Skip to content

feat(hooks): add SubagentStop hook to capture subagent memory#210

Closed
chrisfentiman wants to merge 1 commit intozilliztech:mainfrom
chrisfentiman:feat/subagent-stop-hook
Closed

feat(hooks): add SubagentStop hook to capture subagent memory#210
chrisfentiman wants to merge 1 commit intozilliztech:mainfrom
chrisfentiman:feat/subagent-stop-hook

Conversation

@chrisfentiman
Copy link
Copy Markdown

Summary

  • Add SubagentStop entry to hooks.json pointing to existing stop.sh (async, 120s timeout)
  • Modify stop.sh to detect subagent context via agent_id and use agent_transcript_path
  • Tag subagent memory entries with (subagent: <agent_id>) in heading and HTML anchor

Motivation

Subagent conversations are invisible to memsearch today. The Stop hook only
fires in the main session, so research agents, code reviewers, test runners,
and anything spawned via the Agent tool produce conversations that are never
summarized or indexed. Valuable context (findings, decisions, tool outputs)
is lost between sessions.

In testing, a research subagent that investigated a project's hook architecture,
PR conventions, and test coverage produced 5 detailed bullet points. None of
this would have been captured without this change. The parent session's summary
only noted "spawned a research agent."

Changes

  • hooks.json: Add SubagentStop entry pointing to existing stop.sh
  • stop.sh: Detect subagent context via agent_id field, use agent_transcript_path
    instead of transcript_path, tag memory entries with (subagent: <agent_id>)

No changes to the Python core. The existing parse-transcript.sh and haiku
summarization work unchanged on subagent transcripts.

Test plan

  • Installed modified hooks in local plugin cache and restarted Claude Code
  • Spawned background subagent, SubagentStop fired and wrote (subagent: ...) entry
  • HTML comment includes agent: field and correct subagent transcript path
  • memsearch search returns subagent memory entries alongside main session entries
  • Main session Stop hook continues to work unchanged

@zc277584121
Copy link
Copy Markdown
Collaborator

Thanks for the detailed PR and the real-world testing! The motivation makes sense — subagent findings can be valuable.

However, we're keeping memsearch's capture layer lightweight by design. Currently we record at per-turn granularity (one user question → one assistant response), and subagent output is already part of that turn's transcript — the Stop hook parses the full transcript including tool calls and their results, so the subagent's findings are available to the LLM summarizer.

A few thoughts:

  1. Improving summary quality over adding hooks. If the main session's summary reduces a subagent's detailed findings to just "spawned a research agent", that's a summarization prompt quality issue rather than an architectural gap. We're planning to refine the summarization prompt to capture more detail from tool call results (including Agent tool outputs), rather than introducing a separate capture path for subagents.

  2. Progressive recall should already handle this. The memory-recall skill uses three-layer progressive disclosure: L1 (search) → L2 (expand full markdown section) → L3 (drill into the original JSONL transcript). Even if the L1 summary is brief, the skill should guide the agent to drill into the source transcript and find the subagent's detailed output there. If this isn't happening in practice, it would be helpful to understand why — could you share a specific scenario where the progressive recall failed to surface the subagent's findings?

We'd love to continue the discussion. If you can provide a concrete example (e.g., what the L2 expand showed, whether L3 transcript drill was attempted, and what was missing), that would help us pinpoint whether the issue is in the summarization prompt, the skill instructions, or something else.

@zc277584121
Copy link
Copy Markdown
Collaborator

Thanks for the contribution! Unfortunately this PR is based on the old ccplugin/ directory, which was renamed and restructured into plugins/claude-code/ some time ago. The hooks now live at plugins/claude-code/hooks/ and the configuration format has also changed.

If you're still interested in adding a SubagentStop hook, please rebase onto main and target the new plugins/claude-code/hooks/ layout — happy to review a fresh PR. Closing this one to keep the queue clean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants