@oracle-agent/oracle 0.12.0 → 0.13.1

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 (124) hide show
  1. package/README.md +31 -4
  2. package/SETUP.md +5 -2
  3. package/artifacts/specialist-packs/oracle-full-crypto.json +3 -0
  4. package/dist/address-book.mjs +2 -2
  5. package/dist/assets/profiles/_template/SOUL.md +54 -0
  6. package/dist/assets/profiles/_template/profile.json +22 -0
  7. package/dist/assets/profiles/bitcoin-agent/SOUL.md +31 -0
  8. package/dist/assets/profiles/bitcoin-agent/profile.json +32 -0
  9. package/dist/assets/profiles/hyperliquid-agent/SOUL.md +34 -0
  10. package/dist/assets/profiles/hyperliquid-agent/profile.json +38 -0
  11. package/dist/assets/profiles/oracle/SOUL.md +134 -0
  12. package/dist/assets/profiles/oracle/profile.json +40 -0
  13. package/dist/assets/profiles/polymarket-agent/SOUL.md +35 -0
  14. package/dist/assets/profiles/polymarket-agent/profile.json +34 -0
  15. package/dist/assets/profiles/profile.schema.json +90 -0
  16. package/dist/assets/profiles/protocol-builder/SOUL.md +57 -0
  17. package/dist/assets/profiles/protocol-builder/profile.json +39 -0
  18. package/dist/assets/profiles/robinhood-agent/SOUL.md +53 -0
  19. package/dist/assets/profiles/robinhood-agent/profile.json +41 -0
  20. package/dist/assets/profiles/solana-agent/SOUL.md +37 -0
  21. package/dist/assets/profiles/solana-agent/profile.json +38 -0
  22. package/dist/assets/profiles/stable-agent/SOUL.md +43 -0
  23. package/dist/assets/profiles/stable-agent/profile.json +38 -0
  24. package/dist/assets/skills/balance/SKILL.md +176 -0
  25. package/dist/assets/skills/bitcoin-l1.md +33 -0
  26. package/dist/assets/skills/chain-defi-ecosystem-profiling.md +27 -0
  27. package/dist/assets/skills/evm-contract-research.md +27 -0
  28. package/dist/assets/skills/hyperliquid.md +26 -0
  29. package/dist/assets/skills/multichain-exec-desk.md +33 -0
  30. package/dist/assets/skills/oracle-action-semantics/SKILL.md +40 -0
  31. package/dist/assets/skills/oracle-best-execution/SKILL.md +127 -0
  32. package/dist/assets/skills/oracle-best-execution.md +27 -0
  33. package/dist/assets/skills/oracle-bitcoin/SKILL.md +53 -0
  34. package/dist/assets/skills/oracle-chain-graphs-telegram-cards/SKILL.md +59 -0
  35. package/dist/assets/skills/oracle-chat/SKILL.md +61 -0
  36. package/dist/assets/skills/oracle-chat/chain.SKILL.md +31 -0
  37. package/dist/assets/skills/oracle-chat/setup.SKILL.md +37 -0
  38. package/dist/assets/skills/oracle-circuit-breaker/SKILL.md +51 -0
  39. package/dist/assets/skills/oracle-contract-research/SKILL.md +55 -0
  40. package/dist/assets/skills/oracle-desk/SKILL.md +58 -0
  41. package/dist/assets/skills/oracle-desk.md +27 -0
  42. package/dist/assets/skills/oracle-dex-launch/SKILL.md +38 -0
  43. package/dist/assets/skills/oracle-equities/SKILL.md +62 -0
  44. package/dist/assets/skills/oracle-grants/SKILL.md +69 -0
  45. package/dist/assets/skills/oracle-hypercore-staking/SKILL.md +57 -0
  46. package/dist/assets/skills/oracle-hyperliquid/SKILL.md +56 -0
  47. package/dist/assets/skills/oracle-meme-token-sniper/SKILL.md +73 -0
  48. package/dist/assets/skills/oracle-multichain-nft-launch/SKILL.md +338 -0
  49. package/dist/assets/skills/oracle-multichain-token-launch/SKILL.md +300 -0
  50. package/dist/assets/skills/oracle-nft-gacha-launch/SKILL.md +48 -0
  51. package/dist/assets/skills/oracle-nft-mint-gas-war/SKILL.md +63 -0
  52. package/dist/assets/skills/oracle-polymarket/SKILL.md +60 -0
  53. package/dist/assets/skills/oracle-protocol-builder/SKILL.md +59 -0
  54. package/dist/assets/skills/oracle-protocol-security/SKILL.md +60 -0
  55. package/dist/assets/skills/oracle-public-product/SKILL.md +44 -0
  56. package/dist/assets/skills/oracle-receipts/SKILL.md +52 -0
  57. package/dist/assets/skills/oracle-receipts.md +29 -0
  58. package/dist/assets/skills/oracle-rfq-tokenized-assets/SKILL.md +69 -0
  59. package/dist/assets/skills/oracle-smart-wallet-scanner/SKILL.md +49 -0
  60. package/dist/assets/skills/oracle-solana/SKILL.md +65 -0
  61. package/dist/assets/skills/oracle-solana-nft/SKILL.md +54 -0
  62. package/dist/assets/skills/oracle-token-research/SKILL.md +67 -0
  63. package/dist/assets/skills/solana.md +22 -0
  64. package/dist/bin/desk-server.mjs +56 -11
  65. package/dist/bin/oracle-data-mcp.mjs +6 -6
  66. package/dist/bin/oracle-equities.mjs +20 -0
  67. package/dist/bin/oracle-init.mjs +19 -19
  68. package/dist/bin/oracle-public-server.mjs +4 -4
  69. package/dist/bin/oracle-route.mjs +13 -13
  70. package/dist/bin/oracle-scan.mjs +10 -10
  71. package/dist/bin/oracle.mjs +35 -27
  72. package/dist/cli/commands/auth.mjs +11 -11
  73. package/dist/cli/commands/bootstrap.mjs +6 -6
  74. package/dist/cli/commands/chain.mjs +12 -12
  75. package/dist/cli/commands/chat.mjs +39 -29
  76. package/dist/cli/commands/data-mcp.mjs +2 -2
  77. package/dist/cli/commands/data.mjs +5 -5
  78. package/dist/cli/commands/doctor.mjs +3 -3
  79. package/dist/cli/commands/equities.mjs +15 -0
  80. package/dist/cli/commands/farm.mjs +59 -0
  81. package/dist/cli/commands/follow.mjs +28 -0
  82. package/dist/cli/commands/gate.mjs +4 -4
  83. package/dist/cli/commands/harness.mjs +15 -0
  84. package/dist/cli/commands/init.mjs +3 -3
  85. package/dist/cli/commands/mcp.mjs +50 -23
  86. package/dist/cli/commands/model.mjs +44 -34
  87. package/dist/cli/commands/plugins.mjs +38 -0
  88. package/dist/cli/commands/prepare.mjs +2 -2
  89. package/dist/cli/commands/public.mjs +3 -3
  90. package/dist/cli/commands/resolve.mjs +23 -0
  91. package/dist/cli/commands/route.mjs +2 -2
  92. package/dist/cli/commands/scan.mjs +2 -2
  93. package/dist/cli/commands/setup.mjs +12 -12
  94. package/dist/cli/commands/sign.mjs +19 -2
  95. package/dist/cli/commands/swap.mjs +36 -0
  96. package/dist/cli/commands/upgrade.mjs +2 -2
  97. package/dist/cli/commands/version.mjs +2 -2
  98. package/dist/data/desk-data.mjs +53 -10
  99. package/dist/data/names.mjs +2 -0
  100. package/dist/data/providers/farming.mjs +2 -0
  101. package/dist/equities/index.mjs +1 -0
  102. package/dist/index.mjs +58 -15
  103. package/dist/public-api/agent-grants.mjs +3 -0
  104. package/dist/router/index.mjs +2 -2
  105. package/dist/scanner/index.mjs +3 -3
  106. package/package.json +8 -3
  107. package/public/oracle-splash/_variants/ice.html +2073 -0
  108. package/public/oracle-splash/_variants/ivory.html +2075 -0
  109. package/public/oracle-splash/assets/agents/claude.png +0 -0
  110. package/public/oracle-splash/assets/agents/codex.png +0 -0
  111. package/public/oracle-splash/assets/desktop-app.jpg +0 -0
  112. package/public/oracle-splash/assets/hero/cli-session-poster.jpg +0 -0
  113. package/public/oracle-splash/assets/hero/cli-session.mp4 +0 -0
  114. package/public/oracle-splash/assets/hero/cli-session.webm +0 -0
  115. package/public/oracle-splash/assets/hero/orb-poster.jpg +0 -0
  116. package/public/oracle-splash/assets/hero/orb.webm +0 -0
  117. package/public/oracle-splash/assets/hero/risk-session-poster.jpg +0 -0
  118. package/public/oracle-splash/assets/hero/risk-session.mp4 +0 -0
  119. package/public/oracle-splash/assets/hero/risk-session.webm +0 -0
  120. package/public/oracle-splash/assets/hero/route-session-poster.jpg +0 -0
  121. package/public/oracle-splash/assets/hero/route-session.mp4 +0 -0
  122. package/public/oracle-splash/assets/hero/route-session.webm +0 -0
  123. package/public/oracle-splash/downloads/index.html +241 -0
  124. package/public/oracle-splash/index.html +1211 -242
