Milady Electrobun Teams
Use when orchestrating multi-agent Electrobun feature development. Explains the electrobun-feature-team architecture — UI agent (views, RPC contract) followed by backend agent (bun-side wiring) — the RPC contract handoff format, and how to run the team using CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1.
git clone https://github.com/milady-ai/milady
T=$(mktemp -d) && git clone --depth=1 https://github.com/milady-ai/milady "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/plugins/electrobun-dev/skills/electrobun-teams" ~/.claude/skills/milady-ai-milady-electrobun-teams && rm -rf "$T"
.claude/plugins/electrobun-dev/skills/electrobun-teams/SKILL.mdElectrobun Feature Team
Two-agent sequential pipeline for building complete Electrobun features — renderer first, bun-side second.
Team Architecture
┌─────────────────────────────────────────────────────────────┐ │ Orchestrator (main Claude / /electrobun-feature command) │ │ Creates team, assigns tasks, receives handoff, passes it │ └──────────┬───────────────────────────────────┬──────────────┘ │ Task 1 │ Task 2 (after T1) ▼ ▼ ┌──────────────────────┐ ┌───────────────────────┐ │ electrobun-ui-agent │ ────────► │ electrobun-backend- │ │ │ contract │ agent │ │ Produces: │ handoff │ │ │ • src/<view>/ │ │ Produces: │ │ • src/shared/types │ │ • src/bun/index.ts │ │ • RPC contract doc │ │ • electrobun.config │ └──────────────────────┘ └───────────────────────┘
Enabling Teams
export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 claude # start Claude Code with teams enabled
Teams require this env var. Without it, the team tools (TeamCreate, TaskCreate, SendMessage) are not available.
Orchestrator: How to Run the Team
1. Create team: TeamCreate { team_name: "electrobun-feature-team", description: "Building <feature>" } 2. Create tasks: TaskCreate { subject: "T1: UI agent — design views and produce RPC contract" } TaskCreate { subject: "T2: Backend agent — implement bun-side wiring from RPC contract" } TaskUpdate { taskId: "T2", addBlockedBy: ["T1"] } // T2 blocked until T1 done 3. Spawn UI agent: Agent { name: "ui-agent", team_name: "electrobun-feature-team", subagent_type: "general-purpose", prompt: "You are the electrobun-ui-agent. [full feature spec] ..." } TaskUpdate { taskId: "T1", status: "in_progress", owner: "ui-agent" } 4. Wait for UI agent to complete T1 and produce handoff document. UI agent sends message: SendMessage to orchestrator with contract. 5. Receive contract. Pass to backend agent: Agent { name: "backend-agent", team_name: "electrobun-feature-team", subagent_type: "general-purpose", prompt: "You are the electrobun-backend-agent. Contract: [paste handoff] ..." } TaskUpdate { taskId: "T2", status: "in_progress", owner: "backend-agent" } 6. Wait for backend agent to complete T2. 7. Shutdown team: SendMessage { target: "ui-agent", type: "shutdown_request" } SendMessage { target: "backend-agent", type: "shutdown_request" } 8. Report completion to user.
Team Roles
electrobun-ui-agent
Input: Feature description from orchestrator Output: RPC contract handoff document + all renderer files
Produces:
— markup withsrc/<viewname>/index.html
on every control#id-kebab-case
— layout and stylessrc/<viewname>/index.css
— Electroview wiring usingsrc/<viewname>/index.tselectrobun/view
— thesrc/shared/types.ts
typed RPC schemaMyRPCType
electrobun-backend-agent
Input: RPC contract handoff from UI agent Output: Complete bun-side implementation + config update
Produces:
— BrowserWindow creation + BrowserView.defineRPC()src/bun/index.ts- Updated
— views + copy entrieselectrobun.config.ts
The RPC Contract Handoff Format
# RPC Contract Handoff — <FeatureName> ## Views created | View name | Source dir | Electrobun.config entry | |---|---|---| | mainview | src/mainview/ | mainview: { entrypoint: "src/mainview/index.ts" } | ## RPC type location src/shared/types.ts — exports MyRPCType ## Bun-side requests (renderer calls → bun responds) | RPC name | Params | Return | Trigger | |---|---|---|---| | doTheThing | { param: string } | string | #btn-primary-action click | ## Bun-side messages (renderer sends → bun, no response) | RPC name | Payload | Trigger | |---|---|---| | closeWindow | {} | #btn-done click | ## Webview-side requests (bun calls → renderer responds) | RPC name | Params | Return | |---|---|---| | getViewState | {} | { value: string } | ## Webview-side messages (bun sends → renderer) | RPC name | Payload | UI updated | |---|---|---| | updateStatus | { status: string } | #status-display | ## electrobun.config.ts copy entries copy: { "src/mainview/index.html": "views/mainview/index.html", } ## Platform notes - Requires CEF: no - titleBarStyle: default - Entitlements: none
Sequential Flow: Why UI First?
-
UI defines the contract — the renderer knows what it needs from bun (requests) and what it will push to bun (messages). This is the natural source of truth for the RPC schema.
-
Backend implements the contract — once the schema is known, the bun side is purely mechanical: implement each handler, return the right types.
-
No parallel work — both agents write to different files (renderer vs bun), but the backend agent needs the schema to type its handlers. Running in parallel would require speculative typing.
Using /electrobun-feature Without Full Teams Mode
If
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 is not set, the orchestrator runs the agents sequentially as subagents (one at a time) instead of as teammates. This is slower but produces the same output.
The
/electrobun-feature command handles both modes.
Key Rules for Teammates
- UI agent must not touch
— backend agent owns that directorysrc/bun/ - Backend agent must not touch
— UI agent owns those directoriessrc/<viewname>/ - Both agents read
— UI agent creates it, backend agent imports itsrc/shared/types.ts - Orchestrator passes the full handoff document — do not rely on teammates reading each other's files