opencode-swarm-plugin 0.59.0 → 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 +714 -16
- 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/claude-plugin/skills/swarm-coordination/SKILL.md +42 -8
- 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/plugin.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,22 +46546,20 @@ 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
|
-
var
|
|
46558
|
+
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;
|
|
46538
46559
|
var init_memory_tools = __esm(() => {
|
|
46539
46560
|
init_dist();
|
|
46540
46561
|
init_memory();
|
|
46562
|
+
memoryAdapterCache = new AdapterCache;
|
|
46541
46563
|
semantic_memory_store = tool({
|
|
46542
46564
|
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.",
|
|
46543
46565
|
args: {
|
|
@@ -46554,9 +46576,9 @@ var init_memory_tools = __esm(() => {
|
|
|
46554
46576
|
const adapter = await getMemoryAdapter();
|
|
46555
46577
|
const result = await adapter.store(args2);
|
|
46556
46578
|
try {
|
|
46557
|
-
const projectKey =
|
|
46579
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46558
46580
|
const tags = args2.tags ? args2.tags.split(",").map((t) => t.trim()) : [];
|
|
46559
|
-
const event =
|
|
46581
|
+
const event = createEvent5("memory_stored", {
|
|
46560
46582
|
project_key: projectKey,
|
|
46561
46583
|
memory_id: result.id,
|
|
46562
46584
|
content_preview: args2.information.slice(0, 100),
|
|
@@ -46564,7 +46586,7 @@ var init_memory_tools = __esm(() => {
|
|
|
46564
46586
|
auto_tagged: args2.autoTag,
|
|
46565
46587
|
collection: args2.collection
|
|
46566
46588
|
});
|
|
46567
|
-
await
|
|
46589
|
+
await appendEvent4(event, projectKey);
|
|
46568
46590
|
} catch (error45) {
|
|
46569
46591
|
console.warn("[semantic_memory_store] Failed to emit memory_stored event:", error45);
|
|
46570
46592
|
}
|
|
@@ -46586,9 +46608,9 @@ var init_memory_tools = __esm(() => {
|
|
|
46586
46608
|
const result = await adapter.find(args2);
|
|
46587
46609
|
const duration3 = Date.now() - startTime;
|
|
46588
46610
|
try {
|
|
46589
|
-
const projectKey =
|
|
46611
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46590
46612
|
const topScore = result.results.length > 0 ? result.results[0].score : undefined;
|
|
46591
|
-
const event =
|
|
46613
|
+
const event = createEvent5("memory_found", {
|
|
46592
46614
|
project_key: projectKey,
|
|
46593
46615
|
query: args2.query,
|
|
46594
46616
|
result_count: result.results.length,
|
|
@@ -46596,7 +46618,7 @@ var init_memory_tools = __esm(() => {
|
|
|
46596
46618
|
search_duration_ms: duration3,
|
|
46597
46619
|
used_fts: args2.fts
|
|
46598
46620
|
});
|
|
46599
|
-
await
|
|
46621
|
+
await appendEvent4(event, projectKey);
|
|
46600
46622
|
} catch (error45) {
|
|
46601
46623
|
console.warn("[semantic_memory_find] Failed to emit memory_found event:", error45);
|
|
46602
46624
|
}
|
|
@@ -46624,12 +46646,12 @@ var init_memory_tools = __esm(() => {
|
|
|
46624
46646
|
const result = await adapter.remove(args2);
|
|
46625
46647
|
if (result.success) {
|
|
46626
46648
|
try {
|
|
46627
|
-
const projectKey =
|
|
46628
|
-
const event =
|
|
46649
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46650
|
+
const event = createEvent5("memory_deleted", {
|
|
46629
46651
|
project_key: projectKey,
|
|
46630
46652
|
memory_id: args2.id
|
|
46631
46653
|
});
|
|
46632
|
-
await
|
|
46654
|
+
await appendEvent4(event, projectKey);
|
|
46633
46655
|
} catch (error45) {
|
|
46634
46656
|
console.warn("[semantic_memory_remove] Failed to emit memory_deleted event:", error45);
|
|
46635
46657
|
}
|
|
@@ -46647,13 +46669,13 @@ var init_memory_tools = __esm(() => {
|
|
|
46647
46669
|
const result = await adapter.validate(args2);
|
|
46648
46670
|
if (result.success) {
|
|
46649
46671
|
try {
|
|
46650
|
-
const projectKey =
|
|
46651
|
-
const event =
|
|
46672
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46673
|
+
const event = createEvent5("memory_validated", {
|
|
46652
46674
|
project_key: projectKey,
|
|
46653
46675
|
memory_id: args2.id,
|
|
46654
46676
|
decay_reset: true
|
|
46655
46677
|
});
|
|
46656
|
-
await
|
|
46678
|
+
await appendEvent4(event, projectKey);
|
|
46657
46679
|
} catch (error45) {
|
|
46658
46680
|
console.warn("[semantic_memory_validate] Failed to emit memory_validated event:", error45);
|
|
46659
46681
|
}
|
|
@@ -46706,14 +46728,14 @@ var init_memory_tools = __esm(() => {
|
|
|
46706
46728
|
const adapter = await getMemoryAdapter();
|
|
46707
46729
|
const result = await adapter.upsert(args2);
|
|
46708
46730
|
try {
|
|
46709
|
-
const projectKey =
|
|
46710
|
-
const event =
|
|
46731
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46732
|
+
const event = createEvent5("memory_updated", {
|
|
46711
46733
|
project_key: projectKey,
|
|
46712
46734
|
memory_id: result.memoryId || "unknown",
|
|
46713
46735
|
operation: result.operation,
|
|
46714
46736
|
reason: result.reason
|
|
46715
46737
|
});
|
|
46716
|
-
await
|
|
46738
|
+
await appendEvent4(event, projectKey);
|
|
46717
46739
|
} catch (error45) {
|
|
46718
46740
|
console.warn("[semantic_memory_upsert] Failed to emit memory_updated event:", error45);
|
|
46719
46741
|
}
|
|
@@ -58929,7 +58951,24 @@ var CellEventSchema = exports_external.discriminatedUnion("type", [
|
|
|
58929
58951
|
CellCompactedEventSchema
|
|
58930
58952
|
]);
|
|
58931
58953
|
// src/hive.ts
|
|
58954
|
+
import { createEvent as createEvent2, appendEvent as appendEvent2 } from "swarm-mail";
|
|
58955
|
+
|
|
58956
|
+
// src/utils/event-utils.ts
|
|
58932
58957
|
import { createEvent, appendEvent } from "swarm-mail";
|
|
58958
|
+
async function safeEmitEvent(eventType, data, toolName, projectPath) {
|
|
58959
|
+
try {
|
|
58960
|
+
const effectiveProjectPath = projectPath || process.cwd();
|
|
58961
|
+
const event = createEvent(eventType, {
|
|
58962
|
+
project_key: effectiveProjectPath,
|
|
58963
|
+
...data
|
|
58964
|
+
});
|
|
58965
|
+
await appendEvent(event, effectiveProjectPath);
|
|
58966
|
+
} catch (error45) {
|
|
58967
|
+
console.warn(`[${toolName}] Failed to emit ${eventType} event:`, error45);
|
|
58968
|
+
}
|
|
58969
|
+
}
|
|
58970
|
+
|
|
58971
|
+
// src/hive.ts
|
|
58933
58972
|
var hiveWorkingDirectory = null;
|
|
58934
58973
|
function setHiveWorkingDirectory(directory) {
|
|
58935
58974
|
hiveWorkingDirectory = directory;
|
|
@@ -59087,20 +59126,14 @@ var hive_create = tool({
|
|
|
59087
59126
|
parent_id: validated.parent_id
|
|
59088
59127
|
});
|
|
59089
59128
|
await adapter.markDirty(projectKey, cell.id);
|
|
59090
|
-
|
|
59091
|
-
|
|
59092
|
-
|
|
59093
|
-
|
|
59094
|
-
|
|
59095
|
-
|
|
59096
|
-
|
|
59097
|
-
|
|
59098
|
-
parent_id: validated.parent_id
|
|
59099
|
-
});
|
|
59100
|
-
await appendEvent(event, projectKey);
|
|
59101
|
-
} catch (error45) {
|
|
59102
|
-
console.warn("[hive_create] Failed to emit cell_created event:", error45);
|
|
59103
|
-
}
|
|
59129
|
+
await safeEmitEvent("cell_created", {
|
|
59130
|
+
cell_id: cell.id,
|
|
59131
|
+
title: validated.title,
|
|
59132
|
+
description: validated.description,
|
|
59133
|
+
issue_type: validated.type || "task",
|
|
59134
|
+
priority: validated.priority ?? 2,
|
|
59135
|
+
parent_id: validated.parent_id
|
|
59136
|
+
}, "hive_create", projectKey);
|
|
59104
59137
|
const formatted = formatCellForOutput(cell);
|
|
59105
59138
|
return JSON.stringify(formatted, null, 2);
|
|
59106
59139
|
} catch (error45) {
|
|
@@ -59182,53 +59215,35 @@ var hive_create_epic = tool({
|
|
|
59182
59215
|
subtasks: created.slice(1).map((c) => formatCellForOutput(c))
|
|
59183
59216
|
};
|
|
59184
59217
|
const effectiveProjectKey = args.project_key || projectKey;
|
|
59185
|
-
|
|
59186
|
-
|
|
59187
|
-
|
|
59188
|
-
|
|
59189
|
-
|
|
59190
|
-
|
|
59191
|
-
|
|
59192
|
-
|
|
59193
|
-
|
|
59194
|
-
|
|
59195
|
-
|
|
59196
|
-
|
|
59197
|
-
|
|
59198
|
-
|
|
59199
|
-
|
|
59200
|
-
|
|
59201
|
-
|
|
59202
|
-
|
|
59203
|
-
|
|
59204
|
-
|
|
59205
|
-
|
|
59206
|
-
|
|
59207
|
-
|
|
59208
|
-
|
|
59209
|
-
|
|
59210
|
-
|
|
59211
|
-
|
|
59212
|
-
|
|
59213
|
-
|
|
59214
|
-
} catch (error45) {
|
|
59215
|
-
console.warn("[hive_create_epic] Failed to emit DecompositionGeneratedEvent:", error45);
|
|
59216
|
-
}
|
|
59217
|
-
try {
|
|
59218
|
-
const totalFiles = validated.subtasks.reduce((count, st) => count + (st.files?.length || 0), 0);
|
|
59219
|
-
const swarmStartedEvent = createEvent("swarm_started", {
|
|
59220
|
-
project_key: effectiveProjectKey,
|
|
59221
|
-
epic_id: epic.id,
|
|
59222
|
-
epic_title: validated.epic_title,
|
|
59223
|
-
strategy: args.strategy || "feature-based",
|
|
59224
|
-
subtask_count: validated.subtasks.length,
|
|
59225
|
-
total_files: totalFiles,
|
|
59226
|
-
coordinator_agent: "coordinator"
|
|
59227
|
-
});
|
|
59228
|
-
await appendEvent(swarmStartedEvent, effectiveProjectKey);
|
|
59229
|
-
} catch (error45) {
|
|
59230
|
-
console.warn("[hive_create_epic] Failed to emit SwarmStartedEvent:", error45);
|
|
59231
|
-
}
|
|
59218
|
+
await safeEmitEvent("epic_created", {
|
|
59219
|
+
epic_id: epic.id,
|
|
59220
|
+
title: validated.epic_title,
|
|
59221
|
+
description: validated.epic_description,
|
|
59222
|
+
subtask_count: validated.subtasks.length,
|
|
59223
|
+
subtask_ids: created.slice(1).map((c) => c.id)
|
|
59224
|
+
}, "hive_create_epic", effectiveProjectKey);
|
|
59225
|
+
await safeEmitEvent("decomposition_generated", {
|
|
59226
|
+
epic_id: epic.id,
|
|
59227
|
+
task: args.task || validated.epic_title,
|
|
59228
|
+
context: validated.epic_description,
|
|
59229
|
+
strategy: args.strategy || "feature-based",
|
|
59230
|
+
epic_title: validated.epic_title,
|
|
59231
|
+
subtasks: validated.subtasks.map((st) => ({
|
|
59232
|
+
title: st.title,
|
|
59233
|
+
files: st.files || [],
|
|
59234
|
+
priority: st.priority
|
|
59235
|
+
})),
|
|
59236
|
+
recovery_context: args.recovery_context
|
|
59237
|
+
}, "hive_create_epic", effectiveProjectKey);
|
|
59238
|
+
const totalFiles = validated.subtasks.reduce((count, st) => count + (st.files?.length || 0), 0);
|
|
59239
|
+
await safeEmitEvent("swarm_started", {
|
|
59240
|
+
epic_id: epic.id,
|
|
59241
|
+
epic_title: validated.epic_title,
|
|
59242
|
+
strategy: args.strategy || "feature-based",
|
|
59243
|
+
subtask_count: validated.subtasks.length,
|
|
59244
|
+
total_files: totalFiles,
|
|
59245
|
+
coordinator_agent: "coordinator"
|
|
59246
|
+
}, "hive_create_epic", effectiveProjectKey);
|
|
59232
59247
|
try {
|
|
59233
59248
|
const { captureCoordinatorEvent: captureCoordinatorEvent2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
|
|
59234
59249
|
const filesPerSubtask = {};
|
|
@@ -59359,23 +59374,17 @@ var hive_update = tool({
|
|
|
59359
59374
|
cell = existingCell;
|
|
59360
59375
|
}
|
|
59361
59376
|
await adapter.markDirty(projectKey, cellId);
|
|
59362
|
-
|
|
59363
|
-
|
|
59364
|
-
|
|
59365
|
-
|
|
59366
|
-
|
|
59367
|
-
|
|
59368
|
-
|
|
59369
|
-
|
|
59370
|
-
|
|
59371
|
-
|
|
59372
|
-
|
|
59373
|
-
fields_changed: fieldsChanged
|
|
59374
|
-
});
|
|
59375
|
-
await appendEvent(event, projectKey);
|
|
59376
|
-
} catch (error45) {
|
|
59377
|
-
console.warn("[hive_update] Failed to emit cell_updated event:", error45);
|
|
59378
|
-
}
|
|
59377
|
+
const fieldsChanged = [];
|
|
59378
|
+
if (validated.status)
|
|
59379
|
+
fieldsChanged.push("status");
|
|
59380
|
+
if (validated.description !== undefined)
|
|
59381
|
+
fieldsChanged.push("description");
|
|
59382
|
+
if (validated.priority !== undefined)
|
|
59383
|
+
fieldsChanged.push("priority");
|
|
59384
|
+
await safeEmitEvent("cell_updated", {
|
|
59385
|
+
cell_id: cellId,
|
|
59386
|
+
fields_changed: fieldsChanged
|
|
59387
|
+
}, "hive_update", projectKey);
|
|
59379
59388
|
const formatted = formatCellForOutput(cell);
|
|
59380
59389
|
return JSON.stringify(formatted, null, 2);
|
|
59381
59390
|
} catch (error45) {
|
|
@@ -59408,7 +59417,6 @@ var hive_close = tool({
|
|
|
59408
59417
|
await adapter.markDirty(projectKey, cellId);
|
|
59409
59418
|
if (isEpic && cellBeforeClose) {
|
|
59410
59419
|
try {
|
|
59411
|
-
const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
|
|
59412
59420
|
const subtasks = await adapter.queryCells(projectKey, { parent_id: cellId });
|
|
59413
59421
|
const completedSubtasks = subtasks.filter((st) => st.status === "closed");
|
|
59414
59422
|
const failedSubtasks = subtasks.filter((st) => st.status === "blocked");
|
|
@@ -59446,8 +59454,7 @@ var hive_close = tool({
|
|
|
59446
59454
|
} catch (error45) {
|
|
59447
59455
|
console.warn("[hive_close] Failed to calculate duration:", error45);
|
|
59448
59456
|
}
|
|
59449
|
-
|
|
59450
|
-
project_key: projectKey,
|
|
59457
|
+
await safeEmitEvent("swarm_completed", {
|
|
59451
59458
|
epic_id: cellId,
|
|
59452
59459
|
epic_title: cellBeforeClose.title,
|
|
59453
59460
|
success: failedSubtasks.length === 0,
|
|
@@ -59455,8 +59462,7 @@ var hive_close = tool({
|
|
|
59455
59462
|
subtasks_completed: completedSubtasks.length,
|
|
59456
59463
|
subtasks_failed: failedSubtasks.length,
|
|
59457
59464
|
total_files_touched: totalFilesTouched
|
|
59458
|
-
});
|
|
59459
|
-
await appendEvent2(swarmCompletedEvent, projectKey);
|
|
59465
|
+
}, "hive_close", projectKey);
|
|
59460
59466
|
try {
|
|
59461
59467
|
const { runPostSwarmValidation: runPostSwarmValidation2 } = await Promise.resolve().then(() => (init_swarm_validation(), exports_swarm_validation));
|
|
59462
59468
|
const { readEvents } = await import("swarm-mail");
|
|
@@ -59492,16 +59498,10 @@ var hive_close = tool({
|
|
|
59492
59498
|
console.warn("[hive_close] Failed to emit SwarmCompletedEvent:", error45);
|
|
59493
59499
|
}
|
|
59494
59500
|
}
|
|
59495
|
-
|
|
59496
|
-
|
|
59497
|
-
|
|
59498
|
-
|
|
59499
|
-
reason: validated.reason
|
|
59500
|
-
});
|
|
59501
|
-
await appendEvent(event, projectKey);
|
|
59502
|
-
} catch (error45) {
|
|
59503
|
-
console.warn("[hive_close] Failed to emit cell_closed event:", error45);
|
|
59504
|
-
}
|
|
59501
|
+
await safeEmitEvent("cell_closed", {
|
|
59502
|
+
cell_id: cellId,
|
|
59503
|
+
reason: validated.reason
|
|
59504
|
+
}, "hive_close", projectKey);
|
|
59505
59505
|
return `Closed ${cell.id}: ${validated.reason}`;
|
|
59506
59506
|
} catch (error45) {
|
|
59507
59507
|
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
@@ -59528,13 +59528,13 @@ var hive_start = tool({
|
|
|
59528
59528
|
const cell = await adapter.changeCellStatus(projectKey, cellId, "in_progress");
|
|
59529
59529
|
await adapter.markDirty(projectKey, cellId);
|
|
59530
59530
|
try {
|
|
59531
|
-
const event =
|
|
59531
|
+
const event = createEvent2("cell_status_changed", {
|
|
59532
59532
|
project_key: projectKey,
|
|
59533
59533
|
cell_id: cellId,
|
|
59534
59534
|
old_status: "open",
|
|
59535
59535
|
new_status: "in_progress"
|
|
59536
59536
|
});
|
|
59537
|
-
await
|
|
59537
|
+
await appendEvent2(event, projectKey);
|
|
59538
59538
|
} catch (error45) {
|
|
59539
59539
|
console.warn("[hive_start] Failed to emit cell_status_changed event:", error45);
|
|
59540
59540
|
}
|
|
@@ -59735,12 +59735,12 @@ var hive_sync = tool({
|
|
|
59735
59735
|
pushSuccess = true;
|
|
59736
59736
|
}
|
|
59737
59737
|
try {
|
|
59738
|
-
const event =
|
|
59738
|
+
const event = createEvent2("hive_synced", {
|
|
59739
59739
|
project_key: projectKey,
|
|
59740
59740
|
cells_synced: flushResult.cellsExported,
|
|
59741
59741
|
push_success: pushSuccess
|
|
59742
59742
|
});
|
|
59743
|
-
await
|
|
59743
|
+
await appendEvent2(event, projectKey);
|
|
59744
59744
|
} catch (error45) {
|
|
59745
59745
|
console.warn("[hive_sync] Failed to emit hive_synced event:", error45);
|
|
59746
59746
|
}
|
|
@@ -61755,10 +61755,13 @@ var swarmmail_read_message = tool({
|
|
|
61755
61755
|
}
|
|
61756
61756
|
}
|
|
61757
61757
|
});
|
|
61758
|
+
function normalizePath(path2) {
|
|
61759
|
+
return path2.replace(/\\([[\]()])/g, "$1");
|
|
61760
|
+
}
|
|
61758
61761
|
var swarmmail_reserve = tool({
|
|
61759
|
-
description: "Reserve file paths for exclusive editing. Prevents conflicts with other agents.",
|
|
61762
|
+
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.",
|
|
61760
61763
|
args: {
|
|
61761
|
-
paths: tool.schema.array(tool.schema.string()).describe("File paths or glob patterns to reserve"),
|
|
61764
|
+
paths: tool.schema.array(tool.schema.string()).transform((paths) => paths.map(normalizePath)).describe("File paths or glob patterns to reserve. Do NOT escape [ ] ( ) characters."),
|
|
61762
61765
|
reason: tool.schema.string().optional().describe("Reason for reservation (e.g., bead ID)"),
|
|
61763
61766
|
exclusive: tool.schema.boolean().optional().describe("Whether reservation is exclusive (default: true)"),
|
|
61764
61767
|
ttl_seconds: tool.schema.number().optional().describe("Time-to-live in seconds (default: 3600)")
|
|
@@ -61770,10 +61773,11 @@ var swarmmail_reserve = tool({
|
|
|
61770
61773
|
return JSON.stringify({ error: "Session not initialized. Call swarmmail_init first." }, null, 2);
|
|
61771
61774
|
}
|
|
61772
61775
|
try {
|
|
61776
|
+
const normalizedPaths = args.paths.map(normalizePath);
|
|
61773
61777
|
const result = await reserveSwarmFiles({
|
|
61774
61778
|
projectPath: state.projectKey,
|
|
61775
61779
|
agentName: state.agentName,
|
|
61776
|
-
paths:
|
|
61780
|
+
paths: normalizedPaths,
|
|
61777
61781
|
reason: args.reason,
|
|
61778
61782
|
exclusive: args.exclusive ?? true,
|
|
61779
61783
|
ttlSeconds: args.ttl_seconds
|
|
@@ -61801,9 +61805,9 @@ var swarmmail_reserve = tool({
|
|
|
61801
61805
|
}
|
|
61802
61806
|
});
|
|
61803
61807
|
var swarmmail_release = tool({
|
|
61804
|
-
description: "Release file reservations. Call when done editing files.",
|
|
61808
|
+
description: "Release file reservations. Call when done editing files. " + "Do NOT escape brackets or parentheses in paths.",
|
|
61805
61809
|
args: {
|
|
61806
|
-
paths: tool.schema.array(tool.schema.string()).optional().describe("Specific paths to release (releases all if omitted)"),
|
|
61810
|
+
paths: tool.schema.array(tool.schema.string()).optional().describe("Specific paths to release (releases all if omitted). Do NOT escape [ ] ( ) characters."),
|
|
61807
61811
|
reservation_ids: tool.schema.array(tool.schema.number()).optional().describe("Specific reservation IDs to release")
|
|
61808
61812
|
},
|
|
61809
61813
|
async execute(args, ctx) {
|
|
@@ -61814,10 +61818,11 @@ var swarmmail_release = tool({
|
|
|
61814
61818
|
}
|
|
61815
61819
|
try {
|
|
61816
61820
|
const currentReservations = await getActiveReservations(state.projectKey, state.projectKey, state.agentName);
|
|
61821
|
+
const normalizedPaths = args.paths?.map(normalizePath);
|
|
61817
61822
|
const result = await releaseSwarmFiles({
|
|
61818
61823
|
projectPath: state.projectKey,
|
|
61819
61824
|
agentName: state.agentName,
|
|
61820
|
-
paths:
|
|
61825
|
+
paths: normalizedPaths,
|
|
61821
61826
|
reservationIds: args.reservation_ids
|
|
61822
61827
|
});
|
|
61823
61828
|
if (!args.paths && !args.reservation_ids) {
|
|
@@ -64691,8 +64696,8 @@ import {
|
|
|
64691
64696
|
releaseSwarmFiles as releaseSwarmFiles2,
|
|
64692
64697
|
sendSwarmMessage as sendSwarmMessage3,
|
|
64693
64698
|
getAgent,
|
|
64694
|
-
createEvent as
|
|
64695
|
-
appendEvent as
|
|
64699
|
+
createEvent as createEvent4,
|
|
64700
|
+
appendEvent as appendEvent3,
|
|
64696
64701
|
getSwarmMailLibSQL as getSwarmMailLibSQL4
|
|
64697
64702
|
} from "swarm-mail";
|
|
64698
64703
|
init_skills();
|
|
@@ -65197,15 +65202,15 @@ var swarm_review = tool({
|
|
|
65197
65202
|
downstream_tasks: downstreamTasks.length > 0 ? downstreamTasks : undefined
|
|
65198
65203
|
});
|
|
65199
65204
|
try {
|
|
65200
|
-
const { createEvent:
|
|
65205
|
+
const { createEvent: createEvent4, appendEvent: appendEvent3 } = await import("swarm-mail");
|
|
65201
65206
|
const attempt = getReviewStatus(args.task_id).attempt_count || 1;
|
|
65202
|
-
const reviewStartedEvent =
|
|
65207
|
+
const reviewStartedEvent = createEvent4("review_started", {
|
|
65203
65208
|
project_key: args.project_key,
|
|
65204
65209
|
epic_id: args.epic_id,
|
|
65205
65210
|
bead_id: args.task_id,
|
|
65206
65211
|
attempt
|
|
65207
65212
|
});
|
|
65208
|
-
await
|
|
65213
|
+
await appendEvent3(reviewStartedEvent, args.project_key);
|
|
65209
65214
|
} catch (error45) {
|
|
65210
65215
|
console.warn("[swarm_review] Failed to emit ReviewStartedEvent:", error45);
|
|
65211
65216
|
}
|
|
@@ -65288,16 +65293,16 @@ var swarm_review_feedback = tool({
|
|
|
65288
65293
|
console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
|
|
65289
65294
|
}
|
|
65290
65295
|
try {
|
|
65291
|
-
const { createEvent:
|
|
65296
|
+
const { createEvent: createEvent4, appendEvent: appendEvent3 } = await import("swarm-mail");
|
|
65292
65297
|
const attempt = getReviewStatus(args.task_id).attempt_count || 1;
|
|
65293
|
-
const reviewCompletedEvent =
|
|
65298
|
+
const reviewCompletedEvent = createEvent4("review_completed", {
|
|
65294
65299
|
project_key: args.project_key,
|
|
65295
65300
|
epic_id: epicId,
|
|
65296
65301
|
bead_id: args.task_id,
|
|
65297
65302
|
status: "approved",
|
|
65298
65303
|
attempt
|
|
65299
65304
|
});
|
|
65300
|
-
await
|
|
65305
|
+
await appendEvent3(reviewCompletedEvent, args.project_key);
|
|
65301
65306
|
} catch (error45) {
|
|
65302
65307
|
console.warn("[swarm_review_feedback] Failed to emit ReviewCompletedEvent:", error45);
|
|
65303
65308
|
}
|
|
@@ -65359,16 +65364,16 @@ You may now complete the task with \`swarm_complete\`.`,
|
|
|
65359
65364
|
console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
|
|
65360
65365
|
}
|
|
65361
65366
|
try {
|
|
65362
|
-
const { createEvent:
|
|
65367
|
+
const { createEvent: createEvent4, appendEvent: appendEvent3 } = await import("swarm-mail");
|
|
65363
65368
|
const status = remaining <= 0 ? "blocked" : "needs_changes";
|
|
65364
|
-
const reviewCompletedEvent =
|
|
65369
|
+
const reviewCompletedEvent = createEvent4("review_completed", {
|
|
65365
65370
|
project_key: args.project_key,
|
|
65366
65371
|
epic_id: epicId,
|
|
65367
65372
|
bead_id: args.task_id,
|
|
65368
65373
|
status,
|
|
65369
65374
|
attempt: attemptNumber
|
|
65370
65375
|
});
|
|
65371
|
-
await
|
|
65376
|
+
await appendEvent3(reviewCompletedEvent, args.project_key);
|
|
65372
65377
|
} catch (error45) {
|
|
65373
65378
|
console.warn("[swarm_review_feedback] Failed to emit ReviewCompletedEvent:", error45);
|
|
65374
65379
|
}
|
|
@@ -65428,6 +65433,184 @@ var reviewTools = {
|
|
|
65428
65433
|
|
|
65429
65434
|
// src/swarm-orchestrate.ts
|
|
65430
65435
|
init_eval_capture();
|
|
65436
|
+
|
|
65437
|
+
// src/swarm-verify.ts
|
|
65438
|
+
init_dist();
|
|
65439
|
+
async function runTypecheckVerification() {
|
|
65440
|
+
const step = {
|
|
65441
|
+
name: "typecheck",
|
|
65442
|
+
command: "tsc --noEmit",
|
|
65443
|
+
passed: false,
|
|
65444
|
+
exitCode: -1
|
|
65445
|
+
};
|
|
65446
|
+
try {
|
|
65447
|
+
const tsconfigExists = await Bun.file("tsconfig.json").exists();
|
|
65448
|
+
if (!tsconfigExists) {
|
|
65449
|
+
step.skipped = true;
|
|
65450
|
+
step.skipReason = "No tsconfig.json found";
|
|
65451
|
+
step.passed = true;
|
|
65452
|
+
return step;
|
|
65453
|
+
}
|
|
65454
|
+
const result = await Bun.$`tsc --noEmit`.quiet().nothrow();
|
|
65455
|
+
step.exitCode = result.exitCode;
|
|
65456
|
+
step.passed = result.exitCode === 0;
|
|
65457
|
+
if (!step.passed) {
|
|
65458
|
+
step.error = result.stderr.toString().slice(0, 1000);
|
|
65459
|
+
step.output = result.stdout.toString().slice(0, 1000);
|
|
65460
|
+
}
|
|
65461
|
+
} catch (error45) {
|
|
65462
|
+
step.skipped = true;
|
|
65463
|
+
step.skipReason = `tsc not available: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
65464
|
+
step.passed = true;
|
|
65465
|
+
}
|
|
65466
|
+
return step;
|
|
65467
|
+
}
|
|
65468
|
+
async function runTestVerification(filesTouched) {
|
|
65469
|
+
const step = {
|
|
65470
|
+
name: "tests",
|
|
65471
|
+
command: "bun test <related-files>",
|
|
65472
|
+
passed: false,
|
|
65473
|
+
exitCode: -1
|
|
65474
|
+
};
|
|
65475
|
+
if (filesTouched.length === 0) {
|
|
65476
|
+
step.skipped = true;
|
|
65477
|
+
step.skipReason = "No files touched";
|
|
65478
|
+
step.passed = true;
|
|
65479
|
+
return step;
|
|
65480
|
+
}
|
|
65481
|
+
const testPatterns = [];
|
|
65482
|
+
for (const file2 of filesTouched) {
|
|
65483
|
+
if (file2.includes(".test.") || file2.includes(".spec.")) {
|
|
65484
|
+
testPatterns.push(file2);
|
|
65485
|
+
continue;
|
|
65486
|
+
}
|
|
65487
|
+
const baseName = file2.replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
65488
|
+
testPatterns.push(`${baseName}.test.ts`);
|
|
65489
|
+
testPatterns.push(`${baseName}.test.tsx`);
|
|
65490
|
+
testPatterns.push(`${baseName}.spec.ts`);
|
|
65491
|
+
}
|
|
65492
|
+
const existingTests = [];
|
|
65493
|
+
for (const pattern of testPatterns) {
|
|
65494
|
+
try {
|
|
65495
|
+
const exists = await Bun.file(pattern).exists();
|
|
65496
|
+
if (exists) {
|
|
65497
|
+
existingTests.push(pattern);
|
|
65498
|
+
}
|
|
65499
|
+
} catch {}
|
|
65500
|
+
}
|
|
65501
|
+
if (existingTests.length === 0) {
|
|
65502
|
+
step.skipped = true;
|
|
65503
|
+
step.skipReason = "No related test files found";
|
|
65504
|
+
step.passed = true;
|
|
65505
|
+
return step;
|
|
65506
|
+
}
|
|
65507
|
+
try {
|
|
65508
|
+
step.command = `bun test ${existingTests.join(" ")}`;
|
|
65509
|
+
const result = await Bun.$`bun test ${existingTests}`.quiet().nothrow();
|
|
65510
|
+
step.exitCode = result.exitCode;
|
|
65511
|
+
step.passed = result.exitCode === 0;
|
|
65512
|
+
if (!step.passed) {
|
|
65513
|
+
step.error = result.stderr.toString().slice(0, 1000);
|
|
65514
|
+
step.output = result.stdout.toString().slice(0, 1000);
|
|
65515
|
+
}
|
|
65516
|
+
} catch (error45) {
|
|
65517
|
+
step.skipped = true;
|
|
65518
|
+
step.skipReason = `Test runner failed: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
65519
|
+
step.passed = true;
|
|
65520
|
+
}
|
|
65521
|
+
return step;
|
|
65522
|
+
}
|
|
65523
|
+
async function runVerificationGate(filesTouched, _skipUbs = false) {
|
|
65524
|
+
const steps = [];
|
|
65525
|
+
const blockers = [];
|
|
65526
|
+
const typecheckStep = await runTypecheckVerification();
|
|
65527
|
+
steps.push(typecheckStep);
|
|
65528
|
+
if (!typecheckStep.passed && !typecheckStep.skipped) {
|
|
65529
|
+
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.`);
|
|
65530
|
+
}
|
|
65531
|
+
const testStep = await runTestVerification(filesTouched);
|
|
65532
|
+
steps.push(testStep);
|
|
65533
|
+
if (!testStep.passed && !testStep.skipped) {
|
|
65534
|
+
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.`);
|
|
65535
|
+
}
|
|
65536
|
+
const passedCount = steps.filter((s) => s.passed).length;
|
|
65537
|
+
const skippedCount = steps.filter((s) => s.skipped).length;
|
|
65538
|
+
const failedCount = steps.filter((s) => !s.passed && !s.skipped).length;
|
|
65539
|
+
const summary = failedCount === 0 ? `Verification passed: ${passedCount} checks passed, ${skippedCount} skipped` : `Verification FAILED: ${failedCount} checks failed, ${passedCount} passed, ${skippedCount} skipped`;
|
|
65540
|
+
return {
|
|
65541
|
+
passed: failedCount === 0,
|
|
65542
|
+
steps,
|
|
65543
|
+
summary,
|
|
65544
|
+
blockers
|
|
65545
|
+
};
|
|
65546
|
+
}
|
|
65547
|
+
var swarm_verify = tool({
|
|
65548
|
+
description: "Run verification gate (typecheck + tests) for files. Returns verification results without blocking. Used by swarm_complete to verify worker output.",
|
|
65549
|
+
args: {
|
|
65550
|
+
files_touched: tool.schema.array(tool.schema.string()).describe("Files to verify (typecheck + test discovery)"),
|
|
65551
|
+
skip_verification: tool.schema.boolean().optional().describe("Skip verification entirely (default: false)")
|
|
65552
|
+
},
|
|
65553
|
+
async execute(args) {
|
|
65554
|
+
try {
|
|
65555
|
+
if (args.skip_verification) {
|
|
65556
|
+
return JSON.stringify({
|
|
65557
|
+
success: true,
|
|
65558
|
+
data: {
|
|
65559
|
+
passed: true,
|
|
65560
|
+
skipped: true,
|
|
65561
|
+
reason: "skip_verification=true",
|
|
65562
|
+
summary: "Verification skipped by request",
|
|
65563
|
+
steps: [],
|
|
65564
|
+
blockers: []
|
|
65565
|
+
}
|
|
65566
|
+
}, null, 2);
|
|
65567
|
+
}
|
|
65568
|
+
if (!args.files_touched || args.files_touched.length === 0) {
|
|
65569
|
+
return JSON.stringify({
|
|
65570
|
+
success: true,
|
|
65571
|
+
data: {
|
|
65572
|
+
passed: true,
|
|
65573
|
+
skipped: true,
|
|
65574
|
+
reason: "no files_touched provided",
|
|
65575
|
+
summary: "No files to verify",
|
|
65576
|
+
steps: [],
|
|
65577
|
+
blockers: []
|
|
65578
|
+
}
|
|
65579
|
+
}, null, 2);
|
|
65580
|
+
}
|
|
65581
|
+
const result = await runVerificationGate(args.files_touched, false);
|
|
65582
|
+
return JSON.stringify({
|
|
65583
|
+
success: true,
|
|
65584
|
+
data: {
|
|
65585
|
+
passed: result.passed,
|
|
65586
|
+
skipped: false,
|
|
65587
|
+
summary: result.summary,
|
|
65588
|
+
steps: result.steps.map((s) => ({
|
|
65589
|
+
name: s.name,
|
|
65590
|
+
command: s.command,
|
|
65591
|
+
passed: s.passed,
|
|
65592
|
+
exitCode: s.exitCode,
|
|
65593
|
+
skipped: s.skipped,
|
|
65594
|
+
skipReason: s.skipReason,
|
|
65595
|
+
error: s.error?.slice(0, 200),
|
|
65596
|
+
output: s.output?.slice(0, 200)
|
|
65597
|
+
})),
|
|
65598
|
+
blockers: result.blockers
|
|
65599
|
+
}
|
|
65600
|
+
}, null, 2);
|
|
65601
|
+
} catch (error45) {
|
|
65602
|
+
return JSON.stringify({
|
|
65603
|
+
success: false,
|
|
65604
|
+
error: `Verification failed: ${error45 instanceof Error ? error45.message : String(error45)}`
|
|
65605
|
+
}, null, 2);
|
|
65606
|
+
}
|
|
65607
|
+
}
|
|
65608
|
+
});
|
|
65609
|
+
var verificationTools = {
|
|
65610
|
+
swarm_verify
|
|
65611
|
+
};
|
|
65612
|
+
|
|
65613
|
+
// src/swarm-orchestrate.ts
|
|
65431
65614
|
function generateWorkerHandoff(params) {
|
|
65432
65615
|
const handoff = {
|
|
65433
65616
|
contract: {
|
|
@@ -65569,114 +65752,6 @@ ${progress.blockers.map((b) => `- ${b}`).join(`
|
|
|
65569
65752
|
|
|
65570
65753
|
`);
|
|
65571
65754
|
}
|
|
65572
|
-
async function runTypecheckVerification() {
|
|
65573
|
-
const step = {
|
|
65574
|
-
name: "typecheck",
|
|
65575
|
-
command: "tsc --noEmit",
|
|
65576
|
-
passed: false,
|
|
65577
|
-
exitCode: -1
|
|
65578
|
-
};
|
|
65579
|
-
try {
|
|
65580
|
-
const tsconfigExists = await Bun.file("tsconfig.json").exists();
|
|
65581
|
-
if (!tsconfigExists) {
|
|
65582
|
-
step.skipped = true;
|
|
65583
|
-
step.skipReason = "No tsconfig.json found";
|
|
65584
|
-
step.passed = true;
|
|
65585
|
-
return step;
|
|
65586
|
-
}
|
|
65587
|
-
const result = await Bun.$`tsc --noEmit`.quiet().nothrow();
|
|
65588
|
-
step.exitCode = result.exitCode;
|
|
65589
|
-
step.passed = result.exitCode === 0;
|
|
65590
|
-
if (!step.passed) {
|
|
65591
|
-
step.error = result.stderr.toString().slice(0, 1000);
|
|
65592
|
-
step.output = result.stdout.toString().slice(0, 1000);
|
|
65593
|
-
}
|
|
65594
|
-
} catch (error45) {
|
|
65595
|
-
step.skipped = true;
|
|
65596
|
-
step.skipReason = `tsc not available: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
65597
|
-
step.passed = true;
|
|
65598
|
-
}
|
|
65599
|
-
return step;
|
|
65600
|
-
}
|
|
65601
|
-
async function runTestVerification(filesTouched) {
|
|
65602
|
-
const step = {
|
|
65603
|
-
name: "tests",
|
|
65604
|
-
command: "bun test <related-files>",
|
|
65605
|
-
passed: false,
|
|
65606
|
-
exitCode: -1
|
|
65607
|
-
};
|
|
65608
|
-
if (filesTouched.length === 0) {
|
|
65609
|
-
step.skipped = true;
|
|
65610
|
-
step.skipReason = "No files touched";
|
|
65611
|
-
step.passed = true;
|
|
65612
|
-
return step;
|
|
65613
|
-
}
|
|
65614
|
-
const testPatterns = [];
|
|
65615
|
-
for (const file2 of filesTouched) {
|
|
65616
|
-
if (file2.includes(".test.") || file2.includes(".spec.")) {
|
|
65617
|
-
testPatterns.push(file2);
|
|
65618
|
-
continue;
|
|
65619
|
-
}
|
|
65620
|
-
const baseName = file2.replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
65621
|
-
testPatterns.push(`${baseName}.test.ts`);
|
|
65622
|
-
testPatterns.push(`${baseName}.test.tsx`);
|
|
65623
|
-
testPatterns.push(`${baseName}.spec.ts`);
|
|
65624
|
-
}
|
|
65625
|
-
const existingTests = [];
|
|
65626
|
-
for (const pattern of testPatterns) {
|
|
65627
|
-
try {
|
|
65628
|
-
const exists = await Bun.file(pattern).exists();
|
|
65629
|
-
if (exists) {
|
|
65630
|
-
existingTests.push(pattern);
|
|
65631
|
-
}
|
|
65632
|
-
} catch {}
|
|
65633
|
-
}
|
|
65634
|
-
if (existingTests.length === 0) {
|
|
65635
|
-
step.skipped = true;
|
|
65636
|
-
step.skipReason = "No related test files found";
|
|
65637
|
-
step.passed = true;
|
|
65638
|
-
return step;
|
|
65639
|
-
}
|
|
65640
|
-
try {
|
|
65641
|
-
step.command = `bun test ${existingTests.join(" ")}`;
|
|
65642
|
-
const result = await Bun.$`bun test ${existingTests}`.quiet().nothrow();
|
|
65643
|
-
step.exitCode = result.exitCode;
|
|
65644
|
-
step.passed = result.exitCode === 0;
|
|
65645
|
-
if (!step.passed) {
|
|
65646
|
-
step.error = result.stderr.toString().slice(0, 1000);
|
|
65647
|
-
step.output = result.stdout.toString().slice(0, 1000);
|
|
65648
|
-
}
|
|
65649
|
-
} catch (error45) {
|
|
65650
|
-
step.skipped = true;
|
|
65651
|
-
step.skipReason = `Test runner failed: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
65652
|
-
step.passed = true;
|
|
65653
|
-
}
|
|
65654
|
-
return step;
|
|
65655
|
-
}
|
|
65656
|
-
async function runVerificationGate(filesTouched, _skipUbs = false) {
|
|
65657
|
-
const steps = [];
|
|
65658
|
-
const blockers = [];
|
|
65659
|
-
const typecheckStep = await runTypecheckVerification();
|
|
65660
|
-
steps.push(typecheckStep);
|
|
65661
|
-
if (!typecheckStep.passed && !typecheckStep.skipped) {
|
|
65662
|
-
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.`);
|
|
65663
|
-
}
|
|
65664
|
-
const testStep = await runTestVerification(filesTouched);
|
|
65665
|
-
steps.push(testStep);
|
|
65666
|
-
if (!testStep.passed && !testStep.skipped) {
|
|
65667
|
-
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.`);
|
|
65668
|
-
}
|
|
65669
|
-
const passedCount = steps.filter((s) => s.passed).length;
|
|
65670
|
-
const skippedCount = steps.filter((s) => s.skipped).length;
|
|
65671
|
-
const failedCount = steps.filter((s) => !s.passed && !s.skipped).length;
|
|
65672
|
-
const summary = failedCount === 0 ? `Verification passed: ${passedCount} checks passed, ${skippedCount} skipped` : `Verification FAILED: ${failedCount} checks failed, ${passedCount} passed, ${skippedCount} skipped`;
|
|
65673
|
-
return {
|
|
65674
|
-
passed: failedCount === 0,
|
|
65675
|
-
steps,
|
|
65676
|
-
summary,
|
|
65677
|
-
blockers
|
|
65678
|
-
};
|
|
65679
|
-
}
|
|
65680
65755
|
function classifyFailure(error45) {
|
|
65681
65756
|
const msg = (typeof error45 === "string" ? error45 : error45.message).toLowerCase();
|
|
65682
65757
|
if (msg.includes("timeout"))
|
|
@@ -65938,15 +66013,15 @@ var swarm_progress = tool({
|
|
|
65938
66013
|
}
|
|
65939
66014
|
};
|
|
65940
66015
|
const checkpointData = JSON.stringify(checkpoint);
|
|
65941
|
-
const checkpointEvent =
|
|
66016
|
+
const checkpointEvent = createEvent4("swarm_checkpointed", {
|
|
65942
66017
|
project_key: args.project_key,
|
|
65943
66018
|
...checkpoint,
|
|
65944
66019
|
checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
|
|
65945
66020
|
trigger: "progress"
|
|
65946
66021
|
});
|
|
65947
|
-
await
|
|
66022
|
+
await appendEvent3(checkpointEvent, args.project_key);
|
|
65948
66023
|
const checkpointId = `ckpt-${Date.now()}-${args.bead_id}`;
|
|
65949
|
-
const createdEvent =
|
|
66024
|
+
const createdEvent = createEvent4("checkpoint_created", {
|
|
65950
66025
|
project_key: args.project_key,
|
|
65951
66026
|
epic_id: epicId,
|
|
65952
66027
|
bead_id: args.bead_id,
|
|
@@ -65956,7 +66031,7 @@ var swarm_progress = tool({
|
|
|
65956
66031
|
progress_percent: args.progress_percent,
|
|
65957
66032
|
files_snapshot: args.files_touched
|
|
65958
66033
|
});
|
|
65959
|
-
await
|
|
66034
|
+
await appendEvent3(createdEvent, args.project_key);
|
|
65960
66035
|
checkpointCreated = true;
|
|
65961
66036
|
} catch (error45) {
|
|
65962
66037
|
console.warn(`[swarm_progress] Auto-checkpoint failed at ${args.progress_percent}%:`, error45);
|
|
@@ -66259,7 +66334,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
66259
66334
|
const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
|
|
66260
66335
|
let outcomeEventId;
|
|
66261
66336
|
try {
|
|
66262
|
-
const event =
|
|
66337
|
+
const event = createEvent4("subtask_outcome", {
|
|
66263
66338
|
project_key: args.project_key,
|
|
66264
66339
|
epic_id: eventEpicId,
|
|
66265
66340
|
bead_id: args.bead_id,
|
|
@@ -66272,7 +66347,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
66272
66347
|
scope_violation: contractValidation ? !contractValidation.valid : undefined,
|
|
66273
66348
|
violation_files: contractValidation?.violations
|
|
66274
66349
|
});
|
|
66275
|
-
const savedEvent = await
|
|
66350
|
+
const savedEvent = await appendEvent3(event, args.project_key);
|
|
66276
66351
|
outcomeEventId = savedEvent.id;
|
|
66277
66352
|
} catch (error45) {
|
|
66278
66353
|
console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
|
|
@@ -66290,7 +66365,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
66290
66365
|
}
|
|
66291
66366
|
}
|
|
66292
66367
|
try {
|
|
66293
|
-
const workerCompletedEvent =
|
|
66368
|
+
const workerCompletedEvent = createEvent4("worker_completed", {
|
|
66294
66369
|
project_key: args.project_key,
|
|
66295
66370
|
epic_id: eventEpicId,
|
|
66296
66371
|
bead_id: args.bead_id,
|
|
@@ -66299,7 +66374,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
66299
66374
|
duration_ms: completionDurationMs,
|
|
66300
66375
|
files_touched: args.files_touched || []
|
|
66301
66376
|
});
|
|
66302
|
-
await
|
|
66377
|
+
await appendEvent3(workerCompletedEvent, args.project_key);
|
|
66303
66378
|
} catch (error45) {
|
|
66304
66379
|
console.warn("[swarm_complete] Failed to emit worker_completed event:", error45);
|
|
66305
66380
|
}
|
|
@@ -67023,7 +67098,7 @@ var swarm_checkpoint = tool({
|
|
|
67023
67098
|
}
|
|
67024
67099
|
};
|
|
67025
67100
|
const checkpointData = JSON.stringify(checkpoint);
|
|
67026
|
-
const event =
|
|
67101
|
+
const event = createEvent4("swarm_checkpointed", {
|
|
67027
67102
|
project_key: args.project_key,
|
|
67028
67103
|
epic_id: args.epic_id,
|
|
67029
67104
|
bead_id: args.bead_id,
|
|
@@ -67035,7 +67110,7 @@ var swarm_checkpoint = tool({
|
|
|
67035
67110
|
checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
|
|
67036
67111
|
trigger: args.error_context ? "error" : "manual"
|
|
67037
67112
|
});
|
|
67038
|
-
await
|
|
67113
|
+
await appendEvent3(event, args.project_key);
|
|
67039
67114
|
const now = Date.now();
|
|
67040
67115
|
return JSON.stringify({
|
|
67041
67116
|
success: true,
|
|
@@ -67093,13 +67168,13 @@ var swarm_recover = tool({
|
|
|
67093
67168
|
created_at: row.created_at,
|
|
67094
67169
|
updated_at: row.updated_at
|
|
67095
67170
|
};
|
|
67096
|
-
const event =
|
|
67171
|
+
const event = createEvent4("swarm_recovered", {
|
|
67097
67172
|
project_key: args.project_key,
|
|
67098
67173
|
epic_id: args.epic_id,
|
|
67099
67174
|
bead_id: context.bead_id,
|
|
67100
67175
|
recovered_from_checkpoint: context.recovery.last_checkpoint
|
|
67101
67176
|
});
|
|
67102
|
-
await
|
|
67177
|
+
await appendEvent3(event, args.project_key);
|
|
67103
67178
|
return JSON.stringify({
|
|
67104
67179
|
found: true,
|
|
67105
67180
|
context,
|
|
@@ -67520,6 +67595,27 @@ swarmmail_reserve(
|
|
|
67520
67595
|
|
|
67521
67596
|
**Workers reserve their own files.** This prevents edit conflicts with other agents.
|
|
67522
67597
|
|
|
67598
|
+
### ⚠️ CRITICAL: File Path Handling (Next.js/Special Characters)
|
|
67599
|
+
|
|
67600
|
+
**DO NOT escape brackets or parentheses in file paths!**
|
|
67601
|
+
|
|
67602
|
+
When working with Next.js App Router or any codebase with special characters in paths:
|
|
67603
|
+
|
|
67604
|
+
❌ **WRONG** (will fail):
|
|
67605
|
+
\`\`\`
|
|
67606
|
+
Read: app/\\(content\\)/events/\\[slug\\]/page.tsx
|
|
67607
|
+
Glob: src/**/\\[id\\]/**/*.ts
|
|
67608
|
+
\`\`\`
|
|
67609
|
+
|
|
67610
|
+
✅ **CORRECT** (use raw paths):
|
|
67611
|
+
\`\`\`
|
|
67612
|
+
Read: app/(content)/events/[slug]/page.tsx
|
|
67613
|
+
Glob: src/**/[id]/**/*.ts
|
|
67614
|
+
\`\`\`
|
|
67615
|
+
|
|
67616
|
+
**The Read and Glob tools handle special characters automatically.**
|
|
67617
|
+
Never add backslashes before \`[\`, \`]\`, \`(\`, or \`)\` in file paths.
|
|
67618
|
+
|
|
67523
67619
|
### Step 5: Do the Work (TDD MANDATORY)
|
|
67524
67620
|
|
|
67525
67621
|
**Follow RED → GREEN → REFACTOR. No exceptions.**
|
|
@@ -68282,9 +68378,9 @@ var swarm_spawn_subtask = tool({
|
|
|
68282
68378
|
}
|
|
68283
68379
|
if (args2.project_path) {
|
|
68284
68380
|
try {
|
|
68285
|
-
const { createEvent:
|
|
68381
|
+
const { createEvent: createEvent6, appendEvent: appendEvent5 } = await import("swarm-mail");
|
|
68286
68382
|
const spawnOrder = 0;
|
|
68287
|
-
const workerSpawnedEvent =
|
|
68383
|
+
const workerSpawnedEvent = createEvent6("worker_spawned", {
|
|
68288
68384
|
project_key: args2.project_path,
|
|
68289
68385
|
epic_id: args2.epic_id,
|
|
68290
68386
|
bead_id: args2.bead_id,
|
|
@@ -68294,7 +68390,7 @@ var swarm_spawn_subtask = tool({
|
|
|
68294
68390
|
spawn_order: spawnOrder,
|
|
68295
68391
|
is_parallel: false
|
|
68296
68392
|
});
|
|
68297
|
-
await
|
|
68393
|
+
await appendEvent5(workerSpawnedEvent, args2.project_path);
|
|
68298
68394
|
} catch (error45) {
|
|
68299
68395
|
console.warn("[swarm_spawn_subtask] Failed to emit WorkerSpawnedEvent:", error45);
|
|
68300
68396
|
}
|
|
@@ -68992,7 +69088,8 @@ var swarmTools = {
|
|
|
68992
69088
|
...promptTools,
|
|
68993
69089
|
...orchestrateTools,
|
|
68994
69090
|
...researchTools,
|
|
68995
|
-
...adversarialReviewTools
|
|
69091
|
+
...adversarialReviewTools,
|
|
69092
|
+
...verificationTools
|
|
68996
69093
|
};
|
|
68997
69094
|
|
|
68998
69095
|
// src/repo-crawl.ts
|
|
@@ -70035,36 +70132,35 @@ var mandateTools = {
|
|
|
70035
70132
|
// src/hivemind-tools.ts
|
|
70036
70133
|
init_dist();
|
|
70037
70134
|
init_esm();
|
|
70038
|
-
init_memory();
|
|
70039
|
-
init_memory();
|
|
70040
70135
|
import {
|
|
70041
70136
|
getSwarmMailLibSQL as getSwarmMailLibSQL6,
|
|
70042
|
-
createEvent as createEvent5,
|
|
70043
70137
|
SessionIndexer,
|
|
70044
70138
|
syncMemories as syncMemories2,
|
|
70045
70139
|
toSwarmDb as toSwarmDb2,
|
|
70046
70140
|
makeOllamaLive as makeOllamaLive2
|
|
70047
70141
|
} from "swarm-mail";
|
|
70142
|
+
init_memory();
|
|
70143
|
+
init_memory();
|
|
70048
70144
|
import * as os2 from "node:os";
|
|
70049
70145
|
import * as path3 from "node:path";
|
|
70050
70146
|
import { join as join12 } from "node:path";
|
|
70051
|
-
var
|
|
70147
|
+
var cachedAdapter = null;
|
|
70052
70148
|
var cachedIndexer = null;
|
|
70053
|
-
var
|
|
70149
|
+
var cachedProjectPath = null;
|
|
70054
70150
|
async function getMemoryAdapter2(projectPath) {
|
|
70055
70151
|
const path4 = projectPath || process.cwd();
|
|
70056
|
-
if (
|
|
70057
|
-
return
|
|
70152
|
+
if (cachedAdapter && cachedProjectPath === path4) {
|
|
70153
|
+
return cachedAdapter;
|
|
70058
70154
|
}
|
|
70059
70155
|
const swarmMail = await getSwarmMailLibSQL6(path4);
|
|
70060
70156
|
const dbAdapter = await swarmMail.getDatabase();
|
|
70061
|
-
|
|
70062
|
-
|
|
70063
|
-
return
|
|
70157
|
+
cachedAdapter = await createMemoryAdapter(dbAdapter);
|
|
70158
|
+
cachedProjectPath = path4;
|
|
70159
|
+
return cachedAdapter;
|
|
70064
70160
|
}
|
|
70065
70161
|
async function getSessionIndexer(projectPath) {
|
|
70066
70162
|
const path4 = projectPath || process.cwd();
|
|
70067
|
-
if (cachedIndexer &&
|
|
70163
|
+
if (cachedIndexer && cachedProjectPath === path4) {
|
|
70068
70164
|
return cachedIndexer;
|
|
70069
70165
|
}
|
|
70070
70166
|
const swarmMail = await getSwarmMailLibSQL6(path4);
|
|
@@ -70075,20 +70171,13 @@ async function getSessionIndexer(projectPath) {
|
|
|
70075
70171
|
ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
|
|
70076
70172
|
});
|
|
70077
70173
|
cachedIndexer = new SessionIndexer(db, ollamaLayer);
|
|
70078
|
-
|
|
70174
|
+
cachedProjectPath = path4;
|
|
70079
70175
|
return cachedIndexer;
|
|
70080
70176
|
}
|
|
70081
70177
|
var getHivemindAdapter = getMemoryAdapter2;
|
|
70082
70178
|
async function emitEvent(eventType, data) {
|
|
70083
|
-
|
|
70084
|
-
|
|
70085
|
-
const swarmMail = await getSwarmMailLibSQL6(projectPath);
|
|
70086
|
-
const event = createEvent5(eventType, {
|
|
70087
|
-
project_key: projectPath,
|
|
70088
|
-
...data
|
|
70089
|
-
});
|
|
70090
|
-
await swarmMail.appendEvent(event);
|
|
70091
|
-
} catch {}
|
|
70179
|
+
const projectPath = cachedProjectPath || process.cwd();
|
|
70180
|
+
await safeEmitEvent(eventType, data, "hivemind", projectPath);
|
|
70092
70181
|
}
|
|
70093
70182
|
var AGENT_DIRECTORIES = [
|
|
70094
70183
|
path3.join(os2.homedir(), ".config", "swarm-tools", "sessions"),
|
|
@@ -70131,6 +70220,15 @@ var hivemind_find = tool({
|
|
|
70131
70220
|
fts: tool.schema.boolean().optional().describe("Use full-text search instead of vector search (default: false)")
|
|
70132
70221
|
},
|
|
70133
70222
|
async execute(args2, ctx) {
|
|
70223
|
+
if (!args2.query || typeof args2.query !== "string" || args2.query.trim() === "") {
|
|
70224
|
+
return JSON.stringify({
|
|
70225
|
+
success: false,
|
|
70226
|
+
error: {
|
|
70227
|
+
code: "VALIDATION_ERROR",
|
|
70228
|
+
message: "query parameter is required and must be a non-empty string"
|
|
70229
|
+
}
|
|
70230
|
+
});
|
|
70231
|
+
}
|
|
70134
70232
|
const startTime = Date.now();
|
|
70135
70233
|
const adapter = await getMemoryAdapter2();
|
|
70136
70234
|
const result = await adapter.find(args2);
|
|
@@ -70251,7 +70349,7 @@ var hivemind_sync = tool({
|
|
|
70251
70349
|
args: {},
|
|
70252
70350
|
async execute(args2, ctx) {
|
|
70253
70351
|
try {
|
|
70254
|
-
const projectPath =
|
|
70352
|
+
const projectPath = cachedProjectPath || process.cwd();
|
|
70255
70353
|
const swarmMail = await getSwarmMailLibSQL6(projectPath);
|
|
70256
70354
|
const dbAdapter = await swarmMail.getDatabase();
|
|
70257
70355
|
const hiveDir = join12(projectPath, ".hive");
|
|
@@ -72074,13 +72172,17 @@ var AGENT_DIRECTORIES2 = [
|
|
|
72074
72172
|
path4.join(os3.homedir(), ".local", "share", "Claude"),
|
|
72075
72173
|
path4.join(os3.homedir(), ".aider")
|
|
72076
72174
|
];
|
|
72175
|
+
var sessionIndexerCache = new AdapterCache;
|
|
72077
72176
|
async function getSessionIndexer2() {
|
|
72078
|
-
const
|
|
72079
|
-
|
|
72080
|
-
|
|
72081
|
-
|
|
72177
|
+
const globalKey = "global-session-indexer";
|
|
72178
|
+
return sessionIndexerCache.get(globalKey, async () => {
|
|
72179
|
+
const db = await getDb();
|
|
72180
|
+
const ollamaLayer = makeOllamaLive3({
|
|
72181
|
+
ollamaHost: process.env.OLLAMA_HOST || "http://localhost:11434",
|
|
72182
|
+
ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
|
|
72183
|
+
});
|
|
72184
|
+
return new SessionIndexer2(db, ollamaLayer);
|
|
72082
72185
|
});
|
|
72083
|
-
return new SessionIndexer2(db, ollamaLayer);
|
|
72084
72186
|
}
|
|
72085
72187
|
async function emitEvent2(eventType, data) {
|
|
72086
72188
|
try {
|