@fangorn-network/westmarch 0.0.19-dev → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. package/README.md +35 -5
  2. package/docs/app-to-agent.md +113 -620
  3. package/package.json +18 -18
  4. package/site/dist/assets/__vite-browser-external-D2U8RZpp.js +1 -0
  5. package/site/dist/assets/embed.worker-CmS57Zti.js +1 -0
  6. package/site/dist/assets/index-CkP1WhkV.js +8 -0
  7. package/site/dist/assets/roles-BDPDWrwo.js +1 -0
  8. package/site/dist/assets/rolldown-runtime-COiEfhsA.js +1 -0
  9. package/site/dist/assets/transformers.web-CUZUFjAK.js +49 -0
  10. package/site/dist/assets/transformers.web-CwR_IYQV.js +40 -0
  11. package/site/dist/index.html +6 -7
  12. package/site/feed.js +16 -1
  13. package/site/no-model.js +4 -0
  14. package/site/worker.js +382 -59
  15. package/src/agent/agent-card.js +51 -37
  16. package/src/agent/mcp.js +173 -500
  17. package/src/agent/tools.js +3 -2
  18. package/src/agent/ui.js +1 -1
  19. package/src/agent/view-tools.js +11 -30
  20. package/src/agent/x402.js +194 -85
  21. package/src/core/embed.js +56 -53
  22. package/src/core/embed.worker.js +1 -1
  23. package/src/core/rank.js +1 -1
  24. package/src/core/roles.js +7 -7
  25. package/src/core/shard.js +12 -8
  26. package/src/discover/apps.js +103 -67
  27. package/src/discover/corpora.js +1 -1
  28. package/src/discover/directory.js +3 -3
  29. package/src/market/cohort.js +1 -1
  30. package/src/market/demand.js +1 -1
  31. package/src/market/reactions.js +24 -18
  32. package/src/publish/devnet.js +146 -0
  33. package/src/publish/graph.js +1 -1
  34. package/src/publish/init.js +74 -0
  35. package/src/publish/lint.js +3 -2
  36. package/src/publish/ship.js +433 -287
  37. package/src/publish/view-cli.js +14 -10
  38. package/src/publish/view.js +485 -255
  39. package/src/taste/steam.js +1 -1
  40. package/src/taste/taste-doc.js +4 -3
  41. package/src/taste/taste.js +3 -3
  42. package/src/taste/vault.js +4 -2
  43. package/template/README.md +48 -0
  44. package/template/app.json +27 -0
  45. package/template/eval/goals.md +7 -0
  46. package/template/eval/golden.jsonl +0 -0
  47. package/template/gitignore +3 -0
  48. package/template/package.json +13 -0
  49. package/template/wrangler.json +12 -0
  50. package/plugin/scripts/fx.mjs +0 -268
  51. package/site/dist/assets/AccountNotFoundScreen-C4njXc69-BOfmiSH1.js +0 -1
  52. package/site/dist/assets/AddFundsSelectionScreen-RAoCn7ej-B6uvYyqa.js +0 -31
  53. package/site/dist/assets/Address-H8kD1d9O-DcHv7A8C.js +0 -17
  54. package/site/dist/assets/AffirmativeConsentScreen-BG0MJxku-v2wz-N-s.js +0 -6
  55. package/site/dist/assets/AllowlistRejectionScreen-Cae6e1Od-DhVy9iGN.js +0 -1
  56. package/site/dist/assets/ApiController-BbhXeqTV.js +0 -5
  57. package/site/dist/assets/ArrowsRightLeftIcon-cp60yobq.js +0 -1
  58. package/site/dist/assets/AuthenticateWithWalletScreen-CU6hIcFT-B0eT1zE6.js +0 -1
  59. package/site/dist/assets/AwaitingEvmToSolBridgingScreen-D0e_sZMS-DL5PH-v_.js +0 -1
  60. package/site/dist/assets/AwaitingExternalEthereumTransferScreen-ur5HL4R7-n1BsRPqc.js +0 -1
  61. package/site/dist/assets/AwaitingPasswordlessCodeScreen-DRHz76mM-BVl2BJDY.js +0 -103
  62. package/site/dist/assets/AwaitingSolToEvmBridgingScreen-CdLRrGD2-BD-OZUQb.js +0 -1
  63. package/site/dist/assets/BridgeNetworkSelectionView-CFGjB2nO-CaYrzRje.js +0 -68
  64. package/site/dist/assets/CaptchaScreen-DbpvkIGx-BQJ7inx1.js +0 -1
  65. package/site/dist/assets/CheckCircleIcon-BM409mGI.js +0 -1
  66. package/site/dist/assets/CheckCircleIcon-NCOQc0Gs.js +0 -1
  67. package/site/dist/assets/Checkbox-D1EDeo41-rHlvsZzP.js +0 -52
  68. package/site/dist/assets/ChevronDownIcon-CW-4MSpE.js +0 -1
  69. package/site/dist/assets/Chip-CZKIKt9K-CutJG010.js +0 -26
  70. package/site/dist/assets/CoinbaseOnrampStatusScreen-BbyCJDXL-DDaMC7cl.js +0 -16
  71. package/site/dist/assets/ConnectEmailForm-B-VRE0MN-DVSf4tFJ.js +0 -3
  72. package/site/dist/assets/ConnectLedgerScreen-DWHABGot-h0uYIUi6.js +0 -10
  73. package/site/dist/assets/ConnectOnlyLandingScreen-CZYx9Bmp-DP19hJq5.js +0 -1
  74. package/site/dist/assets/ConnectOnlyStatusScreen-DCRzjxHx-DHvijlTx.js +0 -1
  75. package/site/dist/assets/ConnectOrCreateScreen-CUUYUO07-ewmXYPTQ.js +0 -1
  76. package/site/dist/assets/ConnectPhoneForm-Dek5xn4C-DUYdmVtr.js +0 -95
  77. package/site/dist/assets/ConnectWalletView-DqI-PTvX-RobGErVW.js +0 -74
  78. package/site/dist/assets/ConnectionStatusScreen-fUfROm9m-Bbiq3hY6.js +0 -1
  79. package/site/dist/assets/ConnectionStatusScreen-fUfROm9m-DPkOGNWl.js +0 -7
  80. package/site/dist/assets/ConnectorUtil-BO1L6VvV.js +0 -21
  81. package/site/dist/assets/ConstantsUtil-DmLsRHAl.js +0 -198
  82. package/site/dist/assets/CopyToClipboard-i_OQSBJr-DujUHNzW.js +0 -39
  83. package/site/dist/assets/CopyableText-CQapvaMr-DMIdpDaU.js +0 -28
  84. package/site/dist/assets/CrossAppAuthScreen-CLw7ymZq-DbGy4QyA.js +0 -1
  85. package/site/dist/assets/CustomLandingScreenView-Cm_MBSyX-B3WqJZBh.js +0 -22
  86. package/site/dist/assets/DelegatedActionsConsentScreen-DYF2U4y5-CmUDoS0C.js +0 -1
  87. package/site/dist/assets/DelegatedActionsRevokeScreen-bPp6Uwyh-fcO51q5H.js +0 -1
  88. package/site/dist/assets/DepositAddressAddressStepView-4vdkb55L-ClAb_j1B.js +0 -187
  89. package/site/dist/assets/DepositAddressScreen-DBLRs7aI-CN1P_KY9.js +0 -8
  90. package/site/dist/assets/DepositAddressV3Screen-CDqIEMQw-BtDZmuEN.js +0 -1
  91. package/site/dist/assets/EmailInputForm-Cqo1mda8-B2NG3K5V.js +0 -124
  92. package/site/dist/assets/EmbeddedWalletConnectingScreen-D4T7DUzs-D3pExuaW.js +0 -1
  93. package/site/dist/assets/EmbeddedWalletCreatedScreen-D7WhW5ve-CLsJbPYQ.js +0 -1
  94. package/site/dist/assets/EmbeddedWalletKeyExportScreen-CqV4NYQ3-DI6bu-oi.js +0 -23
  95. package/site/dist/assets/EmbeddedWalletOnAccountCreateScreen-BoKb3Q2S-BQ9Ygr0P.js +0 -1
  96. package/site/dist/assets/EmbeddedWalletPasswordUpdateScreen-D3rMlqS7-CxrfLr5q.js +0 -1
  97. package/site/dist/assets/EmbeddedWalletPasswordUpdateSplashScreen-BPFkWJeE-DHZRGoTN.js +0 -1
  98. package/site/dist/assets/EnrollTotp-Dibew4dp-7gVtJ1Jt.js +0 -66
  99. package/site/dist/assets/EnvelopeIcon-Dh2vSVj4.js +0 -1
  100. package/site/dist/assets/ErrorBanner-BcpGRt0h-BKOYTyCi.js +0 -21
  101. package/site/dist/assets/ErrorMessage-D8VaAP5m-CrZOnUyg.js +0 -8
  102. package/site/dist/assets/ErrorScreen-DipdTWzE-BT8TtRTx.js +0 -4
  103. package/site/dist/assets/ErrorScreen-DipdTWzE-DAam41Xl.js +0 -1
  104. package/site/dist/assets/ExclamationCircleIcon-DUA2wMfO.js +0 -1
  105. package/site/dist/assets/ExclamationTriangleIcon-eZfaqcFq.js +0 -1
  106. package/site/dist/assets/FarcasterConnectStatusScreen-51tjUxqq-BPCBi37Q.js +0 -75
  107. package/site/dist/assets/FarcasterSignerStatusScreen-6x-Uh95G-XCmWpnUd.js +0 -28
  108. package/site/dist/assets/FiatOnrampScreen-BAhYeiTI-DJRcUh2N.js +0 -491
  109. package/site/dist/assets/FingerPrintIcon-Dm6kxmg7.js +0 -1
  110. package/site/dist/assets/FundSolWalletWithExternalSolanaWallet-WtLwYaOl-BfNVSTb1.js +0 -1
  111. package/site/dist/assets/FundWalletMethodHeader-BWNkokCT-BQdbJ5Bb.js +0 -1
  112. package/site/dist/assets/FundWithBankDepositScreen-DajkHxBD-BfvMcHb6.js +0 -58
  113. package/site/dist/assets/FundingEditAmountScreen-CpvpiO4M-VBfbahnA.js +0 -1
  114. package/site/dist/assets/FundingMethodSelectionScreen-Db7vhRlE-CMuBYf64.js +0 -1
  115. package/site/dist/assets/GlobeAltIcon-vqrVV5ho.js +0 -1
  116. package/site/dist/assets/GooglePay-B53WnudL-BX5_WtCx.js +0 -1
  117. package/site/dist/assets/HCaptchaWrapper-CUi9LJsp-D-I8j7NO.js +0 -4
  118. package/site/dist/assets/InAppBrowserLoginNotPossible-BMR9br1T-BY3j50El.js +0 -1
  119. package/site/dist/assets/InfoBanner-Cb3p1z12-DLBl_Ywy.js +0 -22
  120. package/site/dist/assets/InjectedWalletIcon-DLcYOGDj-DLSV_NjP.js +0 -1
  121. package/site/dist/assets/InstallWalletScreen-DTA8dwLv-CxreyXoD.js +0 -1
  122. package/site/dist/assets/JsonTree-BHzNC-ic-DcNcbSoM.js +0 -34
  123. package/site/dist/assets/LabelXs-oqZNqbm_-iafrj25N.js +0 -6
  124. package/site/dist/assets/LandingScreen-CGWUoSUG-Q7hgXKvM.js +0 -1
  125. package/site/dist/assets/Layouts-BMRfo5hw-CeCOyCLK.js +0 -77
  126. package/site/dist/assets/Link-BdDilT2T-BEDEdHuS.js +0 -40
  127. package/site/dist/assets/LinkConflictScreen-C3ZEPsgl-DK1z_v7y.js +0 -77
  128. package/site/dist/assets/LinkEmailScreen-dKo9frwc-BYYpJ5-6.js +0 -1
  129. package/site/dist/assets/LinkPasskeyScreen-zbrl_AI_-uhub9C26.js +0 -1
  130. package/site/dist/assets/LinkPasskeyScreen-zbrl_AI_-uid22VTN.js +0 -117
  131. package/site/dist/assets/LinkPhoneScreen-oIUpfj0w-CVQibNi9.js +0 -1
  132. package/site/dist/assets/Loader-UAZqxsnw-Cy7hEE2f.js +0 -62
  133. package/site/dist/assets/LoadingSkeleton-BMsgO5PV-CiEyS5PZ.js +0 -17
  134. package/site/dist/assets/LockClosedIcon-BgY_5v_Z.js +0 -1
  135. package/site/dist/assets/LoginFailedScreen-CN0dJV6U-DhUMiJZJ.js +0 -1
  136. package/site/dist/assets/ManualTransferScreen-CHqcuqbs-DMygAXMU.js +0 -1
  137. package/site/dist/assets/MfaAuthEnrollmentFlowScreen-Dj7gPTRC-_1GFUSIg.js +0 -1
  138. package/site/dist/assets/MfaAuthVerifyFlowScreen-DbFpyWMy-DLnBJ5b8.js +0 -1
  139. package/site/dist/assets/MfaEnrollmentFlowScreen-DhLnGgnr-BUJY1lzs.js +0 -1
  140. package/site/dist/assets/MfaVerifyFlowScreen-C_XPjMRP-25l5fVun.js +0 -1
  141. package/site/dist/assets/ModalFooter-BCuEK_nz-c-khvG4Y.js +0 -403
  142. package/site/dist/assets/MoonpayStatusScreen-CzTUtokc-BRFN2eXr.js +0 -16
  143. package/site/dist/assets/OAuthStatusScreen-ufbOa-da-DL30vu07.js +0 -1
  144. package/site/dist/assets/OpenLink-CUpJ1mOr-DfAvJRyK.js +0 -39
  145. package/site/dist/assets/PasskeySelectSignupOrLogin-xh2ScC_l-DtxhRQyw.js +0 -1
  146. package/site/dist/assets/PasskeyStatusScreen-Bla8MaOk-CNfu8ujT.js +0 -6
  147. package/site/dist/assets/PasswordRecoveryScreen-awGXZkQk-BR6z6xE8.js +0 -20
  148. package/site/dist/assets/PhArrowCircleDown-D97G-BOA.js +0 -14
  149. package/site/dist/assets/PhArrowClockwise-DVgyFuez.js +0 -14
  150. package/site/dist/assets/PhArrowDown-87b1BizM.js +0 -14
  151. package/site/dist/assets/PhArrowLeft-Da0MfnbK.js +0 -14
  152. package/site/dist/assets/PhArrowRight-AdrIL4DW.js +0 -14
  153. package/site/dist/assets/PhArrowSquareOut-Bk2CMG3I.js +0 -14
  154. package/site/dist/assets/PhArrowUp-4sgyKPGx.js +0 -14
  155. package/site/dist/assets/PhArrowUpRight-BNghD2zq.js +0 -14
  156. package/site/dist/assets/PhArrowsClockwise-BXRn1GEl.js +0 -14
  157. package/site/dist/assets/PhArrowsDownUp-DM09Jo_3.js +0 -14
  158. package/site/dist/assets/PhArrowsLeftRight-MuKBLUoF.js +0 -14
  159. package/site/dist/assets/PhBank-fHbgCqqZ.js +0 -14
  160. package/site/dist/assets/PhBrowser-2-9m-AkM.js +0 -14
  161. package/site/dist/assets/PhCaretDown-BDNabFuL.js +0 -14
  162. package/site/dist/assets/PhCaretLeft-CI460R-A.js +0 -14
  163. package/site/dist/assets/PhCaretRight-D7ZS3Ls8.js +0 -14
  164. package/site/dist/assets/PhCaretUp-C-iIfyvO.js +0 -14
  165. package/site/dist/assets/PhCheck-DxQXn57r.js +0 -14
  166. package/site/dist/assets/PhCircleHalf-MJZeRBGF.js +0 -14
  167. package/site/dist/assets/PhClock-x3MS3Mwi.js +0 -14
  168. package/site/dist/assets/PhCompass-hYn3HhGN.js +0 -14
  169. package/site/dist/assets/PhCopy-CWNYcABI.js +0 -14
  170. package/site/dist/assets/PhCreditCard-Fy4pzwtt.js +0 -14
  171. package/site/dist/assets/PhCurrencyDollar-BgiaenCi.js +0 -14
  172. package/site/dist/assets/PhDesktop-CxrzCSv5.js +0 -14
  173. package/site/dist/assets/PhDeviceMobile-CsyA5Goi.js +0 -14
  174. package/site/dist/assets/PhDotsThree-D-k1BiYg.js +0 -14
  175. package/site/dist/assets/PhEnvelope-D8kzeNox.js +0 -14
  176. package/site/dist/assets/PhFunnelSimple-CfQs5DAW.js +0 -14
  177. package/site/dist/assets/PhGlobe-DvmSc9_A.js +0 -14
  178. package/site/dist/assets/PhIdentificationCard-CfkZm-5K.js +0 -14
  179. package/site/dist/assets/PhImage-Cf0J2ZfJ.js +0 -14
  180. package/site/dist/assets/PhInfo-Bwi51-2X.js +0 -14
  181. package/site/dist/assets/PhLightbulb-C4FZV7Es.js +0 -14
  182. package/site/dist/assets/PhMagnifyingGlass-C9u8jSCJ.js +0 -14
  183. package/site/dist/assets/PhPaperPlaneRight-zxQVvPLX.js +0 -14
  184. package/site/dist/assets/PhPlus-C4UoW-2n.js +0 -14
  185. package/site/dist/assets/PhPower-CFyWDmgD.js +0 -14
  186. package/site/dist/assets/PhPuzzlePiece-BjoNVfST.js +0 -14
  187. package/site/dist/assets/PhQrCode-CP3tFauY.js +0 -14
  188. package/site/dist/assets/PhQuestion-wOWJBd3G.js +0 -14
  189. package/site/dist/assets/PhQuestionMark-CV0k9C0Y.js +0 -14
  190. package/site/dist/assets/PhSealCheck-vIKzREuN.js +0 -14
  191. package/site/dist/assets/PhSignOut-CxELV-i0.js +0 -14
  192. package/site/dist/assets/PhSpinner-CGDmbzUd.js +0 -14
  193. package/site/dist/assets/PhTrash-C9PD0SAt.js +0 -14
  194. package/site/dist/assets/PhUser-0sWNXQeZ.js +0 -14
  195. package/site/dist/assets/PhVault-6JTskUcC.js +0 -14
  196. package/site/dist/assets/PhWarning-CoKs3gz6.js +0 -14
  197. package/site/dist/assets/PhWarningCircle-BXHw1fCt.js +0 -14
  198. package/site/dist/assets/PhX-DX0SFIqC.js +0 -14
  199. package/site/dist/assets/PhoneIcon-CvIiPwYQ.js +0 -1
  200. package/site/dist/assets/PinInput-DbZ0b1i1-CDXZBdQx.js +0 -247
  201. package/site/dist/assets/PrivyPluginContext-DA-yS5vO-CtQWBiV2.js +0 -1
  202. package/site/dist/assets/QrCode-DbnZwlkH-BymHrKY7.js +0 -22
  203. package/site/dist/assets/RecoveryOAuthStatusScreen-CsgtTI2x-Dro1btv5.js +0 -1
  204. package/site/dist/assets/RecoveryPasswordCreateScreen-Be-qJ-LU-C1q1hiaN.js +0 -1
  205. package/site/dist/assets/RecoverySelectionScreen-D1iGtpmi-C21D20gD.js +0 -7
  206. package/site/dist/assets/SIWXUtil-CHZVugix.js +0 -1
  207. package/site/dist/assets/Screen-D30meWsY-CCeVNuWs.js +0 -175
  208. package/site/dist/assets/ScreenHeader-CHmc4-Lu-DjyrH7IK.js +0 -31
  209. package/site/dist/assets/ScreenLayout-OwaQQcxH-CrQM6kvA.js +0 -1
  210. package/site/dist/assets/SelectSourceAsset-CWFog6gm-RKjBsB6m.js +0 -140
  211. package/site/dist/assets/SetAutomaticRecoveryScreen-BO_OEqAZ-BcWHJoEG.js +0 -14
  212. package/site/dist/assets/SetWalletPasswordForm-DwCTVtAh-kq1zvA7d.js +0 -11
  213. package/site/dist/assets/ShieldCheckIcon-o6RHYev1.js +0 -1
  214. package/site/dist/assets/SignRequestScreen-BHKv32KR-iQCaBkcz.js +0 -26
  215. package/site/dist/assets/SolanaWalletConnector-C7Lqk-Wz-BUdJJ0ep.js +0 -1
  216. package/site/dist/assets/StackedContainer-B2vaEl56-eQCM2cmv.js +0 -24
  217. package/site/dist/assets/StandardSignAndSendTransactionScreen-CfhIXVtd-nART-xUU.js +0 -20
  218. package/site/dist/assets/Subtitle-CV-2yKE4-zxWw2m1Q.js +0 -13
  219. package/site/dist/assets/TelegramAuthScreen-UL9zLfO8-Dw9geyK3.js +0 -1
  220. package/site/dist/assets/Title-BnzYV3Is-B_JpTatT.js +0 -7
  221. package/site/dist/assets/TodoList-DnyULl18-C8Eyy28X.js +0 -36
  222. package/site/dist/assets/TransactionDetails-e9nesl30-DeEL1JQS.js +0 -109
  223. package/site/dist/assets/TransactionErrorView-BDBNqA_f-Dffuo7I4.js +0 -178
  224. package/site/dist/assets/TransferFromWalletScreen-Qvn1Yuno-CWLWUiHy.js +0 -31
  225. package/site/dist/assets/TransferOrBridgeLoadingScreen-Dl1I_iIz-Bo-tm6wr.js +0 -6
  226. package/site/dist/assets/TurnstileWrapper-B7sNddys-Jwy1tJtm.js +0 -1
  227. package/site/dist/assets/UpdateEmailScreen-DVOhPV0H-gFbSIUhh.js +0 -1
  228. package/site/dist/assets/UpdatePhoneScreen-CXRswTNZ-Coy4E1NQ.js +0 -1
  229. package/site/dist/assets/UserLimitReachedScreen-5we2DHn8-D7m70C4b.js +0 -1
  230. package/site/dist/assets/Value-DTgR824E-BRuIGiec.js +0 -27
  231. package/site/dist/assets/WalletCards-DH1rqayz-Bgp9Fsgs.js +0 -1
  232. package/site/dist/assets/WalletIcon-gKf0gTw6.js +0 -1
  233. package/site/dist/assets/WalletInfoCard-sq_2wgFg-ISBsQt8p.js +0 -29
  234. package/site/dist/assets/WalletInterstitialScreen-Sh7LfsAh-DG-RuO-F.js +0 -1
  235. package/site/dist/assets/WalletLink-DK5LB5Ha-CXBqCHf3.js +0 -20
  236. package/site/dist/assets/WalletOverflowButton-bfCnp-9T-DP0-PoZL.js +0 -1
  237. package/site/dist/assets/WarningBanner-ZZqCEtZK-2eU4Qo74.js +0 -21
  238. package/site/dist/assets/__vite-browser-external-CitKSmYk.js +0 -1
  239. package/site/dist/assets/_esm-CJe2F7LL.js +0 -7
  240. package/site/dist/assets/_esm-zhBBffjV.js +0 -1
  241. package/site/dist/assets/accounts-Bq8t1wAD.js +0 -1
  242. package/site/dist/assets/accounts-D96UKWkC.js +0 -1
  243. package/site/dist/assets/analytics-mkkvFRju-BRBcadka.js +0 -1
  244. package/site/dist/assets/baseSepolia-DX-qGsik.js +0 -1
  245. package/site/dist/assets/basic-MlZ7f4s9.js +0 -1575
  246. package/site/dist/assets/capitalizeFirstLetter-DmLYqXsO-DtOXx-2n.js +0 -1
  247. package/site/dist/assets/ccip-BI9LWBBg.js +0 -1
  248. package/site/dist/assets/ccip-C-59SNEF.js +0 -7
  249. package/site/dist/assets/ccip-y08wK9du.js +0 -1
  250. package/site/dist/assets/chain-DM3oH6Px.js +0 -8
  251. package/site/dist/assets/check-BPgcwEPP.js +0 -1
  252. package/site/dist/assets/chevron-down-BSsbXkK-.js +0 -1
  253. package/site/dist/assets/circle-alert-DWaeLZNj.js +0 -1
  254. package/site/dist/assets/circle-check-big-Chb1ivw9.js +0 -1
  255. package/site/dist/assets/circle-x-AV9Cet0R.js +0 -1
  256. package/site/dist/assets/client-D0IV9lV9.js +0 -2
  257. package/site/dist/assets/client-Dsa7_3V3.js +0 -9
  258. package/site/dist/assets/coinbase-DCPC2L_R-Rs9nVCfm.js +0 -3
  259. package/site/dist/assets/copy-Ckr0AkL6.js +0 -1
  260. package/site/dist/assets/core-zQ1tZtVZ.js +0 -12
  261. package/site/dist/assets/createLucideIcon-IPW50ckY.js +0 -1
  262. package/site/dist/assets/defineChain-CiuCXUZW.js +0 -1
  263. package/site/dist/assets/dijkstra-Drfl93V4.js +0 -1
  264. package/site/dist/assets/dist-BxQqwnue.js +0 -16
  265. package/site/dist/assets/dist-Cm7pNAtL.js +0 -1
  266. package/site/dist/assets/dist-CoS6E-3x.js +0 -1
  267. package/site/dist/assets/dist-Dl07uGq1.js +0 -1
  268. package/site/dist/assets/embed.worker-ugGhEqCV.js +0 -1
  269. package/site/dist/assets/errors-BQ3N-RVt-BLqjTPNR.js +0 -1
  270. package/site/dist/assets/esm-C3DslVJx.js +0 -1
  271. package/site/dist/assets/esm-Ci1ogKuK.js +0 -1
  272. package/site/dist/assets/esm-DXsETz3H.js +0 -1
  273. package/site/dist/assets/esm-n2lWo7kz.js +0 -1
  274. package/site/dist/assets/esm-vs5jNx_Y.js +0 -37
  275. package/site/dist/assets/ethers-zTjbodk5-B7BBFFKf.js +0 -1
  276. package/site/dist/assets/eventemitter3-CL76jPsW.js +0 -1
  277. package/site/dist/assets/external-link-D-uehwM2.js +0 -1
  278. package/site/dist/assets/farcaster-DPlSjvF5-BqTvDXBR.js +0 -1
  279. package/site/dist/assets/features-CYXRa3_m.js +0 -2
  280. package/site/dist/assets/fingerprint-pattern-D8ytA16Q.js +0 -1
  281. package/site/dist/assets/floating-ui.react-dom-DKWOL9UG.js +0 -1
  282. package/site/dist/assets/floating-ui.react-xRkl9O3u.js +0 -1
  283. package/site/dist/assets/formatErc20TokenAmount-BuPk9xcy-BVqOKQif.js +0 -1
  284. package/site/dist/assets/formatter-CVbp4SlJ.js +0 -1
  285. package/site/dist/assets/get-entropy-details-for-user-dHRH5Gpi-Dukf7_kJ.js +0 -1
  286. package/site/dist/assets/getChainName-DjpPdUSc-DUyKDrnp.js +0 -1
  287. package/site/dist/assets/getErc20Balance-jXNpFf0N-V2btxzrJ.js +0 -1
  288. package/site/dist/assets/getErc20TokenInfo-BNTrzLMP-CtCwQuGA.js +0 -1
  289. package/site/dist/assets/getFormattedUsdFromLamports-De3U9GlO-Gx4_wxON.js +0 -1
  290. package/site/dist/assets/getUsdcMintAddress-BVgm9GRo-r2UnDeEy.js +0 -1
  291. package/site/dist/assets/guards-BIW-GiMJ-CHfXo8XI.js +0 -1
  292. package/site/dist/assets/hooks.module-BYZGfwDl.js +0 -1
  293. package/site/dist/assets/hourglass-CPG1HZmf.js +0 -1
  294. package/site/dist/assets/id-UqEwL2BI-CdKXapd-.js +0 -1
  295. package/site/dist/assets/index-BdEw5wyl-ChSJvPZk.js +0 -1
  296. package/site/dist/assets/index-CKdAF_dK.js +0 -8
  297. package/site/dist/assets/index-CWARkn2w-Cezl_uBr.js +0 -61
  298. package/site/dist/assets/index-DvMddJcd-D-4mRLKK.js +0 -12
  299. package/site/dist/assets/index-YiCw0Y_x-BX1zsiqG.js +0 -437
  300. package/site/dist/assets/index.browser-B-i-Lj3J.js +0 -1
  301. package/site/dist/assets/index.browser-BMmUcykv.js +0 -1
  302. package/site/dist/assets/index.es-BmqyoBEM.js +0 -2
  303. package/site/dist/assets/index.es-C1v1or--.js +0 -3
  304. package/site/dist/assets/isPaymentRequestAvailable-Bq1cemEn-By6r0dVB.js +0 -1
  305. package/site/dist/assets/jsx-runtime-BbDfbRii.js +0 -1
  306. package/site/dist/assets/landmark-CH6LV6F0.js +0 -1
  307. package/site/dist/assets/lib-BsS8z8Lj.js +0 -1
  308. package/site/dist/assets/localBatchGatewayRequest-5YxrERBj.js +0 -32
  309. package/site/dist/assets/lock-DcskI4Bb.js +0 -1
  310. package/site/dist/assets/logger-CsXm3oIv-B0UYpNFI.js +0 -1
  311. package/site/dist/assets/mail-Bs0r5yOi.js +0 -1
  312. package/site/dist/assets/modal-context-CwmSeFcv-DruX9J1E.js +0 -1
  313. package/site/dist/assets/native-BKj27wfc.js +0 -1
  314. package/site/dist/assets/ofetch.CWycOUEr-CHp-crOQ.js +0 -1
  315. package/site/dist/assets/parseAbi-Csg-8t59.js +0 -2
  316. package/site/dist/assets/parseAbiParameters-BWbIMYe4.js +0 -1
  317. package/site/dist/assets/parseEther-CGP3gnf2.js +0 -1
  318. package/site/dist/assets/pkce-DXF0yKjP-Bqz4wAsq.js +0 -1
  319. package/site/dist/assets/preload-helper-BaNbYf_w.js +0 -1
  320. package/site/dist/assets/privy-context-81KmsBw2-CjWGzyg7.js +0 -2
  321. package/site/dist/assets/property-DuZ9DLP4.js +0 -3
  322. package/site/dist/assets/react-DCXkXSrv.js +0 -1
  323. package/site/dist/assets/react-DQnMl2Xv.js +0 -1
  324. package/site/dist/assets/react-DrJ0MmMO.js +0 -1
  325. package/site/dist/assets/react-auth-sHnipzbS.js +0 -1
  326. package/site/dist/assets/react-dom-5dW7aKoP.js +0 -1
  327. package/site/dist/assets/reservoir-x-nGuZkT-BMX127i6.js +0 -1
  328. package/site/dist/assets/roles-32M1l9jI.js +0 -1
  329. package/site/dist/assets/rolldown-runtime-BcKkbAw3.js +0 -1
  330. package/site/dist/assets/safe-url-D7SRPu33-CkMedGro.js +0 -1
  331. package/site/dist/assets/secp256k1-C4nzcPo-.js +0 -1
  332. package/site/dist/assets/secp256k1-D92aGNnU.js +0 -1
  333. package/site/dist/assets/secp256k1-DmbwyFau.js +0 -1
  334. package/site/dist/assets/secp256k1-_MleGpqL.js +0 -1
  335. package/site/dist/assets/secp256k1-xl2og-wO.js +0 -1
  336. package/site/dist/assets/serializeAuthorizationList-CX8hGL56.js +0 -1
  337. package/site/dist/assets/serializeSignature-DfxkPnu-.js +0 -2
  338. package/site/dist/assets/sha2-BU_QyRTx.js +0 -1
  339. package/site/dist/assets/shared-DRZUmnL5-xqAUARWo.js +0 -193
  340. package/site/dist/assets/shared-FM0rljBt--Avg6q2R.js +0 -21
  341. package/site/dist/assets/shouldProceedtoEmbeddedWalletCreationFlow-B3vyavrh-ByFOTrQK.js +0 -1
  342. package/site/dist/assets/simulateTransaction-CfuOrae4-CMFGDgT_.js +0 -1
  343. package/site/dist/assets/smartphone-CcEZ-XAy.js +0 -1
  344. package/site/dist/assets/src-BBjkfi-Q.js +0 -1
  345. package/site/dist/assets/storage-Ufl800Ne-EalZTH9q.js +0 -9
  346. package/site/dist/assets/stringify-BlDm7tuc.js +0 -21
  347. package/site/dist/assets/stripe.esm-CZRDpc-N.js +0 -2
  348. package/site/dist/assets/styles-BsotlekN-CXEB4Ud9.js +0 -9
  349. package/site/dist/assets/styles-Cm9H63WO-D90SsXOs.js +0 -92
  350. package/site/dist/assets/styles-DVyDvTdj-BTABn2K8.js +0 -74
  351. package/site/dist/assets/styles-hslXy6xG-D-49b1rk.js +0 -164
  352. package/site/dist/assets/telegram-B-JqnkqZ-RBoY3PLx.js +0 -1
  353. package/site/dist/assets/to-ui-error-DWe-qwS3-DgCO-Y70.js +0 -4
  354. package/site/dist/assets/toViemAccount-B5iDGq1b-DZ1MBqUW.js +0 -2
  355. package/site/dist/assets/transaction-BNTP-bFm-M5tJx8vY.js +0 -1
  356. package/site/dist/assets/transfer-6YztDh-t-BVQkTvG-.js +0 -1
  357. package/site/dist/assets/transformers.web-D4RvOP4-.js +0 -40
  358. package/site/dist/assets/transformers.web-D8W1u_I2.js +0 -49
  359. package/site/dist/assets/triangle-alert-CWjYH75H.js +0 -1
  360. package/site/dist/assets/twitch-5IOe4sIQ-lDtgk0os.js +0 -1
  361. package/site/dist/assets/types-4CuOD23i.js +0 -1
  362. package/site/dist/assets/use-headless-crypto-deposit-Yn-QRLB3-Dn6_8w-Y.js +0 -1
  363. package/site/dist/assets/use-unlink-wallet-BKK4_5Ur-DgsQ75lh.js +0 -1
  364. package/site/dist/assets/useActiveWallet-B-yZYGc6-B6JWREbk.js +0 -123
  365. package/site/dist/assets/useGetSolPrice-x7gfUIHJ-D1hmQfpA.js +0 -1
  366. package/site/dist/assets/useGetTokenPrice-CaoUkb79-ZnbuJ-vP.js +0 -1
  367. package/site/dist/assets/useI18n-C-5n_noF-BcqC76yj.js +0 -1
  368. package/site/dist/assets/useWalletBalance-CZnP5f_f-L3V0jDjL.js +0 -1
  369. package/site/dist/assets/useWallets-X1ndvJ_U-CLwUcevw.js +0 -1
  370. package/site/dist/assets/utils-BkR7EQjg.js +0 -1
  371. package/site/dist/assets/utils-DJhBNOZA.js +0 -1
  372. package/site/dist/assets/utils-DdckVfQr.js +0 -1
  373. package/site/dist/assets/w3m-modal-BMubXAoG.js +0 -1174
  374. package/site/dist/assets/wallet-Bn85Sg2W.js +0 -1
  375. package/site/dist/assets/wallet-connect-BvJtUsDt-Y03hhqFN.js +0 -1
  376. package/site/dist/assets/wallet-uSKqQsgP.js +0 -2
  377. package/site/dist/assets/walletconnect-registry-xxG8XLCb-D1SSFvMp.js +0 -1
  378. package/site/dist/assets/walletconnect-v2-3frQFwbg-Dv6JY_ko.js +0 -12
  379. package/site/dist/assets/wui-ux-by-reown-fVu0QkI4.js +0 -1147
  380. package/site/dist/assets/x-rlSp9U7W.js +0 -1
  381. package/src/discover/explore.js +0 -271
  382. package/src/market/settle.js +0 -165
  383. package/src/market/terms.js +0 -200
  384. package/src/publish/cli.js +0 -336
  385. package/src/publish/envelope.js +0 -185
  386. package/src/publish/manifest.js +0 -142
@@ -1,6 +1,6 @@
1
1
  // The embedder, off the main thread.
2
2
  //
3
- // nomic-embed-text-v1.5 q8 is a 131MB ONNX download, and ONNX Runtime's WASM init
3
+ // EmbeddingGemma-300m q8 is a ~300MB ONNX download, and ONNX Runtime's WASM init
4
4
  // and every inference after it are synchronous CPU. On the main thread that is a
5
5
  // frozen tab for as long as it takes — which on a first visit is a minute or two
6
6
  // of an app that looks broken rather than busy.
package/src/core/rank.js CHANGED
@@ -159,7 +159,7 @@ export function rankDomains(domains = [], q) {
159
159
  }
160
160
 
161
161
  // ── self-check: `node src/core/rank.js` ──────────────────────────────────────
162
- if (typeof process !== "undefined" && import.meta.url === `file://${process.argv[1]}` && process.argv[1].endsWith("/rank.js")) {
162
+ if (import.meta.url === `file://${globalThis.process?.argv?.[1]}` && process.argv[1].endsWith("/rank.js")) {
163
163
  // Word boundaries: the bug this replaced ranked "intoxicated" for "cat".
164
164
  if (lexScore({ text: "intoxicated education" }, "cat") !== 0) throw new Error("substring matched — word boundaries lost");
165
165
  if (lexScore({ text: "a cat sat" }, "cat") <= 0) throw new Error("whole word must match");
package/src/core/roles.js CHANGED
@@ -5,7 +5,7 @@
5
5
  // on the next — which is exactly what happened the first time the probe was
6
6
  // pointed at a second bundle.
7
7
  //
8
- // The answer is already baked. A quickbeam domain manifest carries `role_map`
8
+ // The answer is already baked. A view's domain manifest carries `role_map`
9
9
  // (which field is the title, the subtitle, the tags, the prose to search, the
10
10
  // measures, the location, the link) and `presentation` (an icon, an accent and a
11
11
  // singular/plural name per entity type, plus per-type external URL templates).
@@ -158,7 +158,7 @@ export function rolesFrom(manifests = [], sample = []) {
158
158
  /**
159
159
  * Which collection a row belongs to.
160
160
  *
161
- * `entityType` is quickbeam's own convention — both bundles here carry it, and
161
+ * `entityType` is the view's own convention — every row carries it, and
162
162
  * the manifest's `entity_types` counts are keyed by it — so this is the one
163
163
  * field name the format actually fixes. `kind` is the older spelling and is
164
164
  * still on-chain in sond3r's vertices, hence the fallback.
@@ -249,7 +249,7 @@ export const isLocked = (field, roles) =>
249
249
  /** Is this row part of the corpus's free sample — the deterministic slice a
250
250
  * paywalled bake hands over whole so a buyer can read before paying?
251
251
  *
252
- * The bake picks it by hashing the row's own id (quickbeam `paywall.in_sample`),
252
+ * The bake picks it by hashing the row's own id (`inSample`),
253
253
  * which is what stops a seller putting its best rows in the shop window. That
254
254
  * only holds if someone CHECKS, and the check is this function: anyone can
255
255
  * recompute which rows should be free and see whether the shard agrees. */
@@ -371,7 +371,7 @@ export function actionsOf(row, roles) {
371
371
  }
372
372
 
373
373
  // ── self-check: `node src/core/roles.js` ─────────────────────────────────────
374
- if (typeof process !== "undefined" && import.meta.url === `file://${process.argv[1]}` && process.argv[1].endsWith("/roles.js")) {
374
+ if (import.meta.url === `file://${globalThis.process?.argv?.[1]}` && process.argv[1].endsWith("/roles.js")) {
375
375
  // The real places manifest's shape.
376
376
  const places = {
377
377
  role_map: {
@@ -460,9 +460,9 @@ if (typeof process !== "undefined" && import.meta.url === `file://${process.argv
460
460
  if (gatesOf(rolesFrom([places])).length) throw new Error("an ungated view must report no gates");
461
461
  if (isLocked("text", rolesFrom([places]))) throw new Error("nothing is locked in an ungated view");
462
462
 
463
- // The free sample, recomputed. Must agree with quickbeam's paywall.in_sample
464
- // byte for byte or the check that keeps a seller honest checks nothing —
465
- // these ids and their verdicts are pinned against that implementation.
463
+ // The free sample, recomputed. Must agree with the bake's sample byte for byte or
464
+ // the check that keeps a seller honest checks nothing — these ids and their
465
+ // verdicts are pinned.
466
466
  for (const [id, yes] of [["row-47", true], ["row-169", true], ["row-0", false], ["row-3", false], ["row-19", false]]) {
467
467
  if (await inSample(id, 0.01) !== yes) throw new Error(`inSample must match the bake: ${id}`);
468
468
  }
package/src/core/shard.js CHANGED
@@ -1,4 +1,4 @@
1
- // Reading a quickbeam VIEW's Semantic CDN shards, in the consumer's own process.
1
+ // Reading a VIEW's Semantic CDN shards (view.js's layout), in the consumer's own process.
2
2
  //
3
3
  // One view → one manifest per watched (owner, namespace) domain → N gzipped
4
4
  // NDJSON shards, downloaded once, kept in memory, ranked locally — no index
@@ -52,6 +52,7 @@ const _meta = new Map(); // view base → [manifest, …]
52
52
  let _rowText = (f) => [f.name, f.path, f.desc].filter(Boolean).join(" ");
53
53
  /** How to learn the default view. Overridden by the app; unset means an app that
54
54
  * always passes an explicit view base, which is a legitimate way to use this. */
55
+ let _fetch = (url) => fetch(url);
55
56
  let _resolveView = null;
56
57
  /** Called with the domain manifests once they land and BEFORE the first shard is
57
58
  * parsed. See configure(). */
@@ -74,8 +75,11 @@ let _onManifests = null;
74
75
  * the argument the second corpus loaded would silently be parsed with the
75
76
  * first one's text role.
76
77
  */
77
- export function configure({ resolveView, rowText, onManifests } = {}) {
78
+ export function configure({ resolveView, rowText, onManifests, fetch: f } = {}) {
78
79
  if (resolveView) _resolveView = resolveView;
80
+ // `fetch`: how a view's files are read. A Worker serving its own view reads them from
81
+ // its bucket, since a Worker cannot fetch its own URL.
82
+ if (f) _fetch = f;
79
83
  if (rowText) _rowText = rowText;
80
84
  if (onManifests) _onManifests = onManifests;
81
85
  }
@@ -135,7 +139,7 @@ export function setDomains(only) {
135
139
  const wanted = (name) => !_only || _only.some((e) =>
136
140
  name === e || name.split("/").pop() === e || name.startsWith(e));
137
141
 
138
- const NO_VIEW = "no quickbeam view configured — pass a view base, or wire one with configure({ resolveView })";
142
+ const NO_VIEW = "no view configured — pass a view base, or wire one with configure({ resolveView })";
139
143
 
140
144
  /** Fetch + parse a view's shards. Cached PER VIEW; concurrent callers share one
141
145
  * fetch. Keyed by the resolved base, so two apps on screen in one session can't
@@ -171,7 +175,7 @@ export async function loadShard(base, onRows) {
171
175
  * below. Exported because an app resolving its own view reads config the same
172
176
  * way, and a second copy of the sniff would drift. */
173
177
  export async function fetchText(url) {
174
- const res = await fetch(url);
178
+ const res = await _fetch(url);
175
179
  if (!res.ok) throw new Error(`shard: HTTP ${res.status} for ${url}`);
176
180
 
177
181
  // Who gunzips depends on the server. `cdn serve` sends a shard as
@@ -266,7 +270,7 @@ async function verifyShard(url, expect, chunks, gz) {
266
270
  * read, so this is an optimisation and never a requirement.
267
271
  */
268
272
  async function fetchLines(url, onLine, expect) {
269
- const res = await fetch(url);
273
+ const res = await _fetch(url);
270
274
  if (!res.ok) throw new Error(`shard: HTTP ${res.status} for ${url}`);
271
275
  if (!res.body) {
272
276
  // The buffered path has every byte before it parses one, so it can verify
@@ -343,7 +347,7 @@ async function load(view, onRows) {
343
347
  // A view with nothing baked yet is the normal state of a brand-new one, not an
344
348
  // error. Say which it is, or "search finds nothing" is indistinguishable from
345
349
  // a URL pointing at the wrong view.
346
- if (!domains.length) console.warn(`shard: quickbeam view ${cdn} has no baked domains yet — nothing to read until the watcher bakes one.`);
350
+ if (!domains.length) console.warn(`shard: view ${cdn} has no baked domains yet — nothing to read until its indexer bakes one.`);
347
351
 
348
352
  const byId = new Map();
349
353
  const dead = new Set();
@@ -438,7 +442,7 @@ export async function suggestDomains(q, { url } = {}) {
438
442
  }
439
443
 
440
444
  // ── self-check: `node src/core/shard.js` — no network, no view ────────────────
441
- if (typeof process !== "undefined" && import.meta.url === `file://${process.argv[1]}` && process.argv[1].endsWith("/shard.js")) {
445
+ if (import.meta.url === `file://${globalThis.process?.argv?.[1]}` && process.argv[1].endsWith("/shard.js")) {
442
446
  const { gzipSync } = await import("node:zlib");
443
447
  const warn = console.warn, info = console.info;
444
448
  console.warn = console.info = () => {}; // the fallback warnings are behaviour under test, not output
@@ -662,7 +666,7 @@ if (typeof process !== "undefined" && import.meta.url === `file://${process.argv
662
666
  }
663
667
 
664
668
  // ── the bake's packed vector (`v`), the form shipped today ──
665
- // Pinned against pack_vec in quickbeam/vectors.py: [0,1,-1] -> "AH+B". A
669
+ // Pinned: [0,1,-1] -> "AH+B" (packVec in embed.js writes it). A
666
670
  // drift here is not a crash, it is cosine ranking on noise.
667
671
  {
668
672
  await serveView({ d0: [[{ track_id: "p1", owner: "0xa", v: "AH+B", fields: { entityType: "file", name: "packed.md", path: "packed.md" } },
@@ -1,20 +1,15 @@
1
- // The index of apps — read off the chain.
1
+ // The index of apps, read off the chain.
2
2
  //
3
- // An app owner binds its agent card with `setAppAgentUri`, and the AppRegistry
4
- // emits `AppAgentChanged(appId, uri)`. The log IS the directory: no registry
5
- // namespace to bake, no relay to ask, nobody's server in the loop. Scan the
6
- // logs, keep each app's latest uri, and hand every uri to `discoverApp`, which
7
- // fetches the card and checks it names that app and is still the one bound on
8
- // chain. The card then says where the data is (`views`) and where it starts
9
- // (`fromBlock`).
3
+ // An app is a publisher's repo whose `@card` record points at an agent card that points back.
4
+ // So the directory is `repos()` (one scan of the update log), each repo's `@card` (one read
5
+ // per repo, cached by head), and `discoverCard` on each card found, which checks the binding.
6
+ // No registry, no relay, nobody's server in the loop.
10
7
  //
11
- // `fangorn` is an SDK client, passed in rather than imported, so this module
12
- // stays usable where the SDK is not installed, and testable without a chain.
13
- // Reads only: a reader can create one with a throwaway key.
8
+ // `fangorn` is an SDK client, passed in rather than imported, so this module stays usable
9
+ // where the SDK is not installed, and testable without a chain.
14
10
  //
15
- // ponytail: one flat list, no ranking. Every card is one fetch, all in
16
- // parallel. Past a few hundred apps, rank by the cards' own coverage instead of
17
- // fetching them all.
11
+ // ponytail: one flat list, no ranking, every card fetched. Past a few hundred apps, rank by
12
+ // the cards' own coverage instead.
18
13
 
19
14
  /**
20
15
  * A pointer someone else wrote, and following it is the one place a reader
@@ -29,85 +24,126 @@ function safeView(url) {
29
24
  } catch { return null; }
30
25
  }
31
26
 
32
- /** The SDK's FANGORN_APP_EXTENSION. Copied so this file needs no SDK;
27
+ /** The SDK's FANGORN_REPO_EXTENSION. Copied so this file needs no SDK;
33
28
  * src/agent/agent-card.js's self-check fails if the two drift. */
34
- export const APP_EXTENSION = "https://fangorn.network/a2a/app/v1";
29
+ export const APP_EXTENSION = "https://fangorn.network/a2a/repo/v1";
35
30
 
36
- /** A verified card → an app entry. `views` is westmarch's param; the SDK does not read it. */
37
- export function toApp({ card, appId, fromBlock, namespaces }, cardUrl) {
38
- const ext = card.capabilities.extensions.find((e) => e.uri === APP_EXTENSION);
39
- const views = (Array.isArray(ext?.params?.views) ? ext.params.views : []).map(safeView).filter(Boolean);
40
- const p = ext?.params?.paid;
41
- const paid = p && /^https?:\/\//.test(p.url ?? "") && p.url.includes("{id}") && /^\d+$/.test(String(p.price)) ? p : null;
31
+ /** The app's agent skill, `{url, sha256}`, when its card names one well-formed; else null. */
32
+ export const skillOf = (ext) => {
33
+ const k = ext?.params?.skill;
34
+ return k && safeView(k.url) && /^[0-9a-f]{64}$/.test(k.sha256 ?? "") ? { url: k.url, sha256: k.sha256 } : null;
35
+ };
36
+
37
+ // The app's Claude Code plugin, for what a skill can't do (hooks). Both fields reach a shell command
38
+ // in the reader's agent, so they are held to a GitHub owner/repo (or https URL) and a plain name.
39
+ export const PLUGIN_MARKETPLACE = /^([\w.-]+\/[\w.-]+|https:\/\/[\w.\/-]+)$/, PLUGIN_NAME = /^[a-z0-9][a-z0-9-]*$/;
40
+ export const pluginOf = (ext) => {
41
+ const p = ext?.params?.plugin;
42
+ return p && PLUGIN_MARKETPLACE.test(p.marketplace ?? "") && PLUGIN_NAME.test(p.name ?? "") ? { marketplace: p.marketplace, name: p.name } : null;
43
+ };
44
+
45
+ /** A verified card (`discoverCard`'s result) → an app entry. `views` etc. are westmarch's params; the SDK ignores them. */
46
+ export function toApp({ card, publisher, repo }, cardUrl) {
47
+ const p = card.capabilities.extensions.find((e) => e.uri === APP_EXTENSION)?.params ?? {};
48
+ const views = (Array.isArray(p.views) ? p.views : []).map(safeView).filter(Boolean);
49
+ const paid = p.paid && /^https?:\/\//.test(p.paid.url ?? "") && p.paid.url.includes("{id}") ? { url: p.paid.url } : null;
42
50
  return {
43
- appId, card: cardUrl, fromBlock, namespaces, views, paid,
44
- name: card.name ?? appId,
51
+ id: `${publisher}:${repo}`, publisher, repo, card: cardUrl,
52
+ fromBlock: /^\d+$/.test(String(p.fromBlock)) ? BigInt(p.fromBlock) : null,
53
+ repos: Array.isArray(p.repos) ? p.repos.filter((r) => typeof r === "string") : [],
54
+ views, paid, skill: skillOf({ params: p }), plugin: pluginOf({ params: p }),
55
+ mcp: safeView(p.mcp),
56
+ tools: (card.skills ?? []).map((k) => k.id),
57
+ name: card.name ?? repo,
45
58
  desc: card.description ?? "",
46
59
  url: safeView(card.url),
47
60
  };
48
61
  }
49
62
 
63
+ // Blocks this close to the head can still reorg: read again every time, never stored.
64
+ const SETTLED = 64n;
65
+
66
+ /**
67
+ * Logs from `start` to `head`, oldest first, reading only the blocks `store`
68
+ * has not seen. A scan from the registry's deployment grows with the chain;
69
+ * this one grows with the time since the last call. `store` is `{ get, set }`
70
+ * of `{ to, logs }` by `key`; `read(from, to)` returns logs with `blockNumber`.
71
+ */
72
+ export async function cachedLogs(store, key, start, head, read) {
73
+ const hit = store.get(key) ?? { to: start - 1n, logs: [] };
74
+ const fresh = hit.to < head ? await read(hit.to + 1n, head) : [];
75
+ const settled = head - SETTLED;
76
+ if (settled > hit.to) store.set(key, { to: settled, logs: [...hit.logs, ...fresh.filter((l) => l.blockNumber <= settled)] });
77
+ return [...hit.logs, ...fresh];
78
+ }
79
+
50
80
  /**
51
- * Every app with a bound, verifiable card. The ones that fail are reported
52
- * with the reason, not dropped: a card that is down and a card that lies look
53
- * the same from outside, and an agent should see both.
54
- *
55
- * An app that cleared its uri (bound to "") is skipped. It is not an error.
81
+ * Every app with a bound, verifiable card. The ones that fail are reported with the reason,
82
+ * not dropped: a card that is down and a card that lies look the same from outside, and an
83
+ * agent should see both. `store` ({ get, set }) caches each repo's card URL by head.
56
84
  */
57
- export async function listApps(fangorn, { fromBlock, toBlock } = {}) {
58
- if (fromBlock == null) throw new Error("listApps: pass fromBlock, a block at or before the AppRegistry's deployment — from 0 is one RPC call per 1000 blocks of chain history");
59
- const logs = await fangorn.getAppRegistry().getAppAgentLogs({ fromBlock: BigInt(fromBlock), toBlock });
60
- // Oldest first, so the last write wins. discoverApp re-reads the binding,
61
- // so a stale uri here is caught there, not trusted.
62
- const latest = new Map(logs.map((l) => [l.appId, l.agentUri]));
85
+ export async function listApps(fangorn, { fromBlock, store } = {}) {
86
+ const repos = await fangorn.repos(fromBlock == null ? {} : { fromBlock: BigInt(fromBlock) });
63
87
  const apps = [], rejected = [];
64
- await Promise.all([...latest].map(async ([appId, uri]) => {
65
- if (!uri) return;
66
- try { apps.push(toApp(await fangorn.discoverApp(uri), uri)); }
67
- catch (e) { rejected.push({ appId, card: uri, why: e?.message ?? String(e) }); }
88
+ await Promise.all(repos.map(async ({ owner, repo, root }) => {
89
+ const key = `card:${owner.toLowerCase()}/${repo}@${root}`;
90
+ let url = store?.get(key);
91
+ if (url === undefined) {
92
+ try { url = (await fangorn.cardOf(owner, repo)) ?? null; } catch { return; } // unreadable now: not cached, tried next time
93
+ store?.set(key, url);
94
+ }
95
+ if (!url) return;
96
+ try { apps.push(toApp(await fangorn.discoverCard(url), url)); }
97
+ catch (e) { rejected.push({ publisher: owner, repo, card: url, why: e?.message ?? String(e) }); }
68
98
  }));
69
99
  apps.sort((a, b) => a.name.localeCompare(b.name));
70
100
  return { apps, rejected };
71
101
  }
72
102
 
73
103
  // ── self-check: `node src/discover/apps.js` ──────────────────────────────────────
74
- if (typeof process !== "undefined" && import.meta.url === `file://${process.argv[1]}` && process.argv[1].endsWith("/apps.js")) {
104
+ if (import.meta.url === `file://${globalThis.process?.argv?.[1]}` && process.argv[1].endsWith("/apps.js")) {
75
105
  const j = (x) => JSON.stringify(x, (_, v) => (typeof v === "bigint" ? `${v}n` : v));
76
106
  const eq = (a, b, m) => { if (j(a) !== j(b)) throw new Error(`${m}: ${j(a)} != ${j(b)}`); };
77
- const A = "0x" + "a".repeat(64), B = "0x" + "b".repeat(64), C = "0x" + "c".repeat(64);
78
- const card = (appId, name, views) => ({ name, description: `${name}!`, url: "https://x.test/", capabilities: { extensions: [
79
- { uri: "https://other/ext", params: { appId, views: ["https://evil.test/"] } },
80
- { uri: "https://fangorn.network/a2a/app/v1", params: { appId, views } },
107
+ const P = "0x" + "11".repeat(20), Q = "0x" + "22".repeat(20);
108
+ const card = (publisher, repo, name, views) => ({ name, description: `${name}!`, url: "https://x.test/", capabilities: { extensions: [
109
+ { uri: "https://other/ext", params: { views: ["https://evil.test/"] } },
110
+ { uri: APP_EXTENSION, params: { publisher, repo, fromBlock: "7", repos: ["n"], views } },
81
111
  ] } });
82
112
  const cards = {
83
- "https://a.test/card": card(A, "Beta", ["https://a.test/q/v1/stream", "javascript:alert(1)"]),
84
- "https://a.test/old": card(A, "Old", []),
85
- "https://b.test/card": card(B, "Alpha", []),
113
+ "https://a.test/card": card(P, "beta", "Beta", ["https://a.test/q/v1/stream", "javascript:alert(1)"]),
114
+ "https://b.test/card": card(Q, "alpha", "Alpha", []),
86
115
  };
87
- let askedFrom;
116
+ const bound = { [`${P}/beta`]: "https://a.test/card", [`${Q}/alpha`]: "https://b.test/card", [`${Q}/liar`]: "https://liar.test/card" };
117
+ let cardReads = 0;
88
118
  const fangorn = {
89
- getAppRegistry: () => ({ getAppAgentLogs: ({ fromBlock }) => (askedFrom = fromBlock, Promise.resolve([
90
- { appId: A, agentUri: "https://a.test/old" },
91
- { appId: B, agentUri: "https://b.test/card" },
92
- { appId: A, agentUri: "https://a.test/card" }, // A rebound: last wins
93
- { appId: C, agentUri: "https://c.test/card" },
94
- { appId: C, agentUri: "" }, // C unbound
95
- { appId: "0x" + "d".repeat(64), agentUri: "https://liar.test/card" },
96
- ])) }),
97
- discoverApp: async (uri) => {
98
- if (uri === "https://liar.test/card") throw new Error("not bound to app");
99
- const c = cards[uri];
100
- return { card: c, appId: c.capabilities.extensions[1].params.appId, fromBlock: 7n, namespaces: ["n"] };
119
+ repos: async () => [{ owner: P, repo: "beta", root: "0x1" }, { owner: Q, repo: "alpha", root: "0x2" },
120
+ { owner: Q, repo: "plain", root: "0x3" }, { owner: Q, repo: "liar", root: "0x4" }],
121
+ cardOf: async (o, r) => (cardReads++, bound[`${o}/${r}`]),
122
+ discoverCard: async (url) => {
123
+ if (url === "https://liar.test/card") throw new Error("not bound");
124
+ const c = cards[url], p = c.capabilities.extensions[1].params;
125
+ return { card: c, publisher: p.publisher, repo: p.repo };
101
126
  },
102
127
  };
103
- const { apps, rejected } = await listApps(fangorn, { fromBlock: 42 });
104
- eq(askedFrom, 42n, "fromBlock forwarded as bigint");
105
- eq(apps.map((a) => a.name), ["Alpha", "Beta"], "one entry per app, latest card, sorted, unbound skipped");
128
+ const m = new Map(), store = { get: (k) => m.get(k), set: (k, v) => m.set(k, v) };
129
+ const { apps, rejected } = await listApps(fangorn, { store });
130
+ eq(apps.map((a) => a.name), ["Alpha", "Beta"], "one entry per carded repo, sorted, repos with no card skipped");
106
131
  const beta = apps[1];
107
132
  eq(beta.views, ["https://a.test/q/v1"], "views from the fangorn extension only, trimmed, non-http dropped");
108
- eq([beta.appId, beta.card, beta.url, beta.fromBlock, beta.desc], [A, "https://a.test/card", "https://x.test", 7n, "Beta!"], "entry fields");
109
- eq(rejected.map((r) => r.why), ["not bound to app"], "a card that fails verification is reported");
110
- await listApps(fangorn).then(() => { throw new Error("missing fromBlock must throw"); }, () => {});
133
+ eq([beta.id, beta.card, beta.url, beta.fromBlock, beta.repos, beta.desc], [`${P}:beta`, "https://a.test/card", "https://x.test", 7n, ["n"], "Beta!"], "entry fields");
134
+ eq(rejected.map((r) => r.why), ["not bound"], "a card that fails verification is reported");
135
+ eq(cardReads, 4, "one @card read per repo");
136
+ await listApps(fangorn, { store });
137
+ eq(cardReads, 4, "an unchanged head is not read again");
138
+
139
+ const asked = [];
140
+ const chain = [{ blockNumber: 10n, n: 1 }, { blockNumber: 150n, n: 2 }, { blockNumber: 190n, n: 3 }];
141
+ const read = async (from, to) => (asked.push([from, to]), chain.filter((l) => l.blockNumber >= from && l.blockNumber <= to));
142
+ const lm = new Map(), ls = { get: (k) => lm.get(k), set: (k, v) => lm.set(k, v) };
143
+ eq((await cachedLogs(ls, "k", 5n, 200n, read)).map((l) => l.n), [1, 2, 3], "first call reads it all");
144
+ eq(lm.get("k").to, 136n, "stores only what is settled");
145
+ eq((await cachedLogs(ls, "k", 5n, 210n, read)).map((l) => l.n), [1, 2, 3], "second call: same logs, no duplicates");
146
+ eq(asked, [[5n, 200n], [137n, 210n]], "second call reads only from the settled point");
111
147
 
112
- console.log("apps.js self-check ok — latest card per app, unbound skipped, failures reported, views gated to http(s)");
148
+ console.log("apps.js self-check ok — an app is a repo whose card verifies, cards read once per head, failures reported, views gated to http(s)");
113
149
  }
@@ -189,7 +189,7 @@ export function follow(picks = [], corpora = [], { at = null } = {}) {
189
189
  }
190
190
 
191
191
  // ── self-check: `node src/discover/corpora.js` ───────────────────────────────────
192
- if (typeof process !== "undefined" && import.meta.url === `file://${process.argv[1]}` && process.argv[1].endsWith("/corpora.js")) {
192
+ if (import.meta.url === `file://${globalThis.process?.argv?.[1]}` && process.argv[1].endsWith("/corpora.js")) {
193
193
  const s = session();
194
194
  const add = (view, name, n) => {
195
195
  const c = s.slot(view);
@@ -62,7 +62,7 @@ export async function survey(sources = [], { timeoutMs = 8000 } = {}) {
62
62
  for (const d of cat.domains ?? []) {
63
63
  corpora.push({
64
64
  view,
65
- publisher: typeof src === "string" ? null : (src.name ?? src.appId ?? null),
65
+ publisher: typeof src === "string" ? null : (src.name ?? src.id ?? null),
66
66
  owner: typeof src === "string" ? null : (src.owner ?? null),
67
67
  domain: d.name,
68
68
  description: d.description || "",
@@ -164,11 +164,11 @@ export async function findCorpora(query, { sources = [], embed, model, limit = 1
164
164
  * modules to run a survey. Rejected cards come back beside the sources. */
165
165
  export async function sourcesFromChain(fangorn, opts) {
166
166
  const { apps, rejected } = await listApps(fangorn, opts);
167
- return { sources: apps.flatMap((a) => a.views.map((view) => ({ view, name: a.name, appId: a.appId }))), rejected };
167
+ return { sources: apps.flatMap((a) => a.views.map((view) => ({ view, name: a.name, id: a.id }))), rejected };
168
168
  }
169
169
 
170
170
  // ── self-check: `node src/discover/directory.js` ─────────────────────────────────
171
- if (typeof process !== "undefined" && import.meta.url === `file://${process.argv[1]}` && process.argv[1].endsWith("/directory.js")) {
171
+ if (import.meta.url === `file://${globalThis.process?.argv?.[1]}` && process.argv[1].endsWith("/directory.js")) {
172
172
  const warn = console.warn; console.warn = () => {};
173
173
  const cov = (...vectors) => ({ dim: 2, sampled: 100, vectors, counts: vectors.map(() => 50) });
174
174
 
@@ -247,7 +247,7 @@ export function readout(total, cohort, { minSupport = MIN_SUPPORT } = {}) {
247
247
  }
248
248
 
249
249
  // ── self-check: `node src/market/cohort.js` ──────────────────────────────────
250
- if (typeof process !== "undefined" && import.meta.url === `file://${process.argv[1]}` && process.argv[1].endsWith("/cohort.js")) {
250
+ if (import.meta.url === `file://${globalThis.process?.argv?.[1]}` && process.argv[1].endsWith("/cohort.js")) {
251
251
  const vec = (a, b) => { const v = new Float32Array(STAT_DIM); v[0] = a; v[1] = b; return v; };
252
252
  const log = (n, seed) => Array.from({ length: n }, (_, i) => ({
253
253
  id: `row-${seed}-${i}`, corpus: "films", reaction: i % 4 === 3 ? "skip" : "like",
@@ -383,7 +383,7 @@ export function brief(rep, { title = "demand" } = {}) {
383
383
  }
384
384
 
385
385
  // ── self-check: `node src/market/demand.js` ────────────────────────────────────
386
- if (typeof process !== "undefined" && import.meta.url === `file://${process.argv[1]}` && process.argv[1].endsWith("/demand.js")) {
386
+ if (import.meta.url === `file://${globalThis.process?.argv?.[1]}` && process.argv[1].endsWith("/demand.js")) {
387
387
  const { keypair, statistics, contribute, aggregate, readout } = await import("./cohort.js");
388
388
 
389
389
  // A shelf with two genuine regions and a hole between them. 128 dims so the
@@ -16,7 +16,7 @@
16
16
  // ------------------------------------------------------
17
17
  // A reaction's vector is the vector of the row reacted to, which the reader
18
18
  // already downloaded in order to react to it. So a reaction corpus needs no
19
- // model, no GPU, no bake, no quickbeam — the vectors are copied, not computed.
19
+ // model, no GPU, no bake — the vectors are copied, not computed.
20
20
  // The only thing that has to be fitted locally is `coverage`, which is eight
21
21
  // centroids and is the function below. A consumer becoming a publisher is
22
22
  // therefore not a tier you upgrade into; it is this file and a price.
@@ -50,8 +50,25 @@
50
50
  // IS that reaction's vector under another name, which is the same leak wearing a
51
51
  // hat, and a reader with nine reactions is exactly who most needs this to hold.
52
52
 
53
- import { packVec } from "../core/embed.js";
54
- import { lineage } from "./terms.js";
53
+ import { EMBED_MODEL, packVec } from "../core/embed.js";
54
+
55
+ const ADDR = /^0x[0-9a-fA-F]{40}$/;
56
+ /** What a publisher owes upstream for one resource, in bps of its share. Deduped by payee:
57
+ * the same source cited twice is one debt, not two, which can't be gamed by repeating an entry. */
58
+ function lineage(entries = []) {
59
+ const by = new Map();
60
+ for (const e of entries) {
61
+ const to = String(e.to ?? "").toLowerCase();
62
+ if (!ADDR.test(to)) throw new Error(`not an address: ${e.to}`);
63
+ const b = BigInt(e.bps ?? 0);
64
+ if (b < 0n || b > 10000n) throw new Error(`lineage bps must be 0..10000, got ${e.bps}`);
65
+ by.set(to, { to, bps: (by.get(to)?.bps ?? 0n) + b, note: e.note ?? by.get(to)?.note ?? "" });
66
+ }
67
+ const out = [...by.values()];
68
+ const total = out.reduce((s, e) => s + e.bps, 0n);
69
+ if (total > 10000n) throw new Error(`lineage owes ${total} bps of the publisher's share — more than all of it`);
70
+ return out.map((e) => ({ to: e.to, bps: String(e.bps), ...(e.note ? { note: e.note } : {}) }));
71
+ }
55
72
 
56
73
  // 32, not 8: on Kingsfoil the top 3 of 23 views held 92% of the true top 10 with 32
57
74
  // centroids and 86% with 8, and 8 missed whole topics (ALS → neurology).
@@ -68,7 +85,7 @@ const dot = (a, b) => { let s = 0, n = Math.min(a.length, b.length); for (let i
68
85
  * Spherical k-means over the corpus's own vectors — the routing summary that
69
86
  * lets a buyer rank this corpus WITHOUT downloading it.
70
87
  *
71
- * Mirrors quickbeam's `cdn._coverage`: fit at full width, truncate to `dim`
88
+ * The view's coverage: fit at full width, truncate to `dim`
72
89
  * leading components (Matryoshka), then RENORMALIZE, because a truncated unit
73
90
  * vector is not unit and the client compares against a truncated query it
74
91
  * renormalizes too. Get that order wrong and routing degrades silently.
@@ -216,7 +233,7 @@ export function reactionCorpus(events = [], {
216
233
  description: description ?? `${rows.length} reactions from one reader across ${byCorpus.size} corpora — what held their attention, and what did not.`,
217
234
  count: rows.length,
218
235
  dim: rows[0].vector.length,
219
- model: "nomic-ai/nomic-embed-text-v1.5",
236
+ model: EMBED_MODEL,
220
237
  distance: "Cosine",
221
238
  role_map: {
222
239
  identity: "event", title: "label", subtitle: "corpus", temporal: "month",
@@ -237,8 +254,7 @@ export function reactionCorpus(events = [], {
237
254
  }
238
255
 
239
256
  // ── self-check: `node src/market/reactions.js` ────────────────────────────────
240
- if (typeof process !== "undefined" && import.meta.url === `file://${process.argv[1]}` && process.argv[1].endsWith("/reactions.js")) {
241
- const { splitPayment } = await import("./terms.js");
257
+ if (import.meta.url === `file://${globalThis.process?.argv?.[1]}` && process.argv[1].endsWith("/reactions.js")) {
242
258
  const A = (n) => `0x${String(n).repeat(40).slice(0, 40)}`;
243
259
  const vec = (a, b) => { const v = new Float32Array(256); v[0] = a; v[1] = b; return v; };
244
260
 
@@ -321,16 +337,6 @@ if (typeof process !== "undefined" && import.meta.url === `file://${process.argv
321
337
  if (bps["archive-films"] !== 1500 || bps.games !== 500) throw new Error(`upstream must follow contribution: ${JSON.stringify(bps)}`);
322
338
  if (up.reduce((s, e) => s + Number(e.bps), 0) !== 2000) throw new Error("the declared upstream total must be exact, not a basis point short");
323
339
 
324
- // …and it reconciles against a real sale. This is the claim: the corpora that
325
- // produced the attention are paid when the attention sells.
326
- const TERMS = { appId: "fangorn.tv", owner: A(9), appBps: 1000 };
327
- const pay = splitPayment(300000n, { terms: TERMS, publisher: A(3), lineage: up });
328
- const got = Object.fromEntries(pay.map((p) => [p.to, p.amount]));
329
- if (got[A(9)] !== 30000n) throw new Error("the app's cut comes off the top and never moves");
330
- if (got[A(1)] !== 40500n || got[A(2)] !== 13500n) throw new Error(`upstream is paid from the publisher's share: ${JSON.stringify(got, (k, v) => typeof v === "bigint" ? String(v) : v)}`);
331
- if (got[A(3)] !== 216000n) throw new Error("the reader keeps the rest");
332
- if (pay.reduce((s, p) => s + p.amount, 0n) !== 300000n) throw new Error("money is neither invented nor destroyed");
333
-
334
340
  // A reader who cites a corpus nobody registered simply owes it nothing.
335
341
  const orphan = reactionCorpus(EV, { publisher: A(3), sources: { games: A(2) } });
336
342
  if (orphan.lineage.length !== 1 || Number(orphan.lineage[0].bps) !== 2000) throw new Error("an unregistered corpus cannot be paid, and its share does not vanish");
@@ -341,5 +347,5 @@ if (typeof process !== "undefined" && import.meta.url === `file://${process.argv
341
347
 
342
348
  console.log("reactions.js self-check ok — reactions become a corpus with no model, coverage is deterministic and renormalized after truncation, "
343
349
  + "the free index ranks on centroids alone, publishes no per-row vector to join against and no paid string anywhere including its own keys, "
344
- + "time is coarse, upstream follows contribution exactly and reconciles against a real sale");
350
+ + "time is coarse, upstream follows contribution exactly");
345
351
  }