@oracle-agent/oracle 0.13.1 → 0.14.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 (449) hide show
  1. package/CONTRIBUTING.md +99 -0
  2. package/README.md +20 -14
  3. package/SECURITY.md +6 -8
  4. package/SETUP.md +25 -27
  5. package/bin/desk-server.mjs +473 -0
  6. package/bin/oracle-data-mcp.mjs +1252 -0
  7. package/bin/oracle-equities.mjs +168 -0
  8. package/bin/oracle-init.mjs +525 -0
  9. package/bin/oracle-public-server.mjs +36 -0
  10. package/bin/oracle-route.mjs +254 -0
  11. package/bin/oracle-scan.mjs +192 -0
  12. package/bin/oracle-upgrade.mjs +42 -0
  13. package/bin/oracle.mjs +34 -0
  14. package/docs/adding-a-chain.md +229 -0
  15. package/docs/architecture.md +139 -0
  16. package/docs/buzz-integration.md +115 -0
  17. package/docs/cli.md +143 -0
  18. package/docs/connectors.md +13 -0
  19. package/docs/hyperliquid-builder-code.md +50 -0
  20. package/docs/locals-only-fee-waiver.md +34 -0
  21. package/docs/oracle-pack-standard.md +29 -0
  22. package/docs/profiles.md +151 -0
  23. package/docs/public-surface.md +206 -0
  24. package/examples/add-a-chain.mjs +65 -0
  25. package/examples/oracle-pack-template.mjs +38 -0
  26. package/examples/research-a-token.mjs +70 -0
  27. package/package.json +78 -32
  28. package/plugins/oracle-owner-gate/__init__.py +288 -0
  29. package/plugins/oracle-owner-gate/plugin.yaml +9 -0
  30. package/{dist/assets/profiles → profiles}/oracle/SOUL.md +0 -14
  31. package/protocols/templates/safe-erc20/SECURITY.md +16 -0
  32. package/protocols/templates/safe-erc20/foundry.toml +12 -0
  33. package/protocols/templates/safe-erc20/remappings.txt +2 -0
  34. package/protocols/templates/safe-erc20/src/SafeERC20.sol +53 -0
  35. package/protocols/templates/safe-erc20/test/SafeERC20.t.sol +72 -0
  36. package/public/oracle-splash/_variants/ice.html +3 -3
  37. package/public/oracle-splash/_variants/ivory.html +3 -3
  38. package/public/oracle-splash/downloads/index.html +34 -223
  39. package/public/oracle-splash/index.html +11 -11
  40. package/scripts/adversarial-bench.mjs +114 -0
  41. package/scripts/build-dist.mjs +119 -0
  42. package/scripts/build-inscription.py +230 -0
  43. package/scripts/check-doc-drift.mjs +123 -0
  44. package/scripts/check-test-count.mjs +105 -0
  45. package/scripts/e2e-hl-markets.mjs +21 -0
  46. package/scripts/e2e-hl-perps.mjs +48 -0
  47. package/scripts/e2e-hypercore-staking.mjs +128 -0
  48. package/scripts/e2e-solana-bitcoin.mjs +183 -0
  49. package/scripts/guard-publish.mjs +22 -0
  50. package/scripts/protocol-template-gate.mjs +15 -0
  51. package/scripts/public-api-scan.mjs +23 -0
  52. package/scripts/publish-dist.mjs +67 -0
  53. package/scripts/record-hero-cli.sh +80 -0
  54. package/scripts/secret-scan.mjs +168 -0
  55. package/scripts/smoke-dist-bins.mjs +89 -0
  56. package/scripts/verify-dist.mjs +29 -0
  57. package/scripts/verify-v3-venues.mjs +233 -0
  58. package/skins/oracle.yaml +56 -0
  59. package/src/action-receipts.mjs +265 -0
  60. package/src/action-semantics.mjs +62 -0
  61. package/src/address-book.mjs +208 -0
  62. package/src/agent-auth.mjs +206 -0
  63. package/src/approval-guard.mjs +282 -0
  64. package/src/attestation-secret.mjs +94 -0
  65. package/src/audit-log.mjs +196 -0
  66. package/src/auth/oauth.mjs +672 -0
  67. package/src/auto-slippage.mjs +378 -0
  68. package/src/capability-posture.mjs +125 -0
  69. package/src/cards.mjs +422 -0
  70. package/src/chains.mjs +62 -0
  71. package/src/cli/chain-catalog.mjs +215 -0
  72. package/src/cli/chain-state.mjs +74 -0
  73. package/src/cli/commands/auth.mjs +193 -0
  74. package/src/cli/commands/bootstrap.mjs +87 -0
  75. package/src/cli/commands/chain.mjs +143 -0
  76. package/src/cli/commands/chat.mjs +465 -0
  77. package/src/cli/commands/credential.mjs +9 -0
  78. package/src/cli/commands/data-mcp.mjs +18 -0
  79. package/src/cli/commands/data.mjs +75 -0
  80. package/src/cli/commands/doctor.mjs +136 -0
  81. package/src/cli/commands/equities.mjs +41 -0
  82. package/src/cli/commands/farm.mjs +129 -0
  83. package/src/cli/commands/fees.mjs +109 -0
  84. package/src/cli/commands/follow.mjs +130 -0
  85. package/src/cli/commands/harness.mjs +63 -0
  86. package/src/cli/commands/help.mjs +7 -0
  87. package/src/cli/commands/init.mjs +27 -0
  88. package/src/cli/commands/mcp.mjs +154 -0
  89. package/src/cli/commands/model.mjs +106 -0
  90. package/src/cli/commands/plugins.mjs +241 -0
  91. package/src/cli/commands/prepare.mjs +12 -0
  92. package/src/cli/commands/public.mjs +20 -0
  93. package/src/cli/commands/resolve.mjs +64 -0
  94. package/src/cli/commands/route.mjs +12 -0
  95. package/src/cli/commands/runner.mjs +9 -0
  96. package/src/cli/commands/scan.mjs +12 -0
  97. package/src/cli/commands/setup.mjs +294 -0
  98. package/src/cli/commands/sign.mjs +21 -0
  99. package/src/cli/commands/signer.mjs +9 -0
  100. package/src/cli/commands/swap.mjs +102 -0
  101. package/src/cli/commands/upgrade.mjs +12 -0
  102. package/src/cli/commands/vault.mjs +9 -0
  103. package/src/cli/commands/version.mjs +22 -0
  104. package/src/cli/first-run.mjs +23 -0
  105. package/src/cli/kernel.mjs +262 -0
  106. package/src/cli/mcp-targets/chatgpt.mjs +51 -0
  107. package/src/cli/mcp-targets/claude-code.mjs +39 -0
  108. package/src/cli/mcp-targets/claude-desktop.mjs +24 -0
  109. package/src/cli/mcp-targets/codex.mjs +41 -0
  110. package/src/cli/mcp-targets/cursor.mjs +32 -0
  111. package/src/cli/mcp-targets/shared.mjs +71 -0
  112. package/src/cli/mcp-targets/vscode.mjs +39 -0
  113. package/src/cli/messaging-platforms.mjs +217 -0
  114. package/src/cli/model-config.mjs +78 -0
  115. package/src/cli/operator-dispatch.mjs +257 -0
  116. package/src/cli/oracle-harness.py +415 -0
  117. package/src/cli/paths.mjs +107 -0
  118. package/src/cli/runtime.mjs +351 -0
  119. package/src/cli/setup-state.mjs +168 -0
  120. package/src/cli/spawn-child.mjs +43 -0
  121. package/src/data/catalog.mjs +858 -0
  122. package/src/data/desk-data.mjs +877 -0
  123. package/src/data/http.mjs +253 -0
  124. package/src/data/names.mjs +188 -0
  125. package/src/data/provider-endpoint.mjs +94 -0
  126. package/src/data/providers/aave-v3.mjs +139 -0
  127. package/src/data/providers/across-bridge.mjs +41 -0
  128. package/src/data/providers/aerodrome.mjs +245 -0
  129. package/src/data/providers/aevo.mjs +33 -0
  130. package/src/data/providers/approval-indexer.mjs +133 -0
  131. package/src/data/providers/approvals.mjs +594 -0
  132. package/src/data/providers/babylon-staking.mjs +149 -0
  133. package/src/data/providers/balancer.mjs +209 -0
  134. package/src/data/providers/beefy-yields.mjs +45 -0
  135. package/src/data/providers/birdeye-tokens.mjs +33 -0
  136. package/src/data/providers/bisq-markets.mjs +145 -0
  137. package/src/data/providers/bitcoin-esplora.mjs +216 -0
  138. package/src/data/providers/bitcoin-meta.mjs +378 -0
  139. package/src/data/providers/blockscout.mjs +14 -0
  140. package/src/data/providers/bob-rootstock.mjs +198 -0
  141. package/src/data/providers/braiins-insights.mjs +103 -0
  142. package/src/data/providers/bridge-aggregator.mjs +259 -0
  143. package/src/data/providers/bridges.mjs +242 -0
  144. package/src/data/providers/bungee.mjs +29 -0
  145. package/src/data/providers/celestia-da.mjs +38 -0
  146. package/src/data/providers/changenow.mjs +135 -0
  147. package/src/data/providers/compound.mjs +32 -0
  148. package/src/data/providers/connext.mjs +28 -0
  149. package/src/data/providers/convex.mjs +30 -0
  150. package/src/data/providers/cow-protocol.mjs +110 -0
  151. package/src/data/providers/cowswap.mjs +415 -0
  152. package/src/data/providers/curve.mjs +201 -0
  153. package/src/data/providers/das-assets.mjs +59 -0
  154. package/src/data/providers/debridge.mjs +109 -0
  155. package/src/data/providers/defillama.mjs +88 -0
  156. package/src/data/providers/dexscreener.mjs +43 -0
  157. package/src/data/providers/drift.mjs +32 -0
  158. package/src/data/providers/dydx.mjs +41 -0
  159. package/src/data/providers/evm-rpc.mjs +225 -0
  160. package/src/data/providers/farming.mjs +291 -0
  161. package/src/data/providers/geckoterminal.mjs +34 -0
  162. package/src/data/providers/gmx.mjs +496 -0
  163. package/src/data/providers/hiro-stacks.mjs +150 -0
  164. package/src/data/providers/hl-assets.mjs +165 -0
  165. package/src/data/providers/hl-info.mjs +108 -0
  166. package/src/data/providers/hl-markets.mjs +210 -0
  167. package/src/data/providers/hl-outcome.mjs +61 -0
  168. package/src/data/providers/hl-perps.mjs +419 -0
  169. package/src/data/providers/hl-staking.mjs +353 -0
  170. package/src/data/providers/hl-ws.mjs +119 -0
  171. package/src/data/providers/hyperevm-dex.mjs +49 -0
  172. package/src/data/providers/jito-mev.mjs +117 -0
  173. package/src/data/providers/jupiter-venues.mjs +119 -0
  174. package/src/data/providers/jupiter.mjs +315 -0
  175. package/src/data/providers/kamino-strategies.mjs +143 -0
  176. package/src/data/providers/l2beat-tvl.mjs +42 -0
  177. package/src/data/providers/lifi.mjs +166 -0
  178. package/src/data/providers/liquid-esplora.mjs +152 -0
  179. package/src/data/providers/magiceden-ordinals.mjs +141 -0
  180. package/src/data/providers/magiceden-sol.mjs +406 -0
  181. package/src/data/providers/mempool-lightning.mjs +144 -0
  182. package/src/data/providers/mempool-mining.mjs +142 -0
  183. package/src/data/providers/meteora-dlmm.mjs +168 -0
  184. package/src/data/providers/morpho.mjs +177 -0
  185. package/src/data/providers/nft-gallery.mjs +163 -0
  186. package/src/data/providers/nft-portfolio.mjs +494 -0
  187. package/src/data/providers/odos.mjs +156 -0
  188. package/src/data/providers/ondo.mjs +31 -0
  189. package/src/data/providers/oneinch.mjs +174 -0
  190. package/src/data/providers/opensea-multichain.mjs +136 -0
  191. package/src/data/providers/opensea-nft.mjs +371 -0
  192. package/src/data/providers/orca.mjs +29 -0
  193. package/src/data/providers/ordinals-runes.mjs +180 -0
  194. package/src/data/providers/pancakeswap.mjs +28 -0
  195. package/src/data/providers/paraswap.mjs +125 -0
  196. package/src/data/providers/pendle.mjs +188 -0
  197. package/src/data/providers/poly-clob.mjs +283 -0
  198. package/src/data/providers/poly-public.mjs +96 -0
  199. package/src/data/providers/poly-ws.mjs +103 -0
  200. package/src/data/providers/polygon-staking.mjs +227 -0
  201. package/src/data/providers/portfolio-history.mjs +394 -0
  202. package/src/data/providers/portfolio.mjs +600 -0
  203. package/src/data/providers/pyth-price-feeds.mjs +172 -0
  204. package/src/data/providers/raydium.mjs +35 -0
  205. package/src/data/providers/relayscan-mev.mjs +72 -0
  206. package/src/data/providers/rfq.mjs +15 -0
  207. package/src/data/providers/rh-agent.mjs +59 -0
  208. package/src/data/providers/sanctum-lst.mjs +180 -0
  209. package/src/data/providers/satflow.mjs +341 -0
  210. package/src/data/providers/signed-material-guard.mjs +108 -0
  211. package/src/data/providers/solana-rpc.mjs +197 -0
  212. package/src/data/providers/solend-lending.mjs +166 -0
  213. package/src/data/providers/spark-lend.mjs +42 -0
  214. package/src/data/providers/squid-router.mjs +29 -0
  215. package/src/data/providers/stargate.mjs +29 -0
  216. package/src/data/providers/sushiswap.mjs +30 -0
  217. package/src/data/providers/symbiotic-restaking.mjs +41 -0
  218. package/src/data/providers/thorchain.mjs +36 -0
  219. package/src/data/providers/traderjoe.mjs +28 -0
  220. package/src/data/providers/twap.mjs +152 -0
  221. package/src/data/providers/uniswap-v3.mjs +457 -0
  222. package/src/data/providers/uniswap-v4.mjs +414 -0
  223. package/src/data/providers/vertex.mjs +41 -0
  224. package/src/data/providers/wallet-watch.mjs +264 -0
  225. package/src/data/providers/wormhole.mjs +28 -0
  226. package/src/data/providers/yearn.mjs +31 -0
  227. package/src/data/providers/zerox.mjs +167 -0
  228. package/src/data/public-api-scan.mjs +61 -0
  229. package/src/data/quote-placeholder.mjs +31 -0
  230. package/src/desk/swap-prepare.mjs +194 -0
  231. package/src/equities/bridge.mjs +388 -0
  232. package/src/equities/fixtures/bridge_routes.json +159 -0
  233. package/src/equities/fixtures/dst_transitions.json +29 -0
  234. package/src/equities/fixtures/equity_dex_pools.json +154 -0
  235. package/src/equities/fixtures/hip3_l2books.json +2711 -0
  236. package/src/equities/fixtures/nyse_holidays.json +1 -0
  237. package/src/equities/fixtures/oracles.json +100 -0
  238. package/src/equities/fixtures/rh_pool_state.json +244 -0
  239. package/src/equities/fixtures/solana_xstocks.json +704 -0
  240. package/src/equities/fixtures/ton_xstocks.json +35 -0
  241. package/src/equities/fixtures/universe.json +411 -0
  242. package/src/equities/fixtures/venues.json +3542 -0
  243. package/src/equities/fixtures.mjs +405 -0
  244. package/src/equities/funding.mjs +142 -0
  245. package/src/equities/index.mjs +166 -0
  246. package/src/equities/liveness.mjs +148 -0
  247. package/src/equities/marketHours.mjs +249 -0
  248. package/src/equities/normalize.mjs +295 -0
  249. package/src/equities/num.mjs +146 -0
  250. package/src/equities/prepare.mjs +95 -0
  251. package/src/equities/rank.mjs +260 -0
  252. package/src/equities/sourceNum.mjs +69 -0
  253. package/src/equities/types.mjs +220 -0
  254. package/src/equities/venues/arcus-perp.mjs +84 -0
  255. package/src/equities/venues/arcus-spot.mjs +105 -0
  256. package/src/equities/venues/hyperliquid-hip3.mjs +224 -0
  257. package/src/equities/venues/rh-uniswap.mjs +216 -0
  258. package/src/equities/venues/solana-xstocks.mjs +139 -0
  259. package/src/equities/venues/ton-stonfi.mjs +139 -0
  260. package/src/exact-integer.mjs +72 -0
  261. package/src/exec-policy.mjs +419 -0
  262. package/src/flags.mjs +15 -0
  263. package/src/fresh-window.mjs +76 -0
  264. package/src/gmx-attestation.mjs +176 -0
  265. package/src/index.mjs +107 -0
  266. package/src/licensing/locals-only.mjs +25 -0
  267. package/src/nft-gas-war-guard.mjs +139 -0
  268. package/src/onboarding/agent-keys.mjs +161 -0
  269. package/src/onboarding/harness-configs.mjs +102 -0
  270. package/src/onboarding/index.mjs +18 -0
  271. package/src/onboarding/tiers.mjs +139 -0
  272. package/src/oracle-env.mjs +55 -0
  273. package/src/package-manifest.mjs +42 -0
  274. package/src/plugins/agent-plugin-loader.mjs +225 -0
  275. package/src/portfolio-risk.mjs +170 -0
  276. package/src/prepare-envelope.mjs +204 -0
  277. package/src/profile-upgrade.mjs +277 -0
  278. package/src/protocol-execution.mjs +84 -0
  279. package/src/protocol-templates/gate.mjs +179 -0
  280. package/src/protocol-templates/prepare-deploy.mjs +81 -0
  281. package/src/public-api/agent-grants.mjs +57 -0
  282. package/src/public-api/buzz-integration.mjs +267 -0
  283. package/src/public-api/connect-agent.mjs +424 -0
  284. package/src/public-api/grants.mjs +142 -0
  285. package/src/public-api/http.mjs +707 -0
  286. package/src/public-api/metering.mjs +111 -0
  287. package/src/public-control/aa-adapter.mjs +402 -0
  288. package/src/public-control/build-registry.mjs +227 -0
  289. package/src/public-control/bundler-client.mjs +357 -0
  290. package/src/public-control/grant-indexer.mjs +296 -0
  291. package/src/public-control/policy-render.mjs +69 -0
  292. package/src/public-control/policy-schema.mjs +322 -0
  293. package/src/public-control/runtime-config.mjs +275 -0
  294. package/src/public-control/session-key-model.mjs +379 -0
  295. package/src/public-control/session-orchestrator.mjs +418 -0
  296. package/src/rfq/intent.mjs +180 -0
  297. package/src/rfq/sources.mjs +181 -0
  298. package/src/route-attestation.mjs +132 -0
  299. package/src/router/best-execution.mjs +326 -0
  300. package/src/router/index.mjs +250 -0
  301. package/src/router/integrator-fee.mjs +135 -0
  302. package/src/router/prepare-bridge.mjs +293 -0
  303. package/src/router/prepare-route.mjs +398 -0
  304. package/src/router/proposal.mjs +311 -0
  305. package/src/router/risk-classifier.mjs +119 -0
  306. package/src/router/route-sources.mjs +364 -0
  307. package/src/scanner/chains.config.mjs +543 -0
  308. package/src/scanner/contract.mjs +270 -0
  309. package/src/scanner/evm-scanner.mjs +394 -0
  310. package/src/scanner/index.mjs +9 -0
  311. package/src/scanner/v2-venue.mjs +351 -0
  312. package/src/scanner/v3-venue.mjs +308 -0
  313. package/src/scopes.mjs +44 -0
  314. package/src/sell-simulation.mjs +167 -0
  315. package/src/signals/engine.mjs +146 -0
  316. package/src/signals/index.mjs +1 -0
  317. package/src/token-transfer-guard.mjs +188 -0
  318. package/src/tui/app.mjs +438 -0
  319. package/src/tui/backend.mjs +215 -0
  320. package/src/tui/format.mjs +272 -0
  321. package/src/tui/gateway-client.mjs +177 -0
  322. package/src/tui/input.mjs +501 -0
  323. package/src/tui/memory.mjs +105 -0
  324. package/src/tui/meta-learn.mjs +85 -0
  325. package/src/tui/renderer.mjs +443 -0
  326. package/src/tui/scheduler.mjs +205 -0
  327. package/src/tui/skills-loader.mjs +140 -0
  328. package/src/tui/standalone-client.mjs +752 -0
  329. package/src/tui/theme.mjs +81 -0
  330. package/src/vault-attestation.mjs +146 -0
  331. package/src/venues.mjs +206 -0
  332. package/src/watch-preferences.mjs +85 -0
  333. package/dist/action-receipts.mjs +0 -1
  334. package/dist/action-semantics.mjs +0 -1
  335. package/dist/address-book.mjs +0 -2
  336. package/dist/bin/desk-server.mjs +0 -59
  337. package/dist/bin/oracle-data-mcp.mjs +0 -8
  338. package/dist/bin/oracle-equities.mjs +0 -20
  339. package/dist/bin/oracle-init.mjs +0 -24
  340. package/dist/bin/oracle-public-server.mjs +0 -5
  341. package/dist/bin/oracle-route.mjs +0 -22
  342. package/dist/bin/oracle-scan.mjs +0 -18
  343. package/dist/bin/oracle-upgrade.mjs +0 -21
  344. package/dist/bin/oracle.mjs +0 -76
  345. package/dist/chains.mjs +0 -1
  346. package/dist/cli/commands/auth.mjs +0 -16
  347. package/dist/cli/commands/bootstrap.mjs +0 -18
  348. package/dist/cli/commands/chain.mjs +0 -21
  349. package/dist/cli/commands/chat.mjs +0 -45
  350. package/dist/cli/commands/credential.mjs +0 -1
  351. package/dist/cli/commands/data-mcp.mjs +0 -2
  352. package/dist/cli/commands/data.mjs +0 -12
  353. package/dist/cli/commands/doctor.mjs +0 -5
  354. package/dist/cli/commands/equities.mjs +0 -15
  355. package/dist/cli/commands/farm.mjs +0 -59
  356. package/dist/cli/commands/follow.mjs +0 -28
  357. package/dist/cli/commands/gate.mjs +0 -13
  358. package/dist/cli/commands/harness.mjs +0 -15
  359. package/dist/cli/commands/help.mjs +0 -1
  360. package/dist/cli/commands/init.mjs +0 -3
  361. package/dist/cli/commands/mcp.mjs +0 -60
  362. package/dist/cli/commands/model.mjs +0 -54
  363. package/dist/cli/commands/plugins.mjs +0 -38
  364. package/dist/cli/commands/prepare.mjs +0 -2
  365. package/dist/cli/commands/public.mjs +0 -3
  366. package/dist/cli/commands/resolve.mjs +0 -23
  367. package/dist/cli/commands/route.mjs +0 -2
  368. package/dist/cli/commands/runner.mjs +0 -1
  369. package/dist/cli/commands/scan.mjs +0 -2
  370. package/dist/cli/commands/setup.mjs +0 -34
  371. package/dist/cli/commands/sign.mjs +0 -21
  372. package/dist/cli/commands/signer.mjs +0 -1
  373. package/dist/cli/commands/swap.mjs +0 -36
  374. package/dist/cli/commands/upgrade.mjs +0 -2
  375. package/dist/cli/commands/vault.mjs +0 -1
  376. package/dist/cli/commands/version.mjs +0 -2
  377. package/dist/data/desk-data.mjs +0 -55
  378. package/dist/data/names.mjs +0 -2
  379. package/dist/data/providers/farming.mjs +0 -2
  380. package/dist/equities/index.mjs +0 -1
  381. package/dist/index.mjs +0 -60
  382. package/dist/nft-gas-war-guard.mjs +0 -1
  383. package/dist/onboarding/harness-configs.mjs +0 -4
  384. package/dist/portfolio-risk.mjs +0 -1
  385. package/dist/prepare-envelope.mjs +0 -1
  386. package/dist/public-api/agent-grants.mjs +0 -3
  387. package/dist/public-control/policy-schema.mjs +0 -1
  388. package/dist/router/index.mjs +0 -2
  389. package/dist/scanner/index.mjs +0 -4
  390. package/dist/signals/index.mjs +0 -1
  391. package/dist/watch-preferences.mjs +0 -1
  392. /package/{dist/assets/profiles → profiles}/_template/SOUL.md +0 -0
  393. /package/{dist/assets/profiles → profiles}/_template/profile.json +0 -0
  394. /package/{dist/assets/profiles → profiles}/bitcoin-agent/SOUL.md +0 -0
  395. /package/{dist/assets/profiles → profiles}/bitcoin-agent/profile.json +0 -0
  396. /package/{dist/assets/profiles → profiles}/hyperliquid-agent/SOUL.md +0 -0
  397. /package/{dist/assets/profiles → profiles}/hyperliquid-agent/profile.json +0 -0
  398. /package/{dist/assets/profiles → profiles}/oracle/profile.json +0 -0
  399. /package/{dist/assets/profiles → profiles}/polymarket-agent/SOUL.md +0 -0
  400. /package/{dist/assets/profiles → profiles}/polymarket-agent/profile.json +0 -0
  401. /package/{dist/assets/profiles → profiles}/profile.schema.json +0 -0
  402. /package/{dist/assets/profiles → profiles}/protocol-builder/SOUL.md +0 -0
  403. /package/{dist/assets/profiles → profiles}/protocol-builder/profile.json +0 -0
  404. /package/{dist/assets/profiles → profiles}/robinhood-agent/SOUL.md +0 -0
  405. /package/{dist/assets/profiles → profiles}/robinhood-agent/profile.json +0 -0
  406. /package/{dist/assets/profiles → profiles}/solana-agent/SOUL.md +0 -0
  407. /package/{dist/assets/profiles → profiles}/solana-agent/profile.json +0 -0
  408. /package/{dist/assets/profiles → profiles}/stable-agent/SOUL.md +0 -0
  409. /package/{dist/assets/profiles → profiles}/stable-agent/profile.json +0 -0
  410. /package/{dist/assets/skills → skills}/balance/SKILL.md +0 -0
  411. /package/{dist/assets/skills → skills}/bitcoin-l1.md +0 -0
  412. /package/{dist/assets/skills → skills}/chain-defi-ecosystem-profiling.md +0 -0
  413. /package/{dist/assets/skills → skills}/evm-contract-research.md +0 -0
  414. /package/{dist/assets/skills → skills}/hyperliquid.md +0 -0
  415. /package/{dist/assets/skills → skills}/multichain-exec-desk.md +0 -0
  416. /package/{dist/assets/skills → skills}/oracle-action-semantics/SKILL.md +0 -0
  417. /package/{dist/assets/skills → skills}/oracle-best-execution/SKILL.md +0 -0
  418. /package/{dist/assets/skills → skills}/oracle-best-execution.md +0 -0
  419. /package/{dist/assets/skills → skills}/oracle-bitcoin/SKILL.md +0 -0
  420. /package/{dist/assets/skills → skills}/oracle-chain-graphs-telegram-cards/SKILL.md +0 -0
  421. /package/{dist/assets/skills → skills}/oracle-chat/SKILL.md +0 -0
  422. /package/{dist/assets/skills → skills}/oracle-chat/chain.SKILL.md +0 -0
  423. /package/{dist/assets/skills → skills}/oracle-chat/setup.SKILL.md +0 -0
  424. /package/{dist/assets/skills → skills}/oracle-circuit-breaker/SKILL.md +0 -0
  425. /package/{dist/assets/skills → skills}/oracle-contract-research/SKILL.md +0 -0
  426. /package/{dist/assets/skills → skills}/oracle-desk/SKILL.md +0 -0
  427. /package/{dist/assets/skills → skills}/oracle-desk.md +0 -0
  428. /package/{dist/assets/skills → skills}/oracle-dex-launch/SKILL.md +0 -0
  429. /package/{dist/assets/skills → skills}/oracle-equities/SKILL.md +0 -0
  430. /package/{dist/assets/skills → skills}/oracle-grants/SKILL.md +0 -0
  431. /package/{dist/assets/skills → skills}/oracle-hypercore-staking/SKILL.md +0 -0
  432. /package/{dist/assets/skills → skills}/oracle-hyperliquid/SKILL.md +0 -0
  433. /package/{dist/assets/skills → skills}/oracle-meme-token-sniper/SKILL.md +0 -0
  434. /package/{dist/assets/skills → skills}/oracle-multichain-nft-launch/SKILL.md +0 -0
  435. /package/{dist/assets/skills → skills}/oracle-multichain-token-launch/SKILL.md +0 -0
  436. /package/{dist/assets/skills → skills}/oracle-nft-gacha-launch/SKILL.md +0 -0
  437. /package/{dist/assets/skills → skills}/oracle-nft-mint-gas-war/SKILL.md +0 -0
  438. /package/{dist/assets/skills → skills}/oracle-polymarket/SKILL.md +0 -0
  439. /package/{dist/assets/skills → skills}/oracle-protocol-builder/SKILL.md +0 -0
  440. /package/{dist/assets/skills → skills}/oracle-protocol-security/SKILL.md +0 -0
  441. /package/{dist/assets/skills → skills}/oracle-public-product/SKILL.md +0 -0
  442. /package/{dist/assets/skills → skills}/oracle-receipts/SKILL.md +0 -0
  443. /package/{dist/assets/skills → skills}/oracle-receipts.md +0 -0
  444. /package/{dist/assets/skills → skills}/oracle-rfq-tokenized-assets/SKILL.md +0 -0
  445. /package/{dist/assets/skills → skills}/oracle-smart-wallet-scanner/SKILL.md +0 -0
  446. /package/{dist/assets/skills → skills}/oracle-solana/SKILL.md +0 -0
  447. /package/{dist/assets/skills → skills}/oracle-solana-nft/SKILL.md +0 -0
  448. /package/{dist/assets/skills → skills}/oracle-token-research/SKILL.md +0 -0
  449. /package/{dist/assets/skills → skills}/solana.md +0 -0
