opencode-swarm-plugin 0.45.1 → 0.45.3
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 +68 -0
- package/dist/bin/swarm.js +883 -467
- package/dist/cass-tools.d.ts +75 -0
- package/dist/cass-tools.d.ts.map +1 -0
- package/dist/eval-capture.d.ts +6 -6
- package/dist/hive.d.ts +20 -20
- package/dist/hive.d.ts.map +1 -1
- package/dist/hive.js +79 -0
- package/dist/index.d.ts +91 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +750 -524
- package/dist/memory-tools.d.ts.map +1 -1
- package/dist/plugin.js +594 -524
- package/dist/schemas/cell-events.d.ts +4 -4
- package/dist/schemas/cell.d.ts +10 -10
- package/dist/schemas/swarm-context.d.ts +2 -2
- package/dist/skills.d.ts +8 -8
- package/dist/skills.d.ts.map +1 -1
- package/dist/swarm-orchestrate.d.ts.map +1 -1
- package/dist/swarm-prompts.js +242 -29
- package/examples/plugin-wrapper-template.ts +108 -7
- package/package.json +2 -2
package/dist/swarm-prompts.js
CHANGED
|
@@ -17242,6 +17242,34 @@ import {
|
|
|
17242
17242
|
sep as sep2
|
|
17243
17243
|
} from "path";
|
|
17244
17244
|
import { fileURLToPath } from "url";
|
|
17245
|
+
import { getSwarmMailLibSQL as getSwarmMailLibSQL2, createEvent as createEvent2 } from "swarm-mail";
|
|
17246
|
+
async function emitSkillLoadedEvent(data) {
|
|
17247
|
+
try {
|
|
17248
|
+
const projectPath = skillsProjectDirectory;
|
|
17249
|
+
const swarmMail = await getSwarmMailLibSQL2(projectPath);
|
|
17250
|
+
const event = createEvent2("skill_loaded", {
|
|
17251
|
+
project_key: projectPath,
|
|
17252
|
+
skill_name: data.skill_name,
|
|
17253
|
+
skill_source: data.skill_source,
|
|
17254
|
+
context_provided: data.context_provided,
|
|
17255
|
+
content_length: data.content_length
|
|
17256
|
+
});
|
|
17257
|
+
await swarmMail.appendEvent(event);
|
|
17258
|
+
} catch {}
|
|
17259
|
+
}
|
|
17260
|
+
async function emitSkillCreatedEvent(data) {
|
|
17261
|
+
try {
|
|
17262
|
+
const projectPath = skillsProjectDirectory;
|
|
17263
|
+
const swarmMail = await getSwarmMailLibSQL2(projectPath);
|
|
17264
|
+
const event = createEvent2("skill_created", {
|
|
17265
|
+
project_key: projectPath,
|
|
17266
|
+
skill_name: data.skill_name,
|
|
17267
|
+
skill_scope: data.skill_scope,
|
|
17268
|
+
description: data.description
|
|
17269
|
+
});
|
|
17270
|
+
await swarmMail.appendEvent(event);
|
|
17271
|
+
} catch {}
|
|
17272
|
+
}
|
|
17245
17273
|
function setSkillsProjectDirectory(dir) {
|
|
17246
17274
|
skillsProjectDirectory = dir;
|
|
17247
17275
|
skillsCache = null;
|
|
@@ -17677,6 +17705,18 @@ If the skill has scripts, you can run them with skills_execute.`,
|
|
|
17677
17705
|
const names = available.map((s) => s.name).join(", ");
|
|
17678
17706
|
return `Skill '${args.name}' not found. Available skills: ${names || "none"}`;
|
|
17679
17707
|
}
|
|
17708
|
+
let skillSource = "project";
|
|
17709
|
+
if (skill.path.includes(".config/opencode/skills") || skill.path.includes(".claude/skills")) {
|
|
17710
|
+
skillSource = "global";
|
|
17711
|
+
} else if (skill.path.includes("global-skills")) {
|
|
17712
|
+
skillSource = "bundled";
|
|
17713
|
+
}
|
|
17714
|
+
await emitSkillLoadedEvent({
|
|
17715
|
+
skill_name: skill.metadata.name,
|
|
17716
|
+
skill_source: skillSource,
|
|
17717
|
+
context_provided: true,
|
|
17718
|
+
content_length: skill.body.length
|
|
17719
|
+
});
|
|
17680
17720
|
const includeScripts = args.include_scripts !== false;
|
|
17681
17721
|
let output = `# Skill: ${skill.metadata.name}
|
|
17682
17722
|
|
|
@@ -17845,6 +17885,12 @@ Good skills have:
|
|
|
17845
17885
|
const content = generateSkillContent(args.name, args.description, args.body, { tags: args.tags, tools: args.tools });
|
|
17846
17886
|
await writeFile(skillPath, content, "utf-8");
|
|
17847
17887
|
invalidateSkillsCache();
|
|
17888
|
+
const skillScope = args.directory === "global" || args.directory === "global-claude" ? "global" : "project";
|
|
17889
|
+
await emitSkillCreatedEvent({
|
|
17890
|
+
skill_name: args.name,
|
|
17891
|
+
skill_scope: skillScope,
|
|
17892
|
+
description: args.description
|
|
17893
|
+
});
|
|
17848
17894
|
const response = {
|
|
17849
17895
|
success: true,
|
|
17850
17896
|
skill: args.name,
|
|
@@ -18080,6 +18126,12 @@ echo "Project directory: $1"
|
|
|
18080
18126
|
createdFiles.push("references/guide.md");
|
|
18081
18127
|
}
|
|
18082
18128
|
invalidateSkillsCache();
|
|
18129
|
+
const skillScope = args.directory === "global" ? "global" : "project";
|
|
18130
|
+
await emitSkillCreatedEvent({
|
|
18131
|
+
skill_name: args.name,
|
|
18132
|
+
skill_scope: skillScope,
|
|
18133
|
+
description: args.description || "[TODO: Complete description]"
|
|
18134
|
+
});
|
|
18083
18135
|
return JSON.stringify({
|
|
18084
18136
|
success: true,
|
|
18085
18137
|
skill: args.name,
|
|
@@ -20679,9 +20731,9 @@ import {
|
|
|
20679
20731
|
releaseSwarmFiles,
|
|
20680
20732
|
sendSwarmMessage as sendSwarmMessage2,
|
|
20681
20733
|
getAgent,
|
|
20682
|
-
createEvent as
|
|
20734
|
+
createEvent as createEvent3,
|
|
20683
20735
|
appendEvent as appendEvent2,
|
|
20684
|
-
getSwarmMailLibSQL as
|
|
20736
|
+
getSwarmMailLibSQL as getSwarmMailLibSQL3
|
|
20685
20737
|
} from "swarm-mail";
|
|
20686
20738
|
|
|
20687
20739
|
// src/tool-availability.ts
|
|
@@ -21092,6 +21144,20 @@ var hive_create = tool({
|
|
|
21092
21144
|
parent_id: validated.parent_id
|
|
21093
21145
|
});
|
|
21094
21146
|
await adapter.markDirty(projectKey, cell.id);
|
|
21147
|
+
try {
|
|
21148
|
+
const event = createEvent("cell_created", {
|
|
21149
|
+
project_key: projectKey,
|
|
21150
|
+
cell_id: cell.id,
|
|
21151
|
+
title: validated.title,
|
|
21152
|
+
description: validated.description,
|
|
21153
|
+
issue_type: validated.type || "task",
|
|
21154
|
+
priority: validated.priority ?? 2,
|
|
21155
|
+
parent_id: validated.parent_id
|
|
21156
|
+
});
|
|
21157
|
+
await appendEvent(event, projectKey);
|
|
21158
|
+
} catch (error45) {
|
|
21159
|
+
console.warn("[hive_create] Failed to emit cell_created event:", error45);
|
|
21160
|
+
}
|
|
21095
21161
|
const formatted = formatCellForOutput(cell);
|
|
21096
21162
|
return JSON.stringify(formatted, null, 2);
|
|
21097
21163
|
} catch (error45) {
|
|
@@ -21151,6 +21217,19 @@ var hive_create_epic = tool({
|
|
|
21151
21217
|
subtasks: created.slice(1).map((c) => formatCellForOutput(c))
|
|
21152
21218
|
};
|
|
21153
21219
|
const effectiveProjectKey = args.project_key || projectKey;
|
|
21220
|
+
try {
|
|
21221
|
+
const epicCreatedEvent = createEvent("epic_created", {
|
|
21222
|
+
project_key: effectiveProjectKey,
|
|
21223
|
+
epic_id: epic.id,
|
|
21224
|
+
title: validated.epic_title,
|
|
21225
|
+
description: validated.epic_description,
|
|
21226
|
+
subtask_count: validated.subtasks.length,
|
|
21227
|
+
subtask_ids: created.slice(1).map((c) => c.id)
|
|
21228
|
+
});
|
|
21229
|
+
await appendEvent(epicCreatedEvent, effectiveProjectKey);
|
|
21230
|
+
} catch (error45) {
|
|
21231
|
+
console.warn("[hive_create_epic] Failed to emit epic_created event:", error45);
|
|
21232
|
+
}
|
|
21154
21233
|
try {
|
|
21155
21234
|
const event = createEvent("decomposition_generated", {
|
|
21156
21235
|
project_key: effectiveProjectKey,
|
|
@@ -21315,6 +21394,23 @@ var hive_update = tool({
|
|
|
21315
21394
|
cell = existingCell;
|
|
21316
21395
|
}
|
|
21317
21396
|
await adapter.markDirty(projectKey, cellId);
|
|
21397
|
+
try {
|
|
21398
|
+
const fieldsChanged = [];
|
|
21399
|
+
if (validated.status)
|
|
21400
|
+
fieldsChanged.push("status");
|
|
21401
|
+
if (validated.description !== undefined)
|
|
21402
|
+
fieldsChanged.push("description");
|
|
21403
|
+
if (validated.priority !== undefined)
|
|
21404
|
+
fieldsChanged.push("priority");
|
|
21405
|
+
const event = createEvent("cell_updated", {
|
|
21406
|
+
project_key: projectKey,
|
|
21407
|
+
cell_id: cellId,
|
|
21408
|
+
fields_changed: fieldsChanged
|
|
21409
|
+
});
|
|
21410
|
+
await appendEvent(event, projectKey);
|
|
21411
|
+
} catch (error45) {
|
|
21412
|
+
console.warn("[hive_update] Failed to emit cell_updated event:", error45);
|
|
21413
|
+
}
|
|
21318
21414
|
const formatted = formatCellForOutput(cell);
|
|
21319
21415
|
return JSON.stringify(formatted, null, 2);
|
|
21320
21416
|
} catch (error45) {
|
|
@@ -21431,6 +21527,16 @@ var hive_close = tool({
|
|
|
21431
21527
|
console.warn("[hive_close] Failed to emit SwarmCompletedEvent:", error45);
|
|
21432
21528
|
}
|
|
21433
21529
|
}
|
|
21530
|
+
try {
|
|
21531
|
+
const event = createEvent("cell_closed", {
|
|
21532
|
+
project_key: projectKey,
|
|
21533
|
+
cell_id: cellId,
|
|
21534
|
+
reason: validated.reason
|
|
21535
|
+
});
|
|
21536
|
+
await appendEvent(event, projectKey);
|
|
21537
|
+
} catch (error45) {
|
|
21538
|
+
console.warn("[hive_close] Failed to emit cell_closed event:", error45);
|
|
21539
|
+
}
|
|
21434
21540
|
return `Closed ${cell.id}: ${validated.reason}`;
|
|
21435
21541
|
} catch (error45) {
|
|
21436
21542
|
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
@@ -21456,6 +21562,17 @@ var hive_start = tool({
|
|
|
21456
21562
|
const cellId = await resolvePartialId(adapter, projectKey, args.id) || args.id;
|
|
21457
21563
|
const cell = await adapter.changeCellStatus(projectKey, cellId, "in_progress");
|
|
21458
21564
|
await adapter.markDirty(projectKey, cellId);
|
|
21565
|
+
try {
|
|
21566
|
+
const event = createEvent("cell_status_changed", {
|
|
21567
|
+
project_key: projectKey,
|
|
21568
|
+
cell_id: cellId,
|
|
21569
|
+
old_status: "open",
|
|
21570
|
+
new_status: "in_progress"
|
|
21571
|
+
});
|
|
21572
|
+
await appendEvent(event, projectKey);
|
|
21573
|
+
} catch (error45) {
|
|
21574
|
+
console.warn("[hive_start] Failed to emit cell_status_changed event:", error45);
|
|
21575
|
+
}
|
|
21459
21576
|
return `Started: ${cell.id}`;
|
|
21460
21577
|
} catch (error45) {
|
|
21461
21578
|
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
@@ -21644,11 +21761,25 @@ var hive_sync = tool({
|
|
|
21644
21761
|
}
|
|
21645
21762
|
const remoteCheckResult = await runGitCommand(["remote"]);
|
|
21646
21763
|
const hasRemote = remoteCheckResult.stdout.trim() !== "";
|
|
21764
|
+
let pushSuccess = false;
|
|
21647
21765
|
if (hasRemote) {
|
|
21648
21766
|
const pushResult = await withTimeout(runGitCommand(["push"]), TIMEOUT_MS, "git push");
|
|
21649
21767
|
if (pushResult.exitCode !== 0) {
|
|
21650
21768
|
throw new HiveError(`Failed to push: ${pushResult.stderr}`, "git push", pushResult.exitCode);
|
|
21651
21769
|
}
|
|
21770
|
+
pushSuccess = true;
|
|
21771
|
+
}
|
|
21772
|
+
try {
|
|
21773
|
+
const event = createEvent("hive_synced", {
|
|
21774
|
+
project_key: projectKey,
|
|
21775
|
+
cells_synced: flushResult.cellsExported,
|
|
21776
|
+
push_success: pushSuccess
|
|
21777
|
+
});
|
|
21778
|
+
await appendEvent(event, projectKey);
|
|
21779
|
+
} catch (error45) {
|
|
21780
|
+
console.warn("[hive_sync] Failed to emit hive_synced event:", error45);
|
|
21781
|
+
}
|
|
21782
|
+
if (hasRemote) {
|
|
21652
21783
|
return "Hive synced and pushed successfully";
|
|
21653
21784
|
} else {
|
|
21654
21785
|
return "Hive synced successfully (no remote configured)";
|
|
@@ -22340,9 +22471,9 @@ var swarm_review = tool({
|
|
|
22340
22471
|
downstream_tasks: downstreamTasks.length > 0 ? downstreamTasks : undefined
|
|
22341
22472
|
});
|
|
22342
22473
|
try {
|
|
22343
|
-
const { createEvent:
|
|
22474
|
+
const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
|
|
22344
22475
|
const attempt = getReviewStatus(args.task_id).attempt_count || 1;
|
|
22345
|
-
const reviewStartedEvent =
|
|
22476
|
+
const reviewStartedEvent = createEvent3("review_started", {
|
|
22346
22477
|
project_key: args.project_key,
|
|
22347
22478
|
epic_id: args.epic_id,
|
|
22348
22479
|
bead_id: args.task_id,
|
|
@@ -22431,9 +22562,9 @@ var swarm_review_feedback = tool({
|
|
|
22431
22562
|
console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
|
|
22432
22563
|
}
|
|
22433
22564
|
try {
|
|
22434
|
-
const { createEvent:
|
|
22565
|
+
const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
|
|
22435
22566
|
const attempt = getReviewStatus(args.task_id).attempt_count || 1;
|
|
22436
|
-
const reviewCompletedEvent =
|
|
22567
|
+
const reviewCompletedEvent = createEvent3("review_completed", {
|
|
22437
22568
|
project_key: args.project_key,
|
|
22438
22569
|
epic_id: epicId,
|
|
22439
22570
|
bead_id: args.task_id,
|
|
@@ -22502,9 +22633,9 @@ You may now complete the task with \`swarm_complete\`.`,
|
|
|
22502
22633
|
console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
|
|
22503
22634
|
}
|
|
22504
22635
|
try {
|
|
22505
|
-
const { createEvent:
|
|
22636
|
+
const { createEvent: createEvent3, appendEvent: appendEvent2 } = await import("swarm-mail");
|
|
22506
22637
|
const status = remaining <= 0 ? "blocked" : "needs_changes";
|
|
22507
|
-
const reviewCompletedEvent =
|
|
22638
|
+
const reviewCompletedEvent = createEvent3("review_completed", {
|
|
22508
22639
|
project_key: args.project_key,
|
|
22509
22640
|
epic_id: epicId,
|
|
22510
22641
|
bead_id: args.task_id,
|
|
@@ -23056,7 +23187,7 @@ var swarm_progress = tool({
|
|
|
23056
23187
|
}
|
|
23057
23188
|
};
|
|
23058
23189
|
const checkpointData = JSON.stringify(checkpoint);
|
|
23059
|
-
const checkpointEvent =
|
|
23190
|
+
const checkpointEvent = createEvent3("swarm_checkpointed", {
|
|
23060
23191
|
project_key: args.project_key,
|
|
23061
23192
|
...checkpoint,
|
|
23062
23193
|
checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
|
|
@@ -23064,7 +23195,7 @@ var swarm_progress = tool({
|
|
|
23064
23195
|
});
|
|
23065
23196
|
await appendEvent2(checkpointEvent, args.project_key);
|
|
23066
23197
|
const checkpointId = `ckpt-${Date.now()}-${args.bead_id}`;
|
|
23067
|
-
const createdEvent =
|
|
23198
|
+
const createdEvent = createEvent3("checkpoint_created", {
|
|
23068
23199
|
project_key: args.project_key,
|
|
23069
23200
|
epic_id: epicId,
|
|
23070
23201
|
bead_id: args.bead_id,
|
|
@@ -23317,7 +23448,7 @@ This will be recorded as a negative learning signal.`;
|
|
|
23317
23448
|
let deferredResolved = false;
|
|
23318
23449
|
let deferredError;
|
|
23319
23450
|
try {
|
|
23320
|
-
const swarmMail = await
|
|
23451
|
+
const swarmMail = await getSwarmMailLibSQL3(args.project_key);
|
|
23321
23452
|
const db = await swarmMail.getDatabase();
|
|
23322
23453
|
const deferredUrl = `deferred:${args.bead_id}`;
|
|
23323
23454
|
const checkResult = await db.query(`SELECT url, resolved FROM deferred WHERE url = ? AND resolved = 0`, [deferredUrl]);
|
|
@@ -23346,16 +23477,16 @@ This will be recorded as a negative learning signal.`;
|
|
|
23346
23477
|
syncError = error45 instanceof Error ? error45.message : String(error45);
|
|
23347
23478
|
console.warn(`[swarm_complete] Auto-sync failed (non-fatal): ${syncError}`);
|
|
23348
23479
|
}
|
|
23480
|
+
const completionDurationMs = args.start_time ? Date.now() - args.start_time : 0;
|
|
23481
|
+
const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
|
|
23349
23482
|
try {
|
|
23350
|
-
const
|
|
23351
|
-
const eventEpicId = cell.parent_id || (args.bead_id.includes(".") ? args.bead_id.split(".")[0] : args.bead_id);
|
|
23352
|
-
const event = createEvent2("subtask_outcome", {
|
|
23483
|
+
const event = createEvent3("subtask_outcome", {
|
|
23353
23484
|
project_key: args.project_key,
|
|
23354
23485
|
epic_id: eventEpicId,
|
|
23355
23486
|
bead_id: args.bead_id,
|
|
23356
23487
|
planned_files: args.planned_files || [],
|
|
23357
23488
|
actual_files: args.files_touched || [],
|
|
23358
|
-
duration_ms:
|
|
23489
|
+
duration_ms: completionDurationMs,
|
|
23359
23490
|
error_count: args.error_count || 0,
|
|
23360
23491
|
retry_count: args.retry_count || 0,
|
|
23361
23492
|
success: true,
|
|
@@ -23366,8 +23497,21 @@ This will be recorded as a negative learning signal.`;
|
|
|
23366
23497
|
} catch (error45) {
|
|
23367
23498
|
console.warn("[swarm_complete] Failed to emit SubtaskOutcomeEvent:", error45);
|
|
23368
23499
|
}
|
|
23500
|
+
try {
|
|
23501
|
+
const workerCompletedEvent = createEvent3("worker_completed", {
|
|
23502
|
+
project_key: args.project_key,
|
|
23503
|
+
epic_id: eventEpicId,
|
|
23504
|
+
bead_id: args.bead_id,
|
|
23505
|
+
worker_agent: args.agent_name,
|
|
23506
|
+
success: true,
|
|
23507
|
+
duration_ms: completionDurationMs,
|
|
23508
|
+
files_touched: args.files_touched || []
|
|
23509
|
+
});
|
|
23510
|
+
await appendEvent2(workerCompletedEvent, args.project_key);
|
|
23511
|
+
} catch (error45) {
|
|
23512
|
+
console.warn("[swarm_complete] Failed to emit worker_completed event:", error45);
|
|
23513
|
+
}
|
|
23369
23514
|
let capturedStrategy;
|
|
23370
|
-
const durationMs = args.start_time ? Date.now() - args.start_time : 0;
|
|
23371
23515
|
const memoryInfo = formatMemoryStoreOnSuccess(args.bead_id, args.summary, args.files_touched || [], capturedStrategy);
|
|
23372
23516
|
let memoryStored = false;
|
|
23373
23517
|
let memoryError;
|
|
@@ -23484,7 +23628,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
|
|
|
23484
23628
|
};
|
|
23485
23629
|
try {
|
|
23486
23630
|
const { captureSubtaskOutcome: captureSubtaskOutcome2 } = await Promise.resolve().then(() => (init_eval_capture(), exports_eval_capture));
|
|
23487
|
-
const
|
|
23631
|
+
const durationMs = args.start_time ? Date.now() - args.start_time : 0;
|
|
23488
23632
|
const evalEpicId = cell.parent_id || epicId2;
|
|
23489
23633
|
captureSubtaskOutcome2({
|
|
23490
23634
|
epicId: evalEpicId,
|
|
@@ -23493,7 +23637,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
|
|
|
23493
23637
|
title: cell.title,
|
|
23494
23638
|
plannedFiles: args.planned_files || [],
|
|
23495
23639
|
actualFiles: args.files_touched || [],
|
|
23496
|
-
durationMs
|
|
23640
|
+
durationMs,
|
|
23497
23641
|
errorCount: args.error_count || 0,
|
|
23498
23642
|
retryCount: args.retry_count || 0,
|
|
23499
23643
|
success: true
|
|
@@ -23502,7 +23646,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
|
|
|
23502
23646
|
console.warn("[swarm_complete] Failed to capture subtask outcome:", error45);
|
|
23503
23647
|
}
|
|
23504
23648
|
try {
|
|
23505
|
-
const
|
|
23649
|
+
const durationMs = args.start_time ? Date.now() - args.start_time : 0;
|
|
23506
23650
|
captureCoordinatorEvent({
|
|
23507
23651
|
session_id: _ctx.sessionID || "unknown",
|
|
23508
23652
|
epic_id: epicId2,
|
|
@@ -23511,7 +23655,7 @@ Files touched: ${args.files_touched?.join(", ") || "none recorded"}`,
|
|
|
23511
23655
|
outcome_type: "subtask_success",
|
|
23512
23656
|
payload: {
|
|
23513
23657
|
bead_id: args.bead_id,
|
|
23514
|
-
duration_ms:
|
|
23658
|
+
duration_ms: durationMs,
|
|
23515
23659
|
files_touched: args.files_touched || [],
|
|
23516
23660
|
verification_passed: verificationResult?.passed ?? false,
|
|
23517
23661
|
verification_skipped: args.skip_verification ?? false
|
|
@@ -23985,7 +24129,7 @@ var swarm_checkpoint = tool({
|
|
|
23985
24129
|
}
|
|
23986
24130
|
};
|
|
23987
24131
|
const checkpointData = JSON.stringify(checkpoint);
|
|
23988
|
-
const event =
|
|
24132
|
+
const event = createEvent3("swarm_checkpointed", {
|
|
23989
24133
|
project_key: args.project_key,
|
|
23990
24134
|
epic_id: args.epic_id,
|
|
23991
24135
|
bead_id: args.bead_id,
|
|
@@ -24027,8 +24171,8 @@ var swarm_recover = tool({
|
|
|
24027
24171
|
},
|
|
24028
24172
|
async execute(args) {
|
|
24029
24173
|
try {
|
|
24030
|
-
const { getSwarmMailLibSQL:
|
|
24031
|
-
const swarmMail = await
|
|
24174
|
+
const { getSwarmMailLibSQL: getSwarmMailLibSQL4 } = await import("swarm-mail");
|
|
24175
|
+
const swarmMail = await getSwarmMailLibSQL4(args.project_key);
|
|
24032
24176
|
const db = await swarmMail.getDatabase();
|
|
24033
24177
|
const result = await db.query(`SELECT * FROM swarm_contexts
|
|
24034
24178
|
WHERE epic_id = $1
|
|
@@ -24055,7 +24199,7 @@ var swarm_recover = tool({
|
|
|
24055
24199
|
created_at: row.created_at,
|
|
24056
24200
|
updated_at: row.updated_at
|
|
24057
24201
|
};
|
|
24058
|
-
const event =
|
|
24202
|
+
const event = createEvent3("swarm_recovered", {
|
|
24059
24203
|
project_key: args.project_key,
|
|
24060
24204
|
epic_id: args.epic_id,
|
|
24061
24205
|
bead_id: context.bead_id,
|
|
@@ -24214,7 +24358,7 @@ init_eval_capture();
|
|
|
24214
24358
|
|
|
24215
24359
|
// src/memory-tools.ts
|
|
24216
24360
|
init_dist();
|
|
24217
|
-
import { getSwarmMailLibSQL as
|
|
24361
|
+
import { getSwarmMailLibSQL as getSwarmMailLibSQL4, createEvent as createEvent4, appendEvent as appendEvent3 } from "swarm-mail";
|
|
24218
24362
|
|
|
24219
24363
|
// ../../node_modules/.bun/effect@3.19.12/node_modules/effect/dist/esm/Function.js
|
|
24220
24364
|
var isFunction = (input) => typeof input === "function";
|
|
@@ -37831,7 +37975,7 @@ async function getMemoryAdapter(projectPath) {
|
|
|
37831
37975
|
if (cachedAdapter && cachedProjectPath === path3) {
|
|
37832
37976
|
return cachedAdapter;
|
|
37833
37977
|
}
|
|
37834
|
-
const swarmMail = await
|
|
37978
|
+
const swarmMail = await getSwarmMailLibSQL4(path3);
|
|
37835
37979
|
const dbAdapter = await swarmMail.getDatabase();
|
|
37836
37980
|
cachedAdapter = await createMemoryAdapter(dbAdapter);
|
|
37837
37981
|
cachedProjectPath = path3;
|
|
@@ -37852,6 +37996,21 @@ var semantic_memory_store = tool({
|
|
|
37852
37996
|
async execute(args2, ctx) {
|
|
37853
37997
|
const adapter = await getMemoryAdapter();
|
|
37854
37998
|
const result = await adapter.store(args2);
|
|
37999
|
+
try {
|
|
38000
|
+
const projectKey = cachedProjectPath || process.cwd();
|
|
38001
|
+
const tags = args2.tags ? args2.tags.split(",").map((t) => t.trim()) : [];
|
|
38002
|
+
const event = createEvent4("memory_stored", {
|
|
38003
|
+
project_key: projectKey,
|
|
38004
|
+
memory_id: result.id,
|
|
38005
|
+
content_preview: args2.information.slice(0, 100),
|
|
38006
|
+
tags,
|
|
38007
|
+
auto_tagged: args2.autoTag,
|
|
38008
|
+
collection: args2.collection
|
|
38009
|
+
});
|
|
38010
|
+
await appendEvent3(event, projectKey);
|
|
38011
|
+
} catch (error45) {
|
|
38012
|
+
console.warn("[semantic_memory_store] Failed to emit memory_stored event:", error45);
|
|
38013
|
+
}
|
|
37855
38014
|
return JSON.stringify(result, null, 2);
|
|
37856
38015
|
}
|
|
37857
38016
|
});
|
|
@@ -37865,8 +38024,25 @@ var semantic_memory_find = tool({
|
|
|
37865
38024
|
fts: tool.schema.boolean().optional().describe("Use full-text search instead of vector search (default: false)")
|
|
37866
38025
|
},
|
|
37867
38026
|
async execute(args2, ctx) {
|
|
38027
|
+
const startTime = Date.now();
|
|
37868
38028
|
const adapter = await getMemoryAdapter();
|
|
37869
38029
|
const result = await adapter.find(args2);
|
|
38030
|
+
const duration3 = Date.now() - startTime;
|
|
38031
|
+
try {
|
|
38032
|
+
const projectKey = cachedProjectPath || process.cwd();
|
|
38033
|
+
const topScore = result.results.length > 0 ? result.results[0].score : undefined;
|
|
38034
|
+
const event = createEvent4("memory_found", {
|
|
38035
|
+
project_key: projectKey,
|
|
38036
|
+
query: args2.query,
|
|
38037
|
+
result_count: result.results.length,
|
|
38038
|
+
top_score: topScore,
|
|
38039
|
+
search_duration_ms: duration3,
|
|
38040
|
+
used_fts: args2.fts
|
|
38041
|
+
});
|
|
38042
|
+
await appendEvent3(event, projectKey);
|
|
38043
|
+
} catch (error45) {
|
|
38044
|
+
console.warn("[semantic_memory_find] Failed to emit memory_found event:", error45);
|
|
38045
|
+
}
|
|
37870
38046
|
return JSON.stringify(result, null, 2);
|
|
37871
38047
|
}
|
|
37872
38048
|
});
|
|
@@ -37889,6 +38065,18 @@ var semantic_memory_remove = tool({
|
|
|
37889
38065
|
async execute(args2, ctx) {
|
|
37890
38066
|
const adapter = await getMemoryAdapter();
|
|
37891
38067
|
const result = await adapter.remove(args2);
|
|
38068
|
+
if (result.success) {
|
|
38069
|
+
try {
|
|
38070
|
+
const projectKey = cachedProjectPath || process.cwd();
|
|
38071
|
+
const event = createEvent4("memory_deleted", {
|
|
38072
|
+
project_key: projectKey,
|
|
38073
|
+
memory_id: args2.id
|
|
38074
|
+
});
|
|
38075
|
+
await appendEvent3(event, projectKey);
|
|
38076
|
+
} catch (error45) {
|
|
38077
|
+
console.warn("[semantic_memory_remove] Failed to emit memory_deleted event:", error45);
|
|
38078
|
+
}
|
|
38079
|
+
}
|
|
37892
38080
|
return JSON.stringify(result, null, 2);
|
|
37893
38081
|
}
|
|
37894
38082
|
});
|
|
@@ -37900,6 +38088,19 @@ var semantic_memory_validate = tool({
|
|
|
37900
38088
|
async execute(args2, ctx) {
|
|
37901
38089
|
const adapter = await getMemoryAdapter();
|
|
37902
38090
|
const result = await adapter.validate(args2);
|
|
38091
|
+
if (result.success) {
|
|
38092
|
+
try {
|
|
38093
|
+
const projectKey = cachedProjectPath || process.cwd();
|
|
38094
|
+
const event = createEvent4("memory_validated", {
|
|
38095
|
+
project_key: projectKey,
|
|
38096
|
+
memory_id: args2.id,
|
|
38097
|
+
decay_reset: true
|
|
38098
|
+
});
|
|
38099
|
+
await appendEvent3(event, projectKey);
|
|
38100
|
+
} catch (error45) {
|
|
38101
|
+
console.warn("[semantic_memory_validate] Failed to emit memory_validated event:", error45);
|
|
38102
|
+
}
|
|
38103
|
+
}
|
|
37903
38104
|
return JSON.stringify(result, null, 2);
|
|
37904
38105
|
}
|
|
37905
38106
|
});
|
|
@@ -37947,6 +38148,18 @@ var semantic_memory_upsert = tool({
|
|
|
37947
38148
|
async execute(args2, ctx) {
|
|
37948
38149
|
const adapter = await getMemoryAdapter();
|
|
37949
38150
|
const result = await adapter.upsert(args2);
|
|
38151
|
+
try {
|
|
38152
|
+
const projectKey = cachedProjectPath || process.cwd();
|
|
38153
|
+
const event = createEvent4("memory_updated", {
|
|
38154
|
+
project_key: projectKey,
|
|
38155
|
+
memory_id: result.memoryId || "unknown",
|
|
38156
|
+
operation: result.operation,
|
|
38157
|
+
reason: result.reason
|
|
38158
|
+
});
|
|
38159
|
+
await appendEvent3(event, projectKey);
|
|
38160
|
+
} catch (error45) {
|
|
38161
|
+
console.warn("[semantic_memory_upsert] Failed to emit memory_updated event:", error45);
|
|
38162
|
+
}
|
|
37950
38163
|
return JSON.stringify(result, null, 2);
|
|
37951
38164
|
}
|
|
37952
38165
|
});
|
|
@@ -39281,9 +39494,9 @@ var swarm_spawn_subtask = tool({
|
|
|
39281
39494
|
}
|
|
39282
39495
|
if (args2.project_path) {
|
|
39283
39496
|
try {
|
|
39284
|
-
const { createEvent:
|
|
39497
|
+
const { createEvent: createEvent5, appendEvent: appendEvent4 } = await import("swarm-mail");
|
|
39285
39498
|
const spawnOrder = 0;
|
|
39286
|
-
const workerSpawnedEvent =
|
|
39499
|
+
const workerSpawnedEvent = createEvent5("worker_spawned", {
|
|
39287
39500
|
project_key: args2.project_path,
|
|
39288
39501
|
epic_id: args2.epic_id,
|
|
39289
39502
|
bead_id: args2.bead_id,
|
|
@@ -39293,7 +39506,7 @@ var swarm_spawn_subtask = tool({
|
|
|
39293
39506
|
spawn_order: spawnOrder,
|
|
39294
39507
|
is_parallel: false
|
|
39295
39508
|
});
|
|
39296
|
-
await
|
|
39509
|
+
await appendEvent4(workerSpawnedEvent, args2.project_path);
|
|
39297
39510
|
} catch (error45) {
|
|
39298
39511
|
console.warn("[swarm_spawn_subtask] Failed to emit WorkerSpawnedEvent:", error45);
|
|
39299
39512
|
}
|
|
@@ -2344,6 +2344,97 @@ Extract from session context:
|
|
|
2344
2344
|
**You are not waiting for instructions. You are the coordinator. Coordinate.**
|
|
2345
2345
|
`;
|
|
2346
2346
|
|
|
2347
|
+
/**
|
|
2348
|
+
* Build dynamic swarm state section from snapshot
|
|
2349
|
+
*
|
|
2350
|
+
* This creates a concrete state summary with actual IDs and status
|
|
2351
|
+
* to prepend to the static compaction context.
|
|
2352
|
+
*/
|
|
2353
|
+
function buildDynamicStateFromSnapshot(snapshot: SwarmStateSnapshot): string {
|
|
2354
|
+
if (!snapshot.epic) {
|
|
2355
|
+
return "";
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
const parts: string[] = [];
|
|
2359
|
+
|
|
2360
|
+
// Header with epic info
|
|
2361
|
+
parts.push(`## 🐝 Current Swarm State\n`);
|
|
2362
|
+
parts.push(`**Epic:** ${snapshot.epic.id} - ${snapshot.epic.title}`);
|
|
2363
|
+
parts.push(`**Status:** ${snapshot.epic.status}`);
|
|
2364
|
+
parts.push(`**Project:** ${projectDirectory}\n`);
|
|
2365
|
+
|
|
2366
|
+
// Subtask breakdown
|
|
2367
|
+
const subtasks = snapshot.epic.subtasks || [];
|
|
2368
|
+
const completed = subtasks.filter(s => s.status === "closed");
|
|
2369
|
+
const inProgress = subtasks.filter(s => s.status === "in_progress");
|
|
2370
|
+
const blocked = subtasks.filter(s => s.status === "blocked");
|
|
2371
|
+
const pending = subtasks.filter(s => s.status === "open");
|
|
2372
|
+
|
|
2373
|
+
parts.push(`**Progress:** ${completed.length}/${subtasks.length} subtasks complete\n`);
|
|
2374
|
+
|
|
2375
|
+
// Immediate actions with real IDs
|
|
2376
|
+
parts.push(`## 1️⃣ IMMEDIATE ACTIONS (Do These FIRST)\n`);
|
|
2377
|
+
parts.push(`1. \`swarm_status(epic_id="${snapshot.epic.id}", project_key="${projectDirectory}")\` - Get current state`);
|
|
2378
|
+
parts.push(`2. \`swarmmail_inbox(limit=5)\` - Check for worker messages`);
|
|
2379
|
+
|
|
2380
|
+
if (inProgress.length > 0) {
|
|
2381
|
+
parts.push(`3. Review in-progress work when workers complete`);
|
|
2382
|
+
}
|
|
2383
|
+
if (pending.length > 0) {
|
|
2384
|
+
const next = pending[0];
|
|
2385
|
+
parts.push(`4. Spawn next subtask: \`swarm_spawn_subtask(bead_id="${next.id}", ...)\``);
|
|
2386
|
+
}
|
|
2387
|
+
if (blocked.length > 0) {
|
|
2388
|
+
parts.push(`5. Unblock: ${blocked.map(s => s.id).join(", ")}`);
|
|
2389
|
+
}
|
|
2390
|
+
parts.push("");
|
|
2391
|
+
|
|
2392
|
+
// Detailed subtask status
|
|
2393
|
+
if (inProgress.length > 0) {
|
|
2394
|
+
parts.push(`### 🚧 In Progress (${inProgress.length})`);
|
|
2395
|
+
for (const s of inProgress) {
|
|
2396
|
+
const files = s.files?.length ? ` (${s.files.slice(0, 3).join(", ")}${s.files.length > 3 ? "..." : ""})` : "";
|
|
2397
|
+
parts.push(`- ${s.id}: ${s.title}${files}`);
|
|
2398
|
+
}
|
|
2399
|
+
parts.push("");
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2402
|
+
if (blocked.length > 0) {
|
|
2403
|
+
parts.push(`### 🚫 Blocked (${blocked.length})`);
|
|
2404
|
+
for (const s of blocked) {
|
|
2405
|
+
parts.push(`- ${s.id}: ${s.title}`);
|
|
2406
|
+
}
|
|
2407
|
+
parts.push("");
|
|
2408
|
+
}
|
|
2409
|
+
|
|
2410
|
+
if (pending.length > 0) {
|
|
2411
|
+
parts.push(`### ⏳ Ready to Spawn (${pending.length})`);
|
|
2412
|
+
for (const s of pending.slice(0, 5)) { // Show first 5
|
|
2413
|
+
const files = s.files?.length ? ` (${s.files.slice(0, 2).join(", ")}${s.files.length > 2 ? "..." : ""})` : "";
|
|
2414
|
+
parts.push(`- ${s.id}: ${s.title}${files}`);
|
|
2415
|
+
}
|
|
2416
|
+
if (pending.length > 5) {
|
|
2417
|
+
parts.push(`- ... and ${pending.length - 5} more`);
|
|
2418
|
+
}
|
|
2419
|
+
parts.push("");
|
|
2420
|
+
}
|
|
2421
|
+
|
|
2422
|
+
if (completed.length > 0) {
|
|
2423
|
+
parts.push(`### ✅ Completed (${completed.length})`);
|
|
2424
|
+
for (const s of completed.slice(-3)) { // Show last 3
|
|
2425
|
+
parts.push(`- ${s.id}: ${s.title} ✓`);
|
|
2426
|
+
}
|
|
2427
|
+
if (completed.length > 3) {
|
|
2428
|
+
parts.push(`- ... and ${completed.length - 3} more`);
|
|
2429
|
+
}
|
|
2430
|
+
parts.push("");
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
parts.push("---\n");
|
|
2434
|
+
|
|
2435
|
+
return parts.join("\n");
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2347
2438
|
/**
|
|
2348
2439
|
* Fallback detection prompt - tells the compactor what to look for
|
|
2349
2440
|
*
|
|
@@ -2610,6 +2701,9 @@ const SwarmPlugin: Plugin = async (
|
|
|
2610
2701
|
has_projection: !!sessionScan.projection?.isSwarm,
|
|
2611
2702
|
});
|
|
2612
2703
|
|
|
2704
|
+
// Hoist snapshot outside try block so it's available in fallback path
|
|
2705
|
+
let snapshot: SwarmStateSnapshot | undefined;
|
|
2706
|
+
|
|
2613
2707
|
try {
|
|
2614
2708
|
// =======================================================================
|
|
2615
2709
|
// PREFER PROJECTION (ground truth from events) OVER HIVE QUERY
|
|
@@ -2617,8 +2711,6 @@ const SwarmPlugin: Plugin = async (
|
|
|
2617
2711
|
// The projection is derived from session events - it's the source of truth.
|
|
2618
2712
|
// Hive query may show all cells closed even if swarm was active.
|
|
2619
2713
|
|
|
2620
|
-
let snapshot: SwarmStateSnapshot;
|
|
2621
|
-
|
|
2622
2714
|
if (sessionScan.projection?.isSwarm) {
|
|
2623
2715
|
// Use projection as primary source - convert to snapshot format
|
|
2624
2716
|
const proj = sessionScan.projection;
|
|
@@ -2801,9 +2893,12 @@ const SwarmPlugin: Plugin = async (
|
|
|
2801
2893
|
});
|
|
2802
2894
|
}
|
|
2803
2895
|
|
|
2804
|
-
// Level 3: Fall back to static context
|
|
2896
|
+
// Level 3: Fall back to static context WITH dynamic state from snapshot
|
|
2805
2897
|
const header = `[Swarm detected: ${detection.reasons.join(", ")}]\n\n`;
|
|
2806
|
-
|
|
2898
|
+
|
|
2899
|
+
// Build dynamic state section if we have snapshot data
|
|
2900
|
+
const dynamicState = snapshot ? buildDynamicStateFromSnapshot(snapshot) : "";
|
|
2901
|
+
const staticContent = header + dynamicState + SWARM_COMPACTION_CONTEXT;
|
|
2807
2902
|
output.context.push(staticContent);
|
|
2808
2903
|
|
|
2809
2904
|
// =======================================================================
|
|
@@ -2811,13 +2906,16 @@ const SwarmPlugin: Plugin = async (
|
|
|
2811
2906
|
// =======================================================================
|
|
2812
2907
|
await captureCompaction(
|
|
2813
2908
|
input.sessionID,
|
|
2814
|
-
"unknown",
|
|
2909
|
+
snapshot?.epic?.id || "unknown",
|
|
2815
2910
|
"context_injected",
|
|
2816
2911
|
{
|
|
2817
2912
|
full_content: staticContent,
|
|
2818
2913
|
content_length: staticContent.length,
|
|
2819
2914
|
injection_method: "output.context.push",
|
|
2820
|
-
context_type: "
|
|
2915
|
+
context_type: "static_with_dynamic_state",
|
|
2916
|
+
has_dynamic_state: !!dynamicState,
|
|
2917
|
+
epic_id: snapshot?.epic?.id,
|
|
2918
|
+
subtask_count: snapshot?.epic?.subtasks?.length ?? 0,
|
|
2821
2919
|
},
|
|
2822
2920
|
);
|
|
2823
2921
|
|
|
@@ -2826,9 +2924,12 @@ const SwarmPlugin: Plugin = async (
|
|
|
2826
2924
|
session_id: input.sessionID,
|
|
2827
2925
|
total_duration_ms: totalDuration,
|
|
2828
2926
|
confidence: detection.confidence,
|
|
2829
|
-
context_type: "static_swarm_context",
|
|
2927
|
+
context_type: dynamicState ? "static_with_dynamic_state" : "static_swarm_context",
|
|
2830
2928
|
content_length: staticContent.length,
|
|
2831
2929
|
context_count_after: output.context.length,
|
|
2930
|
+
has_dynamic_state: !!dynamicState,
|
|
2931
|
+
epic_id: snapshot?.epic?.id,
|
|
2932
|
+
subtask_count: snapshot?.epic?.subtasks?.length ?? 0,
|
|
2832
2933
|
});
|
|
2833
2934
|
} else if (detection.confidence === "low") {
|
|
2834
2935
|
// Level 4: Possible swarm - inject fallback detection prompt
|