https://github.com/codexstar69/pi-agent-teams
Claude Code agent teams style workflow for Pi.
https://github.com/codexstar69/pi-agent-teams
Last synced: about 2 months ago
JSON representation
Claude Code agent teams style workflow for Pi.
- Host: GitHub
- URL: https://github.com/codexstar69/pi-agent-teams
- Owner: codexstar69
- License: mit
- Created: 2026-03-12T03:01:51.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-03-12T05:54:06.000Z (3 months ago)
- Last Synced: 2026-03-12T10:56:16.225Z (3 months ago)
- Language: TypeScript
- Homepage: https://github.com/codexstar69/pi-agent-teams
- Size: 16 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS
- Security: SECURITY.md
- Support: SUPPORT.md
- Governance: GOVERNANCE.md
- Maintainers: MAINTAINERS.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# pi-agent-teams
[](https://www.npmjs.com/package/@codexstar/pi-agent-teams)
[](https://github.com/codexstar69/pi-agent-teams/actions/workflows/ci.yml)
[](./LICENSE)
An experimental [Pi](https://pi.dev) extension that brings [Claude Code agent teams](https://code.claude.com/docs/en/agent-teams) to Pi. Spawn teammates, share a task list, and coordinate work across multiple Pi sessions.

> **Status:** MVP with hardened runtime behavior, multi-OS verification, PowerShell/Windows support paths, and a maintained package surface. See [`docs/claude-parity.md`](docs/claude-parity.md) for roadmap context.
## Project health
- **Package:** [`@codexstar/pi-agent-teams`](https://www.npmjs.com/package/@codexstar/pi-agent-teams)
- **Architecture:** [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
- **Compatibility:** [`docs/COMPATIBILITY.md`](docs/COMPATIBILITY.md)
- **Security policy:** [`SECURITY.md`](SECURITY.md)
- **Support:** [`SUPPORT.md`](SUPPORT.md)
- **Contributing:** [`CONTRIBUTING.md`](CONTRIBUTING.md)
- **Governance:** [`GOVERNANCE.md`](GOVERNANCE.md)
- **Maintainers:** [`MAINTAINERS.md`](MAINTAINERS.md)
- **AI discovery:** [`llms.txt`](llms.txt), [`llms-full.txt`](llms-full.txt)
## Features
Core agent-teams primitives, matching Claude's design:
- **Shared task list** — file-per-task on disk with three states (pending / in-progress / completed) and dependency tracking so blocked tasks stay blocked until their prerequisites finish.
- **Auto-claim** — idle teammates automatically pick up the next unassigned, unblocked task. No manual dispatching required (disable with `PI_TEAMS_DEFAULT_AUTO_CLAIM=0`).
- **Direct messages and broadcast** — send a message to one teammate or all of them at once, via file-based mailboxes.
- **Graceful lifecycle** — spawn, stop, shutdown (with handshake), or kill teammates. The leader tracks who's online, idle, or streaming.
- **LLM-callable teams tool** — the model can spawn teammates, delegate tasks, mutate task assignment/status/dependencies, message teammates, and run lifecycle actions in tool calls (no slash commands needed).
- **Team cleanup** — tear down all team artifacts (tasks, mailboxes, sessions, worktrees) when you're done.
Additional Pi-specific capabilities:
- **Git worktrees** — optionally give each teammate its own worktree so they work on isolated branches without conflicting edits.
- **Session branching** — clone the leader's conversation context into a teammate so it starts with full awareness of the work so far, instead of from scratch.
- **Hooks / quality gates** — optional leader-side hooks on idle / task completion to run scripts (opt-in).

## UI style (terminology + naming)
Built-in styles:
- **normal** (default): "Team leader" + "Teammate " (spawn requires explicit name)
- **soviet**: "Chairman" + "Comrade " (spawn can auto-pick names)
- **pirate**: "Captain" + "Matey " (spawn can auto-pick names)
Configure via:
- env: `PI_TEAMS_STYLE=`
- command: `/team style ` (see: `/team style list`)
### Custom styles
You can add your own styles by creating JSON files under:
- `~/.pi/agent/teams/_styles/.json`
The file can override strings and naming rules.
Strings include both terminology **and lifecycle copy**, e.g. `killedVerb`, `shutdownRequestedVerb`, `shutdownCompletedVerb`, `shutdownRefusedVerb`, `abortRequestedVerb`, plus templates like `teamEndedAllStopped`.
Example:
```json
{
"extends": "pirate",
"strings": {
"memberTitle": "Deckhand",
"memberPrefix": "Deckhand "
},
"naming": {
"requireExplicitSpawnName": false,
"autoNameStrategy": { "kind": "pool", "pool": ["pegleg", "parrot"], "fallbackBase": "deckhand" }
}
}
```
## Install
**Option A — install from npm:**
```bash
pi install npm:@codexstar/pi-agent-teams
```
**Option B — load directly (dev):**
```bash
pi -e ~/projects/pi-agent-teams/extensions/teams/index.ts
```
**Option C — install from a local folder:**
```bash
pi install ~/projects/pi-agent-teams
```
Then run `pi` normally; the extension auto-discovers.
Verify with `/team id` — it should print the current team info.
## Quick start
The fastest way to get going is `/swarm`:
```
/swarm build the auth module # agent spawns a team and coordinates the work
/swarm # agent asks you what to do, then swarms on it
```

Or drive it manually:
```
/team spawn alice # spawn a teammate (fresh session, shared workspace)
/team spawn bob branch worktree # spawn with leader context + isolated worktree
/team attach list # discover existing teams under ~/.pi/agent/teams
/team attach <teamId> [--claim] # attach this session to an existing team workspace (force takeover with --claim)
/team detach # return to this session's own team
/team task add alice: Fix failing tests # create a task and assign it to alice
/team task add Refactor auth module # unassigned — auto-claimed by next idle teammate
/team dm alice Check the edge cases too # direct message
/team broadcast Wrapping up soon # message everyone
/tw # open the interactive widget panel
/team shutdown alice # graceful shutdown (handshake)
/team shutdown # stop all teammates (leader session remains active)
/team cleanup # remove team artifacts when done
```
Or let the model drive it with the delegate tool:
```json
{
"action": "delegate",
"contextMode": "branch",
"workspaceMode": "worktree",
"model": "openai-codex/gpt-5.1-codex-mini",
"thinking": "high",
"teammates": ["alice", "bob"],
"tasks": [
{ "text": "Fix failing unit tests" },
{ "text": "Refactor auth module" }
]
}
```
### Teams tool action reference (agent-run)
| Action | Required fields | Purpose |
| --- | --- | --- |
| `delegate` | `tasks` | Spawn teammates as needed and create/assign tasks. |
| `task_assign` | `taskId`, `assignee` | Assign/reassign a task owner. |
| `task_unassign` | `taskId` | Clear owner (resets to pending for non-completed tasks). |
| `task_set_status` | `taskId`, `status` | Set status to `pending`, `in_progress`, or `completed`. |
| `task_dep_add` | `taskId`, `depId` | Add dependency edge (`taskId` depends on `depId`). |
| `task_dep_rm` | `taskId`, `depId` | Remove dependency edge. |
| `task_dep_ls` | `taskId` | Inspect dependency/block graph for one task. |
| `message_dm` | `name`, `message` | Send mailbox DM to one teammate. |
| `message_broadcast` | `message` | Send mailbox message to all discovered workers. |
| `message_steer` | `name`, `message` | Send steer instruction to a running RPC teammate. |
| `member_spawn` | `name` | Spawn one teammate (supports context/workspace/model/thinking/plan options). |
| `member_shutdown` | `name` or `all=true` | Request graceful shutdown via mailbox handshake. |
| `member_kill` | `name` | Force-stop one RPC teammate and unassign active tasks. |
| `member_prune` | _(none)_ | Mark stale non-RPC workers offline (`all=true` to force). |
| `plan_approve` | `name` | Approve pending plan for a plan-required teammate. |
| `plan_reject` | `name` | Reject pending plan (`feedback` optional). |
| `hooks_policy_get` | _(none)_ | Read team hooks policy (configured + effective with env fallback). |
| `hooks_policy_set` | one or more of: `hookFailureAction`, `hookMaxReopensPerTask`, `hookFollowupOwner` | Update team hooks policy at runtime (`hooksPolicyReset=true` clears team overrides first). |
| `model_policy_get` | _(none)_ | Inspect teammate model policy and default inheritance behavior for the current leader model. |
| `model_policy_check` | optional `model` | Validate a model override before spawning (`<provider>/<modelId>` or `<modelId>`). |
Example calls:
```json
{ "action": "task_assign", "taskId": "12", "assignee": "alice" }
{ "action": "task_dep_add", "taskId": "12", "depId": "7" }
{ "action": "message_broadcast", "message": "Sync: finishing this milestone" }
{ "action": "member_kill", "name": "alice" }
{ "action": "plan_approve", "name": "alice" }
{ "action": "hooks_policy_get" }
{ "action": "hooks_policy_set", "hookFailureAction": "reopen_followup", "hookMaxReopensPerTask": 2, "hookFollowupOwner": "member" }
{ "action": "model_policy_get" }
{ "action": "model_policy_check", "model": "openai-codex/gpt-5.1-codex-mini" }
```
## Commands
### Shortcuts
| Command | Description |
| --- | --- |
| `/swarm [task]` | Tell the agent to spawn a team and work on a task |
| `/tw` | Open the interactive widget panel |
| `/team-widget` | Open the interactive widget panel (alias for `/tw`) |
### Team management
All management commands live under `/team`.
| Command | Description |
| --- | --- |
| `/team spawn <name> [fresh\|branch] [shared\|worktree] [plan] [--model <provider>/<modelId>] [--thinking <level>]` | Start a teammate |
| `/team list` | List teammates and their status |
| `/team panel` | Interactive widget panel (same as `/tw`) |
| `/team attach list` | Discover existing team workspaces under `<teamsRoot>` |
| `/team attach <teamId> [--claim]` | Attach this session to an existing team workspace (`--claim` force-takes over an active claim) |
| `/team detach` | Return to this session's own team workspace |
| `/team style` | Show current style + usage |
| `/team style list` | List available styles (built-in + custom) |
| `/team style init <name> [extends <base>]` | Create a custom style template under `~/.pi/agent/teams/_styles/` |
| `/team style <name>` | Set style (built-in or custom) |
| `/team send <name> <msg>` | Send a prompt over RPC |
| `/team steer <name> <msg>` | Redirect an in-flight run |
| `/team dm <name> <msg>` | Send a mailbox message |
| `/team broadcast <msg>` | Message all teammates |
| `/team stop <name> [reason]` | Abort current work (resets task to pending) |
| `/team shutdown <name> [reason]` | Graceful shutdown (handshake) |
| `/team shutdown` | Stop all teammates (RPC + best-effort manual) (leader session remains active) |
| `/team prune [--all]` | Mark stale manual teammates offline (hides them in widget) |
| `/team kill <name>` | Force-terminate |
| `/team cleanup [--force]` | Delete team artifacts |
| `/team doctor` | Read-only diagnostics for stale workers, locks, and managed worktrees |
| `/team id` | Print team/task-list IDs and paths |
| `/team env <name>` | Print manual-worker startup instructions for both POSIX shells (macOS/Linux) and PowerShell (Windows) |
Model inheritance note:
- If the leader is running a deprecated model id (e.g. Sonnet 4 non-4.5 variants), teammates will **not** inherit that id by default.
- Explicit deprecated `--model` overrides are rejected.
- Agents can introspect/check this at runtime via `teams` actions: `{ "action": "model_policy_get" }` and `{ "action": "model_policy_check", "model": "..." }`.
### Panel shortcuts (`/tw` / `/team panel`)
- `↑/↓` or `w/s`: select teammate / scroll transcript
- `1..9`: jump directly to teammate in overview
- `enter`: open selected teammate transcript
- `t` or `shift+t`: open selected teammate task list (task-centric view with deps/blocks); in task view, toggle back (`esc`/`t`/`shift+t`)
- task view: `c` complete, `p` pending, `i` in-progress, `u` unassign, `r` reassign selected task
- `m` or `d`: compose message to selected teammate
- `a`: request abort
- `k`: kill (SIGTERM)
- `esc`: back/close panel
- attached mode shows a banner (`attached: ...`) with `/team detach` hint
### Tasks
| Command | Description |
| --- | --- |
| `/team task add <text>` | Create a task (prefix with `name:` to assign) |
| `/team task assign <id> <agent>` | Assign a task |
| `/team task unassign <id>` | Remove assignment |
| `/team task list` | Show tasks with status, deps, blocks |
| `/team task show <id>` | Full description + result |
| `/team task dep add <id> <depId>` | Add a dependency |
| `/team task dep rm <id> <depId>` | Remove a dependency |
| `/team task dep ls <id>` | Show deps and blocks |
| `/team task clear [completed\|all]` | Delete task files |
## Configuration
| Environment variable | Purpose | Default |
| --- | --- | --- |
| `PI_TEAMS_ROOT_DIR` | Storage root (absolute or relative to `~/.pi/agent`) | `~/.pi/agent/teams` |
| `PI_TEAMS_DEFAULT_AUTO_CLAIM` | Whether spawned teammates auto-claim tasks | `1` (on) |
| `PI_TEAMS_STYLE` | UI style id (built-in: `normal`, `soviet`, `pirate`, or custom) | `normal` |
| `PI_TEAMS_HOOKS_ENABLED` | Enable leader-side hooks/quality gates | `0` (off) |
| `PI_TEAMS_HOOKS_DIR` | Hooks directory (absolute or relative to `PI_TEAMS_ROOT_DIR`) | `<teamsRoot>/_hooks` |
| `PI_TEAMS_HOOK_TIMEOUT_MS` | Hook execution timeout (ms) | `60000` |
| `PI_TEAMS_HOOKS_FAILURE_ACTION` | Hook-failure policy: `warn`, `followup`, `reopen`, `reopen_followup` | `warn` |
| `PI_TEAMS_HOOKS_MAX_REOPENS_PER_TASK` | Reopen cap per task when failure action includes `reopen` (`0` disables auto-reopen) | `3` |
| `PI_TEAMS_HOOKS_FOLLOWUP_OWNER` | Follow-up owner policy: `member`, `lead`, `none` | `member` |
| `PI_TEAMS_HOOKS_CREATE_TASK_ON_FAILURE` | Legacy shortcut for `PI_TEAMS_HOOKS_FAILURE_ACTION=followup` | `0` (off) |
## Storage layout
```
<teamsRoot>/<teamId>/
config.json # team metadata + members
tasks/<taskListId>/
1.json, 2.json, ... # one file per task
.highwatermark # next task ID
mailboxes/<namespace>/inboxes/
<agent>.json # per-agent inbox
sessions/ # teammate session files
worktrees/<agent>/ # git worktrees (when enabled)
<teamsRoot>/_hooks/
on_idle.{js,sh} # optional hook (see below)
on_task_completed.{js,sh} # optional quality gate
on_task_failed.{js,sh} # optional hook
```
## Hooks / quality gates (optional)
Enable hooks:
```bash
export PI_TEAMS_HOOKS_ENABLED=1
```
Then create hook scripts under:
- `<teamsRoot>/_hooks/` (default: `~/.pi/agent/teams/_hooks/`)
Recognized hook names:
- `on_idle.(js|mjs|sh|ps1)`
- `on_task_completed.(js|mjs|sh|ps1)`
- `on_task_failed.(js|mjs|sh|ps1)`
Hooks run with working directory = the **leader session cwd** and receive context via env vars:
- `PI_TEAMS_HOOK_EVENT`
- `PI_TEAMS_HOOK_CONTEXT_VERSION` (currently `1`)
- `PI_TEAMS_HOOK_CONTEXT_JSON` (stable JSON payload for agent scripts)
- `PI_TEAMS_TEAM_ID`, `PI_TEAMS_TEAM_DIR`, `PI_TEAMS_TASK_LIST_ID`
- `PI_TEAMS_STYLE`
- `PI_TEAMS_MEMBER`
- `PI_TEAMS_TASK_ID`, `PI_TEAMS_TASK_SUBJECT`, `PI_TEAMS_TASK_OWNER`, `PI_TEAMS_TASK_STATUS`
Hook policy can be controlled by agents at runtime via `teams` tool actions:
- `{ "action": "hooks_policy_get" }`
- `{ "action": "hooks_policy_set", ... }`
Team-level policy in `config.json` overrides env defaults for that team.
Hook failure policy (for `task_completed` / `task_failed` hooks):
```bash
# default behavior: notify + annotate task metadata
export PI_TEAMS_HOOKS_FAILURE_ACTION=warn
# create follow-up remediation task
export PI_TEAMS_HOOKS_FAILURE_ACTION=followup
# reopen completed task to pending (re-blocks downstream dependencies)
export PI_TEAMS_HOOKS_FAILURE_ACTION=reopen
# both reopen and create a follow-up task
export PI_TEAMS_HOOKS_FAILURE_ACTION=reopen_followup
# safety cap for auto-reopen loops (0 = disable auto-reopen)
export PI_TEAMS_HOOKS_MAX_REOPENS_PER_TASK=3
# owner for auto-created follow-up tasks
# member (default), lead, or none
export PI_TEAMS_HOOKS_FOLLOWUP_OWNER=member
```
Agent-first intent:
- Hook failures are remediated by agents (reopen/follow-up/assignment + teammate notification).
- The user should not need to manually clear task gate state.
Legacy shortcut still supported:
```bash
export PI_TEAMS_HOOKS_CREATE_TASK_ON_FAILURE=1
```
## Development
### Quality gate
```bash
npm run check
```
Runs strict TypeScript typechecking (`npm run typecheck`) and ESLint (`npm run lint`).
### Smoke test (no API keys)
```bash
npm run smoke-test
# or: npx tsx scripts/smoke-test.mts
```
Filesystem-level smoke test of the task store, mailbox, team config, and protocol parsers.
### E2E RPC test (spawns pi + one teammate)
```bash
node scripts/e2e-rpc-test.mjs
```
Starts a leader in RPC mode, spawns a teammate, runs a shutdown handshake, verifies cleanup. Sets `PI_TEAMS_ROOT_DIR` to a temp directory so nothing touches `~/.pi/agent/teams`.
### Integration: hooks remediation loop
```bash
npm run integration-hooks-remediation-test
```
Deterministic leader-side integration flow that verifies failed `on_task_completed` hook handling end-to-end:
- task is reopened when policy includes `reopen`
- follow-up task is created/assigned when policy includes `followup`
- remediation mailbox nudge is emitted for the responsible teammate
### tmux dogfooding (macOS/Linux)
```bash
./scripts/start-tmux-team.sh pi-teams alice bob
tmux attach -t pi-teams
```
Starts a leader + one tmux window per teammate for interactive testing.
### PowerShell launcher (Windows)
`/team env <name>` now prints both POSIX shell and PowerShell (Windows) startup instructions for manual workers.
For a multi-window local dogfooding setup on Windows:
```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\start-team-windows.ps1 pi-teams alice bob
```
This opens a leader window plus one PowerShell window per teammate using the same filesystem-backed team primitives.
## License
MIT (see [`LICENSE`](LICENSE)).