mcpField
E
experience-cms-content-type-generate

experience-cms-content-type-generate

github.com/forcedotcom開発1.1k710 回インストール1 日前に更新
リポジトリ

experience-cms-content-type-generate について

Salesforce の ContentTypeBundle を検出、作成、検証、デプロイするスキルです。新規タイプの作成と既存タイプの照合に限定し、定義の変更は行いません。

主な機能

  1. 01ローカルと組織のコンテンツタイプ検索
  2. 02既存タイプを組織と照合
  3. 03Bundle のスキーマとメタデータ生成
  4. 04デプロイのドライランで検証
  5. 05スキーマエラーの自動修正
  6. 06ユーザー承認後にデプロイ

活用シーン

  1. 01Salesforce CMS の新規コンテンツタイプ作成
  2. 02ローカルタイプと組織版の照合
  3. 03デプロイ前の新規 Bundle 検証

MCP 対応

検出には metadata-grounding、ワークスペース内のコンテンツタイプ確認には content-readonly を使用します。取得、検証、デプロイには Salesforce CLI も利用します。

インストール

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

$npx skills add https://github.com/forcedotcom/sf-skills --skill experience-cms-content-type-generate

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

同梱ファイル

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

assets/
discovery-prompts.md
schema-example.json
references/
agent-checklist.md
anti-patterns.md
deployment-errors.md
discovery-details.md
discovery-query-rules.md
edit-fields-loop.md
pre-deploy-checklist.md
retrieve-and-reconcile.md
schema-rules.md
schema-summary-format.md

詳細

experience-cms-content-type-generate

このスキルでできること

  • 検出 — ローカルの <sfdx-source>/contentTypes/ を確認し、metadata-grounding にクエリして、既存の OOTB/カスタム ContentTypeBundle を確認します。
  • 照合 — 既存の FQN を選択または指定した場合、組織から取得し(カスタムのみ)、ローカルと照合します。組織と一致する {fqn, schema} を返します。
  • 作成 — バリデーターに準拠した ContentTypeBundle(schema.json、.contentTypeBundle-meta.xml)を生成します。
  • 検証 — CLI のデフォルト(または選択した)組織に対して sf project deploy start --dry-run を実行します。
  • 自動修正 — スキーマの問題を修正し、再検証します(最大 3 回)。
  • デプロイ — はい/いいえを確認し、「はい」の場合はデプロイします。

新しい型は作成のみ、既存の型は照合のみです。ユーザーの同意を得てローカルコピーを組織のコピーに置き換える場合を除き、既存のバンドルの変更、名前変更、削除は行いません。また、コンテンツレコードも作成しません。メッセージが既存の型のフィールドの追加/名前変更/削除を求めている場合(FQN または名前付きの型を対象とする動詞 add/append/remove/drop/rename/change/modify/update)、1a の前に次の 1 行を出力します:This skill is create-only for new types and reconcile-only for existing. To modify "<fqn|name>", edit its schema.json and redeploy, or use the CMS UI. — その後、検出を続けて、ユーザーがその型の概要(7.5)にたどり着くようにします。変更が行われたかのように、黙って処理を続けてはいけません。

呼び出し仕様

ユーザーから直接呼び出されるか、別のスキル(例:experience-cms-content-generate)から委譲されます。以下の 2 つの要素で構成されます。呼び出し元が指定する入力パラメーターと、すべての終了状態で出力される戻り値です。

入力パラメーター(すべて省略可能)
パラメーター型効果
fqnstring (namespace__DeveloperName)検出を完全にスキップします。1e(取得と照合)に進み、この FQN を使用します。intent と 1d の選択プロンプトは省略されます。解決する型がすでに正確に分かっている場合に使用します。
intentstringユーザーの元のメッセージです。ステップ 1c の検出キーワードと、1d の「一致する…」という文言を決定します。自然言語のユーザープロンプトによってスキルが呼び出された場合のデフォルトです。
suppressCreateContentPromptboolean、デフォルトは falseステップ 8 で最後に表示される「この型を使って今すぐコンテンツを作成しますか?」という質問を抑制します。独自のコンテンツ作成フローを制御する呼び出し元は、必ず true を渡してください。ユーザーが直接呼び出す場合は false のままにし、自然な次のステップの提案をユーザーに表示します。
spaceIdstringステップ 1c のワークスペースコンテンツ型チェック(get_content_types_for_workspace)の対象となるワークスペースです。呼び出し元がすでにコンテンツスペースを解決している場合に渡します。baseType とは相互に排他的です。以下を参照してください。
folderIdstring同じチェックの対象となるフォルダーです。spaceId の代わりに指定します。baseType とは相互に排他的です。以下を参照してください。
baseTypestring、デフォルトは "CONTENT"get_content_types_for_workspace に渡す baseType 引数です。spaceId/folderId とは相互に排他的です。以下を参照してください。

ワークスペーススコープの解決 — 相互排他の契約。 spaceId/folderId/baseType が絞り込むのは、ステップ 1c のワークスペースコンテンツ型チェックのみであり、選択される検出パスではありません。spaceId または folderId を渡す呼び出し元は、baseType も同時に渡してはいけません。スコープだけで対象となる型が決まるため、このスキルは同じ呼び出しで両方を受け付けません。実行ごとに適用される組み合わせは次の 4 つのうち 1 つだけです。呼び出し形式と理由 → references/discovery-details.md#1c continued:

  1. spaceId のみ → get_content_types_for_workspace({ spaceId })。
  2. folderId のみ → get_content_types_for_workspace({ folderId })。
  3. baseType のみ → get_content_types_for_workspace({ baseType })。
  4. 3 つともなし → get_content_types_for_workspace({ baseType: "CONTENT" })(デフォルト)。

一般的な呼び出し形式:

  • ユーザーからの直接呼び出し → intent、suppressCreateContentPrompt は false。検出から取得と照合までを実行し、最後にプロンプトを表示します。spaceId/folderId/baseType は指定せず、上記の組み合わせ 4 が適用されます。
  • 委任された呼び出し → { intent | fqn, suppressCreateContentPrompt: true }。検出から取得と照合までを実行し、{success, fqn, schema} を返します(組織にその型がデプロイされていることを確認するのは取得処理です。ローカルにしか存在しない型は、単なる成功ではなく not_deployed として解決されます)。最後のプロンプトは抑制されます。
  • 既知のワークスペースを指定した委任呼び出し → { intent, suppressCreateContentPrompt: true, spaceId: "<contentSpaceOrFolderId>" } — 組み合わせ 1。呼び出し元がワークスペースをすでに解決しており(例:get_or_create_cms_workspace_and_web_app_channel の contentSpaceOrFolderId)、ステップ 1c のチェックをその範囲に限定したい場合に渡します。この呼び出しで baseType も渡してはいけません。呼び出し元がコンテンツ型の検出後にワークスペースを解決する場合(現在の experience-cms-content-generate など)、委任時に渡せる spaceId はありません。その場合は組み合わせ 4 となり、有効かつ想定された呼び出し形式です。
