opencode-swarm-plugin 0.54.2 → 0.55.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/README.md +0 -12
- package/bin/swarm.ts +3 -15
- package/dist/bin/swarm.js +166 -83
- package/dist/examples/plugin-wrapper-template.ts +18 -3
- package/dist/hooks/atomic-write.d.ts +21 -0
- package/dist/hooks/atomic-write.d.ts.map +1 -0
- package/dist/hooks/constants.d.ts +28 -0
- package/dist/hooks/constants.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +16 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/session-start.d.ts +30 -0
- package/dist/hooks/session-start.d.ts.map +1 -0
- package/dist/hooks/tool-complete.d.ts +54 -0
- package/dist/hooks/tool-complete.d.ts.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +68 -30
- package/dist/output-guardrails.d.ts.map +1 -1
- package/dist/plugin.js +68 -30
- package/dist/swarm-mail.d.ts +34 -0
- package/dist/swarm-mail.d.ts.map +1 -1
- package/dist/swarm-orchestrate.d.ts +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 +1 -30
- package/dist/tool-availability.d.ts +1 -2
- package/dist/tool-availability.d.ts.map +1 -1
- package/examples/plugin-wrapper-template.ts +18 -3
- package/global-skills/swarm-coordination/SKILL.md +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -218,18 +218,6 @@ pip install -e .
|
|
|
218
218
|
cass index # Run periodically to index new sessions
|
|
219
219
|
```
|
|
220
220
|
|
|
221
|
-
### Bug Scanning (UBS)
|
|
222
|
-
|
|
223
|
-
Auto-runs on subtask completion:
|
|
224
|
-
|
|
225
|
-
```bash
|
|
226
|
-
git clone https://github.com/Dicklesworthstone/ultimate_bug_scanner
|
|
227
|
-
cd ultimate_bug_scanner
|
|
228
|
-
pip install -e .
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
Check status: `swarm doctor`
|
|
232
|
-
|
|
233
221
|
---
|
|
234
222
|
|
|
235
223
|
## Core Concepts
|
package/bin/swarm.ts
CHANGED
|
@@ -504,15 +504,6 @@ const DEPENDENCIES: Dependency[] = [
|
|
|
504
504
|
installType: "manual",
|
|
505
505
|
description: "Indexes and searches AI coding agent history for context",
|
|
506
506
|
},
|
|
507
|
-
{
|
|
508
|
-
name: "UBS (Ultimate Bug Scanner)",
|
|
509
|
-
command: "ubs",
|
|
510
|
-
checkArgs: ["--help"],
|
|
511
|
-
required: false,
|
|
512
|
-
install: "https://github.com/Dicklesworthstone/ultimate_bug_scanner",
|
|
513
|
-
installType: "manual",
|
|
514
|
-
description: "AI-powered static analysis for pre-completion bug scanning",
|
|
515
|
-
},
|
|
516
507
|
{
|
|
517
508
|
name: "Ollama",
|
|
518
509
|
command: "ollama",
|
|
@@ -1409,7 +1400,7 @@ skills_list()
|
|
|
1409
1400
|
# Check what MCP servers are available (look for context7, pdf-brain, fetch, etc.)
|
|
1410
1401
|
# Note: No direct MCP listing tool - infer from task context or ask coordinator
|
|
1411
1402
|
|
|
1412
|
-
# Check for CLI tools if relevant (bd, cass,
|
|
1403
|
+
# Check for CLI tools if relevant (bd, cass, ollama)
|
|
1413
1404
|
# Use Bash tool to check: which <tool-name>
|
|
1414
1405
|
\`\`\`
|
|
1415
1406
|
|
|
@@ -1538,7 +1529,6 @@ bash("which <tool>", description="Check if <tool> is available")
|
|
|
1538
1529
|
|
|
1539
1530
|
# Examples:
|
|
1540
1531
|
bash("which cass", description="Check CASS availability")
|
|
1541
|
-
bash("which ubs", description="Check UBS availability")
|
|
1542
1532
|
bash("ollama --version", description="Check Ollama availability")
|
|
1543
1533
|
\`\`\`
|
|
1544
1534
|
|
|
@@ -1610,8 +1600,6 @@ function getFixCommand(dep: Dependency): string | null {
|
|
|
1610
1600
|
return "brew install redis && brew services start redis";
|
|
1611
1601
|
case "CASS (Coding Agent Session Search)":
|
|
1612
1602
|
return "See: https://github.com/Dicklesworthstone/coding_agent_session_search";
|
|
1613
|
-
case "UBS (Ultimate Bug Scanner)":
|
|
1614
|
-
return "See: https://github.com/Dicklesworthstone/ultimate_bug_scanner";
|
|
1615
1603
|
default:
|
|
1616
1604
|
// Fallback to generic install command if available
|
|
1617
1605
|
return dep.installType !== "manual" ? dep.install : null;
|
|
@@ -1683,7 +1671,7 @@ async function doctor(debug = false) {
|
|
|
1683
1671
|
// Check skills
|
|
1684
1672
|
p.log.step("Skills:");
|
|
1685
1673
|
const configDir = join(homedir(), ".config", "opencode");
|
|
1686
|
-
const globalSkillsPath = join(configDir, "
|
|
1674
|
+
const globalSkillsPath = join(configDir, "skill");
|
|
1687
1675
|
const bundledSkillsPath = join(__dirname, "..", "global-skills");
|
|
1688
1676
|
|
|
1689
1677
|
// Global skills directory
|
|
@@ -2743,7 +2731,7 @@ function config() {
|
|
|
2743
2731
|
const plannerAgentPath = join(agentDir, "swarm-planner.md");
|
|
2744
2732
|
const workerAgentPath = join(agentDir, "swarm-worker.md");
|
|
2745
2733
|
const researcherAgentPath = join(agentDir, "swarm-researcher.md");
|
|
2746
|
-
const globalSkillsPath = join(configDir, "
|
|
2734
|
+
const globalSkillsPath = join(configDir, "skill");
|
|
2747
2735
|
|
|
2748
2736
|
console.log(yellow(BANNER));
|
|
2749
2737
|
console.log(dim(" " + TAGLINE + " v" + VERSION));
|
package/dist/bin/swarm.js
CHANGED
|
@@ -61,7 +61,9 @@ __export(exports_dist, {
|
|
|
61
61
|
resolvePartialId: () => resolvePartialId,
|
|
62
62
|
reserveSwarmFiles: () => reserveSwarmFiles,
|
|
63
63
|
replayCellEvents: () => replayCellEvents,
|
|
64
|
+
releaseSwarmFilesForAgent: () => releaseSwarmFilesForAgent,
|
|
64
65
|
releaseSwarmFiles: () => releaseSwarmFiles,
|
|
66
|
+
releaseAllSwarmFiles: () => releaseAllSwarmFiles,
|
|
65
67
|
recoverySuccess: () => recoverySuccess,
|
|
66
68
|
rebuildBeadBlockedCache: () => rebuildBeadBlockedCache,
|
|
67
69
|
rebuildAllBlockedCaches: () => rebuildAllBlockedCaches,
|
|
@@ -15781,12 +15783,15 @@ async function handleFileReservedDrizzle(db2, event) {
|
|
|
15781
15783
|
async function handleFileReleasedDrizzle(db2, event) {
|
|
15782
15784
|
if (event.type !== "file_released")
|
|
15783
15785
|
return;
|
|
15786
|
+
const targetAgent = event.target_agent ?? event.agent_name;
|
|
15784
15787
|
if (event.reservation_ids && event.reservation_ids.length > 0) {
|
|
15785
15788
|
await db2.update(reservationsTable).set({ released_at: event.timestamp }).where(inArray(reservationsTable.id, event.reservation_ids));
|
|
15786
15789
|
} else if (event.paths && event.paths.length > 0) {
|
|
15787
|
-
await db2.update(reservationsTable).set({ released_at: event.timestamp }).where(and3(eq(reservationsTable.project_key, event.project_key), eq(reservationsTable.agent_name,
|
|
15790
|
+
await db2.update(reservationsTable).set({ released_at: event.timestamp }).where(and3(eq(reservationsTable.project_key, event.project_key), eq(reservationsTable.agent_name, targetAgent), inArray(reservationsTable.path_pattern, event.paths), sql`${reservationsTable.released_at} IS NULL`));
|
|
15791
|
+
} else if (event.release_all) {
|
|
15792
|
+
await db2.update(reservationsTable).set({ released_at: event.timestamp }).where(and3(eq(reservationsTable.project_key, event.project_key), sql`${reservationsTable.released_at} IS NULL`));
|
|
15788
15793
|
} else {
|
|
15789
|
-
await db2.update(reservationsTable).set({ released_at: event.timestamp }).where(and3(eq(reservationsTable.project_key, event.project_key), eq(reservationsTable.agent_name,
|
|
15794
|
+
await db2.update(reservationsTable).set({ released_at: event.timestamp }).where(and3(eq(reservationsTable.project_key, event.project_key), eq(reservationsTable.agent_name, targetAgent), sql`${reservationsTable.released_at} IS NULL`));
|
|
15790
15795
|
}
|
|
15791
15796
|
}
|
|
15792
15797
|
async function handleDecompositionGeneratedDrizzle(db2, event) {
|
|
@@ -16190,6 +16195,36 @@ async function releaseSwarmFiles(options2) {
|
|
|
16190
16195
|
releasedAt: Date.now()
|
|
16191
16196
|
};
|
|
16192
16197
|
}
|
|
16198
|
+
async function releaseAllSwarmFiles(options2) {
|
|
16199
|
+
const { projectPath, actorName, dbOverride } = options2;
|
|
16200
|
+
const currentReservations = await getActiveReservations2(projectPath, projectPath, undefined, dbOverride);
|
|
16201
|
+
const releaseCount = currentReservations.length;
|
|
16202
|
+
await appendEvent(createEvent("file_released", {
|
|
16203
|
+
project_key: projectPath,
|
|
16204
|
+
agent_name: actorName,
|
|
16205
|
+
release_all: true,
|
|
16206
|
+
file_count: releaseCount
|
|
16207
|
+
}), projectPath, dbOverride);
|
|
16208
|
+
return {
|
|
16209
|
+
released: releaseCount,
|
|
16210
|
+
releasedAt: Date.now()
|
|
16211
|
+
};
|
|
16212
|
+
}
|
|
16213
|
+
async function releaseSwarmFilesForAgent(options2) {
|
|
16214
|
+
const { projectPath, actorName, targetAgent, dbOverride } = options2;
|
|
16215
|
+
const currentReservations = await getActiveReservations2(projectPath, projectPath, targetAgent, dbOverride);
|
|
16216
|
+
const releaseCount = currentReservations.length;
|
|
16217
|
+
await appendEvent(createEvent("file_released", {
|
|
16218
|
+
project_key: projectPath,
|
|
16219
|
+
agent_name: actorName,
|
|
16220
|
+
target_agent: targetAgent,
|
|
16221
|
+
file_count: releaseCount
|
|
16222
|
+
}), projectPath, dbOverride);
|
|
16223
|
+
return {
|
|
16224
|
+
released: releaseCount,
|
|
16225
|
+
releasedAt: Date.now()
|
|
16226
|
+
};
|
|
16227
|
+
}
|
|
16193
16228
|
async function acknowledgeSwarmMessage(options2) {
|
|
16194
16229
|
const { projectPath, messageId, agentName, dbOverride } = options2;
|
|
16195
16230
|
const timestamp = Date.now();
|
|
@@ -17194,14 +17229,18 @@ async function handleFileReserved(db2, event) {
|
|
|
17194
17229
|
async function handleFileReleased(db2, event) {
|
|
17195
17230
|
if (event.type !== "file_released")
|
|
17196
17231
|
return;
|
|
17232
|
+
const targetAgent = event.target_agent ?? event.agent_name;
|
|
17197
17233
|
if (event.reservation_ids && event.reservation_ids.length > 0) {
|
|
17198
17234
|
await db2.query(`UPDATE reservations SET released_at = $1 WHERE id = ANY($2)`, [event.timestamp, event.reservation_ids]);
|
|
17199
17235
|
} else if (event.paths && event.paths.length > 0) {
|
|
17200
17236
|
await db2.query(`UPDATE reservations SET released_at = $1
|
|
17201
|
-
WHERE project_key = $2 AND agent_name = $3 AND path_pattern = ANY($4) AND released_at IS NULL`, [event.timestamp, event.project_key,
|
|
17237
|
+
WHERE project_key = $2 AND agent_name = $3 AND path_pattern = ANY($4) AND released_at IS NULL`, [event.timestamp, event.project_key, targetAgent, event.paths]);
|
|
17238
|
+
} else if (event.release_all) {
|
|
17239
|
+
await db2.query(`UPDATE reservations SET released_at = $1
|
|
17240
|
+
WHERE project_key = $2 AND released_at IS NULL`, [event.timestamp, event.project_key]);
|
|
17202
17241
|
} else {
|
|
17203
17242
|
await db2.query(`UPDATE reservations SET released_at = $1
|
|
17204
|
-
WHERE project_key = $2 AND agent_name = $3 AND released_at IS NULL`, [event.timestamp, event.project_key,
|
|
17243
|
+
WHERE project_key = $2 AND agent_name = $3 AND released_at IS NULL`, [event.timestamp, event.project_key, targetAgent]);
|
|
17205
17244
|
}
|
|
17206
17245
|
}
|
|
17207
17246
|
async function handleDecompositionGenerated(db2, event) {
|
|
@@ -94024,6 +94063,8 @@ ${stack.split(`
|
|
|
94024
94063
|
FileReleasedEventSchema = BaseEventSchema.extend({
|
|
94025
94064
|
type: exports_external.literal("file_released"),
|
|
94026
94065
|
agent_name: exports_external.string(),
|
|
94066
|
+
target_agent: exports_external.string().optional(),
|
|
94067
|
+
release_all: exports_external.boolean().optional(),
|
|
94027
94068
|
paths: exports_external.array(exports_external.string()).optional(),
|
|
94028
94069
|
reservation_ids: exports_external.array(exports_external.number()).optional(),
|
|
94029
94070
|
lock_holder_ids: exports_external.array(exports_external.string()).optional(),
|
|
@@ -107031,7 +107072,9 @@ ${stack.split(`
|
|
|
107031
107072
|
__export2(exports_swarm_mail, {
|
|
107032
107073
|
sendSwarmMessage: () => sendSwarmMessage,
|
|
107033
107074
|
reserveSwarmFiles: () => reserveSwarmFiles,
|
|
107075
|
+
releaseSwarmFilesForAgent: () => releaseSwarmFilesForAgent,
|
|
107034
107076
|
releaseSwarmFiles: () => releaseSwarmFiles,
|
|
107077
|
+
releaseAllSwarmFiles: () => releaseAllSwarmFiles,
|
|
107035
107078
|
readSwarmMessage: () => readSwarmMessage,
|
|
107036
107079
|
initSwarmAgent: () => initSwarmAgent,
|
|
107037
107080
|
getSwarmInbox: () => getSwarmInbox,
|
|
@@ -108037,7 +108080,9 @@ ${stack.split(`
|
|
|
108037
108080
|
rollbackTo: () => rollbackTo,
|
|
108038
108081
|
reserveSwarmFiles: () => reserveSwarmFiles,
|
|
108039
108082
|
reserveAgentFiles: () => reserveAgentFiles,
|
|
108083
|
+
releaseSwarmFilesForAgent: () => releaseSwarmFilesForAgent,
|
|
108040
108084
|
releaseSwarmFiles: () => releaseSwarmFiles,
|
|
108085
|
+
releaseAllSwarmFiles: () => releaseAllSwarmFiles,
|
|
108041
108086
|
releaseAgentFiles: () => releaseAgentFiles,
|
|
108042
108087
|
readSwarmMessage: () => readSwarmMessage,
|
|
108043
108088
|
readEvents: () => readEvents,
|
|
@@ -116537,7 +116582,9 @@ __export(exports_dist2, {
|
|
|
116537
116582
|
resolvePartialId: () => resolvePartialId2,
|
|
116538
116583
|
reserveSwarmFiles: () => reserveSwarmFiles2,
|
|
116539
116584
|
replayCellEvents: () => replayCellEvents2,
|
|
116585
|
+
releaseSwarmFilesForAgent: () => releaseSwarmFilesForAgent2,
|
|
116540
116586
|
releaseSwarmFiles: () => releaseSwarmFiles2,
|
|
116587
|
+
releaseAllSwarmFiles: () => releaseAllSwarmFiles2,
|
|
116541
116588
|
recoverySuccess: () => recoverySuccess2,
|
|
116542
116589
|
rebuildBeadBlockedCache: () => rebuildBeadBlockedCache2,
|
|
116543
116590
|
rebuildAllBlockedCaches: () => rebuildAllBlockedCaches2,
|
|
@@ -132257,12 +132304,15 @@ async function handleFileReservedDrizzle2(db2, event) {
|
|
|
132257
132304
|
async function handleFileReleasedDrizzle2(db2, event) {
|
|
132258
132305
|
if (event.type !== "file_released")
|
|
132259
132306
|
return;
|
|
132307
|
+
const targetAgent = event.target_agent ?? event.agent_name;
|
|
132260
132308
|
if (event.reservation_ids && event.reservation_ids.length > 0) {
|
|
132261
132309
|
await db2.update(reservationsTable2).set({ released_at: event.timestamp }).where(inArray2(reservationsTable2.id, event.reservation_ids));
|
|
132262
132310
|
} else if (event.paths && event.paths.length > 0) {
|
|
132263
|
-
await db2.update(reservationsTable2).set({ released_at: event.timestamp }).where(and32(eq2(reservationsTable2.project_key, event.project_key), eq2(reservationsTable2.agent_name,
|
|
132311
|
+
await db2.update(reservationsTable2).set({ released_at: event.timestamp }).where(and32(eq2(reservationsTable2.project_key, event.project_key), eq2(reservationsTable2.agent_name, targetAgent), inArray2(reservationsTable2.path_pattern, event.paths), sql2`${reservationsTable2.released_at} IS NULL`));
|
|
132312
|
+
} else if (event.release_all) {
|
|
132313
|
+
await db2.update(reservationsTable2).set({ released_at: event.timestamp }).where(and32(eq2(reservationsTable2.project_key, event.project_key), sql2`${reservationsTable2.released_at} IS NULL`));
|
|
132264
132314
|
} else {
|
|
132265
|
-
await db2.update(reservationsTable2).set({ released_at: event.timestamp }).where(and32(eq2(reservationsTable2.project_key, event.project_key), eq2(reservationsTable2.agent_name,
|
|
132315
|
+
await db2.update(reservationsTable2).set({ released_at: event.timestamp }).where(and32(eq2(reservationsTable2.project_key, event.project_key), eq2(reservationsTable2.agent_name, targetAgent), sql2`${reservationsTable2.released_at} IS NULL`));
|
|
132266
132316
|
}
|
|
132267
132317
|
}
|
|
132268
132318
|
async function handleDecompositionGeneratedDrizzle2(db2, event) {
|
|
@@ -132666,6 +132716,36 @@ async function releaseSwarmFiles2(options2) {
|
|
|
132666
132716
|
releasedAt: Date.now()
|
|
132667
132717
|
};
|
|
132668
132718
|
}
|
|
132719
|
+
async function releaseAllSwarmFiles2(options2) {
|
|
132720
|
+
const { projectPath, actorName, dbOverride } = options2;
|
|
132721
|
+
const currentReservations = await getActiveReservations22(projectPath, projectPath, undefined, dbOverride);
|
|
132722
|
+
const releaseCount = currentReservations.length;
|
|
132723
|
+
await appendEvent3(createEvent2("file_released", {
|
|
132724
|
+
project_key: projectPath,
|
|
132725
|
+
agent_name: actorName,
|
|
132726
|
+
release_all: true,
|
|
132727
|
+
file_count: releaseCount
|
|
132728
|
+
}), projectPath, dbOverride);
|
|
132729
|
+
return {
|
|
132730
|
+
released: releaseCount,
|
|
132731
|
+
releasedAt: Date.now()
|
|
132732
|
+
};
|
|
132733
|
+
}
|
|
132734
|
+
async function releaseSwarmFilesForAgent2(options2) {
|
|
132735
|
+
const { projectPath, actorName, targetAgent, dbOverride } = options2;
|
|
132736
|
+
const currentReservations = await getActiveReservations22(projectPath, projectPath, targetAgent, dbOverride);
|
|
132737
|
+
const releaseCount = currentReservations.length;
|
|
132738
|
+
await appendEvent3(createEvent2("file_released", {
|
|
132739
|
+
project_key: projectPath,
|
|
132740
|
+
agent_name: actorName,
|
|
132741
|
+
target_agent: targetAgent,
|
|
132742
|
+
file_count: releaseCount
|
|
132743
|
+
}), projectPath, dbOverride);
|
|
132744
|
+
return {
|
|
132745
|
+
released: releaseCount,
|
|
132746
|
+
releasedAt: Date.now()
|
|
132747
|
+
};
|
|
132748
|
+
}
|
|
132669
132749
|
async function acknowledgeSwarmMessage2(options2) {
|
|
132670
132750
|
const { projectPath, messageId, agentName, dbOverride } = options2;
|
|
132671
132751
|
const timestamp = Date.now();
|
|
@@ -133670,14 +133750,18 @@ async function handleFileReserved2(db2, event) {
|
|
|
133670
133750
|
async function handleFileReleased2(db2, event) {
|
|
133671
133751
|
if (event.type !== "file_released")
|
|
133672
133752
|
return;
|
|
133753
|
+
const targetAgent = event.target_agent ?? event.agent_name;
|
|
133673
133754
|
if (event.reservation_ids && event.reservation_ids.length > 0) {
|
|
133674
133755
|
await db2.query(`UPDATE reservations SET released_at = $1 WHERE id = ANY($2)`, [event.timestamp, event.reservation_ids]);
|
|
133675
133756
|
} else if (event.paths && event.paths.length > 0) {
|
|
133676
133757
|
await db2.query(`UPDATE reservations SET released_at = $1
|
|
133677
|
-
WHERE project_key = $2 AND agent_name = $3 AND path_pattern = ANY($4) AND released_at IS NULL`, [event.timestamp, event.project_key,
|
|
133758
|
+
WHERE project_key = $2 AND agent_name = $3 AND path_pattern = ANY($4) AND released_at IS NULL`, [event.timestamp, event.project_key, targetAgent, event.paths]);
|
|
133759
|
+
} else if (event.release_all) {
|
|
133760
|
+
await db2.query(`UPDATE reservations SET released_at = $1
|
|
133761
|
+
WHERE project_key = $2 AND released_at IS NULL`, [event.timestamp, event.project_key]);
|
|
133678
133762
|
} else {
|
|
133679
133763
|
await db2.query(`UPDATE reservations SET released_at = $1
|
|
133680
|
-
WHERE project_key = $2 AND agent_name = $3 AND released_at IS NULL`, [event.timestamp, event.project_key,
|
|
133764
|
+
WHERE project_key = $2 AND agent_name = $3 AND released_at IS NULL`, [event.timestamp, event.project_key, targetAgent]);
|
|
133681
133765
|
}
|
|
133682
133766
|
}
|
|
133683
133767
|
async function handleDecompositionGenerated2(db2, event) {
|
|
@@ -210500,6 +210584,8 @@ ${stack.split(`
|
|
|
210500
210584
|
FileReleasedEventSchema2 = BaseEventSchema2.extend({
|
|
210501
210585
|
type: exports_external6.literal("file_released"),
|
|
210502
210586
|
agent_name: exports_external6.string(),
|
|
210587
|
+
target_agent: exports_external6.string().optional(),
|
|
210588
|
+
release_all: exports_external6.boolean().optional(),
|
|
210503
210589
|
paths: exports_external6.array(exports_external6.string()).optional(),
|
|
210504
210590
|
reservation_ids: exports_external6.array(exports_external6.number()).optional(),
|
|
210505
210591
|
lock_holder_ids: exports_external6.array(exports_external6.string()).optional(),
|
|
@@ -223507,7 +223593,9 @@ ${stack.split(`
|
|
|
223507
223593
|
__export5(exports_swarm_mail2, {
|
|
223508
223594
|
sendSwarmMessage: () => sendSwarmMessage2,
|
|
223509
223595
|
reserveSwarmFiles: () => reserveSwarmFiles2,
|
|
223596
|
+
releaseSwarmFilesForAgent: () => releaseSwarmFilesForAgent2,
|
|
223510
223597
|
releaseSwarmFiles: () => releaseSwarmFiles2,
|
|
223598
|
+
releaseAllSwarmFiles: () => releaseAllSwarmFiles2,
|
|
223511
223599
|
readSwarmMessage: () => readSwarmMessage2,
|
|
223512
223600
|
initSwarmAgent: () => initSwarmAgent2,
|
|
223513
223601
|
getSwarmInbox: () => getSwarmInbox2,
|
|
@@ -224513,7 +224601,9 @@ ${stack.split(`
|
|
|
224513
224601
|
rollbackTo: () => rollbackTo2,
|
|
224514
224602
|
reserveSwarmFiles: () => reserveSwarmFiles2,
|
|
224515
224603
|
reserveAgentFiles: () => reserveAgentFiles2,
|
|
224604
|
+
releaseSwarmFilesForAgent: () => releaseSwarmFilesForAgent2,
|
|
224516
224605
|
releaseSwarmFiles: () => releaseSwarmFiles2,
|
|
224606
|
+
releaseAllSwarmFiles: () => releaseAllSwarmFiles2,
|
|
224517
224607
|
releaseAgentFiles: () => releaseAgentFiles2,
|
|
224518
224608
|
readSwarmMessage: () => readSwarmMessage2,
|
|
224519
224609
|
readEvents: () => readEvents3,
|
|
@@ -347573,29 +347663,6 @@ var toolCheckers = {
|
|
|
347573
347663
|
};
|
|
347574
347664
|
}
|
|
347575
347665
|
},
|
|
347576
|
-
ubs: async () => {
|
|
347577
|
-
const exists9 = await commandExists("ubs");
|
|
347578
|
-
if (!exists9) {
|
|
347579
|
-
return {
|
|
347580
|
-
available: false,
|
|
347581
|
-
checkedAt: new Date().toISOString(),
|
|
347582
|
-
error: "ubs command not found"
|
|
347583
|
-
};
|
|
347584
|
-
}
|
|
347585
|
-
try {
|
|
347586
|
-
const result = await Bun.$`ubs doctor`.quiet().nothrow();
|
|
347587
|
-
return {
|
|
347588
|
-
available: result.exitCode === 0,
|
|
347589
|
-
checkedAt: new Date().toISOString()
|
|
347590
|
-
};
|
|
347591
|
-
} catch (e) {
|
|
347592
|
-
return {
|
|
347593
|
-
available: false,
|
|
347594
|
-
checkedAt: new Date().toISOString(),
|
|
347595
|
-
error: String(e)
|
|
347596
|
-
};
|
|
347597
|
-
}
|
|
347598
|
-
},
|
|
347599
347666
|
hive: async () => {
|
|
347600
347667
|
const exists9 = await commandExists("hive");
|
|
347601
347668
|
if (!exists9) {
|
|
@@ -347656,7 +347723,6 @@ var fallbackBehaviors = {
|
|
|
347656
347723
|
"semantic-memory": "Learning data stored in-memory only (lost on session end)",
|
|
347657
347724
|
cass: "Decomposition proceeds without historical context from past sessions",
|
|
347658
347725
|
hivemind: "Unified memory unavailable - learnings stored in-memory only, no session history search",
|
|
347659
|
-
ubs: "Subtask completion skips bug scanning - manual review recommended",
|
|
347660
347726
|
hive: "Swarm cannot track issues - task coordination will be less reliable",
|
|
347661
347727
|
beads: "DEPRECATED: Use hive instead. Swarm cannot track issues - task coordination will be less reliable",
|
|
347662
347728
|
"swarm-mail": "Multi-agent coordination disabled - file conflicts possible if multiple agents active",
|
|
@@ -347689,7 +347755,6 @@ async function checkAllTools() {
|
|
|
347689
347755
|
"semantic-memory",
|
|
347690
347756
|
"cass",
|
|
347691
347757
|
"hivemind",
|
|
347692
|
-
"ubs",
|
|
347693
347758
|
"hive",
|
|
347694
347759
|
"beads",
|
|
347695
347760
|
"swarm-mail",
|
|
@@ -349759,9 +349824,6 @@ var swarm_init = tool2({
|
|
|
349759
349824
|
if (!availability.get("cass")?.status.available) {
|
|
349760
349825
|
degradedFeatures.push("historical context from past sessions");
|
|
349761
349826
|
}
|
|
349762
|
-
if (!availability.get("ubs")?.status.available) {
|
|
349763
|
-
degradedFeatures.push("pre-completion bug scanning");
|
|
349764
|
-
}
|
|
349765
349827
|
if (!availability.get("hivemind")?.status.available) {
|
|
349766
349828
|
degradedFeatures.push("persistent learning (using in-memory fallback)");
|
|
349767
349829
|
}
|
|
@@ -350575,7 +350637,7 @@ ${errorStack.slice(0, 1000)}
|
|
|
350575
350637
|
"",
|
|
350576
350638
|
`### Recovery Actions`,
|
|
350577
350639
|
"1. Check error message for specific issue",
|
|
350578
|
-
"2. Review failed step (
|
|
350640
|
+
"2. Review failed step (typecheck, tests, cell close, etc.)",
|
|
350579
350641
|
"3. Fix underlying issue or use skip flags if appropriate",
|
|
350580
350642
|
"4. Retry swarm_complete after fixing"
|
|
350581
350643
|
].filter(Boolean).join(`
|
|
@@ -351635,7 +351697,6 @@ swarm_complete(
|
|
|
351635
351697
|
\`\`\`
|
|
351636
351698
|
|
|
351637
351699
|
**This automatically:**
|
|
351638
|
-
- Runs UBS bug scan
|
|
351639
351700
|
- Releases file reservations
|
|
351640
351701
|
- Records learning signals
|
|
351641
351702
|
- Notifies coordinator
|
|
@@ -357394,29 +357455,6 @@ var toolCheckers2 = {
|
|
|
357394
357455
|
};
|
|
357395
357456
|
}
|
|
357396
357457
|
},
|
|
357397
|
-
ubs: async () => {
|
|
357398
|
-
const exists9 = await commandExists2("ubs");
|
|
357399
|
-
if (!exists9) {
|
|
357400
|
-
return {
|
|
357401
|
-
available: false,
|
|
357402
|
-
checkedAt: new Date().toISOString(),
|
|
357403
|
-
error: "ubs command not found"
|
|
357404
|
-
};
|
|
357405
|
-
}
|
|
357406
|
-
try {
|
|
357407
|
-
const result = await Bun.$`ubs doctor`.quiet().nothrow();
|
|
357408
|
-
return {
|
|
357409
|
-
available: result.exitCode === 0,
|
|
357410
|
-
checkedAt: new Date().toISOString()
|
|
357411
|
-
};
|
|
357412
|
-
} catch (e) {
|
|
357413
|
-
return {
|
|
357414
|
-
available: false,
|
|
357415
|
-
checkedAt: new Date().toISOString(),
|
|
357416
|
-
error: String(e)
|
|
357417
|
-
};
|
|
357418
|
-
}
|
|
357419
|
-
},
|
|
357420
357458
|
hive: async () => {
|
|
357421
357459
|
const exists9 = await commandExists2("hive");
|
|
357422
357460
|
if (!exists9) {
|
|
@@ -357477,7 +357515,6 @@ var fallbackBehaviors2 = {
|
|
|
357477
357515
|
"semantic-memory": "Learning data stored in-memory only (lost on session end)",
|
|
357478
357516
|
cass: "Decomposition proceeds without historical context from past sessions",
|
|
357479
357517
|
hivemind: "Unified memory unavailable - learnings stored in-memory only, no session history search",
|
|
357480
|
-
ubs: "Subtask completion skips bug scanning - manual review recommended",
|
|
357481
357518
|
hive: "Swarm cannot track issues - task coordination will be less reliable",
|
|
357482
357519
|
beads: "DEPRECATED: Use hive instead. Swarm cannot track issues - task coordination will be less reliable",
|
|
357483
357520
|
"swarm-mail": "Multi-agent coordination disabled - file conflicts possible if multiple agents active",
|
|
@@ -357510,7 +357547,6 @@ async function checkAllTools2() {
|
|
|
357510
357547
|
"semantic-memory",
|
|
357511
357548
|
"cass",
|
|
357512
357549
|
"hivemind",
|
|
357513
|
-
"ubs",
|
|
357514
357550
|
"hive",
|
|
357515
357551
|
"beads",
|
|
357516
357552
|
"swarm-mail",
|
|
@@ -358882,6 +358918,67 @@ var swarmmail_release = tool3({
|
|
|
358882
358918
|
}
|
|
358883
358919
|
}
|
|
358884
358920
|
});
|
|
358921
|
+
var swarmmail_release_all = tool3({
|
|
358922
|
+
description: "Release all file reservations in the project (coordinator override)",
|
|
358923
|
+
args: {},
|
|
358924
|
+
async execute(_args, ctx) {
|
|
358925
|
+
const sessionID = ctx.sessionID || "default";
|
|
358926
|
+
const state = loadSessionState2(sessionID);
|
|
358927
|
+
if (!state) {
|
|
358928
|
+
return JSON.stringify({ error: "Session not initialized. Call swarmmail_init first." }, null, 2);
|
|
358929
|
+
}
|
|
358930
|
+
try {
|
|
358931
|
+
const result = await releaseAllSwarmFiles({
|
|
358932
|
+
projectPath: state.projectKey,
|
|
358933
|
+
actorName: state.agentName
|
|
358934
|
+
});
|
|
358935
|
+
state.reservations = [];
|
|
358936
|
+
saveSessionState2(sessionID, state);
|
|
358937
|
+
return JSON.stringify({
|
|
358938
|
+
released: result.released,
|
|
358939
|
+
released_at: result.releasedAt,
|
|
358940
|
+
release_all: true
|
|
358941
|
+
}, null, 2);
|
|
358942
|
+
} catch (error56) {
|
|
358943
|
+
return JSON.stringify({
|
|
358944
|
+
error: `Failed to release all files: ${error56 instanceof Error ? error56.message : String(error56)}`
|
|
358945
|
+
}, null, 2);
|
|
358946
|
+
}
|
|
358947
|
+
}
|
|
358948
|
+
});
|
|
358949
|
+
var swarmmail_release_agent = tool3({
|
|
358950
|
+
description: "Release all file reservations for a specific agent (coordinator override)",
|
|
358951
|
+
args: {
|
|
358952
|
+
agent_name: tool3.schema.string().describe("Target agent name")
|
|
358953
|
+
},
|
|
358954
|
+
async execute(args5, ctx) {
|
|
358955
|
+
const sessionID = ctx.sessionID || "default";
|
|
358956
|
+
const state = loadSessionState2(sessionID);
|
|
358957
|
+
if (!state) {
|
|
358958
|
+
return JSON.stringify({ error: "Session not initialized. Call swarmmail_init first." }, null, 2);
|
|
358959
|
+
}
|
|
358960
|
+
try {
|
|
358961
|
+
const result = await releaseSwarmFilesForAgent({
|
|
358962
|
+
projectPath: state.projectKey,
|
|
358963
|
+
actorName: state.agentName,
|
|
358964
|
+
targetAgent: args5.agent_name
|
|
358965
|
+
});
|
|
358966
|
+
if (args5.agent_name === state.agentName) {
|
|
358967
|
+
state.reservations = [];
|
|
358968
|
+
saveSessionState2(sessionID, state);
|
|
358969
|
+
}
|
|
358970
|
+
return JSON.stringify({
|
|
358971
|
+
released: result.released,
|
|
358972
|
+
released_at: result.releasedAt,
|
|
358973
|
+
target_agent: args5.agent_name
|
|
358974
|
+
}, null, 2);
|
|
358975
|
+
} catch (error56) {
|
|
358976
|
+
return JSON.stringify({
|
|
358977
|
+
error: `Failed to release files for agent: ${error56 instanceof Error ? error56.message : String(error56)}`
|
|
358978
|
+
}, null, 2);
|
|
358979
|
+
}
|
|
358980
|
+
}
|
|
358981
|
+
});
|
|
358885
358982
|
var swarmmail_ack = tool3({
|
|
358886
358983
|
description: "Acknowledge a message (for messages that require acknowledgement)",
|
|
358887
358984
|
args: {
|
|
@@ -358944,6 +359041,8 @@ var swarmMailTools = {
|
|
|
358944
359041
|
swarmmail_read_message,
|
|
358945
359042
|
swarmmail_reserve,
|
|
358946
359043
|
swarmmail_release,
|
|
359044
|
+
swarmmail_release_all,
|
|
359045
|
+
swarmmail_release_agent,
|
|
358947
359046
|
swarmmail_ack,
|
|
358948
359047
|
swarmmail_health
|
|
358949
359048
|
};
|
|
@@ -362767,9 +362866,6 @@ var swarm_init2 = tool3({
|
|
|
362767
362866
|
if (!availability.get("cass")?.status.available) {
|
|
362768
362867
|
degradedFeatures.push("historical context from past sessions");
|
|
362769
362868
|
}
|
|
362770
|
-
if (!availability.get("ubs")?.status.available) {
|
|
362771
|
-
degradedFeatures.push("pre-completion bug scanning");
|
|
362772
|
-
}
|
|
362773
362869
|
if (!availability.get("hivemind")?.status.available) {
|
|
362774
362870
|
degradedFeatures.push("persistent learning (using in-memory fallback)");
|
|
362775
362871
|
}
|
|
@@ -363583,7 +363679,7 @@ ${errorStack.slice(0, 1000)}
|
|
|
363583
363679
|
"",
|
|
363584
363680
|
`### Recovery Actions`,
|
|
363585
363681
|
"1. Check error message for specific issue",
|
|
363586
|
-
"2. Review failed step (
|
|
363682
|
+
"2. Review failed step (typecheck, tests, cell close, etc.)",
|
|
363587
363683
|
"3. Fix underlying issue or use skip flags if appropriate",
|
|
363588
363684
|
"4. Retry swarm_complete after fixing"
|
|
363589
363685
|
].filter(Boolean).join(`
|
|
@@ -364594,7 +364690,6 @@ swarm_complete(
|
|
|
364594
364690
|
\`\`\`
|
|
364595
364691
|
|
|
364596
364692
|
**This automatically:**
|
|
364597
|
-
- Runs UBS bug scan
|
|
364598
364693
|
- Releases file reservations
|
|
364599
364694
|
- Records learning signals
|
|
364600
364695
|
- Notifies coordinator
|
|
@@ -368266,15 +368361,6 @@ var DEPENDENCIES = [
|
|
|
368266
368361
|
installType: "manual",
|
|
368267
368362
|
description: "Indexes and searches AI coding agent history for context"
|
|
368268
368363
|
},
|
|
368269
|
-
{
|
|
368270
|
-
name: "UBS (Ultimate Bug Scanner)",
|
|
368271
|
-
command: "ubs",
|
|
368272
|
-
checkArgs: ["--help"],
|
|
368273
|
-
required: false,
|
|
368274
|
-
install: "https://github.com/Dicklesworthstone/ultimate_bug_scanner",
|
|
368275
|
-
installType: "manual",
|
|
368276
|
-
description: "AI-powered static analysis for pre-completion bug scanning"
|
|
368277
|
-
},
|
|
368278
368364
|
{
|
|
368279
368365
|
name: "Ollama",
|
|
368280
368366
|
command: "ollama",
|
|
@@ -368986,7 +369072,7 @@ skills_list()
|
|
|
368986
369072
|
# Check what MCP servers are available (look for context7, pdf-brain, fetch, etc.)
|
|
368987
369073
|
# Note: No direct MCP listing tool - infer from task context or ask coordinator
|
|
368988
369074
|
|
|
368989
|
-
# Check for CLI tools if relevant (bd, cass,
|
|
369075
|
+
# Check for CLI tools if relevant (bd, cass, ollama)
|
|
368990
369076
|
# Use Bash tool to check: which <tool-name>
|
|
368991
369077
|
\`\`\`
|
|
368992
369078
|
|
|
@@ -369115,7 +369201,6 @@ bash("which <tool>", description="Check if <tool> is available")
|
|
|
369115
369201
|
|
|
369116
369202
|
# Examples:
|
|
369117
369203
|
bash("which cass", description="Check CASS availability")
|
|
369118
|
-
bash("which ubs", description="Check UBS availability")
|
|
369119
369204
|
bash("ollama --version", description="Check Ollama availability")
|
|
369120
369205
|
\`\`\`
|
|
369121
369206
|
|
|
@@ -369178,8 +369263,6 @@ function getFixCommand(dep) {
|
|
|
369178
369263
|
return "brew install redis && brew services start redis";
|
|
369179
369264
|
case "CASS (Coding Agent Session Search)":
|
|
369180
369265
|
return "See: https://github.com/Dicklesworthstone/coding_agent_session_search";
|
|
369181
|
-
case "UBS (Ultimate Bug Scanner)":
|
|
369182
|
-
return "See: https://github.com/Dicklesworthstone/ultimate_bug_scanner";
|
|
369183
369266
|
default:
|
|
369184
369267
|
return dep.installType !== "manual" ? dep.install : null;
|
|
369185
369268
|
}
|
|
@@ -369236,7 +369319,7 @@ async function doctor(debug = false) {
|
|
|
369236
369319
|
const optionalMissing = optional4.filter((r) => !r.available);
|
|
369237
369320
|
p4.log.step("Skills:");
|
|
369238
369321
|
const configDir = join57(homedir16(), ".config", "opencode");
|
|
369239
|
-
const globalSkillsPath = join57(configDir, "
|
|
369322
|
+
const globalSkillsPath = join57(configDir, "skill");
|
|
369240
369323
|
const bundledSkillsPath = join57(__dirname2, "..", "global-skills");
|
|
369241
369324
|
if (existsSync37(globalSkillsPath)) {
|
|
369242
369325
|
try {
|
|
@@ -370073,7 +370156,7 @@ function config8() {
|
|
|
370073
370156
|
const plannerAgentPath = join57(agentDir, "swarm-planner.md");
|
|
370074
370157
|
const workerAgentPath = join57(agentDir, "swarm-worker.md");
|
|
370075
370158
|
const researcherAgentPath = join57(agentDir, "swarm-researcher.md");
|
|
370076
|
-
const globalSkillsPath = join57(configDir, "
|
|
370159
|
+
const globalSkillsPath = join57(configDir, "skill");
|
|
370077
370160
|
console.log(yellow3(BANNER));
|
|
370078
370161
|
console.log(dim4(" " + TAGLINE + " v" + VERSION6));
|
|
370079
370162
|
console.log();
|
|
@@ -981,6 +981,20 @@ const swarmmail_release = tool({
|
|
|
981
981
|
execute: (args, ctx) => execTool("swarmmail_release", args, ctx),
|
|
982
982
|
});
|
|
983
983
|
|
|
984
|
+
const swarmmail_release_all = tool({
|
|
985
|
+
description: "Release all file reservations in the project (coordinator override)",
|
|
986
|
+
args: {},
|
|
987
|
+
execute: (args, ctx) => execTool("swarmmail_release_all", args, ctx),
|
|
988
|
+
});
|
|
989
|
+
|
|
990
|
+
const swarmmail_release_agent = tool({
|
|
991
|
+
description: "Release all file reservations for a specific agent (coordinator override)",
|
|
992
|
+
args: {
|
|
993
|
+
agent_name: tool.schema.string().describe("Target agent name"),
|
|
994
|
+
},
|
|
995
|
+
execute: (args, ctx) => execTool("swarmmail_release_agent", args, ctx),
|
|
996
|
+
});
|
|
997
|
+
|
|
984
998
|
const swarmmail_ack = tool({
|
|
985
999
|
description: "Acknowledge a message",
|
|
986
1000
|
args: {
|
|
@@ -1176,7 +1190,7 @@ const swarm_progress = tool({
|
|
|
1176
1190
|
|
|
1177
1191
|
const swarm_complete = tool({
|
|
1178
1192
|
description:
|
|
1179
|
-
"Mark subtask complete with Verification Gate. Runs
|
|
1193
|
+
"Mark subtask complete with Verification Gate. Runs typecheck and tests before allowing completion.",
|
|
1180
1194
|
args: {
|
|
1181
1195
|
project_key: tool.schema.string().describe("Project key"),
|
|
1182
1196
|
agent_name: tool.schema.string().describe("Agent name"),
|
|
@@ -1187,11 +1201,10 @@ const swarm_complete = tool({
|
|
|
1187
1201
|
.array(tool.schema.string())
|
|
1188
1202
|
.optional()
|
|
1189
1203
|
.describe("Files modified - will be verified"),
|
|
1190
|
-
skip_ubs_scan: tool.schema.boolean().optional().describe("Skip UBS scan"),
|
|
1191
1204
|
skip_verification: tool.schema
|
|
1192
1205
|
.boolean()
|
|
1193
1206
|
.optional()
|
|
1194
|
-
.describe("Skip ALL verification (
|
|
1207
|
+
.describe("Skip ALL verification (typecheck, tests)"),
|
|
1195
1208
|
skip_review: tool.schema
|
|
1196
1209
|
.boolean()
|
|
1197
1210
|
.optional()
|
|
@@ -2832,6 +2845,8 @@ const SwarmPlugin: Plugin = async (
|
|
|
2832
2845
|
swarmmail_read_message,
|
|
2833
2846
|
swarmmail_reserve,
|
|
2834
2847
|
swarmmail_release,
|
|
2848
|
+
swarmmail_release_all,
|
|
2849
|
+
swarmmail_release_agent,
|
|
2835
2850
|
swarmmail_ack,
|
|
2836
2851
|
swarmmail_health,
|
|
2837
2852
|
// Structured
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface AtomicWriteOptions {
|
|
2
|
+
append?: boolean;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Writes content to a file atomically using a temp file + rename pattern.
|
|
6
|
+
*
|
|
7
|
+
* @param path - Target file path
|
|
8
|
+
* @param content - Content to write
|
|
9
|
+
* @param options - Write options (append mode)
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Basic write
|
|
14
|
+
* await writeFileAtomic("output.txt", "Hello, World!");
|
|
15
|
+
*
|
|
16
|
+
* // Append mode
|
|
17
|
+
* await writeFileAtomic("log.txt", "New entry\n", { append: true });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function writeFileAtomic(path: string, content: string, options?: AtomicWriteOptions): Promise<void>;
|
|
21
|
+
//# sourceMappingURL=atomic-write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-write.d.ts","sourceRoot":"","sources":["../../src/hooks/atomic-write.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|