JSPM

opencode-orchestrator

0.5.30
  • 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

πŸš€ Two Modes of Operation

Mode Trigger Behavior
Commander Mode 🎯 /task "mission" Full autonomous execution until MISSION COMPLETE
Chat Mode πŸ’¬ Regular conversation Simple Q&A, no autonomous behavior

Use /task when you need the AI to complete a mission autonomously:

/task "Fix the login bug in the docker-compose environment"
/task "Add dark mode support to the entire app"
/task "Refactor the API to use TypeScript"

What Commander Mode Does:

  • ♾️ Runs until done β€” Never stops until "MISSION COMPLETE"
  • 🧠 Anti-Hallucination β€” Researches docs before coding
  • ⚑ Parallel Execution β€” Up to 50 concurrent agents
  • πŸ”„ Auto-Recovery β€” Handles errors automatically
  • πŸ“Š Trriage System β€” Adapts strategy to complexity (L1/L2/L3)
Commander TUI

/task "mission" triggers full Commander mode


πŸ’¬ Chat Mode - Regular Conversation (Simple Q&A)

Just type normally without /task for simple questions:

How do I add a loading spinner?
What's the difference between useState and useReducer?

Chat Mode is just regular conversation β€” no autonomous execution, no parallel agents, no mission tracking.


πŸ’‘ Pro Tip: Use /task for anything that requires multiple steps, file changes, or verification. Use Chat Mode for quick questions.


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.