---
name: demo-skill
description: Learn how to create demo skills - executable skills that do something impressive quickly and are undo-able so they can be run many times for demos.
compatibility: Created for Zo Computer
metadata:
  author: rob.zo.computer
---

# Demo Skill

Learn how to create demo skills - executable skills that do something impressive quickly and are undo-able so they can be run many times for demos.

## What is a demo skill?

A demo skill is an executable skill that:
- **Does something impressive quickly** - Creates visible, impactful results
- **Is undo-able** - Can be cleaned up and rerun without side effects
- **Is repeatable** - Can be run many times for different demos
- **Is self-contained** - Has clear boundaries for what it creates/changes

## Key principles

### 1. Clear boundaries

Define exactly what the skill creates:
- Files it generates
- Routes it adds
- Data it processes
- Side effects it has

### 2. Undo-ability

Provide a way to clean up:
- List all created files
- Provide cleanup commands
- Make cleanup easy and safe

### 3. Impressive results

Create something that:
- Looks good visually
- Tells a story
- Has interactive elements
- Demonstrates capabilities

### 4. Fast execution

- Should complete in seconds
- No long-running processes
- No external dependencies that might fail

## Demo skill structure

```
Skills/<skill-name>/
├── SKILL.md              # This file - documentation
├── README.md             # Quick-start guide
├── scripts/
│   ├── run-skill.py      # Main execution script
│   └── cleanup.py        # Cleanup script
├── assets/
│   └── templates/        # Templates for generated files
└── references/
    └── patterns.md       # Common patterns and examples
```

## Example: demo-research skill

The `demo-research` skill is a complete example:

**What it creates:**
- Data files: `web/scratch/src/data/usa_energy/*.json`
- Page component: `web/scratch/src/pages/UsaEnergy.tsx`
- Route: `/usa-energy` in `App.tsx`

**How to run:**
```bash
python Skills/demo-research/scripts/run-skill.py
```

**How to clean up:**
```bash
rm -rf web/scratch/src/data/usa_energy
rm web/scratch/src/pages/UsaEnergy.tsx
```

**What it does:**
1. Generates JSON data from DuckDB
2. Creates React page with charts
3. Adds route to application
4. Verifies page works

## Creating your own demo skill

### Step 1: Define the scope

What will your demo skill create?

**Good examples:**
- A data visualization page
- An interactive calculator
- A dashboard with charts
- A story-telling notebook

**Define:**
- What files will be created?
- What routes will be added?
- What data will be processed?
- What will the user see?

### Step 2: Create the skill structure

```bash
mkdir -p Skills/my-demo-skill/{scripts,assets,references}
```

### Step 3: Write the main script

Create `scripts/run-skill.py`:

```python
#!/usr/bin/env python3
"""
My Demo Skill - Main execution script

This script creates [describe what it creates].
"""

import sys
from pathlib import Path

# Define what this skill creates
CREATED_FILES = [
    "web/scratch/src/data/my-demo/data.json",
    "web/scratch/src/pages/MyDemo.tsx",
]

def main():
    print("Running my demo skill...")
    
    # 1. Generate data
    print("Generating data...")
    # ... your code here
    
    # 2. Create page
    print("Creating page...")
    # ... your code here
    
    # 3. Add route
    print("Adding route...")
    # ... your code here
    
    # 4. Verify
    print("Verifying...")
    # ... your code here
    
    print("Done!")
    print(f"Created files: {CREATED_FILES}")

if __name__ == "__main__":
    main()
```

### Step 4: Write the cleanup script

Create `scripts/cleanup.py`:

```python
#!/usr/bin/env python3
"""
Cleanup script for my demo skill
"""

import sys
from pathlib import Path

FILES_TO_DELETE = [
    "web/scratch/src/data/my-demo/data.json",
    "web/scratch/src/pages/MyDemo.tsx",
]

def main():
    print("Cleaning up my demo skill...")
    
    for file_path in FILES_TO_DELETE:
        path = Path(file_path)
        if path.exists():
            if path.is_dir():
                import shutil
                shutil.rmtree(path)
                print(f"Removed directory: {file_path}")
            else:
                path.unlink()
                print(f"Removed file: {file_path}")
        else:
            print(f"Already removed: {file_path}")
    
    print("Cleanup complete!")

if __name__ == "__main__":
    main()
```

### Step 5: Create templates

Create template files in `assets/templates/`:

```tsx
// assets/templates/MyDemoTemplate.tsx
import React from "react";
import NotebookTemplate from "@/components/NotebookTemplate";

export default function MyDemo() {
  return (
    <NotebookTemplate
      title="My Demo"
      subtitle="An impressive demo"
    >
      {/* Your content here */}
    </NotebookTemplate>
  );
}
```

