eagle-mem 4.1.1 → 4.2.0

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.
@@ -37,6 +37,18 @@ eagle_log "INFO" "SessionStart: session=$session_id project=$project source=$sou
37
37
  eagle_upsert_session "$session_id" "$project" "$cwd" "$model" "$source_type"
38
38
  eagle_abandon_stale_sessions "$session_id"
39
39
 
40
+ # ─── Reset turn counter on compact/clear ─────────────────
41
+
42
+ case "$source_type" in
43
+ compact|clear)
44
+ echo "0" > "$EAGLE_MEM_DIR/.turn-counter.${session_id}" 2>/dev/null
45
+ rm -f "$EAGLE_MEM_DIR/.context-pressure" 2>/dev/null
46
+ ;;
47
+ startup)
48
+ echo "0" > "$EAGLE_MEM_DIR/.turn-counter.${session_id}" 2>/dev/null
49
+ ;;
50
+ esac
51
+
40
52
  # ─── Background automation (non-blocking) ────────────────
41
53
 
42
54
  eagle_sessionstart_auto_provision "$project" "$cwd" "$SCRIPTS_DIR"
@@ -46,6 +58,7 @@ eagle_sessionstart_auto_curate "$project" "$SCRIPTS_DIR"
46
58
  find "$EAGLE_MEM_DIR/read-tracker" -type f -mtime +1 -delete 2>/dev/null &
47
59
  find "$EAGLE_MEM_DIR/mod-tracker" -type f -mtime +1 -delete 2>/dev/null &
48
60
  find "$EAGLE_MEM_DIR/edit-tracker" -type f -mtime +1 -delete 2>/dev/null &
61
+ find "$EAGLE_MEM_DIR" -name ".turn-counter.*" -mtime +1 -delete 2>/dev/null &
49
62
 
50
63
  # ─── Version check (non-blocking) ────────────────────────
51
64
 
package/hooks/stop.sh CHANGED
@@ -127,6 +127,12 @@ fi
127
127
  # ─── LLM enrichment: fill in decisions/gotchas/key_files ─────
128
128
  # Check both local vars (from eagle-summary block) AND existing DB enrichment.
129
129
  # Skip LLM call if either source already has enrichment data.
130
+ # Exception: under context pressure, force re-enrichment for richest summary.
131
+
132
+ context_pressure=0
133
+ if [ -f "$EAGLE_MEM_DIR/.context-pressure" ]; then
134
+ context_pressure=1
135
+ fi
130
136
 
131
137
  existing_enrichment=""
132
138
  if [ -z "$decisions" ] && [ -z "$gotchas" ] && [ -z "$key_files" ]; then
@@ -134,7 +140,7 @@ if [ -z "$decisions" ] && [ -z "$gotchas" ] && [ -z "$key_files" ]; then
134
140
  existing_enrichment=$(eagle_db "SELECT decisions||gotchas||key_files FROM summaries WHERE session_id='$s_esc';")
135
141
  fi
136
142
 
137
- if [ -z "$decisions" ] && [ -z "$gotchas" ] && [ -z "$key_files" ] && [ -z "$existing_enrichment" ]; then
143
+ if [ -z "$decisions" ] && [ -z "$gotchas" ] && [ -z "$key_files" ] && { [ -z "$existing_enrichment" ] || [ "$context_pressure" -eq 1 ]; }; then
138
144
  provider=$(eagle_config_get "provider" "type" "none" 2>/dev/null)
139
145
  if [ "$provider" != "none" ] && [ -n "$text_content" ]; then
140
146
  excerpt=$(echo "$text_content" | tail -c 2000)
@@ -87,6 +87,35 @@ if [ "${has_chunks:-0}" -gt 0 ]; then
87
87
  fi
88
88
  fi
89
89
 
90
+ # ─── Context pressure detection (turn counter since last compact) ──
91
+
92
+ if [ -n "$session_id" ] && eagle_validate_session_id "$session_id"; then
93
+ counter_file="$EAGLE_MEM_DIR/.turn-counter.${session_id}"
94
+ turn_count=0
95
+ [ -f "$counter_file" ] && turn_count=$(cat "$counter_file" 2>/dev/null | tr -d '[:space:]')
96
+ turn_count=${turn_count:-0}
97
+ turn_count=$((turn_count + 1))
98
+ echo "$turn_count" > "$counter_file" 2>/dev/null
99
+
100
+ if [ "$turn_count" -ge 30 ]; then
101
+ context+="
102
+ === EAGLE MEM — Context Pressure: CRITICAL ($turn_count turns since compact) ===
103
+ IMMEDIATELY emit a detailed <eagle-summary> covering ALL work this session.
104
+ Tell the user to run /compact NOW to avoid losing context.
105
+ "
106
+ echo "$turn_count" > "$EAGLE_MEM_DIR/.context-pressure"
107
+ elif [ "$turn_count" -ge 20 ]; then
108
+ context+="
109
+ === EAGLE MEM — Context Pressure: HIGH ($turn_count turns since compact) ===
110
+ Include a thorough <eagle-summary> in your next response — capture all decisions, gotchas, and learned context before compaction.
111
+ Suggest the user run /compact to free context for continued work.
112
+ "
113
+ echo "$turn_count" > "$EAGLE_MEM_DIR/.context-pressure"
114
+ else
115
+ rm -f "$EAGLE_MEM_DIR/.context-pressure" 2>/dev/null
116
+ fi
117
+ fi
118
+
90
119
  [ -z "$context" ] && exit 0
