teams-setup — install an agent team

Caution

Generic agents handle everything — and excel at nothing. A frontend task routed to a generic backend agent loses domain context, triggers wrong tools, and produces half-correct results. Claude Code has no native way to scope agents to domains or enforce routing between them.

Tip

/brewcode:teams-setup install analyzes your codebase, proposes agent variants (Minimal / Balanced / Maximum), creates each agent via quorum-reviewed scaffolding, and writes a trace.jsonl log so the team self-improves via /brewcode:teams-setup upgrade. Every team also gets a fixed review-only intent-guard member — see Intent guard below.

Quick reference

FieldValue
Command/brewcode:teams-setup
Arguments[status [name] | install [name] [prompt] | upgrade [name] | enable [name] | disable [name] | uninstall [name] | purge [name]]
No-arg defaultstatus of the first existing team, install of a team named default when none exists
enable / disablePark/unpark the roster’s agent files (renamed to/from <agent>.md.disabled) — intent-guard is exempt
Version stampingteam.md header + agent frontmatter carry the plugin version; write is refused if the version cannot be resolved
Modelopus
ToolsRead, Write, Edit, Glob, Grep, Bash, Task, AskUserQuestion, Skill

When to use

  • New project onboarding — turn architectural analysis into a ready-to-use agent roster
  • Large codebase — split domains (API, data, frontend, infra, testing) so each agent stays focused
  • Repeated failures — a specific domain keeps producing poor results; install or upgrade that agent
  • Maintenancestatus to see health, upgrade to tune underperformers, uninstall to archive trace data and drop inactive agents, purge to remove the team entirely

Examples

# Install a balanced team for the current project
/brewcode:teams-setup install my-team

# Install with a free-form hint about what matters
/brewcode:teams-setup install my-team "focus on API and data pipeline domains"

# Check team health and success rates
/brewcode:teams-setup status my-team

# Tune agents that are underperforming
/brewcode:teams-setup upgrade my-team

# Park the roster's agent files without deleting anything
/brewcode:teams-setup disable my-team

# Bring a parked team back
/brewcode:teams-setup enable my-team

# Archive trace data, remove inactive agents
/brewcode:teams-setup uninstall my-team

# Delete the team outright — agents, framework dir, trace and its archive
/brewcode:teams-setup purge my-team

Modes

ModeCommandWhat it does
status/brewcode:teams-setup status <name>Read-only health report: success rates, open issues, insights, recommendations
install/brewcode:teams-setup install <name> [prompt]Analyze codebase → propose team (+ fixed intent-guard) → create agents → quorum review → framework setup
upgrade/brewcode:teams-setup upgrade <name>Read trace data → classify agents → tune or replace underperformers
enable/brewcode:teams-setup enable <name>Move each roster member’s agent file from <agent>.md.disabled back to <agent>.md — reactivates without touching team.md or trace data
disable/brewcode:teams-setup disable <name>Park each roster member’s agent file as <agent>.md.disabled — Claude Code stops discovering it, nothing is deleted
uninstall/brewcode:teams-setup uninstall <name>Archive trace entries, remove inactive agents, reset cursor
purge/brewcode:teams-setup purge <name>Total removal, no menus and no archive: every domain agent from the team.md roster, then .claude/teams/<name>/ including trace-archive.jsonl. One explicit confirmation, not recoverable

enable / disable park the roster, not delete it

disable moves each roster member’s .claude/agents/<agent>.md to <agent>.md.disabled — Claude Code stops discovering the agent as a project agent, but the file body is byte-identical either way, and enable moves it straight back. intent-guard is always skipped (SKIP:intent-guard (shared with superreview-setup)) because that file may belong to an install with nothing to do with this team. team.md and the trace log are untouched by either verb. The same keyword guard is what keeps purge a mode rather than a team name — earlier versions treated any unknown first word as a team name, so /brewcode:teams-setup purge installed a team called purge.

Fixed: disable no longer reports success on a roster it could not parse

toggle-team.sh disable used to print MOVED:0 alongside a green ✅ disable and exit 0 even when its ## Agents table parser never found the header row — every agent file stayed live while the run claimed success. The parser now recognizes a padded separator row (| ------ |, not just |---|) and hard-fails instead of silently reporting zero moves when it never passes the header. Roster agent ids are also validated against ^[a-z0-9][a-z0-9-]*$ — uppercase and _ are rejected — so a malformed team.md row is reported and skipped rather than interpolated into a file path.

