JSPM

opencode-orchestrator

0.5.18
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2599
  • Score
    100M100P100Q105801F
  • License MIT

Distributed Cognitive Architecture for OpenCode. Turns simple prompts into specialized multi-agent workflows (Planner, Coder, Reviewer).

Package Exports

  • opencode-orchestrator

Readme

Logo

OpenCode Orchestrator 🎯

Enterprise-Grade Autonomous Multi-Agent Plugin for OpenCode

MIT License npm Tests


πŸš€ What's New in v0.6.0

Ultimate Agent Architecture - Production-ready distributed agent orchestration!

Feature Description
♾️ Unlimited Mode No step limits - runs until mission complete
🧠 Anti-Hallucination Research before coding, verify with docs
⚑ 50x Parallel Sessions Massive concurrent task execution
πŸ“Š Auto Memory Management GC, archiving, zero memory leaks
πŸ”„ Auto Recovery Handles rate limits, errors automatically
πŸ“‘ Event-Driven Real-time pub/sub across all components

πŸ›οΈ System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                                                                        β”‚
β”‚                                         USER REQUEST                                                   β”‚
β”‚                                    (OpenCode Terminal / UI)                                            β”‚
β”‚                                              β”‚                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                               β”‚
                                               β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                                                                        β”‚
β”‚                              ORCHESTRATOR PLUGIN  (src/index.ts)                                       β”‚
β”‚                                                                                                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚   Session State     β”‚  β”‚   Agent Definitions β”‚  β”‚   Tools Registry    β”‚  β”‚   Toast.enable      β”‚   β”‚
β”‚  β”‚   Map<sessionId,    β”‚  β”‚   (7 agents)        β”‚  β”‚   (15+ tools)       β”‚  β”‚   AutoToasts()      β”‚   β”‚
β”‚  β”‚   {step, maxSteps,  β”‚  β”‚                     β”‚  β”‚                     β”‚  β”‚   β†’ EventBus sub    β”‚   β”‚
β”‚  β”‚    timestamp}>      β”‚  β”‚   β€’ Commander 🎯    β”‚  β”‚   β€’ call_agent      β”‚  β”‚                     β”‚   β”‚
β”‚  β”‚                     β”‚  β”‚   β€’ Architect πŸ—οΈ   β”‚  β”‚   β€’ launch_parallel β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚  β”‚   Cleanup:          β”‚  β”‚   β€’ Builder πŸ”¨     β”‚  β”‚   β€’ check_parallel  β”‚                            β”‚
β”‚  β”‚   session.deleted   β”‚  β”‚   β€’ Inspector πŸ”   β”‚  β”‚   β€’ webfetch        β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚   β†’ sessions.delete β”‚  β”‚   β€’ Recorder πŸ’Ύ    β”‚  β”‚   β€’ websearch       β”‚  β”‚ ProgressTracker     β”‚   β”‚
β”‚  β”‚   β†’ Progress.clear  β”‚  β”‚   β€’ Librarian πŸ“š   β”‚  β”‚   β€’ grep_search     β”‚  β”‚   .startSession()   β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   β€’ Researcher πŸ”¬  β”‚  β”‚   β€’ run_background  β”‚  β”‚   .recordSnapshot() β”‚   β”‚
β”‚                           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚   .clearSession()   β”‚   β”‚
β”‚                                                                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                               β”‚                                                        β”‚
β”‚                                               β–Ό                                                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                                                                                                  β”‚  β”‚
β”‚  β”‚                               PARENT SESSION (Main Execution Loop)                              β”‚  β”‚
β”‚  β”‚                                                                                                  β”‚  β”‚
β”‚  β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚  β”‚   β”‚  Commander  │───▢│  Architect  │───▢│   Builder   │───▢│  Inspector  │───▢│  Recorder   β”‚  β”‚  β”‚
β”‚  β”‚   β”‚     🎯      β”‚    β”‚     πŸ—οΈ     β”‚    β”‚     πŸ”¨      β”‚    β”‚     πŸ”      β”‚    β”‚     πŸ’Ύ      β”‚  β”‚  β”‚
β”‚  β”‚   β”‚             β”‚    β”‚             β”‚    β”‚             β”‚    β”‚             β”‚    β”‚             β”‚  β”‚  β”‚
β”‚  β”‚   β”‚ Orchestrate β”‚    β”‚ Decompose   β”‚    β”‚ Implement   β”‚    β”‚ Audit &     β”‚    β”‚ Save        β”‚  β”‚  β”‚
β”‚  β”‚   β”‚ & delegate  β”‚    β”‚ into tasks  β”‚    β”‚ code        β”‚    β”‚ verify      β”‚    β”‚ context     β”‚  β”‚  β”‚
β”‚  β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚  β”‚                                                β”‚                                                β”‚  β”‚
β”‚  β”‚                                                β”‚ launch_parallel_agent()                        β”‚  β”‚
β”‚  β”‚                                                β–Ό                                                β”‚  β”‚
β”‚  β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚  β”‚
β”‚  β”‚   β”‚                                                                                           β”‚ β”‚  β”‚
β”‚  β”‚   β”‚    hooks: "chat.message" / "tool.execute.after" / "handler"                               β”‚ β”‚  β”‚
β”‚  β”‚   β”‚                                                                                           β”‚ β”‚  β”‚
β”‚  β”‚   β”‚    chat.message:                                                                          β”‚ β”‚  β”‚
β”‚  β”‚   β”‚      β€’ Parse /task, /plan slash commands                                                  β”‚ β”‚  β”‚
β”‚  β”‚   β”‚      β€’ Auto-start session on Commander agent selection                                    β”‚ β”‚  β”‚
β”‚  β”‚   β”‚      β€’ emit(TASK_EVENTS.STARTED, { taskId, agent })                                       β”‚ β”‚  β”‚
β”‚  β”‚   β”‚                                                                                           β”‚ β”‚  β”‚
β”‚  β”‚   β”‚    tool.execute.after:                                                                    β”‚ β”‚  β”‚
β”‚  β”‚   β”‚      β€’ Check "MISSION COMPLETE" β†’ emit(MISSION_EVENTS.COMPLETE)                           β”‚ β”‚  β”‚
β”‚  β”‚   β”‚      β€’ Check "/stop" or "/cancel" β†’ emit(TASK_EVENTS.FAILED)                              β”‚ β”‚  β”‚
β”‚  β”‚   β”‚      β€’ Record ProgressTracker.recordSnapshot()                                             β”‚ β”‚  β”‚
β”‚  β”‚   β”‚      β€’ Inject CONTINUE_INSTRUCTION β†’ client.session.prompt()                              β”‚ β”‚  β”‚
β”‚  β”‚   β”‚                                                                                           β”‚ β”‚  β”‚
β”‚  β”‚   β”‚    handler (event):                                                                       β”‚ β”‚  β”‚
β”‚  β”‚   β”‚      β€’ session.deleted β†’ cleanup sessions, state, ProgressTracker                         β”‚ β”‚  β”‚
β”‚  β”‚   β”‚      β€’ Pass to ParallelAgentManager.handleEvent()                                         β”‚ β”‚  β”‚
β”‚  β”‚   β”‚                                                                                           β”‚ β”‚  β”‚
β”‚  β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚  β”‚
β”‚  β”‚                                                                                                  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                                                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                     β”‚
                                                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                                                                        β”‚