@@ -1,2 +1,2 @@
1
- import g from"node:path";import{spawn as m}from"node:child_process";var h=["SIGINT","SIGTERM","SIGHUP"];function d(e,a=[],u={},f=e){return new Promise(s=>{let o=m(e,a,u),n=!1,c=null,l=new Map(h.map(r=>[r,()=>{c||=r,o.exitCode===null&&o.signalCode===null&&o.kill(r)}]));for(let[r,t]of l)process.on(r,t);let p=()=>{for(let[r,t]of l)process.off(r,t)};o.once("error",r=>{n||(n=!0,p(),process.stderr.write(`oracle: could not start ${f}: ${r.message}
2
- `),s(1))}),o.once("exit",(r,t)=>{if(n)return;n=!0,p();let i=c||t;if(i){process.kill(process.pid,i);return}s(r??1)})})}var x={name:"data-mcp",summary:"start the read-only data MCP server",group:"read",usage:"oracle data-mcp",async run(e){let a=g.join(e.root,"bin","oracle-data-mcp.mjs");return d(process.execPath,[a,...e.argv],{stdio:"inherit",env:process.env},"oracle-data-mcp")}};export{x as default};
1
+ import{spawn as m}from"node:child_process";var h=["SIGINT","SIGTERM","SIGHUP"];function d(r,a=[],u={},f=r){return new Promise(s=>{let o=m(r,a,u),n=!1,c=null,l=new Map(h.map(e=>[e,()=>{c||=e,o.exitCode===null&&o.signalCode===null&&o.kill(e)}]));for(let[e,t]of l)process.on(e,t);let p=()=>{for(let[e,t]of l)process.off(e,t)};o.once("error",e=>{n||(n=!0,p(),process.stderr.write(`oracle: could not start ${f}: ${e.message}
2
+ `),s(1))}),o.once("exit",(e,t)=>{if(n)return;n=!0,p();let i=c||t;if(i){process.kill(process.pid,i);return}s(e??1)})})}var C={name:"data-mcp",summary:"start the read-only data MCP server",group:"read",usage:"oracle data-mcp",async run(r){let a=r.bin("oracle-data-mcp.mjs");return d(process.execPath,[a,...r.argv],{stdio:"inherit",env:process.env},"oracle-data-mcp")}};export{C as default};
@@ -1,12 +1,12 @@
1
- import w from"node:path";import{parseArgs as S}from"node:util";import{spawn as v}from"node:child_process";var m=["SIGINT","SIGTERM","SIGHUP"];function h(r,t=[],a={},l=r){return new Promise(o=>{let e=v(r,t,a),n=!1,p=null,u=new Map(m.map(s=>[s,()=>{p||=s,e.exitCode===null&&e.signalCode===null&&e.kill(s)}]));for(let[s,c]of u)process.on(s,c);let f=()=>{for(let[s,c]of u)process.off(s,c)};e.once("error",s=>{n||(n=!0,f(),process.stderr.write(`oracle: could not start ${l}: ${s.message}
2
- `),o(1))}),e.once("exit",(s,c)=>{if(n)return;n=!0,f();let g=p||c;if(g){process.kill(process.pid,g);return}o(s??1)})})}var A="http://127.0.0.1:8787";function i(){process.stderr.write(`usage: oracle data <serve|call|catalog|health> [args]
1
+ import{parseArgs as w}from"node:util";import{spawn as v}from"node:child_process";var m=["SIGINT","SIGTERM","SIGHUP"];function h(r,t=[],a={},l=r){return new Promise(o=>{let e=v(r,t,a),n=!1,p=null,u=new Map(m.map(s=>[s,()=>{p||=s,e.exitCode===null&&e.signalCode===null&&e.kill(s)}]));for(let[s,c]of u)process.on(s,c);let f=()=>{for(let[s,c]of u)process.off(s,c)};e.once("error",s=>{n||(n=!0,f(),process.stderr.write(`oracle: could not start ${l}: ${s.message}
2
+ `),o(1))}),e.once("exit",(s,c)=>{if(n)return;n=!0,f();let g=p||c;if(g){process.kill(process.pid,g);return}o(s??1)})})}var S="http://127.0.0.1:8787";function i(){process.stderr.write(`usage: oracle data <serve|call|catalog|health> [args]
3
3
  oracle data serve [--port N]
4
4
  oracle data call <provider> <op> [--args '<json>']
5
5
  oracle data catalog
6
6
  oracle data health
7
- `)}async function d(r,{method:t="GET",body:a}={}){let o=(process.env.ORACLE_DATA_URL||A).replace(/\/$/,"")+r;try{let e=await fetch(o,{method:t,headers:a?{"content-type":"application/json"}:void 0,body:a?JSON.stringify(a):void 0}),n=await e.text();return process.stdout.write(n.endsWith(`
7
+ `)}async function d(r,{method:t="GET",body:a}={}){let o=(process.env.ORACLE_DATA_URL||S).replace(/\/$/,"")+r;try{let e=await fetch(o,{method:t,headers:a?{"content-type":"application/json"}:void 0,body:a?JSON.stringify(a):void 0}),n=await e.text();return process.stdout.write(n.endsWith(`
8
8
  `)?n:n+`
9
9
  `),e.ok?0:1}catch(e){return e&&(e.code==="ECONNREFUSED"||/fetch failed|ECONNREFUSED/i.test(String(e)))?(process.stderr.write(`oracle: data server not running \u2014 start it with 'oracle data serve'
10
10
  `),4):(process.stderr.write(`oracle data: ${e.message||e}
11
- `),1)}}var T={name:"data",summary:"desk data plane",group:"read",usage:"oracle data serve|call|catalog|health",async run(r){let t=r.argv[0];if(!t||t==="--help"||t==="-h")return i(),t?0:1;if(t==="serve"){let a=null;try{let{values:e}=S({args:r.argv.slice(1),options:{port:{type:"string"}},allowPositionals:!0,strict:!1});a=e.port||null}catch{}let l={...process.env};a&&(l.ORACLE_DATA_PORT=String(a));let o=w.join(r.root,"bin","desk-server.mjs");return h(process.execPath,[o],{stdio:"inherit",env:l},"desk-server")}if(t==="health")return d("/health");if(t==="catalog")return d("/data/catalog");if(t==="call"){let a=r.argv[1],l=r.argv[2];if(!a||!l)return i(),1;let o={},e=r.argv.indexOf("--args");if(e>=0)try{o=JSON.parse(r.argv[e+1]||"{}")}catch(n){return process.stderr.write(`oracle data call: invalid --args JSON: ${n.message}
12
- `),1}return d("/data/call",{method:"POST",body:{provider:a,op:l,args:o}})}return i(),1}};export{T as default};
11
+ `),1)}}var R={name:"data",summary:"desk data plane",group:"read",usage:"oracle data serve|call|catalog|health",async run(r){let t=r.argv[0];if(!t||t==="--help"||t==="-h")return i(),t?0:1;if(t==="serve"){let a=null;try{let{values:e}=w({args:r.argv.slice(1),options:{port:{type:"string"}},allowPositionals:!0,strict:!1});a=e.port||null}catch{}let l={...process.env};a&&(l.ORACLE_DATA_PORT=String(a));let o=r.bin("desk-server.mjs");return h(process.execPath,[o],{stdio:"inherit",env:l},"desk-server")}if(t==="health")return d("/health");if(t==="catalog")return d("/data/catalog");if(t==="call"){let a=r.argv[1],l=r.argv[2];if(!a||!l)return i(),1;let o={},e=r.argv.indexOf("--args");if(e>=0)try{o=JSON.parse(r.argv[e+1]||"{}")}catch(n){return process.stderr.write(`oracle data call: invalid --args JSON: ${n.message}
12
+ `),1}return d("/data/call",{method:"POST",body:{provider:a,op:l,args:o}})}return i(),1}};export{R as default};
@@ -1,5 +1,5 @@
1
- import h from"node:fs";import D from"node:path";var _="signing: not installed (optional) \u2014 npm i -g @oracle-agent/operator";import k from"node:fs";import u from"node:path";import j from"node:os";import y from"node:path";import{fileURLToPath as C}from"node:url";var P=y.dirname(C(import.meta.url)),K=y.resolve(P,"../..");function S(){return process.env.ORACLE_FAKE_HOME||j.homedir()}function b(){return y.join(S(),".config","oracle")}var $="0.19.0",W=`hermes-agent==${$}`;var T="0.12.1",q=Object.freeze({posix:Object.freeze({url:`https://github.com/astral-sh/uv/releases/download/${T}/uv-installer.sh`,sha256:"d3f5412d38c99f9d024901843bf98206f0d2c6dbe64df40d0b740e2751ca62c1"}),windows:Object.freeze({url:`https://github.com/astral-sh/uv/releases/download/${T}/uv-installer.ps1`,sha256:"b9ec035151bfbb11d616dbd69886498d885551489eddf095ea3c0ad59f640eb0"})});function N(){return u.join(b(),"runtime")}function I(){return u.join(N(),"venv")}function U(e){let t=process.platform==="win32"?"Scripts":"bin",o=process.platform==="win32"?`${e}.exe`:e;return u.join(I(),t,o)}function H(){return U("hermes")}function L(e){let t=process.platform==="win32"&&!u.extname(e)?["",".exe",".cmd",".bat"]:[""];for(let o of(process.env.PATH||"").split(u.delimiter))if(o)for(let r of t){let s=u.join(o,`${e}${r}`);try{if(k.existsSync(s))return s}catch{}}return null}function R(){if(process.env.ORACLE_HERMES_BIN)return{ok:!0,bin:process.env.ORACLE_HERMES_BIN,source:"env"};let e=L("hermes");if(e)return{ok:!0,bin:e,source:"path"};let t=H();return k.existsSync(t)?{ok:!0,bin:t,source:"managed"}:{ok:!1,bin:null,source:null}}function O(){let[e,t]=process.versions.node.split(".").map(Number);return e>20||e===20&&t>=19}function M(e){if(!h.existsSync(e))return{};let t={};for(let o of h.readFileSync(e,"utf8").split(/\r?\n/)){let r=o.match(/^([A-Z0-9_]+)=(.*)$/);r&&(t[r[1]]=r[2])}return t}async function V(e){try{return(await fetch(e.replace(/\/$/,"")+"/health")).ok}catch{return!1}}var se={name:"doctor",summary:"check read plane; checks signer too when installed",group:"read",usage:"oracle doctor [--json]",async run(e){let t=e.argv.includes("--json"),o=[],r=!1,s=(n,a,f,c=null)=>{o.push({id:n,status:a,detail:f,fix:c}),a==="fail"&&(r=!0)};s("node",O()?"ok":"fail",`node ${process.versions.node}`,O()?null:"install node >= 20.19");let A=e.paths.oracleExecEnvPath(),d=M(A),m=process.env.ORACLE_ROUTE_ATTESTATION_SECRET||process.env.MAD_ROUTE_ATTESTATION_SECRET||process.env.ORACLE_ATTESTATION_SECRET||process.env.ORACLE_STAMP_HMAC_SECRET||d.ORACLE_ROUTE_ATTESTATION_SECRET||d.MAD_ROUTE_ATTESTATION_SECRET||d.ORACLE_ATTESTATION_SECRET||d.ORACLE_STAMP_HMAC_SECRET;s("attestation_secret",m?"ok":"warn",m?"present":"missing",m?null:"run oracle init --apply (writes ~/.config/oracle/exec.env)");let v=process.env.ORACLE_DATA_URL||"http://127.0.0.1:8787",x=await V(v);s("data_server",x?"ok":"warn",x?`reachable ${v}`:`down ${v}`,x?null:"oracle data serve");let l=R();s("agent_runtime",l.ok?"ok":"warn",l.ok?`present ${l.bin} (${l.source})`:"not installed",l.ok?null:"oracle bootstrap");let g=D.join(e.paths.hermesRoot(),"profiles"),p=0;h.existsSync(g)&&(p=h.readdirSync(g,{withFileTypes:!0}).filter(n=>n.isDirectory()).length),s("hermes_lanes",p>0?"ok":"warn",p>0?`${p} profile dir(s)`:"no lane profiles found",p>0?null:"oracle init --apply");let i=e.resolveOperator(),E={installed:!1};if(i.ok){let n=e.dispatchOperator("oracle-agentic-doctor",["--json"],{stdio:"pipe"}),a={installed:!0,version:i.version,source:i.source};if(n&&typeof n=="object"&&n.stdout)try{let c=JSON.parse(n.stdout);a={installed:!0,version:i.version,source:i.source,signingReady:c.signingReady,broadcastReady:c.broadcastReady,executionReady:c.executionReady,masterKillSwitch:c.masterKillSwitch,raw:c}}catch{a.doctorParseError=!0,a.doctorExit=n.code}else typeof n=="number"&&(a.doctorExit=n);E=a;let f=a.signingReady===!0;s("signing",f?"ok":"warn",f?`operator ${i.version} ready via ${i.source}`:`operator ${i.version} installed but signing is not ready`,f?null:"oracle sign doctor --json")}let w={ok:!r,checks:o,operator:E};if(t)process.stdout.write(JSON.stringify(w,null,2)+`
1
+ import v from"node:fs";import M from"node:path";var S="signing: not installed (optional) \u2014 npm i -g @oracle-agent/operator";import k from"node:fs";import u from"node:path";import w from"node:os";import h from"node:path";import{fileURLToPath as C}from"node:url";var P=h.dirname(C(import.meta.url)),z=h.resolve(P,"../..");function E(){return process.env.ORACLE_FAKE_HOME||w.homedir()}function N(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function b(){return N()?process.env.ORACLE_CONFIG_DIR||h.join(E(),".config","oracle"):h.join(E(),".config","oracle")}var $="0.19.0",q=`hermes-agent==${$}`;var T="0.12.1",ee=Object.freeze({posix:Object.freeze({url:`https://github.com/astral-sh/uv/releases/download/${T}/uv-installer.sh`,sha256:"d3f5412d38c99f9d024901843bf98206f0d2c6dbe64df40d0b740e2751ca62c1"}),windows:Object.freeze({url:`https://github.com/astral-sh/uv/releases/download/${T}/uv-installer.ps1`,sha256:"b9ec035151bfbb11d616dbd69886498d885551489eddf095ea3c0ad59f640eb0"})});function I(){return u.join(b(),"runtime")}function L(){return u.join(I(),"venv")}function D(e){let t=process.platform==="win32"?"Scripts":"bin",o=process.platform==="win32"?`${e}.exe`:e;return u.join(L(),t,o)}function U(){return D("hermes")}function H(e){let t=process.platform==="win32"&&!u.extname(e)?["",".exe",".cmd",".bat"]:[""];for(let o of(process.env.PATH||"").split(u.delimiter))if(o)for(let r of t){let s=u.join(o,`${e}${r}`);try{if(k.existsSync(s))return s}catch{}}return null}function O(){if(process.env.ORACLE_HERMES_BIN)return{ok:!0,bin:process.env.ORACLE_HERMES_BIN,source:"env"};let e=H("hermes");if(e)return{ok:!0,bin:e,source:"path"};let t=U();return k.existsSync(t)?{ok:!0,bin:t,source:"managed"}:{ok:!1,bin:null,source:null}}function R(){let[e,t]=process.versions.node.split(".").map(Number);return e>20||e===20&&t>=19}function B(e){if(!v.existsSync(e))return{};let t={};for(let o of v.readFileSync(e,"utf8").split(/\r?\n/)){let r=o.match(/^([A-Z0-9_]+)=(.*)$/);r&&(t[r[1]]=r[2])}return t}async function V(e){try{return(await fetch(e.replace(/\/$/,"")+"/health")).ok}catch{return!1}}var ie={name:"doctor",summary:"check read plane; checks signer too when installed",group:"read",usage:"oracle doctor [--json]",async run(e){let t=e.argv.includes("--json"),o=[],r=!1,s=(n,c,f,a=null)=>{o.push({id:n,status:c,detail:f,fix:a}),c==="fail"&&(r=!0)};s("node",R()?"ok":"fail",`node ${process.versions.node}`,R()?null:"install node >= 20.19");let A=e.paths.oracleExecEnvPath(),d=B(A),m=process.env.ORACLE_ROUTE_ATTESTATION_SECRET||process.env.MAD_ROUTE_ATTESTATION_SECRET||process.env.ORACLE_ATTESTATION_SECRET||process.env.ORACLE_STAMP_HMAC_SECRET||d.ORACLE_ROUTE_ATTESTATION_SECRET||d.MAD_ROUTE_ATTESTATION_SECRET||d.ORACLE_ATTESTATION_SECRET||d.ORACLE_STAMP_HMAC_SECRET;s("attestation_secret",m?"ok":"warn",m?"present":"missing",m?null:"run oracle init --apply (writes ~/.config/oracle/exec.env)");let x=process.env.ORACLE_DATA_URL||"http://127.0.0.1:8787",y=await V(x);s("data_server",y?"ok":"warn",y?`reachable ${x}`:`down ${x}`,y?null:"oracle data serve");let l=O();s("agent_runtime",l.ok?"ok":"warn",l.ok?`present ${l.bin} (${l.source})`:"not installed",l.ok?null:"oracle bootstrap");let g=M.join(e.paths.hermesRoot(),"profiles"),p=0;v.existsSync(g)&&(p=v.readdirSync(g,{withFileTypes:!0}).filter(n=>n.isDirectory()).length),s("hermes_lanes",p>0?"ok":"warn",p>0?`${p} profile dir(s)`:"no lane profiles found",p>0?null:"oracle init --apply");let i=e.resolveOperator(),_={installed:!1};if(i.ok){let n=e.dispatchOperator("oracle-agentic-doctor",["--json"],{stdio:"pipe"}),c={installed:!0,version:i.version,source:i.source};if(n&&typeof n=="object"&&n.stdout)try{let a=JSON.parse(n.stdout);c={installed:!0,version:i.version,source:i.source,signingReady:a.signingReady,broadcastReady:a.broadcastReady,executionReady:a.executionReady,masterKillSwitch:a.masterKillSwitch,raw:a}}catch{c.doctorParseError=!0,c.doctorExit=n.code}else typeof n=="number"&&(c.doctorExit=n);_=c;let f=c.signingReady===!0;s("signing",f?"ok":"warn",f?`operator ${i.version} ready via ${i.source}`:`operator ${i.version} installed but signing is not ready`,f?null:"oracle sign doctor --json")}let j={ok:!r,checks:o,operator:_};if(t)process.stdout.write(JSON.stringify(j,null,2)+`
2
2
  `);else{for(let n of o)process.stdout.write(`${n.status.toUpperCase().padEnd(4)} ${n.id}: ${n.detail}
3
3
  `),n.fix&&process.stdout.write(` fix: ${n.fix}
4
- `);i.ok||process.stdout.write(`INFO ${_}
5
- `)}return r?1:0}};export{se as default};
4
+ `);i.ok||process.stdout.write(`INFO ${S}
5
+ `)}return r?1:0}};export{ie as default};
@@ -0,0 +1,15 @@
1
+ import{spawnSync as i}from"node:child_process";var a={name:"equities",summary:"Crossbook \u2014 HIP-3 / Arcus / RH / Solana / TON best execution",group:"read",usage:"oracle equities <venues|quote|prepare> [ticker] [flags]",async run(e){if(e.argv.includes("-h")||e.argv.includes("--help")||e.argv.length===0)return process.stdout.write(`Crossbook \u2014 separate Oracle product for on-chain equities best execution
2
+
3
+ Venues: HIP-3 builder DEXes \xB7 Arcus spot/perp \xB7 RH Uniswap (4663) \xB7 Solana xStocks \xB7 TON ston.fi
4
+ Custody: prepare-only. Quote-only winners are never sold as signable here.
5
+ Only rh_uniswap can emit an unsigned tx (your wallet signs).
6
+
7
+ Usage:
8
+ oracle equities venues
9
+ oracle equities quote NVDA --size 1000
10
+ oracle equities quote SPY --size 500 --json
11
+ oracle equities prepare NVDA --recipient 0xYourWallet --size 1000
12
+
13
+ Alias bin: oracle-equities
14
+ `),0;let r=e.bin("oracle-equities.mjs"),s=i(process.execPath,[r,...e.argv],{stdio:"inherit"});return s.error?(process.stderr.write(`oracle: failed to spawn oracle-equities: ${s.error.message}
15
+ `),1):typeof s.status=="number"?s.status:1}};export{a as default};
@@ -0,0 +1,59 @@
1
+ import{createHash as U}from"node:crypto";var j=new Set([408,425,429,500,502,503,504]),L=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),F=2,T=4e3,I=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],H=new Set([301,302,303,307,308]),M=3;function O(e){let t=String(e||"").toLowerCase();return I.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function B(e){let t={};for(let[r,o]of Object.entries(e||{}))O(r)||(t[r]=o);return t}function V(e,t){if(!e)throw new Error(`HTTP redirect from ${t} missing Location`);let r=new URL(String(e),String(t));if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`HTTP redirect from ${t} used unsupported protocol ${r.protocol}`);return r.toString()}function W(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}var E=new Map;function q(e,t,r){let o={};for(let[a,l]of Object.entries(r||{}))o[a.toLowerCase()]=l;let n=Object.keys(o).filter(a=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(a)),i=[...new Set([...I,...n])].sort().map(a=>`${a}=${o[a]??""}`).join(`
2
+ `),d=U("sha256").update(i).digest("hex").slice(0,32);return`${e} ${t} ${d}`}function z(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,T):Math.min(250*2**e,T)+Math.floor(Math.random()*100)}var G=e=>new Promise(t=>setTimeout(t,e));async function J(e,{fetchImpl:t,method:r,headers:o,body:n,timeoutMs:s}){let i=new AbortController,d=setTimeout(()=>i.abort(),s);try{let a=String(e),l={...o||{}};for(let u=0;u<=M;u+=1){let p=await t(a,{method:r,headers:l,body:n,signal:i.signal,redirect:"manual"}),h=await p.text(),m=null;if(h)try{m=JSON.parse(h)}catch{m=null}if(H.has(p.status)){if(r!=="GET"&&r!=="HEAD"){let f=new Error(`HTTP ${p.status} ${r} ${a} redirected non-idempotent request`);throw f.status=p.status,f.body=m??h.slice(0,300),f}if(u===M)throw new Error(`HTTP redirect loop for ${e}`);let c=V(p.headers?.get?.("location"),a);W(c,a)||(l=B(l)),a=c;continue}if(!p.ok){let c=new Error(`HTTP ${p.status} ${r} ${a}`);throw c.status=p.status,c.retryAfter=p.headers?.get?.("retry-after")??null,c.body=m??h.slice(0,300),c}return m??h}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(d)}}async function _(e,t={}){let r=t.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let o=t.timeoutMs??12e3,n=(t.method||"GET").toUpperCase(),s={Accept:"application/json",...t.headers||{}},i=t.body;i!=null&&typeof i!="string"&&(s["Content-Type"]=s["Content-Type"]||"application/json",i=JSON.stringify(i));let d=Number.isInteger(t.retries)?Math.max(t.retries,0):F,a=async()=>{let m;for(let c=0;c<=d;c++)try{return await J(e,{fetchImpl:r,method:n,headers:s,body:i,timeoutMs:o})}catch(f){m=f;let k=f?.status,$=f?.name==="AbortError",v=new Set([408,425,429]),A=k!=null?v.has(k)||j.has(k)&&L.has(n):!$&&L.has(n);if(c===d||!A)throw f;await G(z(c,f?.retryAfter))}throw m};if(!(t.dedupe!==!1&&n==="GET"&&i==null))return a();let u=q(n,e,s),p=E.get(u);if(p)return p;let h=a().finally(()=>E.delete(u));return E.set(u,h),h}var Y="https://yields.llama.fi";async function R(e={},t={}){let r=(t.yieldsBaseUrl||process.env.DEFILLAMA_YIELDS_URL||Y).replace(/\/$/,""),o=await _(`${r}/pools`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??3e4}),n=Array.isArray(o?.data)?o.data:[];e.chain&&(n=n.filter(i=>String(i.chain).toLowerCase()===String(e.chain).toLowerCase())),e.project&&(n=n.filter(i=>String(i.project).toLowerCase()===String(e.project).toLowerCase())),e.stablecoin!=null&&(n=n.filter(i=>!!i.stablecoin==!!e.stablecoin)),n.sort((i,d)=>Number(d.tvlUsd||0)-Number(i.tvlUsd||0));let s=Math.min(5e3,Math.max(1,Number(e.limit||n.length||1)));return{...o,data:n.slice(0,s)}}var x=Object.freeze([{id:"stable-loop",label:"Stablecoin loop",risk:"Conservative",targetDelta:"0.00",setup:"Supply USDC, borrow a second major stable, redeposit inside the same protocol or campaign.",exposure:"Borrow APR spike, depeg, collateral-factor change, protocol cap change.",hedge:"No perp hedge by default. Cap leverage, diversify stables, and keep unwind triggers explicit.",monitor:"Borrow APR, utilization, oracle health, depeg distance, reward dilution.",exit:"Unwind if borrow APR exceeds reward-adjusted APR or any stable trades outside the defined band."},{id:"collateral-hedge",label:"Collateral plus perp hedge",risk:"Balanced",targetDelta:"~0.00",setup:"Supply a volatile asset as collateral, borrow stables, and short the collateral notional on a liquid perp venue.",exposure:"Liquidation risk, funding cost, hedge slippage, borrow APR drift.",hedge:"Short collateral notional on a liquid perp venue; rebalance when delta drifts past the band.",monitor:"Health factor, funding, mark price, borrow APR, hedge margin.",exit:"Cut when funding turns persistently negative against the position or health factor nears the floor."},{id:"lp-hedge",label:"LP incentive hedge",risk:"Aggressive",targetDelta:"range-dependent",setup:"Provide concentrated liquidity for incentives and short the estimated volatile-token delta.",exposure:"Impermanent loss, range breaks, reward dilution, exit slippage.",hedge:"Short the estimated volatile-token delta and recompute after material price or range moves.",monitor:"Position delta, range utilization, fee APR, rewards, funding, exit slippage.",exit:"Withdraw when incentives dilute, liquidity caps fill, or expected reward no longer beats IL plus opportunity cost."},{id:"quest-farming",label:"Testnet and quest farming",risk:"Conservative",targetDelta:"n/a",setup:"Complete real protocol tasks with consistent, genuine usage from wallets you actually control.",exposure:"Eligibility rules change, sybil filters, unpaid effort, opportunity cost.",hedge:"No financial hedge. Diversify across campaigns so no single ruleset dominates the outcome.",monitor:"Campaign rules, snapshot windows, task eligibility evidence, wallet hygiene.",exit:"Stop once snapshot risk rises, campaign rules change, or the probability-adjusted expected value turns negative."},{id:"liquidity-usage",label:"Liquidity and route usage",risk:"Balanced",targetDelta:"varies",setup:"Route genuine volume and provide liquidity where usage is a stated eligibility signal.",exposure:"IL, slippage, gas burn, bridge fees, lockup discount.",hedge:"Size positions so IL and fees stay inside the modelled reward, and hedge volatile legs when material.",monitor:"Volume attribution, fee drag, reward accrual, lockup terms.",exit:"Withdraw when incentives dilute or expected reward no longer beats IL plus opportunity cost."},{id:"governance-usage",label:"Governance and ecosystem usage",risk:"Conservative",targetDelta:"n/a",setup:"Participate in governance and ecosystem surfaces where real contribution is the eligibility signal.",exposure:"Vanity activity with no eligibility weight, lock-up of governance assets.",hedge:"No financial hedge. Weight effort toward actions with documented eligibility evidence.",monitor:"Proposal participation, delegation terms, lock durations, published criteria.",exit:"Stop contributing effort once criteria change or the probability-adjusted value turns negative."}]),K={"stable-loop":"No default perp hedge. Bound leverage and monitor depeg plus borrow APR.","collateral-hedge":"Short the collateral notional on a liquid perp venue and rebalance when delta drifts.","lp-hedge":"Short the estimated volatile-token delta and recompute after material price or range moves."},X={"stable-loop":"Borrow APR, utilization, stable peg, reward dilution, health factor.","collateral-hedge":"Health factor, funding, mark price, borrow APR, hedge margin.","lp-hedge":"Position delta, range utilization, fee APR, rewards, funding, exit slippage."},Q={"stable-loop":["Prepare supply for the stable collateral leg.","Prepare borrow only after health factor and borrow APR pass the method limits.","Prepare redeposit or unwind steps as separate wallet-signed actions."],"collateral-hedge":["Prepare collateral supply after sizing liquidation buffer.","Prepare stable borrow if borrow APR remains inside the method limit.","Open or adjust the perp short on the selected hedge venue, then record hedge size."],"lp-hedge":["Prepare LP add only after checking pool depth, range, and expected position delta.","Short the estimated volatile-token delta on the selected hedge venue.","Prepare LP remove if the range breaks or net APR turns negative."]};function w(e){let t=typeof e=="number"?e:Number(e);return Number.isFinite(t)?t:null}function y(e,t="unknown"){if(typeof e!="string")return t;let r=e.trim();return r===""?t:r.slice(0,96)}function Z(e){let t=y(e.symbol,"").toUpperCase(),r=y(e.exposure,"").toLowerCase(),o=w(e.apy)??0,n=w(e.tvlUsd)??0;return o<=0||n<=0?null:e.stablecoin===!0?"stable-loop":t.includes("-")||r.includes("multi")?"lp-hedge":/ETH|BTC|SOL|HYPE|BNB|AVAX|MATIC|OP|ARB/.test(t)?"collateral-hedge":null}function ee(e,t){let r=w(e.tvlUsd)??0,o=y(e.ilRisk,"").toLowerCase(),n=y(e.predictions?.predictedClass,"").toLowerCase(),s=t==="stable-loop"?3:t==="collateral-hedge"?6:9;return r<1e6?s+=6:r<1e7&&(s+=3),(o.includes("yes")||o.includes("high"))&&(s+=3),n.includes("down")&&(s+=2),Math.min(35,Math.max(0,s))}function te(e){let t=Z(e);if(!t)return null;let r=w(e.apy)??0,o=w(e.apyBase)??0,n=Math.max(0,w(e.apyReward)??Math.max(0,r-o)),s=Math.max(0,w(e.tvlUsd)??0),i=ee(e,t),d=t==="stable-loop"?4:t==="collateral-hedge"?6:0,a=t==="stable-loop"?0:t==="collateral-hedge"?4:5,l=s<5e6?1.2:.5,u=r-d-a-l-i,p=u<1?"Avoid":r>80||s<1e7?"Watchlist":u>=8?"Farmable":"Watchlist",h=y(e.project),m=y(e.symbol),c=y(e.chain);return{id:y(e.pool,`${c}:${h}:${m}`),recipe:t,label:`${h} ${m}`,chain:c,project:h,symbol:m,tvlUsd:s,rewardApr:n,nativeApr:o,estimatedBorrowApr:d,estimatedFundingApr:a,gasApr:l,riskHaircut:i,netApr:u,verdict:p,exposure:y(e.exposure,t==="stable-loop"?"stablecoin":t==="lp-hedge"?"multi-asset LP":"single-asset collateral"),hedge:K[t],monitor:X[t],prepareSteps:[`Verify ${h} contracts and reward terms on ${c}.`,"Set wallet grant with chain, protocol, max value, slippage, and TTL before preparing any transaction.",...Q[t]],source:"DeFiLlama yields"}}async function C(e={},t={}){let r=Math.min(24,Math.max(3,Number(e.limit??12)||12)),o=Number(e.minTvl??2e6),n=new Date().toISOString(),s="read-only discovery and prepare-plan design; no signing or broadcast";try{let i=await R({chain:e.chain&&e.chain!=="all"?e.chain:void 0,limit:5e3},t),d=Array.isArray(i?.data)?i.data:[],a=d.map(te).filter(l=>l!==null).filter(l=>l.tvlUsd>=o).filter(l=>l.rewardApr+l.nativeApr<=300).sort((l,u)=>u.netApr-l.netApr||u.tvlUsd-l.tvlUsd).slice(0,r);return{configured:!0,live:!0,source:"DeFiLlama yields",generatedAt:n,chain:e.chain??"all",considered:d.length,consideredNote:"deepest pools by TVL from the DeFiLlama yields feed",candidates:a,posture:s}}catch(i){return{configured:!1,live:!1,source:"DeFiLlama yields",generatedAt:n,chain:e.chain??"all",considered:0,consideredNote:"deepest pools by TVL from the DeFiLlama yields feed",error:String(i?.message||i),candidates:[],posture:s}}}function g(e,t,r,o){let n=typeof e=="number"?e:Number(e);return Number.isFinite(n)?Math.min(o,Math.max(r,n)):t}function D(e={}){let t=g(e.wallets,5,1,500),r=g(e.tasksWeekly,6,0,500),o=g(e.hoursWeekly,4,0,168),n=g(e.hourlyCost,25,0,1e4),s=g(e.gasPerTask,.4,0,1e4),i=g(e.bridgeMonthly,12,0,1e5),d=g(e.expectedReward,900,0,1e7),a=g(e.probability,22,0,100)/100,l=g(e.sybilHaircut,25,0,100)/100,u=g(e.lockupMonths,6,0,120),p=r*t*4.33,h=p*s,m=o*4.33*n,c=h+m+i,f=Math.max(0,1-u*.015),k=t*d*a,$=k*(1-l)*f,v=$-c,A=c>0?v/c*100:null,N=t*d>0?c/(t*d*(1-l)*(f||1))*100:null;return{inputs:{wallets:t,tasksWeekly:r,hoursWeekly:o,hourlyCost:n,gasPerTask:s,bridgeMonthly:i,expectedReward:d,probabilityPct:a*100,sybilHaircutPct:l*100,lockupMonths:u},monthlyTasks:p,monthlyGas:h,laborMonthly:m,monthlyCost:c,lockupDiscount:f,grossExpectedValue:k,adjustedExpectedValue:$,netExpectedValue:v,roiPct:A,breakevenProbabilityPct:N,verdict:v>0?"positive-ev":"negative-ev",posture:"estimate on your own inputs; not a payout promise and not financial advice"}}var P=`oracle farm <methods|discover|airdrop> [options]
3
+
4
+ oracle farm methods list the delta-aware farming playbooks
5
+ oracle farm methods --id stable-loop full setup/exposure/hedge/monitor/exit for one method
6
+ oracle farm discover [--chain base] rank live pools by net APR after costs and risk haircut
7
+ [--limit 12] [--min-tvl 2000000] [--json]
8
+ oracle farm airdrop [--wallets 5] [--tasks-weekly 6] [--hours-weekly 4]
9
+ [--hourly-cost 25] [--gas-per-task 0.4] [--bridge-monthly 12]
10
+ [--expected-reward 900] [--probability 22]
11
+ [--sybil-haircut 25] [--lockup-months 6] [--json]
12
+
13
+ Read-only. Ranks opportunities and designs prepare plans; never signs or broadcasts.`;function re(e){let t={_:[]};for(let r=0;r<e.length;r+=1){let o=e[r];if(o==="--json"){t.json=!0;continue}if(o.startsWith("--")){let n=o.slice(2),s=e[r+1];if(s===void 0||s.startsWith("--")){t[n]=!0;continue}t[n]=s,r+=1;continue}t._.push(o)}return t}var b=e=>`$${Math.round(Number(e)||0).toLocaleString("en-US")}`,S=e=>`${(Number(e)||0).toFixed(1)}%`;function oe(e){let t=typeof e.id=="string"?e.id:null;if(t){let r=x.find(o=>o.id===t);if(!r)return process.stderr.write(`oracle farm: unknown method '${t}'. Known: ${x.map(o=>o.id).join(", ")}
14
+ `),1;if(e.json)return process.stdout.write(JSON.stringify(r,null,2)+`
15
+ `),0;process.stdout.write(`
16
+ ${r.label} [${r.risk}] target delta ${r.targetDelta}
17
+
18
+ `);for(let[o,n]of[["setup","setup"],["exposure","exposure"],["hedge","hedge"],["monitor","monitor"],["exit","exit"]])process.stdout.write(` ${o.padEnd(9)} ${r[n]}
19
+ `);return process.stdout.write(`
20
+ `),0}if(e.json)return process.stdout.write(JSON.stringify(x,null,2)+`
21
+ `),0;process.stdout.write(`
22
+ farming methods
23
+
24
+ `);for(let r of x)process.stdout.write(` ${r.id.padEnd(18)} ${r.label.padEnd(30)} ${r.risk}
25
+ `);return process.stdout.write(`
26
+ oracle farm methods --id <id> for setup, exposure, hedge, monitor, and exit rules.
27
+
28
+ `),0}async function ne(e){let t=await C({chain:typeof e.chain=="string"?e.chain:null,limit:e.limit,minTvl:e["min-tvl"]});if(e.json)return process.stdout.write(JSON.stringify(t,null,2)+`
29
+ `),0;if(!t.live)return process.stderr.write(`oracle farm: discovery unavailable \u2014 ${t.error}
30
+ `),1;process.stdout.write(`
31
+ live farm discovery \u2014 ${t.source}, ${t.considered.toLocaleString("en-US")} pools considered (${t.consideredNote}), chain=${t.chain}
32
+
33
+ `),process.stdout.write(` ${"verdict".padEnd(10)}${"net apr".padStart(9)} ${"tvl".padStart(12)} ${"chain".padEnd(12)}${"recipe".padEnd(18)}pool
34
+ `);for(let r of t.candidates)process.stdout.write(` ${r.verdict.padEnd(10)}${S(r.netApr).padStart(9)} ${b(r.tvlUsd).padStart(12)} ${r.chain.slice(0,11).padEnd(12)}${r.recipe.padEnd(18)}${r.label}
35
+ `);return process.stdout.write(`
36
+ net apr = apy \u2212 borrow \u2212 funding \u2212 gas \u2212 risk haircut.
37
+ ${t.posture}.
38
+
39
+ `),0}function ie(e){let t=D({wallets:e.wallets,tasksWeekly:e["tasks-weekly"],hoursWeekly:e["hours-weekly"],hourlyCost:e["hourly-cost"],gasPerTask:e["gas-per-task"],bridgeMonthly:e["bridge-monthly"],expectedReward:e["expected-reward"],probability:e.probability,sybilHaircut:e["sybil-haircut"],lockupMonths:e["lockup-months"]});if(e.json)return process.stdout.write(JSON.stringify(t,null,2)+`
40
+ `),0;let r=t.inputs;return process.stdout.write(`
41
+ airdrop expected value
42
+
43
+ `),process.stdout.write(` ${r.wallets} wallets \xB7 ${r.tasksWeekly} tasks/wk \xB7 ${r.hoursWeekly} hrs/wk @ ${b(r.hourlyCost)}/hr
44
+ `),process.stdout.write(` ${S(r.probabilityPct)} eligibility \xB7 ${S(r.sybilHaircutPct)} sybil haircut \xB7 ${r.lockupMonths}mo lockup
45
+
46
+ `),process.stdout.write(` monthly cost ${b(t.monthlyCost).padStart(12)} (gas ${b(t.monthlyGas)} + labor ${b(t.laborMonthly)} + bridges ${b(r.bridgeMonthly)})
47
+ `),process.stdout.write(` gross EV ${b(t.grossExpectedValue).padStart(12)}
48
+ `),process.stdout.write(` after haircuts ${b(t.adjustedExpectedValue).padStart(12)} (lockup discount ${(t.lockupDiscount*100).toFixed(0)}%)
49
+ `),process.stdout.write(` net EV ${b(t.netExpectedValue).padStart(12)} ${t.verdict}
50
+ `),t.roiPct!=null&&process.stdout.write(` ROI ${S(t.roiPct).padStart(12)}
51
+ `),t.breakevenProbabilityPct!=null&&process.stdout.write(` breakeven odds ${S(t.breakevenProbabilityPct).padStart(12)} campaign must clear this to profit
52
+ `),process.stdout.write(`
53
+ ${t.posture}.
54
+
55
+ `),0}var he={name:"farm",summary:"farming methods, live farm discovery, airdrop EV",group:"read",usage:P,async run(e){let t=re(e.argv),r=t._[0];return!r||r==="help"?(process.stdout.write(P+`
56
+ `),0):r==="methods"?oe(t):r==="discover"?ne(t):r==="airdrop"?ie(t):(process.stderr.write(`oracle farm: unknown subcommand '${r}'
57
+
58
+ ${P}
59
+ `),1)}};export{he as default};
@@ -0,0 +1,28 @@
1
+ var G="0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",H={1:["https://mainnet.gateway.tenderly.co","https://eth.drpc.org","https://rpc.flashbots.net"],8453:["https://base.gateway.tenderly.co","https://mainnet.base.org","https://base.drpc.org"],42161:["https://arbitrum.gateway.tenderly.co","https://arb1.arbitrum.io/rpc","https://arbitrum.drpc.org"]},yt=1e4,gt=t=>new Promise(e=>setTimeout(e,t)),Y=t=>"0x"+BigInt(t).toString(16),Et=t=>"0x"+"0".repeat(24)+t.slice(2).toLowerCase(),J=t=>"0x"+t.slice(26).toLowerCase(),xt=/timeout|timed out|too many requests|rate.?limit|429|502|503|504|internal error|temporarily|aborted|fetch failed|ECONNRESET|socket hang up/i,St=/too many|exceeds|limited to|not supported on free plan|response too large|range must not exceed|narrow your filter/i,E=class extends Error{constructor(e,{transient:n=!1,tooBig:r=!1,http:s=0}={}){super(e),this.transient=n,this.tooBig=r,this.http=s}};async function kt(t,e,n,r){let s=new AbortController,i=setTimeout(()=>s.abort(),r),a,c;try{a=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:e,params:n}),signal:s.signal}),c=await a.text()}catch(l){throw new E(`${e} network: ${l.message}`,{transient:!0})}finally{clearTimeout(i)}let o;try{o=JSON.parse(c)}catch{throw new E(`${e} non-JSON http=${a.status}: ${c.slice(0,80)}`,{transient:a.status>=500||a.status===429,http:a.status})}if(o.error){let l=o.error.message||"rpc error";throw new E(`${e} rpc: ${l}`,{transient:xt.test(l),tooBig:St.test(l),http:a.status})}if(a.status!==200)throw new E(`${e} http=${a.status}: ${c.slice(0,80)}`,{transient:a.status>=500||a.status===429,http:a.status});return o.result}async function q(t,e,n,{retries:r,timeoutMs:s,onWarn:i}){let a;for(let c of t){for(let o=0;o<=r;o++)try{return{result:await kt(c,e,n,s),url:c}}catch(l){if(a=l,l.tooBig)throw l;if(!l.transient||o===r)break;let f=Math.min(2e3*2**o,8e3)+Math.random()*250;i?.(`retry ${c} (${l.message.slice(0,70)}) in ${Math.round(f)}ms`),await gt(f)}i?.(`endpoint exhausted: ${c} -> ${a?.message.slice(0,70)}`)}throw a??new E("no endpoints available")}async function P(t,e,n,r,s,i){let a=[{...e,fromBlock:Y(n),toBlock:Y(r)}];try{let{result:o}=await q(t,"eth_getLogs",a,s);Array.isArray(o)&&i.push(...o);return}catch(o){if(!o.tooBig||r<=n)throw o;s.onWarn?.(`splitting ${n}-${r} (${o.message.slice(0,60)})`)}let c=n+Math.floor((r-n)/2);await P(t,e,n,c,s,i),await P(t,e,c+1,r,s,i)}async function K(t,e={}){if(!/^0x[0-9a-fA-F]{40}$/.test(t||""))throw new Error(`invalid address: ${t}`);let{chains:n=[1,8453,42161],lookback:r=1e5,fromBlock:s,toBlock:i,chunkSize:a=yt,tokens:c,direction:o="both",retries:l=3,timeoutMs:f=2e4,concurrency:u=4,endpoints:m=H,onWarn:d}=e,p={retries:l,timeoutMs:f,onWarn:d},b=Et(t),y=[],k=[],T={},N=new Set;return await Promise.all(n.map(async w=>{let R=m[w];if(!R?.length){k.push({chainId:w,stage:"config",error:"no endpoints configured"});return}try{let _=i;if(_==null){let{result:h}=await q(R,"eth_blockNumber",[],p);_=parseInt(h,16)}let $=Math.max(0,s??_-r+1),v=Math.max($,_);T[w]={fromBlock:$,toBlock:v,blocks:v-$+1};let j=[];for(let h=$;h<=v;h+=a)j.push([h,Math.min(h+a-1,v)]);let B=[],V=c?.length?{address:c}:{};(o==="in"||o==="both")&&B.push({...V,topics:[G,null,b]}),(o==="out"||o==="both")&&B.push({...V,topics:[G,b,null]});let I=[];for(let h of B)for(let g of j)I.push([h,g]);let z=[],W=0,bt=Array.from({length:Math.min(u,I.length)},async()=>{for(;W<I.length;){let[h,[g,A]]=I[W++];try{await P(R,h,g,A,p,z)}catch(wt){k.push({chainId:w,stage:"getLogs",range:[g,A],error:wt.message})}}});await Promise.all(bt);for(let h of z){if(!h?.topics||h.topics.length<3)continue;let g=parseInt(h.logIndex,16),A=`${w}|${h.transactionHash}|${g}`;N.has(A)||(N.add(A),y.push({chainId:w,token:h.address.toLowerCase(),from:J(h.topics[1]),to:J(h.topics[2]),value:BigInt(h.data==="0x"?"0x0":h.data).toString(),blockNumber:parseInt(h.blockNumber,16),txHash:h.transactionHash,logIndex:g}))}}catch(_){k.push({chainId:w,stage:"range",error:_.message})}})),y.sort((w,R)=>R.blockNumber-w.blockNumber||R.logIndex-w.logIndex),{events:y,errors:k,ranges:T}}import{keccak_256 as M}from"@noble/hashes/sha3.js";import{createHash as Rt}from"node:crypto";var _t=new Set([408,425,429,500,502,503,504]),X=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),At=2,Z=4e3,tt=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],Ct=new Set([301,302,303,307,308]),Q=3;function Tt(t){let e=String(t||"").toLowerCase();return tt.includes(e)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(e)}function Nt(t){let e={};for(let[n,r]of Object.entries(t||{}))Tt(n)||(e[n]=r);return e}function $t(t,e){if(!t)throw new Error(`HTTP redirect from ${e} missing Location`);let n=new URL(String(t),String(e));if(n.protocol!=="http:"&&n.protocol!=="https:")throw new Error(`HTTP redirect from ${e} used unsupported protocol ${n.protocol}`);return n.toString()}function vt(t,e){return new URL(String(t)).origin===new URL(String(e)).origin}var O=new Map;function It(t,e,n){let r={};for(let[o,l]of Object.entries(n||{}))r[o.toLowerCase()]=l;let s=Object.keys(r).filter(o=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(o)),a=[...new Set([...tt,...s])].sort().map(o=>`${o}=${r[o]??""}`).join(`
2
+ `),c=Rt("sha256").update(a).digest("hex").slice(0,32);return`${t} ${e} ${c}`}function Lt(t,e){let n=Number(e);return Number.isFinite(n)&&n>0?Math.min(n*1e3,Z):Math.min(250*2**t,Z)+Math.floor(Math.random()*100)}var Bt=t=>new Promise(e=>setTimeout(e,t));async function Pt(t,{fetchImpl:e,method:n,headers:r,body:s,timeoutMs:i}){let a=new AbortController,c=setTimeout(()=>a.abort(),i);try{let o=String(t),l={...r||{}};for(let f=0;f<=Q;f+=1){let u=await e(o,{method:n,headers:l,body:s,signal:a.signal,redirect:"manual"}),m=await u.text(),d=null;if(m)try{d=JSON.parse(m)}catch{d=null}if(Ct.has(u.status)){if(n!=="GET"&&n!=="HEAD"){let b=new Error(`HTTP ${u.status} ${n} ${o} redirected non-idempotent request`);throw b.status=u.status,b.body=d??m.slice(0,300),b}if(f===Q)throw new Error(`HTTP redirect loop for ${t}`);let p=$t(u.headers?.get?.("location"),o);vt(p,o)||(l=Nt(l)),o=p;continue}if(!u.ok){let p=new Error(`HTTP ${u.status} ${n} ${o}`);throw p.status=u.status,p.retryAfter=u.headers?.get?.("retry-after")??null,p.body=d??m.slice(0,300),p}return d??m}throw new Error(`HTTP redirect loop for ${t}`)}finally{clearTimeout(c)}}async function et(t,e={}){let n=e.fetchImpl||globalThis.fetch;if(typeof n!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let r=e.timeoutMs??12e3,s=(e.method||"GET").toUpperCase(),i={Accept:"application/json",...e.headers||{}},a=e.body;a!=null&&typeof a!="string"&&(i["Content-Type"]=i["Content-Type"]||"application/json",a=JSON.stringify(a));let c=Number.isInteger(e.retries)?Math.max(e.retries,0):At,o=async()=>{let d;for(let p=0;p<=c;p++)try{return await Pt(t,{fetchImpl:n,method:s,headers:i,body:a,timeoutMs:r})}catch(b){d=b;let y=b?.status,k=b?.name==="AbortError",T=new Set([408,425,429]),N=y!=null?T.has(y)||_t.has(y)&&X.has(s):!k&&X.has(s);if(p===c||!N)throw b;await Bt(Lt(p,b?.retryAfter))}throw d};if(!(e.dedupe!==!1&&s==="GET"&&a==null))return o();let f=It(s,t,i),u=O.get(f);if(u)return u;let m=o().finally(()=>O.delete(f));return O.set(f,m),m}var nt={robinhood:{chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC"],evm:!0},ethereum:{chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],evm:!0},polygon:{chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],evm:!0},arbitrum:{chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],evm:!0},base:{chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],evm:!0},hyperevm:{chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],evm:!0},bsc:{chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],evm:!0},avalanche:{chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],evm:!0},optimism:{chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],evm:!0},abstract:{chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],evm:!0},stable:{chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],evm:!0}},Ht=new Map(Object.values(nt).map(t=>[t.chainId,t]));function rt(t){return Ht.get(Number(t))||null}function ot(t,e=process.env){let n=rt(t);if(!n)return null;for(let r of n.rpcEnv){let s=(e[r]||"").trim();if(s)return s}return null}import{Interface as Ot,getAddress as ue}from"ethers";var de=new Ot(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var Mt={1:"https://ethereum.publicnode.com",137:"https://polygon-bor-rpc.publicnode.com",42161:"https://arbitrum-one-rpc.publicnode.com",8453:"https://base-rpc.publicnode.com",10:"https://optimism-rpc.publicnode.com",988:"https://rpc.stable.xyz",56:"https://bsc-rpc.publicnode.com",43114:"https://avalanche-c-chain-rpc.publicnode.com",999:"https://rpc.hyperliquid.xyz/evm",2741:"https://api.mainnet.abs.xyz",4663:"https://rpc.mainnet.chain.robinhood.com"};function Ut(t,{rpcUrl:e,env:n=process.env}={}){if(e)return e;let r=ot(t,n);return r||Mt[Number(t)]||null}var Dt=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function Ft(t){let e=String(t||""),n=e.toLowerCase();if(e!==e.trim()||!/^[a-zA-Z0-9_]+$/.test(e)||!Dt.test(n))throw new Error(`evm-rpc: ${e} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return n}async function st(t,e,n=[],r={}){let s=String(e||"");Ft(s);let i=Ut(t,r);if(!i)throw new Error(`No RPC URL for chainId ${t} (set env from chain registry rpcEnv or pass rpcUrl)`);let c=await et(i,{method:"POST",body:{jsonrpc:"2.0",id:1,method:e,params:n},fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3});if(c?.error){let o=new Error(c.error.message||JSON.stringify(c.error));throw o.code=c.error.code,o}return c.result}var D=999,U=1,jt=8453,at="0x1d9d87eBc14e71490bB87f1C39F65BDB979f3cb7",Vt="0x4d5e4ed4D5e4A160Fa136853597cDc2eBBe66494",ct="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",zt="0xC6d566A56A1aFf6508b41f6c90ff131615583BCD",Wt=".80002105.reverse",it=/^0x[a-fA-F0-9]{40}$/,lt=new TextEncoder,ut=t=>"0x"+Buffer.from(t).toString("hex"),x=t=>ut(M(lt.encode(t))).slice(0,10),dt=t=>t.toLowerCase().replace(/^0x/,"").padStart(64,"0");function L(t){let e=new Uint8Array(32);if(t)for(let n of String(t).split(".").reverse()){let r=M(lt.encode(n)),s=new Uint8Array(64);s.set(e,0),s.set(r,32),e=M(s)}return ut(e)}function F(t){if(!t||t==="0x"||/^0x0*$/.test(t))return"";try{let e=t.slice(2),n=parseInt(e.slice(0,64),16)*2,r=parseInt(e.slice(n,n+64),16);if(!Number.isFinite(r)||r<=0)return"";let s=e.slice(n+64,n+64+r*2);return Buffer.from(s,"hex").toString("utf8")}catch{return""}}async function S(t,e,n){try{return await st(t,"eth_call",[{to:e,data:n},"latest"])}catch{return null}}async function Gt(t){let e=await S(D,at,x("primaryName(address)")+dt(t)),n=F(e);return n?n.endsWith(".hl")?n:`${n}.hl`:null}async function Yt(t){let e=await S(D,Vt,x("getName(address)")+dt(t)),n=F(e);return n?n.endsWith(".hype")?n:`${n}.hype`:null}async function ht(t,e,n){let r=await S(t,n,x("name(bytes32)")+e.slice(2));return F(r)||null}async function Jt(t){let e=L(`${t.slice(2).toLowerCase()}.addr.reverse`),n=await S(U,ct,x("resolver(bytes32)")+e.slice(2));if(!n)return null;let r="0x"+n.slice(-40);return/^0x0+$/.test(r)?null:ht(U,e,r)}async function qt(t){let e=L(t.slice(2).toLowerCase()+Wt);return ht(jt,e,zt)}var Kt=[{source:"hl",fn:Gt},{source:"hype",fn:Yt},{source:"ens",fn:Jt},{source:"basename",fn:qt}];async function Xt(t){let e=L(t),n=await S(D,at,x("ownerOf(uint256)")+e.slice(2));if(!n||n.length<66)return null;let r="0x"+n.slice(-40);return/^0x0+$/.test(r)?null:r}async function Zt(t,e,n){let r=L(e),s=await S(t,n,x("resolver(bytes32)")+r.slice(2));if(!s)return null;let i="0x"+s.slice(-40);if(/^0x0+$/.test(i))return null;let a=await S(t,i,x("addr(bytes32)")+r.slice(2));if(!a)return null;let c="0x"+a.slice(-40);return/^0x0+$/.test(c)?null:c}async function pt(t){let e=String(t||"").trim().toLowerCase();if(!e||!e.includes("."))return null;if(e.endsWith(".hl")){let n=await Xt(e);return n?{address:n,source:"hl",name:e}:null}if(e.endsWith(".eth")){let n=await Zt(U,e,ct);return n?{address:n,source:e.endsWith(".base.eth")?"basename":"ens",name:e}:null}return null}var me=Kt.map(t=>t.source);var C={1:"ethereum",8453:"base",42161:"arbitrum"},Qt=Object.fromEntries(Object.entries(C).map(([t,e])=>[e,Number(t)])),mt=`oracle follow <name-or-address> [--chain <name>] [--blocks <n>] [--json]
3
+
4
+ oracle follow vitalik.eth
5
+ oracle follow demi.hl --chain base
6
+ oracle follow 0x4d47b6757afd42c3dbd9691b71b43d74afa4b6b2 --blocks 20000 --json
7
+
8
+ Reads ERC20 transfer activity for a wallet. Read-only: this calls
9
+ eth_getLogs and eth_blockNumber and nothing else, so it can never move funds.
10
+
11
+ Chains: ${Object.values(C).join(", ")}. Default: ethereum.
12
+ Lookback defaults to 40000 blocks. Endpoints are keyless.
13
+
14
+ Note publicnode-class RPCs are deliberately excluded: they retain only ~128
15
+ blocks, so they return an empty result instead of an error.`;function ft(t,e){let n=t.indexOf(e);return n>=0?t[n+1]:void 0}function te(t){let e=String(t??"");return e.length>22?`${e.slice(0,19)}...`:e}async function ee(t=[]){let e=t.includes("--json"),n=[];for(let o=0;o<t.length;o+=1){let l=t[o];if(l!=="--json"){if(l==="--chain"||l==="--blocks"){o+=1;continue}n.push(l)}}let r=(n[0]||"").trim();if(!r||r==="--help"||r==="-h")return process.stdout.write(`${mt}
16
+ `),r?0:1;let s=(ft(t,"--chain")||"ethereum").toLowerCase(),i=Qt[s]??Number(s);if(!H[i])return process.stderr.write(`follow: unsupported chain "${s}". Supported: ${Object.values(C).join(", ")}
17
+ `),1;let a=ft(t,"--blocks"),c=a?Number(a):4e4;if(!Number.isFinite(c)||c<=0)return process.stderr.write(`follow: --blocks must be a positive number, got "${a}"
18
+ `),1;try{let o=r,l=null;if(!it.test(r)){let d=await pt(r);if(!d?.address)return process.stderr.write(`follow: could not resolve "${r}" to an address
19
+ `),1;o=d.address,l=r}let f=await K(o,{chains:[i],lookback:c,onWarn:e?void 0:d=>process.stderr.write(` warn: ${d}
20
+ `)}),u=f.events||[];if(e)return process.stdout.write(`${JSON.stringify({address:o,resolvedFrom:l,chain:C[i]||String(i),lookbackBlocks:c,count:u.length,errors:f.errors||[],events:u})}
21
+ `),0;let m=l?`${l} ${o}`:o;process.stdout.write(`${m}
22
+ `),process.stdout.write(` ${C[i]||i} \xB7 last ${c} blocks \xB7 ${u.length} transfer${u.length===1?"":"s"}
23
+ `),u.length||process.stdout.write(` no ERC20 transfers in this window
24
+ `);for(let d of u.slice(0,25)){let p=d.to?.toLowerCase()===o.toLowerCase()?"in ":"out";process.stdout.write(` ${p} blk ${d.blockNumber} token ${d.token} ${te(d.value)}
25
+ `)}u.length>25&&process.stdout.write(` ... ${u.length-25} more (use --json for all)
26
+ `);for(let d of f.errors||[])process.stderr.write(` error: ${d.stage||"rpc"}: ${d.error}
27
+ `);return 0}catch(o){return process.stderr.write(`follow failed: ${o?.message||o}
28
+ `),1}}var ge={name:"follow",summary:"read a wallet's recent ERC20 transfer activity",group:"read",usage:mt,async run(t){return ee(t.argv||[])}};export{ge as default};
@@ -1,4 +1,4 @@
1
- import{readFileSync as b,existsSync as v}from"node:fs";import{Contract as x,JsonRpcProvider as A,verifyMessage as j}from"ethers";var i="0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75",p=999,O="https://rpc.hyperliquid.xyz/evm",w=["function balanceOf(address owner) view returns (uint256)"],R=300*1e3,$=720*60*1e3,y=/^0x[a-fA-F0-9]{40}$/;function f(r){return y.test(String(r||""))}async function d(r,{contract:n=i,rpc:t=O,chainId:o=p}={}){let c=new A(t,o,{staticNetwork:!0}),a=new x(n,w,c);return BigInt(await a.balanceOf(r))}import S from"node:os";import l from"node:path";import{fileURLToPath as E}from"node:url";var C=l.dirname(E(import.meta.url)),T=l.resolve(C,"../..");function L(){return process.env.ORACLE_FAKE_HOME||S.homedir()}function _(){return l.join(L(),".config","oracle")}function h(){return l.join(_(),"exec.env")}var g=`oracle gate \u2014 Locals Only holder check
1
+ import{readFileSync as v,existsSync as D}from"node:fs";import{Contract as O,JsonRpcProvider as A,verifyMessage as R}from"ethers";var l="0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75",p=999,y="https://rpc.hyperliquid.xyz/evm",E=["function balanceOf(address owner) view returns (uint256)"],I=300*1e3,$=720*60*1e3,S=/^0x[a-fA-F0-9]{40}$/;function f(r){return S.test(String(r||""))}async function d(r,{contract:n=l,rpc:t=y,chainId:o=p}={}){let a=new A(t,o,{staticNetwork:!0}),s=new O(n,E,a);return BigInt(await s.balanceOf(r))}import w from"node:os";import i from"node:path";import{fileURLToPath as C}from"node:url";var L=i.dirname(C(import.meta.url)),H=i.resolve(L,"../..");function h(){return process.env.ORACLE_FAKE_HOME||w.homedir()}function _(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function b(){return _()?process.env.ORACLE_CONFIG_DIR||i.join(h(),".config","oracle"):i.join(h(),".config","oracle")}function g(){return i.join(b(),"exec.env")}var x=`oracle gate \u2014 Locals Only holder check
2
2
 
3
3
  oracle gate status check the configured agent wallet
4
4
  oracle gate check <address> check any address
@@ -8,6 +8,6 @@ Access to Oracle is granted by holding a Locals Only NFT. This command reads a
8
8
  public balanceOf on HyperEVM; it does not sign, and it never sees a key.
9
9
 
10
10
  This is a local convenience check. Enforcement happens at distribution, where a
11
- signature proves you control the wallet before an install is issued.`;function k(r=h()){if(!v(r))return null;try{let n=b(r,"utf8");for(let t of n.split(`
12
- `)){let o=t.match(/^\s*(?:export\s+)?ORACLE_EVM_ADDRESS\s*=\s*(.+)\s*$/);if(!o)continue;let c=o[1].trim().replace(/^["']|["']$/g,"");if(f(c))return c}}catch{return null}return null}function e(r,n){r.write(n+`
13
- `)}async function D(r=[],n={}){let t=n.out??process.stdout,o=n.err??process.stderr,c=n.balanceOf??d,a=r[0];if(!a||a==="--help"||a==="-h"||a==="help")return e(t,g),0;if(a==="info")return e(t,`contract: ${i}`),e(t,`chain: HyperEVM (${p})`),e(t,"token: Locals Only (LOCALS)"),0;let s;if(a==="status"){if(s=n.agentAddress?n.agentAddress():k(),!s)return e(o,"no agent wallet configured (ORACLE_EVM_ADDRESS not set)"),e(o,"run: oracle init"),1}else if(a==="check"){if(s=r[1],!f(s))return e(o,"usage: oracle gate check <0x address>"),2}else return e(o,`oracle gate: unknown subcommand '${a}'`),2;let u;try{u=await c(s)}catch(m){return e(o,`could not reach HyperEVM to check the gate: ${m.message}`),3}return BigInt(u)>0n?(e(t,`holder: yes (${u})`),e(t,`wallet: ${s}`),0):(e(t,"holder: no"),e(t,`wallet: ${s}`),e(t,""),e(t,"Oracle access requires a Locals Only NFT on HyperEVM."),e(t,`contract: ${i}`),4)}var q="check Locals Only holder access for a wallet",z={name:"gate",summary:"check Locals Only holder access for a wallet",group:"read",usage:g,async run(r){return D(r.argv??[])}};export{k as agentAddress,z as default,q as help,D as run};
11
+ signature proves you control the wallet before an install is issued.`;function k(r=g()){if(!D(r))return null;try{let n=v(r,"utf8");for(let t of n.split(`
12
+ `)){let o=t.match(/^\s*(?:export\s+)?ORACLE_EVM_ADDRESS\s*=\s*(.+)\s*$/);if(!o)continue;let a=o[1].trim().replace(/^["']|["']$/g,"");if(f(a))return a}}catch{return null}return null}function e(r,n){r.write(n+`
13
+ `)}async function j(r=[],n={}){let t=n.out??process.stdout,o=n.err??process.stderr,a=n.balanceOf??d,s=r[0];if(!s||s==="--help"||s==="-h"||s==="help")return e(t,x),0;if(s==="info")return e(t,`contract: ${l}`),e(t,`chain: HyperEVM (${p})`),e(t,"token: Locals Only (LOCALS)"),0;let c;if(s==="status"){if(c=n.agentAddress?n.agentAddress():k(),!c)return e(o,"no agent wallet configured (ORACLE_EVM_ADDRESS not set)"),e(o,"run: oracle init"),1}else if(s==="check"){if(c=r[1],!f(c))return e(o,"usage: oracle gate check <0x address>"),2}else return e(o,`oracle gate: unknown subcommand '${s}'`),2;let u;try{u=await a(c)}catch(m){return e(o,`could not reach HyperEVM to check the gate: ${m.message}`),3}return BigInt(u)>0n?(e(t,`holder: yes (${u})`),e(t,`wallet: ${c}`),0):(e(t,"holder: no"),e(t,`wallet: ${c}`),e(t,""),e(t,"Oracle access requires a Locals Only NFT on HyperEVM."),e(t,`contract: ${l}`),4)}var z="check Locals Only holder access for a wallet",J={name:"gate",summary:"check Locals Only holder access for a wallet",group:"read",usage:x,async run(r){return j(r.argv??[])}};export{k as agentAddress,J as default,z as help,j as run};
@@ -0,0 +1,15 @@
1
+ import l from"node:fs";import i from"node:path";var E=Object.freeze({openrouter:{key:"OPENROUTER_API_KEY",baseUrl:"https://openrouter.ai/api/v1",model:"openrouter/auto"},openai:{key:"OPENAI_API_KEY",baseUrl:"https://api.openai.com/v1",model:"gpt-4.1-mini"},xai:{key:"XAI_API_KEY",baseUrl:"https://api.x.ai/v1",model:"grok-4-latest"},deepseek:{key:"DEEPSEEK_API_KEY",baseUrl:"https://api.deepseek.com/v1",model:"deepseek-chat"},gemini:{key:"GEMINI_API_KEY",alternateKey:"GOOGLE_API_KEY",baseUrl:"https://generativelanguage.googleapis.com/v1beta/openai",model:"gemini-2.5-flash"}}),h=Object.freeze({"anthropic-oauth":{key:"ANTHROPIC_API_KEY",baseUrl:"https://api.anthropic.com/v1",model:"claude-sonnet-4-20250514",protocol:"anthropic-messages"},"openai-codex":{key:"OPENAI_API_KEY",baseUrl:"https://chatgpt.com/backend-api/codex",model:"gpt-5.4",protocol:"responses"},"xai-oauth":{key:"XAI_API_KEY",baseUrl:"https://api.x.ai/v1",model:"grok-4-latest",protocol:"responses"}});var u=Object.freeze([{name:"oracle",bin:"oracle",label:"Oracle Native (default)",kind:"oracle"},{name:"hermes",bin:"hermes",label:"Hermes Agent",kind:"hermes"},{name:"opencode",bin:"opencode",label:"OpenCode",kind:"mcp"},{name:"claude",bin:"claude",label:"Claude Code",kind:"mcp"},{name:"codex",bin:"codex",label:"OpenAI Codex CLI",kind:"mcp"},{name:"cursor",bin:"cursor",label:"Cursor IDE",kind:"mcp"},{name:"windsurf",bin:"windsurf",label:"Windsurf",kind:"mcp"},{name:"aider",bin:"aider",label:"Aider",kind:"mcp"},{name:"continue",bin:"continue",label:"Continue",kind:"mcp"}]);function d(n){for(let t of(process.env.PATH||"").split(i.delimiter)){let e=i.join(t,n);try{if(l.existsSync(e))return e}catch{}}return null}function c(){let n=[];for(let t of u){if(t.name==="oracle"){n.push({...t,path:process.argv[1]||"oracle"});continue}let e=d(t.bin);e&&n.push({...t,path:e})}return n}function s(){return["oracle harness \u2014 detect installed agent harnesses",""," oracle harness detect scan PATH for Agent Plugins-compatible clients","","Oracle runs natively. If you prefer a different harness,","set ORACLE_CHAT_BACKEND=<name>.","","Detected: opencode, claude, codex, cursor, windsurf, aider, continue, hermes"].join(`
2
+ `)}var b={name:"harness",summary:"detect installed agent harnesses",usage:s,async main(n,t){let e=n[0];if(e==="help"||e==="--help"||e==="-h")return process.stdout.write(s()+`
3
+ `),0;if(e&&e!=="detect"&&e!=="list")return process.stderr.write(`oracle harness: unknown subcommand '${e}'
4
+ `),process.stderr.write(s()+`
5
+ `),1;let o=c();if(o.length===0)return process.stderr.write(`No agent harnesses detected on PATH.
6
+ `),process.stderr.write(`Oracle runs natively \u2014 no external agent required.
7
+ `),0;let p=o.find(r=>r.kind==="oracle"),a=o.filter(r=>r.kind!=="oracle");process.stdout.write(`
8
+ Oracle native chat: default
9
+
10
+ `),process.stdout.write(`Installed harnesses:
11
+ `);for(let r of a)process.stdout.write(` ${r.label.padEnd(22)} ${r.path}
12
+ `);return a.length===0&&process.stdout.write(` (none \u2014 Oracle runs standalone)
13
+ `),process.stdout.write(`
14
+ Set ORACLE_CHAT_BACKEND=<name> to use a different harness.
15
+ `),0}};export{b as default};
@@ -1,3 +1,3 @@
1
- import{spawnSync as i}from"node:child_process";import c from"node:path";var n=["oracle data serve # loopback read/prepare plane on 127.0.0.1:8787","oracle doctor # verify","oracle chat # premium oracle chat surface","oracle chain list # pick hyperliquid/base/solana/...","oracle setup # telegram/discord/slack messaging","oracle mcp install claude-code","# optional, explicit second step \u2014 signing stays a separate local package:","npm i -g @oracle-agent/operator","oracle sign init"];function a(){return["","Next:",...n.map(t=>" "+t),""].join(`
2
- `)}var g={name:"init",summary:"install agent lanes + read plane (dry-run by default)",group:"read",usage:"oracle init [--apply --force --only <lane> --json --yes]",async run(t){let r=[...t.argv];r.includes("--yes")&&!r.includes("--apply")&&r.push("--apply");let s=c.join(t.root,"bin","oracle-init.mjs"),e=i(process.execPath,[s,...r],{encoding:"utf8",env:process.env});if(e.error)return process.stderr.write(`oracle: failed to spawn oracle-init: ${e.error.message}
3
- `),1;e.stdout&&process.stdout.write(e.stdout),e.stderr&&process.stderr.write(e.stderr);let o=typeof e.status=="number"?e.status:1;return o===0&&r.includes("--apply")&&!r.includes("--json")&&process.stdout.write(a()),o}};export{g as default};
1
+ import{spawnSync as i}from"node:child_process";var n=["oracle data serve # loopback read/prepare plane on 127.0.0.1:8787","oracle doctor # verify","oracle chat # premium oracle chat surface","oracle chain list # pick hyperliquid/base/solana/...","oracle setup # telegram/discord/slack messaging","oracle mcp install claude-code","# optional, explicit second step \u2014 signing stays a separate local package:","npm i -g @oracle-agent/operator","oracle sign init"];function o(){return["","Next:",...n.map(t=>" "+t),""].join(`
2
+ `)}var d={name:"init",summary:"install agent lanes + read plane (dry-run by default)",group:"read",usage:"oracle init [--apply --force --only <lane> --json --yes]",async run(t){let r=[...t.argv];r.includes("--yes")&&!r.includes("--apply")&&r.push("--apply");let s=t.bin("oracle-init.mjs"),e=i(process.execPath,[s,...r],{encoding:"utf8",env:process.env});if(e.error)return process.stderr.write(`oracle: failed to spawn oracle-init: ${e.error.message}
3
+ `),1;e.stdout&&process.stdout.write(e.stdout),e.stderr&&process.stderr.write(e.stderr);let a=typeof e.status=="number"?e.status:1;return a===0&&r.includes("--apply")&&!r.includes("--json")&&process.stdout.write(o()),a}};export{d as default};
@@ -1,33 +1,60 @@
1
- import{parseArgs as ne}from"node:util";import P from"node:path";import{fileURLToPath as L}from"node:url";var G=P.dirname(L(import.meta.url)),ie=P.resolve(G,"../.."),ce=Object.freeze(["oracle-vault","oracle-credential","oracle-signer","oracle-runner","oracle-agentic-init","oracle-agentic-doctor","oracle-control-mcp","oracle-operator-caps"]),ae=Object.freeze(["vault","credential","signer","runner","sign"]),N=`oracle: signing is unavailable in the public package.
1
+ import{parseArgs as Oe}from"node:util";import G from"node:path";import{fileURLToPath as oe}from"node:url";var se=G.dirname(oe(import.meta.url)),Ae=G.resolve(se,"../.."),$e=Object.freeze(["oracle-vault","oracle-credential","oracle-signer","oracle-runner","oracle-agentic-init","oracle-agentic-doctor","oracle-control-mcp","oracle-operator-caps"]),Ne=Object.freeze(["vault","credential","signer","runner","sign"]),B=`oracle: signing is unavailable in the public package.
2
2
 
3
3
  The public 'oracle' package is prepare-only and never handles keys.
4
4
  Owner-operated signing is private infrastructure and has no public npm install.
5
5
  Review and sign prepared artifacts in your own wallet instead.
6
6
 
7
7
  Nothing about your read/research/prepare setup is affected.
8
- `;function h(e=process.stderr){e.write(N),N.endsWith(`
8
+ `;function O(e=process.stderr){e.write(B),B.endsWith(`
9
9
  `)||e.write(`
10
- `)}import{spawnSync as T}from"node:child_process";import J from"node:path";import g from"node:fs";import _ from"node:path";import q from"node:os";import R from"node:path";import{fileURLToPath as B}from"node:url";var U=R.dirname(B(import.meta.url)),A=R.resolve(U,"../..");function d(){return process.env.ORACLE_FAKE_HOME||q.homedir()}function m({oracleRoot:e=A,operator:t=null,withControl:r=!1}={}){let o={"oracle-data":{command:"node",args:[_.join(e,"bin","oracle-data-mcp.mjs")]}};if(r){if(!t||!t.ok)return{ok:!1,reason:"operator-missing"};let i=t.bins?.["oracle-control-mcp"]||t.controlMcp||null;if(!i)return{ok:!1,reason:"control-bin-missing"};o["oracle-control"]={command:"node",args:[i]}}return{ok:!0,specs:o}}function j(e){if(!g.existsSync(e))return null;let t=`${e}.bak-oracle-${Math.floor(Date.now()/1e3)}`;return g.copyFileSync(e,t),t}function K(e,t={}){return g.existsSync(e)?JSON.parse(g.readFileSync(e,"utf8")):structuredClone(t)}function W(e,t){g.mkdirSync(_.dirname(e),{recursive:!0}),g.writeFileSync(e,JSON.stringify(t,null,2)+`
11
- `)}function b(e,t){let r=K(e,{});(!r.mcpServers||typeof r.mcpServers!="object")&&(r.mcpServers={});let o=!1;for(let[u,n]of Object.entries(t)){let a=r.mcpServers[u];a&&JSON.stringify(a)===JSON.stringify(n)||(r.mcpServers[u]=n,o=!0)}if(!o)return{status:"present",backup:null};let i=j(e);return W(e,r),{status:"written",backup:i}}function f(e,t={}){return{status:e,...t}}function z(){return J.join(d(),".claude.json")}function Y(e){return J.join(e||process.cwd(),".mcp.json")}function V(e,t){let r=T("claude",["--version"],{encoding:"utf8",timeout:1e4});if(r.error||r.status!==0)return null;let o=T("claude",["mcp","add-json",e,JSON.stringify(t),"--scope","user"],{encoding:"utf8",timeout:3e4});return o.status!==0?{ok:!1,stderr:o.stderr||o.stdout||"failed"}:{ok:!0}}async function I({oracleRoot:e,operator:t,withControl:r=!1,project:o=!1,printOnly:i=!1,cwd:u=process.cwd()}){let n=m({oracleRoot:e,operator:t,withControl:r});if(!n.ok)return{ok:!1,code:3,reason:n.reason};if(i)return{ok:!0,print:{mcpServers:n.specs}};if(o){let p=Y(u),c=b(p,n.specs);return{ok:!0,...f(c.status,{path:p,backup:c.backup})}}let a=!1;for(let[p,c]of Object.entries(n.specs)){let k=V(p,c);if(k&&k.ok){a=!0;continue}break}if(a)return{ok:!0,...f("written",{method:"claude-cli"})};let l=z(),s=b(l,n.specs);return{ok:!0,...f(s.status,{path:l,backup:s.backup})}}import Q from"node:fs";import O from"node:path";function X(){return process.platform==="darwin"?O.join(d(),"Library","Application Support","Claude","claude_desktop_config.json"):O.join(d(),".config","Claude","claude_desktop_config.json")}async function w({oracleRoot:e,operator:t,withControl:r=!1,printOnly:o=!1}){let i=m({oracleRoot:e,operator:t,withControl:r});if(!i.ok)return{ok:!1,code:3,reason:i.reason};let u=X(),n={mcpServers:i.specs};if(o)return{ok:!0,print:n};let a=O.dirname(u);if(!Q.existsSync(a))return{ok:!0,status:"printed (Claude Desktop not detected)",path:u,print:n};let l=b(u,i.specs);return{ok:!0,...f(l.status,{path:u,backup:l.backup})}}import y from"node:fs";import $ from"node:path";var H="# oracle-mcp-install begin",D="# oracle-mcp-install end";function Z(){return $.join(d(),".codex","config.toml")}function ee(e){let t=[H];for(let[r,o]of Object.entries(e))t.push(`[mcp_servers.${r}]`),t.push(`command = ${JSON.stringify(o.command)}`),t.push(`args = [${o.args.map(i=>JSON.stringify(i)).join(", ")}]`),t.push("");return t.push(D),t.join(`
10
+ `)}import{spawnSync as W}from"node:child_process";import q from"node:path";import k from"node:fs";import y from"node:path";import pe from"node:os";import ie from"node:fs";import C from"node:path";import{fileURLToPath as ce}from"node:url";var ae=C.dirname(ce(import.meta.url)),v=C.resolve(ae,"../..");function _(e){let t=[C.join(v,"bin",e),C.join(v,"dist","bin",e),C.join(v,"..","bin",e)];return t.find(n=>ie.existsSync(n))||t[0]}function m(){return process.env.ORACLE_FAKE_HOME||pe.homedir()}function g({oracleRoot:e=v,operator:t=null,withControl:n=!1}={}){let r={"oracle-data":{command:"node",args:[e===v?_("oracle-data-mcp.mjs"):[y.join(e,"bin","oracle-data-mcp.mjs"),y.join(e,"dist","bin","oracle-data-mcp.mjs")].find(s=>k.existsSync(s))||y.join(e,"bin","oracle-data-mcp.mjs")]}};if(n){if(!t||!t.ok)return{ok:!1,reason:"operator-missing"};let s=t.bins?.["oracle-control-mcp"]||t.controlMcp||null;if(!s)return{ok:!1,reason:"control-bin-missing"};r["oracle-control"]={command:"node",args:[s]};let o=e===v?_("oracle-exec-mcp.mjs"):[y.join(e,"bin","oracle-exec-mcp.mjs"),y.join(e,"dist","bin","oracle-exec-mcp.mjs")].find(a=>k.existsSync(a))||y.join(e,"bin","oracle-exec-mcp.mjs");k.existsSync(o)&&(r["oracle-exec"]={command:"node",args:[o]})}return{ok:!0,specs:r}}function h(e){if(!k.existsSync(e))return null;let t=`${e}.bak-oracle-${Math.floor(Date.now()/1e3)}`;return k.copyFileSync(e,t),t}function R(e,t={}){return k.existsSync(e)?JSON.parse(k.readFileSync(e,"utf8")):structuredClone(t)}function T(e,t){k.mkdirSync(y.dirname(e),{recursive:!0}),k.writeFileSync(e,JSON.stringify(t,null,2)+`
11
+ `)}function b(e,t){let n=R(e,{});(!n.mcpServers||typeof n.mcpServers!="object")&&(n.mcpServers={});let i=!1;for(let[s,o]of Object.entries(t)){let a=n.mcpServers[s];a&&JSON.stringify(a)===JSON.stringify(o)||(n.mcpServers[s]=o,i=!0)}if(!i)return{status:"present",backup:null};let r=h(e);return T(e,n),{status:"written",backup:r}}function d(e,t={}){return{status:e,...t}}function ue(){return q.join(m(),".claude.json")}function le(e){return q.join(e||process.cwd(),".mcp.json")}function fe(e,t){let n=W("claude",["--version"],{encoding:"utf8",timeout:1e4});if(n.error||n.status!==0)return null;let i=W("claude",["mcp","add-json",e,JSON.stringify(t),"--scope","user"],{encoding:"utf8",timeout:3e4});return i.status!==0?{ok:!1,stderr:i.stderr||i.stdout||"failed"}:{ok:!0}}async function K({oracleRoot:e,operator:t,withControl:n=!1,project:i=!1,printOnly:r=!1,cwd:s=process.cwd()}){let o=g({oracleRoot:e,operator:t,withControl:n});if(!o.ok)return{ok:!1,code:3,reason:o.reason};if(r)return{ok:!0,print:{mcpServers:o.specs}};if(i){let c=le(s),l=b(c,o.specs);return{ok:!0,...d(l.status,{path:c,backup:l.backup})}}let a=!1;for(let[c,l]of Object.entries(o.specs)){let p=fe(c,l);if(p&&p.ok){a=!0;continue}break}if(a)return{ok:!0,...d("written",{method:"claude-cli"})};let f=ue(),u=b(f,o.specs);return{ok:!0,...d(u.status,{path:f,backup:u.backup})}}import de from"node:fs";import I from"node:path";function me(){return process.platform==="darwin"?I.join(m(),"Library","Application Support","Claude","claude_desktop_config.json"):I.join(m(),".config","Claude","claude_desktop_config.json")}async function J({oracleRoot:e,operator:t,withControl:n=!1,printOnly:i=!1}){let r=g({oracleRoot:e,operator:t,withControl:n});if(!r.ok)return{ok:!1,code:3,reason:r.reason};let s=me(),o={mcpServers:r.specs};if(i)return{ok:!0,print:o};let a=I.dirname(s);if(!de.existsSync(a))return{ok:!0,status:"printed (Claude Desktop not detected)",path:s,print:o};let f=b(s,r.specs);return{ok:!0,...d(f.status,{path:s,backup:f.backup})}}import E from"node:fs";import V from"node:path";var z="# oracle-mcp-install begin",Y="# oracle-mcp-install end";function ge(){return V.join(m(),".codex","config.toml")}function ke(e){let t=[z];for(let[n,i]of Object.entries(e))t.push(`[mcp_servers.${n}]`),t.push(`command = ${JSON.stringify(i.command)}`),t.push(`args = [${i.args.map(r=>JSON.stringify(r)).join(", ")}]`),t.push("");return t.push(Y),t.join(`
12
12
  `)+`
13
- `}function te(e){return e.replace(new RegExp(`${H}[\\s\\S]*?${D}\\n?`,"g"),"")}async function x({oracleRoot:e,operator:t,withControl:r=!1,printOnly:o=!1}){let i=m({oracleRoot:e,operator:t,withControl:r});if(!i.ok)return{ok:!1,code:3,reason:i.reason};let u=ee(i.specs),n=Z();if(o)return{ok:!0,printText:u,path:n};y.mkdirSync($.dirname(n),{recursive:!0});let a=y.existsSync(n)?y.readFileSync(n,"utf8"):"";if(a.includes(u.trim()))return{ok:!0,...f("present",{path:n,backup:null})};let s=(te(a).trimEnd()+`
14
-
15
- `+u).replace(/^\n+/,"");if(a.trim()===s.trim())return{ok:!0,...f("present",{path:n,backup:null})};let p=a?j(n):null;return y.writeFileSync(n,s.endsWith(`
16
- `)?s:s+`
17
- `),{ok:!0,...f("written",{path:n,backup:p})}}import M from"node:fs";import F from"node:path";var E="ChatGPT is hosted and can NEVER sign or reach your keys. This connector is read/prepare only; anything it prepares is unsigned until you sign it locally.";function re(){return{openapi:"3.1.0",info:{title:"Oracle Public (read/prepare)",version:"1.0.0",description:"Secret-free public surface for hosted clients. "+E},servers:[{url:"https://REPLACE-WITH-YOUR-TUNNEL"}],paths:{"/public/health":{get:{operationId:"publicHealth",summary:"Health check",responses:{200:{description:"ok"}}}},"/public/config":{get:{operationId:"publicConfig",summary:"Public config",responses:{200:{description:"ok"}}}},"/public/connect/request":{post:{operationId:"connectRequest",summary:"Build a connect request (unsigned)",responses:{200:{description:"unsigned request artifact"}}}},"/public/connect/assemble":{post:{operationId:"connectAssemble",summary:"Assemble an unsigned grant artifact",responses:{200:{description:"unsigned grant artifact"}}}},"/public/grants/active":{post:{operationId:"grantsActive",summary:"List active grants (read)",responses:{200:{description:"ok"}}}},"/public/grants/get":{post:{operationId:"grantsGet",summary:"Get a grant by id (read)",responses:{200:{description:"ok"}}}}}}}async function C({printOnly:e=!1}={}){let t=re(),r=F.join(d(),".config","oracle","connectors","chatgpt-openapi.json"),o=JSON.stringify(t,null,2)+`
18
- `;e||(M.mkdirSync(F.dirname(r),{recursive:!0}),M.writeFileSync(r,o));let i=[E,"","Next steps:"," 1. oracle public serve"," 2. Expose 127.0.0.1:8799 through YOUR HTTPS tunnel (cloudflared, tailscale funnel, etc.)."," Oracle will not create tunnels for you."," 3. Paste the OpenAPI spec into a GPT Action, or add the tunnel URL as a developer-mode MCP connector.",e?"":` Spec written to: ${r}`].filter(Boolean).join(`
19
- `);return{ok:!0,...f(e?"printed":"written",{path:r,print:t,instructions:i,cannotSign:E})}}function v(){process.stderr.write(`usage: oracle mcp <install|print> [target] [flags]
20
- targets: claude-code | claude-desktop | codex | chatgpt | generic
21
- flags: --with-control --project --print --json
22
- `)}function S(e,{json:t=!1}={}){if(e.print&&!e.instructions?process.stdout.write(JSON.stringify(e.print,null,2)+`
13
+ `}function he(e){return e.replace(new RegExp(`${z}[\\s\\S]*?${Y}\\n?`,"g"),"")}async function D({oracleRoot:e,operator:t,withControl:n=!1,printOnly:i=!1}){let r=g({oracleRoot:e,operator:t,withControl:n});if(!r.ok)return{ok:!1,code:3,reason:r.reason};let s=ke(r.specs),o=ge();if(i)return{ok:!0,printText:s,path:o};E.mkdirSync(V.dirname(o),{recursive:!0});let a=E.existsSync(o)?E.readFileSync(o,"utf8"):"";if(a.includes(s.trim()))return{ok:!0,...d("present",{path:o,backup:null})};let u=(he(a).trimEnd()+`
14
+
15
+ `+s).replace(/^\n+/,"");if(a.trim()===u.trim())return{ok:!0,...d("present",{path:o,backup:null})};let c=a?h(o):null;return E.writeFileSync(o,u.endsWith(`
16
+ `)?u:u+`
17
+ `),{ok:!0,...d("written",{path:o,backup:c})}}import Q from"node:fs";import X from"node:path";var L="ChatGPT is hosted and can NEVER sign or reach your keys. This connector is read/prepare only; anything it prepares is unsigned until you sign it locally.";function be(){return{openapi:"3.1.0",info:{title:"Oracle Public (read/prepare)",version:"1.0.0",description:"Secret-free public surface for hosted clients. "+L},servers:[{url:"https://REPLACE-WITH-YOUR-TUNNEL"}],paths:{"/public/health":{get:{operationId:"publicHealth",summary:"Health check",responses:{200:{description:"ok"}}}},"/public/config":{get:{operationId:"publicConfig",summary:"Public config",responses:{200:{description:"ok"}}}},"/public/connect/request":{post:{operationId:"connectRequest",summary:"Build a connect request (unsigned)",responses:{200:{description:"unsigned request artifact"}}}},"/public/connect/assemble":{post:{operationId:"connectAssemble",summary:"Assemble an unsigned grant artifact",responses:{200:{description:"unsigned grant artifact"}}}},"/public/grants/active":{post:{operationId:"grantsActive",summary:"List active grants (read)",responses:{200:{description:"ok"}}}},"/public/grants/get":{post:{operationId:"grantsGet",summary:"Get a grant by id (read)",responses:{200:{description:"ok"}}}}}}}async function M({printOnly:e=!1}={}){let t=be(),n=X.join(m(),".config","oracle","connectors","chatgpt-openapi.json"),i=JSON.stringify(t,null,2)+`
18
+ `;e||(Q.mkdirSync(X.dirname(n),{recursive:!0}),Q.writeFileSync(n,i));let r=[L,"","Next steps:"," 1. oracle public serve"," 2. Expose 127.0.0.1:8799 through YOUR HTTPS tunnel (cloudflared, tailscale funnel, etc.)."," Oracle will not create tunnels for you."," 3. Paste the OpenAPI spec into a GPT Action, or add the tunnel URL as a developer-mode MCP connector.",e?"":` Spec written to: ${n}`].filter(Boolean).join(`
19
+ `);return{ok:!0,...d(e?"printed":"written",{path:n,print:t,instructions:r,cannotSign:L})}}import H from"node:path";import Z from"node:os";function Se(){return process.platform==="darwin"?H.join(Z.homedir(),"Library","Application Support","Cursor","User","globalStorage","mcp.json"):process.platform==="win32"?H.join(Z.homedir(),"AppData","Roaming","Cursor","User","globalStorage","mcp.json"):H.join(m(),".config","cursor","mcp.json")}async function U({oracleRoot:e,operator:t,withControl:n=!1,project:i=!1,printOnly:r=!1,cwd:s=process.cwd()}){let o=g({oracleRoot:e,operator:t,withControl:n});if(!o.ok)return{ok:!1,code:3,reason:o.reason};if(r)return{ok:!0,printText:['Add this to your Cursor MCP config (Cmd+Shift+P \u2192 "MCP: Open Configuration"):',JSON.stringify({mcpServers:o.specs},null,2)].join(`
20
+
21
+ `)};let a=Se(),f=b(a,o.specs);return{ok:!0,...d(f.status,{path:a,backup:f.backup})}}import P from"node:path";import ee from"node:os";function je(){return process.platform==="darwin"?P.join(ee.homedir(),"Library","Application Support","Code","User","globalStorage","mcp.json"):process.platform==="win32"?P.join(ee.homedir(),"AppData","Roaming","Code","User","globalStorage","mcp.json"):P.join(m(),".config","Code","User","globalStorage","mcp.json")}function ve(e){return P.join(e||process.cwd(),".vscode","mcp.json")}async function F({oracleRoot:e,operator:t,withControl:n=!1,project:i=!1,printOnly:r=!1,cwd:s=process.cwd()}){let o=g({oracleRoot:e,operator:t,withControl:n});if(!o.ok)return{ok:!1,code:3,reason:o.reason};if(r)return{ok:!0,printText:["Add this to your VS Code MCP config (.vscode/mcp.json):",JSON.stringify({mcpServers:o.specs},null,2),"","Alternatively, add to VS Code settings.json:",`"mcp.servers": ${JSON.stringify(o.specs,null,2)}`].join(`
22
+ `)};let a=i?ve(s):je(),f=b(a,o.specs);return{ok:!0,...d(f.status,{path:a,backup:f.backup})}}import{readFileSync as $,existsSync as w,writeFileSync as A,mkdirSync as te}from"node:fs";import{join as S,dirname as ye}from"node:path";import{homedir as re}from"node:os";var we=S(ye(new URL(import.meta.url).pathname),"..","..","..","profiles","oracle","SOUL.md");function xe(){let e=[we,S(re(),".config","oracle","SOUL.md")];for(let t of e)if(w(t))return $(t,"utf8");throw new Error("SOUL.md not found \u2014 run 'oracle bootstrap' first")}async function ne(e,{cwd:t=process.cwd(),printOnly:n=!1}={}){let i=xe();if(e==="claude-code"||e==="claude"){let r=S(t,"CLAUDE.md"),s=w(r)?$(r,"utf8"):"",o=`# Oracle Agent Instructions
23
+ ${i}
24
+ ---
25
+ ${s}`;if(n)return{ok:!0,printText:`# Would write to ${r}:
26
+
27
+ ${o.slice(0,500)}...`,status:"printed"};let a=h(r);return A(r,o,"utf8"),{ok:!0,path:r,backup:a,status:"installed"}}if(e==="cursor"){let r=S(t,".cursorrules"),s=w(r)?$(r,"utf8"):"",o=`# Oracle Agent Instructions
28
+ ${i}
29
+ ---
30
+ ${s}`;if(n)return{ok:!0,printText:`# Would write to ${r}:
31
+
32
+ ${o.slice(0,500)}...`,status:"printed"};let a=h(r);return A(r,o,"utf8"),{ok:!0,path:r,backup:a,status:"installed"}}if(e==="claude-desktop"){let r=S(re(),"Library","Application Support","Claude","claude_desktop_config.json");if(!w(r))return{ok:!1,reason:"Claude Desktop config not found. Open Claude Desktop once first, then retry."};let s=R(r);if(n)return{ok:!0,printText:`# Would add Oracle SOUL to Claude Desktop custom instructions
33
+
34
+ ${i.slice(0,500)}...`,status:"printed"};let o=h(r);return s.customInstructions=s.customInstructions||"",s.customInstructions=`# Oracle Agent Instructions
35
+ ${i}
36
+ ---
37
+ ${s.customInstructions}`,T(r,s),{ok:!0,path:r,backup:o,status:"installed"}}if(e==="codex"||e==="copilot"){let r=S(t,".github"),s=S(r,"copilot-instructions.md"),o=w(s)?$(s,"utf8"):"";if(n)return{ok:!0,printText:`# Would write to ${s}:
38
+
39
+ ${i.slice(0,500)}...`,status:"printed"};w(r)||te(r,{recursive:!0});let a=h(s);return A(s,`${i}
40
+ ---
41
+ ${o}`,"utf8"),{ok:!0,path:s,backup:a,status:"installed"}}if(e==="vscode"||e==="vs-code"){let r=S(t,".vscode"),s=S(r,"instructions.md");if(n)return{ok:!0,printText:`# Would write to ${s}:
42
+
43
+ ${i.slice(0,500)}...`,status:"printed"};w(r)||te(r,{recursive:!0});let o=h(s);return A(s,`${i}
44
+ `,"utf8"),{ok:!0,path:s,backup:o,status:"installed"}}return{ok:!1,reason:`--with-soul not supported for target '${e}'`}}function N(){process.stderr.write(`usage: oracle mcp <install|print> [target] [flags]
45
+ targets: claude-code | claude-desktop | codex | copilot | chatgpt | cursor | vscode | generic
46
+ flags: --with-control --with-soul --project --print --json
47
+ `)}function x(e,{json:t=!1}={}){if(e.print&&!e.instructions?process.stdout.write(JSON.stringify(e.print,null,2)+`
23
48
  `):e.printText&&process.stdout.write(e.printText),e.instructions&&(process.stdout.write(e.instructions+`
24
49
  `),e.print&&t&&process.stdout.write(JSON.stringify(e.print,null,2)+`
25
- `)),!e.print&&!e.printText&&!e.instructions){let r={status:e.status,path:e.path||null,backup:e.backup||null,method:e.method||null};process.stdout.write((t?JSON.stringify(r,null,2):`${r.status}${r.path?" "+r.path:""}`)+`
26
- `)}}var Le={name:"mcp",summary:"wire Oracle into AI clients",group:"read",usage:"oracle mcp install <target> | oracle mcp print [--target <t>]",async run(e){let t=e.argv[0];if(!t||t==="--help"||t==="-h")return v(),t?0:1;let r,o;try{({values:r,positionals:o}=ne({args:e.argv.slice(1),options:{"with-control":{type:"boolean",default:!1},project:{type:"boolean",default:!1},print:{type:"boolean",default:!1},json:{type:"boolean",default:!1},target:{type:"string"}},allowPositionals:!0,strict:!1}))}catch(s){return process.stderr.write(`oracle mcp: ${s.message}
27
- `),v(),1}let i=!!r["with-control"],u=!!r.project,n=!!r.json,a=e.resolveOperator?e.resolveOperator():{ok:!1};if(i&&(!a||!a.ok))return h(process.stderr),3;let l={oracleRoot:e.root,operator:a,withControl:i,project:u,cwd:process.cwd()};if(t==="print"){let s=r.target||o[0]||"claude-code";if(s==="generic"||s==="claude-code"){let p=m(l);return p.ok?(process.stdout.write(JSON.stringify({mcpServers:p.specs},null,2)+`
28
- `),0):(h(process.stderr),3)}if(s==="chatgpt"){let p=await C({printOnly:!0});return S(p,{json:n}),0}return s==="codex"?(S(await x({...l,printOnly:!0}),{json:n}),0):s==="claude-desktop"?(S(await w({...l,printOnly:!0}),{json:n}),0):(process.stderr.write(`oracle mcp: unknown target '${s}'
29
- `),1)}if(t==="install"){let s=o[0]||r.target;if(!s)return v(),1;let p=!!r.print,c;if(s==="claude-code")c=await I({...l,printOnly:p});else if(s==="claude-desktop")c=await w({...l,printOnly:p});else if(s==="codex")c=await x({...l,printOnly:p});else if(s==="chatgpt")c=await C({printOnly:p});else if(s==="generic"){let k=m(l);return k.ok?(process.stdout.write(JSON.stringify({mcpServers:k.specs},null,2)+`
30
- `),0):(h(process.stderr),3)}else return process.stderr.write(`oracle mcp: unknown target '${s}'
31
- `),1;return c.ok?(S(c,{json:n}),c.status&&String(c.status).startsWith("printed")&&c.print&&process.stdout.write(JSON.stringify(c.print,null,2)+`
32
- `),0):(c.code===3?h(process.stderr):process.stderr.write(`oracle mcp: ${c.reason||"failed"}
33
- `),c.code||1)}return v(),1}};export{Le as default};
50
+ `)),!e.print&&!e.printText&&!e.instructions){let n={status:e.status,path:e.path||null,backup:e.backup||null,method:e.method||null};process.stdout.write((t?JSON.stringify(n,null,2):`${n.status}${n.path?" "+n.path:""}`)+`
51
+ `)}}var $t={name:"mcp",summary:"wire Oracle into AI clients",group:"read",usage:"oracle mcp install <target> [--with-control] [--with-soul] | oracle mcp print [--target <t>] | oracle mcp watchdog [--once]",async run(e){let t=e.argv[0];if(!t||t==="--help"||t==="-h")return N(),t?0:1;if(t==="watchdog"){let{spawn:c}=await import("node:child_process"),l=await import("node:path"),p=e.argv.includes("--once"),j=l.join(e.root,"bin","oracle-mcp-watchdog.mjs");return c(process.execPath,[j,...p?["--once"]:[]],{stdio:"inherit",detached:!0}).unref(),0}let n,i;try{({values:n,positionals:i}=Oe({args:e.argv.slice(1),options:{"with-control":{type:"boolean",default:!1},"with-soul":{type:"boolean",default:!1},project:{type:"boolean",default:!1},print:{type:"boolean",default:!1},json:{type:"boolean",default:!1},target:{type:"string"}},allowPositionals:!0,strict:!1}))}catch(c){return process.stderr.write(`oracle mcp: ${c.message}
52
+ `),N(),1}let r=!!n["with-control"],s=!!n["with-soul"],o=!!n.project,a=!!n.json,f=e.resolveOperator?e.resolveOperator():{ok:!1};if(r&&(!f||!f.ok))return O(process.stderr),3;let u={oracleRoot:e.root,operator:f,withControl:r,project:o,cwd:process.cwd()};if(t==="print"){let c=n.target||i[0]||"claude-code";if(c==="generic"||c==="claude-code"){let l=g(u);return l.ok?(process.stdout.write(JSON.stringify({mcpServers:l.specs},null,2)+`
53
+ `),0):(O(process.stderr),3)}if(c==="chatgpt"){let l=await M({printOnly:!0});return x(l,{json:a}),0}return c==="codex"||c==="copilot"?(x(await D({...u,printOnly:!0}),{json:a}),0):c==="claude-desktop"?(x(await J({...u,printOnly:!0}),{json:a}),0):c==="cursor"?(x(await U({...u,printOnly:!0}),{json:a}),0):c==="vscode"||c==="vs-code"?(x(await F({...u,printOnly:!0}),{json:a}),0):(process.stderr.write(`oracle mcp: unknown target '${c}'
54
+ `),1)}if(t==="install"){let c=i[0]||n.target;if(!c)return N(),1;let l=!!n.print,p;if(c==="claude-code")p=await K({...u,printOnly:l});else if(c==="claude-desktop")p=await J({...u,printOnly:l});else if(c==="codex"||c==="copilot")p=await D({...u,printOnly:l});else if(c==="chatgpt")p=await M({printOnly:l});else if(c==="cursor")p=await U({...u,printOnly:l});else if(c==="vscode"||c==="vs-code")p=await F({...u,printOnly:l});else if(c==="generic"){let j=g(u);return j.ok?(process.stdout.write(JSON.stringify({mcpServers:j.specs},null,2)+`
55
+ `),0):(O(process.stderr),3)}else return process.stderr.write(`oracle mcp: unknown target '${c}'
56
+ `),1;if(!p.ok)return p.code===3?O(process.stderr):process.stderr.write(`oracle mcp: ${p.reason||"failed"}
57
+ `),p.code||1;if(x(p,{json:a}),s){let j=await ne(c,{cwd:process.cwd(),printOnly:l});j.ok?process.stderr.write(` soul \u2192 ${j.path||"injected"}
58
+ `):process.stderr.write(` soul: ${j.reason||"failed"}
59
+ `)}return p.status&&String(p.status).startsWith("printed")&&p.print&&process.stdout.write(JSON.stringify(p.print,null,2)+`
60
+ `),0}return N(),1}};export{$t as default};