eagle-mem 4.6.2 → 4.7.1

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.
Files changed (40) hide show
  1. package/README.md +49 -15
  2. package/db/023_guardrails.sql +3 -2
  3. package/db/024_guardrails_unique.sql +46 -0
  4. package/db/025_pending_feature_verifications.sql +30 -0
  5. package/db/026_agent_source.sql +18 -0
  6. package/db/027_feature_verification_fingerprints.sql +9 -0
  7. package/db/028_agent_artifact_tables.sql +124 -0
  8. package/hooks/post-tool-use.sh +42 -13
  9. package/hooks/pre-tool-use.sh +107 -14
  10. package/hooks/session-end.sh +3 -1
  11. package/hooks/session-start.sh +64 -15
  12. package/hooks/stop.sh +115 -21
  13. package/hooks/user-prompt-submit.sh +14 -5
  14. package/lib/codex-hooks.sh +194 -0
  15. package/lib/common.sh +345 -0
  16. package/lib/db-backfill.sh +3 -3
  17. package/lib/db-features.sh +222 -0
  18. package/lib/db-guardrails.sh +2 -1
  19. package/lib/db-mirrors.sh +79 -43
  20. package/lib/db-observations.sh +3 -2
  21. package/lib/db-sessions.sh +11 -7
  22. package/lib/db-summaries.sh +9 -6
  23. package/lib/hooks-posttool.sh +8 -6
  24. package/lib/provider.sh +190 -4
  25. package/package.json +7 -3
  26. package/scripts/config.sh +2 -0
  27. package/scripts/feature.sh +70 -2
  28. package/scripts/guard.sh +4 -1
  29. package/scripts/health.sh +5 -1
  30. package/scripts/help.sh +13 -8
  31. package/scripts/install.sh +130 -76
  32. package/scripts/memories.sh +71 -45
  33. package/scripts/refresh.sh +3 -3
  34. package/scripts/search.sh +57 -47
  35. package/scripts/statusline-em.sh +1 -1
  36. package/scripts/tasks.sh +186 -15
  37. package/scripts/uninstall.sh +7 -0
  38. package/scripts/update.sh +51 -7
  39. package/skills/eagle-mem-memories/SKILL.md +13 -13
  40. package/skills/eagle-mem-tasks/SKILL.md +21 -15
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
  # ═══════════════════════════════════════════════════════════
3
3
  # Eagle Mem — Install
4
- # Sets up hooks, database, and skills for Claude Code
4
+ # Sets up hooks, database, and skills for Claude Code and Codex
5
5
  # ═══════════════════════════════════════════════════════════
6
6
  set -euo pipefail
7
7
 
@@ -12,6 +12,7 @@ LIB_DIR="$SCRIPTS_DIR/../lib"
12
12
  . "$SCRIPTS_DIR/style.sh"
13
13
  . "$LIB_DIR/common.sh"
14
14
  . "$LIB_DIR/hooks.sh"
15
+ . "$LIB_DIR/codex-hooks.sh"
15
16
 
16
17
  SETTINGS="$EAGLE_SETTINGS"
17
18
 
@@ -110,15 +111,33 @@ else
110
111
  fi
111
112
  fi
112
113
 
113
- # Claude Code
114
+ # Claude Code / Codex
115
+ claude_found=false
116
+ codex_found=false
117
+
114
118
  if [ -d "$HOME/.claude" ]; then
115
119
  eagle_ok "Claude Code ${DIM}(~/.claude/)${RESET}"
116
120
  else
