# How the setup.py Preflight Check Works Across Platforms in Claude Video

> Discover how Claude Video's setup.py preflight check verifies ffmpeg, yt-dlp, and environment setup on Linux, macOS, and Windows. Learn exit codes for smooth installation.

- Repository: [bradautomates/claude-video](https://github.com/bradautomates/claude-video)
- Tags: internals
- Published: 2026-08-02

---

**The [`setup.py`](https://github.com/bradautomates/claude-video/blob/main/setup.py) script in Claude Video supports three modes—`--check`, `--json`, and the full installer—each returning specific exit codes (0 for success, 2 for missing ffmpeg, 3 for missing yt-dlp, 4 for environment issues) while adapting tool detection and installation guidance to Linux, macOS, and Windows.**

The **setup.py** preflight check is the gatekeeper that ensures Claude Video's **watch** skill can download videos, extract frames, and generate transcriptions. Located at [`skills/watch/scripts/setup.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/setup.py), this script detects the host platform, verifies external dependencies, validates Python version and environment configuration, and reports status through both exit codes and structured JSON output.

## What the Preflight Check Evaluates

When invoked with the **`--check`** flag, [`setup.py`](https://github.com/bradautomates/claude-video/blob/main/setup.py) performs a silent, non-interactive audit of the environment:

1. **Platform detection** via `platform.system()`
2. **ffmpeg availability** in system PATH
3. **yt-dlp availability** in system PATH
4. **Python version** ≥ 3.8
5. **Environment file** (`.env`) existence and required variables

The script returns **granular exit codes** that calling processes can interpret without parsing output:

| Exit Code | Meaning |
|-----------|---------|
| `0` | All checks passed, environment ready |
| `2` | ffmpeg missing or not executable |
| `3` | yt-dlp missing or not executable |
| `4` | Environment configuration problem (missing `.env` or required keys) |

For programmatic consumption, **`--json`** emits the same diagnostic information as a structured object:

```bash
python3 skills/watch/scripts/setup.py --json

```

Example output:

```json
{
  "platform": "Linux",
  "ffmpeg": true,
  "yt_dlp": true,
  "python_ok": true,
  "env_ready": true
}

```

## Platform-Specific Detection Logic

The [`setup.py`](https://github.com/bradautomates/claude-video/blob/main/setup.py) preflight check branches its behavior based on `platform.system()`, using platform-native commands to locate binaries and providing tailored installation guidance.

### Linux

On Linux systems (`platform.system() == "Linux"`), the script uses the standard **`which`** command:

```bash
which ffmpeg
which yt-dlp

```

**Missing dependency behavior:**
- **ffmpeg**: Exits `2`, suggests system package manager installation (`apt`, `yum`, or `dnf`)
- **yt-dlp**: Exits `3`, suggests `pip install yt-dlp` or distribution package

The script does not attempt automatic installation on Linux; it delegates to the user's preferred package manager with explicit commands.

### macOS

On macOS (`"Darwin"`), the detection mechanism remains **`which`**, but the guidance shifts to **Homebrew**:

```bash
which ffmpeg
which yt-dlp

```

**Missing dependency behavior:**
- **ffmpeg**: Exits `2`, advises `brew install ffmpeg`
- **yt-dlp**: Exits `3`, advises `brew install yt-dlp`

This aligns with typical macOS development workflows where Homebrew serves as the primary package manager.

### Windows

On Windows (`"Windows"`), the script substitutes **`which`** with the **`where`** command:

```cmd
where ffmpeg.exe
where yt-dlp.exe

```

**Missing dependency behavior:**
- **ffmpeg**: Exits `2`, recommends `choco install ffmpeg` via Chocolatey
- **yt-dlp**: Exits `3`, recommends `choco install yt-dlp` or `pip install yt-dlp`

The explicit `.exe` extension ensures correct binary identification on Windows where PATH resolution differs from Unix-like systems.

## Full Installer Mode

When run **without flags**, [`setup.py`](https://github.com/bradautomates/claude-video/blob/main/setup.py) executes the complete setup workflow:

```bash
python3 skills/watch/scripts/setup.py

```

This mode performs four sequential operations:

1. **Python dependency installation** — installs required packages if absent
2. **Environment scaffolding** — creates a default `.env` template with placeholder values for `OPENAI_API_KEY` and other configuration
3. **Marker file creation** — writes `SETUP_COMPLETE` to signal successful initialization
4. **Preflight verification** — runs the full check suite and propagates exit codes

The installer ensures first-time users receive both a working configuration and immediate validation that external tools are present.

## Integration with Claude Video Skills

The preflight check is not merely a standalone utility—it integrates directly with Claude Video's execution flow.

In **[`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py)**, the main video processing entry point calls [`setup.py`](https://github.com/bradautomates/claude-video/blob/main/setup.py) when the optional Whisper fallback transcription path requires verification. The exit code determines whether processing continues or the user receives targeted remediation instructions.

In **[`whisper.py`](https://github.com/bradautomates/claude-video/blob/main/whisper.py)**, the transcription module references [`setup.py`](https://github.com/bradautomates/claude-video/blob/main/setup.py) to prompt users to run the installer if Whisper dependencies are detected as missing during runtime.

```bash

# Typical integration pattern used in watch.py

python3 skills/watch/scripts/setup.py --check
if [ $? -ne 0 ]; then
    echo "Environment not ready. Run: python3 skills/watch/scripts/setup.py"
    exit 1
fi

```

## Practical Usage Examples

**Silent verification in CI/CD:**

```bash
python3 skills/watch/scripts/setup.py --check || exit 1

```

**Platform-agnostic status check with JSON parsing:**

```bash
STATUS=$(python3 skills/watch/scripts/setup.py --json)
echo "$STATUS" | jq '.ffmpeg'  # yields true/false

```

**First-time setup:**

```bash
cd skills/watch/scripts
python3 setup.py  # Installs deps, creates .env, verifies everything

```

## Source File Locations

| File | Purpose |
|------|---------|
| [`skills/watch/scripts/setup.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/setup.py) | Core preflight check and installer implementation |
| [`skills/watch/scripts/watch.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/watch.py) | Main entry point that invokes setup checks |
| [`skills/watch/scripts/whisper.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/whisper.py) | Transcription module with setup integration |
| [`tests/test_setup.py`](https://github.com/bradautomates/claude-video/blob/main/tests/test_setup.py) | Test suite validating cross-platform preflight logic |

The test suite in [`tests/test_setup.py`](https://github.com/bradautomates/claude-video/blob/main/tests/test_setup.py) mocks `platform.system()` and subprocess calls to verify correct behavior on all three target platforms without requiring actual Linux, macOS, and Windows hosts.

## Summary

- **`setup.py --check`** performs silent, platform-aware validation of ffmpeg, yt-dlp, Python version, and environment configuration
- **Exit codes** (`0`, `2`, `3`, `4`) enable programmatic decision-making without output parsing
- **`--json`** provides machine-readable status for integration with Claude and other tools
- **Platform branching** uses `which` on Linux/macOS, `where` on Windows, with Homebrew, apt/yum, and Chocolatey guidance respectively
- **Installer mode** scaffolds new environments and confirms readiness in one command

## Frequently Asked Questions

### What happens if I run [`setup.py`](https://github.com/bradautomates/claude-video/blob/main/setup.py) without any arguments?

Running [`setup.py`](https://github.com/bradautomates/claude-video/blob/main/setup.py) without flags executes the full installer: it installs Python dependencies, creates a default `.env` file, writes a `SETUP_COMPLETE` marker, and then runs the preflight check. This is the recommended first step for new Claude Video installations.

### Can I suppress all output and just get the exit status?

Yes. Use **`setup.py --check`** for completely silent operation. The script produces no stdout/stderr on success and returns only the numeric exit code, making it ideal for shell scripts and CI pipelines.

### Why does the script suggest different package managers on different platforms?

The [`setup.py`](https://github.com/bradautomates/claude-video/blob/main/setup.py) preflight check aims to minimize friction by recommending the dominant package manager for each platform: **Homebrew** for macOS, **apt/yum/dnf** for Linux distributions, and **Chocolatey** for Windows. These recommendations reflect common development practices and ensure users receive actionable, familiar commands rather than generic instructions.