Skill: blammectrappora/podcast-cover-generator (version 1.0.0)

--- name: podcast-cover-generator description: Generate professional podcast cover art and show artwork for Spotify, Apple Podcasts, YouTube Music, Amazon Music, and Overcast. Create eye-catching 1400x1400 square covers for true crime, comedy, business, interview, educational, storytelling, news, tech, and entertainment podcasts. Perfect for indie podcasters, podcast networks, audio creators, and show hosts needing custom cover design, episode art, show branding, podcast thumbnails, and directory-ready artwork that stands out in search results via the Neta AI image generation API (free trial at neta.art/open). tools: Bash --- # Podcast Cover Generator Generate professional podcast cover art and show artwork for Spotify, Apple Podcasts, YouTube Music, Amazon Music, and Overcast. Create eye-catching 1400x1400 square covers for true crime, comedy, business, interview, educational, storytelling, news, tech, and entertainment podcasts. Perfect for indie podcasters, podcast networks, audio creators, and show hosts needing custom cover design, episode art, show branding, podcast thumbnails, and directory-ready artwork that stands out in search results. ## Token Requires a Neta API token (free trial at <https://www.neta.art/open/>). Pass it via the `--token` flag. ```bash node <script> "your prompt" --token YOUR_TOKEN ``` ## When to use Use when someone asks to generate or create podcast cover art generator images. ## Quick start ```bash node podcastcovergenerator.js "your description here" --token YOUR_TOKEN ``` ## Options - `--size` — `portrait`, `landscape`, `square`, `tall` (default: `square`) - `--ref` — reference image UUID for style inheritance ## Install ```bash npx skills add blammectrappora/podcast-cover-generator ```

path: README.md
content: # Podcast Cover Generator

Generate professional podcast cover art and show artwork from plain text descriptions. Describe your show — the mood, subject, color palette, central visual — and get back a broadcast-quality square cover ready for Spotify, Apple Podcasts, YouTube Music, Amazon Music, and Overcast. Built for indie podcasters, podcast networks, audio creators, and show hosts who need directory-ready artwork that stands out in search results across true crime, comedy, business, interview, educational, storytelling, news, tech, and entertainment categories.

Powered by the Neta AI image generation API (api.talesofai.com) — the same service as neta.art/open.

## Install

Via the skills CLI:

```bash
npx skills add blammectrappora/podcast-cover-generator
```

Via ClawHub:

```bash
clawhub install podcast-cover-generator
```

## Usage

```bash
node podcastcovergenerator.js "your description here" --token YOUR_TOKEN
```

The first positional argument is your prompt. A cinematic podcast-cover style suffix is appended automatically, so you can focus on describing the subject.

### Examples

Generate a true-crime show cover:

```bash
node podcastcovergenerator.js "shadowy detective silhouette against a neon-lit rainy alley, moody noir atmosphere" --token YOUR_TOKEN
```

Generate a business interview podcast cover:

```bash
node podcastcovergenerator.js "confident founder portrait, clean geometric background, gold and navy palette" --token YOUR_TOKEN
```

Generate a comedy show cover in portrait orientation:

```bash
node podcastcovergenerator.js "two cartoon microphones laughing, playful pastel background" --size portrait --token YOUR_TOKEN
```

Reuse the style of an existing reference image:

```bash
node podcastcovergenerator.js "tech startup podcast, minimal circuit motif" --ref <picture_uuid> --token YOUR_TOKEN
```

### Output

Returns a direct image URL printed to stdout on success. Progress messages go to stderr, so you can pipe the URL cleanly:

```bash
URL=$(node podcastcovergenerator.js "astronomy podcast, deep space nebula" --token YOUR_TOKEN)
echo "$URL"
```

## Options

| Flag | Description | Default |
| --- | --- | --- |
| `<prompt>` | First positional argument — what you want generated | required |
| `--token` | Neta API token | required |
| `--size` | `square`, `portrait`, `landscape`, or `tall` | `square` |
| `--ref` | Reference image `picture_uuid` for style inheritance | none |
| `-h`, `--help` | Show help | — |

Size presets:

| Preset | Dimensions |
| --- | --- |
| `square` | 1024 × 1024 |
| `portrait` | 832 × 1216 |
| `landscape` | 1216 × 832 |
| `tall` | 704 × 1408 |

## Token setup

The script reads your Neta API token **only** from the `--token` command-line flag. There is no config file, no hidden lookup — whatever you pass to `--token` is what the script uses.

Pass it directly:

```bash
node podcastcovergenerator.js "a cozy storytelling podcast cover" --token sk-xxxxxxxxxxxx
```

Or expand a shell variable you set yourself:

```bash
node podcastcovergenerator.js "a cozy storytelling podcast cover" --token "$NETA_TOKEN"
```

If `--token` is missing the script exits with an error.

---

