Windows sends keystrokes to whichever window has the keyboard, and a terminal tab can't be picked from outside. Here is how Nook proves it has the right Claude Code tab before it types a reply, and when it refuses.
Nook lets you reply to a finished Claude Code session from a box in an island at the top of the screen. To deliver the reply it has to type it into the terminal where the session runs, and Windows will send keystrokes to whichever window has the keyboard. If that turns out to be a PowerShell tab, your reply runs as a command.
The version that didn't fit
The first version typed nothing. It started claude -p --resume <id> in the background, in the session's folder, with the reply on its standard input. No window touched, so nothing to get wrong.
It worked, and it was the wrong shape. The conversation carried on in a process nobody could see, and the terminal where you'd started the session showed nothing of it. So Nook now types the reply into that terminal, and the hard part is which one.
You can find the window but not the tab
Nook knows where a session runs. The relay that Claude Code starts reports the chain of processes above it, and that leads to a window. A Windows Terminal window holds many tabs, though, and nothing outside it can pick one. All the window tells you is its title, which is the title of the active tab.
Claude Code writes a title there: a status glyph, then the conversation's name. That's the proof. A window passes only if its title starts with a character that isn't ASCII, a letter or a digit, followed by this conversation's title. Either side may arrive cut short.
let first = window_title.trim_start()
.chars().next();
let marked = first.is_some_and(|c| {
!c.is_ascii() && !c.is_alphanumeric()
});
let (window, title) = (
title_core(window_title),
title_core(title),
);
if !marked
|| title.chars().count() < MIN_TITLE_CHARS
{
return false;
}
window.starts_with(&title)
|| (window.chars().count() >= MIN_PREFIX_CHARS
&& title.starts_with(&window))The glyph does the real work. A shell's own tab starts with a letter or a path, so Windows PowerShell fails. The tests pin the cases: ◐ Nook folders in personal repos passes, the same title without the glyph fails, and ◐ About Nook folders in personal repos fails too, because the conversation's title has to be where the window's begins.
Every check can say no
Before any key goes out, Nook runs seven checks in order. The first five refuse without typing anything.
Windows drops input aimed at a window that runs with more rights, so an administrator terminal can't be typed into. Nook says that instead of pretending it worked. Bringing a window forward takes time, and the tab can change while it does, so the title is proved a second time once the window is in front. Then Nook waits up to 700 ms for your own keys to be let go, so a held Shift or Enter doesn't land in the middle of the reply.
Typing is 32 keys at a time with a 12 ms pause, and before each chunk Nook asks whether the window is still in front. Click away halfway and it stops, doesn't press Enter, and tells you the text is partly there. Enter goes only after the last chunk, and only if the window is still in front.
Five checks refuse without typing a key. Once typing starts, losing focus stops it and Enter is never pressed.
Small things that bit
A new line in Claude Code is a backslash and then Enter, because Enter alone sends. So \n becomes those two keys, and a tab becomes four spaces. Codex doesn't read a backslash that way, so for Codex sessions newlines turn into spaces. Control characters such as Escape are refused outright, since a terminal would act on them.
Keys go in as Unicode input, a pair of units for anything that needs two, and the clipboard is never touched. The function returns an error only when nothing has been typed. After the first key it returns success, even for "interrupted", so a caller can trust that an error always means nothing happened.
Editors get a different route. The Claude Code extension in VS Code and Cursor can open a session by link with its prompt filled in, so Nook builds that link, percent-encodes the text, brings the editor forward and opens it. The reply waits in the prompt box for you to press Enter.
What it costs
Nook can't switch tabs for you. If another tab is showing, nothing is sent, and what you typed stays in the box with the reason. An elevated terminal gets the same answer. The reply box only appears while Nook can find the session's window, and it looks again every few seconds. A feature that sometimes says no is less pleasant than one that always types. When the wrong answer runs a command, I'll take the one that says no.
The takeaway is about any program that sends input to another one: prove what the window is, not just where it is, and prove it again after anything that waits. Windows calls like these have their own traps; the one that caught me in Go was a call reading a buffer the garbage collector had already freed. If you need tooling that sits beside a team's workflow without ever breaking it, that's the kind of automation work I take on.