@oracle-agent/oracle 0.35.4 → 0.35.5

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.
@@ -97,7 +97,7 @@ does not prove npm users receive it. A locally hosted model/data/policy loop doe
97
97
  a bundled signer. A merged feature is not public until the npm artifact containing it is
98
98
  published and inspected.
99
99
 
100
- **Candidate release in this source tree:** public package `@oracle-agent/oracle@0.35.4`
100
+ **Candidate release in this source tree:** public package `@oracle-agent/oracle@0.35.5`
101
101
  ships the encrypted local vault + short-lived loopback signer. Hosted/keyless
102
102
  Oracle cannot hold keys or move funds. Self-host after `oracle sign init|import` is **auto-armed**
103
103
  for user-initiated actions. Public still charges the disclosed fee card; Administrator
@@ -1,50 +1,50 @@
1
1
  #!/usr/bin/env node
2
- var xr=Object.defineProperty;var w=(t,e,r)=>()=>{if(r)throw r[0];try{return t&&(e=t(t=0)),e}catch(n){throw r=[n],n}};var j=(t,e)=>{for(var r in e)xr(t,r,{get:e[r],enumerable:!0})};var qe={};j(qe,{A2ABus:()=>fe,normalizeName:()=>X});function X(t){return String(t||"").trim().toLowerCase().replace(/^@/,"")}var fe,We=w(()=>{fe=class{constructor({maxHops:e=4,historyCap:r=200}={}){this.maxHops=e,this.historyCap=r,this.agents=new Map,this.history=[],this.seq=0}register(e,{role:r="",chains:n=[],handler:o}={}){let a=X(e);if(!a)throw new Error("a2a: agent name required");if(this.agents.has(a))throw new Error(`a2a: agent '${a}' already registered`);if(typeof o!="function")throw new Error(`a2a: agent '${a}' needs a handler`);return this.agents.set(a,{name:a,role:String(r),chains:n.map(String),handler:o}),this.agents.get(a)}unregister(e){this.agents.delete(X(e))}roster(){return[...this.agents.values()].map(({name:e,role:r,chains:n})=>({name:e,role:r,chains:n}))}async send({from:e,to:r,text:n,kind:o="consult",hops:a=0}={}){let i=X(e),c=X(r);if(!i||!this.agents.has(i))return{ok:!1,error:`a2a: unknown sender '${e}'`};if(!c||!this.agents.has(c))return{ok:!1,error:`a2a: unknown recipient '${r}' (roster: ${[...this.agents.keys()].join(", ")||"empty"})`};if(c===i)return{ok:!1,error:"a2a: self-send refused"};let l=String(n||"").trim().slice(0,8e3);if(!l)return{ok:!1,error:"a2a: empty message"};let s=Number(a)+1;if(s>this.maxHops)return this.record({from:i,to:c,kind:o,dropped:"hop-limit"}),{ok:!1,error:`a2a: hop limit ${this.maxHops} reached \u2014 dropped`};let d={id:`a2a-${Date.now()}-${++this.seq}`,from:i,to:c,kind:String(o),text:l,hops:s,ts:new Date().toISOString()};this.record(d);try{let p=await this.agents.get(c).handler(d);return p&&this.record({id:`${d.id}-reply`,from:c,to:i,kind:"reply",text:String(p).slice(0,8e3),hops:s,ts:new Date().toISOString()}),{ok:!0,reply:p||null,id:d.id}}catch(p){return{ok:!1,error:`a2a: '${c}' handler failed: ${p.message}`}}}record(e){this.history.push(e),this.history.length>this.historyCap&&this.history.splice(0,this.history.length-this.historyCap)}recent(e=20){return this.history.slice(-e)}}});import Z from"node:fs";import vr from"node:os";import F from"node:path";import{fileURLToPath as Ar}from"node:url";function he(){return process.env.ORACLE_FAKE_HOME||vr.homedir()}function $r(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function $(){return $r()?process.env.ORACLE_CONFIG_DIR||F.join(he(),".config","oracle"):F.join(he(),".config","oracle")}function _r(){return F.join($(),"desk.json")}function Er(){return F.join($(),"env")}function B({force:t=!1}={}){if(B._done&&!t)return B._result||null;B._done=!0;let e={},r=(o,a)=>{if(a==null)return;let i=String(a).trim();i&&(process.env[o]!=null&&String(process.env[o]).trim()!==""||(process.env[o]=i,e[o]=i))};try{let o=Er();if(Z.existsSync(o))for(let a of Z.readFileSync(o,"utf8").split(/\r?\n/)){let i=a.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*?)\s*$/);if(!i||i[2].startsWith("#"))continue;let c=i[2];(c.startsWith('"')&&c.endsWith('"')||c.startsWith("'")&&c.endsWith("'"))&&(c=c.slice(1,-1)),r(i[1],c)}}catch{}try{let o=_r();if(Z.existsSync(o)){let a=JSON.parse(Z.readFileSync(o,"utf8"));a&&typeof a=="object"&&(r("ORACLE_DESK_URL",a.deskUrl||a.dataUrl||a.url),r("ORACLE_DATA_URL",a.dataUrl||a.deskUrl||a.url),r("ORACLE_API_URL",a.apiUrl||a.dataUrl||a.deskUrl),r("ORACLE_PUBLIC_URL",a.publicUrl||a.deskUrl||a.dataUrl),r("ORACLE_EXEC_URL",a.execUrl),r("MAD_DESK_URL",a.deskUrl||a.dataUrl))}}catch{}let n=process.env.ORACLE_DESK_URL||process.env.ORACLE_DATA_URL||"";return n&&(r("ORACLE_DESK_URL",n),r("ORACLE_DATA_URL",n),r("ORACLE_API_URL",n),r("ORACLE_PUBLIC_URL",n),r("MAD_DESK_URL",n)),B._result=Object.keys(e).length?e:null,B._result}function ae(t){return Z.mkdirSync(t,{recursive:!0}),t}var Cr,Fo,ie=w(()=>{Cr=F.dirname(Ar(import.meta.url)),Fo=F.resolve(Cr,"../..");try{B()}catch{}});function se(t){return String(t||"").trim()||void 0}function Rr(t,{required:e=!1}={}){let r=se(t)?.toLowerCase();if(!r){if(e)throw new Error("model provider is required");return}if(!Or.has(r))throw new Error(`unsupported provider: ${r}`);return r}function Lr(t,{required:e=!1}={}){let r=se(t);if(!r){if(e)throw new Error("model is required");return}if(r.includes("..")||r.startsWith("/")||!/^[a-zA-Z0-9._:/-]{1,200}$/.test(r))throw new Error("invalid model id");return r}function Nr(t){let e=se(t);if(!e||e.length>2048)throw new Error("invalid custom base URL");let r;try{r=new URL(e)}catch{throw new Error("invalid custom base URL")}let n=r.hostname.toLowerCase().replace(/^\[|\]$/g,""),o=n==="localhost"||n==="127.0.0.1"||n==="::1";if(r.protocol!=="https:"&&!(r.protocol==="http:"&&o)||r.username||r.password||r.search||r.hash)throw new Error("custom base URL must use HTTPS or loopback HTTP without credentials, query, or fragment");return r.toString().replace(/\/+$/,"")}function ze({provider:t,model:e,baseUrl:r}={},{requireModel:n=!1}={}){let o=Rr(t),a=Lr(e,{required:n});if(o==="custom")return{provider:o,...a?{model:a}:{},baseUrl:Nr(r)};if(se(r))throw new Error("baseUrl is only supported for the custom provider");return{...o?{provider:o}:{},...a?{model:a}:{}}}var Or,Ve=w(()=>{Or=new Set(["openrouter","openai","anthropic","xai","deepseek","gemini","kimi","mistral","nous","qwen","glm","local","ollama","custom","anthropic-oauth","openai-codex","xai-oauth"])});import G from"node:fs";import ge from"node:path";function Ke(){return ge.join($(),"model.json")}function H(t){return String(t||"").trim()||void 0}function Ye(t={}){let e=H(t.backend)?.toLowerCase()||"auto",r=ze({provider:t.provider,model:t.model,baseUrl:t.baseUrl},{requireModel:e==="standalone"}),n=H(t.apiKeyEnv),o=Number.parseInt(String(t.contextLength||""),10),a=H(t.reasoningEffort),i=H(t.computeHost||t.remoteHost),c=H(t.computeUser||t.remoteUser),l=H(t.computePath||t.remotePath);if(!Ir.has(e))throw new Error(`unsupported backend: ${e}`);if(process.env.ORACLE_PUBLIC_DESKTOP==="1"&&["remote","arch"].includes(e))throw new Error("remote compute backends are disabled in the public desktop");if(n&&!/^[A-Z][A-Z0-9_]*$/.test(n))throw new Error("api key env must be an uppercase environment variable name");if(e==="remote"&&!i)throw new Error("remote backend requires computeHost");return{backend:e,...r,...n?{apiKeyEnv:n}:{},...Number.isFinite(o)&&o>0?{contextLength:o}:{},...a?{reasoningEffort:a}:{},...i?{computeHost:i}:{},...c?{computeUser:c}:{},...l?{computePath:l}:{}}}function q(){let t=Ke();if(!G.existsSync(t))return null;try{return Ye(JSON.parse(G.readFileSync(t,"utf8")))}catch{return null}}function ye(t){let e=Ye(t),r=Ke();ae(ge.dirname(r)),process.platform!=="win32"&&G.chmodSync(ge.dirname(r),448);let n=`${r}.${process.pid}.tmp`;return G.writeFileSync(n,`${JSON.stringify(e,null,2)}
3
- `,{mode:384}),G.renameSync(n,r),process.platform!=="win32"&&G.chmodSync(r,384),e}var Ir,Je=w(()=>{ie();Ve();Ir=new Set(["auto","standalone","hermes","remote","arch"])});import{existsSync as Tr,readFileSync as Pr}from"node:fs";import{request as Ur}from"node:http";import Mr from"node:path";function jr(t=process.env){let e=String(t.ORACLE_SIGNER_URL||Dr).replace(/\/$/,""),r;try{r=new URL(e)}catch{return null}return r.hostname!=="127.0.0.1"&&r.hostname!=="localhost"&&r.hostname!=="::1"?null:r.origin}function Br(t=process.env){if(t.ORACLE_SIGNER_TOKEN)return String(t.ORACLE_SIGNER_TOKEN);let e=Mr.join($(),"signer","signer-token");return Tr(e)?Pr(e,"utf8").trim():null}function T(t,{method:e="GET",body:r=null,env:n=process.env,timeoutMs:o=4e3}={}){let a=jr(n),i=Br(n);return!a||!i?Promise.resolve({ok:!1,error:"local signer is not running"}):new Promise(c=>{let l=new URL(t,a),s=r?Buffer.from(JSON.stringify(r)):null,d=Ur({hostname:l.hostname,port:l.port||80,path:l.pathname,method:e,timeout:o,headers:{authorization:`Bearer ${i}`,origin:a,...s?{"content-type":"application/json","content-length":s.length}:{}}},p=>{let m=[];p.on("data",h=>m.push(h)),p.on("end",()=>{let h=Buffer.concat(m).toString("utf8"),g={};try{g=h?JSON.parse(h):{}}catch{g={error:"signer refused"}}c({httpStatus:p.statusCode,...g})})});d.on("timeout",()=>{d.destroy(),c({ok:!1,error:"local signer timed out"})}),d.on("error",()=>c({ok:!1,error:"local signer is not running"})),s&&d.write(s),d.end()})}var Dr,ce=w(()=>{ie();Dr="http://127.0.0.1:9462"});function Qe(t){return Hr.get(Number(t))||null}var Fr,Hr,Xe=w(()=>{Fr={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}},Hr=new Map(Object.values(Fr).map(t=>[t.chainId,t]))});function u(t){return S(t)?String(t).replace(Gr,e=>`\\${e}`):f}function S(t){return t==null?!1:typeof t=="number"?Number.isFinite(t):typeof t=="string"?t.trim()!=="":!0}function A(t){if(!S(t))return f;let e=String(t).replace(/`/g,"");return e===""?f:`\`${e}\``}function P(t,{decimals:e=2}={}){if(!S(t))return f;let r=Number(t);return Number.isFinite(r)?r.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:e}):f}function b(t,{decimals:e=2}={}){let r=P(t,{decimals:e});return r===f?f:`${r} USD`}function we(t,{decimals:e=2}={}){let r=P(t,{decimals:e});return r===f?f:`${r}%`}function le(t){let e=P(t,{decimals:0});return e===f?f:`${e} bps`}function U(t,e){if(!S(t))return f;let r=Number(e);if(!Number.isInteger(r)||r<0||r>77)return f;let n;try{n=BigInt(typeof t=="string"?t.trim():t)}catch{return f}let o=n<0n,a=o?-n:n,i=10n**BigInt(r),c=(a/i).toString(),l=(a%i).toString().padStart(r,"0").replace(/0+$/,"");return`${o?"-":""}${c}${l?`.${l}`:""}`}function ke(t){if(typeof t=="number"&&Number.isFinite(t))return t<0||t>1?f:t>=.75?"HIGH":t>=.4?"MEDIUM":"LOW";if(typeof t=="string"){let e=t.trim().toUpperCase();if(e==="HIGH"||e==="MEDIUM"||e==="LOW")return e}return f}function R(t={}){let e=t.chainId;if(!S(e)||!Number.isFinite(Number(e)))return S(t.chain)?u(t.chain):f;let n=Qe(e)?.name||(S(t.chain)?String(t.chain):f);return`${u(n)} (chainId ${Number(e)})`}function Ze(t={}){return u(t.venue??t.dex??t.pool?.venue)}function qr(t){return t==null?"NONE (text card only)":typeof t=="string"?t.trim()?A(t):"NONE (text card only)":t.error||t.ok===!1||t.available===!1?`UNAVAILABLE${S(t.error)?` \u2014 ${u(t.error)}`:""} (text card stands)`:S(t.url)?A(t.url):"NONE (text card only)"}function M(t={},{now:e=Date.now()}={}){let r=t.grant??t.session??null;if(!r||typeof r!="object")return{allowed:!1,reason:"no local grant/session",actions:[]};if(r.local===!1)return{allowed:!1,reason:"grant is not local",actions:[]};if(r.revoked===!0)return{allowed:!1,reason:"grant revoked",actions:[]};let n=r.expiresAt??r.expiry;if(S(n)){let a=typeof n=="number"?n:Date.parse(n);if(!Number.isFinite(a))return{allowed:!1,reason:"grant expiry unreadable",actions:[]};if(a<=e)return{allowed:!1,reason:"grant expired",actions:[]}}return{allowed:!0,reason:"valid local grant",actions:Array.isArray(r.actions)&&r.actions.length?r.actions.slice():["BUY","SELL"]}}function Wr(t){let e=M(t);return e.allowed?`${e.actions.map(r=>u(r)).join(" / ")} (${u(e.reason)})`:`prepare-only \u2014 ${u(e.reason)}`}function _(t,e,r={}){let n=[`*${t}*`];for(let[o,a]of e)n.push(`${o}: ${a==null||a===""?f:a}`);return n.push(`Chart: ${qr(r.chart)}`),n.push(`Actions: ${Wr(r)}`),Array.isArray(r.warnings)&&r.warnings.length&&n.push(`Warnings: ${r.warnings.map(o=>u(o)).join("; ")}`),(S(r.source)||S(r.fetchedAt))&&n.push(`Source: ${u(r.source)} at ${u(r.fetchedAt)}`),n.join(`
4
- `)}function E(t){return["Confidence",ke(t.confidence)]}function zr(t){let e=t.quote;if(!e||typeof e!="object")return[];let r=S(e.decimals)?U(e.amountOutRaw??e.out??e.raw,e.decimals):f;return[["Quote out (raw)",A(e.amountOutRaw??e.out??e.raw)],["Quote out",r===f?f:`${u(r)} ${u(e.symbol??"")}`.trim()]]}function et(t){let e=t.autoSlippage;if(!e||typeof e!="object")return["Auto-slippage",f];let r=le(e.selectedBps),n=le(e.capBps);return["Auto-slippage",r===f&&n===f?f:`${r} selected, cap ${n}`]}function Vr(t={}){let e=t||{};return _(`ORACLE TOKEN \u2014 ${u(e.symbol??e.token??e.name)}`,[["Chain",R(e)],["Venue",Ze(e)],["Name",u(e.name)],["Address",A(e.address??e.mint??e.contract)],["Price",b(e.priceUsd,{decimals:8})],["Market cap",b(e.marketCapUsd)],["Liquidity",b(e.liquidityUsd)],["Volume 24h",b(e.volume24hUsd)],["Change 24h",we(e.priceChange24h)],["Fee tier",S(e.feeTier)?`${le(Number(e.feeTier)/100)} (${P(e.feeTier,{decimals:0})})`:f],["Age",u(e.age)],...zr(e),et(e),E(e)],e)}function Kr(t={}){let e=t||{};return _(`ORACLE LAUNCH \u2014 ${u(e.symbol??e.token??e.name)}`,[["Chain",R(e)],["Venue",Ze(e)],["Address",A(e.address??e.mint??e.contract)],["Pool",A(e.pool?.address??e.poolAddress??e.pool)],["Liquidity",b(e.liquidityUsd)],["Route ready",u(e.routeReady)],["Sellable",u(e.sellable)],["Sell sim",u(e.sellSimulation??e.sellSim)],["Smart wallets",u(e.smartWalletOverlap)],["Risk",u(e.risk??e.riskStatus)],["Prepared ticket",u(e.preparedTicket??e.ticketStatus)],et(e),E(e)],e)}function Yr(t={}){let e=t||{};return _(`ORACLE HIP-3 \u2014 ${u(e.market??e.coin??e.name)}`,[["Venue",`Hyperliquid builder-dex ${u(e.dex)}`],["Market",u(e.market??e.coin)],["Mark",b(e.markPx,{decimals:6})],["Oracle",b(e.oraclePx,{decimals:6})],["Funding",we(e.funding,{decimals:6})],["Open interest",b(e.openInterestUsd)],["Depth",u(e.depth)],["Liquidation notes",u(e.liquidationNotes??e.riskNotes)],["Account context",u(e.accountContext)],E(e)],e)}function Jr(t={}){let e=t||{};return _(`ORACLE HIP-4 \u2014 ${u(e.event??e.market??e.name)}`,[["Venue",`Hyperliquid HIP-4 ${u(e.dex??"outcome")}`],["Event",u(e.event)],["Outcome",u(e.outcome)],["Market id",A(e.marketId??e.market)],["Bid",b(e.bid,{decimals:6})],["Ask",b(e.ask,{decimals:6})],["Depth",u(e.depth)],["Edge",we(e.edge)],["Position",u(e.position)],E(e)],e)}function Qr(t={}){let e=t||{};return _(`ORACLE POLYMARKET \u2014 ${u(e.event??e.market??e.name)}`,[["Venue","Polymarket CLOB"],["Event",u(e.event)],["Market",u(e.market)],["Market id",A(e.marketId??e.conditionId??e.tokenId)],["Yes",b(e.yesPrice,{decimals:4})],["No",b(e.noPrice,{decimals:4})],["Best bid / ask",`${b(e.bestBid,{decimals:4})} / ${b(e.bestAsk,{decimals:4})}`],["Volume",b(e.volumeUsd)],["Resolution risk",u(e.resolutionRisk)],["Order intent",u(e.orderIntent)],E(e)],e)}function Xr(t={}){let e=t||{},r=S(e.completedSplits)&&S(e.totalSplits)?`${P(e.completedSplits,{decimals:0})} / ${P(e.totalSplits,{decimals:0})}`:f;return _(`ORACLE TWAP \u2014 ${u(e.pair??e.symbol??e.name)}`,[["Chain",R(e)],["Side",u(e.side??e.direction)],["Amount",`${u(U(e.amountTotal??e.amount,e.decimals??18))} ${u(e.symbol??"")}`.trim()],["Splits",`${P(e.totalSplits,{decimals:0})} over ${u(e.window)}`],["Progress",r],["Avg price",b(e.averagePrice,{decimals:6})],["Next split",u(e.nextSplitAt)],["Slippage cap",le(e.slippageBps)],["Status",u(e.status)],E(e)],e)}function Zr(t={}){let e=t||{},r=e.approval??e.revokeCheck??{},n=r.needsRevoke&&r.spender?`revoke.cash \u2014 ${u(r.spender)}`:r.needsRevoke===!1?"revoke.cash \u2014 clean":"revoke.cash \u2014 unchecked";return _(`ORACLE BRIDGE \u2014 ${u(e.pair??e.fromSymbol)} \u2192 ${u(e.toSymbol??"")}`.replace(/→ $/,""),[["Bridging","deBridge \xB7 LI.FI \u2014 best route wins"],["From chain",R({chainId:e.fromChainId,chain:e.fromChain})],["To chain",R({chainId:e.toChainId,chain:e.toChain})],["Amount",`${u(U(e.amount,e.fromDecimals??18))} ${u(e.fromSymbol??"")}`.trim()],["Best route",u(e.bestRoute??e.winner)],["Est. received",`${u(U(e.amountOut,e.toDecimals??18))} ${u(e.toSymbol??"")}`.trim()],["Fee",b(e.feeUsd)],["Est. time",u(e.estimatedTime)],["Revoke check",n],["All providers",u(e.providers?.join(", "))],["Preparable",u(e.preparable)],E(e)],e)}function en(t){let r=(Array.isArray(t)?t:[]).slice(1,4).map(n=>{let o=u(n.source??n.venue??n.name),a=n.improvementBps==null&&n.deltaBps==null?null:Number(n.improvementBps??n.deltaBps),i=Number.isFinite(a)?`${Math.abs(a).toFixed(0)} bps behind`:"spread UNKNOWN";return`${o} (${i})`});return r.length?r.join("; "):f}function tn(t){let e=t.rankedOn??t.swap?.rankedOn??t.best?.rankedOn;return S(e)?u(e):f}function rn(t={}){let e=t||{},r=e.swap&&typeof e.swap=="object"?e.swap:e,n=e.bridge&&typeof e.bridge=="object"?e.bridge:null,o=r.best??r.winner??{},a=`${u(e.tokenInSymbol??e.fromSymbol??"IN")} \u2192 ${u(e.tokenOutSymbol??e.toSymbol??"OUT")}`,i=[["Intent",u(e.intent??"swap")],["Chain",R({chainId:e.chainId??r.chainId,chain:e.chain??r.chain})],["Pair",a],["Amount in",`${u(U(e.amountIn??r.amountIn,e.decimalsIn??18))} ${u(e.tokenInSymbol??"")}`.trim()],["Best swap",u(o.source??o.venue??r.bestRoute??e.bestRoute)],["Net out",`${u(U(o.netOut??o.amountOut??r.amountOut,e.decimalsOut??18))} ${u(e.tokenOutSymbol??"")}`.trim()],["Ranked on",tn(r)],["Gas accounted",u(o.costAccounted===!0?"yes":o.costAccounted===!1?"no \u2014 gross ranking may flatter this route":null)],["Spread vs next",S(r.improvementBps)?`${u(r.improvementBps)} bps`:f],["Runners-up",en(r.routes??e.routes)]];if(n){let c=n.best??n.winner??{};i.push(["Best bridge",u(c.source??n.bestRoute??e.bestBridge)],["Bridge out",`${u(U(c.netOut??c.amountOut??n.amountOut,e.bridgeDecimalsOut??e.decimalsOut??18))} ${u(e.bridgeOutSymbol??e.tokenOutSymbol??"")}`.trim()],["Bridge to",R({chainId:n.toChainId??e.toChainId,chain:n.toChain??e.toChain})],["Est. time",u(n.estimatedTime??c.meta?.durationSeconds)])}else i.push(["Best bridge","same-chain \u2014 use Best swap"]);return i.push(["Preparable",u(e.preparable??o.executionReady)],E(e)),_(`ORACLE SWAP \u2014 ${a}`,i,e)}function Se(t={}){let e=t||{};return _("ORACLE APPROVE \u2014 local signer",[["Pending id",A(e.id??(typeof e.digest=="string"?e.digest.slice(0,8):null))],["Surface",u(e.surface)],["Action",u(e.action)],["Chain",R({chainId:e.chain??e.chainId,chain:e.chainName})],["To",A(e.to??e.destination)],["Value",S(e.value)?u(e.value):f],["Signer",u(e.armed===!0?"running + armed":e.armed===!1?"running, disarmed":"not running")],E({confidence:e.confidence??(e.armed===!0?"high":"low")})],e)}function be({platform:t="telegram",id:e,digest:r,hasGrant:n=!1}={}){let o=String(e||(typeof r=="string"?r.slice(0,8):"")||"").trim();return n?o?String(t)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:[[{text:"Allow",callback_data:`oracle:approve:${o}`},{text:"Deny",callback_data:`oracle:deny:${o}`}]]},cancelHint:"Allow signs with the local signer. Deny drops the pending artifact."}:{kind:"text_menu",text:["1. Allow \u2014 reply /approve "+o,"2. Deny \u2014 reply /deny "+o].join(`
5
- `),cancelHint:"Cards are not available on this chat. Use /approve or /deny."}:{kind:"text_menu",text:"nothing to approve",cancelHint:""}:String(t)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:[]},cancelHint:"prepare-only \u2014 no local grant/session"}:{kind:"text_menu",text:"prepare-only \u2014 no local grant/session",cancelHint:""}}var f,ra,Gr,na,xe=w(()=>{Xe();f="UNKNOWN",ra=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),Gr=/[_*[\]`]/g;na=Object.freeze({token:Vr,launch:Kr,hip3:Yr,hip4:Jr,polymarket:Qr,twap:Xr,bridge:Zr,swap:rn,approve:Se})});function ve(t){let r=String(t||"").trim().match(/^\/(approve|deny|pending)(?:@[\w_]+)?(?:\s+([0-9a-fA-F]{4,64}))?\s*$/i);return r?{verb:r[1].toLowerCase(),id:r[2]?r[2].toLowerCase():null}:null}function Ae(t,{platform:e,grant:r,armed:n}){if(!t.length)return{text:"No pending local-signer artifacts.",buttons:be({platform:e,hasGrant:!1})};let o=t[0];return{text:t.map(i=>Se({...i,armed:n,grant:r,confidence:n?"high":"medium"})).join(`
2
+ var vr=Object.defineProperty;var w=(t,e,r)=>()=>{if(r)throw r[0];try{return t&&(e=t(t=0)),e}catch(n){throw r=[n],n}};var j=(t,e)=>{for(var r in e)vr(t,r,{get:e[r],enumerable:!0})};var We={};j(We,{A2ABus:()=>fe,normalizeName:()=>Q});function Q(t){return String(t||"").trim().toLowerCase().replace(/^@/,"")}var fe,ze=w(()=>{fe=class{constructor({maxHops:e=4,historyCap:r=200}={}){this.maxHops=e,this.historyCap=r,this.agents=new Map,this.history=[],this.seq=0}register(e,{role:r="",chains:n=[],handler:o}={}){let a=Q(e);if(!a)throw new Error("a2a: agent name required");if(this.agents.has(a))throw new Error(`a2a: agent '${a}' already registered`);if(typeof o!="function")throw new Error(`a2a: agent '${a}' needs a handler`);return this.agents.set(a,{name:a,role:String(r),chains:n.map(String),handler:o}),this.agents.get(a)}unregister(e){this.agents.delete(Q(e))}roster(){return[...this.agents.values()].map(({name:e,role:r,chains:n})=>({name:e,role:r,chains:n}))}async send({from:e,to:r,text:n,kind:o="consult",hops:a=0}={}){let i=Q(e),l=Q(r);if(!i||!this.agents.has(i))return{ok:!1,error:`a2a: unknown sender '${e}'`};if(!l||!this.agents.has(l))return{ok:!1,error:`a2a: unknown recipient '${r}' (roster: ${[...this.agents.keys()].join(", ")||"empty"})`};if(l===i)return{ok:!1,error:"a2a: self-send refused"};let c=String(n||"").trim().slice(0,8e3);if(!c)return{ok:!1,error:"a2a: empty message"};let s=Number(a)+1;if(s>this.maxHops)return this.record({from:i,to:l,kind:o,dropped:"hop-limit"}),{ok:!1,error:`a2a: hop limit ${this.maxHops} reached \u2014 dropped`};let d={id:`a2a-${Date.now()}-${++this.seq}`,from:i,to:l,kind:String(o),text:c,hops:s,ts:new Date().toISOString()};this.record(d);try{let p=await this.agents.get(l).handler(d);return p&&this.record({id:`${d.id}-reply`,from:l,to:i,kind:"reply",text:String(p).slice(0,8e3),hops:s,ts:new Date().toISOString()}),{ok:!0,reply:p||null,id:d.id}}catch(p){return{ok:!1,error:`a2a: '${l}' handler failed: ${p.message}`}}}record(e){this.history.push(e),this.history.length>this.historyCap&&this.history.splice(0,this.history.length-this.historyCap)}recent(e=20){return this.history.slice(-e)}}});import Z from"node:fs";import Ar from"node:os";import F from"node:path";import{fileURLToPath as Cr}from"node:url";function he(){return process.env.ORACLE_FAKE_HOME||Ar.homedir()}function _r(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function $(){return _r()?process.env.ORACLE_CONFIG_DIR||F.join(he(),".config","oracle"):F.join(he(),".config","oracle")}function Er(){return F.join($(),"desk.json")}function Or(){return F.join($(),"env")}function B({force:t=!1}={}){if(B._done&&!t)return B._result||null;B._done=!0;let e={},r=(o,a)=>{if(a==null)return;let i=String(a).trim();i&&(process.env[o]!=null&&String(process.env[o]).trim()!==""||(process.env[o]=i,e[o]=i))};try{let o=Or();if(Z.existsSync(o))for(let a of Z.readFileSync(o,"utf8").split(/\r?\n/)){let i=a.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*?)\s*$/);if(!i||i[2].startsWith("#"))continue;let l=i[2];(l.startsWith('"')&&l.endsWith('"')||l.startsWith("'")&&l.endsWith("'"))&&(l=l.slice(1,-1)),r(i[1],l)}}catch{}try{let o=Er();if(Z.existsSync(o)){let a=JSON.parse(Z.readFileSync(o,"utf8"));a&&typeof a=="object"&&(r("ORACLE_DESK_URL",a.deskUrl||a.dataUrl||a.url),r("ORACLE_DATA_URL",a.dataUrl||a.deskUrl||a.url),r("ORACLE_API_URL",a.apiUrl||a.dataUrl||a.deskUrl),r("ORACLE_PUBLIC_URL",a.publicUrl||a.deskUrl||a.dataUrl),r("ORACLE_EXEC_URL",a.execUrl),r("MAD_DESK_URL",a.deskUrl||a.dataUrl))}}catch{}let n=process.env.ORACLE_DESK_URL||process.env.ORACLE_DATA_URL||"";return n&&(r("ORACLE_DESK_URL",n),r("ORACLE_DATA_URL",n),r("ORACLE_API_URL",n),r("ORACLE_PUBLIC_URL",n),r("MAD_DESK_URL",n)),B._result=Object.keys(e).length?e:null,B._result}function ae(t){return Z.mkdirSync(t,{recursive:!0}),t}var $r,Go,ie=w(()=>{$r=F.dirname(Cr(import.meta.url)),Go=F.resolve($r,"../..");try{B()}catch{}});function se(t){return String(t||"").trim()||void 0}function Nr(t,{required:e=!1}={}){let r=se(t)?.toLowerCase();if(!r){if(e)throw new Error("model provider is required");return}if(!Rr.has(r))throw new Error(`unsupported provider: ${r}`);return r}function Lr(t,{required:e=!1}={}){let r=se(t);if(!r){if(e)throw new Error("model is required");return}if(r.includes("..")||r.startsWith("/")||!/^[a-zA-Z0-9._:/-]{1,200}$/.test(r))throw new Error("invalid model id");return r}function Ir(t){let e=se(t);if(!e||e.length>2048)throw new Error("invalid custom base URL");let r;try{r=new URL(e)}catch{throw new Error("invalid custom base URL")}let n=r.hostname.toLowerCase().replace(/^\[|\]$/g,""),o=n==="localhost"||n==="127.0.0.1"||n==="::1";if(r.protocol!=="https:"&&!(r.protocol==="http:"&&o)||r.username||r.password||r.search||r.hash)throw new Error("custom base URL must use HTTPS or loopback HTTP without credentials, query, or fragment");return r.toString().replace(/\/+$/,"")}function Ve({provider:t,model:e,baseUrl:r}={},{requireModel:n=!1}={}){let o=Nr(t),a=Lr(e,{required:n});if(o==="custom")return{provider:o,...a?{model:a}:{},baseUrl:Ir(r)};if(se(r))throw new Error("baseUrl is only supported for the custom provider");return{...o?{provider:o}:{},...a?{model:a}:{}}}var Rr,Ke=w(()=>{Rr=new Set(["openrouter","openai","anthropic","xai","deepseek","gemini","kimi","mistral","nous","qwen","glm","local","ollama","custom","anthropic-oauth","openai-codex","xai-oauth"])});import G from"node:fs";import ge from"node:path";function Ye(){return ge.join($(),"model.json")}function H(t){return String(t||"").trim()||void 0}function Je(t={}){let e=H(t.backend)?.toLowerCase()||"auto",r=Ve({provider:t.provider,model:t.model,baseUrl:t.baseUrl},{requireModel:e==="standalone"}),n=H(t.apiKeyEnv),o=Number.parseInt(String(t.contextLength||""),10),a=H(t.reasoningEffort),i=H(t.computeHost||t.remoteHost),l=H(t.computeUser||t.remoteUser),c=H(t.computePath||t.remotePath);if(!Tr.has(e))throw new Error(`unsupported backend: ${e}`);if(process.env.ORACLE_PUBLIC_DESKTOP==="1"&&["remote","arch"].includes(e))throw new Error("remote compute backends are disabled in the public desktop");if(n&&!/^[A-Z][A-Z0-9_]*$/.test(n))throw new Error("api key env must be an uppercase environment variable name");if(e==="remote"&&!i)throw new Error("remote backend requires computeHost");return{backend:e,...r,...n?{apiKeyEnv:n}:{},...Number.isFinite(o)&&o>0?{contextLength:o}:{},...a?{reasoningEffort:a}:{},...i?{computeHost:i}:{},...l?{computeUser:l}:{},...c?{computePath:c}:{}}}function q(){let t=Ye();if(!G.existsSync(t))return null;try{return Je(JSON.parse(G.readFileSync(t,"utf8")))}catch{return null}}function ye(t){let e=Je(t),r=Ye();ae(ge.dirname(r)),process.platform!=="win32"&&G.chmodSync(ge.dirname(r),448);let n=`${r}.${process.pid}.tmp`;return G.writeFileSync(n,`${JSON.stringify(e,null,2)}
3
+ `,{mode:384}),G.renameSync(n,r),process.platform!=="win32"&&G.chmodSync(r,384),e}var Tr,Xe=w(()=>{ie();Ke();Tr=new Set(["auto","standalone","hermes","remote","arch"])});import{existsSync as Pr,readFileSync as Mr}from"node:fs";import{request as Ur}from"node:http";import Dr from"node:path";function Br(t=process.env){let e=String(t.ORACLE_SIGNER_URL||jr).replace(/\/$/,""),r;try{r=new URL(e)}catch{return null}return r.hostname!=="127.0.0.1"&&r.hostname!=="localhost"&&r.hostname!=="::1"?null:r.origin}function Fr(t=process.env){if(t.ORACLE_SIGNER_TOKEN)return String(t.ORACLE_SIGNER_TOKEN);let e=Dr.join($(),"signer","signer-token");return Pr(e)?Mr(e,"utf8").trim():null}function T(t,{method:e="GET",body:r=null,env:n=process.env,timeoutMs:o=4e3}={}){let a=Br(n),i=Fr(n);return!a||!i?Promise.resolve({ok:!1,error:"local signer is not running"}):new Promise(l=>{let c=new URL(t,a),s=r?Buffer.from(JSON.stringify(r)):null,d=Ur({hostname:c.hostname,port:c.port||80,path:c.pathname,method:e,timeout:o,headers:{authorization:`Bearer ${i}`,origin:a,...s?{"content-type":"application/json","content-length":s.length}:{}}},p=>{let m=[];p.on("data",h=>m.push(h)),p.on("end",()=>{let h=Buffer.concat(m).toString("utf8"),g={};try{g=h?JSON.parse(h):{}}catch{g={error:"signer refused"}}l({httpStatus:p.statusCode,...g})})});d.on("timeout",()=>{d.destroy(),l({ok:!1,error:"local signer timed out"})}),d.on("error",()=>l({ok:!1,error:"local signer is not running"})),s&&d.write(s),d.end()})}var jr,ce=w(()=>{ie();jr="http://127.0.0.1:9462"});function Qe(t){return Gr.get(Number(t))||null}var Hr,Gr,Ze=w(()=>{Hr={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}},Gr=new Map(Object.values(Hr).map(t=>[t.chainId,t]))});function Wr(t){let e=String(t||"").trim();if(!e||e.includes("ts.net")||!/^https:\/\//i.test(e))return null;try{return new URL(e)}catch{return null}}function et(t,{coin:e,side:r,sizeUsd:n,leverage:o,venue:a,confirm:i,user:l}={}){let c=Wr(t);if(!c)return null;if(e&&qr.test(String(e).toUpperCase())&&c.searchParams.set("coin",String(e).toUpperCase()),(r==="long"||r==="short")&&c.searchParams.set("side",r),Number.isFinite(Number(n))&&Number(n)>=1&&c.searchParams.set("size",String(Math.min(1e5,Math.round(Number(n))))),Number.isInteger(Number(o))&&Number(o)>=1&&c.searchParams.set("lev",String(Math.min(50,Number(o)))),a){let s=String(a).toLowerCase()==="hl"?"hyperliquid":String(a).toLowerCase();c.searchParams.set("venue",s)}else c.searchParams.get("venue")||c.searchParams.set("venue","hyperliquid");return c.searchParams.set("view","perps"),c.searchParams.set("build","1"),i&&/^[0-9a-f]{32}$/i.test(String(i))&&c.searchParams.set("confirm",String(i).toLowerCase()),l&&/^0x[0-9a-fA-F]{40}$/.test(String(l))&&c.searchParams.set("user",String(l).toLowerCase()),c.toString()}var qr,we=w(()=>{qr=/^[A-Z0-9][A-Z0-9._-]{0,11}$/});var ia,sa,tt=w(()=>{we();ia=Object.freeze([100,50,25]),sa=Object.freeze([100,50,25,10])});function u(t){return S(t)?String(t).replace(zr,e=>`\\${e}`):f}function S(t){return t==null?!1:typeof t=="number"?Number.isFinite(t):typeof t=="string"?t.trim()!=="":!0}function A(t){if(!S(t))return f;let e=String(t).replace(/`/g,"");return e===""?f:`\`${e}\``}function P(t,{decimals:e=2}={}){if(!S(t))return f;let r=Number(t);return Number.isFinite(r)?r.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:e}):f}function b(t,{decimals:e=2}={}){let r=P(t,{decimals:e});return r===f?f:`${r} USD`}function ke(t,{decimals:e=2}={}){let r=P(t,{decimals:e});return r===f?f:`${r}%`}function le(t){let e=P(t,{decimals:0});return e===f?f:`${e} bps`}function M(t,e){if(!S(t))return f;let r=Number(e);if(!Number.isInteger(r)||r<0||r>77)return f;let n;try{n=BigInt(typeof t=="string"?t.trim():t)}catch{return f}let o=n<0n,a=o?-n:n,i=10n**BigInt(r),l=(a/i).toString(),c=(a%i).toString().padStart(r,"0").replace(/0+$/,"");return`${o?"-":""}${l}${c?`.${c}`:""}`}function Se(t){if(typeof t=="number"&&Number.isFinite(t))return t<0||t>1?f:t>=.75?"HIGH":t>=.4?"MEDIUM":"LOW";if(typeof t=="string"){let e=t.trim().toUpperCase();if(e==="HIGH"||e==="MEDIUM"||e==="LOW")return e}return f}function R(t={}){let e=t.chainId;if(!S(e)||!Number.isFinite(Number(e)))return S(t.chain)?u(t.chain):f;let n=Qe(e)?.name||(S(t.chain)?String(t.chain):f);return`${u(n)} (chainId ${Number(e)})`}function rt(t={}){return u(t.venue??t.dex??t.pool?.venue)}function Vr(t){return t==null?"NONE (text card only)":typeof t=="string"?t.trim()?A(t):"NONE (text card only)":t.error||t.ok===!1||t.available===!1?`UNAVAILABLE${S(t.error)?` \u2014 ${u(t.error)}`:""} (text card stands)`:S(t.url)?A(t.url):"NONE (text card only)"}function U(t={},{now:e=Date.now()}={}){let r=t.grant??t.session??null;if(!r||typeof r!="object")return{allowed:!1,reason:"no local grant/session",actions:[]};if(r.local===!1)return{allowed:!1,reason:"grant is not local",actions:[]};if(r.revoked===!0)return{allowed:!1,reason:"grant revoked",actions:[]};let n=r.expiresAt??r.expiry;if(S(n)){let a=typeof n=="number"?n:Date.parse(n);if(!Number.isFinite(a))return{allowed:!1,reason:"grant expiry unreadable",actions:[]};if(a<=e)return{allowed:!1,reason:"grant expired",actions:[]}}return{allowed:!0,reason:"valid local grant",actions:Array.isArray(r.actions)&&r.actions.length?r.actions.slice():["BUY","SELL"]}}function Kr(t){let e=U(t);return e.allowed?`${e.actions.map(r=>u(r)).join(" / ")} (${u(e.reason)})`:`prepare-only \u2014 ${u(e.reason)}`}function _(t,e,r={}){let n=[`*${t}*`];for(let[o,a]of e)n.push(`${o}: ${a==null||a===""?f:a}`);return n.push(`Chart: ${Vr(r.chart)}`),n.push(`Actions: ${Kr(r)}`),Array.isArray(r.warnings)&&r.warnings.length&&n.push(`Warnings: ${r.warnings.map(o=>u(o)).join("; ")}`),(S(r.source)||S(r.fetchedAt))&&n.push(`Source: ${u(r.source)} at ${u(r.fetchedAt)}`),n.join(`
4
+ `)}function E(t){return["Confidence",Se(t.confidence)]}function Yr(t){let e=t.quote;if(!e||typeof e!="object")return[];let r=S(e.decimals)?M(e.amountOutRaw??e.out??e.raw,e.decimals):f;return[["Quote out (raw)",A(e.amountOutRaw??e.out??e.raw)],["Quote out",r===f?f:`${u(r)} ${u(e.symbol??"")}`.trim()]]}function nt(t){let e=t.autoSlippage;if(!e||typeof e!="object")return["Auto-slippage",f];let r=le(e.selectedBps),n=le(e.capBps);return["Auto-slippage",r===f&&n===f?f:`${r} selected, cap ${n}`]}function Jr(t={}){let e=t||{};return _(`ORACLE TOKEN \u2014 ${u(e.symbol??e.token??e.name)}`,[["Chain",R(e)],["Venue",rt(e)],["Name",u(e.name)],["Address",A(e.address??e.mint??e.contract)],["Price",b(e.priceUsd,{decimals:8})],["Market cap",b(e.marketCapUsd)],["Liquidity",b(e.liquidityUsd)],["Volume 24h",b(e.volume24hUsd)],["Change 24h",ke(e.priceChange24h)],["Fee tier",S(e.feeTier)?`${le(Number(e.feeTier)/100)} (${P(e.feeTier,{decimals:0})})`:f],["Age",u(e.age)],...Yr(e),nt(e),E(e)],e)}function Xr(t={}){let e=t||{};return _(`ORACLE LAUNCH \u2014 ${u(e.symbol??e.token??e.name)}`,[["Chain",R(e)],["Venue",rt(e)],["Address",A(e.address??e.mint??e.contract)],["Pool",A(e.pool?.address??e.poolAddress??e.pool)],["Liquidity",b(e.liquidityUsd)],["Route ready",u(e.routeReady)],["Sellable",u(e.sellable)],["Sell sim",u(e.sellSimulation??e.sellSim)],["Smart wallets",u(e.smartWalletOverlap)],["Risk",u(e.risk??e.riskStatus)],["Prepared ticket",u(e.preparedTicket??e.ticketStatus)],nt(e),E(e)],e)}function Qr(t={}){let e=t||{};return _(`ORACLE HIP-3 \u2014 ${u(e.market??e.coin??e.name)}`,[["Venue",`Hyperliquid builder-dex ${u(e.dex)}`],["Market",u(e.market??e.coin)],["Mark",b(e.markPx,{decimals:6})],["Oracle",b(e.oraclePx,{decimals:6})],["Funding",ke(e.funding,{decimals:6})],["Open interest",b(e.openInterestUsd)],["Depth",u(e.depth)],["Liquidation notes",u(e.liquidationNotes??e.riskNotes)],["Account context",u(e.accountContext)],E(e)],e)}function Zr(t={}){let e=t||{};return _(`ORACLE HIP-4 \u2014 ${u(e.event??e.market??e.name)}`,[["Venue",`Hyperliquid HIP-4 ${u(e.dex??"outcome")}`],["Event",u(e.event)],["Outcome",u(e.outcome)],["Market id",A(e.marketId??e.market)],["Bid",b(e.bid,{decimals:6})],["Ask",b(e.ask,{decimals:6})],["Depth",u(e.depth)],["Edge",ke(e.edge)],["Position",u(e.position)],E(e)],e)}function en(t={}){let e=t||{};return _(`ORACLE POLYMARKET \u2014 ${u(e.event??e.market??e.name)}`,[["Venue","Polymarket CLOB"],["Event",u(e.event)],["Market",u(e.market)],["Market id",A(e.marketId??e.conditionId??e.tokenId)],["Yes",b(e.yesPrice,{decimals:4})],["No",b(e.noPrice,{decimals:4})],["Best bid / ask",`${b(e.bestBid,{decimals:4})} / ${b(e.bestAsk,{decimals:4})}`],["Volume",b(e.volumeUsd)],["Resolution risk",u(e.resolutionRisk)],["Order intent",u(e.orderIntent)],E(e)],e)}function tn(t={}){let e=t||{},r=S(e.completedSplits)&&S(e.totalSplits)?`${P(e.completedSplits,{decimals:0})} / ${P(e.totalSplits,{decimals:0})}`:f;return _(`ORACLE TWAP \u2014 ${u(e.pair??e.symbol??e.name)}`,[["Chain",R(e)],["Side",u(e.side??e.direction)],["Amount",`${u(M(e.amountTotal??e.amount,e.decimals??18))} ${u(e.symbol??"")}`.trim()],["Splits",`${P(e.totalSplits,{decimals:0})} over ${u(e.window)}`],["Progress",r],["Avg price",b(e.averagePrice,{decimals:6})],["Next split",u(e.nextSplitAt)],["Slippage cap",le(e.slippageBps)],["Status",u(e.status)],E(e)],e)}function rn(t={}){let e=t||{},r=e.approval??e.revokeCheck??{},n=r.needsRevoke&&r.spender?`revoke.cash \u2014 ${u(r.spender)}`:r.needsRevoke===!1?"revoke.cash \u2014 clean":"revoke.cash \u2014 unchecked";return _(`ORACLE BRIDGE \u2014 ${u(e.pair??e.fromSymbol)} \u2192 ${u(e.toSymbol??"")}`.replace(/→ $/,""),[["Bridging","deBridge \xB7 LI.FI \u2014 best route wins"],["From chain",R({chainId:e.fromChainId,chain:e.fromChain})],["To chain",R({chainId:e.toChainId,chain:e.toChain})],["Amount",`${u(M(e.amount,e.fromDecimals??18))} ${u(e.fromSymbol??"")}`.trim()],["Best route",u(e.bestRoute??e.winner)],["Est. received",`${u(M(e.amountOut,e.toDecimals??18))} ${u(e.toSymbol??"")}`.trim()],["Fee",b(e.feeUsd)],["Est. time",u(e.estimatedTime)],["Revoke check",n],["All providers",u(e.providers?.join(", "))],["Preparable",u(e.preparable)],E(e)],e)}function nn(t){let r=(Array.isArray(t)?t:[]).slice(1,4).map(n=>{let o=u(n.source??n.venue??n.name),a=n.improvementBps==null&&n.deltaBps==null?null:Number(n.improvementBps??n.deltaBps),i=Number.isFinite(a)?`${Math.abs(a).toFixed(0)} bps behind`:"spread UNKNOWN";return`${o} (${i})`});return r.length?r.join("; "):f}function on(t){let e=t.rankedOn??t.swap?.rankedOn??t.best?.rankedOn;return S(e)?u(e):f}function an(t={}){let e=t||{},r=e.swap&&typeof e.swap=="object"?e.swap:e,n=e.bridge&&typeof e.bridge=="object"?e.bridge:null,o=r.best??r.winner??{},a=`${u(e.tokenInSymbol??e.fromSymbol??"IN")} \u2192 ${u(e.tokenOutSymbol??e.toSymbol??"OUT")}`,i=[["Intent",u(e.intent??"swap")],["Chain",R({chainId:e.chainId??r.chainId,chain:e.chain??r.chain})],["Pair",a],["Amount in",`${u(M(e.amountIn??r.amountIn,e.decimalsIn??18))} ${u(e.tokenInSymbol??"")}`.trim()],["Best swap",u(o.source??o.venue??r.bestRoute??e.bestRoute)],["Net out",`${u(M(o.netOut??o.amountOut??r.amountOut,e.decimalsOut??18))} ${u(e.tokenOutSymbol??"")}`.trim()],["Ranked on",on(r)],["Gas accounted",u(o.costAccounted===!0?"yes":o.costAccounted===!1?"no \u2014 gross ranking may flatter this route":null)],["Spread vs next",S(r.improvementBps)?`${u(r.improvementBps)} bps`:f],["Runners-up",nn(r.routes??e.routes)]];if(n){let l=n.best??n.winner??{};i.push(["Best bridge",u(l.source??n.bestRoute??e.bestBridge)],["Bridge out",`${u(M(l.netOut??l.amountOut??n.amountOut,e.bridgeDecimalsOut??e.decimalsOut??18))} ${u(e.bridgeOutSymbol??e.tokenOutSymbol??"")}`.trim()],["Bridge to",R({chainId:n.toChainId??e.toChainId,chain:n.toChain??e.toChain})],["Est. time",u(n.estimatedTime??l.meta?.durationSeconds)])}else i.push(["Best bridge","same-chain \u2014 use Best swap"]);return i.push(["Preparable",u(e.preparable??o.executionReady)],E(e)),_(`ORACLE SWAP \u2014 ${a}`,i,e)}function be(t={}){let e=t||{};return _("ORACLE APPROVE \u2014 local signer",[["Pending id",A(e.id??(typeof e.digest=="string"?e.digest.slice(0,8):null))],["Surface",u(e.surface)],["Action",u(e.action)],["Chain",R({chainId:e.chain??e.chainId,chain:e.chainName})],["To",A(e.to??e.destination)],["Value",S(e.value)?u(e.value):f],["Signer",u(e.armed===!0?"running + armed":e.armed===!1?"running, disarmed":"not running")],E({confidence:e.confidence??(e.armed===!0?"high":"low")})],e)}function xe({platform:t="telegram",id:e,digest:r,hasGrant:n=!1}={}){let o=String(e||(typeof r=="string"?r.slice(0,8):"")||"").trim();return n?o?String(t)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:[[{text:"Allow",callback_data:`oracle:approve:${o}`},{text:"Deny",callback_data:`oracle:deny:${o}`}]]},cancelHint:"Allow signs with the local signer. Deny drops the pending artifact."}:{kind:"text_menu",text:["1. Allow \u2014 reply /approve "+o,"2. Deny \u2014 reply /deny "+o].join(`
5
+ `),cancelHint:"Cards are not available on this chat. Use /approve or /deny."}:{kind:"text_menu",text:"nothing to approve",cancelHint:""}:String(t)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:[]},cancelHint:"prepare-only \u2014 no local grant/session"}:{kind:"text_menu",text:"prepare-only \u2014 no local grant/session",cancelHint:""}}var f,pa,zr,ma,ve=w(()=>{Ze();tt();f="UNKNOWN",pa=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),zr=/[_*[\]`]/g;ma=Object.freeze({token:Jr,launch:Xr,hip3:Qr,hip4:Zr,polymarket:en,twap:tn,bridge:rn,swap:an,approve:be})});function Ae(t){let r=String(t||"").trim().match(/^\/(approve|deny|pending)(?:@[\w_]+)?(?:\s+([0-9a-fA-F]{4,64}))?\s*$/i);return r?{verb:r[1].toLowerCase(),id:r[2]?r[2].toLowerCase():null}:null}function Ce(t,{platform:e,grant:r,armed:n}){if(!t.length)return{text:"No pending local-signer artifacts.",buttons:xe({platform:e,hasGrant:!1})};let o=t[0];return{text:t.map(i=>be({...i,armed:n,grant:r,confidence:n?"high":"medium"})).join(`
6
6
 
7
- `),buttons:be({platform:e,id:o.id,digest:o.digest,hasGrant:M({grant:r}).allowed})}}async function Ce({platform:t,text:e,grant:r={local:!0},env:n=process.env,ownerProof:o}={}){let a=ve(e);if(!a)return null;let i=String(t)==="telegram";if(i&&a.verb!=="pending"&&!a.id)return{text:"On Telegram, tap Allow or Deny on the approve card. /approve is only for chats without cards.",buttons:null};if(a.verb==="pending"){let p=await T("/pending",{env:n});if(p.ok===!1||p.error)return{text:`Local signer: ${p.error||"not running"}. Start \`oracle signer\` on this machine first.`,buttons:null};let m=Array.isArray(p.items)?p.items:[],h=Ae(m,{platform:t,grant:r,armed:p.armed===!0});if(i)return h;if(!m.length)return{text:"No pending local-signer artifacts. /approve is only needed when cards are unavailable.",buttons:null};let g=m.map(k=>`\u2022 ${k.id} ${k.surface}/${k.action} to ${k.to||"n/a"}`);return g.push("Cards are not available here. Reply /approve <id> or /deny <id>."),{text:g.join(`
8
- `),buttons:null}}let c=a.verb==="approve"?"/ack":"/deny";if(!a.id)return{text:"Usage: /approve <id> (only when approve cards are not available)",buttons:null};let l=await T(c,{method:"POST",body:{id:a.id,...o?{ownerProof:o}:{}},env:n});if(l.httpStatus===404||l.error==="no pending artifact")return{text:"Nothing pending with that id. It may have expired or already been decided.",buttons:null};if(l.ok===!1||l.httpStatus&&l.httpStatus>=400)return{text:`Local signer refused: ${l.error||"not running"}`,buttons:null};if(a.verb==="deny")return{text:`Denied ${l.id||a.id}. Artifact dropped. Nothing signed.`,buttons:null};let s=l.result?.hash||l.result?.txHash||l.result?.transactionHash||l.hash,d=l.id||a.id;return s?{text:`Bought. Local signer executed ${d}.
9
- Tx: \`${s}\``,buttons:null,executed:!0,hash:s}:{text:`Local signer executed ${d}. Check the signer receipt if no hash was returned.`,buttons:null,executed:!0,result:l.result||null}}async function tt({platform:t,data:e,senderId:r,chatId:n,ownerProofAuthority:o,grant:a={local:!0},env:i=process.env}={}){let l=String(e||"").match(/^oracle:(approve|deny):([0-9a-fA-F]{4,64})$/i);if(!l)return null;let s=l[1].toLowerCase()==="approve"?"approve":"deny",d;if(s==="approve"&&o){let m=(await T("/pending",{env:i})).items?.find(h=>h.id===l[2].toLowerCase()||h.digest===l[2].toLowerCase());if(!m)return{text:"Nothing pending with that id. It may have expired or already been decided.",buttons:null};d=o.mint({digest:m.digest,senderId:r,chatId:n,platform:t})}return Ce({platform:t,text:`/${s} ${l[2]}`,grant:a,env:i,ownerProof:d})}var $e=w(()=>{ce();xe();ce()});import{execFile as nn}from"node:child_process";import{existsSync as on,mkdirSync as an,readFileSync as rt,realpathSync as sn,writeFileSync as cn}from"node:fs";import L from"node:path";import{promisify as ln}from"node:util";import{fileURLToPath as nt}from"node:url";function mn(t=import.meta.url){try{let e=sn(nt(t)),r=`${L.sep}node_modules${L.sep}`,n=e.lastIndexOf(r);if(n>0)return{root:e.slice(0,n),managed:!0}}catch{}return{root:null,managed:!1}}function Ee(t=import.meta.url){try{let e=L.dirname(nt(t));for(let r=0;r<8;r+=1){let n=L.join(e,"package.json");if(on(n)){let a=JSON.parse(rt(n,"utf8"));if(a?.name===_e&&a.version)return a.version}let o=L.dirname(e);if(o===e)break;e=o}}catch{return null}return null}function fn(t,e){let r=a=>String(a).replace(/^v/,"").split("-")[0].split(".").map(i=>Number.parseInt(i,10)||0),n=r(t),o=r(e);for(let a=0;a<Math.max(n.length,o.length);a+=1){let i=n[a]??0,c=o[a]??0;if(i>c)return 1;if(i<c)return-1}return 0}function ot(t){let e=t?.stateDir||L.join(process.env.HOME||".",".oracle");return L.join(e,"update-check.json")}function hn(t){try{return JSON.parse(rt(ot(t),"utf8"))}catch{return null}}function gn(t,e){try{let r=ot(t);an(L.dirname(r),{recursive:!0}),cn(r,`${JSON.stringify(e,null,2)}
10
- `)}catch{}}async function yn({timeoutMs:t=4e3}={}){try{let e=new AbortController,r=setTimeout(()=>e.abort(),t),n=await fetch(`${dn}/${encodeURIComponent(_e)}/latest`,{signal:e.signal});return clearTimeout(r),n.ok&&(await n.json())?.version||null}catch{return null}}async function at({paths:t,force:e=!1,timeoutMs:r=4e3}={}){let n=Ee(),o=e?null:hn(t),i=o&&Date.now()-(o.checkedAt||0)<pn?o.latest:null;return i||(i=await yn({timeoutMs:r}),i&&gn(t,{latest:i,checkedAt:Date.now()})),!n||!i?{current:n,latest:i,updateAvailable:!1,checked:!!i}:{current:n,latest:i,updateAvailable:fn(i,n)>0,checked:!0}}async function it({version:t="latest",dryRun:e=!1}={}){let{root:r,managed:n}=mn();if(!n||!r)return{ok:!1,reason:"unmanaged",message:`oracle is not running from a resolvable node_modules tree (source checkout or linked dev install).
11
- Update it the same way you installed it \u2014 git pull, or npm install -g @oracle-agent/oracle@latest.`};let o=`${_e}@${t}`,a=["install","--prefix",r,"--no-audit","--no-fund",o];if(e)return{ok:!0,dryRun:!0,root:r,command:`npm ${a.join(" ")}`};try{let{stdout:i,stderr:c}=await un("npm",a,{timeout:3e5,maxBuffer:16777216});return{ok:!0,root:r,stdout:i,stderr:c}}catch(i){return{ok:!1,reason:"npm-failed",root:r,message:i?.stderr||i?.message||"npm install failed"}}}var un,_e,dn,pn,st=w(()=>{un=ln(nn),_e="@oracle-agent/oracle",dn="https://registry.npmjs.org",pn=1440*60*1e3});import wn from"node:fs";import kn from"node:os";import ct from"node:path";function W(t){return String(t||"").trim().toLowerCase().replace(/^\/+/,"").replace(/\s+/g,"-")}function Sn(){let t=process.env.ORACLE_CONFIG_DIR||ct.join(kn.homedir(),".config","oracle");return ct.join(t,"chains.json")}function bn(t){if(!t||typeof t!="object")return null;let e=String(t.key??"").trim();if(!e||/[/\\.]/.test(e))return null;let r=W(e);if(!ut.test(r))return null;let n=typeof t.chainId=="string"?t.chainId.trim():Number(t.chainId);if(n===""||n===null||n===void 0||typeof n=="number"&&!Number.isFinite(n))return null;let o=typeof t.agent=="string"&&ut.test(t.agent.trim())?t.agent.trim():"oracle";return{key:r,aliases:Array.isArray(t.aliases)?t.aliases.map(W).filter(Boolean).slice(0,8):[],chainId:n,name:String(t.name||r).slice(0,60),kind:["evm","svm","utxo","venue"].includes(t.kind)?t.kind:"evm",family:W(t.family)||r,agent:o,note:String(t.note||"user-defined").slice(0,80),build:t.build!==!1,source:"user"}}function xn(t=wn.readFileSync){try{let e=JSON.parse(t(Sn(),"utf8")),r=Array.isArray(e?.chains)?e.chains:[],n=[],o=new Set;for(let a of r){let i=bn(a);!i||o.has(i.key)||(o.add(i.key),n.push(i))}return n}catch{return[]}}function dt(){let t=xn();if(t.length===0)return lt;let e=new Map(lt.map(r=>[r.key,r]));for(let r of t)e.set(r.key,r);return[...e.values()]}function vn({buildOnly:t=!1}={}){return dt().filter(e=>t?e.build:!0)}function ee(t){let e=W(t);if(!e)return null;for(let r of dt())if(r.key===e||String(r.chainId).toLowerCase()===e||(r.aliases||[]).map(W).includes(e)||W(r.name)===e)return r;return null}function pt({selectedKey:t=null,buildOnly:e=!1}={}){let r=vn({buildOnly:e}),n=["oracle chains","","pick a build/trade surface:",""];for(let o of r){let a=t&&t===o.key?"*":" ",i=String(o.chainId).padEnd(6),c=o.key.padEnd(12);n.push(`${a} ${c} ${i} ${o.note}`)}return n.push(""),n.push("usage:"),n.push(" /chain list"),n.push(" /chain hyperliquid select"),n.push(" /chain show current"),n.push(" /chain clear unset"),n.push(" oracle chain use base same from shell"),t&&n.push("",`active: ${t}`),n.join(`
7
+ `),buttons:xe({platform:e,id:o.id,digest:o.digest,hasGrant:U({grant:r}).allowed})}}async function $e({platform:t,text:e,grant:r={local:!0},env:n=process.env,ownerProof:o}={}){let a=Ae(e);if(!a)return null;let i=String(t)==="telegram";if(i&&a.verb!=="pending"&&!a.id)return{text:"On Telegram, tap Allow or Deny on the approve card. /approve is only for chats without cards.",buttons:null};if(a.verb==="pending"){let p=await T("/pending",{env:n});if(p.ok===!1||p.error)return{text:`Local signer: ${p.error||"not running"}. Start \`oracle signer\` on this machine first.`,buttons:null};let m=Array.isArray(p.items)?p.items:[],h=Ce(m,{platform:t,grant:r,armed:p.armed===!0});if(i)return h;if(!m.length)return{text:"No pending local-signer artifacts. /approve is only needed when cards are unavailable.",buttons:null};let g=m.map(k=>`\u2022 ${k.id} ${k.surface}/${k.action} to ${k.to||"n/a"}`);return g.push("Cards are not available here. Reply /approve <id> or /deny <id>."),{text:g.join(`
8
+ `),buttons:null}}let l=a.verb==="approve"?"/ack":"/deny";if(!a.id)return{text:"Usage: /approve <id> (only when approve cards are not available)",buttons:null};let c=await T(l,{method:"POST",body:{id:a.id,...o?{ownerProof:o}:{}},env:n});if(c.httpStatus===404||c.error==="no pending artifact")return{text:"Nothing pending with that id. It may have expired or already been decided.",buttons:null};if(c.ok===!1||c.httpStatus&&c.httpStatus>=400)return{text:`Local signer refused: ${c.error||"not running"}`,buttons:null};if(a.verb==="deny")return{text:`Denied ${c.id||a.id}. Artifact dropped. Nothing signed.`,buttons:null};let s=c.result?.hash||c.result?.txHash||c.result?.transactionHash||c.hash,d=c.id||a.id;return s?{text:`Bought. Local signer executed ${d}.
9
+ Tx: \`${s}\``,buttons:null,executed:!0,hash:s}:{text:`Local signer executed ${d}. Check the signer receipt if no hash was returned.`,buttons:null,executed:!0,result:c.result||null}}async function ot({platform:t,data:e,senderId:r,chatId:n,ownerProofAuthority:o,grant:a={local:!0},env:i=process.env}={}){let c=String(e||"").match(/^oracle:(approve|deny):([0-9a-fA-F]{4,64})$/i);if(!c)return null;let s=c[1].toLowerCase()==="approve"?"approve":"deny",d;if(s==="approve"&&o){let m=(await T("/pending",{env:i})).items?.find(h=>h.id===c[2].toLowerCase()||h.digest===c[2].toLowerCase());if(!m)return{text:"Nothing pending with that id. It may have expired or already been decided.",buttons:null};d=o.mint({digest:m.digest,senderId:r,chatId:n,platform:t})}return $e({platform:t,text:`/${s} ${c[2]}`,grant:a,env:i,ownerProof:d})}var _e=w(()=>{ce();ve();ce()});import{execFile as sn}from"node:child_process";import{existsSync as cn,mkdirSync as ln,readFileSync as at,realpathSync as un,writeFileSync as dn}from"node:fs";import N from"node:path";import{promisify as pn}from"node:util";import{fileURLToPath as it}from"node:url";function gn(t=import.meta.url){try{let e=un(it(t)),r=`${N.sep}node_modules${N.sep}`,n=e.lastIndexOf(r);if(n>0)return{root:e.slice(0,n),managed:!0}}catch{}return{root:null,managed:!1}}function Oe(t=import.meta.url){try{let e=N.dirname(it(t));for(let r=0;r<8;r+=1){let n=N.join(e,"package.json");if(cn(n)){let a=JSON.parse(at(n,"utf8"));if(a?.name===Ee&&a.version)return a.version}let o=N.dirname(e);if(o===e)break;e=o}}catch{return null}return null}function yn(t,e){let r=a=>String(a).replace(/^v/,"").split("-")[0].split(".").map(i=>Number.parseInt(i,10)||0),n=r(t),o=r(e);for(let a=0;a<Math.max(n.length,o.length);a+=1){let i=n[a]??0,l=o[a]??0;if(i>l)return 1;if(i<l)return-1}return 0}function st(t){let e=t?.stateDir||N.join(process.env.HOME||".",".oracle");return N.join(e,"update-check.json")}function wn(t){try{return JSON.parse(at(st(t),"utf8"))}catch{return null}}function kn(t,e){try{let r=st(t);ln(N.dirname(r),{recursive:!0}),dn(r,`${JSON.stringify(e,null,2)}
10
+ `)}catch{}}async function Sn({timeoutMs:t=4e3}={}){try{let e=new AbortController,r=setTimeout(()=>e.abort(),t),n=await fetch(`${fn}/${encodeURIComponent(Ee)}/latest`,{signal:e.signal});return clearTimeout(r),n.ok&&(await n.json())?.version||null}catch{return null}}async function ct({paths:t,force:e=!1,timeoutMs:r=4e3}={}){let n=Oe(),o=e?null:wn(t),i=o&&Date.now()-(o.checkedAt||0)<hn?o.latest:null;return i||(i=await Sn({timeoutMs:r}),i&&kn(t,{latest:i,checkedAt:Date.now()})),!n||!i?{current:n,latest:i,updateAvailable:!1,checked:!!i}:{current:n,latest:i,updateAvailable:yn(i,n)>0,checked:!0}}async function lt({version:t="latest",dryRun:e=!1}={}){let{root:r,managed:n}=gn();if(!n||!r)return{ok:!1,reason:"unmanaged",message:`oracle is not running from a resolvable node_modules tree (source checkout or linked dev install).
11
+ Update it the same way you installed it \u2014 git pull, or npm install -g @oracle-agent/oracle@latest.`};let o=`${Ee}@${t}`,a=["install","--prefix",r,"--no-audit","--no-fund",o];if(e)return{ok:!0,dryRun:!0,root:r,command:`npm ${a.join(" ")}`};try{let{stdout:i,stderr:l}=await mn("npm",a,{timeout:3e5,maxBuffer:16777216});return{ok:!0,root:r,stdout:i,stderr:l}}catch(i){return{ok:!1,reason:"npm-failed",root:r,message:i?.stderr||i?.message||"npm install failed"}}}var mn,Ee,fn,hn,ut=w(()=>{mn=pn(sn),Ee="@oracle-agent/oracle",fn="https://registry.npmjs.org",hn=1440*60*1e3});import bn from"node:fs";import xn from"node:os";import dt from"node:path";function W(t){return String(t||"").trim().toLowerCase().replace(/^\/+/,"").replace(/\s+/g,"-")}function vn(){let t=process.env.ORACLE_CONFIG_DIR||dt.join(xn.homedir(),".config","oracle");return dt.join(t,"chains.json")}function An(t){if(!t||typeof t!="object")return null;let e=String(t.key??"").trim();if(!e||/[/\\.]/.test(e))return null;let r=W(e);if(!mt.test(r))return null;let n=typeof t.chainId=="string"?t.chainId.trim():Number(t.chainId);if(n===""||n===null||n===void 0||typeof n=="number"&&!Number.isFinite(n))return null;let o=typeof t.agent=="string"&&mt.test(t.agent.trim())?t.agent.trim():"oracle";return{key:r,aliases:Array.isArray(t.aliases)?t.aliases.map(W).filter(Boolean).slice(0,8):[],chainId:n,name:String(t.name||r).slice(0,60),kind:["evm","svm","utxo","venue"].includes(t.kind)?t.kind:"evm",family:W(t.family)||r,agent:o,note:String(t.note||"user-defined").slice(0,80),build:t.build!==!1,source:"user"}}function Cn(t=bn.readFileSync){try{let e=JSON.parse(t(vn(),"utf8")),r=Array.isArray(e?.chains)?e.chains:[],n=[],o=new Set;for(let a of r){let i=An(a);!i||o.has(i.key)||(o.add(i.key),n.push(i))}return n}catch{return[]}}function ft(){let t=Cn();if(t.length===0)return pt;let e=new Map(pt.map(r=>[r.key,r]));for(let r of t)e.set(r.key,r);return[...e.values()]}function $n({buildOnly:t=!1}={}){return ft().filter(e=>t?e.build:!0)}function ee(t){let e=W(t);if(!e)return null;for(let r of ft())if(r.key===e||String(r.chainId).toLowerCase()===e||(r.aliases||[]).map(W).includes(e)||W(r.name)===e)return r;return null}function ht({selectedKey:t=null,buildOnly:e=!1}={}){let r=$n({buildOnly:e}),n=["oracle chains","","pick a build/trade surface:",""];for(let o of r){let a=t&&t===o.key?"*":" ",i=String(o.chainId).padEnd(6),l=o.key.padEnd(12);n.push(`${a} ${l} ${i} ${o.note}`)}return n.push(""),n.push("usage:"),n.push(" /chain list"),n.push(" /chain hyperliquid select"),n.push(" /chain show current"),n.push(" /chain clear unset"),n.push(" oracle chain use base same from shell"),t&&n.push("",`active: ${t}`),n.join(`
12
12
  `)+`
13
- `}var lt,ut,Oe=w(()=>{lt=Object.freeze([{key:"hyperliquid",aliases:["hl","hyperevm","hype","999"],chainId:999,name:"hyperliquid",kind:"evm",family:"hyperliquid",agent:"hyperliquid-agent",note:"perps \xB7 hip-3/4 \xB7 hyperevm 999",build:!0},{key:"ethereum",aliases:["eth","mainnet","1"],chainId:1,name:"ethereum",kind:"evm",family:"evm",agent:"oracle",note:"l1 \xB7 bridge hub",build:!0},{key:"base",aliases:["8453"],chainId:8453,name:"base",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"arbitrum",aliases:["arb","42161"],chainId:42161,name:"arbitrum",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"optimism",aliases:["op","10"],chainId:10,name:"optimism",kind:"evm",family:"evm",agent:"oracle",note:"op mainnet",build:!0},{key:"polygon",aliases:["matic","137"],chainId:137,name:"polygon",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"bsc",aliases:["bnb","56"],chainId:56,name:"bnb chain",kind:"evm",family:"evm",agent:"oracle",note:"bsc",build:!0},{key:"avalanche",aliases:["avax","43114"],chainId:43114,name:"avalanche",kind:"evm",family:"evm",agent:"oracle",note:"c-chain",build:!0},{key:"abstract",aliases:["abs","2741"],chainId:2741,name:"abstract",kind:"evm",family:"evm",agent:"oracle",note:"open / add agent",build:!0},{key:"stable",aliases:["988"],chainId:988,name:"stable",kind:"evm",family:"stable",agent:"stable-agent",note:"usdt0 gas \xB7 stable agent",build:!0},{key:"robinhood",aliases:["rh","4663"],chainId:4663,name:"robinhood",kind:"evm",family:"robinhood",agent:"robinhood-agent",note:"rh chain 4663",build:!0},{key:"solana",aliases:["sol"],chainId:"SOL",name:"solana",kind:"svm",family:"solana",agent:"solana-agent",note:"jup \xB7 nfts \xB7 dexs",build:!0},{key:"bitcoin",aliases:["btc"],chainId:"BTC",name:"bitcoin",kind:"utxo",family:"bitcoin",agent:"bitcoin-agent",note:"ord \xB7 runes \xB7 l1",build:!0},{key:"polymarket",aliases:["poly","polygon-poly"],chainId:137,name:"polymarket",kind:"venue",family:"polymarket",agent:"polymarket-agent",note:"prediction markets (polygon venue)",build:!1}]);ut=/^[a-z0-9][a-z0-9-]*$/});import Re from"node:fs";import An from"node:path";function mt(){return An.join($(),"active-chain.json")}function Le(){let t=mt();if(!Re.existsSync(t))return null;try{let e=JSON.parse(Re.readFileSync(t,"utf8"));if(!e||typeof e!="object"||!e.key)return null;let r=ee(e.key);return r?{key:r.key,chainId:r.chainId,name:r.name,agent:r.agent,selectedAt:e.selectedAt||null}:null}catch{return null}}function ft(t){let e=ee(t);if(!e){let n=new Error(`unknown chain '${t}'`);throw n.code="UNKNOWN_CHAIN",n}ae($());let r={key:e.key,chainId:e.chainId,name:e.name,agent:e.agent,selectedAt:new Date().toISOString()};return Re.writeFileSync(mt(),JSON.stringify(r,null,2)+`
14
- `,{mode:384}),r}var ht=w(()=>{Oe();ie()});function gt(t,{coin:e,side:r,sizeUsd:n,leverage:o,venue:a,confirm:i,user:c}={}){let l=String(t||"").trim();if(!l||l.includes("ts.net")||!/^https:\/\//i.test(l))return null;let s=new URL(l);if(e&&Cn.test(String(e).toUpperCase())&&s.searchParams.set("coin",String(e).toUpperCase()),(r==="long"||r==="short")&&s.searchParams.set("side",r),Number.isFinite(Number(n))&&Number(n)>=1&&s.searchParams.set("size",String(Math.min(1e5,Math.round(Number(n))))),Number.isInteger(Number(o))&&Number(o)>=1&&s.searchParams.set("lev",String(Math.min(50,Number(o)))),a){let d=String(a).toLowerCase()==="hl"?"hyperliquid":String(a).toLowerCase();s.searchParams.set("venue",d)}else s.searchParams.get("venue")||s.searchParams.set("venue","hyperliquid");return s.searchParams.set("view","perps"),s.searchParams.set("build","1"),i&&/^[0-9a-f]{32}$/i.test(String(i))&&s.searchParams.set("confirm",String(i).toLowerCase()),c&&/^0x[0-9a-fA-F]{40}$/.test(String(c))&&s.searchParams.set("user",String(c).toLowerCase()),s.toString()}var Cn,yt=w(()=>{Cn=/^[A-Z0-9][A-Z0-9._-]{0,11}$/});import{createHash as $n,randomBytes as Ea}from"node:crypto";import{mkdirSync as _n,readFileSync as En,writeFileSync as On}from"node:fs";import{homedir as Rn}from"node:os";import{dirname as Ln,join as wt}from"node:path";function re(t=process.env){return wt(t.ORACLE_CONFIG_DIR||wt(Rn(),".config","oracle"),"telegram-cards.json")}function ne(){return{links:{},artifacts:{},threads:{}}}function ue(){return te}function kt(t,{readFile:e=En}={}){try{let r=JSON.parse(String(e(t)));te={links:r.links&&typeof r.links=="object"?r.links:{},artifacts:r.artifacts&&typeof r.artifacts=="object"?r.artifacts:{},threads:r.threads&&typeof r.threads=="object"?r.threads:{}}}catch{te=ne()}return te}function de(t,e=te,{writeFile:r=On,mkdir:n=_n}={}){n(Ln(t),{recursive:!0,mode:448}),r(t,JSON.stringify(e),{mode:384})}function N(t){return t==null?!1:typeof t=="string"?t.trim()!=="":!0}function Un(t){return $n("sha256").update(String(t)).digest("hex")}function Ne(t){if(Array.isArray(t))return t.map(Ne);if(!t||typeof t!="object")return t;let e={};for(let[r,n]of Object.entries(t))/(secret|token|key|seed|private|password|mnemonic|auth)/i.test(r)||(e[r]=Ne(n));return e}function Mn(t){let r=String(t||"").trim().match(/^oracle:card:(deepen|refresh|prepare|ta|fa|long|short|allow|deny):([a-z0-9-]{4,40})$/i);return r?{action:r[1].toLowerCase(),artifactId:r[2].toLowerCase()}:null}function St({platform:t="telegram",artifactId:e,openUrl:r,hasGrant:n=!1}={}){let o=String(e||"").trim().toLowerCase();if(!Ie.test(o))return{kind:"text_menu",text:"no artifact to continue",cancelHint:""};let a=[],i=[{text:"TA",callback_data:`oracle:card:ta:${o}`},{text:"FA",callback_data:`oracle:card:fa:${o}`}],c=p=>gt(r,{side:p}),l=c("long"),s=c("short"),d=l&&s?[{text:"LONG",url:l},{text:"SHORT",url:s}]:[{text:"LONG",callback_data:`oracle:card:long:${o}`},{text:"SHORT",callback_data:`oracle:card:short:${o}`}];return N(r)?(a.push([{text:"Open",url:String(r)},i[0]]),a.push(d),a.push(n?[i[1],{text:"Prep",callback_data:`oracle:card:prepare:${o}`}]:[i[1]])):(a.push(i),a.push(d),n&&a.push([{text:"Prep",callback_data:`oracle:card:prepare:${o}`}])),String(t)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:a.filter(p=>p.length>0)},cancelHint:"LONG/SHORT open the graph. CONFIRM there. Telegram never sends."}:{kind:"text_menu",text:"TA / FA / LONG / SHORT",cancelHint:""}}function bt(t={}){let r=[`*${N(t.title)?u(t.title):"Oracle artifact"}*`,`Kind: ${N(t.kind)?u(t.kind):f}`,`Id: ${N(t.id)?`\`${String(t.id).replace(/`/g,"")}\``:f}`,`Summary: ${N(t.summary)?u(t.summary):f}`,`Confidence: ${ke(t.confidence)}`];(N(t.source)||N(t.fetchedAt))&&r.push(`Source: ${u(t.source)} at ${u(t.fetchedAt)}`),Array.isArray(t.warnings)&&t.warnings.length&&r.push(`Warnings: ${t.warnings.map(o=>u(o)).join("; ")}`);let n=M(t);return r.push(n.allowed?"Actions: TA / FA / LONG / SHORT open the graph. Execute on CONFIRM there.":`Actions: TA / FA / LONG / SHORT \u2014 ${u(n.reason)}`),r.join(`
15
- `)}function Dn(t,e={},{now:r=Date.now()}={}){let n=t||ne(),o=String(e.id||"").trim().toLowerCase();if(!Ie.test(o))throw new TypeError("artifact id required");let a={id:o,kind:String(e.kind||"thesis"),title:String(e.title||"Oracle artifact"),summary:String(e.summary||""),openUrl:N(e.openUrl)?String(e.openUrl):null,confidence:e.confidence,source:e.source||"oracle",fetchedAt:e.fetchedAt||new Date(r).toISOString(),warnings:Array.isArray(e.warnings)?e.warnings.map(String):[],payload:Ne(e.payload||{}),createdAt:new Date(r).toISOString()};return n.artifacts[o]=a,a}function Te(t,{chatId:e,artifactId:r,now:n=Date.now()}={}){let o=t||ne(),a=String(e||"").trim(),i=String(r||"").trim().toLowerCase();if(!a)throw new TypeError("chat id required");if(!Ie.test(i))throw new TypeError("artifact id required");return o.threads[a]={artifactId:i,updatedAt:n},o.threads[a]}function xt(t,{chatId:e,text:r}={}){let n=String(e||"").trim(),o=String(r||"").trim();if(!n||!o||/^\//.test(o))return null;let a=t?.threads?.[n];if(!a?.artifactId)return null;let i=t.artifacts?.[a.artifactId];return i?`Continue artifact ${i.id} (${i.kind}). Prior: ${i.summary||i.title}. User: ${o}`:null}function vt(t,{token:e,telegramUserId:r,now:n=Date.now()}={}){let o=t||ne(),a=String(e||"").trim(),i=String(r||"").trim();if(!Tn.test(a))return{ok:!1,error:"invalid start token"};if(!Pn.test(i))return{ok:!1,error:"invalid telegram user"};let c=Un(a),l=o.links[c];return l?(delete o.links[c],Number(l.expiresAt)<=n?{ok:!1,error:"start token expired"}:String(l.ownerId)!==i?{ok:!1,error:"start token is bound to a different owner"}:{ok:!0,ownerId:i}):{ok:!1,error:"unknown or already used start token"}}function At(t,{data:e,chatId:r,grant:n=null,now:o=Date.now()}={}){let a=Mn(e);if(!a)return null;if(!In.has(a.action))return{text:"That card action is not available.",buttons:null};let i=t?.artifacts?.[a.artifactId];if(!i)return{text:"That artifact is gone. Ask again and I will issue a new card.",buttons:null};r&&Te(t,{chatId:r,artifactId:i.id,now:o});let c=M({grant:n},{now:o}),l=St({artifactId:i.id,openUrl:i.openUrl,hasGrant:c.allowed});return a.action==="refresh"?{text:bt(i),buttons:l,prompt:null}:a.action==="deepen"?{text:null,buttons:null,prompt:`Deepen artifact ${i.id} (${i.kind}). Prior: ${i.summary||i.title}. Be terse. Do not sign or broadcast.`}:a.action==="ta"?{text:null,buttons:null,prompt:`TA artifact ${i.id}. Prior: ${i.summary||i.title}. Run deterministic TA on the coin/venue in the artifact (RSI divergence, S/R, candle patterns). Reply in this Telegram chat with the verdict rows and say what was drawn. Do not sign or broadcast.`}:a.action==="fa"?{text:null,buttons:null,prompt:`FA artifact ${i.id}. Prior: ${i.summary||i.title}. Run per-coin FA (funding, OI, book, premium) plus the separate MACRO thesis (M1/M2/Fed BS/net liquidity) if relevant. Cite receipts. Stay in this Telegram chat. Do not sign or broadcast.`}:a.action==="allow"?{text:"Allow is the graph. Open the ticket there and CONFIRM. Telegram did not send.",buttons:null,prompt:null}:a.action==="deny"?{text:`Denied ${i.id}. Ticket cancelled. Nothing signed.`,buttons:null,prompt:null}:a.action==="long"||a.action==="short"?{text:null,buttons:null,prompt:`Open the live graph ticket for a ${a.action} on artifact ${i.id}. Prior: ${i.summary||i.title}. Size from the connected HL account. Execute only on CONFIRM on the graph. Never sign from Telegram.`}:c.allowed?{text:`Queued unsigned prepare for ${i.id}. Nothing signed. Allow/Deny still required.`,buttons:l,prompt:null,prepare:{artifactId:i.id,unsigned:!0,broadcast:!1}}:{text:`Prepare blocked \u2014 ${c.reason}. Deepen and Refresh still work.`,buttons:l,prompt:null}}function Ct(t={},{grant:e=null,now:r=Date.now(),state:n}={}){let o=n||ue(),a=String(t.id||`art-${Math.abs(Number(r)).toString(36)}`).toLowerCase().slice(0,40),i=Dn(o,{...t,id:a},{now:r}),c=M({grant:e},{now:r});return{text:bt({...i,grant:e}),replyMarkup:St({artifactId:i.id,openUrl:i.openUrl,hasGrant:c.allowed}).replyMarkup,artifact:i,state:o}}var Nn,In,Ie,Tn,Pn,te,Pe=w(()=>{yt();xe();Nn=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),In=new Set(Nn),Ie=/^[a-z0-9-]{4,40}$/i,Tn=/^[0-9a-f]{32}$/,Pn=/^\d+$/;te=ne()});var Kt={};j(Kt,{NON_OWNER_REPLY:()=>V,buildPersona:()=>K,handleSelfUpdate:()=>Nt,isForwarded:()=>It,isOwnerSender:()=>z,ownerIdsFor:()=>Rt,parseGatewayChainCommand:()=>Ht,parseGatewayCompactCommand:()=>Ft,parseGatewayEffortCommand:()=>Mt,parseGatewayGoalCommand:()=>Bt,parseGatewayHelpCommand:()=>Dt,parseGatewayModelCommand:()=>Ut,parseGatewaySetupModelCommand:()=>Jn,parseGatewayStatusCommand:()=>jt,parsePeerAsk:()=>qt,parseSelfUpdate:()=>Lt,resolveBackendArgv:()=>Wt,resolveGatewayModel:()=>Tt,resolveOracleBin:()=>Ot,routePeerConsult:()=>oe,routeToAgent:()=>O});import{spawn as Et}from"node:child_process";import{dirname as jn,join as Me}from"node:path";import{homedir as Bn}from"node:os";import{mkdirSync as Fn,readFileSync as Hn,writeFileSync as Gn,unlinkSync as qn}from"node:fs";import{fileURLToPath as Wn}from"node:url";function Ot({env:t=process.env,moduleUrl:e=import.meta.url}={}){return t.ORACLE_CLI_ENTRY||Me(jn(Wn(e)),"oracle.mjs")}function Rt(t,e=process.env){let r=String(e[`ORACLE_OWNER_${String(t).toUpperCase()}`]||""),n=String(e.ORACLE_OWNER_IDS||"");return new Set(`${r},${n}`.split(",").map(o=>o.trim()).filter(Boolean))}function z({platform:t,senderId:e,extraOwners:r},n=process.env){let o=String(e||"").trim();return o?Rt(t,n).has(o)?!0:Array.isArray(r)?r.map(a=>String(a).trim()).filter(Boolean).includes(o):!1:!1}function Lt(t){let e=String(t||"").trim();if(!e)return null;let r=e.replace(/^\/update(?:@[\w_]+)?\b/i,"update");return/^(?:oracle\s+)?update\s+--check\s*$/i.test(r)?{checkOnly:!0}:/^(?:oracle\s+)?update\s*$/i.test(r)?{checkOnly:!1}:null}async function Nt(t,{check:e=at,update:r=it,versionOf:n=Ee}={}){let o=await e({force:!0});if(t.checkOnly)return o.checked?o.updateAvailable?`oracle ${o.current} \u2192 ${o.latest} available. Send /update to install.`:`oracle ${o.current} is up to date`:`oracle ${o.current||"?"} \u2014 could not reach npm`;if(o.checked&&!o.updateAvailable)return`oracle ${o.current} is already up to date`;let a=o.latest||"latest",i=await r({version:a==="latest"?"latest":a});if(!i.ok)return`oracle update failed: ${i.message}`;let c=n();return[`oracle ${o.current||"?"} \u2192 ${c||a}`,"Restart the gateway to load it: oracle gateway"].join(`
16
- `)}function It(t={}){return!!(t.forwarded||t.forward_from||t.forward_from_chat||t.forward_origin||t.forward_sender_name||t.forward_date)}function Tt({readConfig:t=q}={}){let e=t();return e?e.backend==="hermes"?{ok:!1,error:"model config delegates to hermes; the gateway runs Oracle's native loop. Set a standalone backend: oracle model --backend standalone"}:e.model?{ok:!0,provider:e.provider,model:e.model,reasoningEffort:e.reasoningEffort||null}:{ok:!1,error:"model config has no model \u2014 run: oracle model --backend standalone --provider <p> --model <m>"}:{ok:!1,error:"gateway has no model configured \u2014 run: oracle model --backend standalone --provider <p> --model <m>"}}function Ut(t){let r=String(t||"").trim().match(/^\/model(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim();if(!n)return{action:"list"};if(n.toLowerCase()==="show"||n==="?")return{action:"show"};if(n.toLowerCase()==="list")return{action:"list"};let o=n.split(/\s+/),a=Pt[o[0].toLowerCase()];if(a&&o.length===1)return{action:"set",provider:a.provider,model:a.model};if(a&&o.length>=2)return{action:"set",provider:a.provider,model:o.slice(1).join(" ")};if(o.length>=2)return{action:"set",provider:o[0],model:o.slice(1).join(" ")};if(o[0]?.includes(":")){let[i,c]=o[0].split(":");if(i&&c)return{action:"set",provider:i,model:c}}return{action:"usage"}}function Mt(t){let r=String(t||"").trim().match(/^\/(?:effort|reasoning)(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim().toLowerCase();return!n||n==="show"||n==="?"?{action:"show"}:Vn.includes(n)?{action:"set",reasoningEffort:n}:{action:"usage"}}function Kn({provider:t,model:e}){let r=q()||{},n=ye({...r,backend:r.backend&&r.backend!=="auto"?r.backend:"standalone",provider:t,model:e});return`model ${n.provider} / ${n.model}
17
- Oracle persona unchanged. Native harness only \u2014 Hermes Telegram uses its own /model.`}function Yn(t){let e=q();if(!e)throw new Error("no model configured \u2014 run /model first");return`effort ${ye({...e,reasoningEffort:t}).reasoningEffort||t}
18
- Native harness only.`}function $t(){let t=q(),e=["Oracle native models (tap /model <id> to switch):"];for(let[r,n]of Object.entries(Pt)){let o=t?.provider===n.provider&&t?.model===n.model?" \u2190 current":"";e.push(`/model ${r} ${n.provider} / ${n.model}${o}`)}return e.push(""),e.push("Add another provider: /setup model"),e.push("Or set exact id: /model <provider> <model-id>"),e.push("/effort low|medium|high"),t?.provider&&(e.push(""),e.push(`current ${t.provider} / ${t.model||"unset"} \xB7 effort ${t.reasoningEffort||"default"}`)),e.join(`
13
+ `}var pt,mt,Re=w(()=>{pt=Object.freeze([{key:"hyperliquid",aliases:["hl","hyperevm","hype","999"],chainId:999,name:"hyperliquid",kind:"evm",family:"hyperliquid",agent:"hyperliquid-agent",note:"perps \xB7 hip-3/4 \xB7 hyperevm 999",build:!0},{key:"ethereum",aliases:["eth","mainnet","1"],chainId:1,name:"ethereum",kind:"evm",family:"evm",agent:"oracle",note:"l1 \xB7 bridge hub",build:!0},{key:"base",aliases:["8453"],chainId:8453,name:"base",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"arbitrum",aliases:["arb","42161"],chainId:42161,name:"arbitrum",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"optimism",aliases:["op","10"],chainId:10,name:"optimism",kind:"evm",family:"evm",agent:"oracle",note:"op mainnet",build:!0},{key:"polygon",aliases:["matic","137"],chainId:137,name:"polygon",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"bsc",aliases:["bnb","56"],chainId:56,name:"bnb chain",kind:"evm",family:"evm",agent:"oracle",note:"bsc",build:!0},{key:"avalanche",aliases:["avax","43114"],chainId:43114,name:"avalanche",kind:"evm",family:"evm",agent:"oracle",note:"c-chain",build:!0},{key:"abstract",aliases:["abs","2741"],chainId:2741,name:"abstract",kind:"evm",family:"evm",agent:"oracle",note:"open / add agent",build:!0},{key:"stable",aliases:["988"],chainId:988,name:"stable",kind:"evm",family:"stable",agent:"stable-agent",note:"usdt0 gas \xB7 stable agent",build:!0},{key:"robinhood",aliases:["rh","4663"],chainId:4663,name:"robinhood",kind:"evm",family:"robinhood",agent:"robinhood-agent",note:"rh chain 4663",build:!0},{key:"solana",aliases:["sol"],chainId:"SOL",name:"solana",kind:"svm",family:"solana",agent:"solana-agent",note:"jup \xB7 nfts \xB7 dexs",build:!0},{key:"bitcoin",aliases:["btc"],chainId:"BTC",name:"bitcoin",kind:"utxo",family:"bitcoin",agent:"bitcoin-agent",note:"ord \xB7 runes \xB7 l1",build:!0},{key:"polymarket",aliases:["poly","polygon-poly"],chainId:137,name:"polymarket",kind:"venue",family:"polymarket",agent:"polymarket-agent",note:"prediction markets (polygon venue)",build:!1}]);mt=/^[a-z0-9][a-z0-9-]*$/});import Ne from"node:fs";import _n from"node:path";function gt(){return _n.join($(),"active-chain.json")}function Le(){let t=gt();if(!Ne.existsSync(t))return null;try{let e=JSON.parse(Ne.readFileSync(t,"utf8"));if(!e||typeof e!="object"||!e.key)return null;let r=ee(e.key);return r?{key:r.key,chainId:r.chainId,name:r.name,agent:r.agent,selectedAt:e.selectedAt||null}:null}catch{return null}}function yt(t){let e=ee(t);if(!e){let n=new Error(`unknown chain '${t}'`);throw n.code="UNKNOWN_CHAIN",n}ae($());let r={key:e.key,chainId:e.chainId,name:e.name,agent:e.agent,selectedAt:new Date().toISOString()};return Ne.writeFileSync(gt(),JSON.stringify(r,null,2)+`
14
+ `,{mode:384}),r}var wt=w(()=>{Re();ie()});import{createHash as En,randomBytes as Ua}from"node:crypto";import{mkdirSync as On,readFileSync as Rn,writeFileSync as Nn}from"node:fs";import{homedir as Ln}from"node:os";import{dirname as In,join as kt}from"node:path";function re(t=process.env){return kt(t.ORACLE_CONFIG_DIR||kt(Ln(),".config","oracle"),"telegram-cards.json")}function ne(){return{links:{},artifacts:{},threads:{}}}function ue(){return te}function St(t,{readFile:e=Rn}={}){try{let r=JSON.parse(String(e(t)));te={links:r.links&&typeof r.links=="object"?r.links:{},artifacts:r.artifacts&&typeof r.artifacts=="object"?r.artifacts:{},threads:r.threads&&typeof r.threads=="object"?r.threads:{}}}catch{te=ne()}return te}function de(t,e=te,{writeFile:r=Nn,mkdir:n=On}={}){n(In(t),{recursive:!0,mode:448}),r(t,JSON.stringify(e),{mode:384})}function L(t){return t==null?!1:typeof t=="string"?t.trim()!=="":!0}function Dn(t){return En("sha256").update(String(t)).digest("hex")}function Ie(t){if(Array.isArray(t))return t.map(Ie);if(!t||typeof t!="object")return t;let e={};for(let[r,n]of Object.entries(t))/(secret|token|key|seed|private|password|mnemonic|auth)/i.test(r)||(e[r]=Ie(n));return e}function jn(t){let r=String(t||"").trim().match(/^oracle:card:(deepen|refresh|prepare|ta|fa|long|short|allow|deny):([a-z0-9-]{4,40})$/i);return r?{action:r[1].toLowerCase(),artifactId:r[2].toLowerCase()}:null}function bt({platform:t="telegram",artifactId:e,openUrl:r,hasGrant:n=!1}={}){let o=String(e||"").trim().toLowerCase();if(!Te.test(o))return{kind:"text_menu",text:"no artifact to continue",cancelHint:""};let a=[],i=[{text:"TA",callback_data:`oracle:card:ta:${o}`},{text:"FA",callback_data:`oracle:card:fa:${o}`}],l=p=>et(r,{side:p}),c=l("long"),s=l("short"),d=c&&s?[{text:"LONG",url:c},{text:"SHORT",url:s}]:[{text:"LONG",callback_data:`oracle:card:long:${o}`},{text:"SHORT",callback_data:`oracle:card:short:${o}`}];return L(r)?(a.push([{text:"Open",url:String(r)},i[0]]),a.push(d),a.push(n?[i[1],{text:"Prep",callback_data:`oracle:card:prepare:${o}`}]:[i[1]])):(a.push(i),a.push(d),n&&a.push([{text:"Prep",callback_data:`oracle:card:prepare:${o}`}])),String(t)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:a.filter(p=>p.length>0)},cancelHint:"LONG/SHORT open the graph. CONFIRM there. Telegram never sends."}:{kind:"text_menu",text:"TA / FA / LONG / SHORT",cancelHint:""}}function xt(t={}){let r=[`*${L(t.title)?u(t.title):"Oracle artifact"}*`,`Kind: ${L(t.kind)?u(t.kind):f}`,`Id: ${L(t.id)?`\`${String(t.id).replace(/`/g,"")}\``:f}`,`Summary: ${L(t.summary)?u(t.summary):f}`,`Confidence: ${Se(t.confidence)}`];(L(t.source)||L(t.fetchedAt))&&r.push(`Source: ${u(t.source)} at ${u(t.fetchedAt)}`),Array.isArray(t.warnings)&&t.warnings.length&&r.push(`Warnings: ${t.warnings.map(o=>u(o)).join("; ")}`);let n=U(t);return r.push(n.allowed?"Actions: TA / FA / LONG / SHORT open the graph. Execute on CONFIRM there.":`Actions: TA / FA / LONG / SHORT \u2014 ${u(n.reason)}`),r.join(`
15
+ `)}function Bn(t,e={},{now:r=Date.now()}={}){let n=t||ne(),o=String(e.id||"").trim().toLowerCase();if(!Te.test(o))throw new TypeError("artifact id required");let a={id:o,kind:String(e.kind||"thesis"),title:String(e.title||"Oracle artifact"),summary:String(e.summary||""),openUrl:L(e.openUrl)?String(e.openUrl):null,confidence:e.confidence,source:e.source||"oracle",fetchedAt:e.fetchedAt||new Date(r).toISOString(),warnings:Array.isArray(e.warnings)?e.warnings.map(String):[],payload:Ie(e.payload||{}),createdAt:new Date(r).toISOString()};return n.artifacts[o]=a,a}function Pe(t,{chatId:e,artifactId:r,now:n=Date.now()}={}){let o=t||ne(),a=String(e||"").trim(),i=String(r||"").trim().toLowerCase();if(!a)throw new TypeError("chat id required");if(!Te.test(i))throw new TypeError("artifact id required");return o.threads[a]={artifactId:i,updatedAt:n},o.threads[a]}function vt(t,{chatId:e,text:r}={}){let n=String(e||"").trim(),o=String(r||"").trim();if(!n||!o||/^\//.test(o))return null;let a=t?.threads?.[n];if(!a?.artifactId)return null;let i=t.artifacts?.[a.artifactId];return i?`Continue artifact ${i.id} (${i.kind}). Prior: ${i.summary||i.title}. User: ${o}`:null}function At(t,{token:e,telegramUserId:r,now:n=Date.now()}={}){let o=t||ne(),a=String(e||"").trim(),i=String(r||"").trim();if(!Mn.test(a))return{ok:!1,error:"invalid start token"};if(!Un.test(i))return{ok:!1,error:"invalid telegram user"};let l=Dn(a),c=o.links[l];return c?(delete o.links[l],Number(c.expiresAt)<=n?{ok:!1,error:"start token expired"}:String(c.ownerId)!==i?{ok:!1,error:"start token is bound to a different owner"}:{ok:!0,ownerId:i}):{ok:!1,error:"unknown or already used start token"}}function Ct(t,{data:e,chatId:r,grant:n=null,now:o=Date.now()}={}){let a=jn(e);if(!a)return null;if(!Pn.has(a.action))return{text:"That card action is not available.",buttons:null};let i=t?.artifacts?.[a.artifactId];if(!i)return{text:"That artifact is gone. Ask again and I will issue a new card.",buttons:null};r&&Pe(t,{chatId:r,artifactId:i.id,now:o});let l=U({grant:n},{now:o}),c=bt({artifactId:i.id,openUrl:i.openUrl,hasGrant:l.allowed});return a.action==="refresh"?{text:xt(i),buttons:c,prompt:null}:a.action==="deepen"?{text:null,buttons:null,prompt:`Deepen artifact ${i.id} (${i.kind}). Prior: ${i.summary||i.title}. Be terse. Do not sign or broadcast.`}:a.action==="ta"?{text:null,buttons:null,prompt:`TA artifact ${i.id}. Prior: ${i.summary||i.title}. Run deterministic TA on the coin/venue in the artifact (RSI divergence, S/R, candle patterns). Reply in this Telegram chat with the verdict rows and say what was drawn. Do not sign or broadcast.`}:a.action==="fa"?{text:null,buttons:null,prompt:`FA artifact ${i.id}. Prior: ${i.summary||i.title}. Run per-coin FA (funding, OI, book, premium) plus the separate MACRO thesis (M1/M2/Fed BS/net liquidity) if relevant. Cite receipts. Stay in this Telegram chat. Do not sign or broadcast.`}:a.action==="allow"?{text:"Allow is the graph. Open the ticket there and CONFIRM. Telegram did not send.",buttons:null,prompt:null}:a.action==="deny"?{text:`Denied ${i.id}. Ticket cancelled. Nothing signed.`,buttons:null,prompt:null}:a.action==="long"||a.action==="short"?{text:null,buttons:null,prompt:`Open the live graph ticket for a ${a.action} on artifact ${i.id}. Prior: ${i.summary||i.title}. Size from the connected HL account. Execute only on CONFIRM on the graph. Never sign from Telegram.`}:l.allowed?{text:`Queued unsigned prepare for ${i.id}. Nothing signed. Allow/Deny still required.`,buttons:c,prompt:null,prepare:{artifactId:i.id,unsigned:!0,broadcast:!1}}:{text:`Prepare blocked \u2014 ${l.reason}. Deepen and Refresh still work.`,buttons:c,prompt:null}}function $t(t={},{grant:e=null,now:r=Date.now(),state:n}={}){let o=n||ue(),a=String(t.id||`art-${Math.abs(Number(r)).toString(36)}`).toLowerCase().slice(0,40),i=Bn(o,{...t,id:a},{now:r}),l=U({grant:e},{now:r});return{text:xt({...i,grant:e}),replyMarkup:bt({artifactId:i.id,openUrl:i.openUrl,hasGrant:l.allowed}).replyMarkup,artifact:i,state:o}}var Tn,Pn,Te,Mn,Un,te,Me=w(()=>{we();ve();Tn=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),Pn=new Set(Tn),Te=/^[a-z0-9-]{4,40}$/i,Mn=/^[0-9a-f]{32}$/,Un=/^\d+$/;te=ne()});var Yt={};j(Yt,{NON_OWNER_REPLY:()=>V,buildPersona:()=>K,handleSelfUpdate:()=>It,isForwarded:()=>Tt,isOwnerSender:()=>z,ownerIdsFor:()=>Nt,parseGatewayChainCommand:()=>Gt,parseGatewayCompactCommand:()=>Ht,parseGatewayEffortCommand:()=>Dt,parseGatewayGoalCommand:()=>Ft,parseGatewayHelpCommand:()=>jt,parseGatewayModelCommand:()=>Ut,parseGatewaySetupModelCommand:()=>Qn,parseGatewayStatusCommand:()=>Bt,parsePeerAsk:()=>Wt,parseSelfUpdate:()=>Lt,resolveBackendArgv:()=>zt,resolveGatewayModel:()=>Pt,resolveOracleBin:()=>Rt,routePeerConsult:()=>oe,routeToAgent:()=>O});import{spawn as Ot}from"node:child_process";import{dirname as Fn,join as De}from"node:path";import{homedir as Hn}from"node:os";import{mkdirSync as Gn,readFileSync as qn,writeFileSync as Wn,unlinkSync as zn}from"node:fs";import{fileURLToPath as Vn}from"node:url";function Rt({env:t=process.env,moduleUrl:e=import.meta.url}={}){return t.ORACLE_CLI_ENTRY||De(Fn(Vn(e)),"oracle.mjs")}function Nt(t,e=process.env){let r=String(e[`ORACLE_OWNER_${String(t).toUpperCase()}`]||""),n=String(e.ORACLE_OWNER_IDS||"");return new Set(`${r},${n}`.split(",").map(o=>o.trim()).filter(Boolean))}function z({platform:t,senderId:e,extraOwners:r},n=process.env){let o=String(e||"").trim();return o?Nt(t,n).has(o)?!0:Array.isArray(r)?r.map(a=>String(a).trim()).filter(Boolean).includes(o):!1:!1}function Lt(t){let e=String(t||"").trim();if(!e)return null;let r=e.replace(/^\/update(?:@[\w_]+)?\b/i,"update");return/^(?:oracle\s+)?update\s+--check\s*$/i.test(r)?{checkOnly:!0}:/^(?:oracle\s+)?update\s*$/i.test(r)?{checkOnly:!1}:null}async function It(t,{check:e=ct,update:r=lt,versionOf:n=Oe}={}){let o=await e({force:!0});if(t.checkOnly)return o.checked?o.updateAvailable?`oracle ${o.current} \u2192 ${o.latest} available. Send /update to install.`:`oracle ${o.current} is up to date`:`oracle ${o.current||"?"} \u2014 could not reach npm`;if(o.checked&&!o.updateAvailable)return`oracle ${o.current} is already up to date`;let a=o.latest||"latest",i=await r({version:a==="latest"?"latest":a});if(!i.ok)return`oracle update failed: ${i.message}`;let l=n();return[`oracle ${o.current||"?"} \u2192 ${l||a}`,"Restart the gateway to load it: oracle gateway"].join(`
16
+ `)}function Tt(t={}){return!!(t.forwarded||t.forward_from||t.forward_from_chat||t.forward_origin||t.forward_sender_name||t.forward_date)}function Pt({readConfig:t=q}={}){let e=t();return e?e.backend==="hermes"?{ok:!1,error:"model config delegates to hermes; the gateway runs Oracle's native loop. Set a standalone backend: oracle model --backend standalone"}:e.model?{ok:!0,provider:e.provider,model:e.model,reasoningEffort:e.reasoningEffort||null}:{ok:!1,error:"model config has no model \u2014 run: oracle model --backend standalone --provider <p> --model <m>"}:{ok:!1,error:"gateway has no model configured \u2014 run: oracle model --backend standalone --provider <p> --model <m>"}}function Ut(t){let r=String(t||"").trim().match(/^\/model(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim();if(!n)return{action:"list"};if(n.toLowerCase()==="show"||n==="?")return{action:"show"};if(n.toLowerCase()==="list")return{action:"list"};let o=n.split(/\s+/),a=Mt[o[0].toLowerCase()];if(a&&o.length===1)return{action:"set",provider:a.provider,model:a.model};if(a&&o.length>=2)return{action:"set",provider:a.provider,model:o.slice(1).join(" ")};if(o.length>=2)return{action:"set",provider:o[0],model:o.slice(1).join(" ")};if(o[0]?.includes(":")){let[i,l]=o[0].split(":");if(i&&l)return{action:"set",provider:i,model:l}}return{action:"usage"}}function Dt(t){let r=String(t||"").trim().match(/^\/(?:effort|reasoning)(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim().toLowerCase();return!n||n==="show"||n==="?"?{action:"show"}:Yn.includes(n)?{action:"set",reasoningEffort:n}:{action:"usage"}}function Jn({provider:t,model:e}){let r=q()||{},n=ye({...r,backend:r.backend&&r.backend!=="auto"?r.backend:"standalone",provider:t,model:e});return`model ${n.provider} / ${n.model}
17
+ Oracle persona unchanged. Native harness only \u2014 Hermes Telegram uses its own /model.`}function Xn(t){let e=q();if(!e)throw new Error("no model configured \u2014 run /model first");return`effort ${ye({...e,reasoningEffort:t}).reasoningEffort||t}
18
+ Native harness only.`}function _t(){let t=q(),e=["Oracle native models (tap /model <id> to switch):"];for(let[r,n]of Object.entries(Mt)){let o=t?.provider===n.provider&&t?.model===n.model?" \u2190 current":"";e.push(`/model ${r} ${n.provider} / ${n.model}${o}`)}return e.push(""),e.push("Add another provider: /setup model"),e.push("Or set exact id: /model <provider> <model-id>"),e.push("/effort low|medium|high"),t?.provider&&(e.push(""),e.push(`current ${t.provider} / ${t.model||"unset"} \xB7 effort ${t.reasoningEffort||"default"}`)),e.join(`
19
19
  `)}function Ue(){let t=q();return t?[`backend ${t.backend||"auto"}`,`provider ${t.provider||"unset"}`,`model ${t.model||"unset"}`,`effort ${t.reasoningEffort||"default"}`,"Aliases: claude, codex, grok, openrouter, nous, qwen, glm, deepseek, gemini, kimi, mistral, local, ollama","/effort low|medium|high"].join(`