This skill requires a Neta API token (free trial available at https://www.neta.art/open/).


path: package.json
content: name: podcast-cover-generator
version: 1.0.0
type: module
description: Podcast Cover Generator — AI-powered podcast cover art generator
license: MIT

path: podcastcovergenerator.js
content: #!/usr/bin/env node
// Podcast Cover Generator — AI-powered podcast cover art via Neta API

const API_BASE = 'https://api.talesofai.com';

const SIZES = {
  square: { width: 1024, height: 1024 },
  portrait: { width: 832, height: 1216 },
  landscape: { width: 1216, height: 832 },
  tall: { width: 704, height: 1408 },
};

const DEFAULT_STYLE_SUFFIX = 'professional podcast cover art, bold central visual focus, dramatic lighting, vibrant color palette, modern minimalist design, broadcast quality, square 1:1 composition, eye-catching thumbnail-ready artwork, clean negative space for title typography, cinematic style';

function parseArgs(argv) {
  const args = { prompt: null, size: 'square', token: null, ref: null };
  const rest = argv.slice(2);
  for (let i = 0; i < rest.length; i++) {
    const a = rest[i];
    if (a === '--size') {
      args.size = rest[++i];
    } else if (a === '--token') {
      args.[REDACTED_SECRET];
    } else if (a === '--ref') {
      args.ref = rest[++i];
    } else if (a === '--help' || a === '-h') {
      args.help = true;
    } else if (!args.prompt) {
      args.prompt = a;
    }
  }
  return args;
}

function printHelp() {
  console.log(`Podcast Cover Generator — generate podcast cover art from a text prompt

Usage:
  node podcastcovergenerator.js "your description" --token YOUR_TOKEN [options]

Options:
  --size <preset>   square | portrait | landscape | tall  (default: square)
  --token <token>   Neta API token (required)
  --ref <uuid>      Reference image picture_uuid for style inheritance
  -h, --help        Show this help

Get a free trial token at: https://www.neta.art/open/
`);
}

async function createTask({ prompt, size, token, ref }) {
  const dims = SIZES[size] || SIZES.square;
  const body = {
    storyId: 'DO_NOT_USE',
    jobType: 'universal',
    rawPrompt: [{ type: 'freetext', value: prompt, weight: 1 }],
    width: dims.width,
    height: dims.height,
    meta: { entrance: 'PICTURE,VERSE' },
    context_model_series: '8_image_edit',
  };
  if (ref) {
    body.inherit_params = { collection_uuid: ref, picture_uuid: ref };
  }

  const res = await fetch(`https://api.talesofai.com/v3/make_image`, {
    method: 'POST',
    headers: {
      'x-token': token,
      'x-platform': 'nieta-app/web',
      'content-type': 'application/json',
    },
    body: JSON.stringify(body),
  });

  if (!res.ok) {
    const text = await res.text();
    throw new Error(`make_image failed: ${res.status} ${res.statusText} — ${text}`);
  }

  const raw = await res.text();
  let taskUuid;
  try {
    const parsed = JSON.parse(raw);
    taskUuid = typeof parsed === 'string' ? parsed : parsed.task_uuid;
  } catch {
    taskUuid = raw.replace(/^"|"$/g, '').trim();
  }
  if (!taskUuid) throw new Error(`No task_uuid in response: ${raw}`);
  return taskUuid;
}

async function pollTask(taskUuid, token) {
  const maxAttempts = 90;
  for (let i = 0; i < maxAttempts; i++) {
    const res = await fetch(`https://api.talesofai.com/v1/artifact/task/${taskUuid}`, {
      headers: {
        'x-token': token,
        'x-platform': 'nieta-app/web',
        'content-type': 'application/json',
      },
    });

    if (!res.ok) {
      const text = await res.text();
      throw new Error(`poll failed: ${res.status} ${res.statusText} — ${text}`);
    }

    const data = await res.json();
    const status = data.task_status;

    if (status !== 'PENDING' && status !== 'MODERATION') {
      const url =
        (data.artifacts && data.artifacts[0] && data.artifacts[0].url) ||
        data.result_image_url;
      if (!url) {
        throw new Error(`Task finished but no image URL. status=${status} data=${JSON.stringify(data)}`);
      }
      return url;
    }

    await new Promise((r) => setTimeout(r, 2000));
  }
  throw new Error('Timed out waiting for image generation');
}

async function main() {
  const args = parseArgs(process.argv);

  if (args.help) {
    printHelp();
    process.exit(0);
  }

  if (!args.prompt) {
    console.error('\n✗ Prompt required. Usage: node podcastcovergenerator.js "your description" --token YOUR_TOKEN');
    process.exit(1);
  }

  const tokenFlag = args.token;
  const [REDACTED_SECRET];

  if (!TOKEN) {
    console.error('\n✗ Token required. Pass via: --token YOUR_TOKEN');
    console.error('  Get yours at: https://www.neta.art/open/');
    process.exit(1);
  }

  if (!SIZES[args.size]) {
    console.error(`\n✗ Unknown size "${args.size}". Use: square | portrait | landscape | tall`);
    process.exit(1);
  }

  const fullPrompt = `${args.prompt}, ${DEFAULT_STYLE_SUFFIX}`;

  console.error(`→ Generating ${args.size} image...`);
  try {
    const taskUuid = await createTask({
      prompt: fullPrompt,
      size: args.size,
      token: TOKEN,
      ref: args.ref,
    });
    console.error(`  task_uuid: ${taskUuid}`);
    console.error('  polling...');
    const url = await pollTask(taskUuid, TOKEN);
    console.log(url);
    process.exit(0);
  } catch (err) {
    console.error(`\n✗ ${err.message}`);
    process.exit(1);
  }
}

main();


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