claude-recall 0.28.4 → 0.28.6
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
|
@@ -129,7 +129,17 @@ With Option B the agent has the memory tools (`load_rules`, `store_memory`, `sea
|
|
|
129
129
|
|
|
130
130
|
**Not available under Kiro** with either option (Kiro's hooks expose no transcript): transcript-based failure detection and session-end auto-checkpoints.
|
|
131
131
|
|
|
132
|
-
> **Project scoping
|
|
132
|
+
> **Project scoping & `--resume`.** Memories scope to the **working directory Kiro reports for the session**. `kiro --resume` (with no conversation id) continues your *most-recent conversation* and restores **its** directory — which may be a different project than the one your shell is in. So a resumed session captures into the project of the conversation you're continuing, not wherever you launched Kiro. That's usually what you want (memories follow the conversation), but if you bounce between projects it can surprise you.
|
|
133
|
+
>
|
|
134
|
+
> To force a fixed project regardless of what `--resume` restores, pin it with `CLAUDE_RECALL_PROJECT_ID`. A per-project shell alias makes it seamless:
|
|
135
|
+
>
|
|
136
|
+
> ```bash
|
|
137
|
+
> alias kiro-epic='CLAUDE_RECALL_PROJECT_ID=epic-workflow-cicd kiro-cli chat --agent mcp-agent-env --resume'
|
|
138
|
+
> ```
|
|
139
|
+
>
|
|
140
|
+
> `claude-recall kiro doctor` always prints the resolved project (and whether it's pinned) so you can confirm where memories are landing before trusting it.
|
|
141
|
+
>
|
|
142
|
+
> **Capture works even when the MCP tools are blocked.** Under enterprise governance that restricts MCP to a trusted registry, Kiro drops the claude-recall MCP server — so the agent may say it "has no memory tools." Ignore that: the hooks capture and inject against the local DB regardless. The agent is told this at session start and will confirm it's remembering; only the on-demand tools (the agent calling `search_memory` itself) need an admin to allowlist claude-recall.
|
|
133
143
|
|
|
134
144
|
### Shared Database
|
|
135
145
|
|
|
@@ -545,6 +555,7 @@ Runtime behavior can be tuned via environment variables. Defaults are chosen so
|
|
|
545
555
|
| `CLAUDE_RECALL_ENFORCE_MODE` | `on` | Set to `off` to bypass the search-enforcer hook. |
|
|
546
556
|
| `CLAUDE_RECALL_LLM_TIMEOUT_MS` | `5000` | Timeout for hook-context LLM calls (classification, hindsight hints). Hooks fall back to regex when it fires. |
|
|
547
557
|
| `CLAUDE_RECALL_STOP_DEBOUNCE_MS` | `300000` | Debounce for the heavy Stop-hook pipeline (episodes, session extraction, promotion). Citations still scan every turn. `0` disables. |
|
|
558
|
+
| `CLAUDE_RECALL_PROJECT_ID` | *(cwd)* | Pin the project scope to a fixed id, overriding working-directory detection. Useful when `kiro --resume` restores a different project's directory than you intend. |
|
|
548
559
|
|
|
549
560
|
---
|
|
550
561
|
|
|
@@ -189,14 +189,23 @@ class HookCommands {
|
|
|
189
189
|
// `kiro --resume`d session whose cwd differs from the shell's), and
|
|
190
190
|
// capture (userPromptSubmit) and injection (agentSpawn) could even
|
|
191
191
|
// disagree. Project memories must scope to ONE deterministic project.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
(0, shared_1.hookLog)('hook-dispatcher', `cwd scoping failed (using inherited cwd): ${(0, shared_1.safeErrorMessage)(err)}`);
|
|
192
|
+
try {
|
|
193
|
+
const { ConfigService } = await Promise.resolve().then(() => __importStar(require('../../services/config')));
|
|
194
|
+
const cfg = ConfigService.getInstance();
|
|
195
|
+
const payloadCwd = (input && typeof input.cwd === 'string' && input.cwd.trim()) ? input.cwd : null;
|
|
196
|
+
if (payloadCwd) {
|
|
197
|
+
cfg.updateConfig({ project: { rootDir: payloadCwd } });
|
|
199
198
|
}
|
|
199
|
+
// Diagnostic: record what the runtime declared vs. what this
|
|
200
|
+
// subprocess inherited, and the project we resolved. Makes "which
|
|
201
|
+
// project did this scope to, and why" answerable from the log —
|
|
202
|
+
// the definitive check for `kiro --resume` scoping questions.
|
|
203
|
+
const pin = process.env.CLAUDE_RECALL_PROJECT_ID || process.env.CLAUDE_PROJECT_ID;
|
|
204
|
+
(0, shared_1.hookLog)('hook-dispatcher', `scope [${names.join('+')}]: payload.cwd=${payloadCwd ?? '(none)'} ` +
|
|
205
|
+
`process.cwd=${process.cwd()} pin=${pin ?? '(none)'} → project=${cfg.getProjectId()}`);
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
(0, shared_1.hookLog)('hook-dispatcher', `cwd scoping failed (using inherited cwd): ${(0, shared_1.safeErrorMessage)(err)}`);
|
|
200
209
|
}
|
|
201
210
|
for (const name of names) {
|
|
202
211
|
try {
|
|
@@ -355,7 +355,10 @@ class KiroCommands {
|
|
|
355
355
|
const ms = MemoryService.getInstance();
|
|
356
356
|
const projectId = ConfigService.getInstance().getProjectId();
|
|
357
357
|
const stats = ms.getStats();
|
|
358
|
-
|
|
358
|
+
const pin = process.env.CLAUDE_RECALL_PROJECT_ID || process.env.CLAUDE_PROJECT_ID;
|
|
359
|
+
line('✓', pin
|
|
360
|
+
? `project: ${projectId} (PINNED via ${process.env.CLAUDE_RECALL_PROJECT_ID ? 'CLAUDE_RECALL_PROJECT_ID' : 'CLAUDE_PROJECT_ID'})`
|
|
361
|
+
: `project: ${projectId} (from working directory)`);
|
|
359
362
|
line('•', `total memories (all projects): ${stats.total}`);
|
|
360
363
|
const rules = ms.loadActiveRules(projectId);
|
|
361
364
|
const ruleCount = rules.preferences.length + rules.corrections.length + rules.failures.length + rules.devops.length;
|
package/dist/hooks/kiro-hooks.js
CHANGED
|
@@ -91,16 +91,26 @@ function formatRulesForContext() {
|
|
|
91
91
|
return { body: sections.join('\n\n'), total };
|
|
92
92
|
}
|
|
93
93
|
/**
|
|
94
|
-
* Standing instruction so the agent KNOWS it has persistent memory
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
94
|
+
* Standing instruction so the agent KNOWS it has persistent memory — and,
|
|
95
|
+
* critically, that capture happens via BACKGROUND HOOKS independent of the MCP
|
|
96
|
+
* tools. Under enterprise Kiro governance the claude-recall MCP server is
|
|
97
|
+
* dropped from the toolset, but the userPromptSubmit/preToolUse/postToolUse
|
|
98
|
+
* hooks still write to and read from the local DB. Without the "even without
|
|
99
|
+
* the tools" clause the agent answers "I can't store that, I have no memory
|
|
100
|
+
* tools" — technically true of the TOOL, but false of the system, since the
|
|
101
|
+
* hook already captured it. This is the exact confusion observed in a
|
|
102
|
+
* governance-locked session.
|
|
98
103
|
*/
|
|
99
|
-
const KIRO_MEMORY_DIRECTIVE = 'You have PERSISTENT MEMORY across sessions via Claude Recall
|
|
100
|
-
'
|
|
101
|
-
'
|
|
102
|
-
'
|
|
103
|
-
'
|
|
104
|
+
const KIRO_MEMORY_DIRECTIVE = 'You have PERSISTENT MEMORY across sessions via Claude Recall. Your preferences, corrections, and the ' +
|
|
105
|
+
'rules shown below are captured AUTOMATICALLY by background hooks and injected into your context at the ' +
|
|
106
|
+
'start of every session — this works even if the claude-recall MCP tools (store_memory, search_memory, …) ' +
|
|
107
|
+
'are NOT in your current toolset (e.g. restricted by your organization\'s policy). ' +
|
|
108
|
+
'So when the user says "remember …", "recall …", "store this", states a preference, or corrects you: ' +
|
|
109
|
+
'if the store_memory tool is available, call it and say what you stored; if it is NOT available, simply ' +
|
|
110
|
+
'confirm the point will be remembered — it is already being captured automatically by the hook. ' +
|
|
111
|
+
'NEVER tell the user you have no memory between sessions or cannot persist anything. ' +
|
|
112
|
+
'When the MCP tools ARE available, also use search_memory before decisions where past context may apply. ' +
|
|
113
|
+
'Memories are scoped per project and shared with the user\'s other coding agents.';
|
|
104
114
|
/**
|
|
105
115
|
* agentSpawn — runs once when a Kiro agent activates. Whatever we print is
|
|
106
116
|
* added to the agent's context, so this IS the load_rules call: rules are in
|
package/dist/services/config.js
CHANGED
|
@@ -97,7 +97,13 @@ class ConfigService {
|
|
|
97
97
|
project: {
|
|
98
98
|
rootDir: process.env.CLAUDE_PROJECT_DIR || process.cwd(),
|
|
99
99
|
name: process.env.CLAUDE_PROJECT_NAME,
|
|
100
|
-
|
|
100
|
+
// Explicit project pin. Overrides cwd-based scoping entirely — set it
|
|
101
|
+
// to force every memory into one project regardless of which directory
|
|
102
|
+
// the runtime reports (e.g. `kiro --resume` restores the resumed
|
|
103
|
+
// conversation's directory, which may not be the project you mean to
|
|
104
|
+
// work in). CLAUDE_RECALL_PROJECT_ID is the documented name;
|
|
105
|
+
// CLAUDE_PROJECT_ID is honored for backward compatibility.
|
|
106
|
+
id: process.env.CLAUDE_RECALL_PROJECT_ID || process.env.CLAUDE_PROJECT_ID
|
|
101
107
|
},
|
|
102
108
|
hooks: {
|
|
103
109
|
timeout: parseInt(process.env.CLAUDE_RECALL_HOOK_TIMEOUT || '5000'),
|
package/package.json
CHANGED