Release 0.2.2 - #16
Merged
Merged
Conversation
Claude Code injects multiple `<system-reminder>` blocks (skills list, CLAUDE.md context, plan-mode markers, …) ahead of the user's actual prompt. Expanding a user message used to dump all of that as wall-of- text, burying "hello claude" under 30+ lines of framework boilerplate — exactly the problem this inspector is supposed to fix. Now each user text block is split on `<system-reminder>` boundaries into: * reminder chunks → collapsed chips (icon · first-line preview · char count), one click to expand the full body * prose remainder → rendered as a normal TEXT block Result: "hello claude" jumps to a one-line TEXT block; the reminders sit one click away as muted chrome. Injection order is preserved so the rendered view is still a faithful representation of what the model actually saw on the wire. Implementation notes: * `splitReminders` is a UI-only transform — produces a local `DisplayBlock` union (`ContentBlock | SystemReminderBlock`) that never touches the wire schema or persisted records. * Applied only on `role === 'user'` messages. Assistant text doesn't carry these wrappers and we don't want to false-positive on user prose that happens to mention the literal string. * `cache_control` on the source text block is intentionally dropped on the prose remainder — it applied to the whole text-with- reminders payload Anthropic saw, not to our prose subset; showing it on just one half would be misleading. The raw-JSON dialog still carries the original. * The existing `oneLineMessageSummary` / `findUserPromptIndex` / `stripSystemReminder` helpers are unchanged — they already do their own stripping and operate on the on-wire blocks, so the inline summary still shows the clean prompt as before. No server-side changes. `pnpm typecheck` is clean.
imsobear
added a commit
that referenced
this pull request
May 17, 2026
Four follow-ups to the 0.2.3 phase 1/2 work, all driven by:
"too much detail leaking out of collapsed headers, too many new
badges per iter, instructions stuck unfoldable, nested system-prompt
wrapper inside system".
1. Strip per-content previews from PROMPT / SKILLS / MEMORY / SYSTEM
section headers — just a count ("skills · 56", "memory · 16",
"system · 10"). The chips inside still reveal everything when
expanded; the headers stop competing with the trace.
2. Codex input[] items now group into TURNS. Each turn = one
model-action cycle (reasoning + assistant text + function_call(s)
+ their tool_call_outputs), rendered as one Section with an
abstract title ("tool_use × N" / "response × N" / "user × N")
and one badge. Iter cards with 4–6 new entries collapse to one
new badge per cycle. Boundaries: reasoning starts a new turn;
function_call after function_call_output starts a new turn;
user message always its own turn.
3. Claude messages[] grouped the same way: an assistant tool_use
message glues with the following user tool_reply (tool_result
block, even when Claude pairs it with auto-injected text like
"Tool loaded." from ToolSearch). One turn = one cycle.
4. System section now flat: instead of a nested "system prompt"
card wrapping the API system field, every system blob is run
through splitSystemPromptByH1 — each markdown H1 section becomes
its own foldable FrameworkBlockChip with the heading as label
("doing tasks", "environment", "frontend guidance", "identity",
…). Codex req.instructions and Claude req.system both flow
through the same idiom, sitting side-by-side with the existing
chrome chips. Cache_control gets dropped at this layer — power
users can find it in raw JSON.
Side-fix: findUserPromptIndex (Claude) now skips messages with
tool_result blocks. Without this, iter ≥2 picked up "Tool loaded."
(the ToolSearch tool_result + paired prose) as the user prompt and
PromptSection surfaced "Tool loaded." instead of the original
"fetch google.com…".
Verified: typecheck, pnpm smoke (all 11 checks), visual inspection
of Codex msg #6 (3 iter) and Claude msg #16 (5 iter, ToolSearch +
WebFetch + Write + Bash chain). One new badge per iter on both
agents; PROMPT renders the right text; system section expands to
13 chips on Claude, 10 on Codex with no nested wrapper.
imsobear
added a commit
that referenced
this pull request
May 17, 2026
Two follow-ups on the turn-coalescing pass:
1. PROMPT was top-of-panel and expanded on every iter. On iter ≥ 2
the prompt is inherited context the user already saw on iter 1 —
pinning it above the trace pushed the new TOOL_USE turn (the
actually-actionable content) below the fold. Now: on iter 1 the
prompt renders at the top and starts open; on iter 2+ it slides
down into the inherited-context cluster (alongside skills /
memory / tools / system) and starts collapsed. Still one click
away when you want to re-read what was asked.
2. The turn section titles carried a ×N count ("tool_use × 4",
"response × 2") that read more like a tally of tool invocations
than what it actually was — the count of *items inside the
collapsed body* (reasoning, assistant text, function_call,
function_call_output). Misleading enough to remove. Titles
collapse to just "tool_use" / "response" / "user" and the
internal item breakdown is one expand away.
Side cleanup: drop the now-unused `accent` field from TURN_META /
MSG_TURN_META — was only powering the dropped count's tinted text.
Verified on Codex msg #6 (3 iter) and Claude msg #16 (5 iter):
iter 1 opens with PROMPT expanded at the top, every subsequent
iter opens with the new TOOL_USE turn at the top + PROMPT
collapsed below. Smoke + typecheck green.
imsobear
added a commit
that referenced
this pull request
May 17, 2026
* feat(ui): classify framework-injected chrome into named kinds (v0.2.3)
Both REQUEST panels used to render Claude `<system-reminder>` blocks
as one generic "system-reminder" chip and showed Codex framework
chunks as plain TEXT blocks. The user can't tell at a glance whether
chrome is CLAUDE.md memory, the skills catalogue, environment
context, or something else.
This version adds a shared classifier (`src/lib/framework-blocks.ts`)
that recognises a finite set of kinds — skills, memory, agents-md,
tools, date, environment, permissions, apps, plugins, collaboration,
custom-instructions — using leading XML-ish tags and known opening
sentences. A new presentational chip (`FrameworkBlockChip`) renders
each with a kind-specific icon, label, and concise preview ("12
skills", "cwd: ~/foo · zsh", "AGENTS.md · ~/repo", "Today:
2026-05-15", …). Unrecognised reminders fall through to a generic
`system-reminder` chip so nothing ever renders as raw chrome text.
Wired into:
- `RequestPanel.tsx` — `splitReminders` now classifies each reminder
body before emitting a chip; the inline `SystemReminderChip` is
gone.
- `ResponsesRequestPanel.tsx` — each `input_text` content block is
classified; framework blocks render as chips, prose renders as a
normal TEXT block. `summariseItem` and `findUserPromptIndex` skip
framework chrome so the inline preview and the `prompt` highlight
land on actual human-typed content.
Verified the rule table against `~/.agentmind/projects/*.jsonl`:
100% of observed framework blocks classify cleanly across both
agents (Claude: 4 distinct kinds, Codex: 9 distinct kinds), with
zero false-positive prose classifications.
* feat(ui): promote skills + memory to top-level Sections
The v0.2.3 classifier already labelled `skills` and `memory` chunks
distinctly, but they still sat as plain chips inside the user
message — the same as `permissions`, `apps`, `plugins`, and so on.
Skills and memory carry actual user data (installed skill catalogue,
CLAUDE.md / cross-session memory summary) and deserve more weight
than platform protocol chrome.
This promotes both to their own top-level Sections, rendered at the
same hierarchy as `tools` and `instructions` in both REQUEST panels.
The first occurrence wins (both agents re-inject identical content
on every iter), and the in-message chips for these kinds are
suppressed to remove the duplicate-across-N-iters noise.
- `framework-blocks.ts`: adds `PROMOTED_KINDS` set, `parseSkillsBullets`
(splits `- name: description` rows from the catalog, handles
Codex's `(file: rN/…)` locator suffix and multi-line descriptions),
and `memoryHeadings` (extracts markdown headings for a TOC
preview, filtering boilerplate framing labels).
- `FrameworkSections.tsx`: new file with `SkillsSection` (one
collapsible row per skill, max-h-96 cap so 60-skill catalogs don't
blow up the layout, raw-body escape hatch) and `MemorySection`
(markdown body with up-to-3-heading TOC in the header summary).
- `RequestPanel.tsx` / `ResponsesRequestPanel.tsx`: extract promoted
blocks via `findPromotedBlocks`, render the sections below the
message list, and skip the matching chips inside the message body.
Codex `summariseItem` also drops promoted kinds from the inline
preview so the developer-item summary matches what's actually
visible.
Verified against real `~/.agentmind/projects/*.jsonl` data:
- Claude (3e3b5b…): 10 skills, 2 memory TOC headings
- Codex (5df6e3…): 60 skills, 16 memory TOC headings spanning user
profile / preferences / per-cwd memory entries — all parsed cleanly.
* refactor(ui): align Skills/Memory section headers with prompt display
The promoted Skills and Memory sections used a `ToolsSection`-style
header (kind label as the title) that looked different from the
neighbouring message sections (`input#user` title + role-coloured
hash). Now they share one header idiom: `input#<role>` on the left
naming the source field, a kind-specific icon, an inline preview,
and a `muted` Badge on the right pinning the kind label — same slots
in the same order as the existing `prompt` / `new` badges.
Mechanics:
- `FrameworkSections.tsx`: introduces `PromotedRole` type plus two
shared header helpers (`InputRoleTitle`, `SectionSummary`).
Title carries the role accent colour (user vs llm); summary slot
uses `Badge variant="muted"` so the kind label reads as metadata,
not an action (`prompt` / `new` stay on `success` green).
- `RequestPanel.tsx` / `ResponsesRequestPanel.tsx`: `findPromotedBlocks`
now returns `{ body, role }` so the source role can flow through
to the section header. Claude always yields `'user'`; Codex
forwards whatever role the source input item carried (typically
`'developer'` for the system-style item).
The skills preview also got richer: shows `${count} · skill1 ·
skill2 · skill3` so the collapsed header carries actual catalogue
samples instead of just a count.
* refactor(ui): promote prompt to first-class section, unify with skills/memory
Reverts the previous `input#<role>` title experiment for skills/memory
and instead unifies prompt + skills + memory under one visual idiom:
- Kind name as the title (`prompt`, `skills`, `memory`) — the loud,
scannable label the user reaches for.
- Inline preview in the summary slot (prose excerpt for prompt,
count+names for skills, count+TOC for memory).
- Small dimmed source-field icon at the very right of the header
marking which wire field the content came from (User for
`input#user`, Settings2 for `input#developer` / `input#system`, Bot
for `input#assistant`). Reads as a metadata footnote, not an
action — keeps the loud `prompt`/`new` action badges in their own
visual lane.
Mechanics:
- `FrameworkSections.tsx`: adds `PromptSection` (peach-tinted body
matching the existing user-prompt highlight, defaults to open),
reverts Skills/Memory headers to kind-first, and introduces a
shared `SourceFieldIcon` helper.
- `RequestPanel.tsx` (Claude): `findPromotedBlocks` now also
extracts the prompt prose from the user-prompt message; the same
message stays in the messages list with a new `promotedPrompt`
prop that filters prose text blocks out of the rendered body. If
nothing remains after dropping prose (the common case), the
section bails to null — orphan chrome chips (date / deferred-
tools) that happened to share the user-prompt message stay
visible.
- `ResponsesRequestPanel.tsx` (Codex): same prompt extraction; the
user-prompt input item is filtered from the items list since
Codex puts the prompt in its own item with prose-only content.
Layout order for both panels is now:
PROMPT → messages/items → SKILLS → MEMORY →
(instructions / system) → TOOLS
— PROMPT anchors the eye at the top, the trace follows newest-
first, resources and chrome land at the bottom. This matches the
"Prompt / SKILLS / Memory / TOOLS / System" mental model the user
sketched in feedback.
* refactor(ui): fold framework chrome into one System parent, move provenance into body
Two related UX wins on top of the v0.2.3 prompt/skills/memory promotion.
System parent
- Bundle everything that's not PROMPT/TOOLS/SKILLS/MEMORY into a single
foldable "system" section at the bottom of the request panel:
- Claude req.system blocks (kept with cache_control awareness via
ClaudeSystemPromptBlocks)
- Codex req.instructions (rendered via CodexInstructionsBlock)
- Every system-reminder / framework input_text classified as
permissions / apps / plugins / collaboration / environment /
agents-md / date / deferred-tools / instructions / ...
- Dedup chrome by exact body so a 60-iter conversation re-injecting
the same date or permissions reminder produces ONE chip, not 60.
- Drop the in-message chrome chip rendering: splitReminders now emits
prose-only; Codex MessageBody skips non-prose blocks; the items
list filter drops message items whose body would be empty after
suppression (developer chrome stack, AGENTS.md+env user item). Net
effect: the trace between PROMPT and SKILLS reads as pure agent
action history (assistant text, reasoning, tool calls, tool
results).
Source provenance
- Drop the right-edge SourceFieldIcon from section headers -- it was
too dim to find, too noisy to ignore.
- Add a SourceCaption rendered at the top of expanded bodies:
arrow + role icon + "input#<role>", dimmed and small. Section
headers stay minimal (kind + preview); provenance appears only
when the user opens the section, which is when they'd actually
care.
Layout for both panels is now:
PROMPT -> agent trace -> SKILLS -> MEMORY -> TOOLS -> SYSTEM
New 'system-prompt' kind added to FrameworkKind union for future
classifier reuse; not currently emitted by classifyFrameworkBlock
(the API-level system prompt is plumbed as a pre-rendered ReactNode).
* feat(ui): smarter rendering for Codex function calls and shell tool outputs
Phase 2 of the v0.2.3 polish — making the function-call traffic easy
to scan at a glance instead of forcing the eye through a JSON dump.
New helpers (src/lib/tool-call.ts)
- parseToolArgs: best-effort JSON parse of function_call.arguments,
with graceful raw-string fallback for mid-stream deltas.
- tryShellArgs: detects the shell-tool shape ({cmd, workdir,
yield_time_ms, max_output_tokens}) so we can surface the command
line as the focus instead of burying it in a JSON blob.
- parseShellEnvelope: pulls Codex's 4-line tool-output wrapper
("Chunk ID / Wall time / Process exited / Original token count /
Output:") apart so the renderer can hoist exit + duration as
badges and treat the trailing stdout as the focus.
- formatDurationSec: sub-second -> ms, otherwise s / m s.
Codex REQUEST panel (ResponsesRequestPanel.tsx)
- function_call items now render via FunctionCallCard with a
pretty-printed args view. Shell-shaped calls show as
$ <cmd>
cwd: ... yield: ... max_out: ...
Non-shell args fall through to pretty JSON. Previously: raw
JSON.stringify dump.
- function_call_output items now render the parsed envelope: exit
code chip (green for 0, red otherwise), duration chip, token-
count chip, then the actual stdout as the body. The full envelope
stays one click away via a "show envelope" toggle.
- custom_tool_call gets its own card matching the response-side
rendering.
- Inline summaries (the iter header preview) parse the same data,
so an iter card now reads
input#function_call · "$ wc -c google.html"
input#function_call_output · "exit 0 · 80562 google.html"
rather than dumping the JSON or the envelope header.
Codex RESPONSE panel (ResponsesResponsePanel.tsx)
- ArgumentsPre now uses the same parseToolArgs + tryShellArgs path,
so the model's outgoing shell call reads identically to its
replay on the next iter's input transcript. Symmetric idiom on
both sides of the wire.
Types (openai-responses-types.ts)
- Extend ResponsesInputItem with function_call / custom_tool_call /
reasoning. Codex CLI rebuilds the full transcript on every turn,
so these assistant-emitted shapes ALSO appear verbatim in
subsequent input[] arrays — the prior narrower union was missing
them and forced an unsafe JSON.stringify fallback in the panel.
* refactor(ui): coalesce items into turns + abstract section headers
Four follow-ups to the 0.2.3 phase 1/2 work, all driven by:
"too much detail leaking out of collapsed headers, too many new
badges per iter, instructions stuck unfoldable, nested system-prompt
wrapper inside system".
1. Strip per-content previews from PROMPT / SKILLS / MEMORY / SYSTEM
section headers — just a count ("skills · 56", "memory · 16",
"system · 10"). The chips inside still reveal everything when
expanded; the headers stop competing with the trace.
2. Codex input[] items now group into TURNS. Each turn = one
model-action cycle (reasoning + assistant text + function_call(s)
+ their tool_call_outputs), rendered as one Section with an
abstract title ("tool_use × N" / "response × N" / "user × N")
and one badge. Iter cards with 4–6 new entries collapse to one
new badge per cycle. Boundaries: reasoning starts a new turn;
function_call after function_call_output starts a new turn;
user message always its own turn.
3. Claude messages[] grouped the same way: an assistant tool_use
message glues with the following user tool_reply (tool_result
block, even when Claude pairs it with auto-injected text like
"Tool loaded." from ToolSearch). One turn = one cycle.
4. System section now flat: instead of a nested "system prompt"
card wrapping the API system field, every system blob is run
through splitSystemPromptByH1 — each markdown H1 section becomes
its own foldable FrameworkBlockChip with the heading as label
("doing tasks", "environment", "frontend guidance", "identity",
…). Codex req.instructions and Claude req.system both flow
through the same idiom, sitting side-by-side with the existing
chrome chips. Cache_control gets dropped at this layer — power
users can find it in raw JSON.
Side-fix: findUserPromptIndex (Claude) now skips messages with
tool_result blocks. Without this, iter ≥2 picked up "Tool loaded."
(the ToolSearch tool_result + paired prose) as the user prompt and
PromptSection surfaced "Tool loaded." instead of the original
"fetch google.com…".
Verified: typecheck, pnpm smoke (all 11 checks), visual inspection
of Codex msg #6 (3 iter) and Claude msg #16 (5 iter, ToolSearch +
WebFetch + Write + Bash chain). One new badge per iter on both
agents; PROMPT renders the right text; system section expands to
13 chips on Claude, 10 on Codex with no nested wrapper.
* refactor(ui): demote inherited prompt + drop misleading turn ×N counts
Two follow-ups on the turn-coalescing pass:
1. PROMPT was top-of-panel and expanded on every iter. On iter ≥ 2
the prompt is inherited context the user already saw on iter 1 —
pinning it above the trace pushed the new TOOL_USE turn (the
actually-actionable content) below the fold. Now: on iter 1 the
prompt renders at the top and starts open; on iter 2+ it slides
down into the inherited-context cluster (alongside skills /
memory / tools / system) and starts collapsed. Still one click
away when you want to re-read what was asked.
2. The turn section titles carried a ×N count ("tool_use × 4",
"response × 2") that read more like a tally of tool invocations
than what it actually was — the count of *items inside the
collapsed body* (reasoning, assistant text, function_call,
function_call_output). Misleading enough to remove. Titles
collapse to just "tool_use" / "response" / "user" and the
internal item breakdown is one expand away.
Side cleanup: drop the now-unused `accent` field from TURN_META /
MSG_TURN_META — was only powering the dropped count's tinted text.
Verified on Codex msg #6 (3 iter) and Claude msg #16 (5 iter):
iter 1 opens with PROMPT expanded at the top, every subsequent
iter opens with the new TOOL_USE turn at the top + PROMPT
collapsed below. Smoke + typecheck green.
* fix(ui): honest provenance label + per-block token badges in response
Two follow-ups to the new section layout.
1. SourceCaption now reads `<container>#<role>` per protocol instead
of hard-coding `input#<role>`. Anthropic blocks come from
`MessageParam.content[]` (-> `messages#user`); OpenAI Responses
blocks come from top-level `input[]` items (-> `input#user`). The
earlier label lied for Claude — "input#user" pointed to a field
that doesn't exist on the wire.
2. Response panel now flashes a `~Nt` order-of-magnitude token badge
on every category header (message, reasoning, function_call,
custom_tool_call, local_shell_call, web_search_call, image_gen,
plus Claude's text / thinking / tool_use / tool_result). Estimate
is `chars / 4`; tooltip shows raw chars. Opt-in via `showTokens`
for the shared ContentBlockView so the request side stays clean
(those blocks already group into TOOL_USE / RESPONSE turns and
per-block size chips there would re-introduce the noise the user
previously asked to remove).
* refactor(ui): align section headers to NAME / source / COUNT
Move the wire-source caption from inside the expanded body up to the
header row, since the body never carried anything else and the empty
caption-only top line read as wasted space. Every top-level Section
(PROMPT / SKILLS / MEMORY / TOOLS / SYSTEM) now renders as a uniform
three-cell header:
[chevron] [icon] NAME source(dim) count(dim)
`source` is the outer-most wire field only (`messages` / `input` /
`system` / `instructions` / `tools`) — no `#role` suffix, matching
the user's "显示最外层的就行" — so a column of headers scans cleanly
against a tiny vocabulary. For mixed-origin SystemSection, the cell
joins unique outer sources in declaration order: `system, messages`
for Claude with reminder chrome, `instructions, input` for Codex.
ClassifiedBlock now carries an optional `.source` field stamped at
construction (Claude `req.system` → 'system', Codex `req.instructions`
→ 'instructions', extractRequestContent.chrome → 'messages' / 'input')
so SystemSection's header can summarise without re-deriving origin.
Drops SourceCaption + TextSummary (no remaining callers) and trims
the now-unused lucide imports.
* feat(cli): exit AgentMind when the launched agent exits
Pre-0.2.3 the launcher parked after `claude` / `codex` exited so the
just-captured trace could be browsed without re-launching. In
practice users always Ctrl+C immediately — the parked window felt
like a hang, and the "press Ctrl+C to stop AgentMind" banner was
greeted with surprise more than relief.
Now `child.on('exit')` tears down the dashboard and propagates the
agent's exit code (signal → 128+signum, code → code, clean → 0) via
a tiny `exitCodeFor()` helper, so shell pipelines and `set -e`
scripts see the agent's verdict instead of AgentMind's "I stopped
fine".
To revisit a saved trace, run `agentmind-cli --no-agent` — it reads
the same `~/.agentmind/projects/*.jsonl` files the launcher just
wrote. README + help text + AGENTS.md updated to reflect the new
flow.
Smoke test: the launcher previously stayed alive after the shim
exited so the test could SIGTERM it; now it races to exit on its
own. Reworked `runOne()` to attach the 'exit' listener BEFORE the
snapshot wait (so we never miss the event) and to assert the auto-
exit actually happens within a generous 5s window — the test now
exercises the new behaviour rather than working around it.
* refactor(ui): hoist instructions out + relayout section header cells
Four follow-ups to the unified header layout.
1. Drop the trailing `·` dot on TOOL_USE (and any other turn section
that just wants a right-side `new` badge). The dot was inherited
from the legacy `· summary` slot; replaced with an explicit
`trailing` slot in Section so badges sit on the right cleanly,
no leading punctuation.
2. Move `count` from the right cell to immediately after the title.
A column of headers now reads `skills 10 messages` left-to-right
like a sentence rather than `skills … messages 10` as two
right-aligned columns. The source cell takes the right-pinned
slot on its own.
3. Promote the API-level system prompt (Anthropic `req.system` /
OpenAI `req.instructions`) into a new top-level
`InstructionsSection`. The remaining SYSTEM bucket now only
holds message-injected chrome, so every section in the column
has a single-source header:
prompt … messages | input
skills N messages | input
memory N messages | input
tools N tools
instructions N system | instructions
system N messages | input
4. Make the source cell visible alongside the `new` badge. Pre-
change a turn-section's `new` badge took the right slot via
ml-auto, hiding the source field. The new Section component
pins `source` right and renders `trailing` after it, so
`tool_use messages new` and `tool_use input new` both surface
provenance even when the badge is present.
Header layout, final form:
[chevron] [icon] NAME [count] [source] [trailing?]
`summary` prop removed from Section — every caller now uses the
structured cells, which keeps the column visually aligned across
section kinds.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
User-visible UI improvement + housekeeping. No protocol changes, no
migrations beyond what 0.2.0 already shipped.
What's in this release
`request panel`: split user prompt from `` noise
(798f5f9)
Claude Code injects multiple `` blocks (skills list,
CLAUDE.md context, plan-mode markers, …) ahead of the user's actual
prompt. Expanding a user message used to dump all of that as wall-of-
text, burying the real prompt under 30+ lines of framework boilerplate.
Now each user text block is split on `` boundaries:
count), one click to expand the full body
Result: "hello claude" jumps to a one-line block; reminders sit one
click away as muted chrome. Injection order preserved so the rendered
view is still a faithful representation of what the model saw.
Already on main since 0.2.1
These are doc-only and ride along.
Scope
`DisplayBlock` synthetic is local to the component — no schema
changes, no persisted-record changes, no migration concerns.
on the prose remainder — it applied to the whole text-with-
reminders payload Anthropic saw, not to our prose subset.
this is a render-time transform.)
Squash-merging this PR triggers publish.