caveat-cli 0.17.8 → 0.19.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
@@ -7,7 +7,6 @@ import {
7
7
  CAVEAT_AUTO_SYNC_ENV,
8
8
  KNOWLEDGE_GITIGNORE,
9
9
  PublishScanError,
10
- SyncError,
11
10
  __commonJS,
12
11
  __export,
13
12
  __toESM,
@@ -76,7 +75,7 @@ import {
76
75
  userPromptSubmitReminderText,
77
76
  writeDigestMarker,
78
77
  writeUserConfigPatch
79
- } from "./chunk-ZBHCOA6R.js";
78
+ } from "./chunk-ULK7SZG6.js";
80
79
 
81
80
  // ../../node_modules/.pnpm/ajv@8.18.0/node_modules/ajv/dist/compile/codegen/code.js
82
81
  var require_code = __commonJS({
@@ -206,10 +205,10 @@ var require_code = __commonJS({
206
205
  function interpolate(x) {
207
206
  return typeof x == "number" || typeof x == "boolean" || x === null ? x : safeStringify(Array.isArray(x) ? x.join(",") : x);
208
207
  }
209
- function stringify(x) {
208
+ function stringify2(x) {
210
209
  return new _Code(safeStringify(x));
211
210
  }
212
- exports.stringify = stringify;
211
+ exports.stringify = stringify2;
213
212
  function safeStringify(x) {
214
213
  return JSON.stringify(x).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
215
214
  }
@@ -455,11 +454,11 @@ var require_codegen = __commonJS({
455
454
  const rhs = this.rhs === void 0 ? "" : ` = ${this.rhs}`;
456
455
  return `${varKind} ${this.name}${rhs};` + _n;
457
456
  }
458
- optimizeNames(names, constants4) {
457
+ optimizeNames(names, constants5) {
459
458
  if (!names[this.name.str])
460
459
  return;
461
460
  if (this.rhs)
462
- this.rhs = optimizeExpr(this.rhs, names, constants4);
461
+ this.rhs = optimizeExpr(this.rhs, names, constants5);
463
462
  return this;
464
463
  }
465
464
  get names() {
@@ -476,10 +475,10 @@ var require_codegen = __commonJS({
476
475
  render({ _n }) {
477
476
  return `${this.lhs} = ${this.rhs};` + _n;
478
477
  }
479
- optimizeNames(names, constants4) {
478
+ optimizeNames(names, constants5) {
480
479
  if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects)
481
480
  return;
482
- this.rhs = optimizeExpr(this.rhs, names, constants4);
481
+ this.rhs = optimizeExpr(this.rhs, names, constants5);
483
482
  return this;
484
483
  }
485
484
  get names() {
@@ -540,8 +539,8 @@ var require_codegen = __commonJS({
540
539
  optimizeNodes() {
541
540
  return `${this.code}` ? this : void 0;
542
541
  }
543
- optimizeNames(names, constants4) {
544
- this.code = optimizeExpr(this.code, names, constants4);
542
+ optimizeNames(names, constants5) {
543
+ this.code = optimizeExpr(this.code, names, constants5);
545
544
  return this;
546
545
  }
547
546
  get names() {
@@ -570,12 +569,12 @@ var require_codegen = __commonJS({
570
569
  }
571
570
  return nodes.length > 0 ? this : void 0;
572
571
  }
573
- optimizeNames(names, constants4) {
572
+ optimizeNames(names, constants5) {
574
573
  const { nodes } = this;
575
574
  let i = nodes.length;
576
575
  while (i--) {
577
576
  const n = nodes[i];
578
- if (n.optimizeNames(names, constants4))
577
+ if (n.optimizeNames(names, constants5))
579
578
  continue;
580
579
  subtractNames(names, n.names);
581
580
  nodes.splice(i, 1);
@@ -628,12 +627,12 @@ var require_codegen = __commonJS({
628
627
  return void 0;
629
628
  return this;
630
629
  }
631
- optimizeNames(names, constants4) {
630
+ optimizeNames(names, constants5) {
632
631
  var _a3;
633
- this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants4);
634
- if (!(super.optimizeNames(names, constants4) || this.else))
632
+ this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants5);
633
+ if (!(super.optimizeNames(names, constants5) || this.else))
635
634
  return;
636
- this.condition = optimizeExpr(this.condition, names, constants4);
635
+ this.condition = optimizeExpr(this.condition, names, constants5);
637
636
  return this;
638
637
  }
639
638
  get names() {
@@ -656,10 +655,10 @@ var require_codegen = __commonJS({
656
655
  render(opts) {
657
656
  return `for(${this.iteration})` + super.render(opts);
658
657
  }
659
- optimizeNames(names, constants4) {
660
- if (!super.optimizeNames(names, constants4))
658
+ optimizeNames(names, constants5) {
659
+ if (!super.optimizeNames(names, constants5))
661
660
  return;
662
- this.iteration = optimizeExpr(this.iteration, names, constants4);
661
+ this.iteration = optimizeExpr(this.iteration, names, constants5);
663
662
  return this;
664
663
  }
665
664
  get names() {
@@ -695,10 +694,10 @@ var require_codegen = __commonJS({
695
694
  render(opts) {
696
695
  return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
697
696
  }
698
- optimizeNames(names, constants4) {
699
- if (!super.optimizeNames(names, constants4))
697
+ optimizeNames(names, constants5) {
698
+ if (!super.optimizeNames(names, constants5))
700
699
  return;
701
- this.iterable = optimizeExpr(this.iterable, names, constants4);
700
+ this.iterable = optimizeExpr(this.iterable, names, constants5);
702
701
  return this;
703
702
  }
704
703
  get names() {
@@ -740,11 +739,11 @@ var require_codegen = __commonJS({
740
739
  (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNodes();
741
740
  return this;
742
741
  }
743
- optimizeNames(names, constants4) {
742
+ optimizeNames(names, constants5) {
744
743
  var _a3, _b;
745
- super.optimizeNames(names, constants4);
746
- (_a3 = this.catch) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants4);
747
- (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants4);
744
+ super.optimizeNames(names, constants5);
745
+ (_a3 = this.catch) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants5);
746
+ (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants5);
748
747
  return this;
749
748
  }
750
749
  get names() {
@@ -1045,7 +1044,7 @@ var require_codegen = __commonJS({
1045
1044
  function addExprNames(names, from) {
1046
1045
  return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
1047
1046
  }
1048
- function optimizeExpr(expr, names, constants4) {
1047
+ function optimizeExpr(expr, names, constants5) {
1049
1048
  if (expr instanceof code_1.Name)
1050
1049
  return replaceName(expr);
1051
1050
  if (!canOptimize(expr))
@@ -1060,14 +1059,14 @@ var require_codegen = __commonJS({
1060
1059
  return items;
1061
1060
  }, []));
1062
1061
  function replaceName(n) {
1063
- const c = constants4[n.str];
1062
+ const c = constants5[n.str];
1064
1063
  if (c === void 0 || names[n.str] !== 1)
1065
1064
  return n;
1066
1065
  delete names[n.str];
1067
1066
  return c;
1068
1067
  }
1069
1068
  function canOptimize(e) {
1070
- return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants4[c.str] !== void 0);
1069
+ return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants5[c.str] !== void 0);
1071
1070
  }
1072
1071
  }
1073
1072
  function subtractNames(names, from) {
@@ -3624,24 +3623,24 @@ var require_fast_uri = __commonJS({
3624
3623
  function normalize(uri, options) {
3625
3624
  if (typeof uri === "string") {
3626
3625
  uri = /** @type {T} */
3627
- serialize(parse3(uri, options), options);
3626
+ serialize(parse4(uri, options), options);
3628
3627
  } else if (typeof uri === "object") {
3629
3628
  uri = /** @type {T} */
3630
- parse3(serialize(uri, options), options);
3629
+ parse4(serialize(uri, options), options);
3631
3630
  }
3632
3631
  return uri;
3633
3632
  }
3634
3633
  function resolve(baseURI, relativeURI, options) {
3635
3634
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3636
- const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
3635
+ const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
3637
3636
  schemelessOptions.skipEscape = true;
3638
3637
  return serialize(resolved, schemelessOptions);
3639
3638
  }
3640
3639
  function resolveComponent(base, relative, options, skipNormalization) {
3641
3640
  const target = {};
3642
3641
  if (!skipNormalization) {
3643
- base = parse3(serialize(base, options), options);
3644
- relative = parse3(serialize(relative, options), options);
3642
+ base = parse4(serialize(base, options), options);
3643
+ relative = parse4(serialize(relative, options), options);
3645
3644
  }
3646
3645
  options = options || {};
3647
3646
  if (!options.tolerant && relative.scheme) {
@@ -3693,13 +3692,13 @@ var require_fast_uri = __commonJS({
3693
3692
  function equal(uriA, uriB, options) {
3694
3693
  if (typeof uriA === "string") {
3695
3694
  uriA = unescape(uriA);
3696
- uriA = serialize(normalizeComponentEncoding(parse3(uriA, options), true), { ...options, skipEscape: true });
3695
+ uriA = serialize(normalizeComponentEncoding(parse4(uriA, options), true), { ...options, skipEscape: true });
3697
3696
  } else if (typeof uriA === "object") {
3698
3697
  uriA = serialize(normalizeComponentEncoding(uriA, true), { ...options, skipEscape: true });
3699
3698
  }
3700
3699
  if (typeof uriB === "string") {
3701
3700
  uriB = unescape(uriB);
3702
- uriB = serialize(normalizeComponentEncoding(parse3(uriB, options), true), { ...options, skipEscape: true });
3701
+ uriB = serialize(normalizeComponentEncoding(parse4(uriB, options), true), { ...options, skipEscape: true });
3703
3702
  } else if (typeof uriB === "object") {
3704
3703
  uriB = serialize(normalizeComponentEncoding(uriB, true), { ...options, skipEscape: true });
3705
3704
  }
@@ -3768,7 +3767,7 @@ var require_fast_uri = __commonJS({
3768
3767
  return uriTokens.join("");
3769
3768
  }
3770
3769
  var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
3771
- function parse3(uri, opts) {
3770
+ function parse4(uri, opts) {
3772
3771
  const options = Object.assign({}, opts);
3773
3772
  const parsed = {
3774
3773
  scheme: void 0,
@@ -3862,7 +3861,7 @@ var require_fast_uri = __commonJS({
3862
3861
  resolveComponent,
3863
3862
  equal,
3864
3863
  serialize,
3865
- parse: parse3
3864
+ parse: parse4
3866
3865
  };
3867
3866
  module.exports = fastUri;
3868
3867
  module.exports.default = fastUri;
@@ -6888,18 +6887,18 @@ var stdoutLogger = {
6888
6887
  };
6889
6888
 
6890
6889
  // src/commands/init.ts
6891
- import { spawnSync as spawnSync4 } from "node:child_process";
6892
- import { existsSync as existsSync6, mkdirSync as mkdirSync2, readdirSync, renameSync, rmdirSync, writeFileSync as writeFileSync3 } from "node:fs";
6893
- import { dirname as dirname3, join as join8 } from "node:path";
6890
+ import { spawnSync as spawnSync3 } from "node:child_process";
6891
+ import { existsSync as existsSync8, mkdirSync as mkdirSync3, readdirSync, renameSync, rmdirSync, writeFileSync as writeFileSync3 } from "node:fs";
6892
+ import { dirname as dirname3, join as join10 } from "node:path";
6894
6893
 
6895
6894
  // src/claudeInstall.ts
6896
- import { spawnSync } from "node:child_process";
6897
- import { constants, existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
6898
- import { join as join3 } from "node:path";
6895
+ import { constants, existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
6896
+ import { join as join4 } from "node:path";
6899
6897
 
6900
6898
  // src/installShared.ts
6901
6899
  import { accessSync, copyFileSync, existsSync, mkdirSync, realpathSync, statSync, writeFileSync } from "node:fs";
6902
- import { dirname as dirname2, isAbsolute } from "node:path";
6900
+ import { dirname as dirname2, isAbsolute, join as join3 } from "node:path";
6901
+ import { homedir as homedir2 } from "node:os";
6903
6902
  function quoteCommandPath(p) {
6904
6903
  return /[\s\\]/.test(p) ? `"${p}"` : p;
6905
6904
  }
@@ -6939,15 +6938,73 @@ function writeJsonWithBackup(path, value) {
6939
6938
  return writeFileWithBackup(path, `${JSON.stringify(value, null, 2)}
6940
6939
  `);
6941
6940
  }
6941
+ function resolveAgentConfigPaths(userHome = homedir2(), env = process.env) {
6942
+ const claudeDir = env.CLAUDE_CONFIG_DIR || join3(userHome, ".claude");
6943
+ return {
6944
+ claudeDir,
6945
+ claudeMcp: claudeMcpConfigPath(claudeDir, env),
6946
+ codexHome: env.CODEX_HOME || join3(userHome, ".codex"),
6947
+ grokHome: env.GROK_HOME || join3(userHome, ".grok"),
6948
+ cursorDir: env.CURSOR_HOME || join3(userHome, ".cursor")
6949
+ };
6950
+ }
6951
+ function claudeMcpConfigPath(claudeDir, env = process.env) {
6952
+ return join3(env.CLAUDE_CONFIG_DIR ? claudeDir : dirname2(claudeDir), ".claude.json");
6953
+ }
6954
+
6955
+ // src/mcpInstall.ts
6956
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
6957
+ import { isDeepStrictEqual } from "node:util";
6958
+ import { parse, stringify } from "smol-toml";
6959
+ function object(value) {
6960
+ return value !== null && typeof value === "object" && !Array.isArray(value);
6961
+ }
6962
+ function installMcpClient(options) {
6963
+ return updateMcpClient(options, (previous) => ({
6964
+ ...previous,
6965
+ ...options.client === "claude" ? { type: "stdio", env: previous?.env ?? {} } : {},
6966
+ command: options.nodePath,
6967
+ args: ["--disable-warning=ExperimentalWarning", options.cliScriptPath, "mcp-server"]
6968
+ }));
6969
+ }
6970
+ function uninstallMcpClient(options) {
6971
+ return updateMcpClient(options, () => void 0);
6972
+ }
6973
+ function updateMcpClient(options, update) {
6974
+ const { client, configPath, dryRun } = options;
6975
+ const json2 = client === "cursor" || client === "claude";
6976
+ const decode3 = (text) => json2 ? JSON.parse(text) : parse(text);
6977
+ const current = existsSync2(configPath) ? decode3(readFileSync2(configPath, "utf8")) : {};
6978
+ const key = json2 ? "mcpServers" : "mcp_servers";
6979
+ if (!object(current) || current[key] !== void 0 && !object(current[key])) {
6980
+ throw new Error(`mcp_config_invalid: ${client}\u306EMCP\u8A2D\u5B9A\u304Cobject\u3067\u306F\u3042\u308A\u307E\u305B\u3093`);
6981
+ }
6982
+ const servers = current[key] ?? {};
6983
+ if (servers.caveat !== void 0 && !object(servers.caveat)) {
6984
+ throw new Error(`mcp_config_invalid: ${client}\u306ECaveat\u767B\u9332\u304Cobject\u3067\u306F\u3042\u308A\u307E\u305B\u3093`);
6985
+ }
6986
+ const previous = servers.caveat;
6987
+ const registration = update(previous);
6988
+ if (isDeepStrictEqual(previous, registration)) return "unchanged";
6989
+ if (dryRun) return "dry-run";
6990
+ const nextServers = { ...servers };
6991
+ if (registration === void 0) delete nextServers.caveat;
6992
+ else nextServers.caveat = registration;
6993
+ const next = { ...current, [key]: nextServers };
6994
+ writeFileWithBackup(configPath, json2 ? `${JSON.stringify(next, null, 2)}
6995
+ ` : stringify(next));
6996
+ const observed = decode3(readFileSync2(configPath, "utf8"));
6997
+ if (!isDeepStrictEqual(observed, next)) {
6998
+ throw new Error(`mcp_config_readback_failed: ${client}\u306E\u8A2D\u5B9A\u8AAD\u623B\u3057\u304C\u4E00\u81F4\u3057\u307E\u305B\u3093`);
6999
+ }
7000
+ return "configured";
7001
+ }
6942
7002
 
6943
7003
  // src/claudeInstall.ts
6944
7004
  var EVENT_USER_PROMPT_SUBMIT = "UserPromptSubmit";
6945
7005
  var EVENT_POST_TOOL_USE = "PostToolUse";
6946
7006
  var EVENT_POST_TOOL_USE_FAILURE = "PostToolUseFailure";
6947
7007
  var EVENT_STOP = "Stop";
6948
- function mcpArgs(cliScriptPath) {
6949
- return ["--disable-warning=ExperimentalWarning", cliScriptPath, "mcp-server"];
6950
- }
6951
7008
  function hookCommand(nodePath, cliScriptPath, event) {
6952
7009
  return `${quoteCommandPath(nodePath)} ${quoteCommandPath(cliScriptPath)} hook ${event}`;
6953
7010
  }
@@ -6999,79 +7056,37 @@ function isCaveatClaudeHookCommand(actual, event) {
6999
7056
  }
7000
7057
  function isCanonicalCaveatClaudeHookCommand(actual, event, nodePath, cliScriptPath) {
7001
7058
  const tokens = commandTokens(actual);
7002
- if (tokens?.length !== 4 || tokens[2] !== "hook" || tokens[3] !== event) return false;
7003
- if (actual !== hookCommand(tokens[0], tokens[1], event)) return false;
7004
- return isCanonicalAsset(tokens[0], nodePath, constants.X_OK) && isCanonicalAsset(tokens[1], cliScriptPath, constants.R_OK);
7059
+ const [actualNodePath, actualCliScriptPath, subcommand, actualEvent] = tokens ?? [];
7060
+ if (tokens?.length !== 4 || actualNodePath === void 0 || actualCliScriptPath === void 0 || subcommand !== "hook" || actualEvent !== event) return false;
7061
+ if (actual !== hookCommand(actualNodePath, actualCliScriptPath, event)) return false;
7062
+ return isCanonicalAsset(actualNodePath, nodePath, constants.X_OK) && isCanonicalAsset(actualCliScriptPath, cliScriptPath, constants.R_OK);
7005
7063
  }
7006
7064
  function isCaveatClaudeMcpRegistration(value, nodePath, cliScriptPath) {
7007
7065
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
7008
7066
  const server = value;
7009
- 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;
7067
+ return ["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.values(server.env).every((value2) => typeof value2 === "string");
7010
7068
  }
7011
7069
  function readSettings(path) {
7012
- if (!existsSync2(path)) return {};
7013
- return JSON.parse(readFileSync2(path, "utf-8"));
7070
+ if (!existsSync3(path)) return {};
7071
+ return JSON.parse(readFileSync3(path, "utf-8"));
7014
7072
  }
7015
7073
  function writeSettings(path, settings) {
7016
7074
  return writeJsonWithBackup(path, settings);
7017
7075
  }
7018
- var CLAUDE_BIN = "claude";
7019
- function shellQuote(s) {
7020
- return /[\s&|<>^()]/.test(s) ? `"${s}"` : s;
7021
- }
7022
- function runClaude(args) {
7023
- const line = [CLAUDE_BIN, ...args].map(shellQuote).join(" ");
7024
- return spawnSync(line, { shell: true, encoding: "utf-8" });
7025
- }
7026
- function registerMcp(nodePath, cliScriptPath, dryRun, logger) {
7027
- const args = mcpArgs(cliScriptPath);
7028
- if (dryRun) {
7029
- logger.info(
7030
- `[dry-run] claude mcp add --scope user caveat -- ${nodePath} ${args.join(" ")}`
7031
- );
7032
- return { action: "skipped", detail: "dry-run" };
7033
- }
7034
- runClaude(["mcp", "remove", "--scope", "user", "caveat"]);
7035
- const result = runClaude([
7036
- "mcp",
7037
- "add",
7038
- "--scope",
7039
- "user",
7040
- "caveat",
7041
- "--",
7042
- nodePath,
7043
- ...args
7044
- ]);
7045
- if (result.status === 0) {
7046
- return { action: "registered" };
7047
- }
7048
- if (result.error && "code" in result.error && result.error.code === "ENOENT") {
7049
- return {
7050
- action: "skipped",
7051
- detail: "claude CLI not found in PATH; install Claude Code to enable MCP"
7052
- };
7053
- }
7054
- const stderr = typeof result.stderr === "string" ? result.stderr : "";
7055
- const stdout = typeof result.stdout === "string" ? result.stdout : "";
7056
- return {
7057
- action: "failed",
7058
- detail: (stderr || stdout || "unknown error").trim()
7059
- };
7060
- }
7061
- function unregisterMcp(dryRun, logger) {
7062
- if (dryRun) {
7063
- logger.info("[dry-run] claude mcp remove --scope user caveat");
7064
- return { action: "skipped", detail: "dry-run" };
7065
- }
7066
- const result = runClaude(["mcp", "remove", "--scope", "user", "caveat"]);
7067
- if (result.status === 0) return { action: "registered", detail: "removed" };
7068
- if (result.error && "code" in result.error && result.error.code === "ENOENT") {
7069
- return { action: "skipped", detail: "claude CLI not found" };
7076
+ function configureMcp(opts, remove = false) {
7077
+ const configPath = opts.mcpConfigPath ?? claudeMcpConfigPath(opts.claudeDir);
7078
+ try {
7079
+ const options = { client: "claude", configPath, dryRun: opts.dryRun };
7080
+ const action = remove ? uninstallMcpClient(options) : installMcpClient({ ...options, nodePath: opts.nodePath, cliScriptPath: opts.cliScriptPath });
7081
+ const detail = remove && action === "configured" ? "removed" : action;
7082
+ opts.logger.info(`Claude MCP: ${detail}`);
7083
+ return { action: opts.dryRun ? "skipped" : "registered", detail };
7084
+ } catch (error51) {
7085
+ return { action: "failed", detail: error51 instanceof Error ? error51.message : String(error51) };
7070
7086
  }
7071
- return { action: "skipped", detail: "not registered or removal failed" };
7072
7087
  }
7073
7088
  function installClaudeIntegration(opts) {
7074
- const settingsPath = join3(opts.claudeDir, "settings.json");
7089
+ const settingsPath = join4(opts.claudeDir, "settings.json");
7075
7090
  const settings = readSettings(settingsPath);
7076
7091
  const usCmd = hookCommand(opts.nodePath, opts.cliScriptPath, "user-prompt-submit");
7077
7092
  const ptCmd = hookCommand(opts.nodePath, opts.cliScriptPath, "post-tool-use");
@@ -7095,7 +7110,7 @@ function installClaudeIntegration(opts) {
7095
7110
  `[dry-run] would ${userPromptSubmit === "added" ? "add" : "keep"} UserPromptSubmit, ${postToolUse === "added" ? "add" : "keep"} PostToolUse, ${postToolUseFailure === "added" ? "add" : "keep"} PostToolUseFailure, ${stop === "added" ? "add" : "keep"} Stop hook in ${settingsPath}`
7096
7111
  );
7097
7112
  }
7098
- const mcp = opts.skipMcpRegistration ? { action: "skipped", detail: "skipped by caller" } : registerMcp(opts.nodePath, opts.cliScriptPath, opts.dryRun, opts.logger);
7113
+ const mcp = opts.skipMcpRegistration ? { action: "skipped", detail: "skipped by caller" } : configureMcp(opts);
7099
7114
  return {
7100
7115
  mcp,
7101
7116
  hooks: { userPromptSubmit, postToolUse, postToolUseFailure, stop },
@@ -7103,7 +7118,7 @@ function installClaudeIntegration(opts) {
7103
7118
  };
7104
7119
  }
7105
7120
  function uninstallClaudeIntegration(opts) {
7106
- const settingsPath = join3(opts.claudeDir, "settings.json");
7121
+ const settingsPath = join4(opts.claudeDir, "settings.json");
7107
7122
  const settings = readSettings(settingsPath);
7108
7123
  const usCmd = hookCommand(opts.nodePath, opts.cliScriptPath, "user-prompt-submit");
7109
7124
  const ptCmd = hookCommand(opts.nodePath, opts.cliScriptPath, "post-tool-use");
@@ -7117,7 +7132,7 @@ function uninstallClaudeIntegration(opts) {
7117
7132
  const backup = writeSettings(settingsPath, settings);
7118
7133
  if (backup) backupPath = backup;
7119
7134
  }
7120
- const mcp = opts.skipMcpRegistration ? { action: "skipped", detail: "skipped by caller" } : unregisterMcp(opts.dryRun, opts.logger);
7135
+ const mcp = opts.skipMcpRegistration ? { action: "skipped", detail: "skipped by caller" } : configureMcp(opts, true);
7121
7136
  return {
7122
7137
  mcp,
7123
7138
  hooks: {
@@ -7131,8 +7146,8 @@ function uninstallClaudeIntegration(opts) {
7131
7146
  }
7132
7147
 
7133
7148
  // src/codexHookInstall.ts
7134
- import { constants as constants2, existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
7135
- import { join as join4 } from "node:path";
7149
+ import { constants as constants2, existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
7150
+ import { join as join5 } from "node:path";
7136
7151
  import { parse as parseToml } from "smol-toml";
7137
7152
  function hookCommand2(nodePath, cliScriptPath, event, platform = process.platform) {
7138
7153
  return `${powershellCallPrefix(platform)}${quoteCommandPath(nodePath)} ${quoteCommandPath(cliScriptPath)} codex-hook ${event}`;
@@ -7168,8 +7183,8 @@ function hasCaveatHook(hooksJson, event, fragment) {
7168
7183
  ) ?? false;
7169
7184
  }
7170
7185
  function readHooks(path) {
7171
- if (!existsSync3(path)) return {};
7172
- return JSON.parse(readFileSync3(path, "utf-8"));
7186
+ if (!existsSync4(path)) return {};
7187
+ return JSON.parse(readFileSync4(path, "utf-8"));
7173
7188
  }
7174
7189
  function upsertHook2(hooksJson, event, command, subcommand) {
7175
7190
  hooksJson.hooks ??= {};
@@ -7393,9 +7408,9 @@ function maskTomlStringsAndComments(raw) {
7393
7408
  return output;
7394
7409
  }
7395
7410
  function installCodexHooks(opts) {
7396
- const hooksPath = join4(opts.codexHome, "hooks.json");
7397
- const configPath = join4(opts.codexHome, "config.toml");
7398
- const rawConfig = existsSync3(configPath) ? readFileSync3(configPath, "utf-8") : "";
7411
+ const hooksPath = join5(opts.codexHome, "hooks.json");
7412
+ const configPath = join5(opts.codexHome, "config.toml");
7413
+ const rawConfig = existsSync4(configPath) ? readFileSync4(configPath, "utf-8") : "";
7399
7414
  const enabled = enableCodexHooksFeature(rawConfig);
7400
7415
  if (enabled.status === "blocked") {
7401
7416
  return {
@@ -7447,7 +7462,7 @@ function installCodexHooks(opts) {
7447
7462
  };
7448
7463
  }
7449
7464
  function uninstallCodexHooks(opts) {
7450
- const hooksPath = join4(opts.codexHome, "hooks.json");
7465
+ const hooksPath = join5(opts.codexHome, "hooks.json");
7451
7466
  const hooksJson = readHooks(hooksPath);
7452
7467
  const userPromptSubmitRemoved = removeHook2(
7453
7468
  hooksJson,
@@ -7485,7 +7500,7 @@ function uninstallCodexHooks(opts) {
7485
7500
  };
7486
7501
  }
7487
7502
  function detectCodexHookInstallation(codexHome) {
7488
- const hooksPath = join4(codexHome, "hooks.json");
7503
+ const hooksPath = join5(codexHome, "hooks.json");
7489
7504
  const hooksJson = readHooks(hooksPath);
7490
7505
  const hooks = {
7491
7506
  userPromptSubmit: hasCaveatHook(
@@ -7512,11 +7527,196 @@ function detectCodexHookInstallation(codexHome) {
7512
7527
  };
7513
7528
  }
7514
7529
 
7530
+ // src/cursorInstall.ts
7531
+ import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync5 } from "node:fs";
7532
+ import { join as join6 } from "node:path";
7533
+ import { constants as constants3 } from "node:fs";
7534
+ var TIMEOUT_SEC = 10;
7535
+ function hookCommand3(nodePath, cliScriptPath, event) {
7536
+ return `${quoteCommandPath(nodePath)} ${quoteCommandPath(cliScriptPath)} cursor-hook ${event}`;
7537
+ }
7538
+ function eventCommandFragment2(event) {
7539
+ return `cursor-hook ${event}`;
7540
+ }
7541
+ function isCaveatCursorHookCommand(actual, event) {
7542
+ const lower = actual.toLowerCase();
7543
+ return lower.includes("caveat") && actual.includes(eventCommandFragment2(event));
7544
+ }
7545
+ function isCanonicalCaveatCursorHookCommand(actual, event, nodePath, cliScriptPath) {
7546
+ const tokens = commandTokens(actual);
7547
+ return tokens?.length === 4 && isCanonicalAsset(tokens[0], nodePath, constants3.X_OK) && isCanonicalAsset(tokens[1], cliScriptPath, constants3.R_OK) && tokens[2] === "cursor-hook" && tokens[3] === event;
7548
+ }
7549
+ function isCanonicalCaveatCursorHookEntry(value, event, nodePath, cliScriptPath) {
7550
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
7551
+ const entry = value;
7552
+ return typeof entry.command === "string" && isCanonicalCaveatCursorHookCommand(entry.command, event, nodePath, cliScriptPath) && entry.timeout === TIMEOUT_SEC;
7553
+ }
7554
+ function readHooks2(path) {
7555
+ if (!existsSync5(path)) return { version: 1, hooks: {} };
7556
+ const parsed = JSON.parse(readFileSync5(path, "utf-8"));
7557
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
7558
+ throw new Error(`${path} \u306F object \u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`);
7559
+ }
7560
+ const file2 = parsed;
7561
+ if (file2.hooks == null) file2.hooks = {};
7562
+ if (typeof file2.hooks !== "object" || Array.isArray(file2.hooks)) {
7563
+ throw new Error(`${path} \u306E hooks \u306F object \u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`);
7564
+ }
7565
+ return file2;
7566
+ }
7567
+ function listFor(file2, event) {
7568
+ const current = file2.hooks?.[event];
7569
+ if (Array.isArray(current)) return current;
7570
+ return [];
7571
+ }
7572
+ function isSameCommand(actual, expected) {
7573
+ const left = commandTokens(actual);
7574
+ const right = commandTokens(expected);
7575
+ return left !== null && right !== null && left.length === right.length && left.every((token, index) => token === right[index]);
7576
+ }
7577
+ function upsertHook3(file2, event, command, subcommand) {
7578
+ file2.hooks ??= {};
7579
+ const list = listFor(file2, event);
7580
+ for (const entry of list) {
7581
+ if (typeof entry.command !== "string") continue;
7582
+ if (isSameCommand(entry.command, command) && entry.timeout === TIMEOUT_SEC) {
7583
+ return "unchanged";
7584
+ }
7585
+ if (isSameCommand(entry.command, command) || isCaveatCursorHookCommand(entry.command, subcommand)) {
7586
+ entry.command = command;
7587
+ entry.timeout = TIMEOUT_SEC;
7588
+ file2.hooks[event] = list;
7589
+ return "added";
7590
+ }
7591
+ }
7592
+ list.push({ command, timeout: TIMEOUT_SEC });
7593
+ file2.hooks[event] = list;
7594
+ return "added";
7595
+ }
7596
+ function removeHook3(file2, event, command, subcommand) {
7597
+ const list = listFor(file2, event);
7598
+ if (list.length === 0) return false;
7599
+ const kept = list.filter((entry) => {
7600
+ if (typeof entry.command !== "string") return true;
7601
+ return !(isSameCommand(entry.command, command) || isCaveatCursorHookCommand(entry.command, subcommand));
7602
+ });
7603
+ if (kept.length === list.length) return false;
7604
+ if (!file2.hooks) return true;
7605
+ if (kept.length > 0) file2.hooks[event] = kept;
7606
+ else delete file2.hooks[event];
7607
+ return true;
7608
+ }
7609
+ function hasCaveatHook2(file2, event, fragment) {
7610
+ return listFor(file2, event).some(
7611
+ (entry) => typeof entry.command === "string" && entry.command.includes(fragment)
7612
+ );
7613
+ }
7614
+ function persist(opts, file2, changed) {
7615
+ const hooksPath = join6(opts.cursorDir, "hooks.json");
7616
+ if (opts.dryRun) {
7617
+ opts.logger.info(`[dry-run] would write Cursor hooks to ${hooksPath}`);
7618
+ return void 0;
7619
+ }
7620
+ if (!changed) return void 0;
7621
+ mkdirSync2(opts.cursorDir, { recursive: true });
7622
+ file2.version = 1;
7623
+ const backup = writeJsonWithBackup(hooksPath, file2);
7624
+ return backup || void 0;
7625
+ }
7626
+ function installCursorHooks(opts) {
7627
+ const hooksPath = join6(opts.cursorDir, "hooks.json");
7628
+ const file2 = readHooks2(hooksPath);
7629
+ const promptCmd = hookCommand3(opts.nodePath, opts.cliScriptPath, "user-prompt-submit");
7630
+ const toolCmd = hookCommand3(opts.nodePath, opts.cliScriptPath, "post-tool-use");
7631
+ const stopCmd = hookCommand3(opts.nodePath, opts.cliScriptPath, "stop");
7632
+ const hooks = {
7633
+ beforeSubmitPrompt: upsertHook3(file2, "beforeSubmitPrompt", promptCmd, "user-prompt-submit"),
7634
+ postToolUse: upsertHook3(file2, "postToolUse", toolCmd, "post-tool-use"),
7635
+ postToolUseFailure: upsertHook3(file2, "postToolUseFailure", toolCmd, "post-tool-use"),
7636
+ stop: upsertHook3(file2, "stop", stopCmd, "stop")
7637
+ };
7638
+ const changed = Object.values(hooks).some((status2) => status2 === "added");
7639
+ const backupPath = persist(opts, file2, changed);
7640
+ return { hooks, backupPath };
7641
+ }
7642
+ function uninstallCursorHooks(opts) {
7643
+ const hooksPath = join6(opts.cursorDir, "hooks.json");
7644
+ const file2 = readHooks2(hooksPath);
7645
+ const promptCmd = hookCommand3(opts.nodePath, opts.cliScriptPath, "user-prompt-submit");
7646
+ const toolCmd = hookCommand3(opts.nodePath, opts.cliScriptPath, "post-tool-use");
7647
+ const stopCmd = hookCommand3(opts.nodePath, opts.cliScriptPath, "stop");
7648
+ const removed = {
7649
+ beforeSubmitPrompt: removeHook3(file2, "beforeSubmitPrompt", promptCmd, "user-prompt-submit"),
7650
+ postToolUse: removeHook3(file2, "postToolUse", toolCmd, "post-tool-use"),
7651
+ postToolUseFailure: removeHook3(file2, "postToolUseFailure", toolCmd, "post-tool-use"),
7652
+ stop: removeHook3(file2, "stop", stopCmd, "stop")
7653
+ };
7654
+ const changed = Object.values(removed).some(Boolean);
7655
+ const backupPath = persist(opts, file2, changed);
7656
+ return {
7657
+ hooks: {
7658
+ beforeSubmitPrompt: removed.beforeSubmitPrompt ? "added" : "unchanged",
7659
+ postToolUse: removed.postToolUse ? "added" : "unchanged",
7660
+ postToolUseFailure: removed.postToolUseFailure ? "added" : "unchanged",
7661
+ stop: removed.stop ? "added" : "unchanged"
7662
+ },
7663
+ backupPath
7664
+ };
7665
+ }
7666
+ function detectCursorHookInstallation(cursorDir) {
7667
+ const hooksPath = join6(cursorDir, "hooks.json");
7668
+ const file2 = existsSync5(hooksPath) ? readHooks2(hooksPath) : { version: 1, hooks: {} };
7669
+ const hooks = {
7670
+ beforeSubmitPrompt: hasCaveatHook2(file2, "beforeSubmitPrompt", eventCommandFragment2("user-prompt-submit")),
7671
+ postToolUse: hasCaveatHook2(file2, "postToolUse", eventCommandFragment2("post-tool-use")),
7672
+ postToolUseFailure: hasCaveatHook2(file2, "postToolUseFailure", eventCommandFragment2("post-tool-use")),
7673
+ stop: hasCaveatHook2(file2, "stop", eventCommandFragment2("stop"))
7674
+ };
7675
+ const count = Object.values(hooks).filter(Boolean).length;
7676
+ return {
7677
+ installation: count === 0 ? "not-installed" : count === 4 ? "installed" : "partial",
7678
+ hooksPath,
7679
+ hooks
7680
+ };
7681
+ }
7682
+ function diagnoseCursorHookConnector(cursorDir, nodePath, cliScriptPath) {
7683
+ const ready = () => ({ status: "ready", reason_code: "ready" });
7684
+ const notReady = () => ({ status: "not_ready", reason_code: "not_installed" });
7685
+ const unreadable = () => ({ status: "unverified", reason_code: "config_unreadable" });
7686
+ const unreadableHooks = {
7687
+ before_submit_prompt: unreadable(),
7688
+ post_tool_use: unreadable(),
7689
+ post_tool_use_failure: unreadable(),
7690
+ stop: unreadable()
7691
+ };
7692
+ const hooksPath = join6(cursorDir, "hooks.json");
7693
+ let file2;
7694
+ try {
7695
+ file2 = existsSync5(hooksPath) ? readHooks2(hooksPath) : { version: 1, hooks: {} };
7696
+ } catch {
7697
+ return { compatibility_status: "unverified", hooks: unreadableHooks };
7698
+ }
7699
+ const exact = (event, subcommand) => listFor(file2, event).some(
7700
+ (entry) => isCanonicalCaveatCursorHookEntry(entry, subcommand, nodePath, cliScriptPath)
7701
+ ) ? ready() : notReady();
7702
+ const hooks = {
7703
+ before_submit_prompt: exact("beforeSubmitPrompt", "user-prompt-submit"),
7704
+ post_tool_use: exact("postToolUse", "post-tool-use"),
7705
+ post_tool_use_failure: exact("postToolUseFailure", "post-tool-use"),
7706
+ stop: exact("stop", "stop")
7707
+ };
7708
+ const statuses = Object.values(hooks).map((item) => item.status);
7709
+ return {
7710
+ compatibility_status: statuses.includes("not_ready") ? "not_ready" : statuses.includes("unverified") ? "unverified" : "ready",
7711
+ hooks
7712
+ };
7713
+ }
7714
+
7515
7715
  // src/ghSetup.ts
7516
- import { spawnSync as spawnSync2 } from "node:child_process";
7716
+ import { spawnSync } from "node:child_process";
7517
7717
  import { readSync } from "node:fs";
7518
7718
  function runGh(args) {
7519
- const result = spawnSync2("gh", args, { encoding: "utf-8" });
7719
+ const result = spawnSync("gh", args, { encoding: "utf-8" });
7520
7720
  return { status: result.status, stdout: typeof result.stdout === "string" ? result.stdout : "", stderr: typeof result.stderr === "string" ? result.stderr : "" };
7521
7721
  }
7522
7722
  function commandError(result, fallback) {
@@ -7536,6 +7736,10 @@ function defaultGitHubRepoUrl(opts) {
7536
7736
  throw new Error(`gh is not authenticated; run \`gh auth login\`, then retry \`${opts.retryCommand}\``);
7537
7737
  }
7538
7738
  const login = user.stdout.trim();
7739
+ const setupGit = opts.ghRunner(["auth", "setup-git"]);
7740
+ if (setupGit.status !== 0) {
7741
+ throw commandError(setupGit, "gh auth setup-git failed");
7742
+ }
7539
7743
  const qualifiedName = `${login}/${opts.repositoryName}`;
7540
7744
  const view = opts.ghRunner(["repo", "view", qualifiedName]);
7541
7745
  if (view.status !== 0) {
@@ -7559,8 +7763,8 @@ function askOnce(question) {
7559
7763
  }
7560
7764
 
7561
7765
  // src/nodePath.ts
7562
- import { existsSync as existsSync4, realpathSync as realpathSync2 } from "node:fs";
7563
- import { delimiter, join as join5 } from "node:path";
7766
+ import { existsSync as existsSync6, realpathSync as realpathSync2 } from "node:fs";
7767
+ import { delimiter, join as join7 } from "node:path";
7564
7768
  var defaultRealpath = (path) => realpathSync2.native(path);
7565
7769
  function safeRealpath(path, realpath = defaultRealpath) {
7566
7770
  try {
@@ -7573,7 +7777,7 @@ function resolveHookNodePath({
7573
7777
  env = process.env,
7574
7778
  execPath = process.execPath,
7575
7779
  platform = process.platform,
7576
- exists = existsSync4,
7780
+ exists = existsSync6,
7577
7781
  realpath = defaultRealpath
7578
7782
  } = {}) {
7579
7783
  const execRealpath = safeRealpath(execPath, realpath);
@@ -7581,7 +7785,7 @@ function resolveHookNodePath({
7581
7785
  const names = nodeExecutableNames(platform);
7582
7786
  for (const dir of pathEnv.split(delimiter).filter(Boolean)) {
7583
7787
  for (const name of names) {
7584
- const candidate = join5(dir, name);
7788
+ const candidate = join7(dir, name);
7585
7789
  if (!exists(candidate)) continue;
7586
7790
  const candidateRealpath = safeRealpath(candidate, realpath);
7587
7791
  if (execRealpath && candidateRealpath && candidateRealpath === execRealpath) {
@@ -7593,14 +7797,14 @@ function resolveHookNodePath({
7593
7797
  }
7594
7798
 
7595
7799
  // src/commands/publish.ts
7596
- import { existsSync as existsSync5 } from "node:fs";
7597
- import { join as join7 } from "node:path";
7800
+ import { existsSync as existsSync7 } from "node:fs";
7801
+ import { join as join9 } from "node:path";
7598
7802
 
7599
7803
  // src/commands/codexSidecarAdvisory.ts
7600
- import { spawnSync as spawnSync3 } from "node:child_process";
7601
- import { mkdtempSync, readFileSync as readFileSync4, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
7804
+ import { spawnSync as spawnSync2 } from "node:child_process";
7805
+ import { mkdtempSync, readFileSync as readFileSync6, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
7602
7806
  import { tmpdir } from "node:os";
7603
- import { join as join6 } from "node:path";
7807
+ import { join as join8 } from "node:path";
7604
7808
  var DEFAULT_HOOK_SIDECAR_TIMEOUT_MS = 12e4;
7605
7809
  var MAX_HOOK_SIDECAR_TIMEOUT_MS = 24e4;
7606
7810
  function resolveHookSidecarTimeoutMs(raw) {
@@ -7656,11 +7860,11 @@ function runCodexSidecarAdvisory(input) {
7656
7860
  let resultDir;
7657
7861
  let advisory;
7658
7862
  try {
7659
- resultDir = mkdtempSync(join6(tmpdir(), "caveat-codex-advisory-"));
7660
- const resultFile = join6(resultDir, "result.json");
7863
+ resultDir = mkdtempSync(join8(tmpdir(), "caveat-codex-advisory-"));
7864
+ const resultFile = join8(resultDir, "result.json");
7661
7865
  args.push("--save-result", resultFile);
7662
7866
  if (input.additionalContext) {
7663
- const additionalContextFile = join6(resultDir, "hook-signal.json");
7867
+ const additionalContextFile = join8(resultDir, "hook-signal.json");
7664
7868
  writeFileSync2(additionalContextFile, JSON.stringify({ context: [input.additionalContext] }) + "\n", { encoding: "utf-8", mode: 384, flag: "wx" });
7665
7869
  args.push("--additional-context-file", additionalContextFile);
7666
7870
  }
@@ -7671,7 +7875,7 @@ function runCodexSidecarAdvisory(input) {
7671
7875
  const command = process.env.CAVEAT_CODEX_SIDECAR_COMMAND;
7672
7876
  if (command) args.push("--command", command);
7673
7877
  }
7674
- const result = spawnSync3(process.execPath, args, {
7878
+ const result = spawnSync2(process.execPath, args, {
7675
7879
  cwd: input.projectRoot,
7676
7880
  encoding: "utf-8",
7677
7881
  // Keep at least one minute between the longest supported model call and
@@ -7688,7 +7892,7 @@ function runCodexSidecarAdvisory(input) {
7688
7892
  message: `sidecar command failed: ${sidecarFailureDetail(detail)}`
7689
7893
  };
7690
7894
  } else {
7691
- const parsed = JSON.parse(readFileSync4(resultFile, "utf-8"));
7895
+ const parsed = JSON.parse(readFileSync6(resultFile, "utf-8"));
7692
7896
  if (parsed.status !== "ok" || typeof parsed.summary !== "string") {
7693
7897
  advisory = {
7694
7898
  status: "failed",
@@ -7756,7 +7960,7 @@ async function runPublish(ctx, opts, dependencies = {}) {
7756
7960
  const isTty = dependencies.isTty ?? (() => Boolean(process.stdin.isTTY));
7757
7961
  const confirm = dependencies.confirm ?? askOnce;
7758
7962
  const projectRoot = process.cwd();
7759
- const hasCodexSidecarConfig = dependencies.hasCodexSidecarConfig ?? ((root) => existsSync5(join7(root, ".codex-sidecar.yml")));
7963
+ const hasCodexSidecarConfig = dependencies.hasCodexSidecarConfig ?? ((root) => existsSync7(join9(root, ".codex-sidecar.yml")));
7760
7964
  const publishAdvisory = hasCodexSidecarConfig(projectRoot) ? (changes) => {
7761
7965
  try {
7762
7966
  return dependencies.runCodexSidecarAdvisory?.(changes, projectRoot) ?? formatCodexSidecarAdvisory(runCodexSidecarAdvisory({
@@ -7811,26 +8015,32 @@ async function runInit(ctx, opts = { skipClaude: false, dryRun: false }, depende
7811
8015
  const isTty = dependencies.isTty ?? (() => Boolean(process.stdin.isTTY));
7812
8016
  const confirm = dependencies.confirm ?? askOnce;
7813
8017
  const ghRunner = dependencies.ghRunner ?? runGh;
8018
+ const env = dependencies.env ?? process.env;
8019
+ const { claudeDir, claudeMcp, codexHome, cursorDir, grokHome } = resolveAgentConfigPaths(ctx.userHome, env);
8020
+ const codexAvailable = (dependencies.codexAvailable ?? detectCodexAvailability)();
7814
8021
  let publishTarget = ctx.config.publishTarget;
7815
8022
  let codexHookState = "not-installed";
7816
- ensureUserConfig(ctx.userConfigPath);
8023
+ let cursorHookState = "not-installed";
8024
+ if (!opts.dryRun) ensureUserConfig(ctx.userConfigPath);
7817
8025
  ctx.logger.info(`user config: ${ctx.userConfigPath}`);
7818
- if (!existsSync6(ctx.paths.knowledgeRepo)) {
7819
- mkdirSync2(ctx.paths.knowledgeRepo, { recursive: true });
7820
- mkdirSync2(ctx.paths.entriesDir, { recursive: true });
7821
- ctx.logger.info(`knowledge repo scaffolded: ${ctx.paths.knowledgeRepo}`);
8026
+ if (!existsSync8(ctx.paths.knowledgeRepo)) {
8027
+ if (!opts.dryRun) {
8028
+ mkdirSync3(ctx.paths.knowledgeRepo, { recursive: true });
8029
+ mkdirSync3(ctx.paths.entriesDir, { recursive: true });
8030
+ }
8031
+ ctx.logger.info(`${opts.dryRun ? "[dry-run] would scaffold" : "knowledge repo scaffolded"}: ${ctx.paths.knowledgeRepo}`);
7822
8032
  } else {
7823
8033
  ctx.logger.info(`knowledge repo: ${ctx.paths.knowledgeRepo}`);
7824
8034
  }
7825
- migrateLegacyCommunityDir(ctx);
7826
- const gitignorePath = join8(ctx.paths.knowledgeRepo, ".gitignore");
7827
- if (!existsSync6(gitignorePath)) {
7828
- writeFileSync3(gitignorePath, KNOWLEDGE_GITIGNORE, "utf-8");
7829
- ctx.logger.info(`.gitignore created: ${gitignorePath}`);
8035
+ if (!opts.dryRun) migrateLegacyCommunityDir(ctx);
8036
+ const gitignorePath = join10(ctx.paths.knowledgeRepo, ".gitignore");
8037
+ if (!existsSync8(gitignorePath)) {
8038
+ if (!opts.dryRun) writeFileSync3(gitignorePath, KNOWLEDGE_GITIGNORE, "utf-8");
8039
+ ctx.logger.info(`${opts.dryRun ? "[dry-run] would create .gitignore" : ".gitignore created"}: ${gitignorePath}`);
7830
8040
  }
7831
8041
  if (!opts.dryRun) {
7832
8042
  const dbDir = dirname3(ctx.paths.dbPath);
7833
- if (!existsSync6(dbDir)) mkdirSync2(dbDir, { recursive: true });
8043
+ if (!existsSync8(dbDir)) mkdirSync3(dbDir, { recursive: true });
7834
8044
  const keyProvider = createKeyserverKeyProvider({ caveatHome: ctx.caveatHome });
7835
8045
  const failures = await prewarmSealedKeys({ paths: ctx.paths, keyProvider });
7836
8046
  for (const failure of failures) {
@@ -7863,7 +8073,7 @@ async function runInit(ctx, opts = { skipClaude: false, dryRun: false }, depende
7863
8073
  );
7864
8074
  let syncRequested = opts.sync !== void 0 && opts.sync !== false;
7865
8075
  let syncNudgeAccepted = false;
7866
- if (opts.sync === void 0 && isTty()) {
8076
+ if (opts.sync === void 0 && !opts.yes && isTty()) {
7867
8077
  syncNudgeAccepted = confirm("private \u540C\u671F\u3092\u4ECA\u3059\u3050\u8A2D\u5B9A\u3059\u308B\uFF1F [y/N]");
7868
8078
  syncRequested = syncNudgeAccepted;
7869
8079
  }
@@ -7873,40 +8083,50 @@ async function runInit(ctx, opts = { skipClaude: false, dryRun: false }, depende
7873
8083
  const target = typeof opts.sync === "string" ? opts.sync : "<user>/Caveat-Private";
7874
8084
  ctx.logger.info(`[dry-run] would initialize private sync: ${target}`);
7875
8085
  } else {
7876
- const url2 = typeof opts.sync === "string" ? opts.sync : defaultGitHubRepoUrl({
7877
- repositoryName: "Caveat-Private",
7878
- visibility: "private",
7879
- yes: (opts.yes ?? false) || syncNudgeAccepted,
7880
- retryCommand: "caveat init --sync <url>",
7881
- ghRunner,
7882
- isTty,
7883
- confirm
7884
- });
7885
- const result = await initOwnSync({
7886
- ownDir: ctx.paths.knowledgeRepo,
7887
- url: url2,
7888
- caveatHome: ctx.caveatHome,
7889
- paths: ctx.paths,
7890
- logger: ctx.logger,
7891
- // file: remotes are governed by local filesystem permissions and have
7892
- // no anonymous HTTP surface for the remote-visibility probe to inspect.
7893
- trustRemotePrivate: isFileRemote(url2)
7894
- });
7895
- ctx.logger.info(
7896
- result.remoteWasEmpty ? `initialized private sync remote: ${url2}` : `checked out existing private remote: ${url2} (branch ${result.branch})`
7897
- );
8086
+ const ownGit = join10(ctx.paths.knowledgeRepo, ".git");
8087
+ if (existsSync8(ownGit)) {
8088
+ const remote = gitOutput(["-C", ctx.paths.knowledgeRepo, "remote", "get-url", "origin"]);
8089
+ const result = await syncOwn({
8090
+ ownDir: ctx.paths.knowledgeRepo,
8091
+ caveatHome: ctx.caveatHome,
8092
+ paths: ctx.paths,
8093
+ logger: ctx.logger,
8094
+ trustRemotePrivate: remote !== null && isFileRemote(remote)
8095
+ });
8096
+ const rebased = result.pulled ? ", rebased onto remote" : "";
8097
+ ctx.logger.info(`synced existing private remote: ${result.branch} (${result.changedFiles} local change(s)${rebased})`);
8098
+ } else {
8099
+ const url2 = typeof opts.sync === "string" ? opts.sync : defaultGitHubRepoUrl({
8100
+ repositoryName: "Caveat-Private",
8101
+ visibility: "private",
8102
+ yes: (opts.yes ?? false) || syncNudgeAccepted,
8103
+ retryCommand: "caveat init --sync <url>",
8104
+ ghRunner,
8105
+ isTty,
8106
+ confirm
8107
+ });
8108
+ const result = await initOwnSync({
8109
+ ownDir: ctx.paths.knowledgeRepo,
8110
+ url: url2,
8111
+ caveatHome: ctx.caveatHome,
8112
+ paths: ctx.paths,
8113
+ logger: ctx.logger,
8114
+ // file: remotes are governed by local filesystem permissions and have
8115
+ // no anonymous HTTP surface for the remote-visibility probe to inspect.
8116
+ trustRemotePrivate: isFileRemote(url2)
8117
+ });
8118
+ ctx.logger.info(
8119
+ result.remoteWasEmpty ? `initialized private sync remote: ${url2}` : `checked out existing private remote: ${url2} (branch ${result.branch})`
8120
+ );
8121
+ }
7898
8122
  }
7899
8123
  } catch (err) {
7900
- if (err instanceof SyncError && err.code === "OWN_REPO_EXISTS") {
7901
- ctx.logger.info("private sync already configured (own repo exists); skipped");
7902
- } else {
7903
- ctx.logger.warn(`private sync setup skipped: ${errorMessage(err)}`);
7904
- }
8124
+ throw new Error(`private sync setup failed: ${errorMessage(err)}`, { cause: err });
7905
8125
  }
7906
8126
  }
7907
8127
  let publishRequested = opts.publishTarget !== void 0 && opts.publishTarget !== false;
7908
8128
  let publishNudgeAccepted = false;
7909
- if (opts.publishTarget === void 0 && isTty()) {
8129
+ if (opts.publishTarget === void 0 && !opts.yes && isTty()) {
7910
8130
  publishNudgeAccepted = confirm("\u516C\u958B repo\uFF08\u5C01\u7DD8\u30DF\u30E9\u30FC\uFF09\u3082\u8A2D\u5B9A\u3059\u308B\uFF1F [y/N]");
7911
8131
  publishRequested = publishNudgeAccepted;
7912
8132
  }
@@ -7939,33 +8159,36 @@ async function runInit(ctx, opts = { skipClaude: false, dryRun: false }, depende
7939
8159
  if (opts.skipClaude) {
7940
8160
  ctx.logger.info("Claude Code integration skipped (--skip-claude)");
7941
8161
  } else {
7942
- const cliScriptPath = process.argv[1];
7943
- if (!cliScriptPath) {
8162
+ const cliScriptPath2 = process.argv[1];
8163
+ if (!cliScriptPath2) {
7944
8164
  ctx.logger.warn("cannot determine CLI script path; skipping Claude integration");
7945
8165
  } else {
7946
8166
  const result = installClaudeIntegration({
7947
- claudeDir: join8(ctx.userHome, ".claude"),
7948
- cliScriptPath,
8167
+ claudeDir,
8168
+ mcpConfigPath: claudeMcp,
8169
+ cliScriptPath: cliScriptPath2,
7949
8170
  nodePath: resolveHookNodePath(),
7950
8171
  dryRun: opts.dryRun,
7951
8172
  logger: ctx.logger
7952
8173
  });
7953
8174
  reportInstallResult(ctx, result, opts.dryRun);
8175
+ if (result.mcp.action === "failed") {
8176
+ throw new Error(`mcp_setup_failed: Claude Code: ${result.mcp.detail}`);
8177
+ }
7954
8178
  }
7955
8179
  }
7956
8180
  if (opts.skipCodexHook) {
7957
8181
  codexHookState = "skipped";
7958
8182
  ctx.logger.info("Codex hook integration skipped (--skip-codex-hook)");
7959
- } else if ((dependencies.codexAvailable ?? detectCodexAvailability)()) {
7960
- const cliScriptPath = process.argv[1];
7961
- if (!cliScriptPath) {
8183
+ } else if (codexAvailable) {
8184
+ const cliScriptPath2 = process.argv[1];
8185
+ if (!cliScriptPath2) {
7962
8186
  codexHookState = "skipped";
7963
8187
  ctx.logger.warn("cannot determine CLI script path; skipping Codex hook integration");
7964
8188
  } else {
7965
- const codexHome = join8(ctx.userHome, ".codex");
7966
8189
  const result = installCodexHooks({
7967
8190
  codexHome,
7968
- cliScriptPath,
8191
+ cliScriptPath: cliScriptPath2,
7969
8192
  nodePath: resolveHookNodePath(),
7970
8193
  dryRun: opts.dryRun,
7971
8194
  logger: ctx.logger
@@ -7973,7 +8196,7 @@ async function runInit(ctx, opts = { skipClaude: false, dryRun: false }, depende
7973
8196
  if (result.feature === "blocked") {
7974
8197
  codexHookState = "skipped";
7975
8198
  ctx.logger.warn(
7976
- `${result.blockedReason}; preserving explicit consent. Set \`hooks = true\` in ${join8(codexHome, "config.toml")}, then rerun \`caveat init\`.`
8199
+ `${result.blockedReason}; preserving explicit consent. Set \`hooks = true\` in ${join10(codexHome, "config.toml")}, then rerun \`caveat init\`.`
7977
8200
  );
7978
8201
  } else if (opts.dryRun) {
7979
8202
  codexHookState = "skipped";
@@ -7983,10 +8206,48 @@ async function runInit(ctx, opts = { skipClaude: false, dryRun: false }, depende
7983
8206
  }
7984
8207
  }
7985
8208
  }
7986
- reportEnvironmentSummary(ctx, publishTarget, codexHookState, opts.dryRun);
8209
+ if (opts.skipCursorHook) {
8210
+ cursorHookState = "skipped";
8211
+ ctx.logger.info("Cursor hook integration skipped (--skip-cursor-hook)");
8212
+ } else if (existsSync8(cursorDir)) {
8213
+ const cliScriptPath2 = process.argv[1];
8214
+ if (!cliScriptPath2) {
8215
+ cursorHookState = "skipped";
8216
+ ctx.logger.warn("cannot determine CLI script path; skipping Cursor hook integration");
8217
+ } else {
8218
+ const result = installCursorHooks({
8219
+ cursorDir,
8220
+ cliScriptPath: cliScriptPath2,
8221
+ nodePath: resolveHookNodePath(),
8222
+ dryRun: opts.dryRun,
8223
+ logger: ctx.logger
8224
+ });
8225
+ if (opts.dryRun) {
8226
+ cursorHookState = "skipped";
8227
+ ctx.logger.info("[dry-run] would install Cursor hooks");
8228
+ } else {
8229
+ cursorHookState = detectCursorHookInstallation(cursorDir).installation;
8230
+ ctx.logger.info(`Cursor beforeSubmitPrompt hook: ${result.hooks.beforeSubmitPrompt}`);
8231
+ ctx.logger.info(`Cursor postToolUse hook: ${result.hooks.postToolUse}`);
8232
+ ctx.logger.info(`Cursor stop hook: ${result.hooks.stop}`);
8233
+ }
8234
+ }
8235
+ }
8236
+ const cliScriptPath = process.argv[1];
8237
+ if (!cliScriptPath) throw new Error("mcp_setup_failed: CLI\u306E\u5B9F\u884C\u30D1\u30B9\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093");
8238
+ for (const [client, configPath, available] of [
8239
+ ["codex", join10(codexHome, "config.toml"), codexAvailable || existsSync8(codexHome)],
8240
+ ["grok", join10(grokHome, "config.toml"), existsSync8(grokHome)],
8241
+ ["cursor", join10(cursorDir, "mcp.json"), existsSync8(cursorDir)]
8242
+ ]) {
8243
+ if (!available) continue;
8244
+ const action = installMcpClient({ client, configPath, cliScriptPath, nodePath: resolveHookNodePath(), dryRun: opts.dryRun });
8245
+ ctx.logger.info(`${client} MCP: ${action}`);
8246
+ }
8247
+ reportEnvironmentSummary(ctx, publishTarget, codexHookState, cursorHookState, opts.dryRun);
7987
8248
  }
7988
8249
  function detectCodexAvailability() {
7989
- const result = spawnSync4("codex --version", {
8250
+ const result = spawnSync3("codex --version", {
7990
8251
  shell: true,
7991
8252
  encoding: "utf-8",
7992
8253
  stdio: "ignore"
@@ -8001,39 +8262,40 @@ function isFileRemote(url2) {
8001
8262
  }
8002
8263
  }
8003
8264
  function gitOutput(args) {
8004
- const result = spawnSync4("git", args, { encoding: "utf-8" });
8265
+ const result = spawnSync3("git", args, { encoding: "utf-8" });
8005
8266
  return result.status === 0 && typeof result.stdout === "string" ? result.stdout.trim() : null;
8006
8267
  }
8007
- function reportEnvironmentSummary(ctx, publishTarget, codexHookState, dryRun) {
8268
+ function reportEnvironmentSummary(ctx, publishTarget, codexHookState, cursorHookState, dryRun) {
8008
8269
  const prefix = dryRun ? "[dry-run] would have " : "";
8009
8270
  const isRepo = gitOutput(["-C", ctx.paths.knowledgeRepo, "rev-parse", "--is-inside-work-tree"]) === "true";
8010
8271
  const remote = isRepo ? gitOutput(["-C", ctx.paths.knowledgeRepo, "config", "--get", "remote.origin.url"]) : null;
8011
- const communityCount = existsSync6(ctx.paths.communityDir) ? readdirSync(ctx.paths.communityDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).length : 0;
8272
+ const communityCount = existsSync8(ctx.paths.communityDir) ? readdirSync(ctx.paths.communityDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).length : 0;
8012
8273
  ctx.logger.info(`${prefix}environment summary:`);
8013
8274
  ctx.logger.info(` own git: ${isRepo ? "repository" : "not initialized"}`);
8014
8275
  ctx.logger.info(` private remote: ${remote || "not configured"}`);
8015
8276
  ctx.logger.info(` publish target: ${publishTarget || "not configured"}`);
8016
8277
  ctx.logger.info(` community sources: ${communityCount}`);
8017
8278
  ctx.logger.info(` codex hook: ${codexHookState}`);
8279
+ ctx.logger.info(` cursor hook: ${cursorHookState}`);
8018
8280
  }
8019
8281
  function errorMessage(err) {
8020
8282
  return err instanceof Error ? err.message : String(err);
8021
8283
  }
8022
8284
  function migrateLegacyCommunityDir(ctx) {
8023
- const legacy = join8(ctx.paths.knowledgeRepo, "community");
8285
+ const legacy = join10(ctx.paths.knowledgeRepo, "community");
8024
8286
  const current = ctx.paths.communityDir;
8025
8287
  if (legacy === current) return;
8026
- if (!existsSync6(legacy)) return;
8027
- if (existsSync6(current)) {
8288
+ if (!existsSync8(legacy)) return;
8289
+ if (existsSync8(current)) {
8028
8290
  ctx.logger.warn(
8029
8291
  `legacy community dir still exists at ${legacy} \u2014 remove manually (new location in use)`
8030
8292
  );
8031
8293
  return;
8032
8294
  }
8033
- mkdirSync2(current, { recursive: true });
8295
+ mkdirSync3(current, { recursive: true });
8034
8296
  for (const entry of readdirSync(legacy, { withFileTypes: true })) {
8035
8297
  if (!entry.isDirectory()) continue;
8036
- renameSync(join8(legacy, entry.name), join8(current, entry.name));
8298
+ renameSync(join10(legacy, entry.name), join10(current, entry.name));
8037
8299
  }
8038
8300
  try {
8039
8301
  rmdirSync(legacy);
@@ -8047,13 +8309,16 @@ function runUninstall(ctx, opts) {
8047
8309
  ctx.logger.error("cannot determine CLI script path");
8048
8310
  process.exit(1);
8049
8311
  }
8312
+ const { claudeDir, claudeMcp } = resolveAgentConfigPaths(ctx.userHome);
8050
8313
  const result = uninstallClaudeIntegration({
8051
- claudeDir: join8(ctx.userHome, ".claude"),
8314
+ claudeDir,
8315
+ mcpConfigPath: claudeMcp,
8052
8316
  cliScriptPath,
8053
8317
  nodePath: resolveHookNodePath(),
8054
8318
  dryRun: opts.dryRun,
8055
8319
  logger: ctx.logger
8056
8320
  });
8321
+ if (result.mcp.action === "failed") throw new Error(`mcp_uninstall_failed: Claude Code: ${result.mcp.detail}`);
8057
8322
  ctx.logger.info(
8058
8323
  `MCP: ${result.mcp.action}${result.mcp.detail ? ` (${result.mcp.detail})` : ""}`
8059
8324
  );
@@ -8095,11 +8360,11 @@ function reportInstallResult(ctx, result, dryRun) {
8095
8360
  }
8096
8361
 
8097
8362
  // src/commands/indexCmd.ts
8098
- import { existsSync as existsSync7, mkdirSync as mkdirSync3 } from "node:fs";
8363
+ import { existsSync as existsSync9, mkdirSync as mkdirSync4 } from "node:fs";
8099
8364
  import { dirname as dirname4 } from "node:path";
8100
8365
  async function runIndex(ctx, opts) {
8101
8366
  const dbDir = dirname4(ctx.paths.dbPath);
8102
- if (!existsSync7(dbDir)) mkdirSync3(dbDir, { recursive: true });
8367
+ if (!existsSync9(dbDir)) mkdirSync4(dbDir, { recursive: true });
8103
8368
  const keyProvider = createKeyserverKeyProvider({ caveatHome: ctx.caveatHome });
8104
8369
  const failures = await prewarmSealedKeys({ paths: ctx.paths, keyProvider });
8105
8370
  for (const failure of failures) {
@@ -8283,7 +8548,7 @@ function runStats(ctx) {
8283
8548
 
8284
8549
  // src/commands/serve.ts
8285
8550
  async function runServe(opts) {
8286
- const { startServer } = await import("./server-GBVHOF67.js");
8551
+ const { startServer } = await import("./server-H6MVY5OK.js");
8287
8552
  const { port, host } = startServer({ port: opts.port });
8288
8553
  process.stdout.write(`[caveat] web portal: http://${host}:${port}/
8289
8554
  `);
@@ -8322,10 +8587,10 @@ var util;
8322
8587
  return obj[e];
8323
8588
  });
8324
8589
  };
8325
- util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object3) => {
8590
+ util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object4) => {
8326
8591
  const keys = [];
8327
- for (const key in object3) {
8328
- if (Object.prototype.hasOwnProperty.call(object3, key)) {
8592
+ for (const key in object4) {
8593
+ if (Object.prototype.hasOwnProperty.call(object4, key)) {
8329
8594
  keys.push(key);
8330
8595
  }
8331
8596
  }
@@ -12426,7 +12691,7 @@ __export(core_exports2, {
12426
12691
  isValidJWT: () => isValidJWT2,
12427
12692
  locales: () => locales_exports,
12428
12693
  meta: () => meta,
12429
- parse: () => parse,
12694
+ parse: () => parse2,
12430
12695
  parseAsync: () => parseAsync,
12431
12696
  prettifyError: () => prettifyError,
12432
12697
  process: () => process2,
@@ -12645,9 +12910,9 @@ function floatSafeRemainder2(val, step) {
12645
12910
  return ratio - roundedRatio;
12646
12911
  }
12647
12912
  var EVALUATING = /* @__PURE__ */ Symbol("evaluating");
12648
- function defineLazy(object3, key, getter) {
12913
+ function defineLazy(object4, key, getter) {
12649
12914
  let value = void 0;
12650
- Object.defineProperty(object3, key, {
12915
+ Object.defineProperty(object4, key, {
12651
12916
  get() {
12652
12917
  if (value === EVALUATING) {
12653
12918
  return void 0;
@@ -12659,7 +12924,7 @@ function defineLazy(object3, key, getter) {
12659
12924
  return value;
12660
12925
  },
12661
12926
  set(v) {
12662
- Object.defineProperty(object3, key, {
12927
+ Object.defineProperty(object4, key, {
12663
12928
  value: v
12664
12929
  // configurable: true,
12665
12930
  });
@@ -13371,7 +13636,7 @@ var _parse = (_Err) => (schema, value, _ctx, _params) => {
13371
13636
  }
13372
13637
  return result.value;
13373
13638
  };
13374
- var parse = /* @__PURE__ */ _parse($ZodRealError);
13639
+ var parse2 = /* @__PURE__ */ _parse($ZodRealError);
13375
13640
  var _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
13376
13641
  const ctx = _ctx ? { ..._ctx, async: true } : { async: true };
13377
13642
  let result = schema._zod.run({ value, issues: [] }, ctx);
@@ -16163,10 +16428,10 @@ var $ZodFunction = /* @__PURE__ */ $constructor("$ZodFunction", (inst, def) => {
16163
16428
  throw new Error("implement() must be called with a function");
16164
16429
  }
16165
16430
  return function(...args) {
16166
- const parsedArgs = inst._def.input ? parse(inst._def.input, args) : args;
16431
+ const parsedArgs = inst._def.input ? parse2(inst._def.input, args) : args;
16167
16432
  const result = Reflect.apply(func, this, parsedArgs);
16168
16433
  if (inst._def.output) {
16169
- return parse(inst._def.output, result);
16434
+ return parse2(inst._def.output, result);
16170
16435
  }
16171
16436
  return result;
16172
16437
  };
@@ -24320,7 +24585,7 @@ var ZodMiniType = /* @__PURE__ */ $constructor("ZodMiniType", (inst, def) => {
24320
24585
  $ZodType.init(inst, def);
24321
24586
  inst.def = def;
24322
24587
  inst.type = def.type;
24323
- inst.parse = (data, params) => parse(inst, data, params, { callee: inst.parse });
24588
+ inst.parse = (data, params) => parse2(inst, data, params, { callee: inst.parse });
24324
24589
  inst.safeParse = (data, params) => safeParse(inst, data, params);
24325
24590
  inst.parseAsync = async (data, params) => parseAsync(inst, data, params, { callee: inst.parseAsync });
24326
24591
  inst.safeParseAsync = async (data, params) => safeParseAsync(inst, data, params);
@@ -24350,7 +24615,7 @@ var ZodMiniObject = /* @__PURE__ */ $constructor("ZodMiniObject", (inst, def) =>
24350
24615
  defineLazy(inst, "shape", () => def.shape);
24351
24616
  });
24352
24617
  // @__NO_SIDE_EFFECTS__
24353
- function object(shape, params) {
24618
+ function object2(shape, params) {
24354
24619
  const def = {
24355
24620
  type: "object",
24356
24621
  shape: shape ?? {},
@@ -24367,11 +24632,11 @@ function isZ4Schema(s) {
24367
24632
  function objectFromShape(shape) {
24368
24633
  const values = Object.values(shape);
24369
24634
  if (values.length === 0)
24370
- return object({});
24635
+ return object2({});
24371
24636
  const allV4 = values.every(isZ4Schema);
24372
24637
  const allV3 = values.every((s) => !isZ4Schema(s));
24373
24638
  if (allV4)
24374
- return object(shape);
24639
+ return object2(shape);
24375
24640
  if (allV3)
24376
24641
  return objectType(shape);
24377
24642
  throw new Error("Mixed Zod versions detected in object shape.");
@@ -24683,10 +24948,10 @@ __export(external_exports, {
24683
24948
  nullable: () => nullable,
24684
24949
  nullish: () => nullish2,
24685
24950
  number: () => number2,
24686
- object: () => object2,
24951
+ object: () => object3,
24687
24952
  optional: () => optional,
24688
24953
  overwrite: () => _overwrite,
24689
- parse: () => parse2,
24954
+ parse: () => parse3,
24690
24955
  parseAsync: () => parseAsync2,
24691
24956
  partialRecord: () => partialRecord,
24692
24957
  pipe: () => pipe,
@@ -24880,7 +25145,7 @@ __export(schemas_exports2, {
24880
25145
  nullable: () => nullable,
24881
25146
  nullish: () => nullish2,
24882
25147
  number: () => number2,
24883
- object: () => object2,
25148
+ object: () => object3,
24884
25149
  optional: () => optional,
24885
25150
  partialRecord: () => partialRecord,
24886
25151
  pipe: () => pipe,
@@ -25033,7 +25298,7 @@ var ZodRealError = /* @__PURE__ */ $constructor("ZodError", initializer2, {
25033
25298
  });
25034
25299
 
25035
25300
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/parse.js
25036
- var parse2 = /* @__PURE__ */ _parse(ZodRealError);
25301
+ var parse3 = /* @__PURE__ */ _parse(ZodRealError);
25037
25302
  var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
25038
25303
  var safeParse3 = /* @__PURE__ */ _safeParse(ZodRealError);
25039
25304
  var safeParseAsync3 = /* @__PURE__ */ _safeParseAsync(ZodRealError);
@@ -25096,7 +25361,7 @@ var ZodType2 = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
25096
25361
  inst.def = def;
25097
25362
  inst.type = def.type;
25098
25363
  Object.defineProperty(inst, "_def", { value: def });
25099
- inst.parse = (data, params) => parse2(inst, data, params, { callee: inst.parse });
25364
+ inst.parse = (data, params) => parse3(inst, data, params, { callee: inst.parse });
25100
25365
  inst.safeParse = (data, params) => safeParse3(inst, data, params);
25101
25366
  inst.parseAsync = async (data, params) => parseAsync2(inst, data, params, { callee: inst.parseAsync });
25102
25367
  inst.safeParseAsync = async (data, params) => safeParseAsync3(inst, data, params);
@@ -25755,7 +26020,7 @@ var ZodObject2 = /* @__PURE__ */ $constructor("ZodObject", (inst, def) => {
25755
26020
  }
25756
26021
  });
25757
26022
  });
25758
- function object2(shape, params) {
26023
+ function object3(shape, params) {
25759
26024
  const def = {
25760
26025
  type: "object",
25761
26026
  shape: shape ?? {},
@@ -26888,10 +27153,10 @@ var TaskCreationParamsSchema = looseObject({
26888
27153
  */
26889
27154
  pollInterval: number2().optional()
26890
27155
  });
26891
- var TaskMetadataSchema = object2({
27156
+ var TaskMetadataSchema = object3({
26892
27157
  ttl: number2().optional()
26893
27158
  });
26894
- var RelatedTaskMetadataSchema = object2({
27159
+ var RelatedTaskMetadataSchema = object3({
26895
27160
  taskId: string2()
26896
27161
  });
26897
27162
  var RequestMetaSchema = looseObject({
@@ -26904,7 +27169,7 @@ var RequestMetaSchema = looseObject({
26904
27169
  */
26905
27170
  [RELATED_TASK_META_KEY]: RelatedTaskMetadataSchema.optional()
26906
27171
  });
26907
- var BaseRequestParamsSchema = object2({
27172
+ var BaseRequestParamsSchema = object3({
26908
27173
  /**
26909
27174
  * See [General fields: `_meta`](/specification/draft/basic/index#meta) for notes on `_meta` usage.
26910
27175
  */
@@ -26922,18 +27187,18 @@ var TaskAugmentedRequestParamsSchema = BaseRequestParamsSchema.extend({
26922
27187
  task: TaskMetadataSchema.optional()
26923
27188
  });
26924
27189
  var isTaskAugmentedRequestParams = (value) => TaskAugmentedRequestParamsSchema.safeParse(value).success;
26925
- var RequestSchema = object2({
27190
+ var RequestSchema = object3({
26926
27191
  method: string2(),
26927
27192
  params: BaseRequestParamsSchema.loose().optional()
26928
27193
  });
26929
- var NotificationsParamsSchema = object2({
27194
+ var NotificationsParamsSchema = object3({
26930
27195
  /**
26931
27196
  * See [MCP specification](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/47339c03c143bb4ec01a26e721a1b8fe66634ebe/docs/specification/draft/basic/index.mdx#general-fields)
26932
27197
  * for notes on _meta usage.
26933
27198
  */
26934
27199
  _meta: RequestMetaSchema.optional()
26935
27200
  });
26936
- var NotificationSchema = object2({
27201
+ var NotificationSchema = object3({
26937
27202
  method: string2(),
26938
27203
  params: NotificationsParamsSchema.loose().optional()
26939
27204
  });
@@ -26945,18 +27210,18 @@ var ResultSchema = looseObject({
26945
27210
  _meta: RequestMetaSchema.optional()
26946
27211
  });
26947
27212
  var RequestIdSchema = union([string2(), number2().int()]);
26948
- var JSONRPCRequestSchema = object2({
27213
+ var JSONRPCRequestSchema = object3({
26949
27214
  jsonrpc: literal(JSONRPC_VERSION),
26950
27215
  id: RequestIdSchema,
26951
27216
  ...RequestSchema.shape
26952
27217
  }).strict();
26953
27218
  var isJSONRPCRequest = (value) => JSONRPCRequestSchema.safeParse(value).success;
26954
- var JSONRPCNotificationSchema = object2({
27219
+ var JSONRPCNotificationSchema = object3({
26955
27220
  jsonrpc: literal(JSONRPC_VERSION),
26956
27221
  ...NotificationSchema.shape
26957
27222
  }).strict();
26958
27223
  var isJSONRPCNotification = (value) => JSONRPCNotificationSchema.safeParse(value).success;
26959
- var JSONRPCResultResponseSchema = object2({
27224
+ var JSONRPCResultResponseSchema = object3({
26960
27225
  jsonrpc: literal(JSONRPC_VERSION),
26961
27226
  id: RequestIdSchema,
26962
27227
  result: ResultSchema
@@ -26973,10 +27238,10 @@ var ErrorCode;
26973
27238
  ErrorCode2[ErrorCode2["InternalError"] = -32603] = "InternalError";
26974
27239
  ErrorCode2[ErrorCode2["UrlElicitationRequired"] = -32042] = "UrlElicitationRequired";
26975
27240
  })(ErrorCode || (ErrorCode = {}));
26976
- var JSONRPCErrorResponseSchema = object2({
27241
+ var JSONRPCErrorResponseSchema = object3({
26977
27242
  jsonrpc: literal(JSONRPC_VERSION),
26978
27243
  id: RequestIdSchema.optional(),
26979
- error: object2({
27244
+ error: object3({
26980
27245
  /**
26981
27246
  * The error type that occurred.
26982
27247
  */
@@ -27016,7 +27281,7 @@ var CancelledNotificationSchema = NotificationSchema.extend({
27016
27281
  method: literal("notifications/cancelled"),
27017
27282
  params: CancelledNotificationParamsSchema
27018
27283
  });
27019
- var IconSchema = object2({
27284
+ var IconSchema = object3({
27020
27285
  /**
27021
27286
  * URL or data URI for the icon.
27022
27287
  */
@@ -27041,7 +27306,7 @@ var IconSchema = object2({
27041
27306
  */
27042
27307
  theme: _enum2(["light", "dark"]).optional()
27043
27308
  });
27044
- var IconsSchema = object2({
27309
+ var IconsSchema = object3({
27045
27310
  /**
27046
27311
  * Optional set of sized icons that the client can display in a user interface.
27047
27312
  *
@@ -27055,7 +27320,7 @@ var IconsSchema = object2({
27055
27320
  */
27056
27321
  icons: array(IconSchema).optional()
27057
27322
  });
27058
- var BaseMetadataSchema = object2({
27323
+ var BaseMetadataSchema = object3({
27059
27324
  /** Intended for programmatic or logical use, but used as a display name in past specs or fallback */
27060
27325
  name: string2(),
27061
27326
  /**
@@ -27085,7 +27350,7 @@ var ImplementationSchema = BaseMetadataSchema.extend({
27085
27350
  */
27086
27351
  description: string2().optional()
27087
27352
  });
27088
- var FormElicitationCapabilitySchema = intersection(object2({
27353
+ var FormElicitationCapabilitySchema = intersection(object3({
27089
27354
  applyDefaults: boolean2().optional()
27090
27355
  }), record(string2(), unknown()));
27091
27356
  var ElicitationCapabilitySchema = preprocess((value) => {
@@ -27095,7 +27360,7 @@ var ElicitationCapabilitySchema = preprocess((value) => {
27095
27360
  }
27096
27361
  }
27097
27362
  return value;
27098
- }, intersection(object2({
27363
+ }, intersection(object3({
27099
27364
  form: FormElicitationCapabilitySchema.optional(),
27100
27365
  url: AssertObjectSchema.optional()
27101
27366
  }), record(string2(), unknown()).optional()));
@@ -27147,7 +27412,7 @@ var ServerTasksCapabilitySchema = looseObject({
27147
27412
  }).optional()
27148
27413
  }).optional()
27149
27414
  });
27150
- var ClientCapabilitiesSchema = object2({
27415
+ var ClientCapabilitiesSchema = object3({
27151
27416
  /**
27152
27417
  * Experimental, non-standard capabilities that the client supports.
27153
27418
  */
@@ -27155,7 +27420,7 @@ var ClientCapabilitiesSchema = object2({
27155
27420
  /**
27156
27421
  * Present if the client supports sampling from an LLM.
27157
27422
  */
27158
- sampling: object2({
27423
+ sampling: object3({
27159
27424
  /**
27160
27425
  * Present if the client supports context inclusion via includeContext parameter.
27161
27426
  * If not declared, servers SHOULD only use `includeContext: "none"` (or omit it).
@@ -27173,7 +27438,7 @@ var ClientCapabilitiesSchema = object2({
27173
27438
  /**
27174
27439
  * Present if the client supports listing roots.
27175
27440
  */
27176
- roots: object2({
27441
+ roots: object3({
27177
27442
  /**
27178
27443
  * Whether the client supports issuing notifications for changes to the roots list.
27179
27444
  */
@@ -27200,7 +27465,7 @@ var InitializeRequestSchema = RequestSchema.extend({
27200
27465
  method: literal("initialize"),
27201
27466
  params: InitializeRequestParamsSchema
27202
27467
  });
27203
- var ServerCapabilitiesSchema = object2({
27468
+ var ServerCapabilitiesSchema = object3({
27204
27469
  /**
27205
27470
  * Experimental, non-standard capabilities that the server supports.
27206
27471
  */
@@ -27216,7 +27481,7 @@ var ServerCapabilitiesSchema = object2({
27216
27481
  /**
27217
27482
  * Present if the server offers any prompt templates.
27218
27483
  */
27219
- prompts: object2({
27484
+ prompts: object3({
27220
27485
  /**
27221
27486
  * Whether this server supports issuing notifications for changes to the prompt list.
27222
27487
  */
@@ -27225,7 +27490,7 @@ var ServerCapabilitiesSchema = object2({
27225
27490
  /**
27226
27491
  * Present if the server offers any resources to read.
27227
27492
  */
27228
- resources: object2({
27493
+ resources: object3({
27229
27494
  /**
27230
27495
  * Whether this server supports clients subscribing to resource updates.
27231
27496
  */
@@ -27238,7 +27503,7 @@ var ServerCapabilitiesSchema = object2({
27238
27503
  /**
27239
27504
  * Present if the server offers any tools to call.
27240
27505
  */
27241
- tools: object2({
27506
+ tools: object3({
27242
27507
  /**
27243
27508
  * Whether this server supports issuing notifications for changes to the tool list.
27244
27509
  */
@@ -27275,7 +27540,7 @@ var PingRequestSchema = RequestSchema.extend({
27275
27540
  method: literal("ping"),
27276
27541
  params: BaseRequestParamsSchema.optional()
27277
27542
  });
27278
- var ProgressSchema = object2({
27543
+ var ProgressSchema = object3({
27279
27544
  /**
27280
27545
  * The progress thus far. This should increase every time progress is made, even if the total is unknown.
27281
27546
  */
@@ -27289,7 +27554,7 @@ var ProgressSchema = object2({
27289
27554
  */
27290
27555
  message: optional(string2())
27291
27556
  });
27292
- var ProgressNotificationParamsSchema = object2({
27557
+ var ProgressNotificationParamsSchema = object3({
27293
27558
  ...NotificationsParamsSchema.shape,
27294
27559
  ...ProgressSchema.shape,
27295
27560
  /**
@@ -27319,7 +27584,7 @@ var PaginatedResultSchema = ResultSchema.extend({
27319
27584
  nextCursor: CursorSchema.optional()
27320
27585
  });
27321
27586
  var TaskStatusSchema = _enum2(["working", "input_required", "completed", "failed", "cancelled"]);
27322
- var TaskSchema = object2({
27587
+ var TaskSchema = object3({
27323
27588
  taskId: string2(),
27324
27589
  status: TaskStatusSchema,
27325
27590
  /**
@@ -27376,7 +27641,7 @@ var CancelTaskRequestSchema = RequestSchema.extend({
27376
27641
  })
27377
27642
  });
27378
27643
  var CancelTaskResultSchema = ResultSchema.merge(TaskSchema);
27379
- var ResourceContentsSchema = object2({
27644
+ var ResourceContentsSchema = object3({
27380
27645
  /**
27381
27646
  * The URI of this resource.
27382
27647
  */
@@ -27412,7 +27677,7 @@ var BlobResourceContentsSchema = ResourceContentsSchema.extend({
27412
27677
  blob: Base64Schema
27413
27678
  });
27414
27679
  var RoleSchema = _enum2(["user", "assistant"]);
27415
- var AnnotationsSchema = object2({
27680
+ var AnnotationsSchema = object3({
27416
27681
  /**
27417
27682
  * Intended audience(s) for the resource.
27418
27683
  */
@@ -27426,7 +27691,7 @@ var AnnotationsSchema = object2({
27426
27691
  */
27427
27692
  lastModified: iso_exports2.datetime({ offset: true }).optional()
27428
27693
  });
27429
- var ResourceSchema = object2({
27694
+ var ResourceSchema = object3({
27430
27695
  ...BaseMetadataSchema.shape,
27431
27696
  ...IconsSchema.shape,
27432
27697
  /**
@@ -27459,7 +27724,7 @@ var ResourceSchema = object2({
27459
27724
  */
27460
27725
  _meta: optional(looseObject({}))
27461
27726
  });
27462
- var ResourceTemplateSchema = object2({
27727
+ var ResourceTemplateSchema = object3({
27463
27728
  ...BaseMetadataSchema.shape,
27464
27729
  ...IconsSchema.shape,
27465
27730
  /**
@@ -27538,7 +27803,7 @@ var ResourceUpdatedNotificationSchema = NotificationSchema.extend({
27538
27803
  method: literal("notifications/resources/updated"),
27539
27804
  params: ResourceUpdatedNotificationParamsSchema
27540
27805
  });
27541
- var PromptArgumentSchema = object2({
27806
+ var PromptArgumentSchema = object3({
27542
27807
  /**
27543
27808
  * The name of the argument.
27544
27809
  */
@@ -27552,7 +27817,7 @@ var PromptArgumentSchema = object2({
27552
27817
  */
27553
27818
  required: optional(boolean2())
27554
27819
  });
27555
- var PromptSchema = object2({
27820
+ var PromptSchema = object3({
27556
27821
  ...BaseMetadataSchema.shape,
27557
27822
  ...IconsSchema.shape,
27558
27823
  /**
@@ -27589,7 +27854,7 @@ var GetPromptRequestSchema = RequestSchema.extend({
27589
27854
  method: literal("prompts/get"),
27590
27855
  params: GetPromptRequestParamsSchema
27591
27856
  });
27592
- var TextContentSchema = object2({
27857
+ var TextContentSchema = object3({
27593
27858
  type: literal("text"),
27594
27859
  /**
27595
27860
  * The text content of the message.
@@ -27605,7 +27870,7 @@ var TextContentSchema = object2({
27605
27870
  */
27606
27871
  _meta: record(string2(), unknown()).optional()
27607
27872
  });
27608
- var ImageContentSchema = object2({
27873
+ var ImageContentSchema = object3({
27609
27874
  type: literal("image"),
27610
27875
  /**
27611
27876
  * The base64-encoded image data.
@@ -27625,7 +27890,7 @@ var ImageContentSchema = object2({
27625
27890
  */
27626
27891
  _meta: record(string2(), unknown()).optional()
27627
27892
  });
27628
- var AudioContentSchema = object2({
27893
+ var AudioContentSchema = object3({
27629
27894
  type: literal("audio"),
27630
27895
  /**
27631
27896
  * The base64-encoded audio data.
@@ -27645,7 +27910,7 @@ var AudioContentSchema = object2({
27645
27910
  */
27646
27911
  _meta: record(string2(), unknown()).optional()
27647
27912
  });
27648
- var ToolUseContentSchema = object2({
27913
+ var ToolUseContentSchema = object3({
27649
27914
  type: literal("tool_use"),
27650
27915
  /**
27651
27916
  * The name of the tool to invoke.
@@ -27668,7 +27933,7 @@ var ToolUseContentSchema = object2({
27668
27933
  */
27669
27934
  _meta: record(string2(), unknown()).optional()
27670
27935
  });
27671
- var EmbeddedResourceSchema = object2({
27936
+ var EmbeddedResourceSchema = object3({
27672
27937
  type: literal("resource"),
27673
27938
  resource: union([TextResourceContentsSchema, BlobResourceContentsSchema]),
27674
27939
  /**
@@ -27691,7 +27956,7 @@ var ContentBlockSchema = union([
27691
27956
  ResourceLinkSchema,
27692
27957
  EmbeddedResourceSchema
27693
27958
  ]);
27694
- var PromptMessageSchema = object2({
27959
+ var PromptMessageSchema = object3({
27695
27960
  role: RoleSchema,
27696
27961
  content: ContentBlockSchema
27697
27962
  });
@@ -27706,7 +27971,7 @@ var PromptListChangedNotificationSchema = NotificationSchema.extend({
27706
27971
  method: literal("notifications/prompts/list_changed"),
27707
27972
  params: NotificationsParamsSchema.optional()
27708
27973
  });
27709
- var ToolAnnotationsSchema = object2({
27974
+ var ToolAnnotationsSchema = object3({
27710
27975
  /**
27711
27976
  * A human-readable title for the tool.
27712
27977
  */
@@ -27745,7 +28010,7 @@ var ToolAnnotationsSchema = object2({
27745
28010
  */
27746
28011
  openWorldHint: boolean2().optional()
27747
28012
  });
27748
- var ToolExecutionSchema = object2({
28013
+ var ToolExecutionSchema = object3({
27749
28014
  /**
27750
28015
  * Indicates the tool's preference for task-augmented execution.
27751
28016
  * - "required": Clients MUST invoke the tool as a task
@@ -27756,7 +28021,7 @@ var ToolExecutionSchema = object2({
27756
28021
  */
27757
28022
  taskSupport: _enum2(["required", "optional", "forbidden"]).optional()
27758
28023
  });
27759
- var ToolSchema = object2({
28024
+ var ToolSchema = object3({
27760
28025
  ...BaseMetadataSchema.shape,
27761
28026
  ...IconsSchema.shape,
27762
28027
  /**
@@ -27767,7 +28032,7 @@ var ToolSchema = object2({
27767
28032
  * A JSON Schema 2020-12 object defining the expected parameters for the tool.
27768
28033
  * Must have type: 'object' at the root level per MCP spec.
27769
28034
  */
27770
- inputSchema: object2({
28035
+ inputSchema: object3({
27771
28036
  type: literal("object"),
27772
28037
  properties: record(string2(), AssertObjectSchema).optional(),
27773
28038
  required: array(string2()).optional()
@@ -27777,7 +28042,7 @@ var ToolSchema = object2({
27777
28042
  * returned in the structuredContent field of a CallToolResult.
27778
28043
  * Must have type: 'object' at the root level per MCP spec.
27779
28044
  */
27780
- outputSchema: object2({
28045
+ outputSchema: object3({
27781
28046
  type: literal("object"),
27782
28047
  properties: record(string2(), AssertObjectSchema).optional(),
27783
28048
  required: array(string2()).optional()
@@ -27853,7 +28118,7 @@ var ToolListChangedNotificationSchema = NotificationSchema.extend({
27853
28118
  method: literal("notifications/tools/list_changed"),
27854
28119
  params: NotificationsParamsSchema.optional()
27855
28120
  });
27856
- var ListChangedOptionsBaseSchema = object2({
28121
+ var ListChangedOptionsBaseSchema = object3({
27857
28122
  /**
27858
28123
  * If true, the list will be refreshed automatically when a list changed notification is received.
27859
28124
  * The callback will be called with the updated list.
@@ -27902,13 +28167,13 @@ var LoggingMessageNotificationSchema = NotificationSchema.extend({
27902
28167
  method: literal("notifications/message"),
27903
28168
  params: LoggingMessageNotificationParamsSchema
27904
28169
  });
27905
- var ModelHintSchema = object2({
28170
+ var ModelHintSchema = object3({
27906
28171
  /**
27907
28172
  * A hint for a model name.
27908
28173
  */
27909
28174
  name: string2().optional()
27910
28175
  });
27911
- var ModelPreferencesSchema = object2({
28176
+ var ModelPreferencesSchema = object3({
27912
28177
  /**
27913
28178
  * Optional hints to use for model selection.
27914
28179
  */
@@ -27926,7 +28191,7 @@ var ModelPreferencesSchema = object2({
27926
28191
  */
27927
28192
  intelligencePriority: number2().min(0).max(1).optional()
27928
28193
  });
27929
- var ToolChoiceSchema = object2({
28194
+ var ToolChoiceSchema = object3({
27930
28195
  /**
27931
28196
  * Controls when tools are used:
27932
28197
  * - "auto": Model decides whether to use tools (default)
@@ -27935,11 +28200,11 @@ var ToolChoiceSchema = object2({
27935
28200
  */
27936
28201
  mode: _enum2(["auto", "required", "none"]).optional()
27937
28202
  });
27938
- var ToolResultContentSchema = object2({
28203
+ var ToolResultContentSchema = object3({
27939
28204
  type: literal("tool_result"),
27940
28205
  toolUseId: string2().describe("The unique identifier for the corresponding tool call."),
27941
28206
  content: array(ContentBlockSchema).default([]),
27942
- structuredContent: object2({}).loose().optional(),
28207
+ structuredContent: object3({}).loose().optional(),
27943
28208
  isError: boolean2().optional(),
27944
28209
  /**
27945
28210
  * See [MCP specification](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/47339c03c143bb4ec01a26e721a1b8fe66634ebe/docs/specification/draft/basic/index.mdx#general-fields)
@@ -27955,7 +28220,7 @@ var SamplingMessageContentBlockSchema = discriminatedUnion("type", [
27955
28220
  ToolUseContentSchema,
27956
28221
  ToolResultContentSchema
27957
28222
  ]);
27958
- var SamplingMessageSchema = object2({
28223
+ var SamplingMessageSchema = object3({
27959
28224
  role: RoleSchema,
27960
28225
  content: union([SamplingMessageContentBlockSchema, array(SamplingMessageContentBlockSchema)]),
27961
28226
  /**
@@ -28055,13 +28320,13 @@ var CreateMessageResultWithToolsSchema = ResultSchema.extend({
28055
28320
  */
28056
28321
  content: union([SamplingMessageContentBlockSchema, array(SamplingMessageContentBlockSchema)])
28057
28322
  });
28058
- var BooleanSchemaSchema = object2({
28323
+ var BooleanSchemaSchema = object3({
28059
28324
  type: literal("boolean"),
28060
28325
  title: string2().optional(),
28061
28326
  description: string2().optional(),
28062
28327
  default: boolean2().optional()
28063
28328
  });
28064
- var StringSchemaSchema = object2({
28329
+ var StringSchemaSchema = object3({
28065
28330
  type: literal("string"),
28066
28331
  title: string2().optional(),
28067
28332
  description: string2().optional(),
@@ -28070,7 +28335,7 @@ var StringSchemaSchema = object2({
28070
28335
  format: _enum2(["email", "uri", "date", "date-time"]).optional(),
28071
28336
  default: string2().optional()
28072
28337
  });
28073
- var NumberSchemaSchema = object2({
28338
+ var NumberSchemaSchema = object3({
28074
28339
  type: _enum2(["number", "integer"]),
28075
28340
  title: string2().optional(),
28076
28341
  description: string2().optional(),
@@ -28078,24 +28343,24 @@ var NumberSchemaSchema = object2({
28078
28343
  maximum: number2().optional(),
28079
28344
  default: number2().optional()
28080
28345
  });
28081
- var UntitledSingleSelectEnumSchemaSchema = object2({
28346
+ var UntitledSingleSelectEnumSchemaSchema = object3({
28082
28347
  type: literal("string"),
28083
28348
  title: string2().optional(),
28084
28349
  description: string2().optional(),
28085
28350
  enum: array(string2()),
28086
28351
  default: string2().optional()
28087
28352
  });
28088
- var TitledSingleSelectEnumSchemaSchema = object2({
28353
+ var TitledSingleSelectEnumSchemaSchema = object3({
28089
28354
  type: literal("string"),
28090
28355
  title: string2().optional(),
28091
28356
  description: string2().optional(),
28092
- oneOf: array(object2({
28357
+ oneOf: array(object3({
28093
28358
  const: string2(),
28094
28359
  title: string2()
28095
28360
  })),
28096
28361
  default: string2().optional()
28097
28362
  });
28098
- var LegacyTitledEnumSchemaSchema = object2({
28363
+ var LegacyTitledEnumSchemaSchema = object3({
28099
28364
  type: literal("string"),
28100
28365
  title: string2().optional(),
28101
28366
  description: string2().optional(),
@@ -28104,26 +28369,26 @@ var LegacyTitledEnumSchemaSchema = object2({
28104
28369
  default: string2().optional()
28105
28370
  });
28106
28371
  var SingleSelectEnumSchemaSchema = union([UntitledSingleSelectEnumSchemaSchema, TitledSingleSelectEnumSchemaSchema]);
28107
- var UntitledMultiSelectEnumSchemaSchema = object2({
28372
+ var UntitledMultiSelectEnumSchemaSchema = object3({
28108
28373
  type: literal("array"),
28109
28374
  title: string2().optional(),
28110
28375
  description: string2().optional(),
28111
28376
  minItems: number2().optional(),
28112
28377
  maxItems: number2().optional(),
28113
- items: object2({
28378
+ items: object3({
28114
28379
  type: literal("string"),
28115
28380
  enum: array(string2())
28116
28381
  }),
28117
28382
  default: array(string2()).optional()
28118
28383
  });
28119
- var TitledMultiSelectEnumSchemaSchema = object2({
28384
+ var TitledMultiSelectEnumSchemaSchema = object3({
28120
28385
  type: literal("array"),
28121
28386
  title: string2().optional(),
28122
28387
  description: string2().optional(),
28123
28388
  minItems: number2().optional(),
28124
28389
  maxItems: number2().optional(),
28125
- items: object2({
28126
- anyOf: array(object2({
28390
+ items: object3({
28391
+ anyOf: array(object3({
28127
28392
  const: string2(),
28128
28393
  title: string2()
28129
28394
  }))
@@ -28148,7 +28413,7 @@ var ElicitRequestFormParamsSchema = TaskAugmentedRequestParamsSchema.extend({
28148
28413
  * A restricted subset of JSON Schema.
28149
28414
  * Only top-level properties are allowed, without nesting.
28150
28415
  */
28151
- requestedSchema: object2({
28416
+ requestedSchema: object3({
28152
28417
  type: literal("object"),
28153
28418
  properties: record(string2(), PrimitiveSchemaDefinitionSchema),
28154
28419
  required: array(string2()).optional()
@@ -28204,14 +28469,14 @@ var ElicitResultSchema = ResultSchema.extend({
28204
28469
  */
28205
28470
  content: preprocess((val) => val === null ? void 0 : val, record(string2(), union([string2(), number2(), boolean2(), array(string2())])).optional())
28206
28471
  });
28207
- var ResourceTemplateReferenceSchema = object2({
28472
+ var ResourceTemplateReferenceSchema = object3({
28208
28473
  type: literal("ref/resource"),
28209
28474
  /**
28210
28475
  * The URI or URI template of the resource.
28211
28476
  */
28212
28477
  uri: string2()
28213
28478
  });
28214
- var PromptReferenceSchema = object2({
28479
+ var PromptReferenceSchema = object3({
28215
28480
  type: literal("ref/prompt"),
28216
28481
  /**
28217
28482
  * The name of the prompt or prompt template
@@ -28223,7 +28488,7 @@ var CompleteRequestParamsSchema = BaseRequestParamsSchema.extend({
28223
28488
  /**
28224
28489
  * The argument's information
28225
28490
  */
28226
- argument: object2({
28491
+ argument: object3({
28227
28492
  /**
28228
28493
  * The name of the argument
28229
28494
  */
@@ -28233,7 +28498,7 @@ var CompleteRequestParamsSchema = BaseRequestParamsSchema.extend({
28233
28498
  */
28234
28499
  value: string2()
28235
28500
  }),
28236
- context: object2({
28501
+ context: object3({
28237
28502
  /**
28238
28503
  * Previously-resolved variables in a URI template or prompt.
28239
28504
  */
@@ -28272,7 +28537,7 @@ var CompleteResultSchema = ResultSchema.extend({
28272
28537
  hasMore: optional(boolean2())
28273
28538
  })
28274
28539
  });
28275
- var RootSchema = object2({
28540
+ var RootSchema = object3({
28276
28541
  /**
28277
28542
  * The URI identifying the root. This *must* start with file:// for now.
28278
28543
  */
@@ -29136,11 +29401,11 @@ function parseMapDef(def, refs) {
29136
29401
 
29137
29402
  // ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.4.3/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js
29138
29403
  function parseNativeEnumDef(def) {
29139
- const object3 = def.values;
29404
+ const object4 = def.values;
29140
29405
  const actualKeys = Object.keys(def.values).filter((key) => {
29141
- return typeof object3[object3[key]] !== "number";
29406
+ return typeof object4[object4[key]] !== "number";
29142
29407
  });
29143
- const actualValues = actualKeys.map((key) => object3[key]);
29408
+ const actualValues = actualKeys.map((key) => object4[key]);
29144
29409
  const parsedTypes = Array.from(new Set(actualValues.map((values) => typeof values)));
29145
29410
  return {
29146
29411
  type: parsedTypes.length === 1 ? parsedTypes[0] === "string" ? "string" : "number" : ["string", "number"],
@@ -32354,8 +32619,8 @@ var StdioServerTransport = class {
32354
32619
  };
32355
32620
 
32356
32621
  // ../mcp/dist/context.js
32357
- import { homedir as homedir2 } from "node:os";
32358
- import { join as join9 } from "node:path";
32622
+ import { homedir as homedir3 } from "node:os";
32623
+ import { join as join11 } from "node:path";
32359
32624
 
32360
32625
  // ../mcp/dist/autoSyncTrigger.js
32361
32626
  function triggerAutoSyncAfterWrite(caveatHome, logger) {
@@ -32372,9 +32637,9 @@ function triggerAutoSyncAfterWrite(caveatHome, logger) {
32372
32637
 
32373
32638
  // ../mcp/dist/context.js
32374
32639
  function buildMcpContext(overrides = {}) {
32375
- const userHome = overrides.userHome ?? homedir2();
32640
+ const userHome = overrides.userHome ?? homedir3();
32376
32641
  const caveatHome = overrides.caveatHome ?? findCaveatHome(userHome);
32377
- const userConfigPath = join9(userHome, ".caveatrc.json");
32642
+ const userConfigPath = join11(userHome, ".caveatrc.json");
32378
32643
  const logger = overrides.logger ?? stderrLogger;
32379
32644
  const config2 = loadConfig(userConfigPath);
32380
32645
  const paths = resolvePaths(caveatHome, config2.knowledgeRepo, userHome);
@@ -32523,12 +32788,12 @@ function handleListRecent(ctx, args) {
32523
32788
  }
32524
32789
 
32525
32790
  // ../mcp/dist/tools/pull.js
32526
- import { existsSync as existsSync8 } from "node:fs";
32791
+ import { existsSync as existsSync10 } from "node:fs";
32527
32792
  var pullInputShape = {};
32528
32793
  async function handlePull(ctx, _args = {}) {
32529
32794
  const pulled = [];
32530
32795
  const indexed = [];
32531
- if (existsSync8(ctx.paths.communityDir)) {
32796
+ if (existsSync10(ctx.paths.communityDir)) {
32532
32797
  const results = await communityPull({
32533
32798
  communityDir: ctx.paths.communityDir,
32534
32799
  logger: ctx.logger
@@ -32684,28 +32949,28 @@ async function runMcpServer() {
32684
32949
  import { spawn as spawn2 } from "node:child_process";
32685
32950
  import {
32686
32951
  chmodSync,
32687
- existsSync as existsSync11,
32952
+ existsSync as existsSync13,
32688
32953
  lstatSync,
32689
32954
  mkdtempSync as mkdtempSync2,
32690
- mkdirSync as mkdirSync5,
32955
+ mkdirSync as mkdirSync6,
32691
32956
  readdirSync as readdirSync2,
32692
- readFileSync as readFileSync6,
32957
+ readFileSync as readFileSync8,
32693
32958
  realpathSync as realpathSync3,
32694
32959
  rmSync as rmSync2,
32695
32960
  writeFileSync as writeFileSync5
32696
32961
  } from "node:fs";
32697
32962
  import { tmpdir as tmpdir2 } from "node:os";
32698
- import { basename, dirname as dirname5, join as join12 } from "node:path";
32963
+ import { basename, dirname as dirname5, join as join14 } from "node:path";
32699
32964
  import { randomBytes } from "node:crypto";
32700
32965
 
32701
32966
  // src/autoReindexTrigger.ts
32702
32967
  import { spawn } from "node:child_process";
32703
- import { existsSync as existsSync9 } from "node:fs";
32704
- import { join as join10 } from "node:path";
32968
+ import { existsSync as existsSync11 } from "node:fs";
32969
+ import { join as join12 } from "node:path";
32705
32970
  function maybeTriggerAutoReindex(ctx) {
32706
32971
  if (process.env.CAVEAT_INDEX_AUTOSYNC === "off") return;
32707
- if (!existsSync9(ctx.paths.dbPath)) return;
32708
- if (existsSync9(join10(ctx.caveatHome, "index", ".reindex-lock"))) return;
32972
+ if (!existsSync11(ctx.paths.dbPath)) return;
32973
+ if (existsSync11(join12(ctx.caveatHome, "index", ".reindex-lock"))) return;
32709
32974
  const current = computeEntriesDigest(ctx.paths);
32710
32975
  const marker = readDigestMarker(ctx.caveatHome);
32711
32976
  if (marker?.digest === current.digest && marker.fileCount === current.fileCount) return;
@@ -32731,8 +32996,8 @@ function maybeTriggerAutoSync(ctx, debounceMs = AUTO_SYNC_DEBOUNCE_MS) {
32731
32996
  }
32732
32997
 
32733
32998
  // src/hookShared.ts
32734
- import { existsSync as existsSync10, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
32735
- import { join as join11 } from "node:path";
32999
+ import { existsSync as existsSync12, mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "node:fs";
33000
+ import { join as join13 } from "node:path";
32736
33001
  import { createHash } from "node:crypto";
32737
33002
  var MAX_CONTEXT_BLOCKS = 3;
32738
33003
  var STOP_REMINDER_PREFIX = "[caveat] \u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u3067\u5916\u90E8\u4ED5\u69D8\u306E\u7F60\u306B\u5F53\u305F\u3063\u305F\u53EF\u80FD\u6027\u3092\u793A\u3059\u30B7\u30B0\u30CA\u30EB:";
@@ -32787,7 +33052,7 @@ function searchCaveatsSafely(host, input) {
32787
33052
  let hits;
32788
33053
  try {
32789
33054
  const ctx = buildContextSafely(host);
32790
- if (!ctx || !existsSync10(ctx.paths.dbPath)) return [];
33055
+ if (!ctx || !existsSync12(ctx.paths.dbPath)) return [];
32791
33056
  caveatHome = ctx.caveatHome;
32792
33057
  db = openDb({ path: ctx.paths.dbPath });
32793
33058
  const searchOptions = {
@@ -32873,19 +33138,19 @@ function stopSignalKey(signals, related) {
32873
33138
  return createHash("sha256").update(body).digest("hex");
32874
33139
  }
32875
33140
  function stopStatePath(host, caveatHome, sessionId) {
32876
- return join11(caveatHome, host.stopStateDir, `${sanitizeStateId(sessionId)}.txt`);
33141
+ return join13(caveatHome, host.stopStateDir, `${sanitizeStateId(sessionId)}.txt`);
32877
33142
  }
32878
33143
  function wasStopReminderQueued(host, caveatHome, sessionId, key) {
32879
33144
  const path = stopStatePath(host, caveatHome, sessionId);
32880
33145
  try {
32881
- return readFileSync5(path, "utf-8") === key;
33146
+ return readFileSync7(path, "utf-8") === key;
32882
33147
  } catch {
32883
33148
  return false;
32884
33149
  }
32885
33150
  }
32886
33151
  function markStopReminderQueued(host, caveatHome, sessionId, key) {
32887
33152
  const path = stopStatePath(host, caveatHome, sessionId);
32888
- mkdirSync4(join11(caveatHome, host.stopStateDir), { recursive: true });
33153
+ mkdirSync5(join13(caveatHome, host.stopStateDir), { recursive: true });
32889
33154
  writeFileSync4(path, key, "utf-8");
32890
33155
  }
32891
33156
  function queueStopForSession(host, sessionId, signals, related, buildText) {
@@ -32997,9 +33262,9 @@ function spawnWorker(job) {
32997
33262
  try {
32998
33263
  root = workerRoot();
32999
33264
  sweepStaleWorkerDirs(Date.now(), root);
33000
- workDir = mkdtempSync2(join12(root, "job-"));
33265
+ workDir = mkdtempSync2(join14(root, "job-"));
33001
33266
  chmodSync(workDir, 448);
33002
- workFile = join12(workDir, `${randomBytes(4).toString("hex")}.json`);
33267
+ workFile = join14(workDir, `${randomBytes(4).toString("hex")}.json`);
33003
33268
  writeFileSync5(workFile, JSON.stringify({ ...job, schemaVersion: "caveat-worker-job/v2" }), { encoding: "utf-8", mode: 384, flag: "wx" });
33004
33269
  } catch (err) {
33005
33270
  process.stderr.write(`[caveat:hook] worker writefile error: ${errorMessage4(err)}
@@ -33031,7 +33296,7 @@ function spawnWorker(job) {
33031
33296
  async function runWorker(workFile) {
33032
33297
  let raw;
33033
33298
  try {
33034
- raw = readFileSync6(workFile, "utf-8");
33299
+ raw = readFileSync8(workFile, "utf-8");
33035
33300
  } catch {
33036
33301
  process.exit(0);
33037
33302
  }
@@ -33095,7 +33360,7 @@ function sweepStaleWorkerDirs(now = Date.now(), root = workerRoot()) {
33095
33360
  }
33096
33361
  for (const entry of entries) {
33097
33362
  if (!entry.startsWith("job-")) continue;
33098
- const path = join12(root, entry);
33363
+ const path = join14(root, entry);
33099
33364
  try {
33100
33365
  if (!isOwnedWorkerDir(path, root)) continue;
33101
33366
  const stat = lstatSync(path);
@@ -33107,29 +33372,29 @@ function sweepStaleWorkerDirs(now = Date.now(), root = workerRoot()) {
33107
33372
  }
33108
33373
  }
33109
33374
  function workerRoot(base = tmpdir2()) {
33110
- const root = join12(base, WORKER_ROOT);
33111
- mkdirSync5(root, { recursive: true, mode: 448 });
33375
+ const root = join14(base, WORKER_ROOT);
33376
+ mkdirSync6(root, { recursive: true, mode: 448 });
33112
33377
  const stat = lstatSync(root);
33113
33378
  const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
33114
33379
  if (!stat.isDirectory() || stat.isSymbolicLink() || !hasPrivateOwnership(stat, uid)) throw new Error("worker root is unsafe");
33115
- const marker = join12(root, WORKER_MARKER);
33380
+ const marker = join14(root, WORKER_MARKER);
33116
33381
  try {
33117
33382
  writeFileSync5(marker, "caveat-worker/v1\n", { mode: 384, flag: "wx" });
33118
33383
  } catch (error51) {
33119
33384
  if (!(error51 && typeof error51 === "object" && "code" in error51 && error51.code === "EEXIST")) throw error51;
33120
33385
  }
33121
33386
  const markerStat = lstatSync(marker);
33122
- if (!markerStat.isFile() || markerStat.isSymbolicLink() || !hasPrivateOwnership(markerStat, uid) || readFileSync6(marker, "utf-8") !== "caveat-worker/v1\n") throw new Error("worker root marker is invalid");
33387
+ if (!markerStat.isFile() || markerStat.isSymbolicLink() || !hasPrivateOwnership(markerStat, uid) || readFileSync8(marker, "utf-8") !== "caveat-worker/v1\n") throw new Error("worker root marker is invalid");
33123
33388
  return root;
33124
33389
  }
33125
33390
  function isStaleWorkerJobDir(path) {
33126
33391
  const entries = readdirSync2(path);
33127
33392
  if (entries.length !== 1 || !entries[0].endsWith(".json")) return false;
33128
- const file2 = join12(path, entries[0]);
33393
+ const file2 = join14(path, entries[0]);
33129
33394
  const stat = lstatSync(file2);
33130
33395
  const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
33131
33396
  if (!stat.isFile() || stat.isSymbolicLink() || !hasPrivateOwnership(stat, uid)) return false;
33132
- return isKnownStaleWorkerJob(JSON.parse(readFileSync6(file2, "utf-8")));
33397
+ return isKnownStaleWorkerJob(JSON.parse(readFileSync8(file2, "utf-8")));
33133
33398
  }
33134
33399
  function hasPrivateOwnership(stat, uid) {
33135
33400
  return isPrivateOwnerStat(stat, uid);
@@ -33151,7 +33416,7 @@ function isKnownStaleWorkerJob(value) {
33151
33416
  }
33152
33417
  function writeLastReindex(caveatHome, value) {
33153
33418
  try {
33154
- writeFileSync5(join12(caveatHome, "index", ".last-reindex.json"), JSON.stringify(value), "utf-8");
33419
+ writeFileSync5(join14(caveatHome, "index", ".last-reindex.json"), JSON.stringify(value), "utf-8");
33155
33420
  } catch (err) {
33156
33421
  process.stderr.write(`[caveat:hook] reindex status write error: ${errorMessage4(err)}
33157
33422
  `);
@@ -33163,7 +33428,7 @@ async function runReindexWorker() {
33163
33428
  return;
33164
33429
  }
33165
33430
  const ctx = buildContextSafely(CLAUDE_HOST);
33166
- if (!ctx || !existsSync11(ctx.paths.dbPath)) {
33431
+ if (!ctx || !existsSync13(ctx.paths.dbPath)) {
33167
33432
  process.stderr.write("[caveat:hook] auto reindex skipped: index database does not exist\n");
33168
33433
  return;
33169
33434
  }
@@ -33230,7 +33495,7 @@ function buildToolErrorReminder(job, hits) {
33230
33495
  const mode = hookCodexSidecarMode();
33231
33496
  if (mode === "off") return base;
33232
33497
  const projectRoot = process.cwd();
33233
- const hasSidecarConfig = existsSync11(join12(projectRoot, ".codex-sidecar.yml"));
33498
+ const hasSidecarConfig = existsSync13(join14(projectRoot, ".codex-sidecar.yml"));
33234
33499
  if (mode === "auto" && !hasSidecarConfig) return base;
33235
33500
  const advisory = runCodexSidecarAdvisory({
33236
33501
  searchText: job.failureText,
@@ -33266,7 +33531,7 @@ function buildStopReminder(signals, related) {
33266
33531
  const mode = hookCodexSidecarMode();
33267
33532
  if (mode === "off") return base;
33268
33533
  const projectRoot = process.cwd();
33269
- const hasSidecarConfig = existsSync11(join12(projectRoot, ".codex-sidecar.yml"));
33534
+ const hasSidecarConfig = existsSync13(join14(projectRoot, ".codex-sidecar.yml"));
33270
33535
  if (mode === "auto" && !hasSidecarConfig) return base;
33271
33536
  const advisory = runCodexSidecarAdvisory({
33272
33537
  searchText: struggleSearchText(signals),
@@ -33405,10 +33670,10 @@ async function runHook(name, arg) {
33405
33670
  }
33406
33671
 
33407
33672
  // src/commands/codexHookCmd.ts
33408
- import { spawn as spawn3, spawnSync as spawnSync5 } from "node:child_process";
33409
- import { existsSync as existsSync12, readFileSync as readFileSync7, unlinkSync, writeFileSync as writeFileSync6 } from "node:fs";
33410
- import { homedir as homedir3, tmpdir as tmpdir3 } from "node:os";
33411
- import { join as join13 } from "node:path";
33673
+ import { spawn as spawn3, spawnSync as spawnSync4 } from "node:child_process";
33674
+ import { existsSync as existsSync14, readFileSync as readFileSync9, unlinkSync, writeFileSync as writeFileSync6 } from "node:fs";
33675
+ import { homedir as homedir4, tmpdir as tmpdir3 } from "node:os";
33676
+ import { join as join15 } from "node:path";
33412
33677
  import { randomBytes as randomBytes2 } from "node:crypto";
33413
33678
  var CODEX_HOST = {
33414
33679
  agent: "codex",
@@ -33438,10 +33703,10 @@ function processExitCodeFromText(text) {
33438
33703
  return m ? Number(m[1]) : null;
33439
33704
  }
33440
33705
  function transcriptToolOutput(transcriptPath, toolUseId) {
33441
- if (!transcriptPath || !toolUseId || !existsSync12(transcriptPath)) return null;
33706
+ if (!transcriptPath || !toolUseId || !existsSync14(transcriptPath)) return null;
33442
33707
  let raw = "";
33443
33708
  try {
33444
- raw = readFileSync7(transcriptPath, "utf-8");
33709
+ raw = readFileSync9(transcriptPath, "utf-8");
33445
33710
  } catch {
33446
33711
  return null;
33447
33712
  }
@@ -33575,7 +33840,7 @@ async function processCodexWorkerJob(job, opts = { waitForTranscript: true }) {
33575
33840
  agent: "codex",
33576
33841
  surface: "tool_error",
33577
33842
  refs: hits
33578
- }), () => toolErrorReminderText(hits));
33843
+ }), () => toolErrorReminderText(hits, "native-cli"));
33579
33844
  } catch {
33580
33845
  process.stderr.write("[caveat:codex-hook] pending reminder build or publish failed\n");
33581
33846
  return;
@@ -33585,7 +33850,7 @@ async function processCodexWorkerJob(job, opts = { waitForTranscript: true }) {
33585
33850
  async function runCodexWorker(workFile) {
33586
33851
  let raw;
33587
33852
  try {
33588
- raw = readFileSync7(workFile, "utf-8");
33853
+ raw = readFileSync9(workFile, "utf-8");
33589
33854
  } catch {
33590
33855
  process.exit(0);
33591
33856
  }
@@ -33602,8 +33867,8 @@ async function runCodexWorker(workFile) {
33602
33867
  await processCodexWorkerJob(job);
33603
33868
  process.exit(0);
33604
33869
  }
33605
- function runDiagnostics(codexHome = process.env.CODEX_HOME ?? join13(homedir3(), ".codex")) {
33606
- const features = spawnSync5("codex", ["features", "list"], {
33870
+ function runDiagnostics(codexHome = process.env.CODEX_HOME ?? join15(homedir4(), ".codex")) {
33871
+ const features = spawnSync4("codex", ["features", "list"], {
33607
33872
  encoding: "utf-8",
33608
33873
  maxBuffer: 1024 * 1024,
33609
33874
  env: codexFeatureListEnv(codexHome)
@@ -33654,7 +33919,7 @@ async function runCodexHook(name, arg) {
33654
33919
  const prompt = typeof payload.prompt === "string" ? payload.prompt : "";
33655
33920
  const hits = searchCaveatsSafely(CODEX_HOST, { topicText: prompt, failureText: prompt, surface: "user_prompt" });
33656
33921
  if (hits.length > 0) {
33657
- contexts.push(userPromptSubmitReminderText(hits));
33922
+ contexts.push(userPromptSubmitReminderText(hits, "native-cli"));
33658
33923
  }
33659
33924
  const compacted = compactContexts(CODEX_HOST, contexts);
33660
33925
  if (compacted.length > 0) {
@@ -33699,7 +33964,7 @@ async function runCodexHook(name, arg) {
33699
33964
  failureText,
33700
33965
  surface: "stop"
33701
33966
  })));
33702
- if (sessionId) queueStopForSession(CODEX_HOST, sessionId, signals, related, () => stopReminderText(signals, related));
33967
+ if (sessionId) queueStopForSession(CODEX_HOST, sessionId, signals, related, () => stopReminderText(signals, related, "native-cli"));
33703
33968
  process.exit(0);
33704
33969
  }
33705
33970
  process.stderr.write(`[caveat:codex-hook] unknown hook name: ${name}
@@ -33707,10 +33972,151 @@ async function runCodexHook(name, arg) {
33707
33972
  process.exit(0);
33708
33973
  }
33709
33974
 
33975
+ // src/commands/cursorHookCmd.ts
33976
+ import { homedir as homedir5 } from "node:os";
33977
+ import { join as join16 } from "node:path";
33978
+ var CURSOR_HOST = {
33979
+ agent: "cursor",
33980
+ stderrTag: "caveat:cursor-hook",
33981
+ errorCode: "CAVEAT.CURSOR_HOOK_FAILED",
33982
+ stopStateDir: "cursor-stop-state",
33983
+ stopDedupeKey: "cursor-stop-reminder"
33984
+ };
33985
+ function cursorContextOutput(text) {
33986
+ return JSON.stringify({ additional_context: text });
33987
+ }
33988
+ function cursorSessionId(payload) {
33989
+ for (const key of ["conversation_id", "session_id", "sessionId"]) {
33990
+ const value = payload[key];
33991
+ if (typeof value === "string" && value.length > 0) return value;
33992
+ }
33993
+ return "_unknown";
33994
+ }
33995
+ function cursorPrompt(payload) {
33996
+ return typeof payload.prompt === "string" ? payload.prompt : "";
33997
+ }
33998
+ function isCursorToolError(payload) {
33999
+ if (payload.hook_event_name === "postToolUseFailure") return true;
34000
+ if (payload.is_error === true) return true;
34001
+ if (typeof payload.error === "string" && payload.error.length > 0) return true;
34002
+ const resp = payload.tool_response ?? payload.toolResponse;
34003
+ if (resp !== null && typeof resp === "object" && !Array.isArray(resp)) {
34004
+ if (resp.is_error === true) return true;
34005
+ }
34006
+ return false;
34007
+ }
34008
+ function loadSignalsSafely3(path) {
34009
+ try {
34010
+ return readSessionSignals(path);
34011
+ } catch (err) {
34012
+ process.stderr.write(`[caveat:cursor-hook] transcript read error: ${errorMessage4(err)}
34013
+ `);
34014
+ return null;
34015
+ }
34016
+ }
34017
+ function runDiagnostics2(cursorDir = join16(homedir5(), ".cursor")) {
34018
+ const installation = detectCursorHookInstallation(cursorDir);
34019
+ process.stdout.write(`${JSON.stringify({
34020
+ installation: installation.installation,
34021
+ cursorDir,
34022
+ hooksPath: installation.hooksPath,
34023
+ installedHooks: installation.hooks
34024
+ }, null, 2)}
34025
+ `);
34026
+ }
34027
+ async function runCursorHook(name, arg) {
34028
+ if (name === "diagnostics") {
34029
+ runDiagnostics2(arg);
34030
+ return;
34031
+ }
34032
+ let raw = "";
34033
+ try {
34034
+ raw = await readStdin();
34035
+ } catch (err) {
34036
+ process.stderr.write(`[caveat:cursor-hook] stdin read error: ${errorMessage4(err)}
34037
+ `);
34038
+ process.exit(0);
34039
+ }
34040
+ const payload = parsePayload(CURSOR_HOST, raw);
34041
+ const sessionId = cursorSessionId(payload);
34042
+ const contexts = name === "stop" ? [] : drainForSession(CURSOR_HOST, sessionId);
34043
+ if (name === "user-prompt-submit") {
34044
+ const prompt = cursorPrompt(payload);
34045
+ const hits = searchCaveatsSafely(CURSOR_HOST, {
34046
+ topicText: prompt,
34047
+ failureText: prompt,
34048
+ surface: "user_prompt"
34049
+ });
34050
+ if (hits.length > 0) contexts.push(userPromptSubmitReminderText(hits, "native-cli"));
34051
+ const compacted = compactContexts(CURSOR_HOST, contexts);
34052
+ if (compacted.length > 0) {
34053
+ process.stdout.write(`${cursorContextOutput(compacted.join("\n\n"))}
34054
+ `);
34055
+ }
34056
+ process.exit(0);
34057
+ }
34058
+ if (name === "post-tool-use") {
34059
+ if (isCursorToolError(payload)) {
34060
+ const errText = extractToolResponseText(
34061
+ payload.tool_response ?? payload.toolResponse ?? payload.error ?? payload
34062
+ );
34063
+ const hits = searchCaveatsSafely(CURSOR_HOST, {
34064
+ topicText: errText,
34065
+ failureText: errText,
34066
+ surface: "tool_error"
34067
+ });
34068
+ if (hits.length > 0) contexts.push(toolErrorReminderText(hits, "native-cli"));
34069
+ }
34070
+ const compacted = compactContexts(CURSOR_HOST, contexts);
34071
+ if (compacted.length > 0) {
34072
+ process.stdout.write(`${cursorContextOutput(compacted.join("\n\n"))}
34073
+ `);
34074
+ }
34075
+ process.exit(0);
34076
+ }
34077
+ if (name === "stop") {
34078
+ const ctx = buildContextSafely(CURSOR_HOST);
34079
+ if (ctx) {
34080
+ try {
34081
+ maybeSweepPendingDirs(ctx.caveatHome);
34082
+ } catch (err) {
34083
+ process.stderr.write(`[caveat:cursor-hook] pending sweep error: ${errorMessage4(err)}
34084
+ `);
34085
+ }
34086
+ try {
34087
+ maybeTriggerAutoReindex(ctx);
34088
+ } catch (err) {
34089
+ process.stderr.write(`[caveat:cursor-hook] auto reindex trigger error: ${errorMessage4(err)}
34090
+ `);
34091
+ }
34092
+ try {
34093
+ maybeTriggerAutoSync(ctx);
34094
+ } catch (err) {
34095
+ process.stderr.write(`[caveat:cursor-hook] auto sync trigger error: ${errorMessage4(err)}
34096
+ `);
34097
+ }
34098
+ }
34099
+ if (payload.stop_hook_active === true) process.exit(0);
34100
+ const transcriptPath = typeof payload.transcript_path === "string" ? payload.transcript_path : "";
34101
+ const signals = transcriptPath ? loadSignalsSafely3(transcriptPath) : null;
34102
+ if (!signals || !hasAnyStruggleSignal(signals)) process.exit(0);
34103
+ const related = searchCaveatsSafely(CURSOR_HOST, signals.errorSnippets.map((failureText) => ({
34104
+ topicText: "",
34105
+ failureText,
34106
+ surface: "stop"
34107
+ })));
34108
+ queueStopForSession(CURSOR_HOST, sessionId, signals, related, () => stopReminderText(signals, related, "native-cli"));
34109
+ process.exit(0);
34110
+ }
34111
+ process.stderr.write(`[caveat:cursor-hook] unknown hook name: ${name}
34112
+ `);
34113
+ process.exit(0);
34114
+ }
34115
+
33710
34116
  // src/commands/pull.ts
33711
- import { existsSync as existsSync13 } from "node:fs";
34117
+ import { existsSync as existsSync15 } from "node:fs";
33712
34118
  async function runPull(ctx) {
33713
- const hasCommunityDir = existsSync13(ctx.paths.communityDir);
34119
+ const hasCommunityDir = existsSync15(ctx.paths.communityDir);
33714
34120
  if (!hasCommunityDir) {
33715
34121
  ctx.logger.info(
33716
34122
  "no community repos yet \u2014 add one with `caveat community add <github-url>`."
@@ -33809,10 +34215,10 @@ async function runSync(ctx, opts, dependencies = {}) {
33809
34215
  }
33810
34216
 
33811
34217
  // src/commands/codexSidecar.ts
33812
- import { spawnSync as spawnSync6 } from "node:child_process";
33813
- import { closeSync, constants as constants3, fstatSync, lstatSync as lstatSync2, mkdirSync as mkdirSync6, mkdtempSync as mkdtempSync3, openSync, readSync as readSync2, realpathSync as realpathSync4, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "node:fs";
34218
+ import { spawnSync as spawnSync5 } from "node:child_process";
34219
+ import { closeSync, constants as constants4, fstatSync, lstatSync as lstatSync2, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync3, openSync, readSync as readSync2, realpathSync as realpathSync4, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "node:fs";
33814
34220
  import { tmpdir as tmpdir4 } from "node:os";
33815
- import { basename as basename2, dirname as dirname6, join as join14 } from "node:path";
34221
+ import { basename as basename2, dirname as dirname6, join as join17 } from "node:path";
33816
34222
  import { cwd, exit } from "node:process";
33817
34223
  function runCodexSidecarDiagnostics(logger, opts) {
33818
34224
  const plan = buildCodexSidecarDiagnosticsCommand({
@@ -33844,8 +34250,8 @@ function runCodexSidecarWithCaveats(ctx, workflow, prompt, opts) {
33844
34250
  process.stdout.write(JSON.stringify({ status: "skipped", decision }, null, 2) + "\n");
33845
34251
  exit(0);
33846
34252
  }
33847
- const contextDir = mkdtempSync3(join14(tmpdir4(), "caveat-sidecar-context-"));
33848
- const contextFile = join14(contextDir, "context.json");
34253
+ const contextDir = mkdtempSync3(join17(tmpdir4(), "caveat-sidecar-context-"));
34254
+ const contextFile = join17(contextDir, "context.json");
33849
34255
  let status2 = 1;
33850
34256
  try {
33851
34257
  const blocks = collectCaveatContextBlocks(ctx, {
@@ -33878,7 +34284,7 @@ function readHookSignalAdditionalContextFile(path, testProbe) {
33878
34284
  const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
33879
34285
  assertPrivateRegular(before, uid, platform);
33880
34286
  testProbe?.afterLstat?.();
33881
- const fd = openSync(path, constants3.O_RDONLY | constants3.O_NONBLOCK | (constants3.O_NOFOLLOW ?? 0));
34287
+ const fd = openSync(path, constants4.O_RDONLY | constants4.O_NONBLOCK | (constants4.O_NOFOLLOW ?? 0));
33882
34288
  let raw;
33883
34289
  try {
33884
34290
  const opened = fstatSync(fd);
@@ -33994,7 +34400,7 @@ function defaultPreset(workflow) {
33994
34400
  }
33995
34401
  function executePlan(logger, command, args, options = {}) {
33996
34402
  logger.info(`[codex-sidecar] ${command} ${args.map(shellDisplayQuote).join(" ")}`);
33997
- const result = spawnSync6(command, args, { encoding: "utf-8", stdio: "pipe" });
34403
+ const result = spawnSync5(command, args, { encoding: "utf-8", stdio: "pipe" });
33998
34404
  if (result.stdout) process.stdout.write(result.stdout);
33999
34405
  if (result.stderr) process.stderr.write(result.stderr);
34000
34406
  if (options.saveResult && result.stdout) {
@@ -34008,7 +34414,7 @@ function executePlan(logger, command, args, options = {}) {
34008
34414
  }
34009
34415
  function saveStructuredResult(path, stdout) {
34010
34416
  const parsed = JSON.parse(stdout);
34011
- mkdirSync6(dirname6(path), { recursive: true });
34417
+ mkdirSync7(dirname6(path), { recursive: true });
34012
34418
  writeFileSync7(path, JSON.stringify(parsed, null, 2) + "\n", "utf-8");
34013
34419
  }
34014
34420
  function shellDisplayQuote(value) {
@@ -34097,8 +34503,8 @@ function runCommunityRemove(ctx, handle, opts) {
34097
34503
 
34098
34504
  // src/commands/factoryDiagnostics.ts
34099
34505
  import { execFileSync } from "node:child_process";
34100
- import { existsSync as existsSync14, readFileSync as readFileSync8 } from "node:fs";
34101
- import { join as join15 } from "node:path";
34506
+ import { existsSync as existsSync16, readFileSync as readFileSync10 } from "node:fs";
34507
+ import { join as join18 } from "node:path";
34102
34508
  import { DatabaseSync } from "node:sqlite";
34103
34509
  import { parse as parseToml2 } from "smol-toml";
34104
34510
  var status = (ok, reason) => ({ status: ok ? "ready" : "not_ready", reason_code: ok ? "ready" : reason });
@@ -34109,20 +34515,19 @@ function hook(present) {
34109
34515
  function isRecord2(value) {
34110
34516
  return typeof value === "object" && value !== null && !Array.isArray(value);
34111
34517
  }
34112
- function claudeRegistration(home, nodePath, cliScriptPath) {
34113
- const path = join15(home, ".claude.json");
34114
- if (!existsSync14(path)) return status(false, "not_registered");
34518
+ function claudeRegistration(path, nodePath, cliScriptPath) {
34519
+ if (!existsSync16(path)) return status(false, "not_registered");
34115
34520
  try {
34116
- const value = JSON.parse(readFileSync8(path, "utf8"));
34521
+ const value = JSON.parse(readFileSync10(path, "utf8"));
34117
34522
  if (!isRecord2(value) || !isRecord2(value.mcpServers)) return status(false, "not_registered");
34118
34523
  return status(isCaveatClaudeMcpRegistration(value.mcpServers.caveat, nodePath, cliScriptPath), "not_registered");
34119
34524
  } catch {
34120
34525
  return unverified("config_unreadable");
34121
34526
  }
34122
34527
  }
34123
- function claudeHooks(home, nodePath, cliScriptPath) {
34528
+ function claudeHooks(claudeDir, nodePath, cliScriptPath) {
34124
34529
  try {
34125
- const settings = JSON.parse(readFileSync8(join15(home, ".claude", "settings.json"), "utf8"));
34530
+ const settings = JSON.parse(readFileSync10(join18(claudeDir, "settings.json"), "utf8"));
34126
34531
  const present = (event, subcommand) => settings.hooks?.[event]?.some((entry) => entry.hooks?.some((item) => typeof item.command === "string" && isCanonicalCaveatClaudeHookCommand(item.command, subcommand, nodePath, cliScriptPath))) ?? false;
34127
34532
  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")) };
34128
34533
  } catch {
@@ -34139,12 +34544,12 @@ var EXPECTED_SEARCH_SQL = /* @__PURE__ */ new Map([
34139
34544
  function strictSearchSchema(db) {
34140
34545
  const normalize = (sql) => (sql ?? "").toLowerCase().replace(/\s+/g, " ");
34141
34546
  const objects = db.prepare("SELECT name, sql FROM sqlite_master WHERE name = 'entries_fts' OR (type = 'trigger' AND tbl_name = 'entries')").all();
34142
- if (objects.length !== EXPECTED_SEARCH_SQL.size || objects.some((object3) => normalize(object3.sql) !== EXPECTED_SEARCH_SQL.get(object3.name))) return false;
34547
+ if (objects.length !== EXPECTED_SEARCH_SQL.size || objects.some((object4) => normalize(object4.sql) !== EXPECTED_SEARCH_SQL.get(object4.name))) return false;
34143
34548
  const columns = db.prepare("PRAGMA table_xinfo(entries_fts)").all();
34144
34549
  return columns.map((column) => `${column.name}:${column.hidden}`).join(",") === "id:0,title:0,body:0,tags:0,entries_fts:1,rank:1";
34145
34550
  }
34146
34551
  function database(path) {
34147
- if (!existsSync14(path)) return { status: "not_ready", reason_code: "missing", schema_version: null, supported_schema_version: 3, migration_status: "unverified" };
34552
+ if (!existsSync16(path)) return { status: "not_ready", reason_code: "missing", schema_version: null, supported_schema_version: 3, migration_status: "unverified" };
34148
34553
  try {
34149
34554
  const db = new DatabaseSync(path, { readOnly: true });
34150
34555
  try {
@@ -34169,10 +34574,10 @@ function database(path) {
34169
34574
  }
34170
34575
  }
34171
34576
  function codexFeature(codexHome) {
34172
- const path = join15(codexHome, "config.toml");
34173
- if (!existsSync14(path)) return status(false, "feature_disabled");
34577
+ const path = join18(codexHome, "config.toml");
34578
+ if (!existsSync16(path)) return status(false, "feature_disabled");
34174
34579
  try {
34175
- const config2 = parseToml2(readFileSync8(path, "utf8"));
34580
+ const config2 = parseToml2(readFileSync10(path, "utf8"));
34176
34581
  if (!isRecord2(config2.features)) return status(false, "feature_disabled");
34177
34582
  const features = config2.features;
34178
34583
  return status(features.hooks === true && features.codex_hooks === void 0, "feature_disabled");
@@ -34181,7 +34586,7 @@ function codexFeature(codexHome) {
34181
34586
  }
34182
34587
  }
34183
34588
  function codexHooks(codexHome, nodePath, cliScriptPath) {
34184
- const value = JSON.parse(readFileSync8(join15(codexHome, "hooks.json"), "utf8"));
34589
+ const value = JSON.parse(readFileSync10(join18(codexHome, "hooks.json"), "utf8"));
34185
34590
  if (!isRecord2(value) || !isRecord2(value.hooks)) throw Error("config_unreadable");
34186
34591
  const hooks = value.hooks;
34187
34592
  const present = (event, subcommand) => Array.isArray(hooks[event]) && hooks[event].some((entry) => isRecord2(entry) && Array.isArray(entry.hooks) && entry.hooks.some((item) => isCanonicalCaveatCodexHookEntry(item, subcommand, nodePath, cliScriptPath)));
@@ -34216,7 +34621,8 @@ function sync(own) {
34216
34621
  return unverified("upstream_unavailable");
34217
34622
  }
34218
34623
  }
34219
- function factoryDiagnostics(ctx, codexHome = process.env.CODEX_HOME ?? join15(ctx.userHome, ".codex")) {
34624
+ function factoryDiagnostics(ctx, codexHome = resolveAgentConfigPaths(ctx.userHome).codexHome, requiredConnectors = []) {
34625
+ const { claudeDir, claudeMcp, cursorDir } = resolveAgentConfigPaths(ctx.userHome);
34220
34626
  const nodePath = process.execPath;
34221
34627
  const cliScriptPath = process.argv[1] ?? "";
34222
34628
  const db = database(ctx.paths.dbPath);
@@ -34227,12 +34633,13 @@ function factoryDiagnostics(ctx, codexHome = process.env.CODEX_HOME ?? join15(ct
34227
34633
  } catch {
34228
34634
  }
34229
34635
  const codexHook2 = (present) => present === void 0 ? unverified("config_unreadable") : !present ? hook(false) : feature.status === "ready" ? hook(true) : { ...feature };
34230
- 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) } } } };
34636
+ 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(claudeMcp, nodePath, cliScriptPath), hooks: claudeHooks(claudeDir, nodePath, cliScriptPath) }, codex: { status: "unverified", hooks: { user_prompt_submit: codexHook2(installedCodexHooks?.userPromptSubmit), post_tool_use: codexHook2(installedCodexHooks?.postToolUse), stop: codexHook2(installedCodexHooks?.stop) } }, cursor: diagnoseCursorHookConnector(cursorDir, nodePath, cliScriptPath) } };
34231
34637
  const aggregate = (all) => all.includes("not_ready") ? "not_ready" : all.includes("unverified") ? "unverified" : "ready";
34232
34638
  const connectorStatus = (connector) => aggregate([...Object.values(connector.hooks), ...connector.mcp ? [connector.mcp] : []].map((v) => v.status));
34233
34639
  output.connectors.claude.status = connectorStatus(output.connectors.claude);
34234
34640
  output.connectors.codex.status = connectorStatus(output.connectors.codex);
34235
34641
  const statuses = [output.database.status, output.sync.status, output.connectors.claude.status, output.connectors.codex.status];
34642
+ if (requiredConnectors.includes("cursor")) statuses.push(output.connectors.cursor.compatibility_status);
34236
34643
  output.overall.status = aggregate(statuses);
34237
34644
  return output;
34238
34645
  }
@@ -34257,12 +34664,16 @@ function parseCursor(value) {
34257
34664
 
34258
34665
  // src/index.ts
34259
34666
  var program = new Command();
34667
+ var agentPaths = resolveAgentConfigPaths();
34260
34668
  function collectRepeatable(value, previous) {
34261
34669
  return [...previous, value];
34262
34670
  }
34263
34671
  program.name("caveat").description("External spec gotcha knowledge base CLI").version(CAVEAT_VERSION);
34264
- program.command("factory-diagnostics").description("Emit read-only factory diagnostics").requiredOption("--json", "emit the versioned JSON contract").action((opts) => {
34265
- const output = factoryDiagnostics(buildContext(stdoutLogger));
34672
+ program.command("factory-diagnostics").description("Emit read-only factory diagnostics").requiredOption("--json", "emit the versioned JSON contract").option("--require-connector <name>", "include a connector in overall readiness (repeatable)", collectRepeatable, []).action((opts) => {
34673
+ const unsupported = opts.requireConnector.filter((name) => name !== "cursor");
34674
+ if (unsupported.length > 0) throw new Error(`unsupported factory connector: ${unsupported.join(", ")}`);
34675
+ const requiredConnectors = [...new Set(opts.requireConnector)];
34676
+ const output = factoryDiagnostics(buildContext(stdoutLogger), void 0, requiredConnectors);
34266
34677
  process.stdout.write(`${JSON.stringify(output)}
34267
34678
  `);
34268
34679
  if (output.overall.status !== "ready") process.exitCode = 1;
@@ -34290,8 +34701,8 @@ for (const action of ["resolve", "reopen"]) runtimeErrors.command(`${action} <fi
34290
34701
  `);
34291
34702
  });
34292
34703
  program.command("init").description(
34293
- "Initialize ~/.caveatrc.json, ~/.caveat/, and register Claude Code integration. Add knowledge sources later with `caveat community add <github-url>`."
34294
- ).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(
34704
+ "Initialize Caveat state and available host integrations, with optional private sync. Add knowledge sources later with `caveat community add <github-url>`."
34705
+ ).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("--skip-cursor-hook", "skip Cursor hook installation", false).option("--dry-run", "show planned changes without writing", false).option(
34295
34706
  "--pending-stale-days <days>",
34296
34707
  "sweep `<caveatHome>/pending/<sessionId>/` whose newest entry is older than this (default 7)",
34297
34708
  (raw) => {
@@ -34311,7 +34722,8 @@ program.command("init").description(
34311
34722
  sync: opts.sync,
34312
34723
  publishTarget: opts.publishTarget,
34313
34724
  yes: opts.yes,
34314
- skipCodexHook: opts.skipCodexHook
34725
+ skipCodexHook: opts.skipCodexHook,
34726
+ skipCursorHook: opts.skipCursorHook
34315
34727
  });
34316
34728
  }
34317
34729
  );
@@ -34379,7 +34791,7 @@ program.command("hook <name> [arg]").description(
34379
34791
  await runHook(name, arg);
34380
34792
  });
34381
34793
  var codexHook = program.command("codex-hook").description("Install or run Codex hooks for Caveat");
34382
- codexHook.command("install").description("Install Caveat hooks into ~/.codex/hooks.json and enable hooks").option("--dry-run", "show planned changes without writing", false).option("--codex-home <path>", "Codex home directory", process.env.CODEX_HOME ?? `${process.env.HOME}/.codex`).action((opts) => {
34794
+ codexHook.command("install").description("Install Caveat hooks into ~/.codex/hooks.json and enable hooks").option("--dry-run", "show planned changes without writing", false).option("--codex-home <path>", "Codex home directory", agentPaths.codexHome).action((opts) => {
34383
34795
  const cliScriptPath = process.argv[1];
34384
34796
  if (!cliScriptPath) {
34385
34797
  process.stderr.write("[caveat:error] cannot determine CLI script path\n");
@@ -34406,7 +34818,7 @@ codexHook.command("install").description("Install Caveat hooks into ~/.codex/hoo
34406
34818
  stdoutLogger.info(`config.toml backed up: ${result.configBackupPath}`);
34407
34819
  }
34408
34820
  });
34409
- codexHook.command("uninstall").description("Remove Caveat-owned Codex hooks from ~/.codex/hooks.json").option("--dry-run", "show planned changes without writing", false).option("--codex-home <path>", "Codex home directory", process.env.CODEX_HOME ?? `${process.env.HOME}/.codex`).action((opts) => {
34821
+ codexHook.command("uninstall").description("Remove Caveat-owned Codex hooks from ~/.codex/hooks.json").option("--dry-run", "show planned changes without writing", false).option("--codex-home <path>", "Codex home directory", agentPaths.codexHome).action((opts) => {
34410
34822
  const cliScriptPath = process.argv[1];
34411
34823
  if (!cliScriptPath) {
34412
34824
  process.stderr.write("[caveat:error] cannot determine CLI script path\n");
@@ -34424,7 +34836,7 @@ codexHook.command("uninstall").description("Remove Caveat-owned Codex hooks from
34424
34836
  stdoutLogger.info(`Stop hook: ${result.hooks.stop === "added" ? "removed" : "not present"}`);
34425
34837
  if (result.backupPath) stdoutLogger.info(`hooks.json backed up: ${result.backupPath}`);
34426
34838
  });
34427
- codexHook.command("diagnostics").description("Check local Codex hook availability").option("--codex-home <path>", "Codex home directory", process.env.CODEX_HOME ?? `${process.env.HOME}/.codex`).action(async (opts) => {
34839
+ codexHook.command("diagnostics").description("Check local Codex hook availability").option("--codex-home <path>", "Codex home directory", agentPaths.codexHome).action(async (opts) => {
34428
34840
  await runCodexHook("diagnostics", opts.codexHome);
34429
34841
  });
34430
34842
  codexHook.command("user-prompt-submit").description("Run the Codex UserPromptSubmit hook").action(async () => {
@@ -34439,6 +34851,57 @@ codexHook.command("stop").description("Run the Codex Stop hook").action(async ()
34439
34851
  codexHook.command("worker <workFile>").description("Run the detached Codex hook worker").action(async (workFile) => {
34440
34852
  await runCodexHook("worker", workFile);
34441
34853
  });
34854
+ var cursorHook = program.command("cursor-hook").description("Install or run Cursor hooks for Caveat");
34855
+ cursorHook.command("install").description("Install Caveat hooks into ~/.cursor/hooks.json (factory hooks are kept)").option("--dry-run", "show planned changes without writing", false).option("--cursor-dir <path>", "Cursor home directory", agentPaths.cursorDir).action((opts) => {
34856
+ const cliScriptPath = process.argv[1];
34857
+ if (!cliScriptPath) {
34858
+ process.stderr.write("[caveat:error] cannot determine CLI script path\n");
34859
+ process.exit(1);
34860
+ }
34861
+ const result = installCursorHooks({
34862
+ cursorDir: opts.cursorDir,
34863
+ cliScriptPath,
34864
+ nodePath: resolveHookNodePath(),
34865
+ dryRun: opts.dryRun,
34866
+ logger: stdoutLogger
34867
+ });
34868
+ stdoutLogger.info(`beforeSubmitPrompt hook: ${result.hooks.beforeSubmitPrompt}`);
34869
+ stdoutLogger.info(`postToolUse hook: ${result.hooks.postToolUse}`);
34870
+ stdoutLogger.info(`postToolUseFailure hook: ${result.hooks.postToolUseFailure}`);
34871
+ stdoutLogger.info(`stop hook: ${result.hooks.stop}`);
34872
+ if (result.backupPath) stdoutLogger.info(`hooks.json backed up: ${result.backupPath}`);
34873
+ });
34874
+ cursorHook.command("uninstall").description("Remove Caveat-owned Cursor hooks from ~/.cursor/hooks.json").option("--dry-run", "show planned changes without writing", false).option("--cursor-dir <path>", "Cursor home directory", agentPaths.cursorDir).action((opts) => {
34875
+ const cliScriptPath = process.argv[1];
34876
+ if (!cliScriptPath) {
34877
+ process.stderr.write("[caveat:error] cannot determine CLI script path\n");
34878
+ process.exit(1);
34879
+ }
34880
+ const result = uninstallCursorHooks({
34881
+ cursorDir: opts.cursorDir,
34882
+ cliScriptPath,
34883
+ nodePath: resolveHookNodePath(),
34884
+ dryRun: opts.dryRun,
34885
+ logger: stdoutLogger
34886
+ });
34887
+ stdoutLogger.info(`beforeSubmitPrompt hook: ${result.hooks.beforeSubmitPrompt === "added" ? "removed" : "not present"}`);
34888
+ stdoutLogger.info(`postToolUse hook: ${result.hooks.postToolUse === "added" ? "removed" : "not present"}`);
34889
+ stdoutLogger.info(`postToolUseFailure hook: ${result.hooks.postToolUseFailure === "added" ? "removed" : "not present"}`);
34890
+ stdoutLogger.info(`stop hook: ${result.hooks.stop === "added" ? "removed" : "not present"}`);
34891
+ if (result.backupPath) stdoutLogger.info(`hooks.json backed up: ${result.backupPath}`);
34892
+ });
34893
+ cursorHook.command("diagnostics").description("Check local Cursor hook installation").option("--cursor-dir <path>", "Cursor home directory", agentPaths.cursorDir).action(async (opts) => {
34894
+ await runCursorHook("diagnostics", opts.cursorDir);
34895
+ });
34896
+ cursorHook.command("user-prompt-submit").description("Run the Cursor beforeSubmitPrompt hook").action(async () => {
34897
+ await runCursorHook("user-prompt-submit");
34898
+ });
34899
+ cursorHook.command("post-tool-use").description("Run the Cursor postToolUse / postToolUseFailure hook").action(async () => {
34900
+ await runCursorHook("post-tool-use");
34901
+ });
34902
+ cursorHook.command("stop").description("Run the Cursor stop hook").action(async () => {
34903
+ await runCursorHook("stop");
34904
+ });
34442
34905
  var codexSidecar = program.command("codex-sidecar").description("Check Codex sidecar availability for the current repository");
34443
34906
  codexSidecar.command("diagnostics").description("Run codex-sidecar diagnostics for this repository").option("--project <path>", "repository root to check").option("--preset <preset>", "codex-sidecar preset", "review").option("--command <command>", "codex-sidecar executable", "codex-sidecar").option("--node-cli <path>", "development path to codex-sidecar CLI JS").option("--save-result <path>", "write structured SidecarResult JSON to this path").action((opts) => {
34444
34907
  runCodexSidecarDiagnostics(stdoutLogger, opts);