From cc3e6c1b057238170e26cf49afdced21ee58e0b6 Mon Sep 17 00:00:00 2001
From: Table
Date: Mon, 21 Sep 2026 10:52:22 +0800
Subject: [PATCH 1/2] fix(prose): preserve empty numbered markers
---
internal/tui2/prose/prose_test.go | 11 +++++++++++
internal/tui2/prose/render.go | 5 +++++
2 files changed, 16 insertions(+)
diff --git a/internal/tui2/prose/prose_test.go b/internal/tui2/prose/prose_test.go
index 860189ac3..ba640c4bd 100644
--- a/internal/tui2/prose/prose_test.go
+++ b/internal/tui2/prose/prose_test.go
@@ -164,6 +164,17 @@ func TestOrderedListsShareARightEdge(t *testing.T) {
}
}
+// TestABareNumberedReplyStillDraws holds the reply boundary where Markdown
+// parses a number and full stop as an ordered list with an empty item.
+func TestABareNumberedReplyStillDraws(t *testing.T) {
+ for _, src := range []string{"32.", "1024."} {
+ rows := plain(render(t, src, Options{Width: 80}))
+ if got, want := strings.Join(rows, "\n"), src; got != want {
+ t.Errorf("Render(%q) = %q, want %q", src, got, want)
+ }
+ }
+}
+
// TestBlockquoteCarriesItsGutter checks that the bar runs down EVERY row of the
// quote including the blank one between its paragraphs — a dashed bar reads as
// two quotes.
diff --git a/internal/tui2/prose/render.go b/internal/tui2/prose/render.go
index 45f2ab2cc..1f9b722bc 100644
--- a/internal/tui2/prose/render.go
+++ b/internal/tui2/prose/render.go
@@ -294,6 +294,11 @@ func (r *renderer) list(n *ast.List) {
saved := r.push(first, indent)
before := len(r.out)
r.container(c, !n.IsTight)
+ // A marker with no item body is still source text. Emit the pending
+ // prefix so a reply such as "32." cannot collapse to zero rows.
+ if len(r.out) == before {
+ r.emit(nil)
+ }
r.pop(saved, len(r.out) > before)
}
}
From a51a7101490ddec175450d50c89f60051559dc2a Mon Sep 17 00:00:00 2001
From: Table
Date: Mon, 21 Sep 2026 10:57:31 +0800
Subject: [PATCH 2/2] docs(changes): record bare numbered reply fix
---
.../unreleased/1330-bare-numbered-reply.md | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 docs/changes/unreleased/1330-bare-numbered-reply.md
diff --git a/docs/changes/unreleased/1330-bare-numbered-reply.md b/docs/changes/unreleased/1330-bare-numbered-reply.md
new file mode 100644
index 000000000..5b0077ba3
--- /dev/null
+++ b/docs/changes/unreleased/1330-bare-numbered-reply.md
@@ -0,0 +1,17 @@
+---
+kind: fixed
+title: Number-only assistant replies remain visible
+pr: 1330
+# Optional. Which part of the repository this touches, so a reader can skip it.
+# One or more of: build, chat, docs, engine, remote, resident
+surface: [chat]
+# Optional, and the reason this file exists. Every statement that WAS true and is
+# not any more, written whole: what it was, and what it is now. A model reading
+# this has to be able to check its own memory against it, so "branch names" is
+# useless and "the trunk was chat-v3-task and no longer exists; work goes to dev"
+# is the whole point. Leave the list empty if nothing anybody believed changed.
+invalidates: []
+---
+
+The Markdown renderer now keeps an empty ordered-list marker in the transcript,
+so replies such as `32.` are not silently dropped.