Skill: dairui1/podcast-transcribe (version 1.4.1)

--- name: transcribe description: "For transcript or subtitle requests involving podcast URLs, public audio URLs/files, or raw transcript cleanup. Generates audio + SRT + TXT artifacts and can optionally clean transcripts with episode-page context." allowed-tools: Bash(curl:*), Bash(podcast-helper:*), Bash(npx podcast-helper:*), Bash(pnpm dlx podcast-helper:*), Bash(node dist/cli.js:*), Bash(pnpm run build:*) metadata: version: "1.4.1" tags: [podcast, transcription, audio, subtitles, asr, cleanup] --- # Transcribe with podcast-helper Generate transcript artifacts from a podcast episode, audio file, or raw transcript, with an optional cleanup pass that uses episode-page context. ## Default Workflow 1. Choose a dedicated output directory such as `./out/<episode-slug>/`. 2. Run `npx podcast-helper transcribe <input> --output-dir <dir> --json`. 3. Add `--progress jsonl` only when machine-readable progress is needed. 4. Report the generated artifact paths for audio, `.srt`, and `.txt`. 5. Ask whether the user wants cleanup. Do not run cleanup implicitly. If you are already inside this repository and `dist/cli.js` exists, `node dist/cli.js ...` is acceptable. Do not default to repository-local build steps outside this repository. If you are inside this repository and `dist/cli.js` is missing, run `pnpm run build` before using the repo-local entry point. ## Gotchas - Prefer no-install entry points first: `npx`, then `pnpm dlx`, then a globally installed `podcast-helper`. - Let the CLI auto-select the engine unless the user explicitly requests a backend or needs offline Apple Silicon transcription. - Spotify URLs are unsupported because the audio is DRM-protected. Ask for an RSS-backed episode page, Apple Podcasts link, or direct audio URL instead. - YouTube inputs require `yt-dlp`. - Generic episode pages sometimes hide audio metadata. If source resolution fails, download the audio separately and rerun with the file path. - Hosted transcription failures usually come from a missing or wrong provider API key. - Local `mlx-whisper` runs require `ffmpeg`, `python3`, and a working runtime from `podcast-helper setup mlx-whisper`. - Keep the raw transcript untouched. Cleanup should write a sibling `*.cleaned.txt`. ## Command Forms Default: ```bash npx podcast-helper transcribe <input> --output-dir ./out/<slug> --json ``` Fallbacks: - `pnpm dlx podcast-helper transcribe <input> --output-dir ./out/<slug> --json` - `podcast-helper transcribe <input> --output-dir ./out/<slug> --json` - `node dist/cli.js transcribe <input> --output-dir ./out/<slug> --json` only inside this repository For offline Apple Silicon: ```bash npx podcast-helper transcribe <input> --engine mlx-whisper --output-dir ./out/<slug> --json ``` ## Cleanup Branch Only enter cleanup when the user asks for it or already has a raw transcript. 1. Fetch episode context with `curl https://r.jina.ai/<podcast-url>`. 2. Use the page as reference context for obvious ASR repairs, especially names and proper nouns. 3. Do not summarize, invent missing content, or overwrite the raw transcript. 4. Write a sibling `*.cleaned.txt` file. If no episode URL is available, clean conservatively and explicitly say that external episode context was not used. ## References - Read `references/inputs-and-engines.md` for supported inputs, engine selection, and dependency notes. - Read `references/output-contract.md` for the JSON success and failure envelopes and progress handling. - Read `references/cleanup.md` for detailed cleanup rules and conservative editing guidance. - Read `references/verification.md` for smoke-test inputs and verification steps. - Read `references/setup.md` when installing this skill into Claude Code, OpenClaw, or other agents.

path: agents/clawhub.json
content: slug: podcast-transcribe

path: agents/openai.yaml
content: interface:
  display_name: "Podcast Transcribe"
  short_description: "Transcribe podcast/audio to SRT, TXT, and cleanup"
  default_prompt: "Use $transcribe to turn this podcast URL, audio URL, or local audio file into transcript artifacts and optionally clean the transcript."

