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-level watch/ directory inside the archive, matching Claude AI's expected layout
  • HEAD: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.sh computes the repository root dynamically to ensure consistent execution from any working directory
  • Clean git enforcement prevents uncommitted code from entering production bundles
  • git archive creates reproducible, prefix-structured zip files from version-controlled source
  • 200-file limit validation enforces Claude AI's platform constraints
  • Single SKILL.md verification guarantees valid skill metadata
  • The resulting .skill file 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →