# Media Setup

> Interactive wizard to configure platform connections, API keys, and dependencies for media-agent. Detects available tools, walks through setup for each platform, tests connections, and writes config files. Run this before any other media-agent skill.

- Skill: `minara-ai/media-setup` (Agent Skill)
- Install (CLI): `npx skillmds@latest add minara-ai/media-setup`
- Raw SKILL.md: https://api.skillmd.com/api/skills/minara-ai/media-setup/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: Minara-AI (https://skillmd.com/u/minara-ai)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/minara-ai/media-setup

---


# /media-setup — Platform Configuration Wizard

Configure your media-agent installation. This skill detects available tools,
walks you through API key setup for each platform, tests connections, and
writes the config files.

## Prerequisites

Before starting, read the shared library files:
- Read `lib/adapter-discovery.md` for how adapters work
- Read `lib/manifest-ops.md` for manifest format

## Step 1: Detect Environment

Check for required and optional tools:

```bash
echo "=== media-agent Setup ==="
echo ""

# Required
echo "Checking dependencies..."
which git >/dev/null 2>&1 && echo "  [OK] git" || echo "  [MISSING] git — required"
which python3 >/dev/null 2>&1 && echo "  [OK] python3" || echo "  [MISSING] python3 — required for YAML parsing"
which curl >/dev/null 2>&1 && echo "  [OK] curl" || echo "  [MISSING] curl — required for API calls"

# Optional
echo ""
echo "Optional tools:"
which convert >/dev/null 2>&1 && echo "  [OK] ImageMagick" || echo "  [MISSING] ImageMagick — needed for image resizing (brew install imagemagick)"
which gh >/dev/null 2>&1 && echo "  [OK] GitHub CLI" || echo "  [MISSING] GitHub CLI — optional, for GitHub Pages"
```

If `python3` or `curl` is missing, stop and tell the user how to install them.

If `ImageMagick` is missing, warn the user but continue — it's only needed for `/media-image`.

## Step 2: Discover Available Adapters

```bash
echo ""
echo "Available platform adapters:"
for adapter in adapters/*/; do
  name=$(basename "$adapter")
  display=$(python3 -c "import yaml; print(yaml.safe_load(open('${adapter}adapter.yaml'))['display_name'])" 2>/dev/null || echo "$name")
  auth_type=$(python3 -c "import yaml; print(yaml.safe_load(open('${adapter}adapter.yaml'))['auth_type'])" 2>/dev/null || echo "unknown")
  echo "  - $display ($auth_type)"
done
```

## Step 3: Configure Each Platform

Use AskUserQuestion to ask which platforms the user wants to configure.
Then for each selected platform:

### GitHub Pages (auth_type: git_push)

Ask the user:
1. "What is the local path to your GitHub Pages repository?" (e.g., `~/myblog`)
2. "Which branch do you publish from?" (default: `main`)
3. "What is your site URL?" (e.g., `https://username.github.io`)
4. "What directory are posts in?" (default: `_posts`)

Verify the repo exists:
```bash
[ -d "<repo_path>/.git" ] && echo "OK: Git repo found" || echo "ERROR: Not a git repo"
```

### Dev.to (auth_type: api_key)

Ask the user for their Dev.to API key. They can get one at https://dev.to/settings/extensions.

Test the connection:
```bash
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \
  -H "api-key: <API_KEY>" \
  "https://dev.to/api/users/me")
[ "$RESPONSE" = "200" ] && echo "OK: Dev.to connected" || echo "ERROR: Auth failed (HTTP $RESPONSE)"
```

### Hashnode (auth_type: api_key)

Ask the user for:
1. Their Hashnode API key (from https://hashnode.com/settings/developer)
2. Their publication ID (from their blog dashboard URL)

Test the connection:
```bash
RESPONSE=$(curl -s -w "\n%{http_code}" \
  -X POST "https://gql.hashnode.com" \
  -H "Authorization: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"query":"{ me { username } }"}')
```

## Step 4: Configure Image Generation (Optional)

Ask if the user wants to set up image generation.

If yes, ask for their OpenAI API key (for DALL-E 3).

Test:
```bash
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer <API_KEY>" \
  "https://api.openai.com/v1/models")
[ "$RESPONSE" = "200" ] && echo "OK: OpenAI connected" || echo "ERROR: Auth failed"
```

## Step 5: Configure Writing Voice (Optional)

Ask the user if they want to set up their personal writing style.

Use AskUserQuestion:
"Want to set up your writing voice? This helps the system match your personal style instead of sounding like AI."
- A) Yes, paste writing samples
- B) Yes, describe my style manually
- C) Skip for now