117
- eagle_fail "Claude Code not found (~/.claude/ does not exist)"
121
+ eagle_warn "Claude Code not found ${DIM}(~/.claude/ does not exist)${RESET}"
122
+ fi
123
+
124
+ if [ -d "$HOME/.claude" ]; then
125
+ claude_found=true
126
+ fi
127
+
128
+ if [ -d "$EAGLE_CODEX_DIR" ] || command -v codex &>/dev/null; then
129
+ codex_found=true
130
+ eagle_ok "Codex ${DIM}($EAGLE_CODEX_DIR/)${RESET}"
131
+ else
132
+ eagle_warn "Codex not found ${DIM}(~/.codex/ missing and codex not on PATH)${RESET}"
133
+ fi
134
+
135
+ if [ "$claude_found" = false ] && [ "$codex_found" = false ]; then
136
+ eagle_fail "No supported agent install found"
118
137
  echo ""
119
- eagle_dim "Install Claude Code first:"
138
+ eagle_dim "Install Claude Code or Codex first, then re-run:"
120
139
  eagle_dim " npm install -g @anthropic-ai/claude-code"
121
- eagle_dim " https://docs.anthropic.com/en/docs/claude-code"
140
+ eagle_dim " npm install -g @openai/codex"
122
141
  echo ""
123
142
  exit 1
124
143
  fi
@@ -160,57 +179,67 @@ eagle_ok "Database ready"
160
179
 
161
180
  # ─── Patch settings.json ───────────────────────────────────
162
181
 
163
- if [ ! -f "$SETTINGS" ]; then
164
- echo '{}' > "$SETTINGS"
165
- fi
182
+ if [ "$claude_found" = true ]; then
183
+ if [ ! -f "$SETTINGS" ]; then
184
+ echo '{}' > "$SETTINGS"
185
+ fi
166
186
 
167
- eagle_patch_hook "$SETTINGS" "SessionStart" "" \
168
- "$EAGLE_MEM_DIR/hooks/session-start.sh" \
169
- "SessionStart hook"
187
+ eagle_patch_hook "$SETTINGS" "SessionStart" "" \
188
+ "$EAGLE_MEM_DIR/hooks/session-start.sh" \
189
+ "SessionStart hook"
170
190
 
171
- eagle_patch_hook "$SETTINGS" "Stop" "" \
172
- "$EAGLE_MEM_DIR/hooks/stop.sh" \
173
- "Stop hook"
191
+ eagle_patch_hook "$SETTINGS" "Stop" "" \
192
+ "$EAGLE_MEM_DIR/hooks/stop.sh" \
193
+ "Stop hook"
174
194
 
175
- eagle_patch_hook "$SETTINGS" "PostToolUse" "Read|Write|Edit|Bash|TaskCreate|TaskUpdate" \
176
- "$EAGLE_MEM_DIR/hooks/post-tool-use.sh" \
177
- "PostToolUse hook"
195
+ eagle_patch_hook "$SETTINGS" "PostToolUse" "Read|Write|Edit|Bash|TaskCreate|TaskUpdate" \
196
+ "$EAGLE_MEM_DIR/hooks/post-tool-use.sh" \
197
+ "PostToolUse hook"
178
198
 
179
- eagle_patch_hook "$SETTINGS" "TaskCreated" "" \
180
- "$EAGLE_MEM_DIR/hooks/post-tool-use.sh" \
181
- "TaskCreated hook"
199
+ eagle_patch_hook "$SETTINGS" "TaskCreated" "" \
200
+ "$EAGLE_MEM_DIR/hooks/post-tool-use.sh" \
201
+ "TaskCreated hook"
182
202
 
183
- eagle_patch_hook "$SETTINGS" "TaskCompleted" "" \
184
- "$EAGLE_MEM_DIR/hooks/post-tool-use.sh" \
185
- "TaskCompleted hook"
203
+ eagle_patch_hook "$SETTINGS" "TaskCompleted" "" \
204
+ "$EAGLE_MEM_DIR/hooks/post-tool-use.sh" \
205
+ "TaskCompleted hook"
186
206
 
187
- eagle_patch_hook "$SETTINGS" "SessionEnd" "" \
188
- "$EAGLE_MEM_DIR/hooks/session-end.sh" \
189
- "SessionEnd hook"
207
+ eagle_patch_hook "$SETTINGS" "SessionEnd" "" \
208
+ "$EAGLE_MEM_DIR/hooks/session-end.sh" \
209
+ "SessionEnd hook"
190
210
 
