Cc-skills bootstrap
Pre-session bootstrap - generates script to start recording BEFORE entering Claude Code. Chunking handled by daemon. TRIGGERS - bootstrap, pre-session, start recording, before claude.
git clone https://github.com/terrylica/cc-skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/terrylica/cc-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/asciinema-tools/skills/bootstrap" ~/.claude/skills/terrylica-cc-skills-bootstrap && rm -rf "$T"
plugins/asciinema-tools/skills/bootstrap/SKILL.md/asciinema-tools:bootstrap
Generate a bootstrap script that runs OUTSIDE Claude Code to start a recording session.
Important: Chunking is handled by the launchd daemon. Run
/asciinema-tools:daemon-setup first if you haven't already.
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
Architecture
┌─────────────────────────────────────────────────────────────────────────────┐ │ DAEMON-BASED RECORDING WORKFLOW │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ 1. ONE-TIME SETUP (if not done): │ │ /asciinema-tools:daemon-setup │ │ → Configures launchd daemon with Keychain credentials │ │ │ │ 2. GENERATE BOOTSTRAP (in Claude Code): │ │ /asciinema-tools:bootstrap │ │ → Generates tmp/bootstrap-claude-session.sh │ │ │ │ 3. EXIT CLAUDE and RUN BOOTSTRAP: │ │ $ ./tmp/bootstrap-claude-session.sh ← NOT source! │ │ → Writes config for daemon │ │ → Starts asciinema recording │ │ │ │ 4. WORK IN RECORDING: │ │ $ claude │ │ → Daemon automatically pushes chunks to GitHub │ │ │ │ 5. EXIT (two times): │ │ Ctrl+D (exit Claude) → exit (end recording) │ │ → Daemon pushes final chunk │ │ │ └─────────────────────────────────────────────────────────────────────────────┘
Arguments
| Argument | Description |
|---|---|
| GitHub repository (e.g., ) |
| Orphan branch name (default: ) |
| Force create orphan branch |
| Skip confirmation prompts |
Execution
Phase 0: Preflight Check
/usr/bin/env bash << 'PREFLIGHT_EOF' MISSING=() for tool in asciinema zstd git; do command -v "$tool" &>/dev/null || MISSING+=("$tool") done if [[ ${#MISSING[@]} -gt 0 ]]; then echo "MISSING: ${MISSING[*]}" exit 1 fi echo "PREFLIGHT: OK" asciinema --version | head -1 # Check daemon status if launchctl list 2>/dev/null | grep -q "asciinema-chunker"; then echo "DAEMON: RUNNING" else echo "DAEMON: NOT_RUNNING" fi PREFLIGHT_EOF
If DAEMON: NOT_RUNNING, use AskUserQuestion:
Question: "The chunker daemon is not running. Chunks won't be pushed to GitHub without it." Header: "Daemon" Options: - label: "Run daemon setup (Recommended)" description: "Switch to /asciinema-tools:daemon-setup to configure the daemon" - label: "Continue anyway" description: "Generate bootstrap script without daemon (local recording only)"
Phase 1: Detect Repository Context
MANDATORY: Run before AskUserQuestion to auto-populate options.
/usr/bin/env bash << 'DETECT_CONTEXT_EOF' IN_GIT_REPO="false" CURRENT_REPO_URL="" CURRENT_REPO_OWNER="" CURRENT_REPO_NAME="" ORPHAN_BRANCH_EXISTS="false" LOCAL_CLONE_EXISTS="false" ORPHAN_BRANCH="asciinema-recordings" if git rev-parse --git-dir &>/dev/null 2>&1; then IN_GIT_REPO="true" if git remote get-url origin &>/dev/null 2>&1; then CURRENT_REPO_URL=$(git remote get-url origin) elif [[ -n "$(git remote)" ]]; then REMOTE=$(git remote | head -1) CURRENT_REPO_URL=$(git remote get-url "$REMOTE") fi if [[ -n "$CURRENT_REPO_URL" ]]; then if [[ "$CURRENT_REPO_URL" =~ github\.com[:/]([^/]+)/([^/.]+) ]]; then CURRENT_REPO_OWNER="${BASH_REMATCH[1]}" CURRENT_REPO_NAME="${BASH_REMATCH[2]%.git}" fi if git ls-remote --heads "$CURRENT_REPO_URL" "$ORPHAN_BRANCH" 2>/dev/null | grep -q "$ORPHAN_BRANCH"; then ORPHAN_BRANCH_EXISTS="true" fi LOCAL_CLONE_PATH="$HOME/asciinema_recordings/$CURRENT_REPO_NAME" if [[ -d "$LOCAL_CLONE_PATH/.git" ]]; then LOCAL_CLONE_EXISTS="true" fi fi fi echo "IN_GIT_REPO=$IN_GIT_REPO" echo "CURRENT_REPO_URL=$CURRENT_REPO_URL" echo "CURRENT_REPO_OWNER=$CURRENT_REPO_OWNER" echo "CURRENT_REPO_NAME=$CURRENT_REPO_NAME" echo "ORPHAN_BRANCH_EXISTS=$ORPHAN_BRANCH_EXISTS" echo "LOCAL_CLONE_EXISTS=$LOCAL_CLONE_EXISTS" DETECT_CONTEXT_EOF
Phase 2: Repository Selection (MANDATORY AskUserQuestion)
Based on detection results:
If IN_GIT_REPO=true, ORPHAN_BRANCH_EXISTS=true:
Question: "Orphan branch found in {repo}. Use it?" Header: "Destination" Options: - label: "Use existing (Recommended)" description: "Branch 'asciinema-recordings' already configured in {repo}" - label: "Use different repository" description: "Store recordings in a different repo"
If IN_GIT_REPO=true, ORPHAN_BRANCH_EXISTS=false:
Question: "No orphan branch in {repo}. Create one?" Header: "Setup" Options: - label: "Create orphan branch (Recommended)" description: "Initialize with GitHub Actions workflow for brotli" - label: "Use different repository" description: "Store recordings elsewhere"
If IN_GIT_REPO=false:
Question: "Not in a git repo. Where to store recordings?" Header: "Destination" Options: - label: "Dedicated recordings repo" description: "Use {owner}/asciinema-recordings" - label: "Enter repository" description: "Specify owner/repo manually"
Phase 3: Create Orphan Branch (if needed)
Clear SSH caches first, then create orphan branch:
/usr/bin/env bash << 'CREATE_ORPHAN_EOF' REPO_URL="${1:?}" BRANCH="${2:-asciinema-recordings}" LOCAL_PATH="$HOME/asciinema_recordings/$(basename "$REPO_URL" .git)" # Clear SSH caches first rm -f ~/.ssh/control-* 2>/dev/null || true ssh -O exit git@github.com 2>/dev/null || true # Get GitHub token for HTTPS clone (prefer env var to avoid process spawning) GH_TOKEN="${GH_TOKEN:-${GITHUB_TOKEN:-$(gh auth token 2>/dev/null || echo "")}}" if [[ -n "$GH_TOKEN" ]]; then # Parse owner/repo if [[ "$REPO_URL" =~ github\.com[:/]([^/]+)/([^/.]+) ]]; then OWNER_REPO="${BASH_REMATCH[1]}/${BASH_REMATCH[2]}" AUTH_URL="https://${GH_TOKEN}@github.com/${OWNER_REPO}.git" CLEAN_URL="https://github.com/${OWNER_REPO}.git" else AUTH_URL="$REPO_URL" CLEAN_URL="$REPO_URL" fi else AUTH_URL="$REPO_URL" CLEAN_URL="$REPO_URL" fi # Clone and create orphan TEMP_DIR=$(mktemp -d) git clone "$AUTH_URL" "$TEMP_DIR/repo" cd "$TEMP_DIR/repo" # Create orphan branch git checkout --orphan "$BRANCH" git reset --hard git commit --allow-empty -m "Initialize asciinema recordings" git push origin "$BRANCH" # Cleanup temp rm -rf "$TEMP_DIR" # Clone orphan branch locally mkdir -p "$(dirname "$LOCAL_PATH")" git clone --single-branch --branch "$BRANCH" --depth 1 "$AUTH_URL" "$LOCAL_PATH" # Strip token from remote git -C "$LOCAL_PATH" remote set-url origin "$CLEAN_URL" mkdir -p "$LOCAL_PATH/chunks" echo "ORPHAN_CREATED: $LOCAL_PATH" CREATE_ORPHAN_EOF
Phase 4: Generate Bootstrap Script
Generate the simplified bootstrap script (daemon handles chunking):
/usr/bin/env bash << 'GENERATE_SCRIPT_EOF' REPO_URL="${1:?}" BRANCH="${2:-asciinema-recordings}" LOCAL_REPO="${3:-$HOME/asciinema_recordings/$(basename "$REPO_URL" .git)}" OUTPUT_FILE="${4:-$PWD/tmp/bootstrap-claude-session.sh}" mkdir -p "$(dirname "$OUTPUT_FILE")" cat > "$OUTPUT_FILE" << 'SCRIPT_EOF' #!/usr/bin/env bash # bootstrap-claude-session.sh - Start asciinema recording session # Generated by /asciinema-tools:bootstrap # Chunking handled by launchd daemon if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then echo "ERROR: Do not source this script. Run directly: ./${BASH_SOURCE[0]##*/}" return 1 fi set -uo pipefail SCRIPT_EOF # Append configuration cat >> "$OUTPUT_FILE" << SCRIPT_CONFIG REPO_URL="$REPO_URL" BRANCH="$BRANCH" LOCAL_REPO="$LOCAL_REPO" SCRIPT_CONFIG cat >> "$OUTPUT_FILE" << 'SCRIPT_BODY' WORKSPACE="$(basename "$PWD")" DATETIME="$(date +%Y-%m-%d_%H-%M)" ASCIINEMA_DIR="$HOME/.asciinema" ACTIVE_DIR="$ASCIINEMA_DIR/active" CAST_FILE="$ACTIVE_DIR/${WORKSPACE}_${DATETIME}.cast" CONFIG_FILE="${CAST_FILE%.cast}.json" echo "╔════════════════════════════════════════════════════════════════╗" echo "║ asciinema Recording Session ║" echo "╠════════════════════════════════════════════════════════════════╣" # Check daemon if ! launchctl list 2>/dev/null | grep -q "asciinema-chunker"; then echo "║ WARNING: Daemon not running! Run /asciinema-tools:daemon-start║" echo "╠════════════════════════════════════════════════════════════════╣" fi # Clear SSH caches rm -f ~/.ssh/control-* 2>/dev/null || true ssh -O exit git@github.com 2>/dev/null || true # Setup mkdir -p "$ACTIVE_DIR" "$LOCAL_REPO/chunks" # Write config for daemon cat > "$CONFIG_FILE" <<EOF { "repo_url": "$REPO_URL", "branch": "$BRANCH", "local_repo": "$LOCAL_REPO", "workspace": "$WORKSPACE", "started": "$(date -u +%Y-%m-%dT%H:%M:%SZ)" } EOF cleanup() { echo "" echo "Recording ended. Daemon will push final chunk." echo "Check status: /asciinema-tools:daemon-status" } trap cleanup EXIT echo "║ Recording to: $CAST_FILE" echo "║ Run 'claude' inside this session. Exit twice to end. ║" echo "╚════════════════════════════════════════════════════════════════╝" echo "" asciinema rec --stdin "$CAST_FILE" SCRIPT_BODY chmod +x "$OUTPUT_FILE" echo "SCRIPT_GENERATED: $OUTPUT_FILE" GENERATE_SCRIPT_EOF
Phase 5: Display Instructions
## Bootstrap Complete Script generated at: `tmp/bootstrap-claude-session.sh` ### Quick Start 1. Exit Claude Code: `exit` or Ctrl+D 2. Run bootstrap: `./tmp/bootstrap-claude-session.sh` ← NOT source! 3. Inside recording, run: `claude` 4. Work normally - daemon pushes chunks to GitHub 5. Exit twice: Ctrl+D (Claude) → `exit` (recording) ### What Happens - asciinema records to `~/.asciinema/active/{workspace}_{datetime}.cast` - Daemon monitors for idle periods - On idle, chunk is compressed and pushed via Keychain PAT - Daemon sends Pushover notification on failures - Recording is decoupled from Claude Code session ### Daemon Commands | Command | Description | | -------------------------------- | ------------------- | | `/asciinema-tools:daemon-status` | Check daemon health | | `/asciinema-tools:daemon-logs` | View logs | | `/asciinema-tools:daemon-start` | Start daemon | | `/asciinema-tools:daemon-stop` | Stop daemon |
Skip Logic
- If
and-r
provided -> skip repository selection-b - If
provided -> skip all confirmations-y - If
provided -> force create orphan branch--setup-orphan
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| asciinema not found | asciinema not installed | |
| zstd not found | zstd not installed | |
| Daemon not running | Daemon not started | Run |
| Git clone fails | Auth issue or wrong URL | Run |
| Orphan branch error | Branch already exists | Remove flag |
| Script not executable | Permission issue | Run |
| Source error | Script was sourced | Execute directly: |
Post-Execution Reflection
After this skill completes, reflect before closing the task:
- Locate yourself. — Find this SKILL.md's canonical path (Glob for this skill's name) before editing. All corrections target THIS file and its sibling references/ — never other documentation.
- What failed? — Fix the instruction that caused it. If it could recur, add it as an anti-pattern.
- What worked better than expected? — Promote it to recommended practice. Document why.
- What drifted? — Any script, reference, or external dependency that no longer matches reality gets fixed now.
- Log it. — Every change gets an evolution-log entry with trigger, fix, and evidence.
Do NOT defer. The next invocation inherits whatever you leave behind.