20
20
  `):["No standalone model configured.","Use /model openrouter","or /model qwen","or /model glm","or /model nous","or /model <provider> <model-id>"].join(`
21
- `)}function Jn(t){let r=String(t||"").trim().match(/^\/setup(?:\s+model(?:\s+(.+))?)?$/i);if(!r)return null;let n=String(r[1]||"").trim();return n?{action:"hint",provider:n.split(/\s+/)[0]}:{action:"menu"}}function Dt(t){let e=String(t||"").trim();return/^\/(?:help|commands|\?)$/i.test(e)?{action:"help"}:null}function jt(t){let e=String(t||"").trim();return/^\/(?:status|usage)$/i.test(e)?{action:"status"}:null}function Bt(t){let r=String(t||"").trim().match(/^\/goal(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim();return!n||n.toLowerCase()==="show"?{action:"show"}:/^(clear|done|complete)$/i.test(n)?{action:"clear"}:{action:"set",goal:n}}function Ft(t){let r=String(t||"").trim().match(/^\/(?:compact|compress)(?:\s+(.+))?$/i);return r?{action:"compact",focus:String(r[1]||"").trim()}:null}function Ht(t){let r=String(t||"").trim().match(/^\/chain(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim();return!n||n.toLowerCase()==="list"?{action:"list"}:{action:"set",chain:n}}function je(){return Me(De,"gateway-goal.json")}function Gt(){try{let t=JSON.parse(Hn(je(),"utf8"));return t&&typeof t.goal=="string"?t:null}catch{return null}}function Qn(t){Fn(De,{recursive:!0,mode:448});let e={schemaVersion:1,goal:String(t),updatedAt:new Date().toISOString()};return Gn(je(),`${JSON.stringify(e,null,2)}
22
- `,{mode:384}),e}function Xn(){try{qn(je())}catch{}}function Zn(){return["Oracle native Telegram \u2014 owner commands","","Start here","/help this list","/commands same as /help","/status model, effort, chain, goal","","Models (like TUI /model)","/model list models you can use now","/model <id> switch: openrouter, nous, qwen, glm, claude, codex, grok, deepseek, gemini, kimi, mistral","/model <provider> <id> set an exact model id","/setup model how to add OpenRouter, Nous Portal, Qwen, GLM, ...","/setup model <id> TTY command to add that provider (never paste keys here)","/effort show current reasoning effort","/effort low|medium|high set effort like Hermes","","Session (like TUI / Hermes)","/goal show pinned objective","/goal <text> pin the session objective","/goal clear clear the objective","/compact [focus] compact context","/compress [focus] alias for /compact","/chain list working chains","/chain <name> switch chain","","Trading / signer","/update install latest Oracle","/approve Allow pending local-signer action","/deny Deny pending local-signer action","","Do not paste API keys into Telegram. Hermes Telegram keeps its own /model."].join(`
23
- `)}function eo(){let t=Ue(),e=Le(),r=Gt();return[t,`chain ${e?.key||e?.name||"default"}`,`goal ${r?.goal||"unset"}`].join(`
24
- `)}function qt(t){let e=String(t||"").trim();if(!e)return null;let r=e.match(/^\/ask(?:@[\w_]+)?\s+([\w-]+)\s+([\s\S]+)$/i);return r||(r=e.match(/^@([\w-]+)\s+([\s\S]+)$/)),r?{peer:r[1].toLowerCase(),text:r[2].trim()}:null}function K(t={}){let e=[];return t.role&&e.push(String(t.role)),Array.isArray(t.chains)&&t.chains.length&&e.push(`chains: ${t.chains.join(", ")}`),t.persona&&e.push(String(t.persona)),e.join(" \xB7 ")}function Wt(t,e,{profile:r}={}){let n=String(t||"oracle").toLowerCase(),o=String(e||"");if(n==="oracle")return{ok:!0,bin:null,args:["chat","-q",o]};if(n==="grok")return{ok:!0,bin:"grok",args:["-p",o]};if(n==="hermes"){let a=[];return r&&a.push("-p",String(r)),a.push("-z",o),{ok:!0,bin:"hermes",args:a}}return n==="claude"?{ok:!0,bin:"claude",args:["-p",o]}:{ok:!1,error:`unknown backend '${t}' (allowed: oracle, grok, hermes, claude)`}}async function oe({from:t,text:e,persona:r="",backend:n,profile:o}={}){let a=[`[a2a consult from agent '${t}' \u2014 answer with information only; do not prepare, arm, or execute anything]`,r?`[your role: ${r}]`:"",String(e||"").trim()].filter(Boolean).join(`
25
- `);return Vt({text:a,backend:n,profile:o,unconfiguredPrefix:"unconfigured: "})}async function O({platform:t,chatId:e,senderId:r,text:n,userName:o,meta:a={},updater:i,extraOwners:c,bus:l,agentName:s,persona:d,backend:p,profile:m}={}){if(!z({platform:t,senderId:r,extraOwners:c}))return process.stderr.write(`gateway: denied non-owner sender ${t}:${String(r||"unknown")}
26
- `),V;if(It(a))return process.stderr.write(`gateway: dropped forwarded message on ${t}
27
- `),null;let h=Lt(n);if(h)return Nt(h,i);let g=Ut(n);if(g)try{return g.action==="list"?$t():g.action==="show"?Ue():g.action==="usage"?$t():Kn(g)}catch(y){return`model not saved: ${y.message}`}let k=Mt(n);if(k)try{return k.action==="show"?Ue():k.action==="usage"?"usage: /effort low|medium|high":Yn(k.reasoningEffort)}catch(y){return`effort not saved: ${y.message}`}if(Dt(n))return Zn();if(jt(n))return eo();let v=Bt(n);if(v){if(v.action==="show"){let y=Gt();return y?.goal?`goal ${y.goal}`:"goal unset \u2014 /goal <objective>"}return v.action==="clear"?(Xn(),"goal cleared"):(Qn(v.goal),`goal pinned: ${v.goal}`)}let x=Ft(n);if(x){let y=x.focus?` Focus: ${x.focus}.`:"";return _t({platform:t,chatId:e,senderId:r,text:`Compact this session context now.${y} Summarize older turns, keep the current goal, model, chain, and any pending unsigned prepare artifacts. Do not sign or broadcast.`,userName:o,persona:d,backend:p,profile:m})}let C=Ht(n);if(C){if(C.action==="list")return pt({selectedKey:Le()?.key||null});let y=ee(C.chain);return y?(ft(y.key),`chain ${y.key}`):`unknown chain '${C.chain}' \u2014 /chain list`}if(ve(n)){let y=await Ce({platform:t,text:n,grant:{local:!0}});return y?y.buttons?.kind==="inline_keyboard"?{text:y.text,replyMarkup:y.buttons.replyMarkup}:y.text:null}if(l){let y=qt(n);if(y){let I=await l.send({from:s||"oracle",to:y.peer,text:y.text,kind:"consult"});return I.ok?I.reply?`[${y.peer}] ${I.reply}`:`[${y.peer}] (no reply)`:I.error}if(/^\/(agents|roster)\b/i.test(String(n||"").trim())){let I=l.roster().map(Q=>`\u2022 ${Q.name}${Q.role?` \u2014 ${Q.role}`:""}${Q.chains.length?` (${Q.chains.join(", ")})`:""}`);return I.length?`Agents on the bus:
21
+ `)}function Qn(t){let r=String(t||"").trim().match(/^\/setup(?:\s+model(?:\s+(.+))?)?$/i);if(!r)return null;let n=String(r[1]||"").trim();return n?{action:"hint",provider:n.split(/\s+/)[0]}:{action:"menu"}}function jt(t){let e=String(t||"").trim();return/^\/(?:help|commands|\?)$/i.test(e)?{action:"help"}:null}function Bt(t){let e=String(t||"").trim();return/^\/(?:status|usage)$/i.test(e)?{action:"status"}:null}function Ft(t){let r=String(t||"").trim().match(/^\/goal(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim();return!n||n.toLowerCase()==="show"?{action:"show"}:/^(clear|done|complete)$/i.test(n)?{action:"clear"}:{action:"set",goal:n}}function Ht(t){let r=String(t||"").trim().match(/^\/(?:compact|compress)(?:\s+(.+))?$/i);return r?{action:"compact",focus:String(r[1]||"").trim()}:null}function Gt(t){let r=String(t||"").trim().match(/^\/chain(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim();return!n||n.toLowerCase()==="list"?{action:"list"}:{action:"set",chain:n}}function Be(){return De(je,"gateway-goal.json")}function qt(){try{let t=JSON.parse(qn(Be(),"utf8"));return t&&typeof t.goal=="string"?t:null}catch{return null}}function Zn(t){Gn(je,{recursive:!0,mode:448});let e={schemaVersion:1,goal:String(t),updatedAt:new Date().toISOString()};return Wn(Be(),`${JSON.stringify(e,null,2)}
22
+ `,{mode:384}),e}function eo(){try{zn(Be())}catch{}}function to(){return["Oracle native Telegram \u2014 owner commands","","Start here","/help this list","/commands same as /help","/status model, effort, chain, goal","","Models (like TUI /model)","/model list models you can use now","/model <id> switch: openrouter, nous, qwen, glm, claude, codex, grok, deepseek, gemini, kimi, mistral","/model <provider> <id> set an exact model id","/setup model how to add OpenRouter, Nous Portal, Qwen, GLM, ...","/setup model <id> TTY command to add that provider (never paste keys here)","/effort show current reasoning effort","/effort low|medium|high set effort like Hermes","","Session (like TUI / Hermes)","/goal show pinned objective","/goal <text> pin the session objective","/goal clear clear the objective","/compact [focus] compact context","/compress [focus] alias for /compact","/chain list working chains","/chain <name> switch chain","","Trading / signer","/update install latest Oracle","/approve Allow pending local-signer action","/deny Deny pending local-signer action","","Do not paste API keys into Telegram. Hermes Telegram keeps its own /model."].join(`
23
+ `)}function ro(){let t=Ue(),e=Le(),r=qt();return[t,`chain ${e?.key||e?.name||"default"}`,`goal ${r?.goal||"unset"}`].join(`
24
+ `)}function Wt(t){let e=String(t||"").trim();if(!e)return null;let r=e.match(/^\/ask(?:@[\w_]+)?\s+([\w-]+)\s+([\s\S]+)$/i);return r||(r=e.match(/^@([\w-]+)\s+([\s\S]+)$/)),r?{peer:r[1].toLowerCase(),text:r[2].trim()}:null}function K(t={}){let e=[];return t.role&&e.push(String(t.role)),Array.isArray(t.chains)&&t.chains.length&&e.push(`chains: ${t.chains.join(", ")}`),t.persona&&e.push(String(t.persona)),e.join(" \xB7 ")}function zt(t,e,{profile:r}={}){let n=String(t||"oracle").toLowerCase(),o=String(e||"");if(n==="oracle")return{ok:!0,bin:null,args:["chat","-q",o]};if(n==="grok")return{ok:!0,bin:"grok",args:["-p",o]};if(n==="hermes"){let a=[];return r&&a.push("-p",String(r)),a.push("-z",o),{ok:!0,bin:"hermes",args:a}}return n==="claude"?{ok:!0,bin:"claude",args:["-p",o]}:{ok:!1,error:`unknown backend '${t}' (allowed: oracle, grok, hermes, claude)`}}async function oe({from:t,text:e,persona:r="",backend:n,profile:o}={}){let a=[`[a2a consult from agent '${t}' \u2014 answer with information only; do not prepare, arm, or execute anything]`,r?`[your role: ${r}]`:"",String(e||"").trim()].filter(Boolean).join(`
25
+ `);return Kt({text:a,backend:n,profile:o,unconfiguredPrefix:"unconfigured: "})}async function O({platform:t,chatId:e,senderId:r,text:n,userName:o,meta:a={},updater:i,extraOwners:l,bus:c,agentName:s,persona:d,backend:p,profile:m}={}){if(!z({platform:t,senderId:r,extraOwners:l}))return process.stderr.write(`gateway: denied non-owner sender ${t}:${String(r||"unknown")}
26
+ `),V;if(Tt(a))return process.stderr.write(`gateway: dropped forwarded message on ${t}
27
+ `),null;let h=Lt(n);if(h)return It(h,i);let g=Ut(n);if(g)try{return g.action==="list"?_t():g.action==="show"?Ue():g.action==="usage"?_t():Jn(g)}catch(y){return`model not saved: ${y.message}`}let k=Dt(n);if(k)try{return k.action==="show"?Ue():k.action==="usage"?"usage: /effort low|medium|high":Xn(k.reasoningEffort)}catch(y){return`effort not saved: ${y.message}`}if(jt(n))return to();if(Bt(n))return ro();let v=Ft(n);if(v){if(v.action==="show"){let y=qt();return y?.goal?`goal ${y.goal}`:"goal unset \u2014 /goal <objective>"}return v.action==="clear"?(eo(),"goal cleared"):(Zn(v.goal),`goal pinned: ${v.goal}`)}let x=Ht(n);if(x){let y=x.focus?` Focus: ${x.focus}.`:"";return Et({platform:t,chatId:e,senderId:r,text:`Compact this session context now.${y} Summarize older turns, keep the current goal, model, chain, and any pending unsigned prepare artifacts. Do not sign or broadcast.`,userName:o,persona:d,backend:p,profile:m})}let C=Gt(n);if(C){if(C.action==="list")return ht({selectedKey:Le()?.key||null});let y=ee(C.chain);return y?(yt(y.key),`chain ${y.key}`):`unknown chain '${C.chain}' \u2014 /chain list`}if(Ae(n)){let y=await $e({platform:t,text:n,grant:{local:!0}});return y?y.buttons?.kind==="inline_keyboard"?{text:y.text,replyMarkup:y.buttons.replyMarkup}:y.text:null}if(c){let y=Wt(n);if(y){let I=await c.send({from:s||"oracle",to:y.peer,text:y.text,kind:"consult"});return I.ok?I.reply?`[${y.peer}] ${I.reply}`:`[${y.peer}] (no reply)`:I.error}if(/^\/(agents|roster)\b/i.test(String(n||"").trim())){let I=c.roster().map(X=>`\u2022 ${X.name}${X.role?` \u2014 ${X.role}`:""}${X.chains.length?` (${X.chains.join(", ")})`:""}`);return I.length?`Agents on the bus:
28
28
  ${I.join(`
29
- `)}`:"No peer agents registered."}}let br=n.toLowerCase().trim();return/\b(buy|sell|swap|bridge|send|transfer|balance|portfolio|watch|quote|price)\b/.test(br)?ro({platform:t,chatId:e,senderId:r,text:n,userName:o}):_t({platform:t,chatId:e,senderId:r,text:n,userName:o,persona:d,backend:p,profile:m})}function zt(t,{timeout:e=12e4}={}){return new Promise(r=>{let n=Et(process.execPath,[zn,...t],{stdio:["ignore","pipe","pipe"],timeout:e,env:{...process.env,ORACLE_CONFIG_DIR:De}}),o="",a="";n.stdout.on("data",i=>o+=i.toString()),n.stderr.on("data",i=>a+=i.toString()),n.on("close",i=>r({code:i,out:o.trim(),err:a.trim()}))})}function to(t,e,{timeout:r=18e4}={}){return new Promise(n=>{let o=Et(t,e,{stdio:["ignore","pipe","pipe"],timeout:r,env:{...process.env}}),a="",i="";o.on("error",c=>n({code:127,out:"",err:String(c.message)})),o.stdout.on("data",c=>a+=c.toString()),o.stderr.on("data",c=>i+=c.toString()),o.on("close",c=>n({code:c,out:a.trim(),err:i.trim()}))})}async function ro({text:t,chatId:e}){let r=await zt(["route","swap","--text",t],{timeout:3e4});if(r.code===0&&r.out)try{return no(JSON.parse(r.out),{chatId:e})}catch{return r.out}return`Trade routing failed. Try: \`${t}\` again.`}async function _t({text:t,persona:e,backend:r,profile:n}){let o=e?`[your role: ${e}]
30
- ${t}`:t;return Vt({text:o,backend:r,profile:n,unconfiguredPrefix:"Oracle is not configured yet: "})}async function Vt({text:t,backend:e,profile:r,unconfiguredPrefix:n}){let o=Wt(e,t,{profile:r});if(!o.ok)return`${n}${o.error}`;if(!o.bin){let i=Tt();if(!i.ok)return`${n}${i.error}`;let c=await zt(o.args);return c.code===0&&c.out?c.out:c.err||"Oracle could not answer that. Try again."}let a=await to(o.bin,o.args);return a.code===0&&a.out?a.out:/ENOENT/.test(a.err)?`${n}backend '${o.bin}' is not installed on this machine`:a.err||`${o.bin} could not answer that. Try again.`}function no(t,{chatId:e}={}){if(t.error)return`\u274C ${t.error}`;let r=t.quote||t.portfolio||(t.tx?"Unsigned trade prepared. Sign from your own wallet.":"");if(!r&&!t.tx)return JSON.stringify(t,null,2);let n=Ct({id:String(t.artifactId||`trade-${Date.now().toString(36)}`).toLowerCase().slice(0,40),kind:t.tx?"prepared_action":t.quote?"strategy":"thesis",title:t.tx?"Prepared trade":t.quote?"Quote":"Desk update",summary:r,payload:t},{grant:{local:!0}});return e&&Te(n.state,{chatId:e,artifactId:n.artifact.id}),de(re(),n.state),{text:n.text,replyMarkup:n.replyMarkup}}var De,zn,V,Pt,Vn,Y=w(()=>{Je();$e();st();Oe();ht();Pe();De=process.env.ORACLE_CONFIG_DIR||Me(Bn(),".config","oracle");zn=Ot();V="Oracle is self-hostable. Install your own instance: npm install -g @oracle-agent/oracle";Pt=Object.freeze({claude:{provider:"anthropic-oauth",model:"claude-sonnet-4-20250514"},anthropic:{provider:"anthropic",model:"claude-sonnet-4-6"},codex:{provider:"openai-codex",model:"gpt-5.4"},openai:{provider:"openai",model:"gpt-4.1-mini"},grok:{provider:"xai-oauth",model:"grok-4.6"},xai:{provider:"xai",model:"grok-4.6"},openrouter:{provider:"openrouter",model:"openrouter/auto"},nous:{provider:"nous",model:"moonshotai/kimi-k3"},deepseek:{provider:"deepseek",model:"deepseek-chat"},gemini:{provider:"gemini",model:"gemini-2.5-flash"},kimi:{provider:"kimi",model:"kimi-k3"},mistral:{provider:"mistral",model:"mistral-large-latest"},qwen:{provider:"qwen",model:"qwen-plus"},glm:{provider:"glm",model:"glm-4.5"},local:{provider:"local",model:"Qwen3-8B-Q4_K_M"},llama:{provider:"local",model:"Qwen3-8B-Q4_K_M"},ollama:{provider:"ollama",model:"llama3.2"}}),Vn=Object.freeze(["low","medium","high"])});function ao(t,e){let r=new Set,n=[];for(let o of Array.isArray(t)?t:[]){let a=typeof o?.digest=="string"?o.digest:null;a&&(r.add(a),e.has(a)||n.push(o))}e.clear();for(let o of r)e.add(o);return n}function Yt({onNew:t,intervalMs:e=oo,env:r=process.env,signerCall:n=T,setIntervalFn:o=setInterval,clearIntervalFn:a=clearInterval}={}){if(typeof t!="function")throw new Error("pending-watch: onNew callback required");let i=new Set,c=!1,l=!1;async function s(){if(!l){l=!0;try{let p=await n("/pending",{env:r});if(!p||p.ok===!1||p.error||!Array.isArray(p.items))return;let m=ao(p.items,i);if(!c){c=!0;return}if(m.length===0)return;try{await t(m,{armed:p.armed===!0})}catch{}}catch{}finally{l=!1}}}let d=o(s,e);return typeof d?.unref=="function"&&d.unref(),{stop(){a(d)},tick:s}}var oo,Jt=w(()=>{ce();oo=4e3});import D from"node:fs";function io(t){if(!t.isFile())throw new Error("local-vault: secret source must be a regular file");if(t.uid!==process.getuid?.())throw new Error("local-vault: secret source must be owned by this user");if(t.nlink!==1)throw new Error("local-vault: refusing hard-linked secret source");if((t.mode&63)!==0)throw new Error("local-vault: secret source must be owner-only (0600)")}function Qt(t){let e;try{e=D.openSync(t,D.constants.O_RDONLY|D.constants.O_NOFOLLOW)}catch(r){throw r.code==="ELOOP"?new Error("local-vault: refusing symlink"):r}try{let r=D.fstatSync(e);if(io(r),r.size>1024*1024)throw new Error("local-vault: secret source changed or is too large");let n=D.lstatSync(t);if(n.isSymbolicLink()||n.dev!==r.dev||n.ino!==r.ino)throw new Error("local-vault: secret source changed or is too large");return D.readFileSync(e,"utf8").replace(/[\r\n]+$/,"")}finally{D.closeSync(e)}}var Ja,Qa,Xa,Xt=w(()=>{Ja=Object.freeze({N:1<<17,r:8,p:1}),Qa=256*1024*1024,Xa=16*1024});import{createHash as so,createHmac as Zt,randomBytes as co,timingSafeEqual as lo}from"node:crypto";function rr({keyFile:t,approvedTelegramOwners:e,nowMs:r=Date.now}={}){if(!t)throw new Error("cex owner proof: signer policy key required");let n=new Set((e||[]).map(J).filter(Boolean));if(!n.size)throw new Error("cex owner proof: approved owner context required");let o=new Set,a=c=>{let l=Buffer.from(Qt(t));try{return c(l)}finally{l.fill(0)}},i=a(c=>so("sha256").update("cex-owner-instance\0").update(c).digest("hex"));return Object.freeze({mint({digest:c,senderId:l,chatId:s,platform:d,ttlMs:p=15e3}={}){let m=J(l),h=J(s),g=r();if(d!=="telegram"||!m||h!==m||!n.has(m))throw new Error("cex owner proof: exact Telegram owner DM required");if(!/^[0-9a-f]{64}$/.test(String(c||""))||!Number.isSafeInteger(p)||p<1||p>3e4)throw new Error("cex owner proof: binding refused");let k={version:1,decision:"Allow",digest:c,ownerSenderId:m,telegramChatId:h,audience:er,instance:i,nonce:co(16).toString("hex"),issuedAtMs:g,expiresAtMs:g+p},v=a(x=>Zt("sha256",x).update(tr(k)).digest("hex"));return{claims:k,mac:v}},verify(c,{digest:l}={}){let s=c?.claims,d=r();if(!s||s.version!==1||s.decision!=="Allow"||s.digest!==l||s.audience!==er||s.instance!==i||!/^[0-9a-f]{32}$/.test(s.nonce||"")||J(s.ownerSenderId)!==J(s.telegramChatId)||!n.has(J(s.ownerSenderId))||!Number.isSafeInteger(s.issuedAtMs)||!Number.isSafeInteger(s.expiresAtMs)||s.expiresAtMs<=d||s.issuedAtMs>d||s.expiresAtMs-s.issuedAtMs>3e4||o.has(s.nonce))return!1;let p=a(m=>Zt("sha256",m).update(tr(s)).digest("hex"));return uo(c.mac,p)?(o.add(s.nonce),!0):!1}})}var er,J,tr,uo,nr=w(()=>{Xt();er="oracle-local-signer-cex-owner-allow-v1",J=t=>/^(?:0|[1-9]\d{0,19})$/.test(String(t||""))?String(t):null,tr=t=>JSON.stringify(t),uo=(t,e)=>{let r=Buffer.from(String(t)),n=Buffer.from(String(e));return r.length===n.length&&lo(r,n)}});var sr={};j(sr,{buildPersona:()=>K,telegram:()=>mo,telegramPendingRecipients:()=>ir});import{join as or}from"node:path";import{homedir as po}from"node:os";function pe(t=process.env){return kt(re(t)),ue()}function ar(t=process.env){de(re(t),ue())}function ir({extraOwners:t,env:e=process.env}={}){let r=String(e.ORACLE_OWNER_TELEGRAM||"").split(",").map(o=>o.trim()).filter(Boolean),n=Array.isArray(t)?t.map(o=>String(o).trim()):[];return[...new Set([...r,...n])].filter(o=>/^\d+$/.test(o))}function Be(t,e){if(!e)return;if(typeof e=="string")return t.reply(e,{parse_mode:"Markdown"});let r=e.replyMarkup?{reply_markup:e.replyMarkup}:{};return t.reply(e.text,{parse_mode:"Markdown",...r})}async function mo(t){let{Bot:e}=await import("grammy");pe();let r=new e(t.token),n=String(t.name||"oracle").toLowerCase(),o=K(t),a=Array.isArray(t.owners)?t.owners:void 0,i=t.bus;i&&i.register(n,{role:t.role||"",chains:t.chains||[],handler:s=>oe({from:s.from,text:s.text,persona:o,backend:t.backend,profile:t.hermesProfile})}),r.command("start",s=>{let d=String(s.from?.id||s.chat.id);if(!z({platform:"telegram",senderId:d,extraOwners:a}))return s.reply(V);let p=String(s.match||"").trim();if(p){let m=pe(),h=vt(m,{token:p,telegramUserId:d});return ar(),h.ok?s.reply("Telegram linked to Oracle. Agent artifacts will land as interactive cards. Deepen stays in this thread."):s.reply(`Link failed: ${h.error}`)}return s.reply(`${n} ready. /help lists every native command. /model lists models. /setup model adds OpenRouter, Nous Portal, Qwen, GLM. /effort sets reasoning. /update installs latest.${i?" /agents lists peers.":""}`)}),r.command("update",async s=>{let d=String(s.from?.id||s.chat.id),p=String(s.chat.id);if(!z({platform:"telegram",senderId:d,extraOwners:a}))return s.reply(V);if(s.message.forward_origin||s.message.forward_from||s.message.forward_date)return;s.replyWithChatAction("typing").catch(()=>{});let m=await O({platform:"telegram",chatId:p,senderId:d,text:s.match?`update ${s.match}`.trim():"update",userName:s.from?.username||s.from?.first_name||"user"});if(m)return Be(s,m)}),r.on("message:text",async s=>{let d=String(s.chat.id),p=String(s.from?.id||d),m=s.message.text;try{s.replyWithChatAction("typing").catch(()=>{});let h=pe(),g=xt(h,{chatId:d,text:m}),k=await O({platform:"telegram",chatId:d,senderId:p,text:g||m,userName:s.from?.username||s.from?.first_name||"user",extraOwners:a,bus:i,agentName:n,persona:o,backend:t.backend,profile:t.hermesProfile,meta:{forward_origin:s.message.forward_origin,forward_from:s.message.forward_from,forward_from_chat:s.message.forward_from_chat,forward_sender_name:s.message.forward_sender_name,forward_date:s.message.forward_date}});k&&await Be(s,k)}catch(h){process.stderr.write(`telegram-gateway[${n}]: ${h.message}
31
- `),await s.reply("Something went wrong. Try again.").catch(()=>{})}}),r.on("callback_query:data",async s=>{let d=String(s.from?.id||"");if(!z({platform:"telegram",senderId:d,extraOwners:a})){await s.answerCallbackQuery({text:V.slice(0,180),show_alert:!0}).catch(()=>{});return}let p=String(s.callbackQuery?.data||""),m=String(process.env.ORACLE_OWNER_TELEGRAM||"").split(",").map(v=>v.trim()).filter(Boolean),h=process.env.ORACLE_CONFIG_DIR||or(po(),".config","oracle"),g;try{g=rr({keyFile:or(h,"signer","policy-integrity-key"),approvedTelegramOwners:m})}catch{}let k=await tt({platform:"telegram",data:p,senderId:d,chatId:String(s.chat?.id||""),ownerProofAuthority:g,grant:{local:!0}});if(!k){let v=pe(),x=At(v,{data:p,chatId:String(s.chat?.id||""),grant:{local:!0}});if(ar(),!x){await s.answerCallbackQuery().catch(()=>{});return}if(await s.answerCallbackQuery({text:"ok"}).catch(()=>{}),x.prompt){let C=await O({platform:"telegram",chatId:String(s.chat?.id||""),senderId:d,text:x.prompt,extraOwners:a,bus:i,agentName:n,persona:o,backend:t.backend,profile:t.hermesProfile});C&&await Be(s,C);return}if(x.text){let C=x.buttons?.replyMarkup?{reply_markup:x.buttons.replyMarkup}:{};await s.reply(x.text,{parse_mode:"Markdown",...C}).catch(()=>{})}return}await s.answerCallbackQuery({text:"ok"}).catch(()=>{}),k.text&&await s.reply(k.text,{parse_mode:"Markdown"}).catch(()=>{})}),r.start();let c=ir({extraOwners:a}),l=null;return c.length>0&&t.pendingWatch!==!1&&(l=Yt({intervalMs:t.pendingWatchIntervalMs,onNew:async(s,{armed:d})=>{let p=Ae(s,{platform:"telegram",grant:{local:!0},armed:d}),m=p.buttons?.replyMarkup?{reply_markup:p.buttons.replyMarkup}:{};for(let h of c)await r.api.sendMessage(h,p.text,{parse_mode:"Markdown",...m}).catch(()=>{})}})),{platform:"telegram",name:n,bot:r,stopPendingWatch:()=>l?.stop()}}var cr=w(()=>{Y();$e();Jt();nr();Pe()});var lr={};j(lr,{discord:()=>fo});async function fo(t){let{Client:e,GatewayIntentBits:r}=await import("discord.js"),n=new e({intents:[r.Guilds,r.GuildMessages,r.MessageContent,r.DirectMessages]}),o=String(t.name||"oracle").toLowerCase(),a=K(t),i=Array.isArray(t.owners)?t.owners:void 0,c=t.bus;return c&&c.register(o,{role:t.role||"",chains:t.chains||[],handler:l=>oe({from:l.from,text:l.text,persona:a,backend:t.backend,profile:t.hermesProfile})}),n.on("messageCreate",async l=>{if(l.author.bot)return;let s=l.channel.id,d=l.author.id,p=l.content;try{let m=!l.guild,h=l.mentions.has(n.user.id);if(!m&&!h)return;l.channel.sendTyping().catch(()=>{});let g=await O({platform:"discord",chatId:s,senderId:d,text:p.replace(`<@${n.user.id}>`,"").trim(),userName:l.author.username,extraOwners:i,bus:c,agentName:o,persona:a,backend:t.backend,profile:t.hermesProfile,meta:{forwarded:l.reference?.type===1||Array.isArray(l.messageSnapshots)&&l.messageSnapshots.length>0}});g&&await l.reply(typeof g=="string"?g:g.text).catch(()=>{})}catch(m){process.stderr.write(`discord-gateway[${o}]: ${m.message}
32
- `)}}),await n.login(t.token),{platform:"discord",name:o,client:n}}var ur=w(()=>{Y()});var pr={};j(pr,{whatsapp:()=>yo});import{join as dr}from"node:path";import{homedir as ho}from"node:os";async function yo(t){let[{Client:e,LocalAuth:r},{generate:n}]=await Promise.all([import("whatsapp-web.js"),import("qrcode-terminal")]),o=new e({authStrategy:new r({dataPath:dr(go,".wwebjs_auth")}),puppeteer:{headless:!0,args:["--no-sandbox"]}});return o.on("qr",a=>{process.stderr.write(`
29
+ `)}`:"No peer agents registered."}}let xr=n.toLowerCase().trim();return/\b(buy|sell|swap|bridge|send|transfer|balance|portfolio|watch|quote|price)\b/.test(xr)?oo({platform:t,chatId:e,senderId:r,text:n,userName:o}):Et({platform:t,chatId:e,senderId:r,text:n,userName:o,persona:d,backend:p,profile:m})}function Vt(t,{timeout:e=12e4}={}){return new Promise(r=>{let n=Ot(process.execPath,[Kn,...t],{stdio:["ignore","pipe","pipe"],timeout:e,env:{...process.env,ORACLE_CONFIG_DIR:je}}),o="",a="";n.stdout.on("data",i=>o+=i.toString()),n.stderr.on("data",i=>a+=i.toString()),n.on("close",i=>r({code:i,out:o.trim(),err:a.trim()}))})}function no(t,e,{timeout:r=18e4}={}){return new Promise(n=>{let o=Ot(t,e,{stdio:["ignore","pipe","pipe"],timeout:r,env:{...process.env}}),a="",i="";o.on("error",l=>n({code:127,out:"",err:String(l.message)})),o.stdout.on("data",l=>a+=l.toString()),o.stderr.on("data",l=>i+=l.toString()),o.on("close",l=>n({code:l,out:a.trim(),err:i.trim()}))})}async function oo({text:t,chatId:e}){let r=await Vt(["route","swap","--text",t],{timeout:3e4});if(r.code===0&&r.out)try{return ao(JSON.parse(r.out),{chatId:e})}catch{return r.out}return`Trade routing failed. Try: \`${t}\` again.`}async function Et({text:t,persona:e,backend:r,profile:n}){let o=e?`[your role: ${e}]
30
+ ${t}`:t;return Kt({text:o,backend:r,profile:n,unconfiguredPrefix:"Oracle is not configured yet: "})}async function Kt({text:t,backend:e,profile:r,unconfiguredPrefix:n}){let o=zt(e,t,{profile:r});if(!o.ok)return`${n}${o.error}`;if(!o.bin){let i=Pt();if(!i.ok)return`${n}${i.error}`;let l=await Vt(o.args);return l.code===0&&l.out?l.out:l.err||"Oracle could not answer that. Try again."}let a=await no(o.bin,o.args);return a.code===0&&a.out?a.out:/ENOENT/.test(a.err)?`${n}backend '${o.bin}' is not installed on this machine`:a.err||`${o.bin} could not answer that. Try again.`}function ao(t,{chatId:e}={}){if(t.error)return`\u274C ${t.error}`;let r=t.quote||t.portfolio||(t.tx?"Unsigned trade prepared. Sign from your own wallet.":"");if(!r&&!t.tx)return JSON.stringify(t,null,2);let n=$t({id:String(t.artifactId||`trade-${Date.now().toString(36)}`).toLowerCase().slice(0,40),kind:t.tx?"prepared_action":t.quote?"strategy":"thesis",title:t.tx?"Prepared trade":t.quote?"Quote":"Desk update",summary:r,payload:t},{grant:{local:!0}});return e&&Pe(n.state,{chatId:e,artifactId:n.artifact.id}),de(re(),n.state),{text:n.text,replyMarkup:n.replyMarkup}}var je,Kn,V,Mt,Yn,Y=w(()=>{Xe();_e();ut();Re();wt();Me();je=process.env.ORACLE_CONFIG_DIR||De(Hn(),".config","oracle");Kn=Rt();V="Oracle is self-hostable. Install your own instance: npm install -g @oracle-agent/oracle";Mt=Object.freeze({claude:{provider:"anthropic-oauth",model:"claude-sonnet-4-20250514"},anthropic:{provider:"anthropic",model:"claude-sonnet-4-6"},codex:{provider:"openai-codex",model:"gpt-5.4"},openai:{provider:"openai",model:"gpt-4.1-mini"},grok:{provider:"xai-oauth",model:"grok-4.6"},xai:{provider:"xai",model:"grok-4.6"},openrouter:{provider:"openrouter",model:"openrouter/auto"},nous:{provider:"nous",model:"moonshotai/kimi-k3"},deepseek:{provider:"deepseek",model:"deepseek-chat"},gemini:{provider:"gemini",model:"gemini-2.5-flash"},kimi:{provider:"kimi",model:"kimi-k3"},mistral:{provider:"mistral",model:"mistral-large-latest"},qwen:{provider:"qwen",model:"qwen-plus"},glm:{provider:"glm",model:"glm-4.5"},local:{provider:"local",model:"Qwen3-8B-Q4_K_M"},llama:{provider:"local",model:"Qwen3-8B-Q4_K_M"},ollama:{provider:"ollama",model:"llama3.2"}}),Yn=Object.freeze(["low","medium","high"])});function so(t,e){let r=new Set,n=[];for(let o of Array.isArray(t)?t:[]){let a=typeof o?.digest=="string"?o.digest:null;a&&(r.add(a),e.has(a)||n.push(o))}e.clear();for(let o of r)e.add(o);return n}function Jt({onNew:t,intervalMs:e=io,env:r=process.env,signerCall:n=T,setIntervalFn:o=setInterval,clearIntervalFn:a=clearInterval}={}){if(typeof t!="function")throw new Error("pending-watch: onNew callback required");let i=new Set,l=!1,c=!1;async function s(){if(!c){c=!0;try{let p=await n("/pending",{env:r});if(!p||p.ok===!1||p.error||!Array.isArray(p.items))return;let m=so(p.items,i);if(!l){l=!0;return}if(m.length===0)return;try{await t(m,{armed:p.armed===!0})}catch{}}catch{}finally{c=!1}}}let d=o(s,e);return typeof d?.unref=="function"&&d.unref(),{stop(){a(d)},tick:s}}var io,Xt=w(()=>{ce();io=4e3});import D from"node:fs";function co(t){if(!t.isFile())throw new Error("local-vault: secret source must be a regular file");if(t.uid!==process.getuid?.())throw new Error("local-vault: secret source must be owned by this user");if(t.nlink!==1)throw new Error("local-vault: refusing hard-linked secret source");if((t.mode&63)!==0)throw new Error("local-vault: secret source must be owner-only (0600)")}function Qt(t){let e;try{e=D.openSync(t,D.constants.O_RDONLY|D.constants.O_NOFOLLOW)}catch(r){throw r.code==="ELOOP"?new Error("local-vault: refusing symlink"):r}try{let r=D.fstatSync(e);if(co(r),r.size>1024*1024)throw new Error("local-vault: secret source changed or is too large");let n=D.lstatSync(t);if(n.isSymbolicLink()||n.dev!==r.dev||n.ino!==r.ino)throw new Error("local-vault: secret source changed or is too large");return D.readFileSync(e,"utf8").replace(/[\r\n]+$/,"")}finally{D.closeSync(e)}}var ai,ii,si,Zt=w(()=>{ai=Object.freeze({N:1<<17,r:8,p:1}),ii=256*1024*1024,si=16*1024});import{createHash as lo,createHmac as er,randomBytes as uo,timingSafeEqual as po}from"node:crypto";function nr({keyFile:t,approvedTelegramOwners:e,nowMs:r=Date.now}={}){if(!t)throw new Error("cex owner proof: signer policy key required");let n=new Set((e||[]).map(J).filter(Boolean));if(!n.size)throw new Error("cex owner proof: approved owner context required");let o=new Set,a=l=>{let c=Buffer.from(Qt(t));try{return l(c)}finally{c.fill(0)}},i=a(l=>lo("sha256").update("cex-owner-instance\0").update(l).digest("hex"));return Object.freeze({mint({digest:l,senderId:c,chatId:s,platform:d,ttlMs:p=15e3}={}){let m=J(c),h=J(s),g=r();if(d!=="telegram"||!m||h!==m||!n.has(m))throw new Error("cex owner proof: exact Telegram owner DM required");if(!/^[0-9a-f]{64}$/.test(String(l||""))||!Number.isSafeInteger(p)||p<1||p>3e4)throw new Error("cex owner proof: binding refused");let k={version:1,decision:"Allow",digest:l,ownerSenderId:m,telegramChatId:h,audience:tr,instance:i,nonce:uo(16).toString("hex"),issuedAtMs:g,expiresAtMs:g+p},v=a(x=>er("sha256",x).update(rr(k)).digest("hex"));return{claims:k,mac:v}},verify(l,{digest:c}={}){let s=l?.claims,d=r();if(!s||s.version!==1||s.decision!=="Allow"||s.digest!==c||s.audience!==tr||s.instance!==i||!/^[0-9a-f]{32}$/.test(s.nonce||"")||J(s.ownerSenderId)!==J(s.telegramChatId)||!n.has(J(s.ownerSenderId))||!Number.isSafeInteger(s.issuedAtMs)||!Number.isSafeInteger(s.expiresAtMs)||s.expiresAtMs<=d||s.issuedAtMs>d||s.expiresAtMs-s.issuedAtMs>3e4||o.has(s.nonce))return!1;let p=a(m=>er("sha256",m).update(rr(s)).digest("hex"));return mo(l.mac,p)?(o.add(s.nonce),!0):!1}})}var tr,J,rr,mo,or=w(()=>{Zt();tr="oracle-local-signer-cex-owner-allow-v1",J=t=>/^(?:0|[1-9]\d{0,19})$/.test(String(t||""))?String(t):null,rr=t=>JSON.stringify(t),mo=(t,e)=>{let r=Buffer.from(String(t)),n=Buffer.from(String(e));return r.length===n.length&&po(r,n)}});var cr={};j(cr,{buildPersona:()=>K,telegram:()=>ho,telegramPendingRecipients:()=>sr});import{join as ar}from"node:path";import{homedir as fo}from"node:os";function pe(t=process.env){return St(re(t)),ue()}function ir(t=process.env){de(re(t),ue())}function sr({extraOwners:t,env:e=process.env}={}){let r=String(e.ORACLE_OWNER_TELEGRAM||"").split(",").map(o=>o.trim()).filter(Boolean),n=Array.isArray(t)?t.map(o=>String(o).trim()):[];return[...new Set([...r,...n])].filter(o=>/^\d+$/.test(o))}function Fe(t,e){if(!e)return;if(typeof e=="string")return t.reply(e,{parse_mode:"Markdown"});let r=e.replyMarkup?{reply_markup:e.replyMarkup}:{};return t.reply(e.text,{parse_mode:"Markdown",...r})}async function ho(t){let{Bot:e}=await import("grammy");pe();let r=new e(t.token),n=String(t.name||"oracle").toLowerCase(),o=K(t),a=Array.isArray(t.owners)?t.owners:void 0,i=t.bus;i&&i.register(n,{role:t.role||"",chains:t.chains||[],handler:s=>oe({from:s.from,text:s.text,persona:o,backend:t.backend,profile:t.hermesProfile})}),r.command("start",s=>{let d=String(s.from?.id||s.chat.id);if(!z({platform:"telegram",senderId:d,extraOwners:a}))return s.reply(V);let p=String(s.match||"").trim();if(p){let m=pe(),h=At(m,{token:p,telegramUserId:d});return ir(),h.ok?s.reply("Telegram linked to Oracle. Agent artifacts will land as interactive cards. Deepen stays in this thread."):s.reply(`Link failed: ${h.error}`)}return s.reply(`${n} ready. /help lists every native command. /model lists models. /setup model adds OpenRouter, Nous Portal, Qwen, GLM. /effort sets reasoning. /update installs latest.${i?" /agents lists peers.":""}`)}),r.command("update",async s=>{let d=String(s.from?.id||s.chat.id),p=String(s.chat.id);if(!z({platform:"telegram",senderId:d,extraOwners:a}))return s.reply(V);if(s.message.forward_origin||s.message.forward_from||s.message.forward_date)return;s.replyWithChatAction("typing").catch(()=>{});let m=await O({platform:"telegram",chatId:p,senderId:d,text:s.match?`update ${s.match}`.trim():"update",userName:s.from?.username||s.from?.first_name||"user"});if(m)return Fe(s,m)}),r.on("message:text",async s=>{let d=String(s.chat.id),p=String(s.from?.id||d),m=s.message.text;try{s.replyWithChatAction("typing").catch(()=>{});let h=pe(),g=vt(h,{chatId:d,text:m}),k=await O({platform:"telegram",chatId:d,senderId:p,text:g||m,userName:s.from?.username||s.from?.first_name||"user",extraOwners:a,bus:i,agentName:n,persona:o,backend:t.backend,profile:t.hermesProfile,meta:{forward_origin:s.message.forward_origin,forward_from:s.message.forward_from,forward_from_chat:s.message.forward_from_chat,forward_sender_name:s.message.forward_sender_name,forward_date:s.message.forward_date}});k&&await Fe(s,k)}catch(h){process.stderr.write(`telegram-gateway[${n}]: ${h.message}
31
+ `),await s.reply("Something went wrong. Try again.").catch(()=>{})}}),r.on("callback_query:data",async s=>{let d=String(s.from?.id||"");if(!z({platform:"telegram",senderId:d,extraOwners:a})){await s.answerCallbackQuery({text:V.slice(0,180),show_alert:!0}).catch(()=>{});return}let p=String(s.callbackQuery?.data||""),m=String(process.env.ORACLE_OWNER_TELEGRAM||"").split(",").map(v=>v.trim()).filter(Boolean),h=process.env.ORACLE_CONFIG_DIR||ar(fo(),".config","oracle"),g;try{g=nr({keyFile:ar(h,"signer","policy-integrity-key"),approvedTelegramOwners:m})}catch{}let k=await ot({platform:"telegram",data:p,senderId:d,chatId:String(s.chat?.id||""),ownerProofAuthority:g,grant:{local:!0}});if(!k){let v=pe(),x=Ct(v,{data:p,chatId:String(s.chat?.id||""),grant:{local:!0}});if(ir(),!x){await s.answerCallbackQuery().catch(()=>{});return}if(await s.answerCallbackQuery({text:"ok"}).catch(()=>{}),x.prompt){let C=await O({platform:"telegram",chatId:String(s.chat?.id||""),senderId:d,text:x.prompt,extraOwners:a,bus:i,agentName:n,persona:o,backend:t.backend,profile:t.hermesProfile});C&&await Fe(s,C);return}if(x.text){let C=x.buttons?.replyMarkup?{reply_markup:x.buttons.replyMarkup}:{};await s.reply(x.text,{parse_mode:"Markdown",...C}).catch(()=>{})}return}await s.answerCallbackQuery({text:"ok"}).catch(()=>{}),k.text&&await s.reply(k.text,{parse_mode:"Markdown"}).catch(()=>{})}),r.start();let l=sr({extraOwners:a}),c=null;return l.length>0&&t.pendingWatch!==!1&&(c=Jt({intervalMs:t.pendingWatchIntervalMs,onNew:async(s,{armed:d})=>{let p=Ce(s,{platform:"telegram",grant:{local:!0},armed:d}),m=p.buttons?.replyMarkup?{reply_markup:p.buttons.replyMarkup}:{};for(let h of l)await r.api.sendMessage(h,p.text,{parse_mode:"Markdown",...m}).catch(()=>{})}})),{platform:"telegram",name:n,bot:r,stopPendingWatch:()=>c?.stop()}}var lr=w(()=>{Y();_e();Xt();or();Me()});var ur={};j(ur,{discord:()=>go});async function go(t){let{Client:e,GatewayIntentBits:r}=await import("discord.js"),n=new e({intents:[r.Guilds,r.GuildMessages,r.MessageContent,r.DirectMessages]}),o=String(t.name||"oracle").toLowerCase(),a=K(t),i=Array.isArray(t.owners)?t.owners:void 0,l=t.bus;return l&&l.register(o,{role:t.role||"",chains:t.chains||[],handler:c=>oe({from:c.from,text:c.text,persona:a,backend:t.backend,profile:t.hermesProfile})}),n.on("messageCreate",async c=>{if(c.author.bot)return;let s=c.channel.id,d=c.author.id,p=c.content;try{let m=!c.guild,h=c.mentions.has(n.user.id);if(!m&&!h)return;c.channel.sendTyping().catch(()=>{});let g=await O({platform:"discord",chatId:s,senderId:d,text:p.replace(`<@${n.user.id}>`,"").trim(),userName:c.author.username,extraOwners:i,bus:l,agentName:o,persona:a,backend:t.backend,profile:t.hermesProfile,meta:{forwarded:c.reference?.type===1||Array.isArray(c.messageSnapshots)&&c.messageSnapshots.length>0}});g&&await c.reply(typeof g=="string"?g:g.text).catch(()=>{})}catch(m){process.stderr.write(`discord-gateway[${o}]: ${m.message}
32
+ `)}}),await n.login(t.token),{platform:"discord",name:o,client:n}}var dr=w(()=>{Y()});var mr={};j(mr,{whatsapp:()=>ko});import{join as pr}from"node:path";import{homedir as yo}from"node:os";async function ko(t){let[{Client:e,LocalAuth:r},{generate:n}]=await Promise.all([import("whatsapp-web.js"),import("qrcode-terminal")]),o=new e({authStrategy:new r({dataPath:pr(wo,".wwebjs_auth")}),puppeteer:{headless:!0,args:["--no-sandbox"]}});return o.on("qr",a=>{process.stderr.write(`
33
33
  WhatsApp: scan this QR code in WhatsApp \u2192 Linked Devices:
34
34
 
35
35
  `),n(a,{small:!0}),process.stderr.write(`
36
36
  `)}),o.on("ready",()=>{process.stderr.write(`whatsapp-gateway: connected
37
- `)}),o.on("message",async a=>{if(a.fromMe)return;let i=a.from,c=a.author||a.from,l=a.body;try{let s=await O({platform:"whatsapp",chatId:i,senderId:c,text:l,userName:a._data?.notifyName||"user",meta:{forwarded:a.isForwarded||a._data?.isForwarded,forward_date:a._data?.forwardingScore?!0:void 0}});if(s){let p=(typeof s=="string"?s:s.text).replace(/\*\*/g,"*").replace(/```[\s\S]*?```/g,"[code]").replace(/`/g,"");await a.reply(p)}}catch(s){process.stderr.write(`whatsapp-gateway: ${s.message}
38
- `)}}),await o.initialize(),{platform:"whatsapp",client:o}}var go,mr=w(()=>{Y();go=process.env.ORACLE_CONFIG_DIR||dr(ho(),".config","oracle")});var fr={};j(fr,{signal_:()=>wo});async function wo(t){return process.stderr.write(`signal-gateway: requires signal-cli binary
37
+ `)}),o.on("message",async a=>{if(a.fromMe)return;let i=a.from,l=a.author||a.from,c=a.body;try{let s=await O({platform:"whatsapp",chatId:i,senderId:l,text:c,userName:a._data?.notifyName||"user",meta:{forwarded:a.isForwarded||a._data?.isForwarded,forward_date:a._data?.forwardingScore?!0:void 0}});if(s){let p=(typeof s=="string"?s:s.text).replace(/\*\*/g,"*").replace(/```[\s\S]*?```/g,"[code]").replace(/`/g,"");await a.reply(p)}}catch(s){process.stderr.write(`whatsapp-gateway: ${s.message}
38
+ `)}}),await o.initialize(),{platform:"whatsapp",client:o}}var wo,fr=w(()=>{Y();wo=process.env.ORACLE_CONFIG_DIR||pr(yo(),".config","oracle")});var hr={};j(hr,{signal_:()=>So});async function So(t){return process.stderr.write(`signal-gateway: requires signal-cli binary
39
39
  `),process.stderr.write(`signal-gateway: not built yet \u2014 use Telegram or Discord for now
40
- `),{platform:"signal",status:"stub"}}var hr=w(()=>{Y()});import{createServer as ko}from"node:http";import{env as wr}from"node:process";import{join as Ge}from"node:path";import{homedir as So}from"node:os";import{readFileSync as kr,existsSync as bo,mkdirSync as xo,writeFileSync as vo}from"node:fs";import{randomBytes as Ao}from"node:crypto";var Sr=wr.ORACLE_CONFIG_DIR||Ge(So(),".config","oracle"),gr=Ge(Sr,"gateway.json");function Co(){return bo(gr)?JSON.parse(kr(gr,"utf8")):{platforms:{}}}function Fe(t){return t?Array.isArray(t)?t.filter(Boolean):[t]:[]}var $o=Object.freeze({telegram:"grammy",discord:"discord.js",whatsapp:"whatsapp-web.js"});async function me(t,e,r,n){try{n.push(await e(r))}catch(o){let a=$o[t];if(a&&/Cannot find (module|package)|ERR_MODULE_NOT_FOUND/.test(String(o.message))){process.stderr.write(`oracle-gateway: ${t} needs an optional dependency. Install it first:
40
+ `),{platform:"signal",status:"stub"}}var gr=w(()=>{Y()});import{createServer as bo}from"node:http";import{env as kr}from"node:process";import{join as qe}from"node:path";import{homedir as xo}from"node:os";import{readFileSync as Sr,existsSync as vo,mkdirSync as Ao,writeFileSync as Co}from"node:fs";import{randomBytes as $o}from"node:crypto";var br=kr.ORACLE_CONFIG_DIR||qe(xo(),".config","oracle"),yr=qe(br,"gateway.json");function _o(){return vo(yr)?JSON.parse(Sr(yr,"utf8")):{platforms:{}}}function He(t){return t?Array.isArray(t)?t.filter(Boolean):[t]:[]}var Eo=Object.freeze({telegram:"grammy",discord:"discord.js",whatsapp:"whatsapp-web.js"});async function me(t,e,r,n){try{n.push(await e(r))}catch(o){let a=Eo[t];if(a&&/Cannot find (module|package)|ERR_MODULE_NOT_FOUND/.test(String(o.message))){process.stderr.write(`oracle-gateway: ${t} needs an optional dependency. Install it first:
41
41
  npm install -g ${a}
42
42
  `);return}process.stderr.write(`oracle-gateway: ${t} failed to start: ${o.message}
43
- `)}}async function _o(){let t=Co(),e=[],r=Fe(t.platforms?.telegram),n=Fe(t.platforms?.discord),o=Fe(t.agents),i=r.length+n.length+o.length>1?new(await Promise.resolve().then(()=>(We(),qe))).A2ABus:null;if(i&&o.length){let{routePeerConsult:l,buildPersona:s}=await Promise.resolve().then(()=>(Y(),Kt));for(let d of o)try{let p=s(d);i.register(d.name,{role:d.role||"",chains:d.chains||[],handler:m=>l({from:m.from,text:m.text,persona:p,backend:d.backend,profile:d.hermesProfile})}),process.stderr.write(`oracle-gateway: headless agent '${d.name}' on bus (backend: ${d.backend||"oracle"})
43
+ `)}}async function Oo(){let t=_o(),e=[],r=He(t.platforms?.telegram),n=He(t.platforms?.discord),o=He(t.agents),i=r.length+n.length+o.length>1?new(await Promise.resolve().then(()=>(ze(),We))).A2ABus:null;if(i&&o.length){let{routePeerConsult:c,buildPersona:s}=await Promise.resolve().then(()=>(Y(),Yt));for(let d of o)try{let p=s(d);i.register(d.name,{role:d.role||"",chains:d.chains||[],handler:m=>c({from:m.from,text:m.text,persona:p,backend:d.backend,profile:d.hermesProfile})}),process.stderr.write(`oracle-gateway: headless agent '${d.name}' on bus (backend: ${d.backend||"oracle"})
44
44
  `)}catch(p){process.stderr.write(`oracle-gateway: headless agent '${d.name||"?"}' skipped: ${p.message}
45
- `)}}for(let l of r)await me("telegram",async()=>(await Promise.resolve().then(()=>(cr(),sr))).telegram({...l,bus:i}),t,e);for(let l of n)await me("discord",async()=>(await Promise.resolve().then(()=>(ur(),lr))).discord({...l,bus:i}),t,e);t.platforms?.whatsapp&&await me("whatsapp",async l=>(await Promise.resolve().then(()=>(mr(),pr))).whatsapp(l.platforms.whatsapp),t,e),t.platforms?.signal&&await me("signal",async l=>(await Promise.resolve().then(()=>(hr(),fr))).signal_(l.platforms.signal),t,e),e.length===0&&process.stderr.write(`oracle-gateway: no platforms configured. Run 'oracle setup telegram' first.
45
+ `)}}for(let c of r)await me("telegram",async()=>(await Promise.resolve().then(()=>(lr(),cr))).telegram({...c,bus:i}),t,e);for(let c of n)await me("discord",async()=>(await Promise.resolve().then(()=>(dr(),ur))).discord({...c,bus:i}),t,e);t.platforms?.whatsapp&&await me("whatsapp",async c=>(await Promise.resolve().then(()=>(fr(),mr))).whatsapp(c.platforms.whatsapp),t,e),t.platforms?.signal&&await me("signal",async c=>(await Promise.resolve().then(()=>(gr(),hr))).signal_(c.platforms.signal),t,e),e.length===0&&process.stderr.write(`oracle-gateway: no platforms configured. Run 'oracle setup telegram' first.
46
46
  `),process.stderr.write(`oracle-gateway: ${e.length} platform(s) connected
47
- `);let c=i?Lo():null;ko((l,s)=>Oo(l,s,{config:t,bus:i,a2aToken:c})).listen(wr.ORACLE_GATEWAY_PORT||9270,"127.0.0.1"),i&&process.stderr.write(`oracle-gateway: a2a loopback contract at GET /a2a (token: a2a-token in config dir)
48
- `)}var Eo=16384;async function Oo(t,e,{config:r,bus:n,a2aToken:o}){let a=new URL(t.url||"/","http://127.0.0.1"),i=(l,s)=>{e.writeHead(l,{"Content-Type":"application/json"}),e.end(JSON.stringify(s))};if(t.method==="GET"&&(a.pathname==="/"||a.pathname==="/health"))return i(200,{status:"ok",platforms:Object.keys(r.platforms||{}),a2a:!!n});if(!a.pathname.startsWith("/a2a"))return i(404,{error:"not found"});if(!n)return i(404,{error:"a2a bus not running (fewer than 2 agents configured)"});if(t.method==="GET"&&a.pathname==="/a2a")return i(200,{contract:"oracle-a2a/1",auth:"Authorization: Bearer <contents of a2a-token in the oracle config dir>",endpoints:["GET /a2a","GET /a2a/agents","POST /a2a/ask {to,text,from?}"],note:"consult-only; loopback-only; peers answer with information, never actions"});let c=String(t.headers.authorization||"");if(!o||c!==`Bearer ${o}`)return i(401,{error:"bad or missing bearer token (read a2a-token in the oracle config dir)"});if(t.method==="GET"&&a.pathname==="/a2a/agents")return i(200,{agents:n.roster()});if(t.method==="POST"&&a.pathname==="/a2a/ask"){let l="";t.on("data",s=>{l+=s,l.length>Eo&&t.destroy()}),t.on("end",async()=>{try{let s=JSON.parse(l||"{}"),d=Ro(s.from);n.agents.has(d)||n.register(d,{role:"loopback client",handler:async()=>null});let p=await n.send({from:d,to:s.to,text:s.text,kind:"consult"});return i(p.ok?200:400,p)}catch(s){return i(400,{ok:!1,error:`bad request: ${s.message}`})}});return}return i(404,{error:"not found"})}function Ro(t){return String(t||"local").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"").slice(0,32)||"local"}function Lo(t=Sr){let e=Ge(t,"a2a-token");try{let n=kr(e,"utf8").trim();if(n)return n}catch{}let r=Ao(24).toString("hex");return xo(t,{recursive:!0}),vo(e,`${r}
49
- `,{mode:384}),r}var{pathToFileURL:No}=await import("node:url"),{realpathSync:Io}=await import("node:fs"),yr=process.argv[1],He=!1;if(yr)try{He=import.meta.url===No(Io(yr)).href}catch{He=!1}He&&_o().catch(t=>{process.stderr.write(`oracle-gateway: ${t.message}
50
- `),process.exit(1)});export{Lo as ensureA2AToken,Oo as serveHttp,Fe as toEntries};
47
+ `);let l=i?Io():null;bo((c,s)=>No(c,s,{config:t,bus:i,a2aToken:l})).listen(kr.ORACLE_GATEWAY_PORT||9270,"127.0.0.1"),i&&process.stderr.write(`oracle-gateway: a2a loopback contract at GET /a2a (token: a2a-token in config dir)
48
+ `)}var Ro=16384;async function No(t,e,{config:r,bus:n,a2aToken:o}){let a=new URL(t.url||"/","http://127.0.0.1"),i=(c,s)=>{e.writeHead(c,{"Content-Type":"application/json"}),e.end(JSON.stringify(s))};if(t.method==="GET"&&(a.pathname==="/"||a.pathname==="/health"))return i(200,{status:"ok",platforms:Object.keys(r.platforms||{}),a2a:!!n});if(!a.pathname.startsWith("/a2a"))return i(404,{error:"not found"});if(!n)return i(404,{error:"a2a bus not running (fewer than 2 agents configured)"});if(t.method==="GET"&&a.pathname==="/a2a")return i(200,{contract:"oracle-a2a/1",auth:"Authorization: Bearer <contents of a2a-token in the oracle config dir>",endpoints:["GET /a2a","GET /a2a/agents","POST /a2a/ask {to,text,from?}"],note:"consult-only; loopback-only; peers answer with information, never actions"});let l=String(t.headers.authorization||"");if(!o||l!==`Bearer ${o}`)return i(401,{error:"bad or missing bearer token (read a2a-token in the oracle config dir)"});if(t.method==="GET"&&a.pathname==="/a2a/agents")return i(200,{agents:n.roster()});if(t.method==="POST"&&a.pathname==="/a2a/ask"){let c="";t.on("data",s=>{c+=s,c.length>Ro&&t.destroy()}),t.on("end",async()=>{try{let s=JSON.parse(c||"{}"),d=Lo(s.from);n.agents.has(d)||n.register(d,{role:"loopback client",handler:async()=>null});let p=await n.send({from:d,to:s.to,text:s.text,kind:"consult"});return i(p.ok?200:400,p)}catch(s){return i(400,{ok:!1,error:`bad request: ${s.message}`})}});return}return i(404,{error:"not found"})}function Lo(t){return String(t||"local").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"").slice(0,32)||"local"}function Io(t=br){let e=qe(t,"a2a-token");try{let n=Sr(e,"utf8").trim();if(n)return n}catch{}let r=$o(24).toString("hex");return Ao(t,{recursive:!0}),Co(e,`${r}
49
+ `,{mode:384}),r}var{pathToFileURL:To}=await import("node:url"),{realpathSync:Po}=await import("node:fs"),wr=process.argv[1],Ge=!1;if(wr)try{Ge=import.meta.url===To(Po(wr)).href}catch{Ge=!1}Ge&&Oo().catch(t=>{process.stderr.write(`oracle-gateway: ${t.message}
50
+ `),process.exit(1)});export{Io as ensureA2AToken,No as serveHttp,He as toEntries};