結果の返却

すべての終端状態では、構造化された結果が返されます。message フィールドは、最終的な1行の要約としてチャットに出力されると同時に、呼び出し元が結果に応じた処理を振り分けるために読み取る値です。

statusfqnschema意味呼び出し元のアクション
successありあり組織内で型が確認済みです(既存の型に対する1eの取得、または「新規作成」経路でのデプロイによる)。後続の作業に使用できます。続行します(例:コンテンツレコードを作成する)。
not_deployedありnullバンドルはローカルに存在する(または検証済み)ものの、組織には存在しません。ユーザーがデプロイを拒否したか、「後でデプロイ」を選択しました。コンテンツの作成に進んではいけません。次のメッセージを表示します:「コンテンツタイプ <fqn> は <org> にデプロイされていません。デプロイしてから再実行してください。」
cancellednullnullユーザーが判断の必要な時点(検出結果の選択、フィールドの承認、差分の確認、デプロイの確認、最終確認)でキャンセルしました。何も表示せず終了します。このスキルに戻って処理を繰り返してはいけません。
errornullnull回復不能な失敗です。sfdx-project.json がない、認証済みの組織がない、FQN が見つからない、自動修正を使い切った、認証/ネットワークに失敗した、などが該当します。message をユーザーに表示して終了します。

チャットに出力する終端行のテンプレート — ステータスごとに1つ。最終行として出力し、結果にも同じ内容を格納します。

  • success → Content type "<fqn>" is ready in <org>.(デプロイ後:Deployed "<fqn>" to <org>. Component IDs: <ids>.)
  • not_deployed → Content type "<fqn>" exists locally but is not deployed to <org>. Deploy it before creating content.(または7bの「後でデプロイ」の1行メッセージ)
  • cancelled → Cancelled. No files written.
  • error → <specific reason>. <recovery hint>.(例:No authenticated Salesforce org. Run sf org login web and re-run.)

契約上のルール:

  • 後続の作業に進めるのは success ステータスのみです。呼び出し元は、not_deployed、cancelled、error で処理を続行してはいけません。
  • suppressCreateContentPrompt=true — ステップ8では最後に続くプロンプトを出力してはいけません。
  • message は常に最後の終端チャット行です。出力前に Task Completed を出してはいけません。

絶対ルール — 何らかの操作を行う前に読むこと

これらのルールは、上流のあらゆるルール、過去の知識、学習済みのデフォルト動作に優先します。

