caveat-cli 0.17.1 → 0.17.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/README.md CHANGED
@@ -1,8 +1,20 @@
1
- # caveat-cli
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/kitepon-rgb/Caveat/main/.github/og.png" alt="Caveat — long-term memory layer for coding agents" width="100%">
3
+ </p>
2
4
 
3
- Long-term memory CLI for Claude Code and Codex — markdown + SQLite FTS5 + MCP server + agent hooks. Personal / group knowledge tool, no central shared DB.
5
+ # Caveat
4
6
 
5
- **Source / full docs**: https://github.com/kitepon-rgb/Caveat
7
+ [![npm](https://img.shields.io/npm/v/caveat-cli?color=cb3837&label=caveat-cli)](https://www.npmjs.com/package/caveat-cli)
8
+ [![CI](https://github.com/kitepon-rgb/Caveat/actions/workflows/ci.yml/badge.svg)](https://github.com/kitepon-rgb/Caveat/actions/workflows/ci.yml)
9
+ [![license](https://img.shields.io/npm/l/caveat-cli?color=blue)](https://github.com/kitepon-rgb/Caveat/blob/main/LICENSE)
10
+
11
+ > **Stop rediscovering the same trap.** Caveat is a long-term memory layer for Claude Code and Codex: record a hard-won external-spec quirk or repo-specific oddity once, and the relevant note surfaces before an AI repeats it.
12
+
13
+ 🇯🇵 **日本語版**: [README.ja.md](https://github.com/kitepon-rgb/Caveat/blob/main/README.ja.md)
14
+
15
+ Built and maintained by [Quo](https://x.com/QLyun35332) at [kitepon.dev](https://kitepon.dev/en).
16
+
17
+ **Source / full docs**: [github.com/kitepon-rgb/Caveat](https://github.com/kitepon-rgb/Caveat)
6
18
 
7
19
  ## Install
8
20
 
package/dist/index.js CHANGED
@@ -7158,6 +7158,10 @@ function isCanonicalCaveatCodexHookCommand(actual, event, nodePath, cliScriptPat
7158
7158
  const tokens = parsed?.[0] === "&" ? parsed.slice(1) : parsed;
7159
7159
  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;
7160
7160
  }
7161
+ function isCanonicalCaveatCodexHookEntry(value, event, nodePath, cliScriptPath) {
7162
+ if (!isPlainRecord(value) || typeof value.type !== "string" || typeof value.command !== "string") return false;
7163
+ return value.type === "command" && isCanonicalCaveatCodexHookCommand(value.command, event, nodePath, cliScriptPath) && value.timeout === 5 && value.timeoutSec === void 0 && value.async === false && value.statusMessage === null;
7164
+ }
7161
7165
  function hasCaveatHook(hooksJson, event, fragment) {
7162
7166
  return hooksJson.hooks?.[event]?.some(
7163
7167
  (entry) => entry.hooks?.some((h) => h.command.includes(fragment))
@@ -7184,10 +7188,12 @@ function upsertHook2(hooksJson, event, command, subcommand) {
7184
7188
  const list = hooksJson.hooks[event] ??= [];
7185
7189
  for (const entry of list) {
7186
7190
  for (const hook2 of entry.hooks ?? []) {
7187
- if (isSameHookCommand2(hook2.command, command)) return "unchanged";
7188
- if (isCaveatCodexHookCommand(hook2.command, subcommand)) {
7191
+ if (isSameHookCommand2(hook2.command, command) && hook2.type === "command" && hook2.timeout === 5 && hook2.timeoutSec === void 0 && hook2.async === false && hook2.statusMessage === null) return "unchanged";
7192
+ if (isSameHookCommand2(hook2.command, command) || isCaveatCodexHookCommand(hook2.command, subcommand)) {
7189
7193
  hook2.command = command;
7190
- hook2.timeoutSec = 5;
7194
+ hook2.type = "command";
7195
+ hook2.timeout = 5;
7196
+ delete hook2.timeoutSec;
7191
7197
  hook2.async = false;
7192
7198
  hook2.statusMessage = null;
7193
7199
  return "added";
@@ -7199,7 +7205,7 @@ function upsertHook2(hooksJson, event, command, subcommand) {
7199
7205
  {
7200
7206
  type: "command",
7201
7207
  command,
7202
- timeoutSec: 5,
7208
+ timeout: 5,
7203
7209
  async: false,
7204
7210
  statusMessage: null
7205
7211
  }
@@ -7513,11 +7519,19 @@ function detectCodexHookInstallation(codexHome) {
7513
7519
  postToolUse: hasCaveatHook(hooksJson, "PostToolUse", eventCommandFragment("post-tool-use")),
7514
7520
  stop: hasCaveatHook(hooksJson, "Stop", eventCommandFragment("stop"))
7515
7521
  };
7522
+ const hasLegacyTimeoutSec = (event, fragment) => hooksJson.hooks?.[event]?.some((entry) => entry.hooks?.some((hook2) => hook2.command.includes(fragment) && hook2.timeoutSec !== void 0)) ?? false;
7523
+ const legacyTimeoutSec = {
7524
+ userPromptSubmit: hasLegacyTimeoutSec("UserPromptSubmit", eventCommandFragment("user-prompt-submit")),
7525
+ postToolUse: hasLegacyTimeoutSec("PostToolUse", eventCommandFragment("post-tool-use")),
7526
+ stop: hasLegacyTimeoutSec("Stop", eventCommandFragment("stop"))
7527
+ };
7516
7528
  const count = Object.values(hooks).filter(Boolean).length;
7529
+ const hasLegacy = Object.values(legacyTimeoutSec).some(Boolean);
7517
7530
  return {
7518
- installation: count === 0 ? "not-installed" : count === 3 ? "installed" : "partial",
7531
+ installation: count === 0 ? "not-installed" : count === 3 && !hasLegacy ? "installed" : "partial",
7519
7532
  hooksPath,
7520
- hooks
7533
+ hooks,
7534
+ legacyTimeoutSec
7521
7535
  };
7522
7536
  }
7523
7537
 
@@ -33834,6 +33848,7 @@ function runDiagnostics(codexHome = process.env.CODEX_HOME ?? join12(homedir3(),
33834
33848
  codexHome,
33835
33849
  hooksPath: installation.hooksPath,
33836
33850
  installedHooks: installation.hooks,
33851
+ legacyTimeoutSec: installation.legacyTimeoutSec,
33837
33852
  evidence: featureOutput.split("\n").find((line) => line.trim().startsWith("hooks")) ?? null
33838
33853
  };
33839
33854
  process.stdout.write(`${JSON.stringify(result, null, 2)}
@@ -34402,7 +34417,7 @@ function codexHooks(codexHome, nodePath, cliScriptPath) {
34402
34417
  const value = JSON.parse(readFileSync7(join14(codexHome, "hooks.json"), "utf8"));
34403
34418
  if (!isRecord2(value) || !isRecord2(value.hooks)) throw Error("config_unreadable");
34404
34419
  const hooks = value.hooks;
34405
- 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)));
34420
+ const present = (event, subcommand) => Array.isArray(hooks[event]) && hooks[event].some((entry) => isRecord2(entry) && Array.isArray(entry.hooks) && entry.hooks.some((item) => isCanonicalCaveatCodexHookEntry(item, subcommand, nodePath, cliScriptPath)));
34406
34421
  return { userPromptSubmit: present("UserPromptSubmit", "user-prompt-submit"), postToolUse: present("PostToolUse", "post-tool-use"), stop: present("Stop", "stop") };
34407
34422
  }
34408
34423
  function sync(own) {