eagle-mem 4.0.1 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -2
- package/package.json +1 -1
- package/scripts/curate.sh +13 -7
- package/scripts/help.sh +8 -4
- package/scripts/search.sh +214 -0
package/README.md
CHANGED
|
@@ -36,17 +36,30 @@ Everything is automatic from here. Eagle Mem scans your codebase, indexes source
|
|
|
36
36
|
|
|
37
37
|
## Commands
|
|
38
38
|
|
|
39
|
-
Six commands. Three for lifecycle, three for
|
|
39
|
+
Six commands. Three for lifecycle, three for lookup and troubleshooting.
|
|
40
40
|
|
|
41
41
|
| Command | What it does |
|
|
42
42
|
|---------|-------------|
|
|
43
43
|
| `eagle-mem install` | First-time setup: hooks, database, skills |
|
|
44
44
|
| `eagle-mem update` | Re-deploy hooks and run migrations after `npm update` |
|
|
45
45
|
| `eagle-mem uninstall` | Remove hooks and optionally delete data |
|
|
46
|
-
| `eagle-mem search
|
|
46
|
+
| `eagle-mem search` | Single lookup command — see modes below |
|
|
47
47
|
| `eagle-mem health` | Diagnose pipeline health and background automation |
|
|
48
48
|
| `eagle-mem config` | View or change LLM provider settings |
|
|
49
49
|
|
|
50
|
+
### Search modes
|
|
51
|
+
|
|
52
|
+
| Mode | What it does |
|
|
53
|
+
|------|-------------|
|
|
54
|
+
| `eagle-mem search "query"` | FTS5 keyword search across session summaries |
|
|
55
|
+
| `eagle-mem search --timeline` | Recent sessions in chronological order |
|
|
56
|
+
| `eagle-mem search --overview` | View project overview |
|
|
57
|
+
| `eagle-mem search --memories` | Mirrored Claude Code memories |
|
|
58
|
+
| `eagle-mem search --tasks` | In-flight tasks (pending/in-progress) |
|
|
59
|
+
| `eagle-mem search --files` | Most frequently modified files |
|
|
60
|
+
| `eagle-mem search --stats` | Project statistics (counts) |
|
|
61
|
+
| `eagle-mem search --session <id>` | Full observation trail for one session |
|
|
62
|
+
|
|
50
63
|
## Skills (inside Claude Code)
|
|
51
64
|
|
|
52
65
|
| Skill | What it does |
|
package/package.json
CHANGED
package/scripts/curate.sh
CHANGED
|
@@ -168,24 +168,30 @@ command_stats=$(eagle_db "SELECT command_category,
|
|
|
168
168
|
LIMIT 10;")
|
|
169
169
|
|
|
170
170
|
if [ -n "$command_stats" ]; then
|
|
171
|
-
# Get
|
|
172
|
-
|
|
171
|
+
# Get noisy commands grouped by base command (first 2 words) to catch variants
|
|
172
|
+
# e.g. "git diff", "git diff HEAD~1", "git -C /path diff" all group under "git diff"
|
|
173
|
+
noisy_commands=$(eagle_db "SELECT
|
|
174
|
+
CASE
|
|
175
|
+
WHEN tool_input_summary LIKE 'Bash: cd %' THEN 'cd ... && ' || SUBSTR(tool_input_summary, INSTR(tool_input_summary, '&& ') + 3, 40)
|
|
176
|
+
ELSE SUBSTR(tool_input_summary, 7, 40)
|
|
177
|
+
END as base_cmd,
|
|
173
178
|
COUNT(*) as count,
|
|
174
179
|
CAST(AVG(output_bytes) AS INTEGER) as avg_bytes,
|
|
180
|
+
CAST(MAX(output_bytes) AS INTEGER) as max_bytes,
|
|
175
181
|
CAST(AVG(output_lines) AS INTEGER) as avg_lines
|
|
176
182
|
FROM observations
|
|
177
183
|
WHERE project = '$p_esc'
|
|
178
184
|
AND tool_name = 'Bash'
|
|
179
|
-
AND output_bytes >
|
|
180
|
-
GROUP BY
|
|
181
|
-
HAVING count >=
|
|
185
|
+
AND output_bytes > 2000
|
|
186
|
+
GROUP BY base_cmd
|
|
187
|
+
HAVING count >= 2
|
|
182
188
|
ORDER BY avg_bytes DESC
|
|
183
189
|
LIMIT 15;")
|
|
184
190
|
|
|
185
191
|
if [ -n "$noisy_commands" ]; then
|
|
186
|
-
cmd_prompt="Analyze these frequently-run
|
|
192
|
+
cmd_prompt="Analyze these frequently-run command patterns and their output sizes for project '$project'. Suggest compression rules for commands that produce consistently large output (>2KB average).
|
|
187
193
|
|
|
188
|
-
COMMAND
|
|
194
|
+
COMMAND PATTERNS (base_command | times_run | avg_bytes | max_bytes | avg_lines):
|
|
189
195
|
$noisy_commands
|
|
190
196
|
|
|
191
197
|
For each command that deserves a compression rule, output EXACTLY:
|
package/scripts/help.sh
CHANGED
|
@@ -23,10 +23,14 @@ echo -e " ${CYAN}search${RESET} Search past sessions, memories, and code
|
|
|
23
23
|
echo -e " ${CYAN}health${RESET} Diagnose pipeline health and background automation"
|
|
24
24
|
echo -e " ${CYAN}config${RESET} View or change LLM provider settings"
|
|
25
25
|
echo ""
|
|
26
|
-
echo -e " ${BOLD}
|
|
27
|
-
echo -e " ${DIM}\$${RESET} eagle-mem
|
|
28
|
-
echo -e " ${DIM}\$${RESET} eagle-mem search
|
|
29
|
-
echo -e " ${DIM}\$${RESET} eagle-mem
|
|
26
|
+
echo -e " ${BOLD}Search modes:${RESET}"
|
|
27
|
+
echo -e " ${DIM}\$${RESET} eagle-mem search \"auth bug\" ${DIM}# keyword search${RESET}"
|
|
28
|
+
echo -e " ${DIM}\$${RESET} eagle-mem search --timeline ${DIM}# recent sessions${RESET}"
|
|
29
|
+
echo -e " ${DIM}\$${RESET} eagle-mem search --overview ${DIM}# project overview${RESET}"
|
|
30
|
+
echo -e " ${DIM}\$${RESET} eagle-mem search --memories ${DIM}# mirrored memories${RESET}"
|
|
31
|
+
echo -e " ${DIM}\$${RESET} eagle-mem search --tasks ${DIM}# in-flight tasks${RESET}"
|
|
32
|
+
echo -e " ${DIM}\$${RESET} eagle-mem search --files ${DIM}# hot files${RESET}"
|
|
33
|
+
echo -e " ${DIM}\$${RESET} eagle-mem search --stats ${DIM}# project stats${RESET}"
|
|
30
34
|
echo ""
|
|
31
35
|
echo -e " ${BOLD}Skills${RESET} ${DIM}(inside Claude Code sessions):${RESET}"
|
|
32
36
|
echo -e " ${CYAN}/eagle-mem-search${RESET} Search memory and past sessions"
|
package/scripts/search.sh
CHANGED
|
@@ -25,6 +25,9 @@ show_help() {
|
|
|
25
25
|
echo -e " eagle-mem search ${CYAN}--session <id>${RESET} ${DIM}# session details${RESET}"
|
|
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
|
+
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}"
|
|
30
|
+
echo -e " eagle-mem search ${CYAN}--tasks${RESET} ${DIM}# in-flight tasks${RESET}"
|
|
28
31
|
echo ""
|
|
29
32
|
echo -e " ${BOLD}Options:${RESET}"
|
|
30
33
|
echo -e " ${CYAN}-p, --project${RESET} <name> Project name (default: current dir)"
|
|
@@ -51,6 +54,9 @@ while [ $# -gt 0 ]; do
|
|
|
51
54
|
--session|-s) mode="session"; session_id="$2"; shift 2 ;;
|
|
52
55
|
--files|-f) mode="files"; shift ;;
|
|
53
56
|
--stats) mode="stats"; shift ;;
|
|
57
|
+
--overview|-o) mode="overview"; shift ;;
|
|
58
|
+
--memories|-m) mode="memories"; shift ;;
|
|
59
|
+
--tasks) mode="tasks"; shift ;;
|
|
54
60
|
--project|-p) project="$2"; shift 2 ;;
|
|
55
61
|
--limit|-n) limit="$2"; shift 2 ;;
|
|
56
62
|
--all|-a) cross_project=true; shift ;;
|
|
@@ -280,6 +286,211 @@ search_stats() {
|
|
|
280
286
|
echo ""
|
|
281
287
|
}
|
|
282
288
|
|
|
289
|
+
# ─── Overview ────────────────────────────────────────────
|
|
290
|
+
|
|
291
|
+
search_overview() {
|
|
292
|
+
local p; p=$(eagle_sql_escape "$project")
|
|
293
|
+
|
|
294
|
+
if [ "$json_output" = true ]; then
|
|
295
|
+
eagle_db_json "SELECT project, content, source, updated_at FROM overviews WHERE project = '$p';"
|
|
296
|
+
return
|
|
297
|
+
fi
|
|
298
|
+
|
|
299
|
+
local content
|
|
300
|
+
content=$(eagle_db "SELECT content FROM overviews WHERE project = '$p';")
|
|
301
|
+
|
|
302
|
+
if [ -z "$content" ]; then
|
|
303
|
+
eagle_dim "No overview for project '$project'"
|
|
304
|
+
eagle_dim " Auto-scan runs on first session, or use /eagle-mem-overview for a rich briefing"
|
|
305
|
+
return
|
|
306
|
+
fi
|
|
307
|
+
|
|
308
|
+
echo ""
|
|
309
|
+
echo -e " ${BOLD}Overview${RESET} ${DIM}($project)${RESET}"
|
|
310
|
+
echo -e " ${DIM}─────────────────────────────────────${RESET}"
|
|
311
|
+
echo ""
|
|
312
|
+
echo " $content"
|
|
313
|
+
echo ""
|
|
314
|
+
|
|
315
|
+
if [ -n "$query" ]; then
|
|
316
|
+
echo -e " ${DIM}To update: eagle-mem search --overview set \"new overview text\"${RESET}"
|
|
317
|
+
fi
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
# ─── Memories ────────────────────────────────────────────
|
|
321
|
+
|
|
322
|
+
search_memories() {
|
|
323
|
+
local p; p=$(eagle_sql_escape "$project")
|
|
324
|
+
|
|
325
|
+
local where_project=""
|
|
326
|
+
if [ "$cross_project" = false ]; then
|
|
327
|
+
where_project="WHERE project = '$p'"
|
|
328
|
+
fi
|
|
329
|
+
|
|
330
|
+
if [ -n "$query" ]; then
|
|
331
|
+
local q; q=$(eagle_sql_escape "$(eagle_fts_sanitize "$query")")
|
|
332
|
+
local where_match="WHERE claude_memories_fts MATCH '$q'"
|
|
333
|
+
if [ "$cross_project" = false ]; then
|
|
334
|
+
where_match="$where_match AND m.project = '$p'"
|
|
335
|
+
fi
|
|
336
|
+
|
|
337
|
+
if [ "$json_output" = true ]; then
|
|
338
|
+
eagle_db_json "SELECT m.memory_name, m.memory_type, m.description, m.project, m.updated_at
|
|
339
|
+
FROM claude_memories m
|
|
340
|
+
JOIN claude_memories_fts f ON f.rowid = m.id
|
|
341
|
+
$where_match
|
|
342
|
+
ORDER BY rank
|
|
343
|
+
LIMIT $limit;"
|
|
344
|
+
return
|
|
345
|
+
fi
|
|
346
|
+
|
|
347
|
+
local results
|
|
348
|
+
results=$(eagle_db "SELECT m.memory_name, m.memory_type, m.description, m.project, m.updated_at
|
|
349
|
+
FROM claude_memories m
|
|
350
|
+
JOIN claude_memories_fts f ON f.rowid = m.id
|
|
351
|
+
$where_match
|
|
352
|
+
ORDER BY rank
|
|
353
|
+
LIMIT $limit;")
|
|
354
|
+
|
|
355
|
+
if [ -z "$results" ]; then
|
|
356
|
+
eagle_dim "No memories matching '$query'"
|
|
357
|
+
return
|
|
358
|
+
fi
|
|
359
|
+
|
|
360
|
+
echo ""
|
|
361
|
+
while IFS='|' read -r mname mtype mdesc mproj mupdated; do
|
|
362
|
+
[ -z "$mname" ] && continue
|
|
363
|
+
echo -e " ${BOLD}$mname${RESET} ${DIM}[$mtype]${RESET}"
|
|
364
|
+
[ "$cross_project" = true ] && echo -e " ${DIM}project:${RESET} $mproj"
|
|
365
|
+
[ -n "$mdesc" ] && echo -e " $mdesc"
|
|
366
|
+
echo ""
|
|
367
|
+
done <<< "$results"
|
|
368
|
+
return
|
|
369
|
+
fi
|
|
370
|
+
|
|
371
|
+
if [ "$json_output" = true ]; then
|
|
372
|
+
eagle_db_json "SELECT memory_name, memory_type, description, project, updated_at
|
|
373
|
+
FROM claude_memories $where_project
|
|
374
|
+
ORDER BY updated_at DESC LIMIT $limit;"
|
|
375
|
+
return
|
|
376
|
+
fi
|
|
377
|
+
|
|
378
|
+
local results
|
|
379
|
+
results=$(eagle_db "SELECT memory_name, memory_type, description, updated_at
|
|
380
|
+
FROM claude_memories $where_project
|
|
381
|
+
ORDER BY updated_at DESC LIMIT $limit;")
|
|
382
|
+
|
|
383
|
+
if [ -z "$results" ]; then
|
|
384
|
+
eagle_dim "No memories found"
|
|
385
|
+
return
|
|
386
|
+
fi
|
|
387
|
+
|
|
388
|
+
echo ""
|
|
389
|
+
echo -e " ${BOLD}Memories${RESET} ${DIM}($project)${RESET}"
|
|
390
|
+
echo -e " ${DIM}─────────────────────────────────────${RESET}"
|
|
391
|
+
echo ""
|
|
392
|
+
|
|
393
|
+
while IFS='|' read -r mname mtype mdesc mupdated; do
|
|
394
|
+
[ -z "$mname" ] && continue
|
|
395
|
+
echo -e " ${CYAN}[$mtype]${RESET} ${BOLD}$mname${RESET}"
|
|
396
|
+
[ -n "$mdesc" ] && echo -e " ${DIM}$mdesc${RESET}"
|
|
397
|
+
done <<< "$results"
|
|
398
|
+
echo ""
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
# ─── Tasks ───────────────────────────────────────────────
|
|
402
|
+
|
|
403
|
+
search_tasks() {
|
|
404
|
+
local p; p=$(eagle_sql_escape "$project")
|
|
405
|
+
|
|
406
|
+
local where_project=""
|
|
407
|
+
if [ "$cross_project" = false ]; then
|
|
408
|
+
where_project="AND project = '$p'"
|
|
409
|
+
fi
|
|
410
|
+
|
|
411
|
+
if [ -n "$query" ]; then
|
|
412
|
+
local q; q=$(eagle_sql_escape "$(eagle_fts_sanitize "$query")")
|
|
413
|
+
|
|
414
|
+
if [ "$json_output" = true ]; then
|
|
415
|
+
eagle_db_json "SELECT t.subject, t.status, t.project, t.updated_at
|
|
416
|
+
FROM claude_tasks t
|
|
417
|
+
JOIN claude_tasks_fts f ON f.rowid = t.id
|
|
418
|
+
WHERE claude_tasks_fts MATCH '$q'
|
|
419
|
+
${where_project/AND/AND t.}
|
|
420
|
+
ORDER BY rank
|
|
421
|
+
LIMIT $limit;"
|
|
422
|
+
return
|
|
423
|
+
fi
|
|
424
|
+
|
|
425
|
+
local results
|
|
426
|
+
results=$(eagle_db "SELECT t.subject, t.status, t.project, t.updated_at
|
|
427
|
+
FROM claude_tasks t
|
|
428
|
+
JOIN claude_tasks_fts f ON f.rowid = t.id
|
|
429
|
+
WHERE claude_tasks_fts MATCH '$q'
|
|
430
|
+
${where_project/AND/AND t.}
|
|
431
|
+
ORDER BY rank
|
|
432
|
+
LIMIT $limit;")
|
|
433
|
+
|
|
434
|
+
if [ -z "$results" ]; then
|
|
435
|
+
eagle_dim "No tasks matching '$query'"
|
|
436
|
+
return
|
|
437
|
+
fi
|
|
438
|
+
|
|
439
|
+
echo ""
|
|
440
|
+
while IFS='|' read -r tsubject tstatus tproj tupdated; do
|
|
441
|
+
[ -z "$tsubject" ] && continue
|
|
442
|
+
local color="$DIM"
|
|
443
|
+
case "$tstatus" in
|
|
444
|
+
in_progress) color="$YELLOW" ;;
|
|
445
|
+
completed) color="$GREEN" ;;
|
|
446
|
+
pending) color="$CYAN" ;;
|
|
447
|
+
esac
|
|
448
|
+
echo -e " ${color}[$tstatus]${RESET} $tsubject"
|
|
449
|
+
done <<< "$results"
|
|
450
|
+
echo ""
|
|
451
|
+
return
|
|
452
|
+
fi
|
|
453
|
+
|
|
454
|
+
if [ "$json_output" = true ]; then
|
|
455
|
+
eagle_db_json "SELECT subject, status, project, updated_at
|
|
456
|
+
FROM claude_tasks
|
|
457
|
+
WHERE status IN ('in_progress', 'pending')
|
|
458
|
+
$where_project
|
|
459
|
+
ORDER BY CASE status WHEN 'in_progress' THEN 0 ELSE 1 END, updated_at DESC
|
|
460
|
+
LIMIT $limit;"
|
|
461
|
+
return
|
|
462
|
+
fi
|
|
463
|
+
|
|
464
|
+
local results
|
|
465
|
+
results=$(eagle_db "SELECT subject, status, updated_at
|
|
466
|
+
FROM claude_tasks
|
|
467
|
+
WHERE status IN ('in_progress', 'pending')
|
|
468
|
+
$where_project
|
|
469
|
+
ORDER BY CASE status WHEN 'in_progress' THEN 0 ELSE 1 END, updated_at DESC
|
|
470
|
+
LIMIT $limit;")
|
|
471
|
+
|
|
472
|
+
if [ -z "$results" ]; then
|
|
473
|
+
eagle_dim "No active tasks for project '$project'"
|
|
474
|
+
return
|
|
475
|
+
fi
|
|
476
|
+
|
|
477
|
+
echo ""
|
|
478
|
+
echo -e " ${BOLD}Tasks${RESET} ${DIM}($project)${RESET}"
|
|
479
|
+
echo -e " ${DIM}─────────────────────────────────────${RESET}"
|
|
480
|
+
echo ""
|
|
481
|
+
|
|
482
|
+
while IFS='|' read -r tsubject tstatus tupdated; do
|
|
483
|
+
[ -z "$tsubject" ] && continue
|
|
484
|
+
local color="$DIM"
|
|
485
|
+
case "$tstatus" in
|
|
486
|
+
in_progress) color="$YELLOW" ;;
|
|
487
|
+
pending) color="$CYAN" ;;
|
|
488
|
+
esac
|
|
489
|
+
echo -e " ${color}[$tstatus]${RESET} $tsubject"
|
|
490
|
+
done <<< "$results"
|
|
491
|
+
echo ""
|
|
492
|
+
}
|
|
493
|
+
|
|
283
494
|
# ─── Dispatch ─────────────────────────────────────────────
|
|
284
495
|
|
|
285
496
|
case "$mode" in
|
|
@@ -295,4 +506,7 @@ case "$mode" in
|
|
|
295
506
|
session) search_session ;;
|
|
296
507
|
files) search_files ;;
|
|
297
508
|
stats) search_stats ;;
|
|
509
|
+
overview) search_overview ;;
|
|
510
|
+
memories) search_memories ;;
|
|
511
|
+
tasks) search_tasks ;;
|
|
298
512
|
esac
|