Skip to content

fix(chat): drop the streaming cursor that detached onto its own line - #4507

Merged
BunsDev merged 2 commits into
mainfrom
fix/cave-1yslk-streaming-cursor
Aug 10, 2026
Merged

fix(chat): drop the streaming cursor that detached onto its own line#4507
BunsDev merged 2 commits into
mainfrom
fix/cave-1yslk-streaming-cursor

Conversation

@BunsDev

@BunsDev BunsDev commented Aug 10, 2026

Copy link
Copy Markdown
Member

Reported from the running app: a small grey bar sitting on its own line between
a message and whatever followed it.

What it was

The streaming cursor () rendered as a sibling of the markdown container:

<div className="cave-md" dangerouslySetInnerHTML={{ __html: html }} />
{pending ? <span ></span> : null}

That placement was chosen deliberately — it is the only way to show a caret
without injecting into the sanitized HTML string — but .cave-md is a
block-level <div>, so the span can never sit at the end of the last rendered
line. It necessarily wraps onto a row of its own.

So this was not specific to one message. It appeared after every streaming
message that had rendered markdown, and read as a rendering artifact rather
than as a caret.

Why remove rather than reposition

Putting a caret back at the end of the text means appending inside the last
inline descendant of the sanitized HTML — exactly the injection the sibling
placement existed to avoid. Progress is already legible from the text growing,
so the affordance goes rather than gets moved.

The plain-text fallback cursor goes with it. It only shows for the window
before the first render lands, so keeping it would flash a caret for a moment
and then lose it for the rest of the stream — a flicker, not an affordance.

pending still drives progressive rendering; only the glyph is gone.

Tests

Two source-text assertions previously required the cursor and would have
failed this change. They now assert its absence at both sites, so it cannot
creep back without the block-container problem being solved first. A third
assertion in session-debug.test.ts still pins that only the last text span
streams — that behaviour is unchanged; only its wording mentioned the glyph.

Verified: pnpm test:app (1161 files), pnpm lint, pnpm typecheck.

Closes cave-1yslk.

The cursor rendered as a sibling of the markdown container. That placement
was chosen deliberately — it is the only way to show a caret without
injecting into the sanitized HTML string — but the container is a
block-level <div>, so the span could never trail the last rendered line and
instead wrapped onto a row of its own.

What the reader saw was a detached grey bar sitting between the message and
whatever followed it, after every streaming message that had rendered
markdown. Reported from the running app.

Restoring a caret would mean appending inside the last inline descendant of
the sanitized HTML, which is exactly the injection the sibling placement
existed to avoid. Progress is already legible from the text growing, so the
affordance goes rather than gets moved. The plain-text fallback cursor goes
with it: it only shows for the window before the first render lands, so
keeping it would flash a caret for a moment and then lose it for the rest of
the stream.

`pending` still drives progressive rendering; only the glyph is gone.

The two source-text assertions that required the cursor now assert its
absence at both sites, so it cannot creep back without the block-container
problem being solved first.
Copilot AI lite review requested due to automatic review settings August 10, 2026 13:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Removes the streaming cursor glyph from MessageBubble markdown/plain-text rendering to eliminate a detached “grey bar” artifact caused by rendering the cursor as a sibling of a block-level markdown container.

Changes:

  • Remove the pending-gated cursor glyph from both the plain-text fallback and sanitized-HTML markdown render paths in MarkdownContent.
  • Update markdown-source tests to assert the cursor glyph is absent and prevent reintroduction without solving the layout constraint.
  • Update session-debug assertions/comments to reflect that progressive rendering remains, but the cursor glyph is gone.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/components/message-bubble.tsx Removes the cursor glyph rendering in MarkdownContent; adds explanatory inline comment about why it’s removed.
src/components/message-bubble-markdown.test.ts Updates source-text assertions to enforce absence of the cursor glyph and sibling pending-gated cursor span.
src/lib/session-debug.test.ts Updates pinned description/assertion text to remove cursor-glyph wording while keeping progressive-render behavior checks.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/components/message-bubble.tsx Outdated
Two comments still described the streaming cursor as if it existed — the
`segments` prop doc ("progressive markdown + cursor") and the assistant
segment comment ("the cursor shows on at most one span"). Both would have
sent the next reader looking for a glyph that is no longer rendered.

Also shortens the block comment at the removal site. The reasoning that
matters is why it cannot simply be re-added as a sibling; the rest belonged
in the PR description, where it already is.

Reviewer flagged both on #4507.
@BunsDev
BunsDev merged commit 3568435 into main Aug 10, 2026
1 check passed
@BunsDev
BunsDev deleted the fix/cave-1yslk-streaming-cursor branch August 10, 2026 14:25
@BunsDev
BunsDev restored the fix/cave-1yslk-streaming-cursor branch August 10, 2026 14:34
@BunsDev
BunsDev deleted the fix/cave-1yslk-streaming-cursor branch August 10, 2026 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants