节点类型
Busabase 中的 Folder、Base、Whiteboard、Workflow、HTML、Skill、Drive、AirApp、File 与 Doc 节点。
节点类型
Busabase 用节点组织可信知识。每个节点都会出现在仪表盘导航中;创建和生命周期操作走变更请求审核流,内容保存方式则取决于节点类型。

当前类型
| 类型 | 适合存放 | 审核方式 |
|---|---|---|
| Folder | 相关节点的导航分组 | 通过节点操作审核重命名、移动、创建、删除和恢复 |
| Base | 带类型字段的结构化记录 | 字段、视图、记录和结构变更都进入审核 |
| Skill | 智能体可读取的文件树 | 文件和元数据存储在对象存储中,通过文件树操作变更 |
| Drive | 纯文件集合 | 文件存储在对象存储中,默认只种子一个 README.md;没有 SKILL.md 或 skill.json |
| AirApp | 智能体编写、人类可运行的网页应用 | 文件存储方式与 Skill/Drive 相同;节点详情页多了一个能在浏览器里运行该应用的 Run 面板 |
| File | 单个上传文件 | 由去重的 Asset 库支撑,节点本身只是指向一个 Asset |
| Doc | 单篇已批准文档 | 文档更新在合并前需要审核 |
| Whiteboard | 自由绘图、草图和空间化规划 | 经过权限检查和审计记录,P0 阶段直接保存 metadata |
| Workflow | 标准化的事件、Webhook、函数、分支、等待、审批、动作和结束流程 | 经过权限检查和审计记录,P0 阶段直接保存 metadata |
| HTML | 可编辑的 HTML 原型和表单 | 直接保存并记录审计;在沙箱 iframe 中预览 |
Whiteboard(白板)
Whiteboard 是完整的 Excalidraw 工作区,可以自由绘制图形、箭头、文字和结构图。场景以版本化 JSON 保存在节点的 metadata.whiteboardDocument 中;在二进制资产接入对象存储前,暂不开放图片插入。
Workflow(工作流)
Workflow 把可重复流程沉淀为版本化图。节点可以由事件触发、调用 Webhook、引用 Webhook 中的沙箱函数规则、判断条件、等待、请求审批、描述动作,或以指定结果结束。连接线同时保存显示标签和机器可读的分支结果;执行模式、并发数、超时和错误策略与图结构分开保存。本阶段保存并校验定义,但暂不执行。
HTML
HTML 同时提供源码编辑与即时预览,适合表单、邮件或落地页原型,以及小型交互概念。预览代码运行在沙箱 iframe 中,不能访问 Busabase 父页面。
Drive
Drive 是纯文件树节点。它复用 Skill 的文件列表、读取、变更请求和合并机制,但默认种子保持最小:只有一个 README.md 文件。

