mcpField
O
objectstack-platform

objectstack-platform

github.com/objectstack-ai開発76220 回インストール今日更新
リポジトリ

objectstack-platform について

objectstack-platform は、ObjectStack のプロジェクト設定、ランタイム構成、プラグイン開発を扱うスキルです。`defineStack()`、検証、メタデータ成果物、ドライバー、カーネルと HTTP の境界を説明します。

主な機能

  1. 01defineStack() によるスタック設定
  2. 02メタデータと相互参照の検証
  3. 03プロジェクトのひな形の構成
  4. 04ストレージドライバーの選択と接続
  5. 05プラグインとカーネル連携の開発
  6. 06Hono による ObjectStack HTTP ルートの統合

活用シーン

  1. 01ObjectStack プロジェクトの初期設定
  2. 02ランタイム起動前のスタックメタデータ確認
  3. 03開発・本番環境に応じたドライバー選択
  4. 04ObjectStack ルートの Hono アプリへの組み込み

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/objectstack-ai/objectstack --skill objectstack-platform

インストール後、Claude Code で/objectstack-platformを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

evals/
config-plugins-ops.json
references/
_index.md
bootstrap.md
plugin-hooks.md
plugin-development.md
operations.md
rules/
plugin-lifecycle.md
service-registry.md

詳細

プラットフォーム — ObjectStack のブートストラップとプラグインシステム

1 つの defineStack()/カーネルのインターフェースで扱う 2 つの関心事です。プロジェクトのセットアップ (objectstack.config.ts、ドライバー、ブートシーケンス)と、プラグイン開発(プラグイン、サービス、カーネルのフック/イベントハンドラー、 ObjectKernel と LiteKernel)。


defineStack() — コア設定

objectstack.config.ts は、すべてのプロジェクトの単一エントリーポイントです。 defineStack() を呼び出して、すべてのメタデータを宣言します。

→ references/bootstrap.md § 最小限の例にそのまま移動しました。

設定リファレンスの全項目

defineStack() は、トップレベルのキーとして manifest、packages、objects、objectExtensions、picklists、 picklistExtensions、views、apps、pages、dashboards、reports、 datasets、actions、flows、jobs、 emailTemplates、docs、books、positions、permissions、 capabilities、sharingRules、apis、webhooks、api、server、 agents、tools、skills、hooks、functions、mappings、 analyticsCubes、connectors、data(シード)、datasources、 datasourceMapping、translations、i18n、plugins、devPlugins、 devHint、devLogins、requires、tiers、onEnable、appName、email、sms を持つ ObjectStackDefinitionInput を受け取ります。

意図的に、トップレベルの workflows コレクションも approvals コレクションもありません。 承認は Approval ノードを含むフローとして作成し(ADR-0019)、レコードのステートマシンは各オブジェクトの state_machine 検証ルールです(ADR-0020)。roles: や policies: のような実体のないキーは、黙って無視されるわけではありません。トップレベルで拒否され、スタックの読み込みに失敗します。

defineStack validation failed (1 issue):

  ✗ (root): Unrecognized key(s) on this stack definition: `policies`. …

未宣言のキーの扱いはインターフェースによって異なるため、次の 2 つの対応方針を区別してください。

  • 拒否 — defineStack() のトップレベル、各 objects[] エントリー (ObjectSchema)、および各フィールド(FieldSchema)。パース時に例外が発生し、対象のインターフェースと問題のキーが示されます。TypeScript はそれより前の段階で、TS2353: Object literal may only specify known properties としてリテラルを拒否します。
  • 警告後に破棄 — まだ形状が確定していない作成インターフェース(connectors など)。defineStack() はパースの前に警告を出力し、その値はパース後に残りません。 defineStack: connectors.stripe.bogusKey: 'bogusKey' is not a declared connector key, so its value is dropped at load. これらは今後エラーになるものとして扱ってください。残る形状を確定する移行は予定されているため、現時点では警告のみのキーも、今後は拒否される見込みです。

