Communitygithub.com

croct-tech/agent-skills

Croctコンテンツモデルの設計と変更に使用します。通常コンポーネントとユニオンコンポーネントの使い分け、コンポーネント、スロット、構造、プリミティブ属性の役割、コンポーネントスキーマJSON(`structure`、`union`、`reference`、`text`、`number`、`boolean`、`list`、`@croct/file`、`@croct/richText`リッチテキスト、`format`、`choices`、`optional`、`private`、`position`)、コンテンツ定義JSON(`static`/`dynamic`値、`nullable`、`default`、`{{placeholder}}`パス)、スロットデフォルト、ローカライズ、エクスペリエンス、実験、コンテンツグループのコンテンツ、スキーマ制限エラー(属性30個、ネスト6段階、ユニオンメンバー10個、複雑度スコア50)、コンポーネントのバージョニングと破壊的変更(`home-hero@2`)、リファクタリング(複製して修正、複製して置換、フラット化してマージ)、`@croct/md-lite`を使ったテキスト属性内のMarkdownに対応します。

agent-skills とは?

このスキルは、Croctプラットフォーム上でコンテンツモデルを設計・管理するための包括的なガイドです。開発者は、コンポーネントとスロットの設計、スキーマJSONの記述、そしてモデル進化に合わせて有効なコンテンツ定義を作成する方法を学べます。通常コンポーネント(`structure`)とユニオンコンポーネント(`union`)の使い分けから、属性タイプ(テキスト、数値、ブール、リスト、ファイル、リッチテキストなど)、バージョニングと破壊的変更への対応、リファクタリング手法まで、実践的なワークフローと具体例を提供します。特に、スキーマの制限(例:属性30個、ネスト6段階、複雑度スコア50)や、ローカライズ、動的値(CQL)の扱い、Markdownテキスト属性のレンダリングなど、プロダクション環境で直面する課題を解決するための知識を網羅しています。このスキルは、Claude Code、Coder、CursorなどのAIエージェントで利用でき、開発者がCroctのコンテンツ管理機能を最大限に活用できるよう設計されています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/croct-tech/agent-skills/tree/HEAD/skills/croct-model-content

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Croctコンテンツのモデリング

コンポーネントとスロットを設計し、スキーマを記述し、モデルの進化に合わせて有効なコンテンツ定義を埋めていきます。スキーマで表現できるものはすべてダッシュボードのビジュアルエディターにも存在します。JSONは同じモデルであり、手書きで記述します。

メンタルモデル

概念説明スコープ
コンポーネント名前付きの再利用可能なスキーマ。structureとunionのみがコンポーネント(トップレベルのスキーマ)になれます。スロットや他のコンポーネント間で再利用可能
通常コンポーネント固定された属性セットを持つstructure。
ユニオンコンポーネント最大10個の通常コンポーネントからなるunion。エディターはコンテンツごとに1つのバリアントを選択します。
スロットアプリ内のプレースホルダー(ヒーロー、アナウンスバー)で、1つのコンポーネントに結びついています。ロケールごとにデフォルトコンテンツを持ちます。コンテキスト固有。1つのコンポーネントが複数のスロットを支えることができます。
コンテンツ定義スキーマの実際の値を保持するJSON。静的または動的(CQL)な値を持ちます。

コンテンツレイヤー(ベースからトップへ):スロットデフォルトコンテンツ(エクスペリエンスや実験が一致しない場合、ボットフィルタリングで除外されたボット、静的レンダリング時、エラー時に表示)→ エクスペリエンスコンテンツ(オーディエンスごと)→ 実験コンテンツ(バリアントごと。少なくとも2バリアント)→ コンテンツグループ(エクスペリエンスまたは実験バリアント内のサブセグメント向けの追加バリエーション)。フォールバックコンテンツはアプリケーションのソースコードに存在し、フェッチが失敗したときやサービスが停止したときにレンダリングされます。CLIはスロットデフォルトコンテンツをフォールバックとしてダウンロードします。