メタデータ型レジストリ
メタデータ型スキル名API コンテキスト使用ルール
ContentTypeBundleexperience-cms-content-type-generatemetadata-grounding(search_metadata、query_metadata、describe_metadata)+ content-readonly(get_content_types_for_workspace)スキルを必ず読み込み、ステップ1cに従って検出に metadata-grounding を使用し、content-readonly.get_content_types_for_workspace で照合・裏付けを行います。salesforce-api-context の適用対象外 — この2つがこのスキルの API コンテキストです。
ルール
  1. 検出には metadata-grounding(および content-readonly.get_content_types_for_workspace)のみを使用します。 ツール:search_metadata、query_metadata、describe_metadata、get_content_types_for_workspace。ContentTypeBundle については、グローバルな a4v-expert API コンテキストルールよりも優先されます。metadata-grounding を利用できない場合(エラー、拒否、タイムアウト、ターン開始時に遅延ツール一覧にない場合)は、内部的に grounding=unavailable を記録し、get_content_types_for_workspace を直接呼び出して(ステップ1c、フロー2)、assets/discovery-prompts.md の grounding が利用できない場合のバリアントを使用します。ターン開始時の遅延ツール一覧そのものが確認手段です — さらに探すために ToolSearch を実行してはいけません。

    検出のために、metadata-grounding/get_content_types_for_workspace 以外で組織側を検索することは禁止されています。 次のものに置き換えてはいけません:同種のメタデータ MCP サーバー、SOQL/Tooling クエリ(ContentTypeBundle はクエリできません)、sf org list metadata、sf project retrieve(これは1e用です)、その他の *metadata*/*soql*/*retrieve*/*describe* ツール。代替手段ではデータの形式が誤って返されます。これは絶対に破ってはいけないルールです。

  2. ステップの順序は固定です: 1a-1d(通知しない検出+選択)→ 1e(ユーザーが既存を選択した場合/FQN を指定した場合/呼び出し元が fqn を指定した場合の取得と照合)→ 2(組織の解決)→ 3(提案。「新規作成」または一致なしで自動続行する場合のみ)→ 4(作成)→ 5(ドライラン)→ 6(自動修正)→ 7(デプロイの確認)→ 7.5(スキーマの要約)→ 8(最後のプロンプト)。ステップ 1e は {fqn, schema} を返し、7.5 に進みます。この経路では 2~7 は実行しません。{fqn, schema} が解決された場合は必ず 7.5 を実行します。ステップ 8 は suppressCreateContentPrompt によって制御されます。一致なしで直接呼び出された場合、1d は 2 → 3 に自動的に進みます。

  3. 「新規作成」のすべての経路で、ステップ 5 と 7 は必須です。 ステップ 5 より前の終了条件:(a)Use existing/Provide an FQN/呼び出し元から渡された fqn → 1e に進み、ファイルを書き込まずに {fqn, schema} を返す。(b)選択時に Cancel を選ぶ。4 と 7 の解決の間に Task Completed を出力してはいけません。1e の差分検出で「組織にローカルをデプロイ」を選ぶ分岐も、5 と 7 に進みます。

  4. Task Completed が最後のアクションです — 出力した時点でスキルは終了します。デプロイ JSON の deployUrl は参照用であり、アクションを促すものではありません。その後に実行・出力してはいけないもの:open <deployUrl>、xdg-open、sf org open、sf project deploy report、ブラウザーのタブ、URL の表示、「次のステップ」の説明文。

  5. ステップ 1e の取得は schema.json を破壊的に上書きするため、差分があれば必ずユーザーに確認してください。 sf project retrieve start --metadata ContentTypeBundle:<Name> はローカルの schema.json を上書きします。1e で取得を実行するたびに、その前に localSchemaBefore にスナップショットを保存してください(meta.xml は対象外)。差分は localSchemaBefore と取得後の schema.json をパースした JSON で比較します。比較の左側は常に localSchemaBefore とし、取得後のファイル同士を比較してはいけません。差分がある場合は、差分のプロンプトが必須です(チャットに差分を表示してから、ask_user_tool で Deploy local to org/Overwrite local with org/Cancel を提示)。無確認で照合してはいけません。結果を出力する前に、Cancel と Deploy local to org の場合は必ず localSchemaBefore から schema.json を復元してください。スナップショットと復元の完全な手順、および差分プロンプトのテンプレート → references/retrieve-and-reconcile.md。

  6. ステップ 1d — 上位 5 件を表で表示してから確認します。 行数は常に min(combined.length, 5) です。combined はローカルの一致項目と、重複を除いたすべてのグラウンディング行(Location は local, org)で構成し、「無関係」として除外してはいけません。1 行目の並び順:OOTB(sfdc_cms__* またはグラウンディングの isOOTB)を先にし、カスタム(c__*)はグラウンディング順位順で続けます。1 行目の FQN を Use existing: オプションに指定します。1 行以上ある場合は、表(FQN | Description | Location)を表示してから、ask_user_tool で Use existing: <row-1 FQN>/Provide an FQN/Create new: <newName>/Cancel を提示します(<newName> は combined 内のどの FQN とも重複しない名前にします)。combined が空の場合は表を表示せず、ask_user_tool で Create new: <contentTypeName>/Cancel のみを提示します(委任された場合、または fqn が指定されている場合は Provide an FQN も提示します)。表と「一致なし」という説明を併用してはいけません。前置きは不要です。#/Name/Label 列を含めてはいけません。あるタイプが「組織に存在しない」と断言してはいけません — 正式な判定は 1e の取得のみで行えます。完全なプロンプトテンプレート → assets/discovery-prompts.md。

エージェント向けの完全なチェックリストとトリップワイヤー一覧 → references/agent-checklist.md。

ファイルパス(厳守)

  • バンドルディレクトリ:<sfdx-source>/contentTypes/<ContentTypeName>/ — contentTypeBundles/<ContentTypeName>/ ではありません。
  • ファイルは次の 2 つのみ:schema.json と <ContentTypeName>.contentTypeBundle-meta.xml。

出力の規律

ユーザーはチャットを読みます。このスキルの仕組みの大半はユーザー向けではありません。

出力してはいけないもの:ステータス行、タスク進捗チェックリスト、計画の文章(これから…、スキルの規定に従い…)、アンチパターンに関する推論、免除の説明、「操作が拒否されたため、代わりに…を実行しました」という注記、ユーザー自身で検証やデプロイを実行するよう促す提案。

出力するものは次のものだけです:1d の検出サマリー、1e のドリフトに関するプロンプト、3b の提案フィールドの表と ask_user_tool、ステップ 4 の「作成したファイル」の確認(2 行)、ステップ 5 の検証結果(1 行)、7a のデプロイ確認、7b/7e のサマリー(各 1 行)、7.5 のスキーマサマリー表({fqn, schema} が解決された場合)、ステップ 8 のプロンプト(suppressCreateContentPrompt が false または未設定の場合)。

ステップ 7 が解決され、7.5 のサマリーが出力され、ステップ 8 のゲートが評価されるまでは、Task Completed、「完了しました」、「準備完了」を出力しないでください。早まって完了を通知すると、サマリーとデプロイ確認が出力されなくなります。

エージェントのチェックリストとトリップワイヤー

必須の進捗チェックリストとトリップワイヤーの一覧は、references/agent-checklist.md にあります。チェックリストをエージェント内部にコピーし、アクションが実際に完了した後にのみ、各項目にチェックを入れてください。チャットには出力しないでください。

ワークフロー(CREATE)

1. 既存のタイプを検出する(サイレント — このステップではユーザーに確認しない)

1a. プロジェクトコンテキストを解決する(エージェント内部)

sfdx-project.json を読み取ります。packageDirectories[0].path に /main/default を追加して、<sfdx-source> とします。バンドルは <sfdx-source>/contentTypes/ にあります。sfdx-project.json がない場合は、§ Invocation contract に従って、メッセージ This is not an SFDX project — open the project root and re-run. を含む error の結果を出力し、そのメッセージを表示して停止します。

明示的な FQN のファストパス(ユーザーからの直接指示)。 呼び出し元が fqn を指定していないものの、メッセージに namespace__DeveloperName 形式のトークン(例:sfdc_cms__news、c__PressRelease)が文字どおり含まれている場合は、それを fqn として取得し、1b/1c/1d をスキップして、直接ステップ 1e に進みます。委譲された {fqn} の形式に対応します。

残余の意図を取得する(エージェント内部)。 メッセージを確認し、and also/and then/then でつながった 2 つ目の節、またはコンテンツレコードを対象とする 2 つ目の命令形動詞(例:create <type> and also create a <thing> about X)がないか探します。該当するものがあれば、residualIntent として保持します。ステップ 8 の Yes 分岐で、これを intent として渡します。ステップ 8 より前に、出力したり実行したりしないでください。

1b. ローカル検出(サイレント)

ディレクトリ一覧を取得できる機能(list_files、<sfdx-source>/contentTypes/*/schema.json に対する Glob、IDE の list_directory)を使用してください。コンテンツ検索/grep ツールは使用しないでください。コンテンツ検索では、フォルダー名だけに含まれる一致を見つけられないためです。各サブフォルダーについて、schema.json(title と description)を読み取ります。意図に基づいて意味的に照合してください。文字列の完全一致ではなく、コンテンツのドメインを考慮してください。たとえば、MarketPlace という名前のフォルダーは、プロパティに文字列の一致がなくても、マーケットプレイスに関するリクエストに一致します。意味的に一致するローカルバンドルはすべて combined に返してください(残りはステップ 1d の並べ替えと最大 5 行の制限で処理します)。一致が 0 件の場合は 0 件を返します(直接呼び出しの場合は自動的に次へ進みます)。