### Step 6: Write documentation

Create `SKILL.md` (this file) and `README.md`:

```markdown
# My Demo Skill

Quick-start guide for running my demo skill.

## Quick start

```bash
python Skills/my-demo-skill/scripts/run-skill.py
```

## Cleanup

```bash
python Skills/my-demo-skill/scripts/cleanup.py
```

## What it creates

- Data files: `web/scratch/src/data/my-demo/*.json`
- Page component: `web/scratch/src/pages/MyDemo.tsx`
- Route: `/my-demo`
```

### Step 7: Test and iterate

1. Run the skill
2. Verify it works
3. Clean up
4. Run again
5. Repeat until it's reliable

## Common patterns

### Pattern 1: Data generation

Generate JSON data from a database:

```python
import duckdb
import json

def generate_data(db_path, output_path):
    conn = duckdb.connect(db_path)
    data = conn.execute("SELECT * FROM my_table").fetchdf().to_dict(orient="records")
    conn.close()
    
    Path(output_path).parent.mkdir(parents=True, exist_ok=True)
    with open(output_path, "w") as f:
        json.dump(data, f, indent=2)
```

### Pattern 2: Page creation

Create a React page from a template:

```python
def create_page(template_path, output_path):
    template = Path(template_path).read_text()
    Path(output_path).parent.mkdir(parents=True, exist_ok=True)
    Path(output_path).write_text(template)
```

### Pattern 3: Route addition

Add a route to App.tsx:

```python
def add_route(route_path, component_name):
    app_path = Path("web/scratch/src/App.tsx")
    content = app_path.read_text()
    
    # Check if route already exists
    if f'path="{route_path}"' in content:
        print("Route already exists")
        return
    
    # Add the route
    import_statement = f'import {component_name} from "./pages/{component_name}";'
    route_element = f'<Route path="{route_path}" element={<{component_name} />} />'
    
    # Insert import at the top
    lines = content.split("\n")
    import_idx = next(i for i, line in enumerate(lines) if "import" in line and "from" in line)
    lines.insert(import_idx, import_statement)
    
    # Insert route before closing Routes tag
    routes_idx = next(i for i, line in enumerate(lines) if "</Routes>" in line)
    lines.insert(routes_idx, f"  {route_element}")
    
    app_path.write_text("\n".join(lines))
```

### Pattern 4: Verification

Verify the page works:

```python
def verify_page(page_path, data_path):
    page = Path(page_path)
    data = Path(data_path)
    
    if not page.exists():
        print(f"ERROR: Page not found: {page_path}")
        return False
    
    if not data.exists():
        print(f"ERROR: Data not found: {data_path}")
        return False
    
    print(f"✓ {page_path}")
    print(f"✓ {data_path}")
    return True
```

## Best practices

### 1. Make it fast

- Avoid long-running processes
- Use pre-generated data when possible
- Minimize external dependencies

### 2. Make it safe

- Don't modify existing files unless necessary
- Always check if files exist before creating
- Provide clear error messages

### 3. Make it clear

- Print what's happening at each step
- Show what files are being created
- Provide success/error feedback

### 4. Make it undo-able

- List all created files
- Provide cleanup script
- Make cleanup easy and safe

### 5. Make it impressive

- Create visually appealing results
- Tell a story with the data
- Include interactive elements
- Demonstrate capabilities

## Examples of demo skills

### demo-research

Creates a notebook-style data analysis page for US electricity energy.

**Run:** `python Skills/demo-research/scripts/run-skill.py`

**Cleanup:**
```bash
rm -rf web/scratch/src/data/usa_energy
rm web/scratch/src/pages/UsaEnergy.tsx
```

### Future demo skills you could create

- **demo-dashboard**: Create a dashboard with multiple charts
- **demo-calculator**: Create an interactive calculator
- **demo-story**: Create a story-telling page with animations
- **demo-api**: Create a page that calls an API and displays results

## Running a demo skill

### For demos

1. Clean up any previous runs
2. Run the skill
3. Show the results
4. Explain what happened

### Between demos

1. Clean up
2. Make any changes
3. Run again
4. Repeat

## Troubleshooting

### Skill fails to run

- Check that all dependencies are installed
- Verify file paths are correct
- Check error messages

### Cleanup doesn't work

- Manually delete the files
- Check file permissions
- Verify file paths

### Page doesn't show up

- Check that the route was added
- Verify the page component exists
- Check the browser console for errors

## Summary

A demo skill should:
- **Do something impressive quickly**
- **Be undo-able**
- **Be repeatable**
- **Be self-contained**

Follow the patterns and best practices in this skill to create your own demo skills.