opencode-swarm-plugin 0.6.1 → 0.6.3
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 +123 -21
- package/package.json +4 -1
- package/scripts/setup.ts +371 -0
package/README.md
CHANGED
|
@@ -20,49 +20,151 @@ This plugin provides intelligent, self-improving tools for multi-agent workflows
|
|
|
20
20
|
- **Graceful degradation** - Works with whatever tools are available, degrades features when tools missing
|
|
21
21
|
- **Swarm discipline** - Enforces beads tracking, aggressive planning, and agent communication
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### 1. Install Dependencies
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# OpenCode (plugin host)
|
|
29
|
+
brew install sst/tap/opencode
|
|
30
|
+
|
|
31
|
+
# Beads CLI (issue tracking)
|
|
32
|
+
npm install -g @joelhooks/beads
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. Install Plugin
|
|
24
36
|
|
|
25
37
|
```bash
|
|
26
38
|
npm install opencode-swarm-plugin
|
|
27
|
-
# or
|
|
28
|
-
bun add opencode-swarm-plugin
|
|
29
|
-
# or
|
|
30
|
-
pnpm add opencode-swarm-plugin
|
|
31
39
|
```
|
|
32
40
|
|
|
33
|
-
|
|
41
|
+
### 3. Create Plugin Wrapper
|
|
42
|
+
|
|
43
|
+
Create a file at `~/.config/opencode/plugins/swarm.ts`:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { SwarmPlugin } from "opencode-swarm-plugin";
|
|
47
|
+
export default SwarmPlugin;
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
That's it! OpenCode will load the plugin automatically.
|
|
51
|
+
|
|
52
|
+
### 4. Copy Examples (Recommended)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Create directories
|
|
56
|
+
mkdir -p ~/.config/opencode/commands ~/.config/opencode/agents
|
|
57
|
+
|
|
58
|
+
# Copy /swarm command
|
|
59
|
+
cp node_modules/opencode-swarm-plugin/examples/commands/swarm.md ~/.config/opencode/commands/
|
|
60
|
+
|
|
61
|
+
# Copy @swarm-planner agent
|
|
62
|
+
cp node_modules/opencode-swarm-plugin/examples/agents/swarm-planner.md ~/.config/opencode/agents/
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 5. Initialize Beads in Your Project
|
|
34
66
|
|
|
35
67
|
```bash
|
|
36
|
-
|
|
68
|
+
cd your-project
|
|
69
|
+
bd init
|
|
37
70
|
```
|
|
38
71
|
|
|
39
|
-
|
|
72
|
+
### Alternative: Direct Copy (No Wrapper)
|
|
40
73
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
74
|
+
If you prefer not to use the wrapper pattern:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
mkdir -p ~/.config/opencode/plugins
|
|
78
|
+
cp node_modules/opencode-swarm-plugin/dist/plugin.js ~/.config/opencode/plugins/swarm.js
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Dependencies
|
|
82
|
+
|
|
83
|
+
### Required
|
|
84
|
+
|
|
85
|
+
| Dependency | Purpose | Install |
|
|
86
|
+
| ----------------------------------------------- | ------------------------- | --------------------------------- |
|
|
87
|
+
| [OpenCode](https://opencode.ai) | Plugin host | `brew install sst/tap/opencode` |
|
|
88
|
+
| [Beads CLI](https://github.com/joelhooks/beads) | Git-backed issue tracking | `npm install -g @joelhooks/beads` |
|
|
89
|
+
|
|
90
|
+
### Optional (Graceful Degradation)
|
|
45
91
|
|
|
46
|
-
|
|
92
|
+
The plugin works without these, but with reduced functionality:
|
|
47
93
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
94
|
+
| Dependency | Purpose | Without It |
|
|
95
|
+
| ----------------------------------------------------- | ------------------------ | ---------------------------------------- |
|
|
96
|
+
| [Agent Mail](https://github.com/joelhooks/agent-mail) | Multi-agent coordination | No file reservations, no agent messaging |
|
|
97
|
+
| [Redis](https://redis.io) | Rate limiting | Falls back to SQLite |
|
|
98
|
+
| [CASS](https://github.com/Dicklesworthstone/cass) | Historical context | No "similar past tasks" in decomposition |
|
|
99
|
+
| [UBS](https://github.com/joelhooks/ubs) | Bug scanning | No pre-completion validation |
|
|
53
100
|
|
|
54
|
-
### Verify
|
|
101
|
+
### Verify Installation
|
|
55
102
|
|
|
56
103
|
```bash
|
|
104
|
+
# Check OpenCode
|
|
105
|
+
opencode --version
|
|
106
|
+
|
|
107
|
+
# Check Beads
|
|
108
|
+
bd --version
|
|
109
|
+
|
|
110
|
+
# Check Agent Mail (if using multi-agent)
|
|
57
111
|
curl http://127.0.0.1:8765/health/liveness
|
|
112
|
+
|
|
113
|
+
# Check Redis (optional)
|
|
114
|
+
redis-cli ping
|
|
58
115
|
```
|
|
59
116
|
|
|
60
|
-
|
|
117
|
+
## Installation Details
|
|
118
|
+
|
|
119
|
+
### From npm
|
|
61
120
|
|
|
62
121
|
```bash
|
|
63
|
-
|
|
122
|
+
npm install opencode-swarm-plugin
|
|
123
|
+
# or
|
|
124
|
+
bun add opencode-swarm-plugin
|
|
125
|
+
# or
|
|
126
|
+
pnpm add opencode-swarm-plugin
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Plugin Setup (Wrapper Pattern)
|
|
130
|
+
|
|
131
|
+
Create `~/.config/opencode/plugins/swarm.ts`:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import { SwarmPlugin } from "opencode-swarm-plugin";
|
|
135
|
+
export default SwarmPlugin;
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
OpenCode runs on Bun and loads TypeScript directly - no build step needed.
|
|
139
|
+
|
|
140
|
+
### Plugin Setup (Direct Copy)
|
|
141
|
+
|
|
142
|
+
Alternatively, copy the pre-built bundle:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
mkdir -p ~/.config/opencode/plugins
|
|
146
|
+
cp node_modules/opencode-swarm-plugin/dist/plugin.js ~/.config/opencode/plugins/swarm.js
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Example Files
|
|
150
|
+
|
|
151
|
+
Copy the `/swarm` command and `@swarm-planner` agent:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Command
|
|
155
|
+
mkdir -p ~/.config/opencode/commands
|
|
156
|
+
cp node_modules/opencode-swarm-plugin/examples/commands/swarm.md ~/.config/opencode/commands/
|
|
157
|
+
|
|
158
|
+
# Agent
|
|
159
|
+
mkdir -p ~/.config/opencode/agents
|
|
160
|
+
cp node_modules/opencode-swarm-plugin/examples/agents/swarm-planner.md ~/.config/opencode/agents/
|
|
64
161
|
```
|
|
65
162
|
|
|
163
|
+
> **Note:** The package has two entry points:
|
|
164
|
+
>
|
|
165
|
+
> - `dist/index.js` - Full library exports (schemas, errors, utilities, learning modules)
|
|
166
|
+
> - `dist/plugin.js` - Plugin entry point that only exports the `plugin` function for OpenCode
|
|
167
|
+
|
|
66
168
|
## Tools Reference
|
|
67
169
|
|
|
68
170
|
### Beads Tools
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm-plugin",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "Multi-agent swarm coordination for OpenCode with learning capabilities, beads integration, and Agent Mail",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"opencode-swarm-setup": "./scripts/setup.ts"
|
|
10
|
+
},
|
|
8
11
|
"exports": {
|
|
9
12
|
".": {
|
|
10
13
|
"import": "./dist/index.js",
|
package/scripts/setup.ts
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* OpenCode Swarm Plugin - Setup Script
|
|
4
|
+
*
|
|
5
|
+
* Checks for required dependencies and installs them if missing.
|
|
6
|
+
* Mac-specific (uses Homebrew).
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* bunx opencode-swarm-plugin/scripts/setup.ts
|
|
10
|
+
* # or after cloning:
|
|
11
|
+
* bun scripts/setup.ts
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { $ } from "bun";
|
|
15
|
+
import { existsSync, mkdirSync, copyFileSync } from "fs";
|
|
16
|
+
import { homedir } from "os";
|
|
17
|
+
import { join } from "path";
|
|
18
|
+
|
|
19
|
+
// ANSI colors
|
|
20
|
+
const green = (s: string) => `\x1b[32m${s}\x1b[0m`;
|
|
21
|
+
const red = (s: string) => `\x1b[31m${s}\x1b[0m`;
|
|
22
|
+
const yellow = (s: string) => `\x1b[33m${s}\x1b[0m`;
|
|
23
|
+
const blue = (s: string) => `\x1b[34m${s}\x1b[0m`;
|
|
24
|
+
const dim = (s: string) => `\x1b[2m${s}\x1b[0m`;
|
|
25
|
+
|
|
26
|
+
const CHECK = green("✓");
|
|
27
|
+
const CROSS = red("✗");
|
|
28
|
+
const WARN = yellow("⚠");
|
|
29
|
+
const INFO = blue("→");
|
|
30
|
+
|
|
31
|
+
interface Dependency {
|
|
32
|
+
name: string;
|
|
33
|
+
check: () => Promise<boolean>;
|
|
34
|
+
install: () => Promise<void>;
|
|
35
|
+
optional?: boolean;
|
|
36
|
+
purpose: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Check if a command exists
|
|
41
|
+
*/
|
|
42
|
+
async function commandExists(cmd: string): Promise<boolean> {
|
|
43
|
+
try {
|
|
44
|
+
const result = await $`which ${cmd}`.quiet().nothrow();
|
|
45
|
+
return result.exitCode === 0;
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Check if a URL is reachable
|
|
53
|
+
*/
|
|
54
|
+
async function urlReachable(url: string): Promise<boolean> {
|
|
55
|
+
try {
|
|
56
|
+
const response = await fetch(url, { method: "HEAD" });
|
|
57
|
+
return response.ok;
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Run a shell command with output
|
|
65
|
+
*/
|
|
66
|
+
async function run(cmd: string, args: string[] = []): Promise<boolean> {
|
|
67
|
+
try {
|
|
68
|
+
const proc = Bun.spawn([cmd, ...args], {
|
|
69
|
+
stdout: "inherit",
|
|
70
|
+
stderr: "inherit",
|
|
71
|
+
});
|
|
72
|
+
const exitCode = await proc.exited;
|
|
73
|
+
return exitCode === 0;
|
|
74
|
+
} catch {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const dependencies: Dependency[] = [
|
|
80
|
+
{
|
|
81
|
+
name: "Homebrew",
|
|
82
|
+
purpose: "Package manager for installing other dependencies",
|
|
83
|
+
check: async () => commandExists("brew"),
|
|
84
|
+
install: async () => {
|
|
85
|
+
console.log(`${INFO} Installing Homebrew...`);
|
|
86
|
+
const script = await fetch(
|
|
87
|
+
"https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh",
|
|
88
|
+
).then((r) => r.text());
|
|
89
|
+
await $`/bin/bash -c ${script}`;
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: "OpenCode",
|
|
94
|
+
purpose: "AI coding assistant (plugin host)",
|
|
95
|
+
check: async () => commandExists("opencode"),
|
|
96
|
+
install: async () => {
|
|
97
|
+
console.log(`${INFO} Installing OpenCode...`);
|
|
98
|
+
await run("brew", ["install", "sst/tap/opencode"]);
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "Beads CLI (bd)",
|
|
103
|
+
purpose: "Git-backed issue tracking",
|
|
104
|
+
check: async () => commandExists("bd"),
|
|
105
|
+
install: async () => {
|
|
106
|
+
console.log(`${INFO} Installing Beads...`);
|
|
107
|
+
// Try npm global install first
|
|
108
|
+
const npmResult = await $`npm install -g @joelhooks/beads`
|
|
109
|
+
.quiet()
|
|
110
|
+
.nothrow();
|
|
111
|
+
if (npmResult.exitCode !== 0) {
|
|
112
|
+
console.log(`${WARN} npm install failed, trying go install...`);
|
|
113
|
+
await run("go", [
|
|
114
|
+
"install",
|
|
115
|
+
"github.com/joelhooks/beads/cmd/bd@latest",
|
|
116
|
+
]);
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "Agent Mail MCP",
|
|
122
|
+
purpose: "Multi-agent coordination server",
|
|
123
|
+
check: async () => {
|
|
124
|
+
// Check if server is running
|
|
125
|
+
const running = await urlReachable(
|
|
126
|
+
"http://127.0.0.1:8765/health/liveness",
|
|
127
|
+
);
|
|
128
|
+
if (running) return true;
|
|
129
|
+
// Check if binary exists
|
|
130
|
+
return commandExists("agent-mail");
|
|
131
|
+
},
|
|
132
|
+
install: async () => {
|
|
133
|
+
console.log(`${INFO} Installing Agent Mail...`);
|
|
134
|
+
console.log(dim(" Agent Mail requires manual setup:"));
|
|
135
|
+
console.log(
|
|
136
|
+
dim(" 1. Clone: git clone https://github.com/joelhooks/agent-mail"),
|
|
137
|
+
);
|
|
138
|
+
console.log(
|
|
139
|
+
dim(" 2. Build: cd agent-mail && go build -o agent-mail ./cmd/server"),
|
|
140
|
+
);
|
|
141
|
+
console.log(dim(" 3. Run: ./agent-mail serve"));
|
|
142
|
+
console.log();
|
|
143
|
+
console.log(
|
|
144
|
+
`${WARN} Skipping automatic install - see instructions above`,
|
|
145
|
+
);
|
|
146
|
+
},
|
|
147
|
+
optional: true,
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: "Redis",
|
|
151
|
+
purpose: "Rate limiting (optional, falls back to SQLite)",
|
|
152
|
+
check: async () => {
|
|
153
|
+
// Check if redis-server is running or installed
|
|
154
|
+
const running = await $`redis-cli ping`.quiet().nothrow();
|
|
155
|
+
if (running.exitCode === 0) return true;
|
|
156
|
+
return commandExists("redis-server");
|
|
157
|
+
},
|
|
158
|
+
install: async () => {
|
|
159
|
+
console.log(`${INFO} Installing Redis...`);
|
|
160
|
+
await run("brew", ["install", "redis"]);
|
|
161
|
+
console.log(dim(" Start with: brew services start redis"));
|
|
162
|
+
},
|
|
163
|
+
optional: true,
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: "CASS (cass-memory)",
|
|
167
|
+
purpose: "Cross-agent session search for historical context",
|
|
168
|
+
check: async () => commandExists("cass"),
|
|
169
|
+
install: async () => {
|
|
170
|
+
console.log(`${INFO} CASS installation...`);
|
|
171
|
+
console.log(
|
|
172
|
+
dim(" Install from: https://github.com/Dicklesworthstone/cass"),
|
|
173
|
+
);
|
|
174
|
+
console.log(`${WARN} Skipping automatic install - see link above`);
|
|
175
|
+
},
|
|
176
|
+
optional: true,
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
name: "UBS (bug scanner)",
|
|
180
|
+
purpose: "Pre-completion bug scanning",
|
|
181
|
+
check: async () => commandExists("ubs"),
|
|
182
|
+
install: async () => {
|
|
183
|
+
console.log(`${INFO} UBS installation...`);
|
|
184
|
+
console.log(dim(" UBS is bundled with OpenCode plugins"));
|
|
185
|
+
console.log(
|
|
186
|
+
`${WARN} Skipping - should be available if OpenCode is installed`,
|
|
187
|
+
);
|
|
188
|
+
},
|
|
189
|
+
optional: true,
|
|
190
|
+
},
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Setup OpenCode directories and copy plugin
|
|
195
|
+
*/
|
|
196
|
+
async function setupOpenCodeDirs(): Promise<void> {
|
|
197
|
+
const configDir = join(homedir(), ".config", "opencode");
|
|
198
|
+
const pluginsDir = join(configDir, "plugins");
|
|
199
|
+
const commandsDir = join(configDir, "commands");
|
|
200
|
+
const agentsDir = join(configDir, "agents");
|
|
201
|
+
|
|
202
|
+
// Create directories
|
|
203
|
+
for (const dir of [pluginsDir, commandsDir, agentsDir]) {
|
|
204
|
+
if (!existsSync(dir)) {
|
|
205
|
+
mkdirSync(dir, { recursive: true });
|
|
206
|
+
console.log(`${CHECK} Created ${dir}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Find plugin files (either in node_modules or local)
|
|
211
|
+
const possiblePaths = [
|
|
212
|
+
join(process.cwd(), "dist", "plugin.js"),
|
|
213
|
+
join(
|
|
214
|
+
process.cwd(),
|
|
215
|
+
"node_modules",
|
|
216
|
+
"opencode-swarm-plugin",
|
|
217
|
+
"dist",
|
|
218
|
+
"plugin.js",
|
|
219
|
+
),
|
|
220
|
+
];
|
|
221
|
+
|
|
222
|
+
let pluginSrc: string | null = null;
|
|
223
|
+
for (const p of possiblePaths) {
|
|
224
|
+
if (existsSync(p)) {
|
|
225
|
+
pluginSrc = p;
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (pluginSrc) {
|
|
231
|
+
const pluginDest = join(pluginsDir, "swarm.js");
|
|
232
|
+
copyFileSync(pluginSrc, pluginDest);
|
|
233
|
+
console.log(`${CHECK} Copied plugin to ${pluginDest}`);
|
|
234
|
+
} else {
|
|
235
|
+
console.log(
|
|
236
|
+
`${WARN} Plugin not found - run 'pnpm build' first or install from npm`,
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Copy example files if they exist
|
|
241
|
+
const examplesDir = join(process.cwd(), "examples");
|
|
242
|
+
const nodeModulesExamples = join(
|
|
243
|
+
process.cwd(),
|
|
244
|
+
"node_modules",
|
|
245
|
+
"opencode-swarm-plugin",
|
|
246
|
+
"examples",
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
const examplesSrc = existsSync(examplesDir)
|
|
250
|
+
? examplesDir
|
|
251
|
+
: nodeModulesExamples;
|
|
252
|
+
|
|
253
|
+
if (existsSync(examplesSrc)) {
|
|
254
|
+
const swarmCmd = join(examplesSrc, "commands", "swarm.md");
|
|
255
|
+
const plannerAgent = join(examplesSrc, "agents", "swarm-planner.md");
|
|
256
|
+
|
|
257
|
+
if (existsSync(swarmCmd)) {
|
|
258
|
+
copyFileSync(swarmCmd, join(commandsDir, "swarm.md"));
|
|
259
|
+
console.log(`${CHECK} Copied /swarm command`);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (existsSync(plannerAgent)) {
|
|
263
|
+
copyFileSync(plannerAgent, join(agentsDir, "swarm-planner.md"));
|
|
264
|
+
console.log(`${CHECK} Copied @swarm-planner agent`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Main setup function
|
|
271
|
+
*/
|
|
272
|
+
async function main() {
|
|
273
|
+
console.log();
|
|
274
|
+
console.log(
|
|
275
|
+
blue("═══════════════════════════════════════════════════════════"),
|
|
276
|
+
);
|
|
277
|
+
console.log(blue(" OpenCode Swarm Plugin - Setup"));
|
|
278
|
+
console.log(
|
|
279
|
+
blue("═══════════════════════════════════════════════════════════"),
|
|
280
|
+
);
|
|
281
|
+
console.log();
|
|
282
|
+
|
|
283
|
+
// Check platform
|
|
284
|
+
if (process.platform !== "darwin") {
|
|
285
|
+
console.log(
|
|
286
|
+
`${WARN} This script is optimized for macOS. Some installs may not work.`,
|
|
287
|
+
);
|
|
288
|
+
console.log();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Check dependencies
|
|
292
|
+
console.log(blue("Checking dependencies...\n"));
|
|
293
|
+
|
|
294
|
+
const missing: Dependency[] = [];
|
|
295
|
+
const optionalMissing: Dependency[] = [];
|
|
296
|
+
|
|
297
|
+
for (const dep of dependencies) {
|
|
298
|
+
const installed = await dep.check();
|
|
299
|
+
const status = installed ? CHECK : dep.optional ? WARN : CROSS;
|
|
300
|
+
const suffix = dep.optional ? dim(" (optional)") : "";
|
|
301
|
+
|
|
302
|
+
console.log(`${status} ${dep.name}${suffix}`);
|
|
303
|
+
console.log(dim(` ${dep.purpose}`));
|
|
304
|
+
|
|
305
|
+
if (!installed) {
|
|
306
|
+
if (dep.optional) {
|
|
307
|
+
optionalMissing.push(dep);
|
|
308
|
+
} else {
|
|
309
|
+
missing.push(dep);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
console.log();
|
|
315
|
+
|
|
316
|
+
// Install missing required dependencies
|
|
317
|
+
if (missing.length > 0) {
|
|
318
|
+
console.log(blue("Installing missing required dependencies...\n"));
|
|
319
|
+
|
|
320
|
+
for (const dep of missing) {
|
|
321
|
+
try {
|
|
322
|
+
await dep.install();
|
|
323
|
+
const nowInstalled = await dep.check();
|
|
324
|
+
if (nowInstalled) {
|
|
325
|
+
console.log(`${CHECK} ${dep.name} installed successfully\n`);
|
|
326
|
+
} else {
|
|
327
|
+
console.log(`${CROSS} ${dep.name} installation may have failed\n`);
|
|
328
|
+
}
|
|
329
|
+
} catch (error) {
|
|
330
|
+
console.log(`${CROSS} Failed to install ${dep.name}: ${error}\n`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Offer to install optional dependencies
|
|
336
|
+
if (optionalMissing.length > 0) {
|
|
337
|
+
console.log(yellow("Optional dependencies not installed:"));
|
|
338
|
+
for (const dep of optionalMissing) {
|
|
339
|
+
console.log(` - ${dep.name}: ${dep.purpose}`);
|
|
340
|
+
}
|
|
341
|
+
console.log();
|
|
342
|
+
console.log(
|
|
343
|
+
dim("The plugin will work without these, with degraded features."),
|
|
344
|
+
);
|
|
345
|
+
console.log();
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Setup OpenCode directories
|
|
349
|
+
console.log(blue("Setting up OpenCode directories...\n"));
|
|
350
|
+
await setupOpenCodeDirs();
|
|
351
|
+
|
|
352
|
+
console.log();
|
|
353
|
+
console.log(
|
|
354
|
+
blue("═══════════════════════════════════════════════════════════"),
|
|
355
|
+
);
|
|
356
|
+
console.log(blue(" Setup Complete!"));
|
|
357
|
+
console.log(
|
|
358
|
+
blue("═══════════════════════════════════════════════════════════"),
|
|
359
|
+
);
|
|
360
|
+
console.log();
|
|
361
|
+
console.log("Next steps:");
|
|
362
|
+
console.log(
|
|
363
|
+
` 1. ${dim("Start Agent Mail (if using multi-agent):")} agent-mail serve`,
|
|
364
|
+
);
|
|
365
|
+
console.log(` 2. ${dim("Initialize beads in your project:")} bd init`);
|
|
366
|
+
console.log(` 3. ${dim("Start OpenCode:")} opencode`);
|
|
367
|
+
console.log(` 4. ${dim("Try the swarm command:")} /swarm "your task here"`);
|
|
368
|
+
console.log();
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
main().catch(console.error);
|