policy:
  allow_implicit_invocation: true


path: references/cleanup.md
content: # Cleanup Guidance

Use this branch when:

- the user says yes after transcription
- the user already has a raw `.txt` transcript that needs cleanup

## Inputs

| Required | Optional |
|----------|----------|
| Raw transcript `.txt` | `.srt` file |
| Original episode URL when available | Original audio file |

## Context Fetch

Fetch the episode page through Jina Reader:

```bash
curl https://r.jina.ai/<podcast-url>
```

Example:

```bash
curl https://r.jina.ai/https://www.xiaoyuzhoufm.com/episode/69b4d2f9f8b8079bfa3ae7f2
```

## Editing Rules

Use the page content as reference context to:

- fix obvious homophone and ASR mistakes
- recover names, products, titles, and other proper nouns
- remove clearly redundant filler words and repetitions
- normalize punctuation and paragraph breaks for readability

Do not:

- invent missing material
- summarize instead of cleaning
- change speaker intent or factual meaning
- overwrite the raw transcript

## Output Naming

Keep the raw transcript unchanged and write a sibling file:

- raw: `episode.txt`
- cleaned: `episode.cleaned.txt`

If the episode URL is unavailable, clean conservatively using transcript-only evidence and explicitly state that no external episode context was used.


path: references/inputs-and-engines.md
content: # Inputs and Engines

## Supported Inputs

| Input Type | Example | Notes |
|------------|---------|-------|
| Xiaoyuzhou URL | `https://www.xiaoyuzhoufm.com/episode/...` | Resolved directly |
| Apple Podcasts URL | `https://podcasts.apple.com/us/podcast/.../id...?i=...` | Uses iTunes lookup |
| YouTube URL | `https://www.youtube.com/watch?v=...` | Requires `yt-dlp` |
| Pocket Casts URL | `https://pca.st/episode/...` | oEmbed plus embed-page discovery |
| Castro URL | `https://castro.fm/episode/...` | HTML audio extraction |
| Ximalaya URL | `https://www.ximalaya.com/sound/...` | Mobile track API |
| Podcast Addict URL | `https://podcastaddict.com/episode/...` | Decodes audio URL from the path |
| Podcast page URL | `https://example.fm/episodes/42` | Looks for `og:audio`, RSS, audio tags, or JSON-LD |
| Direct audio URL | `https://.../file.mp3` | Download then transcribe |
| Local file | `./audio/interview.mp3` | Transcribe directly |

Spotify URLs are detected but rejected because the audio is DRM-protected.

Generic episode-page support works best when the page exposes:

- `og:audio` or similar metadata
- `<audio>` or `<source>` tags
- JSON-LD `AudioObject` or `PodcastEpisode`
- an RSS or Atom feed that links back to the current episode page

## Engine Selection

Provider environment variables:

| Provider | Env Variable | Engine Flag |
|----------|--------------|-------------|
| Local (Apple Silicon) | none | `mlx-whisper` |
| ElevenLabs | `ELEVENLABS_API_KEY` | `elevenlabs` |
| OpenAI | `OPENAI_API_KEY` | `openai` |
| Groq | `GROQ_API_KEY` | `groq` |
| Deepgram | `DEEPGRAM_API_KEY` | `deepgram` |
| Gladia | `GLADIA_API_KEY` | `gladia` |
| AssemblyAI | `ASSEMBLYAI_API_KEY` | `assemblyai` |
| Rev.ai | `REVAI_API_KEY` | `revai` |

Auto-detection order:

1. Local `mlx-whisper`, if installed
2. ElevenLabs, OpenAI, Groq, Deepgram, Gladia, AssemblyAI, Rev.ai
3. Fallback to `mlx-whisper`

Use `--engine <provider>` only when the user explicitly wants a backend or when offline local transcription is required.

## External Dependencies