purge never deletes .claude/agents/intent-guard.md. That file is shared with /brewcode:superreview-setup and may belong to an install that has nothing to do with this team; purge reports it as kept. A team name that does not exist stops the run — nothing is “purged” that was never installed.

Why the -setup suffix

teams-setup installs a mechanism — a roster of agents in .claude/agents/ that you use afterwards instead of the skill. Recurring tools like /brewcode:agents keep a bare name because you run them again and again. The canonical mode vocabulary across setup skills is status, install, upgrade, enable, disable, uninstall, purge; teams implements all seven.

Flow

  1. Parse + confirm

    Mode, team name, and optional prompt are extracted from arguments. Current team state (if any) and agent roster are loaded. The plan is shown via AskUserQuestion before any mutation.

  2. Project analysis

    3–5 Explore agents run in parallel: code structure, existing agents, tech stack, CI/CD, domain boundaries. Results are consolidated into a single analysis document before the team proposal.

  3. Team proposal + model selection

    Three variants presented, domain agents only: Minimal (5), Balanced (10–12, recommended), Maximum (15–20); intent-guard is a fixed non-domain addition to every variant (see Intent guard). User selects variant and default model (Opus / Sonnet / Haiku / Mixed) for domain agents; intent-guard keeps the fixed model: sonnet its template ships with. Final agent list confirmed before creation.

  4. Agent creation

    ONE agent file per spawn — never “create the whole team” in one task. Batches of 3–4 agent-creator spawns run in parallel, each carrying the full six-field brief (see Delegation below). After each batch, /brewtools:text-optimize compresses agent instructions.

  5. intent-guard (C3-IG)

    Exactly once, always — outside the batches above. Creates or reuses .claude/agents/intent-guard.md via the writer shared with /brewcode:superreview-setup (generate.sh emit-agent); see Intent guard for the full write/reuse contract.

  6. Quorum review pipeline (C5–C9)

    3 reviewers analyze all agents in parallel (instruction quality, domain accuracy, architecture consistency). Issues confirmed by 2/3 pass the threshold. A verification agent filters false positives. agent-creator fixes critical and important findings. Re-verify confirms no regressions. Skip with —skip-review.

  7. Framework setup

    .claude/teams/<name>/team.md (roster) and trace.jsonl (empty log) created, then trace-ops.sh is copied next to them — the project-local tracer every generated agent calls (see Tracing). verify-team.sh validates the structure and stops if anything is missing.

  8. Epilogue: CLAUDE.md + final status

    Optionally writes a Teams section to project or local CLAUDE.md — purge removes that section instead. Always outputs the full Team Status table (agents, tasks tracked, success rate, open issues) so you know exactly what was created; after purge there is no team left, so the purge summary is printed instead.

Delegation

Why one agent file per spawn

A big task handed to one agent = an agent gone for an hour: you cannot observe it, cannot correct it, and it usually drifts off-target.

One subagent = ONE bounded unit — here, ONE agent file: roughly 5 files, roughly 10 steps. A 12-agent roster is 12 spawns, batched 3–4 per message in parallel; the C5 review and the C8 fix pass fan out the same way.

Every spawn prompt carries six fields. A bare one-line task is never enough:

FieldContent
GOALthe overall task and why it exists — the point beyond the file edit
ROLEwhat this agent owns; what it must NOT touch
SCOPEexact paths/commands in bounds + explicit out-of-bounds
CONTEXTwhat is already done, by whom, what runs in parallel — trimmed to what THIS agent needs
CONSUMERwho or what uses the result next, and the shape it must fit
DONEacceptance criteria + the exact report shape you want back

In C3 that means each agent-creator owns exactly .claude/agents/{name}.md, is told which colleagues its batch-mates are building (stay off their domains, do not duplicate their triggers), and knows its description line lands in the team.md roster row. In C8 the fixer is told the finding is already verified by 2/3 reviewers plus the C7 double-check — do not re-litigate it — and that C9 will re-verify the same file for regressions.

Every code/test spawn brief in this skill also carries the etalon-first instruction verbatim: find the closest well-built counterpart in the repo and follow its principles, in addition to conventions, rules and docs — never instead of them.

Intent guard

Tip

Every team gets a fixed review-only intent-guard member outside the domain-agent count — Minimal (5), Balanced (10-12), Maximum (15-20) all mean domain agents; picking “Custom” cannot drop it. A model can follow an approved plan for hours and still drift from what was actually asked — intent-guard is the check for that, not a code reviewer and not a smoke test.