191
- eagle_patch_hook "$SETTINGS" "UserPromptSubmit" "" \
192
- "$EAGLE_MEM_DIR/hooks/user-prompt-submit.sh" \
193
- "UserPromptSubmit hook"
211
+ eagle_patch_hook "$SETTINGS" "UserPromptSubmit" "" \
212
+ "$EAGLE_MEM_DIR/hooks/user-prompt-submit.sh" \
213
+ "UserPromptSubmit hook"
194
214
 
195
- eagle_patch_hook "$SETTINGS" "PreToolUse" "Bash" \
196
- "$EAGLE_MEM_DIR/hooks/pre-tool-use.sh" \
197
- "PreToolUse hook (Bash)"
215
+ eagle_patch_hook "$SETTINGS" "PreToolUse" "Bash" \
216
+ "$EAGLE_MEM_DIR/hooks/pre-tool-use.sh" \
217
+ "PreToolUse hook (Bash)"
198
218
 
199
- eagle_patch_hook "$SETTINGS" "PreToolUse" "Read" \
200
- "$EAGLE_MEM_DIR/hooks/pre-tool-use.sh" \
201
- "PreToolUse hook (Read)"
219
+ eagle_patch_hook "$SETTINGS" "PreToolUse" "Read" \
220
+ "$EAGLE_MEM_DIR/hooks/pre-tool-use.sh" \
221
+ "PreToolUse hook (Read)"
202
222
 
203
- eagle_patch_hook "$SETTINGS" "PreToolUse" "Edit" \
204
- "$EAGLE_MEM_DIR/hooks/pre-tool-use.sh" \
205
- "PreToolUse hook (Edit)"
223
+ eagle_patch_hook "$SETTINGS" "PreToolUse" "Edit" \
224
+ "$EAGLE_MEM_DIR/hooks/pre-tool-use.sh" \
225
+ "PreToolUse hook (Edit)"
206
226
 
207
- eagle_patch_hook "$SETTINGS" "PreToolUse" "Write" \
208
- "$EAGLE_MEM_DIR/hooks/pre-tool-use.sh" \
209
- "PreToolUse hook (Write)"
227
+ eagle_patch_hook "$SETTINGS" "PreToolUse" "Write" \
228
+ "$EAGLE_MEM_DIR/hooks/pre-tool-use.sh" \
229
+ "PreToolUse hook (Write)"
230
+ else
231
+ eagle_info "Claude hooks skipped ${DIM}(Claude Code not detected)${RESET}"
232
+ fi
233
+
234
+ if [ "$codex_found" = true ]; then
235
+ eagle_register_codex_hooks
236
+ else
237
+ eagle_info "Codex hooks skipped ${DIM}(Codex not detected)${RESET}"
238
+ fi
210
239
 
211
240
  # ─── Install skills ────────────────────────────────────────
212
241
 
213
- if [ -d "$PACKAGE_DIR/skills" ]; then
242
+ if [ "$claude_found" = true ] && [ -d "$PACKAGE_DIR/skills" ]; then
214
243
  mkdir -p "$EAGLE_SKILLS_DIR"
215
244
  for skill_dir in "$PACKAGE_DIR"/skills/*/; do
216
245
  [ ! -d "$skill_dir" ] && continue
@@ -222,44 +251,58 @@ if [ -d "$PACKAGE_DIR/skills" ]; then
222
251
  done
223
252
  fi
224
253
 
254
+ if [ "$codex_found" = true ] && [ -d "$PACKAGE_DIR/skills" ]; then
255
+ mkdir -p "$EAGLE_CODEX_SKILLS_DIR"
256
+ for skill_dir in "$PACKAGE_DIR"/skills/*/; do
257
+ [ ! -d "$skill_dir" ] && continue
258
+ skill_name=$(basename "$skill_dir")
259
+ dst="$EAGLE_CODEX_SKILLS_DIR/$skill_name"
260
+ [ -L "$dst" ] && rm "$dst"
261
+ ln -sf "$skill_dir" "$dst"
262
+ eagle_ok "Codex skill: $skill_name"
263
+ done
264
+ fi
265
+
225
266
  # ─── Statusline integration ───────────────────────────────
226
267
 
227
- EM_STATUSLINE="$EAGLE_MEM_DIR/scripts/statusline-em.sh"
228
- existing_sl=$(jq -r '.statusLine.command // empty' "$SETTINGS" 2>/dev/null)
268
+ if [ "$claude_found" = true ]; then
269
+ EM_STATUSLINE="$EAGLE_MEM_DIR/scripts/statusline-em.sh"
270
+ existing_sl=$(jq -r '.statusLine.command // empty' "$SETTINGS" 2>/dev/null)
229
271
 
230
- if [ -z "$existing_sl" ]; then
231
- # No statusline configured — set up a minimal one that shows Eagle Mem
232
- wrapper="$EAGLE_MEM_DIR/scripts/statusline-wrapper.sh"
233
- cat > "$wrapper" << 'WRAPPER'
272
+ if [ -z "$existing_sl" ]; then
273
+ # No statusline configured — set up a minimal one that shows Eagle Mem
274
+ wrapper="$EAGLE_MEM_DIR/scripts/statusline-wrapper.sh"
275
+ cat > "$wrapper" << 'WRAPPER'
234
276
  #!/usr/bin/env bash
235
277
  input=$(cat)
236
278
  project_dir=$(echo "$input" | jq -r '.workspace.project_dir // .workspace.current_dir // .cwd // ""' 2>/dev/null)
237
279
  source "$HOME/.eagle-mem/scripts/statusline-em.sh"
238
280
  eagle_mem_statusline "$project_dir"
239
281
  WRAPPER
240
- chmod +x "$wrapper"
241
- tmp=$(mktemp)
242
- jq --arg cmd "sh $wrapper" '.statusLine = {"type": "command", "command": $cmd, "refreshInterval": 30}' "$SETTINGS" > "$tmp" && mv "$tmp" "$SETTINGS"
243
- eagle_ok "Statusline ${DIM}(new — Eagle Mem indicator)${RESET}"
244
- elif echo "$existing_sl" | grep -q "eagle-mem"; then
245
- eagle_ok "Statusline ${DIM}(already has Eagle Mem)${RESET}"
246
- else
247
- # Existing statusline — check if it's a .sh file we can patch
248
- sl_file=$(echo "$existing_sl" | sed 's/^sh //')
249
- if [ -f "$sl_file" ] && ! grep -q "eagle-mem" "$sl_file"; then
250
- eagle_dim " Statusline detected: $sl_file"
251
- eagle_dim " To add Eagle Mem, add this snippet before your ASSEMBLE section:"
252
- echo ""
253
- eagle_dim " # ── Eagle Mem ──"
254
- eagle_dim " em_section=\"\""
255
- eagle_dim " if [ -f \"\$HOME/.eagle-mem/scripts/statusline-em.sh\" ]; then"
256
- eagle_dim " source \"\$HOME/.eagle-mem/scripts/statusline-em.sh\""
257
- eagle_dim " em_section=\$(eagle_mem_statusline \"\$project_dir\")"
258
- eagle_dim " fi"
259
- echo ""
260
- eagle_ok "Statusline ${DIM}(manual patch needed — instructions above)${RESET}"
282
+ chmod +x "$wrapper"
283
+ tmp=$(mktemp)
284
+ jq --arg cmd "sh $wrapper" '.statusLine = {"type": "command", "command": $cmd, "refreshInterval": 30}' "$SETTINGS" > "$tmp" && mv "$tmp" "$SETTINGS"
285
+ eagle_ok "Statusline ${DIM}(new — Eagle Mem indicator)${RESET}"
286
+ elif echo "$existing_sl" | grep -q "eagle-mem"; then
287
+ eagle_ok "Statusline ${DIM}(already has Eagle Mem)${RESET}"
261
288
  else
