feat(desktop): embed BoosAPI Desktop client as a subproject

Vendor the rebranded BoosAPI Desktop client (Tauri + Vue) into metapi as
a monorepo subdirectory under desktop/. Source only — node_modules,
dist, Cargo target and the upstream .git history are excluded.

desktop/ keeps its own independent Cargo workspace (desktop/src-tauri
with crates/*); it is not part of the backend boosapi crate, so a
`cargo check` at the metapi root still compiles only the backend. Build
the desktop app from desktop/src-tauri per desktop/README.md.

Note: app icons are still placeholder assets pending the final BoosAPI
logo. The updater signing keys live outside the repo and are not
included.
This commit is contained in:
boos
2026-06-22 11:32:57 +08:00
parent d9c78ecc73
commit e0a5f57793
2305 changed files with 449355 additions and 0 deletions
@@ -0,0 +1,208 @@
# markstream-vue — Agent Context(中文)(`/llms.zh-CN`)
这个文件是给 AI/LLM/编码代理用的 **项目地图**:帮助快速定位“该看哪份文档/哪段源码”,以及常见问题的最短排错路径。
如果你想看给人类用户直接复制使用的提示词和接入模板,也请结合 `/zh/guide/ai-workflows` 一起看。
## 回答原则
- 用户可见行为以 `docs/guide/*`(以及 `docs/zh/guide/*`)为准;“是否导出/怎么 import”以 `src/exports.ts` 为准。
- 问题不明确时最多问 **1 个**澄清问题,并给出默认建议。
- 排错优先走 checklist,并尽快要 **最小复现**(仓库有可分享 test page)。
- 文档页里避免写裸 `<thinking>` 这类标签;请用转义(VitePress 会把 Markdown 当 Vue SFC 编译)。
---
## 常用命令
- 安装依赖:`pnpm install`
- Playground 开发:`pnpm dev`
- 文档 dev/build/serve:`pnpm docs:dev` / `pnpm docs:build` / `pnpm docs:serve`
- 测试:`pnpm test`
- 类型检查:`pnpm typecheck`
- Lint:`pnpm lint`
---
## 仓库结构(去哪找)
- 库源码:`src/`
- 对外导出:`src/exports.ts`
- 组件:`src/components/*/`
- Workers:`src/workers/`
- 工具:`src/utils/`, `src/composables/`, `src/types/`
- 解析器包:`packages/markdown-parser/`(发布名:`stream-markdown-parser`)
- 文档站:`docs/`(中文:`docs/zh/`)
- Demo:`playground/`(Vite),`playground-nuxt/`(Nuxt SSR)
- 测试:`test/`(Vitest)
---
## 核心心智模型
两层:
1) **解析层**(`stream-markdown-parser`)
- `getMarkdown()`:创建并配置 `markdown-it-ts` 实例
- `parseMarkdownToStructure(content, md)`:Markdown → `ParsedNode[]`
- 流式 mid-state:未闭合 fence / 未闭合 `$$` / 分段 inline HTML,减少闪烁
2) **渲染层**(`markstream-vue`)
- 默认组件:`MarkdownRender`(文档里也常写 `NodeRenderer`)
- 输入:`content: string`(内部解析)或 `nodes: ParsedNode[]`(流式更推荐)
- 性能工具:
- 虚拟化窗口(`maxLiveNodes`, `liveNodeBuffer`)
- 分批渲染(更平滑“打字机”体验)
- 重节点延迟渲染(`viewportPriority`, `deferNodesUntilVisible`)
---
## 对外 API(可以放心建议)
来自 `markstream-vue`(`src/exports.ts`):
- 组件:`MarkdownRender`(默认导出)
- 解析辅助(re-export):`getMarkdown()`, `parseMarkdownToStructure(content, md)`, `setDefaultMathOptions()`
- 自定义节点映射:`setCustomComponents()`, `removeCustomComponents()`, `clearGlobalCustomComponents()`
- 功能开关:`enableMermaid()`, `disableMermaid()`, `enableKatex()`, `disableKatex()`
- Worker 注入:
- KaTeX:`createKaTeXWorkerFromCDN()`, `setKaTeXWorker()`
- Mermaid:`createMermaidWorkerFromCDN()`, `setMermaidWorker()`
来自 `stream-markdown-parser`(`packages/markdown-parser/src/index.ts`):
- `getMarkdown()`, `parseMarkdownToStructure(content, md)`, `ParseOptions` hooks
- Streaming mid-state 与流结束 `final: true`
---
## 排错 checklist(高信号)
遇到“不渲染/样式不对”,按顺序排:
1) **CSS 顺序/Reset**:先 reset,再 `markstream-vue/index.css`(Tailwind 通常放进 `@layer components`)。
2) **可选 peer 是否安装**(Mermaid/KaTeX/Monaco/Shiki)。
3) **是否启用 loader**(仅在你手动关闭/覆盖时需要):`enableMermaid()` / `enableKatex()`。
4) **peer CSS 是否导入**(需要时):`katex/dist/katex.min.css`(Mermaid 不需要额外 CSS)。
5) **单独节点组件 wrapper**:单独用节点组件时,外层需要 `.markstream-vue`。
6) **SSR(Nuxt)**:用 `<client-only>` 包裹,并确保重 peer/worker 仅浏览器初始化。
文档:`docs/guide/troubleshooting.md`, `docs/guide/tailwind.md`, `docs/nuxt-ssr.md`
---
## 常见意图(路由)
把用户问题归类到意图后,直接用“步骤 + 最小追问 + 指向文档/源码”。
### 安装 + 跑通最小例子
- 表述: “怎么用”, “最小示例”
- 步骤:
- 导入 CSS:`markstream-vue/index.css`
- 渲染:`<MarkdownRender :content="md" />`
- 最小追问: “Vite 还是 Nuxt?贴一下 CSS 导入顺序(reset + Tailwind layers)。”
- 文档:`docs/guide/quick-start.md`, `docs/guide/installation.md`
### 样式缺失 / Tailwind 覆盖
- 表述: “没样式”, “Tailwind 抢样式”
- 步骤:
- reset 在前,`markstream-vue/index.css` 在后
- Tailwind:把库 CSS 放进 `@layer components`
- 单独节点组件:外层 `.markstream-vue`
- 最小追问: “贴 `main.css`(Tailwind layers)和 CSS 导入位置。”
- 文档:`docs/guide/tailwind.md`, `docs/guide/troubleshooting.md`
### 流式:结束后卡 loading
- 表述: “最后卡住”, “loading 一直转”
- 步骤:
- 流结束时设置 `final: true`(ParseOptions 或组件 prop),防止 mid-state 卡住
- 最小追问: “你是否在 end-of-stream 设置了 `final`?最后一段是否以 ``` 或 $$ 结尾?”
- 文档:`docs/guide/parser-api.md`, `docs/guide/parser.md`
### 流式:更平滑的打字机体验
- 表述: “一坨一坨冒出来”, “不平滑”
- 步骤:
- 调整 batch(`renderBatchSize` / `renderBatchDelay`)
- 保持重节点延迟(`viewportPriority`, `deferNodesUntilVisible`)
- 最小追问: “你更新 `content/nodes` 的频率(每 token 还是每 chunk)?batch 参数是多少?”
- 文档:`docs/guide/performance.md`, `docs/guide/props.md`
### 长文档:性能/内存
- 表述: “长文卡”, “滚动掉帧”, “内存高”
- 步骤:
- 调虚拟化(`maxLiveNodes`, `liveNodeBuffer`)
- 保持重节点延迟
- 最小追问: “大概多长(KB/行数)?是否有很多代码块/图表?”
- 文档:`docs/guide/performance.md`
### Mermaid 不显示
- 表述: “mermaid 空白”
- 步骤:
- 安装 `mermaid` peer
- 若手动关闭/覆盖过 loader,客户端调用 `enableMermaid()`(或设置自定义 loader)
- 复查 CSS 顺序/reset
- 最小追问: “是否关闭过 loader?是否 SSR?fence 是否是 ```mermaid?”
- 文档:`docs/guide/mermaid.md`, `docs/guide/troubleshooting.md`
- 源码:`src/components/MermaidBlockNode/mermaid.ts`
### KaTeX 不显示
- 表述: “公式不渲染”
- 步骤:
- 安装 `katex` peer
- 导入 `katex/dist/katex.min.css`
- 若手动关闭/覆盖过 loader,客户端调用 `enableKatex()`(或设置自定义 loader)
- 最小追问: “是否导入 KaTeX CSS?`$...$` 还是 `$$...$$`?是否 SSR?是否关闭过 loader?”
- 文档:`docs/guide/math.md`, `docs/guide/installation.md`
- 源码:`src/components/MathInlineNode/katex.ts`
### Monaco 代码块没功能/空白
- 表述: “工具栏没了”, “编辑器空白”
- 步骤:
- 安装 `stream-monaco` peer
- 确认 Monaco workers 已正确打包(Vite plugin),并确保只在浏览器端执行
- 如果应用层要提前预热,调用 `markstream-vue` 的 `preloadCodeBlockRuntime()`;不要为了预热 worker 直接 import `stream-monaco`
- 最小追问: “控制台是否有 worker/Monaco 报错?生产环境是否已打包 Monaco workers?”
- 文档:`docs/guide/monaco.md`, `docs/guide/components.md`
### 想要轻量代码块(不装 Monaco)
- 表述: “SSR 友好”, “减包体”
- 步骤:
- 用 `MarkdownCodeBlockNode`(Shiki)或开启 `render-code-blocks-as-pre`
- 如果用 Shiki:安装 `stream-markdown`
- 最小追问: “需要语法高亮还是纯文本就行?”
- 文档:`docs/guide/code-blocks.md`, `docs/guide/components.md`
### Markdown 里嵌自定义组件(`<thinking>`)
- 表述: “自定义 tag”, “嵌组件”
- 步骤:
- 通过 `customHtmlTags` / `custom-html-tags` 声明自定义标签(未知标签闭合后按原生 HTML 渲染;未闭合或格式不完整的片段按纯文本)
- 用 `setCustomComponents(customId, mapping)` 映射渲染
- 最小追问: “tag 名称有哪些?希望按 HTML 透传还是自定义 node type?”
- 文档:`docs/guide/advanced.md`, `docs/guide/parser-api.md`
### Nuxt SSR 报错
- 表述: “window is not defined”, “SSR crash”
- 步骤:
- 用 `<client-only>` 包裹
- Mermaid/Monaco/worker 仅浏览器初始化
- 最小追问: “Nuxt 版本?报错发生在 build 还是 runtime?安装/启用了哪些 peers?”
- 文档:`docs/nuxt-ssr.md`
### 想确认导出/怎么 import
- 表述: “是否导出 X”, “import 路径”
- 步骤:
- 查 `src/exports.ts` 和 `package.json#exports`
- 最小追问: “要 import 的符号名是什么?现在用的 import 路径是什么?”
- 文档:`docs/guide/components.md`, `docs/guide/api.md`