eagle-mem 4.9.2 → 4.9.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
@@ -152,6 +152,10 @@ Eagle Mem prevents Claude from repeating past mistakes:
152
152
  | `eagle-mem scan` | Scan codebase and generate overview |
153
153
  | `eagle-mem index` | Index source files for FTS5 code search |
154
154
 
155
+ ### v4.9.3 Patch
156
+
157
+ Follow-up hardening for the v4.9.2 project-key repair: Claude transcript workspace detection now reads complete early JSONL records instead of a fixed byte slice, so large SessionStart hook context cannot hide the first `cwd`. Metadata-only memory/plan/task repairs also avoid touching FTS-indexed columns, preventing SQLite FTS update triggers from firing during safe project/source rekeys.
158
+
155
159
  ### v4.9.2 Patch
156
160
 
157
161
  Nested-repo Claude Code projects now use one stable project key. When a Claude workspace contains a git repo subdirectory, hooks prefer the Claude transcript workspace root while repo-local CLI commands can still use git-root keys where appropriate. Memory sync and backfill also repair unchanged memory rows whose content hash stayed the same but whose project key was stale. FTS5 update triggers now ignore metadata-only project rekeys, avoiding SQLite virtual-table errors during safe repairs.
package/lib/common.sh CHANGED
@@ -210,15 +210,12 @@ eagle_transcript_first_cwd() {
210
210
  local transcript_path="${1:-}"
211
211
  [ -f "$transcript_path" ] || return 1
212
212
 
213
- local sample
214
- sample=$(dd if="$transcript_path" bs=65536 count=4 2>/dev/null)
215
- [ -n "$sample" ] || return 1
216
-
217
- printf '%s\n' "$sample" | sed -nE '/"cwd"[[:space:]]*:/ {
218
- s/.*"cwd"[[:space:]]*:[[:space:]]*"([^"]*)".*/\1/
219
- p
220
- q
221
- }'
213
+ local cwd
214
+ cwd=$(sed -n '1,200p' "$transcript_path" 2>/dev/null \
215
+ | jq -r 'select((.cwd? // "") != "") | .cwd' 2>/dev/null \
216
+ | awk 'NF { print; exit }' || true)
217
+ [ -n "$cwd" ] || return 1
218
+ printf '%s\n' "$cwd"
222
219
  }
223
220
 
224
221
  eagle_project_from_claude_project_dir() {
package/lib/db-mirrors.sh CHANGED
@@ -63,22 +63,32 @@ eagle_capture_agent_memory() {
63
63
  agent_sql=$(eagle_sql_escape "$agent")
64
64
 
65
65
  eagle_db_pipe <<SQL
66
- INSERT INTO agent_memories (project, file_path, memory_name, description, memory_type, content, content_hash, origin_session_id, origin_agent)
67
- VALUES ('$proj_sql', '$fp_sql', '$name_sql', '$desc_sql', '$type_sql', '$content_sql', '$hash_sql', '$origin_sql', '$agent_sql')
68
- ON CONFLICT(file_path) DO UPDATE SET
69
- memory_name = excluded.memory_name,
70
- description = excluded.description,
71
- memory_type = excluded.memory_type,
72
- content = excluded.content,
73
- content_hash = excluded.content_hash,
74
- origin_session_id = COALESCE(NULLIF(excluded.origin_session_id, ''), agent_memories.origin_session_id),
75
- origin_agent = COALESCE(NULLIF(excluded.origin_agent, ''), agent_memories.origin_agent),
76
- project = CASE WHEN excluded.project != '' THEN excluded.project ELSE agent_memories.project END,
77
- updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
78
- WHERE agent_memories.content_hash != excluded.content_hash
79
- OR (excluded.project != '' AND agent_memories.project != excluded.project)
80
- OR (excluded.origin_session_id != '' AND agent_memories.origin_session_id != excluded.origin_session_id)
81
- OR (excluded.origin_agent != '' AND agent_memories.origin_agent != excluded.origin_agent);
66
+ INSERT OR IGNORE INTO agent_memories (project, file_path, memory_name, description, memory_type, content, content_hash, origin_session_id, origin_agent)
67
+ VALUES ('$proj_sql', '$fp_sql', '$name_sql', '$desc_sql', '$type_sql', '$content_sql', '$hash_sql', '$origin_sql', '$agent_sql');
68
+
69
+ UPDATE agent_memories
70
+ SET memory_name = '$name_sql',
71
+ description = '$desc_sql',
72
+ memory_type = '$type_sql',
73
+ content = '$content_sql',
74
+ content_hash = '$hash_sql',
75
+ origin_session_id = COALESCE(NULLIF('$origin_sql', ''), origin_session_id),
76
+ origin_agent = COALESCE(NULLIF('$agent_sql', ''), origin_agent),
77
+ project = CASE WHEN '$proj_sql' != '' THEN '$proj_sql' ELSE project END,
78
+ updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
79
+ WHERE file_path = '$fp_sql'
80
+ AND content_hash != '$hash_sql';
81
+
82
+ UPDATE agent_memories
83
+ SET origin_session_id = COALESCE(NULLIF('$origin_sql', ''), origin_session_id),
84
+ origin_agent = COALESCE(NULLIF('$agent_sql', ''), origin_agent),
85
+ project = CASE WHEN '$proj_sql' != '' THEN '$proj_sql' ELSE project END,
86
+ updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
87
+ WHERE file_path = '$fp_sql'
88
+ AND content_hash = '$hash_sql'
89
+ AND (('$proj_sql' != '' AND project != '$proj_sql')
90
+ OR ('$origin_sql' != '' AND origin_session_id != '$origin_sql')
91
+ OR ('$agent_sql' != '' AND origin_agent != '$agent_sql'));
82
92
  SQL
83
93
  }
84
94
 
@@ -151,20 +161,30 @@ eagle_capture_agent_plan() {
151
161
  agent_sql=$(eagle_sql_escape "$agent")
152
162
 
153
163
  eagle_db_pipe <<SQL
154
- INSERT INTO agent_plans (project, file_path, title, content, content_hash, origin_session_id, origin_agent)
155
- VALUES ('$proj_sql', '$fp_sql', '$title_sql', '$content_sql', '$hash_sql', '$origin_sql', '$agent_sql')
156
- ON CONFLICT(file_path) DO UPDATE SET
157
- title = excluded.title,
158
- content = excluded.content,
159
- content_hash = excluded.content_hash,
160
- origin_session_id = COALESCE(NULLIF(excluded.origin_session_id, ''), agent_plans.origin_session_id),
161
- origin_agent = COALESCE(NULLIF(excluded.origin_agent, ''), agent_plans.origin_agent),
162
- project = CASE WHEN excluded.project != '' THEN excluded.project ELSE agent_plans.project END,
163
- updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
164
- WHERE agent_plans.content_hash != excluded.content_hash
165
- OR (excluded.project != '' AND agent_plans.project != excluded.project)
166
- OR (excluded.origin_session_id != '' AND agent_plans.origin_session_id != excluded.origin_session_id)
167
- OR (excluded.origin_agent != '' AND agent_plans.origin_agent != excluded.origin_agent);
164
+ INSERT OR IGNORE INTO agent_plans (project, file_path, title, content, content_hash, origin_session_id, origin_agent)
165
+ VALUES ('$proj_sql', '$fp_sql', '$title_sql', '$content_sql', '$hash_sql', '$origin_sql', '$agent_sql');
166
+
167
+ UPDATE agent_plans
168
+ SET title = '$title_sql',
169
+ content = '$content_sql',
170
+ content_hash = '$hash_sql',
171
+ origin_session_id = COALESCE(NULLIF('$origin_sql', ''), origin_session_id),
172
+ origin_agent = COALESCE(NULLIF('$agent_sql', ''), origin_agent),
173
+ project = CASE WHEN '$proj_sql' != '' THEN '$proj_sql' ELSE project END,
174
+ updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
175
+ WHERE file_path = '$fp_sql'
176
+ AND content_hash != '$hash_sql';
177
+
178
+ UPDATE agent_plans
179
+ SET origin_session_id = COALESCE(NULLIF('$origin_sql', ''), origin_session_id),
180
+ origin_agent = COALESCE(NULLIF('$agent_sql', ''), origin_agent),
181
+ project = CASE WHEN '$proj_sql' != '' THEN '$proj_sql' ELSE project END,
182
+ updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
183
+ WHERE file_path = '$fp_sql'
184
+ AND content_hash = '$hash_sql'
185
+ AND (('$proj_sql' != '' AND project != '$proj_sql')
186
+ OR ('$origin_sql' != '' AND origin_session_id != '$origin_sql')
187
+ OR ('$agent_sql' != '' AND origin_agent != '$agent_sql'));
168
188
  SQL
169
189
  }
170
190
 
@@ -252,22 +272,31 @@ eagle_capture_agent_task() {
252
272
  agent_sql=$(eagle_sql_escape "$agent")
253
273
 
254
274
  eagle_db_pipe <<SQL
255
- INSERT INTO agent_tasks (project, source_session_id, source_task_id, file_path, subject, description, active_form, status, blocks, blocked_by, content_hash, origin_agent)
256
- VALUES ('$proj_sql', '$sid_sql', '$tid_sql', '$fp_sql', '$subj_sql', '$desc_sql', '$af_sql', '$status_sql', '$blocks_sql', '$bb_sql', '$hash_sql', '$agent_sql')
257
- ON CONFLICT(file_path) DO UPDATE SET
258
- subject = excluded.subject,
259
- description = excluded.description,
260
- active_form = excluded.active_form,
261
- status = excluded.status,
262
- blocks = excluded.blocks,
263
- blocked_by = excluded.blocked_by,
264
- content_hash = excluded.content_hash,
265
- origin_agent = excluded.origin_agent,
266
- project = CASE WHEN excluded.project != '' THEN excluded.project ELSE agent_tasks.project END,
267
- updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
268
- WHERE agent_tasks.content_hash != excluded.content_hash
269
- OR (excluded.project != '' AND agent_tasks.project != excluded.project)
270
- OR (excluded.origin_agent != '' AND agent_tasks.origin_agent != excluded.origin_agent);
275
+ INSERT OR IGNORE INTO agent_tasks (project, source_session_id, source_task_id, file_path, subject, description, active_form, status, blocks, blocked_by, content_hash, origin_agent)
276
+ VALUES ('$proj_sql', '$sid_sql', '$tid_sql', '$fp_sql', '$subj_sql', '$desc_sql', '$af_sql', '$status_sql', '$blocks_sql', '$bb_sql', '$hash_sql', '$agent_sql');
277
+
278
+ UPDATE agent_tasks
279
+ SET subject = '$subj_sql',
280
+ description = '$desc_sql',
281
+ active_form = '$af_sql',
282
+ status = '$status_sql',
283
+ blocks = '$blocks_sql',
284
+ blocked_by = '$bb_sql',
285
+ content_hash = '$hash_sql',
286
+ origin_agent = COALESCE(NULLIF('$agent_sql', ''), origin_agent),
287
+ project = CASE WHEN '$proj_sql' != '' THEN '$proj_sql' ELSE project END,
288
+ updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
289
+ WHERE file_path = '$fp_sql'
290
+ AND content_hash != '$hash_sql';
291
+
292
+ UPDATE agent_tasks
293
+ SET origin_agent = COALESCE(NULLIF('$agent_sql', ''), origin_agent),
294
+ project = CASE WHEN '$proj_sql' != '' THEN '$proj_sql' ELSE project END,
295
+ updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
296
+ WHERE file_path = '$fp_sql'
297
+ AND content_hash = '$hash_sql'
298
+ AND (('$proj_sql' != '' AND project != '$proj_sql')
299
+ OR ('$agent_sql' != '' AND origin_agent != '$agent_sql'));
271
300
  SQL
272
301
  }
273
302
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eagle-mem",
3
- "version": "4.9.2",
3
+ "version": "4.9.3",
4
4
  "description": "Shared memory, release guardrails, RTK token protection, and worker lanes for Claude Code and Codex",
5
5
  "bin": {
6
6
  "eagle-mem": "bin/eagle-mem"