claude-recall 0.29.2 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -123,7 +123,7 @@ tail -5 ~/.claude-recall/hook-logs/hook-dispatcher.log
123
123
 
124
124
  The log should show a `scope [...] → project=your-project` line; `claude-recall kiro doctor` gives a fuller health report.
125
125
 
126
- > **Capture uses Kiro's own LLM — no API key needed.** To decide what's worth remembering, the capture hook classifies each prompt with Kiro's model via a headless `kiro-cli chat --no-interactive` call (through a bundled bare `claude-recall-classifier` agent). So natural statements like "my favourite color is green" are captured without any `ANTHROPIC_API_KEY` and without the `store_memory` MCP tool — which matters under enterprise governance that blocks the MCP server. It runs in a detached background worker, so your turn is never blocked; it spends ~0.06 Kiro credits per prompt. Precedence: `ANTHROPIC_API_KEY` (if you set one) Kiro's LLM → a regex fallback. Tune with `CLAUDE_RECALL_KIRO_MODEL` (default `claude-haiku-4.5`). Details in [docs/kiro-llm-capture.md](docs/kiro-llm-capture.md).
126
+ > **Capture uses Kiro's own LLM — no API key needed.** To decide what's worth remembering, the capture hook classifies each prompt with Kiro's model via a headless `kiro-cli chat --no-interactive` call (through a bundled bare `claude-recall-classifier` agent). So natural statements like "my favourite color is green" are captured without any `ANTHROPIC_API_KEY` and without the `store_memory` MCP tool — which matters under enterprise governance that blocks the MCP server. It runs in a detached background worker, so your turn is never blocked; it spends ~0.06 Kiro credits per prompt. **Under Kiro the included LLM is used first even if you happen to have `ANTHROPIC_API_KEY` set** so a key exported for other tools won't quietly spend your Anthropic credits. Order: Kiro's LLM → `ANTHROPIC_API_KEY` (if present) → regex; set `CLAUDE_RECALL_PREFER_API_KEY=1` to force your key first (e.g. for a stronger model you pay for). Tune the Kiro model with `CLAUDE_RECALL_KIRO_MODEL` (default `claude-haiku-4.5`). Details in [docs/kiro-llm-capture.md](docs/kiro-llm-capture.md).
127
127
 
