desktop editors: edit in place what App Store Connect and Play Console let the owner edit (listings per language for both stores with live counters and the check / scan rules, store details, App info, age rating, App Review, Play store settings, Data safety and App Privacy answers, promotion blocks, catalog names / prices / offers, TestFlight information, scene order); storebound edit (project.edit) saves into the config by path keeping comments and formatting, the listing files and the review contact, dry run with the diff and the checks first; Apply shows each store's dry run in the window; unsaved edits survive tab switches with undo / redo; tests/edit.test.ts, apps/desktop/tests/edits.test.ts, boot check editor case

This commit is contained in:
CRTkafa 2026-10-14 00:35:29 +08:00
parent 714352ec18
commit 3cea2af4e1
37 changed files with 3020 additions and 54 deletions

View file

@ -1545,4 +1545,182 @@ export const en = {
'deps.sdkFrom': 'Found through',
'deps.sdkNone': 'Not found. play build needs it (install Android Studio, or set ANDROID_HOME). Checked:',
'ai.dsFrom': 'from {source}',
'ed.countAria': '{n} of {limit} characters',
'ed.unsavedField': 'Unsaved change',
'ed.was': 'Saved:',
'ed.empty': '(empty)',
'ed.removed': '(removed)',
'ed.reset': 'Reset',
'ed.notSet': 'Not set',
'ed.none': 'none',
'ed.notNumber': 'Not a number',
'ed.notJson': 'Not valid JSON: {error}',
'ed.noGit': 'Not a git folder',
'ed.gitClean': 'No uncommitted changes in these files',
'ed.gitDirty': 'Uncommitted in git: {files}. storebound never commits.',
'ed.also': 'the same section also serves {codes}',
'ed.newFile': 'new file',
'ed.masked': 'Personal data: not shown.',
'ed.unsaved': '{count} unsaved changes',
'ed.unsaved_one': '1 unsaved change',
'ed.noChanges': 'No unsaved changes',
'ed.undo': 'Undo',
'ed.redo': 'Redo',
'ed.discard': 'Discard',
'ed.review': 'Review and save',
'ed.close': 'Close',
'ed.fixFirst': 'Fix the errors first',
'ed.save': 'Save to the app folder',
'ed.saved': 'Saved to the app folder',
'ed.nothingToApply': 'Nothing to change on the store.',
'ed.applyNow': 'Apply to the store',
'ed.saveFirst': 'Save your edits first: the store gets what the files hold.',
'ed.statusDraft': 'Machine draft, not reviewed',
'ed.statusTranslate': 'Not translated yet',
'ed.alsoServes': 'also {codes}',
'ed.newSection': '{lang} has no section in the listing file yet. Fill in the required fields; saving adds the section.',
'ed.keywordsHint': 'Comma separated, no spaces after commas; do not repeat words from the name or subtitle.',
'ed.whatsNewApple': 'Not allowed on the first version.',
'ed.nameHint': 'Empty: the app name from the config.',
'ed.supportUrl': 'Support URL',
'ed.marketingUrl': 'Marketing URL',
'ed.privacyUrl': 'Privacy policy URL',
'ed.termsUrl': 'Terms of Use URL',
'ed.termsHint': 'Needed with subscriptions (Apple 3.1.2).',
'ed.website': 'Website',
'ed.websiteHint': 'Google Play: the domain that serves app-ads.txt.',
'ed.contactEmail': 'Contact email',
'ed.copyright': 'Copyright',
'ed.video': 'Promo video (YouTube URL)',
'ed.videoHint': 'Public or unlisted, ads off, embeddable. Play takes no video upload.',
'ed.listingTitle': 'Edit the listing',
'ed.listingSub': 'Per language, both stores side by side. Counters use the store limits; the checks of check and scan run as you type.',
'ed.pullPlay': 'Pull from Google Play',
'ed.pullApple': 'Pull from the App Store',
'ed.pulled': 'The listing file now matches the store',
'ed.pullHint': 'Reads the live texts and shows the diff before anything in the files changes.',
'ed.pullDirty': 'You have unsaved edits: they stay pending on top of the pulled text.',
'ed.pullNote': 'Pulling rewrites the listing files after a diff; your unsaved edits stay pending on top.',
'ed.playCode': 'Play language',
'ed.rtl': 'Right-to-left language.',
'ed.noStoreForLang': '{lang} is on neither store in the config.',
'ed.detailsTitle': 'Store details',
'ed.detailsSub': 'URLs, contact and copyright, shared by both stores (storebound.config.ts).',
'ed.applyTitle': 'Apply to the stores',
'ed.applySub': 'Each store: the dry run (old to new per language) in the window, then the confirm dialog, then the real run.',
'ed.applyPlay': 'Google Play listing: preview',
'ed.applyApple': 'App Store {version}: preview',
'ed.applyNote': 'Nothing goes to review: the texts wait in the store until you send the version or changes for review.',
'ed.appleInfoTitle': 'App Store app information',
'ed.appleInfoSub': 'Categories, content rights, price, export compliance and the App Store name.',
'ed.catPrimary': 'Primary category',
'ed.catSub1': 'Game subcategory 1',
'ed.catSub2': 'Game subcategory 2',
'ed.catSecondary': 'Secondary category',
'ed.free': 'Price',
'ed.freeHint': 'Free: available in every territory and new ones.',
'ed.encHint': 'Only you can answer this: export compliance skill.',
'ed.appleName': 'App Store name',
'ed.appleNameHint': 'When the app name is taken on the App Store.',
'ed.ageTitle': 'Age rating',
'ed.ageSub': 'Every question of the App Store declaration. Not set: the "nothing" answer.',
'ed.ageDefault': 'Default: {value}',
'ed.reviewSub': 'Sign-in, notes and contact for App Review. The demo account password is never shown.',
'ed.notesHint': 'App Store Connect takes at most {max} bytes.',
'ed.signInSteps': 'Sign-in steps for reviewers',
'ed.contact_firstName': 'Contact first name',
'ed.contact_lastName': 'Contact last name',
'ed.contact_phone': 'Contact phone',
'ed.contact_email': 'Contact email',
'ed.contactHint': 'Personal data: kept in the private .storebound/ folder (gitignored), shown masked. Type to replace.',
'ed.demoHint': 'The demo account lives only in the private .storebound/ folder; the window never reads the password.',
'ed.game': 'Game',
'ed.app': 'App',
'ed.playSettingsTitle': 'Google Play store settings',
'ed.playSettingsSub': 'Category, countries, managed publishing, target audience, delete-account page.',
'ed.playCategory': 'App category',
'ed.noApiHint': 'No API: the console plan step uses this value.',
'ed.managed': 'Managed publishing',
'ed.countries': 'Production countries',
'ed.countriesHint': 'Two-letter codes (US, GB, TR). Empty: all countries.',
'ed.targetAges': 'Target age groups',
'ed.targetAgesHint': 'Of {groups}.',
'ed.deletionUrl': 'Delete-account page',
'ed.declTitle': 'Data safety and App Privacy answers',
'ed.declSub': 'The answers both forms are filled from. Only you know them: change what the app and its SDKs really do.',
'ed.dsTypes': 'Data types (Play)',
'ed.dsTypesHint': 'Play data type id to usage: { "PSL_EMAIL": { "shared": false, "collect": ["account"] } }. Not listed: not collected.',
'ed.apAnswers': 'App Privacy (App Store)',
'ed.apHint': 'Checked with the whole config when you save; App Privacy has no API (console fill).',
'ed.promoTitle': 'App Store promotion',
'ed.promoSub': 'Promoted purchases, custom product pages and in-app events.',
'ed.promoted': 'Promoted in-app purchases',
'ed.promotedHint': 'Turning them on stays a terminal step (apple promoted --enable).',
'ed.cpp': 'Custom product pages',
'ed.cppHint': 'Submitting a page and making it visible stay terminal steps.',
'ed.events': 'In-app events',
'ed.eventsHint': 'Name 30, short 50, long 120 characters per locale. Sending to review stays a terminal step.',
'ed.applyCpp': 'Custom product pages: preview',
'ed.applyEvents': 'In-app events: preview',
'ed.applyInfoSub': 'App information, App Review, export compliance, Data safety and the Play app details.',
'ed.applyPlayDetails': 'Play contact email and website: preview',
'ed.playConsoleOnly': 'Category, countries and managed publishing have no API: App info > Console steps.',
'ed.itemName': 'Name',
'ed.itemDescription': 'Description',
'ed.benefits': 'Benefits (Play)',
'ed.benefitsHint': 'Comma separated, up to 4, 40 characters each.',
'ed.usd': 'Base price (USD)',
'ed.usdHint': 'A live product\'s new price waits for your decision (Apply the price changes).',
'ed.refName': 'Reference name',
'ed.reviewNote': 'Review note',
'ed.reviewShot': 'Review screenshot',
'ed.family': 'Family Sharing',
'ed.offerCodes': 'Offer codes',
'ed.offerCodesHint': 'Creating codes stays a terminal step (they work like vouchers).',
'ed.level': 'Level in the group',
'ed.levelHint': '1 = highest level of service.',
'ed.period': 'Period',
'ed.periodHint': 'Cannot change after the subscription is approved.',
'ed.intro': 'Introductory offer',
'ed.introHint': 'For example { "type": "free", "duration": "P1W" }.',
'ed.offers': 'Promotional offers',
'ed.winBack': 'Win-back offers',
'ed.winBackHint': 'Creating one stays a terminal step: it goes live by itself on its start date.',
'ed.catalogTitle': 'Edit the catalog',
'ed.catalogEmpty': 'No products or subscriptions in the config',
'ed.catalogEmptyText': 'Add them with the store-iap-setup or store-subscriptions skill.',
'ed.productsTitle': 'In-app products',
'ed.productsSub': 'Names, descriptions per language, price and review details.',
'ed.groupTitle': 'Subscription group {name}',
'ed.groupSub': 'Group display name per language and each subscription.',
'ed.groupName': 'Group display name',
'ed.applyCatalogSub': 'Each store: the dry run per product in the window, then the confirm dialog.',
'ed.applyPlayProducts': 'Play products: preview',
'ed.applyPlaySubs': 'Play subscriptions: preview',
'ed.applyAppleIap': 'App Store in-app purchases: preview',
'ed.applyAppleSubs': 'App Store subscriptions: preview',
'ed.applyIapReview': 'Review screenshots: preview',
'ed.priceGate': 'Price changes of live products are never applied here: they wait for your decision in the owner action.',
'ed.tfTitle': 'Edit TestFlight information',
'ed.tfSub': 'What to Test per locale, the beta description, notes for Beta App Review and the groups.',
'ed.whatToTest': 'What to Test',
'ed.whatToTestHint': 'Empty: the What\'s new text is used.',
'ed.betaDescription': 'Beta App Description',
'ed.betaDescriptionAll': 'Beta App Description (every locale)',
'ed.betaNotes': 'Notes for Beta App Review',
'ed.tfGroups': 'Beta groups',
'ed.tfGroupsHint': '[{ "name": "Studio team", "internal": true }]. Existing groups are never changed or deleted.',
'ed.applyTfSub': 'Test information and the missing groups. External testing and Beta App Review stay terminal steps.',
'ed.applyTfInfo': 'Test information: preview',
'ed.artTitle': 'Screenshot order and frames',
'ed.artSub': 'The stores show the screenshots in this order. Point a scene at another frame to replace its screenshot.',
'ed.artEmpty': 'No screenshot scenes in the config',
'ed.artEmptyText': 'Set up shots with the store-screenshots skill.',
'ed.frame': 'Frame',
'ed.up': 'Up',
'ed.down': 'Down',
'ed.moveUp': 'Move {id} up',
'ed.moveDown': 'Move {id} down',
'ed.applyArtSub': 'Render, then upload: an upload replaces the store\'s screenshot set (dry run first).',
'ed.loadFailed': 'Could not read the app folder\'s files: {error}',
} as const;