
Brewcode:Setup
- 17 installs
- 29 repo stars
- Updated August 2, 2026
- kochetkov-ma/claude-brewcode
Initialize Brewcode project configuration and environment setup for bounded task execution
About
Brewcode skill for initializing project environments and Brewcode configuration. Solo developers use this at the start of new projects or when configuring Brewcode's lifecycle hooks and delegation settings.
- Environment setup
- Configuration
- Initialization
Brewcode:Setup by the numbers
- 17 all-time installs (skills.sh)
- Ranked #2,076 of 3,282 Productivity & Planning skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/kochetkov-ma/claude-brewcode --skill brewcodesetupAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 17 |
|---|---|
| repo stars | ★ 29 |
| Last updated | August 2, 2026 |
| Repository | kochetkov-ma/claude-brewcode ↗ |
What it does
Initialize Brewcode project configuration and environment setup for bounded task execution
Who is it for?
Developers setting up Brewcode projects
When should I use this skill?
Initializing Brewcode for new projects
Files
<instructions>
Phase 0: Prerequisites Check
Agent: developer | Action: Verify and install required tools
Auto-checks prerequisites. If all required components are present, skips to Phase 1 silently.
Step 1: State Check
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/install.sh" state && echo "✅ state" || echo "❌ state FAILED"STOP if ❌ — verify install.sh exists in scripts/.
Step 2: Evaluate Results
Parse state output table. Required components: brew, timeout, jq.
- All required show ✅ -> Skip to Phase 1 (log: "All prerequisites present, skipping installation.")
- Any required show ❌ -> Continue to Step 3
Step 2.5: Load Deferred Tool Schemas
Call ToolSearch with query: "select:AskUserQuestion" to load its schema. Required for Claude Code v2.1.107+ where AskUserQuestion is deferred. If ToolSearch fails, continue -- AskUserQuestion may already be loaded.
Step 3: Install Required Components
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/install.sh" check-timeout && echo "✅ timeout-check" || echo "❌ timeout-check FAILED"If TIMEOUT_EXISTS=false -> ASK (AskUserQuestion): "The timeout command is missing. Create symlink to gtimeout? This is REQUIRED for brewcode." Options: "Yes, create" | "Cancel setup"
If cancel -> STOP: "Setup cancelled. timeout command is required for brewcode."
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/install.sh" required && echo "✅ required" || echo "❌ required FAILED"STOP if ❌ — required components must be installed before continuing.
If timeout still missing -> EXECUTE: bash "${CLAUDE_SKILL_DIR}/scripts/install.sh" timeout
Step 4: Semantic Search (Optional)
If grepai not installed -> ASK (AskUserQuestion): "Install semantic search (grepai)? Enables AI-powered code search (~1.5GB)." Options: "Yes, install grepai" | "Skip"
If Yes -> EXECUTE: bash "${CLAUDE_SKILL_DIR}/scripts/install.sh" grepai
Step 5: Summary
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/install.sh" summary && echo "✅ summary" || echo "❌ summary FAILED"---
Phase 1: Project Structure Analysis
Agent: Explore | Action: Scan project and gather intelligence
Context: BC_PLUGIN_ROOT is available in your context (injected by pre-task.mjs hook).
EXECUTE using Bash tool:
bash "scripts/setup.sh" scan && echo "✅ scan" || echo "❌ scan FAILED"STOP if ❌ — check script exists and plugin is installed.
---
Phase 2: Intelligence Analysis
Agent: Plan | Action: Consolidate findings and create adaptation strategy
Create Adaptation Plan:
# Adaptation Plan
## Tech Stack
- Language: [Java/Node.js/Python/Go/Rust]
- Framework: [Spring Boot/Express/Django/etc]
- Build: [Maven/Gradle/npm/pip/cargo]
## Testing
- Framework: [JUnit 5/pytest/Jest/Go testing]
- Assertion: [AssertJ/Hamcrest/Chai/assert]
- Mocking: [Mockito/unittest.mock/Sinon]
- Data: [DBRider/Testcontainers/fixtures]
## Database
- Type: [PostgreSQL/MySQL/MongoDB/Redis/ClickHouse]
- Access: [JOOQ/JPA/Hibernate/Sequelize/SQLAlchemy]
## Project Agents
- agent-name: purpose (model)
## Key Patterns (from CLAUDE.md)
- Pattern 1
- Pattern 2
- Pattern 3
## Template Adaptations
- Update AGENTS section with project agents
- Add tech-specific constraints
- Customize verification checklists
- Add database-specific final review agent---
Phase 3: Template Generation
Agent: developer | Action: Generate adapted template at .claude/tasks/templates/PLAN.md.template
Create Structure
EXECUTE using Bash tool:
bash "scripts/setup.sh" structure && echo "✅ structure" || echo "❌ structure FAILED"STOP if ❌ — verify .claude/tasks directory is writable.
Copy/Update Templates
EXECUTE using Bash tool:
bash "scripts/setup.sh" sync && echo "✅ sync" || echo "❌ sync FAILED"STOP if ❌ — verify plugin templates exist.
Templates synced from plugin. Rules created once (never overwritten). Review skill adapted by AI.
Template Modifications
| Section | Adaptation |
|---|---|
| Agents | Add project-specific agents from .claude/agents/ |
| Reference Examples | Fill with project's reference files (controllers, services, tests) |
| Phase V agents | Customize reviewer focus for detected testing/code patterns |
| Final Review | Add project agents (db_expert, etc.) if relevant tech detected |
Required Sections
Preserve universal structure. Key sections to adapt:
## Agents — Add project agents above Core Agents
## Reference Examples — R1..RN with project's canonical files
## Phases — Each phase has: Agent, Status, Context (C#), Refs (R#)
## Phase NV: Verification — 2+ agents, one checks patterns compliance
## Final Review — 3+ agents parallel
## Context Index — C1..CN task-specific files---
Phase 3.5: Copy and Adapt Review Skill
Agent: developer | Action: Copy review skill template and adapt for project
Export project analysis results as environment variables before running the script:
export DETECTED_TECH="<detected technology stack from analysis>"
export AGENT_COUNT="<number of agents discovered>"
export GROUP_COUNT="<number of review groups>"
export MAIN_AGENT="<primary review agent name>"
export TEST_AGENT="<test review agent name>"
export DB_AGENT="<database review agent name>"EXECUTE using Bash tool:
bash "scripts/setup.sh" review && echo "✅ review" || echo "❌ review FAILED"STOP if ❌ — verify review template exists in plugin.
Adapt Review Skill
If you adapt the review skill description, keep it <= 120 chars (optimal ~100), single line, what + 3-5 distinct triggers. Some registries truncate long descriptions.| Placeholder | Source | Example |
|---|---|---|
{PROJECT_AGENTS_TABLE} | .claude/agents/ scan | `\ |
{TECH_SPECIFIC_CHECKS} | Detected tech stack | See Tech-Specific Checks below |
{PROJECT_RULES} | CLAUDE.md patterns | AssertJ rules, Lombok, logging |
{MAIN_AGENT} | Project agent or reviewer | reviewer |
{TEST_AGENT} | Project agent or tester | tester |
{DB_AGENT} | Project agent or sql_expert | db_expert |
{CUSTOM_GROUPS} | Additional review groups | Security, API validation |
{CODEBASE_BLOCKS} | Detected source patterns | src/main/**, src/test/** |
Tech-Specific Checks Templates
Java/Spring:
| Category | Checks |
|---|---|
| DI | Constructor injection, no field injection, @RequiredArgsConstructor |
| Transactions | @Transactional scope, rollback rules, isolation levels |
| Null-safety | Optional usage, @NonNull/@Nullable, null checks |
| N+1 | Eager vs lazy loading, batch fetching, entity graphs |
| Security | @PreAuthorize, input validation, SQL injection |
| Lombok | @Value, @Builder, @Slf4j usage |
Node.js/TypeScript:
| Category | Checks |
|---|---|
| Async | Promise handling, unhandled rejections, async/await |
| Types | Strict null checks, type guards, generics |
| Validation | Input sanitization, schema validation (Zod/Joi) |
| Security | XSS prevention, CSRF tokens, helmet.js |
| Imports | ESM vs CJS, barrel exports, circular deps |
Python:
| Category | Checks |
|---|---|
| Type hints | Function signatures, return types, generics |
| Exceptions | Specific exception types, context managers |
| Async | asyncio patterns, event loop handling |
| Security | SQL parameterization, input validation |
| Style | PEP8, docstrings, comprehensions |
Go:
| Category | Checks |
|---|---|
| Error handling | Error wrapping, sentinel errors, error types |
| Concurrency | Goroutine leaks, channel patterns, sync primitives |
| Memory | Slice capacity, pointer semantics, defer usage |
| Security | SQL injection, input validation |
| Interfaces | Small interfaces, composition |
Validation
EXECUTE using Bash tool:
test -f .claude/skills/brewcode-review/SKILL.md && echo "✅ Review skill created" || echo "❌ Review skill MISSING"
grep -q "Tech-Specific\|tech-specific\|Category.*Checks" .claude/skills/brewcode-review/SKILL.md && echo "✅ Tech checks" || echo "❌ Tech checks MISSING"STOP if any ❌ — review skill must be created before continuing.
---
Phase 3.6: Copy Configuration
Agent: developer | Action: Copy configuration template for runtime settings
EXECUTE using Bash tool:
bash "scripts/setup.sh" config && echo "✅ config" || echo "❌ config FAILED"STOP if ❌ — verify .claude/tasks/cfg directory exists.
| Setting | Default | Description |
|---|---|---|
knowledge.maxEntries | 100 | Max KNOWLEDGE.jsonl entries after compaction |
knowledge.maxTokens | 500 | Max tokens in ## K block injected to agents |
knowledge.priorities | ["❌","✅","ℹ️"] | Priority order for knowledge entries |
stop.maxAttempts | 20 | Stop attempts before escape mechanism triggers |
agents.system | [...] | System agents (don't receive ## K injection) |
Hooks-only architecture: No external runtime. All context management via Claude Code hooks.
---
Phase 4: Validation
Agent: developer | Action: Verify template structure
EXECUTE using Bash tool:
bash "scripts/setup.sh" validate && echo "✅ validate" || echo "❌ validate FAILED"STOP if any ❌ — go back to "Copy Templates" step and fix.
| Check | Status |
|---|---|
| PLAN template | .claude/tasks/templates/PLAN.md.template |
| SPEC template | .claude/tasks/templates/SPEC.md.template |
| KNOWLEDGE template | .claude/tasks/templates/KNOWLEDGE.jsonl.template |
| Config file | .claude/tasks/cfg/brewcode.config.json |
| Project agents | [N] from .claude/agents/ |
| Reference Examples | [N] canonical files populated |
| Tech-specific adaptations | Testing framework, DB patterns |
| Review skill | .claude/skills/brewcode-review/SKILL.md |
---
Phase 5: Update Global CLAUDE.md Agents
Agent: developer | Action: Update agents section in global CLAUDE.md
Step 1: Collect Agents
EXECUTE using Bash tool:
bash "scripts/setup.sh" agents > /tmp/agents-section.md && cat /tmp/agents-section.mdOutput = ready-to-insert content. Script collects system + global + plugin agents.
Internal agents (bc-coordinator, bc-grepai-configurator, bc-knowledge-manager) are automatically excluded.
Step 2: Analyze Existing CLAUDE.md
Read ~/.claude/CLAUDE.md. Find ALL agent-related sections: ## Agents, ## Agent Selection, ### Core Agents, ### Global Utility Agents, any tables with Agent | Model | Purpose columns, any lists of agent names. Identify start/end line boundaries.
Step 3: Ask User
Preflight: Call ToolSearch with query: "select:AskUserQuestion" before proceeding.ASK using AskUserQuestion: "Found agent sections in ~/.claude/CLAUDE.md. Replace with optimized LLM-friendly format?" Options: "Yes -- replace all agent sections" | "No -- keep current format"
Step 4: If YES -- Replace
Use content from /tmp/agents-section.md. Do not add agents manually -- the script already filters internal agents.Using Edit tool: 1. Read /tmp/agents-section.md to get exact replacement content 2. Find ## Agents — DELEGATE! section in ~/.claude/CLAUDE.md 3. Replace with content from /tmp/agents-section.md 4. Preserve ### Global Skills subsection if it exists (append after agents table) 5. Preserve all non-agent content
LLM determines section boundaries, not grep. Content comes from script output.
</instructions>
---
Output Format
# Template Adaptation Complete
## Detection
| Field | Value |
|-------|-------|
| Arguments | `{received args or empty}` |
| Mode | `full` |
## Tech Stack
| Category | Value |
|----------|-------|
| Language | [detected] |
| Framework | [detected] |
| Testing | [framework] |
| Database | [type/access] |
| Project Agents | [N]: `agent1`, `agent2` |
## Adaptations
| Section | Changes |
|---------|---------|
| Agents | +[N] project agents |
| Reference Examples | [N] canonical files |
| Phase V | Reviewers for [tech] patterns |
| Final Review | +[db_expert/project agents] |
| Review Skill | Tech-specific checks, project rules |
## Templates
**Plan template:** `.claude/tasks/templates/PLAN.md.template`
**Review skill:** `.claude/skills/brewcode-review/SKILL.md`
## Usage
/brewcode:spec "Implement feature X"
/brewcode:review "Check null safety"MIT License
Copyright (c) 2025-2026 Maxim Kochetkov (kochetkov-ma)
https://github.com/kochetkov-ma/claude-brewcode
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Setup
Checks prerequisites, then analyzes your project's tech stack, testing framework, database layer, and existing agents to generate tailored templates and a review skill under .claude/tasks/. Run this once before using any other brewcode skill (spec, plan, start, review). Setup handles all required tooling (brew, coreutils, jq) and optionally sets up grepai for semantic code search.
Quick Start
/brewcode:setupPrerequisites
Phase 0 automatically checks and installs the following before project analysis begins:
| Component | Required | Purpose |
|---|---|---|
| brew | Yes | Homebrew package manager |
| coreutils+timeout | Yes | GNU timeout for brewcode scripts |
| jq | Yes | JSON processor for hooks |
| ollama + bge-m3 | No | Local embedding model for grepai |
| grepai | No | Semantic code search CLI |
Required components are installed automatically. Optional components are offered interactively. If all prerequisites are already present, Phase 0 is skipped entirely.
Modes
| Mode | How to trigger | What it does |
|---|---|---|
| Full auto-detect | /brewcode:setup | Scans the project, detects stack, generates all templates and review skill |
| Custom template | /brewcode:setup path/to/PLAN.md.template | Uses the provided template as a base and adapts it to the project |
Both modes run the same phases: check prerequisites, scan, analyze, generate templates, create review skill, and update the global ~/.claude/CLAUDE.md agents section (with confirmation).
Examples
Good Usage
# First-time setup in a new project -- run before anything else
/brewcode:setup# Setup auto-checks prerequisites -- skips if already installed
/brewcode:setup
# Phase 0: All prerequisites present, skipping installation.
# Phase 1: Scanning project...# After adding new agents to .claude/agents/ -- re-run to pick them up
/brewcode:setup# Use a shared team template as the starting point
/brewcode:setup ~/.claude/templates/PLAN.md.template# After switching from JPA to jOOQ -- re-run so templates reflect the new stack
/brewcode:setupCommon Mistakes
# WRONG: Running /brewcode:spec before setup
# Setup has not run yet, so there are no templates to base the spec on.
/brewcode:spec "Add payment endpoint"
# FIX: Run setup first, then spec.
/brewcode:setup
/brewcode:spec "Add payment endpoint"# WRONG: Editing .claude/tasks/templates/PLAN.md.template by hand
# The next /brewcode:setup will overwrite your manual changes.
# FIX: Put customizations in the source template and pass it as an argument.
/brewcode:setup ~/my-custom-template.md# WRONG: Running setup from a different directory than the project root
# The scan script looks at the current working directory for build files and agents.
# FIX: Open Claude Code at the project root, then run setup.Output
| File | Location | Purpose |
|---|---|---|
| PLAN template | .claude/tasks/templates/PLAN.md.template | Multi-phase task plan adapted to your stack |
| SPEC template | .claude/tasks/templates/SPEC.md.template | Specification template for brewcode:spec |
| KNOWLEDGE template | .claude/tasks/templates/KNOWLEDGE.jsonl.template | Knowledge base seed for task sessions |
| Config | .claude/tasks/cfg/brewcode.config.json | Runtime settings (knowledge limits, agent lists) |
| Review skill | .claude/skills/brewcode-review/SKILL.md | Tech-specific code review checklist |
The review skill is generated with checks matched to the detected stack (e.g., Spring DI rules for Java, async patterns for Node.js, error wrapping for Go).
Tips
- Run setup again whenever you change your tech stack, add project agents, or update your test framework. Templates are overwritten; rules are preserved.
- The skill asks for confirmation before modifying
~/.claude/CLAUDE.md. You can safely decline and still get all project-level templates. - After setup completes, the typical workflow is
spec->plan->start. Each of those skills depends on the templates setup creates. - Check
.claude/tasks/cfg/brewcode.config.jsonto tune knowledge compaction limits and agent injection settings after the initial run. - Setup handles prerequisites automatically. No need to install anything manually before running it.
Documentation
Full docs: setup
#!/bin/bash
set -euo pipefail
# brewcode installer
# Usage: install.sh <command> [options]
#
# Commands:
# state - Check current state of all components
# check-updates - Check for available updates
# check-timeout - Check if timeout command exists
# update-all - Update all outdated components
# required - Install required components (brew, coreutils, jq)
# timeout - Create timeout symlink only
# grepai - Install semantic search (ollama, bge-m3, grepai)
# summary - Show final installation summary
CMD="${1:-help}"
# Helper: check ollama service with timeout
ollama_running() {
curl -s --connect-timeout 2 --max-time 5 localhost:11434/api/tags &>/dev/null
}
# Helper: wait for ollama to start (retry loop)
wait_for_ollama() {
local max_attempts=10
for i in $(seq 1 $max_attempts); do
if ollama_running; then
return 0
fi
sleep 1
done
return 1
}
# Helper: log action
if [ -z "${ACTIONS_FILE:-}" ]; then
ACTIONS_FILE=$(mktemp /tmp/ft-install-actions.XXXXXX)
trap 'rm -f "$ACTIONS_FILE"' EXIT
fi
log_action() {
echo "- $1" >> "$ACTIONS_FILE"
}
# Helper: clear actions at start
clear_actions() {
rm -f "$ACTIONS_FILE"
}
# Helper: get grepai versions
get_grepai_versions() {
GREPAI_CURRENT=""
GREPAI_LATEST=""
if command -v grepai &>/dev/null; then
GREPAI_CURRENT=$(grepai version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
GREPAI_CURRENT="${GREPAI_CURRENT:-unknown}"
fi
if command -v brew &>/dev/null; then
GREPAI_LATEST=$(brew info yoanbernabeu/tap/grepai 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
fi
}
case "$CMD" in
state)
clear_actions
echo "=== brewcode Prerequisites ==="
echo ""
echo "| Component | Status | Version | Source | Type |"
echo "|-----------|--------|---------|--------|------|"
# Required: brew
if command -v brew &>/dev/null; then
VER=$(brew --version 2>&1 | head -1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
VER="${VER:-unknown}"
echo "| brew | ✅ | $VER | - | required |"
else
echo "| brew | ❌ missing | - | - | required |"
fi
# Required: timeout (coreutils)
if command -v timeout &>/dev/null; then
VER=$(timeout --version 2>&1 | head -1 | grep -oE '[0-9]+\.[0-9]+' | head -1 || true)
VER="${VER:-unknown}"
TIMEOUT_PATH=$(command -v timeout)
if [ -L "$TIMEOUT_PATH" ]; then
echo "| timeout | ✅ | $VER | symlink | required |"
elif brew list coreutils &>/dev/null 2>&1; then
echo "| timeout | ✅ | $VER | brew | required |"
else
echo "| timeout | ✅ | $VER | system | required |"
fi
else
echo "| timeout | ❌ missing | - | - | required |"
fi
# Required: jq
if command -v jq &>/dev/null; then
VER=$(jq --version 2>&1)
VER="${VER:-unknown}"
if brew list jq &>/dev/null 2>&1; then
echo "| jq | ✅ | $VER | brew | required |"
else
echo "| jq | ✅ | $VER | system | required |"
fi
else
echo "| jq | ❌ missing | - | - | required |"
fi
# Optional: ollama
if command -v ollama &>/dev/null; then
VER=$(ollama --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
VER="${VER:-unknown}"
SRC=$(brew list ollama &>/dev/null 2>&1 && echo "brew" || echo "system")
if ollama_running; then
echo "| ollama | ✅ running | $VER | $SRC | optional |"
else
echo "| ollama | ⚠️ stopped | $VER | $SRC | optional |"
fi
else
echo "| ollama | - | not installed | - | optional |"
fi
# Optional: bge-m3
if command -v ollama &>/dev/null && ollama_running && ollama list 2>/dev/null | grep -q bge-m3; then
echo "| bge-m3 | ✅ | installed | ollama | optional |"
elif command -v ollama &>/dev/null && ! ollama_running; then
echo "| bge-m3 | ? | ollama stopped | - | optional |"
else
echo "| bge-m3 | - | not installed | - | optional |"
fi
# Optional: grepai
get_grepai_versions
if [ -n "$GREPAI_CURRENT" ]; then
SRC=$(brew list yoanbernabeu/tap/grepai &>/dev/null 2>&1 && echo "brew" || echo "system")
if [ -n "$GREPAI_LATEST" ] && [ "$GREPAI_CURRENT" != "$GREPAI_LATEST" ]; then
echo "| grepai | ⚠️ outdated | $GREPAI_CURRENT → $GREPAI_LATEST | $SRC | optional |"
else
echo "| grepai | ✅ | $GREPAI_CURRENT | $SRC | optional |"
fi
else
echo "| grepai | - | not installed | - | optional |"
fi
;;
check-updates)
if ! command -v brew &>/dev/null; then
echo "UPDATES_AVAILABLE=false"
echo "NOTE=brew not installed"
exit 0
fi
# Update brew cache first
echo "BREW_CACHE=updating"
brew update --quiet 2>/dev/null && echo "BREW_CACHE=updated" || echo "BREW_CACHE=failed"
UPDATES=""
NOTES=""
# Check coreutils (timeout) - only if brew-managed
if brew list coreutils &>/dev/null; then
COREUTILS_CURRENT=$(timeout --version 2>&1 | head -1 | grep -oE '[0-9]+\.[0-9]+' | head -1 || true)
COREUTILS_LATEST=$(brew info coreutils 2>/dev/null | grep -oE '[0-9]+\.[0-9]+' | head -1 || true)
if [ -n "$COREUTILS_CURRENT" ] && [ -n "$COREUTILS_LATEST" ] && [ "$COREUTILS_CURRENT" != "$COREUTILS_LATEST" ]; then
UPDATES="${UPDATES:+$UPDATES }coreutils($COREUTILS_CURRENT→$COREUTILS_LATEST)"
fi
fi
# Check jq - only if brew-managed
if brew list jq &>/dev/null; then
JQ_CURRENT=$(jq --version 2>&1 | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -1 || true)
JQ_LATEST=$(brew info jq 2>/dev/null | grep -oE '[0-9]+\.[0-9]+' | head -1 || true)
if [ -n "$JQ_CURRENT" ] && [ -n "$JQ_LATEST" ] && [ "$JQ_CURRENT" != "$JQ_LATEST" ]; then
UPDATES="${UPDATES:+$UPDATES }jq($JQ_CURRENT→$JQ_LATEST)"
fi
elif command -v jq &>/dev/null; then
# jq exists but not brew-managed - note it
JQ_PATH=$(command -v jq)
JQ_CURRENT=$(jq --version 2>&1 | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -1 || true)
NOTES="${NOTES:+$NOTES; }jq($JQ_CURRENT) at $JQ_PATH (not brew-managed)"
fi
# Check grepai
get_grepai_versions
if [ -n "$GREPAI_CURRENT" ] && [ -n "$GREPAI_LATEST" ] && [ "$GREPAI_CURRENT" != "$GREPAI_LATEST" ]; then
UPDATES="${UPDATES:+$UPDATES }grepai($GREPAI_CURRENT→$GREPAI_LATEST)"
fi
# Trim whitespace
UPDATES="${UPDATES## }"
UPDATES="${UPDATES%% }"
if [ -n "$UPDATES" ]; then
echo "UPDATES_AVAILABLE=true"
echo "UPDATES=$UPDATES"
else
echo "UPDATES_AVAILABLE=false"
fi
[ -n "$NOTES" ] && echo "NOTES=$NOTES"
;;
check-timeout)
if command -v timeout &>/dev/null; then
echo "TIMEOUT_EXISTS=true"
echo "VERSION=$(timeout --version 2>&1 | head -1)"
TIMEOUT_PATH=$(command -v timeout)
if [ -L "$TIMEOUT_PATH" ]; then
SYMLINK_TARGET=$(readlink "$TIMEOUT_PATH")
echo "SYMLINK=$TIMEOUT_PATH → $SYMLINK_TARGET"
else
echo "PATH=$TIMEOUT_PATH"
fi
else
echo "TIMEOUT_EXISTS=false"
if command -v gtimeout &>/dev/null; then
echo "GTIMEOUT_EXISTS=true"
echo "GTIMEOUT_PATH=$(command -v gtimeout)"
echo "HINT=Create symlink: ln -sf \$(brew --prefix)/opt/coreutils/libexec/gnubin/timeout \$(brew --prefix)/bin/timeout"
else
echo "GTIMEOUT_EXISTS=false"
fi
fi
;;
update-all)
echo "=== Updating Components ==="
if ! command -v brew &>/dev/null; then
echo "❌ brew not installed"
exit 1
fi
# Update coreutils
if brew list coreutils &>/dev/null; then
OLD_VER=$(timeout --version 2>&1 | head -1 | grep -oE '[0-9]+\.[0-9]+' | head -1 || true)
if brew upgrade coreutils 2>&1 | grep -q "Upgrading"; then
NEW_VER=$(timeout --version 2>&1 | head -1 | grep -oE '[0-9]+\.[0-9]+' | head -1 || true)
echo "✅ coreutils: updated"
log_action "Updated coreutils: $OLD_VER → $NEW_VER"
else
echo "⏭️ coreutils: already latest"
fi
fi
# Update jq
if brew list jq &>/dev/null; then
OLD_VER=$(jq --version 2>&1 | grep -oE '[0-9]+\.[0-9]+' | head -1 || true)
if brew upgrade jq 2>&1 | grep -q "Upgrading"; then
NEW_VER=$(jq --version 2>&1 | grep -oE '[0-9]+\.[0-9]+' | head -1 || true)
echo "✅ jq: updated"
log_action "Updated jq: $OLD_VER → $NEW_VER"
else
echo "⏭️ jq: already latest"
fi
fi
# Update grepai
get_grepai_versions
if [ -n "$GREPAI_CURRENT" ] && [ -n "$GREPAI_LATEST" ] && [ "$GREPAI_CURRENT" != "$GREPAI_LATEST" ]; then
echo "Updating grepai: $GREPAI_CURRENT → $GREPAI_LATEST"
if brew upgrade yoanbernabeu/tap/grepai; then
echo "✅ grepai: updated"
log_action "Updated grepai: $GREPAI_CURRENT → $GREPAI_LATEST"
else
echo "⚠️ grepai: update failed"
fi
elif [ -n "$GREPAI_CURRENT" ]; then
echo "⏭️ grepai: already latest ($GREPAI_CURRENT)"
fi
echo "✅ Updates complete"
;;
required)
echo "=== Installing Required Components ==="
# Homebrew
echo ""
echo "--- Homebrew ---"
if ! command -v brew &>/dev/null; then
echo "Installing Homebrew..."
NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # nosemgrep: curl-pipe-bash
eval "$(/opt/homebrew/bin/brew shellenv)" 2>/dev/null || eval "$(/usr/local/bin/brew shellenv)" 2>/dev/null || true
command -v brew &>/dev/null && { echo "✅ brew: installed"; log_action "Installed Homebrew"; } || { echo "❌ brew: FAILED"; exit 1; }
else
echo "✅ brew: $(brew --version | head -1)"
fi
# coreutils
echo ""
echo "--- coreutils ---"
if ! brew list coreutils &>/dev/null; then
echo "Installing coreutils..."
brew install coreutils
echo "✅ coreutils: installed"
log_action "Installed coreutils"
else
echo "✅ coreutils: already installed"
fi
# jq
echo ""
echo "--- jq ---"
if ! command -v jq &>/dev/null; then
echo "Installing jq..."
brew install jq
command -v jq &>/dev/null && { echo "✅ jq: installed"; log_action "Installed jq"; } || { echo "❌ jq: FAILED"; exit 1; }
else
echo "✅ jq: $(jq --version)"
fi
echo ""
echo "=== Required Components Done ==="
;;
timeout)
echo "=== Creating timeout symlink ==="
if command -v timeout &>/dev/null; then
echo "✅ timeout: already exists"
exit 0
fi
if ! brew list coreutils &>/dev/null; then
echo "Installing coreutils..."
brew install coreutils
log_action "Installed coreutils"
fi
BREW_BIN=$(brew --prefix)/bin
GTIMEOUT_PATH="$(brew --prefix)/opt/coreutils/libexec/gnubin/timeout"
# Safety check: don't overwrite regular file
if [ -e "$BREW_BIN/timeout" ] && [ ! -L "$BREW_BIN/timeout" ]; then
echo "⚠️ timeout: file exists (not symlink), skipping"
exit 1
fi
if [ -f "$GTIMEOUT_PATH" ]; then
ln -sf "$GTIMEOUT_PATH" "$BREW_BIN/timeout"
echo "✅ timeout: symlink created"
log_action "Created timeout symlink → gtimeout"
else
echo "❌ timeout: gtimeout not found at $GTIMEOUT_PATH"
exit 1
fi
;;
grepai)
echo "=== Installing Semantic Search ==="
# ollama
echo ""
echo "--- ollama ---"
if ! command -v ollama &>/dev/null; then
echo "Installing ollama..."
brew install ollama
command -v ollama &>/dev/null && { echo "✅ ollama: installed"; log_action "Installed ollama"; } || { echo "❌ ollama: FAILED"; exit 1; }
else
echo "✅ ollama: $(ollama --version 2>&1 | head -1)"
fi
# Start ollama with retry loop
if command -v ollama &>/dev/null && ! ollama_running; then
echo "Starting ollama service..."
brew services start ollama 2>/dev/null || nohup ollama serve >/dev/null 2>&1 &
disown 2>/dev/null || true
if wait_for_ollama; then
echo "✅ ollama: running"
log_action "Started ollama service"
else
echo "⚠️ ollama: failed to start, run manually: ollama serve"
fi
elif ollama_running; then
echo "✅ ollama: already running"
fi
# bge-m3
echo ""
echo "--- bge-m3 ---"
if command -v ollama &>/dev/null && ollama_running; then
if ! ollama list 2>/dev/null | grep -q bge-m3; then
echo "Pulling bge-m3 model (~1.2GB)..."
ollama pull bge-m3
echo "✅ bge-m3: installed"
log_action "Pulled bge-m3 embedding model"
else
echo "✅ bge-m3: already installed"
fi
else
echo "⚠️ bge-m3: skipped (ollama not running)"
fi
# grepai
echo ""
echo "--- grepai ---"
get_grepai_versions
if [ -z "$GREPAI_CURRENT" ]; then
echo "Installing grepai..."
brew install yoanbernabeu/tap/grepai
command -v grepai &>/dev/null && { echo "✅ grepai: installed"; log_action "Installed grepai CLI"; } || { echo "❌ grepai: FAILED"; exit 1; }
elif [ -n "$GREPAI_LATEST" ] && [ "$GREPAI_CURRENT" != "$GREPAI_LATEST" ]; then
echo "Updating grepai: $GREPAI_CURRENT → $GREPAI_LATEST"
if brew upgrade yoanbernabeu/tap/grepai; then
echo "✅ grepai: updated"
log_action "Updated grepai: $GREPAI_CURRENT → $GREPAI_LATEST"
else
echo "⚠️ grepai: update failed"
fi
else
echo "✅ grepai: $GREPAI_CURRENT (latest)"
fi
echo ""
echo "=== Semantic Search Done ==="
;;
summary)
# Optional: read actions from env or file
if [ -z "${ACTIONS_FILE:-}" ]; then
ACTIONS_FILE=$(mktemp /tmp/ft-install-actions.XXXXXX)
trap 'rm -f "$ACTIONS_FILE"' EXIT
fi
echo ""
echo "=== Installation Summary ==="
echo ""
echo "| Component | Status | Installed | Latest | Source |"
echo "|-----------|--------|-----------|--------|--------|"
# brew
if command -v brew &>/dev/null; then
VER=$(brew --version 2>&1 | head -1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
echo "| brew | ✅ | ${VER:-?} | - | - |"
else
echo "| brew | ❌ | - | - | - |"
fi
# timeout (coreutils)
if command -v timeout &>/dev/null; then
VER=$(timeout --version 2>&1 | head -1 | grep -oE '[0-9]+\.[0-9]+' | head -1 || true)
LATEST=$(brew info coreutils 2>/dev/null | grep -oE '[0-9]+\.[0-9]+' | head -1 || true)
TIMEOUT_PATH=$(command -v timeout)
if [ -L "$TIMEOUT_PATH" ]; then
SRC="symlink"
elif brew list coreutils &>/dev/null 2>&1; then
SRC="brew"
else
SRC="system"
fi
echo "| timeout | ✅ | ${VER:-?} | ${LATEST:-?} | $SRC |"
else
echo "| timeout | ❌ | - | - | - |"
fi
# jq
if command -v jq &>/dev/null; then
VER=$(jq --version 2>&1 | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -1 || true)
LATEST=$(brew info jq 2>/dev/null | grep -oE '[0-9]+\.[0-9]+' | head -1 || true)
if brew list jq &>/dev/null 2>&1; then
SRC="brew"
else
SRC="system"
fi
echo "| jq | ✅ | ${VER:-?} | ${LATEST:-?} | $SRC |"
else
echo "| jq | ❌ | - | - | - |"
fi
# ollama
if command -v ollama &>/dev/null; then
VER=$(ollama --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
LATEST=$(brew info ollama 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
SRC=$(brew list ollama &>/dev/null 2>&1 && echo "brew" || echo "system")
if ollama_running; then
echo "| ollama | ✅ running | ${VER:-?} | ${LATEST:-?} | $SRC |"
else
echo "| ollama | ⚠️ stopped | ${VER:-?} | ${LATEST:-?} | $SRC |"
fi
else
echo "| ollama | ⏭️ skipped | - | - | - |"
fi
# bge-m3
if command -v ollama &>/dev/null && ollama_running && ollama list 2>/dev/null | grep -q bge-m3; then
echo "| bge-m3 | ✅ | installed | - | ollama |"
elif command -v ollama &>/dev/null && ! ollama_running; then
echo "| bge-m3 | ? | unknown | - | - |"
else
echo "| bge-m3 | ⏭️ skipped | - | - | - |"
fi
# grepai
get_grepai_versions
if [ -n "$GREPAI_CURRENT" ]; then
SRC=$(brew list yoanbernabeu/tap/grepai &>/dev/null 2>&1 && echo "brew" || echo "system")
echo "| grepai | ✅ | $GREPAI_CURRENT | ${GREPAI_LATEST:-?} | $SRC |"
else
echo "| grepai | ⏭️ skipped | - | - | - |"
fi
# Actions performed
echo ""
echo "## Actions Performed"
if [ -f "$ACTIONS_FILE" ]; then
cat "$ACTIONS_FILE"
rm -f "$ACTIONS_FILE"
else
echo "- No actions recorded (all components were already installed)"
fi
;;
help|*)
echo "Usage: install.sh <command>"
echo ""
echo "Commands:"
echo " state Check current state of all components"
echo " check-updates Check for available updates"
echo " check-timeout Check if timeout command exists"
echo " update-all Update all outdated components"
echo " required Install required (brew, coreutils, jq)"
echo " timeout Create timeout symlink only"
echo " grepai Install semantic search (ollama, bge-m3, grepai)"
echo " summary Show final installation summary"
;;
esac
#!/bin/bash
# Brewcode Setup Script
# Multi-function script for /brewcode:setup skill
# Usage: setup.sh <mode> [options]
#
# Modes:
# scan - Scan project structure (Phase 1)
# structure - Create directories (Phase 3)
# sync - Sync templates from plugin (Phase 3)
# review - Copy review skill template (Phase 3.5)
# config - Copy config file (Phase 3.6)
# validate - Validation checks (Phase 4)
# all - Run all phases
set -euo pipefail
MODE="${1:-all}"
# Self-location: derive plugin root from script path
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# Path: scripts/setup.sh -> skills/setup/scripts -> skills/setup -> skills -> PLUGIN_ROOT
PLUGIN_ROOT="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")"
PLUGIN_TEMPLATES="$PLUGIN_ROOT/templates"
PLUGIN_SKILLS="$PLUGIN_ROOT/skills"
SETUP_TEMPLATES="$PLUGIN_ROOT/skills/setup/templates"
SETUP_REFERENCES="$PLUGIN_ROOT/skills/setup/references"
# Validate plugin structure
validate_plugin() {
if [ ! -d "$PLUGIN_ROOT" ]; then
echo "❌ Plugin root not found: $PLUGIN_ROOT"
exit 1
fi
if [ ! -d "$SETUP_TEMPLATES" ]; then
echo "❌ Setup templates not found: $SETUP_TEMPLATES"
exit 1
fi
}
# Phase 1: Scan project structure
scan_project() {
echo "=== Phase 1: Project Scan ==="
echo ""
echo "--- Build Files ---"
find . -maxdepth 3 -type f \( \
-name "package.json" -o \
-name "pom.xml" -o \
-name "build.gradle" -o \
-name "build.gradle.kts" -o \
-name "requirements.txt" -o \
-name "Pipfile" -o \
-name "Cargo.toml" -o \
-name "go.mod" -o \
-name "composer.json" \
\) 2>/dev/null || echo "(none found)"
echo ""
echo "--- Project Agents ---"
find .claude/agents -type f -name "*.md" 2>/dev/null | sort || echo "(none)"
echo ""
echo "--- Test Directories ---"
find . -type d \( -name "test" -o -name "tests" -o -name "__tests__" \) 2>/dev/null | head -20 || echo "(none)"
echo ""
echo "--- Sample Test Files ---"
find . -type f \( \
-name "*Test.java" -o \
-name "*Test.kt" -o \
-name "*.test.js" -o \
-name "*.test.ts" -o \
-name "*_test.py" -o \
-name "*_test.go" \
\) 2>/dev/null | head -10 || echo "(none)"
echo ""
echo "--- CLAUDE.md ---"
test -f ./CLAUDE.md && echo "✅ CLAUDE.md exists" || echo "⚠️ No CLAUDE.md"
test -f ./.claude/CLAUDE.md && echo "✅ .claude/CLAUDE.md exists" || echo "⚠️ No .claude/CLAUDE.md"
}
# Phase 3: Create directory structure
create_structure() {
echo "=== Phase 3: Create Structure ==="
mkdir -p .claude/tasks/templates .claude/rules
echo "✅ Created .claude/tasks/templates/"
echo "✅ Created .claude/rules/"
}
# Phase 3: Sync templates from plugin
sync_templates() {
echo "=== Phase 3: Sync Templates ==="
validate_plugin
sync_template() {
local src="$1" dst="$2"
if [ ! -f "$dst" ]; then
cp "$src" "$dst" && echo "✅ Created: $dst"
elif ! diff -q "$src" "$dst" >/dev/null 2>&1; then
cp "$src" "$dst" && echo "🔄 Updated: $dst"
else
echo "⏭️ Unchanged: $dst"
fi
}
sync_template "$SETUP_TEMPLATES/PLAN.md.template" ".claude/tasks/templates/PLAN.md.template"
sync_template "$SETUP_TEMPLATES/SPEC.md.template" ".claude/tasks/templates/SPEC.md.template"
sync_template "$SETUP_TEMPLATES/KNOWLEDGE.jsonl.template" ".claude/tasks/templates/KNOWLEDGE.jsonl.template"
sync_template "$SETUP_TEMPLATES/phase.md.template" ".claude/tasks/templates/phase.md.template"
sync_template "$SETUP_TEMPLATES/phase-verify.md.template" ".claude/tasks/templates/phase-verify.md.template"
sync_template "$SETUP_TEMPLATES/phase-fix.md.template" ".claude/tasks/templates/phase-fix.md.template"
sync_template "$SETUP_TEMPLATES/phase-final-review.md.template" ".claude/tasks/templates/phase-final-review.md.template"
# grepai-first: always sync (plugin-managed rule)
if [ -f "$PLUGIN_TEMPLATES/rules/grepai-first.md.template" ]; then
sync_template "$PLUGIN_TEMPLATES/rules/grepai-first.md.template" ".claude/rules/grepai-first.md"
fi
# Rules: create only if missing (never overwrite user rules)
if [ ! -f ".claude/rules/avoid.md" ]; then
cp "$PLUGIN_TEMPLATES/rules/avoid.md.template" .claude/rules/avoid.md
echo "✅ Created: .claude/rules/avoid.md"
else
echo "⏭️ Preserved: .claude/rules/avoid.md (user rules)"
fi
if [ ! -f ".claude/rules/best-practice.md" ]; then
cp "$PLUGIN_TEMPLATES/rules/best-practice.md.template" .claude/rules/best-practice.md
echo "✅ Created: .claude/rules/best-practice.md"
else
echo "⏭️ Preserved: .claude/rules/best-practice.md (user rules)"
fi
}
# Phase 3.5: Copy review skill template
copy_review_skill() {
echo "=== Phase 3.5: Review Skill ==="
validate_plugin
mkdir -p .claude/skills/brewcode-review
if [ -f "$PLUGIN_TEMPLATES/skills/review/SKILL.md.template" ]; then
# Constraint: env vars must be single-line (no newlines). sed processes line-by-line,
# so a newline in PROJECT_AGENTS_TABLE or CODEBASE_BLOCKS will silently truncate the substitution.
_sep=$'\x01'
sed \
-e "s${_sep}{ADAPTATION_TIMESTAMP}${_sep}$(date -u +%Y-%m-%dT%H:%M:%SZ)${_sep}g" \
-e "s${_sep}{DETECTED_TECH}${_sep}${DETECTED_TECH:-unknown}${_sep}g" \
-e "s${_sep}{AGENT_COUNT}${_sep}${AGENT_COUNT:-0}${_sep}g" \
-e "s${_sep}{GROUP_COUNT}${_sep}${GROUP_COUNT:-3}${_sep}g" \
-e "s${_sep}{MAIN_AGENT}${_sep}${MAIN_AGENT:-reviewer}${_sep}g" \
-e "s${_sep}{TEST_AGENT}${_sep}${TEST_AGENT:-tester}${_sep}g" \
-e "s${_sep}{DB_AGENT}${_sep}${DB_AGENT:-sql_expert}${_sep}g" \
-e "s${_sep}{PROJECT_AGENTS_TABLE}${_sep}${PROJECT_AGENTS_TABLE:-| reviewer | General | All layers |}${_sep}g" \
-e "s${_sep}{TECH_SPECIFIC_CHECKS}${_sep}${TECH_SPECIFIC_CHECKS:-General code quality checks}${_sep}g" \
-e "s${_sep}{PROJECT_RULES}${_sep}${PROJECT_RULES:-Standard coding conventions}${_sep}g" \
-e "s${_sep}{CUSTOM_GROUPS}${_sep}${CUSTOM_GROUPS:-}${_sep}g" \
-e "s${_sep}{CODEBASE_BLOCKS}${_sep}${CODEBASE_BLOCKS:-src/**}${_sep}g" \
-e "s${_sep}{REVIEW_PROMPT}${_sep}${REVIEW_PROMPT:-Review for quality and correctness}${_sep}g" \
"$PLUGIN_TEMPLATES/skills/review/SKILL.md.template" \
> .claude/skills/brewcode-review/SKILL.md
_runtime_placeholders='CONFIRMED_FINDINGS_JSON|REJECTED_FINDINGS_JSON|DISCARDED_FINDINGS_JSON|FILE_LIST|CRITIC_MISSED_FINDINGS_JSON|CRITIC_CHALLENGES_JSON|CRITIC_BLIND_SPOTS|TOTAL|BLOCKERS|CRITICAL|MAJOR|N|P0_COUNT|ACCEPTED|COUNT|TIMESTAMP|NAME'
_unresolved=$(grep -oE '\{[A-Z_]+\}' .claude/skills/brewcode-review/SKILL.md | sort -u | grep -vE "^\{(${_runtime_placeholders})\}$" || true)
if [ -n "$_unresolved" ]; then
echo "⚠️ WARNING: unresolved setup-time placeholders remain in brewcode-review/SKILL.md"
echo "$_unresolved"
fi
echo "✅ brewcode-review/SKILL.md generated"
else
echo "❌ Template not found: $PLUGIN_TEMPLATES/skills/review/SKILL.md.template"
exit 1
fi
# Copy references
if [ -d "$PLUGIN_TEMPLATES/skills/review/references" ]; then
mkdir -p .claude/skills/brewcode-review/references
cp "$PLUGIN_TEMPLATES/skills/review/references/"*.md .claude/skills/brewcode-review/references/
echo "✅ Copied: references/ (agent-prompt.md, report-template.md)"
fi
# Verify
test -f .claude/skills/brewcode-review/SKILL.md && echo "✅ Review skill created" || echo "❌ Review skill MISSING"
}
# Phase 3.6: Copy config
copy_config() {
echo "=== Phase 3.6: Config ==="
validate_plugin
TEMPLATE="$SETUP_TEMPLATES/brewcode.config.json.template"
PROJECT_CFG=".claude/tasks/cfg/brewcode.config.json"
mkdir -p .claude/tasks/cfg
if [ ! -f "$PROJECT_CFG" ]; then
cp "$TEMPLATE" "$PROJECT_CFG"
echo "✅ Config created: $PROJECT_CFG"
else
MERGED=$(jq -s '.[0] * .[1]' "$TEMPLATE" "$PROJECT_CFG" 2>/dev/null)
if [ -n "$MERGED" ]; then
MERGED_HASH=$(echo "$MERGED" | jq -S . | shasum -a 256 | cut -d' ' -f1)
PROJECT_HASH=$(jq -S . "$PROJECT_CFG" 2>/dev/null | shasum -a 256 | cut -d' ' -f1 || true)
if [ "$MERGED_HASH" != "$PROJECT_HASH" ]; then
cp "$PROJECT_CFG" "$PROJECT_CFG.bak"
echo "$MERGED" | jq -S . > "$PROJECT_CFG"
echo "🔄 Config merged (new keys added, user values preserved): $PROJECT_CFG"
echo " Backup: $PROJECT_CFG.bak"
else
echo "⏭️ Config unchanged: $PROJECT_CFG"
fi
else
echo "⚠️ Config merge failed (jq error), keeping existing: $PROJECT_CFG"
fi
fi
}
# Collect agents for CLAUDE.md
collect_agents() {
echo "=== Collect Agents ==="
echo ""
# Header
cat << 'EOF'
## Agents — DELEGATE!
> **MANAGER:** Delegate via Task tool. Never implement directly.
| Name | Scope | Purpose |
|------|-------|---------|
| Explore | system | Find files, search code |
| Plan | system | Design implementation |
| general-purpose | system | Multi-step research |
EOF
# Global agents from ~/.claude/agents/
if [ -d "$HOME/.claude/agents" ]; then
for f in "$HOME/.claude/agents"/*.md; do
[ -f "$f" ] || continue
name=$(grep "^name:" "$f" 2>/dev/null | head -1 | sed 's/^name: *//' | tr -d '"' | xargs || true)
desc=$(grep "^description:" "$f" 2>/dev/null | head -1 | sed 's/^description: *//' | tr -d '"' || true)
# Truncate to 5 words max
purpose=$(echo "$desc" | awk '{for(i=1;i<=5&&i<=NF;i++) printf "%s ", $i}' | xargs)
[ -n "$name" ] && echo "| $name | global | $purpose |"
done
fi
# Plugin agents from PLUGIN_ROOT/agents/ (excluding internal agents)
# Internal agents (bc-coordinator, bc-grepai-configurator, bc-knowledge-manager) are not listed
# because they are only called by the plugin itself, not by users
INTERNAL_AGENTS="bc-coordinator bc-grepai-configurator bc-knowledge-manager"
if [ -d "$PLUGIN_ROOT/agents" ]; then
for f in "$PLUGIN_ROOT/agents"/*.md; do
[ -f "$f" ] || continue
name=$(grep "^name:" "$f" 2>/dev/null | head -1 | sed 's/^name: *//' | tr -d '"' | xargs || true)
# Skip internal agents
echo "$INTERNAL_AGENTS" | grep -qw "$name" && continue
desc=$(grep "^description:" "$f" 2>/dev/null | head -1 | sed 's/^description: *//' | tr -d '"' || true)
purpose=$(echo "$desc" | awk '{for(i=1;i<=5&&i<=NF;i++) printf "%s ", $i}' | xargs)
[ -n "$name" ] && echo "| $name | plugin | $purpose |"
done
fi
}
# Phase 4: Validation
validate_setup() {
echo "=== Phase 4: Validation ==="
ERRORS=0
test -f .claude/tasks/templates/PLAN.md.template && echo "✅ PLAN template" || { echo "❌ PLAN template MISSING"; ERRORS=$((ERRORS+1)); }
test -f .claude/tasks/templates/SPEC.md.template && echo "✅ SPEC template" || { echo "❌ SPEC template MISSING"; ERRORS=$((ERRORS+1)); }
test -f .claude/tasks/templates/KNOWLEDGE.jsonl.template && echo "✅ KNOWLEDGE template" || { echo "❌ KNOWLEDGE template MISSING"; ERRORS=$((ERRORS+1)); }
test -f .claude/tasks/templates/phase.md.template && echo "✅ phase template" || { echo "❌ phase template MISSING"; ERRORS=$((ERRORS+1)); }
test -f .claude/tasks/templates/phase-verify.md.template && echo "✅ phase-verify template" || { echo "❌ phase-verify template MISSING"; ERRORS=$((ERRORS+1)); }
test -f .claude/tasks/templates/phase-fix.md.template && echo "✅ phase-fix template" || { echo "❌ phase-fix template MISSING"; ERRORS=$((ERRORS+1)); }
test -f .claude/tasks/templates/phase-final-review.md.template && echo "✅ phase-final-review template" || { echo "❌ phase-final-review template MISSING"; ERRORS=$((ERRORS+1)); }
test -f .claude/rules/avoid.md && echo "✅ avoid.md rules" || { echo "❌ avoid.md MISSING"; ERRORS=$((ERRORS+1)); }
test -f .claude/rules/best-practice.md && echo "✅ best-practice.md rules" || { echo "❌ best-practice.md MISSING"; ERRORS=$((ERRORS+1)); }
test -f .claude/tasks/cfg/brewcode.config.json && echo "✅ Config file" || echo "⚠️ Config MISSING (optional)"
exit $ERRORS
}
# Main dispatch
case "$MODE" in
scan)
scan_project
;;
structure)
create_structure
;;
sync)
sync_templates
;;
review)
copy_review_skill
;;
config)
copy_config
;;
validate)
validate_setup
;;
agents)
collect_agents
;;
all)
scan_project
echo ""
create_structure
echo ""
sync_templates
echo ""
copy_review_skill
echo ""
copy_config
echo ""
validate_setup
;;
*)
echo "Usage: setup.sh <mode>"
echo ""
echo "Modes:"
echo " scan - Scan project structure"
echo " structure - Create directories"
echo " sync - Sync templates from plugin"
echo " review - Copy review skill template"
echo " config - Copy config file"
echo " validate - Validation checks"
echo " agents - Collect agents for CLAUDE.md"
echo " all - Run all phases"
exit 1
;;
esac
{
"knowledge": {
"maxEntries": 100,
"maxTokens": 500,
"priorities": ["❌", "✅", "ℹ️"],
"validation": {
"enabled": true,
"blocklist": true,
"densityCheck": true
}
},
"logging": {
"level": "info"
},
"agents": {
"system": [
"bc-coordinator", "bc-knowledge-manager", "bd-auto-sync-processor",
"Explore", "Plan", "Bash", "general-purpose",
"claude-code-guide", "skill-creator", "agent-creator",
"text-optimizer", "statusline-setup"
]
},
"constraints": {
"enabled": true
},
"autoSync": {
"intervalDays": 7,
"retention": {
"maxEntries": 200
},
"optimize": false,
"parallelAgents": 5
}
}
# KNOWLEDGE.jsonl Format
## Record Structure
```jsonl
{"ts":"ISO8601","t":"type","txt":"knowledge text","src":"agent-name"}
```
## Fields
| Field | Type | Description |
|-------|------|-------------|
| `ts` | string | ISO8601 timestamp (e.g., "2026-01-26T14:00:00") |
| `t` | string | Type: `❌` (avoid), `✅` (best practice), `ℹ️` (info) |
| `txt` | string | Knowledge text - what was learned |
| `src` | string | Source agent name (e.g., "developer", "tester") |
## Types Priority
| Type | Priority | Meaning |
|------|----------|---------|
| `❌` | 1 (highest) | What NOT to do - mistakes, failures |
| `✅` | 2 | Best practices - what works well |
| `ℹ️` | 3 (lowest) | Neutral information - facts |
## Examples
```jsonl
{"ts":"2026-01-26T14:00:00","t":"❌","txt":"Do not use SELECT * in production queries","src":"sql_expert"}
{"ts":"2026-01-26T14:05:00","t":"✅","txt":"Use @Valid annotation for request DTOs","src":"developer"}
{"ts":"2026-01-26T14:10:00","t":"ℹ️","txt":"DBRider resets sequences after each test","src":"tester"}
{"ts":"2026-01-26T15:00:00","t":"❌","txt":"mem_limit only, not deploy.resources in non-Swarm","src":"developer"}
```
## Compaction Rules
1. Remove exact duplicates
2. Merge semantically similar entries
3. Keep `❌` over `✅` over `ℹ️`
4. Limit to N entries per agent (configurable)
5. Preserve most recent entries when trimming
# Phase FR: Final Review
## Agents
{FR_AGENTS}
> Each agent reviews independently. Results merged by manager.
## Scope
Final verification of ALL completed phases against Completion Criteria.
## Completion Criteria
{COMPLETION_CRITERIA}
## Review Checklist
{REVIEW_CHECKLIST}
## Files Changed
{FILES_CHANGED}
## FINAL.md Generation
After all agents PASS:
- bc-coordinator generates `artifacts/FINAL.md`
- Summary of all phases, key decisions, knowledge entries
## Verdict
> Each agent: PASS or FAIL with justification.
> Manager: majority rule (2/3+).
### If FAIL -- Issues Format
| # | Severity | File | Line | Issue | Suggested Fix |
|---|----------|------|------|-------|---------------|
## Artifacts
- Report: `artifacts/{ARTIFACT_DIR}/{AGENT}_output.md` (one per agent)
## Exit Criteria
- All Completion Criteria verified
- No critical or high severity issues
- FINAL.md generated (if PASS)
# Phase {PHASE_NUM}F{ITERATION}: Fix {PHASE_NAME} (Iteration {ITERATION})
## Agent
`{FIX_AGENT}`
## Original Phase
`phases/{ORIGINAL_PHASE_FILE}`
## Issues to Fix
> From verification report: `artifacts/{VERIFY_ARTIFACT_DIR}/{VERIFY_AGENT}_output.md`
{ISSUES_TABLE}
## Files to Fix
{FILES_TO_FIX}
## Constraints
- Fix ONLY the listed issues
- Do NOT refactor unrelated code
- Preserve existing tests
- Run tests after fixes
## Exit Criteria
- All issues from the table addressed
- Tests pass
- No new issues introduced
## Artifacts
- Report: `artifacts/{ARTIFACT_DIR}/{FIX_AGENT}_output.md`
# Phase {PHASE_NUM}V: Verify {PHASE_NAME}
## Scope
Verify Phase {PHASE_NUM} ({PHASE_NAME}) output.
## Agent
`{VERIFY_AGENT}`
## Files to Review
{FILES_TO_REVIEW}
## Checklist
{VERIFICATION_CHECKLIST}
## Against References
{AGAINST_REFERENCES}
## Verdict
> Write PASS or FAIL with justification.
### If FAIL -- Issues Format
| # | Severity | File | Line | Issue | Suggested Fix |
|---|----------|------|------|-------|---------------|
## Artifacts
- Report: `artifacts/{ARTIFACT_DIR}/{AGENT}_output.md`
## Exit Criteria
- All checklist items verified
- Verdict: PASS or FAIL with justification
- If FAIL: issues table populated with actionable items
# Phase {PHASE_NUM}: {PHASE_NAME}
## Role
`{AGENT}` -- {AGENT_ROLE}
## Objective
{OBJECTIVE}
## Context Files
| # | File | Why |
|---|------|-----|
{CONTEXT_FILES}
## References
| # | Type | File | Description |
|---|------|------|-------------|
{REFERENCES}
## Tasks
{TASK_LIST}
## Constraints
{CONSTRAINTS}
## Exit Criteria
{EXIT_CRITERIA}
## Artifacts
- Report: `artifacts/{ARTIFACT_DIR}/{AGENT}_output.md`
- Additional: {ADDITIONAL_ARTIFACTS}
## Knowledge Guidelines
- Extract 3-10 entries per phase
- Priority: `❌` (errors/anti-patterns) > `✅` (confirmed patterns) > `ℹ️` (context)
- Format: `{"ts":"...","t":"❌|✅|ℹ️","txt":"...","src":"{AGENT}"}`
status: pending
current_phase: 0
total_phases: {N}
# Plan: {NAME}
> Work ONLY through Task API (TaskCreate/TaskUpdate/TaskList). NEVER read phases/ files.
> After compact: TaskList() -> Read PLAN.md -> continue.
## Meta
| Field | Value |
|-------|-------|
| Created | {TIMESTAMP} |
| Spec | SPEC.md |
| Knowledge | KNOWLEDGE.jsonl |
| Task Dir | {TASK_DIR} |
| Phases | phases/ |
## KNOWLEDGE Protocol
> Format: `{"ts":"ISO","t":"❌|✅|ℹ️","txt":"...","src":"agent"}`
> Priority: ❌ > ✅ > ℹ️. Only unique, reusable discoveries.
## Completion Criteria
- [ ] {CRITERION_1}
- [ ] {CRITERION_2}
## Agents
### Project Agents
| Agent | Purpose | Model |
|-------|---------|-------|
### Core Agents
| Agent | Purpose |
|-------|---------|
| developer | Implementation, fixes |
| tester | Tests, verification |
| reviewer | Code review, architecture |
| Explore | Code search, research |
| bc-coordinator | Knowledge extraction, report verification |
## Technology Choices
| Choice | Decision | Rationale | Alternatives |
|--------|----------|-----------|--------------|
## Role Constraints
<!-- ALL -->
<!-- /ALL -->
<!-- DEV -->
<!-- /DEV -->
<!-- TEST -->
<!-- /TEST -->
<!-- REVIEW -->
<!-- /REVIEW -->
## Phase Registry
> Manager: TaskCreate for each row. Description = summary + "Full instructions: phases/{file}"
> Parallel group: tasks in same group can run simultaneously.
| # | Phase File | Agent | Subject | Summary | Artifact Dir | Blocked By | Parallel |
|---|------------|-------|---------|---------|--------------|------------|----------|
| 1 | phases/1-{name}.md | {AGENT} | {SUBJECT} | {SUMMARY} | 1-1e | - | A |
| 1V | phases/1V-verify-{name}.md | {VERIFY_AGENT} | Verify {name} | Verify phase 1 output | 1-1v | 1 | - |
## Execution Protocol
> After EACH agent: WRITE report -> CALL bc-coordinator (ALWAYS)
> Task API (TaskCreate/TaskUpdate/TaskList) is source of truth. Phase Status table is observability only.
### Task Creation
FOR each row in Phase Registry:
TaskCreate(subject="Phase {#}: {Subject}", description="Phase {#}: {Summary}\n\nFull instructions: phases/{Phase File}\nTask dir: {TASK_DIR}\nArtifacts: artifacts/{Artifact Dir from Phase Registry}/\nKNOWLEDGE: KNOWLEDGE.jsonl", activeForm="{Present continuous of Subject}")
THEN set dependencies per Blocked By column.
### Execution Loop
1. TaskList() -> find tasks: status=pending, blockedBy=[]
2. Same Parallel group -> spawn in ONE message
3. Per task: TaskUpdate(in_progress) -> Task(agent) -> WRITE report to artifacts/{Artifact Dir from Phase Registry}/ -> CALL bc-coordinator -> TaskUpdate(completed)
4. Repeat while pending tasks remain
5. All completed -> bc-coordinator mode:finalize
### Coordinator Protocol
| Phase | Coordinator Does | Does NOT Do (Task API) |
|-------|-----------------|----------------------|
| Execution (N) | Knowledge extraction, report verification | Status update |
| Verification (NV) | Knowledge extraction, report verification, phase validation | Status update |
| Final Review (FR) | FINAL.md generation, knowledge extraction | Status update |
| Finalize | status -> {finished\|failed} (line 1 PLAN.md), FINAL.md generation | - |
### Failure Protocol
When NV finds issues:
1. Write phases/{N}F{I}-fix-{name}.md with issues from verification report
2. TaskCreate(subject="Fix phase {N} issues (iter {I})")
3. TaskCreate(subject="Re-verify phase {N} (iter {I+1})", blockedBy=[fix task])
4. Max 3 iterations -> Escalation
### Escalation
| After | Action |
|-------|--------|
| 1 fail | R&D task: explore root cause |
| 2 fails | Split phase into sub-phases |
| 3 fails | Upgrade model (sonnet->opus), reassign, AskUserQuestion |
### Failure Cascade & Deadlock Recovery
When escalation exhausted (task permanently failed):
1. TaskUpdate(failedTaskId, status="failed")
2. Persist to KNOWLEDGE.jsonl: {"ts":"...","t":"❌","txt":"Phase {N} permanently failed: {reason}","src":"manager"}
3. Cascade failure to ALL transitive dependents: TaskList() -> TaskUpdate(T.id, status="failed") for each blocked task
4. Independent tasks (no dependency on failed task) continue normally
5. Deadlock check: pending+unblocked=0 AND in_progress=0 AND blocked>0 -> abort all blocked, Finalize(status="failed")
6. bc-coordinator mode:finalize with status="failed" generates failure summary in FINAL.md
## Handoff
After compact:
1. TaskList() - current task state
2. Read PLAN.md - protocol and Phase Registry
3. DO NOT read phases/ - they are for agents
4. Continue with current in_progress or next pending task
5. WRITE report -> CALL coordinator after EVERY agent (ALWAYS)
## Reports
| Field | Path |
|-------|------|
| Artifacts | artifacts/ |
| Final | artifacts/FINAL.md |
| Report | artifacts/{P}-{N}{T}/{AGENT}_output.md |
## Phase Status
| # | Status | Started | Completed | Iterations |
|---|--------|---------|-----------|------------|
# {NAME}
> {TIMESTAMP}
## Goal
{GOAL}
## Scope
| In | Out |
|----|-----|
| {IN_SCOPE} | {OUT_OF_SCOPE} |
## Original Requirements
{FULL_REQUIREMENTS}
## User Q&A
| # | Question | Answer |
|---|----------|--------|
## Analysis
### Architecture
{ARCHITECTURE_ANALYSIS}
### Data & State
{DATA_STATE_ANALYSIS}
### Impact
| Area | Files | Change |
|------|-------|--------|
## Context Files
| ID | File | Purpose |
|----|------|---------|
## Risks
| Risk | Impact | Mitigation |
|------|--------|------------|
## Decisions
| Decision | Rationale |
|----------|-----------|
## Research
| Area | Agent | Key Findings |
|------|-------|--------------|