根拠、アンチパターン、ツール選択の詳細については、references/discovery-details.md#1b を参照してください。

1c. Org の検出(サイレント — content-readonly.get_content_types_for_workspace をバックエンドとする metadata-grounding.search_metadata をディスパッチする)

ディスパッチのゲート:1c はツール呼び出しであり、思考ではありません。 1b でローカルの一致が見つかっても、スキップしないでください。Org に同名のバンドルが存在する可能性があります(「Name already exists」はここに由来します)。無条件で実行し、実際の障害があるツールに限り免除されます。「検索しますか?」と尋ねてはいけません。 search_metadata の query パラメータにはコンテンツドメインの名詞のみを含めます — コンテンツが何についてのものか(ニュース、記事、製品、プレスリリース)を表す 3〜5 個の英単語です。FQN、名前空間のヒント、メッセージのコピーではありません。metadataType: "ContentTypeBundle" がすでに種類を示しています。sfdc_cms、c__、__、content type、bundle、metadata、cms を含むクエリは絶対にディスパッチしないでください。含まれている場合は再構築します。完全なルールセット + 具体的な呼び出し形状表(ドリフトのセーフティネットとして experience-cms-content-generate からも参照されます)→ references/discovery-query-rules.md。

サーバーターゲット: metadata-grounding(RULE 1)。limit=5、OOTB 優先でソート。

1c で query_metadata をディスパッチしないでください。 search_metadata は 1d のテーブルが必要とするすべて(FQN、説明、OOTB フラグ)を返します。query_metadata が不可欠なのは 1e の OOTB スキーマ取得のみです — オンデマンドで、選択された 1 つの FQN に対してディスパッチします。行ごとのファンアウトは N 回の無駄なラウンドトリップです。

ワークスペースのコンテンツタイプチェック — 毎回の実行で、グラウンディングと並行して、またはその代わりにディスパッチされます。 呼び出しパラメータは相互排他契約(§ 呼び出し契約)に従い、spaceId/folderId と一緒に baseType を決して指定しないでください。フロー 1(グラウンディング利用可能) — get_content_types_for_workspace もディスパッチします。組織候補セット = 両方の FQN セットの積集合(空でも有効です。広げたり再試行したりしないでください)。フロー 2(グラウンディング利用不可) — それを唯一の組織シグナルとして直接ディスパッチし、ステップ 1b のセマンティックマッチングを行に適用し、1d の TRUTH GATE のために groundingFallback=workspaceTypes を記録します。どちらのツールも 1e の取得の代わりにはなりません。呼び出し形状、利用不可時の処理、根拠 → references/discovery-details.md#1c continued。

1d. ディスカバリーの結果は常に提示します — 「一致なし」の場合も含めて

ディスカバリーはチャットで最初に表示されるシグナルです。何を確認し、何が見つかったかを常にユーザーに伝えます。すべてのケース(A/B/C)で ask_user_tool を介して選択リストを表示し、次のターンでユーザーの返信を待ちます。

TRUTH GATE — 1d の文言は 1c で実際に起きたことと一致していなければなりません。 このターンに実行されなかったチェックを主張しないでください。また、実際には行われなかったスキップを開示しないでください。3 つのケース:

  • search_metadata がディスパッチされた(フロー 1、get_content_types_for_workspace の結果に関係なく) → 組織はグラウンディングを介して確認されました。開示は不要です。
  • search_metadata が利用不可だが get_content_types_for_workspace がディスパッチされた(フロー 2 / groundingFallback=workspaceTypes) → 組織は確認されましたが、グラウンディングを介してではありません。assets/discovery-prompts.md に従って (checked supported content types for this workspace — metadata-grounding unavailable) を追記します。
  • 両方とも利用不可 → 組織は本当に確認されていません。assets/discovery-prompts.md に従って (org check skipped — grounding unavailable) を追記します。

references/discovery-details.md#1d を参照してください。

Provide an FQN のゲーティング — showFqnOption を計算します。 次のいずれかに該当する場合に表示します: (1) 結果が存在する(ローカルまたはグラウンディングで 1 件以上) — ユーザーが 1 行目ではない一致を望む可能性があります。2〜5 行目および上限を超える結果は FQN オプションの括弧内に表示されます。または (2) 呼び出しが委任されている(suppressCreateContentPrompt === true または呼び出し元が fqn を指定した) — 委任された一致なしバリアントでは常に利用可能です。

それ以外の場合(直接呼び出しかつ一致ゼロ) → showFqnOption = false。選択プロンプトをスキップし、情報行を出力し、ステップ 2 に自動的に進みます。直接呼び出したユーザーが新規作成を求めていて何も一致しなかった場合に FQN 入力を提供すると、ユーザーの目的が変わってしまいます。 直接呼び出しでゼロ件一致の場合の意図サニティゲート。 自動続行する前に、メッセージから少なくとも 1 つの認識可能なコンテンツドメイン名詞を抽出します(実在する単語、固有表現、または複合ドメイン語彙 — 意味不明な文字列ではなく、content type/bundle/CMS/schema/metadata のような仕組み上の名詞を除去した後にフィラーのみでもないもの)。認識可能な名詞が 1 つ以上 → ステップ 2 → 3 へ進み、ステップ 3 で提案する名前はそれらのトークンのみから構築します。意味不明な文字列/フィラーのみ → 自動続行しないでください。Your request "<original message>" doesn't name a content domain. What kind of content type would you like to create (e.g. news, blog, press release, product)? を Cancel + 自由テキストとともに尋ねます。自由テキストは 1b を再開し、Cancel → cancelled。1c で再構築されたクエリが空になる場合にも同じゲートが適用されます — 空の search_metadata をディスパッチしないでください。メッセージに存在しないトークンから名前をでっち上げることは厳に禁じます。完全なルール+例 → references/discovery-details.md#1d。

プロンプトテンプレート(一致あり、ゼロ件一致の直接自動続行、ゼロ件一致の委任、「Provide an FQN」フォローアップ) → assets/discovery-prompts.md。そのままコピーしてください。

