Busabase

テンプレートを公開する

作り上げたフォルダをインストール可能なアプリにする — busabase-cli export --template、SKILL.md のドラフト、カタログのインデックス、そして自ホスト環境を自前のギャラリーに向ける方法。

space の中で何かを作り上げた — いくつかのテーブル、AirApp、サンプル行、そしてエージェントが従う実際の手順。それをテンプレートとして公開すれば、他の人が URL ひとつでまるごとインストールでき、しかもマニュアルが一緒に届くので、相手のエージェントも使い方を知っています。

手順は 3 つ:エクスポートするマニュアルを仕上げるカタログに載せる


1. フォルダをエクスポートする

npx busabase-cli export busa-email -o ./busa-email --template

--template が無ければ通常のパッケージエクスポートbusabase.jsoncontent/ ツリー)です。--template はその上に 3 つを追加します。

マニュアルをパッケージルートへ引き上げます。 フォルダにこのアプリのマニュアルとして印の付いた Skill ノードがあれば、content/ の下ではなくパッケージルートに SKILL.md(と references/agents/scripts/)として書き出されます。往復してもフォーマットが排除したい重複が生まれません。

マニュアルがまだ無ければドラフトを書きます。 テーブルはあるが Skill ノードが無いフォルダには、実際に存在する構造 — テーブル名、フィールド、アプリの有無 — から生成した SKILL.md が書き出され、判断が要る箇所はすべて明示的な TODO として残ります。

---
name: "busa-email"
description: "受信箱のトリアージデスク。"
metadata:
  busabase:
    template: true
    resources:
      - "settings"
      - "reviews"
---

# busa-email

TODO: describe the job this app does, and when an agent should reach for it.

## Busabase resources

- `settings`: TODO: what this table is for. Fields: name, payload, vault-refs.
- `reviews`: TODO: what this table is for. Fields: subject, batch-id, item-id.
...

このドラフトは決定的に生成され、モデルが書くことは決してありません。この文章はエージェントが従う指示になるのであり、テーブルの意味についてもっともらしい作り話をされるより、明らかな空欄が残っているほうがましだからです。TODO はすべてあなたにしかできない判断です — 公開前に埋めてください。

足りないものを報告します。 エクスポート後にテンプレートバリデータを実行し、失敗を Not yet a valid template: … として、警告も併せて出力します。エクスポート自体は成功します — 何を直すべきかを伝えているのであって、書き出しを拒んでいるわけではありません。

slug は書いたときの形に戻ります

エクスポート対象のフォルダ自体がテンプレートからインストールされたものなら、その Base の slug にはインストール時のフォルダプレフィックス(busa-email-settings)が付いています。エクスポートは所有スタンプからパッケージ本来の slug(settings)を復元し、relation の参照先も合わせて書き換えます。

そうしないと、エクスポート → インストール → エクスポートが不動点になりません。一度インストールされたパッケージはプレフィックス付きで戻ってきて、再インストールすると二重に付くか衝突します。


2. テンプレートを仕上げる

手で直すのは 2 か所。詳細はテンプレートフォーマットにあります。

SKILL.md — TODO を置き換えます。このアプリが何のためのものか、各テーブルに何が入るか、そして — 明示的に — エージェントが決してしてはならないことを書きます。エージェントはそこに書かれたとおりに動きます。

busabase.json — エクスポートはプレースホルダーの "category": "uncategorized" を残します。最低でも実際のカテゴリに直してください。そのうえで、カードの読み味を決めるフィールドを埋めます。

"template": {
  "category": "email",
  "tags": ["inbox", "triage"],
  "screenshots": ["assets/screenshots/overview.webp"],
  "agentPrompts": [
    "今日の受信箱をトリアージして、返信が要るものは下書きを作って。"
  ],
  "airapp": "busa-email-app",
  "schemaVersion": 1
}

agentPrompts は見た目以上に考える価値があります。*「そもそもこれに何を聞けばいいのか」*への最短で正直な答えであり、この問いこそが、インストールされたアプリが使われるか放置されるかを決めます。

そして push します。

cd ./busa-email
git init && git add . && git commit -m "Add busa-email template"
git remote add origin https://github.com/acme/busa-email.git && git push -u origin main

ここまでで URL からインストール可能で、しかもすでに Agent Skill です。次は一覧に載せるステップです。

公開前の自己点検: 自分の space の使い捨てフォルダにインストールしてみてください(busabase-cli install <url> --into-folder scratch --dry-run のあと本番実行)。Base の slug プレフィックスのおかげで、同じ space の別フォルダに同じテンプレートを衝突なく入れられるので、自分のコピーで試せます。


