mcpField
C
create-site

create-site

github.com/microsoft開発1.1k237 回インストール今日更新
リポジトリ

create-site について

create-site は、要件の整理からテンプレート選択、実装まで、Power Pages サイトの作成を案内するスキルです。SPA フレームワークと Enhanced モデルの非 SPA サイトに対応し、それぞれに異なる手順を用意しています。

主な機能

  1. 01サイトの目的と対象者の整理
  2. 02テンプレートカタログからの選択
  3. 03SPA と非 SPA の作成経路
  4. 04スキャフォールドとライブプレビュー
  5. 05デザインとローカライズの指針

活用シーン

  1. 01対象者が明確なポータルの作成
  2. 02テンプレート選択またはゼロからの開始
  3. 03Power Pages SPA サイトの構築
  4. 04Enhanced モデルの非 SPA サイトの作成

インストール

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

$npx skills add https://github.com/microsoft/power-platform-skills --skill create-site

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

同梱ファイル

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

assets/
create-site-plan.html
non-spa-creation-status-template.html
assets/angular/
angular.json
gitignore
package.json
powerpages.config.json
tsconfig.app.json
tsconfig.json
assets/angular/public/
.gitkeep
assets/angular/src/
index.html
main.ts
styles.css
assets/angular/src/app/
app.component.ts
app.config.ts
app.routes.ts
assets/angular/src/app/components/
layout.component.ts
assets/angular/src/app/pages/
about.component.ts
home.component.ts
assets/astro/
astro.config.mjs
gitignore
package.json
powerpages.config.json
tsconfig.json
assets/astro/public/
.gitkeep
assets/astro/src/components/
Footer.astro
Header.astro
assets/astro/src/layouts/
Layout.astro
assets/astro/src/pages/
about.astro
index.astro
assets/astro/src/styles/
theme.css

詳細

翻訳後に原文が更新されています。最新の内容は原文をご確認ください。

プラグインのチェック:node "${PLUGIN_ROOT}/scripts/check-version.js" を実行します。メッセージが出力された場合は、先にユーザーに表示してから続行します。

Power Pages コードサイトを作成する

初期のコンセプトからデプロイ済みサイトまで、完全な本番品質の Power Pages コードサイトの作成をユーザーに案内します。体系的なアプローチに従います。要件を確認し、すぐにスキャフォールドを作成して起動し、コンポーネントとデザインを計画し、デザインを適用して実装し、検証、レビュー、デプロイを行います。

基本原則

  • 第一印象を大切にしたデザイン:スキャフォールドがホームページに置き換わった瞬間にユーザーが「すごい」と感じ、その印象をすべてのページで保ち続けるサイトにします。美的感覚、雰囲気、ブランドについてユーザーが回答したら、フォント、色、レイアウト、画像、モーションは自信を持って決定します。デザインの基準は、デザインリファレンス(${PLUGIN_ROOT}/references/ 内の design-aesthetics.md、page-blueprints.md、design-critique.md)で定め、残りはあなた自身のセンスで補います。
  • TaskCreate/TaskUpdate を使用する:すべてのフェーズを通して進捗を記録します。まずパスに依存しないタスクを作成し、作成方法を選択した後で、その分岐に応じたタスクを追加します。
  • 早期にスキャフォールドを作成し、意図を持ってデザインする:要件の確認後、すぐに開発サーバーを起動し、ユーザーが確認できるものを用意します。その後、スキャフォールドを起動したままデザインと機能を計画し、実装時に選択した美的スタイルを適用します。
  • ライブプレビューのフィードバックループ:カスタマイズを始める前に、開発サーバーを必ず起動しておきます。Playwright(browser_navigate と browser_snapshot)でサイトを閲覧し、重要な変更のたびに構造を検証します。ビジュアルデザインレビューでは、1 回のスクリプト呼び出しですべてのページをキャプチャし、1 ターンでスクリーンショットを開きます(5.7 を参照)。Playwright MCP のスクリーンショットはフェーズ 3 でのブランド抽出にのみ使用します。
  • スキャフォールドのローダーを実際の状況に合わせる:スキャフォールドのローダーは public/scaffold-status.json をポーリングします。各 AskUserQuestion の前(ターミナルのプロンプトをユーザーが見落とさないよう、「入力待ち」バナーを表示するため)と、フェーズ 5 の実装ステップごと(装飾的なスピナーが既定のサイクルを続ける間、進捗バーのラベルを実際の作業に合わせるため)に、このファイルを更新します。ライブプレビューのステータスプロトコルを参照してください。
  • 目的のあるビジュアルを使う:すべての画像に、説明、案内、実演、またはアイデンティティの強化という役割を持たせます。サイト独自の UI を製品の印象的なシーンとして構成する方法を優先し、次に独自のインライン SVG、最後に明確なアートディレクションに基づく具体的な Unsplash 写真を使います(5.3 を参照)。画像プレースホルダーや、存在しないファイルを参照する壊れた <img> タグは決して残しません。
  • Git のチェックポイント:ページやコンポーネントを個別に作成するたびにコミットします。問題が発生した際に変更を取り消せるよう、それぞれを独立したコミットにします。
  • サイトのコンテンツ言語は Dataverse の言語とは独立しています:ユーザーに表示する SPA の文字列はすべて、承認されたコンテンツ言語で生成します。このワークフローでは、Dataverse および Power Pages のプラットフォーム管理メッセージは英語(en-US、LCID 1033)のままとします。
  • 双方向対応をデフォルトにする:${PLUGIN_ROOT}/references/bidirectional-design.md を読みます。最初の言語が一方向のみであっても、すべてのサイトで方向に依存しないレイアウト、混在コンテンツの境界、スクリプトに対応したタイポグラフィを使用します。後から LTR/RTL のロケールを追加しても、全面的な再デザインが不要なようにします。
  • ライフサイクルに対応した成果物:${PLUGIN_ROOT}/references/site-modification-integrity.md に従い、後からページやコンポーネントを追加する際も、共有の変更後バリデーターを通してローカライズ、方向、コンテンツの拡張動作を維持できるようにします。

制約:対応するのは静的 SPA フレームワーク(React、Vue、Angular、Astro)のみです。Next.js、Nuxt.js、Remix、SvelteKit、Liquid は対応していません。

初期リクエスト: $ARGUMENTS

ライブプレビューのステータスプロトコル

スキャフォールドの読み込み画面が表示されている間(Phase 2.6 から、Phase 5 で Home ページ自体が置き換えられるまで)、ローダーは 1.5 秒ごとに GET /scaffold-status.json をポーリングします。<PROJECT_ROOT>/public/scaffold-status.json に書き込む message はプログレスバーの下のラベルとして表示され、awaitingInput は「入力をお待ちしています」バナーの表示を制御します。プログレスバーの上にある装飾的なスピナーは、組み込みのフレーズサイクルを引き続き表示します。実際の状況がローダーに反映されるよう、プログレスバーのラベルを最新の状態に保ってください。

重要な理由:ローダーを表示したブラウザーがユーザーの画面を占有すると、ユーザーが何か入力を求められていることに気付かず、ターミナルのプロンプトが長時間未回答のままになることがあります。バナーを表示すれば、そのことが明確になります。

ファイルの形式(すべてのフィールドは任意です。変更したくないフィールドは省略してください):

{
  "message": "Creating Contact page",
  "awaitingInput": false,
  "inputPrompt": "Please check your terminal to respond."
}
  • message — ローダーのプログレスバーの下にステータス行として表示される、短い現在分詞句です(デフォルトの「Getting started…」/「Setting up infrastructure…」のサイクルを置き換えます)。役立つ場合は、グループのコンテキストを含めてください(例:"Creating Footer component (shared components)")。
  • awaitingInput — true の場合、ローダーの上部に目立つ点滅バナーが表示され、このフィールドがクリアされるまで表示され続けます。すべての AskUserQuestion 呼び出しの前に設定し、ユーザーの回答の直後にクリア(false に設定)してください。
  • inputPrompt — バナーに表示する短いコンテキストです(例:"Choose a framework")。省略可能です。

ファイルを更新するタイミング:

  1. スキャフォールドの起動後(Phase 2 の終わり):{ "message": "Planning your site", "awaitingInput": false } のような初期ステータスを書き込みます。
  2. スキャフォールドが表示されている間に実行される AskUserQuestion の前(Phase 3、4、および Phase 5 でのスキャフォールド内のプロンプト):短い inputPrompt を指定して awaitingInput: true に設定します。ユーザーの回答後、awaitingInput: false にして再度書き込みます。
  3. Phase 5 の各実装ステップの前 — デザイントークンの適用、各共有コンポーネントの作成、各ページの作成、ルーターの更新、ナビゲーションの更新の前に、message を具体的なアクションに更新します。例:"Applying design tokens"、"Creating Navbar component"、"Creating Contact page"。
  4. Home ページの置き換え後、Phase 5 の最後:サイトにデプロイされないように、public/scaffold-status.json を削除します。

Write ツールを使ってファイルを書き込みます(アトミックな上書き)。事前に読み込む必要はありません。


フェーズ 1:要件の確認

目標:構築するサイトと、そのサイトが解決する課題を把握します

アクション:

🚦 ゲート(plan · create-site:1.purpose): サイト名、目的、対象ユーザーを収集する、パスに依存しない要件確認プロンプトです。スキルがテンプレートを使う経路と、ゼロから構築する経路のどちらを選ぶか決定する前に、ユーザーに必要なサイトの種類を確認します。以下のステップ 3 で「サイトの目的が不明確」な分岐に進んだ場合にのみ実行されます。

トリガー: $ARGUMENTS にサイト名、目的、対象ユーザーのいずれかが指定されていない場合、フェーズ 1 で実行します。 質問する理由: 目的や対象ユーザーの認識が誤っていると、分岐の判断と生成されるサイト計画が誤り、修正が煩雑になります。 キャンセル時の状態: 変更はありません。まだ足場の作成を開始していません。

  1. 最小限の初期 ToDo リストを作成します(進捗の追跡を参照):

    • サイトの要件を確認する
    • テンプレートを選択する、またはゼロから構築する
  2. サイト名、目的、対象ユーザーが引数から明確な場合:

    • 理解した内容を要約します
    • サイトの種類(ポータル、ダッシュボード、ランディングページ、ブログなど)を特定します
  3. サイト名、目的、対象ユーザーのいずれかが不明確な場合は、AskUserQuestion を使用します:

    質問ヘッダー選択肢
    サイトの名前は何にしますか?(例:「Contoso Portal」、「HR Dashboard」)サイト名(自由入力 — ユーザーが「その他」から名前を入力できるよう、汎用の選択肢を 1 つだけ使用します)
    サイトの目的は何ですか?目的企業ポータル、ブログ/コンテンツ、ダッシュボード、ランディングページ
    対象ユーザーは誰ですか?対象ユーザー社内(従業員、パートナー)、社外(一般公開される顧客向け)
  4. ユーザーの回答から、以下を導き出します:

    • __SITE_NAME__(タイトルケース、例:Contoso Portal)
    • 暫定的な __SITE_SLUG__(可能であれば、サイト名から派生させた小文字の ASCII ケバブケース)
  5. パスに依存しない理解内容を要約し、続行する前にユーザーに確認します:

    • サイト名
    • サイトの目的/種類
    • 対象ユーザー

    フェーズ 1 では、フレームワークやプロジェクトの場所について質問しないでください。フェーズ 1.5 で経路が決定された後、それぞれの作成経路で場所を確認します。

対象ユーザーがサイト生成に与える影響:

  • 社内向け:タスクの完了を優先します。ステータス、次のアクション、データテーブル、ダッシュボード、認証、ナビゲーションの階層を重視します。魅力は、マーケティング用のヒーローではなく、明快さ、適切な情報密度、細部の仕上がりによって生まれます。
  • 社外向け:印象的な第一印象、疑念が生じる箇所で根拠を示す説得力のあるページ構成、SEO に適した構造、お問い合わせフォームを優先します。

出力:サイトの目的、対象ユーザー、サイト名、暫定的な技術用スラッグを明確に示します。


フェーズ 1.5:テンプレート分岐の決定

目標:パスに依存しない要件確認の後、ユーザーを適切な作成経路に案内します。

現在の実装状況: テンプレートの検出と選択、サポートソリューションのインポート、パッケージ化された SPA のクローン作成/アップロード、任意のシードデータ、アクティベーション、稼働中のサイトのプレビュー、ターミナルテレメトリーは、kind: "spa" で実装されています。従来のカタログエントリも受け付けますが、ソリューションのみのプロビジョニングフローが実装されるまでは表示されません。ユーザーはいつでも ゼロから開始 を選択し、既存の足場作成フローを続行できます。

アクション:

  1. テンプレートを選択する、またはゼロから構築する を in_progress に設定します。

  2. テンプレートカタログを取得します:

    node "${PLUGIN_ROOT}/scripts/fetch-template-catalog.js"
    

    この実行中のすべてのテンプレート成果物リクエストには、返された変更不可能なコミット SHA を使用します。--ref <tag-or-branch> は、テストまたはロールバックを意図的に行う場合にのみ指定します。 JSON の結果を評価します:

    • ok: false の場合:テンプレートは一時的に利用できないことをユーザーに伝え、ゼロから作成する手順に進みます。これは追加の処理です。カタログの取得に失敗しても、create-site が阻止されることはありません。
    • ok: true で selectableCatalog.templates が空の場合:現在利用可能なサポート対象の SPA テンプレートがないことをユーザーに伝え、ゼロから作成する手順に進みます。kind が traditional の catalog.templates の項目は提示しないでください。
    • サポート対象の SPA テンプレートが利用可能な場合:以下のすべての照合、プレビュー、閲覧、選択の手順で selectableCatalog.templates を使用します。catalog.templates はダウンロードしたマニフェスト全体としてのみ保持します。
  3. Phase 1 のコンテキスト($ARGUMENTS、サイト名、目的、対象ユーザー、ユーザーが言及したフレームワーク)に照らして、テンプレートファミリーを意味的に照合します:

    • 各ファミリーテンプレートの displayName、description、keywords、audience、利用可能なバリアントのフレームワーク、およびバリアント固有のプレビューを使用します。
    • 数値スコアを計算したり、ランキングスクリプトを作成したりしないでください。キーワードはエージェントの判断材料であり、数えるものではありません。
    • ユーザー向けのテンプレートはファミリー、インストール可能なパッケージはフレームワークバリアントとして扱います。1つのファミリーに複数のバリアント(react、vue、angular、astro)が含まれる場合があります。
  4. 意味的な照合の後、ユーザーに次の手順を尋ねます:

    一致状況質問ヘッダー選択肢
    明確に一致する候補が1つ以上あるサイトに合ったテンプレートが見つかりました。どのように進めますか?作成方法一致するテンプレートを表示(推奨)、すべてのテンプレートを閲覧、ゼロから作成
    明確に一致する候補がないサイトに合うテンプレートが見つかりませんでした。どのように進めますか?作成方法すべてのテンプレートを閲覧、ゼロから作成(推奨)

    回答に応じて分岐します:

    • 一致するテンプレートを表示:TEMPLATE_PREVIEW_FAMILIES に一致したファミリーを1つ以上設定し、ブラウザーでのプレビューに進みます。
    • すべてのテンプレートを閲覧:TEMPLATE_PREVIEW_FAMILIES に selectableCatalog.templates のすべての項目を設定し、ブラウザーでのプレビューに進みます。
    • ゼロから作成:CREATION_PATH = "from-scratch" を設定し、後続のフレームワークと場所に関する質問に進みます。
  5. ブラウザーでのプレビュー用に TEMPLATE_PREVIEW_FAMILIES を表示します:

    • レンダリングの前に、各 previewImages 成果物を SHA をキーとするキャッシュにダウンロードします:
      node "${PLUGIN_ROOT}/scripts/fetch-template-artifact.js" --sha "<catalog-sha>" --artifactPath "<preview-image-path>"
      
      各プレビュー画像のパスを、返された localUrl に置き換えます。プレビューのダウンロードが ok: false を返した場合は、その 1 つの画像をギャラリーから除外して続行します。プレビューの欠落は、それ以外は有効なテンプレートの使用を妨げるべきではありません。
    • ユーザーがプレビューすべきテンプレートファミリーと、キャッシュされたプレビュー画像 URL を含む TEMPLATES_JSON 配列を持つ一時 JSON ファイルを書き込みます。ブラウザーがフレームワークのバッジやタブを表示できるよう、各ファミリーで利用可能なバリアントを含めますが、ブラウザーは読み取り専用のままにします。
    • 次を実行します:
      node "${PLUGIN_ROOT}/scripts/render-template-browser.js" --templatesJsonPath "<temp-json>" --outputPath "<temp-html>" --open
      
      ユーザーにブラウザーを使用するよう伝える前に、JSON の結果を評価します:
      • status: "ok": 続行します。ブラウザーのプレビューが生成され、開かれました。
      • status: "invalid": テンプレートの選択を続行しないでください。検証エラーを提示し、一致したファミリーから TEMPLATES_JSON ファイルを再構築し、レンダリングを再実行します。それでも無効な場合は、空または不完全なテンプレートブラウザーを表示するのではなく、ゼロからの作成にフォールバックします。
      • status: "ok" かつ opened: false: HTML は検証されましたが、ブラウザーを自動的に開けませんでした。ファイルパスを表示し、ユーザーが手動で開く機会を得た後にのみ、ターミナルでの選択を続行します。
    • ブラウザービューは読み取り専用であり、テンプレートの機能と利用可能なフレームワークのバリアントを閲覧するために存在します。ターミナルの AskUserQuestion が引き続き意思決定の場となります。
  6. 次のいずれかの AskUserQuestion プロンプトを尋ねます:

    一致状況プロンプトの選択肢
    1 つの強力なファミリー + フレームワークの一致<displayName> - <framework> を使用 (推奨)、別のフレームワークを選択、すべてのテンプレートを表示、ゼロから作成
    1 つの強力なファミリーだがフレームワークの一致なし利用可能なフレームワークごとに 1 つの選択肢、すべてのテンプレートを表示、ゼロから作成
    複数の妥当なファミリーの一致候補に挙げたファミリーごとに 1 つの選択肢、すべてのテンプレートを表示、ゼロから作成
    カタログ全体の閲覧ファミリーごとに 1 つの選択肢、ゼロから作成

    ユーザーが一致するテンプレートの分岐から すべてのテンプレートを表示 を選んだ場合、TEMPLATE_PREVIEW_FAMILIES を selectableCatalog.templates のすべてのエントリに設定し、ファミリー優先の SPA テンプレートギャラリーをレンダリングし、カタログ全体の閲覧 の選択肢で再度尋ねます。選択したファミリーに複数のバリアントがある場合は、フレームワークについて 2 つ目のターミナルの質問を尋ねます。

  7. ユーザーの選択に応じて分岐します。

    • テンプレートファミリーとフレームワークのバリアントが選択されている場合:
      1. SELECTED_TEMPLATE にファミリーのエントリーを、SELECTED_TEMPLATE_VARIANT に正確なフレームワークのバリアントを設定します。固定されたカタログ SHA から選択したテンプレートのアセットを一度だけ解決します。結果には、ファミリーがサポートするソリューションと、選択したバリアントのウェブサイトコードが含まれます。

        node "${PLUGIN_ROOT}/scripts/fetch-template-variant.js" \
          --sha "<catalog-sha>" \
          --catalogPath "<catalogPath from fetch-template-catalog.js>" \
          --kind "<SELECTED_TEMPLATE.kind>" \
          --templateId "<SELECTED_TEMPLATE.id>" \
          --variant "<SELECTED_TEMPLATE_VARIANT.variantKey>" \
          --solutionSettingsJson '<JSON.stringify(SELECTED_TEMPLATE.solutions || [])>'
        

        返された websiteCodePath と solutions を使用します。solutions は返された順序どおりに処理します。スキル内でテンプレートアセットを再検出、並べ替え、再検証してはいけません。

      2. 結果が ok: false の場合は、選択したフレームワークのバリアントが利用できないか無効であることをユーザーに伝えます。同じファミリーに利用可能な別のフレームワークバリアントがある場合は、まずそれらを提示します。ない場合は、一から作成または中止を提示します。パッケージの検証に失敗したバリアントについて template_used を出力してはいけません。ユーザーが一から作成する方法に切り替えた場合は、選択していたフレームワークを推奨します。

      3. 結果が ok: true の場合は、CREATION_PATH = "template"、SELECTED_TEMPLATE_SOLUTIONS = <result.solutions>、SELECTED_TEMPLATE_WEBSITE_CODE = <result.websiteCodePath> を設定します。template_used テレメトリーコマンドをサイレントに実行し(フェイルクローズ)、その後、テンプレートのインストール前タスクを追加します(進捗管理を参照)。再インストールポリシーが判明した後に、実行タスクを追加します。フェーズ 2 に進んではいけません。 このテレメトリーコマンドについてユーザーに言及したり、出力を表示したりしてはいけません。

        node "${PLUGIN_ROOT}/scripts/emit-create-site-template-outcome.js" \
          --eventName template_used \
          --templateId "<SELECTED_TEMPLATE.id>" \
          --templateKind "<SELECTED_TEMPLATE.kind>" \
          --framework "<SELECTED_TEMPLATE_VARIANT.framework>" \
          --audience "<internal|external from Phase 1 discovery>"
        

        --audience はフェーズ 1 で取得したサイトの対象ユーザー(internal または external)であり、カタログマニフェストのテンプレートの audience ペルソナ配列ではありません。サイト名、URL、サブドメイン、自由記述の目的、その他のユーザーを特定できる値は含めてはいけません。

      4. ローカルテンプレートディレクトリを選択を in_progress に設定します。

        ローカルテンプレートプロジェクトを作成する場所を尋ねます。

        質問ヘッダーオプション
        テンプレートサイトのローカルファイルはどこに作成しますか?プロジェクトの場所現在のディレクトリ、現在のディレクトリに新しいフォルダーを作成(推奨)、その他のディレクトリ

        クローン先を解決します。

        • 現在のディレクトリ:<cwd> を使用します。
        • 現在のディレクトリに新しいフォルダーを作成:<cwd>/<__SITE_SLUG__>/ を使用します。
        • その他のディレクトリ:フルパスを尋ね、絶対パスに解決します。

        作成先は存在しないか、空でなければなりません。作成せずに確認します。空でない場合は、別のディレクトリを選択するようユーザーに尋ねます。解決したパスを TEMPLATE_CLONE_OUTPUT_DIRECTORY として保存し、「テンプレートプロジェクトは <resolved path> に作成されます。」と確認して、ローカルテンプレートディレクトリを選択を completed に設定します。

    • 一から作成またはカタログを利用できない場合:CREATION_PATH = "from-scratch" を設定し、以下に進みます。
  8. テンプレートを使用する場合のみ:

    1. ターゲット環境の解決をin_progressとしてマークします。
    2. 共有認証ヘルパーを使用してターゲット環境を解決します:
      node "${PLUGIN_ROOT}/scripts/resolve-template-import-context.js"
      
      以降のテンプレートワークフローでは、返されたenvironmentUrlを使用します。PACインポートラッパーは、この明示的なターゲットURLを使用して現在のPAC認証を利用します。Dataverseの事前チェックとシードヘルパーは内部でAzureトークンを取得するため、認証情報がJSONで返されたり、タスク間で引き継がれたりすることはありません。ok: falseの場合は、エラーを提示してインポートの前に停止します。インポートは試行されていないため、template_import_failureは出力しないでください。テンプレートのパスが選択された時点で、template_usedはすでに出力されています。

