@holoscript/framework 6.0.3

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 (329) hide show
  1. package/ALL-test-results.json +1 -0
  2. package/CHANGELOG.md +8 -0
  3. package/LICENSE +21 -0
  4. package/ROADMAP.md +175 -0
  5. package/dist/AgentManifest-CB4xM-Ma.d.cts +704 -0
  6. package/dist/AgentManifest-CB4xM-Ma.d.ts +704 -0
  7. package/dist/BehaviorTree-BrBFECv5.d.cts +103 -0
  8. package/dist/BehaviorTree-BrBFECv5.d.ts +103 -0
  9. package/dist/InvisibleWallet-BB6tFvRA.d.cts +1732 -0
  10. package/dist/InvisibleWallet-rtRrBOA8.d.ts +1732 -0
  11. package/dist/OrchestratorAgent-BvWgf9uw.d.cts +798 -0
  12. package/dist/OrchestratorAgent-Q_CbVTmO.d.ts +798 -0
  13. package/dist/agents/index.cjs +4790 -0
  14. package/dist/agents/index.d.cts +1788 -0
  15. package/dist/agents/index.d.ts +1788 -0
  16. package/dist/agents/index.js +4695 -0
  17. package/dist/ai/index.cjs +5347 -0
  18. package/dist/ai/index.d.cts +1753 -0
  19. package/dist/ai/index.d.ts +1753 -0
  20. package/dist/ai/index.js +5244 -0
  21. package/dist/behavior.cjs +449 -0
  22. package/dist/behavior.d.cts +130 -0
  23. package/dist/behavior.d.ts +130 -0
  24. package/dist/behavior.js +407 -0
  25. package/dist/economy/index.cjs +3659 -0
  26. package/dist/economy/index.d.cts +747 -0
  27. package/dist/economy/index.d.ts +747 -0
  28. package/dist/economy/index.js +3617 -0
  29. package/dist/implementations-D9T3un9D.d.cts +236 -0
  30. package/dist/implementations-D9T3un9D.d.ts +236 -0
  31. package/dist/index.cjs +24550 -0
  32. package/dist/index.d.cts +1729 -0
  33. package/dist/index.d.ts +1729 -0
  34. package/dist/index.js +24277 -0
  35. package/dist/learning/index.cjs +219 -0
  36. package/dist/learning/index.d.cts +104 -0
  37. package/dist/learning/index.d.ts +104 -0
  38. package/dist/learning/index.js +189 -0
  39. package/dist/negotiation/index.cjs +970 -0
  40. package/dist/negotiation/index.d.cts +610 -0
  41. package/dist/negotiation/index.d.ts +610 -0
  42. package/dist/negotiation/index.js +931 -0
  43. package/dist/skills/index.cjs +1118 -0
  44. package/dist/skills/index.d.cts +289 -0
  45. package/dist/skills/index.d.ts +289 -0
  46. package/dist/skills/index.js +1079 -0
  47. package/dist/swarm/index.cjs +5268 -0
  48. package/dist/swarm/index.d.cts +2433 -0
  49. package/dist/swarm/index.d.ts +2433 -0
  50. package/dist/swarm/index.js +5221 -0
  51. package/dist/training/index.cjs +2745 -0
  52. package/dist/training/index.d.cts +1734 -0
  53. package/dist/training/index.d.ts +1734 -0
  54. package/dist/training/index.js +2687 -0
  55. package/extract-failures.js +10 -0
  56. package/package.json +82 -0
  57. package/src/__tests__/bounty-marketplace.test.ts +374 -0
  58. package/src/__tests__/delegation.test.ts +144 -0
  59. package/src/__tests__/distributed-claimer.test.ts +147 -0
  60. package/src/__tests__/done-log-audit.test.ts +342 -0
  61. package/src/__tests__/framework.test.ts +865 -0
  62. package/src/__tests__/goal-synthesizer.test.ts +236 -0
  63. package/src/__tests__/presence.test.ts +223 -0
  64. package/src/__tests__/protocol-agent.test.ts +254 -0
  65. package/src/__tests__/revenue-splitter.test.ts +114 -0
  66. package/src/__tests__/scenario-driven-todo.test.ts +197 -0
  67. package/src/__tests__/self-improve.test.ts +349 -0
  68. package/src/__tests__/service-lifecycle.test.ts +237 -0
  69. package/src/__tests__/skill-router.test.ts +121 -0
  70. package/src/agents/AgentManifest.ts +493 -0
  71. package/src/agents/AgentRegistry.ts +475 -0
  72. package/src/agents/AgentTypes.ts +585 -0
  73. package/src/agents/AgentWalletRegistry.ts +83 -0
  74. package/src/agents/AuthenticatedCRDT.ts +388 -0
  75. package/src/agents/CapabilityMatcher.ts +453 -0
  76. package/src/agents/CrossRealityHandoff.ts +305 -0
  77. package/src/agents/CulturalMemory.ts +454 -0
  78. package/src/agents/FederatedRegistryAdapter.ts +429 -0
  79. package/src/agents/NormEngine.ts +450 -0
  80. package/src/agents/OrchestratorAgent.ts +414 -0
  81. package/src/agents/SkillWorkflowEngine.ts +472 -0
  82. package/src/agents/TaskDelegationService.ts +551 -0
  83. package/src/agents/__tests__/AgentManifest.prod.test.ts +134 -0
  84. package/src/agents/__tests__/AgentManifest.test.ts +182 -0
  85. package/src/agents/__tests__/AgentModule.test.ts +864 -0
  86. package/src/agents/__tests__/AgentRegistry.prod.test.ts +125 -0
  87. package/src/agents/__tests__/AgentRegistry.test.ts +148 -0
  88. package/src/agents/__tests__/AgentTypes.test.ts +534 -0
  89. package/src/agents/__tests__/AgentWalletRegistry.test.ts +152 -0
  90. package/src/agents/__tests__/AuthenticatedCRDT.test.ts +558 -0
  91. package/src/agents/__tests__/CapabilityMatcher.prod.test.ts +117 -0
  92. package/src/agents/__tests__/CapabilityMatcher.test.ts +178 -0
  93. package/src/agents/__tests__/CrossRealityHandoff.test.ts +402 -0
  94. package/src/agents/__tests__/CulturalMemory.test.ts +200 -0
  95. package/src/agents/__tests__/FederatedRegistryAdapter.test.ts +409 -0
  96. package/src/agents/__tests__/NormEngine.test.ts +276 -0
  97. package/src/agents/__tests__/OrchestratorAgent.test.ts +182 -0
  98. package/src/agents/__tests__/SkillWorkflowEngine.test.ts +357 -0
  99. package/src/agents/__tests__/TaskDelegationService.test.ts +446 -0
  100. package/src/agents/index.ts +107 -0
  101. package/src/agents/spatial-comms/Layer1RealTime.ts +621 -0
  102. package/src/agents/spatial-comms/Layer2A2A.ts +661 -0
  103. package/src/agents/spatial-comms/Layer3MCP.ts +651 -0
  104. package/src/agents/spatial-comms/ProtocolTypes.ts +543 -0
  105. package/src/agents/spatial-comms/SpatialCommClient.ts +483 -0
  106. package/src/agents/spatial-comms/__tests__/performance-benchmark.test.ts +465 -0
  107. package/src/agents/spatial-comms/examples/multi-agent-world-creation.ts +409 -0
  108. package/src/agents/spatial-comms/index.ts +66 -0
  109. package/src/ai/AIAdapter.ts +313 -0
  110. package/src/ai/AICopilot.ts +331 -0
  111. package/src/ai/AIOutputValidator.ts +203 -0
  112. package/src/ai/BTNodes.ts +239 -0
  113. package/src/ai/BehaviorSelector.ts +135 -0
  114. package/src/ai/BehaviorTree.ts +153 -0
  115. package/src/ai/Blackboard.ts +165 -0
  116. package/src/ai/GenerationAnalytics.ts +461 -0
  117. package/src/ai/GenerationCache.ts +265 -0
  118. package/src/ai/GoalPlanner.ts +165 -0
  119. package/src/ai/HoloScriptGenerator.ts +580 -0
  120. package/src/ai/InfluenceMap.ts +180 -0
  121. package/src/ai/NavMesh.ts +168 -0
  122. package/src/ai/PerceptionSystem.ts +178 -0
  123. package/src/ai/PromptTemplates.ts +453 -0
  124. package/src/ai/SemanticSearchService.ts +80 -0
  125. package/src/ai/StateMachine.ts +196 -0
  126. package/src/ai/SteeringBehavior.ts +150 -0
  127. package/src/ai/SteeringBehaviors.ts +244 -0
  128. package/src/ai/TrainingDataGenerator.ts +1082 -0
  129. package/src/ai/UtilityAI.ts +145 -0
  130. package/src/ai/__tests__/AIAdapter.prod.test.ts +259 -0
  131. package/src/ai/__tests__/AIAdapter.test.ts +109 -0
  132. package/src/ai/__tests__/AICopilot.prod.test.ts +341 -0
  133. package/src/ai/__tests__/AICopilot.test.ts +178 -0
  134. package/src/ai/__tests__/AIOutputValidator.prod.test.ts +226 -0
  135. package/src/ai/__tests__/AIOutputValidator.test.ts +138 -0
  136. package/src/ai/__tests__/BTNodes.prod.test.ts +391 -0
  137. package/src/ai/__tests__/BTNodes.test.ts +263 -0
  138. package/src/ai/__tests__/BehaviorSelector.prod.test.ts +129 -0
  139. package/src/ai/__tests__/BehaviorSelector.test.ts +132 -0
  140. package/src/ai/__tests__/BehaviorTree.prod.test.ts +266 -0
  141. package/src/ai/__tests__/BehaviorTree.test.ts +216 -0
  142. package/src/ai/__tests__/Blackboard.prod.test.ts +339 -0
  143. package/src/ai/__tests__/Blackboard.test.ts +183 -0
  144. package/src/ai/__tests__/GenerationAnalytics.prod.test.ts +141 -0
  145. package/src/ai/__tests__/GenerationAnalytics.test.ts +165 -0
  146. package/src/ai/__tests__/GenerationCache.prod.test.ts +144 -0
  147. package/src/ai/__tests__/GenerationCache.test.ts +171 -0
  148. package/src/ai/__tests__/GoalPlanner.prod.test.ts +189 -0
  149. package/src/ai/__tests__/GoalPlanner.test.ts +137 -0
  150. package/src/ai/__tests__/GoalPlannerDepth.prod.test.ts +217 -0
  151. package/src/ai/__tests__/HoloScriptGenerator.test.ts +125 -0
  152. package/src/ai/__tests__/InfluenceMap.prod.test.ts +146 -0
  153. package/src/ai/__tests__/InfluenceMap.test.ts +149 -0
  154. package/src/ai/__tests__/NavMesh.prod.test.ts +141 -0
  155. package/src/ai/__tests__/NavMesh.test.ts +159 -0
  156. package/src/ai/__tests__/PerceptionSystem.prod.test.ts +135 -0
  157. package/src/ai/__tests__/PerceptionSystem.test.ts +250 -0
  158. package/src/ai/__tests__/PromptTemplates.prod.test.ts +313 -0
  159. package/src/ai/__tests__/PromptTemplates.test.ts +146 -0
  160. package/src/ai/__tests__/SemanticSearch.test.ts +37 -0
  161. package/src/ai/__tests__/StateMachine.prod.test.ts +162 -0
  162. package/src/ai/__tests__/StateMachine.test.ts +163 -0
  163. package/src/ai/__tests__/SteeringBehavior.prod.test.ts +251 -0
  164. package/src/ai/__tests__/SteeringBehavior.test.ts +135 -0
  165. package/src/ai/__tests__/SteeringBehaviors.prod.test.ts +133 -0
  166. package/src/ai/__tests__/SteeringBehaviors.test.ts +151 -0
  167. package/src/ai/__tests__/TrainingDataGenerator.prod.test.ts +286 -0
  168. package/src/ai/__tests__/TrainingDataGenerator.test.ts +286 -0
  169. package/src/ai/__tests__/UtilityAI.prod.test.ts +207 -0
  170. package/src/ai/__tests__/UtilityAI.test.ts +155 -0
  171. package/src/ai/__tests__/adapters.prod.test.ts +263 -0
  172. package/src/ai/__tests__/adapters.test.ts +320 -0
  173. package/src/ai/adapters.ts +1585 -0
  174. package/src/ai/index.ts +130 -0
  175. package/src/behavior/BehaviorPresets.ts +140 -0
  176. package/src/behavior/BehaviorTree.ts +236 -0
  177. package/src/behavior/StateMachine.ts +176 -0
  178. package/src/behavior/StateTrait.ts +67 -0
  179. package/src/behavior/index.ts +8 -0
  180. package/src/behavior.ts +8 -0
  181. package/src/board/audit.ts +284 -0
  182. package/src/board/board-ops.ts +336 -0
  183. package/src/board/board-types.ts +302 -0
  184. package/src/board/index.ts +69 -0
  185. package/src/define-agent.ts +46 -0
  186. package/src/define-team.ts +33 -0
  187. package/src/delegation.ts +265 -0
  188. package/src/distributed-claimer.ts +228 -0
  189. package/src/economy/AgentBudgetEnforcer.ts +464 -0
  190. package/src/economy/BountyManager.ts +185 -0
  191. package/src/economy/CreatorRevenueAggregator.ts +460 -0
  192. package/src/economy/InvisibleWallet.ts +82 -0
  193. package/src/economy/KnowledgeMarketplace.ts +193 -0
  194. package/src/economy/PaymentWebhookService.ts +512 -0
  195. package/src/economy/RevenueSplitter.ts +156 -0
  196. package/src/economy/SubscriptionManager.ts +546 -0
  197. package/src/economy/UnifiedBudgetOptimizer.ts +635 -0
  198. package/src/economy/UsageMeter.ts +440 -0
  199. package/src/economy/_core-stubs.ts +219 -0
  200. package/src/economy/index.ts +100 -0
  201. package/src/economy/x402-facilitator.ts +1978 -0
  202. package/src/index.ts +348 -0
  203. package/src/knowledge/__tests__/knowledge-consolidator.test.ts +444 -0
  204. package/src/knowledge/__tests__/knowledge-store-vector.test.ts +291 -0
  205. package/src/knowledge/brain.ts +167 -0
  206. package/src/knowledge/consolidation.ts +581 -0
  207. package/src/knowledge/knowledge-consolidator.ts +510 -0
  208. package/src/knowledge/knowledge-store.ts +616 -0
  209. package/src/learning/MemoryConsolidator.ts +102 -0
  210. package/src/learning/MemoryScorer.ts +69 -0
  211. package/src/learning/ProceduralCompiler.ts +45 -0
  212. package/src/learning/SemanticClusterer.ts +66 -0
  213. package/src/learning/index.ts +8 -0
  214. package/src/llm/llm-adapter.ts +159 -0
  215. package/src/mesh/index.ts +309 -0
  216. package/src/negotiation/NegotiationProtocol.ts +694 -0
  217. package/src/negotiation/NegotiationTypes.ts +473 -0
  218. package/src/negotiation/VotingMechanisms.ts +691 -0
  219. package/src/negotiation/index.ts +49 -0
  220. package/src/protocol/goal-synthesizer.ts +317 -0
  221. package/src/protocol/implementations.ts +474 -0
  222. package/src/protocol/micro-phase-decomposer.ts +299 -0
  223. package/src/protocol/micro-step-decomposer.test.ts +306 -0
  224. package/src/protocol-agent.test.ts +353 -0
  225. package/src/protocol-agent.ts +670 -0
  226. package/src/self-improve/absorb-scanner.ts +252 -0
  227. package/src/self-improve/evolution-engine.ts +149 -0
  228. package/src/self-improve/framework-absorber.ts +214 -0
  229. package/src/self-improve/index.ts +50 -0
  230. package/src/self-improve/prompt-optimizer.ts +212 -0
  231. package/src/self-improve/test-generator.ts +175 -0
  232. package/src/skill-router.ts +186 -0
  233. package/src/skills/index.ts +5 -0
  234. package/src/skills/skill-md-bridge.ts +1699 -0
  235. package/src/swarm/ACOEngine.ts +261 -0
  236. package/src/swarm/CollectiveIntelligence.ts +383 -0
  237. package/src/swarm/ContributionSynthesizer.ts +481 -0
  238. package/src/swarm/LeaderElection.ts +393 -0
  239. package/src/swarm/PSOEngine.ts +206 -0
  240. package/src/swarm/QuorumPolicy.ts +173 -0
  241. package/src/swarm/SwarmCoordinator.ts +335 -0
  242. package/src/swarm/SwarmManager.ts +442 -0
  243. package/src/swarm/SwarmMembership.ts +456 -0
  244. package/src/swarm/VotingRound.ts +255 -0
  245. package/src/swarm/__tests__/ACOEngine.prod.test.ts +164 -0
  246. package/src/swarm/__tests__/ACOEngine.test.ts +117 -0
  247. package/src/swarm/__tests__/CollectiveIntelligence.prod.test.ts +296 -0
  248. package/src/swarm/__tests__/CollectiveIntelligence.test.ts +457 -0
  249. package/src/swarm/__tests__/ContributionSynthesizer.prod.test.ts +269 -0
  250. package/src/swarm/__tests__/ContributionSynthesizer.test.ts +254 -0
  251. package/src/swarm/__tests__/LeaderElection.prod.test.ts +196 -0
  252. package/src/swarm/__tests__/LeaderElection.test.ts +151 -0
  253. package/src/swarm/__tests__/PSOEngine.prod.test.ts +162 -0
  254. package/src/swarm/__tests__/PSOEngine.test.ts +106 -0
  255. package/src/swarm/__tests__/QuorumPolicy.prod.test.ts +216 -0
  256. package/src/swarm/__tests__/QuorumPolicy.test.ts +177 -0
  257. package/src/swarm/__tests__/SwarmCoordinator.prod.test.ts +186 -0
  258. package/src/swarm/__tests__/SwarmCoordinator.test.ts +167 -0
  259. package/src/swarm/__tests__/SwarmManager.prod.test.ts +308 -0
  260. package/src/swarm/__tests__/SwarmManager.test.ts +373 -0
  261. package/src/swarm/__tests__/SwarmMembership.prod.test.ts +273 -0
  262. package/src/swarm/__tests__/SwarmMembership.test.ts +264 -0
  263. package/src/swarm/__tests__/VotingRound.prod.test.ts +233 -0
  264. package/src/swarm/__tests__/VotingRound.test.ts +174 -0
  265. package/src/swarm/analytics/SwarmInspector.ts +476 -0
  266. package/src/swarm/analytics/SwarmMetrics.ts +449 -0
  267. package/src/swarm/analytics/__tests__/SwarmInspector.prod.test.ts +366 -0
  268. package/src/swarm/analytics/__tests__/SwarmInspector.test.ts +454 -0
  269. package/src/swarm/analytics/__tests__/SwarmMetrics.prod.test.ts +254 -0
  270. package/src/swarm/analytics/__tests__/SwarmMetrics.test.ts +370 -0
  271. package/src/swarm/analytics/index.ts +7 -0
  272. package/src/swarm/index.ts +69 -0
  273. package/src/swarm/messaging/BroadcastChannel.ts +509 -0
  274. package/src/swarm/messaging/GossipProtocol.ts +565 -0
  275. package/src/swarm/messaging/SwarmEventBus.ts +443 -0
  276. package/src/swarm/messaging/__tests__/BroadcastChannel.prod.test.ts +331 -0
  277. package/src/swarm/messaging/__tests__/BroadcastChannel.test.ts +333 -0
  278. package/src/swarm/messaging/__tests__/GossipProtocol.prod.test.ts +356 -0
  279. package/src/swarm/messaging/__tests__/GossipProtocol.test.ts +437 -0
  280. package/src/swarm/messaging/__tests__/SwarmEventBus.prod.test.ts +191 -0
  281. package/src/swarm/messaging/__tests__/SwarmEventBus.test.ts +247 -0
  282. package/src/swarm/messaging/index.ts +8 -0
  283. package/src/swarm/spatial/FlockingBehavior.ts +462 -0
  284. package/src/swarm/spatial/FormationController.ts +500 -0
  285. package/src/swarm/spatial/Vector3.ts +170 -0
  286. package/src/swarm/spatial/ZoneClaiming.ts +509 -0
  287. package/src/swarm/spatial/__tests__/FlockingBehavior.prod.test.ts +239 -0
  288. package/src/swarm/spatial/__tests__/FlockingBehavior.test.ts +298 -0
  289. package/src/swarm/spatial/__tests__/FormationController.prod.test.ts +240 -0
  290. package/src/swarm/spatial/__tests__/FormationController.test.ts +297 -0
  291. package/src/swarm/spatial/__tests__/Vector3.prod.test.ts +283 -0
  292. package/src/swarm/spatial/__tests__/Vector3.test.ts +224 -0
  293. package/src/swarm/spatial/__tests__/ZoneClaiming.prod.test.ts +246 -0
  294. package/src/swarm/spatial/__tests__/ZoneClaiming.test.ts +374 -0
  295. package/src/swarm/spatial/index.ts +28 -0
  296. package/src/team.ts +1245 -0
  297. package/src/training/LRScheduler.ts +377 -0
  298. package/src/training/QualityScoringPipeline.ts +139 -0
  299. package/src/training/SoftDedup.ts +461 -0
  300. package/src/training/SparsityMonitor.ts +685 -0
  301. package/src/training/SparsityMonitorTypes.ts +209 -0
  302. package/src/training/SpatialTrainingDataGenerator.ts +1526 -0
  303. package/src/training/SpatialTrainingDataTypes.ts +216 -0
  304. package/src/training/TrainingPipelineConfig.ts +215 -0
  305. package/src/training/constants.ts +94 -0
  306. package/src/training/index.ts +138 -0
  307. package/src/training/schema.ts +147 -0
  308. package/src/training/scripts/generate-novel-use-cases-dataset.ts +272 -0
  309. package/src/training/scripts/generate-spatial-dataset.ts +521 -0
  310. package/src/training/training/data/novel-use-cases.jsonl +153 -0
  311. package/src/training/training/data/spatial-reasoning-10k.jsonl +9354 -0
  312. package/src/training/trainingmonkey/TrainingMonkeyIntegration.ts +477 -0
  313. package/src/training/trainingmonkey/TrainingMonkeyTypes.ts +230 -0
  314. package/src/training/trainingmonkey/index.ts +26 -0
  315. package/src/training/trait-mappings.ts +157 -0
  316. package/src/types/core-stubs.d.ts +113 -0
  317. package/src/types.ts +304 -0
  318. package/test-output.txt +0 -0
  319. package/test-result.json +1 -0
  320. package/tsc-errors.txt +4 -0
  321. package/tsc_output.txt +0 -0
  322. package/tsconfig.json +14 -0
  323. package/tsup-learning-esm.config.ts +12 -0
  324. package/tsup.config.ts +21 -0
  325. package/typescript-errors-2.txt +0 -0
  326. package/typescript-errors.txt +22 -0
  327. package/vitest-log-utf8.txt +268 -0
  328. package/vitest-log.txt +0 -0
  329. package/vitest.config.ts +8 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Knowledge Marketplace — Buy, sell, and price knowledge entries via x402 micropayments.