形状の決定

必要なもの使用するもの
固定レイアウト(どこでも同じフィールド)通常コンポーネント(structure)
エディターが選択するバリエーション(テキストバナー vs 画像バナー vs フォームバナー)通常コンポーネントを参照するユニオンコンポーネント
多くの場所での一貫性(どこでも使われるCTAボタン)別のコンポーネントとして作成し、{"type": "reference", "id": "..."}で埋め込む
1つの場所での柔軟性(タイトル+画像ペア)新しいコンポーネントではなく、ネストされたstructure属性またはプリミティブ
独立したセクションが複数あるページ1つの巨大なコンポーネントではなく、セクションごとに1コンポーネント、1スロット
事前定義されたオプションセットchoicesを持つtext(列挙型)
画像、動画、音声、ドキュメントのアップロード@croct/fileへのreference(ファイルは5MBに制限。長時間の動画は代わりにurlテキスト属性を検討)
ツールバーエディターで編集されるフォーマット済みテキスト@croct/richTextへのreference
プレーンテキストフィールドでの軽い書式設定text + アプリ内のMarkdownパーサー(下記のMarkdownを参照)
他の値の計算にのみ使用される値(例:動的変数)"private": trueの属性

ドキュメントからの経験則:「柔軟性が必要か、一貫性が必要か?」と自問してください。柔軟性 → 構造属性。一貫性 → 新しいコンポーネント。

ワークフロー

  1. ページのセクションをリストアップします。独立して配置される各セクションがスロットになります。
  2. 各スロットに対して、通常コンポーネントまたはユニオンコンポーネントを選択します。構造が一貫していることが意図されている場合は既存のコンポーネントを再利用します。
  3. スキーマを記述します:属性にtype、label、description、position、およびコンテンツが存在しない可能性がある場合はoptionalを含めます。実際のUIの制約からバリデーション(maximumLength、minimum、pattern、allowedTypes、リストのmaximumLength)を追加します。
  4. ネストを追加する前に制限(下記)を確認します。複雑度スコアを計算します。
  5. サポートされる各ロケールと各スロットのデフォルトコンテンツ定義を記述します。
  6. コンポーネントが既に使用中の場合、破壊的変更があると新しいバージョンが作成されます。影響を受けるコンテンツを更新した後、アプリ内のスロットバージョンを更新します(バージョニングを参照)。

スキーマの骨格

通常コンポーネントはstructureです。各属性はそのスキーマをtypeでラップします:

{
  "type": "structure",
  "title": "CTA Button",
  "description": "A call-to-action button that links to a page.",
  "attributes": {
    "label": {
      "label": "Label",
      "description": "The text displayed on the button.",
      "position": 0,
      "type": {
        "type": "text"
      }
    },
    "link": {
      "label": "Link",
      "description": "The URL of the page to link to.",
      "position": 1,
      "type": {
        "type": "text"
      }
    }
  }
}

ユニオンコンポーネントはコンポーネントIDを参照にマッピングします。キーは参照するIDと等しくなければなりません:

{
  "type": "union",
  "types": {
    "text-hero": {"type": "reference", "id": "text-hero"},
    "image-hero": {"type": "reference", "id": "image-hero"}
  }
}

アプリ内では、ユニオンスロットコンテンツは判別共用体です。各バリアントにはコンポーネントID(上記のtext-heroまたはimage-hero)に設定された_typeプロパティがあります。_typeで分岐してレンダリングします。croct-integrate-sdkスキルを参照してください。

属性タイプ一覧

