eagle-mem 4.9.5 → 4.9.7
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/README.md +35 -4
- package/architecture.html +1791 -0
- package/bin/eagle-mem +1 -0
- package/db/migrate.sh +13 -2
- package/docs/visible-surface-ux-contract.md +53 -0
- package/hooks/post-tool-use.sh +2 -2
- package/hooks/pre-tool-use.sh +6 -6
- package/hooks/session-start.sh +188 -1
- package/hooks/user-prompt-submit.sh +35 -12
- package/lib/common.sh +361 -21
- package/lib/db-mirrors.sh +3 -6
- package/lib/db-summaries.sh +10 -1
- package/lib/hooks-posttool.sh +44 -10
- package/lib/updater.sh +12 -0
- package/package.json +4 -2
- package/scripts/doctor.sh +262 -0
- package/scripts/feature.sh +37 -11
- package/scripts/health.sh +10 -7
- package/scripts/help.sh +1 -0
- package/scripts/install.sh +9 -3
- package/scripts/memories.sh +189 -55
- package/scripts/orchestrate.sh +2 -2
- package/scripts/search.sh +195 -31
- package/scripts/statusline-em.sh +129 -26
- package/scripts/uninstall.sh +67 -0
- package/scripts/update.sh +20 -5
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ═══════════════════════════════════════════════════════════
|
|
3
|
+
# Eagle Mem — Doctor
|
|
4
|
+
# Read-only trust and install footprint checks.
|
|
5
|
+
# ═══════════════════════════════════════════════════════════
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
PACKAGE_DIR="${1:-.}"
|
|
9
|
+
shift 2>/dev/null || true
|
|
10
|
+
|
|
11
|
+
SCRIPTS_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
12
|
+
LIB_DIR="$SCRIPTS_DIR/../lib"
|
|
13
|
+
|
|
14
|
+
. "$SCRIPTS_DIR/style.sh"
|
|
15
|
+
. "$LIB_DIR/common.sh"
|
|
16
|
+
|
|
17
|
+
mode="install-footprint"
|
|
18
|
+
json_output=false
|
|
19
|
+
|
|
20
|
+
while [ $# -gt 0 ]; do
|
|
21
|
+
case "$1" in
|
|
22
|
+
--json|-j) json_output=true; shift ;;
|
|
23
|
+
--help|-h)
|
|
24
|
+
echo -e " ${BOLD}eagle-mem doctor${RESET} — Trust and install diagnostics"
|
|
25
|
+
echo ""
|
|
26
|
+
echo -e " ${BOLD}Usage:${RESET}"
|
|
27
|
+
echo -e " eagle-mem doctor"
|
|
28
|
+
echo -e " eagle-mem doctor install-footprint"
|
|
29
|
+
echo ""
|
|
30
|
+
echo -e " ${BOLD}Options:${RESET}"
|
|
31
|
+
echo -e " ${CYAN}-j, --json${RESET} Output structured JSON"
|
|
32
|
+
exit 0
|
|
33
|
+
;;
|
|
34
|
+
install-footprint|footprint)
|
|
35
|
+
mode="$1"
|
|
36
|
+
shift
|
|
37
|
+
;;
|
|
38
|
+
*) shift ;;
|
|
39
|
+
esac
|
|
40
|
+
done
|
|
41
|
+
|
|
42
|
+
case "$mode" in
|
|
43
|
+
install-footprint|footprint|"") ;;
|
|
44
|
+
*)
|
|
45
|
+
eagle_err "Unknown doctor check: $mode"
|
|
46
|
+
eagle_dim "Run: eagle-mem doctor --help"
|
|
47
|
+
exit 1
|
|
48
|
+
;;
|
|
49
|
+
esac
|
|
50
|
+
|
|
51
|
+
package_version=$(jq -r .version "$PACKAGE_DIR/package.json" 2>/dev/null || echo "unknown")
|
|
52
|
+
installed_version=$(tr -d '[:space:]' < "$EAGLE_MEM_DIR/.version" 2>/dev/null || true)
|
|
53
|
+
[ -z "$installed_version" ] && installed_version="not installed"
|
|
54
|
+
|
|
55
|
+
sqlite_bin=$(eagle_sqlite_path)
|
|
56
|
+
sqlite_version=$(eagle_sqlite_version)
|
|
57
|
+
sqlite_fts5=false
|
|
58
|
+
if eagle_sqlite_supports_fts5; then
|
|
59
|
+
sqlite_fts5=true
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
runtime_exists=false
|
|
63
|
+
db_exists=false
|
|
64
|
+
[ -d "$EAGLE_MEM_DIR" ] && runtime_exists=true
|
|
65
|
+
[ -f "$EAGLE_MEM_DB" ] && db_exists=true
|
|
66
|
+
|
|
67
|
+
doctor_compare_group() {
|
|
68
|
+
local group="$1"
|
|
69
|
+
local checked=0 missing=0 drift=0
|
|
70
|
+
local src dst
|
|
71
|
+
for src in "$PACKAGE_DIR/$group"/*; do
|
|
72
|
+
[ -f "$src" ] || continue
|
|
73
|
+
case "$group" in
|
|
74
|
+
db) ;;
|
|
75
|
+
*)
|
|
76
|
+
case "$src" in
|
|
77
|
+
*.sh|*/eagle-mem) ;;
|
|
78
|
+
*) continue ;;
|
|
79
|
+
esac
|
|
80
|
+
;;
|
|
81
|
+
esac
|
|
82
|
+
checked=$((checked + 1))
|
|
83
|
+
dst="$EAGLE_MEM_DIR/$group/$(basename "$src")"
|
|
84
|
+
if [ ! -f "$dst" ]; then
|
|
85
|
+
missing=$((missing + 1))
|
|
86
|
+
elif ! cmp -s "$src" "$dst"; then
|
|
87
|
+
drift=$((drift + 1))
|
|
88
|
+
fi
|
|
89
|
+
done
|
|
90
|
+
printf '%s|%s|%s\n' "$checked" "$missing" "$drift"
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
hooks_cmp=$(doctor_compare_group hooks)
|
|
94
|
+
lib_cmp=$(doctor_compare_group lib)
|
|
95
|
+
db_cmp=$(doctor_compare_group db)
|
|
96
|
+
scripts_cmp=$(doctor_compare_group scripts)
|
|
97
|
+
manifest_path=$(eagle_runtime_manifest_path)
|
|
98
|
+
manifest_check=$(eagle_runtime_manifest_check)
|
|
99
|
+
manifest_status="${manifest_check%%|*}"
|
|
100
|
+
manifest_checked=$(printf '%s' "$manifest_check" | cut -d'|' -f2)
|
|
101
|
+
manifest_missing=$(printf '%s' "$manifest_check" | cut -d'|' -f3)
|
|
102
|
+
manifest_drift=$(printf '%s' "$manifest_check" | cut -d'|' -f4)
|
|
103
|
+
manifest_version=$(eagle_runtime_manifest_field '.package.version' 2>/dev/null || true)
|
|
104
|
+
manifest_action=$(eagle_runtime_manifest_field '.action' 2>/dev/null || true)
|
|
105
|
+
manifest_generated_at=$(eagle_runtime_manifest_field '.generated_at' 2>/dev/null || true)
|
|
106
|
+
manifest_package_dir=$(eagle_runtime_manifest_field '.package.dir' 2>/dev/null || true)
|
|
107
|
+
|
|
108
|
+
sum_missing=0
|
|
109
|
+
sum_drift=0
|
|
110
|
+
for row in "$hooks_cmp" "$lib_cmp" "$db_cmp" "$scripts_cmp"; do
|
|
111
|
+
IFS='|' read -r _checked missing drift <<< "$row"
|
|
112
|
+
sum_missing=$((sum_missing + missing))
|
|
113
|
+
sum_drift=$((sum_drift + drift))
|
|
114
|
+
done
|
|
115
|
+
|
|
116
|
+
claude_hooks="not found"
|
|
117
|
+
if [ -f "$EAGLE_SETTINGS" ] && command -v jq >/dev/null 2>&1; then
|
|
118
|
+
if jq -e '.. | objects | .command? // empty | select(test("eagle-mem|\\.eagle-mem"))' "$EAGLE_SETTINGS" >/dev/null 2>&1; then
|
|
119
|
+
claude_hooks="registered"
|
|
120
|
+
else
|
|
121
|
+
claude_hooks="not registered"
|
|
122
|
+
fi
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
codex_hooks="not found"
|
|
126
|
+
if [ -f "$EAGLE_CODEX_HOOKS" ] && command -v jq >/dev/null 2>&1; then
|
|
127
|
+
if jq -e '.. | objects | .command? // empty | select(test("eagle-mem|\\.eagle-mem"))' "$EAGLE_CODEX_HOOKS" >/dev/null 2>&1; then
|
|
128
|
+
codex_hooks="registered"
|
|
129
|
+
else
|
|
130
|
+
codex_hooks="not registered"
|
|
131
|
+
fi
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
statusline_state="not configured"
|
|
135
|
+
statusline_command=""
|
|
136
|
+
if [ -f "$EAGLE_SETTINGS" ] && command -v jq >/dev/null 2>&1; then
|
|
137
|
+
statusline_command=$(jq -r '.statusLine.command // .statusline.command // empty' "$EAGLE_SETTINGS" 2>/dev/null)
|
|
138
|
+
if [ -n "$statusline_command" ]; then
|
|
139
|
+
if printf '%s' "$statusline_command" | grep -qE 'eagle-mem|\.eagle-mem'; then
|
|
140
|
+
statusline_state="registered"
|
|
141
|
+
else
|
|
142
|
+
sl_file=$(eagle_statusline_script_from_command "$statusline_command" 2>/dev/null || true)
|
|
143
|
+
if [ -n "$sl_file" ] && grep -qE 'eagle_mem_statusline|\.eagle-mem/scripts/statusline-em' "$sl_file" 2>/dev/null; then
|
|
144
|
+
statusline_state="registered"
|
|
145
|
+
else
|
|
146
|
+
statusline_state="custom"
|
|
147
|
+
fi
|
|
148
|
+
fi
|
|
149
|
+
fi
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
overall="Healthy"
|
|
153
|
+
if [ "$runtime_exists" != true ] || [ "$db_exists" != true ]; then
|
|
154
|
+
overall="Not installed"
|
|
155
|
+
elif [ "$sqlite_fts5" != true ] || [ "$sum_missing" -gt 0 ] || [ "$sum_drift" -gt 0 ] || [ "$manifest_status" != "ok" ]; then
|
|
156
|
+
overall="Needs attention"
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
if [ "$json_output" = true ]; then
|
|
160
|
+
jq -nc \
|
|
161
|
+
--arg overall "$overall" \
|
|
162
|
+
--arg package_dir "$PACKAGE_DIR" \
|
|
163
|
+
--arg runtime_dir "$EAGLE_MEM_DIR" \
|
|
164
|
+
--arg db "$EAGLE_MEM_DB" \
|
|
165
|
+
--arg package_version "$package_version" \
|
|
166
|
+
--arg installed_version "$installed_version" \
|
|
167
|
+
--arg sqlite_bin "${sqlite_bin:-}" \
|
|
168
|
+
--arg sqlite_version "${sqlite_version:-}" \
|
|
169
|
+
--argjson sqlite_fts5 "$sqlite_fts5" \
|
|
170
|
+
--arg claude_hooks "$claude_hooks" \
|
|
171
|
+
--arg codex_hooks "$codex_hooks" \
|
|
172
|
+
--arg statusline "$statusline_state" \
|
|
173
|
+
--arg hooks_cmp "$hooks_cmp" \
|
|
174
|
+
--arg lib_cmp "$lib_cmp" \
|
|
175
|
+
--arg db_cmp "$db_cmp" \
|
|
176
|
+
--arg scripts_cmp "$scripts_cmp" \
|
|
177
|
+
--arg manifest_path "$manifest_path" \
|
|
178
|
+
--arg manifest_status "$manifest_status" \
|
|
179
|
+
--argjson manifest_checked "${manifest_checked:-0}" \
|
|
180
|
+
--argjson manifest_missing "${manifest_missing:-0}" \
|
|
181
|
+
--argjson manifest_drift "${manifest_drift:-0}" \
|
|
182
|
+
--arg manifest_version "${manifest_version:-}" \
|
|
183
|
+
--arg manifest_action "${manifest_action:-}" \
|
|
184
|
+
--arg manifest_generated_at "${manifest_generated_at:-}" \
|
|
185
|
+
--arg manifest_package_dir "${manifest_package_dir:-}" \
|
|
186
|
+
'{overall:$overall, package_dir:$package_dir, runtime_dir:$runtime_dir, db:$db,
|
|
187
|
+
versions:{package:$package_version, installed:$installed_version},
|
|
188
|
+
sqlite:{path:$sqlite_bin, version:$sqlite_version, fts5:$sqlite_fts5},
|
|
189
|
+
hooks:{claude:$claude_hooks, codex:$codex_hooks, statusline:$statusline},
|
|
190
|
+
runtime_drift:{hooks:$hooks_cmp, lib:$lib_cmp, db:$db_cmp, scripts:$scripts_cmp},
|
|
191
|
+
manifest:{path:$manifest_path, status:$manifest_status, checked:$manifest_checked,
|
|
192
|
+
missing:$manifest_missing, drift:$manifest_drift, version:$manifest_version,
|
|
193
|
+
action:$manifest_action, generated_at:$manifest_generated_at,
|
|
194
|
+
package_dir:$manifest_package_dir}}'
|
|
195
|
+
exit 0
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
eagle_header "Doctor"
|
|
199
|
+
echo -e " ${BOLD}Overall:${RESET} $overall"
|
|
200
|
+
echo ""
|
|
201
|
+
echo -e " ${BOLD}Install footprint${RESET}"
|
|
202
|
+
eagle_kv "Package:" "$PACKAGE_DIR"
|
|
203
|
+
eagle_kv "Runtime:" "$EAGLE_MEM_DIR"
|
|
204
|
+
eagle_kv "Database:" "$EAGLE_MEM_DB"
|
|
205
|
+
eagle_kv "Version:" "package $package_version, installed $installed_version"
|
|
206
|
+
echo ""
|
|
207
|
+
|
|
208
|
+
echo -e " ${BOLD}SQLite${RESET}"
|
|
209
|
+
if [ -n "$sqlite_bin" ]; then
|
|
210
|
+
eagle_kv "Binary:" "$sqlite_bin"
|
|
211
|
+
eagle_kv "Version:" "${sqlite_version:-unknown}"
|
|
212
|
+
if [ "$sqlite_fts5" = true ]; then
|
|
213
|
+
eagle_ok "FTS5 available"
|
|
214
|
+
else
|
|
215
|
+
eagle_fail "FTS5 unavailable"
|
|
216
|
+
fi
|
|
217
|
+
else
|
|
218
|
+
eagle_fail "SQLite not found"
|
|
219
|
+
fi
|
|
220
|
+
echo ""
|
|
221
|
+
|
|
222
|
+
echo -e " ${BOLD}Hooks${RESET}"
|
|
223
|
+
eagle_kv "Claude Code:" "$claude_hooks"
|
|
224
|
+
eagle_kv "Codex:" "$codex_hooks"
|
|
225
|
+
eagle_kv "Statusline:" "$statusline_state"
|
|
226
|
+
echo ""
|
|
227
|
+
|
|
228
|
+
echo -e " ${BOLD}Install manifest${RESET}"
|
|
229
|
+
eagle_kv "Path:" "$manifest_path"
|
|
230
|
+
if [ "$manifest_status" = "ok" ]; then
|
|
231
|
+
eagle_ok "${manifest_checked:-0} files match manifest"
|
|
232
|
+
else
|
|
233
|
+
eagle_warn "status=$manifest_status, checked=${manifest_checked:-0}, missing=${manifest_missing:-0}, drift=${manifest_drift:-0}"
|
|
234
|
+
fi
|
|
235
|
+
[ -n "$manifest_version" ] && eagle_kv "Version:" "$manifest_version"
|
|
236
|
+
[ -n "$manifest_action" ] && eagle_kv "Action:" "$manifest_action"
|
|
237
|
+
[ -n "$manifest_generated_at" ] && eagle_kv "Generated:" "$manifest_generated_at"
|
|
238
|
+
echo ""
|
|
239
|
+
|
|
240
|
+
echo -e " ${BOLD}Runtime drift${RESET}"
|
|
241
|
+
for label_row in "hooks:$hooks_cmp" "lib:$lib_cmp" "db:$db_cmp" "scripts:$scripts_cmp"; do
|
|
242
|
+
label="${label_row%%:*}"
|
|
243
|
+
row="${label_row#*:}"
|
|
244
|
+
IFS='|' read -r checked missing drift <<< "$row"
|
|
245
|
+
if [ "$missing" -eq 0 ] && [ "$drift" -eq 0 ] 2>/dev/null; then
|
|
246
|
+
eagle_ok "$label: $checked checked, no drift"
|
|
247
|
+
else
|
|
248
|
+
eagle_warn "$label: $checked checked, $missing missing, $drift drifted"
|
|
249
|
+
fi
|
|
250
|
+
done
|
|
251
|
+
echo ""
|
|
252
|
+
|
|
253
|
+
echo -e " ${BOLD}Next${RESET}"
|
|
254
|
+
if [ "$overall" = "Healthy" ]; then
|
|
255
|
+
eagle_ok "Installed runtime matches this package."
|
|
256
|
+
else
|
|
257
|
+
[ "$runtime_exists" != true ] && eagle_info "Run: eagle-mem install"
|
|
258
|
+
[ "$manifest_status" != "ok" ] && eagle_info "Run: eagle-mem update to refresh the install manifest."
|
|
259
|
+
[ "$sum_missing" -gt 0 ] || [ "$sum_drift" -gt 0 ] && eagle_info "Run: eagle-mem update"
|
|
260
|
+
[ "$sqlite_fts5" != true ] && eagle_info "Set EAGLE_SQLITE_BIN to an FTS5-capable sqlite3."
|
|
261
|
+
fi
|
|
262
|
+
echo ""
|
package/scripts/feature.sh
CHANGED
|
@@ -18,6 +18,7 @@ eagle_header "Features"
|
|
|
18
18
|
project=$(eagle_project_from_cwd "$(pwd)")
|
|
19
19
|
subcommand="${1:-list}"
|
|
20
20
|
shift 2>/dev/null || true
|
|
21
|
+
raw_output=false
|
|
21
22
|
|
|
22
23
|
case "$subcommand" in
|
|
23
24
|
list|ls)
|
|
@@ -73,28 +74,53 @@ case "$subcommand" in
|
|
|
73
74
|
;;
|
|
74
75
|
|
|
75
76
|
pending)
|
|
77
|
+
limit=50
|
|
78
|
+
while [ $# -gt 0 ]; do
|
|
79
|
+
case "$1" in
|
|
80
|
+
--raw|--debug) raw_output=true; shift ;;
|
|
81
|
+
--limit|-n) limit="$2"; shift 2 ;;
|
|
82
|
+
--project|-p) project="$2"; shift 2 ;;
|
|
83
|
+
*) shift ;;
|
|
84
|
+
esac
|
|
85
|
+
done
|
|
86
|
+
limit=$(eagle_sql_int "$limit")
|
|
87
|
+
[ "$limit" -eq 0 ] && limit=50
|
|
76
88
|
results=$(eagle_list_pending_feature_verifications "$project" 50)
|
|
77
89
|
if [ -z "$results" ]; then
|
|
78
90
|
eagle_ok "No pending feature verifications for '$project'"
|
|
79
91
|
exit 0
|
|
80
92
|
fi
|
|
81
93
|
|
|
82
|
-
|
|
83
|
-
echo -e " ${
|
|
94
|
+
pending_count=$(printf '%s\n' "$results" | sed '/^[[:space:]]*$/d' | wc -l | tr -d ' ')
|
|
95
|
+
echo -e " ${BOLD}Pending verification${RESET} ${DIM}($project)${RESET}"
|
|
96
|
+
echo -e " ${DIM}${pending_count} check(s) must be verified or waived before release-boundary commands.${RESET}"
|
|
97
|
+
echo ""
|
|
98
|
+
|
|
99
|
+
shown=0
|
|
84
100
|
while IFS='|' read -r id feat file reason trigger created smoke fingerprint; do
|
|
85
101
|
[ -z "$id" ] && continue
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
[ -n "$
|
|
92
|
-
[
|
|
93
|
-
|
|
102
|
+
[ "$shown" -ge "$limit" ] && break
|
|
103
|
+
shown=$((shown + 1))
|
|
104
|
+
echo -e " ${BOLD}${shown}. ${feat}${RESET} ${DIM}#${id}${RESET}"
|
|
105
|
+
[ -n "$file" ] && echo -e " ${DIM}File:${RESET} $file"
|
|
106
|
+
[ -n "$reason" ] && echo -e " ${DIM}Why:${RESET} $reason"
|
|
107
|
+
[ -n "$smoke" ] && echo -e " ${CYAN}Smoke:${RESET} $smoke"
|
|
108
|
+
if [ "$raw_output" = true ]; then
|
|
109
|
+
[ -n "$trigger" ] && echo -e " ${DIM}Trigger:${RESET} $trigger"
|
|
110
|
+
[ -n "$fingerprint" ] && echo -e " ${DIM}Diff:${RESET} $fingerprint"
|
|
111
|
+
[ -n "$created" ] && echo -e " ${DIM}Created:${RESET} $created"
|
|
112
|
+
fi
|
|
113
|
+
echo ""
|
|
94
114
|
done <<< "$results"
|
|
95
|
-
|
|
115
|
+
if [ "$pending_count" -gt "$shown" ] 2>/dev/null; then
|
|
116
|
+
eagle_dim "$((pending_count - shown)) more pending; run with --limit $pending_count to show all."
|
|
117
|
+
echo ""
|
|
118
|
+
fi
|
|
96
119
|
eagle_info "Verify after testing: eagle-mem feature verify <name> --notes \"what passed\""
|
|
97
120
|
eagle_info "Waive intentionally: eagle-mem feature waive <id> --reason \"why safe\""
|
|
121
|
+
if [ "$raw_output" = false ]; then
|
|
122
|
+
eagle_dim "Run with --raw to show trigger, diff fingerprint, and created timestamp."
|
|
123
|
+
fi
|
|
98
124
|
;;
|
|
99
125
|
|
|
100
126
|
waive)
|
package/scripts/health.sh
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
2
|
+
# ═══════════════════════════════════════════════════════════
|
|
3
3
|
# Eagle Mem — Health Check
|
|
4
4
|
# Diagnoses how well the self-learning pipeline is working
|
|
5
|
-
#
|
|
5
|
+
# ═══════════════════════════════════════════════════════════
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
|
|
8
8
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
@@ -51,7 +51,7 @@ score=0
|
|
|
51
51
|
max_score=0
|
|
52
52
|
issues=()
|
|
53
53
|
|
|
54
|
-
#
|
|
54
|
+
# ─── 1. Summary capture rate (25 pts) ───────────────────
|
|
55
55
|
|
|
56
56
|
max_score=$((max_score + 25))
|
|
57
57
|
|
|
@@ -263,10 +263,10 @@ else
|
|
|
263
263
|
issues+=("Run: eagle-mem curate --dry-run")
|
|
264
264
|
fi
|
|
265
265
|
|
|
266
|
-
# ─── Score
|
|
266
|
+
# ─── Score ────────────────────────────────────────────────
|
|
267
267
|
|
|
268
268
|
echo ""
|
|
269
|
-
echo -e " ${DIM}
|
|
269
|
+
echo -e " ${DIM}─────────────────────────────────────${RESET}"
|
|
270
270
|
|
|
271
271
|
pct=$((score * 100 / max_score))
|
|
272
272
|
if [ "$pct" -ge 80 ]; then
|
|
@@ -280,14 +280,17 @@ else
|
|
|
280
280
|
grade="Unhealthy"
|
|
281
281
|
fi
|
|
282
282
|
|
|
283
|
-
echo -e " ${BOLD}
|
|
283
|
+
echo -e " ${BOLD}Overall:${RESET} ${color}${grade}${RESET} ${DIM}${score}/${max_score} (${pct}%)${RESET}"
|
|
284
284
|
|
|
285
285
|
if [ ${#issues[@]} -gt 0 ]; then
|
|
286
286
|
echo ""
|
|
287
|
-
echo -e " ${BOLD}
|
|
287
|
+
echo -e " ${BOLD}Next:${RESET}"
|
|
288
288
|
for issue in "${issues[@]}"; do
|
|
289
289
|
echo -e " ${YELLOW}!${RESET} $issue"
|
|
290
290
|
done
|
|
291
|
+
else
|
|
292
|
+
echo ""
|
|
293
|
+
eagle_ok "No immediate action needed."
|
|
291
294
|
fi
|
|
292
295
|
|
|
293
296
|
eagle_footer "Health check complete."
|
package/scripts/help.sh
CHANGED
|
@@ -22,6 +22,7 @@ echo -e " ${CYAN}update${RESET} Re-deploy hooks and run migrations"
|
|
|
22
22
|
echo -e " ${CYAN}uninstall${RESET} Remove hooks and optionally delete data"
|
|
23
23
|
echo -e " ${CYAN}search${RESET} Search past sessions, memories, and code"
|
|
24
24
|
echo -e " ${CYAN}health${RESET} Diagnose pipeline health and background automation"
|
|
25
|
+
echo -e " ${CYAN}doctor${RESET} Show install footprint, hooks, SQLite, manifest, and runtime drift"
|
|
25
26
|
echo -e " ${CYAN}updates${RESET} Auto-update status and policy"
|
|
26
27
|
echo -e " ${CYAN}overview${RESET} Build or view project overview"
|
|
27
28
|
echo -e " ${CYAN}session${RESET} Save a manual session summary"
|
package/scripts/install.sh
CHANGED
|
@@ -180,6 +180,8 @@ if [ "$prereqs_ok" = false ]; then
|
|
|
180
180
|
exit 1
|
|
181
181
|
fi
|
|
182
182
|
|
|
183
|
+
eagle_runtime_change_plan "install" "$PACKAGE_DIR" "$claude_found" "$codex_found"
|
|
184
|
+
|
|
183
185
|
echo ""
|
|
184
186
|
|
|
185
187
|
# ─── Copy files to ~/.eagle-mem/ ───────────────────────────
|
|
@@ -334,8 +336,7 @@ WRAPPER
|
|
|
334
336
|
eagle_dim " # ── Eagle Mem ──"
|
|
335
337
|
eagle_dim " em_section=\"\""
|
|
336
338
|
eagle_dim " if [ -f \"\$HOME/.eagle-mem/scripts/statusline-em.sh\" ]; then"
|
|
337
|
-
eagle_dim "
|
|
338
|
-
eagle_dim " em_section=\$(eagle_mem_statusline \"\$project_dir\" \"\$session_id\" \"\$input\")"
|
|
339
|
+
eagle_dim " em_section=\$(printf '%s' \"\$input\" | bash \"\$HOME/.eagle-mem/scripts/statusline-em.sh\" --hud)"
|
|
339
340
|
eagle_dim " fi"
|
|
340
341
|
echo ""
|
|
341
342
|
eagle_ok "Statusline ${DIM}(manual patch needed — instructions above)${RESET}"
|
|
@@ -365,7 +366,7 @@ eagle_ok "Auto-updates ${DIM}(mode=$(eagle_update_config_mode), allow=$(eagle_up
|
|
|
365
366
|
|
|
366
367
|
if [ "$claude_found" = true ]; then
|
|
367
368
|
if eagle_patch_claude_md; then
|
|
368
|
-
|
|
369
|
+
eagle_ok "CLAUDE.md ${DIM}(Eagle Mem guidance added)${RESET}"
|
|
369
370
|
else
|
|
370
371
|
eagle_ok "CLAUDE.md ${DIM}(already has Eagle Mem section)${RESET}"
|
|
371
372
|
fi
|
|
@@ -384,6 +385,11 @@ fi
|
|
|
384
385
|
version=$(jq -r .version "$PACKAGE_DIR/package.json" 2>/dev/null || echo "unknown")
|
|
385
386
|
echo "$version" > "$EAGLE_MEM_DIR/.version"
|
|
386
387
|
echo "$version" > "$EAGLE_MEM_DIR/.latest-version"
|
|
388
|
+
if eagle_runtime_manifest_write "$PACKAGE_DIR" "install"; then
|
|
389
|
+
eagle_ok "Install manifest written"
|
|
390
|
+
else
|
|
391
|
+
eagle_warn "Install manifest could not be written"
|
|
392
|
+
fi
|
|
387
393
|
|
|
388
394
|
# ─── Summary ───────────────────────────────────────────────
|
|
389
395
|
|