It seems the afterAgentThought hook cuts off text at the start of some messages. I entered the prompt:
follow the steps in the rs-readme-test readme file
The chat transcript JSONL file contained the following:
{"role":"assistant","message":{"content":[{"type":"text","text":"I’ll open `rs-readme-test/README.md`, extract the exact steps, and then run them in order so we can complete the setup end-to-end.\n\n**Following project instructions**\n\nI see the user is asking me to f
ollow steps in the README. I should inspect the file and execute actions within the project. First, I need to provide a commentary update according to the instructions. I might need to read the README to identify any shell commands. Also, it's worth checking the termin
als folder before any long-running processes. Let's focus on updating the user now and then read the file!"},
However the hook only logged this:
"text":"**Following project instructions**\n\nI see the user is asking me to follow steps in the README. I should inspect the
file and execute actions within the project. First, I need to provide a commentary update according to the instructions. I might need to read the README to identify any shell commands. Also, it's worth checking the terminals folder before any long-running processes. Let's focus on updating the user now and then read the file!"
In doing so missing everything before **Following project instructions**
Steps to Reproduce
Ask Cursor to follow some instructions from a file, review the difference in the hook output vs the chat transcript.
Expected Behavior
The hook output should reflect that whole message in the chat transcript.
Hey, thanks for the detailed report. This isn’t a bug, it’s expected behavior. It just looks odd because of how the transcript is built.
Under the hood, the model outputs two separate streams:
textDelta is the visible answer like “I’ll open rs-readme-test/README.md…”
thinkingDelta is the reasoning block like “Following project instructions…”
The afterAgentThought hook is designed to return only the thinking part. The visible text comes through afterAgentResponse, so that’s the one to subscribe to if you need the full “I’ll open…” part.
The JSONL transcript intentionally merges both streams into a single {"type":"text"} block for compatibility with the Claude Code format, so in the file it looks like one continuous message. That’s why it feels like the hook is “cutting something off”. In reality, it’s just returning a different stream than what you see in the merged transcript.
If you want the full output visible plus thinking via hooks, you need to combine data from afterAgentResponse and afterAgentThought. Let me know if that use case isn’t covered. If so, that’s a feature request and we can discuss it separately.
Thanks Dean. I do have afterAgentResponse hook configured as well and I still don’t see that text. The afterAgentThought in my logs directly follows the userSubmitPrompt, so the afterAgentResponse hook didn’t fire an capture that text either, so it seems that use case isn’t covered here.
It’s weird that afterAgentResponse didn’t fire. It should fire at the end of the turn with visible text. To debug this, can you share a couple things:
The full hook event log for this turn from userSubmitPrompt to stop or sessionEnd. I want to confirm afterAgentResponse really didn’t get called, and didn’t just arrive later.
The relevant part of your hooks config (hooks.json or wherever it’s defined) so I can check afterAgentResponse is registered correctly.
Did the agent turn fully finish (did the agent stop on its own, or did you interrupt it)? Were there any queued messages in this turn?
Also, the fact that the JSONL transcript merges text + thinking into one block really does make it harder to build audit pipelines via hooks. a
Thanks, the logs helped. I checked them and here’s what I see:
afterAgentResponse did fire. It’s in your log once at the very end of the turn, with the text "Completed the README steps by running the documented module examples...". So the hook is registered and firing correctly. Check your after_agent_response.sh log, that event should be there.
But the text "I'll open rs-readme-test/README.md..." that you’re looking for is intermediate visible commentary that the agent outputs between tool calls. And that really doesn’t go to any hook right now:
afterAgentThought only returns thinking blocks.
afterAgentResponse only returns the final message of the turn, the "Completed the README steps..." one.
Intermediate visible text between tool calls ("I'll open...", "I found the README content...", etc.) is not delivered to any hook at the moment.
So your case isn’t covered. You can’t collect the full visible output of a turn via hooks right now, because the intermediate commentary is dropped. This is a real gap, I’ve logged it internally. I can’t share an ETA for a change, but if there’s an update I’ll reply in the thread.
If your audit pipeline needs the full visible turn content, right now the only source that includes this intermediate text is the JSONL transcript, even though it merges text and thinking into one block, which is awkward for auditing.