teamcast
v1.2.0
Published
YAML-driven CLI to design, validate, and generate multi-target agent teams for Claude Code and Codex
Downloads
1,319
Maintainers
Readme
TeamCast
CLI to design, generate, and validate multi-target agent teams for Claude Code and Codex from a single manifest.
Define your agent team in one teamcast.yaml file. TeamCast validates the manifest, generates .claude/ and/or .codex/ config files, and keeps generated output in sync with the source config.
Install
Requires Node.js 24 or newer.
npm install -g teamcastOr run without installing:
npx teamcast <command>Community
- Contribution guide: CONTRIBUTING.md
- Code of conduct: CODE_OF_CONDUCT.md
- Security policy: SECURITY.md
- Bug reports and feature requests: use the GitHub issue templates
- Pull requests: use the repository PR template and run
npm testplusnpm run buildbefore opening one
Quick Start
# Initialize a new team with the interactive wizard
teamcast init
# Or skip the wizard and use a preset directly
teamcast init --preset feature-team --target both
# Generate files for the targets defined in teamcast.yaml
teamcast generate
# Validate the manifest
teamcast validateAfter generate, your project will have files for the selected target(s):
- Claude target:
.claude/agents/<name>.md- one file per agent.claude/skills/<skill>/SKILL.md- one stub file per unique skill.claude/settings.json- permissions and sandbox config.claude/settings.local.json- local Claude settings when enabledCLAUDE.md- team documentation for Claude Code
- Codex target:
.codex/config.toml- workspace-level Codex config.codex/agents/<name>.toml- one TOML config per agent.agents/skills/<skill>/SKILL.md- one stub file per unique skillAGENTS.md- team-level instructions for Codex agents
Use teamcast init --target claude|codex|both to choose which outputs are generated up front.
Target Model
TeamCast now uses a canonical manifest shape with target-specific blocks:
claude.agents.<name>- native Claude Code runtime fields and doc outputscodex.agents.<name>- native Codex runtime fields and TOML outputs<target>.agents.<name>.forge- TeamCast-only metadata such as delegation graphproject.environments- active project environments (node,python,go,rust,java,ruby,docker,terraform) — auto-detected or explicit
TeamCast includes a built-in registry of capabilities, traits, instruction fragments, policy fragments, models, and skills. These are not serialized into teamcast.yaml.
Legacy flat manifests are still accepted and normalized automatically, but new writes use the canonical shape.
Command Summary
| Command | Description |
| ------------------------ | -------------------------------------------------------- |
| init | Initialize teamcast.yaml and generate files |
| generate | Generate target files from teamcast.yaml |
| validate | Validate the team configuration |
| validate --format json | Machine-readable validation output for CI pipelines |
| explain | Print a human-readable view of the team architecture |
| diff | Show what generated files would change |
| add agent <name> | Add a new agent |
| edit agent <name> | Edit an existing agent |
| remove agent <name> | Remove an agent and clean up handoffs |
| create skill <name> | Create a new skill and assign it to one agent |
| assign skill <name> | Assign an existing skill to more agents |
| import | Import an existing .claude/ setup into teamcast.yaml |
| reset | Delete generated files, keep teamcast.yaml |
| clean | Delete generated files and teamcast.yaml |
Useful options:
teamcast init --preset <name> # skip wizard and use a preset
teamcast init --from <path> # initialize from an existing YAML file
teamcast init --target <name> # generate claude, codex, or both
teamcast init --yes # non-interactive init, uses defaults
teamcast generate --dry-run # preview generated files without writing
teamcast validate --strict # fail on warnings as well as errors
teamcast validate --format json # JSON output, useful in CI scripts
teamcast import --yes # skip import confirmation
teamcast reset --yes # skip reset confirmation
teamcast clean --yes # skip clean confirmationPresets
| Preset | Agents | Workflow |
| -------------------- | ------ | -------- |
| feature-team | orchestrator, planner, developer, reviewer | orchestrator triages and delegates; planner reads code and produces step-by-step plans; developer implements with tests; reviewer checks quality |
| solo-dev | developer | single full-stack agent handles end-to-end: plan, implement, test, verify |
| research-and-build | orchestrator, researcher, planner, developer | research-first: orchestrator routes to researcher for external info, planner integrates findings, developer implements |
| secure-dev | orchestrator, planner, developer, security-auditor, reviewer | mandatory security pipeline: planner includes threat model, developer follows OWASP, security-auditor gates every change, reviewer checks quality |
| red-blue | orchestrator, red-agent, blue-agent, judge | adversarial hardening: red attacks with failing tests, blue fixes without weakening them, judge decides SHIP or next round |
The built-in preset files live in templates/presets/ and are valid TeamCast YAML. Use them as a reference when creating custom presets, or copy one as a starting point:
cp node_modules/teamcast/templates/presets/feature-team.yaml ./my-team.yaml
teamcast init --from ./my-team.yamlFlows
init
teamcast init creates a fresh teamcast.yaml, validates it, and generates all output files.
Interactive wizard flow:
Project name:- default is auto-detected from the current directory
- must match lowercase letters, numbers, and hyphens
Which target configs should TeamCast generate?ClaudeCodexBoth
How do you want to set up your agent team?Use a presetCustom teamSingle agent
- If you choose
Use a preset:Select a preset:
- If you choose
Custom team:Select roles for your team:- available roles:
orchestrator,planner,researcher,developer,tester,reviewer,security-auditor - if
orchestratoris selected with other roles, handoffs are auto-wired to the other selected agents
Customize agents before generating?- if yes, each agent gets:
Model for <agent>:Reasoning effort [codex]:for Codex agents
Select project environments:- detected environments (e.g. Node.js, Python) are pre-selected
- environments inject policies and workflow instructions into capable agents
- Preview:
- shows the files that will be created
- asks
Generate these files?
Important limitations of the wizard:
- It does not let you rename individual agents.
- It does not ask for custom
instruction_blocksorinstruction_fragments. - It does not ask for environment-specific configuration prompts.
- It does not ask for custom
claude.skills,forge.handoffs,claude.max_turns, or exact tool lists. - Those values come from built-in presets or role templates.
- If you want deeper customization, edit
teamcast.yamlafter init and runteamcast generate.
Non-interactive init flows:
teamcast init --preset <name>- skips the wizard
- loads the preset
- uses the selected
--targetvalue, orclaudeif omitted - uses the detected directory name as
project.name - writes
teamcast.yaml - generates files immediately
teamcast init --from ./my-team.yaml- loads a custom YAML file
- validates schema and manifest rules
- writes
teamcast.yaml - generates files immediately
teamcast init --yes- runs wizard defaults without prompts
- uses detected project name
- uses the
feature-teampreset - skips final confirmation
add agent <name>
teamcast add agent <name> adds a new agent to an existing manifest, writes teamcast.yaml, then regenerates all files.
Two modes are supported:
teamcast add agent <name>- creates a custom agent from a short interactive flow
teamcast add agent <name> --template <role>- creates an agent from a built-in role template
Interactive questions for add agent <name>:
Agent description (when should Claude delegate to this agent?):Model:sonnetopushaiku
Can this agent write/edit files?Can this agent run shell commands?Can this agent access the internet?Can this agent delegate to other agents?
How those answers map into the manifest:
- Every custom agent gets
Read,Grep, andGlob. - If write access is enabled, TeamCast adds
Write,Edit,MultiEdit. - If bash access is enabled, TeamCast adds
Bash. - If internet access is enabled, TeamCast adds
WebFetch,WebSearch. - If delegation is enabled, TeamCast adds
Agent. - For disabled write/bash/web capabilities, the matching tools are written into
claude.disallowed_tools.
What add agent does not ask for:
claude.instructionsinstruction_blocksclaude.skillsforge.handoffsclaude.max_turnsclaude.permission_modeclaude.mcp_servers- a fully custom
claude.tools/claude.disallowed_toolslist
That means a custom agent added this way starts with a minimal prompt. To make it useful, edit teamcast.yaml and add fields such as instruction_blocks, instruction_fragments, skills, and forge.handoffs.
edit agent <name>
teamcast edit agent <name> updates an existing agent, writes teamcast.yaml, then regenerates all files.
Two modes are supported:
- Non-interactive:
teamcast edit agent reviewer --description "Reviews backend changes"
teamcast edit agent reviewer --model opus
teamcast edit agent reviewer --max-turns 40- Interactive:
teamcast edit agent reviewerInteractive questions:
Description:Model:sonnetopushaikuinherit
Max turns (leave empty to keep current):Customize tools?- If yes:
Select allowed tools:claude.disallowed_toolsis computed automatically as the inverse of the selected allow-list
Important limitations:
edit agentdoes not editinstruction_blocks,instruction_fragments,skills,forge.handoffs,permission_mode, ormcp_servers.- If you pass any direct flags such as
--description,--model, or--max-turns, the command updates only those fields and skips the interactive tool editor.
remove agent <name>
teamcast remove agent <name> removes an agent from the manifest, removes that agent from any forge.handoffs, deletes the orphaned .claude/agents/<name>.md file, and regenerates the rest.
Interactive flow:
- Shows the current agent name
- Asks:
Remove agent "<name>"? This will also remove it from any handoffs.
Use --yes to skip confirmation.
create skill <name>
teamcast create skill <name> registers a new skill name on one agent, writes teamcast.yaml, and generates a target-specific stub: .claude/skills/<name>/SKILL.md for Claude or .agents/skills/<name>/SKILL.md for Codex.
Rules and prompts:
- skill names must start with a letter and use lowercase letters, numbers, and hyphens only
- if the skill already exists anywhere in the manifest, the command fails
- existing skill names are shown for context
- then TeamCast asks:
Which agent should own this skill?
The generated SKILL.md file is a stub intended for manual editing. TeamCast will not overwrite an existing skill stub on later generate runs.
assign skill <name>
teamcast assign skill <name> adds an existing skill to one or more additional agents, writes teamcast.yaml, and regenerates files.
Interactive flow:
- Validates that the skill already exists somewhere in the manifest
- Prints agents that already have the skill
- Asks:
Assign to which agents?
The prompt is a multi-select list and requires at least one target agent.
generate
teamcast generate reads teamcast.yaml, validates it for blocking issues, and writes generated files.
teamcast generate
teamcast generate --dry-runBehavior:
generateoverwrites generated agent/docs/settings files- skill stub files under
.claude/skills/and.agents/skills/are created only if missing --dry-runshows what would be generated without writing anything
diff
teamcast diff compares the current manifest to generated files already on disk.
It reports:
- new files
- modified files with added or removed line counts when available
- unchanged files
Use it to preview drift before running teamcast generate.
validate
teamcast validate runs the validator against teamcast.yaml.
teamcast validate
teamcast validate --strict
teamcast validate --format jsonBehavior:
- exits non-zero on validation errors
- with
--strict, also exits non-zero on warnings - with
--format json, prints a JSON result object instead of human-readable output; useful for CI scripts that need to parse results programmatically
Validation categories include:
- handoff graph correctness
- tool conflicts
- role-based warnings
- security baseline checks
Policy Assertions
Assertions are declarative rules about your team that validate enforces. Define them under policies.assertions:
policies:
assertions:
- rule: require_sandbox_with_execute
- rule: no_unrestricted_execute
- rule: max_agents
count: 6
- rule: deny_skill_for_role
agent: reviewer
skill: write_filesAvailable rules:
| Rule | Parameters | Description |
| ------------------------------ | ---------------- | ----------------------------------------------------------------- |
| require_sandbox_with_execute | — | Any agent with execute skill must have sandbox enabled |
| no_unrestricted_execute | — | execute skill must have a permission scope (e.g. Bash(npm *)) |
| require_skill | skill | All agents must have the specified skill |
| deny_skill_for_role | agent, skill | A named agent must not have the specified skill |
| forbid_skill_combination | skills[] | No single agent may hold all listed skills at once |
| max_agents | count | Team must not exceed the given number of agents |
| require_instruction_block | kind | All agents must include an instruction block of the given kind |
| require_delegation_chain | — | At least one agent must have the delegate skill |
The secure-dev preset includes several security assertions by default.
explain
teamcast explain prints a human-readable summary of the team:
- project metadata
- agents
- models
- tools
- handoffs
- skills
Use this after init, import, or larger manifest edits to sanity-check the architecture.
import
teamcast import converts an existing .claude/ setup into teamcast.yaml.
Preconditions:
.claude/must existteamcast.yamlmust not already exist
Flow:
- Scans
.claude/agents/*.md - Scans
.claude/settings.json - Builds a manifest
- Prints import warnings, if any
- Prints discovered agents and policy categories
- Validates the imported manifest
- Asks:
Write teamcast.yaml with imported configuration?
Use --yes to skip confirmation.
Important note:
importwritesteamcast.yaml- it does not run
generate - imported instructions are extracted from the agent markdown body text
- legacy TeamCast markdown is still supported, and old generated
Skills,Delegation, andConstraintssections are stripped during import
reset
teamcast reset deletes generated output but keeps teamcast.yaml.
It targets:
.claude/agents.claude/skills- generated Codex skill files under
.agents/skills/ .claude/settings.json.claude/settings.local.jsonCLAUDE.md.codex/agents.codex/config.tomlAGENTS.md
Flow:
- Shows the files that will be deleted
- Asks:
Delete these files?
Use --yes to skip confirmation.
clean
teamcast clean is the destructive version of reset.
It deletes:
- everything removed by
reset teamcast.yaml
Flow:
- Shows the files that will be deleted
- Asks:
Delete everything including teamcast.yaml?
Use --yes to skip confirmation.
Prompt Generation
Everything is defined in teamcast.yaml at the root of your project.
For Claude targets, TeamCast renders .claude/agents/<name>.md and CLAUDE.md from claude.agents.<name>.
For Codex targets, TeamCast renders .codex/agents/<name>.toml plus .codex/config.toml from codex.agents.<name>, and writes Codex skill docs to .agents/skills/<skill>/.
.codex/config.toml is the workspace-level agent index. Concrete agent runtime config lives in .codex/agents/<name>.toml. Codex skill discovery uses .agents/skills/, not .codex/.
Native Claude Code fields are rendered into frontmatter:
descriptionmodeltoolsdisallowedToolspermissionModemaxTurnsskillsmcpServersbackground
instruction_blocks and instruction_fragments compose the markdown body for Claude agents and the instruction sections embedded in Codex developer_instructions.
forge metadata is not rendered into the agent markdown. It is used by TeamCast for validation, workflow docs, and delegation modeling.
Codex agent TOML uses these native fields:
modelmodel_reasoning_effortsandbox_modedeveloper_instructions
tools, disallowed_tools, skills, and forge.handoffs are encoded as structured sections inside developer_instructions.
Environment Instructions
Project environments inject capability-gated instructions into agent prompts at generation time. Each environment fragment specifies which capabilities an agent must have to receive it:
| Fragment | Requires | Example content |
|----------|----------|----------------|
| node_code_patterns | read_files | ESM imports, TypeScript strict mode, named exports |
| node_development | write_files | npm install, async/await, error handling patterns |
| node_testing | execute + write_files | npm test, vitest/jest commands, test conventions |
This means a reviewer (read + execute, no write) gets code patterns but NOT testing instructions. A developer (read + write + execute) gets everything. An orchestrator (read + delegate only) gets only code patterns.
Custom agents work the same way — a react-dev with write_files + execute automatically gets the right fragments without any role-name matching.
Built-in environments
| Environment | Auto-detected by | Policy allows |
|---|---|---|
| node | package.json | npm, npx, node |
| python | pyproject.toml, requirements.txt, setup.py | pytest, python, uv, poetry |
| go | go.mod | go build/test/run/vet/mod |
| rust | Cargo.toml | cargo, rustfmt, clippy |
| java | pom.xml, build.gradle | mvn, gradle, ./gradlew |
| ruby | Gemfile | bundle, rake, rspec |
| docker | Dockerfile, docker-compose.yml | docker, docker compose |
| terraform | main.tf, terraform.tf | terraform init/plan/validate/fmt |
Custom environments
Drop a YAML file into .agentforge/environments/ to add a new environment or override a builtin:
# .agentforge/environments/bun.yaml
id: bun
description: "Bun runtime environment"
detect_files:
- bun.lockb
policy_rules:
sandbox:
enabled: true
allow:
- "Bash(bun *)"
instruction_fragments:
bun_patterns:
content: |
This project uses Bun.
Use `bun install`, `bun run`, and `bun test`.
requires_capabilities:
- read_filesReference it in teamcast.yaml by id:
project:
environments: [node, bun]Instruction Layers
Agent prompts are composed from three layers:
| Layer | Source | Scope |
|-------|--------|-------|
| instruction_blocks | teamcast.yaml or preset | Project-specific behavior, workflow rules |
| instruction_fragments | Built-in registry | Reusable role patterns (e.g. feature-developer-workflow) |
| environment instructions | Built-in + custom environments | Toolchain best practices, injected by capability |
Presets provide sensible defaults for instruction_blocks and instruction_fragments. For deeper customization, edit teamcast.yaml and run teamcast generate.
Note for add agent:
add agent <name> --template <role>inherits the role template's blocks and fragmentsadd agent <name>without--templatestarts with a minimal prompt until you editteamcast.yaml
Configuration
Everything is defined in teamcast.yaml at the root of your project.
Minimal Example
version: "2"
project:
name: my-project
claude:
agents:
developer:
description: Implements features and fixes bugs
model: sonnet
tools: [Read, Write, Edit, Bash, Grep, Glob]
disallowed_tools: [WebFetch, WebSearch]
instruction_blocks:
- kind: behavior
content: |
Implement the requested changes.
Write tests when behavior changes.Full Example
version: "2"
project:
name: my-project
description: TypeScript/Node.js web app
claude:
agents:
orchestrator:
description: Coordinates the team and delegates tasks
model: opus
tools: [Read, Grep, Glob, Agent]
disallowed_tools: [Edit, Write, Bash]
max_turns: 30
instruction_blocks:
- kind: behavior
content: |
You are the coordinator for the project.
Read the request, break it into subtasks, and delegate to the right agents.
Never modify files yourself.
forge:
handoffs: [planner, developer, reviewer]
planner:
description: Analyzes codebase and produces implementation plans
model: sonnet
tools: [Read, Grep, Glob, WebFetch, WebSearch]
disallowed_tools: [Edit, Write, Bash]
instruction_blocks:
- kind: behavior
content: |
Read the codebase and produce a step-by-step implementation plan.
Never modify files.
developer:
description: Implements features based on the plan
model: sonnet
tools: [Read, Write, Edit, Bash, Grep, Glob]
disallowed_tools: [WebFetch, WebSearch]
skills: [test-first, clean-code]
instruction_blocks:
- kind: behavior
content: |
Implement the plan, write tests, and verify the result.
reviewer:
description: Reviews code for quality and security issues
model: sonnet
tools: [Read, Grep, Glob, Bash]
disallowed_tools: [Edit, Write]
instruction_blocks:
- kind: behavior
content: |
Review the implementation for correctness, style, and security.
Do not modify files yourself.
policies:
permissions:
allow:
- "Bash(npm run *)"
- "Bash(npm test)"
- "Bash(git status)"
- "Bash(git diff *)"
- "Bash(git commit *)"
ask:
- "Bash(git push *)"
deny:
- "Bash(rm -rf *)"
- "Bash(git push --force *)"
- "Write(.env*)"
sandbox:
enabled: true
auto_allow_bash: true
settings:
generate_docs: true
generate_local_settings: trueAgent Fields
| Field | Type | Description |
| ------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| claude.description | string | Required. Shown in the Claude Code subagent picker |
| claude.model | opus \| sonnet \| haiku \| inherit | Model alias to use |
| claude.tools | string[] | Native Claude Code tool allow-list |
| claude.disallowed_tools | string[] | Native Claude Code tool deny-list |
| claude.skills | string[] | Skill names. Each unique skill generates .claude/skills/<skill>/SKILL.md |
| codex.skills | string[] | Skill names. Each unique skill generates .agents/skills/<skill>/SKILL.md |
| claude.max_turns | number | Maximum agentic turns |
| claude.mcp_servers | object[] | MCP server definitions |
| claude.permission_mode | default \| acceptEdits \| bypassPermissions \| plan \| dontAsk | Claude Code permission mode |
| capability_traits | string[] | High-level capability profiles that expand to tools + disallowed_tools |
| instruction_blocks | object[] | Structured instruction blocks rendered into Claude markdown and Codex developer_instructions |
| instruction_fragments | string[] | Named instruction fragments composed with instruction_blocks |
| forge.handoffs | string[] | Other agents this agent can delegate to. Requires Agent in claude.tools |
Available Claude Code tools:
Read, Write, Edit, MultiEdit, Grep, Glob, Bash, WebFetch, WebSearch, Agent
Abstract Skills
Instead of listing raw tool names, you can specify platform-agnostic skills in claude.tools. TeamCast expands each skill to the appropriate Claude Code tools automatically.
| Skill | Expands to |
| ------------- | ------------------------------------------ |
| read_files | Read, Grep, Glob |
| write_files | Write, Edit, MultiEdit |
| execute | Bash |
| search | Glob, Grep |
| web | WebFetch, WebSearch |
| delegate | Agent |
| interact | AskUserQuestion, TodoWrite, TodoRead |
| notebook | NotebookEdit |
Example:
developer:
claude:
tools: [read_files, write_files, execute]Raw tool names and skills can be mixed in the same tools array.
Capability Traits
Capability traits are high-level profiles that compose tools and disallowed_tools from named capability sets. They are the recommended way to define agent permissions in presets and custom manifests — more readable than raw tool lists and safer than manual assembly.
| Trait | Grants | Denies |
| -------------------- | ------------------------------- | --------------- |
| base-read | read_files, search | — |
| file-authoring | write_files | — |
| command-execution | execute | — |
| web-research | web | — |
| delegation | delegate | — |
| interaction | interact | — |
| notebook-editing | notebook | — |
| no-file-edits | — | write_files |
| no-commands | — | execute |
| no-web | — | web |
| full-access | all capabilities | — |
Grant traits expand to the corresponding abstract skills (see table above). Deny traits add the expanded tools to disallowed_tools.
Traits are combined in order. If you need a read-only planner that can browse the web but cannot edit files or run commands:
planner:
capability_traits:
- base-read
- web-research
- no-file-edits
- no-commandsTraits merge with explicit tools and disallowed_tools — you can use both in the same agent definition. Explicit tool lists take precedence for additions; deny traits always add to the disallow list.
Policy Fields
policies:
permissions:
allow: ["Bash(npm run *)", "WebFetch(api.example.com:*)"]
ask: ["Bash(git push *)"]
deny: ["Bash(rm -rf *)", "Write(.env*)"]
default_mode: acceptEdits
sandbox:
enabled: true
auto_allow_bash: trueCustom Templates
Use --from to initialize from any valid TeamCast YAML file:
teamcast init --from ./my-team-template.yamlThis validates the file against the schema, writes teamcast.yaml, and generates all config files.
Preset Metadata
When sharing presets, you can add optional metadata:
preset_meta:
author: your-name
tags: [typescript, fullstack, security]
min_version: "0.5.0"Validation
teamcast validate runs 10 validation phases:
- Registry references — all fragments, traits, skills, and environments resolve
- Trait and capability composition — no grant/deny conflicts
- Capability-to-tool mapping — abstract capabilities map to target tools
- Policy coherence — no allow/deny contradictions
- Capability-policy cross-check — capabilities align with policies
- Skill requirements — capabilities, MCP servers, and target compatibility
- Instruction validation — fragment conflicts, heuristic contradiction detection
- Team graph — handoff targets exist, no orphans, reachability verified
- Environment checks — detected and declared environments valid
- MCP server configuration — required servers present, no duplicates
- Policy assertions (when defined in
policies.assertions)
