- name
- team-develop
- description
- Orchestrate Rust and TypeScript development using agent teams with peer-to-peer communication: classify the task into a chain, spawn specialist teammates, run the fix-review cycle, commit and open a PR. Requires CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1; CLAUDE_CODE_ENABLE_TODO_TOOLS=1 enables shared task-list coordination on Claude Code 2.1.233+.
- when_to_use
- 'create dev team', 'start team development', 'launch agent team', 'team workflow', 'collaborative development', 'implement this with the team'.
- argument-hint
- [task-description]
- allowed-tools
- Bash(printenv *), Bash(git branch *), Bash(git status *), Bash(test *), Bash(echo *), Bash(wc *), Bash(tr *)
# Team Develop Orchestration
You act as **team lead**. Coordinate specialist agents to implement the task.
**Task**: $ARGUMENTS
> You do NOT implement code yourself. ALL implementation is delegated. If you are about to write or edit a source file — STOP. Spawn the appropriate agent.
> The lead drift warning from official docs: "Sometimes the lead starts implementing tasks itself instead of waiting for teammates." This must never happen.
## Preflight (collected automatically when this skill loads)
- Agent teams flag: !`printenv CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS || echo unset`
- Task tools flag: !`printenv CLAUDE_CODE_ENABLE_TODO_TOOLS || echo unset`
- Current branch: !`git branch --show-current 2>/dev/null || echo not-a-git-repo`
- Uncommitted changes: !`git status --porcelain 2>/dev/null | wc -l | tr -d ' '`
- Cargo.toml: !`test -f Cargo.toml && echo present || echo missing`
- tsconfig.json: !`test -f tsconfig.json && echo present || echo missing`
- package.json: !`test -f package.json && echo present || echo missing`
Check the values above before spawning anything. STOP and tell the user when:
1. Agent teams flag is not `1` — without agent teams, `Agent()` calls spawn background subagents (Claude Code 2.1.232+ default), teammates never form, and every WAIT step below stalls
2. Current branch is `main`/`master` — create a feature branch first
3. Uncommitted changes is not `0` — the working tree must be clean
4. Cargo.toml, tsconfig.json, and package.json are all `missing` — no supported stack (monorepo with manifests only in subdirectories: ask the user which stack to pass)
**Stack**: derive `{stack}` from the markers — `Cargo.toml` → `rust`; `tsconfig.json` or `package.json` → `typescript`; both → `rust,typescript`. Narrow it when the task clearly touches one language only. State it next to the detected chain in Step 0; every spawn prompt carries it (see the Team Communication Template), so teammates skip their own detection.
Agent teams never form in non-interactive sessions (`claude -p`, SDK): a named spawn there runs as an ordinary subagent. Do not run this skill headless.
> For complex features that need a written spec before any code: pick the `spec-driven` chain in Step 0 — team-develop runs the SDD pipeline end-to-end (architect → critic → sdd → reviewer → follow-up issue) and produces a versioned spec under `specs/{feature-slug}/`. Run `/dev-agents:sdd` standalone only when you want SDD outside of a team. The existing pre-existing spec convention (`.local/specs/`) still works for the `new-feature` chain — architect and developer pick it up automatically.
## Step 0: Classify Task
Before any team setup, classify the task from `$ARGUMENTS` and confirm with the user. The full pipeline (Steps 1–10) is wasteful for bug fixes, refactors, and security work — pick the right chain up front.
| Signal in task text | Type | Pipeline |
|---|---|---|
| "fix", "bug", "broken", "panic", "regression", crash, stack trace, file:line reference | `bug-fix` | [Workflow: Bug Fix](#workflow-bug-fix) |
| "refactor", "rename", "extract", "restructure", "cleanup", "move module" (behavior preserved) | `refactoring` | [Workflow: Refactoring](#workflow-refactoring) |
| "vulnerability", "CVE", "RUSTSEC", "GHSA", "npm audit", "audit", "unsafe review", credential leak | `security` | [Workflow: Security](#workflow-security) |
| "docs", "README", "mdBook", "doc comment", "rustdoc", "TSDoc", "user guide", "API reference" | `docs` | [Workflow: Documentation](#workflow-documentation) |
| "bump", "update dependency", "cargo update", "npm update", "pnpm update", "upgrade {package}", lockfile changes | `dependency` | [Workflow: Dependency Bump](#workflow-dependency-bump) |
| "optimize", "speed up", "reduce allocations", "profile", "benchmark", "hot path", latency/throughput numbers | `performance` | [Workflow: Performance](#workflow-performance) |
| "CI", "GitHub Actions", "workflow", "justfile", "clippy.toml", "rustfmt.toml", `.cargo/config.toml`, `eslint.config.*`, `tsconfig.json`, `biome.json` | `ci-cd` | [Workflow: CI/CD](#workflow-cicd) |
| "implement", "add", "build", "design", new module/crate/package, greenfield | `new-feature` | Full pipeline (Steps 1–10 below) |
| "spec", "specification", "design doc", "RFC", "proposal", "BRD", "SRS", "NFR", "blueprint", "feasibility", "design only", "spec only", "research before implementing", "deep design", "draft a spec", "produce a spec" | `spec-driven` | [Workflow: Spec-Driven](#workflow-spec-driven) |
| Task already lists concrete required changes (file paths, exact edits) | reduce one level | Skip the lead agent (architect/debugger/security/perf) — start from developer in the matching chain |
| Ambiguous / multiple signals | see rules below | — |
State the detected type and matching chain, then **wait for confirmation** before spawning anything. Example:
```
Detected: bug-fix — task mentions "fix panic in parser at src/parse.rs:142".
Stack: rust (Cargo.toml present).
Pipeline: debugger → developer → tester → reviewer → commit.
Proceed? [y / full / refactor / security / docs / dependency / performance / ci-cd]
```
Do NOT skip this step. Do NOT default silently to the full pipeline.
### Mixed-Signal Rule
When the task hits multiple rows of the table:
1. **Identify the goal verb** — the verb that names the *outcome*, not the means. "Refactor parser to fix panic" → goal is `fix` (bug-fix) — refactor is the technique. "Update tokio to patch RUSTSEC-2026-NNNN" → goal is patching the advisory (security), bump is the means.
2. **If two rows tie on goal verb**, pick the heavier chain — heavier here means "more validators". Order (light → heavy): `docs` < `ci-cd` < `dependency` < `bug-fix` < `refactoring` < `performance` < `security` < `new-feature`.
3. **`spec-driven` sits outside this order** — it is the explicit "design first, ship spec, defer code" mode. Pick it only when the user explicitly asks for a spec/RFC/design doc, or when the scope is large enough that the architect alone cannot commit to an implementable plan in one pass. If `spec-driven` and `new-feature` both fit, ask the user — the choice is "do we want a spec now and code later, or one combined PR?".
4. **If still ambiguous**, ask the user — list the candidate chains and request a choice.
### Escalation Rule
If during execution an agent reports a problem that breaks the assumptions of the chosen chain — e.g. the debugger in a bug-fix finds the root cause is an architectural defect, the developer in a refactoring breaks behavior in a way that needs design rethink, the perf engineer finds the hot path requires structural changes, or the architect in a `new-feature` cannot collapse the design into one implementable plan and asks for more upstream thinking — the lead **stops the chain** and:
1. Sends `shutdown_request` to all idle agents.
2. Summarizes the finding to the user.
3. Proposes upgrade to a heavier or different chain (most commonly `new-feature`, `refactoring`, or `spec-driven` when the scope outgrows a single implementation pass) and waits for confirmation before re-spawning.
The reverse downgrade is also valid: if the `spec-driven` sdd agent reports that the scope is small enough to implement directly, the lead pauses the chain and proposes downgrading to `new-feature` (skip spec, go straight to code). Do not silently morph the chain mid-flight — the user must approve the scope change either way.
## Step 1: Load Tools
```
ToolSearch("select:SendMessage")
ToolSearch("select:TaskCreate,TaskUpdate,TaskList,TaskGet")
```
If the Task tools are not found: Claude Code 2.1.233+ omits them on current models unless `CLAUDE_CODE_ENABLE_TODO_TOOLS=1` is set (e.g. in the `env` block of `settings.json`). Tell the user, then continue in **message-based fallback**: skip every TaskCreate/TaskUpdate call in this workflow, keep the task DAG and its blocked-by order yourself, drop the Tasks line from the spawn template, and sequence agents by WAITing for each handoff message before spawning dependents.
## Step 2: Task Setup
The team forms implicitly when you spawn the first teammate (requires `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`) — there is no team-creation call. Create all tasks upfront and set dependencies (message-based fallback: skip the TaskCreate/TaskUpdate calls; the table stays your execution order):
| Task | Owner | Description |
|------|-------|-------------|
| plan | architect | Architecture design |
| critique | critic | **Adversarial critique of architecture (MANDATORY)** |
| implement | developer | Implementation |
| validate-tests | tester | Test coverage |
| validate-perf | perf | Performance analysis |
| validate-security | security | Security audit |
| validate-critique | impl-critic | **Adversarial critique of implementation (MANDATORY)** |
| review | reviewer | Code review |
| fix-issues | developer | Fix all review issues |
| re-review | reviewer | Verify fixes |
| commit | teamlead | Commit and PR |
```
TaskUpdate(taskId: "critique", addBlockedBy: ["plan"])
TaskUpdate(taskId: "implement", addBlockedBy: ["critique"])
TaskUpdate(taskId: "validate-tests", addBlockedBy: ["implement"])
TaskUpdate(taskId: "validate-perf", addBlockedBy: ["implement"])
TaskUpdate(taskId: "validate-security", addBlockedBy: ["implement"])
TaskUpdate(taskId: "validate-critique", addBlockedBy: ["implement"])
TaskUpdate(taskId: "review", addBlockedBy: ["validate-tests","validate-perf","validate-security","validate-critique"])
TaskUpdate(taskId: "fix-issues", addBlockedBy: ["review"])
TaskUpdate(taskId: "re-review", addBlockedBy: ["fix-issues"])
TaskUpdate(taskId: "commit", addBlockedBy: ["re-review"])
```
## Team Communication Template
Substitute `{agent-role}` and `{stack}` (drop the Tasks line in message-based fallback), then include verbatim in every spawn prompt:
```
You are a teammate in this session's agent team, role `{agent-role}`.
Stack: {stack}
Tasks: ToolSearch("select:TaskCreate,TaskUpdate,TaskList,TaskGet"); update your task to in_progress on start, completed on finish.
Communication: SendMessage(to: "team-lead", message: "...", summary: "..."). Respond to a shutdown_request with SendMessage(to: "team-lead", message: {type: "shutdown_response", request_id: "<echo the request_id>", approve: true}).
Code ownership: only developer edits source. Only team-lead commits.
Handoff (MANDATORY): BEFORE any other work, call Skill(skill: "dev-agents:agent-handoff"). Before messaging the lead, write your handoff file and include inline frontmatter + path in the message.
```
## Teammate Outcomes
Every WAIT step below ends with one of these outcomes. Handle them the same way everywhere:
| Outcome (idle notification or message) | Lead action |
|---|---|
| Handoff frontmatter + path received | Route on the frontmatter as described in the step |
| "stopped at its N-turn limit" (partial result) | `SendMessage(to: "{name}", summary: "Continue", message: "Continue from where you stopped: finish the handoff file and send its frontmatter + path")`. On a second limit, report to the user |
| `failed: <error>` (API error, rate limit) | Report the error to the user; to continue, re-spawn the role under a fresh suffixed name (`reviewer-2`) with the accumulated handoffs |
| Idle without a handoff file | The task is not done: resume with `SendMessage` to the same name, never spawn a duplicate |
Naming: never reuse a name for a fresh spawn — a new agent with an existing name shadows the old one and breaks `SendMessage` routing. Resume existing teammates with `SendMessage` when their context is useful (fix cycles, redesign after a critic verdict); use suffixed names (`developer-2`) when a clean context is wanted.
Isolation: never pass `isolation` on a teammate spawn, even when the Agent tool suggests `isolation: "worktree"` for parallel writers. A named call with `isolation` starts a plain subagent outside the team. Parallel developers stay apart through module ownership; validators are report-only.
## Step 3: Architect
```
Agent(subagent_type: "dev-agents:architect", name: "architect",
prompt: "{template}\n\nDesign architecture for: {feature-description}")
TaskUpdate(taskId: "plan", owner: "architect", status: "in_progress")
```
WAIT for handoff frontmatter + path. `TaskUpdate(taskId: "plan", status: "completed")`.
## Step 4: Critic (MANDATORY)
```
Agent(subagent_type: "dev-agents:critic", name: "critic",
prompt: "{template}\n\nCritique the architecture. Report findings — do NOT write code.\n\nHandoffs:\n{accumulated frontmatters}")
TaskUpdate(taskId: "critique", owner: "critic", status: "in_progress")
```
WAIT for critic. Check verdict from inline frontmatter:
- `critical` or `significant` → `SendMessage(to: "architect", ...)` with the critic handoff for redesign (resume, do not re-spawn), then `SendMessage(to: "critic", ...)` to re-run the critique
- `approved` or `minor` → proceed to developer
## Step 5: Developer(s)
Check `.local/specs/` for an existing spec, then analyze the architect's plan: **can implementation be split into independent subtasks?**
Subtasks are independent when ALL hold: separate modules/crates/packages, no shared mutable state, no cross-task type dependencies, can be tested in isolation.
**Independent** — spawn one developer per subtask:
```
TaskCreate(id: "implement-{a}", description: "Implement {a}")
TaskCreate(id: "implement-{b}", description: "Implement {b}")
TaskUpdate(taskId: "implement-{a}", addBlockedBy: ["critique"])
TaskUpdate(taskId: "implement-{b}", addBlockedBy: ["critique"])
// update validate-* to block on all implement-* tasks
Agent(subagent_type: "dev-agents:developer", name: "developer-a",
prompt: "{template}\n\nImplement only: {a description}. Do NOT touch modules owned by parallel developers.\n\nHandoffs:\n{accumulated frontmatters}")
Agent(subagent_type: "dev-agents:developer", name: "developer-b",
prompt: "{template}\n\nImplement only: {b description}. Do NOT touch modules owned by parallel developers.\n\nHandoffs:\n{accumulated frontmatters}")
```
WAIT for ALL parallel developers before validation. Accumulate all handoffs.
**Dependent** — single developer in sequence:
```
Agent(subagent_type: "dev-agents:developer", name: "developer",
prompt: "{template}\n\nImplement based on architect's plan.\n\nHandoffs:\n{accumulated frontmatters}")
TaskUpdate(taskId: "implement", owner: "developer", status: "in_progress")
```
WAIT for developer's handoff.
## Step 6: Parallel Validation (spawn all 4 simultaneously)
```
Agent(subagent_type: "dev-agents:testing-engineer", name: "tester",
prompt: "{template}\n\nValidate test coverage. Report findings — do NOT edit source.\nHandoffs: {accumulated}")
Agent(subagent_type: "dev-agents:performance-engineer", name: "perf",
View on GitHub