herdr/Explanation/Where Input Box Text Comes From
Properties
- logseq-entity
- Logseq/Entity/Concept
Where input box text comes from
- herdr behaviour read from the herdrdev/herdr source at 952729ee preserve logical lines in scrollback editor —
herdr 0.8.0,preview-2026-08-04-d78e3d3b5126-90-g952729ee. Claude/Code behaviour read from the installed 2.1.228 binary and the changelog it ships. Pane figures measured across 21 panes on one machine at one moment. Overview
- A Claude/Code pane that has finished a turn usually has a line of text sitting in its input box, and nobody typed it. It is a prompt suggestion: Claude Code's own prediction of what the user would type next, generated by the agent in that pane from that pane's conversation, and parked in the box until a keystroke accepts it.
- Reading such a box and taking the text for a message from the human inverts the direction of the conversation. The words came out of the agent, not into it.
- The box is a view of a live editing surface, not a record of anything received. That is the same relationship the pane has to its own history in herdr/Explanation/Copy Mode on the Alternate Screen — what is on screen is the program's current painting, and its provenance is not written on it.
Context
The answerable question is provenance, not authorship
- "Did a human type this?" cannot be answered from the screen, and not because the evidence is weak.
herdr agent promptwrites the prompt's bytes to the pane's PTY and follows them with Enter after a delay (src/app/api/agents.rs:112-116). At the terminal layer those bytes are the same event as a keystroke, and the program has no way to tell them apart. - So one agent driving another produces input that is byte-identical to typing, and any test that claims to detect human authorship is really detecting something else.
- The question that is answerable is narrower and more useful: was this text generated inside this pane, or did it arrive as input? Everything below is about that distinction.
- "Did a human type this?" cannot be answered from the screen, and not because the evidence is weak.
What is in the box, by agent state
- Measured across 21 panes at one moment, isolating the box body the way herdr does:
- Of 11 idle-or-done panes, 7 held a suggestion and 4 held nothing. All 21 panes drew a box with a marker; none was missing.
- The one working pane with content held a multi-line block carrying no faint attribute — text that had arrived as input and was queued behind the running turn.
Mechanism
The suggestion is generated by a fork of the pane's own conversation
- Read from the 2.1.228 binary: the generator forks the live conversation, appends a single instruction headed
[SUGGESTION MODE: Suggest what the user might naturally type next into Claude Code.], denies the model every tool, and writes nothing to the transcript. - The context is therefore the whole conversation as it stands, not the last assistant turn alone. Nothing outside that pane's session feeds it.
- The instruction tells the model to predict what the user would type — "not what you think they should do" — from the user's recent messages and original request, and, when the agent has just offered options, to pick the one the user would likely choose. That is why a suggestion so reliably paraphrases the agent's own closing recommendation: the likeliest next user message, after a proposal, is assent to that proposal.
- Read from the 2.1.228 binary: the generator forks the live conversation, appends a single instruction headed
When no suggestion is generated
- Suppressed before the model is called: fewer than two assistant turns so far, a last response that was an API error, a previous turn too large to be a cache hit (input, cache-creation and output tokens together over 10,000), plan mode, a pending permission prompt, an active elicitation, rate limiting, non-interactive mode, and a terminal that reports itself blurred.
- Suggestions were present on panes that were not the focused pane, so whatever focus signal reaches a pane under herdr does not read as blurred — inferred from that measurement, against a suppression path read from the binary.
The generated text is filtered before it is shown
- The generator discards its own output when it runs over 12 words or 100 characters, spans more than one sentence, is a question, carries newlines or asterisks, opens in Claude's voice (
Let me,I'll,Here's), is evaluative (looks good,thanks), or is the bare worddone. - Those filters are why a suggestion has such a narrow shape, and the shape is measurable. Across the 10 suggestions observed: 27–54 characters, 4–12 words, no questions, no formatting.
- The generator discards its own output when it runs over 12 words or 100 characters, spans more than one sentence, is a question, carries newlines or asterisks, opens in Claude's voice (
How the two kinds of text are painted
- On an idle or done pane the marker is unstyled and the suggestion follows wrapped in SGR 2 — faint. On a working pane the marker is grey and there is nothing after it. Text that arrived as input carries no SGR at all.
- text
❯ ESC[0m ESC[2m run the tests ESC[0m idle pane: a suggestion, faint ❯ ESC[38;2;153;153;153m working pane: grey marker, no content ❯ run the tests text that arrived as input: no styling - Accepting it takes a deliberate keystroke: Tab or an arrow key accepts the suggestion for editing. Claude Code 2.0.70 added Enter as accept-and-submit, and 2.1.136 fixed Enter auto-submitting on an otherwise empty input.
herdr's part is to round-trip the attribute, not to interpret it
- herdr stores
faintas one field on a cell's style alongside bold, italic, blink and underline (src/ghostty/mod.rs:375, copied at:393), and maps it to a dim modifier when rendering (src/pane/terminal.rs:2954-2956). The bit is set only because the program wroteESC[2mand the terminal parsed it (src/ghostty/bindings.rs:3335). --format ansiis documented as preserving terminal escapes "where the source exposes them" (docs/next/website/src/content/docs/cli-reference.mdx:208,docs/next/website/src/content/docs/agent-automation.mdx:82), and arrived as a preservation feature (docs/next/CHANGELOG.md:667). herdr's own guidance is to reach for it "when colors and terminal styling are evidence" (skills/herdr/SKILL.md:181).- The faint rendering is a Claude Code implementation detail observed through herdr, not a herdr feature. Anyone who reads it as a herdr contract will watch the wrong changelog.
- herdr stores
herdr locates the box, but knows nothing about the text in it
- herdr finds the box structurally: the region
prompt_box_bodyis the lines between the second-from-last horizontal rule and the next one (src/detect/manifest.rs:1424-1435), where a rule is any line opening with three or more─(src/detect/manifest.rs:1480). - The
claudedetection manifest'slive_prompt_boxrule reads that region for a line starting❯and calls the pane idle.herdr agent explain <target>prints the matched rule and the region's text. - That is the whole of herdr's knowledge: where the box is, and what characters are in it. It sees cell attributes and never provenance, so it could not expose an "is this text user-authored" field — it does not have the information. Only the program that generated the text knows it generated the text.
- herdr finds the box structurally: the region
Two signals, and which one lasts
The content envelope is the durable signal
- A suggestion is short, single-sentence, unformatted, never a question, and phrased as something the user would say. That envelope follows from why the suggestion exists and from filters applied before it is ever displayed, so it survives any change to how the box is painted.
- The strongest form of the tell is the base rate: a suggestion paraphrases its own pane's closing recommendation, because that is what the generator is asked to predict.
The faint wrapper is detectable but incidental
- Eight entries across 363 versions of the changelog Claude Code ships mention prompt suggestions — the
/configtoggle (2.0.71), the accept keys (2.0.70, 2.1.136), cache regressions (2.1.49, 2.1.50, 2.1.62), and an interaction with output styles (2.1.141). None of them mentions how a suggestion is rendered. - So the rendering is undocumented styling, not a published contract. A Claude Code release that restyles the suggestion — italic instead of faint, a colour, a different placeholder mechanism — would change it silently, with nothing erroring.
- A herdr release is not the exposure. Breaking the round-trip would mean herdr ceasing to preserve cell attributes generally, which breaks every styled read at once: loud, not silent.
- Eight entries across 363 versions of the changelog Claude Code ships mention prompt suggestions — the
Reading a box from outside
--source detectionis always plain text, so a read taken that way drops the styling and with it the signal.--source visible --format ansiis the read that keeps it.- An agent cannot run this check on itself. It is working by definition while it looks, so its own box is the working-state box — a grey marker and no content.
- Where the suggestion is wanted as data rather than as pixels, Claude Code already exposes it explicitly: in print/SDK mode,
--prompt-suggestionsemits aprompt_suggestionmessage after each turn carrying the predicted next user prompt. That is a real interface with a name. The gap is only for reading an interactive pane from outside, and closing it properly would mean asking Claude Code — not herdr — either to stop rendering generated and typed text identically but for one attribute, or to expose the distinction outright.
Turning it off
/configcarries a Prompt suggestions toggle, which writespromptSuggestionEnabledto the user-level Claude Code config; absent or true means enabled.CLAUDE_CODE_ENABLE_PROMPT_SUGGESTIONoverrides it in the environment, and--prompt-suggestionssets it per invocation.- The feature also sits behind a server-side rollout flag, so it can be absent on a build that supports it. A pane with an empty box has not necessarily got nothing to suggest.
Misconceptions
- "No styling means a human typed it." An empty box carries no styling at all — measured on 3 of 3 empty boxes on idle or done panes, where the body held the marker and nothing else. Read as "unstyled means human", an empty box classifies as human input. The test is the faint wrapper around content, never the absence of styling.
- "The box is not drawn during a turn." It is drawn in every state; all 21 panes measured had one. During a turn it is drawn empty with a grey marker, which is why a mid-turn read comes back blank whatever the pane holds — the pane is not hiding the box, it has nothing in it.
- "An empty box means the agent has nothing to say." It can equally mean the turn is still running, the previous turn was too large to reuse the cache, the pane is in plan mode or waiting on a permission prompt, or the suggestion was generated and then discarded by its own shape filters.
- "The suggestion is a summary of what the agent just said." It is a prediction of the user's next message. It resembles the agent's last proposal because assent to that proposal is the likeliest next thing the user would type, not because it is derived from the reply.
- "This is a herdr signal." herdr forwards a cell attribute that Claude Code chose to set. Both halves of the mechanism live in Claude Code: what to suggest, and how to paint it.
- herdr behaviour read from the herdrdev/herdr source at 952729ee preserve logical lines in scrollback editor —