opencode-swarm-plugin 0.59.1 → 0.59.5

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.
@@ -17285,7 +17285,7 @@ import {
17285
17285
  sep as sep2
17286
17286
  } from "path";
17287
17287
  import { fileURLToPath } from "url";
17288
- import { getSwarmMailLibSQL as getSwarmMailLibSQL3, createEvent as createEvent2 } from "swarm-mail";
17288
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL3, createEvent as createEvent3 } from "swarm-mail";
17289
17289
  function resolveGuidanceModel(model) {
17290
17290
  if (!model)
17291
17291
  return "unknown";
@@ -17328,7 +17328,7 @@ async function emitSkillLoadedEvent(data) {
17328
17328
  try {
17329
17329
  const projectPath = skillsProjectDirectory;
17330
17330
  const swarmMail = await getSwarmMailLibSQL3(projectPath);
17331
- const event = createEvent2("skill_loaded", {
17331
+ const event = createEvent3("skill_loaded", {
17332
17332
  project_key: projectPath,
17333
17333
  skill_name: data.skill_name,
17334
17334
  skill_source: data.skill_source,
@@ -17342,7 +17342,7 @@ async function emitSkillCreatedEvent(data) {
17342
17342
  try {
17343
17343
  const projectPath = skillsProjectDirectory;
17344
17344
  const swarmMail = await getSwarmMailLibSQL3(projectPath);
17345
- const event = createEvent2("skill_created", {
17345
+ const event = createEvent3("skill_created", {
17346
17346
  project_key: projectPath,
17347
17347
  skill_name: data.skill_name,
17348
17348
  skill_scope: data.skill_scope,
@@ -19414,6 +19414,27 @@ var init_storage = __esm(() => {
19414
19414
  };
19415
19415
  });
19416
19416
 
19417
+ // src/utils/adapter-cache.ts
19418
+ class AdapterCache {
19419
+ cached = null;
19420
+ cachedPath = null;
19421
+ async get(projectPath, factory) {
19422
+ if (this.cached && this.cachedPath === projectPath) {
19423
+ return this.cached;
19424
+ }
19425
+ this.cached = await factory(projectPath);
19426
+ this.cachedPath = projectPath;
19427
+ return this.cached;
19428
+ }
19429
+ clear() {
19430
+ this.cached = null;
19431
+ this.cachedPath = null;
19432
+ }
19433
+ getCachedPath() {
19434
+ return this.cachedPath;
19435
+ }
19436
+ }
19437
+
19417
19438
  // ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Function.js
19418
19439
  function pipe2(a, ab, bc, cd, de, ef, fg, gh, hi) {
19419
19440
  switch (arguments.length) {
@@ -36740,6 +36761,9 @@ Linked to ${result.links.length} related memor${result.links.length === 1 ? "y"
36740
36761
  };
36741
36762
  },
36742
36763
  async find(args2) {
36764
+ if (!args2.query || typeof args2.query !== "string") {
36765
+ throw new Error("query is required for find operation");
36766
+ }
36743
36767
  const limit = args2.limit ?? 10;
36744
36768
  let results;
36745
36769
  let usedFallback = false;
@@ -36858,22 +36882,20 @@ var init_memory = __esm(() => {
36858
36882
  });
36859
36883
 
36860
36884
  // src/memory-tools.ts
36861
- import { getSwarmMailLibSQL as getSwarmMailLibSQL5, createEvent as createEvent4, appendEvent as appendEvent3 } from "swarm-mail";
36885
+ import { getSwarmMailLibSQL as getSwarmMailLibSQL5, createEvent as createEvent5, appendEvent as appendEvent4 } from "swarm-mail";
36862
36886
  async function getMemoryAdapter(projectPath) {
36863
36887
  const path3 = projectPath || process.cwd();
36864
- if (cachedAdapter && cachedProjectPath === path3) {
36865
- return cachedAdapter;
36866
- }
36867
- const swarmMail = await getSwarmMailLibSQL5(path3);
36868
- const dbAdapter = await swarmMail.getDatabase();
36869
- cachedAdapter = await createMemoryAdapter(dbAdapter);
36870
- cachedProjectPath = path3;
36871
- return cachedAdapter;
36888
+ return memoryAdapterCache.get(path3, async (projectPath2) => {
36889
+ const swarmMail = await getSwarmMailLibSQL5(projectPath2);
36890
+ const dbAdapter = await swarmMail.getDatabase();
36891
+ return await createMemoryAdapter(dbAdapter);
36892
+ });
36872
36893
  }
36873
- var cachedAdapter = null, cachedProjectPath = null, semantic_memory_store, semantic_memory_find, semantic_memory_get, semantic_memory_remove, semantic_memory_validate, semantic_memory_list, semantic_memory_stats, semantic_memory_check, semantic_memory_upsert;
36894
+ var memoryAdapterCache, semantic_memory_store, semantic_memory_find, semantic_memory_get, semantic_memory_remove, semantic_memory_validate, semantic_memory_list, semantic_memory_stats, semantic_memory_check, semantic_memory_upsert;
36874
36895
  var init_memory_tools = __esm(() => {
36875
36896
  init_dist();
36876
36897
  init_memory();
36898
+ memoryAdapterCache = new AdapterCache;
36877
36899
  semantic_memory_store = tool({
36878
36900
  description: "Store a memory with semantic embedding. Memories are searchable by semantic similarity and can be organized into collections. Confidence affects decay rate: high confidence (1.0) = 135 day half-life, low confidence (0.0) = 45 day half-life. Supports auto-tagging, auto-linking, and entity extraction via LLM.",
36879
36901
  args: {
@@ -36890,9 +36912,9 @@ var init_memory_tools = __esm(() => {
36890
36912
  const adapter = await getMemoryAdapter();
36891
36913
  const result = await adapter.store(args2);
36892
36914
  try {
36893
- const projectKey = cachedProjectPath || process.cwd();
36915
+ const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
36894
36916
  const tags = args2.tags ? args2.tags.split(",").map((t) => t.trim()) : [];
36895
- const event = createEvent4("memory_stored", {
36917
+ const event = createEvent5("memory_stored", {
36896
36918
  project_key: projectKey,
36897
36919
  memory_id: result.id,
36898
36920
  content_preview: args2.information.slice(0, 100),
@@ -36900,7 +36922,7 @@ var init_memory_tools = __esm(() => {
36900
36922
  auto_tagged: args2.autoTag,
36901
36923
  collection: args2.collection
36902
36924
  });
36903
- await appendEvent3(event, projectKey);
36925
+ await appendEvent4(event, projectKey);
36904
36926
  } catch (error45) {
36905
36927
  console.warn("[semantic_memory_store] Failed to emit memory_stored event:", error45);
36906
36928
  }
@@ -36922,9 +36944,9 @@ var init_memory_tools = __esm(() => {
36922
36944
  const result = await adapter.find(args2);
36923
36945
  const duration3 = Date.now() - startTime;
36924
36946
  try {
36925
- const projectKey = cachedProjectPath || process.cwd();
36947
+ const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
36926
36948
  const topScore = result.results.length > 0 ? result.results[0].score : undefined;
36927
- const event = createEvent4("memory_found", {
36949
+ const event = createEvent5("memory_found", {
36928
36950
  project_key: projectKey,
36929
36951
  query: args2.query,
36930
36952
  result_count: result.results.length,
@@ -36932,7 +36954,7 @@ var init_memory_tools = __esm(() => {
36932
36954
  search_duration_ms: duration3,
36933
36955
  used_fts: args2.fts
36934
36956
  });
36935
- await appendEvent3(event, projectKey);
36957
+ await appendEvent4(event, projectKey);
36936
36958
  } catch (error45) {
36937
36959
  console.warn("[semantic_memory_find] Failed to emit memory_found event:", error45);
36938
36960
  }
@@ -36960,12 +36982,12 @@ var init_memory_tools = __esm(() => {
36960
36982
  const result = await adapter.remove(args2);
36961
36983
  if (result.success) {
36962
36984
  try {
36963
- const projectKey = cachedProjectPath || process.cwd();
36964
- const event = createEvent4("memory_deleted", {
36985
+ const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
36986
+ const event = createEvent5("memory_deleted", {
36965
36987
  project_key: projectKey,
36966
36988
  memory_id: args2.id
36967
36989
  });
36968
- await appendEvent3(event, projectKey);
36990
+ await appendEvent4(event, projectKey);
36969
36991
  } catch (error45) {
36970
36992
  console.warn("[semantic_memory_remove] Failed to emit memory_deleted event:", error45);
36971
36993
  }
@@ -36983,13 +37005,13 @@ var init_memory_tools = __esm(() => {
36983
37005
  const result = await adapter.validate(args2);
36984
37006
  if (result.success) {
36985
37007
  try {
36986
- const projectKey = cachedProjectPath || process.cwd();
36987
- const event = createEvent4("memory_validated", {
37008
+ const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
37009
+ const event = createEvent5("memory_validated", {
36988
37010
  project_key: projectKey,
36989
37011
  memory_id: args2.id,
36990
37012
  decay_reset: true
36991
37013
  });
36992
- await appendEvent3(event, projectKey);
37014
+ await appendEvent4(event, projectKey);
36993
37015
  } catch (error45) {
36994
37016
  console.warn("[semantic_memory_validate] Failed to emit memory_validated event:", error45);
36995
37017
  }
@@ -37042,14 +37064,14 @@ var init_memory_tools = __esm(() => {
37042
37064
  const adapter = await getMemoryAdapter();
37043
37065
  const result = await adapter.upsert(args2);
37044
37066
  try {
37045
- const projectKey = cachedProjectPath || process.cwd();
37046
- const event = createEvent4("memory_updated", {
37067
+ const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
37068
+ const event = createEvent5("memory_updated", {
37047
37069
  project_key: projectKey,
37048
37070
  memory_id: result.memoryId || "unknown",
37049
37071
  operation: result.operation,
37050
37072
  reason: result.reason
37051
37073
  });
37052
- await appendEvent3(event, projectKey);
37074
+ await appendEvent4(event, projectKey);
37053
37075
  } catch (error45) {
37054
37076
  console.warn("[semantic_memory_upsert] Failed to emit memory_updated event:", error45);
37055
37077
  }
@@ -39961,8 +39983,8 @@ import {
39961
39983
  releaseSwarmFiles,
39962
39984
  sendSwarmMessage as sendSwarmMessage2,
39963
39985
  getAgent,
39964
- createEvent as createEvent3,
39965
- appendEvent as appendEvent2,
39986
+ createEvent as createEvent4,
39987
+ appendEvent as appendEvent3,
39966
39988
  getSwarmMailLibSQL as getSwarmMailLibSQL4
39967
39989
  } from "swarm-mail";
39968
39990
 
@@ -40261,7 +40283,24 @@ import {
40261
40283
  } from "swarm-mail";
40262
40284
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
40263
40285
  import { join as join2 } from "node:path";
40286
+ import { createEvent as createEvent2, appendEvent as appendEvent2 } from "swarm-mail";
40287
+
40288
+ // src/utils/event-utils.ts
40264
40289
  import { createEvent, appendEvent } from "swarm-mail";
40290
+ async function safeEmitEvent(eventType, data, toolName, projectPath) {
40291
+ try {
40292
+ const effectiveProjectPath = projectPath || process.cwd();
40293
+ const event = createEvent(eventType, {
40294
+ project_key: effectiveProjectPath,
40295
+ ...data
40296
+ });
40297
+ await appendEvent(event, effectiveProjectPath);
40298
+ } catch (error45) {
40299
+ console.warn(`[${toolName}] Failed to emit ${eventType} event:`, error45);
40300
+ }
40301
+ }
40302
+
40303
+ // src/hive.ts
40265
40304
  var hiveWorkingDirectory = null;
40266
40305
  function setHiveWorkingDirectory(directory) {
40267
40306
  hiveWorkingDirectory = directory;
@@ -40419,20 +40458,14 @@ var hive_create = tool({
40419
40458
  parent_id: validated.parent_id
40420
40459
  });
40421
40460
  await adapter.markDirty(projectKey, cell.id);
40422
- try {
40423
- const event = createEvent("cell_created", {
40424
- project_key: projectKey,
40425
- cell_id: cell.id,
40426
- title: validated.title,
40427
- description: validated.description,
40428
- issue_type: validated.type || "task",
40429
- priority: validated.priority ?? 2,
40430
- parent_id: validated.parent_id
40431
- });
40432
- await appendEvent(event, projectKey);
40433
- } catch (error45) {
40434
- console.warn("[hive_create] Failed to emit cell_created event:", error45);
40435
- }
40461
+ await safeEmitEvent("cell_created", {
40462
+ cell_id: cell.id,
40463
+ title: validated.title,
40464
+ description: validated.description,
40465
+ issue_type: validated.type || "task",
40466
+ priority: validated.priority ?? 2,
40467
+ parent_id: validated.parent_id
40468
+ }, "hive_create", projectKey);
40436
40469
  const formatted = formatCellForOutput(cell);
40437
40470
  return JSON.stringify(formatted, null, 2);
40438
40471
  } catch (error45) {
@@ -40514,53 +40547,35 @@ var hive_create_epic = tool({
40514
40547
  subtasks: created.slice(1).map((c) => formatCellForOutput(c))
40515
40548
  };
40516
40549
  const effectiveProjectKey = args.project_key || projectKey;
40517
- try {
40518
- const epicCreatedEvent = createEvent("epic_created", {
40519
- project_key: effectiveProjectKey,
40520
- epic_id: epic.id,
40521
- title: validated.epic_title,
40522
- description: validated.epic_description,
40523
- subtask_count: validated.subtasks.length,
40524
- subtask_ids: created.slice(1).map((c) => c.id)
40525
- });
40526
- await appendEvent(epicCreatedEvent, effectiveProjectKey);
40527
- } catch (error45) {
40528
- console.warn("[hive_create_epic] Failed to emit epic_created event:", error45);
40529
- }
40530
- try {
40531
- const event = createEvent("decomposition_generated", {
40532
- project_key: effectiveProjectKey,
40533
- epic_id: epic.id,
40534
- task: args.task || validated.epic_title,
40535
- context: validated.epic_description,
40536
- strategy: args.strategy || "feature-based",
40537
- epic_title: validated.epic_title,
40538
- subtasks: validated.subtasks.map((st) => ({
40539
- title: st.title,
40540
- files: st.files || [],
40541
- priority: st.priority
40542
- })),
40543
- recovery_context: args.recovery_context
40544
- });
40545
- await appendEvent(event, effectiveProjectKey);
40546
- } catch (error45) {
40547
- console.warn("[hive_create_epic] Failed to emit DecompositionGeneratedEvent:", error45);
40548
- }
40549
- try {
40550
- const totalFiles = validated.subtasks.reduce((count, st) => count + (st.files?.length || 0), 0);
40551
- const swarmStartedEvent = createEvent("swarm_started", {
40552
- project_key: effectiveProjectKey,
40553
- epic_id: epic.id,
40554
- epic_title: validated.epic_title,
40555
- strategy: args.strategy || "feature-based",
40556
- subtask_count: validated.subtasks.length,
40557
- total_files: totalFiles,
40558
- coordinator_agent: "coordinator"
40559
- });
40560
- await appendEvent(swarmStartedEvent, effectiveProjectKey);
40561
- } catch (error45) {
40562
- console.warn("[hive_create_epic] Failed to emit SwarmStartedEvent:", error45);
40563
- }
40550
+ await safeEmitEvent("epic_created", {
40551
+ epic_id: epic.id,
40552
+ title: validated.epic_title,
40553
+ description: validated.epic_description,
40554
+ subtask_count: validated.subtasks.length,
40555
+ subtask_ids: created.slice(1).map((c) => c.id)
40556
+ }, "hive_create_epic", effectiveProjectKey);
40557
+ await safeEmitEvent("decomposition_generated", {
40558
+ epic_id: epic.id,
40559
+ task: args.task || validated.epic_title,
40560
+ context: validated.epic_description,
40561
+ strategy: args.strategy || "feature-based",
40562
+ epic_title: validated.epic_title,
40563
+ subtasks: validated.subtasks.map((st) => ({
40564
+ title: st.title,
40565
+ files: st.files || [],
40566
+ priority: st.priority
40567
+ })),
40568
+ recovery_context: args.recovery_context
40569
+ }, "hive_create_epic", effectiveProjectKey);
40570
+ const totalFiles = validated.subtasks.reduce((count, st) => count + (st.files?.length || 0), 0);
40571
+ await safeEmitEvent("swarm_started", {
40572
+ epic_id: epic.id,
40573
+ epic_title: validated.epic_title,
40574
+ strategy: args.strategy || "feature-based",
40575
+ subtask_count: validated.subtasks.length,
40576
+ total_files: totalFiles,
40577
+ coordinator_agent: "coordinator"
40578
+ }, "hive_create_epic", effectiveProjectKey);
40564
40579
  try {
40565
40580
  const { captureCoordinatorEvent: captureCoordinatorEvent2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
40566
40581
  const filesPerSubtask = {};
@@ -40691,23 +40706,17 @@ var hive_update = tool({
40691
40706
  cell = existingCell;
40692
40707
  }
40693
40708
  await adapter.markDirty(projectKey, cellId);
40694
- try {
40695
- const fieldsChanged = [];
40696
- if (validated.status)
40697
- fieldsChanged.push("status");
40698
- if (validated.description !== undefined)
40699
- fieldsChanged.push("description");
40700
- if (validated.priority !== undefined)
40701
- fieldsChanged.push("priority");
40702
- const event = createEvent("cell_updated", {
40703
- project_key: projectKey,
40704
- cell_id: cellId,
40705
- fields_changed: fieldsChanged
40706
- });
40707
- await appendEvent(event, projectKey);
40708
- } catch (error45) {
40709
- console.warn("[hive_update] Failed to emit cell_updated event:", error45);
40710
- }
40709
+ const fieldsChanged = [];
40710
+ if (validated.status)
40711
+ fieldsChanged.push("status");
40712
+ if (validated.description !== undefined)
40713
+ fieldsChanged.push("description");
40714
+ if (validated.priority !== undefined)
40715
+ fieldsChanged.push("priority");
40716
+ await safeEmitEvent("cell_updated", {
40717
+ cell_id: cellId,
40718
+ fields_changed: fieldsChanged
40719
+ }, "hive_update", projectKey);
40711
40720
  const formatted = formatCellForOutput(cell);
40712
40721
  return JSON.stringify(formatted, null, 2);
40713
40722
  } catch (error45) {
@@ -40740,7 +40749,6 @@ var hive_close = tool({
40740
40749
  await adapter.markDirty(projectKey, cellId);
40741
40750
  if (isEpic && cellBeforeClose) {
40742
40751
  try {
40743
- const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
40744
40752
  const subtasks = await adapter.queryCells(projectKey, { parent_id: cellId });
40745
40753
  const completedSubtasks = subtasks.filter((st) => st.status === "closed");
40746
40754
  const failedSubtasks = subtasks.filter((st) => st.status === "blocked");
@@ -40778,8 +40786,7 @@ var hive_close = tool({
40778
40786
  } catch (error45) {
40779
40787
  console.warn("[hive_close] Failed to calculate duration:", error45);
40780
40788
  }
40781
- const swarmCompletedEvent = createEvent2("swarm_completed", {
40782
- project_key: projectKey,
40789
+ await safeEmitEvent("swarm_completed", {
40783
40790
  epic_id: cellId,
40784
40791
  epic_title: cellBeforeClose.title,
40785
40792
  success: failedSubtasks.length === 0,
@@ -40787,8 +40794,7 @@ var hive_close = tool({
40787
40794
  subtasks_completed: completedSubtasks.length,
40788
40795
  subtasks_failed: failedSubtasks.length,
40789
40796
  total_files_touched: totalFilesTouched
40790
- });
40791
- await appendEvent2(swarmCompletedEvent, projectKey);
40797
+ }, "hive_close", projectKey);
40792
40798
  try {
40793
40799
  const { runPostSwarmValidation: runPostSwarmValidation2 } = await Promise.resolve().then(() => (init_swarm_validation(), exports_swarm_validation));
40794
40800
  const { readEvents } = await import("swarm-mail");
@@ -40824,16 +40830,10 @@ var hive_close = tool({
40824
40830
  console.warn("[hive_close] Failed to emit SwarmCompletedEvent:", error45);
40825
40831
  }
40826
40832
  }
40827
- try {
40828
- const event = createEvent("cell_closed", {
40829
- project_key: projectKey,
40830
- cell_id: cellId,
40831
- reason: validated.reason
40832
- });
40833
- await appendEvent(event, projectKey);
40834
- } catch (error45) {
40835
- console.warn("[hive_close] Failed to emit cell_closed event:", error45);
40836
- }
40833
+ await safeEmitEvent("cell_closed", {
40834
+ cell_id: cellId,
40835
+ reason: validated.reason
40836
+ }, "hive_close", projectKey);
40837
40837
  return `Closed ${cell.id}: ${validated.reason}`;
40838
40838
  } catch (error45) {
40839
40839
  const message = error45 instanceof Error ? error45.message : String(error45);
@@ -40860,13 +40860,13 @@ var hive_start = tool({
40860
40860
  const cell = await adapter.changeCellStatus(projectKey, cellId, "in_progress");
40861
40861
  await adapter.markDirty(projectKey, cellId);
40862
40862
  try {
40863
- const event = createEvent("cell_status_changed", {
40863
+ const event = createEvent2("cell_status_changed", {
40864
40864
  project_key: projectKey,
40865
40865
  cell_id: cellId,
40866
40866
  old_status: "open",
40867
40867
  new_status: "in_progress"
40868
40868
  });
40869
- await appendEvent(event, projectKey);
40869
+ await appendEvent2(event, projectKey);
40870
40870
  } catch (error45) {
40871
40871
  console.warn("[hive_start] Failed to emit cell_status_changed event:", error45);
40872
40872
  }
@@ -41067,12 +41067,12 @@ var hive_sync = tool({
41067
41067
  pushSuccess = true;
41068
41068
  }
41069
41069
  try {
41070
- const event = createEvent("hive_synced", {
41070
+ const event = createEvent2("hive_synced", {
41071
41071
  project_key: projectKey,
41072
41072
  cells_synced: flushResult.cellsExported,
41073
41073
  push_success: pushSuccess
41074
41074
  });
41075
- await appendEvent(event, projectKey);
41075
+ await appendEvent2(event, projectKey);
41076
41076
  } catch (error45) {
41077
41077
  console.warn("[hive_sync] Failed to emit hive_synced event:", error45);
41078
41078
  }
@@ -41739,15 +41739,15 @@ var swarm_review = tool({
41739
41739
  downstream_tasks: downstreamTasks.length > 0 ? downstreamTasks : undefined
41740
41740
  });
41741
41741
  try {
41742
- const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
41742
+ const { createEvent: createEvent4, appendEvent: appendEvent3 } = await import("swarm-mail");
41743
41743
  const attempt = getReviewStatus(args.task_id).attempt_count || 1;
41744
- const reviewStartedEvent = createEvent3("review_started", {
41744
+ const reviewStartedEvent = createEvent4("review_started", {
41745
41745
  project_key: args.project_key,
41746
41746
  epic_id: args.epic_id,
41747
41747
  bead_id: args.task_id,
41748
41748
  attempt
41749
41749
  });
41750
- await appendEvent2(reviewStartedEvent, args.project_key);
41750
+ await appendEvent3(reviewStartedEvent, args.project_key);
41751
41751
  } catch (error45) {
41752
41752
  console.warn("[swarm_review] Failed to emit ReviewStartedEvent:", error45);
41753
41753
  }
@@ -41830,16 +41830,16 @@ var swarm_review_feedback = tool({
41830
41830
  console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
41831
41831
  }
41832
41832
  try {
41833
- const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
41833
+ const { createEvent: createEvent4, appendEvent: appendEvent3 } = await import("swarm-mail");
41834
41834
  const attempt = getReviewStatus(args.task_id).attempt_count || 1;
41835
- const reviewCompletedEvent = createEvent3("review_completed", {
41835
+ const reviewCompletedEvent = createEvent4("review_completed", {
41836
41836
  project_key: args.project_key,
41837
41837
  epic_id: epicId,
41838
41838
  bead_id: args.task_id,
41839
41839
  status: "approved",
41840
41840
  attempt
41841
41841
  });
41842
- await appendEvent2(reviewCompletedEvent, args.project_key);
41842
+ await appendEvent3(reviewCompletedEvent, args.project_key);
41843
41843
  } catch (error45) {
41844
41844
  console.warn("[swarm_review_feedback] Failed to emit ReviewCompletedEvent:", error45);
41845
41845
  }
@@ -41901,16 +41901,16 @@ You may now complete the task with \`swarm_complete\`.`,
41901
41901
  console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
41902
41902
  }
41903
41903
  try {
41904
- const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
41904
+ const { createEvent: createEvent4, appendEvent: appendEvent3 } = await import("swarm-mail");
41905
41905
  const status = remaining <= 0 ? "blocked" : "needs_changes";
41906
- const reviewCompletedEvent = createEvent3("review_completed", {
41906
+ const reviewCompletedEvent = createEvent4("review_completed", {
41907
41907
  project_key: args.project_key,
41908
41908
  epic_id: epicId,
41909
41909
  bead_id: args.task_id,
41910
41910
  status,
41911
41911
  attempt: attemptNumber
41912
41912
  });
41913
- await appendEvent2(reviewCompletedEvent, args.project_key);
41913
+ await appendEvent3(reviewCompletedEvent, args.project_key);
41914
41914
  } catch (error45) {
41915
41915
  console.warn("[swarm_review_feedback] Failed to emit ReviewCompletedEvent:", error45);
41916
41916
  }
@@ -41966,6 +41966,181 @@ function getReviewStatus(taskId) {
41966
41966
 
41967
41967
  // src/swarm-orchestrate.ts
41968
41968
  init_eval_capture();
41969
+
41970
+ // src/swarm-verify.ts
41971
+ init_dist();
41972
+ async function runTypecheckVerification() {
41973
+ const step = {
41974
+ name: "typecheck",
41975
+ command: "tsc --noEmit",
41976
+ passed: false,
41977
+ exitCode: -1
41978
+ };
41979
+ try {
41980
+ const tsconfigExists = await Bun.file("tsconfig.json").exists();
41981
+ if (!tsconfigExists) {
41982
+ step.skipped = true;
41983
+ step.skipReason = "No tsconfig.json found";
41984
+ step.passed = true;
41985
+ return step;
41986
+ }
41987
+ const result = await Bun.$`tsc --noEmit`.quiet().nothrow();
41988
+ step.exitCode = result.exitCode;
41989
+ step.passed = result.exitCode === 0;
41990
+ if (!step.passed) {
41991
+ step.error = result.stderr.toString().slice(0, 1000);
41992
+ step.output = result.stdout.toString().slice(0, 1000);
41993
+ }
41994
+ } catch (error45) {
41995
+ step.skipped = true;
41996
+ step.skipReason = `tsc not available: ${error45 instanceof Error ? error45.message : String(error45)}`;
41997
+ step.passed = true;
41998
+ }
41999
+ return step;
42000
+ }
42001
+ async function runTestVerification(filesTouched) {
42002
+ const step = {
42003
+ name: "tests",
42004
+ command: "bun test <related-files>",
42005
+ passed: false,
42006
+ exitCode: -1
42007
+ };
42008
+ if (filesTouched.length === 0) {
42009
+ step.skipped = true;
42010
+ step.skipReason = "No files touched";
42011
+ step.passed = true;
42012
+ return step;
42013
+ }
42014
+ const testPatterns = [];
42015
+ for (const file2 of filesTouched) {
42016
+ if (file2.includes(".test.") || file2.includes(".spec.")) {
42017
+ testPatterns.push(file2);
42018
+ continue;
42019
+ }
42020
+ const baseName = file2.replace(/\.(ts|tsx|js|jsx)$/, "");
42021
+ testPatterns.push(`${baseName}.test.ts`);
42022
+ testPatterns.push(`${baseName}.test.tsx`);
42023
+ testPatterns.push(`${baseName}.spec.ts`);
42024
+ }
42025
+ const existingTests = [];
42026
+ for (const pattern of testPatterns) {
42027
+ try {
42028
+ const exists = await Bun.file(pattern).exists();
42029
+ if (exists) {
42030
+ existingTests.push(pattern);
42031
+ }
42032
+ } catch {}
42033
+ }
42034
+ if (existingTests.length === 0) {
42035
+ step.skipped = true;
42036
+ step.skipReason = "No related test files found";
42037
+ step.passed = true;
42038
+ return step;
42039
+ }
42040
+ try {
42041
+ step.command = `bun test ${existingTests.join(" ")}`;
42042
+ const result = await Bun.$`bun test ${existingTests}`.quiet().nothrow();
42043
+ step.exitCode = result.exitCode;
42044
+ step.passed = result.exitCode === 0;
42045
+ if (!step.passed) {
42046
+ step.error = result.stderr.toString().slice(0, 1000);
42047
+ step.output = result.stdout.toString().slice(0, 1000);
42048
+ }
42049
+ } catch (error45) {
42050
+ step.skipped = true;
42051
+ step.skipReason = `Test runner failed: ${error45 instanceof Error ? error45.message : String(error45)}`;
42052
+ step.passed = true;
42053
+ }
42054
+ return step;
42055
+ }
42056
+ async function runVerificationGate(filesTouched, _skipUbs = false) {
42057
+ const steps = [];
42058
+ const blockers = [];
42059
+ const typecheckStep = await runTypecheckVerification();
42060
+ steps.push(typecheckStep);
42061
+ if (!typecheckStep.passed && !typecheckStep.skipped) {
42062
+ blockers.push(`Typecheck failed: ${typecheckStep.error?.slice(0, 100) || "type errors found"}. Try: Run 'tsc --noEmit' to see full errors, check tsconfig.json configuration, or fix reported type errors in modified files.`);
42063
+ }
42064
+ const testStep = await runTestVerification(filesTouched);
42065
+ steps.push(testStep);
42066
+ if (!testStep.passed && !testStep.skipped) {
42067
+ blockers.push(`Tests failed: ${testStep.error?.slice(0, 100) || "test failures"}. Try: Run 'bun test ${testStep.command.split(" ").slice(2).join(" ")}' to see full output, check test assertions, or fix failing tests in modified files.`);
42068
+ }
42069
+ const passedCount = steps.filter((s) => s.passed).length;
42070
+ const skippedCount = steps.filter((s) => s.skipped).length;
42071
+ const failedCount = steps.filter((s) => !s.passed && !s.skipped).length;
42072
+ const summary = failedCount === 0 ? `Verification passed: ${passedCount} checks passed, ${skippedCount} skipped` : `Verification FAILED: ${failedCount} checks failed, ${passedCount} passed, ${skippedCount} skipped`;
42073
+ return {
42074
+ passed: failedCount === 0,
42075
+ steps,
42076
+ summary,
42077
+ blockers
42078
+ };
42079
+ }
42080
+ var swarm_verify = tool({
42081
+ description: "Run verification gate (typecheck + tests) for files. Returns verification results without blocking. Used by swarm_complete to verify worker output.",
42082
+ args: {
42083
+ files_touched: tool.schema.array(tool.schema.string()).describe("Files to verify (typecheck + test discovery)"),
42084
+ skip_verification: tool.schema.boolean().optional().describe("Skip verification entirely (default: false)")
42085
+ },
42086
+ async execute(args) {
42087
+ try {
42088
+ if (args.skip_verification) {
42089
+ return JSON.stringify({
42090
+ success: true,
42091
+ data: {
42092
+ passed: true,
42093
+ skipped: true,
42094
+ reason: "skip_verification=true",
42095
+ summary: "Verification skipped by request",
42096
+ steps: [],
42097
+ blockers: []
42098
+ }
42099
+ }, null, 2);
42100
+ }
42101
+ if (!args.files_touched || args.files_touched.length === 0) {
42102
+ return JSON.stringify({
42103
+ success: true,
42104
+ data: {
42105
+ passed: true,
42106
+ skipped: true,
42107
+ reason: "no files_touched provided",
42108
+ summary: "No files to verify",
42109
+ steps: [],
42110
+ blockers: []
42111
+ }
42112
+ }, null, 2);
42113
+ }
42114
+ const result = await runVerificationGate(args.files_touched, false);
42115
+ return JSON.stringify({
42116
+ success: true,
42117
+ data: {
42118
+ passed: result.passed,
42119
+ skipped: false,
42120
+ summary: result.summary,
42121
+ steps: result.steps.map((s) => ({
42122
+ name: s.name,
42123
+ command: s.command,
42124
+ passed: s.passed,
42125
+ exitCode: s.exitCode,
42126
+ skipped: s.skipped,
42127
+ skipReason: s.skipReason,
42128
+ error: s.error?.slice(0, 200),
42129
+ output: s.output?.slice(0, 200)
42130
+ })),
42131
+ blockers: result.blockers
42132
+ }
42133
+ }, null, 2);
42134
+ } catch (error45) {
42135
+ return JSON.stringify({
42136
+ success: false,
42137
+ error: `Verification failed: ${error45 instanceof Error ? error45.message : String(error45)}`
42138
+ }, null, 2);
42139
+ }
42140
+ }
42141
+ });
42142
+
42143
+ // src/swarm-orchestrate.ts
41969
42144
  function generateWorkerHandoff(params) {
41970
42145
  const handoff = {
41971
42146
  contract: {
@@ -42107,114 +42282,6 @@ ${progress.blockers.map((b) => `- ${b}`).join(`
42107
42282
 
42108
42283
  `);
42109
42284
  }
42110
- async function runTypecheckVerification() {
42111
- const step = {
42112
- name: "typecheck",
42113
- command: "tsc --noEmit",
42114
- passed: false,
42115
- exitCode: -1
42116
- };
42117
- try {
42118
- const tsconfigExists = await Bun.file("tsconfig.json").exists();
42119
- if (!tsconfigExists) {
42120
- step.skipped = true;
42121
- step.skipReason = "No tsconfig.json found";
42122
- step.passed = true;
42123
- return step;
42124
- }
42125
- const result = await Bun.$`tsc --noEmit`.quiet().nothrow();
42126
- step.exitCode = result.exitCode;
42127
- step.passed = result.exitCode === 0;
42128
- if (!step.passed) {
42129
- step.error = result.stderr.toString().slice(0, 1000);
42130
- step.output = result.stdout.toString().slice(0, 1000);
42131
- }
42132
- } catch (error45) {
42133
- step.skipped = true;
42134
- step.skipReason = `tsc not available: ${error45 instanceof Error ? error45.message : String(error45)}`;
42135
- step.passed = true;
42136
- }
42137
- return step;
42138
- }
42139
- async function runTestVerification(filesTouched) {
42140
- const step = {
42141
- name: "tests",
42142
- command: "bun test <related-files>",
42143
- passed: false,
42144
- exitCode: -1
42145
- };
42146
- if (filesTouched.length === 0) {
42147
- step.skipped = true;
42148
- step.skipReason = "No files touched";
42149
- step.passed = true;
42150
- return step;
42151
- }
42152
- const testPatterns = [];
42153
- for (const file2 of filesTouched) {
42154
- if (file2.includes(".test.") || file2.includes(".spec.")) {
42155
- testPatterns.push(file2);
42156
- continue;
42157
- }
42158
- const baseName = file2.replace(/\.(ts|tsx|js|jsx)$/, "");
42159
- testPatterns.push(`${baseName}.test.ts`);
42160
- testPatterns.push(`${baseName}.test.tsx`);
42161
- testPatterns.push(`${baseName}.spec.ts`);
42162
- }
42163
- const existingTests = [];
42164
- for (const pattern of testPatterns) {
42165
- try {
42166
- const exists = await Bun.file(pattern).exists();
42167
- if (exists) {
42168
- existingTests.push(pattern);
42169
- }
42170
- } catch {}
42171
- }
42172
- if (existingTests.length === 0) {
42173
- step.skipped = true;
42174
- step.skipReason = "No related test files found";
42175
- step.passed = true;
42176
- return step;
42177
- }
42178
- try {
42179
- step.command = `bun test ${existingTests.join(" ")}`;
42180
- const result = await Bun.$`bun test ${existingTests}`.quiet().nothrow();
42181
- step.exitCode = result.exitCode;
42182
- step.passed = result.exitCode === 0;
42183
- if (!step.passed) {
42184
- step.error = result.stderr.toString().slice(0, 1000);
42185
- step.output = result.stdout.toString().slice(0, 1000);
42186
- }
42187
- } catch (error45) {
42188
- step.skipped = true;
42189
- step.skipReason = `Test runner failed: ${error45 instanceof Error ? error45.message : String(error45)}`;
42190
- step.passed = true;
42191
- }
42192
- return step;
42193
- }
42194
- async function runVerificationGate(filesTouched, _skipUbs = false) {
42195
- const steps = [];
42196
- const blockers = [];
42197
- const typecheckStep = await runTypecheckVerification();
42198
- steps.push(typecheckStep);
42199
- if (!typecheckStep.passed && !typecheckStep.skipped) {
42200
- blockers.push(`Typecheck failed: ${typecheckStep.error?.slice(0, 100) || "type errors found"}. Try: Run 'tsc --noEmit' to see full errors, check tsconfig.json configuration, or fix reported type errors in modified files.`);
42201
- }
42202
- const testStep = await runTestVerification(filesTouched);
42203
- steps.push(testStep);
42204
- if (!testStep.passed && !testStep.skipped) {
42205
- blockers.push(`Tests failed: ${testStep.error?.slice(0, 100) || "test failures"}. Try: Run 'bun test ${testStep.command.split(" ").slice(2).join(" ")}' to see full output, check test assertions, or fix failing tests in modified files.`);
42206
- }
42207
- const passedCount = steps.filter((s) => s.passed).length;
42208
- const skippedCount = steps.filter((s) => s.skipped).length;
42209
- const failedCount = steps.filter((s) => !s.passed && !s.skipped).length;
42210
- const summary = failedCount === 0 ? `Verification passed: ${passedCount} checks passed, ${skippedCount} skipped` : `Verification FAILED: ${failedCount} checks failed, ${passedCount} passed, ${skippedCount} skipped`;
42211
- return {
42212
- passed: failedCount === 0,
42213
- steps,
42214
- summary,
42215
- blockers
42216
- };
42217
- }
42218
42285
  function classifyFailure(error45) {
42219
42286
  const msg = (typeof error45 === "string" ? error45 : error45.message).toLowerCase();
42220
42287
  if (msg.includes("timeout"))
@@ -42476,15 +42543,15 @@ var swarm_progress = tool({
42476
42543
  }
42477
42544
  };
42478
42545
  const checkpointData = JSON.stringify(checkpoint);
42479
- const checkpointEvent = createEvent3("swarm_checkpointed", {
42546
+ const checkpointEvent = createEvent4("swarm_checkpointed", {
42480
42547
  project_key: args.project_key,
42481
42548
  ...checkpoint,
42482
42549
  checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
42483
42550
  trigger: "progress"
42484
42551
  });
42485
- await appendEvent2(checkpointEvent, args.project_key);
42552
+ await appendEvent3(checkpointEvent, args.project_key);
42486
42553
  const checkpointId = `ckpt-${Date.now()}-${args.bead_id}`;
42487
- const createdEvent = createEvent3("checkpoint_created", {
42554
+ const createdEvent = createEvent4("checkpoint_created", {
42488
42555
  project_key: args.project_key,
42489
42556
  epic_id: epicId,
42490
42557
  bead_id: args.bead_id,
@@ -42494,7 +42561,7 @@ var swarm_progress = tool({
42494
42561
  progress_percent: args.progress_percent,
42495
42562
  files_snapshot: args.files_touched
42496
42563
  });
42497
- await appendEvent2(createdEvent, args.project_key);
42564
+ await appendEvent3(createdEvent, args.project_key);
42498
42565
  checkpointCreated = true;
42499
42566
  } catch (error45) {
42500
42567
  console.warn(`[swarm_progress] Auto-checkpoint failed at ${args.progress_percent}%:`, error45);
@@ -42797,7 +42864,7 @@ This will be recorded as a negative learning signal.`;
42797
42864
  const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
42798
42865
  let outcomeEventId;
42799
42866
  try {
42800
- const event = createEvent3("subtask_outcome", {
42867
+ const event = createEvent4("subtask_outcome", {
42801
42868
  project_key: args.project_key,
42802
42869
  epic_id: eventEpicId,
42803
42870
  bead_id: args.bead_id,
@@ -42810,7 +42877,7 @@ This will be recorded as a negative learning signal.`;
42810
42877
  scope_violation: contractValidation ? !contractValidation.valid : undefined,
42811
42878
  violation_files: contractValidation?.violations
42812
42879
  });
42813
- const savedEvent = await appendEvent2(event, args.project_key);
42880
+ const savedEvent = await appendEvent3(event, args.project_key);
42814
42881
  outcomeEventId = savedEvent.id;
42815
42882
  } catch (error45) {
42816
42883
  console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
@@ -42828,7 +42895,7 @@ This will be recorded as a negative learning signal.`;
42828
42895
  }
42829
42896
  }
42830
42897
  try {
42831
- const workerCompletedEvent = createEvent3("worker_completed", {
42898
+ const workerCompletedEvent = createEvent4("worker_completed", {
42832
42899
  project_key: args.project_key,
42833
42900
  epic_id: eventEpicId,
42834
42901
  bead_id: args.bead_id,
@@ -42837,7 +42904,7 @@ This will be recorded as a negative learning signal.`;
42837
42904
  duration_ms: completionDurationMs,
42838
42905
  files_touched: args.files_touched || []
42839
42906
  });
42840
- await appendEvent2(workerCompletedEvent, args.project_key);
42907
+ await appendEvent3(workerCompletedEvent, args.project_key);
42841
42908
  } catch (error45) {
42842
42909
  console.warn("[swarm_complete] Failed to emit worker_completed event:", error45);
42843
42910
  }
@@ -43561,7 +43628,7 @@ var swarm_checkpoint = tool({
43561
43628
  }
43562
43629
  };
43563
43630
  const checkpointData = JSON.stringify(checkpoint);
43564
- const event = createEvent3("swarm_checkpointed", {
43631
+ const event = createEvent4("swarm_checkpointed", {
43565
43632
  project_key: args.project_key,
43566
43633
  epic_id: args.epic_id,
43567
43634
  bead_id: args.bead_id,
@@ -43573,7 +43640,7 @@ var swarm_checkpoint = tool({
43573
43640
  checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
43574
43641
  trigger: args.error_context ? "error" : "manual"
43575
43642
  });
43576
- await appendEvent2(event, args.project_key);
43643
+ await appendEvent3(event, args.project_key);
43577
43644
  const now = Date.now();
43578
43645
  return JSON.stringify({
43579
43646
  success: true,
@@ -43631,13 +43698,13 @@ var swarm_recover = tool({
43631
43698
  created_at: row.created_at,
43632
43699
  updated_at: row.updated_at
43633
43700
  };
43634
- const event = createEvent3("swarm_recovered", {
43701
+ const event = createEvent4("swarm_recovered", {
43635
43702
  project_key: args.project_key,
43636
43703
  epic_id: args.epic_id,
43637
43704
  bead_id: context.bead_id,
43638
43705
  recovered_from_checkpoint: context.recovery.last_checkpoint
43639
43706
  });
43640
- await appendEvent2(event, args.project_key);
43707
+ await appendEvent3(event, args.project_key);
43641
43708
  return JSON.stringify({
43642
43709
  found: true,
43643
43710
  context,
@@ -44109,6 +44176,27 @@ swarmmail_reserve(
44109
44176
 
44110
44177
  **Workers reserve their own files.** This prevents edit conflicts with other agents.
44111
44178
 
44179
+ ### ⚠️ CRITICAL: File Path Handling (Next.js/Special Characters)
44180
+
44181
+ **DO NOT escape brackets or parentheses in file paths!**
44182
+
44183
+ When working with Next.js App Router or any codebase with special characters in paths:
44184
+
44185
+ ❌ **WRONG** (will fail):
44186
+ \`\`\`
44187
+ Read: app/\\(content\\)/events/\\[slug\\]/page.tsx
44188
+ Glob: src/**/\\[id\\]/**/*.ts
44189
+ \`\`\`
44190
+
44191
+ ✅ **CORRECT** (use raw paths):
44192
+ \`\`\`
44193
+ Read: app/(content)/events/[slug]/page.tsx
44194
+ Glob: src/**/[id]/**/*.ts
44195
+ \`\`\`
44196
+
44197
+ **The Read and Glob tools handle special characters automatically.**
44198
+ Never add backslashes before \`[\`, \`]\`, \`(\`, or \`)\` in file paths.
44199
+
44112
44200
  ### Step 5: Do the Work (TDD MANDATORY)
44113
44201
 
44114
44202
  **Follow RED → GREEN → REFACTOR. No exceptions.**
@@ -45319,9 +45407,9 @@ var swarm_spawn_subtask = tool({
45319
45407
  }
45320
45408
  if (args2.project_path) {
45321
45409
  try {
45322
- const { createEvent: createEvent5, appendEvent: appendEvent4 } = await import("swarm-mail");
45410
+ const { createEvent: createEvent6, appendEvent: appendEvent5 } = await import("swarm-mail");
45323
45411
  const spawnOrder = 0;
45324
- const workerSpawnedEvent = createEvent5("worker_spawned", {
45412
+ const workerSpawnedEvent = createEvent6("worker_spawned", {
45325
45413
  project_key: args2.project_path,
45326
45414
  epic_id: args2.epic_id,
45327
45415
  bead_id: args2.bead_id,
@@ -45331,7 +45419,7 @@ var swarm_spawn_subtask = tool({
45331
45419
  spawn_order: spawnOrder,
45332
45420
  is_parallel: false
45333
45421
  });
45334
- await appendEvent4(workerSpawnedEvent, args2.project_path);
45422
+ await appendEvent5(workerSpawnedEvent, args2.project_path);
45335
45423
  } catch (error45) {
45336
45424
  console.warn("[swarm_spawn_subtask] Failed to emit WorkerSpawnedEvent:", error45);
45337
45425
  }