Skip to content

Harden streaming markdown rendering#768

Merged
blove merged 1 commit into
mainfrom
blove/streaming-markdown-hardening
Jul 7, 2026
Merged

Harden streaming markdown rendering#768
blove merged 1 commit into
mainfrom
blove/streaming-markdown-hardening

Conversation

@blove

@blove blove commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • consume @cacheplane/partial-markdown 0.5.5, published through npm trusted publishing with provenance
  • add streaming markdown torture coverage for lists, fences, nested inline formatting, and blockquotes
  • keep the existing table streaming coverage pinned to the published parser behavior

Why

The upstream parser fix keeps streamed blockquote paragraphs nested in their owning blockquote and preserves open-line nested preview updates. The chat package should consume that release and cover nearby streaming surfaces so future parser changes do not regress table or blockquote rendering.

Validation

  • git diff --check
  • npx vitest run src/lib/streaming/streaming-markdown.torture.spec.ts src/lib/streaming/streaming-markdown.table-stream.spec.ts --config vite.config.mts --reporter=verbose
  • npx nx build chat
  • Chrome MCP local smoke with mocked LangGraph backend: streamed markdown kitchen sink rendered one table with rows inside the table and blockquote text inside the blockquote

@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
threadplane Ready Ready Preview, Comment Jul 7, 2026 4:26am

Request Review

@github-actions github-actions Bot 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.

Automated approval: this PR received an intelligent (AI) code review. See the review comments on this PR.

@blove blove enabled auto-merge (squash) July 7, 2026 04:24
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 2m 40s —— View job


PR Review

  • Read changed files and diff
  • Analyze test coverage and correctness
  • Check dependency update
  • Post findings

Summary

The dependency bump is clean — @cacheplane/partial-markdown 0.5.4 → 0.5.5 with a valid SHA-512 integrity hash, and the PR description correctly attributes the fix to blockquote paragraph nesting. The new torture spec file is a good addition and the four test scenarios cover the right surfaces (lists, fenced code, nested inline, blockquotes). A few assertion weaknesses worth tightening before merge:

Fenced code test (line 55): el.querySelector('p')?.textContent ?? '' only checks the first <p> element — if the parser regresses and leaks ``` into a second paragraph, this assertion passes silently. Should assert across all paragraphs or on el.textContent directly. See inline comment.

Nested inline test (line 65): Only the **strong delimiter is checked for leakage; the opening *em delimiter could leak without being caught. See inline comment.

Blockquote textContent (line 73): 'hellowor' (no space between lines) is correct for 0.5.5's hard-break continuation behavior, but a one-line comment explaining why no space is expected would help future readers. See inline comment.

No correctness bugs, no security issues, no type-safety problems, no subscription leaks. The package-lock.json version bumps on internal @threadplane/* packages (0.0.53 → 0.0.55) are from the prior support-packages refresh commit and are expected.

@blove blove merged commit 03a8c78 into main Jul 7, 2026
8 checks passed
grow(content);
expect(el.querySelectorAll('pre code')).toHaveLength(1);
expect(el.querySelector('pre code')?.className).toBe('language-ts');
expect(el.querySelector('p')?.textContent ?? '').not.toContain('```');

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.

Weak assertion — checks only the first <p>. querySelector returns a single element, so if the parser leaks ``` into a second paragraph this passes silently. Either widen to all paragraphs or assert on the whole element:

Suggested change
expect(el.querySelector('p')?.textContent ?? '').not.toContain('```');
expect([...el.querySelectorAll('p')].some((p) => p.textContent?.includes('```'))).toBe(false);

Alternatively: expect(el.textContent).not.toContain('```') — simpler, catches leakage anywhere.

expect(el.querySelector('em')?.textContent).toContain('em and');
expect(el.querySelector('strong')?.textContent).toContain('strong and code');
expect(el.querySelector('strong code')?.textContent).toBe('code');
expect(el.textContent).not.toContain('**strong');

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.

Only the **strong opener is checked. The opening *em delimiter could still leak without being caught here. Consider also asserting:

Suggested change
expect(el.textContent).not.toContain('**strong');
expect(el.textContent).not.toContain('**strong');
expect(el.textContent).not.toContain('*em');

const quote = el.querySelector('blockquote');
expect(quote).toBeTruthy();
const paragraph = quote?.querySelector('p');
expect(paragraph?.textContent).toBe('hellowor');

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.

'hellowor' (no space) pins the parser's hard-break behavior for blockquote continuations. This is correct for 0.5.5 and the <br> check below confirms it intentionally, but a short comment would make the why obvious for future readers:

Suggested change
expect(paragraph?.textContent).toBe('hellowor');
// Continuation `> wor` joins via <br>, not a space — check textContent has no space
expect(paragraph?.textContent).toBe('hellowor');

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.

1 participant