From 17721d5e0153ad761fa6155eb90d62b9a5ee3283 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Fri, 12 Jun 2026 20:22:53 +0200 Subject: [PATCH] fix(tui): preserve unordered user list markers (closes #5657) --- packages/coding-agent/CHANGELOG.md | 1 + packages/tui/CHANGELOG.md | 1 + packages/tui/src/components/markdown.ts | 11 +++++++++-- packages/tui/test/markdown.test.ts | 17 ++++++++++++++--- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 2927a100..e770ebdb 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -8,6 +8,7 @@ ### Fixed +- Fixed inherited user-message transcript rendering so standalone `+` messages no longer render as `-` ([#5657](https://github.com/earendil-works/pi/issues/5657)). - Fixed `--model` resolution for authenticated custom model IDs whose slash prefix matches an unauthenticated built-in provider ([#5643](https://github.com/earendil-works/pi/issues/5643)). - Fixed `/fork` to keep session parent chains connected when the forked path contains labels ([#5669](https://github.com/earendil-works/pi/issues/5669)). - Fixed `/share` and `/export` HTML exports to use the active fallback theme when the configured custom theme no longer exists ([#5596](https://github.com/earendil-works/pi/issues/5596)). diff --git a/packages/tui/CHANGELOG.md b/packages/tui/CHANGELOG.md index 6405fe69..b5e277a9 100644 --- a/packages/tui/CHANGELOG.md +++ b/packages/tui/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixed +- Fixed Markdown source list marker preservation to include unordered markers, so standalone `+` user messages no longer render as `-` ([#5657](https://github.com/earendil-works/pi/issues/5657)). - Fixed slash-separated fuzzy queries so provider/model completions remain matchable after insertion. - Fixed WezTerm inline Kitty image rendering so reserved row clears do not erase all but the top strip of tool image previews ([#5618](https://github.com/earendil-works/pi/issues/5618)). diff --git a/packages/tui/src/components/markdown.ts b/packages/tui/src/components/markdown.ts index ed8ad780..83f15aa5 100644 --- a/packages/tui/src/components/markdown.ts +++ b/packages/tui/src/components/markdown.ts @@ -71,7 +71,7 @@ export interface MarkdownTheme { } export interface MarkdownOptions { - /** Preserve source ordered-list markers instead of normalizing them from the list start. */ + /** Preserve source list markers instead of normalizing them. */ preserveOrderedListMarkers?: boolean; } @@ -561,6 +561,11 @@ export class Markdown implements Component { return match ? `${match[1]} ` : undefined; } + private getUnorderedListMarker(item: Tokens.ListItem): string | undefined { + const match = /^(?: {0,3})([-+*])(?:[ \t]+|(?=\r?\n|$))/.exec(item.raw); + return match ? `${match[1]} ` : undefined; + } + /** * Render a list with proper nesting support */ @@ -577,7 +582,9 @@ export class Markdown implements Component { ? this.options.preserveOrderedListMarkers ? (this.getOrderedListMarker(item) ?? `${startNumber + i}. `) : `${startNumber + i}. ` - : "- "; + : this.options.preserveOrderedListMarkers + ? (this.getUnorderedListMarker(item) ?? "- ") + : "- "; const taskMarker = item.task ? `[${item.checked ? "x" : " "}] ` : ""; const marker = bullet + taskMarker; const firstPrefix = indent + this.theme.listBullet(marker); diff --git a/packages/tui/test/markdown.test.ts b/packages/tui/test/markdown.test.ts index 9c0be05c..dc595b11 100644 --- a/packages/tui/test/markdown.test.ts +++ b/packages/tui/test/markdown.test.ts @@ -112,9 +112,9 @@ describe("Markdown component", () => { assert.deepStrictEqual(lines, ["1. alpha", "2. beta", "3. gamma"]); }); - it("should preserve source ordered list markers when configured", () => { + it("should preserve source list markers when configured", () => { const markdown = new Markdown( - " 4. forth\n 3. third\n\n10) ten\n7) seven", + " 4. forth\n 3. third\n\n10) ten\n7) seven\n\n+ plus\n* star\n- minus\n+", 0, 0, defaultMarkdownTheme, @@ -126,7 +126,18 @@ describe("Markdown component", () => { const lines = markdown.render(80).map((line) => stripAnsi(line).trimEnd()); - assert.deepStrictEqual(lines, ["4. forth", "3. third", "", "10) ten", "7) seven"]); + assert.deepStrictEqual(lines, [ + "4. forth", + "3. third", + "", + "10) ten", + "7) seven", + "", + "+ plus", + "* star", + "- minus", + "+", + ]); }); it("should render mixed ordered and unordered nested lists", () => {