caveat-cli 0.16.2 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ import { createRequire as __caveat_createRequire } from 'node:module';
3
3
  const require = __caveat_createRequire(import.meta.url);
4
4
  import {
5
5
  AUTO_SYNC_DEBOUNCE_MS,
6
+ AUTO_SYNC_RECORD_DEBOUNCE_MS,
6
7
  CAVEAT_AUTO_SYNC_ENV,
7
8
  KNOWLEDGE_GITIGNORE,
8
9
  PublishScanError,
@@ -10,6 +11,7 @@ import {
10
11
  __commonJS,
11
12
  __export,
12
13
  __toESM,
14
+ acknowledgeRuntimeErrors,
13
15
  acquireReindexLock,
14
16
  buildAndPublishPendingReminder,
15
17
  buildCodexSidecarDiagnosticsCommand,
@@ -23,6 +25,7 @@ import {
23
25
  communityList,
24
26
  communityPull,
25
27
  communityRemove,
28
+ compactRuntimeErrors,
26
29
  computeEntriesDigest,
27
30
  createKeyserverKeyProvider,
28
31
  decideCodexSidecarExecution,
@@ -41,6 +44,7 @@ import {
41
44
  logHookQueryMiss,
42
45
  markHit,
43
46
  maybeSweepPendingDirs,
47
+ observeRuntimeError,
44
48
  openDb,
45
49
  prewarmSealedKeys,
46
50
  publishOwn,
@@ -54,17 +58,21 @@ import {
54
58
  resetAutoSyncFailureState,
55
59
  resolvePaths,
56
60
  runAutoSync,
61
+ runtimeErrorsDiagnostics,
62
+ runtimeErrorsSnapshot,
57
63
  search,
64
+ setRuntimeErrorStatus,
58
65
  stderrLogger,
59
66
  stopReminderText,
60
67
  struggleSearchText,
61
68
  syncOwn,
62
69
  toolErrorReminderText,
70
+ triggerAutoSync,
63
71
  updateEntry,
64
72
  userPromptSubmitReminderText,
65
73
  writeDigestMarker,
66
74
  writeUserConfigPatch
67
- } from "./chunk-3MLJQLWY.js";
75
+ } from "./chunk-7FEOFAMA.js";
68
76
 
69
77
  // ../../node_modules/.pnpm/ajv@8.18.0/node_modules/ajv/dist/compile/codegen/code.js
70
78
  var require_code = __commonJS({
@@ -443,11 +451,11 @@ var require_codegen = __commonJS({
443
451
  const rhs = this.rhs === void 0 ? "" : ` = ${this.rhs}`;
444
452
  return `${varKind} ${this.name}${rhs};` + _n;
445
453
  }
446
- optimizeNames(names, constants2) {
454
+ optimizeNames(names, constants4) {
447
455
  if (!names[this.name.str])
448
456
  return;
449
457
  if (this.rhs)
450
- this.rhs = optimizeExpr(this.rhs, names, constants2);
458
+ this.rhs = optimizeExpr(this.rhs, names, constants4);
451
459
  return this;
452
460
  }
453
461
  get names() {
@@ -464,10 +472,10 @@ var require_codegen = __commonJS({
464
472
  render({ _n }) {
465
473
  return `${this.lhs} = ${this.rhs};` + _n;
466
474
  }
467
- optimizeNames(names, constants2) {
475
+ optimizeNames(names, constants4) {
468
476
  if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects)
469
477
  return;
470
- this.rhs = optimizeExpr(this.rhs, names, constants2);
478
+ this.rhs = optimizeExpr(this.rhs, names, constants4);
471
479
  return this;
472
480
  }
473
481
  get names() {
@@ -528,8 +536,8 @@ var require_codegen = __commonJS({
528
536
  optimizeNodes() {
529
537
  return `${this.code}` ? this : void 0;
530
538
  }
531
- optimizeNames(names, constants2) {
532
- this.code = optimizeExpr(this.code, names, constants2);
539
+ optimizeNames(names, constants4) {
540
+ this.code = optimizeExpr(this.code, names, constants4);
533
541
  return this;
534
542
  }
535
543
  get names() {
@@ -558,12 +566,12 @@ var require_codegen = __commonJS({
558
566
  }
559
567
  return nodes.length > 0 ? this : void 0;
560
568
  }
561
- optimizeNames(names, constants2) {
569
+ optimizeNames(names, constants4) {
562
570
  const { nodes } = this;
563
571
  let i = nodes.length;
564
572
  while (i--) {
565
573
  const n = nodes[i];
566
- if (n.optimizeNames(names, constants2))
574
+ if (n.optimizeNames(names, constants4))
567
575
  continue;
568
576
  subtractNames(names, n.names);
569
577
  nodes.splice(i, 1);
@@ -616,12 +624,12 @@ var require_codegen = __commonJS({
616
624
  return void 0;
617
625
  return this;
618
626
  }
619
- optimizeNames(names, constants2) {
627
+ optimizeNames(names, constants4) {
620
628
  var _a3;
621
- this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants2);
622
- if (!(super.optimizeNames(names, constants2) || this.else))
629
+ this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants4);
630
+ if (!(super.optimizeNames(names, constants4) || this.else))
623
631
  return;
624
- this.condition = optimizeExpr(this.condition, names, constants2);
632
+ this.condition = optimizeExpr(this.condition, names, constants4);
625
633
  return this;
626
634
  }
627
635
  get names() {
@@ -644,10 +652,10 @@ var require_codegen = __commonJS({
644
652
  render(opts) {
645
653
  return `for(${this.iteration})` + super.render(opts);
646
654
  }
647
- optimizeNames(names, constants2) {
648
- if (!super.optimizeNames(names, constants2))
655
+ optimizeNames(names, constants4) {
656
+ if (!super.optimizeNames(names, constants4))
649
657
  return;
650
- this.iteration = optimizeExpr(this.iteration, names, constants2);
658
+ this.iteration = optimizeExpr(this.iteration, names, constants4);
651
659
  return this;
652
660
  }
653
661
  get names() {
@@ -683,10 +691,10 @@ var require_codegen = __commonJS({
683
691
  render(opts) {
684
692
  return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
685
693
  }
686
- optimizeNames(names, constants2) {
687
- if (!super.optimizeNames(names, constants2))
694
+ optimizeNames(names, constants4) {
695
+ if (!super.optimizeNames(names, constants4))
688
696
  return;
689
- this.iterable = optimizeExpr(this.iterable, names, constants2);
697
+ this.iterable = optimizeExpr(this.iterable, names, constants4);
690
698
  return this;
691
699
  }
692
700
  get names() {
@@ -728,11 +736,11 @@ var require_codegen = __commonJS({
728
736
  (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNodes();
729
737
  return this;
730
738
  }
731
- optimizeNames(names, constants2) {
739
+ optimizeNames(names, constants4) {
732
740
  var _a3, _b;
733
- super.optimizeNames(names, constants2);
734
- (_a3 = this.catch) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants2);
735
- (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants2);
741
+ super.optimizeNames(names, constants4);
742
+ (_a3 = this.catch) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants4);
743
+ (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants4);
736
744
  return this;
737
745
  }
738
746
  get names() {
@@ -1033,7 +1041,7 @@ var require_codegen = __commonJS({
1033
1041
  function addExprNames(names, from) {
1034
1042
  return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
1035
1043
  }
1036
- function optimizeExpr(expr, names, constants2) {
1044
+ function optimizeExpr(expr, names, constants4) {
1037
1045
  if (expr instanceof code_1.Name)
1038
1046
  return replaceName(expr);
1039
1047
  if (!canOptimize(expr))
@@ -1048,14 +1056,14 @@ var require_codegen = __commonJS({
1048
1056
  return items;
1049
1057
  }, []));
1050
1058
  function replaceName(n) {
1051
- const c = constants2[n.str];
1059
+ const c = constants4[n.str];
1052
1060
  if (c === void 0 || names[n.str] !== 1)
1053
1061
  return n;
1054
1062
  delete names[n.str];
1055
1063
  return c;
1056
1064
  }
1057
1065
  function canOptimize(e) {
1058
- return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants2[c.str] !== void 0);
1066
+ return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants4[c.str] !== void 0);
1059
1067
  }
1060
1068
  }
1061
1069
  function subtractNames(names, from) {
@@ -6882,8 +6890,8 @@ import { dirname as dirname4, join as join8 } from "node:path";
6882
6890
 
6883
6891
  // src/claudeInstall.ts
6884
6892
  import { spawnSync } from "node:child_process";
6885
- import { copyFileSync, existsSync, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
6886
- import { dirname as dirname2, join as join3 } from "node:path";
6893
+ import { accessSync, constants, copyFileSync, existsSync, mkdirSync, readFileSync as readFileSync2, realpathSync, statSync, writeFileSync } from "node:fs";
6894
+ import { dirname as dirname2, isAbsolute, join as join3 } from "node:path";
6887
6895
  var EVENT_USER_PROMPT_SUBMIT = "UserPromptSubmit";
6888
6896
  var EVENT_POST_TOOL_USE = "PostToolUse";
6889
6897
  var EVENT_POST_TOOL_USE_FAILURE = "PostToolUseFailure";
@@ -6902,10 +6910,10 @@ function upsertHook(settings, event, command) {
6902
6910
  const list = settings.hooks[event] ??= [];
6903
6911
  const subcommand = command.includes("hook user-prompt-submit") ? "user-prompt-submit" : command.includes("hook post-tool-use") ? "post-tool-use" : command.includes("hook stop") ? "stop" : null;
6904
6912
  for (const entry of list) {
6905
- for (const hook of entry.hooks ?? []) {
6906
- if (isSameHookCommand(hook.command, command)) return "unchanged";
6907
- if (subcommand && isCaveatClaudeHookCommand(hook.command, subcommand)) {
6908
- hook.command = command;
6913
+ for (const hook2 of entry.hooks ?? []) {
6914
+ if (isSameHookCommand(hook2.command, command)) return "unchanged";
6915
+ if (subcommand && isCaveatClaudeHookCommand(hook2.command, subcommand)) {
6916
+ hook2.command = command;
6909
6917
  return "added";
6910
6918
  }
6911
6919
  }
@@ -6943,6 +6951,36 @@ function isCaveatClaudeHookCommand(actual, event) {
6943
6951
  const lower = actual.toLowerCase();
6944
6952
  return !isEnvPrefixedCommand(actual) && lower.includes("caveat") && actual.includes(`hook ${event}`);
6945
6953
  }
6954
+ function commandTokens(command) {
6955
+ const tokens = [];
6956
+ const pattern = /"([^"]*)"|([^\s"]+)/g;
6957
+ let end = 0;
6958
+ let match;
6959
+ while ((match = pattern.exec(command)) !== null) {
6960
+ if (command.slice(end, match.index).trim()) return null;
6961
+ tokens.push(match[1] ?? match[2]);
6962
+ end = pattern.lastIndex;
6963
+ }
6964
+ return command.slice(end).trim() ? null : tokens;
6965
+ }
6966
+ function isCanonicalAsset(path, expectedPath, mode) {
6967
+ if (typeof path !== "string" || !isAbsolute(path) || !isAbsolute(expectedPath)) return false;
6968
+ try {
6969
+ accessSync(path, mode);
6970
+ return statSync(path).isFile() && realpathSync(path) === realpathSync(expectedPath);
6971
+ } catch {
6972
+ return false;
6973
+ }
6974
+ }
6975
+ function isCanonicalCaveatClaudeHookCommand(actual, event, nodePath, cliScriptPath) {
6976
+ const tokens = commandTokens(actual);
6977
+ return tokens?.length === 4 && isCanonicalAsset(tokens[0], nodePath, constants.X_OK) && isCanonicalAsset(tokens[1], cliScriptPath, constants.R_OK) && tokens[2] === "hook" && tokens[3] === event;
6978
+ }
6979
+ function isCaveatClaudeMcpRegistration(value, nodePath, cliScriptPath) {
6980
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
6981
+ const server = value;
6982
+ return Object.keys(server).length === 4 && ["args", "command", "env", "type"].every((key) => Object.hasOwn(server, key)) && server.type === "stdio" && isCanonicalAsset(server.command, nodePath, constants.X_OK) && Array.isArray(server.args) && server.args.length === 3 && server.args[0] === "--disable-warning=ExperimentalWarning" && isCanonicalAsset(server.args[1], cliScriptPath, constants.R_OK) && server.args[2] === "mcp-server" && server.env !== null && typeof server.env === "object" && !Array.isArray(server.env) && Object.keys(server.env).length === 0;
6983
+ }
6946
6984
  function readSettings(path) {
6947
6985
  if (!existsSync(path)) return {};
6948
6986
  return JSON.parse(readFileSync2(path, "utf-8"));
@@ -7074,8 +7112,8 @@ function uninstallClaudeIntegration(opts) {
7074
7112
  }
7075
7113
 
7076
7114
  // src/codexHookInstall.ts
7077
- import { copyFileSync as copyFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
7078
- import { dirname as dirname3, join as join4 } from "node:path";
7115
+ import { accessSync as accessSync2, constants as constants2, copyFileSync as copyFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync as realpathSync2, statSync as statSync2, writeFileSync as writeFileSync2 } from "node:fs";
7116
+ import { dirname as dirname3, isAbsolute as isAbsolute2, join as join4 } from "node:path";
7079
7117
  import { parse as parseToml } from "smol-toml";
7080
7118
  function quote2(p) {
7081
7119
  return p.includes(" ") ? `"${p}"` : p;
@@ -7093,6 +7131,31 @@ function isCaveatCodexHookCommand(actual, event) {
7093
7131
  const lower = actual.toLowerCase();
7094
7132
  return lower.includes("caveat") && actual.includes(eventCommandFragment(event));
7095
7133
  }
7134
+ function commandTokens2(command) {
7135
+ const tokens = [];
7136
+ const pattern = /"([^"]*)"|([^\s"]+)/g;
7137
+ let end = 0;
7138
+ let match;
7139
+ while ((match = pattern.exec(command)) !== null) {
7140
+ if (command.slice(end, match.index).trim()) return null;
7141
+ tokens.push(match[1] ?? match[2]);
7142
+ end = pattern.lastIndex;
7143
+ }
7144
+ return command.slice(end).trim() ? null : tokens;
7145
+ }
7146
+ function isCanonicalAsset2(path, expectedPath, mode) {
7147
+ if (typeof path !== "string" || !isAbsolute2(path) || !isAbsolute2(expectedPath)) return false;
7148
+ try {
7149
+ accessSync2(path, mode);
7150
+ return statSync2(path).isFile() && realpathSync2(path) === realpathSync2(expectedPath);
7151
+ } catch {
7152
+ return false;
7153
+ }
7154
+ }
7155
+ function isCanonicalCaveatCodexHookCommand(actual, event, nodePath, cliScriptPath) {
7156
+ const tokens = commandTokens2(actual);
7157
+ return tokens?.length === 4 && isCanonicalAsset2(tokens[0], nodePath, constants2.X_OK) && isCanonicalAsset2(tokens[1], cliScriptPath, constants2.R_OK) && tokens[2] === "codex-hook" && tokens[3] === event;
7158
+ }
7096
7159
  function hasCaveatHook(hooksJson, event, fragment) {
7097
7160
  return hooksJson.hooks?.[event]?.some(
7098
7161
  (entry) => entry.hooks?.some((h) => h.command.includes(fragment))
@@ -7118,13 +7181,13 @@ function upsertHook2(hooksJson, event, command, subcommand) {
7118
7181
  hooksJson.hooks ??= {};
7119
7182
  const list = hooksJson.hooks[event] ??= [];
7120
7183
  for (const entry of list) {
7121
- for (const hook of entry.hooks ?? []) {
7122
- if (isSameHookCommand2(hook.command, command)) return "unchanged";
7123
- if (isCaveatCodexHookCommand(hook.command, subcommand)) {
7124
- hook.command = command;
7125
- hook.timeoutSec = 5;
7126
- hook.async = false;
7127
- hook.statusMessage = null;
7184
+ for (const hook2 of entry.hooks ?? []) {
7185
+ if (isSameHookCommand2(hook2.command, command)) return "unchanged";
7186
+ if (isCaveatCodexHookCommand(hook2.command, subcommand)) {
7187
+ hook2.command = command;
7188
+ hook2.timeoutSec = 5;
7189
+ hook2.async = false;
7190
+ hook2.statusMessage = null;
7128
7191
  return "added";
7129
7192
  }
7130
7193
  }
@@ -7503,9 +7566,9 @@ function askOnce(question) {
7503
7566
  }
7504
7567
 
7505
7568
  // src/nodePath.ts
7506
- import { existsSync as existsSync3, realpathSync } from "node:fs";
7569
+ import { existsSync as existsSync3, realpathSync as realpathSync3 } from "node:fs";
7507
7570
  import { delimiter, join as join5 } from "node:path";
7508
- var defaultRealpath = (path) => realpathSync.native(path);
7571
+ var defaultRealpath = (path) => realpathSync3.native(path);
7509
7572
  function safeRealpath(path, realpath = defaultRealpath) {
7510
7573
  try {
7511
7574
  return realpath(path);
@@ -8049,7 +8112,13 @@ async function runIndex(ctx, opts) {
8049
8112
  for (const failure of failures) {
8050
8113
  ctx.logger.warn(`${failure.source}: sealed key prewarm failed: ${errorMessage2(failure.error)}`);
8051
8114
  }
8052
- const db = openDb({ path: ctx.paths.dbPath, logger: ctx.logger });
8115
+ let db;
8116
+ try {
8117
+ db = openDb({ path: ctx.paths.dbPath, logger: ctx.logger });
8118
+ } catch (error51) {
8119
+ observeRuntimeError("CAVEAT.DATABASE_OPEN_FAILED", { version: CAVEAT_VERSION });
8120
+ throw error51;
8121
+ }
8053
8122
  try {
8054
8123
  if (opts.full) {
8055
8124
  ctx.logger.info("full rebuild: DELETE FROM entries");
@@ -8064,6 +8133,9 @@ async function runIndex(ctx, opts) {
8064
8133
  }
8065
8134
  }
8066
8135
  writeDigestMarker(ctx.caveatHome, computeEntriesDigest(ctx.paths));
8136
+ } catch (error51) {
8137
+ observeRuntimeError("CAVEAT.INDEX_FAILED", { version: CAVEAT_VERSION });
8138
+ throw error51;
8067
8139
  } finally {
8068
8140
  db.close();
8069
8141
  }
@@ -8218,7 +8290,7 @@ function runStats(ctx) {
8218
8290
 
8219
8291
  // src/commands/serve.ts
8220
8292
  async function runServe(opts) {
8221
- const { startServer } = await import("./server-LAJCQXS3.js");
8293
+ const { startServer } = await import("./server-STR2EAWZ.js");
8222
8294
  const { port, host } = startServer({ port: opts.port });
8223
8295
  process.stdout.write(`[caveat] web portal: http://${host}:${port}/
8224
8296
  `);
@@ -8639,18 +8711,18 @@ var ParseStatus = class _ParseStatus {
8639
8711
  if (this.value !== "aborted")
8640
8712
  this.value = "aborted";
8641
8713
  }
8642
- static mergeArray(status, results) {
8714
+ static mergeArray(status2, results) {
8643
8715
  const arrayValue = [];
8644
8716
  for (const s of results) {
8645
8717
  if (s.status === "aborted")
8646
8718
  return INVALID;
8647
8719
  if (s.status === "dirty")
8648
- status.dirty();
8720
+ status2.dirty();
8649
8721
  arrayValue.push(s.value);
8650
8722
  }
8651
- return { status: status.value, value: arrayValue };
8723
+ return { status: status2.value, value: arrayValue };
8652
8724
  }
8653
- static async mergeObjectAsync(status, pairs) {
8725
+ static async mergeObjectAsync(status2, pairs) {
8654
8726
  const syncPairs = [];
8655
8727
  for (const pair of pairs) {
8656
8728
  const key = await pair.key;
@@ -8660,9 +8732,9 @@ var ParseStatus = class _ParseStatus {
8660
8732
  value
8661
8733
  });
8662
8734
  }
8663
- return _ParseStatus.mergeObjectSync(status, syncPairs);
8735
+ return _ParseStatus.mergeObjectSync(status2, syncPairs);
8664
8736
  }
8665
- static mergeObjectSync(status, pairs) {
8737
+ static mergeObjectSync(status2, pairs) {
8666
8738
  const finalObject = {};
8667
8739
  for (const pair of pairs) {
8668
8740
  const { key, value } = pair;
@@ -8671,14 +8743,14 @@ var ParseStatus = class _ParseStatus {
8671
8743
  if (value.status === "aborted")
8672
8744
  return INVALID;
8673
8745
  if (key.status === "dirty")
8674
- status.dirty();
8746
+ status2.dirty();
8675
8747
  if (value.status === "dirty")
8676
- status.dirty();
8748
+ status2.dirty();
8677
8749
  if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) {
8678
8750
  finalObject[key.value] = value.value;
8679
8751
  }
8680
8752
  }
8681
- return { status: status.value, value: finalObject };
8753
+ return { status: status2.value, value: finalObject };
8682
8754
  }
8683
8755
  };
8684
8756
  var INVALID = Object.freeze({
@@ -9138,7 +9210,7 @@ var ZodString = class _ZodString2 extends ZodType {
9138
9210
  });
9139
9211
  return INVALID;
9140
9212
  }
9141
- const status = new ParseStatus();
9213
+ const status2 = new ParseStatus();
9142
9214
  let ctx = void 0;
9143
9215
  for (const check2 of this._def.checks) {
9144
9216
  if (check2.kind === "min") {
@@ -9152,7 +9224,7 @@ var ZodString = class _ZodString2 extends ZodType {
9152
9224
  exact: false,
9153
9225
  message: check2.message
9154
9226
  });
9155
- status.dirty();
9227
+ status2.dirty();
9156
9228
  }
9157
9229
  } else if (check2.kind === "max") {
9158
9230
  if (input.data.length > check2.value) {
@@ -9165,7 +9237,7 @@ var ZodString = class _ZodString2 extends ZodType {
9165
9237
  exact: false,
9166
9238
  message: check2.message
9167
9239
  });
9168
- status.dirty();
9240
+ status2.dirty();
9169
9241
  }
9170
9242
  } else if (check2.kind === "length") {
9171
9243
  const tooBig = input.data.length > check2.value;
@@ -9191,7 +9263,7 @@ var ZodString = class _ZodString2 extends ZodType {
9191
9263
  message: check2.message
9192
9264
  });
9193
9265
  }
9194
- status.dirty();
9266
+ status2.dirty();
9195
9267
  }
9196
9268
  } else if (check2.kind === "email") {
9197
9269
  if (!emailRegex.test(input.data)) {
@@ -9201,7 +9273,7 @@ var ZodString = class _ZodString2 extends ZodType {
9201
9273
  code: ZodIssueCode.invalid_string,
9202
9274
  message: check2.message
9203
9275
  });
9204
- status.dirty();
9276
+ status2.dirty();
9205
9277
  }
9206
9278
  } else if (check2.kind === "emoji") {
9207
9279
  if (!emojiRegex) {
@@ -9214,7 +9286,7 @@ var ZodString = class _ZodString2 extends ZodType {
9214
9286
  code: ZodIssueCode.invalid_string,
9215
9287
  message: check2.message
9216
9288
  });
9217
- status.dirty();
9289
+ status2.dirty();
9218
9290
  }
9219
9291
  } else if (check2.kind === "uuid") {
9220
9292
  if (!uuidRegex.test(input.data)) {
@@ -9224,7 +9296,7 @@ var ZodString = class _ZodString2 extends ZodType {
9224
9296
  code: ZodIssueCode.invalid_string,
9225
9297
  message: check2.message
9226
9298
  });
9227
- status.dirty();
9299
+ status2.dirty();
9228
9300
  }
9229
9301
  } else if (check2.kind === "nanoid") {
9230
9302
  if (!nanoidRegex.test(input.data)) {
@@ -9234,7 +9306,7 @@ var ZodString = class _ZodString2 extends ZodType {
9234
9306
  code: ZodIssueCode.invalid_string,
9235
9307
  message: check2.message
9236
9308
  });
9237
- status.dirty();
9309
+ status2.dirty();
9238
9310
  }
9239
9311
  } else if (check2.kind === "cuid") {
9240
9312
  if (!cuidRegex.test(input.data)) {
@@ -9244,7 +9316,7 @@ var ZodString = class _ZodString2 extends ZodType {
9244
9316
  code: ZodIssueCode.invalid_string,
9245
9317
  message: check2.message
9246
9318
  });
9247
- status.dirty();
9319
+ status2.dirty();
9248
9320
  }
9249
9321
  } else if (check2.kind === "cuid2") {
9250
9322
  if (!cuid2Regex.test(input.data)) {
@@ -9254,7 +9326,7 @@ var ZodString = class _ZodString2 extends ZodType {
9254
9326
  code: ZodIssueCode.invalid_string,
9255
9327
  message: check2.message
9256
9328
  });
9257
- status.dirty();
9329
+ status2.dirty();
9258
9330
  }
9259
9331
  } else if (check2.kind === "ulid") {
9260
9332
  if (!ulidRegex.test(input.data)) {
@@ -9264,7 +9336,7 @@ var ZodString = class _ZodString2 extends ZodType {
9264
9336
  code: ZodIssueCode.invalid_string,
9265
9337
  message: check2.message
9266
9338
  });
9267
- status.dirty();
9339
+ status2.dirty();
9268
9340
  }
9269
9341
  } else if (check2.kind === "url") {
9270
9342
  try {
@@ -9276,7 +9348,7 @@ var ZodString = class _ZodString2 extends ZodType {
9276
9348
  code: ZodIssueCode.invalid_string,
9277
9349
  message: check2.message
9278
9350
  });
9279
- status.dirty();
9351
+ status2.dirty();
9280
9352
  }
9281
9353
  } else if (check2.kind === "regex") {
9282
9354
  check2.regex.lastIndex = 0;
@@ -9288,7 +9360,7 @@ var ZodString = class _ZodString2 extends ZodType {
9288
9360
  code: ZodIssueCode.invalid_string,
9289
9361
  message: check2.message
9290
9362
  });
9291
- status.dirty();
9363
+ status2.dirty();
9292
9364
  }
9293
9365
  } else if (check2.kind === "trim") {
9294
9366
  input.data = input.data.trim();
@@ -9300,7 +9372,7 @@ var ZodString = class _ZodString2 extends ZodType {
9300
9372
  validation: { includes: check2.value, position: check2.position },
9301
9373
  message: check2.message
9302
9374
  });
9303
- status.dirty();
9375
+ status2.dirty();
9304
9376
  }
9305
9377
  } else if (check2.kind === "toLowerCase") {
9306
9378
  input.data = input.data.toLowerCase();
@@ -9314,7 +9386,7 @@ var ZodString = class _ZodString2 extends ZodType {
9314
9386
  validation: { startsWith: check2.value },
9315
9387
  message: check2.message
9316
9388
  });
9317
- status.dirty();
9389
+ status2.dirty();
9318
9390
  }
9319
9391
  } else if (check2.kind === "endsWith") {
9320
9392
  if (!input.data.endsWith(check2.value)) {
@@ -9324,7 +9396,7 @@ var ZodString = class _ZodString2 extends ZodType {
9324
9396
  validation: { endsWith: check2.value },
9325
9397
  message: check2.message
9326
9398
  });
9327
- status.dirty();
9399
+ status2.dirty();
9328
9400
  }
9329
9401
  } else if (check2.kind === "datetime") {
9330
9402
  const regex = datetimeRegex(check2);
@@ -9335,7 +9407,7 @@ var ZodString = class _ZodString2 extends ZodType {
9335
9407
  validation: "datetime",
9336
9408
  message: check2.message
9337
9409
  });
9338
- status.dirty();
9410
+ status2.dirty();
9339
9411
  }
9340
9412
  } else if (check2.kind === "date") {
9341
9413
  const regex = dateRegex;
@@ -9346,7 +9418,7 @@ var ZodString = class _ZodString2 extends ZodType {
9346
9418
  validation: "date",
9347
9419
  message: check2.message
9348
9420
  });
9349
- status.dirty();
9421
+ status2.dirty();
9350
9422
  }
9351
9423
  } else if (check2.kind === "time") {
9352
9424
  const regex = timeRegex(check2);
@@ -9357,7 +9429,7 @@ var ZodString = class _ZodString2 extends ZodType {
9357
9429
  validation: "time",
9358
9430
  message: check2.message
9359
9431
  });
9360
- status.dirty();
9432
+ status2.dirty();
9361
9433
  }
9362
9434
  } else if (check2.kind === "duration") {
9363
9435
  if (!durationRegex.test(input.data)) {
@@ -9367,7 +9439,7 @@ var ZodString = class _ZodString2 extends ZodType {
9367
9439
  code: ZodIssueCode.invalid_string,
9368
9440
  message: check2.message
9369
9441
  });
9370
- status.dirty();
9442
+ status2.dirty();
9371
9443
  }
9372
9444
  } else if (check2.kind === "ip") {
9373
9445
  if (!isValidIP(input.data, check2.version)) {
@@ -9377,7 +9449,7 @@ var ZodString = class _ZodString2 extends ZodType {
9377
9449
  code: ZodIssueCode.invalid_string,
9378
9450
  message: check2.message
9379
9451
  });
9380
- status.dirty();
9452
+ status2.dirty();
9381
9453
  }
9382
9454
  } else if (check2.kind === "jwt") {
9383
9455
  if (!isValidJWT(input.data, check2.alg)) {
@@ -9387,7 +9459,7 @@ var ZodString = class _ZodString2 extends ZodType {
9387
9459
  code: ZodIssueCode.invalid_string,
9388
9460
  message: check2.message
9389
9461
  });
9390
- status.dirty();
9462
+ status2.dirty();
9391
9463
  }
9392
9464
  } else if (check2.kind === "cidr") {
9393
9465
  if (!isValidCidr(input.data, check2.version)) {
@@ -9397,7 +9469,7 @@ var ZodString = class _ZodString2 extends ZodType {
9397
9469
  code: ZodIssueCode.invalid_string,
9398
9470
  message: check2.message
9399
9471
  });
9400
- status.dirty();
9472
+ status2.dirty();
9401
9473
  }
9402
9474
  } else if (check2.kind === "base64") {
9403
9475
  if (!base64Regex.test(input.data)) {
@@ -9407,7 +9479,7 @@ var ZodString = class _ZodString2 extends ZodType {
9407
9479
  code: ZodIssueCode.invalid_string,
9408
9480
  message: check2.message
9409
9481
  });
9410
- status.dirty();
9482
+ status2.dirty();
9411
9483
  }
9412
9484
  } else if (check2.kind === "base64url") {
9413
9485
  if (!base64urlRegex.test(input.data)) {
@@ -9417,13 +9489,13 @@ var ZodString = class _ZodString2 extends ZodType {
9417
9489
  code: ZodIssueCode.invalid_string,
9418
9490
  message: check2.message
9419
9491
  });
9420
- status.dirty();
9492
+ status2.dirty();
9421
9493
  }
9422
9494
  } else {
9423
9495
  util.assertNever(check2);
9424
9496
  }
9425
9497
  }
9426
- return { status: status.value, value: input.data };
9498
+ return { status: status2.value, value: input.data };
9427
9499
  }
9428
9500
  _regex(regex, validation, message) {
9429
9501
  return this.refinement((data) => regex.test(data), {
@@ -9699,7 +9771,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
9699
9771
  return INVALID;
9700
9772
  }
9701
9773
  let ctx = void 0;
9702
- const status = new ParseStatus();
9774
+ const status2 = new ParseStatus();
9703
9775
  for (const check2 of this._def.checks) {
9704
9776
  if (check2.kind === "int") {
9705
9777
  if (!util.isInteger(input.data)) {
@@ -9710,7 +9782,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
9710
9782
  received: "float",
9711
9783
  message: check2.message
9712
9784
  });
9713
- status.dirty();
9785
+ status2.dirty();
9714
9786
  }
9715
9787
  } else if (check2.kind === "min") {
9716
9788
  const tooSmall = check2.inclusive ? input.data < check2.value : input.data <= check2.value;
@@ -9724,7 +9796,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
9724
9796
  exact: false,
9725
9797
  message: check2.message
9726
9798
  });
9727
- status.dirty();
9799
+ status2.dirty();
9728
9800
  }
9729
9801
  } else if (check2.kind === "max") {
9730
9802
  const tooBig = check2.inclusive ? input.data > check2.value : input.data >= check2.value;
@@ -9738,7 +9810,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
9738
9810
  exact: false,
9739
9811
  message: check2.message
9740
9812
  });
9741
- status.dirty();
9813
+ status2.dirty();
9742
9814
  }
9743
9815
  } else if (check2.kind === "multipleOf") {
9744
9816
  if (floatSafeRemainder(input.data, check2.value) !== 0) {
@@ -9748,7 +9820,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
9748
9820
  multipleOf: check2.value,
9749
9821
  message: check2.message
9750
9822
  });
9751
- status.dirty();
9823
+ status2.dirty();
9752
9824
  }
9753
9825
  } else if (check2.kind === "finite") {
9754
9826
  if (!Number.isFinite(input.data)) {
@@ -9757,13 +9829,13 @@ var ZodNumber = class _ZodNumber extends ZodType {
9757
9829
  code: ZodIssueCode.not_finite,
9758
9830
  message: check2.message
9759
9831
  });
9760
- status.dirty();
9832
+ status2.dirty();
9761
9833
  }
9762
9834
  } else {
9763
9835
  util.assertNever(check2);
9764
9836
  }
9765
9837
  }
9766
- return { status: status.value, value: input.data };
9838
+ return { status: status2.value, value: input.data };
9767
9839
  }
9768
9840
  gte(value, message) {
9769
9841
  return this.setLimit("min", value, true, errorUtil.toString(message));
@@ -9928,7 +10000,7 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
9928
10000
  return this._getInvalidInput(input);
9929
10001
  }
9930
10002
  let ctx = void 0;
9931
- const status = new ParseStatus();
10003
+ const status2 = new ParseStatus();
9932
10004
  for (const check2 of this._def.checks) {
9933
10005
  if (check2.kind === "min") {
9934
10006
  const tooSmall = check2.inclusive ? input.data < check2.value : input.data <= check2.value;
@@ -9941,7 +10013,7 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
9941
10013
  inclusive: check2.inclusive,
9942
10014
  message: check2.message
9943
10015
  });
9944
- status.dirty();
10016
+ status2.dirty();
9945
10017
  }
9946
10018
  } else if (check2.kind === "max") {
9947
10019
  const tooBig = check2.inclusive ? input.data > check2.value : input.data >= check2.value;
@@ -9954,7 +10026,7 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
9954
10026
  inclusive: check2.inclusive,
9955
10027
  message: check2.message
9956
10028
  });
9957
- status.dirty();
10029
+ status2.dirty();
9958
10030
  }
