opencode-swarm-plugin 0.32.0 → 0.33.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/dist/plugin.js CHANGED
@@ -26558,7 +26558,7 @@ var init_skills = __esm(() => {
26558
26558
  "skills"
26559
26559
  ];
26560
26560
  skills_list = tool({
26561
- description: `List all available skills in the project.
26561
+ description: `[DEPRECATED] List all available skills in the project.
26562
26562
 
26563
26563
  Skills are specialized instructions that help with specific domains or tasks.
26564
26564
  Use this tool to discover what skills are available, then use skills_use to
@@ -26569,6 +26569,7 @@ Returns skill names, descriptions, and whether they have executable scripts.`,
26569
26569
  tag: tool.schema.string().optional().describe("Optional tag to filter skills by")
26570
26570
  },
26571
26571
  async execute(args) {
26572
+ console.warn("[DEPRECATED] skills_list is deprecated. OpenCode now provides native skills support. This tool will be removed in a future version.");
26572
26573
  const skills = await discoverSkills();
26573
26574
  let refs = Array.from(skills.values());
26574
26575
  if (args.tag) {
@@ -26591,7 +26592,7 @@ ${formatted}`;
26591
26592
  }
26592
26593
  });
26593
26594
  skills_use = tool({
26594
- description: `Activate a skill by loading its full instructions.
26595
+ description: `[DEPRECATED] Activate a skill by loading its full instructions.
26595
26596
 
26596
26597
  After calling this tool, follow the skill's instructions for the current task.
26597
26598
  Skills provide domain-specific guidance and best practices.
@@ -26602,6 +26603,7 @@ If the skill has scripts, you can run them with skills_execute.`,
26602
26603
  include_scripts: tool.schema.boolean().optional().describe("Also list available scripts (default: true)")
26603
26604
  },
26604
26605
  async execute(args) {
26606
+ console.warn("[DEPRECATED] skills_use is deprecated. OpenCode now provides native skills support. This tool will be removed in a future version.");
26605
26607
  const skill = await getSkill(args.name);
26606
26608
  if (!skill) {
26607
26609
  const available = await listSkills();
@@ -26634,7 +26636,7 @@ Run scripts with skills_execute tool.`;
26634
26636
  }
26635
26637
  });
26636
26638
  skills_execute = tool({
26637
- description: `Execute a script from a skill's scripts/ directory.
26639
+ description: `[DEPRECATED] Execute a script from a skill's scripts/ directory.
26638
26640
 
26639
26641
  Some skills include helper scripts for common operations.
26640
26642
  Use skills_use first to see available scripts, then execute them here.
@@ -26646,6 +26648,7 @@ Scripts run in the skill's directory with the project directory as an argument.`
26646
26648
  args: tool.schema.array(tool.schema.string()).optional().describe("Additional arguments to pass to the script")
26647
26649
  },
26648
26650
  async execute(args, ctx) {
26651
+ console.warn("[DEPRECATED] skills_execute is deprecated. OpenCode now provides native skills support. This tool will be removed in a future version.");
26649
26652
  const skill = await getSkill(args.skill);
26650
26653
  if (!skill) {
26651
26654
  return `Skill '${args.skill}' not found.`;
@@ -26691,7 +26694,7 @@ ${output}`;
26691
26694
  }
26692
26695
  });
26693
26696
  skills_read = tool({
26694
- description: `Read a resource file from a skill's directory.
26697
+ description: `[DEPRECATED] Read a resource file from a skill's directory.
26695
26698
 
26696
26699
  Skills may include additional files like:
26697
26700
  - examples.md - Example usage
@@ -26704,6 +26707,7 @@ Use this to access supplementary skill resources.`,
26704
26707
  file: tool.schema.string().describe("Relative path to the file within the skill directory")
26705
26708
  },
26706
26709
  async execute(args) {
26710
+ console.warn("[DEPRECATED] skills_read is deprecated. OpenCode now provides native skills support. This tool will be removed in a future version.");
26707
26711
  const skill = await getSkill(args.skill);
26708
26712
  if (!skill) {
26709
26713
  return `Skill '${args.skill}' not found.`;
@@ -35144,6 +35148,115 @@ Other cell operations:
35144
35148
  **Memory is the swarm's collective intelligence. Query it. Feed it.**
35145
35149
 
35146
35150
  Begin now.`;
35151
+ var RESEARCHER_PROMPT = `You are a swarm researcher gathering documentation for: **{research_id}**
35152
+
35153
+ ## [IDENTITY]
35154
+ Agent: (assigned at spawn)
35155
+ Research Task: {research_id}
35156
+ Epic: {epic_id}
35157
+
35158
+ ## [MISSION]
35159
+ Gather comprehensive documentation for the specified technologies to inform task decomposition.
35160
+
35161
+ **COORDINATOR PROVIDED THESE TECHNOLOGIES TO RESEARCH:**
35162
+ {tech_stack}
35163
+
35164
+ You do NOT discover what to research - the coordinator already decided that.
35165
+ You DO discover what TOOLS are available to fetch documentation.
35166
+
35167
+ ## [OUTPUT MODE]
35168
+ {check_upgrades}
35169
+
35170
+ ## [WORKFLOW]
35171
+
35172
+ ### Step 1: Initialize (MANDATORY FIRST)
35173
+ \`\`\`
35174
+ swarmmail_init(project_path="{project_path}", task_description="{research_id}: Documentation research")
35175
+ \`\`\`
35176
+
35177
+ ### Step 2: Discover Available Documentation Tools
35178
+ Check what's available for fetching docs:
35179
+ - **next-devtools**: \`nextjs_docs\` for Next.js documentation
35180
+ - **context7**: Library documentation lookup (\`use context7\` in prompts)
35181
+ - **fetch**: General web fetching for official docs sites
35182
+ - **pdf-brain**: Internal knowledge base search
35183
+
35184
+ **Don't assume** - check which tools exist in your environment.
35185
+
35186
+ ### Step 3: Read Installed Versions
35187
+ For each technology in the tech stack:
35188
+ 1. Check package.json (or equivalent) for installed version
35189
+ 2. Record exact version numbers
35190
+ 3. Note any version constraints (^, ~, etc.)
35191
+
35192
+ ### Step 4: Fetch Documentation
35193
+ For EACH technology in the list:
35194
+ - Use the most appropriate tool (Next.js → nextjs_docs, libraries → context7, others → fetch)
35195
+ - Fetch documentation for the INSTALLED version (not latest, unless --check-upgrades)
35196
+ - Focus on: API changes, breaking changes, migration guides, best practices
35197
+ - Extract key patterns, gotchas, and compatibility notes
35198
+
35199
+ **If --check-upgrades mode:**
35200
+ - ALSO fetch docs for the LATEST version
35201
+ - Compare installed vs latest
35202
+ - Note breaking changes, new features, migration complexity
35203
+
35204
+ ### Step 5: Store Detailed Findings
35205
+ For EACH technology, store in semantic-memory:
35206
+ \`\`\`
35207
+ semantic-memory_store(
35208
+ information="<technology-name> <version>: <key patterns, gotchas, API changes, compatibility notes>",
35209
+ tags="research, <tech-name>, documentation, {epic_id}"
35210
+ )
35211
+ \`\`\`
35212
+
35213
+ **Why store individually?** Future agents can search by technology name.
35214
+
35215
+ ### Step 6: Broadcast Summary
35216
+ Send condensed findings to coordinator:
35217
+ \`\`\`
35218
+ swarmmail_send(
35219
+ to=["coordinator"],
35220
+ subject="Research Complete: {research_id}",
35221
+ body="<brief summary - see semantic-memory for details>",
35222
+ thread_id="{epic_id}"
35223
+ )
35224
+ \`\`\`
35225
+
35226
+ ### Step 7: Return Structured Output
35227
+ Output JSON with:
35228
+ \`\`\`json
35229
+ {
35230
+ "technologies": [
35231
+ {
35232
+ "name": "string",
35233
+ "installed_version": "string",
35234
+ "latest_version": "string | null", // Only if --check-upgrades
35235
+ "key_patterns": ["string"],
35236
+ "gotchas": ["string"],
35237
+ "breaking_changes": ["string"], // Only if --check-upgrades
35238
+ "memory_id": "string" // ID of semantic-memory entry
35239
+ }
35240
+ ],
35241
+ "summary": "string" // Condensed summary for shared_context
35242
+ }
35243
+ \`\`\`
35244
+
35245
+ ## [CRITICAL REQUIREMENTS]
35246
+
35247
+ **NON-NEGOTIABLE:**
35248
+ 1. Step 1 (swarmmail_init) MUST be first
35249
+ 2. Research ONLY the technologies the coordinator specified
35250
+ 3. Fetch docs for INSTALLED versions (unless --check-upgrades)
35251
+ 4. Store detailed findings in semantic-memory (one per technology)
35252
+ 5. Return condensed summary for coordinator (full details in memory)
35253
+ 6. Use appropriate doc tools (nextjs_docs for Next.js, context7 for libraries, etc.)
35254
+
35255
+ **Output goes TWO places:**
35256
+ - **semantic-memory**: Detailed findings (searchable by future agents)
35257
+ - **Return JSON**: Condensed summary (for coordinator's shared_context)
35258
+
35259
+ Begin research now.`;
35147
35260
  var COORDINATOR_POST_WORKER_CHECKLIST = `
35148
35261
  ## ⚠️ MANDATORY: Post-Worker Review (DO THIS IMMEDIATELY)
35149
35262
 
@@ -35232,6 +35345,12 @@ For each criterion, assess passed/failed and provide brief feedback:
35232
35345
 
35233
35346
  If any criterion fails, the overall evaluation fails and retry_suggestion
35234
35347
  should describe what needs to be fixed.`;
35348
+ function formatResearcherPrompt(params) {
35349
+ const techList = params.tech_stack.map((t) => `- ${t}`).join(`
35350
+ `);
35351
+ const upgradesMode = params.check_upgrades ? "**UPGRADE COMPARISON MODE**: Fetch docs for BOTH installed AND latest versions. Compare and note breaking changes." : "**DEFAULT MODE**: Fetch docs for INSTALLED versions only (from lockfiles).";
35352
+ return RESEARCHER_PROMPT.replace(/{research_id}/g, params.research_id).replace(/{epic_id}/g, params.epic_id).replace("{tech_stack}", techList).replace("{project_path}", params.project_path).replace("{check_upgrades}", upgradesMode);
35353
+ }
35235
35354
  function formatSubtaskPromptV2(params) {
35236
35355
  const fileList = params.files.length > 0 ? params.files.map((f) => `- \`${f}\``).join(`
35237
35356
  `) : "(no specific files - use judgment)";
@@ -35381,6 +35500,48 @@ var swarm_spawn_subtask = tool({
35381
35500
  }, null, 2);
35382
35501
  }
35383
35502
  });
35503
+ var swarm_spawn_researcher = tool({
35504
+ description: "Prepare a research task for spawning. Returns prompt for gathering technology documentation. Researcher fetches docs and stores findings in semantic-memory.",
35505
+ args: {
35506
+ research_id: tool.schema.string().describe("Unique ID for this research task"),
35507
+ epic_id: tool.schema.string().describe("Parent epic ID"),
35508
+ tech_stack: tool.schema.array(tool.schema.string()).describe("Explicit list of technologies to research (from coordinator)"),
35509
+ project_path: tool.schema.string().describe("Absolute project path for swarmmail_init"),
35510
+ check_upgrades: tool.schema.boolean().optional().describe("If true, compare installed vs latest versions (default: false)")
35511
+ },
35512
+ async execute(args) {
35513
+ const prompt = formatResearcherPrompt({
35514
+ research_id: args.research_id,
35515
+ epic_id: args.epic_id,
35516
+ tech_stack: args.tech_stack,
35517
+ project_path: args.project_path,
35518
+ check_upgrades: args.check_upgrades ?? false
35519
+ });
35520
+ return JSON.stringify({
35521
+ prompt,
35522
+ research_id: args.research_id,
35523
+ epic_id: args.epic_id,
35524
+ tech_stack: args.tech_stack,
35525
+ project_path: args.project_path,
35526
+ check_upgrades: args.check_upgrades ?? false,
35527
+ subagent_type: "swarm/researcher",
35528
+ expected_output: {
35529
+ technologies: [
35530
+ {
35531
+ name: "string",
35532
+ installed_version: "string",
35533
+ latest_version: "string | null",
35534
+ key_patterns: ["string"],
35535
+ gotchas: ["string"],
35536
+ breaking_changes: ["string"],
35537
+ memory_id: "string"
35538
+ }
35539
+ ],
35540
+ summary: "string"
35541
+ }
35542
+ }, null, 2);
35543
+ }
35544
+ });
35384
35545
  var swarm_evaluation_prompt = tool({
35385
35546
  description: "Generate self-evaluation prompt for a completed subtask",
35386
35547
  args: {
@@ -35492,6 +35653,7 @@ ${args.context}` : `## Additional Context
35492
35653
  var promptTools = {
35493
35654
  swarm_subtask_prompt,
35494
35655
  swarm_spawn_subtask,
35656
+ swarm_spawn_researcher,
35495
35657
  swarm_evaluation_prompt,
35496
35658
  swarm_plan_prompt
35497
35659
  };
@@ -50255,6 +50417,368 @@ var memoryTools = {
50255
50417
  "semantic-memory_check": semantic_memory_check
50256
50418
  };
50257
50419
 
50420
+ // src/observability-tools.ts
50421
+ init_dist();
50422
+ import {
50423
+ agentActivity,
50424
+ checkpointFrequency,
50425
+ failedDecompositions,
50426
+ getSwarmMailLibSQL as getSwarmMailLibSQL4,
50427
+ humanFeedback,
50428
+ lockContention,
50429
+ messageLatency,
50430
+ recoverySuccess,
50431
+ scopeViolations,
50432
+ strategySuccessRates,
50433
+ taskDuration
50434
+ } from "swarm-mail";
50435
+ function parseSince(since) {
50436
+ const now = Date.now();
50437
+ const match11 = since.match(/^(\d+)([dhm])$/);
50438
+ if (!match11) {
50439
+ throw new Error(`Invalid since format: ${since}. Use "7d", "24h", or "1h"`);
50440
+ }
50441
+ const [, value, unit] = match11;
50442
+ const num = Number.parseInt(value, 10);
50443
+ switch (unit) {
50444
+ case "d":
50445
+ return now - num * 24 * 60 * 60 * 1000;
50446
+ case "h":
50447
+ return now - num * 60 * 60 * 1000;
50448
+ case "m":
50449
+ return now - num * 60 * 1000;
50450
+ default:
50451
+ throw new Error(`Unknown unit: ${unit}`);
50452
+ }
50453
+ }
50454
+ async function executeQuery(swarmMail, query) {
50455
+ const db = await swarmMail.getDatabase();
50456
+ const result = await db.query(query.sql, Object.values(query.parameters || {}));
50457
+ return result.rows;
50458
+ }
50459
+ function formatSummary(queryType, results) {
50460
+ if (results.length === 0) {
50461
+ return `No ${queryType} data found.`;
50462
+ }
50463
+ const count = results.length;
50464
+ const preview = results.slice(0, 3);
50465
+ return `${queryType}: ${count} result(s). Top 3: ${JSON.stringify(preview, null, 2).slice(0, 400)}`;
50466
+ }
50467
+ function capResults(results) {
50468
+ return results.slice(0, 50);
50469
+ }
50470
+ var swarm_analytics = tool({
50471
+ description: "Query pre-built analytics for swarm coordination. Returns structured data about failed decompositions, strategy success rates, lock contention, agent activity, message latency, scope violations, task duration, checkpoint frequency, recovery success, and human feedback.",
50472
+ args: {
50473
+ query: tool.schema.enum([
50474
+ "failed-decompositions",
50475
+ "strategy-success-rates",
50476
+ "lock-contention",
50477
+ "agent-activity",
50478
+ "message-latency",
50479
+ "scope-violations",
50480
+ "task-duration",
50481
+ "checkpoint-frequency",
50482
+ "recovery-success",
50483
+ "human-feedback"
50484
+ ]).describe("Type of analytics query to run"),
50485
+ since: tool.schema.string().optional().describe("Time filter: '7d', '24h', '1h' (optional)"),
50486
+ format: tool.schema.enum(["json", "summary"]).optional().describe("Output format: 'json' (default) or 'summary' (context-efficient)")
50487
+ },
50488
+ async execute(args2) {
50489
+ try {
50490
+ const projectPath = process.cwd();
50491
+ const db = await getSwarmMailLibSQL4(projectPath);
50492
+ const filters = {
50493
+ project_key: projectPath
50494
+ };
50495
+ if (args2.since) {
50496
+ filters.since = parseSince(args2.since);
50497
+ }
50498
+ let query;
50499
+ switch (args2.query) {
50500
+ case "failed-decompositions":
50501
+ query = failedDecompositions(filters);
50502
+ break;
50503
+ case "strategy-success-rates":
50504
+ query = strategySuccessRates(filters);
50505
+ break;
50506
+ case "lock-contention":
50507
+ query = lockContention(filters);
50508
+ break;
50509
+ case "agent-activity":
50510
+ query = agentActivity(filters);
50511
+ break;
50512
+ case "message-latency":
50513
+ query = messageLatency(filters);
50514
+ break;
50515
+ case "scope-violations":
50516
+ query = scopeViolations.buildQuery ? scopeViolations.buildQuery(filters) : scopeViolations;
50517
+ break;
50518
+ case "task-duration":
50519
+ query = taskDuration.buildQuery ? taskDuration.buildQuery(filters) : taskDuration;
50520
+ break;
50521
+ case "checkpoint-frequency":
50522
+ query = checkpointFrequency.buildQuery ? checkpointFrequency.buildQuery(filters) : checkpointFrequency;
50523
+ break;
50524
+ case "recovery-success":
50525
+ query = recoverySuccess.buildQuery ? recoverySuccess.buildQuery(filters) : recoverySuccess;
50526
+ break;
50527
+ case "human-feedback":
50528
+ query = humanFeedback.buildQuery ? humanFeedback.buildQuery(filters) : humanFeedback;
50529
+ break;
50530
+ default:
50531
+ return JSON.stringify({
50532
+ error: `Unknown query type: ${args2.query}`
50533
+ });
50534
+ }
50535
+ const results = await executeQuery(db, query);
50536
+ if (args2.format === "summary") {
50537
+ return formatSummary(args2.query, results);
50538
+ }
50539
+ return JSON.stringify({
50540
+ query: args2.query,
50541
+ filters,
50542
+ count: results.length,
50543
+ results
50544
+ }, null, 2);
50545
+ } catch (error45) {
50546
+ return JSON.stringify({
50547
+ error: error45 instanceof Error ? error45.message : String(error45)
50548
+ });
50549
+ }
50550
+ }
50551
+ });
50552
+ var swarm_query = tool({
50553
+ description: "Execute raw SQL queries against the swarm event store. Context-safe: results capped at 50 rows. Useful for custom analytics and debugging.",
50554
+ args: {
50555
+ sql: tool.schema.string().describe("SQL query to execute (SELECT only for safety)"),
50556
+ format: tool.schema.enum(["json", "table"]).optional().describe("Output format: 'json' (default) or 'table' (visual)")
50557
+ },
50558
+ async execute(args2) {
50559
+ try {
50560
+ const projectPath = process.cwd();
50561
+ const swarmMail = await getSwarmMailLibSQL4(projectPath);
50562
+ const db = await swarmMail.getDatabase();
50563
+ if (!args2.sql.trim().toLowerCase().startsWith("select")) {
50564
+ return JSON.stringify({
50565
+ error: "Only SELECT queries are allowed for safety"
50566
+ });
50567
+ }
50568
+ const result = await db.query(args2.sql, []);
50569
+ const rows = result.rows;
50570
+ const cappedRows = capResults(rows);
50571
+ if (args2.format === "table") {
50572
+ if (cappedRows.length === 0) {
50573
+ return "No results";
50574
+ }
50575
+ const headers = Object.keys(cappedRows[0]);
50576
+ const headerRow = headers.join(" | ");
50577
+ const separator = headers.map(() => "---").join(" | ");
50578
+ const dataRows = cappedRows.map((row) => headers.map((h) => row[h]).join(" | "));
50579
+ return [headerRow, separator, ...dataRows].join(`
50580
+ `);
50581
+ }
50582
+ return JSON.stringify({
50583
+ count: cappedRows.length,
50584
+ total: rows.length,
50585
+ capped: rows.length > 50,
50586
+ results: cappedRows
50587
+ }, null, 2);
50588
+ } catch (error45) {
50589
+ return JSON.stringify({
50590
+ error: error45 instanceof Error ? error45.message : String(error45)
50591
+ });
50592
+ }
50593
+ }
50594
+ });
50595
+ var swarm_diagnose = tool({
50596
+ description: "Auto-diagnose issues for a specific epic or task. Returns structured diagnosis with blockers, conflicts, slow tasks, errors, and timeline.",
50597
+ args: {
50598
+ epic_id: tool.schema.string().optional().describe("Epic ID to diagnose"),
50599
+ bead_id: tool.schema.string().optional().describe("Task ID to diagnose"),
50600
+ include: tool.schema.array(tool.schema.enum([
50601
+ "blockers",
50602
+ "conflicts",
50603
+ "slow_tasks",
50604
+ "errors",
50605
+ "timeline"
50606
+ ])).optional().describe("What to include in diagnosis (default: all)")
50607
+ },
50608
+ async execute(args2) {
50609
+ try {
50610
+ const projectPath = process.cwd();
50611
+ const swarmMail = await getSwarmMailLibSQL4(projectPath);
50612
+ const db = await swarmMail.getDatabase();
50613
+ const diagnosis = [];
50614
+ const include = args2.include || [
50615
+ "blockers",
50616
+ "conflicts",
50617
+ "slow_tasks",
50618
+ "errors",
50619
+ "timeline"
50620
+ ];
50621
+ if (include.includes("blockers")) {
50622
+ const blockerQuery = `
50623
+ SELECT json_extract(data, '$.agent_name') as agent,
50624
+ json_extract(data, '$.bead_id') as bead_id,
50625
+ timestamp
50626
+ FROM events
50627
+ WHERE type = 'task_blocked'
50628
+ ${args2.epic_id ? "AND json_extract(data, '$.epic_id') = ?" : ""}
50629
+ ${args2.bead_id ? "AND json_extract(data, '$.bead_id') = ?" : ""}
50630
+ ORDER BY timestamp DESC
50631
+ LIMIT 10
50632
+ `;
50633
+ const params = [];
50634
+ if (args2.epic_id)
50635
+ params.push(args2.epic_id);
50636
+ if (args2.bead_id)
50637
+ params.push(args2.bead_id);
50638
+ const blockers = await db.query(blockerQuery, params);
50639
+ if (blockers.rows.length > 0) {
50640
+ diagnosis.push({
50641
+ type: "blockers",
50642
+ message: `Found ${blockers.rows.length} blocked task(s)`,
50643
+ severity: "high"
50644
+ });
50645
+ }
50646
+ }
50647
+ if (include.includes("errors")) {
50648
+ const errorQuery = `
50649
+ SELECT type, json_extract(data, '$.error_count') as error_count
50650
+ FROM events
50651
+ WHERE type = 'subtask_outcome'
50652
+ AND json_extract(data, '$.success') = 'false'
50653
+ ${args2.epic_id ? "AND json_extract(data, '$.epic_id') = ?" : ""}
50654
+ ${args2.bead_id ? "AND json_extract(data, '$.bead_id') = ?" : ""}
50655
+ LIMIT 10
50656
+ `;
50657
+ const params = [];
50658
+ if (args2.epic_id)
50659
+ params.push(args2.epic_id);
50660
+ if (args2.bead_id)
50661
+ params.push(args2.bead_id);
50662
+ const errors3 = await db.query(errorQuery, params);
50663
+ if (errors3.rows.length > 0) {
50664
+ diagnosis.push({
50665
+ type: "errors",
50666
+ message: `Found ${errors3.rows.length} failed task(s)`,
50667
+ severity: "high"
50668
+ });
50669
+ }
50670
+ }
50671
+ let timeline = [];
50672
+ if (include.includes("timeline")) {
50673
+ const timelineQuery = `
50674
+ SELECT timestamp, type, json_extract(data, '$.agent_name') as agent
50675
+ FROM events
50676
+ ${args2.epic_id ? "WHERE json_extract(data, '$.epic_id') = ?" : ""}
50677
+ ${args2.bead_id ? (args2.epic_id ? "AND" : "WHERE") + " json_extract(data, '$.bead_id') = ?" : ""}
50678
+ ORDER BY timestamp DESC
50679
+ LIMIT 20
50680
+ `;
50681
+ const params = [];
50682
+ if (args2.epic_id)
50683
+ params.push(args2.epic_id);
50684
+ if (args2.bead_id)
50685
+ params.push(args2.bead_id);
50686
+ const events = await db.query(timelineQuery, params);
50687
+ timeline = events.rows;
50688
+ }
50689
+ return JSON.stringify({
50690
+ epic_id: args2.epic_id,
50691
+ bead_id: args2.bead_id,
50692
+ diagnosis,
50693
+ timeline: include.includes("timeline") ? timeline : undefined
50694
+ }, null, 2);
50695
+ } catch (error45) {
50696
+ return JSON.stringify({
50697
+ error: error45 instanceof Error ? error45.message : String(error45)
50698
+ });
50699
+ }
50700
+ }
50701
+ });
50702
+ var swarm_insights = tool({
50703
+ description: "Generate learning insights from swarm coordination metrics. Analyzes success rates, duration, conflicts, and retries to provide actionable recommendations.",
50704
+ args: {
50705
+ scope: tool.schema.enum(["epic", "project", "recent"]).describe("Scope of analysis: 'epic', 'project', or 'recent'"),
50706
+ epic_id: tool.schema.string().optional().describe("Epic ID (required if scope='epic')"),
50707
+ metrics: tool.schema.array(tool.schema.enum([
50708
+ "success_rate",
50709
+ "avg_duration",
50710
+ "conflict_rate",
50711
+ "retry_rate"
50712
+ ])).describe("Metrics to analyze")
50713
+ },
50714
+ async execute(args2) {
50715
+ try {
50716
+ if (args2.scope === "epic" && !args2.epic_id) {
50717
+ return JSON.stringify({
50718
+ error: "epic_id is required when scope='epic'"
50719
+ });
50720
+ }
50721
+ const projectPath = process.cwd();
50722
+ const swarmMail = await getSwarmMailLibSQL4(projectPath);
50723
+ const db = await swarmMail.getDatabase();
50724
+ const insights = [];
50725
+ if (args2.metrics.includes("success_rate")) {
50726
+ const query = `
50727
+ SELECT
50728
+ SUM(CASE WHEN json_extract(data, '$.success') = 'true' THEN 1 ELSE 0 END) as successes,
50729
+ COUNT(*) as total
50730
+ FROM events
50731
+ WHERE type = 'subtask_outcome'
50732
+ ${args2.epic_id ? "AND json_extract(data, '$.epic_id') = ?" : ""}
50733
+ `;
50734
+ const result = await db.query(query, args2.epic_id ? [args2.epic_id] : []);
50735
+ const row = result.rows[0];
50736
+ if (row && row.total > 0) {
50737
+ const rate = row.successes / row.total * 100;
50738
+ insights.push({
50739
+ metric: "success_rate",
50740
+ value: `${rate.toFixed(1)}%`,
50741
+ insight: rate < 50 ? "Low success rate - review decomposition strategy" : rate < 80 ? "Moderate success rate - monitor for patterns" : "Good success rate - maintain current approach"
50742
+ });
50743
+ }
50744
+ }
50745
+ if (args2.metrics.includes("avg_duration")) {
50746
+ const query = `
50747
+ SELECT AVG(CAST(json_extract(data, '$.duration_ms') AS REAL)) as avg_duration
50748
+ FROM events
50749
+ WHERE type = 'subtask_outcome'
50750
+ ${args2.epic_id ? "AND json_extract(data, '$.epic_id') = ?" : ""}
50751
+ `;
50752
+ const result = await db.query(query, args2.epic_id ? [args2.epic_id] : []);
50753
+ const row = result.rows[0];
50754
+ if (row?.avg_duration) {
50755
+ const avgMinutes = (row.avg_duration / 60000).toFixed(1);
50756
+ insights.push({
50757
+ metric: "avg_duration",
50758
+ value: `${avgMinutes} min`,
50759
+ insight: row.avg_duration > 600000 ? "Tasks taking >10min - consider smaller decomposition" : "Task duration is reasonable"
50760
+ });
50761
+ }
50762
+ }
50763
+ return JSON.stringify({
50764
+ scope: args2.scope,
50765
+ epic_id: args2.epic_id,
50766
+ insights
50767
+ }, null, 2);
50768
+ } catch (error45) {
50769
+ return JSON.stringify({
50770
+ error: error45 instanceof Error ? error45.message : String(error45)
50771
+ });
50772
+ }
50773
+ }
50774
+ });
50775
+ var observabilityTools = {
50776
+ swarm_analytics,
50777
+ swarm_query,
50778
+ swarm_diagnose,
50779
+ swarm_insights
50780
+ };
50781
+
50258
50782
  // src/output-guardrails.ts
50259
50783
  var DEFAULT_GUARDRAIL_CONFIG = {
50260
50784
  defaultMaxChars: 32000,
@@ -50677,7 +51201,8 @@ var SwarmPlugin = async (input) => {
50677
51201
  ...repoCrawlTools,
50678
51202
  ...skillsTools,
50679
51203
  ...mandateTools,
50680
- ...memoryTools
51204
+ ...memoryTools,
51205
+ ...observabilityTools
50681
51206
  },
50682
51207
  event: async ({ event }) => {
50683
51208
  if (event.type === "session.idle") {
@@ -1 +1 @@
1
- {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"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"}