core-bootstrap
Skill0 starsChanged 4 months agoMITView on GitHub
Bootstrap ~/.claude/ config, symlinks, and settings. Use with /core-bootstrap.
In this repository42 other files it gives its agents.
- .claude/CLAUDE.mdCLAUDE.md
- content-rewriteSkill
- content-writeSkill
- core-auditSkill
- core-commitSkill
- core-explainSkill
- core-finalizeSkill
- core-orchestrateSkill
- core-pullSkill
- core-setupSkill
- core-updateSkill
- design-convertSkill
- design-shipSkill
- design-tokensSkill
- dev-inspectSkill
- dev-learnSkill
- dev-manualSkill
- dev-optimizeSkill
- dev-securitySkill
- dev-shipSkill
- dev-tweakSkill
- game-debugSkill
- game-optimizeSkill
- game-shipSkill
- game-tweakSkill
- marketing-contentSkill
- marketing-researchSkill
- marketing-screenshotsSkill
- project-addSkill
- project-appSkill
- project-memorySkill
- project-planSkill
- project-removeSkill
- project-researchSkill
- project-seedSkill
- project-syncSkill
- project-todoSkill
- project-tunnelSkill
- team-issuesSkill
- team-outsourceSkill
- team-reviewSkill
- team-verifySkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
16 rules. About 0 are common, 1 is distinctive, and 15 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
15
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 47
Check jq availability (advisory only — does not stop execution):
- Very specific: line 55
Check whether ~/.claude/CLAUDE.md already contains a Language: setting:
- Very specific: line 61
If Language: is found → store LANGUAGE_CHOICE=skip (language step skipped — re-runs leave existing setting alone).
- Very specific: line 63
If Language: is not found → ask (two sequential modals, 4-option cap per shared/SKILL-PATTERNS.md § Modal Option Cap.
- Very specific: line 95
Check whether ~/.claude/CLAUDE.md already contains an Explanation Level: setting:
- Very specific: line 101
If Explanation Level: is found → store EXPLANATION_CHOICE=skip (step skipped — re-runs leave existing setting alone).
- Very specific: line 103
If Explanation Level: is not found → ask:
- Very specific: line 130
If ~/.claude/settings.json is found → store PERM_CHOICE=skip (already configured — don't touch it).
- Distinctive: line 132
If not found → ask:
- Very specific: line 149
Check $CONFIG_REPO/.claude/paths.local.yaml for a persisted value first:
- Very specific: line 169
If PLAN_TIER is non-empty → skip the question (use persisted value, note it in PHASE 3 report as <value> (saved)).
- Very specific: line 171
If PLAN_TIER is empty → ask:
- Very specific: line 194
Write per-machine path configuration to $CONFIG_REPO/.claude/paths.local.yaml.
- Very specific: line 349
After copying CLAUDE.md (only if it was actually placed, and LANGUAGE_CHOICE is not skip):
- Very specific: line 397
After copying settings.json (only if it was actually placed, and PERM_CHOICE=auto):
- Very specific: line 703
skip: no plan-tier block shown.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Core Bootstrap Skill
Trigger: /core-bootstrap
Bootstrap of the user-global Claude Code configuration. Deploys 4 user-files to ~/.claude/ and creates 4 global symlinks/junctions. Fully idempotent — running again skips anything already in place, so it is always safe to re-run after a git pull or on a new machine. To replace a deployed file, delete it manually first, then re-run.
PHASE 0: Pre-flight
Resolve CONFIG_REPO — the root of the cloned claude-config repo:
# macOS/Linux — follow symlink of ~/.claude/skills if it already exists
if [ -L "$HOME/.claude/skills" ]; then
CONFIG_REPO="$(realpath "$HOME/.claude/skills/..")"
else
# Fallback: current working directory if it is the repo
CONFIG_REPO="$(pwd)"
fi# Windows
if (Test-Path "$env:USERPROFILE\.claude\skills" -PathType Container) {
$CONFIG_REPO = Split-Path (Resolve-Path "$env:USERPROFILE\.claude\skills") -Parent
} else {
$CONFIG_REPO = (Get-Location).Path
}Validate that $CONFIG_REPO/local/ exists. If not:
Cannot find local/. Run /core-bootstrap from the claude-config repo directory, or ensure ~/.claude/skills already symlinks to the repo.
Stop.
Check jq availability (advisory only — does not stop execution):
command -v jq >/dev/null 2>&1 || echo "warn: jq not found — settings overlay merge will be skipped if personal/settings.overlay.json is present"Language selection
Check whether ~/.claude/CLAUDE.md already contains a Language: setting:
grep -q "Language:" "$HOME/.claude/CLAUDE.md" 2>/dev/null && echo "found" || echo "not-found"If Language: is found → store LANGUAGE_CHOICE=skip (language step skipped — re-runs leave existing setting alone).
If Language: is not found → ask (two sequential modals, 4-option cap per shared/SKILL-PATTERNS.md § Modal Option Cap; show modal 2 only if "More languages →" is picked):
header: "Language"
question: "Which language should Claude use for output?"
options:
- label: "English (Recommended)"
description: "Claude responds in English"
- label: "Nederlands"
description: "Claude responds in Dutch"
- label: "Deutsch"
description: "Claude antwortet auf Deutsch"
- label: "More languages →"
description: "Français, Español"
multiSelect: falseheader: "Language"
question: "Which language should Claude use for output?"
options:
- label: "Français"
description: "Claude répond en français"
- label: "Español"
description: "Claude responde en español"
multiSelect: falseStore the chosen label in LANGUAGE_CHOICE (e.g. "Nederlands"). If the user selects "English (Recommended)" → LANGUAGE_CHOICE=skip (template default, no patch needed).
Explanation Level selection
Check whether ~/.claude/CLAUDE.md already contains an Explanation Level: setting:
grep -q "Explanation Level:" "$HOME/.claude/CLAUDE.md" 2>/dev/null && echo "found" || echo "not-found"If Explanation Level: is found → store EXPLANATION_CHOICE=skip (step skipped — re-runs leave existing setting alone).
If Explanation Level: is not found → ask:
header: "Explanation Level"
question: "How should Claude calibrate jargon and explanation depth by default?"
options:
- label: "Intermediate (Recommended)"
description: "Standard depth. Jargon ok, no extra scaffolding. Good default for most stacks."
- label: "Beginner"
description: "Every non-trivial term explained. Analogies always used. Good for stacks you're learning from scratch."
- label: "Novice"
description: "Framework-specific jargon explained. Analogies when helpful. Between Beginner and standard."
- label: "Expert"
description: "Compact. Assumes full stack familiarity. No term introductions or analogies."
multiSelect: falseStore the chosen label in EXPLANATION_CHOICE (e.g. "Beginner"). If the user selects "Intermediate (Recommended)" → EXPLANATION_CHOICE=skip (template default, no patch needed).
Permission mode selection
settings.json is only copied when it does not already exist. Mirror that for this question — re-runs leave an existing permission posture alone:
[ -f "$HOME/.claude/settings.json" ] && echo "found" || echo "not-found"If ~/.claude/settings.json is found → store PERM_CHOICE=skip (already configured — don't touch it).
If not found → ask:
header: "Permission mode"
question: "How should Claude handle tool permissions by default?"
options:
- label: "Bypass permissions (Recommended)"
description: "No permission prompts. Safe here because all skills run within guard rails (plan mode, security-reminder + format-on-save hooks, explicit handoff contracts)."
- label: "Auto mode"
description: "Claude's classifier auto-approves safe actions and prompts only on risky/irreversible ones."
multiSelect: falseStore the choice in PERM_CHOICE. If the user selects "Bypass permissions (Recommended)" → PERM_CHOICE=skip (template default: bypassPermissions + disableAutoMode + dangerous-mode dialog pre-accepted, no patch needed). If "Auto mode" → PERM_CHOICE=auto (patched in PHASE 1).
Claude plan tier
Check $CONFIG_REPO/.claude/paths.local.yaml for a persisted value first:
# macOS/Linux
PLAN_TIER=""
if [ -f "$CONFIG_REPO/.claude/paths.local.yaml" ]; then
PLAN_TIER=$(grep "claude_plan:" "$CONFIG_REPO/.claude/paths.local.yaml" | sed 's/.*claude_plan:[[:space:]]*//' | tr -d '"')
fi# Windows
$planTier = ""
$pathsLocal = "$CONFIG_REPO\.claude\paths.local.yaml"
if (Test-Path $pathsLocal) {
$line = Select-String -Path $pathsLocal -Pattern "claude_plan:" | Select-Object -First 1
if ($line) { $planTier = ($line.Line -replace '.*claude_plan:\s*"?([^"]+)"?.*', '$1').Trim() }
}If PLAN_TIER is non-empty → skip the question (use persisted value, note it in PHASE 3 report as <value> (saved)).
If PLAN_TIER is empty → ask:
header: "Claude plan"
question: "Which Claude plan are you on? (used to tailor the post-bootstrap tip)"
options:
- label: "Max 5x"
description: 'Tip: /model opus + effortLevel:"high" — full Opus; plan mode is an approval gate, not a routing switch'
- label: "Pro"
description: 'Tip: /model sonnet + effortLevel:"medium" — Opus quota is tight on Pro'
- label: "Max 10x+"
description: 'Tip: /model opus + effortLevel:"high" — quota headroom for full-Opus runs'
- label: "Skip"
description: "No plan-specific tip shown"
multiSelect: falseStore the choice in PLAN_TIER (one of max-5x, pro, max-10x, skip). Write to paths.local.yaml in PHASE 0.5 (see below).
PHASE 0.5: Paths setup
Write per-machine path configuration to $CONFIG_REPO/.claude/paths.local.yaml. Idempotent — skip writing if the file already exists, but validate that its projects_root still points at an existing directory and offer to correct a stale path.
# macOS/Linux
PATHS_LOCAL="$CONFIG_REPO/.claude/paths.local.yaml"
if [ -f "$PATHS_LOCAL" ]; then
PATHS_STATUS="already-exists"
# Validate the configured projects_root still points at an existing directory.
# A stale path (e.g. moved projects folder) leaves the backlog server scanning
# nothing — correct it, but don't re-prompt when the path is fine (stays idempotent).
cur=$(awk -F'"' '/^[[:space:]]*projects_root:/ {print $2; exit}' "$PATHS_LOCAL")
exp="${cur/#\~/$HOME}"; exp="${exp/#\$HOME/$HOME}"
if [ -n "$cur" ] && [ ! -d "$exp" ]; then
# AskUserQuestion (open text input): projects_root "$cur" no longer exists —
# ask for a new absolute path that must exist as a directory. Store in NEW_ROOT.
sed -i '' 's|^\([[:space:]]*projects_root:\).*|\1 "'"$NEW_ROOT"'"|' "$PATHS_LOCAL"
PATHS_STATUS="updated"
fi
else
# Ask the user via AskUserQuestion (open text input — no default, no fallback):
# header: "Projects root"
# question: "What is the absolute path to your projects root? This is where
# /project-add creates new projects.
# Example: /Users/you/projects or /Users/you/Documents/Projects"
# Validate: the path must exist as a directory. If not, re-ask.
# Store input in PROJECTS_ROOT (no fallback — the user must answer).
mkdir -p "$CONFIG_REPO/.claude"
cat > "$PATHS_LOCAL" <<EOF
paths:
projects_root: "$PROJECTS_ROOT"
config_repo: "$CONFIG_REPO"
preferences:
claude_plan: "$PLAN_TIER"
EOF
PATHS_STATUS="written"
fi
# Backfill preferences block if file existed but predates plan-tier
if [ "$PATHS_STATUS" = "already-exists" ] && ! grep -q "claude_plan:" "$PATHS_LOCAL" 2>/dev/null; then
printf '\npreferences:\n claude_plan: "%s"\n' "$PLAN_TIER" >> "$PATHS_LOCAL"
fi# Windows
$pathsLocal = "$CONFIG_REPO\.claude\paths.local.yaml"
if (Test-Path $pathsLocal) {
$pathsStatus = "already-exists"
# Backfill preferences block if missing (old format)
$content = Get-Content $pathsLocal -Raw
if ($content -notmatch "claude_plan:") {
Add-Content $pathsLocal "`npreferences:`n claude_plan: `"$planTier`""
}
# Validate projects_root still exists; correct a stale path (don't re-prompt if fine).
if ($content -match '(?m)^\s*projects_root:\s*"?([^"\r\n]+)"?') {
$cur = $Matches[1].Trim().TrimEnd('"')
if (-not (Test-Path $cur -PathType Container)) {
# AskUserQuestion (open text input): projects_root "$cur" no longer exists —
# ask for a new absolute path that must exist. Store in $newRoot.
(Get-Content $pathsLocal -Raw) -replace '(?m)^(\s*projects_root:).*', "`$1 `"$newRoot`"" | Set-Content $pathsLocal
$pathsStatus = "updated"
}
}
} else {
# Ask the user via AskUserQuestion (open text input — no default, no fallback):
# header: "Projects root"
# question: "What is the absolute path to your projects root?
# Example: C:\Projects or C:\Users\you\Documents\Projects"
# Validate: the path must exist as a directory. If not, re-ask.
# Store as $projectsRoot (no fallback — the user must answer).
# Ask the user (optional):
# header: "Godot executable"
# question: "Where is your Godot executable? (optional — press Enter / leave empty to skip)"
# Store as $godotPath; if empty, omit from file
New-Item -ItemType Directory -Force -Path "$CONFIG_REPO\.claude" | Out-Null
$lines = @("paths:", " projects_root: `"$projectsRoot`"", " config_repo: `"$CONFIG_REPO`"")
if ($godotPath) { $lines += " godot_executable: `"$godotPath`"" }
$lines += @("preferences:", " claude_plan: `"$planTier`"")
$lines -join "`n" | Set-Content $pathsLocal
$pathsStatus = "written"
}Note:
paths.local.yamlis read byserve-backlog.js(and other shared tools) vialib/config.jsfallback — so the backlog server finds your projects automatically after bootstrap without any env var setup. Setting env vars in your shell profile (export CLAUDE_PROJECTS_ROOT="...") remains an override option but is no longer required.
PHASE 1: Copy user-files
Copy 4 files to ~/.claude/. Skip if the destination already exists — never overwrites. Create ~/.claude/ if it is missing.
Report the outcome per file (for the PHASE 3 report):
| File | Source | Destination |
| CLAUDE.md | $CONFIG_REPO/local/CLAUDE.md.base | ~/.claude/CLAUDE.md |
| settings.json | $CONFIG_REPO/local/settings.json.template | ~/.claude/settings.json |
| keybindings.json | $CONFIG_REPO/local/keybindings.json | ~/.claude/keybindings.json |
| statusline-command.cjs | $CONFIG_REPO/local/statusline-command.cjs | ~/.claude/statusline-command.cjs |
# macOS/Linux
CLAUDE_DIR="$HOME/.claude"
mkdir -p "$CLAUDE_DIR"
LOCAL="$CONFIG_REPO/local"
declare -A FILES=(
["CLAUDE.md"]="$LOCAL/CLAUDE.md.base"
["settings.json"]="$LOCAL/settings.json.template"
["keybindings.json"]="$LOCAL/keybindings.json"
["statusline-command.cjs"]="$LOCAL/statusline-command.cjs"
)
for dest_name in "${!FILES[@]}"; do
src="${FILES[$dest_name]}"
dest="$CLAUDE_DIR/$dest_name"
if [ ! -f "$dest" ]; then
cp "$src" "$dest"
# STATUS: placed
else
: # STATUS: already-exists
fi
done# Windows
$claudeDir = "$env:USERPROFILE\.claude"
New-Item -ItemType Directory -Force -Path $claudeDir | Out-Null
$local = "$CONFIG_REPO\local"
$files = @{
"CLAUDE.md" = "$local\CLAUDE.md.base"
"settings.json" = "$local\settings.json.template"
"keybindings.json" = "$local\keybindings.json"
"statusline-command.cjs" = "$local\statusline-command.cjs"
}
foreach ($destName in $files.Keys) {
$src = $files[$destName]
$dest = "$claudeDir\$destName"
if (-not (Test-Path $dest)) {
Copy-Item $src $dest
# STATUS: placed
} else {
# STATUS: already-exists
}
}Language patch
After copying CLAUDE.md (only if it was actually placed, and LANGUAGE_CHOICE is not skip):
Patch the Language: line in ~/.claude/CLAUDE.md and the "language" field in ~/.claude/settings.json to keep them in sync.
# macOS/Linux — CLAUDE.md (portable sed)
sed -i.bak "s/^Language:.*$/Language: $LANGUAGE_CHOICE/" "$HOME/.claude/CLAUDE.md" && rm -f "$HOME/.claude/CLAUDE.md.bak"
# settings.json — prefer jq; fall back to sed
SETTINGS="$HOME/.claude/settings.json"
if command -v jq >/dev/null 2>&1; then
jq --arg lang "$LANGUAGE_CHOICE" '.language = $lang' "$SETTINGS" > "$SETTINGS.tmp" && mv "$SETTINGS.tmp" "$SETTINGS"
else
sed -i.bak "s/\"language\":.*$/\"language\": \"$LANGUAGE_CHOICE\",/" "$SETTINGS" && rm -f "$SETTINGS.bak"
fi# Windows — CLAUDE.md
(Get-Content "$env:USERPROFILE\.claude\CLAUDE.md") -replace '^Language:.*$', "Language: $LANGUAGE_CHOICE" |
Set-Content "$env:USERPROFILE\.claude\CLAUDE.md"
# settings.json
$settings = "$env:USERPROFILE\.claude\settings.json"
$json = Get-Content $settings -Raw | ConvertFrom-Json
$json.language = $LANGUAGE_CHOICE
$json | ConvertTo-Json -Depth 10 | Set-Content $settingsExplanation Level patch
After copying CLAUDE.md (only if it was actually placed, and EXPLANATION_CHOICE is not skip):
Patch the Explanation Level: line in ~/.claude/CLAUDE.md.
# macOS/Linux — CLAUDE.md
sed -i.bak "s/^Explanation Level:.*$/Explanation Level: $EXPLANATION_CHOICE/" "$HOME/.claude/CLAUDE.md" && rm -f "$HOME/.claude/CLAUDE.md.bak"# Windows — CLAUDE.md
(Get-Content "$env:USERPROFILE\.claude\CLAUDE.md") -replace '^Explanation Level:.*$', "Explanation Level: $EXPLANATION_CHOICE" |
Set-Content "$env:USERPROFILE\.claude\CLAUDE.md"Permission mode patch
After copying settings.json (only if it was actually placed, and PERM_CHOICE=auto):
The template ships the recommended bypass posture, so the recommended choice needs no patch. The auto-mode choice flips defaultMode to auto, drops the bypass-only flags, and pre-accepts the auto-mode opt-in dialog.
# macOS/Linux — settings.json (jq preferred, sed fallback)
SETTINGS="$HOME/.claude/settings.json"
if command -v jq >/dev/null 2>&1; then
jq '.permissions.defaultMode = "auto"
| del(.disableAutoMode)
| del(.skipDangerousModePermissionPrompt)
| .skipAutoPermissionPrompt = true' \
"$SETTINGS" > "$SETTINGS.tmp" && mv "$SETTINGS.tmp" "$SETTINGS"
else
# sed fallback flips defaultMode only — it cannot reliably remove the disableAutoMode /
# skipDangerousModePermissionPrompt keys. Install jq for a clean auto-mode switch.
sed -i.bak 's/"defaultMode":[[:space:]]*"bypassPermissions"/"defaultMode": "auto"/' "$SETTINGS" && rm -f "$SETTINGS.bak"
fi# Windows — settings.json
$settings = "$env:USERPROFILE\.claude\settings.json"
$json = Get-Content $settings -Raw | ConvertFrom-Json
$json.permissions.defaultMode = "auto"
$json.PSObject.Properties.Remove("disableAutoMode")
$json.PSObject.Properties.Remove("skipDangerousModePermissionPrompt")
$json | Add-Member -NotePropertyName skipAutoPermissionPrompt -NotePropertyValue $true -Force
$json | ConvertTo-Json -Depth 10 | Set-Content $settingsAfter copying: show a brief reminder:
settings.json copied — verify that hook paths are correct for your platform (see local/README.md).
Show this reminder only if settings.json was actually placed or overwritten.
PHASE 1.5: Personal overlay
Apply user-specific customisations from $CONFIG_REPO/personal/ (gitignored, optional).
# macOS/Linux
PERSONAL_DIR="$CONFIG_REPO/personal"
if [ -d "$PERSONAL_DIR" ]; then
OVERLAY_COUNT=0
# 1. CLAUDE.md overlay — append to base
if [ -f "$PERSONAL_DIR/CLAUDE.md.overlay" ]; then
cat "$PERSONAL_DIR/CLAUDE.md.overlay" >> "$HOME/.claude/CLAUDE.md"
OVERLAY_COUNT=$((OVERLAY_COUNT + 1))
fi
# 2. settings.overlay.json — deep-merge (right-wins) via jq
if [ -f "$PERSONAL_DIR/settings.overlay.json" ]; then
if command -v jq >/dev/null 2>&1; then
jq -s '.[0] * .[1]' "$HOME/.claude/settings.json" "$PERSONAL_DIR/settings.overlay.json" \
> "$HOME/.claude/settings.json.tmp" && mv "$HOME/.claude/settings.json.tmp" "$HOME/.claude/settings.json"
OVERLAY_COUNT=$((OVERLAY_COUNT + 1))
else
echo "warn: jq not found — skipping settings overlay merge"
fi
fi
# 3. styles/ — symlink to ~/.claude/styles/
if [ -d "$PERSONAL_DIR/styles" ]; then
ln -sfn "$PERSONAL_DIR/styles" "$HOME/.claude/styles"
OVERLAY_COUNT=$((OVERLAY_COUNT + 1))
fi
# STATUS: applied ($OVERLAY_COUNT items) if OVERLAY_COUNT > 0, else found-nothing
else
# STATUS: not found (optional)
fi# Windows
$personalDir = "$CONFIG_REPO\personal"
$overlayCount = 0
if (Test-Path $personalDir) {
# 1. CLAUDE.md overlay
$overlay = "$personalDir\CLAUDE.md.overlay"
if (Test-Path $overlay) {
Get-Content $overlay | Add-Content "$env:USERPROFILE\.claude\CLAUDE.md"
$overlayCount++
}
# 2. settings.overlay.json — deep-merge via jq
$settingsOverlay = "$personalDir\settings.overlay.json"
if (Test-Path $settingsOverlay) {
if (Get-Command jq -ErrorAction SilentlyContinue) {
$merged = jq -s '.[0] * .[1]' "$env:USERPROFILE\.claude\settings.json" $settingsOverlay
$merged | Set-Content "$env:USERPROFILE\.claude\settings.json"
$overlayCount++
} else {
Write-Warning "jq not found — skipping settings overlay merge"
}
}
# 3. styles/ — junction to ~/.claude/styles/
$stylesDir = "$personalDir\styles"
$stylesTarget = "$env:USERPROFILE\.claude\styles"
if ((Test-Path $stylesDir) -and (-not (Test-Path $stylesTarget))) {
cmd /c "mklink /J `"$stylesTarget`" `"$stylesDir`""
$overlayCount++
}
# STATUS: applied ($overlayCount items) if $overlayCount > 0, else found-nothing
} else {
# STATUS: not found (optional)
}PHASE 2: Global symlinks / junctions
Link 4 directories: agents, hooks, skills, scripts. Skip if the link already exists (-e check, no overwrite).
# macOS/Linux
for dir in agents hooks skills scripts; do
target="$HOME/.claude/$dir"
[ ! -e "$target" ] && ln -sfn "$CONFIG_REPO/$dir" "$target"
# STATUS: linked (new) or already-exists
done# Windows
foreach ($dir in @("agents","hooks","skills","scripts")) {
$target = "$env:USERPROFILE\.claude\$dir"
if (-not (Test-Path $target)) {
cmd /c "mklink /J `"$target`" `"$CONFIG_REPO\$dir`""
# STATUS: linked (new)
} else {
# STATUS: already-exists
}
}PHASE 2.5: Board background service
Best-effort, silent, non-blocking — sets up the /project-app board's background service
(keeps serve-backlog.js warm so the board is one click, no manual server start; see
project-app/SKILL.md). A failure here (e.g. Node.js not installed yet) must never stop the
rest of bootstrap — this is a nice-to-have, not a core-config requirement.
Todo: Read
.claude/skills/shared/APP-INSTALL-CHECK.mdand follow it.
Runs after PHASE 2 so the ~/.claude/skills/... symlinks/junctions it depends on already exist.
No AskUserQuestion here — installed silently, outcome only surfaces in the PHASE 3 report
(matches this repo owner's explicit preference: no extra prompt for this one).
Store the outcome as BOARD_SERVICE_STATUS: installed-now (from INSTALLED_NOW),
already-installed (from ALREADY_INSTALLED), or skipped: <reason> (from SKIPPED:
<reason>) — for the PHASE 3 report row.
PHASE 2.6: Usage-window opener routine (optional, opt-in)
Best-effort, opt-in — asks once, defaults to Skip. Sets up a daily cloud routine (via the
RemoteTrigger harness tool, same mechanism as the /schedule skill) that pings a minimal Haiku
turn three times a day so the account's rolling 5-hour usage window opens at predictable anchors
instead of drifting with whenever the user happens to first prompt. This is per-account, not
per-machine — re-running bootstrap on a second machine must not create a duplicate routine (the
reference below dedups by name before creating).
header: "Window opener"
question: "Set up a daily cloud routine that opens your 5h usage window at fixed times (08:00 / 18:00 / 23:00 Europe/Amsterdam, Haiku model)?"
options:
- label: "Skip (Recommended)"
description: "Don't create a routine. You can set this up later via /schedule or re-run bootstrap."
- label: "Create"
description: "Creates a cloud routine now (uses account quota for 3 minimal Haiku pings/day)."
multiSelect: falseStore the choice in WINDOW_OPENER. If "Skip (Recommended)" → WINDOW_OPENER_STATUS="skipped (declined)", no further action this phase.
If "Create":
Todo: Read
.claude/skills/core-bootstrap/references/usage-window-opener.mdand follow it.
That reference is fully self-contained (tool loading, account-level dedup, environment/repo
resolution, routine creation) and sets WINDOW_OPENER_STATUS to one of: created ·
already-exists (account) · skipped (<reason>). A failure here must never block PHASE 3.
PHASE 3: Report
Show ASCII table with outcome per item:
Bootstrap complete
══════════════════════════════════════════════════════
Item Status
──────────────────────────────────────────────────────
~/.claude/CLAUDE.md placed
~/.claude/settings.json already-exists
~/.claude/keybindings.json already-exists
~/.claude/statusline-… placed
~/.claude/agents/ linked
~/.claude/hooks/ already-exists
~/.claude/skills/ already-exists
~/.claude/scripts/ already-exists
Personal overlay applied (2 items)
Language English
Explanation Level Intermediate
Permission mode Bypass permissions
Claude plan Max 5x
Paths (paths.local.yaml) written
Board background service installed
Window opener routine created
══════════════════════════════════════════════════════Statuses: placed · already-exists · linked · error: <reason>
For the Board background service row: installed (from BOARD_SERVICE_STATUS=installed-now),
already installed (from already-installed), or skipped (<reason>) (from skipped: <reason>
— e.g. skipped (Node.js not found)). This never blocks the rest of the report or a skipped
overall bootstrap outcome — it's its own independent row.
For the Window opener routine row: show WINDOW_OPENER_STATUS verbatim (created ·
already-exists (account) · skipped (declined) · skipped (<reason>)). If created, also
show the routine link in the closing tip:
Window opener routine created: https://claude.ai/code/routines/{id} Ticks daily at 08:00 / 18:00 / 23:00 Europe/Amsterdam (fixed UTC — shifts an hour earlier in winter). Adjust anytime via /schedule or https://claude.ai/code/routines.
Show this extra tip block only when WINDOW_OPENER_STATUS="created".
For the Language row: show the chosen language, or the current value with (already set) suffix if LANGUAGE_CHOICE=skip. Read the current value via:
CURRENT_LANG=$(grep "^Language:" "$HOME/.claude/CLAUDE.md" | sed 's/^Language:[[:space:]]*//')For the Explanation Level row: show the chosen level, or the current value with (already set) suffix if EXPLANATION_CHOICE=skip. Read the current value via:
CURRENT_EXPL=$(grep "^Explanation Level:" "$HOME/.claude/CLAUDE.md" | sed 's/^Explanation Level:[[:space:]]*//')For the Permission mode row: show Bypass permissions or Auto mode per PERM_CHOICE, or the current defaultMode value with (already set) suffix if PERM_CHOICE=skip. Read the current value via:
CURRENT_MODE=$(jq -r '.permissions.defaultMode' "$HOME/.claude/settings.json" 2>/dev/null)For the Claude plan row: show the PLAN_TIER label (Max 5x, Pro, Max 10x+, or skipped).
For the Paths row: show written / already-exists.
For the Personal overlay row:
personal/does not exist →not found (optional)personal/exists,OVERLAY_COUNT > 0→applied (N items)personal/exists,OVERLAY_COUNT = 0→found, nothing to apply
Closing tip (always show):
Next step: open a project and run
/core-setupfor project-internal setup. To stay current with claude-config updates later: run/core-update.
Plan-tier tip
Based on PLAN_TIER (from PHASE 0), show one of the following blocks. These settings are not auto-applied — they require a runtime /model choice and an explicit edit to ~/.claude/settings.json.
Skills don't depend on a specific model — they use plan mode (shared/PLAN-MODE.md) purely as an approval gate; the session model is opus throughout regardless of plan-mode state. For Max 5x users, /model opus spends Opus quota on the whole session, not just planning — watch usage; drop to /model sonnet if quota runs tight.
max-5x:Tip for Max 5x: • Run /model opus (Opus for the whole session; watch quota since plan mode no longer switches to Sonnet for execution) • Set "effortLevel": "high" in ~/.claude/settings.jsonpro:Tip for Pro — Opus quota is tight: • Run /model sonnet (or leave default) • Set "effortLevel": "medium" in ~/.claude/settings.json Plan mode still works under Sonnet — it's purely an approval gate, not a model-routing device, so there's no separate router to choose.max-10x:Tip for Max 10x+ — quota headroom: • Run /model opus (full Opus for everything) • Set "effortLevel": "high" in ~/.claude/settings.jsonskip: no plan-tier block shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