128
128
  **Option B — MCP tools only (no hooks, works in Kiro's default agent).**
129
129
 
@@ -562,8 +562,9 @@ Runtime behavior can be tuned via environment variables. Defaults are chosen so
562
562
  | Variable | Default | Effect |
563
563
  | ---------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------- |
564
564
  | `CLAUDE_RECALL_DB_PATH` | `~/.claude-recall/` | Database directory. |
565
- | `ANTHROPIC_API_KEY` | _(unset)_ | Enables LLM-based classification (Haiku). Under Kiro, falls back to Kiro's own headless LLM when missing; otherwise falls back to regex. |
565
+ | `ANTHROPIC_API_KEY` | _(unset)_ | LLM classification via Haiku. Not required Claude Code provides it to its hooks, and under Kiro the included LLM is used instead (and is preferred even if this is set). Regex is the final fallback. |
566
566
  | `CLAUDE_RECALL_KIRO_MODEL` | `claude-haiku-4.5` | Model for Kiro-LLM capture classification. Raise to `claude-sonnet-4.6` for steadier judgement at more credits. See [docs/kiro-llm-capture.md](docs/kiro-llm-capture.md). |
567
+ | `CLAUDE_RECALL_PREFER_API_KEY` | _(unset)_ | Under Kiro, force `ANTHROPIC_API_KEY`-based classification ahead of Kiro's included LLM (uses your Anthropic credits — e.g. for a stronger model). No effect under Claude Code. |
567
568
  | `CLAUDE_RECALL_KIRO_LLM_TIMEOUT_MS` | `30000` | Hard cap on the headless `kiro-cli` classify call before the capture worker gives up and falls back to regex. |
568
569
  | `CLAUDE_RECALL_LOAD_BUDGET_TOKENS` | `2000` | Token budget for the `load_rules` payload. Rules are emitted in priority order (corrections → preferences by citation → devops by citation → failures) and dropped rules surface via `search_memory`. |
569
570
  | `CLAUDE_RECALL_AUTO_DEMOTE` | `false` | When `true`, auto-demote rules on MCP boot where `load_count >= CLAUDE_RECALL_DEMOTE_MIN_LOADS`, `cite_count = 0`, and age `> CLAUDE_RECALL_DEMOTE_MIN_AGE_DAYS`. Still reversible via `rules promote <id>`. |
@@ -480,7 +480,9 @@ class KiroCommands {
480
480
  line('⚠', 'kiro-cli not on PATH — capture cannot reach Kiro\'s LLM and falls back to regex.');
481
481
  }
482
482
  if (process.env.ANTHROPIC_API_KEY) {
483
- line('•', 'ANTHROPIC_API_KEY is set — it takes precedence over the Kiro LLM for capture.');
483
+ line('•', process.env.CLAUDE_RECALL_PREFER_API_KEY
484
+ ? 'ANTHROPIC_API_KEY set + CLAUDE_RECALL_PREFER_API_KEY — capture uses your key (your Anthropic credits) before the Kiro LLM.'
485
+ : 'ANTHROPIC_API_KEY is set but under Kiro the included LLM is used first, so it won\'t spend your Anthropic credits. Set CLAUDE_RECALL_PREFER_API_KEY to force the key.');
484
486
  }
485
487
  // --- Hook activity ---
486
488
  console.log('\nRecent hook activity');
@@ -143,14 +143,18 @@ function classifyContentRegex(text) {
143
143
  return null;
144
144
  }
145
145
  /**
146
- * Classify text content — LLM-first, regex fallback.
146
+ * Classify text content — LLM-first, regex fallback. No API key is ever
147
+ * required: each runtime brings its own LLM.
148
+ *
147
149
  * Precedence:
148
- * 1. Claude Haiku via ANTHROPIC_API_KEY (Claude Code sets this automatically).
149
- * 2. Kiro's headless LLM (`kiro-cli chat --no-interactive`) when running under
150
- * Kiro no API key needed. Gated on CLAUDE_RECALL_KIRO_CLASSIFIER, which
151
- * the kiro-capture-worker sets; the classify call is ~3s so it only runs
152
- * from that detached worker, never inline. See docs/kiro-llm-capture.md.
153
- * 3. Regex patterns, if neither LLM path yields a result.
150
+ * - Under Claude Code: Claude Haiku via ANTHROPIC_API_KEY (Claude Code
151
+ * provides this to its hooks) regex.
152
+ * - Under Kiro (CLAUDE_RECALL_KIRO_CLASSIFIER set by the kiro-capture-worker):
153
+ * Kiro's own headless LLM (`kiro-cli chat --no-interactive`) ANTHROPIC_
154
+ * API_KEY if present regex. Kiro's included LLM is preferred so a stray
155
+ * key doesn't spend the user's Anthropic credits; CLAUDE_RECALL_PREFER_API_
156
+ * KEY flips the order. The Kiro call is ~3s, so it runs only from the
157
+ * detached worker, never inline. See docs/kiro-llm-capture.md.
154
158
  */
155
159
  async function classifyContent(text) {
156
160
  // Guard the LLM paths the same way the regex path is guarded: a question or
@@ -167,16 +171,32 @@ async function classifyContent(text) {
167
171
  return result;
168
172
  }
169
173
  async function classifyContentInner(text) {
170
- const llmResult = await (0, llm_classifier_1.classifyWithLLM)(text);
171
- if (llmResult)
172
- return llmResult;
173
- if (process.env.CLAUDE_RECALL_KIRO_CLASSIFIER) {
174
- // Dynamic import keeps kiro-classifier (and child_process) out of the
175
- // module graph for every non-Kiro hook invocation.
176
- const { classifyWithKiro } = await Promise.resolve().then(() => __importStar(require('./kiro-classifier')));
177
- const kiroResult = await classifyWithKiro(text);
178
- if (kiroResult)
179
- return kiroResult;
174
+ const underKiro = !!process.env.CLAUDE_RECALL_KIRO_CLASSIFIER;
175
+ const preferApiKey = !!process.env.CLAUDE_RECALL_PREFER_API_KEY;
176
+ const tryApiKey = () => (0, llm_classifier_1.classifyWithLLM)(text);
177
+ // Dynamic import keeps kiro-classifier (and child_process) out of the module
178
+ // graph for every non-Kiro hook invocation.
179
+ const tryKiro = async () => (await Promise.resolve().then(() => __importStar(require('./kiro-classifier')))).classifyWithKiro(text);
180
+ // Order the two LLM backends. Under Kiro, prefer Kiro's INCLUDED LLM over a
181
+ // stray ANTHROPIC_API_KEY: a key exported for other tools should not silently
182
+ // spend the user's Anthropic credits when Kiro already ships an LLM. Set
183
+ // CLAUDE_RECALL_PREFER_API_KEY to force the key first (e.g. to use a stronger
184
+ // model you pay for). Under Claude Code the Kiro backend isn't available, so
185
+ // the key path is the only LLM classifier.
186
+ const backends = [];
187
+ if (underKiro && !preferApiKey) {
188
+ backends.push(tryKiro, tryApiKey);
189
+ }
190
+ else if (underKiro) {
191
+ backends.push(tryApiKey, tryKiro);
192
+ }
193
+ else {
194
+ backends.push(tryApiKey);
195
+ }
196
+ for (const backend of backends) {
197
+ const result = await backend();
198
+ if (result)
199
+ return result;
180
200
  }
181
201
  return classifyContentRegex(text);
182
202
  }
@@ -93,9 +93,13 @@ Kiro userPromptSubmit
93
93
  └─ regex fallback (only if both above yield nothing)
94
94
  ```
95
95
 
96
- Capture precedence under Kiro becomes: **your own `ANTHROPIC_API_KEY` if you set
97
- oneKiro's headless LLM → regex as a last resort.** In the governance-locked,
98
- no-key setup the Kiro LLM is the primary path and regex is just a safety net.
96
+ Capture precedence under Kiro: **Kiro's included LLM → `ANTHROPIC_API_KEY` if
97
+ present → regex as a last resort.** The Kiro LLM comes first *even when a key is
98
+ set*, so a key exported for other tools never silently spends the user's
99
+ Anthropic credits — Kiro already ships an LLM. `CLAUDE_RECALL_PREFER_API_KEY=1`
100
+ flips the order back to key-first for anyone who deliberately wants to pay for a
101
+ stronger model. (Under Claude Code there is no Kiro backend, so the key path is
102
+ the only LLM classifier — Claude Code provides the key to its hooks.)
99
103
 
100
104
  ### Output parsing
101
105
 
@@ -112,6 +116,7 @@ returns `null`, degrading to regex — a hook must never throw.
112
116
  | `CLAUDE_RECALL_KIRO_CLASSIFIER` | *(set by the worker)* | Enables the Kiro-LLM path in `classifyContent`. Set automatically by `kiro-capture-worker`; never needed by hand. |
113
117
  | `CLAUDE_RECALL_KIRO_MODEL` | `claude-haiku-4.5` | Model for the classify call. Raise to `claude-sonnet-4.6` for steadier judgement at ~3× the credits. |
114
118
  | `CLAUDE_RECALL_KIRO_LLM_TIMEOUT_MS` | `30000` | Hard cap on the headless call before the worker gives up and falls back to regex. |
119
+ | `CLAUDE_RECALL_PREFER_API_KEY` | *(unset)* | Force `ANTHROPIC_API_KEY`-based classification ahead of Kiro's included LLM (opt-in; uses your Anthropic credits). |
115
120
 
116
121
  ## Caveats
117
122
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-recall",
3
- "version": "0.29.2",
3
+ "version": "0.30.0",
4
4
  "description": "Persistent memory for Claude Code and Pi with native Skills integration, automatic capture, failure learning, and project scoping",
5
5
  "main": "dist/index.js",
6
6
  "bin": {