opencode-swarm-plugin 0.57.6 → 0.58.4
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/bin/swarm.ts +350 -8
- package/claude-plugin/.claude-plugin/plugin.json +1 -1
- package/claude-plugin/README.md +187 -0
- package/claude-plugin/agents/worker.md +1 -0
- package/claude-plugin/dist/index.js +214 -47
- package/claude-plugin/hooks/hooks.json +67 -0
- package/claude-plugin/skills/release/SKILL.md +101 -0
- package/claude-plugin/skills/swarm-cli/SKILL.md +82 -0
- package/dist/bin/swarm.js +682 -103
- package/dist/hive.d.ts.map +1 -1
- package/dist/hive.js +34 -8
- package/dist/index.js +198 -47
- package/dist/marketplace/index.js +214 -47
- package/dist/plugin.js +198 -47
- package/dist/query-tools.d.ts +4 -4
- package/dist/query-tools.d.ts.map +1 -1
- package/dist/rate-limiter.d.ts +2 -0
- package/dist/rate-limiter.d.ts.map +1 -1
- package/dist/skills.d.ts.map +1 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/swarm-decompose.d.ts.map +1 -1
- package/dist/swarm-orchestrate.d.ts.map +1 -1
- package/dist/swarm-prompts.d.ts +1 -1
- package/dist/swarm-prompts.d.ts.map +1 -1
- package/dist/swarm-prompts.js +147 -39
- package/dist/tool-availability.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -40378,14 +40378,17 @@ class FlushManager {
|
|
|
40378
40378
|
outputPath;
|
|
40379
40379
|
debounceMs;
|
|
40380
40380
|
onFlush;
|
|
40381
|
+
onError;
|
|
40381
40382
|
timer = null;
|
|
40382
40383
|
flushing = false;
|
|
40384
|
+
lastError = null;
|
|
40383
40385
|
constructor(options2) {
|
|
40384
40386
|
this.adapter = options2.adapter;
|
|
40385
40387
|
this.projectKey = options2.projectKey;
|
|
40386
40388
|
this.outputPath = options2.outputPath;
|
|
40387
40389
|
this.debounceMs = options2.debounceMs ?? 30000;
|
|
40388
40390
|
this.onFlush = options2.onFlush;
|
|
40391
|
+
this.onError = options2.onError;
|
|
40389
40392
|
}
|
|
40390
40393
|
scheduleFlush() {
|
|
40391
40394
|
if (this.timer) {
|
|
@@ -40393,7 +40396,11 @@ class FlushManager {
|
|
|
40393
40396
|
}
|
|
40394
40397
|
this.timer = setTimeout(() => {
|
|
40395
40398
|
this.flush().catch((err) => {
|
|
40399
|
+
this.lastError = err instanceof Error ? err : new Error(String(err));
|
|
40396
40400
|
console.error("[FlushManager] Flush error:", err);
|
|
40401
|
+
if (this.onError) {
|
|
40402
|
+
this.onError(this.lastError);
|
|
40403
|
+
}
|
|
40397
40404
|
});
|
|
40398
40405
|
}, this.debounceMs);
|
|
40399
40406
|
}
|
|
@@ -40455,6 +40462,15 @@ class FlushManager {
|
|
|
40455
40462
|
this.flushing = false;
|
|
40456
40463
|
}
|
|
40457
40464
|
}
|
|
40465
|
+
hasError() {
|
|
40466
|
+
return this.lastError !== null;
|
|
40467
|
+
}
|
|
40468
|
+
getLastError() {
|
|
40469
|
+
return this.lastError;
|
|
40470
|
+
}
|
|
40471
|
+
clearError() {
|
|
40472
|
+
this.lastError = null;
|
|
40473
|
+
}
|
|
40458
40474
|
stop() {
|
|
40459
40475
|
if (this.timer) {
|
|
40460
40476
|
clearTimeout(this.timer);
|
|
@@ -144060,13 +144076,13 @@ Scripts run in the skill's directory with the project directory as an argument.`
|
|
|
144060
144076
|
}
|
|
144061
144077
|
const scriptPath = join23(skill.directory, "scripts", args2.script);
|
|
144062
144078
|
const scriptArgs = args2.args || [];
|
|
144079
|
+
const TIMEOUT_MS = 60000;
|
|
144080
|
+
const proc = Bun.spawn([scriptPath, skillsProjectDirectory, ...scriptArgs], {
|
|
144081
|
+
cwd: skill.directory,
|
|
144082
|
+
stdout: "pipe",
|
|
144083
|
+
stderr: "pipe"
|
|
144084
|
+
});
|
|
144063
144085
|
try {
|
|
144064
|
-
const TIMEOUT_MS = 60000;
|
|
144065
|
-
const proc = Bun.spawn([scriptPath, skillsProjectDirectory, ...scriptArgs], {
|
|
144066
|
-
cwd: skill.directory,
|
|
144067
|
-
stdout: "pipe",
|
|
144068
|
-
stderr: "pipe"
|
|
144069
|
-
});
|
|
144070
144086
|
const timeoutPromise = new Promise((resolve5) => {
|
|
144071
144087
|
setTimeout(() => resolve5({ timedOut: true }), TIMEOUT_MS);
|
|
144072
144088
|
});
|
|
@@ -144080,7 +144096,6 @@ Scripts run in the skill's directory with the project directory as an argument.`
|
|
|
144080
144096
|
})();
|
|
144081
144097
|
const result = await Promise.race([resultPromise, timeoutPromise]);
|
|
144082
144098
|
if (result.timedOut) {
|
|
144083
|
-
proc.kill();
|
|
144084
144099
|
return `Script timed out after ${TIMEOUT_MS / 1000} seconds.`;
|
|
144085
144100
|
}
|
|
144086
144101
|
const output = result.stdout + result.stderr;
|
|
@@ -144092,6 +144107,8 @@ ${output}`;
|
|
|
144092
144107
|
}
|
|
144093
144108
|
} catch (error47) {
|
|
144094
144109
|
return `Failed to execute script: ${error47 instanceof Error ? error47.message : String(error47)}`;
|
|
144110
|
+
} finally {
|
|
144111
|
+
proc.kill();
|
|
144095
144112
|
}
|
|
144096
144113
|
}
|
|
144097
144114
|
});
|
|
@@ -144994,9 +145011,11 @@ async function execSemanticMemory(args2) {
|
|
|
144994
145011
|
stderr: "pipe"
|
|
144995
145012
|
});
|
|
144996
145013
|
try {
|
|
145014
|
+
const TIMEOUT_MS = 30000;
|
|
145015
|
+
const timeoutPromise = new Promise((_, reject3) => setTimeout(() => reject3(new Error("Process timed out after 30s")), TIMEOUT_MS));
|
|
144997
145016
|
const stdout = Buffer.from(await new Response(proc.stdout).arrayBuffer());
|
|
144998
145017
|
const stderr = Buffer.from(await new Response(proc.stderr).arrayBuffer());
|
|
144999
|
-
const exitCode = await proc.exited;
|
|
145018
|
+
const exitCode = await Promise.race([proc.exited, timeoutPromise]);
|
|
145000
145019
|
return { exitCode, stdout, stderr };
|
|
145001
145020
|
} finally {
|
|
145002
145021
|
proc.kill();
|
|
@@ -175327,12 +175346,16 @@ async function runGitCommand(args2) {
|
|
|
175327
175346
|
stdout: "pipe",
|
|
175328
175347
|
stderr: "pipe"
|
|
175329
175348
|
});
|
|
175330
|
-
|
|
175331
|
-
|
|
175332
|
-
|
|
175333
|
-
|
|
175334
|
-
|
|
175335
|
-
|
|
175349
|
+
try {
|
|
175350
|
+
const [stdout, stderr] = await Promise.all([
|
|
175351
|
+
new Response(proc.stdout).text(),
|
|
175352
|
+
new Response(proc.stderr).text()
|
|
175353
|
+
]);
|
|
175354
|
+
const exitCode = await proc.exited;
|
|
175355
|
+
return { exitCode, stdout, stderr };
|
|
175356
|
+
} finally {
|
|
175357
|
+
proc.kill();
|
|
175358
|
+
}
|
|
175336
175359
|
}
|
|
175337
175360
|
|
|
175338
175361
|
class HiveError extends Error {
|
|
@@ -175638,9 +175661,9 @@ var hive_create = tool({
|
|
|
175638
175661
|
}
|
|
175639
175662
|
});
|
|
175640
175663
|
var hive_create_epic = tool({
|
|
175641
|
-
description: "Create epic with subtasks
|
|
175664
|
+
description: "Create epic with subtasks atomically. REQUIRED: epic_title, subtasks (array with {title, files?}). Use after swarm_validate_decomposition confirms your decomposition is valid. Each subtask should list files it will modify to enable parallel work without conflicts.",
|
|
175642
175665
|
args: {
|
|
175643
|
-
epic_title: tool.schema.string().describe("Epic title"),
|
|
175666
|
+
epic_title: tool.schema.string().describe("Epic title (e.g., 'Implement user auth')"),
|
|
175644
175667
|
epic_description: tool.schema.string().optional().describe("Epic description"),
|
|
175645
175668
|
epic_id: tool.schema.string().optional().describe("Custom ID for the epic (e.g., 'phase-0')"),
|
|
175646
175669
|
subtasks: tool.schema.array(tool.schema.object({
|
|
@@ -175659,6 +175682,28 @@ var hive_create_epic = tool({
|
|
|
175659
175682
|
}).optional().describe("Recovery context from checkpoint compaction")
|
|
175660
175683
|
},
|
|
175661
175684
|
async execute(args2, ctx) {
|
|
175685
|
+
const missing = [];
|
|
175686
|
+
if (!args2.epic_title)
|
|
175687
|
+
missing.push("epic_title");
|
|
175688
|
+
if (!args2.subtasks || args2.subtasks.length === 0)
|
|
175689
|
+
missing.push("subtasks (array of subtask objects)");
|
|
175690
|
+
if (missing.length > 0) {
|
|
175691
|
+
return JSON.stringify({
|
|
175692
|
+
success: false,
|
|
175693
|
+
error: `Missing required parameters: ${missing.join(", ")}`,
|
|
175694
|
+
hint: "hive_create_epic creates an epic with subtasks atomically.",
|
|
175695
|
+
example: {
|
|
175696
|
+
epic_title: "Implement user authentication",
|
|
175697
|
+
epic_description: "Add login, logout, and session management",
|
|
175698
|
+
subtasks: [
|
|
175699
|
+
{ title: "Create auth service", files: ["src/auth/service.ts"] },
|
|
175700
|
+
{ title: "Add login endpoint", files: ["src/api/login.ts"] },
|
|
175701
|
+
{ title: "Add session middleware", files: ["src/middleware/session.ts"] }
|
|
175702
|
+
]
|
|
175703
|
+
},
|
|
175704
|
+
tip: "Each subtask should have a title and optionally files it will modify. This helps with file reservation and parallel execution."
|
|
175705
|
+
}, null, 2);
|
|
175706
|
+
}
|
|
175662
175707
|
const validated = EpicCreateArgsSchema.parse(args2);
|
|
175663
175708
|
const projectKey = getHiveWorkingDirectory();
|
|
175664
175709
|
const adapter5 = await getHiveAdapter(projectKey);
|
|
@@ -176497,13 +176542,17 @@ var toolCheckers = {
|
|
|
176497
176542
|
stderr: "pipe"
|
|
176498
176543
|
});
|
|
176499
176544
|
const timeout6 = setTimeout(() => proc.kill(), BUNX_TIMEOUT_MS);
|
|
176500
|
-
|
|
176501
|
-
|
|
176502
|
-
|
|
176503
|
-
|
|
176504
|
-
|
|
176505
|
-
|
|
176506
|
-
|
|
176545
|
+
try {
|
|
176546
|
+
const exitCode = await proc.exited;
|
|
176547
|
+
return {
|
|
176548
|
+
available: exitCode === 0,
|
|
176549
|
+
checkedAt: new Date().toISOString(),
|
|
176550
|
+
version: "bunx"
|
|
176551
|
+
};
|
|
176552
|
+
} finally {
|
|
176553
|
+
clearTimeout(timeout6);
|
|
176554
|
+
proc.kill();
|
|
176555
|
+
}
|
|
176507
176556
|
} catch (e) {
|
|
176508
176557
|
return {
|
|
176509
176558
|
available: false,
|
|
@@ -176576,13 +176625,17 @@ var toolCheckers = {
|
|
|
176576
176625
|
stderr: "pipe"
|
|
176577
176626
|
});
|
|
176578
176627
|
const timeout6 = setTimeout(() => proc.kill(), BUNX_TIMEOUT_MS);
|
|
176579
|
-
|
|
176580
|
-
|
|
176581
|
-
|
|
176582
|
-
|
|
176583
|
-
|
|
176584
|
-
|
|
176585
|
-
|
|
176628
|
+
try {
|
|
176629
|
+
const exitCode = await proc.exited;
|
|
176630
|
+
return {
|
|
176631
|
+
available: exitCode === 0,
|
|
176632
|
+
checkedAt: new Date().toISOString(),
|
|
176633
|
+
version: "bunx-semantic-memory"
|
|
176634
|
+
};
|
|
176635
|
+
} finally {
|
|
176636
|
+
clearTimeout(timeout6);
|
|
176637
|
+
proc.kill();
|
|
176638
|
+
}
|
|
176586
176639
|
} catch (e) {
|
|
176587
176640
|
return {
|
|
176588
176641
|
available: false,
|
|
@@ -176929,17 +176982,20 @@ class SqliteRateLimiter {
|
|
|
176929
176982
|
const MAX_BATCHES = 10;
|
|
176930
176983
|
const cutoff = Date.now() - 7200000;
|
|
176931
176984
|
let totalDeleted = 0;
|
|
176985
|
+
let batches = 0;
|
|
176932
176986
|
for (let i = 0;i < MAX_BATCHES; i++) {
|
|
176933
|
-
const result = this.db.run(`DELETE FROM rate_limits
|
|
176987
|
+
const result = this.db.run(`DELETE FROM rate_limits
|
|
176934
176988
|
WHERE rowid IN (
|
|
176935
|
-
SELECT rowid FROM rate_limits
|
|
176936
|
-
WHERE timestamp < ?
|
|
176989
|
+
SELECT rowid FROM rate_limits
|
|
176990
|
+
WHERE timestamp < ?
|
|
176937
176991
|
LIMIT ?
|
|
176938
176992
|
)`, [cutoff, BATCH_SIZE]);
|
|
176939
176993
|
totalDeleted += result.changes;
|
|
176994
|
+
batches++;
|
|
176940
176995
|
if (result.changes < BATCH_SIZE)
|
|
176941
176996
|
break;
|
|
176942
176997
|
}
|
|
176998
|
+
return { totalDeleted, batches };
|
|
176943
176999
|
}
|
|
176944
177000
|
async recordRequest(agentName, endpoint) {
|
|
176945
177001
|
const now3 = Date.now();
|
|
@@ -179413,14 +179469,27 @@ function formatCassHistoryForPrompt(history) {
|
|
|
179413
179469
|
`);
|
|
179414
179470
|
}
|
|
179415
179471
|
var swarm_decompose = tool({
|
|
179416
|
-
description: "Generate decomposition prompt for breaking task into parallelizable subtasks.
|
|
179472
|
+
description: "Generate decomposition prompt for breaking task into parallelizable subtasks. REQUIRED: task (the work to decompose). Returns a prompt - use it to plan subtasks, then validate with swarm_validate_decomposition, then create with hive_create_epic.",
|
|
179417
179473
|
args: {
|
|
179418
|
-
task: tool.schema.string().min(1).describe("Task description
|
|
179474
|
+
task: tool.schema.string().min(1).describe("Task description (e.g., 'Add user authentication with login/logout')"),
|
|
179419
179475
|
context: tool.schema.string().optional().describe("Additional context (codebase info, constraints, etc.)"),
|
|
179420
179476
|
query_cass: tool.schema.boolean().optional().describe("Query CASS for similar past tasks (default: true)"),
|
|
179421
179477
|
cass_limit: tool.schema.number().int().min(1).optional().describe("Max CASS results to include (default: 3)")
|
|
179422
179478
|
},
|
|
179423
179479
|
async execute(args2) {
|
|
179480
|
+
if (!args2.task) {
|
|
179481
|
+
return JSON.stringify({
|
|
179482
|
+
success: false,
|
|
179483
|
+
error: "Missing required parameter: task",
|
|
179484
|
+
hint: "swarm_decompose generates a decomposition prompt for breaking a task into parallelizable subtasks.",
|
|
179485
|
+
example: {
|
|
179486
|
+
task: "Implement user authentication with login, logout, and session management",
|
|
179487
|
+
context: "This is a Next.js app using Prisma for database access",
|
|
179488
|
+
query_cass: true
|
|
179489
|
+
},
|
|
179490
|
+
tip: "Provide a clear task description. The tool will generate a prompt for decomposition and optionally query past similar tasks for patterns."
|
|
179491
|
+
}, null, 2);
|
|
179492
|
+
}
|
|
179424
179493
|
const { formatMemoryQueryForDecomposition: formatMemoryQueryForDecomposition2 } = await Promise.resolve().then(() => (init_learning(), exports_learning));
|
|
179425
179494
|
let cassContext = "";
|
|
179426
179495
|
let cassResultInfo;
|
|
@@ -179473,9 +179542,9 @@ ${fullContext}` : `## Additional Context
|
|
|
179473
179542
|
}
|
|
179474
179543
|
});
|
|
179475
179544
|
var swarm_validate_decomposition = tool({
|
|
179476
|
-
description: "Validate
|
|
179545
|
+
description: "Validate decomposition JSON before creating epic. REQUIRED: response (JSON string with {epic: {title, description}, subtasks: [{title, files, dependencies}]}). Checks for file conflicts and valid dependencies. Call after planning, before hive_create_epic.",
|
|
179477
179546
|
args: {
|
|
179478
|
-
response: tool.schema.string().describe("JSON
|
|
179547
|
+
response: tool.schema.string().describe("JSON string with epic and subtasks (see example in error hint)"),
|
|
179479
179548
|
project_path: tool.schema.string().optional().describe("Project path for eval capture"),
|
|
179480
179549
|
task: tool.schema.string().optional().describe("Original task description for eval capture"),
|
|
179481
179550
|
context: tool.schema.string().optional().describe("Context provided for decomposition"),
|
|
@@ -179483,8 +179552,35 @@ var swarm_validate_decomposition = tool({
|
|
|
179483
179552
|
epic_id: tool.schema.string().optional().describe("Epic ID for eval capture")
|
|
179484
179553
|
},
|
|
179485
179554
|
async execute(args2) {
|
|
179555
|
+
if (!args2.response) {
|
|
179556
|
+
return JSON.stringify({
|
|
179557
|
+
success: false,
|
|
179558
|
+
valid: false,
|
|
179559
|
+
error: "Missing required parameter: response",
|
|
179560
|
+
hint: "swarm_validate_decomposition validates a decomposition JSON. Pass the decomposition output as the 'response' parameter.",
|
|
179561
|
+
example: {
|
|
179562
|
+
response: JSON.stringify({
|
|
179563
|
+
epic: { title: "Epic title", description: "Epic description" },
|
|
179564
|
+
subtasks: [
|
|
179565
|
+
{ title: "Subtask 1", description: "...", files: ["src/file.ts"], dependencies: [] }
|
|
179566
|
+
]
|
|
179567
|
+
}),
|
|
179568
|
+
project_path: "/path/to/project",
|
|
179569
|
+
task: "Original task description"
|
|
179570
|
+
},
|
|
179571
|
+
tip: "This tool validates the JSON output from your decomposition planning. The 'response' should be a JSON string matching CellTreeSchema."
|
|
179572
|
+
}, null, 2);
|
|
179573
|
+
}
|
|
179486
179574
|
try {
|
|
179487
|
-
|
|
179575
|
+
let parsed;
|
|
179576
|
+
if (typeof args2.response === "string") {
|
|
179577
|
+
parsed = JSON.parse(args2.response);
|
|
179578
|
+
if (typeof parsed === "string") {
|
|
179579
|
+
parsed = JSON.parse(parsed);
|
|
179580
|
+
}
|
|
179581
|
+
} else {
|
|
179582
|
+
parsed = args2.response;
|
|
179583
|
+
}
|
|
179488
179584
|
const validated = CellTreeSchema.parse(parsed);
|
|
179489
179585
|
const conflicts = detectFileConflicts(validated.subtasks);
|
|
179490
179586
|
if (conflicts.length > 0) {
|
|
@@ -182574,17 +182670,41 @@ var swarm_status = tool({
|
|
|
182574
182670
|
}
|
|
182575
182671
|
});
|
|
182576
182672
|
var swarm_progress = tool({
|
|
182577
|
-
description: "Report progress on a subtask to coordinator",
|
|
182673
|
+
description: "Report progress on a subtask to coordinator. REQUIRED: project_key, agent_name, bead_id, status. Call periodically (every 25% or when blocked) to keep coordinator informed. Use status='blocked' with message explaining the blocker if you're stuck.",
|
|
182578
182674
|
args: {
|
|
182579
|
-
project_key: tool.schema.string().describe("Project path"),
|
|
182580
|
-
agent_name: tool.schema.string().describe("Your
|
|
182581
|
-
bead_id: tool.schema.string().describe("
|
|
182675
|
+
project_key: tool.schema.string().describe("Project path (e.g., '/Users/name/project')"),
|
|
182676
|
+
agent_name: tool.schema.string().describe("Your agent name from swarmmail_init"),
|
|
182677
|
+
bead_id: tool.schema.string().describe("Task ID from your spawn prompt or hive cell"),
|
|
182582
182678
|
status: tool.schema.enum(["in_progress", "blocked", "completed", "failed"]).describe("Current status"),
|
|
182583
182679
|
message: tool.schema.string().optional().describe("Progress message or blockers"),
|
|
182584
182680
|
progress_percent: tool.schema.number().min(0).max(100).optional().describe("Completion percentage"),
|
|
182585
182681
|
files_touched: tool.schema.array(tool.schema.string()).optional().describe("Files modified so far")
|
|
182586
182682
|
},
|
|
182587
182683
|
async execute(args2) {
|
|
182684
|
+
const missing = [];
|
|
182685
|
+
if (!args2.bead_id)
|
|
182686
|
+
missing.push("bead_id");
|
|
182687
|
+
if (!args2.project_key)
|
|
182688
|
+
missing.push("project_key");
|
|
182689
|
+
if (!args2.agent_name)
|
|
182690
|
+
missing.push("agent_name");
|
|
182691
|
+
if (!args2.status)
|
|
182692
|
+
missing.push("status");
|
|
182693
|
+
if (missing.length > 0) {
|
|
182694
|
+
return JSON.stringify({
|
|
182695
|
+
success: false,
|
|
182696
|
+
error: `Missing required parameters: ${missing.join(", ")}`,
|
|
182697
|
+
hint: "swarm_progress reports task progress to the coordinator.",
|
|
182698
|
+
example: {
|
|
182699
|
+
project_key: "/path/to/project",
|
|
182700
|
+
agent_name: "your-agent-name",
|
|
182701
|
+
bead_id: "your-task-id from spawn",
|
|
182702
|
+
status: "in_progress",
|
|
182703
|
+
progress_percent: 50,
|
|
182704
|
+
message: "Completed X, working on Y"
|
|
182705
|
+
}
|
|
182706
|
+
}, null, 2);
|
|
182707
|
+
}
|
|
182588
182708
|
const progress = {
|
|
182589
182709
|
bead_id: args2.bead_id,
|
|
182590
182710
|
agent_name: args2.agent_name,
|
|
@@ -182710,12 +182830,12 @@ ${args2.files_affected.map((f) => `- \`${f}\``).join(`
|
|
|
182710
182830
|
}
|
|
182711
182831
|
});
|
|
182712
182832
|
var swarm_complete = tool({
|
|
182713
|
-
description: "Mark subtask complete with Verification Gate. Runs typecheck
|
|
182833
|
+
description: "Mark subtask complete with Verification Gate. REQUIRED: project_key, agent_name, bead_id (from your task assignment), summary, start_time (Date.now() from when you started). Before calling: 1) hivemind_store your learnings, 2) list files_touched for verification. Runs typecheck/tests before finalizing.",
|
|
182714
182834
|
args: {
|
|
182715
|
-
project_key: tool.schema.string().describe("Project path"),
|
|
182716
|
-
agent_name: tool.schema.string().describe("Your
|
|
182717
|
-
bead_id: tool.schema.string().describe("
|
|
182718
|
-
summary: tool.schema.string().describe("
|
|
182835
|
+
project_key: tool.schema.string().describe("Project path (e.g., '/Users/name/project')"),
|
|
182836
|
+
agent_name: tool.schema.string().describe("Your agent name from swarmmail_init"),
|
|
182837
|
+
bead_id: tool.schema.string().describe("Task ID from your spawn prompt or hive cell"),
|
|
182838
|
+
summary: tool.schema.string().describe("What you accomplished (1-3 sentences)"),
|
|
182719
182839
|
evaluation: tool.schema.string().optional().describe("Self-evaluation JSON (Evaluation schema)"),
|
|
182720
182840
|
files_touched: tool.schema.array(tool.schema.string()).optional().describe("Files modified - will be verified (typecheck, tests)"),
|
|
182721
182841
|
skip_verification: tool.schema.boolean().optional().describe("Skip ALL verification (typecheck, tests). Use sparingly! (default: false)"),
|
|
@@ -182726,6 +182846,33 @@ var swarm_complete = tool({
|
|
|
182726
182846
|
skip_review: tool.schema.boolean().optional().describe("Skip review gate check (default: false). Use only for tasks that don't require coordinator review.")
|
|
182727
182847
|
},
|
|
182728
182848
|
async execute(args2, _ctx) {
|
|
182849
|
+
const missing = [];
|
|
182850
|
+
if (!args2.bead_id)
|
|
182851
|
+
missing.push("bead_id");
|
|
182852
|
+
if (!args2.project_key)
|
|
182853
|
+
missing.push("project_key");
|
|
182854
|
+
if (!args2.agent_name)
|
|
182855
|
+
missing.push("agent_name");
|
|
182856
|
+
if (!args2.summary)
|
|
182857
|
+
missing.push("summary");
|
|
182858
|
+
if (args2.start_time === undefined)
|
|
182859
|
+
missing.push("start_time");
|
|
182860
|
+
if (missing.length > 0) {
|
|
182861
|
+
return JSON.stringify({
|
|
182862
|
+
success: false,
|
|
182863
|
+
error: `Missing required parameters: ${missing.join(", ")}`,
|
|
182864
|
+
hint: "swarm_complete marks a subtask as done. All parameters are required.",
|
|
182865
|
+
example: {
|
|
182866
|
+
project_key: "/path/to/project",
|
|
182867
|
+
agent_name: "your-agent-name",
|
|
182868
|
+
bead_id: "epic-id.subtask-num OR cell-id from hive",
|
|
182869
|
+
summary: "Brief description of what you completed",
|
|
182870
|
+
start_time: Date.now(),
|
|
182871
|
+
files_touched: ["src/file1.ts", "src/file2.ts"]
|
|
182872
|
+
},
|
|
182873
|
+
tip: "The bead_id comes from swarm_spawn_subtask or hive_create. Check your task assignment for the correct ID."
|
|
182874
|
+
}, null, 2);
|
|
182875
|
+
}
|
|
182729
182876
|
const epicId = args2.bead_id.includes(".") ? args2.bead_id.split(".")[0] : args2.bead_id;
|
|
182730
182877
|
if (!args2.skip_review) {
|
|
182731
182878
|
const reviewStatusResult = getReviewStatus(args2.bead_id);
|
|
@@ -184062,6 +184209,26 @@ Before writing code:
|
|
|
184062
184209
|
Begin work on your subtask now.`;
|
|
184063
184210
|
var SUBTASK_PROMPT_V2 = `You are a swarm agent working on: **{subtask_title}**
|
|
184064
184211
|
|
|
184212
|
+
╔═══════════════════════════════════════════════════════════════════════════════╗
|
|
184213
|
+
║ ║
|
|
184214
|
+
║ \uD83D\uDED1 STOP - READ THIS FIRST - BEFORE ANY EDIT OR WRITE \uD83D\uDED1 ║
|
|
184215
|
+
║ ║
|
|
184216
|
+
║ You MUST do these 3 things BEFORE your first Edit/Write call: ║
|
|
184217
|
+
║ ║
|
|
184218
|
+
║ 1️⃣ hivemind_find(query="<your task keywords>", limit=5, expand=true) ║
|
|
184219
|
+
║ → Check if past agents already solved this ║
|
|
184220
|
+
║ → Find gotchas, patterns, warnings ║
|
|
184221
|
+
║ ║
|
|
184222
|
+
║ 2️⃣ skills_list() then skills_use(name="<relevant>") ║
|
|
184223
|
+
║ → testing-patterns, swarm-coordination, system-design ║
|
|
184224
|
+
║ ║
|
|
184225
|
+
║ 3️⃣ swarmmail_send(to=["coordinator"], ...) when blocked ║
|
|
184226
|
+
║ → Don't spin >5min - ASK FOR HELP ║
|
|
184227
|
+
║ ║
|
|
184228
|
+
║ SKIPPING THESE = wasted time repeating solved problems ║
|
|
184229
|
+
║ ║
|
|
184230
|
+
╚═══════════════════════════════════════════════════════════════════════════════╝
|
|
184231
|
+
|
|
184065
184232
|
## [IDENTITY]
|
|
184066
184233
|
Agent: (assigned at spawn)
|
|
184067
184234
|
Cell: {bead_id}
|
|
@@ -22,6 +22,73 @@
|
|
|
22
22
|
]
|
|
23
23
|
}
|
|
24
24
|
],
|
|
25
|
+
"PreToolUse": [
|
|
26
|
+
{
|
|
27
|
+
"matcher": "Edit|Write",
|
|
28
|
+
"hooks": [
|
|
29
|
+
{
|
|
30
|
+
"type": "command",
|
|
31
|
+
"command": "swarm claude pre-edit"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"matcher": "swarm_complete",
|
|
37
|
+
"hooks": [
|
|
38
|
+
{
|
|
39
|
+
"type": "command",
|
|
40
|
+
"command": "swarm claude pre-complete"
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"PostToolUse": [
|
|
46
|
+
{
|
|
47
|
+
"matcher": "hivemind_find|mcp__plugin_swarm_swarm-tools__hivemind_find",
|
|
48
|
+
"hooks": [
|
|
49
|
+
{
|
|
50
|
+
"type": "command",
|
|
51
|
+
"command": "swarm claude track-tool hivemind_find"
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"matcher": "skills_use|Skill",
|
|
57
|
+
"hooks": [
|
|
58
|
+
{
|
|
59
|
+
"type": "command",
|
|
60
|
+
"command": "swarm claude track-tool skills_use"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"matcher": "swarmmail_init|mcp__plugin_swarm_swarm-tools__swarmmail_init",
|
|
66
|
+
"hooks": [
|
|
67
|
+
{
|
|
68
|
+
"type": "command",
|
|
69
|
+
"command": "swarm claude track-tool swarmmail_init"
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"matcher": "hivemind_store|mcp__plugin_swarm_swarm-tools__hivemind_store",
|
|
75
|
+
"hooks": [
|
|
76
|
+
{
|
|
77
|
+
"type": "command",
|
|
78
|
+
"command": "swarm claude track-tool hivemind_store"
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"matcher": "swarm_complete",
|
|
84
|
+
"hooks": [
|
|
85
|
+
{
|
|
86
|
+
"type": "command",
|
|
87
|
+
"command": "swarm claude post-complete"
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
],
|
|
25
92
|
"PreCompact": [
|
|
26
93
|
{
|
|
27
94
|
"matcher": "",
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Release Skill
|
|
2
|
+
|
|
3
|
+
Handles version bumps and releases for the opencode-swarm-plugin monorepo.
|
|
4
|
+
|
|
5
|
+
## Version Touchpoints
|
|
6
|
+
|
|
7
|
+
When bumping versions, ALL of these files must be updated:
|
|
8
|
+
|
|
9
|
+
### opencode-swarm-plugin
|
|
10
|
+
- `packages/opencode-swarm-plugin/package.json` - npm package version
|
|
11
|
+
- `packages/opencode-swarm-plugin/claude-plugin/.claude-plugin/plugin.json` - Claude plugin version
|
|
12
|
+
|
|
13
|
+
### claude-code-swarm-plugin (thin wrapper)
|
|
14
|
+
- `packages/claude-code-swarm-plugin/package.json` - npm package version
|
|
15
|
+
- `packages/claude-code-swarm-plugin/.claude-plugin/plugin.json` - Claude plugin version
|
|
16
|
+
|
|
17
|
+
### Other packages (if applicable)
|
|
18
|
+
- `packages/swarm-evals/package.json`
|
|
19
|
+
- `packages/swarm-mail/package.json`
|
|
20
|
+
- `packages/swarm-dashboard/package.json`
|
|
21
|
+
|
|
22
|
+
## Release Process
|
|
23
|
+
|
|
24
|
+
1. **Create changeset** (for proper changelog generation):
|
|
25
|
+
```bash
|
|
26
|
+
# Interactive (won't work in CI/agent context)
|
|
27
|
+
bun changeset
|
|
28
|
+
|
|
29
|
+
# Manual - create file in .changeset/
|
|
30
|
+
echo '---
|
|
31
|
+
"opencode-swarm-plugin": minor
|
|
32
|
+
"claude-code-swarm-plugin": minor
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
feat: description of changes' > .changeset/my-change.md
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
2. **Version bump** (applies changesets):
|
|
39
|
+
```bash
|
|
40
|
+
bun run ci:version
|
|
41
|
+
```
|
|
42
|
+
This runs `changeset version` and updates package.jsons
|
|
43
|
+
|
|
44
|
+
3. **CRITICAL: Sync plugin.json versions manually**:
|
|
45
|
+
```bash
|
|
46
|
+
# Get version from package.json
|
|
47
|
+
VERSION=$(cat packages/opencode-swarm-plugin/package.json | jq -r '.version')
|
|
48
|
+
|
|
49
|
+
# Update both plugin.json files
|
|
50
|
+
jq ".version = \"$VERSION\"" packages/opencode-swarm-plugin/claude-plugin/.claude-plugin/plugin.json > /tmp/p1.json && mv /tmp/p1.json packages/opencode-swarm-plugin/claude-plugin/.claude-plugin/plugin.json
|
|
51
|
+
|
|
52
|
+
VERSION=$(cat packages/claude-code-swarm-plugin/package.json | jq -r '.version')
|
|
53
|
+
jq ".version = \"$VERSION\"" packages/claude-code-swarm-plugin/.claude-plugin/plugin.json > /tmp/p2.json && mv /tmp/p2.json packages/claude-code-swarm-plugin/.claude-plugin/plugin.json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
4. **Build**:
|
|
57
|
+
```bash
|
|
58
|
+
cd packages/opencode-swarm-plugin && bun run build
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
5. **Publish**:
|
|
62
|
+
```bash
|
|
63
|
+
bun run ci:publish
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
6. **Commit and push**:
|
|
67
|
+
```bash
|
|
68
|
+
git add -A && git commit -m "release: bump versions" && git push
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Quick Version Bump Script
|
|
72
|
+
|
|
73
|
+
Run this to bump all version touchpoints at once:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
#!/bin/bash
|
|
77
|
+
NEW_VERSION=$1
|
|
78
|
+
|
|
79
|
+
if [ -z "$NEW_VERSION" ]; then
|
|
80
|
+
echo "Usage: ./bump-version.sh 0.59.0"
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Main package
|
|
85
|
+
jq ".version = \"$NEW_VERSION\"" packages/opencode-swarm-plugin/package.json > /tmp/pkg.json && mv /tmp/pkg.json packages/opencode-swarm-plugin/package.json
|
|
86
|
+
jq ".version = \"$NEW_VERSION\"" packages/opencode-swarm-plugin/claude-plugin/.claude-plugin/plugin.json > /tmp/plug.json && mv /tmp/plug.json packages/opencode-swarm-plugin/claude-plugin/.claude-plugin/plugin.json
|
|
87
|
+
|
|
88
|
+
# Thin wrapper (claude-code-swarm-plugin)
|
|
89
|
+
jq ".version = \"$NEW_VERSION\"" packages/claude-code-swarm-plugin/package.json > /tmp/pkg.json && mv /tmp/pkg.json packages/claude-code-swarm-plugin/package.json
|
|
90
|
+
jq ".version = \"$NEW_VERSION\"" packages/claude-code-swarm-plugin/.claude-plugin/plugin.json > /tmp/plug.json && mv /tmp/plug.json packages/claude-code-swarm-plugin/.claude-plugin/plugin.json
|
|
91
|
+
|
|
92
|
+
echo "Bumped all packages to $NEW_VERSION"
|
|
93
|
+
git diff --stat
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Gotchas
|
|
97
|
+
|
|
98
|
+
- **plugin.json is NOT auto-bumped by changesets** - must be done manually
|
|
99
|
+
- **Two separate plugins**: `opencode-swarm-plugin` (full) and `claude-code-swarm-plugin` (thin wrapper)
|
|
100
|
+
- **Claude Code marketplace installs from cache** - users may need to uninstall/reinstall for updates
|
|
101
|
+
- **npm publish needs `--access public`** for scoped packages
|