🚦 ゲート(同意 · create-site:1.5.confirm-environment): テンプレートのインストールに関する事前チェックを実行する前に、解決されたターゲット環境を確認します。

トリガー: resolve-template-import-context.jsがenvironmentUrlを返した後、CLIテナント、.jsのブロック解除、言語、ソリューションのインポート、シード、または有効化に関するステップを実行する前のフェーズ1.5。 確認が必要な理由: PAC認証が、ユーザーの意図とは異なるDataverse環境を指している可能性があります。事前チェックでも環境レベルの設定を調査または変更することがあるため、このスキルは確認なしに続行してはいけません。 キャンセル時に残るもの: template-cache — テンプレートカタログのアセット、検出されたソリューションのソース、ウェブサイトのコードがすでにローカルにキャッシュされている場合があります。この時点でキャンセルしても、組織への変更は行われていません。

  1. ターゲット環境の解決をcompleted、ターゲット環境の確認をin_progressとしてマークし、環境に関する事前チェックを実行する前に、解決されたターゲット環境をユーザーに確認します:

    質問ヘッダー選択肢
    このテンプレートのインストールに、**<environmentUrl>**をターゲット環境として使用しますか?環境の確認はい、この環境を使用する(推奨)、いいえ、最初からやり直す、キャンセル
    • はい:以下の事前チェックに進みます。
    • いいえ、最初からやり直す:CREATION_PATH = "from-scratch"に設定し、延期されているフレームワーク/場所に関する質問に進みます。環境に関する事前チェックやテンプレートのインポートは実行しないでください。
    • キャンセル:環境に関する事前チェックの前に停止します。インポートは試行されていないため、template_import_failureは出力しないでください。テンプレートのパスが選択された時点で、template_usedはすでに出力されています。
  2. Confirm target environment を completed としてマークし、Validate CLI tenant alignment を in_progress としてマークしてから、両方の CLI に依存するインポート前チェックの前に、PAC CLI と Azure CLI が同じテナントに対して認証されていることを確認します:

    node "${PLUGIN_ROOT}/scripts/validate-cli-tenant-alignment.js" --envUrl "<environmentUrl>"
    
    • ok: true: Validate CLI tenant alignment を completed としてマークします。
    • ok: false: エラーと、存在する場合は pacTenantId、azTenantId、tokenTenantId フィールドを表示します。インポートの前に停止し、PAC 認証または Azure CLI のいずれかを同じテナントに切り替えてからスキルを再実行するようユーザーに伝えます。インポートを試みていないため、template_import_failure を出力しないでください。
  3. Validate JavaScript unblock requirement と Validate Dataverse language requirements の両方を in_progress としてマークします。.js ブロック添付のドライランと Dataverse 言語チェックは、どちらも確認済みのターゲット環境に対する読み取り専用の事前チェックであるため、並行して実行します:

    node "${PLUGIN_ROOT}/scripts/lib/fix-blocked-attachments.js" --envUrl "<environmentUrl>" --extensions js --dry-run --quiet
    node "${PLUGIN_ROOT}/scripts/check-available-languages.js" --envUrl "<environmentUrl>" --requiredLocaleIds "<SELECTED_TEMPLATE_VARIANT.requiredDataverseLanguages または SELECTED_TEMPLATE.requiredDataverseLanguages のカンマ区切り>"
    

    次に何をするかを決める前に、両方の JSON 結果を取得してください。言語チェックも完了するまで blockedattachments を変更しないでください。言語チェックがインポートをブロックする場合は、添付設定を変更せずに言語要件の質問へルーティングしてください。 .js の結果を評価します:

    • wasBlocked に js が含まれない: Validate JavaScript unblock requirement を completed としてマークします。JavaScript 添付は許可されています。
    • wasBlocked に js が含まれる: Validate JavaScript unblock requirement を in_progress のままにします。これには以下の .js ブロック解除の同意ゲートが必要になる場合がありますが、言語の失敗は環境を一切変更せずにインポートをブロックするため、先にそちらを処理してください。 言語の結果を評価します:
    • ok: true かつ hasRequiredLanguages: true: Validate Dataverse language requirements を completed としてマークします。ターゲット環境には、選択したバリアントが必要とするすべての LCID があり、バリアントが上書きしない場合はファミリーの要件にフォールバックします。
    • ok: false: スキルが利用可能な Dataverse 言語を検証できなかったことをユーザーに伝え、スクリプトのエラーを表示してから、ゼロからの作成に切り替えるか停止するかを尋ねます。テンプレートをインポートせず、blockedattachments も変更しないでください。
    • ok: true かつ hasRequiredLanguages: false: 選択したテンプレートが、missingLocaleIds の不足している Dataverse 言語 LCID を必要としていることを説明します。ソリューションのインポート変更の前にブロックします。「それでも続行する」ブランチを提供せず、blockedattachments も変更しないでください。

🚦 ゲート (同意 · create-site:1.5.unblock-js): ウェブサイトのコードをアップロードする前に、ターゲット環境の blockedattachments 設定から .js を事前にブロック解除します。

トリガー: fix-blocked-attachments.js --dry-run --extensions js が、ターゲット環境で .js がブロックされていると報告したときのフェーズ 1.5。 なぜ確認するのか: パッケージ化された SPA は、それを支えるソリューションの準備ができた後に pac pages upload-code-site でアップロードされます。そのアップロードには JavaScript ファイルが含まれており、.js がブロックされていると失敗します。ソリューションのインポート前に確認することで、サイトを作成できないときにサポート用の成果物が残ってしまうのを避けられます。 キャンセルで残るもの: attachment-block-modified は、ユーザーが承認し、更新が部分的に完了した場合にのみ発生する可能性があります。ここで純粋にキャンセルした場合、元の blockedattachments の値は変更されず、テンプレートのインストールも開始されていません。

  `AskUserQuestion` を使用します:
  | 質問 | ヘッダー | 選択肢 |
  |----------|--------|---------|
  | 現在、この環境では `.js` 添付ファイルがブロックされています。.js をブロック解除しないと、テンプレートサイトのコードのアップロードに失敗します。`blockedattachments` から `js` のみを削除しますか? | JavaScript のブロック解除 | はい、`.js` のブロックを解除して続行する(推奨)、いいえ、最初から開始する、キャンセル |

  - **はい**:`--dry-run` を指定せずにヘルパーを実行し、ほかのブロック対象拡張子はすべてそのまま保持します。
    ```bash
    node "${PLUGIN_ROOT}/scripts/lib/fix-blocked-attachments.js" --envUrl "<environmentUrl>" --extensions js --quiet
    ```
    JSON の結果で `removed` に `js` が含まれているか、`changed: true` になっていることを確認してから、ドライランの確認を再実行します。`.js` がブロックされていない場合に限り続行してください。
  - **いいえ、最初から開始する**:`CREATION_PATH = "from-scratch"` を設定し、後回しにしたフレームワーク/場所に関する質問に進みます。テンプレートはインポートしないでください。
  - **キャンセル**:テンプレートのインストール前に停止します。インポートを試みていないため、`template_import_failure` は出力しないでください。テンプレートのパスが選択された時点で、すでに `template_used` が出力されています。



6. 言語の事前確認を続行できない場合に限り、`AskUserQuestion` を使用します。

   | 質問 | ヘッダー | 選択肢 |
   |----------|--------|---------|
   | このテンプレートには Dataverse 言語 LCID `<requiredLocaleIds>` が必要ですが、対象環境には `<missingLocaleIds>` がないか、言語の確認を完了できませんでした。どのようにしますか? | テンプレートの言語要件 | 最初から開始する(推奨)、キャンセル |

   - **最初から開始する**:`CREATION_PATH = "from-scratch"` を設定し、後回しにしたフレームワーク/場所に関する質問に進みます。テンプレートはインポートしないでください。
   - **キャンセル**:テンプレートのインストール前に停止します。インポートを試みていないため、`template_import_failure` は出力しないでください。テンプレートのパスが選択された時点で、すでに `template_used` が出力されています。

🚦 ゲート(同意 · create-site:1.5.template-import): 現在の Power Platform 環境への選択したテンプレートのインストールを確認します。

