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.
- package/claude-plugin/.claude-plugin/plugin.json +1 -1
- package/claude-plugin/commands/swarm.md +125 -2
- package/claude-plugin/dist/index.js +380 -262
- package/claude-plugin/dist/utils/adapter-cache.d.ts +36 -0
- package/claude-plugin/dist/utils/adapter-cache.d.ts.map +1 -0
- package/claude-plugin/dist/utils/event-utils.d.ts +31 -0
- package/claude-plugin/dist/utils/event-utils.d.ts.map +1 -0
- package/dist/bin/swarm.js +783 -596
- package/dist/cass-tools.d.ts.map +1 -1
- package/dist/hive.d.ts.map +1 -1
- package/dist/hive.js +75 -97
- package/dist/hivemind-tools.d.ts.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +396 -295
- package/dist/marketplace/index.js +380 -262
- package/dist/memory-tools.d.ts.map +1 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/plugin.js +395 -293
- package/dist/swarm-mail.d.ts +2 -2
- package/dist/swarm-mail.d.ts.map +1 -1
- package/dist/swarm-orchestrate.d.ts.map +1 -1
- package/dist/swarm-prompts.d.ts +1 -1
- package/dist/swarm-prompts.d.ts.map +1 -1
- package/dist/swarm-prompts.js +347 -259
- package/dist/swarm-verify.d.ts +100 -0
- package/dist/swarm-verify.d.ts.map +1 -0
- package/dist/swarm.d.ts +13 -1
- package/dist/swarm.d.ts.map +1 -1
- package/dist/utils/adapter-cache.d.ts +36 -0
- package/dist/utils/adapter-cache.d.ts.map +1 -0
- package/dist/utils/event-utils.d.ts +31 -0
- package/dist/utils/event-utils.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27180,7 +27180,7 @@ import {
|
|
|
27180
27180
|
sep
|
|
27181
27181
|
} from "path";
|
|
27182
27182
|
import { fileURLToPath } from "url";
|
|
27183
|
-
import { getSwarmMailLibSQL as getSwarmMailLibSQL3, createEvent as
|
|
27183
|
+
import { getSwarmMailLibSQL as getSwarmMailLibSQL3, createEvent as createEvent3 } from "swarm-mail";
|
|
27184
27184
|
function resolveGuidanceModel(model) {
|
|
27185
27185
|
if (!model)
|
|
27186
27186
|
return "unknown";
|
|
@@ -27223,7 +27223,7 @@ async function emitSkillLoadedEvent(data) {
|
|
|
27223
27223
|
try {
|
|
27224
27224
|
const projectPath = skillsProjectDirectory;
|
|
27225
27225
|
const swarmMail = await getSwarmMailLibSQL3(projectPath);
|
|
27226
|
-
const event =
|
|
27226
|
+
const event = createEvent3("skill_loaded", {
|
|
27227
27227
|
project_key: projectPath,
|
|
27228
27228
|
skill_name: data.skill_name,
|
|
27229
27229
|
skill_source: data.skill_source,
|
|
@@ -27237,7 +27237,7 @@ async function emitSkillCreatedEvent(data) {
|
|
|
27237
27237
|
try {
|
|
27238
27238
|
const projectPath = skillsProjectDirectory;
|
|
27239
27239
|
const swarmMail = await getSwarmMailLibSQL3(projectPath);
|
|
27240
|
-
const event =
|
|
27240
|
+
const event = createEvent3("skill_created", {
|
|
27241
27241
|
project_key: projectPath,
|
|
27242
27242
|
skill_name: data.skill_name,
|
|
27243
27243
|
skill_scope: data.skill_scope,
|
|
@@ -29078,6 +29078,27 @@ var init_storage = __esm(() => {
|
|
|
29078
29078
|
};
|
|
29079
29079
|
});
|
|
29080
29080
|
|
|
29081
|
+
// src/utils/adapter-cache.ts
|
|
29082
|
+
class AdapterCache {
|
|
29083
|
+
cached = null;
|
|
29084
|
+
cachedPath = null;
|
|
29085
|
+
async get(projectPath, factory) {
|
|
29086
|
+
if (this.cached && this.cachedPath === projectPath) {
|
|
29087
|
+
return this.cached;
|
|
29088
|
+
}
|
|
29089
|
+
this.cached = await factory(projectPath);
|
|
29090
|
+
this.cachedPath = projectPath;
|
|
29091
|
+
return this.cached;
|
|
29092
|
+
}
|
|
29093
|
+
clear() {
|
|
29094
|
+
this.cached = null;
|
|
29095
|
+
this.cachedPath = null;
|
|
29096
|
+
}
|
|
29097
|
+
getCachedPath() {
|
|
29098
|
+
return this.cachedPath;
|
|
29099
|
+
}
|
|
29100
|
+
}
|
|
29101
|
+
|
|
29081
29102
|
// ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Function.js
|
|
29082
29103
|
function pipe2(a, ab, bc, cd, de, ef, fg, gh, hi) {
|
|
29083
29104
|
switch (arguments.length) {
|
|
@@ -46404,6 +46425,9 @@ Linked to ${result.links.length} related memor${result.links.length === 1 ? "y"
|
|
|
46404
46425
|
};
|
|
46405
46426
|
},
|
|
46406
46427
|
async find(args2) {
|
|
46428
|
+
if (!args2.query || typeof args2.query !== "string") {
|
|
46429
|
+
throw new Error("query is required for find operation");
|
|
46430
|
+
}
|
|
46407
46431
|
const limit = args2.limit ?? 10;
|
|
46408
46432
|
let results;
|
|
46409
46433
|
let usedFallback = false;
|
|
@@ -46522,26 +46546,23 @@ var init_memory = __esm(() => {
|
|
|
46522
46546
|
});
|
|
46523
46547
|
|
|
46524
46548
|
// src/memory-tools.ts
|
|
46525
|
-
import { getSwarmMailLibSQL as getSwarmMailLibSQL5, createEvent as
|
|
46549
|
+
import { getSwarmMailLibSQL as getSwarmMailLibSQL5, createEvent as createEvent5, appendEvent as appendEvent4 } from "swarm-mail";
|
|
46526
46550
|
async function getMemoryAdapter(projectPath) {
|
|
46527
46551
|
const path3 = projectPath || process.cwd();
|
|
46528
|
-
|
|
46529
|
-
|
|
46530
|
-
|
|
46531
|
-
|
|
46532
|
-
|
|
46533
|
-
cachedAdapter = await createMemoryAdapter(dbAdapter);
|
|
46534
|
-
cachedProjectPath = path3;
|
|
46535
|
-
return cachedAdapter;
|
|
46552
|
+
return memoryAdapterCache.get(path3, async (projectPath2) => {
|
|
46553
|
+
const swarmMail = await getSwarmMailLibSQL5(projectPath2);
|
|
46554
|
+
const dbAdapter = await swarmMail.getDatabase();
|
|
46555
|
+
return await createMemoryAdapter(dbAdapter);
|
|
46556
|
+
});
|
|
46536
46557
|
}
|
|
46537
46558
|
function resetMemoryCache() {
|
|
46538
|
-
|
|
46539
|
-
cachedProjectPath = null;
|
|
46559
|
+
memoryAdapterCache.clear();
|
|
46540
46560
|
}
|
|
46541
|
-
var
|
|
46561
|
+
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;
|
|
46542
46562
|
var init_memory_tools = __esm(() => {
|
|
46543
46563
|
init_dist();
|
|
46544
46564
|
init_memory();
|
|
46565
|
+
memoryAdapterCache = new AdapterCache;
|
|
46545
46566
|
semantic_memory_store = tool({
|
|
46546
46567
|
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.",
|
|
46547
46568
|
args: {
|
|
@@ -46558,9 +46579,9 @@ var init_memory_tools = __esm(() => {
|
|
|
46558
46579
|
const adapter = await getMemoryAdapter();
|
|
46559
46580
|
const result = await adapter.store(args2);
|
|
46560
46581
|
try {
|
|
46561
|
-
const projectKey =
|
|
46582
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46562
46583
|
const tags = args2.tags ? args2.tags.split(",").map((t) => t.trim()) : [];
|
|
46563
|
-
const event =
|
|
46584
|
+
const event = createEvent5("memory_stored", {
|
|
46564
46585
|
project_key: projectKey,
|
|
46565
46586
|
memory_id: result.id,
|
|
46566
46587
|
content_preview: args2.information.slice(0, 100),
|
|
@@ -46568,7 +46589,7 @@ var init_memory_tools = __esm(() => {
|
|
|
46568
46589
|
auto_tagged: args2.autoTag,
|
|
46569
46590
|
collection: args2.collection
|
|
46570
46591
|
});
|
|
46571
|
-
await
|
|
46592
|
+
await appendEvent4(event, projectKey);
|
|
46572
46593
|
} catch (error45) {
|
|
46573
46594
|
console.warn("[semantic_memory_store] Failed to emit memory_stored event:", error45);
|
|
46574
46595
|
}
|
|
@@ -46590,9 +46611,9 @@ var init_memory_tools = __esm(() => {
|
|
|
46590
46611
|
const result = await adapter.find(args2);
|
|
46591
46612
|
const duration3 = Date.now() - startTime;
|
|
46592
46613
|
try {
|
|
46593
|
-
const projectKey =
|
|
46614
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46594
46615
|
const topScore = result.results.length > 0 ? result.results[0].score : undefined;
|
|
46595
|
-
const event =
|
|
46616
|
+
const event = createEvent5("memory_found", {
|
|
46596
46617
|
project_key: projectKey,
|
|
46597
46618
|
query: args2.query,
|
|
46598
46619
|
result_count: result.results.length,
|
|
@@ -46600,7 +46621,7 @@ var init_memory_tools = __esm(() => {
|
|
|
46600
46621
|
search_duration_ms: duration3,
|
|
46601
46622
|
used_fts: args2.fts
|
|
46602
46623
|
});
|
|
46603
|
-
await
|
|
46624
|
+
await appendEvent4(event, projectKey);
|
|
46604
46625
|
} catch (error45) {
|
|
46605
46626
|
console.warn("[semantic_memory_find] Failed to emit memory_found event:", error45);
|
|
46606
46627
|
}
|
|
@@ -46628,12 +46649,12 @@ var init_memory_tools = __esm(() => {
|
|
|
46628
46649
|
const result = await adapter.remove(args2);
|
|
46629
46650
|
if (result.success) {
|
|
46630
46651
|
try {
|
|
46631
|
-
const projectKey =
|
|
46632
|
-
const event =
|
|
46652
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46653
|
+
const event = createEvent5("memory_deleted", {
|
|
46633
46654
|
project_key: projectKey,
|
|
46634
46655
|
memory_id: args2.id
|
|
46635
46656
|
});
|
|
46636
|
-
await
|
|
46657
|
+
await appendEvent4(event, projectKey);
|
|
46637
46658
|
} catch (error45) {
|
|
46638
46659
|
console.warn("[semantic_memory_remove] Failed to emit memory_deleted event:", error45);
|
|
46639
46660
|
}
|
|
@@ -46651,13 +46672,13 @@ var init_memory_tools = __esm(() => {
|
|
|
46651
46672
|
const result = await adapter.validate(args2);
|
|
46652
46673
|
if (result.success) {
|
|
46653
46674
|
try {
|
|
46654
|
-
const projectKey =
|
|
46655
|
-
const event =
|
|
46675
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46676
|
+
const event = createEvent5("memory_validated", {
|
|
46656
46677
|
project_key: projectKey,
|
|
46657
46678
|
memory_id: args2.id,
|
|
46658
46679
|
decay_reset: true
|
|
46659
46680
|
});
|
|
46660
|
-
await
|
|
46681
|
+
await appendEvent4(event, projectKey);
|
|
46661
46682
|
} catch (error45) {
|
|
46662
46683
|
console.warn("[semantic_memory_validate] Failed to emit memory_validated event:", error45);
|
|
46663
46684
|
}
|
|
@@ -46710,14 +46731,14 @@ var init_memory_tools = __esm(() => {
|
|
|
46710
46731
|
const adapter = await getMemoryAdapter();
|
|
46711
46732
|
const result = await adapter.upsert(args2);
|
|
46712
46733
|
try {
|
|
46713
|
-
const projectKey =
|
|
46714
|
-
const event =
|
|
46734
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46735
|
+
const event = createEvent5("memory_updated", {
|
|
46715
46736
|
project_key: projectKey,
|
|
46716
46737
|
memory_id: result.memoryId || "unknown",
|
|
46717
46738
|
operation: result.operation,
|
|
46718
46739
|
reason: result.reason
|
|
46719
46740
|
});
|
|
46720
|
-
await
|
|
46741
|
+
await appendEvent4(event, projectKey);
|
|
46721
46742
|
} catch (error45) {
|
|
46722
46743
|
console.warn("[semantic_memory_upsert] Failed to emit memory_updated event:", error45);
|
|
46723
46744
|
}
|
|
@@ -59040,7 +59061,24 @@ var createBeadEvent = createCellEvent;
|
|
|
59040
59061
|
var isBeadEventType = isCellEventType;
|
|
59041
59062
|
var getBeadIdFromEvent = getCellIdFromEvent;
|
|
59042
59063
|
// src/hive.ts
|
|
59064
|
+
import { createEvent as createEvent2, appendEvent as appendEvent2 } from "swarm-mail";
|
|
59065
|
+
|
|
59066
|
+
// src/utils/event-utils.ts
|
|
59043
59067
|
import { createEvent, appendEvent } from "swarm-mail";
|
|
59068
|
+
async function safeEmitEvent(eventType, data, toolName, projectPath) {
|
|
59069
|
+
try {
|
|
59070
|
+
const effectiveProjectPath = projectPath || process.cwd();
|
|
59071
|
+
const event = createEvent(eventType, {
|
|
59072
|
+
project_key: effectiveProjectPath,
|
|
59073
|
+
...data
|
|
59074
|
+
});
|
|
59075
|
+
await appendEvent(event, effectiveProjectPath);
|
|
59076
|
+
} catch (error45) {
|
|
59077
|
+
console.warn(`[${toolName}] Failed to emit ${eventType} event:`, error45);
|
|
59078
|
+
}
|
|
59079
|
+
}
|
|
59080
|
+
|
|
59081
|
+
// src/hive.ts
|
|
59044
59082
|
var hiveWorkingDirectory = null;
|
|
59045
59083
|
function setHiveWorkingDirectory(directory) {
|
|
59046
59084
|
hiveWorkingDirectory = directory;
|
|
@@ -59349,20 +59387,14 @@ var hive_create = tool({
|
|
|
59349
59387
|
parent_id: validated.parent_id
|
|
59350
59388
|
});
|
|
59351
59389
|
await adapter.markDirty(projectKey, cell.id);
|
|
59352
|
-
|
|
59353
|
-
|
|
59354
|
-
|
|
59355
|
-
|
|
59356
|
-
|
|
59357
|
-
|
|
59358
|
-
|
|
59359
|
-
|
|
59360
|
-
parent_id: validated.parent_id
|
|
59361
|
-
});
|
|
59362
|
-
await appendEvent(event, projectKey);
|
|
59363
|
-
} catch (error45) {
|
|
59364
|
-
console.warn("[hive_create] Failed to emit cell_created event:", error45);
|
|
59365
|
-
}
|
|
59390
|
+
await safeEmitEvent("cell_created", {
|
|
59391
|
+
cell_id: cell.id,
|
|
59392
|
+
title: validated.title,
|
|
59393
|
+
description: validated.description,
|
|
59394
|
+
issue_type: validated.type || "task",
|
|
59395
|
+
priority: validated.priority ?? 2,
|
|
59396
|
+
parent_id: validated.parent_id
|
|
59397
|
+
}, "hive_create", projectKey);
|
|
59366
59398
|
const formatted = formatCellForOutput(cell);
|
|
59367
59399
|
return JSON.stringify(formatted, null, 2);
|
|
59368
59400
|
} catch (error45) {
|
|
@@ -59444,53 +59476,35 @@ var hive_create_epic = tool({
|
|
|
59444
59476
|
subtasks: created.slice(1).map((c) => formatCellForOutput(c))
|
|
59445
59477
|
};
|
|
59446
59478
|
const effectiveProjectKey = args.project_key || projectKey;
|
|
59447
|
-
|
|
59448
|
-
|
|
59449
|
-
|
|
59450
|
-
|
|
59451
|
-
|
|
59452
|
-
|
|
59453
|
-
|
|
59454
|
-
|
|
59455
|
-
|
|
59456
|
-
|
|
59457
|
-
|
|
59458
|
-
|
|
59459
|
-
|
|
59460
|
-
|
|
59461
|
-
|
|
59462
|
-
|
|
59463
|
-
|
|
59464
|
-
|
|
59465
|
-
|
|
59466
|
-
|
|
59467
|
-
|
|
59468
|
-
|
|
59469
|
-
|
|
59470
|
-
|
|
59471
|
-
|
|
59472
|
-
|
|
59473
|
-
|
|
59474
|
-
|
|
59475
|
-
|
|
59476
|
-
} catch (error45) {
|
|
59477
|
-
console.warn("[hive_create_epic] Failed to emit DecompositionGeneratedEvent:", error45);
|
|
59478
|
-
}
|
|
59479
|
-
try {
|
|
59480
|
-
const totalFiles = validated.subtasks.reduce((count, st) => count + (st.files?.length || 0), 0);
|
|
59481
|
-
const swarmStartedEvent = createEvent("swarm_started", {
|
|
59482
|
-
project_key: effectiveProjectKey,
|
|
59483
|
-
epic_id: epic.id,
|
|
59484
|
-
epic_title: validated.epic_title,
|
|
59485
|
-
strategy: args.strategy || "feature-based",
|
|
59486
|
-
subtask_count: validated.subtasks.length,
|
|
59487
|
-
total_files: totalFiles,
|
|
59488
|
-
coordinator_agent: "coordinator"
|
|
59489
|
-
});
|
|
59490
|
-
await appendEvent(swarmStartedEvent, effectiveProjectKey);
|
|
59491
|
-
} catch (error45) {
|
|
59492
|
-
console.warn("[hive_create_epic] Failed to emit SwarmStartedEvent:", error45);
|
|
59493
|
-
}
|
|
59479
|
+
await safeEmitEvent("epic_created", {
|
|
59480
|
+
epic_id: epic.id,
|
|
59481
|
+
title: validated.epic_title,
|
|
59482
|
+
description: validated.epic_description,
|
|
59483
|
+
subtask_count: validated.subtasks.length,
|
|
59484
|
+
subtask_ids: created.slice(1).map((c) => c.id)
|
|
59485
|
+
}, "hive_create_epic", effectiveProjectKey);
|
|
59486
|
+
await safeEmitEvent("decomposition_generated", {
|
|
59487
|
+
epic_id: epic.id,
|
|
59488
|
+
task: args.task || validated.epic_title,
|
|
59489
|
+
context: validated.epic_description,
|
|
59490
|
+
strategy: args.strategy || "feature-based",
|
|
59491
|
+
epic_title: validated.epic_title,
|
|
59492
|
+
subtasks: validated.subtasks.map((st) => ({
|
|
59493
|
+
title: st.title,
|
|
59494
|
+
files: st.files || [],
|
|
59495
|
+
priority: st.priority
|
|
59496
|
+
})),
|
|
59497
|
+
recovery_context: args.recovery_context
|
|
59498
|
+
}, "hive_create_epic", effectiveProjectKey);
|
|
59499
|
+
const totalFiles = validated.subtasks.reduce((count, st) => count + (st.files?.length || 0), 0);
|
|
59500
|
+
await safeEmitEvent("swarm_started", {
|
|
59501
|
+
epic_id: epic.id,
|
|
59502
|
+
epic_title: validated.epic_title,
|
|
59503
|
+
strategy: args.strategy || "feature-based",
|
|
59504
|
+
subtask_count: validated.subtasks.length,
|
|
59505
|
+
total_files: totalFiles,
|
|
59506
|
+
coordinator_agent: "coordinator"
|
|
59507
|
+
}, "hive_create_epic", effectiveProjectKey);
|
|
59494
59508
|
try {
|
|
59495
59509
|
const { captureCoordinatorEvent: captureCoordinatorEvent2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
|
|
59496
59510
|
const filesPerSubtask = {};
|
|
@@ -59621,23 +59635,17 @@ var hive_update = tool({
|
|
|
59621
59635
|
cell = existingCell;
|
|
59622
59636
|
}
|
|
59623
59637
|
await adapter.markDirty(projectKey, cellId);
|
|
59624
|
-
|
|
59625
|
-
|
|
59626
|
-
|
|
59627
|
-
|
|
59628
|
-
|
|
59629
|
-
|
|
59630
|
-
|
|
59631
|
-
|
|
59632
|
-
|
|
59633
|
-
|
|
59634
|
-
|
|
59635
|
-
fields_changed: fieldsChanged
|
|
59636
|
-
});
|
|
59637
|
-
await appendEvent(event, projectKey);
|
|
59638
|
-
} catch (error45) {
|
|
59639
|
-
console.warn("[hive_update] Failed to emit cell_updated event:", error45);
|
|
59640
|
-
}
|
|
59638
|
+
const fieldsChanged = [];
|
|
59639
|
+
if (validated.status)
|
|
59640
|
+
fieldsChanged.push("status");
|
|
59641
|
+
if (validated.description !== undefined)
|
|
59642
|
+
fieldsChanged.push("description");
|
|
59643
|
+
if (validated.priority !== undefined)
|
|
59644
|
+
fieldsChanged.push("priority");
|
|
59645
|
+
await safeEmitEvent("cell_updated", {
|
|
59646
|
+
cell_id: cellId,
|
|
59647
|
+
fields_changed: fieldsChanged
|
|
59648
|
+
}, "hive_update", projectKey);
|
|
59641
59649
|
const formatted = formatCellForOutput(cell);
|
|
59642
59650
|
return JSON.stringify(formatted, null, 2);
|
|
59643
59651
|
} catch (error45) {
|
|
@@ -59670,7 +59678,6 @@ var hive_close = tool({
|
|
|
59670
59678
|
await adapter.markDirty(projectKey, cellId);
|
|
59671
59679
|
if (isEpic && cellBeforeClose) {
|
|
59672
59680
|
try {
|
|
59673
|
-
const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
|
|
59674
59681
|
const subtasks = await adapter.queryCells(projectKey, { parent_id: cellId });
|
|
59675
59682
|
const completedSubtasks = subtasks.filter((st) => st.status === "closed");
|
|
59676
59683
|
const failedSubtasks = subtasks.filter((st) => st.status === "blocked");
|
|
@@ -59708,8 +59715,7 @@ var hive_close = tool({
|
|
|
59708
59715
|
} catch (error45) {
|
|
59709
59716
|
console.warn("[hive_close] Failed to calculate duration:", error45);
|
|
59710
59717
|
}
|
|
59711
|
-
|
|
59712
|
-
project_key: projectKey,
|
|
59718
|
+
await safeEmitEvent("swarm_completed", {
|
|
59713
59719
|
epic_id: cellId,
|
|
59714
59720
|
epic_title: cellBeforeClose.title,
|
|
59715
59721
|
success: failedSubtasks.length === 0,
|
|
@@ -59717,8 +59723,7 @@ var hive_close = tool({
|
|
|
59717
59723
|
subtasks_completed: completedSubtasks.length,
|
|
59718
59724
|
subtasks_failed: failedSubtasks.length,
|
|
59719
59725
|
total_files_touched: totalFilesTouched
|
|
59720
|
-
});
|
|
59721
|
-
await appendEvent2(swarmCompletedEvent, projectKey);
|
|
59726
|
+
}, "hive_close", projectKey);
|
|
59722
59727
|
try {
|
|
59723
59728
|
const { runPostSwarmValidation: runPostSwarmValidation2 } = await Promise.resolve().then(() => (init_swarm_validation(), exports_swarm_validation));
|
|
59724
59729
|
const { readEvents } = await import("swarm-mail");
|
|
@@ -59754,16 +59759,10 @@ var hive_close = tool({
|
|
|
59754
59759
|
console.warn("[hive_close] Failed to emit SwarmCompletedEvent:", error45);
|
|
59755
59760
|
}
|
|
59756
59761
|
}
|
|
59757
|
-
|
|
59758
|
-
|
|
59759
|
-
|
|
59760
|
-
|
|
59761
|
-
reason: validated.reason
|
|
59762
|
-
});
|
|
59763
|
-
await appendEvent(event, projectKey);
|
|
59764
|
-
} catch (error45) {
|
|
59765
|
-
console.warn("[hive_close] Failed to emit cell_closed event:", error45);
|
|
59766
|
-
}
|
|
59762
|
+
await safeEmitEvent("cell_closed", {
|
|
59763
|
+
cell_id: cellId,
|
|
59764
|
+
reason: validated.reason
|
|
59765
|
+
}, "hive_close", projectKey);
|
|
59767
59766
|
return `Closed ${cell.id}: ${validated.reason}`;
|
|
59768
59767
|
} catch (error45) {
|
|
59769
59768
|
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
@@ -59790,13 +59789,13 @@ var hive_start = tool({
|
|
|
59790
59789
|
const cell = await adapter.changeCellStatus(projectKey, cellId, "in_progress");
|
|
59791
59790
|
await adapter.markDirty(projectKey, cellId);
|
|
59792
59791
|
try {
|
|
59793
|
-
const event =
|
|
59792
|
+
const event = createEvent2("cell_status_changed", {
|
|
59794
59793
|
project_key: projectKey,
|
|
59795
59794
|
cell_id: cellId,
|
|
59796
59795
|
old_status: "open",
|
|
59797
59796
|
new_status: "in_progress"
|
|
59798
59797
|
});
|
|
59799
|
-
await
|
|
59798
|
+
await appendEvent2(event, projectKey);
|
|
59800
59799
|
} catch (error45) {
|
|
59801
59800
|
console.warn("[hive_start] Failed to emit cell_status_changed event:", error45);
|
|
59802
59801
|
}
|
|
@@ -59997,12 +59996,12 @@ var hive_sync = tool({
|
|
|
59997
59996
|
pushSuccess = true;
|
|
59998
59997
|
}
|
|
59999
59998
|
try {
|
|
60000
|
-
const event =
|
|
59999
|
+
const event = createEvent2("hive_synced", {
|
|
60001
60000
|
project_key: projectKey,
|
|
60002
60001
|
cells_synced: flushResult.cellsExported,
|
|
60003
60002
|
push_success: pushSuccess
|
|
60004
60003
|
});
|
|
60005
|
-
await
|
|
60004
|
+
await appendEvent2(event, projectKey);
|
|
60006
60005
|
} catch (error45) {
|
|
60007
60006
|
console.warn("[hive_sync] Failed to emit hive_synced event:", error45);
|
|
60008
60007
|
}
|
|
@@ -62155,10 +62154,13 @@ var swarmmail_read_message = tool({
|
|
|
62155
62154
|
}
|
|
62156
62155
|
}
|
|
62157
62156
|
});
|
|
62157
|
+
function normalizePath(path2) {
|
|
62158
|
+
return path2.replace(/\\([[\]()])/g, "$1");
|
|
62159
|
+
}
|
|
62158
62160
|
var swarmmail_reserve = tool({
|
|
62159
|
-
description: "Reserve file paths for exclusive editing. Prevents conflicts with other agents.",
|
|
62161
|
+
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.",
|
|
62160
62162
|
args: {
|
|
62161
|
-
paths: tool.schema.array(tool.schema.string()).describe("File paths or glob patterns to reserve"),
|
|
62163
|
+
paths: tool.schema.array(tool.schema.string()).transform((paths) => paths.map(normalizePath)).describe("File paths or glob patterns to reserve. Do NOT escape [ ] ( ) characters."),
|
|
62162
62164
|
reason: tool.schema.string().optional().describe("Reason for reservation (e.g., bead ID)"),
|
|
62163
62165
|
exclusive: tool.schema.boolean().optional().describe("Whether reservation is exclusive (default: true)"),
|
|
62164
62166
|
ttl_seconds: tool.schema.number().optional().describe("Time-to-live in seconds (default: 3600)")
|
|
@@ -62170,10 +62172,11 @@ var swarmmail_reserve = tool({
|
|
|
62170
62172
|
return JSON.stringify({ error: "Session not initialized. Call swarmmail_init first." }, null, 2);
|
|
62171
62173
|
}
|
|
62172
62174
|
try {
|
|
62175
|
+
const normalizedPaths = args.paths.map(normalizePath);
|
|
62173
62176
|
const result = await reserveSwarmFiles({
|
|
62174
62177
|
projectPath: state.projectKey,
|
|
62175
62178
|
agentName: state.agentName,
|
|
62176
|
-
paths:
|
|
62179
|
+
paths: normalizedPaths,
|
|
62177
62180
|
reason: args.reason,
|
|
62178
62181
|
exclusive: args.exclusive ?? true,
|
|
62179
62182
|
ttlSeconds: args.ttl_seconds
|
|
@@ -62201,9 +62204,9 @@ var swarmmail_reserve = tool({
|
|
|
62201
62204
|
}
|
|
62202
62205
|
});
|
|
62203
62206
|
var swarmmail_release = tool({
|
|
62204
|
-
description: "Release file reservations. Call when done editing files.",
|
|
62207
|
+
description: "Release file reservations. Call when done editing files. " + "Do NOT escape brackets or parentheses in paths.",
|
|
62205
62208
|
args: {
|
|
62206
|
-
paths: tool.schema.array(tool.schema.string()).optional().describe("Specific paths to release (releases all if omitted)"),
|
|
62209
|
+
paths: tool.schema.array(tool.schema.string()).optional().describe("Specific paths to release (releases all if omitted). Do NOT escape [ ] ( ) characters."),
|
|
62207
62210
|
reservation_ids: tool.schema.array(tool.schema.number()).optional().describe("Specific reservation IDs to release")
|
|
62208
62211
|
},
|
|
62209
62212
|
async execute(args, ctx) {
|
|
@@ -62214,10 +62217,11 @@ var swarmmail_release = tool({
|
|
|
62214
62217
|
}
|
|
62215
62218
|
try {
|
|
62216
62219
|
const currentReservations = await getActiveReservations(state.projectKey, state.projectKey, state.agentName);
|
|
62220
|
+
const normalizedPaths = args.paths?.map(normalizePath);
|
|
62217
62221
|
const result = await releaseSwarmFiles({
|
|
62218
62222
|
projectPath: state.projectKey,
|
|
62219
62223
|
agentName: state.agentName,
|
|
62220
|
-
paths:
|
|
62224
|
+
paths: normalizedPaths,
|
|
62221
62225
|
reservationIds: args.reservation_ids
|
|
62222
62226
|
});
|
|
62223
62227
|
if (!args.paths && !args.reservation_ids) {
|
|
@@ -65110,8 +65114,8 @@ import {
|
|
|
65110
65114
|
releaseSwarmFiles as releaseSwarmFiles2,
|
|
65111
65115
|
sendSwarmMessage as sendSwarmMessage3,
|
|
65112
65116
|
getAgent,
|
|
65113
|
-
createEvent as
|
|
65114
|
-
appendEvent as
|
|
65117
|
+
createEvent as createEvent4,
|
|
65118
|
+
appendEvent as appendEvent3,
|
|
65115
65119
|
getSwarmMailLibSQL as getSwarmMailLibSQL4
|
|
65116
65120
|
} from "swarm-mail";
|
|
65117
65121
|
init_skills();
|
|
@@ -65616,15 +65620,15 @@ var swarm_review = tool({
|
|
|
65616
65620
|
downstream_tasks: downstreamTasks.length > 0 ? downstreamTasks : undefined
|
|
65617
65621
|
});
|
|
65618
65622
|
try {
|
|
65619
|
-
const { createEvent:
|
|
65623
|
+
const { createEvent: createEvent4, appendEvent: appendEvent3 } = await import("swarm-mail");
|
|
65620
65624
|
const attempt = getReviewStatus(args.task_id).attempt_count || 1;
|
|
65621
|
-
const reviewStartedEvent =
|
|
65625
|
+
const reviewStartedEvent = createEvent4("review_started", {
|
|
65622
65626
|
project_key: args.project_key,
|
|
65623
65627
|
epic_id: args.epic_id,
|
|
65624
65628
|
bead_id: args.task_id,
|
|
65625
65629
|
attempt
|
|
65626
65630
|
});
|
|
65627
|
-
await
|
|
65631
|
+
await appendEvent3(reviewStartedEvent, args.project_key);
|
|
65628
65632
|
} catch (error45) {
|
|
65629
65633
|
console.warn("[swarm_review] Failed to emit ReviewStartedEvent:", error45);
|
|
65630
65634
|
}
|
|
@@ -65707,16 +65711,16 @@ var swarm_review_feedback = tool({
|
|
|
65707
65711
|
console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
|
|
65708
65712
|
}
|
|
65709
65713
|
try {
|
|
65710
|
-
const { createEvent:
|
|
65714
|
+
const { createEvent: createEvent4, appendEvent: appendEvent3 } = await import("swarm-mail");
|
|
65711
65715
|
const attempt = getReviewStatus(args.task_id).attempt_count || 1;
|
|
65712
|
-
const reviewCompletedEvent =
|
|
65716
|
+
const reviewCompletedEvent = createEvent4("review_completed", {
|
|
65713
65717
|
project_key: args.project_key,
|
|
65714
65718
|
epic_id: epicId,
|
|
65715
65719
|
bead_id: args.task_id,
|
|
65716
65720
|
status: "approved",
|
|
65717
65721
|
attempt
|
|
65718
65722
|
});
|
|
65719
|
-
await
|
|
65723
|
+
await appendEvent3(reviewCompletedEvent, args.project_key);
|
|
65720
65724
|
} catch (error45) {
|
|
65721
65725
|
console.warn("[swarm_review_feedback] Failed to emit ReviewCompletedEvent:", error45);
|
|
65722
65726
|
}
|
|
@@ -65778,16 +65782,16 @@ You may now complete the task with \`swarm_complete\`.`,
|
|
|
65778
65782
|
console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
|
|
65779
65783
|
}
|
|
65780
65784
|
try {
|
|
65781
|
-
const { createEvent:
|
|
65785
|
+
const { createEvent: createEvent4, appendEvent: appendEvent3 } = await import("swarm-mail");
|
|
65782
65786
|
const status = remaining <= 0 ? "blocked" : "needs_changes";
|
|
65783
|
-
const reviewCompletedEvent =
|
|
65787
|
+
const reviewCompletedEvent = createEvent4("review_completed", {
|
|
65784
65788
|
project_key: args.project_key,
|
|
65785
65789
|
epic_id: epicId,
|
|
65786
65790
|
bead_id: args.task_id,
|
|
65787
65791
|
status,
|
|
65788
65792
|
attempt: attemptNumber
|
|
65789
65793
|
});
|
|
65790
|
-
await
|
|
65794
|
+
await appendEvent3(reviewCompletedEvent, args.project_key);
|
|
65791
65795
|
} catch (error45) {
|
|
65792
65796
|
console.warn("[swarm_review_feedback] Failed to emit ReviewCompletedEvent:", error45);
|
|
65793
65797
|
}
|
|
@@ -65847,6 +65851,184 @@ var reviewTools = {
|
|
|
65847
65851
|
|
|
65848
65852
|
// src/swarm-orchestrate.ts
|
|
65849
65853
|
init_eval_capture();
|
|
65854
|
+
|
|
65855
|
+
// src/swarm-verify.ts
|
|
65856
|
+
init_dist();
|
|
65857
|
+
async function runTypecheckVerification() {
|
|
65858
|
+
const step = {
|
|
65859
|
+
name: "typecheck",
|
|
65860
|
+
command: "tsc --noEmit",
|
|
65861
|
+
passed: false,
|
|
65862
|
+
exitCode: -1
|
|
65863
|
+
};
|
|
65864
|
+
try {
|
|
65865
|
+
const tsconfigExists = await Bun.file("tsconfig.json").exists();
|
|
65866
|
+
if (!tsconfigExists) {
|
|
65867
|
+
step.skipped = true;
|
|
65868
|
+
step.skipReason = "No tsconfig.json found";
|
|
65869
|
+
step.passed = true;
|
|
65870
|
+
return step;
|
|
65871
|
+
}
|
|
65872
|
+
const result = await Bun.$`tsc --noEmit`.quiet().nothrow();
|
|
65873
|
+
step.exitCode = result.exitCode;
|
|
65874
|
+
step.passed = result.exitCode === 0;
|
|
65875
|
+
if (!step.passed) {
|
|
65876
|
+
step.error = result.stderr.toString().slice(0, 1000);
|
|
65877
|
+
step.output = result.stdout.toString().slice(0, 1000);
|
|
65878
|
+
}
|
|
65879
|
+
} catch (error45) {
|
|
65880
|
+
step.skipped = true;
|
|
65881
|
+
step.skipReason = `tsc not available: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
65882
|
+
step.passed = true;
|
|
65883
|
+
}
|
|
65884
|
+
return step;
|
|
65885
|
+
}
|
|
65886
|
+
async function runTestVerification(filesTouched) {
|
|
65887
|
+
const step = {
|
|
65888
|
+
name: "tests",
|
|
65889
|
+
command: "bun test <related-files>",
|
|
65890
|
+
passed: false,
|
|
65891
|
+
exitCode: -1
|
|
65892
|
+
};
|
|
65893
|
+
if (filesTouched.length === 0) {
|
|
65894
|
+
step.skipped = true;
|
|
65895
|
+
step.skipReason = "No files touched";
|
|
65896
|
+
step.passed = true;
|
|
65897
|
+
return step;
|
|
65898
|
+
}
|
|
65899
|
+
const testPatterns = [];
|
|
65900
|
+
for (const file2 of filesTouched) {
|
|
65901
|
+
if (file2.includes(".test.") || file2.includes(".spec.")) {
|
|
65902
|
+
testPatterns.push(file2);
|
|
65903
|
+
continue;
|
|
65904
|
+
}
|
|
65905
|
+
const baseName = file2.replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
65906
|
+
testPatterns.push(`${baseName}.test.ts`);
|
|
65907
|
+
testPatterns.push(`${baseName}.test.tsx`);
|
|
65908
|
+
testPatterns.push(`${baseName}.spec.ts`);
|
|
65909
|
+
}
|
|
65910
|
+
const existingTests = [];
|
|
65911
|
+
for (const pattern of testPatterns) {
|
|
65912
|
+
try {
|
|
65913
|
+
const exists = await Bun.file(pattern).exists();
|
|
65914
|
+
if (exists) {
|
|
65915
|
+
existingTests.push(pattern);
|
|
65916
|
+
}
|
|
65917
|
+
} catch {}
|
|
65918
|
+
}
|
|
65919
|
+
if (existingTests.length === 0) {
|
|
65920
|
+
step.skipped = true;
|
|
65921
|
+
step.skipReason = "No related test files found";
|
|
65922
|
+
step.passed = true;
|
|
65923
|
+
return step;
|
|
65924
|
+
}
|
|
65925
|
+
try {
|
|
65926
|
+
step.command = `bun test ${existingTests.join(" ")}`;
|
|
65927
|
+
const result = await Bun.$`bun test ${existingTests}`.quiet().nothrow();
|
|
65928
|
+
step.exitCode = result.exitCode;
|
|
65929
|
+
step.passed = result.exitCode === 0;
|
|
65930
|
+
if (!step.passed) {
|
|
65931
|
+
step.error = result.stderr.toString().slice(0, 1000);
|
|
65932
|
+
step.output = result.stdout.toString().slice(0, 1000);
|
|
65933
|
+
}
|
|
65934
|
+
} catch (error45) {
|
|
65935
|
+
step.skipped = true;
|
|
65936
|
+
step.skipReason = `Test runner failed: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
65937
|
+
step.passed = true;
|
|
65938
|
+
}
|
|
65939
|
+
return step;
|
|
65940
|
+
}
|
|
65941
|
+
async function runVerificationGate(filesTouched, _skipUbs = false) {
|
|
65942
|
+
const steps = [];
|
|
65943
|
+
const blockers = [];
|
|
65944
|
+
const typecheckStep = await runTypecheckVerification();
|
|
65945
|
+
steps.push(typecheckStep);
|
|
65946
|
+
if (!typecheckStep.passed && !typecheckStep.skipped) {
|
|
65947
|
+
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.`);
|
|
65948
|
+
}
|
|
65949
|
+
const testStep = await runTestVerification(filesTouched);
|
|
65950
|
+
steps.push(testStep);
|
|
65951
|
+
if (!testStep.passed && !testStep.skipped) {
|
|
65952
|
+
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.`);
|
|
65953
|
+
}
|
|
65954
|
+
const passedCount = steps.filter((s) => s.passed).length;
|
|
65955
|
+
const skippedCount = steps.filter((s) => s.skipped).length;
|
|
65956
|
+
const failedCount = steps.filter((s) => !s.passed && !s.skipped).length;
|
|
65957
|
+
const summary = failedCount === 0 ? `Verification passed: ${passedCount} checks passed, ${skippedCount} skipped` : `Verification FAILED: ${failedCount} checks failed, ${passedCount} passed, ${skippedCount} skipped`;
|
|
65958
|
+
return {
|
|
65959
|
+
passed: failedCount === 0,
|
|
65960
|
+
steps,
|
|
65961
|
+
summary,
|
|
65962
|
+
blockers
|
|
65963
|
+
};
|
|
65964
|
+
}
|
|
65965
|
+
var swarm_verify = tool({
|
|
65966
|
+
description: "Run verification gate (typecheck + tests) for files. Returns verification results without blocking. Used by swarm_complete to verify worker output.",
|
|
65967
|
+
args: {
|
|
65968
|
+
files_touched: tool.schema.array(tool.schema.string()).describe("Files to verify (typecheck + test discovery)"),
|
|
65969
|
+
skip_verification: tool.schema.boolean().optional().describe("Skip verification entirely (default: false)")
|
|
65970
|
+
},
|
|
65971
|
+
async execute(args) {
|
|
65972
|
+
try {
|
|
65973
|
+
if (args.skip_verification) {
|
|
65974
|
+
return JSON.stringify({
|
|
65975
|
+
success: true,
|
|
65976
|
+
data: {
|
|
65977
|
+
passed: true,
|
|
65978
|
+
skipped: true,
|
|
65979
|
+
reason: "skip_verification=true",
|
|
65980
|
+
summary: "Verification skipped by request",
|
|
65981
|
+
steps: [],
|
|
65982
|
+
blockers: []
|
|
65983
|
+
}
|
|
65984
|
+
}, null, 2);
|
|
65985
|
+
}
|
|
65986
|
+
if (!args.files_touched || args.files_touched.length === 0) {
|
|
65987
|
+
return JSON.stringify({
|
|
65988
|
+
success: true,
|
|
65989
|
+
data: {
|
|
65990
|
+
passed: true,
|
|
65991
|
+
skipped: true,
|
|
65992
|
+
reason: "no files_touched provided",
|
|
65993
|
+
summary: "No files to verify",
|
|
65994
|
+
steps: [],
|
|
65995
|
+
blockers: []
|
|
65996
|
+
}
|
|
65997
|
+
}, null, 2);
|
|
65998
|
+
}
|
|
65999
|
+
const result = await runVerificationGate(args.files_touched, false);
|
|
66000
|
+
return JSON.stringify({
|
|
66001
|
+
success: true,
|
|
66002
|
+
data: {
|
|
66003
|
+
passed: result.passed,
|
|
66004
|
+
skipped: false,
|
|
66005
|
+
summary: result.summary,
|
|
66006
|
+
steps: result.steps.map((s) => ({
|
|
66007
|
+
name: s.name,
|
|
66008
|
+
command: s.command,
|
|
66009
|
+
passed: s.passed,
|
|
66010
|
+
exitCode: s.exitCode,
|
|
66011
|
+
skipped: s.skipped,
|
|
66012
|
+
skipReason: s.skipReason,
|
|
66013
|
+
error: s.error?.slice(0, 200),
|
|
66014
|
+
output: s.output?.slice(0, 200)
|
|
66015
|
+
})),
|
|
66016
|
+
blockers: result.blockers
|
|
66017
|
+
}
|
|
66018
|
+
}, null, 2);
|
|
66019
|
+
} catch (error45) {
|
|
66020
|
+
return JSON.stringify({
|
|
66021
|
+
success: false,
|
|
66022
|
+
error: `Verification failed: ${error45 instanceof Error ? error45.message : String(error45)}`
|
|
66023
|
+
}, null, 2);
|
|
66024
|
+
}
|
|
66025
|
+
}
|
|
66026
|
+
});
|
|
66027
|
+
var verificationTools = {
|
|
66028
|
+
swarm_verify
|
|
66029
|
+
};
|
|
66030
|
+
|
|
66031
|
+
// src/swarm-orchestrate.ts
|
|
65850
66032
|
function generateWorkerHandoff(params) {
|
|
65851
66033
|
const handoff = {
|
|
65852
66034
|
contract: {
|
|
@@ -65988,114 +66170,6 @@ ${progress.blockers.map((b) => `- ${b}`).join(`
|
|
|
65988
66170
|
|
|
65989
66171
|
`);
|
|
65990
66172
|
}
|
|
65991
|
-
async function runTypecheckVerification() {
|
|
65992
|
-
const step = {
|
|
65993
|
-
name: "typecheck",
|
|
65994
|
-
command: "tsc --noEmit",
|
|
65995
|
-
passed: false,
|
|
65996
|
-
exitCode: -1
|
|
65997
|
-
};
|
|
65998
|
-
try {
|
|
65999
|
-
const tsconfigExists = await Bun.file("tsconfig.json").exists();
|
|
66000
|
-
if (!tsconfigExists) {
|
|
66001
|
-
step.skipped = true;
|
|
66002
|
-
step.skipReason = "No tsconfig.json found";
|
|
66003
|
-
step.passed = true;
|
|
66004
|
-
return step;
|
|
66005
|
-
}
|
|
66006
|
-
const result = await Bun.$`tsc --noEmit`.quiet().nothrow();
|
|
66007
|
-
step.exitCode = result.exitCode;
|
|
66008
|
-
step.passed = result.exitCode === 0;
|
|
66009
|
-
if (!step.passed) {
|
|
66010
|
-
step.error = result.stderr.toString().slice(0, 1000);
|
|
66011
|
-
step.output = result.stdout.toString().slice(0, 1000);
|
|
66012
|
-
}
|
|
66013
|
-
} catch (error45) {
|
|
66014
|
-
step.skipped = true;
|
|
66015
|
-
step.skipReason = `tsc not available: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
66016
|
-
step.passed = true;
|
|
66017
|
-
}
|
|
66018
|
-
return step;
|
|
66019
|
-
}
|
|
66020
|
-
async function runTestVerification(filesTouched) {
|
|
66021
|
-
const step = {
|
|
66022
|
-
name: "tests",
|
|
66023
|
-
command: "bun test <related-files>",
|
|
66024
|
-
passed: false,
|
|
66025
|
-
exitCode: -1
|
|
66026
|
-
};
|
|
66027
|
-
if (filesTouched.length === 0) {
|
|
66028
|
-
step.skipped = true;
|
|
66029
|
-
step.skipReason = "No files touched";
|
|
66030
|
-
step.passed = true;
|
|
66031
|
-
return step;
|
|
66032
|
-
}
|
|
66033
|
-
const testPatterns = [];
|
|
66034
|
-
for (const file2 of filesTouched) {
|
|
66035
|
-
if (file2.includes(".test.") || file2.includes(".spec.")) {
|
|
66036
|
-
testPatterns.push(file2);
|
|
66037
|
-
continue;
|
|
66038
|
-
}
|
|
66039
|
-
const baseName = file2.replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
66040
|
-
testPatterns.push(`${baseName}.test.ts`);
|
|
66041
|
-
testPatterns.push(`${baseName}.test.tsx`);
|
|
66042
|
-
testPatterns.push(`${baseName}.spec.ts`);
|
|
66043
|
-
}
|
|
66044
|
-
const existingTests = [];
|
|
66045
|
-
for (const pattern of testPatterns) {
|
|
66046
|
-
try {
|
|
66047
|
-
const exists = await Bun.file(pattern).exists();
|
|
66048
|
-
if (exists) {
|
|
66049
|
-
existingTests.push(pattern);
|
|
66050
|
-
}
|
|
66051
|
-
} catch {}
|
|
66052
|
-
}
|
|
66053
|
-
if (existingTests.length === 0) {
|
|
66054
|
-
step.skipped = true;
|
|
66055
|
-
step.skipReason = "No related test files found";
|
|
66056
|
-
step.passed = true;
|
|
66057
|
-
return step;
|
|
66058
|
-
}
|
|
66059
|
-
try {
|
|
66060
|
-
step.command = `bun test ${existingTests.join(" ")}`;
|
|
66061
|
-
const result = await Bun.$`bun test ${existingTests}`.quiet().nothrow();
|
|
66062
|
-
step.exitCode = result.exitCode;
|
|
66063
|
-
step.passed = result.exitCode === 0;
|
|
66064
|
-
if (!step.passed) {
|
|
66065
|
-
step.error = result.stderr.toString().slice(0, 1000);
|
|
66066
|
-
step.output = result.stdout.toString().slice(0, 1000);
|
|
66067
|
-
}
|
|
66068
|
-
} catch (error45) {
|
|
66069
|
-
step.skipped = true;
|
|
66070
|
-
step.skipReason = `Test runner failed: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
66071
|
-
step.passed = true;
|
|
66072
|
-
}
|
|
66073
|
-
return step;
|
|
66074
|
-
}
|
|
66075
|
-
async function runVerificationGate(filesTouched, _skipUbs = false) {
|
|
66076
|
-
const steps = [];
|
|
66077
|
-
const blockers = [];
|
|
66078
|
-
const typecheckStep = await runTypecheckVerification();
|
|
66079
|
-
steps.push(typecheckStep);
|
|
66080
|
-
if (!typecheckStep.passed && !typecheckStep.skipped) {
|
|
66081
|
-
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.`);
|
|
66082
|
-
}
|
|
66083
|
-
const testStep = await runTestVerification(filesTouched);
|
|
66084
|
-
steps.push(testStep);
|
|
66085
|
-
if (!testStep.passed && !testStep.skipped) {
|
|
66086
|
-
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.`);
|
|
66087
|
-
}
|
|
66088
|
-
const passedCount = steps.filter((s) => s.passed).length;
|
|
66089
|
-
const skippedCount = steps.filter((s) => s.skipped).length;
|
|
66090
|
-
const failedCount = steps.filter((s) => !s.passed && !s.skipped).length;
|
|
66091
|
-
const summary = failedCount === 0 ? `Verification passed: ${passedCount} checks passed, ${skippedCount} skipped` : `Verification FAILED: ${failedCount} checks failed, ${passedCount} passed, ${skippedCount} skipped`;
|
|
66092
|
-
return {
|
|
66093
|
-
passed: failedCount === 0,
|
|
66094
|
-
steps,
|
|
66095
|
-
summary,
|
|
66096
|
-
blockers
|
|
66097
|
-
};
|
|
66098
|
-
}
|
|
66099
66173
|
function classifyFailure(error45) {
|
|
66100
66174
|
const msg = (typeof error45 === "string" ? error45 : error45.message).toLowerCase();
|
|
66101
66175
|
if (msg.includes("timeout"))
|
|
@@ -66357,15 +66431,15 @@ var swarm_progress = tool({
|
|
|
66357
66431
|
}
|
|
66358
66432
|
};
|
|
66359
66433
|
const checkpointData = JSON.stringify(checkpoint);
|
|
66360
|
-
const checkpointEvent =
|
|
66434
|
+
const checkpointEvent = createEvent4("swarm_checkpointed", {
|
|
66361
66435
|
project_key: args.project_key,
|
|
66362
66436
|
...checkpoint,
|
|
66363
66437
|
checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
|
|
66364
66438
|
trigger: "progress"
|
|
66365
66439
|
});
|
|
66366
|
-
await
|
|
66440
|
+
await appendEvent3(checkpointEvent, args.project_key);
|
|
66367
66441
|
const checkpointId = `ckpt-${Date.now()}-${args.bead_id}`;
|
|
66368
|
-
const createdEvent =
|
|
66442
|
+
const createdEvent = createEvent4("checkpoint_created", {
|
|
66369
66443
|
project_key: args.project_key,
|
|
66370
66444
|
epic_id: epicId,
|
|
66371
66445
|
bead_id: args.bead_id,
|
|
@@ -66375,7 +66449,7 @@ var swarm_progress = tool({
|
|
|
66375
66449
|
progress_percent: args.progress_percent,
|
|
66376
66450
|
files_snapshot: args.files_touched
|
|
66377
66451
|
});
|
|
66378
|
-
await
|
|
66452
|
+
await appendEvent3(createdEvent, args.project_key);
|
|
66379
66453
|
checkpointCreated = true;
|
|
66380
66454
|
} catch (error45) {
|
|
66381
66455
|
console.warn(`[swarm_progress] Auto-checkpoint failed at ${args.progress_percent}%:`, error45);
|
|
@@ -66678,7 +66752,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
66678
66752
|
const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
|
|
66679
66753
|
let outcomeEventId;
|
|
66680
66754
|
try {
|
|
66681
|
-
const event =
|
|
66755
|
+
const event = createEvent4("subtask_outcome", {
|
|
66682
66756
|
project_key: args.project_key,
|
|
66683
66757
|
epic_id: eventEpicId,
|
|
66684
66758
|
bead_id: args.bead_id,
|
|
@@ -66691,7 +66765,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
66691
66765
|
scope_violation: contractValidation ? !contractValidation.valid : undefined,
|
|
66692
66766
|
violation_files: contractValidation?.violations
|
|
66693
66767
|
});
|
|
66694
|
-
const savedEvent = await
|
|
66768
|
+
const savedEvent = await appendEvent3(event, args.project_key);
|
|
66695
66769
|
outcomeEventId = savedEvent.id;
|
|
66696
66770
|
} catch (error45) {
|
|
66697
66771
|
console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
|
|
@@ -66709,7 +66783,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
66709
66783
|
}
|
|
66710
66784
|
}
|
|
66711
66785
|
try {
|
|
66712
|
-
const workerCompletedEvent =
|
|
66786
|
+
const workerCompletedEvent = createEvent4("worker_completed", {
|
|
66713
66787
|
project_key: args.project_key,
|
|
66714
66788
|
epic_id: eventEpicId,
|
|
66715
66789
|
bead_id: args.bead_id,
|
|
@@ -66718,7 +66792,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
66718
66792
|
duration_ms: completionDurationMs,
|
|
66719
66793
|
files_touched: args.files_touched || []
|
|
66720
66794
|
});
|
|
66721
|
-
await
|
|
66795
|
+
await appendEvent3(workerCompletedEvent, args.project_key);
|
|
66722
66796
|
} catch (error45) {
|
|
66723
66797
|
console.warn("[swarm_complete] Failed to emit worker_completed event:", error45);
|
|
66724
66798
|
}
|
|
@@ -67442,7 +67516,7 @@ var swarm_checkpoint = tool({
|
|
|
67442
67516
|
}
|
|
67443
67517
|
};
|
|
67444
67518
|
const checkpointData = JSON.stringify(checkpoint);
|
|
67445
|
-
const event =
|
|
67519
|
+
const event = createEvent4("swarm_checkpointed", {
|
|
67446
67520
|
project_key: args.project_key,
|
|
67447
67521
|
epic_id: args.epic_id,
|
|
67448
67522
|
bead_id: args.bead_id,
|
|
@@ -67454,7 +67528,7 @@ var swarm_checkpoint = tool({
|
|
|
67454
67528
|
checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
|
|
67455
67529
|
trigger: args.error_context ? "error" : "manual"
|
|
67456
67530
|
});
|
|
67457
|
-
await
|
|
67531
|
+
await appendEvent3(event, args.project_key);
|
|
67458
67532
|
const now = Date.now();
|
|
67459
67533
|
return JSON.stringify({
|
|
67460
67534
|
success: true,
|
|
@@ -67512,13 +67586,13 @@ var swarm_recover = tool({
|
|
|
67512
67586
|
created_at: row.created_at,
|
|
67513
67587
|
updated_at: row.updated_at
|
|
67514
67588
|
};
|
|
67515
|
-
const event =
|
|
67589
|
+
const event = createEvent4("swarm_recovered", {
|
|
67516
67590
|
project_key: args.project_key,
|
|
67517
67591
|
epic_id: args.epic_id,
|
|
67518
67592
|
bead_id: context.bead_id,
|
|
67519
67593
|
recovered_from_checkpoint: context.recovery.last_checkpoint
|
|
67520
67594
|
});
|
|
67521
|
-
await
|
|
67595
|
+
await appendEvent3(event, args.project_key);
|
|
67522
67596
|
return JSON.stringify({
|
|
67523
67597
|
found: true,
|
|
67524
67598
|
context,
|
|
@@ -67939,6 +68013,27 @@ swarmmail_reserve(
|
|
|
67939
68013
|
|
|
67940
68014
|
**Workers reserve their own files.** This prevents edit conflicts with other agents.
|
|
67941
68015
|
|
|
68016
|
+
### ⚠️ CRITICAL: File Path Handling (Next.js/Special Characters)
|
|
68017
|
+
|
|
68018
|
+
**DO NOT escape brackets or parentheses in file paths!**
|
|
68019
|
+
|
|
68020
|
+
When working with Next.js App Router or any codebase with special characters in paths:
|
|
68021
|
+
|
|
68022
|
+
❌ **WRONG** (will fail):
|
|
68023
|
+
\`\`\`
|
|
68024
|
+
Read: app/\\(content\\)/events/\\[slug\\]/page.tsx
|
|
68025
|
+
Glob: src/**/\\[id\\]/**/*.ts
|
|
68026
|
+
\`\`\`
|
|
68027
|
+
|
|
68028
|
+
✅ **CORRECT** (use raw paths):
|
|
68029
|
+
\`\`\`
|
|
68030
|
+
Read: app/(content)/events/[slug]/page.tsx
|
|
68031
|
+
Glob: src/**/[id]/**/*.ts
|
|
68032
|
+
\`\`\`
|
|
68033
|
+
|
|
68034
|
+
**The Read and Glob tools handle special characters automatically.**
|
|
68035
|
+
Never add backslashes before \`[\`, \`]\`, \`(\`, or \`)\` in file paths.
|
|
68036
|
+
|
|
67942
68037
|
### Step 5: Do the Work (TDD MANDATORY)
|
|
67943
68038
|
|
|
67944
68039
|
**Follow RED → GREEN → REFACTOR. No exceptions.**
|
|
@@ -68701,9 +68796,9 @@ var swarm_spawn_subtask = tool({
|
|
|
68701
68796
|
}
|
|
68702
68797
|
if (args2.project_path) {
|
|
68703
68798
|
try {
|
|
68704
|
-
const { createEvent:
|
|
68799
|
+
const { createEvent: createEvent6, appendEvent: appendEvent5 } = await import("swarm-mail");
|
|
68705
68800
|
const spawnOrder = 0;
|
|
68706
|
-
const workerSpawnedEvent =
|
|
68801
|
+
const workerSpawnedEvent = createEvent6("worker_spawned", {
|
|
68707
68802
|
project_key: args2.project_path,
|
|
68708
68803
|
epic_id: args2.epic_id,
|
|
68709
68804
|
bead_id: args2.bead_id,
|
|
@@ -68713,7 +68808,7 @@ var swarm_spawn_subtask = tool({
|
|
|
68713
68808
|
spawn_order: spawnOrder,
|
|
68714
68809
|
is_parallel: false
|
|
68715
68810
|
});
|
|
68716
|
-
await
|
|
68811
|
+
await appendEvent5(workerSpawnedEvent, args2.project_path);
|
|
68717
68812
|
} catch (error45) {
|
|
68718
68813
|
console.warn("[swarm_spawn_subtask] Failed to emit WorkerSpawnedEvent:", error45);
|
|
68719
68814
|
}
|
|
@@ -69411,7 +69506,8 @@ var swarmTools = {
|
|
|
69411
69506
|
...promptTools,
|
|
69412
69507
|
...orchestrateTools,
|
|
69413
69508
|
...researchTools,
|
|
69414
|
-
...adversarialReviewTools
|
|
69509
|
+
...adversarialReviewTools,
|
|
69510
|
+
...verificationTools
|
|
69415
69511
|
};
|
|
69416
69512
|
|
|
69417
69513
|
// src/repo-crawl.ts
|
|
@@ -70500,36 +70596,35 @@ var mandateTools = {
|
|
|
70500
70596
|
// src/hivemind-tools.ts
|
|
70501
70597
|
init_dist();
|
|
70502
70598
|
init_esm();
|
|
70503
|
-
init_memory();
|
|
70504
|
-
init_memory();
|
|
70505
70599
|
import {
|
|
70506
70600
|
getSwarmMailLibSQL as getSwarmMailLibSQL6,
|
|
70507
|
-
createEvent as createEvent5,
|
|
70508
70601
|
SessionIndexer,
|
|
70509
70602
|
syncMemories as syncMemories2,
|
|
70510
70603
|
toSwarmDb as toSwarmDb2,
|
|
70511
70604
|
makeOllamaLive as makeOllamaLive2
|
|
70512
70605
|
} from "swarm-mail";
|
|
70606
|
+
init_memory();
|
|
70607
|
+
init_memory();
|
|
70513
70608
|
import * as os2 from "node:os";
|
|
70514
70609
|
import * as path3 from "node:path";
|
|
70515
70610
|
import { join as join12 } from "node:path";
|
|
70516
|
-
var
|
|
70611
|
+
var cachedAdapter = null;
|
|
70517
70612
|
var cachedIndexer = null;
|
|
70518
|
-
var
|
|
70613
|
+
var cachedProjectPath = null;
|
|
70519
70614
|
async function getMemoryAdapter2(projectPath) {
|
|
70520
70615
|
const path4 = projectPath || process.cwd();
|
|
70521
|
-
if (
|
|
70522
|
-
return
|
|
70616
|
+
if (cachedAdapter && cachedProjectPath === path4) {
|
|
70617
|
+
return cachedAdapter;
|
|
70523
70618
|
}
|
|
70524
70619
|
const swarmMail = await getSwarmMailLibSQL6(path4);
|
|
70525
70620
|
const dbAdapter = await swarmMail.getDatabase();
|
|
70526
|
-
|
|
70527
|
-
|
|
70528
|
-
return
|
|
70621
|
+
cachedAdapter = await createMemoryAdapter(dbAdapter);
|
|
70622
|
+
cachedProjectPath = path4;
|
|
70623
|
+
return cachedAdapter;
|
|
70529
70624
|
}
|
|
70530
70625
|
async function getSessionIndexer(projectPath) {
|
|
70531
70626
|
const path4 = projectPath || process.cwd();
|
|
70532
|
-
if (cachedIndexer &&
|
|
70627
|
+
if (cachedIndexer && cachedProjectPath === path4) {
|
|
70533
70628
|
return cachedIndexer;
|
|
70534
70629
|
}
|
|
70535
70630
|
const swarmMail = await getSwarmMailLibSQL6(path4);
|
|
@@ -70540,20 +70635,13 @@ async function getSessionIndexer(projectPath) {
|
|
|
70540
70635
|
ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
|
|
70541
70636
|
});
|
|
70542
70637
|
cachedIndexer = new SessionIndexer(db, ollamaLayer);
|
|
70543
|
-
|
|
70638
|
+
cachedProjectPath = path4;
|
|
70544
70639
|
return cachedIndexer;
|
|
70545
70640
|
}
|
|
70546
70641
|
var getHivemindAdapter = getMemoryAdapter2;
|
|
70547
70642
|
async function emitEvent(eventType, data) {
|
|
70548
|
-
|
|
70549
|
-
|
|
70550
|
-
const swarmMail = await getSwarmMailLibSQL6(projectPath);
|
|
70551
|
-
const event = createEvent5(eventType, {
|
|
70552
|
-
project_key: projectPath,
|
|
70553
|
-
...data
|
|
70554
|
-
});
|
|
70555
|
-
await swarmMail.appendEvent(event);
|
|
70556
|
-
} catch {}
|
|
70643
|
+
const projectPath = cachedProjectPath || process.cwd();
|
|
70644
|
+
await safeEmitEvent(eventType, data, "hivemind", projectPath);
|
|
70557
70645
|
}
|
|
70558
70646
|
var AGENT_DIRECTORIES = [
|
|
70559
70647
|
path3.join(os2.homedir(), ".config", "swarm-tools", "sessions"),
|
|
@@ -70596,6 +70684,15 @@ var hivemind_find = tool({
|
|
|
70596
70684
|
fts: tool.schema.boolean().optional().describe("Use full-text search instead of vector search (default: false)")
|
|
70597
70685
|
},
|
|
70598
70686
|
async execute(args2, ctx) {
|
|
70687
|
+
if (!args2.query || typeof args2.query !== "string" || args2.query.trim() === "") {
|
|
70688
|
+
return JSON.stringify({
|
|
70689
|
+
success: false,
|
|
70690
|
+
error: {
|
|
70691
|
+
code: "VALIDATION_ERROR",
|
|
70692
|
+
message: "query parameter is required and must be a non-empty string"
|
|
70693
|
+
}
|
|
70694
|
+
});
|
|
70695
|
+
}
|
|
70599
70696
|
const startTime = Date.now();
|
|
70600
70697
|
const adapter = await getMemoryAdapter2();
|
|
70601
70698
|
const result = await adapter.find(args2);
|
|
@@ -70716,7 +70813,7 @@ var hivemind_sync = tool({
|
|
|
70716
70813
|
args: {},
|
|
70717
70814
|
async execute(args2, ctx) {
|
|
70718
70815
|
try {
|
|
70719
|
-
const projectPath =
|
|
70816
|
+
const projectPath = cachedProjectPath || process.cwd();
|
|
70720
70817
|
const swarmMail = await getSwarmMailLibSQL6(projectPath);
|
|
70721
70818
|
const dbAdapter = await swarmMail.getDatabase();
|
|
70722
70819
|
const hiveDir = join12(projectPath, ".hive");
|
|
@@ -72951,13 +73048,17 @@ var AGENT_DIRECTORIES2 = [
|
|
|
72951
73048
|
path5.join(os3.homedir(), ".local", "share", "Claude"),
|
|
72952
73049
|
path5.join(os3.homedir(), ".aider")
|
|
72953
73050
|
];
|
|
73051
|
+
var sessionIndexerCache = new AdapterCache;
|
|
72954
73052
|
async function getSessionIndexer2() {
|
|
72955
|
-
const
|
|
72956
|
-
|
|
72957
|
-
|
|
72958
|
-
|
|
73053
|
+
const globalKey = "global-session-indexer";
|
|
73054
|
+
return sessionIndexerCache.get(globalKey, async () => {
|
|
73055
|
+
const db = await getDb();
|
|
73056
|
+
const ollamaLayer = makeOllamaLive3({
|
|
73057
|
+
ollamaHost: process.env.OLLAMA_HOST || "http://localhost:11434",
|
|
73058
|
+
ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
|
|
73059
|
+
});
|
|
73060
|
+
return new SessionIndexer2(db, ollamaLayer);
|
|
72959
73061
|
});
|
|
72960
|
-
return new SessionIndexer2(db, ollamaLayer);
|
|
72961
73062
|
}
|
|
72962
73063
|
async function emitEvent2(eventType, data) {
|
|
72963
73064
|
try {
|