@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
@@ -27,11 +27,15 @@ describe('defineAgent', () => {
27
27
  });
28
28
 
29
29
  it('throws on invalid role', () => {
30
- expect(() => defineAgent({ ...validAgent, role: 'wizard' as unknown as AgentConfig['role'] })).toThrow('Invalid role');
30
+ expect(() =>
31
+ defineAgent({ ...validAgent, role: 'wizard' as unknown as AgentConfig['role'] })
32
+ ).toThrow('Invalid role');
31
33
  });
32
34
 
33
35
  it('throws on missing model', () => {
34
- expect(() => defineAgent({ ...validAgent, model: { provider: 'anthropic', model: '' } })).toThrow('model');
36
+ expect(() =>
37
+ defineAgent({ ...validAgent, model: { provider: 'anthropic', model: '' } })
38
+ ).toThrow('model');
35
39
  });
36
40
 
37
41
  it('throws on empty capabilities', () => {
@@ -80,7 +84,9 @@ describe('defineTeam', () => {
80
84
  });
81
85
 
82
86
  it('throws when agents exceed max slots', () => {
83
- expect(() => defineTeam({ name: 'test', agents: [coder, reviewer], maxSlots: 1 })).toThrow('slots');
87
+ expect(() => defineTeam({ name: 'test', agents: [coder, reviewer], maxSlots: 1 })).toThrow(
88
+ 'slots'
89
+ );
84
90
  });
85
91
  });
86
92
 
