Audience: Claude Code (the agent), running with read/write access to
the user's ~/.claude/ directory.
The user has cloned claude-code-devkit and wants you to install it into
their global Claude Code profile. Follow the steps below carefully. None
of them are destructive — every overwrite is gated on the user's
existing content being inspected first.
- Confirm the working directory is the root of
claude-code-devkit(look forhooks/,skills/,agents/,SETUP.md). - Confirm Claude Code is installed:
command -v claude && claude --version
- Decide which
CLAUDE_HOMEthe user wants the kit installed into. Default:~/.claude. If the user runs multiple profiles (e.g.~/.claudefor personal +~/.claude-workfor work), ask which one and use it as$DESTbelow. Otherwise just use~/.claude. - Resolve
$DESTto an absolute path. Confirm$DESTexists (it should — Claude Code creates it on first run).
For each file in hooks/:
- Read the source file.
- Read
$DEST/hooks/<name>if it exists. If a different version is already installed, diff against the source and ask the user whether to overwrite, skip, or merge. Don't silently overwrite a pre-existing hook the user may have customized. - Copy the source to
$DEST/hooks/<name>andchmod +xit.
The 6 hooks:
| Hook | Matcher | What it does |
|---|---|---|
block-uv-pip.sh |
PreToolUse / Bash | Blocks uv pip install / uv pip uninstall (forces uv add/uv remove for pyproject.toml reproducibility) |
block-orchestrator-writes.sh |
PreToolUse / Bash + Edit/Write | Read-only contract for sessions with CLAUDE_ROLE=orchestrator — blocks Edit/Write and code-mutating Bash patterns (git commit/push/rebase, sed -i, etc.). Bypasses when called from a sub-agent (payload agent_id set). |
protect-paths.sh |
PreToolUse / Edit/Write/NotebookEdit | Blocks writes to sensitive paths (.env, ~/.ssh/, etc.) |
protect-state-from-rm.sh |
PreToolUse / Bash | Blocks destructive rm -rf against PR pipeline state dirs + bare ~/$HOME//tmp. Allowlists worker worktree paths. |
session-start-git-context.sh |
SessionStart | Injects git status + branch + recent commits into session start so Claude has working-tree context immediately |
second-opinion-commit-gate.sh |
PreToolUse / Bash | Runs codex review --uncommitted on every git commit. Blocks on [P0]. Skip rules: [skip-review] in commit msg, SKIP_SECOND_OPINION=1, diff > 5000 lines, WIP branch, etc. Set CODEX_PROFILE=<name> in env to pin a specific codex profile. |
For each directory under skills/:
- If
$DEST/skills/<name>/exists, ask the user before overwriting. - Otherwise copy the entire directory tree to
$DEST/skills/<name>/.
The 5 skills (each is one SKILL.md file):
pr-review-tick— Agent A (PR review daemon tick)pr-orch-tick— Agent B (PR orchestrator daemon tick)pr-defense-loop— defend a PR against external review botscommit-defense-loop— defend a commit against the gate hookcommit-quality-pipe— three-stage pre-commit quality pipeline
Copy agents/code-reviewer-opus.md to $DEST/agents/code-reviewer-opus.md.
If a file with the same name exists, diff and ask before overwriting.
Copy statusline.py to $DEST/statusline.py. Make sure python3 is on
the user's PATH (command -v python3). If not, warn the user — the
statusline won't render.
This is the most delicate step. Do not overwrite $DEST/settings.json
if it exists — merge instead.
- Read
settings.example.jsonfrom this kit. - Read
$DEST/settings.jsonif it exists; else treat as{}. - Merge per-key:
permissions.allow,permissions.ask: union (don't dedupe destructively — if the user has a more specific rule than ours, keep both)hooks.PreToolUse,hooks.SessionStart: append our hooks to any existing matcher entries; if no matcher entry exists, create one. Don't append a hook that's already registered with the samecommand.statusLine: set if absent; ask before overwriting an existing oneenabledPlugins: union (set entries totrue; don't touch ones the user has set tofalse)- top-level scalars (
effortLevel,defaultMode,tui,preferredNotifChannel, etc.): set if absent; ask before changing an existing value
- Write the merged file. Pretty-print with 2-space indent.
Ask: "Do you want the PR review pipeline? If yes I'll install the launcher script."
If yes:
- Resolve install dir:
~/.local/binif it's on PATH, else~/bin, else ask the user. - Copy
bin/claude-pr-pipeline-upto that dir,chmod +x. - Check
command -v claude-pr-pipeline-upresolves; if not, advise the user to add the install dir to PATH.
Only if the user wants the PR pipeline. Check each, report status:
command -v gh && gh auth status # GitHub CLI authenticated
command -v tmux # tmux installed
command -v flock # flock installed (util-linux)
command -v codex && codex --version # codex CLI installedFor codex: also check the user has at least one working profile in
~/.codex/config.toml. If they don't, point them at codex's docs and
note this kit doesn't prescribe a profile — they can use whatever
non-Claude reviewer they have access to (gpt-5, gpt-4o, etc).
Print to the user:
- Where you installed each artifact
- Which steps were skipped (with reason)
- The next-steps commands they can run:
claude-pr-pipeline-up --only bothto start the PR daemons in a repo- The PR daemon will create a
dry_runflag the first time — Agent B won't actually merge until the userrms it
- Where to read more:
docs/architecture.md
- Don't run
claude-pr-pipeline-upyourself as part of install. That spawns long-running tmux daemons; the user starts those when they're ready, repo-by-repo. - Don't set up systemd services or background daemons.
- Don't modify
~/.codex/config.toml. The user owns their codex profile setup. - Don't try to install missing system packages (
tmux,jq,flock, etc.) — just report what's missing and let the user install via their package manager. - Don't seed
$DEST/scheduled_tasks.jsonor anything the user's cron system depends on. The PR daemons set up their own cron on first tick.