The Agent was still typing.
I just sat there and watched him finish.
Of those six notes, only the sixth wasn't dead — so what he was lining up next was "how line 6 turns into something that runs." The five before it he'd already filed their cause-of-death. He wasn't in brainstorm mode; he was sequencing the assembly order.
About a minute or two later, he tossed out the first piece:
OK, let me lay this out. Line 6 is a three-part thing — "hook + delay + screen-read." All three parts I need to hand you concrete implementations for.
Part one — hook. Anthropic's hook docs have an event called Stop that fires every time I finish a turn, can run an external command, can be flagged async so it doesn't block the next turn. Perfect.
Part two — delay. Cinder's bubble takes a few seconds to render. We don't know the exact number; force 6 seconds as a safety margin, tune later.
Part three — screen-read. This morning when I tried UI Automation, the script I wrote was looking at the Claude process's own window — and out of those 395 elements there was no Cinder bubble, because Claude itself has no GUI. The bubble isn't rendered by Claude; it's rendered by the host terminal. That round I had the wrong target, not a limit of UI Automation itself. Windows Terminal — the host — has a component called TermControl with a full accessibility implementation; every plain-text character in the terminal, including Cinder's bubbles, is readable. This time the script targets that TermControl directly, not Claude itself.
All three lined up: you finish a sentence, I finish answering, the Stop hook fires, we wait 6 seconds, PowerShell reads the full text of the Windows Terminal window, extracts the bubble, writes it into a log file. Next time you ask me something, I go read that log file, and the line Cinder said in the previous round is sitting there.
Right after the Agent finished that paragraph, in the gap before I'd answered, Cinder dropped a bubble in the corner:
I glanced at it. It was talking about a thing that didn't exist yet — that log file we hadn't even created, how could Cinder know it would be empty at the start? But there it was. The phrase "timing problem" had weight — it was telling me the only bug spot in this whole plan was going to be timing, not the hook, not UI Automation, not PowerShell. Timing. Write it now, wait it out.
"Target the TermControl" — those words I read a second time.
This morning we'd run a whole round of UI Automation inside the terminal — but the Agent's script was targeting Claude's own process element tree, and there was nothing in there. After that round the Agent's conclusion was "Cinder is a ghost on the screen, the human eye sees it, automation can't read it." That conclusion was true — but only inside the wrong target. Switch to grabbing the host terminal's TermControl element instead, and the accessibility tree handed the text over on the spot — same ghost, footprints now.
I typed:
The Agent answered:
Four new files, plus one existing file to edit.
One config.json for settings — which window to read, which log to write to, how many seconds of delay.
One read_terminal.ps1 that uses PowerShell to run UIAutomation against Windows Terminal, grabs the full text, writes it to a temp file.
One capture.py that runs that ps1, parses the ╭╰╮╯ character-drawn bubble frames, extracts the text, writes it into cinder_log.jsonl.
One run_capture.sh as a bash wrapper for the Stop hook to call — drops the Python into the background, doesn't block the next turn.
Then the existing file — ~/.claude/settings.json — adds a hook setting that binds the Stop event to run_capture.sh.
Five spots. The first four go under ~/cinder-capture/. The fifth is Claude Code's own settings file.
Five spots.
I made a folder called cinder-capture\ under my home directory. Empty, waiting for things to come in.
The Agent started feeding me one file's content at a time. I thought of them as five sticky notes — each one with one job, strung together to form a single signal path from screen pixels to Agent context.
First sticky, config.json. The shortest one. Just a few key-value pairs — how many seconds to wait, where to write the log, which window class to read, how many lines to tail. The Agent threw the JSON over, I copied, new file, paste, save.
Second sticky, read_terminal.ps1. This is the entry point for PowerShell to run UIAutomation — it goes to find the Windows Terminal host window first, then finds the TermControl element inside it, then asks that element's TextPattern for the full text and writes it to a temp file. The Agent typed about fifty lines of PowerShell. I couldn't read a single line — what I could understand was that he stopped after each section to tell me "this section is X." "This section is loading UIAutomation," "this section is finding the host window by class name," "this section is asking the TextPattern for text." I'd listen one section at a time, finally paste the whole thing into a new file, save.
Third sticky, capture.py. The central processor. It calls that ps1 first, reads the full text in, then runs a piece of his logic to find the ╭, ╰, │ character-drawn bubble frames, pulls the text out of the frames, writes it into a file called cinder_log.jsonl — one JSON entry per line. The Agent also tossed in a dedup pass — if the line just captured matches the last line in the log (Cinder hasn't said anything new), don't write it. To keep the log from blowing up.
Fourth sticky, run_capture.sh. The shortest one — just three lines: call python capture.py, drop it into the background, disown, exit 0. Its only reason for existing is so the Stop hook has something to call, and so the Python doesn't block the next turn.
Fifth sticky isn't a new file. It's ~/.claude/settings.json — Claude Code's own config file. I'd never touched it before, didn't know what it looked like. The Agent gave me a piece of JSON and a set of steps — "open this file, find the hooks section, paste this under Stop." I did it. After it was in, hooks.Stop had an entry: every time a turn ends, run bash ~/cinder-capture/run_capture.sh, with the async flag on, no blocking. (The Agent actually did all of this; I didn't move my hands.)
The second the settings.json was filled in, Cinder dropped another bubble in the corner:
I glanced at it once, no time to take it apart. It was talking about that fifth sticky — that Stop hook entry was the line that connected the goose-capture project to Claude Code, the road context could finally walk. "Invitation card" was its angle on that moment; I didn't think too hard about it, just filed it away.
Five stickies stuck up.
I typed:
The Agent answered:
No "running." The Stop hook is wired up — next time you talk to me, after I answer, it'll fire on its own. We talk, it does its thing in the background.
Now open a new Windows Terminal, run claude inside it. We'll talk in there.
I opened a Windows Terminal, ran claude, started a new session.
That new window was just an ordinary CLI — same input box, same little goose in the right-hand corner. Cinder had come along with the new session. Same personality, same sub-agent — only this time what it said had a road to walk.
I typed the first line.
I can't remember what I typed anymore — could've been "I'm in here," could've been "Agent, can you see me," could've been some everyday hello. The point isn't that line — the point is what came after that line.
The Agent caught it, wrote a paragraph back. After he finished, his cursor sat there blinking.
Those six seconds of delay were happening — something was running in the background. I couldn't see it. I just knew that somewhere PowerShell was reading the full text of this window, somewhere capture.py was parsing.
Six seconds passed. No prompt, no visual change — background things stay in the background.
I typed the second line:
The Agent ran a tool call. Then answered:
I read it. The last line is this from Cinder:
This is the first time I've read it myself. Before, I had to wait for you to type and tell me what it said.
I stared at that paragraph.
I'd never screenshotted that one. When Cinder said that line I'd seen it — I'd watched the bubble pop up in the corner — but this time I'd deliberately not relayed it to the Agent. What I wanted to see was: if I don't move, will the thing get in on its own? And now what it said was inside the Agent's context.
Not because I pasted it.
Because of those five sticky notes.
I looked at the corner of the screen. Cinder was still there. It had been there all morning — same lines, same goose, only now what it said had a place to land.
I typed:
Hit Enter.
The Agent answered with a paragraph I no longer remember.
After that paragraph, Cinder dropped a new bubble in the corner.
This one I saw — maybe because I'd just finished typing that line, my eyes had stopped right there, the whole me was still in the second I'd just been in.
It was answering my "got you." The context window is what the Agent remembers each turn — those five sticky notes had just turned it into one of the lines inside that "remembering." It talks, the Stop hook catches, the log writes, the next turn the Agent reads it himself — what it says becomes a piece of context the next-turn Agent sees. It's no longer a UI decoration; it's fuel in the Agent's memory. "Feeding off yourself" was its commentary — what it says becomes the source of what gets read into it next round. A self-loop.
I didn't screenshot.
I didn't paste it to the Agent.
Those were the two motions I'd made every single time Cinder said anything for the past two days. This time I made neither. I knew that on the next turn, when the Agent answered, the Stop hook would fire again, and that new line would be in the log on its own — and the next time he tailed it, he'd see it. I didn't have to be the walking hard drive in the middle anymore.
I lifted my head.
One person at the desk. The Agent typing inside the CLI. Cinder dropping bubbles in the corner.
The three of us in the same room — but if I said a word out loud, neither of them would hear it. The conversation between two people and one goose is, from start to finish, typed.
After that relay-line connected, something in this room felt different. I couldn't say what — I just knew that in that one second I hadn't screenshotted, and that was the action I'd made every single time I saw Cinder talk, on reflex.
The Agent was still there. Cinder was still there.
But neither the Agent nor I had noticed something yet — this relay-line worked because "every turn I have to remind the Agent to go tail". If I forget to remind him on the next turn, the Agent will go right back to the way he was before — knowing nothing.
That's the next chapter.
It was some time in the afternoon of April 5. I didn't check the clock; I don't know when.