caveat-cli 0.16.1 → 0.16.3
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/{chunk-HCLEIAGO.js → chunk-PD5E6TFL.js} +686 -148
- package/dist/chunk-PD5E6TFL.js.map +1 -0
- package/dist/index.js +622 -218
- package/dist/index.js.map +1 -1
- package/dist/{server-EASKBCNK.js → server-ZMIRSFMH.js} +2 -2
- package/package.json +3 -3
- package/dist/chunk-HCLEIAGO.js.map +0 -1
- /package/dist/{server-EASKBCNK.js.map → server-ZMIRSFMH.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -10,27 +10,30 @@ import {
|
|
|
10
10
|
__commonJS,
|
|
11
11
|
__export,
|
|
12
12
|
__toESM,
|
|
13
|
+
acknowledgeRuntimeErrors,
|
|
13
14
|
acquireReindexLock,
|
|
14
|
-
|
|
15
|
+
buildAndPublishPendingReminder,
|
|
15
16
|
buildCodexSidecarDiagnosticsCommand,
|
|
16
17
|
buildCodexSidecarReadOnlySmokeCommand,
|
|
17
18
|
buildCodexSidecarRunCommand,
|
|
18
19
|
buildHookSignalSidecarContextBlock,
|
|
20
|
+
buildPendingSemanticKey,
|
|
19
21
|
caveatEntriesToSidecarContextBlocks,
|
|
20
22
|
cleanupStalePendingDirs,
|
|
21
23
|
communityAdd,
|
|
22
24
|
communityList,
|
|
23
25
|
communityPull,
|
|
24
26
|
communityRemove,
|
|
27
|
+
compactRuntimeErrors,
|
|
25
28
|
computeEntriesDigest,
|
|
26
29
|
createKeyserverKeyProvider,
|
|
27
30
|
decideCodexSidecarExecution,
|
|
28
31
|
defaultSelfIdentityTokens,
|
|
29
|
-
|
|
30
|
-
drainPendingReminders,
|
|
32
|
+
drainPendingRemindersDetailed,
|
|
31
33
|
ensureUserConfig,
|
|
32
34
|
findCaveatHome,
|
|
33
|
-
|
|
35
|
+
findCaveatsForHook,
|
|
36
|
+
findCaveatsForHookSegments,
|
|
34
37
|
get,
|
|
35
38
|
hasAnyStruggleSignal,
|
|
36
39
|
initOwnSync,
|
|
@@ -40,6 +43,7 @@ import {
|
|
|
40
43
|
logHookQueryMiss,
|
|
41
44
|
markHit,
|
|
42
45
|
maybeSweepPendingDirs,
|
|
46
|
+
observeRuntimeError,
|
|
43
47
|
openDb,
|
|
44
48
|
prewarmSealedKeys,
|
|
45
49
|
publishOwn,
|
|
@@ -53,7 +57,10 @@ import {
|
|
|
53
57
|
resetAutoSyncFailureState,
|
|
54
58
|
resolvePaths,
|
|
55
59
|
runAutoSync,
|
|
60
|
+
runtimeErrorsDiagnostics,
|
|
61
|
+
runtimeErrorsSnapshot,
|
|
56
62
|
search,
|
|
63
|
+
setRuntimeErrorStatus,
|
|
57
64
|
stderrLogger,
|
|
58
65
|
stopReminderText,
|
|
59
66
|
struggleSearchText,
|
|
@@ -63,7 +70,7 @@ import {
|
|
|
63
70
|
userPromptSubmitReminderText,
|
|
64
71
|
writeDigestMarker,
|
|
65
72
|
writeUserConfigPatch
|
|
66
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-PD5E6TFL.js";
|
|
67
74
|
|
|
68
75
|
// ../../node_modules/.pnpm/ajv@8.18.0/node_modules/ajv/dist/compile/codegen/code.js
|
|
69
76
|
var require_code = __commonJS({
|
|
@@ -442,11 +449,11 @@ var require_codegen = __commonJS({
|
|
|
442
449
|
const rhs = this.rhs === void 0 ? "" : ` = ${this.rhs}`;
|
|
443
450
|
return `${varKind} ${this.name}${rhs};` + _n;
|
|
444
451
|
}
|
|
445
|
-
optimizeNames(names,
|
|
452
|
+
optimizeNames(names, constants4) {
|
|
446
453
|
if (!names[this.name.str])
|
|
447
454
|
return;
|
|
448
455
|
if (this.rhs)
|
|
449
|
-
this.rhs = optimizeExpr(this.rhs, names,
|
|
456
|
+
this.rhs = optimizeExpr(this.rhs, names, constants4);
|
|
450
457
|
return this;
|
|
451
458
|
}
|
|
452
459
|
get names() {
|
|
@@ -463,10 +470,10 @@ var require_codegen = __commonJS({
|
|
|
463
470
|
render({ _n }) {
|
|
464
471
|
return `${this.lhs} = ${this.rhs};` + _n;
|
|
465
472
|
}
|
|
466
|
-
optimizeNames(names,
|
|
473
|
+
optimizeNames(names, constants4) {
|
|
467
474
|
if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects)
|
|
468
475
|
return;
|
|
469
|
-
this.rhs = optimizeExpr(this.rhs, names,
|
|
476
|
+
this.rhs = optimizeExpr(this.rhs, names, constants4);
|
|
470
477
|
return this;
|
|
471
478
|
}
|
|
472
479
|
get names() {
|
|
@@ -527,8 +534,8 @@ var require_codegen = __commonJS({
|
|
|
527
534
|
optimizeNodes() {
|
|
528
535
|
return `${this.code}` ? this : void 0;
|
|
529
536
|
}
|
|
530
|
-
optimizeNames(names,
|
|
531
|
-
this.code = optimizeExpr(this.code, names,
|
|
537
|
+
optimizeNames(names, constants4) {
|
|
538
|
+
this.code = optimizeExpr(this.code, names, constants4);
|
|
532
539
|
return this;
|
|
533
540
|
}
|
|
534
541
|
get names() {
|
|
@@ -557,12 +564,12 @@ var require_codegen = __commonJS({
|
|
|
557
564
|
}
|
|
558
565
|
return nodes.length > 0 ? this : void 0;
|
|
559
566
|
}
|
|
560
|
-
optimizeNames(names,
|
|
567
|
+
optimizeNames(names, constants4) {
|
|
561
568
|
const { nodes } = this;
|
|
562
569
|
let i = nodes.length;
|
|
563
570
|
while (i--) {
|
|
564
571
|
const n = nodes[i];
|
|
565
|
-
if (n.optimizeNames(names,
|
|
572
|
+
if (n.optimizeNames(names, constants4))
|
|
566
573
|
continue;
|
|
567
574
|
subtractNames(names, n.names);
|
|
568
575
|
nodes.splice(i, 1);
|
|
@@ -615,12 +622,12 @@ var require_codegen = __commonJS({
|
|
|
615
622
|
return void 0;
|
|
616
623
|
return this;
|
|
617
624
|
}
|
|
618
|
-
optimizeNames(names,
|
|
625
|
+
optimizeNames(names, constants4) {
|
|
619
626
|
var _a3;
|
|
620
|
-
this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names,
|
|
621
|
-
if (!(super.optimizeNames(names,
|
|
627
|
+
this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants4);
|
|
628
|
+
if (!(super.optimizeNames(names, constants4) || this.else))
|
|
622
629
|
return;
|
|
623
|
-
this.condition = optimizeExpr(this.condition, names,
|
|
630
|
+
this.condition = optimizeExpr(this.condition, names, constants4);
|
|
624
631
|
return this;
|
|
625
632
|
}
|
|
626
633
|
get names() {
|
|
@@ -643,10 +650,10 @@ var require_codegen = __commonJS({
|
|
|
643
650
|
render(opts) {
|
|
644
651
|
return `for(${this.iteration})` + super.render(opts);
|
|
645
652
|
}
|
|
646
|
-
optimizeNames(names,
|
|
647
|
-
if (!super.optimizeNames(names,
|
|
653
|
+
optimizeNames(names, constants4) {
|
|
654
|
+
if (!super.optimizeNames(names, constants4))
|
|
648
655
|
return;
|
|
649
|
-
this.iteration = optimizeExpr(this.iteration, names,
|
|
656
|
+
this.iteration = optimizeExpr(this.iteration, names, constants4);
|
|
650
657
|
return this;
|
|
651
658
|
}
|
|
652
659
|
get names() {
|
|
@@ -682,10 +689,10 @@ var require_codegen = __commonJS({
|
|
|
682
689
|
render(opts) {
|
|
683
690
|
return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
|
|
684
691
|
}
|
|
685
|
-
optimizeNames(names,
|
|
686
|
-
if (!super.optimizeNames(names,
|
|
692
|
+
optimizeNames(names, constants4) {
|
|
693
|
+
if (!super.optimizeNames(names, constants4))
|
|
687
694
|
return;
|
|
688
|
-
this.iterable = optimizeExpr(this.iterable, names,
|
|
695
|
+
this.iterable = optimizeExpr(this.iterable, names, constants4);
|
|
689
696
|
return this;
|
|
690
697
|
}
|
|
691
698
|
get names() {
|
|
@@ -727,11 +734,11 @@ var require_codegen = __commonJS({
|
|
|
727
734
|
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNodes();
|
|
728
735
|
return this;
|
|
729
736
|
}
|
|
730
|
-
optimizeNames(names,
|
|
737
|
+
optimizeNames(names, constants4) {
|
|
731
738
|
var _a3, _b;
|
|
732
|
-
super.optimizeNames(names,
|
|
733
|
-
(_a3 = this.catch) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names,
|
|
734
|
-
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names,
|
|
739
|
+
super.optimizeNames(names, constants4);
|
|
740
|
+
(_a3 = this.catch) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants4);
|
|
741
|
+
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants4);
|
|
735
742
|
return this;
|
|
736
743
|
}
|
|
737
744
|
get names() {
|
|
@@ -1032,7 +1039,7 @@ var require_codegen = __commonJS({
|
|
|
1032
1039
|
function addExprNames(names, from) {
|
|
1033
1040
|
return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
|
|
1034
1041
|
}
|
|
1035
|
-
function optimizeExpr(expr, names,
|
|
1042
|
+
function optimizeExpr(expr, names, constants4) {
|
|
1036
1043
|
if (expr instanceof code_1.Name)
|
|
1037
1044
|
return replaceName(expr);
|
|
1038
1045
|
if (!canOptimize(expr))
|
|
@@ -1047,14 +1054,14 @@ var require_codegen = __commonJS({
|
|
|
1047
1054
|
return items;
|
|
1048
1055
|
}, []));
|
|
1049
1056
|
function replaceName(n) {
|
|
1050
|
-
const c =
|
|
1057
|
+
const c = constants4[n.str];
|
|
1051
1058
|
if (c === void 0 || names[n.str] !== 1)
|
|
1052
1059
|
return n;
|
|
1053
1060
|
delete names[n.str];
|
|
1054
1061
|
return c;
|
|
1055
1062
|
}
|
|
1056
1063
|
function canOptimize(e) {
|
|
1057
|
-
return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 &&
|
|
1064
|
+
return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants4[c.str] !== void 0);
|
|
1058
1065
|
}
|
|
1059
1066
|
}
|
|
1060
1067
|
function subtractNames(names, from) {
|
|
@@ -6881,8 +6888,8 @@ import { dirname as dirname4, join as join8 } from "node:path";
|
|
|
6881
6888
|
|
|
6882
6889
|
// src/claudeInstall.ts
|
|
6883
6890
|
import { spawnSync } from "node:child_process";
|
|
6884
|
-
import { copyFileSync, existsSync, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
|
|
6885
|
-
import { dirname as dirname2, join as join3 } from "node:path";
|
|
6891
|
+
import { accessSync, constants, copyFileSync, existsSync, mkdirSync, readFileSync as readFileSync2, realpathSync, statSync, writeFileSync } from "node:fs";
|
|
6892
|
+
import { dirname as dirname2, isAbsolute, join as join3 } from "node:path";
|
|
6886
6893
|
var EVENT_USER_PROMPT_SUBMIT = "UserPromptSubmit";
|
|
6887
6894
|
var EVENT_POST_TOOL_USE = "PostToolUse";
|
|
6888
6895
|
var EVENT_POST_TOOL_USE_FAILURE = "PostToolUseFailure";
|
|
@@ -6901,10 +6908,10 @@ function upsertHook(settings, event, command) {
|
|
|
6901
6908
|
const list = settings.hooks[event] ??= [];
|
|
6902
6909
|
const subcommand = command.includes("hook user-prompt-submit") ? "user-prompt-submit" : command.includes("hook post-tool-use") ? "post-tool-use" : command.includes("hook stop") ? "stop" : null;
|
|
6903
6910
|
for (const entry of list) {
|
|
6904
|
-
for (const
|
|
6905
|
-
if (isSameHookCommand(
|
|
6906
|
-
if (subcommand && isCaveatClaudeHookCommand(
|
|
6907
|
-
|
|
6911
|
+
for (const hook2 of entry.hooks ?? []) {
|
|
6912
|
+
if (isSameHookCommand(hook2.command, command)) return "unchanged";
|
|
6913
|
+
if (subcommand && isCaveatClaudeHookCommand(hook2.command, subcommand)) {
|
|
6914
|
+
hook2.command = command;
|
|
6908
6915
|
return "added";
|
|
6909
6916
|
}
|
|
6910
6917
|
}
|
|
@@ -6942,6 +6949,36 @@ function isCaveatClaudeHookCommand(actual, event) {
|
|
|
6942
6949
|
const lower = actual.toLowerCase();
|
|
6943
6950
|
return !isEnvPrefixedCommand(actual) && lower.includes("caveat") && actual.includes(`hook ${event}`);
|
|
6944
6951
|
}
|
|
6952
|
+
function commandTokens(command) {
|
|
6953
|
+
const tokens = [];
|
|
6954
|
+
const pattern = /"([^"]*)"|([^\s"]+)/g;
|
|
6955
|
+
let end = 0;
|
|
6956
|
+
let match;
|
|
6957
|
+
while ((match = pattern.exec(command)) !== null) {
|
|
6958
|
+
if (command.slice(end, match.index).trim()) return null;
|
|
6959
|
+
tokens.push(match[1] ?? match[2]);
|
|
6960
|
+
end = pattern.lastIndex;
|
|
6961
|
+
}
|
|
6962
|
+
return command.slice(end).trim() ? null : tokens;
|
|
6963
|
+
}
|
|
6964
|
+
function isCanonicalAsset(path, expectedPath, mode) {
|
|
6965
|
+
if (typeof path !== "string" || !isAbsolute(path) || !isAbsolute(expectedPath)) return false;
|
|
6966
|
+
try {
|
|
6967
|
+
accessSync(path, mode);
|
|
6968
|
+
return statSync(path).isFile() && realpathSync(path) === realpathSync(expectedPath);
|
|
6969
|
+
} catch {
|
|
6970
|
+
return false;
|
|
6971
|
+
}
|
|
6972
|
+
}
|
|
6973
|
+
function isCanonicalCaveatClaudeHookCommand(actual, event, nodePath, cliScriptPath) {
|
|
6974
|
+
const tokens = commandTokens(actual);
|
|
6975
|
+
return tokens?.length === 4 && isCanonicalAsset(tokens[0], nodePath, constants.X_OK) && isCanonicalAsset(tokens[1], cliScriptPath, constants.R_OK) && tokens[2] === "hook" && tokens[3] === event;
|
|
6976
|
+
}
|
|
6977
|
+
function isCaveatClaudeMcpRegistration(value, nodePath, cliScriptPath) {
|
|
6978
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
6979
|
+
const server = value;
|
|
6980
|
+
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;
|
|
6981
|
+
}
|
|
6945
6982
|
function readSettings(path) {
|
|
6946
6983
|
if (!existsSync(path)) return {};
|
|
6947
6984
|
return JSON.parse(readFileSync2(path, "utf-8"));
|
|
@@ -7073,8 +7110,8 @@ function uninstallClaudeIntegration(opts) {
|
|
|
7073
7110
|
}
|
|
7074
7111
|
|
|
7075
7112
|
// src/codexHookInstall.ts
|
|
7076
|
-
import { copyFileSync as copyFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
7077
|
-
import { dirname as dirname3, join as join4 } from "node:path";
|
|
7113
|
+
import { accessSync as accessSync2, constants as constants2, copyFileSync as copyFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync as realpathSync2, statSync as statSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
7114
|
+
import { dirname as dirname3, isAbsolute as isAbsolute2, join as join4 } from "node:path";
|
|
7078
7115
|
import { parse as parseToml } from "smol-toml";
|
|
7079
7116
|
function quote2(p) {
|
|
7080
7117
|
return p.includes(" ") ? `"${p}"` : p;
|
|
@@ -7092,6 +7129,31 @@ function isCaveatCodexHookCommand(actual, event) {
|
|
|
7092
7129
|
const lower = actual.toLowerCase();
|
|
7093
7130
|
return lower.includes("caveat") && actual.includes(eventCommandFragment(event));
|
|
7094
7131
|
}
|
|
7132
|
+
function commandTokens2(command) {
|
|
7133
|
+
const tokens = [];
|
|
7134
|
+
const pattern = /"([^"]*)"|([^\s"]+)/g;
|
|
7135
|
+
let end = 0;
|
|
7136
|
+
let match;
|
|
7137
|
+
while ((match = pattern.exec(command)) !== null) {
|
|
7138
|
+
if (command.slice(end, match.index).trim()) return null;
|
|
7139
|
+
tokens.push(match[1] ?? match[2]);
|
|
7140
|
+
end = pattern.lastIndex;
|
|
7141
|
+
}
|
|
7142
|
+
return command.slice(end).trim() ? null : tokens;
|
|
7143
|
+
}
|
|
7144
|
+
function isCanonicalAsset2(path, expectedPath, mode) {
|
|
7145
|
+
if (typeof path !== "string" || !isAbsolute2(path) || !isAbsolute2(expectedPath)) return false;
|
|
7146
|
+
try {
|
|
7147
|
+
accessSync2(path, mode);
|
|
7148
|
+
return statSync2(path).isFile() && realpathSync2(path) === realpathSync2(expectedPath);
|
|
7149
|
+
} catch {
|
|
7150
|
+
return false;
|
|
7151
|
+
}
|
|
7152
|
+
}
|
|
7153
|
+
function isCanonicalCaveatCodexHookCommand(actual, event, nodePath, cliScriptPath) {
|
|
7154
|
+
const tokens = commandTokens2(actual);
|
|
7155
|
+
return tokens?.length === 4 && isCanonicalAsset2(tokens[0], nodePath, constants2.X_OK) && isCanonicalAsset2(tokens[1], cliScriptPath, constants2.R_OK) && tokens[2] === "codex-hook" && tokens[3] === event;
|
|
7156
|
+
}
|
|
7095
7157
|
function hasCaveatHook(hooksJson, event, fragment) {
|
|
7096
7158
|
return hooksJson.hooks?.[event]?.some(
|
|
7097
7159
|
(entry) => entry.hooks?.some((h) => h.command.includes(fragment))
|
|
@@ -7117,13 +7179,13 @@ function upsertHook2(hooksJson, event, command, subcommand) {
|
|
|
7117
7179
|
hooksJson.hooks ??= {};
|
|
7118
7180
|
const list = hooksJson.hooks[event] ??= [];
|
|
7119
7181
|
for (const entry of list) {
|
|
7120
|
-
for (const
|
|
7121
|
-
if (isSameHookCommand2(
|
|
7122
|
-
if (isCaveatCodexHookCommand(
|
|
7123
|
-
|
|
7124
|
-
|
|
7125
|
-
|
|
7126
|
-
|
|
7182
|
+
for (const hook2 of entry.hooks ?? []) {
|
|
7183
|
+
if (isSameHookCommand2(hook2.command, command)) return "unchanged";
|
|
7184
|
+
if (isCaveatCodexHookCommand(hook2.command, subcommand)) {
|
|
7185
|
+
hook2.command = command;
|
|
7186
|
+
hook2.timeoutSec = 5;
|
|
7187
|
+
hook2.async = false;
|
|
7188
|
+
hook2.statusMessage = null;
|
|
7127
7189
|
return "added";
|
|
7128
7190
|
}
|
|
7129
7191
|
}
|
|
@@ -7502,9 +7564,9 @@ function askOnce(question) {
|
|
|
7502
7564
|
}
|
|
7503
7565
|
|
|
7504
7566
|
// src/nodePath.ts
|
|
7505
|
-
import { existsSync as existsSync3, realpathSync } from "node:fs";
|
|
7567
|
+
import { existsSync as existsSync3, realpathSync as realpathSync3 } from "node:fs";
|
|
7506
7568
|
import { delimiter, join as join5 } from "node:path";
|
|
7507
|
-
var defaultRealpath = (path) =>
|
|
7569
|
+
var defaultRealpath = (path) => realpathSync3.native(path);
|
|
7508
7570
|
function safeRealpath(path, realpath = defaultRealpath) {
|
|
7509
7571
|
try {
|
|
7510
7572
|
return realpath(path);
|
|
@@ -7544,6 +7606,16 @@ import { spawnSync as spawnSync3 } from "node:child_process";
|
|
|
7544
7606
|
import { mkdtempSync, readFileSync as readFileSync4, rmSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
7545
7607
|
import { tmpdir } from "node:os";
|
|
7546
7608
|
import { join as join6 } from "node:path";
|
|
7609
|
+
var DEFAULT_HOOK_SIDECAR_TIMEOUT_MS = 12e4;
|
|
7610
|
+
var MAX_HOOK_SIDECAR_TIMEOUT_MS = 24e4;
|
|
7611
|
+
function resolveHookSidecarTimeoutMs(raw) {
|
|
7612
|
+
if (raw === void 0) return DEFAULT_HOOK_SIDECAR_TIMEOUT_MS;
|
|
7613
|
+
const value = Number(raw);
|
|
7614
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > MAX_HOOK_SIDECAR_TIMEOUT_MS) {
|
|
7615
|
+
throw new Error(`CAVEAT_HOOK_CODEX_SIDECAR_TIMEOUT_MS must be an integer from 1 to ${MAX_HOOK_SIDECAR_TIMEOUT_MS}`);
|
|
7616
|
+
}
|
|
7617
|
+
return value;
|
|
7618
|
+
}
|
|
7547
7619
|
function compactFailureMessage(message) {
|
|
7548
7620
|
const singleLine = message.replace(/\s+/g, " ").trim();
|
|
7549
7621
|
if (!singleLine) return "unknown error";
|
|
@@ -7607,7 +7679,9 @@ function runCodexSidecarAdvisory(input) {
|
|
|
7607
7679
|
const result = spawnSync3(process.execPath, args, {
|
|
7608
7680
|
cwd: input.projectRoot,
|
|
7609
7681
|
encoding: "utf-8",
|
|
7610
|
-
|
|
7682
|
+
// Keep at least one minute between the longest supported model call and
|
|
7683
|
+
// the pending single-flight claim TTL (five minutes).
|
|
7684
|
+
timeout: resolveHookSidecarTimeoutMs(process.env.CAVEAT_HOOK_CODEX_SIDECAR_TIMEOUT_MS),
|
|
7611
7685
|
maxBuffer: 10 * 1024 * 1024
|
|
7612
7686
|
});
|
|
7613
7687
|
if (result.error) {
|
|
@@ -8036,7 +8110,13 @@ async function runIndex(ctx, opts) {
|
|
|
8036
8110
|
for (const failure of failures) {
|
|
8037
8111
|
ctx.logger.warn(`${failure.source}: sealed key prewarm failed: ${errorMessage2(failure.error)}`);
|
|
8038
8112
|
}
|
|
8039
|
-
|
|
8113
|
+
let db;
|
|
8114
|
+
try {
|
|
8115
|
+
db = openDb({ path: ctx.paths.dbPath, logger: ctx.logger });
|
|
8116
|
+
} catch (error51) {
|
|
8117
|
+
observeRuntimeError("CAVEAT.DATABASE_OPEN_FAILED", { version: CAVEAT_VERSION });
|
|
8118
|
+
throw error51;
|
|
8119
|
+
}
|
|
8040
8120
|
try {
|
|
8041
8121
|
if (opts.full) {
|
|
8042
8122
|
ctx.logger.info("full rebuild: DELETE FROM entries");
|
|
@@ -8051,6 +8131,9 @@ async function runIndex(ctx, opts) {
|
|
|
8051
8131
|
}
|
|
8052
8132
|
}
|
|
8053
8133
|
writeDigestMarker(ctx.caveatHome, computeEntriesDigest(ctx.paths));
|
|
8134
|
+
} catch (error51) {
|
|
8135
|
+
observeRuntimeError("CAVEAT.INDEX_FAILED", { version: CAVEAT_VERSION });
|
|
8136
|
+
throw error51;
|
|
8054
8137
|
} finally {
|
|
8055
8138
|
db.close();
|
|
8056
8139
|
}
|
|
@@ -8205,7 +8288,7 @@ function runStats(ctx) {
|
|
|
8205
8288
|
|
|
8206
8289
|
// src/commands/serve.ts
|
|
8207
8290
|
async function runServe(opts) {
|
|
8208
|
-
const { startServer } = await import("./server-
|
|
8291
|
+
const { startServer } = await import("./server-ZMIRSFMH.js");
|
|
8209
8292
|
const { port, host } = startServer({ port: opts.port });
|
|
8210
8293
|
process.stdout.write(`[caveat] web portal: http://${host}:${port}/
|
|
8211
8294
|
`);
|
|
@@ -8626,18 +8709,18 @@ var ParseStatus = class _ParseStatus {
|
|
|
8626
8709
|
if (this.value !== "aborted")
|
|
8627
8710
|
this.value = "aborted";
|
|
8628
8711
|
}
|
|
8629
|
-
static mergeArray(
|
|
8712
|
+
static mergeArray(status2, results) {
|
|
8630
8713
|
const arrayValue = [];
|
|
8631
8714
|
for (const s of results) {
|
|
8632
8715
|
if (s.status === "aborted")
|
|
8633
8716
|
return INVALID;
|
|
8634
8717
|
if (s.status === "dirty")
|
|
8635
|
-
|
|
8718
|
+
status2.dirty();
|
|
8636
8719
|
arrayValue.push(s.value);
|
|
8637
8720
|
}
|
|
8638
|
-
return { status:
|
|
8721
|
+
return { status: status2.value, value: arrayValue };
|
|
8639
8722
|
}
|
|
8640
|
-
static async mergeObjectAsync(
|
|
8723
|
+
static async mergeObjectAsync(status2, pairs) {
|
|
8641
8724
|
const syncPairs = [];
|
|
8642
8725
|
for (const pair of pairs) {
|
|
8643
8726
|
const key = await pair.key;
|
|
@@ -8647,9 +8730,9 @@ var ParseStatus = class _ParseStatus {
|
|
|
8647
8730
|
value
|
|
8648
8731
|
});
|
|
8649
8732
|
}
|
|
8650
|
-
return _ParseStatus.mergeObjectSync(
|
|
8733
|
+
return _ParseStatus.mergeObjectSync(status2, syncPairs);
|
|
8651
8734
|
}
|
|
8652
|
-
static mergeObjectSync(
|
|
8735
|
+
static mergeObjectSync(status2, pairs) {
|
|
8653
8736
|
const finalObject = {};
|
|
8654
8737
|
for (const pair of pairs) {
|
|
8655
8738
|
const { key, value } = pair;
|
|
@@ -8658,14 +8741,14 @@ var ParseStatus = class _ParseStatus {
|
|
|
8658
8741
|
if (value.status === "aborted")
|
|
8659
8742
|
return INVALID;
|
|
8660
8743
|
if (key.status === "dirty")
|
|
8661
|
-
|
|
8744
|
+
status2.dirty();
|
|
8662
8745
|
if (value.status === "dirty")
|
|
8663
|
-
|
|
8746
|
+
status2.dirty();
|
|
8664
8747
|
if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) {
|
|
8665
8748
|
finalObject[key.value] = value.value;
|
|
8666
8749
|
}
|
|
8667
8750
|
}
|
|
8668
|
-
return { status:
|
|
8751
|
+
return { status: status2.value, value: finalObject };
|
|
8669
8752
|
}
|
|
8670
8753
|
};
|
|
8671
8754
|
var INVALID = Object.freeze({
|
|
@@ -9125,7 +9208,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9125
9208
|
});
|
|
9126
9209
|
return INVALID;
|
|
9127
9210
|
}
|
|
9128
|
-
const
|
|
9211
|
+
const status2 = new ParseStatus();
|
|
9129
9212
|
let ctx = void 0;
|
|
9130
9213
|
for (const check2 of this._def.checks) {
|
|
9131
9214
|
if (check2.kind === "min") {
|
|
@@ -9139,7 +9222,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9139
9222
|
exact: false,
|
|
9140
9223
|
message: check2.message
|
|
9141
9224
|
});
|
|
9142
|
-
|
|
9225
|
+
status2.dirty();
|
|
9143
9226
|
}
|
|
9144
9227
|
} else if (check2.kind === "max") {
|
|
9145
9228
|
if (input.data.length > check2.value) {
|
|
@@ -9152,7 +9235,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9152
9235
|
exact: false,
|
|
9153
9236
|
message: check2.message
|
|
9154
9237
|
});
|
|
9155
|
-
|
|
9238
|
+
status2.dirty();
|
|
9156
9239
|
}
|
|
9157
9240
|
} else if (check2.kind === "length") {
|
|
9158
9241
|
const tooBig = input.data.length > check2.value;
|
|
@@ -9178,7 +9261,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9178
9261
|
message: check2.message
|
|
9179
9262
|
});
|
|
9180
9263
|
}
|
|
9181
|
-
|
|
9264
|
+
status2.dirty();
|
|
9182
9265
|
}
|
|
9183
9266
|
} else if (check2.kind === "email") {
|
|
9184
9267
|
if (!emailRegex.test(input.data)) {
|
|
@@ -9188,7 +9271,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9188
9271
|
code: ZodIssueCode.invalid_string,
|
|
9189
9272
|
message: check2.message
|
|
9190
9273
|
});
|
|
9191
|
-
|
|
9274
|
+
status2.dirty();
|
|
9192
9275
|
}
|
|
9193
9276
|
} else if (check2.kind === "emoji") {
|
|
9194
9277
|
if (!emojiRegex) {
|
|
@@ -9201,7 +9284,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9201
9284
|
code: ZodIssueCode.invalid_string,
|
|
9202
9285
|
message: check2.message
|
|
9203
9286
|
});
|
|
9204
|
-
|
|
9287
|
+
status2.dirty();
|
|
9205
9288
|
}
|
|
9206
9289
|
} else if (check2.kind === "uuid") {
|
|
9207
9290
|
if (!uuidRegex.test(input.data)) {
|
|
@@ -9211,7 +9294,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9211
9294
|
code: ZodIssueCode.invalid_string,
|
|
9212
9295
|
message: check2.message
|
|
9213
9296
|
});
|
|
9214
|
-
|
|
9297
|
+
status2.dirty();
|
|
9215
9298
|
}
|
|
9216
9299
|
} else if (check2.kind === "nanoid") {
|
|
9217
9300
|
if (!nanoidRegex.test(input.data)) {
|
|
@@ -9221,7 +9304,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9221
9304
|
code: ZodIssueCode.invalid_string,
|
|
9222
9305
|
message: check2.message
|
|
9223
9306
|
});
|
|
9224
|
-
|
|
9307
|
+
status2.dirty();
|
|
9225
9308
|
}
|
|
9226
9309
|
} else if (check2.kind === "cuid") {
|
|
9227
9310
|
if (!cuidRegex.test(input.data)) {
|
|
@@ -9231,7 +9314,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9231
9314
|
code: ZodIssueCode.invalid_string,
|
|
9232
9315
|
message: check2.message
|
|
9233
9316
|
});
|
|
9234
|
-
|
|
9317
|
+
status2.dirty();
|
|
9235
9318
|
}
|
|
9236
9319
|
} else if (check2.kind === "cuid2") {
|
|
9237
9320
|
if (!cuid2Regex.test(input.data)) {
|
|
@@ -9241,7 +9324,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9241
9324
|
code: ZodIssueCode.invalid_string,
|
|
9242
9325
|
message: check2.message
|
|
9243
9326
|
});
|
|
9244
|
-
|
|
9327
|
+
status2.dirty();
|
|
9245
9328
|
}
|
|
9246
9329
|
} else if (check2.kind === "ulid") {
|
|
9247
9330
|
if (!ulidRegex.test(input.data)) {
|
|
@@ -9251,7 +9334,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9251
9334
|
code: ZodIssueCode.invalid_string,
|
|
9252
9335
|
message: check2.message
|
|
9253
9336
|
});
|
|
9254
|
-
|
|
9337
|
+
status2.dirty();
|
|
9255
9338
|
}
|
|
9256
9339
|
} else if (check2.kind === "url") {
|
|
9257
9340
|
try {
|
|
@@ -9263,7 +9346,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9263
9346
|
code: ZodIssueCode.invalid_string,
|
|
9264
9347
|
message: check2.message
|
|
9265
9348
|
});
|
|
9266
|
-
|
|
9349
|
+
status2.dirty();
|
|
9267
9350
|
}
|
|
9268
9351
|
} else if (check2.kind === "regex") {
|
|
9269
9352
|
check2.regex.lastIndex = 0;
|
|
@@ -9275,7 +9358,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9275
9358
|
code: ZodIssueCode.invalid_string,
|
|
9276
9359
|
message: check2.message
|
|
9277
9360
|
});
|
|
9278
|
-
|
|
9361
|
+
status2.dirty();
|
|
9279
9362
|
}
|
|
9280
9363
|
} else if (check2.kind === "trim") {
|
|
9281
9364
|
input.data = input.data.trim();
|
|
@@ -9287,7 +9370,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9287
9370
|
validation: { includes: check2.value, position: check2.position },
|
|
9288
9371
|
message: check2.message
|
|
9289
9372
|
});
|
|
9290
|
-
|
|
9373
|
+
status2.dirty();
|
|
9291
9374
|
}
|
|
9292
9375
|
} else if (check2.kind === "toLowerCase") {
|
|
9293
9376
|
input.data = input.data.toLowerCase();
|
|
@@ -9301,7 +9384,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9301
9384
|
validation: { startsWith: check2.value },
|
|
9302
9385
|
message: check2.message
|
|
9303
9386
|
});
|
|
9304
|
-
|
|
9387
|
+
status2.dirty();
|
|
9305
9388
|
}
|
|
9306
9389
|
} else if (check2.kind === "endsWith") {
|
|
9307
9390
|
if (!input.data.endsWith(check2.value)) {
|
|
@@ -9311,7 +9394,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9311
9394
|
validation: { endsWith: check2.value },
|
|
9312
9395
|
message: check2.message
|
|
9313
9396
|
});
|
|
9314
|
-
|
|
9397
|
+
status2.dirty();
|
|
9315
9398
|
}
|
|
9316
9399
|
} else if (check2.kind === "datetime") {
|
|
9317
9400
|
const regex = datetimeRegex(check2);
|
|
@@ -9322,7 +9405,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9322
9405
|
validation: "datetime",
|
|
9323
9406
|
message: check2.message
|
|
9324
9407
|
});
|
|
9325
|
-
|
|
9408
|
+
status2.dirty();
|
|
9326
9409
|
}
|
|
9327
9410
|
} else if (check2.kind === "date") {
|
|
9328
9411
|
const regex = dateRegex;
|
|
@@ -9333,7 +9416,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9333
9416
|
validation: "date",
|
|
9334
9417
|
message: check2.message
|
|
9335
9418
|
});
|
|
9336
|
-
|
|
9419
|
+
status2.dirty();
|
|
9337
9420
|
}
|
|
9338
9421
|
} else if (check2.kind === "time") {
|
|
9339
9422
|
const regex = timeRegex(check2);
|
|
@@ -9344,7 +9427,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9344
9427
|
validation: "time",
|
|
9345
9428
|
message: check2.message
|
|
9346
9429
|
});
|
|
9347
|
-
|
|
9430
|
+
status2.dirty();
|
|
9348
9431
|
}
|
|
9349
9432
|
} else if (check2.kind === "duration") {
|
|
9350
9433
|
if (!durationRegex.test(input.data)) {
|
|
@@ -9354,7 +9437,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9354
9437
|
code: ZodIssueCode.invalid_string,
|
|
9355
9438
|
message: check2.message
|
|
9356
9439
|
});
|
|
9357
|
-
|
|
9440
|
+
status2.dirty();
|
|
9358
9441
|
}
|
|
9359
9442
|
} else if (check2.kind === "ip") {
|
|
9360
9443
|
if (!isValidIP(input.data, check2.version)) {
|
|
@@ -9364,7 +9447,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9364
9447
|
code: ZodIssueCode.invalid_string,
|
|
9365
9448
|
message: check2.message
|
|
9366
9449
|
});
|
|
9367
|
-
|
|
9450
|
+
status2.dirty();
|
|
9368
9451
|
}
|
|
9369
9452
|
} else if (check2.kind === "jwt") {
|
|
9370
9453
|
if (!isValidJWT(input.data, check2.alg)) {
|
|
@@ -9374,7 +9457,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9374
9457
|
code: ZodIssueCode.invalid_string,
|
|
9375
9458
|
message: check2.message
|
|
9376
9459
|
});
|
|
9377
|
-
|
|
9460
|
+
status2.dirty();
|
|
9378
9461
|
}
|
|
9379
9462
|
} else if (check2.kind === "cidr") {
|
|
9380
9463
|
if (!isValidCidr(input.data, check2.version)) {
|
|
@@ -9384,7 +9467,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9384
9467
|
code: ZodIssueCode.invalid_string,
|
|
9385
9468
|
message: check2.message
|
|
9386
9469
|
});
|
|
9387
|
-
|
|
9470
|
+
status2.dirty();
|
|
9388
9471
|
}
|
|
9389
9472
|
} else if (check2.kind === "base64") {
|
|
9390
9473
|
if (!base64Regex.test(input.data)) {
|
|
@@ -9394,7 +9477,7 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9394
9477
|
code: ZodIssueCode.invalid_string,
|
|
9395
9478
|
message: check2.message
|
|
9396
9479
|
});
|
|
9397
|
-
|
|
9480
|
+
status2.dirty();
|
|
9398
9481
|
}
|
|
9399
9482
|
} else if (check2.kind === "base64url") {
|
|
9400
9483
|
if (!base64urlRegex.test(input.data)) {
|
|
@@ -9404,13 +9487,13 @@ var ZodString = class _ZodString2 extends ZodType {
|
|
|
9404
9487
|
code: ZodIssueCode.invalid_string,
|
|
9405
9488
|
message: check2.message
|
|
9406
9489
|
});
|
|
9407
|
-
|
|
9490
|
+
status2.dirty();
|
|
9408
9491
|
}
|
|
9409
9492
|
} else {
|
|
9410
9493
|
util.assertNever(check2);
|
|
9411
9494
|
}
|
|
9412
9495
|
}
|
|
9413
|
-
return { status:
|
|
9496
|
+
return { status: status2.value, value: input.data };
|
|
9414
9497
|
}
|
|
9415
9498
|
_regex(regex, validation, message) {
|
|
9416
9499
|
return this.refinement((data) => regex.test(data), {
|
|
@@ -9686,7 +9769,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
|
|
|
9686
9769
|
return INVALID;
|
|
9687
9770
|
}
|
|
9688
9771
|
let ctx = void 0;
|
|
9689
|
-
const
|
|
9772
|
+
const status2 = new ParseStatus();
|
|
9690
9773
|
for (const check2 of this._def.checks) {
|
|
9691
9774
|
if (check2.kind === "int") {
|
|
9692
9775
|
if (!util.isInteger(input.data)) {
|
|
@@ -9697,7 +9780,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
|
|
|
9697
9780
|
received: "float",
|
|
9698
9781
|
message: check2.message
|
|
9699
9782
|
});
|
|
9700
|
-
|
|
9783
|
+
status2.dirty();
|
|
9701
9784
|
}
|
|
9702
9785
|
} else if (check2.kind === "min") {
|
|
9703
9786
|
const tooSmall = check2.inclusive ? input.data < check2.value : input.data <= check2.value;
|
|
@@ -9711,7 +9794,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
|
|
|
9711
9794
|
exact: false,
|
|
9712
9795
|
message: check2.message
|
|
9713
9796
|
});
|
|
9714
|
-
|
|
9797
|
+
status2.dirty();
|
|
9715
9798
|
}
|
|
9716
9799
|
} else if (check2.kind === "max") {
|
|
9717
9800
|
const tooBig = check2.inclusive ? input.data > check2.value : input.data >= check2.value;
|
|
@@ -9725,7 +9808,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
|
|
|
9725
9808
|
exact: false,
|
|
9726
9809
|
message: check2.message
|
|
9727
9810
|
});
|
|
9728
|
-
|
|
9811
|
+
status2.dirty();
|
|
9729
9812
|
}
|
|
9730
9813
|
} else if (check2.kind === "multipleOf") {
|
|
9731
9814
|
if (floatSafeRemainder(input.data, check2.value) !== 0) {
|
|
@@ -9735,7 +9818,7 @@ var ZodNumber = class _ZodNumber extends ZodType {
|
|
|
9735
9818
|
multipleOf: check2.value,
|
|
9736
9819
|
message: check2.message
|
|
9737
9820
|
});
|
|
9738
|
-
|
|
9821
|
+
status2.dirty();
|
|
9739
9822
|
}
|
|
9740
9823
|
} else if (check2.kind === "finite") {
|
|
9741
9824
|
if (!Number.isFinite(input.data)) {
|
|
@@ -9744,13 +9827,13 @@ var ZodNumber = class _ZodNumber extends ZodType {
|
|
|
9744
9827
|
code: ZodIssueCode.not_finite,
|
|
9745
9828
|
message: check2.message
|
|
9746
9829
|
});
|
|
9747
|
-
|
|
9830
|
+
status2.dirty();
|
|
9748
9831
|
}
|
|
9749
9832
|
} else {
|
|
9750
9833
|
util.assertNever(check2);
|
|
9751
9834
|
}
|
|
9752
9835
|
}
|
|
9753
|
-
return { status:
|
|
9836
|
+
return { status: status2.value, value: input.data };
|
|
9754
9837
|
}
|
|
9755
9838
|
gte(value, message) {
|
|
9756
9839
|
return this.setLimit("min", value, true, errorUtil.toString(message));
|
|
@@ -9915,7 +9998,7 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
|
|
|
9915
9998
|
return this._getInvalidInput(input);
|
|
9916
9999
|
}
|
|
9917
10000
|
let ctx = void 0;
|
|
9918
|
-
const
|
|
10001
|
+
const status2 = new ParseStatus();
|
|
9919
10002
|
for (const check2 of this._def.checks) {
|
|
9920
10003
|
if (check2.kind === "min") {
|
|
9921
10004
|
const tooSmall = check2.inclusive ? input.data < check2.value : input.data <= check2.value;
|
|
@@ -9928,7 +10011,7 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
|
|
|
9928
10011
|
inclusive: check2.inclusive,
|
|
9929
10012
|
message: check2.message
|
|
9930
10013
|
});
|
|
9931
|
-
|
|
10014
|
+
status2.dirty();
|
|
9932
10015
|
}
|
|
9933
10016
|
} else if (check2.kind === "max") {
|
|
9934
10017
|
const tooBig = check2.inclusive ? input.data > check2.value : input.data >= check2.value;
|
|
@@ -9941,7 +10024,7 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
|
|
|
9941
10024
|
inclusive: check2.inclusive,
|
|
9942
10025
|
message: check2.message
|
|
9943
10026
|
});
|
|
9944
|
-
|
|
10027
|
+
status2.dirty();
|
|
9945
10028
|
}
|
|
9946
10029
|
} else if (check2.kind === "multipleOf") {
|
|
9947
10030
|
if (input.data % check2.value !== BigInt(0)) {
|
|
@@ -9951,13 +10034,13 @@ var ZodBigInt = class _ZodBigInt extends ZodType {
|
|
|
9951
10034
|
multipleOf: check2.value,
|
|
9952
10035
|
message: check2.message
|
|
9953
10036
|
});
|
|
9954
|
-
|
|
10037
|
+
status2.dirty();
|
|
9955
10038
|
}
|
|
9956
10039
|
} else {
|
|
9957
10040
|
util.assertNever(check2);
|
|
9958
10041
|
}
|
|
9959
10042
|
}
|
|
9960
|
-
return { status:
|
|
10043
|
+
return { status: status2.value, value: input.data };
|
|
9961
10044
|
}
|
|
9962
10045
|
_getInvalidInput(input) {
|
|
9963
10046
|
const ctx = this._getOrReturnCtx(input);
|
|
@@ -10115,7 +10198,7 @@ var ZodDate = class _ZodDate extends ZodType {
|
|
|
10115
10198
|
});
|
|
10116
10199
|
return INVALID;
|
|
10117
10200
|
}
|
|
10118
|
-
const
|
|
10201
|
+
const status2 = new ParseStatus();
|
|
10119
10202
|
let ctx = void 0;
|
|
10120
10203
|
for (const check2 of this._def.checks) {
|
|
10121
10204
|
if (check2.kind === "min") {
|
|
@@ -10129,7 +10212,7 @@ var ZodDate = class _ZodDate extends ZodType {
|
|
|
10129
10212
|
minimum: check2.value,
|
|
10130
10213
|
type: "date"
|
|
10131
10214
|
});
|
|
10132
|
-
|
|
10215
|
+
status2.dirty();
|
|
10133
10216
|
}
|
|
10134
10217
|
} else if (check2.kind === "max") {
|
|
10135
10218
|
if (input.data.getTime() > check2.value) {
|
|
@@ -10142,14 +10225,14 @@ var ZodDate = class _ZodDate extends ZodType {
|
|
|
10142
10225
|
maximum: check2.value,
|
|
10143
10226
|
type: "date"
|
|
10144
10227
|
});
|
|
10145
|
-
|
|
10228
|
+
status2.dirty();
|
|
10146
10229
|
}
|
|
10147
10230
|
} else {
|
|
10148
10231
|
util.assertNever(check2);
|
|
10149
10232
|
}
|
|
10150
10233
|
}
|
|
10151
10234
|
return {
|
|
10152
|
-
status:
|
|
10235
|
+
status: status2.value,
|
|
10153
10236
|
value: new Date(input.data.getTime())
|
|
10154
10237
|
};
|
|
10155
10238
|
}
|
|
@@ -10335,7 +10418,7 @@ ZodVoid.create = (params) => {
|
|
|
10335
10418
|
};
|
|
10336
10419
|
var ZodArray = class _ZodArray extends ZodType {
|
|
10337
10420
|
_parse(input) {
|
|
10338
|
-
const { ctx, status } = this._processInputParams(input);
|
|
10421
|
+
const { ctx, status: status2 } = this._processInputParams(input);
|
|
10339
10422
|
const def = this._def;
|
|
10340
10423
|
if (ctx.parsedType !== ZodParsedType.array) {
|
|
10341
10424
|
addIssueToContext(ctx, {
|
|
@@ -10358,7 +10441,7 @@ var ZodArray = class _ZodArray extends ZodType {
|
|
|
10358
10441
|
exact: true,
|
|
10359
10442
|
message: def.exactLength.message
|
|
10360
10443
|
});
|
|
10361
|
-
|
|
10444
|
+
status2.dirty();
|
|
10362
10445
|
}
|
|
10363
10446
|
}
|
|
10364
10447
|
if (def.minLength !== null) {
|
|
@@ -10371,7 +10454,7 @@ var ZodArray = class _ZodArray extends ZodType {
|
|
|
10371
10454
|
exact: false,
|
|
10372
10455
|
message: def.minLength.message
|
|
10373
10456
|
});
|
|
10374
|
-
|
|
10457
|
+
status2.dirty();
|
|
10375
10458
|
}
|
|
10376
10459
|
}
|
|
10377
10460
|
if (def.maxLength !== null) {
|
|
@@ -10384,20 +10467,20 @@ var ZodArray = class _ZodArray extends ZodType {
|
|
|
10384
10467
|
exact: false,
|
|
10385
10468
|
message: def.maxLength.message
|
|
10386
10469
|
});
|
|
10387
|
-
|
|
10470
|
+
status2.dirty();
|
|
10388
10471
|
}
|
|
10389
10472
|
}
|
|
10390
10473
|
if (ctx.common.async) {
|
|
10391
10474
|
return Promise.all([...ctx.data].map((item, i) => {
|
|
10392
10475
|
return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));
|
|
10393
10476
|
})).then((result2) => {
|
|
10394
|
-
return ParseStatus.mergeArray(
|
|
10477
|
+
return ParseStatus.mergeArray(status2, result2);
|
|
10395
10478
|
});
|
|
10396
10479
|
}
|
|
10397
10480
|
const result = [...ctx.data].map((item, i) => {
|
|
10398
10481
|
return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));
|
|
10399
10482
|
});
|
|
10400
|
-
return ParseStatus.mergeArray(
|
|
10483
|
+
return ParseStatus.mergeArray(status2, result);
|
|
10401
10484
|
}
|
|
10402
10485
|
get element() {
|
|
10403
10486
|
return this._def.type;
|
|
@@ -10486,7 +10569,7 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
10486
10569
|
});
|
|
10487
10570
|
return INVALID;
|
|
10488
10571
|
}
|
|
10489
|
-
const { status, ctx } = this._processInputParams(input);
|
|
10572
|
+
const { status: status2, ctx } = this._processInputParams(input);
|
|
10490
10573
|
const { shape, keys: shapeKeys } = this._getCached();
|
|
10491
10574
|
const extraKeys = [];
|
|
10492
10575
|
if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
|
|
@@ -10521,7 +10604,7 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
10521
10604
|
code: ZodIssueCode.unrecognized_keys,
|
|
10522
10605
|
keys: extraKeys
|
|
10523
10606
|
});
|
|
10524
|
-
|
|
10607
|
+
status2.dirty();
|
|
10525
10608
|
}
|
|
10526
10609
|
} else if (unknownKeys === "strip") {
|
|
10527
10610
|
} else {
|
|
@@ -10555,10 +10638,10 @@ var ZodObject = class _ZodObject extends ZodType {
|
|
|
10555
10638
|
}
|
|
10556
10639
|
return syncPairs;
|
|
10557
10640
|
}).then((syncPairs) => {
|
|
10558
|
-
return ParseStatus.mergeObjectSync(
|
|
10641
|
+
return ParseStatus.mergeObjectSync(status2, syncPairs);
|
|
10559
10642
|
});
|
|
10560
10643
|
} else {
|
|
10561
|
-
return ParseStatus.mergeObjectSync(
|
|
10644
|
+
return ParseStatus.mergeObjectSync(status2, pairs);
|
|
10562
10645
|
}
|
|
10563
10646
|
}
|
|
10564
10647
|
get shape() {
|
|
@@ -11036,7 +11119,7 @@ function mergeValues(a, b) {
|
|
|
11036
11119
|
}
|
|
11037
11120
|
var ZodIntersection = class extends ZodType {
|
|
11038
11121
|
_parse(input) {
|
|
11039
|
-
const { status, ctx } = this._processInputParams(input);
|
|
11122
|
+
const { status: status2, ctx } = this._processInputParams(input);
|
|
11040
11123
|
const handleParsed = (parsedLeft, parsedRight) => {
|
|
11041
11124
|
if (isAborted(parsedLeft) || isAborted(parsedRight)) {
|
|
11042
11125
|
return INVALID;
|
|
@@ -11049,9 +11132,9 @@ var ZodIntersection = class extends ZodType {
|
|
|
11049
11132
|
return INVALID;
|
|
11050
11133
|
}
|
|
11051
11134
|
if (isDirty(parsedLeft) || isDirty(parsedRight)) {
|
|
11052
|
-
|
|
11135
|
+
status2.dirty();
|
|
11053
11136
|
}
|
|
11054
|
-
return { status:
|
|
11137
|
+
return { status: status2.value, value: merged.data };
|
|
11055
11138
|
};
|
|
11056
11139
|
if (ctx.common.async) {
|
|
11057
11140
|
return Promise.all([
|
|
@@ -11089,7 +11172,7 @@ ZodIntersection.create = (left, right, params) => {
|
|
|
11089
11172
|
};
|
|
11090
11173
|
var ZodTuple = class _ZodTuple extends ZodType {
|
|
11091
11174
|
_parse(input) {
|
|
11092
|
-
const { status, ctx } = this._processInputParams(input);
|
|
11175
|
+
const { status: status2, ctx } = this._processInputParams(input);
|
|
11093
11176
|
if (ctx.parsedType !== ZodParsedType.array) {
|
|
11094
11177
|
addIssueToContext(ctx, {
|
|
11095
11178
|
code: ZodIssueCode.invalid_type,
|
|
@@ -11117,7 +11200,7 @@ var ZodTuple = class _ZodTuple extends ZodType {
|
|
|
11117
11200
|
exact: false,
|
|
11118
11201
|
type: "array"
|
|
11119
11202
|
});
|
|
11120
|
-
|
|
11203
|
+
status2.dirty();
|
|
11121
11204
|
}
|
|
11122
11205
|
const items = [...ctx.data].map((item, itemIndex) => {
|
|
11123
11206
|
const schema = this._def.items[itemIndex] || this._def.rest;
|
|
@@ -11127,10 +11210,10 @@ var ZodTuple = class _ZodTuple extends ZodType {
|
|
|
11127
11210
|
}).filter((x) => !!x);
|
|
11128
11211
|
if (ctx.common.async) {
|
|
11129
11212
|
return Promise.all(items).then((results) => {
|
|
11130
|
-
return ParseStatus.mergeArray(
|
|
11213
|
+
return ParseStatus.mergeArray(status2, results);
|
|
11131
11214
|
});
|
|
11132
11215
|
} else {
|
|
11133
|
-
return ParseStatus.mergeArray(
|
|
11216
|
+
return ParseStatus.mergeArray(status2, items);
|
|
11134
11217
|
}
|
|
11135
11218
|
}
|
|
11136
11219
|
get items() {
|
|
@@ -11162,7 +11245,7 @@ var ZodRecord = class _ZodRecord extends ZodType {
|
|
|
11162
11245
|
return this._def.valueType;
|
|
11163
11246
|
}
|
|
11164
11247
|
_parse(input) {
|
|
11165
|
-
const { status, ctx } = this._processInputParams(input);
|
|
11248
|
+
const { status: status2, ctx } = this._processInputParams(input);
|
|
11166
11249
|
if (ctx.parsedType !== ZodParsedType.object) {
|
|
11167
11250
|
addIssueToContext(ctx, {
|
|
11168
11251
|
code: ZodIssueCode.invalid_type,
|
|
@@ -11182,9 +11265,9 @@ var ZodRecord = class _ZodRecord extends ZodType {
|
|
|
11182
11265
|
});
|
|
11183
11266
|
}
|
|
11184
11267
|
if (ctx.common.async) {
|
|
11185
|
-
return ParseStatus.mergeObjectAsync(
|
|
11268
|
+
return ParseStatus.mergeObjectAsync(status2, pairs);
|
|
11186
11269
|
} else {
|
|
11187
|
-
return ParseStatus.mergeObjectSync(
|
|
11270
|
+
return ParseStatus.mergeObjectSync(status2, pairs);
|
|
11188
11271
|
}
|
|
11189
11272
|
}
|
|
11190
11273
|
get element() {
|
|
@@ -11215,7 +11298,7 @@ var ZodMap = class extends ZodType {
|
|
|
11215
11298
|
return this._def.valueType;
|
|
11216
11299
|
}
|
|
11217
11300
|
_parse(input) {
|
|
11218
|
-
const { status, ctx } = this._processInputParams(input);
|
|
11301
|
+
const { status: status2, ctx } = this._processInputParams(input);
|
|
11219
11302
|
if (ctx.parsedType !== ZodParsedType.map) {
|
|
11220
11303
|
addIssueToContext(ctx, {
|
|
11221
11304
|
code: ZodIssueCode.invalid_type,
|
|
@@ -11242,11 +11325,11 @@ var ZodMap = class extends ZodType {
|
|
|
11242
11325
|
return INVALID;
|
|
11243
11326
|
}
|
|
11244
11327
|
if (key.status === "dirty" || value.status === "dirty") {
|
|
11245
|
-
|
|
11328
|
+
status2.dirty();
|
|
11246
11329
|
}
|
|
11247
11330
|
finalMap.set(key.value, value.value);
|
|
11248
11331
|
}
|
|
11249
|
-
return { status:
|
|
11332
|
+
return { status: status2.value, value: finalMap };
|
|
11250
11333
|
});
|
|
11251
11334
|
} else {
|
|
11252
11335
|
const finalMap = /* @__PURE__ */ new Map();
|
|
@@ -11257,11 +11340,11 @@ var ZodMap = class extends ZodType {
|
|
|
11257
11340
|
return INVALID;
|
|
11258
11341
|
}
|
|
11259
11342
|
if (key.status === "dirty" || value.status === "dirty") {
|
|
11260
|
-
|
|
11343
|
+
status2.dirty();
|
|
11261
11344
|
}
|
|
11262
11345
|
finalMap.set(key.value, value.value);
|
|
11263
11346
|
}
|
|
11264
|
-
return { status:
|
|
11347
|
+
return { status: status2.value, value: finalMap };
|
|
11265
11348
|
}
|
|
11266
11349
|
}
|
|
11267
11350
|
};
|
|
@@ -11275,7 +11358,7 @@ ZodMap.create = (keyType, valueType, params) => {
|
|
|
11275
11358
|
};
|
|
11276
11359
|
var ZodSet = class _ZodSet extends ZodType {
|
|
11277
11360
|
_parse(input) {
|
|
11278
|
-
const { status, ctx } = this._processInputParams(input);
|
|
11361
|
+
const { status: status2, ctx } = this._processInputParams(input);
|
|
11279
11362
|
if (ctx.parsedType !== ZodParsedType.set) {
|
|
11280
11363
|
addIssueToContext(ctx, {
|
|
11281
11364
|
code: ZodIssueCode.invalid_type,
|
|
@@ -11295,7 +11378,7 @@ var ZodSet = class _ZodSet extends ZodType {
|
|
|
11295
11378
|
exact: false,
|
|
11296
11379
|
message: def.minSize.message
|
|
11297
11380
|
});
|
|
11298
|
-
|
|
11381
|
+
status2.dirty();
|
|
11299
11382
|
}
|
|
11300
11383
|
}
|
|
11301
11384
|
if (def.maxSize !== null) {
|
|
@@ -11308,7 +11391,7 @@ var ZodSet = class _ZodSet extends ZodType {
|
|
|
11308
11391
|
exact: false,
|
|
11309
11392
|
message: def.maxSize.message
|
|
11310
11393
|
});
|
|
11311
|
-
|
|
11394
|
+
status2.dirty();
|
|
11312
11395
|
}
|
|
11313
11396
|
}
|
|
11314
11397
|
const valueType = this._def.valueType;
|
|
@@ -11318,10 +11401,10 @@ var ZodSet = class _ZodSet extends ZodType {
|
|
|
11318
11401
|
if (element.status === "aborted")
|
|
11319
11402
|
return INVALID;
|
|
11320
11403
|
if (element.status === "dirty")
|
|
11321
|
-
|
|
11404
|
+
status2.dirty();
|
|
11322
11405
|
parsedSet.add(element.value);
|
|
11323
11406
|
}
|
|
11324
|
-
return { status:
|
|
11407
|
+
return { status: status2.value, value: parsedSet };
|
|
11325
11408
|
}
|
|
11326
11409
|
const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));
|
|
11327
11410
|
if (ctx.common.async) {
|
|
@@ -11652,15 +11735,15 @@ var ZodEffects = class extends ZodType {
|
|
|
11652
11735
|
return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects ? this._def.schema.sourceType() : this._def.schema;
|
|
11653
11736
|
}
|
|
11654
11737
|
_parse(input) {
|
|
11655
|
-
const { status, ctx } = this._processInputParams(input);
|
|
11738
|
+
const { status: status2, ctx } = this._processInputParams(input);
|
|
11656
11739
|
const effect = this._def.effect || null;
|
|
11657
11740
|
const checkCtx = {
|
|
11658
11741
|
addIssue: (arg) => {
|
|
11659
11742
|
addIssueToContext(ctx, arg);
|
|
11660
11743
|
if (arg.fatal) {
|
|
11661
|
-
|
|
11744
|
+
status2.abort();
|
|
11662
11745
|
} else {
|
|
11663
|
-
|
|
11746
|
+
status2.dirty();
|
|
11664
11747
|
}
|
|
11665
11748
|
},
|
|
11666
11749
|
get path() {
|
|
@@ -11672,7 +11755,7 @@ var ZodEffects = class extends ZodType {
|
|
|
11672
11755
|
const processed = effect.transform(ctx.data, checkCtx);
|
|
11673
11756
|
if (ctx.common.async) {
|
|
11674
11757
|
return Promise.resolve(processed).then(async (processed2) => {
|
|
11675
|
-
if (
|
|
11758
|
+
if (status2.value === "aborted")
|
|
11676
11759
|
return INVALID;
|
|
11677
11760
|
const result = await this._def.schema._parseAsync({
|
|
11678
11761
|
data: processed2,
|
|
@@ -11683,12 +11766,12 @@ var ZodEffects = class extends ZodType {
|
|
|
11683
11766
|
return INVALID;
|
|
11684
11767
|
if (result.status === "dirty")
|
|
11685
11768
|
return DIRTY(result.value);
|
|
11686
|
-
if (
|
|
11769
|
+
if (status2.value === "dirty")
|
|
11687
11770
|
return DIRTY(result.value);
|
|
11688
11771
|
return result;
|
|
11689
11772
|
});
|
|
11690
11773
|
} else {
|
|
11691
|
-
if (
|
|
11774
|
+
if (status2.value === "aborted")
|
|
11692
11775
|
return INVALID;
|
|
11693
11776
|
const result = this._def.schema._parseSync({
|
|
11694
11777
|
data: processed,
|
|
@@ -11699,7 +11782,7 @@ var ZodEffects = class extends ZodType {
|
|
|
11699
11782
|
return INVALID;
|
|
11700
11783
|
if (result.status === "dirty")
|
|
11701
11784
|
return DIRTY(result.value);
|
|
11702
|
-
if (
|
|
11785
|
+
if (status2.value === "dirty")
|
|
11703
11786
|
return DIRTY(result.value);
|
|
11704
11787
|
return result;
|
|
11705
11788
|
}
|
|
@@ -11724,17 +11807,17 @@ var ZodEffects = class extends ZodType {
|
|
|
11724
11807
|
if (inner.status === "aborted")
|
|
11725
11808
|
return INVALID;
|
|
11726
11809
|
if (inner.status === "dirty")
|
|
11727
|
-
|
|
11810
|
+
status2.dirty();
|
|
11728
11811
|
executeRefinement(inner.value);
|
|
11729
|
-
return { status:
|
|
11812
|
+
return { status: status2.value, value: inner.value };
|
|
11730
11813
|
} else {
|
|
11731
11814
|
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => {
|
|
11732
11815
|
if (inner.status === "aborted")
|
|
11733
11816
|
return INVALID;
|
|
11734
11817
|
if (inner.status === "dirty")
|
|
11735
|
-
|
|
11818
|
+
status2.dirty();
|
|
11736
11819
|
return executeRefinement(inner.value).then(() => {
|
|
11737
|
-
return { status:
|
|
11820
|
+
return { status: status2.value, value: inner.value };
|
|
11738
11821
|
});
|
|
11739
11822
|
});
|
|
11740
11823
|
}
|
|
@@ -11752,13 +11835,13 @@ var ZodEffects = class extends ZodType {
|
|
|
11752
11835
|
if (result instanceof Promise) {
|
|
11753
11836
|
throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
|
|
11754
11837
|
}
|
|
11755
|
-
return { status:
|
|
11838
|
+
return { status: status2.value, value: result };
|
|
11756
11839
|
} else {
|
|
11757
11840
|
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {
|
|
11758
11841
|
if (!isValid(base))
|
|
11759
11842
|
return INVALID;
|
|
11760
11843
|
return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
|
|
11761
|
-
status:
|
|
11844
|
+
status: status2.value,
|
|
11762
11845
|
value: result
|
|
11763
11846
|
}));
|
|
11764
11847
|
});
|
|
@@ -11936,7 +12019,7 @@ var ZodBranded = class extends ZodType {
|
|
|
11936
12019
|
};
|
|
11937
12020
|
var ZodPipeline = class _ZodPipeline extends ZodType {
|
|
11938
12021
|
_parse(input) {
|
|
11939
|
-
const { status, ctx } = this._processInputParams(input);
|
|
12022
|
+
const { status: status2, ctx } = this._processInputParams(input);
|
|
11940
12023
|
if (ctx.common.async) {
|
|
11941
12024
|
const handleAsync = async () => {
|
|
11942
12025
|
const inResult = await this._def.in._parseAsync({
|
|
@@ -11947,7 +12030,7 @@ var ZodPipeline = class _ZodPipeline extends ZodType {
|
|
|
11947
12030
|
if (inResult.status === "aborted")
|
|
11948
12031
|
return INVALID;
|
|
11949
12032
|
if (inResult.status === "dirty") {
|
|
11950
|
-
|
|
12033
|
+
status2.dirty();
|
|
11951
12034
|
return DIRTY(inResult.value);
|
|
11952
12035
|
} else {
|
|
11953
12036
|
return this._def.out._parseAsync({
|
|
@@ -11967,7 +12050,7 @@ var ZodPipeline = class _ZodPipeline extends ZodType {
|
|
|
11967
12050
|
if (inResult.status === "aborted")
|
|
11968
12051
|
return INVALID;
|
|
11969
12052
|
if (inResult.status === "dirty") {
|
|
11970
|
-
|
|
12053
|
+
status2.dirty();
|
|
11971
12054
|
return {
|
|
11972
12055
|
status: "dirty",
|
|
11973
12056
|
value: inResult.value
|
|
@@ -28324,8 +28407,8 @@ var UrlElicitationRequiredError = class extends McpError {
|
|
|
28324
28407
|
};
|
|
28325
28408
|
|
|
28326
28409
|
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
|
|
28327
|
-
function isTerminal(
|
|
28328
|
-
return
|
|
28410
|
+
function isTerminal(status2) {
|
|
28411
|
+
return status2 === "completed" || status2 === "failed" || status2 === "cancelled";
|
|
28329
28412
|
}
|
|
28330
28413
|
|
|
28331
28414
|
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.4.3/node_modules/zod-to-json-schema/dist/esm/Options.js
|
|
@@ -30544,8 +30627,8 @@ var Protocol = class {
|
|
|
30544
30627
|
}
|
|
30545
30628
|
return task;
|
|
30546
30629
|
},
|
|
30547
|
-
storeTaskResult: async (taskId,
|
|
30548
|
-
await taskStore.storeTaskResult(taskId,
|
|
30630
|
+
storeTaskResult: async (taskId, status2, result) => {
|
|
30631
|
+
await taskStore.storeTaskResult(taskId, status2, result, sessionId);
|
|
30549
30632
|
const task = await taskStore.getTask(taskId, sessionId);
|
|
30550
30633
|
if (task) {
|
|
30551
30634
|
const notification = TaskStatusNotificationSchema.parse({
|
|
@@ -30561,15 +30644,15 @@ var Protocol = class {
|
|
|
30561
30644
|
getTaskResult: (taskId) => {
|
|
30562
30645
|
return taskStore.getTaskResult(taskId, sessionId);
|
|
30563
30646
|
},
|
|
30564
|
-
updateTaskStatus: async (taskId,
|
|
30647
|
+
updateTaskStatus: async (taskId, status2, statusMessage) => {
|
|
30565
30648
|
const task = await taskStore.getTask(taskId, sessionId);
|
|
30566
30649
|
if (!task) {
|
|
30567
30650
|
throw new McpError(ErrorCode.InvalidParams, `Task "${taskId}" not found - it may have been cleaned up`);
|
|
30568
30651
|
}
|
|
30569
30652
|
if (isTerminal(task.status)) {
|
|
30570
|
-
throw new McpError(ErrorCode.InvalidParams, `Cannot update task "${taskId}" from terminal status "${task.status}" to "${
|
|
30653
|
+
throw new McpError(ErrorCode.InvalidParams, `Cannot update task "${taskId}" from terminal status "${task.status}" to "${status2}". Terminal states (completed, failed, cancelled) cannot transition to other states.`);
|
|
30571
30654
|
}
|
|
30572
|
-
await taskStore.updateTaskStatus(taskId,
|
|
30655
|
+
await taskStore.updateTaskStatus(taskId, status2, statusMessage, sessionId);
|
|
30573
30656
|
const updatedTask = await taskStore.getTask(taskId, sessionId);
|
|
30574
30657
|
if (updatedTask) {
|
|
30575
30658
|
const notification = TaskStatusNotificationSchema.parse({
|
|
@@ -32470,7 +32553,21 @@ function jsonResult(data) {
|
|
|
32470
32553
|
]
|
|
32471
32554
|
};
|
|
32472
32555
|
}
|
|
32473
|
-
function
|
|
32556
|
+
function expectedControlFlow(error51) {
|
|
32557
|
+
const message = error51 instanceof Error ? error51.message : "";
|
|
32558
|
+
return /^caveat not found:/.test(message) || /^community エントリは購読物/.test(message) || /^immutable frontmatter key:/.test(message);
|
|
32559
|
+
}
|
|
32560
|
+
function observeToolFailure(handler, productVersion = "0.0.0") {
|
|
32561
|
+
return async (args) => {
|
|
32562
|
+
try {
|
|
32563
|
+
return jsonResult(await handler(args));
|
|
32564
|
+
} catch (error51) {
|
|
32565
|
+
if (!expectedControlFlow(error51)) observeRuntimeError("CAVEAT.MCP_TOOL_FAILED", { version: productVersion });
|
|
32566
|
+
throw error51;
|
|
32567
|
+
}
|
|
32568
|
+
};
|
|
32569
|
+
}
|
|
32570
|
+
function registerAllTools(server, ctx, productVersion = "0.0.0") {
|
|
32474
32571
|
server.registerTool(
|
|
32475
32572
|
"caveat_search",
|
|
32476
32573
|
{
|
|
@@ -32478,7 +32575,7 @@ function registerAllTools(server, ctx) {
|
|
|
32478
32575
|
description: 'Search the "caveats" knowledge base \u2014 records of time-wasting traps someone already diagnosed, including external-spec issues (GPU/driver/CUDA versions, native-module builds, IDE/shell quirks, platform-specific behavior, library version incompatibilities) and reusable repo-specific context. Call this FIRST when a problem smells like a known trap \u2014 before reading stack traces top-to-bottom or trying fixes. Query: 3+ chars, plain tokens only (no OR/NEAR/other FTS5 operators). If it returns 0 hits, retry with synonyms and Japanese/English paraphrases. Returns summary rows including `{id, source}` \u2014 pass BOTH to caveat_get for the full body.',
|
|
32479
32576
|
inputSchema: searchInputShape
|
|
32480
32577
|
},
|
|
32481
|
-
|
|
32578
|
+
observeToolFailure((args) => handleSearch(ctx, args), productVersion)
|
|
32482
32579
|
);
|
|
32483
32580
|
server.registerTool(
|
|
32484
32581
|
"caveat_get",
|
|
@@ -32487,7 +32584,7 @@ function registerAllTools(server, ctx) {
|
|
|
32487
32584
|
description: 'Fetch the full body (frontmatter + H2 sections + text) of a caveat by id. IMPORTANT: when the id came from caveat_search, you MUST pass the `source` field from that same result (e.g., "community/Caveat"). The default source is "own" only; omitting source for a community entry returns not-found.',
|
|
32488
32585
|
inputSchema: getInputShape
|
|
32489
32586
|
},
|
|
32490
|
-
|
|
32587
|
+
observeToolFailure((args) => handleGet(ctx, args), productVersion)
|
|
32491
32588
|
);
|
|
32492
32589
|
server.registerTool(
|
|
32493
32590
|
"caveat_record",
|
|
@@ -32496,7 +32593,7 @@ function registerAllTools(server, ctx) {
|
|
|
32496
32593
|
description: "Create a new caveat: a reusable record of a time-wasting trap (wrong driver, version mismatch, platform bug, IDE quirk, native-module issue, or repo-specific context) so future sessions can find it via caveat_search. REQUIRED BEFORE CALLING: run caveat_search first to avoid duplicates. Set visibility using this binary criterion: `public` if a third party could reproduce it; `private` if it is repo/workflow-specific or depends on intentional local design; when unclear, prefer `private`; follow an explicit user visibility choice. Qualifies: specific symptom + diagnosed cause (or `outcome: impossible` verdict) + environment fingerprint. Does NOT qualify: ordinary project-internal logic bugs, user preferences, session summaries, or ephemeral task notes; reusable repo-specific traps may be `private`. Auto-fills source_session and environment defaults; source_project is left null by design (shared knowledge must not leak per-user project names).",
|
|
32497
32594
|
inputSchema: recordInputShape
|
|
32498
32595
|
},
|
|
32499
|
-
|
|
32596
|
+
observeToolFailure((args) => handleRecord(ctx, args), productVersion)
|
|
32500
32597
|
);
|
|
32501
32598
|
server.registerTool(
|
|
32502
32599
|
"caveat_update",
|
|
@@ -32505,7 +32602,7 @@ function registerAllTools(server, ctx) {
|
|
|
32505
32602
|
description: "Patch an existing caveat \u2014 use when newer evidence extends or corrects one that already exists. Frontmatter shallow-merges, but array fields (tags etc.) REPLACE rather than append \u2014 to add one tag, read the current list first, then patch with the full new array. Sections match by case-insensitive H2 heading. When changing `Symptom`, preserve raw errors verbatim and add stable Japanese/English symptom keywords when known; do not force or guess translations. Immutable keys: id, created_at, source_session, source_project. Common uses: bump `last_verified` after re-confirming, add a resolution when it was `tentative`, flip `outcome` to `impossible`.",
|
|
32506
32603
|
inputSchema: updateInputShape
|
|
32507
32604
|
},
|
|
32508
|
-
|
|
32605
|
+
observeToolFailure((args) => handleUpdate(ctx, args), productVersion)
|
|
32509
32606
|
);
|
|
32510
32607
|
server.registerTool(
|
|
32511
32608
|
"caveat_list_recent",
|
|
@@ -32514,7 +32611,7 @@ function registerAllTools(server, ctx) {
|
|
|
32514
32611
|
description: "List caveats ordered by updated_at DESC. Use for browsing recent additions \u2014 e.g., showing the user what is new after caveat_pull. Not for search; use caveat_search when you have a query.",
|
|
32515
32612
|
inputSchema: listRecentInputShape
|
|
32516
32613
|
},
|
|
32517
|
-
|
|
32614
|
+
observeToolFailure((args) => handleListRecent(ctx, args), productVersion)
|
|
32518
32615
|
);
|
|
32519
32616
|
server.registerTool(
|
|
32520
32617
|
"caveat_pull",
|
|
@@ -32523,7 +32620,7 @@ function registerAllTools(server, ctx) {
|
|
|
32523
32620
|
description: "git-pull every subscribed community caveat repo (added via `caveat community add`) and re-index. Call when: (a) the user explicitly asks about others' knowledge on a topic, or (b) caveat_search returned empty for a query that feels like it should have hits and a subscribed repo might be stale. Do NOT call reflexively at session start \u2014 it is cheap but not free, and stale-by-minutes is acceptable. Safe and idempotent.",
|
|
32524
32621
|
inputSchema: pullInputShape
|
|
32525
32622
|
},
|
|
32526
|
-
|
|
32623
|
+
observeToolFailure((args) => handlePull(ctx, args), productVersion)
|
|
32527
32624
|
);
|
|
32528
32625
|
}
|
|
32529
32626
|
|
|
@@ -32534,7 +32631,7 @@ async function startMcpStdioServer(overrides = {}) {
|
|
|
32534
32631
|
{ name: "caveat", version: "0.0.0" },
|
|
32535
32632
|
{ capabilities: { tools: {} } }
|
|
32536
32633
|
);
|
|
32537
|
-
registerAllTools(server, ctx);
|
|
32634
|
+
registerAllTools(server, ctx, overrides.productVersion);
|
|
32538
32635
|
const transport = new StdioServerTransport();
|
|
32539
32636
|
await server.connect(transport);
|
|
32540
32637
|
const shutdown = () => {
|
|
@@ -32560,7 +32657,12 @@ if (invokedPath && thisPath && invokedPath.toLowerCase() === thisPath.toLowerCas
|
|
|
32560
32657
|
|
|
32561
32658
|
// src/commands/mcpServer.ts
|
|
32562
32659
|
async function runMcpServer() {
|
|
32563
|
-
|
|
32660
|
+
try {
|
|
32661
|
+
await startMcpStdioServer({ productVersion: CAVEAT_VERSION });
|
|
32662
|
+
} catch (error51) {
|
|
32663
|
+
observeRuntimeError("CAVEAT.MCP_SERVER_FAILED", { version: CAVEAT_VERSION });
|
|
32664
|
+
throw error51;
|
|
32665
|
+
}
|
|
32564
32666
|
}
|
|
32565
32667
|
|
|
32566
32668
|
// src/commands/hookCmd.ts
|
|
@@ -32573,7 +32675,7 @@ import {
|
|
|
32573
32675
|
mkdirSync as mkdirSync5,
|
|
32574
32676
|
readdirSync as readdirSync2,
|
|
32575
32677
|
readFileSync as readFileSync5,
|
|
32576
|
-
realpathSync as
|
|
32678
|
+
realpathSync as realpathSync4,
|
|
32577
32679
|
rmSync as rmSync2,
|
|
32578
32680
|
writeFileSync as writeFileSync5
|
|
32579
32681
|
} from "node:fs";
|
|
@@ -32606,14 +32708,14 @@ function maybeTriggerAutoReindex(ctx) {
|
|
|
32606
32708
|
|
|
32607
32709
|
// src/autoSyncTrigger.ts
|
|
32608
32710
|
import { spawn as spawn2 } from "node:child_process";
|
|
32609
|
-
import { existsSync as existsSync9, statSync } from "node:fs";
|
|
32711
|
+
import { existsSync as existsSync9, statSync as statSync3 } from "node:fs";
|
|
32610
32712
|
import { join as join11 } from "node:path";
|
|
32611
32713
|
function maybeTriggerAutoSync(ctx) {
|
|
32612
32714
|
if (process.env[CAVEAT_AUTO_SYNC_ENV] === "off") return;
|
|
32613
32715
|
const statePath = join11(ctx.caveatHome, "sync", ".last-autosync.json");
|
|
32614
32716
|
const debounceMs = Number(process.env.CAVEAT_AUTO_SYNC_DEBOUNCE_MS ?? AUTO_SYNC_DEBOUNCE_MS);
|
|
32615
32717
|
try {
|
|
32616
|
-
if (existsSync9(statePath) && Date.now() -
|
|
32718
|
+
if (existsSync9(statePath) && Date.now() - statSync3(statePath).mtimeMs < debounceMs) return;
|
|
32617
32719
|
} catch {
|
|
32618
32720
|
}
|
|
32619
32721
|
const cliScript = process.argv[1];
|
|
@@ -32650,6 +32752,7 @@ function parsePayload(raw) {
|
|
|
32650
32752
|
try {
|
|
32651
32753
|
return JSON.parse(raw);
|
|
32652
32754
|
} catch (err) {
|
|
32755
|
+
observeRuntimeError("CAVEAT.CLAUDE_HOOK_FAILED", { version: CAVEAT_VERSION });
|
|
32653
32756
|
const msg = err instanceof Error ? err.message : String(err);
|
|
32654
32757
|
process.stderr.write(`[caveat:hook] json parse error: ${msg}
|
|
32655
32758
|
`);
|
|
@@ -32664,14 +32767,17 @@ function buildContextSafely() {
|
|
|
32664
32767
|
try {
|
|
32665
32768
|
return buildContext(silentLogger);
|
|
32666
32769
|
} catch (err) {
|
|
32770
|
+
observeRuntimeError("CAVEAT.CLAUDE_HOOK_FAILED", { version: CAVEAT_VERSION });
|
|
32667
32771
|
const msg = err instanceof Error ? err.message : String(err);
|
|
32668
32772
|
process.stderr.write(`[caveat:hook] context error: ${msg}
|
|
32669
32773
|
`);
|
|
32670
32774
|
return null;
|
|
32671
32775
|
}
|
|
32672
32776
|
}
|
|
32673
|
-
function
|
|
32674
|
-
|
|
32777
|
+
function searchCaveatsSafely(input) {
|
|
32778
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
32779
|
+
const queryForLog = inputs.map((item) => item.surface === "user_prompt" ? item.topicText || item.failureText : item.failureText).filter(Boolean).join("\n");
|
|
32780
|
+
if (inputs.length === 0 || inputs.every((item) => !item.topicText && !item.failureText)) return [];
|
|
32675
32781
|
let db;
|
|
32676
32782
|
let caveatHome;
|
|
32677
32783
|
let hits;
|
|
@@ -32680,10 +32786,12 @@ function searchCaveatsFromTextSafely(text, surface) {
|
|
|
32680
32786
|
if (!ctx || !existsSync10(ctx.paths.dbPath)) return [];
|
|
32681
32787
|
caveatHome = ctx.caveatHome;
|
|
32682
32788
|
db = openDb({ path: ctx.paths.dbPath });
|
|
32683
|
-
|
|
32789
|
+
const searchOptions = {
|
|
32684
32790
|
selfIdentity: defaultSelfIdentityTokens()
|
|
32685
|
-
}
|
|
32791
|
+
};
|
|
32792
|
+
hits = inputs.length === 1 ? findCaveatsForHook(db, inputs[0], searchOptions) : findCaveatsForHookSegments(db, inputs, searchOptions);
|
|
32686
32793
|
} catch (err) {
|
|
32794
|
+
observeRuntimeError("CAVEAT.CLAUDE_HOOK_FAILED", { version: CAVEAT_VERSION });
|
|
32687
32795
|
const msg = err instanceof Error ? err.message : String(err);
|
|
32688
32796
|
process.stderr.write(`[caveat:hook] search error: ${msg}
|
|
32689
32797
|
`);
|
|
@@ -32693,14 +32801,16 @@ function searchCaveatsFromTextSafely(text, surface) {
|
|
|
32693
32801
|
try {
|
|
32694
32802
|
markHit(db, hits);
|
|
32695
32803
|
} catch (err) {
|
|
32804
|
+
observeRuntimeError("CAVEAT.CLAUDE_HOOK_FAILED", { version: CAVEAT_VERSION });
|
|
32696
32805
|
const msg = err instanceof Error ? err.message : String(err);
|
|
32697
32806
|
process.stderr.write(`[caveat:hook] markHit error: ${msg}
|
|
32698
32807
|
`);
|
|
32699
32808
|
}
|
|
32700
32809
|
} else {
|
|
32701
32810
|
try {
|
|
32702
|
-
logHookQueryMiss({ caveatHome, agent: "claude", surface, query:
|
|
32811
|
+
logHookQueryMiss({ caveatHome, agent: "claude", surface: inputs[0].surface, query: queryForLog });
|
|
32703
32812
|
} catch (err) {
|
|
32813
|
+
observeRuntimeError("CAVEAT.CLAUDE_HOOK_FAILED", { version: CAVEAT_VERSION });
|
|
32704
32814
|
const msg = err instanceof Error ? err.message : String(err);
|
|
32705
32815
|
process.stderr.write(`[caveat:hook] query log error: ${msg}
|
|
32706
32816
|
`);
|
|
@@ -32725,13 +32835,19 @@ function loadSignalsSafely(path) {
|
|
|
32725
32835
|
function systemReminderOutput(text) {
|
|
32726
32836
|
return `<system-reminder>${text.replace(/</g, "\u2039").replace(/>/g, "\u203A")}</system-reminder>`;
|
|
32727
32837
|
}
|
|
32838
|
+
function claudePendingCleanupFailureText() {
|
|
32839
|
+
return "[caveat:hook] pending reminder cleanup failed";
|
|
32840
|
+
}
|
|
32728
32841
|
function drainForSession(sessionId) {
|
|
32729
32842
|
const ctx = buildContextSafely();
|
|
32730
32843
|
if (!ctx) return [];
|
|
32731
|
-
|
|
32732
|
-
|
|
32733
|
-
|
|
32734
|
-
|
|
32844
|
+
const local = drainPendingRemindersDetailed(ctx.caveatHome, sessionId);
|
|
32845
|
+
const global = drainPendingRemindersDetailed(ctx.caveatHome, "_global");
|
|
32846
|
+
for (const _failure of [...local.cleanupFailures, ...global.cleanupFailures]) {
|
|
32847
|
+
process.stderr.write(`${claudePendingCleanupFailureText()}
|
|
32848
|
+
`);
|
|
32849
|
+
}
|
|
32850
|
+
return [...local.reminders, ...global.reminders];
|
|
32735
32851
|
}
|
|
32736
32852
|
function claudeContextDedupeKey(text) {
|
|
32737
32853
|
if (text.startsWith(CLAUDE_STOP_REMINDER_PREFIX)) return "claude-stop-reminder";
|
|
@@ -32750,7 +32866,7 @@ function compactClaudeContexts(contexts) {
|
|
|
32750
32866
|
}
|
|
32751
32867
|
selected.reverse();
|
|
32752
32868
|
const limited = selected.slice(-CLAUDE_MAX_CONTEXT_BLOCKS);
|
|
32753
|
-
const omitted =
|
|
32869
|
+
const omitted = selected.length - limited.length;
|
|
32754
32870
|
if (omitted > 0) {
|
|
32755
32871
|
limited.push(
|
|
32756
32872
|
`[caveat] pending reminder ${omitted} \u4EF6\u3092\u91CD\u8907\u307E\u305F\u306F\u4E0A\u9650\u306B\u3088\u308A\u7701\u7565\u3057\u307E\u3057\u305F\u3002`
|
|
@@ -32795,8 +32911,20 @@ function queueStopForSession(sessionId, signals, related) {
|
|
|
32795
32911
|
if (!ctx) return;
|
|
32796
32912
|
const key = stopSignalKey(signals, related);
|
|
32797
32913
|
if (wasStopReminderQueued(ctx.caveatHome, sessionId, key)) return;
|
|
32914
|
+
let result;
|
|
32915
|
+
try {
|
|
32916
|
+
result = buildAndPublishPendingReminder(ctx.caveatHome, sessionId, buildPendingSemanticKey({
|
|
32917
|
+
agent: "claude",
|
|
32918
|
+
surface: "stop",
|
|
32919
|
+
refs: related,
|
|
32920
|
+
stopSignalDigest: key
|
|
32921
|
+
}), () => buildStopReminder(signals, related));
|
|
32922
|
+
} catch {
|
|
32923
|
+
process.stderr.write("[caveat:hook] pending reminder build or publish failed\n");
|
|
32924
|
+
return;
|
|
32925
|
+
}
|
|
32926
|
+
if (!result.ran) return;
|
|
32798
32927
|
try {
|
|
32799
|
-
appendPendingReminder(ctx.caveatHome, sessionId, buildStopReminder(signals, related));
|
|
32800
32928
|
markStopReminderQueued(ctx.caveatHome, sessionId, key);
|
|
32801
32929
|
} catch (err) {
|
|
32802
32930
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -32827,6 +32955,20 @@ function extractToolResponseText(response) {
|
|
|
32827
32955
|
}
|
|
32828
32956
|
return "";
|
|
32829
32957
|
}
|
|
32958
|
+
function toolTopicText(payload) {
|
|
32959
|
+
const parts = [];
|
|
32960
|
+
const toolName = payload.tool_name ?? payload.toolName;
|
|
32961
|
+
if (typeof toolName === "string") parts.push(toolName);
|
|
32962
|
+
const input = payload.tool_input ?? payload.toolInput;
|
|
32963
|
+
if (typeof input === "string") parts.push(input);
|
|
32964
|
+
if (input !== null && typeof input === "object" && !Array.isArray(input)) {
|
|
32965
|
+
const record2 = input;
|
|
32966
|
+
for (const key of ["command", "cmd", "query", "url"]) {
|
|
32967
|
+
if (typeof record2[key] === "string") parts.push(record2[key]);
|
|
32968
|
+
}
|
|
32969
|
+
}
|
|
32970
|
+
return parts.join("\n");
|
|
32971
|
+
}
|
|
32830
32972
|
function isToolError(payload) {
|
|
32831
32973
|
if (payload.hook_event_name === "PostToolUseFailure") return true;
|
|
32832
32974
|
const resp = payload.tool_response ?? payload.toolResponse;
|
|
@@ -32850,7 +32992,7 @@ function spawnWorker(job) {
|
|
|
32850
32992
|
workDir = mkdtempSync2(join12(root, "job-"));
|
|
32851
32993
|
chmodSync(workDir, 448);
|
|
32852
32994
|
workFile = join12(workDir, `${randomBytes(4).toString("hex")}.json`);
|
|
32853
|
-
writeFileSync5(workFile, JSON.stringify({ ...job, schemaVersion: "caveat-worker-job/
|
|
32995
|
+
writeFileSync5(workFile, JSON.stringify({ ...job, schemaVersion: "caveat-worker-job/v2" }), { encoding: "utf-8", mode: 384, flag: "wx" });
|
|
32854
32996
|
} catch (err) {
|
|
32855
32997
|
const msg = err instanceof Error ? err.message : String(err);
|
|
32856
32998
|
process.stderr.write(`[caveat:hook] worker writefile error: ${msg}
|
|
@@ -32894,15 +33036,27 @@ async function runWorker(workFile) {
|
|
|
32894
33036
|
} catch {
|
|
32895
33037
|
process.exit(0);
|
|
32896
33038
|
}
|
|
32897
|
-
if (!job.
|
|
32898
|
-
const hits =
|
|
33039
|
+
if (!job.failureText || !job.sessionId) process.exit(0);
|
|
33040
|
+
const hits = searchCaveatsSafely({
|
|
33041
|
+
topicText: job.topicText,
|
|
33042
|
+
failureText: job.failureText,
|
|
33043
|
+
surface: "tool_error"
|
|
33044
|
+
});
|
|
32899
33045
|
if (hits.length === 0) process.exit(0);
|
|
32900
33046
|
const ctx = buildContextSafely();
|
|
32901
33047
|
if (!ctx) process.exit(0);
|
|
33048
|
+
let result;
|
|
32902
33049
|
try {
|
|
32903
|
-
|
|
33050
|
+
result = buildAndPublishPendingReminder(ctx.caveatHome, job.sessionId, buildPendingSemanticKey({
|
|
33051
|
+
agent: "claude",
|
|
33052
|
+
surface: "tool_error",
|
|
33053
|
+
refs: hits
|
|
33054
|
+
}), () => buildToolErrorReminder(job, hits));
|
|
32904
33055
|
} catch {
|
|
33056
|
+
process.stderr.write("[caveat:hook] pending reminder build or publish failed\n");
|
|
33057
|
+
process.exit(0);
|
|
32905
33058
|
}
|
|
33059
|
+
if (!result.ran) process.exit(0);
|
|
32906
33060
|
process.exit(0);
|
|
32907
33061
|
}
|
|
32908
33062
|
function cleanupWorkerDir(workDir, root) {
|
|
@@ -32916,8 +33070,8 @@ function isOwnedWorkerDir(path, root = workerRoot()) {
|
|
|
32916
33070
|
try {
|
|
32917
33071
|
const inputStat = lstatSync(path);
|
|
32918
33072
|
if (inputStat.isSymbolicLink()) return false;
|
|
32919
|
-
const tmpRoot =
|
|
32920
|
-
const resolved =
|
|
33073
|
+
const tmpRoot = realpathSync4(root);
|
|
33074
|
+
const resolved = realpathSync4(path);
|
|
32921
33075
|
const stat = lstatSync(resolved);
|
|
32922
33076
|
const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
|
|
32923
33077
|
return dirname6(resolved) === tmpRoot && basename(resolved).startsWith("job-") && stat.isDirectory() && !stat.isSymbolicLink() && hasPrivateOwnership(stat, uid);
|
|
@@ -32969,12 +33123,20 @@ function isStaleWorkerJobDir(path) {
|
|
|
32969
33123
|
const stat = lstatSync(file2);
|
|
32970
33124
|
const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
|
|
32971
33125
|
if (!stat.isFile() || stat.isSymbolicLink() || !hasPrivateOwnership(stat, uid)) return false;
|
|
32972
|
-
return
|
|
33126
|
+
return isKnownStaleWorkerJob(JSON.parse(readFileSync5(file2, "utf-8")));
|
|
32973
33127
|
}
|
|
32974
33128
|
function hasPrivateOwnership(stat, uid) {
|
|
32975
33129
|
return process.platform === "win32" || (stat.mode & 63) === 0 && (uid === void 0 || stat.uid === uid);
|
|
32976
33130
|
}
|
|
32977
33131
|
function isWorkerJob(value) {
|
|
33132
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
33133
|
+
const job = value;
|
|
33134
|
+
const keys = Object.keys(job).sort();
|
|
33135
|
+
if (!(keys.length === 4 && keys.join(",") === "failureText,schemaVersion,sessionId,topicText") && !(keys.length === 5 && keys.join(",") === "additionalContext,failureText,schemaVersion,sessionId,topicText")) return false;
|
|
33136
|
+
return job.schemaVersion === "caveat-worker-job/v2" && typeof job.sessionId === "string" && typeof job.topicText === "string" && typeof job.failureText === "string" && (job.additionalContext === void 0 || job.additionalContext !== null && typeof job.additionalContext === "object" && !Array.isArray(job.additionalContext));
|
|
33137
|
+
}
|
|
33138
|
+
function isKnownStaleWorkerJob(value) {
|
|
33139
|
+
if (isWorkerJob(value)) return true;
|
|
32978
33140
|
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
32979
33141
|
const job = value;
|
|
32980
33142
|
const keys = Object.keys(job).sort();
|
|
@@ -33070,7 +33232,7 @@ function buildToolErrorReminder(job, hits) {
|
|
|
33070
33232
|
const hasSidecarConfig = existsSync10(join12(projectRoot, ".codex-sidecar.yml"));
|
|
33071
33233
|
if (mode === "auto" && !hasSidecarConfig) return base;
|
|
33072
33234
|
const advisory = runCodexSidecarAdvisory({
|
|
33073
|
-
searchText: job.
|
|
33235
|
+
searchText: job.failureText,
|
|
33074
33236
|
limit: hits.length,
|
|
33075
33237
|
projectRoot,
|
|
33076
33238
|
prompt: [
|
|
@@ -33170,7 +33332,7 @@ async function runHook(name, arg) {
|
|
|
33170
33332
|
const contexts = name === "stop" ? [] : drainForSession(sessionId);
|
|
33171
33333
|
if (name === "user-prompt-submit") {
|
|
33172
33334
|
const prompt = typeof payload.prompt === "string" ? payload.prompt : "";
|
|
33173
|
-
const hits =
|
|
33335
|
+
const hits = searchCaveatsSafely({ topicText: prompt, failureText: prompt, surface: "user_prompt" });
|
|
33174
33336
|
if (hits.length > 0) {
|
|
33175
33337
|
contexts.push(userPromptSubmitReminderText(hits));
|
|
33176
33338
|
}
|
|
@@ -33198,7 +33360,8 @@ async function runHook(name, arg) {
|
|
|
33198
33360
|
toolName: payload.tool_name ?? payload.toolName,
|
|
33199
33361
|
failureKind
|
|
33200
33362
|
});
|
|
33201
|
-
|
|
33363
|
+
const topicText = toolTopicText(payload);
|
|
33364
|
+
spawnWorker({ sessionId, topicText, failureText: errText, ...additionalContext ? { additionalContext } : {} });
|
|
33202
33365
|
}
|
|
33203
33366
|
process.exit(0);
|
|
33204
33367
|
}
|
|
@@ -33231,7 +33394,11 @@ async function runHook(name, arg) {
|
|
|
33231
33394
|
const transcriptPath = typeof payload.transcript_path === "string" ? payload.transcript_path : "";
|
|
33232
33395
|
const signals = transcriptPath ? loadSignalsSafely(transcriptPath) : null;
|
|
33233
33396
|
if (!signals || !hasAnyStruggleSignal(signals)) process.exit(0);
|
|
33234
|
-
const related =
|
|
33397
|
+
const related = searchCaveatsSafely(signals.errorSnippets.map((failureText) => ({
|
|
33398
|
+
topicText: "",
|
|
33399
|
+
failureText,
|
|
33400
|
+
surface: "stop"
|
|
33401
|
+
})));
|
|
33235
33402
|
queueStopForSession(sessionId, signals, related);
|
|
33236
33403
|
process.exit(0);
|
|
33237
33404
|
}
|
|
@@ -33269,6 +33436,7 @@ function parsePayload2(raw) {
|
|
|
33269
33436
|
try {
|
|
33270
33437
|
return JSON.parse(raw);
|
|
33271
33438
|
} catch (err) {
|
|
33439
|
+
observeRuntimeError("CAVEAT.CODEX_HOOK_FAILED", { version: CAVEAT_VERSION });
|
|
33272
33440
|
const msg = err instanceof Error ? err.message : String(err);
|
|
33273
33441
|
process.stderr.write(`[caveat:codex-hook] json parse error: ${msg}
|
|
33274
33442
|
`);
|
|
@@ -33279,14 +33447,17 @@ function buildContextSafely2() {
|
|
|
33279
33447
|
try {
|
|
33280
33448
|
return buildContext(silentLogger2);
|
|
33281
33449
|
} catch (err) {
|
|
33450
|
+
observeRuntimeError("CAVEAT.CODEX_HOOK_FAILED", { version: CAVEAT_VERSION });
|
|
33282
33451
|
const msg = err instanceof Error ? err.message : String(err);
|
|
33283
33452
|
process.stderr.write(`[caveat:codex-hook] context error: ${msg}
|
|
33284
33453
|
`);
|
|
33285
33454
|
return null;
|
|
33286
33455
|
}
|
|
33287
33456
|
}
|
|
33288
|
-
function
|
|
33289
|
-
|
|
33457
|
+
function searchCaveatsSafely2(input) {
|
|
33458
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
33459
|
+
const queryForLog = inputs.map((item) => item.surface === "user_prompt" ? item.topicText || item.failureText : item.failureText).filter(Boolean).join("\n");
|
|
33460
|
+
if (inputs.length === 0 || inputs.every((item) => !item.topicText && !item.failureText)) return [];
|
|
33290
33461
|
let db;
|
|
33291
33462
|
let caveatHome;
|
|
33292
33463
|
let hits;
|
|
@@ -33295,10 +33466,12 @@ function searchCaveatsFromTextSafely2(text, surface) {
|
|
|
33295
33466
|
if (!ctx || !existsSync11(ctx.paths.dbPath)) return [];
|
|
33296
33467
|
caveatHome = ctx.caveatHome;
|
|
33297
33468
|
db = openDb({ path: ctx.paths.dbPath });
|
|
33298
|
-
|
|
33469
|
+
const searchOptions = {
|
|
33299
33470
|
selfIdentity: defaultSelfIdentityTokens()
|
|
33300
|
-
}
|
|
33471
|
+
};
|
|
33472
|
+
hits = inputs.length === 1 ? findCaveatsForHook(db, inputs[0], searchOptions) : findCaveatsForHookSegments(db, inputs, searchOptions);
|
|
33301
33473
|
} catch (err) {
|
|
33474
|
+
observeRuntimeError("CAVEAT.CODEX_HOOK_FAILED", { version: CAVEAT_VERSION });
|
|
33302
33475
|
const msg = err instanceof Error ? err.message : String(err);
|
|
33303
33476
|
process.stderr.write(`[caveat:codex-hook] search error: ${msg}
|
|
33304
33477
|
`);
|
|
@@ -33308,14 +33481,16 @@ function searchCaveatsFromTextSafely2(text, surface) {
|
|
|
33308
33481
|
try {
|
|
33309
33482
|
markHit(db, hits);
|
|
33310
33483
|
} catch (err) {
|
|
33484
|
+
observeRuntimeError("CAVEAT.CODEX_HOOK_FAILED", { version: CAVEAT_VERSION });
|
|
33311
33485
|
const msg = err instanceof Error ? err.message : String(err);
|
|
33312
33486
|
process.stderr.write(`[caveat:codex-hook] markHit error: ${msg}
|
|
33313
33487
|
`);
|
|
33314
33488
|
}
|
|
33315
33489
|
} else {
|
|
33316
33490
|
try {
|
|
33317
|
-
logHookQueryMiss({ caveatHome, agent: "codex", surface, query:
|
|
33491
|
+
logHookQueryMiss({ caveatHome, agent: "codex", surface: inputs[0].surface, query: queryForLog });
|
|
33318
33492
|
} catch (err) {
|
|
33493
|
+
observeRuntimeError("CAVEAT.CODEX_HOOK_FAILED", { version: CAVEAT_VERSION });
|
|
33319
33494
|
const msg = err instanceof Error ? err.message : String(err);
|
|
33320
33495
|
process.stderr.write(`[caveat:codex-hook] query log error: ${msg}
|
|
33321
33496
|
`);
|
|
@@ -33443,15 +33618,17 @@ function buildCodexPostToolUseWorkerJob(payload) {
|
|
|
33443
33618
|
const responseText = extractToolResponseText2(payload.tool_response ?? payload.toolResponse);
|
|
33444
33619
|
const inputText = toolInputText(payload.tool_input);
|
|
33445
33620
|
const transcriptOutput = transcriptPath && toolUseId ? transcriptToolOutput(transcriptPath, toolUseId) : null;
|
|
33446
|
-
const
|
|
33621
|
+
const topicText = inputText.trim();
|
|
33622
|
+
const failureText = [responseText, transcriptOutput ?? ""].map((s) => s.trim()).filter(Boolean).join("\n");
|
|
33447
33623
|
const knownError = isCodexToolError(payload);
|
|
33448
33624
|
if (knownError) {
|
|
33449
|
-
return { sessionId,
|
|
33625
|
+
return { sessionId, topicText, failureText, knownError: true, transcriptPath, toolUseId };
|
|
33450
33626
|
}
|
|
33451
|
-
if (transcriptPath && toolUseId && isShellLikeTool(payload) &&
|
|
33627
|
+
if (transcriptPath && toolUseId && isShellLikeTool(payload) && (topicText || failureText)) {
|
|
33452
33628
|
return {
|
|
33453
33629
|
sessionId,
|
|
33454
|
-
|
|
33630
|
+
topicText,
|
|
33631
|
+
failureText,
|
|
33455
33632
|
knownError: false,
|
|
33456
33633
|
allowSymptomOnly: true,
|
|
33457
33634
|
transcriptPath,
|
|
@@ -33468,13 +33645,19 @@ function codexContextOutput(text, eventName = "UserPromptSubmit") {
|
|
|
33468
33645
|
}
|
|
33469
33646
|
});
|
|
33470
33647
|
}
|
|
33648
|
+
function codexPendingCleanupFailureText() {
|
|
33649
|
+
return "[caveat:codex-hook] pending reminder cleanup failed";
|
|
33650
|
+
}
|
|
33471
33651
|
function drainForSession2(sessionId) {
|
|
33472
33652
|
const ctx = buildContextSafely2();
|
|
33473
33653
|
if (!ctx) return [];
|
|
33474
|
-
|
|
33475
|
-
|
|
33476
|
-
|
|
33477
|
-
|
|
33654
|
+
const local = drainPendingRemindersDetailed(ctx.caveatHome, sessionId);
|
|
33655
|
+
const global = drainPendingRemindersDetailed(ctx.caveatHome, "_global");
|
|
33656
|
+
for (const _failure of [...local.cleanupFailures, ...global.cleanupFailures]) {
|
|
33657
|
+
process.stderr.write(`${codexPendingCleanupFailureText()}
|
|
33658
|
+
`);
|
|
33659
|
+
}
|
|
33660
|
+
return [...local.reminders, ...global.reminders];
|
|
33478
33661
|
}
|
|
33479
33662
|
function codexContextDedupeKey(text) {
|
|
33480
33663
|
if (text.startsWith(CODEX_STOP_REMINDER_PREFIX)) return "codex-stop-reminder";
|
|
@@ -33493,7 +33676,7 @@ function compactCodexContexts(contexts) {
|
|
|
33493
33676
|
}
|
|
33494
33677
|
selected.reverse();
|
|
33495
33678
|
const limited = selected.slice(-CODEX_MAX_CONTEXT_BLOCKS);
|
|
33496
|
-
const omitted =
|
|
33679
|
+
const omitted = selected.length - limited.length;
|
|
33497
33680
|
if (omitted > 0) {
|
|
33498
33681
|
limited.push(`[caveat] pending reminder ${omitted} \u4EF6\u3092\u91CD\u8907\u307E\u305F\u306F\u4E0A\u9650\u306B\u3088\u308A\u7701\u7565\u3057\u307E\u3057\u305F\u3002`);
|
|
33499
33682
|
}
|
|
@@ -33536,8 +33719,20 @@ function queueStopForSession2(sessionId, signals, related) {
|
|
|
33536
33719
|
if (!ctx) return;
|
|
33537
33720
|
const key = stopSignalKey2(signals, related);
|
|
33538
33721
|
if (wasStopReminderQueued2(ctx.caveatHome, sessionId, key)) return;
|
|
33722
|
+
let result;
|
|
33723
|
+
try {
|
|
33724
|
+
result = buildAndPublishPendingReminder(ctx.caveatHome, sessionId, buildPendingSemanticKey({
|
|
33725
|
+
agent: "codex",
|
|
33726
|
+
surface: "stop",
|
|
33727
|
+
refs: related,
|
|
33728
|
+
stopSignalDigest: key
|
|
33729
|
+
}), () => stopReminderText(signals, related));
|
|
33730
|
+
} catch {
|
|
33731
|
+
process.stderr.write("[caveat:codex-hook] pending reminder build or publish failed\n");
|
|
33732
|
+
return;
|
|
33733
|
+
}
|
|
33734
|
+
if (!result.ran) return;
|
|
33539
33735
|
try {
|
|
33540
|
-
appendPendingReminder(ctx.caveatHome, sessionId, stopReminderText(signals, related));
|
|
33541
33736
|
markStopReminderQueued2(ctx.caveatHome, sessionId, key);
|
|
33542
33737
|
} catch (err) {
|
|
33543
33738
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -33555,8 +33750,8 @@ async function waitForTranscriptOutput(transcriptPath, toolUseId) {
|
|
|
33555
33750
|
return null;
|
|
33556
33751
|
}
|
|
33557
33752
|
async function processCodexWorkerJob(job, opts = { waitForTranscript: true }) {
|
|
33558
|
-
if (!job.
|
|
33559
|
-
let
|
|
33753
|
+
if (!job.topicText && !job.failureText || !job.sessionId) return;
|
|
33754
|
+
let failureText = job.failureText;
|
|
33560
33755
|
let knownError = job.knownError === true;
|
|
33561
33756
|
if (opts.waitForTranscript && job.transcriptPath && job.toolUseId) {
|
|
33562
33757
|
const transcriptOutput = await waitForTranscriptOutput(job.transcriptPath, job.toolUseId);
|
|
@@ -33566,18 +33761,30 @@ async function processCodexWorkerJob(job, opts = { waitForTranscript: true }) {
|
|
|
33566
33761
|
if (exit2 === 0) return;
|
|
33567
33762
|
knownError = true;
|
|
33568
33763
|
}
|
|
33569
|
-
|
|
33764
|
+
failureText = [failureText, transcriptOutput].filter(Boolean).join("\n");
|
|
33570
33765
|
}
|
|
33571
33766
|
}
|
|
33572
33767
|
if (!knownError && job.allowSymptomOnly !== true) return;
|
|
33573
|
-
const hits =
|
|
33768
|
+
const hits = searchCaveatsSafely2({
|
|
33769
|
+
topicText: job.topicText,
|
|
33770
|
+
failureText,
|
|
33771
|
+
surface: "tool_error"
|
|
33772
|
+
});
|
|
33574
33773
|
if (hits.length === 0) return;
|
|
33575
33774
|
const ctx = buildContextSafely2();
|
|
33576
33775
|
if (!ctx) return;
|
|
33776
|
+
let result;
|
|
33577
33777
|
try {
|
|
33578
|
-
|
|
33778
|
+
result = buildAndPublishPendingReminder(ctx.caveatHome, job.sessionId, buildPendingSemanticKey({
|
|
33779
|
+
agent: "codex",
|
|
33780
|
+
surface: "tool_error",
|
|
33781
|
+
refs: hits
|
|
33782
|
+
}), () => toolErrorReminderText(hits));
|
|
33579
33783
|
} catch {
|
|
33784
|
+
process.stderr.write("[caveat:codex-hook] pending reminder build or publish failed\n");
|
|
33785
|
+
return;
|
|
33580
33786
|
}
|
|
33787
|
+
if (!result.ran) return;
|
|
33581
33788
|
}
|
|
33582
33789
|
async function runCodexWorker(workFile) {
|
|
33583
33790
|
let raw;
|
|
@@ -33649,7 +33856,7 @@ async function runCodexHook(name, arg) {
|
|
|
33649
33856
|
if (name === "user-prompt-submit") {
|
|
33650
33857
|
const contexts = sessionId ? drainForSession2(sessionId) : [];
|
|
33651
33858
|
const prompt = typeof payload.prompt === "string" ? payload.prompt : "";
|
|
33652
|
-
const hits =
|
|
33859
|
+
const hits = searchCaveatsSafely2({ topicText: prompt, failureText: prompt, surface: "user_prompt" });
|
|
33653
33860
|
if (hits.length > 0) {
|
|
33654
33861
|
contexts.push(userPromptSubmitReminderText(hits));
|
|
33655
33862
|
}
|
|
@@ -33694,7 +33901,11 @@ async function runCodexHook(name, arg) {
|
|
|
33694
33901
|
const transcriptPath = typeof payload.transcript_path === "string" ? payload.transcript_path : "";
|
|
33695
33902
|
const signals = transcriptPath ? loadSignalsSafely2(transcriptPath) : null;
|
|
33696
33903
|
if (!signals || !hasAnyStruggleSignal(signals)) process.exit(0);
|
|
33697
|
-
const related =
|
|
33904
|
+
const related = searchCaveatsSafely2(signals.errorSnippets.map((failureText) => ({
|
|
33905
|
+
topicText: "",
|
|
33906
|
+
failureText,
|
|
33907
|
+
surface: "stop"
|
|
33908
|
+
})));
|
|
33698
33909
|
if (sessionId) queueStopForSession2(sessionId, signals, related);
|
|
33699
33910
|
process.exit(0);
|
|
33700
33911
|
}
|
|
@@ -33751,6 +33962,11 @@ async function defaultPrivateRepoUrl(opts, deps) {
|
|
|
33751
33962
|
});
|
|
33752
33963
|
}
|
|
33753
33964
|
async function runSync(ctx, opts, dependencies = {}) {
|
|
33965
|
+
if (opts.repo && (opts.init === void 0 || opts.init === false)) {
|
|
33966
|
+
ctx.logger.error("--repo requires --init");
|
|
33967
|
+
process.exitCode = 1;
|
|
33968
|
+
return;
|
|
33969
|
+
}
|
|
33754
33970
|
try {
|
|
33755
33971
|
const ghRunner = dependencies.ghRunner ?? runGh;
|
|
33756
33972
|
const isTty = dependencies.isTty ?? (() => Boolean(process.stdin.isTTY));
|
|
@@ -33771,7 +33987,6 @@ async function runSync(ctx, opts, dependencies = {}) {
|
|
|
33771
33987
|
);
|
|
33772
33988
|
return;
|
|
33773
33989
|
}
|
|
33774
|
-
if (opts.repo) throw new Error("--repo requires --init");
|
|
33775
33990
|
const result = await syncOwn({
|
|
33776
33991
|
ownDir: ctx.paths.knowledgeRepo,
|
|
33777
33992
|
caveatHome: ctx.caveatHome,
|
|
@@ -33793,6 +34008,7 @@ async function runSync(ctx, opts, dependencies = {}) {
|
|
|
33793
34008
|
}
|
|
33794
34009
|
}
|
|
33795
34010
|
} catch (err) {
|
|
34011
|
+
observeRuntimeError("CAVEAT.SYNC_FAILED", { version: CAVEAT_VERSION });
|
|
33796
34012
|
const message = err instanceof Error ? err.message : String(err);
|
|
33797
34013
|
ctx.logger.error(message);
|
|
33798
34014
|
process.exitCode = 1;
|
|
@@ -33801,7 +34017,7 @@ async function runSync(ctx, opts, dependencies = {}) {
|
|
|
33801
34017
|
|
|
33802
34018
|
// src/commands/codexSidecar.ts
|
|
33803
34019
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
33804
|
-
import { closeSync, constants, fstatSync, lstatSync as lstatSync2, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync3, openSync, readSync as readSync2, realpathSync as
|
|
34020
|
+
import { closeSync, constants as constants3, fstatSync, lstatSync as lstatSync2, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync3, openSync, readSync as readSync2, realpathSync as realpathSync5, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "node:fs";
|
|
33805
34021
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
33806
34022
|
import { basename as basename2, dirname as dirname7, join as join14 } from "node:path";
|
|
33807
34023
|
import { cwd, exit } from "node:process";
|
|
@@ -33837,7 +34053,7 @@ function runCodexSidecarWithCaveats(ctx, workflow, prompt, opts) {
|
|
|
33837
34053
|
}
|
|
33838
34054
|
const contextDir = mkdtempSync3(join14(tmpdir4(), "caveat-sidecar-context-"));
|
|
33839
34055
|
const contextFile = join14(contextDir, "context.json");
|
|
33840
|
-
let
|
|
34056
|
+
let status2 = 1;
|
|
33841
34057
|
try {
|
|
33842
34058
|
const blocks = collectCaveatContextBlocks(ctx, {
|
|
33843
34059
|
query: opts.query ?? prompt ?? "",
|
|
@@ -33855,11 +34071,11 @@ function runCodexSidecarWithCaveats(ctx, workflow, prompt, opts) {
|
|
|
33855
34071
|
contextFile,
|
|
33856
34072
|
cli: cliSpec(opts)
|
|
33857
34073
|
});
|
|
33858
|
-
|
|
34074
|
+
status2 = executePlan(ctx.logger, plan.command, plan.args, { saveResult: opts.saveResult });
|
|
33859
34075
|
} finally {
|
|
33860
34076
|
rmSync3(contextDir, { recursive: true, force: true });
|
|
33861
34077
|
}
|
|
33862
|
-
exit(
|
|
34078
|
+
exit(status2);
|
|
33863
34079
|
}
|
|
33864
34080
|
var MAX_ADDITIONAL_CONTEXT_BYTES = 4096;
|
|
33865
34081
|
function readHookSignalAdditionalContextFile(path, testProbe) {
|
|
@@ -33869,7 +34085,7 @@ function readHookSignalAdditionalContextFile(path, testProbe) {
|
|
|
33869
34085
|
const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
|
|
33870
34086
|
assertPrivateRegular(before, uid, platform);
|
|
33871
34087
|
testProbe?.afterLstat?.();
|
|
33872
|
-
const fd = openSync(path,
|
|
34088
|
+
const fd = openSync(path, constants3.O_RDONLY | constants3.O_NONBLOCK | (constants3.O_NOFOLLOW ?? 0));
|
|
33873
34089
|
let raw;
|
|
33874
34090
|
try {
|
|
33875
34091
|
const opened = fstatSync(fd);
|
|
@@ -33908,8 +34124,8 @@ function assertWindowsPrivateTempContainer(path, platform) {
|
|
|
33908
34124
|
if (platform !== "win32") return;
|
|
33909
34125
|
const parent = dirname7(path);
|
|
33910
34126
|
const parentStat = lstatSync2(parent);
|
|
33911
|
-
const resolvedParent =
|
|
33912
|
-
const resolvedTemp =
|
|
34127
|
+
const resolvedParent = realpathSync5(parent);
|
|
34128
|
+
const resolvedTemp = realpathSync5(tmpdir4());
|
|
33913
34129
|
if (parentStat.isSymbolicLink() || !parentStat.isDirectory() || dirname7(resolvedParent) !== resolvedTemp || !basename2(resolvedParent).startsWith("caveat-")) {
|
|
33914
34130
|
throw new Error("additional context file must be inside a reserved per-user Caveat temporary directory");
|
|
33915
34131
|
}
|
|
@@ -34086,12 +34302,200 @@ function runCommunityRemove(ctx, handle, opts) {
|
|
|
34086
34302
|
}
|
|
34087
34303
|
}
|
|
34088
34304
|
|
|
34305
|
+
// src/commands/factoryDiagnostics.ts
|
|
34306
|
+
import { execFileSync } from "node:child_process";
|
|
34307
|
+
import { existsSync as existsSync13, readFileSync as readFileSync7 } from "node:fs";
|
|
34308
|
+
import { join as join15 } from "node:path";
|
|
34309
|
+
import { DatabaseSync } from "node:sqlite";
|
|
34310
|
+
import { parse as parseToml2 } from "smol-toml";
|
|
34311
|
+
var status = (ok, reason) => ({ status: ok ? "ready" : "not_ready", reason_code: ok ? "ready" : reason });
|
|
34312
|
+
var unverified = (reason) => ({ status: "unverified", reason_code: reason });
|
|
34313
|
+
function hook(present) {
|
|
34314
|
+
return status(present, "not_installed");
|
|
34315
|
+
}
|
|
34316
|
+
function isRecord2(value) {
|
|
34317
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
34318
|
+
}
|
|
34319
|
+
function claudeRegistration(home, nodePath, cliScriptPath) {
|
|
34320
|
+
const path = join15(home, ".claude.json");
|
|
34321
|
+
if (!existsSync13(path)) return status(false, "not_registered");
|
|
34322
|
+
try {
|
|
34323
|
+
const value = JSON.parse(readFileSync7(path, "utf8"));
|
|
34324
|
+
if (!isRecord2(value) || !isRecord2(value.mcpServers)) return status(false, "not_registered");
|
|
34325
|
+
return status(isCaveatClaudeMcpRegistration(value.mcpServers.caveat, nodePath, cliScriptPath), "not_registered");
|
|
34326
|
+
} catch {
|
|
34327
|
+
return unverified("config_unreadable");
|
|
34328
|
+
}
|
|
34329
|
+
}
|
|
34330
|
+
function claudeHooks(home, nodePath, cliScriptPath) {
|
|
34331
|
+
try {
|
|
34332
|
+
const settings = JSON.parse(readFileSync7(join15(home, ".claude", "settings.json"), "utf8"));
|
|
34333
|
+
const present = (event, subcommand) => settings.hooks?.[event]?.some((entry) => entry.hooks?.some((item) => typeof item.command === "string" && isCanonicalCaveatClaudeHookCommand(item.command, subcommand, nodePath, cliScriptPath))) ?? false;
|
|
34334
|
+
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")) };
|
|
34335
|
+
} catch {
|
|
34336
|
+
const bad = unverified("config_unreadable");
|
|
34337
|
+
return { user_prompt_submit: { ...bad }, post_tool_use: { ...bad }, post_tool_use_failure: { ...bad }, stop: { ...bad } };
|
|
34338
|
+
}
|
|
34339
|
+
}
|
|
34340
|
+
var EXPECTED_SEARCH_SQL = /* @__PURE__ */ new Map([
|
|
34341
|
+
["entries_fts", "create virtual table entries_fts using fts5( id unindexed, title, body, tags, content='entries', content_rowid='rowid', tokenize='trigram' )"],
|
|
34342
|
+
["entries_ai", "create trigger entries_ai after insert on entries begin insert into entries_fts(rowid, id, title, body, tags) values (new.rowid, new.id, new.title, new.body, new.tags); end"],
|
|
34343
|
+
["entries_ad", "create trigger entries_ad after delete on entries begin insert into entries_fts(entries_fts, rowid, id, title, body, tags) values('delete', old.rowid, old.id, old.title, old.body, old.tags); end"],
|
|
34344
|
+
["entries_au", "create trigger entries_au after update on entries begin insert into entries_fts(entries_fts, rowid, id, title, body, tags) values('delete', old.rowid, old.id, old.title, old.body, old.tags); insert into entries_fts(rowid, id, title, body, tags) values (new.rowid, new.id, new.title, new.body, new.tags); end"]
|
|
34345
|
+
]);
|
|
34346
|
+
function strictSearchSchema(db) {
|
|
34347
|
+
const normalize = (sql) => (sql ?? "").toLowerCase().replace(/\s+/g, " ");
|
|
34348
|
+
const objects = db.prepare("SELECT name, sql FROM sqlite_master WHERE name = 'entries_fts' OR (type = 'trigger' AND tbl_name = 'entries')").all();
|
|
34349
|
+
if (objects.length !== EXPECTED_SEARCH_SQL.size || objects.some((object3) => normalize(object3.sql) !== EXPECTED_SEARCH_SQL.get(object3.name))) return false;
|
|
34350
|
+
const columns = db.prepare("PRAGMA table_xinfo(entries_fts)").all();
|
|
34351
|
+
return columns.map((column) => `${column.name}:${column.hidden}`).join(",") === "id:0,title:0,body:0,tags:0,entries_fts:1,rank:1";
|
|
34352
|
+
}
|
|
34353
|
+
function database(path) {
|
|
34354
|
+
if (!existsSync13(path)) return { status: "not_ready", reason_code: "missing", schema_version: null, supported_schema_version: 3, migration_status: "unverified" };
|
|
34355
|
+
try {
|
|
34356
|
+
const db = new DatabaseSync(path, { readOnly: true });
|
|
34357
|
+
try {
|
|
34358
|
+
const row = db.prepare("PRAGMA user_version").get();
|
|
34359
|
+
const columns = db.prepare("PRAGMA table_info(entries)").all().map((entry) => entry.name);
|
|
34360
|
+
const expectedColumns = ["rowid", "id", "source", "path", "title", "body", "frontmatter_json", "tags", "confidence", "visibility", "file_mtime", "indexed_at", "last_hit_at", "topical_text", "symptom_text"];
|
|
34361
|
+
const objects = db.prepare("SELECT type, name, tbl_name, sql FROM sqlite_master WHERE name = 'entries_fts' OR (type = 'trigger' AND tbl_name = 'entries')").all();
|
|
34362
|
+
const normalized = (sql) => (sql ?? "").toLowerCase().replace(/\s+/g, " ");
|
|
34363
|
+
const ftsSql = normalized(objects.find((entry) => entry.type === "table" && entry.name === "entries_fts")?.sql ?? null);
|
|
34364
|
+
const fts = ftsSql.startsWith("create virtual table entries_fts using fts5(") && ftsSql.includes("content='entries'") && ftsSql.includes("content_rowid='rowid'") && ftsSql.includes("tokenize='trigram'");
|
|
34365
|
+
const triggers = new Map(objects.filter((entry) => entry.type === "trigger").map((entry) => [entry.name, normalized(entry.sql)]));
|
|
34366
|
+
const triggerShape = triggers.size === 3 && triggers.get("entries_ai")?.includes("after insert on entries") && triggers.get("entries_ai")?.includes("insert into entries_fts") && triggers.get("entries_ad")?.includes("after delete on entries") && triggers.get("entries_ad")?.includes("values('delete'") && triggers.get("entries_au")?.includes("after update on entries") && triggers.get("entries_au")?.includes("values('delete'") && (triggers.get("entries_au")?.match(/insert into entries_fts/g)?.length ?? 0) === 2;
|
|
34367
|
+
const indexes = db.prepare("PRAGMA index_list(entries)").all();
|
|
34368
|
+
const uniqueSourceId = indexes.some((index) => index.unique === 1 && db.prepare(`PRAGMA index_info(${JSON.stringify(index.name)})`).all().map((part) => part.name).join(",") === "source,id");
|
|
34369
|
+
const current = row.user_version === 3 && columns.join(",") === expectedColumns.join(",") && fts && Boolean(triggerShape) && uniqueSourceId && strictSearchSchema(db);
|
|
34370
|
+
return { status: current ? "ready" : "not_ready", reason_code: current ? "ready" : "schema_contract_mismatch", schema_version: row.user_version, supported_schema_version: 3, migration_status: current ? "current" : "failed" };
|
|
34371
|
+
} finally {
|
|
34372
|
+
db.close();
|
|
34373
|
+
}
|
|
34374
|
+
} catch {
|
|
34375
|
+
return { status: "unverified", reason_code: "open_failed", schema_version: null, supported_schema_version: 3, migration_status: "unverified" };
|
|
34376
|
+
}
|
|
34377
|
+
}
|
|
34378
|
+
function codexFeature(codexHome) {
|
|
34379
|
+
const path = join15(codexHome, "config.toml");
|
|
34380
|
+
if (!existsSync13(path)) return status(false, "feature_disabled");
|
|
34381
|
+
try {
|
|
34382
|
+
const config2 = parseToml2(readFileSync7(path, "utf8"));
|
|
34383
|
+
if (!isRecord2(config2.features)) return status(false, "feature_disabled");
|
|
34384
|
+
const features = config2.features;
|
|
34385
|
+
return status(features.hooks === true && features.codex_hooks === void 0, "feature_disabled");
|
|
34386
|
+
} catch {
|
|
34387
|
+
return unverified("config_unreadable");
|
|
34388
|
+
}
|
|
34389
|
+
}
|
|
34390
|
+
function codexHooks(codexHome, nodePath, cliScriptPath) {
|
|
34391
|
+
const value = JSON.parse(readFileSync7(join15(codexHome, "hooks.json"), "utf8"));
|
|
34392
|
+
if (!isRecord2(value) || !isRecord2(value.hooks)) throw Error("config_unreadable");
|
|
34393
|
+
const hooks = value.hooks;
|
|
34394
|
+
const present = (event, subcommand) => Array.isArray(hooks[event]) && hooks[event].some((entry) => isRecord2(entry) && Array.isArray(entry.hooks) && entry.hooks.some((item) => isRecord2(item) && typeof item.command === "string" && isCanonicalCaveatCodexHookCommand(item.command, subcommand, nodePath, cliScriptPath)));
|
|
34395
|
+
return { userPromptSubmit: present("UserPromptSubmit", "user-prompt-submit"), postToolUse: present("PostToolUse", "post-tool-use"), stop: present("Stop", "stop") };
|
|
34396
|
+
}
|
|
34397
|
+
function sync(own) {
|
|
34398
|
+
try {
|
|
34399
|
+
execFileSync("git", ["-C", own, "rev-parse", "--is-inside-work-tree"], { stdio: "ignore" });
|
|
34400
|
+
} catch {
|
|
34401
|
+
return status(false, "not_git_worktree");
|
|
34402
|
+
}
|
|
34403
|
+
try {
|
|
34404
|
+
execFileSync("git", ["-C", own, "remote", "get-url", "origin"], { stdio: "ignore" });
|
|
34405
|
+
} catch {
|
|
34406
|
+
return status(false, "origin_missing");
|
|
34407
|
+
}
|
|
34408
|
+
try {
|
|
34409
|
+
const dirty = execFileSync("git", ["-C", own, "status", "--porcelain=v1", "--untracked-files=normal"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 5e3, env: { ...process.env, GIT_OPTIONAL_LOCKS: "0" } }).trim();
|
|
34410
|
+
if (dirty) return status(false, "worktree_dirty");
|
|
34411
|
+
const upstream = execFileSync("git", ["-C", own, "rev-parse", "--symbolic-full-name", "@{upstream}"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 5e3 }).trim();
|
|
34412
|
+
if (!upstream.startsWith("refs/remotes/origin/")) return status(false, "upstream_not_origin");
|
|
34413
|
+
const remoteRef = `refs/heads/${upstream.slice("refs/remotes/origin/".length)}`;
|
|
34414
|
+
const remote = execFileSync("git", ["-C", own, "ls-remote", "--exit-code", "origin", remoteRef], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 1e4, maxBuffer: 16384 }).trim().split(/\s+/)[0];
|
|
34415
|
+
const head = execFileSync("git", ["-C", own, "rev-parse", "HEAD"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 5e3 }).trim();
|
|
34416
|
+
if (!/^[0-9a-f]{40}$/.test(remote ?? "") || !/^[0-9a-f]{40}$/.test(head)) return unverified("sync_hash_unparseable");
|
|
34417
|
+
if (remote !== head) return status(false, "remote_mismatch");
|
|
34418
|
+
const counts = execFileSync("git", ["-C", own, "rev-list", "--left-right", "--count", "@{upstream}...HEAD"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 5e3 }).trim().split(/\s+/).map(Number);
|
|
34419
|
+
if (counts.length !== 2 || counts.some((value) => !Number.isSafeInteger(value) || value < 0)) return unverified("sync_count_unparseable");
|
|
34420
|
+
if (counts[0] === 0 && counts[1] === 0) return status(true, "ready");
|
|
34421
|
+
return status(false, counts[0] && counts[1] ? "diverged" : counts[0] ? "behind" : "ahead");
|
|
34422
|
+
} catch {
|
|
34423
|
+
return unverified("upstream_unavailable");
|
|
34424
|
+
}
|
|
34425
|
+
}
|
|
34426
|
+
function factoryDiagnostics(ctx, codexHome = process.env.CODEX_HOME ?? join15(ctx.userHome, ".codex")) {
|
|
34427
|
+
const nodePath = process.execPath;
|
|
34428
|
+
const cliScriptPath = process.argv[1] ?? "";
|
|
34429
|
+
const db = database(ctx.paths.dbPath);
|
|
34430
|
+
const feature = codexFeature(codexHome);
|
|
34431
|
+
let installedCodexHooks = null;
|
|
34432
|
+
try {
|
|
34433
|
+
installedCodexHooks = codexHooks(codexHome, nodePath, cliScriptPath);
|
|
34434
|
+
} catch {
|
|
34435
|
+
}
|
|
34436
|
+
const codexHook2 = (present) => present === void 0 ? unverified("config_unreadable") : !present ? hook(false) : feature.status === "ready" ? hook(true) : { ...feature };
|
|
34437
|
+
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) } } } };
|
|
34438
|
+
const aggregate = (all) => all.includes("not_ready") ? "not_ready" : all.includes("unverified") ? "unverified" : "ready";
|
|
34439
|
+
const connectorStatus = (connector) => aggregate([...Object.values(connector.hooks), ...connector.mcp ? [connector.mcp] : []].map((v) => v.status));
|
|
34440
|
+
output.connectors.claude.status = connectorStatus(output.connectors.claude);
|
|
34441
|
+
output.connectors.codex.status = connectorStatus(output.connectors.codex);
|
|
34442
|
+
const statuses = [output.database.status, output.sync.status, output.connectors.claude.status, output.connectors.codex.status];
|
|
34443
|
+
output.overall.status = aggregate(statuses);
|
|
34444
|
+
return output;
|
|
34445
|
+
}
|
|
34446
|
+
|
|
34447
|
+
// src/commands/runtimeErrors.ts
|
|
34448
|
+
function runRuntimeErrors(action, value, opts = {}) {
|
|
34449
|
+
const runtime = { version: CAVEAT_VERSION };
|
|
34450
|
+
if (action === "snapshot") return runtimeErrorsSnapshot(opts.afterCursor ?? 0, opts.limit ?? 256, runtime);
|
|
34451
|
+
if (action === "diagnostics") return runtimeErrorsDiagnostics(runtime);
|
|
34452
|
+
if (action === "ack") return acknowledgeRuntimeErrors(parseCursor(value), runtime);
|
|
34453
|
+
if (action === "resolve") return setRuntimeErrorStatus(value ?? "", "resolved", runtime);
|
|
34454
|
+
if (action === "reopen") return setRuntimeErrorStatus(value ?? "", "open", runtime);
|
|
34455
|
+
if (action === "compact") return compactRuntimeErrors(runtime);
|
|
34456
|
+
throw new Error("unknown_runtime_errors_action");
|
|
34457
|
+
}
|
|
34458
|
+
function parseCursor(value) {
|
|
34459
|
+
if (!value || !/^(?:0|[1-9][0-9]*)$/.test(value)) throw Error("invalid_cursor");
|
|
34460
|
+
const parsed = Number(value);
|
|
34461
|
+
if (!Number.isSafeInteger(parsed)) throw Error("invalid_cursor");
|
|
34462
|
+
return parsed;
|
|
34463
|
+
}
|
|
34464
|
+
|
|
34089
34465
|
// src/index.ts
|
|
34090
34466
|
var program = new Command();
|
|
34091
34467
|
function collectRepeatable(value, previous) {
|
|
34092
34468
|
return [...previous, value];
|
|
34093
34469
|
}
|
|
34094
34470
|
program.name("caveat").description("External spec gotcha knowledge base CLI").version(CAVEAT_VERSION);
|
|
34471
|
+
program.command("factory-diagnostics").description("Emit read-only factory diagnostics").requiredOption("--json", "emit the versioned JSON contract").action((opts) => {
|
|
34472
|
+
const output = factoryDiagnostics(buildContext(stdoutLogger));
|
|
34473
|
+
process.stdout.write(`${JSON.stringify(output)}
|
|
34474
|
+
`);
|
|
34475
|
+
if (output.overall.status !== "ready") process.exitCode = 1;
|
|
34476
|
+
});
|
|
34477
|
+
var runtimeErrors = program.command("runtime-errors").description("Inspect Caveat opt-in runtime errors");
|
|
34478
|
+
var parseLimit = (value) => {
|
|
34479
|
+
const parsed = parseCursor(value);
|
|
34480
|
+
if (parsed < 1 || parsed > 256) throw Error("invalid_limit");
|
|
34481
|
+
return parsed;
|
|
34482
|
+
};
|
|
34483
|
+
runtimeErrors.command("snapshot").requiredOption("--json", "emit JSON").option("--after-cursor <n>", "cursor", parseCursor, 0).option("--limit <n>", "limit", parseLimit, 256).action((opts) => {
|
|
34484
|
+
process.stdout.write(`${JSON.stringify(runRuntimeErrors("snapshot", void 0, opts))}
|
|
34485
|
+
`);
|
|
34486
|
+
});
|
|
34487
|
+
for (const action of ["diagnostics", "compact"]) runtimeErrors.command(action).requiredOption("--json", "emit JSON").action(() => {
|
|
34488
|
+
process.stdout.write(`${JSON.stringify(runRuntimeErrors(action))}
|
|
34489
|
+
`);
|
|
34490
|
+
});
|
|
34491
|
+
runtimeErrors.command("ack <cursor>").requiredOption("--json", "emit JSON").action((cursor) => {
|
|
34492
|
+
process.stdout.write(`${JSON.stringify(runRuntimeErrors("ack", cursor))}
|
|
34493
|
+
`);
|
|
34494
|
+
});
|
|
34495
|
+
for (const action of ["resolve", "reopen"]) runtimeErrors.command(`${action} <fingerprint>`).requiredOption("--json", "emit JSON").action((fingerprint) => {
|
|
34496
|
+
process.stdout.write(`${JSON.stringify(runRuntimeErrors(action, fingerprint))}
|
|
34497
|
+
`);
|
|
34498
|
+
});
|
|
34095
34499
|
program.command("init").description(
|
|
34096
34500
|
"Initialize ~/.caveatrc.json, ~/.caveat/, and register Claude Code integration. Add knowledge sources later with `caveat community add <github-url>`."
|
|
34097
34501
|
).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(
|