β”‚                            PARALLEL AGENT MANAGER  (src/core/agents/manager.ts)                        β”‚
β”‚                                                                                                        β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚   β”‚                                   Component Composition                                         β”‚  β”‚
β”‚   β”‚                                                                                                 β”‚  β”‚
β”‚   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚  β”‚
β”‚   β”‚   β”‚    TaskLauncher       β”‚      β”‚    TaskResumer        β”‚      β”‚    TaskPoller         β”‚      β”‚  β”‚
β”‚   β”‚   β”‚  (task-launcher.ts)   β”‚      β”‚  (task-resumer.ts)    β”‚      β”‚  (task-poller.ts)     β”‚      β”‚  β”‚
β”‚   β”‚   β”‚  ─────────────────    β”‚      β”‚  ─────────────────    β”‚      β”‚  ─────────────────    β”‚      β”‚  β”‚
β”‚   β”‚   β”‚                       β”‚      β”‚                       β”‚      β”‚                       β”‚      β”‚  β”‚
β”‚   β”‚   β”‚  async launch():      β”‚      β”‚  async resume():      β”‚      β”‚  poll() every 1s:     β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    1. await acquire() β”‚      β”‚    1. Find task       β”‚      β”‚    1. Get running     β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    2. session.create()β”‚      β”‚    2. session.message β”‚      β”‚    2. Check events    β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    3. store.set()     β”‚      β”‚    3. Notify parent   β”‚      β”‚    3. If idle+stable  β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    4. emit(STARTED)   β”‚      β”‚                       β”‚      β”‚       β†’ completed     β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    5. session.message β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚    4. emit(COMPLETED) β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    6. Start poller    β”‚                                     β”‚    5. scheduleCleanup β”‚      β”‚  β”‚
β”‚   β”‚   β”‚                       β”‚                                     β”‚                       β”‚      β”‚  β”‚
β”‚   β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚  β”‚
β”‚   β”‚               β”‚                                                             β”‚                  β”‚  β”‚
β”‚   β”‚               β–Ό                                                             β–Ό                  β”‚  β”‚
β”‚   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚  β”‚
β”‚   β”‚   β”‚    TaskCleaner        β”‚      β”‚    EventHandler       β”‚      β”‚ ConcurrencyController β”‚      β”‚  β”‚
β”‚   β”‚   β”‚  (task-cleaner.ts)    β”‚      β”‚  (event-handler.ts)   β”‚      β”‚  (concurrency.ts)     β”‚      β”‚  β”‚
β”‚   β”‚   β”‚  ─────────────────    β”‚      β”‚  ─────────────────    β”‚      β”‚  ─────────────────    β”‚      β”‚  β”‚
β”‚   β”‚   β”‚                       β”‚      β”‚                       β”‚      β”‚                       β”‚      β”‚  β”‚
β”‚   β”‚   β”‚  pruneExpiredTasks(): β”‚      β”‚  handle(event):       β”‚      β”‚  acquire(key):        β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    β€’ TTL > 60min      β”‚      β”‚                       β”‚      β”‚    β€’ limit = 10       β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    β†’ status=timeout   β”‚      β”‚    session.idle:      β”‚      β”‚    β€’ if < limit       β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    β†’ release()        β”‚      β”‚      β€’ MIN_STABILITY  β”‚      β”‚      β†’ immediate      β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    β†’ session.delete() β”‚      β”‚      β€’ validateOutput β”‚      β”‚    β€’ else queue.push  β”‚      β”‚  β”‚
β”‚   β”‚   β”‚                       β”‚      β”‚      β†’ completed      β”‚      β”‚                       β”‚      β”‚  β”‚
β”‚   β”‚   β”‚  scheduleCleanup():   β”‚      β”‚      β†’ release()      β”‚      β”‚  release(key):        β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    β€’ setTimeout 10min β”‚      β”‚      β†’ scheduleClean  β”‚      β”‚    β€’ if queue.length  β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    β†’ session.delete() β”‚      β”‚                       β”‚      β”‚      β†’ queue.shift()  β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    β†’ store.delete()   β”‚      β”‚    session.deleted:   β”‚      β”‚      β†’ next()         β”‚      β”‚  β”‚
β”‚   β”‚   β”‚                       β”‚      β”‚      β†’ release()      β”‚      β”‚    β€’ else count--     β”‚      β”‚  β”‚
β”‚   β”‚   β”‚  notifyParent():      β”‚      β”‚      β†’ store.delete() β”‚      β”‚                       β”‚      β”‚  β”‚
β”‚   β”‚   β”‚    β†’ session.prompt() β”‚      β”‚                       β”‚      β”‚  getLimit(key):       β”‚      β”‚  β”‚
β”‚   β”‚   β”‚                       β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚    β€’ MAX_TOTAL = 50   β”‚      β”‚  β”‚
β”‚   β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                     β”‚    β€’ PER_AGENT = 10   β”‚      β”‚  β”‚
β”‚   β”‚                                                                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚  β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                     β”‚                                                  β”‚
β”‚                                                     β–Ό                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚   β”‚                                                                                                 β”‚  β”‚
β”‚   β”‚                              TaskStore  (task-store.ts)                                         β”‚  β”‚
β”‚   β”‚                                                                                                 β”‚  β”‚
β”‚   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚  β”‚
β”‚   β”‚   β”‚   tasks: Map<id, Task>  β”‚  β”‚ pendingByParent: Map    β”‚  β”‚ notifications: Map      β”‚        β”‚  β”‚
β”‚   β”‚   β”‚   MAX: 1000             β”‚  β”‚ <parentId, Set<taskId>> β”‚  β”‚ <parentId, Task[]>      β”‚        β”‚  β”‚
β”‚   β”‚   β”‚                         β”‚  β”‚                         β”‚  β”‚ MAX: 100/parent         β”‚        β”‚  β”‚
β”‚   β”‚   β”‚   set() β†’ auto gc()     β”‚  β”‚ trackPending()          β”‚  β”‚                         β”‚        β”‚  β”‚
β”‚   β”‚   β”‚   getRunning()          β”‚  β”‚ untrackPending()        β”‚  β”‚ queueNotification()     β”‚        β”‚  β”‚
β”‚   β”‚   β”‚   getByParent()         β”‚  β”‚ hasPending()            β”‚  β”‚ β†’ FIFO eviction         β”‚        β”‚  β”‚
β”‚   β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚  β”‚
β”‚   β”‚                                                                                                 β”‚  β”‚
β”‚   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚   β”‚   β”‚                                                                                          β”‚  β”‚  β”‚
β”‚   β”‚   β”‚   async gc():                                                                            β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ completed > 30min β†’ archiveTasks() β†’ .cache/task-archive/tasks_YYYY-MM-DD.jsonl   β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ error/cancelled > 10min β†’ delete                                                  β”‚  β”‚  β”‚
β”‚   β”‚   β”‚                                                                                          β”‚  β”‚  β”‚
β”‚   β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚   β”‚                                                                                                 β”‚  β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                     β”‚                                                  β”‚
β”‚                                                     β–Ό                                                  β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚   β”‚                                                                                                 β”‚  β”‚
β”‚   β”‚                           CHILD SESSIONS POOL  (up to 50 concurrent)                            β”‚  β”‚
β”‚   β”‚                                                                                                 β”‚  β”‚
β”‚   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚   β”‚   β”‚Session 1 β”‚ β”‚Session 2 β”‚ β”‚Session 3 β”‚ β”‚Session 4 β”‚ β”‚Session 5 β”‚ β”‚Session 6 β”‚ β”‚ ... 50   β”‚  β”‚  β”‚
β”‚   β”‚   β”‚ Builder  β”‚ β”‚Librarian β”‚ β”‚Researcherβ”‚ β”‚Inspector β”‚ β”‚ Builder  β”‚ β”‚ Builder  β”‚ β”‚          β”‚  β”‚  β”‚
β”‚   β”‚   β”‚   πŸ”¨     β”‚ β”‚   πŸ“š     β”‚ β”‚   πŸ”¬     β”‚ β”‚   πŸ”     β”‚ β”‚   πŸ”¨     β”‚ β”‚   πŸ”¨     β”‚ β”‚          β”‚  β”‚  β”‚
β”‚   β”‚   β”‚          β”‚ β”‚          β”‚ β”‚          β”‚ β”‚          β”‚ β”‚          β”‚ β”‚          β”‚ β”‚          β”‚  β”‚  β”‚
β”‚   β”‚   β”‚ running  β”‚ β”‚ running  β”‚ β”‚completed β”‚ β”‚ running  β”‚ β”‚ error    β”‚ β”‚ pending  β”‚ β”‚          β”‚  β”‚  β”‚
β”‚   β”‚   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚   β”‚        β”‚            β”‚            β”‚            β”‚            β”‚            β”‚                      β”‚  β”‚
β”‚   β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β”‚  β”‚
β”‚   β”‚                                         β”‚                                                       β”‚  β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                             β”‚                                                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                              β”‚
                                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                                                                        β”‚
