opencode-swarm-plugin 0.25.2 → 0.25.3

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/dist/plugin.js CHANGED
@@ -27053,7 +27053,11 @@ echo "Project directory: $1"
27053
27053
 
27054
27054
  // src/beads.ts
27055
27055
  init_dist();
27056
- init_zod();
27056
+ import {
27057
+ createBeadsAdapter,
27058
+ FlushManager,
27059
+ getSwarmMail
27060
+ } from "swarm-mail";
27057
27061
 
27058
27062
  // src/schemas/bead.ts
27059
27063
  init_zod();
@@ -27598,20 +27602,6 @@ function setBeadsWorkingDirectory(directory) {
27598
27602
  function getBeadsWorkingDirectory() {
27599
27603
  return beadsWorkingDirectory || process.cwd();
27600
27604
  }
27601
- async function runBdCommand(args) {
27602
- const cwd = getBeadsWorkingDirectory();
27603
- const proc = Bun.spawn(["bd", ...args], {
27604
- cwd,
27605
- stdout: "pipe",
27606
- stderr: "pipe"
27607
- });
27608
- const [stdout, stderr] = await Promise.all([
27609
- new Response(proc.stdout).text(),
27610
- new Response(proc.stderr).text()
27611
- ]);
27612
- const exitCode = await proc.exited;
27613
- return { exitCode, stdout, stderr };
27614
- }
27615
27605
  async function runGitCommand(args) {
27616
27606
  const cwd = getBeadsWorkingDirectory();
27617
27607
  const proc = Bun.spawn(["git", ...args], {
@@ -27639,63 +27629,33 @@ class BeadError extends Error {
27639
27629
  this.name = "BeadError";
27640
27630
  }
27641
27631
  }
27642
-
27643
- class BeadValidationError extends Error {
27644
- zodError;
27645
- constructor(message, zodError) {
27646
- super(message);
27647
- this.zodError = zodError;
27648
- this.name = "BeadValidationError";
27649
- }
27650
- }
27651
- function buildCreateCommand(args) {
27652
- const parts = ["bd", "create", args.title];
27653
- if (args.type && args.type !== "task") {
27654
- parts.push("-t", args.type);
27655
- }
27656
- if (args.priority !== undefined && args.priority !== 2) {
27657
- parts.push("-p", args.priority.toString());
27658
- }
27659
- if (args.description) {
27660
- parts.push("-d", args.description);
27661
- }
27662
- if (args.parent_id) {
27663
- parts.push("--parent", args.parent_id);
27664
- }
27665
- if (args.id) {
27666
- parts.push("--id", args.id);
27667
- }
27668
- parts.push("--json");
27669
- return parts;
27670
- }
27671
- function parseBead(output) {
27672
- try {
27673
- const parsed = JSON.parse(output);
27674
- const data = Array.isArray(parsed) ? parsed[0] : parsed;
27675
- if (!data) {
27676
- throw new BeadError("No bead data in response. The bd CLI may not be installed or returned unexpected output. Try: Run 'bd --version' to verify installation, or check if .beads/ directory exists in project.", "parse");
27677
- }
27678
- return BeadSchema.parse(data);
27679
- } catch (error45) {
27680
- if (error45 instanceof exports_external.ZodError) {
27681
- throw new BeadValidationError(`Invalid bead data: ${error45.message}`, error45);
27682
- }
27683
- if (error45 instanceof BeadError) {
27684
- throw error45;
27685
- }
27686
- 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");
27632
+ var adapterCache = new Map;
27633
+ async function getBeadsAdapter(projectKey) {
27634
+ if (adapterCache.has(projectKey)) {
27635
+ return adapterCache.get(projectKey);
27687
27636
  }
27637
+ const swarmMail = await getSwarmMail(projectKey);
27638
+ const db = await swarmMail.getDatabase();
27639
+ const adapter = createBeadsAdapter(db, projectKey);
27640
+ await adapter.runMigrations();
27641
+ adapterCache.set(projectKey, adapter);
27642
+ return adapter;
27688
27643
  }
27689
- function parseBeads(output) {
27690
- try {
27691
- const parsed = JSON.parse(output);
27692
- return exports_external.array(BeadSchema).parse(parsed);
27693
- } catch (error45) {
27694
- if (error45 instanceof exports_external.ZodError) {
27695
- throw new BeadValidationError(`Invalid beads data: ${error45.message}`, error45);
27696
- }
27697
- 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");
27698
- }
27644
+ function formatBeadForOutput(adapterBead) {
27645
+ return {
27646
+ id: adapterBead.id,
27647
+ title: adapterBead.title,
27648
+ description: adapterBead.description || "",
27649
+ status: adapterBead.status,
27650
+ priority: adapterBead.priority,
27651
+ issue_type: adapterBead.type,
27652
+ created_at: new Date(adapterBead.created_at).toISOString(),
27653
+ updated_at: new Date(adapterBead.updated_at).toISOString(),
27654
+ closed_at: adapterBead.closed_at ? new Date(adapterBead.closed_at).toISOString() : undefined,
27655
+ parent_id: adapterBead.parent_id || undefined,
27656
+ dependencies: [],
27657
+ metadata: {}
27658
+ };
27699
27659
  }
27700
27660
  var beads_create = tool({
27701
27661
  description: "Create a new bead with type-safe validation",
@@ -27708,20 +27668,23 @@ var beads_create = tool({
27708
27668
  },
27709
27669
  async execute(args, ctx) {
27710
27670
  const validated = BeadCreateArgsSchema.parse(args);
27711
- const cmdParts = buildCreateCommand(validated);
27712
- const result = await runBdCommand(cmdParts.slice(1));
27713
- if (result.exitCode !== 0) {
27714
- throw new BeadError(`Failed to create bead because bd command exited with code ${result.exitCode}. Error: ${result.stderr}. Try: Check if beads initialized with 'bd init' in project root, or verify .beads/ directory exists.`, cmdParts.join(" "), result.exitCode, result.stderr);
27715
- }
27716
- const stdout = result.stdout.trim();
27717
- if (!stdout) {
27718
- throw new BeadError("bd create returned empty output because command produced no response. Try: Check if bd is properly installed with 'bd --version', or run 'bd list' to test basic functionality.", cmdParts.join(" "), 0, "Empty stdout");
27719
- }
27720
- if (stdout.startsWith("error:") || stdout.startsWith("Error:")) {
27721
- throw new BeadError(`bd create failed because command returned error in stdout: ${stdout}. Try: Check error message above, verify beads initialized with 'bd init', or check .beads/issues.jsonl for corruption.`, cmdParts.join(" "), 0, stdout);
27671
+ const projectKey = getBeadsWorkingDirectory();
27672
+ const adapter = await getBeadsAdapter(projectKey);
27673
+ try {
27674
+ const bead = await adapter.createBead(projectKey, {
27675
+ title: validated.title,
27676
+ type: validated.type || "task",
27677
+ priority: validated.priority ?? 2,
27678
+ description: validated.description,
27679
+ parent_id: validated.parent_id
27680
+ });
27681
+ await adapter.markDirty(projectKey, bead.id);
27682
+ const formatted = formatBeadForOutput(bead);
27683
+ return JSON.stringify(formatted, null, 2);
27684
+ } catch (error45) {
27685
+ const message = error45 instanceof Error ? error45.message : String(error45);
27686
+ throw new BeadError(`Failed to create bead: ${message}`, "beads_create");
27722
27687
  }
27723
- const bead = parseBead(stdout);
27724
- return JSON.stringify(bead, null, 2);
27725
27688
  }
27726
27689
  });
27727
27690
  var beads_create_epic = tool({
@@ -27747,44 +27710,32 @@ var beads_create_epic = tool({
27747
27710
  },
27748
27711
  async execute(args, ctx) {
27749
27712
  const validated = EpicCreateArgsSchema.parse(args);
27713
+ const projectKey = getBeadsWorkingDirectory();
27714
+ const adapter = await getBeadsAdapter(projectKey);
27750
27715
  const created = [];
27751
27716
  try {
27752
- const epicCmd = buildCreateCommand({
27717
+ const epic = await adapter.createBead(projectKey, {
27753
27718
  title: validated.epic_title,
27754
27719
  type: "epic",
27755
27720
  priority: 1,
27756
- description: validated.epic_description,
27757
- id: validated.epic_id
27721
+ description: validated.epic_description
27758
27722
  });
27759
- const epicResult = await runBdCommand(epicCmd.slice(1));
27760
- if (epicResult.exitCode !== 0) {
27761
- 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);
27762
- }
27763
- const epic = parseBead(epicResult.stdout);
27723
+ await adapter.markDirty(projectKey, epic.id);
27764
27724
  created.push(epic);
27765
27725
  for (const subtask of validated.subtasks) {
27766
- let subtaskId;
27767
- if (validated.epic_id && subtask.id_suffix) {
27768
- subtaskId = `${validated.epic_id}.${subtask.id_suffix}`;
27769
- }
27770
- const subtaskCmd = buildCreateCommand({
27726
+ const subtaskBead = await adapter.createBead(projectKey, {
27771
27727
  title: subtask.title,
27772
27728
  type: "task",
27773
27729
  priority: subtask.priority ?? 2,
27774
- parent_id: epic.id,
27775
- id: subtaskId
27730
+ parent_id: epic.id
27776
27731
  });
27777
- const subtaskResult = await runBdCommand(subtaskCmd.slice(1));
27778
- if (subtaskResult.exitCode !== 0) {
27779
- 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);
27780
- }
27781
- const subtaskBead = parseBead(subtaskResult.stdout);
27732
+ await adapter.markDirty(projectKey, subtaskBead.id);
27782
27733
  created.push(subtaskBead);
27783
27734
  }
27784
27735
  const result = {
27785
27736
  success: true,
27786
- epic,
27787
- subtasks: created.slice(1)
27737
+ epic: formatBeadForOutput(epic),
27738
+ subtasks: created.slice(1).map((b) => formatBeadForOutput(b))
27788
27739
  };
27789
27740
  if (args.project_key) {
27790
27741
  try {
@@ -27809,23 +27760,12 @@ var beads_create_epic = tool({
27809
27760
  }
27810
27761
  return JSON.stringify(result, null, 2);
27811
27762
  } catch (error45) {
27812
- const rollbackCommands = [];
27813
27763
  const rollbackErrors = [];
27814
27764
  for (const bead of created) {
27815
27765
  try {
27816
- const closeArgs = [
27817
- "close",
27818
- bead.id,
27819
- "--reason",
27820
- "Rollback partial epic",
27821
- "--json"
27822
- ];
27823
- const rollbackResult = await runBdCommand(closeArgs);
27824
- if (rollbackResult.exitCode === 0) {
27825
- rollbackCommands.push(`bd close ${bead.id} --reason "Rollback partial epic"`);
27826
- } else {
27827
- rollbackErrors.push(`${bead.id}: exit ${rollbackResult.exitCode} - ${rollbackResult.stderr.trim()}`);
27828
- }
27766
+ await adapter.deleteBead(projectKey, bead.id, {
27767
+ reason: "Rollback partial epic"
27768
+ });
27829
27769
  } catch (rollbackError) {
27830
27770
  const errMsg = rollbackError instanceof Error ? rollbackError.message : String(rollbackError);
27831
27771
  console.error(`Failed to rollback bead ${bead.id}:`, rollbackError);
@@ -27833,14 +27773,9 @@ var beads_create_epic = tool({
27833
27773
  }
27834
27774
  }
27835
27775
  const errorMsg = error45 instanceof Error ? error45.message : String(error45);
27836
- let rollbackInfo = "";
27837
- if (rollbackCommands.length > 0) {
27838
- rollbackInfo += `
27776
+ let rollbackInfo = `
27839
27777
 
27840
- Rolled back ${rollbackCommands.length} bead(s):
27841
- ${rollbackCommands.join(`
27842
- `)}`;
27843
- }
27778
+ Rolled back ${created.length - rollbackErrors.length} bead(s)`;
27844
27779
  if (rollbackErrors.length > 0) {
27845
27780
  rollbackInfo += `
27846
27781
 
@@ -27848,12 +27783,7 @@ Rollback failures (${rollbackErrors.length}):
27848
27783
  ${rollbackErrors.join(`
27849
27784
  `)}`;
27850
27785
  }
27851
- if (!rollbackInfo) {
27852
- rollbackInfo = `
27853
-
27854
- No beads to rollback.`;
27855
- }
27856
- 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);
27786
+ throw new BeadError(`Epic creation failed: ${errorMsg}${rollbackInfo}`, "beads_create_epic", 1);
27857
27787
  }
27858
27788
  }
27859
27789
  });
@@ -27867,25 +27797,26 @@ var beads_query = tool({
27867
27797
  },
27868
27798
  async execute(args, ctx) {
27869
27799
  const validated = BeadQueryArgsSchema.parse(args);
27870
- let cmd;
27871
- if (validated.ready) {
27872
- cmd = ["bd", "ready", "--json"];
27873
- } else {
27874
- cmd = ["bd", "list", "--json"];
27875
- if (validated.status) {
27876
- cmd.push("--status", validated.status);
27877
- }
27878
- if (validated.type) {
27879
- cmd.push("--type", validated.type);
27800
+ const projectKey = getBeadsWorkingDirectory();
27801
+ const adapter = await getBeadsAdapter(projectKey);
27802
+ try {
27803
+ let beads;
27804
+ if (validated.ready) {
27805
+ const readyBead = await adapter.getNextReadyBead(projectKey);
27806
+ beads = readyBead ? [readyBead] : [];
27807
+ } else {
27808
+ beads = await adapter.queryBeads(projectKey, {
27809
+ status: validated.status,
27810
+ type: validated.type,
27811
+ limit: validated.limit || 20
27812
+ });
27880
27813
  }
27814
+ const formatted = beads.map((b) => formatBeadForOutput(b));
27815
+ return JSON.stringify(formatted, null, 2);
27816
+ } catch (error45) {
27817
+ const message = error45 instanceof Error ? error45.message : String(error45);
27818
+ throw new BeadError(`Failed to query beads: ${message}`, "beads_query");
27881
27819
  }
27882
- const result = await runBdCommand(cmd.slice(1));
27883
- if (result.exitCode !== 0) {
27884
- 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);
27885
- }
27886
- const beads = parseBeads(result.stdout);
27887
- const limited = beads.slice(0, validated.limit);
27888
- return JSON.stringify(limited, null, 2);
27889
27820
  }
27890
27821
  });
27891
27822
  var beads_update = tool({
@@ -27898,23 +27829,32 @@ var beads_update = tool({
27898
27829
  },
27899
27830
  async execute(args, ctx) {
27900
27831
  const validated = BeadUpdateArgsSchema.parse(args);
27901
- const cmd = ["bd", "update", validated.id];
27902
- if (validated.status) {
27903
- cmd.push("--status", validated.status);
27904
- }
27905
- if (validated.description) {
27906
- cmd.push("-d", validated.description);
27907
- }
27908
- if (validated.priority !== undefined) {
27909
- cmd.push("-p", validated.priority.toString());
27910
- }
27911
- cmd.push("--json");
27912
- const result = await runBdCommand(cmd.slice(1));
27913
- if (result.exitCode !== 0) {
27914
- throw new BeadError(`Failed to update bead because bd command failed: ${result.stderr}. Try: Verify bead exists with 'bd show ${validated.id}', check for invalid status values, or inspect .beads/issues.jsonl for corruption.`, cmd.join(" "), result.exitCode);
27832
+ const projectKey = getBeadsWorkingDirectory();
27833
+ const adapter = await getBeadsAdapter(projectKey);
27834
+ try {
27835
+ let bead;
27836
+ if (validated.status) {
27837
+ bead = await adapter.changeBeadStatus(projectKey, validated.id, validated.status);
27838
+ }
27839
+ if (validated.description !== undefined || validated.priority !== undefined) {
27840
+ bead = await adapter.updateBead(projectKey, validated.id, {
27841
+ description: validated.description,
27842
+ priority: validated.priority
27843
+ });
27844
+ } else if (!validated.status) {
27845
+ const existingBead = await adapter.getBead(projectKey, validated.id);
27846
+ if (!existingBead) {
27847
+ throw new BeadError(`Bead not found: ${validated.id}`, "beads_update");
27848
+ }
27849
+ bead = existingBead;
27850
+ }
27851
+ await adapter.markDirty(projectKey, validated.id);
27852
+ const formatted = formatBeadForOutput(bead);
27853
+ return JSON.stringify(formatted, null, 2);
27854
+ } catch (error45) {
27855
+ const message = error45 instanceof Error ? error45.message : String(error45);
27856
+ throw new BeadError(`Failed to update bead: ${message}`, "beads_update");
27915
27857
  }
27916
- const bead = parseBead(result.stdout);
27917
- return JSON.stringify(bead, null, 2);
27918
27858
  }
27919
27859
  });
27920
27860
  var beads_close = tool({
@@ -27925,20 +27865,16 @@ var beads_close = tool({
27925
27865
  },
27926
27866
  async execute(args, ctx) {
27927
27867
  const validated = BeadCloseArgsSchema.parse(args);
27928
- const cmd = [
27929
- "bd",
27930
- "close",
27931
- validated.id,
27932
- "--reason",
27933
- validated.reason,
27934
- "--json"
27935
- ];
27936
- const result = await runBdCommand(cmd.slice(1));
27937
- if (result.exitCode !== 0) {
27938
- 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);
27868
+ const projectKey = getBeadsWorkingDirectory();
27869
+ const adapter = await getBeadsAdapter(projectKey);
27870
+ try {
27871
+ const bead = await adapter.closeBead(projectKey, validated.id, validated.reason);
27872
+ await adapter.markDirty(projectKey, validated.id);
27873
+ return `Closed ${bead.id}: ${validated.reason}`;
27874
+ } catch (error45) {
27875
+ const message = error45 instanceof Error ? error45.message : String(error45);
27876
+ throw new BeadError(`Failed to close bead: ${message}`, "beads_close");
27939
27877
  }
27940
- const bead = parseBead(result.stdout);
27941
- return `Closed ${bead.id}: ${validated.reason}`;
27942
27878
  }
27943
27879
  });
27944
27880
  var beads_start = tool({
@@ -27947,34 +27883,35 @@ var beads_start = tool({
27947
27883
  id: tool.schema.string().describe("Bead ID")
27948
27884
  },
27949
27885
  async execute(args, ctx) {
27950
- const result = await runBdCommand([
27951
- "update",
27952
- args.id,
27953
- "--status",
27954
- "in_progress",
27955
- "--json"
27956
- ]);
27957
- if (result.exitCode !== 0) {
27958
- throw new BeadError(`Failed to start bead because bd update command failed: ${result.stderr}. Try: Verify bead exists with 'bd show ${args.id}', check if already in_progress with 'beads_query(status="in_progress")', or use beads_update directly.`, `bd update ${args.id} --status in_progress --json`, result.exitCode);
27886
+ const projectKey = getBeadsWorkingDirectory();
27887
+ const adapter = await getBeadsAdapter(projectKey);
27888
+ try {
27889
+ const bead = await adapter.changeBeadStatus(projectKey, args.id, "in_progress");
27890
+ await adapter.markDirty(projectKey, args.id);
27891
+ return `Started: ${bead.id}`;
27892
+ } catch (error45) {
27893
+ const message = error45 instanceof Error ? error45.message : String(error45);
27894
+ throw new BeadError(`Failed to start bead: ${message}`, "beads_start");
27959
27895
  }
27960
- const bead = parseBead(result.stdout);
27961
- return `Started: ${bead.id}`;
27962
27896
  }
27963
27897
  });
27964
27898
  var beads_ready = tool({
27965
27899
  description: "Get the next ready bead (unblocked, highest priority)",
27966
27900
  args: {},
27967
27901
  async execute(args, ctx) {
27968
- const result = await runBdCommand(["ready", "--json"]);
27969
- if (result.exitCode !== 0) {
27970
- throw new BeadError(`Failed to get ready beads because bd ready command failed: ${result.stderr}. Try: Check if beads initialized with 'bd init', verify .beads/ directory is readable, or run 'bd list --json' to test basic query.`, "bd ready --json", result.exitCode);
27971
- }
27972
- const beads = parseBeads(result.stdout);
27973
- if (beads.length === 0) {
27974
- return "No ready beads";
27902
+ const projectKey = getBeadsWorkingDirectory();
27903
+ const adapter = await getBeadsAdapter(projectKey);
27904
+ try {
27905
+ const bead = await adapter.getNextReadyBead(projectKey);
27906
+ if (!bead) {
27907
+ return "No ready beads";
27908
+ }
27909
+ const formatted = formatBeadForOutput(bead);
27910
+ return JSON.stringify(formatted, null, 2);
27911
+ } catch (error45) {
27912
+ const message = error45 instanceof Error ? error45.message : String(error45);
27913
+ throw new BeadError(`Failed to get ready beads: ${message}`, "beads_ready");
27975
27914
  }
27976
- const next = beads[0];
27977
- return JSON.stringify(next, null, 2);
27978
27915
  }
27979
27916
  });
27980
27917
  var beads_sync = tool({
@@ -27984,6 +27921,8 @@ var beads_sync = tool({
27984
27921
  },
27985
27922
  async execute(args, ctx) {
27986
27923
  const autoPull = args.auto_pull ?? true;
27924
+ const projectKey = getBeadsWorkingDirectory();
27925
+ const adapter = await getBeadsAdapter(projectKey);
27987
27926
  const TIMEOUT_MS = 30000;
27988
27927
  const withTimeout = async (promise2, timeoutMs, operation) => {
27989
27928
  let timeoutId;
@@ -27998,9 +27937,14 @@ var beads_sync = tool({
27998
27937
  }
27999
27938
  }
28000
27939
  };
28001
- const flushResult = await withTimeout(runBdCommand(["sync", "--flush-only"]), TIMEOUT_MS, "bd sync --flush-only");
28002
- if (flushResult.exitCode !== 0) {
28003
- throw new BeadError(`Failed to flush beads because bd sync failed: ${flushResult.stderr}. Try: Check if .beads/ directory is writable, verify no corrupted JSONL files, or run 'bd list' to test basic beads functionality.`, "bd sync --flush-only", flushResult.exitCode);
27940
+ const flushManager = new FlushManager({
27941
+ adapter,
27942
+ projectKey,
27943
+ outputPath: `${projectKey}/.beads/issues.jsonl`
27944
+ });
27945
+ const flushResult = await withTimeout(flushManager.flush(), TIMEOUT_MS, "flush beads");
27946
+ if (flushResult.beadsExported === 0) {
27947
+ return "No beads to sync";
28004
27948
  }
28005
27949
  const beadsStatusResult = await runGitCommand([
28006
27950
  "status",
@@ -28011,65 +27955,22 @@ var beads_sync = tool({
28011
27955
  if (hasChanges) {
28012
27956
  const addResult = await runGitCommand(["add", ".beads/"]);
28013
27957
  if (addResult.exitCode !== 0) {
28014
- throw new BeadError(`Failed to stage beads because git add failed: ${addResult.stderr}. Try: Check if .beads/ directory exists, verify git is initialized with 'git status', or check for .gitignore patterns blocking .beads/.`, "git add .beads/", addResult.exitCode);
27958
+ throw new BeadError(`Failed to stage beads: ${addResult.stderr}`, "git add .beads/", addResult.exitCode);
28015
27959
  }
28016
27960
  const commitResult = await withTimeout(runGitCommand(["commit", "-m", "chore: sync beads"]), TIMEOUT_MS, "git commit");
28017
27961
  if (commitResult.exitCode !== 0 && !commitResult.stdout.includes("nothing to commit")) {
28018
- throw new BeadError(`Failed to commit beads because git commit failed: ${commitResult.stderr}. Try: Check git config (user.name, user.email) with 'git config --list', verify working tree is clean, or check for pre-commit hooks blocking commit.`, "git commit", commitResult.exitCode);
27962
+ throw new BeadError(`Failed to commit beads: ${commitResult.stderr}`, "git commit", commitResult.exitCode);
28019
27963
  }
28020
27964
  }
28021
27965
  if (autoPull) {
28022
- const dirtyCheckResult = await runGitCommand([
28023
- "status",
28024
- "--porcelain",
28025
- "--untracked-files=no"
28026
- ]);
28027
- const hasDirtyFiles = dirtyCheckResult.stdout.trim() !== "";
28028
- let didStash = false;
28029
- if (hasDirtyFiles) {
28030
- console.warn("[beads] Detected unstaged changes, stashing before pull...");
28031
- const stashResult = await runGitCommand([
28032
- "stash",
28033
- "push",
28034
- "-m",
28035
- "beads_sync: auto-stash before pull",
28036
- "--include-untracked"
28037
- ]);
28038
- if (stashResult.exitCode === 0) {
28039
- didStash = true;
28040
- console.warn("[beads] Changes stashed successfully");
28041
- } else {
28042
- console.warn(`[beads] Stash failed (${stashResult.stderr}), attempting pull anyway...`);
28043
- }
28044
- }
28045
27966
  const pullResult = await withTimeout(runGitCommand(["pull", "--rebase"]), TIMEOUT_MS, "git pull --rebase");
28046
- if (didStash) {
28047
- console.warn("[beads] Restoring stashed changes...");
28048
- const unstashResult = await runGitCommand(["stash", "pop"]);
28049
- if (unstashResult.exitCode !== 0) {
28050
- console.error(`[beads] WARNING: Failed to restore stashed changes: ${unstashResult.stderr}`);
28051
- console.error("[beads] Your changes are in 'git stash list' - run 'git stash pop' manually");
28052
- } else {
28053
- console.warn("[beads] Stashed changes restored");
28054
- }
28055
- }
28056
27967
  if (pullResult.exitCode !== 0) {
28057
- throw new BeadError(`Failed to pull because git pull --rebase failed: ${pullResult.stderr}. Try: Resolve merge conflicts manually with 'git status', check if remote is accessible with 'git remote -v', or use skip_verification to bypass automatic pull.`, "git pull --rebase", pullResult.exitCode);
28058
- }
28059
- const importResult = await withTimeout(runBdCommand(["sync", "--import-only"]), TIMEOUT_MS, "bd sync --import-only");
28060
- if (importResult.exitCode !== 0) {
28061
- console.warn(`[beads] Import warning: ${importResult.stderr}`);
27968
+ throw new BeadError(`Failed to pull: ${pullResult.stderr}`, "git pull --rebase", pullResult.exitCode);
28062
27969
  }
28063
27970
  }
28064
27971
  const pushResult = await withTimeout(runGitCommand(["push"]), TIMEOUT_MS, "git push");
28065
27972
  if (pushResult.exitCode !== 0) {
28066
- throw new BeadError(`Failed to push because git push failed: ${pushResult.stderr}. Try: Check if remote branch is up to date with 'git pull --rebase', verify push permissions, check remote URL with 'git remote -v', or force push with 'git push --force-with-lease' if safe.`, "git push", pushResult.exitCode);
28067
- }
28068
- const statusResult = await runGitCommand(["status", "--porcelain"]);
28069
- const status = statusResult.stdout.trim();
28070
- if (status !== "") {
28071
- return `Beads synced and pushed, but working directory not clean:
28072
- ${status}`;
27973
+ throw new BeadError(`Failed to push: ${pushResult.stderr}`, "git push", pushResult.exitCode);
28073
27974
  }
28074
27975
  return "Beads synced and pushed successfully";
28075
27976
  }
@@ -28081,30 +27982,30 @@ var beads_link_thread = tool({
28081
27982
  thread_id: tool.schema.string().describe("Agent Mail thread ID")
28082
27983
  },
28083
27984
  async execute(args, ctx) {
28084
- const queryResult = await runBdCommand(["show", args.bead_id, "--json"]);
28085
- if (queryResult.exitCode !== 0) {
28086
- throw new BeadError(`Failed to get bead because bd show command failed: ${queryResult.stderr}. Try: Verify bead ID is correct with 'beads_query()', check if bead exists with 'bd list --json', or check .beads/issues.jsonl for valid entries.`, `bd show ${args.bead_id} --json`, queryResult.exitCode);
28087
- }
28088
- const bead = parseBead(queryResult.stdout);
28089
- const existingDesc = bead.description || "";
28090
- const threadMarker = `[thread:${args.thread_id}]`;
28091
- if (existingDesc.includes(threadMarker)) {
28092
- return `Bead ${args.bead_id} already linked to thread ${args.thread_id}`;
28093
- }
28094
- const newDesc = existingDesc ? `${existingDesc}
27985
+ const projectKey = getBeadsWorkingDirectory();
27986
+ const adapter = await getBeadsAdapter(projectKey);
27987
+ try {
27988
+ const bead = await adapter.getBead(projectKey, args.bead_id);
27989
+ if (!bead) {
27990
+ throw new BeadError(`Bead not found: ${args.bead_id}`, "beads_link_thread");
27991
+ }
27992
+ const existingDesc = bead.description || "";
27993
+ const threadMarker = `[thread:${args.thread_id}]`;
27994
+ if (existingDesc.includes(threadMarker)) {
27995
+ return `Bead ${args.bead_id} already linked to thread ${args.thread_id}`;
27996
+ }
27997
+ const newDesc = existingDesc ? `${existingDesc}
28095
27998
 
28096
27999
  ${threadMarker}` : threadMarker;
28097
- const updateResult = await runBdCommand([
28098
- "update",
28099
- args.bead_id,
28100
- "-d",
28101
- newDesc,
28102
- "--json"
28103
- ]);
28104
- if (updateResult.exitCode !== 0) {
28105
- 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);
28000
+ await adapter.updateBead(projectKey, args.bead_id, {
28001
+ description: newDesc
28002
+ });
28003
+ await adapter.markDirty(projectKey, args.bead_id);
28004
+ return `Linked bead ${args.bead_id} to thread ${args.thread_id}`;
28005
+ } catch (error45) {
28006
+ const message = error45 instanceof Error ? error45.message : String(error45);
28007
+ throw new BeadError(`Failed to link thread: ${message}`, "beads_link_thread");
28106
28008
  }
28107
- return `Linked bead ${args.bead_id} to thread ${args.thread_id}`;
28108
28009
  }
28109
28010
  });
28110
28011
  var beadsTools = {
@@ -28550,11 +28451,6 @@ class SqliteRateLimiter {
28550
28451
  if (result.changes < BATCH_SIZE)
28551
28452
  break;
28552
28453
  }
28553
- if (totalDeleted > 0) {
28554
- console.log("[RateLimiter] Cleanup completed:", {
28555
- deletedRows: totalDeleted
28556
- });
28557
- }
28558
28454
  }
28559
28455
  async recordRequest(agentName, endpoint) {
28560
28456
  const now = Date.now();
@@ -32097,7 +31993,7 @@ var swarm_complete = tool({
32097
31993
  error_count: tool.schema.number().optional().describe("Number of errors encountered during task"),
32098
31994
  retry_count: tool.schema.number().optional().describe("Number of retry attempts during task")
32099
31995
  },
32100
- async execute(args) {
31996
+ async execute(args, _ctx) {
32101
31997
  const epicId = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
32102
31998
  try {
32103
31999
  const projectKey = args.project_key.replace(/\//g, "-").replace(/\\/g, "-");
@@ -32243,7 +32139,6 @@ Continuing with completion, but this should be fixed for future subtasks.`;
32243
32139
  const storeResult = await Bun.$`semantic-memory store ${memoryInfo.information} --metadata ${memoryInfo.metadata}`.quiet().nothrow();
32244
32140
  if (storeResult.exitCode === 0) {
32245
32141
  memoryStored = true;
32246
- console.log(`[swarm_complete] Stored learning for ${args.bead_id} in semantic-memory`);
32247
32142
  } else {
32248
32143
  memoryError = `semantic-memory store failed: ${storeResult.stderr.toString().slice(0, 200)}`;
32249
32144
  console.warn(`[swarm_complete] ${memoryError}`);
@@ -32276,21 +32171,30 @@ Continuing with completion, but this should be fixed for future subtasks.`;
32276
32171
  `**Memory Capture**: ${memoryStored ? "✓ Stored in semantic-memory" : `✗ ${memoryError || "Failed"}`}`
32277
32172
  ].filter(Boolean).join(`
32278
32173
  `);
32279
- await sendSwarmMessage2({
32280
- projectPath: args.project_key,
32281
- fromAgent: args.agent_name,
32282
- toAgents: [],
32283
- subject: `Complete: ${args.bead_id}`,
32284
- body: completionBody,
32285
- threadId: epicId2,
32286
- importance: "normal"
32287
- });
32174
+ let messageSent = false;
32175
+ let messageError;
32176
+ try {
32177
+ await sendSwarmMessage2({
32178
+ projectPath: args.project_key,
32179
+ fromAgent: args.agent_name,
32180
+ toAgents: [],
32181
+ subject: `Complete: ${args.bead_id}`,
32182
+ body: completionBody,
32183
+ threadId: epicId2,
32184
+ importance: "normal"
32185
+ });
32186
+ messageSent = true;
32187
+ } catch (error45) {
32188
+ messageError = error45 instanceof Error ? error45.message : String(error45);
32189
+ console.warn(`[swarm_complete] Failed to send completion message: ${messageError}`);
32190
+ }
32288
32191
  const response = {
32289
32192
  success: true,
32290
32193
  bead_id: args.bead_id,
32291
32194
  closed: true,
32292
32195
  reservations_released: true,
32293
- message_sent: true,
32196
+ message_sent: messageSent,
32197
+ message_error: messageError,
32294
32198
  agent_registration: {
32295
32199
  verified: agentRegistered,
32296
32200
  warning: registrationWarning || undefined
@@ -34372,7 +34276,6 @@ var SwarmPlugin = async (input) => {
34372
34276
  })
34373
34277
  });
34374
34278
  if (response.ok) {
34375
- console.log(`[swarm-plugin] Auto-released ${activeAgentMailState.reservations.length} file reservation(s)`);
34376
34279
  activeAgentMailState.reservations = [];
34377
34280
  }
34378
34281
  } catch (error45) {
@@ -34409,7 +34312,6 @@ var SwarmPlugin = async (input) => {
34409
34312
  const guardrailResult = guardrailOutput(toolName, output.output);
34410
34313
  if (guardrailResult.truncated) {
34411
34314
  output.output = guardrailResult.output;
34412
- console.log(`[swarm-plugin] Guardrail truncated ${toolName}: ${guardrailResult.originalLength} → ${guardrailResult.truncatedLength} chars`);
34413
34315
  }
34414
34316
  }
34415
34317
  if (toolName === "agentmail_init" && output.output) {
@@ -34433,12 +34335,9 @@ var SwarmPlugin = async (input) => {
34433
34335
  }
34434
34336
  if (toolName === "swarm_complete" && activeAgentMailState) {
34435
34337
  await releaseReservations();
34436
- console.log("[swarm-plugin] Auto-released reservations after swarm:complete");
34437
34338
  }
34438
34339
  if (toolName === "beads_close") {
34439
- $`bd sync`.quiet().nothrow().then(() => {
34440
- console.log("[swarm-plugin] Auto-synced beads after close");
34441
- });
34340
+ $`bd sync`.quiet().nothrow();
34442
34341
  }
34443
34342
  }
34444
34343
  };