workstation: harden memory hooks — prune dead plugin refs + homelab-CLI-only store
All checks were successful
ci/woodpecker/push/default Pipeline was successful

wire-memory-hooks.py now PRUNES any settings.json hook still pointing at the
retired claude-memory plugin (plugins/claude-memory/hooks/) before the additive
pass. install_memory() rm -rf's that dir, so those entries are dangling — and a
missing UserPromptSubmit hook exits 2, a BLOCKING error that erases the prompt
and froze emo's sessions (2026-06-22). The plugin shares basenames with the
homelab hooks, so the old additive-only logic saw the dead plugin path as
"already present" and skipped installing the real ~/.claude/hooks/ copy; pruning
first fixes that. Verified against emo's exact original config: yields the
correct 4-hook set, drops the dead PermissionRequest entry, idempotent on rerun.

auto-learn.py now stores via the `homelab memory` CLI only — dropped the direct
HTTP path and the local-SQLite fallback (memory is homelab-CLI-only per Viktor;
never local files). No-ops silently when no API key is in env (e.g. ancamilea).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Viktor Barzin 2026-06-22 09:24:42 +00:00
parent aeed461591
commit 2169e0de5f
2 changed files with 58 additions and 55 deletions

View file

@ -1,11 +1,17 @@
#!/usr/bin/env python3
"""Wire the homelab-memory hooks into a user's ~/.claude/settings.json, if-absent.
"""Wire the homelab-memory hooks into a user's ~/.claude/settings.json.
Part of the claude-memory MCP -> homelab CLI migration (all-users rollout).
Idempotent + ADDITIVE: only ADDS a hook group when no existing command references
that hook script. Never removes/reorders existing hooks, and never touches `env`
(the per-user MEMORY_API_KEY) or any other setting. Safe to run on every reconcile
and on a user's already-populated config.
Two passes, idempotent, never touching `env` (the per-user MEMORY_API_KEY) or any
other setting:
(0) PRUNE any hook command still pointing at the retired claude-memory plugin
(`plugins/claude-memory/hooks/`). install_memory() rm -rf's that dir, so
those entries are dangling and a missing UserPromptSubmit hook exits 2,
a BLOCKING error that erases the prompt and freezes the session (devvm emo
incident 2026-06-22). Must run BEFORE the additive pass: the plugin shares
basenames with the homelab hooks, so without pruning, the "already present"
check below matches the dead plugin path and skips the real install.
(1) ADD each homelab hook group when no existing command references its script.
Usage: wire-memory-hooks.py <home_dir>
Exit 0 on success (changed or already-present); 1 only on an unreadable settings file.
@ -38,6 +44,28 @@ except (json.JSONDecodeError, OSError) as e:
hooks = data.setdefault("hooks", {})
changed = False
# (0) Prune dead claude-memory plugin hooks (see module docstring). Must precede
# the additive pass so shared basenames don't mask a needed install.
DEAD_REF = "plugins/claude-memory/hooks/"
for event in list(hooks.keys()):
new_groups = []
removed_any = False
for g in (hooks.get(event) or []):
original = g.get("hooks") or []
kept = [h for h in original if DEAD_REF not in (h.get("command", "") or "")]
if len(kept) != len(original):
removed_any = True
if kept:
new_groups.append({**g, "hooks": kept})
if removed_any:
changed = True
if new_groups:
hooks[event] = new_groups
else:
del hooks[event]
# (1) Additively wire each homelab hook, if no command already references it.
for event, basename, command, extra in WANT:
groups = hooks.setdefault(event, [])
already = any(