eagle-mem 4.7.0 → 4.8.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.
@@ -54,7 +54,7 @@ run_step "Index" bash "$SCRIPTS_DIR/index.sh" "$TARGET_DIR"
54
54
  echo ""
55
55
 
56
56
  # ─── 3. Memory sync ─────────────────────────────────────
57
- eagle_info "Step 3/4: Syncing Claude Code memories, plans, and tasks..."
57
+ eagle_info "Step 3/4: Syncing agent memories, plans, and tasks..."
58
58
  run_step "Memory sync" bash "$SCRIPTS_DIR/memories.sh" sync
59
59
  echo ""
60
60
 
@@ -65,8 +65,8 @@ project_sql=$(eagle_sql_escape "$PROJECT")
65
65
  sessions=$(eagle_db "SELECT COUNT(*) FROM sessions WHERE project = '$project_sql';")
66
66
  summaries=$(eagle_db "SELECT COUNT(*) FROM summaries WHERE project = '$project_sql';")
67
67
  chunks=$(eagle_db "SELECT COUNT(*) FROM code_chunks WHERE project = '$project_sql';")
68
- memories=$(eagle_db "SELECT COUNT(*) FROM claude_memories WHERE project = '$project_sql';")
69
- tasks=$(eagle_db "SELECT COUNT(*) FROM claude_tasks WHERE project = '$project_sql';")
68
+ memories=$(eagle_db "SELECT COUNT(*) FROM agent_memories WHERE project = '$project_sql';")
69
+ tasks=$(eagle_db "SELECT COUNT(*) FROM agent_tasks WHERE project = '$project_sql';")
70
70
 
71
71
  echo ""
72
72
  eagle_kv "Sessions:" "${sessions:-0}"