### Option A: Writing samples

Ask the user to paste 2-3 paragraphs of their own writing (blog posts, READMEs, tweets, etc.).

Use AskUserQuestion:
"Paste a writing sample — anything you've written that sounds like *you*. Blog post, README, email, tweet thread, 公众号文章 — all work. (Paste one now, I'll ask for more after.)"

Collect 1-3 samples. For each, extract voice traits:
- Average sentence length (short/medium/long)
- Vocabulary level (academic/technical/conversational/casual)
- Humor presence (none/dry/occasional/frequent)
- Default perspective (first_person/second_person/third_person)
- Formality (formal/neutral/informal)
- Language patterns (e.g., uses rhetorical questions, starts with anecdotes, uses 口语化 Chinese)

Show the extracted traits to the user for confirmation:
```
Based on your samples, here's your voice profile:
  sentence_length: short
  vocabulary: conversational
  humor: dry
  perspective: first_person
  formality: informal

Does this look right? I can adjust any of these.
```

### Option B: Manual style description

Use AskUserQuestion to walk through each trait:

1. "How long are your typical sentences?" (short and punchy / medium / long and flowing)
2. "What's your vocabulary like?" (academic / technical jargon / conversational / casual slang)
3. "Do you use humor in your writing?" (never / dry/subtle / sometimes / a lot)
4. "What perspective do you write from?" (I/我 first person / you/你 second person / third person)
5. "How formal is your tone?" (formal / neutral / informal/casual)

### Write voice.yaml

Write the voice config to `content/config/voice.yaml`:

```yaml
# Generated by /media-setup
samples:
  - |
    <pasted sample 1>
  - |
    <pasted sample 2>

traits:
  sentence_length: <extracted or chosen>
  vocabulary: <extracted or chosen>
  humor: <extracted or chosen>
  perspective: <extracted or chosen>
  formality: <extracted or chosen>
```

Tell the user:
"Voice profile saved. The writing skills will match this style automatically. You can update it anytime by editing `content/config/voice.yaml` or running `/media-setup` again."

## Step 6: Write Config Files

Write credentials to `.env` (gitignored):
```bash
cat > .env << EOF
# Generated by /media-setup on $(date -u +%Y-%m-%dT%H:%M:%SZ)
DEVTO_API_KEY=<value>
HASHNODE_API_KEY=<value>
HASHNODE_PUBLICATION_ID=<value>
OPENAI_API_KEY=<value>
EOF
chmod 600 .env
```

Write platform config to `content/config/platforms.yaml` (non-sensitive, git-tracked):
```yaml
# Generated by /media-setup
github_pages:
  repo_path: "<path>"
  branch: "<branch>"
  site_url: "<url>"
  posts_dir: "<dir>"

platforms:
  - devto
  - hashnode
  - github-pages
```

## Step 7: Configure git-lfs (Optional)

If the user expects to publish many posts with images:

```bash
which git-lfs >/dev/null 2>&1 && echo "[OK] git-lfs available" || echo "[INFO] git-lfs not installed — recommended for repos with >50 posts"
```

If git-lfs is available, offer to configure it:
```bash
git lfs install
git lfs track "content/**/assets/*.png"
git lfs track "content/**/assets/*.jpg"
git add .gitattributes
```

## Step 8: Summary

Print a summary of what was configured:

```
=== media-agent configured! ===

Platforms:
  [OK] GitHub Pages → https://username.github.io
  [OK] Dev.to → connected as @username
  [OK] Hashnode → connected to publication xyz

Image generation:
  [OK] OpenAI DALL-E 3

Writing voice:
  [OK] Voice profile configured (informal, conversational, first person)

Next steps:
  - Run /media-idea to brainstorm your first post
  - Run /media to start the full guided workflow
  - Or write markdown manually and use /media-publish
```