トリガー: フェーズ 1.5 で、テンプレートのバリアントと展開済みソリューションがダウンロードされ、対象環境が確定した後。 確認する理由: インストールによって、アンマネージドのサポート用ソリューションがインポートされ、新しいコードサイトが作成される場合があります。環境やテンプレートを誤って選ぶと、影響が大きく、きれいに元に戻すことはできません。 キャンセル時に残るもの: template-cache — 検出されたソリューションソースとプレビュー画像が、SHA キー付きのプライベートなテンプレートキャッシュに残る場合があります。組織への変更は行われていません。

  1. 言語の事前確認に合格し、.js がブロックされていてユーザーがブロック解除に同意したか、確認に合格した場合は、JavaScript のブロック解除要件を検証を completed にします。次に、テンプレートのインストールを確認を in_progress にし、テンプレートと環境を提示して、次のように質問します。

    マニフェストのメタデータで publishChanges: true が指定されているサポート用ソリューションをすべて一覧表示します。 これらのソリューションでは pac solution import --publish-changes を使用するため、インポートしたフォーム、ビュー、その他のカスタマイズがインポート直後に表示されることを説明します。 PAC の公開手順によって、対象環境にあるほかの保留中のカスタマイズも公開される可能性があることを明示します。

    質問ヘッダー選択肢
    **<SELECTED_TEMPLATE.displayName>を<environmentUrl>**にインストールしますか?必要なアンマネージドのサポート用ソリューションをインポートし、テンプレートのマニフェストで指定されているソリューションに対して PAC の publish-changes 手順を実行し、ウェブサイトのコードをクローンしてビルドしたうえで、新しいコードサイトをアップロードします。公開手順によって、この環境にあるほかの保留中のカスタマイズも公開される場合があります。利用可能な場合、シードデータは有効化の前に適用されます。テンプレートをインストールはい、このテンプレートをインストールする(推奨)、いいえ、最初から開始する、キャンセル
    • いいえ、最初から始めます:CREATION_PATH = "from-scratch" を設定し、後続のフレームワーク/場所に関する質問に進みます。
    • キャンセル:停止します。組織への変更は行われていません。インポートは試行されていないため、template_import_failure は出力しないでください。テンプレートのパスを選択した時点で、すでに template_used が出力されています。
  2. テンプレートのインストールを確認を completed としてマークします。TEMPLATE_SOLUTIONS_TO_IMPORT = [] および TEMPLATE_SOLUTIONS_TO_SKIP = [] を初期化し、SELECTED_TEMPLATE_SOLUTIONS のすべてのエントリを、返された順に処理します。

    node "${PLUGIN_ROOT}/scripts/inspect-template-solution.js" --solutionPath "<solution.solutionPath>"
    node "${PLUGIN_ROOT}/scripts/check-solution-installed.js" --solutionName "<solution.uniqueName>" --envUrl "<environmentUrl>"
    node "${PLUGIN_ROOT}/scripts/inspect-template-solution.js" --solutionPath "<solution.solutionPath>" --installed "<true|false>" --installedVersion "<version-or-empty>"
    

    ソリューションから Web サイト名を推測したり、サポート用ソリューションのインポートによって pac pages list -v の行が追加されると想定したりしないでください。バリアントの検証後にメタデータの検査で ok: false が返された場合、または check-solution-installed.js が 1 で終了した場合は、そのソリューションを存在しないと決めつけず、decision: "ask" として扱います。

    • decision: "import":ソリューションを TEMPLATE_SOLUTIONS_TO_IMPORT に追加します。

    • decision: "confirm-update":この特定のソリューションに新しいバージョンがあることをユーザーに伝え、TEMPLATE_SOLUTIONS_TO_IMPORT に追加する前に確認します。

      🚦 ゲート(同意 · create-site:1.5.update-installed): すでにインストールされている、管理されていないテンプレートソリューションを更新するか確認します。更新が必要なソリューションごとに繰り返します。

      トリガー: 選択したテンプレートソリューションのいずれかがすでにインストールされており、ダウンロードしたソースに新しいバージョンがある場合、フェーズ 1.5 で実行します。 ループの動作: SELECTED_TEMPLATE_SOLUTIONS 内で条件に一致するエントリごとに 1 回実行します。更新が必要なソリューションが 3 つある場合は、確認も 3 回行います。 確認する理由: 管理されていないソリューションを更新すると、環境に変更がマージされ、完全にロールバックできないためです。 キャンセル後に残るもの: template-cache — ダウンロードしたテンプレートの成果物は、プライベートな SHA キー付きテンプレートキャッシュに残ります。キャンセルした場合、組織への変更は行われません。

      AskUserQuestion を使用します:

      質問ヘッダー選択肢
      ソリューション <solution.uniqueName> はバージョン <installedVersion> でインストールされており、テンプレートには <availableVersion> が含まれています。この環境で更新しますか?ソリューションを更新はい、このソリューションを更新します(推奨)、いいえ、キャンセル

      ユーザーが拒否またはキャンセルした場合は、インポートする前に停止します。組織への変更は行われていません。インポートは試行されていないため、template_import_failure は出力しないでください。テンプレートのパスを選択した時点で、すでに template_used が出力されています。 ユーザーが確認した場合は、このソリューションを TEMPLATE_SOLUTIONS_TO_IMPORT に追加します。

    • decision: "offer-clone":同じバージョンまたはそれより新しいソリューションを TEMPLATE_SOLUTIONS_TO_SKIP に追加します。

    • decision: "ask" または検出に失敗した場合:そのソリューションをインポートするか、最初から始めるか、停止するかを確認します。

      🚦 ゲート(同意 · create-site:1.5.reinstall-unknown): インストール済みソリューションの検出に失敗した場合に、インポートするか確認します。

      トリガー: 選択したテンプレートソリューションのいずれかがすでに存在するかどうかを check-solution-installed.js で判定できない場合、フェーズ 1.5 で実行します。 ループの動作: SELECTED_TEMPLATE_SOLUTIONS 内で状態が不明なエントリごとに 1 回実行します。回答は、指定されたソリューションにのみ適用されます。 確認する理由: すでに存在する可能性がある、管理されていないソリューションをインポートすると、コンポーネントがマージされる可能性があるためです。 キャンセル後に残るもの: template-cache — ダウンロードしたテンプレートの成果物は、プライベートな SHA キー付きテンプレートキャッシュに残ります。キャンセルした場合、組織への変更は行われません。 次を使用します:AskUserQuestion。

      QuestionHeaderOptions
      ソリューション <solution.uniqueName> がインストールされているかどうかを判断できませんでした。このソリューションをインポートすると、未管理コンポーネントがマージされる可能性があります。どのように進めますか?Solution Install UnknownImport anyway (advanced), Start from scratch (Recommended), Stop

      回答に応じて分岐します:

      • Import anyway:このソリューションを TEMPLATE_SOLUTIONS_TO_IMPORT に追加します。
      • Start from scratch:CREATION_PATH = "from-scratch" を設定し、後続のフレームワーク/場所に関する質問に進みます。
      • Stop:インポートの前に停止します。組織への変更は行われていません。インポートは試行されていないため、template_import_failure は出力しません。テンプレートのパスを選択した時点で template_used はすでに出力されています。

    サイトのインストールタスク全体を追加します。 TEMPLATE_SOLUTIONS_TO_IMPORT が空でない場合に限り、Import template supporting solutions を含めます。 すべてのソリューションがスキップされた場合は、サイトの作成前に一度だけ確認します:

    🚦 ゲート(同意・create-site:1.5.clone-existing): すでにインストール済みのサポート対象ソリューションを再利用して新しいサイトを作成することを確認します。

    トリガー: 選択されたすべてのテンプレートソリューションが、同じバージョンまたはそれより新しいバージョンでインストール済みの場合のフェーズ 1.5。 確認する理由: スキルはすべてのソリューションのインポートをスキップしますが、新しいコードサイトのクローン作成とアップロードは行います。 キャンセル時に残るもの: template-cache — ダウンロード済みのテンプレート成果物は、SHA キーで管理されるプライベートなテンプレートキャッシュに残ります。キャンセルした場合、サイトのクローン作成/アップロードは行われません。

    QuestionHeaderOptions
    すべてのサポート対象ソリューションは、同じバージョンまたはそれより新しいバージョンでインストール済みです。ウェブサイトのコードから新しい <SELECTED_TEMPLATE_VARIANT.framework> サイトを作成しますか?Create Template SiteYes, create the site (Recommended), No, cancel

    ユーザーが確認した場合は、SKIP_TEMPLATE_SOLUTION_IMPORT = true を設定します。ユーザーが拒否した場合は停止します。ソリューションのインポートは試行されていないため、インポート結果イベントは出力しません。

  3. 読み取り専用のステータスページをレンダリングして開きます:

    # Create <temp-import-status-dir>/ under the operating-system temporary directory,
    # then write this initial status JSON to <temp-import-status-dir>/status.json:
    # Import path:
    # Use "Installing solution" when TEMPLATE_SOLUTIONS_TO_IMPORT has one entry,
    # otherwise use "Installing solutions":
    # { "state": "running", "phase": "solution", "message": "<solution install label>" }
    # SKIP_TEMPLATE_SOLUTION_IMPORT path:
    # { "state": "running", "phase": "site", "message": "Preparing template site" }
    node "${PLUGIN_ROOT}/scripts/render-template-import-status.js" \
      --templateName "<SELECTED_TEMPLATE.displayName>" \
      --statusPath "<temp-import-status-dir>/status.json" \
      --previewImagesJson '<JSON array of SELECTED_TEMPLATE.previewImages localUrl values from the template browser step>' \
      --solutionCount "<TEMPLATE_SOLUTIONS_TO_IMPORT.length, or SELECTED_TEMPLATE_SOLUTIONS.length when imports are skipped>" \
      --outputPath "<temp-import-status-dir>/index.html"
    node "${PLUGIN_ROOT}/scripts/serve-static-dir.js" --root "<temp-import-status-dir>" --urlFile "<temp-import-status-dir>/url.txt" --cleanupRoot
    node "${PLUGIN_ROOT}/scripts/open-url.js" --url "<url from <temp-import-status-dir>/url.txt>"
    

    ブラウザーステップでダウンロード済みのローカルプレビュー画像 URL を再利用してください。このページのためにプレビュー画像を再度取得しないでください。 サーバーコマンドは、リスナーが準備完了した後にのみ復帰します。リダイレクトが成功した後、ブラウザーがポーリングを停止した後、または最大有効期間が経過した後に、一時ステータスディレクトリを削除します。

  4. SKIP_TEMPLATE_SOLUTION_IMPORT = true でない限り、Import template supporting solutions を in_progress としてマークします。TEMPLATE_SOLUTIONS_TO_IMPORT を既存の大文字小文字を区別しない辞書順の一意名の順序で逐次処理します。各エントリについて、CURRENT_TEMPLATE_SOLUTION を設定し、そのアンマネージドソリューションをインポートできるよう準備します:

    # Update the status JSON:
    # { "state": "running", "phase": "solution", "message": "Preparing solution <CURRENT_TEMPLATE_SOLUTION.uniqueName>" }
    node "${PLUGIN_ROOT}/scripts/pack-template-solution.js" \
      --solutionPath "<CURRENT_TEMPLATE_SOLUTION.solutionPath>"
    

    現在のソリューションに対して PACKED_TEMPLATE_SOLUTION_ZIP = <result.zipPath>、PACKED_TEMPLATE_SOLUTION_WORK_DIRECTORY = <result.workDirectory>、PACKED_TEMPLATE_SOLUTION_CLEANUP_MARKER = <result.cleanupMarker>、PACKED_TEMPLATE_SOLUTION_CLEANUP_TOKEN = <result.cleanupToken> を設定します。パッカーはトークンが所有する OS の一時ディレクトリ内にのみ ZIP を作成します。パック済みの ZIP をダウンロード済みテンプレートキャッシュやその他のリポジトリパスに書き込まないでください。

    パッキングが失敗した場合、インポートが試行されていないため、Dataverse を呼び出さず、template_import_failure も出力しないでください。パッカーは部分的な出力を自動的に削除します。

    🚦 ゲート (progress · create-site:1.5.pack-failed): ローカルソリューションパッケージの準備が失敗した後の進め方を選択します。

    トリガー: 検出された 1 つのソリューションについて、ローカル検証または pac solution pack が失敗したときのフェーズ 1.5。 ループの動作: TEMPLATE_SOLUTIONS_TO_IMPORT の失敗した各イテレーションごとに発生します。回答は CURRENT_TEMPLATE_SOLUTION にのみ適用されます。 なぜ質問するのか: 環境の変更はまだ発生していませんが、有効な一時ソリューション ZIP がないとテンプレートのインストールを続行できません。 キャンセル時に残るもの: template-cache — ダウンロード済みのテンプレートソースはプライベートな SHA をキーとするテンプレートキャッシュに残ります。部分的なパック出力は削除されています。

    AskUserQuestion を使用します:

    質問ヘッダー選択肢
    ソリューション <CURRENT_TEMPLATE_SOLUTION.uniqueName> をインポート用に準備できませんでした。どのように続行しますか?テンプレートパックの失敗パックを再試行する、ゼロから作成に切り替える(推奨)、停止する
    • パックを再試行する: 上記のパックコマンドに戻ります。
    • ゼロから作成に切り替える: CREATION_PATH = "from-scratch" を設定し、後回しにしたフレームワークと場所に関する質問に進みます。
    • 停止する: ローカルパックエラーを表示した後に停止します。Import template supporting solutions を完了としてマークしないでください。

    パックに成功したら、PAC CLI ラッパーを使用して一時 ZIP をインポートします。/import-solution を呼び出したり、ALM アーティファクトを書き込んだりしないでください。 ソリューションレベルの publishChanges 値は、固定されたテンプレートマニフェストに基づきます。 この値が true の場合に限り、ラッパーは pac solution import --publish-changes を追加します。

    { "state": "running", "phase": "solution", "message": "Importing solution <CURRENT_TEMPLATE_SOLUTION.uniqueName>" }
    

    このオブジェクトを <temp-import-status-dir>/status.json に書き込んでから、Task サブエージェントで run_in_background: true を指定してインポートラッパーを実行します。

    node "${PLUGIN_ROOT}/scripts/import-template-solution.js" \
      --zipPath "<PACKED_TEMPLATE_SOLUTION_ZIP>" \
      --envUrl "<environmentUrl>" \
      --publishChanges "<CURRENT_TEMPLATE_SOLUTION.publishChanges>"
    

    Task はラッパーの完全な JSON 結果を返す必要があります。 処理が完了したら、メインの会話内で所有する一時ディレクトリをクリーンアップします。

    node "${PLUGIN_ROOT}/scripts/pack-template-solution.js" \
      --cleanup \
      --workDirectory "<PACKED_TEMPLATE_SOLUTION_WORK_DIRECTORY>" \
      --cleanupMarker "<PACKED_TEMPLATE_SOLUTION_CLEANUP_MARKER>" \
      --cleanupToken "<PACKED_TEMPLATE_SOLUTION_CLEANUP_TOKEN>"
    

    インポートコマンドが返った後は、必ず所有する一時ディレクトリをクリーンアップしてください。 クリーンアップに失敗した場合は、ローカル警告として扱い、ユーザーが手動で削除できるように作業ディレクトリのパスを表示してください。インポート結果を隠さないでください。 現在のコマンドが ok: true を返すまで次のソリューションのインポートを開始しないでください。また、TEMPLATE_SOLUTIONS_TO_IMPORT 内のすべてのソリューションのインポートが成功するまで、サイトのクローン作成を開始しないでください。 インポートラッパーが ok: false を返した場合、管理対象外の部分インポートを自動でクリーンアップしないでください。 復旧について質問する前に、template_import_failure テレメトリーコマンドを通知なしで実行してください。 このテレメトリーコマンドについてユーザーに言及したり、その出力を表示したりしないでください。

    node "${PLUGIN_ROOT}/scripts/emit-create-site-template-outcome.js" \
      --eventName template_import_failure \
      --templateId "<SELECTED_TEMPLATE.id>" \
      --templateKind "<SELECTED_TEMPLATE.kind>" \
      --framework "<SELECTED_TEMPLATE_VARIANT.framework>" \
      --audience "<Phase 1 の検出結果に基づく internal|external>" \
      --outcome failure \
      --errorClass "PacSolutionImport"
    

    --audience は Phase 1 で取得したサイトのオーディエンス(internal または external)です。カタログマニフェストにあるテンプレートの audience ペルソナ配列ではありません。自由形式のエラーテキストをテレメトリーに追加しないでください。パス、URL、スタックトレース、ユーザーデータが含まれる可能性があります。

    🚦 ゲート(進捗・create-site:1.5.import-failed): テンプレートソリューションのインポートに失敗した後の進め方を選択してください。

    トリガー: pac solution import が失敗するかタイムアウトした場合のフェーズ 1.5。 ループの動作: TEMPLATE_SOLUTIONS_TO_IMPORT の失敗したイテレーションごとに実行されます。回答は CURRENT_TEMPLATE_SOLUTION にのみ適用されます。 質問する理由: 環境には、今回の実行中にインポートされた現在の部分的なアンマネージドインポートと、それ以前のソリューションが含まれている可能性があります。ローカルでのタイムアウトによって、すでに開始されたサーバー側のインポートがキャンセルされることはないため、再試行するか別の手順に切り替えるかは、明示的に選択する必要があります。 キャンセル時に残るもの: partial-unmanaged-template-import — ダウンロード済みのテンプレートアーティファクトは、SHA をキーとする非公開のテンプレートキャッシュに残ります。現在の部分的なインポートと、それ以前に正常にインポートされたソリューションは Dataverse に残り、エラー概要で説明されます。

    AskUserQuestion を使用します。

    質問ヘッダー選択肢
    サポートソリューション <CURRENT_TEMPLATE_SOLUTION.uniqueName> のインポートに失敗したか、一部のみ完了しました。どのように進めますか?テンプレートのインポートに失敗インポートを再試行、最初から作成に切り替える(推奨)、停止

    回答に応じて分岐します。

    • インポートを再試行:上記のパッケージ化とインポートのコマンドシーケンスに戻ります。
    • 最初から作成に切り替える:CREATION_PATH = "from-scratch" を設定し、後続のフレームワーク/場所に関する質問に進みます。アンマネージドの部分的なインポートが Dataverse に残る可能性があることをユーザーに伝えます。最終的に、最初から作成する分岐で単一の終了テレメトリーイベントが出力されます。
    • 停止:エラー概要を表示した後、処理を停止します。テンプレートのサポートソリューションをインポートを完了としてマークせず、サイトのクローン作成やアップロードも行いません。template_import_failure イベントは、インポート失敗の検出時にすでに出力されています。

    エラーが AttachmentBlocked の場合は、/import-solution のフェーズ 5b の対処方法を案内します。 インポートラッパーが ok: true を返した場合にのみ、次のステップに進みます。

  5. 必要なすべてのソリューションのインポートが成功したら、シード計画とサイトのプロビジョニングに進みます。 これらの確認が完了した後にのみ、テンプレートのサポートソリューションをインポートを completed としてマークし、EMIT_TEMPLATE_IMPORT_SUCCESS = true を設定します。 seedApplied に今回の実行結果が反映されるよう、シードデータの作業ストリームが合流するまで、このテレメトリーイベントの出力を保留します。 すべてのソリューションのインポートがスキップされた場合は、タスクをスキップとしてマークし、EMIT_TEMPLATE_IMPORT_SUCCESS = false を設定します。

  6. 変更を伴ういずれかの作業ストリームを開始する前に、メインの会話でシードデータを準備します。 シードデータがある場合は、取得します。

    node "${PLUGIN_ROOT}/scripts/fetch-template-seed-data.js" --sha "<catalog-sha>" --seedDataPath "<SELECTED_TEMPLATE_VARIANT.seedDataPath or SELECTED_TEMPLATE.seedDataPath>"
    

    成功した結果の localDir と seedFile を、それぞれ TEMPLATE_SEED_DIRECTORY と TEMPLATE_SEED_FILE として保存します。 レコードを挿入せずに、ソースとターゲットを確認します。

    node "${PLUGIN_ROOT}/scripts/apply-seed-data.js" \
      --seedDir "<TEMPLATE_SEED_DIRECTORY>" \
      --seedFile "<TEMPLATE_SEED_FILE>" \
      --envUrl "<environmentUrl>" \
      --plan
    

    writes: 0 の状態で、テーブル/レコード/ファイルの件数、財務エンティティセット、アクティブなターゲット通貨が報告されます。

    requiresCurrencySelection が true の場合、金融サンプル行に使用する既存の有効な通貨をメインの会話で尋ねます。 利用可能な通貨コード/名称を表示し、数値の金額は換算されないことを説明して、サンプルデータをスキップを提示します。 通貨を作成したり、ソース環境の通貨 GUID をコピーしたり、黙って USD を仮定したりしないでください。 選択した ISO コードを TEMPLATE_SEED_CURRENCY_CODE として保存します。 ユーザーがサンプルデータをスキップした場合、シード書き込みを開始しないでください。 金融行がない場合は、通貨の選択と --currencyCode フラグを省略します。 取得/計画の失敗は、ベストエフォートのシード失敗として扱います。明示的な失敗を表示し、シードの概要に保持して、レコードが挿入されたかのように装うことなく、シードタスクなしでサイトを作成します。

    インポートとメインの会話でのシードに関する決定が正常に完了した後にのみ、サイトのプロビジョニングとシードデータの適用を並行して開始します。

    • テンプレートサイトのクローン、ビルド、アップロードを in_progress に設定します。
    • シードデータの準備ができており、スキップされていない場合は、テンプレートのシードデータを適用を in_progress に設定し、run_in_background: true を指定した Task でシードデータのワークストリームを開始します。バックグラウンドタスクでは、準備済みのシードデータの適用と検証のみを行います。クローン、ビルド、アップロード、有効化、共有ステータスファイルの更新、ユーザーへの質問、失敗した書き込みの再試行は行いません。
    • シードデータのタスクの実行中に、メインの会話でサイトプロビジョニングのラッパーを実行します。必要な Dataverse テーブルがサポートソリューションのインポートによって作成された後は、これらのワークストリームは独立して実行できます。 シードデータがある場合は、ステータスページを更新します:
    { "state": "running", "phase": "siteAndSeed", "message": "Creating template site and seeding data" }
    

    シードデータがない場合は、次の内容で更新します:

    { "state": "running", "phase": "site", "message": "Cloning, building, and uploading template site" }
    

    パッケージ化された SPA ソースを、先ほど選択したディレクトリに複製してから、その複製をアップロードします:

    node "${PLUGIN_ROOT}/scripts/provision-template-site.js" \
      --sourcePath "<SELECTED_TEMPLATE_WEBSITE_CODE>" \
      --outputDirectory "<TEMPLATE_CLONE_OUTPUT_DIRECTORY>" \
      --siteName "<__SITE_NAME__>"
    

    ラッパーを、テンプレートサイトのプロビジョニングに使う唯一のエントリーポイントとして扱います。診断のために、内部で実行される pac、npm、またはビルドコマンドを直接再実行しないでください。pac pages clone や pac pages upload-code-site などの状態を変更するコマンドを、コマンドの完了前に出力ストリームを閉じる可能性がある head、tail、その他のコマンドにパイプしないでください。ラッパーはコマンドを中断せず、長さを制限した診断用の末尾出力を安全に取得します。成功したら、返された clonedPath を CLONED_TEMPLATE_SITE_PATH と PROJECT_ROOT の両方に、siteName を IMPORTED_SITE_NAME に、websiteRecordId を IMPORTED_WEBSITE_RECORD_ID に保存します。

  7. シードデータのバックグラウンドタスクでは、メインの会話で準備したディレクトリ/ファイルと通貨の決定を使用します:

    node "${PLUGIN_ROOT}/scripts/apply-seed-data.js" \
      --seedDir "<TEMPLATE_SEED_DIRECTORY>" \
      --seedFile "<TEMPLATE_SEED_FILE>" \
      --envUrl "<environmentUrl>" \
      --currencyCode "<TEMPLATE_SEED_CURRENCY_CODE, only when financial rows were planned>"
    

    財務関連の行を予定していない場合は、通貨フラグ全体を省略します。 シーダーは、書き込みを行う前に、既存かつアクティブな対象通貨と、その正確なメタデータナビゲーションのみを解決します。 作成ペイロードから、宣言されたアップロード列の値と、それに対応して生成されたファイル名を削除します。これらのフィールドにはファイルアップロードアクションで値を設定します。 完全な JSON サマリー(ok、inserted、failed、skipped、errors)をメインの会話に返します。 行、状態、検証、ファイルアップロードのいずれかに部分的な失敗があった場合は、ok: false として報告します。CLI の終了コードが成功だったという理由だけで成功と判断しないでください。 シードレコードでは、テンプレートソリューションのメタデータに記載された正確なテーブルのエンティティセット名、列の論理名、スカラーまたはコレクションの <NavigationProperty>@odata.bind 参照名を使用する必要があります。 主キー、エンティティセット、表示名、または categoryId などのアプリ形式の別名から、参照ナビゲーションプロパティを推測しないでください。シーダーは、あいまいな別名と不正なコレクション参照を、最初の Dataverse 書き込みより前に拒否します。 検証では、$top=1 だけでなく、予定したレコード ID をクエリし、想定される参照とネイティブなコレクションのメンバーシップを比較します。 アップロードした添付ファイルは、作成された添付ファイル行の数だけでなく、対象のファイルメタデータ/コンテンツを通じてそれぞれ検証します。 通常の既存シードレコードのスキップでは、ネイティブな N:N メンバーシップは調整されません。この制限を明示し、既存の連絡先、事業者、または割り当てを黙って更新しないでください。

  8. 非アクティブなサイトのサマリーを表示する前、またはアクティブ化を開始する前に、両方の作業の完了を待ちます。シードのサマリーを記録してから、テンプレートのシードデータを適用を completed にします。シードデータがない場合は、スキップとして記録します。シードの取得と挿入はベストエフォートで実行します。結果を提示しますが、サイトの作成を失敗扱いにしたり、アクティブ化を妨げたりしないでください。 EMIT_TEMPLATE_IMPORT_SUCCESS = true の場合、ここでインポート結果を出力します:

    node "${PLUGIN_ROOT}/scripts/emit-create-site-template-outcome.js" \
      --eventName template_import_success \
      --templateId "<SELECTED_TEMPLATE.id>" \
      --templateKind "<SELECTED_TEMPLATE.kind>" \
      --framework "<SELECTED_TEMPLATE_VARIANT.framework>" \
      --audience "<internal|external from Phase 1 discovery>" \
      --seedApplied "<true only when the seed summary has inserted > 0 and failed = 0; otherwise false>"
    

    --audience はフェーズ 1 で取得したサイトのオーディエンス (internal または external) であり、カタログマニフェストにあるテンプレートの audience ペルソナ配列ではありません。サイト名、URL、サブドメイン、自由記述の目的、その他のユーザーを特定できる値を含めないでください。

  9. クローン、クローンされた識別情報の検査、依存関係のインストール、ビルド、ビルド出力の検証、またはアップロードが失敗した場合、template_clone_failure テレメトリをサイレントに実行します。返された step を errorClass にマッピングします: clone/clone-output → PacPagesClone、install → NpmInstall、build → NpmBuild、build-output → CompiledOutput、upload → PacPagesUploadCodeSite:

    node "${PLUGIN_ROOT}/scripts/emit-create-site-template-outcome.js" \
      --eventName template_clone_failure \
      --templateId "<SELECTED_TEMPLATE.id>" \
      --templateKind "<SELECTED_TEMPLATE.kind>" \
      --framework "<SELECTED_TEMPLATE_VARIANT.framework>" \
      --audience "<internal|external from Phase 1 discovery>" \
      --outcome failure \
      --errorClass "<PacPagesClone|NpmInstall|NpmBuild|CompiledOutput|PacPagesUploadCodeSite>"
    

    リカバリゲートを発火する前にステータスページを更新します:

    { "state": "error", "phase": "site", "message": "Template site creation failed" }
    

    失敗の診断は、ラッパーが返した step、error、および保持されたローカルパスのみから行ってください。ユーザーがリカバリオプションを選択するまで、ラッパーや基盤となるコマンドを再実行しないでください。 その後、このゲートを発火します:

  > 🚦 **ゲート (進行状況 · create-site:1.5.clone-failed):** パッケージ化されたテンプレートサイトのクローン、ビルド、またはアップロードが失敗した後の進め方を選択してください。
  >
  > **トリガー:** フェーズ 1.5 で、クローン、クローンされた識別情報の検査、依存関係のインストール、プロジェクトのビルド、コンパイル済み出力の検証、または `pac pages upload-code-site` が失敗したとき。
  > **確認する理由:** 選択したプロジェクトディレクトリに部分的なクローンやビルド出力が含まれている可能性があり、環境に部分的なコードサイトのアップロードが含まれている可能性があり、サポートソリューションがすでにインストールされている可能性があります。
  > **キャンセルで残るもの:** `partial-template-clone` — キャッシュされたテンプレート成果物とローカルファイルが選択したプロジェクトディレクトリに残ります。サポートソリューションや部分的なサイトアップロードも Dataverse に残る可能性があります。

  | 質問 | ヘッダー | オプション |
  |----------|--------|---------|
  | テンプレートサイトをクローン、ビルド、またはアップロードできませんでした。どのように進めますか? | サイト作成に失敗しました | サイト作成を再試行する (推奨)、ゼロからの作成にフォールバック、停止 |
  自動で再試行しないでください。ラッパーが `outputDirectoryRemoved: true` を返した場合、**Retry site creation** では同じ選択済みの場所を再利用できます。それ以外の場合は、同じ **Project Location** プロンプトを使って空のディレクトリを新たに指定してもらい、`TEMPLATE_CLONE_OUTPUT_DIRECTORY` を更新してラッパーを再実行してください。ユーザーがゼロからの作成に切り替える場合は、ローカルファイル、サポートソリューション、または部分的なサイトのアップロードが残っている可能性を説明し、`<SELECTED_TEMPLATE_VARIANT.framework>` を推奨してください。

