@desplega.ai/agent-swarm 1.0.1 → 1.2.0
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/.claude/settings.local.json +2 -1
- package/.dockerignore +58 -0
- package/.env.docker.example +12 -0
- package/Dockerfile +16 -0
- package/Dockerfile.worker +112 -0
- package/README.md +117 -0
- package/cc-plugin/.claude-plugin/plugin.json +13 -0
- package/cc-plugin/README.md +49 -0
- package/cc-plugin/commands/setup-leader.md +73 -0
- package/cc-plugin/commands/start-worker.md +64 -0
- package/cc-plugin/hooks/hooks.json +71 -0
- package/deploy/DEPLOY.md +60 -0
- package/deploy/agent-swarm.service +17 -0
- package/deploy/install.ts +85 -0
- package/deploy/prod-db.ts +42 -0
- package/deploy/uninstall.ts +12 -0
- package/deploy/update.ts +21 -0
- package/docker-compose.worker.yml +35 -0
- package/docker-entrypoint.sh +62 -0
- package/package.json +9 -2
- package/src/be/db.ts +204 -2
- package/src/cli.tsx +96 -8
- package/src/commands/hook.ts +2 -2
- package/src/commands/setup.tsx +579 -548
- package/src/commands/worker.ts +225 -0
- package/src/hooks/hook.ts +180 -175
- package/src/http.ts +12 -4
- package/src/server.ts +1 -2
- package/src/tools/get-task-details.ts +7 -3
- package/src/tools/join-swarm.ts +23 -11
- package/src/tools/poll-task.ts +34 -2
- package/src/tools/send-task.ts +40 -2
- package/src/tools/store-progress.ts +29 -0
- package/src/types.ts +24 -0
package/src/cli.tsx
CHANGED
|
@@ -6,6 +6,7 @@ import pkg from "../package.json";
|
|
|
6
6
|
import { runClaude } from "./claude.ts";
|
|
7
7
|
import { runHook } from "./commands/hook.ts";
|
|
8
8
|
import { Setup } from "./commands/setup.tsx";
|
|
9
|
+
import { runWorker } from "./commands/worker.ts";
|
|
9
10
|
|
|
10
11
|
// Get CLI name from bin field (assumes single key)
|
|
11
12
|
const binName = Object.keys(pkg.bin)[0];
|
|
@@ -26,6 +27,8 @@ interface ParsedArgs {
|
|
|
26
27
|
headless: boolean;
|
|
27
28
|
dryRun: boolean;
|
|
28
29
|
restore: boolean;
|
|
30
|
+
yes: boolean;
|
|
31
|
+
yolo: boolean;
|
|
29
32
|
additionalArgs: string[];
|
|
30
33
|
}
|
|
31
34
|
|
|
@@ -37,6 +40,8 @@ function parseArgs(args: string[]): ParsedArgs {
|
|
|
37
40
|
let headless = false;
|
|
38
41
|
let dryRun = false;
|
|
39
42
|
let restore = false;
|
|
43
|
+
let yes = false;
|
|
44
|
+
let yolo = false;
|
|
40
45
|
let additionalArgs: string[] = [];
|
|
41
46
|
|
|
42
47
|
// Find if there's a "--" separator for additional args
|
|
@@ -61,10 +66,14 @@ function parseArgs(args: string[]): ParsedArgs {
|
|
|
61
66
|
dryRun = true;
|
|
62
67
|
} else if (arg === "--restore") {
|
|
63
68
|
restore = true;
|
|
69
|
+
} else if (arg === "-y" || arg === "--yes") {
|
|
70
|
+
yes = true;
|
|
71
|
+
} else if (arg === "--yolo") {
|
|
72
|
+
yolo = true;
|
|
64
73
|
}
|
|
65
74
|
}
|
|
66
75
|
|
|
67
|
-
return { command, port, key, msg, headless, dryRun, restore, additionalArgs };
|
|
76
|
+
return { command, port, key, msg, headless, dryRun, restore, yes, yolo, additionalArgs };
|
|
68
77
|
}
|
|
69
78
|
|
|
70
79
|
function Help() {
|
|
@@ -121,6 +130,12 @@ function Help() {
|
|
|
121
130
|
</Box>
|
|
122
131
|
<Text>Run Claude CLI</Text>
|
|
123
132
|
</Box>
|
|
133
|
+
<Box>
|
|
134
|
+
<Box width={12}>
|
|
135
|
+
<Text color="green">worker</Text>
|
|
136
|
+
</Box>
|
|
137
|
+
<Text>Run Claude in headless loop mode</Text>
|
|
138
|
+
</Box>
|
|
124
139
|
<Box>
|
|
125
140
|
<Box width={12}>
|
|
126
141
|
<Text color="green">version</Text>
|
|
@@ -149,6 +164,12 @@ function Help() {
|
|
|
149
164
|
</Box>
|
|
150
165
|
<Text>Restore files from .bak backups</Text>
|
|
151
166
|
</Box>
|
|
167
|
+
<Box>
|
|
168
|
+
<Box width={24}>
|
|
169
|
+
<Text color="yellow">-y, --yes</Text>
|
|
170
|
+
</Box>
|
|
171
|
+
<Text>Non-interactive mode (use env vars)</Text>
|
|
172
|
+
</Box>
|
|
152
173
|
</Box>
|
|
153
174
|
|
|
154
175
|
<Box marginTop={1} flexDirection="column">
|
|
@@ -189,38 +210,82 @@ function Help() {
|
|
|
189
210
|
</Box>
|
|
190
211
|
</Box>
|
|
191
212
|
|
|
213
|
+
<Box marginTop={1} flexDirection="column">
|
|
214
|
+
<Text bold>Options for 'worker':</Text>
|
|
215
|
+
<Box>
|
|
216
|
+
<Box width={24}>
|
|
217
|
+
<Text color="yellow">-m, --msg {"<prompt>"}</Text>
|
|
218
|
+
</Box>
|
|
219
|
+
<Text>Custom prompt (default: /agent-swarm:start-worker)</Text>
|
|
220
|
+
</Box>
|
|
221
|
+
<Box>
|
|
222
|
+
<Box width={24}>
|
|
223
|
+
<Text color="yellow">--yolo</Text>
|
|
224
|
+
</Box>
|
|
225
|
+
<Text>Continue on errors instead of stopping</Text>
|
|
226
|
+
</Box>
|
|
227
|
+
<Box>
|
|
228
|
+
<Box width={24}>
|
|
229
|
+
<Text color="yellow">-- {"<args...>"}</Text>
|
|
230
|
+
</Box>
|
|
231
|
+
<Text>Additional arguments to pass to Claude CLI</Text>
|
|
232
|
+
</Box>
|
|
233
|
+
</Box>
|
|
234
|
+
|
|
192
235
|
<Box marginTop={1} flexDirection="column">
|
|
193
236
|
<Text bold>Examples:</Text>
|
|
194
237
|
<Text dimColor> {binName} setup</Text>
|
|
195
238
|
<Text dimColor> {binName} setup --dry-run</Text>
|
|
239
|
+
<Text dimColor> {binName} setup -y</Text>
|
|
196
240
|
<Text dimColor> {binName} mcp</Text>
|
|
197
241
|
<Text dimColor> {binName} mcp --port 8080</Text>
|
|
198
242
|
<Text dimColor> {binName} mcp -p 8080 -k my-secret-key</Text>
|
|
199
243
|
<Text dimColor> {binName} claude</Text>
|
|
200
244
|
<Text dimColor> {binName} claude --headless -m "Hello"</Text>
|
|
201
245
|
<Text dimColor> {binName} claude -- --resume</Text>
|
|
246
|
+
<Text dimColor> {binName} worker</Text>
|
|
247
|
+
<Text dimColor> {binName} worker --yolo</Text>
|
|
248
|
+
<Text dimColor> {binName} worker -m "Custom prompt"</Text>
|
|
202
249
|
</Box>
|
|
203
250
|
|
|
204
251
|
<Box marginTop={1} flexDirection="column">
|
|
205
252
|
<Text bold>Environment variables:</Text>
|
|
206
253
|
<Box>
|
|
207
|
-
<Box width={
|
|
254
|
+
<Box width={24}>
|
|
208
255
|
<Text color="magenta">PORT</Text>
|
|
209
256
|
</Box>
|
|
210
257
|
<Text>Default port for the MCP server</Text>
|
|
211
258
|
</Box>
|
|
212
259
|
<Box>
|
|
213
|
-
<Box width={
|
|
260
|
+
<Box width={24}>
|
|
214
261
|
<Text color="magenta">API_KEY</Text>
|
|
215
262
|
</Box>
|
|
216
263
|
<Text>API key for authentication (Bearer token)</Text>
|
|
217
264
|
</Box>
|
|
218
265
|
<Box>
|
|
219
|
-
<Box width={
|
|
266
|
+
<Box width={24}>
|
|
220
267
|
<Text color="magenta">MCP_BASE_URL</Text>
|
|
221
268
|
</Box>
|
|
222
269
|
<Text>Base URL for the MCP server (used by setup)</Text>
|
|
223
270
|
</Box>
|
|
271
|
+
<Box>
|
|
272
|
+
<Box width={24}>
|
|
273
|
+
<Text color="magenta">AGENT_ID</Text>
|
|
274
|
+
</Box>
|
|
275
|
+
<Text>UUID for agent identification</Text>
|
|
276
|
+
</Box>
|
|
277
|
+
<Box>
|
|
278
|
+
<Box width={24}>
|
|
279
|
+
<Text color="magenta">SESSION_ID</Text>
|
|
280
|
+
</Box>
|
|
281
|
+
<Text>Folder name for worker logs (auto-generated)</Text>
|
|
282
|
+
</Box>
|
|
283
|
+
<Box>
|
|
284
|
+
<Box width={24}>
|
|
285
|
+
<Text color="magenta">WORKER_YOLO</Text>
|
|
286
|
+
</Box>
|
|
287
|
+
<Text>If "true", worker continues on errors</Text>
|
|
288
|
+
</Box>
|
|
224
289
|
</Box>
|
|
225
290
|
</Box>
|
|
226
291
|
);
|
|
@@ -298,6 +363,27 @@ function ClaudeRunner({ msg, headless, additionalArgs }: ClaudeRunnerProps) {
|
|
|
298
363
|
return null;
|
|
299
364
|
}
|
|
300
365
|
|
|
366
|
+
interface WorkerRunnerProps {
|
|
367
|
+
prompt: string;
|
|
368
|
+
yolo: boolean;
|
|
369
|
+
additionalArgs: string[];
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function WorkerRunner({ prompt, yolo, additionalArgs }: WorkerRunnerProps) {
|
|
373
|
+
const { exit } = useApp();
|
|
374
|
+
|
|
375
|
+
useEffect(() => {
|
|
376
|
+
runWorker({
|
|
377
|
+
prompt: prompt || undefined,
|
|
378
|
+
yolo,
|
|
379
|
+
additionalArgs,
|
|
380
|
+
}).catch((err) => exit(err));
|
|
381
|
+
// Note: runWorker runs indefinitely, so we don't call exit() on success
|
|
382
|
+
}, [prompt, yolo, additionalArgs, exit]);
|
|
383
|
+
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
|
|
301
387
|
function UnknownCommand({ command }: { command: string }) {
|
|
302
388
|
const { exit } = useApp();
|
|
303
389
|
useEffect(() => {
|
|
@@ -328,15 +414,17 @@ function Version() {
|
|
|
328
414
|
}
|
|
329
415
|
|
|
330
416
|
function App({ args }: { args: ParsedArgs }) {
|
|
331
|
-
const { command, port, key, msg, headless, dryRun, restore, additionalArgs } = args;
|
|
417
|
+
const { command, port, key, msg, headless, dryRun, restore, yes, yolo, additionalArgs } = args;
|
|
332
418
|
|
|
333
419
|
switch (command) {
|
|
334
420
|
case "setup":
|
|
335
|
-
return <Setup dryRun={dryRun} restore={restore} />;
|
|
421
|
+
return <Setup dryRun={dryRun} restore={restore} yes={yes} />;
|
|
336
422
|
case "mcp":
|
|
337
423
|
return <McpServer port={port} apiKey={key} />;
|
|
338
424
|
case "claude":
|
|
339
425
|
return <ClaudeRunner msg={msg} headless={headless} additionalArgs={additionalArgs} />;
|
|
426
|
+
case "worker":
|
|
427
|
+
return <WorkerRunner prompt={msg} yolo={yolo} additionalArgs={additionalArgs} />;
|
|
340
428
|
case "version":
|
|
341
429
|
return <Version />;
|
|
342
430
|
case "help":
|
|
@@ -351,7 +439,7 @@ const args = parseArgs(process.argv.slice(2));
|
|
|
351
439
|
|
|
352
440
|
// Handle hook command separately (no UI needed)
|
|
353
441
|
if (args.command === "hook") {
|
|
354
|
-
|
|
442
|
+
runHook();
|
|
355
443
|
} else {
|
|
356
|
-
|
|
444
|
+
render(<App args={args} />);
|
|
357
445
|
}
|
package/src/commands/hook.ts
CHANGED