9959
10031
  } else if (check2.kind === "multipleOf") {
9960
10032
  if (input.data % check2.value !== BigInt(0)) {
@@ -9964,13 +10036,13 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
9964
10036
  multipleOf: check2.value,
9965
10037
  message: check2.message
9966
10038
  });
9967
- status.dirty();
10039
+ status2.dirty();
9968
10040
  }
9969
10041
  } else {
9970
10042
  util.assertNever(check2);
9971
10043
  }
9972
10044
  }
9973
- return { status: status.value, value: input.data };
10045
+ return { status: status2.value, value: input.data };
9974
10046
  }
9975
10047
  _getInvalidInput(input) {
9976
10048
  const ctx = this._getOrReturnCtx(input);
@@ -10128,7 +10200,7 @@ var ZodDate = class _ZodDate extends ZodType {
10128
10200
  });
10129
10201
  return INVALID;
10130
10202
  }
10131
- const status = new ParseStatus();
10203
+ const status2 = new ParseStatus();
10132
10204
  let ctx = void 0;
10133
10205
  for (const check2 of this._def.checks) {
10134
10206
  if (check2.kind === "min") {
@@ -10142,7 +10214,7 @@ var ZodDate = class _ZodDate extends ZodType {
10142
10214
  minimum: check2.value,
10143
10215
  type: "date"
10144
10216
  });
10145
- status.dirty();
10217
+ status2.dirty();
10146
10218
  }
10147
10219
  } else if (check2.kind === "max") {
10148
10220
  if (input.data.getTime() > check2.value) {
@@ -10155,14 +10227,14 @@ var ZodDate = class _ZodDate extends ZodType {
10155
10227
  maximum: check2.value,
10156
10228
  type: "date"
10157
10229
  });
10158
- status.dirty();
10230
+ status2.dirty();
10159
10231
  }
10160
10232
  } else {
10161
10233
  util.assertNever(check2);
10162
10234
  }
10163
10235
  }
10164
10236
  return {
10165
- status: status.value,
10237
+ status: status2.value,
10166
10238
  value: new Date(input.data.getTime())
10167
10239
  };
10168
10240
  }
@@ -10348,7 +10420,7 @@ ZodVoid.create = (params) => {
10348
10420
  };
10349
10421
  var ZodArray = class _ZodArray extends ZodType {
10350
10422
  _parse(input) {
10351
- const { ctx, status } = this._processInputParams(input);
10423
+ const { ctx, status: status2 } = this._processInputParams(input);
10352
10424
  const def = this._def;
10353
10425
  if (ctx.parsedType !== ZodParsedType.array) {
10354
10426
  addIssueToContext(ctx, {
@@ -10371,7 +10443,7 @@ var ZodArray = class _ZodArray extends ZodType {
10371
10443
  exact: true,
10372
10444
  message: def.exactLength.message
10373
10445
  });
10374
- status.dirty();
10446
+ status2.dirty();
10375
10447
  }
10376
10448
  }
10377
10449
  if (def.minLength !== null) {
@@ -10384,7 +10456,7 @@ var ZodArray = class _ZodArray extends ZodType {
10384
10456
  exact: false,
10385
10457
  message: def.minLength.message
10386
10458
  });
10387
- status.dirty();
10459
+ status2.dirty();
10388
10460
  }
10389
10461
  }
10390
10462
  if (def.maxLength !== null) {
@@ -10397,20 +10469,20 @@ var ZodArray = class _ZodArray extends ZodType {
10397
10469
  exact: false,
10398
10470
  message: def.maxLength.message
10399
10471
  });
10400
- status.dirty();
10472
+ status2.dirty();
10401
10473
  }
10402
10474
  }
10403
10475
  if (ctx.common.async) {
10404
10476
  return Promise.all([...ctx.data].map((item, i) => {
10405
10477
  return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));
10406
10478
  })).then((result2) => {
10407
- return ParseStatus.mergeArray(status, result2);
10479
+ return ParseStatus.mergeArray(status2, result2);
10408
10480
  });
10409
10481
  }
10410
10482
  const result = [...ctx.data].map((item, i) => {
10411
10483
  return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));
10412
10484
  });
10413
- return ParseStatus.mergeArray(status, result);
10485
+ return ParseStatus.mergeArray(status2, result);
10414
10486
  }
10415
10487
  get element() {
10416
10488
  return this._def.type;
@@ -10499,7 +10571,7 @@ var ZodObject = class _ZodObject extends ZodType {
10499
10571
  });
10500
10572
  return INVALID;
10501
10573
  }
10502
- const { status, ctx } = this._processInputParams(input);
10574
+ const { status: status2, ctx } = this._processInputParams(input);
10503
10575
  const { shape, keys: shapeKeys } = this._getCached();
10504
10576
  const extraKeys = [];
10505
10577
  if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
@@ -10534,7 +10606,7 @@ var ZodObject = class _ZodObject extends ZodType {
10534
10606
  code: ZodIssueCode.unrecognized_keys,
10535
10607
  keys: extraKeys
10536
10608
  });
10537
- status.dirty();
10609
+ status2.dirty();
10538
10610
  }
10539
10611
  } else if (unknownKeys === "strip") {
10540
10612
  } else {
@@ -10568,10 +10640,10 @@ var ZodObject = class _ZodObject extends ZodType {
10568
10640
  }
10569
10641
  return syncPairs;
10570
10642
  }).then((syncPairs) => {
10571
- return ParseStatus.mergeObjectSync(status, syncPairs);
10643
+ return ParseStatus.mergeObjectSync(status2, syncPairs);
10572
10644
  });
10573
10645
  } else {
10574
- return ParseStatus.mergeObjectSync(status, pairs);
10646
+ return ParseStatus.mergeObjectSync(status2, pairs);
10575
10647
  }
10576
10648
  }