13. クローン、ビルド、アップロードが成功したら、Clone, build, and upload template site を completed にし、template_clone_success テレメトリーをサイレントに実行してください。 bash node "${PLUGIN_ROOT}/scripts/emit-create-site-template-outcome.js" \ --eventName template_clone_success \ --templateId "<SELECTED_TEMPLATE.id>" \ --templateKind "<SELECTED_TEMPLATE.kind>" \ --framework "<SELECTED_TEMPLATE_VARIANT.framework>" \ --audience "<internal|external from Phase 1 discovery>" サイト名、クローンパス、URL、または Website Record ID はテレメトリーに含めないでください。 14. Show inactive template site を in_progress にします。ユーザーに次のように伝えてください。「テンプレート <displayName> が <IMPORTED_SITE_NAME>(<IMPORTED_WEBSITE_RECORD_ID>)として作成されました。まだ有効化されていません。シードデータの処理は完了しており、次は有効化です。」テンプレートにシードデータがない場合は、レコードが挿入されたと誤解されないよう、その旨を伝えてください。Show inactive template site を completed にします。 15. Activate template site を in_progress にします。/activate-site を呼び出す前に、ステータスページを更新してください。 json { "state": "running", "phase": "activation", "message": "Activating template site", "awaitingInput": false } 次に、解決済みの ID とステータスパスをリクエストに渡して /activate-site を呼び出します。これにより、ローカルプロジェクトの検出をスキップし、有効化の入力を待つ間にトーストを表示できます。 text Activate cloned template site: - siteName: <IMPORTED_SITE_NAME> - websiteRecordId: <IMPORTED_WEBSITE_RECORD_ID> - environmentUrl: <environmentUrl> - statusPath: <temp-import-status-dir>/status.json - source: create-site template path activate-site スキルが、サブドメインの選択、入力待ちのトースト、最終的な有効化の確認、プロビジョニング状況のポーリング、復旧を担当します。このフローで必要なポーリングは、フォアグラウンドの有効化スクリプトによるものだけです。 有効化に失敗した場合は、クローンしたサイトは存在するものの公開されておらず、この ID を指定して /activate-site を再実行すれば後から有効化できるとユーザーに伝えてください。有効化の失敗を、サポートソリューションのインポートやサイトのアップロードの失敗として扱わないでください。 16. /activate-site が siteUrl を返したら、Activate template site を completed にし、Show live template site を in_progress にします。 17. すでに開いているステータスページをライブサイトにリダイレクトします。 json { "state": "succeeded", "message": "Template site is live. Opening it now...", "redirectUrl": "<siteUrl>", "shutdownServer": true } テンプレートパス用に別のブラウザーページを開かないでください。ステータスページはこのファイルをポーリングし、URL が http または https の場合、同じタブを redirectUrl にリダイレクトします。shutdownServer: true は、リダイレクト猶予期間の後にローカルサーバーが一時ステータスディレクトリを削除するよう指示します。ユーザーがステータスページを閉じていた場合は、手動で開けるよう siteUrl を表示してください。 activate-site の DNS 伝播に関する注意事項は必ず伝えてください。アクティベーションが成功した後も、サイトの読み込みに数分かかる場合があります。ライブ URL が HTTP 200 を返すまで待つためのバックグラウンドコマンドや Task を別途開始しないでください。ステータスページへのリダイレクトと DNS に関する注意事項でこの遅延に対応できるため、完了サマリーの後も会話を再開できる作業を残さずに済みます。誤って到達可能性のポーリングを開始した場合は、Show live template site を completed にする前に停止してください。 18. Show live template site を completed にしてから、テンプレートのパスに関するサマリーを提示してください。 - テンプレート名とフレームワーク - クローンしたサイト名と Website Record ID - ライブサイトの URL - DNS 伝播に関する注意事項:サイトがどこからでも読み込めるようになるまで数分かかる場合があります - ローカルプロジェクトのパス(PROJECT_ROOT) - "サイトが公開されました。ローカルプロジェクトのカスタマイズを続けますか?"

  1. AskUserQuestion を使用してください。

    質問ヘッダー選択肢
    テンプレートサイトが公開されました。今すぐローカルプロジェクトをカスタマイズしますか?テンプレートサイトをカスタマイズはい、今すぐカスタマイズする(推奨)、いいえ、ここで終了する
    • いいえ、ここで終了する:Select template or choose from-scratch を completed にしてから終了してください。
    • はい、今すぐカスタマイズする:Progress Tracking を参照してテンプレートのカスタマイズタスクを追加し、以下の手順に進んでください。
  2. Plan template customizations を in_progress にしてから、ユーザーに変更内容を尋ねる前にクローンしたプロジェクトを調べてください。

    node "${PLUGIN_ROOT}/scripts/lib/localization-config.js" inspect --projectRoot "<PROJECT_ROOT>"
    

    Phase 4 の計画に必要な言語コンテキストを、次の順序で確立してください。

    • localization.detected=true かつ localization.valid=true の場合は、localization.defaultLocale を正式なロケールとして使用してください。resolve-locale で解決し、返された locale、direction、languageName から SITE_LOCALE、SITE_DIRECTION、SITE_LANGUAGE を設定します。地域や文字体系の詳細を表示する必要がある場合は、localeName も保持してください。ロケール固有のドキュメントルートを、単一言語サイトを示すものとしてスキャンしないでください。
    • localization.detected=true かつ localization.valid=false の場合は、ローカライズ設定の競合を表示して、カスタマイズの計画を立てる前に停止してください。ローカライズ設定を修復する必要があります。静的なドキュメント属性を代わりに使用したり、ローカライズされたルートを単一言語の競合として報告したりしないでください。
    • ローカライズが検出されず、siteLanguage.detected=true かつ siteLanguage.valid=true の場合は、resolve-locale で siteLanguage.locale を解決してください。返された locale、direction、languageName を使用して、SITE_LOCALE、SITE_DIRECTION、SITE_LANGUAGE を設定してください。
    • siteLanguage.reason が document-not-found、html-root-not-found、document-ambiguous、または document-configuration-invalid の場合は、競合と expectedSources を表示して、カスタマイズの計画を立てる前に停止してください。コンテンツの言語を尋ねる前に、実際のアプリケーションのルートドキュメントを見つけるか修復してください。
    • ドキュメントは存在するものの、静的な言語属性が見つからないか無効な場合は、以下の コンテンツの言語 の質問を行い、回答を resolve-locale で解決してください。そのうえで、siteLanguage.source の修復を承認済みのカスタマイズ計画に含めてください。 SITE_LANGUAGE、SITE_LOCALE、SITE_DIRECTION がすべて確定したら、PROJECT_ROOT で何を変更したいかをユーザーに尋ねます。クローンしたプロジェクトに対して、既存の Phase 3/4/5/6/7 の実装・検証・レビューのフローを使用してください。Phase 2 の scaffold/copy-template は実行しないでください。 Phase 3 では、Brand サブプロンプトをスキップし、BRAND_SOURCE を template に設定します。ユーザーが再設計を求めない限り、テンプレートの既存のテーマトークンが信頼できる情報源となります。このパスでは、Phase 5 はクローンしたプロジェクトをその場で編集します。既存のテーマファイル、レイアウト、ページを維持し、承認された計画に記載されたものだけを変更し、ローダーが実行されていないため、すべての scaffold-status.json ステップをスキップします。変更したページに対して Phase 5.7 のデザインクリティークを実行してください。
  3. カスタマイズ計画が承認されたら、Plan template customizations を completed に、Implement pages and components を in_progress にマークし、要求された変更を行います。

  4. 既存の検証・レビューのフローを実行します。ユーザーが明示的に /deploy-site の実行を求めない限り、自動的にデプロイしないでください。

  5. ゼロからの作成パスの場合に限り、ユーザーに伝えてください: 「このサイトをゼロから scaffold します。」

  6. Phase 1 から先送りされていた、ゼロからの作成パス専用の質問をします:

    QuestionHeaderOptions
    Which frontend framework?FrameworkReact (Recommended), Vue, Angular, Astro
    Where should the project be created?LocationCurrent directory, New folder in current directory (Recommended), Any other directory
  7. 目的が $ARGUMENTS で指定されたかどうかとは関係なく、サイトの単一のコンテンツ言語を決定します。

  • リクエストがコンテンツ言語を明示的に指定している場合は、再度尋ねることなく解決し、確認に含めます。
  • 制作者との会話に使われた言語だけから、希望するサイト言語を推測しないでください。

コンテンツ言語が明示されていない場合は、最善の提案を取得します:

node "${PLUGIN_ROOT}/scripts/suggest-content-locale.js"

このスクリプトは、PAC と Azure CLI の認証が利用可能な場合、選択された Dataverse 環境の基本言語を正規の BCP-47 ロケールとして返します。環境、認証、API レスポンス、または LCID マッピングが利用できない場合は、"source": "fallback" とともに en-US を暗黙的に返します。ルックアップがフォールバックした場合は、再試行したり、エラーを表示したり、サイト作成をブロックしたりしないでください。

AskUserQuestion を使用します:

QuestionHeaderOptions
Which language should the site content use?

Pages, navigation, buttons, forms, and accessibility text will use this language. Dataverse and Power Pages system messages will remain in English.
Site content language<language> (<locale>) (Suggested), English (en-US)

<language> と <locale> をスクリプトの結果に置き換えます。その結果が en-US の場合は、重複する英語の選択肢を追加するのではなく、English (United States) (en-US) (Suggested) のみを表示します。環境から導出された選択肢には Recommended ではなく Suggested というラベルを付けます。環境の基本言語は有用なコンテキストですが、公開サイトの意図する言語と一致しない可能性があります。

質問 UI の自由記述オプションにより、制作者は Spanish (es-ES)、Japanese (ja-JP)、Arabic (ar-SA) など、別の言語やロケールを入力できます。言語名は、明示的な地域またはスクリプトが指定されている場合はそれを保持しつつ、適切な BCP-47 タグに変換します。生の回答はデータとしてのみ扱います。シェルコマンドに入れないでください。エージェントのメモリでは、SAFE_LOCALE_CANDIDATE に変換します。これは ^[A-Za-z0-9]{1,8}(?:-[A-Za-z0-9]{1,8})*$ に一致し、最大 255 文字でなければなりません。安全な候補を導出できない場合は、コマンドを実行する前に拒否して再プロンプトします。その制約された候補のみを検証および正規化します:

node "${PLUGIN_ROOT}/scripts/lib/localization-config.js" resolve-locale --locale "<SAFE_LOCALE_CANDIDATE>"

メーカーの回答をそのままこのコマンドに引用、エスケープ、サニタイズ、またはその他の方法で埋め込まないでください。無効なリゾルバー出力は拒否し、その理由を伝えて再度入力を求めてください。言語ラベルを推測せず、正規化されたリゾルバー出力を記録してください。

  • SITE_LANGUAGE — リゾルバーの languageName(例:Spanish)。表示名を取得できない場合は、正規化されたロケールを表示し、推測せずに読みやすいラベルをメーカーに尋ねてください。
  • SITE_LOCALE — 正規化された BCP-47 タグ(例:es-ES)
  • SITE_DIRECTION — リゾルバーから取得した ltr または rtl
  • SITE_LOCALE_NAME — リゾルバーの localeName(例:European Spanish)。地域や文字体系を明確にする必要がある計画テキスト用に保持してください。
  1. プロジェクトの場所を解決します。
  • 「現在のディレクトリ」の場合:プロジェクトルート = <cwd>。
  • 「現在のディレクトリ内の新しいフォルダー」の場合:cwd 内に __SITE_NAME__ という名前のフォルダーを作成します。プロジェクトルート = <cwd>/__SITE_NAME__/。まず、現在のオペレーティングシステムで __SITE_NAME__ が有効なディレクトリ名か確認してください。非ラテン文字だけを理由に拒否してはいけません。サイト名に無効なパス文字が含まれる場合、オペレーティングシステムで予約されている場合、サニタイズ後に空になる場合、またはその他の理由で安全に使用できない場合は、__SITE_SLUG__ に置き換えてください。代替フォルダーを作成する前に、どの名前を使用するか、および元のサイト名がファイルシステムで安全でない理由をメーカーに伝えてください。
  • 「その他のディレクトリ」の場合:フルパスを尋ねます。確認して作成します。プロジェクトルート = 指定されたパス。

解決後、次のように確認してください:「サイトは <resolved path> に作成されます。」

これを PROJECT_ROOT として保存します。

  1. 派生値を確定します。
  • __SITE_NAME__ — メーカーが入力したサイト名/ブランド名をそのまま保持します(例:Contoso Portal)。コンテンツの言語と一致させる必要はありません。
  • __SITE_SLUG__ — npm、Angular プロジェクト設定、ビルドパス、デフォルトのフォルダーで使用する、小文字 ASCII のケバブケース形式の技術識別子です。可能な場合はサイト名から派生させます(例:Contoso Portal → contoso-portal)。信頼できる場合は音訳してください。非ラテン文字の名前から安全で意味のあるスラッグを作成できない場合は、サイトの目的からスラッグを導き出すか、空または無効な識別子を出力せずに、技術プロジェクト名を尋ねてください。
  • __SITE_DESCRIPTION__ — 名前と目的に基づいて SITE_LANGUAGE で記述する、1 行の説明です。
  1. 理解した内容を要約し、先に進む前にユーザーの確認を得ます。サイト名、技術スラッグ、フレームワーク、目的、対象ユーザー、プロジェクトの場所、SITE_LANGUAGE(SITE_LOCALE、SITE_DIRECTION)、および Dataverse と Power Pages のシステムメッセージは英語のままであることを明記してください。
  2. 確認後、承認された分類情報のみのサイト設定を出力します。
  • 目的を company-portal、blog-content、dashboard、landing-page、other のいずれかに対応付けます。メーカーが自由記述した目的は決して渡さないでください。
  • フレームワークとコンテンツのロケールの両方が最初のリクエストに含まれていた場合にのみ、choiceSource を arguments に設定します。それ以外の場合は prompt を使用します。
node "${PLUGIN_ROOT}/scripts/emit-skill-configured-telemetry.js" --skillName "create-site" --projectRoot "<PROJECT_ROOT>" --framework "<react|vue|angular|astro>" --siteContentLocale "<SITE_LOCALE>" --purpose "<PURPOSE_TAXONOMY>" --audience "<internal|external>" --choiceSource "<arguments|prompt>"

テレメトリヘルパーはフェイルクローズ方式で動作し、ロケールの拡張サブタグとプライベート使用サブタグを削除します。サイト名、説明、ページ、ルート、コンポーネント、機能ラベル、その他の自由記述要件をこのコマンドに追加しないでください。

  1. 一から作成する場合のタスクリスト(フェーズ 2~8)を ToDo リストに追加し(進捗状況の追跡を参照)、その後 テンプレートを選択するか、一から作成する を completed に設定します。

出力:クローンしたテンプレートサイトの識別情報(IMPORTED_SITE_NAME、IMPORTED_WEBSITE_RECORD_ID)と、カスタマイズを任意で行えるローカルプロジェクトパス。または、選択したフレームワーク、コンテンツ言語、派生した命名値、解決済みのプロジェクト場所を含む CREATION_PATH = "from-scratch"。


フェーズ 2:スキャフォールドと開発サーバーの起動

目標:すぐに実行できるサイトを用意し、機能やデザインを計画している間にユーザーがプレビューできるようにします。

スキャフォールドは一時的なブランド付きのローディング画面です — 軌道上を回る要素、ステータスメッセージ、機能カードを含む、Power Pages のアニメーション付き「サイトを構築中」画面を表示します。目的は、開発サーバーをすばやく起動し、計画と構築を進めている間にユーザーが確認できるものを用意することだけです。フェーズ 5(実装)では、theme.css、Layout、Home ページ、すべてのプレースホルダーコンポーネントを含むスキャフォールド全体が、ユーザーの実際のサイト(選択したタイポグラフィ、カラーパレット、ページ、コンポーネント、ナビゲーション)に完全に置き換えられます。 ローディング画面をベースに構築しようとせず、完全に置き換えてください。

フレームワーク → ビルドツール → ルーター → 出力パスの対応関係の全容については、${PLUGIN_ROOT}/references/framework-conventions.md を参照してください。

アクション:

2.1 テンプレートをコピーする

${PLUGIN_ROOT} は実行時にプラグインの絶対パスに解決済みです。Glob/Read のパスでそのまま使用してください。プラグインのディレクトリを検索しないでください。

一致するアセットテンプレートのすべてのファイルを読み取り、プロジェクトディレクトリにコピーします。

フレームワークアセットディレクトリ
React${PLUGIN_ROOT}/skills/create-site/assets/react/
Vue${PLUGIN_ROOT}/skills/create-site/assets/vue/
Angular${PLUGIN_ROOT}/skills/create-site/assets/angular/
Astro${PLUGIN_ROOT}/skills/create-site/assets/astro/

Glob を使用してアセットディレクトリ内のすべてのファイルを検出し、各ファイルを Read してから、相対パス構造を維持してプロジェクトディレクトリに Write します。

また、スキャフォールドが CSS から参照する共有ローダーアイコンもコピーします(url('/power-pages-icon.png')):

バイナリファイル ${PLUGIN_ROOT}/skills/create-site/assets/shared/power-pages-icon.png を Read し、<PROJECT_ROOT>/public/power-pages-icon.png に Write します。(サポートされている 4 つのフレームワークはすべて public/ をウェブルートとして提供するため、同じ /power-pages-icon.png URL をどのフレームワークでも使用できます。)

ライブステータスファイルを初期化し、ローダーがマウントされた瞬間から実際のメッセージを表示できるようにします。<PROJECT_ROOT>/public/scaffold-status.json に Write します。

{ "message": "Planning your site", "awaitingInput": false }

仕様全体についてはライブプレビューステータスプロトコルを参照してください。以降は、AskUserQuestion の前、およびフェーズ 5 の各実装ステップの前に、このファイルを更新してください。

2.2 プレースホルダーを置き換える

コピー後、すべてのファイルにある __PLACEHOLDER__ トークンを置き換えます。各ファイルで replace_all: true を指定して Edit を使用してください。

  • 名前/スラッグ/説明のプレースホルダー:フェーズ 1 の実際の値(__SITE_NAME__、__SITE_SLUG__、__SITE_DESCRIPTION__)を使用します。
  • ドキュメント言語のプレースホルダー:__SITE_LOCALE__ を SITE_LOCALE に、__SITE_DIRECTION__ を SITE_DIRECTION に置き換えます。

注: スキャフォールドのローディング画面では Power Pages のブランドカラーがハードコードされているため、置き換えるカラーのプレースホルダー(__PRIMARY_COLOR__ など)はありません。ユーザーが選択したカラーパレットは、フェーズ 5 でスキャフォールド全体を置き換える際に新たに適用します。

2.3 gitignore の名前を変更する

プロジェクトルートの gitignore の名前を .gitignore に変更します(プラグインリポジトリの Git への干渉を避けるため、ドットなしの名前で保存されています)。

2.4 依存関係をインストールする

初回コミットに package-lock.json を含めるため、Git の初期化前に npm install を実行します。

cd "<PROJECT_ROOT>"
npm install

Astro には Node 22.12 以降が必要です。 それより古いバージョンでは Astro 7 は Node.js vX is not supported by Astro! と表示して終了するため、選択したフレームワークが Astro の場合は、先に node --version を実行し、続行する前にユーザーにアップグレードを依頼してください。

2.5 Git リポジトリを初期化する

Git リポジトリを初期化し、最初のコミットを作成します。これにより、すべてのテンプレートファイルと package-lock.json が、クリーンな初期状態としてひとつにまとめられます。

cd "<PROJECT_ROOT>"
git init
git add -A
git commit -m "Initial scaffold: __SITE_NAME__ (__FRAMEWORK__)"

この時点から、重大な変更を元に戻せるよう、重要なマイルストーンごとにコミットしてください。

2.6 開発サーバーを起動する

計画やカスタマイズを始める前に、今すぐ必ず実行してください。 開発サーバーを起動すると、機能やデザインを計画している間、ユーザーがライブプレビューを確認できます:

cd "<PROJECT_ROOT>"
npm run dev