PropertyValue
Counted in the roster size?No — outside 5 / 10-12 / 15-20, cannot be dropped
ComparesWhat was ASKED (tracker ticket, Slack thread, quoted requirements, the user’s verbatim words, or the chat request itself) against what was DELIVERED
Source hierarchyFive tiers; tier 1 (external/original) always wins and is labeled in the report. An absent tier 1 is normal — the chat request becomes the top source. Sources are never invented
EvidenceCheap only: session transcript, file/directory names, git diff --stat, dependency manifests, doc headings — never full-file code reads, builds, tests, or linters
Drift it huntsBuilding something other than asked, over-engineering for an unplanned scale, interface/factory bloat where a direct implementation was requested, file explosion, test bloat against a minimal-tests policy, an unnecessary dependency, architecture substitution, ignored CLAUDE.md/rules instructions, silent skips, over-claimed completion, unrequested artifacts — open-ended examples, not a closed checklist
ToolsRead-only. Invoked explicitly by name at review time only — never competes for auto-activation with the team’s development agents

One writer, shared with superreview. teams-setup does not author intent-guard.md. It runs generate.sh emit-agent from the sibling /brewcode:superreview-setup skill, which creates-or-reuses the file and prints INTENT_GUARD: CREATED or INTENT_GUARD: REUSE. A USABLE existing agent is reused untouched — usable meaning non-empty, carrying name: intent-guard frontmatter, and free of unresolved placeholders. An empty, truncated or placeholder-laden file is treated as absent and recreated. agent-creator is spawned only on CREATED, to replace three seeded generic blocks (project invariants, drift examples, evidence commands) with project-specific content; it never authors the file.

Fixed in v5.1.0

The corruption check used to match ${BASE}-style shell expansions inside an already-adapted evidence block as an unresolved placeholder, so a healthy reused agent could be wrongly deleted and re-emitted. The scan now strips ${VAR} references before matching {PLACEHOLDER} tokens. Separately, the write verification used an unanchored count for the template-header marker, which also matched a tail comment that legitimately names it — every healthy install hit the same false-fail loop back into re-adaptation. Both counts are now anchored to the literal artifact line, not prose about it.

Excluded from:

FlowWhy
Quorum reviewer role (C5/C7/C9)Not a general reviewer — no code domain to judge others by
Implementation ownershipNever accepts a build/fix task
uninstall inactive-agent sweepEmits no trace records by design; zero activity is normal, not grounds for deletion
text-optimize post-processingWould reword its deliberately short, review-only description into a normal domain description

Legacy teams. verify-team.sh does not hard-fail a team created before this change: missing team.md row → WARN with a runnable remediation command, still passes. Row listed but .claude/agents/intent-guard.md missing → real FAIL.

Tracing

Every generated agent logs what it took, refused, completed or failed to .claude/teams/<name>/trace.jsonl, and that log is the only input status and upgrade have. The agent reaches it through a project-local copy of the tracer:

bash ".claude/teams/<name>/trace-ops.sh" add ".claude/teams/<name>" "$SID" "<agent>" "track" "took" "<task>"

The path is repo-relative on purpose. A file in .claude/agents/ is not plugin-owned, so ${CLAUDE_PLUGIN_ROOT} is not substituted inside it and no *_PLUGIN_ROOT environment variable exists there — a plugin path in a generated agent resolves to nothing and the call silently no-ops. Install step C4 therefore cps trace-ops.sh into the team directory and stops the run if the copy fails.

Upgrade an existing team

Teams created by an earlier version point their agents at a plugin path that has been dead since 4.0.0, so not one trace entry was ever written: status reports 0 tasks, and upgrade phase U2 classifies the entire roster as Inactive and proposes deleting it. Run /brewcode:teams-setup upgrade <name> once — the cp is idempotent and part of the flow, so the team self-heals. verify-team.sh also WARNs on a missing trace-ops.sh and prints the exact cp line to run by hand. Until then, treat any “inactive agent” verdict on an old team as an artefact, not evidence.

Guardrails in every team agent

The agent template carries two blocks, so every DOMAIN member of the team inherits them (intent-guard comes from a different template — see the third row):

