opencode-orchestrator 0.1.8 β†’ 0.1.17

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
@@ -1,156 +1,141 @@
1
1
  # OpenCode Orchestrator
2
2
 
3
- > **Multi-Agent Plugin for [OpenCode](https://opencode.ai)** β€” Make cheap models outperform expensive ones
3
+ > **Multi-Agent Plugin for [OpenCode](https://opencode.ai)**
4
4
 
5
5
  <div align="center">
6
6
 
7
7
  [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
+ [![npm](https://img.shields.io/npm/v/opencode-orchestrator.svg)](https://www.npmjs.com/package/opencode-orchestrator)
8
9
  [![OpenCode Plugin](https://img.shields.io/badge/OpenCode-Plugin-purple.svg)](https://opencode.ai)
9
10
 
10
11
  </div>
11
12
 
12
13
  ---
13
14
 
14
- ## πŸ’‘ Philosophy
15
+ ## What is this?
15
16
 
16
- **The model doesn't matter. The workflow does.**
17
+ A 6-agent collaborative system that turns any LLM into a reliable coding team.
17
18
 
18
- Any model β€” even lightweight ones β€” can produce reliable, production-quality code when:
19
+ **Core idea**: Break complex tasks into atomic units, verify each step, fix errors automatically.
19
20
 
20
- 1. **Tasks are atomic** β€” one function, one fix, one file at a time
21
- 2. **Every change is verified** β€” quality gate catches errors immediately
22
- 3. **Errors trigger fixes** β€” self-correcting loop until it works
21
+ ---
22
+
23
+ ## Why Orchestrator?
23
24
 
24
- This plugin implements a **6-agent team** that turns any model into a disciplined development process.
25
+ | Traditional | With Orchestrator |
26
+ |-------------|-------------------|
27
+ | One big prompt β†’ Hope it works | Atomic tasks β†’ Verified every step |
28
+ | Expensive model required | Any model works |
29
+ | Errors compound silently | Self-correcting loop |
30
+ | Unpredictable results | Consistent quality |
25
31
 
26
32
  ---
27
33
 
28
- ## πŸš€ Quick Start
34
+ ## Features
29
35
 
30
- ### Install
36
+ - **πŸ¦€ Rust Core** β€” Fast, memory-safe search and analysis tools
37
+ - **🧠 Micro-Task Architecture** β€” Atomic task decomposition for reliability
38
+ - **πŸ”„ Self-Correcting Loop** β€” Every change reviewed, errors auto-fixed
39
+ - **πŸ‘₯ 6-Agent Team** β€” Specialized roles working together
40
+ - **πŸ›‘οΈ Circuit Breaker** β€” Stops after 3 same errors, prevents infinite loops
41
+ - **⚑ Full Autonomy** β€” `/auto` command handles everything
42
+
43
+ ---
44
+
45
+ ## How It Works
31
46
 
32
- ```bash
33
- npm install opencode-orchestrator
34
- # or
35
- bun add opencode-orchestrator
47
+ ```
48
+ User Request
49
+ β”‚
50
+ β–Ό
51
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
52
+ β”‚ PLANNER β”‚ β†’ Break into atomic tasks
53
+ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
54
+ β”‚
55
+ β–Ό
56
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
57
+ β”‚ For each task: β”‚
58
+ β”‚ β”‚
59
+ β”‚ Search β†’ Code β†’ Review β†’ Fix β”‚
60
+ β”‚ ↑ β”‚ β”‚
61
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
62
+ β”‚ (until PASS) β”‚
63
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
64
+ β”‚
65
+ β–Ό
66
+ βœ… Done
36
67
  ```
37
68
 
38
- Plugin auto-registers. Just restart OpenCode.
69
+ ---
39
70
 
40
- ### Use
71
+ ## Install
41
72
 
42
- ```
43
- /auto implement user authentication with JWT
73
+ ```bash
74
+ npm install opencode-orchestrator
44
75
  ```
45
76
 
46
- That's it. The agents handle the rest.
77
+ Auto-registers with OpenCode. Just restart.
47
78
 
48
79
  ---
49
80
 
50
- ## πŸ€– How It Works
81
+ ## Usage
51
82
 
52
83
  ```
53
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
54
- β”‚ SELF-CORRECTING LOOP β”‚
55
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
56
- β”‚ β”‚
57
- β”‚ User Request β”‚
58
- β”‚ β”‚ β”‚
59
- β”‚ β–Ό β”‚
60
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
61
- β”‚ β”‚ PLANNER │────▢│ Atomic Tasks: [T1] [T2] [T3] ... β”‚ β”‚
62
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
63
- β”‚ β”‚ β”‚
64
- β”‚ β–Ό β”‚
65
- β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
66
- β”‚ β”‚ FOR EACH TASK: β”‚ β”‚
67
- β”‚ β”‚ β”‚ β”‚
68
- β”‚ β”‚ SEARCHER ─▢ CODER ─▢ REVIEWER ─┬─▢ βœ… NEXT β”‚ β”‚
69
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
70
- β”‚ β”‚ ❌ FAIL β”‚ β”‚ β”‚
71
- β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
72
- β”‚ β”‚ β–Ό β”‚ β”‚ β”‚
73
- β”‚ β”‚ FIXER β”€β”€β”€β”€β”˜ β”‚ β”‚
74
- β”‚ β”‚ (retry ≀3) β”‚ β”‚
75
- β”‚ β”‚ β”‚ β”‚
76
- β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
77
- β”‚ β”‚ β”‚
78
- β”‚ β–Ό β”‚
79
- β”‚ βœ… COMPLETE β”‚
80
- β”‚ β”‚
81
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
84
+ /auto implement user authentication with JWT
82
85
  ```
83
86
 
84
- ### Agents
85
-
86
- | Agent | Job |
87
- |-------|-----|
88
- | **Planner** | Decomposes complex tasks into atomic units |
89
- | **Searcher** | Finds patterns and context in codebase |
90
- | **Coder** | Implements one atomic task at a time |
91
- | **Reviewer** | Quality gate β€” catches all errors |
92
- | **Fixer** | Applies targeted fixes from reviewer feedback |
93
-
94
87
  ---
95
88
 
96
- ## πŸ“‹ Commands
89
+ ## Commands
97
90
 
98
91
  | Command | Description |
99
92
  |---------|-------------|
100
- | `/auto "task"` | Autonomous execution until complete |
101
- | `/plan "task"` | Decompose into atomic tasks |
102
- | `/review "code"` | Quality check |
103
- | `/fix "errors"` | Apply fixes |
104
- | `/search "pattern"` | Find context |
93
+ | `/auto` | Autonomous execution until complete |
94
+ | `/plan` | Decompose into atomic tasks |
95
+ | `/review` | Quality check |
96
+ | `/fix` | Fix specific error |
97
+ | `/search` | Find patterns in codebase |
105
98
 
106
99
  ---
107
100
 
108
- ## πŸ›‘οΈ Error Prevention
101
+ ## Agents
109
102
 
110
- | Feature | What It Does |
111
- |---------|--------------|
112
- | **Self-Correcting Loop** | Errors trigger fix β†’ verify cycle |
113
- | **Retry Limit** | Same error 3x = stop and ask user |
114
- | **Iteration Cap** | Max 100 iterations prevents runaway |
115
- | **Atomic Tasks** | Small scope = fewer errors |
103
+ | Agent | Role |
104
+ |-------|------|
105
+ | **Orchestrator** | Team leader β€” coordinates, decides, adapts |
106
+ | **Planner** | Breaks work into atomic tasks |
107
+ | **Coder** | Implements one task at a time |
108
+ | **Reviewer** | Quality gate β€” catches all errors |
109
+ | **Fixer** | Targeted error resolution |
110
+ | **Searcher** | Finds context before coding |
116
111
 
117
112
  ---
118
113
 
119
- ## ⚑ Why This Works
120
-
121
- ### Traditional Approach
122
- ```
123
- [Big Model] ──────────────────────────▢ [Hope it works?]
124
- ```
125
-
126
- ### Orchestrator Approach
127
- ```
128
- [Any Model] ──▢ [Small Task] ──▢ [Verify] ──▢ [Fix if needed] ──▢ βœ…
129
- ```
114
+ ## Documentation
130
115
 
131
- **Results:**
132
- - πŸ”§ **Fewer errors**: Each change is verified
133
- - πŸ’° **Lower cost**: Cheap models work fine
134
- - πŸ”„ **Self-healing**: Errors get fixed automatically
135
- - πŸ“Š **Predictable**: Clear progress tracking
116
+ - [Architecture](docs/ARCHITECTURE.md) β€” Detailed workflow
117
+ - [Configuration](examples/orchestrator.jsonc) β€” Customize settings
136
118
 
137
119
  ---
138
120
 
139
- ## πŸ“š Documentation
121
+ ## Open Source
122
+
123
+ MIT License. No telemetry. No backdoors.
140
124
 
141
- - **[Architecture Guide](docs/ARCHITECTURE.md)** β€” Detailed workflow documentation
142
- - **[Configuration](examples/orchestrator.jsonc)** β€” Customize agent settings
125
+ [github.com/agnusdei1207/opencode-orchestrator](https://github.com/agnusdei1207/opencode-orchestrator)
143
126
 
144
127
  ---
145
128
 
146
- ## πŸ“„ License
129
+ ## Author's Note
147
130
 
148
- [MIT](LICENSE) β€” Use freely, modify freely, no strings attached.
131
+ > My goal is to prove that **affordable models like GLM-4.7** can produce results as good as expensive APIs β€” when you structure the work right.
132
+ >
133
+ > Break tasks down, verify every step, fix errors automatically. The model doesn't need to be smart. The process needs to be disciplined.
134
+ >
135
+ > β€” [@agnusdei1207](https://github.com/agnusdei1207)
149
136
 
150
137
  ---
151
138
 
152
- <div align="center">
153
-
154
- **Built for [OpenCode](https://opencode.ai)** β€’ Make cheap models work like expensive ones
139
+ ## License
155
140
 
156
- </div>
141
+ [MIT](LICENSE)
package/dist/index.js CHANGED
@@ -12348,6 +12348,7 @@ var AGENTS = {
12348
12348
  ## Mission
12349
12349
  Coordinate agents to complete user tasks with ZERO errors.
12350
12350
  Keep iterating until the task is 100% complete and working.
12351
+ FAILURE IS NOT AN OPTION. If you get stuck, change strategy.
12351
12352
 
12352
12353
  ## Your Team
12353
12354
  - **planner**: Decomposes complex tasks into atomic units
@@ -12364,7 +12365,7 @@ Keep iterating until the task is 100% complete and working.
12364
12365
  b. CODE: Call coder with single atomic task
12365
12366
  c. VERIFY: Call reviewer (MANDATORY after every code change)
12366
12367
  d. FIX: If reviewer finds error \u2192 call fixer \u2192 verify again
12367
- e. LOOP: Repeat fix/verify until PASS (max 3 attempts)
12368
+ e. LOOP: Repeat fix/verify until PASS.
12368
12369
  4. NEXT: Move to next task only after current passes
12369
12370
  5. COMPLETE: All tasks done with all reviews passed
12370
12371
 
@@ -12376,22 +12377,24 @@ Keep iterating until the task is 100% complete and working.
12376
12377
  \u274C "Refactor the entire auth module" (too big)
12377
12378
  \u274C "Fix all bugs" (not atomic)
12378
12379
 
12379
- ## Error Recovery Protocol
12380
+ ## Error Recovery Protocol (Resilient Mode)
12380
12381
  - Error from reviewer \u2192 Call fixer with EXACT error details
12381
- - Same error 3 times \u2192 STOP, report to user, suggest alternatives
12382
+ - Same error 3 times \u2192 DO NOT STOP.
12383
+ - Option A: Call searcher to find better context/examples
12384
+ - Option B: Call planner to break task down further
12385
+ - Option C: Try a completely different implementation approach
12382
12386
  - Coder confused \u2192 Provide more context from searcher
12383
- - Stuck on approach \u2192 Try different strategy
12384
12387
 
12385
12388
  ## Progress Tracking (show after each step)
12386
12389
  \uD83D\uDCCB Task: [current task]
12387
12390
  \u2705 Completed: [list]
12388
12391
  \u23F3 Remaining: [list]
12389
- \uD83D\uDD04 Retry: [X/3] if applicable
12392
+ \uD83D\uDD04 Retry: [X] (Reset counter if strategy changes)
12390
12393
 
12391
12394
  ## Critical Rules
12392
12395
  - NEVER skip reviewer after code changes
12393
12396
  - One atomic task at a time
12394
- - Stop if same error persists 3 times
12397
+ - NEVER GIVE UP. Find a way.
12395
12398
  - Always show progress`,
12396
12399
  canWrite: false,
12397
12400
  canBash: false
@@ -12547,7 +12550,17 @@ Find ALL issues in the code. Be thorough but specific.
12547
12550
  - Consistent naming
12548
12551
  - Proper indentation
12549
12552
 
12550
- ### 6. Security (if applicable)
12553
+ ### 1. Syntax & Formatting (Top Priority)
12554
+ - All brackets paired: { } ( ) [ ]
12555
+ - Indentation is consistent
12556
+ - Semicolons present where needed
12557
+ - No obvious syntax typos
12558
+
12559
+ ### 2. Consistency & Sync (Critical)
12560
+ - Export/Import names match EXACTLY
12561
+ - Function signatures match usage (arguments, return types)
12562
+
12563
+ ### 7. Security (if applicable)
12551
12564
  - No hardcoded secrets
12552
12565
  - Input validation present
12553
12566
 
@@ -12557,7 +12570,11 @@ Find ALL issues in the code. Be thorough but specific.
12557
12570
  \`\`\`
12558
12571
  \u2705 PASS
12559
12572
 
12560
- Reviewed: [what was checked]
12573
+ Summary:
12574
+ - Checked syntax, types, and imports
12575
+ - Verified export/import name consistency
12576
+ - Confirmed logic implementation
12577
+
12561
12578
  Status: All checks passed
12562
12579
  \`\`\`
12563
12580
 
@@ -12565,10 +12582,11 @@ Status: All checks passed
12565
12582
  \`\`\`
12566
12583
  \u274C FAIL
12567
12584
 
12568
- [ERROR-001] <category>
12585
+ [ERROR-001] <category: Syntax | Type | Name Mismatch | Import | Logic>
12569
12586
  \u251C\u2500\u2500 File: <path>
12570
12587
  \u251C\u2500\u2500 Line: <number>
12571
12588
  \u251C\u2500\u2500 Issue: <specific problem>
12589
+ \u251C\u2500\u2500 Root Cause: <Typo / Sync Mismatch / Logic Error>
12572
12590
  \u251C\u2500\u2500 Found: \`<problematic code>\`
12573
12591
  \u251C\u2500\u2500 Expected: \`<correct code>\`
12574
12592
  \u2514\u2500\u2500 Fix: <exact fix instruction>
@@ -12577,10 +12595,10 @@ Status: All checks passed
12577
12595
  \`\`\`
12578
12596
 
12579
12597
  ## Rules
12580
- - List ALL errors found (not just first one)
12581
- - Be SPECIFIC about location and fix
12582
- - Prioritize: Syntax > Types > Logic > Style
12583
- - For each error, provide exact fix instruction`,
12598
+ - Check specifically for 'Name Mismatch' (e.g., export 'foo' vs import 'Foo')
12599
+ - Verify function signatures match calls
12600
+ - List ALL errors found
12601
+ - Be SPECIFIC about location and fix`,
12584
12602
  canWrite: false,
12585
12603
  canBash: true
12586
12604
  },
@@ -12605,26 +12623,30 @@ You receive error reports like:
12605
12623
  \`\`\`
12606
12624
 
12607
12625
  ## Fixing Process
12608
- 1. Read each error carefully
12609
- 2. Understand root cause
12610
- 3. Apply minimal fix
12611
- 4. Verify fix addresses the issue
12626
+ 1. ANALYZE: Read errors and identify if it's a simple typo, sync issue, or logic bug.
12627
+ 2. SUMMARIZE: Briefly state what went wrong (e.g., "Export name mismatch in api.ts").
12628
+ 3. FIX: Apply minimal fix to address the root cause.
12629
+ 4. VERIFY: Ensure fix doesn't create new issues.
12612
12630
 
12613
12631
  ## Rules
12614
12632
  - Fix ALL reported errors
12615
12633
  - Make MINIMAL changes
12616
12634
  - Don't "improve" unrelated code
12617
- - Don't refactor while fixing
12635
+ - Check for name mismatches (case sensitivity)
12618
12636
  - Keep existing style
12637
+ - **ANTI-OVERENGINEERING**:
12638
+ - If Syntax/Indent error: ONLY fix the character/spacing. NO logic changes.
12639
+ - If Typo: ONLY fix the name.
12619
12640
 
12620
12641
  ## Output Format
12621
- \`\`\`<language>
12622
- // Fixed code with all errors addressed
12623
12642
  \`\`\`
12643
+ ### Analysis
12644
+ - [ERROR-001]: <cause> (e.g., Missing closing brace at line 42)
12624
12645
 
12625
- ### Changes Made
12626
- - [ERROR-001]: <what was fixed>
12627
- - [ERROR-002]: <what was fixed>
12646
+ ### Fixes Applied
12647
+ \`\`\`<language>
12648
+ // Fixed code
12649
+ \`\`\`
12628
12650
 
12629
12651
  ## If Fix Unclear
12630
12652
  - Ask for clarification
@@ -12796,8 +12818,7 @@ Execute according to your role. Be thorough and precise.
12796
12818
  var COMMANDS = {
12797
12819
  auto: {
12798
12820
  description: "Autonomous execution with self-correcting loop",
12799
- template: `<command-instruction>
12800
- \uD83D\uDE80 AUTO MODE - Self-Correcting Agent Loop
12821
+ template: `\uD83D\uDE80 AUTO MODE - Self-Correcting Agent Loop
12801
12822
 
12802
12823
  ## Protocol
12803
12824
  1. Call planner to decompose into atomic tasks
@@ -12805,18 +12826,18 @@ var COMMANDS = {
12805
12826
  - Call searcher if context needed
12806
12827
  - Call coder to implement
12807
12828
  - Call reviewer to verify (MANDATORY)
12808
- - If FAIL: Call fixer \u2192 reviewer again (max 3 retries)
12829
+ - If FAIL: Call fixer \u2192 reviewer again
12809
12830
  - If PASS: Move to next task
12810
12831
  3. Continue until all tasks complete with PASS
12811
12832
 
12812
- ## Error Recovery
12813
- - Same error 3x \u2192 Stop and ask user
12814
- - New error \u2192 Apply fix and retry
12815
- - Stuck \u2192 Try different approach
12833
+ ## Error Recovery (Resilient Strategy)
12834
+ - Same error 3x \u2192 DO NOT STOP.
12835
+ - Resolve the blocker by finding more context or breaking down the task.
12836
+ - Keep iterating until the task is 100% COMPLETE and VERIFIED.
12816
12837
 
12817
12838
  ## Goal
12818
- Complete "$ARGUMENTS" with zero errors.
12819
- Keep iterating until done.
12839
+ Complete "$ARGUMENTS" with ZERO errors.
12840
+ Relentless execution until absolute success.
12820
12841
  </command-instruction>
12821
12842
 
12822
12843
  <user-task>
@@ -12996,12 +13017,13 @@ Review progress and continue manually.`;
12996
13017
  const retries = (session.taskRetries.get(errorId) || 0) + 1;
12997
13018
  session.taskRetries.set(errorId, retries);
12998
13019
  if (retries >= state.maxRetries) {
12999
- session.enabled = false;
13000
13020
  output.output += `
13001
13021
 
13002
13022
  \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
13003
- \uD83D\uDED1 RETRY LIMIT (${state.maxRetries}x same error)
13004
- Review manually or try different approach.`;
13023
+ \u26A0\uFE0F RETRY LIMIT (${state.maxRetries}x)
13024
+ DO NOT GIVE UP.
13025
+ SYSTEM ALERT: Stop repeating the same fix.
13026
+ REQUIRED: Call 'planner' (break down) or 'searcher' (find context) NOW.`;
13005
13027
  return;
13006
13028
  }
13007
13029
  output.output += `
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "opencode-orchestrator",
3
- "version": "0.1.8",
3
+ "version": "0.1.17",
4
4
  "description": "6-Agent collaborative architecture for OpenCode - Make any model reliable",
5
5
  "author": "agnusdei1207",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "https://github.com/agnusdei1207/opencode-orchestrator"
9
+ "url": "git+https://github.com/agnusdei1207/opencode-orchestrator.git"
10
10
  },
11
11
  "homepage": "https://github.com/agnusdei1207/opencode-orchestrator#readme",
12
12
  "bugs": {
@@ -25,9 +25,6 @@
25
25
  "main": "dist/index.js",
26
26
  "types": "dist/index.d.ts",
27
27
  "type": "module",
28
- "bin": {
29
- "opencode-orchestrator": "./bin/orchestrator"
30
- },
31
28
  "exports": {
32
29
  ".": {
33
30
  "types": "./dist/index.d.ts",
@@ -37,36 +34,27 @@
37
34
  "files": [
38
35
  "dist",
39
36
  "bin",
40
- "src",
41
- "scripts",
42
37
  "README.md",
43
38
  "LICENSE"
44
39
  ],
45
40
  "scripts": {
46
- "// === BUILD: Individual Steps ===": "",
47
41
  "build:rust": "docker compose run --rm dev",
48
42
  "build:rust:copy": "docker compose run --rm dev sh -c 'cp /app/target/release/orchestrator /app/bin/' && chmod +x bin/orchestrator",
49
43
  "build:ts": "bun build src/index.ts --outdir dist --target bun --format esm && tsc --emitDeclarationOnly",
50
44
  "build:scripts": "mkdir -p dist/scripts && bun build scripts/postinstall.ts --outdir dist/scripts --target node",
51
- "// === BUILD: Combined ===": "",
52
45
  "build": "bun run build:ts && bun run build:scripts",
53
46
  "build:full": "bun run build:rust && bun run build:rust:copy && bun run build",
54
- "// === TEST ===": "",
55
47
  "test": "docker compose run --rm test",
56
48
  "test:local": "cargo test",
57
- "// === PUBLISH: Steps ===": "",
58
49
  "version:patch": "npm version patch --no-git-tag-version",
59
50
  "version:minor": "npm version minor --no-git-tag-version",
60
51
  "version:major": "npm version major --no-git-tag-version",
61
- "// === PUBLISH: Combined ===": "",
62
52
  "prepublishOnly": "bun run build",
63
53
  "publish:npm": "npm publish --access public",
64
- "// === RELEASE: Full Workflow ===": "",
65
54
  "release:patch": "bun run build:full && bun run test && bun run version:patch && bun run publish:npm && bun run release:git",
66
55
  "release:minor": "bun run build:full && bun run test && bun run version:minor && bun run publish:npm && bun run release:git",
67
56
  "release:major": "bun run build:full && bun run test && bun run version:major && bun run publish:npm && bun run release:git",
68
57
  "release:git": "git add -A && git commit -m \"Release v$(node -p \"require('./package.json').version\")\" && git tag \"v$(node -p \"require('./package.json').version\")\" && git push && git push --tags",
69
- "// === INSTALL HOOKS ===": "",
70
58
  "postinstall": "node dist/scripts/postinstall.js 2>/dev/null || true"
71
59
  },
72
60
  "dependencies": {
@@ -1,73 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * OpenCode Orchestrator - Post-install script
5
- * Automatically registers the plugin with OpenCode
6
- */
7
-
8
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
9
- import { join } from "path";
10
- import { homedir } from "os";
11
-
12
- const CONFIG_DIR = join(homedir(), ".config", "opencode");
13
- const CONFIG_FILE = join(CONFIG_DIR, "opencode.json");
14
- const PLUGIN_NAME = "opencode-orchestrator";
15
-
16
- function getPluginPath() {
17
- // Find where this package is installed
18
- try {
19
- const packagePath = new URL(".", import.meta.url).pathname;
20
- return packagePath.replace(/\/$/, "");
21
- } catch {
22
- return PLUGIN_NAME;
23
- }
24
- }
25
-
26
- function install() {
27
- console.log("πŸ¦€ OpenCode Orchestrator - Installing...");
28
-
29
- // Ensure config directory exists
30
- if (!existsSync(CONFIG_DIR)) {
31
- mkdirSync(CONFIG_DIR, { recursive: true });
32
- }
33
-
34
- // Load or create config
35
- let config: Record<string, any> = {};
36
- if (existsSync(CONFIG_FILE)) {
37
- try {
38
- config = JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
39
- } catch {
40
- config = {};
41
- }
42
- }
43
-
44
- // Add plugin if not already present
45
- if (!config.plugin) {
46
- config.plugin = [];
47
- }
48
-
49
- const pluginPath = getPluginPath();
50
- const hasPlugin = config.plugin.some((p: string) =>
51
- p === PLUGIN_NAME || p === pluginPath || p.includes("opencode-orchestrator")
52
- );
53
-
54
- if (!hasPlugin) {
55
- config.plugin.push(PLUGIN_NAME);
56
- writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
57
- console.log("βœ… Plugin registered!");
58
- console.log(` Config: ${CONFIG_FILE}`);
59
- } else {
60
- console.log("βœ… Plugin already registered.");
61
- }
62
-
63
- console.log("");
64
- console.log("πŸš€ Ready! Restart OpenCode to use.");
65
- console.log("");
66
- console.log("Commands:");
67
- console.log(" /auto \"task\" - Autonomous execution");
68
- console.log(" /plan \"task\" - Decompose into atomic tasks");
69
- console.log(" /review - Quality check");
70
- console.log("");
71
- }
72
-
73
- install();
package/src/index.ts DELETED
@@ -1,791 +0,0 @@
1
- /**
2
- * OpenCode Orchestrator Plugin
3
- *
4
- * 6-Agent Collaborative Architecture for OpenCode
5
- *
6
- * Philosophy: Cheap models (GLM-4.7, Gemma, Phi) can outperform
7
- * expensive models through intelligent task decomposition and
8
- * team collaboration with quality gates.
9
- */
10
-
11
- import { spawn } from "child_process";
12
- import { join, dirname } from "path";
13
- import { fileURLToPath } from "url";
14
- import { existsSync, writeFileSync, readFileSync, mkdirSync } from "fs";
15
- import { platform, arch } from "os";
16
- import { tool } from "@opencode-ai/plugin";
17
- import type { PluginInput } from "@opencode-ai/plugin";
18
-
19
- const __dirname = dirname(fileURLToPath(import.meta.url));
20
-
21
- // ============================================================================
22
- // 6-Agent Collaborative Architecture
23
- // ============================================================================
24
-
25
- interface AgentDefinition {
26
- id: string;
27
- description: string;
28
- systemPrompt: string;
29
- canWrite: boolean;
30
- canBash: boolean;
31
- }
32
-
33
- const AGENTS: Record<string, AgentDefinition> = {
34
- // ═══════════════════════════════════════════════════════════════
35
- // ORCHESTRATOR - Team Leader & Decision Maker
36
- // ═══════════════════════════════════════════════════════════════
37
- orchestrator: {
38
- id: "orchestrator",
39
- description: "Team leader - delegates atomic tasks, tracks progress, adapts on failure",
40
- systemPrompt: `You are the Orchestrator - the team leader.
41
-
42
- ## Mission
43
- Coordinate agents to complete user tasks with ZERO errors.
44
- Keep iterating until the task is 100% complete and working.
45
-
46
- ## Your Team
47
- - **planner**: Decomposes complex tasks into atomic units
48
- - **coder**: Implements single atomic task
49
- - **reviewer**: Quality gate - catches ALL errors
50
- - **fixer**: Repairs specific errors
51
- - **searcher**: Finds context before coding
52
-
53
- ## Workflow (Self-Correcting Loop)
54
- 1. ANALYZE: Understand user request fully
55
- 2. PLAN: Call planner for complex tasks β†’ get atomic task list
56
- 3. FOR EACH atomic task:
57
- a. CONTEXT: Call searcher if context needed
58
- b. CODE: Call coder with single atomic task
59
- c. VERIFY: Call reviewer (MANDATORY after every code change)
60
- d. FIX: If reviewer finds error β†’ call fixer β†’ verify again
61
- e. LOOP: Repeat fix/verify until PASS (max 3 attempts)
62
- 4. NEXT: Move to next task only after current passes
63
- 5. COMPLETE: All tasks done with all reviews passed
64
-
65
- ## Atomic Task Examples
66
- βœ… "Add validateEmail function to src/utils/validation.ts"
67
- βœ… "Fix syntax error in LoginForm.tsx line 42"
68
- βœ… "Update import statement in api/routes.ts"
69
- βœ… "Add error handling to fetchUser function"
70
- ❌ "Refactor the entire auth module" (too big)
71
- ❌ "Fix all bugs" (not atomic)
72
-
73
- ## Error Recovery Protocol
74
- - Error from reviewer β†’ Call fixer with EXACT error details
75
- - Same error 3 times β†’ STOP, report to user, suggest alternatives
76
- - Coder confused β†’ Provide more context from searcher
77
- - Stuck on approach β†’ Try different strategy
78
-
79
- ## Progress Tracking (show after each step)
80
- πŸ“‹ Task: [current task]
81
- βœ… Completed: [list]
82
- ⏳ Remaining: [list]
83
- πŸ”„ Retry: [X/3] if applicable
84
-
85
- ## Critical Rules
86
- - NEVER skip reviewer after code changes
87
- - One atomic task at a time
88
- - Stop if same error persists 3 times
89
- - Always show progress`,
90
- canWrite: false,
91
- canBash: false,
92
- },
93
-
94
- // ═══════════════════════════════════════════════════════════════
95
- // PLANNER - Atomic Task Decomposition
96
- // ═══════════════════════════════════════════════════════════════
97
- planner: {
98
- id: "planner",
99
- description: "Task decomposition - creates atomic, verifiable units of work",
100
- systemPrompt: `You are the Planner - atomic task decomposition expert.
101
-
102
- ## Your Job
103
- Break complex tasks into the SMALLEST possible units that:
104
- 1. Can be completed independently
105
- 2. Can be verified by reviewer
106
- 3. Have clear success criteria
107
-
108
- ## Atomic Task Format
109
- \`\`\`
110
- [TASK-001] <action verb> + <specific target>
111
- β”œβ”€β”€ File: <exact path>
112
- β”œβ”€β”€ Action: <what to do>
113
- β”œβ”€β”€ Success: <how to verify it worked>
114
- └── Depends: none | TASK-XXX
115
- \`\`\`
116
-
117
- ## What Makes a Task "Atomic"
118
- - Touches ONE file (or one specific location)
119
- - Does ONE thing (add function, fix error, update import)
120
- - Can be reviewed in isolation
121
- - Has clear pass/fail criteria
122
-
123
- ## Good Atomic Tasks
124
- βœ… "Add validateEmail function to utils/validation.ts"
125
- βœ… "Import bcrypt in auth/password.ts"
126
- βœ… "Fix missing closing brace in UserForm.tsx line 58"
127
- βœ… "Add try-catch to fetchData function in api.ts"
128
- βœ… "Update Button component props interface"
129
-
130
- ## Bad Tasks (too large/vague)
131
- ❌ "Implement authentication" β†’ break into 5-10 atomic tasks
132
- ❌ "Fix all errors" β†’ list specific errors as separate tasks
133
- ❌ "Refactor module" β†’ identify specific changes needed
134
-
135
- ## Example Decomposition
136
- Complex task: "Add user login feature"
137
-
138
- [TASK-001] Create password hashing utility
139
- β”œβ”€β”€ File: src/utils/password.ts
140
- β”œβ”€β”€ Action: Add hashPassword and verifyPassword functions
141
- β”œβ”€β”€ Success: Functions exported and callable
142
- └── Depends: none
143
-
144
- [TASK-002] Create User type definition
145
- β”œβ”€β”€ File: src/types/User.ts
146
- β”œβ”€β”€ Action: Add User interface with id, email, passwordHash
147
- β”œβ”€β”€ Success: Type exported and importable
148
- └── Depends: none
149
-
150
- [TASK-003] Create login API handler
151
- β”œβ”€β”€ File: src/api/login.ts
152
- β”œβ”€β”€ Action: Add POST handler that validates credentials
153
- β”œβ”€β”€ Success: Handler returns token on valid login
154
- └── Depends: TASK-001, TASK-002
155
-
156
- ## Output Format
157
- List tasks in dependency order. Independent tasks first.`,
158
- canWrite: false,
159
- canBash: false,
160
- },
161
-
162
- // ═══════════════════════════════════════════════════════════════
163
- // CODER - Single Task Implementation
164
- // ═══════════════════════════════════════════════════════════════
165
- coder: {
166
- id: "coder",
167
- description: "Implementation - executes one atomic task with complete, working code",
168
- systemPrompt: `You are the Coder - implementation specialist.
169
-
170
- ## Your Job
171
- Execute the ONE atomic task you're given. Produce complete, working code.
172
-
173
- ## Before Writing Code
174
- - Understand exactly what the task asks
175
- - Check context provided for patterns to follow
176
- - Plan the implementation mentally first
177
-
178
- ## Code Quality Checklist
179
- Before submitting, verify your code:
180
- - [ ] All brackets { } ( ) [ ] properly paired
181
- - [ ] All quotes " ' \` properly closed
182
- - [ ] All statements terminated correctly
183
- - [ ] All imports included at top
184
- - [ ] No undefined variables
185
- - [ ] Types match (if TypeScript)
186
- - [ ] Follows existing code style
187
-
188
- ## Output Requirements
189
- Provide COMPLETE code that:
190
- 1. Accomplishes the task fully
191
- 2. Compiles/runs without errors
192
- 3. Matches project style
193
- 4. Includes necessary imports
194
-
195
- ## Common Mistakes to Avoid
196
- - Forgetting closing brackets
197
- - Missing imports
198
- - Using wrong variable names
199
- - Type mismatches
200
- - Breaking existing code
201
-
202
- ## If Unsure
203
- - Ask for more context
204
- - Request searcher to find patterns
205
- - Keep implementation simple
206
-
207
- ## Output Format
208
- \`\`\`<language>
209
- // Full code implementation
210
- \`\`\`
211
-
212
- Brief explanation if needed.`,
213
- canWrite: true,
214
- canBash: true,
215
- },
216
-
217
- // ═══════════════════════════════════════════════════════════════
218
- // REVIEWER - Quality Gate
219
- // ═══════════════════════════════════════════════════════════════
220
- reviewer: {
221
- id: "reviewer",
222
- description: "Quality gate - comprehensive error detection with specific fix instructions",
223
- systemPrompt: `You are the Reviewer - quality assurance gate.
224
-
225
- ## Your Job
226
- Find ALL issues in the code. Be thorough but specific.
227
-
228
- ## Review Checklist
229
-
230
- ### 1. Syntax (Critical)
231
- - All brackets paired: { } ( ) [ ]
232
- - All quotes closed: " ' \`
233
- - All statements terminated
234
- - Valid language syntax
235
-
236
- ### 2. Imports & Dependencies
237
- - All used modules imported
238
- - Import paths correct
239
- - No unused imports (warning only)
240
-
241
- ### 3. Types (if applicable)
242
- - Types match declarations
243
- - No implicit any (warning)
244
- - Generics correct
245
-
246
- ### 4. Logic
247
- - Code does what task asked
248
- - Edge cases handled
249
- - No infinite loops possible
250
-
251
- ### 5. Style
252
- - Matches project conventions
253
- - Consistent naming
254
- - Proper indentation
255
-
256
- ### 6. Security (if applicable)
257
- - No hardcoded secrets
258
- - Input validation present
259
-
260
- ## Output Format
261
-
262
- ### If NO errors:
263
- \`\`\`
264
- βœ… PASS
265
-
266
- Reviewed: [what was checked]
267
- Status: All checks passed
268
- \`\`\`
269
-
270
- ### If errors found:
271
- \`\`\`
272
- ❌ FAIL
273
-
274
- [ERROR-001] <category>
275
- β”œβ”€β”€ File: <path>
276
- β”œβ”€β”€ Line: <number>
277
- β”œβ”€β”€ Issue: <specific problem>
278
- β”œβ”€β”€ Found: \`<problematic code>\`
279
- β”œβ”€β”€ Expected: \`<correct code>\`
280
- └── Fix: <exact fix instruction>
281
-
282
- [ERROR-002] ...
283
- \`\`\`
284
-
285
- ## Rules
286
- - List ALL errors found (not just first one)
287
- - Be SPECIFIC about location and fix
288
- - Prioritize: Syntax > Types > Logic > Style
289
- - For each error, provide exact fix instruction`,
290
- canWrite: false,
291
- canBash: true,
292
- },
293
-
294
- // ═══════════════════════════════════════════════════════════════
295
- // FIXER - Error Resolution
296
- // ═══════════════════════════════════════════════════════════════
297
- fixer: {
298
- id: "fixer",
299
- description: "Error resolution - applies targeted fixes based on reviewer feedback",
300
- systemPrompt: `You are the Fixer - error resolution specialist.
301
-
302
- ## Your Job
303
- Fix the SPECIFIC errors reported by reviewer.
304
-
305
- ## Input Format
306
- You receive error reports like:
307
- \`\`\`
308
- [ERROR-001] <category>
309
- β”œβ”€β”€ File: <path>
310
- β”œβ”€β”€ Line: <number>
311
- β”œβ”€β”€ Issue: <problem>
312
- β”œβ”€β”€ Found: \`<bad code>\`
313
- β”œβ”€β”€ Expected: \`<good code>\`
314
- └── Fix: <instruction>
315
- \`\`\`
316
-
317
- ## Fixing Process
318
- 1. Read each error carefully
319
- 2. Understand root cause
320
- 3. Apply minimal fix
321
- 4. Verify fix addresses the issue
322
-
323
- ## Rules
324
- - Fix ALL reported errors
325
- - Make MINIMAL changes
326
- - Don't "improve" unrelated code
327
- - Don't refactor while fixing
328
- - Keep existing style
329
-
330
- ## Output Format
331
- \`\`\`<language>
332
- // Fixed code with all errors addressed
333
- \`\`\`
334
-
335
- ### Changes Made
336
- - [ERROR-001]: <what was fixed>
337
- - [ERROR-002]: <what was fixed>
338
-
339
- ## If Fix Unclear
340
- - Ask for clarification
341
- - Show what you understand
342
- - Propose alternative fix`,
343
- canWrite: true,
344
- canBash: true,
345
- },
346
-
347
- // ═══════════════════════════════════════════════════════════════
348
- // SEARCHER - Context Provider
349
- // ═══════════════════════════════════════════════════════════════
350
- searcher: {
351
- id: "searcher",
352
- description: "Context provider - finds patterns, examples, and project conventions",
353
- systemPrompt: `You are the Searcher - context provider.
354
-
355
- ## Your Job
356
- Find relevant patterns and context BEFORE coder starts working.
357
-
358
- ## Tools
359
- - grep_search: Find text/code patterns
360
- - glob_search: Find files by name
361
-
362
- ## What to Find
363
- 1. Similar implementations in codebase
364
- 2. Import patterns and style
365
- 3. Type definitions being used
366
- 4. Existing utility functions
367
- 5. Project conventions
368
-
369
- ## Output Format
370
- \`\`\`
371
- ### Found Patterns
372
-
373
- [PATTERN-1] <name>
374
- File: <path>
375
- Relevant code:
376
- \`\`\`<lang>
377
- <code snippet>
378
- \`\`\`
379
-
380
- [PATTERN-2] ...
381
-
382
- ### Recommendations for Coder
383
- - Use <pattern> from <file>
384
- - Follow <convention>
385
- - Import from <path>
386
- \`\`\`
387
-
388
- ## Guidelines
389
- - Show actual code, not just file paths
390
- - Focus on most relevant 3-5 findings
391
- - Note project conventions
392
- - Warn about gotchas`,
393
- canWrite: false,
394
- canBash: false,
395
- },
396
- };
397
-
398
- // ============================================================================
399
- // Binary Management
400
- // ============================================================================
401
-
402
- function getBinaryPath(): string {
403
- const binDir = join(__dirname, "..", "bin");
404
- const os = platform();
405
- const cpu = arch();
406
-
407
- let binaryName: string;
408
- if (os === "win32") {
409
- binaryName = "orchestrator-windows-x64.exe";
410
- } else if (os === "darwin") {
411
- binaryName = cpu === "arm64" ? "orchestrator-macos-arm64" : "orchestrator-macos-x64";
412
- } else {
413
- binaryName = cpu === "arm64" ? "orchestrator-linux-arm64" : "orchestrator-linux-x64";
414
- }
415
-
416
- let binaryPath = join(binDir, binaryName);
417
- if (!existsSync(binaryPath)) {
418
- binaryPath = join(binDir, os === "win32" ? "orchestrator.exe" : "orchestrator");
419
- }
420
-
421
- return binaryPath;
422
- }
423
-
424
- async function callRustTool(name: string, args: Record<string, unknown>): Promise<string> {
425
- const binary = getBinaryPath();
426
- if (!existsSync(binary)) {
427
- return JSON.stringify({ error: `Binary not found: ${binary}` });
428
- }
429
-
430
- return new Promise((resolve) => {
431
- const proc = spawn(binary, ["serve"], { stdio: ["pipe", "pipe", "pipe"] });
432
- let stdout = "";
433
-
434
- proc.stdout.on("data", (data) => { stdout += data.toString(); });
435
-
436
- const request = JSON.stringify({
437
- jsonrpc: "2.0",
438
- id: 1,
439
- method: "tools/call",
440
- params: { name, arguments: args },
441
- });
442
-
443
- proc.stdin.write(request + "\n");
444
- proc.stdin.end();
445
-
446
- const timeout = setTimeout(() => { proc.kill(); resolve(JSON.stringify({ error: "Timeout" })); }, 60000);
447
-
448
- proc.on("close", () => {
449
- clearTimeout(timeout);
450
- try {
451
- const lines = stdout.trim().split("\n");
452
- const response = JSON.parse(lines[lines.length - 1]);
453
- const text = response?.result?.content?.[0]?.text;
454
- resolve(text || JSON.stringify(response.result));
455
- } catch {
456
- resolve(stdout || "No output");
457
- }
458
- });
459
- });
460
- }
461
-
462
- // ============================================================================
463
- // State Management
464
- // ============================================================================
465
-
466
- const state = {
467
- autoEnabled: false,
468
- maxIterations: 100,
469
- maxRetries: 3,
470
- sessions: new Map<string, {
471
- enabled: boolean;
472
- iterations: number;
473
- taskRetries: Map<string, number>;
474
- currentTask: string;
475
- }>(),
476
- };
477
-
478
- // ============================================================================
479
- // call_agent Tool
480
- // ============================================================================
481
-
482
- const callAgentTool = tool({
483
- description: `Call a team member to perform specific work.
484
-
485
- ## Team
486
- - **planner**: Decompose complex task into atomic units
487
- - **coder**: Implement single atomic task
488
- - **reviewer**: Quality check (ALWAYS after coder)
489
- - **fixer**: Fix specific errors from reviewer
490
- - **searcher**: Find patterns and context
491
-
492
- ## Self-Correcting Workflow
493
- 1. planner β†’ atomic tasks
494
- 2. For each task:
495
- - searcher (if needed)
496
- - coder
497
- - reviewer (mandatory)
498
- - fixer (if errors) β†’ reviewer again
499
- 3. Continue until all pass`,
500
- args: {
501
- agent: tool.schema
502
- .enum(["planner", "coder", "reviewer", "fixer", "searcher"])
503
- .describe("Team member to call"),
504
- task: tool.schema.string().describe("Atomic task or specific error to address"),
505
- context: tool.schema.string().optional().describe("Relevant context from previous steps"),
506
- },
507
- async execute(args) {
508
- const agentDef = AGENTS[args.agent];
509
- if (!agentDef) {
510
- return `Error: Unknown agent: ${args.agent}`;
511
- }
512
-
513
- const prompt = `
514
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
515
- ${agentDef.id.toUpperCase()} AGENT
516
- ${agentDef.description}
517
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
518
-
519
- <system>
520
- ${agentDef.systemPrompt}
521
- </system>
522
-
523
- <task>
524
- ${args.task}
525
- </task>
526
-
527
- ${args.context ? `<context>\n${args.context}\n</context>` : ""}
528
-
529
- Execute according to your role. Be thorough and precise.
530
- `;
531
-
532
- return prompt;
533
- },
534
- });
535
-
536
- // ============================================================================
537
- // Slash Commands
538
- // ============================================================================
539
-
540
- const COMMANDS: Record<string, { description: string; template: string; argumentHint?: string }> = {
541
- "auto": {
542
- description: "Autonomous execution with self-correcting loop",
543
- template: `<command-instruction>
544
- πŸš€ AUTO MODE - Self-Correcting Agent Loop
545
-
546
- ## Protocol
547
- 1. Call planner to decompose into atomic tasks
548
- 2. For EACH atomic task:
549
- - Call searcher if context needed
550
- - Call coder to implement
551
- - Call reviewer to verify (MANDATORY)
552
- - If FAIL: Call fixer β†’ reviewer again (max 3 retries)
553
- - If PASS: Move to next task
554
- 3. Continue until all tasks complete with PASS
555
-
556
- ## Error Recovery
557
- - Same error 3x β†’ Stop and ask user
558
- - New error β†’ Apply fix and retry
559
- - Stuck β†’ Try different approach
560
-
561
- ## Goal
562
- Complete "$ARGUMENTS" with zero errors.
563
- Keep iterating until done.
564
- </command-instruction>
565
-
566
- <user-task>
567
- $ARGUMENTS
568
- </user-task>`,
569
- argumentHint: '"task description"',
570
- },
571
- "plan": {
572
- description: "Decompose task into atomic units",
573
- template: `<agent-prompt agent="planner">
574
- Decompose into atomic tasks:
575
- $ARGUMENTS
576
- </agent-prompt>`,
577
- argumentHint: '"complex task"',
578
- },
579
- "review": {
580
- description: "Quality check with error detection",
581
- template: `<agent-prompt agent="reviewer">
582
- Review for ALL issues:
583
- $ARGUMENTS
584
- </agent-prompt>`,
585
- argumentHint: '"code to review"',
586
- },
587
- "fix": {
588
- description: "Fix specific errors",
589
- template: `<agent-prompt agent="fixer">
590
- Fix these errors:
591
- $ARGUMENTS
592
- </agent-prompt>`,
593
- argumentHint: '"error details"',
594
- },
595
- "search": {
596
- description: "Find patterns and context",
597
- template: `<agent-prompt agent="searcher">
598
- Find patterns for:
599
- $ARGUMENTS
600
- </agent-prompt>`,
601
- argumentHint: '"what to find"',
602
- },
603
- "agents": {
604
- description: "Show agent team",
605
- template: `## 6-Agent Collaborative Architecture
606
-
607
- | Agent | Role |
608
- |-------|------|
609
- | planner | Decompose into atomic tasks |
610
- | coder | Implement single task |
611
- | reviewer | Quality gate (mandatory) |
612
- | fixer | Apply specific fixes |
613
- | searcher | Find context |
614
-
615
- ## Self-Correcting Loop
616
- \`\`\`
617
- plan β†’ (search β†’ code β†’ review β†’ fix?) β†’ repeat
618
- \`\`\``,
619
- },
620
- "cancel-auto": {
621
- description: "Stop auto mode",
622
- template: `Auto mode stopped.`,
623
- },
624
- };
625
-
626
- // ============================================================================
627
- // Slash Command Tool
628
- // ============================================================================
629
-
630
- function createSlashcommandTool() {
631
- const commandList = Object.entries(COMMANDS)
632
- .map(([name, cmd]) => {
633
- const hint = cmd.argumentHint ? ` ${cmd.argumentHint}` : "";
634
- return `- /${name}${hint}: ${cmd.description}`;
635
- })
636
- .join("\n");
637
-
638
- return tool({
639
- description: `Commands\n\n${commandList}`,
640
- args: {
641
- command: tool.schema.string().describe("Command (without slash)"),
642
- },
643
- async execute(args) {
644
- const cmdName = (args.command || "").replace(/^\//, "").split(/\s+/)[0].toLowerCase();
645
- const cmdArgs = (args.command || "").replace(/^\/?\\S+\s*/, "");
646
-
647
- if (!cmdName) return `Commands:\n${commandList}`;
648
-
649
- const command = COMMANDS[cmdName];
650
- if (!command) return `Unknown: /${cmdName}\n\n${commandList}`;
651
-
652
- return command.template.replace(/\$ARGUMENTS/g, cmdArgs || "continue");
653
- },
654
- });
655
- }
656
-
657
- // ============================================================================
658
- // Search Tools
659
- // ============================================================================
660
-
661
- const grepSearchTool = (directory: string) => tool({
662
- description: "Search code patterns",
663
- args: {
664
- pattern: tool.schema.string().describe("Regex pattern"),
665
- dir: tool.schema.string().optional().describe("Directory"),
666
- },
667
- async execute(args) {
668
- return callRustTool("grep_search", {
669
- pattern: args.pattern,
670
- directory: args.dir || directory,
671
- });
672
- },
673
- });
674
-
675
- const globSearchTool = (directory: string) => tool({
676
- description: "Find files by pattern",
677
- args: {
678
- pattern: tool.schema.string().describe("Glob pattern"),
679
- dir: tool.schema.string().optional().describe("Directory"),
680
- },
681
- async execute(args) {
682
- return callRustTool("glob_search", {
683
- pattern: args.pattern,
684
- directory: args.dir || directory,
685
- });
686
- },
687
- });
688
-
689
- // ============================================================================
690
- // Utilities
691
- // ============================================================================
692
-
693
- function detectSlashCommand(text: string): { command: string; args: string } | null {
694
- const match = text.trim().match(/^\/([a-zA-Z0-9_-]+)(?:\s+(.*))?$/);
695
- if (!match) return null;
696
- return { command: match[1], args: match[2] || "" };
697
- }
698
-
699
- // ============================================================================
700
- // Plugin
701
- // ============================================================================
702
-
703
- const OrchestratorPlugin = async (input: PluginInput) => {
704
- const { directory } = input;
705
-
706
- return {
707
- tool: {
708
- call_agent: callAgentTool,
709
- slashcommand: createSlashcommandTool(),
710
- grep_search: grepSearchTool(directory),
711
- glob_search: globSearchTool(directory),
712
- },
713
-
714
- "chat.message": async (input: any, output: any) => {
715
- const parts = output.parts as Array<{ type: string; text?: string }>;
716
- const textPartIndex = parts.findIndex(p => p.type === "text" && p.text);
717
- if (textPartIndex === -1) return;
718
-
719
- const originalText = parts[textPartIndex].text || "";
720
- const parsed = detectSlashCommand(originalText);
721
-
722
- if (parsed) {
723
- const command = COMMANDS[parsed.command];
724
- if (command) {
725
- parts[textPartIndex].text = command.template.replace(/\$ARGUMENTS/g, parsed.args || "continue");
726
-
727
- if (parsed.command === "auto") {
728
- const sessionID = input.sessionID;
729
- state.sessions.set(sessionID, {
730
- enabled: true,
731
- iterations: 0,
732
- taskRetries: new Map(),
733
- currentTask: "",
734
- });
735
- state.autoEnabled = true;
736
- } else if (parsed.command === "cancel-auto") {
737
- state.sessions.delete(input.sessionID);
738
- state.autoEnabled = false;
739
- }
740
- }
741
- }
742
- },
743
-
744
- "tool.execute.after": async (
745
- input: { tool: string; sessionID: string; callID: string },
746
- output: { title: string; output: string; metadata: any }
747
- ) => {
748
- if (!state.autoEnabled) return;
749
-
750
- const session = state.sessions.get(input.sessionID);
751
- if (!session?.enabled) return;
752
-
753
- session.iterations++;
754
-
755
- // Circuit breaker: max iterations
756
- if (session.iterations >= state.maxIterations) {
757
- session.enabled = false;
758
- output.output += `\n\n━━━━━━━━━━━━\n⚠️ ITERATION LIMIT (${state.maxIterations})\nReview progress and continue manually.`;
759
- return;
760
- }
761
-
762
- // Detect errors and track retries
763
- const errorMatch = output.output.match(/\[ERROR-(\d+)\]/);
764
- if (errorMatch) {
765
- const errorId = `error-${session.currentTask || 'unknown'}`;
766
- const retries = (session.taskRetries.get(errorId) || 0) + 1;
767
- session.taskRetries.set(errorId, retries);
768
-
769
- if (retries >= state.maxRetries) {
770
- session.enabled = false;
771
- output.output += `\n\n━━━━━━━━━━━━\nπŸ›‘ RETRY LIMIT (${state.maxRetries}x same error)\nReview manually or try different approach.`;
772
- return;
773
- }
774
-
775
- output.output += `\n\n━━━━━━━━━━━━\nπŸ”„ RETRY ${retries}/${state.maxRetries}\nApply fix and verify again.`;
776
- return;
777
- }
778
-
779
- // Clear retries on PASS
780
- if (output.output.includes("βœ… PASS")) {
781
- session.taskRetries.clear();
782
- output.output += `\n\n━━━━━━━━━━━━\nβœ… VERIFIED - Continue to next task\n[${session.iterations}/${state.maxIterations}]`;
783
- return;
784
- }
785
-
786
- output.output += `\n\n━━━━━━━━━━━━\n[${session.iterations}/${state.maxIterations}]`;
787
- },
788
- };
789
- };
790
-
791
- export default OrchestratorPlugin;