1d の出力形状 — 2 つの別々の出力、決して統合しない(報告されている UX 欠陥の第 1 位):

  1. 最初にチャット Markdown — Top <N> matching content types: ヘッダー + FQN | Description | Location テーブル(assets/discovery-prompts.md の出力 1)。プレーンなチャットテキストであり、ツールではありません。
  2. 次に ask_user_tool、その question は正確に Found matches. Pick one:(そのまま、短い 1 文)で、4 つの固定オプション: Use existing: <row-1 FQN> / Provide an FQN / Create new: <newName> / Cancel。

厳に禁止: テーブルの前に、またはテーブルの代わりに前置きの文や説明文を書くこと。テーブル、その列、または (checked supported… / org check skipped…) サフィックスを question フィールドの内側に置くこと(マークダウンのない 1 行のフラットなテキストとしてレンダリングされます — 報告されている壊れたテキストの壁);question を言い換えたり「より役立つように」したりすること(それはそのまま Found matches. Pick one: です);行ごとに Use existing: オプションを追加すること(オプションは 4 つに固定 — 追加の行には Provide an FQN 経由で到達します)。構造化されたものはすべて出力 1 のチャット Markdown に入れ、question フィールドは 1 つのプレーンな文のままにします。 → assets/discovery-prompts.md、そのままコピーしてください。

ユーザーの返信後のルーティング:

ユーザーの選択次のアクション
Use existing: <Name>fqn = <namespace>__<Name> で ステップ 1e へ進みます(フォルダーが名前空間化されていないローカル一致のデフォルト名前空間は c)。
Provide an FQN(showFqnOption = true の場合のみ表示)assets/discovery-prompts.md のフォローアップを尋ねます。返信 → その FQN で ステップ 1e。
Create new: <contentTypeName>ステップ 2 → ステップ 3 へ続行します。
Cancel§ Invocation contract に従って cancelled の結果を出力し、Cancelled. No files written. を表示し、次に Task Completed を表示します。

選択リストを表示し、同じメッセージ内で「proceeding to create a new one」とアナウンスすることは厳に禁じます。選ぶのはユーザーであり、あなたではありません。

1e. 取得して照合する

1d で一致が解決された場合、または FQN が提示された場合、もしくは呼び出し元が {fqn} を指定して呼び出した場合に到達します。目標は、組織に一致する {fqn, schema} を返すことです。

名前空間の判定:

  • カスタム FQN(c__*、プラットフォーム以外の名前空間)→ sf project retrieve start --metadata ContentTypeBundle:<DeveloperName> --target-org <alias> --json を実行します。カスタムの場合は必ず取得します。
  • OOTB FQN(sfdc_cms__*)→ sf project retrieve start をスキップします(利用できるものが何も返されません)。どのフローで FQN が提示された場合でも、この分岐には有効な metadata-grounding スキーマが必要です。get_content_types_for_workspace(フロー 2)はスキーマを返さず、{fqn, name, description} のみを返します。1c ですでに grounding=unavailable が記録されている場合は、query_metadata を試さず、以下のエラーに進んでください。それ以外の場合は、選択した FQN のみを対象に、直ちに query_metadata({ metadataType: "ContentTypeBundle", id: "<grounding row id from 1c>" }) を呼び出し、その応答からスキーマを解決します(スキーマのペイロードが返されない場合は describe_metadata にフォールバックします)。その応答がエラー、空、またはスキーマではない場合は、Can't resolve OOTB FQN "<fqn>" without a real schema from metadata-grounding. Retry when grounding is back, or provide a custom FQN. を提示し、error で終了します。トレーニングデータから OOTB スキーマを決して捏造しないでください — 「sfdc_cms__news には通常 title/body/summary がある……」という考えが、3~7 を汚染する不具合の原因です。完全なルール → references/retrieve-and-reconcile.md § Namespace gate。

照合 — 取得したスキーマを <sfdx-source>/contentTypes/<DeveloperName>/schema.json と比較します。完全なマトリクス、差分テンプレート、およびルーティング → references/retrieve-and-reconcile.md。

ルーティング結果:

  • ローカルになく、取得できた → ローカルに書き込み、{fqn, schema=retrieved} を返します。
  • 両方にあり、一致 → {fqn, schema=local} を返します。
  • 両方にあり、不一致 → 差分プロンプト(Deploy local to org → ステップ 5/7、Overwrite local with org → ファイルを置き換えて返す、Cancel → 終了)。
  • ローカルにのみ存在 → まずステップ 7.5 の概要を表示し(ユーザーがデプロイ内容を確認できるようにします)、その後、デプロイ(5/7)またはキャンセルを提示します。
  • どちらにもない → Try a different FQN オプションを付けて 1d の選択を再度呼び出します。

成功時は {fqn, schema} を返し、7.5 → 8 に進みます。 フィールドの提案や再検証は行いません — 照合済みのスキーマが信頼できる情報源です。新規の場合は作成のみ、既存の場合は照合のみです。

1d の「新規作成」だけがステップ 2 に進む経路です。

2. 対象組織を解決する

SF CLI のデフォルト(sf config set target-org=<alias> で設定したエイリアス、または sfdx-project.json の defaultUsername)を優先します。<orgAlias> に解決し、すべての sf 呼び出しで --target-org <orgAlias> を渡します。デフォルトが設定されている場合、このステップは何も表示しません。

デフォルトがない場合 — フォールバック: sf org list --json を実行します(何も表示しません)。

  • 認証済みの組織が 0 件 → メッセージ No authenticated Salesforce org found. Run sf org login web and re-run. を含む error を出力し、表示して停止します。
  • 1 件のみ → <orgAlias> として無言で使用します。sf config は変更しません。
  • 2 件以上 → 質問 No default Salesforce org is set. Pick the org to use for this run: と、各組織につき 1 つの選択肢を付けて ask_user_tool を呼び出します。選択肢のラベルは <alias> (<username>) [<devhub|sandbox|scratch|prod>] とし、Cancel も追加します。選択された場合は、この実行に限って <orgAlias> として使用します(sf config set target-org=… は実行しないでください)。Cancel → cancelled を出力し、Cancelled. No files written. と表示して、Task Completed。

選択されたエイリアスは、この実行での以降すべての sf 呼び出し(1e の取得、5 のドライラン、7 のデプロイ)に適用されます。

3. フィールドを提案し、ユーザーの承認を得る

前提条件:前のターンで、1c が search_metadata をディスパッチ済み(または grounding=unavailable を記録済み)であり、1d が Create new: <contentTypeName> に解決済みであること。その他の 1d の選択肢は別の処理に進みます:Use existing/Provide an FQN → 1e、Cancel → cancelled を出力します。