GuardrailApplies toWhat it says
Return ContractEvery team agent, unconditionallyA named ## Return Contract section: verdict first, <=30 lines, path:line, no file bodies / command output / logs / preamble. Bulk material goes to .claude/reports/<YYYYMMDD-HHMMSS>_<name>/ and only the path returns. When /brewtools:agent-return-setup is installed, the same guard enforces it at the token level (~1000 est-tokens blocks for compression, ~2500 routes the detail to a report).
Scope FitOnly agents whose domain writes code, scripts, SQL, schemas or infraBuild for the actual scale and the problems that exist today, not imagined load or speculative abstraction — a 10-user app does not need hardening against DB lock contention. After finishing, one pass: can this be simpler — fewer files, less config, less indirection?
Etalon-firstSame gating as Scope Fit — code/script/SQL/schema/infra domains onlyBefore writing a class, module or test, find the closest well-built existing one in this repo (.claude/convention/* checked first) and take its principles — additive to conventions, rules and docs, never a replacement
Anti-drift reviewintent-guard only — not built from these two blocksCompares ASKED vs DELIVERED at review time, explicit invocation only — see Intent guard above

agent-creator deletes the Scope Fit and Etalon-first pair together for research, docs, and review-only domain members; the Return Contract stays in all team agents, including intent-guard, which carries it via its own ## Output section rather than this one. This matters most on a 12-agent roster, where a single verbose member can cost more context than the rest of the batch combined.

Legacy team missing the Return Contract

verify-team.sh checks every roster agent (intent-guard exempt — it comes from the superreview template, not this one) for the contract’s opening line (Verdict first, <=30 lines) and WARNs, never fails, when a pre-existing team predates it. Fix: /brewcode:teams-setup upgrade &lt;name&gt;, which re-adds ## Return Contract from references/agent-template.md.

Internals

Framework files

FilePurpose
.claude/teams/<name>/team.mdAgent roster: names, domains, missions, health status. Source of truth for team composition.
.claude/teams/<name>/trace.jsonlJSONL log per session: tasks (took/refused/completed/failed), issues (by severity), insights (by category). Written via trace-ops.sh add — append-only, ~96% token savings vs full reads.
.claude/teams/<name>/trace-ops.shThe tracer itself, copied from the plugin at install (C4) and re-copied on every upgrade. The only tracing path a generated agent can resolve. Deleted by purge, kept by uninstall.
.claude/teams/<name>/trace-archive.jsonlArchived entries after uninstall. Cursor reset after archiving. purge deletes this file along with everything else.

Version and ownership

FieldWhereValue
Header rowsteam.md: | Version |, | Generated by |, | Last update |Plugin version, brewcode:teams-setup, install/upgrade date
FrontmatterEach .claude/agents/<member>.mddoc_type: llm, version: "X.Y.Z", generated_by: "brewcode:teams-setup", last_updated: "YYYY-MM-DD"
Sourcedetect-mode.sh reads .claude-plugin/plugin.jsonResolves before any write; if it cannot, the run exits 1 (ERROR:cannot resolve plugin version) instead of stamping a fake value
Staleness check/brewcode:setup-statusReads the | Version | row and flags a team installed at an older plugin version than the one currently running

Task Acceptance Protocol

Every generated agent contains a self-selection protocol. When a task arrives, the agent evaluates three questions before accepting:

  1. Domain check — “Is this my domain?” If not, refuses and names a better-suited colleague from team.md.
  2. Duplicate check — “Has this been done?” If yes, refuses and links the existing result in trace.jsonl.
  3. Best candidate — “Is a colleague better suited?” If yes, redirects without accepting.

Agent health classification

HealthCriteriaAction
Green>70% success, active in recent tasksNo action needed
Yellow30–70% success or many refusalsTune instructions via upgrade
Red<30% success or inactiveReplace or remove via upgrade

Immutable vs mutable traits

TraitMutable?If wrong
NameNoDelete + create new
Base roleNoDelete + create new
CharacterYesUpdate during tuning
InstructionsYesUpdate during tuning

Integration with core skills

Team agents are preferred by any skill that spawns domain work when matching domains are found. Priority: team agent → project agent → plugin agent.

🤖

Agents skill

Create individual domain agents — the same scaffolding teams use under the hood.

📋

setup-status

Read-only dashboard: is this team installed, stale or missing, and what command fixes it.

🔗

GitHub source

Source code, scripts, and framework file templates.

📄

Brewcode overview

All brewcode skills — setup, agents, conventions, review, and more.

Updating plugins

Use /brewtools:plugin-update to check and update the brewcode plugin suite in one command. See the FAQ for details.