eagle-mem 4.10.13 → 4.11.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.
- package/CHANGELOG.md +13 -0
- package/README.md +20 -20
- package/architecture.html +26 -14
- package/bin/eagle-mem +4 -0
- package/db/039_recall_events.sql +27 -0
- package/db/040_graph_decision_nodes.sql +21 -0
- package/db/041_graph_semantic_edge_types.sql +21 -0
- package/db/042_orchestration_auto_events.sql +23 -0
- package/db/043_eagle_events.sql +22 -0
- package/docs/agent-compatibility/README.md +38 -0
- package/docs/agent-compatibility/claude-code.md +50 -0
- package/docs/agent-compatibility/codex.md +51 -0
- package/docs/agent-compatibility/opencode.md +71 -0
- package/hooks/post-tool-use.sh +8 -0
- package/hooks/pre-tool-use.sh +10 -1
- package/hooks/session-end.sh +3 -0
- package/hooks/session-start.sh +7 -0
- package/hooks/stop.sh +10 -1
- package/hooks/user-prompt-submit.sh +79 -6
- package/integrations/opencode_eagle_mem_plugin.js +387 -0
- package/lib/codex-hooks.sh +13 -6
- package/lib/common.sh +63 -0
- package/lib/db-events.sh +89 -0
- package/lib/db-graph.sh +154 -0
- package/lib/db-observations.sh +34 -0
- package/lib/db-orchestration.sh +149 -0
- package/lib/db.sh +2 -0
- package/lib/hooks.sh +12 -7
- package/lib/opencode-hooks.sh +105 -0
- package/lib/provider.sh +2 -2
- package/package.json +5 -2
- package/scripts/compaction.sh +108 -8
- package/scripts/dashboard.sh +372 -0
- package/scripts/doctor.sh +30 -3
- package/scripts/health.sh +40 -2
- package/scripts/help.sh +10 -2
- package/scripts/inspect.sh +285 -0
- package/scripts/install.sh +31 -7
- package/scripts/memories.sh +13 -0
- package/scripts/repair.sh +187 -0
- package/scripts/replay.sh +248 -0
- package/scripts/search.sh +44 -3
- package/scripts/statusline-em.sh +34 -7
- package/scripts/tasks.sh +34 -0
- package/scripts/test.sh +13 -0
- package/scripts/uninstall.sh +9 -0
- package/scripts/update.sh +18 -2
- package/tests/fixtures/agent-hooks/claude-statusline.json +32 -0
- package/tests/fixtures/agent-hooks/claude-user-prompt-submit.json +9 -0
- package/tests/fixtures/agent-hooks/codex-pre-tool-use.json +10 -0
- package/tests/fixtures/agent-hooks/codex-user-prompt-submit.json +7 -0
- package/tests/fixtures/agent-hooks/opencode-chat-message.json +36 -0
- package/tests/fixtures/agent-hooks/opencode-session-compacting.json +9 -0
- package/tests/fixtures/agent-hooks/opencode-todo-updated.json +13 -0
- package/tests/fixtures/agent-hooks/opencode-tool-execute-after.json +15 -0
- package/tests/fixtures/agent-hooks/opencode-tool-execute-before.json +12 -0
- package/tests/test_agent_compatibility_docs_gate.sh +123 -0
- package/tests/test_auto_orchestration_detection.sh +109 -0
- package/tests/test_claude_stop_hook_registration.sh +56 -0
- package/tests/test_codex_hooks_config.sh +73 -0
- package/tests/test_compaction_survival_matrix.sh +237 -0
- package/tests/test_dashboard.sh +96 -0
- package/tests/test_eagle_events.sh +96 -0
- package/tests/test_opencode_hooks_config.sh +56 -0
- package/tests/test_opencode_plugin_adapter.sh +202 -0
- package/tests/test_recall_observability.sh +144 -0
- package/tests/test_repair.sh +63 -0
- package/tests/test_rust_migration_plan.sh +75 -0
- package/tests/test_trust_surfaces.sh +123 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# OpenCode Compatibility
|
|
2
|
+
|
|
3
|
+
Last verified: 2026-06-02
|
|
4
|
+
|
|
5
|
+
## Official Sources
|
|
6
|
+
|
|
7
|
+
- Plugins reference: https://opencode.ai/docs/plugins/
|
|
8
|
+
- Config reference: https://opencode.ai/docs/config/
|
|
9
|
+
- Config schema: https://opencode.ai/config.json
|
|
10
|
+
|
|
11
|
+
## Installed Surface Verified Locally
|
|
12
|
+
|
|
13
|
+
- OpenCode CLI: `opencode --version` reported `1.14.24`.
|
|
14
|
+
- OpenCode plugin package: `@opencode-ai/plugin@1.14.24`.
|
|
15
|
+
- Resolved config path: `~/.config/opencode/opencode.json`.
|
|
16
|
+
- Global plugin directory: `~/.config/opencode/plugins/`.
|
|
17
|
+
|
|
18
|
+
## Behavior Relied On
|
|
19
|
+
|
|
20
|
+
- OpenCode local plugins are JavaScript or TypeScript modules placed in `.opencode/plugins/` for project scope or `~/.config/opencode/plugins/` for global scope.
|
|
21
|
+
- Files in those plugin directories are loaded automatically at startup.
|
|
22
|
+
- NPM plugins are declared with the top-level `plugin` array in `opencode.json`, but Eagle Mem uses the global local-plugin directory so it does not need to mutate the user plugin array.
|
|
23
|
+
- Plugin functions receive a context object with `project`, `directory`, `worktree`, `client`, and `$`, then return a hooks object.
|
|
24
|
+
- The plugin event bus includes `session.created`, `session.updated`, `session.idle`, `session.compacted`, `session.deleted`, `message.updated`, `message.part.updated`, and `todo.updated`.
|
|
25
|
+
- Direct hook keys include `chat.message`, `tool.execute.before`, `tool.execute.after`, `shell.env`, and `experimental.session.compacting`.
|
|
26
|
+
- `tool.execute.before` can deny a tool call by throwing an error and can mutate `output.args` before execution.
|
|
27
|
+
- `tool.execute.after` receives tool output fields that can be annotated for the model.
|
|
28
|
+
- `experimental.session.compacting` fires before compaction and can push additional strings into `output.context`.
|
|
29
|
+
- `opencode --pure` runs without external plugins; doctor checks should report that Eagle Mem OpenCode support depends on non-pure OpenCode sessions.
|
|
30
|
+
|
|
31
|
+
## Eagle Mem Mapping
|
|
32
|
+
|
|
33
|
+
- `chat.message` maps to Eagle Mem `SessionStart` once per session and `UserPromptSubmit` on each user message.
|
|
34
|
+
- `tool.execute.before` maps to Eagle Mem `PreToolUse`; denial becomes a thrown OpenCode plugin error and `updatedInput` mutates `output.args`.
|
|
35
|
+
- `tool.execute.after` maps to Eagle Mem `PostToolUse`; additional context is appended to the tool output so the agent can see guardrail or stale-memory hints.
|
|
36
|
+
- `todo.updated` maps OpenCode todos into Eagle Mem task records through synthetic `TaskCreated` and `TaskUpdate` hook payloads.
|
|
37
|
+
- `session.idle` maps to Eagle Mem `Stop` using the latest assistant text accumulated from message events.
|
|
38
|
+
- `session.deleted` maps to Eagle Mem `SessionEnd`.
|
|
39
|
+
- `experimental.session.compacting` maps to Eagle Mem compact recall by running `SessionStart` with `source=compact` and appending the returned context.
|
|
40
|
+
|
|
41
|
+
## Eagle Mem Files Depending On This
|
|
42
|
+
|
|
43
|
+
- `integrations/opencode_eagle_mem_plugin.js`
|
|
44
|
+
- `lib/opencode-hooks.sh`
|
|
45
|
+
- `lib/common.sh`
|
|
46
|
+
- `scripts/install.sh`
|
|
47
|
+
- `scripts/update.sh`
|
|
48
|
+
- `scripts/uninstall.sh`
|
|
49
|
+
- `scripts/doctor.sh`
|
|
50
|
+
- `scripts/test.sh`
|
|
51
|
+
- `hooks/session-start.sh`
|
|
52
|
+
- `hooks/user-prompt-submit.sh`
|
|
53
|
+
- `hooks/pre-tool-use.sh`
|
|
54
|
+
- `hooks/post-tool-use.sh`
|
|
55
|
+
- `hooks/stop.sh`
|
|
56
|
+
- `hooks/session-end.sh`
|
|
57
|
+
|
|
58
|
+
## Fixtures And Tests
|
|
59
|
+
|
|
60
|
+
- `tests/fixtures/agent-hooks/opencode-chat-message.json`
|
|
61
|
+
- `tests/fixtures/agent-hooks/opencode-tool-execute-before.json`
|
|
62
|
+
- `tests/fixtures/agent-hooks/opencode-tool-execute-after.json`
|
|
63
|
+
- `tests/fixtures/agent-hooks/opencode-todo-updated.json`
|
|
64
|
+
- `tests/fixtures/agent-hooks/opencode-session-compacting.json`
|
|
65
|
+
- `tests/test_agent_compatibility_docs_gate.sh`
|
|
66
|
+
- `tests/test_opencode_hooks_config.sh`
|
|
67
|
+
- `tests/test_opencode_plugin_adapter.sh`
|
|
68
|
+
|
|
69
|
+
## Reverification Notes
|
|
70
|
+
|
|
71
|
+
When editing OpenCode support, re-read the plugins and config docs first. If OpenCode changes plugin load order, local plugin directories, hook names, `tool.execute.*` mutation semantics, `chat.message` payloads, or compaction hooks, update these fixtures before implementation.
|
package/hooks/post-tool-use.sh
CHANGED
|
@@ -122,6 +122,7 @@ esac
|
|
|
122
122
|
|
|
123
123
|
project=$(eagle_project_from_hook_input "$input")
|
|
124
124
|
[ -z "$project" ] && exit 0
|
|
125
|
+
eagle_hook_observability_begin "$input" "PostToolUse"
|
|
125
126
|
|
|
126
127
|
# Ensure session row exists before inserting observations (FK constraint).
|
|
127
128
|
# PostToolUse can race SessionStart — the session row might not exist yet.
|
|
@@ -249,5 +250,12 @@ eagle_posttool_decision_surface "$tool_name" "$fp" "$project" "$agent"
|
|
|
249
250
|
if ! eagle_insert_observation "$session_id" "$project" "$tool_name" "$tool_summary" "$files_read" "$files_modified" "$output_bytes" "$output_lines" "$command_category" "$agent"; then
|
|
250
251
|
eagle_log "ERROR" "PostToolUse: observation insert failed for session=$session_id tool=$tool_name"
|
|
251
252
|
fi
|
|
253
|
+
eagle_hook_observability_set_detail "$(jq -nc \
|
|
254
|
+
--arg tool "$tool_name" \
|
|
255
|
+
--arg summary "$tool_summary" \
|
|
256
|
+
--arg files_read "$files_read" \
|
|
257
|
+
--arg files_modified "$files_modified" \
|
|
258
|
+
'{tool_name:$tool, summary:$summary, files_read:($files_read | fromjson? // []), files_modified:($files_modified | fromjson? // [])}')"
|
|
259
|
+
eagle_hook_observability_complete 0
|
|
252
260
|
|
|
253
261
|
exit 0
|
package/hooks/pre-tool-use.sh
CHANGED
|
@@ -33,6 +33,7 @@ esac
|
|
|
33
33
|
[ ! -f "$EAGLE_MEM_DB" ] && exit 0
|
|
34
34
|
project=$(eagle_project_from_hook_input "$input")
|
|
35
35
|
[ -z "$project" ] && exit 0
|
|
36
|
+
eagle_hook_observability_begin "$input" "PreToolUse"
|
|
36
37
|
|
|
37
38
|
context=""
|
|
38
39
|
updated_input=""
|
|
@@ -382,15 +383,23 @@ Use the existing context, run a narrower search, or bypass once with:
|
|
|
382
383
|
;;
|
|
383
384
|
esac
|
|
384
385
|
|
|
385
|
-
[ -z "$context" ] && [ -z "$updated_input" ]
|
|
386
|
+
if [ -z "$context" ] && [ -z "$updated_input" ]; then
|
|
387
|
+
eagle_hook_observability_set_detail "$(jq -nc --arg tool "$tool_name" --arg action "no_action" '{tool_name:$tool, action:$action}')"
|
|
388
|
+
eagle_hook_observability_complete 0
|
|
389
|
+
exit 0
|
|
390
|
+
fi
|
|
386
391
|
|
|
387
392
|
# Codex PreToolUse now natively receives both blocking decisions and advisory context.
|
|
388
393
|
# Removing the old early-exit to align Codex's pre-tool capabilities with Claude and Antigravity.
|
|
389
394
|
|
|
390
395
|
if [ -n "$updated_input" ]; then
|
|
396
|
+
eagle_hook_observability_set_detail "$(jq -nc --arg tool "$tool_name" --arg action "updated_input" '{tool_name:$tool, action:$action}')"
|
|
397
|
+
eagle_hook_observability_complete 0
|
|
391
398
|
jq -nc --arg ctx "$context" --argjson ui "$updated_input" \
|
|
392
399
|
'{"hookSpecificOutput":{"hookEventName":"PreToolUse","updatedInput":$ui,"additionalContext":$ctx}}'
|
|
393
400
|
else
|
|
401
|
+
eagle_hook_observability_set_detail "$(jq -nc --arg tool "$tool_name" --arg action "additional_context" '{tool_name:$tool, action:$action}')"
|
|
402
|
+
eagle_hook_observability_complete 0
|
|
394
403
|
jq -nc --arg ctx "$context" '{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":$ctx}}'
|
|
395
404
|
fi
|
|
396
405
|
|
package/hooks/session-end.sh
CHANGED
|
@@ -24,6 +24,7 @@ agent=$(eagle_agent_source_from_json "$input")
|
|
|
24
24
|
cwd=$(echo "$input" | jq -r '.cwd // empty')
|
|
25
25
|
project=$(eagle_project_from_hook_input "$input")
|
|
26
26
|
[ -z "$project" ] && exit 0
|
|
27
|
+
eagle_hook_observability_begin "$input" "SessionEnd"
|
|
27
28
|
|
|
28
29
|
# Final sweep: re-capture all task files to catch status changes
|
|
29
30
|
# Claude Code may update task status without triggering PostToolUse
|
|
@@ -40,6 +41,8 @@ fi
|
|
|
40
41
|
|
|
41
42
|
eagle_end_session "$session_id"
|
|
42
43
|
eagle_log "INFO" "SessionEnd: session=$session_id marked completed"
|
|
44
|
+
eagle_hook_observability_set_detail "$(jq -nc --arg action "session_completed" '{action:$action}')"
|
|
45
|
+
eagle_hook_observability_complete 0
|
|
43
46
|
|
|
44
47
|
# Prune observations older than 90 days (keeps DB size bounded)
|
|
45
48
|
eagle_prune_observations 90 "$project"
|
package/hooks/session-start.sh
CHANGED
|
@@ -35,6 +35,7 @@ codex_compact=0
|
|
|
35
35
|
|
|
36
36
|
project=$(eagle_project_from_hook_input "$input")
|
|
37
37
|
[ -z "$project" ] && exit 0
|
|
38
|
+
eagle_hook_observability_begin "$input" "SessionStart"
|
|
38
39
|
|
|
39
40
|
p_esc=$(eagle_sql_escape "$project")
|
|
40
41
|
recall_scope=$(eagle_recall_project_scope_from_cwd "$cwd" "$project")
|
|
@@ -655,7 +656,13 @@ regression_risks: [risk, ...]
|
|
|
655
656
|
fi
|
|
656
657
|
|
|
657
658
|
if [ -n "$context" ]; then
|
|
659
|
+
eagle_hook_observability_set_detail "$(jq -nc \
|
|
660
|
+
--arg source_type "$source_type" \
|
|
661
|
+
--arg recall_scope "$recall_scope" \
|
|
662
|
+
--argjson injected_chars "${#context}" \
|
|
663
|
+
'{source_type:$source_type, recall_scope:$recall_scope, injected_chars:$injected_chars}')"
|
|
658
664
|
eagle_emit_context_for_agent "$agent" "SessionStart" "$context"
|
|
659
665
|
fi
|
|
666
|
+
eagle_hook_observability_complete 0
|
|
660
667
|
|
|
661
668
|
exit 0
|
package/hooks/stop.sh
CHANGED
|
@@ -31,6 +31,7 @@ agent=$(eagle_agent_source_from_json "$input")
|
|
|
31
31
|
|
|
32
32
|
project=$(eagle_project_from_hook_input "$input")
|
|
33
33
|
[ -z "$project" ] && exit 0
|
|
34
|
+
eagle_hook_observability_begin "$input" "Stop"
|
|
34
35
|
|
|
35
36
|
eagle_log "INFO" "Stop: session=$session_id project=$project transcript=$transcript_path agent=$agent"
|
|
36
37
|
|
|
@@ -237,7 +238,7 @@ if [ "$needs_enrichment" -eq 1 ]; then
|
|
|
237
238
|
# lifecycle timeouts and make the hook look broken to users.
|
|
238
239
|
if [ "${EAGLE_MEM_STOP_ENRICH:-0}" != "1" ]; then
|
|
239
240
|
defer_enrichment=1
|
|
240
|
-
eagle_log "INFO" "Stop: LLM enrichment skipped
|
|
241
|
+
eagle_log "INFO" "Stop: LLM enrichment skipped on fast hook path; provider=$provider"
|
|
241
242
|
elif [ "$provider" != "none" ] && [ -n "$text_content" ]; then
|
|
242
243
|
excerpt=$(echo "$text_content" | tail -c 3000)
|
|
243
244
|
|
|
@@ -399,10 +400,18 @@ fi
|
|
|
399
400
|
if [ -n "$request" ] || [ -n "$completed" ] || [ -n "$learned" ]; then
|
|
400
401
|
if eagle_insert_summary "$session_id" "$project" "$request" "$investigated" "$learned" "$completed" "$next_steps" "$files_read" "$files_modified" "$notes" "$decisions" "$gotchas" "$key_files" "$agent"; then
|
|
401
402
|
eagle_log "INFO" "Stop: summary saved for session=$session_id"
|
|
403
|
+
eagle_insert_event "$project" "$session_id" "$agent" "memory_created" "" "Stop" "ok" "$(jq -nc --arg source "summary" '{source:$source}')" >/dev/null 2>&1 || true
|
|
402
404
|
else
|
|
403
405
|
eagle_log "ERROR" "Stop: summary insert FAILED for session=$session_id — check DB constraints"
|
|
404
406
|
fi
|
|
405
407
|
fi
|
|
408
|
+
eagle_hook_observability_set_detail "$(jq -nc \
|
|
409
|
+
--argjson files_read "$files_read" \
|
|
410
|
+
--argjson files_modified "$files_modified" \
|
|
411
|
+
--arg request "$request" \
|
|
412
|
+
--arg completed "$completed" \
|
|
413
|
+
'{request_chars:($request | length), completed_chars:($completed | length), files_read:$files_read, files_modified:$files_modified}')"
|
|
414
|
+
eagle_hook_observability_complete 0
|
|
406
415
|
|
|
407
416
|
if [ "$defer_enrichment" -eq 1 ] && [ "${EAGLE_MEM_STOP_BACKGROUND_ENRICH:-1}" = "1" ] && [ -n "$text_content" ]; then
|
|
408
417
|
mkdir -p "$EAGLE_MEM_DIR/tmp" 2>/dev/null || true
|
|
@@ -30,11 +30,22 @@ recall_scope=$(eagle_recall_project_scope_from_cwd "$cwd" "$project")
|
|
|
30
30
|
[ -z "$recall_scope" ] && recall_scope="$project"
|
|
31
31
|
codex_compact=0
|
|
32
32
|
[ "$agent" = "codex" ] && codex_compact=1
|
|
33
|
+
eagle_hook_observability_begin "$input" "UserPromptSubmit"
|
|
33
34
|
|
|
34
35
|
# ─── Context pressure detection (turn counter since last compact) ──
|
|
35
36
|
# Must run before any early exits so every prompt is counted
|
|
36
37
|
|
|
37
38
|
context=""
|
|
39
|
+
summary_matches=0
|
|
40
|
+
memory_matches=0
|
|
41
|
+
code_matches=0
|
|
42
|
+
summary_refs="[]"
|
|
43
|
+
memory_refs="[]"
|
|
44
|
+
code_refs="[]"
|
|
45
|
+
|
|
46
|
+
count_pipe_rows() {
|
|
47
|
+
awk -F'|' '($1 != "" || $2 != "") { c++ } END { print c + 0 }'
|
|
48
|
+
}
|
|
38
49
|
|
|
39
50
|
if [ -n "$session_id" ] && eagle_validate_session_id "$session_id"; then
|
|
40
51
|
counter_file="$EAGLE_MEM_DIR/.turn-counter.${session_id}"
|
|
@@ -85,6 +96,9 @@ fi
|
|
|
85
96
|
# Skip short prompts — not enough signal for meaningful search
|
|
86
97
|
word_count=$(echo "$user_prompt" | wc -w | tr -d ' ')
|
|
87
98
|
if [ "$word_count" -lt 3 ]; then
|
|
99
|
+
eagle_insert_recall_event "$session_id" "$recall_scope" "$cwd" "$agent" "$user_prompt" "" 0 0 0 "${#context}" "skipped_short_prompt" "" >/dev/null 2>&1 || true
|
|
100
|
+
eagle_hook_observability_set_detail "$(jq -nc --arg recall_status "skipped_short_prompt" --argjson injected_chars "${#context}" '{recall_status:$recall_status, injected_chars:$injected_chars}')"
|
|
101
|
+
eagle_hook_observability_complete 0
|
|
88
102
|
eagle_emit_context_for_agent "$agent" "UserPromptSubmit" "$context"
|
|
89
103
|
exit 0
|
|
90
104
|
fi
|
|
@@ -105,6 +119,9 @@ fts_query=$(echo "$user_prompt" | tr -cs '[:alnum:]' ' ' | tr '[:upper:]' '[:low
|
|
|
105
119
|
}')
|
|
106
120
|
|
|
107
121
|
if [ -z "$fts_query" ]; then
|
|
122
|
+
eagle_insert_recall_event "$session_id" "$recall_scope" "$cwd" "$agent" "$user_prompt" "" 0 0 0 "${#context}" "skipped_no_query" "" >/dev/null 2>&1 || true
|
|
123
|
+
eagle_hook_observability_set_detail "$(jq -nc --arg recall_status "skipped_no_query" --argjson injected_chars "${#context}" '{recall_status:$recall_status, injected_chars:$injected_chars}')"
|
|
124
|
+
eagle_hook_observability_complete 0
|
|
108
125
|
eagle_emit_context_for_agent "$agent" "UserPromptSubmit" "$context"
|
|
109
126
|
exit 0
|
|
110
127
|
fi
|
|
@@ -113,19 +130,27 @@ fi
|
|
|
113
130
|
|
|
114
131
|
lower_prompt=$(printf '%s' "$user_prompt" | tr '[:upper:]' '[:lower:]')
|
|
115
132
|
if printf '%s\n' "$lower_prompt" | grep -Eq '(orchestrat|worker|parallel|multi-agent|multi agent|split|lane|scope out|plan and get started|broad|full codebase|release|publish|ship)'; then
|
|
133
|
+
auto_orchestration=$(eagle_auto_orchestrate_from_prompt "$project" "$session_id" "$agent" "$user_prompt" "$cwd" "broad_prompt" 2>/dev/null || true)
|
|
134
|
+
if [ -n "$auto_orchestration" ]; then
|
|
135
|
+
IFS='|' read -r auto_name auto_id auto_lane_count _auto_lanes_json <<< "$auto_orchestration"
|
|
136
|
+
context+="
|
|
137
|
+
Eagle Mem orchestration: detected broad work and created durable orchestration '$auto_name' with $auto_lane_count lanes.
|
|
138
|
+
- Inspect it with: eagle-mem orchestrate --name $auto_name
|
|
139
|
+
- Lanes already exist as durable tasks; update them instead of relying on memory alone.
|
|
140
|
+
"
|
|
141
|
+
fi
|
|
116
142
|
if [ "$codex_compact" -eq 1 ]; then
|
|
117
143
|
context+="
|
|
118
144
|
Eagle Mem orchestration:
|
|
119
|
-
-
|
|
120
|
-
-
|
|
145
|
+
- Continue from the durable lanes Eagle already created.
|
|
146
|
+
- Keep lane/task status current as work progresses.
|
|
121
147
|
"
|
|
122
148
|
else
|
|
123
149
|
context+="=== Eagle Mem: Orchestration Protocol ===
|
|
124
|
-
|
|
150
|
+
Eagle has already detected broad work and registered durable orchestration state.
|
|
125
151
|
|
|
126
152
|
Use:
|
|
127
|
-
eagle-mem orchestrate
|
|
128
|
-
eagle-mem orchestrate lane add <key> --agent codex|claude-code --desc \"<self-contained scope>\" --validate \"<command>\"
|
|
153
|
+
eagle-mem orchestrate --name auto
|
|
129
154
|
eagle-mem orchestrate lane start|block|complete <key>
|
|
130
155
|
|
|
131
156
|
Keep this mostly invisible to the user; surface only concise status or handoff when useful.
|
|
@@ -146,6 +171,8 @@ memory_limit=3
|
|
|
146
171
|
|
|
147
172
|
results=$(eagle_search_summaries "$fts_query" "$recall_scope" "$summary_limit")
|
|
148
173
|
memory_results=$(eagle_search_agent_memories "$fts_query" "$recall_scope" "$memory_limit" 2>/dev/null || true)
|
|
174
|
+
summary_matches=$(printf '%s\n' "$results" | count_pipe_rows)
|
|
175
|
+
memory_matches=$(printf '%s\n' "$memory_results" | count_pipe_rows)
|
|
149
176
|
|
|
150
177
|
if [ -n "$results" ] || [ -n "$memory_results" ]; then
|
|
151
178
|
if [ "$codex_compact" -eq 1 ]; then
|
|
@@ -195,6 +222,13 @@ Eagle Mem recalls:
|
|
|
195
222
|
context+="
|
|
196
223
|
"
|
|
197
224
|
fi
|
|
225
|
+
summary_refs=$(printf '%s' "$summary_refs" | jq -c \
|
|
226
|
+
--arg created_at "$created_at" \
|
|
227
|
+
--arg agent "$summary_agent" \
|
|
228
|
+
--arg request "$req" \
|
|
229
|
+
--arg completed "$completed" \
|
|
230
|
+
--arg learned "$learned" \
|
|
231
|
+
'. + [{created_at:$created_at, agent:$agent, request:$request, completed:$completed, learned:$learned}]' 2>/dev/null || printf '[]')
|
|
198
232
|
done <<< "$results"
|
|
199
233
|
|
|
200
234
|
while IFS='|' read -r mname mtype mdesc msnippet _mfile _mupdated morigin; do
|
|
@@ -219,6 +253,12 @@ Eagle Mem recalls:
|
|
|
219
253
|
context+="
|
|
220
254
|
"
|
|
221
255
|
fi
|
|
256
|
+
memory_refs=$(printf '%s' "$memory_refs" | jq -c \
|
|
257
|
+
--arg name "$mname" \
|
|
258
|
+
--arg type "$mtype" \
|
|
259
|
+
--arg description "$mdesc" \
|
|
260
|
+
--arg agent "$morigin" \
|
|
261
|
+
'. + [{name:$name, type:$type, description:$description, agent:$agent}]' 2>/dev/null || printf '[]')
|
|
222
262
|
done <<< "$memory_results"
|
|
223
263
|
fi
|
|
224
264
|
|
|
@@ -226,6 +266,7 @@ fi
|
|
|
226
266
|
has_chunks=$(eagle_count_code_chunks "$project")
|
|
227
267
|
if [ "${has_chunks:-0}" -gt 0 ]; then
|
|
228
268
|
code_results=$(eagle_search_code_chunks "$fts_query" "$project" "$code_limit")
|
|
269
|
+
code_matches=$(printf '%s\n' "$code_results" | count_pipe_rows)
|
|
229
270
|
|
|
230
271
|
if [ -n "$code_results" ]; then
|
|
231
272
|
if [ "$codex_compact" -eq 1 ]; then
|
|
@@ -246,11 +287,27 @@ Relevant code:
|
|
|
246
287
|
[ -n "$lang" ] && context+=" ($lang)"
|
|
247
288
|
context+="
|
|
248
289
|
"
|
|
290
|
+
code_refs=$(printf '%s' "$code_refs" | jq -c \
|
|
291
|
+
--arg file "$fpath" \
|
|
292
|
+
--arg start_line "$sline" \
|
|
293
|
+
--arg end_line "$eline" \
|
|
294
|
+
--arg language "$lang" \
|
|
295
|
+
'. + [{file:$file, start_line:$start_line, end_line:$end_line, language:$language}]' 2>/dev/null || printf '[]')
|
|
249
296
|
done <<< "$code_results"
|
|
250
297
|
fi
|
|
251
298
|
fi
|
|
252
299
|
|
|
253
|
-
[ -z "$context" ]
|
|
300
|
+
if [ -z "$context" ]; then
|
|
301
|
+
eagle_insert_recall_event "$session_id" "$recall_scope" "$cwd" "$agent" "$user_prompt" "$fts_query" "$summary_matches" "$memory_matches" "$code_matches" 0 "no_context" "" "$summary_refs" "$memory_refs" "$code_refs" >/dev/null 2>&1 || true
|
|
302
|
+
eagle_hook_observability_set_detail "$(jq -nc \
|
|
303
|
+
--arg recall_status "no_context" \
|
|
304
|
+
--argjson summary_matches "${summary_matches:-0}" \
|
|
305
|
+
--argjson memory_matches "${memory_matches:-0}" \
|
|
306
|
+
--argjson code_matches "${code_matches:-0}" \
|
|
307
|
+
'{recall_status:$recall_status, summary_matches:$summary_matches, memory_matches:$memory_matches, code_matches:$code_matches, injected_chars:0}')"
|
|
308
|
+
eagle_hook_observability_complete 0
|
|
309
|
+
exit 0
|
|
310
|
+
fi
|
|
254
311
|
|
|
255
312
|
if [ "$codex_compact" -eq 1 ]; then
|
|
256
313
|
context+="
|
|
@@ -264,5 +321,21 @@ IMPORTANT: If directly useful, start with one short Eagle Mem attribution line,
|
|
|
264
321
|
"
|
|
265
322
|
fi
|
|
266
323
|
|
|
324
|
+
eagle_insert_recall_event "$session_id" "$recall_scope" "$cwd" "$agent" "$user_prompt" "$fts_query" "$summary_matches" "$memory_matches" "$code_matches" "${#context}" "ok" "" "$summary_refs" "$memory_refs" "$code_refs" >/dev/null 2>&1 || true
|
|
325
|
+
eagle_insert_event "$recall_scope" "$session_id" "$agent" "context_injected" "" "UserPromptSubmit" "ok" "$(jq -nc \
|
|
326
|
+
--argjson summary_matches "${summary_matches:-0}" \
|
|
327
|
+
--argjson memory_matches "${memory_matches:-0}" \
|
|
328
|
+
--argjson code_matches "${code_matches:-0}" \
|
|
329
|
+
--argjson injected_chars "${#context}" \
|
|
330
|
+
'{summary_matches:$summary_matches, memory_matches:$memory_matches, code_matches:$code_matches, injected_chars:$injected_chars}')" >/dev/null 2>&1 || true
|
|
331
|
+
eagle_hook_observability_set_detail "$(jq -nc \
|
|
332
|
+
--arg recall_status "ok" \
|
|
333
|
+
--argjson summary_matches "${summary_matches:-0}" \
|
|
334
|
+
--argjson memory_matches "${memory_matches:-0}" \
|
|
335
|
+
--argjson code_matches "${code_matches:-0}" \
|
|
336
|
+
--argjson injected_chars "${#context}" \
|
|
337
|
+
'{recall_status:$recall_status, summary_matches:$summary_matches, memory_matches:$memory_matches, code_matches:$code_matches, injected_chars:$injected_chars}')"
|
|
338
|
+
eagle_hook_observability_complete 0
|
|
339
|
+
|
|
267
340
|
eagle_emit_context_for_agent "$agent" "UserPromptSubmit" "$context"
|
|
268
341
|
exit 0
|