package/scripts/search.sh CHANGED
@@ -26,7 +26,7 @@ show_help() {
26
26
  echo -e " eagle-mem search ${CYAN}--files${RESET} ${DIM}# frequently modified files${RESET}"
27
27
  echo -e " eagle-mem search ${CYAN}--stats${RESET} ${DIM}# project statistics${RESET}"
28
28
  echo -e " eagle-mem search ${CYAN}--overview${RESET} ${DIM}# project overview${RESET}"
29
- echo -e " eagle-mem search ${CYAN}--memories${RESET} ${DIM}# mirrored Claude memories${RESET}"
29
+ echo -e " eagle-mem search ${CYAN}--memories${RESET} ${DIM}# mirrored agent memories${RESET}"
30
30
  echo -e " eagle-mem search ${CYAN}--tasks${RESET} ${DIM}# in-flight tasks${RESET}"
31
31
  echo ""
32
32
  echo -e " ${BOLD}Options:${RESET}"
@@ -269,7 +269,7 @@ search_stats() {
269
269
  sessions_codex=$(eagle_db "SELECT COUNT(*) FROM sessions WHERE project = '$p' AND agent = 'codex';")
270
270
  summaries=$(eagle_db "SELECT COUNT(*) FROM summaries WHERE project = '$p';")
271
271
  observations=$(eagle_db "SELECT COUNT(*) FROM observations o JOIN sessions s ON s.id = o.session_id WHERE s.project = '$p';")
272
- tasks=$(eagle_db "SELECT COUNT(*) FROM claude_tasks WHERE project = '$p';")
272
+ tasks=$(eagle_db "SELECT COUNT(*) FROM agent_tasks WHERE project = '$p';")
273
273
  local chunks
274
274
  chunks=$(eagle_db "SELECT COUNT(*) FROM code_chunks WHERE project = '$p';")
275
275
 
@@ -349,15 +349,15 @@ search_memories() {
349
349
  exit 1
350
350
  fi
351
351
  local q; q=$(eagle_sql_escape "$sanitized_mq")
352
- local where_match="WHERE claude_memories_fts MATCH '$q'"
352
+ local where_match="WHERE agent_memories_fts MATCH '$q'"
353
353
  if [ "$cross_project" = false ]; then
354
354
  where_match="$where_match AND m.project = '$p'"
355
355
  fi
356
356
 
357
357
  if [ "$json_output" = true ]; then
358
358
  eagle_db_json "SELECT m.memory_name, m.memory_type, m.description, m.project, m.updated_at, m.origin_agent
359
- FROM claude_memories m
360
- JOIN claude_memories_fts f ON f.rowid = m.id
359
+ FROM agent_memories m
360
+ JOIN agent_memories_fts f ON f.rowid = m.id
361
361
  $where_match
362
362
  ORDER BY rank
363
363
  LIMIT $limit;"
@@ -366,8 +366,8 @@ search_memories() {
366
366
 
367
367
  local results
368
368
  results=$(eagle_db "SELECT m.memory_name, m.memory_type, m.description, m.project, m.updated_at, m.origin_agent
369
- FROM claude_memories m
370
- JOIN claude_memories_fts f ON f.rowid = m.id
369
+ FROM agent_memories m
370
+ JOIN agent_memories_fts f ON f.rowid = m.id
371
371
  $where_match
372
372
  ORDER BY rank
373
373
  LIMIT $limit;")
@@ -390,14 +390,14 @@ search_memories() {
390
390
 
391
391
  if [ "$json_output" = true ]; then
392
392
  eagle_db_json "SELECT memory_name, memory_type, description, project, updated_at, origin_agent
393
- FROM claude_memories $where_project
393
+ FROM agent_memories $where_project
394
394
  ORDER BY updated_at DESC LIMIT $limit;"
395
395
  return
396
396
  fi
397
397
 
398
398
  local results
399
399
  results=$(eagle_db "SELECT memory_name, memory_type, description, updated_at, origin_agent
400
- FROM claude_memories $where_project
400
+ FROM agent_memories $where_project
401
401
  ORDER BY updated_at DESC LIMIT $limit;")
402
402
 
403
403
  if [ -z "$results" ]; then
@@ -424,8 +424,10 @@ search_tasks() {
424
424
  local p; p=$(eagle_sql_escape "$project")
425
425
 
426
426
  local where_project=""
427
+ local where_task_project=""
427
428
  if [ "$cross_project" = false ]; then
428
429
  where_project="AND project = '$p'"
430
+ where_task_project="AND t.project = '$p'"
429
431
  fi
430
432
 
431
433
  if [ -n "$query" ]; then
@@ -439,10 +441,10 @@ search_tasks() {
439
441
 
440
442
  if [ "$json_output" = true ]; then
441
443
  eagle_db_json "SELECT t.subject, t.status, t.project, t.updated_at, t.origin_agent
442
- FROM claude_tasks t
443
- JOIN claude_tasks_fts f ON f.rowid = t.id
444
- WHERE claude_tasks_fts MATCH '$q'
445
- ${where_project/AND/AND t.}
444
+ FROM agent_tasks t
445
+ JOIN agent_tasks_fts f ON f.rowid = t.id
446
+ WHERE agent_tasks_fts MATCH '$q'
447
+ $where_task_project
446
448
  ORDER BY rank
447
449
  LIMIT $limit;"
448
450
  return
@@ -450,10 +452,10 @@ search_tasks() {
450
452
 
451
453
  local results
452
454
  results=$(eagle_db "SELECT t.subject, t.status, t.project, t.updated_at, t.origin_agent
453
- FROM claude_tasks t
454
- JOIN claude_tasks_fts f ON f.rowid = t.id
455
- WHERE claude_tasks_fts MATCH '$q'
456
- ${where_project/AND/AND t.}
455
+ FROM agent_tasks t
456
+ JOIN agent_tasks_fts f ON f.rowid = t.id
457
+ WHERE agent_tasks_fts MATCH '$q'
458
+ $where_task_project
457
459
  ORDER BY rank
458
460
  LIMIT $limit;")
459
461
 
@@ -479,7 +481,7 @@ search_tasks() {
479
481
 
480
482
  if [ "$json_output" = true ]; then
481
483
  eagle_db_json "SELECT subject, status, project, updated_at, origin_agent
482
- FROM claude_tasks
484
+ FROM agent_tasks
483
485
  WHERE status IN ('in_progress', 'pending')
484
486
  $where_project
485
487
  ORDER BY CASE status WHEN 'in_progress' THEN 0 ELSE 1 END, updated_at DESC
@@ -489,7 +491,7 @@ search_tasks() {
489
491
 
490
492
  local results
491
493
  results=$(eagle_db "SELECT subject, status, updated_at, origin_agent
492
- FROM claude_tasks
494
+ FROM agent_tasks
493
495
  WHERE status IN ('in_progress', 'pending')
494
496
  $where_project
495
497
  ORDER BY CASE status WHEN 'in_progress' THEN 0 ELSE 1 END, updated_at DESC
@@ -21,7 +21,7 @@ eagle_mem_statusline() {
21
21
  cnt=$(echo ".headers off
22
22
  SELECT COUNT(*) FROM sessions WHERE project = '${proj}';" | sqlite3 "$em_db" 2>/dev/null | tr -d '[:space:]')
23
23
  mem=$(echo ".headers off
24
- SELECT COUNT(*) FROM claude_memories WHERE project = '${proj}';" | sqlite3 "$em_db" 2>/dev/null | tr -d '[:space:]')
24
+ SELECT COUNT(*) FROM agent_memories WHERE project = '${proj}';" | sqlite3 "$em_db" 2>/dev/null | tr -d '[:space:]')
25
25
  cnt=${cnt:-0}; mem=${mem:-0}
26
26
 
27
27
  local R='\033[0m' CYAN='\033[96m' WHT='\033[97m' DIM='\033[2m'
package/scripts/tasks.sh CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env bash
2
2
  # ═══════════════════════════════════════════════════════════
3
- # Eagle Mem — Tasks (read-only viewer of Claude Code tasks)
4
- # Claude Code manages task state via TaskCreate/TaskUpdate;
5
- # Eagle Mem mirrors it and displays it here.
3
+ # Eagle Mem — Tasks
4
+ # Mirrors native task state and lets agents without native task files persist
5
+ # task handoff records directly.
6
6
  # ═══════════════════════════════════════════════════════════
7
7
  set -euo pipefail
8
8
 
@@ -26,22 +26,29 @@ esac
26
26
 
27
27
  project=""
28
28
  json_output=false
29
+ agent=""
29
30
 
30
31
  show_help() {
31
- echo -e " ${BOLD}eagle-mem tasks${RESET} — View mirrored Claude Code tasks"
32
+ echo -e " ${BOLD}eagle-mem tasks${RESET} — View mirrored agent tasks"
32
33
  echo ""
33
34
  echo -e " ${BOLD}Usage:${RESET}"
34
35
  echo -e " eagle-mem tasks ${DIM}# list pending/in-progress tasks${RESET}"
35
36
  echo -e " eagle-mem tasks ${CYAN}list${RESET} ${DIM}# list all tasks${RESET}"
36
37
  echo -e " eagle-mem tasks ${CYAN}completed${RESET} ${DIM}# list completed tasks${RESET}"
37
38
  echo -e " eagle-mem tasks ${CYAN}search${RESET} <query> ${DIM}# search tasks by keyword${RESET}"
39
+ echo -e " eagle-mem tasks ${CYAN}add${RESET} <subject> ${DIM}# create a persistent task record${RESET}"
40
+ echo -e " eagle-mem tasks ${CYAN}update${RESET} <id> ${DIM}# update subject/description/status${RESET}"
41
+ echo -e " eagle-mem tasks ${CYAN}start${RESET} <id> ${DIM}# mark task in_progress${RESET}"
42
+ echo -e " eagle-mem tasks ${CYAN}complete${RESET} <id> ${DIM}# mark task completed${RESET}"
43
+ echo -e " eagle-mem tasks ${CYAN}cancel${RESET} <id> ${DIM}# mark task cancelled${RESET}"
38
44
  echo ""
39
45
  echo -e " ${BOLD}Options:${RESET}"
40
46
  echo -e " ${CYAN}-p, --project${RESET} <name> Project name (default: current dir)"
47
+ echo -e " ${CYAN}--agent${RESET} <name> Source agent (codex or claude-code)"
41
48
  echo -e " ${CYAN}-j, --json${RESET} Output as JSON"
42
49
  echo ""
43
- echo -e " ${DIM}Tasks are managed by Claude Code (TaskCreate/TaskUpdate).${RESET}"
44
- echo -e " ${DIM}Eagle Mem automatically mirrors them for cross-session recall.${RESET}"
50
+ echo -e " ${DIM}Claude Code task files are mirrored automatically.${RESET}"
51
+ echo -e " ${DIM}Codex can persist tasks with this CLI when using the eagle-mem-tasks skill.${RESET}"
45
52
  echo ""
46
53
  exit 0
47
54
  }
@@ -50,6 +57,7 @@ args=()
50
57
  while [ $# -gt 0 ]; do
51
58
  case "$1" in
52
59
  --project|-p) project="$2"; shift 2 ;;
60
+ --agent) agent="$2"; shift 2 ;;
53
61
  --json|-j) json_output=true; shift ;;
54
62
  --help|-h) show_help ;;
55
63
  *) args+=("$1"); shift ;;
@@ -58,6 +66,8 @@ done
58
66
 
59
67
  [ -z "$project" ] && project=$(eagle_project_from_cwd "$(pwd)")
60
68
  project_sql=$(eagle_sql_escape "$project")
69
+ [ -z "$agent" ] && agent=$(eagle_agent_source)
70
+ agent_sql=$(eagle_sql_escape "$agent")
61
71
 
62
72
  # ─── List tasks ───────────────────────────────────────────
63
73
 
@@ -73,7 +83,7 @@ tasks_list() {
73
83
 
74
84
  if [ "$json_output" = true ]; then
75
85
  eagle_db_json "SELECT source_task_id, subject, description, status, blocks, blocked_by, updated_at
76
- FROM claude_tasks
86
+ FROM agent_tasks
77
87
  WHERE project = '$project_sql' $where_status
78
88
  ORDER BY updated_at DESC
79
89
  LIMIT 20;"
@@ -82,7 +92,7 @@ tasks_list() {
82
92
 
83
93
  local results
84
94
  results=$(eagle_db "SELECT source_task_id, subject, status, blocked_by, description
85
- FROM claude_tasks
95
+ FROM agent_tasks
86
96
  WHERE project = '$project_sql' $where_status
87
97
  ORDER BY
88
98
  CASE status WHEN 'in_progress' THEN 0 WHEN 'pending' THEN 1 ELSE 2 END,
@@ -106,7 +116,7 @@ tasks_list() {
106
116
  in_progress) icon="${CYAN}>${RESET}"; marker=" ${CYAN}[in_progress]${RESET}" ;;
107
117
  pending) icon="${DIM}o${RESET}"; marker="" ;;
108
118
  completed) icon="${GREEN}+${RESET}"; marker=" ${DIM}[completed]${RESET}" ;;
109
- deleted) icon="${RED}x${RESET}"; marker=" ${RED}[deleted]${RESET}" ;;
119
+ cancelled) icon="${RED}x${RESET}"; marker=" ${RED}[cancelled]${RESET}" ;;
110
120
  *) icon="$DOT"; marker="" ;;
111
121
  esac
112
122
  if [ "$blocked_by" != "[]" ] && [ -n "$blocked_by" ]; then
@@ -137,9 +147,9 @@ tasks_search() {
137
147
  if [ "$json_output" = true ]; then
138
148
  local query_sql; query_sql=$(eagle_sql_escape "$sanitized_query")
139
149
  eagle_db_json "SELECT t.source_task_id, t.subject, t.status, t.description, t.updated_at
140
- FROM claude_tasks t
141
- JOIN claude_tasks_fts f ON f.rowid = t.id
142
- WHERE claude_tasks_fts MATCH '$query_sql'
150
+ FROM agent_tasks t
151
+ JOIN agent_tasks_fts f ON f.rowid = t.id
152
+ WHERE agent_tasks_fts MATCH '$query_sql'
143
153
  AND t.project = '$project_sql'
144
154
  ORDER BY rank
145
155
  LIMIT 10;"
@@ -149,9 +159,9 @@ tasks_search() {
149
159
  local results
150
160
  local query_sql; query_sql=$(eagle_sql_escape "$sanitized_query")
151
161
  results=$(eagle_db "SELECT t.source_task_id, t.subject, t.status, t.description
152
- FROM claude_tasks t
153
- JOIN claude_tasks_fts f ON f.rowid = t.id
154
- WHERE claude_tasks_fts MATCH '$query_sql'
162
+ FROM agent_tasks t
163
+ JOIN agent_tasks_fts f ON f.rowid = t.id
164
+ WHERE agent_tasks_fts MATCH '$query_sql'
155
165
  AND t.project = '$project_sql'
156
166
  ORDER BY rank
157
167
  LIMIT 10;")
@@ -174,6 +184,162 @@ tasks_search() {
174
184
  echo ""
175
185
  }
176
186
 
187
+ # ─── Mutate task records ──────────────────────────────────
188
+
189
+ tasks_add() {
190
+ local subject="${args[0]:-}"
191
+ if [ -z "$subject" ]; then
192
+ eagle_err "Usage: eagle-mem tasks add <subject> [--desc <text>] [--status pending|in_progress]"
193
+ exit 1
194
+ fi
195
+
196
+ local desc=""
197
+ local status="pending"
198
+ local i=1
199
+ while [ "$i" -lt "${#args[@]}" ]; do
200
+ case "${args[$i]}" in
201
+ --desc|-d)
202
+ i=$((i + 1))
203
+ desc="${args[$i]:-}"
204
+ ;;
205
+ --status)
206
+ i=$((i + 1))
207
+ status="${args[$i]:-pending}"
208
+ ;;
209
+ esac
210
+ i=$((i + 1))
211
+ done
212
+
213
+ case "$status" in
214
+ pending|in_progress|completed|cancelled) ;;
215
+ *)
216
+ eagle_err "Invalid status: $status"
217
+ exit 1
218
+ ;;
219
+ esac
220
+
221
+ local task_id file_path content_hash
222
+ task_id="agent-$(date -u +%Y%m%d%H%M%S)-$$"
223
+ file_path="agent-task://$project/$task_id"
224
+ content_hash=$(printf '%s|%s|%s|%s' "$subject" "$desc" "$status" "$agent" | shasum -a 256 | awk '{print $1}')
225
+
226
+ local tid_sql fp_sql subj_sql desc_sql status_sql hash_sql
227
+ tid_sql=$(eagle_sql_escape "$task_id")
228
+ fp_sql=$(eagle_sql_escape "$file_path")
229
+ subj_sql=$(eagle_sql_escape "$subject")
230
+ desc_sql=$(eagle_sql_escape "$desc")
231
+ status_sql=$(eagle_sql_escape "$status")
232
+ hash_sql=$(eagle_sql_escape "$content_hash")
233
+
234
+ eagle_db_pipe <<SQL
235
+ 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)
236
+ VALUES ('$project_sql', 'manual', '$tid_sql', '$fp_sql', '$subj_sql', '$desc_sql', '', '$status_sql', '[]', '[]', '$hash_sql', '$agent_sql');
237
+ SQL
238
+
239
+ if [ "$json_output" = true ]; then
240
+ jq -nc --arg id "$task_id" --arg subject "$subject" --arg status "$status" --arg agent "$agent" \
241
+ '{source_task_id:$id, subject:$subject, status:$status, origin_agent:$agent}'
242
+ else
243
+ eagle_ok "Task '$task_id' created"
244
+ fi
245
+ }
246
+
247
+ tasks_set_status() {
248
+ local task_id="${args[0]:-}"
249
+ local status="$1"
250
+ if [ -z "$task_id" ]; then
251
+ eagle_err "Usage: eagle-mem tasks $action <id>"
252
+ exit 1
253
+ fi
254
+
255
+ local tid_sql status_sql
256
+ tid_sql=$(eagle_sql_escape "$task_id")
257
+ status_sql=$(eagle_sql_escape "$status")
258
+
259
+ changed=$(eagle_db_pipe <<SQL
260
+ UPDATE agent_tasks
261
+ SET status = '$status_sql',
262
+ origin_agent = COALESCE(NULLIF('$agent_sql', ''), origin_agent),
263
+ updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
264
+ WHERE project = '$project_sql' AND source_task_id = '$tid_sql';
265
+ SELECT changes();
266
+ SQL
267
+ )
268
+
269
+ if [ "${changed:-0}" -gt 0 ] 2>/dev/null; then
270
+ eagle_ok "Task '$task_id' marked $status"
271
+ else
272
+ eagle_err "Task not found: $task_id"
273
+ exit 1
274
+ fi
275
+ }
276
+
277
+ tasks_update() {
278
+ local task_id="${args[0]:-}"
279
+ if [ -z "$task_id" ]; then
280
+ eagle_err "Usage: eagle-mem tasks update <id> [--subject <text>] [--desc <text>] [--status <status>]"
281
+ exit 1
282
+ fi
283
+
284
+ local subject="" desc="" status=""
285
+ local i=1
286
+ while [ "$i" -lt "${#args[@]}" ]; do
287
+ case "${args[$i]}" in
288
+ --subject)
289
+ i=$((i + 1))
290
+ subject="${args[$i]:-}"
291
+ ;;
292
+ --desc|-d)
293
+ i=$((i + 1))
294
+ desc="${args[$i]:-}"
295
+ ;;
296
+ --status)
297
+ i=$((i + 1))
298
+ status="${args[$i]:-}"
299
+ ;;
300
+ esac
301
+ i=$((i + 1))
302
+ done
303
+
304
+ if [ -n "$status" ]; then
305
+ case "$status" in
306
+ pending|in_progress|completed|cancelled) ;;
307
+ *)
308
+ eagle_err "Invalid status: $status"
309
+ exit 1
310
+ ;;
311
+ esac
312
+ fi
313
+
314
+ local tid_sql subj_sql desc_sql status_sql hash_sql
315
+ tid_sql=$(eagle_sql_escape "$task_id")
316
+ subj_sql=$(eagle_sql_escape "$subject")
317
+ desc_sql=$(eagle_sql_escape "$desc")
318
+ status_sql=$(eagle_sql_escape "$status")
319
+ hash_sql=$(printf '%s|%s|%s|%s|%s' "$task_id" "$subject" "$desc" "$status" "$agent" | shasum -a 256 | awk '{print $1}')
320
+ hash_sql=$(eagle_sql_escape "$hash_sql")
321
+
322
+ changed=$(eagle_db_pipe <<SQL
323
+ UPDATE agent_tasks
324
+ SET subject = CASE WHEN '$subj_sql' != '' THEN '$subj_sql' ELSE subject END,
325
+ description = CASE WHEN '$desc_sql' != '' THEN '$desc_sql' ELSE description END,
326
+ status = CASE WHEN '$status_sql' != '' THEN '$status_sql' ELSE status END,
327
+ origin_agent = COALESCE(NULLIF('$agent_sql', ''), origin_agent),
328
+ content_hash = '$hash_sql',
329
+ updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
330
+ WHERE project = '$project_sql' AND source_task_id = '$tid_sql';
331
+ SELECT changes();
332
+ SQL
333
+ )
334
+
335
+ if [ "${changed:-0}" -gt 0 ] 2>/dev/null; then
336
+ eagle_ok "Task '$task_id' updated"
337
+ else
338
+ eagle_err "Task not found: $task_id"
339
+ exit 1
340
+ fi
341
+ }
342
+
177
343
  # ─── Dispatch ─────────────────────────────────────────────
178
344
 
179
345
  case "$action" in
@@ -181,6 +347,11 @@ case "$action" in
181
347
  pending) tasks_list "pending" ;;
182
348
  completed) tasks_list "completed" ;;
183
349
  search) tasks_search ;;
350
+ add) tasks_add ;;
351
+ update) tasks_update ;;
352
+ start) tasks_set_status "in_progress" ;;
353
+ complete) tasks_set_status "completed" ;;
354
+ cancel) tasks_set_status "cancelled" ;;
184
355
  --help|-h) show_help ;;