Skill
Skill 保持向后兼容。现有 /skills/* API 路由、SkillVO、contract schema 和 core handler 导出名称与形状都不变;实现现在委托给共享的 file-tree kind。

AirApp
AirApp 是 Busabase 的 Instant App(即时应用):由 Agent 编写、直接在工作区里打开的实时界面,不需要单独部署。它不像传统应用那样依赖固定的发布周期,更像一份建立在工作区数据之上的“实时 Slides”。适合用来制作仪表盘、工作简报、数据故事、审核界面,或任何用界面表达比再写一份文档更清楚的专用视图。
Instant App 有什么不同
- 不需要部署。 Agent 提议的文件通过审核并合并后,打开 AirApp 就会自动运行当前版本。不需要另外配置托管,也不需要一直开着本地的
pnpm dev终端。 - 界面始终连接 Busabase。 AirApp 可以通过 Busabase 的同源 API 读取工作区里的当前数据。它不必把 Base 复制成一份静态导出,而是可以在每次运行时呈现最新的已批准记录。
- 对话就是修改方式。 继续告诉 Codex、Claude Code 或其他已连接的 Agent:移动一个区块、增加一个指标,或者换一种方式讲清楚这些数据。Agent 会通过正常的 Change Request 流程提交修改;审核通过后,同一个 AirApp 就会运行新版本。
- 运行是即时的,应用是持续保存的。 它的文件、历史记录以及与工作区数据的关系都会留在 Busabase。你可以随时重新打开、继续迭代和复用,不会像一次性的 localhost 原型那样丢失。
因此,当人需要的是看见并理解 Agent 的实时工作,而不只是按照固定按钮操作时,AirApp 尤其有用。它仍然可以交互,但不必先变成一个单独部署的正式产品,才能开始创造价值。
AirApp 同样是一个文件树节点——复用 Skill、Drive 一样的文件列表、读取、变更请求和合并机制。智能体通过和编辑 Skill、Drive 完全相同的变更请求流程来编写或修改应用文件。人类打开节点会看到三个标签页:App(默认标签页——一个运行按钮和一个实时预览 iframe)、Files(只读的文件浏览器 + 代码查看器)和 Logs(安装/启动过程的实时输出)。

点击运行会在审核者自己的浏览器里执行这个应用,而不是在服务器上执行:Nodepod(@scelar/nodepod)是一个基于 Web Worker + Service Worker 的 Node.js 运行时,它会安装应用声明的依赖、启动它的服务,并把输出实时流到 Logs 标签页。一旦服务报告就绪,App 标签页的预览 iframe 就会指向一个同源的虚拟地址(/__virtual__/...),提供这个正在运行的应用。
一旦运行就绪,App 标签页的工具栏还会多出两个按钮:一个全屏切换按钮,方便以更大尺寸查看预览;一个"固定到侧边栏"按钮,可以把正在运行的预览固定到右侧的常驻侧边栏——固定之后即使你切换到工作区里的其他任何节点,它也会继续保持运行,而且可以同时固定多个 AirApp,各自作为独立的标签页。运行状态本身也能扛得住普通的页面切换:切换到别的节点再切回来(或者重新打开同一个 AirApp)都不会让它重新启动——它依然在运行,预览会保持在原来的状态,审核者不需要因为看了别的东西就得重新点一次运行。
Nodepod 里到底能跑什么——写给编写 AirApp 的智能体
Nodepod 不是完整的 Node.js——它是把 Node 的 API 表面重新实现了一遍,好让它能跑在浏览器的 Web Worker 里。这一个事实就能解释下面所有内容:任何需要真实操作系统进程、真实原生二进制文件,或者真实无头浏览器的东西都跑不起来,不管怎么配置都一样。纯 JavaScript(加上编译成 WASM 的降级方案)的东西基本都能跑。
已确认可用——新建 AirApp 时的安全默认选择:
- 纯 Node HTTP 服务器。种子模板用的是 Hono +
@hono/node-server——没有打包工具,没有构建步骤,npm install && node server.js就能开始服务。这是做任何偏后端的东西最安全的起点。 node:sqlite(Node 内置的 SQLite 模块),用来存放真实的、可查询的状态——不依赖外部数据库,而且它不是原生二进制文件(它是编译进 Node 本体里的)。- Vite,锁定在
vite@7.3.1,用来做基于打包工具的前端开发服务器。老版本 Vite(^5.4.10/4.5.5)在 Nodepod 里启动就崩:Cannot destructure property 'createServer'——这是一个 esbuild/原生二进制文件解析的 bug,Nodepod 上游已经针对 Vite 7 附带的 esbuild 版本修复了。不要用@vitejs/plugin-react(见下文)——改用 Vite 自带的 esbuild transform 来处理 JSX: 代价是没有 React Fast Refresh——改动会触发整页刷新,而不是保留组件状态。也可以把 Hono 直接挂载成 Vite 的中间件(通过// vite.config.js export default defineConfig({ esbuild: { jsx: 'automatic' }, server: { host: '0.0.0.0', port: 5173, strictPort: true }, });configureServer),做成单进程全栈模式——同样在vite@7.3.1这个版本锁定下确认可用。 @vitejs/plugin-react(基于 Babel 的 React Fast Refresh,真正能保留组件状态的热更新)——在 Nodepod1.9.5及之前确认不可用([BABEL] .length is not a valid Plugin property,Nodepod 加载 Babel 插件时的一个真实 bug)。在1.9.6已经被上游修复——在1.9.9上实测复现:完整点击测试通过(demo 的计数按钮能用,改动会保留组件状态)。如果你想要真正的 Fast Refresh 而不是上面那种整页刷新的折中方案,用这个。
已确认不可用——这些是可识别的失败特征,不要重试:
@vitejs/plugin-react-swc(基于 SWC 的 Fast Refresh,绕开了 Babel)——报错Failed to load native binding。@swc/core自带一个平台原生二进制文件;Nodepod 没有操作系统可以加载它。在 Nodepod1.9.9上仍然不可用(报错完全一致)。- 任何安装或启动开发服务器时需要平台原生二进制文件的工具——上面 SWC 的失败就是这条通用规律的一个例子。如果一个包的
postinstall会下载或编译原生产物(原生 ML 运行时、带原生编译的图像处理库等),就该假设它跑不起来,即便npm install本身成功了也一样。 - 任何需要启动真实无头浏览器或真实操作系统子进程的工具——比如 HeyGen 的 HyperFrames CLI。它完整的 HTML 转 MP4 渲染管线依赖 Puppeteer(真实的无头 Chrome)和 FFmpeg(原生二进制文件),不管怎么配置,架构上都跟 Web Worker 沙盒不兼容。它更轻量的
hyperframes preview命令(不需要 Puppeteer/FFmpeg)经过了实测:npm install真的能成功,但运行时会崩溃报错TypeError: require is not a function——这是 Nodepod 运行时本身的一个真实限制,不是 AirApp 自身代码能修的问题。在 Nodepod1.9.9上仍然不可用(报错完全一致)。 - Next.js 还没有直接测试过(官方没有 Nodepod 示例可以参考改造)。它的默认编译器 SWC 因为上面同样的原因仍然确认不可用;它的备选编译器 Babel 已经不再是"确认不可用"了(见上面 Fast Refresh 那条),所以从零搭一个用 Babel 的 Next.js AirApp 可能值得一试,只是还没试过。
种子示例库是活的参考,不只是文档。 全新安装的 Busabase 会种入可用的 demo(Hono API 服务、两个 Vite + React 变体、挂载在 Vite 里的 Hono、node:sqlite),同时把上面仍然坏掉的例子(SWC、HyperFrames)作为真实、可运行的节点保留下来,而不是删掉——点击任意一个的运行按钮都会复现真实的失败。如果 Nodepod 在上游也把这些修好了,这个 demo 就会开始成功运行,而不是报错,Busabase 这边不需要做任何改动——上面 Babel 那个 demo 就是这么回事。
运行时永远反映节点当前(已合并/HEAD)的文件树——预览一个尚未合并的变更请求的文件快照,目前 Busabase 里任何节点类型都还不支持。
运行需要安全上下文。 Service Worker——Nodepod 用它来拦截预览/虚拟服务器的请求——只会在浏览器的"安全上下文"里注册:https:,或者字面意义上的主机名 localhost/127.0.0.1/[::1]。通过其它主机名(局域网 IP、映射到你机器的自定义域名、隧道域名)以纯 HTTP 方式访问仪表盘,即使解析到的是同一台服务器,也不是安全上下文,所以 Service Worker 会静默注册失败,点击运行会 404。请使用 https:// 或 http://localhost:<端口>。
File
File 是最简单的节点:它只是指向去重 Asset 库中的一个 Asset(名称、MIME 类型、大小和下载链接)。它没有文件树——如果需要一组文件,请使用 Drive。

拖拽排序与移动节点
把鼠标悬停在侧边栏的任意节点上,会出现一个小小的拖拽手柄——抓住它就能在同级节点之间上下拖动排序,或者把它拖到某个文件夹上完成移动。

悬停在侧边栏节点上会显示出它的拖拽手柄。
放置的位置得说得通——不能把一个文件夹拖进它自己的子文件夹里,也不能把节点拖到一个不是文件夹的东西上。除此之外都可以自由操作。
有一点值得留意: 排序和移动是立即生效的——它们不会像本页其他任何编辑那样经过变更请求审核。这被当作整理导航结构,而不是修改内容,所以没有什么需要批准的。
审核流
节点创建和生命周期操作、受审核的文件变化以及支持审核的文档编辑会进入 Inbox。富节点内容保存仍会经过权限检查并写入审计日志,但 P0 阶段的 Whiteboard、Workflow 与 HTML metadata 更新是直接保存,暂时不会创建 Inbox 项目。
