From vbw
Initializes VBW by setting up environment, scaffolding .vbw-planning directory, detecting project context from files like package.json or pyproject.toml, and bootstrapping project files.
npx claudepluginhub swt-labs/vibe-better-with-claude-code-vbw# VBW Init
<!-- Full init flow: Steps 0-4 handle environment/scaffold/hooks/mapping/summary -->
<!-- Steps 5-8 handle auto-bootstrap: detect scenario, run inference (brownfield/GSD), confirm with user, generate project files -->
## Context
Working directory:
Plugin root:
Store the plugin root path output above as `{plugin-root}` for use in script invocations below. Replace `{plugin-root}` with the literal `Plugin root` value from Context whenever a step below references a script, template, command, or reference file.
Existing state:
Project files:
Skills:
## Guard
1. **Already .../initInitializes beads issue tracking database in current directory with optional prefix (defaults to dir name). Shows DB location, prefix, workflow overview, next steps; displays stats if already set up.
/initInitializes guided UI design for dashboards, apps, and tools. Assesses intent, proposes styles with rationale, builds components, and offers to save patterns.
/initDownloads and installs/updates the platform-specific notification binary for claude-notifications plugin from GitHub into the plugin's bin directory.
/initInitializes or re-boots llmdoc/ directory structure, runs multi-themed project investigations with investigator, and generates initial stable docs via recorder.
/initInitializes AI task harness with ai/tasks/ directory for modular backlog, progress log, bootstrap script, and CLAUDE.md instructions. Supports --mode new|scan and --task-type ops|data|infra|manual.
/initScans ~/.claude/agents/ for custom agent files, lets user select which to import/register into orchestration plugin registry, updates JSON registry and documentation.
Working directory:
!`pwd`
Plugin root:
!`VBW_CACHE_ROOT="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plugins/cache/vbw-marketplace/vbw"; SESSION_KEY="${CLAUDE_SESSION_ID:-default}"; SESSION_LINK="/tmp/.vbw-plugin-root-link-${SESSION_KEY}"; R=""; if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/scripts/hook-wrapper.sh" ]; then R="${CLAUDE_PLUGIN_ROOT}"; fi; if [ -z "$R" ] && [ -f "${VBW_CACHE_ROOT}/local/scripts/hook-wrapper.sh" ]; then R="${VBW_CACHE_ROOT}/local"; fi; if [ -z "$R" ]; then V=$(find "${VBW_CACHE_ROOT}" -maxdepth 1 -mindepth 1 2>/dev/null | awk -F/ '{print $NF}' | grep -E '^[0-9]+(\.[0-9]+)*$' | sort -t. -k1,1n -k2,2n -k3,3n | tail -1); [ -n "$V" ] && [ -f "${VBW_CACHE_ROOT}/${V}/scripts/hook-wrapper.sh" ] && R="${VBW_CACHE_ROOT}/${V}"; fi; if [ -z "$R" ]; then L=$(find "${VBW_CACHE_ROOT}" -maxdepth 1 -mindepth 1 2>/dev/null | awk -F/ '{print $NF}' | sort | tail -1); [ -n "$L" ] && [ -f "${VBW_CACHE_ROOT}/${L}/scripts/hook-wrapper.sh" ] && R="${VBW_CACHE_ROOT}/${L}"; fi; if [ -z "$R" ] && [ -f "${SESSION_LINK}/scripts/hook-wrapper.sh" ]; then R="${SESSION_LINK}"; fi; if [ -z "$R" ]; then ANY_LINK=$(command find -H /tmp -maxdepth 1 -name '.vbw-plugin-root-link-*' -print 2>/dev/null | LC_ALL=C sort | while IFS= read -r link; do if [ -f "$link/scripts/hook-wrapper.sh" ]; then printf '%s\n' "$link"; break; fi; done || true); [ -n "$ANY_LINK" ] && R="$ANY_LINK"; fi; if [ -z "$R" ]; then D=$(ps axww -o args= 2>/dev/null | grep -v grep | grep -oE -- "--plugin-dir [^ ]+" | head -1); D="${D#--plugin-dir }"; [ -n "$D" ] && [ -f "$D/scripts/hook-wrapper.sh" ] && R="$D"; fi; if [ -z "$R" ] || [ ! -d "$R" ]; then echo "VBW: plugin root resolution failed" >&2; exit 1; fi; LINK="${SESSION_LINK}"; REAL_R=$(cd "$R" 2>/dev/null && pwd -P) || REAL_R="$R"; bash "$REAL_R/scripts/ensure-plugin-root-link.sh" "$LINK" "$REAL_R" >/dev/null 2>&1 || { echo "VBW: plugin root link failed" >&2; exit 1; }; echo "$LINK"`
Store the plugin root path output above as {plugin-root} for use in script invocations below. Replace {plugin-root} with the literal Plugin root value from Context whenever a step below references a script, template, command, or reference file.
Existing state:
!`ls -la .vbw-planning 2>/dev/null || echo "No .vbw-planning directory"`
Project files:
!`ls package.json pyproject.toml Cargo.toml go.mod Gemfile build.gradle pom.xml mix.exs 2>/dev/null || echo "No detected project files"`
Skills:
!`if [ -n "${CLAUDE_CONFIG_DIR:-}" ]; then _cd="$CLAUDE_CONFIG_DIR"; elif [ -d "$HOME/.config/claude-code" ]; then _cd="$HOME/.config/claude-code"; else _cd="$HOME/.claude"; fi; ls "$_cd/skills/" 2>/dev/null || echo "No global skills"`
!`ls .claude/skills/ 2>/dev/null || echo "No project skills"`
command -v jq via Bash. If missing, STOP: "VBW requires jq. Install: macOS brew install jq, Linux apt install jq, Manual: https://jqlang.github.io/jq/download/ — then re-run /vbw:init." Do NOT proceed without jq.git ls-files --error-unmatch . 2>/dev/null | head -5 — any output = BROWNFIELD=true**/*.* excluding .vbw-planning/, .claude/, node_modules/, .git/ — any match = BROWNFIELD=trueCRITICAL: Complete ENTIRE step (including writing settings.json) BEFORE Step 1. Use AskUserQuestion for prompts. Wait for answers. Write settings.json. Only then proceed.
Resolve config directory: Try in order: env var CLAUDE_CONFIG_DIR (if set, even if directory does not yet exist), ~/.config/claude-code (if exists), otherwise ~/.claude. Store result as CLAUDE_DIR. Use it for all config paths in this command.
Read CLAUDE_DIR/settings.json (create {} if missing).
0a. Agent Teams: Check env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS == "1".
"1". Declined: display "○ Skipped."0b. Statusline: Read statusLine (may be string or object with command field).
| State | Condition | Action |
|---|---|---|
| HAS_VBW | Value contains vbw-statusline | Display "✓ Statusline — installed", skip to 0c |
| HAS_OTHER | Non-empty, no vbw-statusline | AskUserQuestion (mention replacement) |
| EMPTY | Missing/null/empty | AskUserQuestion |
AskUserQuestion text: "○ VBW includes a custom status line showing phase progress, context usage, cost, duration, and more — updated after every response. Install it?" (If HAS_OTHER, mention existing statusline would be replaced.)
If approved, set statusLine to:
{"type": "command", "command": "bash -c 'for _d in \"${CLAUDE_CONFIG_DIR:-}\" \"$HOME/.config/claude-code\" \"$HOME/.claude\"; do [ -z \"$_d\" ] && continue; f=$(ls -1 \"$_d\"/plugins/cache/vbw-marketplace/vbw/*/scripts/vbw-statusline.sh 2>/dev/null | sort -V | tail -1 || true); [ -f \"$f\" ] && exec bash \"$f\"; done'"}
Object format with type+command is required — plain string fails silently.
If declined: display "○ Skipped. Run /vbw:config to install it later."
0c. Write settings.json if changed (single write). Display summary:
Environment setup complete:
{✓ or ○} Agent Teams
{✓ or ○} Statusline {add "(restart to activate)" if newly installed}
Timing rationale: Detection happens after environment setup (Step 0) but before scaffold (Step 1) to ensure:
Index structure: The INDEX.json file generated by scripts/generate-gsd-index.sh contains:
imported_at: UTC timestampgsd_version: From .planning/config.json (or "unknown")phases_total, phases_complete: Counts based on SUMMARY file presencemilestones: Extracted from ROADMAP.md h2 headersquick_paths: Relative paths to key archive files (roadmap, project, phases, config)phases: Array of {num, slug, plans, status} per phase directorySee docs/migration-gsd-to-vbw.md for full field descriptions and usage examples.
Detection: Check for .planning/ directory: [ -d .planning ]
mkdir -p .vbw-planning/gsd-archivecp -r .planning/* .vbw-planning/gsd-archive/bash "{plugin-root}/scripts/generate-gsd-index.sh"Read each template from {plugin-root}/templates/ and write to .vbw-planning/:
| Target | Source |
|---|---|
| .vbw-planning/PROJECT.md | {plugin-root}/templates/PROJECT.md |
| .vbw-planning/REQUIREMENTS.md | {plugin-root}/templates/REQUIREMENTS.md |
| .vbw-planning/ROADMAP.md | {plugin-root}/templates/ROADMAP.md |
| .vbw-planning/STATE.md | {plugin-root}/templates/STATE.md |
| .vbw-planning/config.json | {plugin-root}/config/defaults.json |
Create .vbw-planning/phases/. Ensure config.json includes "prefer_teams": "auto" and "model_profile": "quality".
AskUserQuestion (single select):
manual (default): don't auto-ignore or auto-commit planning filesignore: keep .vbw-planning/ ignored in root .gitignorecommit: track .vbw-planning/ + CLAUDE.md at helper-backed planning boundaries (bootstrap, planning checkpoints, todo adds, archive)AskUserQuestion (single select):
never (default)after_phase (push once after a phase completes)always (push after each commit when upstream exists)Write selected values to .vbw-planning/config.json:
jq '.planning_tracking = "'"$PLANNING_TRACKING"'" | .auto_push = "'"$AUTO_PUSH"'"' .vbw-planning/config.json > .vbw-planning/config.json.tmp && mv .vbw-planning/config.json.tmp .vbw-planning/config.json
Then align git ignore behavior with config:
PG_SCRIPT="/tmp/.vbw-plugin-root-link-${CLAUDE_SESSION_ID:-default}/scripts/planning-git.sh"
if [ -f "$PG_SCRIPT" ]; then
bash "$PG_SCRIPT" sync-ignore .vbw-planning/config.json
else
echo "VBW: planning-git.sh unavailable; skipping .gitignore sync" >&2
fi
git rev-parse --git-dir — if not a git repo, display "○ Git hooks skipped (not a git repository)" and skipbash "{plugin-root}/scripts/install-hooks.sh", display based on output:
✓ Git hooks installed (pre-push)✓ Git hooks (already installed)1.7a. Detection: [ -d "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/commands/gsd" ] || [ -d "$HOME/.config/claude-code/commands/gsd" ] || [ -d ".planning" ] || [ -d ".vbw-planning/gsd-archive" ]
1.7b. Consent: AskUserQuestion: "GSD detected. Enable plugin isolation?\n\nThis adds a PreToolUse hook that prevents GSD commands and agents from\nreading or writing files in .vbw-planning/. VBW commands are unaffected." Options: "Enable (Recommended)" / "Skip". If declined: "○ GSD isolation skipped", skip to Step 2.
1.7c. Create isolation: If approved:
echo "enabled" > .vbw-planning/.gsd-isolationecho "session" > .vbw-planning/.vbw-session✓ GSD isolation enabled + ✓ .vbw-planning/.gsd-isolation (flag) + ✓ Plugin Isolation section will be added to CLAUDE.md in Step 3.5Set GSD_ISOLATION_ENABLED=true for Step 3.5.
2a. If BROWNFIELD=true:
2b. Run bash "{plugin-root}/scripts/detect-stack.sh" "$(pwd)". Save full JSON. Display: ✓ Stack: {comma-separated detected_stack items}
2.5. LSP setup (language servers + Claude plugins):
Run bash "{plugin-root}/scripts/resolve-lsp.sh" with the detected_stack JSON array from Step 2b and CLAUDE_DIR/settings.json path. Capture the JSON output.
If env_needed=false AND all plugins have plugin_enabled=true: display ✓ LSP — already configured, skip to 2c.
Otherwise, display detected languages and recommended LSP plugins, then proceed through sub-steps:
2.5a (env flag): If env_needed=true:
env.ENABLE_LSP_TOOL to "1" in CLAUDE_DIR/settings.json (same write pattern as Step 0c)2.5b (binary check): For each plugin where binary_installed=false:
install_cmd is not null: AskUserQuestion: "Install {description} language server?\nCommand: {install_cmd}"
install_cmd is null (install_url only): display "○ {description} — manual install: {install_url}"2.5c (marketplace catalog): If any plugins have plugin_enabled=false:
unset CLAUDECODE && claude plugin marketplace list 2>&1 | grep -q "{org}" (using the org from the first pending plugin){org} marketplace catalog. Add it?"
unset CLAUDECODE && claude plugin marketplace add {org} 2>&12.5d (plugin install): For plugins where plugin_enabled=false:
unset CLAUDECODE && claude plugin marketplace update {org} 2>&1 once, then for each: unset CLAUDECODE && claude plugin install {plugin} 2>&1Display summary: ✓ LSP — {N} language server(s) configured or ○ LSP — skipped
If any settings.json changes or plugins installed: display (restart Claude Code to activate LSP)
2c. Codebase mapping (adaptive):
○ Greenfield — skipping codebase mapping{plugin-root}/commands/map.md and follow directly◆ Codebase mapping started ({SOURCE_FILE_COUNT} files). Do NOT run in background. The map MUST complete before proceeding to Step 3.2d. find-skills bootstrap: Check find_skills_available from detect-stack JSON.
true: display "✓ Skills.sh registry — available"false: AskUserQuestion: "○ Skills.sh Registry\n\nVBW can search the Skills.sh registry (~2000 community skills) to find\nskills matching your project. This requires the find-skills meta-skill.\nInstall it now?" Options: "Install (Recommended)" / "Skip"
npx skills add vercel-labs/skills --skill find-skills -g -y3a. Verify mapping completed. Display ✓ Codebase mapped ({document-count} documents). If skipped (greenfield): proceed immediately.
3b. If .vbw-planning/codebase/STACK.md exists, read it and merge additional stack components into detected_stack[].
3b2. Auto-detect conventions: If .vbw-planning/codebase/PATTERNS.md exists:
{plugin-root}/commands/teach.md (Step R2).vbw-planning/conventions.json. Display: ✓ {count} conventions auto-detected from codebaseIf greenfield: write {"conventions": []}. Display: ○ Conventions — none yet (add with /vbw:teach)
3c. Parallel registry search (if find-skills available): run npx skills find "<stack-item>" for ALL detected_stack items in parallel (multiple concurrent Bash calls). Deduplicate against installed skills. If detected_stack empty, search by project type. Display results with (registry) tag.
3d. Unified skill prompt: Combine curated (from 2b) + registry (from 3c) results into single AskUserQuestion multiSelect. Tag (curated) or (registry). Max 4 options + "Skip". Install selected: npx skills add <skill> -g -y.
VBW needs its rules and state sections in a CLAUDE.md file. /vbw:vibe regenerates later with project content.
Brownfield handling: Read root CLAUDE.md via the Read tool.
## Active Context, ## VBW Rules, ## Plugin Isolation) and add ## Code Intelligence only if no Code Intelligence heading/guidance already exists anywhere in the file. Display ✓ CLAUDE.md (VBW sections refreshed in place).CLAUDE.md via bootstrap-claude.sh during Step 7f. Do NOT hand-compose the file here.Do not append ## Project Conventions or ## Commands to CLAUDE.md.
Display Phase Banner then file checklist (✓ for each created file).
GSD import status (conditional):
find .vbw-planning/gsd-archive -type f | wc -l, then display sub-bullet: " • Index: .vbw-planning/gsd-archive/INDEX.json"Then show conditional lines for GSD isolation, statusline, codebase mapping, conventions, skills.
Display transition message: ◆ Infrastructure complete. Defining project...
Detect the initialization scenario based on flags set in earlier steps:
.vbw-planning/gsd-archive/ directory exists (created in Step 0.5). Has GSD work history to import..vbw-planning/codebase/ directory exists (created in Step 2c mapping). Has codebase context to infer from..vbw-planning/codebase/ does not exist. Edge case — should not occur after Step 2c, but handle gracefully by treating as GREENFIELD.Check conditions in order (GSD_MIGRATION first since a GSD project may also be brownfield):
if [ -d .vbw-planning/gsd-archive ]; then SCENARIO=GSD_MIGRATION
elif [ "$BROWNFIELD" = "true" ] && [ -d .vbw-planning/codebase ]; then SCENARIO=BROWNFIELD
elif [ "$BROWNFIELD" = "true" ]; then SCENARIO=HYBRID
else SCENARIO=GREENFIELD
fi
Display the detected scenario:
○ Scenario: Greenfield — new project◆ Scenario: Brownfield — existing codebase detected◆ Scenario: GSD Migration — importing work history○ Scenario: Hybrid — treating as greenfield (no mapping)No user interaction in this step. Proceed immediately to Step 6.
Run inference scripts based on the detected scenario, display results, and confirm with the user. Always show inferred data even if fields are null (REQ-03).
6a. Greenfield branch (SCENARIO=GREENFIELD or SCENARIO=HYBRID):
○ Greenfield — no codebase context to infer6b. Brownfield branch (SCENARIO=BROWNFIELD):
bash "{plugin-root}/scripts/infer-project-context.sh" .vbw-planning/codebase/ "$(pwd)".vbw-planning/inference.json via Bash◆ Inferred project context:
Name: {name.value} (source: {name.source})
Tech stack: {tech_stack.value | join(", ")} (source: {tech_stack.source})
Architecture: {architecture.value} (source: {architecture.source})
Purpose: {purpose.value} (source: {purpose.source})
Features: {features.value | join(", ")} (source: {features.source})
{field}: (not detected) — always show every field6c. GSD Migration branch (SCENARIO=GSD_MIGRATION):
bash "{plugin-root}/scripts/infer-gsd-summary.sh" .vbw-planning/gsd-archive/.vbw-planning/gsd-inference.json via Bash.vbw-planning/codebase/ exists, also run: bash "{plugin-root}/scripts/infer-project-context.sh" .vbw-planning/codebase/ "$(pwd)"
.vbw-planning/inference.json◆ Inferred from GSD work history:
Latest milestone: {latest_milestone.name} ({latest_milestone.status})
Recent phases: {recent_phases | map(.name) | join(", ")}
Key decisions: {key_decisions | join("; ")}
Current work: {current_work.phase} ({current_work.status})
{field}: (not detected) — always show every field6d. Confirmation UX (all non-greenfield scenarios):
Use AskUserQuestion to confirm inferred data:
"Does this look right?"
Options:
6e. Correction flow (when user picks "Close, but needs adjustments"):
Display all fields as a numbered list. Use AskUserQuestion: "Which fields would you like to correct? (enter numbers, comma-separated)"
For each selected field, use AskUserQuestion to ask the user for the corrected value. Update the inference JSON with corrected values.
After all corrections, display updated summary and proceed to Step 7 with corrected data.
Write the final confirmed/corrected data to .vbw-planning/inference.json for Step 7 consumption.
Generate all project-defining files using confirmed data from Step 6 or discovery questions.
Display: ◆ Generating project files...
7a. Gather project data:
If SKIP_INFERENCE=true (greenfield or user chose "Define from scratch"):
If SKIP_INFERENCE=false (confirmed/corrected inference data):
.vbw-planning/inference.json to get confirmed project contextname.value, DESCRIPTION from purpose.value.vbw-planning/gsd-inference.json for milestone/phase context7b. Generate PROJECT.md:
bash "{plugin-root}/scripts/bootstrap/bootstrap-project.sh" .vbw-planning/PROJECT.md "$NAME" "$DESCRIPTION"✓ PROJECT.md7c. Generate REQUIREMENTS.md:
.vbw-planning/discovery.json with format: {"answered": [...], "inferred": [...]}
answered: array of requirement strings from user answersinferred: array of {"text": "...", "priority": "Must-have"} from inference featuresbash "{plugin-root}/scripts/bootstrap/bootstrap-requirements.sh" .vbw-planning/REQUIREMENTS.md .vbw-planning/discovery.json✓ REQUIREMENTS.md7d. Generate ROADMAP.md:
.vbw-planning/phases.json with format: [{"name": "...", "goal": "...", "requirements": [...], "success_criteria": [...]}]
bash "{plugin-root}/scripts/bootstrap/bootstrap-roadmap.sh" .vbw-planning/ROADMAP.md "$NAME" .vbw-planning/phases.json✓ ROADMAP.md7e. Generate STATE.md:
bash "{plugin-root}/scripts/bootstrap/bootstrap-state.sh" .vbw-planning/STATE.md "$NAME" "$MILESTONE_NAME" "$PHASE_COUNT"✓ STATE.md7f. Generate/update CLAUDE.md:
CORE_VALUE from .vbw-planning/PROJECT.md (grep -m1 '^\*\*Core value:\*\*' .vbw-planning/PROJECT.md | sed 's/^\*\*Core value:\*\* *//')bash "{plugin-root}/scripts/bootstrap/bootstrap-claude.sh" CLAUDE.md "$NAME" "$CORE_VALUE" "CLAUDE.md"
✓ CLAUDE.md7g. Cleanup temporary files:
.vbw-planning/discovery.json, .vbw-planning/phases.json, .vbw-planning/inference.json, .vbw-planning/gsd-inference.json (if they exist)7h. Planning commit boundary (conditional):
PG_SCRIPT="/tmp/.vbw-plugin-root-link-${CLAUDE_SESSION_ID:-default}/scripts/planning-git.sh"
if [ -f "$PG_SCRIPT" ]; then
bash "$PG_SCRIPT" commit-boundary "bootstrap project files" .vbw-planning/config.json
else
echo "VBW: planning-git.sh unavailable; skipping planning git boundary commit" >&2
fi
planning_tracking=commit: stages .vbw-planning/ + CLAUDE.md and commits if there are changesplanning_tracking=manual|ignore: no-opauto_push=always, pushes when branch has an upstreamDisplay a banner per @${CLAUDE_PLUGIN_ROOT}/references/vbw-brand-essentials.md with the title "VBW Initialization Complete".
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
VBW Initialization Complete
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
File checklist: Display all created/updated files:
✓ .vbw-planning/PROJECT.md✓ .vbw-planning/REQUIREMENTS.md✓ .vbw-planning/ROADMAP.md✓ .vbw-planning/STATE.md✓ CLAUDE.md✓ .vbw-planning/config.json✓ Bootstrap planning artifacts committed✓ GSD project archived✓ Codebase mappedNext steps:
➜ Next: Run /vbw:vibe to start planning your first milestone
Or: Run /vbw:status to review project state
Follow @${CLAUDE_PLUGIN_ROOT}/references/vbw-brand-essentials.md — Phase Banner (double-line box), File Checklist (✓), ○ for pending, Next Up Block, no ANSI color codes.