Skills Plugins MCP Prompt Model 博客 我的中心
内容创作 #marketing #image

app-store-screenshots

Use when building App Store or Google Play screenshot pages, generating exportable marketing screenshots for iOS and/or Android apps, or scaffolding a screenshot editor with Next.js. Triggers on app store, play store, screenshots, marketing assets, html-to-image, phone mockup, android screenshots, feature graphic.

DeepseekModel 官方收录技能 质量 优秀 · 90 v1.0.0

获取

https://deepseekmodel.com/api/download.php?id=parthjadhav-app-store-screenshots-skills-app-store-screenshots-skill-md&format=skill
下载 .skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用
.skill 文件中 system_prompt 字段的实际内容。
name app-store-screenshots description Use when building App Store or Google Play screenshot pages, generating exportable marketing screenshots for iOS and/or Android apps, or scaffolding a screenshot editor with Next.js. Triggers on app store, play store, screenshots, marketing assets, html-to-image, phone mockup, android screenshots, feature graphic. App Store & Google Play Screenshots Generator Overview Scaffold a pre-built Next.js + ShadCN editor that lets the user design and export App Store and Google Play screenshots as advertisements (not UI showcases). The editor handles all the heavy lifting: Connected live preview at the canvas's true resolution (scaled to fit) Drag-to-reorder screens, inline text editing, layout switcher per screen Cross-screen mockups: phone/device frames, captions, and layered elements can be moved across adjacent screens, then exported as clipped crops Drop-target screenshot picker (file → saved to public/screenshots/uploaded/<hash>.png ) Auto-save to app-store-screenshots.json at the project root (git-trackable) + localStorage mirror Easy iOS ↔ Android platform switch — separate slide decks live side by side One-click bulk PNG export at every Apple/Google-required resolution via html-to-image Light/dark variant toggle per slide, theme presets, locale select Guided in-place migration for older projects created by this skill; passive and explicit migrations keep legacy decks isolated until the user intentionally opts into connected canvas Supported devices out of the box: iPhone (portrait) — Apple App Store iPad (portrait) — Apple App Store Android Phone (portrait) — Google Play Android Tablet 7" (portrait + landscape) — Google Play Android Tablet 10" (portrait + landscape) — Google Play Feature Graphic (1024×500 banner) — Google Play store listing header Core Principle Screenshots are advertisements, not documentation. Every screenshot sells one idea. If you're showing UI, you're doing it wrong — you're selling a feeling , an outcome , or killing a pain point . Use this skill's interactive editor to iterate on copy and layout fast; do not hand-craft the page from scratch. What This Skill Does Copies a pre-built template from template/ (co-located with this SKILL.md ) into the user's working directory. Installs dependencies with the user's package manager. Drops the user's screenshots into public/screenshots/... and their app icon into public/ . (Optionally) prefills app-store-screenshots.json with the user's app name, starting copy, screenshots, and connected-canvas preference so the first preview is meaningful. Starts the dev server and tells the user to open the editor in the browser. You should NOT write page.tsx , device frames, or export logic by hand. They live in the template. Step 0: Probe for Existing Screenshot Projects Before asking the new-project questions in Step 1, always inspect the current working directory for an existing app-store-screenshots implementation. Run lightweight probes: test -f package.json && sed -n '1,220p' package.json test -f app-store-screenshots.json && sed -n '1,120p' app-store-screenshots.json rg -n "app-store-screenshots|html-to-image|toPng|ScreenshotEditor|DeckCanvas|connectedCanvas|EXPORT_SIZES|mockup.png|PHONE_SCREEN" package.json src app public 2>/dev/null find public -maxdepth 4 \( -path "*/screenshots*" -o -name "mockup.png" -o -name "app-icon.png" \) - print 2>/dev/null Treat the project as an older implementation when any of these are true: app-store-screenshots.json exists but has no schemaVersion , has schemaVersion < 2 , or lacks connectedCanvas . src/components/editor/screenshot-editor.tsx exists but the editor does not reference DeckCanvas or connectedCanvas . src/app/page.tsx contains a previous all-in-one generator ( html-to-image , toPng , EXPORT_SIZES , PHONE_SCREEN , hardcoded slide arrays/themes). The repo contains the old screenshot asset layout ( public/mockup.png , public/screenshots... ) plus a screenshot generator package setup. If an older implementation is detected, ask exactly one question before doing anything else: I found an older App Store screenshots project here. Do you want me to migrate this existing project to the new connected-canvas editor? Yes — migrate the existing project to the new editor No — set up or modify a project another way If the user chooses Yes , do not ask the Step 1 questionnaire. Run the migration path below using the files already in the repo. If the user chooses No , continue to Step 1. Migration Path (When User Says Yes) The goal is an in-place UI/template upgrade, not a redesign. Preserve the user's existing app name, copy, screenshot paths, app icon, uploaded assets, locales, and device decks wherever they already exist. Replace the old UI implementation with the current template. Keep legacy decks in isolated export mode unless the project already explicitly opted into connected canvas. Migration rules: Do not ask further product/design questions. The user already has a project. Infer from existing files and report any non-blocking gaps at the end. Never delete user assets. Preserve public/screenshots/ , public/app-icon.png , uploaded screenshots, and any existing app-store-screenshots.json . Preserve recoverability. If the worktree is not clean, do not revert unrelated changes. Before overwriting template files, copy replaced project-state/assets/code snapshots to a temporary backup outside the repo (for example /tmp/app-store-screenshots-migration-<timestamp>/ ) and mention the path in the final response. Prefer structured migration. Read and write app-store-screenshots.json with JSON tooling. Do not regex-edit JSON. Set schemaVersion: 2 and keep legacy connectedCanvas safe. If the existing project already has an explicit boolean connectedCanvas , preserve it. If the project is pre-v2 or lacks the flag, write "connectedCanvas": false so offscreen/clipped legacy mockups do not leak into neighboring exports. New projects still default to connected canvas. Keep screenshots pointed at existing files. Do not rename screenshot files unless the old project already depended on numeric names and the migration needs them. Existing static paths are fine. Handle custom themes without asking. If the old project references a custom themeId , merge the matching theme object into the new src/lib/constants.ts when it can be found. If it cannot be recovered, leave the themeId in project JSON; the editor will fall back to clean-light and warn, and you should note that a custom theme needs manual restoration. Merge package metadata when possible. The template's dependencies and scripts must win for the screenshot editor, but preserve unrelated existing dependencies , devDependencies , and useful scripts unless they directly conflict. Do not import template sample decks into real migrations. If the old project already has decks or screenshots, use the template for UI/code only. Keep template sample screenshots/decks out of the migrated project so the user's app does not inherit unrelated example content. Use a disposable copy for dogfooding. If the user asks to test or review the migration instead of actually migrating their project, copy the app to a temp directory or worktree and run the migration there. Only touch the real checkout when the user explicitly asks for the real migration and answers Yes . Recommended migration sequence: # 1. Snapshot useful old files outside the repo. STAMP=$( date +%Y%m%d-%H%M%S) BACKUP_DIR= "/tmp/app-store-screenshots-migration- $STAMP " mkdir -p " $BACKUP_DIR " cp -R app-store-screenshots.json public src package.json tailwind.config.ts next.config.mjs " $BACKUP_DIR /" 2>/dev/null || true # 2. Preserve project state and assets that must survive template copy. PRESERVE_DIR= " $BACKUP_DIR /preserve" mkdir -p " $PRESERVE_DIR " cp app-store-screenshots.json " $PRESERVE_DIR /" 2>/dev/null || true cp -R public/screenshots " $PRESERVE_DIR /screenshots" 2>/dev/null || true cp public/app-icon.png " $PRESERVE_DIR /app-icon.png" 2>/dev/null || true # 3. Copy the current template over the old UI implementation. cp -R "<SKILL_DIR>/template/." " $PWD /" cp app-store-screenshots.json " $BACKUP_DIR /template-app-store-screenshots.json" 2>/dev/null || true # 4. Restore preserved user state/assets over template samples. cp " $PRESERVE_DIR /app-store-screenshots.json" app-store-screenshots.json 2>/dev/null || true mkdir -p public if [ -d " $PRESERVE_DIR /screenshots" ]; then mkdir -p " $BACKUP_DIR /template-samples/public" mv public/screenshots " $BACKUP_DIR /template-samples/public/screenshots" 2>/dev/null || true cp -R " $PRESERVE_DIR /screenshots" public/screenshots else mkdir -p public/screenshots fi cp " $PRESERVE_DIR /app-icon.png" public/app-icon.png 2>/dev/null || true After copying, upgrade or create app-store-screenshots.json . If an existing project file exists, coerce it in place. If no project file exists but old slide data is embedded in src/lib/defaults.ts or src/app/page.tsx , extract it best-effort into the template's project JSON before falling back to starter slides. Prefer old arrays or objects named slides , screens , features , defaultSlides , appName , tagline , theme , and screenshot paths. If the old implementation only has image files, sort public/screenshots/** by path and seed slides from those files. Use a small JSON script like this for the final project-state coercion: BACKUP_DIR= " $BACKUP_DIR " node << 'NODE' const fs = require( "fs" ); const path = require( "path" ); const PROJECT_FILE = "app-store-screenshots.json" ; const DEFAULT_LOCALE = "en" ; const DEVICE_KEYS = [ "iphone" , "ipad" , "android" , "android-7" , "android-10" , "feature-graphic" ]; const LAYOUTS = [ "hero" , "device-bottom" , "device-top" , "two-devices" , "no-device" , "split-landscape" , "feature-graphic" ]; function readJson(file) { try { return JSON.parse(fs.readFileSync(file, "utf8" )); } catch { return null; } } const templateState = readJson(path.join(process.env.BACKUP_DIR || "" , "template-app-store-screenshots.json" )) || readJson(PROJECT_FILE) || {}; const existingState = readJson(PROJECT_FILE) || {}; const hasExplicitConnectedCanvas = typeof existingState.connectedCanvas === "boolean" ; const existingDecks = existingState.slidesByDevice && typeof existingState.slidesByDevice === "object" ? existingState.slidesByDevice : {}; const hasExistingDecks = Object.keys(existingDecks).length > 0; const state = { ...templateState, ...existingState, slidesByDevice: hasExistingDecks ? existingDecks : templateState.slidesByDevice || {}, }; const legacySlides = Array.isArray(existingState.slides) ? existingState.slides : Array.isArray(existingState.screens) ? existingState.screens : Array.isArray(existingState.features) ? existingState.features : null; if (legacySlides && !hasExistingDecks) { state.slidesByDevice = { iphone: legacySlides, }; } function localized(value) { if (typeof value === "string" ) return { [DEFAULT_LOCALE]: value }; if (value && typeof value === "object" ) return value; return {}; } function cleanTransform(value) { if (!value || typeof value !== "object" ) return undefined; const { x, y, width, height, rotation, zIndex } = value; if (![x, y, width, height].every((n) => typeof n === "number" && Number.isFinite(n))) return undefined; return { x, y, width: Math.max(1, width), height: Math.max(1, height), ...(typeof rotation === "number" && Number.isFinite(rotation) ? { rotation } : {}), ...(typeof zIndex === "number" && Number.isFinite(zIndex) ? { zIndex } : {}), }; } function firstString(...values) { return values.find((value) => typeof value === "string") || ""; } function migrateSlide(slide) { if (!slide || typeof slide !== "object") return null; const transforms = {}; const rawTransforms = slide.transforms && typeof slide.transforms === "object" ? slide.transforms : {}; for (const [id, transform] of Object.entries(rawTransforms)) { const cleaned = cleanTransform(transform); if (cleaned) transforms[ id ] = cleaned; } const textElements = Array.isArray(slide.textElements) ? slide.textElements .map((element) => { const transform = cleanTransform(element.transform); if (!element || typeof element.id !== "string" || !transform) return null; return { ...element, text: localized(element.text), transform, }; }) .filter(Boolean) : undefined; return { ...slide, id: typeof slide.id === "string" ? slide.id : `migrated- ${Math.random().toString(36).slice(2, 10)} `, layout: LAYOUTS.includes(slide.layout) ? slide.layout : "device-bottom", label: localized(slide.label), headline: localized(slide.headline || slide.title || slide.caption || slide.copy), screenshot: firstString(slide.screenshot, slide.image, slide.src, slide.path), ...(Object.keys(transforms).length ? { transforms } : { transforms: undefined }), ...(textElements && textElements.length ? { textElements } : { textElements: undefined }), }; } state.schemaVersion = 2 ; state.connectedCanvas = hasExplicitConnectedCanvas ? existingState.connectedCanvas : false; state.locales = Array.isArray(state.locales) && state.locales.length ? state.locales : [DEFAULT_LOCALE]; state.locale = state.locales.includes(state.locale) ? state.locale : state.locales[ 0 ]; state.device = DEVICE_KEYS.includes(state.device) ? state.device : "iphone"; if (state.slidesByDevice && typeof state.slidesByDevice === "object") { for (const [device, slides] of Object.entries(state.slidesByDevice)) { if (!DEVICE_KEYS.includes(device)) continue ; state.slidesByDevice[device] = Array.isArray(slides) ? slides.map(migrateSlide).filter(Boolean) : []; } } if (!state.slidesByDevice[state.device]) { const firstDeviceWithSlides = DEVICE_KEYS.find((device) => state.slidesByDevice[device]?.length); if (firstDeviceWithSlides) state.device = firstDeviceWithSlides; } fs.writeFileSync(PROJECT_FILE, JSON.stringify(state, null, 2 ) + "\n"); NODE If package.json existed before the template copy, merge it after the project-state coercion instead of leaving a blind overwrite. Keep the template's dev , build , and start scripts and all editor dependencies, then add any old non-conflicting scripts and dependencies from the backed-up package.json . BACKUP_DIR= " $BACKUP_DIR " node << 'NODE' const fs = require( "fs" ); const path = require( "path" ); function readJson(file) { try { return JSON.parse(fs.readFileSync(file, "utf8" )); } catch { return null; } } const oldPkg = readJson(path.join(process.env.BACKUP_DIR || "" , "package.json" )); const templatePkg = readJson( "package.json" );
Agent 识别该技能的关键词,点击任意一个即可复制。

该技能未提供触发词。

下载的 .skill 包内含以下字段。
字段 说明
format格式标识(skill/v1)
skill_id技能唯一 ID
name技能名称
version版本号
description技能描述
category所属分类(数组)
trigger_words触发词列表
tags标签列表
source来源标识
source_url来源链接(本页地址)
exported_at导出时间(每次下载生成)
system_prompt系统提示词正文
model_config模型参数:provider / model / temperature / max_tokens / top_p
examples示例
install_guide各平台导入说明(Coze / Dify / Claude / 自定义框架)
同一份技能可按不同平台格式导出。
.skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用 下载
.skillpro 增强格式,额外含脚本 / 工具 / 依赖 / 钩子占位 下载
.json 纯 JSON 导出,只含 system_prompt 与模型参数 下载
Coze 带 frontmatter 的 Markdown,Coze 平台导入用 下载
Dify Dify DSL,创建应用后直接导入 下载

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

验证码 --

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。