3
+ *
4
+ * Enables agents to monetize their discovered W/P/G entries.
5
+ * Integrates with KnowledgeStore for entry lookup and X402Facilitator for settlement.
6
+ *
7
+ * FW-0.6
8
+ */
9
+
10
+ import type { StoredEntry } from '../knowledge/knowledge-store';
11
+ import type { KnowledgeInsight } from '../types';
12
+
13
+ // ── Types ──
14
+
15
+ export type ListingStatus = 'active' | 'sold' | 'delisted';
16
+
17
+ export interface KnowledgeListing {
18
+ id: string;
19
+ entryId: string;
20
+ seller: string;
21
+ price: number;
22
+ /** Currency: 'USDC' for x402 settlement, 'credits' for in-memory ledger. */
23
+ currency: 'USDC' | 'credits';
24
+ status: ListingStatus;
25
+ createdAt: string;
26
+ /** Entry snapshot for buyer preview (type + domain + truncated content). */
27
+ preview: {
28
+ type: KnowledgeInsight['type'];
29
+ domain: string;
30
+ snippet: string;
31
+ };
32
+ }
33
+
34
+ export interface PurchaseResult {
35
+ success: boolean;
36
+ listingId: string;
37
+ entryId?: string;
38
+ buyer: string;
39
+ price: number;
40
+ error?: string;
41
+ }
42
+
43
+ export interface ListingResult {
44
+ success: boolean;
45
+ listingId: string;
46
+ error?: string;
47
+ }
48
+
49
+ export interface PricingFactors {
50
+ /** Base price per type: wisdom > pattern > gotcha. */
51
+ typeWeights?: Record<KnowledgeInsight['type'], number>;
52
+ /** Multiplier for high-confidence entries (confidence >= 0.8). */
53
+ confidenceMultiplier?: number;
54
+ /** Multiplier for high-reuse entries (reuseCount >= 5). */
55
+ reuseMultiplier?: number;
56
+ }
57
+
58
+ const DEFAULT_TYPE_WEIGHTS: Record<KnowledgeInsight['type'], number> = {
59
+ wisdom: 0.05,
60
+ pattern: 0.03,
61
+ gotcha: 0.02,
62
+ };
63
+
64
+ // ── Marketplace ──
65
+
66
+ export class KnowledgeMarketplace {
67
+ private listings: Map<string, KnowledgeListing> = new Map();
68
+ private purchases: Map<string, PurchaseResult[]> = new Map(); // buyer -> purchases
69
+ private nextId = 1;
70
+ private pricingFactors: PricingFactors;
71
+
72
+ constructor(pricingFactors?: PricingFactors) {
73
+ this.pricingFactors = pricingFactors ?? {};
74
+ }
75
+
76
+ /** Estimate the value of a knowledge entry (in USDC). */
77
+ priceKnowledge(entry: StoredEntry): number {
78
+ const weights = this.pricingFactors.typeWeights ?? DEFAULT_TYPE_WEIGHTS;
79
+ let price = weights[entry.type] ?? 0.02;
80
+
81
+ // Confidence boost
82
+ if (entry.confidence >= 0.8) {
83
+ price *= (this.pricingFactors.confidenceMultiplier ?? 1.5);
84
+ }
85
+
86
+ // Reuse boost — popular entries are worth more
87
+ if (entry.reuseCount >= 5) {
88
+ price *= (this.pricingFactors.reuseMultiplier ?? 2.0);
89
+ }
90
+
91
+ // Query frequency boost
92
+ if (entry.queryCount >= 10) {
93
+ price *= 1.25;
94
+ }
95
+
96
+ // Round to 4 decimal places
97
+ return Math.round(price * 10_000) / 10_000;
98
+ }
99
+
100
+ /** List a knowledge entry for sale. */
101
+ sellKnowledge(entry: StoredEntry, price: number, seller: string, currency: 'USDC' | 'credits' = 'USDC'): ListingResult {
102
+ if (price <= 0) return { success: false, listingId: '', error: 'Price must be positive' };
103
+
104
+ // Prevent duplicate listings for same entry
105
+ for (const listing of this.listings.values()) {
106
+ if (listing.entryId === entry.id && listing.status === 'active') {
107
+ return { success: false, listingId: listing.id, error: 'Entry already listed' };
108
+ }
109
+ }
110
+
111
+ const id = `listing_${String(this.nextId++).padStart(4, '0')}`;
112
+
113
+ const listing: KnowledgeListing = {
114
+ id,
115
+ entryId: entry.id,
116
+ seller,
117
+ price,
118
+ currency,
119
+ status: 'active',
120
+ createdAt: new Date().toISOString(),
121
+ preview: {
122
+ type: entry.type,
123
+ domain: entry.domain,
124
+ snippet: entry.content.slice(0, 100),
125
+ },
126
+ };
127
+
128
+ this.listings.set(id, listing);
129
+ return { success: true, listingId: id };
130
+ }
131
+
132
+ /** Buy a listed knowledge entry. */
133
+ buyKnowledge(listingId: string, buyer: string): PurchaseResult {
134
+ const listing = this.listings.get(listingId);
135
+ if (!listing) return { success: false, listingId, buyer, price: 0, error: 'Listing not found' };
136
+ if (listing.status !== 'active') return { success: false, listingId, buyer, price: listing.price, error: `Listing is ${listing.status}` };
137
+ if (listing.seller === buyer) return { success: false, listingId, buyer, price: listing.price, error: 'Cannot buy your own listing' };
138
+
139
+ listing.status = 'sold';
140
+
141
+ const result: PurchaseResult = {
142
+ success: true,
143
+ listingId,
144
+ entryId: listing.entryId,
145
+ buyer,
146
+ price: listing.price,
147
+ };
148
+
149
+ // Track purchases per buyer
150
+ const buyerPurchases = this.purchases.get(buyer) ?? [];
151
+ buyerPurchases.push(result);
152
+ this.purchases.set(buyer, buyerPurchases);
153
+
154
+ return result;
155
+ }
156
+
157
+ /** Get a listing by ID. */
158
+ getListing(listingId: string): KnowledgeListing | undefined {
159
+ return this.listings.get(listingId);
160
+ }
161
+
162
+ /** List all active listings. */
163
+ activeListings(): KnowledgeListing[] {
164
+ return Array.from(this.listings.values()).filter(l => l.status === 'active');
165
+ }
166
+
167
+ /** Get purchase history for a buyer. */
168
+ purchaseHistory(buyer: string): PurchaseResult[] {
169
+ return this.purchases.get(buyer) ?? [];
170
+ }
171
+
172
+ /** Delist an entry (only the seller can delist). */
173
+ delist(listingId: string, seller: string): boolean {
174
+ const listing = this.listings.get(listingId);
175
+ if (!listing || listing.seller !== seller || listing.status !== 'active') return false;
176
+ listing.status = 'delisted';
177
+ return true;
178
+ }
179
+
180
+ /** Total revenue for a seller across all sold listings. */
181
+ sellerRevenue(seller: string): number {
182
+ return Array.from(this.listings.values())
183
+ .filter(l => l.seller === seller && l.status === 'sold')
184
+ .reduce((sum, l) => sum + l.price, 0);
185
+ }
186
+
187
+ /** Total marketplace volume (all completed sales). */
188
+ totalVolume(): number {
189
+ return Array.from(this.listings.values())
190
+ .filter(l => l.status === 'sold')
191
+ .reduce((sum, l) => sum + l.price, 0);
192
+ }
193
+ }
@@ -0,0 +1,512 @@
1
+ /**
2
+ * PaymentWebhookService — Webhook processing for payment confirmations
3
+ *
4
+ * Receives payment provider webhooks, verifies HMAC-SHA256 signatures,
5
+ * updates LedgerEntry settlement status, and emits telemetry events.
6
+ *
7
+ * Part of HoloScript v5.8 "Live Economy".
8
+ *
9
+ * @version 1.0.0
10
+ */
11
+
12
+ import type { TelemetryCollector } from './_core-stubs';
13
+ import type { LedgerEntry } from './x402-facilitator';
14
+
15
+ // =============================================================================
16
+ // TYPES
17
+ // =============================================================================
18
+
19
+ /**
20
+ * Supported webhook providers.
21
+ */
22
+ export type WebhookProvider = 'x402' | 'stripe' | 'coinbase' | 'custom';
23
+
24
+ /**
25
+ * Webhook event types.
26
+ */
27
+ export type WebhookEventType =
28
+ | 'payment.confirmed'
29
+ | 'payment.failed'
30
+ | 'payment.refunded'
31
+ | 'settlement.completed'
32
+ | 'settlement.failed'
33
+ | 'subscription.renewed'
34
+ | 'subscription.cancelled';
35
+
36
+ /**
37
+ * Incoming webhook payload.
38
+ */
39
+ export interface WebhookPayload {
40
+ /** Provider-specific event ID */
41
+ eventId: string;
42
+ /** Event type */
43
+ type: WebhookEventType;
44
+ /** Provider name */
45
+ provider: WebhookProvider;
46
+ /** Timestamp of the event (ISO 8601) */
47
+ timestamp: string;
48
+ /** Provider-specific data */
49
+ data: Record<string, unknown>;
50
+ /** Ledger entry ID (if applicable) */
51
+ ledgerEntryId?: string;
52
+ /** Transaction hash (if on-chain) */
53
+ transactionHash?: string;
54
+ /** Amount in USDC base units */
55
+ amount?: number;
56
+ /** Payer identifier */
57
+ payer?: string;
58
+ /** Recipient identifier */
59
+ recipient?: string;
60
+ }
61
+
62
+ /**
63
+ * Webhook verification result.
64
+ */
65
+ export interface WebhookVerificationResult {
66
+ /** Whether the webhook signature is valid */
67
+ verified: boolean;
68
+ /** Provider name */
69
+ provider: WebhookProvider;
70
+ /** Error message if verification failed */
71
+ error?: string;
72
+ /** Parsed payload (if verified) */
73
+ payload?: WebhookPayload;
74
+ }
75
+
76
+ /**
77
+ * Webhook processing result.
78
+ */
79
+ export interface WebhookProcessingResult {
80
+ /** Whether processing succeeded */
81
+ success: boolean;
82
+ /** Event ID that was processed */
83
+ eventId: string;
84
+ /** Event type */
85
+ type: WebhookEventType;
86
+ /** Updated ledger entry (if applicable) */
87
+ updatedEntry?: LedgerEntry;
88
+ /** Error message if processing failed */
89
+ error?: string;
90
+ }
91
+
92
+ /**
93
+ * Webhook handler function type.
94
+ */
95
+ export type WebhookHandler = (
96
+ payload: WebhookPayload
97
+ ) => Promise<WebhookProcessingResult> | WebhookProcessingResult;
98
+
99
+ /**
100
+ * Configuration for the webhook service.
101
+ */
102
+ export interface WebhookServiceConfig {
103
+ /** HMAC secrets per provider */
104
+ secrets: Partial<Record<WebhookProvider, string>>;
105
+ /** Maximum age for webhook events (ms, default: 5 minutes) */
106
+ maxAgeMs?: number;
107
+ /** Maximum retry attempts for failed deliveries */
108
+ maxRetries?: number;
109
+ /** Retry backoff base (ms) */
110
+ retryBackoffMs?: number;
111
+ /** Telemetry collector */
112
+ telemetry?: TelemetryCollector;
113
+ }
114
+
115
+ /**
116
+ * Retry queue entry.
117
+ */
118
+ interface RetryEntry {
119
+ payload: WebhookPayload;
120
+ attempts: number;
121
+ nextRetryAt: number;
122
+ lastError?: string;
123
+ }
124
+
125
+ // =============================================================================
126
+ // HMAC UTILITIES
127
+ // =============================================================================
128
+
129
+ /**
130
+ * Compute HMAC-SHA256 hex digest (Node.js crypto).
131
+ */
132
+ function computeHmac(payload: string, secret: string): string {
133
+ // Use dynamic import pattern to work in both Node and test environments
134
+ try {
135
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
136
+ const crypto = require('crypto');
137
+ return crypto.createHmac('sha256', secret).update(payload).digest('hex');
138
+ } catch {
139
+ // Fallback for environments without crypto
140
+ // Simple hash for testing — never use in production
141
+ let hash = 0;
142
+ const combined = payload + secret;
143
+ for (let i = 0; i < combined.length; i++) {
144
+ const char = combined.charCodeAt(i);
145
+ hash = (hash << 5) - hash + char;
146
+ hash = hash & hash; // Convert to 32-bit integer
147
+ }
148
+ return Math.abs(hash).toString(16).padStart(8, '0');
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Timing-safe string comparison.
154
+ */
155
+ function timingSafeEqual(a: string, b: string): boolean {
156
+ if (a.length !== b.length) return false;
157
+ let result = 0;
158
+ for (let i = 0; i < a.length; i++) {
159
+ result |= a.charCodeAt(i) ^ b.charCodeAt(i);
160
+ }
161
+ return result === 0;
162
+ }
163
+
164
+ // =============================================================================
165
+ // PAYMENT WEBHOOK SERVICE
166
+ // =============================================================================
167
+
168
+ export class PaymentWebhookService {
169
+ private config: Required<Omit<WebhookServiceConfig, 'telemetry'>> & {
170
+ telemetry?: TelemetryCollector;
171
+ };
172
+ private handlers: Map<WebhookEventType, WebhookHandler[]> = new Map();
173
+ private processedEvents: Set<string> = new Set();
174
+ private retryQueue: RetryEntry[] = [];
175
+ private ledgerUpdateCallback?: (entryId: string, updates: Partial<LedgerEntry>) => void;
176
+
177
+ // Stats
178
+ private stats = {
179
+ received: 0,
180
+ verified: 0,
181
+ processed: 0,
182
+ failed: 0,
183
+ retried: 0,
184
+ rejected: 0,
185
+ duplicates: 0,
186
+ };
187
+
188
+ constructor(config: WebhookServiceConfig) {
189
+ this.config = {
190
+ secrets: config.secrets,
191
+ maxAgeMs: config.maxAgeMs ?? 5 * 60 * 1000, // 5 minutes
192
+ maxRetries: config.maxRetries ?? 3,
193
+ retryBackoffMs: config.retryBackoffMs ?? 1000,
194
+ telemetry: config.telemetry,
195
+ };
196
+ }
197
+
198
+ // ===========================================================================
199
+ // VERIFICATION
200
+ // ===========================================================================
201
+
202
+ /**
203
+ * Verify a webhook's HMAC-SHA256 signature.
204
+ */
205
+ verifySignature(
206
+ rawBody: string,
207
+ signature: string,
208
+ provider: WebhookProvider
209
+ ): WebhookVerificationResult {
210
+ this.stats.received++;
211
+
212
+ const secret = this.config.secrets[provider];
213
+ if (!secret) {
214
+ this.stats.rejected++;
215
+ return {
216
+ verified: false,
217
+ provider,
218
+ error: `No secret configured for provider: ${provider}`,
219
+ };
220
+ }
221
+
222
+ const expected = computeHmac(rawBody, secret);
223
+ const isValid = timingSafeEqual(expected, signature);
224
+
225
+ if (!isValid) {
226
+ this.stats.rejected++;
227
+ this.emitTelemetry('webhook_signature_invalid', { provider });
228
+ return {
229
+ verified: false,
230
+ provider,
231
+ error: 'Invalid HMAC-SHA256 signature',
232
+ };
233
+ }
234
+
235
+ // Parse payload
236
+ let payload: WebhookPayload;
237
+ try {
238
+ payload = JSON.parse(rawBody) as WebhookPayload;
239
+ } catch {
240
+ this.stats.rejected++;
241
+ return {
242
+ verified: false,
243
+ provider,
244
+ error: 'Invalid JSON payload',
245
+ };
246
+ }
247
+
248
+ // Check age
249
+ const eventAge = Date.now() - new Date(payload.timestamp).getTime();
250
+ if (eventAge > this.config.maxAgeMs) {
251
+ this.stats.rejected++;
252
+ return {
253
+ verified: false,
254
+ provider,
255
+ error: `Webhook too old: ${Math.round(eventAge / 1000)}s (max: ${Math.round(this.config.maxAgeMs / 1000)}s)`,
256
+ };
257
+ }
258
+
259
+ this.stats.verified++;
260
+ this.emitTelemetry('webhook_verified', { provider, eventId: payload.eventId });
261
+
262
+ return {
263
+ verified: true,
264
+ provider,
265
+ payload,
266
+ };
267
+ }
268
+
269
+ // ===========================================================================
270
+ // PROCESSING
271
+ // ===========================================================================
272
+
273
+ /**
274
+ * Process a verified webhook payload.
275
+ */
276
+ async processWebhook(payload: WebhookPayload): Promise<WebhookProcessingResult> {
277
+ // Idempotency check
278
+ if (this.processedEvents.has(payload.eventId)) {
279
+ this.stats.duplicates++;
280
+ return {
281
+ success: true,
282
+ eventId: payload.eventId,
283
+ type: payload.type,
284
+ };
285
+ }
286
+
287
+ // Update ledger entry if applicable
288
+ let updatedEntry: LedgerEntry | undefined;
289
+ if (payload.ledgerEntryId && this.ledgerUpdateCallback) {
290
+ try {
291
+ if (payload.type === 'payment.confirmed' || payload.type === 'settlement.completed') {
292
+ this.ledgerUpdateCallback(payload.ledgerEntryId, {
293
+ settled: true,
294
+ settlementTx: payload.transactionHash || null,
295
+ });
296
+ } else if (payload.type === 'payment.failed' || payload.type === 'settlement.failed') {
297
+ this.ledgerUpdateCallback(payload.ledgerEntryId, {
298
+ settled: false,
299
+ settlementTx: null,
300
+ });
301
+ }
302
+ } catch (err) {
303
+ // Log but don't fail — handlers may still want this event
304
+ this.emitTelemetry('webhook_ledger_update_error', {
305
+ eventId: payload.eventId,
306
+ error: err instanceof Error ? err.message : String(err),
307
+ });
308
+ }
309
+ }
310
+
311
+ // Invoke registered handlers
312
+ const handlers = this.handlers.get(payload.type) || [];
313
+ const errors: string[] = [];
314
+
315
+ for (const handler of handlers) {
316
+ try {
317
+ const result = await handler(payload);
318
+ if (!result.success && result.error) {
319
+ errors.push(result.error);
320
+ }
321
+ if (result.updatedEntry) {
322
+ updatedEntry = result.updatedEntry;
323
+ }
324
+ } catch (err) {
325
+ errors.push(err instanceof Error ? err.message : String(err));
326
+ }
327
+ }
328
+
329
+ if (errors.length > 0) {
330
+ this.stats.failed++;
331
+ this.emitTelemetry('webhook_processing_failed', {
332
+ eventId: payload.eventId,
333
+ type: payload.type,
334
+ errors,
335
+ });
336
+
337
+ // Add to retry queue
338
+ this.addToRetryQueue(payload, errors.join('; '));
339
+
340
+ return {
341
+ success: false,
342
+ eventId: payload.eventId,
343
+ type: payload.type,
344
+ error: errors.join('; '),
345
+ };
346
+ }
347
+
348
+ // Mark as processed (idempotency)
349
+ this.processedEvents.add(payload.eventId);
350
+
351
+ // Trim processed events set if too large
352
+ if (this.processedEvents.size > 10000) {
353
+ const entries = [...this.processedEvents];
354
+ this.processedEvents = new Set(entries.slice(-5000));
355
+ }
356
+
357
+ this.stats.processed++;
358
+ this.emitTelemetry('webhook_processed', {
359
+ eventId: payload.eventId,
360
+ type: payload.type,
361
+ provider: payload.provider,
362
+ });
363
+
364
+ return {
365
+ success: true,
366
+ eventId: payload.eventId,
367
+ type: payload.type,
368
+ updatedEntry,
369
+ };
370
+ }
371
+
372
+ // ===========================================================================
373
+ // HANDLER REGISTRATION
374
+ // ===========================================================================
375
+
376
+ /**
377
+ * Register a handler for a specific webhook event type.
378
+ */
379
+ on(eventType: WebhookEventType, handler: WebhookHandler): void {
380
+ const existing = this.handlers.get(eventType) || [];
381
+ existing.push(handler);
382
+ this.handlers.set(eventType, existing);
383
+ }
384
+
385
+ /**
386
+ * Remove a handler for a specific webhook event type.
387
+ */
388
+ off(eventType: WebhookEventType, handler: WebhookHandler): void {
389
+ const existing = this.handlers.get(eventType) || [];
390
+ this.handlers.set(
391
+ eventType,
392
+ existing.filter((h) => h !== handler)
393
+ );
394
+ }
395
+
396
+ /**
397
+ * Set callback for ledger entry updates.
398
+ */
399
+ onLedgerUpdate(callback: (entryId: string, updates: Partial<LedgerEntry>) => void): void {
400
+ this.ledgerUpdateCallback = callback;
401
+ }
402
+
403
+ // ===========================================================================
404
+ // RETRY QUEUE
405
+ // ===========================================================================
406
+
407
+ /**
408
+ * Add a failed webhook to the retry queue.
409
+ */
410
+ private addToRetryQueue(payload: WebhookPayload, error: string): void {
411
+ const existing = this.retryQueue.find((r) => r.payload.eventId === payload.eventId);
412
+ if (existing) {
413
+ existing.attempts++;
414
+ existing.lastError = error;
415
+ existing.nextRetryAt =
416
+ Date.now() + this.config.retryBackoffMs * Math.pow(2, existing.attempts - 1);
417
+ return;
418
+ }
419
+
420
+ if (this.retryQueue.length >= 1000) {
421
+ // Evict oldest
422
+ this.retryQueue.shift();
423
+ }
424
+
425
+ this.retryQueue.push({
426
+ payload,
427
+ attempts: 1,
428
+ nextRetryAt: Date.now() + this.config.retryBackoffMs,
429
+ lastError: error,
430
+ });
431
+ }
432
+
433
+ /**
434
+ * Process retry queue entries that are ready.
435
+ */
436
+ async processRetryQueue(): Promise<number> {
437
+ const now = Date.now();
438
+ const ready = this.retryQueue.filter(
439
+ (r) => r.nextRetryAt <= now && r.attempts < this.config.maxRetries
440
+ );
441
+
442
+ let processed = 0;
443
+ for (const entry of ready) {
444
+ const result = await this.processWebhook(entry.payload);
445
+ if (result.success) {
446
+ // Remove from queue
447
+ const idx = this.retryQueue.indexOf(entry);
448
+ if (idx >= 0) this.retryQueue.splice(idx, 1);
449
+ this.stats.retried++;
450
+ processed++;
451
+ }
452
+ }
453
+
454
+ // Remove entries that exceeded max retries
455
+ this.retryQueue = this.retryQueue.filter((r) => r.attempts < this.config.maxRetries);
456
+
457
+ return processed;
458
+ }
459
+
460
+ /**
461
+ * Get retry queue length.
462
+ */
463
+ getRetryQueueLength(): number {
464
+ return this.retryQueue.length;
465
+ }
466
+
467
+ // ===========================================================================
468
+ // QUERIES
469
+ // ===========================================================================
470
+
471
+ /**
472
+ * Check if an event has been processed.
473
+ */
474
+ isProcessed(eventId: string): boolean {
475
+ return this.processedEvents.has(eventId);
476
+ }
477
+
478
+ /**
479
+ * Get comprehensive stats.
480
+ */
481
+ getStats(): typeof this.stats & { retryQueueLength: number } {
482
+ return {
483
+ ...this.stats,
484
+ retryQueueLength: this.retryQueue.length,
485
+ };
486
+ }
487
+
488
+ /**
489
+ * Create a webhook signature for testing purposes.
490
+ */
491
+ createSignature(rawBody: string, provider: WebhookProvider): string {
492
+ const secret = this.config.secrets[provider];
493
+ if (!secret) throw new Error(`No secret for provider: ${provider}`);
494
+ return computeHmac(rawBody, secret);
495
+ }
496
+
497
+ // ===========================================================================
498
+ // TELEMETRY
499
+ // ===========================================================================
500
+
501
+ private emitTelemetry(type: string, data?: Record<string, unknown>): void {
502
+ this.config.telemetry?.record({
503
+ type,
504
+ severity:
505
+ type.includes('error') || type.includes('failed') || type.includes('invalid')
506
+ ? 'error'
507
+ : 'info',
508
+ agentId: 'payment-webhook-service',
509
+ data,
510
+ });
511
+ }
512
+ }