name: update-store description: ストア情報の更新自動化 — スクリーンショット撮影(シミュレーター × モック画面 × Marionette MCP)とメタデータテキスト更新。ストア更新、スクショ更新、App Store / Google Play のメタデータ更新、リリースノート作成の際に使用すること。
Update Store
ストアスクリーンショットの自動撮影・合成と、メタデータテキスト(description, release_notes等)の更新を行う。
前提
- デバッグモードのアプリにはストアスクショ用のカスタムエクステンション(
ccpocket.navigateToStoreScenario)が登録済み - Marionette MCPの
call_custom_extensionが使用可能 - ImageMagickがインストール済み(
compose.shで使用) - sim-tap.swift: 同梱のSwiftスクリプト(
scripts/sim-tap.swift)。macOSアクセシビリティAPIでSimulatorのネイティブダイアログ(通知許可等)をラベル指定でタップできる
ワークフロー
Step 1: バージョン確認 & 変更分析
# 最新リリースタグ
git tag -l 'ios/v*' --sort=-v:refname | head -1
# 現在のバージョン
grep '^version:' apps/mobile/pubspec.yaml
# 前回リリースからの変更コミット
git log $(git tag -l 'ios/v*' --sort=-v:refname | head -1)..HEAD --oneline -- apps/mobile/
CHANGELOGの最新セクションも確認:
head -80 CHANGELOG.md
変更内容を分析し、UI変更があったかどうかを判断する。
Step 2: 更新対象の選択
AskUserQuestion(multiSelect)で更新対象を確認する。 変更分析結果に基づいて推奨をdescriptionに含める。
iPhone スクリーンショット(8シナリオ):
| Key | シナリオ名 | 内容 | テーマ |
|---|---|---|---|
01_session_list |
Session List (Recent) | ホーム画面(名前付きセッション) | ライト |
02_approval_list |
Session List | 承認待ち一覧(3セッション) | ライト |
03_multi_question |
Multi-Question Approval | 質問UI(3問) | ライト |
04_markdown_input |
Markdown Input | Markdown箇条書き入力 | ライト |
05_image_attach |
Image Attach | 画像添付UI | ライト |
06_git_diff |
Git Diff | Diff表示画面 | ライト |
07_new_session |
New Session | 新規セッションシート | ライト |
08_dark_theme |
Session List | 承認待ち一覧(ダークモード訴求) | ダーク |
iPad スクリーンショット(5シナリオ):
| Key | シナリオ名 | 内容 | テーマ |
|---|---|---|---|
01_workspace_overview |
Workspace Overview | 左一覧 + 中央チャット + 右Git | ライト |
02_workspace_explorer |
Workspace Explorer | 左一覧 + 中央チャット + 右Explorer | ライト |
03_approval_context |
Approval In Context | 左一覧 + 中央承認UI | ライト |
04_approval_queue |
Approval Queue | 複数の承認待ちセッションを同時に確認 | ライト |
05_dark_workspace |
Dark Workspace | 3-pane ワークスペースのダークテーマ訴求 | ダーク |
メタデータテキスト:
| ファイル | 対象 |
|---|---|
fastlane/metadata/en-US/release_notes.txt |
iOS リリースノート (EN) |
fastlane/metadata/ja/release_notes.txt |
iOS リリースノート (JA) |
fastlane/metadata/en-US/description.txt |
App Store 説明文 (EN) |
fastlane/metadata/ja/description.txt |
App Store 説明文 (JA) |
fastlane/metadata/en-US/promotional_text.txt |
プロモーションテキスト (EN) |
fastlane/metadata/android/en-US/full_description.txt |
Play Store 説明文 (EN) |
fastlane/metadata/android/ja-JP/full_description.txt |
Play Store 説明文 (JA) |
fastlane/metadata/android/en-US/changelogs/default.txt |
Play Store リリースノート (EN) |
fastlane/metadata/android/ja-JP/changelogs/default.txt |
Play Store リリースノート (JA) |
上記のファイルパスは apps/mobile/ からの相対パス。
Step 3: メタデータテキスト更新(選択された場合)
CHANGELOGの内容をベースに:
- release_notes — CHANGELOG最新セクションを簡潔にまとめる
- description — 新機能に応じて追記・修正
- promotional_text — キャッチコピーを更新
更新後、AskUserQuestionで内容確認を挟む。
Step 4: iPhone スクリーンショット撮影(選択された場合)
4-1. デバイス確認 & シミュレーター起動
xcrun simctl list devices available | grep -E "iPhone 17|iPad Pro.*13"
ソフトウェアキーボードを無効化(全デバイス共通、セッション冒頭で1回実行):
defaults write com.apple.iphonesimulator ConnectHardwareKeyboard -bool true
これによりソフトウェアキーボードが表示されなくなり、日本語キーボードがスクショに映り込む問題を防止する。
iPhone / iPad ともに 既存シミュレーターを再利用するのがデフォルト。毎回 erase すると通知・音声認識・マイク等のネイティブダイアログが再出現し、スクショフローが不安定になる。通常はアプリの再起動と向き調整だけで十分。
iPhone 17 Proシミュレーターを起動し、ライトモードに設定:
xcrun simctl boot "iPhone 17 Pro" 2>/dev/null || true
xcrun simctl ui booted appearance light
英語ロケール設定(ストアスクショは en-US 基準のため):
# iPhone・iPad の両デバイスIDで実行
for ID in <iPhone_ID> <iPad_ID>; do
xcrun simctl spawn $ID defaults write -g AppleLanguages "(en-US)"
xcrun simctl spawn $ID defaults write -g AppleLocale "en_US"
done
# 反映には再起動が必要
for ID in <iPhone_ID> <iPad_ID>; do
xcrun simctl shutdown $ID
done
sleep 2
for ID in <iPhone_ID> <iPad_ID>; do
xcrun simctl boot $ID
done
これによりアプリ内の標準コンポーネント(DatePicker、システムダイアログ等)も英語化される。
アプリ内文言はカスタムエクステンション ccpocket.setLocale で別途 en に切り替える。
ステータスバーを Apple 純正風に固定(9:41 / WiFi / 100% 充電 / キャリア非表示):
for ID in <iPhone_ID> <iPad_ID>; do
xcrun simctl status_bar $ID override \
--time "9:41" \
--dataNetwork wifi \
--wifiMode active \
--wifiBars 3 \
--cellularMode notSupported \
--batteryState charged \
--batteryLevel 100
done
iPad の日付について(既知の制限):
iPad のステータスバーには時刻に加えて日付(例: Tue Apr 21)が表示されるが、xcrun simctl status_bar --time は 時刻部分のみ反映で日付は変更不可(Xcode 26.1 時点で ISO 日付を渡してもエラーになる)。
Apple 純正アプリのスクショは Apr 1 等になっているが、現状はシミュレーターのシステム日付がそのまま出る。完全一致が必要な場合のみ、シミュレーター内 Settings > General > Date & Time > Set Automatically OFF で手動設定する。通常は許容して進める。
参考:
4-2. アプリ起動 & Marionette接続
dart-mcp launch_app でアプリを起動:
root: /Users/k9i-mini/Workspace/ccpocket/apps/mobile
device: <iPhone 17 Pro の device ID>
起動後、dart-mcp list_running_apps でDTD URIを取得し、connect_dart_tooling_daemon で接続。
dart-mcp get_app_logs でVM Service URIを取得し、marionette connect で接続。
4-3. 各シナリオのスクショ撮影
テーマ設定: アプリ起動後、カスタムエクステンションでテーマを切り替える(01〜07はライトテーマ):
- marionette
call_custom_extension:ccpocket.setTheme/{ "theme": "light" } - 値:
light,dark,system
言語設定: 必要に応じてカスタムエクステンションで言語を切り替える:
- marionette
call_custom_extension:ccpocket.setLocale/{ "locale": "en" } - 値:
en,ja,zh,""(システムデフォルト)
選択された各シナリオに対して:
遷移: marionette
call_custom_extension- extension:
ccpocket.navigateToStoreScenario - params:
{ "scenario": "<シナリオ名>" }
- extension:
待機: 2-3秒(描画完了を待つ。New SessionやImage Attachなど複雑なUIは3秒推奨)
撮影:
xcrun simctl io booted screenshot apps/mobile/fastlane/screenshots/en-US/<key>.png戻る: marionette
call_custom_extension- extension:
ccpocket.popToRoot
- extension:
待機: 1秒(ルートへの遷移完了)
08_dark_theme の撮影: 01〜07撮影後、ccpocket.setTheme で dark に切り替え、Session List シナリオを撮影する。
4-4. アプリ停止
dart-mcp stop_app でアプリを停止。
シミュレーターはシャットダウンしない。次のデバイスの起動に進む。
Step 5: iPad スクリーンショット撮影(選択された場合)
iPad は iPhone とは別セットを撮影する。既存の mobile 専用シナリオを流用せず、 workspace レイアウト前提の 5 シナリオを撮る。
5-1. iPadシミュレーターの全画面表示を保証
iPadでアプリが互換モード(iPhone用の小さいウィンドウ + 黒帯)で起動する場合がある。
ただし、通常は erase しない。まずは既存シミュレーターをそのまま使い、アプリだけ再起動する:
# シミュレーターを起動(未起動なら)
xcrun simctl boot "iPad Pro 13-inch (M4)" 2>/dev/null || true
重要: erase を実行するとアプリがアンインストールされ、通知・音声認識・マイク等のネイティブダイアログが毎回復活する。これはスクショ取得の妨げになるため、erase は最後の手段に限定する。
erase を使ってよいケース:
- 実際に互換モード(iPhone用の小さいウィンドウ + 黒帯)で起動した
- アプリ再起動だけでは解消しない
- raw スクショの解像度が期待値から大きく外れている
その場合のみ、以下を実行してやり直す:
xcrun simctl shutdown "iPad Pro 13-inch (M4)" 2>/dev/null || true
xcrun simctl erase "iPad Pro 13-inch (M4)"
xcrun simctl boot "iPad Pro 13-inch (M4)" 2>/dev/null || true
横向き前提: iPad スクショは landscape で撮る。起動後に sim-tap.swift の準備コマンドを必ず実行する:
swift .claude/skills/update-store/scripts/sim-tap.swift prepare-store ipad
これで以下をまとめて行う:
- Simulator を前面化
Device > Orientation > Landscape Leftで iPad を明示的に横向き固定- 通知許諾などのネイティブダイアログを dismiss
撮影中に向きが崩れた場合や許諾ダイアログが再表示された場合も、スクショを撮る前に再度これを実行する。
ネイティブダイアログの自動dismiss: erase を避ければ、これらのダイアログは通常は再発しない。既存シミュレーター再利用時は、まず prepare-store ipad で向きを整え、ダイアログが出ていた場合だけ dismiss する。
事前権限付与: もし erase を実行した場合のみ、アプリ起動前に実行する:
xcrun simctl privacy booted grant notifications com.k9i.ccpocket
xcrun simctl privacy booted grant speech-recognition com.k9i.ccpocket
xcrun simctl privacy booted grant microphone com.k9i.ccpocket
これによりダイアログの表示自体を防止できる。simctl privacy が失敗した場合は以下のフォールバックを使う。
フォールバック: sim-tap.swift の個別コマンド: ダイアログはホーム画面ではなくセッション画面遷移後に表示されることがある。 最初のシナリオ遷移後にdismissし、必要なら撮り直す。
AX API でボタンが見つからない場合(特にiPad)、CGEvent ベースのクリックで自動フォールバックする:
swift .claude/skills/update-store/scripts/sim-tap.swift rotate right
swift .claude/skills/update-store/scripts/sim-tap.swift dismiss-dialogs ipad
swift .claude/skills/update-store/scripts/sim-tap.swift dismiss-dialogs iphone
従来の個別タップも引き続き使用可能:
while swift .claude/skills/update-store/scripts/sim-tap.swift tap "許可" 2>/dev/null; do sleep 1; done
5-2. シナリオ撮影 & 解像度検証
テーマ設定: iPad 側は Dark Workspace 以外をライトテーマで撮る。アプリ起動後に最初に一度:
marionette call_custom_extension
- extension:
ccpocket.setTheme - params:
{ "theme": "light" }
Dark Workspace はシナリオ側で一時的にダークへ切り替わるため、個別に setTheme dark する必要はない。
各シナリオに対して:
marionette
call_custom_extension- extension:
ccpocket.navigateToStoreScenario - params:
{ "scenario": "<シナリオ名>" } - 値:
Workspace OverviewWorkspace ExplorerApproval In ContextApproval QueueDark Workspace
- extension:
2-3秒待機
撮影
swift .claude/skills/update-store/scripts/sim-tap.swift capture-store ipad apps/mobile/fastlane/screenshots/en-US/ipad_<key>.pngmarionette
call_custom_extension- extension:
ccpocket.popToRoot
- extension:
1秒待機
5-3. 解像度検証
撮影後、スクショの解像度がiPadのネイティブ解像度と一致するか検証する:
swift .claude/skills/update-store/scripts/sim-tap.swift capture-store ipad apps/mobile/fastlane/screenshots/en-US/ipad_<key>.png
# 解像度検証(互換モード検出)
WIDTH=$(sips -g pixelWidth apps/mobile/fastlane/screenshots/en-US/ipad_<key>.png | tail -1 | awk '{print $2}')
HEIGHT=$(sips -g pixelHeight apps/mobile/fastlane/screenshots/en-US/ipad_<key>.png | tail -1 | awk '{print $2}')
echo "Screenshot: ${WIDTH}x${HEIGHT}"
# iPad Pro 13-inch (M4) landscape: 2752x2064 が期待値
# 解像度が大幅に小さい場合のみ、互換モードを疑って erase を検討する
もし解像度が期待値と異なる場合は、まずアプリ再起動で再確認する。それでも解消しない場合のみ erase、必要に応じて flutter clean → flutter build ios --simulator でやり直すこと。
5-4. アプリ停止
dart-mcp stop_app でアプリを停止。
シミュレーターはシャットダウンしない(compose.sh 実行や確認に支障はない)。
Step 6: スクリーンショット合成 & 配置
cd apps/mobile && bash fastlane/screenshots/compose.sh
このスクリプトが行うこと:
- iPhone/iPad の raw スクショにデバイスフレーム・テキストオーバーレイを追加
- en-US と ja の両方のframed画像を生成
fastlane/screenshots/store/へコピー(fastlane deliver用)fastlane/metadata/android/へコピー(Google Play用)docs/images/screenshots.pngを更新(READMEバナー)
Step 7: 確認
# 生成画像の確認
ls -la apps/mobile/fastlane/screenshots/store/en-US/
ls -la apps/mobile/fastlane/screenshots/store/ja/
# 変更ファイル一覧
git diff --stat
シナリオ名 ↔ ファイルキー対応表
| シナリオ名(extension引数) | ファイルキー(スクショファイル名) | テーマ |
|---|---|---|
| Session List (Recent) | 01_session_list |
ライト |
| Session List | 02_approval_list |
ライト |
| Multi-Question Approval | 03_multi_question |
ライト |
| Markdown Input | 04_markdown_input |
ライト |
| Image Attach | 05_image_attach |
ライト |
| Git Diff | 06_git_diff |
ライト |
| New Session | 07_new_session |
ライト |
| Session List | 08_dark_theme |
ダーク |
注意事項
- New Session シナリオ: ボトムシートが
addPostFrameCallbackで自動表示されるため、3秒待機推奨 - Markdown Input シナリオ: DraftServiceで入力欄にテキストが事前セットされる。キーボードは非表示のまま撮影すること(
ConnectHardwareKeyboardを有効化済み) - Image Attach シナリオ: モック画像が自動的に添付される
- シミュレーターデバイス名: Xcode バージョンにより正確な名前が異なる場合がある。
xcrun simctl list devices availableで確認 - compose.sh: ImageMagick (
convert/magick) が必要。PNGタイムスタンプを除去して不要なgit diffを防止 - iPad スクショ: landscape 前提。raw スクショも framed 画像も
2752x2064を基準に扱う - ステータスバー override の解除: 撮影完了後に通常開発に戻す場合は
xcrun simctl status_bar <ID> clearを実行する(override 自体はシミュレーター再起動後も保持される) - ロケールを日本語に戻す:
xcrun simctl spawn <ID> defaults write -g AppleLanguages "(ja-JP)"+defaults write -g AppleLocale "ja_JP"を実行して再起動