β”‚                                    EVENT BUS  (src/core/bus/)                                          β”‚
β”‚                                                                                                        β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚   β”‚                                                                                                 β”‚  β”‚
β”‚   β”‚                                    Event Types (Pub/Sub)                                        β”‚  β”‚
β”‚   β”‚                                                                                                 β”‚  β”‚
β”‚   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚   β”‚   β”‚task.started β”‚  β”‚task.completedβ”‚ β”‚ task.failed β”‚  β”‚session.idle β”‚  β”‚ mission.complete    β”‚  β”‚  β”‚
β”‚   β”‚   β”‚             β”‚  β”‚             β”‚  β”‚             β”‚  β”‚session.deleteβ”‚ β”‚ mission.all_completeβ”‚  β”‚  β”‚
β”‚   β”‚   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚   β”‚          β”‚                β”‚                β”‚                β”‚                    β”‚             β”‚  β”‚
β”‚   β”‚          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚  β”‚
β”‚   β”‚                                            β”‚                                                    β”‚  β”‚
β”‚   β”‚                                            β–Ό                                                    β”‚  β”‚
β”‚   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚   β”‚   β”‚                                    Subscribers                                           β”‚  β”‚  β”‚
β”‚   β”‚   β”‚                                                                                          β”‚  β”‚  β”‚
β”‚   β”‚   β”‚   Toast.enableAutoToasts():           EventHandler.handle():                             β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ task.started β†’ presets.taskStarted()      β€’ release concurrency                    β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ task.completed β†’ presets.taskCompleted()  β€’ cleanup resources                      β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ task.failed β†’ presets.taskFailed()                                                β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ mission.complete β†’ presets.missionComplete()                                      β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ document.cached β†’ presets.documentCached()                                        β”‚  β”‚  β”‚
β”‚   β”‚   β”‚                                                                                          β”‚  β”‚  β”‚
β”‚   β”‚   β”‚   Returns: () => void (unsubscribe function for cleanup)                                β”‚  β”‚  β”‚
β”‚   β”‚   β”‚                                                                                          β”‚  β”‚  β”‚
β”‚   β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚   β”‚                                                                                                 β”‚  β”‚
β”‚   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚   β”‚   β”‚   EventBusImpl:                                                                          β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ subscribe(type, handler) β†’ unsubscribe fn                                         β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ publish(type, properties) β†’ Event                                                 β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ emit(type, properties) β†’ void                                                     β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ once(type, handler) β†’ unsubscribe fn                                              β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ waitFor(type, timeout) β†’ Promise<Event>                                           β”‚  β”‚  β”‚
β”‚   β”‚   β”‚     β€’ history: Event[] (max 100, FIFO)                                                  β”‚  β”‚  β”‚
β”‚   β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚   β”‚                                                                                                 β”‚  β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                                                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                     β”‚
                                                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                                                                        β”‚
