opencode-swarm-plugin 0.25.1 → 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/index.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();
@@ -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
- function buildCreateCommand(args) {
27715
- const parts = ["bd", "create", args.title];
27716
- if (args.type && args.type !== "task") {
27717
- parts.push("-t", args.type);
27718
- }
27719
- if (args.priority !== undefined && args.priority !== 2) {
27720
- parts.push("-p", args.priority.toString());
27721
- }
27722
- if (args.description) {
27723
- parts.push("-d", args.description);
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;
27733
- }
27734
- function parseBead(output) {
27735
- try {
27736
- const parsed = JSON.parse(output);
27737
- const data = Array.isArray(parsed) ? parsed[0] : parsed;
27738
- if (!data) {
27739
- 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");
27740
- }
27741
- return BeadSchema.parse(data);
27742
- } catch (error45) {
27743
- if (error45 instanceof exports_external.ZodError) {
27744
- throw new BeadValidationError(`Invalid bead data: ${error45.message}`, error45);
27745
- }
27746
- if (error45 instanceof BeadError) {
27747
- throw error45;
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");
27704
+ var adapterCache = new Map;
27705
+ async function getBeadsAdapter(projectKey) {
27706
+ if (adapterCache.has(projectKey)) {
27707
+ return adapterCache.get(projectKey);
27750
27708
  }
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;
27751
27715
  }
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 cmdParts = buildCreateCommand(validated);
27775
- const result = await runBdCommand(cmdParts.slice(1));
27776
- if (result.exitCode !== 0) {
27777
- 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);
27778
- }
27779
- const stdout = result.stdout.trim();
27780
- if (!stdout) {
27781
- 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");
27782
- }
27783
- if (stdout.startsWith("error:") || stdout.startsWith("Error:")) {
27784
- 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);
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 epicCmd = buildCreateCommand({
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
- const epicResult = await runBdCommand(epicCmd.slice(1));
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
- let subtaskId;
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
- const subtaskResult = await runBdCommand(subtaskCmd.slice(1));
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
- const closeArgs = [
27880
- "close",
27881
- bead.id,
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 ${rollbackCommands.length} bead(s):
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
- if (!rollbackInfo) {
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
- let cmd;
27934
- if (validated.ready) {
27935
- cmd = ["bd", "ready", "--json"];
27936
- } else {
27937
- cmd = ["bd", "list", "--json"];
27938
- if (validated.status) {
27939
- cmd.push("--status", validated.status);
27940
- }
27941
- if (validated.type) {
27942
- cmd.push("--type", validated.type);
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 cmd = ["bd", "update", validated.id];
27965
- if (validated.status) {
27966
- cmd.push("--status", validated.status);
27967
- }
27968
- if (validated.description) {
27969
- cmd.push("-d", validated.description);
27970
- }
27971
- if (validated.priority !== undefined) {
27972
- cmd.push("-p", validated.priority.toString());
27973
- }
27974
- cmd.push("--json");
27975
- const result = await runBdCommand(cmd.slice(1));
27976
- if (result.exitCode !== 0) {
27977
- 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);
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 cmd = [
27992
- "bd",
27993
- "close",
27994
- validated.id,
27995
- "--reason",
27996
- validated.reason,
27997
- "--json"
27998
- ];
27999
- const result = await runBdCommand(cmd.slice(1));
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 result = await runBdCommand([
28014
- "update",
28015
- args.id,
28016
- "--status",
28017
- "in_progress",
28018
- "--json"
28019
- ]);
28020
- if (result.exitCode !== 0) {
28021
- 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);
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 result = await runBdCommand(["ready", "--json"]);
28032
- if (result.exitCode !== 0) {
28033
- 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);
28034
- }
28035
- const beads = parseBeads(result.stdout);
28036
- if (beads.length === 0) {
28037
- return "No ready beads";
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 flushResult = await withTimeout(runBdCommand(["sync", "--flush-only"]), TIMEOUT_MS, "bd sync --flush-only");
28065
- if (flushResult.exitCode !== 0) {
28066
- 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);
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 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);
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 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);
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 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);
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 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);
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 queryResult = await runBdCommand(["show", args.bead_id, "--json"]);
28148
- if (queryResult.exitCode !== 0) {
28149
- 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);
28150
- }
28151
- const bead = parseBead(queryResult.stdout);
28152
- const existingDesc = bead.description || "";
28153
- const threadMarker = `[thread:${args.thread_id}]`;
28154
- if (existingDesc.includes(threadMarker)) {
28155
- return `Bead ${args.bead_id} already linked to thread ${args.thread_id}`;
28156
- }
28157
- const newDesc = existingDesc ? `${existingDesc}
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
- const updateResult = await runBdCommand([
28161
- "update",
28162
- args.bead_id,
28163
- "-d",
28164
- newDesc,
28165
- "--json"
28166
- ]);
28167
- if (updateResult.exitCode !== 0) {
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();
@@ -31470,9 +31375,28 @@ swarmmail_release() # Manually release reservations
31470
31375
  **Note:** \`swarm_complete\` automatically releases reservations. Only use manual release if aborting work.
31471
31376
 
31472
31377
  ## [OTHER TOOLS]
31473
- ### Beads
31378
+ ### Beads - You Have Autonomy to File Issues
31379
+ You can create new beads against this epic when you discover:
31380
+ - **Bugs**: Found a bug while working? File it.
31381
+ - **Tech debt**: Spotted something that needs cleanup? File it.
31382
+ - **Follow-up work**: Task needs more work than scoped? File a follow-up.
31383
+ - **Dependencies**: Need something from another agent? File and link it.
31384
+
31385
+ \`\`\`
31386
+ beads_create(
31387
+ title="<descriptive title>",
31388
+ type="bug", # or "task", "chore"
31389
+ priority=2,
31390
+ parent_id="{epic_id}", # Links to this epic
31391
+ description="Found while working on {bead_id}: <details>"
31392
+ )
31393
+ \`\`\`
31394
+
31395
+ **Don't silently ignore issues.** File them so they get tracked and addressed.
31396
+
31397
+ Other bead operations:
31474
31398
  - beads_update(id, status) - Mark blocked if stuck
31475
- - beads_create(title, type) - Log new bugs found
31399
+ - beads_query(status="open") - See what else needs work
31476
31400
 
31477
31401
  ### Skills
31478
31402
  - skills_list() - Discover available skills
@@ -32287,7 +32211,7 @@ var swarm_complete = tool({
32287
32211
  error_count: tool.schema.number().optional().describe("Number of errors encountered during task"),
32288
32212
  retry_count: tool.schema.number().optional().describe("Number of retry attempts during task")
32289
32213
  },
32290
- async execute(args) {
32214
+ async execute(args, _ctx) {
32291
32215
  const epicId = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
32292
32216
  try {
32293
32217
  const projectKey = args.project_key.replace(/\//g, "-").replace(/\\/g, "-");
@@ -32433,7 +32357,6 @@ Continuing with completion, but this should be fixed for future subtasks.`;
32433
32357
  const storeResult = await Bun.$`semantic-memory store ${memoryInfo.information} --metadata ${memoryInfo.metadata}`.quiet().nothrow();
32434
32358
  if (storeResult.exitCode === 0) {
32435
32359
  memoryStored = true;
32436
- console.log(`[swarm_complete] Stored learning for ${args.bead_id} in semantic-memory`);
32437
32360
  } else {
32438
32361
  memoryError = `semantic-memory store failed: ${storeResult.stderr.toString().slice(0, 200)}`;
32439
32362
  console.warn(`[swarm_complete] ${memoryError}`);
@@ -32466,21 +32389,30 @@ Continuing with completion, but this should be fixed for future subtasks.`;
32466
32389
  `**Memory Capture**: ${memoryStored ? "✓ Stored in semantic-memory" : `✗ ${memoryError || "Failed"}`}`
32467
32390
  ].filter(Boolean).join(`
32468
32391
  `);
32469
- await sendSwarmMessage2({
32470
- projectPath: args.project_key,
32471
- fromAgent: args.agent_name,
32472
- toAgents: [],
32473
- subject: `Complete: ${args.bead_id}`,
32474
- body: completionBody,
32475
- threadId: epicId2,
32476
- importance: "normal"
32477
- });
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
+ }
32478
32409
  const response = {
32479
32410
  success: true,
32480
32411
  bead_id: args.bead_id,
32481
32412
  closed: true,
32482
32413
  reservations_released: true,
32483
- message_sent: true,
32414
+ message_sent: messageSent,
32415
+ message_error: messageError,
32484
32416
  agent_registration: {
32485
32417
  verified: agentRegistered,
32486
32418
  warning: registrationWarning || undefined
@@ -34625,7 +34557,6 @@ class SemanticMemoryStorage {
34625
34557
  config;
34626
34558
  constructor(config2 = {}) {
34627
34559
  this.config = { ...getDefaultStorageConfig(), ...config2 };
34628
- console.log(`[storage] SemanticMemoryStorage initialized with collections:`, this.config.collections);
34629
34560
  }
34630
34561
  async checkLowUsageAlert() {
34631
34562
  const TEN_MINUTES = 10 * 60 * 1000;
@@ -34643,7 +34574,6 @@ class SemanticMemoryStorage {
34643
34574
  if (metadata) {
34644
34575
  args.push("--metadata", JSON.stringify(metadata));
34645
34576
  }
34646
- console.log(`[storage] store() -> collection="${collection}"`);
34647
34577
  sessionStats.storesCount++;
34648
34578
  const result = await execSemanticMemory2(args);
34649
34579
  if (result.exitCode !== 0) {
@@ -34664,7 +34594,6 @@ class SemanticMemoryStorage {
34664
34594
  if (useFts) {
34665
34595
  args.push("--fts");
34666
34596
  }
34667
- console.log(`[storage] find() -> collection="${collection}", query="${query.slice(0, 50)}${query.length > 50 ? "..." : ""}", limit=${limit}, fts=${useFts}`);
34668
34597
  sessionStats.queriesCount++;
34669
34598
  const result = await execSemanticMemory2(args);
34670
34599
  if (result.exitCode !== 0) {
@@ -34691,7 +34620,6 @@ class SemanticMemoryStorage {
34691
34620
  }
34692
34621
  }
34693
34622
  async list(collection) {
34694
- console.log(`[storage] list() -> collection="${collection}"`);
34695
34623
  sessionStats.queriesCount++;
34696
34624
  const result = await execSemanticMemory2([
34697
34625
  "list",
@@ -34949,7 +34877,6 @@ var SwarmPlugin = async (input) => {
34949
34877
  })
34950
34878
  });
34951
34879
  if (response.ok) {
34952
- console.log(`[swarm-plugin] Auto-released ${activeAgentMailState.reservations.length} file reservation(s)`);
34953
34880
  activeAgentMailState.reservations = [];
34954
34881
  }
34955
34882
  } catch (error45) {
@@ -34986,7 +34913,6 @@ var SwarmPlugin = async (input) => {
34986
34913
  const guardrailResult = guardrailOutput(toolName, output.output);
34987
34914
  if (guardrailResult.truncated) {
34988
34915
  output.output = guardrailResult.output;
34989
- console.log(`[swarm-plugin] Guardrail truncated ${toolName}: ${guardrailResult.originalLength} → ${guardrailResult.truncatedLength} chars`);
34990
34916
  }
34991
34917
  }
34992
34918
  if (toolName === "agentmail_init" && output.output) {
@@ -35010,12 +34936,9 @@ var SwarmPlugin = async (input) => {
35010
34936
  }
35011
34937
  if (toolName === "swarm_complete" && activeAgentMailState) {
35012
34938
  await releaseReservations();
35013
- console.log("[swarm-plugin] Auto-released reservations after swarm:complete");
35014
34939
  }
35015
34940
  if (toolName === "beads_close") {
35016
- $`bd sync`.quiet().nothrow().then(() => {
35017
- console.log("[swarm-plugin] Auto-synced beads after close");
35018
- });
34941
+ $`bd sync`.quiet().nothrow();
35019
34942
  }
35020
34943
  }
35021
34944
  };
@@ -35079,6 +35002,7 @@ export {
35079
35002
  getSchemaByName,
35080
35003
  getMandateStorage,
35081
35004
  getBeadsWorkingDirectory,
35005
+ getBeadsAdapter,
35082
35006
  getBeadIdFromEvent,
35083
35007
  getAgentMailProjectDirectory,
35084
35008
  formatZodErrors,