185
356
  *)
186
357
  eagle_err "Unknown action: $action"
package/scripts/update.sh CHANGED
@@ -119,7 +119,26 @@ if [ "$claude_found" = true ] && [ -d "$PACKAGE_DIR/skills" ]; then
119
119
  [ -L "$dst" ] && rm "$dst"
120
120
  ln -sf "$skill_dir" "$dst"
121
121
  done
122
- eagle_ok "Skills updated"
122
+ eagle_ok "Claude skills updated"
123
+ fi
124
+
125
+ if [ "$codex_found" = true ] && [ -d "$PACKAGE_DIR/skills" ]; then
126
+ mkdir -p "$EAGLE_CODEX_SKILLS_DIR"
127
+ find "$EAGLE_CODEX_SKILLS_DIR" -maxdepth 1 -name "eagle-mem-*" -type l 2>/dev/null | while read -r existing; do
128
+ skill_name=$(basename "$existing")
129
+ if [ ! -d "$PACKAGE_DIR/skills/$skill_name" ]; then
130
+ rm "$existing"
131
+ eagle_ok "Removed stale Codex skill: $skill_name"
132
+ fi
133
+ done
134
+ for skill_dir in "$PACKAGE_DIR"/skills/*/; do
135
+ [ ! -d "$skill_dir" ] && continue
136
+ skill_name=$(basename "$skill_dir")
137
+ dst="$EAGLE_CODEX_SKILLS_DIR/$skill_name"
138
+ [ -L "$dst" ] && rm "$dst"
139
+ ln -sf "$skill_dir" "$dst"
140
+ done
141
+ eagle_ok "Codex skills updated"
123
142
  fi
124
143
 
125
144
  # ─── Backfill project names ───────────────────────────────
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: eagle-mem-memories
3
3
  description: >
4
- View and sync Claude Code auto-memories, plans, and tasks mirrored in Eagle Mem. Use when:
5
- 'eagle memories', 'show memories', 'sync memories', 'what does claude remember',
4
+ View and sync Claude Code and Codex memories, plans, and tasks mirrored in Eagle Mem. Use when:
5
+ 'eagle memories', 'show memories', 'sync memories', 'what does the agent remember',
6
6
  'show plans', 'show tasks', 'mirror memories', 'onboard project',
7
7
  'what did past sessions learn'. Uses the eagle-mem CLI.
8
8
  ---
@@ -11,9 +11,9 @@ description: >
11
11
 
12
12
  ## Purpose
13
13
 
14
- **For the user:** Claude Code remembers across sessions. Decisions, preferences, project context, and architectural plans survive session boundaries. The user never has to re-explain "we chose Postgres because..." or "don't use semicolons in this project."
14
+ **For the user:** Claude Code and Codex remember across sessions. Decisions, preferences, project context, and architectural plans survive session boundaries. The user never has to re-explain "we chose Postgres because..." or "don't use semicolons in this project."
15
15
 
16
- **For you (Claude Code):** Access to what past Claude sessions learned about this project. Memories tell you *why* decisions were made. Plans tell you *what's coming*. Tasks tell you *what's in flight*. Together they're the knowledge bridge that makes you effective from message one.
16
+ **For you:** Access to what past Claude Code and Codex sessions learned about this project. Memories tell you *why* decisions were made. Plans tell you *what's coming*. Tasks tell you *what's in flight*. Together they're the knowledge bridge that makes you effective from message one.
17
17
 
18
18
  ## Judgment
19
19
 
@@ -21,7 +21,7 @@ description: >
21
21
  - The user references a past decision ("remember when we decided to...", "what's our convention for...")
22
22
  - You're about to make an architectural or style choice -- memories may record the user's preference
23
23
  - You need project context that isn't in CLAUDE.md or README (relationships between services, deployment quirks, naming conventions)
24
- - The user asks "what does Claude remember about X?"
24
+ - The user asks "what does Claude/Codex/Eagle Mem remember about X?"
25
25
 
26
26
  **Check plans when:**
27
27
  - The user asks about upcoming work or roadmap
@@ -43,21 +43,21 @@ description: >
43
43
 
44
44
  ### 1. Know the three data types
45
45
 
46
- **Memories** -- Claude Code's auto-memory files (`~/.claude/projects/*/memory/*.md`). These contain user preferences, project conventions, and feedback. Each has a name, type (user/feedback/project/reference), and description.
46
+ **Memories** -- Claude Code auto-memory files (`~/.claude/projects/*/memory/*.md`) plus top-level Codex memory files (`~/.codex/memories/MEMORY.md`, `memory_summary.md`). These contain user preferences, project conventions, and feedback. Each mirrored row is source-attributed.
47
47
  ```bash
48
48
  eagle-mem memories list # all memories
49
49
  eagle-mem memories search "typescript" # FTS5 search
50
50
  eagle-mem memories show <file_path> # full content
51
51
  ```
52
52
 
53
- **Plans** -- Claude Code's plan files (`~/.claude/plans/*.md`). Multi-step strategies for complex work. Each has a title, optional project tag, and markdown content.
53
+ **Plans** -- Claude Code plan files (`~/.claude/plans/*.md`) and future agent plan files as support is added. Multi-step strategies for complex work. Each has a title, optional project tag, and markdown content.
54
54
  ```bash
55
55
  eagle-mem memories plans # all plans
56
56
  eagle-mem memories plans search "migration"
57
57
  eagle-mem memories plans show <file_path>
58
58
  ```
59
59
 
60
- **Tasks** -- Claude Code's task JSON (`~/.claude/tasks/<session>/*.json`). Individual units of work with status tracking (pending/in_progress/completed).
60
+ **Tasks** -- Claude Code task JSON (`~/.claude/tasks/<session>/*.json`) and Eagle Mem task records created directly by agents such as Codex. Individual units of work with status tracking (pending/in_progress/completed).
61
61
  ```bash
62
62
  eagle-mem memories tasks # all tasks
63
63
  eagle-mem memories tasks search "refactor"
@@ -68,13 +68,13 @@ eagle-mem memories tasks show <file_path>
68
68
 
69
69
  Two paths feed the mirror:
70
70
 
71
- **Real-time (PostToolUse hook).** Every time Claude Code writes or edits a memory file, plan file, or creates/updates a task, the hook intercepts it and mirrors it into Eagle Mem's SQLite with FTS5 indexing. This happens automatically -- no user action needed.
71
+ **Real-time hooks.** Claude Code memory/plan/task files are mirrored when written. Codex sessions are captured through SessionStart/UserPromptSubmit/PostToolUse/Stop hooks, and important durable facts should be placed in `<eagle-summary>` so they become shared recall.
72
72
 
73
- **Backfill (sync command).** For memories, plans, and tasks that existed before Eagle Mem was installed, or that were written outside a Claude Code session:
73
+ **Backfill (sync command).** For memories, plans, and tasks that existed before Eagle Mem was installed, or that were written outside a hooked session:
74
74
  ```bash
75
75
  eagle-mem memories sync
76
76
  ```
77
- This scans all three directories, hashes each file, skips unchanged ones, and mirrors anything new or modified. It also backfills project names from Claude Code transcripts. Safe to run repeatedly -- content-hash dedup prevents double-insertion.
77
+ This scans known Claude Code and Codex memory/task locations, hashes each file, skips unchanged ones, and mirrors anything new or modified. It also backfills project names from transcripts. Safe to run repeatedly -- content-hash dedup prevents double-insertion.
78
78
 
79
79
  ### 3. Search effectively
80
80
 
@@ -104,7 +104,7 @@ This asymmetry is intentional but easy to forget. If you're getting too many irr
104
104
 
105
105
  ### 5. Onboard an existing project
106
106
 
107
- When Eagle Mem is installed on a project that already has Claude Code history:
107
+ When Eagle Mem is installed on a project that already has Claude Code or Codex history:
108
108
  ```bash
109
109
  eagle-mem memories sync
110
110
  ```
@@ -117,7 +117,7 @@ After sync or after expecting the hook to fire:
117
117
  eagle-mem memories list # should show recent memories
118
118
  eagle-mem search --stats # check counts are non-zero
119
119
  ```
120
- If memories list is empty after sync, check that `~/.claude/projects/` contains memory files for this project. If the hook isn't capturing new writes, check that PostToolUse hook is registered in settings.json.
120
+ If memories list is empty after sync, check that `~/.claude/projects/` or `~/.codex/memories/` contains memory files. If the hook isn't capturing new writes, check Claude Code `settings.json` or Codex `hooks.json`.
121
121
 
122
122
  ## What makes a good memory lookup
123
123