store art from the live stores: storebound art pull (App Store screenshot sets and previews per locale and display type from imageAsset.templateUrl at the original size, the App Store icon from the newest build or the public artwork; per Play language icon, feature graphic, phone / 7" / 10" / TV / Wear screenshots as the =s0 originals checked against Play's sha256) into store/renders with pulled.json (sha256, store, URL host, store checksum); upsert (a re-run changes nothing, differing local files kept unless --force, the upload's file of a slot compared: Play .jpg, App Store .png, the App Store icon as a picture); onboard runs it; apple screenshots / previews and play images see unchanged pulled files as the store's own; check: render sources are notes with pulled art; local renders check: pulled files pass, store-empty sets not demanded; art live / thumb / replace; desktop Store art tab: live thumbnails per store, language and set (same / differs / not pulled), Pull from stores, store-only apps read-only, Replace with a file (image_pick, art.replace) in the lightbox and the art editor; boot check store art case; tests/art-pull.test.ts; console parity 76 rows (57 complete, 19 with the reason); store-screenshots skill (pull first for live apps), pitfall 59
This commit is contained in:
parent
49a73c90e4
commit
00be838b76
40 changed files with 1669 additions and 58 deletions
|
|
@ -333,8 +333,11 @@ export const TOOLS: ToolDef[] = [
|
|||
description: 'Store titles and descriptions (Play: benefits) of in-app purchases and subscriptions vs the config listings, as a proposal diff. storebound.config.ts is never rewritten; with dry_run false the proposal is saved to .storebound/pull/catalog.json.',
|
||||
props: { store: { type: 'string', enum: ['apple', 'play'] } }, args: i => [...opt('store', i.store), '--json', ...(i.dry_run === false ? ['--write'] : [])] },
|
||||
{ name: 'onboard', title: 'Onboard a live app', command: ['onboard'], write: true, network: true, idempotent: true,
|
||||
description: 'For an app that is already live: reads the live products and subscriptions (USD / base prices), contact e-mail, website, privacy and support URLs, the App Review contact and demo account, sign-in for review and the account deletion page from the stores, the code and the app\'s site, and lists the owner questions nothing proves. Read-only on the stores, never changes store prices. dry_run shows the plan; with dry_run false storebound.config.ts and .storebound/credentials.json are updated (personal data masked, never printed).',
|
||||
description: 'For an app that is already live: reads the live products and subscriptions (USD / base prices), contact e-mail, website, privacy and support URLs, the App Review contact and demo account, sign-in for review and the account deletion page from the stores, the code and the app\'s site, plus the live store art (art_pull: screenshots, previews, icon, feature graphic into store/renders), and lists the owner questions nothing proves. Read-only on the stores, never changes store prices. dry_run shows the plan; with dry_run false storebound.config.ts, .storebound/credentials.json and the store art files are updated (personal data masked, never printed; differing local art is kept).',
|
||||
props: { store: { type: 'string', enum: ['apple', 'play'] } }, args: i => [...opt('store', i.store), '--json', ...(i.dry_run === false ? ['--write'] : [])] },
|
||||
{ name: 'art_pull', title: 'Pull the live store art', command: ['art', 'pull'], write: true, network: true, idempotent: true,
|
||||
description: 'For an app that is already live: every App Store screenshot set and app preview per locale and display type, the App Store icon, and per Play language the icon, feature graphic and phone / tablet / TV / Wear screenshots, downloaded at their original size into the store art layout (store/renders/<lang>/<size>/NN.png, feature/1024x500, the icons) with store/renders/pulled.json (sha256, store, URL host, when), so check / validate treat them like rendered art and play_images / apple_screenshots see them as the store\'s own (nothing uploaded). Read-only on the stores. An upsert: a re-run changes nothing; a local file that differs from the store (your own render) is kept and listed (only the owner\'s terminal run with --force replaces it). dry_run shows the plan; with dry_run false the files are written (local files only).',
|
||||
props: { store: { type: 'string', enum: ['apple', 'play'] } }, args: i => [...opt('store', i.store), ...(i.dry_run === false ? ['--write'] : [])] },
|
||||
{ name: 'whats_new_languages', title: 'Release notes per language', command: ['whats-new'], write: true, network: false, idempotent: true,
|
||||
description: 'Draft release notes from git into one file per language (store/whats-new/<language id>.md): the first language gets the draft, the others status=translate files for you to translate (keep the header line, set status=translated). Then whats_new_check and whats_new_apply. Local files only.',
|
||||
props: { languages: { type: 'string', pattern: '^[A-Za-z0-9_-]+(,[A-Za-z0-9_-]+)*$', description: 'Comma-separated language ids or store codes, source language first' }, since: { type: 'string', description: 'Git tag or ref (default: latest tag)' } },
|
||||
|
|
@ -426,7 +429,7 @@ export const FORBIDDEN_ARGS = ['--write', '--yes', '--manual-release', '--cancel
|
|||
* `scan --write` (compliance answers into the config) stays unreachable: scan is not in this list.
|
||||
*/
|
||||
export const LOCAL_WRITE_TOOLS: Record<string, readonly string[]> = {
|
||||
apple_listing_pull: ['--write'], play_listing_pull: ['--write'], catalog_pull: ['--write'], onboard: ['--write'],
|
||||
apple_listing_pull: ['--write'], play_listing_pull: ['--write'], catalog_pull: ['--write'], onboard: ['--write'], art_pull: ['--write'],
|
||||
};
|
||||
|
||||
export function inputSchema(t: ToolDef): Record<string, unknown> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue