Make any legacy project Claude-Code-ready — without forcing AI tooling on your teammates.
📖 Read this in other languages: English · 简体中文
/onboard is a Claude Code Skill that walks a legacy project through a structured 10-phase onboarding protocol — discovering stacks, generating a token-compact CLAUDE.md, configuring guard hooks, aligning CI with local commands — all offer-only, never auto-installing system tools. Default --local-only mode writes zero project files; team members pulling the branch see nothing.
Current version: v3.2.0.
| Problem | What /onboard does |
|---|---|
| Cold-starting Claude Code on a legacy repo takes hours of project archaeology | 10-phase protocol auto-discovers stacks, lockfiles, CI, forbidden zones, behavioral conventions (8-dimension deep analysis in Phase 1.7) |
A 5KB CLAUDE.md chews 5K tokens every turn |
Extraction-first template, hard token ceiling at 5000 (soft cap 2500), empty sections omitted entirely |
| AI-tool adoption shouldn't pollute the team's repo by default | --local-only is the default — all outputs land in .claude/local-only/ + .git/info/exclude; zero .gitignore change, zero commits |
Letting an LLM brew install or npm i whatever it wants is a recipe for disaster |
Iron Law 7 + meta-rule 19: every system install is offer-only, every project dependency change is batch-AUTH'd by a human |
--uninstall should be possible |
v2.8+ marker/manifest/snapshot protocol makes every PROJECT write reversible (Iron-level reversibility) |
- Multi-language stack support (v2.4) — first-class for repos like TypeScript frontend + Python backend + ML pipeline; Phase 1 detects each stack, Phase 4 applies lint/format/typecheck per-stack, Phase 7 hook dispatches by file extension via
stacks.json. - Two modes —
--local-only(default, zero team pollution) and--share(opt-in, OUTPUT files committed). - 4 guard hooks wired via
.claude/settings.json—guard-bash(deny dangerous shell),guard-edit(forbidden-zone protection),post-edit-check(multi-stack format check),stop-verify(lint + typecheck on touched files). - Doctor mode (
--doctor, v2.5+) — D1-D15 health checks, no writes, reportshealthy | drifted | broken. - Reversible by design (v2.8+) — marker + manifest + snapshot make
--uninstallprecise;=skill(L1 only) and=all(L1+L2+L3) modes (v2.11+). - Plugin marketplace standard (v2.9+) —
/plugin marketplace add sdsrss/onboardworks natively. - Lazy-loaded spec (v3.0+) — SKILL.md keeps a compact entry; consumer Claude reads
phases/phase-7.md/phases/uninstall.md/references/state-schema.mdonly when entering those scopes (meta-rule 27). - Compact plan output (v3.1+) — Phase 2 / 2.5 cards default to Top-N highlights (Top 3 for plan, Top 1-2 per install category), remainder folded as
+N more;--verbose-planrestores full listing. Phase 0 now emits a first-run session-auth tip. Skill description expanded with English trigger surface for better discovery. - Plugin matrix sub-file (v3.2+) — 15-plugin recommendation matrix extracted to
references/recommendations.md; SKILL.md keeps a 7-bullet sentinel summary; consumer Claude Reads the sub-file when entering Phase 2.5 (meta-rule 27 enumeration expanded to 4 sub-files). 3/3 Opus subagent dogfood verified the lazy-load contract.
/plugin marketplace add sdsrss/onboard
/plugin install onboard
Upgrade:
/plugin marketplace update onboard
/plugin update onboard
curl -sSL https://raw.githubusercontent.com/sdsrss/onboard/main/install.sh | bash # install
curl -sSL https://raw.githubusercontent.com/sdsrss/onboard/main/install.sh | bash -s -- update
curl -sSL https://raw.githubusercontent.com/sdsrss/onboard/main/install.sh | bash -s -- doctor
curl -sSL https://raw.githubusercontent.com/sdsrss/onboard/main/install.sh | bash -s -- uninstallEnvironment overrides: ONBOARD_TARGET=project|user · ONBOARD_REPO · ONBOARD_BRANCH · ONBOARD_ALLOW_DIRTY=1 · ONBOARD_CONFIRM_UNINSTALL=yes.
The skill files live at skills/onboard/ inside the repo (Claude Code plugin convention), so a direct clone to ~/.claude/skills/onboard would nest SKILL.md two levels deep. Clone to a fresh scratch dir, then copy the skill subtree:
SRC=$(mktemp -d -t onboard-src.XXXXXX)
git clone --depth 1 https://github.com/sdsrss/onboard.git "$SRC"
mkdir -p ~/.claude/skills
cp -r "$SRC/skills/onboard" ~/.claude/skills/
chmod +x ~/.claude/skills/onboard/hooks/*.sh ~/.claude/skills/onboard/scripts/*.sh
rm -rf "$SRC"Using
mktemp -davoidsfatal: destination path … already existsif you re-run after a typo.
In a git-initialized project root:
/onboard
Claude prints an execution plan first — phase list, current mode (--local-only by default), file-change budget, size class, total ETA — then waits for your confirmation. Each phase ends with a phase card showing what was changed.
| Mode | When to use | What gets written |
|---|---|---|
--local-only (default, v2.6+) |
Personal use on a team repo · team has no AI policy yet · OSS repo where you're a contributor · trial run | CLAUDE.local.md · .claude/settings.local.json · .claude/local-only/* · .git/info/exclude markers. Zero changes to tracked files. |
--share (opt-in) |
Team has approved AI tooling · solo project where you want multi-machine sync · the team wants CLAUDE.md reviewed in PR |
CLAUDE.md (tracked) · .claude/settings.json · .claude/onboarding-logs/* · revised .gitignore · optionally opens PR / MR via host adapter (gh / glab / tea) |
Why local-only is the default: most teams have only a few AI-tool early adopters. Default-commit means one person's experiment forces tooling on the rest of the team. Default-local-only = zero team pollution risk; promote to --share after team alignment.
Mode is not silently switched: changing modes mid-project requires /onboard --update [--share|--local-only] with hard AUTH.
Full protocol in skills/onboard/SKILL.md. The 10 phases and your role at each:
| Phase | What happens | Your role |
|---|---|---|
| 0 · Preflight | git topology, host detection, tool availability | Resolve dirty tree / submodule / detached HEAD if flagged |
| 0.5 · Migration | Inherit prior --update decisions |
Skip if first run |
| 1 · Discovery | Multi-stack detection, lockfiles, CI parsing | Review the "Environment Report" |
| 1.5 · Blocking Decisions | Forbidden-zone candidates, lockfile/CI choices | Answer via enumerated DSL |
| 1.7 · Deep Analysis (v2.7) | 8-dimension behavioral profile | Approve / correct findings |
| 2 · Authorization | Touch budget, write scope | proceed safe / approve install <id> / skip <id> |
| 2.5 · Install Plan (v2.7) | dev tools · system CLIs · runtimes · plugins | Batch authorize 4 lists |
| 3 · CLAUDE.md | Extraction template, token-budget enforced | Review draft (hard cap 5000 tokens) |
| 4 · Dev & Lint | Per-stack lint / format / typecheck integration | — |
| 5 · Test | Test runner discovery + sanity | — |
| 6 · Commit & CI Gates | Pre-commit / pre-push hooks | — |
| 7 · Claude Code Hooks | 4 hooks installed via settings.json |
— |
8 · .gitignore & Verification |
Final wiring; in --share mode offers PR/MR |
— |
Run a single phase with /onboard --phase=<n>. Re-onboard with --resume (same version) or --update (cross-version migration via Phase 0.5).
Four hooks installed in .claude/settings.json (share) or .claude/settings.local.json (local-only):
| Hook | Event | Purpose |
|---|---|---|
guard-bash.sh |
PreToolUse / Bash |
Deny rm -rf /, force-push to main, curl | sh, project-defined ONBOARD_FORBIDDEN_COMMANDS regex list (v2.12.0+) |
guard-edit.sh |
PreToolUse / Edit|Write|MultiEdit |
Block edits inside ONBOARD_FORBIDDEN_PATHS (confirmed forbidden zones) |
post-edit-check.sh |
PostToolUse / Edit|Write|MultiEdit |
Log touched file + per-stack format check |
stop-verify.sh |
Stop |
Lint + typecheck on touched files per ONBOARD_STOP_MODE (light / standard / strict) |
All four follow Iron Law 15 (exit 0 + stdout JSON, never mixed) and Iron Law 19 (warn-only checks must exit 0).
Third-party hook coexistence (v2.5+): independent matcher-block strategy — onboard never overwrites existing hooks, both are listed and Claude Code's "deny-first" semantics apply.
Plugin install path note: ${CLAUDE_PLUGIN_ROOT} is ephemeral (changes every plugin update). Onboard's Phase 7 default is to invoke scripts/mirror-hooks.sh (v2.10.1+, idempotent) to mirror hooks to a stable ~/.claude/onboard-runtime/hooks/ location; settings.json references the mirror.
/onboard --doctor # D1-D15 health check, no writes
/onboard --update # cross-version migration (Phase 0.5)
/onboard --update --local-only # switch from --share back to local-only
/onboard --dry-run # preview without writing
/onboard --uninstall # remove all onboard writes from this project
/onboard --uninstall=skill # uninstall only L1 user-global skill, preserve project config
Uninstall protocol (v2.8+, three-layer model in v2.11+): =skill clears L1 user-global (~/.claude/skills/onboard/ + plugin cache + mirror), preserves project-side L2 (settings hook references) and L3 (hook scripts) via keeper-rewrite (.claude/onboard-keeper/). =all clears all three layers. Marker/manifest/snapshot make every PROJECT write reversible; users can restore-snapshot to recover the pre-onboard state.
| Platform | Status | Notes |
|---|---|---|
| Linux | First-class | — |
| macOS | First-class (v2.5+) | brew install coreutils recommended for gtimeout |
| WSL2 | First-class | Treated as Linux |
| Windows native | Not supported | Use WSL2 |
Tools: git, bash 3.2+, jq (all required — installer refuses without jq because guard hooks shell out to it; missing jq silently disables permissionDecision deny payloads) · coreutils on macOS (strongly recommended) · make (optional).
Git host adapters (Phase 8 PR/MR offer, never auto-execute): GitHub (gh), GitLab (glab), Gitea/Forgejo/Codeberg (tea); Bitbucket and unknown hosts fall back to web URLs.
After install + first run:
/hooks
Should list 4 hook configs (PreToolUse × 2, PostToolUse, Stop). Test a forbidden-zone edit to confirm guard-edit.sh denies it; test a deliberate lint error to confirm stop-verify.sh blocks the Stop event.
Run the in-repo test suite:
bash tests/run.sh
# 10 integration tests / 224 assertions / 0 fail| Symptom | Check |
|---|---|
/onboard not in command list |
SKILL.md frontmatter disable-model-invocation: true may hit issue anthropic#43875; temporarily remove or switch to Command form |
| Hooks not firing | /hooks to confirm loaded; check ${CLAUDE_PROJECT_DIR} expansion; verify ls -l .claude/skills/onboard/hooks/ shows executable |
guard-edit false positive |
Inspect ONBOARD_FORBIDDEN_PATHS env (colon-separated, no quotes, no spaces) |
stop-verify timing out |
Lower ONBOARD_STOP_MODE to light, or tune per-stack lint_timeout_sec / typecheck_timeout_sec in stacks.json (v2.12+) |
--update migration fails |
Old state backed up to .claude/onboarding-state.v<old>.json.bak; check Phase 0.5 output |
Full troubleshooting + edge cases in SKILL.md § "异常处理".
This repo evolved through 4 simulation-based stress testing rounds in the v2 series (v2.0 → v2.4 was net-line-decrease; v2.5-v2.12 added features on real-run evidence). The v3 series begins with C1 SKILL.md shallow-split (lazy-load contract). Any change should follow this pattern:
- Run current version (simulated or real)
- Number each issue (P-A, P-B, …) with Critical / High / Medium / Low severity
- Accept-or-reject each with written rationale
- Roll the accepted set into the next version
No speculative features. See CLAUDE.md for full repo-maintainer conventions (Iron Laws, meta-rules, validation commands, file-classification, multi-stack discipline).
Bug reports: capture the failing-state evidence (error message, state file, phase card) and open an issue. Evidence-driven PRs welcome.
MIT — Copyright (c) sds.
- Full protocol spec (SKILL.md) · Phase 7 hooks · Uninstall mode · State schema
- Changelog (full history; v3.2.0 = current)
- Releases
- Issues
- Claude Code documentation
- Claude Code plugins documentation