opencode-swarm-plugin 0.44.1 → 0.45.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 +277 -54
- package/bin/swarm.ts +3 -3
- package/dist/decision-trace-integration.d.ts +204 -0
- package/dist/decision-trace-integration.d.ts.map +1 -0
- package/dist/hive.d.ts.map +1 -1
- package/dist/hive.js +14834 -0
- package/dist/index.d.ts +50 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +640 -27
- package/dist/plugin.js +395 -27
- package/dist/query-tools.d.ts +20 -12
- package/dist/query-tools.d.ts.map +1 -1
- package/dist/swarm-decompose.d.ts +4 -4
- package/dist/swarm-decompose.d.ts.map +1 -1
- package/dist/swarm-prompts.d.ts.map +1 -1
- package/dist/swarm-prompts.js +39605 -0
- package/dist/swarm-review.d.ts.map +1 -1
- package/dist/swarm-signature.d.ts +106 -0
- package/dist/swarm-signature.d.ts.map +1 -0
- package/dist/swarm-strategies.d.ts +16 -3
- package/dist/swarm-strategies.d.ts.map +1 -1
- package/dist/swarm-validation.d.ts +127 -0
- package/dist/swarm-validation.d.ts.map +1 -0
- package/dist/swarm.d.ts +4 -2
- package/dist/swarm.d.ts.map +1 -1
- package/dist/validators/index.d.ts +7 -0
- package/dist/validators/index.d.ts.map +1 -0
- package/dist/validators/schema-validator.d.ts +58 -0
- package/dist/validators/schema-validator.d.ts.map +1 -0
- package/examples/commands/swarm.md +745 -0
- package/examples/plugin-wrapper-template.ts +2611 -0
- package/examples/skills/hive-workflow/SKILL.md +212 -0
- package/examples/skills/skill-creator/SKILL.md +223 -0
- package/examples/skills/swarm-coordination/SKILL.md +292 -0
- package/global-skills/cli-builder/SKILL.md +344 -0
- package/global-skills/cli-builder/references/advanced-patterns.md +244 -0
- package/global-skills/learning-systems/SKILL.md +644 -0
- package/global-skills/skill-creator/LICENSE.txt +202 -0
- package/global-skills/skill-creator/SKILL.md +352 -0
- package/global-skills/skill-creator/references/output-patterns.md +82 -0
- package/global-skills/skill-creator/references/workflows.md +28 -0
- package/global-skills/swarm-coordination/SKILL.md +995 -0
- package/global-skills/swarm-coordination/references/coordinator-patterns.md +235 -0
- package/global-skills/swarm-coordination/references/strategies.md +138 -0
- package/global-skills/system-design/SKILL.md +213 -0
- package/global-skills/testing-patterns/SKILL.md +430 -0
- package/global-skills/testing-patterns/references/dependency-breaking-catalog.md +586 -0
- package/package.json +6 -3
package/dist/plugin.js
CHANGED
|
@@ -13177,6 +13177,74 @@ var init_eval_capture = __esm(() => {
|
|
|
13177
13177
|
inProgressRecords = new Map;
|
|
13178
13178
|
});
|
|
13179
13179
|
|
|
13180
|
+
// src/swarm-validation.ts
|
|
13181
|
+
var exports_swarm_validation = {};
|
|
13182
|
+
__export(exports_swarm_validation, {
|
|
13183
|
+
runPostSwarmValidation: () => runPostSwarmValidation,
|
|
13184
|
+
reportIssue: () => reportIssue,
|
|
13185
|
+
ValidationIssueSeverity: () => ValidationIssueSeverity,
|
|
13186
|
+
ValidationIssueSchema: () => ValidationIssueSchema,
|
|
13187
|
+
ValidationIssueCategory: () => ValidationIssueCategory
|
|
13188
|
+
});
|
|
13189
|
+
async function runPostSwarmValidation(ctx, events) {
|
|
13190
|
+
const startTime = Date.now();
|
|
13191
|
+
const issues = [];
|
|
13192
|
+
await ctx.emit({
|
|
13193
|
+
type: "validation_started",
|
|
13194
|
+
project_key: ctx.project_key,
|
|
13195
|
+
timestamp: startTime,
|
|
13196
|
+
epic_id: ctx.epic_id,
|
|
13197
|
+
swarm_id: ctx.swarm_id,
|
|
13198
|
+
started_at: ctx.started_at.getTime()
|
|
13199
|
+
});
|
|
13200
|
+
const duration_ms = Date.now() - startTime;
|
|
13201
|
+
await ctx.emit({
|
|
13202
|
+
type: "validation_completed",
|
|
13203
|
+
project_key: ctx.project_key,
|
|
13204
|
+
timestamp: Date.now(),
|
|
13205
|
+
epic_id: ctx.epic_id,
|
|
13206
|
+
swarm_id: ctx.swarm_id,
|
|
13207
|
+
passed: issues.length === 0,
|
|
13208
|
+
issue_count: issues.length,
|
|
13209
|
+
duration_ms
|
|
13210
|
+
});
|
|
13211
|
+
return { passed: issues.length === 0, issues };
|
|
13212
|
+
}
|
|
13213
|
+
async function reportIssue(ctx, issue2) {
|
|
13214
|
+
await ctx.emit({
|
|
13215
|
+
type: "validation_issue",
|
|
13216
|
+
project_key: ctx.project_key,
|
|
13217
|
+
timestamp: new Date().toISOString(),
|
|
13218
|
+
epic_id: ctx.epic_id,
|
|
13219
|
+
severity: issue2.severity,
|
|
13220
|
+
category: issue2.category,
|
|
13221
|
+
message: issue2.message,
|
|
13222
|
+
location: issue2.location
|
|
13223
|
+
});
|
|
13224
|
+
}
|
|
13225
|
+
var ValidationIssueSeverity, ValidationIssueCategory, ValidationIssueSchema;
|
|
13226
|
+
var init_swarm_validation = __esm(() => {
|
|
13227
|
+
init_zod();
|
|
13228
|
+
ValidationIssueSeverity = exports_external.enum(["error", "warning", "info"]);
|
|
13229
|
+
ValidationIssueCategory = exports_external.enum([
|
|
13230
|
+
"schema_mismatch",
|
|
13231
|
+
"missing_event",
|
|
13232
|
+
"undefined_value",
|
|
13233
|
+
"dashboard_render",
|
|
13234
|
+
"websocket_delivery"
|
|
13235
|
+
]);
|
|
13236
|
+
ValidationIssueSchema = exports_external.object({
|
|
13237
|
+
severity: ValidationIssueSeverity,
|
|
13238
|
+
category: ValidationIssueCategory,
|
|
13239
|
+
message: exports_external.string(),
|
|
13240
|
+
location: exports_external.object({
|
|
13241
|
+
event_type: exports_external.string().optional(),
|
|
13242
|
+
field: exports_external.string().optional(),
|
|
13243
|
+
component: exports_external.string().optional()
|
|
13244
|
+
}).optional()
|
|
13245
|
+
});
|
|
13246
|
+
});
|
|
13247
|
+
|
|
13180
13248
|
// ../../node_modules/.bun/@ioredis+commands@1.4.0/node_modules/@ioredis/commands/built/commands.json
|
|
13181
13249
|
var require_commands = __commonJS((exports, module) => {
|
|
13182
13250
|
module.exports = {
|
|
@@ -22492,7 +22560,7 @@ __export(exports_swarm_strategies, {
|
|
|
22492
22560
|
NEGATIVE_MARKERS: () => NEGATIVE_MARKERS,
|
|
22493
22561
|
DecompositionStrategySchema: () => DecompositionStrategySchema
|
|
22494
22562
|
});
|
|
22495
|
-
function selectStrategy(task) {
|
|
22563
|
+
async function selectStrategy(task, projectKey) {
|
|
22496
22564
|
const taskLower = task.toLowerCase();
|
|
22497
22565
|
const scores = {
|
|
22498
22566
|
"file-based": 0,
|
|
@@ -22520,7 +22588,8 @@ function selectStrategy(task) {
|
|
|
22520
22588
|
const [winner, winnerScore] = entries[0];
|
|
22521
22589
|
const [, runnerUpScore] = entries[1] || [null, 0];
|
|
22522
22590
|
const totalScore = entries.reduce((sum, [, score]) => sum + score, 0);
|
|
22523
|
-
|
|
22591
|
+
let confidence = totalScore > 0 ? Math.min(0.95, 0.5 + (winnerScore - runnerUpScore) / totalScore) : 0.5;
|
|
22592
|
+
const finalStrategy = winnerScore === 0 ? "feature-based" : winner;
|
|
22524
22593
|
let reasoning;
|
|
22525
22594
|
if (winnerScore === 0) {
|
|
22526
22595
|
reasoning = `No strong keyword signals. Defaulting to feature-based as it's most versatile.`;
|
|
@@ -22528,12 +22597,73 @@ function selectStrategy(task) {
|
|
|
22528
22597
|
const matchedKeywords = STRATEGIES[winner].keywords.filter((k) => taskLower.includes(k));
|
|
22529
22598
|
reasoning = `Matched keywords: ${matchedKeywords.join(", ")}. ${STRATEGIES[winner].description}`;
|
|
22530
22599
|
}
|
|
22531
|
-
|
|
22600
|
+
let precedent;
|
|
22601
|
+
if (projectKey) {
|
|
22602
|
+
try {
|
|
22603
|
+
const {
|
|
22604
|
+
createLibSQLAdapter,
|
|
22605
|
+
getDatabasePath,
|
|
22606
|
+
findSimilarDecisions,
|
|
22607
|
+
getStrategySuccessRates
|
|
22608
|
+
} = await import("swarm-mail");
|
|
22609
|
+
const dbPath = getDatabasePath(projectKey);
|
|
22610
|
+
const db = await createLibSQLAdapter({ url: `file:${dbPath}` });
|
|
22611
|
+
const similarDecisions = await findSimilarDecisions(db, task, 5);
|
|
22612
|
+
const successRates = await getStrategySuccessRates(db);
|
|
22613
|
+
precedent = {
|
|
22614
|
+
similar_decisions: similarDecisions.length
|
|
22615
|
+
};
|
|
22616
|
+
if (similarDecisions.length > 0) {
|
|
22617
|
+
const epicIds = [];
|
|
22618
|
+
for (const decision of similarDecisions) {
|
|
22619
|
+
try {
|
|
22620
|
+
const decisionData = typeof decision.decision === "string" ? JSON.parse(decision.decision) : decision.decision;
|
|
22621
|
+
if (decisionData.epic_id) {
|
|
22622
|
+
epicIds.push(decisionData.epic_id);
|
|
22623
|
+
}
|
|
22624
|
+
} catch {}
|
|
22625
|
+
}
|
|
22626
|
+
if (epicIds.length > 0) {
|
|
22627
|
+
precedent.cited_epics = epicIds;
|
|
22628
|
+
}
|
|
22629
|
+
const precedentStrategies = similarDecisions.map((d) => {
|
|
22630
|
+
try {
|
|
22631
|
+
const data = typeof d.decision === "string" ? JSON.parse(d.decision) : d.decision;
|
|
22632
|
+
return data.strategy;
|
|
22633
|
+
} catch {
|
|
22634
|
+
return null;
|
|
22635
|
+
}
|
|
22636
|
+
}).filter(Boolean);
|
|
22637
|
+
const agreesWithKeywords = precedentStrategies.includes(finalStrategy);
|
|
22638
|
+
if (agreesWithKeywords) {
|
|
22639
|
+
confidence = Math.min(0.95, confidence + 0.1);
|
|
22640
|
+
reasoning += ` Precedent confirms: ${precedent.similar_decisions} similar decision(s) also chose ${finalStrategy}.`;
|
|
22641
|
+
}
|
|
22642
|
+
}
|
|
22643
|
+
const strategyRate = successRates.find((r) => r.strategy === finalStrategy);
|
|
22644
|
+
if (strategyRate) {
|
|
22645
|
+
precedent.strategy_success_rate = strategyRate.success_rate;
|
|
22646
|
+
if (strategyRate.success_rate >= 0.7) {
|
|
22647
|
+
confidence = Math.min(0.95, confidence + 0.05);
|
|
22648
|
+
reasoning += ` ${finalStrategy} has ${Math.round(strategyRate.success_rate * 100)}% success rate.`;
|
|
22649
|
+
} else if (strategyRate.success_rate < 0.3) {
|
|
22650
|
+
confidence = Math.max(0.1, confidence - 0.1);
|
|
22651
|
+
reasoning += ` Warning: ${finalStrategy} has low success rate (${Math.round(strategyRate.success_rate * 100)}%).`;
|
|
22652
|
+
}
|
|
22653
|
+
}
|
|
22654
|
+
if (db.close) {
|
|
22655
|
+
await db.close();
|
|
22656
|
+
}
|
|
22657
|
+
} catch (error45) {
|
|
22658
|
+
console.warn("Failed to query precedent data:", error45);
|
|
22659
|
+
}
|
|
22660
|
+
}
|
|
22532
22661
|
return {
|
|
22533
22662
|
strategy: finalStrategy,
|
|
22534
22663
|
confidence,
|
|
22535
22664
|
reasoning,
|
|
22536
|
-
alternatives: entries.filter(([s]) => s !== finalStrategy).map(([strategy, score]) => ({ strategy, score }))
|
|
22665
|
+
alternatives: entries.filter(([s]) => s !== finalStrategy).map(([strategy, score]) => ({ strategy, score })),
|
|
22666
|
+
precedent
|
|
22537
22667
|
};
|
|
22538
22668
|
}
|
|
22539
22669
|
function formatStrategyGuidelines(strategy) {
|
|
@@ -22742,13 +22872,14 @@ var init_swarm_strategies = __esm(() => {
|
|
|
22742
22872
|
}
|
|
22743
22873
|
};
|
|
22744
22874
|
swarm_select_strategy = tool({
|
|
22745
|
-
description: "Analyze task and recommend decomposition strategy (file-based, feature-based, or risk-based)",
|
|
22875
|
+
description: "Analyze task and recommend decomposition strategy (file-based, feature-based, or risk-based) with optional precedent data",
|
|
22746
22876
|
args: {
|
|
22747
22877
|
task: tool.schema.string().min(1).describe("Task description to analyze"),
|
|
22748
|
-
codebase_context: tool.schema.string().optional().describe("Optional codebase context (file structure, tech stack, etc.)")
|
|
22878
|
+
codebase_context: tool.schema.string().optional().describe("Optional codebase context (file structure, tech stack, etc.)"),
|
|
22879
|
+
projectKey: tool.schema.string().optional().describe("Optional project path for precedent-aware strategy selection")
|
|
22749
22880
|
},
|
|
22750
22881
|
async execute(args) {
|
|
22751
|
-
const result = selectStrategy(args.task);
|
|
22882
|
+
const result = await selectStrategy(args.task, args.projectKey);
|
|
22752
22883
|
let enhancedReasoning = result.reasoning;
|
|
22753
22884
|
if (args.codebase_context) {
|
|
22754
22885
|
enhancedReasoning += `
|
|
@@ -22766,7 +22897,8 @@ Codebase context considered: ${args.codebase_context.slice(0, 200)}...`;
|
|
|
22766
22897
|
strategy: alt.strategy,
|
|
22767
22898
|
description: STRATEGIES[alt.strategy].description,
|
|
22768
22899
|
score: alt.score
|
|
22769
|
-
}))
|
|
22900
|
+
})),
|
|
22901
|
+
precedent: result.precedent
|
|
22770
22902
|
}, null, 2);
|
|
22771
22903
|
}
|
|
22772
22904
|
});
|
|
@@ -38949,7 +39081,8 @@ import {
|
|
|
38949
39081
|
importFromJSONL,
|
|
38950
39082
|
syncMemories,
|
|
38951
39083
|
getSwarmMailLibSQL,
|
|
38952
|
-
resolvePartialId
|
|
39084
|
+
resolvePartialId,
|
|
39085
|
+
findCellsByPartialId
|
|
38953
39086
|
} from "swarm-mail";
|
|
38954
39087
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
38955
39088
|
import { join as join2 } from "node:path";
|
|
@@ -39972,6 +40105,37 @@ var hive_close = tool({
|
|
|
39972
40105
|
total_files_touched: totalFilesTouched
|
|
39973
40106
|
});
|
|
39974
40107
|
await appendEvent2(swarmCompletedEvent, projectKey);
|
|
40108
|
+
try {
|
|
40109
|
+
const { runPostSwarmValidation: runPostSwarmValidation2 } = await Promise.resolve().then(() => (init_swarm_validation(), exports_swarm_validation));
|
|
40110
|
+
const { readEvents } = await import("swarm-mail");
|
|
40111
|
+
const swarmEvents = await readEvents({
|
|
40112
|
+
projectKey,
|
|
40113
|
+
types: [
|
|
40114
|
+
"swarm_started",
|
|
40115
|
+
"swarm_completed",
|
|
40116
|
+
"worker_spawned",
|
|
40117
|
+
"subtask_outcome",
|
|
40118
|
+
"decomposition_generated"
|
|
40119
|
+
]
|
|
40120
|
+
}, projectKey);
|
|
40121
|
+
runPostSwarmValidation2({
|
|
40122
|
+
project_key: projectKey,
|
|
40123
|
+
epic_id: cellId,
|
|
40124
|
+
swarm_id: cellId,
|
|
40125
|
+
started_at: new Date,
|
|
40126
|
+
emit: async (event) => {
|
|
40127
|
+
await appendEvent2(event, projectKey);
|
|
40128
|
+
}
|
|
40129
|
+
}, swarmEvents).then((result) => {
|
|
40130
|
+
if (!result.passed) {
|
|
40131
|
+
console.warn(`[Validation] Found ${result.issues.length} issues in swarm ${cellId}`);
|
|
40132
|
+
}
|
|
40133
|
+
}).catch((err) => {
|
|
40134
|
+
console.error(`[Validation] Failed:`, err);
|
|
40135
|
+
});
|
|
40136
|
+
} catch (error45) {
|
|
40137
|
+
console.warn("[hive_close] Validation hook failed (non-fatal):", error45);
|
|
40138
|
+
}
|
|
39975
40139
|
} catch (error45) {
|
|
39976
40140
|
console.warn("[hive_close] Failed to emit SwarmCompletedEvent:", error45);
|
|
39977
40141
|
}
|
|
@@ -40065,13 +40229,12 @@ PREFER THIS OVER hive_query when you need to:
|
|
|
40065
40229
|
const adapter = await getHiveAdapter(projectKey);
|
|
40066
40230
|
try {
|
|
40067
40231
|
if (args.id) {
|
|
40068
|
-
const
|
|
40069
|
-
|
|
40070
|
-
if (!cell) {
|
|
40232
|
+
const matchingCells = await findCellsByPartialId(adapter, projectKey, args.id);
|
|
40233
|
+
if (matchingCells.length === 0) {
|
|
40071
40234
|
throw new HiveError(`No cell found matching ID '${args.id}'`, "hive_cells");
|
|
40072
40235
|
}
|
|
40073
|
-
const formatted2 = formatCellForOutput(
|
|
40074
|
-
return JSON.stringify(
|
|
40236
|
+
const formatted2 = matchingCells.map((c) => formatCellForOutput(c));
|
|
40237
|
+
return JSON.stringify(formatted2, null, 2);
|
|
40075
40238
|
}
|
|
40076
40239
|
if (args.ready) {
|
|
40077
40240
|
const ready = await adapter.getNextReadyCell(projectKey);
|
|
@@ -40090,10 +40253,10 @@ PREFER THIS OVER hive_query when you need to:
|
|
|
40090
40253
|
const formatted = cells.map((c) => formatCellForOutput(c));
|
|
40091
40254
|
return JSON.stringify(formatted, null, 2);
|
|
40092
40255
|
} catch (error45) {
|
|
40093
|
-
|
|
40094
|
-
|
|
40095
|
-
throw new HiveError(`Ambiguous ID '${args.id}': multiple cells match. Please provide more characters.`, "hive_cells");
|
|
40256
|
+
if (error45 instanceof HiveError) {
|
|
40257
|
+
throw error45;
|
|
40096
40258
|
}
|
|
40259
|
+
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
40097
40260
|
if (message.includes("Bead not found") || message.includes("Cell not found")) {
|
|
40098
40261
|
throw new HiveError(`No cell found matching ID '${args.id || "unknown"}'`, "hive_cells");
|
|
40099
40262
|
}
|
|
@@ -42402,6 +42565,139 @@ init_dist();
|
|
|
42402
42565
|
init_zod();
|
|
42403
42566
|
init_swarm_strategies();
|
|
42404
42567
|
init_eval_capture();
|
|
42568
|
+
|
|
42569
|
+
// src/decision-trace-integration.ts
|
|
42570
|
+
import {
|
|
42571
|
+
createDecisionTrace,
|
|
42572
|
+
createEntityLink
|
|
42573
|
+
} from "swarm-mail";
|
|
42574
|
+
import { createLibSQLAdapter } from "swarm-mail";
|
|
42575
|
+
import { getDatabasePath } from "swarm-mail";
|
|
42576
|
+
async function getTraceDb(projectPath) {
|
|
42577
|
+
const dbPath = getDatabasePath(projectPath);
|
|
42578
|
+
return createLibSQLAdapter({ url: `file:${dbPath}` });
|
|
42579
|
+
}
|
|
42580
|
+
function extractMemoryIds(precedentCited) {
|
|
42581
|
+
if (!precedentCited) {
|
|
42582
|
+
return [];
|
|
42583
|
+
}
|
|
42584
|
+
if (precedentCited.memoryIds && Array.isArray(precedentCited.memoryIds)) {
|
|
42585
|
+
return precedentCited.memoryIds;
|
|
42586
|
+
}
|
|
42587
|
+
if (precedentCited.memoryId) {
|
|
42588
|
+
return [precedentCited.memoryId];
|
|
42589
|
+
}
|
|
42590
|
+
return [];
|
|
42591
|
+
}
|
|
42592
|
+
async function traceStrategySelection(input) {
|
|
42593
|
+
try {
|
|
42594
|
+
const db = await getTraceDb(input.projectKey);
|
|
42595
|
+
const trace = await createDecisionTrace(db, {
|
|
42596
|
+
decision_type: "strategy_selection",
|
|
42597
|
+
epic_id: input.epicId,
|
|
42598
|
+
bead_id: input.beadId,
|
|
42599
|
+
agent_name: input.agentName,
|
|
42600
|
+
project_key: input.projectKey,
|
|
42601
|
+
decision: {
|
|
42602
|
+
strategy: input.strategy,
|
|
42603
|
+
confidence: input.confidence,
|
|
42604
|
+
task_preview: input.taskPreview
|
|
42605
|
+
},
|
|
42606
|
+
rationale: input.reasoning,
|
|
42607
|
+
inputs_gathered: input.inputsGathered,
|
|
42608
|
+
alternatives: input.alternatives,
|
|
42609
|
+
precedent_cited: input.precedentCited
|
|
42610
|
+
});
|
|
42611
|
+
const memoryIds = extractMemoryIds(input.precedentCited);
|
|
42612
|
+
for (const memoryId of memoryIds) {
|
|
42613
|
+
await createEntityLink(db, {
|
|
42614
|
+
source_decision_id: trace.id,
|
|
42615
|
+
target_entity_type: "memory",
|
|
42616
|
+
target_entity_id: memoryId,
|
|
42617
|
+
link_type: "cites_precedent",
|
|
42618
|
+
strength: input.precedentCited?.similarity ?? 1,
|
|
42619
|
+
context: "Cited as precedent for strategy selection"
|
|
42620
|
+
});
|
|
42621
|
+
}
|
|
42622
|
+
await db.close?.();
|
|
42623
|
+
return trace.id;
|
|
42624
|
+
} catch (error45) {
|
|
42625
|
+
console.warn("[decision-trace] Failed to trace strategy_selection:", error45);
|
|
42626
|
+
return "";
|
|
42627
|
+
}
|
|
42628
|
+
}
|
|
42629
|
+
async function traceWorkerSpawn(input) {
|
|
42630
|
+
try {
|
|
42631
|
+
const db = await getTraceDb(input.projectKey);
|
|
42632
|
+
const trace = await createDecisionTrace(db, {
|
|
42633
|
+
decision_type: "worker_spawn",
|
|
42634
|
+
epic_id: input.epicId,
|
|
42635
|
+
bead_id: input.beadId,
|
|
42636
|
+
agent_name: input.agentName,
|
|
42637
|
+
project_key: input.projectKey,
|
|
42638
|
+
decision: {
|
|
42639
|
+
worker: input.workerName || "worker",
|
|
42640
|
+
subtask_title: input.subtaskTitle,
|
|
42641
|
+
files: input.files,
|
|
42642
|
+
model: input.model,
|
|
42643
|
+
spawn_order: input.spawnOrder,
|
|
42644
|
+
is_parallel: input.isParallel
|
|
42645
|
+
},
|
|
42646
|
+
rationale: input.rationale || `Spawning worker for: ${input.subtaskTitle}`
|
|
42647
|
+
});
|
|
42648
|
+
for (const file2 of input.files) {
|
|
42649
|
+
await createEntityLink(db, {
|
|
42650
|
+
source_decision_id: trace.id,
|
|
42651
|
+
target_entity_type: "file",
|
|
42652
|
+
target_entity_id: file2,
|
|
42653
|
+
link_type: "assigns_file",
|
|
42654
|
+
strength: 1,
|
|
42655
|
+
context: `File assigned to worker ${input.workerName || "worker"}`
|
|
42656
|
+
});
|
|
42657
|
+
}
|
|
42658
|
+
await db.close?.();
|
|
42659
|
+
return trace.id;
|
|
42660
|
+
} catch (error45) {
|
|
42661
|
+
console.warn("[decision-trace] Failed to trace worker_spawn:", error45);
|
|
42662
|
+
return "";
|
|
42663
|
+
}
|
|
42664
|
+
}
|
|
42665
|
+
async function traceReviewDecision(input) {
|
|
42666
|
+
try {
|
|
42667
|
+
const db = await getTraceDb(input.projectKey);
|
|
42668
|
+
const trace = await createDecisionTrace(db, {
|
|
42669
|
+
decision_type: "review_decision",
|
|
42670
|
+
epic_id: input.epicId,
|
|
42671
|
+
bead_id: input.beadId,
|
|
42672
|
+
agent_name: input.agentName,
|
|
42673
|
+
project_key: input.projectKey,
|
|
42674
|
+
decision: {
|
|
42675
|
+
status: input.status,
|
|
42676
|
+
worker_id: input.workerId,
|
|
42677
|
+
issues_count: input.issues?.length || 0,
|
|
42678
|
+
attempt_number: input.attemptNumber,
|
|
42679
|
+
remaining_attempts: input.remainingAttempts
|
|
42680
|
+
},
|
|
42681
|
+
rationale: input.rationale || input.summary || `Review ${input.status}`,
|
|
42682
|
+
inputs_gathered: input.issues ? [{ source: "code_review", issues: input.issues }] : undefined
|
|
42683
|
+
});
|
|
42684
|
+
await createEntityLink(db, {
|
|
42685
|
+
source_decision_id: trace.id,
|
|
42686
|
+
target_entity_type: "agent",
|
|
42687
|
+
target_entity_id: input.workerId,
|
|
42688
|
+
link_type: "reviewed_work_by",
|
|
42689
|
+
strength: 1,
|
|
42690
|
+
context: `Review ${input.status} for ${input.workerId}`
|
|
42691
|
+
});
|
|
42692
|
+
await db.close?.();
|
|
42693
|
+
return trace.id;
|
|
42694
|
+
} catch (error45) {
|
|
42695
|
+
console.warn("[decision-trace] Failed to trace review_decision:", error45);
|
|
42696
|
+
return "";
|
|
42697
|
+
}
|
|
42698
|
+
}
|
|
42699
|
+
|
|
42700
|
+
// src/swarm-decompose.ts
|
|
42405
42701
|
var DECOMPOSITION_PROMPT = `You are decomposing a task into parallelizable subtasks for a swarm of agents.
|
|
42406
42702
|
|
|
42407
42703
|
## Task
|
|
@@ -42833,7 +43129,7 @@ var swarm_delegate_planning = tool({
|
|
|
42833
43129
|
selectedStrategy = args.strategy;
|
|
42834
43130
|
strategyReasoning = `User-specified strategy: ${selectedStrategy}`;
|
|
42835
43131
|
} else {
|
|
42836
|
-
const selection = selectStrategy2(args.task);
|
|
43132
|
+
const selection = await selectStrategy2(args.task);
|
|
42837
43133
|
selectedStrategy = selection.strategy;
|
|
42838
43134
|
strategyReasoning = selection.reasoning;
|
|
42839
43135
|
}
|
|
@@ -42875,6 +43171,27 @@ var swarm_delegate_planning = tool({
|
|
|
42875
43171
|
} else {
|
|
42876
43172
|
cassResultInfo = { queried: false, reason: "disabled" };
|
|
42877
43173
|
}
|
|
43174
|
+
try {
|
|
43175
|
+
await traceStrategySelection({
|
|
43176
|
+
projectKey: args.context?.includes("/") ? args.context.split(" ")[0] : process.cwd(),
|
|
43177
|
+
agentName: "coordinator",
|
|
43178
|
+
epicId: undefined,
|
|
43179
|
+
strategy: selectedStrategy,
|
|
43180
|
+
reasoning: strategyReasoning,
|
|
43181
|
+
confidence: undefined,
|
|
43182
|
+
taskPreview: args.task.slice(0, 200),
|
|
43183
|
+
inputsGathered: cassResultInfo.queried ? [
|
|
43184
|
+
{
|
|
43185
|
+
source: "cass",
|
|
43186
|
+
query: args.task,
|
|
43187
|
+
results: cassResultInfo.results_found ?? 0
|
|
43188
|
+
}
|
|
43189
|
+
] : undefined,
|
|
43190
|
+
alternatives: undefined
|
|
43191
|
+
});
|
|
43192
|
+
} catch (error45) {
|
|
43193
|
+
console.warn("[swarm_delegate_planning] Failed to trace strategy_selection:", error45);
|
|
43194
|
+
}
|
|
42878
43195
|
let skillsContext = "";
|
|
42879
43196
|
let skillsInfo = {
|
|
42880
43197
|
included: false
|
|
@@ -42993,7 +43310,7 @@ Limit: ${memoryQuery.limit}`;
|
|
|
42993
43310
|
}
|
|
42994
43311
|
} catch (error45) {}
|
|
42995
43312
|
if (mode === "fast") {
|
|
42996
|
-
const strategyResult = selectStrategy2(args.task);
|
|
43313
|
+
const strategyResult = await selectStrategy2(args.task);
|
|
42997
43314
|
const guidelines = formatStrategyGuidelines2(strategyResult.strategy);
|
|
42998
43315
|
const output = {
|
|
42999
43316
|
mode: "fast",
|
|
@@ -43012,7 +43329,7 @@ ${guidelines}`
|
|
|
43012
43329
|
return JSON.stringify(output, null, 2);
|
|
43013
43330
|
}
|
|
43014
43331
|
if (mode === "auto") {
|
|
43015
|
-
const strategyResult = selectStrategy2(args.task);
|
|
43332
|
+
const strategyResult = await selectStrategy2(args.task);
|
|
43016
43333
|
const output = {
|
|
43017
43334
|
mode: "auto",
|
|
43018
43335
|
phase: "ready",
|
|
@@ -43107,7 +43424,7 @@ ${guidelines}`
|
|
|
43107
43424
|
return JSON.stringify(output, null, 2);
|
|
43108
43425
|
}
|
|
43109
43426
|
if (currentPhase === "alternatives") {
|
|
43110
|
-
const strategyResult = selectStrategy2(args.task);
|
|
43427
|
+
const strategyResult = await selectStrategy2(args.task);
|
|
43111
43428
|
const alternatives = [];
|
|
43112
43429
|
alternatives.push({
|
|
43113
43430
|
name: strategyResult.strategy,
|
|
@@ -43134,7 +43451,7 @@ ${guidelines}`
|
|
|
43134
43451
|
return JSON.stringify(output, null, 2);
|
|
43135
43452
|
}
|
|
43136
43453
|
if (currentPhase === "recommendation") {
|
|
43137
|
-
const strategyResult = selectStrategy2(args.task);
|
|
43454
|
+
const strategyResult = await selectStrategy2(args.task);
|
|
43138
43455
|
const guidelines = formatStrategyGuidelines2(strategyResult.strategy);
|
|
43139
43456
|
const output = {
|
|
43140
43457
|
mode: "socratic",
|
|
@@ -45205,6 +45522,22 @@ var swarm_review_feedback = tool({
|
|
|
45205
45522
|
} catch (error45) {
|
|
45206
45523
|
console.warn("[swarm_review_feedback] Failed to capture review_completed:", error45);
|
|
45207
45524
|
}
|
|
45525
|
+
try {
|
|
45526
|
+
await traceReviewDecision({
|
|
45527
|
+
projectKey: args.project_key,
|
|
45528
|
+
agentName: "coordinator",
|
|
45529
|
+
epicId,
|
|
45530
|
+
beadId: args.task_id,
|
|
45531
|
+
workerId: args.worker_id,
|
|
45532
|
+
status: "approved",
|
|
45533
|
+
summary: args.summary,
|
|
45534
|
+
attemptNumber: 1,
|
|
45535
|
+
remainingAttempts: MAX_REVIEW_ATTEMPTS,
|
|
45536
|
+
rationale: args.summary || "Review approved"
|
|
45537
|
+
});
|
|
45538
|
+
} catch (error45) {
|
|
45539
|
+
console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
|
|
45540
|
+
}
|
|
45208
45541
|
try {
|
|
45209
45542
|
const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
|
|
45210
45543
|
const attempt = getReviewStatus(args.task_id).attempt_count || 1;
|
|
@@ -45259,6 +45592,23 @@ You may now complete the task with \`swarm_complete\`.`,
|
|
|
45259
45592
|
} catch (error45) {
|
|
45260
45593
|
console.warn("[swarm_review_feedback] Failed to capture review_completed:", error45);
|
|
45261
45594
|
}
|
|
45595
|
+
try {
|
|
45596
|
+
await traceReviewDecision({
|
|
45597
|
+
projectKey: args.project_key,
|
|
45598
|
+
agentName: "coordinator",
|
|
45599
|
+
epicId,
|
|
45600
|
+
beadId: args.task_id,
|
|
45601
|
+
workerId: args.worker_id,
|
|
45602
|
+
status: "needs_changes",
|
|
45603
|
+
summary: args.summary,
|
|
45604
|
+
issues: parsedIssues,
|
|
45605
|
+
attemptNumber,
|
|
45606
|
+
remainingAttempts: remaining,
|
|
45607
|
+
rationale: args.summary || `Review rejected: ${parsedIssues.length} issue(s) found`
|
|
45608
|
+
});
|
|
45609
|
+
} catch (error45) {
|
|
45610
|
+
console.warn("[swarm_review_feedback] Failed to trace review_decision:", error45);
|
|
45611
|
+
}
|
|
45262
45612
|
try {
|
|
45263
45613
|
const { createEvent: createEvent2, appendEvent: appendEvent2 } = await import("swarm-mail");
|
|
45264
45614
|
const status = remaining <= 0 ? "blocked" : "needs_changes";
|
|
@@ -61435,9 +61785,9 @@ async function getPromptInsights(options2) {
|
|
|
61435
61785
|
}
|
|
61436
61786
|
async function getCoordinatorInsights(project_key) {
|
|
61437
61787
|
try {
|
|
61438
|
-
const { createLibSQLAdapter, createSwarmMailAdapter: createSwarmMailAdapter2 } = await import("swarm-mail");
|
|
61788
|
+
const { createLibSQLAdapter: createLibSQLAdapter2, createSwarmMailAdapter: createSwarmMailAdapter2 } = await import("swarm-mail");
|
|
61439
61789
|
const { getStrategyInsights: getStrategyInsights2, getPatternInsights: getPatternInsights2, formatInsightsForPrompt: formatInsightsForPrompt2 } = await Promise.resolve().then(() => (init_swarm_insights(), exports_swarm_insights));
|
|
61440
|
-
const dbAdapter = await
|
|
61790
|
+
const dbAdapter = await createLibSQLAdapter2({ url: "file:./.swarm-mail/streams.db" });
|
|
61441
61791
|
const adapter = createSwarmMailAdapter2(dbAdapter, project_key || "default");
|
|
61442
61792
|
const [strategies, patterns] = await Promise.all([
|
|
61443
61793
|
getStrategyInsights2(adapter, ""),
|
|
@@ -61465,7 +61815,7 @@ ${formatted}
|
|
|
61465
61815
|
}
|
|
61466
61816
|
async function getWorkerInsights(files, domain2) {
|
|
61467
61817
|
try {
|
|
61468
|
-
const { createLibSQLAdapter, createSwarmMailAdapter: createSwarmMailAdapter2 } = await import("swarm-mail");
|
|
61818
|
+
const { createLibSQLAdapter: createLibSQLAdapter2, createSwarmMailAdapter: createSwarmMailAdapter2 } = await import("swarm-mail");
|
|
61469
61819
|
const { getFileInsights: getFileInsights2, formatInsightsForPrompt: formatInsightsForPrompt2 } = await Promise.resolve().then(() => (init_swarm_insights(), exports_swarm_insights));
|
|
61470
61820
|
const memoryAdapter = await getMemoryAdapter();
|
|
61471
61821
|
let query = "";
|
|
@@ -61482,7 +61832,7 @@ async function getWorkerInsights(files, domain2) {
|
|
|
61482
61832
|
if (!files || files.length === 0)
|
|
61483
61833
|
return [];
|
|
61484
61834
|
try {
|
|
61485
|
-
const dbAdapter = await
|
|
61835
|
+
const dbAdapter = await createLibSQLAdapter2({ url: "file:./.swarm-mail/streams.db" });
|
|
61486
61836
|
const swarmMail = createSwarmMailAdapter2(dbAdapter, "default");
|
|
61487
61837
|
return await getFileInsights2(swarmMail, files);
|
|
61488
61838
|
} catch (e) {
|
|
@@ -61691,6 +62041,23 @@ var swarm_spawn_subtask = tool({
|
|
|
61691
62041
|
} catch (error45) {
|
|
61692
62042
|
console.warn("[swarm_spawn_subtask] Failed to capture worker_spawned:", error45);
|
|
61693
62043
|
}
|
|
62044
|
+
try {
|
|
62045
|
+
await traceWorkerSpawn({
|
|
62046
|
+
projectKey: args2.project_path || process.cwd(),
|
|
62047
|
+
agentName: "coordinator",
|
|
62048
|
+
epicId: args2.epic_id,
|
|
62049
|
+
beadId: args2.bead_id,
|
|
62050
|
+
workerName: "worker",
|
|
62051
|
+
subtaskTitle: args2.subtask_title,
|
|
62052
|
+
files: args2.files,
|
|
62053
|
+
model: selectedModel,
|
|
62054
|
+
spawnOrder: 0,
|
|
62055
|
+
isParallel: false,
|
|
62056
|
+
rationale: args2.subtask_description || `Spawning worker for: ${args2.subtask_title}`
|
|
62057
|
+
});
|
|
62058
|
+
} catch (error45) {
|
|
62059
|
+
console.warn("[swarm_spawn_subtask] Failed to trace worker_spawn:", error45);
|
|
62060
|
+
}
|
|
61694
62061
|
if (args2.project_path) {
|
|
61695
62062
|
try {
|
|
61696
62063
|
const { createEvent: createEvent3, appendEvent: appendEvent3 } = await import("swarm-mail");
|
|
@@ -61920,7 +62287,7 @@ var swarm_plan_prompt = tool({
|
|
|
61920
62287
|
selectedStrategy = args2.strategy;
|
|
61921
62288
|
strategyReasoning = `User-specified strategy: ${selectedStrategy}`;
|
|
61922
62289
|
} else {
|
|
61923
|
-
const selection = selectStrategy2(args2.task);
|
|
62290
|
+
const selection = await selectStrategy2(args2.task);
|
|
61924
62291
|
selectedStrategy = selection.strategy;
|
|
61925
62292
|
strategyReasoning = selection.reasoning;
|
|
61926
62293
|
}
|
|
@@ -65626,6 +65993,7 @@ var sessionStats = {
|
|
|
65626
65993
|
|
|
65627
65994
|
// src/index.ts
|
|
65628
65995
|
init_skills();
|
|
65996
|
+
init_swarm_validation();
|
|
65629
65997
|
var SwarmPlugin = async (input) => {
|
|
65630
65998
|
const { $, directory, client } = input;
|
|
65631
65999
|
setHiveWorkingDirectory(directory);
|
package/dist/query-tools.d.ts
CHANGED
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
* GREEN PHASE: SQL Query Tools Implementation
|
|
3
3
|
*
|
|
4
4
|
* Provides:
|
|
5
|
-
* -
|
|
5
|
+
* - 13 preset queries for observability insights (10 base + 3 decision trace)
|
|
6
6
|
* - Custom SQL execution with timing
|
|
7
7
|
* - 3 output formats: Table (box-drawing), CSV, JSON
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
export type PresetQueryName = "failed_decompositions" | "duration_by_strategy" | "file_conflicts" | "worker_success_rate" | "review_rejections" | "blocked_tasks" | "agent_activity" | "event_frequency" | "error_patterns" | "compaction_stats";
|
|
9
|
+
export type PresetQueryName = "failed_decompositions" | "duration_by_strategy" | "file_conflicts" | "worker_success_rate" | "review_rejections" | "blocked_tasks" | "agent_activity" | "event_frequency" | "error_patterns" | "compaction_stats" | "decision_quality" | "strategy_success_rates" | "decisions_by_pattern";
|
|
11
10
|
export interface QueryResult {
|
|
12
11
|
columns: string[];
|
|
13
12
|
rows: Record<string, unknown>[];
|
|
@@ -16,14 +15,23 @@ export interface QueryResult {
|
|
|
16
15
|
}
|
|
17
16
|
export declare const presetQueries: Record<PresetQueryName, string>;
|
|
18
17
|
/**
|
|
19
|
-
* Execute custom SQL
|
|
18
|
+
* Execute custom SQL query (CLI wrapper).
|
|
19
|
+
* Creates database adapter automatically.
|
|
20
20
|
*
|
|
21
|
-
* @param
|
|
21
|
+
* @param projectPath - Project path (unused, queries global database)
|
|
22
22
|
* @param sql - SQL query string
|
|
23
|
-
* @
|
|
24
|
-
* @returns QueryResult with rows, columns, timing
|
|
23
|
+
* @returns Raw rows array for CLI formatting
|
|
25
24
|
*/
|
|
26
|
-
export declare function executeQuery(
|
|
25
|
+
export declare function executeQuery(projectPath: string, sql: string): Promise<any[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Execute a preset query by name (CLI wrapper).
|
|
28
|
+
* Creates database adapter automatically.
|
|
29
|
+
*
|
|
30
|
+
* @param projectPath - Project path (unused, queries global database)
|
|
31
|
+
* @param presetName - Name of the preset query
|
|
32
|
+
* @returns Raw rows array for CLI formatting
|
|
33
|
+
*/
|
|
34
|
+
export declare function executePreset(projectPath: string, presetName: string): Promise<any[]>;
|
|
27
35
|
/**
|
|
28
36
|
* Format query result as aligned table with box-drawing characters.
|
|
29
37
|
*
|
|
@@ -34,9 +42,9 @@ export declare function executeQuery(db: DatabaseAdapter, sql: string, params?:
|
|
|
34
42
|
* │ AgentA │ 5 │
|
|
35
43
|
* │ AgentB │ 3 │
|
|
36
44
|
* └──────────┴───────┘
|
|
37
|
-
* 2 rows
|
|
45
|
+
* 2 rows
|
|
38
46
|
*/
|
|
39
|
-
export declare function formatAsTable(
|
|
47
|
+
export declare function formatAsTable(rows: Record<string, unknown>[]): string;
|
|
40
48
|
/**
|
|
41
49
|
* Format query result as CSV with proper escaping.
|
|
42
50
|
*
|
|
@@ -45,7 +53,7 @@ export declare function formatAsTable(result: QueryResult): string;
|
|
|
45
53
|
* - Quotes → double them
|
|
46
54
|
* - Newlines → wrap in quotes
|
|
47
55
|
*/
|
|
48
|
-
export declare function formatAsCSV(
|
|
56
|
+
export declare function formatAsCSV(rows: Record<string, unknown>[]): string;
|
|
49
57
|
/**
|
|
50
58
|
* Format query result as pretty-printed JSON array.
|
|
51
59
|
*
|
|
@@ -55,5 +63,5 @@ export declare function formatAsCSV(result: QueryResult): string;
|
|
|
55
63
|
* { "name": "AgentB", "count": 3 }
|
|
56
64
|
* ]
|
|
57
65
|
*/
|
|
58
|
-
export declare function formatAsJSON(
|
|
66
|
+
export declare function formatAsJSON(rows: Record<string, unknown>[]): string;
|
|
59
67
|
//# sourceMappingURL=query-tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-tools.d.ts","sourceRoot":"","sources":["../src/query-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"query-tools.d.ts","sourceRoot":"","sources":["../src/query-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,MAAM,MAAM,eAAe,GACxB,uBAAuB,GACvB,sBAAsB,GACtB,gBAAgB,GAChB,qBAAqB,GACrB,mBAAmB,GACnB,eAAe,GACf,gBAAgB,GAChB,iBAAiB,GACjB,gBAAgB,GAChB,kBAAkB,GAClB,kBAAkB,GAClB,wBAAwB,GACxB,sBAAsB,CAAC;AAE1B,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;CACxB;AAMD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAgKzD,CAAC;AAgFF;;;;;;;GAOG;AACH,wBAAsB,YAAY,CACjC,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,GACT,OAAO,CAAC,GAAG,EAAE,CAAC,CAIhB;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAClC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,GAAG,EAAE,CAAC,CAIhB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,MAAM,CAmErE;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,MAAM,CA2BnE;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,MAAM,CAEpE"}
|