feat(web): markdown Source | Preview toggle in session file pane#957
Open
heavygee wants to merge 4 commits into
Open
feat(web): markdown Source | Preview toggle in session file pane#957heavygee wants to merge 4 commits into
heavygee wants to merge 4 commits into
Conversation
Add Source | Preview toggle for .md/.mdx files in the session file route, defaulting to preview with localStorage persistence. Reuse chat markdown pipeline via MarkdownRenderer standalone mode (no assistant-ui thread). Includes unit tests, Playwright smoke, and e2e fixture. Closes tiann#954 Co-authored-by: Cursor <cursoragent@cursor.com>
Soup verify gate: defaultComponents merge type is wider than react-markdown Components; standalone file-pane path needs explicit cast.
Draft
2 tasks
There was a problem hiding this comment.
Findings
- [Major] Markdown preview loses fenced code block rendering — the new standalone path calls
ReactMarkdowndirectly withdefaultComponents, but those components depend on theMarkdownTextPrimitivepre/code override to detect fenced code blocks and route them throughSyntaxHighlighter/MARKDOWN_COMPONENTS_BY_LANGUAGE. In this branch, a fenced block renders as a normal<pre>containing inline-styled<code>, so markdown files with code fences ormermaidblocks lose the existing code shell, syntax highlighting, and diagram rendering. Evidence:web/src/components/MarkdownRenderer.tsx:34, triggered byweb/src/routes/sessions/file.tsx:420.
Suggested fix:export function MarkdownRenderer(props: MarkdownRendererProps) { return <MarkdownContent {...props} /> } // file preview can use the same renderer path: <MarkdownRenderer content={decodedContent} />
Summary
- Review mode: initial
- One functional regression found in the markdown preview rendering path. The added tests cover headings/tables/source toggle, but not fenced code blocks or mermaid blocks, which is where the standalone renderer diverges from the production chat renderer.
Testing
- Not run (automation)
HAPI Bot
Standalone file preview now mirrors chat code-block rendering: fenced blocks use SyntaxHighlighter and MARKDOWN_COMPONENTS_BY_LANGUAGE (mermaid included) without requiring ThreadPrimitive context. Addresses HAPI Bot Major on tiann#957. Co-authored-by: Cursor <cursoragent@cursor.com>
Collaborator
Author
|
Addressed the Major finding in 2daee4f: standalone file-pane preview now routes fenced code blocks through |
There was a problem hiding this comment.
Findings
- [Major] Inline markdown code renders as full code blocks -
react-markdown@10.1.0does not pass aninlineboolean to customcodecomponents; its publicComponentstype is intrinsic element props plusnode. Because this branch is never taken, inline backtick code in the file markdown preview falls through to the block renderer and gets a header plus.aui-md-codeblockwith languageunknown. Evidence:web/src/components/MarkdownRenderer.tsx:36.
Suggested fix:import { Children, isValidElement, type ReactElement } from 'react' function StandaloneCode(props: ComponentPropsWithoutRef<'code'>) { const Code = defaultComponents.code! return <Code {...props} /> } function StandalonePre(props: ComponentPropsWithoutRef<'pre'>) { const child = Children.toArray(props.children)[0] if (!isValidElement<ComponentPropsWithoutRef<'code'>>(child)) { const Pre = defaultComponents.pre! return <Pre {...props} /> } const className = String(child.props.className ?? '') const language = /language-(\w+)/.exec(className)?.[1] ?? 'unknown' const code = String(child.props.children ?? '').replace(/\n$/, '') const Highlighter = MARKDOWN_COMPONENTS_BY_LANGUAGE[language as keyof typeof MARKDOWN_COMPONENTS_BY_LANGUAGE]?.SyntaxHighlighter ?? SyntaxHighlighter const CodeHeader = defaultComponents.CodeHeader as ComponentType<CodeHeaderProps> const Pre = defaultComponents.pre! const Code = defaultComponents.code! return ( <> <CodeHeader language={language} code={code} /> <Highlighter language={language} code={code} components={{ Pre, Code }} /> </> ) } const components = useMemo<Components>(() => ({ ...(componentsRest as Components), pre: StandalonePre, code: StandaloneCode, }), [componentsRest])
Questions
- None.
Summary
- Review mode: follow-up after new commits
- One regression remains in the standalone markdown renderer. The added tests check fenced code blocks, but not inline code inside normal markdown prose.
Testing
- Not run (automation;
bunis unavailable in this runner)
HAPI Bot
Move block detection to the pre override (react-markdown v10 does not pass inline to custom code components). Add inline-code regression test. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Findings
- No issues found.
Questions
- None.
Summary
- Review mode: follow-up after new commits
- The prior inline-code rendering finding appears addressed in the current head. I did not find any remaining correctness/security regression in the added markdown preview toggle or standalone renderer path.
Testing
- Not run locally:
bunis unavailable in this runner. Static review plusgit diff --checkcompleted.
HAPI Bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a Source | Preview toggle on the session File tab for
.md/.mdxfiles. Preview renders markdown viaMarkdownRendererin a newstandalonemode (the file route sits outside the assistant-ui thread). Source keeps the existing Shiki-highlighted raw view. Default is Preview; the choice persists inlocalStorage(hapi.filePreview.markdownMode.v1).Includes vitest coverage for the helper + route, a Playwright smoke spec, and standalone file-pane markdown rendering that routes fenced code blocks through the same
SyntaxHighlighter/MARKDOWN_COMPONENTS_BY_LANGUAGEpipeline as chat (mermaid included).Known v1 gaps (follow-up, not blockers):
Test plan
bun typecheck(cli + web + hub)cd web && bun run test— 1114/1114 passe2e/file-md-preview.spec.ts(local smoke; not in upstream CI)Issues
Closes #954