console: agent-first mode (console plan / console verify), verified App Privacy and Play Create app facts

- `storebound console plan <form> [--json] [--lookup]`: read-only plan for an AI agent that drives the browser
  itself: start URL (deep links), ordered steps, answer sheet with the console's exact labels (certain / ask owner,
  curly quotes noted), never-press list, verified UI facts, driving guidance (in-page async loop + window.__log),
  verify instructions. All six forms.
- `storebound console verify <form> [--from-text <file|->]`: App Privacy per-type summaries from page text, Play
  Create app from input states, content rating / target audience summaries, App Store record and age rating from
  the API; exit 1 on a mismatch.
- MCP: console_plan, console_verify (read-only); console fill stays off MCP.
- App Privacy (verified 2026-10-12): two information steps, unlabeled purpose checkboxes (nearest parent text),
  "Definitions and Examples" never pressed; fixture and engine follow.
- Play Create app (verified 2026-10-12): /developers/<id>/create-new-app, App package name + read-only Check
  availability, material-radio inner [role=radio] click, app dashboard URL and play.appId, service account
  "Add app" as an owner step.
- console-autofill skill rewritten agent-first; agents-core rule 10; README; pitfalls 12, 18 (confirmed sign-out),
  19; CHANGELOG; play-first-release.
This commit is contained in:
CRTkafa 2026-10-12 08:22:03 +08:00
parent a9261a8052
commit c9a7f095c4
34 changed files with 1430 additions and 113 deletions

View file

@ -390,6 +390,15 @@ export const TOOLS: ToolDef[] = [
{ name: 'apple_events_upload', title: 'Upload in-app event images', command: ['apple', 'events', 'upload'], write: true, destructive: true, network: true, idempotent: true,
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'] } },
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'] },
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,
description: 'Read-only: per territory whether the app is available, its release date, pre-order on / off and its content status. Enabling or ending a pre-order is an owner-only terminal command.', args: () => ['--json'] },
];