iso-init-repo

star 0

Set up a repo with IsaiaScope governance defaults — GitHub repo creation, prod/test/dev branch structure with protection, prod-gate CI, commitlint, version-bump hook, and /deploy-cascade command. Use when the user runs /iso-init-repo or asks to set up repo governance.

IsaiaScope By IsaiaScope schedule Updated 5/29/2026

name: iso-init-repo description: Set up a repo with IsaiaScope governance defaults — GitHub repo creation, prod/test/dev branch structure with protection, prod-gate CI, commitlint, version-bump hook, and /deploy-cascade command. Use when the user runs /iso-init-repo or asks to set up repo governance.

iso-init-repo

Set up GitHub repo governance. Run from inside the target repo.

All templates live in templates/ next to this file.

Pre-flight

Run these checks before any step.

git

command -v git &>/dev/null \
  || { echo "✗ git not found. Install Xcode CLI tools: xcode-select --install"; exit 1; }

gh (GitHub CLI)

if ! command -v gh &>/dev/null; then
  echo "⚠ gh not found — installing..."
  brew install gh
  command -v gh &>/dev/null \
    || { echo "✗ gh install failed. Run manually: brew install gh"; exit 1; }
  echo "✓ gh installed"
fi

gh authentication

Authentication is interactive — cannot be automated. If not authenticated, stop and run the login command manually.

if ! gh auth status &>/dev/null; then
  echo "⚠ gh not authenticated."
  echo "  Run: gh auth login"
  echo "  Then re-run /iso-init-repo"
  exit 1
fi

Remote detection

git remote get-url origin 2>/dev/null || echo "no remote"

node / npx (Node repos — commitlint + version-bump)

Only relevant when package.json exists. Warns rather than fails — repo/branch steps still run.

if [ -f package.json ] && ! command -v npx &>/dev/null; then
  echo "⚠ node/npx not found — Steps 5–6 (commitlint, version-bump) will be skipped."
  echo "  Install Node.js: https://nodejs.org or via nvm/fnm"
fi

All checks pass → proceed to Step 1.

Step 1 — GitHub repo

No remote → create

Ask user for repo name (default: current directory name) and visibility (private/public).

gh repo create <name> --private --source=. --remote=origin --push

Remote exists → verify

gh repo view

Confirm accessible, then continue.

Step 2 — Branch structure

Target: dev (default, daily work) ← test (staging) ← prod (release)

ORIGIN=$(git symbolic-ref --short HEAD)   # current default, likely 'main'

# Create prod from current default
git checkout -b prod 2>/dev/null || git checkout prod
git push -u origin prod

# Create test and dev from prod
git checkout -b test prod && git push -u origin test
git checkout -b dev prod && git push -u origin dev

# Set dev as GitHub default branch
gh repo edit --default-branch dev

# Delete original default (main) if it was the starting point
if [ "$ORIGIN" = "main" ]; then
  git push origin --delete main
  git branch -d main
fi

Only delete main if prod was successfully created with full history.

Step 3 — Branch protection

Requires the branches from Step 2 to exist on origin.

REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)

# prod — PR required, no force push. ci-prod-gate enforces source=test.
gh api "repos/$REPO/branches/prod/protection" --method PUT \
  --input - <<'EOF'
{
  "required_status_checks": null,
  "enforce_admins": false,
  "required_pull_request_reviews": { "required_approving_review_count": 0 },
  "restrictions": null
}
EOF

# test — PR required, no force push
gh api "repos/$REPO/branches/test/protection" --method PUT \
  --input - <<'EOF'
{
  "required_status_checks": null,
  "enforce_admins": false,
  "required_pull_request_reviews": { "required_approving_review_count": 0 },
  "restrictions": null
}
EOF

# dev — PR required, no force push
gh api "repos/$REPO/branches/dev/protection" --method PUT \
  --input - <<'EOF'
{
  "required_status_checks": null,
  "enforce_admins": false,
  "required_pull_request_reviews": { "required_approving_review_count": 0 },
  "restrictions": null
}
EOF

Branch protection can't restrict PR source branch — that's what ci-prod-gate.yml handles.

Step 4 — GitHub files

Read templates/ci-prod-gate.yml → write to .github/workflows/ci-prod-gate.yml.

git checkout dev
git add .github/
git commit -m "chore(repo): add prod-gate workflow"
git push origin dev

Step 5 — Commitlint

Skip if no package.json.

5a — Package manager

if [ -f pnpm-lock.yaml ]; then echo "pnpm"
elif [ -f yarn.lock ]; then echo "yarn"
elif [ -f bun.lockb ] || [ -f bun.lock ]; then echo "bun"
else echo "npm"; fi

5b — Init Husky (only if .husky/ missing)

[ -d .husky ] || npx husky init

5c — Install deps

Only install packages not already in package.json. Skip any already present.

pnpm add -D -w @commitlint/cli @commitlint/config-conventional   # pnpm
yarn add -D -W @commitlint/cli @commitlint/config-conventional   # yarn
bun add -d @commitlint/cli @commitlint/config-conventional       # bun
npm install --save-dev @commitlint/cli @commitlint/config-conventional  # npm

Also ensure "prepare": "husky" is in package.json scripts if missing.

5d — commit-msg hook

Read templates/commit-msg.sh → write to .husky/commit-msg, chmod +x.

Guard:

grep -q "commitlint" .husky/commit-msg 2>/dev/null \
  && echo "commit-msg: already configured, skipping" \
  || { cat templates/commit-msg.sh > .husky/commit-msg && chmod +x .husky/commit-msg; }

5e — commitlint.config.js

Check before writing:

[ -f commitlint.config.js ] \
  && echo "commitlint.config.js: already exists, skipping — review manually if needed" \
  || cp templates/commitlint.config.js commitlint.config.js

Before enabling scope-enum, audit all scopes in git history:

git log --oneline | sed -n 's/[^(]*(\([^)]*\)).*/\1/p' | sort -u

Only uncomment scope-enum if the repo has clean, consistent scopes. Populate from:

  • scopes found above
  • names from ls apps/ packages/
  • cross-cutting: ci, deps, docs, repo

If history has free-text scopes — leave scope-enum commented. scope-empty alone is sufficient.

Commit:

git add .husky/ commitlint.config.js package.json
git commit -m "chore(repo): add commitlint"
git push origin dev

Step 6 — Version bump hook

Skip if no package.json.

Read templates/post-commit-version-bump.sh → write to .husky/post-commit-version-bump.sh, chmod +x.

If .husky/post-commit exists, append; otherwise create:

bash "$(dirname "$0")/post-commit-version-bump.sh"

Commit:

git add .husky/
git commit -m "chore(repo): add version-bump post-commit hook"
git push origin dev

Step 8 — Deploy cascade command

Read templates/deploy-cascade-command.md → write to .claude/commands/deploy-cascade.md.

This gives the repo a /deploy-cascade command. Uses caveman skill for all output. Starting point is auto-detected from current branch — runnable from any branch except prod.

mkdir -p .claude/commands
git add .claude/commands/deploy-cascade.md
git commit -m "chore(repo): add /deploy-cascade command"
git push origin dev

Step 9 — Summary

✓ GitHub repo created/configured
✓ Branches: dev (default) ← test ← prod
✓ Protection: PR required on dev, test, prod (no direct push)
✓ .github/workflows/ci-prod-gate.yml       — prod accepts PRs from test only
✓ .husky/commit-msg + commitlint.config.js [or: skipped — no package.json]
✓ .husky/post-commit-version-bump.sh       [or: skipped — no package.json]
✓ .claude/commands/deploy-cascade.md       — /deploy-cascade command

Cascade: <any branch> → dev → test → prod /deploy-cascade auto-detects starting point — run from any branch except prod. Uses caveman skill. Prod-gate: PRs to prod from any branch other than test fail CI automatically.

Install via CLI
npx skills add https://github.com/IsaiaScope/ai --skill iso-init-repo
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator