opencode-swarm-plugin 0.25.2 → 0.26.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/.turbo/turbo-build.log +3 -3
- package/CHANGELOG.md +48 -0
- package/dist/beads.d.ts +6 -0
- package/dist/beads.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +192 -287
- package/dist/plugin.js +191 -292
- package/dist/rate-limiter.d.ts.map +1 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/swarm-orchestrate.d.ts.map +1 -1
- package/docs/swarm-mail-architecture.md +1 -1
- package/package.json +2 -2
- package/src/beads.integration.test.ts +55 -61
- package/src/beads.ts +239 -410
- package/src/index.ts +1 -15
- package/src/rate-limiter.ts +0 -5
- package/src/storage.ts +0 -9
- package/src/swarm-mail.integration.test.ts +5 -1
- package/src/swarm-orchestrate.ts +24 -14
- package/src/swarm.integration.test.ts +83 -0
- package/src/agent-mail.integration.test.ts +0 -1429
package/dist/index.js
CHANGED
|
@@ -27053,7 +27053,11 @@ echo "Project directory: $1"
|
|
|
27053
27053
|
|
|
27054
27054
|
// src/beads.ts
|
|
27055
27055
|
init_dist();
|
|
27056
|
-
|
|
27056
|
+
import {
|
|
27057
|
+
createBeadsAdapter,
|
|
27058
|
+
FlushManager,
|
|
27059
|
+
getSwarmMail
|
|
27060
|
+
} from "swarm-mail";
|
|
27057
27061
|
|
|
27058
27062
|
// src/schemas/bead.ts
|
|
27059
27063
|
init_zod();
|
|
@@ -27661,20 +27665,6 @@ function setBeadsWorkingDirectory(directory) {
|
|
|
27661
27665
|
function getBeadsWorkingDirectory() {
|
|
27662
27666
|
return beadsWorkingDirectory || process.cwd();
|
|
27663
27667
|
}
|
|
27664
|
-
async function runBdCommand(args) {
|
|
27665
|
-
const cwd = getBeadsWorkingDirectory();
|
|
27666
|
-
const proc = Bun.spawn(["bd", ...args], {
|
|
27667
|
-
cwd,
|
|
27668
|
-
stdout: "pipe",
|
|
27669
|
-
stderr: "pipe"
|
|
27670
|
-
});
|
|
27671
|
-
const [stdout, stderr] = await Promise.all([
|
|
27672
|
-
new Response(proc.stdout).text(),
|
|
27673
|
-
new Response(proc.stderr).text()
|
|
27674
|
-
]);
|
|
27675
|
-
const exitCode = await proc.exited;
|
|
27676
|
-
return { exitCode, stdout, stderr };
|
|
27677
|
-
}
|
|
27678
27668
|
async function runGitCommand(args) {
|
|
27679
27669
|
const cwd = getBeadsWorkingDirectory();
|
|
27680
27670
|
const proc = Bun.spawn(["git", ...args], {
|
|
@@ -27711,54 +27701,33 @@ class BeadValidationError extends Error {
|
|
|
27711
27701
|
this.name = "BeadValidationError";
|
|
27712
27702
|
}
|
|
27713
27703
|
}
|
|
27714
|
-
|
|
27715
|
-
|
|
27716
|
-
if (
|
|
27717
|
-
|
|
27704
|
+
var adapterCache = new Map;
|
|
27705
|
+
async function getBeadsAdapter(projectKey) {
|
|
27706
|
+
if (adapterCache.has(projectKey)) {
|
|
27707
|
+
return adapterCache.get(projectKey);
|
|
27718
27708
|
}
|
|
27719
|
-
|
|
27720
|
-
|
|
27721
|
-
|
|
27722
|
-
|
|
27723
|
-
|
|
27724
|
-
|
|
27725
|
-
if (args.parent_id) {
|
|
27726
|
-
parts.push("--parent", args.parent_id);
|
|
27727
|
-
}
|
|
27728
|
-
if (args.id) {
|
|
27729
|
-
parts.push("--id", args.id);
|
|
27730
|
-
}
|
|
27731
|
-
parts.push("--json");
|
|
27732
|
-
return parts;
|
|
27709
|
+
const swarmMail = await getSwarmMail(projectKey);
|
|
27710
|
+
const db = await swarmMail.getDatabase();
|
|
27711
|
+
const adapter = createBeadsAdapter(db, projectKey);
|
|
27712
|
+
await adapter.runMigrations();
|
|
27713
|
+
adapterCache.set(projectKey, adapter);
|
|
27714
|
+
return adapter;
|
|
27733
27715
|
}
|
|
27734
|
-
function
|
|
27735
|
-
|
|
27736
|
-
|
|
27737
|
-
|
|
27738
|
-
|
|
27739
|
-
|
|
27740
|
-
|
|
27741
|
-
|
|
27742
|
-
|
|
27743
|
-
|
|
27744
|
-
|
|
27745
|
-
|
|
27746
|
-
|
|
27747
|
-
|
|
27748
|
-
|
|
27749
|
-
throw new BeadError(`Failed to parse bead JSON because output is malformed. Try: Check if bd CLI is up to date with 'bd --version' (need v1.0.0+), or inspect output: ${output.slice(0, 100)}`, "parse");
|
|
27750
|
-
}
|
|
27751
|
-
}
|
|
27752
|
-
function parseBeads(output) {
|
|
27753
|
-
try {
|
|
27754
|
-
const parsed = JSON.parse(output);
|
|
27755
|
-
return exports_external.array(BeadSchema).parse(parsed);
|
|
27756
|
-
} catch (error45) {
|
|
27757
|
-
if (error45 instanceof exports_external.ZodError) {
|
|
27758
|
-
throw new BeadValidationError(`Invalid beads data: ${error45.message}`, error45);
|
|
27759
|
-
}
|
|
27760
|
-
throw new BeadError(`Failed to parse beads JSON because output is malformed. Try: Check if bd CLI is up to date with 'bd --version' (need v1.0.0+), or inspect output: ${output.slice(0, 100)}`, "parse");
|
|
27761
|
-
}
|
|
27716
|
+
function formatBeadForOutput(adapterBead) {
|
|
27717
|
+
return {
|
|
27718
|
+
id: adapterBead.id,
|
|
27719
|
+
title: adapterBead.title,
|
|
27720
|
+
description: adapterBead.description || "",
|
|
27721
|
+
status: adapterBead.status,
|
|
27722
|
+
priority: adapterBead.priority,
|
|
27723
|
+
issue_type: adapterBead.type,
|
|
27724
|
+
created_at: new Date(adapterBead.created_at).toISOString(),
|
|
27725
|
+
updated_at: new Date(adapterBead.updated_at).toISOString(),
|
|
27726
|
+
closed_at: adapterBead.closed_at ? new Date(adapterBead.closed_at).toISOString() : undefined,
|
|
27727
|
+
parent_id: adapterBead.parent_id || undefined,
|
|
27728
|
+
dependencies: [],
|
|
27729
|
+
metadata: {}
|
|
27730
|
+
};
|
|
27762
27731
|
}
|
|
27763
27732
|
var beads_create = tool({
|
|
27764
27733
|
description: "Create a new bead with type-safe validation",
|
|
@@ -27771,20 +27740,23 @@ var beads_create = tool({
|
|
|
27771
27740
|
},
|
|
27772
27741
|
async execute(args, ctx) {
|
|
27773
27742
|
const validated = BeadCreateArgsSchema.parse(args);
|
|
27774
|
-
const
|
|
27775
|
-
const
|
|
27776
|
-
|
|
27777
|
-
|
|
27778
|
-
|
|
27779
|
-
|
|
27780
|
-
|
|
27781
|
-
|
|
27782
|
-
|
|
27783
|
-
|
|
27784
|
-
|
|
27743
|
+
const projectKey = getBeadsWorkingDirectory();
|
|
27744
|
+
const adapter = await getBeadsAdapter(projectKey);
|
|
27745
|
+
try {
|
|
27746
|
+
const bead = await adapter.createBead(projectKey, {
|
|
27747
|
+
title: validated.title,
|
|
27748
|
+
type: validated.type || "task",
|
|
27749
|
+
priority: validated.priority ?? 2,
|
|
27750
|
+
description: validated.description,
|
|
27751
|
+
parent_id: validated.parent_id
|
|
27752
|
+
});
|
|
27753
|
+
await adapter.markDirty(projectKey, bead.id);
|
|
27754
|
+
const formatted = formatBeadForOutput(bead);
|
|
27755
|
+
return JSON.stringify(formatted, null, 2);
|
|
27756
|
+
} catch (error45) {
|
|
27757
|
+
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
27758
|
+
throw new BeadError(`Failed to create bead: ${message}`, "beads_create");
|
|
27785
27759
|
}
|
|
27786
|
-
const bead = parseBead(stdout);
|
|
27787
|
-
return JSON.stringify(bead, null, 2);
|
|
27788
27760
|
}
|
|
27789
27761
|
});
|
|
27790
27762
|
var beads_create_epic = tool({
|
|
@@ -27810,44 +27782,32 @@ var beads_create_epic = tool({
|
|
|
27810
27782
|
},
|
|
27811
27783
|
async execute(args, ctx) {
|
|
27812
27784
|
const validated = EpicCreateArgsSchema.parse(args);
|
|
27785
|
+
const projectKey = getBeadsWorkingDirectory();
|
|
27786
|
+
const adapter = await getBeadsAdapter(projectKey);
|
|
27813
27787
|
const created = [];
|
|
27814
27788
|
try {
|
|
27815
|
-
const
|
|
27789
|
+
const epic = await adapter.createBead(projectKey, {
|
|
27816
27790
|
title: validated.epic_title,
|
|
27817
27791
|
type: "epic",
|
|
27818
27792
|
priority: 1,
|
|
27819
|
-
description: validated.epic_description
|
|
27820
|
-
id: validated.epic_id
|
|
27793
|
+
description: validated.epic_description
|
|
27821
27794
|
});
|
|
27822
|
-
|
|
27823
|
-
if (epicResult.exitCode !== 0) {
|
|
27824
|
-
throw new BeadError(`Failed to create epic because bd command failed: ${epicResult.stderr}. Try: Verify beads initialized with 'bd init', check if .beads/ directory is writable, or run 'bd list' to test basic functionality.`, epicCmd.join(" "), epicResult.exitCode);
|
|
27825
|
-
}
|
|
27826
|
-
const epic = parseBead(epicResult.stdout);
|
|
27795
|
+
await adapter.markDirty(projectKey, epic.id);
|
|
27827
27796
|
created.push(epic);
|
|
27828
27797
|
for (const subtask of validated.subtasks) {
|
|
27829
|
-
|
|
27830
|
-
if (validated.epic_id && subtask.id_suffix) {
|
|
27831
|
-
subtaskId = `${validated.epic_id}.${subtask.id_suffix}`;
|
|
27832
|
-
}
|
|
27833
|
-
const subtaskCmd = buildCreateCommand({
|
|
27798
|
+
const subtaskBead = await adapter.createBead(projectKey, {
|
|
27834
27799
|
title: subtask.title,
|
|
27835
27800
|
type: "task",
|
|
27836
27801
|
priority: subtask.priority ?? 2,
|
|
27837
|
-
parent_id: epic.id
|
|
27838
|
-
id: subtaskId
|
|
27802
|
+
parent_id: epic.id
|
|
27839
27803
|
});
|
|
27840
|
-
|
|
27841
|
-
if (subtaskResult.exitCode !== 0) {
|
|
27842
|
-
throw new BeadError(`Failed to create subtask because bd command failed: ${subtaskResult.stderr}. Try: Check if parent epic exists with 'bd show ${epic.id}', verify .beads/issues.jsonl is not corrupted, or check for invalid characters in title.`, subtaskCmd.join(" "), subtaskResult.exitCode);
|
|
27843
|
-
}
|
|
27844
|
-
const subtaskBead = parseBead(subtaskResult.stdout);
|
|
27804
|
+
await adapter.markDirty(projectKey, subtaskBead.id);
|
|
27845
27805
|
created.push(subtaskBead);
|
|
27846
27806
|
}
|
|
27847
27807
|
const result = {
|
|
27848
27808
|
success: true,
|
|
27849
|
-
epic,
|
|
27850
|
-
subtasks: created.slice(1)
|
|
27809
|
+
epic: formatBeadForOutput(epic),
|
|
27810
|
+
subtasks: created.slice(1).map((b) => formatBeadForOutput(b))
|
|
27851
27811
|
};
|
|
27852
27812
|
if (args.project_key) {
|
|
27853
27813
|
try {
|
|
@@ -27872,23 +27832,12 @@ var beads_create_epic = tool({
|
|
|
27872
27832
|
}
|
|
27873
27833
|
return JSON.stringify(result, null, 2);
|
|
27874
27834
|
} catch (error45) {
|
|
27875
|
-
const rollbackCommands = [];
|
|
27876
27835
|
const rollbackErrors = [];
|
|
27877
27836
|
for (const bead of created) {
|
|
27878
27837
|
try {
|
|
27879
|
-
|
|
27880
|
-
"
|
|
27881
|
-
|
|
27882
|
-
"--reason",
|
|
27883
|
-
"Rollback partial epic",
|
|
27884
|
-
"--json"
|
|
27885
|
-
];
|
|
27886
|
-
const rollbackResult = await runBdCommand(closeArgs);
|
|
27887
|
-
if (rollbackResult.exitCode === 0) {
|
|
27888
|
-
rollbackCommands.push(`bd close ${bead.id} --reason "Rollback partial epic"`);
|
|
27889
|
-
} else {
|
|
27890
|
-
rollbackErrors.push(`${bead.id}: exit ${rollbackResult.exitCode} - ${rollbackResult.stderr.trim()}`);
|
|
27891
|
-
}
|
|
27838
|
+
await adapter.deleteBead(projectKey, bead.id, {
|
|
27839
|
+
reason: "Rollback partial epic"
|
|
27840
|
+
});
|
|
27892
27841
|
} catch (rollbackError) {
|
|
27893
27842
|
const errMsg = rollbackError instanceof Error ? rollbackError.message : String(rollbackError);
|
|
27894
27843
|
console.error(`Failed to rollback bead ${bead.id}:`, rollbackError);
|
|
@@ -27896,14 +27845,9 @@ var beads_create_epic = tool({
|
|
|
27896
27845
|
}
|
|
27897
27846
|
}
|
|
27898
27847
|
const errorMsg = error45 instanceof Error ? error45.message : String(error45);
|
|
27899
|
-
let rollbackInfo =
|
|
27900
|
-
if (rollbackCommands.length > 0) {
|
|
27901
|
-
rollbackInfo += `
|
|
27848
|
+
let rollbackInfo = `
|
|
27902
27849
|
|
|
27903
|
-
Rolled back ${
|
|
27904
|
-
${rollbackCommands.join(`
|
|
27905
|
-
`)}`;
|
|
27906
|
-
}
|
|
27850
|
+
Rolled back ${created.length - rollbackErrors.length} bead(s)`;
|
|
27907
27851
|
if (rollbackErrors.length > 0) {
|
|
27908
27852
|
rollbackInfo += `
|
|
27909
27853
|
|
|
@@ -27911,12 +27855,7 @@ Rollback failures (${rollbackErrors.length}):
|
|
|
27911
27855
|
${rollbackErrors.join(`
|
|
27912
27856
|
`)}`;
|
|
27913
27857
|
}
|
|
27914
|
-
|
|
27915
|
-
rollbackInfo = `
|
|
27916
|
-
|
|
27917
|
-
No beads to rollback.`;
|
|
27918
|
-
}
|
|
27919
|
-
throw new BeadError(`Epic creation failed: ${errorMsg}${rollbackInfo}. Try: If rollback failed, manually close beads with 'bd close <id> --reason "Rollback"', check .beads/issues.jsonl for partial state, or re-run beads_create_epic with corrected parameters.`, "beads_create_epic", 1);
|
|
27858
|
+
throw new BeadError(`Epic creation failed: ${errorMsg}${rollbackInfo}`, "beads_create_epic", 1);
|
|
27920
27859
|
}
|
|
27921
27860
|
}
|
|
27922
27861
|
});
|
|
@@ -27930,25 +27869,26 @@ var beads_query = tool({
|
|
|
27930
27869
|
},
|
|
27931
27870
|
async execute(args, ctx) {
|
|
27932
27871
|
const validated = BeadQueryArgsSchema.parse(args);
|
|
27933
|
-
|
|
27934
|
-
|
|
27935
|
-
|
|
27936
|
-
|
|
27937
|
-
|
|
27938
|
-
|
|
27939
|
-
|
|
27940
|
-
}
|
|
27941
|
-
|
|
27942
|
-
|
|
27872
|
+
const projectKey = getBeadsWorkingDirectory();
|
|
27873
|
+
const adapter = await getBeadsAdapter(projectKey);
|
|
27874
|
+
try {
|
|
27875
|
+
let beads;
|
|
27876
|
+
if (validated.ready) {
|
|
27877
|
+
const readyBead = await adapter.getNextReadyBead(projectKey);
|
|
27878
|
+
beads = readyBead ? [readyBead] : [];
|
|
27879
|
+
} else {
|
|
27880
|
+
beads = await adapter.queryBeads(projectKey, {
|
|
27881
|
+
status: validated.status,
|
|
27882
|
+
type: validated.type,
|
|
27883
|
+
limit: validated.limit || 20
|
|
27884
|
+
});
|
|
27943
27885
|
}
|
|
27886
|
+
const formatted = beads.map((b) => formatBeadForOutput(b));
|
|
27887
|
+
return JSON.stringify(formatted, null, 2);
|
|
27888
|
+
} catch (error45) {
|
|
27889
|
+
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
27890
|
+
throw new BeadError(`Failed to query beads: ${message}`, "beads_query");
|
|
27944
27891
|
}
|
|
27945
|
-
const result = await runBdCommand(cmd.slice(1));
|
|
27946
|
-
if (result.exitCode !== 0) {
|
|
27947
|
-
throw new BeadError(`Failed to query beads because bd command failed: ${result.stderr}. Try: Check if beads initialized with 'bd init', verify .beads/ directory exists, or run 'bd --version' to check CLI version.`, cmd.join(" "), result.exitCode);
|
|
27948
|
-
}
|
|
27949
|
-
const beads = parseBeads(result.stdout);
|
|
27950
|
-
const limited = beads.slice(0, validated.limit);
|
|
27951
|
-
return JSON.stringify(limited, null, 2);
|
|
27952
27892
|
}
|
|
27953
27893
|
});
|
|
27954
27894
|
var beads_update = tool({
|
|
@@ -27961,23 +27901,32 @@ var beads_update = tool({
|
|
|
27961
27901
|
},
|
|
27962
27902
|
async execute(args, ctx) {
|
|
27963
27903
|
const validated = BeadUpdateArgsSchema.parse(args);
|
|
27964
|
-
const
|
|
27965
|
-
|
|
27966
|
-
|
|
27967
|
-
|
|
27968
|
-
|
|
27969
|
-
|
|
27970
|
-
|
|
27971
|
-
|
|
27972
|
-
|
|
27973
|
-
|
|
27974
|
-
|
|
27975
|
-
|
|
27976
|
-
|
|
27977
|
-
|
|
27904
|
+
const projectKey = getBeadsWorkingDirectory();
|
|
27905
|
+
const adapter = await getBeadsAdapter(projectKey);
|
|
27906
|
+
try {
|
|
27907
|
+
let bead;
|
|
27908
|
+
if (validated.status) {
|
|
27909
|
+
bead = await adapter.changeBeadStatus(projectKey, validated.id, validated.status);
|
|
27910
|
+
}
|
|
27911
|
+
if (validated.description !== undefined || validated.priority !== undefined) {
|
|
27912
|
+
bead = await adapter.updateBead(projectKey, validated.id, {
|
|
27913
|
+
description: validated.description,
|
|
27914
|
+
priority: validated.priority
|
|
27915
|
+
});
|
|
27916
|
+
} else if (!validated.status) {
|
|
27917
|
+
const existingBead = await adapter.getBead(projectKey, validated.id);
|
|
27918
|
+
if (!existingBead) {
|
|
27919
|
+
throw new BeadError(`Bead not found: ${validated.id}`, "beads_update");
|
|
27920
|
+
}
|
|
27921
|
+
bead = existingBead;
|
|
27922
|
+
}
|
|
27923
|
+
await adapter.markDirty(projectKey, validated.id);
|
|
27924
|
+
const formatted = formatBeadForOutput(bead);
|
|
27925
|
+
return JSON.stringify(formatted, null, 2);
|
|
27926
|
+
} catch (error45) {
|
|
27927
|
+
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
27928
|
+
throw new BeadError(`Failed to update bead: ${message}`, "beads_update");
|
|
27978
27929
|
}
|
|
27979
|
-
const bead = parseBead(result.stdout);
|
|
27980
|
-
return JSON.stringify(bead, null, 2);
|
|
27981
27930
|
}
|
|
27982
27931
|
});
|
|
27983
27932
|
var beads_close = tool({
|
|
@@ -27988,20 +27937,16 @@ var beads_close = tool({
|
|
|
27988
27937
|
},
|
|
27989
27938
|
async execute(args, ctx) {
|
|
27990
27939
|
const validated = BeadCloseArgsSchema.parse(args);
|
|
27991
|
-
const
|
|
27992
|
-
|
|
27993
|
-
|
|
27994
|
-
validated.id,
|
|
27995
|
-
|
|
27996
|
-
validated.reason
|
|
27997
|
-
|
|
27998
|
-
|
|
27999
|
-
|
|
28000
|
-
if (result.exitCode !== 0) {
|
|
28001
|
-
throw new BeadError(`Failed to close bead because bd command failed: ${result.stderr}. Try: Verify bead exists and is not already closed with 'beads_query(status="closed")' or 'bd show ${validated.id}', check if bead ID is correct.`, cmd.join(" "), result.exitCode);
|
|
27940
|
+
const projectKey = getBeadsWorkingDirectory();
|
|
27941
|
+
const adapter = await getBeadsAdapter(projectKey);
|
|
27942
|
+
try {
|
|
27943
|
+
const bead = await adapter.closeBead(projectKey, validated.id, validated.reason);
|
|
27944
|
+
await adapter.markDirty(projectKey, validated.id);
|
|
27945
|
+
return `Closed ${bead.id}: ${validated.reason}`;
|
|
27946
|
+
} catch (error45) {
|
|
27947
|
+
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
27948
|
+
throw new BeadError(`Failed to close bead: ${message}`, "beads_close");
|
|
28002
27949
|
}
|
|
28003
|
-
const bead = parseBead(result.stdout);
|
|
28004
|
-
return `Closed ${bead.id}: ${validated.reason}`;
|
|
28005
27950
|
}
|
|
28006
27951
|
});
|
|
28007
27952
|
var beads_start = tool({
|
|
@@ -28010,34 +27955,35 @@ var beads_start = tool({
|
|
|
28010
27955
|
id: tool.schema.string().describe("Bead ID")
|
|
28011
27956
|
},
|
|
28012
27957
|
async execute(args, ctx) {
|
|
28013
|
-
const
|
|
28014
|
-
|
|
28015
|
-
|
|
28016
|
-
"
|
|
28017
|
-
|
|
28018
|
-
|
|
28019
|
-
|
|
28020
|
-
|
|
28021
|
-
throw new BeadError(`Failed to start bead
|
|
27958
|
+
const projectKey = getBeadsWorkingDirectory();
|
|
27959
|
+
const adapter = await getBeadsAdapter(projectKey);
|
|
27960
|
+
try {
|
|
27961
|
+
const bead = await adapter.changeBeadStatus(projectKey, args.id, "in_progress");
|
|
27962
|
+
await adapter.markDirty(projectKey, args.id);
|
|
27963
|
+
return `Started: ${bead.id}`;
|
|
27964
|
+
} catch (error45) {
|
|
27965
|
+
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
27966
|
+
throw new BeadError(`Failed to start bead: ${message}`, "beads_start");
|
|
28022
27967
|
}
|
|
28023
|
-
const bead = parseBead(result.stdout);
|
|
28024
|
-
return `Started: ${bead.id}`;
|
|
28025
27968
|
}
|
|
28026
27969
|
});
|
|
28027
27970
|
var beads_ready = tool({
|
|
28028
27971
|
description: "Get the next ready bead (unblocked, highest priority)",
|
|
28029
27972
|
args: {},
|
|
28030
27973
|
async execute(args, ctx) {
|
|
28031
|
-
const
|
|
28032
|
-
|
|
28033
|
-
|
|
28034
|
-
|
|
28035
|
-
|
|
28036
|
-
|
|
28037
|
-
|
|
27974
|
+
const projectKey = getBeadsWorkingDirectory();
|
|
27975
|
+
const adapter = await getBeadsAdapter(projectKey);
|
|
27976
|
+
try {
|
|
27977
|
+
const bead = await adapter.getNextReadyBead(projectKey);
|
|
27978
|
+
if (!bead) {
|
|
27979
|
+
return "No ready beads";
|
|
27980
|
+
}
|
|
27981
|
+
const formatted = formatBeadForOutput(bead);
|
|
27982
|
+
return JSON.stringify(formatted, null, 2);
|
|
27983
|
+
} catch (error45) {
|
|
27984
|
+
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
27985
|
+
throw new BeadError(`Failed to get ready beads: ${message}`, "beads_ready");
|
|
28038
27986
|
}
|
|
28039
|
-
const next = beads[0];
|
|
28040
|
-
return JSON.stringify(next, null, 2);
|
|
28041
27987
|
}
|
|
28042
27988
|
});
|
|
28043
27989
|
var beads_sync = tool({
|
|
@@ -28047,6 +27993,8 @@ var beads_sync = tool({
|
|
|
28047
27993
|
},
|
|
28048
27994
|
async execute(args, ctx) {
|
|
28049
27995
|
const autoPull = args.auto_pull ?? true;
|
|
27996
|
+
const projectKey = getBeadsWorkingDirectory();
|
|
27997
|
+
const adapter = await getBeadsAdapter(projectKey);
|
|
28050
27998
|
const TIMEOUT_MS = 30000;
|
|
28051
27999
|
const withTimeout = async (promise2, timeoutMs, operation) => {
|
|
28052
28000
|
let timeoutId;
|
|
@@ -28061,9 +28009,14 @@ var beads_sync = tool({
|
|
|
28061
28009
|
}
|
|
28062
28010
|
}
|
|
28063
28011
|
};
|
|
28064
|
-
const
|
|
28065
|
-
|
|
28066
|
-
|
|
28012
|
+
const flushManager = new FlushManager({
|
|
28013
|
+
adapter,
|
|
28014
|
+
projectKey,
|
|
28015
|
+
outputPath: `${projectKey}/.beads/issues.jsonl`
|
|
28016
|
+
});
|
|
28017
|
+
const flushResult = await withTimeout(flushManager.flush(), TIMEOUT_MS, "flush beads");
|
|
28018
|
+
if (flushResult.beadsExported === 0) {
|
|
28019
|
+
return "No beads to sync";
|
|
28067
28020
|
}
|
|
28068
28021
|
const beadsStatusResult = await runGitCommand([
|
|
28069
28022
|
"status",
|
|
@@ -28074,65 +28027,22 @@ var beads_sync = tool({
|
|
|
28074
28027
|
if (hasChanges) {
|
|
28075
28028
|
const addResult = await runGitCommand(["add", ".beads/"]);
|
|
28076
28029
|
if (addResult.exitCode !== 0) {
|
|
28077
|
-
throw new BeadError(`Failed to stage beads
|
|
28030
|
+
throw new BeadError(`Failed to stage beads: ${addResult.stderr}`, "git add .beads/", addResult.exitCode);
|
|
28078
28031
|
}
|
|
28079
28032
|
const commitResult = await withTimeout(runGitCommand(["commit", "-m", "chore: sync beads"]), TIMEOUT_MS, "git commit");
|
|
28080
28033
|
if (commitResult.exitCode !== 0 && !commitResult.stdout.includes("nothing to commit")) {
|
|
28081
|
-
throw new BeadError(`Failed to commit beads
|
|
28034
|
+
throw new BeadError(`Failed to commit beads: ${commitResult.stderr}`, "git commit", commitResult.exitCode);
|
|
28082
28035
|
}
|
|
28083
28036
|
}
|
|
28084
28037
|
if (autoPull) {
|
|
28085
|
-
const dirtyCheckResult = await runGitCommand([
|
|
28086
|
-
"status",
|
|
28087
|
-
"--porcelain",
|
|
28088
|
-
"--untracked-files=no"
|
|
28089
|
-
]);
|
|
28090
|
-
const hasDirtyFiles = dirtyCheckResult.stdout.trim() !== "";
|
|
28091
|
-
let didStash = false;
|
|
28092
|
-
if (hasDirtyFiles) {
|
|
28093
|
-
console.warn("[beads] Detected unstaged changes, stashing before pull...");
|
|
28094
|
-
const stashResult = await runGitCommand([
|
|
28095
|
-
"stash",
|
|
28096
|
-
"push",
|
|
28097
|
-
"-m",
|
|
28098
|
-
"beads_sync: auto-stash before pull",
|
|
28099
|
-
"--include-untracked"
|
|
28100
|
-
]);
|
|
28101
|
-
if (stashResult.exitCode === 0) {
|
|
28102
|
-
didStash = true;
|
|
28103
|
-
console.warn("[beads] Changes stashed successfully");
|
|
28104
|
-
} else {
|
|
28105
|
-
console.warn(`[beads] Stash failed (${stashResult.stderr}), attempting pull anyway...`);
|
|
28106
|
-
}
|
|
28107
|
-
}
|
|
28108
28038
|
const pullResult = await withTimeout(runGitCommand(["pull", "--rebase"]), TIMEOUT_MS, "git pull --rebase");
|
|
28109
|
-
if (didStash) {
|
|
28110
|
-
console.warn("[beads] Restoring stashed changes...");
|
|
28111
|
-
const unstashResult = await runGitCommand(["stash", "pop"]);
|
|
28112
|
-
if (unstashResult.exitCode !== 0) {
|
|
28113
|
-
console.error(`[beads] WARNING: Failed to restore stashed changes: ${unstashResult.stderr}`);
|
|
28114
|
-
console.error("[beads] Your changes are in 'git stash list' - run 'git stash pop' manually");
|
|
28115
|
-
} else {
|
|
28116
|
-
console.warn("[beads] Stashed changes restored");
|
|
28117
|
-
}
|
|
28118
|
-
}
|
|
28119
28039
|
if (pullResult.exitCode !== 0) {
|
|
28120
|
-
throw new BeadError(`Failed to pull
|
|
28121
|
-
}
|
|
28122
|
-
const importResult = await withTimeout(runBdCommand(["sync", "--import-only"]), TIMEOUT_MS, "bd sync --import-only");
|
|
28123
|
-
if (importResult.exitCode !== 0) {
|
|
28124
|
-
console.warn(`[beads] Import warning: ${importResult.stderr}`);
|
|
28040
|
+
throw new BeadError(`Failed to pull: ${pullResult.stderr}`, "git pull --rebase", pullResult.exitCode);
|
|
28125
28041
|
}
|
|
28126
28042
|
}
|
|
28127
28043
|
const pushResult = await withTimeout(runGitCommand(["push"]), TIMEOUT_MS, "git push");
|
|
28128
28044
|
if (pushResult.exitCode !== 0) {
|
|
28129
|
-
throw new BeadError(`Failed to push
|
|
28130
|
-
}
|
|
28131
|
-
const statusResult = await runGitCommand(["status", "--porcelain"]);
|
|
28132
|
-
const status = statusResult.stdout.trim();
|
|
28133
|
-
if (status !== "") {
|
|
28134
|
-
return `Beads synced and pushed, but working directory not clean:
|
|
28135
|
-
${status}`;
|
|
28045
|
+
throw new BeadError(`Failed to push: ${pushResult.stderr}`, "git push", pushResult.exitCode);
|
|
28136
28046
|
}
|
|
28137
28047
|
return "Beads synced and pushed successfully";
|
|
28138
28048
|
}
|
|
@@ -28144,30 +28054,30 @@ var beads_link_thread = tool({
|
|
|
28144
28054
|
thread_id: tool.schema.string().describe("Agent Mail thread ID")
|
|
28145
28055
|
},
|
|
28146
28056
|
async execute(args, ctx) {
|
|
28147
|
-
const
|
|
28148
|
-
|
|
28149
|
-
|
|
28150
|
-
|
|
28151
|
-
|
|
28152
|
-
|
|
28153
|
-
|
|
28154
|
-
|
|
28155
|
-
|
|
28156
|
-
|
|
28157
|
-
|
|
28057
|
+
const projectKey = getBeadsWorkingDirectory();
|
|
28058
|
+
const adapter = await getBeadsAdapter(projectKey);
|
|
28059
|
+
try {
|
|
28060
|
+
const bead = await adapter.getBead(projectKey, args.bead_id);
|
|
28061
|
+
if (!bead) {
|
|
28062
|
+
throw new BeadError(`Bead not found: ${args.bead_id}`, "beads_link_thread");
|
|
28063
|
+
}
|
|
28064
|
+
const existingDesc = bead.description || "";
|
|
28065
|
+
const threadMarker = `[thread:${args.thread_id}]`;
|
|
28066
|
+
if (existingDesc.includes(threadMarker)) {
|
|
28067
|
+
return `Bead ${args.bead_id} already linked to thread ${args.thread_id}`;
|
|
28068
|
+
}
|
|
28069
|
+
const newDesc = existingDesc ? `${existingDesc}
|
|
28158
28070
|
|
|
28159
28071
|
${threadMarker}` : threadMarker;
|
|
28160
|
-
|
|
28161
|
-
|
|
28162
|
-
|
|
28163
|
-
|
|
28164
|
-
|
|
28165
|
-
|
|
28166
|
-
|
|
28167
|
-
|
|
28168
|
-
throw new BeadError(`Failed to update bead because bd update command failed: ${updateResult.stderr}. Try: Verify bead exists with 'bd show ${args.bead_id}', check for invalid characters in description, or inspect .beads/issues.jsonl for corruption.`, `bd update ${args.bead_id} -d ...`, updateResult.exitCode);
|
|
28072
|
+
await adapter.updateBead(projectKey, args.bead_id, {
|
|
28073
|
+
description: newDesc
|
|
28074
|
+
});
|
|
28075
|
+
await adapter.markDirty(projectKey, args.bead_id);
|
|
28076
|
+
return `Linked bead ${args.bead_id} to thread ${args.thread_id}`;
|
|
28077
|
+
} catch (error45) {
|
|
28078
|
+
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
28079
|
+
throw new BeadError(`Failed to link thread: ${message}`, "beads_link_thread");
|
|
28169
28080
|
}
|
|
28170
|
-
return `Linked bead ${args.bead_id} to thread ${args.thread_id}`;
|
|
28171
28081
|
}
|
|
28172
28082
|
});
|
|
28173
28083
|
var beadsTools = {
|
|
@@ -28639,11 +28549,6 @@ class SqliteRateLimiter {
|
|
|
28639
28549
|
if (result.changes < BATCH_SIZE)
|
|
28640
28550
|
break;
|
|
28641
28551
|
}
|
|
28642
|
-
if (totalDeleted > 0) {
|
|
28643
|
-
console.log("[RateLimiter] Cleanup completed:", {
|
|
28644
|
-
deletedRows: totalDeleted
|
|
28645
|
-
});
|
|
28646
|
-
}
|
|
28647
28552
|
}
|
|
28648
28553
|
async recordRequest(agentName, endpoint) {
|
|
28649
28554
|
const now = Date.now();
|
|
@@ -32306,7 +32211,7 @@ var swarm_complete = tool({
|
|
|
32306
32211
|
error_count: tool.schema.number().optional().describe("Number of errors encountered during task"),
|
|
32307
32212
|
retry_count: tool.schema.number().optional().describe("Number of retry attempts during task")
|
|
32308
32213
|
},
|
|
32309
|
-
async execute(args) {
|
|
32214
|
+
async execute(args, _ctx) {
|
|
32310
32215
|
const epicId = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
|
|
32311
32216
|
try {
|
|
32312
32217
|
const projectKey = args.project_key.replace(/\//g, "-").replace(/\\/g, "-");
|
|
@@ -32452,7 +32357,6 @@ Continuing with completion, but this should be fixed for future subtasks.`;
|
|
|
32452
32357
|
const storeResult = await Bun.$`semantic-memory store ${memoryInfo.information} --metadata ${memoryInfo.metadata}`.quiet().nothrow();
|
|
32453
32358
|
if (storeResult.exitCode === 0) {
|
|
32454
32359
|
memoryStored = true;
|
|
32455
|
-
console.log(`[swarm_complete] Stored learning for ${args.bead_id} in semantic-memory`);
|
|
32456
32360
|
} else {
|
|
32457
32361
|
memoryError = `semantic-memory store failed: ${storeResult.stderr.toString().slice(0, 200)}`;
|
|
32458
32362
|
console.warn(`[swarm_complete] ${memoryError}`);
|
|
@@ -32485,21 +32389,30 @@ Continuing with completion, but this should be fixed for future subtasks.`;
|
|
|
32485
32389
|
`**Memory Capture**: ${memoryStored ? "✓ Stored in semantic-memory" : `✗ ${memoryError || "Failed"}`}`
|
|
32486
32390
|
].filter(Boolean).join(`
|
|
32487
32391
|
`);
|
|
32488
|
-
|
|
32489
|
-
|
|
32490
|
-
|
|
32491
|
-
|
|
32492
|
-
|
|
32493
|
-
|
|
32494
|
-
|
|
32495
|
-
|
|
32496
|
-
|
|
32392
|
+
let messageSent = false;
|
|
32393
|
+
let messageError;
|
|
32394
|
+
try {
|
|
32395
|
+
await sendSwarmMessage2({
|
|
32396
|
+
projectPath: args.project_key,
|
|
32397
|
+
fromAgent: args.agent_name,
|
|
32398
|
+
toAgents: [],
|
|
32399
|
+
subject: `Complete: ${args.bead_id}`,
|
|
32400
|
+
body: completionBody,
|
|
32401
|
+
threadId: epicId2,
|
|
32402
|
+
importance: "normal"
|
|
32403
|
+
});
|
|
32404
|
+
messageSent = true;
|
|
32405
|
+
} catch (error45) {
|
|
32406
|
+
messageError = error45 instanceof Error ? error45.message : String(error45);
|
|
32407
|
+
console.warn(`[swarm_complete] Failed to send completion message: ${messageError}`);
|
|
32408
|
+
}
|
|
32497
32409
|
const response = {
|
|
32498
32410
|
success: true,
|
|
32499
32411
|
bead_id: args.bead_id,
|
|
32500
32412
|
closed: true,
|
|
32501
32413
|
reservations_released: true,
|
|
32502
|
-
message_sent:
|
|
32414
|
+
message_sent: messageSent,
|
|
32415
|
+
message_error: messageError,
|
|
32503
32416
|
agent_registration: {
|
|
32504
32417
|
verified: agentRegistered,
|
|
32505
32418
|
warning: registrationWarning || undefined
|
|
@@ -34644,7 +34557,6 @@ class SemanticMemoryStorage {
|
|
|
34644
34557
|
config;
|
|
34645
34558
|
constructor(config2 = {}) {
|
|
34646
34559
|
this.config = { ...getDefaultStorageConfig(), ...config2 };
|
|
34647
|
-
console.log(`[storage] SemanticMemoryStorage initialized with collections:`, this.config.collections);
|
|
34648
34560
|
}
|
|
34649
34561
|
async checkLowUsageAlert() {
|
|
34650
34562
|
const TEN_MINUTES = 10 * 60 * 1000;
|
|
@@ -34662,7 +34574,6 @@ class SemanticMemoryStorage {
|
|
|
34662
34574
|
if (metadata) {
|
|
34663
34575
|
args.push("--metadata", JSON.stringify(metadata));
|
|
34664
34576
|
}
|
|
34665
|
-
console.log(`[storage] store() -> collection="${collection}"`);
|
|
34666
34577
|
sessionStats.storesCount++;
|
|
34667
34578
|
const result = await execSemanticMemory2(args);
|
|
34668
34579
|
if (result.exitCode !== 0) {
|
|
@@ -34683,7 +34594,6 @@ class SemanticMemoryStorage {
|
|
|
34683
34594
|
if (useFts) {
|
|
34684
34595
|
args.push("--fts");
|
|
34685
34596
|
}
|
|
34686
|
-
console.log(`[storage] find() -> collection="${collection}", query="${query.slice(0, 50)}${query.length > 50 ? "..." : ""}", limit=${limit}, fts=${useFts}`);
|
|
34687
34597
|
sessionStats.queriesCount++;
|
|
34688
34598
|
const result = await execSemanticMemory2(args);
|
|
34689
34599
|
if (result.exitCode !== 0) {
|
|
@@ -34710,7 +34620,6 @@ class SemanticMemoryStorage {
|
|
|
34710
34620
|
}
|
|
34711
34621
|
}
|
|
34712
34622
|
async list(collection) {
|
|
34713
|
-
console.log(`[storage] list() -> collection="${collection}"`);
|
|
34714
34623
|
sessionStats.queriesCount++;
|
|
34715
34624
|
const result = await execSemanticMemory2([
|
|
34716
34625
|
"list",
|
|
@@ -34968,7 +34877,6 @@ var SwarmPlugin = async (input) => {
|
|
|
34968
34877
|
})
|
|
34969
34878
|
});
|
|
34970
34879
|
if (response.ok) {
|
|
34971
|
-
console.log(`[swarm-plugin] Auto-released ${activeAgentMailState.reservations.length} file reservation(s)`);
|
|
34972
34880
|
activeAgentMailState.reservations = [];
|
|
34973
34881
|
}
|
|
34974
34882
|
} catch (error45) {
|
|
@@ -35005,7 +34913,6 @@ var SwarmPlugin = async (input) => {
|
|
|
35005
34913
|
const guardrailResult = guardrailOutput(toolName, output.output);
|
|
35006
34914
|
if (guardrailResult.truncated) {
|
|
35007
34915
|
output.output = guardrailResult.output;
|
|
35008
|
-
console.log(`[swarm-plugin] Guardrail truncated ${toolName}: ${guardrailResult.originalLength} → ${guardrailResult.truncatedLength} chars`);
|
|
35009
34916
|
}
|
|
35010
34917
|
}
|
|
35011
34918
|
if (toolName === "agentmail_init" && output.output) {
|
|
@@ -35029,12 +34936,9 @@ var SwarmPlugin = async (input) => {
|
|
|
35029
34936
|
}
|
|
35030
34937
|
if (toolName === "swarm_complete" && activeAgentMailState) {
|
|
35031
34938
|
await releaseReservations();
|
|
35032
|
-
console.log("[swarm-plugin] Auto-released reservations after swarm:complete");
|
|
35033
34939
|
}
|
|
35034
34940
|
if (toolName === "beads_close") {
|
|
35035
|
-
$`bd sync`.quiet().nothrow()
|
|
35036
|
-
console.log("[swarm-plugin] Auto-synced beads after close");
|
|
35037
|
-
});
|
|
34941
|
+
$`bd sync`.quiet().nothrow();
|
|
35038
34942
|
}
|
|
35039
34943
|
}
|
|
35040
34944
|
};
|
|
@@ -35098,6 +35002,7 @@ export {
|
|
|
35098
35002
|
getSchemaByName,
|
|
35099
35003
|
getMandateStorage,
|
|
35100
35004
|
getBeadsWorkingDirectory,
|
|
35005
|
+
getBeadsAdapter,
|
|
35101
35006
|
getBeadIdFromEvent,
|
|
35102
35007
|
getAgentMailProjectDirectory,
|
|
35103
35008
|
formatZodErrors,
|