markstream-vue — Agent Context (/llms)
This file is a compact, agent-focused map of markstream-vue: where things live, how to answer common questions, and what to check first when users report issues.
Answering guidelines
- Prefer user-facing behavior from
docs/guide/*(anddocs/zh/guide/*) and export surface fromsrc/exports.ts. - Ask at most one clarifying question if the request is ambiguous.
- When debugging, ask for a minimal repro (there’s a shareable test page) and walk the user through the checklist below.
- Avoid raw HTML tags like
<thinking>in Markdown docs pages; escape them (VitePress compiles Markdown as Vue SFC).
Setup commands
- Install deps:
pnpm install - Playground dev:
pnpm dev - Docs dev/build/serve:
pnpm docs:dev,pnpm docs:build,pnpm docs:serve - Tests:
pnpm test - Typecheck:
pnpm typecheck - Lint:
pnpm lint
Repo structure
- Library source:
src/- Public exports:
src/exports.ts - Components:
src/components/*/ - Workers:
src/workers/ - Utilities:
src/utils/,src/composables/,src/types/
- Public exports:
- Parser-only package:
packages/markdown-parser/(published asstream-markdown-parser) - Docs site (VitePress):
docs/(Chinese underdocs/zh/) - Demos:
playground/(Vite),playground-nuxt/(Nuxt SSR) - Tests:
test/(Vitest)
Core mental model
There are two layers:
Parser layer (
stream-markdown-parser)getMarkdown()creates a configuredmarkdown-it-tsinstanceparseMarkdownToStructure()turns Markdown into a node tree (ParsedNode[])- Streaming mid-states reduce flicker (unclosed fences /
$$/ partial inline HTML)
Renderer layer (
markstream-vue)- Default component:
MarkdownRender(also referred to asNodeRenderer) - Takes either
content: string(parses internally) ornodes: ParsedNode[](recommended for streaming) - Performance tools:
- Virtualization window (
maxLiveNodes,liveNodeBuffer) - Batch rendering (steady “typewriter” feel)
- Defer heavy nodes until visible (
viewportPriority,deferNodesUntilVisible)
- Virtualization window (
- Default component:
Public API (safe to suggest)
From markstream-vue (src/exports.ts):
- Component:
MarkdownRender(default export) - Parser helpers (re-exported):
getMarkdown(),parseMarkdownToStructure(),setDefaultMathOptions() - Custom node renderers:
setCustomComponents(),removeCustomComponents(),clearGlobalCustomComponents() - Feature toggles:
enableMermaid(),disableMermaid(),enableKatex(),disableKatex() - Worker injection:
- KaTeX:
createKaTeXWorkerFromCDN(),setKaTeXWorker() - Mermaid:
createMermaidWorkerFromCDN(),setMermaidWorker()
- KaTeX:
From stream-markdown-parser (packages/markdown-parser/src/index.ts):
getMarkdown(),parseMarkdownToStructure(),ParseOptionshooks- Streaming mid-state behavior and
final: trueend-of-stream mode
Troubleshooting checklist (high signal)
When “it doesn’t render” or “looks wrong”, check these in order:
- CSS order/reset: reset first, then
markstream-vue/index.css(Tailwind usually inside@layer components). - Optional peer installed (Mermaid/KaTeX/Monaco/Shiki).
- Feature enabled where required:
enableMermaid()/enableKatex(). - Peer CSS imported where required:
katex/dist/katex.min.css,mermaid/dist/mermaid.css. - Standalone node wrapper: standalone node components need a
.markstream-vuewrapper for scoped styles/vars. - SSR: in Nuxt, wrap with
<client-only>when using browser-only peers/workers.
Docs: docs/guide/troubleshooting.md, docs/guide/tailwind.md, docs/nuxt-ssr.md
Common intents (router)
Use these as “answer skeletons”: quick steps + minimal repro questions + where to read next.
Install + first render
- Signals: “how to use”, “minimal example”
- Steps:
- Import CSS:
markstream-vue/index.css - Render:
<MarkdownRender :content="md" />
- Import CSS:
- Ask: “Vite or Nuxt? Show your CSS import order (reset + Tailwind layers).”
- Docs:
docs/guide/quick-start.md,docs/guide/installation.md
CSS missing / Tailwind overrides
- Signals: “unstyled”, “Tailwind overrides”, “looks wrong”
- Steps:
- Ensure reset loads before
markstream-vue/index.css - Tailwind: import library CSS inside
@layer components - If using standalone node components, wrap
.markstream-vue
- Ensure reset loads before
- Ask: “Paste
main.css(Tailwind layers) + where you importmarkstream-vue/index.css.” - Docs:
docs/guide/tailwind.md,docs/guide/troubleshooting.md
Streaming: “loading forever” at end
- Signals: “stuck loading”, “final chunk”
- Steps:
- On end-of-stream set
final: true(ParseOptions or component prop) so mid-states don’t stick
- On end-of-stream set
- Ask: “Do you set
finalwhen the stream ends? What are the last ~40 chars (often ends with ``` or $$)?” - Docs:
docs/guide/parser-api.md,docs/guide/parser.md
Streaming: smooth typewriter feel
- Signals: “bursty”, “jumpy”, “not smooth”
- Steps:
- Enable/tune batching (
renderBatchSize/renderBatchDelay) - Keep heavy nodes deferred (
viewportPriority,deferNodesUntilVisible)
- Enable/tune batching (
- Ask: “How often do you update
content/nodes(per token? per chunk?) and what batch props are set?” - Docs:
docs/guide/performance.md,docs/guide/props.md
Large documents: perf/memory
- Signals: “huge markdown”, “scroll lag”, “memory high”
- Steps:
- Tune virtualization (
maxLiveNodes,liveNodeBuffer) - Keep heavy nodes deferred
- Tune virtualization (
- Ask: “Approx size (KB/lines)? Many code blocks/diagrams?”
- Docs:
docs/guide/performance.md
Mermaid not rendering
- Signals: “mermaid blank”
- Steps:
- Install peer
mermaid - Call
enableMermaid()on the client - Re-check CSS order/reset
- Install peer
- Ask: “Where do you call
enableMermaid()? Any SSR? Is the fence ```mermaid?” - Docs:
docs/guide/mermaid.md,docs/guide/troubleshooting.md - Code:
src/components/MermaidBlockNode/mermaid.ts
KaTeX not rendering
- Signals: “math not shown”
- Steps:
- Install peer
katex - Import
katex/dist/katex.min.css - Call
enableKatex()on the client
- Install peer
- Ask: “Is KaTeX CSS imported?
$...$or$$...$$? Any SSR?” - Docs:
docs/guide/math.md,docs/guide/installation.md - Code:
src/components/MathInlineNode/katex.ts
Monaco code blocks missing features / blank
- Signals: “toolbar missing”, “blank editor”
- Steps:
- Install peer
stream-monaco - Ensure Monaco workers are bundled (Vite plugin) and you’re on the client
- Install peer
- Ask: “Any worker-related console errors? Are Monaco workers bundled in production?”
- Docs:
docs/guide/monaco.md,docs/guide/components.md
Prefer lightweight code blocks (no Monaco)
- Signals: “SSR friendly”, “reduce bundle”
- Steps:
- Use
MarkdownCodeBlockNode(Shiki) orrender-code-blocks-as-pre - If using Shiki, install
shiki+stream-markdown
- Use
- Ask: “Need highlighting or just plain code?”
- Docs:
docs/guide/code-blocks.md,docs/guide/components.md
Custom components in Markdown (<thinking>)
- Signals: “custom tag”, “embed component”
- Steps:
- Allow tags via
customHtmlTags/custom-html-tags - Map via
setCustomComponents(customId, mapping)
- Allow tags via
- Ask: “What tag names? Do you want HTML passthrough or a custom node type?”
- Docs:
docs/guide/advanced.md,docs/guide/parser-api.md
Nuxt SSR errors
- Signals: “window is not defined”, “SSR crash”
- Steps:
- Wrap renderer in
<client-only> - Ensure heavy peers/workers initialize only in browser
- Wrap renderer in
- Ask: “Nuxt version? Error during build or runtime? Which peers are installed/enabled?”
- Docs:
docs/nuxt-ssr.md
“What does the package export?”
- Signals: “is X exported”, “how to import Y”
- Steps:
- Check
src/exports.tsandpackage.json#exports
- Check
- Ask: “Which symbol and what import path did you try?”
- Docs:
docs/guide/components.md,docs/guide/api.md