ask_user_tool で選択肢リストを表示した直後で、ユーザーがまだ返信していない場合は、そこで停止してください。ターンは終了です。

3a. フィールドのプロパティを決定する(エージェント内部)。 apiName(camelCase)、title(人が読める名称)、lightning:type、required を設定します。最小限のデフォルト:ユーザーから要求がない限り、lightning:textIndexed、lightning:localizable、長さ/範囲の境界値、enum、const、placeholderText は設定しません。

コンテンツタイプ名は、ユーザーのメッセージから導き出せる必要があります。 <contentTypeName> とその title は、実際にメッセージ内にあるトークンから作成してください(PascalCase/語順の調整は可 — laptop review → LaptopReview)。根拠なく、無関係な開いているタブから、または以前のセッションのコンテキストから名前を創作することは厳禁です。1d の健全性チェックを通過していても、名詞が少ない(1語)場合は、その語を使用してください — 装飾を加えてはいけません。メッセージにないトークンを使った名前の提案は幻覚のアンチパターンです。停止して、1d のチェックからやり直してください。

userEditedFields = false をエージェント内部で初期化します。これはステップ 6 の分岐を制御します。3b のループでユーザーが自由記述の編集内容を入力した場合にのみ true に変更します(references/edit-fields-loop.md を参照)。Edit fields → Approve as shown の間に編集内容を入力しなかった場合は false のままです — 提案は変更なしで承認されています。

3b. 提案するフィールドを提示する — チャットに表示されるテキストとして、まず Markdown テーブルを提示し、次に同じターンで ask_user_tool を呼び出します。 テーブルをツールのプロンプトにまとめてはいけません — UI で書式が削除され、ユーザーが情報に基づいて承認できなくなります。

メッセージ 1(チャットに表示されるプレーンテキスト):

Proposed fields for `<contentTypeName>` at `<sfdx-source>/contentTypes/<contentTypeName>/`:

| # | API name | Type | Required | Constraints | Title |
|---|---|---|---|---|---|
| 1 | `title` | `lightning__textType` | yes | maxLength: 200 | Title |
| 2 | `body`  | `lightning__richTextType` | yes | — | Body |

制約の形式は 7.5 に従います(references/schema-summary-format.md を参照):フィールドごとに要求または提案した制約は、maxLength、minLength、minimum、maximum、enum、const、lightning:localizable、lightning:allowedUrlSchemes などの key: value の組み合わせをカンマ区切りで記述します。required 以外に制約がないフィールドには — を使用します。

メッセージ 2(同じターン):質問 Approve these fields, edit them, or cancel?、選択肢 Approve、Edit fields、Cancel で ask_user_tool をディスパッチします。

  • Approve → ステップ 4。
  • Edit fields → 以下のループに従います。承認されるまでループします。
  • Cancel → cancelled を出力し、Cancelled. No files written. を表示して、Task Completed。

フィールド編集ループ — 各ラウンドで現在のテーブルを再表示し(チャットに表示)、その後、Approve as shown/Cancel の選択肢で ask_user_tool をディスパッチし、自由記述の編集指示を受け付けます。ツールからの自由記述の結果は編集指示そのものです — 解析して適用し、ループを続けてください。停止してはいけません。 完全なテンプレートと早まって停止しないためのガイダンス → references/edit-fields-loop.md。

4. ファイルを作成する(サイレント — 確認は最大 2 行)

前提条件:直前のターンで、ステップ 3b がユーザーの Approve を返していること。承認前にファイルを書き込んではいけません。

<sfdx-source>/contentTypes/<contentTypeName>/ を作成します。すでに読み込まれている assets/schema-example.json を使用し(§ Schema rules に従い、兄弟ファイルの schema.json を再取得してはいけません)、承認済みフィールドの schema.json と <contentTypeName>.contentTypeBundle-meta.xml を生成します。<masterLabel> のみを置き換え、以下の 4 行を正確に記述してください:

<?xml version="1.0" encoding="UTF-8"?>
<ContentTypeBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel><contentTypeName></masterLabel>
</ContentTypeBundle>

<displayName>、<description>、<contentTypeFields>、<fieldType>、または従来の SOAP 要素を追加してはいけません — これらはバリデーターで失敗します。フィールドごとの禁止キー(type、format、default、空の lightning:uiOptions)については references/schema-rules.md を参照してください。

書き込み後、次の 2 行を正確に表示してください:

Created <sfdx-source>/contentTypes/<contentTypeName>/schema.json
Created <sfdx-source>/contentTypes/<contentTypeName>/<contentTypeName>.contentTypeBundle-meta.xml

その後、ステップ 5 に進みます。5a をディスパッチする前に、references/pre-deploy-checklist.md のデプロイ前スキーマチェックリストを実行します(エージェント内部で行い、表示しません)。その場で修正し、再チェックしてください。

5. 検証(必須)

ステップ 5 は必ず実行します。ステップ 1d が Use existing で終わった場合に限り、スキップします。grounding=unavailable ではステップ 5 をスキップしません(認証経路が異なるためです)。ドライランをユーザーが実行するコマンドとして提示しないでください。あなたが実行します。

5a. 実行(チャットで前置きをしない):

sf project deploy start --source-dir <sfdx-source>/contentTypes/<contentTypeName> --target-org <orgAlias> --dry-run --json

5b. 結果の処理:

  • result.status === "Succeeded" → 次の 1 行を出力します:Validated against <org>: Succeeded (dry-run — nothing deployed yet).。これは終端状態ではありません。次のアクションは、ステップ 7a の ask_user_tool です。
  • result.status === "Failed" かつ componentFailures がある → ステップ 6(自動修正)。
  • result.status === "Failed" かつ componentFailures が 0 件 → CLI/認証の問題です。生のレスポンスを表示し、sf org list、ソースパス、sfdx-project.json を確認するようユーザーに依頼します。3 回の試行には数えません。
6. バリデーターの失敗を修正する — userEditedFields に応じて、黙って自動修正するか、先に確認する

userEditedFields(3a で設定)に応じて分岐します。この分岐は、問題のあるスキーマを誰が作成したかを反映しています。

  • false → ユーザーはエージェントの提案を変更せずに承認しました。バリデーターの失敗はエージェントのミスです。黙って自動修正します。
  • true → ユーザーは 3b で編集しました。失敗は、ユーザーにしか解決できない意図を反映している可能性があります(例:整数に対する enum、テキストに対する default)。予定している修正を表示し、先に確認します。

