@holoscript/framework 6.0.3 → 6.0.4

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.
Files changed (160) hide show
  1. package/CHANGELOG.md +1 -2
  2. package/ROADMAP.md +68 -66
  3. package/dist/{InvisibleWallet-BB6tFvRA.d.cts → InvisibleWallet-EFiuaLn3.d.cts} +1 -1
  4. package/dist/{OrchestratorAgent-BvWgf9uw.d.cts → OrchestratorAgent-CrLDGNL6.d.cts} +1 -1
  5. package/dist/agents/index.cjs +11 -10
  6. package/dist/agents/index.d.cts +4 -16
  7. package/dist/ai/index.cjs +2 -2
  8. package/dist/behavior.cjs +10 -0
  9. package/dist/economy/index.cjs +4 -4
  10. package/dist/economy/index.d.cts +2 -2
  11. package/dist/index.cjs +33 -11
  12. package/dist/index.d.cts +3 -3
  13. package/dist/swarm/index.cjs +3 -0
  14. package/package.json +14 -9
  15. package/src/__tests__/bounty-marketplace.test.ts +53 -21
  16. package/src/__tests__/delegation.test.ts +1 -4
  17. package/src/__tests__/done-log-audit.test.ts +38 -46
  18. package/src/__tests__/framework.test.ts +172 -53
  19. package/src/__tests__/goal-synthesizer.test.ts +9 -6
  20. package/src/__tests__/presence.test.ts +1 -1
  21. package/src/__tests__/protocol-agent.test.ts +12 -11
  22. package/src/__tests__/revenue-splitter.test.ts +22 -15
  23. package/src/__tests__/scenario-driven-todo.test.ts +55 -35
  24. package/src/__tests__/self-improve.test.ts +28 -9
  25. package/src/__tests__/service-lifecycle.test.ts +9 -3
  26. package/src/__tests__/skill-router.test.ts +3 -3
  27. package/src/agents/CulturalMemory.ts +6 -6
  28. package/src/agents/DelegationTraceHooks.ts +560 -0
  29. package/src/agents/FederatedRegistryAdapter.ts +1 -1
  30. package/src/agents/NormEngine.ts +3 -8
  31. package/src/agents/OrchestratorAgent.ts +1 -1
  32. package/src/agents/TaskDelegationService.ts +5 -9
  33. package/src/agents/__tests__/AgentWalletRegistry.test.ts +5 -4
  34. package/src/agents/__tests__/CrossRealityHandoff.test.ts +9 -3
  35. package/src/agents/__tests__/DelegationTraceHooks.test.ts +390 -0
  36. package/src/agents/__tests__/TaskDelegationService.test.ts +4 -2
  37. package/src/agents/spatial-comms/Layer1RealTime.ts +36 -19
  38. package/src/agents/spatial-comms/Layer2A2A.ts +1 -3
  39. package/src/agents/spatial-comms/Layer3MCP.ts +13 -4
  40. package/src/agents/spatial-comms/ProtocolTypes.ts +5 -2
  41. package/src/agents/spatial-comms/examples/multi-agent-world-creation.ts +2 -2
  42. package/src/ai/HoloScriptGenerator.ts +2 -2
  43. package/src/ai/__tests__/PerceptionSystem.prod.test.ts +1 -1
  44. package/src/ai/__tests__/PerceptionSystem.test.ts +14 -14
  45. package/src/ai/__tests__/SteeringBehaviors.prod.test.ts +1 -1
  46. package/src/ai/index.ts +5 -1
  47. package/src/board/audit.ts +17 -6
  48. package/src/board/board-ops.ts +45 -15
  49. package/src/board/board-types.ts +94 -20
  50. package/src/delegation.ts +5 -3
  51. package/src/distributed-claimer.ts +13 -2
  52. package/src/economy/BountyManager.ts +40 -18
  53. package/src/economy/KnowledgeMarketplace.ts +27 -8
  54. package/src/economy/PaymentWebhookService.ts +0 -1
  55. package/src/economy/RevenueSplitter.ts +2 -4
  56. package/src/economy/UnifiedBudgetOptimizer.ts +8 -9
  57. package/src/economy/_core-stubs.ts +1 -1
  58. package/src/economy/x402-facilitator.ts +17 -8
  59. package/src/index.ts +16 -12
  60. package/src/knowledge/__tests__/knowledge-consolidator.test.ts +138 -89
  61. package/src/knowledge/__tests__/knowledge-store-vector.test.ts +59 -16
  62. package/src/knowledge/brain.ts +7 -7
  63. package/src/knowledge/consolidation.ts +16 -16
  64. package/src/knowledge/knowledge-consolidator.ts +60 -30
  65. package/src/knowledge/knowledge-store.ts +83 -45
  66. package/src/learning/ProceduralCompiler.ts +6 -1
  67. package/src/learning/learning/MemoryConsolidator.ts +102 -0
  68. package/src/learning/learning/MemoryScorer.ts +69 -0
  69. package/src/learning/learning/ProceduralCompiler.ts +45 -0
  70. package/src/learning/learning/SemanticClusterer.ts +66 -0
  71. package/src/llm/llm-adapter.ts +24 -10
  72. package/src/mesh/index.ts +37 -17
  73. package/src/protocol/goal-synthesizer.ts +24 -34
  74. package/src/protocol/implementations.ts +91 -22
  75. package/src/protocol/micro-phase-decomposer.ts +25 -17
  76. package/src/protocol/micro-step-decomposer.test.ts +104 -39
  77. package/src/protocol-agent.test.ts +17 -7
  78. package/src/protocol-agent.ts +45 -42
  79. package/src/self-improve/absorb-scanner.ts +9 -6
  80. package/src/self-improve/evolution-engine.ts +36 -18
  81. package/src/self-improve/framework-absorber.ts +21 -16
  82. package/src/self-improve/index.ts +2 -10
  83. package/src/self-improve/prompt-optimizer.ts +31 -19
  84. package/src/self-improve/test-generator.ts +16 -12
  85. package/src/skill-router.ts +7 -6
  86. package/src/swarm/messaging/GossipProtocol.ts +1 -1
  87. package/src/swarm/messaging/__tests__/BroadcastChannel.prod.test.ts +31 -9
  88. package/src/swarm/messaging/__tests__/GossipProtocol.prod.test.ts +21 -7
  89. package/src/swarm/messaging/__tests__/SwarmEventBus.prod.test.ts +24 -8
  90. package/src/swarm/messaging/__tests__/SwarmEventBus.test.ts +6 -2
  91. package/src/team.ts +277 -122
  92. package/src/training/scripts/generate-spatial-dataset.ts +1 -1
  93. package/src/training/training/LRScheduler.ts +377 -0
  94. package/src/training/training/QualityScoringPipeline.ts +139 -0
  95. package/src/training/training/SoftDedup.ts +461 -0
  96. package/src/training/training/SparsityMonitor.ts +685 -0
  97. package/src/training/training/SparsityMonitorTypes.ts +209 -0
  98. package/src/training/training/SpatialTrainingDataGenerator.ts +1526 -0
  99. package/src/training/training/SpatialTrainingDataTypes.ts +216 -0
  100. package/src/training/training/TrainingPipelineConfig.ts +215 -0
  101. package/src/training/training/__tests__/CorpusValidation.test.ts +87 -0
  102. package/src/training/training/__tests__/LRScheduler.test.ts +592 -0
  103. package/src/training/training/__tests__/SoftDedup.test.ts +415 -0
  104. package/src/training/training/__tests__/SparsityMonitor.test.ts +1623 -0
  105. package/src/training/training/__tests__/SpatialCorpusValidation.test.ts +72 -0
  106. package/src/training/training/__tests__/SpatialTrainingDataGenerator.test.ts +1244 -0
  107. package/src/training/training/__tests__/TrainingMonkeyIntegration.test.ts +897 -0
  108. package/src/training/training/__tests__/TrainingPipelineConfig.test.ts +202 -0
  109. package/src/training/training/__tests__/schema.test.ts +72 -0
  110. package/src/training/training/__tests__/training-constants.test.ts +106 -0
  111. package/src/training/training/__tests__/trait-mappings.test.ts +81 -0
  112. package/src/training/training/constants.ts +94 -0
  113. package/src/training/training/index.ts +17 -0
  114. package/src/training/training/schema.ts +147 -0
  115. package/src/training/training/scripts/generate-novel-use-cases-dataset.ts +272 -0
  116. package/src/training/training/scripts/generate-spatial-dataset.ts +521 -0
  117. package/src/training/training/trainingmonkey/TrainingMonkeyIntegration.ts +477 -0
  118. package/src/training/training/trainingmonkey/TrainingMonkeyTypes.ts +230 -0
  119. package/src/training/training/trainingmonkey/index.ts +26 -0
  120. package/src/training/training/trait-mappings.ts +157 -0
  121. package/src/types.ts +2 -7
  122. package/ALL-test-results.json +0 -1
  123. package/LICENSE +0 -21
  124. package/dist/AgentManifest-CB4xM-Ma.d.ts +0 -704
  125. package/dist/BehaviorTree-BrBFECv5.d.ts +0 -103
  126. package/dist/InvisibleWallet-rtRrBOA8.d.ts +0 -1732
  127. package/dist/OrchestratorAgent-Q_CbVTmO.d.ts +0 -798
  128. package/dist/agents/index.d.ts +0 -1788
  129. package/dist/agents/index.js +0 -4695
  130. package/dist/ai/index.d.ts +0 -1753
  131. package/dist/ai/index.js +0 -5244
  132. package/dist/behavior.d.ts +0 -130
  133. package/dist/behavior.js +0 -407
  134. package/dist/economy/index.d.ts +0 -747
  135. package/dist/economy/index.js +0 -3617
  136. package/dist/implementations-D9T3un9D.d.ts +0 -236
  137. package/dist/index.d.ts +0 -1729
  138. package/dist/index.js +0 -24277
  139. package/dist/learning/index.d.ts +0 -104
  140. package/dist/learning/index.js +0 -189
  141. package/dist/negotiation/index.d.ts +0 -610
  142. package/dist/negotiation/index.js +0 -931
  143. package/dist/skills/index.d.ts +0 -289
  144. package/dist/skills/index.js +0 -1079
  145. package/dist/swarm/index.d.ts +0 -2433
  146. package/dist/swarm/index.js +0 -5221
  147. package/dist/training/index.d.ts +0 -1734
  148. package/dist/training/index.js +0 -2687
  149. package/extract-failures.js +0 -10
  150. package/src/training/training/data/novel-use-cases.jsonl +0 -153
  151. package/src/training/training/data/spatial-reasoning-10k.jsonl +0 -9354
  152. package/src/types/core-stubs.d.ts +0 -113
  153. package/test-output.txt +0 -0
  154. package/test-result.json +0 -1
  155. package/tsc-errors.txt +0 -4
  156. package/tsc_output.txt +0 -0
  157. package/typescript-errors-2.txt +0 -0
  158. package/typescript-errors.txt +0 -22
  159. package/vitest-log-utf8.txt +0 -268
  160. package/vitest-log.txt +0 -0