| Scenario | Dependency | Install |
|----------|------------|---------|
| YouTube extraction | `yt-dlp` | `brew install yt-dlp` or `pip install yt-dlp` |
| Local transcription | `ffmpeg`, `python3` | `brew install ffmpeg` |
| `mlx-whisper` runtime | `podcast-helper setup mlx-whisper` | Installs the stable local runtime |

Quick environment check:

```bash
printenv ELEVENLABS_API_KEY
podcast-helper doctor
```


path: references/output-contract.md
content: # Output Contract

Prefer machine-readable output:

```bash
npx podcast-helper transcribe <input> --output-dir <dir> --json
```

Add `--progress jsonl` when you want machine-readable progress events and terminal failure events on `stderr`.

## Artifacts

The command writes:

- the original audio file
- a `.srt` subtitle file
- a `.txt` transcript file

Always report these artifact paths back to the user.

## Success Envelope

```json
{
  "ok": true,
  "command": "transcribe",
  "input": "https://storage.googleapis.com/eleven-public-cdn/audio/marketing/nicole.mp3",
  "source": "remote-audio-url",
  "language": "eng",
  "artifacts": {
    "audio": "/abs/path/nicole.mp3",
    "srt": "/abs/path/nicole.srt",
    "txt": "/abs/path/nicole.txt"
  }
}
```

## Failure Envelope

```json
{
  "ok": false,
  "command": "transcribe",
  "error": {
    "code": "SOURCE_RESOLUTION_FAILED",
    "category": "source",
    "message": "Could not extract podcast audio from the provided page.",
    "hints": [
      "Pass the original episode page URL, a direct audio URL, or a local audio file.",
      "If this site hides audio metadata, download the audio separately and rerun `transcribe` with the file path."
    ]
  }
}
```

## Operational Notes

- Progress logs are emitted on `stderr`.
- Final success payloads are emitted as JSON on `stdout`.
- Structured failures are emitted as JSON on `stderr`.
- The local workflow uses a request-scoped temp workspace and cleans it up unless `--keep-temp` is set.


path: references/setup.md
content: # Setup

This file is for installation and platform-specific activation details. It is not needed for routine transcription runs.

## Claude Code

Project-local install:

```bash
npx skills add dairui1/podcast-helper --skill transcribe
```

Global install:

```bash
npx skills add dairui1/podcast-helper --skill transcribe -g
```

Manual install from a local checkout:

```bash
mkdir -p ~/.claude/skills
cp -R skills/transcribe ~/.claude/skills/transcribe
```

Optional reminder hook:

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'podcast-helper transcribe'; then echo 'Transcription complete; ask whether cleanup is needed.'; fi"
          }
        ]
      }
    ]
  }
}
```

## OpenClaw

Recommended install:

```bash
clawdhub install dairui1/podcast-helper --skill transcribe
```

Manual install from a local checkout:

```bash
mkdir -p ~/.openclaw/skills
cp -R skills/transcribe ~/.openclaw/skills/transcribe
```

## Other Agents

For agents that do not auto-load `SKILL.md`, add a short pointer in `AGENTS.md`, `CLAUDE.md`, or `.github/copilot-instructions.md`:

```markdown
Use podcast-helper for podcast transcription:
- `npx podcast-helper transcribe <input> --output-dir <dir> --json`
- ask before cleanup
- see `skills/transcribe/SKILL.md` for workflow details
```


path: references/verification.md
content: # Verification

Use a small public sample for low-cost verification:

```text
https://storage.googleapis.com/eleven-public-cdn/audio/marketing/nicole.mp3
```

## Smoke Test

```bash
npx podcast-helper transcribe https://storage.googleapis.com/eleven-public-cdn/audio/marketing/nicole.mp3 --output-dir ./out/smoke --json
```

## What to Verify

- the command exits successfully
- the success envelope includes `audio`, `srt`, and `txt` artifact paths
- the `.txt` transcript is non-empty
- the `.srt` file contains timestamped subtitle blocks

## Local Runtime Debugging

If local `mlx-whisper` is failing:

```bash
podcast-helper doctor
podcast-helper setup mlx-whisper
```

When debugging progress or chunking behavior, rerun with `--progress jsonl`.


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