version: '3'
dotenv: ['.env', '.env.local']
vars:
BINARY: ./target/release/video-transcriber-mcp
BINARY_DEV: ./target/debug/video-transcriber-mcp
TEST_VIDEO: "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
MODELS_DIR: "{{.HOME}}/.cache/video-transcriber-mcp/models"
tasks:
build:
desc: Build the project in release mode (optimized)
cmds:
- cargo build --release
sources:
- src/**/*.rs
- Cargo.toml
generates:
- target/release/video-transcriber-mcp
build:dev:
desc: Build the project in dev mode (fast compilation)
cmds:
- cargo build
clean:
desc: Clean build artifacts
cmds:
- cargo clean
- rm -rf target/
check:
desc: Check if the project compiles
cmds:
- cargo check
fmt:
desc: Format code
cmds:
- cargo fmt
lint:
desc: Run clippy linter
cmds:
- cargo clippy -- -D warnings
fix:
desc: Auto-fix linting issues
cmds:
- cargo clippy --fix --allow-dirty
- cargo fmt
download:base:
desc: Download base Whisper model (recommended)
cmds:
- bash scripts/download-models.sh base
download:all:
desc: Download all Whisper models
cmds:
- bash scripts/download-models.sh all
download:tiny:
desc: Download tiny model (fastest)
cmds:
- bash scripts/download-models.sh tiny
download:small:
desc: Download small model (balanced)
cmds:
- bash scripts/download-models.sh small
download:medium:
desc: Download medium model (high accuracy)
cmds:
- bash scripts/download-models.sh medium
download:large:
desc: Download large model (best accuracy)
cmds:
- bash scripts/download-models.sh large
models:status:
desc: Check which models are downloaded
cmds:
- ls -lh {{.MODELS_DIR}}/*.bin 2>/dev/null || echo "No models found. Run 'task download:base' to download."
test:quick:
desc: Quick test with a short video (requires base model)
deps: [build]
cmds:
- |
echo "🎬 Testing with short video..."
{{.BINARY}} --url "{{.TEST_VIDEO}}" --model base
preconditions:
- sh: test -f {{.MODELS_DIR}}/ggml-base.bin
msg: "Base model not found. Run 'task download:base' first."
test:local:
desc: Test with a local video file
deps: [build]
cmds:
- |
if [ -z "{{.VIDEO_PATH}}" ]; then
echo "❌ Please provide VIDEO_PATH: task test:local VIDEO_PATH=/path/to/video.mp4"
exit 1
fi
{{.BINARY}} --url "{{.VIDEO_PATH}}" --model base
vars:
VIDEO_PATH: '{{.VIDEO_PATH | default ""}}'
test:url:
desc: Test with a custom URL
deps: [build]
cmds:
- |
if [ -z "{{.VIDEO_URL}}" ]; then
echo "❌ Please provide VIDEO_URL: task test:url VIDEO_URL=https://..."
exit 1
fi
{{.BINARY}} --url "{{.VIDEO_URL}}" --model base
vars:
VIDEO_URL: '{{.VIDEO_URL | default ""}}'
test:all-models:
desc: Test transcription with all available models
deps: [build]
cmds:
- |
echo "🎯 Testing all available models..."
for model in tiny base small medium large; do
if [ -f "{{.MODELS_DIR}}/ggml-${model}.bin" ]; then
echo "Testing with ${model} model..."
time {{.BINARY}} --url "{{.TEST_VIDEO}}" --model ${model}
echo "---"
fi
done
benchmark:
desc: Run benchmark with timing
deps: [build]
cmds:
- |
echo "⏱️ Running benchmark..."
time {{.BINARY}} --url "{{.TEST_VIDEO}}" --model base
benchmark:compare:
desc: Compare performance across models
deps: [build]
cmds:
- |
echo "📊 Benchmarking different models..."
echo "Video: {{.TEST_VIDEO}}"
echo ""
for model in tiny base small; do
if [ -f "{{.MODELS_DIR}}/ggml-${model}.bin" ]; then
echo "=== Model: ${model} ==="
time {{.BINARY}} --url "{{.TEST_VIDEO}}" --model ${model}
echo ""
fi
done
benchmark:vs-typescript:
desc: Compare with TypeScript version
cmds:
- |
echo "🏁 Rust vs TypeScript Benchmark"
echo "================================"
echo ""
# Rust version
echo "🦀 Rust Version (video-transcriber-mcp):"
cd {{.ROOT_DIR}}
time {{.BINARY}} --url "{{.TEST_VIDEO}}" --model base
echo ""
echo "---"
echo ""
# TypeScript version
echo "📘 TypeScript Version (video-transcriber-mcp):"
cd ../video-transcriber
time npm run start -- "{{.TEST_VIDEO}}"
deps:check:
desc: Check if all required dependencies are installed
cmds:
- |
echo "🔍 Checking dependencies..."
echo ""
# Check Rust
if command -v rustc &> /dev/null; then
echo "✅ Rust: $(rustc --version)"
else
echo "❌ Rust: NOT INSTALLED"
fi
# Check yt-dlp
if command -v yt-dlp &> /dev/null; then
echo "✅ yt-dlp: $(yt-dlp --version)"
else
echo "❌ yt-dlp: NOT INSTALLED (run: brew install yt-dlp)"
fi
# Check ffmpeg
if command -v ffmpeg &> /dev/null; then
echo "✅ ffmpeg: $(ffmpeg -version | head -1)"
else
echo "❌ ffmpeg: NOT INSTALLED (run: brew install ffmpeg)"
fi
echo ""
echo "📦 Whisper Models:"
ls -lh {{.MODELS_DIR}}/*.bin 2>/dev/null || echo " ⚠️ No models found (run: task download:base)"
deps:install:
desc: Install all required dependencies (macOS)
cmds:
- |
echo "📥 Installing dependencies..."
if ! command -v yt-dlp &> /dev/null; then
echo "Installing yt-dlp..."
brew install yt-dlp
fi
if ! command -v ffmpeg &> /dev/null; then
echo "Installing ffmpeg..."
brew install ffmpeg
fi
echo "✅ All dependencies installed!"
task deps:check
dev:
desc: Run in development mode (for testing changes)
cmds:
- cargo run -- --url "{{.TEST_VIDEO}}" --model base
watch:
desc: Watch for changes and rebuild
cmds:
- cargo watch -x check -x test
run:
desc: Run the binary directly
deps: [build]
cmds:
- |
if [ -z "{{.ARGS}}" ]; then
echo "Usage: task run ARGS='--url VIDEO_URL --model base'"
exit 1
fi
{{.BINARY}} {{.ARGS}}
vars:
ARGS: '{{.ARGS | default ""}}'
setup:
desc: Complete project setup (build + download base model)
cmds:
- task: build
- task: download:base
- task: deps:check
- |
echo ""
echo "🎉 Setup complete! Try: task test:quick"
setup:full:
desc: Complete setup with all models
cmds:
- task: build
- task: download:all
- task: deps:check
clean:models:
desc: Delete all downloaded models
cmds:
- rm -rf {{.MODELS_DIR}}/*.bin
- echo "🗑️ All models deleted"
clean:outputs:
desc: Delete all transcription outputs
cmds:
- rm -rf ~/Downloads/video-transcripts/*
- echo "🗑️ All transcripts deleted"
size:
desc: Show binary size
deps: [build]
cmds:
- |
echo "📦 Binary Size:"
ls -lh {{.BINARY}}
echo ""
echo "📊 Stripped size: $(du -h {{.BINARY}} | cut -f1)"
info:
desc: Show project information
cmds:
- |
echo "🚀 Video Transcriber RS"
echo "======================"
echo ""
echo "📂 Project: {{.ROOT_DIR}}"
echo "🔨 Binary: {{.BINARY}}"
echo "📦 Models: {{.MODELS_DIR}}"
echo "📝 Outputs: ~/Downloads/video-transcripts/"
echo ""
task size
echo ""
task deps:check
release:build:
desc: Build optimized release binary
cmds:
- cargo build --release --locked
- strip {{.BINARY}} 2>/dev/null || true
- |
echo "✅ Release build complete!"
task size
release:check:
desc: Pre-release checks (fmt, lint, test, build)
cmds:
- task: fmt
- task: lint
- task: build
- echo "✅ All checks passed! Ready for release."
release:tag:
desc: "Create and push a release tag - usage: task release:tag VERSION=0.1.1"
cmds:
- |
if [ -z "{{.VERSION}}" ]; then
echo "❌ Please provide VERSION: task release:tag VERSION=0.1.1"
exit 1
fi
echo "🏷️ Creating release tag v{{.VERSION}}..."
git tag -a v{{.VERSION}} -m "Release v{{.VERSION}}"
git push origin v{{.VERSION}}
echo "✅ Tag v{{.VERSION}} pushed! Check GitHub Actions for build progress."
vars:
VERSION: '{{.VERSION | default ""}}'
release:
desc: "Full release workflow - usage: task release VERSION=0.1.1"
cmds:
- |
if [ -z "{{.VERSION}}" ]; then
echo "❌ Please provide VERSION: task release VERSION=0.1.1"
exit 1
fi
echo "🚀 Starting release v{{.VERSION}}..."
- task: release:check
- |
echo ""
echo "📝 Please update version in Cargo.toml and CHANGELOG.md if needed"
echo "Press Enter to continue or Ctrl+C to abort..."
read
- task: "release:tag"
vars:
VERSION: '{{.VERSION}}'
vars:
VERSION: '{{.VERSION | default ""}}'
release:delete:
desc: "Delete a release tag - usage: task release:delete VERSION=0.1.1"
cmds:
- |
if [ -z "{{.VERSION}}" ]; then
echo "❌ Please provide VERSION: task release:delete VERSION=0.1.1"
exit 1
fi
echo "⚠️ Deleting tag v{{.VERSION}}..."
git tag -d v{{.VERSION}}
git push origin :refs/tags/v{{.VERSION}}
echo "✅ Tag v{{.VERSION}} deleted"
vars:
VERSION: '{{.VERSION | default ""}}'
release:cargo:
desc: "Release to crates.io"
cmds:
- cargo publish
release:arm64:
desc: "Build macOS ARM64 and upload to release - usage: task release:arm64 VERSION=0.3.0"
cmds:
- |
if [ -z "{{.VERSION}}" ]; then
echo "❌ Please provide VERSION: task release:arm64 VERSION=0.3.0"
exit 1
fi
echo "🍎 Building macOS ARM64 binary..."
rustup target add aarch64-apple-darwin
cargo build --release --target aarch64-apple-darwin
echo "📦 Packaging binary..."
cd target/aarch64-apple-darwin/release
tar czf ../../../video-transcriber-mcp-aarch64-apple-darwin.tar.gz video-transcriber-mcp
cd ../../..
echo "📤 Uploading to GitHub release v{{.VERSION}}..."
gh release upload v{{.VERSION}} video-transcriber-mcp-aarch64-apple-darwin.tar.gz
echo "✅ ARM64 binary uploaded to release v{{.VERSION}}!"
vars:
VERSION: '{{.VERSION | default ""}}'
help:
desc: Show available tasks
cmds:
- task --list
readme:
desc: Open README in default viewer
cmds:
- |
if command -v glow &> /dev/null; then
glow README.md
else
cat README.md
fi
mcp:test:
desc: Test MCP server with stdio
deps: [build]
cmds:
- |
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | {{.BINARY}}
mcp:setup:
desc: Show MCP setup instructions
cmds:
- |
echo "📝 Add this to ~/.claude/settings.json:"
echo ""
echo '{'
echo ' "mcpServers": {'
echo ' "video-transcriber-mcp": {'
echo ' "command": "{{.BINARY}}"'
echo ' }'
echo ' }'
echo '}'
echo ""
echo "Then restart Claude Code!"