opencode-orchestrator 1.0.5 → 1.0.10

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
@@ -2,13 +2,21 @@
2
2
  <img src="assets/logo.png" alt="logo" width="280" />
3
3
  <h1>OpenCode Orchestrator</h1>
4
4
 
5
+ <p><b>Next-Gen Autonomous Mastery: Powered by HPFA™ & MSVP™</b></p>
6
+ <p><i>Redefining Scalability with Fractal Swarm Intelligence and Multi-Stage Integrity</i></p>
7
+
5
8
  [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
9
  [![npm](https://img.shields.io/npm/v/opencode-orchestrator.svg)](https://www.npmjs.com/package/opencode-orchestrator)
7
10
  [![Tests](https://img.shields.io/badge/tests-216%20passed-brightgreen.svg)]()
8
11
  </div>
9
12
 
10
- > **Multi-Agent Orchestration Plugin for [OpenCode](https://opencode.ai)**
13
+ ---
14
+
15
+ ### 🌌 **The End of Sequential Limits. The Era of Fractal Mastery.**
16
+
17
+ Where traditional agents hit a sequential wall, we deploy a fractal swarm. OpenCode Orchestrator is the world's most advanced autonomous engineering platform—a **Titan-Class Execution Engine** designed to conquer missions that break conventional AI.
11
18
 
19
+ By fusing **Fractal Swarm Intelligence (HPFA™)** with **Continuous Multi-Stage Verification Pipeline (MSVP™)**, it delivers a level of scale, velocity, and architectural absolute previously considered impossible. Welcome to the final form of autonomous development. No bottlenecks. No limits. Only pure execution.
12
20
 
13
21
  ## ⚡ Quick Start
14
22
 
@@ -16,20 +24,21 @@
16
24
  npm install -g opencode-orchestrator
17
25
  ```
18
26
 
19
- Then in OpenCode:
27
+ Then in OpenCode, launch your mission:
20
28
  ```bash
21
- /extreme-mission "Implement a Diablo2 Online Game for Web"
29
+ /extreme-mission "Architect and Build a Diablo-like Web Engine"
22
30
  ```
23
31
 
24
- ## 🏔️ Extreme Resilience & Performance
32
+ ## 💎 The Four Pillars of Excellence
25
33
 
26
- Built for "Infinite Missions," the OpenCode Orchestrator is engineered to handle massive codebases and long-running tasks where absolute stability is non-negotiable.
34
+ We’ve combined industrial-grade reliability with cutting-edge parallel intelligence to redefine what’s possible in AI coding.
27
35
 
28
- - **🔄 Continuous Operation (WAL)**: Mission continuity is guaranteed via Write-Ahead Logging. Even after a system crash, the orchestrator "replays" its history from disk to resume complex tasks exactly where they left off.
29
- - **⚡ 80% Resource Efficiency**: Smart intent-based polling and output caching reduce API overhead by 60-80%. The system intelligently filters redundant traffic, ensuring extreme agility even under heavy multi-agent load.
30
- - **🧬 Self-Scaling Intelligence**: Real-time success/failure feedback dynamic concurrency. The system learns model reliability and rate limits on the fly, autonomously balancing execution speed with fail-safe stability.
31
- - **💎 Zero-Leak Architecture**: Rigorous, lifecycle-based resource management ensures 100% memory reclamation. Engineered for sessions lasting 10,000+ iterations without a single byte of memory drift.
36
+ * **⚡ Velocity**: Parallelize up to 50 concurrent sessions. What takes hours for others is finished in minutes through **Cognitive Elasticity**.
37
+ * **🧬 Scale**: **Fractal Delegation** allows workers to recursively spawn their own sub-agents. No task is too big for a system that can replicate its own intelligence.
38
+ * **🛡️ Safety**: Our **MSVP (Multi-Stage Verification Pipeline)** reviews every line of code in parallel "Shadow Sessions" before it ever touches your build.
39
+ * **♾️ Trust**: **Iron-Clad Reliability** via Write-Ahead Logging (WAL). Even after a crash, the system replays its history to resume exactly where it was.
32
40
 
41
+ ---
33
42
 
34
43
  ## ⭐ Core Philosophy
35
44
 
@@ -63,47 +72,90 @@ Built for "Infinite Missions," the OpenCode Orchestrator is engineered to handle
63
72
  | 🤝 **Specialized Roles** | Each agent has a clear, focused responsibility |
64
73
 
65
74
 
66
- ## 🏛️ Workflow Architecture
75
+ ## 🏛️ Hyper-Parallel Architecture: HPFA & MSVP
76
+
77
+ The orchestrator eliminates the linear bottleneck of AI development through two breakthrough technologies:
78
+
79
+ ### 🧬 **HPFA (Hyper-Parallel Fractal Architecture)**
80
+ Imagine an agent that doesn't just work, but **thinks like a Hive Mind**.
81
+ * **Fractal Delegation**: Workers are no longer just "doers." They are mini-planners that can recursively spawn their own sub-agents to handle complexity at every level.
82
+ * **Speculative Racing**: Ambiguous tasks are solved using multiple strategies in parallel. The fastest, most accurate path wins, while others are pruned—minimizing latency and maximizing quality.
83
+
84
+ ### 🛡️ **MSVP (Multi-Stage Verification Pipeline)**
85
+ Speed is nothing without accuracy. MSVP ensures your code is production-ready at every second.
86
+ * **Shadow Parallel Review**: As soon as a file is written, a parallel reviewer session is already validating it before the main task even finishes.
87
+ * **Barrier-Sync Integration**: A 4-stage verification gate that prevents "architectural drift" by forcing a global synchronization barrier before final sealing.
67
88
 
68
89
  ```
69
- /extreme-mission "Build REST API"
70
-
71
- ╔═══════════════════════════════════╗
72
- 🎯 COMMANDER — "Start the task"
73
- ╚═══════════════╤═══════════════════╝
74
-
75
- ┌───────────────┼───────────────┐
76
- ▼ ▼ ▼
77
- ┌───────┐ ┌───────┐ ┌───────┐
78
- PLANNER│ │WORKER WORKER │ ← 🔥 50 PARALLEL
79
- │plan.md│ │auth.ts│ │api.ts │ TASKS CONCURRENTLY
80
- └───────┘ └───────┘ └───────┘
81
- │ │ │
82
- └───────────────┼───────────────┘
83
-
84
- ╔═══════════════════════════════════╗
85
- ║ ✅ REVIEWER — "Verify everything"║
86
- ╚═══════════════╤═══════════════════╝
87
-
88
- ┌────────┴────────┐
89
- │ TODO 100%? │
90
- Issues = 0?
91
- └────────┬────────┘
92
- No ↙ ↘ Yes
93
- ♻️ LOOP ✅ COMPLETE
90
+ /extreme-mission "Build Complex System"
91
+
92
+ ╔═══════════════════════════════════════╗
93
+ 🎯 COMMANDER — Orchestrator
94
+ ║ (Main Session - Single) ║
95
+ ╚═══════════════════╤═══════════════════╝
96
+
97
+ ┌───────────────────▼───────────────────┐
98
+ 📋 PLANNER — Create Plan │
99
+ Outputs: Architectural Grid
100
+ └───────────────────┬───────────────────┘
101
+
102
+ ══════════════════════════╧══════════════════════════
103
+ ║ 🔥 HPFA PARALLEL GRID (MSVP) ║
104
+ ══════════════════════════════════════════════════════
105
+ │ │ │ │
106
+ ▼ ▼ ▼ ▼
107
+ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
108
+ │🔨 WORKER │🔨 WORKER │ │🔨 WORKER │ │🔨 WORKER │ <-- Fractal Spawning
109
+ │ Module A │ │ Module B │ │ Module C │ │ Module D │
110
+ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
111
+ Instant │ ⚡ Instant ⚡ Instant │ ⚡ Instant
112
+ ▼ Review ▼ Review ▼ Review ▼ Review
113
+ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
114
+ │✅ REVIEWR│ │✅ REVIEWR│ │✅ REVIEWR│ │✅ REVIEWR│ <-- Stage 1: Unit
115
+ │ (Unit-A) │ │ (Unit-B) │ │ (Unit-C) │ │ (Unit-D) │ Verification
116
+ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
117
+ │ │ │ │
118
+ ═▼═══════════════▼═══════════════▼═══════════════▼════
119
+ ║ ⏳ SYNC BARRIER ║
120
+ ══════════════════════════════════════════════════════
121
+
122
+ ┌───────────────────▼───────────────────┐
123
+ │ ✅ MASTER REVIEWER — Final Pass │
124
+ │ (Cross-module Integration) │
125
+ │ → Stage 2: E2E & System Integrity │
126
+ └───────────────────┬───────────────────┘
127
+
128
+ ┌─────────┴─────────┐
129
+ │ Seal Conditions │
130
+ │ Verified? │
131
+ └─────────┬─────────┘
132
+ No ↙ ↘ Yes
133
+ ♻️ LOOP 🎖️ MISSION
134
+ (Adaptive) SEALED
94
135
  ```
95
136
 
137
+ ### Execution Model (MSVP)
138
+
139
+ | Phase | Agent | Parallelism | Verification Level |
140
+ |:------|:------|:------------|:-------------------|
141
+ | 1️⃣ Plan | Planner | **Single** | Static Analysis |
142
+ | 2️⃣ Implement | Workers | **HPFA Parallel** | Direct Coding |
143
+ | 3️⃣ Unit Pass | Reviewers | **Shadow Parallel** | **1차 리뷰**: Unit Tests (Async) |
144
+ | 4️⃣ Final Sync | Barrier | **Blocking** | All Units Verified |
145
+ | 5️⃣ Integration | Master Reviewer | **Single** | **2차 리뷰**: Full E2E & Sync |
146
+
96
147
  ## Features
97
148
 
98
149
  | Feature | What It Does |
99
150
  |:---------|:-------------|
100
- | 🚀 **60-80% Optimization**| Smart polling & output caching for massive speed gains |
101
- | **50 Parallel Tasks** | Run up to 50 agents simultaneously |
151
+ | 🚀 **MSVP Pipeline** | Parallel unit reviews triggered immediately after worker tasks |
152
+ | 🧬 **Fractal Spawning** | Workers can recursively spawn sub-missions for complex tasks |
153
+ | ⚡ **20+ Parallel Tasks** | High-intensity execution with safety concurrency limits |
102
154
  | 🔄 **Non-Stop Recovery** | WAL-based persistence (resumes tasks after crashes) |
103
155
  | 🔥 **Multi-File Ops** | Work on different files at the same time |
104
156
  | 🛡️ **Self-Scaling** | Dynamic concurrency limits based on success/failure |
105
157
  | 🩹 **Memory Integrity** | Strict resource cleanup prevents leaks in long sessions |
106
- | 🧬 **Adaptive AI** | Agents learn and adapt based on the project |
158
+ | 🏗️ **Architectural Modularity**| Enforces language-agnostic clean code principles |
107
159
 
108
160
  ---
109
161
 
@@ -119,14 +171,13 @@ Built for "Infinite Missions," the OpenCode Orchestrator is engineered to handle
119
171
  | 🔨 Build failure | Fix the issue and retry |
120
172
 
121
173
 
122
- ## 📚 Documentation
123
-
124
- - **[System Architecture](docs/SYSTEM_ARCHITECTURE.md)** — Full technical deep-dive
125
-
174
+ ---
126
175
 
127
176
  ## 🎹 Developer's Words
128
177
 
129
- > [Read the full note →](docs/DEVELOPERS_NOTE.md)
178
+ > "We are not just building a tool; we are building an autonomous engineer that can evolve with the project. HPFA and MSVP are the heart of this evolution—turning AI from a chatbot into a high-performance execution engine."
179
+ >
180
+ > [Read the full Developer's Note →](docs/DEVELOPERS_NOTE.md)
130
181
 
131
182
 
132
183
  ## 📄 License
@@ -0,0 +1,4 @@
1
+ /**
2
+ * HPFA (Hyper-Parallel Fractal Architecture) Guidelines
3
+ */
4
+ export declare const HYPER_PARALLEL_ENFORCEMENT: string;
@@ -12,3 +12,5 @@ export { VERIFICATION_REQUIREMENTS } from "./verification.js";
12
12
  export { CORE_PHILOSOPHY } from "./core-philosophy.js";
13
13
  export { SHARED_LSP_TOOLS } from "./lsp.js";
14
14
  export { SHARED_AST_TOOLS } from "./ast.js";
15
+ export { MODULARITY_ENFORCEMENT } from "./modularity.js";
16
+ export { HYPER_PARALLEL_ENFORCEMENT } from "./hyper-parallel.js";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Modularity & Separation of Concerns (Anti-Monolith Strategy)
3
+ *
4
+ * This fragment enforces physical file separation to prevent monolithic output.
5
+ */
6
+ export declare const MODULARITY_ENFORCEMENT: string;
@@ -5,5 +5,5 @@ export declare const CONFIG: {
5
5
  readonly TASK_TTL_MS: number;
6
6
  readonly CLEANUP_DELAY_MS: number;
7
7
  readonly MIN_STABILITY_MS: number;
8
- readonly POLL_INTERVAL_MS: 500;
8
+ readonly POLL_INTERVAL_MS: 2000;
9
9
  };
@@ -7,4 +7,6 @@ export interface LaunchInput {
7
7
  agent: string;
8
8
  parentSessionID: string;
9
9
  depth?: number;
10
+ mode?: "normal" | "race" | "fractal";
11
+ groupID?: string;
10
12
  }
@@ -17,6 +17,8 @@ export interface ParallelTask {
17
17
  result?: string;
18
18
  concurrencyKey?: string;
19
19
  depth: number;
20
+ mode?: "normal" | "race" | "fractal";
21
+ groupID?: string;
20
22
  lastMsgCount?: number;
21
23
  stablePolls?: number;
22
24
  progress?: TaskProgress;
@@ -14,7 +14,8 @@ export declare class EventHandler {
14
14
  private notifyParentIfAllComplete;
15
15
  private scheduleCleanup;
16
16
  private validateSessionHasOutput;
17
- constructor(client: OpencodeClient, store: TaskStore, concurrency: ConcurrencyController, findBySession: (sessionID: string) => ParallelTask | undefined, notifyParentIfAllComplete: (parentSessionID: string) => Promise<void>, scheduleCleanup: (taskId: string) => void, validateSessionHasOutput: (sessionID: string) => Promise<boolean>);
17
+ private onTaskComplete?;
18
+ constructor(client: OpencodeClient, store: TaskStore, concurrency: ConcurrencyController, findBySession: (sessionID: string) => ParallelTask | undefined, notifyParentIfAllComplete: (parentSessionID: string) => Promise<void>, scheduleCleanup: (taskId: string) => void, validateSessionHasOutput: (sessionID: string) => Promise<boolean>, onTaskComplete?: ((task: ParallelTask) => void | Promise<void>) | undefined);
18
19
  /**
19
20
  * Handle OpenCode session events for proper resource cleanup.
20
21
  * Call this from your plugin's event hook.
@@ -15,6 +15,19 @@ export declare class TaskLauncher {
15
15
  private onTaskError;
16
16
  private startPolling;
17
17
  constructor(client: OpencodeClient, directory: string, store: TaskStore, concurrency: ConcurrencyController, onTaskError: (taskId: string, error: unknown) => void, startPolling: () => void);
18
- launch(input: LaunchInput): Promise<ParallelTask>;
18
+ /**
19
+ * Unified launch method - handles both single and multiple tasks efficiently.
20
+ * All session creations happen in parallel immediately.
21
+ * Concurrency acquisition and prompt firing happen in the background.
22
+ */
23
+ launch(inputs: LaunchInput | LaunchInput[]): Promise<ParallelTask | ParallelTask[]>;
24
+ /**
25
+ * Prepare task: Create session and registration without blocking on concurrency
26
+ */
27
+ private prepareTask;
28
+ /**
29
+ * Background execution: Acquire slot and fire prompt
30
+ */
31
+ private executeBackground;
19
32
  }
20
33
  export {};
@@ -13,8 +13,9 @@ export declare class TaskPoller {
13
13
  private notifyParentIfAllComplete;
14
14
  private scheduleCleanup;
15
15
  private pruneExpiredTasks;
16
+ private onTaskComplete?;
16
17
  private pollingInterval?;
17
- constructor(client: OpencodeClient, store: TaskStore, concurrency: ConcurrencyController, notifyParentIfAllComplete: (parentSessionID: string) => Promise<void>, scheduleCleanup: (taskId: string) => void, pruneExpiredTasks: () => void);
18
+ constructor(client: OpencodeClient, store: TaskStore, concurrency: ConcurrencyController, notifyParentIfAllComplete: (parentSessionID: string) => Promise<void>, scheduleCleanup: (taskId: string) => void, pruneExpiredTasks: () => void, onTaskComplete?: ((task: ParallelTask) => void | Promise<void>) | undefined);
18
19
  start(): void;
19
20
  stop(): void;
20
21
  isRunning(): boolean;
@@ -30,7 +30,7 @@ export declare class ParallelAgentManager {
30
30
  private eventHandler;
31
31
  private constructor();
32
32
  static getInstance(client?: OpencodeClient, directory?: string): ParallelAgentManager;
33
- launch(input: LaunchInput): Promise<ParallelTask>;
33
+ launch(inputs: LaunchInput | LaunchInput[]): Promise<ParallelTask | ParallelTask[]>;
34
34
  resume(input: ResumeInput): Promise<ParallelTask>;
35
35
  getTask(id: string): ParallelTask | undefined;
36
36
  getRunningTasks(): ParallelTask[];
@@ -54,6 +54,7 @@ export declare class ParallelAgentManager {
54
54
  }): void;
55
55
  private findBySession;
56
56
  private handleTaskError;
57
+ private handleTaskComplete;
57
58
  private recoverActiveTasks;
58
59
  }
59
60
  export declare const parallelAgentManager: {
package/dist/index.js CHANGED
@@ -288,17 +288,24 @@ var PARALLEL_TASK = {
288
288
  // Task lifecycle (24 hours for long tasks)
289
289
  TTL_MS: 24 * TIME.HOUR,
290
290
  CLEANUP_DELAY_MS: 10 * TIME.MINUTE,
291
- MAX_DEPTH: 3,
292
- // Concurrency limits (safe for most APIs)
293
- DEFAULT_CONCURRENCY: 3,
294
- MAX_CONCURRENCY: 10,
291
+ MAX_DEPTH: 5,
292
+ // Increased for fractal recursion
293
+ // Concurrency limits (Aggressive for intense processing)
294
+ DEFAULT_CONCURRENCY: 5,
295
+ MAX_CONCURRENCY: 20,
295
296
  // Sync polling (for delegate_task sync mode)
297
+ // Optimized: Reduced polling frequency while relying more on events
296
298
  SYNC_TIMEOUT_MS: 5 * TIME.MINUTE,
297
- POLL_INTERVAL_MS: 500,
298
- MIN_IDLE_TIME_MS: 5 * TIME.SECOND,
299
- MIN_STABILITY_MS: 3 * TIME.SECOND,
300
- STABLE_POLLS_REQUIRED: 3,
301
- MAX_POLL_COUNT: 600,
299
+ POLL_INTERVAL_MS: 2e3,
300
+ // 500 2000ms (75% less API calls)
301
+ MIN_IDLE_TIME_MS: 3 * TIME.SECOND,
302
+ // 5s → 3s (faster detection)
303
+ MIN_STABILITY_MS: 2 * TIME.SECOND,
304
+ // 3s → 2s (faster stability)
305
+ STABLE_POLLS_REQUIRED: 2,
306
+ // 3 → 2 (faster completion)
307
+ MAX_POLL_COUNT: 150,
308
+ // 600 → 150 (adjusted for 2s interval)
302
309
  // Session naming
303
310
  SESSION_TITLE_PREFIX: "Parallel",
304
311
  // Labels for output
@@ -1610,10 +1617,10 @@ function mergeDefs(...defs) {
1610
1617
  function cloneDef(schema) {
1611
1618
  return mergeDefs(schema._zod.def);
1612
1619
  }
1613
- function getElementAtPath(obj, path5) {
1614
- if (!path5)
1620
+ function getElementAtPath(obj, path6) {
1621
+ if (!path6)
1615
1622
  return obj;
1616
- return path5.reduce((acc, key) => acc?.[key], obj);
1623
+ return path6.reduce((acc, key) => acc?.[key], obj);
1617
1624
  }
1618
1625
  function promiseAllObject(promisesObj) {
1619
1626
  const keys = Object.keys(promisesObj);
@@ -1974,11 +1981,11 @@ function aborted(x, startIndex = 0) {
1974
1981
  }
1975
1982
  return false;
1976
1983
  }
1977
- function prefixIssues(path5, issues) {
1984
+ function prefixIssues(path6, issues) {
1978
1985
  return issues.map((iss) => {
1979
1986
  var _a;
1980
1987
  (_a = iss).path ?? (_a.path = []);
1981
- iss.path.unshift(path5);
1988
+ iss.path.unshift(path6);
1982
1989
  return iss;
1983
1990
  });
1984
1991
  }
@@ -2146,7 +2153,7 @@ function treeifyError(error45, _mapper) {
2146
2153
  return issue2.message;
2147
2154
  };
2148
2155
  const result = { errors: [] };
2149
- const processError = (error46, path5 = []) => {
2156
+ const processError = (error46, path6 = []) => {
2150
2157
  var _a, _b;
2151
2158
  for (const issue2 of error46.issues) {
2152
2159
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -2156,7 +2163,7 @@ function treeifyError(error45, _mapper) {
2156
2163
  } else if (issue2.code === "invalid_element") {
2157
2164
  processError({ issues: issue2.issues }, issue2.path);
2158
2165
  } else {
2159
- const fullpath = [...path5, ...issue2.path];
2166
+ const fullpath = [...path6, ...issue2.path];
2160
2167
  if (fullpath.length === 0) {
2161
2168
  result.errors.push(mapper(issue2));
2162
2169
  continue;
@@ -2188,8 +2195,8 @@ function treeifyError(error45, _mapper) {
2188
2195
  }
2189
2196
  function toDotPath(_path) {
2190
2197
  const segs = [];
2191
- const path5 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
2192
- for (const seg of path5) {
2198
+ const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
2199
+ for (const seg of path6) {
2193
2200
  if (typeof seg === "number")
2194
2201
  segs.push(`[${seg}]`);
2195
2202
  else if (typeof seg === "symbol")
@@ -13679,6 +13686,70 @@ var SHARED_AST_TOOLS = `<ast_tools>
13679
13686
  - Always verify structural changes with \`${TOOL_NAMES.LSP_DIAGNOSTICS}\`.
13680
13687
  </ast_tools>`;
13681
13688
 
13689
+ // src/agents/prompts/common/modularity.ts
13690
+ var MODULARITY_ENFORCEMENT = `${PROMPT_TAGS.QUALITY_CHECKLIST.open}
13691
+ \u{1F3D7}\uFE0F UNIVERSAL ARCHITECTURAL MODULARITY (Language-Agnostic)
13692
+
13693
+ To maintain a scalable and maintainable codebase, follow these structural principles regardless of the programming language:
13694
+
13695
+ ### 1. Structural Layering (The "Layer Separation" Rule)
13696
+ Physically separate code based on its functional role. Do not mix these layers in a single file:
13697
+ - **Definitions & Contracts**: Data structures, types, interfaces, or schemas that define the "shape" of data.
13698
+ - **Static Values & Constants**: Hard-coded values, configuration keys, translations, or design tokens.
13699
+ - **Core Implementation**: The active logic, algorithms, functions, or classes that perform the work.
13700
+ - **State & Storage**: Persistent data handling, database interactions, or memory management logic.
13701
+
13702
+ ### 2. Folder-Based Encapsulation (Feature-Oriented)
13703
+ - **Group by Domain/Feature**: Instead of grouping by technical type (e.g., all "utils" in one flat folder), create a directory for each meaningful feature or domain.
13704
+ - **Internal Structure**: For any feature complex enough to need multiple files, use a dedicated folder.
13705
+ - **Public Interface**: Each folder should have a clear entry point (e.g., \`index\`, \`mod.rs\`, \`main\`, or exports) that acts as the "Receptionist" for that module, hiding internal complexity.
13706
+
13707
+ ### 3. Complexity Sharding
13708
+ If a single unit of code (file or module) starts to handle multiple distinct concerns, **shard it** into a directory:
13709
+ - **High Cohesion**: Keep related code close together within the same folder.
13710
+ - **Low Coupling**: Minimize dependencies between folders. Use "Shared/Common" directories only for truly universal helpers.
13711
+
13712
+ ### 4. Code "Mass" Limits
13713
+ - Keep individual files concise and focused on a single responsibility.
13714
+ - If you have to scroll through "screens of code" to find a different type of logic, it belongs in a new file or sub-folder.
13715
+ ${PROMPT_TAGS.QUALITY_CHECKLIST.close}`;
13716
+
13717
+ // src/agents/prompts/common/hyper-parallel.ts
13718
+ var HYPER_PARALLEL_ENFORCEMENT = `${PROMPT_TAGS.QUALITY_CHECKLIST.open}
13719
+ \u{1F680} HYPER-PARALLEL COGNITIVE ARCHITECTURE (HPFA)
13720
+
13721
+ To achieve maximum velocity, you MUST leverage these advanced parallel execution patterns:
13722
+
13723
+ ### 1. Fractal Self-Delegation (Recursive Scaling)
13724
+ If you are a Worker and your assigned task is complex (e.g., implementing multiple endpoints, refactoring several files), **do not do it sequentially**.
13725
+ - **Spawn Sub-Workers**: Use \`delegate_task\` to launch sub-agents for independent sub-components.
13726
+ - **Fractal Depth**: You can scale down to any depth. Each worker acts as a local coordinator for its sub-workers.
13727
+ - **Context Sharding**: Give each sub-worker a focused, atomic prompt and relevant file context.
13728
+
13729
+ ### 2. Speculative Racing (Competitive Implementation)
13730
+ When faced with a high-uncertainty problem (bug fixing, complex refactoring with multiple possible approaches):
13731
+ - **Launch a Race**: Spawn multiple Workers (\`mode: "race"\`) with slightly different prompts or strategies.
13732
+ - **Winning Criteria**: The first agent to produce a solution that passes unit tests "wins".
13733
+ - **Efficiency**: This eliminates the "try-fail-repeat" loop by trying all likely solutions simultaneously.
13734
+
13735
+ ### 3. Asynchronous Batching
13736
+ When you need to perform many independent reads or metadata checks:
13737
+ - **Batch Operations**: Group your tool calls to trigger massive parallel execution host-side.
13738
+ - **Avoid Serial Bottlenecks**: Never wait for a tool result if you have other independent tasks you could be launching in parallel.
13739
+
13740
+ ### 4. Barrier-Sync Integrated Pipeline (BSIP)
13741
+ Don't wait for all workers to finish before starting reviews:
13742
+ - **Pipelined Verification**: Immediately spawn a Reviewer task as soon as a Worker finishes its individual sub-task. The review of Module A happens while Module B is still being built.
13743
+ - **Synchronization Point**: Use the "Final Sync Barrier" to wait for all parallel implementation AND individual reviews to complete.
13744
+ - **Global Integration**: The final master Reviewer only acts once all individual units have been verified by their respective sub-reviewers.
13745
+
13746
+ ### 5. Real-time Brain Sync
13747
+ As you work in a parallel session, log your critical findings or discovered interface changes to the shared task log.
13748
+ Assume that:
13749
+ - **Global Awareness**: Other workers are aware of your public findings.
13750
+ - **Consistency**: You must check for "Global Context Updates" to ensure your parallel work aligns with the latest state of the system.
13751
+ ${PROMPT_TAGS.QUALITY_CHECKLIST.close}`;
13752
+
13682
13753
  // src/agents/prompts/commander/role.ts
13683
13754
  var COMMANDER_ROLE = `${PROMPT_TAGS.ROLE.open}
13684
13755
  You are ${AGENT_NAMES.COMMANDER}. Autonomous mission controller.
@@ -15295,6 +15366,8 @@ var commander = {
15295
15366
  // src/agents/subagents/planner.ts
15296
15367
  var systemPrompt2 = [
15297
15368
  PLANNER_ROLE,
15369
+ MODULARITY_ENFORCEMENT,
15370
+ HYPER_PARALLEL_ENFORCEMENT,
15298
15371
  PLANNER_FORBIDDEN,
15299
15372
  PLANNER_REQUIRED,
15300
15373
  ENVIRONMENT_DISCOVERY,
@@ -15320,6 +15393,8 @@ var planner = {
15320
15393
  // src/agents/subagents/worker.ts
15321
15394
  var systemPrompt3 = [
15322
15395
  WORKER_ROLE,
15396
+ MODULARITY_ENFORCEMENT,
15397
+ HYPER_PARALLEL_ENFORCEMENT,
15323
15398
  WORKER_FORBIDDEN,
15324
15399
  WORKER_REQUIRED,
15325
15400
  ANTI_HALLUCINATION_CORE,
@@ -15347,6 +15422,8 @@ var worker = {
15347
15422
  // src/agents/subagents/reviewer.ts
15348
15423
  var systemPrompt4 = [
15349
15424
  REVIEWER_ROLE,
15425
+ MODULARITY_ENFORCEMENT,
15426
+ HYPER_PARALLEL_ENFORCEMENT,
15350
15427
  REVIEWER_FORBIDDEN,
15351
15428
  REVIEWER_REQUIRED,
15352
15429
  REVIEWER_VERIFICATION,
@@ -16229,7 +16306,7 @@ var TaskStore = class {
16229
16306
  return Array.from(this.tasks.values());
16230
16307
  }
16231
16308
  getRunning() {
16232
- return this.getAll().filter((t) => t.status === TASK_STATUS.RUNNING);
16309
+ return this.getAll().filter((t) => t.status === TASK_STATUS.RUNNING || t.status === TASK_STATUS.PENDING);
16233
16310
  }
16234
16311
  getByParent(parentSessionID) {
16235
16312
  return this.getAll().filter((t) => t.parentSessionID === parentSessionID);
@@ -16948,74 +17025,114 @@ var TaskLauncher = class {
16948
17025
  this.onTaskError = onTaskError;
16949
17026
  this.startPolling = startPolling;
16950
17027
  }
16951
- async launch(input) {
16952
- log("[task-launcher.ts] launch() called", { agent: input.agent, description: input.description, parent: input.parentSessionID });
16953
- const concurrencyKey = input.agent;
16954
- await this.concurrency.acquire(concurrencyKey);
16955
- log("[task-launcher.ts] concurrency acquired for", concurrencyKey);
16956
- try {
16957
- const createResult = await this.client.session.create({
16958
- body: { parentID: input.parentSessionID, title: `${PARALLEL_TASK.SESSION_TITLE_PREFIX}: ${input.description}` },
16959
- query: { directory: this.directory }
17028
+ /**
17029
+ * Unified launch method - handles both single and multiple tasks efficiently.
17030
+ * All session creations happen in parallel immediately.
17031
+ * Concurrency acquisition and prompt firing happen in the background.
17032
+ */
17033
+ async launch(inputs) {
17034
+ const isArray = Array.isArray(inputs);
17035
+ const taskInputs = isArray ? inputs : [inputs];
17036
+ if (taskInputs.length === 0) return isArray ? [] : null;
17037
+ log(`[task-launcher.ts] Batch launching ${taskInputs.length} task(s)`);
17038
+ const startTime = Date.now();
17039
+ const tasks = await Promise.all(taskInputs.map(
17040
+ (input) => this.prepareTask(input).catch((error45) => {
17041
+ log(`[task-launcher.ts] Failed to prepare task ${input.description}:`, error45);
17042
+ return null;
17043
+ })
17044
+ ));
17045
+ const successfulTasks = tasks.filter((t) => t !== null);
17046
+ successfulTasks.forEach((task) => {
17047
+ this.executeBackground(task).catch((error45) => {
17048
+ log(`[task-launcher.ts] Background execution failed for ${task.id}:`, error45);
17049
+ this.onTaskError(task.id, error45);
16960
17050
  });
16961
- if (createResult.error) {
16962
- this.concurrency.release(concurrencyKey);
16963
- throw new Error(`Failed to create session: ${createResult.error}`);
16964
- }
16965
- const sessionID = createResult.data.id;
16966
- const taskId = `${ID_PREFIX.TASK}${crypto.randomUUID().slice(0, 8)}`;
16967
- const depth = (input.depth ?? 0) + 1;
16968
- log("[task-launcher.ts] Creating task with depth", depth);
16969
- const task = {
17051
+ });
17052
+ const elapsed = Date.now() - startTime;
17053
+ log(`[task-launcher.ts] Batch launch prepared: ${successfulTasks.length} tasks in ${elapsed}ms`);
17054
+ if (successfulTasks.length > 0) {
17055
+ this.startPolling();
17056
+ }
17057
+ return isArray ? successfulTasks : successfulTasks[0] || null;
17058
+ }
17059
+ /**
17060
+ * Prepare task: Create session and registration without blocking on concurrency
17061
+ */
17062
+ async prepareTask(input) {
17063
+ const createResult = await this.client.session.create({
17064
+ body: {
17065
+ parentID: input.parentSessionID,
17066
+ title: `${PARALLEL_TASK.SESSION_TITLE_PREFIX}: ${input.description}`
17067
+ },
17068
+ query: { directory: this.directory }
17069
+ });
17070
+ if (createResult.error || !createResult.data?.id) {
17071
+ throw new Error(`Session creation failed: ${createResult.error || "No ID"}`);
17072
+ }
17073
+ const sessionID = createResult.data.id;
17074
+ const taskId = `${ID_PREFIX.TASK}${crypto.randomUUID().slice(0, 8)}`;
17075
+ const task = {
17076
+ id: taskId,
17077
+ sessionID,
17078
+ parentSessionID: input.parentSessionID,
17079
+ description: input.description,
17080
+ prompt: input.prompt,
17081
+ agent: input.agent,
17082
+ status: TASK_STATUS.PENDING,
17083
+ // Start as PENDING
17084
+ startedAt: /* @__PURE__ */ new Date(),
17085
+ concurrencyKey: input.agent,
17086
+ depth: (input.depth ?? 0) + 1,
17087
+ mode: input.mode || "normal",
17088
+ groupID: input.groupID
17089
+ };
17090
+ this.store.set(taskId, task);
17091
+ this.store.trackPending(input.parentSessionID, taskId);
17092
+ taskWAL.log(WAL_ACTIONS.LAUNCH, task).catch(() => {
17093
+ });
17094
+ const toastManager = getTaskToastManager();
17095
+ if (toastManager) {
17096
+ toastManager.addTask({
16970
17097
  id: taskId,
16971
- sessionID,
16972
- parentSessionID: input.parentSessionID,
16973
17098
  description: input.description,
16974
- prompt: input.prompt,
16975
17099
  agent: input.agent,
16976
- status: TASK_STATUS.RUNNING,
16977
- startedAt: /* @__PURE__ */ new Date(),
16978
- concurrencyKey,
16979
- depth
16980
- };
16981
- this.store.set(taskId, task);
16982
- this.store.trackPending(input.parentSessionID, taskId);
17100
+ isBackground: true,
17101
+ parentSessionID: input.parentSessionID,
17102
+ sessionID
17103
+ });
17104
+ }
17105
+ presets.sessionCreated(sessionID, input.agent);
17106
+ return task;
17107
+ }
17108
+ /**
17109
+ * Background execution: Acquire slot and fire prompt
17110
+ */
17111
+ async executeBackground(task) {
17112
+ try {
17113
+ await this.concurrency.acquire(task.agent);
17114
+ task.status = TASK_STATUS.RUNNING;
17115
+ task.startedAt = /* @__PURE__ */ new Date();
17116
+ this.store.set(task.id, task);
16983
17117
  taskWAL.log(WAL_ACTIONS.LAUNCH, task).catch(() => {
16984
17118
  });
16985
- this.startPolling();
16986
- this.client.session.prompt({
16987
- path: { id: sessionID },
17119
+ await this.client.session.prompt({
17120
+ path: { id: task.sessionID },
16988
17121
  body: {
16989
- agent: input.agent,
17122
+ agent: task.agent,
16990
17123
  tools: {
16991
- // Prevent recursive task spawning from subagents
16992
- delegate_task: false,
16993
- get_task_result: false,
16994
- list_tasks: false,
16995
- cancel_task: false
17124
+ // HPFA: Allow agents to delegate sub-tasks (Fractal Spawning)
17125
+ delegate_task: true,
17126
+ get_task_result: true,
17127
+ list_tasks: true,
17128
+ cancel_task: true
16996
17129
  },
16997
- parts: [{ type: PART_TYPES.TEXT, text: input.prompt }]
17130
+ parts: [{ type: PART_TYPES.TEXT, text: task.prompt }]
16998
17131
  }
16999
- }).catch((error45) => {
17000
- log(`Prompt error for ${taskId}:`, error45);
17001
- this.onTaskError(taskId, error45);
17002
17132
  });
17003
- const toastManager = getTaskToastManager();
17004
- if (toastManager) {
17005
- toastManager.addTask({
17006
- id: taskId,
17007
- description: input.description,
17008
- agent: input.agent,
17009
- isBackground: true,
17010
- parentSessionID: input.parentSessionID,
17011
- sessionID
17012
- });
17013
- }
17014
- presets.sessionCreated(sessionID, input.agent);
17015
- log(`Launched ${taskId} in session ${sessionID}`);
17016
- return task;
17133
+ log(`[task-launcher.ts] Task ${task.id} (${task.agent}) started running`);
17017
17134
  } catch (error45) {
17018
- this.concurrency.release(concurrencyKey);
17135
+ this.concurrency.release(task.agent);
17019
17136
  throw error45;
17020
17137
  }
17021
17138
  }
@@ -17079,13 +17196,14 @@ var CONFIG = {
17079
17196
 
17080
17197
  // src/core/agents/manager/task-poller.ts
17081
17198
  var TaskPoller = class {
17082
- constructor(client, store, concurrency, notifyParentIfAllComplete, scheduleCleanup, pruneExpiredTasks) {
17199
+ constructor(client, store, concurrency, notifyParentIfAllComplete, scheduleCleanup, pruneExpiredTasks, onTaskComplete) {
17083
17200
  this.client = client;
17084
17201
  this.store = store;
17085
17202
  this.concurrency = concurrency;
17086
17203
  this.notifyParentIfAllComplete = notifyParentIfAllComplete;
17087
17204
  this.scheduleCleanup = scheduleCleanup;
17088
17205
  this.pruneExpiredTasks = pruneExpiredTasks;
17206
+ this.onTaskComplete = onTaskComplete;
17089
17207
  }
17090
17208
  pollingInterval;
17091
17209
  start() {
@@ -17116,6 +17234,7 @@ var TaskPoller = class {
17116
17234
  const allStatuses = statusResult.data ?? {};
17117
17235
  for (const task of running) {
17118
17236
  try {
17237
+ if (task.status === TASK_STATUS.PENDING) continue;
17119
17238
  const sessionStatus = allStatuses[task.sessionID];
17120
17239
  if (sessionStatus?.type === SESSION_STATUS.IDLE) {
17121
17240
  const elapsed2 = Date.now() - task.startedAt.getTime();
@@ -17168,6 +17287,9 @@ var TaskPoller = class {
17168
17287
  this.scheduleCleanup(task.id);
17169
17288
  taskWAL.log(WAL_ACTIONS.COMPLETE, task).catch(() => {
17170
17289
  });
17290
+ if (this.onTaskComplete) {
17291
+ Promise.resolve(this.onTaskComplete(task)).catch((err) => log("Error in onTaskComplete callback:", err));
17292
+ }
17171
17293
  const duration3 = formatDuration(task.startedAt, task.completedAt);
17172
17294
  presets.sessionCompleted(task.sessionID, duration3);
17173
17295
  log(`Completed ${task.id} (${duration3})`);
@@ -17324,7 +17446,7 @@ You will be notified when ALL tasks complete. Continue productive work.`;
17324
17446
 
17325
17447
  // src/core/agents/manager/event-handler.ts
17326
17448
  var EventHandler = class {
17327
- constructor(client, store, concurrency, findBySession, notifyParentIfAllComplete, scheduleCleanup, validateSessionHasOutput2) {
17449
+ constructor(client, store, concurrency, findBySession, notifyParentIfAllComplete, scheduleCleanup, validateSessionHasOutput2, onTaskComplete) {
17328
17450
  this.client = client;
17329
17451
  this.store = store;
17330
17452
  this.concurrency = concurrency;
@@ -17332,6 +17454,7 @@ var EventHandler = class {
17332
17454
  this.notifyParentIfAllComplete = notifyParentIfAllComplete;
17333
17455
  this.scheduleCleanup = scheduleCleanup;
17334
17456
  this.validateSessionHasOutput = validateSessionHasOutput2;
17457
+ this.onTaskComplete = onTaskComplete;
17335
17458
  }
17336
17459
  /**
17337
17460
  * Handle OpenCode session events for proper resource cleanup.
@@ -17380,6 +17503,9 @@ var EventHandler = class {
17380
17503
  this.scheduleCleanup(task.id);
17381
17504
  taskWAL.log(WAL_ACTIONS.COMPLETE, task).catch(() => {
17382
17505
  });
17506
+ if (this.onTaskComplete) {
17507
+ Promise.resolve(this.onTaskComplete(task)).catch((err) => log("Error in onTaskComplete callback:", err));
17508
+ }
17383
17509
  log(`Task ${task.id} completed via session.idle event (${formatDuration(task.startedAt, task.completedAt)})`);
17384
17510
  }
17385
17511
  handleSessionDeleted(task) {
@@ -17426,7 +17552,8 @@ var ParallelAgentManager = class _ParallelAgentManager {
17426
17552
  this.concurrency,
17427
17553
  (parentSessionID) => this.cleaner.notifyParentIfAllComplete(parentSessionID),
17428
17554
  (taskId) => this.cleaner.scheduleCleanup(taskId),
17429
- () => this.cleaner.pruneExpiredTasks()
17555
+ () => this.cleaner.pruneExpiredTasks(),
17556
+ (task) => this.handleTaskComplete(task)
17430
17557
  );
17431
17558
  this.launcher = new TaskLauncher(
17432
17559
  client,
@@ -17450,7 +17577,8 @@ var ParallelAgentManager = class _ParallelAgentManager {
17450
17577
  (sessionID) => this.findBySession(sessionID),
17451
17578
  (parentSessionID) => this.cleaner.notifyParentIfAllComplete(parentSessionID),
17452
17579
  (taskId) => this.cleaner.scheduleCleanup(taskId),
17453
- (sessionID) => this.poller.validateSessionHasOutput(sessionID)
17580
+ (sessionID) => this.poller.validateSessionHasOutput(sessionID),
17581
+ (task) => this.handleTaskComplete(task)
17454
17582
  );
17455
17583
  this.recoverActiveTasks().catch((err) => {
17456
17584
  log("Recovery error:", err);
@@ -17468,9 +17596,9 @@ var ParallelAgentManager = class _ParallelAgentManager {
17468
17596
  // ========================================================================
17469
17597
  // Public API
17470
17598
  // ========================================================================
17471
- async launch(input) {
17599
+ async launch(inputs) {
17472
17600
  this.cleaner.pruneExpiredTasks();
17473
- return this.launcher.launch(input);
17601
+ return this.launcher.launch(inputs);
17474
17602
  }
17475
17603
  async resume(input) {
17476
17604
  return this.resumer.resume(input);
@@ -17570,6 +17698,30 @@ var ParallelAgentManager = class _ParallelAgentManager {
17570
17698
  taskWAL.log(WAL_ACTIONS.UPDATE, task).catch(() => {
17571
17699
  });
17572
17700
  }
17701
+ async handleTaskComplete(task) {
17702
+ if (task.agent === AGENT_NAMES.WORKER && task.mode !== "race") {
17703
+ log(`[MSVP] Triggering 1\uCC28 \uB9AC\uBDF0 (Unit Review) for task ${task.id}`);
17704
+ try {
17705
+ await this.launch({
17706
+ agent: AGENT_NAMES.REVIEWER,
17707
+ description: `1\uCC28 \uB9AC\uBDF0: ${task.description}`,
17708
+ prompt: `\uC9C4\uD589\uB41C \uC791\uC5C5(\`${task.description}\`)\uC5D0 \uB300\uD574 1\uCC28 \uB9AC\uBDF0(\uC720\uB2DB \uAC80\uC99D)\uB97C \uC218\uD589\uD558\uC138\uC694.
17709
+ \uC8FC\uC694 \uC810\uAC80 \uC0AC\uD56D:
17710
+ 1. \uD574\uB2F9 \uBAA8\uB4C8\uC758 \uC720\uB2DB \uD14C\uC2A4\uD2B8 \uCF54\uB4DC \uC791\uC131 \uC5EC\uBD80 \uBC0F \uD1B5\uACFC \uD655\uC778
17711
+ 2. \uCF54\uB4DC \uD488\uC9C8 \uBC0F \uBAA8\uB4C8\uC131 \uC900\uC218 \uC5EC\uBD80
17712
+ 3. \uBC1C\uACAC\uB41C \uACB0\uD568 \uC989\uC2DC \uC218\uC815 \uC9C0\uC2DC \uB610\uB294 \uB9AC\uD3EC\uD2B8
17713
+
17714
+ \uC774 \uC791\uC5C5\uC740 \uC804\uCCB4 \uD1B5\uD569 \uC804 \uBD80\uD488 \uB2E8\uC704\uC758 \uC644\uACB0\uC131\uC744 \uBCF4\uC7A5\uD558\uAE30 \uC704\uD568\uC785\uB2C8\uB2E4.`,
17715
+ parentSessionID: task.parentSessionID,
17716
+ depth: task.depth,
17717
+ groupID: task.groupID || task.id
17718
+ // Group reviews with their origins
17719
+ });
17720
+ } catch (error45) {
17721
+ log(`[MSVP] Failed to trigger review for ${task.id}:`, error45);
17722
+ }
17723
+ }
17724
+ }
17573
17725
  async recoverActiveTasks() {
17574
17726
  const tasks = await taskWAL.readAll();
17575
17727
  if (tasks.size === 0) return;
@@ -17749,27 +17901,44 @@ var createDelegateTaskTool = (manager, client) => tool({
17749
17901
  description: tool.schema.string().describe("Task description"),
17750
17902
  prompt: tool.schema.string().describe("Prompt for the agent"),
17751
17903
  background: tool.schema.boolean().describe("true=async, false=sync"),
17752
- resume: tool.schema.string().optional().describe("Session ID to resume (from previous task.sessionID)")
17904
+ resume: tool.schema.string().optional().describe("Session ID to resume (from previous task.sessionID)"),
17905
+ mode: tool.schema.enum(["normal", "race", "fractal"]).optional().describe("Task mode (race=first wins, fractal=recursive)"),
17906
+ groupID: tool.schema.string().optional().describe("Group ID for racing or tracking recursive families")
17753
17907
  },
17754
17908
  async execute(args, context) {
17755
- const { agent, description, prompt, background, resume } = args;
17909
+ const { agent, description, prompt, background, resume, mode, groupID } = args;
17756
17910
  const ctx = context;
17757
- log(`${PARALLEL_LOG.DELEGATE_TASK} execute() called`, { agent, description, background, resume, parentSession: ctx.sessionID });
17911
+ log(`${PARALLEL_LOG.DELEGATE_TASK} execute() called`, { agent, description, background, resume, mode, groupID, parentSession: ctx.sessionID });
17758
17912
  const sessionClient = client;
17759
17913
  if (background === void 0) {
17760
17914
  return `${OUTPUT_LABEL.ERROR} 'background' parameter is REQUIRED.`;
17761
17915
  }
17762
17916
  if (resume) {
17763
17917
  try {
17764
- const task = await manager.resume({
17918
+ const input = {
17765
17919
  sessionId: resume,
17766
17920
  prompt,
17767
- parentSessionID: ctx.sessionID
17768
- });
17921
+ parentSessionID: ctx.sessionID,
17922
+ agent,
17923
+ // Assuming agent is needed for resume context
17924
+ description,
17925
+ // Assuming description is needed for resume context
17926
+ mode,
17927
+ groupID
17928
+ };
17929
+ const launchResult = await manager.launch(input);
17930
+ const task = Array.isArray(launchResult) ? launchResult[0] : launchResult;
17931
+ if (!task) {
17932
+ return `Failed to launch task: ${input.description}`;
17933
+ }
17934
+ const taskId = task.id;
17769
17935
  if (background === true) {
17770
- return `${OUTPUT_LABEL.RESUME} task: \`${task.id}\` (${task.agent}) in session \`${task.sessionID}\`
17936
+ const message = `Launched ${input.agent} task: ${input.description}
17937
+ Task ID: ${taskId}
17938
+ Session: ${task.sessionID}`;
17939
+ return `${OUTPUT_LABEL.RESUME} task: \`${taskId}\` (${task.agent}) in session \`${task.sessionID}\`
17771
17940
 
17772
- Previous context preserved. Use \`get_task_result({ taskId: "${task.id}" })\` when complete.`;
17941
+ Previous context preserved. Use \`get_task_result({ taskId: "${taskId}" })\` when complete.`;
17773
17942
  }
17774
17943
  const startTime = Date.now();
17775
17944
  const session = sessionClient.session;
@@ -17789,12 +17958,15 @@ ${text || "(No output)"}`;
17789
17958
  }
17790
17959
  if (background === true) {
17791
17960
  try {
17792
- const task = await manager.launch({
17961
+ const launchResult = await manager.launch({
17793
17962
  agent,
17794
17963
  description,
17795
17964
  prompt,
17796
- parentSessionID: ctx.sessionID
17965
+ parentSessionID: ctx.sessionID,
17966
+ mode,
17967
+ groupID
17797
17968
  });
17969
+ const task = Array.isArray(launchResult) ? launchResult[0] : launchResult;
17798
17970
  presets.taskStarted(task.id, agent);
17799
17971
  return `${OUTPUT_LABEL.SPAWNED} task: \`${task.id}\` (${agent})
17800
17972
  Session: \`${task.sessionID}\` (save for resume)`;
@@ -18841,10 +19013,10 @@ async function resolveCommandPath(key, commandName) {
18841
19013
  const currentPending = pending.get(key);
18842
19014
  if (currentPending) return currentPending;
18843
19015
  const promise2 = (async () => {
18844
- const path5 = await findCommand(commandName);
18845
- cache[key] = path5;
19016
+ const path6 = await findCommand(commandName);
19017
+ cache[key] = path6;
18846
19018
  pending.delete(key);
18847
- return path5;
19019
+ return path6;
18848
19020
  })();
18849
19021
  pending.set(key, promise2);
18850
19022
  return promise2;
@@ -18903,21 +19075,21 @@ import { exec as exec2 } from "node:child_process";
18903
19075
  import { promisify as promisify2 } from "node:util";
18904
19076
  var execAsync2 = promisify2(exec2);
18905
19077
  async function notifyDarwin(title, message) {
18906
- const path5 = await resolveCommandPath(
19078
+ const path6 = await resolveCommandPath(
18907
19079
  NOTIFICATION_COMMAND_KEYS.OSASCRIPT,
18908
19080
  NOTIFICATION_COMMANDS.OSASCRIPT
18909
19081
  );
18910
- if (!path5) return;
19082
+ if (!path6) return;
18911
19083
  const escT = title.replace(/"/g, '\\"');
18912
19084
  const escM = message.replace(/"/g, '\\"');
18913
- await execAsync2(`${path5} -e 'display notification "${escM}" with title "${escT}" sound name "Glass"'`);
19085
+ await execAsync2(`${path6} -e 'display notification "${escM}" with title "${escT}" sound name "Glass"'`);
18914
19086
  }
18915
19087
  async function notifyLinux(title, message) {
18916
- const path5 = await resolveCommandPath(
19088
+ const path6 = await resolveCommandPath(
18917
19089
  NOTIFICATION_COMMAND_KEYS.NOTIFY_SEND,
18918
19090
  NOTIFICATION_COMMANDS.NOTIFY_SEND
18919
19091
  );
18920
- if (path5) await execAsync2(`${path5} "${title}" "${message}" 2>/dev/null`);
19092
+ if (path6) await execAsync2(`${path6} "${title}" "${message}" 2>/dev/null`);
18921
19093
  }
18922
19094
  async function notifyWindows(title, message) {
18923
19095
  const ps = await resolveCommandPath(
@@ -18963,11 +19135,11 @@ import { exec as exec3 } from "node:child_process";
18963
19135
  async function playDarwin(soundPath) {
18964
19136
  if (!soundPath) return;
18965
19137
  try {
18966
- const path5 = await resolveCommandPath(
19138
+ const path6 = await resolveCommandPath(
18967
19139
  NOTIFICATION_COMMAND_KEYS.AFPLAY,
18968
19140
  NOTIFICATION_COMMANDS.AFPLAY
18969
19141
  );
18970
- if (path5) exec3(`"${path5}" "${soundPath}"`);
19142
+ if (path6) exec3(`"${path6}" "${soundPath}"`);
18971
19143
  } catch (err) {
18972
19144
  log(`[session-notify] Error playing sound (Darwin): ${err}`);
18973
19145
  }
@@ -20237,10 +20409,65 @@ function createEventHandler(ctx) {
20237
20409
  };
20238
20410
  }
20239
20411
 
20412
+ // src/utils/compatibility/claude.ts
20413
+ import fs6 from "fs";
20414
+ import path5 from "path";
20415
+ function findClaudeRules(startDir = process.cwd()) {
20416
+ try {
20417
+ let currentDir = startDir;
20418
+ const root = path5.parse(startDir).root;
20419
+ while (true) {
20420
+ const claudeMdPath = path5.join(currentDir, "CLAUDE.md");
20421
+ if (fs6.existsSync(claudeMdPath)) {
20422
+ try {
20423
+ const content = fs6.readFileSync(claudeMdPath, "utf-8");
20424
+ log(`[compatibility] Loaded CLAUDE.md from ${claudeMdPath}`);
20425
+ return formatRules("CLAUDE.md", content);
20426
+ } catch (e) {
20427
+ log(`[compatibility] Error reading CLAUDE.md: ${e}`);
20428
+ }
20429
+ }
20430
+ if (currentDir === root) break;
20431
+ currentDir = path5.dirname(currentDir);
20432
+ }
20433
+ const copilotPath = path5.join(startDir, ".github", "copilot-instructions.md");
20434
+ if (fs6.existsSync(copilotPath)) {
20435
+ return formatRules("Copilot Instructions", fs6.readFileSync(copilotPath, "utf-8"));
20436
+ }
20437
+ return null;
20438
+ } catch (error45) {
20439
+ log(`[compatibility] Error finding Claude rules: ${error45}`);
20440
+ return null;
20441
+ }
20442
+ }
20443
+ function formatRules(source, content) {
20444
+ return `
20445
+ <project_rules source="${source}">
20446
+ ${content}
20447
+ </project_rules>
20448
+
20449
+ <claude_compatibility>
20450
+ These rules are from the project's ${source}.
20451
+ You MUST follow them as strictly as if they were your system prompt.
20452
+ This plugin runs in "Claude Code Compatibility Mode".
20453
+ </claude_compatibility>
20454
+ `;
20455
+ }
20456
+
20240
20457
  // src/plugin-handlers/config-handler.ts
20241
20458
  function createConfigHandler() {
20242
- const commanderPrompt = AGENTS[AGENT_NAMES.COMMANDER]?.systemPrompt || "";
20243
20459
  return async (config2) => {
20460
+ const claudeRules = findClaudeRules();
20461
+ const injectRules = (prompt) => {
20462
+ if (!claudeRules) return prompt;
20463
+ return `${prompt}
20464
+
20465
+ ${claudeRules}`;
20466
+ };
20467
+ const commanderPrompt = injectRules(AGENTS[AGENT_NAMES.COMMANDER]?.systemPrompt || "");
20468
+ const plannerPrompt = injectRules(AGENTS[AGENT_NAMES.PLANNER]?.systemPrompt || "");
20469
+ const workerPrompt = injectRules(AGENTS[AGENT_NAMES.WORKER]?.systemPrompt || "");
20470
+ const reviewerPrompt = injectRules(AGENTS[AGENT_NAMES.REVIEWER]?.systemPrompt || "");
20244
20471
  const existingCommands = config2.command ?? {};
20245
20472
  const existingAgents = config2.agent ?? {};
20246
20473
  const orchestratorCommands = {};
@@ -20266,7 +20493,7 @@ function createConfigHandler() {
20266
20493
  description: "Strategic planning and research specialist",
20267
20494
  mode: "subagent",
20268
20495
  hidden: true,
20269
- prompt: AGENTS[AGENT_NAMES.PLANNER]?.systemPrompt || "",
20496
+ prompt: plannerPrompt,
20270
20497
  maxTokens: AGENT_TOKENS.SUBAGENT_MAX_TOKENS,
20271
20498
  color: "#9B59B6"
20272
20499
  },
@@ -20274,7 +20501,7 @@ function createConfigHandler() {
20274
20501
  description: "Implementation and documentation specialist",
20275
20502
  mode: "subagent",
20276
20503
  hidden: true,
20277
- prompt: AGENTS[AGENT_NAMES.WORKER]?.systemPrompt || "",
20504
+ prompt: workerPrompt,
20278
20505
  maxTokens: AGENT_TOKENS.SUBAGENT_MAX_TOKENS,
20279
20506
  color: "#E67E22"
20280
20507
  },
@@ -20282,7 +20509,7 @@ function createConfigHandler() {
20282
20509
  description: "Verification and context management specialist",
20283
20510
  mode: "subagent",
20284
20511
  hidden: true,
20285
- prompt: AGENTS[AGENT_NAMES.REVIEWER]?.systemPrompt || "",
20512
+ prompt: reviewerPrompt,
20286
20513
  maxTokens: AGENT_TOKENS.SUBAGENT_MAX_TOKENS,
20287
20514
  color: "#27AE60"
20288
20515
  }
@@ -1,18 +1,23 @@
1
1
  /**
2
2
  * Parallel Task Configuration
3
3
  */
4
+ export declare const TASK_MODE: {
5
+ readonly NORMAL: "normal";
6
+ readonly RACE: "race";
7
+ readonly FRACTAL: "fractal";
8
+ };
4
9
  export declare const PARALLEL_TASK: {
5
10
  readonly TTL_MS: number;
6
11
  readonly CLEANUP_DELAY_MS: number;
7
- readonly MAX_DEPTH: 3;
8
- readonly DEFAULT_CONCURRENCY: 3;
9
- readonly MAX_CONCURRENCY: 10;
12
+ readonly MAX_DEPTH: 5;
13
+ readonly DEFAULT_CONCURRENCY: 5;
14
+ readonly MAX_CONCURRENCY: 20;
10
15
  readonly SYNC_TIMEOUT_MS: number;
11
- readonly POLL_INTERVAL_MS: 500;
16
+ readonly POLL_INTERVAL_MS: 2000;
12
17
  readonly MIN_IDLE_TIME_MS: number;
13
18
  readonly MIN_STABILITY_MS: number;
14
- readonly STABLE_POLLS_REQUIRED: 3;
15
- readonly MAX_POLL_COUNT: 600;
19
+ readonly STABLE_POLLS_REQUIRED: 2;
20
+ readonly MAX_POLL_COUNT: 150;
16
21
  readonly SESSION_TITLE_PREFIX: "Parallel";
17
22
  readonly LABEL: "parallel";
18
23
  readonly GROUP_PREFIX: "parallel:";
@@ -18,6 +18,12 @@ export declare const createDelegateTaskTool: (manager: ParallelAgentManager, cli
18
18
  prompt: import("zod").ZodString;
19
19
  background: import("zod").ZodBoolean;
20
20
  resume: import("zod").ZodOptional<import("zod").ZodString>;
21
+ mode: import("zod").ZodOptional<import("zod").ZodEnum<{
22
+ normal: "normal";
23
+ race: "race";
24
+ fractal: "fractal";
25
+ }>>;
26
+ groupID: import("zod").ZodOptional<import("zod").ZodString>;
21
27
  };
22
28
  execute(args: {
23
29
  agent: string;
@@ -25,5 +31,7 @@ export declare const createDelegateTaskTool: (manager: ParallelAgentManager, cli
25
31
  prompt: string;
26
32
  background: boolean;
27
33
  resume?: string | undefined;
34
+ mode?: "normal" | "race" | "fractal" | undefined;
35
+ groupID?: string | undefined;
28
36
  }, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
29
37
  };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Find and read CLAUDE.md guidelines.
3
+ * Follows Claude Code's discovery logic:
4
+ * 1. CLAUDE.md in current directory or parents
5
+ * 2. .github/instructions/ *.md (checking main ones)
6
+ * 3. .cursor/rules/ *.md
7
+ * 4. .claude/rules/ *.md
8
+ */
9
+ export declare function findClaudeRules(startDir?: string): string | null;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "opencode-orchestrator",
3
3
  "displayName": "OpenCode Orchestrator",
4
4
  "description": "Distributed Cognitive Architecture for OpenCode. Turns simple prompts into specialized multi-agent workflows (Planner, Coder, Reviewer).",
5
- "version": "1.0.5",
5
+ "version": "1.0.10",
6
6
  "author": "agnusdei1207",
7
7
  "license": "MIT",
8
8
  "repository": {