任意キーやコレクション項目の型を含む、正確な Zod 形状については、 node_modules/@objectstack/spec/src/stack.zod.ts (ObjectStackDefinitionSchema)を参照してください。各コレクションの項目形状は、それぞれのドメインフォルダー(data/object.zod.ts、ui/view.zod.ts など)にあります。

→ references/bootstrap.md § マップ形式(キー → 名前)・§ バレルインポートパターンにそのまま移動しました。

厳密な検証

defineStack() はデフォルトで検証します(strict: true)。

  1. Zod スキーマ — フィールド名、型、列挙型
  2. 相互参照 — ビュー/アクション/フローが、定義済みのオブジェクトを参照していること
  3. シードデータ — データセットのオブジェクトが定義内に存在すること

無効にする場合(上級者向け。たとえば、別のプラグインがオブジェクトを提供する場合):

export default defineStack(config, { strict: false });
コンパイル済みアーティファクトとランタイムメタデータの境界

ObjectStack のランタイムメタデータは、ローカル開発時にはソースファイルから、またはコンパイル済みアーティファクトから取得する必要があります。環境ランタイムがビジネスデータベースを通じてメタデータを読み書きするように設定しないでください。

# the CLI ships an `os` binary; `objectstack` is an alias for it
objectstack compile
# -> dist/objectstack.json

OS_ARTIFACT_PATH=./dist/objectstack.json objectstack dev

ランタイムの基本ルール:

コンテキストメタデータソースデータベースの役割
ローカル開発TS ファイルまたは dist/objectstack.jsonビジネスデータのみ
本番ランタイムアーティファクト API のレスポンスビジネスデータのみ
コントロールプレーンメタデータストレージ内の公開済み JSON環境リビジョン、履歴、オーバーレイ

objectstack.config.ts を生成するときは、オブジェクト名を短く snake_case にしてください。tableName は設定せず、環境ランタイムマニフェストに sys_metadata オブジェクトを追加しないでください。


マニフェストのリファレンス

エコシステム内で自身を識別するため、すべてのスタックに manifest が必要です。

manifest: {
  id: 'com.example.crm',        // Reverse domain unique ID
  version: '1.0.0',             // Semver
  type: 'app',                  // app | plugin | driver | module | ...
  name: 'Acme CRM',             // Human-readable display name
  description: 'CRM system',    // Optional description
  engines: { protocol: '^17' }, // Metadata-protocol major this app targets
}

manifest.engines.protocol: アプリの作成時に準拠するメタデータプロトコルのメジャーバージョンです。create-objectstack は、生成するすべてのプロジェクトにこれを設定します(3 つのサンプルアプリすべてにも設定されています)。ランタイムは何かを読み込む前にこれを確認するため、範囲外のランタイムは、後からクラッシュするのではなく、境界で正確な移行コマンドを示してアプリを拒否します。新しいプロトコルメジャーバージョンに意図的に移行するときに変更してください。不一致を黙らせるために変更してはいけません。

オブジェクトの命名: オブジェクトの name は正規識別子であり、物理テーブル名と一致します。ドメインのプレフィックスは名前に直接含めてください(例:name: 'crm_account')。オブジェクトレベルの namespace フィールド は廃止されており(ADR-0129 D3)、読み込み時に拒否されます。

manifest.namespace(ADR-0048): 任意ですが、一度設定すると適用されます。パッケージで manifest.namespace: 'crm' を宣言すると、すべての object.name が crm_ で始まる必要があります。そうでない場合、defineStack がエラーになります(@objectstack/spec の validateNamespacePrefix)。従来の <ns>__<short> という二重アンダースコア形式は拒否され、sys_ で始まる名前はプラットフォーム予約済みのため対象外です。名前空間はパッケージ所有権のキーでもあるため、同じ crm を宣言するパッケージを 2 つインストールすると、NamespaceConflictError が発生します(OS_METADATA_COLLISION=warn にすると警告に格下げされます)。名前空間が設定されている場合、os lint は名前がプレフィックスなしの UI/自動化項目(app、page、dashboard、flow、action、report、dataset)に対して、致命的ではない naming/namespace-prefix 警告も出力します。