Bash を使用し、run_in_background: true を指定して、バックグラウンドで npm run dev を実行します。ローカル URL を確認してください(通常、Vite では http://localhost:5173、Angular では http://localhost:4200、Astro では http://localhost:4321 です)。

2.7 Playwright で検証し、URL を共有する

開発サーバーの起動直後に、スキャフォールドが正しく動作していることを検証します:

  1. mcp__plugin_power-pages_playwright__browser_navigate を使用して、開発サーバーの URL を開きます
  2. mcp__plugin_power-pages_playwright__browser_snapshot を使用して、ページが正しく読み込まれたことを検証します(アクセシビリティスナップショットのみを使用してください。スクリーンショットはフェーズ 5 のデザインチェック用です)
  3. 開発サーバーの URL をユーザーに共有し、自身のブラウザーでサイトをプレビューできるようにします(例:「サイトは http://localhost:5173 で起動しています。ブラウザーで開くと、構築の様子を確認できます。」)

🚦 ゲート:以下のすべてを満たすまで、フェーズ 3 に進まないでください:

  1. テンプレートファイルをコピーし、プレースホルダーを置換済み
  2. Git リポジトリを初期化し、最初のスキャフォールドコミットを作成済み
  3. npm install が正常に完了済み
  4. 開発サーバーがバックグラウンドで実行中(npm run dev)
  5. Playwright でサイトを開き、browser_snapshot による読み込みの検証が完了済み
  6. 開発サーバーの URL をユーザーに共有済み

いずれかが未完了の場合は、先に進む前に今すぐ完了させてください。

出力:検証済みのスキャフォールドが稼働する開発サーバーと、ユーザーに共有済みの URL


フェーズ 3:コンポーネントの計画

目標:ユーザーが稼働中のスキャフォールドをプレビューしている間に、サイトに必要なページ、コンポーネント、デザイン要素を決定します

🚦 ゲート(plan · create-site:3.requirements): 4 つのサブプロンプト(機能の複数選択、テイスト、ムード、ブランド)と、ユーザーにブランド関連の入力がある場合のブランドに関する追加質問が、フェーズ 4 の計画とフェーズ 5 の実装を方向付けます。以下のアクションリストのステップ 2 で実行します。

トリガー: フェーズ 3 の開始時。スキャフォールドのローダーが起動しています。 質問する理由: 機能セット、テイスト、ブランドを誤ると、レンダリングされる計画に反映されてしまいます。フェーズ 4.7 のゲートでほとんどの誤りは検出されますが、検出を後回しにすると無駄が生じます。 キャンセル時に残るもの: 何もありません。スキャフォールドのローダーファイルは一時的なもので、フェーズ 5 で全体を置き換えます。

アクション:

  1. ブラウザーのローダーが全画面表示されていても、ユーザーがターミナルのプロンプトに気付くように、「入力待ち」バナーを表示します。<PROJECT_ROOT>/public/scaffold-status.json に Write します:

    { "message": "Planning your site", "awaitingInput": true, "inputPrompt": "Features, aesthetic, mood, and brand - please answer in the terminal." }
    

    ユーザーが回答した直後(ブランドに関する追加質問への回答を含む)に、同じファイルへ "awaitingInput": false を再度 Write し、バナーを非表示にします。

  2. AskUserQuestion を使用して、機能とデザインの要件を収集します:

    質問ヘッダー選択肢
    どの機能が必要ですか?(複数選択可)機能(フェーズ 1 で得たサイト名、目的、対象ユーザーに基づいて、状況に応じた選択肢を 3~4 個作成します)
    どのようなテイストにしますか?テイストミニマル&クリーン(おすすめ)、大胆&鮮やか、ダーク&ムーディー、温かみ&オーガニック
    全体的なムードはどのようなものですか?ムードプロフェッショナル&信頼感(おすすめ)、クリエイティブ&遊び心、テクニカル&緻密、エレガント&プレミアム
    サイトに合わせる既存のブランドはありますか?ブランドいいえ、新しいアイデンティティを作成する(おすすめ)、既存のウェブサイトに合わせる、ブランドカラーまたはロゴを使用する

    ブランドに関する追加質問。 回答を BRAND_SOURCE(fresh、website、または assets)として記録します。既存のウェブサイトに合わせるを選んだ場合は、AskUserQuestion を使用して URL を尋ねます(自由入力です。「その他」からユーザーが入力できるよう、汎用の選択肢を 1 つだけ用意します)。http:// または https:// で始まる URL のみ受け付け、それ以外の場合は再度尋ねます。ブランドカラーまたはロゴを使用するを選んだ場合は、同じ方法で、16 進数カラーコードおよび/またはロゴファイルの絶対パスを尋ねます。テンプレートをカスタマイズする場合は、この追加質問を省略します(フェーズ 1.5 のステップ 20 を参照)。

    機能オプションはハードコードされていません。 フェーズ 1 の回答から関連する機能を推測してください。たとえば:

    • 「HR ダッシュボード」+ 社内向け → 従業員ディレクトリ、休暇申請、お知らせ、組織図
    • 「Contoso ポータル」+ 社外向け → お問い合わせフォーム、サービスカタログ、ナレッジベース、FAQ
    • 「パートナーハブ」+ 社内向け → ドキュメントライブラリ、パートナーディレクトリ、商談トラッカー、通知

    常に、その特定のサイトにとって意味のあるオプションを生成してください — 固定のリストを再利用しないでください。

    認証機能のオプションを含める場合は、「応募状況を追跡するためのログイン/サインアップ」などと一般的に説明してください。機能の説明で特定の ID プロバイダー(例:「Entra ID」「SAML」「Google」)に言及しないでください — /power-pages:setup-auth スキルが、ユーザーに希望するプロバイダーを尋ねます。

  3. AI コンポーネントの計画 — フェーズ 1 の回答(サイト名、目的、対象ユーザー)と上記の機能選択に基づいて、サイトが使用する可能性のある Power Pages の生成 AI 要約 API を提案します。サイト自体はこれらの API に依存しません — ページには予約済みのスロットが用意されて出荷され、AI なしで動作します。ユーザーが準備できた時点で、/add-ai-webapi が後からスロットを埋めます。AskUserQuestion を複数選択で使用して、ユーザーがオプトインできるようにします:

    質問ヘッダーオプション
    サイトにどの AI 要約機能を持たせるべきですか?(複数選択 — それぞれ後から /add-ai-webapi で追加できます)AI 要約(文脈に合ったオプションを 2〜4 個、さらに「今はなし」を生成)

    オプションはハードコードされていません。 フェーズ 1 と上記で選択された機能から、関連する AI 要約機能を推測してください。例:

    • 「HR ダッシュボード」+ 休暇申請機能 → 「休暇申請のデータ要約」、「ナレッジベースの検索要約」
    • 「Contoso ポータル」+ ナレッジベース → 「サイト全体の検索での検索要約」、「記事のデータ要約」
    • 「カスタマーセルフサービス」+ サポート案件 / インシデント → 「サポート案件のデータ要約(Microsoft 提供のレシピ)」、「添付されたナレッジ記事のデータ要約」

    標準の incident テーブルは他の Dataverse テーブルと同様に扱ってください — サイトがサポート案件を扱う場合は そのデータ要約を提案しますが、Microsoft 提供のレシピ($select=description,title + ポータルコメントの 展開)がユーザーの UX に本当に合致しない限り、それを強制しないでください。カスタムの案件類似テーブルや、 標準の incident の別の側面は、通常のデータ要約の選択肢です。常に 今はなし を含めて、ユーザーが 先送りできるようにしてください。このスキルでは API を統合しないでください — ユーザーの選択を記録する だけにとどめ、フェーズ 4 の計画でそれらに言及でき、フェーズ 8 で /add-ai-webapi を推奨の次の ステップとして提案できるようにしてください。

    選択内容はメモリ内に AI_SUMMARY_PICKS として記録します — search-summary、data-summarization の 1 つ以上を含むリストです。

  4. 選択を対象ページにマッピングします。 AI_SUMMARY_PICKS の各エントリについて、どのページが AI サーフェスを担うかを決定し、そのマッピングを AI_SUMMARY_PLACEMENTS として保存します。これはフェーズ 4 でユーザーに示すものであり、フェーズ 5 でスロットを予約する対象でもあります。ステップ 2 の機能選択を使用し — このマッピングを、ステップ 7 で Claude が提案するページリストへの 入力 として扱ってください:選択に対応する自然な対象ページがない場合は、要約の置き場所ができるように計画にページを 1 つ追加します:

    選択デフォルトの対象ページ一致するページが計画されていない場合
    search-summary検索 / 検索結果ページ(例:SearchResults、Search)要約の置き場所ができるように、計画に検索ページを追加する
    data-summarizationユーザーが指定したテーブルの詳細ページ(例:製品なら ProductDetail、サポート案件なら CaseDetail) — 曖昧な場合はユーザーに尋ねる詳細ページの追加を提案する。拒否された場合は、リスト / ダッシュボードページにフォールバックする
    AI_SUMMARY_PLACEMENTS の形状: 配置ごとに 1 レコード。例:
    [{ pick: "data-summarization", targetPage: "CaseDetail", marker: "POWERPAGES:AI-SLOT kind=data-summarization" }]。

    marker 文字列は、Phase 5 が予約済みアンカーとしてページソースに出力するコメントタグであり、後で /add-ai-webapi がそれを見つけます。形状は統一してください。配置ごとに 1 つのマーカー、常に同じタグにすることで、後続スキルの探索ステップが決定的に grep できるようになります。

  5. デザインリファレンスを読みます: ${PLUGIN_ROOT}/references/design-aesthetics.md、${PLUGIN_ROOT}/references/page-blueprints.md、${PLUGIN_ROOT}/references/bidirectional-design.md。

  6. エクスペリエンスブリーフを作成します (design-aesthetics.md セクション 1) — 対象読者と目的、主要アクションと副次アクション、主な懸念、証明戦略、デザインテーゼ、ヒーローコンセプト、シグネチャーモーメント。まずブランドソースを決定します (セクション 2): website の場合は、そこの Playwright スニペットで URL からブランドを抽出します。assets の場合は、提供された色を中心にパレットを構築します。fresh の場合は、美的 x ムードマップ (セクション 11) の一致するセルから始めます。表示フォントと本文フォント、カラーダイレクション、ジオメトリ、モーションダイレクションを記録します。フォントの選択は、SITE_LOCALE で使用される完全な書記体系をサポートする必要があります。美的感覚に一致するという理由だけでラテン文字専用のフォントを選ぶのではなく、グリフのカバレッジとシェーピングを検証し、互換性のあるスクリプト対応のフォールバックスタックを使用してください。

  7. 要件を分析し、必要なコンポーネントを決定します。各ページのコンテンツを page-blueprints.md のナラティブビートとして、順番に、セクションごとに 1 行でその目的とともに計画します。ステップ 4 の AI_SUMMARY_PLACEMENTS が、すでに計画に含まれていないページ (たとえば、サポートケーステーブルの data-summarization ピックに対する CaseDetail ページ) を暗示している場合は、今すぐページリストに追加します。コンポーネント計画を表としてユーザーに提示します:

    | Component Type      | Count | Details |
    |---------------------|-------|---------|
    | Pages               | 4     | Home, About, Services, Contact |
    | Shared Components   | 3     | Navbar, Footer, ContactForm |
    | Design Elements     | 5     | Schibsted Grotesk + Public Sans, 15 color tokens, product-moment hero, status-timeline signature moment, paper-grain backgrounds |
    | Routes              | 4     | /, /about, /services, /contact |
    

    計画されたすべての可視またはインタラクティブなコンポーネントに対して BIDIRECTIONAL_REVIEW_DATA を構築します。共有ソースコンポーネントではない ページローカルのコントロールも含みます。共有双方向標準を使用して、 各エントリを direction-neutral、direction-aware、 direction-fixed、または unknown-third-party に分類します。ローカライズされた理由、 該当する状態、該当する desktop/narrow ビューポート、計画されたチェックを記録します。 インライン配置、テキストの方向、水平方向の移動、順序、方向の意味、 混合スクリプトのコンテンツ、または通常のコンポーネントサブツリー外での レンダリングに関わるものはすべて、潜在的な双方向サーフェスとして扱います。

    これはプロジェクトマニフェストではなく、想定されるレビュースコープです。Phase 5 は これを実際のソースおよびレンダリングされたアプリケーションと照合し、 実装中に発見されたコンポーネントや状態を追加する必要があります。 別個のコンポーネントインベントリ JSON ファイルは作成しないでください。

  8. ブリーフとブランドソースから最終的なカラートークン — design-aesthetics.md セクション 3 のすべてのカラーロール — を選択します。値が計画に到達する前に、各テキストと背景のペアを WCAG AA に対して今すぐ確認します。これらは、スキャフォールドのローディング画面が完全に置き換えられる実装 (Phase 5) 中に、新しい theme.css に新規で書き込まれます。

出力: 作成するページ (ナラティブビート付き)、コンポーネント、デザイン要素、ルートの確定リスト、およびエクスペリエンスブリーフとカラートークン


Phase 4: 計画の承認

ゴール: 実装計画を HTML ドキュメントとしてレンダリングし、ユーザーのデフォルトブラウザで開き、実装を開始する前に承認を得ます。

チャットメッセージではなく HTML を使う理由: 構造化された HTML 計画 (/integrate-backend、/add-server-logic、/add-cloud-flow が生成するものなど) を使うと、ユーザーはセクションをざっと読み、スウォッチを比較し、タイポグラフィをプレビューできます — これらはすべてターミナルでは不可能です。ユーザーのブラウザのスキャフォールドローダーも全画面表示になっている可能性があるため、計画を新しいタブに表示することで、実際に読める場所に配置できます。

4.1 デザインの参考資料を読む

${PLUGIN_ROOT}/references/design-aesthetics.md と ${PLUGIN_ROOT}/references/page-blueprints.md がまだコンテキストにない場合は、読み込んでください。以下で設定するすべての項目は、Phase 3 のエクスペリエンスブリーフに基づいている必要があります。

計画における AI 対応。 Phase 3 の AI_SUMMARY_PLACEMENTS が空でない場合は、各配置を対応する PAGES_DATA エントリーの description または content に反映してください。例:「AI サマリーカード用の予約枠。後で /add-ai-webapi によって設定されます。このページは AI なしで公開されます。」 これにより、テナントで生成 AI 機能が有効になっていることをサイトが前提とせず、エンドユーザーに「Run /add-ai-webapi」というプレースホルダーが表示されないことを明確にできます。AI_SUMMARY_PLACEMENTS が空の場合は、計画に AI への言及を含めないでください。

4.2 計画データを作成する

以下のキーを含む単一の JSON オブジェクトを作成してください。計画テンプレートでは必須キーが欠けているデータは拒否されるため、すべて含めてください。

キー型内容
SITE_NAMEstringPhase 1 のサイト/ブランド名。入力された表記を維持します
PLAN_TITLEstringSITE_LOCALE における "Implementation Plan" のローカライズ表記
FRAMEWORKstringReact/Vue/Angular/Astro
SITE_LANGUAGEstringPhase 1 の読みやすいコンテンツ言語名。可能な場合はその言語で記述します
SITE_LOCALEstring正規の BCP-47 コンテンツロケール
SITE_DIRECTIONstringltr または rtl
AESTHETICstring選択した美的スタイル(例:Minimal & Clean)
MOODstring選択したムード(例:Professional & Trustworthy)
SUMMARYstringサイトの内容と対象ユーザーを説明する、ローカライズされた段落
PLAN_LABELSobject以下で定義するテンプレートラベルの完全なローカライズ辞書
DESIGN_DIRECTION_DATAobjectエクスペリエンスブリーフ:{ thesis, brandSource, audience, primaryAction, secondaryAction, principalDoubt, proofStrategy, heroConcept, signatureMoment } — すべて文字列です。brandSource にはトークンの由来を記載します(例:"Fresh identity"、"Matched to https://contoso.com")
TYPOGRAPHY_DATAobject{ primary: { name, sample, reason }, secondary: { name, sample, reason } } — primary は本文用書体、secondary は見出し用書体です。name は design-aesthetics.md のセクション 3 にある確認済み書体の表のファミリー、またはブランド独自の Google Font である必要があります
PALETTE_DATAarray[{ var, hex, description }] — design-aesthetics.md のセクション 3 にある色トークンごとに 1 エントリー
MOTION_DATAarray[{ label, description }] — ファーストスクリーンの表示アニメーション、特徴的な演出、スクロール時の表示、インタラクション状態、ルート遷移
BACKGROUNDS_DATAarray[{ label, description }] — ヒーローの雰囲気、セクションの背景帯、テクスチャ、パターン
PAGES_DATAarray[{ name, route, description, content: [...], components: [...] }] — content はページの物語を構成する要素を順番に並べたもので、各セクションの目的を 1 行ずつ記述します。components は使用する共有コンポーネント名です
COMPONENTS_DATAarray[{ name, purpose, usedBy: [...] }] — 共有コンポーネントと、それを使用するページ名
ROUTES_DATAarray[{ path, page }] — ルーターに登録するすべてのルート
BIDIRECTIONAL_REVIEW_DATAarray計画対象の、表示または操作可能なすべてのコンポーネントを { component, classification, reason, states: [...], viewports: ["desktop" or "narrow"], checks: [...] } として記述します。制作担当者向けの文字列はすべてローカライズします
REVIEW_DATAobject以下の責任範囲の定義に従った { agentChecks: [...], makerReview: [...] }
DEPLOYMENT_DATAarray[{ title, description, recommended?: boolean }] — recommended: true をちょうど 1 つ設定します
PLAN_LABELS には、以下のすべてのキーを含める必要があります。英語の値は各ラベルの意味を説明しています。すべての値を SITE_LOCALE に翻訳してください。レンダラーが実行時にこれらのトークンを置換するため、{siteName} と {count} は正確にそのまま保持してください。キーを省略したり、個々のラベルを英語のままにしたりしないでください。
{
  "navigation": {
    "group": "Plan",
    "overview": "Overview",
    "design": "Design",
    "pages": "Pages & Components",
    "deployment": "Deployment & Review"
  },
  "overview": {
    "title": "Overview",
    "description": "Implementation plan for {siteName}",
    "stats": {
      "pages": "Pages",
      "components": "Shared Components",
      "routes": "Routes"
    },
    "nextSteps": {
      "title": "What happens next",
      "design": {
        "title": "Apply design tokens",
        "description": "Fonts, palette, motion, and backgrounds written into your theme"
      },
      "components": {
        "title": "Build shared components",
        "descriptionOne": "{count} reusable component used across pages",
        "descriptionOther": "{count} reusable components used across pages"
      },
      "pages": {
        "title": "Create pages",
        "descriptionOne": "{count} page with routing and navigation",
        "descriptionOther": "{count} pages with routing and navigation"
      },
      "critique": {
        "title": "Critique the design",
        "description": "Desktop and mobile screenshots scored and refined against the design rubric"
      },
      "verify": {
        "title": "Verify & accessibility",
        "description": "axe-core audit, Playwright checks, and user review"
      }
    }
  },
  "design": {
    "title": "Design",
    "description": "Design direction, typography, palette, motion, and background treatments",
    "direction": {
      "title": "Design direction",
      "heroConcept": "Hero concept",
      "signatureMoment": "Signature moment",
      "primaryAction": "Primary action",
      "secondaryAction": "Secondary action",
      "principalDoubt": "Principal doubt",
      "proofStrategy": "Proof strategy",
      "brandSource": "Brand source",
      "audience": "Audience and job"
    },
    "typography": "Typography",
    "palette": "Color palette",
    "motion": "Motion & animation",
    "backgrounds": "Background treatment",
    "primaryRole": "Primary — body & UI",
    "secondaryRole": "Secondary — headings"
  },
  "pages": {
    "title": "Pages & Components",
    "description": "Pages to build, their content outline, and the shared components they rely on",
    "pages": "Pages",
    "components": "Shared components",
    "routing": "Routing",
    "path": "Path",
    "page": "Page",
    "content": "Content",
    "componentsUsed": "Components used",
    "usedBy": "Used by",
    "noComponents": "No shared components planned yet."
  },
  "bidirectional": {
    "title": "Bidirectional review scope",
    "description": "Planned component, state, and viewport coverage; reconciled with the actual implementation before handoff",
    "classification": "Classification",
    "reason": "Reason",
    "states": "Applicable states",
    "viewports": "Applicable viewports",
    "checks": "Planned checks",
    "classifications": {
      "directionNeutral": "Direction-neutral",
      "directionAware": "Direction-aware",
      "directionFixed": "Direction-fixed",
      "unknownThirdParty": "Unknown or third-party"
    },
    "viewport": {
      "desktop": "Desktop",
      "narrow": "Narrow or mobile"
    }
  },
  "deployment": {
    "title": "Deployment & Review",
    "description": "Verification checklist and deployment options",
    "verify": "Before handoff — verify",
    "agentChecks": "Agent verification",
    "agentChecksDescription": "The agent will run and report these checks before handoff.",
    "makerReview": "Maker review",
    "makerReviewDescription": "Review these judgment-based items in the live preview.",
    "options": "Deployment options",
    "recommended": "Recommended"
  },
  "common": {
    "noneSpecified": "None specified."
  },
  "footer": {
    "aiWarning": "AI-generated content may be incorrect"
  }
}

メーカー向けのプランデータはすべて、選択したコンテンツ言語で記述してください。 これには PLAN_TITLE、SUMMARY、PLAN_LABELS、説明的な AESTHETIC と MOOD の名前、タイポグラフィの理由とサンプル、パレットの説明、モーションと背景のラベルと説明、ページの表示名・説明・コンテンツ概要、コンポーネントの表示名・目的、ルートページのラベル、レビュー項目、デプロイのタイトルと説明が含まれます。

技術的な値は変更しないでください。フレームワーク名とパッケージ名、ファイルパス、ルート、コマンド、ロケールタグ、CSS 変数、16 進数のカラーコード、識別子、API 名、ブランド名・製品名が該当します。ページやコンポーネントの name が計画上のコード識別子でもある場合は、そのまま変更せず、人間が読む表示名のみをローカライズしてください。翻訳した断片を英語の語順で連結するのではなく、完全に翻訳されたフレーズを使用してください。

REVIEW_DATA は、空でないローカライズ済みの文字列配列 2 つとして構築してください。

{
  "agentChecks": [
    "The root document uses the canonical site locale and resolved writing direction",
    "The bidirectional-readiness audit reports no errors; layout uses logical CSS and every physical exception is documented and verified",
    "Every visible or interactive component is classified, and the planned review scope is reconciled with the actual source and rendered application",
    "Every applicable state and viewport of direction-aware, direction-fixed, and unknown or third-party components has verification evidence",
    "Localized form labels, placeholders, hints, helper text, validation messages, prefixes, suffixes, and overlays follow the active UI direction; only classified machine-oriented values remain LTR",
    "Representative routes work in the selected direction and a pseudo-opposite direction at desktop and narrow widths without console errors, broken reading order, or broken focus order",
    "Unknown-direction content uses bdi or dir=auto, while URLs, email addresses, code, paths, GUIDs, and identifiers are explicitly isolated",
    "Dates, numbers, currency, percentages, and relative time use locale-aware Intl formatting",
    "Typography covers the selected script and expanded or opposite-direction text does not clip or overlap",
    "Directional components, interactions, icons, and assets behave according to their reviewed mirror, preserve, or replace classification",
    "Every route has zero critical or serious axe-core accessibility violations"
  ],
  "makerReview": [
    "Language, terminology, tone, regional wording, and regulated content are appropriate",
    "Visual hierarchy and reading flow feel natural in the selected direction and the opposite-direction preview",
    "Typography remains readable and preserves the intended brand character",
    "Icon and image direction choices are culturally and semantically appropriate",
    "Text wrapping, expansion, and narrow-screen layouts remain visually acceptable"
  ]
}

これらは英語の文言をそのままコピーするのではなく、完全な判断基準として翻訳してください。2 つのグループは責任の所在を伝えます。

  • agentChecks は、エージェントがフェーズ 5〜7 で実行し報告する必要がある客観的なコミットメントです。メーカー向けの指示ではありません。
  • makerReview には、自動化では承認できない言語的、文化的、ブランド的、視覚的な判断が含まれます。メーカーはフェーズ 7 のライブプレビューでこれらをレビューします。

主観的なメーカーの判断を agentChecks に移動しないでください。また、決定的なソース、ブラウザ、アクセシビリティのチェックをメーカーに繰り返させることもしないでください。

4.3 HTML プランをレンダリングする

<PROJECT_ROOT>/docs/ 配下の出力パスを選びます。デフォルトは create-site-plan.html です。そのファイルがすでに存在する場合は、create-site-plan-v2.html のような説明的なバリアントを選びます (レンダリングスクリプトは既存ファイルの上書きを拒否します)。

node "${PLUGIN_ROOT}/scripts/render-createsite-plan.js" --output "<PROJECT_ROOT>/docs/create-site-plan.html" --data - <<'PLAN'
<plan JSON>
PLAN

示されているように、プラン JSON を標準入力から送信してください。これにより一時ファイルが作成されず、ユーザーが入力したブランド URL など、その内容がシェルによって解析されることもありません。引用符で囲まれた 'PLAN' デリミタは展開を無効にします。

スクリプトは成功時に {"status":"ok","output":"<path>"} を出力します。その実際の出力パスを取得し、次のステップで使用してください。

4.4 デフォルトブラウザでプランを開く

現在の環境に適したプラットフォーム別のファイルオープナーを使用して、<OUTPUT_PATH> をデフォルトブラウザで開きます。たとえば、macOS では open、Linux では xdg-open、Windows では利用可能な同等のデフォルトブラウザオープナーを使用します。

4.5 ターミナルに簡単な概要を表示する

ターミナルのメッセージは短くしてください。完全なプランは今や HTML ファイル内にあります。 以下を含めます。

  • プランがレンダリングされたことと、その場所 (出力パス) を確認する 1 文。
  • 3〜5 行の箇条書きの概要: デザインのテーゼ、シグネチャーモーメント、フレームワーク、コンテンツ言語、ページ数とコンポーネント数、主要なパレットカラー。
  • 案内: 「デザインの方向性、ページ、カラースウォッチ、タイポグラフィのサンプル、デプロイオプションについては、開いているブラウザタブを参照してください。」

プランの内容をターミナルに全部出力しないでください。それでは HTML ビューの目的が損なわれます。

4.6 「入力待ち」バナーを表示する

承認を求めた時点で、ユーザーがまだ全画面のスキャフォールドローダーを見ている可能性があります。<PROJECT_ROOT>/public/scaffold-status.json を Write してください。

{ "message": "Ready to build", "awaitingInput": true, "inputPrompt": "Plan approval needed — review the plan in your browser and answer in the terminal." }

ユーザーが回答した直後に、同じファイルを "awaitingInput": false として再度 Write してください。

4.7 承認を求める

🚦 ゲート(plan · create-site:4.7.plan-approval): Phase 5 で足場を実際のページ、コンポーネント、デザイントークンに置き換える前に、レンダリングされた HTML プランの最終承認を得ます。

トリガー: Phase 4.3 で docs/create-site-plan.html をレンダリングし、Phase 4.4 でブラウザーで開きました。 確認する理由: Phase 5 では足場全体(theme.css、Layout、Home ページ、コンポーネント、ルート)を書き換えます。これを元に戻す場合、実装フェーズのすべてのコミットに影響します。 キャンセル時に残るもの: 破壊的な変更はありません。足場自体はプロジェクトディレクトリごと削除できます。Dataverse への操作やデプロイは実行されていません。

AskUserQuestion を使用します。

質問ヘッダー選択肢
このプランでよさそうですか?プラン承認してビルドを開始(推奨)、変更したい箇所があります
  • 「承認」の場合: Phase 5 に進みます。
  • 「変更したい箇所があります」の場合: 変更したい内容を尋ね、JSON を更新して、新しいファイル名で再レンダリングします(レンダリングスクリプトは既存のファイルを上書きしません)。ブラウザーで新しいファイルを開き、4.5~4.7 を繰り返します。

出力: 承認済みの実装プランと、実装中および実装後にユーザーが参照できるよう、プロジェクトと一緒にコミットされた HTML 版。


Phase 5:実装

目標: デザインの方針を最初から反映しながら、すべてのページ、コンポーネント、デザイン要素を構築し、ビジュアルデザインの批評で成果を検証します。

前提条件: 開発サーバーがすでに起動しており、Playwright で検証済みである必要があります(Phase 2 で完了)。そうでない場合は、戻って Phase 2 を完了してください。

デザインリファレンス: ${PLUGIN_ROOT}/references/design-aesthetics.md(デザインシステム)と ${PLUGIN_ROOT}/references/page-blueprints.md(ページの構成、ヒーローパターン、コピー)を基に構築します。まだコンテキストにない場合は、今すぐ読み込んでください。選択したタイポグラフィ、カラートークン、画像、モーション、背景は、すべてのページとコンポーネントに最初から反映します。最初に中立的なスタイルで構築し、後から再デザインすることはしないでください。

アクション:

5.1 すべての作業の Todo を作成する

コードを書く前に、TaskCreate を使って、作業項目ごとに Todo を作成します。これにより、構築する内容をユーザーがすべて把握できます。

  • ページごとに Todo を1つ — 例:「Contact ページ(/contact)を作成」「Dashboard ページ(/dashboard)を作成」
  • 共有コンポーネントごとに Todo を1つ — 例:「ContactForm コンポーネントを作成」「DataTable コンポーネントを作成」
  • ルーティング用の Todo を1つ — 「新しいルートをすべてルーターに追加」
  • ナビゲーション用の Todo を1つ — 「ナビゲーションリンクを追加するために Layout/Header を更新」
  • デザイン基盤用の Todo を1つ - 「デザイントークン(テーマトークン、フォント、モーション、背景)を適用」
  • デザイン批評用の Todo を1つ - 「デザイン批評を実施(デスクトップとモバイル)」

各 Todo には、ファイルパスとページまたはコンポーネントの役割を記載した、明確な subject、activeForm、description を設定します。その後、Todo の順に作業を進め、それぞれのステータスを in_progress → completed に更新します。

5.2 足場を置き換えて構築する

足場は一時的なローディング画面です。このフェーズ中に完全に置き換える必要があります。その上に構築したり、ローディングアニメーションを実際のページに改造しようとしたりしないでください。ユーザーが選んだデザインを使って、最初から作り直します。

ローダーに進捗を表示する: 以下の手順に進む前に、<PROJECT_ROOT>/public/scaffold-status.json を更新します。Home ページのローダーをまだ見ている可能性のあるユーザーに、固定のプレースホルダー表示ではなく、実際の作業状況を伝えるためです。現在進行中の作業を示す短い message を使います(例:"Creating Navbar component"、"Creating Contact page")。関連するグループの情報があれば、メッセージ自体に含めます。ローダーには約1.5秒以内に変更が反映されます。手順 4 で Home ページを置き換えると、更新は反映されなくなります。

  1. デザインの基盤 - theme.css(Angular の場合は styles.css)を、design-aesthetics.md のセクション 3 にあるすべてのトークンセット、基本要素のスタイル、セクション 8 のインタラクション状態のスタイル、prefers-reduced-motion ブロック、背景の処理、論理 CSS プロパティを含めて、一から全面的に書き直します。選択したフォントスタックは、SITE_LOCALE の解決済みの文字体系に対応する必要があります。最初は LTR のみのサイトであっても、物理的な左/右レイアウトをデフォルトにしないでください。選択した Google Fonts を、エントリー HTML のフォント用 <link>(index.html、Astro の場合は Layout.astro)に、スキャフォールドの DM Sans + Outfit と合わせて追加します。ローダーはステップ 4 まで引き続きスキャフォールドのフォントを使用します。スキャフォールドのローディング画面用 CSS は完全に破棄します。このステップの完了後にコミットします。開始前に、ローダーのステータスを { "message": "Applying design tokens" } に設定してください。

  2. レイアウト - 選択したデザインを反映する、適切なナビゲーション、ヘッダー、フッターを備えた Layout コンポーネント(Astro の場合は Header/Footer も)に書き直します。承認済みプラン内のすべてのルートへのリンクを配置し、第一印象レビューを行う前にヘッダーを完成させます。スキャフォールドのパススルー型 Layout は、実際のレイアウト構造に置き換えます。ステータスを { "message": "Rewriting Layout" } に設定してください。

  3. 共有コンポーネント - ページで使用する再利用可能なコンポーネント(Navbar、Footer、ContactForm など)を構築します。それぞれに、design-aesthetics.md の状態テーブルにある、該当するすべての状態を実装します。各コンポーネントについて、ステータスを { "message": "Creating <Component> component" } に設定してください。

  4. ページ - リクエストされた各ページのルートコンポーネントを作成し、スキャフォールドの Home ページと About のプレースホルダーを完全に置き換えます。まず Home を作成し、そのヒーローを最初に作成します。ブリーフのヒーローコンセプトに従ってください。Home の作成後すぐに、/ の第一印象レビューを実施し(5.7 の「レビューの実施」を参照)、最大 3 回のラウンドでヒーローが合格するまで修正します。後続のすべてのページは、この基盤を引き継ぎます。各ページのセクションは、計画されたナラティブの展開順に作成します。各ページコンポーネントは、マウント時に現在のページを反映するよう document.title を更新する必要があります(例:"Contact — Contoso Portal")。フレームワークに適したライフサイクルフックを使用します。React では useEffect、Vue では onMounted、Angular では ngOnInit、Astro ではフロントマターの <title> タグを使用します。形式は "<Page Name> — <Site Name>" とし、ホームページでは "<Site Name>" のみを使用します。各ページについて、ファイルを書き込む前にステータスを { "message": "Creating <Page> page" } に設定してください。Home ページ自体が置き換えられるとローダーは消えるため、その後のステータス更新は不要です。

  5. ルーター — 新しいルートをすべて登録します(スキャフォールドには / と /about しかないため、リクエストされたルートをすべて追加します)

  6. ナビゲーション - Layout/Header のすべてのリンクが登録済みのルートに解決されることを確認し、現在の項目に aria-current="page" を設定します

  7. エントリー HTML - index.html(Astro の場合は Layout.astro)のフォント用 <link> からスキャフォールドの DM Sans + Outfit を削除し、選択したフォントファミリーのみを読み込むようにします。また、<meta name="theme-color"> を --color-bg の値に設定します

  8. AI 要約スロットの予約 — Phase 3 の AI_SUMMARY_PLACEMENTS が空でない場合のみ実施します。各配置について、挿入位置にコメントマーカーを 1 つだけ対象ページのソースに挿入します。表示されるプレースホルダー UI、スタブコンポーネント、追加のルートは作成せず、後で /add-ai-webapi が検索して置換できる grep 可能なアンカーだけを配置します。構文はフレームワークによって異なります。

    フレームワークマーカーの構文
    React (JSX){/* POWERPAGES:AI-SLOT kind=<pick> */} をコンポーネントの return JSX 内に配置
    Vue (SFC template)`` を <template> 内に配置
    Angular (HTML template)`` をコンポーネントのテンプレート内に配置
    Astro`` をコンポーネントの HTML 内に配置

    <pick> は search-summary または data-summarization のいずれかで、配置レコードに記載されたとおりにそのまま使用します。

    ページ内の配置位置:

    • data-summarization (レコード詳細): ページ見出しの直後、詳細コンテンツの上 — ここは、Copilot スタイルの要約カードが読み順において自然に読まれる位置です。
    • data-summarization (リストページ): リスト / テーブルの直上、ページ見出しとフィルターバーの下。
    • search-summary: 検索結果リストの直上、検索入力の下 — 要約段落はキーワードのヒットの前に読まれます。

    AI_SUMMARY_PLACEMENTS レコードの marker フィールドで定義されているとおりに、配置ごとにマーカーを1つだけ記述します。スタブコンポーネント(<CopilotSummaryCard /> など)、CSS クラス、空の <aside> 要素を追加しないでください — スロットは単なるコメントです。サイトは AI が考慮されていないかのように出荷される必要があり、実際の処理は後続のスキルが行います。

コンテンツ言語の要件:

  • コンテンツは SITE_LANGUAGE でネイティブに記述してください。英語のサイトを制作して後から機械的に翻訳してはいけません。
  • ユーザーに見えるすべての SPA 文字列をローカライズしてください: ナビゲーション、見出し、本文コピー、ボタン、リンク、フォーム、バリデーション、読み込み / エラー / 空の状態、ドキュメントタイトル、メタデータ、画像の alt テキスト、ARIA ラベル。
  • コード識別子、パッケージ名、CSS クラス、Dataverse の論理名、API エンドポイント、環境変数は技術的なまま翻訳せずに保持してください。
  • ルートパスは、デフォルトでは安定した意味のある英語 ASCII 識別子(たとえば /services)として保持し、ナビゲーションラベルとページタイトルには SITE_LANGUAGE を使用してください。単一言語サイトの作成中はパスを翻訳しないでください。安定したルートは、ブックマーク、アナリティクス、連携、テスト、および後からの /add-localization 設定を壊すのを避けます。ローカライズされたパスは、メーカーが永続的に単一言語の SEO 戦略のために明示的に要求した場合にのみ使用してください。
  • すべてのロケールについて、論理 CSS プロパティを使用し、意味のある DOM の読み取り / フォーカス順序を維持してください。RTL をシミュレートするために配列を逆にしたり row-reverse を使用したりしないでください。初期の RTL サイトも RTL で視覚的に検証する必要があります。
  • 各フォームフィールドを1つの複合的な方向サーフェスとして扱ってください: ローカライズされたラベル、プレースホルダー、ヒント、ヘルパーテキスト、バリデーションメッセージ、プレフィックス、サフィックス、アイコン、開いているメニューは、アクティブな UI 方向に従い、論理的な配置を使用します。ネイティブの自由記述入力とテキストエリアは適応型の dir を使用します: 空のときはアクティブな UI 方向、入力済みのときは auto、クリア後は再びアクティブな UI 方向。送信される方向メタデータが適切な場合は dirname を保持または追加してください。メールアドレス、電話番号、URL、コード、パス、GUID、識別子など、分類された機械指向の値のみを LTR に保ってください。共有標準で要求される隣接する /* bidi-fixed: <specific reason>; verify=ltr,rtl */ または同等の HTML ディレクティブを追加してください。それらを取り囲むフィールド UI は方向対応のままです。
  • 独立して挿入される未知の方向のコンテンツ(名前、コメント、タイトル、検索クエリ)は、<bdi> または dir="auto" でラップしてください。URL、メール、コード、ファイルパス、GUID、その他の機械的な値は明示的に分離し、通常は LTR に保ってください。自由記述のネイティブコントロールは、恒久的な dir="auto" を使用してはいけません。それらのネイティブ方向は、値の空かどうかとアクティブな UI 方向にバインドしてください。
  • 日付、数値、通貨、パーセンテージ、相対時間は、ロケール依存の句読点や記号を連結するのではなく、Intl API でフォーマットしてください。
  • 方向性のあるアイコンとアセットを、変更なし、ミラーリング、置換に分類してください。読み進める方向に従うセマンティクスを持つコントロールのみをミラーリングしてください。
  • 必須の物理宣言は、隣接する /* bidi-physical: <specific reason>; verify=ltr,rtl */ ディレクティブと、両方向でのブラウザー検証の成功がある場合にのみ残すことができます。 重要:デザインの方針を反映した、実際に機能する UI を構築してください。プレースホルダーの「近日公開」ページや、装飾のない一般的なマークアップにはしないでください。すべてのページとコンポーネントは、作成した時点からデザインの方針を反映させます。このフェーズが終わったら、スキャフォールドの読み込み画面は完全に消してください。Power Pages ブランドのアニメーションの痕跡を一切残さないでください。
5.3 意図のあるビジュアルを用意する

design-aesthetics.md のセクション 6 にあるビジュアルの優先順位に従ってください。まずサイト自体の UI をプロダクトの一場面として構成し、次にオーダーメイドのインライン SVG、最後に写真を使用します。プレースホルダーサービス(例:placeholder.com、placehold.co)、壊れた <img> タグ、空の画像領域は使用しないでください。

写真を探す:

  1. WebSearch を使い、セクションに必要な具体的な被写体を Unsplash で検索します(例:site:unsplash.com city clerk helping resident at counter)。対象ユーザーと用途に即した内容にし、「ビジネスミーティング」のような一般的な検索は避けてください。
  2. 具体的な写真を選び、サイズ指定のパラメーターを付けて直接 URL を使用します:https://images.unsplash.com/photo-{id}?w={width}&h={height}&fit=crop(カードには w=800、ヒーローや全幅バンドには w=1600)。
  3. すべての写真で、照明や色温度をそろえた一貫性のあるアートディレクションを採用し、同じトリミング比率と色調を反映した処理を適用します。
  4. すべての <img> に説明的な alt テキスト(装飾目的の場合は alt="")、明示的な width と height を指定し、画面下部にある画像には loading="lazy" を指定します。
5.4 Git コミットのチェックポイント

変更を元に戻せるように、個々のページとコンポーネントごとにコミットしてください。ページとコンポーネントはそれぞれ個別にコミットします。複数のページやコンポーネントを 1 つのコミットにまとめないでください。

git add -A
git commit -m "<short description of what was added/changed>"

ツールを呼び出すたびに会話全体が再送信されるため、コミットをまとめずに呼び出しを節約してください。コンポーネントのファイル(例:Navbar.tsx と Navbar.css)は 1 回のターンで書き込みます。また、複数のコンポーネントを 1 回のターンで書き込む場合は、1 つのコマンド内でそれぞれ個別にコミットします(git add src/components/Navbar.* && git commit -m "Add Navbar component" && git add src/components/Footer.* && git commit -m "Add Footer component")。

コミットするタイミング:

  • デザインの基盤(トークン、フォント、モーション)を適用した後
  • 各ページの作成後(例:「Add Home page」、「Add Contact page」)
  • Home ページの第一印象レビューでの修正後
  • 共通コンポーネントの作成後(例:「Add Navbar component」、「Add Footer component」)
  • ルーティングとナビゲーションの更新後
  • デザイン批評での各修正ラウンド後
  • リスクの高い作業や実験的な作業に取りかかる前

問題が発生した場合は、最後に正常だったコミットに戻します。

git revert HEAD
5.5 ライブ検証

重要な変更(新しいページやコンポーネント)の後は、Playwright でサイトを開き、構造とコンテンツを確認してください。

  1. mcp__plugin_power-pages_playwright__browser_navigate を使って、更新したページを再読み込みするか、ページに移動します。
  2. mcp__plugin_power-pages_playwright__browser_snapshot を使って、ページの構造とコンテンツが正しいことを確認します。
  3. スナップショットに問題があれば、先に修正してから次へ進みます。

スクリーンショットを使ったデスクトップとモバイル幅での視覚的な評価は、第一印象レビュー(5.2 のステップ 4)と批評の段階(5.7)でのみ行います。スクリーンショットは会話内に保持され、その後の呼び出しごとに再送信されるため、構築中のページごとの確認にはキャプチャスクリプトではなく browser_snapshot を使用します。ユーザーは、フェーズ 2.7 で共有された開発サーバーの URL から、自分のブラウザーでプレビューしています。

すべてのページとコンポーネントがそろったら、決定論的な準備状況監査を実行します。

node "${PLUGIN_ROOT}/scripts/audit-bidirectional-readiness.js" --projectRoot "<PROJECT_ROOT>"

コマンドは構造化された JSON を出力し、決定的なエラーがある場合は 0 以外のコードで終了します。想定されるこの失敗パスでも JSON を解析してください。すべての error 指摘を修正してください。実際のサイトで、ジオメトリ、スクロール、視覚的な順序、コンテンツの展開に関する指摘をすべて確認してください。物理的な配置が意図された要件の場合は、宣言を維持し、検証済みの bidi-physical ディレクティブを隣接して追加し、該当コンポーネントを LTR と RTL の両方で検証してください。機械向けのテキストを意図的に固定する場合は、隣接して bidi-fixed ディレクティブを追加し、周囲の UI を両方向で検証してください。2 つ目の実際のロケールがまだ存在しない場合でも、疑似反対方向のコンテンツを使って、折り返し、ナビゲーション、フォーム、複数方向が混在する名前や識別子、アイコン、カレンダー、狭い画面やモバイルのレイアウトを確認してください。自由入力できるすべてのネイティブ入力欄とテキストエリアについて、UI の両方向で、空、RTL の値、LTR の値、RTL 値の入力後にクリア、LTR 値の入力後にクリアという各状態を検証してください。各クリア状態では、クリアする前に対応する値を入力する必要があります。空の状態とクリア後の状態は UI のロケールに従い、入力値がある状態は入力された値に従います。

完了したソースとレンダリング済みルートを照合し、BIDIRECTIONAL_REVIEW_DATA を更新してください。計画時に把握されていなかった、実装済みの可視またはインタラクティブなコンポーネントをすべて追加し、実装中に判明した適用対象の状態やビューポートもすべて追加してください。各サイトで、選択された方向と疑似反対方向を検証してください。LTR サイトでは疑似 RTL の網羅性を、RTL サイトでは疑似 LTR の網羅性を確保してください。方向に依存しないコンポーネントでは継承を確認する必要があります。方向を認識するコンポーネントでは、適用対象となるすべての状態を両方向で確認する必要があります。方向が固定されたコンポーネントでは、意味上の理由を示し、周囲の UI も確認する必要があります。未知のコンポーネントやサードパーティ製コンポーネントでは、開くダイアログ、メニュー、オートコンプリートパネル、ツールチップ、テレポート、ポータル、オーバーレイ、Shadow DOM、iframe を含め、レンダリング結果を確認する必要があります。

${PLUGIN_ROOT}/references/rendered-bidirectional-verification.md に記載された、一時的なレンダリング検証仕様を作成してください。照合済みのコンポーネント範囲と実際のセレクターを基に導出してください。コンポーネントマニフェストとしてコミットしてはいけません。不安定だが重要な検証対象には data-bidi-id 属性を付けてください。適用対象となるすべての状態とビューポート、複合フォームの各部、body にマウントされるオーバーレイ、明示的なフォーカス順序、重なりが発生してはならない要素の組み合わせ、方向ごとの計算済みスタイルの期待値を含めてください。LTR と RTL の実際のロケールが両方存在する場合は、それらを使用してください。存在しない場合は、ブラウザーのみで使用する疑似反対方向のロケールを追加してください。実際のロケールはアプリケーション経由で有効化し、代表的なローカライズ済みコンテンツでその動作を確認してください。ブラウザー専用の set-document アクションを使用できるのは、疑似ロケールのみです。実行時ローカライズを追加した場合は、実際のデフォルト以外の各ロケールについて、default -> locale -> default と locale -> default -> locale の両方の遷移シーケンスを含め、ルート、フォーム状態、アプリケーション状態、フォーカスが維持されることを確認してください。疑似ロケールはアプリケーション切り替え時の遷移確認には含めません。デフォルトを含むすべての実際のロケールに、再利用可能なアプリケーション有効化アクションが必要です。ラウンドトリップ中のロケール復元に use-current を使うことはできません。新たに追加された実行時ロケールには、add-localization で定義されているローカライズ検証トランザクションを使用してください。通常のセレクターを通じて、記録された対象のみを一時的に公開し、ループバックの開発サーバーに対して Playwright を実行し、成功した場合は利用可能な状態を維持し、失敗した場合はフェイルクローズで利用不可の状態に戻してください。検証トランザクションが存在する間は、作成を完了したりデプロイを提案したりしないでください。preserve のみを指定するセレクターはフォームコントロールに限ります。タブ、パネル、カウンター、その他のアプリケーション状態には、テキスト、属性、プロパティを明示した保持エントリーを使用してください。 該当するすべての REVIEW_DATA.agentChecks 項目について、証拠を保持してください。監査結果、確認したルート/ビューポート、使用した方向、混在コンテンツのフィクスチャ、フォント/テキスト拡張に関する所見、コンポーネント/アセットの分類、コンソールの結果、実施した修正を記録してください。作成者による目視確認だけを根拠に、エージェントが担当する基準を完了扱いにしないでください。

5.6 ライブステータスファイルをクリーンアップする

スキャフォールドローダーを削除すると、public/scaffold-status.json はデプロイ済みサイトに含まれるだけの不要ファイルになります。<PROJECT_ROOT>/public/ からこのファイルを削除し、最終実装と併せて削除をコミットしてください。

5.7 デザイン批評パス

スクリーンショットを見て、${PLUGIN_ROOT}/references/design-critique.md(最初のレビュー時に一度読みます)に照らしてサイトを評価します。ツールを呼び出すたびに会話全体が再送信されるため、レビューでは呼び出し回数を抑えられるようにしています。1回のスクリプト呼び出しですべてのルートを両方の幅でキャプチャし、自動チェックを実行し、1回のターンですべてのスクリーンショットを並行して開きます。ページごとにブラウザー操作(移動、サイズ変更、スクリーンショット、評価)を1つずつ呼び出すと、同じレビューに何倍ものコストがかかります。

レビューの実行(5.2 の手順 4 で行う第一印象レビューと、各批評ラウンドで使用します):

  1. design-critique.md の Capture セクションに示されているとおり、リクエストを標準入力から送信してキャプチャします。開発サーバーの URL とルートをコマンドラインに指定することはありません。インストールは不要です。スクリプトはプラグインに固定された Playwright を使用します。

    node "${PLUGIN_ROOT}/scripts/capture-design-review.js" --input - <<'REQUEST'
    {"url": "<DEV_SERVER_URL>", "routes": ["/", "/about"]}
    REQUEST
    
  2. summary.images にあるすべてのパスを1回のターンですべて開き、JSON から自動チェックの結果を読み取ります。

  3. design-critique.md の説明に従って評価し、定義されている簡潔なスコアカードと修正リストを作成します。

  4. スコアカードにある修正を、影響の大きいものから順にすべて適用してコミットします。再キャプチャするのは次のラウンドの開始時だけです。各修正のたびではなく、ラウンド内の修正をすべて適用した後に、ラウンドごとに1回キャプチャします。

批評パス:すべてのルートをレビューし、修正してから再レビューします。1つの条件を満たすまで、変更されたルートと / のみをキャプチャします。

  • 重大なゲートがすべて合格し、すべてのカテゴリのスコアが3以上になった場合、パスは完了です。
  • 重大なゲートがすべて合格した状態で3ラウンド実施した場合、パスは完了です。スコアが3未満のカテゴリがあれば、その理由とともにスコアカードに記録し、Phase 7 の概要でユーザーに示します。
  • 重大なゲートが不合格のまま3ラウンド実施した場合は、以下のゲートに進みます。重大なゲートを黙って合格扱いにすることはありません。Phase 7 の概要用に最終スコアカードを保持し、同じスクリプトに同じ方法で {"cleanup": "<outputDir>"} を送信して、各ラウンドのスクリーンショットを削除します。

🚦 ゲート(進行状況 · create-site:5.7.critique-blocked): 3回の批評ラウンド後も、重大なデザインゲートが不合格のままです。

発動条件: Phase 5.7 の第3ラウンド終了時に、design-critique.md の重大なゲートが1つ以上不合格であること。 確認する理由: 重大なゲートの不合格は、最初の画面の崩れ、モバイルレイアウトの問題、アクセシブルな操作フローの問題、または信頼性のある証拠の問題を意味します。黙って先に進むと、問題が監査やデプロイ済みサイトに持ち越されます。 キャンセル時に残るもの: なし。サイトのファイルとコミットはディスク上に残ります。

質問では不合格となった重大なゲートとその証拠をそれぞれ示し、AskUserQuestion を使用します。

質問ヘッダー選択肢
(不合格のゲートと証拠) - どのように進めますか?デザインゲート修正を続ける(推奨)、続行して既知の問題として記録する、ここで停止する
  • 修正を続ける:不合格のゲートを対象に、最大3ラウンド実施します。それでも不合格の場合は、このゲートに戻ります。
  • 続行して既知の問題として記録する:既知の問題としてスコアカードに追加し、5.7 の完了まで進みます。Phase 7 の概要にその問題を記載します。
  • ここで停止する:スキルを停止します。プロジェクトとそのコミットはディスク上に残ります。

ゲート:カスタマイズがすべて完了し、5.7 の批評パスが完了するまで、Phase 6 に進まないでください。 要求されたページと機能がすべて存在し、デザイントークンがテーマファイルにあり、選択した Google Fonts がフォントチェックに合格し、ユーザーが続行を選択した場合を除いて重大なゲートに不合格がなく、スコアカードが記録されている必要があります。

出力:すべてのページ、コンポーネント、デザイン要素が実装され、批評され、検証されていること

5.8 追加言語を提案する

子ワークフローを提案する前に、中央管理されたローカライズの利用可否を確認します。

node "${PLUGIN_ROOT}/scripts/lib/localization-config.js" mode-availability --framework "<react|vue|angular|astro>"

availableModes が空の場合は、返された理由を使って、選択されたフレームワークではローカライズを一時的に利用できないことを説明し、LOCALIZATION_REQUESTED=false に設定して、追加言語について質問しないでください。現在、これは Astro に適用されます。create-site に別個のフレームワーク利用可否リストをハードコードしないでください。

今すぐ言語を追加するかどうかを尋ねます。

今すぐ言語を追加しますか? 現在、サイトは <SITE_LANGUAGE> の単一言語です。これは SPA のローカライズのみを追加します。Dataverse と Power Pages のシステムメッセージは英語のままです。

次の正確な文言と選択肢を使って AskUserQuestion を使用します。

質問ヘッダー選択肢
今すぐ言語を追加しますか?

現在、サイトは <SITE_LANGUAGE> の単一言語です。これは SPA のローカライズのみを追加します。Dataverse と Power Pages のシステムメッセージは英語のままです。
追加言語はい — 今すぐ言語を追加する、いいえ — サイトを <SITE_LANGUAGE> のみにする

回答を LOCALIZATION_REQUESTED=true|false として記録します。$ARGUMENTS でローカライズに言及されている場合も、この時点で質問してください。これにより、作成者の回答によって子ワークフローを開始するかどうかが直ちに決まります。

LOCALIZATION_REQUESTED=true の場合、次を呼び出します。

/power-pages:add-localization <PROJECT_ROOT> [FROM_CREATE_SITE]

アクセシビリティ検証を行う前に、スキルの完了を待ちます。子スキルは、ロケール/パッケージに関する質問、翻訳の生成、セレクターの接続、その実装レビュー、ビルド、ローカライズチェックを担当します。[FROM_CREATE_SITE] コンテキストにより、デプロイに関する質問の重複を防ぎます。制御はここに戻り、create-site がアクセシビリティ検証、最終レビュー、および既存のデプロイに関する質問を実行します。

LOCALIZATION_REQUESTED=false の場合、子ワークフローをスキップします。

5.9 承認済みのサイト言語を検証する

承認済みの言語コンテキストを明示して、create-site バリデーターを実行します。resolve-locale が返す正規の SITE_LOCALE と、検証済みの SITE_DIRECTION 列挙値のみを使用し、作成者が最初に入力した自由記述の回答は決して渡さないでください。作業ディレクトリを PROJECT_ROOT に設定してコマンドを実行します。

node "${PLUGIN_ROOT}/skills/create-site/scripts/validate-site.js" \
  --expectedLocale "<SITE_LOCALE>" \
  --expectedDirection "<SITE_DIRECTION>"

終了コード 2 はブロッキングとして扱います。報告されたドキュメントまたはローカライズのデフォルト値の不一致を修正し、合格するまでコマンドを再実行してください。自動スキルバリデーターはこれらの引数なしで実行され、検出されたドキュメントまたはローカライズコンテキストが内部的に有効であることも引き続き確認します。この明示的な実行では、一時的または永続的なメタデータを使わずに、create-site セッションで承認されたロケールと方向にも一致していることを検証します。

ゲート:フェーズ 5.7 のデザイン批評が完了し、要求されたローカライズが完了し、承認済みのサイト言語の検証に合格するまで、フェーズ 6 に進まないでください。完成したデザインでは、選択した文字体系に対応するタイポグラフィと、論理的で方向に依存しないレイアウトを使用する必要があります。

出力:すべてのページ、コンポーネント、デザイン要素、および要求されたローカライズの実装と検証


フェーズ 6:アクセシビリティ検証

目標:axe-core の自動テストを使用して、サイトが WCAG 2.2 AA 規格を満たしていることを確認し、違反を修正します

**前提条件:**すべてのページとコンポーネントが完全に実装されている必要があります(フェーズ 5 完了)。開発サーバーが起動している必要があります。

アクション:

6.1 前提条件

開発サーバーが起動している必要があります。インストールは不要です。監査では、プラグインに固定された Playwright とシステムにインストール済みのブラウザー(Edge または Chrome)を使用し、実行前に axe-core スクリプトのハッシュが固定値と一致することを検証します。

6.2 すべてのページで axe-core 監査を実行する

監査スクリプトは Bash 経由で実行します。開発サーバーの URL とサイトのすべてのルートを JSON リクエストとして stdin で渡し、シェルによる解析を避けてください。

node "${PLUGIN_ROOT}/scripts/axe-audit.js" --input - <<'REQUEST'
{"url": "<DEV_SERVER_URL>", "routes": ["/", "/about", "/services", "/contact"]}
REQUEST

返されたルートごとの結果を含む JSON 配列を解析します。各結果には、id、impact、description、helpUrl、影響を受ける nodes を含む violations、passes の件数、incomplete の件数が含まれます。終了コードが 0 以外の場合、critical または serious の違反が少なくとも 1 件検出されたか、ルートを監査できなかったことを意味します。後者の場合、結果には violations の代わりに error が含まれるため、原因(ルートの破損、または開発サーバーの停止)を修正し、再度監査してください。

JSON 出力を解析し、すべての違反を記録します。

6.2b 描画結果の双方向監査を実行する

${PLUGIN_ROOT}/references/rendered-bidirectional-verification.md を読みます。 add-localization が成功レポートを返した場合は、まずそのレポートを検証して再利用します。

node "${PLUGIN_ROOT}/scripts/audit-rendered-bidirectional-readiness.js" \
  --projectRoot "<PROJECT_ROOT>" \
  --reuse-report "<ADD_LOCALIZATION_REPORT_PATH>"

これは、子レポートが完了済みの standard または extensive の実行に由来し、その実行が合格していて、ソース、リソース、依存関係、ビルド設定、ロケールの利用可否が引き続き一致する場合にのみ成功します。targeted 修復レポートは再利用できません。準備状態のみを示すメタデータは、レポートを無効にしません。再利用に成功した場合は、仕様を作成したり、マトリックスを再実行したりしないでください。再利用できるレポートが古くなっている場合(アクセシビリティ修正によって関連ソースが変更された場合など)は、現在の実装に基づいてコンポーネント/状態/ビューポートの仕様を作成し、実行します。

node "${PLUGIN_ROOT}/scripts/audit-rendered-bidirectional-readiness.js" \
  --url "<DEV_SERVER_URL>" \
  --projectRoot "<PROJECT_ROOT>" \
  --spec "<TEMP_SPEC_PATH>" \
  --evidence-dir "<PROJECT_ROOT>/docs/bidirectional-evidence/<RUN_ID>" \
  --output "<PROJECT_ROOT>/docs/bidirectional-evidence/<RUN_ID>/report.json"

このコマンドは JSON を出力し、描画結果にブロッキング対象の問題がある場合は終了コード 1 で終了します。この想定される場合は stdout を解析してください。終了コード 2 はランナーまたは仕様の失敗を示します。続行する前に修正する必要があります。レポートの書き込み後、一時的な仕様を削除してください。

描画結果のすべての error を修正し、影響を受けるマトリックス全体を再実行します。レビュー指摘にはスクリーンショットに基づく判断が必要であり、自動的に合格とはなりません。監査では、計算後の lang/dir、コンポーネントと複合フィールドの方向、クリッピング、ページのオーバーフロー、ビューポートからのはみ出し、宣言された非重複、フォーカス順序、ポータル/オーバーレイ、不明な領域/サードパーティの領域、および該当する場合は実行時のラウンドトリップによる保持を網羅する必要があります。表示されている不透明な外部領域は、対象ロケールで置き換えるか、意図的に利用不可にしない限り、ブロッキング対象です。

描画結果検証リファレンスのグループ化実行モデルを使用してください。デフォルトでは maxConcurrency: 3、決定論的なリセットが存在しない場合の状態分離には reload、明示的なリセット操作がある場合に限り resettable、グローバルまたは破壊的な状態には isolated を使用します。独立したルート/ビューポート/ロケールのグループは並行して実行できますが、ロケール切り替えのシーケンスは順次実行します。

GATE: 利用可能なロケールまたは利用可能なサイト体験に影響する error、あるいは未トリアージのレビュー指摘が create-site レポートに含まれている間は、Phase 7 に進まないでください。 すべてのレビュー項目について、証拠と、提案する解決策、判断に基づく合格判定、または利用可能性に関する制限の判断を maker のレビュー用に提示する必要があります。add-localization のブロッカーについては、影響を受けるロケールがすべての有効化境界で利用不可であることを検証できる場合に限り、続行できます。その子レポートは保留中の証拠として保持し、実際のロケールと疑似的な反対方向を使用して、残りの利用可能な体験を監査してください。スクリーンショットは描画された内容を記録するものであり、決定論的な失敗を覆すものではありません。

各レビュー指摘について、解決済み、判断に基づく合格として受け入れ済み、または利用可能性に関する制限として提案済みのいずれかを記録します。利用可能性に関する制限には、影響を受けるコンポーネント/ページ、ユーザーへの影響、レポートまたはスクリーンショットによる証拠を明記する必要があります。error の指摘について、maker の上書きを提案してはいけません。add-localization の子レポートが pending-remediation を返した場合は、続行する前に、影響を受けるすべてのロケールがセレクター、検出、メタデータ、本番出力から引き続き除外されていることを検証してください。

6.3 アクセシビリティ違反の修正

見つかった違反ごとに、該当するソースファイルを特定し、修正を適用します。

違反修正
画像の alt テキストがない<img> タグに説明的な alt 属性を追加します
色のコントラストが不十分CSS の色変数を調整し、コントラスト比を 4.5:1(通常のテキスト)または 3:1(大きなテキスト)にします
フォームのラベルがない<label> 要素または aria-label 属性を追加します
ランドマーク領域がないコンテンツを <main>、<nav>、<header>、<footer> で囲みます
見出しレベルが飛んでいる見出しの階層を正しくします(h1 → h2 → h3 のように、間を飛ばさない)
リンクテキストがないリンクに説明的なテキストまたは aria-label を追加します
lang/dir 属性がない、または正しくないルートの <html> 要素に lang="<SITE_LOCALE>" と dir="<SITE_DIRECTION>" を設定します
フォーカスインジケーターが不十分インタラクティブ要素に視認できる outline スタイルを追加します

関連する違反を各グループで修正した後、コミットします。

git add -A
git commit -m "Fix accessibility: <violation description>"
6.4 修正後の再検証

すべての修正を適用した後、監査スクリプトを再実行し(6.2 と同じコマンド)、違反が解消されたことを確認します。

  1. 新たな違反が見つかった場合(例:修正によってリグレッションが発生した場合)、6.3〜6.4 を繰り返します
  2. スクリプトがコード 0 で終了するまで続けます(すべてのルートが監査され、critical と serious の違反が 0 件)
  3. 修正によって色、間隔、またはレイアウトが変わった場合、影響を受けるルートを再レビューし、スコアカードが引き続き満たされていることを確認します。レビューでソースが変更される場合もあるため、その場合は該当ルートの監査を再実行します。最後の監査と最後のレビューの両方が、追加の修正なしで合格したときに限り、Phase 6 は完了です

ユーザーにサマリーテーブルを提示します。

| Page | Route | Violations Found | Violations Fixed | Status |
|------|-------|-----------------|-----------------|--------|
| Home | / | 3 | 3 | Pass |
| About | /about | 1 | 1 | Pass |
| Contact | /contact | 2 | 2 | Pass |
| **Total** | | **6** | **6** | **All passing** |

GATE:すべてのページが axe-core で critical と serious の違反 0 件で合格するまで、Phase 7 に進まないでください。 軽微および中程度の違反も、可能な範囲で修正してください。ただし、進行を妨げるものではありません。

最終的な axe-core の結果を、対応する REVIEW_DATA.agentChecks 項目に記録します。アクセシビリティの確認は引き続きエージェントが担当します。maker に自動監査の再現を求めることはありません。

出力:axe-core の重大および深刻な違反が 0 件であることを確認済みのサイト


Phase 7:レビューとユーザーテスト

目標:サイトがユーザーの期待を満たし、すべてのページが正しく動作することを確認します

🚦 ゲート(plan · create-site:7.review): ライブサイトのレビュー — デプロイプロンプトの前に変更を依頼できる最後の機会です。キャンセルすると、ユーザーは反復作業を続けられます。以下のアクション一覧のステップ 5 で実行されます。

トリガー: Phase 7 で、Playwright を使ってすべてのページがレンダリングされることを確認済みです。 確認する理由: デプロイ前に UI の問題に気付く機会をユーザーが失い、壊れたページが公開されるおそれがあります。 キャンセル後: 変更はありません。サイトのファイルはディスク上にそのまま残ります。

アクション:

  1. 5.7 のすべてのルートを指定したキャプチャリクエストに "checksOnly": true を設定して 1 回呼び出し、各ルートが引き続き問題なく読み込まれることを確認します。summary.pageErrors、summary.overflow、または summary.captureErrors に記載されたルートがあれば修正します。ビジュアルレビューはすでに Phase 5.7 で実施済みです

  2. Phase 5.7 のデザインスコアカードとともに、構築した内容のサマリーを提示します。

    | Component Type      | Count | Details |
    |---------------------|-------|---------|
    | Pages               | 4     | Home (/), About (/about), Services (/services), Contact (/contact) |
    | Shared Components   | 3     | Navbar, Footer, ContactForm |
    | Design Elements     | 5     | Schibsted Grotesk + Public Sans, 15 color tokens, product-moment hero, status-timeline signature moment, paper-grain backgrounds |
    | Git Commits         | 9     | scaffold + 8 feature and critique commits |
    

    続けて、デザインの主旨を 1 文で示し、スコアカード (カテゴリ、スコア、1 行の根拠)を提示します。3 未満のカテゴリがあれば、その理由も含めます。SITE_LANGUAGE、SITE_LOCALE、SITE_DIRECTION も記載します。

    整合性を確認した双方向レビューの対象範囲を、各コンポーネントの分類と、検証した該当する状態/ビューポートとともに提示します。 方向対応、方向固定、証拠不明/サードパーティの各項目は分けて報告します。実装前の計画を、実装済みコンポーネントの検証根拠として扱わないでください。

    対象範囲の各項目を、レンダリングされたレポートケースおよび取得したスクリーンショットにリンクします。合格、要確認、不合格のケース数を示します。プロジェクト設定として一時的な仕様の内部情報を公開しないでください。 次に、REVIEW_DATA.agentChecks の基準を、フェーズ 5~6 で収集したエビデンスとともに個別に報告します。すべての基準は Passed または Blocked として報告する必要があり、メーカーによる検証として報告してはいけません。承認を求める前に、ブロックされた技術的な基準を修正してください。

    REVIEW_DATA.makerReview は、メーカー向けのライブプレビューチェックリストとして提示します。メーカーに、言語的な正確さ、用語、トーン、地域ごとの表現、規制対象コンテンツ、視覚的な階層と読みの流れ、ブランドのタイポグラフィ、方向性を示す画像/アイコン、テキストの伸長を評価してもらいます。自動チェックでは、これらの判断に基づく基準を承認することはできません。

    最後に、サイトにまだ残っているサンプルコンテンツをリストアップします。src 内で SAMPLE CONTENT マーカーを検索し、各マーカーのファイルと、それが何の代わりをしているかを示します。これにより、ユーザーはこのレビューで実際のコンテンツを提供できます。

  3. 開発サーバーの URL をユーザーに共有し、利用可能なすべてのルートをリストアップします

  4. 双方向対応の準備状況を次のように分類します:

    • Ready: 未解決の静的またはレンダリング済みの指摘が残っていない場合。
    • Ready with proposed limitations: 残っているすべての指摘がレビュー重大度であり、サイトが引き続き機能/可読/アクセシブルであり、各指摘に正確な影響とエビデンスがある場合のみ。
    • Blocked: 決定論的なエラーが利用可能なロケールまたは利用可能なサイト体験に影響を与えている場合。フェーズ 5~6 に戻ってください。メーカーに欠陥の受け入れを求めてはいけません。
    • Ready for available locales; localization pending: 残っているすべてのエラーが、すべてのアクティベーション境界から除外されている add-localization ロケールのみに属する場合。利用できないロケールとブロッカーを示し、そのロケールを承認または有効化のために提供してはいけません。
  5. AskUserQuestion を使用してユーザーにレビューを依頼します:

    「サイトは <dev server URL> でレビューの準備ができています。ブラウザーで確認してください。変更をご希望ですか?」 Ready の場合は、Accept changes と Request revisions を提供します。提案された使用可能な制限がある場合は、Fix before handoff、Accept with documented limitations、Request revisions を提供します。承認はレビュー重大度の制限にのみ適用されます。最終サマリーに承認タイムスタンプ、影響、エビデンスのパスを記録します。ローカライズが構成されている場合は、.powerpages-localization.json で同じ処分を確定し、すべてのセレクター、検出、メタデータ、静的出力の可用性境界を更新してから、先に進む前にローカライズバリデーター、プロジェクトビルド、影響を受ける実際のロケールのアクティベーションケースを再実行します。

  6. ユーザーが変更を要求した場合は、それらを適用し、このゲートに戻る前に該当する静的、レンダリング済み、アクセシビリティ、ブラウザーの各チェックを繰り返します。新しいコントロール、フォームフィールド、または再構築されたセクションは、視覚的な変化がなくても違反を追加する可能性があるため、影響を受けるすべてのルートで axe-core 監査 (6.2) を再実行します。変更が外観に影響する場合は、影響を受けるルートで別のデザインレビューラウンドも実行します。

7.1 最終的なサイト整合性ゲート

ユーザー承認済みのソース変更とすべての通常の検証が完了した後、次を実行します:

node "${PLUGIN_ROOT}/scripts/validate-site-integrity.js" --projectRoot "<PROJECT_ROOT>"

先に進む前に、すべてのブロッキングエラーを修正してください。関連する方向で、拡張されたコンテンツを用いてレビュー指摘を検査および報告します。レビューによってさらにソース変更が発生した場合は、このゲートを再実行します。正常に終了するまでデプロイフェーズに入らないでください。

出力: デプロイ準備が完了したユーザー承認済みのサイト


フェーズ 8:デプロイと次のステップ

目標:サイトをデプロイし、拡張案を提案します。

このフェーズは必須です。デプロイについて確認せずにセッションを終了しないでください。

🚦 ゲート(plan · create-site:8.deploy): デプロイの確認 — 「はい」を選ぶと /deploy-site を実行します。スキップすると、サイトファイルはディスクに残り、後でユーザーがデプロイできます。以下のアクションリストの手順 3 で実行されます。

トリガー: フェーズ 8 開始時。フェーズ 7 のレビュー承認後。 確認する理由: 自動デプロイでは、PAC CLI が現在指している環境がそのまま使用されます。最初のデプロイ先を誤ると、取り消しが困難です。 キャンセルした場合: 何も起こりません。サイトファイルはディスクに残り、デプロイは実行されません。

アクション:

  1. スキルの使用状況を記録します。

    参照先:${PLUGIN_ROOT}/references/skill-tracking-reference.md

    参照先のスキル追跡手順に従って、このスキルの使用状況を記録します。--skillName "CreateSite" を使用してください。注:初回作成のサイトでは .powerpages-site が存在しない場合があります。その場合、スクリプトは何も表示せずに終了します。

  2. src を再度検索し、SAMPLE CONTENT マーカーを確認します。残っている場合は、確認する前に各マーカーとそのファイルを一覧表示し、公開前に置き換えるべき仮のプレースホルダーであることを伝え、質問に件数を含めてください。その場合は 今回はスキップ を推奨オプションにします。

  3. AskUserQuestion を使い、次の選択肢を提示します。今すぐデプロイ(推奨)、今回はスキップ。サンプルコンテンツが残っている場合は、今すぐデプロイ、今回はスキップ(推奨):

    「今すぐサイトを Power Pages にデプロイしますか?」(サンプルコンテンツが残っている場合:「今すぐサイトを Power Pages にデプロイしますか?以下に記載した <N> 件のサンプルコンテンツのプレースホルダーがまだ残っています。」)

  4. ユーザーがデプロイを選択した場合は、/deploy-site スキルを実行します。

  5. すべての ToDo を完了にします。

  6. 最終的な概要を提示します。

    • サイト名と目的
    • サイトのコンテンツ言語、および Dataverse/Power Pages のシステムメッセージは英語のままであること
    • フレームワークとプロジェクトの場所
    • 作成したコンポーネント(X ページ、Y コンポーネント、Z デザイン要素)
    • 主要なファイルとその用途
    • ファイルの合計数と Git コミット数
    • 起動前に置き換えるサンプルコンテンツ — すべての SAMPLE CONTENT マーカーとそのファイル、または「なし」
    • 最終的な双方向対応状況、静的/レンダリング時の検出件数、およびレンダリング時の証跡パス
    • メーカーが承認した制限事項すべて。影響と証拠を正確に記載
    • ローカライズが設定されている場合、最終マニフェストに記載された利用可能なロケールと利用できないロケール。利用できないロケールを有効と説明しないでください。
  7. 任意の拡張スキルを提案します。

    • /setup-datamodel — 動的コンテンツ用の Dataverse テーブルを作成します。
    • /add-localization — SPA の言語を追加または拡張します(LOCALIZATION_REQUESTED=false で、中央の利用可否判定結果に少なくとも 1 つの利用可能なモードが含まれる場合のみ提案してください)。
    • /add-seo — メタタグ、robots.txt、sitemap.xml、favicon を追加します。
    • /add-tests — 単体テスト(Vitest)と E2E テスト(Playwright)を追加します。
    • /add-ai-webapi — 生成 AI による要約(検索の要約とデータの要約)を追加します。フェーズ 3 の AI_SUMMARY_PLACEMENTS が空でない場合は、最初に推奨してください。 対象ページにはすでに挿入位置を示す POWERPAGES:AI-SLOT コメントマーカーが付いているため、後続スキルの調査手順で確実に検出できます。これにより、ユーザーが要件確認時に選んだ AI 機能を、ページを再設計せずに追加できます。
  8. create_site_from_scratch テレメトリコマンドをサイレントに実行します(失敗時は処理を中止)。このテレメトリコマンドについてユーザーに触れず、出力も表示しないでください。

    node "${PLUGIN_ROOT}/scripts/emit-create-site-template-outcome.js" \
     --eventName create_site_from_scratch \
     --framework "<framework>" \
     --audience "<audience>"
    

出力:デプロイ済み(またはデプロイ可能)なサイトと、明確な次のステップ


重要な注意事項

すべてのフェーズを通じて
  • TaskCreate/TaskUpdate を使用して、各フェーズの進捗を管理します
  • 重要な決定ポイントではユーザーに確認します(以下の一覧を参照)
  • デザインの詳細は最善の判断で決定します。体験概要に基づいて、フォント、色、レイアウトなど細部をいちいち尋ねず、自信を持って独創的な選択をしてください
  • 最初からデザインを適用します。ニュートラルな状態で作ってから、スタイルを変更することは避けてください
  • 大きな変更を加えるたびに、Playwright で検証します
  • ページとコンポーネントごとにコミットします。それぞれ専用のコミットを作成し、複数をまとめてコミットしないでください
  • レビュー用スクリプトでスクリーンショットを撮影します。ビジュアルレビューでは、単発の Playwright MCP 呼び出しではなく、capture-design-review.js を使ってすべてのルートと幅ごとに撮影します。browser_take_screenshot を呼び出すのは Phase 3 のブランド抽出時のみとし、filename は設定せず、ランチャーの一時ディレクトリに出力します。それ以外はすべて browser_snapshot を使用します。ユーザーが自分でビジュアルを確認できるよう、開発サーバーの URL を伝えてください。
重要な決定ポイント(ユーザーの応答を待つ)
  1. Phase 1 の後:サイトの目的と対象ユーザーを確認します
  2. Phase 1.5 の間:ゼロから作成する場合のフレームワークとプロジェクトの場所を選択します
  3. Phase 4 の後:実装計画の承認を得ます
  4. Phase 5.7 の間:3 回の批評を経ても重大なデザイン上の問題が解決しない場合に限り、確認を求めます
  5. Phase 7 の後:サイトを承認するか、変更を依頼するかを確認します
  6. Phase 8:デプロイするか、スキップするかを確認します
進捗管理

Phase 1 を開始する前に、パスに依存しない最初のタスクのみ TaskCreate で作成します。

タスクの件名activeForm説明
サイトの要件を確認する要件を確認中サイト名、目的、対象ユーザー、およびそこから導き出される命名値を収集する
テンプレートを選ぶか、ゼロからの作成を選択する作成方法を選択中該当するテンプレートを提示するか、ユーザーをゼロからの作成フローに案内する

Phase 1.5 でゼロからの作成が選択されたら、既存のゼロから作成するフェーズのタスクを追加します。

タスクの件名activeForm説明
プロジェクトをひな形化して開発サーバーを起動するプロジェクトをひな形化中テンプレートをコピーし、プレースホルダーをデフォルト値に置き換え、git init、npm install を実行して開発サーバーを起動し、URL を共有する
サイトのコンポーネントを計画するコンポーネントを計画中ユーザーがひな形をプレビューしている間に、ページ、コンポーネント、デザインの方向性、ルートを決定する
実装計画の承認を得る計画の承認を取得中デザインとページを含む実装計画を提示し、ユーザーの承認を得る
ページとコンポーネントを実装するサイトを構築中承認されたコンテンツの言語でデザイントークンを適用し、すべてのページ、コンポーネント、ルーティング、ナビゲーションを作成する。デザイン批評を実施してから、他の言語を追加するかユーザーに確認する
axe-core でアクセシビリティを検証するアクセシビリティを検証中すべてのページで axe-core を実行し、重大および深刻な違反を修正して、合格するまで再検証する
ユーザーとレビューするサイトをレビュー中すべてのページを表示し、URL を共有してユーザーからフィードバックを得て、変更を適用する
デプロイして仕上げるサイトをデプロイ中デプロイについて尋ね、概要を提示し、次のステップを提案する

Phase 1.5 でテンプレートを使用する方法が選択されたら、環境チェックごとにユーザーが確認できるよう、インストール前のタスクをすぐに追加します。

タスクの主題実行中の表示説明
ローカルテンプレートディレクトリを選択プロジェクトの場所を選択中ローカルテンプレートプロジェクトをどこにクローンするかを尋ね、新規または空の保存先を指定するよう求めます
対象環境を解決環境を解決中環境の事前確認を行う前に、アクティブな PAC/Azure の対象環境とトークンを解決します
対象環境を確認環境を確認中解決した環境が、テンプレートのインストール先としてユーザーが希望する環境かどうかを尋ねます
CLI テナントの一致を検証CLI テナントを確認中インストール前に、PAC CLI と Azure CLI が同じテナントで認証されていることを確認します
JavaScript のブロック解除要件を検証JavaScript の設定を確認中.js に対する blockedattachments を確認し、同意を得たうえで、サイトのアップロード前に js のみを削除します
Dataverse の言語要件を検証言語の利用可否を確認中RetrieveAvailableLanguages を呼び出し、選択したテンプレートの requiredDataverseLanguages に記載されたすべての LCID が利用可能であることを必須とします
テンプレートのインストールを確認テンプレートのインストールを確認中選択したテンプレートと対象環境を表示し、インストールの最終確認を求めます

再インストールポリシーで通常のインポート、更新、または強制インポートのいずれかを選択した後、次を追加します。

TEMPLATE_SOLUTIONS_TO_IMPORT にエントリが 1 つだけ含まれる場合は、タスクの主題に テンプレートのサポートソリューションをインポート、実行中の表示に サポートソリューションをインポート中 を使用します。エントリが 2 つ以上の場合は、表の複数形を使用します。

タスクの主題実行中の表示説明
テンプレートのサポートソリューションをインポートサポートソリューションをインポート中必要な未管理のサポートソリューションを決定的な順序でそれぞれインポートします。マニフェストで publishChanges が指定されたソリューションは、インポートの一部として変更を公開します
テンプレートサイトをクローン、ビルド、アップロードテンプレートサイトを作成中パッケージ化された SPA ソースを選択したローカルディレクトリにクローンし、依存関係をインストールし、設定されたコンパイル済み出力をビルドして検証した後、生成されたコードサイトをアップロードします
テンプレートのシードデータを適用シードデータを適用中読み取り専用の計画と通貨に関する判断が完了した後、サイト作成と並行して、任意のテンプレートシードレコードを挿入します。失敗しても有効化はブロックされません
非アクティブなテンプレートサイトを表示テンプレートサイトを表示中サイトの作成とシード処理が合流した後、pac pages clone が .powerpages-site/website.yml に書き込んだ Website Record ID を使用し、アップロードしたサイトはまだ有効化されていないことをユーザーに伝えます
テンプレートサイトを有効化テンプレートサイトを有効化中解決したサイト名と Website Record ID を指定して activate-site を呼び出します
ライブテンプレートサイトを表示ライブサイトを表示中有効化したサイトの URL をブラウザーで開き、カスタマイズを続けるようユーザーに案内します

ユーザーがライブテンプレートのカスタマイズを選択した場合は、次を追加します。

タスクの主題実行中の表示説明
テンプレートのカスタマイズを計画カスタマイズを計画中ユーザーが変更したい内容を尋ね、既存のクローン済みプロジェクトに対する編集を計画します

すべてのサポートソリューションが同じバージョンまたはそれより新しいバージョンですでにインストールされている場合は、テンプレートのサポートソリューションをインポートを除いた同じリストを追加します。パッケージ化された SPA のクローンとアップロード、サイトの検出、シード、サイトの有効化、ライブプレビューの各タスクは引き続き実行します。

各タスクの開始時に TaskUpdate で in_progress に、完了時に completed に設定します。これにより、ユーザーは進行状況を確認でき、今後の「最初から」ではない分岐でタスクが恒久的にスキップされるのを防ぎながら、ワークフローの決定性を保てます。

品質基準

すべてのサイトは、完成前に次の基準を満たす必要があります。

  • Phase 5.7 のデザイン批評に合格していること:重大なゲート違反がなく、すべての評価項目が 3 以上であること。または、3 回のラウンドを経ても 3 未満の項目について、その理由が記録されていること(design-critique.md を参照)。ユーザーが続行を選んだ重大なゲート違反は、既知の問題として記録されていること
  • デザイントークン(色の役割、フォント、間隔、角丸、シャドウ、モーション)がテーマファイルで一度だけ定義され、全体で使用されていること
  • 選定した Google Fonts がフォントチェックで読み込み済みと確認されていること
  • SITE_LOCALE に対するグリフがすべて含まれ、正しく形成されていること
  • 要求されたページと機能がすべて実装されていること(プレースホルダーではないこと)
  • すべてのルートが動作し、ナビゲーションが完成していること
  • ルートドキュメントで承認済みの SITE_LOCALE と SITE_DIRECTION が使用されていること
  • axe-core によるアクセシビリティ検証済みで、すべてのページに重大または深刻な違反がないこと
  • 主要なマイルストーンで Git にコミットしていること
  • Playwright で検証済みであること
  • ユーザーがレビューし、承認していること
  • デプロイを提案していること

ワークフローの例

ユーザーのリクエスト

「コンサルタント向けのパートナーポータルを作成してください」

Phase 1:要件の確認
  • 名前:Partner Portal
  • 目的:Company Portal
  • 対象:社内(パートナー、コンサルタント)
Phase 1.5:テンプレート分岐の決定
  • 作成方法:ゼロから作成
  • フレームワーク:React
  • 場所:現在のディレクトリに新しいフォルダー partner-portal
Phase 2:スキャフォールドの作成と起動
  • React テンプレートをコピーし、デフォルトのプレースホルダーを置き換え
  • Git を初期化し、npm をインストール。開発サーバーを http://localhost:5173 で起動
  • Playwright でスキャフォールドが読み込まれることを検証
  • URL をユーザーに共有し、すぐにプレビューできるようにする
Phase 3:コンポーネントの計画
  • 機能:コンサルタント一覧、プロジェクトトラッカー、ドキュメントライブラリ、お知らせ
  • 美的方向性:ミニマルで洗練されたデザイン
  • 雰囲気:プロフェッショナルで信頼感のあるデザイン
  • ブランド:新しいアイデンティティ
  • エクスペリエンスの概要:主なアクションは「コンサルタントを探す」。主な懸念は「この一覧は最新ですか?」。その裏付けとして、ライブデータによる「本日更新」の表示を目に見える形で示す
  • デザインの主張:落ち着きがあり、正確で、控えめながらも自信を感じさせるデザイン。温かみのある紙のような表面、Public Sans の本文に Schibsted Grotesk の見出しを組み合わせ、深みのあるティールをアクションカラーに一色だけ使用し、ライブのプロジェクト件数を表示するタスク優先のウェルカムヒーローを設ける
  • 印象的な瞬間:一覧のフィルターを適用すると、コンサルタントカードがアニメーション付きで即座に再配置される
  • ページごとのストーリー展開を含むコンポーネント表を提示し、承認を得る
Phase 4:計画の承認
  • DESIGN_DIRECTION_DATA を含む計画データを 1 つの JSON オブジェクトとして組み立てる
  • render-createsite-plan.js を使って docs/create-site-plan.html にレンダリングする
  • ユーザーの既定のブラウザーで開く
  • ブラウザーのタブを案内する簡潔な概要をターミナルに表示する
  • AskUserQuestion でユーザーの承認を得る
Phase 5:実装
  • 各ページ、コンポーネント、ルーティング、ナビゲーション、デザイン基盤、批評工程について Todo を作成
  • デザイントークン → レイアウト → 共通コンポーネント → ホーム(まずヒーローを作成し、第一印象を確認) → 残りのページ → ルーター → ナビゲーションの順に構築
  • デザイン批評の第 1 ラウンドでは、ナラティブが 2(ホームに同一のカードセクションが 3 つ)、ディテールが 2(アイコンの線幅が混在)と評価されたため、両方を修正。第 2 ラウンドでは、すべての評価項目が 3 以上
  • 各主要部分の完成後、および各批評ラウンドの後に Git にコミット
Phase 6:アクセシビリティの検証
  • browser_evaluate を使い、4 ページすべてに axe-core を注入して実行
  • 5 件の違反を検出:alt テキストの欠落 2 件、コントラスト不足 1 件、lang 属性の欠落 1 件、見出しレベルの飛び越し 1 件
  • すべての違反をソースコードで修正し、コミット
  • 再実行して、すべてのページで重大または深刻な違反がないことを確認
Phase 7:レビュー
  • 概要表とデザイン評価表を提示
  • ユーザーが http://localhost:5173 でレビューし、色の軽微な調整を依頼
  • 調整を適用し、再検証
Phase 8:デプロイ
  • ユーザーがデプロイを選択 → /deploy-site を実行
  • 次のステップの提案を含む最終概要を提示

Phase 1:要件の確認から始めてください

コメント