262
- eagle_ok "Statusline ${DIM}(existingcannot auto-patch; add Eagle Mem manually)${RESET}"
289
+ # Existing statuslinecheck if it's a .sh file we can patch
290
+ sl_file=$(echo "$existing_sl" | sed 's/^sh //')
291
+ if [ -f "$sl_file" ] && ! grep -q "eagle-mem" "$sl_file"; then
292
+ eagle_dim " Statusline detected: $sl_file"
293
+ eagle_dim " To add Eagle Mem, add this snippet before your ASSEMBLE section:"
294
+ echo ""
295
+ eagle_dim " # ── Eagle Mem ──"
296
+ eagle_dim " em_section=\"\""
297
+ eagle_dim " if [ -f \"\$HOME/.eagle-mem/scripts/statusline-em.sh\" ]; then"
298
+ eagle_dim " source \"\$HOME/.eagle-mem/scripts/statusline-em.sh\""
299
+ eagle_dim " em_section=\$(eagle_mem_statusline \"\$project_dir\")"
300
+ eagle_dim " fi"
301
+ echo ""
302
+ eagle_ok "Statusline ${DIM}(manual patch needed — instructions above)${RESET}"
303
+ else
304
+ eagle_ok "Statusline ${DIM}(existing — cannot auto-patch; add Eagle Mem manually)${RESET}"
305
+ fi
263
306
  fi
264
307
  fi
265
308
 
@@ -275,10 +318,20 @@ fi
275
318
 
276
319
  # ─── Patch CLAUDE.md with Eagle Mem instructions ─────────
277
320
 
278
- if eagle_patch_claude_md; then
279
- eagle_ok "CLAUDE.md ${DIM}(eagle-summary instructions added)${RESET}"
280
- else
281
- eagle_ok "CLAUDE.md ${DIM}(already has Eagle Mem section)${RESET}"
321
+ if [ "$claude_found" = true ]; then
322
+ if eagle_patch_claude_md; then
323
+ eagle_ok "CLAUDE.md ${DIM}(eagle-summary instructions added)${RESET}"
324
+ else
325
+ eagle_ok "CLAUDE.md ${DIM}(already has Eagle Mem section)${RESET}"
326
+ fi
327
+ fi
328
+
329
+ if [ "$codex_found" = true ]; then
330
+ if eagle_patch_codex_agents_md; then
331
+ eagle_ok "AGENTS.md ${DIM}(Codex eagle-summary instructions added)${RESET}"
332
+ else
333
+ eagle_ok "AGENTS.md ${DIM}(already has Eagle Mem section)${RESET}"
334
+ fi
282
335
  fi
283
336
 
284
337
  # ─── Save installed version ───────────────────────────────
@@ -292,8 +345,9 @@ eagle_footer "Eagle Mem installed successfully."
292
345
 
293
346
  eagle_kv "Database:" "$EAGLE_MEM_DIR/memory.db"
294
347
  eagle_kv "Hooks:" "$EAGLE_MEM_DIR/hooks/"
295
- eagle_kv "Settings:" "$SETTINGS"
348
+ [ "$claude_found" = true ] && eagle_kv "Claude settings:" "$SETTINGS"
349
+ [ "$codex_found" = true ] && eagle_kv "Codex hooks:" "$EAGLE_CODEX_HOOKS"
296
350
 
297
351
  echo ""
298
- eagle_dim "Start a new Claude Code session — Eagle Mem will activate automatically."
352
+ eagle_dim "Start a new Claude Code or Codex session — Eagle Mem will activate automatically."
299
353
  echo ""