アプリとプラットフォームの境界

ObjectStack アプリは、ビジネス機能を簡潔に実装したものです。プラットフォームの仕様に従ってメタデータを作成し、これらのスキルを参考にしながら、os コマンドで確認してください(作業内容の検証)。プラットフォームが担うものを作り直してはいけません。

  • ビジネス機能はアプリに、機能はプラットフォームに属します。 デフォルト値がない、診断が間違っている、仕様で拒否される形式である場合、修正すべきなのは上流です。そちらで問題を報告し、ここで補おうとしないでください。
  • メタデータだけを持ち、この会社についての知識がないものでも、これを書けるでしょうか? いいえ — この会社独自の判断(割引上限、案件の割り当て先、受注/失注の記録方法など)を表すものなら ⇒ アプリです。はい — メタデータに整合性があるかどうかだけを確認するもの(参照整合性、翻訳の網羅性、ビューの登録項目、共有ルールの適用範囲、CRUD の往復処理、宣言されたロールごとの RLS プローブなど)なら ⇒ プラットフォームです。
  • プラットフォームの不具合がある場合は、プラットフォームの修正を待ちます。 防御的なコーディング、形式の許容、プラットフォームのルールを再実装する手書きの述語は避け、「できる半分だけを取り込む」ことも絶対にしないでください。これは契約優先の選択肢を消費し、判断を中途半端に実行したままにします。ブロック事項をプラットフォームのイシューに記録し、機械判読できるようにしてください。再開する前に、固定したバージョンに修正が含まれていること(上流へのマージ ≠ 固定したバージョンへの反映)を確認し、不具合固有の再現手順を再実行してください。
  • プラットフォームの不適切なデフォルト値は修正すべきものであり、呼び出し箇所ごとに回避するものではありません。

テンプレート

