Accepted messages briefly stage in the composer before entering the transcript
- Dominant language
- TypeScript
- Stars
- 909
- Forks
- 116
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 156
Description
## Before filing
- [x] I searched open and closed issues for duplicates.
- [x] I reproduced this on the latest release/current development baseline.
- [x] This is one bug, not several bundled together.
## Closest existing issue
#111 is related because transcript identity and scroll stability matter during
live runs, but it reports scroll locking rather than delayed insertion. No issue
matched searches for `queued message`, `pending message`, `optimistic
transcript`, or `message stages before sending`.
## What's broken
After a message is accepted from the chat composer, Berd briefly renders it as
a pending queue pill inside the composer and only later inserts the user turn in
the transcript. The delay is especially visible while a Claude Code session is
being prepared.
## Steps to reproduce
1. Launch Berd 0.6.2 on macOS and select Claude Code (Haiku is sufficient).
2. Open a new or idle chat.
3. Send any ordinary text message.
4. Watch the composer before the provider starts responding.
## What you expected to happen
The accepted message should appear as a normal user turn in the transcript in
the same interaction frame. Berd may still keep the durable queue record
internally for ordering and retry, and it should show the normal responding
affordance while session/provider preparation continues.
## What actually happened
The text first appeared in the composer's queued-message treatment. It moved to
the transcript only when ACP setup reached the user-message commit boundary.
That can take noticeably longer than the composer's 200 ms queue-pill grace
period, so a normal send reads like a staged draft rather than an accepted turn.
## How often does it happen?
Every time the pre-dispatch preparation path takes longer than the 200 ms visual
grace period; reliably reproducible during Claude Code session setup.
## Berd version
0.6.2 and current development `main` as of 2026-08-19.
## Operating system
macOS 26.0.1, Apple Silicon.
## Model and provider
Claude Haiku via Claude Code. The timing boundary is provider-agnostic, but
faster providers can make the flash harder to notice.
## Relevant log output
No relevant error output. This is a renderer timing/state-presentation issue,
not a failed transport request.
## Screenshots, recordings, or other context
The queue is intentionally authoritative under `LAWS/CHAT.md`: every accepted
message must enter it, failed pre-commit dispatches must retain the record, and
retries must not create duplicate user turns. The presentation does not need to
expose that internal boundary during a healthy send.
A narrow implementation can preserve those laws by projecting the actively
dispatching queue head into the transcript immediately, stamping both the
projection and committed message with the same queue-record identity, and
filtering only that active record from the composer. If dispatch fails before
commit, the durable record can return to the composer for editing/retry.
Important acceptance checks:
- rich attachments, chips, display text, and target persona render identically
before and after commit;
- the live user turn does not duplicate or remount when commit occurs;
- an owner unmount/remount during an unresolved send cannot leave the active
record hidden;
- failed pre-commit dispatch still leaves the record first in the queue;
- the fix does not weaken queue ordering, retry, or ownership rules.
This should remain separate from structured form elicitation (#114); it affects
every ordinary message send.
Contributor guide
Research direction
Start with LAWS/CHAT.md and trace the chat composer, transcript, and ACP setup path for an accepted message. Check how the active queue record is presented before commit and how commit, retry, and owner remount affect it. Done means the user turn appears immediately without duplication, while attachments and ordering remain intact and failed dispatches return to the queue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- desktop, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100