eagle-mem 4.9.6 → 4.9.8
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 +31 -4
- package/architecture.html +1791 -0
- package/bin/eagle-mem +1 -0
- package/db/migrate.sh +13 -2
- package/docs/visible-surface-ux-contract.md +53 -0
- package/hooks/post-tool-use.sh +2 -2
- package/hooks/pre-tool-use.sh +6 -6
- package/hooks/session-start.sh +216 -9
- package/hooks/user-prompt-submit.sh +72 -15
- package/lib/common.sh +485 -35
- package/lib/db-mirrors.sh +9 -18
- package/lib/db-sessions.sh +22 -15
- package/lib/db-summaries.sh +19 -7
- package/lib/hooks-posttool.sh +44 -10
- package/lib/updater.sh +12 -0
- package/package.json +4 -2
- package/scripts/doctor.sh +262 -0
- package/scripts/feature.sh +37 -11
- package/scripts/health.sh +10 -7
- package/scripts/help.sh +1 -0
- package/scripts/install.sh +9 -3
- package/scripts/memories.sh +258 -65
- package/scripts/orchestrate.sh +2 -2
- package/scripts/search.sh +240 -56
- package/scripts/statusline-em.sh +130 -26
- package/scripts/uninstall.sh +67 -0
- package/scripts/update.sh +8 -1
package/scripts/memories.sh
CHANGED
|
@@ -24,8 +24,11 @@ case "${1:-}" in
|
|
|
24
24
|
esac
|
|
25
25
|
|
|
26
26
|
project=""
|
|
27
|
+
project_was_explicit=false
|
|
27
28
|
limit=20
|
|
28
29
|
query=""
|
|
30
|
+
raw_output=false
|
|
31
|
+
cross_project=false
|
|
29
32
|
|
|
30
33
|
show_help() {
|
|
31
34
|
echo -e " ${BOLD}eagle-mem memories${RESET} — Agent memory, plan & task mirror"
|
|
@@ -44,8 +47,10 @@ show_help() {
|
|
|
44
47
|
echo -e " eagle-mem memories sync ${DIM}# backfill memories + plans + tasks${RESET}"
|
|
45
48
|
echo ""
|
|
46
49
|
echo -e " ${BOLD}Options:${RESET}"
|
|
47
|
-
echo -e " ${CYAN}-p, --project${RESET} <name> Filter by project"
|
|
50
|
+
echo -e " ${CYAN}-p, --project${RESET} <name> Filter by project (default: current project)"
|
|
48
51
|
echo -e " ${CYAN}-l, --limit${RESET} <N> Max results (default: 20)"
|
|
52
|
+
echo -e " ${CYAN}-a, --all${RESET} Show all projects"
|
|
53
|
+
echo -e " ${CYAN}--raw, --debug${RESET} Show source paths, sessions, and raw backing data"
|
|
49
54
|
echo ""
|
|
50
55
|
echo -e " ${BOLD}How it works:${RESET}"
|
|
51
56
|
echo -e " ${DOT} Eagle Mem mirrors agent memory, plan, and task writes"
|
|
@@ -72,8 +77,10 @@ esac
|
|
|
72
77
|
|
|
73
78
|
while [ $# -gt 0 ]; do
|
|
74
79
|
case "$1" in
|
|
75
|
-
--project|-p) project="$2"; shift 2 ;;
|
|
80
|
+
--project|-p) project="$2"; project_was_explicit=true; shift 2 ;;
|
|
76
81
|
--limit|-l) limit="$2"; shift 2 ;;
|
|
82
|
+
--all|-a) cross_project=true; shift ;;
|
|
83
|
+
--raw|--debug) raw_output=true; shift ;;
|
|
77
84
|
--help|-h) show_help ;;
|
|
78
85
|
*)
|
|
79
86
|
if [ -z "$query" ]; then
|
|
@@ -86,6 +93,42 @@ while [ $# -gt 0 ]; do
|
|
|
86
93
|
esac
|
|
87
94
|
done
|
|
88
95
|
|
|
96
|
+
if [ -z "$project" ] && [ "$cross_project" = false ]; then
|
|
97
|
+
project=$(eagle_project_from_cwd "$(pwd)")
|
|
98
|
+
fi
|
|
99
|
+
if [ "$cross_project" = false ] && [ "$project_was_explicit" = false ]; then
|
|
100
|
+
project=$(eagle_recall_project_scope_from_cwd "$(pwd)" "$project")
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
eagle_age_label() {
|
|
104
|
+
local updated="${1:-}"
|
|
105
|
+
[ -z "$updated" ] && { printf 'unknown'; return; }
|
|
106
|
+
local days
|
|
107
|
+
days=$(eagle_db "SELECT CAST(julianday('now') - julianday('$(eagle_sql_escape "$updated")') AS INTEGER);" 2>/dev/null | awk 'NF {print; exit}')
|
|
108
|
+
if [ -z "$days" ]; then
|
|
109
|
+
printf 'unknown'
|
|
110
|
+
elif [ "$days" -le 0 ] 2>/dev/null; then
|
|
111
|
+
printf 'Fresh'
|
|
112
|
+
elif [ "$days" -le 14 ] 2>/dev/null; then
|
|
113
|
+
printf '%sd old' "$days"
|
|
114
|
+
elif [ "$days" -le 45 ] 2>/dev/null; then
|
|
115
|
+
printf 'Recent'
|
|
116
|
+
else
|
|
117
|
+
printf 'Older'
|
|
118
|
+
fi
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
eagle_print_wrapped_block() {
|
|
122
|
+
local text="${1:-}" indent="${2:- }" max_chars="${3:-1200}"
|
|
123
|
+
[ -z "$text" ] && return
|
|
124
|
+
printf '%s' "$text" | head -c "$max_chars" | while IFS= read -r line; do
|
|
125
|
+
printf '%s%s\n' "$indent" "$line"
|
|
126
|
+
done
|
|
127
|
+
if [ "${#text}" -gt "$max_chars" ] 2>/dev/null; then
|
|
128
|
+
printf '%s%s\n' "$indent" "..."
|
|
129
|
+
fi
|
|
130
|
+
}
|
|
131
|
+
|
|
89
132
|
# ─── Actions ─────────────────────────────────────────────
|
|
90
133
|
|
|
91
134
|
memories_list() {
|
|
@@ -116,9 +159,14 @@ memories_list() {
|
|
|
116
159
|
reference) type_color="$BLUE" ;;
|
|
117
160
|
esac
|
|
118
161
|
|
|
119
|
-
|
|
162
|
+
local age_label
|
|
163
|
+
age_label=$(eagle_age_label "$updated")
|
|
164
|
+
echo -e " ${BOLD}${name}${RESET} ${type_color}[${mtype}]${RESET} ${DIM}[$(eagle_agent_label "$origin_agent")][$age_label]${RESET}"
|
|
120
165
|
[ -n "$desc" ] && echo -e " ${DIM}${desc}${RESET}"
|
|
121
|
-
|
|
166
|
+
if [ "$raw_output" = true ]; then
|
|
167
|
+
echo -e " ${DIM}file: $_fp${RESET}"
|
|
168
|
+
echo -e " ${DIM}updated: ${updated}${RESET}"
|
|
169
|
+
fi
|
|
122
170
|
echo ""
|
|
123
171
|
done <<< "$result"
|
|
124
172
|
|
|
@@ -158,12 +206,17 @@ memories_search() {
|
|
|
158
206
|
reference) type_color="$BLUE" ;;
|
|
159
207
|
esac
|
|
160
208
|
|
|
161
|
-
|
|
209
|
+
local age_label
|
|
210
|
+
age_label=$(eagle_age_label "$updated")
|
|
211
|
+
echo -e " ${BOLD}${name}${RESET} ${type_color}[${mtype}]${RESET} ${DIM}[$(eagle_agent_label "$origin_agent")][$age_label]${RESET}"
|
|
162
212
|
[ -n "$desc" ] && echo -e " ${DIM}${desc}${RESET}"
|
|
163
213
|
local snippet
|
|
164
214
|
snippet=$(printf '%s' "$content" | head -c 200)
|
|
165
215
|
[ -n "$snippet" ] && echo -e " ${snippet}"
|
|
166
|
-
|
|
216
|
+
if [ "$raw_output" = true ]; then
|
|
217
|
+
echo -e " ${DIM}file: $_fp${RESET}"
|
|
218
|
+
echo -e " ${DIM}updated: ${updated}${RESET}"
|
|
219
|
+
fi
|
|
167
220
|
echo ""
|
|
168
221
|
done <<< "$result"
|
|
169
222
|
|
|
@@ -177,37 +230,63 @@ memories_show() {
|
|
|
177
230
|
exit 1
|
|
178
231
|
fi
|
|
179
232
|
|
|
180
|
-
local
|
|
181
|
-
|
|
182
|
-
|
|
233
|
+
local query_sql project_filter meta_json
|
|
234
|
+
query_sql=$(eagle_sql_escape "$query")
|
|
235
|
+
project_filter=""
|
|
236
|
+
if [ -n "$project" ]; then
|
|
237
|
+
project_filter="AND $(eagle_sql_project_scope_condition "project" "$project")"
|
|
238
|
+
fi
|
|
183
239
|
|
|
184
|
-
|
|
240
|
+
meta_json=$(eagle_db_json "SELECT memory_name, memory_type, description, content, file_path, updated_at, origin_session_id, origin_agent
|
|
241
|
+
FROM agent_memories
|
|
242
|
+
WHERE (file_path = '$query_sql' OR memory_name = '$query_sql')
|
|
243
|
+
$project_filter
|
|
244
|
+
ORDER BY updated_at DESC
|
|
245
|
+
LIMIT 1;")
|
|
246
|
+
|
|
247
|
+
if [ -z "$meta_json" ] || [ "$(printf '%s' "$meta_json" | jq 'length' 2>/dev/null)" = "0" ]; then
|
|
185
248
|
eagle_err "Memory not found: $query"
|
|
186
249
|
exit 1
|
|
187
250
|
fi
|
|
188
251
|
|
|
189
|
-
|
|
252
|
+
name=$(printf '%s' "$meta_json" | jq -r '.[0].memory_name // ""')
|
|
253
|
+
mtype=$(printf '%s' "$meta_json" | jq -r '.[0].memory_type // ""')
|
|
254
|
+
desc=$(printf '%s' "$meta_json" | jq -r '.[0].description // ""')
|
|
255
|
+
content=$(printf '%s' "$meta_json" | jq -r '.[0].content // ""')
|
|
256
|
+
fp=$(printf '%s' "$meta_json" | jq -r '.[0].file_path // ""')
|
|
257
|
+
updated=$(printf '%s' "$meta_json" | jq -r '.[0].updated_at // ""')
|
|
258
|
+
origin=$(printf '%s' "$meta_json" | jq -r '.[0].origin_session_id // ""')
|
|
259
|
+
origin_agent=$(printf '%s' "$meta_json" | jq -r '.[0].origin_agent // ""')
|
|
190
260
|
|
|
191
261
|
eagle_header "Memory Detail"
|
|
192
262
|
|
|
193
263
|
eagle_kv "Name:" "$name"
|
|
194
264
|
eagle_kv "Type:" "$mtype"
|
|
195
|
-
eagle_kv "File:" "$fp"
|
|
196
|
-
eagle_kv "Updated:" "$updated"
|
|
197
265
|
eagle_kv "Source:" "$(eagle_agent_label "$origin_agent")"
|
|
198
|
-
|
|
266
|
+
eagle_kv "Freshness:" "$(eagle_age_label "$updated")"
|
|
267
|
+
if [ "$raw_output" = true ]; then
|
|
268
|
+
eagle_kv "File:" "$fp"
|
|
269
|
+
eagle_kv "Updated:" "$updated"
|
|
270
|
+
[ -n "$origin" ] && eagle_kv "Session:" "$origin"
|
|
271
|
+
fi
|
|
199
272
|
echo ""
|
|
200
273
|
|
|
201
274
|
[ -n "$desc" ] && echo -e " ${BOLD}Description:${RESET} $desc"
|
|
202
275
|
echo ""
|
|
203
276
|
|
|
204
|
-
if [ -
|
|
277
|
+
if [ -n "$content" ]; then
|
|
205
278
|
echo -e " ${BOLD}Content:${RESET}"
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
279
|
+
eagle_print_wrapped_block "$content" " " 1600
|
|
280
|
+
fi
|
|
281
|
+
|
|
282
|
+
if [ "$raw_output" = true ]; then
|
|
283
|
+
echo ""
|
|
284
|
+
if [ -f "$fp" ]; then
|
|
285
|
+
echo -e " ${BOLD}Source file:${RESET}"
|
|
286
|
+
eagle_print_wrapped_block "$(cat "$fp")" " " 4000
|
|
287
|
+
else
|
|
288
|
+
eagle_dim "Source file no longer exists on disk."
|
|
289
|
+
fi
|
|
211
290
|
fi
|
|
212
291
|
echo ""
|
|
213
292
|
}
|
|
@@ -235,8 +314,10 @@ plans_list() {
|
|
|
235
314
|
local proj_label=""
|
|
236
315
|
[ -n "$proj" ] && proj_label=" ${DIM}[${proj}]${RESET}"
|
|
237
316
|
|
|
238
|
-
|
|
239
|
-
|
|
317
|
+
local age_label
|
|
318
|
+
age_label=$(eagle_age_label "$updated")
|
|
319
|
+
echo -e " ${BOLD}${title}${RESET}${proj_label} ${DIM}[$(eagle_agent_label "$origin_agent")][$age_label]${RESET}"
|
|
320
|
+
[ "$raw_output" = true ] && echo -e " ${DIM}updated: ${updated}${RESET}"
|
|
240
321
|
echo ""
|
|
241
322
|
done <<< "$result"
|
|
242
323
|
|
|
@@ -271,9 +352,11 @@ plans_search() {
|
|
|
271
352
|
local proj_label=""
|
|
272
353
|
[ -n "$proj" ] && proj_label=" ${DIM}[${proj}]${RESET}"
|
|
273
354
|
|
|
274
|
-
|
|
355
|
+
local age_label
|
|
356
|
+
age_label=$(eagle_age_label "$updated")
|
|
357
|
+
echo -e " ${BOLD}${title}${RESET}${proj_label} ${DIM}[$(eagle_agent_label "$origin_agent")][$age_label]${RESET}"
|
|
275
358
|
[ -n "$snippet" ] && echo -e " ${snippet}"
|
|
276
|
-
echo -e " ${DIM}updated: ${updated}${RESET}"
|
|
359
|
+
[ "$raw_output" = true ] && echo -e " ${DIM}updated: ${updated}${RESET}"
|
|
277
360
|
echo ""
|
|
278
361
|
done <<< "$result"
|
|
279
362
|
|
|
@@ -287,34 +370,58 @@ plans_show() {
|
|
|
287
370
|
exit 1
|
|
288
371
|
fi
|
|
289
372
|
|
|
290
|
-
local
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
373
|
+
local query_sql project_filter meta_json
|
|
374
|
+
query_sql=$(eagle_sql_escape "$query")
|
|
375
|
+
project_filter=""
|
|
376
|
+
if [ -n "$project" ]; then
|
|
377
|
+
project_filter="AND $(eagle_sql_project_scope_condition "project" "$project")"
|
|
378
|
+
fi
|
|
379
|
+
meta_json=$(eagle_db_json "SELECT title, project, content, file_path, updated_at, origin_session_id, origin_agent
|
|
380
|
+
FROM agent_plans
|
|
381
|
+
WHERE (file_path = '$query_sql' OR title = '$query_sql')
|
|
382
|
+
$project_filter
|
|
383
|
+
ORDER BY updated_at DESC
|
|
384
|
+
LIMIT 1;")
|
|
385
|
+
|
|
386
|
+
if [ -z "$meta_json" ] || [ "$(printf '%s' "$meta_json" | jq 'length' 2>/dev/null)" = "0" ]; then
|
|
295
387
|
eagle_err "Plan not found: $query"
|
|
296
388
|
exit 1
|
|
297
389
|
fi
|
|
298
390
|
|
|
299
|
-
|
|
391
|
+
title=$(printf '%s' "$meta_json" | jq -r '.[0].title // ""')
|
|
392
|
+
proj=$(printf '%s' "$meta_json" | jq -r '.[0].project // ""')
|
|
393
|
+
content=$(printf '%s' "$meta_json" | jq -r '.[0].content // ""')
|
|
394
|
+
fp=$(printf '%s' "$meta_json" | jq -r '.[0].file_path // ""')
|
|
395
|
+
updated=$(printf '%s' "$meta_json" | jq -r '.[0].updated_at // ""')
|
|
396
|
+
origin=$(printf '%s' "$meta_json" | jq -r '.[0].origin_session_id // ""')
|
|
397
|
+
origin_agent=$(printf '%s' "$meta_json" | jq -r '.[0].origin_agent // ""')
|
|
300
398
|
|
|
301
399
|
eagle_header "Plan Detail"
|
|
302
400
|
|
|
303
401
|
eagle_kv "Title:" "$title"
|
|
304
402
|
[ -n "$proj" ] && eagle_kv "Project:" "$proj"
|
|
305
|
-
eagle_kv "File:" "$fp"
|
|
306
|
-
eagle_kv "Updated:" "$updated"
|
|
307
403
|
eagle_kv "Source:" "$(eagle_agent_label "$origin_agent")"
|
|
308
|
-
|
|
404
|
+
eagle_kv "Freshness:" "$(eagle_age_label "$updated")"
|
|
405
|
+
if [ "$raw_output" = true ]; then
|
|
406
|
+
eagle_kv "File:" "$fp"
|
|
407
|
+
eagle_kv "Updated:" "$updated"
|
|
408
|
+
[ -n "$origin" ] && eagle_kv "Session:" "$origin"
|
|
409
|
+
fi
|
|
309
410
|
echo ""
|
|
310
411
|
|
|
311
|
-
if [ -
|
|
412
|
+
if [ -n "$content" ]; then
|
|
312
413
|
echo -e " ${BOLD}Content:${RESET}"
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
414
|
+
eagle_print_wrapped_block "$content" " " 2000
|
|
415
|
+
fi
|
|
416
|
+
|
|
417
|
+
if [ "$raw_output" = true ]; then
|
|
418
|
+
echo ""
|
|
419
|
+
if [ -f "$fp" ]; then
|
|
420
|
+
echo -e " ${BOLD}Source file:${RESET}"
|
|
421
|
+
eagle_print_wrapped_block "$(cat "$fp")" " " 4000
|
|
422
|
+
else
|
|
423
|
+
eagle_dim "Source file no longer exists on disk."
|
|
424
|
+
fi
|
|
318
425
|
fi
|
|
319
426
|
echo ""
|
|
320
427
|
}
|
|
@@ -346,8 +453,12 @@ tasks_list() {
|
|
|
346
453
|
completed) status_color="$GREEN" ;;
|
|
347
454
|
esac
|
|
348
455
|
|
|
349
|
-
|
|
350
|
-
|
|
456
|
+
local age_label
|
|
457
|
+
age_label=$(eagle_age_label "$updated")
|
|
458
|
+
echo -e " ${BOLD}${subject}${RESET} ${status_color}[${status}]${RESET} ${DIM}[$(eagle_agent_label "$origin_agent")][$age_label]${RESET}"
|
|
459
|
+
if [ "$raw_output" = true ]; then
|
|
460
|
+
echo -e " ${DIM}session: ${sid:0:8}… task: #${tid} updated: ${updated}${RESET}"
|
|
461
|
+
fi
|
|
351
462
|
echo ""
|
|
352
463
|
done <<< "$result"
|
|
353
464
|
|
|
@@ -386,9 +497,13 @@ tasks_search() {
|
|
|
386
497
|
completed) status_color="$GREEN" ;;
|
|
387
498
|
esac
|
|
388
499
|
|
|
389
|
-
|
|
500
|
+
local age_label
|
|
501
|
+
age_label=$(eagle_age_label "$updated")
|
|
502
|
+
echo -e " ${BOLD}${subject}${RESET} ${status_color}[${status}]${RESET} ${DIM}[$(eagle_agent_label "$origin_agent")][$age_label]${RESET}"
|
|
390
503
|
[ -n "$desc" ] && echo -e " ${desc}"
|
|
391
|
-
|
|
504
|
+
if [ "$raw_output" = true ]; then
|
|
505
|
+
echo -e " ${DIM}session: ${sid:0:8}… task: #${tid} updated: ${updated}${RESET}"
|
|
506
|
+
fi
|
|
392
507
|
echo ""
|
|
393
508
|
done <<< "$result"
|
|
394
509
|
|
|
@@ -402,38 +517,61 @@ tasks_show() {
|
|
|
402
517
|
exit 1
|
|
403
518
|
fi
|
|
404
519
|
|
|
405
|
-
local
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
520
|
+
local query_sql project_filter meta_json
|
|
521
|
+
query_sql=$(eagle_sql_escape "$query")
|
|
522
|
+
project_filter=""
|
|
523
|
+
if [ -n "$project" ]; then
|
|
524
|
+
project_filter="AND $(eagle_sql_project_scope_condition "project" "$project")"
|
|
525
|
+
fi
|
|
526
|
+
meta_json=$(eagle_db_json "SELECT subject, status, description, active_form, source_session_id, source_task_id, file_path, updated_at, origin_agent
|
|
527
|
+
FROM agent_tasks
|
|
528
|
+
WHERE (file_path = '$query_sql' OR source_task_id = '$query_sql' OR subject = '$query_sql')
|
|
529
|
+
$project_filter
|
|
530
|
+
ORDER BY updated_at DESC
|
|
531
|
+
LIMIT 1;")
|
|
532
|
+
|
|
533
|
+
if [ -z "$meta_json" ] || [ "$(printf '%s' "$meta_json" | jq 'length' 2>/dev/null)" = "0" ]; then
|
|
410
534
|
eagle_err "Task not found: $query"
|
|
411
535
|
exit 1
|
|
412
536
|
fi
|
|
413
537
|
|
|
414
|
-
|
|
538
|
+
subject=$(printf '%s' "$meta_json" | jq -r '.[0].subject // ""')
|
|
539
|
+
status=$(printf '%s' "$meta_json" | jq -r '.[0].status // ""')
|
|
540
|
+
desc=$(printf '%s' "$meta_json" | jq -r '.[0].description // ""')
|
|
541
|
+
af=$(printf '%s' "$meta_json" | jq -r '.[0].active_form // ""')
|
|
542
|
+
sid=$(printf '%s' "$meta_json" | jq -r '.[0].source_session_id // ""')
|
|
543
|
+
tid=$(printf '%s' "$meta_json" | jq -r '.[0].source_task_id // ""')
|
|
544
|
+
fp=$(printf '%s' "$meta_json" | jq -r '.[0].file_path // ""')
|
|
545
|
+
updated=$(printf '%s' "$meta_json" | jq -r '.[0].updated_at // ""')
|
|
546
|
+
origin_agent=$(printf '%s' "$meta_json" | jq -r '.[0].origin_agent // ""')
|
|
415
547
|
|
|
416
548
|
eagle_header "Task Detail"
|
|
417
549
|
|
|
418
550
|
eagle_kv "Subject:" "$subject"
|
|
419
551
|
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
552
|
eagle_kv "Source:" "$(eagle_agent_label "$origin_agent")"
|
|
553
|
+
eagle_kv "Freshness:" "$(eagle_age_label "$updated")"
|
|
554
|
+
if [ "$raw_output" = true ]; then
|
|
555
|
+
eagle_kv "Task ID:" "$tid"
|
|
556
|
+
eagle_kv "Session:" "$sid"
|
|
557
|
+
eagle_kv "File:" "$fp"
|
|
558
|
+
eagle_kv "Updated:" "$updated"
|
|
559
|
+
fi
|
|
425
560
|
echo ""
|
|
426
561
|
|
|
427
562
|
[ -n "$desc" ] && echo -e " ${BOLD}Description:${RESET} $desc" && echo ""
|
|
428
563
|
[ -n "$af" ] && echo -e " ${BOLD}Active Form:${RESET} $af" && echo ""
|
|
429
564
|
|
|
430
|
-
if [
|
|
565
|
+
if [ "$raw_output" = true ]; then
|
|
566
|
+
echo ""
|
|
567
|
+
if [ -f "$fp" ]; then
|
|
431
568
|
echo -e " ${BOLD}Raw JSON:${RESET}"
|
|
432
569
|
jq '.' "$fp" 2>/dev/null | while IFS= read -r line; do
|
|
433
570
|
echo " $line"
|
|
434
571
|
done
|
|
435
|
-
|
|
436
|
-
|
|
572
|
+
else
|
|
573
|
+
eagle_dim "Source file no longer exists on disk."
|
|
574
|
+
fi
|
|
437
575
|
fi
|
|
438
576
|
echo ""
|
|
439
577
|
}
|
|
@@ -441,6 +579,33 @@ tasks_show() {
|
|
|
441
579
|
memories_sync() {
|
|
442
580
|
eagle_header "Memory, Plan & Task Sync"
|
|
443
581
|
|
|
582
|
+
local lock_root="$EAGLE_MEM_DIR/locks"
|
|
583
|
+
local lock_dir="$lock_root/memories-sync.lock"
|
|
584
|
+
mkdir -p "$lock_root" 2>/dev/null || true
|
|
585
|
+
if mkdir "$lock_dir" 2>/dev/null; then
|
|
586
|
+
printf '%s\n' "$$" > "$lock_dir/pid" 2>/dev/null || true
|
|
587
|
+
_EAGLE_MEMORIES_SYNC_LOCK_DIR="$lock_dir"
|
|
588
|
+
trap 'rm -rf "${_EAGLE_MEMORIES_SYNC_LOCK_DIR:-}" 2>/dev/null || true' EXIT
|
|
589
|
+
else
|
|
590
|
+
local lock_pid=""
|
|
591
|
+
[ -f "$lock_dir/pid" ] && lock_pid=$(cat "$lock_dir/pid" 2>/dev/null | tr -cd '0-9')
|
|
592
|
+
if [ -n "$lock_pid" ] && kill -0 "$lock_pid" 2>/dev/null; then
|
|
593
|
+
eagle_info "Sync already running (pid $lock_pid). Skipping this duplicate run."
|
|
594
|
+
echo ""
|
|
595
|
+
eagle_footer "Sync skipped."
|
|
596
|
+
return 0
|
|
597
|
+
fi
|
|
598
|
+
rm -rf "$lock_dir" 2>/dev/null || true
|
|
599
|
+
if mkdir "$lock_dir" 2>/dev/null; then
|
|
600
|
+
printf '%s\n' "$$" > "$lock_dir/pid" 2>/dev/null || true
|
|
601
|
+
_EAGLE_MEMORIES_SYNC_LOCK_DIR="$lock_dir"
|
|
602
|
+
trap 'rm -rf "${_EAGLE_MEMORIES_SYNC_LOCK_DIR:-}" 2>/dev/null || true' EXIT
|
|
603
|
+
else
|
|
604
|
+
eagle_err "Could not acquire memories sync lock."
|
|
605
|
+
return 1
|
|
606
|
+
fi
|
|
607
|
+
fi
|
|
608
|
+
|
|
444
609
|
# ─── Sync memories ───────────────────────────────────
|
|
445
610
|
eagle_info "Scanning for agent memory files..."
|
|
446
611
|
echo ""
|
|
@@ -449,15 +614,21 @@ memories_sync() {
|
|
|
449
614
|
local mem_synced=0
|
|
450
615
|
local mem_skipped=0
|
|
451
616
|
|
|
452
|
-
|
|
453
|
-
|
|
617
|
+
sync_one_memory_file() {
|
|
618
|
+
local memfile="$1"
|
|
619
|
+
[ -f "$memfile" ] || return 0
|
|
620
|
+
|
|
454
621
|
local base
|
|
455
622
|
base=$(basename "$memfile")
|
|
456
|
-
[ "$base" = "MEMORY.md" ] &&
|
|
623
|
+
[ "$base" = "MEMORY.md" ] && return 0
|
|
457
624
|
|
|
458
625
|
local mem_project mem_project_dir existing_row existing_hash existing_project
|
|
459
626
|
mem_project_dir="${memfile%/memory/*}"
|
|
460
627
|
mem_project=$(eagle_project_from_claude_project_dir "$mem_project_dir" 2>/dev/null || true)
|
|
628
|
+
if [ "$cross_project" = false ] && [ -n "$project" ]; then
|
|
629
|
+
eagle_project_scope_contains "$project" "$mem_project" || return 0
|
|
630
|
+
fi
|
|
631
|
+
|
|
461
632
|
existing_row=$(eagle_db "SELECT content_hash, project FROM agent_memories WHERE file_path = '$(eagle_sql_escape "$memfile")';")
|
|
462
633
|
IFS='|' read -r existing_hash existing_project <<< "$existing_row"
|
|
463
634
|
local new_hash
|
|
@@ -471,7 +642,25 @@ memories_sync() {
|
|
|
471
642
|
eagle_capture_agent_memory "$memfile" "" "$mem_project" "claude-code"
|
|
472
643
|
mem_synced=$((mem_synced + 1))
|
|
473
644
|
eagle_ok "Memory: $base"
|
|
474
|
-
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
if [ -d "$claude_mem_root" ]; then
|
|
648
|
+
if [ "$cross_project" = true ] || [ -z "$project" ]; then
|
|
649
|
+
while IFS= read -r -d '' memfile; do
|
|
650
|
+
sync_one_memory_file "$memfile"
|
|
651
|
+
done < <(find "$claude_mem_root" -path "*/memory/*.md" -print0 2>/dev/null)
|
|
652
|
+
else
|
|
653
|
+
while IFS= read -r scope_project; do
|
|
654
|
+
[ -z "$scope_project" ] && continue
|
|
655
|
+
scope_dir=$(eagle_claude_project_dir_for_key "$scope_project")
|
|
656
|
+
[ -d "$scope_dir/memory" ] || continue
|
|
657
|
+
while IFS= read -r -d '' memfile; do
|
|
658
|
+
sync_one_memory_file "$memfile"
|
|
659
|
+
done < <(find "$scope_dir/memory" -maxdepth 1 -type f -name "*.md" -print0 2>/dev/null)
|
|
660
|
+
done <<EOF
|
|
661
|
+
$(printf '%s' "$project" | tr '|' '\n')
|
|
662
|
+
EOF
|
|
663
|
+
fi
|
|
475
664
|
fi
|
|
476
665
|
|
|
477
666
|
local codex_mem_root="$EAGLE_CODEX_MEMORIES_DIR"
|
|
@@ -576,12 +765,16 @@ memories_sync() {
|
|
|
576
765
|
# ─── Backfill project names ──────────────────────────
|
|
577
766
|
eagle_info "Resolving project names from agent transcripts..."
|
|
578
767
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
768
|
+
if [ "$cross_project" = true ]; then
|
|
769
|
+
local backfilled
|
|
770
|
+
backfilled=$(eagle_backfill_projects)
|
|
771
|
+
if [ "${backfilled:-0}" -gt 0 ]; then
|
|
772
|
+
eagle_ok "$backfilled rows updated with correct project names"
|
|
773
|
+
else
|
|
774
|
+
eagle_ok "All project names up to date"
|
|
775
|
+
fi
|
|
583
776
|
else
|
|
584
|
-
eagle_ok "
|
|
777
|
+
eagle_ok "Scoped sync complete; use --all for global transcript backfill"
|
|
585
778
|
fi
|
|
586
779
|
|
|
587
780
|
eagle_footer "Sync complete."
|
package/scripts/orchestrate.sh
CHANGED
|
@@ -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
|
|
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
|
|
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"
|