# How Working Directory Cleanup Works After Video Processing in Claude Video

> Discover how bradautomates claude-video ensures efficient storage by cleaning its working directory after video processing. Learn about its four-stage cleanup contract.

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

---

**The `watch` skill in bradautomates/claude-video implements a strict "cleanup contract" that deletes temporary files at four distinct stages—before extraction, after perceptual deduplication, after even-sampling selection, and during final key-frame generation—to ensure only the selected frames remain on disk.**

The `claude-video` repository handles video processing through a systematic pipeline that prevents disk space bloat by aggressively removing intermediate files. According to the source code in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py), the cleanup process follows a predictable lifecycle that guarantees no stray JPEGs or temporary artifacts survive after processing completes.

## The Four-Stage Cleanup Process

The working directory maintenance operates through four specific phases, each targeting different categories of temporary files created during frame extraction.

### Stage 1: Pre-Extraction Purge

Before any frame extraction begins, the target output folder is sanitized to remove leftovers from previous runs. In [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py) (lines 596–599), the code ensures a clean slate:

```python
out_dir.mkdir(parents=True, exist_ok=True)
for existing in out_dir.glob("frame_*.jpg"):
    existing.unlink()

```

This **pre-extraction purge** eliminates any existing `frame_*.jpg` files that might remain from interrupted or previous processing sessions, preventing contamination of the new extraction batch.

### Stage 2: Deduplication Removal

After frames are extracted, the `dedupe_perceptual` function identifies near-identical images. The cleanup logic (lines 500–505) immediately deletes these redundant files from disk rather than merely excluding them from the selection set:

```python
for cand in dropped:
    Path(cand["path"]).unlink()

```

This **deduplication removal** ensures that perceptually similar frames—those deemed too close in visual content—are physically removed, freeing space before the final sampling stage.

### Stage 3: Even-Sampling Prune

When the `_even_sample` function selects the final frame distribution, it generates a list of kept paths (`keep_paths`). Any candidate frames not selected for the final set are purged (lines 404–410):

```python
for cand in candidates:
    if cand["path"] not in keep_paths:
        Path(cand["path"]).unlink()

```

This **even-sampling prune** operation guarantees that only the evenly distributed representative frames remain, deleting all intermediate candidates that failed the selection criteria.

### Stage 4: Key-Frame Extraction Finalization

The high-level `extract_keyframes` helper orchestrates the complete workflow by repeating the pre-extraction purge (Stage 1) and then invoking `ffmpeg` to write fresh key-frame JPEGs into the now-empty directory. This final stage ensures that the output directory contains **only** the definitive set of selected frames, with all processing artifacts removed.

## Complete Working Example

The cleanup process operates automatically when calling the extraction helpers. The following example demonstrates how `extract_keyframes` manages the entire lifecycle:

```python
from pathlib import Path
from skills.watch.scripts.frames import extract_keyframes

# Example: extract up to 50 keyframes from a video

video = "sample.mp4"
out_dir = Path("/tmp/video_frames")
selected_frames, meta = extract_keyframes(
    video_path=video,
    out_dir=out_dir,
    resolution=512,
    max_frames=50,
)

print(f"Kept {len(selected_frames)} frames – directory now contains only these files.")

```

Executing this snippet performs the complete cleanup contract automatically: it creates `out_dir` if missing, deletes pre-existing `frame_*.jpg` files, writes new keyframes, removes near-duplicates, and finally retains only the evenly-sampled set.

## Supporting Cleanup in Other Modules

While [`frames.py`](https://github.com/bradautomates/claude-video/blob/main/frames.py) handles the core image cleanup, the cleanup contract extends to other components:

- **[`skills/watch/scripts/download.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/download.py)**: Removes temporary download artifacts after video acquisition
- **[`skills/watch/scripts/transcribe.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/transcribe.py)**: Deletes temporary audio and text files generated during speech-to-text processing
- **[`skills/watch/scripts/watch.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/watch.py)**: The high-level orchestrator that coordinates these helpers and ensures the complete pipeline maintains disk hygiene

## Summary

- **Pre-extraction purge**: Deletes existing `frame_*.jpg` files before processing begins (frames.py:596–599)
- **Deduplication cleanup**: Physically removes near-duplicate frames identified by `dedupe_perceptual` (frames.py:500–505)
- **Sampling cleanup**: Unlinks rejected candidates after `_even_sample` selects the final distribution (frames.py:404–410)
- **Orchestrated cleanup**: The `extract_keyframes` helper and [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py) entry point ensure temporary files never persist between runs
- **Cross-module hygiene**: Download and transcription modules implement similar cleanup patterns for their respective temporary files

## Frequently Asked Questions

### What happens if a video processing job is interrupted midway?

The next run automatically triggers the **pre-extraction purge** (lines 596–599), which deletes any `frame_*.jpg` files in the output directory before new extraction begins. This ensures no orphaned frames from failed runs contaminate subsequent processing.

### Why does the cleanup delete files during deduplication rather than just marking them as skipped?

The `dedupe_perceptual` function uses `Path(cand["path"]).unlink()` (lines 500–505) to immediately delete near-duplicate frames. This aggressive approach prevents disk space exhaustion when processing long videos that might generate hundreds of temporary frames before the final selection.

### How does the even-sampling algorithm decide which frames to delete?

The `_even_sample` function creates a `keep_paths` set containing only the selected frame paths. It then iterates through all candidates and calls `unlink()` on any path not present in that set (lines 404–410), ensuring only the evenly-distributed final selection remains physically on disk.

### Are there any temporary files that persist after processing completes?

No. According to the source code in `bradautomates/claude-video`, the design guarantees that **only the final, selected frames remain** in the working directory. All temporary files created during intermediate stages—including duplicates and rejected candidates—are explicitly deleted before the function returns.