opencode-orchestrator 0.6.0 β†’ 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -30,276 +30,67 @@
30
30
  ## πŸ›οΈ System Architecture
31
31
 
32
32
  ```
33
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
34
- β”‚ β”‚
35
- β”‚ USER REQUEST β”‚
36
- β”‚ (OpenCode Terminal / UI) β”‚
37
- β”‚ β”‚ β”‚
38
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
39
- β”‚
40
- β–Ό
41
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
42
- β”‚ β”‚
43
- β”‚ ORCHESTRATOR PLUGIN (src/index.ts) β”‚
44
- β”‚ β”‚
45
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
46
- β”‚ β”‚ Session State β”‚ β”‚ Agent Definitions β”‚ β”‚ Tools Registry β”‚ β”‚ Toast.enable β”‚ β”‚
47
- β”‚ β”‚ Map<sessionId, β”‚ β”‚ (7 agents) β”‚ β”‚ (15+ tools) β”‚ β”‚ AutoToasts() β”‚ β”‚
48
- β”‚ β”‚ {step, maxSteps, β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β†’ EventBus sub β”‚ β”‚
49
- β”‚ β”‚ timestamp}> β”‚ β”‚ β€’ Commander 🎯 β”‚ β”‚ β€’ call_agent β”‚ β”‚ β”‚ β”‚
50
- β”‚ β”‚ β”‚ β”‚ β€’ Architect πŸ—οΈ β”‚ β”‚ β€’ launch_parallel β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
51
- β”‚ β”‚ Cleanup: β”‚ β”‚ β€’ Builder πŸ”¨ β”‚ β”‚ β€’ check_parallel β”‚ β”‚
52
- β”‚ β”‚ session.deleted β”‚ β”‚ β€’ Inspector πŸ” β”‚ β”‚ β€’ webfetch β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
53
- β”‚ β”‚ β†’ sessions.delete β”‚ β”‚ β€’ Recorder πŸ’Ύ β”‚ β”‚ β€’ websearch β”‚ β”‚ ProgressTracker β”‚ β”‚
54
- β”‚ β”‚ β†’ Progress.clear β”‚ β”‚ β€’ Librarian πŸ“š β”‚ β”‚ β€’ grep_search β”‚ β”‚ .startSession() β”‚ β”‚
55
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β€’ Researcher πŸ”¬ β”‚ β”‚ β€’ run_background β”‚ β”‚ .recordSnapshot() β”‚ β”‚
56
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ .clearSession() β”‚ β”‚
57
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
58
- β”‚ β”‚ β”‚
59
- β”‚ β–Ό β”‚
60
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
61
- β”‚ β”‚ β”‚ β”‚
62
- β”‚ β”‚ PARENT SESSION (Main Execution Loop) β”‚ β”‚
63
- β”‚ β”‚ β”‚ β”‚
64
- β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
65
- β”‚ β”‚ β”‚ Commander │───▢│ Architect │───▢│ Builder │───▢│ Inspector │───▢│ Recorder β”‚ β”‚ β”‚
66
- β”‚ β”‚ β”‚ 🎯 β”‚ β”‚ πŸ—οΈ β”‚ β”‚ πŸ”¨ β”‚ β”‚ πŸ” β”‚ β”‚ πŸ’Ύ β”‚ β”‚ β”‚
67
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
68
- β”‚ β”‚ β”‚ Orchestrate β”‚ β”‚ Decompose β”‚ β”‚ Implement β”‚ β”‚ Audit & β”‚ β”‚ Save β”‚ β”‚ β”‚
69
- β”‚ β”‚ β”‚ & delegate β”‚ β”‚ into tasks β”‚ β”‚ code β”‚ β”‚ verify β”‚ β”‚ context β”‚ β”‚ β”‚
70
- β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
71
- β”‚ β”‚ β”‚ β”‚ β”‚
72
- β”‚ β”‚ β”‚ launch_parallel_agent() β”‚ β”‚
73
- β”‚ β”‚ β–Ό β”‚ β”‚
74
- β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
75
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
76
- β”‚ β”‚ β”‚ hooks: "chat.message" / "tool.execute.after" / "handler" β”‚ β”‚ β”‚
77
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
78
- β”‚ β”‚ β”‚ chat.message: β”‚ β”‚ β”‚
79
- β”‚ β”‚ β”‚ β€’ Parse /task, /plan slash commands β”‚ β”‚ β”‚
80
- β”‚ β”‚ β”‚ β€’ Auto-start session on Commander agent selection β”‚ β”‚ β”‚
81
- β”‚ β”‚ β”‚ β€’ emit(TASK_EVENTS.STARTED, { taskId, agent }) β”‚ β”‚ β”‚
82
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
83
- β”‚ β”‚ β”‚ tool.execute.after: β”‚ β”‚ β”‚
84
- β”‚ β”‚ β”‚ β€’ Check "MISSION COMPLETE" β†’ emit(MISSION_EVENTS.COMPLETE) β”‚ β”‚ β”‚
85
- β”‚ β”‚ β”‚ β€’ Check "/stop" or "/cancel" β†’ emit(TASK_EVENTS.FAILED) β”‚ β”‚ β”‚
86
- β”‚ β”‚ β”‚ β€’ Record ProgressTracker.recordSnapshot() β”‚ β”‚ β”‚
87
- β”‚ β”‚ β”‚ β€’ Inject CONTINUE_INSTRUCTION β†’ client.session.prompt() β”‚ β”‚ β”‚
88
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
89
- β”‚ β”‚ β”‚ handler (event): β”‚ β”‚ β”‚
90
- β”‚ β”‚ β”‚ β€’ session.deleted β†’ cleanup sessions, state, ProgressTracker β”‚ β”‚ β”‚
91
- β”‚ β”‚ β”‚ β€’ Pass to ParallelAgentManager.handleEvent() β”‚ β”‚ β”‚
92
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
93
- β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
94
- β”‚ β”‚ β”‚ β”‚
95
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
96
- β”‚ β”‚
97
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
98
- β”‚
99
- β–Ό
100
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
101
- β”‚ β”‚
102
- β”‚ PARALLEL AGENT MANAGER (src/core/agents/manager.ts) β”‚
103
- β”‚ β”‚
104
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
105
- β”‚ β”‚ Component Composition β”‚ β”‚
106
- β”‚ β”‚ β”‚ β”‚
107
- β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
108
- β”‚ β”‚ β”‚ TaskLauncher β”‚ β”‚ TaskResumer β”‚ β”‚ TaskPoller β”‚ β”‚ β”‚
109
- β”‚ β”‚ β”‚ (task-launcher.ts) β”‚ β”‚ (task-resumer.ts) β”‚ β”‚ (task-poller.ts) β”‚ β”‚ β”‚
110
- β”‚ β”‚ β”‚ ───────────────── β”‚ β”‚ ───────────────── β”‚ β”‚ ───────────────── β”‚ β”‚ β”‚
111
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
112
- β”‚ β”‚ β”‚ async launch(): β”‚ β”‚ async resume(): β”‚ β”‚ poll() every 1s: β”‚ β”‚ β”‚
113
- β”‚ β”‚ β”‚ 1. await acquire() β”‚ β”‚ 1. Find task β”‚ β”‚ 1. Get running β”‚ β”‚ β”‚
114
- β”‚ β”‚ β”‚ 2. session.create()β”‚ β”‚ 2. session.message β”‚ β”‚ 2. Check events β”‚ β”‚ β”‚
115
- β”‚ β”‚ β”‚ 3. store.set() β”‚ β”‚ 3. Notify parent β”‚ β”‚ 3. If idle+stable β”‚ β”‚ β”‚
116
- β”‚ β”‚ β”‚ 4. emit(STARTED) β”‚ β”‚ β”‚ β”‚ β†’ completed β”‚ β”‚ β”‚
117
- β”‚ β”‚ β”‚ 5. session.message β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ 4. emit(COMPLETED) β”‚ β”‚ β”‚
118
- β”‚ β”‚ β”‚ 6. Start poller β”‚ β”‚ 5. scheduleCleanup β”‚ β”‚ β”‚
119
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
120
- β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
121
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
122
- β”‚ β”‚ β–Ό β–Ό β”‚ β”‚
123
- β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
124
- β”‚ β”‚ β”‚ TaskCleaner β”‚ β”‚ EventHandler β”‚ β”‚ ConcurrencyController β”‚ β”‚ β”‚
125
- β”‚ β”‚ β”‚ (task-cleaner.ts) β”‚ β”‚ (event-handler.ts) β”‚ β”‚ (concurrency.ts) β”‚ β”‚ β”‚
126
- β”‚ β”‚ β”‚ ───────────────── β”‚ β”‚ ───────────────── β”‚ β”‚ ───────────────── β”‚ β”‚ β”‚
127
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
128
- β”‚ β”‚ β”‚ pruneExpiredTasks(): β”‚ β”‚ handle(event): β”‚ β”‚ acquire(key): β”‚ β”‚ β”‚
129
- β”‚ β”‚ β”‚ β€’ TTL > 60min β”‚ β”‚ β”‚ β”‚ β€’ limit = 10 β”‚ β”‚ β”‚
130
- β”‚ β”‚ β”‚ β†’ status=timeout β”‚ β”‚ session.idle: β”‚ β”‚ β€’ if < limit β”‚ β”‚ β”‚
131
- β”‚ β”‚ β”‚ β†’ release() β”‚ β”‚ β€’ MIN_STABILITY β”‚ β”‚ β†’ immediate β”‚ β”‚ β”‚
132
- β”‚ β”‚ β”‚ β†’ session.delete() β”‚ β”‚ β€’ validateOutput β”‚ β”‚ β€’ else queue.push β”‚ β”‚ β”‚
133
- β”‚ β”‚ β”‚ β”‚ β”‚ β†’ completed β”‚ β”‚ β”‚ β”‚ β”‚
134
- β”‚ β”‚ β”‚ scheduleCleanup(): β”‚ β”‚ β†’ release() β”‚ β”‚ release(key): β”‚ β”‚ β”‚
135
- β”‚ β”‚ β”‚ β€’ setTimeout 10min β”‚ β”‚ β†’ scheduleClean β”‚ β”‚ β€’ if queue.length β”‚ β”‚ β”‚
136
- β”‚ β”‚ β”‚ β†’ session.delete() β”‚ β”‚ β”‚ β”‚ β†’ queue.shift() β”‚ β”‚ β”‚
137
- β”‚ β”‚ β”‚ β†’ store.delete() β”‚ β”‚ session.deleted: β”‚ β”‚ β†’ next() β”‚ β”‚ β”‚
138
- β”‚ β”‚ β”‚ β”‚ β”‚ β†’ release() β”‚ β”‚ β€’ else count-- β”‚ β”‚ β”‚
139
- β”‚ β”‚ β”‚ notifyParent(): β”‚ β”‚ β†’ store.delete() β”‚ β”‚ β”‚ β”‚ β”‚
140
- β”‚ β”‚ β”‚ β†’ session.prompt() β”‚ β”‚ β”‚ β”‚ getLimit(key): β”‚ β”‚ β”‚
141
- β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β€’ MAX_TOTAL = 50 β”‚ β”‚ β”‚
142
- β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β€’ PER_AGENT = 10 β”‚ β”‚ β”‚
143
- β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
144
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
145
- β”‚ β”‚ β”‚
146
- β”‚ β–Ό β”‚
147
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
148
- β”‚ β”‚ β”‚ β”‚
149
- β”‚ β”‚ TaskStore (task-store.ts) β”‚ β”‚
150
- β”‚ β”‚ β”‚ β”‚
151
- β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
152
- β”‚ β”‚ β”‚ tasks: Map<id, Task> β”‚ β”‚ pendingByParent: Map β”‚ β”‚ notifications: Map β”‚ β”‚ β”‚
153
- β”‚ β”‚ β”‚ MAX: 1000 β”‚ β”‚ <parentId, Set<taskId>> β”‚ β”‚ <parentId, Task[]> β”‚ β”‚ β”‚
154
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ MAX: 100/parent β”‚ β”‚ β”‚
155
- β”‚ β”‚ β”‚ set() β†’ auto gc() β”‚ β”‚ trackPending() β”‚ β”‚ β”‚ β”‚ β”‚
156
- β”‚ β”‚ β”‚ getRunning() β”‚ β”‚ untrackPending() β”‚ β”‚ queueNotification() β”‚ β”‚ β”‚
157
- β”‚ β”‚ β”‚ getByParent() β”‚ β”‚ hasPending() β”‚ β”‚ β†’ FIFO eviction β”‚ β”‚ β”‚
158
- β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
159
- β”‚ β”‚ β”‚ β”‚
160
- β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
161
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
162
- β”‚ β”‚ β”‚ async gc(): β”‚ β”‚ β”‚
163
- β”‚ β”‚ β”‚ β€’ completed > 30min β†’ archiveTasks() β†’ .cache/task-archive/tasks_YYYY-MM-DD.jsonl β”‚ β”‚ β”‚
164
- β”‚ β”‚ β”‚ β€’ error/cancelled > 10min β†’ delete β”‚ β”‚ β”‚
165
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
166
- β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
167
- β”‚ β”‚ β”‚ β”‚
168
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
169
- β”‚ β”‚ β”‚
170
- β”‚ β–Ό β”‚
171
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
172
- β”‚ β”‚ β”‚ β”‚
173
- β”‚ β”‚ CHILD SESSIONS POOL (up to 50 concurrent) β”‚ β”‚
174
- β”‚ β”‚ β”‚ β”‚
175
- β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
176
- β”‚ β”‚ β”‚Session 1 β”‚ β”‚Session 2 β”‚ β”‚Session 3 β”‚ β”‚Session 4 β”‚ β”‚Session 5 β”‚ β”‚Session 6 β”‚ β”‚ ... 50 β”‚ β”‚ β”‚
177
- β”‚ β”‚ β”‚ Builder β”‚ β”‚Librarian β”‚ β”‚Researcherβ”‚ β”‚Inspector β”‚ β”‚ Builder β”‚ β”‚ Builder β”‚ β”‚ β”‚ β”‚ β”‚
178
- β”‚ β”‚ β”‚ πŸ”¨ β”‚ β”‚ πŸ“š β”‚ β”‚ πŸ”¬ β”‚ β”‚ πŸ” β”‚ β”‚ πŸ”¨ β”‚ β”‚ πŸ”¨ β”‚ β”‚ β”‚ β”‚ β”‚
179
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
180
- β”‚ β”‚ β”‚ running β”‚ β”‚ running β”‚ β”‚completed β”‚ β”‚ running β”‚ β”‚ error β”‚ β”‚ pending β”‚ β”‚ β”‚ β”‚ β”‚
181
- β”‚ β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
182
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
183
- β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
184
- β”‚ β”‚ β”‚ β”‚ β”‚
185
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
186
- β”‚ β”‚ β”‚
187
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
188
- β”‚
189
- β–Ό
190
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
191
- β”‚ β”‚
192
- β”‚ EVENT BUS (src/core/bus/) β”‚
193
- β”‚ β”‚
194
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
195
- β”‚ β”‚ β”‚ β”‚
196
- β”‚ β”‚ Event Types (Pub/Sub) β”‚ β”‚
197
- β”‚ β”‚ β”‚ β”‚
198
- β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
199
- β”‚ β”‚ β”‚task.started β”‚ β”‚task.completedβ”‚ β”‚ task.failed β”‚ β”‚session.idle β”‚ β”‚ mission.complete β”‚ β”‚ β”‚
200
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚session.deleteβ”‚ β”‚ mission.all_completeβ”‚ β”‚ β”‚
201
- β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
202
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
203
- β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
204
- β”‚ β”‚ β”‚ β”‚ β”‚
205
- β”‚ β”‚ β–Ό β”‚ β”‚
206
- β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
207
- β”‚ β”‚ β”‚ Subscribers β”‚ β”‚ β”‚
208
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
209
- β”‚ β”‚ β”‚ Toast.enableAutoToasts(): EventHandler.handle(): β”‚ β”‚ β”‚
210
- β”‚ β”‚ β”‚ β€’ task.started β†’ presets.taskStarted() β€’ release concurrency β”‚ β”‚ β”‚
211
- β”‚ β”‚ β”‚ β€’ task.completed β†’ presets.taskCompleted() β€’ cleanup resources β”‚ β”‚ β”‚
212
- β”‚ β”‚ β”‚ β€’ task.failed β†’ presets.taskFailed() β”‚ β”‚ β”‚
213
- β”‚ β”‚ β”‚ β€’ mission.complete β†’ presets.missionComplete() β”‚ β”‚ β”‚
214
- β”‚ β”‚ β”‚ β€’ document.cached β†’ presets.documentCached() β”‚ β”‚ β”‚
215
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
216
- β”‚ β”‚ β”‚ Returns: () => void (unsubscribe function for cleanup) β”‚ β”‚ β”‚
217
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
218
- β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
219
- β”‚ β”‚ β”‚ β”‚
220
- β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
221
- β”‚ β”‚ β”‚ EventBusImpl: β”‚ β”‚ β”‚
222
- β”‚ β”‚ β”‚ β€’ subscribe(type, handler) β†’ unsubscribe fn β”‚ β”‚ β”‚
223
- β”‚ β”‚ β”‚ β€’ publish(type, properties) β†’ Event β”‚ β”‚ β”‚
224
- β”‚ β”‚ β”‚ β€’ emit(type, properties) β†’ void β”‚ β”‚ β”‚
225
- β”‚ β”‚ β”‚ β€’ once(type, handler) β†’ unsubscribe fn β”‚ β”‚ β”‚
226
- β”‚ β”‚ β”‚ β€’ waitFor(type, timeout) β†’ Promise<Event> β”‚ β”‚ β”‚
227
- β”‚ β”‚ β”‚ β€’ history: Event[] (max 100, FIFO) β”‚ β”‚ β”‚
228
- β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
229
- β”‚ β”‚ β”‚ β”‚
230
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
231
- β”‚ β”‚
232
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
233
- β”‚
234
- β–Ό
235
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
236
- β”‚ β”‚
237
- β”‚ CORE SYSTEMS LAYER β”‚
238
- β”‚ β”‚
239
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
240
- β”‚ β”‚ Progress Tracker β”‚ β”‚ Auto Recovery β”‚ β”‚ Document Cache β”‚ β”‚
241
- β”‚ β”‚ (src/core/progress/) β”‚ β”‚ (src/core/recovery/) β”‚ β”‚ (src/core/cache/) β”‚ β”‚
242
- β”‚ β”‚ ────────────────── β”‚ β”‚ ────────────────── β”‚ β”‚ ────────────────── β”‚ β”‚
243
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
244
- β”‚ β”‚ startSession(id) β”‚ β”‚ handleError(context) β”‚ β”‚ get(filename) β”‚ β”‚
245
- β”‚ β”‚ recordSnapshot(id, { β”‚ β”‚ β†’ match patterns β”‚ β”‚ set(filename, content) β”‚ β”‚
246
- β”‚ β”‚ currentStep, β”‚ β”‚ β†’ return action β”‚ β”‚ list() β”‚ β”‚
247
- β”‚ β”‚ maxSteps β”‚ β”‚ β”‚ β”‚ clear(filename) β”‚ β”‚
248
- β”‚ β”‚ }) β”‚ β”‚ Patterns: β”‚ β”‚ cleanExpired() β”‚ β”‚
249
- β”‚ β”‚ formatCompact(id) β”‚ β”‚ β€’ rate_limit β”‚ β”‚ β”‚ β”‚
250
- β”‚ β”‚ clearSession(id) β”‚ β”‚ β†’ retry+backoff β”‚ β”‚ Storage: β”‚ β”‚
251
- β”‚ β”‚ β”‚ β”‚ β€’ context_overflow β”‚ β”‚ .cache/docs/*.md β”‚ β”‚
252
- β”‚ β”‚ Store: β”‚ β”‚ β†’ compact β”‚ β”‚ β”‚ β”‚
253
- β”‚ β”‚ sessions: Map<id, β”‚ β”‚ β€’ network β”‚ β”‚ β”‚ β”‚
254
- β”‚ β”‚ ProgressSnapshot[]> β”‚ β”‚ β†’ retry 3x β”‚ β”‚ β”‚ β”‚
255
- β”‚ β”‚ max 100/session β”‚ β”‚ β€’ parse_error β”‚ β”‚ β”‚ β”‚
256
- β”‚ β”‚ β”‚ β”‚ β†’ skip β”‚ β”‚ β”‚ β”‚
257
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
258
- β”‚ β”‚
259
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
260
- β”‚ β”‚ Toast Notifier β”‚ β”‚ Async Queue β”‚ β”‚ Background Commands β”‚ β”‚
261
- β”‚ β”‚ (src/core/notification)β”‚ β”‚ (src/core/queue/) β”‚ β”‚ (src/core/commands/) β”‚ β”‚
262
- β”‚ β”‚ ────────────────── β”‚ β”‚ ────────────────── β”‚ β”‚ ────────────────── β”‚ β”‚
263
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
264
- β”‚ β”‚ show({ title, msg }) β”‚ β”‚ workPool(items, fn, β”‚ β”‚ runBackground(cmd) β”‚ β”‚
265
- β”‚ β”‚ β”‚ β”‚ concurrency) β”‚ β”‚ checkBackground(id) β”‚ β”‚
266
- β”‚ β”‚ presets: β”‚ β”‚ workPoolWithResults() β”‚ β”‚ listBackground() β”‚ β”‚
267
- β”‚ β”‚ β€’ taskStarted() β”‚ β”‚ processBatches() β”‚ β”‚ killBackground(id) β”‚ β”‚
268
- β”‚ β”‚ β€’ taskCompleted() β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
269
- β”‚ β”‚ β€’ taskFailed() β”‚ β”‚ retryWithBackoff(fn, β”‚ β”‚ Storage: β”‚ β”‚
270
- β”‚ β”‚ β€’ missionComplete() β”‚ β”‚ maxRetries, delay) β”‚ β”‚ backgroundJobs: Map β”‚ β”‚
271
- β”‚ β”‚ β€’ documentCached() β”‚ β”‚ withTimeout(fn, ms) β”‚ β”‚ <id, BackgroundTask> β”‚ β”‚
272
- β”‚ β”‚ β”‚ β”‚ debounceAsync(fn, ms) β”‚ β”‚ β”‚ β”‚
273
- β”‚ β”‚ enableAutoToasts() β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
274
- β”‚ β”‚ β†’ EventBus.subscribe() β”‚ β”‚ AsyncQueue<T>: β”‚ β”‚ β”‚ β”‚
275
- β”‚ β”‚ β†’ returns disable fn β”‚ β”‚ async iterator β”‚ β”‚ β”‚ β”‚
276
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
277
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
278
- β”‚ β”‚
279
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
280
- β”‚ β”‚ Shared Context β”‚ β”‚ Task Decomposer β”‚ β”‚ Todo Enforcer β”‚ β”‚
281
- β”‚ β”‚ (src/core/session/) β”‚ β”‚ (src/core/task/) β”‚ β”‚ (src/core/loop/) β”‚ β”‚
282
- β”‚ β”‚ ────────────────── β”‚ β”‚ ────────────────── β”‚ β”‚ ────────────────── β”‚ β”‚
283
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
284
- β”‚ β”‚ create(id, parentId) β”‚ β”‚ create(id, objective) β”‚ β”‚ parseTodos(data) β”‚ β”‚
285
- β”‚ β”‚ get(id) β”‚ β”‚ addTask(id, { β”‚ β”‚ getIncompleteCount() β”‚ β”‚
286
- β”‚ β”‚ getMerged(id) β”‚ β”‚ description, β”‚ β”‚ hasRemainingWork() β”‚ β”‚
287
- β”‚ β”‚ β†’ includes parent ctx β”‚ β”‚ level: 1|2|3, β”‚ β”‚ getNextPending() β”‚ β”‚
288
- β”‚ β”‚ β”‚ β”‚ parallelGroup?, β”‚ β”‚ getStats() β”‚ β”‚
289
- β”‚ β”‚ addDocument(id, doc) β”‚ β”‚ dependsOn? β”‚ β”‚ formatProgress() β”‚ β”‚
290
- β”‚ β”‚ addFinding(id, find) β”‚ β”‚ }) β”‚ β”‚ isMissionComplete() β”‚ β”‚
291
- β”‚ β”‚ addDecision(id, dec) β”‚ β”‚ updateStatus(id, task) β”‚ β”‚ β”‚ β”‚
292
- β”‚ β”‚ β”‚ β”‚ getNextTasks(id) β”‚ β”‚ generateContinuation β”‚ β”‚
293
- β”‚ β”‚ delete(id) β”‚ β”‚ getParallelBatch(id) β”‚ β”‚ Prompt() β”‚ β”‚
294
- β”‚ β”‚ getStats(id) β”‚ β”‚ getSummary(id) β”‚ β”‚ generateCompletion β”‚ β”‚
295
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Message() β”‚ β”‚
296
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
297
- β”‚ β”‚
298
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
33
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
34
+ β”‚ πŸ‘€ USER REQUEST β”‚
35
+ β”‚ OpenCode Terminal / UI β”‚
36
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
37
+ β”‚
38
+ β–Ό
39
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
40
+ β”‚ πŸ”Œ ORCHESTRATOR PLUGIN β”‚
41
+ β”‚ β”‚
42
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
43
+ β”‚ β”‚ Session State β”‚ β”‚ 7 AGENTS β”‚ β”‚
44
+ β”‚ β”‚ Map<id,state> β”‚ β”‚ 🎯 Commander (primary) β”‚ β”‚
45
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ ↓ delegate_task / OpenCode Task tool β”‚ β”‚
46
+ β”‚ β”‚ πŸ—οΈ Architect πŸ”¨ Builder πŸ” Inspector β”‚ β”‚
47
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ πŸ’Ύ Recorder πŸ“š Librarian πŸ”¬ Researcher β”‚ β”‚
48
+ β”‚ β”‚ Plugin Hooks β”‚ β”‚ (subagents, hidden) β”‚ β”‚
49
+ β”‚ β”‚ config β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
50
+ β”‚ β”‚ chat.message β”‚ β”‚
51
+ β”‚ β”‚ tool.execute β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
52
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ 12 TOOLS β”‚ β”‚
53
+ β”‚ β”‚ delegate_task get_task_result list_tasks β”‚ β”‚
54
+ β”‚ β”‚ webfetch websearch codesearch β”‚ β”‚
55
+ β”‚ β”‚ run_background grep_search mgrep β”‚ β”‚
56
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
57
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
58
+ β”‚
59
+ β–Ό
60
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
61
+ β”‚ βš™οΈ PARALLEL AGENT MANAGER β”‚
62
+ β”‚ β”‚
63
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
64
+ β”‚ β”‚ TaskLauncher β”‚ β”‚ TaskPoller β”‚ β”‚ ConcurrencyController β”‚ β”‚
65
+ β”‚ β”‚ launch() β”‚ β”‚ poll() β”‚ β”‚ MAX=50, PER_AGENT=10 β”‚ β”‚
66
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
67
+ β”‚ β”‚
68
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
69
+ β”‚ β”‚ TaskStore (MAX: 1000 tasks) β”‚ β”‚
70
+ β”‚ β”‚ pending β†’ running β†’ completed/error β†’ archived (disk) β”‚ β”‚
71
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
72
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
73
+ β”‚
74
+ β–Ό
75
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
76
+ β”‚ πŸ”„ CHILD SESSIONS POOL (up to 50) β”‚
77
+ β”‚ β”‚
78
+ β”‚ Session 1 Session 2 Session 3 Session N β”‚
79
+ β”‚ Builder πŸ”¨ Librarian πŸ“š Inspector πŸ” ... β”‚
80
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
81
+ β”‚
82
+ β–Ό
83
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
84
+ β”‚ πŸ“‘ EVENT BUS β”‚
85
+ β”‚ β”‚
86
+ β”‚ task.started | task.completed | task.failed | session.idle β”‚
87
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
299
88
  ```
300
89
 
301
90
  ---
302
91
 
92
+
93
+
303
94
  ## 🎯 Key Differentiators
304
95
 
305
96
  | Capability | OpenCode Orchestrator | Basic Plugins |
@@ -393,16 +184,17 @@ What's the difference between useState and useReducer?
393
184
 
394
185
  | Tool | Description |
395
186
  |------|-------------|
396
- | `call_agent` | Call another agent synchronously |
397
- | `launch_parallel_agent` | Start parallel async session |
398
- | `check_parallel_task` | Check task status |
399
- | `collect_parallel_results` | Gather completed results |
187
+ | `delegate_task` | Delegate work to subagent (async/sync) |
188
+ | `get_task_result` | Get result from delegated task |
189
+ | `list_tasks` | List all running/completed tasks |
190
+ | `cancel_task` | Cancel a running task |
400
191
  | `webfetch` | Fetch URL content as Markdown |
401
192
  | `websearch` | Search web (SearXNG β†’ Brave β†’ DuckDuckGo) |
402
193
  | `codesearch` | Search open source code patterns |
403
194
  | `cache_docs` | Manage cached documentation |
404
195
  | `run_background` | Run command in background |
405
- | `grep_search` / `glob_search` | Fast file search |
196
+ | `check_background` / `list_background` | Monitor background jobs |
197
+ | `grep_search` / `glob_search` / `mgrep` | Fast file search |
406
198
 
