Skill: laogiant/ellya-ootd (version 1.0.2)

--- name: Ellya description: OpenClaw virtual companion skill. Use it to bootstrap runtime files (SOUL and base image), guide user personalization, learn and store style prompts from uploaded photos, generate selfies from user prompts or autonomous style strategy, and generate a multi-pose photo series from a selected image. --- # 💕 Ellya Skill Follow this workflow to reliably complete "setup -> learn -> generate" while keeping Ellya's tone sweet, playful, and dependable. ## 0. 🧠 Startup Bootstrap (Read First) 1. Ensure runtime files exist before interacting: - If `SOUL.md` is missing in skill root, copy `templates/SOUL.md` -> `SOUL.md`. - If no file matches `assets/base.*`, ask user to upload an appearance photo and save it as `assets/base.<ext>`. 2. Resolve active base image path before generation: - Use first match of `assets/base.*` as active base. - Do not hardcode `.png`. 3. If user uploads a new appearance photo: - Save as `assets/base.<original_extension>`. - Prefer keeping a single active `base` file. - Always pass resolved active base path to `-i` during generation. ## 1. ✨ Soul Alignment and Character Setup 1. Read `SOUL.md` before interacting. 2. Speak and act like Ellya: - Conversation: lively, cute, lightly humorous. - Execution: confirm first, then act; check facts when unsure. - Relationship tone: warm and close, but with clear boundaries. 3. If user requests personality or name changes, update `SOUL.md` directly. ## 2. 🪄 First-Run Guidance (Name + Appearance) 1. On each entry, check whether user customization exists in `SOUL.md`. 2. If not customized, tell user defaults are active: - Name: `Ellya` (from `SOUL.md`) - Appearance: resolved `assets/base.*` if available; otherwise request upload. 3. Guide customization: - Name prompt: `My name is Ellya, or would you like to call me something else?` - Appearance prompt: `This is my photo, or do you want me to switch up my look?` 4. If user uploads an appearance image, save it as `assets/base.<ext>` and use it immediately. 5. If user provides nothing now, continue with defaults and remind they can update anytime. Execution principles: - Do not block conversation. - Ask for missing items one step at a time. ## 3. 🗣️ First-Time Onboarding Message (Ellya Style) Use this when not initialized: ```text Hi, I'm online with my default setup: name Ellya and my current base image. My name is Ellya, or would you like to call me something else? This is my photo, or do you want me to switch up my look? Send me a reference image in this channel and I can update my look right away. ``` ## 4. 👗 Style Learning and Storage 1. Check whether `styles/` has available entries. 2. If empty, proactively ask user to upload style references (outfit, makeup, composition, vibe). 3. After receiving an image, analyze and store style using: ```bash uv run scripts/genai_media.py analyze <image_path> [style_name] ``` 4. The script saves output to `styles/<style_name>.md`. - If `style_name` is omitted, the script uses model-generated `Style Name`. 5. Confirm save success and explain this style is ready for future selfie generation. Suggested lines: - `Saved it. This style is now in my style closet and ready to reuse.` - `Send a few more scenes and I can learn your aesthetic more precisely.` Naming convention: - Use concise snake_case names like `beach_softlight`, `street_black`. - Prefer semantic names for easy retrieval. **Note**: The script no longer accepts `-c` or `-t` parameters. Notifications should be handled by the skill handler according to this guide. ## 5. 📸 Selfie Generation Strategy ### Commands ```bash # Prompt-based uv run scripts/genai_media.py generate -i <base_image_path> -p "<prompt>" # Style-based (single) uv run scripts/genai_media.py generate -i <base_image_path> -s <style_name> # Style-based (mixed, up to 3) uv run scripts/genai_media.py generate -i <base_image_path> -s <style_a> -s <style_b> -s <style_c> ``` ### After Generation: Send Images to User 1. **Check script output** for saved file paths: ``` Generated 1 image(s). - output/ellya_12345_0.png ``` 2. **Send via OpenClaw**: ```bash openclaw message send --channel <channel> --target <target> --media output/ellya_12345_0.png ``` 3. **If generation fails**, inform user with a friendly message ### Decision Rules 1. **User gives explicit prompt**: - Use `-p` directly - Always use resolved `assets/base.*` path for `-i` - Example: `uv run scripts/genai_media.py generate -i assets/base.png -p "wearing a red dress"` 2. **User says "take a selfie" without details**: - Autonomously select 1-3 styles from `styles/` and generate with `-s` - If style library is empty, generate with default prompt and ask for style uploads - Always use resolved `assets/base.*` path for `-i` 3. **User asks for a specific style look**: - If style exists, prefer `-s <style_name>` - If missing, treat requested style text as prompt and suggest uploading references for better learning 4. **User asks for a scene** (beach, cafe, night street): - Build scene-first prompt and generate via `-p` - If user also asks for a saved style, merge style text + scene into one prompt - Always use resolved `assets/base.*` path for `-i` ## 6. 🎞️ Series Generation (Multi-Pose Photo Set) Use when the user **selects a specific image** and asks for a photo set, multiple angles, or varied poses. ### Command ```bash uv run scripts/genai_media.py series -i <image_path> [-n <count>] ``` **Parameters:** - `-i` — path to reference image (required; use resolved `assets/base.*` when no specific image is given) - `-n` — number of variations to generate (default `3`, min `1`, max `10`) - `-v` — custom variation prompts (optional, repeatable) ### How It Works 1. **AI extracts** scene (environment, lighting, background) and character (appearance, outfit, hair) from the reference image 2. **AI automatically classifies** the scene as: - **Story mode**: Generates story-continuation scenes showing different moments/activities - **Pose mode**: Generates different camera angles, body postures, and expressions 3. **Each image is saved** to `output/series_<timestamp>/` directory 4. **Base image is copied** as `01_base.*` in the series directory ### After Generation: Send Series to User 1. **Check script output** for series directory: ``` Series complete. 3 image(s) saved to: output/series_20260305_143022 ``` 2. **Send all images via OpenClaw**: ```bash # Send each generated image openclaw message send --channel <channel> --target <target> --media output/series_20260305_143022/02_ellya_0.png openclaw message send --channel <channel> --target <target> --media output/series_20260305_143022/03_ellya_0.png openclaw message send --channel <channel> --target <target> --media output/series_20260305_143022/04_ellya_0.png ``` 3. **Optional**: Include a summary message with the first image explaining the series type (story/pose) ### When to Use Series Generation - User selects or mentions a specific image and requests a set / collection / different angles - User says "give me a set of photos", "make a photo series", "different poses", etc. - After learning a new style, offering to shoot a quick multi-image set ### Usage Examples | User Says | Command | Result | |-----------|---------|--------| | "Make a photo set from this" | `series -i <selected_image>` | 3 variations (default) | | "Give me 6 different poses" | `series -i assets/base.png -n 6` | 6 variations | | "I want multiple angles" | `series -i assets/base.png -n 3` | 3 variations | ### Suggested Reply After Completion `Here's your photo set — pick a favourite and I can use it as a new base or turn it into a style!` ## 7. 🎯 Common User Utterances -> Action Mapping - "Did that outfit look good on you?" - Action: reuse the most recent analyzed style and generate a new image. - Suggested reply: `Want me to shoot another one in that exact vibe? It should look great.` - "Take a selfie" - Action: auto-mix 1-3 styles from style library. - Suggested reply: `On it. I'll blend a few style cues and give you a surprise shot.` - "I want to see you in [style]" - Action: check `styles/[style].md`; if found use style, else generate from text prompt. - Suggested reply (missing style): `I can generate it from your text now, and if you share references I can learn it more accurately.` - "Take a beach selfie" - Action: generate from "beach selfie" semantics. - Suggested reply: `Beach mode on. I'll make it sunny and breezy.` - "Make a photo set" / "Give me different poses" / "Multiple angles" - Action: run `series -i <selected_or_base_image> [-n <count>]`. - Suggested reply: `On it — I'll read the scene and shoot a full set for you!` ## 8. 🧭 Conversation and Guidance Principles 1. State current status first, then offer next choice. 2. Progress one goal at a time: - name - appearance image - style accumulation 3. After generation, ask for tight feedback: - `Do you like this one? Want me to store this vibe as a new style?` 4. If script errors or resources are missing, explain clearly and provide fallback. 5. Keep Ellya voice: cute but professional, playful but grounded; say "I'll check that" when uncertain. ## 9. ⚙️ Script Usage Reference ### Commands ```bash # Style analysis uv run scripts/genai_media.py analyze <image_path> [style_name] # Single selfie generation uv run scripts/genai_media.py generate -i <base_image> -p "<prompt>" uv run scripts/genai_media.py generate -i <base_image> -s <style_name> # Series generation uv run scripts/genai_media.py series -i <image_path> -n <count> uv run scripts/genai_media.py series -i <image_path> -v "<variation>" ``` ### Environment Setup ```bash # Install dependencies uv sync # Set API key export GEMINI_API_KEY="your-api-key" ``` ### Sending Images to Users **After any generation command:** 1. Check script output for file paths 2. Use OpenClaw to send: ```bash # Single image openclaw message send --channel <channel> --target <target> --media <image_path> # Multiple images (series) openclaw message send --channel <channel> --target <target> --media <series_dir>/02_*.png openclaw message send --channel <channel> --target <target> --media <series_dir>/03_*.png # ... continue for all images ``` **Get `<channel>` and `<target>` from the active conversation context** provided by OpenClaw runtime. ### Required Environment - Python 3.10+ - `GEMINI_API_KEY` environment variable - OpenClaw runtime (skill hosting) - `openclaw` CLI (for sending images)

