opencode-swarm-plugin 0.26.0 → 0.27.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.
Files changed (78) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +37 -0
  3. package/README.md +43 -46
  4. package/bin/swarm.ts +8 -8
  5. package/dist/compaction-hook.d.ts +57 -0
  6. package/dist/compaction-hook.d.ts.map +1 -0
  7. package/dist/hive.d.ts +741 -0
  8. package/dist/hive.d.ts.map +1 -0
  9. package/dist/index.d.ts +139 -23
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +1418 -387
  12. package/dist/learning.d.ts +9 -9
  13. package/dist/plugin.js +1240 -386
  14. package/dist/schemas/cell-events.d.ts +1352 -0
  15. package/dist/schemas/{bead-events.d.ts.map → cell-events.d.ts.map} +1 -1
  16. package/dist/schemas/{bead.d.ts → cell.d.ts} +173 -29
  17. package/dist/schemas/cell.d.ts.map +1 -0
  18. package/dist/schemas/index.d.ts +11 -7
  19. package/dist/schemas/index.d.ts.map +1 -1
  20. package/dist/structured.d.ts +17 -7
  21. package/dist/structured.d.ts.map +1 -1
  22. package/dist/swarm-decompose.d.ts +5 -5
  23. package/dist/swarm-orchestrate.d.ts +16 -2
  24. package/dist/swarm-orchestrate.d.ts.map +1 -1
  25. package/dist/swarm-prompts.d.ts +9 -9
  26. package/dist/swarm-prompts.d.ts.map +1 -1
  27. package/dist/swarm-review.d.ts +210 -0
  28. package/dist/swarm-review.d.ts.map +1 -0
  29. package/dist/swarm-worktree.d.ts +185 -0
  30. package/dist/swarm-worktree.d.ts.map +1 -0
  31. package/dist/swarm.d.ts +7 -0
  32. package/dist/swarm.d.ts.map +1 -1
  33. package/dist/tool-availability.d.ts +3 -2
  34. package/dist/tool-availability.d.ts.map +1 -1
  35. package/docs/analysis-socratic-planner-pattern.md +1 -1
  36. package/docs/planning/ADR-007-swarm-enhancements-worktree-review.md +168 -0
  37. package/docs/testing/context-recovery-test.md +2 -2
  38. package/evals/README.md +2 -2
  39. package/evals/scorers/index.ts +7 -7
  40. package/examples/commands/swarm.md +21 -23
  41. package/examples/plugin-wrapper-template.ts +310 -44
  42. package/examples/skills/{beads-workflow → hive-workflow}/SKILL.md +40 -40
  43. package/examples/skills/swarm-coordination/SKILL.md +1 -1
  44. package/global-skills/swarm-coordination/SKILL.md +14 -14
  45. package/global-skills/swarm-coordination/references/coordinator-patterns.md +3 -3
  46. package/package.json +2 -2
  47. package/src/compaction-hook.ts +161 -0
  48. package/src/{beads.integration.test.ts → hive.integration.test.ts} +92 -80
  49. package/src/hive.ts +1017 -0
  50. package/src/index.ts +57 -20
  51. package/src/learning.ts +9 -9
  52. package/src/output-guardrails.test.ts +4 -4
  53. package/src/output-guardrails.ts +9 -9
  54. package/src/planning-guardrails.test.ts +1 -1
  55. package/src/planning-guardrails.ts +1 -1
  56. package/src/schemas/{bead-events.test.ts → cell-events.test.ts} +83 -77
  57. package/src/schemas/cell-events.ts +807 -0
  58. package/src/schemas/{bead.ts → cell.ts} +95 -41
  59. package/src/schemas/evaluation.ts +1 -1
  60. package/src/schemas/index.ts +90 -18
  61. package/src/schemas/swarm-context.ts +2 -2
  62. package/src/structured.test.ts +15 -15
  63. package/src/structured.ts +18 -11
  64. package/src/swarm-decompose.ts +23 -23
  65. package/src/swarm-orchestrate.ts +135 -21
  66. package/src/swarm-prompts.ts +43 -43
  67. package/src/swarm-review.test.ts +702 -0
  68. package/src/swarm-review.ts +696 -0
  69. package/src/swarm-worktree.test.ts +501 -0
  70. package/src/swarm-worktree.ts +575 -0
  71. package/src/swarm.integration.test.ts +12 -12
  72. package/src/tool-availability.ts +36 -3
  73. package/dist/beads.d.ts +0 -383
  74. package/dist/beads.d.ts.map +0 -1
  75. package/dist/schemas/bead-events.d.ts +0 -698
  76. package/dist/schemas/bead.d.ts.map +0 -1
  77. package/src/beads.ts +0 -800
  78. package/src/schemas/bead-events.ts +0 -583
package/dist/plugin.js CHANGED
@@ -26166,7 +26166,7 @@ __export(exports_skills, {
26166
26166
  });
26167
26167
  import { readdir, readFile, stat, mkdir, writeFile, rm } from "fs/promises";
