eagle-mem 4.10.7 → 4.10.9

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/CHANGELOG.md CHANGED
@@ -4,6 +4,24 @@ All notable changes to the **Eagle Mem** project are documented here.
4
4
 
5
5
  ---
6
6
 
7
+ ## v4.10.9 Dream Cycle Graph Memory Hotfix
8
+
9
+ This hotfix closes the remaining graph-memory curation gap:
10
+
11
+ - **Memory Node Wiring**: Dream Cycle curation now creates graph `memory` nodes for active mirrored agent memories before consolidation runs, so consolidated memories can supersede real source memory nodes instead of depending on fuzzy or accidental matches.
12
+ - **Regression Coverage**: The smoke suite now runs an isolated Dream Cycle graph-memory regression that proves multiline memory content does not become bogus graph nodes and that consolidated memories supersede both originals.
13
+
14
+ ---
15
+
16
+ ## v4.10.8 Graph Neighbors Hotfix
17
+
18
+ This hotfix tightens the final graph-memory verification path:
19
+
20
+ - **Exact Neighbor Matching**: `eagle-mem graph neighbors <node>` now prefers exact `node_name` matches before fuzzy matches, and prefers file nodes when names are otherwise ambiguous.
21
+ - **Regression Coverage**: The graph-memory regression suite now verifies that `graph neighbors "a.sh"` selects the exact file node rather than a declaration node whose scoped name merely contains the file path.
22
+
23
+ ---
24
+
7
25
  ## v4.10.7 Graph Rebuild Hotfix
8
26
 
9
27
  This hotfix closes an installed-runtime failure found after the v4.10.6 graph-memory release:
package/README.md CHANGED
@@ -184,6 +184,8 @@ eagle-mem overview set "Current project briefing..."
184
184
 
185
185
  If graph search shows stale deleted files, run `eagle-mem graph rebuild` from the project root. The rebuild command filters missing tracked paths, clears stale code chunks and declaration nodes, preserves manual overviews, and rewires declarations with file-scoped names such as `apps/mac/DictationController.swift::finishDictation`.
186
186
 
187
+ Dream Cycle curation also wires mirrored agent memories into graph `memory` nodes before consolidation, so `supersedes` relationships stay attached to the source memories rather than to incidental text inside memory content.
188
+
187
189
  ### Trust and Recovery
188
190
 
189
191
  Eagle Mem now treats installation as a visible product surface, not a black box:
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "eagle-mem",
3
- "version": "4.10.7",
3
+ "version": "4.10.9",
4
4
  "description": "Shared memory, release guardrails, RTK token protection, and worker lanes for Claude Code, Codex, Grok, and Google Antigravity",
5
5
  "bin": {
6
6
  "eagle-mem": "bin/eagle-mem"
7
7
  },