91
120
 
92
121
  context+="
package/lib/common.sh CHANGED
@@ -157,3 +157,42 @@ eagle_collect_files() {
157
157
  | sed 's|^\./||') > "$output_file"
158
158
  fi
159
159
  }
160
+
161
+ eagle_patch_claude_md() {
162
+ local claude_md="$HOME/.claude/CLAUDE.md"
163
+ local marker="## Eagle Mem — Persistent Memory"
164
+
165
+ if [ -f "$claude_md" ] && grep -qF "$marker" "$claude_md" 2>/dev/null; then
166
+ return 1
167
+ fi
168
+
169
+ mkdir -p "$HOME/.claude"
170
+
171
+ cat >> "$claude_md" << 'EAGLE_MD'
172
+
173
+ ---
174
+
175
+ ## Eagle Mem — Persistent Memory
176
+
177
+ Eagle Mem hooks are active in every project. SessionStart injects context (overview, recent sessions, memories, tasks, core files). Stop captures session summaries. PostToolUse mirrors memories/plans/tasks.
178
+
179
+ **Rule:** Before your final response in every session, emit an `<eagle-summary>` block so the Stop hook can capture a rich summary instead of just heuristics.
180
+
181
+ ```
182
+ <eagle-summary>
183
+ request: [what user asked] | completed: [what shipped] | learned: [non-obvious discoveries]
184
+ next_steps: [concrete actions] | decisions: [choice — why] | gotchas: [what surprised]
185
+ key_files: [path — role] | files_read: [...] | files_modified: [...]
186
+ </eagle-summary>
187
+ ```
188
+
189
+ **Why:** Without this block, summaries degrade to "(auto-captured)" with no decisions, gotchas, or learned context. Rich summaries are what make future sessions useful.
190
+
191
+ **How to apply:**
192
+ - Emit `<eagle-summary>` before your final text response, every session
193
+ - When Eagle Mem injects context at SessionStart, attribute it: "Eagle Mem recalls:"
194
+ - Do not revert decisions surfaced by PostToolUse without asking the user
195
+ - Never put raw secrets in the summary — Eagle Mem redacts but defense in depth
196
+ - If you contradict a loaded memory, update the memory file
197
+ EAGLE_MD
198
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eagle-mem",
3
- "version": "4.1.1",
3
+ "version": "4.2.0",
4
4
  "description": "Persistent memory for Claude Code — SQLite + FTS5, no daemon, no bloat",
5
5
  "bin": {
6
6
  "eagle-mem": "bin/eagle-mem"
@@ -271,6 +271,14 @@ else
271
271
  eagle_ok "Config ${DIM}(already exists)${RESET}"
272
272
  fi
273
273
 
274
+ # ─── Patch CLAUDE.md with Eagle Mem instructions ─────────
275
+
276
+ if eagle_patch_claude_md; then
277
+ eagle_ok "CLAUDE.md ${DIM}(eagle-summary instructions added)${RESET}"
278
+ else
279
+ eagle_ok "CLAUDE.md ${DIM}(already has Eagle Mem section)${RESET}"
280
+ fi
281
+
274
282
  # ─── Save installed version ───────────────────────────────
275
283
 
276
284
  version=$(jq -r .version "$PACKAGE_DIR/package.json" 2>/dev/null || echo "unknown")
package/scripts/update.sh CHANGED
@@ -114,6 +114,14 @@ else
114
114
  eagle_ok "Project names up to date"
115
115
  fi
116
116
 
117
+ # ─── Patch CLAUDE.md with Eagle Mem instructions ─────────
118
+
119
+ if eagle_patch_claude_md; then
120
+ eagle_ok "CLAUDE.md updated ${DIM}(eagle-summary instructions added)${RESET}"
121
+ else
122
+ eagle_ok "CLAUDE.md up to date"
123
+ fi
124
+
117
125
  # ─── Save installed version ───────────────────────────────
118
126
 
119
127
  version=$(jq -r .version "$PACKAGE_DIR/package.json" 2>/dev/null || echo "unknown")