eagle-mem 4.9.7 → 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/hooks/session-start.sh +39 -19
- package/hooks/user-prompt-submit.sh +38 -4
- package/lib/common.sh +124 -14
- package/lib/db-mirrors.sh +6 -12
- package/lib/db-sessions.sh +22 -15
- package/lib/db-summaries.sh +9 -6
- package/package.json +1 -1
- package/scripts/memories.sh +72 -13
- package/scripts/search.sh +45 -25
- package/scripts/statusline-em.sh +5 -4
package/hooks/session-start.sh
CHANGED
|
@@ -37,6 +37,12 @@ project=$(eagle_project_from_hook_input "$input")
|
|
|
37
37
|
[ -z "$project" ] && exit 0
|
|
38
38
|
|
|
39
39
|
p_esc=$(eagle_sql_escape "$project")
|
|
40
|
+
recall_scope=$(eagle_recall_project_scope_from_cwd "$cwd" "$project")
|
|
41
|
+
[ -z "$recall_scope" ] && recall_scope="$project"
|
|
42
|
+
recall_scope_label=$(eagle_project_scope_label "$recall_scope")
|
|
43
|
+
recall_project_filter=$(eagle_sql_project_scope_condition "project" "$recall_scope")
|
|
44
|
+
recall_memory_filter=$(eagle_sql_project_scope_condition "m.project" "$recall_scope")
|
|
45
|
+
recall_lane_filter=$(eagle_sql_project_scope_condition "l.project" "$recall_scope")
|
|
40
46
|
|
|
41
47
|
eagle_log "INFO" "SessionStart: session=$session_id project=$project source=$source_type agent=$agent"
|
|
42
48
|
|
|
@@ -96,7 +102,7 @@ while IFS='|' read -r key val; do
|
|
|
96
102
|
last_active) stat_last_active="$val" ;;
|
|
97
103
|
last_summary) stat_last_summary="$val" ;;
|
|
98
104
|
esac
|
|
99
|
-
done <<< "$(eagle_get_project_stats "$
|
|
105
|
+
done <<< "$(eagle_get_project_stats "$recall_scope")"
|
|
100
106
|
|
|
101
107
|
# ─── Build compressed banner (elide zero-value lines) ────
|
|
102
108
|
|
|
@@ -119,6 +125,10 @@ eagle_banner="======================================
|
|
|
119
125
|
Project | $project
|
|
120
126
|
Agent | $agent_label
|
|
121
127
|
Sessions | $stat_sessions ($stat_with_summaries with summaries)"
|
|
128
|
+
if [ "$recall_scope_label" != "$project" ]; then
|
|
129
|
+
eagle_banner+="
|
|
130
|
+
Recall Scope | $recall_scope_label"
|
|
131
|
+
fi
|
|
122
132
|
if [ "$stat_sessions_codex" -gt 0 ] || [ "$stat_sessions_claude" -gt 0 ]; then
|
|
123
133
|
eagle_banner+="
|
|
124
134
|
Sources | Claude $stat_sessions_claude, Codex $stat_sessions_codex"
|
|
@@ -137,12 +147,18 @@ eagle_banner+="
|
|
|
137
147
|
======================================"
|
|
138
148
|
|
|
139
149
|
context="$eagle_banner
|
|
150
|
+
Eagle Mem recalls: use the project memory below before making design or implementation claims. If it affects your answer, mention the recall in one short attribution line.
|
|
140
151
|
"
|
|
141
152
|
|
|
142
153
|
if [ "$codex_compact" -eq 1 ]; then
|
|
143
154
|
codex_context="Eagle Mem Recall Ready
|
|
144
155
|
Project: $project | Agent: $agent_label
|
|
145
156
|
Memory: $stat_sessions sessions"
|
|
157
|
+
if [ "$recall_scope_label" != "$project" ]; then
|
|
158
|
+
codex_context="Eagle Mem Recall Ready
|
|
159
|
+
Project: $project | Recall: $recall_scope_label | Agent: $agent_label
|
|
160
|
+
Memory: $stat_sessions sessions"
|
|
161
|
+
fi
|
|
146
162
|
[ "$stat_with_summaries" -gt 0 ] && codex_context+=", $stat_with_summaries summarized"
|
|
147
163
|
[ "$stat_memories" -gt 0 ] && codex_context+=", $stat_memories memories"
|
|
148
164
|
[ "$stat_chunks" -gt 0 ] && codex_context+=", $stat_chunks code chunks"
|
|
@@ -172,7 +188,7 @@ Project brief: no overview yet; background scan is running.
|
|
|
172
188
|
"
|
|
173
189
|
fi
|
|
174
190
|
|
|
175
|
-
recent=$(eagle_get_recent_summaries "$
|
|
191
|
+
recent=$(eagle_get_recent_summaries "$recall_scope" 1)
|
|
176
192
|
if [ -n "$recent" ]; then
|
|
177
193
|
codex_context+="
|
|
178
194
|
Relevant now:
|
|
@@ -194,16 +210,18 @@ Relevant now:
|
|
|
194
210
|
memories=$(eagle_db "SELECT memory_name, memory_type, description, origin_agent,
|
|
195
211
|
CAST(julianday('now') - julianday(updated_at) AS INTEGER) as days_ago
|
|
196
212
|
FROM agent_memories
|
|
197
|
-
WHERE
|
|
213
|
+
WHERE $recall_project_filter
|
|
214
|
+
AND memory_name NOT IN ('Codex Memory Registry', 'Codex Memory Summary')
|
|
198
215
|
ORDER BY
|
|
199
216
|
CASE
|
|
200
217
|
WHEN lower(memory_name) LIKE 'current status%' THEN 4
|
|
201
|
-
WHEN memory_type
|
|
202
|
-
WHEN memory_type = '
|
|
203
|
-
|
|
218
|
+
WHEN memory_type = 'project' THEN 0
|
|
219
|
+
WHEN memory_type = 'feedback' THEN 1
|
|
220
|
+
WHEN memory_type IN ('user', 'reference') THEN 2
|
|
221
|
+
ELSE 3
|
|
204
222
|
END,
|
|
205
223
|
updated_at DESC
|
|
206
|
-
LIMIT
|
|
224
|
+
LIMIT 4;")
|
|
207
225
|
if [ -n "$memories" ]; then
|
|
208
226
|
[ -z "$recent" ] && codex_context+="
|
|
209
227
|
Relevant now:
|
|
@@ -225,7 +243,7 @@ Relevant now:
|
|
|
225
243
|
fi
|
|
226
244
|
|
|
227
245
|
synced_tasks=$(eagle_db "SELECT subject, status, blocked_by, origin_agent FROM agent_tasks
|
|
228
|
-
WHERE
|
|
246
|
+
WHERE $recall_project_filter
|
|
229
247
|
AND status IN ('in_progress', 'pending')
|
|
230
248
|
AND source_session_id != 'orchestration'
|
|
231
249
|
AND updated_at > strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-7 days')
|
|
@@ -234,7 +252,7 @@ Relevant now:
|
|
|
234
252
|
orchestration_lanes=$(eagle_db "SELECT o.name, l.lane_key, l.title, l.agent, l.status
|
|
235
253
|
FROM orchestration_lanes l
|
|
236
254
|
JOIN orchestrations o ON o.id = l.orchestration_id
|
|
237
|
-
WHERE
|
|
255
|
+
WHERE $recall_lane_filter
|
|
238
256
|
AND o.status = 'active'
|
|
239
257
|
AND l.status IN ('in_progress', 'pending', 'blocked')
|
|
240
258
|
ORDER BY CASE l.status WHEN 'in_progress' THEN 0 WHEN 'blocked' THEN 1 ELSE 2 END, l.updated_at DESC
|
|
@@ -361,7 +379,7 @@ else
|
|
|
361
379
|
_summary_limit=2
|
|
362
380
|
fi
|
|
363
381
|
|
|
364
|
-
recent=$(eagle_get_recent_summaries "$
|
|
382
|
+
recent=$(eagle_get_recent_summaries "$recall_scope" "$_summary_limit")
|
|
365
383
|
|
|
366
384
|
if [ -n "$recent" ]; then
|
|
367
385
|
context+="
|
|
@@ -410,18 +428,20 @@ fi
|
|
|
410
428
|
|
|
411
429
|
# ─── Memories (skip if none) ─────────────────────────────
|
|
412
430
|
|
|
413
|
-
memory_limit=
|
|
414
|
-
[ "$codex_compact" -eq 1 ] && memory_limit=
|
|
431
|
+
memory_limit=5
|
|
432
|
+
[ "$codex_compact" -eq 1 ] && memory_limit=3
|
|
415
433
|
memories=$(eagle_db "SELECT memory_name, memory_type, description, file_path, updated_at, origin_agent,
|
|
416
434
|
CAST(julianday('now') - julianday(updated_at) AS INTEGER) as days_ago
|
|
417
435
|
FROM agent_memories
|
|
418
|
-
WHERE
|
|
436
|
+
WHERE $recall_project_filter
|
|
437
|
+
AND memory_name NOT IN ('Codex Memory Registry', 'Codex Memory Summary')
|
|
419
438
|
ORDER BY
|
|
420
439
|
CASE
|
|
421
440
|
WHEN lower(memory_name) LIKE 'current status%' THEN 4
|
|
422
|
-
WHEN memory_type
|
|
423
|
-
WHEN memory_type = '
|
|
424
|
-
|
|
441
|
+
WHEN memory_type = 'project' THEN 0
|
|
442
|
+
WHEN memory_type = 'feedback' THEN 1
|
|
443
|
+
WHEN memory_type IN ('user', 'reference') THEN 2
|
|
444
|
+
ELSE 3
|
|
425
445
|
END,
|
|
426
446
|
updated_at DESC
|
|
427
447
|
LIMIT $memory_limit;")
|
|
@@ -450,7 +470,7 @@ fi
|
|
|
450
470
|
|
|
451
471
|
# ─── Plans (skip if none) ────────────────────────────────
|
|
452
472
|
|
|
453
|
-
plans=$(eagle_list_agent_plans "$
|
|
473
|
+
plans=$(eagle_list_agent_plans "$recall_scope" 3)
|
|
454
474
|
if [ -n "$plans" ]; then
|
|
455
475
|
context+="
|
|
456
476
|
=== Eagle Mem: Plans ===
|
|
@@ -468,7 +488,7 @@ fi
|
|
|
468
488
|
task_limit=5
|
|
469
489
|
[ "$codex_compact" -eq 1 ] && task_limit=3
|
|
470
490
|
synced_tasks=$(eagle_db "SELECT subject, status, blocked_by, origin_agent FROM agent_tasks
|
|
471
|
-
WHERE
|
|
491
|
+
WHERE $recall_project_filter
|
|
472
492
|
AND status IN ('in_progress', 'pending')
|
|
473
493
|
AND source_session_id != 'orchestration'
|
|
474
494
|
AND updated_at > strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-7 days')
|
|
@@ -501,7 +521,7 @@ orchestration_lanes=$(eagle_db "SELECT o.name, o.goal, l.lane_key, l.title,
|
|
|
501
521
|
l.agent, l.status, l.validation, l.worktree_path, l.notes
|
|
502
522
|
FROM orchestration_lanes l
|
|
503
523
|
JOIN orchestrations o ON o.id = l.orchestration_id
|
|
504
|
-
WHERE
|
|
524
|
+
WHERE $recall_lane_filter
|
|
505
525
|
AND o.status = 'active'
|
|
506
526
|
AND l.status IN ('in_progress', 'pending', 'blocked')
|
|
507
527
|
ORDER BY
|
|
@@ -26,6 +26,8 @@ agent=$(eagle_agent_source_from_json "$input")
|
|
|
26
26
|
[ -z "$user_prompt" ] && exit 0
|
|
27
27
|
|
|
28
28
|
project=$(eagle_project_from_hook_input "$input")
|
|
29
|
+
recall_scope=$(eagle_recall_project_scope_from_cwd "$cwd" "$project")
|
|
30
|
+
[ -z "$recall_scope" ] && recall_scope="$project"
|
|
29
31
|
codex_compact=0
|
|
30
32
|
[ "$agent" = "codex" ] && codex_compact=1
|
|
31
33
|
|
|
@@ -93,8 +95,10 @@ fts_query=$(echo "$user_prompt" | tr -cs '[:alnum:]' ' ' | tr '[:upper:]' '[:low
|
|
|
93
95
|
split("the a an is are was were be been being have has had do does did will would shall should may might can could of in to for on with at by from", sw, " ")
|
|
94
96
|
for (i in sw) stop[sw[i]]=1
|
|
95
97
|
n=0
|
|
98
|
+
split("ad ai ui ux db", keep, " ")
|
|
99
|
+
for (i in keep) short_keep[keep[i]]=1
|
|
96
100
|
for (i=1; i<=NF && n<6; i++) {
|
|
97
|
-
if (length($i) > 2 && !($i in stop)) {
|
|
101
|
+
if ((length($i) > 2 || ($i in short_keep)) && !($i in stop)) {
|
|
98
102
|
printf "%s%s", (n>0?" OR ":""), $i; n++
|
|
99
103
|
}
|
|
100
104
|
}
|
|
@@ -137,15 +141,21 @@ if [ "$codex_compact" -eq 1 ]; then
|
|
|
137
141
|
code_limit=2
|
|
138
142
|
fi
|
|
139
143
|
|
|
140
|
-
|
|
144
|
+
memory_limit=3
|
|
145
|
+
[ "$codex_compact" -eq 1 ] && memory_limit=2
|
|
141
146
|
|
|
142
|
-
|
|
147
|
+
results=$(eagle_search_summaries "$fts_query" "$recall_scope" "$summary_limit")
|
|
148
|
+
memory_results=$(eagle_search_agent_memories "$fts_query" "$recall_scope" "$memory_limit" 2>/dev/null || true)
|
|
149
|
+
|
|
150
|
+
if [ -n "$results" ] || [ -n "$memory_results" ]; then
|
|
143
151
|
if [ "$codex_compact" -eq 1 ]; then
|
|
144
152
|
context+="
|
|
145
153
|
Eagle Mem recalls:
|
|
146
154
|
"
|
|
147
155
|
else
|
|
148
|
-
context+="
|
|
156
|
+
context+="Eagle Mem recalls: apply these retrieved project facts before answering. If they are relevant to the user's prompt, start with one short \"Eagle Mem recalls:\" attribution line.
|
|
157
|
+
|
|
158
|
+
=== Eagle Mem: Relevant Recall ===
|
|
149
159
|
"
|
|
150
160
|
fi
|
|
151
161
|
while IFS='|' read -r req completed learned _next_steps created_at _proj decisions gotchas key_files summary_agent; do
|
|
@@ -186,6 +196,30 @@ Eagle Mem recalls:
|
|
|
186
196
|
"
|
|
187
197
|
fi
|
|
188
198
|
done <<< "$results"
|
|
199
|
+
|
|
200
|
+
while IFS='|' read -r mname mtype mdesc msnippet _mfile _mupdated morigin; do
|
|
201
|
+
[ -z "$mname" ] && continue
|
|
202
|
+
case "$mname" in
|
|
203
|
+
"Codex Memory Registry"|"Codex Memory Summary") continue ;;
|
|
204
|
+
esac
|
|
205
|
+
origin_label=$(eagle_agent_label "$morigin")
|
|
206
|
+
if [ "$codex_compact" -eq 1 ]; then
|
|
207
|
+
mdesc=$(eagle_trim_text "$mdesc" 120)
|
|
208
|
+
context+="- Memory [$mtype][$origin_label]: $mname"
|
|
209
|
+
[ -n "$mdesc" ] && context+=" — $mdesc"
|
|
210
|
+
context+="
|
|
211
|
+
"
|
|
212
|
+
else
|
|
213
|
+
mdesc=$(eagle_trim_text "$mdesc" 180)
|
|
214
|
+
msnippet=$(eagle_trim_text "$msnippet" 220)
|
|
215
|
+
context+="[Memory][$origin_label][$mtype] $mname"
|
|
216
|
+
[ -n "$mdesc" ] && context+=" — $mdesc"
|
|
217
|
+
[ -n "$msnippet" ] && context+="
|
|
218
|
+
Snippet: $msnippet"
|
|
219
|
+
context+="
|
|
220
|
+
"
|
|
221
|
+
fi
|
|
222
|
+
done <<< "$memory_results"
|
|
189
223
|
fi
|
|
190
224
|
|
|
191
225
|
# Search indexed code chunks (if any exist for this project)
|
package/lib/common.sh
CHANGED
|
@@ -362,6 +362,121 @@ eagle_project_from_existing_ancestor() {
|
|
|
362
362
|
return 1
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
+
eagle_project_has_recall_rows() {
|
|
366
|
+
local project="${1:-}"
|
|
367
|
+
[ -n "$project" ] || return 1
|
|
368
|
+
|
|
369
|
+
eagle_project_has_table_row "agent_memories" "$project" \
|
|
370
|
+
|| eagle_project_has_table_row "agent_plans" "$project" \
|
|
371
|
+
|| eagle_project_has_table_row "agent_tasks" "$project" \
|
|
372
|
+
|| eagle_project_has_table_row "summaries" "$project"
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
eagle_recall_ancestor_project_from_cwd() {
|
|
376
|
+
local path="${1:-$(pwd)}"
|
|
377
|
+
local current_project="${2:-}"
|
|
378
|
+
local current key
|
|
379
|
+
|
|
380
|
+
current=$(eagle_normalize_project_path "$path")
|
|
381
|
+
eagle_is_ephemeral_project_path "$current" && return 1
|
|
382
|
+
|
|
383
|
+
[ -d "$current" ] || current=$(dirname "$current")
|
|
384
|
+
current=$(dirname "$current")
|
|
385
|
+
|
|
386
|
+
while [ -n "$current" ] && [ "$current" != "/" ]; do
|
|
387
|
+
if [ "$current" = "$HOME" ]; then
|
|
388
|
+
break
|
|
389
|
+
fi
|
|
390
|
+
|
|
391
|
+
key=$(eagle_project_key_from_target_dir "$current")
|
|
392
|
+
if [ -n "$key" ] && [ "$key" != "$current_project" ]; then
|
|
393
|
+
if eagle_project_has_recall_rows "$key"; then
|
|
394
|
+
printf '%s\n' "$key"
|
|
395
|
+
return 0
|
|
396
|
+
fi
|
|
397
|
+
fi
|
|
398
|
+
|
|
399
|
+
current=$(dirname "$current")
|
|
400
|
+
done
|
|
401
|
+
|
|
402
|
+
return 1
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
eagle_recall_project_scope_from_cwd() {
|
|
406
|
+
local path="${1:-$(pwd)}"
|
|
407
|
+
local project="${2:-}"
|
|
408
|
+
local ancestor
|
|
409
|
+
|
|
410
|
+
[ -z "$project" ] && project=$(eagle_project_from_cwd "$path")
|
|
411
|
+
if ancestor=$(eagle_recall_ancestor_project_from_cwd "$path" "$project"); then
|
|
412
|
+
if [ -n "$project" ] && [ "$ancestor" != "$project" ]; then
|
|
413
|
+
printf '%s|%s\n' "$project" "$ancestor"
|
|
414
|
+
return 0
|
|
415
|
+
fi
|
|
416
|
+
printf '%s\n' "$ancestor"
|
|
417
|
+
return 0
|
|
418
|
+
fi
|
|
419
|
+
|
|
420
|
+
printf '%s\n' "$project"
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
eagle_sql_project_scope_condition() {
|
|
424
|
+
local column="${1:-project}"
|
|
425
|
+
local scope="${2:-}"
|
|
426
|
+
local values="" count=0 item escaped
|
|
427
|
+
|
|
428
|
+
while IFS= read -r item; do
|
|
429
|
+
[ -n "$item" ] || continue
|
|
430
|
+
escaped=$(eagle_sql_escape "$item")
|
|
431
|
+
values="${values},'${escaped}'"
|
|
432
|
+
count=$((count + 1))
|
|
433
|
+
done <<EOF
|
|
434
|
+
$(printf '%s' "$scope" | tr '|' '\n')
|
|
435
|
+
EOF
|
|
436
|
+
|
|
437
|
+
if [ "$count" -eq 0 ]; then
|
|
438
|
+
printf '1 = 0\n'
|
|
439
|
+
elif [ "$count" -eq 1 ]; then
|
|
440
|
+
printf "%s = %s\n" "$column" "${values#,}"
|
|
441
|
+
else
|
|
442
|
+
printf "%s IN (%s)\n" "$column" "${values#,}"
|
|
443
|
+
fi
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
eagle_project_scope_label() {
|
|
447
|
+
local scope="${1:-}"
|
|
448
|
+
printf '%s\n' "$scope" | tr '|' ','
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
eagle_project_scope_contains() {
|
|
452
|
+
local scope="${1:-}"
|
|
453
|
+
local target="${2:-}"
|
|
454
|
+
local item
|
|
455
|
+
[ -n "$target" ] || return 1
|
|
456
|
+
|
|
457
|
+
while IFS= read -r item; do
|
|
458
|
+
[ -z "$item" ] && continue
|
|
459
|
+
[ "$item" = "$target" ] && return 0
|
|
460
|
+
done <<EOF
|
|
461
|
+
$(printf '%s' "$scope" | tr '|' '\n')
|
|
462
|
+
EOF
|
|
463
|
+
|
|
464
|
+
return 1
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
eagle_claude_project_dir_for_key() {
|
|
468
|
+
local project="${1:-}"
|
|
469
|
+
[ -n "$project" ] || return 1
|
|
470
|
+
|
|
471
|
+
local abs slug
|
|
472
|
+
case "$project" in
|
|
473
|
+
/*) abs="$project" ;;
|
|
474
|
+
*) abs="$HOME/$project" ;;
|
|
475
|
+
esac
|
|
476
|
+
slug=$(printf '%s' "$abs" | sed -E 's#[^[:alnum:].]+#-#g')
|
|
477
|
+
printf '%s/%s\n' "$EAGLE_CLAUDE_PROJECTS_DIR" "$slug"
|
|
478
|
+
}
|
|
479
|
+
|
|
365
480
|
eagle_project_from_workspace_path() {
|
|
366
481
|
if [ -n "${EAGLE_MEM_PROJECT:-}" ]; then
|
|
367
482
|
printf '%s\n' "$EAGLE_MEM_PROJECT"
|
|
@@ -728,20 +843,15 @@ eagle_emit_context_for_agent() {
|
|
|
728
843
|
|
|
729
844
|
[ -z "$context" ] && return 0
|
|
730
845
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
}'
|
|
741
|
-
return 0
|
|
742
|
-
fi
|
|
743
|
-
|
|
744
|
-
printf '%s\n' "$context"
|
|
846
|
+
jq -cn \
|
|
847
|
+
--arg event "$hook_event" \
|
|
848
|
+
--arg context "$context" \
|
|
849
|
+
'{
|
|
850
|
+
hookSpecificOutput: {
|
|
851
|
+
hookEventName: $event,
|
|
852
|
+
additionalContext: $context
|
|
853
|
+
}
|
|
854
|
+
}'
|
|
745
855
|
}
|
|
746
856
|
|
|
747
857
|
eagle_config_get_light() {
|
package/lib/db-mirrors.sh
CHANGED
|
@@ -103,8 +103,7 @@ eagle_search_agent_memories() {
|
|
|
103
103
|
|
|
104
104
|
local where_clause=""
|
|
105
105
|
if [ -n "$project" ]; then
|
|
106
|
-
|
|
107
|
-
where_clause="AND m.project = '$project'"
|
|
106
|
+
where_clause="AND $(eagle_sql_project_scope_condition "m.project" "$project")"
|
|
108
107
|
fi
|
|
109
108
|
|
|
110
109
|
eagle_db "SELECT m.memory_name, m.memory_type, m.description,
|
|
@@ -124,8 +123,7 @@ eagle_list_agent_memories() {
|
|
|
124
123
|
|
|
125
124
|
local where_clause=""
|
|
126
125
|
if [ -n "$project" ]; then
|
|
127
|
-
|
|
128
|
-
where_clause="WHERE project = '$project'"
|
|
126
|
+
where_clause="WHERE $(eagle_sql_project_scope_condition "project" "$project")"
|
|
129
127
|
fi
|
|
130
128
|
|
|
131
129
|
eagle_db "SELECT memory_name, memory_type, description, file_path, updated_at, origin_agent
|
|
@@ -198,8 +196,7 @@ eagle_search_agent_plans() {
|
|
|
198
196
|
|
|
199
197
|
local where_clause=""
|
|
200
198
|
if [ -n "$project" ]; then
|
|
201
|
-
|
|
202
|
-
where_clause="AND p.project = '$project'"
|
|
199
|
+
where_clause="AND $(eagle_sql_project_scope_condition "p.project" "$project")"
|
|
203
200
|
fi
|
|
204
201
|
|
|
205
202
|
eagle_db "SELECT p.title, p.project,
|
|
@@ -219,8 +216,7 @@ eagle_list_agent_plans() {
|
|
|
219
216
|
|
|
220
217
|
local where_clause=""
|
|
221
218
|
if [ -n "$project" ]; then
|
|
222
|
-
|
|
223
|
-
where_clause="WHERE project = '$project'"
|
|
219
|
+
where_clause="WHERE $(eagle_sql_project_scope_condition "project" "$project")"
|
|
224
220
|
fi
|
|
225
221
|
|
|
226
222
|
eagle_db "SELECT title, project, file_path, updated_at, origin_agent
|
|
@@ -303,8 +299,7 @@ eagle_list_agent_tasks() {
|
|
|
303
299
|
|
|
304
300
|
local where_clause=""
|
|
305
301
|
if [ -n "$project" ]; then
|
|
306
|
-
|
|
307
|
-
where_clause="WHERE project = '$project'"
|
|
302
|
+
where_clause="WHERE $(eagle_sql_project_scope_condition "project" "$project")"
|
|
308
303
|
fi
|
|
309
304
|
|
|
310
305
|
eagle_db "SELECT subject, status, source_session_id, source_task_id, updated_at, origin_agent
|
|
@@ -326,8 +321,7 @@ eagle_search_agent_tasks() {
|
|
|
326
321
|
|
|
327
322
|
local where_clause=""
|
|
328
323
|
if [ -n "$project" ]; then
|
|
329
|
-
|
|
330
|
-
where_clause="AND t.project = '$project'"
|
|
324
|
+
where_clause="AND $(eagle_sql_project_scope_condition "t.project" "$project")"
|
|
331
325
|
fi
|
|
332
326
|
|
|
333
327
|
eagle_db "SELECT t.subject, t.status,
|
package/lib/db-sessions.sh
CHANGED
|
@@ -167,24 +167,31 @@ eagle_abandon_stale_sessions() {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
eagle_get_project_stats() {
|
|
170
|
-
local
|
|
170
|
+
local project_scope="${1:-}"
|
|
171
|
+
local session_filter memory_filter plan_filter task_filter chunk_filter observation_filter
|
|
172
|
+
session_filter=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
173
|
+
memory_filter=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
174
|
+
plan_filter=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
175
|
+
task_filter=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
176
|
+
chunk_filter=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
177
|
+
observation_filter=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
171
178
|
eagle_db_pipe <<SQL
|
|
172
|
-
SELECT 'sessions|' || COUNT(*) FROM sessions WHERE
|
|
173
|
-
SELECT 'sessions_claude|' || COUNT(*) FROM sessions WHERE
|
|
174
|
-
SELECT 'sessions_codex|' || COUNT(*) FROM sessions WHERE
|
|
175
|
-
SELECT 'summaries|' || COUNT(*) FROM summaries WHERE
|
|
176
|
-
SELECT 'with_summaries|' || COUNT(*) FROM summaries WHERE
|
|
177
|
-
SELECT 'memories|' || COUNT(*) FROM agent_memories WHERE
|
|
178
|
-
SELECT 'plans|' || COUNT(*) FROM agent_plans WHERE
|
|
179
|
-
SELECT 'tasks_pending|' || COUNT(*) FROM agent_tasks WHERE
|
|
180
|
-
SELECT 'tasks_progress|' || COUNT(*) FROM agent_tasks WHERE
|
|
181
|
-
SELECT 'tasks_done|' || COUNT(*) FROM agent_tasks WHERE
|
|
182
|
-
SELECT 'chunks|' || COUNT(*) FROM code_chunks WHERE
|
|
183
|
-
SELECT 'observations|' || COUNT(*) FROM observations WHERE
|
|
184
|
-
SELECT 'last_active|' || COALESCE(MAX(date(COALESCE(last_activity_at, started_at))), 'never') FROM sessions WHERE
|
|
179
|
+
SELECT 'sessions|' || COUNT(*) FROM sessions WHERE $session_filter;
|
|
180
|
+
SELECT 'sessions_claude|' || COUNT(*) FROM sessions WHERE $session_filter AND agent = 'claude-code';
|
|
181
|
+
SELECT 'sessions_codex|' || COUNT(*) FROM sessions WHERE $session_filter AND agent = 'codex';
|
|
182
|
+
SELECT 'summaries|' || COUNT(*) FROM summaries WHERE $session_filter;
|
|
183
|
+
SELECT 'with_summaries|' || COUNT(*) FROM summaries WHERE $session_filter AND request IS NOT NULL AND request != '';
|
|
184
|
+
SELECT 'memories|' || COUNT(*) FROM agent_memories WHERE $memory_filter;
|
|
185
|
+
SELECT 'plans|' || COUNT(*) FROM agent_plans WHERE $plan_filter;
|
|
186
|
+
SELECT 'tasks_pending|' || COUNT(*) FROM agent_tasks WHERE $task_filter AND status = 'pending';
|
|
187
|
+
SELECT 'tasks_progress|' || COUNT(*) FROM agent_tasks WHERE $task_filter AND status = 'in_progress';
|
|
188
|
+
SELECT 'tasks_done|' || COUNT(*) FROM agent_tasks WHERE $task_filter AND status = 'completed';
|
|
189
|
+
SELECT 'chunks|' || COUNT(*) FROM code_chunks WHERE $chunk_filter;
|
|
190
|
+
SELECT 'observations|' || COUNT(*) FROM observations WHERE $observation_filter;
|
|
191
|
+
SELECT 'last_active|' || COALESCE(MAX(date(COALESCE(last_activity_at, started_at))), 'never') FROM sessions WHERE $session_filter;
|
|
185
192
|
SELECT 'last_summary|' || COALESCE((SELECT substr(request, 1, 60)
|
|
186
193
|
FROM summaries
|
|
187
|
-
WHERE
|
|
194
|
+
WHERE $session_filter
|
|
188
195
|
AND COALESCE(request, '') NOT LIKE '# AGENTS.md instructions%'
|
|
189
196
|
AND COALESCE(request, '') NOT LIKE '<environment_context>%'
|
|
190
197
|
ORDER BY created_at DESC
|
package/lib/db-summaries.sh
CHANGED
|
@@ -57,12 +57,16 @@ SQL
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
eagle_get_recent_summaries() {
|
|
60
|
-
local
|
|
60
|
+
local project_scope="${1:-}"
|
|
61
61
|
local limit; limit=$(eagle_sql_int "${2:-5}")
|
|
62
|
+
local project_filter="1 = 1"
|
|
63
|
+
if [ -n "$project_scope" ]; then
|
|
64
|
+
project_filter=$(eagle_sql_project_scope_condition "s.project" "$project_scope")
|
|
65
|
+
fi
|
|
62
66
|
|
|
63
67
|
eagle_db "SELECT s.request, s.completed, s.learned, s.next_steps, s.created_at, s.decisions, s.gotchas, s.key_files, s.agent
|
|
64
68
|
FROM summaries s
|
|
65
|
-
WHERE
|
|
69
|
+
WHERE $project_filter
|
|
66
70
|
AND COALESCE(s.request, '') NOT LIKE '%<local-command-caveat>%'
|
|
67
71
|
AND COALESCE(s.request, '') NOT LIKE '# AGENTS.md instructions%'
|
|
68
72
|
AND COALESCE(s.request, '') NOT LIKE '<environment_context>%'
|
|
@@ -73,13 +77,12 @@ eagle_get_recent_summaries() {
|
|
|
73
77
|
eagle_search_summaries() {
|
|
74
78
|
local query; query=$(eagle_fts_sanitize "$1")
|
|
75
79
|
query=$(eagle_sql_escape "$query")
|
|
76
|
-
local
|
|
80
|
+
local project_scope="${2:-}"
|
|
77
81
|
local limit; limit=$(eagle_sql_int "${3:-10}")
|
|
78
82
|
|
|
79
83
|
local where_clause=""
|
|
80
|
-
if [ -n "$
|
|
81
|
-
|
|
82
|
-
where_clause="AND s.project = '$project'"
|
|
84
|
+
if [ -n "$project_scope" ]; then
|
|
85
|
+
where_clause="AND $(eagle_sql_project_scope_condition "s.project" "$project_scope")"
|
|
83
86
|
fi
|
|
84
87
|
|
|
85
88
|
eagle_db "SELECT s.request, s.completed, s.learned, s.next_steps, s.created_at, s.project, s.decisions, s.gotchas, s.key_files, s.agent
|
package/package.json
CHANGED
package/scripts/memories.sh
CHANGED
|
@@ -24,6 +24,7 @@ case "${1:-}" in
|
|
|
24
24
|
esac
|
|
25
25
|
|
|
26
26
|
project=""
|
|
27
|
+
project_was_explicit=false
|
|
27
28
|
limit=20
|
|
28
29
|
query=""
|
|
29
30
|
raw_output=false
|
|
@@ -76,7 +77,7 @@ esac
|
|
|
76
77
|
|
|
77
78
|
while [ $# -gt 0 ]; do
|
|
78
79
|
case "$1" in
|
|
79
|
-
--project|-p) project="$2"; shift 2 ;;
|
|
80
|
+
--project|-p) project="$2"; project_was_explicit=true; shift 2 ;;
|
|
80
81
|
--limit|-l) limit="$2"; shift 2 ;;
|
|
81
82
|
--all|-a) cross_project=true; shift ;;
|
|
82
83
|
--raw|--debug) raw_output=true; shift ;;
|
|
@@ -95,6 +96,9 @@ done
|
|
|
95
96
|
if [ -z "$project" ] && [ "$cross_project" = false ]; then
|
|
96
97
|
project=$(eagle_project_from_cwd "$(pwd)")
|
|
97
98
|
fi
|
|
99
|
+
if [ "$cross_project" = false ] && [ "$project_was_explicit" = false ]; then
|
|
100
|
+
project=$(eagle_recall_project_scope_from_cwd "$(pwd)" "$project")
|
|
101
|
+
fi
|
|
98
102
|
|
|
99
103
|
eagle_age_label() {
|
|
100
104
|
local updated="${1:-}"
|
|
@@ -230,7 +234,7 @@ memories_show() {
|
|
|
230
234
|
query_sql=$(eagle_sql_escape "$query")
|
|
231
235
|
project_filter=""
|
|
232
236
|
if [ -n "$project" ]; then
|
|
233
|
-
project_filter="AND
|
|
237
|
+
project_filter="AND $(eagle_sql_project_scope_condition "project" "$project")"
|
|
234
238
|
fi
|
|
235
239
|
|
|
236
240
|
meta_json=$(eagle_db_json "SELECT memory_name, memory_type, description, content, file_path, updated_at, origin_session_id, origin_agent
|
|
@@ -370,7 +374,7 @@ plans_show() {
|
|
|
370
374
|
query_sql=$(eagle_sql_escape "$query")
|
|
371
375
|
project_filter=""
|
|
372
376
|
if [ -n "$project" ]; then
|
|
373
|
-
project_filter="AND
|
|
377
|
+
project_filter="AND $(eagle_sql_project_scope_condition "project" "$project")"
|
|
374
378
|
fi
|
|
375
379
|
meta_json=$(eagle_db_json "SELECT title, project, content, file_path, updated_at, origin_session_id, origin_agent
|
|
376
380
|
FROM agent_plans
|
|
@@ -517,7 +521,7 @@ tasks_show() {
|
|
|
517
521
|
query_sql=$(eagle_sql_escape "$query")
|
|
518
522
|
project_filter=""
|
|
519
523
|
if [ -n "$project" ]; then
|
|
520
|
-
project_filter="AND
|
|
524
|
+
project_filter="AND $(eagle_sql_project_scope_condition "project" "$project")"
|
|
521
525
|
fi
|
|
522
526
|
meta_json=$(eagle_db_json "SELECT subject, status, description, active_form, source_session_id, source_task_id, file_path, updated_at, origin_agent
|
|
523
527
|
FROM agent_tasks
|
|
@@ -575,6 +579,33 @@ tasks_show() {
|
|
|
575
579
|
memories_sync() {
|
|
576
580
|
eagle_header "Memory, Plan & Task Sync"
|
|
577
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
|
+
|
|
578
609
|
# ─── Sync memories ───────────────────────────────────
|
|
579
610
|
eagle_info "Scanning for agent memory files..."
|
|
580
611
|
echo ""
|
|
@@ -583,15 +614,21 @@ memories_sync() {
|
|
|
583
614
|
local mem_synced=0
|
|
584
615
|
local mem_skipped=0
|
|
585
616
|
|
|
586
|
-
|
|
587
|
-
|
|
617
|
+
sync_one_memory_file() {
|
|
618
|
+
local memfile="$1"
|
|
619
|
+
[ -f "$memfile" ] || return 0
|
|
620
|
+
|
|
588
621
|
local base
|
|
589
622
|
base=$(basename "$memfile")
|
|
590
|
-
[ "$base" = "MEMORY.md" ] &&
|
|
623
|
+
[ "$base" = "MEMORY.md" ] && return 0
|
|
591
624
|
|
|
592
625
|
local mem_project mem_project_dir existing_row existing_hash existing_project
|
|
593
626
|
mem_project_dir="${memfile%/memory/*}"
|
|
594
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
|
+
|
|
595
632
|
existing_row=$(eagle_db "SELECT content_hash, project FROM agent_memories WHERE file_path = '$(eagle_sql_escape "$memfile")';")
|
|
596
633
|
IFS='|' read -r existing_hash existing_project <<< "$existing_row"
|
|
597
634
|
local new_hash
|
|
@@ -605,7 +642,25 @@ memories_sync() {
|
|
|
605
642
|
eagle_capture_agent_memory "$memfile" "" "$mem_project" "claude-code"
|
|
606
643
|
mem_synced=$((mem_synced + 1))
|
|
607
644
|
eagle_ok "Memory: $base"
|
|
608
|
-
|
|
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
|
|
609
664
|
fi
|
|
610
665
|
|
|
611
666
|
local codex_mem_root="$EAGLE_CODEX_MEMORIES_DIR"
|
|
@@ -710,12 +765,16 @@ memories_sync() {
|
|
|
710
765
|
# ─── Backfill project names ──────────────────────────
|
|
711
766
|
eagle_info "Resolving project names from agent transcripts..."
|
|
712
767
|
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
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
|
|
717
776
|
else
|
|
718
|
-
eagle_ok "
|
|
777
|
+
eagle_ok "Scoped sync complete; use --all for global transcript backfill"
|
|
719
778
|
fi
|
|
720
779
|
|
|
721
780
|
eagle_footer "Sync complete."
|
package/scripts/search.sh
CHANGED
|
@@ -43,6 +43,9 @@ show_help() {
|
|
|
43
43
|
|
|
44
44
|
mode="keyword"
|
|
45
45
|
project=""
|
|
46
|
+
project_was_explicit=false
|
|
47
|
+
project_scope=""
|
|
48
|
+
project_label=""
|
|
46
49
|
limit=10
|
|
47
50
|
session_id=""
|
|
48
51
|
json_output=false
|
|
@@ -59,7 +62,7 @@ while [ $# -gt 0 ]; do
|
|
|
59
62
|
--overview|-o) mode="overview"; shift ;;
|
|
60
63
|
--memories|-m) mode="memories"; shift ;;
|
|
61
64
|
--tasks) mode="tasks"; shift ;;
|
|
62
|
-
--project|-p) project="$2"; shift 2 ;;
|
|
65
|
+
--project|-p) project="$2"; project_was_explicit=true; shift 2 ;;
|
|
63
66
|
--limit|-n) limit="$2"; shift 2 ;;
|
|
64
67
|
--all|-a) cross_project=true; shift ;;
|
|
65
68
|
--json|-j) json_output=true; shift ;;
|
|
@@ -75,6 +78,12 @@ while [ $# -gt 0 ]; do
|
|
|
75
78
|
done
|
|
76
79
|
|
|
77
80
|
[ -z "$project" ] && project=$(eagle_project_from_cwd "$(pwd)")
|
|
81
|
+
project_scope="$project"
|
|
82
|
+
if [ "$cross_project" = false ] && [ "$project_was_explicit" = false ]; then
|
|
83
|
+
project_scope=$(eagle_recall_project_scope_from_cwd "$(pwd)" "$project")
|
|
84
|
+
fi
|
|
85
|
+
project_label=$(eagle_project_scope_label "$project_scope")
|
|
86
|
+
[ -z "$project_label" ] && project_label="$project"
|
|
78
87
|
limit=$(eagle_sql_int "$limit")
|
|
79
88
|
[ "$limit" -eq 0 ] && limit=10
|
|
80
89
|
|
|
@@ -88,11 +97,12 @@ search_keyword() {
|
|
|
88
97
|
exit 1
|
|
89
98
|
fi
|
|
90
99
|
local q; q=$(eagle_sql_escape "$sanitized_q")
|
|
91
|
-
local
|
|
100
|
+
local project_condition
|
|
101
|
+
project_condition=$(eagle_sql_project_scope_condition "s.project" "$project_scope")
|
|
92
102
|
|
|
93
103
|
local where_project=""
|
|
94
104
|
if [ "$cross_project" = false ]; then
|
|
95
|
-
where_project="AND
|
|
105
|
+
where_project="AND $project_condition"
|
|
96
106
|
fi
|
|
97
107
|
|
|
98
108
|
if [ "$json_output" = true ]; then
|
|
@@ -173,12 +183,13 @@ search_keyword() {
|
|
|
173
183
|
# ─── Timeline ────────────────────────────────────────────
|
|
174
184
|
|
|
175
185
|
search_timeline() {
|
|
176
|
-
local
|
|
186
|
+
local project_condition
|
|
187
|
+
project_condition=$(eagle_sql_project_scope_condition "s.project" "$project_scope")
|
|
177
188
|
|
|
178
189
|
if [ "$json_output" = true ]; then
|
|
179
190
|
eagle_db_json "SELECT s.id, s.agent, s.request, s.completed, s.learned, s.next_steps, s.created_at
|
|
180
191
|
FROM summaries s
|
|
181
|
-
WHERE
|
|
192
|
+
WHERE $project_condition
|
|
182
193
|
ORDER BY s.created_at DESC
|
|
183
194
|
LIMIT $limit;"
|
|
184
195
|
return
|
|
@@ -187,7 +198,7 @@ search_timeline() {
|
|
|
187
198
|
local results
|
|
188
199
|
results=$(eagle_db "SELECT s.id, s.agent, s.request, s.completed, s.learned, s.next_steps, s.created_at
|
|
189
200
|
FROM summaries s
|
|
190
|
-
WHERE
|
|
201
|
+
WHERE $project_condition
|
|
191
202
|
ORDER BY s.created_at DESC
|
|
192
203
|
LIMIT $limit;")
|
|
193
204
|
|
|
@@ -197,7 +208,7 @@ search_timeline() {
|
|
|
197
208
|
fi
|
|
198
209
|
|
|
199
210
|
echo ""
|
|
200
|
-
echo -e " ${BOLD}Recent sessions${RESET} ${DIM}($
|
|
211
|
+
echo -e " ${BOLD}Recent sessions${RESET} ${DIM}($project_label)${RESET}"
|
|
201
212
|
echo -e " ${DIM}─────────────────────────────────────${RESET}"
|
|
202
213
|
echo ""
|
|
203
214
|
|
|
@@ -401,20 +412,25 @@ search_files() {
|
|
|
401
412
|
# ─── Stats ────────────────────────────────────────────────
|
|
402
413
|
|
|
403
414
|
search_stats() {
|
|
404
|
-
local
|
|
415
|
+
local sessions_condition summaries_condition observations_condition tasks_condition chunks_condition
|
|
416
|
+
sessions_condition=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
417
|
+
summaries_condition=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
418
|
+
observations_condition=$(eagle_sql_project_scope_condition "s.project" "$project_scope")
|
|
419
|
+
tasks_condition=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
420
|
+
chunks_condition=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
405
421
|
|
|
406
422
|
local sessions sessions_claude sessions_codex summaries observations tasks
|
|
407
|
-
sessions=$(eagle_db "SELECT COUNT(*) FROM sessions WHERE
|
|
408
|
-
sessions_claude=$(eagle_db "SELECT COUNT(*) FROM sessions WHERE
|
|
409
|
-
sessions_codex=$(eagle_db "SELECT COUNT(*) FROM sessions WHERE
|
|
410
|
-
summaries=$(eagle_db "SELECT COUNT(*) FROM summaries WHERE
|
|
411
|
-
observations=$(eagle_db "SELECT COUNT(*) FROM observations o JOIN sessions s ON s.id = o.session_id WHERE
|
|
412
|
-
tasks=$(eagle_db "SELECT COUNT(*) FROM agent_tasks WHERE
|
|
423
|
+
sessions=$(eagle_db "SELECT COUNT(*) FROM sessions WHERE $sessions_condition;")
|
|
424
|
+
sessions_claude=$(eagle_db "SELECT COUNT(*) FROM sessions WHERE $sessions_condition AND agent = 'claude-code';")
|
|
425
|
+
sessions_codex=$(eagle_db "SELECT COUNT(*) FROM sessions WHERE $sessions_condition AND agent = 'codex';")
|
|
426
|
+
summaries=$(eagle_db "SELECT COUNT(*) FROM summaries WHERE $summaries_condition;")
|
|
427
|
+
observations=$(eagle_db "SELECT COUNT(*) FROM observations o JOIN sessions s ON s.id = o.session_id WHERE $observations_condition;")
|
|
428
|
+
tasks=$(eagle_db "SELECT COUNT(*) FROM agent_tasks WHERE $tasks_condition;")
|
|
413
429
|
local chunks
|
|
414
|
-
chunks=$(eagle_db "SELECT COUNT(*) FROM code_chunks WHERE
|
|
430
|
+
chunks=$(eagle_db "SELECT COUNT(*) FROM code_chunks WHERE $chunks_condition;")
|
|
415
431
|
|
|
416
432
|
if [ "$json_output" = true ]; then
|
|
417
|
-
jq -nc --arg project "$
|
|
433
|
+
jq -nc --arg project "$project_label" \
|
|
418
434
|
--argjson sessions "${sessions:-0}" \
|
|
419
435
|
--argjson sessions_claude "${sessions_claude:-0}" \
|
|
420
436
|
--argjson sessions_codex "${sessions_codex:-0}" \
|
|
@@ -427,7 +443,7 @@ search_stats() {
|
|
|
427
443
|
fi
|
|
428
444
|
|
|
429
445
|
echo ""
|
|
430
|
-
echo -e " ${BOLD}Stats${RESET} ${DIM}($
|
|
446
|
+
echo -e " ${BOLD}Stats${RESET} ${DIM}($project_label)${RESET}"
|
|
431
447
|
echo -e " ${DIM}─────────────────────────────────────${RESET}"
|
|
432
448
|
echo ""
|
|
433
449
|
eagle_kv "Sessions:" "${sessions:-0}"
|
|
@@ -474,11 +490,13 @@ search_overview() {
|
|
|
474
490
|
# ─── Memories ────────────────────────────────────────────
|
|
475
491
|
|
|
476
492
|
search_memories() {
|
|
477
|
-
local
|
|
493
|
+
local project_condition memory_condition
|
|
494
|
+
project_condition=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
495
|
+
memory_condition=$(eagle_sql_project_scope_condition "m.project" "$project_scope")
|
|
478
496
|
|
|
479
497
|
local where_project=""
|
|
480
498
|
if [ "$cross_project" = false ]; then
|
|
481
|
-
where_project="WHERE
|
|
499
|
+
where_project="WHERE $project_condition"
|
|
482
500
|
fi
|
|
483
501
|
|
|
484
502
|
if [ -n "$query" ]; then
|
|
@@ -491,7 +509,7 @@ search_memories() {
|
|
|
491
509
|
local q; q=$(eagle_sql_escape "$sanitized_mq")
|
|
492
510
|
local where_match="WHERE agent_memories_fts MATCH '$q'"
|
|
493
511
|
if [ "$cross_project" = false ]; then
|
|
494
|
-
where_match="$where_match AND
|
|
512
|
+
where_match="$where_match AND $memory_condition"
|
|
495
513
|
fi
|
|
496
514
|
|
|
497
515
|
if [ "$json_output" = true ]; then
|
|
@@ -570,7 +588,7 @@ search_memories() {
|
|
|
570
588
|
fi
|
|
571
589
|
|
|
572
590
|
echo ""
|
|
573
|
-
echo -e " ${BOLD}Memories${RESET} ${DIM}($
|
|
591
|
+
echo -e " ${BOLD}Memories${RESET} ${DIM}($project_label)${RESET}"
|
|
574
592
|
echo -e " ${DIM}─────────────────────────────────────${RESET}"
|
|
575
593
|
echo ""
|
|
576
594
|
|
|
@@ -585,13 +603,15 @@ search_memories() {
|
|
|
585
603
|
# ─── Tasks ───────────────────────────────────────────────
|
|
586
604
|
|
|
587
605
|
search_tasks() {
|
|
588
|
-
local
|
|
606
|
+
local task_condition bare_task_condition
|
|
607
|
+
task_condition=$(eagle_sql_project_scope_condition "t.project" "$project_scope")
|
|
608
|
+
bare_task_condition=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
589
609
|
|
|
590
610
|
local where_project=""
|
|
591
611
|
local where_task_project=""
|
|
592
612
|
if [ "$cross_project" = false ]; then
|
|
593
|
-
where_project="AND
|
|
594
|
-
where_task_project="AND
|
|
613
|
+
where_project="AND $bare_task_condition"
|
|
614
|
+
where_task_project="AND $task_condition"
|
|
595
615
|
fi
|
|
596
616
|
|
|
597
617
|
if [ -n "$query" ]; then
|
|
@@ -662,7 +682,7 @@ search_tasks() {
|
|
|
662
682
|
LIMIT $limit;")
|
|
663
683
|
|
|
664
684
|
if [ -z "$results" ]; then
|
|
665
|
-
eagle_dim "No active tasks for project '$
|
|
685
|
+
eagle_dim "No active tasks for project '$project_label'"
|
|
666
686
|
return
|
|
667
687
|
fi
|
|
668
688
|
|
package/scripts/statusline-em.sh
CHANGED
|
@@ -58,17 +58,18 @@ eagle_mem_statusline_stats() {
|
|
|
58
58
|
[ -z "$project_dir" ] && project_dir="$(pwd)"
|
|
59
59
|
[ -z "$current_dir" ] && current_dir="$project_dir"
|
|
60
60
|
|
|
61
|
-
local project_key
|
|
61
|
+
local project_key project_scope project_condition stats sessions memories last_raw turns version latest
|
|
62
62
|
project_key=$(eagle_project_from_statusline_input "$statusline_input" "$project_dir" "$current_dir" "$session_id")
|
|
63
63
|
[ -n "$project_key" ] || return
|
|
64
|
-
|
|
64
|
+
project_scope=$(eagle_recall_project_scope_from_cwd "${current_dir:-$project_dir}" "$project_key")
|
|
65
|
+
project_condition=$(eagle_sql_project_scope_condition "project" "$project_scope")
|
|
65
66
|
|
|
66
67
|
stats=$("$sqlite_bin" "$em_db" "SELECT
|
|
67
68
|
COUNT(*) || '|' ||
|
|
68
|
-
(SELECT COUNT(*) FROM agent_memories WHERE
|
|
69
|
+
(SELECT COUNT(*) FROM agent_memories WHERE $project_condition) || '|' ||
|
|
69
70
|
COALESCE(MAX(COALESCE(last_activity_at, started_at)), 'never')
|
|
70
71
|
FROM sessions
|
|
71
|
-
WHERE
|
|
72
|
+
WHERE $project_condition;" 2>/dev/null)
|
|
72
73
|
IFS='|' read -r sessions memories last_raw <<< "${stats:-0|0|never}"
|
|
73
74
|
sessions=${sessions:-0}
|
|
74
75
|
memories=${memories:-0}
|