8
+ "scripts": {
9
+ "test": "bash scripts/test.sh"
10
+ },
8
11
  "files": [
9
12
  "bin/",
10
13
  "scripts/",
package/scripts/curate.sh CHANGED
@@ -575,6 +575,22 @@ fi
575
575
  # 7.3 Offline Memory Consolidation (Compiled Truth vs Evidence)
576
576
  active_memories=$(eagle_db "SELECT memory_name, memory_type, description, content FROM agent_memories WHERE project = '$p_esc';")
577
577
  if [ -n "$active_memories" ]; then
578
+ memory_node_count=0
579
+ active_memory_nodes=$(eagle_db_json "SELECT memory_name, content FROM agent_memories WHERE project = '$p_esc';" || true)
580
+ active_memory_node_count=$(printf '%s' "$active_memory_nodes" | jq 'length' 2>/dev/null || echo 0)
581
+ memory_node_index=0
582
+ while [ "$memory_node_index" -lt "$active_memory_node_count" ]; do
583
+ mname=$(printf '%s' "$active_memory_nodes" | jq -r ".[$memory_node_index].memory_name // empty")
584
+ mcontent=$(printf '%s' "$active_memory_nodes" | jq -r ".[$memory_node_index].content // empty")
585
+ memory_node_index=$((memory_node_index + 1))
586
+ [ -n "$mname" ] || continue
587
+ if [ "$DRY_RUN" -eq 0 ]; then
588
+ eagle_graph_add_node "$project" "memory" "$mname" "$mcontent" ""
589
+ fi
590
+ memory_node_count=$((memory_node_count + 1))
591
+ done
592
+ eagle_ok "Wired $memory_node_count agent memory graph nodes"
593
+
578
594
  consolidation_prompt="Analyze these mirrored agent memories for project '$project'. Identify any memories that are redundant, overlap in scope, or describe the same subsystem/gotcha/concept.
579
595
 
580
596
  MEMORIES:
@@ -906,7 +906,18 @@ memories_graph() {
906
906
 
907
907
  # Find node by name (fuzzy or exact)
908
908
  local matched
909
- matched=$(eagle_db "SELECT id, node_type, node_name FROM graph_nodes WHERE project = '$(eagle_sql_escape "$project")' AND (node_name = '$(eagle_sql_escape "$target_name")' OR node_name LIKE '%$(eagle_sql_escape "$target_name")%') LIMIT 1;")
909
+ local project_sql target_sql
910
+ project_sql=$(eagle_sql_escape "$project")
911
+ target_sql=$(eagle_sql_escape "$target_name")
912
+ matched=$(eagle_db "SELECT id, node_type, node_name
913
+ FROM graph_nodes
914
+ WHERE project = '$project_sql'
915
+ AND (node_name = '$target_sql' OR node_name LIKE '%$target_sql%')
916
+ ORDER BY
917
+ CASE WHEN node_name = '$target_sql' THEN 0 ELSE 1 END,
918
+ CASE WHEN node_type = 'file' THEN 0 ELSE 1 END,
919
+ id
920
+ LIMIT 1;")
910
921
  if [ -z "$matched" ]; then
911
922
  eagle_err "Node not found matching '$target_name'."
912
923
  exit 1
package/scripts/test.sh CHANGED
@@ -52,6 +52,7 @@ run_check "Cross Agent Memory (memories query)" "\"$EAGLE_BIN\" memories --json
52
52
  run_check "Installer And Updater (install / update syntax)" "bash -n \"$SCRIPTS_DIR/install.sh\" && bash -n \"$SCRIPTS_DIR/update.sh\""
53
53
  run_check "Code Scan And Index (scan / index syntax)" "bash -n \"$SCRIPTS_DIR/scan.sh\" && bash -n \"$SCRIPTS_DIR/index.sh\""
54
54
  run_check "Graph Memory Rebuild (isolated regression suite)" "bash \"$SCRIPTS_DIR/../tests/test_graph_memory.sh\""
55
+ run_check "Dream Cycle Memory Graph Wiring (isolated regression suite)" "bash \"$SCRIPTS_DIR/../tests/test_curate_graph_memories.sh\""
55
56
 
56
57
  echo ""
57
58
  if [ "$errors" -eq 0 ]; then
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env bash
2
+ # Ensures curate wires source agent memories before adding consolidated graph edges.
3
+ set -euo pipefail
4
+
5
+ ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
6
+ EAGLE_BIN="$ROOT_DIR/bin/eagle-mem"
7
+
8
+ tmp_dir=$(mktemp -d "$ROOT_DIR/.tmp-curate-graph.XXXXXX")
9
+ trap 'rm -rf "$tmp_dir"' EXIT
10
+
11
+ export HOME="$tmp_dir/home"
12
+ export EAGLE_MEM_DIR="$tmp_dir/eagle-mem"
13
+ mkdir -p "$HOME" "$EAGLE_MEM_DIR" "$tmp_dir/bin"
14
+
15
+ cat > "$tmp_dir/bin/curl" <<'EOF'
16
+ #!/usr/bin/env bash
17
+ body=""
18
+ while [ "$#" -gt 0 ]; do
19
+ case "$1" in
20
+ -d)
21
+ shift
22
+ body="${1:-}"
23
+ ;;
24
+ esac
25
+ shift || true
26
+ done
27
+
28
+ if printf '%s' "$body" | grep -q "mirrored agent memories"; then
29
+ content="CONSOLIDATE: Memory A, Memory B -> Compiled AB | description: merged memories | value: --- Compiled Truth --- merged truth"
30
+ else
31
+ content="NONE"
32
+ fi
33
+
34
+ jq -nc --arg content "$content" '{message:{content:$content}}'
35
+ EOF
36
+ chmod +x "$tmp_dir/bin/curl"
37
+ export PATH="$tmp_dir/bin:$PATH"
38
+
39
+ . "$ROOT_DIR/lib/common.sh"
40
+ "$ROOT_DIR/db/migrate.sh" >/dev/null
41
+ . "$ROOT_DIR/lib/db.sh"
42
+
43
+ cat > "$EAGLE_MEM_DIR/config.toml" <<'EOF'
44
+ [provider]
45
+ type = "ollama"
46
+
47
+ [ollama]
48
+ url = "http://127.0.0.1:11434"
49
+ model = "fake"
50
+ EOF
51
+
52
+ eagle_db "INSERT INTO agent_memories (project, file_path, memory_name, memory_type, description, content)
53
+ VALUES
54
+ ('project', 'memory://a', 'Memory A', 'project', 'First memory', 'Content A
55
+ Evidence line that must not become a graph node'),
56
+ ('project', 'memory://b', 'Memory B', 'project', 'Second memory', 'Content B');" >/dev/null
57
+
58
+ "$EAGLE_BIN" curate -p project >/dev/null
59
+
60
+ original_count=$(eagle_db "SELECT COUNT(*)
61
+ FROM graph_nodes
62
+ WHERE project = 'project'
63
+ AND node_type = 'memory'
64
+ AND node_name IN ('Memory A', 'Memory B');")
65
+ if [ "$original_count" != "2" ]; then
66
+ echo "expected original agent memories to be graph nodes, got $original_count" >&2
67
+ exit 1
68
+ fi
69
+
70
+ memory_node_count=$(eagle_db "SELECT COUNT(*)
71
+ FROM graph_nodes
72
+ WHERE project = 'project'
73
+ AND node_type = 'memory';")
74
+ if [ "$memory_node_count" != "3" ]; then
75
+ echo "expected two originals plus one consolidated memory node, got $memory_node_count" >&2
76
+ exit 1
77
+ fi
78
+
79
+ supersedes_edges=$(eagle_db "SELECT COUNT(*)
80
+ FROM graph_edges e
81
+ JOIN graph_nodes s ON s.id = e.source_node_id
82
+ JOIN graph_nodes t ON t.id = e.target_node_id
83
+ WHERE e.project = 'project'
84
+ AND e.edge_type = 'supersedes'
85
+ AND s.node_type = 'memory'
86
+ AND s.node_name = 'Compiled AB'
87
+ AND t.node_type = 'memory'
88
+ AND t.node_name IN ('Memory A', 'Memory B');")
89
+ if [ "$supersedes_edges" != "2" ]; then
90
+ echo "expected consolidated memory to supersede both originals, got $supersedes_edges" >&2
91
+ exit 1
92
+ fi
93
+
94
+ echo "curate graph memory regressions passed"
@@ -107,6 +107,16 @@ case "$overview_value" in
107
107
  ;;
108
108
  esac
109
109
 
110
+ neighbors_output=$(cd "$repo" && "$EAGLE_BIN" graph neighbors "a.sh" | sed -E $'s/\x1b\\[[0-9;]*m//g')
111
+ case "$neighbors_output" in
112
+ *"Node: a.sh [file]"*) ;;
113
+ *)
114
+ echo "graph neighbors did not prefer exact file node match" >&2
115
+ echo "$neighbors_output" >&2
116
+ exit 1
117
+ ;;
118
+ esac
119
+
110
120
  eagle_db "INSERT INTO sessions (id, project, cwd, model, status)
111
121
  VALUES ('session-graph-test', 'project', '$repo', 'test-model', 'completed');" >/dev/null
112
122
  eagle_db "INSERT INTO observations (session_id, project, tool_name, files_read, files_modified)