eagle-mem 4.9.5 → 4.9.7

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.
@@ -26,6 +26,8 @@ esac
26
26
  project=""
27
27
  limit=20
28
28
  query=""
29
+ raw_output=false
30
+ cross_project=false
29
31
 
30
32
  show_help() {
31
33
  echo -e " ${BOLD}eagle-mem memories${RESET} — Agent memory, plan & task mirror"
@@ -44,8 +46,10 @@ show_help() {
44
46
  echo -e " eagle-mem memories sync ${DIM}# backfill memories + plans + tasks${RESET}"
45
47
  echo ""
46
48
  echo -e " ${BOLD}Options:${RESET}"
47
- echo -e " ${CYAN}-p, --project${RESET} <name> Filter by project"
49
+ echo -e " ${CYAN}-p, --project${RESET} <name> Filter by project (default: current project)"
48
50
  echo -e " ${CYAN}-l, --limit${RESET} <N> Max results (default: 20)"
51
+ echo -e " ${CYAN}-a, --all${RESET} Show all projects"
52
+ echo -e " ${CYAN}--raw, --debug${RESET} Show source paths, sessions, and raw backing data"
49
53
  echo ""
50
54
  echo -e " ${BOLD}How it works:${RESET}"
51
55
  echo -e " ${DOT} Eagle Mem mirrors agent memory, plan, and task writes"
@@ -74,6 +78,8 @@ while [ $# -gt 0 ]; do
74
78
  case "$1" in
75
79
  --project|-p) project="$2"; shift 2 ;;
76
80
  --limit|-l) limit="$2"; shift 2 ;;
81
+ --all|-a) cross_project=true; shift ;;
82
+ --raw|--debug) raw_output=true; shift ;;
77
83
  --help|-h) show_help ;;
78
84
  *)
79
85
  if [ -z "$query" ]; then
