# How build-skill.sh in claude-video Archives the Skill Folder for Claude AI Upload

> Learn how build-skill.sh archives the skill folder for claude.ai upload. This script zips the skills/watch subtree, enforces limits, and prepares the upload bundle.

- Repository: [bradautomates/claude-video](https://github.com/bradautomates/claude-video)
- Tags: how-to-guide
- Published: 2026-07-14

---

**The [`build-skill.sh`](https://github.com/bradautomates/claude-video/blob/main/build-skill.sh) script creates a `.skill` archive by using `git archive` to zip the `skills/watch` subtree, verifying Git cleanliness, enforcing a 200-file limit, and confirming exactly one [`SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/SKILL.md) manifest before outputting the upload-ready bundle.**

The bradautomates/claude-video repository provides a shell-based build pipeline for packaging custom Claude AI skills. The [`build-skill.sh`](https://github.com/bradautomates/claude-video/blob/main/build-skill.sh) script located at [`skills/watch/scripts/build-skill.sh`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/build-skill.sh) transforms the skill folder into a validated `.skill` file that complies with Claude AI's upload constraints.

## Repository Root Resolution and Clean State Verification

### Locating the Repository Root

The script begins by computing the **repository root** (`REPO_ROOT`) relative to its own location at [`skills/watch/scripts/build-skill.sh`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/build-skill.sh). By navigating three directories upward using `../../..` and changing to that directory, it guarantees the build works regardless of where the user invokes the command within the repository.

### Verifying Git Cleanliness

Before creating any archive, the script enforces a **clean Git state** to prevent accidental inclusion of work-in-progress files. It runs `git diff --quiet` to check for unstaged changes and `git diff --cached --quiet` to detect staged but uncommitted changes. If either check finds modifications, the script aborts immediately, ensuring only committed code enters the bundle.

## Creating the Claude AI Skill Archive

### The git archive Command

At the core of the archiving process is a precise `git archive` invocation. The script specifies `--format=zip` to generate a zip-compatible archive and `--output dist/watch.skill` to write the result directly to the distribution directory.

The command targets `HEAD:skills/watch`, which instructs Git to archive the exact state of the `skills/watch` directory as it appears in the current commit. This ensures the bundle excludes any uncommitted working directory changes.

### Archive Structure and Prefixing

The script uses the `--prefix=watch/` flag to ensure all archived contents appear under a top-level `watch/` folder inside the zip. This structure places [`SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/SKILL.md) at [`watch/SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/watch/SKILL.md) within the archive, matching the path format Claude AI expects for skill ingestion.

## Validating Upload Constraints for claude.ai

### Enforcing the 200-File Limit

After creation, the script validates **Claude AI's upload constraints** using `unzip -l` to extract the file list and count the entries, while `du -h` reports the archive size. If the file count exceeds 200, the script exits with a descriptive error message to prevent upload rejection.

### Manifest Verification with SKILL.md

The script verifies the presence of exactly one canonical manifest by piping the `unzip -l` output through `grep -c "SKILL.md"`. This check ensures the bundle contains the required skill contract that Claude AI uses to parse the interface configuration. A count other than one causes immediate build failure before reaching the upload stage.

## Building and Deploying the Skill

To generate the upload-ready bundle, execute the script from anywhere within the repository:

```bash
bash skills/watch/scripts/build-skill.sh

```

Successful execution produces output similar to:

```text
built dist/watch.skill (42 files, 1.8M)
upload via the claude.ai skill UI

```

The resulting `dist/watch.skill` file contains the complete `watch/` subtree including [`SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/SKILL.md) and all runtime scripts in `scripts/`, compressed and ready for drag-and-drop upload to the Claude AI skill interface.

## Summary

- The **[`build-skill.sh`](https://github.com/bradautomates/claude-video/blob/main/build-skill.sh)** script in `skills/watch/scripts/` automates `.skill` bundle creation for the bradautomates/claude-video repository.
- It enforces **Git cleanliness** via `git diff --quiet` and `git diff --cached --quiet` checks to ensure only committed code is archived.
- The **`git archive`** command packages the `HEAD:skills/watch` subtree with a `watch/` prefix into `dist/watch.skill`.
- Validation ensures **≤200 files** and exactly **one [`SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/SKILL.md)** manifest, complying with Claude AI upload requirements.

## Frequently Asked Questions

### Why does build-skill.sh require a clean Git state before archiving?

The script checks for uncommitted changes using `git diff --quiet` and `git diff --cached --quiet` to guarantee that the resulting `.skill` bundle contains only committed code. This prevents debugging confusion caused by uploading experimental modifications that exist only in the working directory but have not been committed to the repository.

### What are the Claude AI file limits enforced by the script?

The script validates two hard constraints: the archive must contain **no more than 200 files**, and it must include exactly **one [`SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/SKILL.md) manifest file**. These limits align with Claude AI's upload interface requirements, and exceeding them causes the build to abort with a specific error message before generating the final bundle.

### Can I manually create a .skill file without using build-skill.sh?

While technically possible to manually zip the `skills/watch` directory, the script ensures critical validation steps that manual archiving might miss. It verifies the exact `HEAD` commit state using `git archive`, confirms the 200-file limit, and checks for the mandatory [`SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/SKILL.md) manifest. Manual zipping risks creating an invalid bundle that Claude AI will reject during upload.

### Where is the SKILL.md manifest located within the claude-video repository?

The **[`SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/SKILL.md)** file resides at [`skills/watch/SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/SKILL.md) in the repository root. During the archive process, the `--prefix=watch/` flag ensures this file appears at [`watch/SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/watch/SKILL.md) inside the generated zip, maintaining the expected path structure that Claude AI requires for skill ingestion.