opencode-swarm-plugin 0.12.15 → 0.12.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.beads/issues.jsonl +17 -17
- package/dist/index.js +138 -50
- package/dist/plugin.js +130 -48
- package/package.json +1 -1
- package/src/beads.ts +201 -67
- package/src/index.ts +6 -2
- package/src/storage.ts +14 -2
package/dist/plugin.js
CHANGED
|
@@ -21765,6 +21765,42 @@ var SwarmStatusSchema = exports_external.object({
|
|
|
21765
21765
|
last_update: exports_external.string().datetime({ offset: true })
|
|
21766
21766
|
});
|
|
21767
21767
|
// src/beads.ts
|
|
21768
|
+
var beadsWorkingDirectory = null;
|
|
21769
|
+
function setBeadsWorkingDirectory(directory) {
|
|
21770
|
+
beadsWorkingDirectory = directory;
|
|
21771
|
+
}
|
|
21772
|
+
function getBeadsWorkingDirectory() {
|
|
21773
|
+
return beadsWorkingDirectory || process.cwd();
|
|
21774
|
+
}
|
|
21775
|
+
async function runBdCommand(args) {
|
|
21776
|
+
const cwd = getBeadsWorkingDirectory();
|
|
21777
|
+
const proc = Bun.spawn(["bd", ...args], {
|
|
21778
|
+
cwd,
|
|
21779
|
+
stdout: "pipe",
|
|
21780
|
+
stderr: "pipe"
|
|
21781
|
+
});
|
|
21782
|
+
const [stdout, stderr] = await Promise.all([
|
|
21783
|
+
new Response(proc.stdout).text(),
|
|
21784
|
+
new Response(proc.stderr).text()
|
|
21785
|
+
]);
|
|
21786
|
+
const exitCode = await proc.exited;
|
|
21787
|
+
return { exitCode, stdout, stderr };
|
|
21788
|
+
}
|
|
21789
|
+
async function runGitCommand(args) {
|
|
21790
|
+
const cwd = getBeadsWorkingDirectory();
|
|
21791
|
+
const proc = Bun.spawn(["git", ...args], {
|
|
21792
|
+
cwd,
|
|
21793
|
+
stdout: "pipe",
|
|
21794
|
+
stderr: "pipe"
|
|
21795
|
+
});
|
|
21796
|
+
const [stdout, stderr] = await Promise.all([
|
|
21797
|
+
new Response(proc.stdout).text(),
|
|
21798
|
+
new Response(proc.stderr).text()
|
|
21799
|
+
]);
|
|
21800
|
+
const exitCode = await proc.exited;
|
|
21801
|
+
return { exitCode, stdout, stderr };
|
|
21802
|
+
}
|
|
21803
|
+
|
|
21768
21804
|
class BeadError extends Error {
|
|
21769
21805
|
command;
|
|
21770
21806
|
exitCode;
|
|
@@ -21844,11 +21880,18 @@ var beads_create = tool({
|
|
|
21844
21880
|
async execute(args, ctx) {
|
|
21845
21881
|
const validated = BeadCreateArgsSchema.parse(args);
|
|
21846
21882
|
const cmdParts = buildCreateCommand(validated);
|
|
21847
|
-
const result = await
|
|
21883
|
+
const result = await runBdCommand(cmdParts.slice(1));
|
|
21848
21884
|
if (result.exitCode !== 0) {
|
|
21849
|
-
throw new BeadError(`Failed to create bead: ${result.stderr
|
|
21885
|
+
throw new BeadError(`Failed to create bead: ${result.stderr}`, cmdParts.join(" "), result.exitCode, result.stderr);
|
|
21886
|
+
}
|
|
21887
|
+
const stdout = result.stdout.trim();
|
|
21888
|
+
if (!stdout) {
|
|
21889
|
+
throw new BeadError("bd create returned empty output", cmdParts.join(" "), 0, "Empty stdout");
|
|
21890
|
+
}
|
|
21891
|
+
if (stdout.startsWith("error:") || stdout.startsWith("Error:")) {
|
|
21892
|
+
throw new BeadError(`bd create failed: ${stdout}`, cmdParts.join(" "), 0, stdout);
|
|
21850
21893
|
}
|
|
21851
|
-
const bead = parseBead(
|
|
21894
|
+
const bead = parseBead(stdout);
|
|
21852
21895
|
return JSON.stringify(bead, null, 2);
|
|
21853
21896
|
}
|
|
21854
21897
|
});
|
|
@@ -21873,11 +21916,11 @@ var beads_create_epic = tool({
|
|
|
21873
21916
|
priority: 1,
|
|
21874
21917
|
description: validated.epic_description
|
|
21875
21918
|
});
|
|
21876
|
-
const epicResult = await
|
|
21919
|
+
const epicResult = await runBdCommand(epicCmd.slice(1));
|
|
21877
21920
|
if (epicResult.exitCode !== 0) {
|
|
21878
|
-
throw new BeadError(`Failed to create epic: ${epicResult.stderr
|
|
21921
|
+
throw new BeadError(`Failed to create epic: ${epicResult.stderr}`, epicCmd.join(" "), epicResult.exitCode);
|
|
21879
21922
|
}
|
|
21880
|
-
const epic = parseBead(epicResult.stdout
|
|
21923
|
+
const epic = parseBead(epicResult.stdout);
|
|
21881
21924
|
created.push(epic);
|
|
21882
21925
|
for (const subtask of validated.subtasks) {
|
|
21883
21926
|
const subtaskCmd = buildCreateCommand({
|
|
@@ -21886,11 +21929,11 @@ var beads_create_epic = tool({
|
|
|
21886
21929
|
priority: subtask.priority ?? 2,
|
|
21887
21930
|
parent_id: epic.id
|
|
21888
21931
|
});
|
|
21889
|
-
const subtaskResult = await
|
|
21932
|
+
const subtaskResult = await runBdCommand(subtaskCmd.slice(1));
|
|
21890
21933
|
if (subtaskResult.exitCode !== 0) {
|
|
21891
|
-
throw new BeadError(`Failed to create subtask: ${subtaskResult.stderr
|
|
21934
|
+
throw new BeadError(`Failed to create subtask: ${subtaskResult.stderr}`, subtaskCmd.join(" "), subtaskResult.exitCode);
|
|
21892
21935
|
}
|
|
21893
|
-
const subtaskBead = parseBead(subtaskResult.stdout
|
|
21936
|
+
const subtaskBead = parseBead(subtaskResult.stdout);
|
|
21894
21937
|
created.push(subtaskBead);
|
|
21895
21938
|
}
|
|
21896
21939
|
const result = {
|
|
@@ -21901,30 +21944,49 @@ var beads_create_epic = tool({
|
|
|
21901
21944
|
return JSON.stringify(result, null, 2);
|
|
21902
21945
|
} catch (error45) {
|
|
21903
21946
|
const rollbackCommands = [];
|
|
21947
|
+
const rollbackErrors = [];
|
|
21904
21948
|
for (const bead of created) {
|
|
21905
21949
|
try {
|
|
21906
|
-
const
|
|
21907
|
-
"bd",
|
|
21950
|
+
const closeArgs = [
|
|
21908
21951
|
"close",
|
|
21909
21952
|
bead.id,
|
|
21910
21953
|
"--reason",
|
|
21911
21954
|
"Rollback partial epic",
|
|
21912
21955
|
"--json"
|
|
21913
21956
|
];
|
|
21914
|
-
await
|
|
21915
|
-
|
|
21957
|
+
const rollbackResult = await runBdCommand(closeArgs);
|
|
21958
|
+
if (rollbackResult.exitCode === 0) {
|
|
21959
|
+
rollbackCommands.push(`bd close ${bead.id} --reason "Rollback partial epic"`);
|
|
21960
|
+
} else {
|
|
21961
|
+
rollbackErrors.push(`${bead.id}: exit ${rollbackResult.exitCode} - ${rollbackResult.stderr.trim()}`);
|
|
21962
|
+
}
|
|
21916
21963
|
} catch (rollbackError) {
|
|
21964
|
+
const errMsg = rollbackError instanceof Error ? rollbackError.message : String(rollbackError);
|
|
21917
21965
|
console.error(`Failed to rollback bead ${bead.id}:`, rollbackError);
|
|
21966
|
+
rollbackErrors.push(`${bead.id}: ${errMsg}`);
|
|
21918
21967
|
}
|
|
21919
21968
|
}
|
|
21920
21969
|
const errorMsg = error45 instanceof Error ? error45.message : String(error45);
|
|
21921
|
-
|
|
21970
|
+
let rollbackInfo = "";
|
|
21971
|
+
if (rollbackCommands.length > 0) {
|
|
21972
|
+
rollbackInfo += `
|
|
21922
21973
|
|
|
21923
21974
|
Rolled back ${rollbackCommands.length} bead(s):
|
|
21924
21975
|
${rollbackCommands.join(`
|
|
21925
|
-
`)}
|
|
21976
|
+
`)}`;
|
|
21977
|
+
}
|
|
21978
|
+
if (rollbackErrors.length > 0) {
|
|
21979
|
+
rollbackInfo += `
|
|
21980
|
+
|
|
21981
|
+
Rollback failures (${rollbackErrors.length}):
|
|
21982
|
+
${rollbackErrors.join(`
|
|
21983
|
+
`)}`;
|
|
21984
|
+
}
|
|
21985
|
+
if (!rollbackInfo) {
|
|
21986
|
+
rollbackInfo = `
|
|
21926
21987
|
|
|
21927
21988
|
No beads to rollback.`;
|
|
21989
|
+
}
|
|
21928
21990
|
throw new BeadError(`Epic creation failed: ${errorMsg}${rollbackInfo}`, "beads_create_epic", 1);
|
|
21929
21991
|
}
|
|
21930
21992
|
}
|
|
@@ -21951,11 +22013,11 @@ var beads_query = tool({
|
|
|
21951
22013
|
cmd.push("--type", validated.type);
|
|
21952
22014
|
}
|
|
21953
22015
|
}
|
|
21954
|
-
const result = await
|
|
22016
|
+
const result = await runBdCommand(cmd.slice(1));
|
|
21955
22017
|
if (result.exitCode !== 0) {
|
|
21956
|
-
throw new BeadError(`Failed to query beads: ${result.stderr
|
|
22018
|
+
throw new BeadError(`Failed to query beads: ${result.stderr}`, cmd.join(" "), result.exitCode);
|
|
21957
22019
|
}
|
|
21958
|
-
const beads = parseBeads(result.stdout
|
|
22020
|
+
const beads = parseBeads(result.stdout);
|
|
21959
22021
|
const limited = beads.slice(0, validated.limit);
|
|
21960
22022
|
return JSON.stringify(limited, null, 2);
|
|
21961
22023
|
}
|
|
@@ -21981,11 +22043,11 @@ var beads_update = tool({
|
|
|
21981
22043
|
cmd.push("-p", validated.priority.toString());
|
|
21982
22044
|
}
|
|
21983
22045
|
cmd.push("--json");
|
|
21984
|
-
const result = await
|
|
22046
|
+
const result = await runBdCommand(cmd.slice(1));
|
|
21985
22047
|
if (result.exitCode !== 0) {
|
|
21986
|
-
throw new BeadError(`Failed to update bead: ${result.stderr
|
|
22048
|
+
throw new BeadError(`Failed to update bead: ${result.stderr}`, cmd.join(" "), result.exitCode);
|
|
21987
22049
|
}
|
|
21988
|
-
const bead = parseBead(result.stdout
|
|
22050
|
+
const bead = parseBead(result.stdout);
|
|
21989
22051
|
return JSON.stringify(bead, null, 2);
|
|
21990
22052
|
}
|
|
21991
22053
|
});
|
|
@@ -22005,11 +22067,11 @@ var beads_close = tool({
|
|
|
22005
22067
|
validated.reason,
|
|
22006
22068
|
"--json"
|
|
22007
22069
|
];
|
|
22008
|
-
const result = await
|
|
22070
|
+
const result = await runBdCommand(cmd.slice(1));
|
|
22009
22071
|
if (result.exitCode !== 0) {
|
|
22010
|
-
throw new BeadError(`Failed to close bead: ${result.stderr
|
|
22072
|
+
throw new BeadError(`Failed to close bead: ${result.stderr}`, cmd.join(" "), result.exitCode);
|
|
22011
22073
|
}
|
|
22012
|
-
const bead = parseBead(result.stdout
|
|
22074
|
+
const bead = parseBead(result.stdout);
|
|
22013
22075
|
return `Closed ${bead.id}: ${validated.reason}`;
|
|
22014
22076
|
}
|
|
22015
22077
|
});
|
|
@@ -22019,12 +22081,17 @@ var beads_start = tool({
|
|
|
22019
22081
|
id: tool.schema.string().describe("Bead ID")
|
|
22020
22082
|
},
|
|
22021
22083
|
async execute(args, ctx) {
|
|
22022
|
-
const
|
|
22023
|
-
|
|
22084
|
+
const result = await runBdCommand([
|
|
22085
|
+
"update",
|
|
22086
|
+
args.id,
|
|
22087
|
+
"--status",
|
|
22088
|
+
"in_progress",
|
|
22089
|
+
"--json"
|
|
22090
|
+
]);
|
|
22024
22091
|
if (result.exitCode !== 0) {
|
|
22025
|
-
throw new BeadError(`Failed to start bead: ${result.stderr
|
|
22092
|
+
throw new BeadError(`Failed to start bead: ${result.stderr}`, `bd update ${args.id} --status in_progress --json`, result.exitCode);
|
|
22026
22093
|
}
|
|
22027
|
-
const bead = parseBead(result.stdout
|
|
22094
|
+
const bead = parseBead(result.stdout);
|
|
22028
22095
|
return `Started: ${bead.id}`;
|
|
22029
22096
|
}
|
|
22030
22097
|
});
|
|
@@ -22032,12 +22099,11 @@ var beads_ready = tool({
|
|
|
22032
22099
|
description: "Get the next ready bead (unblocked, highest priority)",
|
|
22033
22100
|
args: {},
|
|
22034
22101
|
async execute(args, ctx) {
|
|
22035
|
-
const
|
|
22036
|
-
const result = await Bun.$`${cmd}`.quiet().nothrow();
|
|
22102
|
+
const result = await runBdCommand(["ready", "--json"]);
|
|
22037
22103
|
if (result.exitCode !== 0) {
|
|
22038
|
-
throw new BeadError(`Failed to get ready beads: ${result.stderr
|
|
22104
|
+
throw new BeadError(`Failed to get ready beads: ${result.stderr}`, "bd ready --json", result.exitCode);
|
|
22039
22105
|
}
|
|
22040
|
-
const beads = parseBeads(result.stdout
|
|
22106
|
+
const beads = parseBeads(result.stdout);
|
|
22041
22107
|
if (beads.length === 0) {
|
|
22042
22108
|
return "No ready beads";
|
|
22043
22109
|
}
|
|
@@ -22054,25 +22120,34 @@ var beads_sync = tool({
|
|
|
22054
22120
|
const autoPull = args.auto_pull ?? true;
|
|
22055
22121
|
const TIMEOUT_MS = 30000;
|
|
22056
22122
|
const withTimeout = async (promise2, timeoutMs, operation) => {
|
|
22057
|
-
|
|
22058
|
-
|
|
22123
|
+
let timeoutId;
|
|
22124
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
22125
|
+
timeoutId = setTimeout(() => reject(new BeadError(`Operation timed out after ${timeoutMs}ms`, operation)), timeoutMs);
|
|
22126
|
+
});
|
|
22127
|
+
try {
|
|
22128
|
+
return await Promise.race([promise2, timeoutPromise]);
|
|
22129
|
+
} finally {
|
|
22130
|
+
if (timeoutId !== undefined) {
|
|
22131
|
+
clearTimeout(timeoutId);
|
|
22132
|
+
}
|
|
22133
|
+
}
|
|
22059
22134
|
};
|
|
22060
22135
|
if (autoPull) {
|
|
22061
|
-
const pullResult = await withTimeout(
|
|
22136
|
+
const pullResult = await withTimeout(runGitCommand(["pull", "--rebase"]), TIMEOUT_MS, "git pull --rebase");
|
|
22062
22137
|
if (pullResult.exitCode !== 0) {
|
|
22063
|
-
throw new BeadError(`Failed to pull: ${pullResult.stderr
|
|
22138
|
+
throw new BeadError(`Failed to pull: ${pullResult.stderr}`, "git pull --rebase", pullResult.exitCode);
|
|
22064
22139
|
}
|
|
22065
22140
|
}
|
|
22066
|
-
const syncResult = await withTimeout(
|
|
22141
|
+
const syncResult = await withTimeout(runBdCommand(["sync"]), TIMEOUT_MS, "bd sync");
|
|
22067
22142
|
if (syncResult.exitCode !== 0) {
|
|
22068
|
-
throw new BeadError(`Failed to sync beads: ${syncResult.stderr
|
|
22143
|
+
throw new BeadError(`Failed to sync beads: ${syncResult.stderr}`, "bd sync", syncResult.exitCode);
|
|
22069
22144
|
}
|
|
22070
|
-
const pushResult = await withTimeout(
|
|
22145
|
+
const pushResult = await withTimeout(runGitCommand(["push"]), TIMEOUT_MS, "git push");
|
|
22071
22146
|
if (pushResult.exitCode !== 0) {
|
|
22072
|
-
throw new BeadError(`Failed to push: ${pushResult.stderr
|
|
22147
|
+
throw new BeadError(`Failed to push: ${pushResult.stderr}`, "git push", pushResult.exitCode);
|
|
22073
22148
|
}
|
|
22074
|
-
const statusResult = await
|
|
22075
|
-
const status = statusResult.stdout.
|
|
22149
|
+
const statusResult = await runGitCommand(["status", "--porcelain"]);
|
|
22150
|
+
const status = statusResult.stdout.trim();
|
|
22076
22151
|
if (status !== "") {
|
|
22077
22152
|
return `Beads synced and pushed, but working directory not clean:
|
|
22078
22153
|
${status}`;
|
|
@@ -22087,11 +22162,11 @@ var beads_link_thread = tool({
|
|
|
22087
22162
|
thread_id: tool.schema.string().describe("Agent Mail thread ID")
|
|
22088
22163
|
},
|
|
22089
22164
|
async execute(args, ctx) {
|
|
22090
|
-
const queryResult = await
|
|
22165
|
+
const queryResult = await runBdCommand(["show", args.bead_id, "--json"]);
|
|
22091
22166
|
if (queryResult.exitCode !== 0) {
|
|
22092
|
-
throw new BeadError(`Failed to get bead: ${queryResult.stderr
|
|
22167
|
+
throw new BeadError(`Failed to get bead: ${queryResult.stderr}`, `bd show ${args.bead_id} --json`, queryResult.exitCode);
|
|
22093
22168
|
}
|
|
22094
|
-
const bead = parseBead(queryResult.stdout
|
|
22169
|
+
const bead = parseBead(queryResult.stdout);
|
|
22095
22170
|
const existingDesc = bead.description || "";
|
|
22096
22171
|
const threadMarker = `[thread:${args.thread_id}]`;
|
|
22097
22172
|
if (existingDesc.includes(threadMarker)) {
|
|
@@ -22100,9 +22175,15 @@ var beads_link_thread = tool({
|
|
|
22100
22175
|
const newDesc = existingDesc ? `${existingDesc}
|
|
22101
22176
|
|
|
22102
22177
|
${threadMarker}` : threadMarker;
|
|
22103
|
-
const updateResult = await
|
|
22178
|
+
const updateResult = await runBdCommand([
|
|
22179
|
+
"update",
|
|
22180
|
+
args.bead_id,
|
|
22181
|
+
"-d",
|
|
22182
|
+
newDesc,
|
|
22183
|
+
"--json"
|
|
22184
|
+
]);
|
|
22104
22185
|
if (updateResult.exitCode !== 0) {
|
|
22105
|
-
throw new BeadError(`Failed to update bead: ${updateResult.stderr
|
|
22186
|
+
throw new BeadError(`Failed to update bead: ${updateResult.stderr}`, `bd update ${args.bead_id} -d ...`, updateResult.exitCode);
|
|
22106
22187
|
}
|
|
22107
22188
|
return `Linked bead ${args.bead_id} to thread ${args.thread_id}`;
|
|
22108
22189
|
}
|
|
@@ -26075,7 +26156,8 @@ class InMemoryMaturityStorage {
|
|
|
26075
26156
|
|
|
26076
26157
|
// src/index.ts
|
|
26077
26158
|
var SwarmPlugin = async (input) => {
|
|
26078
|
-
const {
|
|
26159
|
+
const { $, directory } = input;
|
|
26160
|
+
setBeadsWorkingDirectory(directory);
|
|
26079
26161
|
let activeAgentMailState = null;
|
|
26080
26162
|
async function releaseReservations() {
|
|
26081
26163
|
if (!activeAgentMailState || activeAgentMailState.reservations.length === 0) {
|
package/package.json
CHANGED