[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6FFZRY08X21SN45PDQJJKMM":3,"skill-same:01M6FFZRY08X21SN45PDQJJKMM":54},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":27,"linkOnly":28,"markdownContent":29,"markdownBody":29,"frontMatter":30,"refName":31,"commitSha":32,"skillDirectory":33,"forksCount":34,"repositoryHtmlUrl":35,"repositoryHomepageUrl":36,"ownerHtmlUrl":37,"ownerBlogUrl":6,"ownerDescription":38,"updatedAt":39,"install":40,"resources":53},"01M6FFZRY08X21SN45PDQJJKMM","asc-localize-metadata",null,"ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",66,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Frudrankriyam\u002Fapp-store-connect-cli-skills\u002Fasc-localize-metadata\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[23,24,25,26],"metadata","localize","asc","asc localize metadata","2026-11-10 10:12:30",false,"# asc localize metadata\n\nUse this skill to pull English (or any source locale) App Store metadata, translate it with LLM, and push translations back to App Store Connect — all automated.\n\n## Command discovery and output conventions\n\n- Always confirm flags with `--help` for the exact `asc` version:\n  - `asc localizations --help`\n  - `asc localizations download --help`\n  - `asc localizations upload --help`\n  - `asc apps info edit --help`\n- Prefer explicit long flags (`--app`, `--version`, `--version-id`, `--type`, `--app-info`).\n- Default output is JSON; use `--output table` only for human verification steps.\n- Prefer deterministic ID-based operations. Do not \"pick the first row\" via `head -1` unless the user explicitly agrees.\n\n## Preconditions\n- Auth configured (`asc auth login` or `ASC_*` env vars)\n- Know your app ID (`asc apps list` to find it)\n- At least one locale (typically en-US) already has metadata in App Store Connect\n\n## Supported Locales\n\nApp Store Connect locales for version and app-info localizations:\n```\nar-SA, ca, cs, da, de-DE, el, en-AU, en-CA, en-GB, en-US,\nes-ES, es-MX, fi, fr-CA, fr-FR, he, hi, hr, hu, id, it,\nja, ko, ms, nl-NL, no, pl, pt-BR, pt-PT, ro, ru, sk,\nsv, th, tr, uk, vi, zh-Hans, zh-Hant\n```\n\n## Two Types of Metadata\n\n### Version Localizations (per-release)\nFields: `description`, `keywords`, `whatsNew`, `supportUrl`, `marketingUrl`, `promotionalText`\n\n### App Info Localizations (app-level, persistent)\nFields: `name`, `subtitle`, `privacyPolicyUrl`, `privacyChoicesUrl`, `privacyPolicyText`\n\n## Workflow\n\n### Step 1: Resolve IDs\n\n```bash\n# Find app ID\nasc apps list --output table\n\n# Find latest version ID\nasc versions list --app \"APP_ID\" --state READY_FOR_DISTRIBUTION --output table\n# or for editable version:\nasc versions list --app \"APP_ID\" --state PREPARE_FOR_SUBMISSION --output table\n\n# Find app info ID (for app-level fields like name\u002Fsubtitle)\nasc apps info list --app \"APP_ID\" --output table\n```\n\nNotes:\n- Version-localization fields (description, keywords, whatsNew, etc.) are per-version.\n- App-info fields (name, subtitle, privacy URLs\u002Ftext) are app-level and use `--type app-info`.\n- If you only have names (app name, version string) and need IDs deterministically, use `asc-id-resolver`.\n\n### Step 2: Download source locale\n\n```bash\n# Download version localizations to local .strings files\n# (description, keywords, whatsNew, promotionalText, supportUrl, marketingUrl, ...)\nasc localizations download --version \"VERSION_ID\" --path \".\u002Flocalizations\"\n\n# Download app-info localizations to local .strings files\n# (name, subtitle, privacyPolicyUrl, privacyChoicesUrl, privacyPolicyText, ...)\nasc localizations download --app \"APP_ID\" --type app-info --app-info \"APP_INFO_ID\" --path \".\u002Fapp-info-localizations\"\n```\n\nThis creates files like `.\u002Flocalizations\u002Fen-US.strings` and `.\u002Fapp-info-localizations\u002Fen-US.strings`. If download is unavailable, read fields individually:\n\n```bash\n# List version localizations to see existing locales and their content\nasc localizations list --version \"VERSION_ID\" --output table\n```\n\n### Step 3: Translate with LLM\n\nFor each target locale, translate the source text. Follow these rules:\n\n#### Translation Guidelines\n- **Tone & Register**: Always use formal, polite language. Use formal \"you\" forms where the language distinguishes them (Russian: «вы», German: «Sie», French: «vous», Spanish: «usted», Dutch: «u», Italian: «Lei», Portuguese: «você» formal, etc.). App Store descriptions are professional marketing copy — never use casual or informal register.\n- **description**: Translate naturally, adapt tone to local market. Keep formatting (line breaks, bullet points, emoji). Stay within 4000 chars.\n- **keywords**: Do NOT literally translate. Research what users in that locale would search for. Comma-separated, max 100 chars total. No duplicates, no app name (Apple adds it automatically).\n- **whatsNew**: Translate release notes. Keep it concise. Max 4000 chars.\n- **promotionalText**: Translate marketing hook. Max 170 chars. This can be updated without a new version.\n- **subtitle**: Translate or adapt tagline. Max 30 chars — this is very tight, may need creative adaptation.\n- **name**: Usually keep the original app name. Only translate if the user explicitly asks. Max 30 chars.\n\n#### LLM Translation Prompt Template\n\nFor each target locale, use this approach:\n\n```\nTranslate the following App Store metadata from {source_locale} to {target_locale}.\n\nRules:\n- description: Natural, fluent translation. Preserve formatting (line breaks, bullets, emoji). Max 4000 chars.\n- keywords: Do NOT literally translate. Choose keywords native speakers would search for in the App Store. Comma-separated, max 100 chars total. Do not include the app name.\n- whatsNew: Translate release notes naturally. Max 4000 chars.\n- promotionalText: Translate marketing tagline. Max 170 chars.\n- subtitle: Adapt tagline creatively to fit 30 chars max.\n- name: Keep the original app name unless explicitly requested to translate it. Max 30 chars.\n- Use formal, polite language and formal \"you\" forms (Russian: вы, German: Sie, French: vous, Spanish: usted, Dutch: u, etc.). App Store copy is professional marketing — never use informal register.\n- Respect cultural context. A playful tone in English may need adjustment for formal markets (e.g., ja, de-DE).\n\nSource ({source_locale}):\ndescription: \"\"\"\n{description}\n\"\"\"\n\nkeywords: {keywords}\n\nwhatsNew: \"\"\"\n{whatsNew}\n\"\"\"\n\npromotionalText: {promotionalText}\n\nname: {name}\n\nsubtitle: {subtitle}\n```\n\n### Step 4: Upload translations\n\n#### Option A: Via .strings files (bulk)\n\nCreate a `.strings` file per locale in the appropriate directory.\n\nVersion localization example:\n\n```\n\u002F\u002F nl-NL.strings\n\"description\" = \"Je app-beschrijving hier\";\n\"keywords\" = \"wiskunde,kinderen,tafels,leren\";\n\"whatsNew\" = \"Bugfixes en verbeteringen\";\n\"promotionalText\" = \"Leer de tafels van vermenigvuldiging!\";\n```\n\nThen upload version localizations:\n```bash\nasc localizations upload --version \"VERSION_ID\" --path \".\u002Flocalizations\"\n```\n\nApp-info localization example:\n\n```\n\u002F\u002F nl-NL.strings\n\"subtitle\" = \"Leer tafels spelenderwijs\";\n```\n\nThen upload app-info localizations:\n```bash\nasc localizations upload --app \"APP_ID\" --type app-info --app-info \"APP_INFO_ID\" --path \".\u002Fapp-info-localizations\"\n```\n\n#### Option B: Via individual commands (fine control)\n\n```bash\n# Version localization fields (fine control).\n# Prefer passing the explicit version ID for determinism.\nasc apps info edit --app \"APP_ID\" --version-id \"VERSION_ID\" --locale \"nl-NL\" \\\n  --description \"Je beschrijving...\" \\\n  --keywords \"wiskunde,kinderen,tafels\" \\\n  --whats-new \"Bugfixes en verbeteringen\"\n```\n\nFor app-level fields:\n```bash\n# Subtitle\u002Fname (app-info localization) is managed via app-info localizations.\n# Use the app-info localization .strings + upload flow (there is no `asc app-infos localizations ...` command).\n#\n# 1) Edit: .\u002Fapp-info-localizations\u002Fnl-NL.strings\n# \"subtitle\" = \"Leer tafels spelenderwijs\";\n#\n# 2) Upload:\nasc localizations upload --app \"APP_ID\" --type app-info --app-info \"APP_INFO_ID\" --path \".\u002Fapp-info-localizations\"\n```\n\n### Step 5: Verify\n\n```bash\n# Check all locales are present\nasc localizations list --version \"VERSION_ID\" --output table\n\n# Check app info localizations\nasc localizations list --app \"APP_ID\" --type app-info --app-info \"APP_INFO_ID\" --output table\n```\n\n## Character Limits (enforce before upload!)\n\n| Field | Limit |\n|-------|-------|\n| Name | 30 |\n| Subtitle | 30 |\n| Keywords | 100 (comma-separated) |\n| Description | 4000 |\n| What's New | 4000 |\n| Promotional Text | 170 |\n\n**Always validate** translated text fits within limits before uploading. Truncated text looks unprofessional. If translation exceeds the limit, shorten it — do not truncate mid-sentence.\n\n## Full Example: Add nl-NL and ru to Roxy Math\n\n```bash\n# 1) Resolve IDs deterministically (do not auto-pick the \"first\" row)\n# If you only have names, use asc-id-resolver skill.\nasc apps list --output table\nAPP_ID=\"APP_ID_HERE\"\n\nasc versions list --app \"$APP_ID\" --state PREPARE_FOR_SUBMISSION --output table\nVERSION_ID=\"VERSION_ID_HERE\"\n\nasc apps info list --app \"$APP_ID\" --output table\nAPP_INFO_ID=\"APP_INFO_ID_HERE\"\n\n# 2) Download English source (or your chosen source locale)\nasc localizations download --version \"$VERSION_ID\" --path \".\u002Flocalizations\"\nasc localizations download --app \"$APP_ID\" --type app-info --app-info \"$APP_INFO_ID\" --path \".\u002Fapp-info-localizations\"\n\n# 3) Read en-US.strings, translate to nl-NL and ru (LLM step)\n\n# 4) Write nl-NL.strings and ru.strings to:\n#    - .\u002Flocalizations\u002F (version localization fields)\n#    - .\u002Fapp-info-localizations\u002F (subtitle\u002Fname\u002Fprivacy fields)\n\n# 5) Upload all\nasc localizations upload --version \"$VERSION_ID\" --path \".\u002Flocalizations\"\nasc localizations upload --app \"$APP_ID\" --type app-info --app-info \"$APP_INFO_ID\" --path \".\u002Fapp-info-localizations\"\n\n# 6) Verify\nasc localizations list --version \"$VERSION_ID\" --output table\nasc localizations list --app \"$APP_ID\" --type app-info --app-info \"$APP_INFO_ID\" --output table\n```\n\n## Agent Behavior\n\n1. **Always start by reading the source locale** — never translate from memory or assumptions.\n2. **Check existing localizations first** — don't overwrite existing translations unless the user asks to update them.\n3. **Version vs app-info is different** — version fields live under `--version \"VERSION_ID\"`; subtitle\u002Fname\u002Fprivacy live under `--app ... --type app-info`.\n4. **Prefer deterministic IDs** — do not select IDs via `head -1` unless explicitly requested; use `--output table` for selection or `asc-id-resolver`.\n5. **Validate character limits** before uploading. Count characters for each field. If over limit, re-translate shorter.\n6. **Keywords are special** — do not literally translate. Research locale-appropriate search terms. Think like a user searching the App Store in that language.\n7. **Show the user translations before uploading** — present a summary table of all fields × locales for approval. Do not push without confirmation.\n8. **Process one locale at a time** if translating many languages — easier to review and catch errors.\n9. **If upload fails** for a locale, log the error, continue with other locales, report all failures at the end.\n10. **For updates to existing localizations** — download current, show diff of what will change, get approval, then upload.\n\n## Notes\n- Version localizations are tied to a specific version. Create the version first if it doesn't exist.\n- `promotionalText` can be updated anytime without a new version submission.\n- `whatsNew` is only relevant for updates, not the first version.\n- Use `asc-id-resolver` skill if you only have app\u002Fversion names instead of IDs.\n- Use `asc-metadata-sync` skill for non-translation metadata operations.\n- For subscription\u002FIAP display name localization, use `asc-subscription-localization` skill instead.\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Frudrankriyam\u002Fapp-store-connect-cli-skills\u002Fasc-localize-metadata",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":7,"skillName":5,"commands":41,"prompt":51,"zipAvailable":52},[42,45,48],{"tool":43,"command":44},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill asc-localize-metadata",{"tool":46,"command":47},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill asc-localize-metadata",{"tool":49,"command":50},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill asc-localize-metadata","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Frudrankriyam\u002Fapp-store-connect-cli-skills\u002Fasc-localize-metadata\u002FSKILL.md",true,[],[55,65,75,84,90,97],{"skillNo":56,"name":57,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":58,"categories":59,"keywords":61,"publishedAt":27},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[60],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},[62,63,64],"model","model hierarchy","model hierarchy skill",{"skillNo":66,"name":67,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":71,"publishedAt":27},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[70],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},[72,73,74],"MCP","zoom","zoom mcp",{"skillNo":76,"name":77,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":78,"categories":79,"keywords":80,"publishedAt":27},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[81,82,83,73],"sdk","zoom apps sdk","apps",{"skillNo":85,"name":86,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":89,"publishedAt":27},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[86],{"skillNo":91,"name":92,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":96,"publishedAt":27},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[95],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},[92],{"skillNo":98,"name":99,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":27},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[99]]