A starter ~/.claude/ config for Claude Code with:
- Anti-degradation defaults —
effortLevel: "high", max thinking tokens, no adaptive thinking — to keep model quality up. - Two-stage auto-compact survival — early-warning hooks and a snapshot/restore pair so you don't lose your working memory when context auto-compacts.
- Generic statusline — model, directory, and a colored context-usage bar (green → yellow → orange → blinking red with a 💀 at 80%+).
- A
CLAUDE.mdtemplate — global rules with seven concrete anti-degradation principles, plus optional sections you can uncomment for a per-project working-memory pattern (.planning/CURRENT.md), GSD, gstack, ralph-loop, or aggressive auto-commit.
No secrets, no transcripts, no project-specific personal config — fork or copy and adjust to taste.
.
├── CLAUDE.md # global rules — copy to ~/.claude/CLAUDE.md
├── settings.json # config + hook wiring — copy to ~/.claude/settings.json
├── hooks/
│ ├── auto-compact-nudge.js # PostToolUse: 2-stage warning before auto-compact
│ ├── pre-compact-snapshot.js # PreCompact: dumps git + transcript tail
│ ├── post-compact-restore.js # SessionStart(compact): tells the model to read the snapshot
│ ├── session-context-hint.js # SessionStart: surfaces .planning/CURRENT.md (optional pattern)
│ ├── context-statusline.js # statusline + bridge file consumed by auto-compact-nudge
│ ├── auto-backup.js # Stop: spawns the backup worker (no-op without CLAUDE_BACKUP_REPO)
│ ├── auto-backup-worker.js # Stop worker: mirrors ~/.claude/ subset to a private git clone
│ └── auto-continue.js # Stop: overnight auto-continue (no-op without auto-continue.flag)
├── .gitattributes # forces LF line endings (shebangs need them on macOS/Linux)
├── .gitignore
├── LICENSE # MIT
└── README.md
The seven hooks are independent of any plugin (no GSD, gstack, or
ralph-loop dependencies). They use only Node's built-in modules
(fs, path, os, child_process).
- Claude Code installed and working.
- Node.js on
PATH(for the hooks). - Anthropic plan that supports
effortLevel: "high"— if your plan only allowsmedium, drop theeffortLevelfield fromsettings.json(the rest still works). - Extended thinking access —
MAX_THINKING_TOKENS=128000andalwaysThinkingEnabled: truerequire a plan that exposes the extended-thinking budget. Without it those keys are silently ignored; no harm, just no benefit. Drop them or lower the value to match your plan's ceiling.
Backup first. If you already have a
~/.claude/CLAUDE.mdor~/.claude/settings.json, copy them aside before overwriting.
macOS / Linux / Git Bash on Windows:
mkdir -p ~/.claude/hooks
cp CLAUDE.md ~/.claude/CLAUDE.md
cp settings.json ~/.claude/settings.json
cp hooks/*.js ~/.claude/hooks/The hooks are invoked by Claude Code as
node "path/to/hook.js"(seesettings.json), so the executable bit and the#!/usr/bin/env nodeshebang are decorative — nochmod +xneeded.
PowerShell (Windows):
$claude = "$env:USERPROFILE\.claude"
New-Item -ItemType Directory -Force -Path "$claude\hooks" | Out-Null
Copy-Item CLAUDE.md "$claude\CLAUDE.md" -Force
Copy-Item settings.json "$claude\settings.json" -Force
Copy-Item hooks\*.js "$claude\hooks\" -ForceThe hook commands in settings.json reference <CLAUDE_HOME> as a
placeholder — Claude Code does not expand ~ in hook command strings,
so the path must be absolute. Replace it with your real ~/.claude
path:
macOS / Linux:
sed -i.bak "s|<CLAUDE_HOME>|$HOME/.claude|g" ~/.claude/settings.json
rm ~/.claude/settings.json.bakGit Bash on Windows:
HOME_FWD=$(cygpath -m "$HOME") # forward-slash form, e.g. C:/Users/you
sed -i "s|<CLAUDE_HOME>|$HOME_FWD/.claude|g" ~/.claude/settings.jsonPowerShell (Windows PowerShell 5.1 and PowerShell 7+):
$file = "$env:USERPROFILE\.claude\settings.json"
$path = ("$env:USERPROFILE\.claude") -replace '\\', '/'
$utf8 = [System.Text.UTF8Encoding]::new($false) # UTF-8, no BOM
$body = [System.IO.File]::ReadAllText($file, $utf8) -replace '<CLAUDE_HOME>', $path
[System.IO.File]::WriteAllText($file, $body, $utf8)Why
[System.IO.File]instead ofSet-Content? Windows PowerShell 5.1'sSet-Contentwrites in the system default encoding (ANSI on most Windows installs), which corrupts the JSON if your$USERPROFILEcontains non-ASCII characters.[System.IO.File]writes UTF-8 without a BOM on both 5.1 and 7+ regardless of locale.
Start a new Claude Code session and check:
- The statusline shows
Claude │ <dirname> │ ░░░░░░░░░░ 0%(it grows as context fills, going green → yellow → orange → blinking red with a 💀 as the bar approaches 100%). - After a few tool calls, a bridge file
claude-ctx-<session-id>.jsonappears in your system temp directory. The nudge hook reads it to decide when to warn you about the upcoming auto-compact:- Windows:
%TEMP%\claude-ctx-<sid>.json(typicallyC:\Users\<you>\AppData\Local\Temp\) - macOS:
$TMPDIR/claude-ctx-<sid>.json(typically/var/folders/.../T/) - Linux:
/tmp/claude-ctx-<sid>.json
- Windows:
If something is wrong, look at ~/.claude/debug/ for hook errors.
Open it and skim the seven anti-degradation rules — adjust language, remove what doesn't fit your workflow. Optional sections at the bottom are commented out; uncomment whichever apply to you:
-
Per-project working memory (
.planning/CURRENT.md) — a workflow pattern, not a tool install. Keep one short file per repo with current status, open files, and the next concrete step. Survives auto-compact, session crashes, and power loss because it lives in the repo rather than in conversation context. Pairs naturally with the auto-compact survival hooks shipped here. Adopt it if you switch between several projects, or if your environment is unreliable (laptop with bad battery, region with power outages); skip it for one-off scripts.Wired up with
session-context-hint.js(SessionStart hook): when you launch Claude inside a project that has.planning/CURRENT.md, the hook injects a one-line "read this file first" instruction; when you launch outside any project, it lists active projects sorted by recency. Silent no-op if you don't use the pattern, so it's safe to leave wired up. Configure where the hook looks for projects with theCLAUDE_PROJECTS_ROOTenv var (default:~/Projects) — set it insettings.json'senvblock:"env": { "CLAUDE_PROJECTS_ROOT": "C:/Projects" }
-
GSD, gstack, ralph-loop — third-party plugin/skill packs. Uncomment the matching block only if you've installed the tool.
-
Aggressive auto-commit — overrides the default "don't commit unless asked". Use it if losing in-flight work is costly in your setup.
Cost trade-off — read this before you copy. The thinking-related defaults here (
alwaysThinkingEnabled: true+CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1+MAX_THINKING_TOKENS=128000) are tuned for hard engineering work — multi-file refactors, debugging, architecture, anything where you'd rather Claude take 60 seconds and get it right than 5 seconds and confidently miss the bug. The thinking-token spend is justified there.The downside: every turn — including trivial ones like "open this file" or "what does this command do" — also walks up to the 128K thinking ceiling. On a small Anthropic plan, or in a workflow dominated by short Q&A and quick lookups, this preset will feel expensive. If that's you, drop
alwaysThinkingEnabled(and optionallyCLAUDE_CODE_DISABLE_ADAPTIVE_THINKING) and let the model scale its thinking budget adaptively — you keep the quality ceiling for hard turns and skip the burn on easy ones.
Things you may want to change:
effortLevel—"high"is the recommended ceiling. Drop or lower it if your plan doesn't support it.alwaysThinkingEnabled— whentrue, every turn enters extended thinking, even trivial ones. Set tofalse(or remove) if you do a lot of short Q&A; you keepeffortLevel: "high"for hard turns and skip the thinking budget on easy ones.theme—"dark"/"light"/ etc.MAX_THINKING_TOKENS—128000is the ceiling, not the spend per turn. With adaptive thinking enabled the model usually uses far less; with adaptive thinking disabled (default below) it walks closer to the ceiling on every turn. Lower it if you want a hard cap.CLAUDE_CODE_DISABLE_1M_CONTEXT=1— keeps you on the standard ~200K window. The 1M-token beta is available, but empirically the model degrades noticeably on it (loses long-range coherence, gets sloppy with file paths). Remove only if you really need >200K and accept the quality drop.CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1— forces the fullMAX_THINKING_TOKENSbudget on every turn instead of letting the system shrink it for easy questions. Pair withalwaysThinkingEnabled: truefor maximum quality at maximum cost; remove both for a cheaper "think only when it actually helps" mode.
This template intentionally ships only the seven custom hooks. The plugins and skill packs below pair well with the anti-degradation defaults — install whichever you want, independently from this template. Each is maintained by its own author and stays fresh on its own release cycle.
Why not bundle them? Bundling third-party code freezes it at the version I happened to copy and creates licence/attribution ambiguity. A pointer keeps you on the upstream.
A meta-prompting / context-engineering system. Adds 80+ /gsd:*
slash commands (planner, executor, debugger, verifier, etc.) and
runs heavy work in fresh 200K sub-agent contexts so your main
session stays lean.
- Source: https://github.com/gsd-build/get-shit-done
- Author: TÂCHES (Lex Christopherson / glittercowboy)
- Install: see the project README — current versions auto-detect Claude Code's skills directory.
If you install GSD, uncomment the ## GSD block at the bottom
of CLAUDE.md.
Browser-driven QA, design review, eng review, security review,
release tooling. The /browse skill is a fast headless-browser
replacement for mcp__claude-in-chrome__*.
- Source: https://github.com/garrytan/gstack
- Author: Garry Tan (Y Combinator)
- License: MIT
- Install: follow the project README (one-paste install).
Heads-up on naming: gstack commands are flat-namespace (
/review,/qa,/ship,/cso,/freeze, …) — they don't carry agstack:prefix the way/gsd:*and/ralph-loop:*do. If you install multiple skill packs, this is the one whose commands are easiest to mistake for built-ins.
If you install gstack, uncomment the ## gstack block at the
bottom of CLAUDE.md — it lists all ~30 commands shipped with the
pack as of this writing (subject to change upstream).
Runs a /ralph-loop:ralph-loop command that loops Claude on a
target until a stop condition fires. From the official Anthropic
plugin marketplace.
- Source: https://github.com/anthropics/claude-plugins-official
- Install (inside Claude Code):
/plugin install ralph-loop@claude-plugins-official
If you install it, uncomment the ## ralph-loop block in
CLAUDE.md.
Talk to a running Chrome (or AdsPower / Dolphin / AgentX profile) over CDP without the Playwright MCP overhead. Useful for browser automation when you want full control of the session.
-
Fork with AgentX support: https://github.com/cryptoyasenka/chrome-cdp-skill
-
Install: clone somewhere, then link into
~/.claude/skills/.macOS / Linux / Git Bash on Windows:
git clone https://github.com/pasky/chrome-cdp-skill.git ln -s "$PWD/chrome-cdp-skill/skills/chrome-cdp" ~/.claude/skills/chrome-cdp
PowerShell (Windows) —
ln -srequires Developer Mode or admin; a directory junction works without either:git clone https://github.com/pasky/chrome-cdp-skill.git $src = Join-Path $PWD "chrome-cdp-skill\skills\chrome-cdp" $dst = "$env:USERPROFILE\.claude\skills\chrome-cdp" New-Item -ItemType Directory -Force -Path (Split-Path $dst) | Out-Null cmd /c mklink /J "$dst" "$src"
Add hooks that play a system sound when Claude finishes a turn or asks for input.
Merge, don't replace. The shipped
settings.jsonalready has aStoparray (it runsauto-backup.js). Don't paste these snippets as-is — that creates a duplicateStopkey (invalid JSON) or overwrites the backup hook. Instead, add another{ "hooks": [...] }entry inside the existingStoparray, and add theNotificationarray as a sibling ofStop.
Windows (PowerShell sounds):
"Stop": [{
"hooks": [{
"type": "command",
"command": "powershell -NoProfile -WindowStyle Hidden -Command \"[System.Media.SystemSounds]::Asterisk.Play()\"",
"timeout": 3
}]
}],
"Notification": [{
"hooks": [{
"type": "command",
"command": "powershell -NoProfile -WindowStyle Hidden -Command \"[System.Media.SystemSounds]::Exclamation.Play()\"",
"timeout": 3
}]
}]macOS:
"Stop": [{
"hooks": [{
"type": "command",
"command": "afplay /System/Library/Sounds/Glass.aiff",
"timeout": 3
}]
}],
"Notification": [{
"hooks": [{
"type": "command",
"command": "afplay /System/Library/Sounds/Ping.aiff",
"timeout": 3
}]
}]Linux (PulseAudio / paplay):
"Stop": [{
"hooks": [{
"type": "command",
"command": "paplay /usr/share/sounds/freedesktop/stereo/complete.oga",
"timeout": 3
}]
}]Two backup strategies live in this README and they're independent — pick one, or run both:
- This section — automatic, hook-driven, mirrors a curated subset of
~/.claude/into a separate private git clone on every Stop event.- "Backing up your live
~/.claude/" — manual, git-init inside~/.claude/itself with a whitelist.gitignore. You commit by hand whenever you feel like it.The auto-backup is "fire and forget"; the in-place version gives you a single repo that is your live config. Either one survives a disk failure if you push.
auto-backup.js + auto-backup-worker.js mirror a curated subset of
your ~/.claude/ (CLAUDE.md, settings.json, hooks/, agents/, commands/,
projects/*/memory/) into a separate git clone, commit any real changes,
and push them. The Stop-hook entry script spawns the worker as a
detached background process, so the user-facing turn is never blocked
by the backup.
Useful if your storage isn't trusted (laptop with bad disk, region with power outages, frequent OS reinstalls), or if you want a chronological audit log of how your config and auto-memory evolved over time.
Without CLAUDE_BACKUP_REPO set, both scripts are silent no-ops —
they're safe to leave wired up in settings.json even if you don't
adopt the pattern.
-
Create a private GitHub repo (e.g.
<you>/claude-config-backup) and clone it locally somewhere outside~/.claude/:gh repo create <you>/claude-config-backup --private git clone git@github.com:<you>/claude-config-backup.git ~/claude-config-backup
-
Add a
.gitattributesto neutralize CRLF noise on Windows so the worker doesn't see phantom diffs every session:* text=auto eol=lfCommit and push it before enabling the hook.
-
Set
CLAUDE_BACKUP_REPOinsettings.json'senvblock so the worker knows where to mirror. Use the absolute path to the local clone:"env": { "CLAUDE_BACKUP_REPO": "/Users/you/claude-config-backup" }
On Windows: forward slashes work fine (
"C:/Users/you/claude-config-backup"). -
Configure global git identity if you haven't already — the worker uses whatever's in
~/.gitconfig:git config --global user.name "Your Name" git config --global user.email "you@example.com"
-
Initial commit — push at least one commit (the
.gitattributesfrom step 2 counts) so the local clone has an upstream-tracking branch the worker can push to. The worker calls plaingit pushwith no refspec, so whatever branch your initial clone landed on (main,master, or anything else) is what gets pushed.
Whitelist (everything else is never copied):
CLAUDE.md,settings.jsonhooks/,agents/,commands/— minusnode_modules/,*.log,*.lockprojects/*/memory/— auto-memory across all project slugs (the slugprojects/<C--Users-you>/memory/is keyed off your home directory, so it varies per machine — the worker discovers it dynamically)
Sensitive paths NOT mirrored: .credentials.json, .claude.json,
.mcp.json, settings.local.json, conversation transcripts (*.jsonl),
snapshots/, plugins/, skills/, debug/, telemetry/,
paste-cache/, etc.
If you want to add new categories of file to the backup, edit
auto-backup-worker.js directly.
Note: only the categories above are mirrored — root-level files other
than CLAUDE.md/settings.json are not copied. If you keep a helper
script at ~/.claude/ root (e.g. a Windows auto-continue.ps1 with
ac-on/ac-off/ac-status), back it up by adding both a
copyFile(...) line in auto-backup-worker.js and a matching
!your-file allow in your backup .gitignore. The whitelist
.gitignore denies everything by default, so a copyFile without the
paired !allow is silently dropped by git add and never reaches the
backup.
Create the file ~/.claude/.no-auto-backup to disable the hook
without editing settings.json. Delete it to re-enable.
The worker writes to ~/.claude/hooks/auto-backup.log. Each line is
either pushed: <shortstat> (success) or push failed (will retry next session): <git error> (push couldn't reach the remote).
If the local clone diverges from origin (rare — typically only if
you push to the same backup repo from elsewhere, like a different
machine using the same hook), every subsequent push fails as
non-fast-forward. Reconcile in the backup clone — substitute your
default branch name for <branch> (usually main, sometimes
master):
cd "$CLAUDE_BACKUP_REPO"
git fetch origin
git reset --hard origin/<branch>This discards local auto-commits not on origin — safe because their
file content is already mirrored from ~/.claude/, the next session's
backup will recreate any missing changes.
The combined repo this template lives in (claude-config-template)
gives you the bones; your private backup repo gives you the contents.
Migration:
-
Clone your backup repo over a fresh
~/.claude/:git clone git@github.com:<you>/claude-config-backup.git ~/.claude
-
Re-do anything outside the whitelist:
- Run
claudeand re-authenticate (recreates.credentials.json). - Re-install plugins inside Claude Code (
/plugin install ...). - Re-install skills (junctions / clones outside
~/.claude/). - Re-install MCP servers if you use them.
- Run
-
Re-point machine-specific
envvalues insettings.json— these are absolute paths from the old machine, baked in at substitution time, so they almost certainly don't exist on the new one:CLAUDE_BACKUP_REPO→ the new local clone path of the backup repoCLAUDE_PROJECTS_ROOT→ the new local projects directory (only present if you use thesession-context-hint.jsworkflow)- Any hook paths still reading
<CLAUDE_HOME>/...— if your home directory has a different absolute path on the new machine, redo the substitution from step 2 of the install section.
auto-continue.js is a Stop hook that lets Claude keep working unattended
(e.g. overnight) instead of stopping to wait for input. It is opt-in and
silent: with no flag file present it exits in milliseconds and does nothing,
so it is safe to leave wired in settings.json.
# turn ON for any session
touch ~/.claude/auto-continue.flag
# bind to ONE session only: put that session_id inside the flag file instead
# turn OFF
rm ~/.claude/auto-continue.flag(Windows PowerShell users: a convenience auto-continue.ps1 with ac-on /
ac-off / ac-status helpers is not shipped here — it is personal/OS-specific.
The flag-file mechanism above is all the hook needs and works everywhere.)
MAX_ITERATIONS = 100hard cap per session.- Context floor: if a
claude-ctx-<sid>.jsonbridge file (written by the statusline hook) reports remaining context below 22%, it yields to auto-compact instead of blocking. - Verified done-marker. When Claude ends a turn whose final line is exactly
AUTO_CONTINUE: DONE, the hook spawns an independentclaude -pverifier that reads the transcript and ratifies or rejects the claim. A rejected claim feeds the reason back and keeps working — this closes the self-report hole where an agent stops on an unproven "done". - Delete the flag at any time.
The verifier is a real headless claude call (Haiku by default), so it costs
tokens — but it only runs when the marker is actually emitted, never on a
normal continue turn (detection is role-aware: only the last assistant turn's
standalone marker line counts; the hook's own injected text, post-compact
summaries and tool output are ignored). The Stop hook timeout in
settings.json is 150 s on purpose: the verifier needs 60–120 s, and a
shorter timeout would kill it before it returns. If the verifier is
unavailable it fails safe (trusts the marker). A filesystem lock plus an
AC_EVAL env guard prevent the verifier's own session from recursing.
tests/auto-continue.test.js covers the detection logic and every
false-positive source — run node tests/auto-continue.test.js.
Claude Code's built-in auto-compact fires automatically at ~16.5% native context remaining (≈100% on the displayed bar). When it does, the model loses its in-flight working memory: open files, decisions made but not yet on disk, the immediate next step. The hooks in this config minimize that loss in three steps:
- Warning (
auto-compact-nudge.js, PostToolUse). At 35% remaining ("PREP") it asks Claude to write a snapshot itself — Claude knows what's in flight, the hook doesn't. At 26% remaining ("CRITICAL") it makes that snapshot the next mandatory tool call. - Hook fallback (
pre-compact-snapshot.js, PreCompact). Right before built-in auto-compact runs, it dumpsgit status, recent commits, and the last 30 transcript entries to~/.claude/snapshots/pre-compact-<session>.md. This is external state only — it can't capture in-memory plans. - Restore (
post-compact-restore.js, SessionStart withmatcher: "compact"). After auto-compact, it injects an instruction telling Claude to read whichever snapshot exists, preferring Claude's own prep snapshot over the automated one.
The bridge file written by context-statusline.js is what makes the
nudge possible — it's how the PostToolUse hook learns the current
remaining-percentage, which Claude Code does not pass to that hook
directly.
If you want to keep a sanitized backup of your working ~/.claude/ in
git (not just this template), don't reuse this repo's .gitignore —
your live directory contains OAuth tokens (.credentials.json), API
keys (.claude.json, .mcp.json), and full conversation transcripts
(*.jsonl). Use a whitelist strategy: deny everything, then
explicitly allow safe files. Example:
# Deny everything
/*
!.gitignore
!README.md
!CLAUDE.md
!settings.json
!hooks/
hooks/**/node_modules/
!agents/
!commands/
# Optional: include auto-memory but never sessions
!projects/
projects/*
!projects/*/
projects/*/*
!projects/*/memory/
!projects/*/memory/**
# Belt-and-suspenders: explicit denylist of known-sensitive files
.credentials.json
.claude.json
.mcp.json
settings.local.json
history.jsonl
**/*.jsonl
sessions/
shell-snapshots/
file-history/
todos/
tasks/
telemetry/
session-env/
paste-cache/
cache/
debug/
backups/
plugins/
skills/After applying, run git status and verify nothing sensitive is
staged before your first commit.
MIT — do whatever you like.