mcpField
B
bootstrap

bootstrap

github.com/terrylicaエージェントワークフロー292 回インストール1 日前に更新
リポジトリ

bootstrap について

Claude Code の外で asciinema の録画セッションを開始するブートストラップスクリプトを生成するスキルです。環境と GitHub リポジトリを確認し、チャンク処理は launchd デーモンに任せます。

主な機能

  1. 01asciinema、zstd、git の確認
  2. 02Git リポジトリとブランチ状態の検出
  3. 03録画用リポジトリと orphan ブランチの選択・作成
  4. 04ブートストラップスクリプトの生成
  5. 05起動手順とトラブルシューティングの提示

活用シーン

  1. 01Claude Code セッションの端末録画設定
  2. 02指定した GitHub リポジトリへの録画保存
  3. 03録画に必要なデーモンとツールの確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/terrylica/cc-skills --skill bootstrap

インストール後、Claude Code で/bootstrapを入力して読み込まれたか確認します。

同梱ファイルreferences/evolution-log.md

詳細

/asciinema-tools:bootstrap

Claude Code の外部で実行し、録画セッションを開始するブートストラップスクリプトを生成します。

重要:チャンク分割は launchd デーモンが処理します。まだ設定していない場合は、先に /asciinema-tools:daemon-setup を実行してください。

自己進化型スキル:このスキルは使用するたびに改善されます。指示に誤りがある場合、パラメーターにずれがある場合、または回避策が必要だった場合は、先送りせず、すぐにこのファイルを修正してください。実際に再現できる問題がある場合にのみ更新してください。

アーキテクチャ

┌─────────────────────────────────────────────────────────────────────────────┐
│                        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                                             │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

引数

引数説明
-r, --repoGitHub リポジトリ(例:owner/repo)
-b, --branch孤立ブランチ名(デフォルト:asciinema-recordings)
--setup-orphan孤立ブランチを強制的に作成
-y, --yes確認プロンプトをスキップ

実行

フェーズ 0:事前チェック
/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

DAEMON: NOT_RUNNING の場合は、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)"
フェーズ 1:リポジトリのコンテキストを検出

必須:オプションを自動入力するため、AskUserQuestion の前に実行してください。

/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
フェーズ 2:リポジトリの選択(AskUserQuestion を必ず使用)

検出結果に基づきます:

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"

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"

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"
フェーズ 3:孤立ブランチの作成(必要な場合)

最初に SSH キャッシュをクリアしてから、孤立ブランチを作成します:

/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 [email protected] 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
フェーズ 4:ブートストラップスクリプトの生成

簡略化したブートストラップスクリプトを生成します(チャンク分割はデーモンが処理します):

/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 [email protected] 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
フェーズ 5:手順の表示
## 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         |

スキップ条件

  • -r と -b が指定されている場合 -> リポジトリの選択をスキップ
  • -y が指定されている場合 -> すべての確認をスキップ
  • --setup-orphan が指定されている場合 -> 孤立ブランチを強制的に作成

トラブルシューティング

問題原因解決策
asciinema が見つからないasciinema がインストールされていないbrew install asciinema
zstd が見つからないzstd がインストールされていないbrew install zstd
デーモンが起動していないデーモンが起動していない/asciinema-tools:daemon-start を実行
Git のクローンに失敗する認証の問題または URL の誤りgh auth login を実行
孤立ブランチのエラーブランチがすでに存在する--setup-orphan フラグを削除
スクリプトが実行可能でない権限の問題chmod +x tmp/bootstrap-*.sh を実行
ソースエラースクリプトが source された直接実行してください:./script.sh

実行後の振り返り

このスキルの実行後、タスクを終了する前に振り返ってください:

  1. 自分の場所を確認します。 — 編集する前に、このスキル名で Glob を実行して SKILL.md の正規パスを見つけてください。修正対象は必ずこのファイルとその兄弟ファイルである references/ に限定し、他のドキュメントは変更しないでください。
  2. 何が失敗しましたか? — 原因となった指示を修正してください。再発する可能性がある場合は、アンチパターンとして追加してください。
  3. 予想以上にうまくいったことは何ですか? — 推奨プラクティスとして取り入れてください。その理由も記録してください。
  4. 何にずれがありましたか? — 現状と一致しなくなったスクリプト、参照資料、外部依存関係は、今すぐ修正してください。
  5. 記録してください。 — 変更のたびに、きっかけ、修正内容、根拠を含む進化ログのエントリーを追加してください。

先送りしないでください。次回の実行では、ここに残した状態が引き継がれます。

コメント