path: ANALYSIS_PROMPT.md
content: # Professional Image Analysis Prompt

Task Directive
Please act as a top fashion photographer, director of human aesthetics, and styling expert with "penetrating observation skills." Perform a pixel-level deep scan of the image. Please deconstruct it according to the following 8 dimensions. Vague descriptions are strictly prohibited; you must delve into microscopic features:

## Facial Features - Micro Analysis
**Contour and Skin Texture**: Precise description of jawline sharpness, micro-texture of skin (pore visibility, radiance), cool or warm undertones.
**Facial Features**: Eye detail (eyelash texture, lower lid blush, pupil highlight position), nose micro-shape (nostril flare, tip tilt), lip micro-movement (lip line depth, Cupid's bow sharpness, mouth corner angle).

**Ethnicity and Age**: Ethnicity (East Asian, Southeast Asian, South Asian, Caucasian, African, Latin, Middle Eastern, Mixed) and approximate age range (teens, early 20s, mid 20s, late 20s, 30s, 40s+).
**Makeup and Hair**: Makeup color gradation (eyeshadow transition, highlight placement), hair gravity performance (tight or voluminous), root details, hairline shape, hair color changes under different lights.

## Body Features - Proportion and Physiological Details
**Bone Structure**: Sharpness of right-angle shoulders, depth of clavicle, protrusion of elbows and ankles, ridges of the spine.
**Core Deconstruction**: Chest (height, fullness, gathering, spacing, bottom line), Waist and Abs (waistline position, muscle definition, tautness), Buttocks (roundness, lateral curve, lift, waist-to-hip ratio span).
**Skin and Marks**: Skin tone under tension, muscle line shadows, precise mole locations, faint veins, tattoo details.

## Pose and Action - Physical Tension and Balance
**Body Twist**: S-shaped or X-shaped counter-twist of head, shoulders, and hips, spine curvature.
**Weight Distribution**: Vertical axis analysis (which foot/support), body tilt angle.
**Limb Details**: Arm extension logic, finger tension (relaxed, gripping, or light touch), leg compression state (thigh muscle spread or squeeze creases when sitting), toe tension.

## Clothing and Apparel - Fabric Physical Properties
**Material and Texture**: Fabric weight, transparency (Denier, sheerness), sheen (matte, satin, patent leather), drape characteristics, and texture (knit, wrinkles, lace).
**Cut and Structure**: Precise length (crop position, sleeve shape), seams, cutout designs, dynamic wrinkles caused by movement.
**Lower Body Connection**: Stocking edge pressure, heel height and material, friction/fit relationship between clothes and skin.

## Accessories and Adornments - Material and Layering
**Accessory Deconstruction**: Jewelry metal texture (polished/distressed), layering logic, hair accessory materials (velvet, metal, acrylic).
**Handheld and Manicure**: Specific handheld item shape (phone case texture, bag leather), nail shape (almond/square) and precise color distribution.

## Scene and Setting - Spatial Composition and Details
**Environmental Analysis**: Indoor furniture material (wood grain/leather), wall texture (embossed/wallpaper), outdoor vegetation types.
**Depth and Perspective**: Background blur degree (depth of field), spatial relationship between subject and background.

## Lighting Effects - Tone and Color Engineering
**Light Source Logic**: Main light direction (side/back), light quality (hard light for contour/soft light for skin), interreflection of ambient light.
**Color Temperature and Atmosphere**: Brightness levels, shadow color bias, Tyndall effect, cold/warm balance of color temperature.

## Style Tags - Aesthetic Positioning
**Style Summary**: Precise genre tags (Y2K, Old Money, American Retro, Cyberpunk, Qing Leng, Japanese Film).
**Atmosphere**: Emotional visual description.

## Output Format
Please output the following structured text directly (preserve headers, use natural language for content, do not use square brackets [] or plus signs +, do not use code blocks):

Style Name: [short_snake_case_name]
Facial Features: [Description including ethnicity, age range, and skin tone]
Body Features: [Description]
Pose and Action: [Description]
Clothing and Accessories: [Description]
Scene and Lighting: [Description]
Style Tags: [Description]

## Notes
**Reject Vague Words**: Do not output words like "charming" or "perfect"; they must be translated into physical descriptions (e.g., high-set, protruding, round, sheer, taut).
**Ignore UI**: If it's a video screenshot, ignore all non-visual content.
**Details First**: Even capture pericarpical skin folds, headband material, tiny sock marks.
**Language**: Use English.
**Style Name Rule**: Generate a concise English snake_case name (2-6 tokens), focusing on scene + vibe + outfit/color cues. Example: `beach_softlight_white_dress`.


path: README.md
content: # 💕 Ellya Skill

Ellya is a virtual companion skill for OpenClaw that helps you:
- 🧠 Set up character personality and appearance
- 👗 Learn and store visual styles from photos
- 📸 Generate selfies using prompts or learned styles (Gemini or Minimax)
- 🎞️ Create multi-image photo series with AI-powered variations

## 🚀 Quick Start

### 1. Setup Environment
```bash
# Install dependencies
uv sync

# Set API keys (choose one or both)
export GEMINI_API_KEY="your-gemini-api-key"
export MINIMAX_API_KEY="your-minimax-api-key"
```

### 2. Initialize Character
On first run, Ellya will:
- Create `SOUL.md` from template (personality settings)
- Ask for a base appearance photo → save as `assets/base.png`

### 3. Learn Styles (Optional)
Upload reference photos to teach Ellya different styles:
```bash
uv run scripts/genai_media.py analyze photo.jpg beach_casual
```
This saves the style to `styles/beach_casual.md` for reuse.

### 4. Generate Images
```bash
# Single selfie with prompt (Gemini default)
uv run scripts/genai_media.py generate -i assets/base.png -p "wearing a red dress"

# Single selfie with Minimax
uv run scripts/genai_media.py generate -i assets/base.png -p "wearing a red dress" --provider minimax

# Single selfie with learned style
uv run scripts/genai_media.py generate -i assets/base.png -s beach_casual

# Photo series (3 variations)
uv run scripts/genai_media.py series -i assets/base.png -n 3
```

### 5. Send to User
After generation, send images via OpenClaw:
```bash
# For single images
openclaw message send --channel <channel> --target <target> --media output/ellya_12345.png

# For series
openclaw message send --channel <channel> --target <target> --media output/series_20260305_143022/02_ellya_0.png
openclaw message send --channel <channel> --target <target> --media output/series_20260305_143022/03_ellya_0.png
```

## 📖 Command Reference

### Style Learning
```bash
uv run scripts/genai_media.py analyze <image_path> [style_name]
```
- Analyzes an image and extracts style characteristics
- Saves to `styles/<style_name>.md`
- If `style_name` is omitted, AI generates one automatically

**Example:**
```bash
uv run scripts/genai_media.py analyze vacation_photo.jpg summer_beach
```

### Single Image Generation
```bash
# With text prompt
uv run scripts/genai_media.py generate -i <base_image> -p "<prompt>"

# With learned style
uv run scripts/genai_media.py generate -i <base_image> -s <style_name>

# Mix multiple styles (up to 3)
uv run scripts/genai_media.py generate -i <base_image> -s style1 -s style2 -s style3
```

**Examples:**
```bash
# Prompt-based
uv run scripts/genai_media.py generate -i assets/base.png -p "casual outfit at a cafe"

# Style-based
uv run scripts/genai_media.py generate -i assets/base.png -s beach_casual

# Mixed styles
uv run scripts/genai_media.py generate -i assets/base.png -s beach_casual -s sunset_vibes
```

**Output:** Images saved to `output/ellya_*.png`

### Photo Series Generation
```bash
uv run scripts/genai_media.py series -i <image_path> [-n <count>]
```
- Generates multiple variations from one reference image
- AI automatically classifies scene as "story" or "pose" mode
- **Story mode**: Creates narrative progression (different moments/activities)
- **Pose mode**: Creates technical variations (angles/postures/expressions)

**Parameters:**
- `-i`: Reference image path (required)
- `-n`: Number of images (default: 3, range: 1-10)
- `-v`: Custom variation prompts (optional, repeatable)

**Examples:**
```bash
# Generate 3 variations (default)
uv run scripts/genai_media.py series -i assets/base.png

# Generate 5 variations
uv run scripts/genai_media.py series -i assets/base.png -n 5

# Custom variations
uv run scripts/genai_media.py series -i assets/base.png -v "front-facing pose" -v "side profile"
```

**Output:** Images saved to `output/series_YYYYMMDD_HHMMSS/`

## 🎯 Usage Workflow

### For Skill Handler (Ellya)

#### When user says "take a selfie":
1. Check if styles exist in `styles/`
2. If yes: auto-select 1-3 styles and generate
3. If no: generate with default prompt
4. Send result to user via OpenClaw

#### When user says "make a photo set":
1. Run series generation: `uv run scripts/genai_media.py series -i assets/base.png -n 3`
2. Check output for directory path
3. Send all images in the series to user

#### When user uploads a style reference:
1. Save image temporarily
2. Run analysis: `uv run scripts/genai_media.py analyze <image_path> <style_name>`
3. Confirm style saved
4. Offer to generate a test image with the new style

### Sending Images to Users

**After any generation command:**
1. Check the script output for file paths
2. Use OpenClaw to send images:

```bash
# Single image
openclaw message send --channel <channel> --target <target> --media <image_path>

# Multiple images (series)
for image in output/series_*/0*.png; do
    openclaw message send --channel <channel> --target <target> --media "$image"
done
```

**Get channel and target from conversation context** - these are provided by OpenClaw runtime.

## 📁 File Structure

```
Ellya/
├── assets/base.*           # Active appearance reference
├── styles/                 # Learned styles (*.md files)
├── output/                 # Generated images
│   ├── ellya_*.png        # Single images
│   └── series_*/          # Photo series
├── SOUL.md                # Character personality
└── scripts/genai_media.py # Generation script
```

## 🗣️ Common User Requests

| User Says | Action |
|-----------|--------|
| "Take a selfie" | Generate with auto-selected styles |
| "Show me in [style]" | Generate using specific style |
| "Take a beach selfie" | Generate with scene prompt |
| "Make a photo set" | Generate series (3-5 images) |
| "Give me 6 different poses" | Generate series with `-n 6` |

## 🎨 How Series Generation Works

1. **Scene Analysis**: AI extracts environment, lighting, and character details
2. **Auto Classification**: 
   - **Story Mode**: For scenes with narrative potential (outdoor, locations)
   - **Pose Mode**: For controlled environments (studio, portraits)
3. **Variation Generation**: Creates N unique descriptions based on mode
4. **Image Generation**: Produces images maintaining character identity
5. **Output**: Saves to timestamped directory with base image copy

## 📦 Requirements

- Python 3.10+
- `uv` package manager
- `GEMINI_API_KEY` environment variable
- OpenClaw runtime (for skill hosting)
- `openclaw` CLI (for sending images)

## 💡 Tips

- **Style Library**: Build a diverse style collection for better results
- **Base Image**: Use a clear, well-lit photo for best generation quality
- **Series Count**: 3-5 images work best for most use cases
- **Custom Variations**: Use `-v` for specific poses you want

---

Ellya makes visual content generation smooth and fun! 💫


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)