@@ -86,6 +92,39 @@ while [ $# -gt 0 ]; do
86
92
  esac
87
93
  done
88
94
 
95
+ if [ -z "$project" ] && [ "$cross_project" = false ]; then
96
+ project=$(eagle_project_from_cwd "$(pwd)")
97
+ fi
98
+
99
+ eagle_age_label() {
100
+ local updated="${1:-}"
101
+ [ -z "$updated" ] && { printf 'unknown'; return; }
102
+ local days
103
+ days=$(eagle_db "SELECT CAST(julianday('now') - julianday('$(eagle_sql_escape "$updated")') AS INTEGER);" 2>/dev/null | awk 'NF {print; exit}')
104
+ if [ -z "$days" ]; then
105
+ printf 'unknown'
106
+ elif [ "$days" -le 0 ] 2>/dev/null; then
107
+ printf 'Fresh'
108
+ elif [ "$days" -le 14 ] 2>/dev/null; then
109
+ printf '%sd old' "$days"
110
+ elif [ "$days" -le 45 ] 2>/dev/null; then
111
+ printf 'Recent'
112
+ else
113
+ printf 'Older'
114
+ fi
115
+ }
116
+
117
+ eagle_print_wrapped_block() {
118
+ local text="${1:-}" indent="${2:- }" max_chars="${3:-1200}"
119
+ [ -z "$text" ] && return
120
+ printf '%s' "$text" | head -c "$max_chars" | while IFS= read -r line; do
121
+ printf '%s%s\n' "$indent" "$line"
122
+ done
123
+ if [ "${#text}" -gt "$max_chars" ] 2>/dev/null; then
124
+ printf '%s%s\n' "$indent" "..."
125
+ fi
126
+ }
127
+
89
128
  # ─── Actions ─────────────────────────────────────────────
90
129
 
91
130
  memories_list() {
@@ -116,9 +155,14 @@ memories_list() {
116
155
  reference) type_color="$BLUE" ;;
117
156
  esac
118
157
 
119
- echo -e " ${BOLD}${name}${RESET} ${type_color}[${mtype}]${RESET} ${DIM}[$(eagle_agent_label "$origin_agent")]${RESET}"
158
+ local age_label
159
+ age_label=$(eagle_age_label "$updated")
160
+ echo -e " ${BOLD}${name}${RESET} ${type_color}[${mtype}]${RESET} ${DIM}[$(eagle_agent_label "$origin_agent")][$age_label]${RESET}"
120
161
  [ -n "$desc" ] && echo -e " ${DIM}${desc}${RESET}"
121
- echo -e " ${DIM}updated: ${updated}${RESET}"
162
+ if [ "$raw_output" = true ]; then
163
+ echo -e " ${DIM}file: $_fp${RESET}"
164
+ echo -e " ${DIM}updated: ${updated}${RESET}"
165
+ fi
122
166
  echo ""
123
167
  done <<< "$result"
124
168
 
@@ -158,12 +202,17 @@ memories_search() {
158
202
  reference) type_color="$BLUE" ;;
159
203
  esac
160
204
 
161
- echo -e " ${BOLD}${name}${RESET} ${type_color}[${mtype}]${RESET} ${DIM}[$(eagle_agent_label "$origin_agent")]${RESET}"
205
+ local age_label
206
+ age_label=$(eagle_age_label "$updated")
207
+ echo -e " ${BOLD}${name}${RESET} ${type_color}[${mtype}]${RESET} ${DIM}[$(eagle_agent_label "$origin_agent")][$age_label]${RESET}"
162
208
  [ -n "$desc" ] && echo -e " ${DIM}${desc}${RESET}"
163
209
  local snippet
164
210
  snippet=$(printf '%s' "$content" | head -c 200)
165
211
  [ -n "$snippet" ] && echo -e " ${snippet}"
166
- echo -e " ${DIM}updated: ${updated}${RESET}"
212
+ if [ "$raw_output" = true ]; then
213
+ echo -e " ${DIM}file: $_fp${RESET}"
214
+ echo -e " ${DIM}updated: ${updated}${RESET}"
215
+ fi
167
216
  echo ""
168
217
  done <<< "$result"
169
218
 
@@ -177,37 +226,63 @@ memories_show() {
177
226
  exit 1
178
227
  fi
179
228
 
180
- local meta
181
- meta=$(eagle_db "SELECT memory_name, memory_type, description, file_path, updated_at, origin_session_id, origin_agent
182
- FROM agent_memories WHERE file_path = '$(eagle_sql_escape "$query")';")
229
+ local query_sql project_filter meta_json
230
+ query_sql=$(eagle_sql_escape "$query")
231
+ project_filter=""
232
+ if [ -n "$project" ]; then
233
+ project_filter="AND project = '$(eagle_sql_escape "$project")'"
234
+ fi
183
235
 
184
- if [ -z "$meta" ]; then
236
+ meta_json=$(eagle_db_json "SELECT memory_name, memory_type, description, content, file_path, updated_at, origin_session_id, origin_agent
237
+ FROM agent_memories
238
+ WHERE (file_path = '$query_sql' OR memory_name = '$query_sql')
239
+ $project_filter
240
+ ORDER BY updated_at DESC
241
+ LIMIT 1;")
242
+
243
+ if [ -z "$meta_json" ] || [ "$(printf '%s' "$meta_json" | jq 'length' 2>/dev/null)" = "0" ]; then
185
244
  eagle_err "Memory not found: $query"
186
245
  exit 1
187
246
  fi
188
247
 
189
- IFS='|' read -r name mtype desc fp updated origin origin_agent <<< "$meta"
248
+ name=$(printf '%s' "$meta_json" | jq -r '.[0].memory_name // ""')
249
+ mtype=$(printf '%s' "$meta_json" | jq -r '.[0].memory_type // ""')
250
+ desc=$(printf '%s' "$meta_json" | jq -r '.[0].description // ""')
251
+ content=$(printf '%s' "$meta_json" | jq -r '.[0].content // ""')
252
+ fp=$(printf '%s' "$meta_json" | jq -r '.[0].file_path // ""')
253
+ updated=$(printf '%s' "$meta_json" | jq -r '.[0].updated_at // ""')
254
+ origin=$(printf '%s' "$meta_json" | jq -r '.[0].origin_session_id // ""')
255
+ origin_agent=$(printf '%s' "$meta_json" | jq -r '.[0].origin_agent // ""')
190
256
 
191
257
  eagle_header "Memory Detail"
192
258
 
193
259
  eagle_kv "Name:" "$name"
194
260
  eagle_kv "Type:" "$mtype"
195
- eagle_kv "File:" "$fp"
196
- eagle_kv "Updated:" "$updated"
197
261
  eagle_kv "Source:" "$(eagle_agent_label "$origin_agent")"
198
- [ -n "$origin" ] && eagle_kv "Session:" "$origin"
262
+ eagle_kv "Freshness:" "$(eagle_age_label "$updated")"
263
+ if [ "$raw_output" = true ]; then
264
+ eagle_kv "File:" "$fp"
265
+ eagle_kv "Updated:" "$updated"
266
+ [ -n "$origin" ] && eagle_kv "Session:" "$origin"
267
+ fi
199
268
  echo ""
200
269
 
201
270
  [ -n "$desc" ] && echo -e " ${BOLD}Description:${RESET} $desc"
202
271
  echo ""
203
272
 
204
- if [ -f "$fp" ]; then
273
+ if [ -n "$content" ]; then
205
274
  echo -e " ${BOLD}Content:${RESET}"
206
- awk '/^---$/{c++; next} c>=2' "$fp" | while IFS= read -r line; do
207
- echo " $line"
208
- done
209
- else
210
- eagle_dim "Source file no longer exists on disk."
275
+ eagle_print_wrapped_block "$content" " " 1600
276
+ fi
277
+
278
+ if [ "$raw_output" = true ]; then
279
+ echo ""
280
+ if [ -f "$fp" ]; then
281
+ echo -e " ${BOLD}Source file:${RESET}"
282
+ eagle_print_wrapped_block "$(cat "$fp")" " " 4000
283
+ else
284
+ eagle_dim "Source file no longer exists on disk."
285
+ fi
211
286
  fi
212
287
  echo ""
213
288
  }
@@ -235,8 +310,10 @@ plans_list() {
235
310
  local proj_label=""
236
311
  [ -n "$proj" ] && proj_label=" ${DIM}[${proj}]${RESET}"
237
312
 
238
- echo -e " ${BOLD}${title}${RESET}${proj_label} ${DIM}[$(eagle_agent_label "$origin_agent")]${RESET}"
239
- echo -e " ${DIM}updated: ${updated}${RESET}"
313
+ local age_label
314
+ age_label=$(eagle_age_label "$updated")
315
+ echo -e " ${BOLD}${title}${RESET}${proj_label} ${DIM}[$(eagle_agent_label "$origin_agent")][$age_label]${RESET}"
316
+ [ "$raw_output" = true ] && echo -e " ${DIM}updated: ${updated}${RESET}"
240
317
  echo ""
241
318
  done <<< "$result"
242
319
 
@@ -271,9 +348,11 @@ plans_search() {
271
348
  local proj_label=""
272
349
  [ -n "$proj" ] && proj_label=" ${DIM}[${proj}]${RESET}"
273
350
 
274
- echo -e " ${BOLD}${title}${RESET}${proj_label} ${DIM}[$(eagle_agent_label "$origin_agent")]${RESET}"
351
+ local age_label
352
+ age_label=$(eagle_age_label "$updated")
353
+ echo -e " ${BOLD}${title}${RESET}${proj_label} ${DIM}[$(eagle_agent_label "$origin_agent")][$age_label]${RESET}"
275
354
  [ -n "$snippet" ] && echo -e " ${snippet}"
276
- echo -e " ${DIM}updated: ${updated}${RESET}"
355
+ [ "$raw_output" = true ] && echo -e " ${DIM}updated: ${updated}${RESET}"
277
356
  echo ""
278
357
  done <<< "$result"
279
358
 
@@ -287,34 +366,58 @@ plans_show() {
287
366
  exit 1
288
367
  fi
289
368
 
290
- local meta
291
- meta=$(eagle_db "SELECT title, project, file_path, updated_at, origin_session_id, origin_agent
292
- FROM agent_plans WHERE file_path = '$(eagle_sql_escape "$query")';")
293
-
294
- if [ -z "$meta" ]; then
369
+ local query_sql project_filter meta_json
370
+ query_sql=$(eagle_sql_escape "$query")
371
+ project_filter=""
372
+ if [ -n "$project" ]; then
373
+ project_filter="AND project = '$(eagle_sql_escape "$project")'"
374
+ fi
375
+ meta_json=$(eagle_db_json "SELECT title, project, content, file_path, updated_at, origin_session_id, origin_agent
376
+ FROM agent_plans
377
+ WHERE (file_path = '$query_sql' OR title = '$query_sql')
378
+ $project_filter
379
+ ORDER BY updated_at DESC
380
+ LIMIT 1;")
381
+
382
+ if [ -z "$meta_json" ] || [ "$(printf '%s' "$meta_json" | jq 'length' 2>/dev/null)" = "0" ]; then
295
383
  eagle_err "Plan not found: $query"
296
384
  exit 1
297
385
  fi
298
386
 
299
- IFS='|' read -r title proj fp updated origin origin_agent <<< "$meta"
387
+ title=$(printf '%s' "$meta_json" | jq -r '.[0].title // ""')
388
+ proj=$(printf '%s' "$meta_json" | jq -r '.[0].project // ""')
389
+ content=$(printf '%s' "$meta_json" | jq -r '.[0].content // ""')
390
+ fp=$(printf '%s' "$meta_json" | jq -r '.[0].file_path // ""')
391
+ updated=$(printf '%s' "$meta_json" | jq -r '.[0].updated_at // ""')
392
+ origin=$(printf '%s' "$meta_json" | jq -r '.[0].origin_session_id // ""')
393
+ origin_agent=$(printf '%s' "$meta_json" | jq -r '.[0].origin_agent // ""')
300
394
 
301
395
  eagle_header "Plan Detail"
302
396
 
303
397
  eagle_kv "Title:" "$title"
304
398
  [ -n "$proj" ] && eagle_kv "Project:" "$proj"
305
- eagle_kv "File:" "$fp"
306
- eagle_kv "Updated:" "$updated"
307
399
  eagle_kv "Source:" "$(eagle_agent_label "$origin_agent")"
308
- [ -n "$origin" ] && eagle_kv "Session:" "$origin"
400
+ eagle_kv "Freshness:" "$(eagle_age_label "$updated")"
401
+ if [ "$raw_output" = true ]; then
402
+ eagle_kv "File:" "$fp"
403
+ eagle_kv "Updated:" "$updated"
404
+ [ -n "$origin" ] && eagle_kv "Session:" "$origin"
405
+ fi
309
406
  echo ""
310
407
 
311
- if [ -f "$fp" ]; then
408
+ if [ -n "$content" ]; then
312
409
  echo -e " ${BOLD}Content:${RESET}"
313
- cat "$fp" | while IFS= read -r line; do
314
- echo " $line"
315
- done
316
- else
317
- eagle_dim "Source file no longer exists on disk."
410
+ eagle_print_wrapped_block "$content" " " 2000
411
+ fi
412
+
413
+ if [ "$raw_output" = true ]; then
414
+ echo ""
415
+ if [ -f "$fp" ]; then
416
+ echo -e " ${BOLD}Source file:${RESET}"
417
+ eagle_print_wrapped_block "$(cat "$fp")" " " 4000
418
+ else
419
+ eagle_dim "Source file no longer exists on disk."
420
+ fi
318
421
  fi
319
422
  echo ""
320
423
  }
@@ -346,8 +449,12 @@ tasks_list() {
346
449
  completed) status_color="$GREEN" ;;
347
450
  esac
348
451
 
349
- echo -e " ${BOLD}${subject}${RESET} ${status_color}[${status}]${RESET} ${DIM}[$(eagle_agent_label "$origin_agent")]${RESET}"
350
- echo -e " ${DIM}session: ${sid:0:8}… task: #${tid} updated: ${updated}${RESET}"
452
+ local age_label
453
+ age_label=$(eagle_age_label "$updated")
454
+ echo -e " ${BOLD}${subject}${RESET} ${status_color}[${status}]${RESET} ${DIM}[$(eagle_agent_label "$origin_agent")][$age_label]${RESET}"
455
+ if [ "$raw_output" = true ]; then
456
+ echo -e " ${DIM}session: ${sid:0:8}… task: #${tid} updated: ${updated}${RESET}"
457
+ fi
351
458
  echo ""
352
459
  done <<< "$result"
353
460
 
@@ -386,9 +493,13 @@ tasks_search() {
386
493
  completed) status_color="$GREEN" ;;
387
494
  esac
388
495
 
389
- echo -e " ${BOLD}${subject}${RESET} ${status_color}[${status}]${RESET} ${DIM}[$(eagle_agent_label "$origin_agent")]${RESET}"
496
+ local age_label
497
+ age_label=$(eagle_age_label "$updated")
498
+ echo -e " ${BOLD}${subject}${RESET} ${status_color}[${status}]${RESET} ${DIM}[$(eagle_agent_label "$origin_agent")][$age_label]${RESET}"
390
499
  [ -n "$desc" ] && echo -e " ${desc}"
391
- echo -e " ${DIM}session: ${sid:0:8}… task: #${tid} updated: ${updated}${RESET}"
500
+ if [ "$raw_output" = true ]; then
501
+ echo -e " ${DIM}session: ${sid:0:8}… task: #${tid} updated: ${updated}${RESET}"
502
+ fi
392
503
  echo ""
393
504
  done <<< "$result"
394
505
 
@@ -402,38 +513,61 @@ tasks_show() {
402
513
  exit 1
403
514
  fi
404
515
 
405
- local meta
406
- meta=$(eagle_db "SELECT subject, status, description, active_form, source_session_id, source_task_id, file_path, updated_at, origin_agent
407
- FROM agent_tasks WHERE file_path = '$(eagle_sql_escape "$query")';")
408
-
409
- if [ -z "$meta" ]; then
516
+ local query_sql project_filter meta_json
517
+ query_sql=$(eagle_sql_escape "$query")
518
+ project_filter=""
519
+ if [ -n "$project" ]; then
520
+ project_filter="AND project = '$(eagle_sql_escape "$project")'"
521
+ fi
522
+ meta_json=$(eagle_db_json "SELECT subject, status, description, active_form, source_session_id, source_task_id, file_path, updated_at, origin_agent
523
+ FROM agent_tasks
524
+ WHERE (file_path = '$query_sql' OR source_task_id = '$query_sql' OR subject = '$query_sql')
525
+ $project_filter
526
+ ORDER BY updated_at DESC
527
+ LIMIT 1;")
528
+
529
+ if [ -z "$meta_json" ] || [ "$(printf '%s' "$meta_json" | jq 'length' 2>/dev/null)" = "0" ]; then
410
530
  eagle_err "Task not found: $query"
411
531
  exit 1
412
532
  fi
413
533
 
414
- IFS='|' read -r subject status desc af sid tid fp updated origin_agent <<< "$meta"
534
+ subject=$(printf '%s' "$meta_json" | jq -r '.[0].subject // ""')
535
+ status=$(printf '%s' "$meta_json" | jq -r '.[0].status // ""')
536
+ desc=$(printf '%s' "$meta_json" | jq -r '.[0].description // ""')
537
+ af=$(printf '%s' "$meta_json" | jq -r '.[0].active_form // ""')
538
+ sid=$(printf '%s' "$meta_json" | jq -r '.[0].source_session_id // ""')
539
+ tid=$(printf '%s' "$meta_json" | jq -r '.[0].source_task_id // ""')
540
+ fp=$(printf '%s' "$meta_json" | jq -r '.[0].file_path // ""')
541
+ updated=$(printf '%s' "$meta_json" | jq -r '.[0].updated_at // ""')
542
+ origin_agent=$(printf '%s' "$meta_json" | jq -r '.[0].origin_agent // ""')
415
543
 
416
544
  eagle_header "Task Detail"
417
545
 
418
546
  eagle_kv "Subject:" "$subject"
419
547
  eagle_kv "Status:" "$status"
420
- eagle_kv "Task ID:" "$tid"
421
- eagle_kv "Session:" "$sid"
422
- eagle_kv "File:" "$fp"
423
- eagle_kv "Updated:" "$updated"
424
548
  eagle_kv "Source:" "$(eagle_agent_label "$origin_agent")"
549
+ eagle_kv "Freshness:" "$(eagle_age_label "$updated")"
550
+ if [ "$raw_output" = true ]; then
551
+ eagle_kv "Task ID:" "$tid"
552
+ eagle_kv "Session:" "$sid"
553
+ eagle_kv "File:" "$fp"
554
+ eagle_kv "Updated:" "$updated"
555
+ fi
425
556
  echo ""
426
557
 
427
558
  [ -n "$desc" ] && echo -e " ${BOLD}Description:${RESET} $desc" && echo ""
428
559
  [ -n "$af" ] && echo -e " ${BOLD}Active Form:${RESET} $af" && echo ""
429
560
 
430
- if [ -f "$fp" ]; then
561
+ if [ "$raw_output" = true ]; then
562
+ echo ""
563
+ if [ -f "$fp" ]; then
431
564
  echo -e " ${BOLD}Raw JSON:${RESET}"
432
565
  jq '.' "$fp" 2>/dev/null | while IFS= read -r line; do
433
566
  echo " $line"
434
567
  done
435
- else
436
- eagle_dim "Source file no longer exists on disk."
568
+ else
569
+ eagle_dim "Source file no longer exists on disk."
570
+ fi
437
571
  fi
438
572
  echo ""
439
573
  }
@@ -797,9 +797,9 @@ orchestrate_worker_run_script() {
797
797
  printf 'printf "%%s\\n" "$rc" > %q\n' "$exit_path"
798
798
  printf 'date -u "+%%Y-%%m-%%dT%%H:%%M:%%SZ" > %q.done\n' "$exit_path"
799
799
  echo 'if [ "$rc" -eq 0 ]; then'
800
- printf ' bash %q orchestrate lane --project %q --name %q complete %q --notes %q >/dev/null 2>&1\n' "$bin_path" "$project" "$name" "$lane_key" "$complete_note"
800
+ printf ' bash %q orchestrate --project %q --name %q lane complete %q --notes %q >/dev/null 2>&1\n' "$bin_path" "$project" "$name" "$lane_key" "$complete_note"
801
801
  echo 'else'
802
- printf ' bash %q orchestrate lane --project %q --name %q block %q --notes %q >/dev/null 2>&1\n' "$bin_path" "$project" "$name" "$lane_key" "$block_note"
802
+ printf ' bash %q orchestrate --project %q --name %q lane block %q --notes %q >/dev/null 2>&1\n' "$bin_path" "$project" "$name" "$lane_key" "$block_note"
803
803
  echo 'fi'
804
804
  echo 'exit "$rc"'
805
805
  } > "$run_script"