安装与导出(packages)
用 busabase-cli export 把 space 的一部分变成一个 git 仓库,任何人都能通过 GitHub URL 安装;也可以在网页端或用 busabase-cli 安装别人的包——默认先审核,再生效。
安装与导出(packages)
**package(包)就是把 Busabase space 里的一棵子树渲染成 git 仓库里的普通文件:一个 busabase.json 清单,加上一棵 content/ 目录树——真正的 markdown 文档、真正的 Base 定义,记录则是一行一个 JSON 对象。busabase-cli export 负责写出一个包;把包从一个 GitHub URL 装进你的 space,可以走网页端的从 GitHub 安装…**对话框,也可以用 busabase-cli install。你可以用它把一套模板、一个 skill,或者一整个知识库交给别人——而因为包就是一堆文件,对方可以先读、先 diff、先在 pull request 里评审,然后它才会碰到任何一个 space。
install 默认是先审核后生效的,而且它把包分成两半来处理。结构——文件夹、Base 及其字段和视图——会立即创建:一个还挂在待审核状态的 Base 没有 id,而没有 id 就无处安放视图、字段和记录。内容——记录、文档、skill、AirApp——则会作为 Change Request 等你审核;install 会打印出有多少条在等着,busabase-cli change-requests list 可以列出它们。所以陌生人的仓库最多只能在你的 space 里摆出几张空表,而在你读过并合并之前,没有任何人往里面写的东西是生效的。
在网页端安装
装包不一定要用 CLI。侧边栏里,和动态这类快捷入口并排、在收藏和 Base 树上方,有一项从 GitHub 安装…。点开是一个对话框,分三步走:粘贴 URL、读一遍它会创建什么、确认。
安装是 space owner/admin 的操作。 预览和安装两步服务端都会校验,因为包里可以带 skill 和 AirApp——那是这个 space 的 agent 会真正执行的代码。侧边栏这一项只对用得了它的角色显示,成员不会看到一扇打不开的门;无论如何,服务端校验才是最终依据。自托管的单用户服务器上没有角色可校验,所有人都能通过。
第一步——URL
只有一个仓库地址输入框,吃的 URL 和 CLI 完全一样(https://github.com/owner/repo,后面可以跟 /tree/<ref>[/<subdir>])。浏览器里只检查一件事:别是空的。其余全由服务端说了算:它只接受 GitHub 的域名,会重新解析主机名以拒绝任何指向内网或回环地址的目标,然后再确认下载下来的东西确实是一个包。改动 URL 会清空下方的预览,所以屏幕上的内容绝不会是另一个仓库的答案。
第二步——预览
点预览,它会抓取这个包并告诉你装下去会发生什么。抓仓库的从来不是你的浏览器,而是服务端,它返回的是一份大纲:
- 包自己的身份——名称、描述,以及
busabase.json里声明了的版本、作者、许可证——再加上它实际解析到的来源,形如owner/repo 版本 <ref> 位于 <subdir>。 - 将会创建的内容——节点树,每一行显示图标、名称和 slug,每个 Base 后面跟着
N 个字段 · N 条记录,每个 skill、AirApp、drive 后面跟着N 个文件。下方是一行合计:文件夹 · 文档 · Base · 记录 · 文件。 - 名称已被占用——每一个和你已有内容撞车的 slug;如果开了改名,还会显示它实际会用哪个 slug 安装。
- 需要留意——和 CLI 打印的是同一批警告(被跳过的二进制文件、被丢弃的附件值等等)。
预览下方有三个选项:
| 控件 | 作用 | 对应的 CLI 参数 |
|---|---|---|
| 安装到文件夹 | 目标文件夹 slug。默认填好包自己的名字(已转成 slug)。改动它会重跑预览,因为目标文件夹决定了哪些 slug 会撞车 | --into-folder <name> |
| 撞车的项目改名后安装 | 加 -2、-3 后缀,而不是直接失败。只有真的存在冲突时才出现,勾上的瞬间就重跑预览 | --rename |
| 跳过评审,直接安装 | 当场合并包里的内容,而不是留下 change request。始终显示,默认不勾 | --auto-merge |
预览是跳不过去的:预览没出来之前,安装按钮根本不存在。--dry-run 在 CLI 上是可选的,在网页端却是唯一的入口。
只要还有没解决的冲突,或者一个必须跳过评审才能装的包还没勾上那个复选框,安装按钮就一直是禁用的。后一种情况会出现一条红色的该软件包只能跳过评审安装提示,说明原因并指向那个复选框,而不是把你晾在死路上。
第三步——结果
跑的过程中你会看到一个转圈图标和「可能需要一点时间——每一项都是逐个创建的。」没有进度条,东西是一件一件创建的。
跑完之后,对话框换成已安装到 <文件夹>,以及创建了多少东西的合计——文件夹 · Base · 视图 · 文档 · 记录 · 文件。接着是真正重要的那部分:
- 如果有待处理的,显示**「有 N 个变更请求等你处理」,并给一个现在去评审**的链接直达收件箱。包里的内容只是被提议,还没有生效。
- 如果你勾了跳过评审,直接安装,则显示**「全部已合并——软件包已在你的空间中生效。」**
完成会关掉对话框并刷新网页端——结构是立即创建的,所以哪怕每一条记录都还等着审核,树也已经变了。
万一出错,对话框直接把服务端自己那句话原样贴出来,而不是一句笼统的失败提示——「Not a Busabase package — expected busabase.json at …」、拒绝域名的提示、角色不足的提示。有用的恰恰是这些措辞,所以原样呈现(这些是服务端消息,不随界面语言翻译)。
用命令行安装
npx busabase-cli install https://github.com/acme/support-kb-template| 参数 | 作用 |
|---|---|
--into-folder <name> | 目标文件夹 slug(默认取包清单里的 name) |
--dry-run | 打印执行计划(节点树、记录条数、冲突)但什么都不创建 |
--auto-merge | 直接合并包里的记录和文档,而不是把它们留成待审核的 change request——见下文 |
--rename | 冲突的条目改用带后缀的 slug(-2、-3……)安装,而不是直接失败 |
先跑 --dry-run:它会打印出确切的节点树、每个 Base 的记录条数,以及所有冲突,而且什么都不创建。要装私有仓库,设置 GITHUB_TOKEN 即可。
网页端还是 CLI?
两边跑的是同一套安装——同样的包格式、同样的计划、同样的五趟 apply、同样的先审核后生效。差别在下面这几处,选之前值得知道:
| 网页端 | busabase-cli install | |
|---|---|---|
| 预览 | 强制——不预览就装不了 | 可选,靠 --dry-run |
| 谁去下载仓库 | 服务端 | 你自己的机器 |
| 私有仓库 | 用服务端的 GITHUB_TOKEN,由运维这台主机的人配置,不是你的 | 用你自己的 GITHUB_TOKEN |
| 需要的权限 | space owner/admin | 普通写权限——它调的是任何客户端都能调的那批节点级接口,并不经过 owner/admin 这道安装闸门 |
| 导出 | 没有 | busabase-cli export |
实际影响是:在 Busabase Cloud 上,除非运维方配了 token,否则你没法从网页端装私有仓库——那就用 CLI,它用的是你自己的 token。另外导出在网页端根本没有对应功能,那是一个 CLI 命令。
URL 就是版本锁定
| URL | 装的是 |
|---|---|
https://github.com/acme/kb | 仓库默认分支此刻的内容 |
https://github.com/acme/kb/tree/v1.2.0 | v1.2.0 这个 tag——永远是该 tag 的内容,哪怕分支后来往前走了 |
https://github.com/acme/packages/tree/v1.2.0/skills/pdf-summarizer | 一个仓库里放了很多包时,只装其中一个 |
任何 git ref 都可以——分支、tag,或者 commit SHA。凡是你要重复安装或者交给同事的,请用 tag:只有这种形式不会在你脚下悄悄变掉。
把一个节点导出成包
导出只有 CLI 一条路,网页端没有对应功能。
npx busabase-cli export support-kb -o ./support-kb-template你指定的那个节点本身就是这个包,它的子节点才是落到 content/ 下面的东西:
busabase.json
content/getting-started.md
content/cms/_folder.json
content/cms/blog/base.json
content/cms/blog/records.ndjson
content/cms/agent-integrations/base.json
content/pdf-summarizer/_node.json
content/pdf-summarizer/SKILL.md每个文件都是给人读的:文档就是带 YAML frontmatter 的真 .md,base.json 是某个 Base 的字段和视图,records.ndjson 一行一个 JSON 对象、字段值按 slug 索引,skill 或 AirApp 自己的文件则原样携带。推上去就能安装:
cd ./support-kb-template
git init && git add . && git commit -m "Add support-kb package"
git remote add origin https://github.com/acme/support-kb-template.git && git push -u origin main| 参数 | 作用 |
|---|---|
-o, --out-dir <dir> | 包的输出目录(必填) |
--name <name> | 包名(默认复用 busabase.json,否则用节点 slug) |
--dry-run | 只列出将要写入的文件,不实际写入 |
输出是确定性的:space 没变的情况下导出两次,产出的文件字节完全一致——所以 GitHub 上的 diff 精确反映改了什么,改一条记录就只有一行变化。重新导出前会先清空 content/,所以你删掉的节点不会赖在仓库里。你手工加进 busabase.json 的内容(version、author、license、tags)会在重新导出时保留。
包的格式里根本没有留给节点权限、变更历史、Vault 密钥、webhook 规则的位置——格式表达不了的东西,也就泄露不出去。附件的值同样不会被携带;附件字段的定义会保留,而 export 会告诉你它丢弃了多少个值。
跳过审核意味着你信任包的作者
--auto-merge——以及它在网页端的孪生兄弟跳过评审,直接安装——是放弃审核、直接把包里的记录和文档合并生效。skill 和 AirApp 里带的是你的 agent 将会执行的代码——只有当这个仓库你已经读过,或者作者是你愿意给提交权限的人时,才跳过审核。
动手前值得先知道的限制
- 包里的记录只要带 relation 值,就只能跳过审核安装。 CLI 会提前拒绝并让你加上
--auto-merge重跑;网页端给出的是同一个结论,只不过表现为一条指向那个复选框的提示。两边的原因都一样:relation 存的是它所指向的那些记录的 id,而这些 id 只有在记录被合并之后才存在——先审核的装法只会给你一堆空的 relation。只有真正的值才会触发这一条:一个仅仅定义了 relation 字段、还没有任何关联的 Base,和其他内容一样可以先审核再合并。 - 在会返回非绝对上传 url 的主机上,二进制文件会被跳过——典型情况是用本地文件系统存储的自托管服务器,它给出的上传 url 只有它自己的网页端才知道怎么用。install 会给出警告、点名是哪个文件,然后把其余内容照常装完。使用 S3/R2/MinIO 存储的主机(包括 Cloud)上传一切正常;而 skill、AirApp、drive 内部携带的文本——markdown、JSON、SVG——是内联的、不走上传,所以无论哪种主机都不受影响。
- 同一个包不能往同一个 space 里装两次。 Base 的 slug 在 space 内唯一,节点 slug 在同一文件夹内唯一,所以第二次安装会在计划阶段就失败,并列出冲突的 slug。
--rename——网页端叫撞车的项目改名后安装——是逃生口:它会以-2、-3的形式安装,并把所有 relation 改写为指向被重命名后的 Base。
配置
这一节只跟 busabase-cli 有关——网页端本来就知道你在哪台主机、哪个 space,身份也就是你自己。和 busabase-cli 其他地方的优先级一致:
| 内容 | 参数 | 环境变量 | 保存位置 |
|---|---|---|---|
| 服务地址 | --base-url <url> | BUSABASE_BASE_URL | ~/.busabase/.env |
| API key | --api-key <token> | BUSABASE_API_KEY | ~/.busabase/.env |
| Space | --space-id <id> | BUSABASE_SPACE_ID | ~/.busabase/.env |
如果 install/export 连不上服务器,或者返回 401/403,参见故障排查。
另见:节点类型 · Change Requests · 备份与还原 · 故障排查