@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.
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import{createInterface as Ae}from"node:readline";var S=Object.freeze({maxRequestBytes:256*1024,maxResponseBytes:2*1024*1024,maxTools:256,maxToolNameLength:64,maxArgumentBytes:128*1024,defaultCallTimeoutMs:3e4,maxCallTimeoutMs:6e4,maxConcurrentCalls:32}),Ce=/^[A-Za-z0-9_-]{1,64}$/;function q(t,e){return{jsonrpc:"2.0",id:t??null,result:e}}function g(t,e,r){return{jsonrpc:"2.0",id:t??null,error:{code:e,message:r}}}function Re(t){return!!(t&&typeof t=="object"&&!Array.isArray(t)&&t.jsonrpc==="2.0"&&typeof t.method=="string"&&t.method.length>0)}function _e(t){if(!Array.isArray(t))return[];let e=[],r=new Set;for(let n of t){if(e.length>=S.maxTools)break;if(!n||typeof n!="object"||Array.isArray(n))continue;let o=typeof n.name=="string"?n.name.trim():"";if(!Ce.test(o)||r.has(o))continue;r.add(o);let a=n.inputSchema&&typeof n.inputSchema=="object"&&!Array.isArray(n.inputSchema)?{...n.inputSchema}:{type:"object",properties:{},additionalProperties:!1};a.type==="object"&&a.additionalProperties===void 0&&(a.additionalProperties=!1),e.push({...n,name:o,inputSchema:a})}return e}function Oe(t){let e=Number(t)||S.defaultCallTimeoutMs;return Math.min(Math.max(e,1),S.maxCallTimeoutMs)}async function Ne(t,e,r){let n;try{return await Promise.race([t,new Promise((o,a)=>{n=setTimeout(()=>{let i=new Error("tool call timed out");i.code="ORACLE_MCP_TIMEOUT",a(i);try{r?.()}catch{}},e)})])}finally{clearTimeout(n)}}function Ee(t){return t===null?"null":Array.isArray(t)?"array":Number.isInteger(t)?"integer":typeof t}function j(t,e,r="arguments",n=0){if(!e||typeof e!="object"||Array.isArray(e))return null;if(n>12)return`${r} exceeded the nesting limit`;if(Array.isArray(e.oneOf)&&e.oneOf.length&&!e.oneOf.some(a=>j(t,a,r,n+1)===null))return`${r} did not match an allowed shape`;if(Array.isArray(e.anyOf)&&e.anyOf.length&&!e.anyOf.some(a=>j(t,a,r,n+1)===null))return`${r} did not match a required alternative`;if(Array.isArray(e.enum)&&!e.enum.some(o=>Object.is(o,t)))return`${r} must be one of the allowed values`;if(Object.hasOwn(e,"const")&&!Object.is(e.const,t))return`${r} must equal the required constant`;if(e.type){let o=Ee(t);if(!(e.type==="number"?typeof t=="number"&&Number.isFinite(t):e.type==="integer"?Number.isSafeInteger(t):o===e.type))return`${r} must be ${e.type}`}if(typeof t=="string"){let o=Math.min(Number.isSafeInteger(e.maxLength)?e.maxLength:16384,16384);if(t.length>o)return`${r} exceeded the string limit`;if(Number.isSafeInteger(e.minLength)&&t.length<e.minLength)return`${r} is too short`}if(Array.isArray(t)){let o=Math.min(Number.isSafeInteger(e.maxItems)?e.maxItems:1e3,1e3);if(t.length>o)return`${r} exceeded the array limit`;if(Number.isSafeInteger(e.minItems)&&t.length<e.minItems)return`${r} has too few items`;if(e.items)for(let a=0;a<t.length;a+=1){let i=j(t[a],e.items,`${r}[${a}]`,n+1);if(i)return i}}if(t&&typeof t=="object"&&!Array.isArray(t)){let o=Object.keys(t);if(o.length>256)return`${r} exceeded the property limit`;let a=e.properties&&typeof e.properties=="object"?e.properties:{};for(let i of Array.isArray(e.required)?e.required:[])if(!Object.hasOwn(t,i))return`${r}.${i} is required`;if(e.additionalProperties===!1){let i=o.find(l=>!Object.hasOwn(a,l));if(i)return`${r}.${i} is not allowed`}for(let i of o){if(!Object.hasOwn(a,i))continue;let l=j(t[i],a[i],`${r}.${i}`,n+1);if(l)return l}}return null}function Ie(t,e={}){let r=_e(t?.tools),n=new Set(r.map(c=>c.name)),o=new Map(r.map(c=>[c.name,c])),a=typeof t?.name=="string"&&t.name?t.name.slice(0,80):"oracle-mcp",i=typeof t?.version=="string"&&t.version?t.version.slice(0,40):"1",l=Oe(e.callTimeoutMs),d=!1;return async function(f){let p=f?.id??null;if(!Re(f))return g(p,-32600,"invalid request");if(f.method==="initialize")return d=!0,q(p,{protocolVersion:f.params?.protocolVersion??"2025-03-26",capabilities:{tools:{}},serverInfo:{name:a,version:i}});if(f.method==="notifications/initialized")return null;if(f.method==="ping")return q(p,{});if(!d)return g(p,-32002,"server not initialized");if(f.method==="tools/list")return q(p,{tools:r});if(f.method==="tools/call"){let $=f.params?.name,w=f.params?.arguments??{};if(typeof $!="string"||!n.has($))return g(p,-32602,"unknown tool");if(!w||typeof w!="object"||Array.isArray(w))return g(p,-32602,"tool arguments must be an object");let O;try{O=JSON.stringify(w)}catch{return g(p,-32602,"tool arguments are not serializable")}if(Buffer.byteLength(O)>S.maxArgumentBytes)return g(p,-32602,"tool arguments exceeded the size limit");let v=j(w,o.get($)?.inputSchema);if(v)return g(p,-32602,v);try{let x=new AbortController,N=await Ne(Promise.resolve(t.call($,w,{signal:x.signal})),l,()=>x.abort(new Error("tool call timed out")));return q(p,N)}catch(x){if(x?.code==="ORACLE_MCP_TIMEOUT")return g(p,-32001,"tool call timed out");let N=typeof x?.message=="string"?x.message.replace(/\s+/g," ").trim():"",B=/\b(requires?|must be|missing|unknown|invalid|expected|unsupported|out of range|too (?:large|small|long|many)|not a|cannot convert)\b/i.test(N),F=/https?:\/\/|[/~][\w.-]+\/|0x[0-9a-fA-F]{8,}|[A-Za-z0-9+/_-]{24,}={0,2}|\b(?:secret|apikey|api[-_ ]key|private[-_ ]?key|token|password|credential|seed|mnemonic)s?\b/i.test(N.replace(/\btoken(?:In|Out|s\b)/g,"asset"));return B&&!F&&N.length<=200?g(p,-32e3,`tool call failed: ${N}`):g(p,-32e3,"tool call failed")}}return g(p,-32601,"method not found")}}function te(t,e={}){let r=e.input||process.stdin,n=e.output||process.stdout,o=Math.min(Math.max(Number(e.maxRequestBytes)||S.maxRequestBytes,64),S.maxRequestBytes),a=Math.min(Math.max(Number(e.maxResponseBytes)||S.maxResponseBytes,256),S.maxResponseBytes),i=Math.min(Math.max(Number(e.maxConcurrentCalls)||S.maxConcurrentCalls,1),S.maxConcurrentCalls),l=i*8,d=Ie(t,e),c={closed:!1,inflight:0},f=Ae({input:r,terminal:!1,crlfDelay:1/0}),p=0,$=[],w=!1,O=!1;function v(){if(c.closed||c.readerClosed)return;let y=c.inflight>=i||$.length>0||O;y&&!w?(w=!0,f.pause(),typeof r.pause=="function"&&r.pause()):!y&&w&&(w=!1,typeof r.resume=="function"&&r.resume(),f.resume())}function x(y){if(!y||c.closed)return;let k=JSON.stringify(y);Buffer.byteLength(k)>a&&(k=JSON.stringify(g(y.id,-32003,"response exceeded the size limit"))),n.write(`${k}
3
- `)===!1&&!O&&(O=!0,v(),n.once("drain",()=>{O=!1,B()}))}function N(y){c.inflight+=1,v(),Promise.resolve(d(y)).then(x).catch(()=>x(g(y?.id,-32603,"internal error"))).finally(()=>{c.inflight-=1,B()})}function B(){for(;!c.closed&&!O&&c.inflight<i&&$.length>0;)N($.shift());v()}function F(){c.closed||(x(g(null,-32700,"request exceeded the size limit")),c.closed=!0,f.close(),typeof r.destroy=="function"&&r.destroy())}return r.on("data",y=>{if(c.closed)return;let k=String(y).split(`
4
- `);for(let U=0;U<k.length;U+=1){if(p+=Buffer.byteLength(k[U]),p>o){F();return}U<k.length-1&&(p=0)}}),f.on("line",y=>{if(c.closed)return;if(Buffer.byteLength(y)>o){F();return}let k;try{k=JSON.parse(y)}catch{x(g(null,-32700,"parse error"));return}if($.length>=l){x(g(k?.id,-32e3,"server busy"));return}$.push(k),B()}),f.on("close",()=>{c.readerClosed=!0,e.exitOnClose!==!1&&(process.exitCode=0)}),c}import{createHash as Ye,randomBytes as Xe}from"node:crypto";import{mkdirSync as Ze,readFileSync as Qe,writeFileSync as et}from"node:fs";import{homedir as tt}from"node:os";import{dirname as rt,join as ae}from"node:path";var Le=/^[A-Z0-9][A-Z0-9._-]{0,11}$/;function re(t,{coin:e,side:r,sizeUsd:n,leverage:o,venue:a,confirm:i,user:l}={}){let d=String(t||"").trim();if(!d||d.includes("ts.net")||!/^https:\/\//i.test(d))return null;let c=new URL(d);if(e&&Le.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 f=String(a).toLowerCase()==="hl"?"hyperliquid":String(a).toLowerCase();c.searchParams.set("venue",f)}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 Te={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}},ve=new Map(Object.values(Te).map(t=>[t.chainId,t]));function ne(t){return ve.get(Number(t))||null}var u="UNKNOWN",St=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),Pe=/[_*[\]`]/g;function s(t){return m(t)?String(t).replace(Pe,e=>`\\${e}`):u}function m(t){return t==null?!1:typeof t=="number"?Number.isFinite(t):typeof t=="string"?t.trim()!=="":!0}function A(t){if(!m(t))return u;let e=String(t).replace(/`/g,"");return e===""?u:`\`${e}\``}function L(t,{decimals:e=2}={}){if(!m(t))return u;let r=Number(t);return Number.isFinite(r)?r.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:e}):u}function h(t,{decimals:e=2}={}){let r=L(t,{decimals:e});return r===u?u:`${r} USD`}function W(t,{decimals:e=2}={}){let r=L(t,{decimals:e});return r===u?u:`${r}%`}function z(t){let e=L(t,{decimals:0});return e===u?u:`${e} bps`}function T(t,e){if(!m(t))return u;let r=Number(e);if(!Number.isInteger(r)||r<0||r>77)return u;let n;try{n=BigInt(typeof t=="string"?t.trim():t)}catch{return u}let o=n<0n,a=o?-n:n,i=10n**BigInt(r),l=(a/i).toString(),d=(a%i).toString().padStart(r,"0").replace(/0+$/,"");return`${o?"-":""}${l}${d?`.${d}`:""}`}function K(t){if(typeof t=="number"&&Number.isFinite(t))return t<0||t>1?u: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 u}function E(t={}){let e=t.chainId;if(!m(e)||!Number.isFinite(Number(e)))return m(t.chain)?s(t.chain):u;let n=ne(e)?.name||(m(t.chain)?String(t.chain):u);return`${s(n)} (chainId ${Number(e)})`}function ie(t={}){return s(t.venue??t.dex??t.pool?.venue)}function Me(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${m(t.error)?` \u2014 ${s(t.error)}`:""} (text card stands)`:m(t.url)?A(t.url):"NONE (text card only)"}function D(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(m(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 Be(t){let e=D(t);return e.allowed?`${e.actions.map(r=>s(r)).join(" / ")} (${s(e.reason)})`:`prepare-only \u2014 ${s(e.reason)}`}function C(t,e,r={}){let n=[`*${t}*`];for(let[o,a]of e)n.push(`${o}: ${a==null||a===""?u:a}`);return n.push(`Chart: ${Me(r.chart)}`),n.push(`Actions: ${Be(r)}`),Array.isArray(r.warnings)&&r.warnings.length&&n.push(`Warnings: ${r.warnings.map(o=>s(o)).join("; ")}`),(m(r.source)||m(r.fetchedAt))&&n.push(`Source: ${s(r.source)} at ${s(r.fetchedAt)}`),n.join(`
5
- `)}function R(t){return["Confidence",K(t.confidence)]}function Ue(t){let e=t.quote;if(!e||typeof e!="object")return[];let r=m(e.decimals)?T(e.amountOutRaw??e.out??e.raw,e.decimals):u;return[["Quote out (raw)",A(e.amountOutRaw??e.out??e.raw)],["Quote out",r===u?u:`${s(r)} ${s(e.symbol??"")}`.trim()]]}function oe(t){let e=t.autoSlippage;if(!e||typeof e!="object")return["Auto-slippage",u];let r=z(e.selectedBps),n=z(e.capBps);return["Auto-slippage",r===u&&n===u?u:`${r} selected, cap ${n}`]}function je(t={}){let e=t||{};return C(`ORACLE TOKEN \u2014 ${s(e.symbol??e.token??e.name)}`,[["Chain",E(e)],["Venue",ie(e)],["Name",s(e.name)],["Address",A(e.address??e.mint??e.contract)],["Price",h(e.priceUsd,{decimals:8})],["Market cap",h(e.marketCapUsd)],["Liquidity",h(e.liquidityUsd)],["Volume 24h",h(e.volume24hUsd)],["Change 24h",W(e.priceChange24h)],["Fee tier",m(e.feeTier)?`${z(Number(e.feeTier)/100)} (${L(e.feeTier,{decimals:0})})`:u],["Age",s(e.age)],...Ue(e),oe(e),R(e)],e)}function De(t={}){let e=t||{};return C(`ORACLE LAUNCH \u2014 ${s(e.symbol??e.token??e.name)}`,[["Chain",E(e)],["Venue",ie(e)],["Address",A(e.address??e.mint??e.contract)],["Pool",A(e.pool?.address??e.poolAddress??e.pool)],["Liquidity",h(e.liquidityUsd)],["Route ready",s(e.routeReady)],["Sellable",s(e.sellable)],["Sell sim",s(e.sellSimulation??e.sellSim)],["Smart wallets",s(e.smartWalletOverlap)],["Risk",s(e.risk??e.riskStatus)],["Prepared ticket",s(e.preparedTicket??e.ticketStatus)],oe(e),R(e)],e)}function He(t={}){let e=t||{};return C(`ORACLE HIP-3 \u2014 ${s(e.market??e.coin??e.name)}`,[["Venue",`Hyperliquid builder-dex ${s(e.dex)}`],["Market",s(e.market??e.coin)],["Mark",h(e.markPx,{decimals:6})],["Oracle",h(e.oraclePx,{decimals:6})],["Funding",W(e.funding,{decimals:6})],["Open interest",h(e.openInterestUsd)],["Depth",s(e.depth)],["Liquidation notes",s(e.liquidationNotes??e.riskNotes)],["Account context",s(e.accountContext)],R(e)],e)}function Fe(t={}){let e=t||{};return C(`ORACLE HIP-4 \u2014 ${s(e.event??e.market??e.name)}`,[["Venue",`Hyperliquid HIP-4 ${s(e.dex??"outcome")}`],["Event",s(e.event)],["Outcome",s(e.outcome)],["Market id",A(e.marketId??e.market)],["Bid",h(e.bid,{decimals:6})],["Ask",h(e.ask,{decimals:6})],["Depth",s(e.depth)],["Edge",W(e.edge)],["Position",s(e.position)],R(e)],e)}function qe(t={}){let e=t||{};return C(`ORACLE POLYMARKET \u2014 ${s(e.event??e.market??e.name)}`,[["Venue","Polymarket CLOB"],["Event",s(e.event)],["Market",s(e.market)],["Market id",A(e.marketId??e.conditionId??e.tokenId)],["Yes",h(e.yesPrice,{decimals:4})],["No",h(e.noPrice,{decimals:4})],["Best bid / ask",`${h(e.bestBid,{decimals:4})} / ${h(e.bestAsk,{decimals:4})}`],["Volume",h(e.volumeUsd)],["Resolution risk",s(e.resolutionRisk)],["Order intent",s(e.orderIntent)],R(e)],e)}function ze(t={}){let e=t||{},r=m(e.completedSplits)&&m(e.totalSplits)?`${L(e.completedSplits,{decimals:0})} / ${L(e.totalSplits,{decimals:0})}`:u;return C(`ORACLE TWAP \u2014 ${s(e.pair??e.symbol??e.name)}`,[["Chain",E(e)],["Side",s(e.side??e.direction)],["Amount",`${s(T(e.amountTotal??e.amount,e.decimals??18))} ${s(e.symbol??"")}`.trim()],["Splits",`${L(e.totalSplits,{decimals:0})} over ${s(e.window)}`],["Progress",r],["Avg price",h(e.averagePrice,{decimals:6})],["Next split",s(e.nextSplitAt)],["Slippage cap",z(e.slippageBps)],["Status",s(e.status)],R(e)],e)}function Ve(t={}){let e=t||{},r=e.approval??e.revokeCheck??{},n=r.needsRevoke&&r.spender?`revoke.cash \u2014 ${s(r.spender)}`:r.needsRevoke===!1?"revoke.cash \u2014 clean":"revoke.cash \u2014 unchecked";return C(`ORACLE BRIDGE \u2014 ${s(e.pair??e.fromSymbol)} \u2192 ${s(e.toSymbol??"")}`.replace(/→ $/,""),[["Bridging","deBridge \xB7 LI.FI \u2014 best route wins"],["From chain",E({chainId:e.fromChainId,chain:e.fromChain})],["To chain",E({chainId:e.toChainId,chain:e.toChain})],["Amount",`${s(T(e.amount,e.fromDecimals??18))} ${s(e.fromSymbol??"")}`.trim()],["Best route",s(e.bestRoute??e.winner)],["Est. received",`${s(T(e.amountOut,e.toDecimals??18))} ${s(e.toSymbol??"")}`.trim()],["Fee",h(e.feeUsd)],["Est. time",s(e.estimatedTime)],["Revoke check",n],["All providers",s(e.providers?.join(", "))],["Preparable",s(e.preparable)],R(e)],e)}function We(t){let r=(Array.isArray(t)?t:[]).slice(1,4).map(n=>{let o=s(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("; "):u}function Ke(t){let e=t.rankedOn??t.swap?.rankedOn??t.best?.rankedOn;return m(e)?s(e):u}function Je(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=`${s(e.tokenInSymbol??e.fromSymbol??"IN")} \u2192 ${s(e.tokenOutSymbol??e.toSymbol??"OUT")}`,i=[["Intent",s(e.intent??"swap")],["Chain",E({chainId:e.chainId??r.chainId,chain:e.chain??r.chain})],["Pair",a],["Amount in",`${s(T(e.amountIn??r.amountIn,e.decimalsIn??18))} ${s(e.tokenInSymbol??"")}`.trim()],["Best swap",s(o.source??o.venue??r.bestRoute??e.bestRoute)],["Net out",`${s(T(o.netOut??o.amountOut??r.amountOut,e.decimalsOut??18))} ${s(e.tokenOutSymbol??"")}`.trim()],["Ranked on",Ke(r)],["Gas accounted",s(o.costAccounted===!0?"yes":o.costAccounted===!1?"no \u2014 gross ranking may flatter this route":null)],["Spread vs next",m(r.improvementBps)?`${s(r.improvementBps)} bps`:u],["Runners-up",We(r.routes??e.routes)]];if(n){let l=n.best??n.winner??{};i.push(["Best bridge",s(l.source??n.bestRoute??e.bestBridge)],["Bridge out",`${s(T(l.netOut??l.amountOut??n.amountOut,e.bridgeDecimalsOut??e.decimalsOut??18))} ${s(e.bridgeOutSymbol??e.tokenOutSymbol??"")}`.trim()],["Bridge to",E({chainId:n.toChainId??e.toChainId,chain:n.toChain??e.toChain})],["Est. time",s(n.estimatedTime??l.meta?.durationSeconds)])}else i.push(["Best bridge","same-chain \u2014 use Best swap"]);return i.push(["Preparable",s(e.preparable??o.executionReady)],R(e)),C(`ORACLE SWAP \u2014 ${a}`,i,e)}function Ge(t={}){let e=t||{};return C("ORACLE APPROVE \u2014 local signer",[["Pending id",A(e.id??(typeof e.digest=="string"?e.digest.slice(0,8):null))],["Surface",s(e.surface)],["Action",s(e.action)],["Chain",E({chainId:e.chain??e.chainId,chain:e.chainName})],["To",A(e.to??e.destination)],["Value",m(e.value)?s(e.value):u],["Signer",s(e.armed===!0?"running + armed":e.armed===!1?"running, disarmed":"not running")],R({confidence:e.confidence??(e.armed===!0?"high":"low")})],e)}var At=Object.freeze({token:je,launch:De,hip3:He,hip4:Fe,polymarket:qe,twap:ze,bridge:Ve,swap:Je,approve:Ge});var nt=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),it=new Set(nt),G=/^[a-z0-9-]{4,40}$/i,se=/^[0-9a-f]{32}$/,ce=/^\d+$/;function Y(t=process.env){return ae(t.ORACLE_CONFIG_DIR||ae(tt(),".config","oracle"),"telegram-cards.json")}function P(){return{links:{},artifacts:{},threads:{}}}var H=P();function X(){return H}function le(t,{readFile:e=Qe}={}){try{let r=JSON.parse(String(e(t)));H={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{H=P()}return H}function ue(t,e=H,{writeFile:r=et,mkdir:n=Ze}={}){n(rt(t),{recursive:!0,mode:448}),r(t,JSON.stringify(e),{mode:384})}function I(t){return t==null?!1:typeof t=="string"?t.trim()!=="":!0}function de(t){return Ye("sha256").update(String(t)).digest("hex")}function J(t){if(Array.isArray(t))return t.map(J);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]=J(n));return e}function ot(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 fe({platform:t="telegram",artifactId:e,openUrl:r,hasGrant:n=!1}={}){let o=String(e||"").trim().toLowerCase();if(!G.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=>re(r,{side:p}),d=l("long"),c=l("short"),f=d&&c?[{text:"LONG",url:d},{text:"SHORT",url:c}]:[{text:"LONG",callback_data:`oracle:card:long:${o}`},{text:"SHORT",callback_data:`oracle:card:short:${o}`}];return I(r)?(a.push([{text:"Open",url:String(r)},i[0]]),a.push(f),a.push(n?[i[1],{text:"Prep",callback_data:`oracle:card:prepare:${o}`}]:[i[1]])):(a.push(i),a.push(f),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 pe(t={}){let r=[`*${I(t.title)?s(t.title):"Oracle artifact"}*`,`Kind: ${I(t.kind)?s(t.kind):u}`,`Id: ${I(t.id)?`\`${String(t.id).replace(/`/g,"")}\``:u}`,`Summary: ${I(t.summary)?s(t.summary):u}`,`Confidence: ${K(t.confidence)}`];(I(t.source)||I(t.fetchedAt))&&r.push(`Source: ${s(t.source)} at ${s(t.fetchedAt)}`),Array.isArray(t.warnings)&&t.warnings.length&&r.push(`Warnings: ${t.warnings.map(o=>s(o)).join("; ")}`);let n=D(t);return r.push(n.allowed?"Actions: TA / FA / LONG / SHORT open the graph. Execute on CONFIRM there.":`Actions: TA / FA / LONG / SHORT \u2014 ${s(n.reason)}`),r.join(`
6
- `)}function at(t,e={},{now:r=Date.now()}={}){let n=t||P(),o=String(e.id||"").trim().toLowerCase();if(!G.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:I(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:J(e.payload||{}),createdAt:new Date(r).toISOString()};return n.artifacts[o]=a,a}function Z(t,{chatId:e,artifactId:r,now:n=Date.now()}={}){let o=t||P(),a=String(e||"").trim(),i=String(r||"").trim().toLowerCase();if(!a)throw new TypeError("chat id required");if(!G.test(i))throw new TypeError("artifact id required");return o.threads[a]={artifactId:i,updatedAt:n},o.threads[a]}function me(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 he(t,{ownerId:e,botUsername:r,now:n=Date.now(),ttlMs:o=600*1e3,token:a,randomBytes:i=Xe}={}){let l=t||P(),d=String(e||"").trim(),c=String(r||"").replace(/^@/,"").trim();if(!ce.test(d))throw new TypeError("owner Telegram id required");if(!/^[A-Za-z0-9_]{5,32}$/.test(c))throw new TypeError("bot username required");let f=a||i(16).toString("hex");if(!se.test(f))throw new TypeError("link token must be 32 hex chars");return l.links[de(f)]={ownerId:d,expiresAt:n+Number(o)},{token:f,url:`https://t.me/${c}?start=${f}`,expiresAt:n+Number(o)}}function ge(t,{token:e,telegramUserId:r,now:n=Date.now()}={}){let o=t||P(),a=String(e||"").trim(),i=String(r||"").trim();if(!se.test(a))return{ok:!1,error:"invalid start token"};if(!ce.test(i))return{ok:!1,error:"invalid telegram user"};let l=de(a),d=o.links[l];return d?(delete o.links[l],Number(d.expiresAt)<=n?{ok:!1,error:"start token expired"}:String(d.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 ye(t,{data:e,chatId:r,grant:n=null,now:o=Date.now()}={}){let a=ot(e);if(!a)return null;if(!it.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&&Z(t,{chatId:r,artifactId:i.id,now:o});let l=D({grant:n},{now:o}),d=fe({artifactId:i.id,openUrl:i.openUrl,hasGrant:l.allowed});return a.action==="refresh"?{text:pe(i),buttons:d,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:d,prompt:null,prepare:{artifactId:i.id,unsigned:!0,broadcast:!1}}:{text:`Prepare blocked \u2014 ${l.reason}. Deepen and Refresh still work.`,buttons:d,prompt:null}}function be(t={},{grant:e=null,now:r=Date.now(),state:n}={}){let o=n||X(),a=String(t.id||`art-${Math.abs(Number(r)).toString(36)}`).toLowerCase().slice(0,40),i=at(o,{...t,id:a},{now:r}),l=D({grant:e},{now:r});return{text:pe({...i,grant:e}),replyMarkup:fe({artifactId:i.id,openUrl:i.openUrl,hasGrant:l.allowed}).replyMarkup,artifact:i,state:o}}var xe=`oracle telegram \u2014 TrueNorth-style interactive cards (native, no Hermes)
2
+ import{createInterface as Ce}from"node:readline";var S=Object.freeze({maxRequestBytes:256*1024,maxResponseBytes:2*1024*1024,maxTools:256,maxToolNameLength:64,maxArgumentBytes:128*1024,defaultCallTimeoutMs:3e4,maxCallTimeoutMs:6e4,maxConcurrentCalls:32}),Ae=/^[A-Za-z0-9_-]{1,64}$/;function q(t,e){return{jsonrpc:"2.0",id:t??null,result:e}}function g(t,e,r){return{jsonrpc:"2.0",id:t??null,error:{code:e,message:r}}}function Re(t){return!!(t&&typeof t=="object"&&!Array.isArray(t)&&t.jsonrpc==="2.0"&&typeof t.method=="string"&&t.method.length>0)}function _e(t){if(!Array.isArray(t))return[];let e=[],r=new Set;for(let n of t){if(e.length>=S.maxTools)break;if(!n||typeof n!="object"||Array.isArray(n))continue;let o=typeof n.name=="string"?n.name.trim():"";if(!Ae.test(o)||r.has(o))continue;r.add(o);let a=n.inputSchema&&typeof n.inputSchema=="object"&&!Array.isArray(n.inputSchema)?{...n.inputSchema}:{type:"object",properties:{},additionalProperties:!1};a.type==="object"&&a.additionalProperties===void 0&&(a.additionalProperties=!1),e.push({...n,name:o,inputSchema:a})}return e}function Ne(t){let e=Number(t)||S.defaultCallTimeoutMs;return Math.min(Math.max(e,1),S.maxCallTimeoutMs)}async function Oe(t,e,r){let n;try{return await Promise.race([t,new Promise((o,a)=>{n=setTimeout(()=>{let i=new Error("tool call timed out");i.code="ORACLE_MCP_TIMEOUT",a(i);try{r?.()}catch{}},e)})])}finally{clearTimeout(n)}}function Ee(t){return t===null?"null":Array.isArray(t)?"array":Number.isInteger(t)?"integer":typeof t}function j(t,e,r="arguments",n=0){if(!e||typeof e!="object"||Array.isArray(e))return null;if(n>12)return`${r} exceeded the nesting limit`;if(Array.isArray(e.oneOf)&&e.oneOf.length&&!e.oneOf.some(a=>j(t,a,r,n+1)===null))return`${r} did not match an allowed shape`;if(Array.isArray(e.anyOf)&&e.anyOf.length&&!e.anyOf.some(a=>j(t,a,r,n+1)===null))return`${r} did not match a required alternative`;if(Array.isArray(e.enum)&&!e.enum.some(o=>Object.is(o,t)))return`${r} must be one of the allowed values`;if(Object.hasOwn(e,"const")&&!Object.is(e.const,t))return`${r} must equal the required constant`;if(e.type){let o=Ee(t);if(!(e.type==="number"?typeof t=="number"&&Number.isFinite(t):e.type==="integer"?Number.isSafeInteger(t):o===e.type))return`${r} must be ${e.type}`}if(typeof t=="string"){let o=Math.min(Number.isSafeInteger(e.maxLength)?e.maxLength:16384,16384);if(t.length>o)return`${r} exceeded the string limit`;if(Number.isSafeInteger(e.minLength)&&t.length<e.minLength)return`${r} is too short`}if(Array.isArray(t)){let o=Math.min(Number.isSafeInteger(e.maxItems)?e.maxItems:1e3,1e3);if(t.length>o)return`${r} exceeded the array limit`;if(Number.isSafeInteger(e.minItems)&&t.length<e.minItems)return`${r} has too few items`;if(e.items)for(let a=0;a<t.length;a+=1){let i=j(t[a],e.items,`${r}[${a}]`,n+1);if(i)return i}}if(t&&typeof t=="object"&&!Array.isArray(t)){let o=Object.keys(t);if(o.length>256)return`${r} exceeded the property limit`;let a=e.properties&&typeof e.properties=="object"?e.properties:{};for(let i of Array.isArray(e.required)?e.required:[])if(!Object.hasOwn(t,i))return`${r}.${i} is required`;if(e.additionalProperties===!1){let i=o.find(c=>!Object.hasOwn(a,c));if(i)return`${r}.${i} is not allowed`}for(let i of o){if(!Object.hasOwn(a,i))continue;let c=j(t[i],a[i],`${r}.${i}`,n+1);if(c)return c}}return null}function Ie(t,e={}){let r=_e(t?.tools),n=new Set(r.map(d=>d.name)),o=new Map(r.map(d=>[d.name,d])),a=typeof t?.name=="string"&&t.name?t.name.slice(0,80):"oracle-mcp",i=typeof t?.version=="string"&&t.version?t.version.slice(0,40):"1",c=Ne(e.callTimeoutMs),u=!1;return async function(f){let p=f?.id??null;if(!Re(f))return g(p,-32600,"invalid request");if(f.method==="initialize")return u=!0,q(p,{protocolVersion:f.params?.protocolVersion??"2025-03-26",capabilities:{tools:{}},serverInfo:{name:a,version:i}});if(f.method==="notifications/initialized")return null;if(f.method==="ping")return q(p,{});if(!u)return g(p,-32002,"server not initialized");if(f.method==="tools/list")return q(p,{tools:r});if(f.method==="tools/call"){let $=f.params?.name,w=f.params?.arguments??{};if(typeof $!="string"||!n.has($))return g(p,-32602,"unknown tool");if(!w||typeof w!="object"||Array.isArray(w))return g(p,-32602,"tool arguments must be an object");let N;try{N=JSON.stringify(w)}catch{return g(p,-32602,"tool arguments are not serializable")}if(Buffer.byteLength(N)>S.maxArgumentBytes)return g(p,-32602,"tool arguments exceeded the size limit");let P=j(w,o.get($)?.inputSchema);if(P)return g(p,-32602,P);try{let x=new AbortController,O=await Oe(Promise.resolve(t.call($,w,{signal:x.signal})),c,()=>x.abort(new Error("tool call timed out")));return q(p,O)}catch(x){if(x?.code==="ORACLE_MCP_TIMEOUT")return g(p,-32001,"tool call timed out");let O=typeof x?.message=="string"?x.message.replace(/\s+/g," ").trim():"",B=/\b(requires?|must be|missing|unknown|invalid|expected|unsupported|out of range|too (?:large|small|long|many)|not a|cannot convert)\b/i.test(O),F=/https?:\/\/|[/~][\w.-]+\/|0x[0-9a-fA-F]{8,}|[A-Za-z0-9+/_-]{24,}={0,2}|\b(?:secret|apikey|api[-_ ]key|private[-_ ]?key|token|password|credential|seed|mnemonic)s?\b/i.test(O.replace(/\btoken(?:In|Out|s\b)/g,"asset"));return B&&!F&&O.length<=200?g(p,-32e3,`tool call failed: ${O}`):g(p,-32e3,"tool call failed")}}return g(p,-32601,"method not found")}}function te(t,e={}){let r=e.input||process.stdin,n=e.output||process.stdout,o=Math.min(Math.max(Number(e.maxRequestBytes)||S.maxRequestBytes,64),S.maxRequestBytes),a=Math.min(Math.max(Number(e.maxResponseBytes)||S.maxResponseBytes,256),S.maxResponseBytes),i=Math.min(Math.max(Number(e.maxConcurrentCalls)||S.maxConcurrentCalls,1),S.maxConcurrentCalls),c=i*8,u=Ie(t,e),d={closed:!1,inflight:0},f=Ce({input:r,terminal:!1,crlfDelay:1/0}),p=0,$=[],w=!1,N=!1;function P(){if(d.closed||d.readerClosed)return;let y=d.inflight>=i||$.length>0||N;y&&!w?(w=!0,f.pause(),typeof r.pause=="function"&&r.pause()):!y&&w&&(w=!1,typeof r.resume=="function"&&r.resume(),f.resume())}function x(y){if(!y||d.closed)return;let k=JSON.stringify(y);Buffer.byteLength(k)>a&&(k=JSON.stringify(g(y.id,-32003,"response exceeded the size limit"))),n.write(`${k}
3
+ `)===!1&&!N&&(N=!0,P(),n.once("drain",()=>{N=!1,B()}))}function O(y){d.inflight+=1,P(),Promise.resolve(u(y)).then(x).catch(()=>x(g(y?.id,-32603,"internal error"))).finally(()=>{d.inflight-=1,B()})}function B(){for(;!d.closed&&!N&&d.inflight<i&&$.length>0;)O($.shift());P()}function F(){d.closed||(x(g(null,-32700,"request exceeded the size limit")),d.closed=!0,f.close(),typeof r.destroy=="function"&&r.destroy())}return r.on("data",y=>{if(d.closed)return;let k=String(y).split(`
4
+ `);for(let U=0;U<k.length;U+=1){if(p+=Buffer.byteLength(k[U]),p>o){F();return}U<k.length-1&&(p=0)}}),f.on("line",y=>{if(d.closed)return;if(Buffer.byteLength(y)>o){F();return}let k;try{k=JSON.parse(y)}catch{x(g(null,-32700,"parse error"));return}if($.length>=c){x(g(k?.id,-32e3,"server busy"));return}$.push(k),B()}),f.on("close",()=>{d.readerClosed=!0,e.exitOnClose!==!1&&(process.exitCode=0)}),d}import{createHash as Xe,randomBytes as Ze}from"node:crypto";import{mkdirSync as Qe,readFileSync as et,writeFileSync as tt}from"node:fs";import{homedir as rt}from"node:os";import{dirname as nt,join as ae}from"node:path";var Le=/^[A-Z0-9][A-Z0-9._-]{0,11}$/;function Te(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 re(t,{coin:e,side:r,sizeUsd:n,leverage:o,venue:a,confirm:i,user:c}={}){let u=Te(t);if(!u)return null;if(e&&Le.test(String(e).toUpperCase())&&u.searchParams.set("coin",String(e).toUpperCase()),(r==="long"||r==="short")&&u.searchParams.set("side",r),Number.isFinite(Number(n))&&Number(n)>=1&&u.searchParams.set("size",String(Math.min(1e5,Math.round(Number(n))))),Number.isInteger(Number(o))&&Number(o)>=1&&u.searchParams.set("lev",String(Math.min(50,Number(o)))),a){let d=String(a).toLowerCase()==="hl"?"hyperliquid":String(a).toLowerCase();u.searchParams.set("venue",d)}else u.searchParams.get("venue")||u.searchParams.set("venue","hyperliquid");return u.searchParams.set("view","perps"),u.searchParams.set("build","1"),i&&/^[0-9a-f]{32}$/i.test(String(i))&&u.searchParams.set("confirm",String(i).toLowerCase()),c&&/^0x[0-9a-fA-F]{40}$/.test(String(c))&&u.searchParams.set("user",String(c).toLowerCase()),u.toString()}var Pe={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}},Me=new Map(Object.values(Pe).map(t=>[t.chainId,t]));function ne(t){return Me.get(Number(t))||null}var At=Object.freeze([100,50,25]),Rt=Object.freeze([100,50,25,10]);var l="UNKNOWN",It=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),ve=/[_*[\]`]/g;function s(t){return m(t)?String(t).replace(ve,e=>`\\${e}`):l}function m(t){return t==null?!1:typeof t=="number"?Number.isFinite(t):typeof t=="string"?t.trim()!=="":!0}function C(t){if(!m(t))return l;let e=String(t).replace(/`/g,"");return e===""?l:`\`${e}\``}function L(t,{decimals:e=2}={}){if(!m(t))return l;let r=Number(t);return Number.isFinite(r)?r.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:e}):l}function h(t,{decimals:e=2}={}){let r=L(t,{decimals:e});return r===l?l:`${r} USD`}function W(t,{decimals:e=2}={}){let r=L(t,{decimals:e});return r===l?l:`${r}%`}function z(t){let e=L(t,{decimals:0});return e===l?l:`${e} bps`}function T(t,e){if(!m(t))return l;let r=Number(e);if(!Number.isInteger(r)||r<0||r>77)return l;let n;try{n=BigInt(typeof t=="string"?t.trim():t)}catch{return l}let o=n<0n,a=o?-n:n,i=10n**BigInt(r),c=(a/i).toString(),u=(a%i).toString().padStart(r,"0").replace(/0+$/,"");return`${o?"-":""}${c}${u?`.${u}`:""}`}function K(t){if(typeof t=="number"&&Number.isFinite(t))return t<0||t>1?l: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 l}function E(t={}){let e=t.chainId;if(!m(e)||!Number.isFinite(Number(e)))return m(t.chain)?s(t.chain):l;let n=ne(e)?.name||(m(t.chain)?String(t.chain):l);return`${s(n)} (chainId ${Number(e)})`}function ie(t={}){return s(t.venue??t.dex??t.pool?.venue)}function Be(t){return t==null?"NONE (text card only)":typeof t=="string"?t.trim()?C(t):"NONE (text card only)":t.error||t.ok===!1||t.available===!1?`UNAVAILABLE${m(t.error)?` \u2014 ${s(t.error)}`:""} (text card stands)`:m(t.url)?C(t.url):"NONE (text card only)"}function H(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(m(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 Ue(t){let e=H(t);return e.allowed?`${e.actions.map(r=>s(r)).join(" / ")} (${s(e.reason)})`:`prepare-only \u2014 ${s(e.reason)}`}function A(t,e,r={}){let n=[`*${t}*`];for(let[o,a]of e)n.push(`${o}: ${a==null||a===""?l:a}`);return n.push(`Chart: ${Be(r.chart)}`),n.push(`Actions: ${Ue(r)}`),Array.isArray(r.warnings)&&r.warnings.length&&n.push(`Warnings: ${r.warnings.map(o=>s(o)).join("; ")}`),(m(r.source)||m(r.fetchedAt))&&n.push(`Source: ${s(r.source)} at ${s(r.fetchedAt)}`),n.join(`
5
+ `)}function R(t){return["Confidence",K(t.confidence)]}function je(t){let e=t.quote;if(!e||typeof e!="object")return[];let r=m(e.decimals)?T(e.amountOutRaw??e.out??e.raw,e.decimals):l;return[["Quote out (raw)",C(e.amountOutRaw??e.out??e.raw)],["Quote out",r===l?l:`${s(r)} ${s(e.symbol??"")}`.trim()]]}function oe(t){let e=t.autoSlippage;if(!e||typeof e!="object")return["Auto-slippage",l];let r=z(e.selectedBps),n=z(e.capBps);return["Auto-slippage",r===l&&n===l?l:`${r} selected, cap ${n}`]}function He(t={}){let e=t||{};return A(`ORACLE TOKEN \u2014 ${s(e.symbol??e.token??e.name)}`,[["Chain",E(e)],["Venue",ie(e)],["Name",s(e.name)],["Address",C(e.address??e.mint??e.contract)],["Price",h(e.priceUsd,{decimals:8})],["Market cap",h(e.marketCapUsd)],["Liquidity",h(e.liquidityUsd)],["Volume 24h",h(e.volume24hUsd)],["Change 24h",W(e.priceChange24h)],["Fee tier",m(e.feeTier)?`${z(Number(e.feeTier)/100)} (${L(e.feeTier,{decimals:0})})`:l],["Age",s(e.age)],...je(e),oe(e),R(e)],e)}function De(t={}){let e=t||{};return A(`ORACLE LAUNCH \u2014 ${s(e.symbol??e.token??e.name)}`,[["Chain",E(e)],["Venue",ie(e)],["Address",C(e.address??e.mint??e.contract)],["Pool",C(e.pool?.address??e.poolAddress??e.pool)],["Liquidity",h(e.liquidityUsd)],["Route ready",s(e.routeReady)],["Sellable",s(e.sellable)],["Sell sim",s(e.sellSimulation??e.sellSim)],["Smart wallets",s(e.smartWalletOverlap)],["Risk",s(e.risk??e.riskStatus)],["Prepared ticket",s(e.preparedTicket??e.ticketStatus)],oe(e),R(e)],e)}function Fe(t={}){let e=t||{};return A(`ORACLE HIP-3 \u2014 ${s(e.market??e.coin??e.name)}`,[["Venue",`Hyperliquid builder-dex ${s(e.dex)}`],["Market",s(e.market??e.coin)],["Mark",h(e.markPx,{decimals:6})],["Oracle",h(e.oraclePx,{decimals:6})],["Funding",W(e.funding,{decimals:6})],["Open interest",h(e.openInterestUsd)],["Depth",s(e.depth)],["Liquidation notes",s(e.liquidationNotes??e.riskNotes)],["Account context",s(e.accountContext)],R(e)],e)}function qe(t={}){let e=t||{};return A(`ORACLE HIP-4 \u2014 ${s(e.event??e.market??e.name)}`,[["Venue",`Hyperliquid HIP-4 ${s(e.dex??"outcome")}`],["Event",s(e.event)],["Outcome",s(e.outcome)],["Market id",C(e.marketId??e.market)],["Bid",h(e.bid,{decimals:6})],["Ask",h(e.ask,{decimals:6})],["Depth",s(e.depth)],["Edge",W(e.edge)],["Position",s(e.position)],R(e)],e)}function ze(t={}){let e=t||{};return A(`ORACLE POLYMARKET \u2014 ${s(e.event??e.market??e.name)}`,[["Venue","Polymarket CLOB"],["Event",s(e.event)],["Market",s(e.market)],["Market id",C(e.marketId??e.conditionId??e.tokenId)],["Yes",h(e.yesPrice,{decimals:4})],["No",h(e.noPrice,{decimals:4})],["Best bid / ask",`${h(e.bestBid,{decimals:4})} / ${h(e.bestAsk,{decimals:4})}`],["Volume",h(e.volumeUsd)],["Resolution risk",s(e.resolutionRisk)],["Order intent",s(e.orderIntent)],R(e)],e)}function Ve(t={}){let e=t||{},r=m(e.completedSplits)&&m(e.totalSplits)?`${L(e.completedSplits,{decimals:0})} / ${L(e.totalSplits,{decimals:0})}`:l;return A(`ORACLE TWAP \u2014 ${s(e.pair??e.symbol??e.name)}`,[["Chain",E(e)],["Side",s(e.side??e.direction)],["Amount",`${s(T(e.amountTotal??e.amount,e.decimals??18))} ${s(e.symbol??"")}`.trim()],["Splits",`${L(e.totalSplits,{decimals:0})} over ${s(e.window)}`],["Progress",r],["Avg price",h(e.averagePrice,{decimals:6})],["Next split",s(e.nextSplitAt)],["Slippage cap",z(e.slippageBps)],["Status",s(e.status)],R(e)],e)}function We(t={}){let e=t||{},r=e.approval??e.revokeCheck??{},n=r.needsRevoke&&r.spender?`revoke.cash \u2014 ${s(r.spender)}`:r.needsRevoke===!1?"revoke.cash \u2014 clean":"revoke.cash \u2014 unchecked";return A(`ORACLE BRIDGE \u2014 ${s(e.pair??e.fromSymbol)} \u2192 ${s(e.toSymbol??"")}`.replace(/→ $/,""),[["Bridging","deBridge \xB7 LI.FI \u2014 best route wins"],["From chain",E({chainId:e.fromChainId,chain:e.fromChain})],["To chain",E({chainId:e.toChainId,chain:e.toChain})],["Amount",`${s(T(e.amount,e.fromDecimals??18))} ${s(e.fromSymbol??"")}`.trim()],["Best route",s(e.bestRoute??e.winner)],["Est. received",`${s(T(e.amountOut,e.toDecimals??18))} ${s(e.toSymbol??"")}`.trim()],["Fee",h(e.feeUsd)],["Est. time",s(e.estimatedTime)],["Revoke check",n],["All providers",s(e.providers?.join(", "))],["Preparable",s(e.preparable)],R(e)],e)}function Ke(t){let r=(Array.isArray(t)?t:[]).slice(1,4).map(n=>{let o=s(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("; "):l}function Je(t){let e=t.rankedOn??t.swap?.rankedOn??t.best?.rankedOn;return m(e)?s(e):l}function Ye(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=`${s(e.tokenInSymbol??e.fromSymbol??"IN")} \u2192 ${s(e.tokenOutSymbol??e.toSymbol??"OUT")}`,i=[["Intent",s(e.intent??"swap")],["Chain",E({chainId:e.chainId??r.chainId,chain:e.chain??r.chain})],["Pair",a],["Amount in",`${s(T(e.amountIn??r.amountIn,e.decimalsIn??18))} ${s(e.tokenInSymbol??"")}`.trim()],["Best swap",s(o.source??o.venue??r.bestRoute??e.bestRoute)],["Net out",`${s(T(o.netOut??o.amountOut??r.amountOut,e.decimalsOut??18))} ${s(e.tokenOutSymbol??"")}`.trim()],["Ranked on",Je(r)],["Gas accounted",s(o.costAccounted===!0?"yes":o.costAccounted===!1?"no \u2014 gross ranking may flatter this route":null)],["Spread vs next",m(r.improvementBps)?`${s(r.improvementBps)} bps`:l],["Runners-up",Ke(r.routes??e.routes)]];if(n){let c=n.best??n.winner??{};i.push(["Best bridge",s(c.source??n.bestRoute??e.bestBridge)],["Bridge out",`${s(T(c.netOut??c.amountOut??n.amountOut,e.bridgeDecimalsOut??e.decimalsOut??18))} ${s(e.bridgeOutSymbol??e.tokenOutSymbol??"")}`.trim()],["Bridge to",E({chainId:n.toChainId??e.toChainId,chain:n.toChain??e.toChain})],["Est. time",s(n.estimatedTime??c.meta?.durationSeconds)])}else i.push(["Best bridge","same-chain \u2014 use Best swap"]);return i.push(["Preparable",s(e.preparable??o.executionReady)],R(e)),A(`ORACLE SWAP \u2014 ${a}`,i,e)}function Ge(t={}){let e=t||{};return A("ORACLE APPROVE \u2014 local signer",[["Pending id",C(e.id??(typeof e.digest=="string"?e.digest.slice(0,8):null))],["Surface",s(e.surface)],["Action",s(e.action)],["Chain",E({chainId:e.chain??e.chainId,chain:e.chainName})],["To",C(e.to??e.destination)],["Value",m(e.value)?s(e.value):l],["Signer",s(e.armed===!0?"running + armed":e.armed===!1?"running, disarmed":"not running")],R({confidence:e.confidence??(e.armed===!0?"high":"low")})],e)}var Lt=Object.freeze({token:He,launch:De,hip3:Fe,hip4:qe,polymarket:ze,twap:Ve,bridge:We,swap:Ye,approve:Ge});var it=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),ot=new Set(it),Y=/^[a-z0-9-]{4,40}$/i,se=/^[0-9a-f]{32}$/,ce=/^\d+$/;function G(t=process.env){return ae(t.ORACLE_CONFIG_DIR||ae(rt(),".config","oracle"),"telegram-cards.json")}function M(){return{links:{},artifacts:{},threads:{}}}var D=M();function X(){return D}function le(t,{readFile:e=et}={}){try{let r=JSON.parse(String(e(t)));D={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{D=M()}return D}function ue(t,e=D,{writeFile:r=tt,mkdir:n=Qe}={}){n(nt(t),{recursive:!0,mode:448}),r(t,JSON.stringify(e),{mode:384})}function I(t){return t==null?!1:typeof t=="string"?t.trim()!=="":!0}function de(t){return Xe("sha256").update(String(t)).digest("hex")}function J(t){if(Array.isArray(t))return t.map(J);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]=J(n));return e}function at(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 fe({platform:t="telegram",artifactId:e,openUrl:r,hasGrant:n=!1}={}){let o=String(e||"").trim().toLowerCase();if(!Y.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=>re(r,{side:p}),u=c("long"),d=c("short"),f=u&&d?[{text:"LONG",url:u},{text:"SHORT",url:d}]:[{text:"LONG",callback_data:`oracle:card:long:${o}`},{text:"SHORT",callback_data:`oracle:card:short:${o}`}];return I(r)?(a.push([{text:"Open",url:String(r)},i[0]]),a.push(f),a.push(n?[i[1],{text:"Prep",callback_data:`oracle:card:prepare:${o}`}]:[i[1]])):(a.push(i),a.push(f),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 pe(t={}){let r=[`*${I(t.title)?s(t.title):"Oracle artifact"}*`,`Kind: ${I(t.kind)?s(t.kind):l}`,`Id: ${I(t.id)?`\`${String(t.id).replace(/`/g,"")}\``:l}`,`Summary: ${I(t.summary)?s(t.summary):l}`,`Confidence: ${K(t.confidence)}`];(I(t.source)||I(t.fetchedAt))&&r.push(`Source: ${s(t.source)} at ${s(t.fetchedAt)}`),Array.isArray(t.warnings)&&t.warnings.length&&r.push(`Warnings: ${t.warnings.map(o=>s(o)).join("; ")}`);let n=H(t);return r.push(n.allowed?"Actions: TA / FA / LONG / SHORT open the graph. Execute on CONFIRM there.":`Actions: TA / FA / LONG / SHORT \u2014 ${s(n.reason)}`),r.join(`
6
+ `)}function st(t,e={},{now:r=Date.now()}={}){let n=t||M(),o=String(e.id||"").trim().toLowerCase();if(!Y.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:I(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:J(e.payload||{}),createdAt:new Date(r).toISOString()};return n.artifacts[o]=a,a}function Z(t,{chatId:e,artifactId:r,now:n=Date.now()}={}){let o=t||M(),a=String(e||"").trim(),i=String(r||"").trim().toLowerCase();if(!a)throw new TypeError("chat id required");if(!Y.test(i))throw new TypeError("artifact id required");return o.threads[a]={artifactId:i,updatedAt:n},o.threads[a]}function me(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 he(t,{ownerId:e,botUsername:r,now:n=Date.now(),ttlMs:o=600*1e3,token:a,randomBytes:i=Ze}={}){let c=t||M(),u=String(e||"").trim(),d=String(r||"").replace(/^@/,"").trim();if(!ce.test(u))throw new TypeError("owner Telegram id required");if(!/^[A-Za-z0-9_]{5,32}$/.test(d))throw new TypeError("bot username required");let f=a||i(16).toString("hex");if(!se.test(f))throw new TypeError("link token must be 32 hex chars");return c.links[de(f)]={ownerId:u,expiresAt:n+Number(o)},{token:f,url:`https://t.me/${d}?start=${f}`,expiresAt:n+Number(o)}}function ge(t,{token:e,telegramUserId:r,now:n=Date.now()}={}){let o=t||M(),a=String(e||"").trim(),i=String(r||"").trim();if(!se.test(a))return{ok:!1,error:"invalid start token"};if(!ce.test(i))return{ok:!1,error:"invalid telegram user"};let c=de(a),u=o.links[c];return u?(delete o.links[c],Number(u.expiresAt)<=n?{ok:!1,error:"start token expired"}:String(u.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 ye(t,{data:e,chatId:r,grant:n=null,now:o=Date.now()}={}){let a=at(e);if(!a)return null;if(!ot.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&&Z(t,{chatId:r,artifactId:i.id,now:o});let c=H({grant:n},{now:o}),u=fe({artifactId:i.id,openUrl:i.openUrl,hasGrant:c.allowed});return a.action==="refresh"?{text:pe(i),buttons:u,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:u,prompt:null,prepare:{artifactId:i.id,unsigned:!0,broadcast:!1}}:{text:`Prepare blocked \u2014 ${c.reason}. Deepen and Refresh still work.`,buttons:u,prompt:null}}function be(t={},{grant:e=null,now:r=Date.now(),state:n}={}){let o=n||X(),a=String(t.id||`art-${Math.abs(Number(r)).toString(36)}`).toLowerCase().slice(0,40),i=st(o,{...t,id:a},{now:r}),c=H({grant:e},{now:r});return{text:pe({...i,grant:e}),replyMarkup:fe({artifactId:i.id,openUrl:i.openUrl,hasGrant:c.allowed}).replyMarkup,artifact:i,state:o}}var xe=`oracle telegram \u2014 TrueNorth-style interactive cards (native, no Hermes)
7
7
 
8
8
  oracle telegram link --owner <tg-id> --bot <username>
9
9
  oracle telegram redeem --token <32hex> --user <tg-id>
@@ -13,10 +13,10 @@ import{createInterface as Ae}from"node:readline";var S=Object.freeze({maxRequest
13
13
 
14
14
  Native oracle-gateway uses the same module. Hermes is an optional adapter that
15
15
  must call this CLI instead of owning card state. Prepare is unsigned. Execute
16
- stays on Allow/Deny.`;function b(t,e){let r=t.indexOf(e);return r<0||r+1>=t.length?null:t[r+1]}function we(t,e){return t.includes(e)}function st(){return le(Y()),X()}function V(t){ue(Y(),t)}function M(t,e){t.write(JSON.stringify(e)+`
16
+ stays on Allow/Deny.`;function b(t,e){let r=t.indexOf(e);return r<0||r+1>=t.length?null:t[r+1]}function we(t,e){return t.includes(e)}function ct(){return le(G()),X()}function V(t){ue(G(),t)}function v(t,e){t.write(JSON.stringify(e)+`
17
17
  `)}async function ke(t=[],e={}){let r=e.out??process.stdout,n=e.err??process.stderr,o=t[0];if(!o||o==="--help"||o==="-h"||o==="help")return r.write(xe+`
18
- `),0;let a=st();if(o==="link")try{let i=he(a,{ownerId:b(t,"--owner"),botUsername:b(t,"--bot")});return V(a),M(r,{ok:!0,...i}),0}catch(i){return n.write(String(i.message||i)+`
19
- `),1}if(o==="redeem"){let i=ge(a,{token:b(t,"--token"),telegramUserId:b(t,"--user")});return V(a),M(r,i),i.ok?0:1}if(o==="wrap")try{let i=be({id:b(t,"--id"),kind:b(t,"--kind")||"thesis",title:b(t,"--title")||"Oracle artifact",summary:b(t,"--summary")||"",openUrl:b(t,"--url"),source:"oracle-telegram"},{grant:we(t,"--grant")?{local:!0}:null,state:a}),l=b(t,"--chat");return l&&Z(a,{chatId:l,artifactId:i.artifact.id}),V(a),M(r,{ok:!0,text:i.text,replyMarkup:i.replyMarkup||null,artifactId:i.artifact.id,fallback:`Reply: deepen ${i.artifact.id} | refresh ${i.artifact.id}`}),0}catch(i){return n.write(String(i.message||i)+`
20
- `),1}if(o==="callback"){let i=ye(a,{data:b(t,"--data"),chatId:b(t,"--chat"),grant:we(t,"--grant")?{local:!0}:null});return V(a),i?(M(r,{ok:!0,...i}),0):(M(r,{ok:!1,error:"not an interactive card callback"}),1)}if(o==="continue"){let i=me(a,{chatId:b(t,"--chat"),text:b(t,"--text")});return M(r,{ok:!0,prompt:i}),0}return n.write(`unknown telegram verb '${o}'
18
+ `),0;let a=ct();if(o==="link")try{let i=he(a,{ownerId:b(t,"--owner"),botUsername:b(t,"--bot")});return V(a),v(r,{ok:!0,...i}),0}catch(i){return n.write(String(i.message||i)+`
19
+ `),1}if(o==="redeem"){let i=ge(a,{token:b(t,"--token"),telegramUserId:b(t,"--user")});return V(a),v(r,i),i.ok?0:1}if(o==="wrap")try{let i=be({id:b(t,"--id"),kind:b(t,"--kind")||"thesis",title:b(t,"--title")||"Oracle artifact",summary:b(t,"--summary")||"",openUrl:b(t,"--url"),source:"oracle-telegram"},{grant:we(t,"--grant")?{local:!0}:null,state:a}),c=b(t,"--chat");return c&&Z(a,{chatId:c,artifactId:i.artifact.id}),V(a),v(r,{ok:!0,text:i.text,replyMarkup:i.replyMarkup||null,artifactId:i.artifact.id,fallback:`Reply: deepen ${i.artifact.id} | refresh ${i.artifact.id}`}),0}catch(i){return n.write(String(i.message||i)+`
20
+ `),1}if(o==="callback"){let i=ye(a,{data:b(t,"--data"),chatId:b(t,"--chat"),grant:we(t,"--grant")?{local:!0}:null});return V(a),i?(v(r,{ok:!0,...i}),0):(v(r,{ok:!1,error:"not an interactive card callback"}),1)}if(o==="continue"){let i=me(a,{chatId:b(t,"--chat"),text:b(t,"--text")});return v(r,{ok:!0,prompt:i}),0}return n.write(`unknown telegram verb '${o}'
21
21
  ${xe}
22
- `),1}var ct=40,lt=200,ut=4e3,dt=4e3,ft=128,$e=/^[a-z0-9][a-z0-9-]{3,39}$/i,Q=/^\d{1,20}$/,pt=/^oracle:card:(deepen|refresh|prepare|ta|fa|long|short|allow|deny):[a-z0-9][a-z0-9-]{3,39}$/i;function mt(t=process.env){return t.ORACLE_TELEGRAM_CARD_GRANT==="1"?{local:!0}:null}function _(t,{field:e,max:r,pattern:n}){if(typeof t!="string")throw new Error(`${e} must be a string`);let o=t.trim();if(!o)throw new Error(`${e} is required`);if(o.length>r)throw new Error(`${e} exceeds ${r} chars`);if(n&&!n.test(o))throw new Error(`${e} is malformed`);return o}function ht(){let t="",e="";return{io:{out:{write(r){return t+=String(r),!0}},err:{write(r){return e+=String(r),!0}}},stdout(){return t},stderr(){return e}}}async function ee(t){let e=ht(),r=await ke(t,e.io),n;try{n=JSON.parse(e.stdout()||"{}")}catch{n={text:e.stdout()}}return r!==0&&!n.error&&(n.error=e.stderr()||"telegram command failed"),{content:[{type:"text",text:JSON.stringify({code:r,...n})}]}}function Se(t){return{isError:!0,content:[{type:"text",text:JSON.stringify({error:t})}]}}var gt=[{name:"telegram_wrap",description:"Wrap a scan/quote/thesis as a TrueNorth-style Oracle artifact card. Prepare stays unsigned. No Execute button.",inputSchema:{type:"object",required:["id","title","summary"],properties:{id:{type:"string",description:"artifact id, [a-z0-9-]{4,40}"},title:{type:"string"},summary:{type:"string"},kind:{type:"string"},chat:{type:"string",description:"Telegram chat id, digits only"}}}},{name:"telegram_callback",description:"Handle deepen/refresh/prepare on an Oracle artifact card. Prepare is unsigned. Execute stays on Allow/Deny.",inputSchema:{type:"object",required:["data","chat"],properties:{data:{type:"string",description:"oracle:card:<action>:<id>"},chat:{type:"string"}}}},{name:"telegram_continue",description:"Continue the last artifact thread for this Telegram chat.",inputSchema:{type:"object",required:["chat","text"],properties:{chat:{type:"string"},text:{type:"string"}}}}],yt={name:"oracle-telegram",version:"2",tools:gt,async call(t,e={},{env:r=process.env}={}){let n=mt(r);try{if(t==="telegram_wrap"){let o=["wrap","--id",_(e.id,{field:"id",max:ct,pattern:$e}),"--title",_(e.title,{field:"title",max:lt}),"--summary",_(e.summary,{field:"summary",max:ut})];return e.kind!==void 0&&o.push("--kind",_(e.kind,{field:"kind",max:40,pattern:$e})),e.chat!==void 0&&o.push("--chat",_(e.chat,{field:"chat",max:20,pattern:Q})),n&&o.push("--grant"),await ee(o)}if(t==="telegram_callback"){let o=["callback","--data",_(e.data,{field:"data",max:ft,pattern:pt}),"--chat",_(e.chat,{field:"chat",max:20,pattern:Q})];return n&&o.push("--grant"),await ee(o)}if(t==="telegram_continue")return await ee(["continue","--chat",_(e.chat,{field:"chat",max:20,pattern:Q}),"--text",_(e.text,{field:"text",max:dt})])}catch(o){return Se(o.message)}return Se("unknown tool")}};process.argv[1]&&process.argv[1].endsWith("oracle-telegram-mcp.mjs")&&te(yt);export{mt as grantFromEnv,yt as server};
22
+ `),1}var lt=40,ut=200,dt=4e3,ft=4e3,pt=128,$e=/^[a-z0-9][a-z0-9-]{3,39}$/i,Q=/^\d{1,20}$/,mt=/^oracle:card:(deepen|refresh|prepare|ta|fa|long|short|allow|deny):[a-z0-9][a-z0-9-]{3,39}$/i;function ht(t=process.env){return t.ORACLE_TELEGRAM_CARD_GRANT==="1"?{local:!0}:null}function _(t,{field:e,max:r,pattern:n}){if(typeof t!="string")throw new Error(`${e} must be a string`);let o=t.trim();if(!o)throw new Error(`${e} is required`);if(o.length>r)throw new Error(`${e} exceeds ${r} chars`);if(n&&!n.test(o))throw new Error(`${e} is malformed`);return o}function gt(){let t="",e="";return{io:{out:{write(r){return t+=String(r),!0}},err:{write(r){return e+=String(r),!0}}},stdout(){return t},stderr(){return e}}}async function ee(t){let e=gt(),r=await ke(t,e.io),n;try{n=JSON.parse(e.stdout()||"{}")}catch{n={text:e.stdout()}}return r!==0&&!n.error&&(n.error=e.stderr()||"telegram command failed"),{content:[{type:"text",text:JSON.stringify({code:r,...n})}]}}function Se(t){return{isError:!0,content:[{type:"text",text:JSON.stringify({error:t})}]}}var yt=[{name:"telegram_wrap",description:"Wrap a scan/quote/thesis as a TrueNorth-style Oracle artifact card. Prepare stays unsigned. No Execute button.",inputSchema:{type:"object",required:["id","title","summary"],properties:{id:{type:"string",description:"artifact id, [a-z0-9-]{4,40}"},title:{type:"string"},summary:{type:"string"},kind:{type:"string"},chat:{type:"string",description:"Telegram chat id, digits only"}}}},{name:"telegram_callback",description:"Handle deepen/refresh/prepare on an Oracle artifact card. Prepare is unsigned. Execute stays on Allow/Deny.",inputSchema:{type:"object",required:["data","chat"],properties:{data:{type:"string",description:"oracle:card:<action>:<id>"},chat:{type:"string"}}}},{name:"telegram_continue",description:"Continue the last artifact thread for this Telegram chat.",inputSchema:{type:"object",required:["chat","text"],properties:{chat:{type:"string"},text:{type:"string"}}}}],bt={name:"oracle-telegram",version:"2",tools:yt,async call(t,e={},{env:r=process.env}={}){let n=ht(r);try{if(t==="telegram_wrap"){let o=["wrap","--id",_(e.id,{field:"id",max:lt,pattern:$e}),"--title",_(e.title,{field:"title",max:ut}),"--summary",_(e.summary,{field:"summary",max:dt})];return e.kind!==void 0&&o.push("--kind",_(e.kind,{field:"kind",max:40,pattern:$e})),e.chat!==void 0&&o.push("--chat",_(e.chat,{field:"chat",max:20,pattern:Q})),n&&o.push("--grant"),await ee(o)}if(t==="telegram_callback"){let o=["callback","--data",_(e.data,{field:"data",max:pt,pattern:mt}),"--chat",_(e.chat,{field:"chat",max:20,pattern:Q})];return n&&o.push("--grant"),await ee(o)}if(t==="telegram_continue")return await ee(["continue","--chat",_(e.chat,{field:"chat",max:20,pattern:Q}),"--text",_(e.text,{field:"text",max:ft})])}catch(o){return Se(o.message)}return Se("unknown tool")}};process.argv[1]&&process.argv[1].endsWith("oracle-telegram-mcp.mjs")&&te(bt);export{ht as grantFromEnv,bt as server};
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{realpathSync as T}from"node:fs";import{fileURLToPath as oe}from"node:url";import h from"node:fs";import g from"node:path";import{pathToFileURL as z}from"node:url";import d from"node:fs";import P from"node:os";import i from"node:path";import{fileURLToPath as $}from"node:url";var M=i.dirname($(import.meta.url)),l=i.resolve(M,"../..");function u(){return process.env.ORACLE_FAKE_HOME||P.homedir()}function v(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function f(){return v()?process.env.ORACLE_CONFIG_DIR||i.join(u(),".config","oracle"):i.join(u(),".config","oracle")}function I(){return i.join(f(),"exec.env")}function R(){return i.join(f(),"desk.json")}function k(){return i.join(f(),"env")}function p({force:e=!1}={}){if(p._done&&!e)return p._result||null;p._done=!0;let o={},n=(c,t)=>{if(t==null)return;let r=String(t).trim();r&&(process.env[c]!=null&&String(process.env[c]).trim()!==""||(process.env[c]=r,o[c]=r))};try{let c=k();if(d.existsSync(c))for(let t of d.readFileSync(c,"utf8").split(/\r?\n/)){let r=t.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*?)\s*$/);if(!r||r[2].startsWith("#"))continue;let a=r[2];(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),n(r[1],a)}}catch{}try{let c=R();if(d.existsSync(c)){let t=JSON.parse(d.readFileSync(c,"utf8"));t&&typeof t=="object"&&(n("ORACLE_DESK_URL",t.deskUrl||t.dataUrl||t.url),n("ORACLE_DATA_URL",t.dataUrl||t.deskUrl||t.url),n("ORACLE_API_URL",t.apiUrl||t.dataUrl||t.deskUrl),n("ORACLE_PUBLIC_URL",t.publicUrl||t.deskUrl||t.dataUrl),n("ORACLE_EXEC_URL",t.execUrl),n("MAD_DESK_URL",t.deskUrl||t.dataUrl))}}catch{}let s=process.env.ORACLE_DESK_URL||process.env.ORACLE_DATA_URL||"";return s&&(n("ORACLE_DESK_URL",s),n("ORACLE_DATA_URL",s),n("ORACLE_API_URL",s),n("ORACLE_PUBLIC_URL",s),n("MAD_DESK_URL",s)),p._result=Object.keys(o).length?o:null,p._result}try{p()}catch{}function H(){return process.env.HERMES_HOME?i.resolve(process.env.HERMES_HOME):i.join(u(),".hermes")}function N(){return i.join(u(),".claude.json")}function F(e=process.cwd()){return i.join(e,".mcp.json")}function q(){return process.platform==="darwin"?i.join(u(),"Library","Application Support","Claude","claude_desktop_config.json"):i.join(u(),".config","Claude","claude_desktop_config.json")}function K(){return i.join(u(),".codex","config.toml")}function C(){return i.join(f(),"connectors")}function B(){return i.join(C(),"chatgpt-openapi.json")}function G(){return i.join(f(),"active-chain.json")}function y(e){let o=[i.join(l,"bin",e),i.join(l,"dist","bin",e),i.join(l,"..","bin",e)];return o.find(n=>d.existsSync(n))||o[0]}function V(e){return d.mkdirSync(e,{recursive:!0}),e}var j={homeDir:u,isPublicDesktop:v,oracleConfigDir:f,oracleExecEnvPath:I,oracleDeskJsonPath:R,oracleEnvFilePath:k,loadDeskRouting:p,hermesRoot:H,activeChainPath:G,claudeCodeUserConfigPath:N,claudeCodeProjectMcpPath:F,claudeDesktopConfigPath:q,codexConfigPath:K,chatgptConnectorDir:C,chatgptOpenApiPath:B,packageBin:y,ensureDir:V,PACKAGE_ROOT:l};import{execFile as J}from"node:child_process";import{existsSync as me,mkdirSync as he,readFileSync as W,realpathSync as ge,writeFileSync as ye}from"node:fs";import w from"node:path";import{promisify as Y}from"node:util";var Ae=Y(J);var _e=1440*60*1e3;function L(e,o){let n=t=>String(t).replace(/^v/,"").split("-")[0].split(".").map(r=>Number.parseInt(r,10)||0),s=n(e),c=n(o);for(let t=0;t<Math.max(s.length,c.length);t+=1){let r=s[t]??0,a=c[t]??0;if(r>a)return 1;if(r<a)return-1}return 0}function X(e){let o=e?.stateDir||w.join(process.env.HOME||".",".oracle");return w.join(o,"update-check.json")}function O(e){try{return JSON.parse(W(X(e),"utf8"))}catch{return null}}var Q="\u25C7 ORACLE // self-custody multichain agent control plane",Z=`START
2
+ import{realpathSync as T}from"node:fs";import{fileURLToPath as oe}from"node:url";import h from"node:fs";import g from"node:path";import{pathToFileURL as z}from"node:url";import d from"node:fs";import P from"node:os";import i from"node:path";import{fileURLToPath as $}from"node:url";var M=i.dirname($(import.meta.url)),l=i.resolve(M,"../..");function u(){return process.env.ORACLE_FAKE_HOME||P.homedir()}function v(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function m(){return v()?process.env.ORACLE_CONFIG_DIR||i.join(u(),".config","oracle"):i.join(u(),".config","oracle")}function I(){return i.join(m(),"exec.env")}function R(){return i.join(m(),"desk.json")}function k(){return i.join(m(),"env")}function p({force:e=!1}={}){if(p._done&&!e)return p._result||null;p._done=!0;let o={},n=(c,t)=>{if(t==null)return;let r=String(t).trim();r&&(process.env[c]!=null&&String(process.env[c]).trim()!==""||(process.env[c]=r,o[c]=r))};try{let c=k();if(d.existsSync(c))for(let t of d.readFileSync(c,"utf8").split(/\r?\n/)){let r=t.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*?)\s*$/);if(!r||r[2].startsWith("#"))continue;let a=r[2];(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),n(r[1],a)}}catch{}try{let c=R();if(d.existsSync(c)){let t=JSON.parse(d.readFileSync(c,"utf8"));t&&typeof t=="object"&&(n("ORACLE_DESK_URL",t.deskUrl||t.dataUrl||t.url),n("ORACLE_DATA_URL",t.dataUrl||t.deskUrl||t.url),n("ORACLE_API_URL",t.apiUrl||t.dataUrl||t.deskUrl),n("ORACLE_PUBLIC_URL",t.publicUrl||t.deskUrl||t.dataUrl),n("ORACLE_EXEC_URL",t.execUrl),n("MAD_DESK_URL",t.deskUrl||t.dataUrl))}}catch{}let s=process.env.ORACLE_DESK_URL||process.env.ORACLE_DATA_URL||"";return s&&(n("ORACLE_DESK_URL",s),n("ORACLE_DATA_URL",s),n("ORACLE_API_URL",s),n("ORACLE_PUBLIC_URL",s),n("MAD_DESK_URL",s)),p._result=Object.keys(o).length?o:null,p._result}try{p()}catch{}function H(){return process.env.HERMES_HOME?i.resolve(process.env.HERMES_HOME):i.join(u(),".hermes")}function N(){return i.join(u(),".claude.json")}function F(e=process.cwd()){return i.join(e,".mcp.json")}function q(){return process.platform==="darwin"?i.join(u(),"Library","Application Support","Claude","claude_desktop_config.json"):i.join(u(),".config","Claude","claude_desktop_config.json")}function K(){return i.join(u(),".codex","config.toml")}function C(){return i.join(m(),"connectors")}function B(){return i.join(C(),"chatgpt-openapi.json")}function G(){return i.join(m(),"active-chain.json")}function y(e){let o=[i.join(l,"bin",e),i.join(l,"dist","bin",e),i.join(l,"..","bin",e)];return o.find(n=>d.existsSync(n))||o[0]}function V(e){return d.mkdirSync(e,{recursive:!0}),e}var w={homeDir:u,isPublicDesktop:v,oracleConfigDir:m,oracleExecEnvPath:I,oracleDeskJsonPath:R,oracleEnvFilePath:k,loadDeskRouting:p,hermesRoot:H,activeChainPath:G,claudeCodeUserConfigPath:N,claudeCodeProjectMcpPath:F,claudeDesktopConfigPath:q,codexConfigPath:K,chatgptConnectorDir:C,chatgptOpenApiPath:B,packageBin:y,ensureDir:V,PACKAGE_ROOT:l};import{execFile as J}from"node:child_process";import{existsSync as fe,mkdirSync as he,readFileSync as W,realpathSync as ge,writeFileSync as ye}from"node:fs";import j from"node:path";import{promisify as Y}from"node:util";var Ae=Y(J);var _e=1440*60*1e3;function L(e,o){let n=t=>String(t).replace(/^v/,"").split("-")[0].split(".").map(r=>Number.parseInt(r,10)||0),s=n(e),c=n(o);for(let t=0;t<Math.max(s.length,c.length);t+=1){let r=s[t]??0,a=c[t]??0;if(r>a)return 1;if(r<a)return-1}return 0}function X(e){let o=e?.stateDir||j.join(process.env.HOME||".",".oracle");return j.join(o,"update-check.json")}function O(e){try{return JSON.parse(W(X(e),"utf8"))}catch{return null}}var Q="\u25C7 ORACLE // self-custody multichain agent control plane",Z=`START
3
3
  oracle open the native Oracle chat (TTY)
4
4
  oracle chat open chat explicitly
5
5
  oracle setup connect a model and optional messaging
@@ -19,6 +19,7 @@ PREPARE
19
19
  oracle swap unsigned route and wallet-signable calldata
20
20
  oracle prepare build an unsigned swap (alias of route prepare)
21
21
  oracle strategy draft|validate|backtest|optimize|evidence \xB7 shadow \xB7 prepare
22
+ oracle shadow record|mark|summary prepare and NO_TRADE outcomes
22
23
  oracle mev observe \xB7 status \xB7 control \xB7 operator (execute needs --execute)
23
24
  oracle snipe twitter CA watch \u2192 USD-book prepare (no broadcast)
24
25
 
@@ -48,15 +49,15 @@ BOUNDARY
48
49
  MEV observe is read-only. Flash-loan execute needs ORACLE_MEV_EXECUTE_ENABLED=1
49
50
  and literal --execute. There is no autonomous MEV loop.
50
51
  Use oracle <command> --help for command details.
51
- `;function U(){try{return JSON.parse(h.readFileSync(g.join(l,"package.json"),"utf8")).version||"0.0.0"}catch{return"0.0.0"}}function ee(){let e=g.join(l,"src","cli","commands");return h.existsSync(e)?e:g.join(l,"dist","cli","commands")}async function m(){let e=ee(),o=new Map;if(!h.existsSync(e))return o;let n=h.readdirSync(e).filter(s=>s.endsWith(".mjs")).sort();for(let s of n){let c=g.join(e,s);try{let r=(await import(z(c).href+`?t=${Date.now()}`)).default;if(!r||typeof r!="object"||typeof r.run!="function")continue;let a=r.name||s.replace(/\.mjs$/,""),A={...r,name:a,__file:c};o.set(a,A);for(let _ of Array.isArray(r.aliases)?r.aliases:[])o.set(_,{...A,name:_,aliasFor:a})}catch(t){process.env.ORACLE_CLI_DEBUG&&console.error(`oracle: failed loading command ${s}: ${t.message}`)}}return o}function te(e,o=O()){return!o?.latest||!e||L(o.latest,e)<=0?"":`
52
+ `;function U(){try{return JSON.parse(h.readFileSync(g.join(l,"package.json"),"utf8")).version||"0.0.0"}catch{return"0.0.0"}}function ee(){let e=g.join(l,"src","cli","commands");return h.existsSync(e)?e:g.join(l,"dist","cli","commands")}async function f(){let e=ee(),o=new Map;if(!h.existsSync(e))return o;let n=h.readdirSync(e).filter(s=>s.endsWith(".mjs")).sort();for(let s of n){let c=g.join(e,s);try{let r=(await import(z(c).href+`?t=${Date.now()}`)).default;if(!r||typeof r!="object"||typeof r.run!="function")continue;let a=r.name||s.replace(/\.mjs$/,""),A={...r,name:a,__file:c};o.set(a,A);for(let _ of Array.isArray(r.aliases)?r.aliases:[])o.set(_,{...A,name:_,aliasFor:a})}catch(t){process.env.ORACLE_CLI_DEBUG&&console.error(`oracle: failed loading command ${s}: ${t.message}`)}}return o}function te(e,o=O()){return!o?.latest||!e||L(o.latest,e)<=0?"":`
52
53
  Update available: ${e} \u2192 ${o.latest}. Run 'oracle update'.
53
- `}function E(e,o){let n=[];n.push(`${Q} (v${e})`),n.push(""),n.push(Z.trimEnd());let s=[];for(let c of o.values()){if(["help","version"].includes(c.name))continue;!new Set(["init","doctor","chat","model","auth","chain","setup","data","data-mcp","scan","route","prepare","swap","farm","follow","equities","strategy","mev","snipe","public","mcp","plugins","harness","clients","upgrade","bootstrap","eval","fees","sign","signer"]).has(c.name)&&c.summary&&s.push(` oracle ${c.name.padEnd(20)} ${c.summary}`)}return s.length&&(n.push(""),n.push("ADDITIONAL"),n.push(...s)),n.join(`
54
+ `}function E(e,o){let n=[];n.push(`${Q} (v${e})`),n.push(""),n.push(Z.trimEnd());let s=[];for(let c of o.values()){if(["help","version"].includes(c.name))continue;!new Set(["init","doctor","chat","model","auth","chain","setup","data","data-mcp","scan","route","prepare","swap","farm","follow","equities","strategy","shadow","mev","snipe","public","mcp","plugins","harness","clients","upgrade","bootstrap","eval","fees","sign","signer"]).has(c.name)&&c.summary&&s.push(` oracle ${c.name.padEnd(20)} ${c.summary}`)}return s.length&&(n.push(""),n.push("ADDITIONAL"),n.push(...s)),n.join(`
54
55
  `)+`
55
56
  `+te(e)}function S(e,o){let n=[...o.keys()].sort(),s=n.length?n.join(", "):"(none loaded yet)";return`oracle: unknown command '${e}'. Known: ${s}
56
57
  Try: oracle --help
57
- `}function x(e){return{argv:e,root:l,bin:y,paths:j}}async function D(e=[]){let o=U();if(e.includes("--version")||e.includes("-V"))return b();if(e[0]==="--help"||e[0]==="-h"){let r=await m();return process.stdout.write(E(o,r)),0}if(e.length===0){let r=await m();if(re(e)){let a=r.get("chat");if(a)return a.run(x([]))}return process.stdout.write(E(o,r)),0}if(ne(e[0])){let a=(await m()).get("chat");if(a)return a.run(x(e))}let n=e[0],s=e.slice(1);if(n==="version")return b();if(n==="help"){let r=await m();if(s[0]){let a=r.get(s[0]);return a?(process.stdout.write((a.usage||`oracle ${a.name}`)+`
58
+ `}function x(e){return{argv:e,root:l,bin:y,paths:w}}async function D(e=[]){let o=U();if(e.includes("--version")||e.includes("-V"))return b();if(e[0]==="--help"||e[0]==="-h"){let r=await f();return process.stdout.write(E(o,r)),0}if(e.length===0){let r=await f();if(re(e)){let a=r.get("chat");if(a)return a.run(x([]))}return process.stdout.write(E(o,r)),0}if(ne(e[0])){let a=(await f()).get("chat");if(a)return a.run(x(e))}let n=e[0],s=e.slice(1);if(n==="version")return b();if(n==="help"){let r=await f();if(s[0]){let a=r.get(s[0]);return a?(process.stdout.write((a.usage||`oracle ${a.name}`)+`
58
59
  `),a.summary&&process.stdout.write(a.summary+`
59
- `),0):(process.stderr.write(S(s[0],r)),1)}return process.stdout.write(E(o,r)),0}let c=await m(),t=c.get(n);if(t){if(s[0]==="--help"||s[0]==="-h")return process.stdout.write((t.usage||`oracle ${t.name}`)+`
60
+ `),0):(process.stderr.write(S(s[0],r)),1)}return process.stdout.write(E(o,r)),0}let c=await f(),t=c.get(n);if(t){if(s[0]==="--help"||s[0]==="-h")return process.stdout.write((t.usage||`oracle ${t.name}`)+`
60
61
  `),t.summary&&process.stdout.write(t.summary+`
61
62
  `),0;try{let r=await t.run(x(s));return typeof r=="number"?r:0}catch(r){return process.stderr.write(`oracle ${n}: ${r?.message||r}
62
63
  `),1}}return process.stderr.write(S(n,c)),1}async function b(){let e=U();return process.stdout.write(`oracle ${e}