テーマビルドスキル
ユーザーの自然言語によるサイト説明に基づいて、WP.orgからフルサイト編集(FSE)ブロックテーマを選択、インストール、有効化します。このスキルはWP.orgテーマAPI v1.2をFSEテーマでクエリし、Claudeのコンテキスト内判断を使用して結果をNLプロンプトに対して評価し、最適なものをインストールします。APIが不十分な結果を返した場合や利用できない場合に備え、キュレーションされたフォールバックリストが確実なテーマ選択を保証します。
重要な実行順序: このスキルはbuild-mcpセクション2(MCPアダプタ有効化、データベース再エクスポート)の後、かつbuild-content(コンテンツシーディング)の前に実行されます。コンテンツシーディングではメニュー位置の検出にアクティブなテーマが必要なため、テーマは事前に有効化されている必要があります。
このスキルは、呼び出し元のコマンドによって以下の変数が既に設定されていることを前提とします。
BUILD_DIR— ビルドディレクトリの絶対パス(build-scaffoldセクション2で設定)WP— WP-CLIコマンドプレフィックス(例:wp --path=$BUILD_DIRまたはDocker相当、build-scaffoldセクション4で設定)NL_PROMPT— ユーザーの自然言語によるサイト説明文字列SITE_TITLE— NLプロンプトから派生したサイトタイトル(このスキルの前に呼び出し元コマンドが設定)
セクション1: WP.orgテーマAPIクエリ
FSEブロックテーマプールをWP.orgテーマAPI v1.2にクエリします。フィルタリングにはfull-site-editingタグを使用します — これがFSE/ブロックテーマの正規の公開シグナルです。searchパラメータとtagパラメータを組み合わせないでください。APIはsearchが存在する場合、タグを無視します。Claudeはプールを取得した後、コンテキスト内でテーマの関連性を評価します。
echo "[Build] FSEテーマプールをWP.orgテーマAPIにクエリ中..."
# 重要なアンチパターン: ?action=query_themes&request[search]=...&request[tag][]=full-site-editing は使用しないこと
# APIはsearchが存在する場合、tag[]を無視します。タグのみのクエリを使用し、Claudeがコンテキスト内で関連性を評価します。
FSE_THEMES_FILE="/tmp/fse_themes_$$.json"
curl -s --max-time 10 \
"https://api.wordpress.org/themes/info/1.2/?action=query_themes&request[tag][]=full-site-editing&request[browse]=popular&request[per_page]=50&request[fields][active_installs]=true&request[fields][rating]=true&request[fields][description]=true&request[fields][tags]=true" \
-o "$FSE_THEMES_FILE"
CURL_EXIT=$?
# レスポンスの検証 — 終了コード、空でないファイル、JSON構造をチェック
API_AVAILABLE=false
if [ $CURL_EXIT -eq 0 ] && [ -s "$FSE_THEMES_FILE" ]; then
# レスポンス内のテーマ数をカウント — Claudeが適切に評価するには少なくとも3つ必要
THEME_COUNT=$(python3 -c "import json,sys; d=json.load(open(sys.argv[1])); print(len(d.get('themes', [])))" "$FSE_THEMES_FILE" 2>/dev/null || echo "0")
if [ "$THEME_COUNT" -ge 3 ]; then
API_AVAILABLE=true
echo "[Build] WP.org APIが評価用に$THEME_COUNT個のFSEテーマを返しました。"
else
echo "[Build] WP.org APIが3つ未満のテーマしか返しませんでした($THEME_COUNT)。キュレーションリストにフォールバックします。"
fi
else
echo "[Build] WP.org APIが利用できません — キュレーションテーマリストを使用します"
fi
セクション2: テーマ評価と選択
ClaudeはAPIのJSONレスポンスを読み取り、各テーマをNL_PROMPTに対して評価します。APIが実行可能なプールを返した場合、Claudeは関連性、人気、評価を使用して最適なものを選択します。APIが失敗した場合や結果が少なすぎる場合、ClaudeはNL_PROMPTのサイトカテゴリに基づいてキュレーションされたフォールバックリストから選択します。
スコアリング基準(優先順位順):
NL_PROMPTに記述されたサイトタイプに対する名前、説明、タグの関連性active_installs— 人気シグナル(高いほど良い)rating— 品質シグナル(高いほど良い)
クラシックテーマは決して選択されません。たとえ他の指標で高いスコアを獲得してもです。
if [ "$API_AVAILABLE" = "true" ]; then
echo "[Build] NLプロンプトに対してFSEテーマを評価中: \"$NL_PROMPT\""
echo "[Build] テーマファイルを読み込み中: $FSE_THEMES_FILE"
# ClaudeがFSEテーマJSONを読み取り、各テーマを評価:
# - themes[].name: 表示名
# - themes[].slug: WP.orgインストールスラッグ
# - themes[].description: テーマ説明
# - themes[].tags: テーマ機能/カテゴリタグ
# - themes[].active_installs: 人気(アクティブインストール数)
# - themes[].rating: 品質評価(0-100スケール)
#
# Claudeは以下の最良の組み合わせを持つテーマを選択:
# (1) NL_PROMPTサイトタイプへの関連性
# (2) 高い active_installs
# (3) 高い rating
#
# 該当なし動作: NL_PROMPTサイトタイプに対してどのテーマも良好なスコアを獲得できない場合、
# Claudeは上位3候補をユーザーに提示し、選択を促します。
# これは意図的に自律フローを中断します — 満足度 > 自動化。
#
# 選択後、Claudeは以下を設定:
THEME_SLUG="<ClaudeがAPI結果から選択したスラッグ>"
THEME_NAME="<ClaudeがAPI結果から選択した表示名>"
else
# キュレーションフォールバックリスト — サイトカテゴリを既知のFSE互換テーマスラッグにマッピング
# これらのテーマはWP.orgでメンテナンスされている検証済みのFSEブロックテーマです。
# テーマがWP.orgから削除された場合、このリストを更新してください。
#
# カテゴリ → スラッグマッピング(ClaudeはNL_PROMPTからサイトカテゴリを抽出):
#
# portfolio / photography / creative → flavor
# business / corporate / agency → flavor
# blog / magazine / news → flavor
# restaurant / food / cafe → flavor
# ecommerce / shop / store → flavor
# default (その他) → twentytwentyfour
#
# twentytwentyfour は保証された最終手段のフォールバックです(WordPress.orgコアチームがメンテナンス)。
#
# ClaudeはNL_PROMPTを読み、サイトカテゴリを判断し、以下を設定:
THEME_SLUG="<Claudeがキュレーションフォールバックリストから選択したスラッグ>"
THEME_NAME="<選択されたキュレーションテーマの表示名>"
fi
echo "[Build] 選択されたテーマ: $THEME_NAME ($THEME_SLUG)"
セクション3: テーマのインストールと有効化
選択されたテーマをWP-CLIを使用してインストールし、有効化します。インストールに失敗した場合は、フォールバック候補を試みます。インストール後、theme.jsonの存在を確認してFSE互換性を常に検証します。警告を表示して続行 — テーマの失敗でビルドを中止しないでください。
echo "[Build] テーマをインストール中: $THEME_SLUG..."
install_theme() {
local slug="$1"
if $WP theme install "$slug" --activate 2>&1; then
echo "[Build] テーマがインストールされ、有効化されました: $slug"
# FSE検証 — theme.jsonの存在を確認
# ClaudeはFSEプールから選択したため、これは二次確認です。
# theme.jsonがサブディレクトリにあるか、別の名前の場合、偽陰性の可能性があります。
if [ -f "$BUILD_DIR/wp-content/themes/$slug/theme.json" ]; then
echo "[Build] FSE検証: theme.jsonが見つかりました。"
else
echo "[Build] 警告: theme.jsonが見つかりません — テーマがFSE互換でない可能性があります。"
echo "[Build] 続行します — Claudeはfull-site-editingタグプールからこのテーマを選択しました。"
fi
# テーマバージョンを取得
THEME_VERSION=$($WP theme get "$slug" --field=version 2>/dev/null || \
grep -m 1 "^Version:" "$BUILD_DIR/wp-content/themes/$slug/style.css" 2>/dev/null | \
sed 's/Version: //' | tr -d '[:space:]' || \
echo "unknown")
THEME_INSTALLED=true
echo "[Build] テーマがインストールされ、有効化されました: $slug (v$THEME_VERSION)"
return 0
else
echo "[Build] 警告: テーマのインストールが失敗しました(スラッグ: $slug)"
THEME_INSTALLED=false
return 1
fi
}
# 試行1: API選択またはキュレーションテーマをインストール
if ! install_theme "$THEME_SLUG"; then
# 試行2: API選択テーマが失敗した場合、キュレーションフォールバックを試行
if [ "$API_AVAILABLE" = "true" ]; then
echo "[Build] サイトカテゴリのキュレーションフォールバックテーマを試行中..."
# ClaudeはNL_PROMPTサイトカテゴリからキュレーションフォールバックスラッグを決定
# (セクション2のキュレーションリストを参照)して再試行
FALLBACK_SLUG="twentytwentyfour" # Claudeが該当する場合はカテゴリ固有のスラッグに置き換え
if ! install_theme "$FALLBACK_SLUG"; then
# 試行3: 最終手段 — twentytwentyfour(WordPress.orgがメンテナンス)
if [ "$FALLBACK_SLUG" != "twentytwentyfour" ]; then
echo "[Build] 最終手段のフォールバックを試行中: twentytwentyfour..."
if ! install_theme "twentytwentyfour"; then
# 最終フォールバック — 警告をログに記録し、WPデフォルトテーマで続行
echo "[Build] 警告: すべてのテーマインストール試行が失敗しました。"
echo "[Build] 警告: WordPressデフォルトテーマでビルドを続行します。"
THEME_SLUG="default"
THEME_NAME="WordPress Default"
THEME_VERSION="unknown"
THEME_INSTALLED=false
fi
else
# twentytwentyfour が既に失敗 — デフォルトで続行
echo "[Build] 警告: すべてのテーマインストール試行が失敗しました。"
echo "[Build] 警告: WordPressデフォルトテーマでビルドを続行します。"
THEME_SLUG="default"
THEME_NAME="WordPress Default"
THEME_VERSION="unknown"
THEME_INSTALLED=false
fi
fi
else
# キュレーションテーマが失敗 — 最終手段としてtwentytwentyfourを試行
if [ "$THEME_SLUG" != "twentytwentyfour" ]; then
echo "[Build] 最終手段のフォールバックを試行中: twentytwentyfour..."
if ! install_theme "twentytwentyfour"; then
echo "[Build] 警告: すべてのテーマインストール試行が失敗しました。"
echo "[Build] 警告: WordPressデフォルトテーマでビルドを続行します。"
THEME_SLUG="default"
THEME_NAME="WordPress Default"
THEME_VERSION="unknown"
THEME_INSTALLED=false
fi
else
echo "[Build] 警告: すべてのテーマインストール試行が失敗しました。"
echo "[Build] 警告: WordPressデフォルトテーマでビルドを続行します。"
THEME_SLUG="default"
THEME_NAME="WordPress Default"
THEME_VERSION="unknown"
THEME_INSTALLED=false
fi
fi
fi
# 一時APIレスポンスファイルをクリーンアップ
rm -f "$FSE_THEMES_FILE"
セクション4: サイトタイトルの更新
WordPressのサイトタイトルとタグラインをNL_PROMPTに記述されたサイトに合わせて更新します。サイトタイトルはbuild-scaffoldのWPインストール時に既に設定されています(--title="$SITE_TITLE")が、このステップではNLプロンプトから生成されたコンテキストに応じた説明でタグラインを設定できます。
echo "[Build] サイトタイトルとタグラインを設定中..."
# サイトタイトルを更新(build-scaffoldの--titleと既に一致している場合もありますが、確認のために更新)
$WP option update blogname "$SITE_TITLE" 2>&1
# ClaudeがNL_PROMPTから簡単なタグライン(1行、引用符なし)を生成
# 例:
# NL_PROMPT: "a portfolio site for a freelance photographer"
# → タグライン: "Capturing moments that matter"
#
# NL_PROMPT: "a restaurant website for an Italian bistro in Sydney"
# → タグライン: "Authentic Italian flavours in the heart of Sydney"
#
# ClaudeがSITE_TAGLINEを生成されたタグラインに設定し、次を実行:
SITE_TAGLINE="<ClaudeがNL_PROMPTから生成したタグライン>"
$WP option update blogdescription "$SITE_TAGLINE" 2>&1
echo "[Build] サイトタイトルを設定: $SITE_TITLE"
echo "[Build] サイトタグラインを設定: $SITE_TAGLINE"
実装ノート
パイプライン上の位置: このスキルはNLビルドパイプライン内で、厳密にbuild-mcpセクション2(MCPアダプタ有効化、データベース再エクスポート)の後、かつbuild-contentの前に実行されます。コンテンツシーディングでは$WP menu location listを使用してアクティブテーマのナビゲーション位置を検出するため、テーマは事前にインストールされ有効化されている必要があります。
Docker MySQLコンテナ: build-scaffoldセクション3のエフェメラルDocker MySQLコンテナは、このスキルが実行される際にまだ実行中である必要があります。WP-CLIテーマインストールはWordPressオプションテーブル(アクティブテーマスラッグ)に書き込みます。build-scaffoldセクション3で設定されたEXITトラップはビルドセッション全体でアクティブのままで、完全なコマンドが終了したときにのみ発火します — スキル呼び出しの間ではありません。
出力変数: 以下の変数はこのスキルによって設定され、後続のスキル(build-content、build-setup)で使用されます:
THEME_SLUG— インストールされたテーマスラッグ(例:twentytwentyfour、flavor)THEME_NAME— 表示名(例:Twenty Twenty-Four、Flavor)THEME_VERSION— インストールされたバージョン文字列(例:1.3、検出不可の場合はunknown)THEME_INSTALLED— インストール成功時はtrue、すべてのフォールバックが失敗した場合はfalse
キュレーションフォールバックリストのメンテナンス: キュレーションリストはサイトカテゴリをWP.org上の既知のFSEブロックテーマにマッピングします。キュレーションテーマのスラッグがWP.orgから削除され(wp theme installが「not found」で失敗する)、現在のFSE互換の代替テーマでこのリストを更新してください。twentytwentyfourは保証された最終手段のフォールバックです — WordPress.orgコアチームによってメンテナンスされており、削除されることはありません。
インストール後のカスタマイズなし(固定決定): CONTEXT.mdに記録されたユーザーの決定により、インストール後にtheme.jsonのオーバーライド、子テーマ、グローバルスタイルの変更は適用されません。テーマはWP.orgからそのままインストールされ、有効化されます。テーマの組み込みデザインがそのまま提供されます。
FSE検証の信頼性: theme.jsonのチェックは二次確認です — ClaudeはAPIクエリでfull-site-editingタグによって既にテーマをフィルタリングしています。「警告: theme.jsonが見つかりません」というメッセージはエラーを示しません:テーマがtheme.jsonを非標準の場所に保存しているか、WP.orgタグが正しく設定されていてもファイルパスのチェックが失敗した可能性があります。ビルドは関係なく続行されます。
参考文献:
- @references/wp-block-themes/SKILL.md — FSEテーマ構造、theme.jsonスキーマ、ブロックテンプレートパターン
- @references/wp-wpcli-and-ops/SKILL.md — WP-CLIテーマコマンドリファレンス、--activateフラグ、--field出力