@@ -3,238 +3,49 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>ORACLE / download</title>
6
+ <title>Download Oracle</title>
7
+ <meta name="description" content="Public Oracle CLI and desktop beta downloads for Linux, macOS, and Windows." />
8
+ <meta name="robots" content="index,follow" />
9
+ <meta name="theme-color" content="#0B1018" />
7
10
  <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
8
- <meta name="description" content="Install the Oracle CLI. Desktop builds are in beta." />
9
- <link rel="preconnect" href="https://fonts.googleapis.com">
10
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600&family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
11
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
12
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
13
+ <link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;1,400&family=IBM+Plex+Mono:wght@400;500;600&family=Outfit:wght@300;400;500;600&display=swap" rel="stylesheet" />
12
14
  <style>
13
- :root{
14
- --bg:#0B1018; --ink:#E8F0F7; --dim:#94A7BC; --line:rgba(184,240,255,.14);
15
- --line-2:rgba(184,240,255,.22); --ice:#B8F0FF; --blue2:#6FA8FF;
16
- --mono:"JetBrains Mono",ui-monospace,monospace;
17
- --sans:"Instrument Sans",system-ui,sans-serif;
18
- --serif:"Instrument Serif",Georgia,serif;
19
- --ease:cubic-bezier(.22,1,.36,1); --max:1100px; --pad:24px;
20
- }
21
- *{box-sizing:border-box}
22
- html{scroll-behavior:smooth}
23
- body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);
24
- -webkit-font-smoothing:antialiased;line-height:1.55;overflow-x:hidden}
25
- a{color:inherit}
26
- .wrap{max-width:var(--max);margin:0 auto;padding:0 var(--pad);text-align:center}
27
- .wrap section{margin-left:auto;margin-right:auto}
28
- .install{margin-left:auto;margin-right:auto}
29
- .cmd{justify-content:center}
30
- .wrap ul,.wrap ol{display:inline-block;text-align:left}
31
-
32
- .nav{position:fixed;top:0;left:0;right:0;z-index:50;backdrop-filter:blur(14px);
33
- background:color-mix(in oklab,var(--bg) 82%,transparent);border-bottom:1px solid var(--line)}
34
- .nav-in{max-width:var(--max);margin:0 auto;padding:14px var(--pad);
35
- display:flex;align-items:center;justify-content:space-between}
36
- .brand{font-family:var(--serif);font-size:22px;letter-spacing:.02em;text-decoration:none;display:inline-flex;align-items:center;gap:10px}
37
- .orbital{width:26px;height:26px;display:inline-block;flex:0 0 auto}
38
- .orbital svg{width:100%;height:100%;overflow:visible}
39
- .orbital .ring{fill:none;stroke:currentColor;stroke-width:2.2;opacity:.55}
40
- .orbital .ring.r1{animation:orbspin 14s linear infinite;transform-origin:50% 50%}
41
- .orbital .ring.r2{animation:orbspin 19s linear infinite reverse;transform-origin:50% 50%}
42
- .orbital .halo{fill:currentColor;opacity:.16}
43
- .orbital .core{fill:currentColor;opacity:.92}
44
- @keyframes orbspin{to{transform:rotate(360deg)}}
45
- @media (prefers-reduced-motion:reduce){.orbital .ring{animation:none}}
46
- .nav a.back{font-family:var(--mono);font-size:11px;letter-spacing:.16em;
47
- text-transform:uppercase;color:var(--dim);text-decoration:none;transition:color .4s var(--ease)}
48
- .nav a.back:hover{color:var(--ice)}
49
-
50
- header{padding:150px 0 56px}
51
- .eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;
52
- color:var(--blue2);margin:0 0 18px}
53
- h1{font-family:var(--serif);font-weight:400;font-size:clamp(38px,6.5vw,72px);
54
- line-height:1.02;letter-spacing:-.015em;margin:0 0 20px}
55
- h1 em{font-style:italic;color:var(--ice)}
56
- .lede{max-width:60ch;color:var(--dim);font-size:17px;margin:0 auto}
57
-
58
- section{padding:0 0 64px}
59
- h2{font-family:var(--serif);font-weight:400;font-size:clamp(24px,3.4vw,34px);
60
- letter-spacing:-.01em;margin:0 0 8px}
61
- .sub{color:var(--dim);font-size:15px;margin:0 auto 26px;max-width:62ch}
62
-
63
- .install{border:1px solid var(--line-2);border-radius:14px;background:#05080D;
64
- padding:26px;position:relative;overflow:hidden}
65
- .install::after{content:"";position:absolute;inset:0;pointer-events:none;
66
- background:linear-gradient(130deg,rgba(184,240,255,.08),transparent 46%)}
67
- .cmd{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
68
- .cmd code{font-family:var(--mono);font-size:15px;color:var(--ice);
69
- background:rgba(184,240,255,.07);border:1px solid var(--line);
70
- padding:12px 16px;border-radius:9px;flex:1;min-width:260px}
71
- .copy{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
72
- background:transparent;color:var(--ink);border:1px solid var(--line-2);
73
- padding:12px 18px;border-radius:9px;cursor:pointer;transition:all .4s var(--ease)}
74
- .copy:hover{border-color:var(--ice);color:var(--ice)}
75
- .copy.done{border-color:var(--ice);color:var(--ice)}
76
- .ver{font-family:var(--mono);font-size:11px;color:var(--dim);
77
- letter-spacing:.1em;margin-top:16px;display:flex;gap:18px;flex-wrap:wrap}
78
- .ver b{color:var(--ink);font-weight:500}
79
-
80
- .os-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-top:14px}
81
- .os{border:1px solid var(--line);border-radius:12px;padding:18px;background:rgba(255,255,255,.012)}
82
- .os h3{font-family:var(--sans);font-size:14px;font-weight:600;margin:0 0 6px;letter-spacing:.01em}
83
- .os p{margin:0;color:var(--dim);font-size:13px}
84
- .os .tag{display:inline-block;margin-top:12px;font-family:var(--mono);font-size:10px;
85
- letter-spacing:.14em;text-transform:uppercase;padding:5px 10px;border-radius:999px;
86
- border:1px solid var(--line-2);color:var(--dim)}
87
- .os .tag.ready{color:var(--ice);border-color:color-mix(in oklab,var(--ice) 40%,transparent)}
88
-
89
- .note{border:1px solid var(--line);border-left:2px solid var(--blue2);border-radius:10px;
90
- padding:18px 20px;background:rgba(111,168,255,.05);color:var(--dim);font-size:14px}
91
- .note b{color:var(--ink);font-weight:600}
92
- .note code{font-family:var(--mono);font-size:13px;color:var(--ice)}
93
-
94
- footer{border-top:1px solid var(--line);padding:30px 0 60px;color:var(--dim);font-size:13px}
95
- footer .tag{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase}
96
-
97
- @media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}
98
- html{scroll-behavior:auto}}
99
- @media (max-width:640px){header{padding:120px 0 40px}.cmd code{min-width:100%}}
100
- table.dl{width:100%;border-collapse:collapse;margin:16px 0 0;font-size:14px}
101
- table.dl th{text-align:left;font-weight:600;padding:8px 10px;border-bottom:1px solid rgba(255,255,255,.14);color:#9fb2c9}
102
- table.dl td{padding:8px 10px;border-bottom:1px solid rgba(255,255,255,.07);vertical-align:top}
103
- table.dl code{font-size:12px;overflow-wrap:anywhere}
104
- .arch{font-size:11px;color:#7f93aa;letter-spacing:.08em}
15
+ :root{--bg:#0b1018;--panel:#111925;--ice:#f4f9fe;--blue:#7cc4ff;--blue2:#a7d8ff;--muted:#9fb8d2;--line:rgba(124,196,255,.16);--line2:rgba(124,196,255,.3);--display:"Cormorant Garamond",Georgia,serif;--sans:"Outfit",system-ui,sans-serif;--mono:"IBM Plex Mono",ui-monospace,monospace}
16
+ *{box-sizing:border-box;margin:0;padding:0}html{background:var(--bg);color:var(--ice);scroll-behavior:smooth;-webkit-font-smoothing:antialiased}body{min-height:100vh;font-family:var(--sans);background:radial-gradient(70% 45% at 50% 0,rgba(124,196,255,.11),transparent 65%),var(--bg)}a{color:inherit;text-decoration:none}button{font:inherit}
17
+ .nav{position:sticky;top:0;z-index:10;border-bottom:1px solid var(--line);background:rgba(11,16,24,.88);backdrop-filter:blur(18px)}.nav-inner,.wrap{width:min(1040px,calc(100% - 36px));margin:auto}.nav-inner{height:72px;display:flex;align-items:center;justify-content:space-between}.brand{display:flex;align-items:center;gap:11px;font-family:var(--display);font-size:27px}.mark{width:25px;height:25px;border:1px solid var(--blue);border-radius:50%;position:relative;box-shadow:0 0 24px rgba(124,196,255,.35)}.mark:before,.mark:after{content:"";position:absolute;inset:5px -4px;border:1px solid rgba(124,196,255,.55);border-radius:50%;transform:rotate(58deg)}.mark:after{transform:rotate(-58deg)}.back{font:500 10px var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
18
+ .wrap{padding:clamp(54px,8vw,96px) 0}.eyebrow{font:600 10px var(--mono);letter-spacing:.24em;text-transform:uppercase;color:var(--blue);margin-bottom:15px}h1{font:400 clamp(54px,8vw,92px)/.92 var(--display);letter-spacing:-.04em;max-width:780px}h1 em{color:var(--blue2);font-weight:400}.lede{max-width:730px;margin-top:24px;color:var(--muted);font-size:18px;line-height:1.65}
19
+ .policy{margin-top:44px;border:1px solid var(--line2);border-radius:22px;padding:clamp(24px,4vw,38px);background:linear-gradient(155deg,rgba(124,196,255,.085),rgba(17,25,37,.72));box-shadow:0 28px 80px rgba(0,0,0,.24)}.policy h2,section h2{font:400 clamp(30px,4vw,46px)/1 var(--display)}.policy p{max-width:760px;color:var(--muted);line-height:1.65;margin-top:12px}.policy b{color:var(--ice)}
20
+ section{padding-top:72px;scroll-margin-top:90px}.sub{color:var(--muted);line-height:1.65;margin-top:13px;max-width:760px}.install{margin-top:24px;border:1px solid var(--line);border-radius:16px;overflow:hidden;background:var(--panel)}.cmd{display:flex;align-items:center;gap:14px;padding:18px 20px}.cmd code{min-width:0;overflow:auto;white-space:nowrap;font:500 12px var(--mono);color:var(--blue2);flex:1}.copy{border:1px solid var(--line2);border-radius:999px;background:none;color:var(--ice);padding:8px 13px;font:600 10px var(--mono);letter-spacing:.1em;text-transform:uppercase;cursor:pointer}.meta{display:flex;flex-wrap:wrap;gap:10px 22px;border-top:1px solid var(--line);padding:13px 20px;font:500 10px var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
21
+ .artifacts{margin-top:24px;border:1px solid var(--line);border-radius:16px;overflow:hidden;background:var(--panel)}.artifact{display:grid;grid-template-columns:minmax(150px,.75fr) minmax(180px,.9fr) minmax(220px,1.4fr) auto;gap:18px;align-items:center;padding:18px 20px;border-bottom:1px solid var(--line)}.artifact:last-child{border-bottom:0}.artifact h3{font:500 16px var(--sans)}.artifact small,.artifact .build{display:block;margin-top:5px;color:var(--muted);font:10px/1.5 var(--mono)}.hash{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--blue2);font:10px var(--mono)}.dl-btn{border:1px solid var(--blue);border-radius:999px;padding:9px 13px;font:600 10px var(--mono);letter-spacing:.08em;text-transform:uppercase;color:#071018;background:var(--blue);white-space:nowrap}.dl-btn[aria-disabled="true"]{opacity:.45;pointer-events:none}.platform-note{margin-top:18px;color:var(--muted);font-size:14px;line-height:1.7}.checksum{color:var(--blue2);text-decoration:underline;text-underline-offset:4px}footer{border-top:1px solid var(--line);padding:26px 0 46px;color:var(--muted);font:10px var(--mono);letter-spacing:.12em;text-transform:uppercase}
22
+ @media(max-width:760px){.artifact{grid-template-columns:1fr auto}.artifact .artifact-meta,.hash{grid-column:1/-1}.cmd{align-items:flex-start;flex-direction:column}.copy{align-self:flex-end}.wrap{padding-top:48px}}
105
23
  </style>
106
24
  </head>
107
25
  <body>
108
-
109
- <nav class="nav">
110
- <div class="nav-in">
111
- <a class="brand" href="/">
112
- <span class="orbital" aria-hidden="true">
113
- <svg viewBox="0 0 100 100">
114
- <g class="ring r1"><ellipse cx="50" cy="50" rx="45" ry="17"/></g>
115
- <g class="ring r2"><ellipse cx="50" cy="50" rx="45" ry="17" transform="rotate(64 50 50)"/></g>
116
- <circle class="halo" cx="50" cy="50" r="13"/>
117
- <circle class="core" cx="50" cy="50" r="11"/>
118
- </svg>
119
- </span>
120
- oracle</a>
121
- <a class="back" href="/">← back to site</a>
122
- </div>
123
- </nav>
124
-
26
+ <nav class="nav"><div class="nav-inner"><a class="brand" href="/"><span class="mark" aria-hidden="true"></span>oracle</a><a class="back" href="/">Back to site</a></div></nav>
125
27
  <main class="wrap">
126
- <header>
127
- <p class="eyebrow">Download</p>
128
- <h1>Install <em>Oracle.</em></h1>
129
- <p class="lede">The CLI is the full product and it runs on macOS, Windows and Linux today.
130
- Linux, macOS and Windows desktop builds are all live. Locals Only holders get 0% fees.</p>
131
- </header>
132
-
133
- <section>
134
- <h2>Oracle CLI</h2>
135
- <p class="sub">One command. Node 20 or newer. The CLI recognises your agent wallet and applies 0% fees automatically for Locals Only holders. Keys and signing never live in the public
136
- package.</p>
137
- <div class="install">
138
- <div class="cmd">
139
- <code id="cmd">curl -fL -o oracle.tgz "$ORACLE_GATE_LINK" &amp;&amp; npm i -g ./oracle.tgz</code>
140
- <button class="copy" id="copy" type="button">Copy</button>
141
- </div>
142
- <div class="ver">
143
- <span>latest <b id="ver">0.12.0</b></span>
144
- <span>registry <b>npmjs.com</b></span>
145
- <span>requires <b>node ≥ 20</b></span>
146
- </div>
147
- </div>
148
-
149
- <div class="os-grid">
150
- <div class="os">
151
- <h3>macOS</h3>
152
- <p>Apple silicon and Intel. Runs in any terminal.</p>
153
- <span class="tag ready">CLI ready</span>
154
- </div>
155
- <div class="os">
156
- <h3>Linux</h3>
157
- <p>Any distro with Node 20+. Primary development target.</p>
158
- <span class="tag ready">CLI ready</span>
159
- </div>
160
- <div class="os">
161
- <h3>Windows</h3>
162
- <p>PowerShell or WSL. Same command.</p>
163
- <span class="tag ready">CLI ready</span>
164
- </div>
165
- </div>
166
- </section>
167
-
168
- <section>
169
- <h2>Desktop app</h2>
170
- <p class="sub">An Electron shell around the same runtime.</p>
171
- <div class="note">
172
- <b>Beta, ready to use.</b> Desktop builds are live for everyone. Locals Only holders get 0% fees.
173
- Pull the AppImage, DMG, or installer — no gate, no link. Verify the checksum, then run it.
174
- The desktop app runs the same runtime as the CLI, no separate signer needed.
175
- </div>
176
- <table class="dl">
177
- <tr><th>Build</th><th>Status</th><th>SHA-256</th></tr>
178
- <tr><td>Linux <code>.AppImage</code></td><td>Live &middot; 123 MB</td>
179
- <td><code>64cef5676ca19fbd01ab58e27a1f98eb5b5a6678e3ba51a095fd5685be70c814</code></td></tr>
180
- <tr><td>macOS <code>.dmg</code> <span class="arch">arm64</span></td><td>Live &middot; signed + notarized &middot; 118 MB</td>
181
- <td><code>6d45a0c4063fa1071217e94e2871916d161fa2dbf4512d127262203e17902c57</code></td></tr>
182
- <tr><td>Windows <code>.exe</code> <span class="arch">x64</span></td><td>Live &middot; 99 MB</td>
183
- <td><code>cb84c8f7c2da7743c17fe022b001da7701f13ae48053f760214daf62972bfbbf</code></td></tr>
184
- </table>
185
- <p class="sub"><b>Windows SmartScreen will warn on first run.</b> The installer carries
186
- electron-builder's generated signature, not a CA-issued code-signing certificate, so
187
- Windows shows "unknown publisher": choose More info, then Run anyway. Verify the checksum
188
- below first.</p>
189
- <p class="sub"><b>The macOS build is signed and notarized</b> with Developer ID
190
- <code>5BV985Z9LJ</code>, and the ticket is stapled, so it opens with no Gatekeeper prompt.
191
- Verified by mounting the dmg and asking Gatekeeper directly:
192
- <code>Oracle.app: accepted &middot; source=Notarized Developer ID</code>.</p>
193
- <p class="sub">Checksums are printed so you can verify what the gate served you:
194
- <code>sha256sum Oracle-0.1.0.AppImage</code>. The desktop shell holds no keys and
195
- broadcasts nothing; it prepares transactions your wallet signs.</p>
196
- </section>
197
-
198
- <section>
199
- <h2>After install</h2>
200
- <p class="sub">Run <code style="font-family:var(--mono);color:var(--ice)">oracle</code> to open the shell.
201
- Pin a surface with <code style="font-family:var(--mono);color:var(--ice)">/chain hyperliquid</code>,
202
- switch models with <code style="font-family:var(--mono);color:var(--ice)">/model</code>, then ask naturally.
203
- Oracle reads state, prices routes and prepares transactions. Your wallet signs them.</p>
204
- </section>
28
+ <header><p class="eyebrow">Public release</p><h1>Install Oracle.<br><em>Your wallet signs.</em></h1><p class="lede">The CLI, desktop beta, source, research tools, and unsigned transaction preparation are public to everyone. No wallet connection or NFT is required to download or run Oracle.</p></header>
29
+ <aside class="policy"><h2>Locals Only means 0% Oracle fees</h2><p>A Locals Only NFT waives the <b>Oracle integrator fee</b>. It does not unlock the product, arm execution, waive provider or network costs, or change the keyless prepare-only custody boundary.</p></aside>
30
+ <section id="cli"><p class="eyebrow">Oracle CLI</p><h2>Install from npm</h2><p class="sub">Requires Node 20.19 or newer. npm <code>latest</code> contains the full public runtime.</p><div class="install"><div class="cmd"><code id="cmd">npm i -g @oracle-agent/oracle</code><button class="copy" id="copy" type="button">Copy</button></div><div class="meta"><span>public npm package</span><span>keyless</span><span>prepare-only</span></div></div></section>
31
+ <section id="desktop"><p class="eyebrow">Desktop beta · 0.2.0</p><h2>Native installers</h2><p class="sub">Each installer bundles the same public runtime. Download directly, then verify it against the published SHA-256 manifest.</p><div class="artifacts">
32
+ <div class="artifact" data-artifact="Oracle-0.2.0.AppImage"><div><h3>Linux</h3><small>AppImage · x64</small></div><div class="artifact-meta"><span class="build">Oracle 0.2.0 beta</span></div><code class="hash" data-hash>checksum loading</code><a class="dl-btn" href="/downloads/artifacts/Oracle-0.2.0.AppImage" download>Download</a></div>
33
+ <div class="artifact" data-artifact="Oracle-0.2.0-arm64.dmg"><div><h3>macOS</h3><small>DMG · Apple silicon</small></div><div class="artifact-meta"><span class="build">Oracle 0.2.0 beta</span></div><code class="hash" data-hash>checksum loading</code><a class="dl-btn" href="/downloads/artifacts/Oracle-0.2.0-arm64.dmg" download>Download</a></div>
34
+ <div class="artifact" data-artifact="Oracle-Setup-0.2.0.exe"><div><h3>Windows</h3><small>NSIS installer · x64</small></div><div class="artifact-meta"><span class="build">Oracle 0.2.0 beta</span></div><code class="hash" data-hash>checksum loading</code><a class="dl-btn" href="/downloads/artifacts/Oracle-Setup-0.2.0.exe" download>Download</a></div>
35
+ </div><p class="platform-note">Checksums: <a class="checksum" href="/downloads/artifacts/SHA256SUMS.txt">SHA256SUMS.txt</a>. Beta installers may trigger macOS Gatekeeper or Windows SmartScreen when a build is not notarized or CA-signed. Oracle never asks for a private key, seed phrase, or wallet approval.</p></section>
205
36
  </main>
206
-
207
- <footer class="wrap">
208
- <span class="tag">the future is agentic / by demi</span>
209
- </footer>
210
-
37
+ <footer><div class="nav-inner"><span>oracle · locals only labs</span><span>public / self-custody / prepare-only</span></div></footer>
211
38
  <script>
212
- (function(){
213
- var btn=document.getElementById("copy");
214
- var cmd=document.getElementById("cmd");
215
- if(!btn||!cmd)return;
216
- btn.addEventListener("click",function(){
217
- var text=cmd.textContent.trim();
39
+ document.getElementById("copy").addEventListener("click",async function(){try{await navigator.clipboard.writeText(document.getElementById("cmd").textContent.trim());this.textContent="Copied";var button=this;setTimeout(function(){button.textContent="Copy"},1400)}catch(_){this.textContent="Select command"}});
40
+ (async function(){
41
+ var rows=Array.from(document.querySelectorAll("[data-artifact]"));
42
+ function unavailable(row){row.querySelector("[data-hash]").textContent="checksum unavailable";row.querySelector(".dl-btn").setAttribute("aria-disabled","true")}
218
43
  try{
219
- if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(text);}
220
- else{
221
- var ta=document.createElement("textarea");ta.value=text;ta.setAttribute("readonly","");
222
- ta.style.position="fixed";ta.style.opacity="0";document.body.appendChild(ta);
223
- ta.select();document.execCommand("copy");document.body.removeChild(ta);
224
- }
225
- }catch(e){}
226
- // Feedback is unconditional: a button that looks dead is worse than one that
227
- // confirms while the browser blocked the write. The command stays selectable.
228
- btn.textContent="Copied";btn.classList.add("done");
229
- setTimeout(function(){btn.textContent="Copy";btn.classList.remove("done");},1600);
230
- });
231
- // Click the command to select it -- always works, no permissions involved.
232
- cmd.style.cursor="pointer";
233
- cmd.title="Click to select";
234
- cmd.addEventListener("click",function(){
235
- var r=document.createRange();r.selectNodeContents(cmd);
236
- var sel=window.getSelection();sel.removeAllRanges();sel.addRange(r);
237
- });
44
+ var response=await fetch("/downloads/artifacts/SHA256SUMS.txt",{cache:"no-store"});
45
+ if(!response.ok)throw new Error("manifest unavailable");
46
+ var sums=new Map((await response.text()).trim().split(/\r?\n/).map(function(line){var match=line.match(/^([a-f0-9]{64})\s+\*?(.+)$/i);return match?[match[2],match[1].toLowerCase()]:null}).filter(Boolean));
47
+ rows.forEach(function(row){var sum=sums.get(row.dataset.artifact);if(!sum){unavailable(row);return}row.querySelector("[data-hash]").textContent=sum});
48
+ }catch(_){rows.forEach(unavailable)}
238
49
  })();
239
50
  </script>
240
51
  </body>
@@ -8,7 +8,7 @@
8
8
  <link rel="shortcut icon" href="/favicon.ico">
9
9
  <meta name="description" content="ORACLE is a self-custodial agent control plane for wallets, markets, and protocol routes.">
10
10
  <meta name="theme-color" content="#0B1018" />
11
- <meta name="robots" content="noindex,nofollow" />
11
+ <meta name="robots" content="index,follow" />
12
12
  <link rel="preconnect" href="https://fonts.googleapis.com" />
13
13
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
14
14
  <link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&family=IBM+Plex+Mono:wght@400;500;600&family=Outfit:wght@300;400;500;600;700&family=UnifrakturCook:wght@700&display=swap" rel="stylesheet" />
@@ -1173,10 +1173,10 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
1173
1173
  <h1 class="home-title rv">Trade every chain<br>from <em>one</em> agent</h1>
1174
1174
  <p class="hero-sub rv">Hyperliquid, EVM, Bitcoin, Solana, Stable and Robinhood Chain in a single control plane. Oracle reads state, prices routes and prepares the transaction. Your wallet signs it.</p>
1175
1175
  <div class="home-actions">
1176
- <a class="enter-cta primary" href="#cli">Download</a>
1176
+ <a class="enter-cta primary" href="/downloads/">Download</a>
1177
1177
  <a class="enter-cta ghost" href="#cli">See the CLI</a>
1178
1178
  </div>
1179
- <p class="hero-note-line">macOS · Windows · Linux &nbsp;/&nbsp; desktop app or holder-gated CLI</p>
1179
+ <p class="hero-note-line">macOS · Windows · Linux &nbsp;/&nbsp; public CLI and desktop beta</p>
1180
1180
  </div>
1181
1181
 
1182
1182
  <figure class="hero-product">
@@ -1489,8 +1489,8 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
1489
1489
  <button class="btn btn-claude" onclick="navigator.clipboard.writeText('oracle mcp install claude-code');var b=this;b.textContent='Copied ✓';setTimeout(function(){b.textContent='Claude'},1500)">Claude</button>
1490
1490
  <button class="btn btn-chatgpt" onclick="navigator.clipboard.writeText('oracle mcp install chatgpt');var b=this;b.textContent='Copied ✓';setTimeout(function(){b.textContent='ChatGPT'},1500)">ChatGPT</button>
1491
1491
  <button class="btn btn-cursor" onclick="navigator.clipboard.writeText('oracle mcp install cursor');var b=this;b.textContent='Copied ✓';setTimeout(function(){b.textContent='Cursor'},1500)">Cursor</button>
1492
- <button class="btn btn-vscode" onclick="navigator.clipboard.writeText('oracle mcp install vscode');var b=this;b.textContent='Copied ✓';setTimeout(function(){b.textContent='VS Code'},1500)">VS Code</button>
1493
- <button class="btn btn-copilot" onclick="navigator.clipboard.writeText('oracle mcp install copilot');var b=this;b.textContent='Copied ✓';setTimeout(function(){b.textContent='Copilot'},1500)">Copilot</button>
1492
+ <button class="btn btn-vscode" onclick="navigator.clipboard.writeText('oracle mcp install claude-desktop');var b=this;b.textContent='Copied ✓';setTimeout(function(){b.textContent='Claude Desktop'},1500)">Claude Desktop</button>
1493
+ <button class="btn btn-copilot" onclick="navigator.clipboard.writeText('oracle mcp install codex');var b=this;b.textContent='Copied ✓';setTimeout(function(){b.textContent='Codex'},1500)">Codex</button>
1494
1494
  </div>
1495
1495
  <p class="cmd-hint">Click copies the install command — paste it in your terminal</p>
1496
1496
  </div>
@@ -1734,7 +1734,7 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
1734
1734
  <section class="section" id="chains">
1735
1735
  <p class="section-label rv">Chains</p>
1736
1736
  <h2 class="section-title rv">Where you can <em>operate.</em></h2>
1737
- <p class="section-lede rv">Every chain reads live. <b>Route</b> means Oracle can also price and prepare a swap there; <b>read only</b> means the venue registry is still empty, so routing fail-closes rather than guessing a router. Any EVM chain can be registered with a chain id and an RPC.</p>
1737
+ <p class="section-lede rv">Every built-in EVM chain exposes the full scanner capability set. <b>Route</b> means Oracle can price and prepare a swap there. Any additional EVM chain can be registered with a chain id and an RPC; unsupported paths fail closed rather than guessing a router.</p>
1738
1738
  <div class="chain-grid" id="chain-grid"></div>
1739
1739
  <div class="hl-surface rv">
1740
1740
  <div class="venues-head"><span>hyperliquid // what oracle actually does</span></div>
@@ -1752,8 +1752,8 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
1752
1752
  <p class="section-label rv">Oracle CLI</p>
1753
1753
  <h2 class="section-title rv">One surface. <em>Every chain.</em></h2>
1754
1754
  <div class="cli-install rv">
1755
- <div class="cli-install-cmd"><code>oracle</code> <span class="cli-install-hint">npm install -g @oracle-agent/oracle</span></div>
1756
- <p class="cli-install-gate"><b>Locals Only</b> Holders get 0% Oracle fees. The CLI recognises your agent wallet and applies the holder rate automatically. The public package never touches keys.</p>
1755
+ <div class="cli-install-cmd"><code>npm i -g @oracle-agent/oracle</code> <span class="cli-install-hint">public npm package · Node 20.19+</span></div>
1756
+ <p class="cli-install-gate"><b>Locals Only</b> holders get 0% Oracle integrator fees. Everyone gets the same public CLI, desktop, source, and prepare-only product access.</p>
1757
1757
  </div>
1758
1758
  <p class="section-lede rv">The real Oracle shell, isolated from desktop chrome. No accounts, no servers. The CLI runs on your machine and reads straight from public RPCs.</p>
1759
1759
  <p class="section-lede rv">Pin the active surface with <code style="color:var(--blue2)">/chain hyperliquid</code>, switch models, ask naturally. Oracle reads, prices, and prepares — you sign.</p>
@@ -1776,7 +1776,7 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
1776
1776
  <img src="assets/desktop-app.jpg" width="1736" height="959" loading="lazy" decoding="async" alt="Oracle desktop app showing the specialist mesh, with Portfolio, Approvals, Prepare, CLI, Farming Methods, Agent Connect, Receipts, Campaigns and Routes panes.">
1777
1777
  <figcaption>Portfolio, approvals, prepare, farming, receipts and routes in one pane.</figcaption>
1778
1778
  </figure>
1779
- <div class="os-dl"><a class="os-link" href="https://github.com/demi-hl/oracle/releases/download/v0.2.0/Oracle-0.2.0-arm64.dmg">macOS</a><a class="os-link" href="https://github.com/demi-hl/oracle/releases/download/v0.2.0/Oracle-0.2.0.AppImage">Linux</a><a class="os-link" href="https://github.com/demi-hl/oracle/releases/download/v0.2.0/Oracle-Setup-0.2.0.exe">Windows</a></div>
1779
+ <div class="os-dl"><a class="os-link" href="/downloads/#desktop">macOS</a><a class="os-link" href="/downloads/#desktop">Linux</a><a class="os-link" href="/downloads/#desktop">Windows</a></div>
1780
1780
  </div>
1781
1781
  </div>
1782
1782
  </section>
@@ -1803,7 +1803,7 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
1803
1803
  <a href="https://hermes-agent.nousresearch.com" target="_blank" rel="noopener noreferrer">Hermes</a>
1804
1804
  </div>
1805
1805
  <div class="foot-links">
1806
- <a href="/oracle-console/">Console</a>
1806
+ <a href="/downloads/">Download</a>
1807
1807
  <a href="https://hermes-agent.nousresearch.com/docs" target="_blank" rel="noopener noreferrer">Docs</a>
1808
1808
  </div>
1809
1809
  </div>
@@ -2254,7 +2254,7 @@ var activeLenis = null;
2254
2254
  }
2255
2255
  splitWords(document);
2256
2256
  if (window.ScrollTrigger) {
2257
- gsap.fromTo("[data-split] .word-mask > span", { yPercent:112, rotate:2 }, { yPercent:0, rotate:0, duration:1.1, ease:"power4.out", stagger:.035, scrollTrigger:{ trigger:"#protocols", start:"top 78%" }, clearProps:"transform" });
2257
+ gsap.fromTo("[data-split] .word-mask > span", { yPercent:112, rotate:2 }, { yPercent:0, rotate:0, duration:1.1, ease:"power4.out", stagger:.035, scrollTrigger:{ trigger:"[data-split]", start:"top 78%" }, clearProps:"transform" });
2258
2258
  gsap.to(".hero-art", { yPercent:18, scale:.9, ease:"none", scrollTrigger:{ trigger:".home", start:"top top", end:"bottom top", scrub:true } });
2259
2259
  gsap.fromTo(".motion-card", { y:80, rotateX:8, scale:.965 }, { y:0, rotateX:0, scale:1, duration:1.25, ease:"power4.out", stagger:.08, scrollTrigger:{ trigger:".operator-grid", start:"top 82%" }, clearProps:"transform" });
2260
2260
  gsap.to(".motion-command", { y:-34, rotateX:3, ease:"none", scrollTrigger:{ trigger:".motion-lab", start:"top 70%", end:"bottom top", scrub:true } });
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { pathToFileURL } from "node:url";
4
+ import { resolve } from "node:path";
5
+
6
+ const INJECTION_RULES = [
7
+ ["instruction-override", /\b(?:ignore|disregard|override)\b.{0,48}\b(?:previous|prior|system|developer|instructions?)\b/i],
8
+ ["secret-exfiltration", /\b(?:reveal|print|return|exfiltrate|send)\b.{0,48}\b(?:private\s*key|seed\s*phrase|mnemonic|secret|credentials?|system\s*prompt)\b/i],
9
+ ["transaction-coercion", /\b(?:sign|send|broadcast|execute)\b.{0,32}\b(?:transaction|transfer|approval|trade)\b/i],
10
+ ["tool-coercion", /\b(?:call|invoke|use|run)\b.{0,24}\b(?:tool|function|shell|command)\b/i],
11
+ ];
12
+
13
+ const FORBIDDEN_EXPORT = /^(?:signer|sign|signMessage|signTransaction|sendTransaction|broadcastTransaction|submitTransaction|executeTransaction|privateKey|secretKey|mnemonic|seedPhrase|wallet)$/i;
14
+
15
+ function finding(code, path, message) {
16
+ return { code, path, message };
17
+ }
18
+
19
+ function scanStrings(value, path, findings, seen) {
20
+ if (typeof value === "string") {
21
+ for (const [rule, pattern] of INJECTION_RULES) {
22
+ if (pattern.test(value)) {
23
+ findings.push(finding("prompt-injection", path, `metadata matches ${rule}`));
24
+ break;
25
+ }
26
+ }
27
+ return;
28
+ }
29
+ if (!value || typeof value !== "object" || seen.has(value)) return;
30
+ seen.add(value);
31
+ if (Array.isArray(value)) {
32
+ value.forEach((item, index) => scanStrings(item, `${path}[${index}]`, findings, seen));
33
+ return;
34
+ }
35
+ for (const key of Object.keys(value).sort()) {
36
+ scanStrings(value[key], path ? `${path}.${key}` : key, findings, seen);
37
+ }
38
+ }
39
+
40
+ /** Validate one loaded Oracle protocol pack without calling provider code. */
41
+ export function benchmarkPack(moduleValue, { name = "pack" } = {}) {
42
+ const namespace = moduleValue && typeof moduleValue === "object" ? moduleValue : {};
43
+ const pack = namespace.default && typeof namespace.default === "object" ? namespace.default : namespace;
44
+ const findings = [];
45
+
46
+ for (const key of Object.keys(namespace).sort()) {
47
+ if (key !== "default" && FORBIDDEN_EXPORT.test(key)) {
48
+ findings.push(finding("forbidden-signer-export", `exports.${key}`, `pack exports custody capability ${key}`));
49
+ }
50
+ }
51
+ for (const key of Object.keys(pack).sort()) {
52
+ if (FORBIDDEN_EXPORT.test(key)) {
53
+ findings.push(finding("forbidden-signer-export", `pack.${key}`, `pack exports custody capability ${key}`));
54
+ }
55
+ }
56
+
57
+ if (!pack.provider || typeof pack.provider !== "object") {
58
+ findings.push(finding("missing-provider", "pack.provider", "provider metadata is required"));
59
+ }
60
+ if (typeof pack.prepare !== "function") {
61
+ findings.push(finding("missing-prepare", "pack.prepare", "prepare must be a function"));
62
+ }
63
+ if (typeof pack.decode !== "function") {
64
+ findings.push(finding("missing-decoder", "pack.decode", "decode must be a function"));
65
+ }
66
+ if (!(Array.isArray(pack.riskRules) || typeof pack.riskRules === "function")) {
67
+ findings.push(finding("missing-risk-rules", "pack.riskRules", "riskRules must be an array or function"));
68
+ }
69
+ if (!pack.tests || typeof pack.tests !== "object" || Array.isArray(pack.tests) || Object.keys(pack.tests).length === 0) {
70
+ findings.push(finding("missing-tests", "pack.tests", "non-empty tests metadata is required"));
71
+ }
72
+
73
+ // Metadata is untrusted even when nested below token/NFT records. Scan data only;
74
+ // functions are deliberately never invoked by this local harness.
75
+ scanStrings(pack.metadata, "pack.metadata", findings, new Set());
76
+ scanStrings(pack.provider, "pack.provider", findings, new Set());
77
+
78
+ findings.sort((a, b) => `${a.code}\0${a.path}\0${a.message}`.localeCompare(`${b.code}\0${b.path}\0${b.message}`));
79
+ return { name, ok: findings.length === 0, findings };
80
+ }
81
+
82
+ /** Run a stable summary over already-loaded fixture/module records. */
83
+ export function runAdversarialBenchmark(entries) {
84
+ const results = entries
85
+ .map((entry, index) => benchmarkPack(entry.module ?? entry, { name: entry.name ?? `pack-${index + 1}` }))
86
+ .sort((a, b) => a.name.localeCompare(b.name));
87
+ return {
88
+ ok: results.every((result) => result.ok),
89
+ packs: results.length,
90
+ passed: results.filter((result) => result.ok).length,
91
+ failed: results.filter((result) => !result.ok).length,
92
+ findings: results.reduce((count, result) => count + result.findings.length, 0),
93
+ results,
94
+ };
95
+ }
96
+
97
+ async function main(paths) {
98
+ if (paths.length === 0) throw new Error("usage: node scripts/adversarial-bench.mjs <pack.mjs> [...]");
99
+ const entries = [];
100
+ for (const input of paths) {
101
+ const absolute = resolve(input);
102
+ entries.push({ name: input, module: await import(pathToFileURL(absolute).href) });
103
+ }
104
+ const summary = runAdversarialBenchmark(entries);
105
+ process.stdout.write(`${JSON.stringify(summary, null, 2)}\n`);
106
+ if (!summary.ok) process.exitCode = 1;
107
+ }
108
+
109
+ if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
110
+ main(process.argv.slice(2)).catch((error) => {
111
+ process.stdout.write(`${JSON.stringify({ ok: false, error: String(error.message || error) }, null, 2)}\n`);
112
+ process.exitCode = 2;
113
+ });
114
+ }
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env node
2
+ // Bundle the package for publish so `src/` never ships.
3
+ //
4
+ // Every public entry point (package.json "exports" + "bin") becomes its own
5
+ // bundled file under dist/. Runtime dependencies stay external — we are hiding
6
+ // OUR source, not vendoring ethers into the tarball.
7
+ //
8
+ // This is obfuscation, not a security boundary. It raises the cost of lifting
9
+ // the provider/router/scanner work from "npm pack and read it" to "reverse a
10
+ // minified bundle". The real boundary is that the signer never ships at all.
11
+
12
+ import { build } from "esbuild";
13
+ import { cpSync, readdirSync, readFileSync, writeFileSync, rmSync, mkdirSync, existsSync } from "node:fs";
14
+ import { dirname, join, resolve } from "node:path";
15
+ import { fileURLToPath } from "node:url";
16
+
17
+ const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
18
+ const DIST = join(ROOT, "dist");
19
+ const pkg = JSON.parse(readFileSync(join(ROOT, "package.json"), "utf8"));
20
+
21
+ const external = [
22
+ ...Object.keys(pkg.dependencies || {}),
23
+ ...Object.keys(pkg.peerDependencies || {}),
24
+ ];
25
+
26
+ // src-relative entry -> dist-relative output, derived from the real manifest so
27
+ // a new export can never silently ship unbundled.
28
+ const entries = new Map();
29
+ for (const [name, target] of Object.entries(pkg.exports || {})) {
30
+ if (typeof target !== "string" || !target.startsWith("./src/")) continue;
31
+ entries.set(target.slice(2), distPathFor(target, "exports", name));
32
+ }
33
+ for (const [name, target] of Object.entries(pkg.bin || {})) {
34
+ if (typeof target !== "string" || !target.startsWith("./bin/")) continue;
35
+ entries.set(target.slice(2), distPathFor(target, "bin", name));
36
+ }
37
+
38
+ const commandDir = join(ROOT, "src", "cli", "commands");
39
+ for (const file of readdirSync(commandDir).filter((f) => f.endsWith(".mjs")).sort()) {
40
+ entries.set(join("src", "cli", "commands", file), join("cli", "commands", file));
41
+ }
42
+
43
+ function distPathFor(target, kind, name) {
44
+ const rel = target.replace(/^\.\/(src|bin)\//, "");
45
+ return kind === "bin" ? join("bin", rel) : rel;
46
+ }
47
+
48
+ if (existsSync(DIST)) rmSync(DIST, { recursive: true });
49
+ mkdirSync(DIST, { recursive: true });
50
+
51
+ const results = [];
52
+ for (const [entry, outRel] of entries) {
53
+ const outfile = join(DIST, outRel);
54
+ mkdirSync(dirname(outfile), { recursive: true });
55
+ await build({
56
+ entryPoints: [join(ROOT, entry)],
57
+ outfile,
58
+ bundle: true,
59
+ platform: "node",
60
+ target: "node20",
61
+ format: "esm",
62
+ minify: true,
63
+ legalComments: "none",
64
+ external,
65
+ logLevel: "error",
66
+ // The CLI kernel loads user plugin files from disk at runtime; that import
67
+ // is intentionally dynamic and must stay unresolved.
68
+ // Bin entries already carry their own shebang in source — esbuild preserves
69
+ // it, so adding a banner here would emit a second one on line 2 and break
70
+ // the file. Only add it when the source genuinely lacks one.
71
+ banner:
72
+ outRel.startsWith("bin/") && !readFileSync(join(ROOT, entry), "utf8").startsWith("#!")
73
+ ? { js: "#!/usr/bin/env node" }
74
+ : undefined,
75
+ });
76
+ const bytes = readFileSync(outfile).byteLength;
77
+ results.push({ entry, outRel, bytes });
78
+ }
79
+
80
+ // Rewrite the published manifest to point at dist/ and ship no source.
81
+ const out = structuredClone(pkg);
82
+ out.exports = Object.fromEntries(
83
+ Object.entries(pkg.exports || {}).map(([k, v]) =>
84
+ typeof v === "string" && v.startsWith("./src/")
85
+ ? [k, "./dist/" + distPathFor(v, "exports", k)]
86
+ : [k, v],
87
+ ),
88
+ );
89
+ out.bin = Object.fromEntries(
90
+ Object.entries(pkg.bin || {}).map(([k, v]) =>
91
+ typeof v === "string" && v.startsWith("./bin/")
92
+ ? [k, "./dist/" + distPathFor(v, "bin", k)]
93
+ : [k, v],
94
+ ),
95
+ );
96
+ // Ship the bundle and the user-facing assets. Never src/, scripts/, skills/,
97
+ // profiles/, docs/, examples/ — those are internal surface, not runtime need.
98
+ out.files = ["dist/", "public/", "artifacts/", "README.md", "SETUP.md", "LICENSE", "SECURITY.md"];
99
+ delete out.scripts;
100
+ delete out.devDependencies;
101
+
102
+ writeFileSync(join(DIST, "package.publish.json"), JSON.stringify(out, null, 2) + "\n");
103
+
104
+ // Runtime data the bins read from disk. esbuild bundles code, not JSON assets,
105
+ // so `oracle init` shipped without profiles/ and skills/ and crashed on ENOENT.
106
+ // They land under dist/assets/ and src/package-manifest.mjs looks there first.
107
+ const ASSET_DIRS = ["profiles", "skills"];
108
+ for (const name of ASSET_DIRS) {
109
+ const from = join(ROOT, name);
110
+ if (!existsSync(from)) continue;
111
+ cpSync(from, join(DIST, "assets", name), { recursive: true });
112
+ }
113
+
114
+ const total = results.reduce((a, r) => a + r.bytes, 0);
115
+ console.log(`bundled ${results.length} entry points -> dist/ (${(total / 1024).toFixed(0)} KB)`);
116
+ for (const r of results.slice(0, 6)) {
117
+ console.log(` ${r.outRel.padEnd(34)} ${(r.bytes / 1024).toFixed(0)} KB`);
118
+ }
119
+ if (results.length > 6) console.log(` ... ${results.length - 6} more`);