ダッシュボードタイプスキーマJSON
テキスト{"type": "text"}(+ minimumLength、maximumLength、pattern)
複数行テキスト{"type": "text", "format": "multiline"}
URL{"type": "text", "format": "url"}
色{"type": "text", "format": "color"}
日付/時刻{"type": "text", "format": "instant"}(local-date、local-time、local-date-time、zoned-date-timeも)
列挙型{"type": "text", "choices": {"left": {"label": "Left"}}}
リッチテキスト{"type": "reference", "id": "@croct/richText", "properties": {}}
ファイル{"type": "reference", "id": "@croct/file", "properties": {}}
数値{"type": "number"}(+ integer、minimum、maximum)
ブール{"type": "boolean"}(+ label.true、label.false、default)
リスト{"type": "list", "items": {...}}(+ itemLabel、minimumLength、maximumLength)
構造{"type": "structure", "attributes": {...}}
コンポーネント{"type": "reference", "id": "<component-id>"}

formatとchoicesはtype以外のテキストプロパティと組み合わせることはできません。全プロパティリスト、デフォルト値、制限については:references/schema.mdを参照してください。

スキーマの制限

制限値
構造あたりの属性数30
ネストの深さ6レベル
ユニオン内のコンポーネント数10
スキーマ複雑度スコア50
リストアイテム数(スキーマのデフォルトmaximumLength)30
テキストのmaximumLengthシングルライン300、マルチラインとURLは1000(暗黙的な制限:プレーンなtextはformatとmaximumLengthを組み合わせることはできません。リッチテキストは可能)
テキストのchoices20
ファイルサイズ5 MB(5242880 バイト)
ラベル/説明60 / 160 文字

複雑度スコア:structure = 1 + その属性数;list = 1 + そのアイテムタイプ;プリミティブ = 1;union = 最も複雑なメンバー;reference = 参照先コンポーネント。タイトル、画像、価格を持つ製品のリストは5になります。

コンテンツ定義の骨格

すべての値は{"type": "<content type>", "value": {"type": "static" | "dynamic", ...}}です。Structureはattributesをネストし、listはitemsを保持し、unionコンテンツはnameがユニオンキーに設定されたstructureです。

{
  "type": "structure",
  "attributes": {
    "message": {
      "type": "text",
      "value": {"type": "static", "value": "Welcome, {{variable}}!"}
    },
    "variable": {
      "type": "text",
      "value": {
        "type": "dynamic",
        "expression": "user's name",
        "nullable": true,
        "default": "guest"
      }
    }
  }
}
  • expressionはCQLです(croct-cqlスキルを参照)。defaultは評価が失敗した場合、nullを返した場合、または互換性のない型を返した場合に使用されます。
  • nullableはスキーマ内の属性のoptionalフラグと一致する必要があります。
  • variableのようなヘルパー属性は、アプリに配信されるコンテンツから除外するために、スキーマ内で"private": trueとマークします。
  • コンテンツの制限:最大30リストアイテム、最大10動的値、複雑度スコア50。
  • 動的値はScaleプランの機能です。ローカライゼーションはアドオンです。

プレースホルダー、相対パス、フォールバック、およびすべてのコンテンツタイプについては:references/definition.mdを参照してください。

ローカライゼーション

  • ロケールはワークスペースごとに設定されます。ローカライゼーションはアドオンです。
  • サポートされるロケールごとに各スロットにデフォルトコンテンツを指定します。デフォルトコンテンツがないロケールはデフォルトロケールのコンテンツを使用します。エクスペリエンスと実験もロケールごとにコンテンツを保持します。ロケールのコンテンツがないエクスペリエンスは、スロットのデフォルトコンテンツを提供します。
  • 要求されたロケールがない場合のフォールバック:SDKのドキュメントはワークスペースのデフォルトロケールを、Content APIのドキュメントはスロットのデフォルトロケールを参照しています。ドキュメント間で矛盾があるため、どちらかを選択せずにその旨を伝えてください。
  • コード内でロケールを要求するには、preferredLocale(フェッチごと)、defaultPreferredLocale(アプリ全体)、またはNext.js/HydrogenのlocaleResolverを使用します。croct-integrate-sdkスキルを参照してください。
  • croct.jsonはdefaultLocaleとlocalesを保持します。croct installはスロット、バージョン、ロケールごとにフォールバックコンテンツをダウンロードします。croct-use-cliスキルを参照してください。

