template compliance answers never reach a store: init writes unanswered (dataSafety, appPrivacy, reviewNotes, ageRating, accounts, reviewAccess), older configs are recognised by the template values; check / validate / scan block, play data-safety (also --dry), console plan / fill, apple review-details and appinfo refuse. onboard --declarations replaces them on a live app: name and copyright from the stores (a copyright with a private term is left out), the rows the code proves (scan proposal, sign-up methods from auth code and login SDKs), the rest as one owner question list. play data-safety --dry prints the answers that change (old -> new, account and deletion first) against the last uploaded CSV; pitfall 60; tests

This commit is contained in:
CRTkafa 2026-10-14 11:36:30 +08:00
parent 34c2fa22e5
commit 7219ded3e8
27 changed files with 659 additions and 19 deletions

View file

@ -27,6 +27,7 @@
// Sources (checked October 2026): see cli/lib/console-answers.ts; Playwright launchPersistentContext, getByRole,
// getByLabel: https://playwright.dev/docs/api/class-browsertype#browser-type-launch-persistent-context ,
// https://playwright.dev/docs/locators
import { FORM_AREAS, refuseTemplate } from '../lib/template-answers';
import { homedir } from 'node:os';
import { join } from 'node:path';
import type { Ctx } from '../lib/ctx';
@ -905,6 +906,7 @@ export async function run(ctx: Ctx): Promise<void> {
return;
}
if (!isForm(form)) throw new Error(`console fill: unknown form "${form}" (one of ${FORM_IDS.join(', ')})`);
refuseTemplate(config, FORM_AREAS[form] ?? [], `console fill ${form}`);
const meta = formMeta(form, config);
const store = args.get('store');
if (store && store !== 'apple' && store !== 'play') throw new Error('--store: apple | play');

View file

@ -7,6 +7,7 @@
// apple.appId / play.developerId / play.appId, the ids cached by earlier runs (.storebound/console-app-ids.json,
// ~/.storebound/console-accounts.json) and the workspace's account ids; --lookup also asks the App Store Connect API
// for the app id by bundle id (a GET; needs the API key). Pure logic in cli/lib/console-plan.ts. MCP: console_plan.
import { FORM_AREAS, refuseTemplate } from '../lib/template-answers';
import type { Ctx } from '../lib/ctx';
import { formMeta, isForm, isPlanForm, PLAN_FORM_IDS } from '../lib/console-answers';
import { reviewDemoAccount } from '../lib/credentials';
@ -28,6 +29,7 @@ export async function run(ctx: Ctx): Promise<void> {
return;
}
if (!isPlanForm(form)) throw new Error(`console plan: unknown form "${form}" (one of ${PLAN_FORM_IDS.join(', ')})`);
refuseTemplate(config, FORM_AREAS[form] ?? [], `console plan ${form}`);
const { withAccountIds, readAccounts } = await import('./accounts');
const cfg = withAccountIds(config);
const pkg = cfg.play?.packageName;