price changes of existing products need --allow-price-changes (play products, play/apple subscriptions, prices import): --yes and flow run --apply --yes confirm creates, first prices and other updates only; without the flag the run writes the rest, names each held change and exits 3 (declined), dry runs mark them owner, flows refuse the flag; lib/price-gate.ts, tests/price-gate.test.ts. CLI wording: console fill leaves what it cannot open or fill to the calling agent's browser tool (console plan / verify) instead of 'yourself'; other 'by hand' output points at the config; do-it-dont-ask test scans cli/ output

This commit is contained in:
CRTkafa 2026-10-12 09:38:56 +08:00
parent b5b8f2da9d
commit e01a27d7b7
33 changed files with 414 additions and 117 deletions

View file

@ -156,10 +156,10 @@ export const TOOLS: ToolDef[] = [
description: 'Replace icon, feature graphic and phone screenshots per Play language from the renders folder (or an A/B variant folder); optional 7" / 10" tablet, TV and Wear sets only when rendered (play.tablets). A missing optional set never deletes what Play has (--prune is an owner terminal run). Slow (minutes): prefer the terminal with a log for many languages.',
props: { only, variant }, args: i => [...opt('only', i.only), ...opt('variant', i.variant)] },
{ name: 'play_products', title: 'Sync Play one-time products', command: ['play', 'products'], write: true, network: true, idempotent: true,
description: 'Create one-time products with regional prices and activate them; update listing text of existing ones. dry_run shows per product what would change. Price, region or activation changes of existing products are the owner\'s (terminal confirmation): here they are skipped with a warning.',
description: 'Create one-time products with regional prices and activate them; update listing text of existing ones. dry_run shows per product what would change. Price or region changes of existing products are the owner\'s (a terminal run with --allow-price-changes): here everything else is written and each held change is named ("price change on <id> ... needs the owner", exit 3); activating an existing product needs a terminal confirmation.',
props: { only }, args: i => opt('only', i.only) },
{ name: 'play_subscriptions', title: 'Sync Play subscriptions', command: ['play', 'subscriptions'], write: true, network: true, idempotent: true,
description: 'Auto-renewable subscriptions on Google Play from the config: listings per language (title, description, benefits), one auto-renewing base plan with regional prices (convertRegionPrices + overrides + optional prices CSV), activation, and the introductory offer for new subscribers. dry_run prints the plan. Without a terminal it creates only what is new; price changes of existing base plans are an owner terminal run.',
description: 'Auto-renewable subscriptions on Google Play from the config: listings per language (title, description, benefits), one auto-renewing base plan with regional prices (convertRegionPrices + overrides + optional prices CSV), activation, and the introductory offer for new subscribers. dry_run prints the plan. Without a terminal it writes what is new; price changes of existing base plans are the owner\'s (a terminal run with --allow-price-changes): each is named ("price change on <id> ... needs the owner", exit 3).',
props: { only, csv: { type: 'string', description: 'Prices CSV with rows for subscription ids' } },
args: i => [...opt('only', i.only), ...opt('csv', i.csv)] },
{ name: 'play_data_safety', title: 'Push Play Data safety', command: ['play', 'data-safety'], write: true, destructive: true, network: true, idempotent: true,
@ -176,7 +176,7 @@ export const TOOLS: ToolDef[] = [
description: 'Create missing in-app purchases, localizations, price schedules and availability. Never submits.',
props: { only }, args: i => opt('only', i.only) },
{ name: 'apple_subscriptions', title: 'Sync App Store subscriptions', command: ['apple', 'subscriptions'], write: true, network: true, idempotent: true,
description: 'Auto-renewable subscriptions from the config: subscription groups and display names, subscriptions (period, level), localizations, availability, prices (USA price point + equalizations + overrides, optional prices CSV), introductory offers, review screenshot. dry_run prints the plan. Without a terminal it creates only what is new; price changes of existing subscriptions are an owner terminal run. Never submits.',
description: 'Auto-renewable subscriptions from the config: subscription groups and display names, subscriptions (period, level), localizations, availability, prices (USA price point + equalizations + overrides, optional prices CSV), introductory offers, review screenshot. dry_run prints the plan. Without a terminal it writes what is new; price changes of existing subscriptions are the owner\'s (a terminal run with --allow-price-changes): each is named ("price change on <id> ... needs the owner", exit 3). Never submits.',
props: { only, csv: { type: 'string', description: 'Prices CSV (product, store, region, currency, price, start_date) with rows for subscription ids' } },
args: i => [...opt('only', i.only), ...opt('csv', i.csv)] },
{ name: 'apple_iap_review', title: 'IAP review screenshots', command: ['apple', 'iap-review'], write: true, destructive: true, network: true, idempotent: true,