opencode-swarm-plugin 0.59.1 → 0.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/bin/commands/doctor.test.ts +622 -0
- package/bin/commands/doctor.ts +658 -0
- package/bin/commands/status.test.ts +506 -0
- package/bin/commands/status.ts +520 -0
- package/bin/commands/tree.ts +39 -3
- package/bin/swarm.ts +19 -3
- package/claude-plugin/.claude-plugin/plugin.json +1 -1
- package/claude-plugin/commands/swarm.md +125 -2
- package/claude-plugin/dist/index.js +669 -308
- package/claude-plugin/dist/schemas/cell.d.ts +2 -0
- package/claude-plugin/dist/schemas/cell.d.ts.map +1 -1
- 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/dist/utils/git-commit-info.d.ts +10 -0
- package/claude-plugin/dist/utils/git-commit-info.d.ts.map +1 -0
- package/claude-plugin/dist/utils/tree-renderer.d.ts +69 -13
- package/claude-plugin/dist/utils/tree-renderer.d.ts.map +1 -1
- package/dist/bin/swarm.js +2664 -980
- package/dist/cass-tools.d.ts.map +1 -1
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/hive.d.ts +8 -0
- package/dist/hive.d.ts.map +1 -1
- package/dist/hive.js +81 -101
- package/dist/hivemind-tools.d.ts.map +1 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +458 -311
- package/dist/marketplace/index.js +669 -308
- package/dist/memory-tools.d.ts.map +1 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/plugin.js +456 -308
- package/dist/replay-tools.d.ts +5 -1
- package/dist/replay-tools.d.ts.map +1 -1
- package/dist/schemas/cell.d.ts +2 -0
- package/dist/schemas/cell.d.ts.map +1 -1
- package/dist/skills.d.ts +4 -0
- package/dist/skills.d.ts.map +1 -1
- package/dist/storage.d.ts +7 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/swarm-mail.d.ts +2 -2
- package/dist/swarm-mail.d.ts.map +1 -1
- package/dist/swarm-orchestrate.d.ts +12 -0
- 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 +408 -274
- package/dist/swarm-verify.d.ts +100 -0
- package/dist/swarm-verify.d.ts.map +1 -0
- package/dist/swarm.d.ts +19 -1
- package/dist/swarm.d.ts.map +1 -1
- package/dist/test-utils/msw-server.d.ts +21 -0
- package/dist/test-utils/msw-server.d.ts.map +1 -0
- 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/dist/utils/git-commit-info.d.ts +10 -0
- package/dist/utils/git-commit-info.d.ts.map +1 -0
- package/dist/utils/tree-renderer.d.ts +69 -13
- package/dist/utils/tree-renderer.d.ts.map +1 -1
- package/package.json +3 -2
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,
|
|
@@ -27757,7 +27757,8 @@ Scripts run in the skill's directory with the project directory as an argument.`
|
|
|
27757
27757
|
args: {
|
|
27758
27758
|
skill: tool.schema.string().describe("Name of the skill"),
|
|
27759
27759
|
script: tool.schema.string().describe("Name of the script file to execute"),
|
|
27760
|
-
args: tool.schema.array(tool.schema.string()).optional().describe("Additional arguments to pass to the script")
|
|
27760
|
+
args: tool.schema.array(tool.schema.string()).optional().describe("Additional arguments to pass to the script"),
|
|
27761
|
+
timeout_ms: tool.schema.number().optional().describe("Timeout in milliseconds (default: 60000)")
|
|
27761
27762
|
},
|
|
27762
27763
|
async execute(args, ctx) {
|
|
27763
27764
|
console.warn("[DEPRECATED] skills_execute is deprecated. OpenCode now provides native skills support. This tool will be removed in a future version.");
|
|
@@ -27770,7 +27771,7 @@ Scripts run in the skill's directory with the project directory as an argument.`
|
|
|
27770
27771
|
}
|
|
27771
27772
|
const scriptPath = join6(skill.directory, "scripts", args.script);
|
|
27772
27773
|
const scriptArgs = args.args || [];
|
|
27773
|
-
const TIMEOUT_MS = 60000;
|
|
27774
|
+
const TIMEOUT_MS = args.timeout_ms ?? 60000;
|
|
27774
27775
|
const proc = Bun.spawn([scriptPath, skillsProjectDirectory, ...scriptArgs], {
|
|
27775
27776
|
cwd: skill.directory,
|
|
27776
27777
|
stdout: "pipe",
|
|
@@ -28673,6 +28674,7 @@ __export(exports_storage, {
|
|
|
28673
28674
|
resetStorage: () => resetStorage,
|
|
28674
28675
|
resetSessionStats: () => resetSessionStats,
|
|
28675
28676
|
resetCommandCache: () => resetCommandCache,
|
|
28677
|
+
resetAvailabilityCache: () => resetAvailabilityCache,
|
|
28676
28678
|
isSemanticMemoryAvailable: () => isSemanticMemoryAvailable,
|
|
28677
28679
|
getTestCollectionName: () => getTestCollectionName,
|
|
28678
28680
|
getStorage: () => getStorage,
|
|
@@ -29023,12 +29025,25 @@ function createStorage(config2 = {}) {
|
|
|
29023
29025
|
}
|
|
29024
29026
|
}
|
|
29025
29027
|
async function isSemanticMemoryAvailable() {
|
|
29026
|
-
|
|
29027
|
-
|
|
29028
|
-
|
|
29029
|
-
|
|
29030
|
-
|
|
29031
|
-
|
|
29028
|
+
if (_availabilityCache !== null)
|
|
29029
|
+
return _availabilityCache;
|
|
29030
|
+
if (_availabilityPromise)
|
|
29031
|
+
return _availabilityPromise;
|
|
29032
|
+
_availabilityPromise = (async () => {
|
|
29033
|
+
try {
|
|
29034
|
+
const result = await execSemanticMemory(["stats"]);
|
|
29035
|
+
_availabilityCache = result.exitCode === 0;
|
|
29036
|
+
} catch {
|
|
29037
|
+
_availabilityCache = false;
|
|
29038
|
+
}
|
|
29039
|
+
_availabilityPromise = null;
|
|
29040
|
+
return _availabilityCache;
|
|
29041
|
+
})();
|
|
29042
|
+
return _availabilityPromise;
|
|
29043
|
+
}
|
|
29044
|
+
function resetAvailabilityCache() {
|
|
29045
|
+
_availabilityCache = null;
|
|
29046
|
+
_availabilityPromise = null;
|
|
29032
29047
|
}
|
|
29033
29048
|
async function getResolvedCommand() {
|
|
29034
29049
|
return resolveSemanticMemoryCommand();
|
|
@@ -29064,7 +29079,7 @@ async function resetStorage() {
|
|
|
29064
29079
|
}
|
|
29065
29080
|
globalStoragePromise = null;
|
|
29066
29081
|
}
|
|
29067
|
-
var cachedCommand = null, DEFAULT_STORAGE_CONFIG, sessionStats, globalStorage = null, globalStoragePromise = null;
|
|
29082
|
+
var cachedCommand = null, DEFAULT_STORAGE_CONFIG, sessionStats, _availabilityCache = null, _availabilityPromise = null, globalStorage = null, globalStoragePromise = null;
|
|
29068
29083
|
var init_storage = __esm(() => {
|
|
29069
29084
|
init_learning();
|
|
29070
29085
|
init_anti_patterns();
|
|
@@ -29078,6 +29093,27 @@ var init_storage = __esm(() => {
|
|
|
29078
29093
|
};
|
|
29079
29094
|
});
|
|
29080
29095
|
|
|
29096
|
+
// src/utils/adapter-cache.ts
|
|
29097
|
+
class AdapterCache {
|
|
29098
|
+
cached = null;
|
|
29099
|
+
cachedPath = null;
|
|
29100
|
+
async get(projectPath, factory) {
|
|
29101
|
+
if (this.cached && this.cachedPath === projectPath) {
|
|
29102
|
+
return this.cached;
|
|
29103
|
+
}
|
|
29104
|
+
this.cached = await factory(projectPath);
|
|
29105
|
+
this.cachedPath = projectPath;
|
|
29106
|
+
return this.cached;
|
|
29107
|
+
}
|
|
29108
|
+
clear() {
|
|
29109
|
+
this.cached = null;
|
|
29110
|
+
this.cachedPath = null;
|
|
29111
|
+
}
|
|
29112
|
+
getCachedPath() {
|
|
29113
|
+
return this.cachedPath;
|
|
29114
|
+
}
|
|
29115
|
+
}
|
|
29116
|
+
|
|
29081
29117
|
// ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Function.js
|
|
29082
29118
|
function pipe2(a, ab, bc, cd, de, ef, fg, gh, hi) {
|
|
29083
29119
|
switch (arguments.length) {
|
|
@@ -46404,6 +46440,9 @@ Linked to ${result.links.length} related memor${result.links.length === 1 ? "y"
|
|
|
46404
46440
|
};
|
|
46405
46441
|
},
|
|
46406
46442
|
async find(args2) {
|
|
46443
|
+
if (!args2.query || typeof args2.query !== "string") {
|
|
46444
|
+
throw new Error("query is required for find operation");
|
|
46445
|
+
}
|
|
46407
46446
|
const limit = args2.limit ?? 10;
|
|
46408
46447
|
let results;
|
|
46409
46448
|
let usedFallback = false;
|
|
@@ -46522,22 +46561,20 @@ var init_memory = __esm(() => {
|
|
|
46522
46561
|
});
|
|
46523
46562
|
|
|
46524
46563
|
// src/memory-tools.ts
|
|
46525
|
-
import { getSwarmMailLibSQL as getSwarmMailLibSQL5, createEvent as
|
|
46564
|
+
import { getSwarmMailLibSQL as getSwarmMailLibSQL5, createEvent as createEvent5, appendEvent as appendEvent4 } from "swarm-mail";
|
|
46526
46565
|
async function getMemoryAdapter(projectPath) {
|
|
46527
46566
|
const path3 = projectPath || process.cwd();
|
|
46528
|
-
|
|
46529
|
-
|
|
46530
|
-
|
|
46531
|
-
|
|
46532
|
-
|
|
46533
|
-
cachedAdapter = await createMemoryAdapter(dbAdapter);
|
|
46534
|
-
cachedProjectPath = path3;
|
|
46535
|
-
return cachedAdapter;
|
|
46567
|
+
return memoryAdapterCache.get(path3, async (projectPath2) => {
|
|
46568
|
+
const swarmMail = await getSwarmMailLibSQL5(projectPath2);
|
|
46569
|
+
const dbAdapter = await swarmMail.getDatabase();
|
|
46570
|
+
return await createMemoryAdapter(dbAdapter);
|
|
46571
|
+
});
|
|
46536
46572
|
}
|
|
46537
|
-
var
|
|
46573
|
+
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
46574
|
var init_memory_tools = __esm(() => {
|
|
46539
46575
|
init_dist();
|
|
46540
46576
|
init_memory();
|
|
46577
|
+
memoryAdapterCache = new AdapterCache;
|
|
46541
46578
|
semantic_memory_store = tool({
|
|
46542
46579
|
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
46580
|
args: {
|
|
@@ -46554,9 +46591,9 @@ var init_memory_tools = __esm(() => {
|
|
|
46554
46591
|
const adapter = await getMemoryAdapter();
|
|
46555
46592
|
const result = await adapter.store(args2);
|
|
46556
46593
|
try {
|
|
46557
|
-
const projectKey =
|
|
46594
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46558
46595
|
const tags = args2.tags ? args2.tags.split(",").map((t) => t.trim()) : [];
|
|
46559
|
-
const event =
|
|
46596
|
+
const event = createEvent5("memory_stored", {
|
|
46560
46597
|
project_key: projectKey,
|
|
46561
46598
|
memory_id: result.id,
|
|
46562
46599
|
content_preview: args2.information.slice(0, 100),
|
|
@@ -46564,7 +46601,7 @@ var init_memory_tools = __esm(() => {
|
|
|
46564
46601
|
auto_tagged: args2.autoTag,
|
|
46565
46602
|
collection: args2.collection
|
|
46566
46603
|
});
|
|
46567
|
-
await
|
|
46604
|
+
await appendEvent4(event, projectKey);
|
|
46568
46605
|
} catch (error45) {
|
|
46569
46606
|
console.warn("[semantic_memory_store] Failed to emit memory_stored event:", error45);
|
|
46570
46607
|
}
|
|
@@ -46586,9 +46623,9 @@ var init_memory_tools = __esm(() => {
|
|
|
46586
46623
|
const result = await adapter.find(args2);
|
|
46587
46624
|
const duration3 = Date.now() - startTime;
|
|
46588
46625
|
try {
|
|
46589
|
-
const projectKey =
|
|
46626
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46590
46627
|
const topScore = result.results.length > 0 ? result.results[0].score : undefined;
|
|
46591
|
-
const event =
|
|
46628
|
+
const event = createEvent5("memory_found", {
|
|
46592
46629
|
project_key: projectKey,
|
|
46593
46630
|
query: args2.query,
|
|
46594
46631
|
result_count: result.results.length,
|
|
@@ -46596,7 +46633,7 @@ var init_memory_tools = __esm(() => {
|
|
|
46596
46633
|
search_duration_ms: duration3,
|
|
46597
46634
|
used_fts: args2.fts
|
|
46598
46635
|
});
|
|
46599
|
-
await
|
|
46636
|
+
await appendEvent4(event, projectKey);
|
|
46600
46637
|
} catch (error45) {
|
|
46601
46638
|
console.warn("[semantic_memory_find] Failed to emit memory_found event:", error45);
|
|
46602
46639
|
}
|
|
@@ -46624,12 +46661,12 @@ var init_memory_tools = __esm(() => {
|
|
|
46624
46661
|
const result = await adapter.remove(args2);
|
|
46625
46662
|
if (result.success) {
|
|
46626
46663
|
try {
|
|
46627
|
-
const projectKey =
|
|
46628
|
-
const event =
|
|
46664
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46665
|
+
const event = createEvent5("memory_deleted", {
|
|
46629
46666
|
project_key: projectKey,
|
|
46630
46667
|
memory_id: args2.id
|
|
46631
46668
|
});
|
|
46632
|
-
await
|
|
46669
|
+
await appendEvent4(event, projectKey);
|
|
46633
46670
|
} catch (error45) {
|
|
46634
46671
|
console.warn("[semantic_memory_remove] Failed to emit memory_deleted event:", error45);
|
|
46635
46672
|
}
|
|
@@ -46647,13 +46684,13 @@ var init_memory_tools = __esm(() => {
|
|
|
46647
46684
|
const result = await adapter.validate(args2);
|
|
46648
46685
|
if (result.success) {
|
|
46649
46686
|
try {
|
|
46650
|
-
const projectKey =
|
|
46651
|
-
const event =
|
|
46687
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46688
|
+
const event = createEvent5("memory_validated", {
|
|
46652
46689
|
project_key: projectKey,
|
|
46653
46690
|
memory_id: args2.id,
|
|
46654
46691
|
decay_reset: true
|
|
46655
46692
|
});
|
|
46656
|
-
await
|
|
46693
|
+
await appendEvent4(event, projectKey);
|
|
46657
46694
|
} catch (error45) {
|
|
46658
46695
|
console.warn("[semantic_memory_validate] Failed to emit memory_validated event:", error45);
|
|
46659
46696
|
}
|
|
@@ -46706,14 +46743,14 @@ var init_memory_tools = __esm(() => {
|
|
|
46706
46743
|
const adapter = await getMemoryAdapter();
|
|
46707
46744
|
const result = await adapter.upsert(args2);
|
|
46708
46745
|
try {
|
|
46709
|
-
const projectKey =
|
|
46710
|
-
const event =
|
|
46746
|
+
const projectKey = memoryAdapterCache.getCachedPath() || process.cwd();
|
|
46747
|
+
const event = createEvent5("memory_updated", {
|
|
46711
46748
|
project_key: projectKey,
|
|
46712
46749
|
memory_id: result.memoryId || "unknown",
|
|
46713
46750
|
operation: result.operation,
|
|
46714
46751
|
reason: result.reason
|
|
46715
46752
|
});
|
|
46716
|
-
await
|
|
46753
|
+
await appendEvent4(event, projectKey);
|
|
46717
46754
|
} catch (error45) {
|
|
46718
46755
|
console.warn("[semantic_memory_upsert] Failed to emit memory_updated event:", error45);
|
|
46719
46756
|
}
|
|
@@ -58423,7 +58460,8 @@ var CellUpdateArgsSchema = exports_external.object({
|
|
|
58423
58460
|
});
|
|
58424
58461
|
var CellCloseArgsSchema = exports_external.object({
|
|
58425
58462
|
id: exports_external.string(),
|
|
58426
|
-
reason: exports_external.string().min(1, "Reason required")
|
|
58463
|
+
reason: exports_external.string().min(1, "Reason required"),
|
|
58464
|
+
result: exports_external.string().optional()
|
|
58427
58465
|
});
|
|
58428
58466
|
var CellQueryArgsSchema = exports_external.object({
|
|
58429
58467
|
status: CellStatusSchema.optional(),
|
|
@@ -58929,7 +58967,24 @@ var CellEventSchema = exports_external.discriminatedUnion("type", [
|
|
|
58929
58967
|
CellCompactedEventSchema
|
|
58930
58968
|
]);
|
|
58931
58969
|
// src/hive.ts
|
|
58970
|
+
import { createEvent as createEvent2, appendEvent as appendEvent2 } from "swarm-mail";
|
|
58971
|
+
|
|
58972
|
+
// src/utils/event-utils.ts
|
|
58932
58973
|
import { createEvent, appendEvent } from "swarm-mail";
|
|
58974
|
+
async function safeEmitEvent(eventType, data, toolName, projectPath) {
|
|
58975
|
+
try {
|
|
58976
|
+
const effectiveProjectPath = projectPath || process.cwd();
|
|
58977
|
+
const event = createEvent(eventType, {
|
|
58978
|
+
project_key: effectiveProjectPath,
|
|
58979
|
+
...data
|
|
58980
|
+
});
|
|
58981
|
+
await appendEvent(event, effectiveProjectPath);
|
|
58982
|
+
} catch (error45) {
|
|
58983
|
+
console.warn(`[${toolName}] Failed to emit ${eventType} event:`, error45);
|
|
58984
|
+
}
|
|
58985
|
+
}
|
|
58986
|
+
|
|
58987
|
+
// src/hive.ts
|
|
58933
58988
|
var hiveWorkingDirectory = null;
|
|
58934
58989
|
function setHiveWorkingDirectory(directory) {
|
|
58935
58990
|
hiveWorkingDirectory = directory;
|
|
@@ -59087,20 +59142,14 @@ var hive_create = tool({
|
|
|
59087
59142
|
parent_id: validated.parent_id
|
|
59088
59143
|
});
|
|
59089
59144
|
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
|
-
}
|
|
59145
|
+
await safeEmitEvent("cell_created", {
|
|
59146
|
+
cell_id: cell.id,
|
|
59147
|
+
title: validated.title,
|
|
59148
|
+
description: validated.description,
|
|
59149
|
+
issue_type: validated.type || "task",
|
|
59150
|
+
priority: validated.priority ?? 2,
|
|
59151
|
+
parent_id: validated.parent_id
|
|
59152
|
+
}, "hive_create", projectKey);
|
|
59104
59153
|
const formatted = formatCellForOutput(cell);
|
|
59105
59154
|
return JSON.stringify(formatted, null, 2);
|
|
59106
59155
|
} catch (error45) {
|
|
@@ -59182,53 +59231,35 @@ var hive_create_epic = tool({
|
|
|
59182
59231
|
subtasks: created.slice(1).map((c) => formatCellForOutput(c))
|
|
59183
59232
|
};
|
|
59184
59233
|
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
|
-
}
|
|
59234
|
+
await safeEmitEvent("epic_created", {
|
|
59235
|
+
epic_id: epic.id,
|
|
59236
|
+
title: validated.epic_title,
|
|
59237
|
+
description: validated.epic_description,
|
|
59238
|
+
subtask_count: validated.subtasks.length,
|
|
59239
|
+
subtask_ids: created.slice(1).map((c) => c.id)
|
|
59240
|
+
}, "hive_create_epic", effectiveProjectKey);
|
|
59241
|
+
await safeEmitEvent("decomposition_generated", {
|
|
59242
|
+
epic_id: epic.id,
|
|
59243
|
+
task: args.task || validated.epic_title,
|
|
59244
|
+
context: validated.epic_description,
|
|
59245
|
+
strategy: args.strategy || "feature-based",
|
|
59246
|
+
epic_title: validated.epic_title,
|
|
59247
|
+
subtasks: validated.subtasks.map((st) => ({
|
|
59248
|
+
title: st.title,
|
|
59249
|
+
files: st.files || [],
|
|
59250
|
+
priority: st.priority
|
|
59251
|
+
})),
|
|
59252
|
+
recovery_context: args.recovery_context
|
|
59253
|
+
}, "hive_create_epic", effectiveProjectKey);
|
|
59254
|
+
const totalFiles = validated.subtasks.reduce((count, st) => count + (st.files?.length || 0), 0);
|
|
59255
|
+
await safeEmitEvent("swarm_started", {
|
|
59256
|
+
epic_id: epic.id,
|
|
59257
|
+
epic_title: validated.epic_title,
|
|
59258
|
+
strategy: args.strategy || "feature-based",
|
|
59259
|
+
subtask_count: validated.subtasks.length,
|
|
59260
|
+
total_files: totalFiles,
|
|
59261
|
+
coordinator_agent: "coordinator"
|
|
59262
|
+
}, "hive_create_epic", effectiveProjectKey);
|
|
59232
59263
|
try {
|
|
59233
59264
|
const { captureCoordinatorEvent: captureCoordinatorEvent2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
|
|
59234
59265
|
const filesPerSubtask = {};
|
|
@@ -59359,23 +59390,17 @@ var hive_update = tool({
|
|
|
59359
59390
|
cell = existingCell;
|
|
59360
59391
|
}
|
|
59361
59392
|
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
|
-
}
|
|
59393
|
+
const fieldsChanged = [];
|
|
59394
|
+
if (validated.status)
|
|
59395
|
+
fieldsChanged.push("status");
|
|
59396
|
+
if (validated.description !== undefined)
|
|
59397
|
+
fieldsChanged.push("description");
|
|
59398
|
+
if (validated.priority !== undefined)
|
|
59399
|
+
fieldsChanged.push("priority");
|
|
59400
|
+
await safeEmitEvent("cell_updated", {
|
|
59401
|
+
cell_id: cellId,
|
|
59402
|
+
fields_changed: fieldsChanged
|
|
59403
|
+
}, "hive_update", projectKey);
|
|
59379
59404
|
const formatted = formatCellForOutput(cell);
|
|
59380
59405
|
return JSON.stringify(formatted, null, 2);
|
|
59381
59406
|
} catch (error45) {
|
|
@@ -59394,7 +59419,8 @@ var hive_close = tool({
|
|
|
59394
59419
|
description: "Close a cell with reason",
|
|
59395
59420
|
args: {
|
|
59396
59421
|
id: tool.schema.string().describe("Cell ID or partial hash"),
|
|
59397
|
-
reason: tool.schema.string().describe("Completion reason")
|
|
59422
|
+
reason: tool.schema.string().describe("Completion reason"),
|
|
59423
|
+
result: tool.schema.string().optional().describe("Implementation summary - what was actually done (like a PR description)")
|
|
59398
59424
|
},
|
|
59399
59425
|
async execute(args, ctx) {
|
|
59400
59426
|
const validated = CellCloseArgsSchema.parse(args);
|
|
@@ -59404,11 +59430,10 @@ var hive_close = tool({
|
|
|
59404
59430
|
const cellId = await resolvePartialId(adapter, projectKey, validated.id) || validated.id;
|
|
59405
59431
|
const cellBeforeClose = await adapter.getCell(projectKey, cellId);
|
|
59406
59432
|
const isEpic = cellBeforeClose?.type === "epic";
|
|
59407
|
-
const cell = await adapter.closeCell(projectKey, cellId, validated.reason);
|
|
59433
|
+
const cell = await adapter.closeCell(projectKey, cellId, validated.reason, validated.result ? { result: validated.result } : undefined);
|
|
59408
59434
|
await adapter.markDirty(projectKey, cellId);
|
|
59409
59435
|
if (isEpic && cellBeforeClose) {
|
|
59410
59436
|
try {
|
|
59411
|
-
const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
|
|
59412
59437
|
const subtasks = await adapter.queryCells(projectKey, { parent_id: cellId });
|
|
59413
59438
|
const completedSubtasks = subtasks.filter((st) => st.status === "closed");
|
|
59414
59439
|
const failedSubtasks = subtasks.filter((st) => st.status === "blocked");
|
|
@@ -59446,8 +59471,7 @@ var hive_close = tool({
|
|
|
59446
59471
|
} catch (error45) {
|
|
59447
59472
|
console.warn("[hive_close] Failed to calculate duration:", error45);
|
|
59448
59473
|
}
|
|
59449
|
-
|
|
59450
|
-
project_key: projectKey,
|
|
59474
|
+
await safeEmitEvent("swarm_completed", {
|
|
59451
59475
|
epic_id: cellId,
|
|
59452
59476
|
epic_title: cellBeforeClose.title,
|
|
59453
59477
|
success: failedSubtasks.length === 0,
|
|
@@ -59455,8 +59479,7 @@ var hive_close = tool({
|
|
|
59455
59479
|
subtasks_completed: completedSubtasks.length,
|
|
59456
59480
|
subtasks_failed: failedSubtasks.length,
|
|
59457
59481
|
total_files_touched: totalFilesTouched
|
|
59458
|
-
});
|
|
59459
|
-
await appendEvent2(swarmCompletedEvent, projectKey);
|
|
59482
|
+
}, "hive_close", projectKey);
|
|
59460
59483
|
try {
|
|
59461
59484
|
const { runPostSwarmValidation: runPostSwarmValidation2 } = await Promise.resolve().then(() => (init_swarm_validation(), exports_swarm_validation));
|
|
59462
59485
|
const { readEvents } = await import("swarm-mail");
|
|
@@ -59492,16 +59515,10 @@ var hive_close = tool({
|
|
|
59492
59515
|
console.warn("[hive_close] Failed to emit SwarmCompletedEvent:", error45);
|
|
59493
59516
|
}
|
|
59494
59517
|
}
|
|
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
|
-
}
|
|
59518
|
+
await safeEmitEvent("cell_closed", {
|
|
59519
|
+
cell_id: cellId,
|
|
59520
|
+
reason: validated.reason
|
|
59521
|
+
}, "hive_close", projectKey);
|
|
59505
59522
|
return `Closed ${cell.id}: ${validated.reason}`;
|
|
59506
59523
|
} catch (error45) {
|
|
59507
59524
|
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
@@ -59528,13 +59545,13 @@ var hive_start = tool({
|
|
|
59528
59545
|
const cell = await adapter.changeCellStatus(projectKey, cellId, "in_progress");
|
|
59529
59546
|
await adapter.markDirty(projectKey, cellId);
|
|
59530
59547
|
try {
|
|
59531
|
-
const event =
|
|
59548
|
+
const event = createEvent2("cell_status_changed", {
|
|
59532
59549
|
project_key: projectKey,
|
|
59533
59550
|
cell_id: cellId,
|
|
59534
59551
|
old_status: "open",
|
|
59535
59552
|
new_status: "in_progress"
|
|
59536
59553
|
});
|
|
59537
|
-
await
|
|
59554
|
+
await appendEvent2(event, projectKey);
|
|
59538
59555
|
} catch (error45) {
|
|
59539
59556
|
console.warn("[hive_start] Failed to emit cell_status_changed event:", error45);
|
|
59540
59557
|
}
|
|
@@ -59735,12 +59752,12 @@ var hive_sync = tool({
|
|
|
59735
59752
|
pushSuccess = true;
|
|
59736
59753
|
}
|
|
59737
59754
|
try {
|
|
59738
|
-
const event =
|
|
59755
|
+
const event = createEvent2("hive_synced", {
|
|
59739
59756
|
project_key: projectKey,
|
|
59740
59757
|
cells_synced: flushResult.cellsExported,
|
|
59741
59758
|
push_success: pushSuccess
|
|
59742
59759
|
});
|
|
59743
|
-
await
|
|
59760
|
+
await appendEvent2(event, projectKey);
|
|
59744
59761
|
} catch (error45) {
|
|
59745
59762
|
console.warn("[hive_sync] Failed to emit hive_synced event:", error45);
|
|
59746
59763
|
}
|
|
@@ -61755,10 +61772,13 @@ var swarmmail_read_message = tool({
|
|
|
61755
61772
|
}
|
|
61756
61773
|
}
|
|
61757
61774
|
});
|
|
61775
|
+
function normalizePath(path2) {
|
|
61776
|
+
return path2.replace(/\\([[\]()])/g, "$1");
|
|
61777
|
+
}
|
|
61758
61778
|
var swarmmail_reserve = tool({
|
|
61759
|
-
description: "Reserve file paths for exclusive editing. Prevents conflicts with other agents.",
|
|
61779
|
+
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
61780
|
args: {
|
|
61761
|
-
paths: tool.schema.array(tool.schema.string()).describe("File paths or glob patterns to reserve"),
|
|
61781
|
+
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
61782
|
reason: tool.schema.string().optional().describe("Reason for reservation (e.g., bead ID)"),
|
|
61763
61783
|
exclusive: tool.schema.boolean().optional().describe("Whether reservation is exclusive (default: true)"),
|
|
61764
61784
|
ttl_seconds: tool.schema.number().optional().describe("Time-to-live in seconds (default: 3600)")
|
|
@@ -61770,10 +61790,11 @@ var swarmmail_reserve = tool({
|
|
|
61770
61790
|
return JSON.stringify({ error: "Session not initialized. Call swarmmail_init first." }, null, 2);
|
|
61771
61791
|
}
|
|
61772
61792
|
try {
|
|
61793
|
+
const normalizedPaths = args.paths.map(normalizePath);
|
|
61773
61794
|
const result = await reserveSwarmFiles({
|
|
61774
61795
|
projectPath: state.projectKey,
|
|
61775
61796
|
agentName: state.agentName,
|
|
61776
|
-
paths:
|
|
61797
|
+
paths: normalizedPaths,
|
|
61777
61798
|
reason: args.reason,
|
|
61778
61799
|
exclusive: args.exclusive ?? true,
|
|
61779
61800
|
ttlSeconds: args.ttl_seconds
|
|
@@ -61801,9 +61822,9 @@ var swarmmail_reserve = tool({
|
|
|
61801
61822
|
}
|
|
61802
61823
|
});
|
|
61803
61824
|
var swarmmail_release = tool({
|
|
61804
|
-
description: "Release file reservations. Call when done editing files.",
|
|
61825
|
+
description: "Release file reservations. Call when done editing files. " + "Do NOT escape brackets or parentheses in paths.",
|
|
61805
61826
|
args: {
|
|
61806
|
-
paths: tool.schema.array(tool.schema.string()).optional().describe("Specific paths to release (releases all if omitted)"),
|
|
61827
|
+
paths: tool.schema.array(tool.schema.string()).optional().describe("Specific paths to release (releases all if omitted). Do NOT escape [ ] ( ) characters."),
|
|
61807
61828
|
reservation_ids: tool.schema.array(tool.schema.number()).optional().describe("Specific reservation IDs to release")
|
|
61808
61829
|
},
|
|
61809
61830
|
async execute(args, ctx) {
|
|
@@ -61814,10 +61835,11 @@ var swarmmail_release = tool({
|
|
|
61814
61835
|
}
|
|
61815
61836
|
try {
|
|
61816
61837
|
const currentReservations = await getActiveReservations(state.projectKey, state.projectKey, state.agentName);
|
|
61838
|
+
const normalizedPaths = args.paths?.map(normalizePath);
|
|
61817
61839
|
const result = await releaseSwarmFiles({
|
|
61818
61840
|
projectPath: state.projectKey,
|
|
61819
61841
|
agentName: state.agentName,
|
|
61820
|
-
paths:
|
|
61842
|
+
paths: normalizedPaths,
|
|
61821
61843
|
reservationIds: args.reservation_ids
|
|
61822
61844
|
});
|
|
61823
61845
|
if (!args.paths && !args.reservation_ids) {
|
|
@@ -64691,8 +64713,8 @@ import {
|
|
|
64691
64713
|
releaseSwarmFiles as releaseSwarmFiles2,
|
|
64692
64714
|
sendSwarmMessage as sendSwarmMessage3,
|
|
64693
64715
|
getAgent,
|
|
64694
|
-
createEvent as
|
|
64695
|
-
appendEvent as
|
|
64716
|
+
createEvent as createEvent4,
|
|
64717
|
+
appendEvent as appendEvent3,
|
|
64696
64718
|
getSwarmMailLibSQL as getSwarmMailLibSQL4
|
|
64697
64719
|
} from "swarm-mail";
|
|
64698
64720
|
init_skills();
|
|
@@ -65197,15 +65219,15 @@ var swarm_review = tool({
|
|
|
65197
65219
|
downstream_tasks: downstreamTasks.length > 0 ? downstreamTasks : undefined
|
|
65198
65220
|
});
|
|
65199
65221
|
try {
|
|
65200
|
-
const { createEvent:
|
|
65222
|
+
const { createEvent: createEvent4, appendEvent: appendEvent3 } = await import("swarm-mail");
|
|
65201
65223
|
const attempt = getReviewStatus(args.task_id).attempt_count || 1;
|
|
65202
|
-
const reviewStartedEvent =
|
|
65224
|
+
const reviewStartedEvent = createEvent4("review_started", {
|
|
65203
65225
|
project_key: args.project_key,
|
|
65204
65226
|
epic_id: args.epic_id,
|
|
65205
65227
|
bead_id: args.task_id,
|
|
65206
65228
|
attempt
|
|
65207
65229
|
});
|
|
65208
|
-
await
|
|
65230
|
+
await appendEvent3(reviewStartedEvent, args.project_key);
|
|
65209
65231
|
} catch (error45) {
|
|
65210
65232
|
console.warn("[swarm_review] Failed to emit ReviewStartedEvent:", error45);
|
|
65211
65233
|
}
|
|
@@ -65288,16 +65310,16 @@ var swarm_review_feedback = tool({
|
|
|
65288
65310
|
console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
|
|
65289
65311
|
}
|
|
65290
65312
|
try {
|
|
65291
|
-
const { createEvent:
|
|
65313
|
+
const { createEvent: createEvent4, appendEvent: appendEvent3 } = await import("swarm-mail");
|
|
65292
65314
|
const attempt = getReviewStatus(args.task_id).attempt_count || 1;
|
|
65293
|
-
const reviewCompletedEvent =
|
|
65315
|
+
const reviewCompletedEvent = createEvent4("review_completed", {
|
|
65294
65316
|
project_key: args.project_key,
|
|
65295
65317
|
epic_id: epicId,
|
|
65296
65318
|
bead_id: args.task_id,
|
|
65297
65319
|
status: "approved",
|
|
65298
65320
|
attempt
|
|
65299
65321
|
});
|
|
65300
|
-
await
|
|
65322
|
+
await appendEvent3(reviewCompletedEvent, args.project_key);
|
|
65301
65323
|
} catch (error45) {
|
|
65302
65324
|
console.warn("[swarm_review_feedback] Failed to emit ReviewCompletedEvent:", error45);
|
|
65303
65325
|
}
|
|
@@ -65359,16 +65381,16 @@ You may now complete the task with \`swarm_complete\`.`,
|
|
|
65359
65381
|
console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
|
|
65360
65382
|
}
|
|
65361
65383
|
try {
|
|
65362
|
-
const { createEvent:
|
|
65384
|
+
const { createEvent: createEvent4, appendEvent: appendEvent3 } = await import("swarm-mail");
|
|
65363
65385
|
const status = remaining <= 0 ? "blocked" : "needs_changes";
|
|
65364
|
-
const reviewCompletedEvent =
|
|
65386
|
+
const reviewCompletedEvent = createEvent4("review_completed", {
|
|
65365
65387
|
project_key: args.project_key,
|
|
65366
65388
|
epic_id: epicId,
|
|
65367
65389
|
bead_id: args.task_id,
|
|
65368
65390
|
status,
|
|
65369
65391
|
attempt: attemptNumber
|
|
65370
65392
|
});
|
|
65371
|
-
await
|
|
65393
|
+
await appendEvent3(reviewCompletedEvent, args.project_key);
|
|
65372
65394
|
} catch (error45) {
|
|
65373
65395
|
console.warn("[swarm_review_feedback] Failed to emit ReviewCompletedEvent:", error45);
|
|
65374
65396
|
}
|
|
@@ -65426,8 +65448,200 @@ var reviewTools = {
|
|
|
65426
65448
|
swarm_review_feedback
|
|
65427
65449
|
};
|
|
65428
65450
|
|
|
65451
|
+
// src/utils/git-commit-info.ts
|
|
65452
|
+
import { execSync } from "child_process";
|
|
65453
|
+
function getGitCommitInfo(cwd) {
|
|
65454
|
+
try {
|
|
65455
|
+
const opts = { cwd, encoding: "utf-8", timeout: 5000 };
|
|
65456
|
+
const sha = execSync("git rev-parse HEAD", opts).trim();
|
|
65457
|
+
const message = execSync("git log -1 --format=%s", opts).trim();
|
|
65458
|
+
const branch = execSync("git rev-parse --abbrev-ref HEAD", opts).trim();
|
|
65459
|
+
return { sha, message, branch };
|
|
65460
|
+
} catch {
|
|
65461
|
+
return null;
|
|
65462
|
+
}
|
|
65463
|
+
}
|
|
65464
|
+
|
|
65429
65465
|
// src/swarm-orchestrate.ts
|
|
65430
65466
|
init_eval_capture();
|
|
65467
|
+
|
|
65468
|
+
// src/swarm-verify.ts
|
|
65469
|
+
init_dist();
|
|
65470
|
+
async function runTypecheckVerification() {
|
|
65471
|
+
const step = {
|
|
65472
|
+
name: "typecheck",
|
|
65473
|
+
command: "tsc --noEmit",
|
|
65474
|
+
passed: false,
|
|
65475
|
+
exitCode: -1
|
|
65476
|
+
};
|
|
65477
|
+
try {
|
|
65478
|
+
const tsconfigExists = await Bun.file("tsconfig.json").exists();
|
|
65479
|
+
if (!tsconfigExists) {
|
|
65480
|
+
step.skipped = true;
|
|
65481
|
+
step.skipReason = "No tsconfig.json found";
|
|
65482
|
+
step.passed = true;
|
|
65483
|
+
return step;
|
|
65484
|
+
}
|
|
65485
|
+
const result = await Bun.$`tsc --noEmit`.quiet().nothrow();
|
|
65486
|
+
step.exitCode = result.exitCode;
|
|
65487
|
+
step.passed = result.exitCode === 0;
|
|
65488
|
+
if (!step.passed) {
|
|
65489
|
+
step.error = result.stderr.toString().slice(0, 1000);
|
|
65490
|
+
step.output = result.stdout.toString().slice(0, 1000);
|
|
65491
|
+
}
|
|
65492
|
+
} catch (error45) {
|
|
65493
|
+
step.skipped = true;
|
|
65494
|
+
step.skipReason = `tsc not available: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
65495
|
+
step.passed = true;
|
|
65496
|
+
}
|
|
65497
|
+
return step;
|
|
65498
|
+
}
|
|
65499
|
+
async function runTestVerification(filesTouched) {
|
|
65500
|
+
const step = {
|
|
65501
|
+
name: "tests",
|
|
65502
|
+
command: "bun test <related-files>",
|
|
65503
|
+
passed: false,
|
|
65504
|
+
exitCode: -1
|
|
65505
|
+
};
|
|
65506
|
+
if (filesTouched.length === 0) {
|
|
65507
|
+
step.skipped = true;
|
|
65508
|
+
step.skipReason = "No files touched";
|
|
65509
|
+
step.passed = true;
|
|
65510
|
+
return step;
|
|
65511
|
+
}
|
|
65512
|
+
const testPatterns = [];
|
|
65513
|
+
for (const file2 of filesTouched) {
|
|
65514
|
+
if (file2.includes(".test.") || file2.includes(".spec.")) {
|
|
65515
|
+
testPatterns.push(file2);
|
|
65516
|
+
continue;
|
|
65517
|
+
}
|
|
65518
|
+
const baseName = file2.replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
65519
|
+
testPatterns.push(`${baseName}.test.ts`);
|
|
65520
|
+
testPatterns.push(`${baseName}.test.tsx`);
|
|
65521
|
+
testPatterns.push(`${baseName}.spec.ts`);
|
|
65522
|
+
}
|
|
65523
|
+
const existingTests = [];
|
|
65524
|
+
for (const pattern of testPatterns) {
|
|
65525
|
+
try {
|
|
65526
|
+
const exists = await Bun.file(pattern).exists();
|
|
65527
|
+
if (exists) {
|
|
65528
|
+
existingTests.push(pattern);
|
|
65529
|
+
}
|
|
65530
|
+
} catch {}
|
|
65531
|
+
}
|
|
65532
|
+
if (existingTests.length === 0) {
|
|
65533
|
+
step.skipped = true;
|
|
65534
|
+
step.skipReason = "No related test files found";
|
|
65535
|
+
step.passed = true;
|
|
65536
|
+
return step;
|
|
65537
|
+
}
|
|
65538
|
+
try {
|
|
65539
|
+
step.command = `bun test ${existingTests.join(" ")}`;
|
|
65540
|
+
const result = await Bun.$`bun test ${existingTests}`.quiet().nothrow();
|
|
65541
|
+
step.exitCode = result.exitCode;
|
|
65542
|
+
step.passed = result.exitCode === 0;
|
|
65543
|
+
if (!step.passed) {
|
|
65544
|
+
step.error = result.stderr.toString().slice(0, 1000);
|
|
65545
|
+
step.output = result.stdout.toString().slice(0, 1000);
|
|
65546
|
+
}
|
|
65547
|
+
} catch (error45) {
|
|
65548
|
+
step.skipped = true;
|
|
65549
|
+
step.skipReason = `Test runner failed: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
65550
|
+
step.passed = true;
|
|
65551
|
+
}
|
|
65552
|
+
return step;
|
|
65553
|
+
}
|
|
65554
|
+
async function runVerificationGate(filesTouched, _skipUbs = false) {
|
|
65555
|
+
const steps = [];
|
|
65556
|
+
const blockers = [];
|
|
65557
|
+
const typecheckStep = await runTypecheckVerification();
|
|
65558
|
+
steps.push(typecheckStep);
|
|
65559
|
+
if (!typecheckStep.passed && !typecheckStep.skipped) {
|
|
65560
|
+
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.`);
|
|
65561
|
+
}
|
|
65562
|
+
const testStep = await runTestVerification(filesTouched);
|
|
65563
|
+
steps.push(testStep);
|
|
65564
|
+
if (!testStep.passed && !testStep.skipped) {
|
|
65565
|
+
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.`);
|
|
65566
|
+
}
|
|
65567
|
+
const passedCount = steps.filter((s) => s.passed).length;
|
|
65568
|
+
const skippedCount = steps.filter((s) => s.skipped).length;
|
|
65569
|
+
const failedCount = steps.filter((s) => !s.passed && !s.skipped).length;
|
|
65570
|
+
const summary = failedCount === 0 ? `Verification passed: ${passedCount} checks passed, ${skippedCount} skipped` : `Verification FAILED: ${failedCount} checks failed, ${passedCount} passed, ${skippedCount} skipped`;
|
|
65571
|
+
return {
|
|
65572
|
+
passed: failedCount === 0,
|
|
65573
|
+
steps,
|
|
65574
|
+
summary,
|
|
65575
|
+
blockers
|
|
65576
|
+
};
|
|
65577
|
+
}
|
|
65578
|
+
var swarm_verify = tool({
|
|
65579
|
+
description: "Run verification gate (typecheck + tests) for files. Returns verification results without blocking. Used by swarm_complete to verify worker output.",
|
|
65580
|
+
args: {
|
|
65581
|
+
files_touched: tool.schema.array(tool.schema.string()).describe("Files to verify (typecheck + test discovery)"),
|
|
65582
|
+
skip_verification: tool.schema.boolean().optional().describe("Skip verification entirely (default: false)")
|
|
65583
|
+
},
|
|
65584
|
+
async execute(args) {
|
|
65585
|
+
try {
|
|
65586
|
+
if (args.skip_verification) {
|
|
65587
|
+
return JSON.stringify({
|
|
65588
|
+
success: true,
|
|
65589
|
+
data: {
|
|
65590
|
+
passed: true,
|
|
65591
|
+
skipped: true,
|
|
65592
|
+
reason: "skip_verification=true",
|
|
65593
|
+
summary: "Verification skipped by request",
|
|
65594
|
+
steps: [],
|
|
65595
|
+
blockers: []
|
|
65596
|
+
}
|
|
65597
|
+
}, null, 2);
|
|
65598
|
+
}
|
|
65599
|
+
if (!args.files_touched || args.files_touched.length === 0) {
|
|
65600
|
+
return JSON.stringify({
|
|
65601
|
+
success: true,
|
|
65602
|
+
data: {
|
|
65603
|
+
passed: true,
|
|
65604
|
+
skipped: true,
|
|
65605
|
+
reason: "no files_touched provided",
|
|
65606
|
+
summary: "No files to verify",
|
|
65607
|
+
steps: [],
|
|
65608
|
+
blockers: []
|
|
65609
|
+
}
|
|
65610
|
+
}, null, 2);
|
|
65611
|
+
}
|
|
65612
|
+
const result = await runVerificationGate(args.files_touched, false);
|
|
65613
|
+
return JSON.stringify({
|
|
65614
|
+
success: true,
|
|
65615
|
+
data: {
|
|
65616
|
+
passed: result.passed,
|
|
65617
|
+
skipped: false,
|
|
65618
|
+
summary: result.summary,
|
|
65619
|
+
steps: result.steps.map((s) => ({
|
|
65620
|
+
name: s.name,
|
|
65621
|
+
command: s.command,
|
|
65622
|
+
passed: s.passed,
|
|
65623
|
+
exitCode: s.exitCode,
|
|
65624
|
+
skipped: s.skipped,
|
|
65625
|
+
skipReason: s.skipReason,
|
|
65626
|
+
error: s.error?.slice(0, 200),
|
|
65627
|
+
output: s.output?.slice(0, 200)
|
|
65628
|
+
})),
|
|
65629
|
+
blockers: result.blockers
|
|
65630
|
+
}
|
|
65631
|
+
}, null, 2);
|
|
65632
|
+
} catch (error45) {
|
|
65633
|
+
return JSON.stringify({
|
|
65634
|
+
success: false,
|
|
65635
|
+
error: `Verification failed: ${error45 instanceof Error ? error45.message : String(error45)}`
|
|
65636
|
+
}, null, 2);
|
|
65637
|
+
}
|
|
65638
|
+
}
|
|
65639
|
+
});
|
|
65640
|
+
var verificationTools = {
|
|
65641
|
+
swarm_verify
|
|
65642
|
+
};
|
|
65643
|
+
|
|
65644
|
+
// src/swarm-orchestrate.ts
|
|
65431
65645
|
function generateWorkerHandoff(params) {
|
|
65432
65646
|
const handoff = {
|
|
65433
65647
|
contract: {
|
|
@@ -65569,114 +65783,6 @@ ${progress.blockers.map((b) => `- ${b}`).join(`
|
|
|
65569
65783
|
|
|
65570
65784
|
`);
|
|
65571
65785
|
}
|
|
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
65786
|
function classifyFailure(error45) {
|
|
65681
65787
|
const msg = (typeof error45 === "string" ? error45 : error45.message).toLowerCase();
|
|
65682
65788
|
if (msg.includes("timeout"))
|
|
@@ -65938,15 +66044,15 @@ var swarm_progress = tool({
|
|
|
65938
66044
|
}
|
|
65939
66045
|
};
|
|
65940
66046
|
const checkpointData = JSON.stringify(checkpoint);
|
|
65941
|
-
const checkpointEvent =
|
|
66047
|
+
const checkpointEvent = createEvent4("swarm_checkpointed", {
|
|
65942
66048
|
project_key: args.project_key,
|
|
65943
66049
|
...checkpoint,
|
|
65944
66050
|
checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
|
|
65945
66051
|
trigger: "progress"
|
|
65946
66052
|
});
|
|
65947
|
-
await
|
|
66053
|
+
await appendEvent3(checkpointEvent, args.project_key);
|
|
65948
66054
|
const checkpointId = `ckpt-${Date.now()}-${args.bead_id}`;
|
|
65949
|
-
const createdEvent =
|
|
66055
|
+
const createdEvent = createEvent4("checkpoint_created", {
|
|
65950
66056
|
project_key: args.project_key,
|
|
65951
66057
|
epic_id: epicId,
|
|
65952
66058
|
bead_id: args.bead_id,
|
|
@@ -65956,7 +66062,7 @@ var swarm_progress = tool({
|
|
|
65956
66062
|
progress_percent: args.progress_percent,
|
|
65957
66063
|
files_snapshot: args.files_touched
|
|
65958
66064
|
});
|
|
65959
|
-
await
|
|
66065
|
+
await appendEvent3(createdEvent, args.project_key);
|
|
65960
66066
|
checkpointCreated = true;
|
|
65961
66067
|
} catch (error45) {
|
|
65962
66068
|
console.warn(`[swarm_progress] Auto-checkpoint failed at ${args.progress_percent}%:`, error45);
|
|
@@ -66027,7 +66133,10 @@ var swarm_complete = tool({
|
|
|
66027
66133
|
start_time: tool.schema.number().describe("Task start timestamp (Unix ms) for duration calculation - REQUIRED for accurate analytics"),
|
|
66028
66134
|
error_count: tool.schema.number().optional().describe("Number of errors encountered during task"),
|
|
66029
66135
|
retry_count: tool.schema.number().optional().describe("Number of retry attempts during task"),
|
|
66030
|
-
skip_review: tool.schema.boolean().optional().describe("Skip review gate check (default: false). Use only for tasks that don't require coordinator review.")
|
|
66136
|
+
skip_review: tool.schema.boolean().optional().describe("Skip review gate check (default: false). Use only for tasks that don't require coordinator review."),
|
|
66137
|
+
commit_sha: tool.schema.string().optional().describe("Git commit SHA (auto-detected if not provided)"),
|
|
66138
|
+
commit_message: tool.schema.string().optional().describe("Commit message (auto-detected if not provided)"),
|
|
66139
|
+
commit_branch: tool.schema.string().optional().describe("Git branch (auto-detected if not provided)")
|
|
66031
66140
|
},
|
|
66032
66141
|
async execute(args, _ctx) {
|
|
66033
66142
|
const missing = [];
|
|
@@ -66088,6 +66197,13 @@ var swarm_complete = tool({
|
|
|
66088
66197
|
}, null, 2);
|
|
66089
66198
|
}
|
|
66090
66199
|
}
|
|
66200
|
+
const gitInfo = getGitCommitInfo(args.project_key) || {};
|
|
66201
|
+
const commitSha = args.commit_sha || gitInfo.sha;
|
|
66202
|
+
const commitMessage = args.commit_message || gitInfo.message;
|
|
66203
|
+
const commitBranch = args.commit_branch || gitInfo.branch;
|
|
66204
|
+
const resultText = commitSha ? `${args.summary}
|
|
66205
|
+
|
|
66206
|
+
Commit: ${commitSha.slice(0, 8)} (${commitBranch || "unknown"}) - ${commitMessage || "no message"}` : args.summary;
|
|
66091
66207
|
try {
|
|
66092
66208
|
const adapter = await getHiveAdapter(args.project_key);
|
|
66093
66209
|
const cell = await adapter.getCell(args.project_key, args.bead_id);
|
|
@@ -66202,7 +66318,9 @@ This will be recorded as a negative learning signal.`;
|
|
|
66202
66318
|
}
|
|
66203
66319
|
}
|
|
66204
66320
|
try {
|
|
66205
|
-
await adapter.closeCell(args.project_key, args.bead_id, args.summary
|
|
66321
|
+
await adapter.closeCell(args.project_key, args.bead_id, args.summary, {
|
|
66322
|
+
result: resultText
|
|
66323
|
+
});
|
|
66206
66324
|
} catch (closeError) {
|
|
66207
66325
|
const errorMessage = closeError instanceof Error ? closeError.message : String(closeError);
|
|
66208
66326
|
return JSON.stringify({
|
|
@@ -66259,7 +66377,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
66259
66377
|
const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
|
|
66260
66378
|
let outcomeEventId;
|
|
66261
66379
|
try {
|
|
66262
|
-
const event =
|
|
66380
|
+
const event = createEvent4("subtask_outcome", {
|
|
66263
66381
|
project_key: args.project_key,
|
|
66264
66382
|
epic_id: eventEpicId,
|
|
66265
66383
|
bead_id: args.bead_id,
|
|
@@ -66270,9 +66388,10 @@ This will be recorded as a negative learning signal.`;
|
|
|
66270
66388
|
retry_count: args.retry_count || 0,
|
|
66271
66389
|
success: true,
|
|
66272
66390
|
scope_violation: contractValidation ? !contractValidation.valid : undefined,
|
|
66273
|
-
violation_files: contractValidation?.violations
|
|
66391
|
+
violation_files: contractValidation?.violations,
|
|
66392
|
+
commit: commitSha ? { sha: commitSha, message: commitMessage, branch: commitBranch } : undefined
|
|
66274
66393
|
});
|
|
66275
|
-
const savedEvent = await
|
|
66394
|
+
const savedEvent = await appendEvent3(event, args.project_key);
|
|
66276
66395
|
outcomeEventId = savedEvent.id;
|
|
66277
66396
|
} catch (error45) {
|
|
66278
66397
|
console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
|
|
@@ -66290,7 +66409,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
66290
66409
|
}
|
|
66291
66410
|
}
|
|
66292
66411
|
try {
|
|
66293
|
-
const workerCompletedEvent =
|
|
66412
|
+
const workerCompletedEvent = createEvent4("worker_completed", {
|
|
66294
66413
|
project_key: args.project_key,
|
|
66295
66414
|
epic_id: eventEpicId,
|
|
66296
66415
|
bead_id: args.bead_id,
|
|
@@ -66299,7 +66418,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
66299
66418
|
duration_ms: completionDurationMs,
|
|
66300
66419
|
files_touched: args.files_touched || []
|
|
66301
66420
|
});
|
|
66302
|
-
await
|
|
66421
|
+
await appendEvent3(workerCompletedEvent, args.project_key);
|
|
66303
66422
|
} catch (error45) {
|
|
66304
66423
|
console.warn("[swarm_complete] Failed to emit worker_completed event:", error45);
|
|
66305
66424
|
}
|
|
@@ -66455,6 +66574,8 @@ This will be recorded as a negative learning signal.`;
|
|
|
66455
66574
|
success: true,
|
|
66456
66575
|
bead_id: args.bead_id,
|
|
66457
66576
|
closed: true,
|
|
66577
|
+
result: resultText,
|
|
66578
|
+
commit: commitSha ? { sha: commitSha, message: commitMessage, branch: commitBranch } : undefined,
|
|
66458
66579
|
reservations_released: reservationsReleased,
|
|
66459
66580
|
reservations_released_count: reservationsReleasedCount,
|
|
66460
66581
|
reservations_release_error: reservationsReleaseError,
|
|
@@ -67023,7 +67144,7 @@ var swarm_checkpoint = tool({
|
|
|
67023
67144
|
}
|
|
67024
67145
|
};
|
|
67025
67146
|
const checkpointData = JSON.stringify(checkpoint);
|
|
67026
|
-
const event =
|
|
67147
|
+
const event = createEvent4("swarm_checkpointed", {
|
|
67027
67148
|
project_key: args.project_key,
|
|
67028
67149
|
epic_id: args.epic_id,
|
|
67029
67150
|
bead_id: args.bead_id,
|
|
@@ -67035,7 +67156,7 @@ var swarm_checkpoint = tool({
|
|
|
67035
67156
|
checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
|
|
67036
67157
|
trigger: args.error_context ? "error" : "manual"
|
|
67037
67158
|
});
|
|
67038
|
-
await
|
|
67159
|
+
await appendEvent3(event, args.project_key);
|
|
67039
67160
|
const now = Date.now();
|
|
67040
67161
|
return JSON.stringify({
|
|
67041
67162
|
success: true,
|
|
@@ -67093,13 +67214,13 @@ var swarm_recover = tool({
|
|
|
67093
67214
|
created_at: row.created_at,
|
|
67094
67215
|
updated_at: row.updated_at
|
|
67095
67216
|
};
|
|
67096
|
-
const event =
|
|
67217
|
+
const event = createEvent4("swarm_recovered", {
|
|
67097
67218
|
project_key: args.project_key,
|
|
67098
67219
|
epic_id: args.epic_id,
|
|
67099
67220
|
bead_id: context.bead_id,
|
|
67100
67221
|
recovered_from_checkpoint: context.recovery.last_checkpoint
|
|
67101
67222
|
});
|
|
67102
|
-
await
|
|
67223
|
+
await appendEvent3(event, args.project_key);
|
|
67103
67224
|
return JSON.stringify({
|
|
67104
67225
|
found: true,
|
|
67105
67226
|
context,
|
|
@@ -67520,6 +67641,27 @@ swarmmail_reserve(
|
|
|
67520
67641
|
|
|
67521
67642
|
**Workers reserve their own files.** This prevents edit conflicts with other agents.
|
|
67522
67643
|
|
|
67644
|
+
### ⚠️ CRITICAL: File Path Handling (Next.js/Special Characters)
|
|
67645
|
+
|
|
67646
|
+
**DO NOT escape brackets or parentheses in file paths!**
|
|
67647
|
+
|
|
67648
|
+
When working with Next.js App Router or any codebase with special characters in paths:
|
|
67649
|
+
|
|
67650
|
+
❌ **WRONG** (will fail):
|
|
67651
|
+
\`\`\`
|
|
67652
|
+
Read: app/\\(content\\)/events/\\[slug\\]/page.tsx
|
|
67653
|
+
Glob: src/**/\\[id\\]/**/*.ts
|
|
67654
|
+
\`\`\`
|
|
67655
|
+
|
|
67656
|
+
✅ **CORRECT** (use raw paths):
|
|
67657
|
+
\`\`\`
|
|
67658
|
+
Read: app/(content)/events/[slug]/page.tsx
|
|
67659
|
+
Glob: src/**/[id]/**/*.ts
|
|
67660
|
+
\`\`\`
|
|
67661
|
+
|
|
67662
|
+
**The Read and Glob tools handle special characters automatically.**
|
|
67663
|
+
Never add backslashes before \`[\`, \`]\`, \`(\`, or \`)\` in file paths.
|
|
67664
|
+
|
|
67523
67665
|
### Step 5: Do the Work (TDD MANDATORY)
|
|
67524
67666
|
|
|
67525
67667
|
**Follow RED → GREEN → REFACTOR. No exceptions.**
|
|
@@ -68282,9 +68424,9 @@ var swarm_spawn_subtask = tool({
|
|
|
68282
68424
|
}
|
|
68283
68425
|
if (args2.project_path) {
|
|
68284
68426
|
try {
|
|
68285
|
-
const { createEvent:
|
|
68427
|
+
const { createEvent: createEvent6, appendEvent: appendEvent5 } = await import("swarm-mail");
|
|
68286
68428
|
const spawnOrder = 0;
|
|
68287
|
-
const workerSpawnedEvent =
|
|
68429
|
+
const workerSpawnedEvent = createEvent6("worker_spawned", {
|
|
68288
68430
|
project_key: args2.project_path,
|
|
68289
68431
|
epic_id: args2.epic_id,
|
|
68290
68432
|
bead_id: args2.bead_id,
|
|
@@ -68294,7 +68436,7 @@ var swarm_spawn_subtask = tool({
|
|
|
68294
68436
|
spawn_order: spawnOrder,
|
|
68295
68437
|
is_parallel: false
|
|
68296
68438
|
});
|
|
68297
|
-
await
|
|
68439
|
+
await appendEvent5(workerSpawnedEvent, args2.project_path);
|
|
68298
68440
|
} catch (error45) {
|
|
68299
68441
|
console.warn("[swarm_spawn_subtask] Failed to emit WorkerSpawnedEvent:", error45);
|
|
68300
68442
|
}
|
|
@@ -68992,7 +69134,8 @@ var swarmTools = {
|
|
|
68992
69134
|
...promptTools,
|
|
68993
69135
|
...orchestrateTools,
|
|
68994
69136
|
...researchTools,
|
|
68995
|
-
...adversarialReviewTools
|
|
69137
|
+
...adversarialReviewTools,
|
|
69138
|
+
...verificationTools
|
|
68996
69139
|
};
|
|
68997
69140
|
|
|
68998
69141
|
// src/repo-crawl.ts
|
|
@@ -70035,36 +70178,35 @@ var mandateTools = {
|
|
|
70035
70178
|
// src/hivemind-tools.ts
|
|
70036
70179
|
init_dist();
|
|
70037
70180
|
init_esm();
|
|
70038
|
-
init_memory();
|
|
70039
|
-
init_memory();
|
|
70040
70181
|
import {
|
|
70041
70182
|
getSwarmMailLibSQL as getSwarmMailLibSQL6,
|
|
70042
|
-
createEvent as createEvent5,
|
|
70043
70183
|
SessionIndexer,
|
|
70044
70184
|
syncMemories as syncMemories2,
|
|
70045
70185
|
toSwarmDb as toSwarmDb2,
|
|
70046
70186
|
makeOllamaLive as makeOllamaLive2
|
|
70047
70187
|
} from "swarm-mail";
|
|
70188
|
+
init_memory();
|
|
70189
|
+
init_memory();
|
|
70048
70190
|
import * as os2 from "node:os";
|
|
70049
70191
|
import * as path3 from "node:path";
|
|
70050
70192
|
import { join as join12 } from "node:path";
|
|
70051
|
-
var
|
|
70193
|
+
var cachedAdapter = null;
|
|
70052
70194
|
var cachedIndexer = null;
|
|
70053
|
-
var
|
|
70195
|
+
var cachedProjectPath = null;
|
|
70054
70196
|
async function getMemoryAdapter2(projectPath) {
|
|
70055
70197
|
const path4 = projectPath || process.cwd();
|
|
70056
|
-
if (
|
|
70057
|
-
return
|
|
70198
|
+
if (cachedAdapter && cachedProjectPath === path4) {
|
|
70199
|
+
return cachedAdapter;
|
|
70058
70200
|
}
|
|
70059
70201
|
const swarmMail = await getSwarmMailLibSQL6(path4);
|
|
70060
70202
|
const dbAdapter = await swarmMail.getDatabase();
|
|
70061
|
-
|
|
70062
|
-
|
|
70063
|
-
return
|
|
70203
|
+
cachedAdapter = await createMemoryAdapter(dbAdapter);
|
|
70204
|
+
cachedProjectPath = path4;
|
|
70205
|
+
return cachedAdapter;
|
|
70064
70206
|
}
|
|
70065
70207
|
async function getSessionIndexer(projectPath) {
|
|
70066
70208
|
const path4 = projectPath || process.cwd();
|
|
70067
|
-
if (cachedIndexer &&
|
|
70209
|
+
if (cachedIndexer && cachedProjectPath === path4) {
|
|
70068
70210
|
return cachedIndexer;
|
|
70069
70211
|
}
|
|
70070
70212
|
const swarmMail = await getSwarmMailLibSQL6(path4);
|
|
@@ -70075,20 +70217,13 @@ async function getSessionIndexer(projectPath) {
|
|
|
70075
70217
|
ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
|
|
70076
70218
|
});
|
|
70077
70219
|
cachedIndexer = new SessionIndexer(db, ollamaLayer);
|
|
70078
|
-
|
|
70220
|
+
cachedProjectPath = path4;
|
|
70079
70221
|
return cachedIndexer;
|
|
70080
70222
|
}
|
|
70081
70223
|
var getHivemindAdapter = getMemoryAdapter2;
|
|
70082
70224
|
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 {}
|
|
70225
|
+
const projectPath = cachedProjectPath || process.cwd();
|
|
70226
|
+
await safeEmitEvent(eventType, data, "hivemind", projectPath);
|
|
70092
70227
|
}
|
|
70093
70228
|
var AGENT_DIRECTORIES = [
|
|
70094
70229
|
path3.join(os2.homedir(), ".config", "swarm-tools", "sessions"),
|
|
@@ -70131,6 +70266,15 @@ var hivemind_find = tool({
|
|
|
70131
70266
|
fts: tool.schema.boolean().optional().describe("Use full-text search instead of vector search (default: false)")
|
|
70132
70267
|
},
|
|
70133
70268
|
async execute(args2, ctx) {
|
|
70269
|
+
if (!args2.query || typeof args2.query !== "string" || args2.query.trim() === "") {
|
|
70270
|
+
return JSON.stringify({
|
|
70271
|
+
success: false,
|
|
70272
|
+
error: {
|
|
70273
|
+
code: "VALIDATION_ERROR",
|
|
70274
|
+
message: "query parameter is required and must be a non-empty string"
|
|
70275
|
+
}
|
|
70276
|
+
});
|
|
70277
|
+
}
|
|
70134
70278
|
const startTime = Date.now();
|
|
70135
70279
|
const adapter = await getMemoryAdapter2();
|
|
70136
70280
|
const result = await adapter.find(args2);
|
|
@@ -70251,7 +70395,7 @@ var hivemind_sync = tool({
|
|
|
70251
70395
|
args: {},
|
|
70252
70396
|
async execute(args2, ctx) {
|
|
70253
70397
|
try {
|
|
70254
|
-
const projectPath =
|
|
70398
|
+
const projectPath = cachedProjectPath || process.cwd();
|
|
70255
70399
|
const swarmMail = await getSwarmMailLibSQL6(projectPath);
|
|
70256
70400
|
const dbAdapter = await swarmMail.getDatabase();
|
|
70257
70401
|
const hiveDir = join12(projectPath, ".hive");
|
|
@@ -72074,13 +72218,17 @@ var AGENT_DIRECTORIES2 = [
|
|
|
72074
72218
|
path4.join(os3.homedir(), ".local", "share", "Claude"),
|
|
72075
72219
|
path4.join(os3.homedir(), ".aider")
|
|
72076
72220
|
];
|
|
72221
|
+
var sessionIndexerCache = new AdapterCache;
|
|
72077
72222
|
async function getSessionIndexer2() {
|
|
72078
|
-
const
|
|
72079
|
-
|
|
72080
|
-
|
|
72081
|
-
|
|
72223
|
+
const globalKey = "global-session-indexer";
|
|
72224
|
+
return sessionIndexerCache.get(globalKey, async () => {
|
|
72225
|
+
const db = await getDb();
|
|
72226
|
+
const ollamaLayer = makeOllamaLive3({
|
|
72227
|
+
ollamaHost: process.env.OLLAMA_HOST || "http://localhost:11434",
|
|
72228
|
+
ollamaModel: process.env.OLLAMA_MODEL || "mxbai-embed-large"
|
|
72229
|
+
});
|
|
72230
|
+
return new SessionIndexer2(db, ollamaLayer);
|
|
72082
72231
|
});
|
|
72083
|
-
return new SessionIndexer2(db, ollamaLayer);
|
|
72084
72232
|
}
|
|
72085
72233
|
async function emitEvent2(eventType, data) {
|
|
72086
72234
|
try {
|