407
199
  ---
408
200
 
@@ -423,7 +215,7 @@ What's the difference between useState and useReducer?
423
215
 
424
216
  ```
425
217
  Test Files: 18 passed
426
- Tests: 211 passed
218
+ Tests: 198 passed
427
219
  Duration: ~4.3s
428
220
  ```
429
221
 
@@ -437,6 +229,19 @@ npm uninstall -g opencode-orchestrator
437
229
 
438
230
  ---
439
231
 
232
+ ## πŸ”§ Debugging
233
+
234
+ **Log file location:**
235
+ ```bash
236
+ # macOS/Linux
237
+ tail -f /tmp/opencode-orchestrator.log
238
+
239
+ # Windows
240
+ # C:\Users\<username>\AppData\Local\Temp\opencode-orchestrator.log
241
+ ```
242
+
243
+ ---
244
+
440
245
  ## Documentation
441
246
 
442
247
  - **[System Architecture](docs/SYSTEM_ARCHITECTURE.md)** β€” Detailed technical docs
@@ -6,4 +6,5 @@ export interface LaunchInput {
6
6
  prompt: string;
7
7
  agent: string;
8
8
  parentSessionID: string;
9
+ depth?: number;
9
10
  }
@@ -16,6 +16,7 @@ export interface ParallelTask {
16
16
  error?: string;
17
17
  result?: string;
18
18
  concurrencyKey?: string;
19
+ depth: number;
19
20
  lastMsgCount?: number;
20
21
  stablePolls?: number;
21
22
  progress?: TaskProgress;
@@ -1,4 +1,7 @@
1
1
  /**
2
2
  * Debug logger for parallel agent
3
+ * Logs to both console (when DEBUG=true) and file (always)
4
+ * Log file location: /tmp/opencode-orchestrator.log (or OS temp dir)
3
5
  */
4
6
  export declare function log(...args: unknown[]): void;
7
+ export declare function getLogPath(): string;
@@ -1,7 +1,6 @@
1
1
  /**
2
- * Session Module - State and Task management
2
+ * Session Module - State management
3
3
  */
4
4
  export * from "./types/index.js";
5
5
  export * from "./interfaces/index.js";
6
- export { TaskGraph } from "./task-graph.js";
7
6
  export { state } from "./state.js";
@@ -1,5 +1,4 @@
1
1
  /**
2
2
  * Session Interfaces Index
3
3
  */
4
- export { Task } from "./task.js";
5
4
  export { SessionState } from "./session-state.js";
@@ -1,13 +1,11 @@
1
1
  /**
2
2
  * SessionState - State for a single orchestration session
3
3
  */
4
- import type { TaskGraph } from "../task-graph.js";
5
4
  export interface SessionState {
6
5
  enabled: boolean;
7
6
  iterations: number;
8
7
  taskRetries: Map<string, number>;
9
8
  currentTask: string;
10
- graph?: TaskGraph;
11
9
  anomalyCount: number;
12
10
  lastHealthyOutput?: string;
13
11
  }
@@ -2,4 +2,3 @@
2
2
  * Orchestrator Types Index
3
3
  */
4
4
  export { TaskStatus } from "./task-status.js";
5
- export { TaskType } from "./task-type.js";