26168
26168
  import {
26169
- join as join4,
26169
+ join as join5,
26170
26170
  basename,
26171
26171
  dirname as dirname2,
26172
26172
  resolve,
@@ -26214,19 +26214,19 @@ function validateSkillMetadata(raw, filePath) {
26214
26214
  }
26215
26215
  function getGlobalSkillsDir() {
26216
26216
  const home = process.env.HOME || process.env.USERPROFILE || "~";
26217
- return join4(home, ".config", "opencode", "skills");
26217
+ return join5(home, ".config", "opencode", "skills");
26218
26218
  }
26219
26219
  function getClaudeGlobalSkillsDir() {
26220
26220
  const home = process.env.HOME || process.env.USERPROFILE || "~";
26221
- return join4(home, ".claude", "skills");
26221
+ return join5(home, ".claude", "skills");
26222
26222
  }
26223
26223
  function getPackageSkillsDir() {
26224
26224
  try {
26225
26225
  const currentFilePath = fileURLToPath(import.meta.url);
26226
- return join4(dirname2(currentFilePath), "..", "global-skills");
26226
+ return join5(dirname2(currentFilePath), "..", "global-skills");
26227
26227
  } catch {
26228
26228
  const currentDir = decodeURIComponent(new URL(".", import.meta.url).pathname);
26229
- return join4(currentDir, "..", "global-skills");
26229
+ return join5(currentDir, "..", "global-skills");
26230
26230
  }
26231
26231
  }
26232
26232
  async function findSkillFiles(baseDir) {
@@ -26235,7 +26235,7 @@ async function findSkillFiles(baseDir) {
26235
26235
  const entries = await readdir(baseDir, { withFileTypes: true });
26236
26236
  for (const entry of entries) {
26237
26237
  if (entry.isDirectory()) {
26238
- const skillPath = join4(baseDir, entry.name, "SKILL.md");
26238
+ const skillPath = join5(baseDir, entry.name, "SKILL.md");
26239
26239
  try {
26240
26240
  const s = await stat(skillPath);
26241
26241
  if (s.isFile()) {
@@ -26249,7 +26249,7 @@ async function findSkillFiles(baseDir) {
26249
26249
  }
26250
26250
  async function findSkillScripts(skillDir) {
26251
26251
  const scripts = [];
26252
- const scriptsDir = join4(skillDir, "scripts");
26252
+ const scriptsDir = join5(skillDir, "scripts");
26253
26253
  try {
26254
26254
  const entries = await readdir(scriptsDir, { withFileTypes: true });
26255
26255
  for (const entry of entries) {
@@ -26297,7 +26297,7 @@ async function discoverSkills(projectDir) {
26297
26297
  }
26298
26298
  }
26299
26299
  for (const relPath of PROJECT_SKILL_DIRECTORIES) {
26300
- await loadSkillsFromDir(join4(dir, relPath));
26300
+ await loadSkillsFromDir(join5(dir, relPath));
26301
26301
  }
26302
26302
  await loadSkillsFromDir(getGlobalSkillsDir());
26303
26303
  await loadSkillsFromDir(getClaudeGlobalSkillsDir());
@@ -26653,7 +26653,7 @@ Scripts run in the skill's directory with the project directory as an argument.`
26653
26653
  if (!skill.scripts.includes(args.script)) {
26654
26654
  return `Script '${args.script}' not found in skill '${args.skill}'. Available: ${skill.scripts.join(", ") || "none"}`;
26655
26655
  }
26656
- const scriptPath = join4(skill.directory, "scripts", args.script);
26656
+ const scriptPath = join5(skill.directory, "scripts", args.script);
26657
26657
  const scriptArgs = args.args || [];
26658
26658
  try {
26659
26659
  const TIMEOUT_MS = 60000;
@@ -26761,14 +26761,14 @@ Good skills have:
26761
26761
  const csoWarnings = validateCSOCompliance(args.name, args.description);
26762
26762
  let skillDir;
26763
26763
  if (args.directory === "global") {
26764
- skillDir = join4(getGlobalSkillsDir(), args.name);
26764
+ skillDir = join5(getGlobalSkillsDir(), args.name);
26765
26765
  } else if (args.directory === "global-claude") {
26766
- skillDir = join4(getClaudeGlobalSkillsDir(), args.name);
26766
+ skillDir = join5(getClaudeGlobalSkillsDir(), args.name);
26767
26767
  } else {
26768
26768
  const baseDir = args.directory || DEFAULT_SKILLS_DIR;
26769
- skillDir = join4(skillsProjectDirectory, baseDir, args.name);
26769
+ skillDir = join5(skillsProjectDirectory, baseDir, args.name);
26770
26770
  }
26771
- const skillPath = join4(skillDir, "SKILL.md");
26771
+ const skillPath = join5(skillDir, "SKILL.md");
26772
26772
  try {
26773
26773
  await mkdir(skillDir, { recursive: true });
26774
26774
  const content = generateSkillContent(args.name, args.description, args.body, { tags: args.tags, tools: args.tools });
@@ -26919,8 +26919,8 @@ executed with skills_execute. Use for:
26919
26919
  if (isAbsolute(args.script_name) || args.script_name.includes("..") || args.script_name.includes("/") || args.script_name.includes("\\") || basename(args.script_name) !== args.script_name) {
26920
26920
  return "Invalid script name. Use simple filenames without paths.";
26921
26921
  }
26922
- const scriptsDir = join4(skill.directory, "scripts");
26923
- const scriptPath = join4(scriptsDir, args.script_name);
26922
+ const scriptsDir = join5(skill.directory, "scripts");
26923
+ const scriptPath = join5(scriptsDir, args.script_name);
26924
26924
  try {
26925
26925
  await mkdir(scriptsDir, { recursive: true });
26926
26926
  await writeFile(scriptPath, args.content, {
@@ -26969,20 +26969,20 @@ Perfect for learning to create effective skills.`,
26969
26969
  }
26970
26970
  let skillDir;
26971
26971
  if (args.directory === "global") {
26972
- skillDir = join4(getGlobalSkillsDir(), args.name);
26972
+ skillDir = join5(getGlobalSkillsDir(), args.name);
26973
26973
  } else {
26974
26974
  const baseDir = args.directory || DEFAULT_SKILLS_DIR;
26975
- skillDir = join4(skillsProjectDirectory, baseDir, args.name);
26975
+ skillDir = join5(skillsProjectDirectory, baseDir, args.name);
26976
26976
  }
26977
26977
  const createdFiles = [];
26978
26978
  try {
26979
26979
  await mkdir(skillDir, { recursive: true });
26980
- const skillPath = join4(skillDir, "SKILL.md");
26980
+ const skillPath = join5(skillDir, "SKILL.md");
26981
26981
  const skillContent = generateSkillTemplate(args.name, args.description);
26982
26982
  await writeFile(skillPath, skillContent, "utf-8");
26983
26983
  createdFiles.push("SKILL.md");
26984
26984
  if (args.include_example_script !== false) {
26985
- const scriptsDir = join4(skillDir, "scripts");
26985
+ const scriptsDir = join5(skillDir, "scripts");
26986
26986
  await mkdir(scriptsDir, { recursive: true });
26987
26987
  const exampleScript = `#!/usr/bin/env bash
26988
26988
  # Example helper script for ${args.name}
@@ -26996,15 +26996,15 @@ echo "Project directory: $1"
26996
26996
 
26997
26997
  # TODO: Add actual script logic
26998
26998
  `;
26999
- const scriptPath = join4(scriptsDir, "example.sh");
26999
+ const scriptPath = join5(scriptsDir, "example.sh");
27000
27000
  await writeFile(scriptPath, exampleScript, { mode: 493 });
27001
27001
  createdFiles.push("scripts/example.sh");
27002
27002
  }
27003
27003
  if (args.include_reference !== false) {
27004
- const refsDir = join4(skillDir, "references");
27004
+ const refsDir = join5(skillDir, "references");
27005
27005
  await mkdir(refsDir, { recursive: true });
27006
27006
  const refContent = generateReferenceTemplate(args.name);
27007
- const refPath = join4(refsDir, "guide.md");
27007
+ const refPath = join5(refsDir, "guide.md");
27008
27008
  await writeFile(refPath, refContent, "utf-8");
27009
27009
  createdFiles.push("references/guide.md");
27010
27010
  }
@@ -27051,40 +27051,43 @@ echo "Project directory: $1"
27051
27051
  };
27052
27052
  });
27053
27053
 
27054
- // src/beads.ts
27054
+ // src/hive.ts
27055
27055
  init_dist();
27056
27056
  import {
27057
- createBeadsAdapter,
27057
+ createHiveAdapter,
27058
27058
  FlushManager,
27059
+ importFromJSONL,
27059
27060
  getSwarmMail
27060
27061
  } from "swarm-mail";
27062
+ import { existsSync, readFileSync } from "node:fs";
27063
+ import { join } from "node:path";
27061
27064
 
27062
- // src/schemas/bead.ts
27065
+ // src/schemas/cell.ts
27063
27066
  init_zod();
27064
- var BeadStatusSchema = exports_external.enum([
27067
+ var CellStatusSchema = exports_external.enum([
27065
27068
  "open",
27066
27069
  "in_progress",
27067
27070
  "blocked",
27068
27071
  "closed"
27069
27072
  ]);
27070
- var BeadTypeSchema = exports_external.enum([
27073
+ var CellTypeSchema = exports_external.enum([
27071
27074
  "bug",
27072
27075
  "feature",
27073
27076
  "task",
27074
27077
  "epic",
27075
27078
  "chore"
27076
27079
  ]);
27077
- var BeadDependencySchema = exports_external.object({
27080
+ var CellDependencySchema = exports_external.object({
27078
27081
  id: exports_external.string(),
27079
27082
  type: exports_external.enum(["blocks", "blocked-by", "related", "discovered-from"])
27080
27083
  });
27081
- var BeadSchema = exports_external.object({
27082
- id: exports_external.string().regex(/^[a-z0-9]+(-[a-z0-9]+)+(\.[\w-]+)?$/, "Invalid bead ID format (expected: project-slug-hash or project-slug-hash.N)"),
27084
+ var CellSchema = exports_external.object({
27085
+ id: exports_external.string().regex(/^[a-z0-9]+(-[a-z0-9]+)+(\.[\w-]+)?$/, "Invalid cell ID format (expected: project-slug-hash or project-slug-hash.N)"),
27083
27086
  title: exports_external.string().min(1, "Title required"),
27084
27087
  description: exports_external.string().optional().default(""),
27085
- status: BeadStatusSchema.default("open"),
27088
+ status: CellStatusSchema.default("open"),
27086
27089
  priority: exports_external.number().int().min(0).max(3).default(2),
27087
- issue_type: BeadTypeSchema.default("task"),
27090
+ issue_type: CellTypeSchema.default("task"),
27088
27091
  created_at: exports_external.string().datetime({
27089
27092
  offset: true,
27090
27093
  message: "Must be ISO-8601 datetime with timezone (e.g., 2024-01-15T10:30:00Z)"
@@ -27095,30 +27098,30 @@ var BeadSchema = exports_external.object({
27095
27098
  }).optional(),
27096
27099
  closed_at: exports_external.string().datetime({ offset: true }).optional(),
27097
27100
  parent_id: exports_external.string().optional(),
27098
- dependencies: exports_external.array(BeadDependencySchema).default([]),
27101
+ dependencies: exports_external.array(CellDependencySchema).default([]),
27099
27102
  metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
27100
27103
  });
27101
- var BeadCreateArgsSchema = exports_external.object({
27104
+ var CellCreateArgsSchema = exports_external.object({
27102
27105
  title: exports_external.string().min(1, "Title required"),
27103
- type: BeadTypeSchema.default("task"),
27106
+ type: CellTypeSchema.default("task"),
27104
27107
  priority: exports_external.number().int().min(0).max(3).default(2),
27105
27108
  description: exports_external.string().optional(),
27106
27109
  parent_id: exports_external.string().optional(),
27107
27110
  id: exports_external.string().optional()
27108
27111
  });
27109
- var BeadUpdateArgsSchema = exports_external.object({
27112
+ var CellUpdateArgsSchema = exports_external.object({
27110
27113
  id: exports_external.string(),
27111
- status: BeadStatusSchema.optional(),
27114
+ status: CellStatusSchema.optional(),
27112
27115
  description: exports_external.string().optional(),
27113
27116
  priority: exports_external.number().int().min(0).max(3).optional()
27114
27117
  });
27115
- var BeadCloseArgsSchema = exports_external.object({
27118
+ var CellCloseArgsSchema = exports_external.object({
27116
27119
  id: exports_external.string(),
27117
27120
  reason: exports_external.string().min(1, "Reason required")
27118
27121
  });
27119
- var BeadQueryArgsSchema = exports_external.object({
27120
- status: BeadStatusSchema.optional(),
27121
- type: BeadTypeSchema.optional(),
27122
+ var CellQueryArgsSchema = exports_external.object({
27123
+ status: CellStatusSchema.optional(),
27124
+ type: CellTypeSchema.optional(),
27122
27125
  ready: exports_external.boolean().optional(),
27123
27126
  limit: exports_external.number().int().positive().default(20)
27124
27127
  });
@@ -27129,7 +27132,7 @@ var SubtaskSpecSchema = exports_external.object({
27129
27132
  dependencies: exports_external.array(exports_external.number().int().min(0)).default([]),
27130
27133
  estimated_complexity: exports_external.number().int().min(1).max(5).default(3)
27131
27134
  });
27132
- var BeadTreeSchema = exports_external.object({
27135
+ var CellTreeSchema = exports_external.object({
27133
27136
  epic: exports_external.object({
27134
27137
  title: exports_external.string().min(1),
27135
27138
  description: exports_external.string().optional().default("")
@@ -27149,10 +27152,11 @@ var EpicCreateArgsSchema = exports_external.object({
27149
27152
  });
27150
27153
  var EpicCreateResultSchema = exports_external.object({
27151
27154
  success: exports_external.boolean(),
27152
- epic: BeadSchema,
27153
- subtasks: exports_external.array(BeadSchema),
27155
+ epic: CellSchema,
27156
+ subtasks: exports_external.array(CellSchema),
27154
27157
  rollback_hint: exports_external.string().optional()
27155
27158
  });
27159
+ var BeadSchema = CellSchema;
27156
27160
  // src/schemas/evaluation.ts
27157
27161
  init_zod();
27158
27162
  var CriterionEvaluationSchema = exports_external.object({
@@ -27416,29 +27420,29 @@ var QuerySwarmContextsArgsSchema = exports_external.object({
27416
27420
  strategy: SwarmStrategySchema.optional(),
27417
27421
  has_errors: exports_external.boolean().optional()
27418
27422
  });
27419
- // src/schemas/bead-events.ts
27423
+ // src/schemas/cell-events.ts
27420
27424
  init_zod();
27421
- var BaseBeadEventSchema = exports_external.object({
27425
+ var BaseCellEventSchema = exports_external.object({
27422
27426
  id: exports_external.number().optional(),
27423
27427
  type: exports_external.string(),
27424
27428
  project_key: exports_external.string(),
27425
27429
  timestamp: exports_external.number(),
27426
27430
  sequence: exports_external.number().optional()
27427
27431
  });
27428
- var BeadCreatedEventSchema = BaseBeadEventSchema.extend({
27429
- type: exports_external.literal("bead_created"),
27430
- bead_id: exports_external.string(),
27432
+ var CellCreatedEventSchema = BaseCellEventSchema.extend({
27433
+ type: exports_external.literal("cell_created"),
27434
+ cell_id: exports_external.string(),
27431
27435
  title: exports_external.string(),
27432
27436
  description: exports_external.string().optional(),
27433
- issue_type: BeadTypeSchema,
27437
+ issue_type: CellTypeSchema,
27434
27438
  priority: exports_external.number().int().min(0).max(3),
27435
27439
  parent_id: exports_external.string().optional(),
27436
27440
  created_by: exports_external.string().optional(),
27437
27441
  metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
27438
27442
  });
27439
- var BeadUpdatedEventSchema = BaseBeadEventSchema.extend({
27440
- type: exports_external.literal("bead_updated"),
27441
- bead_id: exports_external.string(),
27443
+ var CellUpdatedEventSchema = BaseCellEventSchema.extend({
27444
+ type: exports_external.literal("cell_updated"),
27445
+ cell_id: exports_external.string(),
27442
27446
  updated_by: exports_external.string().optional(),
27443
27447
  changes: exports_external.object({
27444
27448
  title: exports_external.object({
@@ -27455,155 +27459,155 @@ var BeadUpdatedEventSchema = BaseBeadEventSchema.extend({
27455
27459
  }).optional()
27456
27460
  })
27457
27461
  });
27458
- var BeadStatusChangedEventSchema = BaseBeadEventSchema.extend({
27459
- type: exports_external.literal("bead_status_changed"),
27460
- bead_id: exports_external.string(),
27461
- from_status: BeadStatusSchema,
27462
- to_status: BeadStatusSchema,
27462
+ var CellStatusChangedEventSchema = BaseCellEventSchema.extend({
27463
+ type: exports_external.literal("cell_status_changed"),
27464
+ cell_id: exports_external.string(),
27465
+ from_status: CellStatusSchema,
27466
+ to_status: CellStatusSchema,
27463
27467
  changed_by: exports_external.string().optional(),
27464
27468
  reason: exports_external.string().optional()
27465
27469
  });
27466
- var BeadClosedEventSchema = BaseBeadEventSchema.extend({
27467
- type: exports_external.literal("bead_closed"),
27468
- bead_id: exports_external.string(),
27470
+ var CellClosedEventSchema = BaseCellEventSchema.extend({
27471
+ type: exports_external.literal("cell_closed"),
27472
+ cell_id: exports_external.string(),
27469
27473
  reason: exports_external.string(),
27470
27474
  closed_by: exports_external.string().optional(),
27471
27475
  files_touched: exports_external.array(exports_external.string()).optional(),
27472
27476
  duration_ms: exports_external.number().optional()
27473
27477
  });
27474
- var BeadReopenedEventSchema = BaseBeadEventSchema.extend({
27475
- type: exports_external.literal("bead_reopened"),
27476
- bead_id: exports_external.string(),
27478
+ var CellReopenedEventSchema = BaseCellEventSchema.extend({
27479
+ type: exports_external.literal("cell_reopened"),
27480
+ cell_id: exports_external.string(),
27477
27481
  reason: exports_external.string().optional(),
27478
27482
  reopened_by: exports_external.string().optional()
27479
27483
  });
27480
- var BeadDeletedEventSchema = BaseBeadEventSchema.extend({
27481
- type: exports_external.literal("bead_deleted"),
27482
- bead_id: exports_external.string(),
27484
+ var CellDeletedEventSchema = BaseCellEventSchema.extend({
27485
+ type: exports_external.literal("cell_deleted"),
27486
+ cell_id: exports_external.string(),
27483
27487
  reason: exports_external.string().optional(),
27484
27488
  deleted_by: exports_external.string().optional()
27485
27489
  });
27486
- var BeadDependencyAddedEventSchema = BaseBeadEventSchema.extend({
27487
- type: exports_external.literal("bead_dependency_added"),
27488
- bead_id: exports_external.string(),
27489
- dependency: BeadDependencySchema,
27490
+ var CellDependencyAddedEventSchema = BaseCellEventSchema.extend({
27491
+ type: exports_external.literal("cell_dependency_added"),
27492
+ cell_id: exports_external.string(),
27493
+ dependency: CellDependencySchema,
27490
27494
  added_by: exports_external.string().optional(),
27491
27495
  reason: exports_external.string().optional()
27492
27496
  });
27493
- var BeadDependencyRemovedEventSchema = BaseBeadEventSchema.extend({
27494
- type: exports_external.literal("bead_dependency_removed"),
27495
- bead_id: exports_external.string(),
27496
- dependency: BeadDependencySchema,
27497
+ var CellDependencyRemovedEventSchema = BaseCellEventSchema.extend({
27498
+ type: exports_external.literal("cell_dependency_removed"),
27499
+ cell_id: exports_external.string(),
27500
+ dependency: CellDependencySchema,
27497
27501
  removed_by: exports_external.string().optional(),
27498
27502
  reason: exports_external.string().optional()
27499
27503
  });
27500
- var BeadLabelAddedEventSchema = BaseBeadEventSchema.extend({
27501
- type: exports_external.literal("bead_label_added"),
27502
- bead_id: exports_external.string(),
27504
+ var CellLabelAddedEventSchema = BaseCellEventSchema.extend({
27505
+ type: exports_external.literal("cell_label_added"),
27506
+ cell_id: exports_external.string(),
27503
27507
  label: exports_external.string(),
27504
27508
  added_by: exports_external.string().optional()
27505
27509
  });
27506
- var BeadLabelRemovedEventSchema = BaseBeadEventSchema.extend({
27507
- type: exports_external.literal("bead_label_removed"),
27508
- bead_id: exports_external.string(),
27510
+ var CellLabelRemovedEventSchema = BaseCellEventSchema.extend({
27511
+ type: exports_external.literal("cell_label_removed"),
27512
+ cell_id: exports_external.string(),
27509
27513
  label: exports_external.string(),
27510
27514
  removed_by: exports_external.string().optional()
27511
27515
  });
27512
- var BeadCommentAddedEventSchema = BaseBeadEventSchema.extend({
27513
- type: exports_external.literal("bead_comment_added"),
27514
- bead_id: exports_external.string(),
27516
+ var CellCommentAddedEventSchema = BaseCellEventSchema.extend({
27517
+ type: exports_external.literal("cell_comment_added"),
27518
+ cell_id: exports_external.string(),
27515
27519
  comment_id: exports_external.number().optional(),
27516
27520
  author: exports_external.string(),
27517
27521
  body: exports_external.string(),
27518
27522
  parent_comment_id: exports_external.number().optional(),
27519
27523
  metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
27520
27524
  });
27521
- var BeadCommentUpdatedEventSchema = BaseBeadEventSchema.extend({
27522
- type: exports_external.literal("bead_comment_updated"),
27523
- bead_id: exports_external.string(),
27525
+ var CellCommentUpdatedEventSchema = BaseCellEventSchema.extend({
27526
+ type: exports_external.literal("cell_comment_updated"),
27527
+ cell_id: exports_external.string(),
27524
27528
  comment_id: exports_external.number(),
27525
27529
  old_body: exports_external.string(),
27526
27530
  new_body: exports_external.string(),
27527
27531
  updated_by: exports_external.string()
27528
27532
  });
27529
- var BeadCommentDeletedEventSchema = BaseBeadEventSchema.extend({
27530
- type: exports_external.literal("bead_comment_deleted"),
27531
- bead_id: exports_external.string(),
27533
+ var CellCommentDeletedEventSchema = BaseCellEventSchema.extend({
27534
+ type: exports_external.literal("cell_comment_deleted"),
27535
+ cell_id: exports_external.string(),
27532
27536
  comment_id: exports_external.number(),
27533
27537
  deleted_by: exports_external.string(),
27534
27538
  reason: exports_external.string().optional()
27535
27539
  });
27536
- var BeadEpicChildAddedEventSchema = BaseBeadEventSchema.extend({
27537
- type: exports_external.literal("bead_epic_child_added"),
27538
- bead_id: exports_external.string(),
27540
+ var CellEpicChildAddedEventSchema = BaseCellEventSchema.extend({
27541
+ type: exports_external.literal("cell_epic_child_added"),
27542
+ cell_id: exports_external.string(),
27539
27543
  child_id: exports_external.string(),
27540
27544
  child_index: exports_external.number().optional(),
27541
27545
  added_by: exports_external.string().optional()
27542
27546
  });
27543
- var BeadEpicChildRemovedEventSchema = BaseBeadEventSchema.extend({
27544
- type: exports_external.literal("bead_epic_child_removed"),
27545
- bead_id: exports_external.string(),
27547
+ var CellEpicChildRemovedEventSchema = BaseCellEventSchema.extend({
27548
+ type: exports_external.literal("cell_epic_child_removed"),
27549
+ cell_id: exports_external.string(),
27546
27550
  child_id: exports_external.string(),
27547
27551
  removed_by: exports_external.string().optional(),
27548
27552
  reason: exports_external.string().optional()
27549
27553
  });
27550
- var BeadEpicClosureEligibleEventSchema = BaseBeadEventSchema.extend({
27551
- type: exports_external.literal("bead_epic_closure_eligible"),
27552
- bead_id: exports_external.string(),
27554
+ var CellEpicClosureEligibleEventSchema = BaseCellEventSchema.extend({
27555
+ type: exports_external.literal("cell_epic_closure_eligible"),
27556
+ cell_id: exports_external.string(),
27553
27557
  child_ids: exports_external.array(exports_external.string()),
27554
27558
  total_duration_ms: exports_external.number().optional(),
27555
27559
  all_files_touched: exports_external.array(exports_external.string()).optional()
27556
27560
  });
27557
- var BeadAssignedEventSchema = BaseBeadEventSchema.extend({
27558
- type: exports_external.literal("bead_assigned"),
27559
- bead_id: exports_external.string(),
27561
+ var CellAssignedEventSchema = BaseCellEventSchema.extend({
27562
+ type: exports_external.literal("cell_assigned"),
27563
+ cell_id: exports_external.string(),
27560
27564
  agent_name: exports_external.string(),
27561
27565
  task_description: exports_external.string().optional()
27562
27566
  });
27563
- var BeadWorkStartedEventSchema = BaseBeadEventSchema.extend({
27564
- type: exports_external.literal("bead_work_started"),
27565
- bead_id: exports_external.string(),
27567
+ var CellWorkStartedEventSchema = BaseCellEventSchema.extend({
27568
+ type: exports_external.literal("cell_work_started"),
27569
+ cell_id: exports_external.string(),
27566
27570
  agent_name: exports_external.string(),
27567
27571
  reserved_files: exports_external.array(exports_external.string()).optional()
27568
27572
  });
27569
- var BeadCompactedEventSchema = BaseBeadEventSchema.extend({
27570
- type: exports_external.literal("bead_compacted"),
27571
- bead_id: exports_external.string(),
27573
+ var CellCompactedEventSchema = BaseCellEventSchema.extend({
27574
+ type: exports_external.literal("cell_compacted"),
27575
+ cell_id: exports_external.string(),
27572
27576
  events_archived: exports_external.number(),
27573
27577
  new_start_sequence: exports_external.number()
27574
27578
  });
27575
- var BeadEventSchema = exports_external.discriminatedUnion("type", [
27576
- BeadCreatedEventSchema,
27577
- BeadUpdatedEventSchema,
27578
- BeadStatusChangedEventSchema,
27579
- BeadClosedEventSchema,
27580
- BeadReopenedEventSchema,
27581
- BeadDeletedEventSchema,
27582
- BeadDependencyAddedEventSchema,
27583
- BeadDependencyRemovedEventSchema,
27584
- BeadLabelAddedEventSchema,
27585
- BeadLabelRemovedEventSchema,
27586
- BeadCommentAddedEventSchema,
27587
- BeadCommentUpdatedEventSchema,
27588
- BeadCommentDeletedEventSchema,
27589
- BeadEpicChildAddedEventSchema,
27590
- BeadEpicChildRemovedEventSchema,
27591
- BeadEpicClosureEligibleEventSchema,
27592
- BeadAssignedEventSchema,
27593
- BeadWorkStartedEventSchema,
27594
- BeadCompactedEventSchema
27579
+ var CellEventSchema = exports_external.discriminatedUnion("type", [
27580
+ CellCreatedEventSchema,
27581
+ CellUpdatedEventSchema,
27582
+ CellStatusChangedEventSchema,
27583
+ CellClosedEventSchema,
27584
+ CellReopenedEventSchema,
27585
+ CellDeletedEventSchema,
27586
+ CellDependencyAddedEventSchema,
27587
+ CellDependencyRemovedEventSchema,
27588
+ CellLabelAddedEventSchema,
27589
+ CellLabelRemovedEventSchema,
27590
+ CellCommentAddedEventSchema,
27591
+ CellCommentUpdatedEventSchema,
27592
+ CellCommentDeletedEventSchema,
27593
+ CellEpicChildAddedEventSchema,
27594
+ CellEpicChildRemovedEventSchema,
27595
+ CellEpicClosureEligibleEventSchema,
27596
+ CellAssignedEventSchema,
27597
+ CellWorkStartedEventSchema,
27598
+ CellCompactedEventSchema
27595
27599
  ]);
27596
- // src/beads.ts
27600
+ // src/hive.ts
27597
27601
  import { createEvent, appendEvent } from "swarm-mail";
27598
- var beadsWorkingDirectory = null;
27599
- function setBeadsWorkingDirectory(directory) {
27600
- beadsWorkingDirectory = directory;
27602
+ var hiveWorkingDirectory = null;
27603
+ function setHiveWorkingDirectory(directory) {
27604
+ hiveWorkingDirectory = directory;
27601
27605
  }
27602
- function getBeadsWorkingDirectory() {
27603
- return beadsWorkingDirectory || process.cwd();
27606
+ function getHiveWorkingDirectory() {
27607
+ return hiveWorkingDirectory || process.cwd();
27604
27608
  }
27605
27609
  async function runGitCommand(args) {
27606
- const cwd = getBeadsWorkingDirectory();
27610
+ const cwd = getHiveWorkingDirectory();
27607
27611
  const proc = Bun.spawn(["git", ...args], {
27608
27612
  cwd,
27609
27613
  stdout: "pipe",
@@ -27617,7 +27621,7 @@ async function runGitCommand(args) {
27617
27621
  return { exitCode, stdout, stderr };
27618
27622
  }
27619
27623
 
27620
- class BeadError extends Error {
27624
+ class HiveError extends Error {
27621
27625
  command;
27622
27626
  exitCode;
27623
27627
  stderr;
@@ -27626,68 +27630,93 @@ class BeadError extends Error {
27626
27630
  this.command = command;
27627
27631
  this.exitCode = exitCode;
27628
27632
  this.stderr = stderr;
27629
- this.name = "BeadError";
27633
+ this.name = "HiveError";
27630
27634
  }
27631
27635
  }
27632
27636
  var adapterCache = new Map;
27633
- async function getBeadsAdapter(projectKey) {
27637
+ async function getHiveAdapter(projectKey) {
27634
27638
  if (adapterCache.has(projectKey)) {
27635
27639
  return adapterCache.get(projectKey);
27636
27640
  }
27637
27641
  const swarmMail = await getSwarmMail(projectKey);
27638
27642
  const db = await swarmMail.getDatabase();
27639
- const adapter = createBeadsAdapter(db, projectKey);
27643
+ const adapter = createHiveAdapter(db, projectKey);
27640
27644
  await adapter.runMigrations();
27645
+ await autoMigrateFromJSONL(adapter, projectKey);
27641
27646
  adapterCache.set(projectKey, adapter);
27642
27647
  return adapter;
27643
27648
  }
27644
- function formatBeadForOutput(adapterBead) {
27649
+ async function autoMigrateFromJSONL(adapter, projectKey) {
27650
+ const jsonlPath = join(projectKey, ".hive", "issues.jsonl");
27651
+ if (!existsSync(jsonlPath)) {
27652
+ return;
27653
+ }
27654
+ const existingCells = await adapter.queryCells(projectKey, { limit: 1 });
27655
+ if (existingCells.length > 0) {
27656
+ return;
27657
+ }
27658
+ try {
27659
+ const jsonlContent = readFileSync(jsonlPath, "utf-8");
27660
+ const result = await importFromJSONL(adapter, projectKey, jsonlContent, {
27661
+ skipExisting: true
27662
+ });
27663
+ if (result.created > 0 || result.updated > 0) {
27664
+ console.log(`[hive] Auto-migrated ${result.created} cells from ${jsonlPath} (${result.skipped} skipped, ${result.errors.length} errors)`);
27665
+ }
27666
+ if (result.errors.length > 0) {
27667
+ console.warn(`[hive] Migration errors:`, result.errors.slice(0, 5).map((e) => `${e.cellId}: ${e.error}`));
27668
+ }
27669
+ } catch (error45) {
27670
+ console.warn(`[hive] Failed to auto-migrate from ${jsonlPath}:`, error45 instanceof Error ? error45.message : String(error45));
27671
+ }
27672
+ }
27673
+ function formatCellForOutput(adapterCell) {
27645
27674
  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,
27675
+ id: adapterCell.id,
27676
+ title: adapterCell.title,
27677
+ description: adapterCell.description || "",
27678
+ status: adapterCell.status,
27679
+ priority: adapterCell.priority,
27680
+ issue_type: adapterCell.type,
27681
+ created_at: new Date(adapterCell.created_at).toISOString(),
27682
+ updated_at: new Date(adapterCell.updated_at).toISOString(),
27683
+ closed_at: adapterCell.closed_at ? new Date(adapterCell.closed_at).toISOString() : undefined,
27684
+ parent_id: adapterCell.parent_id || undefined,
27656
27685
  dependencies: [],
27657
27686
  metadata: {}
27658
27687
  };
27659
27688
  }
27660
- var beads_create = tool({
27661
- description: "Create a new bead with type-safe validation",
27689
+ var hive_create = tool({
27690
+ description: "Create a new cell in the hive with type-safe validation",
27662
27691
  args: {
27663
- title: tool.schema.string().describe("Bead title"),
27692
+ title: tool.schema.string().describe("Cell title"),
27664
27693
  type: tool.schema.enum(["bug", "feature", "task", "epic", "chore"]).optional().describe("Issue type (default: task)"),
27665
27694
  priority: tool.schema.number().min(0).max(3).optional().describe("Priority 0-3 (default: 2)"),
27666
- description: tool.schema.string().optional().describe("Bead description"),
27667
- parent_id: tool.schema.string().optional().describe("Parent bead ID for epic children")
27695
+ description: tool.schema.string().optional().describe("Cell description"),
27696
+ parent_id: tool.schema.string().optional().describe("Parent cell ID for epic children")
27668
27697
  },
27669
27698
  async execute(args, ctx) {
27670
- const validated = BeadCreateArgsSchema.parse(args);
27671
- const projectKey = getBeadsWorkingDirectory();
27672
- const adapter = await getBeadsAdapter(projectKey);
27699
+ const validated = CellCreateArgsSchema.parse(args);
27700
+ const projectKey = getHiveWorkingDirectory();
27701
+ const adapter = await getHiveAdapter(projectKey);
27673
27702
  try {
27674
- const bead = await adapter.createBead(projectKey, {
27703
+ const cell = await adapter.createCell(projectKey, {
27675
27704
  title: validated.title,
27676
27705
  type: validated.type || "task",
27677
27706
  priority: validated.priority ?? 2,
27678
27707
  description: validated.description,
27679
27708
  parent_id: validated.parent_id
27680
27709
  });
27681
- await adapter.markDirty(projectKey, bead.id);
27682
- const formatted = formatBeadForOutput(bead);
27710
+ await adapter.markDirty(projectKey, cell.id);
27711
+ const formatted = formatCellForOutput(cell);
27683
27712
  return JSON.stringify(formatted, null, 2);
27684
27713
  } catch (error45) {
27685
27714
  const message = error45 instanceof Error ? error45.message : String(error45);
27686
- throw new BeadError(`Failed to create bead: ${message}`, "beads_create");
27715
+ throw new HiveError(`Failed to create cell: ${message}`, "hive_create");
27687
27716
  }
27688
27717
  }
27689
27718
  });
27690
- var beads_create_epic = tool({
27719
+ var hive_create_epic = tool({
27691
27720
  description: "Create epic with subtasks in one atomic operation",
27692
27721
  args: {
27693
27722
  epic_title: tool.schema.string().describe("Epic title"),
@@ -27710,11 +27739,11 @@ var beads_create_epic = tool({
27710
27739
  },
27711
27740
  async execute(args, ctx) {
27712
27741
  const validated = EpicCreateArgsSchema.parse(args);
27713
- const projectKey = getBeadsWorkingDirectory();
27714
- const adapter = await getBeadsAdapter(projectKey);
27742
+ const projectKey = getHiveWorkingDirectory();
27743
+ const adapter = await getHiveAdapter(projectKey);
27715
27744
  const created = [];
27716
27745
  try {
27717
- const epic = await adapter.createBead(projectKey, {
27746
+ const epic = await adapter.createCell(projectKey, {
27718
27747
  title: validated.epic_title,
27719
27748
  type: "epic",
27720
27749
  priority: 1,
@@ -27723,19 +27752,19 @@ var beads_create_epic = tool({
27723
27752
  await adapter.markDirty(projectKey, epic.id);
27724
27753
  created.push(epic);
27725
27754
  for (const subtask of validated.subtasks) {
27726
- const subtaskBead = await adapter.createBead(projectKey, {
27755
+ const subtaskCell = await adapter.createCell(projectKey, {
27727
27756
  title: subtask.title,
27728
27757
  type: "task",
27729
27758
  priority: subtask.priority ?? 2,
27730
27759
  parent_id: epic.id
27731
27760
  });
27732
- await adapter.markDirty(projectKey, subtaskBead.id);
27733
- created.push(subtaskBead);
27761
+ await adapter.markDirty(projectKey, subtaskCell.id);
27762
+ created.push(subtaskCell);
27734
27763
  }
27735
27764
  const result = {
27736
27765
  success: true,
27737
- epic: formatBeadForOutput(epic),
27738
- subtasks: created.slice(1).map((b) => formatBeadForOutput(b))
27766
+ epic: formatCellForOutput(epic),
27767
+ subtasks: created.slice(1).map((c) => formatCellForOutput(c))
27739
27768
  };
27740
27769
  if (args.project_key) {
27741
27770
  try {
@@ -27755,27 +27784,27 @@ var beads_create_epic = tool({
27755
27784
  });
27756
27785
  await appendEvent(event, args.project_key);
27757
27786
  } catch (error45) {
27758
- console.warn("[beads_create_epic] Failed to emit DecompositionGeneratedEvent:", error45);
27787
+ console.warn("[hive_create_epic] Failed to emit DecompositionGeneratedEvent:", error45);
27759
27788
  }
27760
27789
  }
27761
27790
  return JSON.stringify(result, null, 2);
27762
27791
  } catch (error45) {
27763
27792
  const rollbackErrors = [];
27764
- for (const bead of created) {
27793
+ for (const cell of created) {
27765
27794
  try {
27766
- await adapter.deleteBead(projectKey, bead.id, {
27795
+ await adapter.deleteCell(projectKey, cell.id, {
27767
27796
  reason: "Rollback partial epic"
27768
27797
  });
27769
27798
  } catch (rollbackError) {
27770
27799
  const errMsg = rollbackError instanceof Error ? rollbackError.message : String(rollbackError);
27771
- console.error(`Failed to rollback bead ${bead.id}:`, rollbackError);
27772
- rollbackErrors.push(`${bead.id}: ${errMsg}`);
27800
+ console.error(`Failed to rollback cell ${cell.id}:`, rollbackError);
27801
+ rollbackErrors.push(`${cell.id}: ${errMsg}`);
27773
27802
  }
27774
27803
  }
27775
27804
  const errorMsg = error45 instanceof Error ? error45.message : String(error45);
27776
27805
  let rollbackInfo = `
27777
27806
 
27778
- Rolled back ${created.length - rollbackErrors.length} bead(s)`;
27807
+ Rolled back ${created.length - rollbackErrors.length} cell(s)`;
27779
27808
  if (rollbackErrors.length > 0) {
27780
27809
  rollbackInfo += `
27781
27810
 
@@ -27783,151 +27812,151 @@ Rollback failures (${rollbackErrors.length}):
27783
27812
  ${rollbackErrors.join(`
27784
27813
  `)}`;
27785
27814
  }
27786
- throw new BeadError(`Epic creation failed: ${errorMsg}${rollbackInfo}`, "beads_create_epic", 1);
27815
+ throw new HiveError(`Epic creation failed: ${errorMsg}${rollbackInfo}`, "hive_create_epic", 1);
27787
27816
  }
27788
27817
  }
27789
27818
  });
27790
- var beads_query = tool({
27791
- description: "Query beads with filters (replaces bd list, bd ready, bd wip)",
27819
+ var hive_query = tool({
27820
+ description: "Query hive cells with filters (replaces bd list, bd ready, bd wip)",
27792
27821
  args: {
27793
27822
  status: tool.schema.enum(["open", "in_progress", "blocked", "closed"]).optional().describe("Filter by status"),
27794
27823
  type: tool.schema.enum(["bug", "feature", "task", "epic", "chore"]).optional().describe("Filter by type"),
27795
- ready: tool.schema.boolean().optional().describe("Only show unblocked beads (uses bd ready)"),
27824
+ ready: tool.schema.boolean().optional().describe("Only show unblocked cells"),
27796
27825
  limit: tool.schema.number().optional().describe("Max results to return (default: 20)")
27797
27826
  },
27798
27827
  async execute(args, ctx) {
27799
- const validated = BeadQueryArgsSchema.parse(args);
27800
- const projectKey = getBeadsWorkingDirectory();
27801
- const adapter = await getBeadsAdapter(projectKey);
27828
+ const validated = CellQueryArgsSchema.parse(args);
27829
+ const projectKey = getHiveWorkingDirectory();
27830
+ const adapter = await getHiveAdapter(projectKey);
27802
27831
  try {
27803
- let beads;
27832
+ let cells;
27804
27833
  if (validated.ready) {
27805
- const readyBead = await adapter.getNextReadyBead(projectKey);
27806
- beads = readyBead ? [readyBead] : [];
27834
+ const readyCell = await adapter.getNextReadyCell(projectKey);
27835
+ cells = readyCell ? [readyCell] : [];
27807
27836
  } else {
27808
- beads = await adapter.queryBeads(projectKey, {
27837
+ cells = await adapter.queryCells(projectKey, {
27809
27838
  status: validated.status,
27810
27839
  type: validated.type,
27811
27840
  limit: validated.limit || 20
27812
27841
  });
27813
27842
  }
27814
- const formatted = beads.map((b) => formatBeadForOutput(b));
27843
+ const formatted = cells.map((c) => formatCellForOutput(c));
27815
27844
  return JSON.stringify(formatted, null, 2);
27816
27845
  } catch (error45) {
27817
27846
  const message = error45 instanceof Error ? error45.message : String(error45);
27818
- throw new BeadError(`Failed to query beads: ${message}`, "beads_query");
27847
+ throw new HiveError(`Failed to query cells: ${message}`, "hive_query");
27819
27848
  }
27820
27849
  }
27821
27850
  });
27822
- var beads_update = tool({
27823
- description: "Update bead status/description",
27851
+ var hive_update = tool({
27852
+ description: "Update cell status/description",
27824
27853
  args: {
27825
- id: tool.schema.string().describe("Bead ID"),
27854
+ id: tool.schema.string().describe("Cell ID"),
27826
27855
  status: tool.schema.enum(["open", "in_progress", "blocked", "closed"]).optional().describe("New status"),
27827
27856
  description: tool.schema.string().optional().describe("New description"),
27828
27857
  priority: tool.schema.number().min(0).max(3).optional().describe("New priority")
27829
27858
  },
27830
27859
  async execute(args, ctx) {
27831
- const validated = BeadUpdateArgsSchema.parse(args);
27832
- const projectKey = getBeadsWorkingDirectory();
27833
- const adapter = await getBeadsAdapter(projectKey);
27860
+ const validated = CellUpdateArgsSchema.parse(args);
27861
+ const projectKey = getHiveWorkingDirectory();
27862
+ const adapter = await getHiveAdapter(projectKey);
27834
27863
  try {
27835
- let bead;
27864
+ let cell;
27836
27865
  if (validated.status) {
27837
- bead = await adapter.changeBeadStatus(projectKey, validated.id, validated.status);
27866
+ cell = await adapter.changeCellStatus(projectKey, validated.id, validated.status);
27838
27867
  }
27839
27868
  if (validated.description !== undefined || validated.priority !== undefined) {
27840
- bead = await adapter.updateBead(projectKey, validated.id, {
27869
+ cell = await adapter.updateCell(projectKey, validated.id, {
27841
27870
  description: validated.description,
27842
27871
  priority: validated.priority
27843
27872
  });
27844
27873
  } 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");
27874
+ const existingCell = await adapter.getCell(projectKey, validated.id);
27875
+ if (!existingCell) {
27876
+ throw new HiveError(`Cell not found: ${validated.id}`, "hive_update");
27848
27877
  }
27849
- bead = existingBead;
27878
+ cell = existingCell;
27850
27879
  }
27851
27880
  await adapter.markDirty(projectKey, validated.id);
27852
- const formatted = formatBeadForOutput(bead);
27881
+ const formatted = formatCellForOutput(cell);
27853
27882
  return JSON.stringify(formatted, null, 2);
27854
27883
  } catch (error45) {
27855
27884
  const message = error45 instanceof Error ? error45.message : String(error45);
27856
- throw new BeadError(`Failed to update bead: ${message}`, "beads_update");
27885
+ throw new HiveError(`Failed to update cell: ${message}`, "hive_update");
27857
27886
  }
27858
27887
  }
27859
27888
  });
27860
- var beads_close = tool({
27861
- description: "Close a bead with reason",
27889
+ var hive_close = tool({
27890
+ description: "Close a cell with reason",
27862
27891
  args: {
27863
- id: tool.schema.string().describe("Bead ID"),
27892
+ id: tool.schema.string().describe("Cell ID"),
27864
27893
  reason: tool.schema.string().describe("Completion reason")
27865
27894
  },
27866
27895
  async execute(args, ctx) {
27867
- const validated = BeadCloseArgsSchema.parse(args);
27868
- const projectKey = getBeadsWorkingDirectory();
27869
- const adapter = await getBeadsAdapter(projectKey);
27896
+ const validated = CellCloseArgsSchema.parse(args);
27897
+ const projectKey = getHiveWorkingDirectory();
27898
+ const adapter = await getHiveAdapter(projectKey);
27870
27899
  try {
27871
- const bead = await adapter.closeBead(projectKey, validated.id, validated.reason);
27900
+ const cell = await adapter.closeCell(projectKey, validated.id, validated.reason);
27872
27901
  await adapter.markDirty(projectKey, validated.id);
27873
- return `Closed ${bead.id}: ${validated.reason}`;
27902
+ return `Closed ${cell.id}: ${validated.reason}`;
27874
27903
  } catch (error45) {
27875
27904
  const message = error45 instanceof Error ? error45.message : String(error45);
27876
- throw new BeadError(`Failed to close bead: ${message}`, "beads_close");
27905
+ throw new HiveError(`Failed to close cell: ${message}`, "hive_close");
27877
27906
  }
27878
27907
  }
27879
27908
  });
27880
- var beads_start = tool({
27881
- description: "Mark a bead as in-progress (shortcut for update --status in_progress)",
27909
+ var hive_start = tool({
27910
+ description: "Mark a cell as in-progress (shortcut for update --status in_progress)",
27882
27911
  args: {
27883
- id: tool.schema.string().describe("Bead ID")
27912
+ id: tool.schema.string().describe("Cell ID")
27884
27913
  },
27885
27914
  async execute(args, ctx) {
27886
- const projectKey = getBeadsWorkingDirectory();
27887
- const adapter = await getBeadsAdapter(projectKey);
27915
+ const projectKey = getHiveWorkingDirectory();
27916
+ const adapter = await getHiveAdapter(projectKey);
27888
27917
  try {
27889
- const bead = await adapter.changeBeadStatus(projectKey, args.id, "in_progress");
27918
+ const cell = await adapter.changeCellStatus(projectKey, args.id, "in_progress");
27890
27919
  await adapter.markDirty(projectKey, args.id);
27891
- return `Started: ${bead.id}`;
27920
+ return `Started: ${cell.id}`;
27892
27921
  } catch (error45) {
27893
27922
  const message = error45 instanceof Error ? error45.message : String(error45);
27894
- throw new BeadError(`Failed to start bead: ${message}`, "beads_start");
27923
+ throw new HiveError(`Failed to start cell: ${message}`, "hive_start");
27895
27924
  }
27896
27925
  }
27897
27926
  });
27898
- var beads_ready = tool({
27899
- description: "Get the next ready bead (unblocked, highest priority)",
27927
+ var hive_ready = tool({
27928
+ description: "Get the next ready cell (unblocked, highest priority)",
27900
27929
  args: {},
27901
27930
  async execute(args, ctx) {
27902
- const projectKey = getBeadsWorkingDirectory();
27903
- const adapter = await getBeadsAdapter(projectKey);
27931
+ const projectKey = getHiveWorkingDirectory();
27932
+ const adapter = await getHiveAdapter(projectKey);
27904
27933
  try {
27905
- const bead = await adapter.getNextReadyBead(projectKey);
27906
- if (!bead) {
27907
- return "No ready beads";
27934
+ const cell = await adapter.getNextReadyCell(projectKey);
27935
+ if (!cell) {
27936
+ return "No ready cells";
27908
27937
  }
27909
- const formatted = formatBeadForOutput(bead);
27938
+ const formatted = formatCellForOutput(cell);
27910
27939
  return JSON.stringify(formatted, null, 2);
27911
27940
  } catch (error45) {
27912
27941
  const message = error45 instanceof Error ? error45.message : String(error45);
27913
- throw new BeadError(`Failed to get ready beads: ${message}`, "beads_ready");
27942
+ throw new HiveError(`Failed to get ready cells: ${message}`, "hive_ready");
27914
27943
  }
27915
27944
  }
27916
27945
  });
27917
- var beads_sync = tool({
27918
- description: "Sync beads to git and push (MANDATORY at session end)",
27946
+ var hive_sync = tool({
27947
+ description: "Sync hive to git and push (MANDATORY at session end)",
27919
27948
  args: {
27920
27949
  auto_pull: tool.schema.boolean().optional().describe("Pull before sync (default: true)")
27921
27950
  },
27922
27951
  async execute(args, ctx) {
27923
27952
  const autoPull = args.auto_pull ?? true;
27924
- const projectKey = getBeadsWorkingDirectory();
27925
- const adapter = await getBeadsAdapter(projectKey);
27953
+ const projectKey = getHiveWorkingDirectory();
27954
+ const adapter = await getHiveAdapter(projectKey);
27926
27955
  const TIMEOUT_MS = 30000;
27927
27956
  const withTimeout = async (promise2, timeoutMs, operation) => {
27928
27957
  let timeoutId;
27929
27958
  const timeoutPromise = new Promise((_, reject) => {
27930
- timeoutId = setTimeout(() => reject(new BeadError(`Operation timed out after ${timeoutMs}ms`, operation)), timeoutMs);
27959
+ timeoutId = setTimeout(() => reject(new HiveError(`Operation timed out after ${timeoutMs}ms`, operation)), timeoutMs);
27931
27960
  });
27932
27961
  try {
27933
27962
  return await Promise.race([promise2, timeoutPromise]);
@@ -27940,85 +27969,156 @@ var beads_sync = tool({
27940
27969
  const flushManager = new FlushManager({
27941
27970
  adapter,
27942
27971
  projectKey,
27943
- outputPath: `${projectKey}/.beads/issues.jsonl`
27972
+ outputPath: `${projectKey}/.hive/issues.jsonl`
27944
27973
  });
27945
- const flushResult = await withTimeout(flushManager.flush(), TIMEOUT_MS, "flush beads");
27946
- if (flushResult.beadsExported === 0) {
27947
- return "No beads to sync";
27974
+ const flushResult = await withTimeout(flushManager.flush(), TIMEOUT_MS, "flush hive");
27975
+ if (flushResult.cellsExported === 0) {
27976
+ return "No cells to sync";
27948
27977
  }
27949
- const beadsStatusResult = await runGitCommand([
27978
+ const hiveStatusResult = await runGitCommand([
27950
27979
  "status",
27951
27980
  "--porcelain",
27952
- ".beads/"
27981
+ ".hive/"
27953
27982
  ]);
27954
- const hasChanges = beadsStatusResult.stdout.trim() !== "";
27983
+ const hasChanges = hiveStatusResult.stdout.trim() !== "";
27955
27984
  if (hasChanges) {
27956
- const addResult = await runGitCommand(["add", ".beads/"]);
27985
+ const addResult = await runGitCommand(["add", ".hive/"]);
27957
27986
  if (addResult.exitCode !== 0) {
27958
- throw new BeadError(`Failed to stage beads: ${addResult.stderr}`, "git add .beads/", addResult.exitCode);
27987
+ throw new HiveError(`Failed to stage hive: ${addResult.stderr}`, "git add .hive/", addResult.exitCode);
27959
27988
  }
27960
- const commitResult = await withTimeout(runGitCommand(["commit", "-m", "chore: sync beads"]), TIMEOUT_MS, "git commit");
27989
+ const commitResult = await withTimeout(runGitCommand(["commit", "-m", "chore: sync hive"]), TIMEOUT_MS, "git commit");
27961
27990
  if (commitResult.exitCode !== 0 && !commitResult.stdout.includes("nothing to commit")) {
27962
- throw new BeadError(`Failed to commit beads: ${commitResult.stderr}`, "git commit", commitResult.exitCode);
27991
+ throw new HiveError(`Failed to commit hive: ${commitResult.stderr}`, "git commit", commitResult.exitCode);
27963
27992
  }
27964
27993
  }
27965
27994
  if (autoPull) {
27966
27995
  const pullResult = await withTimeout(runGitCommand(["pull", "--rebase"]), TIMEOUT_MS, "git pull --rebase");
27967
27996
  if (pullResult.exitCode !== 0) {
27968
- throw new BeadError(`Failed to pull: ${pullResult.stderr}`, "git pull --rebase", pullResult.exitCode);
27997
+ throw new HiveError(`Failed to pull: ${pullResult.stderr}`, "git pull --rebase", pullResult.exitCode);
27969
27998
  }
27970
27999
  }
27971
28000
  const pushResult = await withTimeout(runGitCommand(["push"]), TIMEOUT_MS, "git push");
27972
28001
  if (pushResult.exitCode !== 0) {
27973
- throw new BeadError(`Failed to push: ${pushResult.stderr}`, "git push", pushResult.exitCode);
28002
+ throw new HiveError(`Failed to push: ${pushResult.stderr}`, "git push", pushResult.exitCode);
27974
28003
  }
27975
- return "Beads synced and pushed successfully";
28004
+ return "Hive synced and pushed successfully";
27976
28005
  }
27977
28006
  });
27978
- var beads_link_thread = tool({
27979
- description: "Add metadata linking bead to Agent Mail thread",
28007
+ var hive_link_thread = tool({
28008
+ description: "Add metadata linking cell to Agent Mail thread",
27980
28009
  args: {
27981
- bead_id: tool.schema.string().describe("Bead ID"),
28010
+ cell_id: tool.schema.string().describe("Cell ID"),
27982
28011
  thread_id: tool.schema.string().describe("Agent Mail thread ID")
27983
28012
  },
27984
28013
  async execute(args, ctx) {
27985
- const projectKey = getBeadsWorkingDirectory();
27986
- const adapter = await getBeadsAdapter(projectKey);
28014
+ const projectKey = getHiveWorkingDirectory();
28015
+ const adapter = await getHiveAdapter(projectKey);
27987
28016
  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");
28017
+ const cell = await adapter.getCell(projectKey, args.cell_id);
28018
+ if (!cell) {
28019
+ throw new HiveError(`Cell not found: ${args.cell_id}`, "hive_link_thread");
27991
28020
  }
27992
- const existingDesc = bead.description || "";
28021
+ const existingDesc = cell.description || "";
27993
28022
  const threadMarker = `[thread:${args.thread_id}]`;
27994
28023
  if (existingDesc.includes(threadMarker)) {
27995
- return `Bead ${args.bead_id} already linked to thread ${args.thread_id}`;
28024
+ return `Cell ${args.cell_id} already linked to thread ${args.thread_id}`;
27996
28025
  }
27997
28026
  const newDesc = existingDesc ? `${existingDesc}
27998
28027
 
27999
28028
  ${threadMarker}` : threadMarker;
28000
- await adapter.updateBead(projectKey, args.bead_id, {
28029
+ await adapter.updateCell(projectKey, args.cell_id, {
28001
28030
  description: newDesc
28002
28031
  });
28003
- await adapter.markDirty(projectKey, args.bead_id);
28004
- return `Linked bead ${args.bead_id} to thread ${args.thread_id}`;
28032
+ await adapter.markDirty(projectKey, args.cell_id);
28033
+ return `Linked cell ${args.cell_id} to thread ${args.thread_id}`;
28005
28034
  } catch (error45) {
28006
28035
  const message = error45 instanceof Error ? error45.message : String(error45);
28007
- throw new BeadError(`Failed to link thread: ${message}`, "beads_link_thread");
28036
+ throw new HiveError(`Failed to link thread: ${message}`, "hive_link_thread");
28008
28037
  }
28009
28038
  }
28010
28039
  });
28011
- var beadsTools = {
28012
- beads_create,
28013
- beads_create_epic,
28014
- beads_query,
28015
- beads_update,
28016
- beads_close,
28017
- beads_start,
28018
- beads_ready,
28019
- beads_sync,
28020
- beads_link_thread
28040
+ var hiveTools = {
28041
+ hive_create,
28042
+ hive_create_epic,
28043
+ hive_query,
28044
+ hive_update,
28045
+ hive_close,
28046
+ hive_start,
28047
+ hive_ready,
28048
+ hive_sync,
28049
+ hive_link_thread
28021
28050
  };
28051
+ var warnedTools = new Set;
28052
+ function warnDeprecated(oldName, newName) {
28053
+ if (warnedTools.has(oldName)) {
28054
+ return;
28055
+ }
28056
+ warnedTools.add(oldName);
28057
+ console.warn(`[DEPRECATED] ${oldName} is deprecated, use ${newName} instead. Will be removed in v1.0`);
28058
+ }
28059
+ var beads_create = tool({
28060
+ ...hive_create,
28061
+ async execute(args, ctx) {
28062
+ warnDeprecated("beads_create", "hive_create");
28063
+ return hive_create.execute(args, ctx);
28064
+ }
28065
+ });
28066
+ var beads_create_epic = tool({
28067
+ ...hive_create_epic,
28068
+ async execute(args, ctx) {
28069
+ warnDeprecated("beads_create_epic", "hive_create_epic");
28070
+ return hive_create_epic.execute(args, ctx);
28071
+ }
28072
+ });
28073
+ var beads_query = tool({
28074
+ ...hive_query,
28075
+ async execute(args, ctx) {
28076
+ warnDeprecated("beads_query", "hive_query");
28077
+ return hive_query.execute(args, ctx);
28078
+ }
28079
+ });
28080
+ var beads_update = tool({
28081
+ ...hive_update,
28082
+ async execute(args, ctx) {
28083
+ warnDeprecated("beads_update", "hive_update");
28084
+ return hive_update.execute(args, ctx);
28085
+ }
28086
+ });
28087
+ var beads_close = tool({
28088
+ ...hive_close,
28089
+ async execute(args, ctx) {
28090
+ warnDeprecated("beads_close", "hive_close");
28091
+ return hive_close.execute(args, ctx);
28092
+ }
28093
+ });
28094
+ var beads_start = tool({
28095
+ ...hive_start,
28096
+ async execute(args, ctx) {
28097
+ warnDeprecated("beads_start", "hive_start");
28098
+ return hive_start.execute(args, ctx);
28099
+ }
28100
+ });
28101
+ var beads_ready = tool({
28102
+ ...hive_ready,
28103
+ async execute(args, ctx) {
28104
+ warnDeprecated("beads_ready", "hive_ready");
28105
+ return hive_ready.execute(args, ctx);
28106
+ }
28107
+ });
28108
+ var beads_sync = tool({
28109
+ ...hive_sync,
28110
+ async execute(args, ctx) {
28111
+ warnDeprecated("beads_sync", "hive_sync");
28112
+ return hive_sync.execute(args, ctx);
28113
+ }
28114
+ });
28115
+ var beads_link_thread = tool({
28116
+ ...hive_link_thread,
28117
+ async execute(args, ctx) {
28118
+ warnDeprecated("beads_link_thread", "hive_link_thread");
28119
+ return hive_link_thread.execute(args, ctx);
28120
+ }
28121
+ });
28022
28122
 
28023
28123
  // src/agent-mail.ts
28024
28124
  init_dist();
@@ -28137,6 +28237,29 @@ var toolCheckers = {
28137
28237
  };
28138
28238
  }
28139
28239
  },
28240
+ hive: async () => {
28241
+ const exists = await commandExists("hive");
28242
+ if (!exists) {
28243
+ return {
28244
+ available: false,
28245
+ checkedAt: new Date().toISOString(),
28246
+ error: "hive command not found"
28247
+ };
28248
+ }
28249
+ try {
28250
+ const result = await Bun.$`hive --version`.quiet().nothrow();
28251
+ return {
28252
+ available: result.exitCode === 0,
28253
+ checkedAt: new Date().toISOString()
28254
+ };
28255
+ } catch (e) {
28256
+ return {
28257
+ available: false,
28258
+ checkedAt: new Date().toISOString(),
28259
+ error: String(e)
28260
+ };
28261
+ }
28262
+ },
28140
28263
  beads: async () => {
28141
28264
  const exists = await commandExists("bd");
28142
28265
  if (!exists) {
@@ -28190,7 +28313,8 @@ var fallbackBehaviors = {
28190
28313
  "semantic-memory": "Learning data stored in-memory only (lost on session end)",
28191
28314
  cass: "Decomposition proceeds without historical context from past sessions",
28192
28315
  ubs: "Subtask completion skips bug scanning - manual review recommended",
28193
- beads: "Swarm cannot track issues - task coordination will be less reliable",
28316
+ hive: "Swarm cannot track issues - task coordination will be less reliable",
28317
+ beads: "DEPRECATED: Use hive instead. Swarm cannot track issues - task coordination will be less reliable",
28194
28318
  "swarm-mail": "Multi-agent coordination disabled - file conflicts possible if multiple agents active",
28195
28319
  "agent-mail": "DEPRECATED: Use swarm-mail instead. Legacy MCP server mode - file conflicts possible if multiple agents active"
28196
28320
  };
@@ -28221,6 +28345,7 @@ async function checkAllTools() {
28221
28345
  "semantic-memory",
28222
28346
  "cass",
28223
28347
  "ubs",
28348
+ "hive",
28224
28349
  "beads",
28225
28350
  "swarm-mail",
28226
28351
  "agent-mail"
@@ -28257,8 +28382,8 @@ function formatToolAvailability(availability) {
28257
28382
 
28258
28383
  // src/rate-limiter.ts
28259
28384
  var import_ioredis = __toESM(require_built3(), 1);
28260
- import { mkdirSync, existsSync } from "node:fs";
28261
- import { dirname, join } from "node:path";
28385
+ import { mkdirSync, existsSync as existsSync2 } from "node:fs";
28386
+ import { dirname, join as join2 } from "node:path";
28262
28387
  import { homedir } from "node:os";
28263
28388
  var sqliteAvailable = false;
28264
28389
  var createDatabase = null;
@@ -28374,7 +28499,7 @@ class SqliteRateLimiter {
28374
28499
  throw new Error("SQLite is not available in this runtime (requires Bun)");
28375
28500
  }
28376
28501
  const dir = dirname(dbPath);
28377
- if (!existsSync(dir)) {
28502
+ if (!existsSync2(dir)) {
28378
28503
  mkdirSync(dir, { recursive: true });
28379
28504
  }
28380
28505
  this.db = createDatabase(dbPath);
@@ -28519,7 +28644,7 @@ async function createRateLimiter(options2) {
28519
28644
  const {
28520
28645
  backend,
28521
28646
  redisUrl = process.env.OPENCODE_RATE_LIMIT_REDIS_URL || "redis://localhost:6379",
28522
- sqlitePath = process.env.OPENCODE_RATE_LIMIT_SQLITE_PATH || join(homedir(), ".config", "opencode", "rate-limits.db")
28647
+ sqlitePath = process.env.OPENCODE_RATE_LIMIT_SQLITE_PATH || join2(homedir(), ".config", "opencode", "rate-limits.db")
28523
28648
  } = options2 || {};
28524
28649
  if (backend === "memory") {
28525
28650
  return new InMemoryRateLimiter;
@@ -28579,13 +28704,13 @@ async function getRateLimiter() {
28579
28704
 
28580
28705
  // src/agent-mail.ts
28581
28706
  import {
28582
- existsSync as existsSync2,
28707
+ existsSync as existsSync3,
28583
28708
  mkdirSync as mkdirSync2,
28584
- readFileSync,
28709
+ readFileSync as readFileSync2,
28585
28710
  writeFileSync,
28586
28711
  unlinkSync
28587
28712
  } from "fs";
28588
- import { join as join2 } from "path";
28713
+ import { join as join3 } from "path";
28589
28714
  import { tmpdir } from "os";
28590
28715
  var AGENT_MAIL_URL = "http://127.0.0.1:8765";
28591
28716
  var DEFAULT_TTL_SECONDS = 3600;
@@ -28609,16 +28734,16 @@ var RECOVERY_CONFIG = {
28609
28734
  restartCooldownMs: 1e4,
28610
28735
  enabled: process.env.OPENCODE_AGENT_MAIL_AUTO_RESTART !== "false"
28611
28736
  };
28612
- var SESSION_STATE_DIR = process.env.SWARM_STATE_DIR || join2(tmpdir(), "swarm-sessions");
28737
+ var SESSION_STATE_DIR = process.env.SWARM_STATE_DIR || join3(tmpdir(), "swarm-sessions");
28613
28738
  function getSessionStatePath(sessionID) {
28614
28739
  const safeID = sessionID.replace(/[^a-zA-Z0-9_-]/g, "_");
28615
- return join2(SESSION_STATE_DIR, `${safeID}.json`);
28740
+ return join3(SESSION_STATE_DIR, `${safeID}.json`);
28616
28741
  }
28617
28742
  function loadSessionState(sessionID) {
28618
28743
  const path = getSessionStatePath(sessionID);
28619
28744
  try {
28620
- if (existsSync2(path)) {
28621
- const data = readFileSync(path, "utf-8");
28745
+ if (existsSync3(path)) {
28746
+ const data = readFileSync2(path, "utf-8");
28622
28747
  return JSON.parse(data);
28623
28748
  }
28624
28749
  } catch (error45) {
@@ -28628,7 +28753,7 @@ function loadSessionState(sessionID) {
28628
28753
  }
28629
28754
  function saveSessionState(sessionID, state) {
28630
28755
  try {
28631
- if (!existsSync2(SESSION_STATE_DIR)) {
28756
+ if (!existsSync3(SESSION_STATE_DIR)) {
28632
28757
  mkdirSync2(SESSION_STATE_DIR, { recursive: true });
28633
28758
  }
28634
28759
  const path = getSessionStatePath(sessionID);
@@ -29316,13 +29441,13 @@ import {
29316
29441
  getActiveReservations
29317
29442
  } from "swarm-mail";
29318
29443
  import {
29319
- existsSync as existsSync3,
29444
+ existsSync as existsSync4,
29320
29445
  mkdirSync as mkdirSync3,
29321
- readFileSync as readFileSync2,
29446
+ readFileSync as readFileSync3,
29322
29447
  writeFileSync as writeFileSync2,
29323
29448
  unlinkSync as unlinkSync2
29324
29449
  } from "node:fs";
29325
- import { join as join3 } from "node:path";
29450
+ import { join as join4 } from "node:path";
29326
29451
  import { tmpdir as tmpdir2 } from "node:os";
29327
29452
  var MAX_INBOX_LIMIT2 = 5;
29328
29453
  var swarmMailProjectDirectory = null;
@@ -29332,16 +29457,16 @@ function setSwarmMailProjectDirectory(directory) {
29332
29457
  function getSwarmMailProjectDirectory() {
29333
29458
  return swarmMailProjectDirectory ?? undefined;
29334
29459
  }
29335
- var SESSION_STATE_DIR2 = process.env.SWARM_STATE_DIR || join3(tmpdir2(), "swarm-sessions");
29460
+ var SESSION_STATE_DIR2 = process.env.SWARM_STATE_DIR || join4(tmpdir2(), "swarm-sessions");
29336
29461
  function getSessionStatePath2(sessionID) {
29337
29462
  const safeID = sessionID.replace(/[^a-zA-Z0-9_-]/g, "_");
29338
- return join3(SESSION_STATE_DIR2, `${safeID}.json`);
29463
+ return join4(SESSION_STATE_DIR2, `${safeID}.json`);
29339
29464
  }
29340
29465
  function loadSessionState2(sessionID) {
29341
29466
  const path = getSessionStatePath2(sessionID);
29342
29467
  try {
29343
- if (existsSync3(path)) {
29344
- const data = readFileSync2(path, "utf-8");
29468
+ if (existsSync4(path)) {
29469
+ const data = readFileSync3(path, "utf-8");
29345
29470
  return JSON.parse(data);
29346
29471
  }
29347
29472
  } catch (error45) {
@@ -29351,7 +29476,7 @@ function loadSessionState2(sessionID) {
29351
29476
  }
29352
29477
  function saveSessionState2(sessionID, state) {
29353
29478
  try {
29354
- if (!existsSync3(SESSION_STATE_DIR2)) {
29479
+ if (!existsSync4(SESSION_STATE_DIR2)) {
29355
29480
  mkdirSync3(SESSION_STATE_DIR2, { recursive: true });
29356
29481
  }
29357
29482
  const path = getSessionStatePath2(sessionID);
@@ -29695,7 +29820,7 @@ function formatZodErrors(error45) {
29695
29820
  var SCHEMA_REGISTRY = {
29696
29821
  evaluation: EvaluationSchema,
29697
29822
  task_decomposition: TaskDecompositionSchema,
29698
- bead_tree: BeadTreeSchema
29823
+ cell_tree: CellTreeSchema
29699
29824
  };
29700
29825
  function getSchemaByName(name) {
29701
29826
  const schema = SCHEMA_REGISTRY[name];
@@ -29831,7 +29956,7 @@ var structured_validate = tool({
29831
29956
  description: "Validate agent response against a schema. Extracts JSON and validates with Zod. Returns structured errors for retry feedback.",
29832
29957
  args: {
29833
29958
  response: tool.schema.string().describe("Agent response to validate"),
29834
- schema_name: tool.schema.enum(["evaluation", "task_decomposition", "bead_tree"]).describe("Schema to validate against: " + "evaluation = agent self-eval with criteria, " + "task_decomposition = swarm task breakdown, " + "bead_tree = epic with subtasks"),
29959
+ schema_name: tool.schema.enum(["evaluation", "task_decomposition", "cell_tree"]).describe("Schema to validate against: " + "evaluation = agent self-eval with criteria, " + "task_decomposition = swarm task breakdown, " + "cell_tree = epic with subtasks"),
29835
29960
  max_retries: tool.schema.number().min(1).max(5).optional().describe("Max retries (for tracking - actual retry logic is external)")
29836
29961
  },
29837
29962
  async execute(args, ctx) {
@@ -30017,15 +30142,15 @@ var structured_parse_decomposition = tool({
30017
30142
  }
30018
30143
  }
30019
30144
  });
30020
- var structured_parse_bead_tree = tool({
30021
- description: "Parse and validate bead tree response. Uses BeadTreeSchema. Validates before creating epic with subtasks.",
30145
+ var structured_parse_cell_tree = tool({
30146
+ description: "Parse and validate bead tree response. Uses CellTreeSchema. Validates before creating epic with subtasks.",
30022
30147
  args: {
30023
30148
  response: tool.schema.string().describe("Agent response containing bead tree")
30024
30149
  },
30025
30150
  async execute(args, ctx) {
30026
30151
  try {
30027
30152
  const [extracted, method] = extractJsonFromText(args.response);
30028
- const validated = BeadTreeSchema.parse(extracted);
30153
+ const validated = CellTreeSchema.parse(extracted);
30029
30154
  const allFiles = validated.subtasks.flatMap((s) => s.files);
30030
30155
  const uniqueFiles = [...new Set(allFiles)];
30031
30156
  return JSON.stringify({
@@ -30084,7 +30209,7 @@ var structuredTools = {
30084
30209
  structured_validate,
30085
30210
  structured_parse_evaluation,
30086
30211
  structured_parse_decomposition,
30087
- structured_parse_bead_tree
30212
+ structured_parse_cell_tree
30088
30213
  };
30089
30214
 
30090
30215
  // src/swarm.ts
@@ -30107,9 +30232,9 @@ var DECOMPOSITION_PROMPT = `You are decomposing a task into parallelizable subta
30107
30232
 
30108
30233
  After decomposition, the coordinator will:
30109
30234
  1. Create an epic bead for the overall task
30110
- 2. Create child beads for each subtask
30235
+ 2. Create child cells for each subtask
30111
30236
  3. Track progress through bead status updates
30112
- 4. Close beads with summaries when complete
30237
+ 4. Close cells with summaries when complete
30113
30238
 
30114
30239
  Agents MUST update their bead status as they work. No silent progress.
30115
30240
 
@@ -30129,7 +30254,7 @@ Respond with a JSON object matching this schema:
30129
30254
  \`\`\`typescript
30130
30255
  {
30131
30256
  epic: {
30132
- title: string, // Epic title for the beads tracker
30257
+ title: string, // Epic title for the hive tracker
30133
30258
  description?: string // Brief description of the overall goal
30134
30259
  },
30135
30260
  subtasks: [
@@ -30180,9 +30305,9 @@ var STRATEGY_DECOMPOSITION_PROMPT = `You are decomposing a task into paralleliza
30180
30305
 
30181
30306
  After decomposition, the coordinator will:
30182
30307
  1. Create an epic bead for the overall task
30183
- 2. Create child beads for each subtask
30308
+ 2. Create child cells for each subtask
30184
30309
  3. Track progress through bead status updates
30185
- 4. Close beads with summaries when complete
30310
+ 4. Close cells with summaries when complete
30186
30311
 
30187
30312
  Agents MUST update their bead status as they work. No silent progress.
30188
30313
 
@@ -30202,7 +30327,7 @@ Respond with a JSON object matching this schema:
30202
30327
  \`\`\`typescript
30203
30328
  {
30204
30329
  epic: {
30205
- title: string, // Epic title for the beads tracker
30330
+ title: string, // Epic title for the hive tracker
30206
30331
  description?: string // Brief description of the overall goal
30207
30332
  },
30208
30333
  subtasks: [
@@ -30392,7 +30517,7 @@ ${fullContext}` : `## Additional Context
30392
30517
  const prompt = DECOMPOSITION_PROMPT.replace("{task}", args.task).replace("{max_subtasks}", (args.max_subtasks ?? 5).toString()).replace("{context_section}", contextSection);
30393
30518
  return JSON.stringify({
30394
30519
  prompt,
30395
- expected_schema: "BeadTree",
30520
+ expected_schema: "CellTree",
30396
30521
  schema_hint: {
30397
30522
  epic: { title: "string", description: "string?" },
30398
30523
  subtasks: [
@@ -30405,21 +30530,21 @@ ${fullContext}` : `## Additional Context
30405
30530
  }
30406
30531
  ]
30407
30532
  },
30408
- validation_note: "Parse agent response as JSON and validate with BeadTreeSchema from schemas/bead.ts",
30533
+ validation_note: "Parse agent response as JSON and validate with CellTreeSchema from schemas/bead.ts",
30409
30534
  cass_history: cassResultInfo,
30410
30535
  memory_query: formatMemoryQueryForDecomposition2(args.task, 3)
30411
30536
  }, null, 2);
30412
30537
  }
30413
30538
  });
30414
30539
  var swarm_validate_decomposition = tool({
30415
- description: "Validate a decomposition response against BeadTreeSchema",
30540
+ description: "Validate a decomposition response against CellTreeSchema",
30416
30541
  args: {
30417
- response: tool.schema.string().describe("JSON response from agent (BeadTree format)")
30542
+ response: tool.schema.string().describe("JSON response from agent (CellTree format)")
30418
30543
  },
30419
30544
  async execute(args) {
30420
30545
  try {
30421
30546
  const parsed = JSON.parse(args.response);
30422
- const validated = BeadTreeSchema.parse(parsed);
30547
+ const validated = CellTreeSchema.parse(parsed);
30423
30548
  const conflicts = detectFileConflicts(validated.subtasks);
30424
30549
  if (conflicts.length > 0) {
30425
30550
  return JSON.stringify({
@@ -30450,7 +30575,7 @@ var swarm_validate_decomposition = tool({
30450
30575
  const instructionConflicts = detectInstructionConflicts(validated.subtasks);
30451
30576
  return JSON.stringify({
30452
30577
  valid: true,
30453
- bead_tree: validated,
30578
+ cell_tree: validated,
30454
30579
  stats: {
30455
30580
  subtask_count: validated.subtasks.length,
30456
30581
  total_files: new Set(validated.subtasks.flatMap((s) => s.files)).size,
@@ -30552,7 +30677,7 @@ ${args.context}` : `## Additional Context
30552
30677
  const subagentInstructions = `
30553
30678
  ## CRITICAL: Output Format
30554
30679
 
30555
- You are a planner subagent. Your ONLY output must be valid JSON matching the BeadTree schema.
30680
+ You are a planner subagent. Your ONLY output must be valid JSON matching the CellTree schema.
30556
30681
 
30557
30682
  DO NOT include:
30558
30683
  - Explanatory text before or after the JSON
@@ -30586,7 +30711,7 @@ OUTPUT ONLY the raw JSON object.
30586
30711
  ]
30587
30712
  }
30588
30713
 
30589
- Now generate the BeadTree for the given task.`;
30714
+ Now generate the CellTree for the given task.`;
30590
30715
  const fullPrompt = `${planningPrompt}
30591
30716
 
30592
30717
  ${subagentInstructions}`;
@@ -30598,12 +30723,12 @@ ${subagentInstructions}`;
30598
30723
  selected: selectedStrategy,
30599
30724
  reasoning: strategyReasoning
30600
30725
  },
30601
- expected_output: "BeadTree JSON (raw JSON, no markdown)",
30726
+ expected_output: "CellTree JSON (raw JSON, no markdown)",
30602
30727
  next_steps: [
30603
30728
  "1. Spawn subagent with Task tool using returned prompt",
30604
30729
  "2. Parse subagent response as JSON",
30605
30730
  "3. Validate with swarm_validate_decomposition",
30606
- "4. Create beads with beads_create_epic"
30731
+ "4. Create cells with hive_create_epic"
30607
30732
  ],
30608
30733
  cass_history: cassResultInfo,
30609
30734
  skills: skillsInfo,
@@ -30843,17 +30968,17 @@ var STRATEGY_DECOMPOSITION_PROMPT2 = `You are decomposing a task into paralleliz
30843
30968
 
30844
30969
  {skills_context}
30845
30970
 
30846
- ## MANDATORY: Beads Issue Tracking
30971
+ ## MANDATORY: Hive Issue Tracking
30847
30972
 
30848
- **Every subtask MUST become a bead.** This is non-negotiable.
30973
+ **Every subtask MUST become a cell.** This is non-negotiable.
30849
30974
 
30850
30975
  After decomposition, the coordinator will:
30851
- 1. Create an epic bead for the overall task
30852
- 2. Create child beads for each subtask
30853
- 3. Track progress through bead status updates
30854
- 4. Close beads with summaries when complete
30976
+ 1. Create an epic cell for the overall task
30977
+ 2. Create child cells for each subtask
30978
+ 3. Track progress through cell status updates
30979
+ 4. Close cells with summaries when complete
30855
30980
 
30856
- Agents MUST update their bead status as they work. No silent progress.
30981
+ Agents MUST update their cell status as they work. No silent progress.
30857
30982
 
30858
30983
  ## Requirements
30859
30984
 
@@ -30871,7 +30996,7 @@ Respond with a JSON object matching this schema:
30871
30996
  \`\`\`typescript
30872
30997
  {
30873
30998
  epic: {
30874
- title: string, // Epic title for the beads tracker
30999
+ title: string, // Epic title for the hive tracker
30875
31000
  description?: string // Brief description of the overall goal
30876
31001
  },
30877
31002
  subtasks: [
@@ -30892,7 +31017,7 @@ var SUBTASK_PROMPT = `You are a swarm agent working on a subtask of a larger epi
30892
31017
 
30893
31018
  ## Your Identity
30894
31019
  - **Agent Name**: {agent_name}
30895
- - **Bead ID**: {bead_id}
31020
+ - **Cell ID**: {bead_id}
30896
31021
  - **Epic ID**: {epic_id}
30897
31022
 
30898
31023
  ## Your Subtask
@@ -30910,16 +31035,16 @@ send a message to the coordinator requesting the change.
30910
31035
  ## Shared Context
30911
31036
  {shared_context}
30912
31037
 
30913
- ## MANDATORY: Beads Tracking
31038
+ ## MANDATORY: Hive Tracking
30914
31039
 
30915
- You MUST keep your bead updated as you work:
31040
+ You MUST keep your cell updated as you work:
30916
31041
 
30917
- 1. **Your bead is already in_progress** - don't change this unless blocked
30918
- 2. **If blocked**: \`bd update {bead_id} --status blocked\` and message coordinator
30919
- 3. **When done**: Use \`swarm_complete\` - it closes your bead automatically
30920
- 4. **Discovered issues**: Create new beads with \`bd create "issue" -t bug\`
31042
+ 1. **Your cell is already in_progress** - don't change this unless blocked
31043
+ 2. **If blocked**: \`hive_update {bead_id} --status blocked\` and message coordinator
31044
+ 3. **When done**: Use \`swarm_complete\` - it closes your cell automatically
31045
+ 4. **Discovered issues**: Create new cells with \`hive_create "issue" -t bug\`
30921
31046
 
30922
- **Never work silently.** Your bead status is how the swarm tracks progress.
31047
+ **Never work silently.** Your cell status is how the swarm tracks progress.
30923
31048
 
30924
31049
  ## MANDATORY: Swarm Mail Communication
30925
31050
 
@@ -30942,11 +31067,11 @@ swarmmail_send(
30942
31067
 
30943
31068
  ## Coordination Protocol
30944
31069
 
30945
- 1. **Start**: Your bead is already marked in_progress
31070
+ 1. **Start**: Your cell is already marked in_progress
30946
31071
  2. **Progress**: Use swarm_progress to report status updates
30947
31072
  3. **Blocked**: Report immediately via Swarm Mail - don't spin
30948
31073
  4. **Complete**: Use swarm_complete when done - it handles:
30949
- - Closing your bead with a summary
31074
+ - Closing your cell with a summary
30950
31075
  - Releasing file reservations
30951
31076
  - Notifying the coordinator
30952
31077
 
@@ -30973,7 +31098,7 @@ var SUBTASK_PROMPT_V2 = `You are a swarm agent working on: **{subtask_title}**
30973
31098
 
30974
31099
  ## [IDENTITY]
30975
31100
  Agent: (assigned at spawn)
30976
- Bead: {bead_id}
31101
+ Cell: {bead_id}
30977
31102
  Epic: {epic_id}
30978
31103
 
30979
31104
  ## [TASK]
@@ -31117,7 +31242,7 @@ swarm_complete(
31117
31242
  - Records learning signals
31118
31243
  - Notifies coordinator
31119
31244
 
31120
- **DO NOT manually close the bead with beads_close.** Use swarm_complete.
31245
+ **DO NOT manually close the cell with hive_close.** Use swarm_complete.
31121
31246
 
31122
31247
  ## [SWARM MAIL COMMUNICATION]
31123
31248
 
@@ -31136,7 +31261,7 @@ swarmmail_send(
31136
31261
  importance="high",
31137
31262
  thread_id="{epic_id}"
31138
31263
  )
31139
- beads_update(id="{bead_id}", status="blocked")
31264
+ hive_update(id="{bead_id}", status="blocked")
31140
31265
  \`\`\`
31141
31266
 
31142
31267
  ### Report Issues to Other Agents
@@ -31157,15 +31282,15 @@ swarmmail_release() # Manually release reservations
31157
31282
  **Note:** \`swarm_complete\` automatically releases reservations. Only use manual release if aborting work.
31158
31283
 
31159
31284
  ## [OTHER TOOLS]
31160
- ### Beads - You Have Autonomy to File Issues
31161
- You can create new beads against this epic when you discover:
31285
+ ### Hive - You Have Autonomy to File Issues
31286
+ You can create new cells against this epic when you discover:
31162
31287
  - **Bugs**: Found a bug while working? File it.
31163
31288
  - **Tech debt**: Spotted something that needs cleanup? File it.
31164
31289
  - **Follow-up work**: Task needs more work than scoped? File a follow-up.
31165
31290
  - **Dependencies**: Need something from another agent? File and link it.
31166
31291
 
31167
31292
  \`\`\`
31168
- beads_create(
31293
+ hive_create(
31169
31294
  title="<descriptive title>",
31170
31295
  type="bug", # or "task", "chore"
31171
31296
  priority=2,
@@ -31176,9 +31301,9 @@ beads_create(
31176
31301
 
31177
31302
  **Don't silently ignore issues.** File them so they get tracked and addressed.
31178
31303
 
31179
- Other bead operations:
31180
- - beads_update(id, status) - Mark blocked if stuck
31181
- - beads_query(status="open") - See what else needs work
31304
+ Other cell operations:
31305
+ - hive_update(id, status) - Mark blocked if stuck
31306
+ - hive_query(status="open") - See what else needs work
31182
31307
 
31183
31308
  ### Skills
31184
31309
  - skills_list() - Discover available skills
@@ -31192,7 +31317,7 @@ Other bead operations:
31192
31317
  2. Step 2 (semantic-memory_find) MUST happen before starting work
31193
31318
  3. Step 4 (swarmmail_reserve) - YOU reserve files, not coordinator
31194
31319
  4. Step 6 (swarm_progress) - Report at milestones, don't work silently
31195
- 5. Step 9 (swarm_complete) - Use this to close, NOT beads_close
31320
+ 5. Step 9 (swarm_complete) - Use this to close, NOT hive_close
31196
31321
 
31197
31322
  **If you skip these steps:**
31198
31323
  - Your work won't be tracked (swarm_complete will fail)
@@ -31205,7 +31330,7 @@ Begin now.`;
31205
31330
  var EVALUATION_PROMPT = `Evaluate the work completed for this subtask.
31206
31331
 
31207
31332
  ## Subtask
31208
- **Bead ID**: {bead_id}
31333
+ **Cell ID**: {bead_id}
31209
31334
  **Title**: {subtask_title}
31210
31335
 
31211
31336
  ## Files Modified
@@ -31307,7 +31432,7 @@ var swarm_subtask_prompt = tool({
31307
31432
  }
31308
31433
  });
31309
31434
  var swarm_spawn_subtask = tool({
31310
- description: "Prepare a subtask for spawning. Returns prompt with Agent Mail/beads instructions. IMPORTANT: Pass project_path for swarmmail_init.",
31435
+ description: "Prepare a subtask for spawning. Returns prompt with Agent Mail/hive tracking instructions. IMPORTANT: Pass project_path for swarmmail_init.",
31311
31436
  args: {
31312
31437
  bead_id: tool.schema.string().describe("Subtask bead ID"),
31313
31438
  epic_id: tool.schema.string().describe("Parent epic bead ID"),
@@ -31432,7 +31557,7 @@ ${args.context}` : `## Additional Context
31432
31557
  guidelines: STRATEGIES2[selectedStrategy].guidelines,
31433
31558
  anti_patterns: STRATEGIES2[selectedStrategy].antiPatterns
31434
31559
  },
31435
- expected_schema: "BeadTree",
31560
+ expected_schema: "CellTree",
31436
31561
  schema_hint: {
31437
31562
  epic: { title: "string", description: "string?" },
31438
31563
  subtasks: [
@@ -31464,12 +31589,672 @@ init_learning();
31464
31589
  import {
31465
31590
  getSwarmInbox as getSwarmInbox2,
31466
31591
  releaseSwarmFiles as releaseSwarmFiles2,
31467
- sendSwarmMessage as sendSwarmMessage2,
31592
+ sendSwarmMessage as sendSwarmMessage3,
31468
31593
  getAgent,
31469
31594
  createEvent as createEvent2,
31470
31595
  appendEvent as appendEvent2
31471
31596
  } from "swarm-mail";
31472
31597
  init_skills();
31598
+
31599
+ // src/swarm-worktree.ts
31600
+ init_dist();
31601
+ init_zod();
31602
+ import { join as join6 } from "node:path";
31603
+ import { existsSync as existsSync5 } from "node:fs";
31604
+ var WORKTREE_DIR = ".swarm/worktrees";
31605
+ function getWorktreePath(projectPath, taskId) {
31606
+ const safeTaskId = taskId.replace(/[^a-zA-Z0-9.-]/g, "_");
31607
+ return join6(projectPath, WORKTREE_DIR, safeTaskId);
31608
+ }
31609
+ function parseTaskIdFromPath(worktreePath) {
31610
+ const parts = worktreePath.split("/");
31611
+ const worktreesIdx = parts.indexOf("worktrees");
31612
+ if (worktreesIdx >= 0 && worktreesIdx < parts.length - 1) {
31613
+ return parts[worktreesIdx + 1];
31614
+ }
31615
+ return null;
31616
+ }
31617
+ async function isGitRepo(path) {
31618
+ const result = await Bun.$`git -C ${path} rev-parse --git-dir`.quiet().nothrow();
31619
+ return result.exitCode === 0;
31620
+ }
31621
+ async function hasUncommittedChanges(path) {
31622
+ const result = await Bun.$`git -C ${path} status --porcelain`.quiet().nothrow();
31623
+ if (result.exitCode !== 0)
31624
+ return true;
31625
+ return result.stdout.toString().trim().length > 0;
31626
+ }
31627
+ async function getCurrentCommit(path) {
31628
+ const result = await Bun.$`git -C ${path} rev-parse HEAD`.quiet().nothrow();
31629
+ if (result.exitCode !== 0)
31630
+ return null;
31631
+ return result.stdout.toString().trim();
31632
+ }
31633
+ async function getWorktreeCommits(worktreePath, startCommit) {
31634
+ const result = await Bun.$`git -C ${worktreePath} log --format=%H ${startCommit}..HEAD`.quiet().nothrow();
31635
+ if (result.exitCode !== 0)
31636
+ return [];
31637
+ return result.stdout.toString().trim().split(`
31638
+ `).filter((c) => c.length > 0);
31639
+ }
31640
+ async function ensureWorktreeDir(projectPath) {
31641
+ const worktreeDir = join6(projectPath, WORKTREE_DIR);
31642
+ await Bun.$`mkdir -p ${worktreeDir}`.quiet().nothrow();
31643
+ }
31644
+ var swarm_worktree_create = tool({
31645
+ description: "Create a git worktree for isolated task execution. Worker operates in worktree, not main branch.",
31646
+ args: {
31647
+ project_path: exports_external.string().describe("Absolute path to project root"),
31648
+ task_id: exports_external.string().describe("Task/bead ID (e.g., bd-abc123.1)"),
31649
+ start_commit: exports_external.string().describe("Commit SHA to create worktree at (swarm start point)")
31650
+ },
31651
+ async execute(args) {
31652
+ if (!await isGitRepo(args.project_path)) {
31653
+ const result2 = {
31654
+ success: false,
31655
+ error: `${args.project_path} is not a git repository`
31656
+ };
31657
+ return JSON.stringify(result2, null, 2);
31658
+ }
31659
+ const worktreePath = getWorktreePath(args.project_path, args.task_id);
31660
+ const exists = existsSync5(worktreePath);
31661
+ if (exists) {
31662
+ const result2 = {
31663
+ success: false,
31664
+ error: `Worktree already exists for task ${args.task_id}`,
31665
+ worktree_path: worktreePath
31666
+ };
31667
+ return JSON.stringify(result2, null, 2);
31668
+ }
31669
+ await ensureWorktreeDir(args.project_path);
31670
+ const createResult = await Bun.$`git -C ${args.project_path} worktree add --detach ${worktreePath} ${args.start_commit}`.quiet().nothrow();
31671
+ if (createResult.exitCode !== 0) {
31672
+ const result2 = {
31673
+ success: false,
31674
+ error: `Failed to create worktree: ${createResult.stderr.toString()}`
31675
+ };
31676
+ return JSON.stringify(result2, null, 2);
31677
+ }
31678
+ const result = {
31679
+ success: true,
31680
+ worktree_path: worktreePath,
31681
+ task_id: args.task_id,
31682
+ created_at_commit: args.start_commit
31683
+ };
31684
+ return JSON.stringify(result, null, 2);
31685
+ }
31686
+ });
31687
+ var swarm_worktree_merge = tool({
31688
+ description: "Cherry-pick commits from worktree back to main branch. Call after worker completes.",
31689
+ args: {
31690
+ project_path: exports_external.string().describe("Absolute path to project root"),
31691
+ task_id: exports_external.string().describe("Task/bead ID"),
31692
+ start_commit: exports_external.string().optional().describe("Original start commit (to find new commits)")
31693
+ },
31694
+ async execute(args) {
31695
+ const worktreePath = getWorktreePath(args.project_path, args.task_id);
31696
+ const exists = existsSync5(worktreePath);
31697
+ if (!exists) {
31698
+ const result2 = {
31699
+ success: false,
31700
+ error: `Worktree not found for task ${args.task_id}`
31701
+ };
31702
+ return JSON.stringify(result2, null, 2);
31703
+ }
31704
+ let startCommit = args.start_commit;
31705
+ if (!startCommit) {
31706
+ const mergeBaseResult = await Bun.$`git -C ${args.project_path} merge-base HEAD ${worktreePath}`.quiet().nothrow();
31707
+ if (mergeBaseResult.exitCode === 0) {
31708
+ startCommit = mergeBaseResult.stdout.toString().trim();
31709
+ }
31710
+ }
31711
+ if (!startCommit) {
31712
+ const result2 = {
31713
+ success: false,
31714
+ error: "Could not determine start commit for cherry-pick"
31715
+ };
31716
+ return JSON.stringify(result2, null, 2);
31717
+ }
31718
+ const commits = await getWorktreeCommits(worktreePath, startCommit);
31719
+ if (commits.length === 0) {
31720
+ const result2 = {
31721
+ success: false,
31722
+ error: `Worktree has no commits since ${startCommit.slice(0, 7)}`
31723
+ };
31724
+ return JSON.stringify(result2, null, 2);
31725
+ }
31726
+ const reversedCommits = commits.reverse();
31727
+ let lastMergedCommit = null;
31728
+ for (const commit of reversedCommits) {
31729
+ const cherryResult = await Bun.$`git -C ${args.project_path} cherry-pick ${commit}`.quiet().nothrow();
31730
+ if (cherryResult.exitCode !== 0) {
31731
+ const stderr = cherryResult.stderr.toString();
31732
+ if (stderr.includes("conflict") || stderr.includes("CONFLICT")) {
31733
+ const statusResult = await Bun.$`git -C ${args.project_path} status --porcelain`.quiet().nothrow();
31734
+ const conflictingFiles = statusResult.stdout.toString().split(`
31735
+ `).filter((line) => line.startsWith("UU") || line.startsWith("AA")).map((line) => line.slice(3).trim());
31736
+ await Bun.$`git -C ${args.project_path} cherry-pick --abort`.quiet().nothrow();
31737
+ const result3 = {
31738
+ success: false,
31739
+ error: `Merge conflict during cherry-pick of ${commit.slice(0, 7)}`,
31740
+ conflicting_files: conflictingFiles
31741
+ };
31742
+ return JSON.stringify(result3, null, 2);
31743
+ }
31744
+ const result2 = {
31745
+ success: false,
31746
+ error: `Failed to cherry-pick ${commit.slice(0, 7)}: ${stderr}`
31747
+ };
31748
+ return JSON.stringify(result2, null, 2);
31749
+ }
31750
+ lastMergedCommit = commit;
31751
+ }
31752
+ const result = {
31753
+ success: true,
31754
+ task_id: args.task_id,
31755
+ merged_commit: lastMergedCommit || undefined
31756
+ };
31757
+ return JSON.stringify(result, null, 2);
31758
+ }
31759
+ });
31760
+ var swarm_worktree_cleanup = tool({
31761
+ description: "Remove a worktree after completion or abort. Idempotent - safe to call multiple times.",
31762
+ args: {
31763
+ project_path: exports_external.string().describe("Absolute path to project root"),
31764
+ task_id: exports_external.string().optional().describe("Task/bead ID to clean up"),
31765
+ cleanup_all: exports_external.boolean().optional().describe("Remove all worktrees for this project")
31766
+ },
31767
+ async execute(args) {
31768
+ if (args.cleanup_all) {
31769
+ const listResult = await Bun.$`git -C ${args.project_path} worktree list --porcelain`.quiet().nothrow();
31770
+ if (listResult.exitCode !== 0) {
31771
+ const result3 = {
31772
+ success: false,
31773
+ error: `Failed to list worktrees: ${listResult.stderr.toString()}`
31774
+ };
31775
+ return JSON.stringify(result3, null, 2);
31776
+ }
31777
+ const output = listResult.stdout.toString();
31778
+ const worktreeDir = join6(args.project_path, WORKTREE_DIR);
31779
+ const worktrees = output.split(`
31780
+
31781
+ `).filter((block) => block.includes(worktreeDir)).map((block) => {
31782
+ const pathMatch = block.match(/^worktree (.+)$/m);
31783
+ return pathMatch ? pathMatch[1] : null;
31784
+ }).filter((p) => p !== null);
31785
+ let removedCount = 0;
31786
+ for (const wt of worktrees) {
31787
+ const removeResult2 = await Bun.$`git -C ${args.project_path} worktree remove --force ${wt}`.quiet().nothrow();
31788
+ if (removeResult2.exitCode === 0) {
31789
+ removedCount++;
31790
+ }
31791
+ }
31792
+ const result2 = {
31793
+ success: true,
31794
+ removed_count: removedCount
31795
+ };
31796
+ return JSON.stringify(result2, null, 2);
31797
+ }
31798
+ if (!args.task_id) {
31799
+ const result2 = {
31800
+ success: false,
31801
+ error: "Either task_id or cleanup_all must be provided"
31802
+ };
31803
+ return JSON.stringify(result2, null, 2);
31804
+ }
31805
+ const worktreePath = getWorktreePath(args.project_path, args.task_id);
31806
+ const exists = existsSync5(worktreePath);
31807
+ if (!exists) {
31808
+ const result2 = {
31809
+ success: true,
31810
+ already_removed: true,
31811
+ removed_path: worktreePath
31812
+ };
31813
+ return JSON.stringify(result2, null, 2);
31814
+ }
31815
+ const removeResult = await Bun.$`git -C ${args.project_path} worktree remove --force ${worktreePath}`.quiet().nothrow();
31816
+ if (removeResult.exitCode !== 0) {
31817
+ await Bun.$`rm -rf ${worktreePath}`.quiet().nothrow();
31818
+ await Bun.$`git -C ${args.project_path} worktree prune`.quiet().nothrow();
31819
+ }
31820
+ const result = {
31821
+ success: true,
31822
+ removed_path: worktreePath,
31823
+ task_id: args.task_id
31824
+ };
31825
+ return JSON.stringify(result, null, 2);
31826
+ }
31827
+ });
31828
+ var swarm_worktree_list = tool({
31829
+ description: "List all active worktrees for a project",
31830
+ args: {
31831
+ project_path: exports_external.string().describe("Absolute path to project root")
31832
+ },
31833
+ async execute(args) {
31834
+ const listResult = await Bun.$`git -C ${args.project_path} worktree list --porcelain`.quiet().nothrow();
31835
+ if (listResult.exitCode !== 0) {
31836
+ return JSON.stringify({
31837
+ worktrees: [],
31838
+ count: 0,
31839
+ error: `Failed to list worktrees: ${listResult.stderr.toString()}`
31840
+ }, null, 2);
31841
+ }
31842
+ const output = listResult.stdout.toString();
31843
+ const worktreeDir = join6(args.project_path, WORKTREE_DIR);
31844
+ const worktrees = [];
31845
+ const blocks = output.split(`
31846
+
31847
+ `).filter((b) => b.trim());
31848
+ for (const block of blocks) {
31849
+ const pathMatch = block.match(/^worktree (.+)$/m);
31850
+ const commitMatch = block.match(/^HEAD ([a-f0-9]+)$/m);
31851
+ const branchMatch = block.match(/^branch (.+)$/m);
31852
+ if (pathMatch && pathMatch[1].includes(worktreeDir)) {
31853
+ const path = pathMatch[1];
31854
+ const taskId = parseTaskIdFromPath(path);
31855
+ if (taskId) {
31856
+ worktrees.push({
31857
+ task_id: taskId,
31858
+ path,
31859
+ commit: commitMatch ? commitMatch[1] : "unknown",
31860
+ branch: branchMatch ? branchMatch[1] : undefined
31861
+ });
31862
+ }
31863
+ }
31864
+ }
31865
+ return JSON.stringify({
31866
+ worktrees,
31867
+ count: worktrees.length
31868
+ }, null, 2);
31869
+ }
31870
+ });
31871
+ async function canUseWorktreeIsolation(projectPath) {
31872
+ if (!await isGitRepo(projectPath)) {
31873
+ return { canUse: false, reason: "Not a git repository" };
31874
+ }
31875
+ if (await hasUncommittedChanges(projectPath)) {
31876
+ return {
31877
+ canUse: false,
31878
+ reason: "Uncommitted changes exist - commit or stash first"
31879
+ };
31880
+ }
31881
+ return { canUse: true };
31882
+ }
31883
+ async function getStartCommit(projectPath) {
31884
+ return getCurrentCommit(projectPath);
31885
+ }
31886
+ var worktreeTools = {
31887
+ swarm_worktree_create,
31888
+ swarm_worktree_merge,
31889
+ swarm_worktree_cleanup,
31890
+ swarm_worktree_list
31891
+ };
31892
+
31893
+ // src/swarm-review.ts
31894
+ init_dist();
31895
+ init_zod();
31896
+ import { sendSwarmMessage as sendSwarmMessage2 } from "swarm-mail";
31897
+ var ReviewIssueSchema = exports_external.object({
31898
+ file: exports_external.string(),
31899
+ line: exports_external.number().optional(),
31900
+ issue: exports_external.string(),
31901
+ suggestion: exports_external.string().optional()
31902
+ });
31903
+ var ReviewResultSchema = exports_external.object({
31904
+ status: exports_external.enum(["approved", "needs_changes"]),
31905
+ summary: exports_external.string().optional(),
31906
+ issues: exports_external.array(ReviewIssueSchema).optional(),
31907
+ remaining_attempts: exports_external.number().optional()
31908
+ }).refine((data) => {
31909
+ if (data.status === "needs_changes") {
31910
+ return data.issues && data.issues.length > 0;
31911
+ }
31912
+ return true;
31913
+ }, {
31914
+ message: "issues array is required when status is 'needs_changes'"
31915
+ });
31916
+ var reviewAttempts = new Map;
31917
+ var MAX_REVIEW_ATTEMPTS = 3;
31918
+ function getAttemptCount(taskId) {
31919
+ return reviewAttempts.get(taskId) || 0;
31920
+ }
31921
+ function incrementAttempt(taskId) {
31922
+ const current = getAttemptCount(taskId);
31923
+ const newCount = current + 1;
31924
+ reviewAttempts.set(taskId, newCount);
31925
+ return newCount;
31926
+ }
31927
+ function clearAttempts(taskId) {
31928
+ reviewAttempts.delete(taskId);
31929
+ }
31930
+ function getRemainingAttempts(taskId) {
31931
+ return MAX_REVIEW_ATTEMPTS - getAttemptCount(taskId);
31932
+ }
31933
+ function generateReviewPrompt(context) {
31934
+ const sections = [];
31935
+ sections.push(`# Code Review: ${context.task_title}`);
31936
+ sections.push("");
31937
+ sections.push("## Epic Goal");
31938
+ sections.push(`**${context.epic_title}**`);
31939
+ if (context.epic_description) {
31940
+ sections.push(context.epic_description);
31941
+ }
31942
+ sections.push("");
31943
+ sections.push("## Task Requirements");
31944
+ sections.push(`**${context.task_title}**`);
31945
+ if (context.task_description) {
31946
+ sections.push(context.task_description);
31947
+ }
31948
+ sections.push("");
31949
+ if (context.completed_dependencies && context.completed_dependencies.length > 0) {
31950
+ sections.push("## This Task Builds On");
31951
+ for (const dep of context.completed_dependencies) {
31952
+ sections.push(`- **${dep.title}** (${dep.id})`);
31953
+ if (dep.summary) {
31954
+ sections.push(` ${dep.summary}`);
31955
+ }
31956
+ }
31957
+ sections.push("");
31958
+ }
31959
+ if (context.downstream_tasks && context.downstream_tasks.length > 0) {
31960
+ sections.push("## Downstream Tasks (depend on this)");
31961
+ for (const task of context.downstream_tasks) {
31962
+ sections.push(`- **${task.title}** (${task.id})`);
31963
+ }
31964
+ sections.push("");
31965
+ }
31966
+ sections.push("## Files Modified");
31967
+ for (const file2 of context.files_touched) {
31968
+ sections.push(`- \`${file2}\``);
31969
+ }
31970
+ sections.push("");
31971
+ sections.push("## Code Changes");
31972
+ sections.push("```diff");
31973
+ sections.push(context.diff);
31974
+ sections.push("```");
31975
+ sections.push("");
31976
+ sections.push("## Review Criteria");
31977
+ sections.push("");
31978
+ sections.push("Please evaluate the changes against these criteria:");
31979
+ sections.push("");
31980
+ sections.push("1. **Fulfills Requirements**: Does the code implement what the task requires?");
31981
+ sections.push("2. **Serves Epic Goal**: Does this work contribute to the overall epic objective?");
31982
+ sections.push("3. **Enables Downstream**: Can downstream tasks use this work as expected?");
31983
+ sections.push("4. **Type Safety**: Are types correct and complete?");
31984
+ sections.push("5. **No Critical Bugs**: Are there any obvious bugs or issues?");
31985
+ sections.push("6. **Test Coverage**: Are there tests for the new code? (warning only)");
31986
+ sections.push("");
31987
+ sections.push("## Response Format");
31988
+ sections.push("");
31989
+ sections.push("Respond with a JSON object:");
31990
+ sections.push("```json");
31991
+ sections.push(`{
31992
+ "status": "approved" | "needs_changes",
31993
+ "summary": "Brief summary of your review",
31994
+ "issues": [
31995
+ {
31996
+ "file": "path/to/file.ts",
31997
+ "line": 42,
31998
+ "issue": "Description of the problem",
31999
+ "suggestion": "How to fix it"
32000
+ }
32001
+ ]
32002
+ }`);
32003
+ sections.push("```");
32004
+ return sections.join(`
32005
+ `);
32006
+ }
32007
+ async function getHiveAdapterSafe(projectPath) {
32008
+ try {
32009
+ return getHiveAdapter(projectPath);
32010
+ } catch {
32011
+ return null;
32012
+ }
32013
+ }
32014
+ async function getCellDependencies(adapter, projectKey, _cellId, epicId) {
32015
+ const completedDependencies = [];
32016
+ const downstreamTasks = [];
32017
+ try {
32018
+ const subtasks = await adapter.queryCells(projectKey, { parent_id: epicId });
32019
+ for (const subtask of subtasks) {
32020
+ if (subtask.id === _cellId)
32021
+ continue;
32022
+ if (subtask.status === "closed") {
32023
+ completedDependencies.push({
32024
+ id: subtask.id,
32025
+ title: subtask.title,
32026
+ summary: subtask.closed_reason ?? undefined
32027
+ });
32028
+ }
32029
+ if (subtask.status !== "closed") {
32030
+ downstreamTasks.push({
32031
+ id: subtask.id,
32032
+ title: subtask.title
32033
+ });
32034
+ }
32035
+ }
32036
+ } catch {}
32037
+ return { completed: completedDependencies, downstream: downstreamTasks };
32038
+ }
32039
+ var swarm_review = tool({
32040
+ description: "Generate a review prompt for a completed subtask. Includes epic context, dependencies, and diff.",
32041
+ args: {
32042
+ project_key: exports_external.string().describe("Project path"),
32043
+ epic_id: exports_external.string().describe("Epic cell ID"),
32044
+ task_id: exports_external.string().describe("Subtask cell ID to review"),
32045
+ files_touched: exports_external.array(exports_external.string()).optional().describe("Files modified (will get diff for these)")
32046
+ },
32047
+ async execute(args) {
32048
+ let epicTitle = args.epic_id;
32049
+ let epicDescription;
32050
+ let taskTitle = args.task_id;
32051
+ let taskDescription;
32052
+ let completedDependencies = [];
32053
+ let downstreamTasks = [];
32054
+ const adapter = await getHiveAdapterSafe(args.project_key);
32055
+ if (adapter) {
32056
+ try {
32057
+ const epic = await adapter.getCell(args.project_key, args.epic_id);
32058
+ if (epic) {
32059
+ epicTitle = epic.title || epicTitle;
32060
+ epicDescription = epic.description ?? undefined;
32061
+ }
32062
+ const task = await adapter.getCell(args.project_key, args.task_id);
32063
+ if (task) {
32064
+ taskTitle = task.title || taskTitle;
32065
+ taskDescription = task.description ?? undefined;
32066
+ }
32067
+ const deps = await getCellDependencies(adapter, args.project_key, args.task_id, args.epic_id);
32068
+ completedDependencies = deps.completed;
32069
+ downstreamTasks = deps.downstream;
32070
+ } catch {}
32071
+ }
32072
+ let diff = "";
32073
+ if (args.files_touched && args.files_touched.length > 0) {
32074
+ try {
32075
+ const diffResult = await Bun.$`git diff HEAD~1 -- ${args.files_touched}`.cwd(args.project_key).quiet().nothrow();
32076
+ if (diffResult.exitCode === 0) {
32077
+ diff = diffResult.stdout.toString();
32078
+ } else {
32079
+ const stagedResult = await Bun.$`git diff --cached -- ${args.files_touched}`.cwd(args.project_key).quiet().nothrow();
32080
+ diff = stagedResult.stdout.toString();
32081
+ }
32082
+ } catch {}
32083
+ }
32084
+ const reviewPrompt = generateReviewPrompt({
32085
+ epic_id: args.epic_id,
32086
+ epic_title: epicTitle,
32087
+ epic_description: epicDescription,
32088
+ task_id: args.task_id,
32089
+ task_title: taskTitle,
32090
+ task_description: taskDescription,
32091
+ files_touched: args.files_touched || [],
32092
+ diff: diff || "(no diff available)",
32093
+ completed_dependencies: completedDependencies.length > 0 ? completedDependencies : undefined,
32094
+ downstream_tasks: downstreamTasks.length > 0 ? downstreamTasks : undefined
32095
+ });
32096
+ return JSON.stringify({
32097
+ review_prompt: reviewPrompt,
32098
+ context: {
32099
+ epic_id: args.epic_id,
32100
+ epic_title: epicTitle,
32101
+ task_id: args.task_id,
32102
+ task_title: taskTitle,
32103
+ files_touched: args.files_touched || [],
32104
+ completed_dependencies: completedDependencies.length,
32105
+ downstream_tasks: downstreamTasks.length,
32106
+ remaining_attempts: getRemainingAttempts(args.task_id)
32107
+ }
32108
+ }, null, 2);
32109
+ }
32110
+ });
32111
+ var swarm_review_feedback = tool({
32112
+ description: "Send review feedback to a worker. Tracks attempts (max 3). Fails task after 3 rejections.",
32113
+ args: {
32114
+ project_key: exports_external.string().describe("Project path"),
32115
+ task_id: exports_external.string().describe("Subtask cell ID"),
32116
+ worker_id: exports_external.string().describe("Worker agent name"),
32117
+ status: exports_external.enum(["approved", "needs_changes"]).describe("Review status"),
32118
+ summary: exports_external.string().optional().describe("Review summary"),
32119
+ issues: exports_external.string().optional().describe("JSON array of ReviewIssue objects (for needs_changes)")
32120
+ },
32121
+ async execute(args) {
32122
+ let parsedIssues = [];
32123
+ if (args.issues) {
32124
+ try {
32125
+ parsedIssues = JSON.parse(args.issues);
32126
+ } catch {
32127
+ return JSON.stringify({
32128
+ success: false,
32129
+ error: "Failed to parse issues JSON"
32130
+ }, null, 2);
32131
+ }
32132
+ }
32133
+ if (args.status === "needs_changes" && parsedIssues.length === 0) {
32134
+ return JSON.stringify({
32135
+ success: false,
32136
+ error: "needs_changes status requires at least one issue"
32137
+ }, null, 2);
32138
+ }
32139
+ const epicId = args.task_id.includes(".") ? args.task_id.split(".")[0] : args.task_id;
32140
+ if (args.status === "approved") {
32141
+ markReviewApproved(args.task_id);
32142
+ await sendSwarmMessage2({
32143
+ projectPath: args.project_key,
32144
+ fromAgent: "coordinator",
32145
+ toAgents: [args.worker_id],
32146
+ subject: `APPROVED: ${args.task_id}`,
32147
+ body: `## Review Approved ✓
32148
+
32149
+ ${args.summary || "Your work has been approved."}
32150
+
32151
+ You may now complete the task with \`swarm_complete\`.`,
32152
+ threadId: epicId,
32153
+ importance: "normal"
32154
+ });
32155
+ return JSON.stringify({
32156
+ success: true,
32157
+ status: "approved",
32158
+ task_id: args.task_id,
32159
+ message: "Review approved. Worker can now complete the task."
32160
+ }, null, 2);
32161
+ }
32162
+ const attemptNumber = incrementAttempt(args.task_id);
32163
+ const remaining = MAX_REVIEW_ATTEMPTS - attemptNumber;
32164
+ if (remaining <= 0) {
32165
+ const adapter = await getHiveAdapterSafe(args.project_key);
32166
+ if (adapter) {
32167
+ try {
32168
+ await adapter.changeCellStatus(args.project_key, args.task_id, "blocked");
32169
+ } catch {}
32170
+ }
32171
+ await sendSwarmMessage2({
32172
+ projectPath: args.project_key,
32173
+ fromAgent: "coordinator",
32174
+ toAgents: [args.worker_id],
32175
+ subject: `FAILED: ${args.task_id} - max review attempts reached`,
32176
+ body: `## Task Failed ✗
32177
+
32178
+ Maximum review attempts (${MAX_REVIEW_ATTEMPTS}) reached.
32179
+
32180
+ **Last Issues:**
32181
+ ${parsedIssues.map((i) => `- ${i.file}${i.line ? `:${i.line}` : ""}: ${i.issue}`).join(`
32182
+ `)}
32183
+
32184
+ The task has been marked as blocked. A human or different approach is needed.`,
32185
+ threadId: epicId,
32186
+ importance: "urgent"
32187
+ });
32188
+ return JSON.stringify({
32189
+ success: true,
32190
+ status: "needs_changes",
32191
+ task_failed: true,
32192
+ task_id: args.task_id,
32193
+ attempt: attemptNumber,
32194
+ remaining_attempts: 0,
32195
+ message: `Task failed after ${MAX_REVIEW_ATTEMPTS} review attempts`
32196
+ }, null, 2);
32197
+ }
32198
+ const issuesList = parsedIssues.map((i) => {
32199
+ let line = `- **${i.file}**`;
32200
+ if (i.line)
32201
+ line += `:${i.line}`;
32202
+ line += `: ${i.issue}`;
32203
+ if (i.suggestion)
32204
+ line += `
32205
+ → ${i.suggestion}`;
32206
+ return line;
32207
+ }).join(`
32208
+ `);
32209
+ await sendSwarmMessage2({
32210
+ projectPath: args.project_key,
32211
+ fromAgent: "coordinator",
32212
+ toAgents: [args.worker_id],
32213
+ subject: `NEEDS CHANGES: ${args.task_id} (attempt ${attemptNumber}/${MAX_REVIEW_ATTEMPTS})`,
32214
+ body: `## Review: Changes Needed
32215
+
32216
+ ${args.summary || "Please address the following issues:"}
32217
+
32218
+ **Issues:**
32219
+ ${issuesList}
32220
+
32221
+ **Remaining attempts:** ${remaining}
32222
+
32223
+ Please fix these issues and request another review.`,
32224
+ threadId: epicId,
32225
+ importance: "high"
32226
+ });
32227
+ return JSON.stringify({
32228
+ success: true,
32229
+ status: "needs_changes",
32230
+ task_id: args.task_id,
32231
+ attempt: attemptNumber,
32232
+ remaining_attempts: remaining,
32233
+ issues: parsedIssues,
32234
+ message: `Feedback sent. ${remaining} attempt(s) remaining.`
32235
+ }, null, 2);
32236
+ }
32237
+ });
32238
+ var reviewStatus = new Map;
32239
+ function markReviewApproved(taskId) {
32240
+ reviewStatus.set(taskId, { approved: true, timestamp: Date.now() });
32241
+ clearAttempts(taskId);
32242
+ }
32243
+ function getReviewStatus(taskId) {
32244
+ const status = reviewStatus.get(taskId);
32245
+ return {
32246
+ reviewed: status !== undefined,
32247
+ approved: status?.approved ?? false,
32248
+ attempt_count: getAttemptCount(taskId),
32249
+ remaining_attempts: getRemainingAttempts(taskId)
32250
+ };
32251
+ }
32252
+ var reviewTools = {
32253
+ swarm_review,
32254
+ swarm_review_feedback
32255
+ };
32256
+
32257
+ // src/swarm-orchestrate.ts
31473
32258
  async function queryEpicSubtasks(epicId) {
31474
32259
  const beadsAvailable = await isToolAvailable("beads");
31475
32260
  if (!beadsAvailable) {
@@ -31739,7 +32524,8 @@ var globalStrikeStorage = new InMemoryStrikeStorage;
31739
32524
  var swarm_init = tool({
31740
32525
  description: "Initialize swarm session: discovers available skills, checks tool availability. ALWAYS call at swarm start.",
31741
32526
  args: {
31742
- project_path: tool.schema.string().optional().describe("Project path (for Agent Mail init)")
32527
+ project_path: tool.schema.string().optional().describe("Project path (for Agent Mail init)"),
32528
+ isolation: tool.schema.enum(["worktree", "reservation"]).optional().default("reservation").describe("Isolation mode: 'worktree' for git worktree isolation (requires clean git state), 'reservation' for file reservations (default)")
31743
32529
  },
31744
32530
  async execute(args) {
31745
32531
  const availability = await checkAllTools();
@@ -31781,8 +32567,39 @@ var swarm_init = tool({
31781
32567
  } else {
31782
32568
  skillsGuidance = "No skills found. Add skills to .opencode/skills/ or .claude/skills/ for specialized guidance.";
31783
32569
  }
32570
+ const isolationMode = args.isolation ?? "reservation";
32571
+ let isolationInfo = {
32572
+ mode: isolationMode,
32573
+ available: true
32574
+ };
32575
+ if (isolationMode === "worktree" && args.project_path) {
32576
+ const worktreeCheck = await canUseWorktreeIsolation(args.project_path);
32577
+ if (worktreeCheck.canUse) {
32578
+ const startCommit = await getStartCommit(args.project_path);
32579
+ isolationInfo = {
32580
+ mode: "worktree",
32581
+ available: true,
32582
+ start_commit: startCommit ?? undefined
32583
+ };
32584
+ } else {
32585
+ isolationInfo = {
32586
+ mode: "reservation",
32587
+ available: false,
32588
+ reason: `Worktree mode unavailable: ${worktreeCheck.reason}. Falling back to reservation mode.`
32589
+ };
32590
+ warnings.push(`⚠️ Worktree isolation unavailable: ${worktreeCheck.reason}. Using file reservations instead.`);
32591
+ }
32592
+ } else if (isolationMode === "worktree" && !args.project_path) {
32593
+ isolationInfo = {
32594
+ mode: "reservation",
32595
+ available: false,
32596
+ reason: "Worktree mode requires project_path. Falling back to reservation mode."
32597
+ };
32598
+ warnings.push("⚠️ Worktree isolation requires project_path. Using file reservations instead.");
32599
+ }
31784
32600
  return JSON.stringify({
31785
32601
  ready: true,
32602
+ isolation: isolationInfo,
31786
32603
  tool_availability: Object.fromEntries(Array.from(availability.entries()).map(([k, v]) => [
31787
32604
  k,
31788
32605
  {
@@ -31796,7 +32613,8 @@ var swarm_init = tool({
31796
32613
  recommendations: {
31797
32614
  skills: skillsGuidance,
31798
32615
  beads: beadsAvailable ? "✓ Use beads for all task tracking" : "Install beads: npm i -g @joelhooks/beads",
31799
- agent_mail: agentMailAvailable2 ? "✓ Use Agent Mail for coordination" : "Start Agent Mail: agent-mail serve"
32616
+ agent_mail: agentMailAvailable2 ? "✓ Use Agent Mail for coordination" : "Start Agent Mail: agent-mail serve",
32617
+ isolation: isolationInfo.mode === "worktree" ? "✓ Using git worktree isolation" : "✓ Using file reservation isolation"
31800
32618
  },
31801
32619
  report
31802
32620
  }, null, 2);
@@ -31888,7 +32706,7 @@ var swarm_progress = tool({
31888
32706
  await Bun.$`bd update ${args.bead_id} --status ${beadStatus} --json`.quiet().nothrow();
31889
32707
  }
31890
32708
  const epicId = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
31891
- await sendSwarmMessage2({
32709
+ await sendSwarmMessage3({
31892
32710
  projectPath: args.project_key,
31893
32711
  fromAgent: args.agent_name,
31894
32712
  toAgents: [],
@@ -31956,7 +32774,7 @@ ${args.files_affected.map((f) => `- \`${f}\``).join(`
31956
32774
  ].filter(Boolean).join(`
31957
32775
  `);
31958
32776
  const mailImportance = args.importance === "blocker" ? "urgent" : args.importance === "warning" ? "high" : "normal";
31959
- await sendSwarmMessage2({
32777
+ await sendSwarmMessage3({
31960
32778
  projectPath: args.project_path,
31961
32779
  fromAgent: args.agent_name,
31962
32780
  toAgents: [],
@@ -31991,10 +32809,42 @@ var swarm_complete = tool({
31991
32809
  planned_files: tool.schema.array(tool.schema.string()).optional().describe("Files that were originally planned to be modified"),
31992
32810
  start_time: tool.schema.number().optional().describe("Task start timestamp (Unix ms) for duration calculation"),
31993
32811
  error_count: tool.schema.number().optional().describe("Number of errors encountered during task"),
31994
- retry_count: tool.schema.number().optional().describe("Number of retry attempts during task")
32812
+ retry_count: tool.schema.number().optional().describe("Number of retry attempts during task"),
32813
+ skip_review: tool.schema.boolean().optional().describe("Skip review gate check (default: false). Use only for tasks that don't require coordinator review.")
31995
32814
  },
31996
32815
  async execute(args, _ctx) {
31997
32816
  const epicId = args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id;
32817
+ if (!args.skip_review) {
32818
+ const reviewStatusResult = getReviewStatus(args.bead_id);
32819
+ if (!reviewStatusResult.approved) {
32820
+ if (!reviewStatusResult.reviewed) {
32821
+ return JSON.stringify({
32822
+ success: false,
32823
+ error: "Review required before completion",
32824
+ review_status: reviewStatusResult,
32825
+ hint: `This task requires coordinator review before completion.
32826
+
32827
+ **Next steps:**
32828
+ 1. Request review with swarm_review(project_key="${args.project_key}", epic_id="${epicId}", task_id="${args.bead_id}", files_touched=[...])
32829
+ 2. Wait for coordinator to review and approve with swarm_review_feedback
32830
+ 3. Once approved, call swarm_complete again
32831
+
32832
+ Or use skip_review=true to bypass (not recommended for production work).`
32833
+ }, null, 2);
32834
+ }
32835
+ return JSON.stringify({
32836
+ success: false,
32837
+ error: "Review not approved",
32838
+ review_status: reviewStatusResult,
32839
+ hint: `Task was reviewed but not approved. ${reviewStatusResult.remaining_attempts} attempt(s) remaining.
32840
+
32841
+ **Next steps:**
32842
+ 1. Address the feedback from the reviewer
32843
+ 2. Request another review with swarm_review
32844
+ 3. Once approved, call swarm_complete again`
32845
+ }, null, 2);
32846
+ }
32847
+ }
31998
32848
  try {
31999
32849
  const projectKey = args.project_key.replace(/\//g, "-").replace(/\\/g, "-");
32000
32850
  let agentRegistered = false;
@@ -32089,7 +32939,7 @@ Continuing with completion, but this should be fixed for future subtasks.`;
32089
32939
  const isNotFoundError = stderrOutput.includes("not found") || stderrOutput.includes("does not exist");
32090
32940
  return JSON.stringify({
32091
32941
  success: false,
32092
- error: "Failed to close bead",
32942
+ error: "Failed to close cell",
32093
32943
  failed_step: "bd close",
32094
32944
  details: stderrOutput || stdoutOutput || "Unknown error from bd close command",
32095
32945
  bead_id: args.bead_id,
@@ -32098,15 +32948,15 @@ Continuing with completion, but this should be fixed for future subtasks.`;
32098
32948
  steps: isNoDatabaseError ? [
32099
32949
  `1. Verify project_key is correct: "${args.project_key}"`,
32100
32950
  `2. Check .beads/ exists in that directory`,
32101
- `3. Bead ID prefix "${args.bead_id.split("-")[0]}" should match project`,
32102
- `4. Try: beads_close(id="${args.bead_id}", reason="...")`
32951
+ `3. Cell ID prefix "${args.bead_id.split("-")[0]}" should match project`,
32952
+ `4. Try: hive_close(id="${args.bead_id}", reason="...")`
32103
32953
  ] : [
32104
- `1. Check bead exists: bd show ${args.bead_id}`,
32105
- `2. Check bead status (might already be closed): beads_query()`,
32106
- `3. If bead is blocked, unblock first: beads_update(id="${args.bead_id}", status="in_progress")`,
32107
- `4. Try closing directly: beads_close(id="${args.bead_id}", reason="...")`
32954
+ `1. Check cell exists: bd show ${args.bead_id}`,
32955
+ `2. Check cell status (might already be closed): hive_query()`,
32956
+ `3. If cell is blocked, unblock first: hive_update(id="${args.bead_id}", status="in_progress")`,
32957
+ `4. Try closing directly: hive_close(id="${args.bead_id}", reason="...")`
32108
32958
  ],
32109
- hint: isNoDatabaseError ? `The project_key "${args.project_key}" doesn't have a .beads/ directory. Make sure you're using the correct project path.` : isNotFoundError ? `Bead "${args.bead_id}" not found. It may have been closed already or the ID is incorrect.` : "If bead is in 'blocked' status, you must change it to 'in_progress' or 'open' before closing."
32959
+ hint: isNoDatabaseError ? `The project_key "${args.project_key}" doesn't have a .beads/ directory. Make sure you're using the correct project path.` : isNotFoundError ? `Cell "${args.bead_id}" not found. It may have been closed already or the ID is incorrect.` : "If cell is in 'blocked' status, you must change it to 'in_progress' or 'open' before closing."
32110
32960
  }
32111
32961
  }, null, 2);
32112
32962
  }
@@ -32174,7 +33024,7 @@ Continuing with completion, but this should be fixed for future subtasks.`;
32174
33024
  let messageSent = false;
32175
33025
  let messageError;
32176
33026
  try {
32177
- await sendSwarmMessage2({
33027
+ await sendSwarmMessage3({
32178
33028
  projectPath: args.project_key,
32179
33029
  fromAgent: args.agent_name,
32180
33030
  toAgents: [],
@@ -32284,14 +33134,14 @@ ${errorStack.slice(0, 1000)}
32284
33134
  "",
32285
33135
  `### Recovery Actions`,
32286
33136
  "1. Check error message for specific issue",
32287
- "2. Review failed step (UBS scan, typecheck, bead close, etc.)",
33137
+ "2. Review failed step (UBS scan, typecheck, cell close, etc.)",
32288
33138
  "3. Fix underlying issue or use skip flags if appropriate",
32289
33139
  "4. Retry swarm_complete after fixing"
32290
33140
  ].filter(Boolean).join(`
32291
33141
  `);
32292
33142
  let notificationSent = false;
32293
33143
  try {
32294
- await sendSwarmMessage2({
33144
+ await sendSwarmMessage3({
32295
33145
  projectPath: args.project_key,
32296
33146
  fromAgent: args.agent_name,
32297
33147
  toAgents: [],
@@ -32329,7 +33179,7 @@ ${errorStack.slice(0, 1000)}
32329
33179
  common_fixes: {
32330
33180
  "Verification Gate": "Use skip_verification=true to bypass (not recommended)",
32331
33181
  "UBS scan": "Use skip_ubs_scan=true to bypass",
32332
- "Bead close": "Check bead status with beads_query(), may need beads_update() first",
33182
+ "Cell close": "Check cell status with hive_query(), may need hive_update() first",
32333
33183
  "Self-evaluation": "Check evaluation JSON format matches EvaluationSchema"
32334
33184
  }
32335
33185
  }
@@ -32428,7 +33278,7 @@ var swarm_record_outcome = tool({
32428
33278
  var swarm_accumulate_error = tool({
32429
33279
  description: "Record an error during subtask execution. Errors feed into retry prompts.",
32430
33280
  args: {
32431
- bead_id: tool.schema.string().describe("Bead ID where error occurred"),
33281
+ bead_id: tool.schema.string().describe("Cell ID where error occurred"),
32432
33282
  error_type: tool.schema.enum(["validation", "timeout", "conflict", "tool_failure", "unknown"]).describe("Category of error"),
32433
33283
  message: tool.schema.string().describe("Human-readable error message"),
32434
33284
  stack_trace: tool.schema.string().optional().describe("Stack trace for debugging"),
@@ -32455,7 +33305,7 @@ var swarm_accumulate_error = tool({
32455
33305
  var swarm_get_error_context = tool({
32456
33306
  description: "Get accumulated errors for a bead. Returns formatted context for retry prompts.",
32457
33307
  args: {
32458
- bead_id: tool.schema.string().describe("Bead ID to get errors for"),
33308
+ bead_id: tool.schema.string().describe("Cell ID to get errors for"),
32459
33309
  include_resolved: tool.schema.boolean().optional().describe("Include resolved errors (default: false)")
32460
33310
  },
32461
33311
  async execute(args) {
@@ -32491,7 +33341,7 @@ var swarm_resolve_error = tool({
32491
33341
  var swarm_check_strikes = tool({
32492
33342
  description: "Check 3-strike status for a bead. Records failures, detects architectural problems, generates architecture review prompts.",
32493
33343
  args: {
32494
- bead_id: tool.schema.string().describe("Bead ID to check"),
33344
+ bead_id: tool.schema.string().describe("Cell ID to check"),
32495
33345
  action: tool.schema.enum(["check", "add_strike", "clear", "get_prompt"]).describe("Action: check count, add strike, clear strikes, or get prompt"),
32496
33346
  attempt: tool.schema.string().optional().describe("Description of fix attempt (required for add_strike)"),
32497
33347
  reason: tool.schema.string().optional().describe("Why the fix failed (required for add_strike)")
@@ -32756,7 +33606,7 @@ ${args.files_context.map((f) => `- \`${f}\``).join(`
32756
33606
  *Learned from swarm execution on ${new Date().toISOString().split("T")[0]}*`;
32757
33607
  const { getSkill: getSkill2, invalidateSkillsCache: invalidateSkillsCache2 } = await Promise.resolve().then(() => (init_skills(), exports_skills));
32758
33608
  const { mkdir: mkdir2, writeFile: writeFile2 } = await import("node:fs/promises");
32759
- const { join: join5 } = await import("node:path");
33609
+ const { join: join7 } = await import("node:path");
32760
33610
  const existing = await getSkill2(args.skill_name);
32761
33611
  if (existing) {
32762
33612
  return JSON.stringify({
@@ -32767,8 +33617,8 @@ ${args.files_context.map((f) => `- \`${f}\``).join(`
32767
33617
  suggestion: "Use skills_update to add to existing skill, or choose a different name"
32768
33618
  }, null, 2);
32769
33619
  }
32770
- const skillDir = join5(process.cwd(), ".opencode", "skills", args.skill_name);
32771
- const skillPath = join5(skillDir, "SKILL.md");
33620
+ const skillDir = join7(process.cwd(), ".opencode", "skills", args.skill_name);
33621
+ const skillPath = join7(skillDir, "SKILL.md");
32772
33622
  const frontmatter = [
32773
33623
  "---",
32774
33624
  `name: ${args.skill_name}`,
@@ -33892,14 +34742,14 @@ var DEFAULT_GUARDRAIL_CONFIG = {
33892
34742
  cass_stats: 8000
33893
34743
  },
33894
34744
  skipTools: [
33895
- "beads_create",
33896
- "beads_create_epic",
33897
- "beads_query",
33898
- "beads_update",
33899
- "beads_close",
33900
- "beads_start",
33901
- "beads_ready",
33902
- "beads_sync",
34745
+ "hive_create",
34746
+ "hive_create_epic",
34747
+ "hive_query",
34748
+ "hive_update",
34749
+ "hive_close",
34750
+ "hive_start",
34751
+ "hive_ready",
34752
+ "hive_sync",
33903
34753
  "agentmail_init",
33904
34754
  "agentmail_send",
33905
34755
  "agentmail_inbox",
@@ -33919,7 +34769,7 @@ var DEFAULT_GUARDRAIL_CONFIG = {
33919
34769
  "structured_validate",
33920
34770
  "structured_parse_evaluation",
33921
34771
  "structured_parse_decomposition",
33922
- "structured_parse_bead_tree",
34772
+ "structured_parse_cell_tree",
33923
34773
  "swarm_select_strategy",
33924
34774
  "swarm_plan_prompt",
33925
34775
  "swarm_decompose",
@@ -34095,7 +34945,7 @@ function analyzeTodoWrite(args) {
34095
34945
  warning: `⚠️ This looks like a multi-file implementation plan (${fileModificationCount}/${todos.length} items are file modifications).
34096
34946
 
34097
34947
  Consider using swarm instead:
34098
- swarm_decompose → beads_create_epic → parallel task spawns
34948
+ swarm_decompose → hive_create_epic → parallel task spawns
34099
34949
 
34100
34950
  TodoWrite is for tracking progress, not parallelizable implementation work.
34101
34951
  Swarm workers can complete these ${fileModificationCount} tasks in parallel.
@@ -34249,7 +35099,7 @@ var sessionStats = {
34249
35099
  init_skills();
34250
35100
  var SwarmPlugin = async (input) => {
34251
35101
  const { $, directory } = input;
34252
- setBeadsWorkingDirectory(directory);
35102
+ setHiveWorkingDirectory(directory);
34253
35103
  setSkillsProjectDirectory(directory);
34254
35104
  setAgentMailProjectDirectory(directory);
34255
35105
  setSwarmMailProjectDirectory(directory);
@@ -34284,10 +35134,12 @@ var SwarmPlugin = async (input) => {
34284
35134
  }
34285
35135
  return {
34286
35136
  tool: {
34287
- ...beadsTools,
35137
+ ...hiveTools,
34288
35138
  ...swarmMailTools,
34289
35139
  ...structuredTools,
34290
35140
  ...swarmTools,
35141
+ ...worktreeTools,
35142
+ ...reviewTools,
34291
35143
  ...repoCrawlTools,
34292
35144
  ...skillsTools,
34293
35145
  ...mandateTools
@@ -34336,17 +35188,19 @@ var SwarmPlugin = async (input) => {
34336
35188
  if (toolName === "swarm_complete" && activeAgentMailState) {
34337
35189
  await releaseReservations();
34338
35190
  }
34339
- if (toolName === "beads_close") {
35191
+ if (toolName === "hive_close" || toolName === "hive_close") {
34340
35192
  $`bd sync`.quiet().nothrow();
34341
35193
  }
34342
35194
  }
34343
35195
  };
34344
35196
  };
34345
35197
  var allTools = {
34346
- ...beadsTools,
35198
+ ...hiveTools,
34347
35199
  ...swarmMailTools,
34348
35200
  ...structuredTools,
34349
35201
  ...swarmTools,
35202
+ ...worktreeTools,
35203
+ ...reviewTools,
34350
35204
  ...repoCrawlTools,
34351
35205
  ...skillsTools,
34352
35206
  ...mandateTools