Michaelliv/pi-generative-ui

GitHub: Michaelliv/pi-generative-ui

逆向复刻 Claude.ai 生成式 UI 的 pi 扩展,支持在原生 macOS 窗口中实时流式渲染交互式 HTML/SVG 小组件。

Stars: 386 | Forks: 17

# pi-generative-ui Claude.ai 的生成式 UI — 逆向工程实现,专为 [pi](https://github.com/badlogic/pi-mono) 重建。 让 pi "展示复利如何工作",你将获得一个实时交互式小部件 — 滑块、图表、动画 — 在原生 macOS 窗口中渲染。不是截图。不是代码块。而是一个真正的带 JavaScript 的 HTML 应用程序,随着 LLM 生成内容实时流式呈现。 ## 工作原理 在 claude.ai 上,当你要求 Claude 可视化某些内容时,它会调用一个名为 `show_widget` 的工具,该工具在对话中内联渲染 HTML。HTML 是实时流式传输的 — 你可以看到卡片、图表和滑块随着 token 到达而出现。 此扩展为 pi 复制了该系统: 1. **LLM 调用 `visualize_read_me`** — 加载设计准则(惰性加载,仅加载相关模块) 2. **LLM 调用 `show_widget`** — 生成一个 HTML 片段作为工具调用参数 3. **扩展拦截流** — 通过 [Glimpse](https://github.com/hazat/glimpse) 打开原生 macOS 窗口,并在 token 到达时馈送部分 HTML 4. **[morphdom](https://github.com/patrick-steele-idem/morphdom) 进行 DOM diff** — 新元素平滑淡入,未更改的元素保持不动 5. **脚本在完成后执行** — Chart.js、D3、Three.js,任何来自 CDN 的内容 小部件窗口具有完整的浏览器功能 (WKWebView) 和双向桥接 — `window.glimpse.send(data)` 将数据发送回代理。 ## 安装 ``` pi install git:github.com/Michaelliv/pi-generative-ui ``` ## 用法 只需让 pi 可视化事物。扩展添加了两个 LLM 自动调用的工具: - **"展示复利如何工作"** → 带滑块和 Chart.js 的交互式解释器 - **"可视化 Transformer 的架构"** → 带标签组件的 SVG 图表 - **"为此数据创建一个仪表板"** → 指标卡、图表、表格 - **"绘制一个粒子系统"** → Canvas 动画 LLM 根据请求决定何时使用小部件或文本。解释性/可视化请求触发小部件;代码/文本请求保留在终端中。 ## 内部结构 ### 设计准则 — 从 Claude 提取 设计准则不是手写的。它们是**从 claude.ai 逐字提取**的。 诀窍在于:你可以将任何 claude.ai 对话导出为 JSON。导出包含完整的工具调用载荷 — 包括包含 Anthropic 实际设计系统的完整 `read_me` 工具结果。72K 的生产规则涵盖排版、调色板、流式安全 CSS 模式、Chart.js 配置、SVG 图表工程等。 我们用每种模块组合触发 `read_me`,导出对话,解析 JSON,将响应拆分为去重部分,并验证与原始内容的字节级准确性。结果:我们的 LLM 获得与 claude.ai 上 Claude 完全相同的指令。 五个模块,按需加载: | 模块 | 大小 | 覆盖内容 | |---|---|---| | `interactive` | 19KB | 滑块、指标卡、实时计算 | | `chart` | 22KB | Chart.js 设置、自定义图例、数字格式化 | | `mockup` | 19KB | UI 组件 token、卡片、表单、骨架屏加载 | | `art` | 17KB | SVG 插图、Canvas 动画、创意图案 | | `diagram` | 59KB | 流程图、架构图、SVG 箭头系统 | ### 流式架构 扩展拦截 pi 的流式事件(`toolcall_start` / `toolcall_delta` / `toolcall_end`),以在 token 到达时实时渲染小部件: ``` toolcall_start → initialize streaming state toolcall_delta → debounce 150ms, open window, morphdom diff toolcall_end → final diff + execute