How build-skill.sh Creates the `.skill` Bundle for Claude AI: A Complete Breakdown
build-skill.sh is a Bash bundler that packages the watch skill into a .skill archive for Claude AI using git archive, enforces clean git state, validates file count limits, and ensures exactly one SKILL.md exists.
The build-skill.sh script in the bradautomates/claude-video repository automates the creation of Claude AI-compatible skill bundles. Located at skills/watch/scripts/build-skill.sh, this utility ensures that every .skill file meets Claude AI's packaging requirements before upload.
Locating the Repository Root
The script begins by establishing a reliable working directory. It navigates three levels up from its own location to reach the repository root:
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
Source: Line 11‑12
This path calculation makes the script location-independent. Whether invoked from the repository root or a nested subdirectory, it consistently resolves to the correct project base.
Enforcing a Clean Git Working Tree
Before generating the .skill bundle, the script validates repository cleanliness. It checks both unstaged and staged changes:
if [ -n "$(git diff --stat)" ] || [ -n "$(git diff --cached --stat)" ]; then
echo "Error: Working tree has uncommitted changes."
exit 1
fi
Source: Line 14‑17
This safeguard prevents ephemeral or unreviewed code from entering production bundles. Developers must commit or stash changes before proceeding.
Creating the Output Directory
The script ensures the dist folder exists at the repository root:
mkdir -p "${ROOT_DIR}/dist"
Source: Line 19
This directory serves as the destination for the final .skill archive. The -p flag creates parent directories as needed without error if the directory already exists.
Archiving the Skill with git archive
The core bundling operation uses git archive to create a zip file from the skills/watch subtree:
git archive --format=zip --prefix=watch/ --output="${ROOT_DIR}/dist/watch.skill" HEAD:skills/watch
Source: Line 21
Key parameters:
--format=zip— Produces a zip archive (Claude AI's required format)--prefix=watch/— Prepends a top-levelwatch/directory inside the archive, matching Claude AI's expected layoutHEAD:skills/watch— Archives the committed state of the skill directory, not the working tree
This approach guarantees reproducible builds from version-controlled source rather than arbitrary filesystem state.
Validating Bundle Constraints
File Count Limit
Claude AI enforces a hard limit of 200 files per skill. The script validates compliance:
FILE_COUNT=$(unzip -l "${ROOT_DIR}/dist/watch.skill" | tail -1 | awk '{print $2}')
if [ "${FILE_COUNT}" -gt 200 ]; then
echo "Error: Bundle contains ${FILE_COUNT} files (max 200)."
exit 1
fi
Source: Line 23‑30
SKILL.md Verification
The script ensures exactly one SKILL.md file exists in the bundle:
SKILL_MD_COUNT=$(unzip -l "${ROOT_DIR}/dist/watch.skill" | grep -c "SKILL.md")
if [ "${SKILL_MD_COUNT}" -ne 1 ]; then
echo "Error: Bundle must contain exactly one SKILL.md (found ${SKILL_MD_COUNT})."
exit 1
fi
Source: Line 32‑36
SKILL.md serves as the canonical skill contract that Claude AI uses to understand the skill's capabilities, tools, and instructions. Absence or duplication would cause upload failures.
Bundle Size Reporting
After validation, the script reports the final bundle metrics:
echo "built ${ROOT_DIR}/dist/watch.skill (${FILE_COUNT} files, $(du -h "${ROOT_DIR}/dist/watch.skill" | cut -f1))"
Source: Line 38‑39
Running the Build Script
Execute the bundler from any directory within the repository:
bash skills/watch/scripts/build-skill.sh
Successful output follows this format:
built /path/to/claude-video/dist/watch.skill (42 files, 3.1M)
upload via the claude.ai skill UI
Inspect the generated bundle contents with:
unzip -l dist/watch.skill
Expected structure:
Archive: dist/watch.skill
Length Date Time Name
--------- ---------- ----- ----
0 01-15-2025 10:30 watch/
2456 01-15-2025 10:30 watch/SKILL.md
1843 01-15-2025 10:30 watch/scripts/download.py
2156 01-15-2025 10:30 watch/scripts/frames.py
1987 01-15-2025 10:30 watch/scripts/transcribe.py
...
Key Files in the Bundle
| File | Purpose |
|---|---|
skills/watch/scripts/build-skill.sh |
The bundling script itself |
skills/watch/SKILL.md |
Claude AI skill definition and metadata |
skills/watch/scripts/download.py |
Video download runtime |
skills/watch/scripts/frames.py |
Frame extraction runtime |
skills/watch/scripts/transcribe.py |
Audio transcription runtime |
Summary
build-skill.shcomputes the repository root dynamically to ensure consistent execution from any working directory- Clean git enforcement prevents uncommitted code from entering production bundles
git archivecreates reproducible, prefix-structured zip files from version-controlled source- 200-file limit validation enforces Claude AI's platform constraints
- Single
SKILL.mdverification guarantees valid skill metadata - The resulting
.skillfile requires no post-processing before Claude AI upload
Frequently Asked Questions
What is a .skill file?
A .skill file is a zip archive containing a Claude AI skill definition. It must include exactly one SKILL.md file at its root plus any runtime scripts or assets. The file extension distinguishes it from generic zip archives in the Claude AI upload interface.
Why does build-skill.sh use git archive instead of regular zip?
git archive guarantees that the bundle contains only committed, version-controlled files. This prevents temporary files, uncommitted experiments, or .gitignored artifacts from polluting the production bundle. It also enables reproducible builds from any commit ref.
What happens if my skill exceeds 200 files?
The script aborts with an explicit error message. You must reduce the file count by consolidating scripts, excluding non-essential assets, or restructuring the skill. Claude AI enforces this limit strictly during upload validation.
Can I build the skill with uncommitted changes?
No. The script checks git diff and git diff --cached and exits with an error if either reports changes. This ensures traceability: every uploaded .skill corresponds to a specific git commit.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →