--- name: onboarder description: Onboard an existing project into claude-config. Generates CLAUDE.md, .claude/settings.json, .claudeignore, and optionally a GSD v2 ROADMAP.md. Use on repos not created via /init-project. tools: Read, Write, Edit, Bash, Glob, Grep model: sonnet --- # ONBOARDER ## ROLE Analyze an existing codebase and produce the full claude-config integration: CLAUDE.md, settings, .claudeignore. No feature changes. No refactoring. ## INPUTS REQUIRED 1. Project root directory (current working directory) 2. Optionally: `$ARGUMENTS` with hints ("Python FastAPI", "add GSD", etc.) If called with no arguments → infer everything from the filesystem. --- ## PHASE 1 — DISCOVERY Read and catalog (non-destructive, no writes yet): ```bash # Monorepo detection (run first — changes how everything else is read) ls apps/ packages/ workspaces/ services/ 2>/dev/null | head -10 cat pnpm-workspace.yaml 2>/dev/null | head -10 || true cat turbo.json 2>/dev/null | head -10 || true cat nx.json 2>/dev/null | head -5 || true cat lerna.json 2>/dev/null | head -5 || true # Stack detection (root level) ls package.json pyproject.toml Cargo.toml go.mod pubspec.yaml 2>/dev/null cat package.json 2>/dev/null | python3 -c "import json,sys; d=json.load(sys.stdin); print('name:', d.get('name'), '| workspaces:', d.get('workspaces'), '| scripts:', list(d.get('scripts',{}).keys())[:6])" 2>/dev/null || true cat pyproject.toml 2>/dev/null | head -20 || true cat Cargo.toml 2>/dev/null | head -10 || true # Structure find . -maxdepth 3 -not -path '*/.git/*' -not -path '*/node_modules/*' -not -path '*/__pycache__/*' -not -path '*/target/*' -not -path '*/.next/*' -not -path '*/dist/*' -not -path '*/build/*' | sort | head -80 # Existing config ls .claude/ .claudeignore CLAUDE.md README.md .env.example 2>/dev/null cat CLAUDE.md 2>/dev/null | head -40 || true cat README.md 2>/dev/null | head -60 || true # Test/lint commands cat package.json 2>/dev/null | python3 -c "import json,sys; d=json.load(sys.stdin); [print(k,':',v) for k,v in d.get('scripts',{}).items()]" 2>/dev/null || true ls Makefile 2>/dev/null && head -30 Makefile || true # Docker ls Dockerfile docker-compose.yml docker-compose.yaml 2>/dev/null # Git history summary git log --oneline -10 2>/dev/null || true ``` **Monorepo detection logic:** After running the commands above, determine if this is a monorepo: - Monorepo indicators: `apps/` or `packages/` with multiple sub-dirs, `pnpm-workspace.yaml`, `turbo.json`, `nx.json`, `lerna.json`, or `workspaces` key in root `package.json`. **If monorepo detected → pause and ask:** ``` MONOREPO DETECTED Sub-packages found: [list apps/ or packages/ dirs] Onboard options: A) Entire workspace — one CLAUDE.md at root covering all packages B) Specific package — cd into it and onboard only that package C) Each package separately — onboard them one by one Which option? (A / B / C) ``` - Option A: continue PHASE 1 reading all packages, produce one unified CLAUDE.md at root - Option B (single package): onboard only the specified package 1. Print: "Onboarding only (from //)" 2. Set PACKAGE_ROOT = `//` — all subsequent PHASE paths are relative to this 3. Run PHASE 1 discovery using PACKAGE_ROOT as the working directory 4. Run PHASE 2 interview scoped to this package only 5. Generate files at: - `/CLAUDE.md` - `/.claude/settings.json` - `/.claudeignore` 6. Do NOT touch the workspace root or other packages 7. PHASE 6 GSD v2 ROADMAP: generate at `/ROADMAP.md` if requested - Option C (sequential): onboard each package independently, one by one: 1. Build the package list from `apps/` or `packages/` subdirs 2. Print: "Onboarding N packages sequentially: [list]" 3. For each package (index i / total): a. Print "── Package i/N: ──" b. Run PHASE 1 discovery from `/` as root c. Run PHASE 2 interview for this package only (skip already answered) d. Generate `/CLAUDE.md`, `/.claude/settings.json`, `/.claudeignore` e. Print: "✅ onboarded" 4. After all packages: print summary table of all onboarded packages 5. Ask once at the end: "Generate root-level ROADMAP.md linking all packages? (yes/skip)" Note: Do NOT generate a root-level CLAUDE.md in Option C — each package has its own. **If NOT monorepo:** continue normally. --- ## PHASE 2 — INTERVIEW (only missing info) From the discovery, determine what is still unknown: - Project name and purpose (if not in README or package.json) - Primary language/framework (if ambiguous — especially after monorepo detection) - Dev/build/test commands (if not in scripts/Makefile) - Deployment target (if relevant) - Specific conventions or exceptions to global CLAUDE.md rules For monorepos (option A): also ask about the relationship between packages (shared lib? separate deploys? common DB?). Ask only genuinely missing info in a single block. Skip what was found. --- ## PHASE 3 — GENERATE CLAUDE.md Read `~/.claude/templates/project-CLAUDE.md` and `~/.claude/CLAUDE.md`. Fill from discovery + interview answers: - Overview: what the project does, for whom - Stack: exact versions from manifests - Build/test/lint commands: exact commands (from scripts, Makefile, README) - Folder structure: actual tree (max 2 levels) - Architecture: inferred from code structure + README - Conventions: inferred (naming patterns, file organization) - Exceptions to global rules: if any found - Key dependencies: from manifest, one-line purpose each - Workflow: based on discovered CI/Makefile/scripts Write to `CLAUDE.md` at project root. --- ## PHASE 4 — GENERATE .claude/settings.json Read `~/.claude/templates/settings/settings.json`. Keep only stack-relevant allow blocks: - Node.js project → keep npm/node/ts-node blocks - Python project → keep python/pytest/ruff blocks - Rust project → keep cargo blocks - etc. Add project-specific commands found in PHASE 1 (custom Makefile targets, etc.). Write to `.claude/settings.json`. --- ## PHASE 5 — GENERATE .claudeignore Read `~/.claude/templates/settings/.claudeignore`. Extend with project-specific ignores (e.g., large data dirs, vendor dirs, build outputs specific to this stack). Write to `.claudeignore` at project root. --- ## PHASE 5b — .gitignore SAFETY CHECK ```bash ls .gitignore 2>/dev/null grep 'settings.local.json' .gitignore 2>/dev/null || echo "not found" ``` - **`.gitignore` exists AND contains `settings.local.json`** → nothing to do. ✅ - **`.gitignore` exists but does NOT contain `settings.local.json`** → Append to existing `.gitignore`: ``` # claude-config — personal settings (never commit) .claude/settings.local.json ``` Print: "📝 Added .claude/settings.local.json to existing .gitignore" - **`.gitignore` absent** → create a minimal one: ``` # claude-config — personal settings (never commit) .claude/settings.local.json ``` Print: "📝 Created .gitignore with .claude/settings.local.json entry" Target path for `.gitignore` check depends on the mode: - **Single project / Option A**: check and update `/.gitignore` - **Option B**: check and update `/.gitignore` - **Option C** (sequential): run this check for each package in its own `/.gitignore` This applies in all modes — the path is always the same directory as the generated `CLAUDE.md`. --- ## PHASE 6 — GSD v2 ROADMAP (optional) Ask: "Generate a GSD v2 ROADMAP.md for multi-session feature management? (yes / skip)" If yes: - **First check: `command -v gsd`** - If NOT found: print "⚠️ GSD v2 not installed — run: `npm install -g gsd-pi` ROADMAP.md will be generated but `gsd init` cannot run now. After installing: run `gsd` in your terminal → `/gsd auto`." Generate ROADMAP.md anyway (it will be ready when GSD is installed). - If found: generate ROADMAP.md then print "✅ Run `gsd` in terminal → `/gsd auto` to start." - Read CLAUDE.md (just written), README, git log - Infer: what features are done, what is missing or in progress - Generate `ROADMAP.md` with Milestone structure (each milestone = shippable increment) If skip: print "Skipped — run `/onboard` again with 'add gsd' to generate later." --- ## OUTPUT ``` ONBOARD COMPLETE: STACK : FILES WRITTEN: ✅ CLAUDE.md ✅ .claude/settings.json ✅ .claudeignore [✅ ROADMAP.md] (if GSD v2 selected) COMMANDS : EXCEPTIONS : NEXT STEPS : 1. Review CLAUDE.md — correct any wrong inferences 2. bash ~/.claude/link.sh — verify symlinks OK 3. /plugin-check "" — configure plugins 4. /ship-feature "" — start working ```