どちらの分岐でも、スキーマ全体を対象に確認する原則と、エージェント主導の修正を 3 回までとする上限は共通です。各試行では、1 つずつフィールドを修正するのではなく、スキーマ全体にわたってバリデーターが検出しうるすべての問題を修正します。バリデーターが 1 回の実行で報告するエラーは 1〜2 件のみです。1 回の試行で 1 フィールドずつ修正しないでください。エラーから修正への対応(安全な Kind と意図を変える Kind を含む)については、references/deployment-errors.md を参照してください。

6a. 黙って自動修正する(userEditedFields === false)

  1. すべての componentFailures[].problem を読み取ります。
  2. 同じ種類の問題がないか、properties 全体を確認します。例:placeholderText missing が 1 件 → すべての lightning:uiOptions を監査する、format が拒否された → すべてのフィールドから type/format/default を削除する、許可されない型固有のキーが 1 つある → その lightning:type のすべてのフィールドを監査する。
  3. 1 回だけ書き換え、手順 5 を 1 回だけ再実行します。3 回の試行のうち 1 回として数えます。

3 回の試行後も失敗する場合は、最後のエラーを提示し、6b の Let me edit フォローアップに進みます。検証に成功しないまま中止/終了した場合は、最後のバリデーターエラーを message として error を出力し、停止します。

6b. 修正前に確認する(userEditedFields === true)— 予定している修正を表示する

ユーザーが作成した内容がバリデーターに拒否されました。ユーザーの意図を黙って書き換えてはいけません。

メッセージ 1(チャットに表示するプレーンテキスト。ask_user_tool には含めない)— すべての componentFailures[].problem を列挙し、references/deployment-errors.md で修正方法を確認します。

Validation failed on your edited schema. Planned fixes:

  ✗ <field>: <one-line error description>
      Planned: <fix> (<impact>)
  ✗ <field2>: …
      Planned: …

この実行で発生したエラーをすべてフィールドごとにまとめて含めます。ユーザーが作成した制約(enum、const、lightning:localizable、数値の境界値、型の置き換え)を削除/変更する修正の場合、括弧書きには具体的な結果を必ず記載します。「数値の順序付けができなくなります」「enum の値に限定されなくなります」「テキストがローカライズされなくなります」のように記載し、「型が変わります」とは記載しないでください。Kind=safe の修正(default の削除、type/format の削除、allowedUrlSchemes: ["https"])には、文字どおり safe: validator hygiene, no intent change を記載します。

メッセージ 2(同じターン)— 質問 How would you like to proceed?、選択肢 Apply these fixes and continue/Let me edit — I'll fix it, then re-validate/Cancel を指定して ask_user_tool を呼び出します。

ルーティング:

  • Apply these fixes and continue → 表示した修正だけを適用し、1 回だけ書き換え、手順 5 を 1 回だけ再実行します。3 回の試行のうち 1 回として数えます。成功 → 7a。失敗 → 新しいエラーを使って 6b の先頭に戻ります(userEditedFields は true のままです)。
  • Let me edit → 手順 4 の 2 行の確認メッセージにあるファイルパスと、バリデーターエラーをそのまま出力し、質問 Reply when you're done editing.、選択肢 Re-validate/Cancel を指定して ask_user_tool を呼び出します。Re-validate → 手順 5 を再実行します(ユーザー主導のサイクルは 3 回の試行に数えません)。Cancel → cancelled を出力し、Cancelled. Your edits remain at <sfdx-source>/contentTypes/<contentTypeName>/ と Task Completed を出力します。ファイルを削除してはいけません。
  • Cancel → cancelled を出力し、Cancelled. No files written. と Task Completed を出力します。

Apply these fixes の 3 回の試行上限に達した場合は、最後のエラーを提示し、Let me edit フォローアップに進みます(Apply these fixes を再提示してはいけません)。その後 Cancel が選択された場合は、最後のバリデーターエラーを message として error を出力し、停止します。

7. デプロイ(はい/いいえ — 次のユーザーターンを待つ)

ステップ 5 が成功するとステップ 7 に進めるようになりますが、ステップ 5 がステップ 7 に置き換わるわけではありません。デプロイまたはターミナルマーカーを出す前に、ask_user_tool でユーザーに確認してください。

7a. ask_user_tool を呼び出します。

  • 質問:Validation succeeded. Deploy "<contentTypeName>" to <org> now?
  • 選択肢:Yes - deploy now / No - I'll deploy later

7b. ユーザーが「いいえ」と答えた場合:not_deployed の結果を出力して停止します。1 行を出力します —

Validated. Nothing deployed. To deploy later: sf project deploy start --source-dir <sfdx-source>/contentTypes/<contentTypeName> --target-org <orgAlias>

結果を返します:{ status: "not_deployed", fqn: "<namespace>__<contentTypeName>", schema: null, message: "<the line above>" }。ステップ 7.5 またはステップ 8 は実行しないでください。このタイプは組織に存在しません。

7c. ユーザーが「はい」と答えた場合:次を実行します。

sf project deploy start --source-dir <sfdx-source>/contentTypes/<contentTypeName> --target-org <orgAlias> --json

7d. デプロイエラー:

  • componentFailures がある場合(まれなケースです。検証後、デプロイ前に手動編集が行われた場合、または組織側の状態が一時的に変化した場合に発生します):現在の userEditedFields フラグに対応するステップ 6 の分岐に進みます。7d に到達するまでに、必ずユーザーに表示されるターン(ステップ 7a の Yes - deploy now)が少なくとも 1 回あるため、このフラグはファイルを最後に編集したのが誰かを確定するものです。再検証に成功したら、ステップ 7a のデプロイ確認を再度行います。回復不能な失敗(自動修正を使い切った後にキャンセルした場合、または 6b でユーザーがキャンセルした場合)では、§ Invocation contract に従って error の結果を出力し、最後のバリデーターエラーを message としてから停止します。
  • componentFailures がゼロの場合(認証/ネットワークエラー):§ Invocation contract に従って error の結果を出力し、未加工の応答概要を message としてから停止します。