10577
10649
  get shape() {
@@ -11049,7 +11121,7 @@ function mergeValues(a, b) {
11049
11121
  }
11050
11122
  var ZodIntersection = class extends ZodType {
11051
11123
  _parse(input) {
11052
- const { status, ctx } = this._processInputParams(input);
11124
+ const { status: status2, ctx } = this._processInputParams(input);
11053
11125
  const handleParsed = (parsedLeft, parsedRight) => {
11054
11126
  if (isAborted(parsedLeft) || isAborted(parsedRight)) {
11055
11127
  return INVALID;
@@ -11062,9 +11134,9 @@ var ZodIntersection = class extends ZodType {
11062
11134
  return INVALID;
11063
11135
  }
11064
11136
  if (isDirty(parsedLeft) || isDirty(parsedRight)) {
11065
- status.dirty();
11137
+ status2.dirty();
11066
11138
  }
11067
- return { status: status.value, value: merged.data };
11139
+ return { status: status2.value, value: merged.data };
11068
11140
  };
11069
11141
  if (ctx.common.async) {
11070
11142
  return Promise.all([
@@ -11102,7 +11174,7 @@ ZodIntersection.create = (left, right, params) => {
11102
11174
  };
11103
11175
  var ZodTuple = class _ZodTuple extends ZodType {
11104
11176
  _parse(input) {
11105
- const { status, ctx } = this._processInputParams(input);
11177
+ const { status: status2, ctx } = this._processInputParams(input);
11106
11178
  if (ctx.parsedType !== ZodParsedType.array) {
11107
11179
  addIssueToContext(ctx, {
11108
11180
  code: ZodIssueCode.invalid_type,
@@ -11130,7 +11202,7 @@ var ZodTuple = class _ZodTuple extends ZodType {
11130
11202
  exact: false,
11131
11203
  type: "array"
11132
11204
  });
11133
- status.dirty();
11205
+ status2.dirty();
11134
11206
  }
11135
11207
  const items = [...ctx.data].map((item, itemIndex) => {
11136
11208
  const schema = this._def.items[itemIndex] || this._def.rest;
@@ -11140,10 +11212,10 @@ var ZodTuple = class _ZodTuple extends ZodType {
11140
11212
  }).filter((x) => !!x);
11141
11213
  if (ctx.common.async) {
11142
11214
  return Promise.all(items).then((results) => {
11143
- return ParseStatus.mergeArray(status, results);
11215
+ return ParseStatus.mergeArray(status2, results);
11144
11216
  });
11145
11217
  } else {
11146
- return ParseStatus.mergeArray(status, items);
11218
+ return ParseStatus.mergeArray(status2, items);
11147
11219
  }
11148
11220
  }
11149
11221
  get items() {
@@ -11175,7 +11247,7 @@ var ZodRecord = class _ZodRecord extends ZodType {
11175
11247
  return this._def.valueType;
11176
11248
  }
11177
11249
  _parse(input) {
11178
- const { status, ctx } = this._processInputParams(input);
11250
+ const { status: status2, ctx } = this._processInputParams(input);
11179
11251
  if (ctx.parsedType !== ZodParsedType.object) {
11180
11252
  addIssueToContext(ctx, {
11181
11253
  code: ZodIssueCode.invalid_type,
@@ -11195,9 +11267,9 @@ var ZodRecord = class _ZodRecord extends ZodType {
11195
11267
  });
11196
11268
  }
11197
11269
  if (ctx.common.async) {
11198
- return ParseStatus.mergeObjectAsync(status, pairs);
11270
+ return ParseStatus.mergeObjectAsync(status2, pairs);
11199
11271
  } else {
11200
- return ParseStatus.mergeObjectSync(status, pairs);
11272
+ return ParseStatus.mergeObjectSync(status2, pairs);
11201
11273
  }
11202
11274
  }
11203
11275
  get element() {
@@ -11228,7 +11300,7 @@ var ZodMap = class extends ZodType {
11228
11300
  return this._def.valueType;
11229
11301
  }
11230
11302
  _parse(input) {
11231
- const { status, ctx } = this._processInputParams(input);
11303
+ const { status: status2, ctx } = this._processInputParams(input);
11232
11304
  if (ctx.parsedType !== ZodParsedType.map) {
11233
11305
  addIssueToContext(ctx, {
11234
11306
  code: ZodIssueCode.invalid_type,
@@ -11255,11 +11327,11 @@ var ZodMap = class extends ZodType {
11255
11327
  return INVALID;
11256
11328
  }
11257
11329
  if (key.status === "dirty" || value.status === "dirty") {
11258
- status.dirty();
11330
+ status2.dirty();
11259
11331
  }
11260
11332
  finalMap.set(key.value, value.value);
11261
11333
  }
11262
- return { status: status.value, value: finalMap };
11334
+ return { status: status2.value, value: finalMap };
11263
11335
  });
11264
11336
  } else {
11265
11337
  const finalMap = /* @__PURE__ */ new Map();
@@ -11270,11 +11342,11 @@ var ZodMap = class extends ZodType {
11270
11342
  return INVALID;
11271
11343
  }
11272
11344
  if (key.status === "dirty" || value.status === "dirty") {
11273
- status.dirty();
11345
+ status2.dirty();
11274
11346
  }
11275
11347
  finalMap.set(key.value, value.value);
11276
11348
  }
11277
- return { status: status.value, value: finalMap };
11349
+ return { status: status2.value, value: finalMap };
11278
11350
  }
11279
11351
  }
11280
11352
  };
@@ -11288,7 +11360,7 @@ ZodMap.create = (keyType, valueType, params) => {
11288
11360
  };
11289
11361
  var ZodSet = class _ZodSet extends ZodType {
11290
11362
  _parse(input) {
11291
- const { status, ctx } = this._processInputParams(input);
11363
+ const { status: status2, ctx } = this._processInputParams(input);
11292
11364
  if (ctx.parsedType !== ZodParsedType.set) {
11293
11365
  addIssueToContext(ctx, {
11294
11366
  code: ZodIssueCode.invalid_type,
@@ -11308,7 +11380,7 @@ var ZodSet = class _ZodSet extends ZodType {
11308
11380
  exact: false,
11309
11381
  message: def.minSize.message
11310
11382
  });
11311
- status.dirty();
11383
+ status2.dirty();
11312
11384
  }
11313
11385
  }
11314
11386
  if (def.maxSize !== null) {
@@ -11321,7 +11393,7 @@ var ZodSet = class _ZodSet extends ZodType {
11321
11393
  exact: false,
11322
11394
  message: def.maxSize.message
11323
11395
  });
11324
- status.dirty();
11396
+ status2.dirty();
11325
11397
  }
11326
11398
  }
11327
11399
  const valueType = this._def.valueType;
@@ -11331,10 +11403,10 @@ var ZodSet = class _ZodSet extends ZodType {
11331
11403
  if (element.status === "aborted")
11332
11404
  return INVALID;
11333
11405
  if (element.status === "dirty")
11334
- status.dirty();
11406
+ status2.dirty();
11335
11407
  parsedSet.add(element.value);
11336
11408
  }
11337
- return { status: status.value, value: parsedSet };
11409
+ return { status: status2.value, value: parsedSet };
11338
11410
  }
11339
11411
  const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));
11340
11412
  if (ctx.common.async) {
@@ -11665,15 +11737,15 @@ var ZodEffects = class extends ZodType {
11665
11737
  return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects ? this._def.schema.sourceType() : this._def.schema;
11666
11738
  }
11667
11739
  _parse(input) {
11668
- const { status, ctx } = this._processInputParams(input);
11740
+ const { status: status2, ctx } = this._processInputParams(input);
11669
11741
  const effect = this._def.effect || null;
11670
11742
  const checkCtx = {
11671
11743
  addIssue: (arg) => {
11672
11744
  addIssueToContext(ctx, arg);
11673
11745
  if (arg.fatal) {
11674
- status.abort();
11746
+ status2.abort();
11675
11747
  } else {
11676
- status.dirty();
11748
+ status2.dirty();
11677
11749
  }
11678
11750
  },
11679
11751
  get path() {
@@ -11685,7 +11757,7 @@ var ZodEffects = class extends ZodType {
11685
11757
  const processed = effect.transform(ctx.data, checkCtx);
11686
11758
  if (ctx.common.async) {
11687
11759
  return Promise.resolve(processed).then(async (processed2) => {
11688
- if (status.value === "aborted")
11760
+ if (status2.value === "aborted")
11689
11761
  return INVALID;
11690
11762
  const result = await this._def.schema._parseAsync({
11691
11763
  data: processed2,
@@ -11696,12 +11768,12 @@ var ZodEffects = class extends ZodType {
11696
11768
  return INVALID;
11697
11769
  if (result.status === "dirty")
11698
11770
  return DIRTY(result.value);
11699
- if (status.value === "dirty")
11771
+ if (status2.value === "dirty")
11700
11772
  return DIRTY(result.value);
11701
11773
  return result;
11702
11774
  });
11703
11775
  } else {
11704
- if (status.value === "aborted")
11776
+ if (status2.value === "aborted")
11705
11777
  return INVALID;
11706
11778
  const result = this._def.schema._parseSync({
11707
11779
  data: processed,
@@ -11712,7 +11784,7 @@ var ZodEffects = class extends ZodType {
11712
11784
  return INVALID;
11713
11785
  if (result.status === "dirty")
11714
11786
  return DIRTY(result.value);
11715
- if (status.value === "dirty")
11787
+ if (status2.value === "dirty")
11716
11788
  return DIRTY(result.value);
11717
11789
  return result;
11718
11790
  }
@@ -11737,17 +11809,17 @@ var ZodEffects = class extends ZodType {
11737
11809
  if (inner.status === "aborted")
11738
11810
  return INVALID;
11739
11811
  if (inner.status === "dirty")
11740
- status.dirty();
11812
+ status2.dirty();
11741
11813
  executeRefinement(inner.value);
11742
- return { status: status.value, value: inner.value };
11814
+ return { status: status2.value, value: inner.value };
11743
11815
  } else {
11744
11816
  return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => {
11745
11817
  if (inner.status === "aborted")
11746
11818
  return INVALID;
11747
11819
  if (inner.status === "dirty")
11748
- status.dirty();
11820
+ status2.dirty();
11749
11821
  return executeRefinement(inner.value).then(() => {
11750
- return { status: status.value, value: inner.value };
11822
+ return { status: status2.value, value: inner.value };
11751
11823
  });
11752
11824
  });
11753
11825
  }
@@ -11765,13 +11837,13 @@ var ZodEffects = class extends ZodType {
11765
11837
  if (result instanceof Promise) {
11766
11838
  throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
11767
11839
  }
11768
- return { status: status.value, value: result };
11840
+ return { status: status2.value, value: result };
11769
11841
  } else {
11770
11842
  return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {
11771
11843
  if (!isValid(base))
11772
11844
  return INVALID;
11773
11845
  return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
11774
- status: status.value,
11846
+ status: status2.value,
11775
11847
  value: result
11776
11848
  }));
11777
11849
  });
@@ -11949,7 +12021,7 @@ var ZodBranded = class extends ZodType {
11949
12021
  };
11950
12022
  var ZodPipeline = class _ZodPipeline extends ZodType {
11951
12023
  _parse(input) {
11952
- const { status, ctx } = this._processInputParams(input);
12024
+ const { status: status2, ctx } = this._processInputParams(input);
11953
12025
  if (ctx.common.async) {
11954
12026
  const handleAsync = async () => {
11955
12027
  const inResult = await this._def.in._parseAsync({
@@ -11960,7 +12032,7 @@ var ZodPipeline = class _ZodPipeline extends ZodType {
11960
12032
  if (inResult.status === "aborted")
11961
12033
  return INVALID;
11962
12034
  if (inResult.status === "dirty") {
11963
- status.dirty();
12035
+ status2.dirty();
11964
12036
  return DIRTY(inResult.value);
11965
12037
  } else {
11966
12038
  return this._def.out._parseAsync({
@@ -11980,7 +12052,7 @@ var ZodPipeline = class _ZodPipeline extends ZodType {
11980
12052
  if (inResult.status === "aborted")
11981
12053
  return INVALID;
11982
12054
  if (inResult.status === "dirty") {
11983
- status.dirty();
12055
+ status2.dirty();
11984
12056
  return {
11985
12057
  status: "dirty",
11986
12058
  value: inResult.value
@@ -28337,8 +28409,8 @@ var UrlElicitationRequiredError = class extends McpError {
28337
28409
  };
28338
28410
 
28339
28411
  // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
28340
- function isTerminal(status) {
28341
- return status === "completed" || status === "failed" || status === "cancelled";
28412
+ function isTerminal(status2) {
28413
+ return status2 === "completed" || status2 === "failed" || status2 === "cancelled";
28342
28414
  }
28343
28415
 
28344
28416
  // ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.4.3/node_modules/zod-to-json-schema/dist/esm/Options.js
@@ -30557,8 +30629,8 @@ var Protocol = class {
30557
30629
  }
30558
30630
  return task;
30559
30631
  },
30560
- storeTaskResult: async (taskId, status, result) => {
30561
- await taskStore.storeTaskResult(taskId, status, result, sessionId);
30632
+ storeTaskResult: async (taskId, status2, result) => {
30633
+ await taskStore.storeTaskResult(taskId, status2, result, sessionId);
30562
30634
  const task = await taskStore.getTask(taskId, sessionId);
30563
30635
  if (task) {
30564
30636
  const notification = TaskStatusNotificationSchema.parse({
@@ -30574,15 +30646,15 @@ var Protocol = class {
30574
30646
  getTaskResult: (taskId) => {
30575
30647
  return taskStore.getTaskResult(taskId, sessionId);
30576
30648
  },
30577
- updateTaskStatus: async (taskId, status, statusMessage) => {
30649
+ updateTaskStatus: async (taskId, status2, statusMessage) => {
30578
30650
  const task = await taskStore.getTask(taskId, sessionId);
30579
30651
  if (!task) {
30580
30652
  throw new McpError(ErrorCode.InvalidParams, `Task "${taskId}" not found - it may have been cleaned up`);
30581
30653
  }
30582
30654
  if (isTerminal(task.status)) {
30583
- throw new McpError(ErrorCode.InvalidParams, `Cannot update task "${taskId}" from terminal status "${task.status}" to "${status}". Terminal states (completed, failed, cancelled) cannot transition to other states.`);
30655
+ throw new McpError(ErrorCode.InvalidParams, `Cannot update task "${taskId}" from terminal status "${task.status}" to "${status2}". Terminal states (completed, failed, cancelled) cannot transition to other states.`);
30584
30656
  }
30585
- await taskStore.updateTaskStatus(taskId, status, statusMessage, sessionId);
30657
+ await taskStore.updateTaskStatus(taskId, status2, statusMessage, sessionId);
30586
30658
  const updatedTask = await taskStore.getTask(taskId, sessionId);
30587
30659
  if (updatedTask) {
30588
30660
  const notification = TaskStatusNotificationSchema.parse({
@@ -32291,6 +32363,21 @@ var StdioServerTransport = class {
32291
32363
  // ../mcp/dist/context.js
32292
32364
  import { homedir as homedir2 } from "node:os";
32293
32365
  import { join as join9 } from "node:path";
32366
+
32367
+ // ../mcp/dist/autoSyncTrigger.js
32368
+ function triggerAutoSyncAfterWrite(caveatHome, logger) {
32369
+ try {
32370
+ triggerAutoSync({
32371
+ caveatHome,
32372
+ cliScript: process.argv[1] ?? "",
32373
+ debounceMs: AUTO_SYNC_RECORD_DEBOUNCE_MS
32374
+ });
32375
+ } catch (err) {
32376
+ logger.warn(`auto sync trigger failed: ${err instanceof Error ? err.message : String(err)}`);
32377
+ }
32378
+ }
32379
+
32380
+ // ../mcp/dist/context.js
32294
32381
  function buildMcpContext(overrides = {}) {
32295
32382
  const userHome = overrides.userHome ?? homedir2();
32296
32383
  const caveatHome = overrides.caveatHome ?? findCaveatHome(userHome);
@@ -32299,7 +32386,8 @@ function buildMcpContext(overrides = {}) {
32299
32386
  const config2 = loadConfig(userConfigPath);
32300
32387
  const paths = resolvePaths(caveatHome, config2.knowledgeRepo, userHome);
32301
32388
  const db = openDb({ path: paths.dbPath, logger });
32302
- return { caveatHome, userHome, userConfigPath, config: config2, paths, logger, db };
32389
+ const onEntryWritten = overrides.onEntryWritten ?? (() => triggerAutoSyncAfterWrite(caveatHome, logger));
32390
+ return { caveatHome, userHome, userConfigPath, config: config2, paths, logger, db, onEntryWritten };
32303
32391
  }
32304
32392
 
32305
32393
  // ../mcp/dist/tools/search.js
@@ -32382,10 +32470,12 @@ var recordInputShape = {
32382
32470
  category: external_exports.string().optional().describe("Directory under entries/ (e.g., gpu, claude-code). Default: misc")
32383
32471
  };
32384
32472
  function handleRecord(ctx, args) {
32385
- return recordEntry(args, {
32473
+ const result = recordEntry(args, {
32386
32474
  db: ctx.db,
32387
32475
  entriesRoot: ctx.paths.entriesDir
32388
32476
  });
32477
+ ctx.onEntryWritten();
32478
+ return result;
32389
32479
  }
32390
32480
 
32391
32481
  // ../mcp/dist/tools/update.js
@@ -32422,11 +32512,13 @@ function handleUpdate(ctx, args) {
32422
32512
  if (source !== "own") {
32423
32513
  throw new Error("community \u30A8\u30F3\u30C8\u30EA\u306F\u8CFC\u8AAD\u7269\u3067\u3059; \u7DE8\u96C6\u306F\u4E0A\u6D41\u3067\u884C\u3063\u3066\u304F\u3060\u3055\u3044");
32424
32514
  }
32425
- return updateEntry(args.id, args.patch, {
32515
+ const result = updateEntry(args.id, args.patch, {
32426
32516
  db: ctx.db,
32427
32517
  entriesRoot: ctx.paths.entriesDir,
32428
32518
  source
32429
32519
  });
32520
+ ctx.onEntryWritten();
32521
+ return result;
32430
32522
  }
32431
32523
 
32432
32524
  // ../mcp/dist/tools/listRecent.js
@@ -32483,7 +32575,21 @@ function jsonResult(data) {
32483
32575
  ]
32484
32576
  };
32485
32577
  }
32486
- function registerAllTools(server, ctx) {
32578
+ function expectedControlFlow(error51) {
32579
+ const message = error51 instanceof Error ? error51.message : "";
32580
+ return /^caveat not found:/.test(message) || /^community エントリは購読物/.test(message) || /^immutable frontmatter key:/.test(message);
32581
+ }
32582
+ function observeToolFailure(handler, productVersion = "0.0.0") {
32583
+ return async (args) => {
32584
+ try {
32585
+ return jsonResult(await handler(args));
32586
+ } catch (error51) {
32587
+ if (!expectedControlFlow(error51)) observeRuntimeError("CAVEAT.MCP_TOOL_FAILED", { version: productVersion });
32588
+ throw error51;
32589
+ }
32590
+ };
32591
+ }
32592
+ function registerAllTools(server, ctx, productVersion = "0.0.0") {
32487
32593
  server.registerTool(
32488
32594
  "caveat_search",
32489
32595
  {
@@ -32491,7 +32597,7 @@ function registerAllTools(server, ctx) {
32491
32597
  description: 'Search the "caveats" knowledge base \u2014 records of time-wasting traps someone already diagnosed, including external-spec issues (GPU/driver/CUDA versions, native-module builds, IDE/shell quirks, platform-specific behavior, library version incompatibilities) and reusable repo-specific context. Call this FIRST when a problem smells like a known trap \u2014 before reading stack traces top-to-bottom or trying fixes. Query: 3+ chars, plain tokens only (no OR/NEAR/other FTS5 operators). If it returns 0 hits, retry with synonyms and Japanese/English paraphrases. Returns summary rows including `{id, source}` \u2014 pass BOTH to caveat_get for the full body.',
32492
32598
  inputSchema: searchInputShape
32493
32599
  },
32494
- async (args) => jsonResult(handleSearch(ctx, args))
32600
+ observeToolFailure((args) => handleSearch(ctx, args), productVersion)
32495
32601
  );
32496
32602
  server.registerTool(
32497
32603
  "caveat_get",
@@ -32500,7 +32606,7 @@ function registerAllTools(server, ctx) {
32500
32606
  description: 'Fetch the full body (frontmatter + H2 sections + text) of a caveat by id. IMPORTANT: when the id came from caveat_search, you MUST pass the `source` field from that same result (e.g., "community/Caveat"). The default source is "own" only; omitting source for a community entry returns not-found.',
32501
32607
  inputSchema: getInputShape
32502
32608
  },
32503
- async (args) => jsonResult(handleGet(ctx, args))
32609
+ observeToolFailure((args) => handleGet(ctx, args), productVersion)
32504
32610
  );
32505
32611
  server.registerTool(
32506
32612
  "caveat_record",
@@ -32509,7 +32615,7 @@ function registerAllTools(server, ctx) {
32509
32615
  description: "Create a new caveat: a reusable record of a time-wasting trap (wrong driver, version mismatch, platform bug, IDE quirk, native-module issue, or repo-specific context) so future sessions can find it via caveat_search. REQUIRED BEFORE CALLING: run caveat_search first to avoid duplicates. Set visibility using this binary criterion: `public` if a third party could reproduce it; `private` if it is repo/workflow-specific or depends on intentional local design; when unclear, prefer `private`; follow an explicit user visibility choice. Qualifies: specific symptom + diagnosed cause (or `outcome: impossible` verdict) + environment fingerprint. Does NOT qualify: ordinary project-internal logic bugs, user preferences, session summaries, or ephemeral task notes; reusable repo-specific traps may be `private`. Auto-fills source_session and environment defaults; source_project is left null by design (shared knowledge must not leak per-user project names).",
32510
32616
  inputSchema: recordInputShape
32511
32617
  },
32512
- async (args) => jsonResult(handleRecord(ctx, args))
32618
+ observeToolFailure((args) => handleRecord(ctx, args), productVersion)
32513
32619
  );
32514
32620
  server.registerTool(
32515
32621
  "caveat_update",
@@ -32518,7 +32624,7 @@ function registerAllTools(server, ctx) {
32518
32624
  description: "Patch an existing caveat \u2014 use when newer evidence extends or corrects one that already exists. Frontmatter shallow-merges, but array fields (tags etc.) REPLACE rather than append \u2014 to add one tag, read the current list first, then patch with the full new array. Sections match by case-insensitive H2 heading. When changing `Symptom`, preserve raw errors verbatim and add stable Japanese/English symptom keywords when known; do not force or guess translations. Immutable keys: id, created_at, source_session, source_project. Common uses: bump `last_verified` after re-confirming, add a resolution when it was `tentative`, flip `outcome` to `impossible`.",
32519
32625
  inputSchema: updateInputShape
32520
32626
  },
32521
- async (args) => jsonResult(handleUpdate(ctx, args))
32627
+ observeToolFailure((args) => handleUpdate(ctx, args), productVersion)
32522
32628
  );
32523
32629
  server.registerTool(
32524
32630
  "caveat_list_recent",
@@ -32527,7 +32633,7 @@ function registerAllTools(server, ctx) {
32527
32633
  description: "List caveats ordered by updated_at DESC. Use for browsing recent additions \u2014 e.g., showing the user what is new after caveat_pull. Not for search; use caveat_search when you have a query.",
32528
32634
  inputSchema: listRecentInputShape
32529
32635
  },
32530
- async (args) => jsonResult(handleListRecent(ctx, args))
32636
+ observeToolFailure((args) => handleListRecent(ctx, args), productVersion)
32531
32637
  );
32532
32638
  server.registerTool(
32533
32639
  "caveat_pull",
@@ -32536,7 +32642,7 @@ function registerAllTools(server, ctx) {
32536
32642
  description: "git-pull every subscribed community caveat repo (added via `caveat community add`) and re-index. Call when: (a) the user explicitly asks about others' knowledge on a topic, or (b) caveat_search returned empty for a query that feels like it should have hits and a subscribed repo might be stale. Do NOT call reflexively at session start \u2014 it is cheap but not free, and stale-by-minutes is acceptable. Safe and idempotent.",
32537
32643
  inputSchema: pullInputShape
32538
32644
  },
32539
- async (args) => jsonResult(await handlePull(ctx, args))
32645
+ observeToolFailure((args) => handlePull(ctx, args), productVersion)
32540
32646
  );
32541
32647
  }
32542
32648
 
@@ -32547,7 +32653,7 @@ async function startMcpStdioServer(overrides = {}) {
32547
32653
  { name: "caveat", version: "0.0.0" },
32548
32654
  { capabilities: { tools: {} } }
32549
32655
  );
32550
- registerAllTools(server, ctx);
32656
+ registerAllTools(server, ctx, overrides.productVersion);
32551
32657
  const transport = new StdioServerTransport();
32552
32658
  await server.connect(transport);
32553
32659
  const shutdown = () => {
@@ -32573,25 +32679,30 @@ if (invokedPath && thisPath && invokedPath.toLowerCase() === thisPath.toLowerCas
32573
32679
 
32574
32680
  // src/commands/mcpServer.ts
32575
32681
  async function runMcpServer() {
32576
- await startMcpStdioServer();
32682
+ try {
32683
+ await startMcpStdioServer({ productVersion: CAVEAT_VERSION });
32684
+ } catch (error51) {
32685
+ observeRuntimeError("CAVEAT.MCP_SERVER_FAILED", { version: CAVEAT_VERSION });
32686
+ throw error51;
32687
+ }
32577
32688
  }
32578
32689
 
32579
32690
  // src/commands/hookCmd.ts
32580
- import { spawn as spawn3 } from "node:child_process";
32691
+ import { spawn as spawn2 } from "node:child_process";
32581
32692
  import {
32582
32693
  chmodSync,
32583
- existsSync as existsSync10,
32694
+ existsSync as existsSync9,
32584
32695
  lstatSync,
32585
32696
  mkdtempSync as mkdtempSync2,
32586
32697
  mkdirSync as mkdirSync5,
32587
32698
  readdirSync as readdirSync2,
32588
32699
  readFileSync as readFileSync5,
32589
- realpathSync as realpathSync2,
32700
+ realpathSync as realpathSync4,
32590
32701
  rmSync as rmSync2,
32591
32702
  writeFileSync as writeFileSync5
32592
32703
  } from "node:fs";
32593
32704
  import { tmpdir as tmpdir2 } from "node:os";
32594
- import { basename, dirname as dirname6, join as join12 } from "node:path";
32705
+ import { basename, dirname as dirname6, join as join11 } from "node:path";
32595
32706
  import { createHash, randomBytes } from "node:crypto";
32596
32707
 
32597
32708
  // src/autoReindexTrigger.ts
@@ -32618,25 +32729,12 @@ function maybeTriggerAutoReindex(ctx) {
32618
32729
  }
32619
32730
 
32620
32731
  // src/autoSyncTrigger.ts
32621
- import { spawn as spawn2 } from "node:child_process";
32622
- import { existsSync as existsSync9, statSync } from "node:fs";
32623
- import { join as join11 } from "node:path";
32624
- function maybeTriggerAutoSync(ctx) {
32625
- if (process.env[CAVEAT_AUTO_SYNC_ENV] === "off") return;
32626
- const statePath = join11(ctx.caveatHome, "sync", ".last-autosync.json");
32627
- const debounceMs = Number(process.env.CAVEAT_AUTO_SYNC_DEBOUNCE_MS ?? AUTO_SYNC_DEBOUNCE_MS);
32628
- try {
32629
- if (existsSync9(statePath) && Date.now() - statSync(statePath).mtimeMs < debounceMs) return;
32630
- } catch {
32631
- }
32632
- const cliScript = process.argv[1];
32633
- if (!cliScript) throw new Error("current Caveat CLI script path is unavailable");
32634
- const child = spawn2(
32635
- process.execPath,
32636
- [...process.execArgv, "--disable-warning=ExperimentalWarning", cliScript, "hook", "autosync"],
32637
- { detached: true, stdio: "ignore", windowsHide: true }
32638
- );
32639
- child.unref();
32732
+ function maybeTriggerAutoSync(ctx, debounceMs = AUTO_SYNC_DEBOUNCE_MS) {
32733
+ triggerAutoSync({
32734
+ caveatHome: ctx.caveatHome,
32735
+ cliScript: process.argv[1] ?? "",
32736
+ debounceMs
32737
+ });
32640
32738
  }
32641
32739
 
32642
32740
  // src/commands/hookCmd.ts
@@ -32663,6 +32761,7 @@ function parsePayload(raw) {
32663
32761
  try {
32664
32762
  return JSON.parse(raw);
32665
32763
  } catch (err) {
32764
+ observeRuntimeError("CAVEAT.CLAUDE_HOOK_FAILED", { version: CAVEAT_VERSION });
32666
32765
  const msg = err instanceof Error ? err.message : String(err);
32667
32766
  process.stderr.write(`[caveat:hook] json parse error: ${msg}
32668
32767
  `);
@@ -32677,6 +32776,7 @@ function buildContextSafely() {
32677
32776
  try {
32678
32777
  return buildContext(silentLogger);
32679
32778
  } catch (err) {
32779
+ observeRuntimeError("CAVEAT.CLAUDE_HOOK_FAILED", { version: CAVEAT_VERSION });
32680
32780
  const msg = err instanceof Error ? err.message : String(err);
32681
32781
  process.stderr.write(`[caveat:hook] context error: ${msg}
32682
32782
  `);
@@ -32692,7 +32792,7 @@ function searchCaveatsSafely(input) {
32692
32792
  let hits;
32693
32793
  try {
32694
32794
  const ctx = buildContextSafely();
32695
- if (!ctx || !existsSync10(ctx.paths.dbPath)) return [];
32795
+ if (!ctx || !existsSync9(ctx.paths.dbPath)) return [];
32696
32796
  caveatHome = ctx.caveatHome;
32697
32797
  db = openDb({ path: ctx.paths.dbPath });
32698
32798
  const searchOptions = {
@@ -32700,6 +32800,7 @@ function searchCaveatsSafely(input) {
32700
32800
  };
32701
32801
  hits = inputs.length === 1 ? findCaveatsForHook(db, inputs[0], searchOptions) : findCaveatsForHookSegments(db, inputs, searchOptions);
32702
32802
  } catch (err) {
32803
+ observeRuntimeError("CAVEAT.CLAUDE_HOOK_FAILED", { version: CAVEAT_VERSION });
32703
32804
  const msg = err instanceof Error ? err.message : String(err);
32704
32805
  process.stderr.write(`[caveat:hook] search error: ${msg}
32705
32806
  `);
@@ -32709,6 +32810,7 @@ function searchCaveatsSafely(input) {
32709
32810
  try {
32710
32811
  markHit(db, hits);
32711
32812
  } catch (err) {
32813
+ observeRuntimeError("CAVEAT.CLAUDE_HOOK_FAILED", { version: CAVEAT_VERSION });
32712
32814
  const msg = err instanceof Error ? err.message : String(err);
32713
32815
  process.stderr.write(`[caveat:hook] markHit error: ${msg}
32714
32816
  `);
@@ -32717,6 +32819,7 @@ function searchCaveatsSafely(input) {
32717
32819
  try {
32718
32820
  logHookQueryMiss({ caveatHome, agent: "claude", surface: inputs[0].surface, query: queryForLog });
32719
32821
  } catch (err) {
32822
+ observeRuntimeError("CAVEAT.CLAUDE_HOOK_FAILED", { version: CAVEAT_VERSION });
32720
32823
  const msg = err instanceof Error ? err.message : String(err);
32721
32824
  process.stderr.write(`[caveat:hook] query log error: ${msg}
32722
32825
  `);
@@ -32797,7 +32900,7 @@ function stopSignalKey(signals, related) {
32797
32900
  return createHash("sha256").update(body).digest("hex");
32798
32901
  }
32799
32902
  function stopStatePath(caveatHome, sessionId) {
32800
- return join12(caveatHome, CLAUDE_STOP_STATE_DIR, `${sanitizeClaudeStateId(sessionId)}.txt`);
32903
+ return join11(caveatHome, CLAUDE_STOP_STATE_DIR, `${sanitizeClaudeStateId(sessionId)}.txt`);
32801
32904
  }
32802
32905
  function wasStopReminderQueued(caveatHome, sessionId, key) {
32803
32906
  const path = stopStatePath(caveatHome, sessionId);
@@ -32809,7 +32912,7 @@ function wasStopReminderQueued(caveatHome, sessionId, key) {
32809
32912
  }
32810
32913
  function markStopReminderQueued(caveatHome, sessionId, key) {
32811
32914
  const path = stopStatePath(caveatHome, sessionId);
32812
- mkdirSync5(join12(caveatHome, CLAUDE_STOP_STATE_DIR), { recursive: true });
32915
+ mkdirSync5(join11(caveatHome, CLAUDE_STOP_STATE_DIR), { recursive: true });
32813
32916
  writeFileSync5(path, key, "utf-8");
32814
32917
  }
32815
32918
  function queueStopForSession(sessionId, signals, related) {
@@ -32895,9 +32998,9 @@ function spawnWorker(job) {
32895
32998
  try {
32896
32999
  root = workerRoot();
32897
33000
  sweepStaleWorkerDirs(Date.now(), root);
32898
- workDir = mkdtempSync2(join12(root, "job-"));
33001
+ workDir = mkdtempSync2(join11(root, "job-"));
32899
33002
  chmodSync(workDir, 448);
32900
- workFile = join12(workDir, `${randomBytes(4).toString("hex")}.json`);
33003
+ workFile = join11(workDir, `${randomBytes(4).toString("hex")}.json`);
32901
33004
  writeFileSync5(workFile, JSON.stringify({ ...job, schemaVersion: "caveat-worker-job/v2" }), { encoding: "utf-8", mode: 384, flag: "wx" });
32902
33005
  } catch (err) {
32903
33006
  const msg = err instanceof Error ? err.message : String(err);
@@ -32912,7 +33015,7 @@ function spawnWorker(job) {
32912
33015
  return;
32913
33016
  }
32914
33017
  try {
32915
- const child = spawn3(
33018
+ const child = spawn2(
32916
33019
  process.execPath,
32917
33020
  ["--disable-warning=ExperimentalWarning", cliScript, "hook", "worker", workFile],
32918
33021
  { detached: true, stdio: "ignore", windowsHide: true }
@@ -32976,8 +33079,8 @@ function isOwnedWorkerDir(path, root = workerRoot()) {
32976
33079
  try {
32977
33080
  const inputStat = lstatSync(path);
32978
33081
  if (inputStat.isSymbolicLink()) return false;
32979
- const tmpRoot = realpathSync2(root);
32980
- const resolved = realpathSync2(path);
33082
+ const tmpRoot = realpathSync4(root);
33083
+ const resolved = realpathSync4(path);
32981
33084
  const stat = lstatSync(resolved);
32982
33085
  const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
32983
33086
  return dirname6(resolved) === tmpRoot && basename(resolved).startsWith("job-") && stat.isDirectory() && !stat.isSymbolicLink() && hasPrivateOwnership(stat, uid);
@@ -32995,7 +33098,7 @@ function sweepStaleWorkerDirs(now = Date.now(), root = workerRoot()) {
32995
33098
  }
32996
33099
  for (const entry of entries) {
32997
33100
  if (!entry.startsWith("job-")) continue;
32998
- const path = join12(root, entry);
33101
+ const path = join11(root, entry);
32999
33102
  try {
33000
33103
  if (!isOwnedWorkerDir(path, root)) continue;
33001
33104
  const stat = lstatSync(path);
@@ -33007,12 +33110,12 @@ function sweepStaleWorkerDirs(now = Date.now(), root = workerRoot()) {
33007
33110
  }
33008
33111
  }
33009
33112
  function workerRoot(base = tmpdir2()) {
33010
- const root = join12(base, WORKER_ROOT);
33113
+ const root = join11(base, WORKER_ROOT);
33011
33114
  mkdirSync5(root, { recursive: true, mode: 448 });
33012
33115
  const stat = lstatSync(root);
33013
33116
  const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
33014
33117
  if (!stat.isDirectory() || stat.isSymbolicLink() || !hasPrivateOwnership(stat, uid)) throw new Error("worker root is unsafe");
33015
- const marker = join12(root, WORKER_MARKER);
33118
+ const marker = join11(root, WORKER_MARKER);
33016
33119
  try {
33017
33120
  writeFileSync5(marker, "caveat-worker/v1\n", { mode: 384, flag: "wx" });
33018
33121
  } catch (error51) {
@@ -33025,7 +33128,7 @@ function workerRoot(base = tmpdir2()) {
33025
33128
  function isStaleWorkerJobDir(path) {
33026
33129
  const entries = readdirSync2(path);
33027
33130
  if (entries.length !== 1 || !entries[0].endsWith(".json")) return false;
33028
- const file2 = join12(path, entries[0]);
33131
+ const file2 = join11(path, entries[0]);
33029
33132
  const stat = lstatSync(file2);
33030
33133
  const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
33031
33134
  if (!stat.isFile() || stat.isSymbolicLink() || !hasPrivateOwnership(stat, uid)) return false;
@@ -33051,7 +33154,7 @@ function isKnownStaleWorkerJob(value) {
33051
33154
  }
33052
33155
  function writeLastReindex(caveatHome, value) {
33053
33156
  try {
33054
- writeFileSync5(join12(caveatHome, "index", ".last-reindex.json"), JSON.stringify(value), "utf-8");
33157
+ writeFileSync5(join11(caveatHome, "index", ".last-reindex.json"), JSON.stringify(value), "utf-8");
33055
33158
  } catch (err) {
33056
33159
  const msg = err instanceof Error ? err.message : String(err);
33057
33160
  process.stderr.write(`[caveat:hook] reindex status write error: ${msg}
@@ -33067,7 +33170,7 @@ async function runReindexWorker() {
33067
33170
  return;
33068
33171
  }
33069
33172
  const ctx = buildContextSafely();
33070
- if (!ctx || !existsSync10(ctx.paths.dbPath)) {
33173
+ if (!ctx || !existsSync9(ctx.paths.dbPath)) {
33071
33174
  process.stderr.write("[caveat:hook] auto reindex skipped: index database does not exist\n");
33072
33175
  return;
33073
33176
  }
@@ -33135,7 +33238,7 @@ function buildToolErrorReminder(job, hits) {
33135
33238
  const mode = hookCodexSidecarMode();
33136
33239
  if (mode === "off") return base;
33137
33240
  const projectRoot = process.cwd();
33138
- const hasSidecarConfig = existsSync10(join12(projectRoot, ".codex-sidecar.yml"));
33241
+ const hasSidecarConfig = existsSync9(join11(projectRoot, ".codex-sidecar.yml"));
33139
33242
  if (mode === "auto" && !hasSidecarConfig) return base;
33140
33243
  const advisory = runCodexSidecarAdvisory({
33141
33244
  searchText: job.failureText,
@@ -33171,7 +33274,7 @@ function buildStopReminder(signals, related) {
33171
33274
  const mode = hookCodexSidecarMode();
33172
33275
  if (mode === "off") return base;
33173
33276
  const projectRoot = process.cwd();
33174
- const hasSidecarConfig = existsSync10(join12(projectRoot, ".codex-sidecar.yml"));
33277
+ const hasSidecarConfig = existsSync9(join11(projectRoot, ".codex-sidecar.yml"));
33175
33278
  if (mode === "auto" && !hasSidecarConfig) return base;
33176
33279
  const advisory = runCodexSidecarAdvisory({
33177
33280
  searchText: struggleSearchText(signals),
@@ -33314,10 +33417,10 @@ async function runHook(name, arg) {
33314
33417
  }
33315
33418
 
33316
33419
  // src/commands/codexHookCmd.ts
33317
- import { spawn as spawn4, spawnSync as spawnSync5 } from "node:child_process";
33318
- import { existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync6 } from "node:fs";
33420
+ import { spawn as spawn3, spawnSync as spawnSync5 } from "node:child_process";
33421
+ import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync6 } from "node:fs";
33319
33422
  import { homedir as homedir3, tmpdir as tmpdir3 } from "node:os";
33320
- import { join as join13 } from "node:path";
33423
+ import { join as join12 } from "node:path";
33321
33424
  import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
33322
33425
  var silentLogger2 = {
33323
33426
  info: () => {
@@ -33342,6 +33445,7 @@ function parsePayload2(raw) {
33342
33445
  try {
33343
33446
  return JSON.parse(raw);
33344
33447
  } catch (err) {
33448
+ observeRuntimeError("CAVEAT.CODEX_HOOK_FAILED", { version: CAVEAT_VERSION });
33345
33449
  const msg = err instanceof Error ? err.message : String(err);
33346
33450
  process.stderr.write(`[caveat:codex-hook] json parse error: ${msg}
33347
33451
  `);
@@ -33352,6 +33456,7 @@ function buildContextSafely2() {
33352
33456
  try {
33353
33457
  return buildContext(silentLogger2);
33354
33458
  } catch (err) {
33459
+ observeRuntimeError("CAVEAT.CODEX_HOOK_FAILED", { version: CAVEAT_VERSION });
33355
33460
  const msg = err instanceof Error ? err.message : String(err);
33356
33461
  process.stderr.write(`[caveat:codex-hook] context error: ${msg}
33357
33462
  `);
@@ -33367,7 +33472,7 @@ function searchCaveatsSafely2(input) {
33367
33472
  let hits;
33368
33473
  try {
33369
33474
  const ctx = buildContextSafely2();
33370
- if (!ctx || !existsSync11(ctx.paths.dbPath)) return [];
33475
+ if (!ctx || !existsSync10(ctx.paths.dbPath)) return [];
33371
33476
  caveatHome = ctx.caveatHome;
33372
33477
  db = openDb({ path: ctx.paths.dbPath });
33373
33478
  const searchOptions = {
@@ -33375,6 +33480,7 @@ function searchCaveatsSafely2(input) {
33375
33480
  };
33376
33481
  hits = inputs.length === 1 ? findCaveatsForHook(db, inputs[0], searchOptions) : findCaveatsForHookSegments(db, inputs, searchOptions);
33377
33482
  } catch (err) {
33483
+ observeRuntimeError("CAVEAT.CODEX_HOOK_FAILED", { version: CAVEAT_VERSION });
33378
33484
  const msg = err instanceof Error ? err.message : String(err);
33379
33485
  process.stderr.write(`[caveat:codex-hook] search error: ${msg}
33380
33486
  `);
@@ -33384,6 +33490,7 @@ function searchCaveatsSafely2(input) {
33384
33490
  try {
33385
33491
  markHit(db, hits);
33386
33492
  } catch (err) {
33493
+ observeRuntimeError("CAVEAT.CODEX_HOOK_FAILED", { version: CAVEAT_VERSION });
33387
33494
  const msg = err instanceof Error ? err.message : String(err);
33388
33495
  process.stderr.write(`[caveat:codex-hook] markHit error: ${msg}
33389
33496
  `);
@@ -33392,6 +33499,7 @@ function searchCaveatsSafely2(input) {
33392
33499
  try {
33393
33500
  logHookQueryMiss({ caveatHome, agent: "codex", surface: inputs[0].surface, query: queryForLog });
33394
33501
  } catch (err) {
33502
+ observeRuntimeError("CAVEAT.CODEX_HOOK_FAILED", { version: CAVEAT_VERSION });
33395
33503
  const msg = err instanceof Error ? err.message : String(err);
33396
33504
  process.stderr.write(`[caveat:codex-hook] query log error: ${msg}
33397
33505
  `);
@@ -33448,7 +33556,7 @@ function processExitCodeFromText(text) {
33448
33556
  return m ? Number(m[1]) : null;
33449
33557
  }
33450
33558
  function transcriptToolOutput(transcriptPath, toolUseId) {
33451
- if (!transcriptPath || !toolUseId || !existsSync11(transcriptPath)) return null;
33559
+ if (!transcriptPath || !toolUseId || !existsSync10(transcriptPath)) return null;
33452
33560
  let raw = "";
33453
33561
  try {
33454
33562
  raw = readFileSync6(transcriptPath, "utf-8");
@@ -33600,7 +33708,7 @@ function stopSignalKey2(signals, related) {
33600
33708
  return createHash2("sha256").update(body).digest("hex");
33601
33709
  }
33602
33710
  function stopStatePath2(caveatHome, sessionId) {
33603
- return join13(caveatHome, CODEX_STOP_STATE_DIR, `${sanitizeCodexStateId(sessionId)}.txt`);
33711
+ return join12(caveatHome, CODEX_STOP_STATE_DIR, `${sanitizeCodexStateId(sessionId)}.txt`);
33604
33712
  }
33605
33713
  function wasStopReminderQueued2(caveatHome, sessionId, key) {
33606
33714
  const path = stopStatePath2(caveatHome, sessionId);
@@ -33612,7 +33720,7 @@ function wasStopReminderQueued2(caveatHome, sessionId, key) {
33612
33720
  }
33613
33721
  function markStopReminderQueued2(caveatHome, sessionId, key) {
33614
33722
  const path = stopStatePath2(caveatHome, sessionId);
33615
- mkdirSync6(join13(caveatHome, CODEX_STOP_STATE_DIR), { recursive: true });
33723
+ mkdirSync6(join12(caveatHome, CODEX_STOP_STATE_DIR), { recursive: true });
33616
33724
  writeFileSync6(path, key, "utf-8");
33617
33725
  }
33618
33726
  function queueStopForSession2(sessionId, signals, related) {
@@ -33707,7 +33815,7 @@ async function runCodexWorker(workFile) {
33707
33815
  await processCodexWorkerJob(job);
33708
33816
  process.exit(0);
33709
33817
  }
33710
- function runDiagnostics(codexHome = process.env.CODEX_HOME ?? join13(homedir3(), ".codex")) {
33818
+ function runDiagnostics(codexHome = process.env.CODEX_HOME ?? join12(homedir3(), ".codex")) {
33711
33819
  const features = spawnSync5("codex", ["features", "list"], {
33712
33820
  encoding: "utf-8",
33713
33821
  maxBuffer: 1024 * 1024,
@@ -33816,9 +33924,9 @@ async function runCodexHook(name, arg) {
33816
33924
  }
33817
33925
 
33818
33926
  // src/commands/pull.ts
33819
- import { existsSync as existsSync12 } from "node:fs";
33927
+ import { existsSync as existsSync11 } from "node:fs";
33820
33928
  async function runPull(ctx) {
33821
- const hasCommunityDir = existsSync12(ctx.paths.communityDir);
33929
+ const hasCommunityDir = existsSync11(ctx.paths.communityDir);
33822
33930
  if (!hasCommunityDir) {
33823
33931
  ctx.logger.info(
33824
33932
  "no community repos yet \u2014 add one with `caveat community add <github-url>`."
@@ -33863,6 +33971,11 @@ async function defaultPrivateRepoUrl(opts, deps) {
33863
33971
  });
33864
33972
  }
33865
33973
  async function runSync(ctx, opts, dependencies = {}) {
33974
+ if (opts.repo && (opts.init === void 0 || opts.init === false)) {
33975
+ ctx.logger.error("--repo requires --init");
33976
+ process.exitCode = 1;
33977
+ return;
33978
+ }
33866
33979
  try {
33867
33980
  const ghRunner = dependencies.ghRunner ?? runGh;
33868
33981
  const isTty = dependencies.isTty ?? (() => Boolean(process.stdin.isTTY));
@@ -33883,7 +33996,6 @@ async function runSync(ctx, opts, dependencies = {}) {
33883
33996
  );
33884
33997
  return;
33885
33998
  }
33886
- if (opts.repo) throw new Error("--repo requires --init");
33887
33999
  const result = await syncOwn({
33888
34000
  ownDir: ctx.paths.knowledgeRepo,
33889
34001
  caveatHome: ctx.caveatHome,
@@ -33905,6 +34017,7 @@ async function runSync(ctx, opts, dependencies = {}) {
33905
34017
  }
33906
34018
  }
33907
34019
  } catch (err) {
34020
+ observeRuntimeError("CAVEAT.SYNC_FAILED", { version: CAVEAT_VERSION });
33908
34021
  const message = err instanceof Error ? err.message : String(err);
33909
34022
  ctx.logger.error(message);
33910
34023
  process.exitCode = 1;
@@ -33913,9 +34026,9 @@ async function runSync(ctx, opts, dependencies = {}) {
33913
34026
 
33914
34027
  // src/commands/codexSidecar.ts
33915
34028
  import { spawnSync as spawnSync6 } from "node:child_process";
33916
- import { closeSync, constants, fstatSync, lstatSync as lstatSync2, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync3, openSync, readSync as readSync2, realpathSync as realpathSync3, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "node:fs";
34029
+ import { closeSync, constants as constants3, fstatSync, lstatSync as lstatSync2, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync3, openSync, readSync as readSync2, realpathSync as realpathSync5, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "node:fs";
33917
34030
  import { tmpdir as tmpdir4 } from "node:os";
33918
- import { basename as basename2, dirname as dirname7, join as join14 } from "node:path";
34031
+ import { basename as basename2, dirname as dirname7, join as join13 } from "node:path";
33919
34032
  import { cwd, exit } from "node:process";
33920
34033
  function runCodexSidecarDiagnostics(logger, opts) {
33921
34034
  const plan = buildCodexSidecarDiagnosticsCommand({
@@ -33947,9 +34060,9 @@ function runCodexSidecarWithCaveats(ctx, workflow, prompt, opts) {
33947
34060
  process.stdout.write(JSON.stringify({ status: "skipped", decision }, null, 2) + "\n");
33948
34061
  exit(0);
33949
34062
  }
33950
- const contextDir = mkdtempSync3(join14(tmpdir4(), "caveat-sidecar-context-"));
33951
- const contextFile = join14(contextDir, "context.json");
33952
- let status = 1;
34063
+ const contextDir = mkdtempSync3(join13(tmpdir4(), "caveat-sidecar-context-"));
34064
+ const contextFile = join13(contextDir, "context.json");
34065
+ let status2 = 1;
33953
34066
  try {
33954
34067
  const blocks = collectCaveatContextBlocks(ctx, {
33955
34068
  query: opts.query ?? prompt ?? "",
@@ -33967,11 +34080,11 @@ function runCodexSidecarWithCaveats(ctx, workflow, prompt, opts) {
33967
34080
  contextFile,
33968
34081
  cli: cliSpec(opts)
33969
34082
  });
33970
- status = executePlan(ctx.logger, plan.command, plan.args, { saveResult: opts.saveResult });
34083
+ status2 = executePlan(ctx.logger, plan.command, plan.args, { saveResult: opts.saveResult });
33971
34084
  } finally {
33972
34085
  rmSync3(contextDir, { recursive: true, force: true });
33973
34086
  }
33974
- exit(status);
34087
+ exit(status2);
33975
34088
  }
33976
34089
  var MAX_ADDITIONAL_CONTEXT_BYTES = 4096;
33977
34090
  function readHookSignalAdditionalContextFile(path, testProbe) {
@@ -33981,7 +34094,7 @@ function readHookSignalAdditionalContextFile(path, testProbe) {
33981
34094
  const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
33982
34095
  assertPrivateRegular(before, uid, platform);
33983
34096
  testProbe?.afterLstat?.();
33984
- const fd = openSync(path, constants.O_RDONLY | constants.O_NONBLOCK | (constants.O_NOFOLLOW ?? 0));
34097
+ const fd = openSync(path, constants3.O_RDONLY | constants3.O_NONBLOCK | (constants3.O_NOFOLLOW ?? 0));
33985
34098
  let raw;
33986
34099
  try {
33987
34100
  const opened = fstatSync(fd);
@@ -34020,8 +34133,8 @@ function assertWindowsPrivateTempContainer(path, platform) {
34020
34133
  if (platform !== "win32") return;
34021
34134
  const parent = dirname7(path);
34022
34135
  const parentStat = lstatSync2(parent);
34023
- const resolvedParent = realpathSync3(parent);
34024
- const resolvedTemp = realpathSync3(tmpdir4());
34136
+ const resolvedParent = realpathSync5(parent);
34137
+ const resolvedTemp = realpathSync5(tmpdir4());
34025
34138
  if (parentStat.isSymbolicLink() || !parentStat.isDirectory() || dirname7(resolvedParent) !== resolvedTemp || !basename2(resolvedParent).startsWith("caveat-")) {
34026
34139
  throw new Error("additional context file must be inside a reserved per-user Caveat temporary directory");
34027
34140
  }
@@ -34198,12 +34311,200 @@ function runCommunityRemove(ctx, handle, opts) {
34198
34311
  }
34199
34312
  }
34200
34313
 
34314
+ // src/commands/factoryDiagnostics.ts
34315
+ import { execFileSync } from "node:child_process";
34316
+ import { existsSync as existsSync12, readFileSync as readFileSync7 } from "node:fs";
34317
+ import { join as join14 } from "node:path";
34318
+ import { DatabaseSync } from "node:sqlite";
34319
+ import { parse as parseToml2 } from "smol-toml";
34320
+ var status = (ok, reason) => ({ status: ok ? "ready" : "not_ready", reason_code: ok ? "ready" : reason });
34321
+ var unverified = (reason) => ({ status: "unverified", reason_code: reason });
34322
+ function hook(present) {
34323
+ return status(present, "not_installed");
34324
+ }
34325
+ function isRecord2(value) {
34326
+ return typeof value === "object" && value !== null && !Array.isArray(value);
34327
+ }
34328
+ function claudeRegistration(home, nodePath, cliScriptPath) {
34329
+ const path = join14(home, ".claude.json");
34330
+ if (!existsSync12(path)) return status(false, "not_registered");
34331
+ try {
34332
+ const value = JSON.parse(readFileSync7(path, "utf8"));
34333
+ if (!isRecord2(value) || !isRecord2(value.mcpServers)) return status(false, "not_registered");
34334
+ return status(isCaveatClaudeMcpRegistration(value.mcpServers.caveat, nodePath, cliScriptPath), "not_registered");
34335
+ } catch {
34336
+ return unverified("config_unreadable");
34337
+ }
34338
+ }
34339
+ function claudeHooks(home, nodePath, cliScriptPath) {
34340
+ try {
34341
+ const settings = JSON.parse(readFileSync7(join14(home, ".claude", "settings.json"), "utf8"));
34342
+ const present = (event, subcommand) => settings.hooks?.[event]?.some((entry) => entry.hooks?.some((item) => typeof item.command === "string" && isCanonicalCaveatClaudeHookCommand(item.command, subcommand, nodePath, cliScriptPath))) ?? false;
34343
+ return { user_prompt_submit: hook(present("UserPromptSubmit", "user-prompt-submit")), post_tool_use: hook(present("PostToolUse", "post-tool-use")), post_tool_use_failure: hook(present("PostToolUseFailure", "post-tool-use")), stop: hook(present("Stop", "stop")) };
34344
+ } catch {
34345
+ const bad = unverified("config_unreadable");
34346
+ return { user_prompt_submit: { ...bad }, post_tool_use: { ...bad }, post_tool_use_failure: { ...bad }, stop: { ...bad } };
34347
+ }
34348
+ }
34349
+ var EXPECTED_SEARCH_SQL = /* @__PURE__ */ new Map([
34350
+ ["entries_fts", "create virtual table entries_fts using fts5( id unindexed, title, body, tags, content='entries', content_rowid='rowid', tokenize='trigram' )"],
34351
+ ["entries_ai", "create trigger entries_ai after insert on entries begin insert into entries_fts(rowid, id, title, body, tags) values (new.rowid, new.id, new.title, new.body, new.tags); end"],
34352
+ ["entries_ad", "create trigger entries_ad after delete on entries begin insert into entries_fts(entries_fts, rowid, id, title, body, tags) values('delete', old.rowid, old.id, old.title, old.body, old.tags); end"],
34353
+ ["entries_au", "create trigger entries_au after update on entries begin insert into entries_fts(entries_fts, rowid, id, title, body, tags) values('delete', old.rowid, old.id, old.title, old.body, old.tags); insert into entries_fts(rowid, id, title, body, tags) values (new.rowid, new.id, new.title, new.body, new.tags); end"]
34354
+ ]);
34355
+ function strictSearchSchema(db) {
34356
+ const normalize = (sql) => (sql ?? "").toLowerCase().replace(/\s+/g, " ");
34357
+ const objects = db.prepare("SELECT name, sql FROM sqlite_master WHERE name = 'entries_fts' OR (type = 'trigger' AND tbl_name = 'entries')").all();
34358
+ if (objects.length !== EXPECTED_SEARCH_SQL.size || objects.some((object3) => normalize(object3.sql) !== EXPECTED_SEARCH_SQL.get(object3.name))) return false;
34359
+ const columns = db.prepare("PRAGMA table_xinfo(entries_fts)").all();
34360
+ return columns.map((column) => `${column.name}:${column.hidden}`).join(",") === "id:0,title:0,body:0,tags:0,entries_fts:1,rank:1";
34361
+ }
34362
+ function database(path) {
34363
+ if (!existsSync12(path)) return { status: "not_ready", reason_code: "missing", schema_version: null, supported_schema_version: 3, migration_status: "unverified" };
34364
+ try {
34365
+ const db = new DatabaseSync(path, { readOnly: true });
34366
+ try {
34367
+ const row = db.prepare("PRAGMA user_version").get();
34368
+ const columns = db.prepare("PRAGMA table_info(entries)").all().map((entry) => entry.name);
34369
+ const expectedColumns = ["rowid", "id", "source", "path", "title", "body", "frontmatter_json", "tags", "confidence", "visibility", "file_mtime", "indexed_at", "last_hit_at", "topical_text", "symptom_text"];
34370
+ const objects = db.prepare("SELECT type, name, tbl_name, sql FROM sqlite_master WHERE name = 'entries_fts' OR (type = 'trigger' AND tbl_name = 'entries')").all();
34371
+ const normalized = (sql) => (sql ?? "").toLowerCase().replace(/\s+/g, " ");
34372
+ const ftsSql = normalized(objects.find((entry) => entry.type === "table" && entry.name === "entries_fts")?.sql ?? null);
34373
+ const fts = ftsSql.startsWith("create virtual table entries_fts using fts5(") && ftsSql.includes("content='entries'") && ftsSql.includes("content_rowid='rowid'") && ftsSql.includes("tokenize='trigram'");
34374
+ const triggers = new Map(objects.filter((entry) => entry.type === "trigger").map((entry) => [entry.name, normalized(entry.sql)]));
34375
+ const triggerShape = triggers.size === 3 && triggers.get("entries_ai")?.includes("after insert on entries") && triggers.get("entries_ai")?.includes("insert into entries_fts") && triggers.get("entries_ad")?.includes("after delete on entries") && triggers.get("entries_ad")?.includes("values('delete'") && triggers.get("entries_au")?.includes("after update on entries") && triggers.get("entries_au")?.includes("values('delete'") && (triggers.get("entries_au")?.match(/insert into entries_fts/g)?.length ?? 0) === 2;
34376
+ const indexes = db.prepare("PRAGMA index_list(entries)").all();
34377
+ const uniqueSourceId = indexes.some((index) => index.unique === 1 && db.prepare(`PRAGMA index_info(${JSON.stringify(index.name)})`).all().map((part) => part.name).join(",") === "source,id");
34378
+ const current = row.user_version === 3 && columns.join(",") === expectedColumns.join(",") && fts && Boolean(triggerShape) && uniqueSourceId && strictSearchSchema(db);
34379
+ return { status: current ? "ready" : "not_ready", reason_code: current ? "ready" : "schema_contract_mismatch", schema_version: row.user_version, supported_schema_version: 3, migration_status: current ? "current" : "failed" };
34380
+ } finally {
34381
+ db.close();
34382
+ }
34383
+ } catch {
34384
+ return { status: "unverified", reason_code: "open_failed", schema_version: null, supported_schema_version: 3, migration_status: "unverified" };
34385
+ }
34386
+ }
34387
+ function codexFeature(codexHome) {
34388
+ const path = join14(codexHome, "config.toml");
34389
+ if (!existsSync12(path)) return status(false, "feature_disabled");
34390
+ try {
34391
+ const config2 = parseToml2(readFileSync7(path, "utf8"));
34392
+ if (!isRecord2(config2.features)) return status(false, "feature_disabled");
34393
+ const features = config2.features;
34394
+ return status(features.hooks === true && features.codex_hooks === void 0, "feature_disabled");
34395
+ } catch {
34396
+ return unverified("config_unreadable");
34397
+ }
34398
+ }
34399
+ function codexHooks(codexHome, nodePath, cliScriptPath) {
34400
+ const value = JSON.parse(readFileSync7(join14(codexHome, "hooks.json"), "utf8"));
34401
+ if (!isRecord2(value) || !isRecord2(value.hooks)) throw Error("config_unreadable");
34402
+ const hooks = value.hooks;
34403
+ const present = (event, subcommand) => Array.isArray(hooks[event]) && hooks[event].some((entry) => isRecord2(entry) && Array.isArray(entry.hooks) && entry.hooks.some((item) => isRecord2(item) && typeof item.command === "string" && isCanonicalCaveatCodexHookCommand(item.command, subcommand, nodePath, cliScriptPath)));
34404
+ return { userPromptSubmit: present("UserPromptSubmit", "user-prompt-submit"), postToolUse: present("PostToolUse", "post-tool-use"), stop: present("Stop", "stop") };
34405
+ }
34406
+ function sync(own) {
34407
+ try {
34408
+ execFileSync("git", ["-C", own, "rev-parse", "--is-inside-work-tree"], { stdio: "ignore" });
34409
+ } catch {
34410
+ return status(false, "not_git_worktree");
34411
+ }
34412
+ try {
34413
+ execFileSync("git", ["-C", own, "remote", "get-url", "origin"], { stdio: "ignore" });
34414
+ } catch {
34415
+ return status(false, "origin_missing");
34416
+ }
34417
+ try {
34418
+ const dirty = execFileSync("git", ["-C", own, "status", "--porcelain=v1", "--untracked-files=normal"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 5e3, env: { ...process.env, GIT_OPTIONAL_LOCKS: "0" } }).trim();
34419
+ if (dirty) return status(false, "worktree_dirty");
34420
+ const upstream = execFileSync("git", ["-C", own, "rev-parse", "--symbolic-full-name", "@{upstream}"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 5e3 }).trim();
34421
+ if (!upstream.startsWith("refs/remotes/origin/")) return status(false, "upstream_not_origin");
34422
+ const remoteRef = `refs/heads/${upstream.slice("refs/remotes/origin/".length)}`;
34423
+ const remote = execFileSync("git", ["-C", own, "ls-remote", "--exit-code", "origin", remoteRef], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 1e4, maxBuffer: 16384 }).trim().split(/\s+/)[0];
34424
+ const head = execFileSync("git", ["-C", own, "rev-parse", "HEAD"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 5e3 }).trim();
34425
+ if (!/^[0-9a-f]{40}$/.test(remote ?? "") || !/^[0-9a-f]{40}$/.test(head)) return unverified("sync_hash_unparseable");
34426
+ if (remote !== head) return status(false, "remote_mismatch");
34427
+ const counts = execFileSync("git", ["-C", own, "rev-list", "--left-right", "--count", "@{upstream}...HEAD"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 5e3 }).trim().split(/\s+/).map(Number);
34428
+ if (counts.length !== 2 || counts.some((value) => !Number.isSafeInteger(value) || value < 0)) return unverified("sync_count_unparseable");
34429
+ if (counts[0] === 0 && counts[1] === 0) return status(true, "ready");
34430
+ return status(false, counts[0] && counts[1] ? "diverged" : counts[0] ? "behind" : "ahead");
34431
+ } catch {
34432
+ return unverified("upstream_unavailable");
34433
+ }
34434
+ }
34435
+ function factoryDiagnostics(ctx, codexHome = process.env.CODEX_HOME ?? join14(ctx.userHome, ".codex")) {
34436
+ const nodePath = process.execPath;
34437
+ const cliScriptPath = process.argv[1] ?? "";
34438
+ const db = database(ctx.paths.dbPath);
34439
+ const feature = codexFeature(codexHome);
34440
+ let installedCodexHooks = null;
34441
+ try {
34442
+ installedCodexHooks = codexHooks(codexHome, nodePath, cliScriptPath);
34443
+ } catch {
34444
+ }
34445
+ const codexHook2 = (present) => present === void 0 ? unverified("config_unreadable") : !present ? hook(false) : feature.status === "ready" ? hook(true) : { ...feature };
34446
+ const output = { schema: "caveat.native_factory_diagnostics.v1", product: "caveat", version: CAVEAT_VERSION, overall: { status: "unverified" }, database: db, sync: sync(ctx.paths.knowledgeRepo), connectors: { claude: { status: "unverified", mcp: claudeRegistration(ctx.userHome, nodePath, cliScriptPath), hooks: claudeHooks(ctx.userHome, nodePath, cliScriptPath) }, codex: { status: "unverified", hooks: { user_prompt_submit: codexHook2(installedCodexHooks?.userPromptSubmit), post_tool_use: codexHook2(installedCodexHooks?.postToolUse), stop: codexHook2(installedCodexHooks?.stop) } } } };
34447
+ const aggregate = (all) => all.includes("not_ready") ? "not_ready" : all.includes("unverified") ? "unverified" : "ready";
34448
+ const connectorStatus = (connector) => aggregate([...Object.values(connector.hooks), ...connector.mcp ? [connector.mcp] : []].map((v) => v.status));
34449
+ output.connectors.claude.status = connectorStatus(output.connectors.claude);
34450
+ output.connectors.codex.status = connectorStatus(output.connectors.codex);
34451
+ const statuses = [output.database.status, output.sync.status, output.connectors.claude.status, output.connectors.codex.status];
34452
+ output.overall.status = aggregate(statuses);
34453
+ return output;
34454
+ }
34455
+
34456
+ // src/commands/runtimeErrors.ts
34457
+ function runRuntimeErrors(action, value, opts = {}) {
34458
+ const runtime = { version: CAVEAT_VERSION };
34459
+ if (action === "snapshot") return runtimeErrorsSnapshot(opts.afterCursor ?? 0, opts.limit ?? 256, runtime);
34460
+ if (action === "diagnostics") return runtimeErrorsDiagnostics(runtime);
34461
+ if (action === "ack") return acknowledgeRuntimeErrors(parseCursor(value), runtime);
34462
+ if (action === "resolve") return setRuntimeErrorStatus(value ?? "", "resolved", runtime);
34463
+ if (action === "reopen") return setRuntimeErrorStatus(value ?? "", "open", runtime);
34464
+ if (action === "compact") return compactRuntimeErrors(runtime);
34465
+ throw new Error("unknown_runtime_errors_action");
34466
+ }
34467
+ function parseCursor(value) {
34468
+ if (!value || !/^(?:0|[1-9][0-9]*)$/.test(value)) throw Error("invalid_cursor");
34469
+ const parsed = Number(value);
34470
+ if (!Number.isSafeInteger(parsed)) throw Error("invalid_cursor");
34471
+ return parsed;
34472
+ }
34473
+
34201
34474
  // src/index.ts
34202
34475
  var program = new Command();
34203
34476
  function collectRepeatable(value, previous) {
34204
34477
  return [...previous, value];
34205
34478
  }
34206
34479
  program.name("caveat").description("External spec gotcha knowledge base CLI").version(CAVEAT_VERSION);
34480
+ program.command("factory-diagnostics").description("Emit read-only factory diagnostics").requiredOption("--json", "emit the versioned JSON contract").action((opts) => {
34481
+ const output = factoryDiagnostics(buildContext(stdoutLogger));
34482
+ process.stdout.write(`${JSON.stringify(output)}
34483
+ `);
34484
+ if (output.overall.status !== "ready") process.exitCode = 1;
34485
+ });
34486
+ var runtimeErrors = program.command("runtime-errors").description("Inspect Caveat opt-in runtime errors");
34487
+ var parseLimit = (value) => {
34488
+ const parsed = parseCursor(value);
34489
+ if (parsed < 1 || parsed > 256) throw Error("invalid_limit");
34490
+ return parsed;
34491
+ };
34492
+ runtimeErrors.command("snapshot").requiredOption("--json", "emit JSON").option("--after-cursor <n>", "cursor", parseCursor, 0).option("--limit <n>", "limit", parseLimit, 256).action((opts) => {
34493
+ process.stdout.write(`${JSON.stringify(runRuntimeErrors("snapshot", void 0, opts))}
34494
+ `);
34495
+ });
34496
+ for (const action of ["diagnostics", "compact"]) runtimeErrors.command(action).requiredOption("--json", "emit JSON").action(() => {
34497
+ process.stdout.write(`${JSON.stringify(runRuntimeErrors(action))}
34498
+ `);
34499
+ });
34500
+ runtimeErrors.command("ack <cursor>").requiredOption("--json", "emit JSON").action((cursor) => {
34501
+ process.stdout.write(`${JSON.stringify(runRuntimeErrors("ack", cursor))}
34502
+ `);
34503
+ });
34504
+ for (const action of ["resolve", "reopen"]) runtimeErrors.command(`${action} <fingerprint>`).requiredOption("--json", "emit JSON").action((fingerprint) => {
34505
+ process.stdout.write(`${JSON.stringify(runRuntimeErrors(action, fingerprint))}
34506
+ `);
34507
+ });
34207
34508
  program.command("init").description(
34208
34509
  "Initialize ~/.caveatrc.json, ~/.caveat/, and register Claude Code integration. Add knowledge sources later with `caveat community add <github-url>`."
34209
34510
  ).option("--skip-claude", "skip Claude Code MCP + hook registration", false).option("--sync [url]", "initialize private sync (optionally with its URL)").option("--publish-target [url]", "configure the sealed public mirror target").option("--yes", "approve creating conventional GitHub repositories", false).option("--skip-codex-hook", "skip Codex hook installation", false).option("--dry-run", "show planned changes without writing", false).option(