eagle-mem 3.0.1 → 3.0.2
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/post-tool-use.sh +11 -146
- package/hooks/pre-tool-use.sh +5 -25
- package/hooks/session-end.sh +1 -1
- package/hooks/session-start.sh +23 -29
- package/hooks/stop.sh +1 -1
- package/lib/common.sh +3 -0
- package/lib/db-backfill.sh +96 -0
- package/lib/db-core.sh +65 -0
- package/lib/db-features.sh +160 -0
- package/lib/db-mirrors.sh +264 -0
- package/lib/db-observations.sh +77 -0
- package/lib/db-sessions.sh +68 -0
- package/lib/db-summaries.sh +142 -0
- package/lib/db.sh +14 -737
- package/lib/hooks-posttool.sh +138 -0
- package/package.json +1 -1
- package/scripts/memories.sh +3 -3
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ═══════════════════════════════════════════════════════════
|
|
3
|
+
# Eagle Mem — PostToolUse extracted responsibilities
|
|
4
|
+
# Source from hooks/post-tool-use.sh after common.sh + db.sh
|
|
5
|
+
# ═══════════════════════════════════════════════════════════
|
|
6
|
+
[ -n "${_EAGLE_HOOKS_POSTTOOL_LOADED:-}" ] && return 0
|
|
7
|
+
_EAGLE_HOOKS_POSTTOOL_LOADED=1
|
|
8
|
+
|
|
9
|
+
eagle_posttool_mirror_writes() {
|
|
10
|
+
local tool_name="$1" fp="$2" session_id="$3" project="$4"
|
|
11
|
+
|
|
12
|
+
case "$tool_name" in
|
|
13
|
+
Write|Edit)
|
|
14
|
+
if [ -n "$fp" ]; then
|
|
15
|
+
case "$fp" in
|
|
16
|
+
*..*) ;; # path traversal — skip
|
|
17
|
+
"$EAGLE_CLAUDE_PROJECTS_DIR"/*/memory/*.md)
|
|
18
|
+
local mem_base
|
|
19
|
+
mem_base=$(basename "$fp")
|
|
20
|
+
if [ "$mem_base" != "MEMORY.md" ] && [ -f "$fp" ]; then
|
|
21
|
+
eagle_capture_claude_memory "$fp" "$session_id" "$project"
|
|
22
|
+
fi
|
|
23
|
+
;;
|
|
24
|
+
"$EAGLE_CLAUDE_PLANS_DIR/"*.md)
|
|
25
|
+
if [ -f "$fp" ]; then
|
|
26
|
+
eagle_capture_claude_plan "$fp" "$session_id" "$project"
|
|
27
|
+
fi
|
|
28
|
+
;;
|
|
29
|
+
esac
|
|
30
|
+
fi
|
|
31
|
+
;;
|
|
32
|
+
esac
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
eagle_posttool_mirror_tasks() {
|
|
36
|
+
local tool_name="$1" session_id="$2" project="$3" input="$4"
|
|
37
|
+
|
|
38
|
+
case "$tool_name" in
|
|
39
|
+
TaskCreate|TaskUpdate)
|
|
40
|
+
if eagle_validate_session_id "$session_id"; then
|
|
41
|
+
local task_dir="$EAGLE_CLAUDE_TASKS_DIR/$session_id"
|
|
42
|
+
if [ -d "$task_dir" ]; then
|
|
43
|
+
local task_id
|
|
44
|
+
task_id=$(echo "$input" | jq -r '.tool_input.id // empty')
|
|
45
|
+
if [ -z "$task_id" ]; then
|
|
46
|
+
local newest
|
|
47
|
+
newest=$(ls -t "$task_dir"/*.json 2>/dev/null | head -1)
|
|
48
|
+
[ -n "$newest" ] && [ -f "$newest" ] && eagle_capture_claude_task "$newest" "$session_id" "$project"
|
|
49
|
+
elif eagle_validate_session_id "$task_id"; then
|
|
50
|
+
local task_json="$task_dir/$task_id.json"
|
|
51
|
+
[ -f "$task_json" ] && eagle_capture_claude_task "$task_json" "$session_id" "$project"
|
|
52
|
+
fi
|
|
53
|
+
fi
|
|
54
|
+
fi
|
|
55
|
+
;;
|
|
56
|
+
esac
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
eagle_posttool_stale_hint() {
|
|
60
|
+
local tool_name="$1" fp="$2" project="$3"
|
|
61
|
+
|
|
62
|
+
case "$tool_name" in
|
|
63
|
+
Write|Edit)
|
|
64
|
+
if [ -n "$fp" ]; then
|
|
65
|
+
local fname fname_stem
|
|
66
|
+
fname=$(basename "$fp")
|
|
67
|
+
fname_stem="${fname%.*}"
|
|
68
|
+
case "$fp" in
|
|
69
|
+
"$HOME/.claude/"*) ;; # skip Claude config files
|
|
70
|
+
*)
|
|
71
|
+
if [ ${#fname_stem} -ge 3 ]; then
|
|
72
|
+
local fts_query
|
|
73
|
+
fts_query=$(eagle_fts_sanitize "$fname_stem")
|
|
74
|
+
if [ -n "$fts_query" ]; then
|
|
75
|
+
local stale_hit
|
|
76
|
+
stale_hit=$(eagle_search_stale_memories "$project" "$fts_query")
|
|
77
|
+
if [ -n "$stale_hit" ]; then
|
|
78
|
+
local stale_msg="Eagle Mem: Memory '${stale_hit}' may reference '${fname}'. If your edit contradicts it, update the memory."
|
|
79
|
+
jq -nc --arg ctx "$stale_msg" '{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":$ctx}}'
|
|
80
|
+
fi
|
|
81
|
+
fi
|
|
82
|
+
fi
|
|
83
|
+
;;
|
|
84
|
+
esac
|
|
85
|
+
fi
|
|
86
|
+
;;
|
|
87
|
+
esac
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
eagle_posttool_decision_surface() {
|
|
91
|
+
local tool_name="$1" fp="$2" project="$3"
|
|
92
|
+
|
|
93
|
+
case "$tool_name" in
|
|
94
|
+
Read)
|
|
95
|
+
if [ -n "$fp" ]; then
|
|
96
|
+
local fname fname_stem read_context=""
|
|
97
|
+
fname=$(basename "$fp")
|
|
98
|
+
fname_stem="${fname%.*}"
|
|
99
|
+
case "$fp" in
|
|
100
|
+
"$HOME/.claude/"*) ;; # skip Claude config files
|
|
101
|
+
*)
|
|
102
|
+
if [ ${#fname_stem} -ge 3 ]; then
|
|
103
|
+
local fts_query
|
|
104
|
+
fts_query=$(eagle_fts_sanitize "$fname_stem")
|
|
105
|
+
if [ -n "$fts_query" ]; then
|
|
106
|
+
local decision_hit
|
|
107
|
+
decision_hit=$(eagle_search_decisions_for_file "$project" "$fts_query")
|
|
108
|
+
if [ -n "$decision_hit" ]; then
|
|
109
|
+
read_context+="Eagle Mem decision history for '${fname}': ${decision_hit} — Do not revert without explicit user request. "
|
|
110
|
+
fi
|
|
111
|
+
fi
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
local feature_hit
|
|
115
|
+
feature_hit=$(eagle_find_features_for_file "$project" "$fp")
|
|
116
|
+
if [ -n "$feature_hit" ]; then
|
|
117
|
+
while IFS='|' read -r feat_name feat_desc feat_verified _role feat_deps feat_other_files feat_smoke; do
|
|
118
|
+
[ -z "$feat_name" ] && continue
|
|
119
|
+
read_context+="Eagle Mem: '${fname}' is part of feature '${feat_name}'"
|
|
120
|
+
[ -n "$feat_desc" ] && read_context+=" ($feat_desc)"
|
|
121
|
+
read_context+="."
|
|
122
|
+
[ -n "$feat_verified" ] && read_context+=" Last verified: ${feat_verified}."
|
|
123
|
+
[ -n "$feat_deps" ] && read_context+=" Dependencies: ${feat_deps}."
|
|
124
|
+
[ -n "$feat_other_files" ] && read_context+=" Other files in pipeline: ${feat_other_files}."
|
|
125
|
+
[ -n "$feat_smoke" ] && read_context+=" Smoke tests: ${feat_smoke}."
|
|
126
|
+
read_context+=" Changes require re-testing after deploy. "
|
|
127
|
+
done <<< "$feature_hit"
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
if [ -n "$read_context" ]; then
|
|
131
|
+
jq -nc --arg ctx "$read_context" '{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":$ctx}}'
|
|
132
|
+
fi
|
|
133
|
+
;;
|
|
134
|
+
esac
|
|
135
|
+
fi
|
|
136
|
+
;;
|
|
137
|
+
esac
|
|
138
|
+
}
|
package/package.json
CHANGED
package/scripts/memories.sh
CHANGED
|
@@ -438,7 +438,7 @@ memories_sync() {
|
|
|
438
438
|
eagle_info "Scanning for Claude Code auto-memory files..."
|
|
439
439
|
echo ""
|
|
440
440
|
|
|
441
|
-
local claude_mem_root="$
|
|
441
|
+
local claude_mem_root="$EAGLE_CLAUDE_PROJECTS_DIR"
|
|
442
442
|
local mem_synced=0
|
|
443
443
|
local mem_skipped=0
|
|
444
444
|
|
|
@@ -471,7 +471,7 @@ memories_sync() {
|
|
|
471
471
|
eagle_info "Scanning for Claude Code plan files..."
|
|
472
472
|
echo ""
|
|
473
473
|
|
|
474
|
-
local plans_dir="$
|
|
474
|
+
local plans_dir="$EAGLE_CLAUDE_PLANS_DIR"
|
|
475
475
|
local plan_synced=0
|
|
476
476
|
local plan_skipped=0
|
|
477
477
|
|
|
@@ -504,7 +504,7 @@ memories_sync() {
|
|
|
504
504
|
eagle_info "Scanning for Claude Code task files..."
|
|
505
505
|
echo ""
|
|
506
506
|
|
|
507
|
-
local tasks_dir="$
|
|
507
|
+
local tasks_dir="$EAGLE_CLAUDE_TASKS_DIR"
|
|
508
508
|
local task_synced=0
|
|
509
509
|
local task_skipped=0
|
|
510
510
|
|