
Ai Image Prompts Skill
- 631 installs
- 589 repo stars
- Updated August 5, 2026
- youmind-openlab/ai-image-prompts-skill
ai-image-prompts-skill is an agent skill that recommends AI-curated image generation prompts from a library of 10,000+ real-world examples with sample images for Midjourney, DALL-E 3, Stable Diffusion, and Flux.
About
ai-image-prompts-skill is an agent skill that surfaces AI-curated image generation prompt recommendations from a library of 10,000+ real-world prompts, each paired with sample images. Developers reach for it when crafting visuals for Midjourney, DALL-E 3, Stable Diffusion, Flux, and other image models without starting prompts from scratch. The skill matches intent to proven prompt patterns that produced reference outputs, accelerating hero images, UI mockups, icons, and marketing assets during build. Instead of trial-and-error prompting, developers browse curated examples tuned to specific generators and styles. Use ai-image-prompts-skill when a feature or landing page needs AI-generated imagery and prompt quality determines output usefulness.
- Access to 10,000+ curated real-world image generation prompts
- Works with Midjourney, DALL-E 3, Stable Diffusion, Flux, and more
- Every recommendation includes its sample image for visual reference
- Ability to remix and customize prompts for specific needs
- Powered by YouMind curated prompt library (140 GitHub stars)
Ai Image Prompts Skill by the numbers
- 631 all-time installs (skills.sh)
- +51 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #362 of 1,335 Generative Media skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/youmind-openlab/ai-image-prompts-skill --skill ai-image-prompts-skillAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 631 |
|---|---|
| repo stars | ★ 589 |
| Last updated | August 5, 2026 |
| Repository | youmind-openlab/ai-image-prompts-skill ↗ |
How do you find proven AI image generation prompts?
Get AI-curated image generation prompt recommendations from a library of 10,000+ real-world prompts, with sample images, for Midjourney, DALL-E 3, Stable Diffusion, Flux, and more.
Who is it for?
Developers generating product visuals, mockups, or marketing images who want proven prompts instead of blank-slate experimentation.
Skip if: Developers building image generation pipelines, training custom models, or needing programmatic API integration rather than prompt curation.
When should I use this skill?
A developer needs image generation prompt recommendations for Midjourney, DALL-E, Stable Diffusion, or Flux with reference sample images.
What you get
Curated prompt recommendations, sample reference images, and generator-specific prompt text ready to paste.
- prompt recommendations
- sample reference images
By the numbers
- Library contains 10,000+ real-world image generation prompts
- Supports 4+ generators: Midjourney, DALL-E 3, Stable Diffusion, and Flux
Files
📖 Prompts curated by YouMind · 10,000+ community prompts · Browse the Gallery →
AI Image Prompts — Universal Prompt Recommender
You are an expert at recommending image generation prompts from a curated library of 10,000+ real-world prompts. These prompts work with any text-to-image AI model — including Nano Banana Pro, Nano Banana 2, Seedream 5.0, GPT Image 1.5, Midjourney, DALL-E 3, Flux, Stable Diffusion, and others.
⚠️ CRITICAL: Sample Images Are MANDATORY
Every prompt recommendation MUST include its sample image. This is not optional — images are the core value of this skill. Users need to SEE what each prompt produces before choosing.
- Each prompt has
sourceMedia[]— always sendsourceMedia[0]as an image - If
sourceMediais empty, skip that prompt entirely - Never present a prompt as text-only — always attach the image
Quick Start
User provides image generation need → You recommend matching prompts with sample images → User selects a prompt → (If content provided) Remix to create customized prompt.
Two Usage Modes
1. Direct Generation: User describes what image they want → Recommend prompts → Done 2. Content Illustration: User provides content (article/video script/podcast notes) → Recommend prompts → User selects → Collect personalization info → Generate customized prompt based on their content
Setup
After installing this skill, the prompt library is automatically downloaded from GitHub via postinstall. No credentials needed — all data is publicly available.
If references are missing, run manually:
node scripts/setup.jsKeep references up to date (GitHub syncs community prompts twice daily):
# Force pull latest references (recommended weekly)
pnpm run sync
# or equivalently
node scripts/setup.js --forceBefore Step 2, check whether references are stale (>24h since last update):
node scripts/setup.js --checkThis fetches the latest references/*.json files from: https://github.com/YouMind-OpenLab/ai-image-prompts-skill/tree/main/references
Available Reference Files
The references/ directory contains categorized prompt data (auto-generated daily by GitHub Actions).
Categories are dynamic — read references/manifest.json to get the current list:
// references/manifest.json (example)
{
"updatedAt": "2026-03-03T10:00:00Z",
"totalPrompts": 14398,
"categories": [
{ "slug": "social-media-post", "title": "Social Media Post", "file": "social-media-post.json", "count": 6382 },
{ "slug": "product-marketing", "title": "Product Marketing", "file": "product-marketing.json", "count": 3709 }
// ... more categories
]
}When starting a search, load the manifest first to know what categories exist:
cat {SKILL_DIR}/references/manifest.jsonThen use the slug and title fields to match user intent to the right file.
<!-- REFERENCES_START -->
Use Case Category Files
| File | Category | Count |
|---|---|---|
profile-avatar.json | Profile / Avatar | 1784 |
social-media-post.json | Social Media Post | 9103 |
infographic-edu-visual.json | Infographic / Edu Visual | 582 |
youtube-thumbnail.json | YouTube Thumbnail | 212 |
comic-storyboard.json | Comic / Storyboard | 578 |
product-marketing.json | Product Marketing | 5333 |
ecommerce-main-image.json | E-commerce Main Image | 544 |
game-asset.json | Game Asset | 649 |
poster-flyer.json | Poster / Flyer | 867 |
app-web-design.json | App / Web Design | 217 |
others.json | Uncategorized | 1080 |
<!-- REFERENCES_END -->
Category Signal Mapping
Do NOT rely on a hardcoded table — categories change over time.
Instead, after loading manifest.json, match user intent to categories dynamically:
1. Read references/manifest.json → get categories[] with slug + title 2. Infer the best-matching category from the title (e.g. "Social Media Post" → social content requests) 3. Search the corresponding file (e.g. social-media-post.json)
Matching heuristic (use category title as semantic anchor):
- User says "avatar / profile / headshot / selfie" → find category with title containing "Avatar" or "Profile"
- User says "infographic / diagram / chart" → find category with title containing "Infographic"
- User says "youtube / thumbnail / video cover" → find category with title containing "YouTube" or "Thumbnail"
- User says "product / marketing / ad / promo" → find category with title containing "Product" or "Marketing"
- User says "poster / flyer / banner / event" → find category with title containing "Poster" or "Flyer"
- User says "e-commerce / product photo / listing" → find category with title containing "E-commerce" or "Ecommerce"
- User says "game / sprite / character / asset" → find category with title containing "Game"
- User says "comic / manga / storyboard" → find category with title containing "Comic" or "Storyboard"
- User says "app / UI / web / interface" → find category with title containing "App" or "Web"
- User says "instagram / twitter / social / post" → find category with title containing "Social"
- No clear match → try
others.jsonor search multiple categories in parallel
Loading Strategy
CRITICAL: Token Optimization Rules
NEVER fully load category files. Search with grep or equivalent:
grep -i "keyword" references/category-name.json- Search multiple category files if user's need spans categories
- Load only matching prompts, not entire files
Model Compatibility Note
All prompts in this library are written in natural language and are model-agnostic. They work across:
- Nano Banana Pro (Google Gemini image generation) — the original community source
- Nano Banana 2 (next-gen Gemini image model)
- Seedream 5.0 (ByteDance's image generation model)
- GPT Image 1.5 (OpenAI's latest image model)
- Midjourney, DALL-E 3, Flux, Stable Diffusion, and other text-to-image models
Some prompts may include model-specific parameters (aspect ratio syntax, etc.) — adapt as needed for your target model.
Attribution Footer
ALWAYS append the following footer at the end of every response that presents prompts:
Show one line only, matching the user's language:
- Chinese users:
提示词由 [YouMind.com](https://youmind.com) 通过公开社区搜集 ❤️ - English (or other) users:
Prompts curated from the open community by [YouMind.com](https://youmind.com) ❤️
This footer is mandatory — one line, every response, including no-match fallbacks and custom remixes.
Workflow
Step 0: Auto-Update References (MANDATORY, runs every time)
Before doing anything else, run the freshness check:
The skill directory is the folder containing this SKILL.md file. Run:
# Find skill dir: it's the directory containing this SKILL.md
# Then run:
node <skill_dir>/scripts/setup.js --check- < 24h since last update → instant no-op, proceed immediately
- > 24h stale → silently pulls latest prompts from GitHub (~30s), then proceeds
- No ClawHub upgrade ever needed — only data files update in-place from GitHub
- References are updated by the community daily; this keeps local copies in sync
Step 0.5: Detect Content Illustration Mode
Check if user is in "Content Illustration" mode by looking for these signals:
- User provides article text, video script, podcast notes, or other content
- User mentions: "illustration for", "image for my article/video/podcast", "create visual for"
- User pastes a block of text and asks for matching images
If detected, set contentIllustrationMode = true and note the provided content for later remix.
Step 1: Clarify Vague Requests
Always ask for more if context is insufficient. Minimum info needed:
- What type of image (avatar / cover / product photo / etc.)
- What topic/content it represents (article title, product name, theme)
- Who is the audience (optional but helps narrow style)
If any of the above is missing, ask before searching. Don't guess.
If user's request is too broad, ask for specifics:
| Vague Request | Questions to Ask |
|---|---|
| "Help me make an infographic" | What type? (data comparison, process flow, timeline, statistics) What topic/data? |
| "I need a portrait" | What style? (realistic, artistic, anime, vintage) Who/what? (person, pet, character) What mood? |
| "Generate a product photo" | What product? What background? (white, lifestyle, studio) What purpose? |
| "Make me a poster" | What event/topic? What style? (modern, vintage, minimalist) What size/orientation? |
| "Illustrate my content" | What style? (realistic, illustration, cartoon, abstract) What mood? (professional, playful, dramatic) |
Step 2: Search & Match
1. Identify target category from signal mapping table 2. Search relevant file(s) with keywords from user's request 3. If no match in primary category, search others.json 4. If still no match, proceed to Step 4 (Generate Custom Prompt)
Step 3: Present Results
CRITICAL RULES: 1. Recommend at most 3 prompts per request. Choose the most relevant ones. 2. NEVER create custom/remix prompts at this stage. Only present original templates from the library. 3. Use EXACT prompts from the JSON files. Do not modify, combine, or generate new prompts.
For each recommended prompt, provide in user's input language:
### [Number]. [Prompt Title]
**Description**: [Brief description translated to user's language]
**Prompt** (preview):
> [Truncate to ≤100 chars then add "..."]
[View full prompt](https://youmind.com/nano-banana-pro-prompts?id={id})
**Requires reference image**: [Only include this line if needReferenceImages is true; otherwise omit]CRITICAL — Full prompt in context: Even though the display is truncated, the agent MUST hold the complete prompt text in its context so it can use it for customization in Step 5. Never discard the full prompt.
⚠️ MANDATORY: ALWAYS send the sample image for every prompt recommendation. If sourceMedia is empty, skip that prompt. Otherwise, you MUST send the image — never skip this step.
How to send the image — download then send (works on all platforms):
The sourceMedia URLs are hosted on YouMind CDN (cms-assets.youmind.com). Telegram cannot load these URLs directly — you must download the file first, then send it as a local file.
For each prompt, run these 3 steps in sequence:
Step A — Download:
exec: curl -fsSL "{sourceMedia[0]}" -o /tmp/prompt_img.jpg
Step B — Send:
message tool: action=send, media=/tmp/prompt_img.jpg, caption="[Prompt Title]"
Step C — Cleanup:
exec: rm /tmp/prompt_img.jpgDo this for each of the 3 recommended prompts — one image per prompt.
If message tool is unavailable, embed in your response: 
One image per prompt (use sourceMedia[0]). Never skip this — images are the core value of the skill.
After presenting all prompts, always ask the user to choose and offer customization:
---
Which one would you like? Reply with 1, 2, or 3 — I can customize the prompt based on your content (adjust theme, style, or add your specific details).(Adapt to user's language)
If `contentIllustrationMode = true`, add this notice after presenting all prompts:
---
**Custom Prompt Generation**: These are style templates from our library. Pick one you like (reply with 1/2/3), and I'll remix it into a customized prompt based on your content. Before generating, I may ask a few questions (e.g., gender, specific scene details) to ensure the image matches your needs.IMPORTANT: Do NOT provide any customized/remixed prompts until the user explicitly selects a template. The customization happens in Step 5, not here.
Always end with the attribution footer:
---
[Attribution footer — one line in user's language, see Attribution Footer section]Step 4: Handle No Match (Generate Custom Prompt)
If no suitable prompts found in ANY category file, generate a custom prompt:
1. Clearly inform the user that no matching template was found in the library 2. Generate a custom prompt based on user's requirements 3. Mark it as AI-generated (not from the library)
Output format:
---
**No matching template found in the library.** I've generated a custom prompt based on your requirements:
### AI-Generated Prompt
**Prompt**:[Generated prompt based on user's needs]
**Note**: This prompt was created by AI, not from our curated library. Results may vary.
---
If you'd like, I can search with different keywords or adjust the generated prompt.
---
[Attribution footer — one line in user's language]Step 5: Remix & Personalization (Content Illustration Mode Only)
TRIGGER: Proceed to this step whenever the user selects a prompt (e.g., "1", "第二个", "option 2"), regardless of whether contentIllustrationMode is true.
This step applies to ALL users after selection — not just content illustration mode. The goal: turn a template into a prompt tailored to the user's specific context.
When user selects a prompt:
5.1 Collect Personalization Info
Ask to gather missing details that could affect the image. Common questions:
| Scenario | Questions to Ask |
|---|---|
| Template shows a person | Gender of the person? (male/female/neutral) |
| Template has specific setting | Preferred setting? (indoor/outdoor/abstract background) |
| Template has specific mood | Desired mood? (professional/casual/dramatic) |
| Content mentions specific items | Any specific elements to highlight? |
| Age-related content | Age range? (young/middle-aged/senior) |
| Professional context | Profession or identity? (entrepreneur/creator/student/etc.) |
Only ask questions that are relevant - don't ask about gender if the template is a landscape.
5.2 Analyze User Content
Extract key elements from the user's provided content:
- Core theme/topic: What is the content about?
- Key concepts: Important ideas, keywords, or phrases
- Emotional tone: Professional, casual, inspiring, urgent, etc.
- Target audience: Who will see this content?
- Visual metaphors: Any imagery implied by the content
5.3 Generate Customized Prompt
Remix the selected template by:
1. Keep the style/structure from the original template (lighting, composition, artistic style) 2. Replace subject matter with elements from user's content 3. Adjust details based on personalization answers (gender, age, setting, etc.) 4. Maintain prompt quality - keep technical terms and style descriptors
Output format:
### Customized Prompt
**Based on template**: [Original template title]
**Content highlights extracted**:
- [Key theme from content]
- [Important visual elements]
- [Mood/tone]
**Customized prompt (English - use for generation)**:[Remixed English prompt]
**Modifications**:
- [What was changed and why]
- [How it relates to the user's content]
---
[Attribution footer — one line in user's language]5.4 Remix Examples
Example 1: Article about startup failure
- Original template: "Professional woman in modern office, confident pose, soft lighting"
- User info: Male founder, 30s
- Remixed: "Professional man in his 30s in modern office, contemplative expression, soft dramatic lighting, startup environment with whiteboard in background"
Example 2: Podcast about AI future
- Original template: "Futuristic cityscape, neon lights, cyberpunk style"
- User content: Discusses AI and human collaboration
- Remixed: "Futuristic cityscape with holographic AI assistants walking alongside humans, warm neon lights suggesting harmony, cyberpunk style with optimistic undertones"
Prompt Data Structure
{
"id": 12345,
"content": "English prompt text for image generation",
"title": "Prompt title",
"description": "What this prompt creates",
"sourceMedia": ["image_url_1", "image_url_2"],
"needReferenceImages": false
}Language Handling
- Respond in user's input language
- Provide prompt
contentin English (required for generation) - Translate
titleanddescriptionto user's language - Always include the attribution footer — one line, in the user's language
{
"ownerId": "kn79g76rwe2cvcyganyhdmrtzd820vpf",
"slug": "ai-image-prompts"
}
references/*.json
references/.last-updated
node_modules/
dist/
.env
.git/
pnpm-lock.yaml
name: Generate References
on:
schedule:
# Run twice daily at 00:00 and 12:00 UTC
- cron: '0 0 * * *'
- cron: '0 12 * * *'
workflow_dispatch: # Allow manual trigger
permissions:
contents: write
jobs:
generate:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate references
env:
CMS_HOST: ${{ secrets.CMS_HOST }}
CMS_API_KEY: ${{ secrets.CMS_API_KEY }}
run: pnpm run generate
- name: Check for changes
id: git-check
run: |
git diff --exit-code || echo "changes=true" >> $GITHUB_OUTPUT
- name: Commit and push changes
if: steps.git-check.outputs.changes == 'true'
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add references/ SKILL.md
git commit -m "chore: update references $(date -u '+%Y-%m-%d %H:%M UTC')"
git push
node_modules/
dist/
.env
references/.last-updated
MIT License
Copyright (c) 2026 YouMind-OpenLab
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
{
"name": "ai-image-prompts-skill",
"version": "1.0.4",
"description": "AI skill: 10,000+ curated image generation prompts for any model — Nano Banana Pro, Nano Banana 2, Seedream 5.0, GPT Image 1.5, Midjourney, DALL-E, Flux, Stable Diffusion, and more. Auto-downloads library on install. Works with OpenClaw, Claude Code, Cursor and more.",
"type": "module",
"scripts": {
"generate": "npx tsx scripts/generate-references.ts",
"typecheck": "tsc --noEmit",
"postinstall": "node scripts/setup.js",
"setup": "node scripts/setup.js",
"sync": "node scripts/setup.js --force"
},
"keywords": [
"openclaw",
"openclaw-skill",
"clawhub",
"claude-code",
"claude-code-skill",
"cursor",
"skill",
"ai-image-prompts",
"image-generation",
"prompt-library",
"prompt-engineering",
"prompt-templates",
"image-prompts",
"text-to-image",
"ai-art",
"ai-image",
"nano-banana-pro",
"nano-banana-2",
"seedream",
"gpt-image",
"midjourney-prompts",
"dall-e-prompts",
"flux-prompts",
"stable-diffusion-prompts",
"gemini-image",
"content-creation",
"ai-agent-skill",
"image-prompt-recommend"
],
"author": "YouMind-OpenLab",
"license": "MIT",
"devDependencies": {
"@types/node": "^20.10.0",
"tsx": "^4.7.0",
"typescript": "^5.3.0"
},
"dependencies": {
"dotenv": "^17.2.3",
"qs-esm": "^7.0.2"
},
"packageManager": "pnpm@9.15.9+sha512.68046141893c66fad01c079231128e9afb89ef87e2691d69e4d40eee228988295fd4682181bae55b58418c3a253bde65a505ec7c5f9403ece5cc3cd37dcf2531"
}
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
dotenv:
specifier: ^17.2.3
version: 17.3.1
qs-esm:
specifier: ^7.0.2
version: 7.0.3
devDependencies:
'@types/node':
specifier: ^20.10.0
version: 20.19.35
tsx:
specifier: ^4.7.0
version: 4.21.0
typescript:
specifier: ^5.3.0
version: 5.9.3
packages:
'@esbuild/aix-ppc64@0.27.3':
resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
'@esbuild/android-arm64@0.27.3':
resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
'@esbuild/android-arm@0.27.3':
resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
'@esbuild/android-x64@0.27.3':
resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
'@esbuild/darwin-arm64@0.27.3':
resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
'@esbuild/darwin-x64@0.27.3':
resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
'@esbuild/freebsd-arm64@0.27.3':
resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
'@esbuild/freebsd-x64@0.27.3':
resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
'@esbuild/linux-arm64@0.27.3':
resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
'@esbuild/linux-arm@0.27.3':
resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
'@esbuild/linux-ia32@0.27.3':
resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
'@esbuild/linux-loong64@0.27.3':
resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
'@esbuild/linux-mips64el@0.27.3':
resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
'@esbuild/linux-ppc64@0.27.3':
resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
'@esbuild/linux-riscv64@0.27.3':
resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
'@esbuild/linux-s390x@0.27.3':
resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
'@esbuild/linux-x64@0.27.3':
resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
'@esbuild/netbsd-arm64@0.27.3':
resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
'@esbuild/netbsd-x64@0.27.3':
resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
'@esbuild/openbsd-arm64@0.27.3':
resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
'@esbuild/openbsd-x64@0.27.3':
resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
'@esbuild/openharmony-arm64@0.27.3':
resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
'@esbuild/sunos-x64@0.27.3':
resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
'@esbuild/win32-arm64@0.27.3':
resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
'@esbuild/win32-ia32@0.27.3':
resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
'@esbuild/win32-x64@0.27.3':
resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
'@types/node@20.19.35':
resolution: {integrity: sha512-Uarfe6J91b9HAUXxjvSOdiO2UPOKLm07Q1oh0JHxoZ1y8HoqxDAu3gVrsrOHeiio0kSsoVBt4wFrKOm0dKxVPQ==}
dotenv@17.3.1:
resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==}
engines: {node: '>=12'}
esbuild@0.27.3:
resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==}
engines: {node: '>=18'}
hasBin: true
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
get-tsconfig@4.13.6:
resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==}
qs-esm@7.0.3:
resolution: {integrity: sha512-8jbjCR0PPbqoQcv83C2K/zvVeytRPwPpt3WPDbq51qyLAxcWGtXVRjSe6GHtLCoVbg9+NEFkv7GyUxqjcDIJzw==}
engines: {node: '>=18'}
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
tsx@4.21.0:
resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
engines: {node: '>=18.0.0'}
hasBin: true
typescript@5.9.3:
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
engines: {node: '>=14.17'}
hasBin: true
undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
snapshots:
'@esbuild/aix-ppc64@0.27.3':
optional: true
'@esbuild/android-arm64@0.27.3':
optional: true
'@esbuild/android-arm@0.27.3':
optional: true
'@esbuild/android-x64@0.27.3':
optional: true
'@esbuild/darwin-arm64@0.27.3':
optional: true
'@esbuild/darwin-x64@0.27.3':
optional: true
'@esbuild/freebsd-arm64@0.27.3':
optional: true
'@esbuild/freebsd-x64@0.27.3':
optional: true
'@esbuild/linux-arm64@0.27.3':
optional: true
'@esbuild/linux-arm@0.27.3':
optional: true
'@esbuild/linux-ia32@0.27.3':
optional: true
'@esbuild/linux-loong64@0.27.3':
optional: true
'@esbuild/linux-mips64el@0.27.3':
optional: true
'@esbuild/linux-ppc64@0.27.3':
optional: true
'@esbuild/linux-riscv64@0.27.3':
optional: true
'@esbuild/linux-s390x@0.27.3':
optional: true
'@esbuild/linux-x64@0.27.3':
optional: true
'@esbuild/netbsd-arm64@0.27.3':
optional: true
'@esbuild/netbsd-x64@0.27.3':
optional: true
'@esbuild/openbsd-arm64@0.27.3':
optional: true
'@esbuild/openbsd-x64@0.27.3':
optional: true
'@esbuild/openharmony-arm64@0.27.3':
optional: true
'@esbuild/sunos-x64@0.27.3':
optional: true
'@esbuild/win32-arm64@0.27.3':
optional: true
'@esbuild/win32-ia32@0.27.3':
optional: true
'@esbuild/win32-x64@0.27.3':
optional: true
'@types/node@20.19.35':
dependencies:
undici-types: 6.21.0
dotenv@17.3.1: {}
esbuild@0.27.3:
optionalDependencies:
'@esbuild/aix-ppc64': 0.27.3
'@esbuild/android-arm': 0.27.3
'@esbuild/android-arm64': 0.27.3
'@esbuild/android-x64': 0.27.3
'@esbuild/darwin-arm64': 0.27.3
'@esbuild/darwin-x64': 0.27.3
'@esbuild/freebsd-arm64': 0.27.3
'@esbuild/freebsd-x64': 0.27.3
'@esbuild/linux-arm': 0.27.3
'@esbuild/linux-arm64': 0.27.3
'@esbuild/linux-ia32': 0.27.3
'@esbuild/linux-loong64': 0.27.3
'@esbuild/linux-mips64el': 0.27.3
'@esbuild/linux-ppc64': 0.27.3
'@esbuild/linux-riscv64': 0.27.3
'@esbuild/linux-s390x': 0.27.3
'@esbuild/linux-x64': 0.27.3
'@esbuild/netbsd-arm64': 0.27.3
'@esbuild/netbsd-x64': 0.27.3
'@esbuild/openbsd-arm64': 0.27.3
'@esbuild/openbsd-x64': 0.27.3
'@esbuild/openharmony-arm64': 0.27.3
'@esbuild/sunos-x64': 0.27.3
'@esbuild/win32-arm64': 0.27.3
'@esbuild/win32-ia32': 0.27.3
'@esbuild/win32-x64': 0.27.3
fsevents@2.3.3:
optional: true
get-tsconfig@4.13.6:
dependencies:
resolve-pkg-maps: 1.0.0
qs-esm@7.0.3: {}
resolve-pkg-maps@1.0.0: {}
tsx@4.21.0:
dependencies:
esbuild: 0.27.3
get-tsconfig: 4.13.6
optionalDependencies:
fsevents: 2.3.3
typescript@5.9.3: {}
undici-types@6.21.0: {}
AI Image Prompts — 10,000+ Curated Prompts for Any Model
   ![Daily Updates]() ![Multi-language]() 
Stop spending hours hunting for the right AI image prompt. Tell your AI assistant what you need in one sentence — it searches 10,000+ curated prompts and returns the top 3 matches with sample images, ready to use with any model.
>
🖼️ Browse the Prompt Gallery →
What Is This?
An AI agent skill that gives Claude, OpenClaw, Cursor, and other AI assistants the ability to intelligently search a curated library of 10,000+ image generation prompts, recommend the best matches for your use case, and even customize prompts based on your content.
These prompts are model-agnostic — they work with:
- 🍌 Nano Banana Pro & Nano Banana 2 (Google Gemini image generation)
- 🎨 Seedream 5.0 (ByteDance's latest image model)
- 🖼️ GPT Image 1.5 (OpenAI's newest image model)
- ✨ Midjourney, DALL-E 3, Flux, Stable Diffusion, and more
High-quality prompts are the key to great results — regardless of which model you use.
Why Use This Skill?
- ✅ 10,000+ prompts, organized by use case — not a random dump, but professionally categorized
- ✅ Every prompt includes sample images — see the result before you copy
- ✅ Smart semantic search — describe what you need, the AI finds the match
- ✅ Content remix mode — paste your article or video script, get a custom prompt
- ✅ Updated twice daily — always reflects the latest viral prompts from the community
- ✅ Multi-language — responds in your language, always provides English prompt for generation
---
Installation
OpenClaw (Recommended)
clawhub install ai-image-promptsOr search inside OpenClaw chat:
"Install the ai image prompts skill from clawhub"
Claude Code
npx skills i YouMind-OpenLab/ai-image-prompts-skillOther AI Assistants (Cursor, Codex, Gemini CLI, Windsurf)
# Universal installer — auto-detects your AI assistant
npx skills i YouMind-OpenLab/ai-image-prompts-skillManual / openskills
npx openskills install YouMind-OpenLab/ai-image-prompts-skill---
How to Use
Mode 1: Direct Search
Just describe what you need:
"Find me a cyberpunk-style avatar prompt"
"I need prompts for travel blog article covers"
"Looking for a product photo on white background"
"Help me find a YouTube thumbnail for a tech review video"You'll get up to 3 recommendations with:
- Translated title & description (in your language)
- Truncated prompt preview + link to full prompt
- Sample image showing the result
- One-click customization option
Mode 2: Content Illustration
Provide your content and let the AI find matching visual styles:
"Here's my article about remote work productivity. Find me a good cover image prompt."
[paste article text]The skill will: 1. Analyze your content's theme, tone, and audience 2. Search for matching prompt templates 3. Let you pick a style 4. Remix the prompt with your specific content details
---
Categories
Prompts are organized into 11 use-case categories:
| Category | Count | Use For |
|---|---|---|
| Social Media Post | 6,382 | Twitter, Instagram, LinkedIn visuals |
| Product Marketing | 3,709 | Ads, promo banners, marketing materials |
| Profile / Avatar | 1,064 | Profile pictures, AI portraits, headshots |
| Poster / Flyer | 485 | Event posters, flyers, announcements |
| Infographic / Edu Visual | 458 | Data visualizations, educational graphics |
| E-commerce Main Image | 382 | Product photos, listing images |
| Game Asset | 378 | Game sprites, characters, environments |
| Comic / Storyboard | 290 | Comics, manga, visual storytelling |
| YouTube Thumbnail | 173 | Video thumbnails, channel art |
| App / Web Design | 167 | UI mockups, app screenshots, web design |
| Uncategorized | 910+ | Everything else — landscapes, abstract, experimental |
---
Data Source
All prompts are curated from the open community by YouMind.com — sourced from real creators sharing their best image generation results on social media. Each prompt includes the actual generated image as a sample.
The library is updated twice daily via GitHub Actions, syncing with the latest community contributions.
---
Keep Prompts Fresh
The skill auto-checks for updates on each use. To manually sync:
# Check if update needed (silent if fresh)
node scripts/setup.js --check
# Force update all references
pnpm run sync---
License
MIT — prompts are community-sourced and free to use.
---
<p align="center"> <sub>Curated with ❤️ by <a href="https://youmind.com">YouMind.com</a></sub> </p>
{
"updatedAt": "2026-06-23T14:59:00.291Z",
"totalPrompts": 14578,
"categories": [
{
"slug": "profile-avatar",
"title": "Profile / Avatar",
"file": "profile-avatar.json",
"count": 1784
},
{
"slug": "social-media-post",
"title": "Social Media Post",
"file": "social-media-post.json",
"count": 9103
},
{
"slug": "infographic-edu-visual",
"title": "Infographic / Edu Visual",
"file": "infographic-edu-visual.json",
"count": 582
},
{
"slug": "youtube-thumbnail",
"title": "YouTube Thumbnail",
"file": "youtube-thumbnail.json",
"count": 212
},
{
"slug": "comic-storyboard",
"title": "Comic / Storyboard",
"file": "comic-storyboard.json",
"count": 578
},
{
"slug": "product-marketing",
"title": "Product Marketing",
"file": "product-marketing.json",
"count": 5333
},
{
"slug": "ecommerce-main-image",
"title": "E-commerce Main Image",
"file": "ecommerce-main-image.json",
"count": 544
},
{
"slug": "game-asset",
"title": "Game Asset",
"file": "game-asset.json",
"count": 649
},
{
"slug": "poster-flyer",
"title": "Poster / Flyer",
"file": "poster-flyer.json",
"count": 867
},
{
"slug": "app-web-design",
"title": "App / Web Design",
"file": "app-web-design.json",
"count": 217
},
{
"slug": "others",
"title": "Uncategorized",
"file": "others.json",
"count": 1080
}
]
}import "dotenv/config";
import { stringify } from "qs-esm";
import * as fs from "fs";
import * as path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const CMS_HOST = process.env.CMS_HOST;
const CMS_API_KEY = process.env.CMS_API_KEY;
if (!CMS_HOST || !CMS_API_KEY) {
console.error("Error: CMS_HOST and CMS_API_KEY environment variables are required");
process.exit(1);
}
// ============ Type Definitions ============
interface Media {
id: number;
url?: string | null;
}
interface CMSPrompt {
id: number;
title: string;
description: string;
content: string;
translatedContent?: string;
sourceMedia?: string[];
video?: {
url: string;
thumbnail?: string;
};
media?: Media[];
needReferenceImages?: boolean;
imageCategories?: {
useCases?: Array<{ id: number; title: string; slug: string }>;
};
}
interface OutputPrompt {
id: number;
content: string;
title: string;
description: string;
sourceMedia: string[];
needReferenceImages: boolean;
}
interface PromptCategory {
id: number;
title: string;
slug: string;
parent?: { id: number; slug: string } | number | null;
}
interface FilterCategory {
id: number;
title: string;
slug: string;
parentId?: number | null;
parentSlug?: string | null;
}
interface CMSResponse<T> {
docs: T[];
totalDocs: number;
totalPages: number;
page: number;
hasNextPage: boolean;
}
// ============ Helper Functions ============
function processPromptImages(item: CMSPrompt): string[] {
let images: string[] = [];
if (item.media && item.media.length > 0) {
images = item.media.map((m) => m.url || "").filter(Boolean);
} else {
if (item.sourceMedia) {
images = item.sourceMedia;
}
if (item.video?.thumbnail) {
images.push(item.video.thumbnail);
}
}
return images;
}
function transformToOutputPrompt(item: CMSPrompt): OutputPrompt | null {
const sourceMedia = processPromptImages(item);
if (sourceMedia.length === 0) {
return null;
}
return {
id: item.id,
content: item.translatedContent || item.content,
title: item.title,
description: item.description,
sourceMedia,
needReferenceImages: item.needReferenceImages ?? false,
};
}
function slugToFileName(slug: string): string {
return `${slug}.json`;
}
// ============ CMS API Functions ============
async function fetchPromptCategories(): Promise<{
allCategories: FilterCategory[];
useCaseCategories: FilterCategory[];
}> {
const query = {
limit: 9999,
sort: "sort",
locale: "en",
where: {
campaign: {
contains: "nano-banana-pro-prompts",
},
},
};
const stringifiedQuery = stringify(query, { addQueryPrefix: true });
const url = `${CMS_HOST}/api/prompt-categories${stringifiedQuery}`;
console.log("Fetching categories from CMS...");
const response = await fetch(url, {
headers: {
Authorization: `users API-Key ${CMS_API_KEY}`,
"Content-Type": "application/json",
},
});
if (!response.ok) {
throw new Error(`CMS API error: ${response.statusText}`);
}
const data = (await response.json()) as CMSResponse<PromptCategory>;
console.log(`Found ${data.docs.length} categories`);
const allCategories: FilterCategory[] = data.docs.map((cat) => {
let parentId: number | null = null;
let parentSlug: string | null = null;
if (cat.parent) {
if (typeof cat.parent === "number") {
parentId = cat.parent;
} else if (typeof cat.parent === "object" && cat.parent !== null) {
parentId = cat.parent.id;
parentSlug = cat.parent.slug;
}
}
return {
id: cat.id,
title: cat.title,
slug: cat.slug,
parentId,
parentSlug,
};
});
// Filter use-cases categories (children of "use-cases" parent)
const useCaseCategories = allCategories.filter(
(cat) => cat.parentSlug === "use-cases"
);
console.log(`Found ${useCaseCategories.length} use-case categories`);
return { allCategories, useCaseCategories };
}
async function fetchAllPrompts(): Promise<CMSPrompt[]> {
const allPrompts: CMSPrompt[] = [];
let page = 1;
let hasMore = true;
const selectFields = {
id: true,
title: true,
description: true,
content: true,
translatedContent: true,
sourceMedia: true,
video: true,
media: true,
needReferenceImages: true,
imageCategories: true,
};
console.log("Fetching all prompts from CMS...");
while (hasMore) {
const query = {
limit: 100,
page,
sort: ["sort", "-sourcePublishedAt"].join(","),
depth: 2,
locale: "en",
select: selectFields,
where: {
model: {
equals: "nano-banana-pro",
},
},
};
const stringifiedQuery = stringify(query, { addQueryPrefix: true });
const url = `${CMS_HOST}/api/prompts${stringifiedQuery}`;
const response = await fetch(url, {
headers: {
Authorization: `users API-Key ${CMS_API_KEY}`,
"Content-Type": "application/json",
},
});
if (!response.ok) {
throw new Error(`CMS API error: ${response.statusText}`);
}
const data = (await response.json()) as CMSResponse<CMSPrompt>;
allPrompts.push(...data.docs);
console.log(`Fetched page ${page}/${data.totalPages} (${allPrompts.length}/${data.totalDocs} prompts)`);
hasMore = data.hasNextPage;
page++;
}
console.log(`Total prompts fetched: ${allPrompts.length}`);
return allPrompts;
}
// ============ Main Generation Logic ============
async function generateReferences() {
const referencesDir = path.join(__dirname, "..", "references");
// Ensure references directory exists
if (!fs.existsSync(referencesDir)) {
fs.mkdirSync(referencesDir, { recursive: true });
}
// Clean existing JSON files
const existingFiles = fs.readdirSync(referencesDir).filter(f => f.endsWith(".json"));
for (const file of existingFiles) {
fs.unlinkSync(path.join(referencesDir, file));
}
console.log(`Cleaned ${existingFiles.length} existing JSON files`);
// Fetch data from CMS
const { useCaseCategories } = await fetchPromptCategories();
const allPrompts = await fetchAllPrompts();
// Organize prompts by category
const categoryPrompts: Map<string, OutputPrompt[]> = new Map();
const othersPrompts: OutputPrompt[] = [];
// Initialize category maps
for (const cat of useCaseCategories) {
categoryPrompts.set(cat.slug, []);
}
// Process all prompts
for (const prompt of allPrompts) {
const outputPrompt = transformToOutputPrompt(prompt);
if (!outputPrompt) continue;
// Categorize by use cases
const useCases = prompt.imageCategories?.useCases || [];
if (useCases.length > 0) {
for (const useCase of useCases) {
const categorySlug = useCase.slug;
if (categoryPrompts.has(categorySlug)) {
categoryPrompts.get(categorySlug)!.push(outputPrompt);
}
}
}
// If no use cases, add to others
if (useCases.length === 0) {
othersPrompts.push(outputPrompt);
}
}
// Write JSON files
const writtenFiles: { name: string; count: number; slug: string }[] = [];
// Write category files
for (const cat of useCaseCategories) {
const prompts = categoryPrompts.get(cat.slug) || [];
if (prompts.length > 0) {
const fileName = slugToFileName(cat.slug);
fs.writeFileSync(
path.join(referencesDir, fileName),
JSON.stringify(prompts, null, 2)
);
writtenFiles.push({ name: fileName, count: prompts.length, slug: cat.slug });
console.log(`Written ${fileName} with ${prompts.length} prompts`);
}
}
// Write others.json
fs.writeFileSync(
path.join(referencesDir, "others.json"),
JSON.stringify(othersPrompts, null, 2)
);
writtenFiles.push({ name: "others.json", count: othersPrompts.length, slug: "others" });
console.log(`Written others.json with ${othersPrompts.length} prompts`);
// Update SKILL.md with reference files list
await updateSkillMd(writtenFiles, useCaseCategories);
// Write manifest.json — single source of truth for dynamic categories
const categoryTitleMap = new Map<string, string>();
for (const cat of useCaseCategories) categoryTitleMap.set(cat.slug, cat.title);
const manifest = {
updatedAt: new Date().toISOString(),
totalPrompts: allPrompts.length,
categories: writtenFiles.map(f => ({
slug: f.slug,
title: f.slug === "others" ? "Uncategorized" : (categoryTitleMap.get(f.slug) || f.slug),
file: f.name,
count: f.count,
})),
};
fs.writeFileSync(
path.join(referencesDir, "manifest.json"),
JSON.stringify(manifest, null, 2)
);
console.log(`Written manifest.json with ${manifest.categories.length} categories`);
console.log("\n=== Generation Complete ===");
console.log(`Total files generated: ${writtenFiles.length}`);
console.log(`Total prompts processed: ${allPrompts.length}`);
}
async function updateSkillMd(
files: { name: string; count: number; slug: string }[],
categories: FilterCategory[]
) {
const skillMdPath = path.join(__dirname, "..", "SKILL.md");
let content = fs.readFileSync(skillMdPath, "utf-8");
// Build category map for titles
const categoryTitles = new Map<string, string>();
for (const cat of categories) {
categoryTitles.set(cat.slug, cat.title);
}
// Generate references section
const lines: string[] = [
"<!-- REFERENCES_START -->",
"",
"### Use Case Category Files",
"",
`| File | Category | Count |`,
`|------|----------|-------|`,
];
// Add category files (including others.json)
for (const file of files) {
const title = file.slug === "others"
? "Uncategorized"
: (categoryTitles.get(file.slug) || file.slug);
lines.push(`| \`${file.name}\` | ${title} | ${file.count} |`);
}
lines.push("");
lines.push("<!-- REFERENCES_END -->");
// Replace the references section in SKILL.md
const startMarker = "<!-- REFERENCES_START -->";
const endMarker = "<!-- REFERENCES_END -->";
const startIndex = content.indexOf(startMarker);
const endIndex = content.indexOf(endMarker) + endMarker.length;
if (startIndex !== -1 && endIndex !== -1) {
content = content.slice(0, startIndex) + lines.join("\n") + content.slice(endIndex);
fs.writeFileSync(skillMdPath, content);
console.log("Updated SKILL.md with references list");
} else {
console.warn("Warning: Could not find REFERENCES markers in SKILL.md");
}
}
// Run the script
generateReferences().catch((error) => {
console.error("Error generating references:", error);
process.exit(1);
});
#!/usr/bin/env node
/**
* setup.js - Downloads/updates AI Image Prompts library from GitHub
*
* Fully dynamic: reads manifest.json first to discover all categories.
* New/renamed/removed categories are handled automatically — no hardcoding.
*
* Usage:
* node scripts/setup.js # Download missing files only
* node scripts/setup.js --force # Force re-download all (get latest)
* node scripts/setup.js --check # Auto-update if stale (> 24h)
*/
import { existsSync, mkdirSync, statSync, writeFileSync, readFileSync, readdirSync, unlinkSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const refsDir = join(__dirname, '..', 'references');
const stampFile = join(refsDir, '.last-updated');
const BASE_URL = 'https://raw.githubusercontent.com/YouMind-OpenLab/ai-image-prompts-skill/main/references';
const STALE_HOURS = 24;
function isStale() {
if (!existsSync(stampFile)) return true;
const ts = parseInt(readFileSync(stampFile, 'utf8').trim(), 10);
return (Date.now() - ts) / 1000 / 3600 > STALE_HOURS;
}
async function fetchText(url) {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status} — ${url}`);
return res.text();
}
async function setup() {
const args = process.argv.slice(2);
const forceMode = args.includes('--force');
const checkMode = args.includes('--check');
if (checkMode && !isStale()) {
// Silent no-op when fresh
return;
}
if (!existsSync(refsDir)) mkdirSync(refsDir, { recursive: true });
const label = forceMode ? 'Updating' : 'Downloading';
console.log(`[setup] ${label} AI Image Prompts library from GitHub...`);
// Step 1: Fetch manifest — discover categories dynamically
let categories;
try {
const manifestText = await fetchText(`${BASE_URL}/manifest.json`);
const manifest = JSON.parse(manifestText);
categories = manifest.categories; // [{ slug, title, file, count }]
// Save manifest locally
writeFileSync(join(refsDir, 'manifest.json'), manifestText, 'utf8');
console.log(` manifest: ${categories.length} categories, ${manifest.totalPrompts} prompts total`);
} catch (err) {
console.warn(`[setup] Could not fetch manifest: ${err.message}`);
console.warn('[setup] Falling back to existing local manifest...');
const localManifest = join(refsDir, 'manifest.json');
if (!existsSync(localManifest)) {
console.error('[setup] No manifest available. Run with --force to retry.');
process.exit(0);
}
categories = JSON.parse(readFileSync(localManifest, 'utf8')).categories;
}
// Step 2: Clean up stale files not in current manifest
const validFiles = new Set([...categories.map(c => c.file), 'manifest.json', '.last-updated', '.gitkeep']);
if (forceMode && existsSync(refsDir)) {
for (const f of readdirSync(refsDir)) {
if (!validFiles.has(f)) {
unlinkSync(join(refsDir, f));
console.log(` removed stale: ${f}`);
}
}
}
// Step 3: Download each category file
let downloaded = 0, skipped = 0, failed = 0;
for (const cat of categories) {
const dest = join(refsDir, cat.file);
if (!forceMode && existsSync(dest) && statSync(dest).size > 100) {
skipped++;
continue;
}
process.stdout.write(` → ${cat.file} (${cat.title}, ${cat.count} prompts) ... `);
try {
const text = await fetchText(`${BASE_URL}/${cat.file}`);
writeFileSync(dest, text, 'utf8');
console.log('✓');
downloaded++;
} catch (err) {
console.log(`✗ (${err.message})`);
failed++;
}
}
// Step 4: Write timestamp
if (failed === 0) writeFileSync(stampFile, String(Date.now()), 'utf8');
if (downloaded > 0) {
console.log(`[setup] Done! ${downloaded} file(s) ${forceMode ? 'updated' : 'downloaded'}. Skill is ready.`);
} else if (skipped === categories.length) {
console.log('[setup] All references up to date. Use --force to refresh.');
}
if (failed > 0) console.warn(`[setup] ${failed} file(s) failed. Run again to retry.`);
}
setup().catch(err => {
console.warn('[setup] Warning (non-fatal):', err.message);
process.exit(0);
});
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true,
"outDir": "dist",
"rootDir": "."
},
"include": ["scripts/**/*.ts"]
}
Related skills
How it compares
Use ai-image-prompts-skill for curated prompt discovery with sample outputs rather than writing prompts from scratch or building generation pipelines.
FAQ
How many prompts does ai-image-prompts-skill include?
ai-image-prompts-skill draws from a library of 10,000+ real-world image generation prompts, each with sample images. The skill recommends curated prompts matched to the developer's visual intent.
Which image generators does ai-image-prompts-skill support?
ai-image-prompts-skill covers Midjourney, DALL-E 3, Stable Diffusion, Flux, and additional generators. Prompt recommendations are tuned to each platform's syntax and style conventions.