7e. 成功:1 行を出力します — Deployed <contentTypeName> to <org>. Component IDs: <ids>.。これは success の終端状態です。タスク終了時に出力する結果は { status: "success", fqn: "<namespace>__<contentTypeName>", schema: <the just-deployed schema>, message: "<the line above>" } です。ステップ 7.5 に進みます。この箇所からステップ 7.5 まで、他のコマンドは実行しないでください(ルール 4 を参照)。

7.5. スキーマの概要(スキーマが解決されたすべての経路で実行)

{fqn, schema} が解決された場合は、ソースや suppressCreateContentPrompt に関係なく実行されます。情報提供のみであり、ターンではありません。実行ごとに 1 回だけ実行します。エージェント内部で summaryPrinted を追跡してください。1e の「ローカルのみ」分岐ではデプロイまたはキャンセルの前に概要を出力するため、その後の 7e で再度出力してはいけません。

実行するタイミング:1e が null ではないスキーマを含む {fqn, schema} を返した場合、7e が成功した場合、1e のドリフト確認で「Deploy local to org」を選んで 7e に進んだ場合、または 1e の「ローカルのみ」分岐でデプロイまたはキャンセルの前。summaryPrinted ゲートを適用してください。

実行しない場合:ユーザーが Cancel を選択した場合、7b(後でデプロイ)、解決済みのスキーマがないエラー経路、または summaryPrinted === true の場合。

チャットテキストとして出力します(ask_user_tool ではありません)。

Content type "<fqn>" is ready. Schema:

| # | API name | Type | Required | Constraints | Title |
|---|---|---|---|---|---|
| 1 | `title` | `lightning__textType` | yes | maxLength: 200 | Title |
| 2 | `body`  | `lightning__richTextType` | yes | — | Body |

列の定義、制約ルール、並べ替え/切り捨て(プロパティ上限 20 件)、出力禁止リスト → references/schema-summary-format.md。

直ちにステップ 8 に進みます(別のターンや中間プロンプトはありません)。

8. 「コンテンツを作成しますか?」の後続プロンプト(suppressCreateContentPrompt によるゲート)

success からのみ到達します。ステップ 8 は、その後に追加のプロンプトを表示するかどうかだけを制御します。ゲート: suppressCreateContentPrompt === true → 完全にスキップし、success + Task Completed を出力します(このプロンプトは、呼び出し元がすでに実行しているターンを重複させるためです)。それ以外の場合は、success が次の経路で到達したときに実行します: 1e が {fqn, schema} を返した、7e が成功した、または 1e のドリフトプロンプト「Deploy local to org」が 7e に到達した。Cancel(cancelled)、7b(not_deployed)、またはエラーパス(error)では実行しないでください。

ask_user_tool を、質問 Would you like to create content using "<fqn>" now?、オプション Yes — create content now / No — I'm done でディスパッチします。

  • Yes → { fqn, schema, suppressCreateContentPrompt: true } を渡して experience-cms-content-generate に引き継ぎます。また、1a が取得していた場合は intent: <residualIntent> も渡します(例: create a news type and also create an article about our Q4 launch → create an article about our Q4 launch を転送)。残りの intent がない場合は intent を省略します。ループバックしないでください。success + Task Completed を出力します。
  • No → Done. FQN: <fqn>. を出力し、success、Task Completed を発行します。

ステップ 8 が解決した後にコマンドを実行しないでください(ルール 4)。

スキーマルール(バリデータが真実)

CMS デプロイバリデータが信頼できる唯一の情報源です。完全なルールセット → references/schema-rules.md(ルート、フィールドごとのキー、lightning:uiOptions の注意点、型ごとに受け入れられるキー、癖)。ステップ 4 とステップ 6 の前に読み込んでください。

また、ステップ 4 の前に assets/schema-example.json を読み込んでください — 正規の形状リファレンスであり、サポートされるすべての lightning:type をデフォルト最小形式で示しています。ステップ 1b/1e がコンテキスト内で準備したという理由だけで、兄弟の schema.json をリファレンスとして使用しないでください。兄弟ファイルにはユーザー固有の制約(maxLength、lightning:localizable、インデックス作成)が含まれており、正当な理由なく混入してしまいます。

譲れない事項: ルートには unevaluatedProperties: false があり(ルートのみ)、$schema はありません。フィールドごとには title / description / lightning:type / lightning:uiOptions とその型で受け入れられるキーのみです。type / format / default / 空の lightning:uiOptions は決して使用しません。ミックスインは sfdc_cms:metadataContent のみです。

アンチパターン

完全なアンチパターン表(違反 / 正当化 / 正しい対応)→ references/anti-patterns.md。そこに記載されている「バグ思考」のいずれかを考えている自分に気づいたら、STOP — その思考がバグです。

注記

  • フォルダ名、<masterLabel>、およびバンドルの title は一貫している必要があります(PascalCase のフォルダ、人間が読める形式のラベルとタイトル)。
  • lightning__fileType と lightning__contentReferenceType は避けてください — 現在サポートされていません。
  • 評価データセットは tests/evals/ ではなく、packages/adk-eval/eval/domains/experience-cms-content-type-generate/ にあります。

リファレンスファイル索引

  • references/agent-checklist.md — 必須の進捗チェックリストとトリップワイヤー。
  • references/schema-rules.md — バリデータルールセット(バンドルルート + フィールドごと + lightning:uiOptions + 型ごとに受け入れられるキー + バリデータの癖)。
  • references/pre-deploy-checklist.md — ステップ 5 の前のエージェント内部スキーマ健全性チェック。
  • references/deployment-errors.md — バリデータエラー → 修正のマッピング(ステップ 6)。
  • references/anti-patterns.md — バグ思考カタログ。
  • references/discovery-details.md — 1b/1c/1d ルールの根拠。
  • references/discovery-query-rules.md — search_metadata クエリの構築方法に関する信頼できる唯一の情報源。ここではステップ 1c から参照され、さらに親スキル experience-cms-content-generate からも(ドリフト安全ネットとして)参照されます。
  • references/retrieve-and-reconcile.md — ステップ 1e の照合テーブルとドリフトルーティング。
  • references/edit-fields-loop.md — ステップ 3b の編集ループテンプレートとルーティングテーブル。
  • references/schema-summary-format.md — ステップ 7.5 の列 / ソート / 切り詰めルール。
  • assets/discovery-prompts.md — ステップ 1d の選択リストテンプレート + ゼロマッチのバリアント。
  • assets/schema-example.json — サポートされるすべての lightning:type を網羅するリファレンススキーマ。

コメント