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.
@@ -27992,6 +27992,11 @@ function withLock3(resource, effect4, config22) {
27992
27992
  return yield* _(service4.withLock(resource, effect4, config22));
27993
27993
  });
27994
27994
  }
27995
+ async function cleanupExpiredReservations(db2, projectKey) {
27996
+ const now3 = Date.now();
27997
+ const result = await db2.update(reservationsTable).set({ released_at: now3 }).where(and3(eq(reservationsTable.project_key, projectKey), sql`${reservationsTable.released_at} IS NULL`, sql`${reservationsTable.expires_at} < ${now3}`));
27998
+ return result.rowsAffected ?? 0;
27999
+ }
27995
28000
  async function getAgentsDrizzle(db2, projectKey) {
27996
28001
  const result = await db2.select().from(agentsTable).where(eq(agentsTable.project_key, projectKey)).orderBy(agentsTable.registered_at);
27997
28002
  return result.map((row) => ({
@@ -28088,7 +28093,7 @@ async function getThreadMessagesDrizzle(db2, projectKey, threadId) {
28088
28093
  }
28089
28094
  async function getActiveReservationsDrizzle(db2, projectKey, agentName) {
28090
28095
  const now3 = Date.now();
28091
- await db2.update(reservationsTable).set({ released_at: now3 }).where(and3(eq(reservationsTable.project_key, projectKey), sql`${reservationsTable.released_at} IS NULL`, sql`${reservationsTable.expires_at} < ${now3}`));
28096
+ await cleanupExpiredReservations(db2, projectKey);
28092
28097
  const conditions2 = [
28093
28098
  eq(reservationsTable.project_key, projectKey),
28094
28099
  sql`${reservationsTable.released_at} IS NULL`,
@@ -28789,12 +28794,10 @@ async function reserveSwarmFiles(options2) {
28789
28794
  } = options2;
28790
28795
  const { getOrCreateAdapter: getOrCreateAdapter3 } = await Promise.resolve().then(() => (init_store_drizzle(), exports_store_drizzle));
28791
28796
  const { toDrizzleDb: toDrizzleDb2 } = await Promise.resolve().then(() => (init_libsql_convenience(), exports_libsql_convenience));
28792
- const { reservationsTable: reservationsTable2 } = await Promise.resolve().then(() => (init_streams(), exports_streams));
28793
- const { eq: eq2, and: and4, sql: sql4 } = await Promise.resolve().then(() => (init_drizzle_orm(), exports_drizzle_orm));
28797
+ const { cleanupExpiredReservations: cleanupExpiredReservations2 } = await Promise.resolve().then(() => (init_reservation_utils(), exports_reservation_utils));
28794
28798
  const adapter5 = await getOrCreateAdapter3(projectPath, dbOverride);
28795
28799
  const swarmDb = toDrizzleDb2(adapter5);
28796
- const now3 = Date.now();
28797
- await swarmDb.update(reservationsTable2).set({ released_at: now3 }).where(and4(eq2(reservationsTable2.project_key, projectPath), sql4`${reservationsTable2.released_at} IS NULL`, sql4`${reservationsTable2.expires_at} < ${now3}`));
28800
+ await cleanupExpiredReservations2(swarmDb, projectPath);
28798
28801
  const conflicts = await checkConflicts2(projectPath, agentName, paths, projectPath, dbOverride);
28799
28802
  const reserveEvent = createEvent("file_reserved", {
28800
28803
  project_key: projectPath,
@@ -28828,12 +28831,10 @@ async function releaseSwarmFiles(options2) {
28828
28831
  const { projectPath, agentName, paths, reservationIds, dbOverride } = options2;
28829
28832
  const { getOrCreateAdapter: getOrCreateAdapter3 } = await Promise.resolve().then(() => (init_store_drizzle(), exports_store_drizzle));
28830
28833
  const { toDrizzleDb: toDrizzleDb2 } = await Promise.resolve().then(() => (init_libsql_convenience(), exports_libsql_convenience));
28831
- const { reservationsTable: reservationsTable2 } = await Promise.resolve().then(() => (init_streams(), exports_streams));
28832
- const { eq: eq2, and: and4, sql: sql4 } = await Promise.resolve().then(() => (init_drizzle_orm(), exports_drizzle_orm));
28834
+ const { cleanupExpiredReservations: cleanupExpiredReservations2 } = await Promise.resolve().then(() => (init_reservation_utils(), exports_reservation_utils));
28833
28835
  const adapter5 = await getOrCreateAdapter3(projectPath, dbOverride);
28834
28836
  const swarmDb = toDrizzleDb2(adapter5);
28835
- const now3 = Date.now();
28836
- await swarmDb.update(reservationsTable2).set({ released_at: now3 }).where(and4(eq2(reservationsTable2.project_key, projectPath), sql4`${reservationsTable2.released_at} IS NULL`, sql4`${reservationsTable2.expires_at} < ${now3}`));
28837
+ await cleanupExpiredReservations2(swarmDb, projectPath);
28837
28838
  const currentReservations = await getActiveReservations2(projectPath, projectPath, agentName, dbOverride);
28838
28839
  let releaseCount = 0;
28839
28840
  if (paths && paths.length > 0) {
@@ -30670,6 +30671,10 @@ function createMemoryStore(db2) {
30670
30671
  },
30671
30672
  async ftsSearch(searchQuery, options2 = {}) {
30672
30673
  const { limit = 10, collection } = options2;
30674
+ if (!searchQuery || typeof searchQuery !== "string") {
30675
+ console.warn("[store] ftsSearch called with invalid query, returning empty results");
30676
+ return [];
30677
+ }
30673
30678
  const quotedQuery = `"${searchQuery.replace(/"/g, '""')}"`;
30674
30679
  const conditions2 = collection ? sql`fts.content MATCH ${quotedQuery} AND m.collection = ${collection}` : sql`fts.content MATCH ${quotedQuery}`;
30675
30680
  const results = await db2.all(sql`
@@ -59956,7 +59961,7 @@ ${prefix}}`;
59956
59961
  fromDriver(value10) {
59957
59962
  return Array.from(new Float32Array(value10.buffer));
59958
59963
  }
59959
- }), memories, memoryLinks, entities, relationships, memoryEntities, init_memory, init_expressions2, exports_drizzle_orm, init_drizzle_orm, exports_streams, eventsTable, agentsTable, messagesTable, messageRecipientsTable, reservationsTable, locksTable, cursorsTable, evalRecordsTable, swarmContextsTable, decisionTracesTable, entityLinksTable, init_streams, exports_hive, beads, cells, cellEvents, beadLabels, cellLabels, beadComments, cellComments, beadDependencies, cellDependencies, blockedBeadsCache, dirtyBeads, schemaVersion, init_hive, exports_schema, init_schema, init_drizzle, require_entity, require_logger, require_query_promise, require_column, require_column_builder, require_table_utils, require_foreign_keys, require_tracing_utils, require_unique_constraint, require_array, require_common2, require_enum, require_subquery, require_version, require_tracing, require_view_common, require_table, require_sql, require_alias, require_selection_proxy, require_utils, require_delete, require_casing, require_errors, require_int_common, require_bigint, require_bigserial, require_boolean, require_char, require_cidr, require_custom, require_date_common, require_date, require_double_precision, require_inet, require_integer, require_interval, require_json, require_jsonb, require_line, require_macaddr, require_macaddr8, require_numeric, require_point, require_utils2, require_geometry, require_real, require_serial, require_smallint, require_smallserial, require_text, require_time, require_timestamp, require_uuid, require_varchar, require_bit, require_halfvec, require_sparsevec, require_vector, require_columns, require_all, require_table2, require_primary_keys, require_conditions, require_select, require_expressions, require_relations, require_aggregate, require_vector2, require_functions, require_sql2, require_view_base, require_dialect, require_query_builder, require_select2, require_query_builder2, require_insert, require_refresh_materialized_view, require_select_types, require_update, require_query_builders, require_count, require_query, require_raw, require_db, require_alias2, require_checks, require_indexes, require_policies, require_roles, require_sequence, require_view_common2, require_view, require_schema, require_session, require_subquery2, require_utils3, require_utils4, require_pg_core, require_session2, require_driver, require_pglite, exports_libsql_convenience, instances, init_libsql_convenience, exports_lock, DurableLock, DurableLockLive, init_lock, init_projections_drizzle, exports_store_drizzle, init_store_drizzle, exports_swarm_mail, MAX_INBOX_LIMIT = 5, DEFAULT_TTL_SECONDS = 3600, ADJECTIVES, NOUNS, init_swarm_mail, MAX_INBOX_LIMIT2 = 5, DEFAULT_TTL_SECONDS2 = 3600, ADJECTIVES2, NOUNS2, init_agent_mail, exports_migrations, beadsMigration, cellsViewMigration, cellsViewMigrationLibSQL, beadsMigrationLibSQL, beadsMigrations, hiveMigrations, sessionsMigrationLibSQL, hiveMigrationsLibSQL, init_migrations, memoryMigration, memoryMigrations, init_migrations2, exports_migrations2, migrations, init_migrations3, urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", POOL_SIZE_MULTIPLIER = 128, pool, poolOffset, init_nanoid = () => {}, init_decision_trace_store, ClientBuffer, init_client_buffer, exports_streams2, SLOW_QUERY_THRESHOLD_MS = 100, init_streams2, exports_store, adapterCache, TIMESTAMP_SAFE_UNTIL, init_store, init_adapter, exports_dependencies_drizzle, MAX_DEPENDENCY_DEPTH = 100, init_dependencies_drizzle, exports_projections_drizzle, init_projections_drizzle2, exports_dependencies, MAX_DEPENDENCY_DEPTH2 = 100, EMBEDDING_DIM2 = 1024, init_store2, OllamaError, Ollama, makeOllamaLive = (config22) => exports_Layer.succeed(Ollama, (() => {
59964
+ }), memories, memoryLinks, entities, relationships, memoryEntities, init_memory, init_expressions2, exports_drizzle_orm, init_drizzle_orm, exports_streams, eventsTable, agentsTable, messagesTable, messageRecipientsTable, reservationsTable, locksTable, cursorsTable, evalRecordsTable, swarmContextsTable, decisionTracesTable, entityLinksTable, init_streams, exports_hive, beads, cells, cellEvents, beadLabels, cellLabels, beadComments, cellComments, beadDependencies, cellDependencies, blockedBeadsCache, dirtyBeads, schemaVersion, init_hive, exports_schema, init_schema, init_drizzle, require_entity, require_logger, require_query_promise, require_column, require_column_builder, require_table_utils, require_foreign_keys, require_tracing_utils, require_unique_constraint, require_array, require_common2, require_enum, require_subquery, require_version, require_tracing, require_view_common, require_table, require_sql, require_alias, require_selection_proxy, require_utils, require_delete, require_casing, require_errors, require_int_common, require_bigint, require_bigserial, require_boolean, require_char, require_cidr, require_custom, require_date_common, require_date, require_double_precision, require_inet, require_integer, require_interval, require_json, require_jsonb, require_line, require_macaddr, require_macaddr8, require_numeric, require_point, require_utils2, require_geometry, require_real, require_serial, require_smallint, require_smallserial, require_text, require_time, require_timestamp, require_uuid, require_varchar, require_bit, require_halfvec, require_sparsevec, require_vector, require_columns, require_all, require_table2, require_primary_keys, require_conditions, require_select, require_expressions, require_relations, require_aggregate, require_vector2, require_functions, require_sql2, require_view_base, require_dialect, require_query_builder, require_select2, require_query_builder2, require_insert, require_refresh_materialized_view, require_select_types, require_update, require_query_builders, require_count, require_query, require_raw, require_db, require_alias2, require_checks, require_indexes, require_policies, require_roles, require_sequence, require_view_common2, require_view, require_schema, require_session, require_subquery2, require_utils3, require_utils4, require_pg_core, require_session2, require_driver, require_pglite, exports_libsql_convenience, instances, init_libsql_convenience, exports_lock, DurableLock, DurableLockLive, init_lock, exports_reservation_utils, init_reservation_utils, init_projections_drizzle, exports_store_drizzle, init_store_drizzle, exports_swarm_mail, MAX_INBOX_LIMIT = 5, DEFAULT_TTL_SECONDS = 3600, ADJECTIVES, NOUNS, init_swarm_mail, MAX_INBOX_LIMIT2 = 5, DEFAULT_TTL_SECONDS2 = 3600, ADJECTIVES2, NOUNS2, init_agent_mail, exports_migrations, beadsMigration, cellsViewMigration, cellsViewMigrationLibSQL, beadsMigrationLibSQL, beadsMigrations, hiveMigrations, sessionsMigrationLibSQL, hiveMigrationsLibSQL, init_migrations, memoryMigration, memoryMigrations, init_migrations2, exports_migrations2, migrations, init_migrations3, urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", POOL_SIZE_MULTIPLIER = 128, pool, poolOffset, init_nanoid = () => {}, init_decision_trace_store, ClientBuffer, init_client_buffer, exports_streams2, SLOW_QUERY_THRESHOLD_MS = 100, init_streams2, exports_store, adapterCache, TIMESTAMP_SAFE_UNTIL, init_store, init_adapter, exports_dependencies_drizzle, MAX_DEPENDENCY_DEPTH = 100, init_dependencies_drizzle, exports_projections_drizzle, init_projections_drizzle2, exports_dependencies, MAX_DEPENDENCY_DEPTH2 = 100, EMBEDDING_DIM2 = 1024, init_store2, OllamaError, Ollama, makeOllamaLive = (config22) => exports_Layer.succeed(Ollama, (() => {
59960
59965
  const embedSingle = (text3) => exports_Effect.gen(function* () {
59961
59966
  const response = yield* exports_Effect.tryPromise({
59962
59967
  try: () => fetch(`${config22.ollamaHost}/api/embeddings`, {
@@ -65947,7 +65952,7 @@ ${prefix}}`;
65947
65952
  return path22;
65948
65953
  }
65949
65954
  return sp2.join(cwd, path22);
65950
- }, EMPTY_SET, STAT_METHOD_F = "stat", STAT_METHOD_L = "lstat", FSWatcher, chokidar_default, FileWatcher, NormalizedMessageSchema, OpenCodeSwarmEventSchema, SWARM_MAIL_VERSION = "1.10.1";
65955
+ }, EMPTY_SET, STAT_METHOD_F = "stat", STAT_METHOD_L = "lstat", FSWatcher, chokidar_default, FileWatcher, NormalizedMessageSchema, OpenCodeSwarmEventSchema, SWARM_MAIL_VERSION = "1.10.4";
65951
65956
  var init_dist2 = __esm(() => {
65952
65957
  __create2 = Object.create;
65953
65958
  __getProtoOf2 = Object.getPrototypeOf;
@@ -110875,7 +110880,8 @@ ${stack.split(`
110875
110880
  }, (table5) => ({
110876
110881
  projectIdx: index("idx_messages_project").on(table5.project_key),
110877
110882
  threadIdIdx: index("idx_messages_thread").on(table5.thread_id),
110878
- createdIdx: index("idx_messages_created").on(table5.created_at)
110883
+ createdIdx: index("idx_messages_created").on(table5.created_at),
110884
+ senderTimeIdx: index("idx_messages_sender_time").on(table5.project_key, table5.from_agent, table5.created_at)
110879
110885
  }));
110880
110886
  messageRecipientsTable = sqliteTable("message_recipients", {
110881
110887
  message_id: integer4("message_id").notNull(),
@@ -110899,7 +110905,8 @@ ${stack.split(`
110899
110905
  }, (table5) => ({
110900
110906
  projectIdx: index("idx_reservations_project").on(table5.project_key),
110901
110907
  agentIdx: index("idx_reservations_agent").on(table5.agent_name),
110902
- expiresIdx: index("idx_reservations_expires").on(table5.expires_at)
110908
+ expiresIdx: index("idx_reservations_expires").on(table5.expires_at),
110909
+ activeIdx: index("idx_reservations_active").on(table5.project_key, table5.released_at, table5.expires_at)
110903
110910
  }));
110904
110911
  locksTable = sqliteTable("locks", {
110905
110912
  resource: text("resource").primaryKey(),
@@ -119729,10 +119736,19 @@ ${stack.split(`
119729
119736
  withLock: withLockImpl
119730
119737
  });
119731
119738
  });
119739
+ exports_reservation_utils = {};
119740
+ __export2(exports_reservation_utils, {
119741
+ cleanupExpiredReservations: () => cleanupExpiredReservations
119742
+ });
119743
+ init_reservation_utils = __esm2(() => {
119744
+ init_drizzle_orm();
119745
+ init_streams();
119746
+ });
119732
119747
  init_projections_drizzle = __esm2(() => {
119733
119748
  init_drizzle_orm();
119734
119749
  init_esm3();
119735
119750
  init_streams();
119751
+ init_reservation_utils();
119736
119752
  });
119737
119753
  exports_store_drizzle = {};
119738
119754
  __export2(exports_store_drizzle, {
@@ -145619,6 +145635,27 @@ var init_storage = __esm(() => {
145619
145635
  };
145620
145636
  });
145621
145637
 
145638
+ // src/utils/adapter-cache.ts
145639
+ class AdapterCache {
145640
+ cached = null;
145641
+ cachedPath = null;
145642
+ async get(projectPath, factory) {
145643
+ if (this.cached && this.cachedPath === projectPath) {
145644
+ return this.cached;
145645
+ }
145646
+ this.cached = await factory(projectPath);
145647
+ this.cachedPath = projectPath;
145648
+ return this.cached;
145649
+ }
145650
+ clear() {
145651
+ this.cached = null;
145652
+ this.cachedPath = null;
145653
+ }
145654
+ getCachedPath() {
145655
+ return this.cachedPath;
145656
+ }
145657
+ }
145658
+
145622
145659
  // ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Function.js
145623
145660
  function pipe3(a, ab, bc, cd, de, ef, fg, gh, hi) {
145624
145661
  switch (arguments.length) {
@@ -162935,6 +162972,9 @@ Linked to ${result.links.length} related memor${result.links.length === 1 ? "y"
162935
162972
  };
162936
162973
  },
162937
162974
  async find(args3) {
162975
+ if (!args3.query || typeof args3.query !== "string") {
162976
+ throw new Error("query is required for find operation");
162977
+ }
162938
162978
  const limit = args3.limit ?? 10;
162939
162979
  let results;
162940
162980
  let usedFallback = false;
@@ -163056,24 +163096,21 @@ var init_memory2 = __esm(() => {
163056
163096
  // src/memory-tools.ts
163057
163097
  async function getMemoryAdapter(projectPath) {
163058
163098
  const path4 = projectPath || process.cwd();
163059
- if (cachedAdapter && cachedProjectPath === path4) {
163060
- return cachedAdapter;
163061
- }
163062
- const swarmMail = await getSwarmMailLibSQL(path4);
163063
- const dbAdapter = await swarmMail.getDatabase();
163064
- cachedAdapter = await createMemoryAdapter2(dbAdapter);
163065
- cachedProjectPath = path4;
163066
- return cachedAdapter;
163099
+ return memoryAdapterCache.get(path4, async (projectPath2) => {
163100
+ const swarmMail = await getSwarmMailLibSQL(projectPath2);
163101
+ const dbAdapter = await swarmMail.getDatabase();
163102
+ return await createMemoryAdapter2(dbAdapter);
163103
+ });
163067
163104
  }
163068
163105
  function resetMemoryCache() {
163069
- cachedAdapter = null;
163070
- cachedProjectPath = null;
163106
+ memoryAdapterCache.clear();
163071
163107
  }
163072
- 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, memoryTools;
163108
+ 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, memoryTools;
163073
163109
  var init_memory_tools = __esm(() => {
163074
163110
  init_dist();
163075
163111
  init_dist2();
163076
163112
  init_memory2();
163113
+ memoryAdapterCache = new AdapterCache;
163077
163114
  semantic_memory_store = tool({
163078
163115
  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.",
163079
163116
  args: {
@@ -163090,7 +163127,7 @@ var init_memory_tools = __esm(() => {
163090
163127
  const adapter5 = await getMemoryAdapter();
163091
163128
  const result = await adapter5.store(args3);
163092
163129
  try {
163093
- const projectKey = cachedProjectPath || process.cwd();
163130
+ const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
163094
163131
  const tags3 = args3.tags ? args3.tags.split(",").map((t) => t.trim()) : [];
163095
163132
  const event = createEvent("memory_stored", {
163096
163133
  project_key: projectKey,
@@ -163122,7 +163159,7 @@ var init_memory_tools = __esm(() => {
163122
163159
  const result = await adapter5.find(args3);
163123
163160
  const duration7 = Date.now() - startTime;
163124
163161
  try {
163125
- const projectKey = cachedProjectPath || process.cwd();
163162
+ const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
163126
163163
  const topScore = result.results.length > 0 ? result.results[0].score : undefined;
163127
163164
  const event = createEvent("memory_found", {
163128
163165
  project_key: projectKey,
@@ -163160,7 +163197,7 @@ var init_memory_tools = __esm(() => {
163160
163197
  const result = await adapter5.remove(args3);
163161
163198
  if (result.success) {
163162
163199
  try {
163163
- const projectKey = cachedProjectPath || process.cwd();
163200
+ const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
163164
163201
  const event = createEvent("memory_deleted", {
163165
163202
  project_key: projectKey,
163166
163203
  memory_id: args3.id
@@ -163183,7 +163220,7 @@ var init_memory_tools = __esm(() => {
163183
163220
  const result = await adapter5.validate(args3);
163184
163221
  if (result.success) {
163185
163222
  try {
163186
- const projectKey = cachedProjectPath || process.cwd();
163223
+ const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
163187
163224
  const event = createEvent("memory_validated", {
163188
163225
  project_key: projectKey,
163189
163226
  memory_id: args3.id,
@@ -163242,7 +163279,7 @@ var init_memory_tools = __esm(() => {
163242
163279
  const adapter5 = await getMemoryAdapter();
163243
163280
  const result = await adapter5.upsert(args3);
163244
163281
  try {
163245
- const projectKey = cachedProjectPath || process.cwd();
163282
+ const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
163246
163283
  const event = createEvent("memory_updated", {
163247
163284
  project_key: projectKey,
163248
163285
  memory_id: result.memoryId || "unknown",
@@ -175565,6 +175602,23 @@ var isBeadEventType = isCellEventType;
175565
175602
  var getBeadIdFromEvent = getCellIdFromEvent;
175566
175603
  // src/hive.ts
175567
175604
  init_dist2();
175605
+
175606
+ // src/utils/event-utils.ts
175607
+ init_dist2();
175608
+ async function safeEmitEvent(eventType, data, toolName, projectPath) {
175609
+ try {
175610
+ const effectiveProjectPath = projectPath || process.cwd();
175611
+ const event = createEvent(eventType, {
175612
+ project_key: effectiveProjectPath,
175613
+ ...data
175614
+ });
175615
+ await appendEvent(event, effectiveProjectPath);
175616
+ } catch (error47) {
175617
+ console.warn(`[${toolName}] Failed to emit ${eventType} event:`, error47);
175618
+ }
175619
+ }
175620
+
175621
+ // src/hive.ts
175568
175622
  var hiveWorkingDirectory = null;
175569
175623
  function setHiveWorkingDirectory(directory) {
175570
175624
  hiveWorkingDirectory = directory;
@@ -175873,20 +175927,14 @@ var hive_create = tool({
175873
175927
  parent_id: validated.parent_id
175874
175928
  });
175875
175929
  await adapter5.markDirty(projectKey, cell.id);
175876
- try {
175877
- const event = createEvent("cell_created", {
175878
- project_key: projectKey,
175879
- cell_id: cell.id,
175880
- title: validated.title,
175881
- description: validated.description,
175882
- issue_type: validated.type || "task",
175883
- priority: validated.priority ?? 2,
175884
- parent_id: validated.parent_id
175885
- });
175886
- await appendEvent(event, projectKey);
175887
- } catch (error47) {
175888
- console.warn("[hive_create] Failed to emit cell_created event:", error47);
175889
- }
175930
+ await safeEmitEvent("cell_created", {
175931
+ cell_id: cell.id,
175932
+ title: validated.title,
175933
+ description: validated.description,
175934
+ issue_type: validated.type || "task",
175935
+ priority: validated.priority ?? 2,
175936
+ parent_id: validated.parent_id
175937
+ }, "hive_create", projectKey);
175890
175938
  const formatted = formatCellForOutput(cell);
175891
175939
  return JSON.stringify(formatted, null, 2);
175892
175940
  } catch (error47) {
@@ -175968,53 +176016,35 @@ var hive_create_epic = tool({
175968
176016
  subtasks: created.slice(1).map((c) => formatCellForOutput(c))
175969
176017
  };
175970
176018
  const effectiveProjectKey = args2.project_key || projectKey;
175971
- try {
175972
- const epicCreatedEvent = createEvent("epic_created", {
175973
- project_key: effectiveProjectKey,
175974
- epic_id: epic.id,
175975
- title: validated.epic_title,
175976
- description: validated.epic_description,
175977
- subtask_count: validated.subtasks.length,
175978
- subtask_ids: created.slice(1).map((c) => c.id)
175979
- });
175980
- await appendEvent(epicCreatedEvent, effectiveProjectKey);
175981
- } catch (error47) {
175982
- console.warn("[hive_create_epic] Failed to emit epic_created event:", error47);
175983
- }
175984
- try {
175985
- const event = createEvent("decomposition_generated", {
175986
- project_key: effectiveProjectKey,
175987
- epic_id: epic.id,
175988
- task: args2.task || validated.epic_title,
175989
- context: validated.epic_description,
175990
- strategy: args2.strategy || "feature-based",
175991
- epic_title: validated.epic_title,
175992
- subtasks: validated.subtasks.map((st) => ({
175993
- title: st.title,
175994
- files: st.files || [],
175995
- priority: st.priority
175996
- })),
175997
- recovery_context: args2.recovery_context
175998
- });
175999
- await appendEvent(event, effectiveProjectKey);
176000
- } catch (error47) {
176001
- console.warn("[hive_create_epic] Failed to emit DecompositionGeneratedEvent:", error47);
176002
- }
176003
- try {
176004
- const totalFiles = validated.subtasks.reduce((count10, st) => count10 + (st.files?.length || 0), 0);
176005
- const swarmStartedEvent = createEvent("swarm_started", {
176006
- project_key: effectiveProjectKey,
176007
- epic_id: epic.id,
176008
- epic_title: validated.epic_title,
176009
- strategy: args2.strategy || "feature-based",
176010
- subtask_count: validated.subtasks.length,
176011
- total_files: totalFiles,
176012
- coordinator_agent: "coordinator"
176013
- });
176014
- await appendEvent(swarmStartedEvent, effectiveProjectKey);
176015
- } catch (error47) {
176016
- console.warn("[hive_create_epic] Failed to emit SwarmStartedEvent:", error47);
176017
- }
176019
+ await safeEmitEvent("epic_created", {
176020
+ epic_id: epic.id,
176021
+ title: validated.epic_title,
176022
+ description: validated.epic_description,
176023
+ subtask_count: validated.subtasks.length,
176024
+ subtask_ids: created.slice(1).map((c) => c.id)
176025
+ }, "hive_create_epic", effectiveProjectKey);
176026
+ await safeEmitEvent("decomposition_generated", {
176027
+ epic_id: epic.id,
176028
+ task: args2.task || validated.epic_title,
176029
+ context: validated.epic_description,
176030
+ strategy: args2.strategy || "feature-based",
176031
+ epic_title: validated.epic_title,
176032
+ subtasks: validated.subtasks.map((st) => ({
176033
+ title: st.title,
176034
+ files: st.files || [],
176035
+ priority: st.priority
176036
+ })),
176037
+ recovery_context: args2.recovery_context
176038
+ }, "hive_create_epic", effectiveProjectKey);
176039
+ const totalFiles = validated.subtasks.reduce((count10, st) => count10 + (st.files?.length || 0), 0);
176040
+ await safeEmitEvent("swarm_started", {
176041
+ epic_id: epic.id,
176042
+ epic_title: validated.epic_title,
176043
+ strategy: args2.strategy || "feature-based",
176044
+ subtask_count: validated.subtasks.length,
176045
+ total_files: totalFiles,
176046
+ coordinator_agent: "coordinator"
176047
+ }, "hive_create_epic", effectiveProjectKey);
176018
176048
  try {
176019
176049
  const { captureCoordinatorEvent: captureCoordinatorEvent2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
176020
176050
  const filesPerSubtask = {};
@@ -176145,23 +176175,17 @@ var hive_update = tool({
176145
176175
  cell = existingCell;
176146
176176
  }
176147
176177
  await adapter5.markDirty(projectKey, cellId);
176148
- try {
176149
- const fieldsChanged = [];
176150
- if (validated.status)
176151
- fieldsChanged.push("status");
176152
- if (validated.description !== undefined)
176153
- fieldsChanged.push("description");
176154
- if (validated.priority !== undefined)
176155
- fieldsChanged.push("priority");
176156
- const event = createEvent("cell_updated", {
176157
- project_key: projectKey,
176158
- cell_id: cellId,
176159
- fields_changed: fieldsChanged
176160
- });
176161
- await appendEvent(event, projectKey);
176162
- } catch (error47) {
176163
- console.warn("[hive_update] Failed to emit cell_updated event:", error47);
176164
- }
176178
+ const fieldsChanged = [];
176179
+ if (validated.status)
176180
+ fieldsChanged.push("status");
176181
+ if (validated.description !== undefined)
176182
+ fieldsChanged.push("description");
176183
+ if (validated.priority !== undefined)
176184
+ fieldsChanged.push("priority");
176185
+ await safeEmitEvent("cell_updated", {
176186
+ cell_id: cellId,
176187
+ fields_changed: fieldsChanged
176188
+ }, "hive_update", projectKey);
176165
176189
  const formatted = formatCellForOutput(cell);
176166
176190
  return JSON.stringify(formatted, null, 2);
176167
176191
  } catch (error47) {
@@ -176194,7 +176218,6 @@ var hive_close = tool({
176194
176218
  await adapter5.markDirty(projectKey, cellId);
176195
176219
  if (isEpic && cellBeforeClose) {
176196
176220
  try {
176197
- const { createEvent: createEvent2, appendEvent: appendEvent3 } = await Promise.resolve().then(() => (init_dist2(), exports_dist));
176198
176221
  const subtasks = await adapter5.queryCells(projectKey, { parent_id: cellId });
176199
176222
  const completedSubtasks = subtasks.filter((st) => st.status === "closed");
176200
176223
  const failedSubtasks = subtasks.filter((st) => st.status === "blocked");
@@ -176232,8 +176255,7 @@ var hive_close = tool({
176232
176255
  } catch (error47) {
176233
176256
  console.warn("[hive_close] Failed to calculate duration:", error47);
176234
176257
  }
176235
- const swarmCompletedEvent = createEvent2("swarm_completed", {
176236
- project_key: projectKey,
176258
+ await safeEmitEvent("swarm_completed", {
176237
176259
  epic_id: cellId,
176238
176260
  epic_title: cellBeforeClose.title,
176239
176261
  success: failedSubtasks.length === 0,
@@ -176241,8 +176263,7 @@ var hive_close = tool({
176241
176263
  subtasks_completed: completedSubtasks.length,
176242
176264
  subtasks_failed: failedSubtasks.length,
176243
176265
  total_files_touched: totalFilesTouched
176244
- });
176245
- await appendEvent3(swarmCompletedEvent, projectKey);
176266
+ }, "hive_close", projectKey);
176246
176267
  try {
176247
176268
  const { runPostSwarmValidation: runPostSwarmValidation2 } = await Promise.resolve().then(() => (init_swarm_validation(), exports_swarm_validation));
176248
176269
  const { readEvents: readEvents3 } = await Promise.resolve().then(() => (init_dist2(), exports_dist));
@@ -176262,7 +176283,7 @@ var hive_close = tool({
176262
176283
  swarm_id: cellId,
176263
176284
  started_at: new Date,
176264
176285
  emit: async (event) => {
176265
- await appendEvent3(event, projectKey);
176286
+ await appendEvent(event, projectKey);
176266
176287
  }
176267
176288
  }, swarmEvents).then((result) => {
176268
176289
  if (!result.passed) {
@@ -176278,16 +176299,10 @@ var hive_close = tool({
176278
176299
  console.warn("[hive_close] Failed to emit SwarmCompletedEvent:", error47);
176279
176300
  }
176280
176301
  }
176281
- try {
176282
- const event = createEvent("cell_closed", {
176283
- project_key: projectKey,
176284
- cell_id: cellId,
176285
- reason: validated.reason
176286
- });
176287
- await appendEvent(event, projectKey);
176288
- } catch (error47) {
176289
- console.warn("[hive_close] Failed to emit cell_closed event:", error47);
176290
- }
176302
+ await safeEmitEvent("cell_closed", {
176303
+ cell_id: cellId,
176304
+ reason: validated.reason
176305
+ }, "hive_close", projectKey);
176291
176306
  return `Closed ${cell.id}: ${validated.reason}`;
176292
176307
  } catch (error47) {
176293
176308
  const message = error47 instanceof Error ? error47.message : String(error47);
@@ -178667,10 +178682,13 @@ var swarmmail_read_message = tool({
178667
178682
  }
178668
178683
  }
178669
178684
  });
178685
+ function normalizePath2(path4) {
178686
+ return path4.replace(/\\([[\]()])/g, "$1");
178687
+ }
178670
178688
  var swarmmail_reserve = tool({
178671
- description: "Reserve file paths for exclusive editing. Prevents conflicts with other agents.",
178689
+ description: "Reserve file paths for exclusive editing. Prevents conflicts with other agents. " + "IMPORTANT: Do NOT escape brackets or parentheses - paths like app/(content)/[slug]/page.tsx work as-is.",
178672
178690
  args: {
178673
- paths: tool.schema.array(tool.schema.string()).describe("File paths or glob patterns to reserve"),
178691
+ paths: tool.schema.array(tool.schema.string()).transform((paths) => paths.map(normalizePath2)).describe("File paths or glob patterns to reserve. Do NOT escape [ ] ( ) characters."),
178674
178692
  reason: tool.schema.string().optional().describe("Reason for reservation (e.g., bead ID)"),
178675
178693
  exclusive: tool.schema.boolean().optional().describe("Whether reservation is exclusive (default: true)"),
178676
178694
  ttl_seconds: tool.schema.number().optional().describe("Time-to-live in seconds (default: 3600)")
@@ -178682,10 +178700,11 @@ var swarmmail_reserve = tool({
178682
178700
  return JSON.stringify({ error: "Session not initialized. Call swarmmail_init first." }, null, 2);
178683
178701
  }
178684
178702
  try {
178703
+ const normalizedPaths = args2.paths.map(normalizePath2);
178685
178704
  const result = await reserveSwarmFiles({
178686
178705
  projectPath: state.projectKey,
178687
178706
  agentName: state.agentName,
178688
- paths: args2.paths,
178707
+ paths: normalizedPaths,
178689
178708
  reason: args2.reason,
178690
178709
  exclusive: args2.exclusive ?? true,
178691
178710
  ttlSeconds: args2.ttl_seconds
@@ -178713,9 +178732,9 @@ var swarmmail_reserve = tool({
178713
178732
  }
178714
178733
  });
178715
178734
  var swarmmail_release = tool({
178716
- description: "Release file reservations. Call when done editing files.",
178735
+ description: "Release file reservations. Call when done editing files. " + "Do NOT escape brackets or parentheses in paths.",
178717
178736
  args: {
178718
- paths: tool.schema.array(tool.schema.string()).optional().describe("Specific paths to release (releases all if omitted)"),
178737
+ paths: tool.schema.array(tool.schema.string()).optional().describe("Specific paths to release (releases all if omitted). Do NOT escape [ ] ( ) characters."),
178719
178738
  reservation_ids: tool.schema.array(tool.schema.number()).optional().describe("Specific reservation IDs to release")
178720
178739
  },
178721
178740
  async execute(args2, ctx) {
@@ -178726,10 +178745,11 @@ var swarmmail_release = tool({
178726
178745
  }
178727
178746
  try {
178728
178747
  const currentReservations = await getActiveReservations2(state.projectKey, state.projectKey, state.agentName);
178748
+ const normalizedPaths = args2.paths?.map(normalizePath2);
178729
178749
  const result = await releaseSwarmFiles({
178730
178750
  projectPath: state.projectKey,
178731
178751
  agentName: state.agentName,
178732
- paths: args2.paths,
178752
+ paths: normalizedPaths,
178733
178753
  reservationIds: args2.reservation_ids
178734
178754
  });
178735
178755
  if (!args2.paths && !args2.reservation_ids) {
@@ -182351,6 +182371,184 @@ var reviewTools = {
182351
182371
 
182352
182372
  // src/swarm-orchestrate.ts
182353
182373
  init_eval_capture();
182374
+
182375
+ // src/swarm-verify.ts
182376
+ init_dist();
182377
+ async function runTypecheckVerification() {
182378
+ const step4 = {
182379
+ name: "typecheck",
182380
+ command: "tsc --noEmit",
182381
+ passed: false,
182382
+ exitCode: -1
182383
+ };
182384
+ try {
182385
+ const tsconfigExists = await Bun.file("tsconfig.json").exists();
182386
+ if (!tsconfigExists) {
182387
+ step4.skipped = true;
182388
+ step4.skipReason = "No tsconfig.json found";
182389
+ step4.passed = true;
182390
+ return step4;
182391
+ }
182392
+ const result = await Bun.$`tsc --noEmit`.quiet().nothrow();
182393
+ step4.exitCode = result.exitCode;
182394
+ step4.passed = result.exitCode === 0;
182395
+ if (!step4.passed) {
182396
+ step4.error = result.stderr.toString().slice(0, 1000);
182397
+ step4.output = result.stdout.toString().slice(0, 1000);
182398
+ }
182399
+ } catch (error47) {
182400
+ step4.skipped = true;
182401
+ step4.skipReason = `tsc not available: ${error47 instanceof Error ? error47.message : String(error47)}`;
182402
+ step4.passed = true;
182403
+ }
182404
+ return step4;
182405
+ }
182406
+ async function runTestVerification(filesTouched) {
182407
+ const step4 = {
182408
+ name: "tests",
182409
+ command: "bun test <related-files>",
182410
+ passed: false,
182411
+ exitCode: -1
182412
+ };
182413
+ if (filesTouched.length === 0) {
182414
+ step4.skipped = true;
182415
+ step4.skipReason = "No files touched";
182416
+ step4.passed = true;
182417
+ return step4;
182418
+ }
182419
+ const testPatterns = [];
182420
+ for (const file3 of filesTouched) {
182421
+ if (file3.includes(".test.") || file3.includes(".spec.")) {
182422
+ testPatterns.push(file3);
182423
+ continue;
182424
+ }
182425
+ const baseName = file3.replace(/\.(ts|tsx|js|jsx)$/, "");
182426
+ testPatterns.push(`${baseName}.test.ts`);
182427
+ testPatterns.push(`${baseName}.test.tsx`);
182428
+ testPatterns.push(`${baseName}.spec.ts`);
182429
+ }
182430
+ const existingTests = [];
182431
+ for (const pattern2 of testPatterns) {
182432
+ try {
182433
+ const exists8 = await Bun.file(pattern2).exists();
182434
+ if (exists8) {
182435
+ existingTests.push(pattern2);
182436
+ }
182437
+ } catch {}
182438
+ }
182439
+ if (existingTests.length === 0) {
182440
+ step4.skipped = true;
182441
+ step4.skipReason = "No related test files found";
182442
+ step4.passed = true;
182443
+ return step4;
182444
+ }
182445
+ try {
182446
+ step4.command = `bun test ${existingTests.join(" ")}`;
182447
+ const result = await Bun.$`bun test ${existingTests}`.quiet().nothrow();
182448
+ step4.exitCode = result.exitCode;
182449
+ step4.passed = result.exitCode === 0;
182450
+ if (!step4.passed) {
182451
+ step4.error = result.stderr.toString().slice(0, 1000);
182452
+ step4.output = result.stdout.toString().slice(0, 1000);
182453
+ }
182454
+ } catch (error47) {
182455
+ step4.skipped = true;
182456
+ step4.skipReason = `Test runner failed: ${error47 instanceof Error ? error47.message : String(error47)}`;
182457
+ step4.passed = true;
182458
+ }
182459
+ return step4;
182460
+ }
182461
+ async function runVerificationGate(filesTouched, _skipUbs = false) {
182462
+ const steps = [];
182463
+ const blockers = [];
182464
+ const typecheckStep = await runTypecheckVerification();
182465
+ steps.push(typecheckStep);
182466
+ if (!typecheckStep.passed && !typecheckStep.skipped) {
182467
+ 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.`);
182468
+ }
182469
+ const testStep = await runTestVerification(filesTouched);
182470
+ steps.push(testStep);
182471
+ if (!testStep.passed && !testStep.skipped) {
182472
+ 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.`);
182473
+ }
182474
+ const passedCount = steps.filter((s) => s.passed).length;
182475
+ const skippedCount = steps.filter((s) => s.skipped).length;
182476
+ const failedCount = steps.filter((s) => !s.passed && !s.skipped).length;
182477
+ const summary11 = failedCount === 0 ? `Verification passed: ${passedCount} checks passed, ${skippedCount} skipped` : `Verification FAILED: ${failedCount} checks failed, ${passedCount} passed, ${skippedCount} skipped`;
182478
+ return {
182479
+ passed: failedCount === 0,
182480
+ steps,
182481
+ summary: summary11,
182482
+ blockers
182483
+ };
182484
+ }
182485
+ var swarm_verify = tool({
182486
+ description: "Run verification gate (typecheck + tests) for files. Returns verification results without blocking. Used by swarm_complete to verify worker output.",
182487
+ args: {
182488
+ files_touched: tool.schema.array(tool.schema.string()).describe("Files to verify (typecheck + test discovery)"),
182489
+ skip_verification: tool.schema.boolean().optional().describe("Skip verification entirely (default: false)")
182490
+ },
182491
+ async execute(args2) {
182492
+ try {
182493
+ if (args2.skip_verification) {
182494
+ return JSON.stringify({
182495
+ success: true,
182496
+ data: {
182497
+ passed: true,
182498
+ skipped: true,
182499
+ reason: "skip_verification=true",
182500
+ summary: "Verification skipped by request",
182501
+ steps: [],
182502
+ blockers: []
182503
+ }
182504
+ }, null, 2);
182505
+ }
182506
+ if (!args2.files_touched || args2.files_touched.length === 0) {
182507
+ return JSON.stringify({
182508
+ success: true,
182509
+ data: {
182510
+ passed: true,
182511
+ skipped: true,
182512
+ reason: "no files_touched provided",
182513
+ summary: "No files to verify",
182514
+ steps: [],
182515
+ blockers: []
182516
+ }
182517
+ }, null, 2);
182518
+ }
182519
+ const result = await runVerificationGate(args2.files_touched, false);
182520
+ return JSON.stringify({
182521
+ success: true,
182522
+ data: {
182523
+ passed: result.passed,
182524
+ skipped: false,
182525
+ summary: result.summary,
182526
+ steps: result.steps.map((s) => ({
182527
+ name: s.name,
182528
+ command: s.command,
182529
+ passed: s.passed,
182530
+ exitCode: s.exitCode,
182531
+ skipped: s.skipped,
182532
+ skipReason: s.skipReason,
182533
+ error: s.error?.slice(0, 200),
182534
+ output: s.output?.slice(0, 200)
182535
+ })),
182536
+ blockers: result.blockers
182537
+ }
182538
+ }, null, 2);
182539
+ } catch (error47) {
182540
+ return JSON.stringify({
182541
+ success: false,
182542
+ error: `Verification failed: ${error47 instanceof Error ? error47.message : String(error47)}`
182543
+ }, null, 2);
182544
+ }
182545
+ }
182546
+ });
182547
+ var verificationTools = {
182548
+ swarm_verify
182549
+ };
182550
+
182551
+ // src/swarm-orchestrate.ts
182354
182552
  function generateWorkerHandoff(params) {
182355
182553
  const handoff = {
182356
182554
  contract: {
@@ -182492,114 +182690,6 @@ ${progress.blockers.map((b) => `- ${b}`).join(`
182492
182690
 
182493
182691
  `);
182494
182692
  }
182495
- async function runTypecheckVerification() {
182496
- const step4 = {
182497
- name: "typecheck",
182498
- command: "tsc --noEmit",
182499
- passed: false,
182500
- exitCode: -1
182501
- };
182502
- try {
182503
- const tsconfigExists = await Bun.file("tsconfig.json").exists();
182504
- if (!tsconfigExists) {
182505
- step4.skipped = true;
182506
- step4.skipReason = "No tsconfig.json found";
182507
- step4.passed = true;
182508
- return step4;
182509
- }
182510
- const result = await Bun.$`tsc --noEmit`.quiet().nothrow();
182511
- step4.exitCode = result.exitCode;
182512
- step4.passed = result.exitCode === 0;
182513
- if (!step4.passed) {
182514
- step4.error = result.stderr.toString().slice(0, 1000);
182515
- step4.output = result.stdout.toString().slice(0, 1000);
182516
- }
182517
- } catch (error47) {
182518
- step4.skipped = true;
182519
- step4.skipReason = `tsc not available: ${error47 instanceof Error ? error47.message : String(error47)}`;
182520
- step4.passed = true;
182521
- }
182522
- return step4;
182523
- }
182524
- async function runTestVerification(filesTouched) {
182525
- const step4 = {
182526
- name: "tests",
182527
- command: "bun test <related-files>",
182528
- passed: false,
182529
- exitCode: -1
182530
- };
182531
- if (filesTouched.length === 0) {
182532
- step4.skipped = true;
182533
- step4.skipReason = "No files touched";
182534
- step4.passed = true;
182535
- return step4;
182536
- }
182537
- const testPatterns = [];
182538
- for (const file3 of filesTouched) {
182539
- if (file3.includes(".test.") || file3.includes(".spec.")) {
182540
- testPatterns.push(file3);
182541
- continue;
182542
- }
182543
- const baseName = file3.replace(/\.(ts|tsx|js|jsx)$/, "");
182544
- testPatterns.push(`${baseName}.test.ts`);
182545
- testPatterns.push(`${baseName}.test.tsx`);
182546
- testPatterns.push(`${baseName}.spec.ts`);
182547
- }
182548
- const existingTests = [];
182549
- for (const pattern2 of testPatterns) {
182550
- try {
182551
- const exists8 = await Bun.file(pattern2).exists();
182552
- if (exists8) {
182553
- existingTests.push(pattern2);
182554
- }
182555
- } catch {}
182556
- }
182557
- if (existingTests.length === 0) {
182558
- step4.skipped = true;
182559
- step4.skipReason = "No related test files found";
182560
- step4.passed = true;
182561
- return step4;
182562
- }
182563
- try {
182564
- step4.command = `bun test ${existingTests.join(" ")}`;
182565
- const result = await Bun.$`bun test ${existingTests}`.quiet().nothrow();
182566
- step4.exitCode = result.exitCode;
182567
- step4.passed = result.exitCode === 0;
182568
- if (!step4.passed) {
182569
- step4.error = result.stderr.toString().slice(0, 1000);
182570
- step4.output = result.stdout.toString().slice(0, 1000);
182571
- }
182572
- } catch (error47) {
182573
- step4.skipped = true;
182574
- step4.skipReason = `Test runner failed: ${error47 instanceof Error ? error47.message : String(error47)}`;
182575
- step4.passed = true;
182576
- }
182577
- return step4;
182578
- }
182579
- async function runVerificationGate(filesTouched, _skipUbs = false) {
182580
- const steps = [];
182581
- const blockers = [];
182582
- const typecheckStep = await runTypecheckVerification();
182583
- steps.push(typecheckStep);
182584
- if (!typecheckStep.passed && !typecheckStep.skipped) {
182585
- 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.`);
182586
- }
182587
- const testStep = await runTestVerification(filesTouched);
182588
- steps.push(testStep);
182589
- if (!testStep.passed && !testStep.skipped) {
182590
- 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.`);
182591
- }
182592
- const passedCount = steps.filter((s) => s.passed).length;
182593
- const skippedCount = steps.filter((s) => s.skipped).length;
182594
- const failedCount = steps.filter((s) => !s.passed && !s.skipped).length;
182595
- const summary11 = failedCount === 0 ? `Verification passed: ${passedCount} checks passed, ${skippedCount} skipped` : `Verification FAILED: ${failedCount} checks failed, ${passedCount} passed, ${skippedCount} skipped`;
182596
- return {
182597
- passed: failedCount === 0,
182598
- steps,
182599
- summary: summary11,
182600
- blockers
182601
- };
182602
- }
182603
182693
  function classifyFailure(error47) {
182604
182694
  const msg = (typeof error47 === "string" ? error47 : error47.message).toLowerCase();
182605
182695
  if (msg.includes("timeout"))
@@ -184443,6 +184533,27 @@ swarmmail_reserve(
184443
184533
 
184444
184534
  **Workers reserve their own files.** This prevents edit conflicts with other agents.
184445
184535
 
184536
+ ### ⚠️ CRITICAL: File Path Handling (Next.js/Special Characters)
184537
+
184538
+ **DO NOT escape brackets or parentheses in file paths!**
184539
+
184540
+ When working with Next.js App Router or any codebase with special characters in paths:
184541
+
184542
+ ❌ **WRONG** (will fail):
184543
+ \`\`\`
184544
+ Read: app/\\(content\\)/events/\\[slug\\]/page.tsx
184545
+ Glob: src/**/\\[id\\]/**/*.ts
184546
+ \`\`\`
184547
+
184548
+ ✅ **CORRECT** (use raw paths):
184549
+ \`\`\`
184550
+ Read: app/(content)/events/[slug]/page.tsx
184551
+ Glob: src/**/[id]/**/*.ts
184552
+ \`\`\`
184553
+
184554
+ **The Read and Glob tools handle special characters automatically.**
184555
+ Never add backslashes before \`[\`, \`]\`, \`(\`, or \`)\` in file paths.
184556
+
184446
184557
  ### Step 5: Do the Work (TDD MANDATORY)
184447
184558
 
184448
184559
  **Follow RED → GREEN → REFACTOR. No exceptions.**
@@ -185915,7 +186026,8 @@ var swarmTools = {
185915
186026
  ...promptTools,
185916
186027
  ...orchestrateTools,
185917
186028
  ...researchTools,
185918
- ...adversarialReviewTools
186029
+ ...adversarialReviewTools,
186030
+ ...verificationTools
185919
186031
  };
185920
186032
 
185921
186033
  // src/repo-crawl.ts
@@ -187010,23 +187122,23 @@ init_memory2();
187010
187122
  import * as os2 from "node:os";
187011
187123
  import * as path6 from "node:path";
187012
187124
  import { join as join30 } from "node:path";
187013
- var cachedAdapter2 = null;
187125
+ var cachedAdapter = null;
187014
187126
  var cachedIndexer = null;
187015
- var cachedProjectPath2 = null;
187127
+ var cachedProjectPath = null;
187016
187128
  async function getMemoryAdapter2(projectPath) {
187017
187129
  const path4 = projectPath || process.cwd();
187018
- if (cachedAdapter2 && cachedProjectPath2 === path4) {
187019
- return cachedAdapter2;
187130
+ if (cachedAdapter && cachedProjectPath === path4) {
187131
+ return cachedAdapter;
187020
187132
  }
187021
187133
  const swarmMail = await getSwarmMailLibSQL(path4);
187022
187134
  const dbAdapter = await swarmMail.getDatabase();
187023
- cachedAdapter2 = await createMemoryAdapter2(dbAdapter);
187024
- cachedProjectPath2 = path4;
187025
- return cachedAdapter2;
187135
+ cachedAdapter = await createMemoryAdapter2(dbAdapter);
187136
+ cachedProjectPath = path4;
187137
+ return cachedAdapter;
187026
187138
  }
187027
187139
  async function getSessionIndexer(projectPath) {
187028
187140
  const path4 = projectPath || process.cwd();
187029
- if (cachedIndexer && cachedProjectPath2 === path4) {
187141
+ if (cachedIndexer && cachedProjectPath === path4) {
187030
187142
  return cachedIndexer;
187031
187143
  }
187032
187144
  const swarmMail = await getSwarmMailLibSQL(path4);
@@ -187037,20 +187149,13 @@ async function getSessionIndexer(projectPath) {
187037
187149
  ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
187038
187150
  });
187039
187151
  cachedIndexer = new SessionIndexer(db, ollamaLayer);
187040
- cachedProjectPath2 = path4;
187152
+ cachedProjectPath = path4;
187041
187153
  return cachedIndexer;
187042
187154
  }
187043
187155
  var getHivemindAdapter = getMemoryAdapter2;
187044
187156
  async function emitEvent(eventType, data) {
187045
- try {
187046
- const projectPath = cachedProjectPath2 || process.cwd();
187047
- const swarmMail = await getSwarmMailLibSQL(projectPath);
187048
- const event = createEvent(eventType, {
187049
- project_key: projectPath,
187050
- ...data
187051
- });
187052
- await swarmMail.appendEvent(event);
187053
- } catch {}
187157
+ const projectPath = cachedProjectPath || process.cwd();
187158
+ await safeEmitEvent(eventType, data, "hivemind", projectPath);
187054
187159
  }
187055
187160
  var AGENT_DIRECTORIES = [
187056
187161
  path6.join(os2.homedir(), ".config", "swarm-tools", "sessions"),
@@ -187093,6 +187198,15 @@ var hivemind_find = tool({
187093
187198
  fts: tool.schema.boolean().optional().describe("Use full-text search instead of vector search (default: false)")
187094
187199
  },
187095
187200
  async execute(args3, ctx) {
187201
+ if (!args3.query || typeof args3.query !== "string" || args3.query.trim() === "") {
187202
+ return JSON.stringify({
187203
+ success: false,
187204
+ error: {
187205
+ code: "VALIDATION_ERROR",
187206
+ message: "query parameter is required and must be a non-empty string"
187207
+ }
187208
+ });
187209
+ }
187096
187210
  const startTime = Date.now();
187097
187211
  const adapter5 = await getMemoryAdapter2();
187098
187212
  const result = await adapter5.find(args3);
@@ -187213,7 +187327,7 @@ var hivemind_sync = tool({
187213
187327
  args: {},
187214
187328
  async execute(args3, ctx) {
187215
187329
  try {
187216
- const projectPath = cachedProjectPath2 || process.cwd();
187330
+ const projectPath = cachedProjectPath || process.cwd();
187217
187331
  const swarmMail = await getSwarmMailLibSQL(projectPath);
187218
187332
  const dbAdapter = await swarmMail.getDatabase();
187219
187333
  const hiveDir = join30(projectPath, ".hive");
@@ -189429,13 +189543,17 @@ var AGENT_DIRECTORIES2 = [
189429
189543
  path8.join(os3.homedir(), ".local", "share", "Claude"),
189430
189544
  path8.join(os3.homedir(), ".aider")
189431
189545
  ];
189546
+ var sessionIndexerCache = new AdapterCache;
189432
189547
  async function getSessionIndexer2() {
189433
- const db = await getDb();
189434
- const ollamaLayer = makeOllamaLive({
189435
- ollamaHost: process.env.OLLAMA_HOST || "http://localhost:11434",
189436
- ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
189548
+ const globalKey = "global-session-indexer";
189549
+ return sessionIndexerCache.get(globalKey, async () => {
189550
+ const db = await getDb();
189551
+ const ollamaLayer = makeOllamaLive({
189552
+ ollamaHost: process.env.OLLAMA_HOST || "http://localhost:11434",
189553
+ ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
189554
+ });
189555
+ return new SessionIndexer(db, ollamaLayer);
189437
189556
  });
189438
- return new SessionIndexer(db, ollamaLayer);
189439
189557
  }
189440
189558
  async function emitEvent2(eventType, data) {
189441
189559
  try {