buttercut 0.4.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.
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env ruby
2
+ # Export rough cut YAML to Final Cut Pro XML using ButterCut
3
+
4
+ require 'date'
5
+ require 'yaml'
6
+ require 'buttercut'
7
+
8
+ def timecode_to_seconds(timecode)
9
+ # Convert HH:MM:SS or HH:MM:SS.s to seconds (supports decimal seconds)
10
+ parts = timecode.split(':')
11
+ hours = parts[0].to_i
12
+ minutes = parts[1].to_i
13
+ seconds = parts[2].to_f # to_f handles both "03" and "03.5"
14
+ hours * 3600 + minutes * 60 + seconds
15
+ end
16
+
17
+ def main
18
+ if ARGV.length < 2 || ARGV.length > 3
19
+ puts "Usage: #{$0} <roughcut.yaml> <output.xml> [editor]"
20
+ puts " editor: fcpx (default), premiere, or resolve"
21
+ exit 1
22
+ end
23
+
24
+ roughcut_path = ARGV[0]
25
+ output_path = ARGV[1]
26
+ editor_choice = ARGV[2] || 'fcpx'
27
+
28
+ unless File.exist?(roughcut_path)
29
+ puts "Error: Rough cut file not found: #{roughcut_path}"
30
+ exit 1
31
+ end
32
+
33
+ # Load rough cut YAML
34
+ roughcut = YAML.load_file(roughcut_path, permitted_classes: [Date, Time, Symbol])
35
+
36
+ # Find library name from path
37
+ # Path pattern: libraries/[library-name]/roughcuts/[roughcut-name].yaml
38
+ library_match = roughcut_path.match(%r{libraries/([^/]+)/roughcuts})
39
+ unless library_match
40
+ puts "Error: Could not extract library name from path: #{roughcut_path}"
41
+ exit 1
42
+ end
43
+ library_name = library_match[1]
44
+
45
+ # Load library file to get full video paths
46
+ library_yaml = "libraries/#{library_name}/library.yaml"
47
+ unless File.exist?(library_yaml)
48
+ puts "Error: Library file not found: #{library_yaml}"
49
+ exit 1
50
+ end
51
+
52
+ library_data = YAML.load_file(library_yaml, permitted_classes: [Date, Time, Symbol])
53
+
54
+ # Build lookup map: filename -> full path
55
+ video_paths = {}
56
+ library_data['videos'].each do |video|
57
+ filename = File.basename(video['path'])
58
+ video_paths[filename] = video['path']
59
+ end
60
+
61
+ # Convert rough cut clips to ButterCut format
62
+ buttercut_clips = []
63
+
64
+ roughcut['clips'].each do |clip|
65
+ source_file = clip['source_file']
66
+
67
+ unless video_paths[source_file]
68
+ puts "Warning: Source file not found in library data: #{source_file}"
69
+ next
70
+ end
71
+
72
+ full_path = video_paths[source_file]
73
+ start_at = timecode_to_seconds(clip['in_point'])
74
+ out_point = timecode_to_seconds(clip['out_point'])
75
+ duration = out_point - start_at
76
+
77
+ buttercut_clips << {
78
+ path: full_path,
79
+ start_at: start_at.to_f,
80
+ duration: duration.to_f
81
+ }
82
+ end
83
+
84
+ # Validate and normalize editor choice
85
+ editor_symbol = case editor_choice.downcase
86
+ when 'fcpx', 'finalcutpro', 'finalcut', 'fcp'
87
+ :fcpx
88
+ when 'premiere', 'premierepro', 'adobepremiere'
89
+ :fcp7
90
+ when 'resolve', 'davinci', 'davinciresolve'
91
+ :fcp7
92
+ else
93
+ puts "Error: Unknown editor '#{editor_choice}'. Use 'fcpx', 'premiere', or 'resolve'"
94
+ exit 1
95
+ end
96
+
97
+ editor_name = editor_symbol == :fcpx ? "Final Cut Pro X" : "#{editor_choice.capitalize}"
98
+
99
+ puts "Converting #{buttercut_clips.length} clips to #{editor_name} XML..."
100
+
101
+ generator = ButterCut.new(buttercut_clips, editor: editor_symbol)
102
+ generator.save(output_path)
103
+
104
+ puts "\n✓ Rough cut exported to: #{output_path}"
105
+ end
106
+
107
+ main
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: setup
3
+ description: Sets up a Mac for ButterCut. Installs all required dependencies (Homebrew, Ruby, Python, FFmpeg, WhisperX). Use when user says "install buttercut", "set up my mac", "get started", "first time setup", "install dependencies" or "check my installation".
4
+ ---
5
+
6
+ # Skill: Mac Setup
7
+
8
+ Sets up a Mac for ButterCut. Two installation paths available based on user preference.
9
+
10
+ ## Step 1: Check Current State
11
+
12
+ First, run the verification script to see what's already installed:
13
+
14
+ ```bash
15
+ ruby .claude/skills/setup/verify_install.rb
16
+ ```
17
+
18
+ If all dependencies pass, inform the user they're ready to go.
19
+
20
+ ## Step 2: Ask User Preference
21
+
22
+ If dependencies are missing, use AskUserQuestion:
23
+
24
+ ```
25
+ Question: "How would you like to install ButterCut?"
26
+ Header: "Install type"
27
+ Options:
28
+ 1. "Simple (recommended)" - "Fully automatic setup. We'll install everything for you using sensible defaults."
29
+ 2. "Advanced" - "For developers who want control. You manage Ruby/Python versions with your preferred tools."
30
+ ```
31
+
32
+ ## Step 3: Run Appropriate Setup
33
+
34
+ Based on user choice:
35
+
36
+ - **Simple**: Read and follow `.claude/skills/setup/simple-setup.md`
37
+ - **Advanced**: Read and follow `.claude/skills/setup/advanced-setup.md`
38
+
39
+ ## Step 4: Verify Installation
40
+
41
+ After setup completes, run verification again:
42
+
43
+ ```bash
44
+ ruby .claude/skills/setup/verify_install.rb
45
+ ```
46
+
47
+ Report results to user.
@@ -0,0 +1,141 @@
1
+ # Advanced Setup (Developers)
2
+
3
+ For developers who manage their own Ruby/Python environments. This guide tells you what's needed; you decide how to install it.
4
+
5
+ ## Required Versions
6
+
7
+ Check `.ruby-version` and `.python-version` in the project root:
8
+
9
+ - **Ruby**: 3.3.6
10
+ - **Python**: 3.12.8
11
+
12
+ These files are compatible with rbenv, pyenv, asdf, mise, and most version managers.
13
+
14
+ ## Checklist
15
+
16
+ Work through each item. Skip any you already have.
17
+
18
+ ### 1. Xcode Command Line Tools
19
+
20
+ ```bash
21
+ xcode-select -p 2>/dev/null || xcode-select --install
22
+ ```
23
+
24
+ ### 2. Homebrew
25
+
26
+ Required for FFmpeg and libyaml. If you prefer another package manager, adapt accordingly.
27
+
28
+ **Note:** Homebrew installation requires interactive terminal access (password prompts, confirmations). If running via an agent, the user must run the install command manually.
29
+
30
+ ```bash
31
+ which brew || /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
32
+ ```
33
+
34
+ ### 3. Libyaml (Ruby Dependency)
35
+
36
+ Required for Ruby's psych extension. Install before compiling Ruby:
37
+
38
+ ```bash
39
+ brew install libyaml
40
+ ```
41
+
42
+ ### 4. Ruby 3.3.6
43
+
44
+ Install using your preferred version manager (rbenv, asdf, mise, rvm, etc.).
45
+
46
+ The project includes `.ruby-version` which most managers auto-detect.
47
+
48
+ Verify:
49
+
50
+ ```bash
51
+ ruby --version # Should show 3.3.6
52
+ ```
53
+
54
+ ### 5. Bundler
55
+
56
+ ```bash
57
+ gem install bundler
58
+ ```
59
+
60
+ ### 6. Python 3.12.8
61
+
62
+ Install using your preferred version manager (pyenv, asdf, mise, etc.).
63
+
64
+ The project includes `.python-version` which most managers auto-detect.
65
+
66
+ Verify:
67
+
68
+ ```bash
69
+ python3 --version # Should show 3.12.8
70
+ ```
71
+
72
+ ### 7. FFmpeg
73
+
74
+ ```bash
75
+ brew install ffmpeg
76
+ ```
77
+
78
+ Or install via your preferred method.
79
+
80
+ ### 8. WhisperX
81
+
82
+ Two options depending on how you manage Python:
83
+
84
+ **Option A: Virtual Environment (Recommended)**
85
+
86
+ Isolates WhisperX dependencies. Creates a wrapper script for easy access.
87
+
88
+ ```bash
89
+ mkdir -p ~/.buttercut
90
+ python3 -m venv ~/.buttercut/venv
91
+ source ~/.buttercut/venv/bin/activate
92
+ pip install --upgrade pip
93
+ pip install whisperx
94
+ deactivate
95
+
96
+ # Create wrapper script
97
+ cat > ~/.buttercut/whisperx << 'EOF'
98
+ #!/bin/bash
99
+ source ~/.buttercut/venv/bin/activate
100
+ whisperx "$@"
101
+ deactivate
102
+ EOF
103
+ chmod +x ~/.buttercut/whisperx
104
+
105
+ # Add to PATH (adjust for your shell)
106
+ echo 'export PATH="$HOME/.buttercut:$PATH"' >> ~/.zshrc
107
+ ```
108
+
109
+ **Option B: Direct pip install**
110
+
111
+ If you manage Python environments yourself and want whisperx globally available:
112
+
113
+ ```bash
114
+ pip install whisperx
115
+ ```
116
+
117
+ Ensure `whisperx` is in your PATH.
118
+
119
+ ### 9. ButterCut Ruby Dependencies
120
+
121
+ From the buttercut directory:
122
+
123
+ ```bash
124
+ bundle install
125
+ ```
126
+
127
+ ## Verification
128
+
129
+ Run the verification script:
130
+
131
+ ```bash
132
+ ruby .claude/skills/setup/verify_install.rb
133
+ ```
134
+
135
+ All items should show OK.
136
+
137
+ ## Notes
138
+
139
+ - The `.mise.toml` file is provided for mise users but is not required
140
+ - WhisperX uses CPU-only mode for simplicity (no CUDA/GPU setup needed)
141
+ - If you use pyenv-virtualenv or similar, you can install whisperx in a dedicated virtualenv instead of `~/.buttercut/venv`
@@ -0,0 +1,185 @@
1
+ # Simple Setup (Non-Technical Users)
2
+
3
+ Fully automatic installation. Run each step in order, waiting for each to complete. Don't move forward until each step is successful. This may be a non-technical user so adjust your explanations accordingly.
4
+
5
+ **Note:** ButterCut encourages the use of the CPU version of WhisperX only. This simplifies installation and works reliably on all modern Macs with Apple Silicon.
6
+
7
+ ## Step 0: Check Install Location
8
+
9
+ Check the current working directory. Warn if ButterCut is in a problematic location:
10
+
11
+ **Problematic locations:**
12
+ - `~/Desktop/` - Desktop gets cluttered, easy to accidentally delete
13
+ - `~/Downloads/` - Often cleaned up automatically
14
+ - `~/Library/Mobile Documents/` (iCloud) - Sync causes issues with git and large files
15
+ - Any path containing spaces - Some CLI tools have issues
16
+
17
+ **Recommended locations:**
18
+ - `~/code/buttercut`
19
+ - `~/projects/buttercut`
20
+
21
+ If in a problematic location, ask if they'd like to move it. If yes:
22
+
23
+ 1. Run `mkdir -p ~/code` (or `~/projects` if that exists)
24
+ 2. Run `cp -R [current-path] ~/code/buttercut`
25
+ 3. Tell the user:
26
+ ```
27
+ I've copied ButterCut to ~/code/buttercut. To finish:
28
+ 1. Delete [current-path] (drag to Trash)
29
+ 2. Run this in Terminal: cd ~/code/buttercut && claude
30
+ ```
31
+
32
+ If they prefer to stay in the current location, continue with setup.
33
+
34
+ ## Step 1: Xcode Command Line Tools
35
+
36
+ ```bash
37
+ xcode-select -p 2>/dev/null || xcode-select --install
38
+ ```
39
+
40
+ If `xcode-select --install` runs, a GUI dialog appears. **Tell user to click "Install" and wait** (5-10 minutes). Then verify:
41
+
42
+ ```bash
43
+ xcode-select -p
44
+ ```
45
+
46
+ Should return `/Library/Developer/CommandLineTools` or similar.
47
+
48
+ ## Step 2: Homebrew (Manual Installation Required)
49
+
50
+ Check if Homebrew is installed:
51
+
52
+ ```bash
53
+ which brew
54
+ ```
55
+
56
+ If not installed, **tell the user to run the install command themselves**. Homebrew requires interactive terminal access (password prompts, confirmations) and cannot be installed by the agent directly.
57
+
58
+ Tell the user to run:
59
+
60
+ ```bash
61
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
62
+ ```
63
+
64
+ Wait for the user to confirm installation is complete before continuing.
65
+
66
+ After install, add to PATH (Apple Silicon):
67
+
68
+ ```bash
69
+ eval "$(/opt/homebrew/bin/brew shellenv)"
70
+ ```
71
+
72
+ Verify with `brew --version`. Don't proceed until brew works.
73
+
74
+ Install libyaml (required for Ruby's psych extension):
75
+
76
+ ```bash
77
+ brew install libyaml
78
+ ```
79
+
80
+ ## Step 3: Mise (Version Manager)
81
+
82
+ ```bash
83
+ which mise || brew install mise
84
+ ```
85
+
86
+ Activate mise in shell profile:
87
+
88
+ ```bash
89
+ # Detect shell and add mise activation
90
+ if [[ "$SHELL" == *"zsh"* ]]; then
91
+ grep -q 'mise activate' ~/.zshrc 2>/dev/null || echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
92
+ eval "$(mise activate zsh)"
93
+ elif [[ "$SHELL" == *"bash"* ]]; then
94
+ grep -q 'mise activate' ~/.bash_profile 2>/dev/null || echo 'eval "$(mise activate bash)"' >> ~/.bash_profile
95
+ eval "$(mise activate bash)"
96
+ fi
97
+ ```
98
+
99
+ Verify: `mise --version`
100
+
101
+ ## Step 4: Ruby and Python via Mise
102
+
103
+ From the buttercut directory:
104
+
105
+ ```bash
106
+ mise trust
107
+ mise install
108
+ ```
109
+
110
+ **Note:** Ruby is compiled from source and can take 5-10 minutes. This is normal.
111
+
112
+ Verify versions:
113
+
114
+ ```bash
115
+ ruby --version # Should show 3.3.6
116
+ python3 --version # Should show 3.12.8
117
+ ```
118
+
119
+ ## Step 5: Bundler
120
+
121
+ ```bash
122
+ which bundle || gem install bundler
123
+ ```
124
+
125
+ ## Step 6: FFmpeg
126
+
127
+ ```bash
128
+ which ffmpeg || brew install ffmpeg
129
+ ```
130
+
131
+ ## Step 7: WhisperX Virtual Environment
132
+
133
+ ```bash
134
+ mkdir -p ~/.buttercut
135
+
136
+ if [ ! -d ~/.buttercut/venv ]; then
137
+ python3 -m venv ~/.buttercut/venv
138
+ fi
139
+
140
+ source ~/.buttercut/venv/bin/activate
141
+ pip install --upgrade pip
142
+ pip install whisperx
143
+ deactivate
144
+ ```
145
+
146
+ ## Step 8: WhisperX Wrapper Script
147
+
148
+ ```bash
149
+ cat > ~/.buttercut/whisperx << 'EOF'
150
+ #!/bin/bash
151
+ source ~/.buttercut/venv/bin/activate
152
+ whisperx "$@"
153
+ deactivate
154
+ EOF
155
+ chmod +x ~/.buttercut/whisperx
156
+ ```
157
+
158
+ ## Step 9: Add to PATH
159
+
160
+ ```bash
161
+ if [[ "$SHELL" == *"zsh"* ]]; then
162
+ grep -q 'buttercut' ~/.zshrc 2>/dev/null || echo 'export PATH="$HOME/.buttercut:$PATH"' >> ~/.zshrc
163
+ elif [[ "$SHELL" == *"bash"* ]]; then
164
+ grep -q 'buttercut' ~/.bash_profile 2>/dev/null || echo 'export PATH="$HOME/.buttercut:$PATH"' >> ~/.bash_profile
165
+ fi
166
+ ```
167
+
168
+ ## Step 10: Install ButterCut Dependencies
169
+
170
+ ```bash
171
+ bundle install
172
+ ```
173
+
174
+ ## Final Step
175
+
176
+ Tell user to open a new terminal window for all changes to take effect.
177
+
178
+ ## Troubleshooting
179
+
180
+ - **Xcode stuck**: `sudo rm -rf /Library/Developer/CommandLineTools` then retry
181
+ - **Homebrew not in PATH**: Run `eval "$(/opt/homebrew/bin/brew shellenv)"`
182
+ - **Mise not activating**: Open new terminal, run `mise doctor`
183
+ - **Wrong Ruby/Python**: Run `mise trust && mise install` from buttercut directory
184
+ - **WhisperX not found**: Ensure `~/.buttercut` is in PATH, open new terminal
185
+ - **WhisperX import errors**: The wrapper script handles venv activation automatically; ensure you're using `~/.buttercut/whisperx` not calling whisperx directly
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env ruby
2
+ # Verifies all ButterCut dependencies are installed
3
+
4
+ class DependencyChecker
5
+ def run
6
+ puts "ButterCut Dependency Check"
7
+ puts "=" * 40
8
+ puts
9
+
10
+ results = []
11
+
12
+ # Core dependencies (required)
13
+ results << check("Xcode CLI Tools", "xcode-select -p", "xcode-select --install")
14
+ results << check("Homebrew", "which brew", "See https://brew.sh")
15
+ results << check_ruby_version
16
+ results << check("Bundler", "which bundle", "gem install bundler")
17
+ results << check_python_version
18
+ results << check("FFmpeg", "which ffmpeg", "brew install ffmpeg")
19
+ results << check_whisperx
20
+ results << check_bundle_install
21
+
22
+ # Optional: show mise status if installed (not required)
23
+ check_mise_optional
24
+
25
+ puts
26
+ puts "=" * 40
27
+
28
+ passed = results.count { |r| r[:status] == :ok }
29
+ failed = results.select { |r| r[:status] == :missing }
30
+
31
+ if failed.empty?
32
+ puts "All #{passed} dependencies installed!"
33
+ puts "ButterCut is ready to use."
34
+ true
35
+ else
36
+ puts "#{passed}/#{results.size} dependencies installed"
37
+ puts
38
+ puts "Missing dependencies:"
39
+ failed.each do |r|
40
+ puts " - #{r[:name]}: #{r[:install]}"
41
+ end
42
+ false
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def check(name, cmd, install)
49
+ result = system("#{cmd} > /dev/null 2>&1")
50
+ status = result ? :ok : :missing
51
+ icon = result ? "OK" : "MISSING"
52
+ puts "#{icon.ljust(8)} #{name}"
53
+ { name: name, status: status, install: install }
54
+ end
55
+
56
+ def check_ruby_version
57
+ version_output = `ruby --version 2>/dev/null`.strip
58
+ if version_output.match?(/ruby 3\.3/)
59
+ puts "OK Ruby (#{version_output.split[1]})"
60
+ { name: "Ruby 3.3.x", status: :ok }
61
+ elsif version_output.empty?
62
+ puts "MISSING Ruby"
63
+ { name: "Ruby 3.3.x", status: :missing, install: "Install Ruby 3.3.6 (see .ruby-version)" }
64
+ else
65
+ puts "WRONG Ruby (#{version_output.split[1]} - need 3.3.x)"
66
+ { name: "Ruby 3.3.x", status: :missing, install: "Install Ruby 3.3.6 (see .ruby-version)" }
67
+ end
68
+ end
69
+
70
+ def check_python_version
71
+ version_output = `python3 --version 2>/dev/null`.strip
72
+ if version_output.match?(/Python 3\.12/)
73
+ puts "OK Python (#{version_output.split[1]})"
74
+ { name: "Python 3.12.x", status: :ok }
75
+ elsif version_output.empty?
76
+ puts "MISSING Python"
77
+ { name: "Python 3.12.x", status: :missing, install: "Install Python 3.12.8 (see .python-version)" }
78
+ else
79
+ puts "WRONG Python (#{version_output.split[1]} - need 3.12.x)"
80
+ { name: "Python 3.12.x", status: :missing, install: "Install Python 3.12.8 (see .python-version)" }
81
+ end
82
+ end
83
+
84
+ def check_whisperx
85
+ # Check various possible locations for whisperx
86
+ locations = [
87
+ "which whisperx",
88
+ "test -x ~/.buttercut/whisperx",
89
+ "test -x ~/.buttercut/venv/bin/whisperx"
90
+ ]
91
+
92
+ found = locations.any? { |cmd| system("#{cmd} > /dev/null 2>&1") }
93
+
94
+ if found
95
+ puts "OK WhisperX"
96
+ { name: "WhisperX", status: :ok }
97
+ else
98
+ puts "MISSING WhisperX"
99
+ { name: "WhisperX", status: :missing, install: "pip install whisperx (see setup instructions)" }
100
+ end
101
+ end
102
+
103
+ def check_bundle_install
104
+ gemfile_lock = File.join(Dir.pwd, "Gemfile.lock")
105
+
106
+ if File.exist?(gemfile_lock)
107
+ puts "OK Bundle installed"
108
+ { name: "Bundle installed", status: :ok }
109
+ else
110
+ puts "MISSING Bundle installed"
111
+ { name: "Bundle installed", status: :missing, install: "Run 'bundle install' in buttercut directory" }
112
+ end
113
+ end
114
+
115
+ def check_mise_optional
116
+ if system("which mise > /dev/null 2>&1")
117
+ puts
118
+ puts "(info) Mise detected - using mise for version management"
119
+ end
120
+ end
121
+ end
122
+
123
+ success = DependencyChecker.new.run
124
+ exit(success ? 0 : 1)
@@ -0,0 +1,83 @@
1
+ ---
2
+ name: transcribe-audio
3
+ description: Transcribes video audio using WhisperX, preserving original timestamps. Creates JSON transcript with word-level timing. Use when you need to generate audio transcripts for videos.
4
+ ---
5
+
6
+ # Skill: Transcribe Audio
7
+
8
+ Transcribes video audio using WhisperX and creates clean JSON transcripts with word-level timing data.
9
+
10
+ ## When to Use
11
+ - Videos need audio transcripts before visual analysis
12
+
13
+ ## Critical Requirements
14
+
15
+ Use WhisperX, NOT standard Whisper. WhisperX preserves the original video timeline including leading silence, ensuring transcripts match actual video timestamps. Run WhisperX directly on video files. Don't extract audio separately - this ensures timestamp alignment.
16
+
17
+ ## Workflow
18
+
19
+ ### 1. Read Language from Library File
20
+
21
+ Read the library's `library.yaml` to get the language code:
22
+
23
+ ```yaml
24
+ # Library metadata
25
+ library_name: [library-name]
26
+ language: en # Language code stored here
27
+ ...
28
+ ```
29
+
30
+ ### 2. Run WhisperX
31
+
32
+ ```bash
33
+ whisperx "/full/path/to/video.mov" \
34
+ --language en \
35
+ --model medium \
36
+ --compute_type float32 \
37
+ --device cpu \
38
+ --output_format json \
39
+ --output_dir libraries/[library-name]/transcripts
40
+ ```
41
+
42
+ ### 3. Prepare Audio Transcript
43
+
44
+ After WhisperX completes, format the JSON using our prepare_audio_script:
45
+
46
+ ```bash
47
+ ruby .claude/skills/transcribe-audio/prepare_audio_script.rb \
48
+ libraries/[library-name]/transcripts/video_name.json \
49
+ /full/path/to/original/video_name.mov
50
+ ```
51
+
52
+ This script:
53
+ - Adds video source path as metadata
54
+ - Removes unnecessary fields to reduce file size
55
+ - Prettifies JSON
56
+
57
+ ### 4. Return Success Response
58
+
59
+ After audio preparation completes, return this structured response to the parent agent:
60
+
61
+ ```
62
+ ✓ [video_filename.mov] transcribed successfully
63
+ Audio transcript: libraries/[library-name]/transcripts/video_name.json
64
+ Video path: /full/path/to/video_filename.mov
65
+ ```
66
+
67
+ **DO NOT update library.yaml** - the parent agent will handle this to avoid race conditions when running multiple transcriptions in parallel.
68
+
69
+ ## Running in Parallel
70
+
71
+ This skill is designed to run inside a Task agent for parallel execution:
72
+ - Each agent handles ONE video file
73
+ - Multiple agents can run simultaneously
74
+ - Parent thread updates library.yaml sequentially after each agent completes
75
+ - No race conditions on shared YAML file
76
+
77
+ ## Next Step
78
+
79
+ After audio transcription, use the **analyze-video** skill to add visual descriptions and create the visual transcript.
80
+
81
+ ## Installation
82
+
83
+ Ensure WhisperX is installed. Use the **setup** skill to verify dependencies.