caveat-cli 0.14.2 → 0.14.4
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/README.md +22 -5
- package/dist/{chunk-CSXD73IX.js → chunk-EH3S6X6X.js} +9 -3
- package/dist/{chunk-CSXD73IX.js.map → chunk-EH3S6X6X.js.map} +1 -1
- package/dist/index.js +205 -37
- package/dist/index.js.map +1 -1
- package/dist/{server-BP54BTEL.js → server-P4FQZD2N.js} +2 -2
- package/package.json +16 -13
- /package/dist/{server-BP54BTEL.js.map → server-P4FQZD2N.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
toolErrorReminderText,
|
|
41
41
|
updateEntry,
|
|
42
42
|
userPromptSubmitReminderText
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-EH3S6X6X.js";
|
|
44
44
|
|
|
45
45
|
// ../../node_modules/.pnpm/ajv@8.18.0/node_modules/ajv/dist/compile/codegen/code.js
|
|
46
46
|
var require_code = __commonJS({
|
|
@@ -7345,7 +7345,7 @@ function runStats(ctx) {
|
|
|
7345
7345
|
|
|
7346
7346
|
// src/commands/serve.ts
|
|
7347
7347
|
async function runServe(opts) {
|
|
7348
|
-
const { startServer } = await import("./server-
|
|
7348
|
+
const { startServer } = await import("./server-P4FQZD2N.js");
|
|
7349
7349
|
const { port, host } = startServer({ port: opts.port });
|
|
7350
7350
|
process.stdout.write(`[caveat] web portal: http://${host}:${port}/
|
|
7351
7351
|
`);
|
|
@@ -21846,6 +21846,7 @@ async function runMcpServer() {
|
|
|
21846
21846
|
import { spawn, spawnSync as spawnSync2 } from "node:child_process";
|
|
21847
21847
|
import {
|
|
21848
21848
|
existsSync as existsSync5,
|
|
21849
|
+
mkdirSync as mkdirSync4,
|
|
21849
21850
|
mkdtempSync,
|
|
21850
21851
|
readFileSync as readFileSync3,
|
|
21851
21852
|
rmSync,
|
|
@@ -21854,7 +21855,7 @@ import {
|
|
|
21854
21855
|
} from "node:fs";
|
|
21855
21856
|
import { tmpdir } from "node:os";
|
|
21856
21857
|
import { join as join8 } from "node:path";
|
|
21857
|
-
import { randomBytes } from "node:crypto";
|
|
21858
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
21858
21859
|
var silentLogger = {
|
|
21859
21860
|
info: () => {
|
|
21860
21861
|
},
|
|
@@ -21863,6 +21864,9 @@ var silentLogger = {
|
|
|
21863
21864
|
error: (m) => process.stderr.write(`[caveat:hook] ${m}
|
|
21864
21865
|
`)
|
|
21865
21866
|
};
|
|
21867
|
+
var CLAUDE_MAX_CONTEXT_BLOCKS = 3;
|
|
21868
|
+
var CLAUDE_STOP_REMINDER_PREFIX = "[caveat] \u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u3067\u5916\u90E8\u4ED5\u69D8\u306E\u7F60\u306B\u5F53\u305F\u3063\u305F\u53EF\u80FD\u6027\u3092\u793A\u3059\u30B7\u30B0\u30CA\u30EB:";
|
|
21869
|
+
var CLAUDE_STOP_STATE_DIR = "claude-stop-state";
|
|
21866
21870
|
async function readStdin() {
|
|
21867
21871
|
const chunks = [];
|
|
21868
21872
|
for await (const chunk of process.stdin) {
|
|
@@ -21934,12 +21938,82 @@ function loadSignalsSafely(path) {
|
|
|
21934
21938
|
return null;
|
|
21935
21939
|
}
|
|
21936
21940
|
}
|
|
21941
|
+
function systemReminderOutput(text) {
|
|
21942
|
+
return `<system-reminder>${text}</system-reminder>`;
|
|
21943
|
+
}
|
|
21937
21944
|
function drainForSession(sessionId) {
|
|
21945
|
+
const ctx = buildContextSafely();
|
|
21946
|
+
if (!ctx) return [];
|
|
21947
|
+
return drainPendingReminders(ctx.caveatHome, sessionId);
|
|
21948
|
+
}
|
|
21949
|
+
function claudeContextDedupeKey(text) {
|
|
21950
|
+
if (text.startsWith(CLAUDE_STOP_REMINDER_PREFIX)) return "claude-stop-reminder";
|
|
21951
|
+
return text.trim();
|
|
21952
|
+
}
|
|
21953
|
+
function compactClaudeContexts(contexts) {
|
|
21954
|
+
const selected = [];
|
|
21955
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21956
|
+
for (let i = contexts.length - 1; i >= 0; i -= 1) {
|
|
21957
|
+
const text = contexts[i]?.trim();
|
|
21958
|
+
if (!text) continue;
|
|
21959
|
+
const key = claudeContextDedupeKey(text);
|
|
21960
|
+
if (seen.has(key)) continue;
|
|
21961
|
+
seen.add(key);
|
|
21962
|
+
selected.push(text);
|
|
21963
|
+
}
|
|
21964
|
+
selected.reverse();
|
|
21965
|
+
const limited = selected.slice(-CLAUDE_MAX_CONTEXT_BLOCKS);
|
|
21966
|
+
const omitted = contexts.filter((t) => t.trim().length > 0).length - limited.length;
|
|
21967
|
+
if (omitted > 0) {
|
|
21968
|
+
limited.push(
|
|
21969
|
+
`[caveat] pending reminder ${omitted} \u4EF6\u3092\u91CD\u8907\u307E\u305F\u306F\u4E0A\u9650\u306B\u3088\u308A\u7701\u7565\u3057\u307E\u3057\u305F\u3002`
|
|
21970
|
+
);
|
|
21971
|
+
}
|
|
21972
|
+
return limited;
|
|
21973
|
+
}
|
|
21974
|
+
function sanitizeClaudeStateId(raw) {
|
|
21975
|
+
const clean = raw.replace(/[^A-Za-z0-9_-]/g, "");
|
|
21976
|
+
return clean.length > 0 ? clean : "_unknown";
|
|
21977
|
+
}
|
|
21978
|
+
function stopSignalKey(signals, related) {
|
|
21979
|
+
const body = JSON.stringify({
|
|
21980
|
+
toolFailureCount: signals.toolFailureCount,
|
|
21981
|
+
fileEditCounts: signals.fileEditCounts.map((e) => [e.path, e.count]),
|
|
21982
|
+
webSearchCount: signals.webSearchCount,
|
|
21983
|
+
webFetchCount: signals.webFetchCount,
|
|
21984
|
+
bashRetryCount: signals.bashRetryCount,
|
|
21985
|
+
searchQueries: signals.searchQueries,
|
|
21986
|
+
related: related.map((h) => [h.source, h.id])
|
|
21987
|
+
});
|
|
21988
|
+
return createHash("sha256").update(body).digest("hex");
|
|
21989
|
+
}
|
|
21990
|
+
function stopStatePath(caveatHome, sessionId) {
|
|
21991
|
+
return join8(caveatHome, CLAUDE_STOP_STATE_DIR, `${sanitizeClaudeStateId(sessionId)}.txt`);
|
|
21992
|
+
}
|
|
21993
|
+
function wasStopReminderQueued(caveatHome, sessionId, key) {
|
|
21994
|
+
const path = stopStatePath(caveatHome, sessionId);
|
|
21995
|
+
try {
|
|
21996
|
+
return readFileSync3(path, "utf-8") === key;
|
|
21997
|
+
} catch {
|
|
21998
|
+
return false;
|
|
21999
|
+
}
|
|
22000
|
+
}
|
|
22001
|
+
function markStopReminderQueued(caveatHome, sessionId, key) {
|
|
22002
|
+
const path = stopStatePath(caveatHome, sessionId);
|
|
22003
|
+
mkdirSync4(join8(caveatHome, CLAUDE_STOP_STATE_DIR), { recursive: true });
|
|
22004
|
+
writeFileSync3(path, key, "utf-8");
|
|
22005
|
+
}
|
|
22006
|
+
function queueStopForSession(sessionId, signals, related) {
|
|
21938
22007
|
const ctx = buildContextSafely();
|
|
21939
22008
|
if (!ctx) return;
|
|
21940
|
-
const
|
|
21941
|
-
|
|
21942
|
-
|
|
22009
|
+
const key = stopSignalKey(signals, related);
|
|
22010
|
+
if (wasStopReminderQueued(ctx.caveatHome, sessionId, key)) return;
|
|
22011
|
+
try {
|
|
22012
|
+
appendPendingReminder(ctx.caveatHome, sessionId, buildStopReminder(signals, related));
|
|
22013
|
+
markStopReminderQueued(ctx.caveatHome, sessionId, key);
|
|
22014
|
+
} catch (err) {
|
|
22015
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
22016
|
+
process.stderr.write(`[caveat:hook] pending reminder write error: ${msg}
|
|
21943
22017
|
`);
|
|
21944
22018
|
}
|
|
21945
22019
|
}
|
|
@@ -22105,6 +22179,20 @@ function buildStopReminder(signals, related) {
|
|
|
22105
22179
|
`[caveat:codex-sidecar] advisory unavailable: ${advisory.message}`
|
|
22106
22180
|
].join("\n");
|
|
22107
22181
|
}
|
|
22182
|
+
function compactFailureMessage(message) {
|
|
22183
|
+
const singleLine = message.replace(/\s+/g, " ").trim();
|
|
22184
|
+
if (!singleLine) return "unknown error";
|
|
22185
|
+
return singleLine.length > 220 ? `${singleLine.slice(0, 220)}...` : singleLine;
|
|
22186
|
+
}
|
|
22187
|
+
function sidecarFailureDetail(output) {
|
|
22188
|
+
const protocol = output.match(/PROTOCOL_ERROR:[^"\r\n]+/);
|
|
22189
|
+
if (protocol) return compactFailureMessage(protocol[0]);
|
|
22190
|
+
const lines = output.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
22191
|
+
const diagnostic = lines.find(
|
|
22192
|
+
(line) => !line.startsWith("[caveat] [codex-sidecar] codex-sidecar ")
|
|
22193
|
+
);
|
|
22194
|
+
return compactFailureMessage(diagnostic ?? output);
|
|
22195
|
+
}
|
|
22108
22196
|
function runCodexSidecarAdvisory(input) {
|
|
22109
22197
|
const cliScript = process.argv[1];
|
|
22110
22198
|
if (!cliScript) {
|
|
@@ -22144,15 +22232,21 @@ function runCodexSidecarAdvisory(input) {
|
|
|
22144
22232
|
maxBuffer: 10 * 1024 * 1024
|
|
22145
22233
|
});
|
|
22146
22234
|
if (result.error) {
|
|
22147
|
-
return { status: "failed", message: result.error.message };
|
|
22235
|
+
return { status: "failed", message: compactFailureMessage(result.error.message) };
|
|
22148
22236
|
}
|
|
22149
22237
|
if (result.status !== 0) {
|
|
22150
22238
|
const detail = (result.stderr || result.stdout || `exit ${result.status}`).trim();
|
|
22151
|
-
return {
|
|
22239
|
+
return {
|
|
22240
|
+
status: "failed",
|
|
22241
|
+
message: `sidecar command failed: ${sidecarFailureDetail(detail)}`
|
|
22242
|
+
};
|
|
22152
22243
|
}
|
|
22153
22244
|
const parsed = JSON.parse(readFileSync3(resultFile, "utf-8"));
|
|
22154
22245
|
if (parsed.status !== "ok" || typeof parsed.summary !== "string") {
|
|
22155
|
-
return {
|
|
22246
|
+
return {
|
|
22247
|
+
status: "failed",
|
|
22248
|
+
message: compactFailureMessage(`unexpected SidecarResult status: ${String(parsed.status)}`)
|
|
22249
|
+
};
|
|
22156
22250
|
}
|
|
22157
22251
|
return {
|
|
22158
22252
|
status: "ok",
|
|
@@ -22161,7 +22255,10 @@ function runCodexSidecarAdvisory(input) {
|
|
|
22161
22255
|
};
|
|
22162
22256
|
} catch (err) {
|
|
22163
22257
|
const msg = err instanceof Error ? err.message : String(err);
|
|
22164
|
-
return {
|
|
22258
|
+
return {
|
|
22259
|
+
status: "failed",
|
|
22260
|
+
message: compactFailureMessage(`invalid SidecarResult JSON: ${msg}`)
|
|
22261
|
+
};
|
|
22165
22262
|
} finally {
|
|
22166
22263
|
rmSync(resultDir, { recursive: true, force: true });
|
|
22167
22264
|
}
|
|
@@ -22183,19 +22280,26 @@ async function runHook(name, arg) {
|
|
|
22183
22280
|
}
|
|
22184
22281
|
const payload = parsePayload(raw);
|
|
22185
22282
|
const sessionId = getSessionId(payload);
|
|
22186
|
-
drainForSession(sessionId);
|
|
22283
|
+
const contexts = name === "stop" ? [] : drainForSession(sessionId);
|
|
22187
22284
|
if (name === "user-prompt-submit") {
|
|
22188
22285
|
const prompt = typeof payload.prompt === "string" ? payload.prompt : "";
|
|
22189
22286
|
const hits = searchCaveatsFromTextSafely(prompt);
|
|
22190
22287
|
if (hits.length > 0) {
|
|
22191
|
-
|
|
22192
|
-
|
|
22193
|
-
|
|
22194
|
-
|
|
22288
|
+
contexts.push(userPromptSubmitReminderText(hits));
|
|
22289
|
+
}
|
|
22290
|
+
const compacted = compactClaudeContexts(contexts);
|
|
22291
|
+
if (compacted.length > 0) {
|
|
22292
|
+
process.stdout.write(`${systemReminderOutput(compacted.join("\n\n"))}
|
|
22293
|
+
`);
|
|
22195
22294
|
}
|
|
22196
22295
|
process.exit(0);
|
|
22197
22296
|
}
|
|
22198
22297
|
if (name === "post-tool-use") {
|
|
22298
|
+
const compacted = compactClaudeContexts(contexts);
|
|
22299
|
+
if (compacted.length > 0) {
|
|
22300
|
+
process.stdout.write(`${systemReminderOutput(compacted.join("\n\n"))}
|
|
22301
|
+
`);
|
|
22302
|
+
}
|
|
22199
22303
|
if (!isToolError(payload)) process.exit(0);
|
|
22200
22304
|
const errText = extractToolResponseText(
|
|
22201
22305
|
payload.tool_response ?? payload.toolResponse ?? payload.error ?? payload
|
|
@@ -22211,8 +22315,7 @@ async function runHook(name, arg) {
|
|
|
22211
22315
|
const signals = transcriptPath ? loadSignalsSafely(transcriptPath) : null;
|
|
22212
22316
|
if (!signals || !hasAnyStruggleSignal(signals)) process.exit(0);
|
|
22213
22317
|
const related = searchCaveatsFromTextSafely(struggleSearchText(signals));
|
|
22214
|
-
|
|
22215
|
-
`);
|
|
22318
|
+
queueStopForSession(sessionId, signals, related);
|
|
22216
22319
|
process.exit(0);
|
|
22217
22320
|
}
|
|
22218
22321
|
process.stderr.write(`[caveat:hook] unknown hook name: ${name}
|
|
@@ -22222,13 +22325,13 @@ async function runHook(name, arg) {
|
|
|
22222
22325
|
|
|
22223
22326
|
// src/commands/codexHookCmd.ts
|
|
22224
22327
|
import { spawn as spawn2, spawnSync as spawnSync3 } from "node:child_process";
|
|
22225
|
-
import { existsSync as existsSync7, readFileSync as readFileSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
22328
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
22226
22329
|
import { homedir as homedir3, tmpdir as tmpdir2 } from "node:os";
|
|
22227
22330
|
import { join as join10 } from "node:path";
|
|
22228
|
-
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
22331
|
+
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
22229
22332
|
|
|
22230
22333
|
// src/codexHookInstall.ts
|
|
22231
|
-
import { copyFileSync as copyFileSync2, existsSync as existsSync6, mkdirSync as
|
|
22334
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "node:fs";
|
|
22232
22335
|
import { dirname as dirname5, join as join9 } from "node:path";
|
|
22233
22336
|
function quote2(p) {
|
|
22234
22337
|
return p.includes(" ") ? `"${p}"` : p;
|
|
@@ -22253,7 +22356,7 @@ function readHooks(path) {
|
|
|
22253
22356
|
}
|
|
22254
22357
|
function writeJsonWithBackup(path, value) {
|
|
22255
22358
|
const dir = dirname5(path);
|
|
22256
|
-
if (!existsSync6(dir))
|
|
22359
|
+
if (!existsSync6(dir)) mkdirSync5(dir, { recursive: true });
|
|
22257
22360
|
let backupPath = "";
|
|
22258
22361
|
if (existsSync6(path)) {
|
|
22259
22362
|
backupPath = `${path}.caveat-backup-${Date.now()}`;
|
|
@@ -22322,7 +22425,7 @@ codex_hooks = true
|
|
|
22322
22425
|
}
|
|
22323
22426
|
function writeConfigWithBackup(path, text) {
|
|
22324
22427
|
const dir = dirname5(path);
|
|
22325
|
-
if (!existsSync6(dir))
|
|
22428
|
+
if (!existsSync6(dir)) mkdirSync5(dir, { recursive: true });
|
|
22326
22429
|
let backupPath = "";
|
|
22327
22430
|
if (existsSync6(path)) {
|
|
22328
22431
|
backupPath = `${path}.caveat-backup-${Date.now()}`;
|
|
@@ -22439,6 +22542,9 @@ var silentLogger2 = {
|
|
|
22439
22542
|
error: (m) => process.stderr.write(`[caveat:codex-hook] ${m}
|
|
22440
22543
|
`)
|
|
22441
22544
|
};
|
|
22545
|
+
var CODEX_MAX_CONTEXT_BLOCKS = 3;
|
|
22546
|
+
var CODEX_STOP_REMINDER_PREFIX = "[caveat] \u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u3067\u5916\u90E8\u4ED5\u69D8\u306E\u7F60\u306B\u5F53\u305F\u3063\u305F\u53EF\u80FD\u6027\u3092\u793A\u3059\u30B7\u30B0\u30CA\u30EB:";
|
|
22547
|
+
var CODEX_STOP_STATE_DIR = "codex-stop-state";
|
|
22442
22548
|
async function readStdin2() {
|
|
22443
22549
|
const chunks = [];
|
|
22444
22550
|
for await (const chunk of process.stdin) {
|
|
@@ -22637,18 +22743,77 @@ function codexContextOutput(text, eventName = "UserPromptSubmit") {
|
|
|
22637
22743
|
}
|
|
22638
22744
|
});
|
|
22639
22745
|
}
|
|
22640
|
-
function
|
|
22641
|
-
|
|
22642
|
-
|
|
22643
|
-
|
|
22746
|
+
function drainForSession2(sessionId) {
|
|
22747
|
+
const ctx = buildContextSafely2();
|
|
22748
|
+
if (!ctx) return [];
|
|
22749
|
+
return drainPendingReminders(ctx.caveatHome, sessionId);
|
|
22750
|
+
}
|
|
22751
|
+
function codexContextDedupeKey(text) {
|
|
22752
|
+
if (text.startsWith(CODEX_STOP_REMINDER_PREFIX)) return "codex-stop-reminder";
|
|
22753
|
+
return text.trim();
|
|
22754
|
+
}
|
|
22755
|
+
function compactCodexContexts(contexts) {
|
|
22756
|
+
const selected = [];
|
|
22757
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22758
|
+
for (let i = contexts.length - 1; i >= 0; i -= 1) {
|
|
22759
|
+
const text = contexts[i]?.trim();
|
|
22760
|
+
if (!text) continue;
|
|
22761
|
+
const key = codexContextDedupeKey(text);
|
|
22762
|
+
if (seen.has(key)) continue;
|
|
22763
|
+
seen.add(key);
|
|
22764
|
+
selected.push(text);
|
|
22765
|
+
}
|
|
22766
|
+
selected.reverse();
|
|
22767
|
+
const limited = selected.slice(-CODEX_MAX_CONTEXT_BLOCKS);
|
|
22768
|
+
const omitted = contexts.filter((t) => t.trim().length > 0).length - limited.length;
|
|
22769
|
+
if (omitted > 0) {
|
|
22770
|
+
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`);
|
|
22771
|
+
}
|
|
22772
|
+
return limited;
|
|
22773
|
+
}
|
|
22774
|
+
function sanitizeCodexStateId(raw) {
|
|
22775
|
+
const clean = raw.replace(/[^A-Za-z0-9_-]/g, "");
|
|
22776
|
+
return clean.length > 0 ? clean : "_unknown";
|
|
22777
|
+
}
|
|
22778
|
+
function stopSignalKey2(signals, related) {
|
|
22779
|
+
const body = JSON.stringify({
|
|
22780
|
+
toolFailureCount: signals.toolFailureCount,
|
|
22781
|
+
fileEditCounts: signals.fileEditCounts.map((e) => [e.path, e.count]),
|
|
22782
|
+
webSearchCount: signals.webSearchCount,
|
|
22783
|
+
webFetchCount: signals.webFetchCount,
|
|
22784
|
+
bashRetryCount: signals.bashRetryCount,
|
|
22785
|
+
searchQueries: signals.searchQueries,
|
|
22786
|
+
related: related.map((h) => [h.source, h.id])
|
|
22644
22787
|
});
|
|
22788
|
+
return createHash2("sha256").update(body).digest("hex");
|
|
22789
|
+
}
|
|
22790
|
+
function stopStatePath2(caveatHome, sessionId) {
|
|
22791
|
+
return join10(caveatHome, CODEX_STOP_STATE_DIR, `${sanitizeCodexStateId(sessionId)}.txt`);
|
|
22645
22792
|
}
|
|
22646
|
-
function
|
|
22793
|
+
function wasStopReminderQueued2(caveatHome, sessionId, key) {
|
|
22794
|
+
const path = stopStatePath2(caveatHome, sessionId);
|
|
22795
|
+
try {
|
|
22796
|
+
return readFileSync5(path, "utf-8") === key;
|
|
22797
|
+
} catch {
|
|
22798
|
+
return false;
|
|
22799
|
+
}
|
|
22800
|
+
}
|
|
22801
|
+
function markStopReminderQueued2(caveatHome, sessionId, key) {
|
|
22802
|
+
const path = stopStatePath2(caveatHome, sessionId);
|
|
22803
|
+
mkdirSync6(join10(caveatHome, CODEX_STOP_STATE_DIR), { recursive: true });
|
|
22804
|
+
writeFileSync5(path, key, "utf-8");
|
|
22805
|
+
}
|
|
22806
|
+
function queueStopForSession2(sessionId, signals, related) {
|
|
22647
22807
|
const ctx = buildContextSafely2();
|
|
22648
22808
|
if (!ctx) return;
|
|
22649
|
-
const
|
|
22650
|
-
|
|
22651
|
-
|
|
22809
|
+
const key = stopSignalKey2(signals, related);
|
|
22810
|
+
if (wasStopReminderQueued2(ctx.caveatHome, sessionId, key)) return;
|
|
22811
|
+
try {
|
|
22812
|
+
appendPendingReminder(ctx.caveatHome, sessionId, stopReminderText(signals, related));
|
|
22813
|
+
markStopReminderQueued2(ctx.caveatHome, sessionId, key);
|
|
22814
|
+
} catch (err) {
|
|
22815
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
22816
|
+
process.stderr.write(`[caveat:codex-hook] pending reminder write error: ${msg}
|
|
22652
22817
|
`);
|
|
22653
22818
|
}
|
|
22654
22819
|
}
|
|
@@ -22748,13 +22913,17 @@ async function runCodexHook(name, arg) {
|
|
|
22748
22913
|
}
|
|
22749
22914
|
const payload = parsePayload2(raw);
|
|
22750
22915
|
const sessionId = codexSessionId(payload);
|
|
22751
|
-
if (sessionId
|
|
22752
|
-
else if (!sessionId) process.stderr.write("[caveat:codex-hook] missing session_id; pending drain disabled\n");
|
|
22916
|
+
if (!sessionId) process.stderr.write("[caveat:codex-hook] missing session_id; pending drain disabled\n");
|
|
22753
22917
|
if (name === "user-prompt-submit") {
|
|
22918
|
+
const contexts = sessionId ? drainForSession2(sessionId) : [];
|
|
22754
22919
|
const prompt = typeof payload.prompt === "string" ? payload.prompt : "";
|
|
22755
22920
|
const hits = searchCaveatsFromTextSafely2(prompt);
|
|
22756
22921
|
if (hits.length > 0) {
|
|
22757
|
-
|
|
22922
|
+
contexts.push(userPromptSubmitReminderText(hits));
|
|
22923
|
+
}
|
|
22924
|
+
const compacted = compactCodexContexts(contexts);
|
|
22925
|
+
if (compacted.length > 0) {
|
|
22926
|
+
process.stdout.write(`${codexContextOutput(compacted.join("\n\n"))}
|
|
22758
22927
|
`);
|
|
22759
22928
|
}
|
|
22760
22929
|
process.exit(0);
|
|
@@ -22770,8 +22939,7 @@ async function runCodexHook(name, arg) {
|
|
|
22770
22939
|
const signals = transcriptPath ? loadSignalsSafely2(transcriptPath) : null;
|
|
22771
22940
|
if (!signals || !hasAnyStruggleSignal(signals)) process.exit(0);
|
|
22772
22941
|
const related = searchCaveatsFromTextSafely2(struggleSearchText(signals));
|
|
22773
|
-
|
|
22774
|
-
`);
|
|
22942
|
+
if (sessionId) queueStopForSession2(sessionId, signals, related);
|
|
22775
22943
|
process.exit(0);
|
|
22776
22944
|
}
|
|
22777
22945
|
process.stderr.write(`[caveat:codex-hook] unknown hook name: ${name}
|
|
@@ -22822,7 +22990,7 @@ async function runPull(ctx) {
|
|
|
22822
22990
|
|
|
22823
22991
|
// src/commands/codexSidecar.ts
|
|
22824
22992
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
22825
|
-
import { mkdirSync as
|
|
22993
|
+
import { mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync2, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
22826
22994
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
22827
22995
|
import { dirname as dirname6, join as join12 } from "node:path";
|
|
22828
22996
|
import { cwd, exit } from "node:process";
|
|
@@ -22935,7 +23103,7 @@ function executePlan(logger, command, args, options = {}) {
|
|
|
22935
23103
|
}
|
|
22936
23104
|
function saveStructuredResult(path, stdout) {
|
|
22937
23105
|
const parsed = JSON.parse(stdout);
|
|
22938
|
-
|
|
23106
|
+
mkdirSync7(dirname6(path), { recursive: true });
|
|
22939
23107
|
writeFileSync6(path, JSON.stringify(parsed, null, 2) + "\n", "utf-8");
|
|
22940
23108
|
}
|
|
22941
23109
|
function shellDisplayQuote(value) {
|