Play console steps without an API as agent plans: play-store-settings (App category; play listing cannot set it), play-app-content (every card in order, one owner batch) and its cards (privacy policy, ads, sign in details, advertising ID, government, financial, health), play-production-countries and play-production-release; IARC plan with the Terms of Use agreement, follow-ups (console.contentRating.details, products[].randomRewards, social) and the Summary's final Save; config play.category / countries / managedPublishing, console.appContent; check, validate, play status and play release reminders; inPageLoop helper and material checkbox clicks; App Privacy published signal; first IAPs via apple iap-submit --with-version. Pitfalls 27, 28

This commit is contained in:
CRTkafa 2026-10-12 10:16:34 +08:00
parent dbd9f2973c
commit b7bfe89151
37 changed files with 1624 additions and 121 deletions

View file

@ -32,6 +32,11 @@ const APP_NAMES = '^[^,\\x00-\\x1f]{1,120}(,[^,\\x00-\\x1f]{1,120}){0,99}$';
const opt = (flag: string, v: unknown): string[] => (v === undefined || v === null || v === '' ? [] : [`--${flag}`, String(v)]);
const flag = (name: string, v: unknown): string[] => (v === true ? [`--${name}`] : []);
/** Every form `console plan` / `console verify` know (cli/lib/console-answers.ts PLAN_FORM_IDS; a test keeps them equal). */
export const CONSOLE_PLAN_FORMS = ['apple-app-record', 'apple-age-rating', 'apple-app-privacy', 'play-app-record', 'play-content-rating', 'play-target-audience',
'play-store-settings', 'play-app-content', 'play-privacy-policy', 'play-ads', 'play-sign-in-details', 'play-advertising-id', 'play-government-apps',
'play-financial-features', 'play-health-apps', 'play-production-countries', 'play-production-release'];
export const TOOLS: ToolDef[] = [
{ name: 'check', title: 'Offline config check', command: ['check'], write: false, network: false,
description: 'Validate storebound.config.ts, both listing files, screenshot copy, Data safety answers, product texts and referenced files. Offline.' },
@ -391,12 +396,12 @@ export const TOOLS: ToolDef[] = [
description: 'Upload the event card (16:9, 1920x1080 to 3840x2160) and details page (9:16) images of one draft in-app event per locale, size-checked first.',
props: { name: { type: 'string', description: 'Reference name from apple.events' } }, required: ['name'], args: i => opt('name', i.name) },
{ name: 'console_plan', title: 'Console form plan (agent-first)', command: ['console', 'plan'], write: false, network: false,
description: 'Read-only plan for filling a console form that has no API with YOUR OWN browser tool (Claude in Chrome, a built-in browser, Playwright): start URL (deep link when the ids are known), ordered steps (what to click by visible text, what to answer), the answer sheet from the config (each answer certain or ask-owner, with the console\'s exact labels, curly quotes noted), the buttons never to press (Publish, Submit, Create, agreements, help panels), known UI facts per form, how to drive long flows (an in-page async loop writing window.__log) and how to verify. Drive the page yourself, stop before the final button and tell the owner what to press, then call console_verify.',
props: { form: { type: 'string', enum: ['apple-app-record', 'apple-age-rating', 'apple-app-privacy', 'play-app-record', 'play-content-rating', 'play-target-audience'] } },
description: 'Read-only plan for filling a console form that has no API with YOUR OWN browser tool (Claude in Chrome, a built-in browser, Playwright): start URL (deep link when the ids are known), ordered steps (what to click by visible text, what to answer), the answer sheet from the config (each answer certain or ask-owner, with the console\'s exact labels, curly quotes noted), the buttons never to press (Publish, Submit, Create, agreements, help panels), known UI facts per form (Play: material radios and checkboxes take a JS click on the inner [role=radio] / [role=checkbox]), a ready-made in-page helper (inPageLoop: one evaluate call times out around 45 s, so long flows run in the page and you poll window.__log) and how to verify. Forms: the App Store and Play forms of `console fill`, plus agent-only Play pages: play-store-settings (the App category, which the Play API cannot set), play-app-content (every App content card in order with its page and one batch of owner questions) and its cards play-privacy-policy, play-ads, play-sign-in-details, play-advertising-id, play-government-apps, play-financial-features, play-health-apps; and the first production release: play-production-countries (the API cannot set them) and play-production-release (its final Send changes for review is the owner\'s). Drive the page yourself, stop before the final button and tell the owner what to press, then call console_verify.',
props: { form: { type: 'string', enum: CONSOLE_PLAN_FORMS } },
required: ['form'], args: i => [String(i.form), '--json'] },
{ name: 'console_verify', title: 'Verify a console form', command: ['console', 'verify'], write: false, network: true,
description: 'Read-only check of a filled console form against the config. Pass the page text you read (App Privacy: the App Privacy page\'s innerText, whose Data Types section shows per type "Used for …", linked and tracking; Play Create app: the JSON of the plan\'s capture snippet; Play content rating / target audience: the summary page text). apple-app-record and apple-age-rating without text read the App Store Connect API. Returns a per-item match / mismatch table; exit code 1 on a mismatch.',
props: { form: { type: 'string', enum: ['apple-app-record', 'apple-age-rating', 'apple-app-privacy', 'play-app-record', 'play-content-rating', 'play-target-audience'] },
description: 'Read-only check of a filled console form against the config. Pass the page text you read (App Privacy: the App Privacy page\'s innerText, whose Data Types section shows per type "Used for …", linked and tracking; Play Create app: the JSON of the plan\'s capture snippet; Play content rating / target audience: the summary page text; play-app-content: the JSON of the plan\'s capture snippet; Play store settings and the other App content cards: the page text after Save). apple-app-record and apple-age-rating without text read the App Store Connect API. Returns a per-item match / mismatch table; exit code 1 on a mismatch.',
props: { form: { type: 'string', enum: CONSOLE_PLAN_FORMS },
text: { type: 'string', description: 'The page text (or the capture JSON) of the finished form' } },
required: ['form'], args: i => [String(i.form), ...(typeof i.text === 'string' && i.text ? [`--text=${i.text}`] : []), '--json'] },
{ name: 'apple_preorder_status', title: 'App Store pre-order status', command: ['apple', 'preorder', 'status'], write: false, network: true,