create-railcode-app について
Railcodeを使うエージェント向けに、アプリの開発と保守を案内するスキルです。CLIの更新、アプリ世代、コネクター、移行、破壊的変更を扱い、作業前に現行情報を確認します。
主な機能
- 01CLIとスキルの更新確認
- 02アプリ世代の判別
- 03コネクター移行の案内
- 04破壊的変更の調査
- 05フィードバック報告手順
活用シーン
- 01Railcodeアプリの新規作成
- 02既存アプリのコネクター更新
- 03デプロイ後の回帰問題の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ railcode-hq/ railcode-skills --skill create-railcode-appインストール後、Claude Code で/create-railcode-appを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlreferences/app-patterns.mdcli-workflow.mddeployment.mdmigration.mdv1-legacy.mdworker-sdk.md詳細
Railcode アプリを作成する
まず更新する
Railcode に関する質問に回答したり、railcode コマンドを実行したりする前に、Railcode のスキルと CLI を更新し、npm の公開バージョンを確認してください。
npx skills add Railcode-HQ/railcode-skills
npm install -g railcode@latest
railcode --version
npm view railcode version
スキルに変更があった場合は、このファイルを先頭から読み直してください。npm に接続できない場合は、その旨を伝え、ガイダンスが最新だと主張しないでください。このバージョンは、CLI 0.3.10 と @railcode/sdk 0.5.1(どちらも 2026-10-28 に公開済みであることを確認済み)を基準にしています。
このドキュメントが前提とする最低バージョンは 0.3.0 です。 個人用コネクターが railcode connector に統合されたのはこのバージョンです(破壊的変更を参照)。古いバイナリには connector link/add-mcp/share サブコマンドがなく、railcode personal-connectors がまだ存在します。そのコマンドが動作する場合は、このガイダンスの対象外となる CLI を使っています。以下の手順に従う前に、再インストールしてください。
ユーザー単位のコネクターには CLI 0.3.9 と @railcode/sdk 0.5.0 が必要です。 古い SDK では ApiError.connectionRequired が undefined となり、connector().connection() も存在しません。古い CLI では railcode connector connect/status/link --per-user は不明なコマンドです。プラットフォーム側の機能はすでに有効なため、SDK 0.4.0 を使うアプリでも 409 は受け取りますが、detail.code を手作業で解析する必要があります。アップグレードを推奨します。
CLI はメジャーバージョンの範囲内で自動更新されます。ただし、対話型ターミナルでのみ更新されます。エージェントによるセッションは非対話型なので、最新だと決めつけず、上記の npm install -g railcode@latest を明示的に実行し続けてください。
Railcode に関するフィードバックを報告する
Railcode で重要な作業を行った後、具体的な製品フィードバック(バグ、使いづらさ、提案、特にうまくいった点)がある場合は、非公開の railcode agent-feedback コマンドを使ってください。異なる発見事項ごとに 1 回送信してください。タスク、期待した動作、実際の動作、および回避策を簡潔に記述し、認証情報、非公開の顧客データ、ソースファイル、会話の記録は含めないでください。
railcode agent-feedback --message "Deploy failed with an unclear error; expected the missing field to be named." \
--category friction --command "deploy" --context "Static app deploy; corrected the manifest to unblock."
用意したレポートを送る場合は --file <path> を使うか、--message の代わりに標準入力からテキストをパイプしてください。メッセージの上限は 10,000 文字です。--context は任意で、上限は 5,000 文字です。カテゴリは bug、friction、suggestion、praise、other(デフォルト)です。任意で --agent を使ってアシスタント/ツール名(例:Codex や Claude Code)を、既知の場合は --model を使ってモデル名を自己申告できます。これらは自己申告であり、正確でない可能性があります。不明な値は推測せず、省略してください。これらのフィールドと --command は、それぞれ 200 文字までです。
CLI はバージョン、OS プラットフォーム、CPU アーキテクチャ、Node のバージョンを添付します。バックエンドはレポートを PostHog 上のログイン済みユーザーと組織に関連付けます。既存のログインが必要ですが、アプリのディレクトリ外でも動作します。Feedback accepted. はベストエフォートで受け付けたことを示すものであり、保存が確認されたことを意味しません。報告に失敗した場合は、繰り返し再試行したり、フィードバック送信だけを目的にログインしたりせず、元の作業を続けてください。
このコマンドは意図的に CLI のヘルプに表示されず、CLI 0.3.3 以降が必要です。古い CLI では Unknown command が返る場合があります。その場合は利用できないものとして扱ってください。
破壊的変更
すでに利用されているアプリやエージェントに影響し、そのままでは動作しなくなるプラットフォーム変更を、新しい順に記録します。以前は動作していたものが動かなくなったとユーザーから報告された場合は、デバッグする前にここを読んでください。プラットフォーム独自のエラーメッセージには修正手順が記載されており、以下の項目には、それを受けてどう対応すべきかが書かれています。既存のアプリが変更なしでは動作しなくなる変更がリリースされたら、ここに項目を追加してください。
公開アプリ — CLI 0.3.10、@railcode/sdk 0.5.1(破壊的変更ではありませんが、1 つのルールが逆になります)
オーナーまたは組織管理者は、アプリを公開できるようになりました(railcode apps set-access <app> --public on、またはインスタンスで利用できる場合はアクセスページから設定できます)。ゲストの場合も cron の場合も、ctx.user は null になります。そのため、「呼び出し元が null ならスケジューラー」というルールは当てはまらなくなります。ctx.isGuest または ctx.trigger を使用してください。有効にする前に、メンバー限定のルートを制限してください。詳しくは
app-patterns.md を参照してください。
ユーザーごとのコネクター — CLI 0.3.9、@railcode/sdk 0.5.0(破壊的変更ではありませんが、2 つのルールが逆になります)
コネクターをユーザーごとに設定できるようになりました。名前は 1 つで、独自の認証情報は持たず、各メンバーがそれぞれのアカウントを接続します。connector("granola").call(…) の動作は変わりませんが、呼び出し元が接続していない場合、またはこのアプリを承認していない場合に、409 connection_required を返すことがあります。この機能のリリースに伴い、次の 2 つの説明は条件付きになりました。
- 「接続フローを作らないでください。」(下記の移行表)。共有コネクターと所有コネクターでは、引き続きこの説明が当てはまります。ユーザーごとのコネクターでは、アプリがブラウザーを転送します。ただし、転送先はプラットフォームの接続ページ
err.connectionRequired.connectUrl(および&return_to=)であり、独自の OAuth URL ではありません。 - 「cron が使えるようになりました。」(worker-sdk.md → コネクターの個人所有)。共有コネクターと所有コネクターでは使えます。ユーザーごとのコネクターは cron 実行時に呼び出し元が存在しないため、
connector_needs_userを返します。
既存の動作に変更はありません。共有または所有の行は、これまでどおり動作します。worker-sdk.md → ユーザーごとのコネクター と cli-workflow.md → ユーザーごとのコネクター を参照してください。
パーソナルコネクターは廃止されました — CLI 0.3.0、@railcode/sdk 0.4.0
personalConnections と personal_connectors: マニフェストキーは削除されました。コネクターは、connectors: の下に宣言する、オーナーとアクセスモードを持つ組織リソースの1種類になりました。共有チーム認証情報を保持する場合も、個人のアカウントを保持する場合も同じです。所有者付きの行は、共有されるまでは restricted(オーナー、管理者、共有相手のみがアクセス可能)です。
表示される内容
personalConnections.*を呼び出す v1 アプリまたは v2 ワーカーには、404 ではなく HTTP 410 が返されます。レスポンス本文には、ツールキットに代わるコネクター、呼び出し元が所有するコネクターの一覧、コピーして使える置き換え用の呼び出しが含まれます。本文を確認してください。そこに答えがあります。personal_connectors:が残っているマニフェストでrailcode deployを実行すると、「personal_connectorsは削除されました — アカウントをコネクターとしてリンクし、connectors:の下に指定してください…」 というエラーで失敗します。アプリの提供は継続され、拒否されるのはデプロイのみです。- マネージドエージェントには作業は不要でした。 プラットフォームがマニフェスト、プロンプト、許可行をそのまま書き換えました。エージェントにまだ問題がある場合、原因はこれではありません。
対応方法
-
railcode connector listを実行します。アカウントはすでに登録されています。認証情報は移行済みで、再認証は不要です。 -
名前を確認します。 同じ組織内で同じプロバイダーを使う人が2人いた場合、または通常の名前がすでに使われていた場合、行名にはサフィックスが追加されています。たとえば、
gmailがgmail-jpになっている可能性があります。以前のツールキット ID ではなく、connector listに表示される名前を使ってください。 -
呼び出しを置き換えます。ワーカー SDK と v1 ブラウザー SDK で、同じ API を使えます。
旧 新 personalConnections.call("gmail", "send_email", args)connector("gmail-jp").call("send_email", args)personalConnections.tools("gmail")connector("gmail-jp").tools()personalConnections.list()serviceConnectors()personalConnections.connect("gmail")共有行または所有行に相当するアプリ側の処理はありません。 アカウントのリンクはアプリの外で行います。ユーザーは railcode connector link gmailを実行するか、ダッシュボードからリンクします。アプリに接続フローを実装しないでください。例外はユーザーごとのコネクターで、アプリがブラウザーをプラットフォームのconnectUrlに転送します。上記の項目とユーザーごとのコネクターを参照してください。 -
マニフェストの
personal_connectors:をconnectors:に置き換え、呼び出し可能なツールとともに行名を指定します。たとえば、connectors: { "gmail-jp": ["send_email"] }、または行全体を対象にする場合は["*"]とします。その後、再デプロイします。
この対応のために、v1 アプリを apps v2 に移行する必要はありません。 connector() は、/_api/sdk.js から提供されるプラットフォーム SDK にすでに含まれています。ただし、呼び出し箇所はバンドルにコンパイルされるため、再ビルドは必要です。したがって、この対応を実施できるのは、アプリのソースをまだ持っている人だけです。
プロジェクトとアプリ
Railcode コンソールでは、これまで app と表示されていた箇所が project になりました。My projects、New project、プロジェクトの Settings ページなどです。デプロイするものは、必ずしもブラウザーで開くものとは限らず、Web アプリ、エージェント、API、あるいは UI のないワーカーの場合もあるため、呼び方が変わりました。「Project」はそのすべてを表します。
プロジェクトとアプリは同じオブジェクトです。 変わったのはコンソール上の表記だけです。CLI
(railcode apps、railcode init、railcode deploy)、railcode.json、API、コンソールの URL(/apps/<slug>)では引き続き app と表示され、このスキルのほかの箇所も同様です。2 つの言葉は同じ意味として扱ってください。
- ユーザーが「自分のプロジェクト」「プロジェクトの設定」「プロジェクトを共有」と言う場合、意味するのはアプリです。
appのコマンドとアプリのスラッグを使ってください。railcode projectコマンドはありません。 - ユーザーと話すときは、ユーザーが使った言葉に合わせてください。コンソールを利用している人は「project」と言います。訂正しないでください。
- コンソールの New project ダイアログで作成したプロジェクトは、何もデプロイされていない状態で、すでに組織内に存在しています。別のプロジェクトを作成するのではなく、そのプロジェクトにデプロイされるよう、必ずそのスラッグをそのまま使用してください。新しいフォルダーの場合は
railcode init <slug>を、既存のコードの場合はrailcode.jsonの"app"に同じ値を指定します。 - この 2 つの言葉の意味が異なる場所が 1 つあります。Railcode の外では、「project」はソースフォルダーまたはリポジトリも意味します(
migrate-to-railcodeスキルではその意味で使われています)。ユーザーの意図が不明な場合は、質問する前にrailcode apps listで一致する名前がないか確認してください。
この意味でエージェントであるプロジェクトも、依然としてアプリです。作成したコードがワーカーで実行されます。コンソールの Agents に表示され、Railcode が実行するマニフェストである managed agent は別のもので、create-railcode-agent スキルを使って作成します。
まず、どの世代かを確認する
Railcode アプリには 2 つの形式があり、以下のほぼすべてのルールは、どちらを扱っているかによって決まります。ほかのことをする前に確認してください。
- 新しいアプリは常に generation 2(apps v2)です。 選択肢やフラグ、
railcode.jsonのキーはありません。サーバーが割り当てます。 - 既存のアプリは generation 1(v1)の場合があります。これは従来のブラウザー SDK 形式です。既存のアプリは generation 1 として補完されており、明示的に移行されるまでそのままです。
railcode apps show <app> --json | grep generation # 1 = legacy, 2 = apps v2
通常のテキスト出力には世代が表示されないため、--json を使ってください。
| 状況 | 対応 |
|---|---|
| 新しいアプリを作成する | Apps v2 です。このファイルの続きを読んでください。 |
"type" と "server" がある railcode.json を含むアプリを変更する | Apps v2 です。このファイルの続きを読んでください。 |
index.html で /_api/sdk.js を読み込むアプリを変更する | Generation 1 です。v1 legacy を読んでください。ここにあるルールのほとんどは適用されません。 |
| v1 アプリを変更しており、リクエストに v1 では実現できない機能(シークレット、バックエンド、cron、維持必須の認可)が必要な場合 | 移行して、ユーザーに伝えてください。 次に When a v1 App Can't Do What's Asked を読んでください。ブラウザー側で回避する方法は実装しないでください。 |
| ユーザーが v1 アプリを v2 として作り直すことを希望している | まず Migration を読んでください。これは一方向の移行であり、ダウンタイムが発生します。 |
サーバーに接続して確認できない場合は、ソースツリーを見て判断してください。index.html に /_api/sdk.js があれば v1、railcode.json に "server" キーがあれば v2 です。
v1 アプリでは要求に応えられない場合
v1 アプリはページとブラウザー SDK で構成されます。ワーカーがないため、シークレットも、cron も、サーバーサイドのコードも、アプリが信頼できる呼び出し元もありません。リクエストにこれらのいずれかが必要な場合、プラットフォームの回答は「それにはワーカーが必要です」となります。そして、v1 アプリは移行しないかぎりワーカーを利用できません。「このアプリに X を追加する」という依頼は、X が以下のいずれかに当てはまる場合、移行が必要であることを隠しています。
| リクエストに必要なもの… | v1 ではできない理由 | v2 での対応 |
|---|---|---|
| ブラウザーに見せてはならない認証情報 — AWS キー、署名キー、サードパーティ API のシークレット | シークレットがありません。ページが読み取れるものはすべて(KV、設定コレクション、バンドルされた定数など)、アプリを開けるユーザーなら誰でも読み取れます | ワーカー内の secrets.NAME |
| コネクタープロキシが認証できない API — リクエストごとの署名(SigV4)、mTLS、独自のハンドシェイク | コネクターが対応するのは bearer/header/query/basic のみで、サーバーサイドで署名コードを実行する場所がありません | ワーカーから egress: 経由で呼び出します |
| スケジュールに従って実行する処理 | cron がなく、ページが開いていないかぎり何も実行されません | ワーカールートを呼び出す crons: エントリー、または AI 作業の場合はエージェント独自のスケジュール |
| 必ず守らなければならないルール — 「X が申請し、Y が承認し、X は自分の申請を承認できない」 | ページ側のチェックはあくまで助言的なもので、ユーザーは誰でも devtools から回避できます | ctx.user を使ったワーカー内のチェック |
| サーバーサイドの処理 — 多数のレコードの集計、複数のサービスの連携、タブで実行するには重すぎる、または機密性が高すぎる処理 | サーバーサイドでは何も実行されません | ワーカールート |
原則:移行し、ユーザーに伝えてから、作業を続けます。 リクエストが該当する場合、成果物は移行と機能の両方です。機能をv1で近似的に実現するのではありません。
- 回避策を作らないでください — ページがリクエストに署名できるよう KV にキーを置く、スケジュールの代わりにポーリングループを使う、タブ内で承認チェックを行う、といった方法です。
- 最初に一段落で説明してから、作業を進めてください: リクエストに必要なもの、v1 では提供できないこと、アプリを v2 に移行すること、そしてどちらの方法を使うか(新しいスラッグ(Path A — 元に戻せるため推奨)またはその場での移行(Path B — 一方向で、ダウンタイムが発生))。移行するかどうかを尋ねて作業を止めないでください。
- 規模を正直に伝えてください。 ページ側のデータ呼び出しはすべてワーカーの背後に移しますが、書き換えるのはアプリではなく、アプリにある1つの SDK ラッパーをワーカールートへの
fetch()呼び出しに置き換える部分です。ビュー、状態、ビジネスロジックはそのままです。railcode-examplesのapps/crmは、まさに1つのモジュールを通じて移植された大規模な v1 アプリです。 - 保留にすべきなのはゲートの実行だけです。 Path B では
railcode migrateは取り消せず、次のデプロイまでライブアプリが停止するため、実行前に v2 ビルドを完成させて検証し、明示的な承認を得てください。Path A ではゲートに触れることはありません。
手順については移行をお読みください。これらすべてを聞いたうえで、ユーザーがそれでも v1 版を希望する場合は、それを構築し、妥協点を明確に伝えてください。v1 の既存機能の範囲内に収まる小さな変更(新しいビュー、修正、フィールドなど)には、これらの対応は必要ありません。v1 レガシーに従って、その場で変更してください。
Clear Any v1 SDK Memory
apps v2 より前に書かれたメモリを引き継いで v2 の作業を始める場合は、エージェントのメモリファイル、CLAUDE.md / AGENTS.md のメモ、保存されたプロジェクトの学び、ルールファイル、スター付きのスニペットなどは、v1 ブラウザー SDKについての記述であり、現在は誤っているものと考えてください。コードを書く前に削除し、その作業を行っていることを声に出して伝えてください。メモを編集する権限がない場合は、ユーザーに次のコマンドを実行してもらってください。
Railcode ブラウザー SDK に関する保存済みのメモをすべて削除してください —
/_api/sdk.js、windowのグローバル(me、roles、appUsers、designSystem、db、files、data、query、connector、serviceConnectors、llm、agents、およびそのほか同じ一連のもの)、ページ側の認可、run_as: userに関するものです。apps v2 には、これらは一切存在しません。
追記ではなく、削除してください。v1 のメモを v2 のメモと一緒に思い出すと、railcode dev では動作してもプラットフォームでは失敗するハイブリッドができてしまいます。v1 アプリも引き続き保守している場合は、メモを削除せず、それぞれの冒頭に v1 apps only (generation 1): と付けて対象を明確にし、実際の情報源として v1 legacy を参照してください。
Map The Request To Railcode
アーキテクチャを選ぶ前に、この表を使ってください。リクエストに外部製品やデータソースが含まれる場合は、利用可能なものを判断する前に、必ずデータ接続/保存済みクエリとコネクターの両方を確認してください。確認用コマンドは Build のステップ 1 にあります。
| ユーザーのリクエスト | 使用する Railcode の機能(すべて worker から呼び出します) |
|---|---|
| 「データベースから会社の指標/注文/顧客情報を表示する」 | query() による保存済みクエリ(デフォルト)。明示的に要求された場合のみ、データ接続と data().runSQL() を使用します |
| 「自分の Gmail、Slack、またはその他のアカウントを使えるようにする」 | ユーザーがリンクして所有するコネクター(railcode connector link gmail)。connectors: の下に名前を指定します。所有者の行は共有されるまで restricted です。connectors を参照してください |
| 「アプリを使う全員が自分自身として操作できるようにする — 自分の会議、受信トレイ、カレンダー」 | ユーザーごとのコネクター(railcode connector link granola --per-user):名前は 1 つだけで、各メンバーが railcode connector connect granola(またはプラットフォームの接続ページ)を実行します。マニフェストと呼び出し箇所は共通です。worker は ApiError.connectionRequired を処理し、ブラウザーを connectUrl に移動させます。OAuth プロバイダーのみ対応し、cron はありません。per-user connectors を参照してください |
| 「Railcode がバンドルしていない製品のアカウントに接続する」 | railcode connector add-mcp <name> <https-url> — 自分が所有するコネクターとしてリモート MCP サーバーを追加します |
| 「チームで共有する Stripe、CRM、またはその他の SaaS アカウントを使う」 | connector().fetch() または connector().call() による組織管理コネクター(メンバー所有者はおらず、管理者が認証情報を保持します)。メンバーがアクセスできるかどうかは、その行の個別の access_mode で決まります |
| 「アプリの設定、下書き、承認、または軽量なレコードを保存する」 | db — フラットなストアです。パーティション分割とアクセス方針はworker のコードで設定します |
| 「ファイルをアップロード、保存、ダウンロード、または表示する」 | files(サーバープレーン:worker がバイトデータを保持します) |
| 「AI でファイルを読み取り、抽出、要約、変換、または生成する」 | マネージドエージェント — Worker LLM vs Managed Agents を参照してください |
| 「ユーザーを待たせている間にデータを要約または分類する」 | worker 内の llm.generate() / llm.stream() |
| 「スケジュールに従って実行する」 | worker のルートを呼び出す crons: エントリー、またはエージェント独自のスケジュール |
| 「バックグラウンドで、Slack から、またはタブを閉じた後に実行する」 | マネージドエージェント — Worker LLM vs Managed Agents を参照してください |
| 「システムが管理するトランザクションメールを送信する」 | email.send()。特定のユーザー自身のアカウントからメールを送る必要がある場合は、Gmail のコネクター |
| 「任意の Web サイト/API を呼び出す」 | egress: の下にホストを宣言するか、コネクターを使用します。デフォルトの許可リストはデータプレーンのみです |
例から始める
railcode init は新しいアプリの出発点です。デフォルトの hono+vite テンプレートは、オンボーディング用のウェルカムアプリをひな形として作成します。hono+static と tanstack は、小規模なプラットフォームツアー(ID、db 上の ToDo リスト、ファイル、読み取り専用の組織関連画面)をひな形として作成します。どちらも、読んだ後に削除することを想定しています。
ツアーの範囲を超えるアプリを作る場合は、railcode-examples を読んでください。そこにあるアプリはすべて世代 2(frontend/ + server/index.ts、これから構築する構成)なので、安全にコピーできます。それぞれに、次のいずれかの要点が含まれています。
| 例 | 参考になる内容 |
|---|---|
apps/kanban | 最もシンプルなワーカーアプリです。共有ストアと、呼び出し元から到達できない場所に記述された、非対称なルール(削除できるのは作成者または管理者のみ)があります。 |
apps/chat | ワーカーで動作するエージェントループと、ページへの ndjson ストリーミング。キーとオーナーチェックによって再構築されたユーザーごとの分離(server/keys.ts)。S3 以外のストレージ向けのフォールバックを備えた、ファイル URL の一括処理。 |
apps/crm | 大規模な v1 アプリを 1 つのモジュール経由で移植する方法と、書き込みが人間の承認クリックを待つため、ブラウザー内に残す必要があったツールループ。 |
agents/pitch-deck | agents.start() + ポーリング、更新後に再接続する実行、ブリッジを介さずにアプリ独自のストアに保存されるエージェントの出力。 |
agents/proposals | スケジュールをアプリではなく AGENT に持たせる理由:cron には呼び出し元がないため、cron からの agents.start() は 409 になります。 |
例全体を出発点としてコピーします。
mkdir my-app && curl -fsSL \
https://github.com/Railcode-HQ/railcode-examples/archive/refs/heads/main.tar.gz \
| tar -xz --strip-components=3 -C my-app railcode-examples-main/apps/kanban
次に、railcode.json の app にスラッグを設定します。コピーせずにファイルを 1 つだけ確認するには、https://raw.githubusercontent.com/Railcode-HQ/railcode-examples/main/<path> から raw ファイルを取得してください。
ビルドプロセス(順番に進めてください)
手順 1~2 が完了するまで、アプリのコードを書き始めないでください。
1. 構築を始める前に質問する
アプリの範囲を定めるため、ユーザーに簡潔な質問をいくつかします。すべてを最初に一度にまとめて質問します。 設計に影響することだけを尋ね、残りは妥当な既定値を選んで、その旨を伝えます。
質問はすべて、Railcode の内部事情を何も知らない非技術者向けに表現します。仕組みではなく、目的について尋ね、回答に応じて使用するプリミティブを決めます。「各ユーザーには自分のレコードだけが表示されるようにしますか。それとも全員が同じデータを扱いますか?」——「フラットストアをワーカーでどのように分割しますか?」ではありません。
何かを尋ねる前に、以下の制限事項とリクエストを照らし合わせます。Railcode では対応できないことが必要な場合は、まずその旨を明確に伝え、最も近い対応可能な形を提案します。
**外部ソースの調査は必須です。**ユーザーが、名前の挙がった製品(「X」)のデータを読み取り、書き込み、同期、検索、または操作するアプリを依頼した場合、新しいインテグレーションが必要だと決めつけてはいけません。まず、次の3つのプレーンすべてを調べます。
railcode db list # data connections
railcode query list # admin-published saved queries
railcode connector list # connectors you can reach: owned, shared, org-managed
railcode connector catalog # providers that could be linked, if none exists yet
利用できそうなものがあれば、それを前提に設計する前に、実際に提供される機能を確認します(http 行には railcode connector docs <name>、mcp 行には railcode connector tools <name> を使用します)。コネクター名、エンドポイント、ツールのスラッグを決してでっち上げてはいけません。インスタンスに接続できない場合は、何が設定されているかをユーザーに尋ね、これらのコマンドを提示します。ローカルで結果が空でも、X がサポートされていない証拠にはなりません。
適切なものが見つからない場合は、その不足を説明し、インテグレーションを黙って省くのではなく、実際に可能な次の選択肢を提示します。管理者にデータベースを接続して保存済みクエリを公開してもらう、共有認証情報用の組織管理コネクターを作成する、バンドルされたプロバイダーをコネクターとしてリンクする、または X のリモート MCP サーバーを URL で追加する(railcode connector add-mcp)。X に API、データベース、リモート MCP サーバーのいずれもない場合は、Railcode から直接アクセスできないと伝え、どの対応可能なデータソースを使うか尋ねます。
最低限、以下を確認します。
- 何を、誰が使うか — アプリに何をさせるのか、誰が使うのか。(アクセス制御ポリシーと、ワーカーによるフラットストアの分割方法が決まります)
- データ — 何を保存または読み取るのか。ユーザーごとか、共有か。外部データベースの場合は、ユーザーが直接 SQL を明示的に希望しない限り、管理者が公開した保存済みクエリを使用します。サードパーティの SaaS の場合は、サービスコネクターを使用します。LLM を使用するか。AI を使う場合は、その用途を確認します。ファイルを処理するのか、コードを実行するのか、リクエストの完了後も処理を継続する必要があるのか。いずれかが「はい」であれば、管理エージェントを使用します。
- スタック — 既定では
hono+viteを使用します。小規模なものにはhono+static、ファイルベースのルーティングとサーバー関数を希望する場合はtanstack、ユーザーが Next.js を希望する場合、またはサーバーレンダリングされたページが必要な場合はnext(CLI 0.3.8 以降。まずreferences/cli-workflow.mdで制限事項を確認します)、バックエンドがまったくない場合はstaticを提案します。 - デザイン — 「Railcode の既定のデザインシステムを使いますか。それとも、具体的なデザインの方向性がありますか?」
- ブラウザテスト — 「完了とする前に、ブラウザーで変更をテストしますか?」
2. デザインシステムを取得する(ユーザーが希望する場合)
railcode login # once, if not already logged in
railcode design-system
組織のデザインシステムのガイダンス(Markdown)を出力します。結果が空の場合、またはサーバーがない場合は、取得を省略して以下のビジュアルの方向性を使用します。
3. アプリを構築する
railcode init <app> [dir] [--template hono+vite|hono+static|tanstack|next|static]
cd <app>
npm install
railcode dev
**ビルドは CLI が管理します。**アプリでは、バンドラー、wrangler、Cloudflare パッケージ、ワーカービルドスクリプトを宣言しません。server/index.ts とフロントエンドを作成します。railcode deploy により、プラットフォームに必要な、自己完結型の ESM モジュールが1つ生成されます。
続いて、以下の実装ルールに従い、railcode.json と同じ場所に manifest.yaml を作成します。
**v2 では run_as: app が必須です。**ワーカーが実際に使用する機能をすべて宣言し、それ以上は宣言しません。デプロイの前に検証します。
railcode manifest validate
4. 完了とする前にテストする
検証のチェックを実行します。作業完了を宣言する前に、見つかった問題を修正します。
5. デプロイする(ユーザーが公開を希望する場合)
railcode deploy
プッシュのたびにデプロイするには、プロジェクトで railcode ci github を実行します。このコマンドはアプリスコープの
デプロイトークンを生成し、gh を使ってリポジトリのシークレットとして設定したうえで、ワークフローを作成します。CI に個人用トークンを
設定しないでください。
読み込む内容を決める
タスクに必要なリファレンスだけを読み込んでください。
- Worker SDK —
@railcode/sdkの機能:ctx、db、files、llm、agents、query、コネクター、email、secrets。v2 の作業における主要なリファレンスです。 - アプリのパターン — worker のルート、フロントエンドと worker の接続、データ モデリング、worker コードでの認可、cron、エラーの中継。
- CLI ワークフロー — 正確なコマンド:init/dev/deploy/secrets/logs/ migrate、マニフェストの権威、アプリへのアクセス。
- デプロイ — デプロイ先の解決、アクセスモード、検証。
- 移行 — 既存の v1 アプリを v2 アプリに変換する方法。v1 アプリでは実現できない要求を受けた場合も含みます。
- v1 レガシー — ブラウザー SDK プラットフォーム。既存の第 1 世代アプリの保守に限って使用します。新しいものの開発には決して使用しないでください。
実装ルール
アプリをフロントエンドとワーカーに分け、その境界を明確に保ってください。
フロントエンドは静的です。認証情報やプラットフォームへの呼び出し、権限は持ちません。権限が必要に見える操作は、ワーカー自身の /api/* ルートに対する fetch() だけです。v2 ページから呼び出せるプラットフォームのエンドポイントは /_api/me と /_api/logout(クロームバーが使用するもの)だけです。通常、ユーザーの識別情報は独自のワーカーから取得してください。
ワーカーは @railcode/sdk をインポートし、実際の処理をすべて担います。目的に合う最小限の機能を使用してください。
| 必要なもの | ワーカー SDK の機能 |
|---|---|
| 呼び出し元の識別 | ctx.user(検証済み。cron の場合、および公開アプリのゲストの場合は null(ctx.isGuest)) |
| レコード、設定、下書き | db — 単一のフラットなストアです。パーティション分割は自分で行います |
| ファイル | files.put/get/url/urls/list/delete |
| データベースの読み取り | デフォルトでは query() / savedQueries()。依頼された場合に限り data()/postgres()/bigquery()/turso() |
| サードパーティのアカウント(共有または個人所有) | connector('name').fetch()(http)または connector('name').call()(mcp)— どちらも同じインターフェースを使用し、所有権とアクセスモードは行に保存されています |
| AI | llm.generate() / llm.stream()、または agents.start() とマネージドエージェント — ワーカー LLM とマネージドエージェントを参照してください |
| 組織メンバーのディレクトリ | appUsers() |
| アプリごとのシークレット | secrets.NAME |
| システム所有のメール | email.send() |
認可は自分のコードで行う必要があり、ほかの機能が代わりに行うことはありません。 アプリのアクセス制御では、誰がアプリを開けるかを決めます。その後のすべて — 誰が編集、承認、削除できるか、誰のレコードを閲覧できるか — は、ctx.user を使ってワーカー内に自分で記述するチェックで決まります。暗黙的に処理するスコープ付きストアはもうありません。db は単一のフラットなストアなので、「ユーザーごと」にするには、読み取り時に自分で ctx.user.id をキーにし、自分でアクセスを確認する必要があります。
リクエスト本文の値を、識別情報や所有者の判定に決して使わないでください。 ctx.user から取得してください。v2 ワーカーが無条件で利用できるのは、信頼できる呼び出し元だけです。
公開アプリには見知らぬ人もアクセスできます。 オーナーや組織の管理者は、公開アクセス(リンクを知っている人なら誰でもアクセス可能。サインイン不要)を有効にできます。有効にすると、サインアウト中の訪問者や別の組織にサインインしている人も、マニフェストで許可された機能(llm、email、保存済みクエリ、コネクター)を組織の費用で使用し、ctx.user === null および ctx.isGuest === true の状態ですべてのワーカールートにアクセスします。有効にされる前に、メンバー専用ルートで ctx.user を確認してください。また、null の呼び出し元を「これは cron だ」と決めつけないでください。ctx.trigger を確認してください。app-patterns.mdを参照してください。(CLI 0.3.10+ / SDK 0.5.1+ が必要です。また、インスタンスで公開アクセスが有効になっている必要があります。)
最上位のセクションごとに専用のパスを設けてください(/companies、/companies/acme)。ナビゲーションをメモリ内の view 変数で管理してはいけません。ディープリンク、ページの再読み込み、戻る/進むが機能する必要があります。これらのアプリは Slack やチケットからリンクされます。Railcode の配信は index.html にフォールバックするため、設定なしでクライアント側ルートを解決できます。
ルートを /api/openapi.json で定義してください。 ワーカーから OpenAPI ドキュメントを配信します(server/openapi.ts に置いてください)。パスパラメーターと本文スキーマには required を設定してください。これにより、Railcode MCP 経由でアプリを呼び出すエージェントは、推測する代わりにルートとその引数を把握できます。このドキュメントがない場合、誤ったパスも誤ったメソッドも、どちらも 404 になります。app-patterns.mdを参照してください。
SDK のエラーステータスを引き継いでください。 ワーカールートで SDK の呼び出しをラップする場合は、ApiError をキャッチし、その .status と本文を返してください。フロントエンドの 403/409/429 の処理は、追加の中継を経てもステータスが維持されることを前提としています。エラーを無視して 500 に置き換えると、プラットフォームが提供する型付きエラーがすべて失われます。
ワーカーの LLM とマネージドエージェント
v2 ではページ内に LLM はありません。llm はワーカー内で実行されます。現在の本質的な境界はワーカーの LLM とマネージドエージェントであり、違いは高度さではなく、実行できる機能です。
| AI 機能… | 使用するもの |
|---|---|
| ワーカーがすでに読み取っているデータを数秒で要約/分類する | ワーカーの llm |
| ファイルを読み取り、理解、抽出、変換、または生成する | マネージドエージェント(app_files + サンドボックス)。ワーカーはファイルの put/get/list/delete を実行できますが、代替手段としてファイルの内容や URL を llm.generate() に渡してはいけません |
| コードを書いて実行する | マネージドエージェント(サンドボックス) |
| リクエストの終了後も処理を継続する必要がある、再試行する必要がある、または数分かかる | マネージドエージェント |
| Slack またはエージェントのスケジュールから起動される | マネージドエージェント |
| 誰かが監査できる実行履歴が必要 | マネージドエージェント |
両者を組み合わせることもできます。ワーカーが高速な処理を自ら実行し、重いステップを agents.start() で委任してから、その実行をポーリングします。Worker SDK を参照してください。
制限事項
リクエストが以下の項目に該当する場合は、最初にその旨を伝え、最も近いサポート対象の方法を提示してください。実現できない近似案を、説明なく構築しないでください。
プラットフォームの仕様
| 実現できないこと | 理由と、最も近いサポート対象の方法 |
|---|---|
| 一般公開アプリ、または顧客向けアプリ | すべての閲覧者がサインイン済みの組織メンバーである必要があります。匿名アクセスやセルフサインアップはできません。これらは社内ツールです |
| インバウンド Webhook/公開 API エンドポイント | ワーカーが実行されるのは、認証済みのアプリリクエストまたは独自の cron の場合のみです。イベントを受信する代わりに、cron でソースをポーリングしてください |
| 任意のアウトバウンド呼び出し | Egress は許可リスト方式です。egress: の下にホストを指定してください(完全一致名またはワイルドカード 1 階層。スキーム、ポート、パスは指定不可)。デフォルトではデータプレーンのみが許可されます |
| リアルタイムのプッシュ(WebSocket、SSE サブスクリプション、プレゼンス) | サーバープッシュの仕組みはありません。UI はポーリングします。リクエスト単位のストリーミングレスポンスは使用できます。toNdjson() は任意のイテラブル(llm.stream() または独自のイテラブル)をページにストリーミングします |
| プリセットのサポート範囲外での Next.js | Next.js 自体は実行できます:railcode init <app> --template next(App Router、通常の URL でページを表示します。references/cli-workflow.md の「Next.js and worker-first routing」を参照)。サポート対象外:Next 16.4(ビルドは成功しますが、すべてのリクエストで失敗します。next は ~16.3.8 に固定してください)、画像オプティマイザー、next/og および .wasm を読み込むその他の機能、時間指定の ISR(export const revalidate = N)。Pages Router は未テストです。CLI に next テンプレートがない場合、またはサーバーに worker_routes がない場合(古いバイナリ、あるいは更新が遅れているセルフホストサーバー)、migrate-to-railcode スキルの Next.js ガイドに、アプリを /api 配下にマウントする代替方法があります |
| ネイティブモバイル、プッシュ通知 | アプリは <app>.<parent> で提供されるレスポンシブ Web アプリです。カスタムドメインはアプリコードの対象ではありません。管理者がダッシュボードの「Settings」→「Custom domain」で設定する、組織レベルのアドオンです |
| フロントエンドコードへの独自 API キーの持ち込み | フロントエンドには何も保持しません。ワーカーの secrets またはコネクターを使用してください |
ワーカーのランタイム
| 制約 | 値 |
|---|---|
| ワーカーは単一の自己完結型 ESM モジュールである必要があります | コード分割されたワーカー、CJS のワーカー、または依存関係を参照するワーカーはデプロイ後、呼び出し時にクラッシュします。CLI のテンプレートではこれが保証されますが、独自のものを持ち込む場合は自己責任です |
| サブリクエストの上限 | 呼び出しあたり約 100 件です。ループ内で files.url() を使わず、バッチには files.urls() を使用してください |
| モジュールサイズ | 10 MB(worker_routes がないサーバーでは 5 MB) |
| シークレット | アプリあたり 64 個、値あたり 5 KB、書き込み専用 |
| 1 日あたりの上限 | アプリあたりの LLM トークン数とメール数。どちらも型付きの 429 を返します |
| 呼び出しログ | 現時点では無期限に保持されます(プランに応じた保持期間を導入予定)。取り込み量には呼び出しあたりの上限があり(200 行/256 KiB)、超過した行は破棄されます |
データ
| 制約 | 詳細 |
|---|---|
db は単一のフラットなストアです | 結合、トランザクション、集計はできません。パーティショニングが設計の要です。大容量データはデータウェアハウスに保管し、保存済みクエリ経由で読み取ってください |
KV list() は最初のページのみを返します | デフォルトは 100、最大は 500 です。ワーカー内でページネーションしないと、後続のデータが気づかれないまま欠落します |
| 埋め込みやベクトル検索には対応していません | LLM ゲートウェイはテキスト入力/テキスト出力です |
エージェントと cron
関数の cron はアルファ版であり、今後変更される可能性があります。 以下のルールは現時点で適用されているもので、拒否動作も意図的なものですが、制限は現在見直し中です。この表でできないとされている処理を cron に依存する中核ループを持つアプリを構築しないでください。対応している代替手段については app-patterns.md を参照してください。
| 制約 | 詳細 |
|---|---|
| cron の呼び出し元は存在しません | ctx.user は null、ctx.trigger は "cron" です。以下の制限はすべて、この事実に起因します |
| cron からエージェントの実行を開始できません | 実行は (app, caller) によって所有されるため、cron が開始した実行には所有者がなく、409 になります。エージェントには独自のスケジュールを設定してください |
| cron からエージェントの実行をポーリングすることもできません | agents.get() は同じ (app, caller) の組み合わせに一致するため、cron は http 呼び出しで開始された実行を読み戻せず、こちらも 409 になります |
| ユーザーごとのコネクターは cron と併用できません | ユーザーごとのコネクターは呼び出し元のアカウントで実行されます。cron には呼び出し元がないため、fetch/tools/call は 409 connector_needs_user で拒否されます(connection()/checkHealth() も同様です) |
| 1 人のアカウントでスケジュール済みの作業を行うには、その人が所有するコネクターを使用してください | 所有者付きの行では認証情報がその行に属するため、cron ルートから呼び出せます(connectors: { "granola-jp": ["*"] })。承認できるのは所有者と、その人が共有した相手のみです。代替手段として、マネージドエージェントに独自の railcode agent schedule を設定できます。エージェントはユーザーごとのコネクターも指定できません |
| 独自の認可コードでは、呼び出し元が null の場合に対応する必要があります | 共有ルートで ctx.user.roles を読み取ると、cron では例外が発生するか、すべてを返してしまいます。フラットなストアは何も強制しません。if (!ctx.user) でガードしてください |
| それ以外は cron でも引き続き動作します | db(db.scoped を含む)、files、data/postgres/bigquery/turso、query、llm、email、appUsers()、secrets、egress、組織/サービスのコネクターは利用できます。v2 ワーカーの権限は呼び出し元ではなく、run_as: app マニフェストによって決まります |
| cron の上限 | アプリあたり最大 5 スケジュール、最短間隔は 1 分です。現在のデプロイにワーカーがない場合、スケジュールは理由を表示して一時停止します |
| cron は少なくとも 1 回実行され、重複する場合があります | ctx.invocationId を冪等性キーとして使用してください。「厳密に 1 回」と約束してはいけません |
| cron は POST をディスパッチします | GET のみで宣言されたルートは、実行のたびに 404 となり、スケジュールが壊れているように見えます |
| エージェントの実行はインバンドで待機されません | agents.start() はキューに登録された実行を返し、agents.get(request_id) で読み戻せます。ワーカー SDK には待機する呼び出しがありません。get() のループも待機にはなりません。フロントエンドまたは後続の呼び出しからポーリングしてください |
| v2 アプリでは組織エージェントを優先してください | 組織エージェントはアプリの共有スコープに書き込みます。これは v2 アプリのフラットなストアです。個人エージェントは所有者のユーザースコープに書き込みますが、移行済みアプリでは読み取り専用に固定されています |
| ワーカーには公開されません | 組織のロール一覧とデザインシステムのガイダンスです。ctx.user.roles で取得できるのは呼び出し元自身のロールです。デザインガイダンスはビルド時に railcode design-system で取得してください |
ビジュアルの方針
スキャフォールドは機能を支える土台であり、スタイルガイドではありません。
ユーザーが Railcode デザインシステムを選択した場合は、railcode design-system で取得して従ってください。そうでない場合は、その理念に沿った、落ち着いた社内ツール向け UI をデフォルトにします。ニュートラルなサーフェス、コンパクトなコントロール、見やすいテーブルやリスト、控えめなボーダーや角丸、抑えたアクセントカラーを使います。
アプリはレスポンシブにしてください。デスクトップとモバイルの幅で主要なワークフローを確認し、テキストの重なり、コントロールの見切れ、使いにくいテーブルがないようにします。
すべてのアプリにファビコンを用意してください。 これらのツールはタブに並べてピン留めされるため、アイコンが空白だと大きな不便になります。アプリの内容を示す小さな SVG を、アクセントカラーで描いてください。パイプラインならファネル、カンバンならボードを使い、次のようにリンクします。
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
フロントエンドの静的ルート(Vite スタックでは public/、hono+static では index.html と同じ場所)に配置します。16px でも見やすくしてください。図形は 1 つにして、細かいディテールや文字は入れません。同じファイルに実際の <title> も設定します。これはアイコンの横に表示されるラベルです。
ローカル開発
railcode dev
フロントエンドとワーカーを実行し、本番環境で使われるパス(/api/*、/_serverFn/*)をそのまま提供します。ワーカーは本番環境と同じワイヤ形式で、HTTP 経由で CLI のローカルデータプレーンを呼び出します。そのため、「railcode dev で動く」ことは「デプロイ後も動く」ことを意味します。
db/files はローカルのスクラッチストアを使用します(--reset で消去され、開発時にライブデータへ触れることはありません)。ガバナンス対象の機能(SQL、保存済みクエリ、LLM、メール、コネクター、エージェント)は、ユーザーの ID を持つ開発用トークンを使って実際のインスタンスに転送されます。実際のプロバイダー、実際のデータ、実際の費用が発生し、メールの送信や実際のエージェント実行も行われます。
許容される制限は、ID が 1 つであること、ローカル環境変数のシークレットを使用すること、cron は手動で起動することです。
ローカル開発用ストレージはデプロイ済みアプリのストレージとは別です。railcode app kv/railcode app files はライブアプリを読み書きし、ローカルエミュレーションにはアクセスしません。
検証
cd <app>
railcode dev # confirm the frontend loads and its /api routes answer
railcode manifest validate
ワーカー独自のログを確認してください。 これは v2 のデバッグ用インターフェースであり、v1 には同等のものがありません。
railcode logs app --app <slug> # invocations: path, status, duration, who
railcode logs app <invocation_id> # one full trace: console lines, errors, authority ops
すべての呼び出しが記録され、その中のガバナンス対象の呼び出しはすべて、判定とともに op として表示されます。そのため、拒否された場合は、気づかない失敗ではなく、リソース名とともに denied と表示されます。
テスト用データの投入。 ストアが空のアプリでは、空の状態しか表示されません。デプロイ後に railcode app kv set <collection> <key> '<json>'(長い内容には --file)と railcode app files upload <path> を使って、現実的なレコードをいくつか投入してください。ワーカーが実際に書き込む形式に合わせます。形式は railcode app kv get で確認できます。何を投入したかを伝え、テスト用のレコードは後で削除してください。アプリにすでに実データがある場合は、まず確認してください。railcode dev では、アプリ独自の UI からデータを投入します。CLI はローカル開発用ストレージにアクセスしません。
ユーザーからブラウザでのテストを依頼された場合は、実行中のアプリをデスクトップとモバイルの幅でエンドツーエンドにテストしてください。コンソールエラー、失敗した /api/* 呼び出し、レイアウトの崩れは修正が必要な問題として扱います。
デプロイ
railcode deploy
railcode.json を読み込み、CLI が管理するビルドを実行して、静的ツリーとワーカーを一体としてアップロードし、マニフェストを承認して、ライブ URL を出力します。静的ツリーとワーカーは一緒に有効化および復元されるため、復元するとデプロイ時とまったく同じ実行可能ファイルに戻ります。
新しいアプリは組織全体からのアクセスをデフォルトとします。初回のデプロイを非公開にするには --private を使います。
このアプリを作成していない場合、デプロイ担当者はあなた一人とは限りません。 アプリには共同デプロイ担当者向けの 編集者 権限があります。デプロイ前に railcode apps show <app>(can edit/can manage)で権限を確認し、railcode pull を実行してください。デプロイ時の 409 は、最後に同期してから同僚が公開したことを示すものとして扱い、--force で無理に進めないでください。
シークレットはライブアプリの状態であり、デプロイには含まれません。 一度設定すると、その後のデプロイ、復元、コールド復元のたびに現在のシークレット一式が再適用されます。
railcode secrets set NAME # hidden prompt, or piped on stdin — never inline
railcode secrets ls # names + set-at + digest, never values
解決方法、アクセスモード、検証については、デプロイを参照してください。