バージョニングと破壊的変更

  1. コンポーネントスキーマを変更します(例:属性の追加や既存属性の変更)。
  2. 変更がアプリを壊す可能性のある方法でコンテンツ構造に影響を与える場合、Croctは新しいバージョンを作成し、アプリには古いバージョンを提供し続けます。
  3. 影響を受けるすべてのスロットとエクスペリエンスのコンテンツを更新します(ダッシュボードがそれらをフラグします)。
  4. アプリコード内のスロットバージョンを更新します(例:fetchContent('home-hero@2'))。

すべきこと:

  • アプリコードではスロットバージョンを固定します(home-hero@1)。バージョンなしのIDは最新バージョンを使用するため、破壊的変更が即座に反映され、アプリを壊す可能性があります。
  • スロットデフォルトコンテンツだけでなく、エクスペリエンスや実験のコンテンツも更新してください。
  • 変更後はフォールバックコンテンツを同期してください(croct-use-cliスキルで同期をカバーしています)。

してはいけないこと:

  • どの編集が破壊的変更かを推測しないでください。ドキュメントにはリストされていません。ダッシュボードのスロット影響アラートに依存してください。

リファクタリング

状況テクニック
変更をほとんどの使用箇所に適用するが、すべてではない場合複製して修正:コンポーネントを複製し、少数の例外をコピーに向け、元のコンポーネントを変更する
変更を少数の使用箇所にのみ適用する場合複製して置換:複製、コピーを変更、該当する使用箇所をコピーに向ける
コンポーネントが最大ネストレベルに達した場合フラット化してマージ:ネストされた構造の属性を親にマージし、使用されているすべての場所でコンテンツを更新する
コンポーネントが複雑度制限に近い場合別々のスロットでレンダリングされる小さなコンポーネントに分割する
構造が30属性の制限に達した場合ガイダンス(ドキュメントにガイドはありません):関連する属性をネストされた構造にグループ化し、ネストレベル6以内に収めるか、別々のコンポーネントとスロットに分割する。固定されたスロットバージョン(home-hero@1)は、移行中、ライブアプリを古いスキーマで維持します

詳細、手順、ベストプラクティス:references/design-and-refactoring.mdを参照してください。

テキスト属性内のMarkdown

  • リッチテキスト(@croct/richText)は、ツールバーエディターによって生成されたMarkdownを保存します。allowedFormattingで制限します。
  • プレーンなtext属性は生の文字列を保存します。そこでMarkdownをサポートするには、アプリ内で例えば@croct/md-lite(太字、斜体、取り消し線、コード、リンク、画像、段落)を使ってパースします。
  • シンプルな書式設定に留めてください。CTAラベル、URL、製品データは別々の属性としてモデリングしてください。
  • サポートされる構文を属性のdescriptionに記載してください。例:「Supports markdown syntax for **bold**, *italic*, and [links](https://example.com\).」

レンダリングコード:references/design-and-refactoring.mdを参照してください。

落とし穴

  • 単一のタイトルや画像に対してコンポーネントを作成すること。プリミティブまたはstructureを使用してください。
  • 一般的な名前(「Product cards」)。目的に応じた名前(「Product feature list」)を優先してください。
  • ユニオンのtypesキーが参照するコンポーネントIDと異なる場合:スキーマは無効です。
  • 複数のchoicesエントリに"default": trueがある場合:スキーマは無効です。
  • 秒を含まない日付/時刻値:10:15は無効、10:15:00は有効です。
  • nullableがスキーマのoptionalフラグと一致しない動的値。
  • エクスペリエンスのスロットバージョンがアプリのバージョンと異なる場合、プレビューに古いコンテンツが表示されます。

ライブドキュメント

  • インデックス:https://docs.croct.com/llms.txt
  • 任意のページをMarkdownとして:https://docs.croct.com/reference/content/schema/introduction.md
  • 検索:https://docs.croct.com/api/search.md?term=<terms>

関連スキル