buttercut 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.claude/settings.local.json +8 -1
- data/.claude/skills +1 -0
- data/CLAUDE.md +1 -308
- data/LICENSE +106 -21
- data/README.md +13 -8
- data/lib/buttercut/version.rb +1 -1
- data/templates/library_template.yaml +14 -3
- data/templates/plan_template.md +1 -1
- data/templates/settings_template.yaml +6 -0
- metadata +5 -42
- data/.claude/scripts/script_extractor.rb +0 -66
- data/.claude/skills/analyze-video/SKILL.md +0 -30
- data/.claude/skills/analyze-video/agent_prompt.md +0 -84
- data/.claude/skills/analyze-video/prepare_visual_script.rb +0 -25
- data/.claude/skills/backup-library/SKILL.md +0 -26
- data/.claude/skills/backup-library/backup_libraries.rb +0 -46
- data/.claude/skills/cut-planner/SKILL.md +0 -74
- data/.claude/skills/release/SKILL.md +0 -214
- data/.claude/skills/roughcut/SKILL.md +0 -65
- data/.claude/skills/roughcut/agent_prompt.md +0 -153
- data/.claude/skills/roughcut/export_to_fcpxml.rb +0 -132
- data/.claude/skills/setup/SKILL.md +0 -47
- data/.claude/skills/setup/advanced-setup.md +0 -141
- data/.claude/skills/setup/simple-setup.md +0 -185
- data/.claude/skills/setup/verify_install.rb +0 -124
- data/.claude/skills/summarize-video/SKILL.md +0 -31
- data/.claude/skills/summarize-video/agent_prompt.md +0 -39
- data/.claude/skills/summarize-video/summary_skeleton.rb +0 -78
- data/.claude/skills/summarize-video/visual_script_extractor.rb +0 -78
- data/.claude/skills/transcribe-audio/SKILL.md +0 -36
- data/.claude/skills/transcribe-audio/agent_prompt.md +0 -53
- data/.claude/skills/transcribe-audio/prepare_audio_script.rb +0 -48
- data/.claude/skills/transcribe-audio/refine_instructions.md +0 -114
- data/.claude/skills/update-buttercut/SKILL.md +0 -54
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 768b511af86ba148f459f7238a4e181755e9a8e034c1f826194b4b273fa7cb3f
|
|
4
|
+
data.tar.gz: a9a83cbe8000fa315f8716505fd0bc9e21cb2411b743446629296e413ff3fef9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0a70a6a73a80edea617161468519ec22ce8089b21dc95fb5689811eb7221f84c38e3b5b11b833b48dd5e33e712c8a8e12512f00de7cf12723820dbfebae31c6d
|
|
7
|
+
data.tar.gz: 464000a7106249b5a09fac805c97d60063934c745d6cd7efd9e6e06579d25587b71f4532338733f1ca9bf2f864c703dfa17a4c106e6e21adcad293ac4aa394c3
|
data/.claude/settings.local.json
CHANGED
|
@@ -28,7 +28,14 @@
|
|
|
28
28
|
"Bash(gh api:*)",
|
|
29
29
|
"Bash(gh pr:*)",
|
|
30
30
|
"Bash(cp *)",
|
|
31
|
-
"Bash(chmod +x .claude/skills/export-video/export_video.rb)"
|
|
31
|
+
"Bash(chmod +x .claude/skills/export-video/export_video.rb)",
|
|
32
|
+
"Bash(bundle exec *)",
|
|
33
|
+
"Bash(cp libraries/programmer-story-vlog/roughcuts/backstory-aroll_20260507_155307.fcpxml ~/Desktop/)",
|
|
34
|
+
"Bash(grep -v \"^--$\")",
|
|
35
|
+
"Bash(grep -v \"^$\")",
|
|
36
|
+
"Bash(ls ~/code/buttercut-evals/library-processing/)",
|
|
37
|
+
"Bash(caffeinate -dimsu)",
|
|
38
|
+
"Bash(echo \"caffeinate PID: $!\")"
|
|
32
39
|
],
|
|
33
40
|
"deny": [],
|
|
34
41
|
"ask": []
|
data/.claude/skills
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../skills
|
data/CLAUDE.md
CHANGED
|
@@ -1,308 +1 @@
|
|
|
1
|
-
|
|
2
|
-
**ButterCut** is a Ruby gem for generating Final Cut Pro XML from video files with AI-powered rough cut creation. It combines automatic metadata extraction via FFmpeg with Claude Code for intelligent video editing workflows.
|
|
3
|
-
|
|
4
|
-
The project has two main components:
|
|
5
|
-
1. **Ruby Gem** - XML generation library supporting Final Cut Pro X and FCP7/Premiere
|
|
6
|
-
2. **Claude Code Integration** - AI-powered video editing workflow with transcription and rough cut creation
|
|
7
|
-
|
|
8
|
-
## Supported Editors
|
|
9
|
-
|
|
10
|
-
Currently supports:
|
|
11
|
-
- **Final Cut Pro X** (FCPXML 1.8 format)
|
|
12
|
-
- **Adobe Premiere Pro** (xmeml version 5)
|
|
13
|
-
- **DaVinci Resolve** (xmeml version 5)
|
|
14
|
-
|
|
15
|
-
## Core Workflow
|
|
16
|
-
|
|
17
|
-
You are an AI video editor assistant working with a software engineer. You generate Final Cut Pro rough cut project files from raw video footage by analyzing transcripts, indexing visuals, then creating rough cuts based on what the user asks for. Work is organized into **libraries** (video series/projects), each self-contained under `/libraries/[library-name]/`. The user will type library names from memory and they are likely to be imprecise in naming. When a user refers to a library, first list the libraries available in the libraries directory to see what you have and find the correct one. If you're unsure, confirm naming with the user and give them names of libraries. If it's clear what library they're referring to, just start working with that library.
|
|
18
|
-
|
|
19
|
-
### Workflow Steps
|
|
20
|
-
|
|
21
|
-
1. **Setup** → Initialize a new library or work with an existing library
|
|
22
|
-
- Check for existing library in `/libraries/[library-name]/`
|
|
23
|
-
- If new: gather project information (library name, video file locations, language)
|
|
24
|
-
- Create directory structure and library.yaml from template
|
|
25
|
-
- Automatically start footage analysis after setup
|
|
26
|
-
2. **Transcribe** → Use `transcribe-audio`, `analyze-video`, and `summarize-video` skills to process videos
|
|
27
|
-
- First: `transcribe-audio` creates audio transcripts with WhisperX (word-level timing)
|
|
28
|
-
- Then: `analyze-video` adds visual descriptions by extracting and analyzing frames
|
|
29
|
-
- Then: `summarize-video` generates a short markdown summary from each visual transcript
|
|
30
|
-
- All videos must have audio transcripts, visual transcripts, AND summaries before proceeding to rough cut or sequence creation
|
|
31
|
-
3. **Edit** → Use `cut-planner` then `roughcut` to plan and build a timeline from transcripts
|
|
32
|
-
- `cut-planner` reads all summaries in the main thread, proposes 2–3 narrative options, iterates with the user, and writes an approved plan markdown file
|
|
33
|
-
- `roughcut` consumes that plan, spins up a sub-agent that reads the library directly, builds the YAML iteratively, reviews against format conventions, exports the XML, and returns conversational editorial notes the parent uses to dialogue with the user
|
|
34
|
-
- **Rough cuts**: 3–15+ min edits. **Sequences**: 30–60s clips. Same pair of skills, different target duration.
|
|
35
|
-
- **PREREQUISITE:** Check library.yaml to verify all videos have `visual_transcript` and `summary` populated
|
|
36
|
-
4. **Backup** → Use `backup-library` skill to create compressed archives of all libraries
|
|
37
|
-
- Creates timestamped ZIP backup of entire libraries directory
|
|
38
|
-
- Backups are stored in `/backups/` and excluded from git
|
|
39
|
-
|
|
40
|
-
## Library Setup and Management
|
|
41
|
-
|
|
42
|
-
Libraries are the primary abstraction in ButterCut - each library represents a video series or project and is self-contained under `/libraries/[library-name]/`. A library is conceptually similar to a Final Cut Pro library, but uses a simple file structure (YAML, JSON transcripts) optimized for AI analysis rather than FCP's proprietary format.
|
|
43
|
-
|
|
44
|
-
### Initialize Settings
|
|
45
|
-
|
|
46
|
-
Before any library setup, check if `libraries/settings.yaml` exists. If not, copy from template:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
cp templates/settings_template.yaml libraries/settings.yaml
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
If no previous settings.yaml was present, use the ask user question tool to ask the user to confirm or change their defaults (editor and whisper_model).
|
|
53
|
-
|
|
54
|
-
Editor Options:
|
|
55
|
-
- Final Cut Pro X
|
|
56
|
-
- Adobe Premiere Pro
|
|
57
|
-
- DaVinci Resolve
|
|
58
|
-
|
|
59
|
-
Model Options:
|
|
60
|
-
- Small (recommended — pairs well with per-library transcript_refinement)
|
|
61
|
-
- Medium
|
|
62
|
-
- Turbo (Large)
|
|
63
|
-
|
|
64
|
-
Save these options into libraries/settings.yaml.
|
|
65
|
-
|
|
66
|
-
Note: `transcript_refinement` is a **per-library** setting (not global). Ask about it during library setup (see "Gather Project Information" below), not during initial settings setup.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
When creating a new library, read `libraries/settings.yaml` and use the `editor` value to pre-populate the library's `editor` field.
|
|
70
|
-
|
|
71
|
-
### Check for Existing Library
|
|
72
|
-
|
|
73
|
-
**ALWAYS** check if a library already exists before starting setup:
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
ls libraries/[library-name]/library.yaml
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
**If library.yaml exists:**
|
|
80
|
-
- Skip setup entirely - the library is already configured
|
|
81
|
-
- Read the existing library.yaml to understand project status
|
|
82
|
-
- User is returning to existing work
|
|
83
|
-
|
|
84
|
-
**If library directory exists but library.yaml is missing:**
|
|
85
|
-
- Check what files are present (`/transcripts/`, `/roughcuts/`, etc.)
|
|
86
|
-
- Inform user of current state
|
|
87
|
-
- Proceed with creating/recreating library.yaml to restore consistency
|
|
88
|
-
|
|
89
|
-
**If no library directory exists:**
|
|
90
|
-
- Proceed to gather project information and create new library
|
|
91
|
-
|
|
92
|
-
### Gather Project Information
|
|
93
|
-
|
|
94
|
-
Ask the user these questions for new libraries one at a time (never all at once):
|
|
95
|
-
|
|
96
|
-
1. **What do you want to call this project library?**
|
|
97
|
-
- Examples: "bike-locking-video-series", "raiders-2025-highlights", "yo-yo-techniques"
|
|
98
|
-
- Normalize the name:
|
|
99
|
-
- Replace spaces with dashes
|
|
100
|
-
- Convert to lowercase
|
|
101
|
-
- Remove special characters (keep alphanumeric and dashes)
|
|
102
|
-
|
|
103
|
-
2. **Where are the video files located?**
|
|
104
|
-
- Ask: "Where are your video files? You can drag folders or individual files directly into the chat."
|
|
105
|
-
- Verify all files exist before proceeding
|
|
106
|
-
- Inform user of what was found: "Found 5 video files totaling 2.3GB"
|
|
107
|
-
|
|
108
|
-
3. **What language is spoken in these videos?**
|
|
109
|
-
- Ask using AskUserQuestion with options: "English", "Spanish" and a free-text fallback for other languages
|
|
110
|
-
- Save the language name (e.g., "English") to library.yaml
|
|
111
|
-
- Map to language code (e.g., `en`, `es`, `fr`) behind the scenes when needed for transcription
|
|
112
|
-
|
|
113
|
-
4. **Can I proofread the transcripts after they're generated?**
|
|
114
|
-
- Ask using AskUserQuestion with this exact question: "Can I proofread the transcripts after they're generated? I'll use the video's context to fix mistakes."
|
|
115
|
-
- Options: "Yes - Recommended (Use Claude to refine video understanding)" and "No"
|
|
116
|
-
- Save the boolean to `transcript_refinement` in library.yaml (true for Yes, false for No)
|
|
117
|
-
- Default to `true` if the user skips
|
|
118
|
-
|
|
119
|
-
### Create Directory Structure
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
mkdir -p libraries/[library-name]
|
|
123
|
-
mkdir -p libraries/[library-name]/transcripts
|
|
124
|
-
mkdir -p libraries/[library-name]/roughcuts
|
|
125
|
-
mkdir -p libraries/[library-name]/summaries
|
|
126
|
-
mkdir -p libraries/[library-name]/plans
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
Note: A single `tmp/` directory inside the buttercut project root is used for all temporary files. Create subdirectories as needed and delete after use.
|
|
130
|
-
|
|
131
|
-
### Create Library File
|
|
132
|
-
|
|
133
|
-
Duplicate `templates/library_template.yaml` to create `libraries/[library-name]/library.yaml`:
|
|
134
|
-
|
|
135
|
-
For each video file:
|
|
136
|
-
1. Use `ffprobe` to get duration
|
|
137
|
-
2. Add entry to library.yaml with empty `transcript`, `visual_transcript`, and `summary`
|
|
138
|
-
3. Empty fields mean "todo", valid filenames mean "done"
|
|
139
|
-
|
|
140
|
-
The `language` field stores the language code for all videos in this library.
|
|
141
|
-
|
|
142
|
-
Progressively update the `footage_summary` field after each video is transcribed with 1-3 sentences covering subjects, locations, activities, visual style, etc.
|
|
143
|
-
|
|
144
|
-
### Start Footage Analysis
|
|
145
|
-
|
|
146
|
-
After library setup completes, **automatically start analyzing all footage**:
|
|
147
|
-
|
|
148
|
-
1. Inform user: "Library setup complete. Found [N] videos ([total size]). Starting footage analysis..."
|
|
149
|
-
2. Read `libraries/settings.yaml` (for `whisper_model`) and the library's `library.yaml` (for `language`, `transcript_refinement`, `user_context`, `footage_summary`) ONCE in the parent thread. If any expected field is missing, run the appropriate migration first (see Critical Principles below).
|
|
150
|
-
3. Launch `transcribe-audio` agents. Pass these values inline in each agent's prompt:
|
|
151
|
-
- `video_path`, `transcript_output_dir`, `language_code`, `whisper_model`
|
|
152
|
-
- `transcript_refinement` (boolean). If `true`, also pass the current `user_context` and `footage_summary` strings (empty strings are fine — refinement still catches nonsense-token and self-witness fixes).
|
|
153
|
-
4. As each agent completes, update library.yaml with `transcript` (filename only, not full path).
|
|
154
|
-
5. After all audio transcripts complete, launch `analyze-video` agents. Pass inline: `video_path`, `audio_transcript_path`, `visual_transcript_path`.
|
|
155
|
-
6. As each agent completes, update library.yaml with `visual_transcript` (filename only, not full path).
|
|
156
|
-
7. After all visual transcripts complete, summarize each video using the `summarize-video` skill on the **Haiku model**:
|
|
157
|
-
- For each video, first pre-create a skeleton file in the parent: `ruby .claude/skills/summarize-video/summary_skeleton.rb <visual_transcript_path> <summary_output_path>`
|
|
158
|
-
- Then launch the agent passing inline: `visual_transcript_path`, `summary_output_path` (e.g., `libraries/[library-name]/summaries/summary_[videoname].md`)
|
|
159
|
-
- The agent fills the four placeholders via Edit. The skeleton + Edit pattern is required: without it, Haiku frequently refuses Write and dumps markdown into its reply instead.
|
|
160
|
-
8. As each agent completes, update library.yaml with `summary` (filename only, not full path).
|
|
161
|
-
9. Analyze ALL videos before offering to create rough cuts.
|
|
162
|
-
10. **After all analysis completes, automatically create a backup** using the `backup-library` skill.
|
|
163
|
-
|
|
164
|
-
**Contract: sub-agents receive `agent_prompt.md`, not `SKILL.md`.** For parallelizable skills (`transcribe-audio`, `analyze-video`, `summarize-video`), the parent reads `SKILL.md` for dispatch info (parallelism cap, required inputs) and inlines `agent_prompt.md` into the sub-agent's prompt. `SKILL.md` is parent-only.
|
|
165
|
-
|
|
166
|
-
**Note on refinement:** When `transcript_refinement: true`, each `transcribe-audio` agent reviews and corrects its transcript in place before returning, using the `user_context` and `footage_summary` the parent passed in. Empty context strings are fine — the agent still runs and catches nonsense-token and self-witness fixes. The parent still only writes `transcript: <filename>.json` to `library.yaml` after the agent completes.
|
|
167
|
-
|
|
168
|
-
**Terminology:**
|
|
169
|
-
- User-facing: Call it "footage analysis" or "analyzing footage"
|
|
170
|
-
- Internal/file names: Use "transcription" (library.yaml, transcript, etc.)
|
|
171
|
-
|
|
172
|
-
**If user requests rough cut before analysis completes:**
|
|
173
|
-
- Warn: "I can create a rough cut now, but I'll do a better job after analyzing all the footage. Continue anyway?"
|
|
174
|
-
- If user confirms, proceed with rough cut creation
|
|
175
|
-
- Otherwise, wait for analysis to complete
|
|
176
|
-
|
|
177
|
-
## Parallel Transcription Pattern
|
|
178
|
-
|
|
179
|
-
When processing multiple videos, use parallel agents for maximum throughput:
|
|
180
|
-
|
|
181
|
-
1. **Parent agent responsibilities:**
|
|
182
|
-
- Read `library.yaml` and `settings.yaml` once to gather: videos needing work, `language_code`, `whisper_model`, `transcript_refinement`, `user_context`, `footage_summary`.
|
|
183
|
-
- Launch Task agents with transcribe-audio or analyze-video skills, passing all needed values **inline in the prompt**.
|
|
184
|
-
- Update library.yaml sequentially as agents complete.
|
|
185
|
-
- Handle errors and retries.
|
|
186
|
-
|
|
187
|
-
2. **Child agent (transcribe-audio/analyze-video) responsibilities:**
|
|
188
|
-
- Process ONE video file using only the inputs passed inline by the parent.
|
|
189
|
-
- Run WhisperX or frame extraction.
|
|
190
|
-
- Prepare and clean transcript JSON.
|
|
191
|
-
- Return structured response with file paths.
|
|
192
|
-
|
|
193
|
-
Each skill's `agent_prompt.md` documents its own IO contract — including whether the sub-agent reads or writes `library.yaml`.
|
|
194
|
-
|
|
195
|
-
3. **Benefits:**
|
|
196
|
-
- Multiple videos process simultaneously
|
|
197
|
-
- No race conditions on shared YAML file
|
|
198
|
-
- Clear separation of concerns
|
|
199
|
-
- Easy to retry individual failed videos
|
|
200
|
-
|
|
201
|
-
## Critical Principles
|
|
202
|
-
|
|
203
|
-
Each library has a `library.yaml` file that serves as your persistent memory and the SOURCE OF TRUTH. This file contains all library metadata, footage descriptions, transcription status, and key learnings. Always read this file when working on a library and you need guidance for how/where to save files.
|
|
204
|
-
|
|
205
|
-
**Migrate legacy library.yaml files before doing anything else.** Every time you read a library.yaml, check it against the canonical field list in `templates/library_template.yaml`. If any expected field is missing, or any field appears under an old name, the library predates a feature and MUST be migrated before you do any further work on it — no rough cuts, sequences, transcription, exports, or anything else until the schema is current. The migrations are fast, idempotent, and safe; don't ask the user for permission and don't describe them as optional "tidying." Just run them.
|
|
206
|
-
|
|
207
|
-
Known migration triggers (match each to a `scripts/NNN_migrate_*.rb` script via CHANGELOG.md):
|
|
208
|
-
|
|
209
|
-
- `editor` missing (added in 0.4.0)
|
|
210
|
-
- `transcript_refinement` missing (added in [Unreleased]; missing means "predates the feature, default to `false`" — NOT the template default of `true`)
|
|
211
|
-
- `footage_summary` missing OR old name `footage_description` present (renamed in [Unreleased])
|
|
212
|
-
- video entries with `summary` missing (added in [Unreleased]; missing means "todo", default to empty string)
|
|
213
|
-
- video entries with `transcript_path` / `visual_transcript_path` (renamed to `transcript` / `visual_transcript` in 0.3.0)
|
|
214
|
-
- video entries with `file_size_mb` (removed in 0.3.0)
|
|
215
|
-
|
|
216
|
-
A missing field is not the same as a field set to the template default — the template default only applies to freshly created libraries. If you see a schema issue not on this list, still check CHANGELOG.md; the list may be behind. After running migrations, re-read the library.yaml and continue with whatever the user asked for.
|
|
217
|
-
|
|
218
|
-
**Keep main-thread context minimal.** The main thread orchestrates; sub-agents do the heavy work and return concise summaries. Don't read full transcript JSON, visual transcript JSON, or extracted frames into the main thread as part of routine workflow — across a large library this bloats context fast. Trust sub-agent return messages when updating library.yaml. Direct user requests ("show me transcript X") are fine; the rule is about automatic workflow behavior.
|
|
219
|
-
|
|
220
|
-
**Use actual filenames.** Never use generic labels like "Video 1" or "Clip A" - always reference actual filenames like "DJI_20250423171212_0210_D.mov" for clear traceability.
|
|
221
|
-
|
|
222
|
-
**Visual transcripts and summaries are mandatory.** Before creating any rough cut or sequence, verify ALL videos have audio transcripts, visual transcripts, AND summaries. Check `library.yaml` — every video entry must have `visual_transcript` and `summary` with filenames (not empty, null, or ""). Transcripts are stored in `libraries/[library-name]/transcripts/`; summaries in `libraries/[library-name]/summaries/`. Visual descriptions and summaries are essential for shot selection and pacing decisions.
|
|
223
|
-
|
|
224
|
-
**Single-track timelines only.** ButterCut produces one sequential video track. Each clip's own audio plays during that clip — there is no second video track for cutaways layered over a continuing voiceover, and no separate audio track. When planning or pitching cuts, never propose "B-roll over VO," "story under meetup footage," picture-in-picture, or any structure that assumes a clip's audio continues while different visuals play on top. Cutaways are fine, but they're hard cuts: when you cut to the wide shot, you cut to that shot's audio too. Plan every cut as a strictly linear sequence of clips.
|
|
225
|
-
|
|
226
|
-
**Be curious and ask questions.** Occasionally ask users questions about their libraries and footage to better understand context, creative intent, and preferences. When you receive answers, add this information to the `user_context` key in the library.yaml file. This builds institutional knowledge that improves future rough cut and sequence decisions and helps maintain continuity across editing sessions.
|
|
227
|
-
|
|
228
|
-
## Key Reminders
|
|
229
|
-
|
|
230
|
-
- Never modify source video files - always preserve originals
|
|
231
|
-
- Flag areas needing human judgment rather than making assumptions
|
|
232
|
-
- When you have lots of videos to process (dozens or hundreds isn't out of the ordinary), create a reasonable task list with 5 tasks and then a final task that says to check the yaml processing file to see if you need to then generate more tasks. This way users can see progress and the agent doesn't get overwhelmed.
|
|
233
|
-
- Generally avoid writing one-off scripts, but if you do need to write one, write it in Ruby unless you have a very strong reason to write in another language.
|
|
234
|
-
- Parallelism caps live in each skill's `SKILL.md` (parent brief). Read it before dispatching.
|
|
235
|
-
- Whenever you export XML files, include a datetime timestamp in the filename so it's clear when they were generated.
|
|
236
|
-
|
|
237
|
-
## Programming Style
|
|
238
|
-
|
|
239
|
-
When you add a Ruby script under `.claude/scripts/` or similar, follow these conventions:
|
|
240
|
-
|
|
241
|
-
- **One class per script; file name matches the class name.** `ScriptExtractor` lives in `script_extractor.rb`.
|
|
242
|
-
- **Single high-level entry point.** Expose a class method (`Klass.extract`, `Klass.run`, etc.) that calls `new(...).extract` internally — callers shouldn't need to know about instantiation.
|
|
243
|
-
- **Break the work into small private methods with clear names** (`load_transcript`, `format_script`, `write_output`, `report`). The public entry point should read like a short outline of the workflow.
|
|
244
|
-
- **Required arguments are required.** Don't silently default `nil`/missing args — raise `ArgumentError` in `initialize` if a required value is missing or empty. No hidden fallback paths.
|
|
245
|
-
- **Keep CLI arg parsing out of the class.** Use a bottom-of-file `if __FILE__ == $PROGRAM_NAME` block to parse `ARGV`, validate file paths, print a usage line, and delegate to the class.
|
|
246
|
-
|
|
247
|
-
## Project Structure
|
|
248
|
-
|
|
249
|
-
- `lib/buttercut.rb` - Factory class that creates editor-specific generators
|
|
250
|
-
- `lib/buttercut/editor_base.rb` - Shared validation, metadata extraction, and timeline math
|
|
251
|
-
- `lib/buttercut/fcpx.rb` - Final Cut Pro X implementation (FCPXML 1.8)
|
|
252
|
-
- `lib/buttercut/fcp7.rb` - Final Cut Pro 7 / Premiere / DaVinci Resolve implementation (xmeml v5)
|
|
253
|
-
- `.claude/skills/` - Claude Code skills for AI-powered workflow
|
|
254
|
-
- `spec/` - RSpec test suite
|
|
255
|
-
- `templates/` - Library and project templates
|
|
256
|
-
- `libraries/` - Working directory for user's video projects (gitignored)
|
|
257
|
-
- `libraries/settings.yaml` - User settings (editor, whisper_model) — created from template on first library setup
|
|
258
|
-
- `backups/` - Compressed library backups (transcriptions, roughcuts, etc) (gitignored)
|
|
259
|
-
|
|
260
|
-
## Design Philosophy
|
|
261
|
-
|
|
262
|
-
ButterCut is designed to be simple, automatic and geared toward working with non technical people using ButterCut via a client, Claude Cowork or Claude Code.
|
|
263
|
-
|
|
264
|
-
- **Input**: Array of full file paths to video files
|
|
265
|
-
- **Output**: Working XML file ready to import into the non-technical user's video editor (Final Cut, Premiere, Resolve)
|
|
266
|
-
- **Automatic Metadata Extraction**: Uses FFmpeg internally to extract video properties (duration, resolution, frame rate, audio rate, etc.)
|
|
267
|
-
|
|
268
|
-
The user should not need to understand video codecs, frame rates, or FCPXML structure - just provide file paths and get working XML. We should talk to the user from a video editing perspective, not a technical software engineer perspective.
|
|
269
|
-
|
|
270
|
-
### Vocabulary — talk like an editor, not a developer
|
|
271
|
-
|
|
272
|
-
The user is a video editor, not a programmer (generally). They don't need to know what file the cut lives in, what tool transcribed their audio, or which skill or sub-agent is doing the work behind the scenes. Implementation details are for the codebase; user-facing chat stays in the language of video editing. When in doubt, drop the technical noun entirely and just say what's happening. Skills, code, etc, should obviously stay technical, but keep that out when chatting with the user.
|
|
273
|
-
|
|
274
|
-
Editor vocabulary that's always fine: rough cut, sequence, scene, beat, timeline, B-roll, cutaway, shot, take, transcript, footage, library, clip, splice, Final Cut, Premiere, Resolve.
|
|
275
|
-
|
|
276
|
-
Don't say → say (one per category — generalize the pattern, don't treat as a lookup table):
|
|
277
|
-
|
|
278
|
-
- *File/format nouns:* "I'll update the YAML" / "regenerate the FCPXML" → "I'll update the cut" / "I'll re-export it for Final Cut"
|
|
279
|
-
- *Architecture nouns:* "I'll spin up a sub-agent" / "running the roughcut skill" / "the parent thread" → just speak in first person ("I'll build the cut")
|
|
280
|
-
- *Tools and models:* "WhisperX will transcribe" / "running ffmpeg" / "I used Haiku for the summary" → "I'll transcribe the audio" / "I'll analyze the visuals" (don't name models)
|
|
281
|
-
- *Internal field names:* "I'll update footage_summary" / "transcript_refinement is true" → "I'll note that about your footage" / "I'll proofread the transcripts"
|
|
282
|
-
- *Paths in casual chat:* `.fcpxml`, `.json`, `libraries/foo/transcripts/…` → name the artifact ("the Final Cut export", "the transcript") and only show the path at final delivery or when the user needs to grab the file
|
|
283
|
-
|
|
284
|
-
Two exceptions where technical detail IS appropriate:
|
|
285
|
-
1. The user explicitly asks ("where is it saved?", "what format?") — answer plainly.
|
|
286
|
-
2. Final delivery summary — naming the export file path is genuinely useful so they can find it.
|
|
287
|
-
|
|
288
|
-
## Development Commands
|
|
289
|
-
|
|
290
|
-
### Testing
|
|
291
|
-
RSpec tests for the XML generation library. This doesn't include agent or end to end testing.
|
|
292
|
-
```bash
|
|
293
|
-
# Install dependencies
|
|
294
|
-
bundle install
|
|
295
|
-
|
|
296
|
-
# Run all tests
|
|
297
|
-
bundle exec rspec
|
|
298
|
-
|
|
299
|
-
# Run specific test file
|
|
300
|
-
bundle exec rspec spec/buttercut_spec.rb
|
|
301
|
-
|
|
302
|
-
# Run specific test
|
|
303
|
-
bundle exec rspec spec/buttercut_spec.rb:10
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
## Claude Skills
|
|
307
|
-
|
|
308
|
-
When creating new Claude skills, aim to keep them as brief as possible. Use active voice to help condense instructions. Use simple, plain language.
|
|
1
|
+
@AGENTS.md
|
data/LICENSE
CHANGED
|
@@ -1,21 +1,106 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
Required Notice: Copyright 2025 TubeSalt LLC
|
|
2
|
+
|
|
3
|
+
## Additional Permission: Commercial Output
|
|
4
|
+
|
|
5
|
+
The licensor grants the following permission in addition to the rights
|
|
6
|
+
granted by the PolyForm Noncommercial License 1.0.0 below.
|
|
7
|
+
|
|
8
|
+
You may use the software to produce video files, project files, edits,
|
|
9
|
+
exports, and other creative works ("Outputs") for any purpose, including
|
|
10
|
+
commercial purposes. You retain all rights to your Outputs, and the
|
|
11
|
+
licensor claims no ownership of them. Producing or distributing your
|
|
12
|
+
Outputs, including for monetary compensation, is not by itself a
|
|
13
|
+
commercial use of the software.
|
|
14
|
+
|
|
15
|
+
This Additional Permission covers using the software as a tool to make
|
|
16
|
+
videos. It does **not** permit any of the following, which remain
|
|
17
|
+
restricted to noncommercial purposes under the license below:
|
|
18
|
+
|
|
19
|
+
- Distributing, sublicensing, or selling the software (in original or
|
|
20
|
+
modified form), whether on its own or as part of another product;
|
|
21
|
+
- Offering the software (in original or modified form) as a hosted,
|
|
22
|
+
managed, or Software-as-a-Service product;
|
|
23
|
+
- Incorporating the software into a commercial software product,
|
|
24
|
+
plugin, extension, or service.
|
|
25
|
+
|
|
26
|
+
Plainly: you may use ButterCut to make commercial videos. You may not
|
|
27
|
+
use ButterCut to make commercial software.
|
|
28
|
+
|
|
29
|
+
If any term of this Additional Permission conflicts with the PolyForm
|
|
30
|
+
Noncommercial License 1.0.0 below, this Additional Permission controls.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
# PolyForm Noncommercial License 1.0.0
|
|
35
|
+
|
|
36
|
+
<https://polyformproject.org/licenses/noncommercial/1.0.0>
|
|
37
|
+
|
|
38
|
+
## Acceptance
|
|
39
|
+
|
|
40
|
+
In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
|
|
41
|
+
|
|
42
|
+
## Copyright License
|
|
43
|
+
|
|
44
|
+
The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license).
|
|
45
|
+
|
|
46
|
+
## Distribution License
|
|
47
|
+
|
|
48
|
+
The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license).
|
|
49
|
+
|
|
50
|
+
## Notices
|
|
51
|
+
|
|
52
|
+
You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example:
|
|
53
|
+
|
|
54
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
55
|
+
|
|
56
|
+
## Changes and New Works License
|
|
57
|
+
|
|
58
|
+
The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
|
|
59
|
+
|
|
60
|
+
## Patent License
|
|
61
|
+
|
|
62
|
+
The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
|
|
63
|
+
|
|
64
|
+
## Noncommercial Purposes
|
|
65
|
+
|
|
66
|
+
Any noncommercial purpose is a permitted purpose.
|
|
67
|
+
|
|
68
|
+
## Personal Uses
|
|
69
|
+
|
|
70
|
+
Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose.
|
|
71
|
+
|
|
72
|
+
## Noncommercial Organizations
|
|
73
|
+
|
|
74
|
+
Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding.
|
|
75
|
+
|
|
76
|
+
## Fair Use
|
|
77
|
+
|
|
78
|
+
You may have "fair use" rights for the software under the law. These terms do not limit them.
|
|
79
|
+
|
|
80
|
+
## No Other Rights
|
|
81
|
+
|
|
82
|
+
These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
|
|
83
|
+
|
|
84
|
+
## Patent Defense
|
|
85
|
+
|
|
86
|
+
If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
|
|
87
|
+
|
|
88
|
+
## Violations
|
|
89
|
+
|
|
90
|
+
The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
|
|
91
|
+
|
|
92
|
+
## No Liability
|
|
93
|
+
|
|
94
|
+
***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
|
|
95
|
+
|
|
96
|
+
## Definitions
|
|
97
|
+
|
|
98
|
+
The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
|
|
99
|
+
|
|
100
|
+
**You** refers to the individual or entity agreeing to these terms.
|
|
101
|
+
|
|
102
|
+
**Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
|
|
103
|
+
|
|
104
|
+
**Your licenses** are all the licenses granted to you for the software under these terms.
|
|
105
|
+
|
|
106
|
+
**Use** means anything you do with the software requiring one of your licenses.
|
data/README.md
CHANGED
|
@@ -44,7 +44,7 @@ For manual installation, see [docs/installation.md](docs/installation.md).
|
|
|
44
44
|
|
|
45
45
|
## Usage
|
|
46
46
|
|
|
47
|
-
First tell Claude to create a **Library**. A library organizes your video footage along with
|
|
47
|
+
First tell Claude to create a **Library**. A library organizes your video footage along with the transcripts, contact sheets, and summaries Claude needs to edit it. Then tell Claude you want to create a **rough cut** or **sequence**.
|
|
48
48
|
|
|
49
49
|
### Creating a Video Library
|
|
50
50
|
|
|
@@ -60,14 +60,14 @@ You:
|
|
|
60
60
|
|
|
61
61
|
Claude: [Automatically processes all videos]
|
|
62
62
|
✓ Creates library structure
|
|
63
|
-
✓ Transcribes audio
|
|
64
|
-
✓
|
|
65
|
-
✓
|
|
63
|
+
✓ Transcribes audio
|
|
64
|
+
✓ Builds a contact sheet for every clip
|
|
65
|
+
✓ Writes a short summary of each clip
|
|
66
66
|
|
|
67
67
|
Result: Full footage analysis ready for rough cut creation
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
Claude handles the parallel processing, metadata extraction, and
|
|
70
|
+
Claude handles the parallel processing, metadata extraction, and analysis. See the [full walkthrough](docs/example-library-setup.md) for a detailed example of me setting up a library from my wedding footage.
|
|
71
71
|
|
|
72
72
|
### Creating a Roughcut or Sequence
|
|
73
73
|
|
|
@@ -76,7 +76,7 @@ Once your library is analyzed, Claude can create rough cuts through an interacti
|
|
|
76
76
|
```plaintext
|
|
77
77
|
You: "Let's create a new roughcut"
|
|
78
78
|
|
|
79
|
-
Claude: [Loads
|
|
79
|
+
Claude: [Loads cut skill and analyzes footage]
|
|
80
80
|
What should this roughcut focus on?
|
|
81
81
|
- Full story
|
|
82
82
|
- Just the meetup coverage
|
|
@@ -100,7 +100,7 @@ Claude: [Asks which video editor you want to use]
|
|
|
100
100
|
You: "Final Cut Pro X"
|
|
101
101
|
|
|
102
102
|
Claude: [Creates roughcut with editorial decisions]
|
|
103
|
-
✓
|
|
103
|
+
✓ Reviewed contact sheets and transcripts
|
|
104
104
|
✓ Selected 29 clips (4:32 total)
|
|
105
105
|
✓ Exported to FCPXML
|
|
106
106
|
|
|
@@ -120,7 +120,12 @@ ButterCut was inspired by ambitious open source work from [Chris Hocking](https:
|
|
|
120
120
|
|
|
121
121
|
## License
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
ButterCut is open source under the [PolyForm Noncommercial License 1.0.0 with a Commercial Output exception](LICENSE).
|
|
124
|
+
|
|
125
|
+
- **You can use ButterCut to make videos commercially.** Cut a YouTube video for ad revenue, edit a paid client project, deliver a sponsored brand piece — all fine. The videos are yours, and the licensor claims no rights to them.
|
|
126
|
+
- **You can't repackage ButterCut as commercial software.** Selling, hosting, or bundling the tool itself (or a fork of it) into a commercial product, plugin, or SaaS requires a separate commercial license from TubeSalt LLC.
|
|
127
|
+
|
|
128
|
+
Personal, hobby, research, and educational use of the software is also free under the underlying license. If you'd like a commercial software license, reach out.
|
|
124
129
|
|
|
125
130
|
## Contributing
|
|
126
131
|
|
data/lib/buttercut/version.rb
CHANGED
|
@@ -14,10 +14,21 @@ footage_summary: "No footage analyzed yet."
|
|
|
14
14
|
# "This footage appears to be wedding footage. It includes the bride and groom getting dressed, preparing for the wedding ceremomy, the ceremony, and the post ceremony dinner and party."
|
|
15
15
|
# "This footage appears to be a vlog. The footage starts in The Richmond District in San Francisco, includes a bus ride on the 38R, and concludes at a Ruby Meetup in downtown San Francisco."
|
|
16
16
|
|
|
17
|
-
# Video files and
|
|
17
|
+
# Video files and analysis status
|
|
18
|
+
#
|
|
19
|
+
# Per clip, analysis fills three fields:
|
|
20
|
+
# transcript — audio transcript JSON (word-level timing, in transcripts/);
|
|
21
|
+
# also the source for on-demand dialogue extraction via
|
|
22
|
+
# skills/analyze-video/script_extractor.rb
|
|
23
|
+
# contact_sheet — _full.jpg visual overview (in contact_sheets/); per-segment
|
|
24
|
+
# sheets for clips >10 min live alongside on disk
|
|
25
|
+
# summary — markdown overview (in summaries/)
|
|
26
|
+
#
|
|
27
|
+
# Note: visual_transcript is deprecated. Older libraries may still carry the
|
|
28
|
+
# field; new libraries use the contact_sheet field instead.
|
|
18
29
|
videos:
|
|
19
30
|
- path: /full/path/to/video_file.mp4
|
|
20
31
|
duration: "00:05:32"
|
|
21
32
|
transcript: # filename only (stored in libraries/[library-name]/transcripts/)
|
|
22
|
-
|
|
23
|
-
summary: # filename only (summary_*.md
|
|
33
|
+
contact_sheet: # filename only (_full.jpg in libraries/[library-name]/contact_sheets/)
|
|
34
|
+
summary: # filename only (summary_*.md in libraries/[library-name]/summaries/)
|
data/templates/plan_template.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
Cut Plan Template — written by `cut
|
|
2
|
+
Cut Plan Template — written and consumed by the `cut` skill's Roughcut path (see `skills/cut/roughcut_planning.md`).
|
|
3
3
|
|
|
4
4
|
Fill in every section. Delete this comment block before saving.
|
|
5
5
|
The plan is editorial direction; the build agent picks the exact clips
|
|
@@ -11,3 +11,9 @@ whisper_model: small
|
|
|
11
11
|
|
|
12
12
|
# After exporting a roughcut, also drop a copy of the XML on the Desktop for easy import
|
|
13
13
|
save_to_desktop_after_export: true
|
|
14
|
+
|
|
15
|
+
# Where to write library backup archives.
|
|
16
|
+
# Defaults to ~/Documents/buttercut-video-editor-backups so backups live outside
|
|
17
|
+
# the project directory and survive a fresh clone or `update-buttercut` run.
|
|
18
|
+
# Set to a different absolute path (or one starting with ~) to redirect.
|
|
19
|
+
# backups_dir: ~/Documents/buttercut-video-editor-backups
|