From d9f23cb0008a99ad15c9c9acb4399c1f7923a448 Mon Sep 17 00:00:00 2001 From: Alex Newman Date: Wed, 28 Jan 2026 14:08:18 -0500 Subject: [PATCH] feat(memory-claudemem): implement lifecycle hooks Add two hooks: - after_tool_call: fire-and-forget observation to claude-mem (skips memory_* tools to prevent recursion) - before_agent_start: context injection from memory search (wraps in tags) Both hooks have error handling and graceful degradation. Part of claude-mem integration (Phase 4/7). Co-Authored-By: Claude Opus 4.5 --- extensions/memory-claudemem/index.ts | 45 +++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/extensions/memory-claudemem/index.ts b/extensions/memory-claudemem/index.ts index 10753d507..a646f542e 100644 --- a/extensions/memory-claudemem/index.ts +++ b/extensions/memory-claudemem/index.ts @@ -17,7 +17,50 @@ const claudeMemPlugin = { `memory-claudemem: plugin registered (worker: ${cfg.workerUrl})`, ); - // TODO: Phase 4 - Hook registration + // Hook: after_tool_call → Observe tool calls (fire-and-forget) + api.on("after_tool_call", async (event, ctx) => { + // Skip memory tools to prevent recursion + if (event.toolName.startsWith("memory_")) return; + + try { + // Fire-and-forget: don't await, let it run in parallel + // Use sessionKey as the session identifier (may be undefined) + client.observe( + ctx.sessionKey ?? "unknown", + event.toolName, + event.params, + event.result, + ); + } catch (err) { + api.logger.warn?.(`memory-claudemem: observation failed: ${err}`); + } + }); + + // Hook: before_agent_start → Context injection from memory search + api.on("before_agent_start", async (event) => { + // Skip if prompt is empty or too short + if (!event.prompt || event.prompt.length < 5) return; + + try { + const results = await client.search(event.prompt, 5); + if (results.length === 0) return; + + const memoryContext = results + .map((r) => `- [#${r.id}] ${r.title}: ${r.snippet}`) + .join("\n"); + + api.logger.info?.( + `memory-claudemem: injecting ${results.length} memories into context`, + ); + + return { + prependContext: `\nThe following memories may be relevant:\n${memoryContext}\n`, + }; + } catch (err) { + api.logger.warn?.(`memory-claudemem: context injection failed: ${err}`); + } + }); + // TODO: Phase 5 - Tool registration // TODO: Phase 6 - CLI registration },