From a5441706f3263396dcb67cd4c543766be5b7b9ff Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Mon, 12 Jan 2026 18:21:11 +0300 Subject: [PATCH] fix(tui): numbered list items showing "1." when code blocks break list continuity --- packages/tui/CHANGELOG.md | 4 +++ packages/tui/src/components/markdown.ts | 6 ++-- packages/tui/test/markdown.test.ts | 37 +++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/packages/tui/CHANGELOG.md b/packages/tui/CHANGELOG.md index 5e597070..9d1d058f 100644 --- a/packages/tui/CHANGELOG.md +++ b/packages/tui/CHANGELOG.md @@ -6,6 +6,10 @@ - `pageUp` and `pageDown` key support with `selectPageUp`/`selectPageDown` editor actions ([#662](https://github.com/badlogic/pi-mono/pull/662) by [@aliou](https://github.com/aliou)) +### Fixed + +- Numbered list items showing "1." for all items when code blocks break list continuity ([#660](https://github.com/badlogic/pi-mono/pull/660) by [@ogulcancelik](https://github.com/ogulcancelik)) + ## [0.43.0] - 2026-01-11 ### Added diff --git a/packages/tui/src/components/markdown.ts b/packages/tui/src/components/markdown.ts index 857af283..a271ff5f 100644 --- a/packages/tui/src/components/markdown.ts +++ b/packages/tui/src/components/markdown.ts @@ -418,13 +418,15 @@ export class Markdown implements Component { /** * Render a list with proper nesting support */ - private renderList(token: Token & { items: any[]; ordered: boolean }, depth: number): string[] { + private renderList(token: Token & { items: any[]; ordered: boolean; start?: number }, depth: number): string[] { const lines: string[] = []; const indent = " ".repeat(depth); + // Use the list's start property (defaults to 1 for ordered lists) + const startNumber = token.start ?? 1; for (let i = 0; i < token.items.length; i++) { const item = token.items[i]; - const bullet = token.ordered ? `${i + 1}. ` : "- "; + const bullet = token.ordered ? `${startNumber + i}. ` : "- "; // Process item tokens to handle nested lists const itemLines = this.renderListItem(item.tokens || [], depth); diff --git a/packages/tui/test/markdown.test.ts b/packages/tui/test/markdown.test.ts index 1bb2b240..56b86698 100644 --- a/packages/tui/test/markdown.test.ts +++ b/packages/tui/test/markdown.test.ts @@ -108,6 +108,43 @@ describe("Markdown component", () => { assert.ok(plainLines.some((line) => line.includes(" - Unordered nested"))); assert.ok(plainLines.some((line) => line.includes("2. Second ordered"))); }); + + it("should maintain numbering when code blocks are not indented (LLM output)", () => { + // When code blocks aren't indented, marked parses each item as a separate list. + // We use token.start to preserve the original numbering. + const markdown = new Markdown( + `1. First item + +\`\`\`typescript +// code block +\`\`\` + +2. Second item + +\`\`\`typescript +// another code block +\`\`\` + +3. Third item`, + 0, + 0, + defaultMarkdownTheme, + ); + + const lines = markdown.render(80); + const plainLines = lines.map((line) => line.replace(/\x1b\[[0-9;]*m/g, "").trim()); + + // Find all lines that start with a number and period + const numberedLines = plainLines.filter((line) => /^\d+\./.test(line)); + + // Should have 3 numbered items + assert.strictEqual(numberedLines.length, 3, `Expected 3 numbered items, got: ${numberedLines.join(", ")}`); + + // Check the actual numbers + assert.ok(numberedLines[0].startsWith("1."), `First item should be "1.", got: ${numberedLines[0]}`); + assert.ok(numberedLines[1].startsWith("2."), `Second item should be "2.", got: ${numberedLines[1]}`); + assert.ok(numberedLines[2].startsWith("3."), `Third item should be "3.", got: ${numberedLines[2]}`); + }); }); describe("Tables", () => {