Skip to content

feat(swarm): P1-P5 — concurrent task map, identity, mailbox, permission bridge, file mailbox#12191

Open
DavinciDreams wants to merge 17 commits intoRooCodeInc:mainfrom
DavinciDreams:feat/swarm-prd
Open

feat(swarm): P1-P5 — concurrent task map, identity, mailbox, permission bridge, file mailbox#12191
DavinciDreams wants to merge 17 commits intoRooCodeInc:mainfrom
DavinciDreams:feat/swarm-prd

Conversation

@DavinciDreams
Copy link
Copy Markdown

@DavinciDreams DavinciDreams commented Apr 25, 2026

Summary

Full implementation of the Swarm / Multi-Agent PRD through Phase 5. Each phase is a self-contained commit on this branch.

  • P1 — Replace clineStack: Task[] with tasks: Map<string, Task>; remove single-open invariant; add concurrent: true to spawn_parallel_tasks
  • PT — Teams system: run_team_phase tool, TeamsManager, .roo/teams/*.json config, conventions injection, abortOnChildFailure
  • P2 — Swarm identity: SwarmRegistry, AgentIdentity, round-robin color assignment, color dots in SubtaskRow UI
  • P3 — In-process mailbox: InMemoryMailbox, MailboxManager, idle worker loop in AttemptCompletionTool (persistent: true sessions)
  • P4 — Permission bridge: LeaderPermissionBridge singleton; concurrent workers route tool-approval through leader's VS Code dialog instead of surfacing a hidden UI prompt
  • P5 — File-backed mailbox: FileMailbox with proper-lockfile; MailboxManager.createFileMailbox(); enables cross-process workers (consumed by P6)

What's not in this PR (P6 — separate branch)

  • CliWorkerBackend / moo-worker headless CLI entry point
  • spawn_swarm tool
  • VsCodeWindowBackend

Test plan

  • spawn_parallel_tasks with concurrent: true runs subtasks simultaneously (wall time ≈ max subtask time)
  • Color dots appear in SubtaskRow for concurrent workers
  • With persistent: true, workers enter idle loop after attempt_completion and accept new task_assignment messages
  • Concurrent worker tool-approval routes to VS Code modal (Allow / Deny) rather than blocking on worker UI
  • FileMailbox round-trip: write a message, poll, dequeue — verified by manual test or unit test
  • run_team_phase with a .roo/teams/*.json config dispatches agents in the correct order/concurrency
  • TypeScript and lint pass (tsc --noEmit, turbo lint)

🤖 Generated with Claude Code

Interactively review PR in Roo Code Cloud

DavinciDreams and others added 16 commits April 23, 2026 08:20
- Strip all telemetry (PostHog, cloud telemetry) - no data leaves the machine

- Disable all cloud features (auth, settings sync, sharing, Roo provider)

- Rebrand extension: roo-cline -> moo-code, RooVeterinaryInc -> moo-code

- Update all commands, settings, views to moo-code.* prefix

- Remove upstream CI/CD workflows (marketplace publish, nightly, website)

- Rewrite README, PRIVACY, CONTRIBUTING, SECURITY docs

- Build verified: bin/moo-code-3.52.1.vsix (31.44 MB)
- Update all cloud package tests to match no-op implementations
- All 171 tests now pass
- Update src/package.json repository URL and homepage to point to actual fork
…upport

- Port session memory compaction, microcompact, hooks system, and
  prompt-too-long retry from the Claude Code CLI source
- Add spawn_parallel_tasks tool with serial queue drain fan-out pattern
- Add worktree isolation: new_task/spawn_parallel_tasks accept a worktree
  param; ClineProvider creates/cleans up git worktrees per child task
- Add completionPayload: attempt_completion result parsed as JSON and
  aggregated across parallel tasks for structured fan-in
- Fix workspacePath priority so explicit override always wins over parent
- Emit TaskSpawned event from delegateParentAndOpenChild
- Scope MCP hub to per-task workspacePath for worktree-aware mcp.json
- Fix microCompact bugs: touched flag, off-by-one threshold, keepRecent:0
- Fix lazy OutputChannel init in hooks executor to avoid test failures
- Fix pre-existing lint warnings across src, packages/cloud, webview-ui

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…and telemetry

- Introspection API: add ParallelTaskStatus type and getParallelTaskStatus() on
  TaskProviderLike so callers can list active child, queued tasks, and completed
  results (with errors) for any task ID
- Worktree orphan detection: detectAndCleanOrphanedWorktrees() scans history on
  startup, emits telemetry for each find, and offers a VS Code cleanup prompt
- Error propagation: reopenParentFromDelegation accepts childFailed flag; when
  abortOnChildFailure is set on the parent the remaining parallel queue is
  abandoned and partial results returned immediately
- abortOnChildFailure option: SpawnParallelTasksTool forwards the flag through
  delegation so callers can opt into fail-fast queue behaviour
- Worktree naming: worktree paths and branches now embed the last 8 chars of the
  parent task ID (e.g. project-a1b2c3d4) instead of a random suffix, making
  manual inspection easy
- Telemetry: six new events — WORKTREE_CREATED, WORKTREE_DELETED,
  WORKTREE_ORPHAN_DETECTED, PARALLEL_TASK_SPAWNED, PARALLEL_TASK_COMPLETED,
  PARALLEL_TASK_CHILD_FAILED — with matching TelemetryService capture methods
- error field on parallelResults items and abortOnChildFailure on HistoryItem
  schema so failure context survives process restarts

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Captures the full architecture plan for moving Moo Code from sequential
task delegation to genuine concurrent in-process swarm, modelled on the
claude-code teammate/swarm implementation.

Phases:
  P1 - Replace clineStack with concurrent tasks: Map, remove single-open invariant
  P2 - SwarmRegistry, AgentIdentity, round-robin color assignment
  P3 - InMemoryMailbox, idle worker loop, task_assignment/idle_notification
  P4 - LeaderPermissionBridge, worker badge in tool-ask UI
  P5 - FileMailbox with lockfile for cross-process workers
  P6 - CliWorkerBackend, moo-worker entry point, spawn_swarm tool

Includes data model changes, new event names, updated API surface for
spawn_parallel_tasks (concurrent flag) and new spawn_swarm tool spec,
UI changes, phased delivery estimates, and risk/mitigation table.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…path

Replace the LIFO `clineStack: Task[]` with a flat `tasks: Map<string, Task>`
(+ `focusedTaskId`, `leaderTaskId`, `childCompletionHandlers`) so multiple
tasks can be registered simultaneously — the prerequisite for true concurrent
fan-out.

Key changes:
- ClineProvider: swap all 19 clineStack usages; add `getTaskById()`,
  `spawnConcurrentChildren()`, `resolveChildCompletion()`
- SpawnParallelTasksTool: add `concurrent?: boolean` flag; concurrent path
  awaits Promise.all via spawnConcurrentChildren instead of queue drain
- AttemptCompletionTool: detect concurrent vs sequential by checking whether
  parent is still alive in the tasks map; route to resolveChildCompletion
  (concurrent) or reopenParentFromDelegation (sequential)
- Tests: update three spec files that accessed clineStack directly

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…ent spawn

Three targeted fixes:

1. Tool schema: add concurrent and abortOnChildFailure params to
   spawn_parallel_tasks so the LLM can discover and use them. Update
   description to explain sequential vs concurrent trade-offs.

2. Mode-switch race: spawnConcurrentChildren was using tasks.map(async)
   which ran all handleModeSwitch calls concurrently, causing each child
   to read whatever mode happened to win the race. Rewrite to a sequential
   for-loop for setup (mode switch + createTask), then a tight sync loop
   for all child.start() calls so execution is still concurrent.

3. abortOnChildFailure for concurrent mode: when a child rejects and the
   flag is set, immediately abort all sibling tasks via removeClineFromStack
   and reject their completion Promises. Previously this flag was only
   wired for the sequential queue-drain path.

Add 7 unit tests covering: aggregated results, serialised mode switches,
simultaneous start ordering, per-child error collection, sibling abort,
event emission, and worktree creation.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…i-agent workflows

Implements the Atlas-Agent-Teams pattern for Roo-Code:
- TeamConfig JSON schema in packages/types (slug, phases, agents, conventions)
- TeamsManager scans .roo/teams/*.json and caches configs
- RunTeamPhaseTool executes one phase: concurrent via spawnConcurrentChildren,
  sequential single via delegateParentAndOpenChild, sequential multiple via queue drain
- LLM schema (run_team_phase.ts) with orchestrator loop description
- Wired into ClineProvider (init, getTeamConfig, dispose), TOOL_GROUPS.modes,
  TOOL_DISPLAY_NAMES, NativeToolArgs, toolParamNames, and presentAssistantMessage
- Sample .roo/teams/fullstack.json: discovery (concurrent) → implementation → review

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…nce guide

- prd-swarm-multi-agent.md: mark Phase 1 and Teams (PT) as shipped in delivery
  table; update problem statement to reflect clineStack removal; add section 7b
  summarising the teams system and linking to the new reference
- docs/teams.md: new full reference for .roo/teams/*.json config format,
  template variables, execution modes, conventions injection, orchestrator loop
  pattern, and the fullstack.json example

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…current workers

- packages/types/src/swarm.ts: AgentColorName, AgentIdentity, SwarmSession,
  TeammateMessage stubs (P3)
- packages/types/src/history.ts: add swarmSessionId, agentId, agentName,
  agentColor, isSwarmLeader fields to HistoryItem schema
- packages/types/src/events.ts: add SwarmSessionStarted, SwarmSessionEnded,
  WorkerRegistered events to RooCodeEventName, rooCodeEventsSchema, taskEventSchema
- packages/types/src/task.ts: add swarm events to TaskProviderEvents so ClineProvider
  emit calls are properly typed
- src/core/swarm/SwarmRegistry.ts: round-robin color assignment, session lifecycle
- ClineProvider: add SwarmRegistry field; spawnConcurrentChildren now creates a
  session, assigns agentName/agentColor/agentId to each worker's HistoryItem,
  marks parent as isSwarmLeader, emits SwarmSessionStarted/WorkerRegistered/
  SwarmSessionEnded; accepts optional role field in task spec
- RunTeamPhaseTool: pass role through to spawnConcurrentChildren
- SubtaskRow: render 8px color dot (with tooltip showing agentName) when
  agentColor is set on a history item

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Infrastructure:
- IMailboxService interface (abstraction over in-process and future file backends)
- InMemoryMailbox: EventEmitter-based, instant delivery, configurable timeout fallback
- MailboxManager: per-session mailbox lifecycle + assignTask/shutdownWorker/
  waitForNextMessage/notifyIdle helpers

Events:
- WorkerIdle [sessionId, taskId] — emitted when a persistent worker finishes a turn
- WorkerShutdown [sessionId, taskId] — emitted when a worker receives shutdown_request

Idle loop (opt-in via persistent:true on spawnConcurrentChildren):
- spawnConcurrentChildren gains persistent?: boolean param; creates/destroys mailbox
- AttemptCompletionTool concurrent path: if session has an active mailbox, sends
  idle_notification and awaits task_assignment or shutdown_request (5-min safety
  timeout). On task_assignment: pushes new task context and returns "reassigned"
  so the LLM loop continues without resolving the parent Promise. On shutdown or
  timeout: resolves normally. TaskCompleted is NOT emitted for reassigned workers.
- DelegationProvider interface gains swarmRegistry, mailboxManager, emit fields

Public API on ClineProvider:
- assignTaskToWorker(sessionId, workerId, message): sends task_assignment
- shutdownWorkers(sessionId): broadcasts shutdown_request to all session workers

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…pproval

Workers that are running concurrently (parent still alive in task Map)
now route tool-approval through LeaderPermissionBridge instead of
surfacing a UI prompt on the hidden worker task.

- LeaderPermissionBridge: module-level singleton, register/submit/dialog
- presentAssistantMessage: intercept askApproval for concurrent workers
- ClineProvider: register showWorkerPermissionDialog on construction
- events/task.ts: PermissionRequested + PermissionResolved event types

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
FileMailbox implements IMailboxService using a JSON file per agent
with proper-lockfile for concurrent-write safety. Polling replaces
the EventEmitter used by InMemoryMailbox.

- FileMailbox: ~/<baseDir>/<safe-agentId>.json, 500ms poll interval
- Race-safe inbox creation via exclusive O_EXCL write (flag "wx")
- MailboxManager: createFileMailbox(sessionId, baseDir?) alongside
  existing createMailbox(); map type widened to IMailboxService

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@dosubot dosubot Bot added size:XXL This PR changes 1000+ lines, ignoring generated files. Enhancement New feature or request labels Apr 25, 2026
…utor

Backslashes were not escaped before double-quotes in the PowerShell
command wrapper, so paths like C:\foo\" would terminate the string
early and allow injection. cmd /c wrapper had no escaping at all.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement New feature or request size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant