storebound/cli/lib/desktop-coverage.ts

142 lines
14 KiB
TypeScript

// Where every CLI command (cli/commands.ts COMMANDS + PLAIN) lives in the desktop app. One source for
// tools/gen-desktop-coverage.ts (docs/desktop-coverage.md) and the guard test (tests/desktop-coverage.test.ts): a
// command without an entry, or with a method the window never calls, fails the test.
//
// methods: serve.ts methods (`play.listing`, `owner.play_rollout`) or host commands of src-tauri (`host:accounts_list`).
// owner: the owner-only parts of the command; the More tools tab lists them as terminal steps (OWNER_STEPS).
export type Coverage =
| { where: string; methods: string[]; owner?: string }
| { not: string };
/** The More tools tab (apps/desktop/src/screens/tabs/Tools.tsx): one typed form per method, built from its schema
* (`system.methods`). Reads run; writes go through the dry run, the native dialog and the confirm token. */
export const TOOLBOX: { id: string; methods: string[] }[] = [
{ id: 'build', methods: ['play.build', 'play.upload', 'play.share', 'play.next_version_code', 'play.app_id', 'apple.build', 'apple.upload', 'apple.next_build',
'apple.signing_status', 'apple.signing_ensure', 'apple.bundle', 'apple.testflight_info', 'apple.testflight_wait'] },
{ id: 'adhoc', methods: ['apple.adhoc_devices', 'apple.adhoc_register', 'apple.adhoc_options', 'apple.adhoc_export'] },
{ id: 'store', methods: ['apple.iap_review', 'apple.iap_review_plan', 'apple.creative_assets', 'apple.creative_assets_verify', 'apple.cpp_list', 'apple.cpp_create',
'apple.cpp_upload', 'apple.events_list', 'apple.events_create', 'apple.events_upload', 'apple.preorder_status', 'catalog.pull', 'onboard', 'revenuecat.diff', 'prices.ppp'] },
{ id: 'text', methods: ['whats.new', 'whats.new_languages', 'whats.new_check', 'whats.new_apply', 'listing.translate', 'listing.check', 'check.aso', 'aso.rank',
'aso.competitors', 'aso.suggest'] },
{ id: 'capture', methods: ['shots.capture', 'shots.record', 'shots.check', 'shots.fonts', 'shots.jpeg'] },
{ id: 'quality', methods: ['health.report', 'triage', 'originality', 'privacy.manifest', 'ads.scan', 'web.init', 'web.check'] },
{ id: 'ads', methods: ['ads.apple_status', 'ads.apple_campaigns', 'ads.apple_report'] },
{ id: 'flows', methods: ['flow.list', 'flow.run', 'agent.install'] },
];
/** Owner-only steps without a window button: the More tools tab shows each with its terminal command to copy. */
export const OWNER_STEPS: { id: string; command: string }[] = [
{ id: 'offer_codes', command: 'storebound apple offer-codes' },
{ id: 'win_back', command: 'storebound apple win-back' },
{ id: 'promoted', command: 'storebound apple promoted --enable' },
{ id: 'preorder', command: 'storebound apple preorder enable --release-date YYYY-MM-DD' },
{ id: 'cpp_submit', command: 'storebound apple cpp submit --name <page>' },
{ id: 'events_submit', command: 'storebound apple events submit --name <event>' },
{ id: 'tf_expire', command: 'storebound apple testflight expire --keep 5' },
{ id: 'ads_change', command: 'storebound ads apple bid --campaign <id> --keyword <id> --bid 1.20' },
{ id: 'rc_sync', command: 'storebound revenuecat sync' },
{ id: 'shots_login', command: 'storebound shots login' },
];
const T = 'More tools';
export const DESKTOP_COVERAGE: Record<string, Coverage> = {
// PLAIN
'init': { where: 'App folders: Start an app folder', methods: ['host:project_init'] },
'import': { where: 'App folders / first-run guide: Import from fastlane', methods: ['host:project_import_fastlane'] },
'install': { where: `${T}: Install for an AI tool`, methods: ['agent.install'] },
'mcp': { not: 'the stdio server for AI tools; the window itself is the GUI over the same commands' },
'settings': { not: 'per-machine switch for AI agents (bypass mode); in the window the owner presses owner actions in a native dialog anyway' },
'serve': { not: 'the JSON-RPC sidecar the window runs on; nothing to click' },
'apps': { where: 'Accounts (store apps per account, key check) and App folders (list, add, remove)', methods: ['host:store_apps_refresh', 'host:account_check', 'host:projects_list', 'host:project_add', 'host:project_remove'] },
'desktop': { not: 'opens or installs this window from a terminal' },
'accounts': { where: 'Accounts screen (profiles shared with the CLI)', methods: ['host:accounts_list', 'host:account_add_play', 'host:account_add_apple', 'host:account_update'] },
'doctor': { where: 'Dependencies screen', methods: ['system.tools', 'host:tools_info'] },
'scan': { where: 'Checks tab: Scan, Fix', methods: ['scan', 'scan.write'] },
'api': { not: 'raw API calls by operation id: every task has its own screen, and raw writes stay a terminal step the owner types' },
'privacy-manifest': { where: `${T}: Quality`, methods: ['privacy.manifest'] },
'ws': { where: 'Portfolio, studios and Settings (the workspace of this machine)', methods: ['host:workspace_get', 'host:portfolio_status'] },
'release': { where: 'Portfolio release trains and the Releases tab', methods: ['host:portfolio_status', 'apple.status', 'play.status'] },
'flow': { where: `${T}: Workflows (plans; owner steps never run)`, methods: ['flow.list', 'flow.run'] },
'ads': { where: `${T}: Quality (AdAttributionKit / SKAdNetwork scan)`, methods: ['ads.scan'] },
// COMMANDS
'edit': { where: 'Editors on every tab (Save edits)', methods: ['project.editable', 'project.edit'] },
'inspect': { where: 'App card, App info, Listings, Store art (offline reads)', methods: ['host:portfolio_status', 'project.declarations', 'project.listings', 'project.listing_text', 'project.icon', 'project.render'] },
'check': { where: 'Checks tab', methods: ['check'] },
'validate': { where: 'Checks tab', methods: ['validate'] },
'report': { where: 'Checks tab: readiness report', methods: ['report'] },
'analytics': { where: 'Growth tab: chart, snapshot, setup', methods: ['analytics.compare', 'analytics.snapshot', 'analytics.setup'] },
'health': { where: 'Health tab; weekly report in More tools', methods: ['health', 'health.issue', 'health.report'] },
'art': { where: 'Store art tab: live art, pull, replace', methods: ['art.live', 'art.thumb', 'art.pull', 'art.replace'] },
'onboard': { where: `${T}: Store features`, methods: ['onboard'] },
'catalog': { where: 'Catalog tab (parity); pull in More tools', methods: ['catalog.diff', 'catalog.pull'] },
'reports': { where: 'Growth tab: sales and finance reports', methods: ['reports'] },
'triage': { where: `${T}: Quality`, methods: ['triage'] },
'aso': { where: 'Growth tab: ASO audit; rank, competitors, suggest in More tools', methods: ['aso.audit', 'aso.rank', 'aso.competitors', 'aso.suggest'] },
'prices': { where: 'Prices tab (export, compare, apply = owner action); PPP sheet in More tools', methods: ['prices.current', 'prices.export', 'prices.diff', 'owner.prices_import', 'prices.ppp'] },
'ads apple': { where: `${T}: Apple Ads (status, campaigns, report)`, methods: ['ads.apple_status', 'ads.apple_campaigns', 'ads.apple_report'], owner: 'bid, budget, pause' },
'web': { where: `${T}: Quality (init, check)`, methods: ['web.init', 'web.check'] },
'revenuecat': { where: `${T}: Store features (diff)`, methods: ['revenuecat.diff'], owner: 'sync' },
'console plan': { where: 'App info: Console steps without an API', methods: ['console.plan'] },
'console verify': { where: 'App info: Console steps, Check', methods: ['console.verify'] },
'console fill': { where: 'App info: Fill in console', methods: ['console.fill'] },
'reviews': { where: 'Reviews tab (list, draft, reply, approve; Send = owner action)', methods: ['reviews.list', 'reviews.draft', 'reviews.drafts', 'reviews.reply', 'reviews.approve', 'owner.reply_send'] },
'originality': { where: `${T}: Quality`, methods: ['originality'] },
'listing': { where: 'Listings tab (live texts, store edits); translate and check in More tools', methods: ['listing.live', 'listing.set', 'listing.translate', 'listing.check'] },
'whats-new': { where: `${T}: Text and ASO`, methods: ['whats.new', 'whats.new_languages', 'whats.new_check', 'whats.new_apply'] },
'play products': { where: 'Catalog tab', methods: ['play.products', 'owner.prices_play_products'] },
'play subscriptions': { where: 'Catalog tab', methods: ['play.subscriptions', 'owner.prices_play_subscriptions'] },
'play listing': { where: 'Listings tab (push, pull)', methods: ['play.listing', 'play.listing_pull'] },
'play images': { where: 'Listings tab: Play graphics', methods: ['play.images'] },
'play data-safety': { where: 'App info tab: Data safety upload', methods: ['play.data_safety'] },
'play games': { where: 'App info tab: Game services card (Sync Play Games, Setup plan)', methods: ['play.games', 'games.status'] },
'play release': { where: 'Releases tab: Send to production (owner action); testing tracks via play upload in More tools', methods: ['owner.play_production', 'play.upload'] },
'play build': { where: `${T}: Build and upload`, methods: ['play.build'] },
'play upload': { where: `${T}: Build and upload`, methods: ['play.upload'] },
'play status': { where: 'Releases tab: Google Play card', methods: ['play.status'] },
'play rollout': { where: 'Releases tab: rollout (owner action)', methods: ['owner.play_rollout'] },
'play share': { where: `${T}: Build and upload`, methods: ['play.share'] },
'play app-id': { where: `${T}: Build and upload`, methods: ['play.app_id'] },
'play next-version-code': { where: `${T}: Build and upload`, methods: ['play.next_version_code'] },
'apple bundle': { where: `${T}: Build and upload`, methods: ['apple.bundle'] },
'apple iap': { where: 'Catalog tab', methods: ['apple.iap'] },
'apple subscriptions': { where: 'Catalog tab', methods: ['apple.subscriptions', 'owner.prices_apple_subscriptions'] },
'apple iap-review': { where: `${T}: Store features`, methods: ['apple.iap_review'] },
'apple iap-submit': { where: 'Releases tab: Submit in-app purchases (owner action); plan in More tools', methods: ['owner.apple_iap_submit', 'apple.iap_review_plan'] },
'apple submit': { where: 'Releases tab: Submit for review (owner action)', methods: ['owner.apple_submit'] },
'apple resubmit': { where: 'Releases tab: Resubmit (owner action)', methods: ['owner.apple_resubmit'] },
'apple offer-codes': { where: `${T}: owner steps (terminal command)`, methods: [], owner: 'creating campaigns and codes' },
'apple win-back': { where: `${T}: owner steps (terminal command)`, methods: [], owner: 'win-back offers go live on their start date' },
'apple promoted': { where: `${T}: owner steps (terminal command)`, methods: [], owner: 'promoted purchases on the product page' },
'apple preorder': { where: `${T}: Store features (status); enable / end as owner steps`, methods: ['apple.preorder_status'], owner: 'enable, end' },
'apple cpp': { where: `${T}: Store features (list, create, upload)`, methods: ['apple.cpp_list', 'apple.cpp_create', 'apple.cpp_upload'], owner: 'submit, visible' },
'apple events': { where: `${T}: Store features (list, create, upload)`, methods: ['apple.events_list', 'apple.events_create', 'apple.events_upload'], owner: 'submit' },
'apple listing': { where: 'Listings tab (push, pull)', methods: ['apple.listing', 'apple.listing_pull'] },
'apple screenshots': { where: 'Listings tab: App Store screenshots', methods: ['apple.screenshots'] },
'apple appinfo': { where: 'App info tab: Push', methods: ['apple.appinfo'] },
'apple review-details': { where: 'App info tab: App Review details', methods: ['apple.review_details'] },
'apple status': { where: 'Releases tab: Send for review, App Store card', methods: ['apple.status'] },
'apple creative-assets': { where: `${T}: Store features`, methods: ['apple.creative_assets', 'apple.creative_assets_verify'] },
'apple previews': { where: 'Listings tab: App Store previews', methods: ['apple.previews'] },
'apple release': { where: 'Releases tab: phased release (owner action)', methods: ['owner.ios_phased'] },
'apple signing': { where: `${T}: Build and upload (status, ensure)`, methods: ['apple.signing_status', 'apple.signing_ensure'] },
'apple build': { where: `${T}: Build and upload`, methods: ['apple.build'] },
'apple upload': { where: `${T}: Build and upload`, methods: ['apple.upload'] },
'apple adhoc': { where: `${T}: Ad-hoc devices (devices, register, options, export)`, methods: ['apple.adhoc_devices', 'apple.adhoc_register', 'apple.adhoc_options', 'apple.adhoc_export'] },
'apple next-build': { where: `${T}: Build and upload`, methods: ['apple.next_build'] },
'apple encryption': { where: 'App info tab: export compliance', methods: ['apple.encryption'] },
'apple game-center': { where: 'App info tab: Game services card (Sync Game Center)', methods: ['apple.game_center', 'games.status'] },
'games status': { where: 'App info tab: Game services card', methods: ['games.status'] },
'apple ppo': { where: 'Growth tab: PPO tests (start / stop = owner actions)', methods: ['apple.ppo_status', 'apple.ppo_create', 'apple.ppo_upload', 'owner.ppo_start', 'owner.ppo_stop'] },
'apple testflight': { where: 'TestFlight tab (status, groups, What to Test, distribute, testers = owner action); info and wait in More tools', methods: ['apple.testflight_status', 'apple.testflight_groups', 'apple.testflight_what_to_test', 'apple.testflight_distribute', 'owner.testflight_testers', 'apple.testflight_info', 'apple.testflight_wait'], owner: 'expire' },
'icons': { where: 'Store art tab: icons', methods: ['icons'] },
'shots capture': { where: `${T}: Captures`, methods: ['shots.capture'] },
'shots login': { where: `${T}: owner steps (terminal command)`, methods: [], owner: 'signing in to a demo account by hand in a visible browser' },
'shots fonts': { where: `${T}: Captures`, methods: ['shots.fonts'] },
'shots render': { where: 'Store art tab: Render', methods: ['shots.render'] },
'shots jpeg': { where: `${T}: Captures`, methods: ['shots.jpeg'] },
'shots check': { where: `${T}: Captures`, methods: ['shots.check'] },
'shots record': { where: `${T}: Captures`, methods: ['shots.record'] },
'shots video': { where: 'Store art tab: previews', methods: ['shots.video'] },
'shots gallery': { where: 'Store art tab: gallery, review page', methods: ['shots.gallery', 'project.renders'] },
};