β”‚                                        CORE SYSTEMS LAYER                                              β”‚
β”‚                                                                                                        β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚   β”‚   Progress Tracker       β”‚  β”‚   Auto Recovery          β”‚  β”‚   Document Cache         β”‚            β”‚
β”‚   β”‚   (src/core/progress/)   β”‚  β”‚   (src/core/recovery/)   β”‚  β”‚   (src/core/cache/)      β”‚            β”‚
β”‚   β”‚   ──────────────────     β”‚  β”‚   ──────────────────     β”‚  β”‚   ──────────────────     β”‚            β”‚
β”‚   β”‚                          β”‚  β”‚                          β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚   startSession(id)       β”‚  β”‚   handleError(context)   β”‚  β”‚   get(filename)          β”‚            β”‚
β”‚   β”‚   recordSnapshot(id, {   β”‚  β”‚     β†’ match patterns     β”‚  β”‚   set(filename, content) β”‚            β”‚
β”‚   β”‚     currentStep,         β”‚  β”‚     β†’ return action      β”‚  β”‚   list()                 β”‚            β”‚
β”‚   β”‚     maxSteps             β”‚  β”‚                          β”‚  β”‚   clear(filename)        β”‚            β”‚
β”‚   β”‚   })                     β”‚  β”‚   Patterns:              β”‚  β”‚   cleanExpired()         β”‚            β”‚
β”‚   β”‚   formatCompact(id)      β”‚  β”‚     β€’ rate_limit         β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚   clearSession(id)       β”‚  β”‚       β†’ retry+backoff    β”‚  β”‚   Storage:               β”‚            β”‚
β”‚   β”‚                          β”‚  β”‚     β€’ context_overflow   β”‚  β”‚   .cache/docs/*.md       β”‚            β”‚
β”‚   β”‚   Store:                 β”‚  β”‚       β†’ compact          β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚   sessions: Map<id,      β”‚  β”‚     β€’ network            β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚     ProgressSnapshot[]>  β”‚  β”‚       β†’ retry 3x         β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚   max 100/session        β”‚  β”‚     β€’ parse_error        β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚                          β”‚  β”‚       β†’ skip             β”‚  β”‚                          β”‚            β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β”‚                                                                                                        β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚   β”‚   Toast Notifier         β”‚  β”‚   Async Queue            β”‚  β”‚   Background Commands    β”‚            β”‚
β”‚   β”‚   (src/core/notification)β”‚  β”‚   (src/core/queue/)      β”‚  β”‚   (src/core/commands/)   β”‚            β”‚
β”‚   β”‚   ──────────────────     β”‚  β”‚   ──────────────────     β”‚  β”‚   ──────────────────     β”‚            β”‚
β”‚   β”‚                          β”‚  β”‚                          β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚   show({ title, msg })   β”‚  β”‚   workPool(items, fn,    β”‚  β”‚   runBackground(cmd)     β”‚            β”‚
β”‚   β”‚                          β”‚  β”‚     concurrency)         β”‚  β”‚   checkBackground(id)    β”‚            β”‚
β”‚   β”‚   presets:               β”‚  β”‚   workPoolWithResults()  β”‚  β”‚   listBackground()       β”‚            β”‚
β”‚   β”‚     β€’ taskStarted()      β”‚  β”‚   processBatches()       β”‚  β”‚   killBackground(id)     β”‚            β”‚
β”‚   β”‚     β€’ taskCompleted()    β”‚  β”‚                          β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚     β€’ taskFailed()       β”‚  β”‚   retryWithBackoff(fn,   β”‚  β”‚   Storage:               β”‚            β”‚
β”‚   β”‚     β€’ missionComplete()  β”‚  β”‚     maxRetries, delay)   β”‚  β”‚   backgroundJobs: Map    β”‚            β”‚
β”‚   β”‚     β€’ documentCached()   β”‚  β”‚   withTimeout(fn, ms)    β”‚  β”‚   <id, BackgroundTask>   β”‚            β”‚
β”‚   β”‚                          β”‚  β”‚   debounceAsync(fn, ms)  β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚   enableAutoToasts()     β”‚  β”‚                          β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚   β†’ EventBus.subscribe() β”‚  β”‚   AsyncQueue<T>:         β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚   β†’ returns disable fn   β”‚  β”‚     async iterator       β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚                          β”‚  β”‚                          β”‚  β”‚                          β”‚            β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β”‚                                                                                                        β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚   β”‚   Shared Context         β”‚  β”‚   Task Decomposer        β”‚  β”‚   Todo Enforcer          β”‚            β”‚
β”‚   β”‚   (src/core/session/)    β”‚  β”‚   (src/core/task/)       β”‚  β”‚   (src/core/loop/)       β”‚            β”‚
β”‚   β”‚   ──────────────────     β”‚  β”‚   ──────────────────     β”‚  β”‚   ──────────────────     β”‚            β”‚
β”‚   β”‚                          β”‚  β”‚                          β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚   create(id, parentId)   β”‚  β”‚   create(id, objective)  β”‚  β”‚   parseTodos(data)       β”‚            β”‚
β”‚   β”‚   get(id)                β”‚  β”‚   addTask(id, {          β”‚  β”‚   getIncompleteCount()   β”‚            β”‚
β”‚   β”‚   getMerged(id)          β”‚  β”‚     description,         β”‚  β”‚   hasRemainingWork()     β”‚            β”‚
β”‚   β”‚   β†’ includes parent ctx  β”‚  β”‚     level: 1|2|3,        β”‚  β”‚   getNextPending()       β”‚            β”‚
β”‚   β”‚                          β”‚  β”‚     parallelGroup?,      β”‚  β”‚   getStats()             β”‚            β”‚
β”‚   β”‚   addDocument(id, doc)   β”‚  β”‚     dependsOn?           β”‚  β”‚   formatProgress()       β”‚            β”‚
β”‚   β”‚   addFinding(id, find)   β”‚  β”‚   })                     β”‚  β”‚   isMissionComplete()    β”‚            β”‚
β”‚   β”‚   addDecision(id, dec)   β”‚  β”‚   updateStatus(id, task) β”‚  β”‚                          β”‚            β”‚
β”‚   β”‚                          β”‚  β”‚   getNextTasks(id)       β”‚  β”‚   generateContinuation   β”‚            β”‚
β”‚   β”‚   delete(id)             β”‚  β”‚   getParallelBatch(id)   β”‚  β”‚     Prompt()             β”‚            β”‚
β”‚   β”‚   getStats(id)           β”‚  β”‚   getSummary(id)         β”‚  β”‚   generateCompletion     β”‚            β”‚
β”‚   β”‚                          β”‚  β”‚                          β”‚  β”‚     Message()            β”‚            β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β”‚                                                                                                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎯 Key Differentiators

Capability OpenCode Orchestrator Basic Plugins
Parallel Sessions Up to 50 concurrent Single session
Memory Management Auto GC + disk archiving Memory leaks
Error Recovery Pattern-based auto retry Crash
Context Sharing Parent-child merge Isolated
Event System Real-time pub/sub None
Task Decomposition 3-level hierarchy Flat

Installation

npm install -g opencode-orchestrator

Restart OpenCode after installation.


Usage

Press Tab in OpenCode β†’ Select Commander β†’ Type your mission!

Commander TUI

Commander agent selection interface in OpenCode (TUI)


Commander Windows

Execution of Commander agent on Windows environment

"Fix the login bug in the docker-compose environment"

πŸ’‘ Recommended: For complex missions, select Commander directly via Tab to use the full orchestration system with parallel processing, anti-hallucination, and auto-recovery features.

πŸ“‹ Use /task Command (Simple Tasks)

For quick, simple tasks, you can use the /task command:

/task "Add a loading spinner to the button"

⚠️ Note: /task uses a simplified prompt template. For complex multi-step missions, use Commander directly via Tab key.


The 7 Agents

Agent Role Responsibility
Commander 🎯 Orchestrator Autonomous mission control
Architect πŸ—οΈ Planner Hierarchical task decomposition
Builder πŸ”¨ Developer Full-stack implementation
Inspector πŸ” Quality Audit, auto-fix & doc verification
Recorder πŸ’Ύ Context Progress tracking
Librarian πŸ“š Research Documentation & API research
Researcher πŸ”¬ Investigation Pre-task research & analysis

πŸ› οΈ Available Tools

Tool Description
call_agent Call another agent synchronously
launch_parallel_agent Start parallel async session
check_parallel_task Check task status
collect_parallel_results Gather completed results
webfetch Fetch URL content as Markdown
websearch Search web (SearXNG β†’ Brave β†’ DuckDuckGo)
codesearch Search open source code patterns
cache_docs Manage cached documentation
run_background Run command in background
grep_search / glob_search Fast file search

πŸ“Š Resource Guarantees

Resource Limit Safety Mechanism
Parallel Sessions 50 Queue overflow protection
Tasks in Memory 1,000 Auto GC + disk archive
Notifications 100/parent FIFO eviction
Event History 100 Ring buffer
Session TTL 60 min Auto cleanup
Poll Interval 1 second Fast completion detection

πŸ§ͺ Test Coverage

Test Files:  18 passed
Tests:       211 passed
Duration:    ~4.3s

Uninstall

npm uninstall -g opencode-orchestrator

Documentation


License

MIT License. LICENSE


Enterprise-scale. Memory-safe. Self-healing. Unlimited.