@@ -90,11 +96,15 @@ describe('Team.addTasks', () => {
90
96
  it('adds tasks and deduplicates', async () => {
91
97
  const team = defineTeam({
92
98
  name: 'board-test',
93
- agents: [defineAgent({
94
- name: 'A', role: 'coder',
95
- model: { provider: 'anthropic', model: 'claude-sonnet-4' },
96
- capabilities: ['c'], claimFilter: { roles: ['coder'], maxPriority: 10 },
97
- })],
99
+ agents: [
100
+ defineAgent({
101
+ name: 'A',
102
+ role: 'coder',
103
+ model: { provider: 'anthropic', model: 'claude-sonnet-4' },
104
+ capabilities: ['c'],
105
+ claimFilter: { roles: ['coder'], maxPriority: 10 },
106
+ }),
107
+ ],
98
108
  });
99
109
 
100
110
  const added1 = await team.addTasks([
@@ -116,11 +126,15 @@ describe('Team.addTasks', () => {
116
126
  it('sorts open tasks by priority', async () => {
117
127
  const team = defineTeam({
118
128
  name: 'priority-test',
119
- agents: [defineAgent({
120
- name: 'A', role: 'coder',
121
- model: { provider: 'anthropic', model: 'claude-sonnet-4' },
122
- capabilities: ['c'], claimFilter: { roles: ['coder'], maxPriority: 10 },
123
- })],
129
+ agents: [
130
+ defineAgent({
131
+ name: 'A',
132
+ role: 'coder',
133
+ model: { provider: 'anthropic', model: 'claude-sonnet-4' },
134
+ capabilities: ['c'],
135
+ claimFilter: { roles: ['coder'], maxPriority: 10 },
136
+ }),
137
+ ],
124
138
  });
125
139
 
126
140
  await team.addTasks([
@@ -142,11 +156,15 @@ describe('Team.scoutFromTodos', () => {
142
156
  it('parses grep output into tasks', async () => {
143
157
  const team = defineTeam({
144
158
  name: 'scout-test',
145
- agents: [defineAgent({
146
- name: 'A', role: 'coder',
147
- model: { provider: 'anthropic', model: 'claude-sonnet-4' },
148
- capabilities: ['c'], claimFilter: { roles: ['coder'], maxPriority: 10 },
149
- })],
159
+ agents: [
160
+ defineAgent({
161
+ name: 'A',
162
+ role: 'coder',
163
+ model: { provider: 'anthropic', model: 'claude-sonnet-4' },
164
+ capabilities: ['c'],
165
+ claimFilter: { roles: ['coder'], maxPriority: 10 },
166
+ }),
167
+ ],
150
168
  });
151
169
 
152
170
  const grepOutput = [
@@ -173,9 +191,36 @@ describe('KnowledgeStore', () => {
173
191
  it('publishes and searches entries', () => {
174
192
  const store = new KnowledgeStore({ persist: false });
175
193
 
176
- store.publish({ type: 'pattern', content: 'Use JWT for stateless auth', domain: 'security', confidence: 0.9, source: 'Coder' }, 'Coder');
177
- store.publish({ type: 'gotcha', content: 'Never store tokens in localStorage', domain: 'security', confidence: 0.95, source: 'Reviewer' }, 'Reviewer');
178
- store.publish({ type: 'wisdom', content: 'GraphQL reduces over-fetching', domain: 'api', confidence: 0.7, source: 'Researcher' }, 'Researcher');
194
+ store.publish(
195
+ {
196
+ type: 'pattern',
197
+ content: 'Use JWT for stateless auth',
198
+ domain: 'security',
199
+ confidence: 0.9,
200
+ source: 'Coder',
201
+ },
202
+ 'Coder'
203
+ );
204
+ store.publish(
205
+ {
206
+ type: 'gotcha',
207
+ content: 'Never store tokens in localStorage',
208
+ domain: 'security',
209
+ confidence: 0.95,
210
+ source: 'Reviewer',
211
+ },
212
+ 'Reviewer'
213
+ );
214
+ store.publish(
215
+ {
216
+ type: 'wisdom',
217
+ content: 'GraphQL reduces over-fetching',
218
+ domain: 'api',
219
+ confidence: 0.7,
220
+ source: 'Researcher',
221
+ },
222
+ 'Researcher'
223
+ );
179
224
 
180
225
  expect(store.size).toBe(3);
181
226
 
@@ -190,8 +235,26 @@ describe('KnowledgeStore', () => {
190
235
  it('deduplicates identical content', () => {
191
236
  const store = new KnowledgeStore({ persist: false });
192
237
 
193
- const e1 = store.publish({ type: 'wisdom', content: 'Test your code', domain: 'general', confidence: 0.8, source: 'A' }, 'A');
194
- const e2 = store.publish({ type: 'wisdom', content: 'Test your code', domain: 'general', confidence: 0.8, source: 'B' }, 'B');
238
+ const e1 = store.publish(
239
+ {
240
+ type: 'wisdom',
241
+ content: 'Test your code',
242
+ domain: 'general',
243
+ confidence: 0.8,
244
+ source: 'A',
245
+ },
246
+ 'A'
247
+ );
248
+ const e2 = store.publish(
249
+ {
250
+ type: 'wisdom',
251
+ content: 'Test your code',
252
+ domain: 'general',
253
+ confidence: 0.8,
254
+ source: 'B',
255
+ },
256
+ 'B'
257
+ );
195
258
 
196
259
  expect(e1.id).toBe(e2.id); // same entry returned
197
260
  expect(store.size).toBe(1);
@@ -200,11 +263,35 @@ describe('KnowledgeStore', () => {
200
263
  it('compounds cross-domain insights', () => {
201
264
  const store = new KnowledgeStore({ persist: false });
202
265
 
203
- store.publish({ type: 'pattern', content: 'Rate limiting prevents abuse', domain: 'security', confidence: 0.9, source: 'A' }, 'A');
204
- store.publish({ type: 'pattern', content: 'Cache invalidation is hard', domain: 'performance', confidence: 0.8, source: 'B' }, 'B');
266
+ store.publish(
267
+ {
268
+ type: 'pattern',
269
+ content: 'Rate limiting prevents abuse',
270
+ domain: 'security',
271
+ confidence: 0.9,
272
+ source: 'A',
273
+ },
274
+ 'A'
275
+ );
276
+ store.publish(
277
+ {
278
+ type: 'pattern',
279
+ content: 'Cache invalidation is hard',
280
+ domain: 'performance',
281
+ confidence: 0.8,
282
+ source: 'B',
283
+ },
284
+ 'B'
285
+ );
205
286
 
206
287
  const crossRefs = store.compound([
207
- { type: 'wisdom', content: 'Rate limiting and caching need coordination', domain: 'architecture', confidence: 0.7, source: 'C' },
288
+ {
289
+ type: 'wisdom',
290
+ content: 'Rate limiting and caching need coordination',
291
+ domain: 'architecture',
292
+ confidence: 0.7,
293
+ source: 'C',
294
+ },
208
295
  ]);
209
296
 
210
297
  expect(crossRefs).toBeGreaterThan(0);
@@ -216,10 +303,7 @@ describe('KnowledgeStore', () => {
216
303
  describe('Behavior Tree', () => {
217
304
  it('Sequence succeeds when all children succeed', () => {
218
305
  const tree = new BehaviorTree(
219
- new SequenceNode([
220
- new ActionNode('a', () => 'success'),
221
- new ActionNode('b', () => 'success'),
222
- ])
306
+ new SequenceNode([new ActionNode('a', () => 'success'), new ActionNode('b', () => 'success')])
223
307
  );
224
308
  expect(tree.tick(0)).toBe('success');
225
309
  });
@@ -229,7 +313,10 @@ describe('Behavior Tree', () => {
229
313
  const tree = new BehaviorTree(
230
314
  new SequenceNode([
231
315
  new ActionNode('a', () => 'failure'),
232
- new ActionNode('b', () => { bRan = true; return 'success'; }),
316
+ new ActionNode('b', () => {
317
+ bRan = true;
318
+ return 'success';
319
+ }),
233
320
  ])
234
321
  );
235
322
  expect(tree.tick(0)).toBe('failure');
@@ -252,7 +339,10 @@ describe('Behavior Tree', () => {
252
339
  const tree = new BehaviorTree(
253
340
  new SequenceNode([
254
341
  new ConditionNode('check', () => true),
255
- new ActionNode('do', () => { executed = true; return 'success'; }),
342
+ new ActionNode('do', () => {
343
+ executed = true;
344
+ return 'success';
345
+ }),
256
346
  ])
257
347
  );
258
348
  tree.tick(0);
@@ -273,7 +363,13 @@ vi.mock('../protocol-agent', () => ({
273
363
  runProtocolCycle: vi.fn().mockResolvedValue({
274
364
  summary: 'Completed synthesized task',
275
365
  insights: [
276
- { type: 'wisdom', content: 'Autonomous goals keep agents productive', domain: 'security', confidence: 0.7, source: 'Coder' },
366
+ {
367
+ type: 'wisdom',
368
+ content: 'Autonomous goals keep agents productive',
369
+ domain: 'security',
370
+ confidence: 0.7,
371
+ source: 'Coder',
372
+ },
277
373
  ],
278
374
  }),
279
375
  }));
@@ -346,9 +442,11 @@ describe('Goal Synthesis (empty board)', () => {
346
442
 
347
443
  describe('Team remote facade methods', () => {
348
444
  const agent = defineAgent({
349
- name: 'A', role: 'coder',
445
+ name: 'A',
446
+ role: 'coder',
350
447
  model: { provider: 'anthropic', model: 'claude-sonnet-4' },
351
- capabilities: ['c'], claimFilter: { roles: ['coder'], maxPriority: 10 },
448
+ capabilities: ['c'],
449
+ claimFilter: { roles: ['coder'], maxPriority: 10 },
352
450
  });
353
451
 
354
452
  // Helper: create a local-only team (no boardUrl)
@@ -375,8 +473,14 @@ describe('Team remote facade methods', () => {
375
473
 
376
474
  describe('suggest() remote', () => {
377
475
  it('calls POST /suggestions with correct body', async () => {
378
- const { team, fetchSpy } = remoteTeam({ suggestion: { id: 's1', title: 'idea', status: 'open', votes: 0, createdAt: '2026-01-01' } });
379
- const result = await team.suggest('idea', { description: 'desc', category: 'ux', evidence: 'data' });
476
+ const { team, fetchSpy } = remoteTeam({
477
+ suggestion: { id: 's1', title: 'idea', status: 'open', votes: 0, createdAt: '2026-01-01' },
478
+ });
479
+ const result = await team.suggest('idea', {
480
+ description: 'desc',
481
+ category: 'ux',
482
+ evidence: 'data',
483
+ });
380
484
  expect(result.suggestion.id).toBe('s1');
381
485
  expect(fetchSpy).toHaveBeenCalledTimes(1);
382
486
  const [url, opts] = fetchSpy.mock.calls[0];
@@ -401,7 +505,9 @@ describe('Team remote facade methods', () => {
401
505
 
402
506
  describe('vote() remote', () => {
403
507
  it('calls PATCH /suggestions/:id with vote action', async () => {
404
- const { team, fetchSpy } = remoteTeam({ suggestion: { id: 's1', title: 'idea', status: 'open', votes: 1, createdAt: '2026-01-01' } });
508
+ const { team, fetchSpy } = remoteTeam({
509
+ suggestion: { id: 's1', title: 'idea', status: 'open', votes: 1, createdAt: '2026-01-01' },
510
+ });
405
511
  const result = await team.vote('s1', 1, 'good idea');
406
512
  expect(result.suggestion.votes).toBe(1);
407
513
  const [url, opts] = fetchSpy.mock.calls[0];
@@ -494,7 +600,9 @@ describe('Team remote facade methods', () => {
494
600
  });
495
601
 
496
602
  it('calls GET /slots', async () => {
497
- const { team, fetchSpy } = remoteTeam({ slots: [{ agentName: 'A', role: 'coder', status: 'active' }] });
603
+ const { team, fetchSpy } = remoteTeam({
604
+ slots: [{ agentName: 'A', role: 'coder', status: 'active' }],
605
+ });
498
606
  const result = await team.presence();
499
607
  expect(result.slots).toHaveLength(1);
500
608
  expect(result.slots[0].agentName).toBe('A');
@@ -541,14 +649,18 @@ describe('Team remote facade methods', () => {
541
649
 
542
650
  describe('Team local suggestions', () => {
543
651
  const agent1 = defineAgent({
544
- name: 'Alice', role: 'coder',
652
+ name: 'Alice',
653
+ role: 'coder',
545
654
  model: { provider: 'anthropic', model: 'claude-sonnet-4' },
546
- capabilities: ['code-generation'], claimFilter: { roles: ['coder'], maxPriority: 10 },
655
+ capabilities: ['code-generation'],
656
+ claimFilter: { roles: ['coder'], maxPriority: 10 },
547
657
  });
548
658
  const agent2 = defineAgent({
549
- name: 'Bob', role: 'researcher',
659
+ name: 'Bob',
660
+ role: 'researcher',
550
661
  model: { provider: 'anthropic', model: 'claude-sonnet-4' },
551
- capabilities: ['research'], claimFilter: { roles: ['researcher'], maxPriority: 10 },
662
+ capabilities: ['research'],
663
+ claimFilter: { roles: ['researcher'], maxPriority: 10 },
552
664
  });
553
665
 
554
666
  function makeTeam() {
@@ -599,7 +711,7 @@ describe('Team local suggestions', () => {
599
711
 
600
712
  it('allows resubmission after dismiss', async () => {
601
713
  const team = makeTeam();
602
- const { suggestion } = (await team.suggest('Add caching'));
714
+ const { suggestion } = await team.suggest('Add caching');
603
715
  team.dismissSuggestion(suggestion.id);
604
716
  // Should not throw — dismissed suggestions don't block new ones
605
717
  const result = await team.suggest('Add caching');
@@ -659,7 +771,7 @@ describe('Team local suggestions', () => {
659
771
  expect(result.promotedTaskId).toBeDefined();
660
772
  expect(result.promotedTaskId).toMatch(/^task_/);
661
773
  // Verify task was added to board
662
- expect(team.openTasks.some(t => t.source === `suggestion:${suggestion.id}`)).toBe(true);
774
+ expect(team.openTasks.some((t) => t.source === `suggestion:${suggestion.id}`)).toBe(true);
663
775
  });
664
776
 
665
777
  it('auto-dismisses when downvotes reach threshold', async () => {
@@ -733,7 +845,7 @@ describe('Team local suggestions', () => {
733
845
  const result = await team.promoteSuggestion(suggestion.id, 'Bob');
734
846
  expect(result.suggestion.status).toBe('promoted');
735
847
  expect(result.promotedTaskId).toBeDefined();
736
- const task = team.openTasks.find(t => t.id === result.promotedTaskId);
848
+ const task = team.openTasks.find((t) => t.id === result.promotedTaskId);
737
849
  expect(task).toBeDefined();
738
850
  expect(task!.title).toBe('Build widget');
739
851
  expect(task!.description).toContain('Promoted by Bob');
@@ -756,7 +868,7 @@ describe('Team local suggestions', () => {
756
868
  const team = makeTeam();
757
869
  const { suggestion } = await team.suggest('Restructure', { category: 'architecture' });
758
870
  const result = await team.promoteSuggestion(suggestion.id);
759
- const task = team.openTasks.find(t => t.id === result.promotedTaskId);
871
+ const task = team.openTasks.find((t) => t.id === result.promotedTaskId);
760
872
  expect(task!.priority).toBe(2);
761
873
  });
762
874
 
@@ -764,7 +876,7 @@ describe('Team local suggestions', () => {
764
876
  const team = makeTeam();
765
877
  const { suggestion } = await team.suggest('Add tests', { category: 'testing' });
766
878
  const result = await team.promoteSuggestion(suggestion.id);
767
- const task = team.openTasks.find(t => t.id === result.promotedTaskId);
879
+ const task = team.openTasks.find((t) => t.id === result.promotedTaskId);
768
880
  expect(task!.priority).toBe(3);
769
881
  });
770
882
  });
@@ -787,8 +899,10 @@ describe('Team local suggestions', () => {
787
899
 
788
900
  it('throws on remote team', async () => {
789
901
  const team = defineTeam({
790
- name: 'remote', agents: [agent1],
791
- boardUrl: 'https://example.com', boardApiKey: 'key',
902
+ name: 'remote',
903
+ agents: [agent1],
904
+ boardUrl: 'https://example.com',
905
+ boardApiKey: 'key',
792
906
  });
793
907
  expect(() => team.dismissSuggestion('s1')).toThrow('not supported in remote mode');
794
908
  });
@@ -799,7 +913,8 @@ describe('Team local suggestions', () => {
799
913
 
800
914
  describe('Team mesh integration', () => {
801
915
  const agent1: AgentConfig = {
802
- name: 'Coder1', role: 'coder',
916
+ name: 'Coder1',
917
+ role: 'coder',
803
918
  model: { provider: 'anthropic', model: 'claude-sonnet-4' },
804
919
  capabilities: ['code-gen', 'testing'],
805
920
  claimFilter: { roles: ['coder'], maxPriority: 8 },
@@ -822,8 +937,12 @@ describe('Team mesh integration', () => {
822
937
  it('registerPeer() + peers() returns registered peer', () => {
823
938
  const team = mkTeam();
824
939
  team.registerPeer({
825
- id: 'peer-1', hostname: 'localhost', port: 3000,
826
- version: '1.0.0', agentCount: 2, capabilities: ['code'],
940
+ id: 'peer-1',
941
+ hostname: 'localhost',
942
+ port: 3000,
943
+ version: '1.0.0',
944
+ agentCount: 2,
945
+ capabilities: ['code'],
827
946
  lastSeen: Date.now(),
828
947
  });
829
948
  expect(team.peers()).toHaveLength(1);
@@ -142,13 +142,16 @@ describe('GoalSynthesizer', () => {
142
142
  it('filters out recently completed tasks', async () => {
143
143
  const gs = new GoalSynthesizer();
144
144
  const completed = GENERIC_GOALS.slice(0, 4);
145
- const goals = await gs.synthesizeMultiple({
146
- domain: 'general',
147
- recentCompletedTasks: completed,
148
- }, 3);
145
+ const goals = await gs.synthesizeMultiple(
146
+ {
147
+ domain: 'general',
148
+ recentCompletedTasks: completed,
149
+ },
150
+ 3
151
+ );
149
152
  // None of the returned goals should match completed tasks
150
153
  for (const g of goals) {
151
- expect(completed.map(c => c.toLowerCase())).not.toContain(g.description.toLowerCase());
154
+ expect(completed.map((c) => c.toLowerCase())).not.toContain(g.description.toLowerCase());
152
155
  }
153
156
  });
154
157
 
@@ -208,7 +211,7 @@ describe('GoalSynthesizer', () => {
208
211
  // Request enough goals to ensure the knowledge-derived one is included
209
212
  const goals = await gs.synthesizeMultiple({ domain: 'security' }, 15);
210
213
 
211
- const knowledgeGapGoals = goals.filter(g => g.category === 'knowledge-gap');
214
+ const knowledgeGapGoals = goals.filter((g) => g.category === 'knowledge-gap');
212
215
  // At least one goal should be derived from the gotcha
213
216
  expect(knowledgeGapGoals.length).toBeGreaterThanOrEqual(1);
214
217
  const derived = knowledgeGapGoals[0];
@@ -70,7 +70,7 @@ describe('Local Presence Tracking (FW-0.3)', () => {
70
70
  team.localHeartbeat('Bob', 'Task B');
71
71
  const agents = team.localPresence();
72
72
  expect(agents).toHaveLength(2);
73
- const names = agents.map(a => a.name).sort();
73
+ const names = agents.map((a) => a.name).sort();
74
74
  expect(names).toEqual(['Alice', 'Bob']);
75
75
  });
76
76
  });
@@ -80,7 +80,9 @@ describe('ProtocolAgent', () => {
80
80
  });
81
81
 
82
82
  it('execute phase calls LLM with full model', async () => {
83
- fetchSpy.mockResolvedValue(mockFetchResponse('Fixed the authentication bug by updating JWT validation'));
83
+ fetchSpy.mockResolvedValue(
84
+ mockFetchResponse('Fixed the authentication bug by updating JWT validation')
85
+ );
84
86
 
85
87
  const agent = new ProtocolAgent(testAgent);
86
88
  const plan = { plan: 'Use TDD', context: { task: 'Fix auth bug' } };
@@ -101,8 +103,8 @@ describe('ProtocolAgent', () => {
101
103
  fetchSpy.mockResolvedValue(
102
104
  mockFetchResponse(
103
105
  '[wisdom] JWT tokens should be validated on every request\n' +
104
- '[pattern] Use middleware for auth validation\n' +
105
- '[gotcha] Never store refresh tokens in localStorage'
106
+ '[pattern] Use middleware for auth validation\n' +
107
+ '[gotcha] Never store refresh tokens in localStorage'
106
108
  )
107
109
  );
108
110
 
@@ -168,7 +170,10 @@ describe('runProtocolCycle', () => {
168
170
  // Phase 2 (execute): full model
169
171
  if (callCount === 2) return mockFetchResponse('SUMMARY: Fixed JWT validation\nDone.');
170
172
  // Phase 3 (compress): extract knowledge
171
- if (callCount === 3) return mockFetchResponse('[wisdom] Always validate token expiry\n[pattern] Use middleware for auth');
173
+ if (callCount === 3)
174
+ return mockFetchResponse(
175
+ '[wisdom] Always validate token expiry\n[pattern] Use middleware for auth'
176
+ );
172
177
  // Phase 4 (reintake): validate
173
178
  if (callCount === 4) return mockFetchResponse('[wisdom] Always validate token expiry');
174
179
  // Phase 5 (grow): patterns
@@ -196,9 +201,7 @@ describe('runProtocolCycle', () => {
196
201
  });
197
202
 
198
203
  it('returns summary from execute phase even when compress finds nothing', async () => {
199
- fetchSpy.mockImplementation(async () =>
200
- mockFetchResponse('Completed the task successfully')
201
- );
204
+ fetchSpy.mockImplementation(async () => mockFetchResponse('Completed the task successfully'));
202
205
 
203
206
  const result = await runProtocolCycle(
204
207
  testAgent,
@@ -218,9 +221,7 @@ describe('runProtocolCycle', () => {
218
221
  model: { provider: 'openai', model: 'gpt-4o', apiKey: 'test-key' },
219
222
  };
220
223
 
221
- fetchSpy.mockImplementation(async () =>
222
- mockOpenAIResponse('Task done')
223
- );
224
+ fetchSpy.mockImplementation(async () => mockOpenAIResponse('Task done'));
224
225
 
225
226
  const result = await runProtocolCycle(
226
227
  openaiAgent,
@@ -248,7 +249,7 @@ describe('runProtocolCycle', () => {
248
249
  // Should still return a result (BaseAgent catches phase errors)
249
250
  expect(result.phaseResults.length).toBeGreaterThan(0);
250
251
  // The reflect phase should fail, which cascades
251
- const reflectPhase = result.phaseResults.find(p => p.phase === ProtocolPhase.REFLECT);
252
+ const reflectPhase = result.phaseResults.find((p) => p.phase === ProtocolPhase.REFLECT);
252
253
  expect(reflectPhase?.status).toBe('failure');
253
254
  });
254
255
  });
@@ -39,10 +39,13 @@ describe('RevenueSplitter', () => {
39
39
  });
40
40
 
41
41
  it('throws on basis points not summing to 10000', () => {
42
- expect(() => new RevenueSplitter([
43
- { id: 'a', basisPoints: 5000 },
44
- { id: 'b', basisPoints: 4000 },
45
- ])).toThrow('sum to 10000');
42
+ expect(
43
+ () =>
44
+ new RevenueSplitter([
45
+ { id: 'a', basisPoints: 5000 },
46
+ { id: 'b', basisPoints: 4000 },
47
+ ])
48
+ ).toThrow('sum to 10000');
46
49
  });
47
50
 
48
51
  it('throws on empty recipients', () => {
@@ -50,23 +53,27 @@ describe('RevenueSplitter', () => {
50
53
  });
51
54
 
52
55
  it('throws on negative basis points', () => {
53
- expect(() => new RevenueSplitter([
54
- { id: 'a', basisPoints: -1000 },
55
- { id: 'b', basisPoints: 11000 },
56
- ])).toThrow('Negative');
56
+ expect(
57
+ () =>
58
+ new RevenueSplitter([
59
+ { id: 'a', basisPoints: -1000 },
60
+ { id: 'b', basisPoints: 11000 },
61
+ ])
62
+ ).toThrow('Negative');
57
63
  });
58
64
 
59
65
  it('throws on duplicate IDs', () => {
60
- expect(() => new RevenueSplitter([
61
- { id: 'a', basisPoints: 5000 },
62
- { id: 'a', basisPoints: 5000 },
63
- ])).toThrow('Duplicate');
66
+ expect(
67
+ () =>
68
+ new RevenueSplitter([
69
+ { id: 'a', basisPoints: 5000 },
70
+ { id: 'a', basisPoints: 5000 },
71
+ ])
72
+ ).toThrow('Duplicate');
64
73
  });
65
74
 
66
75
  it('throws on negative amount', () => {
67
- const splitter = new RevenueSplitter([
68
- { id: 'a', basisPoints: 10000 },
69
- ]);
76
+ const splitter = new RevenueSplitter([{ id: 'a', basisPoints: 10000 }]);
70
77
  expect(() => splitter.split(-1n)).toThrow('negative');
71
78
  });
72
79