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 +82 -97
- package/dist/index.js +57 -35
- package/package.json +2 -14
- package/scripts/postinstall.ts +0 -73
- package/src/index.ts +0 -791
package/README.md
CHANGED
|
@@ -1,156 +1,141 @@
|
|
|
1
1
|
# OpenCode Orchestrator
|
|
2
2
|
|
|
3
|
-
> **Multi-Agent Plugin for [OpenCode](https://opencode.ai)**
|
|
3
|
+
> **Multi-Agent Plugin for [OpenCode](https://opencode.ai)**
|
|
4
4
|
|
|
5
5
|
<div align="center">
|
|
6
6
|
|
|
7
7
|
[](LICENSE)
|
|
8
|
+
[](https://www.npmjs.com/package/opencode-orchestrator)
|
|
8
9
|
[](https://opencode.ai)
|
|
9
10
|
|
|
10
11
|
</div>
|
|
11
12
|
|
|
12
13
|
---
|
|
13
14
|
|
|
14
|
-
##
|
|
15
|
+
## What is this?
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
A 6-agent collaborative system that turns any LLM into a reliable coding team.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
**Core idea**: Break complex tasks into atomic units, verify each step, fix errors automatically.
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Why Orchestrator?
|
|
23
24
|
|
|
24
|
-
|
|
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
|
-
##
|
|
34
|
+
## Features
|
|
29
35
|
|
|
30
|
-
|
|
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
|
-
```
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
69
|
+
---
|
|
39
70
|
|
|
40
|
-
|
|
71
|
+
## Install
|
|
41
72
|
|
|
42
|
-
```
|
|
43
|
-
|
|
73
|
+
```bash
|
|
74
|
+
npm install opencode-orchestrator
|
|
44
75
|
```
|
|
45
76
|
|
|
46
|
-
|
|
77
|
+
Auto-registers with OpenCode. Just restart.
|
|
47
78
|
|
|
48
79
|
---
|
|
49
80
|
|
|
50
|
-
##
|
|
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
|
-
##
|
|
89
|
+
## Commands
|
|
97
90
|
|
|
98
91
|
| Command | Description |
|
|
99
92
|
|---------|-------------|
|
|
100
|
-
| `/auto
|
|
101
|
-
| `/plan
|
|
102
|
-
| `/review
|
|
103
|
-
| `/fix
|
|
104
|
-
| `/search
|
|
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
|
-
##
|
|
101
|
+
## Agents
|
|
109
102
|
|
|
110
|
-
|
|
|
111
|
-
|
|
112
|
-
| **
|
|
113
|
-
| **
|
|
114
|
-
| **
|
|
115
|
-
| **
|
|
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
|
-
##
|
|
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
|
-
|
|
132
|
-
-
|
|
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
|
-
##
|
|
121
|
+
## Open Source
|
|
122
|
+
|
|
123
|
+
MIT License. No telemetry. No backdoors.
|
|
140
124
|
|
|
141
|
-
-
|
|
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
|
-
##
|
|
129
|
+
## Author's Note
|
|
147
130
|
|
|
148
|
-
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
**Built for [OpenCode](https://opencode.ai)** β’ Make cheap models work like expensive ones
|
|
139
|
+
## License
|
|
155
140
|
|
|
156
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
-
|
|
12581
|
-
-
|
|
12582
|
-
-
|
|
12583
|
-
-
|
|
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
|
|
12609
|
-
2.
|
|
12610
|
-
3. Apply minimal fix
|
|
12611
|
-
4.
|
|
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
|
-
-
|
|
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
|
-
###
|
|
12626
|
-
|
|
12627
|
-
|
|
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:
|
|
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
|
|
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
|
|
12814
|
-
-
|
|
12815
|
-
-
|
|
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
|
|
12819
|
-
|
|
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
|
-
\
|
|
13004
|
-
|
|
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.
|
|
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": {
|
package/scripts/postinstall.ts
DELETED
|
@@ -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;
|