3. カタログをビルドする

テンプレートセンターのギャラリーは 1 つの JSON ファイルを読み、そのファイルは手で保守しません — 5 つしか作らないパッケージのカードに「6 tables」と書いてあるのは誤字ではなく信頼の欠陥です。busabase-cli index は、テンプレートを収めたリポジトリのチェックアウトからそれを組み立てます。

npx busabase-cli index . --repo acme/templates -o templates.json
フラグ効果
--repo <owner/repo>必須。 エントリの subdir が相対するリポジトリ
--ref <ref>エントリを読む git ref(既定は main)— カードがインストールするバージョン
-o, --out <file>書き出し先(既定は標準出力)
--checkディスク上のファイルが生成結果と違えば非ゼロで終了

indexローカルコマンドです。ディレクトリを読むだけで、ホストも API キーも space も不要 — だから CI ステップとして使えます。すべての pull request で --check を走らせれば、カタログが対象リポジトリからずれることはありません。

テンプレートが載るかどうかはインストーラと同じバリデータが決めるので、カードがインストールの実態と違う約束をすることはあり得ません。テンプレートを名乗って要件を満たさなかったパッケージは、理由付きで rejected 配列に公開されます。このファイルを最も読みそうな人は、自分のエントリが無いことに気づいた作者であり、理由の無い「あなたの skill はカタログにありません」はビルドが出せる最も行動しづらいメッセージだからです。

{
  "format": "busabase-template-index@1",
  "repo": "acme/templates",
  "ref": "main",
  "templates": [
    {
      "subdir": "busa-email",
      "name": "busa-email",
      "description": "受信箱のトリアージデスク。",
      "category": "email",
      "tags": ["inbox", "triage"],
      "screenshots": ["assets/screenshots/overview.webp"],
      "agentPrompts": ["今日の受信箱をトリアージして…"],
      "version": "1.2.0",
      "license": "MIT",
      "stats": {
        "folders": 1, "docs": 0, "bases": 3, "records": 7,
        "files": 41, "airapps": 1, "skill": true
      }
    }
  ],
  "rejected": [
    {
      "subdir": "half-done",
      "name": "half-done",
      "errors": ["AirApp \"ui\": package.json has no `dev` script. …"]
    }
  ]
}

エントリは名前順に並ぶので、リポジトリが変わっていなければ再ビルドはバイト単位で同じファイルになります。diff がノイズだらけのカタログは、誰にもレビューされなくなります。


ギャラリーはどこを読むか

Busabase は既定で busabase/templates リポジトリの templates.json を読みます。

https://raw.githubusercontent.com/busabase/templates/main/templates.json

busabase/skills の一角ではなく独立したリポジトリなのは、skills リポジトリが汎用 skill を入れるために clone されるものであり、テンプレート 1 つ — アプリのソース一式、スクリーンショット、サンプルデータ — だけで追跡バイトの大半を占めかねないからです。そこにテンプレートを置くと、すべての skill インストールがすべてのテンプレート分を支払うことになります。

自ホスト環境は環境変数 1 つで自前のカタログを指せます。

BUSABASE_TEMPLATE_CATALOG_URL=https://raw.githubusercontent.com/acme/templates/main/templates.json

取得はサーバー側で行われます。ファイルはクロスオリジンで、ブラウザがユーザーごとに取得してもキャッシュは共有されず、ページ側にホストを決めさせると「どのカタログを信頼するか」がクライアントの判断になってしまいます。結果は 1 時間キャッシュされます — カタログが変わるのは誰かがテンプレートをマージしたときだけで稀ですし、レート制限下の運用者がページの再読み込みで枠を使い切らされるべきでもありません。

スクリーンショットのパスは、カードのインストール元と同じリポジトリ・ref に対して URL 化されるため、表示と実際のインストールがずれることはありません。


チェックリスト

  • busabase-cli export <folder> -o <dir> --templateNot yet a valid template: の行が出ない
  • SKILL.mdTODO をすべて埋めた(「してはならないこと」を含む)
  • template.categoryuncategorized ではなく実際のカテゴリ
  • スクリーンショット 1 枚以上、agentPrompts 1 件以上
  • サンプル行はデータセットではなくデモ(1 テーブル 50 件まで
  • 必須リレーションが循環しておらず、各 key が参照先 Base に存在する
  • 各 AirApp に dev スクリプトがあり、.busabaseignorepackage.json を除外していない
  • 使い捨てフォルダにインストールし、change request から一通り開いて確認した
  • CI で busabase-cli index . --repo <owner/repo> --check が通る

関連

On this page