package/src/team.ts CHANGED
@@ -50,13 +50,19 @@ import { parseDeriveContent, ROOM_PRESETS } from './board';
50
50
  import { MeshDiscovery, SignalService, GossipProtocol } from './mesh';
51
51
  import type { PeerMetadata, GossipPacket } from './mesh';
52
52
  import { BountyManager } from './economy/BountyManager';
53
- import type { Bounty, BountyReward, ClaimResult as BountyClaimResult, CompletionProof, PayoutResult } from './economy/BountyManager';
53
+ import type {
54
+ Bounty,
55
+ BountyReward,
56
+ ClaimResult as BountyClaimResult,
57
+ CompletionProof,
58
+ PayoutResult,
59
+ } from './economy/BountyManager';
54
60
 
55
61
  // ── Mode Claim Filters (FW-0.3) ──
56
62
  // Each mode defines which SlotRoles can actively claim tasks.
57
63
  // Agents whose claimFilter.roles don't overlap with the active set are deprioritized.
58
64
 
59
- const MODE_CLAIM_ROLES: Record<TeamMode, SlotRole[]> = {
65
+ const _MODE_CLAIM_ROLES: Record<TeamMode, SlotRole[]> = {
60
66
  audit: ['researcher', 'reviewer', 'tester'],
61
67
  build: ['coder', 'tester'],
62
68
  research: ['researcher'],
@@ -96,7 +102,7 @@ function computeTier(score: number): ReputationTier {
96
102
  const OPEN_TASK_THRESHOLD = 3;
97
103
 
98
104
  /** Default presence timeouts (FW-0.3). */
99
- const DEFAULT_IDLE_TIMEOUT_MS = 60_000; // 60 seconds
105
+ const DEFAULT_IDLE_TIMEOUT_MS = 60_000; // 60 seconds
100
106
  const DEFAULT_OFFLINE_TIMEOUT_MS = 300_000; // 5 minutes
101
107
 
102
108
  /** Internal record for tracking an agent's presence state. */
@@ -114,7 +120,12 @@ export class Team {
114
120
  private agentConfigs: AgentConfig[];
115
121
  private runtimes: Map<string, AgentRuntime> = new Map();
116
122
  private board: TaskDef[] = [];
117
- private doneLog: Array<{ taskId: string; title: string; completedBy: string; timestamp: string }> = [];
123
+ private doneLog: Array<{
124
+ taskId: string;
125
+ title: string;
126
+ completedBy: string;
127
+ timestamp: string;
128
+ }> = [];
118
129
  private cycle = 0;
119
130
  private consensusMode: ConsensusMode;
120
131
  private proposals: Map<string, InternalProposal> = new Map();
@@ -146,9 +157,7 @@ export class Team {
146
157
  this.idleTimeoutMs = config.presence?.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
147
158
  this.offlineTimeoutMs = config.presence?.offlineTimeoutMs ?? DEFAULT_OFFLINE_TIMEOUT_MS;
148
159
 
149
- this.knowledge = new KnowledgeStore(
150
- config.knowledge ?? { persist: false }
151
- );
160
+ this.knowledge = new KnowledgeStore(config.knowledge ?? { persist: false });
152
161
 
153
162
  // GoalSynthesizer gets knowledge store so it can derive context-aware goals (FW-0.2)
154
163
  // LLM config comes from first agent — all agents on a team typically share a provider.
@@ -218,15 +227,24 @@ export class Team {
218
227
  /** Add tasks to the board. Deduplicates by normalized title. */
219
228
  async addTasks(tasks: Array<Omit<TaskDef, 'id' | 'status' | 'createdAt'>>): Promise<TaskDef[]> {
220
229
  if (this.isRemote) {
221
- const res = await this.boardFetch(`/api/holomesh/team/${encodeURIComponent(this.name)}/board`, 'POST', { tasks });
230
+ const res = await this.boardFetch(
231
+ `/api/holomesh/team/${encodeURIComponent(this.name)}/board`,
232
+ 'POST',
233
+ { tasks }
234
+ );
222
235
  if (res && res.error) throw new Error(String(res.error));
223
236
  return (res?.tasks || res?.added || []) as TaskDef[];
224
237
  }
225
238
 
226
- const normalize = (s: string) => s.toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim().slice(0, 60);
239
+ const normalize = (s: string) =>
240
+ s
241
+ .toLowerCase()
242
+ .replace(/[^a-z0-9]+/g, ' ')
243
+ .trim()
244
+ .slice(0, 60);
227
245
  const existing = new Set([
228
- ...this.board.map(t => normalize(t.title)),
229
- ...this.doneLog.map(d => normalize(d.title)),
246
+ ...this.board.map((t) => normalize(t.title)),
247
+ ...this.doneLog.map((d) => normalize(d.title)),
230
248
  ]);
231
249
 
232
250
  const added: TaskDef[] = [];
@@ -253,9 +271,7 @@ export class Team {
253
271
 
254
272
  /** Get all open tasks, sorted by priority. */
255
273
  get openTasks(): TaskDef[] {
256
- return this.board
257
- .filter(t => t.status === 'open')
258
- .sort((a, b) => a.priority - b.priority);
274
+ return this.board.filter((t) => t.status === 'open').sort((a, b) => a.priority - b.priority);
259
275
  }
260
276
 
261
277
  /** Get all board tasks. */
@@ -302,7 +318,7 @@ export class Team {
302
318
  teamName: this.name,
303
319
  agentName: runtime.name,
304
320
  capabilities: agent.capabilities,
305
- recentCompletedTasks: this.doneLog.slice(-10).map(d => d.title),
321
+ recentCompletedTasks: this.doneLog.slice(-10).map((d) => d.title),
306
322
  };
307
323
  try {
308
324
  const goals = await this.goalSynthesizer.synthesizeMultiple(goalContext, 1);
@@ -344,7 +360,7 @@ export class Team {
344
360
  // Mark done
345
361
  task.status = 'done';
346
362
  task.completedAt = new Date().toISOString();
347
- this.board = this.board.filter(t => t.id !== task.id);
363
+ this.board = this.board.filter((t) => t.id !== task.id);
348
364
  this.doneLog.push({
349
365
  taskId: task.id,
350
366
  title: task.title,
@@ -407,8 +423,9 @@ export class Team {
407
423
 
408
424
  // Fetch board state from remote
409
425
  const boardData = await this.boardFetch(`/api/holomesh/team/${teamId}/board`, 'GET');
410
- const openTasks = ((boardData?.board as Record<string, unknown>)?.open as TaskDef[] || [])
411
- .sort((a, b) => a.priority - b.priority);
426
+ const openTasks = (
427
+ ((boardData?.board as Record<string, unknown>)?.open as TaskDef[]) || []
428
+ ).sort((a, b) => a.priority - b.priority);
412
429
 
413
430
  const claimed = new Set<string>();
414
431
 
@@ -424,25 +441,31 @@ export class Team {
424
441
  const domain = agent.knowledgeDomains?.[0] ?? 'general';
425
442
  let goal: Goal;
426
443
  try {
427
- const goals = await this.goalSynthesizer.synthesizeMultiple({
428
- domain,
429
- teamName: this.name,
430
- agentName: runtime.name,
431
- capabilities: agent.capabilities,
432
- recentCompletedTasks: this.doneLog.slice(-10).map(d => d.title),
433
- }, 1);
444
+ const goals = await this.goalSynthesizer.synthesizeMultiple(
445
+ {
446
+ domain,
447
+ teamName: this.name,
448
+ agentName: runtime.name,
449
+ capabilities: agent.capabilities,
450
+ recentCompletedTasks: this.doneLog.slice(-10).map((d) => d.title),
451
+ },
452
+ 1
453
+ );
434
454
  goal = goals[0] ?? this.goalSynthesizer.synthesize(domain, 'autonomous-boredom');
435
455
  } catch {
436
456
  goal = this.goalSynthesizer.synthesize(domain, 'autonomous-boredom');
437
457
  }
438
458
  const addRes = await this.boardFetch(`/api/holomesh/team/${teamId}/board`, 'POST', {
439
- tasks: [{
440
- title: goal.description,
441
- description: `Autonomously synthesized goal [${goal.category}] — priority ${goal.priority}`,
442
- priority: goal.priority === 'high' ? 2 : goal.priority === 'medium' ? 4 : 6,
443
- role: (agent.role === 'architect' || agent.role === 'researcher') ? 'researcher' : 'coder',
444
- source: `synthesizer:${goal.source}`,
445
- }],
459
+ tasks: [
460
+ {
461
+ title: goal.description,
462
+ description: `Autonomously synthesized goal [${goal.category}] priority ${goal.priority}`,
463
+ priority: goal.priority === 'high' ? 2 : goal.priority === 'medium' ? 4 : 6,
464
+ role:
465
+ agent.role === 'architect' || agent.role === 'researcher' ? 'researcher' : 'coder',
466
+ source: `synthesizer:${goal.source}`,
467
+ },
468
+ ],
446
469
  });
447
470
  const addedTasks = (addRes?.tasks || addRes?.added || []) as TaskDef[];
448
471
  task = addedTasks[0];
@@ -450,7 +473,14 @@ export class Team {
450
473
  }
451
474
 
452
475
  if (!task) {
453
- results.push({ agentName: runtime.name, taskId: null, taskTitle: null, action: 'skipped', summary: 'No matching open tasks', knowledge: [] });
476
+ results.push({
477
+ agentName: runtime.name,
478
+ taskId: null,
479
+ taskTitle: null,
480
+ action: 'skipped',
481
+ summary: 'No matching open tasks',
482
+ knowledge: [],
483
+ });
454
484
  continue;
455
485
  }
456
486
 
@@ -460,9 +490,20 @@ export class Team {
460
490
  this.localHeartbeat(runtime.name, task.title);
461
491
 
462
492
  // Claim via API
463
- const claimRes = await this.boardFetch(`/api/holomesh/team/${teamId}/board/${encodeURIComponent(task.id)}`, 'PATCH', { action: 'claim' });
493
+ const claimRes = await this.boardFetch(
494
+ `/api/holomesh/team/${teamId}/board/${encodeURIComponent(task.id)}`,
495
+ 'PATCH',
496
+ { action: 'claim' }
497
+ );
464
498
  if (claimRes?.error) {
465
- results.push({ agentName: runtime.name, taskId: task.id, taskTitle: task.title, action: 'error', summary: `Claim failed: ${claimRes.error}`, knowledge: [] });
499
+ results.push({
500
+ agentName: runtime.name,
501
+ taskId: task.id,
502
+ taskTitle: task.title,
503
+ action: 'error',
504
+ summary: `Claim failed: ${claimRes.error}`,
505
+ knowledge: [],
506
+ });
466
507
  continue;
467
508
  }
468
509
 
@@ -477,7 +518,11 @@ export class Team {
477
518
  // Proactively buy relevant knowledge if cheap enough (e.g. < 5 credits)
478
519
  const activeListings = this.knowledge.marketplace.activeListings();
479
520
  for (const listing of activeListings) {
480
- if (listing.price <= 5 && listing.currency === 'credits' && task.title.toLowerCase().includes(listing.preview.domain?.toLowerCase() || '')) {
521
+ if (
522
+ listing.price <= 5 &&
523
+ listing.currency === 'credits' &&
524
+ task.title.toLowerCase().includes(listing.preview.domain?.toLowerCase() || '')
525
+ ) {
481
526
  this.knowledge.marketplace.buyKnowledge(listing.id, runtime.name);
482
527
  }
483
528
  }
@@ -487,7 +532,11 @@ export class Team {
487
532
  const { summary, insights } = await this.executeTask(runtime, task);
488
533
 
489
534
  // Mark done via API
490
- await this.boardFetch(`/api/holomesh/team/${teamId}/board/${encodeURIComponent(task.id)}`, 'PATCH', { action: 'done', summary });
535
+ await this.boardFetch(
536
+ `/api/holomesh/team/${teamId}/board/${encodeURIComponent(task.id)}`,
537
+ 'PATCH',
538
+ { action: 'done', summary }
539
+ );
491
540
 
492
541
  // Complete the bounty with proof
493
542
  for (const b of taskBounties) {
@@ -507,11 +556,29 @@ export class Team {
507
556
  runtime.reputationTier = computeTier(runtime.reputationScore);
508
557
 
509
558
  allInsights.push(...insights);
510
- results.push({ agentName: runtime.name, taskId: task.id, taskTitle: task.title, action: synthesized ? 'synthesized' : 'completed', summary, knowledge: insights });
559
+ results.push({
560
+ agentName: runtime.name,
561
+ taskId: task.id,
562
+ taskTitle: task.title,
563
+ action: synthesized ? 'synthesized' : 'completed',
564
+ summary,
565
+ knowledge: insights,
566
+ });
511
567
  } catch (err) {
512
568
  // Reopen task on failure
513
- await this.boardFetch(`/api/holomesh/team/${teamId}/board/${encodeURIComponent(task.id)}`, 'PATCH', { action: 'reopen' });
514
- results.push({ agentName: runtime.name, taskId: task.id, taskTitle: task.title, action: 'error', summary: err instanceof Error ? err.message : String(err), knowledge: [] });
569
+ await this.boardFetch(
570
+ `/api/holomesh/team/${teamId}/board/${encodeURIComponent(task.id)}`,
571
+ 'PATCH',
572
+ { action: 'reopen' }
573
+ );
574
+ results.push({
575
+ agentName: runtime.name,
576
+ taskId: task.id,
577
+ taskTitle: task.title,
578
+ action: 'error',
579
+ summary: err instanceof Error ? err.message : String(err),
580
+ knowledge: [],
581
+ });
515
582
  }
516
583
  }
517
584
 
@@ -522,7 +589,14 @@ export class Team {
522
589
  await this.knowledge.syncToRemote();
523
590
  }
524
591
 
525
- return { teamName: this.name, cycle: this.cycle, agentResults: results, knowledgeProduced: allInsights, compoundedInsights: compounded, durationMs: Date.now() - start };
592
+ return {
593
+ teamName: this.name,
594
+ cycle: this.cycle,
595
+ agentResults: results,
596
+ knowledgeProduced: allInsights,
597
+ compoundedInsights: compounded,
598
+ durationMs: Date.now() - start,
599
+ };
526
600
  }
527
601
 
528
602
  // ── Consensus ──
@@ -549,7 +623,7 @@ export class Team {
549
623
  }
550
624
  }
551
625
 
552
- const votesFor = Array.from(proposal.votes.values()).filter(v => v).length;
626
+ const votesFor = Array.from(proposal.votes.values()).filter((v) => v).length;
553
627
  const votesAgainst = proposal.votes.size - votesFor;
554
628
  const total = proposal.votes.size;
555
629
 
@@ -585,8 +659,7 @@ export class Team {
585
659
 
586
660
  /** Get the reputation leaderboard. */
587
661
  leaderboard(): AgentRuntime[] {
588
- return Array.from(this.runtimes.values())
589
- .sort((a, b) => b.reputationScore - a.reputationScore);
662
+ return Array.from(this.runtimes.values()).sort((a, b) => b.reputationScore - a.reputationScore);
590
663
  }
591
664
 
592
665
  /** Get a specific agent's runtime. */
@@ -615,7 +688,7 @@ export class Team {
615
688
  taskId: String(d.taskId ?? d.task_id ?? ''),
616
689
  title: String(d.title ?? ''),
617
690
  completedBy: String(d.completedBy ?? d.completed_by ?? ''),
618
- commitHash: d.commitHash as string | undefined ?? d.commit_hash as string | undefined,
691
+ commitHash: (d.commitHash as string | undefined) ?? (d.commit_hash as string | undefined),
619
692
  timestamp: String(d.timestamp ?? d.completedAt ?? ''),
620
693
  summary: String(d.summary ?? ''),
621
694
  }));
@@ -666,9 +739,13 @@ export class Team {
666
739
  const trimmedTitle = title.trim().slice(0, 200);
667
740
  if (!trimmedTitle) throw new Error('title is required');
668
741
 
669
- const normalize = (s: string) => s.toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim();
742
+ const normalize = (s: string) =>
743
+ s
744
+ .toLowerCase()
745
+ .replace(/[^a-z0-9]+/g, ' ')
746
+ .trim();
670
747
  const existingNorm = new Set(
671
- this.localSuggestions.filter(s => s.status === 'open').map(s => normalize(s.title))
748
+ this.localSuggestions.filter((s) => s.status === 'open').map((s) => normalize(s.title))
672
749
  );
673
750
  if (existingNorm.has(normalize(trimmedTitle))) {
674
751
  throw new Error('A similar open suggestion already exists');
@@ -697,10 +774,17 @@ export class Team {
697
774
  * Local mode: vote(id, agentName, 'up'|'down', reason?).
698
775
  * Remote mode: vote(id, 1|-1, reason?) for backward compatibility.
699
776
  */
700
- async vote(suggestionId: string, agentNameOrValue: string | 1 | -1, voteOrReason?: 'up' | 'down' | string, reason?: string): Promise<SuggestionVoteResult> {
777
+ async vote(
778
+ suggestionId: string,
779
+ agentNameOrValue: string | 1 | -1,
780
+ voteOrReason?: 'up' | 'down' | string,
781
+ reason?: string
782
+ ): Promise<SuggestionVoteResult> {
701
783
  if (this.isRemote) {
702
- const value = typeof agentNameOrValue === 'number' ? agentNameOrValue : (voteOrReason === 'down' ? -1 : 1);
703
- const remoteReason = typeof agentNameOrValue === 'number' ? (voteOrReason as string | undefined) : reason;
784
+ const value =
785
+ typeof agentNameOrValue === 'number' ? agentNameOrValue : voteOrReason === 'down' ? -1 : 1;
786
+ const remoteReason =
787
+ typeof agentNameOrValue === 'number' ? (voteOrReason as string | undefined) : reason;
704
788
  const teamId = encodeURIComponent(this.name);
705
789
  const res = await this.boardFetch(
706
790
  `/api/holomesh/team/${teamId}/suggestions/${encodeURIComponent(suggestionId)}`,
@@ -713,38 +797,51 @@ export class Team {
713
797
  }
714
798
 
715
799
  const agentName = String(agentNameOrValue);
716
- const voteDir: 'up' | 'down' = (voteOrReason === 'up' || voteOrReason === 'down') ? voteOrReason : 'up';
800
+ const voteDir: 'up' | 'down' =
801
+ voteOrReason === 'up' || voteOrReason === 'down' ? voteOrReason : 'up';
717
802
 
718
- const suggestion = this.localSuggestions.find(s => s.id === suggestionId);
803
+ const suggestion = this.localSuggestions.find((s) => s.id === suggestionId);
719
804
  if (!suggestion) throw new Error('Suggestion not found');
720
- if (suggestion.status !== 'open') throw new Error(`Suggestion is ${suggestion.status}, voting closed`);
721
-
722
- suggestion.votes = suggestion.votes.filter(v => v.agent !== agentName);
723
- suggestion.votes.push({ agent: agentName, vote: voteDir, reason, votedAt: new Date().toISOString() });
805
+ if (suggestion.status !== 'open')
806
+ throw new Error(`Suggestion is ${suggestion.status}, voting closed`);
807
+
808
+ suggestion.votes = suggestion.votes.filter((v) => v.agent !== agentName);
809
+ suggestion.votes.push({
810
+ agent: agentName,
811
+ vote: voteDir,
812
+ reason,
813
+ votedAt: new Date().toISOString(),
814
+ });
724
815
 
725
- const upvotes = suggestion.votes.filter(v => v.vote === 'up').length;
726
- const downvotes = suggestion.votes.filter(v => v.vote === 'down').length;
816
+ const upvotes = suggestion.votes.filter((v) => v.vote === 'up').length;
817
+ const downvotes = suggestion.votes.filter((v) => v.vote === 'down').length;
727
818
  suggestion.score = upvotes - downvotes;
728
819
 
729
820
  let promotedTaskId: string | undefined;
730
821
 
731
- const promoteThreshold = suggestion.autoPromoteThreshold ?? Math.ceil(this.agentConfigs.length / 2);
822
+ const promoteThreshold =
823
+ suggestion.autoPromoteThreshold ?? Math.ceil(this.agentConfigs.length / 2);
732
824
  if (upvotes >= promoteThreshold && suggestion.status === 'open') {
733
825
  suggestion.status = 'promoted';
734
826
  suggestion.resolvedAt = new Date().toISOString();
735
- const promoted = await this.addTasks([{
736
- title: suggestion.title,
737
- description: `${suggestion.description ?? ''}\n\n[Auto-promoted from suggestion by ${suggestion.proposedBy} with ${suggestion.score} net votes]`.trim(),
738
- priority: suggestion.category === 'architecture' ? 2 : suggestion.category === 'testing' ? 3 : 4,
739
- source: `suggestion:${suggestion.id}`,
740
- }]);
827
+ const promoted = await this.addTasks([
828
+ {
829
+ title: suggestion.title,
830
+ description:
831
+ `${suggestion.description ?? ''}\n\n[Auto-promoted from suggestion by ${suggestion.proposedBy} with ${suggestion.score} net votes]`.trim(),
832
+ priority:
833
+ suggestion.category === 'architecture' ? 2 : suggestion.category === 'testing' ? 3 : 4,
834
+ source: `suggestion:${suggestion.id}`,
835
+ },
836
+ ]);
741
837
  if (promoted.length > 0) {
742
838
  promotedTaskId = promoted[0].id;
743
839
  suggestion.promotedTaskId = promotedTaskId;
744
840
  }
745
841
  }
746
842
 
747
- const dismissThreshold = suggestion.autoDismissThreshold ?? Math.ceil(this.agentConfigs.length / 2);
843
+ const dismissThreshold =
844
+ suggestion.autoDismissThreshold ?? Math.ceil(this.agentConfigs.length / 2);
748
845
  if (downvotes >= dismissThreshold && suggestion.status === 'open') {
749
846
  suggestion.status = 'dismissed';
750
847
  suggestion.resolvedAt = new Date().toISOString();
@@ -768,28 +865,36 @@ export class Team {
768
865
  }
769
866
 
770
867
  const filtered = status
771
- ? this.localSuggestions.filter(s => s.status === status)
868
+ ? this.localSuggestions.filter((s) => s.status === status)
772
869
  : [...this.localSuggestions];
773
870
  return { suggestions: filtered };
774
871
  }
775
872
 
776
873
  /** Promote a suggestion to a board task manually. Local-only. */
777
- async promoteSuggestion(suggestionId: string, promoterName?: string): Promise<SuggestionVoteResult> {
778
- if (this.isRemote) throw new Error('promoteSuggestion() is not supported in remote mode — use the board API');
779
-
780
- const suggestion = this.localSuggestions.find(s => s.id === suggestionId);
874
+ async promoteSuggestion(
875
+ suggestionId: string,
876
+ promoterName?: string
877
+ ): Promise<SuggestionVoteResult> {
878
+ if (this.isRemote)
879
+ throw new Error('promoteSuggestion() is not supported in remote mode — use the board API');
880
+
881
+ const suggestion = this.localSuggestions.find((s) => s.id === suggestionId);
781
882
  if (!suggestion) throw new Error('Suggestion not found');
782
883
  if (suggestion.status !== 'open') throw new Error(`Suggestion is already ${suggestion.status}`);
783
884
 
784
885
  suggestion.status = 'promoted';
785
886
  suggestion.resolvedAt = new Date().toISOString();
786
887
 
787
- const promoted = await this.addTasks([{
788
- title: suggestion.title,
789
- description: `${suggestion.description ?? ''}\n\n[Promoted by ${promoterName ?? 'team'} from suggestion by ${suggestion.proposedBy}]`.trim(),
790
- priority: suggestion.category === 'architecture' ? 2 : suggestion.category === 'testing' ? 3 : 4,
791
- source: `suggestion:${suggestion.id}`,
792
- }]);
888
+ const promoted = await this.addTasks([
889
+ {
890
+ title: suggestion.title,
891
+ description:
892
+ `${suggestion.description ?? ''}\n\n[Promoted by ${promoterName ?? 'team'} from suggestion by ${suggestion.proposedBy}]`.trim(),
893
+ priority:
894
+ suggestion.category === 'architecture' ? 2 : suggestion.category === 'testing' ? 3 : 4,
895
+ source: `suggestion:${suggestion.id}`,
896
+ },
897
+ ]);
793
898
 
794
899
  const promotedTaskId = promoted.length > 0 ? promoted[0].id : undefined;
795
900
  suggestion.promotedTaskId = promotedTaskId;
@@ -798,9 +903,10 @@ export class Team {
798
903
 
799
904
  /** Dismiss a suggestion. Local-only. */
800
905
  dismissSuggestion(suggestionId: string): SuggestionVoteResult {
801
- if (this.isRemote) throw new Error('dismissSuggestion() is not supported in remote mode — use the board API');
906
+ if (this.isRemote)
907
+ throw new Error('dismissSuggestion() is not supported in remote mode — use the board API');
802
908
 
803
- const suggestion = this.localSuggestions.find(s => s.id === suggestionId);
909
+ const suggestion = this.localSuggestions.find((s) => s.id === suggestionId);
804
910
  if (!suggestion) throw new Error('Suggestion not found');
805
911
  if (suggestion.status !== 'open') throw new Error(`Suggestion is already ${suggestion.status}`);
806
912
 
@@ -829,7 +935,8 @@ export class Team {
829
935
  /** Switch the team's operating mode. Local-first with optional remote sync. */
830
936
  async setMode(mode: TeamMode): Promise<SetModeResult> {
831
937
  const preset = ROOM_PRESETS[mode];
832
- if (!preset) throw new Error(`Unknown mode: ${mode}. Valid: ${Object.keys(ROOM_PRESETS).join(', ')}`);
938
+ if (!preset)
939
+ throw new Error(`Unknown mode: ${mode}. Valid: ${Object.keys(ROOM_PRESETS).join(', ')}`);
833
940
 
834
941
  const previousMode = this.currentMode;
835
942
  this.currentMode = mode;
@@ -857,7 +964,10 @@ export class Team {
857
964
  async derive(source: string, content: string): Promise<DeriveResult> {
858
965
  if (this.isRemote) {
859
966
  const teamId = encodeURIComponent(this.name);
860
- const res = await this.boardFetch(`/api/holomesh/team/${teamId}/board/derive`, 'POST', { source, content });
967
+ const res = await this.boardFetch(`/api/holomesh/team/${teamId}/board/derive`, 'POST', {
968
+ source,
969
+ content,
970
+ });
861
971
  if (!res) throw new Error('Failed to derive tasks — no response from board');
862
972
  if (res.error) throw new Error(String(res.error));
863
973
  return res as unknown as DeriveResult;
@@ -879,13 +989,18 @@ export class Team {
879
989
  * Modifies both boards. Requires connected remote board.
880
990
  */
881
991
  async delegate(otherTeamId: string, taskId: string): Promise<boolean> {
882
- if (!this.isRemote) throw new Error('Delegation requires a remote board to communicate with other teams');
992
+ if (!this.isRemote)
993
+ throw new Error('Delegation requires a remote board to communicate with other teams');
883
994
  const teamId = encodeURIComponent(this.name);
884
- const res = await this.boardFetch(`/api/holomesh/team/${teamId}/board/${encodeURIComponent(taskId)}`, 'PATCH', {
885
- action: 'delegate',
886
- targetTeamId: otherTeamId
887
- });
888
-
995
+ const res = await this.boardFetch(
996
+ `/api/holomesh/team/${teamId}/board/${encodeURIComponent(taskId)}`,
997
+ 'PATCH',
998
+ {
999
+ action: 'delegate',
1000
+ targetTeamId: otherTeamId,
1001
+ }
1002
+ );
1003
+
889
1004
  if (res?.error) throw new Error(String(res.error));
890
1005
  return true;
891
1006
  }
@@ -945,7 +1060,8 @@ export class Team {
945
1060
 
946
1061
  /** Get presence/slot info for the team. Requires remote board. */
947
1062
  async presence(): Promise<PresenceResult> {
948
- if (!this.isRemote) throw new Error('presence() requires a remote board (boardUrl + boardApiKey)');
1063
+ if (!this.isRemote)
1064
+ throw new Error('presence() requires a remote board (boardUrl + boardApiKey)');
949
1065
  const teamId = encodeURIComponent(this.name);
950
1066
  const res = await this.boardFetch(`/api/holomesh/team/${teamId}/slots`, 'GET');
951
1067
  if (!res) throw new Error('Failed to get presence — no response from board');
@@ -955,7 +1071,8 @@ export class Team {
955
1071
 
956
1072
  /** Send a heartbeat to the team's presence system. Requires remote board. */
957
1073
  async heartbeat(ideType?: string): Promise<HeartbeatResult> {
958
- if (!this.isRemote) throw new Error('heartbeat() requires a remote board (boardUrl + boardApiKey)');
1074
+ if (!this.isRemote)
1075
+ throw new Error('heartbeat() requires a remote board (boardUrl + boardApiKey)');
959
1076
  const teamId = encodeURIComponent(this.name);
960
1077
  const res = await this.boardFetch(`/api/holomesh/team/${teamId}/presence`, 'POST', {
961
1078
  ide_type: ideType ?? 'unknown',
@@ -1021,7 +1138,11 @@ export class Team {
1021
1138
  /** On-demand scout: parse TODO/FIXME content into tasks. */
1022
1139
  async scoutFromTodos(grepOutput: string): Promise<TaskDef[]> {
1023
1140
  if (this.isRemote) {
1024
- const res = await this.boardFetch(`/api/holomesh/team/${encodeURIComponent(this.name)}/board/scout`, 'POST', { todo_content: grepOutput });
1141
+ const res = await this.boardFetch(
1142
+ `/api/holomesh/team/${encodeURIComponent(this.name)}/board/scout`,
1143
+ 'POST',
1144
+ { todo_content: grepOutput }
1145
+ );
1025
1146
  if (res && res.error) throw new Error(String(res.error));
1026
1147
  return (res?.tasks || res?.added || []) as TaskDef[];
1027
1148
  }
@@ -1029,14 +1150,20 @@ export class Team {
1029
1150
  const tasks: Array<Omit<TaskDef, 'id' | 'status' | 'createdAt'>> = [];
1030
1151
 
1031
1152
  for (const line of grepOutput.split('\n')) {
1032
- const match = line.trim().match(/^(.+?):(\d+):\s*(?:\/\/\s*)?(TODO|FIXME|HACK|XXX)\s*:?\s*(.+)$/i);
1153
+ const match = line
1154
+ .trim()
1155
+ .match(/^(.+?):(\d+):\s*(?:\/\/\s*)?(TODO|FIXME|HACK|XXX)\s*:?\s*(.+)$/i);
1033
1156
  if (!match) continue;
1034
1157
 
1035
1158
  const [, file, lineNo, kind, detail] = match;
1036
1159
  const upper = `${kind} ${detail}`.toUpperCase();
1037
- const priority = /SECURITY|VULN|AUTH|CRITICAL/.test(upper) ? 1
1038
- : /FIXME|BUG|BROKEN|ERROR/.test(upper) ? 2
1039
- : /TODO|HACK|REFACTOR/.test(upper) ? 3 : 4;
1160
+ const priority = /SECURITY|VULN|AUTH|CRITICAL/.test(upper)
1161
+ ? 1
1162
+ : /FIXME|BUG|BROKEN|ERROR/.test(upper)
1163
+ ? 2
1164
+ : /TODO|HACK|REFACTOR/.test(upper)
1165
+ ? 3
1166
+ : 4;
1040
1167
 
1041
1168
  tasks.push({
1042
1169
  title: `${kind.toUpperCase()}: ${detail.trim().slice(0, 180)}`,
@@ -1090,7 +1217,7 @@ export class Team {
1090
1217
  }
1091
1218
 
1092
1219
  // Remove the original complex task and add sub-tasks
1093
- this.board = this.board.filter(t => t.id !== task.id);
1220
+ this.board = this.board.filter((t) => t.id !== task.id);
1094
1221
  await this.addTasks(subTasks);
1095
1222
 
1096
1223
  return result;
@@ -1105,31 +1232,50 @@ export class Team {
1105
1232
 
1106
1233
  async listBoard(): Promise<Record<string, unknown>> {
1107
1234
  if (!this.isRemote) throw new Error('listBoard() requires a remote board');
1108
- const res = await this.boardFetch(`/api/holomesh/team/${encodeURIComponent(this.name)}/board`, 'GET');
1235
+ const res = await this.boardFetch(
1236
+ `/api/holomesh/team/${encodeURIComponent(this.name)}/board`,
1237
+ 'GET'
1238
+ );
1109
1239
  if (!res) throw new Error('Failed to list board');
1110
1240
  return res as Record<string, unknown>;
1111
1241
  }
1112
1242
 
1113
1243
  async claimTask(taskId: string): Promise<Record<string, unknown>> {
1114
1244
  if (!this.isRemote) throw new Error('claimTask() requires a remote board');
1115
- const res = await this.boardFetch(`/api/holomesh/team/${encodeURIComponent(this.name)}/board/${encodeURIComponent(taskId)}`, 'PATCH', { action: 'claim' });
1245
+ const res = await this.boardFetch(
1246
+ `/api/holomesh/team/${encodeURIComponent(this.name)}/board/${encodeURIComponent(taskId)}`,
1247
+ 'PATCH',
1248
+ { action: 'claim' }
1249
+ );
1116
1250
  if (!res) throw new Error('Failed to claim task');
1117
1251
  return res as Record<string, unknown>;
1118
1252
  }
1119
1253
 
1120
- async completeTask(taskId: string, commit?: string, summary?: string): Promise<Record<string, unknown>> {
1254
+ async completeTask(
1255
+ taskId: string,
1256
+ commit?: string,
1257
+ summary?: string
1258
+ ): Promise<Record<string, unknown>> {
1121
1259
  if (!this.isRemote) throw new Error('completeTask() requires a remote board');
1122
1260
  const body: Record<string, unknown> = { action: 'done' };
1123
1261
  if (commit) body.commit = commit;
1124
1262
  if (summary) body.summary = summary;
1125
- const res = await this.boardFetch(`/api/holomesh/team/${encodeURIComponent(this.name)}/board/${encodeURIComponent(taskId)}`, 'PATCH', body);
1263
+ const res = await this.boardFetch(
1264
+ `/api/holomesh/team/${encodeURIComponent(this.name)}/board/${encodeURIComponent(taskId)}`,
1265
+ 'PATCH',
1266
+ body
1267
+ );
1126
1268
  if (!res) throw new Error('Failed to complete task');
1127
1269
  return res as Record<string, unknown>;
1128
1270
  }
1129
1271
 
1130
1272
  async assignSlots(roles: string[]): Promise<Record<string, unknown>> {
1131
1273
  if (!this.isRemote) throw new Error('assignSlots() requires a remote board');
1132
- const res = await this.boardFetch(`/api/holomesh/team/${encodeURIComponent(this.name)}/roles`, 'PATCH', { roles });
1274
+ const res = await this.boardFetch(
1275
+ `/api/holomesh/team/${encodeURIComponent(this.name)}/roles`,
1276
+ 'PATCH',
1277
+ { roles }
1278
+ );
1133
1279
  if (!res) throw new Error('Failed to assign slots');
1134
1280
  return res as Record<string, unknown>;
1135
1281
  }
@@ -1139,7 +1285,7 @@ export class Team {
1139
1285
  /** Create a bounty for a board task. */
1140
1286
  createBounty(taskId: string, reward: BountyReward, createdBy: string, deadline?: number): Bounty {
1141
1287
  // Verify the task exists on the board
1142
- const task = this.board.find(t => t.id === taskId);
1288
+ const task = this.board.find((t) => t.id === taskId);
1143
1289
  if (!task) throw new Error(`Task ${taskId} not found on board`);
1144
1290
  return this.bounties.createBounty(taskId, reward, createdBy, deadline);
1145
1291
  }
@@ -1170,7 +1316,10 @@ export class Team {
1170
1316
  title: goal.description,
1171
1317
  description: `Autonomously synthesized goal [${goal.category}] — priority ${goal.priority}`,
1172
1318
  priority: goal.priority === 'high' ? 2 : goal.priority === 'medium' ? 4 : 6,
1173
- role: (agentRole === 'architect' || agentRole === 'researcher') ? 'researcher' as const : 'coder' as const,
1319
+ role:
1320
+ agentRole === 'architect' || agentRole === 'researcher'
1321
+ ? ('researcher' as const)
1322
+ : ('coder' as const),
1174
1323
  source: `synthesizer:${goal.source}`,
1175
1324
  status: 'open',
1176
1325
  createdAt: goal.generatedAt,
@@ -1179,11 +1328,15 @@ export class Team {
1179
1328
  return task;
1180
1329
  }
1181
1330
 
1182
- private findClaimableTask(runtime: AgentRuntime, alreadyClaimed: Set<string>, pool?: TaskDef[]): TaskDef | undefined {
1331
+ private findClaimableTask(
1332
+ runtime: AgentRuntime,
1333
+ alreadyClaimed: Set<string>,
1334
+ pool?: TaskDef[]
1335
+ ): TaskDef | undefined {
1183
1336
  const tasks = pool ?? this.openTasks;
1184
1337
  const agent = runtime.config;
1185
1338
 
1186
- const validTasks = tasks.filter(task => {
1339
+ const validTasks = tasks.filter((task) => {
1187
1340
  if (alreadyClaimed.has(task.id)) return false;
1188
1341
  if (task.priority > agent.claimFilter.maxPriority) return false;
1189
1342
  if (task.role) return agent.claimFilter.roles.includes(task.role);
@@ -1193,23 +1346,25 @@ export class Team {
1193
1346
  if (validTasks.length === 0) return undefined;
1194
1347
 
1195
1348
  // Score and pick highest
1196
- return validTasks.map(task => {
1197
- let score = (10 - task.priority) * 10; // Prioritize higher priority
1198
- score += runtime.reputationScore;
1199
-
1200
- const fullText = `${task.title} ${task.description}`.toLowerCase();
1201
- for (const cap of agent.capabilities || []) {
1202
- if (fullText.includes(cap.toLowerCase())) {
1203
- score += 15; // Capability match bonus
1349
+ return validTasks
1350
+ .map((task) => {
1351
+ let score = (10 - task.priority) * 10; // Prioritize higher priority
1352
+ score += runtime.reputationScore;
1353
+
1354
+ const fullText = `${task.title} ${task.description}`.toLowerCase();
1355
+ for (const cap of agent.capabilities || []) {
1356
+ if (fullText.includes(cap.toLowerCase())) {
1357
+ score += 15; // Capability match bonus
1358
+ }
1204
1359
  }
1205
- }
1206
1360
 
1207
- if (task.role && agent.role === task.role) {
1208
- score += 20; // Exact role match bonus
1209
- }
1361
+ if (task.role && agent.role === task.role) {
1362
+ score += 20; // Exact role match bonus
1363
+ }
1210
1364
 
1211
- return { task, score };
1212
- }).sort((a, b) => b.score - a.score)[0]?.task;
1365
+ return { task, score };
1366
+ })
1367
+ .sort((a, b) => b.score - a.score)[0]?.task;
1213
1368
  }
1214
1369
 
1215
1370
  private async executeTask(
@@ -1217,16 +1372,16 @@ export class Team {
1217
1372
  task: TaskDef
1218
1373
  ): Promise<{ summary: string; insights: KnowledgeInsight[] }> {
1219
1374
  const relevantKnowledge = this.knowledge.search(task.title, 3);
1220
- const knowledgeContext = relevantKnowledge.length > 0
1221
- ? relevantKnowledge.map(k => `[${k.type}] ${k.content}`).join('\n')
1222
- : '';
1375
+ const knowledgeContext =
1376
+ relevantKnowledge.length > 0
1377
+ ? relevantKnowledge.map((k) => `[${k.type}] ${k.content}`).join('\n')
1378
+ : '';
1223
1379
 
1224
1380
  // Run the full 7-phase protocol cycle
1225
1381
  const result = await runProtocolCycle(runtime.config, task, knowledgeContext);
1226
1382
  return { summary: result.summary, insights: result.insights };
1227
1383
  }
1228
1384
 
1229
-
1230
1385
  private async getAgentVote<T>(runtime: AgentRuntime, key: string, value: T): Promise<boolean> {
1231
1386
  const messages: LLMMessage[] = [
1232
1387
  {