@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
@@ -12,8 +12,19 @@ function mockLLM(response: string): LLMAdapter {
12
12
  return { call: vi.fn().mockResolvedValue(response) };
13
13
  }
14
14
 
15
- function phase(id: string, deps: string[] = [], duration = 5000, caps: string[] = ['coding']): MicroPhase {
16
- return { id, description: `Phase ${id}`, dependencies: deps, estimatedDuration: duration, requiredCapabilities: caps };
15
+ function phase(
16
+ id: string,
17
+ deps: string[] = [],
18
+ duration = 5000,
19
+ caps: string[] = ['coding']
20
+ ): MicroPhase {
21
+ return {
22
+ id,
23
+ description: `Phase ${id}`,
24
+ dependencies: deps,
25
+ estimatedDuration: duration,
26
+ requiredCapabilities: caps,
27
+ };
17
28
  }
18
29
 
19
30
  const simpleTask: TaskDescription = {
@@ -30,11 +41,7 @@ describe('SmartMicroPhaseDecomposer', () => {
30
41
  const llm = mockLLM('');
31
42
  const decomposer = new SmartMicroPhaseDecomposer(llm);
32
43
 
33
- const phases: MicroPhase[] = [
34
- phase('a'),
35
- phase('b'),
36
- phase('c'),
37
- ];
44
+ const phases: MicroPhase[] = [phase('a'), phase('b'), phase('c')];
38
45
 
39
46
  const plan = decomposer.buildExecutionPlan(phases);
40
47
 
@@ -49,18 +56,14 @@ describe('SmartMicroPhaseDecomposer', () => {
49
56
  const llm = mockLLM('');
50
57
  const decomposer = new SmartMicroPhaseDecomposer(llm);
51
58
 
52
- const phases: MicroPhase[] = [
53
- phase('a'),
54
- phase('b', ['a']),
55
- phase('c', ['b']),
56
- ];
59
+ const phases: MicroPhase[] = [phase('a'), phase('b', ['a']), phase('c', ['b'])];
57
60
 
58
61
  const plan = decomposer.buildExecutionPlan(phases);
59
62
 
60
63
  expect(plan.waves).toHaveLength(3);
61
- expect(plan.waves[0].map(p => p.id)).toEqual(['a']);
62
- expect(plan.waves[1].map(p => p.id)).toEqual(['b']);
63
- expect(plan.waves[2].map(p => p.id)).toEqual(['c']);
64
+ expect(plan.waves[0].map((p) => p.id)).toEqual(['a']);
65
+ expect(plan.waves[1].map((p) => p.id)).toEqual(['b']);
66
+ expect(plan.waves[2].map((p) => p.id)).toEqual(['c']);
64
67
  expect(plan.totalEstimatedDuration).toBe(15000);
65
68
  expect(plan.parallelizationRatio).toBe(0);
66
69
  });
@@ -84,9 +87,9 @@ describe('SmartMicroPhaseDecomposer', () => {
84
87
  const plan = decomposer.buildExecutionPlan(phases);
85
88
 
86
89
  expect(plan.waves).toHaveLength(3);
87
- expect(plan.waves[0].map(p => p.id)).toEqual(['a']);
88
- expect(plan.waves[1].map(p => p.id).sort()).toEqual(['b', 'c']);
89
- expect(plan.waves[2].map(p => p.id)).toEqual(['d']);
90
+ expect(plan.waves[0].map((p) => p.id)).toEqual(['a']);
91
+ expect(plan.waves[1].map((p) => p.id).sort()).toEqual(['b', 'c']);
92
+ expect(plan.waves[2].map((p) => p.id)).toEqual(['d']);
90
93
  });
91
94
 
92
95
  it('returns empty plan for no phases', () => {
@@ -112,10 +115,7 @@ describe('SmartMicroPhaseDecomposer', () => {
112
115
  const llm = mockLLM('');
113
116
  const decomposer = new SmartMicroPhaseDecomposer(llm);
114
117
 
115
- const phases: MicroPhase[] = [
116
- phase('a', ['b']),
117
- phase('b', ['a']),
118
- ];
118
+ const phases: MicroPhase[] = [phase('a', ['b']), phase('b', ['a'])];
119
119
 
120
120
  expect(() => decomposer.buildExecutionPlan(phases)).toThrow('Circular dependency');
121
121
  });
@@ -150,10 +150,34 @@ describe('SmartMicroPhaseDecomposer', () => {
150
150
  it('parses well-formed LLM JSON response', async () => {
151
151
  const llmResponse = JSON.stringify({
152
152
  phases: [
153
- { id: 'phase_1', description: 'Setup project', dependencies: [], estimatedDuration: 3000, requiredCapabilities: ['coding'] },
154
- { id: 'phase_2', description: 'Write components', dependencies: ['phase_1'], estimatedDuration: 8000, requiredCapabilities: ['coding'] },
155
- { id: 'phase_3', description: 'Write tests', dependencies: ['phase_1'], estimatedDuration: 5000, requiredCapabilities: ['testing'] },
156
- { id: 'phase_4', description: 'Integration test', dependencies: ['phase_2', 'phase_3'], estimatedDuration: 4000, requiredCapabilities: ['testing'] },
153
+ {
154
+ id: 'phase_1',
155
+ description: 'Setup project',
156
+ dependencies: [],
157
+ estimatedDuration: 3000,
158
+ requiredCapabilities: ['coding'],
159
+ },
160
+ {
161
+ id: 'phase_2',
162
+ description: 'Write components',
163
+ dependencies: ['phase_1'],
164
+ estimatedDuration: 8000,
165
+ requiredCapabilities: ['coding'],
166
+ },
167
+ {
168
+ id: 'phase_3',
169
+ description: 'Write tests',
170
+ dependencies: ['phase_1'],
171
+ estimatedDuration: 5000,
172
+ requiredCapabilities: ['testing'],
173
+ },
174
+ {
175
+ id: 'phase_4',
176
+ description: 'Integration test',
177
+ dependencies: ['phase_2', 'phase_3'],
178
+ estimatedDuration: 4000,
179
+ requiredCapabilities: ['testing'],
180
+ },
157
181
  ],
158
182
  });
159
183
 
@@ -169,7 +193,8 @@ describe('SmartMicroPhaseDecomposer', () => {
169
193
  });
170
194
 
171
195
  it('extracts JSON from markdown code blocks', async () => {
172
- const llmResponse = '```json\n{"phases": [{"id": "p1", "description": "Do it", "dependencies": [], "estimatedDuration": 5000, "requiredCapabilities": ["coding"]}]}\n```';
196
+ const llmResponse =
197
+ '```json\n{"phases": [{"id": "p1", "description": "Do it", "dependencies": [], "estimatedDuration": 5000, "requiredCapabilities": ["coding"]}]}\n```';
173
198
 
174
199
  const llm = mockLLM(llmResponse);
175
200
  const decomposer = new SmartMicroPhaseDecomposer(llm);
@@ -200,7 +225,15 @@ describe('SmartMicroPhaseDecomposer', () => {
200
225
 
201
226
  it('does not mark as decomposed when below complexity threshold', async () => {
202
227
  const llmResponse = JSON.stringify({
203
- phases: [{ id: 'only', description: 'Just do it', dependencies: [], estimatedDuration: 3000, requiredCapabilities: ['coding'] }],
228
+ phases: [
229
+ {
230
+ id: 'only',
231
+ description: 'Just do it',
232
+ dependencies: [],
233
+ estimatedDuration: 3000,
234
+ requiredCapabilities: ['coding'],
235
+ },
236
+ ],
204
237
  });
205
238
 
206
239
  const llm = mockLLM(llmResponse);
@@ -214,8 +247,20 @@ describe('SmartMicroPhaseDecomposer', () => {
214
247
  it('respects custom complexity threshold', async () => {
215
248
  const llmResponse = JSON.stringify({
216
249
  phases: [
217
- { id: 'a', description: 'Step A', dependencies: [], estimatedDuration: 3000, requiredCapabilities: ['coding'] },
218
- { id: 'b', description: 'Step B', dependencies: [], estimatedDuration: 3000, requiredCapabilities: ['coding'] },
250
+ {
251
+ id: 'a',
252
+ description: 'Step A',
253
+ dependencies: [],
254
+ estimatedDuration: 3000,
255
+ requiredCapabilities: ['coding'],
256
+ },
257
+ {
258
+ id: 'b',
259
+ description: 'Step B',
260
+ dependencies: [],
261
+ estimatedDuration: 3000,
262
+ requiredCapabilities: ['coding'],
263
+ },
219
264
  ],
220
265
  });
221
266
 
@@ -229,10 +274,34 @@ describe('SmartMicroPhaseDecomposer', () => {
229
274
  it('enforces maxParallelism by adding synthetic dependencies', async () => {
230
275
  const llmResponse = JSON.stringify({
231
276
  phases: [
232
- { id: 'a', description: 'A', dependencies: [], estimatedDuration: 3000, requiredCapabilities: ['coding'] },
233
- { id: 'b', description: 'B', dependencies: [], estimatedDuration: 3000, requiredCapabilities: ['coding'] },
234
- { id: 'c', description: 'C', dependencies: [], estimatedDuration: 3000, requiredCapabilities: ['coding'] },
235
- { id: 'd', description: 'D', dependencies: [], estimatedDuration: 3000, requiredCapabilities: ['coding'] },
277
+ {
278
+ id: 'a',
279
+ description: 'A',
280
+ dependencies: [],
281
+ estimatedDuration: 3000,
282
+ requiredCapabilities: ['coding'],
283
+ },
284
+ {
285
+ id: 'b',
286
+ description: 'B',
287
+ dependencies: [],
288
+ estimatedDuration: 3000,
289
+ requiredCapabilities: ['coding'],
290
+ },
291
+ {
292
+ id: 'c',
293
+ description: 'C',
294
+ dependencies: [],
295
+ estimatedDuration: 3000,
296
+ requiredCapabilities: ['coding'],
297
+ },
298
+ {
299
+ id: 'd',
300
+ description: 'D',
301
+ dependencies: [],
302
+ estimatedDuration: 3000,
303
+ requiredCapabilities: ['coding'],
304
+ },
236
305
  ],
237
306
  });
238
307
 
@@ -272,11 +341,7 @@ describe('SmartMicroPhaseDecomposer', () => {
272
341
  const decomposer = new SmartMicroPhaseDecomposer(llm);
273
342
 
274
343
  // a(5s) and b(5s) in parallel, c(5s) depends on both
275
- const phases = [
276
- phase('a', [], 5000),
277
- phase('b', [], 5000),
278
- phase('c', ['a', 'b'], 5000),
279
- ];
344
+ const phases = [phase('a', [], 5000), phase('b', [], 5000), phase('c', ['a', 'b'], 5000)];
280
345
  const plan = decomposer.buildExecutionPlan(phases);
281
346
 
282
347
  // Sequential: 15000ms, Parallel: 5000 + 5000 = 10000ms
@@ -36,17 +36,21 @@ describe('defineProtocolAgent', () => {
36
36
  // ── Validation ──
37
37
 
38
38
  it('throws on empty name', () => {
39
- expect(() => defineProtocolAgent({ ...BASE_CONFIG, name: '' })).toThrow('Agent name is required');
39
+ expect(() => defineProtocolAgent({ ...BASE_CONFIG, name: '' })).toThrow(
40
+ 'Agent name is required'
41
+ );
40
42
  });
41
43
 
42
44
  it('throws on invalid role', () => {
43
- expect(() => defineProtocolAgent({ ...BASE_CONFIG, role: 'wizard' as never })).toThrow('Invalid role');
45
+ expect(() => defineProtocolAgent({ ...BASE_CONFIG, role: 'wizard' as never })).toThrow(
46
+ 'Invalid role'
47
+ );
44
48
  });
45
49
 
46
50
  it('throws on missing model provider', () => {
47
- expect(() => defineProtocolAgent({ ...BASE_CONFIG, model: { provider: '' as never, model: 'x' } })).toThrow(
48
- 'Agent model must specify provider and model'
49
- );
51
+ expect(() =>
52
+ defineProtocolAgent({ ...BASE_CONFIG, model: { provider: '' as never, model: 'x' } })
53
+ ).toThrow('Agent model must specify provider and model');
50
54
  });
51
55
 
52
56
  it('throws on empty capabilities', () => {
@@ -138,7 +142,7 @@ describe('defineProtocolAgent', () => {
138
142
  expect(handle.status).toBe('cancelled');
139
143
 
140
144
  // At least INTAKE and REFLECT ran, then EXECUTE should be skipped
141
- const skipped = result.phases.filter(p => p.status === 'skipped');
145
+ const skipped = result.phases.filter((p) => p.status === 'skipped');
142
146
  expect(skipped.length).toBeGreaterThan(0);
143
147
  });
144
148
 
@@ -256,7 +260,13 @@ describe('protocolToFrameworkCycleResult', () => {
256
260
  status: 'success',
257
261
  data: {
258
262
  validated: [
259
- { type: 'wisdom', content: 'insight', domain: 'testing', confidence: 0.8, source: 'test' },
263
+ {
264
+ type: 'wisdom',
265
+ content: 'insight',
266
+ domain: 'testing',
267
+ confidence: 0.8,
268
+ source: 'test',
269
+ },
260
270
  ],
261
271
  },
262
272
  durationMs: 50,
@@ -29,8 +29,7 @@ const PHASE_PROMPTS: Record<number, string> = {
29
29
  'You are gathering context for a task. Summarize the task, relevant knowledge, and constraints. Be concise.',
30
30
  [ProtocolPhase.REFLECT]:
31
31
  'You are analyzing an approach. Given the context, identify the best strategy, risks, and key considerations. Be brief.',
32
- [ProtocolPhase.EXECUTE]:
33
- '', // Uses the agent's own system prompt
32
+ [ProtocolPhase.EXECUTE]: '', // Uses the agent's own system prompt
34
33
  [ProtocolPhase.COMPRESS]:
35
34
  'You are extracting knowledge from completed work. Identify Wisdom (insights), Patterns (reusable solutions), and Gotchas (pitfalls). Format each as: [wisdom|pattern|gotcha] content',
36
35
  [ProtocolPhase.REINTAKE]:
@@ -302,11 +301,7 @@ export class ProtocolAgent extends BaseAgent {
302
301
  // ── Helpers ──
303
302
 
304
303
  /** Parse LLM output into KnowledgeInsight[]. */
305
- function parseKnowledgeItems(
306
- content: string,
307
- domain: string,
308
- source: string
309
- ): KnowledgeInsight[] {
304
+ function parseKnowledgeItems(content: string, domain: string, source: string): KnowledgeInsight[] {
310
305
  const insights: KnowledgeInsight[] = [];
311
306
 
312
307
  for (const line of content.split('\n')) {
@@ -344,20 +339,13 @@ export async function runProtocolCycle(
344
339
  });
345
340
 
346
341
  // Extract summary from EXECUTE phase
347
- const executePhase = cycleResult.phases.find(
348
- (p) => p.phase === ProtocolPhase.EXECUTE
349
- );
342
+ const executePhase = cycleResult.phases.find((p) => p.phase === ProtocolPhase.EXECUTE);
350
343
  const summary =
351
- (executePhase?.data as { output?: string })?.output?.slice(0, 500) ??
352
- 'Task completed';
344
+ (executePhase?.data as { output?: string })?.output?.slice(0, 500) ?? 'Task completed';
353
345
 
354
346
  // Extract insights from REINTAKE phase (validated) or COMPRESS phase (raw)
355
- const reintakePhase = cycleResult.phases.find(
356
- (p) => p.phase === ProtocolPhase.REINTAKE
357
- );
358
- const compressPhase = cycleResult.phases.find(
359
- (p) => p.phase === ProtocolPhase.COMPRESS
360
- );
347
+ const reintakePhase = cycleResult.phases.find((p) => p.phase === ProtocolPhase.REINTAKE);
348
+ const compressPhase = cycleResult.phases.find((p) => p.phase === ProtocolPhase.COMPRESS);
361
349
  const insights: KnowledgeInsight[] =
362
350
  (reintakePhase?.data as { validated?: KnowledgeInsight[] })?.validated ??
363
351
  (compressPhase?.data as { insights?: KnowledgeInsight[] })?.insights ??
@@ -383,29 +371,32 @@ export function protocolToFrameworkCycleResult(
383
371
  cycle: number
384
372
  ): FrameworkCycleResult {
385
373
  // Extract insights from compress/reintake phases
386
- const reintake = protocol.phases.find(p => p.phase === ProtocolPhase.REINTAKE);
387
- const compress = protocol.phases.find(p => p.phase === ProtocolPhase.COMPRESS);
374
+ const reintake = protocol.phases.find((p) => p.phase === ProtocolPhase.REINTAKE);
375
+ const compress = protocol.phases.find((p) => p.phase === ProtocolPhase.COMPRESS);
388
376
  const insights: KnowledgeInsight[] =
389
377
  (reintake?.data as { validated?: KnowledgeInsight[] })?.validated ??
390
378
  (compress?.data as { insights?: KnowledgeInsight[] })?.insights ??
391
379
  [];
392
380
 
393
- const executePhase = protocol.phases.find(p => p.phase === ProtocolPhase.EXECUTE);
394
- const summary = (executePhase?.data as { output?: string })?.output?.slice(0, 500) ?? 'Task completed';
381
+ const executePhase = protocol.phases.find((p) => p.phase === ProtocolPhase.EXECUTE);
382
+ const summary =
383
+ (executePhase?.data as { output?: string })?.output?.slice(0, 500) ?? 'Task completed';
395
384
 
396
385
  const hasFailed = protocol.status === 'failed';
397
386
 
398
387
  return {
399
388
  teamName,
400
389
  cycle,
401
- agentResults: [{
402
- agentName: protocol.domain, // best available identifier
403
- taskId: protocol.cycleId,
404
- taskTitle: protocol.task,
405
- action: hasFailed ? 'error' : 'completed',
406
- summary,
407
- knowledge: insights,
408
- }],
390
+ agentResults: [
391
+ {
392
+ agentName: protocol.domain, // best available identifier
393
+ taskId: protocol.cycleId,
394
+ taskTitle: protocol.task,
395
+ action: hasFailed ? 'error' : 'completed',
396
+ summary,
397
+ knowledge: insights,
398
+ },
399
+ ],
409
400
  knowledgeProduced: insights,
410
401
  compoundedInsights: insights.length,
411
402
  durationMs: protocol.totalDurationMs,
@@ -421,7 +412,7 @@ export function frameworkToProtocolCycleResult(
421
412
  domain: string
422
413
  ): ProtocolCycleResult {
423
414
  const now = Date.now();
424
- const hasError = fw.agentResults.some(r => r.action === 'error');
415
+ const hasError = fw.agentResults.some((r) => r.action === 'error');
425
416
 
426
417
  return {
427
418
  cycleId: `cycle_${fw.cycle}_${now.toString(36)}`,
@@ -460,7 +451,7 @@ export function defineProtocolAgent(config: ProtocolAgentConfig): ProtocolAgentH
460
451
  throw new Error('Agent name is required');
461
452
  }
462
453
  const VALID_ROLES = ['architect', 'coder', 'researcher', 'reviewer'] as const;
463
- if (!VALID_ROLES.includes(config.role as typeof VALID_ROLES[number])) {
454
+ if (!VALID_ROLES.includes(config.role as (typeof VALID_ROLES)[number])) {
464
455
  throw new Error(`Invalid role "${config.role}". Valid: ${VALID_ROLES.join(', ')}`);
465
456
  }
466
457
  if (!config.model?.provider || !config.model?.model) {
@@ -472,7 +463,9 @@ export function defineProtocolAgent(config: ProtocolAgentConfig): ProtocolAgentH
472
463
 
473
464
  const protocolStyle = config.protocolStyle ?? 'uaa2';
474
465
  if (protocolStyle !== 'uaa2') {
475
- throw new Error(`Protocol style "${protocolStyle}" is not yet implemented. Only 'uaa2' is supported.`);
466
+ throw new Error(
467
+ `Protocol style "${protocolStyle}" is not yet implemented. Only 'uaa2' is supported.`
468
+ );
476
469
  }
477
470
 
478
471
  // Internal mutable state
@@ -509,7 +502,7 @@ export function defineProtocolAgent(config: ProtocolAgentConfig): ProtocolAgentH
509
502
  // Check pause — wait until resumed
510
503
  if (pauseRequested) {
511
504
  status = 'paused';
512
- await new Promise<void>(resolve => {
505
+ await new Promise<void>((resolve) => {
513
506
  pauseResolver = resolve;
514
507
  });
515
508
  status = 'running';
@@ -555,14 +548,24 @@ export function defineProtocolAgent(config: ProtocolAgentConfig): ProtocolAgentH
555
548
  }
556
549
 
557
550
  const handle: ProtocolAgentHandle = {
558
- get name() { return config.name; },
559
- get role() { return config.role; },
560
- get status() { return status; },
561
- get history() { return [...phaseHistory]; },
551
+ get name() {
552
+ return config.name;
553
+ },
554
+ get role() {
555
+ return config.role;
556
+ },
557
+ get status() {
558
+ return status;
559
+ },
560
+ get history() {
561
+ return [...phaseHistory];
562
+ },
562
563
 
563
564
  async execute(task: { title: string; description: string }): Promise<ProtocolCycleResult> {
564
565
  if (status === 'running') {
565
- throw new Error('Agent is already executing. Await the current execution or cancel() first.');
566
+ throw new Error(
567
+ 'Agent is already executing. Await the current execution or cancel() first.'
568
+ );
566
569
  }
567
570
 
568
571
  status = 'running';
@@ -605,17 +608,17 @@ export function defineProtocolAgent(config: ProtocolAgentConfig): ProtocolAgentH
605
608
  previousData = result.data;
606
609
  }
607
610
 
608
- const hasFailed = phaseResults.some(p => p.status === 'failure');
611
+ const hasFailed = phaseResults.some((p) => p.status === 'failure');
609
612
  const wasCancelled = cancelRequested;
610
613
 
611
- status = wasCancelled ? 'cancelled' : (hasFailed ? 'error' : 'idle');
614
+ status = wasCancelled ? 'cancelled' : hasFailed ? 'error' : 'idle';
612
615
 
613
616
  return {
614
617
  cycleId,
615
618
  task: task.title,
616
619
  domain: agent.identity.domain,
617
620
  phases: phaseResults,
618
- status: wasCancelled ? 'partial' : (hasFailed ? 'partial' : 'complete'),
621
+ status: wasCancelled ? 'partial' : hasFailed ? 'partial' : 'complete',
619
622
  totalDurationMs: Date.now() - startedAt,
620
623
  startedAt,
621
624
  completedAt: Date.now(),
@@ -71,10 +71,11 @@ interface KnowledgeEntry {
71
71
  */
72
72
  export async function scanFramework(config: AbsorbScanConfig = {}): Promise<ScanResult> {
73
73
  const orchestratorUrl = config.orchestratorUrl || DEFAULT_ORCHESTRATOR_URL;
74
- const apiKey = config.mcpApiKey || process.env.MCP_API_KEY || '';
74
+ const apiKey = config.mcpApiKey || process.env.HOLOSCRIPT_API_KEY || '';
75
75
  const workspaceId = config.workspaceId || DEFAULT_WORKSPACE_ID;
76
76
  const maxTasks = config.maxTasks || 20;
77
- const searchQuery = config.searchQuery ||
77
+ const searchQuery =
78
+ config.searchQuery ||
78
79
  'framework improvement opportunities type-safety test-coverage refactoring agents';
79
80
 
80
81
  if (!apiKey) {
@@ -84,7 +85,7 @@ export async function scanFramework(config: AbsorbScanConfig = {}): Promise<Scan
84
85
  issuesFound: 0,
85
86
  improvements: [],
86
87
  knowledge: [],
87
- error: 'MCP_API_KEY required for knowledge store query',
88
+ error: 'HOLOSCRIPT_API_KEY required for knowledge store query',
88
89
  };
89
90
  }
90
91
 
@@ -108,7 +109,7 @@ export async function scanFramework(config: AbsorbScanConfig = {}): Promise<Scan
108
109
  let filesAnalyzed = 0;
109
110
 
110
111
  if (queryRes.ok) {
111
- const data = await queryRes.json() as {
112
+ const data = (await queryRes.json()) as {
112
113
  results?: KnowledgeEntry[];
113
114
  entries?: KnowledgeEntry[];
114
115
  };
@@ -245,8 +246,10 @@ export async function scanTodos(codebasePath: string): Promise<ScanResult> {
245
246
  function categorizeContent(content: string): ImprovementTask['category'] {
246
247
  const lower = content.toLowerCase();
247
248
  if (lower.includes('test') || lower.includes('coverage') || lower.includes('spec')) return 'test';
248
- if (lower.includes('perf') || lower.includes('slow') || lower.includes('optim')) return 'performance';
249
+ if (lower.includes('perf') || lower.includes('slow') || lower.includes('optim'))
250
+ return 'performance';
249
251
  if (lower.includes('doc') || lower.includes('readme') || lower.includes('comment')) return 'docs';
250
- if (lower.includes('type') || lower.includes('any') || lower.includes('cast')) return 'type-safety';
252
+ if (lower.includes('type') || lower.includes('any') || lower.includes('cast'))
253
+ return 'type-safety';
251
254
  return 'refactor';
252
255
  }
@@ -91,7 +91,9 @@ export async function evolve(team: Team, config: EvolutionConfig = {}): Promise<
91
91
  await team.suggest(imp.title, {
92
92
  description: imp.description,
93
93
  category: mapCategory(imp.category),
94
- evidence: imp.file ? `Detected in ${imp.file}${imp.line ? `:${imp.line}` : ''}` : undefined,
94
+ evidence: imp.file
95
+ ? `Detected in ${imp.file}${imp.line ? `:${imp.line}` : ''}`
96
+ : undefined,
95
97
  });
96
98
  suggestionsCreated++;
97
99
  } catch {
@@ -102,9 +104,9 @@ export async function evolve(team: Team, config: EvolutionConfig = {}): Promise<
102
104
 
103
105
  // Step 3: Auto-board critical items
104
106
  if (autoBoard) {
105
- const critical = scan.improvements.filter(imp => imp.priority <= autoBoardMinPriority);
107
+ const critical = scan.improvements.filter((imp) => imp.priority <= autoBoardMinPriority);
106
108
  if (critical.length > 0) {
107
- const tasks = critical.map(imp => ({
109
+ const tasks = critical.map((imp) => ({
108
110
  title: imp.title,
109
111
  description: `[Self-improvement] ${imp.description}`,
110
112
  priority: imp.priority,
@@ -119,31 +121,47 @@ export async function evolve(team: Team, config: EvolutionConfig = {}): Promise<
119
121
  // Step 4: Publish extracted knowledge
120
122
  for (const k of scan.knowledge) {
121
123
  team.knowledge.publish(
122
- { type: k.type, content: k.content, domain: k.domain, confidence: k.confidence, source: 'evolution:self-scan' },
124
+ {
125
+ type: k.type,
126
+ content: k.content,
127
+ domain: k.domain,
128
+ confidence: k.confidence,
129
+ source: 'evolution:self-scan',
130
+ },
123
131
  'evolution-engine'
124
132
  );
125
133
  knowledgePublished++;
126
134
  }
127
135
 
128
136
  // Step 5: Compound
129
- team.knowledge.compound(scan.knowledge.map(k => ({
130
- type: k.type,
131
- content: k.content,
132
- domain: k.domain,
133
- confidence: k.confidence,
134
- source: 'evolution:self-scan',
135
- })));
137
+ team.knowledge.compound(
138
+ scan.knowledge.map((k) => ({
139
+ type: k.type,
140
+ content: k.content,
141
+ domain: k.domain,
142
+ confidence: k.confidence,
143
+ source: 'evolution:self-scan',
144
+ }))
145
+ );
136
146
 
137
147
  return { scan, todoScan, suggestionsCreated, tasksCreated, knowledgePublished };
138
148
  }
139
149
 
140
- function mapCategory(cat: ImprovementTask['category']): 'process' | 'tooling' | 'architecture' | 'testing' | 'docs' | 'performance' | 'other' {
150
+ function mapCategory(
151
+ cat: ImprovementTask['category']
152
+ ): 'process' | 'tooling' | 'architecture' | 'testing' | 'docs' | 'performance' | 'other' {
141
153
  switch (cat) {
142
- case 'refactor': return 'architecture';
143
- case 'test': return 'testing';
144
- case 'docs': return 'docs';
145
- case 'performance': return 'performance';
146
- case 'type-safety': return 'tooling';
147
- default: return 'other';
154
+ case 'refactor':
155
+ return 'architecture';
156
+ case 'test':
157
+ return 'testing';
158
+ case 'docs':
159
+ return 'docs';
160
+ case 'performance':
161
+ return 'performance';
162
+ case 'type-safety':
163
+ return 'tooling';
164
+ default:
165
+ return 'other';
148
166
  }
149
167
  }
@@ -10,7 +10,12 @@
10
10
  * service is unreachable.
11
11
  */
12
12
 
13
- import type { AbsorbScanConfig, ScanResult, ImprovementTask, ExtractedKnowledge } from './absorb-scanner';
13
+ import type {
14
+ AbsorbScanConfig,
15
+ ScanResult,
16
+ ImprovementTask,
17
+ ExtractedKnowledge,
18
+ } from './absorb-scanner';
14
19
  import { scanFramework, scanTodos } from './absorb-scanner';
15
20
 
16
21
  export interface CodebaseGraph {
@@ -117,7 +122,7 @@ export class FrameworkAbsorber {
117
122
  if (rpcResult.result?.content) {
118
123
  // Parse the absorb graph from the MCP response
119
124
  const raw = rpcResult.result.content;
120
- const textContent = raw.find(c => c.text)?.text;
125
+ const textContent = raw.find((c) => c.text)?.text;
121
126
  let parsed: Record<string, unknown> = {};
122
127
  if (textContent) {
123
128
  try {
@@ -129,19 +134,19 @@ export class FrameworkAbsorber {
129
134
  }
130
135
 
131
136
  return {
132
- fileCount: typeof parsed.file_count === 'number'
133
- ? parsed.file_count
134
- : typeof parsed.files === 'number'
135
- ? parsed.files
136
- : 0,
137
- edgeCount: typeof parsed.edge_count === 'number'
138
- ? parsed.edge_count
139
- : typeof parsed.edges === 'number'
140
- ? parsed.edges
141
- : 0,
142
- modules: Array.isArray(parsed.modules)
143
- ? parsed.modules as string[]
144
- : [],
137
+ fileCount:
138
+ typeof parsed.file_count === 'number'
139
+ ? parsed.file_count
140
+ : typeof parsed.files === 'number'
141
+ ? parsed.files
142
+ : 0,
143
+ edgeCount:
144
+ typeof parsed.edge_count === 'number'
145
+ ? parsed.edge_count
146
+ : typeof parsed.edges === 'number'
147
+ ? parsed.edges
148
+ : 0,
149
+ modules: Array.isArray(parsed.modules) ? (parsed.modules as string[]) : [],
145
150
  raw: parsed,
146
151
  };
147
152
  }
@@ -167,7 +172,7 @@ export class FrameworkAbsorber {
167
172
  * Returns ranked improvement list with confidence scores.
168
173
  */
169
174
  async findImprovements(): Promise<Improvement[]> {
170
- const scan = this.lastScan || await this.runFullScan();
175
+ const scan = this.lastScan || (await this.runFullScan());
171
176
  return scan.improvements.map((imp, i) => ({
172
177
  id: `fw-imp-${i}-${Date.now()}`,
173
178
  title: imp.title,