blank は create-objectstack が提供する唯一のテンプレートで、デフォルトです。

  • create-objectstack に同梱されているため、ネットワークから取得する必要はありません
  • サンプルオブジェクトを1つ含みます。requires: ['automation', 'triggers'] に加えて、plugins: に汎用コネクター実行器を3つ含みます。また、8つのジェネレーターバレル(objects、views、actions、flows、dashboards、apps、skills、picklists)があり、それぞれの src/*/index.ts は exportsOf を通じて、名前と同じスタックキーに渡されます。スキャフォールドされた AGENTS.md に追加方法が記載されています。メモリドライバーと Hono サーバーはファイルに含まれていません。CLI が起動時に両方を自動登録します
  • このスキルで説明するメタデータを追加するための、まっさらな状態です

→ references/bootstrap.md § Scaffolding Command にそのまま移動しました。


プロジェクト構造の規約

すべての ObjectStack プロジェクトは、次のディレクトリ構造に従います。

my-app/
├── objectstack.config.ts    # ← THE entry point — defineStack()
├── package.json
├── tsconfig.json
└── src/
    ├── objects/              # Business object definitions
    │   ├── task.object.ts    # → exports a single object
    │   └── index.ts          # → barrel: export * from './task.object'
    ├── views/                # Optional: UI view definitions
    │   ├── task.view.ts
    │   └── index.ts
    ├── apps/                 # Optional: app definitions (nav, pages)
    │   ├── main.app.ts
    │   └── index.ts
    ├── flows/                # Optional: automation flows
    │   ├── task.flow.ts
    │   └── index.ts
    ├── actions/              # Optional: action definitions
    │   ├── task.action.ts
    │   └── index.ts
    ├── dashboards/           # Optional: dashboards
    ├── reports/              # Optional: reports
    ├── datasets/             # Optional: analytics datasets
    ├── i18n/                 # Optional: translation bundles
    └── handlers/             # Optional: runtime hook handlers
命名規則
概念規約例
ファイル名{name}.{type}.tstask.object.ts、main.app.ts
マシン名snake_caseproject_task、first_name
設定キーcamelCasemaxLength、defaultValue
バレルエクスポートObject.values(imported)objects: Object.values(objects)

ドライバー選択ガイド

ドライバーはストレージ層です。環境に応じて選択してください。

ドライバーパッケージ最適な用途備考
Memory@objectstack/driver-memory開発、テスト、プロトタイピングInMemoryDriver — 再起動するとデータは失われます
SQL@objectstack/driver-sql本番環境(PostgreSQL、MySQL、SQLite)SqlDriver — 内部では Knex.js を使用(pg/mysql/better-sqlite3 クライアント)
MongoDB@objectstack/driver-mongodb本番環境(ドキュメントストア)MongoDBDriver
SQLite WASM@objectstack/driver-sqlite-wasmブラウザー/WebContainerSqliteWasmDriver — インプロセスで動作し、サーバーは不要です
Turso@objectstack/driver-tursoエッジ、サーバーレス、マルチテナントクラウド/EE のみ — ObjectStack のクラウド/エンタープライズ配布版に同梱されており、オープンフレームワークには含まれていません。オープンコアの CLI は libsql:// URL を認識しますが、明確なエラー(UnsupportedDriverError)で失敗します
ドライバーの接続 — 通常は不要です

os dev/os serve/os start では、CLI がデータベース URL からドライバーを自動的に解決し、DriverPlugin を登録します(開発環境では memory、本番環境では SQL)。設定の plugins: 配列にドライバーを追加しないでください。サンプルアプリではどれも追加しておらず、plugins: キーは CLI が推測できないプラグイン(コネクター実行器や独自プラグイン)用です。コードではなく、DB URL を設定してドライバーを選択してください。

DriverPlugin を自分で構築するのは、Runtime/ObjectKernel を組み込む場合や、カーネルを直接起動するテストなど、実行環境を自分で管理する場合に限ります。

import { DriverPlugin } from '@objectstack/runtime';
import { SqlDriver } from '@objectstack/driver-sql';

new DriverPlugin(new SqlDriver({ client: 'pg', connection: process.env.DATABASE_URL }));

HTTP レイヤー(Hono)

パッケージは2つあります。

パッケージエクスポート使用する場面
@objectstack/honocreateHonoApp({ kernel, prefix })サーバーを自分で管理する場合。ObjectStack のルートを独自の Hono アプリ/デプロイ先に組み込みます。
@objectstack/plugin-hono-serverHonoServerPluginObjectStack がサーバーを管理する場合。Hono アプリをホストして待ち受けソケットを開くカーネルプラグインです(os dev/os serve が登録するのはこちらです)。

@objectstack/adapter-* パッケージはありません(adapter-express/-fastify/-nextjs/-nuxt/-nestjs/-sveltekit もありません)。別のフレームワークと統合するには、Hono アプリ(Web 標準の fetch ハンドラー)をマウントするか、ディスパッチャーを直接呼び出してください。

使用パターン(Hono)
import { createHonoApp } from '@objectstack/hono';

// prefix defaults to '/api'.
export default createHonoApp({ kernel });

⚠️ prefix を指定しても認証の場所は変わりません。 /auth/* マウントは prefix ではなく、認証サービスの basePath(AuthPlugin のデフォルトは /api/v1/auth)に従います。createHonoApp({ kernel }) は better-auth の /api/v1/auth/* に到達します。basePath が含まれていない prefix を指定すると、起動時に両方の値を示して拒否されます。

アーキテクチャ

createHonoApp は HttpDispatcher を作成し、認証とディスカバリーの明示的なルートをマウントして、それ以外のすべてを HttpDispatcher に委譲します。そのため、HttpDispatcher に追加された新しいルートは自動的に機能します。


ランタイムの起動シーケンス

ObjectStack の起動方法を理解しておくと、デバッグやカスタマイズに役立ちます。

objectstack.config.ts
  └── defineStack({ manifest, objects, views, ... })
        │
        ▼
CLI: `os serve` / `os dev`
  1. Load .env files (NODE_ENV-based)
  2. Dynamic import of config file
  3. Create Runtime + ObjectKernel
  4. Auto-detect and register plugins (in this order):
     ├── ObjectQLPlugin (if objects defined)
     ├── DriverPlugin (memory in dev, SQL in prod)
     ├── AppPlugin (loads the defineStack bundle)
     ├── I18nServicePlugin (if translations/i18n defined)
     ├── HonoServerPlugin (registered BEFORE AuthPlugin — the server must
     │     exist for plugins that mount routes during init/start)
     ├── AuthPlugin
     ├── Split platform-app plugins (ADR-0048, optional/best-effort, after AuthPlugin):
     │     @objectstack/setup → createSetupAppPlugin   (first-run wizard)
     │     @objectstack/account → createAccountAppPlugin
     │     (@objectstack/studio is intentionally NOT default-loaded — the
     │      Console, mounted at /_console/ by `--ui`, ships its own Studio
     │      surface at /_console/studio/…)
     ├── RESTPlugin (auto-generated API)
     ├── DispatcherPlugin
     └── AIServicePlugin (cloud / EE only — reverse-mounted by a cloud host; absent in the open framework per cloud ADR-0025)
  5. Runtime.start() → init + start all plugins
  6. Server listens on the resolved port (see "Ports & networking" in Part 3)

ポートの解決(os dev と os start はどちらも os serve を実行): --port フラグ › $OS_PORT › $PORT › 3000。競合時の動作はモードによって異なり、開発モードでは次の空きポートに移り、本番モードでは明確なエラーで失敗します。ポートとネットワークを参照してください。

requires: — 起動するサービスプラグイン

ステップ 4 のリストは固定のコアです。それ以外のサービスプラグインはすべてオプトインであり、スタックのルートにある requires: [...] で有効にします。CLI は各トークンを packages/cli/src/commands/serve.ts の CAPABILITY_PROVIDERS レジストリを通じて展開します。このレジストリには、次の 19 個のオプトイン項目があります。

トークンプロバイダーパッケージ
automation@objectstack/service-automation — フロー、および宣言的な connectors: エントリー
analytics cache storage queue job messaging realtime settings sms@objectstack/service- + トークン
marketplace@objectstack/service-package
audit email sharing approvals webhooks@objectstack/plugin- + トークン
pinyin-search@objectstack/plugin-pinyin-search
mcp@objectstack/mcp
triggers@objectstack/trigger-record-change、および trigger-schedule と trigger-api

このマップにない PLATFORM_CAPABILITY_TOKENS のトークンは、このマップでは解決されません。

  • ティアによる制御 — ai、ai-studio、i18n、ui、auth にはプロバイダーエントリーがありません。serve.ts の run() にある専用ブロックが、代わりにそれぞれのティアを有効にします(ai/ai-studio はインテント駆動型の AI ブロックを通じて、残りの 3 つはそれぞれのティアブロックを通じて有効になります)。
  • エンタープライズ/クラウド — hierarchy-security にはオープン版のプロバイダーがなく、@objectstack/security-enterprise に含まれており、plugins[] を通じて読み込まれます。ai-seat と governance はクラウドの objectos-runtime でのみ解決されます。

正式なリストは PLATFORM_CAPABILITY_TOKENS(@objectstack/spec、kernel/platform-capabilities.ts)です。不明なトークンは起動時ではなく、作成時に defineStack によって拒否されます。

記述内容に影響する 5 つのルール:

  • 優先順位: requires › tiers › --preset › 組み込みのデフォルト。plugins: に明示的なインスタンスがある場合は、常に能力の解決より優先されます。
  • 宣言は要求です。 あなたが宣言した能力のプロバイダーパッケージが存在しない場合、起動時に致命的なエラーになります。プラットフォームが自動で注入した能力はベストエフォートとして扱われ(警告を出して続行します)。
  • auth は email を含意します。 認証コールバック(パスワードのリセット、メールアドレスの確認、マジックリンク、招待)にはメールサービスが必要なため、CLI は auth が要求されると email を追加します。
  • plugins: にコネクターを列挙する場合は、automation を含めてください。 コネクターのエグゼキューターはプロバイダーファクトリーを automation に登録します。これがないと登録先がなく、起動に失敗します。
  • triggers と job を組み合わせてください。 triggers だけで有効になるのはレコード変更トリガーです。スケジュールトリガーと相対時刻トリガーはジョブサービスで実行されるため、job がないと自動起動されるスケジュール済みフローは動作しません。
onEnable — アプリがランタイムコードをバインドする場所

objectstack.config.ts では、デフォルトのスタックと並べて onEnable をエクスポートできます。 AppPlugin は起動時にこれを呼び出し、アプリのライブなランタイムハンドルを渡します。宣言型のメタデータが命令型のコードに接続される唯一の接点です(アクションハンドラーの登録、ジョブへのデータハンドルの受け渡し、フィクスチャデータソースのプロビジョニングなど)。3つのサンプルアプリすべてで使用しています。

export const onEnable = async (ctx: { ql: { registerAction: (...a: unknown[]) => void } }) => {
  registerTaskActionHandlers(ctx.ql);
};

→ references/bootstrap.md の § プラグインの読み込み順が重要 · § プログラムによるブートストラップ(CLI なし)へ、そのまま移動しました。


→ references/bootstrap.md の § 複数アプリの合成へ、そのまま移動しました。


シードデータ

スタックの data: コレクションは defineSeed() を使って定義します。これは objectstack-data が管理しています。externalId による照合、env: のスコープ設定、導出されるキーについては、そちらを参照してください。特に、object はオブジェクト定義から導出されるため、手書きしないでください。また、data: [{ object: … }] のようなリテラルを直接書かないでください。

mode によって、シードの実行時に既存の行をどう扱うかが決まります。

モード動作
upsert(デフォルト)externalId の一致に基づいて挿入または更新します
insert常に挿入します(重複時は失敗します)
update見つかったレコードのみ更新し、新規レコードは無視します
ignore存在しない場合は挿入し、存在する場合はスキップします
replace⚠️ データ損失 — すべてのレコードを削除して再挿入します

CLI コマンド

日常的に使うコマンドはパート 3 — 運用にあります。 ブートストラップループのチートシート:

npx create-objectstack my-app
cd my-app && npm install
os dev --ui          # dev server + Console at /_console/ (auto-hops port if taken)
os validate          # metadata cross-reference checks
os compile           # produce dist/ artifact
os migrate plan      # preview metadata↔DB schema drift (additive sync never alters existing columns)
os migrate apply     # reconcile DB to metadata (loosening only; --allow-destructive for drops/tightenings)
PORT=8080 os start   # production — pin the port explicitly (see Ports & networking)

→ references/bootstrap.md の § 完全な動作例へ、そのまま移動しました。



→ パート 2 — プラグイン開発とカーネル拡張は、そのまま references/plugin-development.md(クイックリファレンス — 詳細なルール · ObjectKernel と LiteKernel の比較 · プラグインインターフェース — クイック概要 · PluginContext API · プラグインの完全な例 · プラグインの使用 · プラグインのテスト · 既知のプラグイン名とサービス · MetadataPlugin のランタイム境界 · ヘルスモニタリング · 機能フラグ)へ移動しました。詳細なルールは rules/plugin-lifecycle.md · rules/service-registry.md · references/plugin-hooks.md にあります。



→ パート 3 — 運用:CLI、テスト、デプロイは、そのまま references/operations.md(日常ループのコマンド · ビルドとランタイム · 作業の確認 · ポートとネットワーク · データとマイグレーション · 環境とデプロイ · プラグインのリリース · テストのパターン · デプロイ先 · ヘルスと可観測性 · よくある運用上の落とし穴)へ移動しました。


リファレンス

Zod スキーマの全一覧(一行の説明付き)は references/_index.md を参照してください。node_modules/@objectstack/spec/src/ 内の各ファイルへの参照が記載されています。フィールドの正確な形状を確認するには、必ずソースを Read してください。プロパティ名の記憶に頼らないでください。

コメント