busabase-app-creator について
Busabase App Creatorは、Busabase AirAppやインストール可能なテンプレートを作成・保守するスキルです。アプリ構成、ランタイム、セキュリティ、デプロイ、レビューの技術要件を定め、視覚や製品上の判断はユーザーまたは上位スキルに委ねます。
主な機能
- 01AirAppとインストール可能なテンプレートの作成
- 02指定された既存AirAppの保守
- 03ランタイム、セキュリティ、デプロイ要件の定義
- 04BusabaseリソースとChangeRequestの利用
活用シーン
- 01新しいワークスペースを基盤にしたAirAppの構築
- 02アプリのインストール可能なテンプレート化
- 03承認範囲内での既存AirAppの更新
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ busabase/ skills --skill busabase-app-creatorインストール後、Claude Code で/busabase-app-creatorを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlassets/airapp-template/.gitignoreairapp.json.templatepackage.json.templateserver.jsserver.pyassets/airapp-template/app/index.htmlstyles.cssassets/airapp-template/app/js/app.jsbusabase-client.jsconfig.jsmessages.jsruntime.jsassets/airapp-template/app/js/providers/busabase-provider.jsdemo-provider.jsindex.jsassets/airapp-template/scripts/check.mjsassets/package-scripts/sync-content.mjsreferences/app-engineering.mddeployment-and-review.mdinterview-and-blueprint.mdmaintenance.mdresource-model-and-security.mdruntime-and-sdk.mdtemplate-format.mdui-and-validation.mdscripts/airapp-kit.mjsairapp-kit.test.mjscheck-runtimes.test.mjs詳細
Busabase アプリクリエーター
分離された Busabase ワークスペースと AirApp を 1 つ作成するか、インストール可能なテンプレートをディスク上のファイルとして作成するか、明示的に特定された既存の AirApp を 1 つ保守します。このスキルは、AirApp のモデリング、テンプレート/パッケージ形式、セキュリティ、ランタイムエンジニアリング、デプロイ、保守に関する唯一の技術的な信頼できる情報源です。より上位のワークフロースキルは、これらの事項をここに委ねます。
ここで定めるのは形式と正確性であり、好みではありません。有効なアプリと有効なテンプレートに含めるべきもの、つまりリソース、マニュアル、ランタイムルール、レビューゲートを示し、それ以上のことには踏み込みません。プロダクトの表現、ビジュアルスタイル、レイアウトの慣例、インタラクションの仕上げは、ユーザー、またはそれらをこのスキルの上に重ねる上位スキル(kelly-app-skill-creator のようなもの)に委ねられます。このスキルは、そのようなレイヤーと衝突する意見を決して持ち込んではなりません。
現在存在する 2 つのレイヤーは、公開されている busabase/templates カタログ向けの busabase-template-creator と、mr-kelly/skills 向けの kelly-app-skill-creator です。どちらも正確性のためにこのスキルを呼び出し、その上に公開基準のみを追加します。busabase-package-creator、busabase-skill-creator、busabase-app-package-creator はこのスキルへのシンボリックリンクであり、別個のスキルではありません。名前は 4 つありますが、契約は 1 つです。
譲れない契約
- 接続、API、ChangeRequest、承認の動作には
$busabaseを使用します。リモート操作を行う前に、必ずそのSKILL.mdを読みます。 - リソースだけでなく、手引きとプロンプトも提供します。 この実行で何を作成する場合も、その Folder の最後にはアプリ名を付けた
skillノードを 1 つ配置し、作成するすべてのノードに、その skill をエージェントに最初に案内するシナリオ用プロンプトを付けます。 ノードの種類に応じた汎用プロンプトしかない Folder は未完成です。インストールした人は「データはあるが、次に何をすればよいのか」と困ることになります。作業と並行して両方を書きます。アプリの形ができてきたら skill ノードを、ノードを作成するたびにそのノードのプロンプトを用意します(ステップ 5、項目 6)。構成と基準についてはステップ 10 を参照してください。 - 最初に作業ルートを決め、実行中にルートを混在させないでください。
reinstall(ビルド済みバンドルが Space 内に存在するだけで十分です。ステップ 1 を参照)、createworkspace-first、createpackage-first(§「2 つの開始方法」を参照)、またはmaintainのいずれかです。createでは、新しい Folder、少なくとも 1 つの新しいワークフロー Base、必要なネイティブリソース、新しい AirApp を作成します。既存の業務用 Base にアタッチしたり、変更したりしてはいけません。maintainではreferences/maintenance.mdに従います。承認済みのメンテナンス範囲に含まれる場合、アプリは関連するワークスペースリソースを継続的に作成または変更できます。 - 1 つのメッセージにつき、意思決定を求める質問は 1 つだけにします。
A、B、必要に応じてCのラベルを付けた具体的な選択肢を 2 つまたは 3 つ提示します。適切な場合は 1 つを推奨として示し、その後、選択肢の文字または独自の回答を返すよう促します。漠然とした自由回答形式の質問だけをしてはいけません。 - 接続する前に、Busabase Cloud と Desktop のどちらを使うかユーザーに選んでもらいます。
- 足場を組む前に、ソースの所有場所を確定します。スタンドアロン AirApp の場合は、一時ディレクトリを使うか、ユーザー指定の永続ディレクトリを使うか尋ねます。上位の App-in-Skill 作成者から委任された場合は、再度尋ねず、その skill の AirApp プロジェクトルートを完全な永続ソースとして使います。そのルートは
<skill-root>/content/<name>-app/です。これはテンプレートのレイアウトであり、アプリを含む skill の構成です。プロジェクトが<skill-root>/app/に置かれている skill は、それより前の形式で、移行待ちです。現在の場所から読み取り、無関係な作業の副作用として移動してはいけません(移動するとハーネスのパスとルートスクリプトにも影響するため、意図的な移行の一環として行う必要があります)。content/<name>-app/の下にpackage.jsonがあるかを先に調べ、次にapp/を調べてルートを特定します。どちらの形式でも、package.json、server.js、ブラウザー用のapp/サブツリー、チェック用ファイル、ロックファイルを含みます。pnpm devで引き続き実行できますが、委任された作成では、ユーザーがローカルプレビューまたはデバッグを明示的に求めない限り、ローカル開発を開始しません。 - 永続的なローカルプロジェクトを正本として扱います。同じレビュー済みのプロジェクトファイルツリーを AirApp に送信し、
.env、node_modules、ログなどのローカル専用ファイルは除外します。AirApp の実装を別にもう 1 つ管理してはいけません。また、リモートだけに編集を残してはいけません。リモートから読み戻し、正本であるローカルプロジェクトに反映して、続行前にチェックを再実行します。 - まずランタイムを選びます。
node(デフォルト)またはpythonです。 AirApp のブラウザー側(app/の下にあるすべてのもの)はどちらでも同じで、違うのは配信を担うプロセスだけです。アプリ独自の処理が Python(データ処理、スクレイピング、ML)ならpython、それ以外はnodeを選びます。Python AirApps にできないことは、以下の「Python AirApps」を参照してください。 - 新しいアプリの足場を組むとき、
nodeアプリには Hono とバニラ HTML/CSS/JavaScript を、pythonアプリには標準ライブラリのserver.pyテンプレート(airapp-kit.mjs scaffold ... --runtime python)を使います。どちらの場合も、React、Vite、JSX、アプリケーションフレームワークのビルドパイプラインを導入してはいけません。足場を組むときに、インストール済みの SDK をローカルにバンドルします。デプロイ後のstartはサーバーの起動だけを実行します。 - これは足場を組む際のデフォルトであり、自分が作成していないアプリへの評価ではありません。 フレームワークを使った AirApp も有効です。
[email protected]はブラウザー内エンジンで起動し、remoteエンジンは通常のコンテナで、Next/React は同梱デモとして動作します。maintainでは、既存アプリを評価する前にreferences/runtime-and-sdk.mdの「許可されるスタック」を読みます。フレームワークへの依存を違反とみなしてはいけません。また、動作中のフレームワークアプリをバニラ JS に書き換える提案をしてはいけません。さらに、この skill が足場を組んでいないプロジェクトに対してairapp-kit checkを実行してはいけません。React/Vite are forbidden.で失敗しますが、これは誤検出であり、実際の問題ではありません。 maintainでは、正本のツリーを通常の対象として読む前に、デプロイ済みのツリーからそれ自体を生成できるか確認します。「ソースは本当にここにあるか?」(references/maintenance.md)を参照してください。ツリー内に生成元がなく、ソースもどこにも見つからないdistのみのプッシュは、基盤として利用できるものではなく中止条件です。要求された変更を満たすために、圧縮済みバンドルにパッチを当ててはいけません。- 最新の公開済み
busabase-sdk(0.99.0 以降)を解決し、createBusabaseClient、ローカル AirApp OAuth ゲートウェイ、describeBusabaseAirAppRuntime、Node の認証情報ストアエントリ、busabase-sdk/airappのブラウザー用 AirApp ヘルパー(detectAirAppRuntime、createAirAppRecords、airAppWriteMessage)がエクスポートされていることを確認してから、生成するアプリで正確なバージョンを固定します。スキャフォールドはこれらすべてを実行し、古い SDK は拒否します。 - SDK の AirApp ヘルパーを使い、独自のものを書いてはいけません。 ランタイムの検出、レコードの読み書き、「保存済みまたはレビュー待ち」という結果と文言は、すべて
busabase-sdk/airappから取得します。スキャフォールドでは、これをすでにapp/vendor/busabase-airapp.js(detectAirAppRuntime、createAirAppRecords、toAirAppWriteOutcome、airAppWriteMessage)としてベンダー化しています。いずれかをアプリごとに複製したことが原因で、同じバグが数十個のアプリで手作業により修正されることになりました。それぞれの使用方法についてはreferences/runtime-and-sdk.mdを参照してください。 - ブラウザーコードでは、
window.location.originを指定してcreateBusabaseClientを使います。Busabase の絶対 URL をハードコードしてはいけません。廃止された/__busabase_api__/ブリッジプレフィックスを使ってはいけません。API キー、Bearer トークン、OAuth トークン、セッション Cookie、シークレットをブラウザーコードや AirApp ファイルに含めてはいけません。Hono OAuth 境界を使うのは、references/runtime-and-sdk.mdで定義されているループバックのローカル開発だけです。デプロイ済み AirApp では OAuth ゲートを省き、ビューアーと同じオリジンの既存セッションを使います。環境変数の認証情報は、ユーザーのオンボーディング経路ではなく、明示的な自動化/テスト用オーバーライドです。 createでは、ユーザーが小規模なアクションを明示的に求めない限り、最初のバージョンは読み取り専用にします。どちらのモードでも、要求された書き込みはすべて、SDK のレコードヘルパーが作成する ChangeRequest を通じて行い、autoMergeは未設定のままにします。Busabase は、書き込み権限のあるビューアーには変更をマージし、権限のないビューアーにはレビュー待ちとしてキューに入れます。アプリは、どちらの結果になったかを伝えます。AirApp はレビューやマージを呼び出さず、独自にレビューを強制することもありません。createでは、この実行中に作成したリソースにのみアクセスします。maintainでは、既存リソースの正確な ID を使い、新たに承認されたリソースについては ID を明示的に取得して確定します。名前や slug の一致だけを頼りに、無関係なリソースを見つけたり転用したりしてはいけません。新しい関心事は、Busabase のネイティブリソースを使ってモデル化します。- サードパーティー連携と Vault の要件は、値を含めずに設計図で宣言します。ブラウザー AirApp は Vault を読み取れません。シークレットを必要とする処理は、信頼された Busabase Workflow、または明示的に構成された Agent 経由で実行する必要があります。
- 永続的なアプリ設定とワークフロー/ドメイン状態は
busabase-sdkを使って Busabase から読み込み、機能に応じて適切なネイティブノードを選びます。階層と識別情報には Folder/Node、構造化された運用状態には Base と View、永続的な説明設定には Doc、アセットには Drive/File、シークレットには Vault の参照を使います。生成されるローカル設定に含めてよいのは、正確に確定した ID、手順の許可リスト、制限、スキーマのバージョン、シークレットを含まない準備状態メタデータだけです。永続的な正本を二重に持つ場所として、ローカル JSON、SQLite、ブラウザーのストレージ、デモ用プロバイダーを使ってはいけません。 createでは、構造を作成した後、確定したすべての Folder、Node、Base、View、リソースの ID を設計図に書き戻します。その後、生成されたランタイムコードは、ワークスペースを一覧表示して名前や slug を照合するのではなく、安定したハンドルを使ってそれらのリソースにアクセスする必要があります。どのハンドルを使うかは、成果物のバインド方法によります。§「2 つのバインド方法」を参照してください。どちらも有効ですが、ルートに合わない方を選ぶとアプリは動作しません。- データを読むすべてのワークフローに明示的な予算を設定します。対話型ページのデフォルトは Base あたり最大 50 レコード、関連する保留中 ChangeRequest は 20 件までとします。サーバー側のフィルターとソートを使用し、独立した読み取りは並列に実行し、
nextCursorを保持します。また、ユーザーの操作 1 回につき 1 ページだけを取得します。読み込み、検索、フィルタリング、更新、ナビゲーション、詳細表示、「ページ N に移動」、上限付きのwhile (cursor && n < 4)ループ、totalPagesに対するPromise.all、フィルターが効かなかったように見えたときの「フォールバック」の背後に、全件スキャンを隠してはいけません。references/runtime-and-sdk.md§「巧妙に隠された全件スキャン」を参照してください。全件エクスポートとオフライン分析には、別途、明示的なバッチ処理ワークフローが必要です。 - UI はユーザーとの会話で使われている言語で生成します。後からロケールを追加できるよう、メッセージは一元管理します。
createでは、デフォルトで現実的なシードレコードを 3 ~ 5 件生成し、他のすべての書き込みと同様に ChangeRequest 経由で書き込みます。autoMergeは省略し、認証情報の権限に応じて適用またはキューイングされるようにします。- 委任された App-in-Skill の
createモードでは、デフォルトでtarget-first検証を使います。決定的な静的チェックとプロジェクトチェックを実行し、レビュー済みの正本ツリーを AirApp CR として送信し、対象の Busabase 内にあるマージ済み HEAD で UI の受け入れ確認を行います。委任元の skill またはユーザーがpnpm dev、ローカル URL、プレビュー、デバッグを明示的に求めた場合に限り、local-previewを使います。スタンドアロン AirApp の作成では、ユーザーがtarget-firstを明示的に選ばない限り、受け入れ確認にlocal-previewを使います。maintainではreferences/maintenance.mdの検証ゲートと受け入れゲートを適用します。 - 書き込みは
$busabaseの指示に従います。autoMergeを省略し、応答のstatusを読み取ります。 レビューの要否は権限による設定であり、この skill が追加する手順ではありません。書き込み可能な認証情報なら即座に公開され、権限の弱い認証情報なら ChangeRequest が作成されます。どちらの結果も正しいものです。ワークスペースが求めていないレビューゲートを作るためにautoMerge: falseを渡してはいけません。認証情報の権限に関係なく、特定の変更について追加確認が必要だと判断した場合に限り、これを指定します。この skill がゲートするのは範囲です。createでは、現在の会話でユーザーが承認した正確な Folder/Base/フィールド/リレーション構造だけを書き込めます。maintainでは、承認済みの変更セットだけを書き込めます。 - 人によるゲートの対象は、書き込みごとではなく範囲です。 複数のエージェントや人が同じ Space で同時に作業することはよくあります。承認済みの範囲内にある各書き込みについて人にマージを求めても、安全性は高まらず、作業が遅くなるだけです。そのため、範囲が承認された後は、権限に応じた方法で AirApp コードとシードデータを書き込み、そのまま作業を続けます。ただし、次の 3 つの場合は人による確認が必要です。承認済みの範囲外のもの、リスクが高いと判断した変更(他の人が書いたデータの削除や上書き、破壊的なスキーマ変更など)には、
autoMerge: falseを明示して送信し、その理由を説明します。また、認証情報がマージできないため、書き込み結果が保留中の ChangeRequest になった場合も確認が必要です。ユーザーから特定のものを依頼されない限り、自分のものも他のエージェントのものも、保留中の ChangeRequest を自分で承認またはマージしてはいけません。
2 つのバインド方法
アーティファクトがリソースにアクセスする方法は 2 通りあり、どちらの経路を使うかによって決まります。 これは単なる言葉の問題ではありません。同じ設定フィールドが、一方では必須で、もう一方では禁止されているため、境界をまたいでプロバイダーをコピーすると、決して読み込めないアプリになってしまいます。
| バインド | アプリ設定内の ID | 解決方法 | 該当するケース |
|---|---|---|---|
pinned | はい — Space ID とすべての Folder/Node/Base/View ID | そのまま使用。検出は行わない | ワークスペース優先の create と maintain。アプリのひな型を作る前に ID が存在するケース |
runtime | いいえ | inspectProvisionedResources が、付与された resourceKey に基づいて各 Base を照合 | パッケージ優先の create と、インストールされるすべてのテンプレート。誰かがインストールするまで ID が存在しないケース |
resourceKey による解決は、このスキルが禁止する名前とスラッグによる再検出ではありません。
キーはインストール時に付与され、そのインストール済みアプリに固有のものなので、名前が一致するだけの無関係なリソースに紐づくことはありません。これは、禁止によって防ごうとしている失敗です。
この 2 つの方法を適切に使い分けるため、次の 2 つのルールを守ります。
pinnedでは、ID が不足していても検出にフォールバックしてはいけません。 フォールバックすると、明確な設定エラーが、誤ったリソースをひそかに読み書きするアプリに変わってしまいます。不足しているスラッグを示して失敗させてください。pinnedアーティファクトをテンプレートとして公開してはいけません。 テンプレートはインストーラーの Space に新しいリソースを作成しますが、ピン留めされた ID が指すのは作成者のリソースです。公開すると、作成者の Node ID がすべてのインストーラーに渡され、インストールは成功したのにアプリは何も読み込めない、あるいは ID が衝突した場合には他人のデータを読み込んでしまいます。content/<base>/base.jsonはリソースの宣言であり、ピン留めされた ID は作成結果です。結果を宣言として配布するのは、カテゴリーの取り違えです。
したがって、ライフサイクルの流れは一方向だけです。テンプレートを runtime にバインドしてインストールし、その後に限り、そのインスタンスだけをピン留めできます。ピン留めはデプロイメントに対する操作であり、配布物の属性ではありません。
同じルールはスキル自体にも当てはまります。ポインタースタブ、つまりデプロイ済みスキルノードの ID を指定し、使用時にその本文を取得するリポジトリ内の SKILL.md(§「2 つの取り込み方法」)は、デプロイメントに対するピン留めです。これは、1 つのワークスペーススキルを複数のリポジトリで利用する方法であり、テンプレートとして公開することはありません。
参照資料を意図的に読む
選択した参照資料は、作業を始める前にすべて読みます。
| 必要な情報 | 参照資料 |
|---|---|
| インタビューの順序、中止ルール、ブループリントの形式 | references/interview-and-blueprint.md |
| リソースの配置、ネイティブ View、Vault と実行時のセキュリティ | references/resource-model-and-security.md |
SDK、同一オリジンの /api/v1 アクセス、ブラウザーでの読み込み、実データを使ったローカル開発 | references/runtime-and-sdk.md |
| フロントエンドのアーキテクチャ、レスポンシブ UX、状態とテストマトリクス | references/app-engineering.md |
| 構造の作成、AirApp のデプロイ、シード CR、承認ルール | references/deployment-and-review.md |
| 共有シェル、ドメインのカスタマイズ、ローカル環境とターゲット環境での検証 | references/ui-and-validation.md |
| 既存の AirApp の識別情報、リソースと UI の継続的な進化、正規の読み戻し | references/maintenance.md |
パッケージのレイアウト、busabase.json、SKILL.md のフロントマター、検証 — パッケージ優先でファイルを作成する前に必ず読むこと | references/template-format.md |
接続または書き込みを行う前に、必ず隣接する Busabase スキル ../busabase/SKILL.md を読みます。エンドポイントの形式が不明な場合は、ライブの OpenAPI を正式な情報源として扱います。
ワークフロー
1. 実行を開始する
まず、再インストールとcreate/maintainを区別します。完全にビルド済みのAirAppバンドルがディスク上に存在しますか(委任されたApp-in-Skillの<skill-root>/app/、またはその他のビルド済みで以前にレビュー済みのプロジェクトなど)。必要なのは、このSpaceに存在させることだけで、ヒアリングも新しい設計書も必要なく、コードも変更されませんか?その場合は、このワークフローの残りをスキップして、busabase-sdk/airappのpublishAirAppを使用します(references/deployment-and-review.md §「ビルド済みバンドルの再インストール」を参照)。これはprovisionDeclaredResourcesの宣言からFolderを解決し、SpaceにAirAppがまだない場合は作成し、すでにある場合は更新を提案します。また、他のすべての書き込みと同様、権限を考慮して反映します。認証情報にFolderへの書き込み権限がある場合は直接マージし、ない場合はChangeRequestを作成します。ただし、ChangeRequestファイルを1つずつ手作業で構築する必要はありません。この作業が、これまで再インストールのたびにスクリプトではなくエージェントのセッションになっていた理由です。また、「セットアップスクリプトではBasesが作成されただけで、AirAppが作成されなかった」という問題への答えでもあります。そのスクリプトによるデータレイヤーのプロビジョニングでは、同じリクエストにAirAppのデプロイを含めることは想定されていませんでした(airapp.tsのAirAppNodeDeclarationに関する注記を参照してください。実行可能コードは、データレイヤーの構造に関するリクエストとは別のリクエストです)。AirAppが作成されていないことに誰かが気づくまで放置するのではなく、明示的な次の手順としてpublishAirAppを呼び出してください。
それ以外の場合は、すでに明示されている情報のみをスキップし、以下の質問を選択肢に文字を付けて1つずつ尋ねてください。
- 新しいワークスペースアプリを作成しますか、それとも既存のAirAppを保守しますか?
- Busabase CloudとDesktopのどちらにデプロイしますか?
- スタンドアロンのAirAppの場合、生成されたソースを一時ディレクトリと永続ディレクトリのどちらに保存しますか?
委任されたApp-in-Skillの場合は、指定された
<skill-root>/app/プロジェクトルートを記録し、この質問をスキップしてください。 - 検証モードを記録します。委任されたApp-in-Skillの作成では、デフォルトは
target-firstです。local-previewを選択するのは、ユーザーから明示的なリクエストがあった場合に限ります。スタンドアロンの作成では、ユーザーがtarget-firstを明示的に希望しない限り、既存のlocal-previewのデフォルトを維持します。 createでは、workspace-firstとpackage-firstのどちらから始めますか?詳しくは、以下の§「2つの開始方法」を参照してください。maintainでは、この質問をスキップしてください。createでは、AirAppで何を確認または管理できるようにしますか?maintainでは、対象とするSpace、AirAppのノードID、動作/ランタイムの変更内容を正確に確認してください。
Cloudの場合は、busabase-cli loginで選択した接続を使用し、対象のSpaceを確認してください。Desktopの場合は、ローカルのBusabase URLを確認してください。.envの内容やトークン値は決して表示せず、サニタイズ済みの準備状況のみを表示してください。
1a. 2つの開始方法
create には2つの開始方法があります。違いは、ファイルが最初に存在する場所だけです。どちらも同じ完成形にたどり着き、もう一方の検証を省略することはできません。
どちらを選ぶかは、好みではなく、何を作るかで決まります。
-
スキル(skills リポジトリに置くディレクトリ)を作る → パッケージファースト。アプリを含むスキルはテンプレートです。それ以外の方法で作成する場合は、ファイルを書いたあとに Space と照合する必要があります。
-
1つのワークスペース向けのアプリを作り、配布可能な成果物が求められていない → ワークスペースファースト。
-
まだ決めかねている、または形を検討中 → ワークスペースファーストにし、共有する価値があるとわかった場合は最後にエクスポートします。
-
ワークスペースにすでにデプロイ済みのスキルへのリポジトリアクセスを作る(「ほかのリポジトリでも同じスキルを使いたい」) → どちらの方法でもありません。リポジトリごとにコピーをエクスポートしないでください。コピーは互いに乖離します。代わりに、利用する各リポジトリにポインタースタブを書きます。内容は、frontmatter に実際のトリガーとなる
description、以下の取得コマンド、Space/node の表だけを記載した最小限のローカルSKILL.mdにします。npx --yes busabase-cli@latest skills read-file --node-id <id> --file-path SKILL.md --output jsonどちらのフラグにも、それぞれ異なる理由があり、必要です。本文をすべて返すのは
--output jsonです。デフォルトのテキスト出力では1行のプレビューに縮められます。実際のサーバーで測定したところ、40 KB のスキルは省略記号で終わる426バイトで返される一方、JSON 形式ではcontentHashとともに40652文字すべてが返されます。もう一方の問題を防ぐのが@latestです。npxは、サブコマンド自体がない古い CLI をキャッシュから実行することがあります。スタブには ID が固定されるため、上記の
pinnedルールがそのまま適用されます。テンプレートとして公開してはいけません。また、取得に失敗した場合は停止します。エージェントが1行の説明から手順を推測して実行してはいけません。
ワークスペースファースト(形を検討中の場合に選ぶ方法)。以下のワークフローを使って、稼働中の Space で Folder、Bases、AirApp を構築し、実際のデータで動作させます。配布可能にしたいとユーザーが望む場合に限り、そのあとでエクスポートします(§「完成したアプリをインストール可能なテンプレートとして公開する」)。テンプレートは、実際に動作したことが確認できたものを記録したものになります。
パッケージファースト(スキルやテンプレートを作成する場合の方法。新しいアプリスキル、busabase/templates へのコントリビューション、または構築に使う Space がない場合)。最初のファイルを書く前に references/template-format.md を最後まで読んでください。レイアウト、マニフェストと frontmatter の形式、レコード上限、テンプレートが不適格になる条件が記載されています。パッケージをディスク上に作成し、検証のためスクラッチ Space にインストールします。
npx --yes busabase-cli@latest install <path-or-repo-url> --into-folder <scratch>
npx の呼び出しには毎回 @latest を付けてください。付けない場合、npx はすでに見つけた busabase-cli(グローバルインストール、または親ディレクトリ内の node_modules)を実行するため、古い check/install/export が使われることがあります。長い作業ループでは、セッションごとに一度 npm i -g busabase-cli@latest を実行し、その後は busabase-cli をそのまま呼び出してください。
パッケージファーストの作業は、インストールして開くまで完了ではありません。 これは形式だけの手順ではありません。すべての静的ルールに合格していても(バリデーターが成功し、カタログに表示されていても)、アプリ独自のプロビジョニングが壊れていることがあります。パッケージからのインストールでは content/<base>/base.json が読み込まれ、アプリ自身がプロビジョニングに使う宣言は検証されないためです。実際にまったく同じ不具合が一度リリースされました。アプリの設定から Base のスラッグが抜けていたため、テンプレートは問題なくインストールできたものの、アプリは独自のテーブルを作成できませんでした。実際にインストールして開いて初めて、この問題が見つかります。
どちらの方法でも、このドキュメントのほかのすべてのルールに従ってください。パッケージファーストだからといってランタイム契約を無視した AirApp を手書きしてよいわけではありません。また、ワークスペースファーストだからといって、SKILL.md を一度も書いていないテンプレートを出荷してよいわけではありません。
2. モード別のルーティング
maintain の場合は、references/maintenance.md をすべて読み、指示に従ってください。正規のアプリを起点とし、承認済みの変更範囲外はすべてそのまま維持してください。承認済みのイテレーションでは、関連するリソース、スキーマ、データ、ファイル、UI の作成、更新、移動、削除が可能です。作成専用の独立ワークスペースのワークフローを続けてはいけません。
create の場合は、手順 3〜9 に進んでください。すべての分離およびブループリント承認ルールは引き続き必須です。
手順 3〜9 は、ワークスペース優先の表現で記述されています。パッケージ優先ルートでも同じ手順を適用しますが、書き込み先が変わります。規律はそのまま引き継がれますが、API 呼び出しは検証インストールまで行いません。
| 手順 | ワークスペース優先で行うこと | パッケージ優先で行うこと |
|---|---|---|
| 3–4 発見、ブループリント | 同一 — インタビューと承認済みブループリントに変更はありません | 同一 |
| 5 構造を作成 | Space に Folder/Bases/Views を作成 | busabase.json、content/_folder.json、content/<base>/base.json を書き込む |
| 6 AirApp の足場を作成 | 足場を作成してからデプロイ | content/<name>-app/ に足場を作成(_node.json を含む。テスト/ロックファイル用の .busabaseignore も作成) |
| 7 検証 | ローカルチェック + UI 受け入れ | ローカルチェックは同一。UI 受け入れは手順 9 のスクラッチインストールで実施 |
| 8 ChangeRequest としてデプロイ | AirApp の CR を送信 | 何もしない — 手順 9 のインストールで提案されます |
| 9 シードして検証 | CR をシードし、マージ済み HEAD を実行 | records.ndjson を書き込み(Base あたり ≤50)、busabase-cli index . --repo <owner/repo> -o templates.json を実行してから、busabase-cli install でスクラッチ Space にインストールし、マージして、アプリを開き、データを読み戻す |
マニュアルは最後にまとめてではなく、作業しながら書いてください。このルートでは SKILL.md を直接作成します(エクスポート元となる Skill ノードはありません)。また、実際に content/ に含まれるリソースだけを記載する必要があります。
3. プロダクトを把握する
references/interview-and-blueprint.md の選択肢優先のインタラクション契約に従ってください。以下が判明するまで、アルファベット付きの質問を一度に 1 つずつ続けてください。
- アプリ名と、実現することを一文で表した内容
- 対象ユーザーと、繰り返し発生する業務
- 業務オブジェクトとその関係
- ネイティブの成果物:Views、Docs、ファイル、Whiteboards、Forms、Workflows、HTML のいずれか
- ライフサイクル/ステータスの値と重要な日付
- 最初の画面、リスト/詳細ビュー、指標、フィルター、検索
- Base ごとの詳細モード(
ui.detail_modes):レコード自体が作業場所となる場合(関連リスト、長いコンテンツ、共有リンク)はpage、ユーザーが多数のレコードを確認し、1〜2 個のフィールドを操作する場合はdrawer、1 件ずつ処理するキュー形式のビューにはsplitを指定します。 - 人による対応が必要な状態
- ChangeRequest を生成する小さな操作が必要かどうか
- 外部連携に信頼された Workflow/Agent と、名前を指定した Vault 要件が必要かどうか
- ブランド上の制約、または控えめな業務スタイルを推定してよいか
ユーザーにテーブルの設計を求めないでください。ユーザーの説明を、最小限で一貫性のあるモデルに落とし込んでください。モデルの規模が大きい場合は警告し、ユーザーが広い範囲を確認した場合は、その選択を尊重してください。
4. 承認用ブループリントを提示する
機械可読な blueprint.json を作成し、ユーザーに簡潔な人間向けの概要を提示します。概要には次の項目を含めます。
- ユーザーストーリー。
- ページとナビゲーションのマップ。
- Bases、ネイティブ Views、Docs、Drives、任意のノードを含むフォルダー/リソースのグラフ。
- フィールド、型、必須値、選択肢、View の設定。
- シードレコードと初期アーティファクトの概要。
5a. ノードごとのシナリオ一覧 — 各ノードでエージェントに何を依頼できるか。
ユーザーストーリーで繰り返し発生する作業と、先ほど記述した Actions の許可リストから導きます。別の語彙を作り出してはいけません。各シナリオは、ユーザーが実際に言う表現(「顧客訪問を記録する」など)で 1 行にまとめ、該当するノードごとにグループ化します。これは手順 5 で各ノードの
agentPromptsとなるものであり、承認の対象に含めます。「何を依頼できますか」は、ユーザーが実際に承認する内容だからです。 - 手順の実行能力マトリックス、画面ごとのデータ予算、アクションの許可リスト。
- Vault の要件名と信頼された実行所有者。シークレット値は記載しません。
- 製品オンボーディングのバージョン、必須フィールド、Busabase の完了リソース、検証、ロック解除される機能。または、根拠を添えた明示的な空の契約。
- 明示的な除外事項とリスク。
実行します。
node <skill-dir>/scripts/airapp-kit.mjs validate-blueprint --blueprint <path>/blueprint.json
ブループリントについて、承認、修正、停止のいずれかを明示的に判断するよう求めます。承認前にリモートの構造を作成してはいけません。
5. 承認された構造を作成する
承認後:
- 対象の Space/workspace を再読み込みし、スラッグの衝突を確認します。
- 一意のスラッグを生成し、既存の一致するノードを再利用してはいけません。
- ブループリントに含まれる Folder、Bases、フィールド、リレーション、ネイティブ Views、Docs、Drives、承認済みの任意のリソースを作成します。
新しい Base には、スキップしない限り、すべてのレコードとフィールドを含むデフォルトの「Grid view」が作成され、Base は一番左の View を開きます。そのため、ブループリントで Base に独自の Views を指定する場合は、
--skip-default-view(node_createのskipDefaultView、REST のdefaultView: false)を指定して Base を作成し、その後、ブループリントの順序で Views を作成します。最初の View が Base を開いたときに表示されるものであり、後からexport --templateすると、これらだけが正確に含まれます。ブループリントで Base に Views を指定しない場合は、デフォルトの Grid view を残し、他と同様にそのview_idを記録します。Base には常に 1 つの View が必要です。 autoMergeは省略します。ユーザーはこの正確な構造を承認しているため、認証情報でマージ可能なものはすべて今ここでマージされます。リスクがあると判断した手順に限り、明示的にautoMerge: falseを渡します(上記のスコープルールを参照)。- 実体化されたリソースを読み戻し、足場作成の前に、すべての Folder/Node/Base/View/リソースの ID を
blueprint.jsonに書き込みます。 - **ノードが作成された時点で、そのノードの
agentPromptsを書き込みます。**承認済みブループリントのシナリオ一覧(手順 4、項目 5a)に基づきます。形式、CLI 呼び出し、記述基準については手順 10 を参照してください。ノードを開いた人が何を依頼できるかを確認できて初めて、そのノードは「作成済み」となります。これを最後まで先送りすると、すでに見なくなったアプリの記憶を頼りにプロンプトを書くことになります。
返されたステータスが実体化/マージ済みでない場合は、構造が存在するかのように装わず、処理を停止して CR を報告します。
6. AirApp のスキャフォールドを作成してカスタマイズする
最新の SDK バージョンを解決してスキャフォールドを作成します。
node <skill-dir>/scripts/airapp-kit.mjs scaffold \
--blueprint <path>/blueprint.json \
--output <chosen-source-dir>
委譲型 App-in-Skill の場合、<chosen-source-dir> は厳密に <skill-root>/app/ です。したがって、生成されたプロジェクトは <skill-root>/app/package.json に配置され、ブラウザー用ファイルは <skill-root>/app/app/ に配置されます。この入れ子の名前は意図的なものです。外側のディレクトリはスキルにバンドルされたプロジェクトで、内側のディレクトリは AirApp の静的ファイルツリーです。スキャフォールドは引き続き、空でないディレクトリへの上書きを拒否します。既存の正規プロジェクトを更新する場合は、無条件に置き換えるのではなく、保守モードを使用してください。
スキャフォールドは、実体化されていないブループリントを拒否します。テスト済みの Hono/バニラのシェルをコピーし、解決済みの SDK(0.99.0 以降)を固定し、正確な Folder/Node/Base/View/リソース ID と、シークレットではない Vault 要件をデプロイ設定に書き込み、依存関係をインストールし、SDK クライアントのエクスポートとブラウザー用 AirApp ヘルパーを検証し、ブラウザーバンドル(クライアント用の app/vendor/busabase-sdk.js、AirApp ヘルパー用の busabase-airapp.js、接続ゲート用の busabase-airapp-gate.js)を作成し、ロックファイルを作成します。Nodepod がビルドツールを実行しないよう、これらのバンドルはレビュー済み AirApp ソースの一部です。生成されたドメイン UI とプロジェクションを、承認済みブループリントに合わせてカスタマイズしてください。本番モードに汎用的なプレースホルダーラベルやデモ用エンティティを残さないでください。
プロバイダーは分離してください。
- デモプロバイダー:ローカル UI データの決定的な提供のみを行います。
- Busabase プロバイダー:SDK を使ってアプリ自身のオリジン上の
/api/v1にアクセスし、承認済みの正規リソースと保留中の CR サマリーのみを扱います。SDK を通じてcreateAirAppRecordsでレコードを読み書きし、アプリ固有のルール(手続きの許可リストや、レコードを UI の行にマッピングする方法など)のみを保持します。Vault を公開したり、暗黙にデモデータへフォールバックしたりすることはありません。
また、スキャフォールドは change_request 種別の各ブループリントアクションを、開いているレコード上の小さなフォーム(ui.actions[].fields、編集可能なフィールド型のみ)として表示し、変更が保存されたのか、レビュー待ちなのかをユーザーに伝えます。読み取り専用アプリでは、これらを一切表示しません。別の実装を作成せず、この処理を拡張してください。この処理が編集するのは開いているレコードのみです。意図的に**「新規レコード」フォームはありません**(references/runtime-and-sdk.md の § Optional Actions を参照)。承認済みブループリントで必要な場合は、追加してください。
ローカル Hono スキャフォールドには、references/runtime-and-sdk.md に記載された OAuth ルートとプロキシの契約も含める必要があります。生成されるセットアップ画面ではラベルやレイアウトをカスタマイズできますが、createBusabaseAirAppLocalGateway() を使用し、その契約はループバックのドキュメントオリジン上でのみ呼び出してください。別のトークンストアを実装したり、認証情報をブラウザーの JavaScript に送信したりしてはいけません。AirApp では、ローカル接続画面を表示したり、/auth/status や /auth/start を呼び出したりしないでください。
UI ではデータアクセスの上限を明示してください。各 Base はブループリントの read_limit(デフォルトは 50、許容範囲は 1~50)と、生成された設定の readLimit を使用します。表示する保留中の ChangeRequest は、引き続き 20 件までに制限します。続きの取得は毎回、上限付きのページを 1 つだけ取得します。nextCursor が存在する場合は + などで示し、すべてのページを隠れて取得するループではなく、「さらに読み込む」機能を用意してください。検索とフィルターでは、読み込み済みの行に対して適用されることを明示するか、デバウンス付きのサーバーフィルターによるページクエリを実行してください。Base 全体を暗黙にスキャンしてはいけません。
7. 検証して UI の承認を得る
必ず次を実行してください。
pnpm check # node runtime
node --check server.js # node runtime
node scripts/check.mjs # python runtime (no package.json, so no `pnpm check`)
python3 -m py_compile server.py # python runtime
pnpm check はスキャフォールド独自のゲートです。アプリをパッケージまたはテンプレートに含める場合は、そのパッケージに対してプラットフォームのチェッカーも実行してください。その airapp レイヤーは、同じ契約(ランタイム検出、上限付き読み取り、および true というリテラル値ではない autoMerge に対する airapp/forced-review)を適用します。
npx --yes busabase-cli@latest check <package-dir>
1 つのワークスペースの ID に固定されたアプリ(workspace-first)は、テンプレートとして公開できません。そのため、そこで package/workspace-ids の指摘が出るのは想定どおりです。airapp レイヤーを確認してください。
Python AirApps
同じスクリプトに --runtime python を指定して、アプリをスキャフォールドします。
node <skill-dir>/scripts/airapp-kit.mjs scaffold --blueprint <path>/blueprint.json \
--output <chosen-source-dir> --runtime python
python アプリには airapp.json、server.py、Node アプリと同じ app/ サブツリーが含まれます。package.json は含まれません(Busabase はこれがあると Node アプリとして読み込むためです)。Busabase が読み込める npm スクリプトがないため、アプリ自身でコマンドを宣言します。
{ "runtime": "python", "install": "…", "start": "python3 server.py" }
port は宣言しないでください。指定しない場合、ホストエンジンは PORT で空いているポートをアプリに割り当て(server.py が読み取ります)、listening on port N という行からポートを検出します。3000 を固定すると、そのマシンで 2 つ目に起動する Python アプリや、すでに 3000 番ポートを使っている別のアプリが Address already in use で終了します。
ブラウザー側には、Node アプリと同じ 3 つのバンドルが必要です。 app/index.html と app/js/ は、読み込み時に app/vendor/busabase-sdk.js、busabase-airapp.js、busabase-airapp-gate.js をインポートします。Python アプリには build:sdk を実行するための package.json がないため、スキャフォールドでは一時ディレクトリ内でテンプレート自身の build:sdk スクリプトを使ってバンドルをビルドし、app/vendor/ にコピーします。これらがないと、アプリは空のページとして開き、手がかりとなるのはゲートバンドルの 404 だけです。node scripts/check.mjs は、これらが存在しない場合にエラーを返すようになりました。
Python AirApp はホスト環境専用であり、これは回避すべき不足ではありません。 server.js の /auth/* ルートと認証情報を使う /api/v1 プロキシは、busabase-sdk のローカル AirApp OAuth ゲートウェイによって提供されます。これらは、Busabase の外部で実行されるアプリが独自の認証情報を取得できるようにするものです。このゲートウェイは意図的に Python では再実装していません。認証フローを別の言語に移植すると実装間に差異が生じ、その差異はセキュリティ境界に関わるためです。
Busabase 内では不足はありません。ブラウザーからの /api/v1 呼び出しは同一オリジンで行われ、閲覧者のセッションが付与されるため、ゲートウェイは関与しません。単独で実行すると、接続ゲートが表示され(Node アプリの場合と同様です)、server.py は /auth/* に対して単なる 404 ではなく説明を返します。アプリを独自の認証情報で単独実行する必要が本当にある場合は、node で作成してください。
続いて、references/ui-and-validation.md で選択した検証モードに従ってください。
target-first の場合、pnpm dev を起動せず、localhost の URL も報告しないでください。静的チェックと承認済みブループリントがあれば、権限を考慮した方法で AirApp を作成することが許可されます(ステップ 8)。デスクトップ、スマートフォン、操作性、アンビエントセッション、実データの受け入れ確認は、ステップ 9 でマージ済み HEAD に対して行います。その Run が完了するまでは、レポートに UI の受け入れ確認が未完了であると記載してください。
local-preview が明示的に選択されている場合は、pnpm dev を実行し、実際のローカル URL を ?demo=1 付きで開いてから、デスクトップと幅 390px のモバイルレイアウトを送信前に確認してください。
local-preview モードでは、送信前に実際のデータで確認してください。?demo=1 を付けずにローカル URL を開き、Busabase Cloud を選択するか、カスタムの Busabase オリジンを入力して、ブラウザーの OAuth フローを完了します。この対話型の方法では、CLI へのログイン、デバイスコード、API キーの貼り付けを求めないでください。
環境のブートストラップは、非対話型 CI およびオペレーターによる明示的なテストでも引き続き利用できます。
BUSABASE_BASE_URL=http://localhost:15419 pnpm dev # Desktop / OSS
BUSABASE_BASE_URL=https://busabase.com \
BUSABASE_API_KEY=… BUSABASE_SPACE_ID=… pnpm dev # Cloud
設定済みの Bases が実データを返すことを確認してください。対話型のローカル経路では、委任された API 権限の付与を通じてユーザーを認証します。一方、デプロイ済みの AirApp は閲覧者のアンビエントセッションを使用するため、ステップ 9 の target Run では、この異なる権限と埋め込みの経路を引き続き検証します。
local-preview モードでは、送信前にユーザーが UI を明示的に承認するまで反復してください。target-first モードでは、target Run ごとに反復します。各修正は独自の AirApp ChangeRequest であり、権限を考慮した同じ方法で作成されます。
8. ChangeRequest を通じて AirApp をデプロイする
新しい Folder に、完全に検証済みのファイルツリーと mergeMode: "replace" を指定して、新しい AirApp を作成します。autoMerge は省略して結果を読み取ります。Folder への書き込み権限を持つ認証情報の場合はアプリがそのまま公開され、権限がより限定的な認証情報の場合は保留中の ChangeRequest になります。どちらも正しい結果として報告してください。検証が target-first と local-preview のどちらだったかを記録します。
結果を報告してください。マージされた場合は AirApp のノード ID、担当者の対応待ちの場合は CR ID を伝え、主なセキュリティ上の事実も伝えます。
- デプロイされたアプリは、閲覧中のユーザーのブラウザーセッションとして認証されます。
- API キーは埋め込まれていません。
- 一覧に記載された読み取りプロシージャ。
- 一覧に記載された ChangeRequest を生成するプロシージャ(該当する場合)。
- 正規データへの直接変更はありません。
マージされた場合は、すぐにステップ 9 に進みます。認証情報ではマージできないため保留中の場合は、Folder の書き込み権限を持つユーザーの対応が必要であることを伝えてください。ユーザーからその特定の CR の承認を依頼されない限り、自分で承認してはいけません。シードレコードは AirApp に依存しないため、待機中でも引き続き作成してください(ステップ 9)。AirApp がマージされるまで待つ必要があるのは、対象の Run だけです。
9. 実データをシードし、検証する
他のすべてと同様に、権限を考慮しながら ChangeRequest を通じて、現実的なレコードを 3 ~ 5 件作成します。リレーションの依存関係を守ってください。ライブ API が一時レコード参照を明示的にサポートしている場合を除き、子レコードのリレーションに正規 ID を使う前に、マージ済みの親レコードを読み取ってください。
AirApp とシードレコードがマージされたら(自分で書き込んだもの、またはキューに入ったものを担当者が処理した後)、次のことを行います。
- 正規レコードを読み取ります。
- 対象の Busabase で、マージ済みの AirApp をユーザーに Run してもらいます。
- 選択したデプロイ方法、Base の検出、データが空でないこと、空状態、ブラウザーコンソール、デスクトップレイアウト、390px のスマートフォンレイアウトを検証します。target-first モードでは、これは必須の最初の UI 受け入れゲートであり、localhost の受け入れ確認後に行うものではありません。
- ブリッジ、セッション、スペース、スキーマの各エラーを個別に診断します。
保留中の AirApp CR は実行できません。マージ済みの HEAD が実際に実行される前に、対象環境での検証が完了したと主張してはいけません。
10. マニュアルとプロンプト — 形を整え、最後に確認する
このステップで行うのではなく、作業全体を通じて作成します。アプリの形が整うにつれてスキルノードを作成し、各ノードのプロンプトはそのノードの作成時に作成します(ステップ 5、項目 6)。このステップでは、それらの形を定義し、作業完了を宣言する前に見落としがないか最後に確認します。
インストールに必要なのはリソースだけではありません。もう半分は、専門知識がない人がそれらをどう使うかであり、2 か所に記述されます。
Folder のスキルノード。 Folder 内に skill ノードを 1 つ作成し、アプリと同じ名前を付けます。Bases の意味、各フィールドの用途、ワークフロー、そしてアプリが決して行ってはいけないことを記載します。パッケージ優先の場合、これはインストーラーがそのノードに取り込むルートの SKILL.md です。ワークスペース優先の場合は、ノードを直接作成します。$busabase は、すべてのエージェントに、その Folder への書き込み前にこれを読むよう指示します。つまり、アプリを自走可能にする唯一のドキュメントです。Folder には複数のスキルを置けます。各ノードの名前は、そのスキルの frontmatter の name と同じにしてください。
すべてのノードにシナリオプロンプトを作成する。 これらをここで考案するのではありません。ブループリントでユーザーがすでに承認した、ノードごとのシナリオ一覧(ステップ 4、項目 5a)を完全な形で書き出します。各 Base、Doc、AirApp、Drive に、それぞれに該当するものを設定します。
シナリオの出どころ。 ブループリントの User Story には 1 つの対象ユーザーと、繰り返し発生する 1 つの業務が記載され、Actions allowlist にはアプリが実行できる操作が記載されています。シナリオとは、その交差点、つまりその対象ユーザーがこのノードを使って頻繁に行うことです。As a sales rep, I want to keep visit notes with the account と Visits Base の組み合わせなら、「顧客訪問を記録する」「今四半期にこのアカウントについて話し合った内容をすべて表示する」といったシナリオになります。候補のプロンプトをストーリーにたどって結び付けられない場合、そのプロンプトはこのアプリに属していないか、ストーリーが不完全です。プロンプトの一覧ではなく、ストーリーを修正してください。
基準。 プロンプトが価値を発揮するのは、その人が望んでいることを本人の言葉で伝え、エージェントが操作方法を判断しなければならないときです。陥りやすい失敗パターンは次の2つです。
| ❌ | ✅ | 理由 |
|---|---|---|
| "Create a record in Visits" | "Log a customer visit" | 1つ目は Base 名を貼り付けた API であり、ノードタイプに組み込まれたプロンプトですでに対応しています。 |
| "Update the status field to closed-won" | "Mark this deal as won and note why" | 1つ目は、どの列に書き込むかをエージェントに指示しています。2つ目は何が起きたかを伝えています。これはスキルのワークフローが担う役割です。 |
| フィールドごとに1つのプロンプト | ノードごとに、繰り返し発生する作業向けのプロンプトを2~5個 | スキーマと同じくらい長いプロンプト一覧は、尋ねる価値のある項目のメニューではなく、スキーマそのものです。 |
ノードごとに2~5個作成してください。2個未満の場合、そのノードに固有の役割がなく、プロンプトは親に配置すべきであることがほとんどです。5個を超える場合、フィールド単位の操作が混入していることがほとんどです。
すべての本文はスキル名を明示して始めます。
Read the `crm-visits` skill in this folder and follow its workflow, then add a visit record with
today's date, the contact I name, and a one-line summary.
タスクだけを記述してください。Busabase はすべてのプロンプトの先頭に、そのノードを示す文を追加します。—Target: the Busabase Base "Visits" (nodeId: nod_…), in space "Acme" (spaceId: spc_…).—組み込みプロンプトの先頭にも同じ文が付くため、{target} は記述しないでください。古い本文に残っていても引き続き機能します。{target} だけの行は削除され、文中にある場合はノード名として扱われます。
CLI で作成してください。送信前に検証されます。
npx --yes busabase-cli@latest nodes set-agent-prompts --node-id <nodeId> --file prompts.json
prompts.json は { key, label, body, intent? } のリストです。label はユーザーがリストから選ぶ項目です(≤80 chars)。body はエージェントが受け取るタスクで、Busabase が前に追加するノード/スペースのターゲット行の後に続きます。intent は read-only または change です(既定値は change)。
上限:ノードごとにプロンプトは50個、ロケールごとに本文は8 KiB です。アプリが多言語対応の場合、label と body はどちらも i18n オブジェクト({ "en": "…", "zh-CN": "…" })を受け付けます。
パッケージを優先し、エクスポート → インストール後も維持されるよう、同じリストを各ノードのサイドカー(_node.json、_folder.json、base.json、file ノードの .node.json、または Doc のフロントマターにある agentPrompts)にも書き込んでください。スキルノードがないパッケージや、プロンプトのないノードがある場合は、busabase-cli check が警告します。
最終確認。 完了基準に照らして確認する前に、Folder のノードを一覧にし、それぞれについて、API ではなく人が自分の仕事として認識できるプロンプトがあることを確認してください。パッケージを優先し、busabase-cli check を実行して、template/node-without-prompts の警告を無視せず、やるべきことの一覧として読み取ってください。この確認で何も設定されていないノードは、定義のステップ5の後半を行わずに作成されたものです。実際にできあがったノードを対象に、プロンプトを作成してください。
完了条件
create の場合は、以下のすべてを満たしたときにのみ完了です。
- 承認済みの Folder、Bases、Views、アーティファクト、および任意のリソースが、選択した Cloud Space またはデスクトップワークスペースに存在すること。
- AirApp のソースがチェックに合格し、マージ済み Busabase HEAD でのターゲット優先の受け入れ確認、または明示的に選択したローカルプレビューでの受け入れ確認後のターゲット Run のいずれかが完了していること。
- AirApp の書き込みが反映されていること。つまり、マージが完了しているか、その認証情報ではマージできなかったため ChangeRequest として残されていること。また、結果を推測で済ませず、読み戻していること。
- 正規のシードレコードを読み戻していること。
- Folder にアプリ名の
skillノードがあり、この実行で作成したすべてのノードに、そのスキル名を本文に含むシナリオエージェントプロンプトが設定されていること。各プロンプトが、承認済みブループリント内のシナリオ(ステップ 4~5、形式はステップ 10)に追跡可能であること。 - マージ済み AirApp が、ターゲット環境の実データに対して実行されること。
- ランタイム設定に、実体化された Folder/Node/Base/View/リソースの正確な ID と、シークレットではない Vault 要件が含まれていること。また、対話型の読み取りパスがすべて上限付きで適切にフィルタリングされ、ページネーションが明示されていること。
- ファイル、ログ、スクリーンショット、チャットにシークレットが一切含まれていないこと。
- ローカルの対話型認証で PKCE と AirApp ごとの所有者限定登録(
~/.busabase/airapps配下)を使用し、CLI ログインもブラウザー上で確認できる認証情報も不要であること。 - 実際のノード URL、CR ID、ソースディレクトリ、SDK バージョン、残っている制約を報告していること。
- App-in-Skill クリエイターから委任された場合、委任元スキルの AirApp プロジェクトルート(
<skill-root>/content/<name>-app/、または未移行のスキルでは<skill-root>/app/)が正規のローカルプロジェクトとして維持されること。pnpm devが引き続きサポートされ、デフォルトでは起動されず、マージ済み AirApp が同じレビュー済みソースツリーに追跡可能であること。
package-first の create 実行では、さらに以下を満たす必要があります。パッケージが警告なしでスクラッチ Space にインストールされること、その AirApp がそこで開き、実データを読み取れること、SKILL.md にパッケージが実際に同梱するリソースのみが記載されていること、スクラッチ Space でインストール済みノードを開いたとき、作成者が設定したプロンプト(ノードタイプのデフォルトではない)が表示されること。バリデーターの合格は前提条件であり、完了条件ではありません。
maintain の場合は、references/maintenance.md に記載された別の完了条件を使用してください。
完成したアプリをインストール可能なテンプレートとして公開する
ユーザーから依頼された場合に限ります。1 つのワークスペースで動作するアプリが成果物です。テンプレート化は、「誰でもこれをインストールできる」ようにするための追加ステップです。
パッケージのレイアウトを手書きしないでください。作成して動作を確認したアプリをエクスポートしてください。そうすれば、公開するテンプレートは、そのアプリを別の形で説明したものではなく、実際に動作したものになります。
npx --yes busabase-cli@latest export <folder-slug> -o ./<name> --template
これにより、Template Center が読み込むレイアウトが書き出されます。フォルダーの Skill ノードをパッケージのルートに移した SKILL.md、カタログのメタデータを含む busabase.json、そして content/ の下にあるリソースです。Base のスラッグは、ワークスペースでプレフィックスを付けてインストールされた名前ではなく、アプリで宣言された名前で戻ります。フォルダーに Skill ノードがまだない場合は、その構造から SKILL.md の草案が生成されます。意図的に TODO だらけです。エージェントはそのファイルに書かれた内容に基づいて動作するため、テーブルの意味についてもっともらしく推測するより、明らかな空欄のほうが望ましいからです。ユーザーと一緒に内容を埋めてください。
プルリクエストを作成する前に、チェックしてください。
npx --yes busabase-cli@latest check ./<name> --strict # the contract
npx --yes busabase-cli@latest index . --repo busabase/templates -o templates.json --check # the catalog
cd templates/<name> && node scripts/sync-content.mjs --check # only if it has one
check はディレクトリに対して上記のルールを読み込み、該当する各レイヤー(package、skill、template、airapp)を個別に報告します。該当しないレイヤーは ✓ ではなく – と表示されます。これは静的チェックです。何もインストールされず、テンプレート独自のコードも実行されません。そのため、提出前だけでなく、作成中に繰り返し実行するチェックとして使用してください。エラーはインストールするユーザーに支障をきたすものです。警告はレビューで正当性を確認する価値のあるデフォルト設定であり、--strict を指定すると警告でも失敗します。リポジトリのルートを指定するとすべてのテンプレートを一括チェックでき、アプリの作業中は --only airapp を、CI では --json を指定します。
2 つ目のコマンドは別の問い、つまりリポジトリのカタログファイルが最新かどうかに答えるものです。一方を実行しても、もう一方を実行したことにはなりません。
テンプレートは、https://github.com/busabase/templates へのプルリクエストで提出します。このリポジトリの AGENTS.md には、そのリポジトリ独自の規約(テンプレートの配置場所、生成されるもの、テンプレートとして認められない条件)が記載されています。PR を作成する前に読み、ここで内容を繰り返したり、上書きしたりしないでください。
停止条件
次の場合は作業を停止し、指示を求めてください。
- 対象の環境または Space が曖昧な場合
- 認証を利用できない場合
createでユーザーがブループリントを承認していない場合- 要求された操作が ChangeRequests を迂回することになる場合
- ライブ API の動作がこの Skill と矛盾する場合
- SDK に
createBusabaseClientがない場合、または Nodepod の検証に失敗する場合 - マージ後に Cloud/Desktop Run を検証できない場合
maintainで、デプロイ済みのツリーがビルド出力のみで構成され、生成元が含まれておらず、どこにもソースが見つからない場合 —references/maintenance.mdの「Is There Source Here At All?」を参照してください。