anyray-connect 0.11.128 → 0.11.129
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.
- package/dist/index.js +53 -53
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ var hI="http://localhost:8787",Ba="anyray-placeholder",Ie=e=>{let t=e?.trim();re
|
|
|
4
4
|
`,{mode:384})}catch(a){throw await Tr(e,{recursive:!0,force:!0}).catch(()=>{}),a}return async()=>{try{JSON.parse(await Wa(t,"utf-8")).nonce===r&&await Tr(e,{recursive:!0,force:!0})}catch{}}}catch(a){if(a.code!=="EEXIST")throw a}if(!(await UI(e).catch(()=>!1)&&await Tr(e,{recursive:!0,force:!0}).then(()=>!0).catch(()=>!1))){if(Date.now()>=n)throw new Error("connect profile is busy; retry the command");await new Promise(a=>setTimeout(a,MI))}}},qy=async e=>{let t=Object.fromEntries(Object.entries(e).filter(([,o])=>o!==void 0)),n=await Eo(),r=`${n}.${process.pid}.${DI++}.tmp`;await Ki(r,`${JSON.stringify(t,null,2)}
|
|
5
5
|
`,{mode:384}),await hu(r,384);try{await pe(r,n)}catch(o){throw await Tr(r,{force:!0}).catch(()=>{}),o}},te=async e=>{let t=await zy();try{await qy(e)}finally{await t()}},Qy=async e=>{let t=await zy();try{let n=await P(),{next:r,result:o}=e(n);return r&&await qy(r),o}finally{await t()}},fu=["clientKey","clientKeyExpiresAt","enrolledCert","enrolledCertExpiry","enrolledCertLifetimeMs","enrolledTokenHash"],Zy="ssoLink",gu=async()=>{let e=await P();return fu.some(t=>e[t]!==void 0)?!0:await Me()!==void 0},ji=async()=>{let e=await P(),t=fu.some(a=>e[a]!==void 0),n=e[Zy]!==void 0,r=e.byoUpstream!==void 0,o=await Me()!==void 0;if(!t&&!n&&!r&&!o)return!1;if(t||n||r){let a={...e};for(let s of fu)delete a[s];delete a[Zy],delete a.byoUpstream,delete a.anyrayFleetManaged,await te(a)}if(await Ka(),await Me())throw new Error(`could not remove the dev key from ${Q()}`);return!0},eg=["fallback-bundle.enc","fallback-key","fallback-usage-queue.jsonl"],Vi=async()=>{let e=Q();for(let t of eg)await Tr(Cn(e,t),{force:!0}).catch(()=>{})},wu=async()=>{let e=Q(),t=[];for(let n of eg){let r=Cn(e,n);try{await PI(r),t.push(r)}catch{}}return t},Vn=async(e,t,n=!1)=>{let r=await P(),o=new Set(r.managedTools??[]),a=new Set(r.revertedTools??[]),s=r.offboardedAt;for(let h of e){let m=h.status==="configured"||h.status==="queued";!t&&m&&(o.add(h.id),a.delete(h.id),s=void 0),t&&(h.status==="reverted"||h.status==="queued")&&(o.delete(h.id),a.add(h.id))}n&&o.clear();let i=[...o].sort(),c=[...r.managedTools??[]].sort(),l=[...a].sort(),d=[...r.revertedTools??[]].sort();if(i.length===c.length&&i.every((h,m)=>h===c[m])&&r.revertedTools!=null&&l.length===d.length&&l.every((h,m)=>h===d[m])&&s===r.offboardedAt)return;let{offboardedAt:f,...p}=r;await te({...p,...s!==void 0?{offboardedAt:s}:{},managedTools:i,revertedTools:l})},Yi=async(e=new Date().toISOString())=>{await te({...await P(),offboardedAt:e})};var Io=e=>XI(e).replace(/\\/g,"/").toLowerCase(),ku=(e=process.platform)=>e==="win32"?"anyray-connect.exe":"anyray-connect",ja=e=>`${e}.source`,ag=e=>/(^|\/)_npx(\/|$)/.test(Io(e)),Cu=e=>/(^|\/)node_modules\/anyray-connect\/dist\/index\.js$/.test(Io(e)),vu=e=>{let t=Io(e),n=[ZI(),"/tmp","/private/tmp","/var/folders","/private/var/folders"].map(Io);return ag(t)||n.some(r=>t===r||t.startsWith(`${r}/`))},yt=()=>({execPath:process.execPath,scriptPath:process.argv[1]}),Va=e=>/[\\/](node|node\.exe)$/i.test(e),Yn=(e=yt())=>Va(e.execPath)&&e.scriptPath?e.scriptPath:e.execPath,ng=e=>{try{let t=rg(e);return t.isFile()?t.size:void 0}catch{return}},Su=e=>{let t=We(e);if(xo(t)==="versions")return t;let n=We(t);return xo(n)==="versions"?n:void 0},Xi=(e,t)=>t!==void 0&&(We(e)===t||We(We(e))===t),JI=e=>{let t=Su(e);if(!t)return;let n=Oe(We(t),"bin",ku());try{let r=Ga(n);return r===Ga(e)||Xi(r,Ga(t))?n:void 0}catch{return}},Oo=(e=Q(),t=process.platform)=>{let n=Oe(e,"bin",ku(t));try{let r=Ga(n),o=Ga(Oe(e,"versions"));if(Xi(r,o))return n;if(t==="win32"){let a=WI(ja(n),"utf8").trim();if(!/^[0-9A-Za-z.-]+$/.test(a))return;let s=ng(Oe(o,a,ku(t)))??ng(Oe(o,a));if(s!==void 0&&s===rg(n).size)return n}}catch{return}},Lr=(e=yt())=>{let t=Yn(e),n=Cu(t)||xu(t)?Oo():void 0;return JI(e.execPath)??n??t},sg=(e=yt())=>Lr(e)!==Yn(e),cn=(e,t=yt())=>{let n=Lr(t);return Va(t.execPath)&&t.scriptPath!==void 0&&n===Yn(t)?{command:t.execPath,args:[n,...e],entryPath:n}:{command:n,args:e,entryPath:n}},ig=(e=yt())=>{let t=Lr(e);return!Va(e.execPath)&&!vu(t)?We(t):Oe(Q(),"bin")},Zi=async e=>{try{return await KI(e),!0}catch{return!1}},zI=async e=>{let t=await jI(e),n=We(t),r=We(n),o=Oe(r,"package.json"),a=await Au(o,"utf8"),s=JSON.parse(a);if(typeof s.version!="string"||!/^[0-9A-Za-z][0-9A-Za-z.-]*$/.test(s.version))throw new Error("published package has no safe version");if(!await Zi(Oe(n,"index.js")))throw new Error("published package is missing dist/index.js");return{root:r,dist:n,packageJson:o,version:s.version}},qI=async(e,t)=>{let n=t;for(;;){let r=Oe(n,"node_modules",e);if(await Zi(Oe(r,"package.json")))return r;let o=We(n);if(o===n)return;n=o}},QI=async(e,t)=>{let n=new Set,r=[e];for(;r.length>0;){let o=r.shift(),a=JSON.parse(await Au(Oe(o,"package.json"),"utf8"));for(let s of Object.keys(a.dependencies??{})){if(n.has(s))continue;n.add(s);let i=await qI(s,o);if(!i)throw new Error(`runtime dependency "${s}" is not installed`);await og(i,Oe(t,s),{recursive:!0}),r.push(i)}}},eO=async(e=yt())=>{let t=Oo();if(t)return{command:t,args:[],entryPath:t};if(!Va(e.execPath)||!e.scriptPath)return{command:e.execPath,args:[],entryPath:e.execPath};let n=await zI(e.scriptPath);await kt();let r=Oe(Q(),"bin",`connect-runtime-${n.version}`),o=Oe(r,"dist","index.js");if(!await Zi(o)){let a=`${r}.stage-${process.pid}-${Date.now()}`;await bu(a,{recursive:!0,force:!0}),await tg(a,{recursive:!0,mode:448});try{await og(n.dist,Oe(a,"dist"),{recursive:!0}),await YI(Oe(a,"package.json"),await Au(n.packageJson),{mode:384}),await QI(n.root,Oe(a,"node_modules")),await tg(We(r),{recursive:!0,mode:448});try{await VI(a,r)}catch(s){if(!await Zi(o))throw s}}finally{await bu(a,{recursive:!0,force:!0})}}return{command:e.execPath,args:[o],entryPath:o}},Eu=/^connect-runtime-(?!.*\.stage-)[0-9A-Za-z][0-9A-Za-z.-]*$/,tO=e=>{let t=xo(We(We(e)));return Eu.test(t)?t:void 0},xu=(e,t=Q())=>{let n=We(We(e));return Io(We(n))===Io(Oe(t,"bin"))&&Eu.test(xo(n))&&xo(We(e))==="dist"&&xo(e)==="index.js"},Ji=async(e=yt())=>{let t=Oe(Q(),"bin"),n=tO(Yn(e)),r=[];for(let o of await GI(t).catch(()=>[])){if(!Eu.test(o)||o===n)continue;let a=Oe(t,o);await bu(a,{recursive:!0,force:!0}).then(()=>!0,()=>!1)&&r.push(a)}return r},cg=async(e,t=yt())=>{let n=Yn(t);if(!Va(t.execPath)||!ag(n)||Oo())return;let r=await eO(t),o=HI(r.command,[...r.args,...e],{stdio:"inherit",env:process.env});if(o.error)throw o.error;return o.status??1};var Iu=e=>/^[A-Za-z0-9_./:=-]+$/.test(e)?e:`"${e.replace(/"/g,'\\"')}"`,Ya=(e,t)=>[e,...t].map(Iu).join(" "),vn=(e,t={})=>({...t.matcher!==void 0?{matcher:t.matcher}:{},hooks:[{type:"command",command:e,...t.timeout!==void 0?{timeout:t.timeout}:{},...t.async!==void 0?{async:t.async}:{}}]}),Zn=(e,t)=>{if(e===null||typeof e!="object")return!1;let n=e.hooks;return Array.isArray(n)&&n.some(r=>r!==null&&typeof r=="object"&&typeof r.command=="string"&&r.command.includes(t))},zi=(e,t,n,r,o="append")=>{let a=e.hooks??{},i=(Array.isArray(a[t])?a[t]:[]).filter(c=>!Zn(c,n));a[t]=o==="prepend"?[r,...i]:[...i,r],e.hooks=a},Ro=(e,t,n)=>{let r=e.hooks;if(!r||!Array.isArray(r[t]))return!1;let o=r[t],a=o.filter(s=>!Zn(s,n));return a.length===o.length?!1:(a.length?r[t]=a:delete r[t],Object.keys(r).length===0&&delete e.hooks,!0)},Ou=e=>{let t=e.hooks;if(!t)return!1;let n=!1;for(let[r,o]of Object.entries(t)){if(!Array.isArray(o))continue;let a=o.filter(s=>!Zn(s,"__anyray-"));a.length!==o.length&&(n=!0,a.length?t[r]=a:delete t[r])}return n&&Object.keys(t).length===0&&delete e.hooks,n};var Ze="__anyray-hook",lg="__anyray-codex-hook",Xn="__anyray-prompt-hook",dg="__anyray-shell-pretool",Ru="__anyray-shell-run",ug="__anyray-read-pretool",Jn="__anyray-refresh",Za=(e,t=[])=>{let{command:n,args:r}=cn([e,...t]);return{command:n,args:r}},Rt=(e,t=[])=>{let n=Za(e,t);return[n.command,...n.args].map(Iu).join(" ")},qi=(e,t,n=[])=>typeof e=="string"&&e.trim()===Rt(t,n),pg=()=>Rt("print-key"),Re=()=>Lr(),Ke=vu,ce=()=>!Ke(Re()),Dr=async()=>{if(!ce())return!1;try{return await nO(Re()),!0}catch{return!1}},zn="__anyray-mcp-server",Ge=e=>Za(zn,[e]),rO=(e,t)=>Array.isArray(e)&&e.length===t.length&&e.every((n,r)=>n===t[r]),Qi=(e,t)=>{if(!e||typeof e!="object"||Array.isArray(e))return!1;let n=e,r=Ge(t);return n.command===r.command&&rO(n.args,r.args)},Vt=(e,t)=>{if(!e||typeof e!="object"||Array.isArray(e))return!1;let n=e;if(typeof n.command!="string"||!Array.isArray(n.args)||!n.args.every(o=>typeof o=="string"))return!1;let r=n.args;return(r.length===2||r.length===3)&&r.at(-2)===zn&&r.at(-1)===t};var q=(e,t)=>e.authMode==="subscription"?!0:e.authMode==="placeholder"?!1:e.seat?.[t]??!1,le=e=>{let t=Object.entries(e).filter(([,n])=>n);if(t.length!==0)return JSON.stringify(Object.fromEntries(t))};var Nr=["ANTHROPIC_BASE_URL","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_CUSTOM_HEADERS","ENABLE_TOOL_SEARCH","_CLAUDE_CODE_ASSUME_FIRST_PARTY_BASE_URL"],fg=["ENABLE_TOOL_SEARCH","_CLAUDE_CODE_ASSUME_FIRST_PARTY_BASE_URL"],ec=[...Nr,"CLAUDE_CODE_MAX_CONTEXT_TOKENS","CLAUDE_CODE_USE_BEDROCK","CLAUDE_CODE_USE_VERTEX"],oO=(e,t,n,r)=>{let o=[];return(t||r)&&(o.push("x-anyray-provider: anthropic"),o.push("x-anyray-auth-mode: passthrough"),r&&o.push(`x-anyray-custom-host: ${r}`),n&&o.push(`x-anyray-api-key: ${n}`)),e&&o.push(`x-anyray-metadata: ${e}`),o.join(`
|
|
6
6
|
`)},ln=(e,t={})=>{let n=e.byoUpstream,r=!n&&q(e,"anthropic"),o=le({...e.metadata,tool:e.metadata.tool??"claude-code"}),a=t.includeClientKey!==!1&&!((r||n)&&e.viaLocalProxy),s=t.includeAuthToken!==!1,{contextWindowTokens:i}=t,c=oO(o,r,a?e.clientKey:void 0,n?.url);return{env:{ANTHROPIC_BASE_URL:e.anthropicBaseUrl,...c?{ANTHROPIC_CUSTOM_HEADERS:c}:{},...n&&s?{ANTHROPIC_AUTH_TOKEN:n.key}:{},...r||n||!s?{}:{ANTHROPIC_AUTH_TOKEN:e.clientKey??e.placeholderKey},...n?{}:{ENABLE_TOOL_SEARCH:"true"},...n?{}:{_CLAUDE_CODE_ASSUME_FIRST_PARTY_BASE_URL:"1"},...i!==void 0?{CLAUDE_CODE_MAX_CONTEXT_TOKENS:String(i)}:{}},subscription:r,byoUpstream:!!n,meta:o,headers:c}};import{z as _u}from"zod";var aO=5e3,sO=1e3,iO=1e8,cO=_u.object({modelContext:_u.object({contextTokens:_u.number().int().min(sO).max(iO)}).optional()}),hg=e=>{let t=e.model;if(typeof t!="string")return;let n=t.trim();return n.length>0?n:void 0},mg=async(e,t,n,r={})=>{if(!t||!n)return;let o=r.timeoutMs??aO,a=new AbortController,s=setTimeout(()=>a.abort(),o);try{let i=`${e}/connect/policy?model=${encodeURIComponent(n)}`,c=await fetch(i,{method:"GET",headers:{"x-anyray-api-key":t},signal:a.signal});if(!c.ok)return;let l=cO.safeParse(await c.json());return l.success?l.data.modelContext?.contextTokens:void 0}catch{return}finally{clearTimeout(s)}};var lO=1e6,Xa="[1m]",dO=e=>{let t=e.trim().toLowerCase();return!(t.startsWith("claude-")||t.split(/[/.]/).some(r=>r.startsWith("claude-")))},yg=(e,t)=>!e||t===void 0?{}:dO(e)?{envTokens:t}:t<lO?{}:e.toLowerCase().endsWith(Xa)?{}:{model:`${e}${Xa}`},gg=(e,t)=>{if(!(!e||!e.toLowerCase().endsWith(Xa))&&typeof t=="string"&&!t.trim().toLowerCase().endsWith(Xa))return e.slice(0,-Xa.length)};import{platform as uO}from"node:os";var _t=(e=uO())=>{switch(e){case"darwin":return"/Library/Application Support/ClaudeCode/managed-settings.json";case"win32":return"C:\\Program Files\\ClaudeCode\\managed-settings.json";default:return"/etc/claude-code/managed-settings.json"}};var Sn=[{name:"CLAUDE_CODE_USE_BEDROCK",cloud:"AWS Bedrock"},{name:"CLAUDE_CODE_USE_VERTEX",cloud:"Google Vertex AI"}],tc=e=>typeof e=="string"&&e.trim()!=="",pO=(e,t)=>typeof e[t]=="string"&&!tc(e[t]),wg=e=>{let t=e.env;return t&&typeof t=="object"&&!Array.isArray(t)?t:{}},fO=()=>M(_t()).catch(()=>({})),bg=async(e={})=>{let t=e.env??process.env,n=wg(e.userSettings??{}),r=wg(await(e.readManaged??fO)().catch(()=>({}))),o=[];for(let{name:a,cloud:s}of Sn)tc(r[a])?o.push({name:a,cloud:s,kind:"managed",source:`managed settings (${_t()})`,repairable:!1}):tc(n[a])?o.push({name:a,cloud:s,kind:"userSettings",source:"~/.claude/settings.json env block",repairable:!0}):!pO(n,a)&&tc(t[a])&&o.push({name:a,cloud:s,kind:"shell",source:"shell environment",repairable:!0});return o},Pu=e=>`${e.name} is set (${e.source}) \u2014 Claude Code sends requests straight to ${e.cloud} and ignores the gateway routing written here, so none of its traffic reaches Anyray until that setting is removed`,Tu=e=>"Fix: remove the setting where it is set"+(e.some(t=>t.kind==="managed")?" (the managed settings file is IT-owned \u2014 ask your admin)":"")+", then restart Claude Code. The gateway can serve Bedrock/Vertex itself once its provider is configured \u2014 see the Bedrock page in the Anyray docs.",kg=e=>`Disabled direct ${e.cloud} mode: ${e.name} was set (${e.source}), which would bypass the gateway route entirely \u2014 pinned it empty in settings.json (the env block outranks shell exports, and '' is Claude Code's documented unset). Delete the original setting to drop the pin.`;var hO=Sn.map(e=>e.name),mO=ec.filter(e=>!hO.includes(e)),Ag=e=>typeof e=="string"&&e.trim()!=="",Cg=e=>{let t=e.env;return t&&typeof t=="object"&&!Array.isArray(t)?t:{}},yO=(e,t,n)=>{if(typeof e!="string"||typeof t!="string")return!1;let r=o=>n?o.trim().replace(/\/+$/,""):o.trim();return r(e)===r(t)},gO=e=>{if(typeof e=="string")try{return new URL(e.trim()).origin}catch{return}},Lu=()=>M(_t()).catch(()=>({})),vg=Lu,wO=e=>{let t=e.hooks;if(!t||typeof t!="object"||Array.isArray(t))return!1;let n=t.PostToolUse;return Array.isArray(n)&&n.some(r=>Zn(r,Ze))},Sg=async(e={})=>{let t=await(e.readManaged??vg)().catch(()=>({}));return t.disableAllHooks===!0?{state:"disabled"}:t.allowManagedHooksOnly===!0&&!wO(t)?{state:"restricted_dropping_ours"}:{state:"fine"}},nc=e=>e.state==="disabled"?`disableAllHooks is true in managed settings (${_t()}) \u2014 Claude Code skips every hook and the status line, including Anyray's savings hook`:e.state==="restricted_dropping_ours"?`allowManagedHooksOnly is true in managed settings (${_t()}), but that file does not carry the Anyray PostToolUse hook \u2014 Claude Code silently drops the user-scope hook Connect installed`:"Claude Code managed hook policy allows the Anyray hook lane",rc=e=>e.state==="disabled"?"Fix: ask the MDM owner to drop `disableAllHooks`, then restart Claude Code. Connect never overrides machine policy.":e.state==="restricted_dropping_ours"?"Fix: ask the MDM owner to drop `allowManagedHooksOnly`, or add the Anyray hooks to the managed file. `anyray-connect managed --print --sso <link> --bin <path>` emits the credential-free block; then restart Claude Code.":"No action required.",Eg=async(e={})=>{let t=Cg(e.userSettings??{}),n=Cg(await(e.readManaged??vg)().catch(()=>({}))),r=[];for(let o of mO){if(!Ag(n[o])||!Ag(t[o]))continue;let a=o==="ANTHROPIC_BASE_URL";if(yO(n[o],t[o],a))continue;let s=a?gO(n[o]):void 0;r.push({name:o,source:`managed settings (${_t()})`,routing:a,...s?{managedOrigin:s}:{}})}return r},xg=e=>e.routing?`${e.name} is set to a different value (${e.source}), which outranks the routing written in settings.json \u2014 Claude Code sends its traffic to ${e.managedOrigin??"that endpoint"} instead, so none of it reaches Anyray until the managed value changes`:`${e.name} is set to a different value (${e.source}), which outranks the value written in settings.json \u2014 Claude Code uses the managed one, so the behavior this key controls is not the one connect configured`,Ig=e=>"Fix: the managed settings file is IT-owned \u2014 ask your admin to "+(e.some(t=>t.routing)?"point it at the Anyray gateway (`anyray-connect managed --print` emits the block to deploy) or drop the key so per-user setup governs":"drop the key so per-user setup governs")+", then restart Claude Code.";import{homedir as bO}from"node:os";import{join as kO}from"node:path";import{readFile as AO}from"node:fs/promises";var rt=e=>!!e.keyRefreshEnabled;var CO=400,Og=async()=>{try{let e=kO(bO(),".claude","settings.json"),n=JSON.parse(await AO(e,"utf-8"))?.env,r=n?.ANTHROPIC_BASE_URL;if(!r)return null;let o=new URL(r).origin,a=n?.ANTHROPIC_CUSTOM_HEADERS??"",s=l=>{for(let d of a.split(`
|
|
7
|
-
`)){let u=d.indexOf(":");if(u>0&&d.slice(0,u).trim().toLowerCase()===l)return d.slice(u+1).trim()}},i=s("x-anyray-api-key"),c=n?.ANTHROPIC_AUTH_TOKEN;return{origin:o,metadata:s("x-anyray-metadata"),apiKey:i||(c?.startsWith("ark_")?c:void 0)}}catch{return null}},Rg=async()=>{try{let e=await P();return e.gateway?{origin:new URL(e.gateway).origin,metadata:le({user:e.name,team:e.team}),apiKey:e.clientKey}:null}catch{return null}},ot=async(e="auto")=>e==="profile"?Rg():e==="claude"?Og():await Og()??await Rg(),oc=async(e={})=>{let t=e.readTarget??ot,n=e.loadProfile??P,r;try{r=await n()}catch{return"unreadable"}if(!r.gateway)return"unreadable";let o;try{o=await t("claude")}catch{return"unreadable"}if(!o)return"missing";let a=new Set;try{a.add(new URL(r.gateway).origin)}catch{return"unreadable"}return rt(r)&&r.fallbackPort&&a.add(`http://${mt}:${r.fallbackPort}`),a.has(o.origin)?"owned":"foreign"},Yt=e=>{let t={"content-type":"application/json"};return e.metadata&&(t["x-anyray-metadata"]=e.metadata),e.apiKey&&(t["x-anyray-api-key"]=e.apiKey),t},ac=async(e,t,n,r)=>{if(!e)return;let o=new AbortController,a=setTimeout(()=>o.abort(),CO);try{await fetch(`${e.origin}/connect/hook-savings`,{method:"POST",headers:Yt(e),body:JSON.stringify({source:t,...r?{tool:r}:{},...n}),signal:o.signal})}catch{}finally{clearTimeout(a)}};var En=()=>ic(sc(),".claude","settings.json"),Ja=()=>ic(sc(),".claude.json"),vO=ec,qn="anyray",SO=()=>({type:"stdio",...Ge("claude"),alwaysLoad:!0}),$r=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),EO=e=>{if("mcpServers"in e&&!$r(e.mcpServers))return"conflict";let t=$r(e.mcpServers)?{...e.mcpServers}:{},n=t[qn];return n!==void 0&&!Vt(n,"claude")?"conflict":(t[qn]=SO(),e.mcpServers=t,"installed")},_g=e=>{let t=e.mcpServers;return!t||!(qn in t)||!Vt(t[qn],"claude")?!1:(delete t[qn],Object.keys(t).length===0&&delete e.mcpServers,!0)},xO=e=>{zi(e,"PostToolUse",Ze,vn(Rt(Ze),{matcher:"*"})),zi(e,"UserPromptSubmit",Xn,vn(Rt(Xn)))},IO=e=>{zi(e,"SessionStart",Jn,vn(Rt(Jn),{async:!0}))},Lg=e=>Ro(e,"SessionStart",Jn),Pg=e=>{let t=Ro(e,"PostToolUse",Ze),n=Ro(e,"UserPromptSubmit",Xn),r=Lg(e);return t||n||r},OO="print-key",RO=e=>e.includes("anyray-connect")||e.includes("connect-runtime")||e.includes(Re()),Mr=e=>{let t=e.apiKeyHelper;if(typeof t!="string")return!1;let n=t.trim().split(/\s+/);return n[n.length-1]===OO&&RO(t)},_O=async(e,t)=>{let n=(await Pr(e)).env,r=n&&typeof n=="object"&&!Array.isArray(n)?n:{},o=[];for(let a of vO){let s=r[a];typeof s=="string"?(t[a]=s,o.push(a)):delete t[a]}return o},PO=e=>typeof e.apiKeyHelper=="string"&&!Mr(e),Dg=async e=>{let t=await Lu(),n=async()=>t,[r,o,a]=await Promise.all([bg({userSettings:e,readManaged:n}),Eg({userSettings:e,readManaged:n}).catch(()=>[]),Sg({readManaged:n})]);return{directOverrides:r,managedOverrides:o,hookPolicy:a}},Tg=async e=>{let{directOverrides:t,managedOverrides:n,hookPolicy:r}=await Dg(e),o=Tu(t),a=Ig(n);return{routingOverrides:[...t.map(i=>({problem:Pu(i),fix:i.repairable?"Fix: run `anyray-connect doctor --repair` (or re-run `anyray-connect`) \u2014 apply disables this switch by pinning it empty in settings.json.":o,repairable:i.repairable})),...n.map(i=>({problem:xg(i),fix:a,repairable:!1,bypass:i.routing}))],claudeCodeHookPolicy:r.state}},Qn={id:"claude-code",title:"Claude Code",automatic:!0,async detect(){let e=ic(sc(),".claude"),t=await O(e);return{installed:t,detail:t?En():"no ~/.claude directory"}},async apply(e,t){let n=En(),r=await M(n),o=hg(r),a=await mg(e.origin,e.clientKey,o),s=yg(o,a),{env:i,subscription:c,byoUpstream:l,meta:d,headers:u}=ln(e,{contextWindowTokens:s.envTokens}),{directOverrides:f,hookPolicy:p}=await Dg(r),h=f.filter(I=>!I.repairable),m=f.filter(I=>I.repairable),w=[...h.map(I=>`WARNING: ${Pu(I)}.`),...h.length?[Tu(h)]:[],...p.state==="fine"?[]:[`WARNING: ${nc(p)}.`,rc(p)],...m.map(I=>kg(I)),`${n} \u2192 env.ANTHROPIC_BASE_URL = ${e.anthropicBaseUrl}`,l?`BYO-upstream mode: your personal upstream key passes through the gateway to ${e.byoUpstream.url} (never the org key).${e.clientKey?" Your personal gateway key rides x-anyray-api-key.":""}`:c?`Subscription mode: Claude Code keeps your seat sign-in; its OAuth token passes through the gateway (never stored).${e.clientKey?" Your personal gateway key rides x-anyray-api-key.":""}`:e.clientKey?"Auth: personal gateway key (not shown here; see below for where it lives)":"Auth: placeholder token (gateway swaps in the server-held key)",`Attribution: ${d??"(none)"}`,...l?[]:["Restored on-demand MCP tool loading (env.ENABLE_TOOL_SEARCH) that Claude Code otherwise disables behind a non-first-party gateway. Deferred servers stay out of context until used; the first-party AnyRay retrieval server stays always loaded so capability is visible per request."],...s.envTokens!==void 0?[`Context window: env.CLAUDE_CODE_MAX_CONTEXT_TOKENS = ${s.envTokens} \u2014 your model's real window, so Claude Code stops budgeting the 200k it assumes behind any custom base URL.`]:[],...s.model!==void 0?[`Context window: model = ${s.model} \u2014 same model, its long-context variant. Claude Code ignores CLAUDE_CODE_MAX_CONTEXT_TOKENS for claude-* ids, so the [1m] alias is what actually gets you your ${a} window back instead of the 200k it assumes behind any custom base URL. A --model flag on your launch command, or picking a model in-app, overrides this \u2014 add [1m] there too (quote it in zsh).`]:[],"Claude Code settings.json routing covers the CLI and VS Code extension. Claude Desktop is separate: its verified macOS automatic setup supports either the Claude Code subscription-backed Gateway lane or API billing; other Desktop lanes fail closed or use the documented API setup.","Restart Claude Code (or open a new session) to pick up the change."];if(t.dryRun)return{status:"configured",messages:w};s.model!==void 0&&(r.model=s.model);let g=r.env??{};r.env={...g,...i};let y=r.env;for(let{name:I}of Sn)m.some(R=>R.name===I)?y[I]="":y[I]===""&&(process.env[I]??"").trim()===""&&delete y[I];if(u||delete y.ANTHROPIC_CUSTOM_HEADERS,c&&(g.ANTHROPIC_AUTH_TOKEN&&w.push("Removed env.ANTHROPIC_AUTH_TOKEN \u2014 it would override your subscription sign-in."),delete y.ANTHROPIC_AUTH_TOKEN),l)for(let I of fg)delete y[I];let b=!!e.clientKey,C=ce(),S=PO(r);!c&&!l&&b&&C&&!S?(r.apiKeyHelper=pg(),delete y.ANTHROPIC_AUTH_TOKEN,w.push("Installed an apiKeyHelper that reprints a fresh gateway key on demand \u2014 Claude Code refreshes it at startup and on any 401, so an idle session no longer 401s (no re-enrollment).")):Mr(r)&&delete r.apiKeyHelper,S&&!c&&!l&&b&&C&&w.push("Kept your existing apiKeyHelper; your gateway key stays in ANTHROPIC_AUTH_TOKEN (Anyray auto-refresh via the helper is off)."),(c||l)&&b&&C?(IO(r),w.push("Installed a SessionStart hook that refreshes your gateway key each session, so an idle subscription session no longer needs re-enrollment.")):Lg(r),ce()?(xO(r),w.push("Installed a PostToolUse hook (trims oversized tool outputs, cache-safe) and a UserPromptSubmit hook (beacons oversized pasted-data prompts) \u2014 both content-free.")):(Pg(r),w.push(`Skipped the Anyray hooks \u2014 anyray-connect is running from a temporary path (${Re()}). Re-run via the installer (it persists the binary under ~/.anyray/bin) or a global install to enable cache-safe trimming and paste-savings beacons.`)),await Z(n,r);let x=[n],A=Ja();try{let I=await M(A),R=!1;ce()?EO(I)==="conflict"?w.push(`MCP name conflict in ${A}: mcpServers.${qn} is not owned by Anyray Connect, so it was left untouched.`):(R=!0,w.push("Registered the Anyray retrieval MCP server (anyray_retrieve) for explicit recovery of stashed context \u2014 always loaded so retrieval capability is visible on every request.")):R=_g(I),R&&(await Z(A,I),x.push(A))}catch(I){w.push(`Could not register the Anyray MCP server in ${A} (${I instanceof Error?I.message:String(I)}); retrieval via anyray_retrieve is unavailable until this is fixed.`)}return{status:"configured",messages:w,changedFiles:x}},skillsDir(){return ic(sc(),".claude","skills")},async watchPaths(){return[En(),Ja()]},async pointsAt(e){let t=En();if(!await O(t))return!1;try{let o=(await M(t)).env?.ANTHROPIC_BASE_URL;return typeof o=="string"&&o.replace(/\/+$/,"")===e}catch{return!1}},async runtimeDiagnostics(){let e=await M(En()).catch(()=>({}));return Tg(e)},async routingOverrides(){let e=await M(En()).catch(()=>({}));return(await Tg(e)).routingOverrides},async mcpStatus(){let e=Ja();if(!await O(e))return{registered:!1,command:null};try{let r=(await M(e)).mcpServers?.[qn];return!r||!Vt(r,"claude")?{registered:!1,command:null}:{registered:!0,command:typeof r.command=="string"?r.command:null}}catch{return{registered:!1,command:null}}},async integrationStatus(){let e,t=!0,n=En();if(!await O(n))e="missing";else try{let s=await M(n);if(s.hooks===void 0)e="missing";else if(!$r(s.hooks))e="unreadable";else{let i=s.hooks.PostToolUse;e=i===void 0?"missing":Array.isArray(i)?i.some(c=>Zn(c,Ze))?"owned":"missing":"unreadable",e==="owned"&&Array.isArray(i)&&(t=i.some(c=>Zn(c,Ze)&&$r(c)&&Array.isArray(c.hooks)&&c.hooks.some(l=>$r(l)&&qi(l.command,Ze))))}}catch{e="unreadable"}let r,o=!0,a=Ja();if(!await O(a))r="missing";else try{let s=await M(a);if(s.mcpServers===void 0)r="missing";else if(!$r(s.mcpServers))r="unreadable";else{let i=s.mcpServers[qn];r=i===void 0?"missing":Vt(i,"claude")?"owned":"foreign",r==="owned"&&(o=Qi(i,"claude"))}}catch{r="unreadable"}return{hook_registration:e,mcp_registration:r,hook_binary:t&&o&&await Dr()?"owned":"missing",beacon_target:await oc().catch(()=>"unreadable")}},async inferenceAuthLanes(){try{let e=await M(En()),t=$r(e.env)?e.env:{},n=typeof t.ANTHROPIC_CUSTOM_HEADERS=="string"?t.ANTHROPIC_CUSTOM_HEADERS:"";if(/^x-anyray-custom-host:/m.test(n))return["byo"];if(/^x-anyray-auth-mode:\s*passthrough$/m.test(n))return["subscription"];if(typeof t.ANTHROPIC_AUTH_TOKEN=="string"||typeof e.apiKeyHelper=="string")return["api_key"]}catch{}return["unknown"]},async revert(e){let t=En();if(!await O(t))return{status:"not-found",messages:["nothing to revert"]};if(e.dryRun)return{status:"reverted",messages:[`would remove Anyray keys from ${t}`]};let n=await M(t),r=n.env,o=Pg(n),a=Mr(n);a&&delete n.apiKeyHelper;let s=r?await _O(t,r):[],i=gg(typeof n.model=="string"?n.model:void 0,(await Pr(t)).model);i!==void 0&&(n.model=i),r&&Object.keys(r).length===0&&delete n.env,(r||o||a||i!==void 0)&&await Z(t,n,{backup:!1});let c=[`removed Anyray keys from ${t}`];i!==void 0&&c.push(`Put model back to ${i} \u2014 dropped the [1m] alias Anyray added for your context window.`),o&&c.push("Removed the Anyray PostToolUse, UserPromptSubmit, and SessionStart hooks."),a&&c.push("Removed the Anyray apiKeyHelper."),s.length&&c.push(`Put back the ${s.join(" and ")} you had set before Anyray.`);let l=Ja();try{let d=await M(l);_g(d)&&(await Z(l,d,{backup:!1}),c.push("Removed the Anyray retrieval MCP server (anyray_retrieve)."))}catch{}return await oe(t),{status:"reverted",messages:c,changedFiles:[t]}}};var ke="0.11.128";var dn=e=>{let{command:t,args:n}=cn([e]);return{command:t,args:n}},er=()=>Lr();import{homedir as Ng,userInfo as TO}from"node:os";var za=()=>{try{return Ng()!==TO().homedir}catch{return!1}},_o=e=>[`Skipped ${e} \u2014 HOME (${Ng()}) is not this account's home directory.`,"The OS registers a per-user service against the account, not against HOME, so","one installed from here would point at a path the real login session cannot use."];var gt=(e=process.env)=>e.CODESPACES==="true"||e.CODESPACE_NAME?"codespaces":e.REMOTE_CONTAINERS==="true"||e.REMOTE_CONTAINERS_IPC||e.DEVCONTAINER?"devcontainer":e.SSH_CONNECTION||e.SSH_TTY?"ssh":null,qa=(e=process.env)=>gt(e)!==null,At=e=>e==="codespaces"||e==="devcontainer",tr=e=>{switch(e){case"codespaces":return"a GitHub Codespace";case"devcontainer":return"a dev container";case"ssh":return"an SSH session"}};var Mu="__anyray-fallback-proxy",ts="ai.anyray.connect.fallback",nr="anyray-fallback",Ug=ts,Ce=8785,ns=60,Fu="x-anyray-local",Bu=()=>dn(Mu),$g=er,lc=async(e=Ce)=>{let t=n=>new Promise(r=>{let o=NO();o.once("error",()=>r(!1)),o.listen(n,"127.0.0.1",()=>o.close(()=>r(!0)))});for(let n=e;n<e+20;n++)if(await t(n))return n;return e},Ae=async(e,t=1500)=>{let n=new AbortController,r=setTimeout(()=>n.abort(),t);try{let o=await fetch(`http://127.0.0.1:${e}/__anyray/health`,{signal:n.signal});return o.ok?await o.json():null}catch{return null}finally{clearTimeout(r)}},Do=()=>Lo(es(),"Library","LaunchAgents",`${Ug}.plist`),rs=()=>Lo(es(),".anyray","logs"),Qa=()=>Lo(rs(),"connect-daemon.log"),Hg=async(e,t=1048576)=>{await Fg(e).then(r=>r.size,()=>0)>t&&await DO(e).catch(()=>{})},No=()=>Lo(es(),".config","systemd","user",`${nr}.service`),Du=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),os=(e=Bu())=>{let{command:t,args:n}=e,r=[t,...n].map(o=>` <string>${Du(o)}</string>`).join(`
|
|
7
|
+
`)){let u=d.indexOf(":");if(u>0&&d.slice(0,u).trim().toLowerCase()===l)return d.slice(u+1).trim()}},i=s("x-anyray-api-key"),c=n?.ANTHROPIC_AUTH_TOKEN;return{origin:o,metadata:s("x-anyray-metadata"),apiKey:i||(c?.startsWith("ark_")?c:void 0)}}catch{return null}},Rg=async()=>{try{let e=await P();return e.gateway?{origin:new URL(e.gateway).origin,metadata:le({user:e.name,team:e.team}),apiKey:e.clientKey}:null}catch{return null}},ot=async(e="auto")=>e==="profile"?Rg():e==="claude"?Og():await Og()??await Rg(),oc=async(e={})=>{let t=e.readTarget??ot,n=e.loadProfile??P,r;try{r=await n()}catch{return"unreadable"}if(!r.gateway)return"unreadable";let o;try{o=await t("claude")}catch{return"unreadable"}if(!o)return"missing";let a=new Set;try{a.add(new URL(r.gateway).origin)}catch{return"unreadable"}return rt(r)&&r.fallbackPort&&a.add(`http://${mt}:${r.fallbackPort}`),a.has(o.origin)?"owned":"foreign"},Yt=e=>{let t={"content-type":"application/json"};return e.metadata&&(t["x-anyray-metadata"]=e.metadata),e.apiKey&&(t["x-anyray-api-key"]=e.apiKey),t},ac=async(e,t,n,r)=>{if(!e)return;let o=new AbortController,a=setTimeout(()=>o.abort(),CO);try{await fetch(`${e.origin}/connect/hook-savings`,{method:"POST",headers:Yt(e),body:JSON.stringify({source:t,...r?{tool:r}:{},...n}),signal:o.signal})}catch{}finally{clearTimeout(a)}};var En=()=>ic(sc(),".claude","settings.json"),Ja=()=>ic(sc(),".claude.json"),vO=ec,qn="anyray",SO=()=>({type:"stdio",...Ge("claude"),alwaysLoad:!0}),$r=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),EO=e=>{if("mcpServers"in e&&!$r(e.mcpServers))return"conflict";let t=$r(e.mcpServers)?{...e.mcpServers}:{},n=t[qn];return n!==void 0&&!Vt(n,"claude")?"conflict":(t[qn]=SO(),e.mcpServers=t,"installed")},_g=e=>{let t=e.mcpServers;return!t||!(qn in t)||!Vt(t[qn],"claude")?!1:(delete t[qn],Object.keys(t).length===0&&delete e.mcpServers,!0)},xO=e=>{zi(e,"PostToolUse",Ze,vn(Rt(Ze),{matcher:"*"})),zi(e,"UserPromptSubmit",Xn,vn(Rt(Xn)))},IO=e=>{zi(e,"SessionStart",Jn,vn(Rt(Jn),{async:!0}))},Lg=e=>Ro(e,"SessionStart",Jn),Pg=e=>{let t=Ro(e,"PostToolUse",Ze),n=Ro(e,"UserPromptSubmit",Xn),r=Lg(e);return t||n||r},OO="print-key",RO=e=>e.includes("anyray-connect")||e.includes("connect-runtime")||e.includes(Re()),Mr=e=>{let t=e.apiKeyHelper;if(typeof t!="string")return!1;let n=t.trim().split(/\s+/);return n[n.length-1]===OO&&RO(t)},_O=async(e,t)=>{let n=(await Pr(e)).env,r=n&&typeof n=="object"&&!Array.isArray(n)?n:{},o=[];for(let a of vO){let s=r[a];typeof s=="string"?(t[a]=s,o.push(a)):delete t[a]}return o},PO=e=>typeof e.apiKeyHelper=="string"&&!Mr(e),Dg=async e=>{let t=await Lu(),n=async()=>t,[r,o,a]=await Promise.all([bg({userSettings:e,readManaged:n}),Eg({userSettings:e,readManaged:n}).catch(()=>[]),Sg({readManaged:n})]);return{directOverrides:r,managedOverrides:o,hookPolicy:a}},Tg=async e=>{let{directOverrides:t,managedOverrides:n,hookPolicy:r}=await Dg(e),o=Tu(t),a=Ig(n);return{routingOverrides:[...t.map(i=>({problem:Pu(i),fix:i.repairable?"Fix: run `anyray-connect doctor --repair` (or re-run `anyray-connect`) \u2014 apply disables this switch by pinning it empty in settings.json.":o,repairable:i.repairable})),...n.map(i=>({problem:xg(i),fix:a,repairable:!1,bypass:i.routing}))],claudeCodeHookPolicy:r.state}},Qn={id:"claude-code",title:"Claude Code",automatic:!0,async detect(){let e=ic(sc(),".claude"),t=await O(e);return{installed:t,detail:t?En():"no ~/.claude directory"}},async apply(e,t){let n=En(),r=await M(n),o=hg(r),a=await mg(e.origin,e.clientKey,o),s=yg(o,a),{env:i,subscription:c,byoUpstream:l,meta:d,headers:u}=ln(e,{contextWindowTokens:s.envTokens}),{directOverrides:f,hookPolicy:p}=await Dg(r),h=f.filter(I=>!I.repairable),m=f.filter(I=>I.repairable),w=[...h.map(I=>`WARNING: ${Pu(I)}.`),...h.length?[Tu(h)]:[],...p.state==="fine"?[]:[`WARNING: ${nc(p)}.`,rc(p)],...m.map(I=>kg(I)),`${n} \u2192 env.ANTHROPIC_BASE_URL = ${e.anthropicBaseUrl}`,l?`BYO-upstream mode: your personal upstream key passes through the gateway to ${e.byoUpstream.url} (never the org key).${e.clientKey?" Your personal gateway key rides x-anyray-api-key.":""}`:c?`Subscription mode: Claude Code keeps your seat sign-in; its OAuth token passes through the gateway (never stored).${e.clientKey?" Your personal gateway key rides x-anyray-api-key.":""}`:e.clientKey?"Auth: personal gateway key (not shown here; see below for where it lives)":"Auth: placeholder token (gateway swaps in the server-held key)",`Attribution: ${d??"(none)"}`,...l?[]:["Restored on-demand MCP tool loading (env.ENABLE_TOOL_SEARCH) that Claude Code otherwise disables behind a non-first-party gateway. Deferred servers stay out of context until used; the first-party AnyRay retrieval server stays always loaded so capability is visible per request."],...s.envTokens!==void 0?[`Context window: env.CLAUDE_CODE_MAX_CONTEXT_TOKENS = ${s.envTokens} \u2014 your model's real window, so Claude Code stops budgeting the 200k it assumes behind any custom base URL.`]:[],...s.model!==void 0?[`Context window: model = ${s.model} \u2014 same model, its long-context variant. Claude Code ignores CLAUDE_CODE_MAX_CONTEXT_TOKENS for claude-* ids, so the [1m] alias is what actually gets you your ${a} window back instead of the 200k it assumes behind any custom base URL. A --model flag on your launch command, or picking a model in-app, overrides this \u2014 add [1m] there too (quote it in zsh).`]:[],"Claude Code settings.json routing covers the CLI and VS Code extension. Claude Desktop is separate: its verified macOS automatic setup supports either the Claude Code subscription-backed Gateway lane or API billing; other Desktop lanes fail closed or use the documented API setup.","Restart Claude Code (or open a new session) to pick up the change."];if(t.dryRun)return{status:"configured",messages:w};s.model!==void 0&&(r.model=s.model);let g=r.env??{};r.env={...g,...i};let y=r.env;for(let{name:I}of Sn)m.some(R=>R.name===I)?y[I]="":y[I]===""&&(process.env[I]??"").trim()===""&&delete y[I];if(u||delete y.ANTHROPIC_CUSTOM_HEADERS,c&&(g.ANTHROPIC_AUTH_TOKEN&&w.push("Removed env.ANTHROPIC_AUTH_TOKEN \u2014 it would override your subscription sign-in."),delete y.ANTHROPIC_AUTH_TOKEN),l)for(let I of fg)delete y[I];let b=!!e.clientKey,C=ce(),S=PO(r);!c&&!l&&b&&C&&!S?(r.apiKeyHelper=pg(),delete y.ANTHROPIC_AUTH_TOKEN,w.push("Installed an apiKeyHelper that reprints a fresh gateway key on demand \u2014 Claude Code refreshes it at startup and on any 401, so an idle session no longer 401s (no re-enrollment).")):Mr(r)&&delete r.apiKeyHelper,S&&!c&&!l&&b&&C&&w.push("Kept your existing apiKeyHelper; your gateway key stays in ANTHROPIC_AUTH_TOKEN (Anyray auto-refresh via the helper is off)."),(c||l)&&b&&C?(IO(r),w.push("Installed a SessionStart hook that refreshes your gateway key each session, so an idle subscription session no longer needs re-enrollment.")):Lg(r),ce()?(xO(r),w.push("Installed a PostToolUse hook (trims oversized tool outputs, cache-safe) and a UserPromptSubmit hook (beacons oversized pasted-data prompts) \u2014 both content-free.")):(Pg(r),w.push(`Skipped the Anyray hooks \u2014 anyray-connect is running from a temporary path (${Re()}). Re-run via the installer (it persists the binary under ~/.anyray/bin) or a global install to enable cache-safe trimming and paste-savings beacons.`)),await Z(n,r);let x=[n],A=Ja();try{let I=await M(A),R=!1;ce()?EO(I)==="conflict"?w.push(`MCP name conflict in ${A}: mcpServers.${qn} is not owned by Anyray Connect, so it was left untouched.`):(R=!0,w.push("Registered the Anyray retrieval MCP server (anyray_retrieve) for explicit recovery of stashed context \u2014 always loaded so retrieval capability is visible on every request.")):R=_g(I),R&&(await Z(A,I),x.push(A))}catch(I){w.push(`Could not register the Anyray MCP server in ${A} (${I instanceof Error?I.message:String(I)}); retrieval via anyray_retrieve is unavailable until this is fixed.`)}return{status:"configured",messages:w,changedFiles:x}},skillsDir(){return ic(sc(),".claude","skills")},async watchPaths(){return[En(),Ja()]},async pointsAt(e){let t=En();if(!await O(t))return!1;try{let o=(await M(t)).env?.ANTHROPIC_BASE_URL;return typeof o=="string"&&o.replace(/\/+$/,"")===e}catch{return!1}},async runtimeDiagnostics(){let e=await M(En()).catch(()=>({}));return Tg(e)},async routingOverrides(){let e=await M(En()).catch(()=>({}));return(await Tg(e)).routingOverrides},async mcpStatus(){let e=Ja();if(!await O(e))return{registered:!1,command:null};try{let r=(await M(e)).mcpServers?.[qn];return!r||!Vt(r,"claude")?{registered:!1,command:null}:{registered:!0,command:typeof r.command=="string"?r.command:null}}catch{return{registered:!1,command:null}}},async integrationStatus(){let e,t=!0,n=En();if(!await O(n))e="missing";else try{let s=await M(n);if(s.hooks===void 0)e="missing";else if(!$r(s.hooks))e="unreadable";else{let i=s.hooks.PostToolUse;e=i===void 0?"missing":Array.isArray(i)?i.some(c=>Zn(c,Ze))?"owned":"missing":"unreadable",e==="owned"&&Array.isArray(i)&&(t=i.some(c=>Zn(c,Ze)&&$r(c)&&Array.isArray(c.hooks)&&c.hooks.some(l=>$r(l)&&qi(l.command,Ze))))}}catch{e="unreadable"}let r,o=!0,a=Ja();if(!await O(a))r="missing";else try{let s=await M(a);if(s.mcpServers===void 0)r="missing";else if(!$r(s.mcpServers))r="unreadable";else{let i=s.mcpServers[qn];r=i===void 0?"missing":Vt(i,"claude")?"owned":"foreign",r==="owned"&&(o=Qi(i,"claude"))}}catch{r="unreadable"}return{hook_registration:e,mcp_registration:r,hook_binary:t&&o&&await Dr()?"owned":"missing",beacon_target:await oc().catch(()=>"unreadable")}},async inferenceAuthLanes(){try{let e=await M(En()),t=$r(e.env)?e.env:{},n=typeof t.ANTHROPIC_CUSTOM_HEADERS=="string"?t.ANTHROPIC_CUSTOM_HEADERS:"";if(/^x-anyray-custom-host:/m.test(n))return["byo"];if(/^x-anyray-auth-mode:\s*passthrough$/m.test(n))return["subscription"];if(typeof t.ANTHROPIC_AUTH_TOKEN=="string"||typeof e.apiKeyHelper=="string")return["api_key"]}catch{}return["unknown"]},async revert(e){let t=En();if(!await O(t))return{status:"not-found",messages:["nothing to revert"]};if(e.dryRun)return{status:"reverted",messages:[`would remove Anyray keys from ${t}`]};let n=await M(t),r=n.env,o=Pg(n),a=Mr(n);a&&delete n.apiKeyHelper;let s=r?await _O(t,r):[],i=gg(typeof n.model=="string"?n.model:void 0,(await Pr(t)).model);i!==void 0&&(n.model=i),r&&Object.keys(r).length===0&&delete n.env,(r||o||a||i!==void 0)&&await Z(t,n,{backup:!1});let c=[`removed Anyray keys from ${t}`];i!==void 0&&c.push(`Put model back to ${i} \u2014 dropped the [1m] alias Anyray added for your context window.`),o&&c.push("Removed the Anyray PostToolUse, UserPromptSubmit, and SessionStart hooks."),a&&c.push("Removed the Anyray apiKeyHelper."),s.length&&c.push(`Put back the ${s.join(" and ")} you had set before Anyray.`);let l=Ja();try{let d=await M(l);_g(d)&&(await Z(l,d,{backup:!1}),c.push("Removed the Anyray retrieval MCP server (anyray_retrieve)."))}catch{}return await oe(t),{status:"reverted",messages:c,changedFiles:[t]}}};var ke="0.11.129";var dn=e=>{let{command:t,args:n}=cn([e]);return{command:t,args:n}},er=()=>Lr();import{homedir as Ng,userInfo as TO}from"node:os";var za=()=>{try{return Ng()!==TO().homedir}catch{return!1}},_o=e=>[`Skipped ${e} \u2014 HOME (${Ng()}) is not this account's home directory.`,"The OS registers a per-user service against the account, not against HOME, so","one installed from here would point at a path the real login session cannot use."];var gt=(e=process.env)=>e.CODESPACES==="true"||e.CODESPACE_NAME?"codespaces":e.REMOTE_CONTAINERS==="true"||e.REMOTE_CONTAINERS_IPC||e.DEVCONTAINER?"devcontainer":e.SSH_CONNECTION||e.SSH_TTY?"ssh":null,qa=(e=process.env)=>gt(e)!==null,At=e=>e==="codespaces"||e==="devcontainer",tr=e=>{switch(e){case"codespaces":return"a GitHub Codespace";case"devcontainer":return"a dev container";case"ssh":return"an SSH session"}};var Mu="__anyray-fallback-proxy",ts="ai.anyray.connect.fallback",nr="anyray-fallback",Ug=ts,Ce=8785,ns=60,Fu="x-anyray-local",Bu=()=>dn(Mu),$g=er,lc=async(e=Ce)=>{let t=n=>new Promise(r=>{let o=NO();o.once("error",()=>r(!1)),o.listen(n,"127.0.0.1",()=>o.close(()=>r(!0)))});for(let n=e;n<e+20;n++)if(await t(n))return n;return e},Ae=async(e,t=1500)=>{let n=new AbortController,r=setTimeout(()=>n.abort(),t);try{let o=await fetch(`http://127.0.0.1:${e}/__anyray/health`,{signal:n.signal});return o.ok?await o.json():null}catch{return null}finally{clearTimeout(r)}},Do=()=>Lo(es(),"Library","LaunchAgents",`${Ug}.plist`),rs=()=>Lo(es(),".anyray","logs"),Qa=()=>Lo(rs(),"connect-daemon.log"),Hg=async(e,t=1048576)=>{await Fg(e).then(r=>r.size,()=>0)>t&&await DO(e).catch(()=>{})},No=()=>Lo(es(),".config","systemd","user",`${nr}.service`),Du=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),os=(e=Bu())=>{let{command:t,args:n}=e,r=[t,...n].map(o=>` <string>${Du(o)}</string>`).join(`
|
|
8
8
|
`);return`<?xml version="1.0" encoding="UTF-8"?>
|
|
9
9
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
10
10
|
<plist version="1.0">
|
|
@@ -34,7 +34,7 @@ TimeoutStopSec=${ns}
|
|
|
34
34
|
|
|
35
35
|
[Install]
|
|
36
36
|
WantedBy=default.target
|
|
37
|
-
`},cc=()=>{let{command:e,args:t}=Bu();return["Auto-start is not wired for this OS. Run the key-refresh proxy yourself:",` ${[e,...t].map(r=>/\s/.test(r)?JSON.stringify(r):r).join(" ")}`,"(keep it running in the background \u2014 your tools route through it)."]},Wg=async()=>{let e=To();if(e!=="darwin"&&e!=="linux")return!1;let t=e==="darwin"?Do():No();try{return await Fg(t),!0}catch{return!1}},Kg=async()=>{let e=To();if(e!=="darwin"&&e!=="linux")return!0;let t=e==="darwin"?Do():No(),n=e==="darwin"?os():as();return await Mg(t,"utf-8").catch(()=>null)===n},$u=async e=>{await Nu(Lo(es(),"Library","LaunchAgents"),{recursive:!0}),await Nu(rs(),{recursive:!0,mode:448}),await Bg(e,os())},Gg=async()=>{let e=To();return e==="darwin"?(await $u(Do()),!0):e==="linux"?(await Nu(Lo(es(),".config","systemd","user"),{recursive:!0}),await Bg(No(),as()),!0):!1},jg=async()=>Gg().catch(()=>!1),$O=async(e,t)=>{let n=To();if(n!=="darwin"&&n!=="linux")return!1;let r=n==="darwin"?Do():No(),o=n==="darwin"?os():as();if(await Mg(r,"utf-8").catch(()=>null)!==o)return!1;let s=await Ae(e);return s?.version!==ke?!1:typeof s.remoteOrigin=="string"&&Ye(s.remoteOrigin)===Ye(t)},Pt=async e=>{if(Ke($g()))return{ok:!1,messages:[`Skipped key-refresh auto-start \u2014 anyray-connect is running from a temporary path (${$g()}).`,"Install it durably (the installer persists it under ~/.anyray/bin) and re-run."]};if(za())return{ok:!1,messages:_o("key-refresh auto-start")};{let n=gt();if(At(n))return{ok:!1,messages:[`Skipped key-refresh auto-start \u2014 ${tr(n)} has no per-user service manager to supervise the daemon.`]}}if(await $O(e.port,e.remoteOrigin))return{ok:!0,messages:["Key-refresh service already current \u2014 left running."]};let t=To();try{if(t==="darwin"){let n=Do(),r=String(process.getuid?.()??""),o=`${n}.new-${process.pid}`;await Po(o,{force:!0}).catch(()=>{}),await $u(o),un("launchctl",["bootout",`gui/${r}`,n]),await Po(n,{force:!0}).catch(()=>{});try{await LO(o,n)}catch{await $u(n),await Po(o,{force:!0}).catch(()=>{})}return un("launchctl",["bootstrap",`gui/${r}`,n]).status===0||un("launchctl",["load","-w",n]).status===0?{ok:!0,messages:[`Installed launchd agent ${n}.`]}:{ok:!1,messages:[`Wrote ${n} but launchd would not load the agent.`,...cc()]}}if(t==="linux"){let n=No();return await Gg(),un("systemctl",["--user","daemon-reload"]),un("systemctl",["--user","enable",`${nr}.service`]),un("systemctl",["--user","restart",`${nr}.service`]).status!==0?{ok:!1,messages:[`Wrote ${n} but \`systemctl --user restart\` failed.`,...cc()]}:{ok:!0,messages:[`Installed systemd user unit ${n}.`]}}return{ok:!1,messages:cc()}}catch(n){return{ok:!1,messages:[`Could not install the key-refresh service: ${n instanceof Error?n.message:String(n)}`,...cc()]}}},Uu=async(e=Ce,t={})=>{if(await Ae(e)===null)return!1;let n=t.drain==="idle"?"?drain=idle":"";try{let r=new AbortController,o=setTimeout(()=>r.abort(),1500);try{await fetch(`http://127.0.0.1:${e}/__anyray/shutdown${n}`,{method:"POST",headers:{[Fu]:"1"},signal:r.signal})}finally{clearTimeout(o)}}catch{}for(let r=0;r<10&&await Ae(e,300)!==null;r++)await new Promise(o=>setTimeout(o,100));return!0},Zt=async(e=Ce)=>{let t=To();await Po(Qa(),{force:!0}).catch(()=>{});let n=[],r=za();try{if(r)n.push(..._o("key-refresh service teardown"));else if(t==="darwin"){let o=Do(),a=String(process.getuid?.()??"");un("launchctl",["bootout",`gui/${a}`,o]),un("launchctl",["unload",o]),await Po(o,{force:!0}),n.push("Removed the launchd key-refresh agent.")}else t==="linux"&&(un("systemctl",["--user","disable","--now",`${nr}.service`]),await Po(No(),{force:!0}),un("systemctl",["--user","daemon-reload"]),n.push("Removed the systemd key-refresh unit."))}catch{}try{await Uu(e)&&n.push("Stopped the running key-refresh proxy daemon.")}catch{}return{ok:!0,messages:n}};import{stat as
|
|
37
|
+
`},cc=()=>{let{command:e,args:t}=Bu();return["Auto-start is not wired for this OS. Run the key-refresh proxy yourself:",` ${[e,...t].map(r=>/\s/.test(r)?JSON.stringify(r):r).join(" ")}`,"(keep it running in the background \u2014 your tools route through it)."]},Wg=async()=>{let e=To();if(e!=="darwin"&&e!=="linux")return!1;let t=e==="darwin"?Do():No();try{return await Fg(t),!0}catch{return!1}},Kg=async()=>{let e=To();if(e!=="darwin"&&e!=="linux")return!0;let t=e==="darwin"?Do():No(),n=e==="darwin"?os():as();return await Mg(t,"utf-8").catch(()=>null)===n},$u=async e=>{await Nu(Lo(es(),"Library","LaunchAgents"),{recursive:!0}),await Nu(rs(),{recursive:!0,mode:448}),await Bg(e,os())},Gg=async()=>{let e=To();return e==="darwin"?(await $u(Do()),!0):e==="linux"?(await Nu(Lo(es(),".config","systemd","user"),{recursive:!0}),await Bg(No(),as()),!0):!1},jg=async()=>Gg().catch(()=>!1),$O=async(e,t)=>{let n=To();if(n!=="darwin"&&n!=="linux")return!1;let r=n==="darwin"?Do():No(),o=n==="darwin"?os():as();if(await Mg(r,"utf-8").catch(()=>null)!==o)return!1;let s=await Ae(e);return s?.version!==ke?!1:typeof s.remoteOrigin=="string"&&Ye(s.remoteOrigin)===Ye(t)},Pt=async e=>{if(Ke($g()))return{ok:!1,messages:[`Skipped key-refresh auto-start \u2014 anyray-connect is running from a temporary path (${$g()}).`,"Install it durably (the installer persists it under ~/.anyray/bin) and re-run."]};if(za())return{ok:!1,messages:_o("key-refresh auto-start")};{let n=gt();if(At(n))return{ok:!1,messages:[`Skipped key-refresh auto-start \u2014 ${tr(n)} has no per-user service manager to supervise the daemon.`]}}if(await $O(e.port,e.remoteOrigin))return{ok:!0,messages:["Key-refresh service already current \u2014 left running."]};let t=To();try{if(t==="darwin"){let n=Do(),r=String(process.getuid?.()??""),o=`${n}.new-${process.pid}`;await Po(o,{force:!0}).catch(()=>{}),await $u(o),un("launchctl",["bootout",`gui/${r}`,n]),await Po(n,{force:!0}).catch(()=>{});try{await LO(o,n)}catch{await $u(n),await Po(o,{force:!0}).catch(()=>{})}return un("launchctl",["bootstrap",`gui/${r}`,n]).status===0||un("launchctl",["load","-w",n]).status===0?{ok:!0,messages:[`Installed launchd agent ${n}.`]}:{ok:!1,messages:[`Wrote ${n} but launchd would not load the agent.`,...cc()]}}if(t==="linux"){let n=No();return await Gg(),un("systemctl",["--user","daemon-reload"]),un("systemctl",["--user","enable",`${nr}.service`]),un("systemctl",["--user","restart",`${nr}.service`]).status!==0?{ok:!1,messages:[`Wrote ${n} but \`systemctl --user restart\` failed.`,...cc()]}:{ok:!0,messages:[`Installed systemd user unit ${n}.`]}}return{ok:!1,messages:cc()}}catch(n){return{ok:!1,messages:[`Could not install the key-refresh service: ${n instanceof Error?n.message:String(n)}`,...cc()]}}},Uu=async(e=Ce,t={})=>{if(await Ae(e)===null)return!1;let n=t.drain==="idle"?"?drain=idle":"";try{let r=new AbortController,o=setTimeout(()=>r.abort(),1500);try{await fetch(`http://127.0.0.1:${e}/__anyray/shutdown${n}`,{method:"POST",headers:{[Fu]:"1"},signal:r.signal})}finally{clearTimeout(o)}}catch{}for(let r=0;r<10&&await Ae(e,300)!==null;r++)await new Promise(o=>setTimeout(o,100));return!0},Zt=async(e=Ce)=>{let t=To();await Po(Qa(),{force:!0}).catch(()=>{});let n=[],r=za();try{if(r)n.push(..._o("key-refresh service teardown"));else if(t==="darwin"){let o=Do(),a=String(process.getuid?.()??"");un("launchctl",["bootout",`gui/${a}`,o]),un("launchctl",["unload",o]),await Po(o,{force:!0}),n.push("Removed the launchd key-refresh agent.")}else t==="linux"&&(un("systemctl",["--user","disable","--now",`${nr}.service`]),await Po(No(),{force:!0}),un("systemctl",["--user","daemon-reload"]),n.push("Removed the systemd key-refresh unit."))}catch{}try{await Uu(e)&&n.push("Stopped the running key-refresh proxy daemon.")}catch{}return{ok:!0,messages:n}};import{stat as LY}from"node:fs/promises";import{readFileSync as MO,rmSync as FO,writeFileSync as BO,mkdirSync as UO}from"node:fs";import{join as HO}from"node:path";var Hu=()=>HO(Q(),"draining"),Vg=e=>{try{UO(Q(),{recursive:!0}),BO(Hu(),`${Math.floor(e)}
|
|
38
38
|
`,"utf-8")}catch{}},Wu=()=>{try{FO(Hu(),{force:!0})}catch{}},WO=16*6e4,Ku=(e=Date.now())=>{let t;try{t=MO(Hu(),"utf-8")}catch{return!1}let n=t.trim();if(!/^\d+$/.test(n))return!1;let r=Number(n);return Number.isSafeInteger(r)&&r>e&&r<=e+WO};import{homedir as Yu,platform as Zu}from"node:os";import{join as $o}from"node:path";import{mkdir as Gu,readFile as KO,rename as GO,writeFile as dc,rm as Fr}from"node:fs/promises";import{spawnSync as jO}from"node:child_process";var Vu=()=>$o(rs(),"connect-refresh.log"),pc=1800,cs="ai.anyray.connect.refresh",Br="anyray-refresh",fc="\\AnyrayConnectKeyRefresh",hc=cs,ls=Br,is=fc,VO=String(pc/60),Xu=(e,t)=>{let n=jO(e,t,{stdio:"ignore"});return{ok:!n.error&&n.status===0}},Ju=()=>$o(Yu(),"Library","LaunchAgents",`${hc}.plist`),zu=()=>$o(Yu(),".config","systemd","user"),Yg=()=>$o(zu(),`${ls}.service`),uc=()=>$o(zu(),`${ls}.timer`),ju=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),mc=()=>dn(Jn),YO=(e=mc())=>{let{command:t,args:n}=e,r=[t,...n].map(o=>` <string>${ju(o)}</string>`).join(`
|
|
39
39
|
`);return`<?xml version="1.0" encoding="UTF-8"?>
|
|
40
40
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -109,7 +109,7 @@ PRAGMA wal_checkpoint(TRUNCATE);
|
|
|
109
109
|
`,{mode:384}),await pe(a,o)}catch{}finally{await Ob(a,{force:!0})}},BP=async(e,t)=>{await Rb(Bp(e,t)).catch(()=>{})},Fb=async(e,t,n,r={},o={mode:"copilot-seat"})=>{let a={...Lb,...r,home:r.home??Go()},s=dr[e];if(n==="configure"&&!t?.clientKey)return{ok:!1,reason:"failed"};if(n==="configure"&&!Tb(t.origin))return{ok:!1,reason:"unsafe-gateway"};let i=(o.gatewayModels??[]).filter((g,y,b)=>typeof g.id=="string"&&g.id.length>0&&g.id.length<=200&&!/[\u0000-\u001f\u007f]/.test(g.id)&&typeof g.name=="string"&&g.name.length>0&&g.name.length<=200&&!/[\u0000-\u001f\u007f]/.test(g.name)&&b.findIndex(C=>C.id===g.id)===y);if(n==="configure"&&o.mode==="gateway-api"&&i.length===0)return{ok:!1,reason:"failed"};let c=await Db(e,a);if(!c)return{ok:!1,reason:"cli-not-found"};if(n==="configure"&&c.version&&!qu(c.version))return{ok:!1,reason:"unsupported-version"};let{command:l}=c,d=a.listProfiles??(g=>nw(g,Fp(),a.home)),u=n==="configure"?await d(e).catch(()=>[]):[];if(n==="configure"&&await MP(e,t,o,u,s.slug,a).catch(()=>!1))return{ok:!0,receipt:Ko(a.home,s.slug),profiles:{installed:[],failed:[]},alreadyCurrent:!0};let f=a.extensionPath;if(n==="configure"){try{f??=await $P(a.home)}catch{return{ok:!1,reason:"extension-missing"}}if(!await NP(f))return{ok:!1,reason:"extension-missing"}}let p=a.nonce(),h=xs(a.home,".anyray",SP,`${p}.json`),m=Ko(a.home,s.slug);await $p(_b(h),{recursive:!0,mode:448}),await Mp(h,`${JSON.stringify({version:Is,action:n,nonce:p,variant:s.slug,...n==="configure"&&{gatewayUrl:t.origin,clientKey:t.clientKey,metadata:t.metadata,mode:o.mode,gatewayModels:i},expectedExtensionVersion:On,expectedExtensionDistSha256:Vr})}
|
|
110
110
|
`,{mode:384});let w={installed:[],failed:[]};try{if(n==="configure"){await a.run(l,["--install-extension",f,"--force"]);for(let y of u)try{await a.run(l,["--profile",y,"--install-extension",f,"--force"]),w.installed.push(y)}catch{w.failed.push(y)}}await a.run(l,["--open-url",`${s.scheme}://${Pe}/configure?nonce=${encodeURIComponent(p)}`]);let g=await DP(m,p,n,a);return g!=="confirmed"?{ok:!1,reason:g==="reload-required"?"reload-required":"activation-timeout"}:(n==="configure"?w.failed.length===0&&await FP(a.home,s.slug,Mb(t,o,u),p):await BP(a.home,s.slug),{ok:!0,receipt:m,profiles:w})}catch{return{ok:!1,reason:"failed"}}finally{await Rb(h).catch(()=>{})}},Bb=async(e,t=Go())=>{try{let n=JSON.parse(await Yr(Ko(t,dr[e].slug),"utf8"));return n.action==="reload-required"?!0:n.action==="configure"&&(n.extensionVersion!==On||n.extensionDistSha256!==Vr)}catch{return!1}},Ub=async(e,t=Go())=>{try{let n=JSON.parse(await Yr(Ko(t,dr[e].slug),"utf8"));return n.version!==Is||n.action!=="configure"?void 0:n.mode==="copilot-seat"||n.mode==="gateway-api"?n.mode:void 0}catch{return}},Hb=async(e,t,n=Go(),r={})=>{try{let o=Os(t);if(!o)return!1;let a=JSON.parse(await Yr(Ko(n,dr[e].slug),"utf8"));if(!(a.version===Is&&a.action==="configure"&&a.gatewayUrl===o&&a.extensionVersion===On&&a.extensionDistSha256===Vr))return!1;let i={...Lb,...r,home:n};return await Nb(e,i)===!0}catch{return!1}};var ur="Anyray",fn="anyray",Yb="--anyray-owner=vscode-profile-v1",Rs=e=>Vb(at(e),"User","chatLanguageModels.json"),VP=e=>Vb(at(e),"User","settings.json"),_s="github.copilot.advanced",zc="debug.overrideCapiUrl",vt=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),YP=e=>{if(typeof e!="string")return!1;try{let t=new URL(e);return(t.protocol==="https:"||t.protocol==="http:")&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/v1\/copilot\/[^/]+\/ark_[A-Za-z0-9_-]{20,512}\/?$/.test(t.pathname)}catch{return!1}},Zb=e=>{let t=e[_s];if(!vt(t)||!YP(t[zc]))return{next:e,removed:!1};let n={...t};delete n[zc];let r={...e};return Object.keys(n).length>0?r[_s]=n:delete r[_s],{next:r,removed:!0}},Ps="anyray-default",Ts=()=>{let e=(process.env.ANYRAY_COPILOT_MODEL??"").split(",").map(t=>t.trim()).filter(t=>t.length>0&&t.length<=200&&!/[\u0000-\u001f\u007f]/.test(t)).filter((t,n,r)=>r.indexOf(t)===n).slice(0,64);return e.length?e:[Ps]},Xb=e=>e===Ps?"Anyray Gateway":`Anyray \xB7 ${e}`.slice(0,200),Jc=async e=>{if(!await O(e))return{kind:"missing"};try{let t=await jb(e,"utf-8");if(!t.trim())return{kind:"array",entries:[]};let n=JSON.parse(t);return Array.isArray(n)?{kind:"array",entries:n}:{kind:"unrecognized"}}catch{return{kind:"unrecognized"}}},Jb=async(e,t)=>{await HP(jP(e),{recursive:!0});let n=`${e}.anyray-tmp-${process.pid}-${GP()}`;try{await KP(n,`${JSON.stringify(t,null,2)}
|
|
111
111
|
`,{flag:"wx",mode:384}),await pe(n,e),await UP(e,384)}finally{await WP(n,{force:!0}).catch(()=>{})}},Up=e=>{if(!vt(e))return!1;let t=e,n=Object.keys(t).sort(),r=["apiType",...t.apiKey===void 0?[]:["apiKey"],"models","name","vendor"].sort();return n.length!==r.length||!n.every((o,a)=>o===r[a])||t.name!==ur||t.vendor!=="customendpoint"||t.apiType!=="chat-completions"||!(t.apiKey===void 0||typeof t.apiKey=="string"&&t.apiKey.length>0&&t.apiKey.length<=512&&!/[\u0000-\u001f\u007f]/.test(t.apiKey))||!Array.isArray(t.models)||t.models.length===0||t.models.length>64?!1:t.models.every(o=>{if(!vt(o))return!1;let a=["id","maxInputTokens","maxOutputTokens","name",...o.requestHeaders===void 0?[]:["requestHeaders"],"toolCalling","url","vision"].sort(),s=Object.keys(o).sort();if(s.length!==a.length||!s.every((i,c)=>i===a[c])||typeof o.id!="string"||o.id.length===0||o.id.length>200||o.name!==Xb(o.id)||typeof o.url!="string"||o.toolCalling!==!0||o.vision!==!0||o.maxInputTokens!==128e3||o.maxOutputTokens!==16e3||o.requestHeaders!==void 0&&(!vt(o.requestHeaders)||Object.keys(o.requestHeaders).length!==1||typeof o.requestHeaders["x-anyray-metadata"]!="string"||o.requestHeaders["x-anyray-metadata"].length>8192))return!1;try{let i=new URL(o.url);return(i.protocol==="https:"||i.protocol==="http:")&&!i.username&&!i.password&&!i.search&&!i.hash&&i.pathname==="/v1/chat/completions"}catch{return!1}})},Hp=e=>{let t=e.filter(n=>!Up(n));return{next:t,removed:t.length!==e.length}},ZP=async(e,t)=>{let n=Rs(e),r=await Jc(n);if(r.kind==="missing")return{changedFiles:[],messages:[],manual:!1};if(r.kind==="unrecognized")return{changedFiles:[],manual:!0,messages:[`Could not recognize ${n}; left it untouched. Remove the legacy "${ur}" Custom Endpoint manually if it is still listed.`]};let{next:o,removed:a}=Hp(r.entries);if(!a)return{changedFiles:[],messages:[],manual:!1};if(t)return{changedFiles:[],manual:!1,messages:[`Would remove the obsolete "${ur}" Custom Endpoint from ${n}.`]};try{return await Jb(n,o),await oe(n),{changedFiles:[n],manual:!1,messages:[`Removed the obsolete "${ur}" Custom Endpoint from ${n}.`]}}catch{return{changedFiles:[],manual:!0,messages:[`Could not remove the obsolete "${ur}" Custom Endpoint from ${n}; remove it manually from Manage Language Models.`]}}},XP=async e=>{try{let t=lr(await jb(e,"utf-8"));if(vt(t))return Zb(t).removed?{changedFiles:[],manual:!0,messages:[`Found the retired Anyray ${_s}.${zc} in ${e}, which uses JSONC that Connect will not rewrite; remove it manually.`]}:{changedFiles:[],messages:[],manual:!1}}catch{}return{changedFiles:[],manual:!0,messages:[`Could not parse ${e}; remove an old Anyray ${_s}.${zc} value manually if present.`]}},zb=async(e,t)=>{let n=VP(e),r;try{r=await M(n)}catch{return XP(n)}let{next:o,removed:a}=Zb(r);if(!a)return{changedFiles:[],messages:[],manual:!1};if(t)return{changedFiles:[],manual:!1,messages:[`Would remove the retired Anyray Copilot debug override from ${n}.`]};try{return await Z(n,o,{backup:!1}),await oe(n),{changedFiles:[n],manual:!1,messages:[`Removed the retired Anyray Copilot debug override from ${n}.`]}}catch{return{changedFiles:[],manual:!0,messages:[`Could not remove the retired Anyray Copilot debug override from ${n}; remove it manually.`]}}},JP=async(e,t)=>{let n=await ZP(e,t),r=await zb(e,t);return{changedFiles:[...n.changedFiles,...r.changedFiles],messages:[...n.messages,...r.messages],manual:n.manual||r.manual}},qb=e=>{let t=e.mcpServerCommand("profile");return{type:"stdio",command:t.command,args:[...t.args,Yb]}},Qb=(e,t)=>{let n=Object.keys(e).sort(),r=[...t].sort();return n.length===r.length&&n.every((o,a)=>o===r[a])},ek=(e,t)=>Array.isArray(e)&&Array.isArray(t)&&e.length===t.length&&e.every((n,r)=>typeof n=="string"&&n===t[r]),zP=e=>Array.isArray(e.args)&&e.args.at(-1)===Yb,tk=(e,t)=>{if(!t.hookBinaryIsDurable()||!vt(e)||!Qb(e,["type","command","args"]))return!1;let n=qb(t);return e.type==="stdio"&&e.command===n.command&&ek(e.args,n.args)},qP=(e,t)=>{if(!vt(e)||!Qb(e,["type","command","args"])||e.type!=="stdio"||typeof e.command!="string"||!Array.isArray(e.args)||!e.args.every(i=>typeof i=="string"))return!1;let n=t.mcpServerCommand("profile");if(e.command===n.command&&ek(e.args,n.args))return!0;if(Ke(e.command))return!1;let r=e.args;if(!((r.length===2||r.length===3)&&r.at(-2)===zn&&r.at(-1)==="profile"))return!1;let a=e.command.replaceAll("\\","/");if(/(?:^|\/)anyray-connect(?:\.exe)?$/.test(a))return r.length===2;if(!/(?:^|\/)node(?:\.exe)?$/.test(a)||r.length!==3)return!1;let s=r[0].replaceAll("\\","/");return!Ke(s)&&(/(?:^|\/)anyray-connect(?:\/|$)/.test(s)||/(?:^|\/)\.anyray\/bin\/connect-runtime-[0-9A-Za-z][0-9A-Za-z.-]*\/dist\/index\.js$/.test(s))},Wp=(e,t)=>tk(e,t)?"exact":vt(e)&&zP(e)||qP(e,t)?"stale-owned":"foreign",Wb=e=>`MCP name conflict in ${e}: servers.${fn} is not owned by Anyray Connect, so it was left untouched. Rename that existing server, then re-run anyray-connect to register Anyray retrieval.`,QP=async(e,t,n,r,o)=>{let a=await o.vscodeUserMcpConfigPaths(e,r),s=o.hookBinaryIsDurable(),i=n&&s,c=[],l=[],d=0,u=!1,f=[];for(let p of a)try{let h=await M(p);if(i){if("servers"in h&&!vt(h.servers)){u=!0,l.push(`Could not register Anyray retrieval in ${p} because its servers value is not an object; left the file untouched. Repair that value, then re-run anyray-connect.`);continue}let y=vt(h.servers)?{...h.servers}:{},b=qb(o),C=y[fn],S=C===void 0?void 0:Wp(C,o);if(S==="exact"){d+=1;continue}if(S==="foreign"){u=!0,l.push(Wb(p));continue}if(t){d+=1;continue}y[fn]=b,f.push({path:p,next:{...h,servers:y},backup:S!=="stale-owned",clearBackupAfter:!1});continue}if(!vt(h.servers)||!(fn in h.servers))continue;if(Wp(h.servers[fn],o)==="foreign"){u=!0,l.push(Wb(p));continue}if(t)continue;let w={...h.servers};delete w[fn];let g={...h};Object.keys(w).length===0?delete g.servers:g.servers=w,f.push({path:p,next:g,backup:!1,clearBackupAfter:!0})}catch(h){u=!0,l.push(`Could not update the Anyray MCP server in ${p} (${h instanceof Error?h.name:"unknown error"}); retrieval via anyray_retrieve is unavailable in that profile.`)}if(!u&&!t)for(let p of f)try{await Z(p.path,p.next,p.backup?{}:{backup:!1}),p.clearBackupAfter&&await oe(p.path),c.push(p.path),i&&(d+=1)}catch(h){u=!0,l.push(`Could not update the Anyray MCP server in ${p.path} (${h instanceof Error?h.name:"unknown error"}); retrieval via anyray_retrieve is unavailable in that profile.`);break}return i?l.unshift(t?d===a.length?`Would register the Anyray retrieval MCP server in ${a.length} VS Code user profile config(s).`:`Would register the Anyray retrieval MCP server in ${d} of ${a.length} VS Code user profile config(s); resolve the conflicts below first.`:d===a.length?`Registered the Anyray retrieval MCP server (anyray_retrieve / anyray_recall) in ${a.length} VS Code user profile config(s).`:`Registered the Anyray retrieval MCP server in ${d} of ${a.length} VS Code user profile config(s); see the profile-specific errors below.`):n?l.unshift(t?`Would skip the Anyray retrieval MCP server because ${o.hookBinaryPath()} is temporary.`:`Skipped the Anyray retrieval MCP server because ${o.hookBinaryPath()} is temporary; removed any stale owned registration. Re-run via the installer or a global install to enable retrieval.`):l.unshift(`${t?"Would skip":"Skipped"} the Anyray retrieval MCP server because this VS Code build predates profile-scoped mcp.json support (${qg}+).`),{changedFiles:c,messages:l,manual:u}},eT=async(e,t,n,r)=>{let o=await r.vscodeUserMcpConfigPaths(e,n),a=[],s=[],i=0;for(let c of o)if(await O(c))try{let l=await M(c);if(!vt(l.servers)||!(fn in l.servers)||Wp(l.servers[fn],r)==="foreign"||(i+=1,t))continue;let d={...l.servers};delete d[fn];let u={...l};Object.keys(d).length===0?delete u.servers:u.servers=d,await Z(c,u,{backup:!1}),await oe(c),a.push(c)}catch{}return t&&i>0?s.push(`would remove the Anyray retrieval MCP server from ${i} VS Code user profile config(s)`):a.length>0&&s.push("Removed the Anyray retrieval MCP server (anyray_retrieve / anyray_recall)."),{changedFiles:a,messages:s,manual:!1}},nk=e=>[...e.installed.length>0?[`Also installed into ${e.installed.length} additional VS Code profile(s): ${e.installed.join(", ")}. Config is shared through SecretStorage \u2014 no further steps.`]:[],...e.failed.length>0?[`Couldn\u2019t install into profile(s): ${e.failed.join(", ")}. Open VS Code with that profile and use \u201CApply Extension to all Profiles\u201D, or re-run anyray-connect.`]:[]],rk=()=>`${Pe} is already installed and configured for this gateway \u2014 skipped the VSIX reinstall and the VS Code URI confirmation prompt. (Run --revert first to force re-delivery.)`,Kb=e=>[`${Pe} mirrors the GitHub Copilot models available to this VS Code install.`,`Gateway: ${e.origin} (client key stored by VS Code SecretStorage).`,"Mode: SUBSCRIPTION \u2014 requests use your existing Copilot sign-in and model; Anyray supplies a supported before-request optimization provider.","Inline completions remain native GitHub Copilot traffic. Choose an \u201CAnyray \xB7 \u2026\u201D model in Chat for optimized requests.",'Copilot\u2019s internal utility models (chat titles, summaries) keep working with an Anyray main model: the extension sets VS Code\u2019s chat.byokUtilityModelDefault to "copilot" unless you already set it yourself.',"VS Code profiles scope extensions; Connect installs the provider into every profile registered at apply time. A profile created later needs a Connect re-run (or VS Code\u2019s \u201CApply Extension to all Profiles\u201D action).","Copilot Business/Enterprise administrators must allow language-model providers in GitHub\u2019s Bring Your Own Language Model Key policy."],ok=(e,t,n,r)=>({runMcp:o=>QP(e,o,t,n,r),runLegacy:o=>n?Promise.resolve({changedFiles:[],messages:[],manual:!1}):JP(e,o)}),tT=async(e,t,n,r,o,a,s)=>{let{runMcp:i,runLegacy:c}=ok(e,o,a,s);if(!t.clientKey)return{status:"manual",messages:["A personal gateway key is required for the authenticated Anyray VS Code provider. Re-run anyray-connect with --enroll, then apply Copilot again."]};if(n.dryRun){let p=await c(!0),h=await i(!0);return{status:p.manual||h.manual?"manual":"configured",messages:[`Would install the bundled ${Pe} VSIX with the ${e} CLI and configure it through VS Code SecretStorage.`,...Kb(t),...h.messages,...p.messages]}}let l=await i(!0);if(l.manual)return{status:"manual",messages:[`Did not configure ${Pe}; resolve the retrieval MCP profile conflicts first.`,...l.messages]};let d=await r(e,t,"configure",{},{mode:"copilot-seat"});if(!d.ok)return{status:"manual",messages:[d.reason==="reload-required"?`A newer ${Pe} build was installed, but ${e} is still running the previous build. Reload VS Code completely, then re-run anyray-connect.`:d.reason==="cli-not-found"?`The ${e} data directory exists, but its command-line launcher was not found. Install the \u201Ccode\u201D command in PATH and re-run anyray-connect.`:d.reason==="unsupported-version"?`The Anyray language-model provider requires VS Code ${wc} or newer. Upgrade ${e}, then re-run anyray-connect; no extension configuration was written.`:d.reason==="unsafe-gateway"?"The Anyray VS Code provider requires HTTPS for a remote gateway because it sends a personal key and prompt content. Publish a trusted TLS gateway URL (or use literal loopback HTTP), then re-run anyray-connect.":d.reason==="extension-missing"?`This anyray-connect installation is missing its bundled ${Pe} VSIX. Reinstall a complete anyray-connect release; no Marketplace fallback was attempted.`:`VS Code did not confirm the one-time ${Pe} configuration. Open VS Code and re-run anyray-connect.`]};let u=await c(!1),f=await i(!1);return{status:u.manual||f.manual?"manual":"configured",changedFiles:[d.receipt,...f.changedFiles,...u.changedFiles],messages:[...d.alreadyCurrent?[rk()]:[],...Kb(t),...d.alreadyCurrent?[]:nk(d.profiles),...f.messages,...u.messages]}},Gb=e=>[`${Pe} exposes the configured Anyray gateway models without writing a key to chatLanguageModels.json.`,`Gateway: ${e.origin} (personal client key and attribution stored together in VS Code SecretStorage).`,"Mode: API KEY \u2014 the extension streams normal /v1/chat/completions requests through Anyray. Text chat only: the models register without tool calling (the OpenAI bridge cannot carry VS Code's structured tool results).",`Models in the picker: ${Ts().join(", ")}.`,"Inline GitHub Copilot completions remain native GitHub traffic; choose an Anyray model in Chat for gateway-routed requests.",'Copilot\u2019s internal utility models (chat titles, summaries) follow the selected Anyray model: the extension sets VS Code\u2019s chat.byokUtilityModelDefault to "mainAgent" unless you already set it yourself.',"VS Code profiles scope extensions; Connect installs the provider into every profile registered at apply time. A profile created later needs a Connect re-run (or VS Code\u2019s \u201CApply Extension to all Profiles\u201D action).","Copilot Business/Enterprise administrators must allow language-model providers in GitHub\u2019s Bring Your Own Language Model Key policy."],nT=async(e,t,n,r,o,a,s)=>{let{runMcp:i,runLegacy:c}=ok(e,o,a,s);if(!t.clientKey)return{status:"manual",messages:["A personal gateway key is required."]};if(n.dryRun){let p=await c(!0),h=await i(!0);return{status:p.manual||h.manual?"manual":"configured",messages:[`Would install the bundled ${Pe} VSIX with the ${e} CLI and configure gateway API mode through VS Code SecretStorage.`,...Gb(t),...h.messages,...p.messages]}}let l=await i(!0);if(l.manual)return{status:"manual",messages:[`Did not configure ${Pe}; resolve the retrieval MCP profile conflicts first.`,...l.messages]};let d=await r(e,t,"configure",{},{mode:"gateway-api",gatewayModels:Ts().map(p=>({id:p,name:Xb(p)}))});if(!d.ok)return{status:"manual",messages:[d.reason==="reload-required"?`A newer ${Pe} build was installed, but ${e} is still running the previous build. Reload VS Code completely, then re-run anyray-connect.`:d.reason==="cli-not-found"?`The ${e} data directory exists, but its command-line launcher was not found. Install the \u201Ccode\u201D command in PATH and re-run anyray-connect.`:d.reason==="unsupported-version"?`The Anyray language-model provider requires VS Code ${wc} or newer. Upgrade ${e}, then re-run anyray-connect; no extension configuration was written.`:d.reason==="unsafe-gateway"?"The Anyray VS Code provider requires HTTPS for a remote gateway because it sends a personal key and prompt content. Publish a trusted TLS gateway URL (or use literal loopback HTTP), then re-run anyray-connect.":d.reason==="extension-missing"?`This anyray-connect installation is missing its bundled ${Pe} VSIX. Reinstall a complete anyray-connect release; no Marketplace fallback was attempted.`:`VS Code did not confirm the one-time ${Pe} gateway API configuration. Open VS Code and re-run anyray-connect.`]};let u=await c(!1),f=await i(!1);return{status:u.manual||f.manual?"manual":"configured",changedFiles:[d.receipt,...f.changedFiles,...u.changedFiles],messages:[...d.alreadyCurrent?[rk()]:[],...Gb(t),...d.alreadyCurrent?[]:nk(d.profiles),...f.messages,...u.messages]}},rT=async(e,t,n)=>{let r=await n.vscodeUserMcpConfigPaths(e,t);if(r.length===0)return{registered:!1,command:null};let o=[];for(let s of r){if(!await O(s))return{registered:!1,command:null};try{let i=await M(s),c=vt(i.servers)?i.servers[fn]:void 0;if(!tk(c,n))return{registered:!1,command:null};o.push(c.command)}catch{return{registered:!1,command:null}}}let a=o[0]||null;return{registered:!0,command:o.every(s=>s===a)?a:null}};var oT=async(e={installedVariant:kc,remoteServerVariant:tp,isRemoteDevContext:qa})=>{let t=await e.installedVariant();if(t)return{variant:t,remote:!1};if(!e.isRemoteDevContext())return{remote:!1};let n=await e.remoteServerVariant();return n?{variant:n,remote:!0}:{remote:!1}},aT={installedVariant:kc,remoteServerVariant:tp,detectVscodeLmProviderEligibility:aw,configureVscodeExtension:Fb,vscodeExtensionPointsAt:Hb,vscodeExtensionAwaitingReload:Bb,vscodeExtensionReceiptMode:Ub,hookBinaryIsDurable:ce,hookBinaryPath:Re,mcpServerCommand:Ge,vscodeUserMcpConfigPaths:rw,isRemoteDevContext:qa},sT=(e={})=>{let t={...aT,...e},n=()=>oT(t);return{id:"copilot",title:"GitHub Copilot Chat",automatic:!0,quitGated:{isRunning:Es,quitTarget:Zc},async detect(){let{variant:r,remote:o}=await n();return r?{installed:!0,detail:o?`remote server at ${Fo(r,!0)}`:Rs(r)}:{installed:!1,detail:"no VS Code install found"}},async apply(r,o){if(!Ie(r.clientKey))return{status:"manual",messages:["Enrollment required: Copilot setup needs a personal ark_ gateway key. Re-run anyray-connect with --enroll or --sso; no VS Code configuration was written."]};let{variant:a,remote:s}=await n();if(!a)return{status:"manual",messages:[t.isRemoteDevContext()?"No VS Code server found here yet \u2014 this looks like a dev container, Codespace, or SSH remote. `--tools copilot` now configures the Anyray provider directly in a remote VS Code window, but only after VS Code has attached to this machine and installed its server. Open this machine with the VS Code Remote-SSH (or Dev Containers) extension, then re-run anyray-connect --tools copilot in that window\u2019s integrated terminal. To route this shell through Anyray without the Copilot UI, use an in-container tool instead: anyray-connect --tools opencode --sso <link> --subscription.":"No VS Code install found. Install VS Code, then re-run anyray-connect; the personal key will be transferred directly into SecretStorage."]};let i=await t.detectVscodeLmProviderEligibility(a);if(i.status==="needs-update")return{status:"manual",messages:[`${a} ${i.version??""} cannot expose public third-party models in Chat's picker. Upgrade to VS Code ${wc} or newer, then re-run anyray-connect; no extension configuration was written.`]};let c=i.version===void 0||Qg(i.version);return q(r,"copilot")?tT(a,r,o,t.configureVscodeExtension,c,s,t):nT(a,r,o,t.configureVscodeExtension,c,s,t)},async mcpStatus(){let{variant:r,remote:o}=await n();return r?rT(r,o,t):{registered:!1,command:null}},async pointsAt(r){let{variant:o}=await n();if(!o)return!1;let a=Os(r);if(!a)return!1;if(await t.vscodeExtensionPointsAt(o,a))return!0;let s=await Jc(Rs(o));if(s.kind==="array"){let c=s.entries.find(Up)?.models?.[0]?.url;if(typeof c=="string"&&new URL(c).origin===a)return!0}return!1},async routingExpected(r){if(r.includes("copilot"))return!0;let{variant:o}=await n();return o?(await t.detectVscodeLmProviderEligibility(o)).status!=="needs-update":!1},async routingPendingReload(){let{variant:r}=await n();return r?t.vscodeExtensionAwaitingReload(r):!1},async inferenceAuthLanes(){try{let{variant:r}=await n();if(!r)return["unknown"];let o=await Jc(Rs(r));if(o.kind==="array"&&o.entries.some(Up))return["api_key"];let a=await t.vscodeExtensionReceiptMode(r);if(a==="copilot-seat")return["subscription"];if(a==="gateway-api")return["api_key"]}catch{}return["unknown"]},async revert(r){let{variant:o,remote:a}=await n();if(!o)return{status:"not-found",messages:["no VS Code install found \u2014 nothing to revert"]};let s=await eT(o,r.dryRun,a,t),i=a?{changedFiles:[],messages:[],manual:!1}:await zb(o,r.dryRun),c=!1,l=!1,d,u=[...i.messages];if(r.dryRun)u.push(`would ask ${Pe} to clear its global configuration and SecretStorage key`);else{let y=await t.configureVscodeExtension(o,void 0,"reset");y.ok?(c=!0,d=y.receipt,u.push(`Cleared ${Pe} gateway configuration and secret.`)):(l=!0,u.push(y.reason==="cli-not-found"?`The ${o} command-line launcher was not found, so Anyray could not ask ${Pe} to clear its SecretStorage configuration. Install the launcher and re-run revert.`:`VS Code did not confirm the ${Pe} reset. Open VS Code and re-run revert.`))}let f=Rs(o),p=await Jc(f),h=p.kind==="missing"||p.kind==="array"&&!Hp(p.entries).removed,m=[...s.changedFiles,...i.changedFiles,...d?[d]:[]];if(u.push(...s.messages),h)return r.dryRun||c?{status:i.manual?"manual":"reverted",changedFiles:m.length?m:void 0,messages:u}:l||i.manual?{status:"manual",changedFiles:m.length?m:void 0,messages:u}:i.changedFiles.length||s.changedFiles.length?{status:"reverted",changedFiles:m,messages:u}:{status:"not-found",messages:["nothing to revert"]};if(p.kind==="unrecognized")return{status:"manual",changedFiles:m.length?m:void 0,messages:[...u,`Couldn't recognize ${f} \u2014 remove the "${ur}" Custom Endpoint by hand: Chat model picker \u2192 "Manage Language Models\u2026".`]};let{next:w}=Hp(p.entries);if(r.dryRun)return{status:"reverted",messages:[...u,`would remove the ${ur} Custom Endpoint from ${f}`]};await Jb(f,w);let g=[...u,`Removed the ${ur} Custom Endpoint from ${f}.`];return await oe(f),{status:l||i.manual?"manual":"reverted",changedFiles:[...m,f],messages:g}}}},ak=sT();import{accessSync as OT,constants as yk,statSync as RT}from"node:fs";import{readFile as gk,rm as Ds}from"node:fs/promises";import{homedir as qp,platform as Sk}from"node:os";import{delimiter as _T,join as Qp,resolve as PT}from"node:path";import{execFile as uT}from"node:child_process";import{readFile as pT}from"node:fs/promises";import{homedir as jp,platform as fT}from"node:os";import{join as Ls}from"node:path";import{join as iT}from"node:path";var Kp="Iv1.b507a08c87ecfe98",cT="https://github.com/login/device/code",lT="https://github.com/login/oauth/access_token",dT="read:user",sk=1e4,jo=()=>iT(Q(),"copilot-seat-login.json"),ik={fetch:(...e)=>fetch(...e),now:()=>Date.now(),sleep:e=>new Promise(t=>setTimeout(t,e))},Gp=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),ck=async(e={})=>{let t={...ik,...e};try{let n=await t.fetch(cT,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({client_id:Kp,scope:dT}),signal:AbortSignal.timeout(sk)});if(!n.ok)return;let r=await n.json();if(!Gp(r))return;let o=r.device_code,a=r.user_code,s=r.verification_uri;if(typeof o!="string"||typeof a!="string"||typeof s!="string")return;let i=r.interval,c=r.expires_in;return{deviceCode:o,userCode:a,verificationUri:s,intervalSeconds:typeof i=="number"&&i>0?i:5,expiresInSeconds:typeof c=="number"&&c>0?c:900}}catch{return}},lk=async(e,t={})=>{let n={...ik,...t},r=n.now()+e.expiresInSeconds*1e3,o=e.intervalSeconds*1e3;for(;n.now()<r;){await n.sleep(o);try{let s=await(await n.fetch(lT,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({client_id:Kp,device_code:e.deviceCode,grant_type:"urn:ietf:params:oauth:grant-type:device_code"}),signal:AbortSignal.timeout(sk)})).json();if(!Gp(s))continue;let i=s.access_token;if(typeof i=="string"&&i.length>0)return{status:"ok",token:i};let c=s.error;if(c==="authorization_pending")continue;if(c==="slow_down"){let l=s.interval;o=(typeof l=="number"&&l>0?l:o/1e3+5)*1e3;continue}return c==="access_denied"?{status:"denied"}:c==="expired_token"?{status:"expired"}:{status:"failed"}}catch{continue}}return{status:"expired"}},dk=async(e,t)=>{let n=jo();return await fe(n,`${JSON.stringify({token:e,clientId:Kp,mintedAtIso:t},null,2)}
|
|
112
|
-
`),n},qc=async()=>{try{let e=await M(jo());if(!Gp(e))return;let t=e.token;return typeof t=="string"&&t.length>0?t:void 0}catch{return}};var hT=5e3,Vp=5e3,mT=["copilot-cli","CopilotCLI"],yT="https://api.github.com/copilot_internal/user",pk="~/.copilot/config.json",fk="macOS Keychain (Copilot CLI)",hk=e=>e===pk||e===fk,Vo=e=>typeof e=="string"&&/^[\x21-\x7e]{20,255}$/.test(e),zt=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),gT=()=>process.env.XDG_CONFIG_HOME?.trim()||Ls(jp(),".config"),wT=()=>process.env.XDG_DATA_HOME?.trim()||Ls(jp(),".local","share"),bT=async()=>{try{let e=await pT(Ls(jp(),".copilot","config.json"),"utf-8"),t=/\bgh[ou]_[A-Za-z0-9_]{16,251}/.exec(e)?.[0];return Vo(t)?t:void 0}catch{}},kT=async e=>{try{let t=await M(Ls(gT(),"github-copilot",e));if(!zt(t))return;for(let n of Object.values(t))if(zt(n)&&Vo(n.oauth_token))return n.oauth_token}catch{}},AT=async()=>{try{let e=await M(Ls(wT(),"opencode","auth.json")),t=zt(e)?e["github-copilot"]:void 0;if(!zt(t)||t.type!=="oauth")return;if(Vo(t.access))return t.access;if(Vo(t.refresh))return t.refresh}catch{}},CT=(e,t)=>new Promise((n,r)=>{try{uT(e,[...t],{timeout:hT},(a,s)=>{a?r(a):n({stdout:s})}).on("error",r)}catch(o){r(o)}}),vT=async(e,t)=>{try{let{stdout:n}=await t("security",["find-generic-password","-s",e,"-w"]),r=n?.trim();return Vo(r)?r:void 0}catch{return}},ST=async(e=CT)=>{for(let t of mT){let n=await vT(t,e);if(n)return n}};var Qc={env:process.env,platform:fT,tokenFromDeviceLogin:qc,tokenFromCopilotCliConfig:bT,tokenFromSharedConfig:kT,tokenFromOpenCode:AT,tokenFromKeychain:ST,fetch:(...e)=>fetch(...e)},ET=new Set([401,403,404]),mk=/^[a-z][a-z0-9-]{0,30}$/,xT=e=>e!=="default"&&mk.test(e)?`https://api.${e}.githubcopilot.com`:"https://api.githubcopilot.com",IT=e=>typeof e!="string"?"default":/^https:\/\/api\.([a-z][a-z0-9-]{0,30})\.githubcopilot\.com\/?$/.exec(e.trim())?.[1]??"default",Yp=async(e,t={})=>{let n={...Qc,...t},r=new AbortController,o=setTimeout(()=>r.abort(),Vp);try{let a=await n.fetch(yT,{headers:{authorization:`Bearer ${e}`},signal:r.signal});if(a.ok){let s;try{let i=await a.json();s=zt(i)&&zt(i.endpoints)?i.endpoints.api:void 0}catch{}return{verdict:"valid",capiSegment:IT(s)}}return{verdict:ET.has(a.status)?"no-copilot":"unreachable",capiSegment:"default"}}catch{return{verdict:"unreachable",capiSegment:"default"}}finally{clearTimeout(o)}};var Yo=async(e,t={},n="default",r)=>{if(r){let o=`${r.laneOrigin.replace(/\/+$/,"")}/v1/copilot/${mk.test(n)?n:"default"}/header/models`,a=await uk(o,e,r.clientKey,t);if(a.length>0)return a}return uk(`${xT(n)}/models`,e,void 0,t)},uk=async(e,t,n,r={})=>{let o={...Qc,...r},a=new AbortController,s=setTimeout(()=>a.abort(),Vp);try{let i=await o.fetch(e,{headers:{authorization:`Bearer ${t}`,...n?{"x-anyray-api-key":n}:{}},signal:a.signal});if(!i.ok)return[];let c=await i.json(),l=zt(c)?c.data:void 0;if(!Array.isArray(l))return[];let d=[];for(let u of l){if(!zt(u))continue;let f=u.id;if(typeof f!="string"||f.length===0||u.model_picker_enabled!==!0)continue;let p=u.policy;if(zt(p)&&p.state!=="enabled")continue;let h=u.supported_endpoints,m=Array.isArray(h)?h.filter(E=>typeof E=="string"):[],w=u.capabilities,g=zt(w)?w.limits:void 0,y=E=>{let x=zt(g)?g[E]:void 0;return typeof x=="number"&&Number.isFinite(x)&&x>0?Math.floor(x):void 0},b={id:f,endpoints:m},C=y("max_prompt_tokens"),S=y("max_output_tokens");C!==void 0&&(b.maxPromptTokens=C),S!==void 0&&(b.maxOutputTokens=S),d.push(b)}return d}catch{return[]}finally{clearTimeout(s)}},el=async(e,t,n,r={})=>{let o={...Qc,...r},a=new AbortController,s=setTimeout(()=>a.abort(),Vp);try{let i=/\/responses\/?$/.test(new URL(e).pathname),c=await o.fetch(e,{method:"POST",headers:{...t,"content-type":"application/json"},body:JSON.stringify(i?{model:n,max_output_tokens:16,input:"ping"}:{model:n,max_tokens:1,messages:[{role:"user",content:"ping"}]}),signal:a.signal});return c.ok?"ok":c.status===400||c.status===404||c.status===422?"rejected":"unreachable"}catch{return"unreachable"}finally{clearTimeout(s)}},tl=async(e={},t={})=>{let n={...Qc,...t},r=[{source:"COPILOT_GITHUB_TOKEN",read:async()=>{let a=n.env.COPILOT_GITHUB_TOKEN?.trim();return Vo(a)?a:void 0}},{source:"~/.config/github-copilot/apps.json",read:()=>n.tokenFromSharedConfig("apps.json")},{source:"~/.config/github-copilot/hosts.json",read:()=>n.tokenFromSharedConfig("hosts.json")},{source:"OpenCode github-copilot login",read:()=>n.tokenFromOpenCode()},{source:"Anyray Copilot sign-in (device login)",read:()=>n.tokenFromDeviceLogin()},...e.allowKeychainPrompt===!0&&n.platform()==="darwin"?[{source:fk,read:()=>n.tokenFromKeychain()}]:[],{source:pk,read:()=>n.tokenFromCopilotCliConfig()}],o=[];for(let a of r){let s=await a.read();if(!s)continue;let i=await Yp(s,t);if(i.verdict==="no-copilot"){o.push(a.source);continue}return{token:{token:s,source:a.source},rejected:o,capiSegment:i.capiSegment}}return{rejected:o}};var Jr="copilot-cli",hn="copilot-cli",TT=Es,LT=()=>TT()?["VS Code is open \u2014 its Copilot CLI runs inside the extension host, which","captured your shell environment when the editor launched. Restart VS Code,","or its CLI chat and Autopilot sessions stay on native GitHub traffic and","never reach the gateway (no spend, no traces) even though this block is set."]:[],Ek=["Editor-Version: vscode/1.99.0","Editor-Plugin-Version: copilot-chat/0.26.7","Copilot-Integration-Id: vscode-chat"],ef=()=>Object.fromEntries(Ek.map(e=>{let t=e.indexOf(": ");return[e.slice(0,t).toLowerCase(),e.slice(t+2)]})),Zp=()=>Qp(qp(),".anyray","copilot-cli.sh"),xk="# Managed by anyray-connect. Do not source this file anywhere else.",wk=e=>e.split(/\r?\n/,1)[0]===xk,DT=["COPILOT_PROVIDER_TYPE","COPILOT_PROVIDER_BASE_URL","COPILOT_PROVIDER_WIRE_API","COPILOT_PROVIDER_HEADERS","COPILOT_MODEL","COPILOT_PROVIDER_MAX_PROMPT_TOKENS","COPILOT_PROVIDER_MAX_OUTPUT_TOKENS","COPILOT_PROVIDER_API_KEY"],nl="COPILOT_PROVIDER_API_KEY",bk=e=>e.startsWith(`export ${nl}=`)||e.startsWith("export COPILOT_PROVIDER_HEADERS=")&&e.includes("x-anyray-api-key:"),_n=e=>/(^|\/)(gpt-5|o[1-9])[\w.-]*$/.test(e)?"responses":"completions",NT=()=>Ts()[0],Ns=(e="default")=>`/copilot/${e}/header`,
|
|
112
|
+
`),n},qc=async()=>{try{let e=await M(jo());if(!Gp(e))return;let t=e.token;return typeof t=="string"&&t.length>0?t:void 0}catch{return}};var hT=5e3,Vp=5e3,mT=["copilot-cli","CopilotCLI"],yT="https://api.github.com/copilot_internal/user",pk="~/.copilot/config.json",fk="macOS Keychain (Copilot CLI)",hk=e=>e===pk||e===fk,Vo=e=>typeof e=="string"&&/^[\x21-\x7e]{20,255}$/.test(e),zt=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),gT=()=>process.env.XDG_CONFIG_HOME?.trim()||Ls(jp(),".config"),wT=()=>process.env.XDG_DATA_HOME?.trim()||Ls(jp(),".local","share"),bT=async()=>{try{let e=await pT(Ls(jp(),".copilot","config.json"),"utf-8"),t=/\bgh[ou]_[A-Za-z0-9_]{16,251}/.exec(e)?.[0];return Vo(t)?t:void 0}catch{}},kT=async e=>{try{let t=await M(Ls(gT(),"github-copilot",e));if(!zt(t))return;for(let n of Object.values(t))if(zt(n)&&Vo(n.oauth_token))return n.oauth_token}catch{}},AT=async()=>{try{let e=await M(Ls(wT(),"opencode","auth.json")),t=zt(e)?e["github-copilot"]:void 0;if(!zt(t)||t.type!=="oauth")return;if(Vo(t.access))return t.access;if(Vo(t.refresh))return t.refresh}catch{}},CT=(e,t)=>new Promise((n,r)=>{try{uT(e,[...t],{timeout:hT},(a,s)=>{a?r(a):n({stdout:s})}).on("error",r)}catch(o){r(o)}}),vT=async(e,t)=>{try{let{stdout:n}=await t("security",["find-generic-password","-s",e,"-w"]),r=n?.trim();return Vo(r)?r:void 0}catch{return}},ST=async(e=CT)=>{for(let t of mT){let n=await vT(t,e);if(n)return n}};var Qc={env:process.env,platform:fT,tokenFromDeviceLogin:qc,tokenFromCopilotCliConfig:bT,tokenFromSharedConfig:kT,tokenFromOpenCode:AT,tokenFromKeychain:ST,fetch:(...e)=>fetch(...e)},ET=new Set([401,403,404]),mk=/^[a-z][a-z0-9-]{0,30}$/,xT=e=>e!=="default"&&mk.test(e)?`https://api.${e}.githubcopilot.com`:"https://api.githubcopilot.com",IT=e=>typeof e!="string"?"default":/^https:\/\/api\.([a-z][a-z0-9-]{0,30})\.githubcopilot\.com\/?$/.exec(e.trim())?.[1]??"default",Yp=async(e,t={})=>{let n={...Qc,...t},r=new AbortController,o=setTimeout(()=>r.abort(),Vp);try{let a=await n.fetch(yT,{headers:{authorization:`Bearer ${e}`},signal:r.signal});if(a.ok){let s;try{let i=await a.json();s=zt(i)&&zt(i.endpoints)?i.endpoints.api:void 0}catch{}return{verdict:"valid",capiSegment:IT(s)}}return{verdict:ET.has(a.status)?"no-copilot":"unreachable",capiSegment:"default"}}catch{return{verdict:"unreachable",capiSegment:"default"}}finally{clearTimeout(o)}};var Yo=async(e,t={},n="default",r)=>{if(r){let o=`${r.laneOrigin.replace(/\/+$/,"")}/v1/copilot/${mk.test(n)?n:"default"}/header/models`,a=await uk(o,e,r.clientKey,t);if(a.length>0)return a}return uk(`${xT(n)}/models`,e,void 0,t)},uk=async(e,t,n,r={})=>{let o={...Qc,...r},a=new AbortController,s=setTimeout(()=>a.abort(),Vp);try{let i=await o.fetch(e,{headers:{authorization:`Bearer ${t}`,...n?{"x-anyray-api-key":n}:{}},signal:a.signal});if(!i.ok)return[];let c=await i.json(),l=zt(c)?c.data:void 0;if(!Array.isArray(l))return[];let d=[];for(let u of l){if(!zt(u))continue;let f=u.id;if(typeof f!="string"||f.length===0||u.model_picker_enabled!==!0)continue;let p=u.policy;if(zt(p)&&p.state!=="enabled")continue;let h=u.supported_endpoints,m=Array.isArray(h)?h.filter(E=>typeof E=="string"):[],w=u.capabilities,g=zt(w)?w.limits:void 0,y=E=>{let x=zt(g)?g[E]:void 0;return typeof x=="number"&&Number.isFinite(x)&&x>0?Math.floor(x):void 0},b={id:f,endpoints:m},C=y("max_prompt_tokens"),S=y("max_output_tokens");C!==void 0&&(b.maxPromptTokens=C),S!==void 0&&(b.maxOutputTokens=S),d.push(b)}return d}catch{return[]}finally{clearTimeout(s)}},el=async(e,t,n,r={})=>{let o={...Qc,...r},a=new AbortController,s=setTimeout(()=>a.abort(),Vp);try{let i=/\/responses\/?$/.test(new URL(e).pathname),c=await o.fetch(e,{method:"POST",headers:{...t,"content-type":"application/json"},body:JSON.stringify(i?{model:n,max_output_tokens:16,input:"ping"}:{model:n,max_tokens:1,messages:[{role:"user",content:"ping"}]}),signal:a.signal});return c.ok?"ok":c.status===400||c.status===404||c.status===422?"rejected":"unreachable"}catch{return"unreachable"}finally{clearTimeout(s)}},tl=async(e={},t={})=>{let n={...Qc,...t},r=[{source:"COPILOT_GITHUB_TOKEN",read:async()=>{let a=n.env.COPILOT_GITHUB_TOKEN?.trim();return Vo(a)?a:void 0}},{source:"~/.config/github-copilot/apps.json",read:()=>n.tokenFromSharedConfig("apps.json")},{source:"~/.config/github-copilot/hosts.json",read:()=>n.tokenFromSharedConfig("hosts.json")},{source:"OpenCode github-copilot login",read:()=>n.tokenFromOpenCode()},{source:"Anyray Copilot sign-in (device login)",read:()=>n.tokenFromDeviceLogin()},...e.allowKeychainPrompt===!0&&n.platform()==="darwin"?[{source:fk,read:()=>n.tokenFromKeychain()}]:[],{source:pk,read:()=>n.tokenFromCopilotCliConfig()}],o=[];for(let a of r){let s=await a.read();if(!s)continue;let i=await Yp(s,t);if(i.verdict==="no-copilot"){o.push(a.source);continue}return{token:{token:s,source:a.source},rejected:o,capiSegment:i.capiSegment}}return{rejected:o}};var Jr="copilot-cli",hn="copilot-cli",TT=Es,LT=()=>TT()?["VS Code is open \u2014 its Copilot CLI runs inside the extension host, which","captured your shell environment when the editor launched. Restart VS Code,","or its CLI chat and Autopilot sessions stay on native GitHub traffic and","never reach the gateway (no spend, no traces) even though this block is set."]:[],Ek=["Editor-Version: vscode/1.99.0","Editor-Plugin-Version: copilot-chat/0.26.7","Copilot-Integration-Id: vscode-chat"],ef=()=>Object.fromEntries(Ek.map(e=>{let t=e.indexOf(": ");return[e.slice(0,t).toLowerCase(),e.slice(t+2)]})),Zp=()=>Qp(qp(),".anyray","copilot-cli.sh"),xk="# Managed by anyray-connect. Do not source this file anywhere else.",wk=e=>e.split(/\r?\n/,1)[0]===xk,DT=["COPILOT_PROVIDER_TYPE","COPILOT_PROVIDER_BASE_URL","COPILOT_PROVIDER_WIRE_API","COPILOT_PROVIDER_HEADERS","COPILOT_MODEL","COPILOT_PROVIDER_MAX_PROMPT_TOKENS","COPILOT_PROVIDER_MAX_OUTPUT_TOKENS","COPILOT_PROVIDER_API_KEY"],nl="COPILOT_PROVIDER_API_KEY",bk=e=>e.startsWith(`export ${nl}=`)||e.startsWith("export COPILOT_PROVIDER_HEADERS=")&&e.includes("x-anyray-api-key:"),_n=e=>/(^|\/)(gpt-5|o[1-9])[\w.-]*$/.test(e)?"responses":"completions",NT=()=>Ts()[0],Ns=(e="default")=>`/copilot/${e}/header`,K3=Ns(),Zr=e=>e.replace(/\/+$/,""),$T=(e,t="default")=>`${Zr(e.openaiBaseUrl)}${Ns(t)}`,Xp=e=>/\/v1\/copilot\/[^/]+\/header\/?$/.test(e),zp="claude-sonnet-5",MT=()=>{let e=Ts()[0];return e===Ps?zp:e},Ik=e=>e.endpoints.includes(_n(e.id)==="responses"?"/responses":"/chat/completions"),tf=e=>{let t=e.filter(Ik),n=a=>{let s=/^claude-sonnet-(\d+(?:\.\d+)*)$/.exec(a);return s?s[1].split(".").map(Number):void 0},r=t.map(a=>({m:a,version:n(a.id)})).filter(a=>!!a.version).sort((a,s)=>kk(a.version,s.version)?-1:kk(s.version,a.version)?1:0).map(a=>a.m),o=t.filter(a=>!n(a.id));return[...r,...o]};var kk=(e,t)=>{for(let n=0;n<Math.max(e.length,t.length);n+=1){let r=(e[n]??0)-(t[n]??0);if(r!==0)return r>0}return!1},Ak=(e,t,n,r,o,a="default")=>{let s=le({...e.metadata,tool:Jr}),i=[...r?[`x-anyray-api-key: ${r}`]:[],...s?[`x-anyray-metadata: ${s}`]:[],...Ek];return["export COPILOT_PROVIDER_TYPE='openai'",`export COPILOT_PROVIDER_BASE_URL=${Ee($T(e,a))}`,`export COPILOT_PROVIDER_WIRE_API='${_n(t)}'`,`export COPILOT_MODEL=${Ee(t)}`,...o?.maxPromptTokens?[`export COPILOT_PROVIDER_MAX_PROMPT_TOKENS='${o.maxPromptTokens}'`]:[],...o?.maxOutputTokens?[`export COPILOT_PROVIDER_MAX_OUTPUT_TOKENS='${o.maxOutputTokens}'`]:[],...i.length>0?[`export COPILOT_PROVIDER_HEADERS=${Ee(i.join(`
|
|
113
113
|
`))}`]:[],`export ${nl}=${Ee(n)}`]},Jp=(e,t,n)=>{let r=le({...e.metadata,tool:Jr});return["export COPILOT_PROVIDER_TYPE='openai'",`export COPILOT_PROVIDER_BASE_URL=${Ee(e.openaiBaseUrl)}`,`export COPILOT_PROVIDER_WIRE_API='${_n(t)}'`,`export COPILOT_MODEL=${Ee(t)}`,...r?[`export COPILOT_PROVIDER_HEADERS=${Ee(`x-anyray-metadata: ${r}`)}`]:[],...n?[`export ${nl}=${Ee(n)}`]:[]]},FT=(e,t)=>t||!q(e,"copilot"),Ck=()=>{let e=DT.filter(t=>(process.env[t]??"")!=="");return e.length===0?[]:[`This shell still exports ${e.join(", ")} \u2014 Copilot CLI keeps using BYOK until you`,`run \`unset ${e.join(" ")}\` or open a new terminal (fully quit a long-lived parent app).`]},vk=(e,t=[])=>["Left on native GitHub Copilot inference \u2014 a Copilot seat was detected, but no","Copilot sign-in Connect can read. To route the CLI through Anyray with billing","KEPT on your Copilot plan, give Connect a seat token and re-run:",...e==="darwin"?[" - run `copilot` once and `/login` (macOS Keychain; read on",` \`anyray-connect --tools ${Jr}\`), or`]:[" - run `copilot` once and `/login` (say YES to storing credentials locally),"," then re-run \u2014 Connect reads the sign-in left in ~/.copilot/ or"," ~/.config/github-copilot/ on any run, with no extra flag, or"]," - set COPILOT_GITHUB_TOKEN to a Copilot OAuth token, or sign into"," OpenCode\u2019s github-copilot provider.",...t.length>0?[`GitHub rejected the sign-in Connect did find (${t.join(", ")}):`,"it is expired, or its account holds no Copilot seat. Sign in again."]:[],"To route on org API billing instead (replaces seat inference), re-run with `--org`."],BT=(e=process.env.PATH,t=Sk())=>{if(!e)return;let n=t==="win32"?"copilot.exe":"copilot";for(let r of e.split(_T)){let o=r.trim().replace(/^"|"$/g,"");if(!o)continue;let a=PT(o,n);try{if(!RT(a).isFile())continue;return OT(a,t==="win32"?yk.F_OK:yk.X_OK),a}catch{}}},UT=()=>Qp(qp(),".copilot","config.json"),Rn=()=>Qp(qp(),".copilot","mcp-config.json"),Xr="anyray",HT=()=>({type:"local",...Ge("profile"),tools:["*"]}),pr=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),WT=async()=>{let e=Rn(),t;try{t=await M(e)}catch{return{status:"skipped",message:`Skipped the Anyray retrieval MCP server because ${e} could not be parsed; it was left unchanged.`}}if("mcpServers"in t&&!pr(t.mcpServers))return{status:"skipped",message:`Skipped the Anyray retrieval MCP server because mcpServers in ${e} is not an object; it was left unchanged.`};let r=(pr(t.mcpServers)?t.mcpServers:{})[Xr];return r!==void 0&&!Vt(r,"profile")?{status:"skipped",message:`MCP name conflict in ${e}: mcpServers.${Xr} is not owned by Anyray Connect, so retrieval was skipped and the existing server was left untouched.`}:{status:"installable",json:t}},KT=async e=>{let t=Rn(),n=e.json,r=pr(n.mcpServers)?n.mcpServers:{};r[Xr]=HT(),n.mcpServers=r,await Z(t,n)},GT=async()=>{let e=Rn(),t;try{let r=await M(e);if(!pr(r))return!1;t=r}catch{return!1}let n=t.mcpServers;return!pr(n)||!(Xr in n)||!Vt(n[Xr],"profile")?!1:(delete n[Xr],Object.keys(n).length===0&&delete t.mcpServers,Object.keys(t).length===0?await Ds(e,{force:!0}):await Z(e,t,{backup:!1}),await oe(e),!0)},jT={resolveCopilotCommand:BT,platform:Sk,detectCopilotSeat:np,discoverSeatToken:tl,readDeviceLoginToken:qc,fetchSeatModelCatalog:Yo,probeSeatChatModel:el},VT=e=>`'${e.replace(/'/g,"''")}'`,YT=e=>e.split(`
|
|
114
114
|
`).map(VT).join(" + [Environment]::NewLine + "),ZT=(e={})=>{let t={...jT,...e},n=()=>t.platform()==="win32",r=async()=>{let i=(await Lc(Ct(),hn))?.find(c=>c.startsWith("export COPILOT_PROVIDER_BASE_URL="));if(i)return i.slice(i.indexOf("=")+1).replace(/^'|'$/g,"")},o=(s,i)=>s!==void 0&&Zr(s)===`${Zr(i)}/v1`,a=(s,i)=>s!==void 0&&Xp(s)&&Zr(s).startsWith(`${Zr(i)}/v1/copilot/`);return{id:Jr,title:"GitHub Copilot CLI",automatic:!0,changesBilling:!1,quitGated:{isRunning:Es,quitTarget:Zc},async usesDynamicCredential(s){let i=await r();return a(i,s)||!o(i,s)?!1:!await O(Zp())},async detect(){let s=t.resolveCopilotCommand();if(s)return{installed:!0,detail:s};let i=UT();return await O(i)?{installed:!0,detail:i}:{installed:!1,detail:"no `copilot` on PATH and no ~/.copilot state"}},async apply(s,i){let c=Ct(),l=async(E,x,A)=>{let I=E.filter(bk),R=E.filter(L=>!bk(L)),B=Zp(),V=[...R,...I.length>0?[`[ -r ${Ee(B)} ] && . ${Ee(B)}`]:[]],H=await O(B),X=H?await gk(B,"utf8"):void 0,ie=X===void 0||wk(X);if(I.length>0&&!ie)return{status:"manual",messages:[`Refused to overwrite user-managed ${B}; move or rename that file, then run Connect again.`]};let ye=ce(),Ue=ye?await WT():void 0,re=[`${c} \u2190 managed Anyray block (${hn})`,...x.map(L=>` ${L}`),...I.length>0?[`${B} \u2190 owner-only credential (mode 0600)`]:["No key exported \u2014 the local refresh daemon injects a freshly minted","key per request, so a running CLI session never carries a stale one."],...A,Ue?.status==="skipped"?Ue.message:ye?`${Rn()} \u2190 Anyray retrieval MCP server (anyray_retrieve / anyray_recall)`:`Skipped the Anyray MCP server \u2014 anyray-connect is running from a temporary path (${Re()}). Re-run via the installer or a global install to enable retrieval.`,"Inline `copilot` completions and GitHub-hosted features stay native GitHub traffic.",`Run \`source ${c}\` or open a new terminal to apply.`,...LT()];if(i.dryRun)return{status:"configured",messages:re};let je=!1;Ue?.status==="installable"&&(await KT(Ue),je=!0);try{I.length>0?await fe(B,[xk,...I,""].join(`
|
|
115
115
|
`)):H&&ie&&await Ds(B,{force:!0}),await Tc(c,V,hn)}catch(L){try{X!==void 0&&ie?await fe(B,X):ie&&await Ds(B,{force:!0})}catch{throw new Error("Copilot CLI environment update failed and credential rollback could not be completed")}throw L}return{status:"configured",messages:re,changedFiles:[c,...I.length>0||H&&ie?[B]:[],...je?[Rn()]:[]]}},d=await r(),u=d!==void 0&&!Xp(d),f=s.authMode==="placeholder",p=u&&!s.viaLocalProxy,h=u&&(!p||!q(s,"copilot")),m=f?void 0:await t.readDeviceLoginToken().catch(()=>{}),w=f||h&&!m?{rejected:[]}:await t.discoverSeatToken({allowKeychainPrompt:i.explicit===!0&&!i.dryRun}),g=w.token,y=w.rejected;if(g){let E=w.capiSegment??"default",x=MT(),A=x!==zp||!!process.env.ANYRAY_COPILOT_MODEL,I=await t.fetchSeatModelCatalog(g.token,{},E,{laneOrigin:Zr(s.origin),...s.clientKey?{clientKey:s.clientKey}:{}}),R=I.find(re=>re.id===x);if(!A){let re=tf(I);if(R=re[0],!i.dryRun&&re.length>0){let je=J=>`${Zr(s.origin)}/v1${Ns(E)}/${_n(J)==="responses"?"responses":"chat/completions"}`,L={...ef(),authorization:`Bearer ${g.token}`,...s.clientKey?{"x-anyray-api-key":s.clientKey}:{}},T=new Set,K;for(let J of re.slice(0,4)){let ge=await t.probeSeatChatModel(je(J.id),L,J.id);if(ge==="ok"){K=J;break}if(ge==="unreachable")break;T.add(J.id)}R=K??re.find(J=>!T.has(J.id))??re[0]}x=R?.id??zp}let B=s.viaLocalProxy?void 0:s.clientKey??s.placeholderKey,V=B&&s.clientKey?Lt(B):B,H=Ak(s,x,g.token,B,R,E),X=Ak(s,x,Lt(g.token),V,R,E),ie=_n(x),ye=I.filter(re=>Ik(re)&&_n(re.id)===ie).map(re=>re.id).filter(re=>re!==x),Ue=[`Mode: Copilot seat \u2014 requests route through the gateway's Copilot carrier lane and stay billed to your Copilot plan (seat token from ${g.source}).`,`Model: ${x}${A?" (pinned via ANYRAY_COPILOT_MODEL)":I.length>0?" (your plan's default class; pin via ANYRAY_COPILOT_MODEL)":" (seat-lane fallback; pin via ANYRAY_COPILOT_MODEL)"}.`,...I.length===0&&hk(g.source)?["GitHub served no current models for this sign-in \u2014 the Copilot CLI's own login is","entitled to legacy models only. Fix it with: `anyray-connect copilot-login`","(one browser step), then re-run this command."]:[],...ye.length>0?[`Your plan also serves: ${ye.slice(0,8).join(", ")}${ye.length>8?", \u2026":""} \u2014 switch anytime with \`copilot --model <id>\`.`]:[]];return n()?{status:"manual",messages:["Windows: run these in PowerShell (persists user env), then restart your terminal \u2014",...X.map(re=>{let je=re.indexOf("="),L=re.slice(7,je),T=re.slice(je+1).replace(/^'|'$/g,"");return` [Environment]::SetEnvironmentVariable('${L}', ${YT(T)}, 'User')`}),`(secrets are shown masked \u2014 substitute the Copilot token from ${g.source}, and the gateway key from \`anyray-connect print-key\`.)`,...Ue]}:l(H,X,Ue)}if(!FT(s,h)){if(p&&!i.dryRun){let E=Ct();if(await hs(E,hn))return{status:"reverted",changedFiles:[E],messages:[`removed a stale Anyray ${hn} block from ${E}`,"It routed the CLI on ORG API billing, which predates the Copilot","seat lane and is not a lane you chose. Nothing replaces it yet:",...vk(t.platform(),y),...Ck()]}}return{status:"held",messages:[...p&&i.dryRun?[`would remove a stale Anyray ${hn} block from ${Ct()} (org lane, not chosen)`]:[],...vk(t.platform(),y)]}}let b=NT(),C=s.viaLocalProxy?void 0:s.clientKey??s.placeholderKey,S=C&&s.clientKey?Lt(C):C;return n()?{status:"manual",messages:["Windows: set these for your user, then restart your terminal \u2014",...Jp(s,b,S).map(E=>{let[x,...A]=E.replace(/^export /,"").split("=");return` setx ${x} "${A.join("=").replace(/^'|'$/g,"")}"`}),...s.clientKey?[`(${nl} is shown masked \u2014 substitute the real one from \`anyray-connect print-key\`.)`]:[]]}:l(Jp(s,b,C),Jp(s,b,S),["Mode: BYOK \u2014 Copilot CLI requests are billed as org API usage through the gateway, not against your Copilot subscription.",`Model: ${b}${b===Ps?" (the gateway resolves the org default)":" (pinned via ANYRAY_COPILOT_MODEL)"}.`])},async revert(s){let i=Ct(),c=Zp(),l=await O(c),d=l?wk(await gk(c,"utf8")):!1;if(s.dryRun)return{status:"reverted",messages:[`would remove the Anyray ${hn} block from ${i}`,...d?[`would remove owner-only credential ${c}`]:l?[`would preserve user-managed ${c}`]:[],`would remove the Anyray MCP server from ${Rn()} if registered`,...await O(jo())?[`would remove the Copilot sign-in Connect minted (${jo()})`]:[]]};let u=await hs(i,hn);d&&await Ds(c,{force:!0});let f=await GT(),p=jo(),h=await O(p);h&&await Ds(p,{force:!0});let m=[...u?[i]:[],...d?[c]:[],...f?[Rn()]:[],...h?[p]:[]];return{status:m.length>0?"reverted":"not-found",messages:[u?`removed the Anyray ${hn} block from ${i}`:`no Anyray ${hn} block found in ${i}`,...d?[`removed owner-only credential ${c}`]:l?[`preserved user-managed ${c}`]:[],...h?[`removed the Copilot sign-in Connect minted (${p})`]:[],...f?[`removed the Anyray MCP server from ${Rn()}`]:[],...Ck()],changedFiles:m.length>0?m:void 0}},async pointsAt(s){let i=await r();return o(i,s)||a(i,s)},async mcpStatus(){try{let s=await M(Rn()),i=pr(s)?s.mcpServers:void 0,c=pr(i)?i[Xr]:void 0;return!pr(c)||!Vt(c,"profile")?{registered:!1,command:null}:{registered:!0,command:typeof c.command=="string"?c.command:null}}catch{return{registered:!1,command:null}}},async inferenceAuthLanes(){try{let s=await r();return s===void 0?["native"]:Xp(s)?["subscription"]:["api_key"]}catch{return["unknown"]}},async routingExpected(s){return s.includes(Jr)?!0:!await t.detectCopilotSeat()}}},Ok=ZT();import{homedir as $k}from"node:os";import{join as hr}from"node:path";import{constants as zT,chmod as qT,copyFile as QT,readFile as al}from"node:fs/promises";import{applyEdits as eL,modify as tL}from"jsonc-parser";import{readFile as Rk,rm as XT}from"node:fs/promises";var _k="// Managed by anyray-connect: OpenCode trim carrier v1",JT=5e3,nf=e=>`${_k}
|
|
@@ -688,7 +688,7 @@ Getting the export (you do this, not Anyray \u2014 it needs your Claude login):
|
|
|
688
688
|
`)&&g({kind:"ok",values:[]});continue}if(x==="\x1B[A"||x==="k")s=(s-1+e.items.length)%e.items.length,d();else if(x==="\x1B[B"||x==="j")s=(s+1)%e.items.length,d();else if(x===" "){if(e.single){let A=!a[s];a.fill(!1),a[s]=A}else a[s]=!a[s];d()}else if(x==="a"&&!e.single){let A=e.items.map((R,B)=>({item:R,index:B})).filter(({item:R})=>R.requiresExplicitChoice!==!0),I=!A.every(({index:R})=>a[R]);for(let{index:R}of A)a[R]=I;d()}else if(x==="\r"||x===`
|
|
689
689
|
`){g({kind:"ok",values:e.items.filter((A,I)=>a[I]).map(A=>A.value)});return}}}catch(x){y(x)}};r.on("data",S),r.on("end",b),r.on("close",b),r.on("error",C)})}finally{try{u(),o.write("\x1B[?25h")}catch{}try{r.pause?.(),p&&r.setRawMode(f)}catch{}n.close()}};var l0=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],lK=80,Bd=async(e,t,n={})=>{let r=n.output??process.stderr;if(!(!!r.isTTY&&va(r,n.env??process.env)))return r.write(`${e}
|
|
690
690
|
`),t();let a=0,s=()=>{r.write(`\r${l0[a++%l0.length]} ${e}`)};s();let i=setInterval(s,lK);i.unref();try{return await t()}finally{try{clearInterval(i),r.write("\r\x1B[2K")}catch{}}};import{createWriteStream as dK}from"node:fs";import{spawnSync as uK}from"node:child_process";import{chmod as pK,copyFile as Bm,lstat as Um,mkdir as _a,readdir as Hm,realpath as Hd,rename as Ud,rm as Ot,stat as fK,symlink as hK,writeFile as mK}from"node:fs/promises";import{createHash as yK}from"node:crypto";import{basename as Mm,dirname as Ir,join as ft}from"node:path";import{Readable as gK}from"node:stream";import{pipeline as wK}from"node:stream/promises";var d0="https://github.com/anyrayHQ/install/releases",u0="connect-v",bK=new RegExp(`/releases/tag/${u0}([0-9][0-9A-Za-z.-]*)$`),kK=300*1024*1024,Wd=1e4,AK=5*6e4,CK=360*6e4,vK=30*6e4,Pa=(e,t)=>{let n=s=>s.split("-")[0].split(".").map(i=>Number.parseInt(i,10)||0),r=n(e),o=n(t);for(let s=0;s<Math.max(r.length,o.length);s++){let i=(r[s]??0)-(o[s]??0);if(i!==0)return i<0?-1:1}let a=s=>s.includes("-")?0:1;return a(e)-a(t)},p0=(e,t)=>{let n=t==="arm64"?"arm64":t==="x64"?"x64":void 0;if(n){if(e==="darwin")return`anyray-connect-darwin-${n}`;if(e==="linux")return`anyray-connect-linux-${n}`;if(e==="win32")return"anyray-connect-windows-x64.exe"}},SK=e=>{if(e)return bK.exec(e.trim())?.[1]},Wm=(e,t)=>{for(let n of e.split(`
|
|
691
|
-
`)){let[r,o]=n.trim().split(/\s+/);if(!r||!o)continue;if((o.startsWith("*")?o.slice(1):o)===t&&/^[0-9a-f]{64}$/i.test(r))return r.toLowerCase()}},f0=e=>{if(e.latest===e.current)return{apply:!1,mandatory:!1};if(e.autoUpdate||e.forced)return{apply:!0,mandatory:!1};let t=!!e.minVersion&&Pa(e.current,e.minVersion)<0&&Pa(e.latest,e.minVersion)>=0;return{apply:t,mandatory:t}},EK=e=>Pa(e.latest,e.current)<0?{apply:!1,mandatory:!1,downgradeBlocked:!0}:e.latest===e.current?{apply:e.autoUpdate||e.forced===!0,mandatory:!1,downgradeBlocked:!1}:{...f0(e),downgradeBlocked:!1},Ta=()=>process.platform==="win32"?"anyray-connect.exe":"anyray-connect",xK=(e=process.execPath)=>{let t=Su(e);return t?Ir(t):Ir(Ir(e))},IK=async(e=yt())=>{if(/[\\/]node(\.exe)?$/i.test(e.execPath))return;let t=ft(xK(e.execPath),"bin",Ta());try{if(await Hd(t)!==await Hd(e.execPath))return}catch{return}return t},Km=async(e=yt(),t=Q())=>{let n=await IK(e);if(n)return{kind:"managed",root:Ir(Ir(n)),link:n,entryPath:Yn(e)};let r=Yn(e);return xu(r,t)?{kind:"durable",root:t,entryPath:r}:Cu(r)?{kind:"npm",root:t,entryPath:r}:{kind:"unmanaged",root:t,entryPath:r}},Kd=async(e,t,n)=>{let r=new AbortController,o=setTimeout(()=>r.abort(),t);try{return await fetch(e,{...n,signal:r.signal})}finally{clearTimeout(o)}},Gm=async(e=Wd)=>{let t=await Kd(`${d0}/latest`,e,{redirect:"manual"});return SK(t.headers.get("location"))},OK=async e=>{try{let t=await Kd(`${e}/connect-update.json`,Wd);if(!t.ok)return;let n=await t.json();if(!n||typeof n!="object")return;let r=n.minVersion;return typeof r=="string"&&/^\d+\.\d+\.\d+/.test(r)?r:void 0}catch{return}},xi=class extends Error{status;constructor(t){super(`download failed (${t})`),this.status=t,this.name="DownloadHttpError"}},jm=async(e,t,n)=>{let r=await Kd(e,AK);if(!r.ok||!r.body)throw new xi(r.status);let o=yK("sha256"),a=0;if(await wK(gK.fromWeb(r.body),async function*(s){for await(let i of s){let c=i;if(a+=c.length,a>kK)throw new Error("asset exceeds size cap");o.update(c),yield c}},dK(t,{mode:493})),o.digest("hex")!==n)throw new Error("checksum mismatch")},RK=e=>Mm(e)===Ta()?Mm(Ir(e)):Mm(e),_K=async e=>{let t=await Hm(e).catch(()=>[]);for(let n of t)/\.part-\d+$/.test(n)&&await Ot(ft(e,n),{force:!0}).catch(()=>{})},h0=async(e,t)=>{if(process.platform==="win32"){let r=`${e}.old-${process.pid}`;await Ot(r,{force:!0}).catch(()=>{});let o=!1;try{await Ud(e,r),o=!0}catch{}try{await Bm(t,e),await mK(ja(e),RK(t))}catch(a){throw o&&await Ud(r,e).catch(()=>{}),a}await Ot(r,{force:!0}).catch(()=>{});return}let n=`${e}.new-${process.pid}`;await Ot(n,{force:!0}),await hK(t,n),await Ud(n,e)},PK=async(e,t={})=>{let n=ft(e.root,"bin"),r=ft(e.root,"versions"),o=ft(n,Ta());await _a(n,{recursive:!0,mode:448}),await _a(r,{recursive:!0,mode:448});let a=ft(r,e.version),i=(await Um(a).catch(()=>{}))?.isFile()?a:ft(a,Ta());if(!(await Um(i).catch(()=>{}))?.isFile()){let l=await(t.fetchResponse??Kd)(`${e.tagUrl}/SHA256SUMS`,Wd),d=l.ok?Wm(await l.text(),e.asset):void 0;if(!d)throw new Error("no published checksum");await _a(Ir(i),{recursive:!0,mode:448}),await _K(Ir(i));let u=`${i}.part-${process.pid}`;try{await(t.download??jm)(`${e.tagUrl}/${e.asset}`,u,d),await pK(u,493),await Ud(u,i)}catch(f){throw await Ot(u,{force:!0}).catch(()=>{}),f}}return await(t.activate??h0)(o,i),{link:o,target:i,versionsDir:r}},TK=async e=>{let t=uK(e,["--version"],{stdio:"ignore",timeout:Wd});return!t.error&&t.status===0},LK=async(e,t={})=>{let n=e.managedTools??[];if(n.length>0){let r=await(t.findTools??po)(n);if(r.length>0){let o=await(t.resolveTarget??_e)(async()=>e);if(!o||!(await(t.repair??wt)(r,o.target)).every(uo))return!1}}return e.persistenceOwner==="tray"?!0:!(e.refreshSchedulerEnabled&&!(await(t.installScheduler??rr)()).ok||e.keyRefreshEnabled&&(!e.gateway||!e.fallbackPort||!(await(t.installDaemon??Pt)({port:e.fallbackPort,remoteOrigin:e.gateway})).ok))},DK=async e=>{let t=await e.install();if(!await(e.smoke??TK)(t.target))throw await e.rollback?.(t),new Error("managed binary smoke test failed");if(!await e.repoint(t.link))throw new Error("persistent config repoint failed");return await e.prune(),t},NK=async(e,t)=>{let n=await Hm(e).catch(()=>[]);for(let r of n)t.includes(r)||await Ot(ft(e,r),{force:!0,recursive:!0}).catch(()=>{})},$K=async e=>{let t=await Hm(e).catch(()=>[]);for(let n of t)/\.(new|old|rollback)-\d+$/.test(n)&&await Ot(ft(e,n),{force:!0}).catch(()=>{})},MK=async(e,t)=>{let n=async()=>{await Ot(e,{recursive:!0,force:!0}).catch(()=>{})};try{return await _a(e,{recursive:!1}),n}catch{}let r=await fK(e).catch(()=>{});if(!(!r||t-r.mtimeMs<vK)){await n();try{return await _a(e,{recursive:!1}),n}catch{return}}},Fm=e=>ft(e,"update-state.json"),FK=async e=>{let t=await M(e).catch(()=>({})),n=t.failedVersion,r=t.failedAt;return{failedVersion:typeof n=="string"?n:void 0,failedAt:typeof r=="number"?r:void 0}},BK=1e3,UK=16*6e4,HK=e=>e.inFlight===0,WK=async(e,t,n={})=>{let r=n.probe??Ae,o=n.sleep??(i=>new Promise(c=>setTimeout(c,i))),a=n.now??Date.now,s=a()+(n.timeoutMs??UK);for(;;){let i=await r(e).catch(()=>null);if(i!==null&&i.version===t&&HK(i))return!0;if(a()>=s)return!1;await o(BK)}},Ii=async(e={})=>{let t=e.now??Date.now,n=ke;if(At(gt(e.env??process.env)))return{outcome:"container",current:n};let r=e.context??yt(),o=e.root??Q(),a;try{let s=await Km(r,o);if(o=s.root,s.kind==="unmanaged")return{outcome:"unmanaged",current:n};if(s.kind==="npm"&&!e.allowNpmMigration)return{outcome:"unmanaged",current:n};let i=s.kind!=="managed",c=p0(e.platform??process.platform,e.arch??process.arch);if(!c)return{outcome:"platform-unsupported",current:n};if(a=await(e.latestVersion??Gm)().catch(()=>{}),!a)return{outcome:"unavailable",current:n};let l=a;if(!i&&l===n)return{outcome:"current",current:n,latest:l};if(i&&Pa(l,n)<0)return{outcome:"migration-deferred",current:n,latest:l};let d=e.force===!0,u=await FK(Fm(o));if(!d&&u.failedVersion===l&&u.failedAt!==void 0&&t()-u.failedAt<CK)return{outcome:"failed",current:n,latest:l};let f=`${d0}/download/${u0}${l}`,p=await(e.load??P)().catch(()=>({})),h=p.autoUpdate!==!1,m=h||d?void 0:await(e.minimumVersion??OK)(f),w={current:n,latest:l,autoUpdate:h,forced:d,minVersion:m},g=i?EK(w):{...f0(w),downgradeBlocked:!1};if(g.downgradeBlocked)return{outcome:"migration-deferred",current:n,latest:l};if(!g.apply)return{outcome:"disabled",current:n,latest:l};if(e.checkOnly)return{outcome:i?"migration-available":"available",current:n,latest:l,mandatory:g.mandatory};o===Q()?await kt():await _a(o,{recursive:!0,mode:448});let y=await MK(ft(o,"update.lock"),t());if(!y)return{outcome:i?"migration-available":"available",current:n,latest:l};let b,C;try{await $K(ft(o,"bin"));let x=await Hd(ft(o,"versions")).catch(()=>{}),A=await Hd(ft(o,"bin",Ta())).catch(()=>{}),I=A&&Xi(A,x)?A:void 0,R=ft(o,"bin",Ta());i&&process.platform==="win32"&&(await Um(R).catch(()=>{}))?.isFile()&&(C=`${R}.rollback-${process.pid}`,await Bm(R,C));let B=()=>(e.installBinary??PK)({root:o,version:l,asset:c,tagUrl:f});i?b=await DK({install:B,smoke:e.smoke,rollback:async({link:V,target:H})=>{C?(await Bm(C,V),await Ot(ja(V),{force:!0}).catch(()=>{})):I&&I!==H?await h0(V,I):(await Ot(V,{force:!0}),await Ot(ja(V),{force:!0}).catch(()=>{}))},repoint:async V=>e.repoint?e.repoint(p,V):LK(p),prune:async()=>{await(e.pruneDurable??(V=>Ji(V)))(r)}}):b=await B(),await NK(b.versionsDir,[l,n]),await Ot(Fm(o),{force:!0}).catch(()=>{})}finally{C&&await Ot(C,{force:!0}).catch(()=>{}),await y()}let S=e.bounceDaemon??Uu,E=p.persistenceOwner==="tray";if(!i&&(p.refreshSchedulerEnabled||p.keyRefreshEnabled)){let x=p.fallbackPort??Ce,A=E?!0:await Kg().catch(()=>!0),I=await S(p.fallbackPort,{drain:"idle"}).catch(()=>!1);!A&&p.gateway&&((I?await(e.waitForDaemon??WK)(x,l):!0)?await Pt({port:x,remoteOrigin:p.gateway}).catch(()=>{}):await(e.writeUnitFile??jg)().catch(()=>!1))}return{outcome:i?"migrated":"updated",current:n,latest:l,managedPath:b.link,mandatory:g.mandatory}}catch{return a&&await Z(Fm(o),{failedVersion:a,failedAt:t()},{backup:!1}).catch(()=>{}),{outcome:"failed",current:n,latest:a}}},m0=async(e={})=>{let t=e.context??yt(),n=await Km(t,e.root??Q()),r=Oo(e.root??Q());return n.kind==="managed"||(n.kind==="npm"||n.kind==="durable")&&r?{outcome:"current",current:ke,managedPath:n.link??r}:Ii({...e,context:t,allowNpmMigration:!0})},ko=async(e={})=>{let t=e.context??yt(),n=e.root??Q(),r=await Km(t,n),o=r.kind==="npm"||r.kind==="durable"?Oo(n):void 0,a=await(e.load??P)().catch(()=>({})),s=r.kind==="managed"||r.kind==="durable"||r.kind==="npm"||!!o,i=s&&!!p0(e.platform??process.platform,e.arch??process.arch),c=r.link??o,l=At(gt(e.env??process.env))?"container":s?i?c?"managed":"will-migrate":"platform-unsupported":"unmanaged";return{version:ke,managed:!!c,available:i,autoUpdate:a.autoUpdate!==!1,path:c??r.entryPath,state:l}};var KK=async(e,t)=>{if(!e.gateway||!e.clientKey)return;let n=await t().catch(()=>{});return me({origin:e.gateway,clientKey:e.clientKey,subscription:e.authMode==="subscription",placeholder:e.authMode==="placeholder",byoUpstream:e.byoUpstream,seat:n,user:e.name,team:e.team})},y0=(e,t)=>e.keyRefreshEnabled===t.keyRefreshEnabled&&e.fallbackPort===t.fallbackPort,GK=(e,t)=>async n=>{let r=await e(),{next:o,result:a}=n(r);return o&&await t(o),a},Vm=async(e={})=>{let t=e.load??P,n=e.save??te,r=e.mutate??(e.load||e.save?GK(t,n):Qy),o=e.loadDevKey??Me,a=e.heartbeat??sd,s=e.detectSeat??Tt,i=e.rewriteTools??di,c=e.uninstallProxy??Zt;try{let l=await t();if(l.credentialProtocol==="stable-heartbeat-v1"&&l.directMigration==="complete")return"already-direct";if(!l.keyRefreshEnabled&&!l.refreshSchedulerEnabled||!l.gateway||!l.clientKey||!l.enrolledCert)return"not-eligible";let d=l.enrolledCert.sig,u=await o();if(!u)return"not-eligible";let f;try{f=await a(l.gateway,l.clientKey,l.enrolledCert,u)}catch(y){return y instanceof br&&y.status===404?"unsupported":"pending"}let p=await r(y=>{if(y.clientKey!==l.clientKey||y.enrolledCert?.sig!==d||!y0(y,l))return{result:void 0};let b={...y,clientKeyExpiresAt:f.expiresAt,credentialProtocol:"stable-heartbeat-v1",directMigration:"pending"};return{next:b,result:b}});if(!p)return"pending";let h=await KK(p,s);if(!h)return"pending";let m=l.keyRefreshEnabled===!0,w=Number.isInteger(l.fallbackPort)&&l.fallbackPort>0&&l.fallbackPort<=65535?l.fallbackPort:Ce;if(m){let y=`http://${mt}:${w}`;if(await i(h,y)===!1)return"pending"}return await r(y=>y.clientKey!==l.clientKey||y.enrolledCert?.sig!==d||y.credentialProtocol!=="stable-heartbeat-v1"||y.directMigration!=="pending"||!y0(y,p)?{result:!1}:{next:{...y,clientKeyExpiresAt:f.expiresAt,credentialProtocol:"stable-heartbeat-v1",directMigration:"complete",keyRefreshEnabled:!1,fallbackPort:void 0},result:!0})?((m||l.fallbackPort!==void 0)&&await c(w).catch(()=>{}),"migrated"):"pending"}catch{return"pending"}};var jK=12e3,VK="anyray-wiring-probe-not-a-real-token",YK={model:"anyray-default",messages:[{role:"user",content:"ping"}],max_tokens:1},Zm={model:"claude-3-5-haiku-20241022",max_tokens:1,messages:[{role:"user",content:"ping"}]},Ao=e=>{let t=e.replace(/\s+/g," ").trim();return t.length>160?`${t.slice(0,157)}\u2026`:t},w0=e=>{let t=e.toLowerCase();return t.includes("bedrock")||t.includes("unsupported model")},Xm=e=>{let t=e.toLowerCase();return t.includes("client key required")||["missing_key","key_unknown","key_expired","key_revoked"].some(n=>t.includes(`"${n}"`))},g0=e=>["Note: OpenCode\u2019s Claude provider can ONLY use a server-side key \u2014 unlike","Claude Code, it has no personal-subscription path. For Claude, either:",...e," \u2022 use Claude Code with your own Claude subscription instead of OpenCode.","OpenCode ChatGPT OAuth uses a non-configurable endpoint. Use Codex for"," config-native ChatGPT subscription pass-through, or use an OpenCode"," API-key/Copilot provider that Connect can route."],ZK=e=>e.includes("no provider key configured for"),Jm=e=>{let t=e.toLowerCase();return t.includes("verified_dev_required")||t.includes("verified developers")},zm=e=>({kind:"enrollment-required",detail:`gateway requires per-developer enrollment (HTTP ${e}).`,remedy:["This gateway only serves enrolled developers. Re-run with your enrollment","link from your admin so connect can mint your personal key automatically:"," anyray-connect --enroll <link>"]}),Oi=e=>({kind:"key-rejected",detail:`gateway rejected the client key (HTTP ${e}).`,remedy:["The gateway did not receive a usable personal key (missing, unknown, expired,","or revoked). Re-run `anyray-connect` to refresh an existing enrollment, or","use `--enroll` / `--sso` to enroll first."]}),XK=(e,t,n=[])=>e>=200&&e<300?{kind:"ok",detail:"gateway served a completion with the org key \u2014 traffic flows.",remedy:[]}:e===401||e===403?Jm(t)?zm(e):Xm(t)?Oi(e):w0(t)?{kind:"routed-elsewhere",detail:`gateway routed to the org provider and it rejected the request: ${Ao(t)}`,remedy:["The org provider rejected the request \u2014 check the gateway\u2019s provider","key/config (e.g. the model is enabled for that account)."]}:ZK(t)?{kind:"provider-rejected",detail:`gateway has no server-side provider key for this lane (HTTP ${e}): ${Ao(t)}`,remedy:["Your enrollment key is fine \u2014 the gateway has NO server-side provider","key configured (org-key mode), so it refused to forward the request.","Fix: add a provider key in the console \u2192 Providers.",...n.includes("opencode")?g0([" \u2022 add a provider key in the console \u2192 Providers (fixes it for everyone), or"]):["If you ONLY use a subscription tool (e.g. Copilot), this org-key check","does not apply \u2014 you can ignore it."]]}:{kind:"provider-rejected",detail:`gateway accepted your key but the model provider rejected the request (HTTP ${e}): ${Ao(t)}`,remedy:n.includes("opencode")?["Your enrollment key is fine \u2014 the gateway forwarded the request and the","upstream model provider refused the credential it was given: this","gateway has no WORKING provider key for it (either none is configured,","or the configured one is wrong or revoked).",...g0([" \u2022 open the console \u2192 Providers and add a key for that provider, or"," replace the one already listed (fixes it for everyone), or"])]:["Your enrollment key is fine \u2014 the gateway forwarded the request and the","upstream model provider refused it.","Open the console \u2192 Providers: if no key is listed for that provider,","add one; if a key IS listed, it is wrong, revoked, or not entitled to","the model \u2014 replace it.","Either way this is gateway config, not your enrollment. Alternatively,","sign in with your own provider subscription instead of the org key.","If you ONLY use a subscription tool (e.g. Copilot), this org-key check","does not apply \u2014 you can ignore it."]}:{kind:"unknown",detail:`gateway responded HTTP ${e}: ${Ao(t)}`,remedy:[]},JK=(e,t)=>{if(Xm(t))return Oi(e);if(Jm(t))return zm(e);if(w0(t))return{kind:"routed-elsewhere",detail:"gateway sent the request to the org provider, not your subscription.",remedy:["Pass-through isn\u2019t being honored for this gateway \u2014 your seat token would","not be used. Check the gateway is current (subscription pass-through support)."]};let n=t.toLowerCase();return e===401||n.includes("authentication_error")||n.includes("invalid bearer")||n.includes('"provider":"anthropic"')?{kind:"ok",detail:"gateway passes your sign-in through to Anthropic \u2014 your Claude seat will be used.",remedy:[]}:e>=200&&e<300?{kind:"ok",detail:"gateway pass-through reached the provider \u2014 your seat will be used.",remedy:[]}:{kind:"unknown",detail:`seat-wiring probe got HTTP ${e}: ${Ao(t)}`,remedy:[]}},zK=e=>e.includes("anthropic_messages:")||e.includes("invalid model name passed in model=")||e.includes("to view available models"),qK=(e,t)=>{if(Xm(t))return Oi(e);if(Jm(t))return zm(e);let n=t.toLowerCase();if(n.includes("bedrock"))return{kind:"routed-elsewhere",detail:"gateway routed to the org provider instead of the configured BYO upstream.",remedy:["Re-run anyray-connect with your --upstream URL and --upstream-key so","the custom-host pass-through pins are restored."]};if(n.includes("invalid custom host")||n.includes("custom_host_blocked")||n.includes("hostname is not authorized"))return{kind:"routed-elsewhere",detail:"gateway rejected the configured BYO upstream before routing to it.",remedy:["Ask the gateway admin to authorize this LiteLLM/upstream hostname in","ANYRAY_CUSTOM_HOST_ALLOWLIST (or TRUSTED_CUSTOM_HOSTS for an internal host)."]};if(e===401||e===403)return{kind:"provider-rejected",detail:`gateway accepted your personal key but the BYO upstream rejected its credential (HTTP ${e}).`,remedy:["Your Anyray enrollment key is fine. The configured personal upstream key","was rejected by the BYO upstream (for example, LiteLLM). Re-run","anyray-connect with a current --upstream-key."]};let r=e>=400&&e<500&&(n.includes("litellm")||zK(n));return e>=200&&e<300||r?{kind:"ok",detail:e>=200&&e<300?"gateway served a completion through the configured BYO upstream.":`gateway authenticated and reached the configured BYO upstream, which rejected this probe's fixed model (HTTP ${e}).`,remedy:[]}:{kind:"unknown",detail:`BYO-upstream probe got HTTP ${e}: ${Ao(t)}`,remedy:[`The probe asks for a fixed model (${Zm.model}) your upstream`,"is not required to serve, so a model rejection here does not mean your","tools are broken. Check that the upstream serves it before chasing this."]}},Ym=async(e,t,n,r)=>{let o=new AbortController,a=setTimeout(()=>o.abort(),r);try{let s=await fetch(e,{method:"POST",headers:{"content-type":"application/json",...t},body:JSON.stringify(n),signal:o.signal});return{status:s.status,bodyText:await s.text()}}finally{clearTimeout(a)}},QK=async(e,t)=>{if(!e.clientKey)return Oi(401);let n=new AbortController,r=setTimeout(()=>n.abort(),t);try{let o=await fetch(`${e.origin}/connect/savings`,{method:"GET",headers:{"x-anyray-api-key":e.clientKey},signal:n.signal}),a=await o.text();return o.ok?{kind:"ok",detail:"gateway accepted your personal key \u2014 Cursor hooks/MCP can report and retrieve.",remedy:[]}:o.status===401||o.status===403?Oi(o.status):{kind:"unknown",detail:`Cursor hook-auth probe got HTTP ${o.status}: ${Ao(a)}`,remedy:o.status===404?["Update the gateway image \u2014 this one predates the content-free /connect/savings key check."]:[]}}finally{clearTimeout(r)}},eG=(e,t)=>{let n=typeof t?.code=="string"?` ${t.code}`:"";return{kind:"unreachable",detail:`could not reach the gateway to verify (${t instanceof Error&&t.name==="AbortError"?`no response within ${e}ms`:t instanceof Error?`${t.name}${n}`:"unknown error"}).`,remedy:["Your config was still written \u2014 re-run the curl below once the gateway is reachable."]}},Ri=async(e,t={})=>{let n=t.timeoutMs??jK,r=le(e.metadata);try{if(e.authMode!=="placeholder"&&t.tools?.length===1&&t.tools[0]==="cursor")return await QK(e,n);if(e.byoUpstream){let l={Authorization:`Bearer ${e.byoUpstream.key}`,"anthropic-version":"2023-06-01","x-anyray-auth-mode":"passthrough","x-anyray-provider":"anthropic","x-anyray-custom-host":e.byoUpstream.url};e.clientKey&&(l["x-anyray-api-key"]=e.clientKey),r&&(l["x-anyray-metadata"]=r);let{status:d,bodyText:u}=await Ym(`${e.anthropicBaseUrl}/v1/messages`,l,Zm,n);return qK(d,u)}if(q(e,"anthropic")){let l={Authorization:`Bearer ${VK}`,"anthropic-version":"2023-06-01","anthropic-beta":"oauth-2025-04-20","x-anyray-auth-mode":"passthrough","x-anyray-provider":"anthropic"};r&&(l["x-anyray-metadata"]=r),e.clientKey&&(l["x-anyray-api-key"]=e.clientKey);let{status:d,bodyText:u}=await Ym(`${e.anthropicBaseUrl}/v1/messages`,l,Zm,n);return JK(d,u)}let s={Authorization:`Bearer ${e.clientKey??e.placeholderKey}`};r&&(s["x-anyray-metadata"]=r);let{status:i,bodyText:c}=await Ym(`${e.openaiBaseUrl}/chat/completions`,s,YK,n);return XK(i,c,t.tools??[])}catch(o){return eG(n,o)}};var b0=async e=>{let t=await P(),n;try{n=Er(e.gateway,t)}catch(s){return k(j("Anyray connect \u2014 status")),F(`Gateway: ${s.message}`),0}k(j("Anyray connect \u2014 status")),W("Gateway"),k(` Origin: ${et(n)}`),t.gateway?F(" (cached in ~/.anyray)"):process.env.ANYRAY_GATEWAY_URL?F(" (from $ANYRAY_GATEWAY_URL)"):e.gateway||F(" (default \u2014 not yet connected; run `anyray-connect` to set up)"),W("Identity"),k(` Name: ${t.name??v("(not set)")}`),k(` Team: ${t.team??v("(not set)")}`);let r=gt();r&&(W("Environment"),k(` Remote dev context: ${tr(r)}`),At(r)&&F(" No per-user service manager here \u2014 key refresh rides the Claude Code helper and `anyray-connect` runs, not an OS schedule."),F(" VS Code tools configure the remote server variant backing this window.")),t.credentialProtocol==="stable-heartbeat-v1"&&(W("Credential renewal"),t.directMigration==="pending"?(k(" Stable-key heartbeat active; direct-routing migration is still completing."),F(" The local proxy remains available until every managed tool moves.")):($(" Direct gateway routing with a proof-backed stable-key heartbeat."),F(" Renewal extends the same key; tool configuration is not rewritten.")));let o=!!(rt(t)&&t.fallbackPort),a=o?`http://${mt}:${t.fallbackPort}`:n;o&&(W("Local key-refresh proxy"),await Ae(t.fallbackPort)?$(` Running on 127.0.0.1:${t.fallbackPort} \u2192 ${n} `+v("(auto-refreshes your key so long sessions never 401)")):(N(` Enabled on 127.0.0.1:${t.fallbackPort} but NOT responding \u2014 your tools cannot reach any gateway until it's back.`),k(v(" Re-run `anyray-connect`, or check the service logs.")))),W("Tools");for(let s of ae){if(!(await s.detect()).installed){F(` ${s.title}: not installed`);continue}if(!s.pointsAt){F(` ${s.title}: installed ${v("(status not introspectable)")}`);continue}let c=await s.pointsAt(Ai(s.id,n,a));if(c){if(s.id==="cursor"&&(t.authMode==="auto"||t.authMode==="subscription")){$(` ${s.title}: native Cursor subscription; Anyray hooks/MCP active`),k(v(" Claude/Opus model requests remain Cursor-hosted; only supported local Shell/MCP context is optimized by Anyray."));continue}$(` ${s.title}: pointed at Anyray${o&&ki(s.id)?v(" (via key-refresh proxy)"):""}`)}else{let l=null,d=null;if(s.id===Ia&&s.mcpStatus)try{let u=(await s.mcpStatus()).registered,f=await Sd();l=Ed({id:s.id,installed:!0,pointedAt:c,mcpRegistered:u,introspectable:f.authoritative}),d={...f.authoritative?{}:{reason:f.reason},mcpRegistered:u}}catch{l=null,d=null}if((l==="not-routed"||l==="unverifiable")&&d){let u=xd(l,d);N(` ${s.title}: ${u.headline}`);for(let f of u.detail)k(v(` ${f}`))}else F(` ${s.title}: installed, not pointed at this gateway`)}}return 0};import{existsSync as sG}from"node:fs";import{isAbsolute as iG}from"node:path";import{access as tG}from"node:fs/promises";import{constants as nG}from"node:fs";import{platform as rG}from"node:os";var oG=async e=>{try{return await tG(e,nG.F_OK),!0}catch{return!1}},aG=e=>e==="darwin"?["/Library/LaunchDaemons/com.fleetdm.orbit.plist","/opt/orbit/bin/orbit"]:e==="linux"?["/etc/systemd/system/orbit.service","/usr/lib/systemd/system/orbit.service","/opt/orbit/bin/orbit"]:e==="win32"?["C:\\Program Files\\Orbit\\bin\\orbit\\orbit.exe"]:[],La=async(e={})=>{let t=e.os??rG(),n=e.exists??oG;for(let r of aG(t))if(await n(r))return!0;return!1};var on="connect",qm=e=>e.replace(/-/g,"_"),k0=e=>{let t=[];e.gateway.reachable!==null&&t.push({tool:on,checkId:"gateway_reachable",status:e.gateway.reachable?"ok":"unreachable"});let n=Date.parse(e.report.generatedAt),r=Date.parse(e.enrollment.expiresAt??""),o=e.enrollment.enrolled&&e.enrollment.expired===!1&&Number.isFinite(n)&&Number.isFinite(r)&&r-n<=336*60*60*1e3;if(t.push({tool:on,checkId:"enrollment_cert",status:e.enrollment.expired?"expired":o?"problems":e.enrollment.enrolled?"ok":"unenrolled",...o?{errorClass:"cert_expiring"}:{}}),t.push({tool:on,checkId:"shell_exports",status:e.shell.staleExports.length?"stale":"ok"}),e.fallbackProxy.enabled&&t.push({tool:on,checkId:"fallback_proxy",status:e.fallbackProxy.healthy===!1?"fail":e.fallbackProxy.healthy===!0?"ok":"unknown"}),e.refreshScheduler.enabled){let i=e.refreshScheduler.owner==="tray"?e.refreshScheduler.trayHealthy===!0:e.refreshScheduler.installed;t.push({tool:on,checkId:"refresh_scheduler",status:i?"ok":"missing",...i?{}:{errorClass:e.serviceRemoval?.kinds.includes("scheduler")?"unit_deleted":"refresh_scheduler_missing"}})}if(e.pendingOps.some(i=>!i.watcherAlive)&&t.push({tool:on,checkId:"pending_op",status:"problems",errorClass:"watcher_dead"}),e.retrieval){let i=qm(e.retrieval.kind);t.push({tool:on,checkId:"retrieval_loop",status:i,...i==="ok"?{}:{errorClass:`retrieval_${i}`}})}if(e.verify){let i=e.verify.notApplicableSubscription===!0,c=i?"ok":qm(e.verify.kind);t.push({tool:on,checkId:"auth_verify",status:c,...i?{errorClass:"verify_not_applicable_subscription"}:c==="ok"?{}:{errorClass:`verify_${c}`}})}for(let i of e.tools)!i.installed||i.claudeCodeHookPolicy===void 0||t.push({tool:i.id,checkId:"hook_policy",status:i.claudeCodeHookPolicy==="fine"?"ok":i.claudeCodeHookPolicy});if(e.hookLane&&e.hookLane.verdict!=="indeterminate"){let i=e.hookLane.verdict==="dark";t.push({tool:on,checkId:"hook_lane",status:i?"dark":"ok",...i?{errorClass:qm(e.hookLane.reason)}:{}})}t.push({tool:on,checkId:"overall",status:e.problems===0?"ok":"problems"});let a=new Set(e.fleetPlan?.tombstonedIds),s=new Set(e.fleetPlan?.candidateIds);for(let i of e.tools)i.installed&&(i.pointedAt!==null?t.push({tool:i.id,checkId:"routing",status:i.pointedAt?i.routingOverrides?.some(c=>c.bypass!==!1)?"bypassed":"ok":i.routingPendingReload?"reload_required":"fail"}):i.routingHeld&&t.push({tool:i.id,checkId:"routing",status:"held"}),i.inferenceUnverifiableReason==="managed-policy"&&t.push({tool:i.id,checkId:"machine_policy",status:"blocked"}),i.mcp&&t.push({tool:i.id,checkId:"mcp_registration",status:i.mcp.registered?i.mcp.commandOk===!1?"command_gone":"ok":i.routingHeld?"held":"missing"}),a.has(i.id)?t.push({tool:i.id,checkId:"fleet_compliance",status:"reverted_required"}):s.has(i.id)&&t.push({tool:i.id,checkId:"fleet_compliance",status:"ok"}));return t.push({tool:on,checkId:"doctor_report",status:e.problems===0?"ok":"problems"}),t};function cG(){return ke}var lG="ctx_doctor-probe-synthetic",dG=(e,t={mode:"unknown",ssoLink:null})=>{if(e.ok||e.kind==="not-found")return{kind:"ok",detail:"Retrieval loop healthy: gateway answered, key authorized, optimizer retrieval wired.",remedy:[]};switch(e.kind){case"auth":return{kind:"auth",detail:"The gateway rejected the retrieval call (no valid personal key).",remedy:[`Fix: ${ty(t.mode,t.ssoLink)}, or set ANYRAY_CLIENT_KEY.`,"Retrieval needs a personal key \u2014 the MCP server hits the same wall, so externalized output is unretrievable until this is fixed."]};case"unsupported":return{kind:"unsupported",detail:"The gateway has no /connect/retrieve route.",remedy:["Fix: update the gateway image \u2014 this one predates the retrieval loop."]};case"timeout":case"network":return{kind:"unreachable",detail:`Could not reach the gateway for the retrieval probe (${e.kind}).`,remedy:["Fix: check the gateway origin and network (see the Gateway section above)."]};default:return{kind:"unavailable",detail:e.message,remedy:["Fix: the gateway answered but retrieval is unavailable \u2014 usually the optimizer is down or ANYRAY_OPTIMIZER_URL is unset on the gateway. Check the optimizer service."]}}};function uG(e){return e.identity.personalKeySource==="env"?"env":e.identity.personalKeySource==="profile"?"profile":e.enrollment.enrolled?"enrolled-no-key":"none"}function pG(e){return e.ssoLink?"sso":e.enrolledViaToken?"passwordless":"unknown"}function ty(e,t){let n=`\`anyray-connect --sso ${t??"<link>"}\``,r="`anyray-connect --enroll <link>`";switch(e){case"sso":return`enroll via SSO with ${n}`;case"passwordless":return`enroll with the link from your admin (${r})`;default:return`enroll \u2014 SSO org: use ${n}; passwordless org: use ${r} (link from your admin)`}}var A0=e=>Ed({id:e.id,installed:e.installed,pointedAt:e.pointedAt,mcpRegistered:e.mcp?.registered===!0,introspectable:e.inferenceIntrospectable===!0}),Qm=e=>e.pointedAt===!1&&e.tombstoned!==!0&&A0(e)!=="unverifiable",C0=e=>e.registered&&e.command&&iG(e.command)?sG(e.command):null,ey=e=>(Qm(e)?1:0)+(e.mcp?.commandOk===!1?1:0)+(e.routingOverrides?.length?1:0)+(e.claudeCodeHookPolicy&&e.claudeCodeHookPolicy!=="fine"?1:0),fG=async(e,t,n)=>e===!1&&t.routingExpected&&!await t.routingExpected(n)?null:e,hG=async(e,t)=>{if(e.length===0)return!1;for(let n of e){let r=t.find(a=>a.id===n);if(!r?.inferenceAuthLanes)return!1;let o=await r.inferenceAuthLanes().catch(()=>["unknown"]);if(o.length===0||o.some(a=>a!=="subscription"&&a!=="native"))return!1}return!0},v0=async e=>{for(let t of e)if(t.integrationStatus)try{if(!(await t.detect()).installed)continue;if((await t.integrationStatus()).hook_registration==="owned")return!0}catch{}return!1},mG=(e,t)=>{let n=c=>typeof c=="object"&&c!==null&&!Array.isArray(c),r=c=>typeof c=="number"&&Number.isSafeInteger(c)&&c>=0&&Number.isFinite(new Date(c).getTime()),o=new Set(t.map(c=>c.id)),a=new Set(mo),s=[],i=n(e.selfcheck?.adapters)?e.selfcheck.adapters:{};for(let[c,l]of Object.entries(i)){if(!o.has(c)||!n(l))continue;let d=n(l.lastRepaired)?l.lastRepaired:{},u=Object.entries(d).filter(w=>a.has(w[0])&&r(w[1])).map(([w,g])=>({checkId:w,at:g})),f=n(l.flapping)?l.flapping:void 0,p=Array.isArray(f?.checks)?f.checks.filter(w=>typeof w=="string"&&a.has(w)):[],h=f?.reason==="rebroke_same_day"||f?.reason==="repeat_days"?f.reason:void 0,m=f&&r(f.since)&&h&&p.length>0?{since:f.since,reason:h,checks:p}:void 0;(u.length>0||m)&&s.push({tool:c,repaired:u,...m?{flapping:m}:{}})}return s},yG=async(e,t,n,r,o,a,s=n,i=Ri,c=!0,l=wo,d=ko,u=Ut,f=wa)=>{let p=c?await $d(e):null,h=!!(rt(t)&&t.fallbackPort),m=h?await Ae(t.fallbackPort):null,w=h?`http://${mt}:${t.fallbackPort}`:e,g=process.env.ANYRAY_CLIENT_KEY?.trim()?"env":t.clientKey?"profile":null,y=t.enrolledCert?.payload,b=y?.expiresAt??t.enrolledCertExpiry??null,S=(await a())?.sso??null,E=pG({ssoLink:S,enrolledViaToken:!!t.enrolledTokenHash}),x=Ct(),A=await kw(x),I=A?[]:Ew(me({origin:w})),R=[];for(let Y of r){let De=await Y.detect(),He=null;if(De.installed&&Y.mcpStatus)try{let nt=await Y.mcpStatus();He={...nt,commandOk:C0(nt)}}catch{}let ht=De.installed&&Y.id===Ia?await o():void 0,Co=De.installed&&Y.pointsAt?await Y.pointsAt(Ai(Y.id,e,w)):null,an=await fG(Co,Y,t.managedTools??[]),Ma=Co===!1&&an===null,Bi=an===!1&&Y.routingPendingReload?await Y.routingPendingReload().catch(()=>!1):!1,ou=De.installed?Y.runtimeDiagnostics?await Y.runtimeDiagnostics().catch(()=>({routingOverrides:[]})):{routingOverrides:Y.routingOverrides?await Y.routingOverrides().catch(()=>[]):[]}:{routingOverrides:[]},{routingOverrides:Fa,claudeCodeHookPolicy:ue}=ou,tt=t.fleetToolPolicy,_r=tt?.enabled.includes(Y.id)?tt.tiers?.[Y.id]??ma:void 0;R.push({id:Y.id,title:Y.title,installed:De.installed,...De.detail?{detail:De.detail}:{},pointedAt:an,...Ma?{routingHeld:!0}:{},...Bi?{routingPendingReload:!0}:{},...Fa.length?{routingOverrides:Fa}:{},...ue===void 0?{}:{claudeCodeHookPolicy:ue},mcp:He,..._r?{policyTier:_r}:{},...t.revertedTools?.includes(Y.id)?{tombstoned:!0}:{},...Y.id==="cursor"&&(t.authMode==="auto"||t.authMode==="subscription")?{nativeSubscription:!0}:{},...ht===void 0?{}:{inferenceIntrospectable:ht.authoritative,...ht.authoritative?{}:{inferenceUnverifiableReason:ht.reason}}})}let B=s?await(async()=>{let{kind:Y,detail:De,remedy:He}=await i(me({origin:e,clientKey:process.env.ANYRAY_CLIENT_KEY?.trim()||t.clientKey,subscription:t.authMode==="subscription",placeholder:t.authMode==="placeholder",byoUpstream:t.byoUpstream,...t.authMode==="auto"?{seat:{anthropic:!1,openai:!1,copilot:!1}}:{},user:t.name,team:t.team}),{tools:t.managedTools??[]});return{kind:Y,detail:De,remedy:He}})():null,V=B?.kind==="provider-rejected"&&await hG(t.managedTools??[],r),H=B?{...B,...V?{notApplicableSubscription:!0}:{}}:null,X=n?dG(await ga({origin:e,apiKey:process.env.ANYRAY_CLIENT_KEY?.trim()||t.clientKey||void 0,metadata:le({user:t.name,team:t.team})},lG,{probe:!0}),{mode:E,ssoLink:S}):null,ie=await u().catch(()=>({})),ye=bn(ie.hookLane),Ue=s?await v0(r):!1,re=Ue?await(async()=>{let Y=await f().catch(()=>({verdict:"indeterminate",reason:"unreachable"}));return{...Kh(Y,{hookRegistered:Ue,neverInvoked:Hh(ye,Date.now())}),lastInvokedAt:cd(ye)}})():null,je=(await ar()).map(Y=>({adapter:Y.adapter,op:Y.op,requestedAt:Y.requestedAt,watcherAlive:ir(Y.watcherPid)})),L=je.find(Y=>Y.adapter==="cursor"),T=L?{op:L.op,requestedAt:L.requestedAt,watcherAlive:L.watcherAlive}:null,K=!!t.refreshSchedulerEnabled,J=await yc(),ge=await d(),z=t.persistenceOwner==="tray",Ve=z?await l(t)==="healthy":null,we=await GS({daemonEnabled:h&&!z,daemonHealthy:h?!!m:null,schedulerEnabled:K&&!z,schedulerInstalled:J,binaryDurable:!Ke(er())}),be=await wu(),he=0;p&&!p.reachable&&(he+=1),h&&!m&&(he+=1),z?K&&!Ve&&(he+=1):K&&!J&&(he+=1);for(let Y of R)he+=ey(Y);return H&&H.kind!=="ok"&&!H.notApplicableSubscription&&(he+=1),X&&X.kind!=="ok"&&(he+=1),re?.verdict==="dark"&&(he+=1),I.length>0&&(he+=1),he+=je.filter(Y=>!Y.watcherAlive).length,be.length>0&&(he+=1),{report:{format:1,generatedAt:new Date().toISOString()},connect:{version:cG(),node:process.versions.node,platform:`${process.platform}/${process.arch}`,remoteContext:gt(),selfUpdate:{managed:ge.managed,available:ge.available,autoUpdate:ge.autoUpdate,state:ge.state}},gateway:{origin:e,reachable:p?p.reachable:null,detail:p?p.detail:"not probed (--quick)"},toolOrigin:w,fallbackProxy:{enabled:h,port:h?t.fallbackPort:null,healthy:h?!!m:null},refreshScheduler:{enabled:K,installed:J,owner:z?"tray":"os",...z?{trayHealthy:!!Ve}:{}},serviceRemoval:we,retiredFallbackState:be,fleetdPresent:await La(),identity:{user:t.name??null,team:t.team??null,authMode:t.authMode??null,personalKeySource:g,clientKeyExpiresAt:t.clientKeyExpiresAt??null},enrollment:{enrolled:!!y,deploymentId:y?.deploymentId??null,issuedAt:y?.issuedAt??null,expiresAt:b,expired:b?Date.parse(b)<Date.now():null,orgMode:E,ssoLink:S},shell:{profilePath:x,blockPresent:A,staleExports:I},tools:R,...t.fleetToolPolicy?{fleetPlan:nd(t,t.fleetToolPolicy,!1)}:{},cursorQueue:T,pendingOps:je,ambientRepairs:mG(ie,r),verify:H,retrieval:X,hookLane:re,problems:he}},gG=e=>{if(e.serviceRemoval.suspected){W("Endpoint security"),N(" Anyray installed these background services, but their files are gone from disk \u2014"),N(" endpoint-security software (SentinelOne, CrowdStrike, Defender \u2026) quarantines them"),N(" as suspected persistence. Re-running connect just rewrites them.");for(let t of e.serviceRemoval.missingPaths)k(v(` missing: ${t}`));k(v(" Fix now: `anyray-connect --no-key-refresh` \u2014 installs no background service, points")),k(v(" tools straight at the gateway (your key then needs a periodic re-run).")),k(v(" Fix properly: `anyray-connect doctor --security-review` prints the allow-list your")),k(v(" security team needs; once approved, `anyray-connect --yes` restores auto-refresh."))}},wG=e=>{if(e.retiredFallbackState.length!==0){W("Retired fallback lane"),_(" A cached organization provider key from the removed --fallback lane is still on this machine.");for(let t of e.retiredFallbackState)k(v(` ${t}`));k(v(" Fix: `anyray-connect doctor --repair` deletes it (a normal `anyray-connect` run does too)."))}},bG=e=>{switch(k(j("Anyray connect \u2014 doctor")),e.connect.remoteContext&&(W("Environment"),k(` Remote dev context: ${tr(e.connect.remoteContext)}`),At(e.connect.remoteContext)&&k(v(" No per-user service manager here \u2014 key refresh rides the Claude Code helper and `anyray-connect` runs, not an OS schedule."))),W("CLI updates"),e.connect.selfUpdate.state){case"managed":$(" Managed standalone binary installed; one updater owns this seat."),e.connect.selfUpdate.autoUpdate||N(" Automatic CLI updates are off (`anyray-connect update --auto on`).");break;case"will-migrate":N(" This npm runtime will migrate to the managed standalone binary on the next persistent setup change."),k(v(" Run `anyray-connect update` to migrate now."));break;case"platform-unsupported":N(" Self-update is unavailable on this platform because no standalone binary is published."),k(v(" Use `npx anyray-connect@latest` to stay current."));break;case"unmanaged":k(v(" This copy is externally managed; update it with the method that installed it."));break;case"container":k(v(" Self-update is off in this container; updates arrive when it is rebuilt."));break}switch(W("Gateway"),e.gateway.reachable===null?k(v(` Probe skipped (--quick): ${e.gateway.origin} not contacted.`)):e.gateway.reachable?$(` Reachable: ${e.gateway.origin} ${v(`(${e.gateway.detail})`)}`):(_(` Unreachable: ${e.gateway.origin} (${e.gateway.detail})`),k(v(" Fix: start the gateway, or check the URL with `anyray-connect status`."))),e.fallbackProxy.enabled&&(W("Local key-refresh proxy"),e.fallbackProxy.healthy?$(` Running on 127.0.0.1:${e.fallbackProxy.port} \u2192 ${e.gateway.origin} `+v("(auto-refreshes your key so long sessions never 401)")):(_(` Enabled on 127.0.0.1:${e.fallbackProxy.port} but NOT responding \u2014 your tools point at it and cannot reach any gateway until it's back.`),e.serviceRemoval.kinds.includes("daemon")||k(v(" Fix: re-run `anyray-connect` to reinstall it, or `anyray-connect --no-key-refresh` to point tools straight at the gateway.")))),e.refreshScheduler.enabled&&(W("Automatic key refresh"),e.refreshScheduler.owner==="tray"?e.refreshScheduler.trayHealthy?$(" Managed by the Anyray Connect app \u2014 it triggers the ~30-min key refresh and supervises the daemon."):(_(" The Anyray Connect app owns the background services on this machine, but it is missing or no longer passes its signature check."),k(v(" Fix: run `anyray-connect` to restore the background services (it reinstalls the OS schedule and clears the app takeover)."))):e.refreshScheduler.installed?$(" Scheduled \u2014 your gateway key re-mints every ~30 min, so no tool 401s on a stale key mid-session."):(_(" Enabled but the OS schedule is missing \u2014 a long session can still 401 when your key lapses."),e.serviceRemoval.kinds.includes("scheduler")||k(v(" Fix: re-run `anyray-connect` to reinstall it, or `anyray-connect --no-key-refresh` to opt out.")))),gG(e),wG(e),W("Personal key"),uG(e)){case"env":$(" Personal gateway key present ($ANYRAY_CLIENT_KEY).");break;case"profile":$(" Personal gateway key present (enrolled via connect).");break;case"enrolled-no-key":N(" Enrolled, but no personal key is cached locally right now."),k(v(" Fix: re-run `anyray-connect` to re-mint it from your enrollment \u2014 no need to re-enroll. Claude Code and Codex are still attributed to you by name."));break;default:N(" Enrollment required \u2014 no personal gateway key is available."),k(v(` Fix: ${ty(e.enrollment.orgMode,e.enrollment.ssoLink)}, or set $ANYRAY_CLIENT_KEY to a minted ark_ key.`))}e.enrollment.enrolled&&(e.enrollment.expired?N(` Enrollment cert expired ${v(`(${e.enrollment.expiresAt})`)} \u2014 the next run re-enrolls.`):$(` Enrollment cert valid until ${e.enrollment.expiresAt} ${v(`(deployment ${e.enrollment.deploymentId})`)}`)),e.shell.staleExports.length>0&&(W("Shell"),_(" This terminal still exports Anyray, but the config is gone."),k(v(` Still set here: ${e.shell.staleExports.join(", ")}`)),k(v(` No Anyray block in ${e.shell.profilePath} \u2014 so these came from before a revert.`)),k(v(" Anything you start from this terminal keeps reaching the gateway with")),k(v(" no credential, and fails with 401.")),k(v(` Fix: unset ${e.shell.staleExports.join(" ")}`)),k(v(" Or open a new terminal. In VS Code, quit the app entirely (Cmd+Q) \u2014 it")),k(v(" reuses the environment it captured at launch, so a new terminal")),k(v(" (or Reload Window) keeps serving the old one.")));let t=e.tools.find(c=>c.installed&&c.claudeCodeHookPolicy!==void 0&&c.claudeCodeHookPolicy!=="fine");if(t?.claudeCodeHookPolicy){let c={state:t.claudeCodeHookPolicy};W("Claude Code hook policy"),_(` ${nc(c)}.`),k(v(` ${rc(c)}`))}W("Tools");let n=!1,r=!1,o=c=>{for(let l of c.routingOverrides??[])_(` ${c.title}: ${l.problem}.`),k(v(` ${l.fix}`))},a=c=>{c.mcp&&(c.mcp.registered?c.mcp.commandOk===!1?(_(` ${c.title}: retrieval MCP server registered, but its binary is gone (${c.mcp.command}).`),k(v(" Fix: re-run `anyray-connect` to re-register the current binary."))):$(` ${c.title}: retrieval MCP server registered ${v("(anyray_retrieve / anyray_recall)")}`):(N(` ${c.title}: retrieval MCP server not registered \u2014 externalized output can't be pulled back.`),k(v(" Fix: re-run `anyray-connect` from a durable install (registration is skipped for one-off npx runs)."))))};for(let c of e.tools){if(!c.installed){k(v(` ${c.title}: not installed (skipped)`));continue}if(c.pointedAt===null){k(v(` ${c.title}: installed (config not introspectable)`)),a(c);continue}if(c.pointedAt){if(n=!0,c.id==="cursor"&&c.nativeSubscription){$(` ${c.title}: native Cursor subscription; Anyray hooks/MCP active`),k(v(" Note: Claude/Opus model requests remain Cursor-hosted. Anyray can optimize and measure only the supported local Shell/MCP context seams.")),a(c);continue}$(` ${c.title}: pointed at ${e.gateway.origin}${e.fallbackProxy.enabled&&ki(c.id)?v(" (via key-refresh proxy)"):""}`),o(c),c.id==="claude-code"&&k(v(" Note: settings.json routing covers the Claude Code CLI and VS Code extension. For Claude Desktop, use the supported third-party Gateway setup; verified macOS builds can use the Claude Code subscription helper, while Windows remains API-billed.")),c.id===Ia&&k(v(` ${rA}`)),c.id==="codex"&&k(v(" Note: Codex app, CLI, and IDE extension share config.toml; Codex cloud/web tasks cannot route through a local gateway.")),a(c)}else{o(c);let l=A0(c);if(l==="not-routed"||l==="unverifiable"){let d=xd(l,{...c.inferenceUnverifiableReason?{reason:c.inferenceUnverifiableReason}:{},mcpRegistered:c.mcp?.registered===!0});N(` ${c.title}: ${d.headline}`);for(let u of d.detail)k(v(` ${u}`));l==="unverifiable"&&(r=!0)}else c.tombstoned?c.policyTier==="required"?(N(` ${c.title}: reverted locally against admin policy (out of compliance)`),k(v(` Re-enroll with \`anyray-connect --tools ${c.id}\`.`))):c.policyTier==="locked"?N(` ${c.title}: reverted locally but locked by admin policy \u2014 the next reconcile re-applies it`):k(v(` ${c.title}: reverted by you (not managed) \u2014 re-enroll with \`anyray-connect --tools ${c.id}\``)):c.routingPendingReload?(_(` ${c.title}: configured, but ${c.title} is still running the previous Anyray build`),k(v(" Fix: reload the app completely (quit and reopen \u2014 a window reload is not enough), then re-run `anyray-connect`."))):(_(` ${c.title}: installed but not pointed at ${e.gateway.origin}`),k(v(" Fix: run `anyray-connect` to (re)configure it.")))}}let s=(e.repairs?.length??0)>0;if(!n&&!r&&!s&&e.problems===0&&(N(" No tools are pointed at this gateway yet."),k(v(" Fix: run `anyray-connect` to configure your tools."))),e.pendingOps.length>0){W("Queued operations");for(let c of e.pendingOps){let l=Bt(c.adapter)?.title??c.adapter;c.watcherAlive?N(` ${l} ${c.op} queued since ${c.requestedAt} \u2014 completes automatically when ${l} quits.`):(_(` ${l} ${c.op} queued since ${c.requestedAt}, but its watcher is not running.`),k(v(` Fix: quit ${l} and re-run \`anyray-connect\` to complete it.`)))}}if(e.ambientRepairs.length>0){W("Ambient repairs");let c=l=>l==="hook_registration"?"hook re-installed":l==="mcp_registration"?"MCP registration re-installed":"hook binary repaired";for(let l of e.ambientRepairs){let d=Bt(l.tool)?.title??l.tool,u=l.repaired.map(({checkId:p,at:h})=>`${c(p)} ${new Date(h).toISOString().slice(0,10)}`);l.flapping&&u.push(`flapping since ${new Date(l.flapping.since).toISOString().slice(0,10)} (${l.flapping.reason})`);let f=` ${d}: ${u.join("; ")}`;l.flapping?N(f):k(f)}}let i=e.fleetPlan;if(i&&(i.freshIds.length>0||i.tombstonedIds.length>0)){W("Fleet policy");let c=l=>l.map(d=>Bt(d)?.title??d).join(", ");i.freshIds.length>0&&k(` Pending enrollment (the next policy sync applies): ${c(i.freshIds)}`),i.tombstonedIds.length>0&&N(` Out of compliance (reverted against required policy): ${c(i.tombstonedIds)}`)}if(e.verify)if(W("Auth probe"),e.verify.notApplicableSubscription)$(" Provider-key verification is not applicable to subscription/native inference lanes.");else if(e.verify.kind==="ok")$(` ${e.verify.detail}`);else{_(` ${e.verify.kind}: ${e.verify.detail}`);for(let c of e.verify.remedy)k(v(` ${c}`))}if(e.retrieval)if(W("Retrieval loop"),e.retrieval.kind==="ok")$(` ${e.retrieval.detail}`);else{_(` ${e.retrieval.kind}: ${e.retrieval.detail}`);for(let c of e.retrieval.remedy)k(v(` ${c}`))}if(e.hookLane){if(W("Hook lane"),e.hookLane.verdict==="live")$(` ${e.hookLane.detail}`);else if(e.hookLane.verdict==="dark"){_(` ${e.hookLane.reason}: ${e.hookLane.detail}`);for(let c of e.hookLane.remedy)k(v(` ${c}`))}else{N(` ${e.hookLane.reason}: ${e.hookLane.detail}`);for(let c of e.hookLane.remedy)k(v(` ${c}`))}e.hookLane.lastInvokedAt!==null&&k(v(` Last hook run: ${new Date(e.hookLane.lastInvokedAt).toISOString()}`))}W("Summary"),e.problems===0?(e.verify?$(" No problems found."):$(" No configuration problems found (no request was sent \u2014 drop `--no-verify` to test one)."),k(v(" Sharing with support? `anyray-connect doctor --json` prints this as a content-free report."))):_(` ${e.problems} problem(s) found \u2014 see fixes above.`)},kG=e=>({...e,verify:e.verify?{kind:e.verify.kind,detail:"",remedy:e.verify.remedy,...e.verify.notApplicableSubscription?{notApplicableSubscription:!0}:{}}:null,retrieval:e.retrieval?{kind:e.retrieval.kind,detail:"",remedy:e.retrieval.remedy}:null}),AG=async(e,t)=>{let n=e.hookLane;if(!n||n.verdict!=="dark"||n.reason!=="key_rejected")return null;if(!Fh(n.code))return{hookLane:n,note:`Hook lane: the gateway rejected this machine\u2019s key as '${n.code??"unclassified"}', which an automatic re-mint must never answer \u2014 no key was minted. Re-enroll (see the Hook lane fixes above).`};let r=t.probeHookLane??wa,o,a=async()=>(o??=await r().catch(()=>({verdict:"indeterminate",reason:"unreachable"})),o),s=await(t.refreshKey??Qe)({force:!0,hookLaneRepair:!0,probeHookLane:a}).catch(()=>"failed"),i=await a(),c=bn((await(t.readRefreshState??Ut)().catch(()=>({}))).hookLane),l=Kh(i,{hookRegistered:await v0(t.adapters??ae).catch(()=>!1),neverInvoked:Hh(c,Date.now())}),d=s==="disabled"?"Hook lane: key refresh is disabled here (ANYRAY_REFRESH_DISABLE), so no key was minted and the finding stands.":l.verdict==="live"?"Hook lane: re-minted the personal key and rewrote the configured tools \u2014 the lane answers again.":l.verdict==="indeterminate"?`Hook lane: re-mint reported '${s}', but the confirming probe could not establish the lane's state \u2014 nothing is proven fixed and the finding stands.`:`Hook lane: re-mint reported '${s}' and the lane is still not live \u2014 re-enroll (see the Hook lane fixes above).`;return{hookLane:{...l,lastInvokedAt:cd(c)},note:d}},CG=async(e,t,n={})=>{let r=n.adapters??ae,o=n.resolveTarget??_e,a=n.applyTools??wt,s=await AG(e,n).catch(()=>null),i=s&&e.hookLane?.verdict==="dark"&&s.hookLane?.verdict==="live"?1:0,c=s?{hookLane:s.hookLane,notes:[s.note]}:{notes:[]},l=e.tools.filter(y=>y.installed&&(Qm(y)||y.mcp?.commandOk===!1||y.routingOverrides?.some(b=>b.repairable)));if(l.length===0)return{entries:[],remainingProblems:Math.max(0,e.problems-i),refreshedTools:new Map,...c,notes:[...c.notes,"Nothing to repair \u2014 no tool has drifted."]};let d=await o(async()=>t,void 0,Ae);if(!d)return{entries:l.map(y=>({id:y.id,title:y.title,status:"skipped-not-enrolled"})),remainingProblems:Math.max(0,e.problems-i),refreshedTools:new Map,...c,notes:[...c.notes,`Repair needs an enrolled personal key \u2014 ${ty(e.enrollment?.orgMode??"unknown",e.enrollment?.ssoLink??null)}, then re-run.`]};let u=new Set(t.managedTools??[]),f=[],p=[...c.notes],h=[];for(let y of l){let b=r.find(C=>C.id===y.id);if(!u.has(y.id)||!b){f.push({id:y.id,title:y.title,status:"skipped-unmanaged"});continue}h.push(b)}f.length>0&&p.push("Drifted tools outside the managed record are never auto-repaired \u2014 run `anyray-connect` once to (re)configure and record them.");let m=await a(h,d.target),w=new Map,g=0;for(let y of m){if(f.push(y),!uo(y))continue;let b=e.tools.find(R=>R.id===y.id);if(!b)continue;let C=r.find(R=>R.id===y.id),S=b.mcp;if(C?.mcpStatus)try{let R=await C.mcpStatus();S={...R,commandOk:C0(R)}}catch{}let E=Qm(b)?!0:b.pointedAt;if(C?.pointsAt&&b.pointedAt!==null)try{E=await C.pointsAt(Ai(C.id,e.gateway.origin,e.toolOrigin))}catch{}let x=b.routingOverrides,A=b.claudeCodeHookPolicy;if(C?.runtimeDiagnostics)try{let R=await C.runtimeDiagnostics();x=R.routingOverrides.length?R.routingOverrides:void 0,A=R.claudeCodeHookPolicy}catch{}else if(C?.routingOverrides)try{let R=await C.routingOverrides();x=R.length?R:void 0}catch{}let I={...b,pointedAt:E,mcp:S,...x?{routingOverrides:x}:{},...A===void 0?{}:{claudeCodeHookPolicy:A}};x||delete I.routingOverrides,A===void 0&&delete I.claudeCodeHookPolicy,w.set(y.id,I),g+=ey(b)-ey(I)}return{entries:f,remainingProblems:Math.max(0,e.problems-g-i),refreshedTools:w,...s?{hookLane:s.hookLane}:{},notes:p}},vG=e=>{W("Repair"),e.entries.length===0&&$(" Nothing to repair.");for(let t of e.entries)t.status==="configured"||t.status==="reverted"?$(` ${t.title}: re-applied`):t.status==="queued"?$(` ${t.title}: re-apply queued (completes when the app quits)`):t.status.startsWith("skipped-")?k(v(` ${t.title}: ${t.status}`)):_(` ${t.title}: ${t.status}`);for(let t of e.notes)k(v(` ${t}`))},S0=async(e,t={})=>{let n=await P();if(e.securityReview){k(j("Anyray connect \u2014 security review"));for(let c of jS(n.fallbackPort??Ce))k(c?` ${c}`:"");return 0}let r;try{r=Er(e.gateway,n)}catch(c){return e.json?(console.log(JSON.stringify({error:c.message})),1):(k(j("Anyray connect \u2014 doctor")),_(` Gateway URL: ${c.message}`),k(v(" Fix: pass a gateway URL, e.g. `anyray-connect doctor http://localhost:8787`.")),1)}if(e.quick&&e.verify)return e.json?console.log(JSON.stringify({error:"--quick cannot be combined with --verify"})):(k(j("Anyray connect \u2014 doctor")),_(" --quick skips the network probes; it cannot be combined with --verify.")),1;let o=!e.noVerify&&!e.quick,a=await yG(r,n,!!e.verify&&!e.quick,t.adapters??ae,t.inferenceIntrospection??Sd,t.fleetBootstrap??Wt,o,t.verifyAuth??Ri,!e.quick,t.checkTray??wo,t.updateStatus??ko,t.readRefreshState??Ut,t.probeHookLane??wa);e.repair&&a.retiredFallbackState.length>0&&(await Vi(),a.retiredFallbackState=await wu(),a.retiredFallbackState.length===0&&(a.problems-=1));let s=e.repair?await CG(a,n,t):void 0,i=s?{...a,tools:a.tools.map(c=>s.refreshedTools.get(c.id)??c),...s.hookLane!==void 0?{hookLane:s.hookLane}:{},repairs:s.entries,problems:s.remainingProblems}:a;e.json?console.log(JSON.stringify(kG(i),null,2)):(bG(i),s&&vG(s));try{e.quick||await(t.reportHealth??Nv)(k0(i),i.connect.version)}catch{}return i.problems===0?0:1};var SG=()=>{let e=[];for(let t of ae){let n=t.skillsDir?.();n&&e.push(n)}return e},E0=async e=>{let t=await P();k(j("Anyray connect \u2014 sync"));let n;try{n=Er(e.gateway,t)}catch(s){return _(s.message),1}F(`Gateway: ${n}`);let r=bE(t.clientKey,"anyray-placeholder"),o;try{o=await od(n,r)}catch(s){return _(`Team policy sync failed: ${rd(s)}`),1}let a=SG();if(a.length===0)EG();else if(o.skills.length===0)F("No team skills published yet \u2014 nothing to sync.");else{let s=await yv(o,a,t.syncedSkills??{});W("Skills");for(let i of s.results)i.written?$(` ${i.name} ${v(`(${i.id}@${i.version})`)} \u2192 ${i.files.length} file(s)`):F(` ${i.name} ${v(`(${i.id}@${i.version})`)} \u2014 up to date`);try{await te({...t,syncedSkills:s.versions,syncedAt:s.updatedAt??new Date().toISOString()})}catch(i){F(`Could not record sync state: ${i instanceof Error?i.message:String(i)}`)}W("Summary"),k(` ${et(String(s.changed))} updated, ${s.unchanged} unchanged, across ${a.length} tool dir(s).`)}try{let s=await ad(o);(s.routingUpdated||s.teamUpdated||s.toolsRequested>0||s.toolsTombstoned.length>0)&&(k(`Fleet policy: routing ${s.routingUpdated?"updated":"unchanged"}, team ${s.teamUpdated?"updated":"unchanged"}, ${s.toolsApplied}/${s.toolsRequested} tool(s) reconciled${s.toolsEnrolled>0?` (${s.toolsEnrolled} newly enrolled)`:""}.`),s.toolsTombstoned.length>0&&F(` Locally reverted against admin policy (out of compliance): ${s.toolsTombstoned.join(", ")}. Re-run \`anyray-connect --tools <id>\` to re-enroll.`))}catch(s){F(`Fleet policy reconcile skipped: ${rd(s)}`)}return 0},EG=()=>{F("No installed tool exposes a skills directory \u2014 nothing to sync.")};import{gzip as Sj}from"node:zlib";import{promisify as Ej}from"node:util";var Or={maxChars:12e3,headChars:6e3,tailChars:4e3,middleWindows:3},ny=e=>({text:e,trimmed:!1,originalChars:e.length,trimmedChars:e.length,charsRemoved:0,estTokensSaved:0}),x0=e=>`
|
|
691
|
+
`)){let[r,o]=n.trim().split(/\s+/);if(!r||!o)continue;if((o.startsWith("*")?o.slice(1):o)===t&&/^[0-9a-f]{64}$/i.test(r))return r.toLowerCase()}},f0=e=>{if(e.latest===e.current)return{apply:!1,mandatory:!1};if(e.autoUpdate||e.forced)return{apply:!0,mandatory:!1};let t=!!e.minVersion&&Pa(e.current,e.minVersion)<0&&Pa(e.latest,e.minVersion)>=0;return{apply:t,mandatory:t}},EK=e=>Pa(e.latest,e.current)<0?{apply:!1,mandatory:!1,downgradeBlocked:!0}:e.latest===e.current?{apply:e.autoUpdate||e.forced===!0,mandatory:!1,downgradeBlocked:!1}:{...f0(e),downgradeBlocked:!1},Ta=()=>process.platform==="win32"?"anyray-connect.exe":"anyray-connect",xK=(e=process.execPath)=>{let t=Su(e);return t?Ir(t):Ir(Ir(e))},IK=async(e=yt())=>{if(/[\\/]node(\.exe)?$/i.test(e.execPath))return;let t=ft(xK(e.execPath),"bin",Ta());try{if(await Hd(t)!==await Hd(e.execPath))return}catch{return}return t},Km=async(e=yt(),t=Q())=>{let n=await IK(e);if(n)return{kind:"managed",root:Ir(Ir(n)),link:n,entryPath:Yn(e)};let r=Yn(e);return xu(r,t)?{kind:"durable",root:t,entryPath:r}:Cu(r)?{kind:"npm",root:t,entryPath:r}:{kind:"unmanaged",root:t,entryPath:r}},Kd=async(e,t,n)=>{let r=new AbortController,o=setTimeout(()=>r.abort(),t);try{return await fetch(e,{...n,signal:r.signal})}finally{clearTimeout(o)}},Gm=async(e=Wd)=>{let t=await Kd(`${d0}/latest`,e,{redirect:"manual"});return SK(t.headers.get("location"))},OK=async e=>{try{let t=await Kd(`${e}/connect-update.json`,Wd);if(!t.ok)return;let n=await t.json();if(!n||typeof n!="object")return;let r=n.minVersion;return typeof r=="string"&&/^\d+\.\d+\.\d+/.test(r)?r:void 0}catch{return}},xi=class extends Error{status;constructor(t){super(`download failed (${t})`),this.status=t,this.name="DownloadHttpError"}},jm=async(e,t,n)=>{let r=await Kd(e,AK);if(!r.ok||!r.body)throw new xi(r.status);let o=yK("sha256"),a=0;if(await wK(gK.fromWeb(r.body),async function*(s){for await(let i of s){let c=i;if(a+=c.length,a>kK)throw new Error("asset exceeds size cap");o.update(c),yield c}},dK(t,{mode:493})),o.digest("hex")!==n)throw new Error("checksum mismatch")},RK=e=>Mm(e)===Ta()?Mm(Ir(e)):Mm(e),_K=async e=>{let t=await Hm(e).catch(()=>[]);for(let n of t)/\.part-\d+$/.test(n)&&await Ot(ft(e,n),{force:!0}).catch(()=>{})},h0=async(e,t)=>{if(process.platform==="win32"){let r=`${e}.old-${process.pid}`;await Ot(r,{force:!0}).catch(()=>{});let o=!1;try{await Ud(e,r),o=!0}catch{}try{await Bm(t,e),await mK(ja(e),RK(t))}catch(a){throw o&&await Ud(r,e).catch(()=>{}),a}await Ot(r,{force:!0}).catch(()=>{});return}let n=`${e}.new-${process.pid}`;await Ot(n,{force:!0}),await hK(t,n),await Ud(n,e)},PK=async(e,t={})=>{let n=ft(e.root,"bin"),r=ft(e.root,"versions"),o=ft(n,Ta());await _a(n,{recursive:!0,mode:448}),await _a(r,{recursive:!0,mode:448});let a=ft(r,e.version),i=(await Um(a).catch(()=>{}))?.isFile()?a:ft(a,Ta());if(!(await Um(i).catch(()=>{}))?.isFile()){let l=await(t.fetchResponse??Kd)(`${e.tagUrl}/SHA256SUMS`,Wd),d=l.ok?Wm(await l.text(),e.asset):void 0;if(!d)throw new Error("no published checksum");await _a(Ir(i),{recursive:!0,mode:448}),await _K(Ir(i));let u=`${i}.part-${process.pid}`;try{await(t.download??jm)(`${e.tagUrl}/${e.asset}`,u,d),await pK(u,493),await Ud(u,i)}catch(f){throw await Ot(u,{force:!0}).catch(()=>{}),f}}return await(t.activate??h0)(o,i),{link:o,target:i,versionsDir:r}},TK=async e=>{let t=uK(e,["--version"],{stdio:"ignore",timeout:Wd});return!t.error&&t.status===0},LK=async(e,t={})=>{let n=e.managedTools??[];if(n.length>0){let r=await(t.findTools??po)(n);if(r.length>0){let o=await(t.resolveTarget??_e)(async()=>e);if(!o||!(await(t.repair??wt)(r,o.target)).every(uo))return!1}}return e.persistenceOwner==="tray"?!0:!(e.refreshSchedulerEnabled&&!(await(t.installScheduler??rr)()).ok||e.keyRefreshEnabled&&(!e.gateway||!e.fallbackPort||!(await(t.installDaemon??Pt)({port:e.fallbackPort,remoteOrigin:e.gateway})).ok))},DK=async e=>{let t=await e.install();if(!await(e.smoke??TK)(t.target))throw await e.rollback?.(t),new Error("managed binary smoke test failed");if(!await e.repoint(t.link))throw new Error("persistent config repoint failed");return await e.prune(),t},NK=async(e,t)=>{let n=await Hm(e).catch(()=>[]);for(let r of n)t.includes(r)||await Ot(ft(e,r),{force:!0,recursive:!0}).catch(()=>{})},$K=async e=>{let t=await Hm(e).catch(()=>[]);for(let n of t)/\.(new|old|rollback)-\d+$/.test(n)&&await Ot(ft(e,n),{force:!0}).catch(()=>{})},MK=async(e,t)=>{let n=async()=>{await Ot(e,{recursive:!0,force:!0}).catch(()=>{})};try{return await _a(e,{recursive:!1}),n}catch{}let r=await fK(e).catch(()=>{});if(!(!r||t-r.mtimeMs<vK)){await n();try{return await _a(e,{recursive:!1}),n}catch{return}}},Fm=e=>ft(e,"update-state.json"),FK=async e=>{let t=await M(e).catch(()=>({})),n=t.failedVersion,r=t.failedAt;return{failedVersion:typeof n=="string"?n:void 0,failedAt:typeof r=="number"?r:void 0}},BK=1e3,UK=16*6e4,HK=e=>e.inFlight===0,WK=async(e,t,n={})=>{let r=n.probe??Ae,o=n.sleep??(i=>new Promise(c=>setTimeout(c,i))),a=n.now??Date.now,s=a()+(n.timeoutMs??UK);for(;;){let i=await r(e).catch(()=>null);if(i!==null&&i.version===t&&HK(i))return!0;if(a()>=s)return!1;await o(BK)}},Ii=async(e={})=>{let t=e.now??Date.now,n=ke;if(At(gt(e.env??process.env)))return{outcome:"container",current:n};let r=e.context??yt(),o=e.root??Q(),a;try{let s=await Km(r,o);if(o=s.root,s.kind==="unmanaged")return{outcome:"unmanaged",current:n};if(s.kind==="npm"&&!e.allowNpmMigration)return{outcome:"unmanaged",current:n};let i=s.kind!=="managed",c=p0(e.platform??process.platform,e.arch??process.arch);if(!c)return{outcome:"platform-unsupported",current:n};if(a=await(e.latestVersion??Gm)().catch(()=>{}),!a)return{outcome:"unavailable",current:n};let l=a;if(!i&&l===n)return{outcome:"current",current:n,latest:l};if(i&&Pa(l,n)<0)return{outcome:"migration-deferred",current:n,latest:l};let d=e.force===!0,u=await FK(Fm(o));if(!d&&u.failedVersion===l&&u.failedAt!==void 0&&t()-u.failedAt<CK)return{outcome:"failed",current:n,latest:l};let f=`${d0}/download/${u0}${l}`,p=await(e.load??P)().catch(()=>({})),h=p.autoUpdate!==!1,m=h||d?void 0:await(e.minimumVersion??OK)(f),w={current:n,latest:l,autoUpdate:h,forced:d,minVersion:m},g=i?EK(w):{...f0(w),downgradeBlocked:!1};if(g.downgradeBlocked)return{outcome:"migration-deferred",current:n,latest:l};if(!g.apply)return{outcome:"disabled",current:n,latest:l};if(e.checkOnly)return{outcome:i?"migration-available":"available",current:n,latest:l,mandatory:g.mandatory};o===Q()?await kt():await _a(o,{recursive:!0,mode:448});let y=await MK(ft(o,"update.lock"),t());if(!y)return{outcome:i?"migration-available":"available",current:n,latest:l};let b,C;try{await $K(ft(o,"bin"));let x=await Hd(ft(o,"versions")).catch(()=>{}),A=await Hd(ft(o,"bin",Ta())).catch(()=>{}),I=A&&Xi(A,x)?A:void 0,R=ft(o,"bin",Ta());i&&process.platform==="win32"&&(await Um(R).catch(()=>{}))?.isFile()&&(C=`${R}.rollback-${process.pid}`,await Bm(R,C));let B=()=>(e.installBinary??PK)({root:o,version:l,asset:c,tagUrl:f});i?b=await DK({install:B,smoke:e.smoke,rollback:async({link:V,target:H})=>{C?(await Bm(C,V),await Ot(ja(V),{force:!0}).catch(()=>{})):I&&I!==H?await h0(V,I):(await Ot(V,{force:!0}),await Ot(ja(V),{force:!0}).catch(()=>{}))},repoint:async V=>e.repoint?e.repoint(p,V):LK(p),prune:async()=>{await(e.pruneDurable??(V=>Ji(V)))(r)}}):b=await B(),await NK(b.versionsDir,[l,n]),await Ot(Fm(o),{force:!0}).catch(()=>{})}finally{C&&await Ot(C,{force:!0}).catch(()=>{}),await y()}let S=e.bounceDaemon??Uu,E=p.persistenceOwner==="tray";if(!i&&(p.refreshSchedulerEnabled||p.keyRefreshEnabled)){let x=p.fallbackPort??Ce,A=E?!0:await Kg().catch(()=>!0),I=await S(p.fallbackPort,{drain:"idle"}).catch(()=>!1);!A&&p.gateway&&((I?await(e.waitForDaemon??WK)(x,l):!0)?await Pt({port:x,remoteOrigin:p.gateway}).catch(()=>{}):await(e.writeUnitFile??jg)().catch(()=>!1))}return{outcome:i?"migrated":"updated",current:n,latest:l,managedPath:b.link,mandatory:g.mandatory}}catch{return a&&await Z(Fm(o),{failedVersion:a,failedAt:t()},{backup:!1}).catch(()=>{}),{outcome:"failed",current:n,latest:a}}},m0=async(e={})=>{let t=e.context??yt(),n=await Km(t,e.root??Q()),r=Oo(e.root??Q());return n.kind==="managed"||(n.kind==="npm"||n.kind==="durable")&&r?{outcome:"current",current:ke,managedPath:n.link??r}:Ii({...e,context:t,allowNpmMigration:!0})},ko=async(e={})=>{let t=e.context??yt(),n=e.root??Q(),r=await Km(t,n),o=r.kind==="npm"||r.kind==="durable"?Oo(n):void 0,a=await(e.load??P)().catch(()=>({})),s=r.kind==="managed"||r.kind==="durable"||r.kind==="npm"||!!o,i=s&&!!p0(e.platform??process.platform,e.arch??process.arch),c=r.link??o,l=At(gt(e.env??process.env))?"container":s?i?c?"managed":"will-migrate":"platform-unsupported":"unmanaged";return{version:ke,managed:!!c,available:i,autoUpdate:a.autoUpdate!==!1,path:c??r.entryPath,state:l}};var KK=async(e,t)=>{if(!e.gateway||!e.clientKey)return;let n=await t().catch(()=>{});return me({origin:e.gateway,clientKey:e.clientKey,subscription:e.authMode==="subscription",placeholder:e.authMode==="placeholder",byoUpstream:e.byoUpstream,seat:n,user:e.name,team:e.team})},y0=(e,t)=>e.keyRefreshEnabled===t.keyRefreshEnabled&&e.fallbackPort===t.fallbackPort,GK=(e,t)=>async n=>{let r=await e(),{next:o,result:a}=n(r);return o&&await t(o),a},Vm=async(e={})=>{let t=e.load??P,n=e.save??te,r=e.mutate??(e.load||e.save?GK(t,n):Qy),o=e.loadDevKey??Me,a=e.heartbeat??sd,s=e.detectSeat??Tt,i=e.rewriteTools??di,c=e.uninstallProxy??Zt;try{let l=await t();if(l.credentialProtocol==="stable-heartbeat-v1"&&l.directMigration==="complete")return"already-direct";if(!l.keyRefreshEnabled&&!l.refreshSchedulerEnabled||!l.gateway||!l.clientKey||!l.enrolledCert)return"not-eligible";let d=l.enrolledCert.sig,u=await o();if(!u)return"not-eligible";let f;try{f=await a(l.gateway,l.clientKey,l.enrolledCert,u)}catch(y){return y instanceof br&&y.status===404?"unsupported":"pending"}let p=await r(y=>{if(y.clientKey!==l.clientKey||y.enrolledCert?.sig!==d||!y0(y,l))return{result:void 0};let b={...y,clientKeyExpiresAt:f.expiresAt,credentialProtocol:"stable-heartbeat-v1",directMigration:"pending"};return{next:b,result:b}});if(!p)return"pending";let h=await KK(p,s);if(!h)return"pending";let m=l.keyRefreshEnabled===!0,w=Number.isInteger(l.fallbackPort)&&l.fallbackPort>0&&l.fallbackPort<=65535?l.fallbackPort:Ce;if(m){let y=`http://${mt}:${w}`;if(await i(h,y)===!1)return"pending"}return await r(y=>y.clientKey!==l.clientKey||y.enrolledCert?.sig!==d||y.credentialProtocol!=="stable-heartbeat-v1"||y.directMigration!=="pending"||!y0(y,p)?{result:!1}:{next:{...y,clientKeyExpiresAt:f.expiresAt,credentialProtocol:"stable-heartbeat-v1",directMigration:"complete",keyRefreshEnabled:!1,fallbackPort:void 0},result:!0})?((m||l.fallbackPort!==void 0)&&await c(w).catch(()=>{}),"migrated"):"pending"}catch{return"pending"}};var jK=12e3,VK="anyray-wiring-probe-not-a-real-token",YK={model:"anyray-default",messages:[{role:"user",content:"ping"}],max_tokens:1},Zm={model:"claude-3-5-haiku-20241022",max_tokens:1,messages:[{role:"user",content:"ping"}]},Ao=e=>{let t=e.replace(/\s+/g," ").trim();return t.length>160?`${t.slice(0,157)}\u2026`:t},w0=e=>{let t=e.toLowerCase();return t.includes("bedrock")||t.includes("unsupported model")},Xm=e=>{let t=e.toLowerCase();return t.includes("client key required")||["missing_key","key_unknown","key_expired","key_revoked"].some(n=>t.includes(`"${n}"`))},g0=e=>["Note: OpenCode\u2019s Claude provider can ONLY use a server-side key \u2014 unlike","Claude Code, it has no personal-subscription path. For Claude, either:",...e," \u2022 use Claude Code with your own Claude subscription instead of OpenCode.","OpenCode ChatGPT OAuth uses a non-configurable endpoint. Use Codex for"," config-native ChatGPT subscription pass-through, or use an OpenCode"," API-key/Copilot provider that Connect can route."],ZK=e=>e.includes("no provider key configured for"),Jm=e=>{let t=e.toLowerCase();return t.includes("verified_dev_required")||t.includes("verified developers")},zm=e=>({kind:"enrollment-required",detail:`gateway requires per-developer enrollment (HTTP ${e}).`,remedy:["This gateway only serves enrolled developers. Re-run with your enrollment","link from your admin so connect can mint your personal key automatically:"," anyray-connect --enroll <link>"]}),Oi=e=>({kind:"key-rejected",detail:`gateway rejected the client key (HTTP ${e}).`,remedy:["The gateway did not receive a usable personal key (missing, unknown, expired,","or revoked). Re-run `anyray-connect` to refresh an existing enrollment, or","use `--enroll` / `--sso` to enroll first."]}),XK=(e,t,n=[])=>e>=200&&e<300?{kind:"ok",detail:"gateway served a completion with the org key \u2014 traffic flows.",remedy:[]}:e===401||e===403?Jm(t)?zm(e):Xm(t)?Oi(e):w0(t)?{kind:"routed-elsewhere",detail:`gateway routed to the org provider and it rejected the request: ${Ao(t)}`,remedy:["The org provider rejected the request \u2014 check the gateway\u2019s provider","key/config (e.g. the model is enabled for that account)."]}:ZK(t)?{kind:"provider-rejected",detail:`gateway has no server-side provider key for this lane (HTTP ${e}): ${Ao(t)}`,remedy:["Your enrollment key is fine \u2014 the gateway has NO server-side provider","key configured (org-key mode), so it refused to forward the request.","Fix: add a provider key in the console \u2192 Providers.",...n.includes("opencode")?g0([" \u2022 add a provider key in the console \u2192 Providers (fixes it for everyone), or"]):["If you ONLY use a subscription tool (e.g. Copilot), this org-key check","does not apply \u2014 you can ignore it."]]}:{kind:"provider-rejected",detail:`gateway accepted your key but the model provider rejected the request (HTTP ${e}): ${Ao(t)}`,remedy:n.includes("opencode")?["Your enrollment key is fine \u2014 the gateway forwarded the request and the","upstream model provider refused the credential it was given: this","gateway has no WORKING provider key for it (either none is configured,","or the configured one is wrong or revoked).",...g0([" \u2022 open the console \u2192 Providers and add a key for that provider, or"," replace the one already listed (fixes it for everyone), or"])]:["Your enrollment key is fine \u2014 the gateway forwarded the request and the","upstream model provider refused it.","Open the console \u2192 Providers: if no key is listed for that provider,","add one; if a key IS listed, it is wrong, revoked, or not entitled to","the model \u2014 replace it.","Either way this is gateway config, not your enrollment. Alternatively,","sign in with your own provider subscription instead of the org key.","If you ONLY use a subscription tool (e.g. Copilot), this org-key check","does not apply \u2014 you can ignore it."]}:{kind:"unknown",detail:`gateway responded HTTP ${e}: ${Ao(t)}`,remedy:[]},JK=(e,t)=>{if(Xm(t))return Oi(e);if(Jm(t))return zm(e);if(w0(t))return{kind:"routed-elsewhere",detail:"gateway sent the request to the org provider, not your subscription.",remedy:["Pass-through isn\u2019t being honored for this gateway \u2014 your seat token would","not be used. Check the gateway is current (subscription pass-through support)."]};let n=t.toLowerCase();return e===401||n.includes("authentication_error")||n.includes("invalid bearer")||n.includes('"provider":"anthropic"')?{kind:"ok",detail:"gateway passes your sign-in through to Anthropic \u2014 your Claude seat will be used.",remedy:[]}:e>=200&&e<300?{kind:"ok",detail:"gateway pass-through reached the provider \u2014 your seat will be used.",remedy:[]}:{kind:"unknown",detail:`seat-wiring probe got HTTP ${e}: ${Ao(t)}`,remedy:[]}},zK=e=>e.includes("anthropic_messages:")||e.includes("invalid model name passed in model=")||e.includes("to view available models"),qK=(e,t)=>{if(Xm(t))return Oi(e);if(Jm(t))return zm(e);let n=t.toLowerCase();if(n.includes("bedrock"))return{kind:"routed-elsewhere",detail:"gateway routed to the org provider instead of the configured BYO upstream.",remedy:["Re-run anyray-connect with your --upstream URL and --upstream-key so","the custom-host pass-through pins are restored."]};if(n.includes("invalid custom host")||n.includes("custom_host_blocked")||n.includes("hostname is not authorized"))return{kind:"routed-elsewhere",detail:"gateway rejected the configured BYO upstream before routing to it.",remedy:["Ask the gateway admin to authorize this LiteLLM/upstream hostname in","ANYRAY_CUSTOM_HOST_ALLOWLIST (or TRUSTED_CUSTOM_HOSTS for an internal host)."]};if(e===401||e===403)return{kind:"provider-rejected",detail:`gateway accepted your personal key but the BYO upstream rejected its credential (HTTP ${e}).`,remedy:["Your Anyray enrollment key is fine. The configured personal upstream key","was rejected by the BYO upstream (for example, LiteLLM). Re-run","anyray-connect with a current --upstream-key."]};let r=e>=400&&e<500&&(n.includes("litellm")||zK(n));return e>=200&&e<300||r?{kind:"ok",detail:e>=200&&e<300?"gateway served a completion through the configured BYO upstream.":`gateway authenticated and reached the configured BYO upstream, which rejected this probe's fixed model (HTTP ${e}).`,remedy:[]}:{kind:"unknown",detail:`BYO-upstream probe got HTTP ${e}: ${Ao(t)}`,remedy:[`The probe asks for a fixed model (${Zm.model}) your upstream`,"is not required to serve, so a model rejection here does not mean your","tools are broken. Check that the upstream serves it before chasing this."]}},Ym=async(e,t,n,r)=>{let o=new AbortController,a=setTimeout(()=>o.abort(),r);try{let s=await fetch(e,{method:"POST",headers:{"content-type":"application/json",...t},body:JSON.stringify(n),signal:o.signal});return{status:s.status,bodyText:await s.text()}}finally{clearTimeout(a)}},QK=async(e,t)=>{if(!e.clientKey)return Oi(401);let n=new AbortController,r=setTimeout(()=>n.abort(),t);try{let o=await fetch(`${e.origin}/connect/savings`,{method:"GET",headers:{"x-anyray-api-key":e.clientKey},signal:n.signal}),a=await o.text();return o.ok?{kind:"ok",detail:"gateway accepted your personal key \u2014 Cursor hooks/MCP can report and retrieve.",remedy:[]}:o.status===401||o.status===403?Oi(o.status):{kind:"unknown",detail:`Cursor hook-auth probe got HTTP ${o.status}: ${Ao(a)}`,remedy:o.status===404?["Update the gateway image \u2014 this one predates the content-free /connect/savings key check."]:[]}}finally{clearTimeout(r)}},eG=(e,t)=>{let n=typeof t?.code=="string"?` ${t.code}`:"";return{kind:"unreachable",detail:`could not reach the gateway to verify (${t instanceof Error&&t.name==="AbortError"?`no response within ${e}ms`:t instanceof Error?`${t.name}${n}`:"unknown error"}).`,remedy:["Your config was still written \u2014 re-run the curl below once the gateway is reachable."]}},Ri=async(e,t={})=>{let n=t.timeoutMs??jK,r=le(e.metadata);try{if(e.authMode!=="placeholder"&&t.tools?.length===1&&t.tools[0]==="cursor")return await QK(e,n);if(e.byoUpstream){let l={Authorization:`Bearer ${e.byoUpstream.key}`,"anthropic-version":"2023-06-01","x-anyray-auth-mode":"passthrough","x-anyray-provider":"anthropic","x-anyray-custom-host":e.byoUpstream.url};e.clientKey&&(l["x-anyray-api-key"]=e.clientKey),r&&(l["x-anyray-metadata"]=r);let{status:d,bodyText:u}=await Ym(`${e.anthropicBaseUrl}/v1/messages`,l,Zm,n);return qK(d,u)}if(q(e,"anthropic")){let l={Authorization:`Bearer ${VK}`,"anthropic-version":"2023-06-01","anthropic-beta":"oauth-2025-04-20","x-anyray-auth-mode":"passthrough","x-anyray-provider":"anthropic"};r&&(l["x-anyray-metadata"]=r),e.clientKey&&(l["x-anyray-api-key"]=e.clientKey);let{status:d,bodyText:u}=await Ym(`${e.anthropicBaseUrl}/v1/messages`,l,Zm,n);return JK(d,u)}let s={Authorization:`Bearer ${e.clientKey??e.placeholderKey}`};r&&(s["x-anyray-metadata"]=r);let{status:i,bodyText:c}=await Ym(`${e.openaiBaseUrl}/chat/completions`,s,YK,n);return XK(i,c,t.tools??[])}catch(o){return eG(n,o)}};var b0=async e=>{let t=await P(),n;try{n=Er(e.gateway,t)}catch(s){return k(j("Anyray connect \u2014 status")),F(`Gateway: ${s.message}`),0}k(j("Anyray connect \u2014 status")),W("Gateway"),k(` Origin: ${et(n)}`),t.gateway?F(" (cached in ~/.anyray)"):process.env.ANYRAY_GATEWAY_URL?F(" (from $ANYRAY_GATEWAY_URL)"):e.gateway||F(" (default \u2014 not yet connected; run `anyray-connect` to set up)"),W("Identity"),k(` Name: ${t.name??v("(not set)")}`),k(` Team: ${t.team??v("(not set)")}`);let r=gt();r&&(W("Environment"),k(` Remote dev context: ${tr(r)}`),At(r)&&F(" No per-user service manager here \u2014 key refresh rides the Claude Code helper and `anyray-connect` runs, not an OS schedule."),F(" VS Code tools configure the remote server variant backing this window.")),t.credentialProtocol==="stable-heartbeat-v1"&&(W("Credential renewal"),t.directMigration==="pending"?(k(" Stable-key heartbeat active; direct-routing migration is still completing."),F(" The local proxy remains available until every managed tool moves.")):($(" Direct gateway routing with a proof-backed stable-key heartbeat."),F(" Renewal extends the same key; tool configuration is not rewritten.")));let o=!!(rt(t)&&t.fallbackPort),a=o?`http://${mt}:${t.fallbackPort}`:n;o&&(W("Local key-refresh proxy"),await Ae(t.fallbackPort)?$(` Running on 127.0.0.1:${t.fallbackPort} \u2192 ${n} `+v("(auto-refreshes your key so long sessions never 401)")):(N(` Enabled on 127.0.0.1:${t.fallbackPort} but NOT responding \u2014 your tools cannot reach any gateway until it's back.`),k(v(" Re-run `anyray-connect`, or check the service logs.")))),W("Tools");for(let s of ae){if(!(await s.detect()).installed){F(` ${s.title}: not installed`);continue}if(!s.pointsAt){F(` ${s.title}: installed ${v("(status not introspectable)")}`);continue}let c=await s.pointsAt(Ai(s.id,n,a));if(c){if(s.id==="cursor"&&(t.authMode==="auto"||t.authMode==="subscription")){$(` ${s.title}: native Cursor subscription; Anyray hooks/MCP active`),k(v(" Claude/Opus model requests remain Cursor-hosted; only supported local Shell/MCP context is optimized by Anyray."));continue}$(` ${s.title}: pointed at Anyray${o&&ki(s.id)?v(" (via key-refresh proxy)"):""}`)}else{let l=null,d=null;if(s.id===Ia&&s.mcpStatus)try{let u=(await s.mcpStatus()).registered,f=await Sd();l=Ed({id:s.id,installed:!0,pointedAt:c,mcpRegistered:u,introspectable:f.authoritative}),d={...f.authoritative?{}:{reason:f.reason},mcpRegistered:u}}catch{l=null,d=null}if((l==="not-routed"||l==="unverifiable")&&d){let u=xd(l,d);N(` ${s.title}: ${u.headline}`);for(let f of u.detail)k(v(` ${f}`))}else F(` ${s.title}: installed, not pointed at this gateway`)}}return 0};import{existsSync as sG}from"node:fs";import{isAbsolute as iG}from"node:path";import{access as tG}from"node:fs/promises";import{constants as nG}from"node:fs";import{platform as rG}from"node:os";var oG=async e=>{try{return await tG(e,nG.F_OK),!0}catch{return!1}},aG=e=>e==="darwin"?["/Library/LaunchDaemons/com.fleetdm.orbit.plist","/opt/orbit/bin/orbit"]:e==="linux"?["/etc/systemd/system/orbit.service","/usr/lib/systemd/system/orbit.service","/opt/orbit/bin/orbit"]:e==="win32"?["C:\\Program Files\\Orbit\\bin\\orbit\\orbit.exe"]:[],La=async(e={})=>{let t=e.os??rG(),n=e.exists??oG;for(let r of aG(t))if(await n(r))return!0;return!1};var on="connect",qm=e=>e.replace(/-/g,"_"),k0=e=>{let t=[];e.gateway.reachable!==null&&t.push({tool:on,checkId:"gateway_reachable",status:e.gateway.reachable?"ok":"unreachable"});let n=Date.parse(e.report.generatedAt),r=Date.parse(e.enrollment.expiresAt??""),o=e.enrollment.enrolled&&e.enrollment.expired===!1&&Number.isFinite(n)&&Number.isFinite(r)&&r-n<=336*60*60*1e3;if(t.push({tool:on,checkId:"enrollment_cert",status:e.enrollment.expired?"expired":o?"problems":e.enrollment.enrolled?"ok":"unenrolled",...o?{errorClass:"cert_expiring"}:{}}),t.push({tool:on,checkId:"shell_exports",status:e.shell.staleExports.length?"stale":"ok"}),e.fallbackProxy.enabled&&t.push({tool:on,checkId:"fallback_proxy",status:e.fallbackProxy.healthy===!1?"fail":e.fallbackProxy.healthy===!0?"ok":"unknown"}),e.refreshScheduler.enabled){let i=e.refreshScheduler.owner==="tray"?e.refreshScheduler.trayHealthy===!0:e.refreshScheduler.installed;t.push({tool:on,checkId:"refresh_scheduler",status:i?"ok":"missing",...i?{}:{errorClass:e.serviceRemoval?.kinds.includes("scheduler")?"unit_deleted":"refresh_scheduler_missing"}})}if(e.pendingOps.some(i=>!i.watcherAlive)&&t.push({tool:on,checkId:"pending_op",status:"problems",errorClass:"watcher_dead"}),e.retrieval){let i=qm(e.retrieval.kind);t.push({tool:on,checkId:"retrieval_loop",status:i,...i==="ok"?{}:{errorClass:`retrieval_${i}`}})}if(e.verify){let i=e.verify.notApplicableSubscription===!0,c=i?"ok":qm(e.verify.kind);t.push({tool:on,checkId:"auth_verify",status:c,...i?{errorClass:"verify_not_applicable_subscription"}:c==="ok"?{}:{errorClass:`verify_${c}`}})}for(let i of e.tools)!i.installed||i.claudeCodeHookPolicy===void 0||t.push({tool:i.id,checkId:"hook_policy",status:i.claudeCodeHookPolicy==="fine"?"ok":i.claudeCodeHookPolicy});if(e.hookLane&&e.hookLane.verdict!=="indeterminate"){let i=e.hookLane.verdict==="dark";t.push({tool:on,checkId:"hook_lane",status:i?"dark":"ok",...i?{errorClass:qm(e.hookLane.reason)}:{}})}t.push({tool:on,checkId:"overall",status:e.problems===0?"ok":"problems"});let a=new Set(e.fleetPlan?.tombstonedIds),s=new Set(e.fleetPlan?.candidateIds);for(let i of e.tools)i.installed&&(i.pointedAt!==null?t.push({tool:i.id,checkId:"routing",status:i.pointedAt?i.routingOverrides?.some(c=>c.bypass!==!1)?"bypassed":"ok":i.routingPendingReload?"reload_required":"fail"}):i.routingHeld&&t.push({tool:i.id,checkId:"routing",status:"held"}),i.inferenceUnverifiableReason==="managed-policy"&&t.push({tool:i.id,checkId:"machine_policy",status:"blocked"}),i.mcp&&t.push({tool:i.id,checkId:"mcp_registration",status:i.mcp.registered?i.mcp.commandOk===!1?"command_gone":"ok":i.routingHeld?"held":"missing"}),a.has(i.id)?t.push({tool:i.id,checkId:"fleet_compliance",status:"reverted_required"}):s.has(i.id)&&t.push({tool:i.id,checkId:"fleet_compliance",status:"ok"}));return t.push({tool:on,checkId:"doctor_report",status:e.problems===0?"ok":"problems"}),t};function cG(){return ke}var lG="ctx_doctor-probe-synthetic",dG=(e,t={mode:"unknown",ssoLink:null})=>{if(e.ok||e.kind==="not-found")return{kind:"ok",detail:"Retrieval loop healthy: gateway answered, key authorized, optimizer retrieval wired.",remedy:[]};switch(e.kind){case"auth":return{kind:"auth",detail:"The gateway rejected the retrieval call (no valid personal key).",remedy:[`Fix: ${ty(t.mode,t.ssoLink)}, or set ANYRAY_CLIENT_KEY.`,"Retrieval needs a personal key \u2014 the MCP server hits the same wall, so externalized output is unretrievable until this is fixed."]};case"unsupported":return{kind:"unsupported",detail:"The gateway has no /connect/retrieve route.",remedy:["Fix: update the gateway image \u2014 this one predates the retrieval loop."]};case"timeout":case"network":return{kind:"unreachable",detail:`Could not reach the gateway for the retrieval probe (${e.kind}).`,remedy:["Fix: check the gateway origin and network (see the Gateway section above)."]};default:return{kind:"unavailable",detail:e.message,remedy:["Fix: the gateway answered but retrieval is unavailable \u2014 usually the optimizer is down or ANYRAY_OPTIMIZER_URL is unset on the gateway. Check the optimizer service."]}}};function uG(e){return e.identity.personalKeySource==="env"?"env":e.identity.personalKeySource==="profile"?"profile":e.enrollment.enrolled?"enrolled-no-key":"none"}function pG(e){return e.ssoLink?"sso":e.enrolledViaToken?"passwordless":"unknown"}function ty(e,t){let n=`\`anyray-connect --sso ${t??"<link>"}\``,r="`anyray-connect --enroll <link>`";switch(e){case"sso":return`enroll via SSO with ${n}`;case"passwordless":return`enroll with the link from your admin (${r})`;default:return`enroll \u2014 SSO org: use ${n}; passwordless org: use ${r} (link from your admin)`}}var A0=e=>Ed({id:e.id,installed:e.installed,pointedAt:e.pointedAt,mcpRegistered:e.mcp?.registered===!0,introspectable:e.inferenceIntrospectable===!0}),Qm=e=>e.pointedAt===!1&&e.tombstoned!==!0&&A0(e)!=="unverifiable",C0=e=>e.registered&&e.command&&iG(e.command)?sG(e.command):null,ey=e=>(Qm(e)?1:0)+(e.mcp?.commandOk===!1?1:0)+(e.routingOverrides?.length?1:0)+(e.claudeCodeHookPolicy&&e.claudeCodeHookPolicy!=="fine"?1:0),fG=async(e,t,n)=>e===!1&&t.routingExpected&&!await t.routingExpected(n)?null:e,hG=async(e,t)=>{if(e.length===0)return!1;for(let n of e){let r=t.find(a=>a.id===n);if(!r?.inferenceAuthLanes)return!1;let o=await r.inferenceAuthLanes().catch(()=>["unknown"]);if(o.length===0||o.some(a=>a!=="subscription"&&a!=="native"))return!1}return!0},v0=async e=>{for(let t of e)if(t.integrationStatus)try{if(!(await t.detect()).installed)continue;if((await t.integrationStatus()).hook_registration==="owned")return!0}catch{}return!1},mG=(e,t)=>{let n=c=>typeof c=="object"&&c!==null&&!Array.isArray(c),r=c=>typeof c=="number"&&Number.isSafeInteger(c)&&c>=0&&Number.isFinite(new Date(c).getTime()),o=new Set(t.map(c=>c.id)),a=new Set(mo),s=[],i=n(e.selfcheck?.adapters)?e.selfcheck.adapters:{};for(let[c,l]of Object.entries(i)){if(!o.has(c)||!n(l))continue;let d=n(l.lastRepaired)?l.lastRepaired:{},u=Object.entries(d).filter(w=>a.has(w[0])&&r(w[1])).map(([w,g])=>({checkId:w,at:g})),f=n(l.flapping)?l.flapping:void 0,p=Array.isArray(f?.checks)?f.checks.filter(w=>typeof w=="string"&&a.has(w)):[],h=f?.reason==="rebroke_same_day"||f?.reason==="repeat_days"?f.reason:void 0,m=f&&r(f.since)&&h&&p.length>0?{since:f.since,reason:h,checks:p}:void 0;(u.length>0||m)&&s.push({tool:c,repaired:u,...m?{flapping:m}:{}})}return s},yG=async(e,t,n,r,o,a,s=n,i=Ri,c=!0,l=wo,d=ko,u=Ut,f=wa)=>{let p=c?await $d(e):null,h=!!(rt(t)&&t.fallbackPort),m=h?await Ae(t.fallbackPort):null,w=h?`http://${mt}:${t.fallbackPort}`:e,g=process.env.ANYRAY_CLIENT_KEY?.trim()?"env":t.clientKey?"profile":null,y=t.enrolledCert?.payload,b=y?.expiresAt??t.enrolledCertExpiry??null,S=(await a())?.sso??null,E=pG({ssoLink:S,enrolledViaToken:!!t.enrolledTokenHash}),x=Ct(),A=await kw(x),I=A?[]:Ew(me({origin:w})),R=[];for(let Y of r){let De=await Y.detect(),He=null;if(De.installed&&Y.mcpStatus)try{let nt=await Y.mcpStatus();He={...nt,commandOk:C0(nt)}}catch{}let ht=De.installed&&Y.id===Ia?await o():void 0,Co=De.installed&&Y.pointsAt?await Y.pointsAt(Ai(Y.id,e,w)):null,an=await fG(Co,Y,t.managedTools??[]),Ma=Co===!1&&an===null,Bi=an===!1&&Y.routingPendingReload?await Y.routingPendingReload().catch(()=>!1):!1,ou=De.installed?Y.runtimeDiagnostics?await Y.runtimeDiagnostics().catch(()=>({routingOverrides:[]})):{routingOverrides:Y.routingOverrides?await Y.routingOverrides().catch(()=>[]):[]}:{routingOverrides:[]},{routingOverrides:Fa,claudeCodeHookPolicy:ue}=ou,tt=t.fleetToolPolicy,_r=tt?.enabled.includes(Y.id)?tt.tiers?.[Y.id]??ma:void 0;R.push({id:Y.id,title:Y.title,installed:De.installed,...De.detail?{detail:De.detail}:{},pointedAt:an,...Ma?{routingHeld:!0}:{},...Bi?{routingPendingReload:!0}:{},...Fa.length?{routingOverrides:Fa}:{},...ue===void 0?{}:{claudeCodeHookPolicy:ue},mcp:He,..._r?{policyTier:_r}:{},...t.revertedTools?.includes(Y.id)?{tombstoned:!0}:{},...Y.id==="cursor"&&(t.authMode==="auto"||t.authMode==="subscription")?{nativeSubscription:!0}:{},...ht===void 0?{}:{inferenceIntrospectable:ht.authoritative,...ht.authoritative?{}:{inferenceUnverifiableReason:ht.reason}}})}let B=s?await(async()=>{let{kind:Y,detail:De,remedy:He}=await i(me({origin:e,clientKey:process.env.ANYRAY_CLIENT_KEY?.trim()||t.clientKey,subscription:t.authMode==="subscription",placeholder:t.authMode==="placeholder",byoUpstream:t.byoUpstream,...t.authMode==="auto"?{seat:{anthropic:!1,openai:!1,copilot:!1}}:{},user:t.name,team:t.team}),{tools:t.managedTools??[]});return{kind:Y,detail:De,remedy:He}})():null,V=B?.kind==="provider-rejected"&&await hG(t.managedTools??[],r),H=B?{...B,...V?{notApplicableSubscription:!0}:{}}:null,X=n?dG(await ga({origin:e,apiKey:process.env.ANYRAY_CLIENT_KEY?.trim()||t.clientKey||void 0,metadata:le({user:t.name,team:t.team})},lG,{probe:!0}),{mode:E,ssoLink:S}):null,ie=await u().catch(()=>({})),ye=bn(ie.hookLane),Ue=s?await v0(r):!1,re=Ue?await(async()=>{let Y=await f().catch(()=>({verdict:"indeterminate",reason:"unreachable"}));return{...Kh(Y,{hookRegistered:Ue,neverInvoked:Hh(ye,Date.now())}),lastInvokedAt:cd(ye)}})():null,je=(await ar()).map(Y=>({adapter:Y.adapter,op:Y.op,requestedAt:Y.requestedAt,watcherAlive:ir(Y.watcherPid)})),L=je.find(Y=>Y.adapter==="cursor"),T=L?{op:L.op,requestedAt:L.requestedAt,watcherAlive:L.watcherAlive}:null,K=!!t.refreshSchedulerEnabled,J=await yc(),ge=await d(),z=t.persistenceOwner==="tray",Ve=z?await l(t)==="healthy":null,we=await GS({daemonEnabled:h&&!z,daemonHealthy:h?!!m:null,schedulerEnabled:K&&!z,schedulerInstalled:J,binaryDurable:!Ke(er())}),be=await wu(),he=0;p&&!p.reachable&&(he+=1),h&&!m&&(he+=1),z?K&&!Ve&&(he+=1):K&&!J&&(he+=1);for(let Y of R)he+=ey(Y);return H&&H.kind!=="ok"&&!H.notApplicableSubscription&&(he+=1),X&&X.kind!=="ok"&&(he+=1),re?.verdict==="dark"&&(he+=1),I.length>0&&(he+=1),he+=je.filter(Y=>!Y.watcherAlive).length,be.length>0&&(he+=1),{report:{format:1,generatedAt:new Date().toISOString()},connect:{version:cG(),node:process.versions.node,platform:`${process.platform}/${process.arch}`,remoteContext:gt(),selfUpdate:{managed:ge.managed,available:ge.available,autoUpdate:ge.autoUpdate,state:ge.state}},gateway:{origin:e,reachable:p?p.reachable:null,detail:p?p.detail:"not probed (--quick)"},toolOrigin:w,fallbackProxy:{enabled:h,port:h?t.fallbackPort:null,healthy:h?!!m:null},refreshScheduler:{enabled:K,installed:J,owner:z?"tray":"os",...z?{trayHealthy:!!Ve}:{}},serviceRemoval:we,retiredFallbackState:be,fleetdPresent:await La(),identity:{user:t.name??null,team:t.team??null,authMode:t.authMode??null,personalKeySource:g,clientKeyExpiresAt:t.clientKeyExpiresAt??null},enrollment:{enrolled:!!y,deploymentId:y?.deploymentId??null,issuedAt:y?.issuedAt??null,expiresAt:b,expired:b?Date.parse(b)<Date.now():null,orgMode:E,ssoLink:S},shell:{profilePath:x,blockPresent:A,staleExports:I},tools:R,...t.fleetToolPolicy?{fleetPlan:nd(t,t.fleetToolPolicy,!1)}:{},cursorQueue:T,pendingOps:je,ambientRepairs:mG(ie,r),verify:H,retrieval:X,hookLane:re,problems:he}},gG=e=>{if(e.serviceRemoval.suspected){W("Endpoint security"),N(" Anyray installed these background services, but their files are gone from disk \u2014"),N(" endpoint-security software (SentinelOne, CrowdStrike, Defender \u2026) quarantines them"),N(" as suspected persistence. Re-running connect just rewrites them.");for(let t of e.serviceRemoval.missingPaths)k(v(` missing: ${t}`));k(v(" Fix now: `anyray-connect --no-key-refresh` \u2014 installs no background service, points")),k(v(" tools straight at the gateway (your key then needs a periodic re-run).")),k(v(" Fix properly: `anyray-connect doctor --security-review` prints the allow-list your")),k(v(" security team needs; once approved, `anyray-connect --yes` restores auto-refresh."))}},wG=e=>{if(e.retiredFallbackState.length!==0){W("Retired fallback lane"),_(" A cached organization provider key from the removed --fallback lane is still on this machine.");for(let t of e.retiredFallbackState)k(v(` ${t}`));k(v(" Fix: `anyray-connect doctor --repair` deletes it (a normal `anyray-connect` run does too)."))}},bG=e=>{switch(k(j("Anyray connect \u2014 doctor")),e.connect.remoteContext&&(W("Environment"),k(` Remote dev context: ${tr(e.connect.remoteContext)}`),At(e.connect.remoteContext)&&k(v(" No per-user service manager here \u2014 key refresh rides the Claude Code helper and `anyray-connect` runs, not an OS schedule."))),W("CLI updates"),e.connect.selfUpdate.state){case"managed":$(" Managed standalone binary installed; one updater owns this seat."),e.connect.selfUpdate.autoUpdate||N(" Automatic CLI updates are off (`anyray-connect update --auto on`).");break;case"will-migrate":N(" This npm runtime will migrate to the managed standalone binary on the next persistent setup change."),k(v(" Run `anyray-connect update` to migrate now."));break;case"platform-unsupported":N(" Self-update is unavailable on this platform because no standalone binary is published."),k(v(" Use `npx anyray-connect@latest` to stay current."));break;case"unmanaged":k(v(" This copy is externally managed; update it with the method that installed it."));break;case"container":k(v(" Self-update is off in this container; updates arrive when it is rebuilt."));break}switch(W("Gateway"),e.gateway.reachable===null?k(v(` Probe skipped (--quick): ${e.gateway.origin} not contacted.`)):e.gateway.reachable?$(` Reachable: ${e.gateway.origin} ${v(`(${e.gateway.detail})`)}`):(_(` Unreachable: ${e.gateway.origin} (${e.gateway.detail})`),k(v(" Fix: start the gateway, or check the URL with `anyray-connect status`."))),e.fallbackProxy.enabled&&(W("Local key-refresh proxy"),e.fallbackProxy.healthy?$(` Running on 127.0.0.1:${e.fallbackProxy.port} \u2192 ${e.gateway.origin} `+v("(auto-refreshes your key so long sessions never 401)")):(_(` Enabled on 127.0.0.1:${e.fallbackProxy.port} but NOT responding \u2014 your tools point at it and cannot reach any gateway until it's back.`),e.serviceRemoval.kinds.includes("daemon")||k(v(" Fix: re-run `anyray-connect` to reinstall it, or `anyray-connect --no-key-refresh` to point tools straight at the gateway.")))),e.refreshScheduler.enabled&&(W("Automatic key refresh"),e.refreshScheduler.owner==="tray"?e.refreshScheduler.trayHealthy?$(" Managed by the Anyray Connect app \u2014 it triggers the ~30-min key refresh and supervises the daemon."):(_(" The Anyray Connect app owns the background services on this machine, but it is missing or no longer passes its signature check."),k(v(" Fix: run `anyray-connect` to restore the background services (it reinstalls the OS schedule and clears the app takeover)."))):e.refreshScheduler.installed?$(" Scheduled \u2014 your gateway key re-mints every ~30 min, so no tool 401s on a stale key mid-session."):(_(" Enabled but the OS schedule is missing \u2014 a long session can still 401 when your key lapses."),e.serviceRemoval.kinds.includes("scheduler")||k(v(" Fix: re-run `anyray-connect` to reinstall it, or `anyray-connect --no-key-refresh` to opt out.")))),gG(e),wG(e),W("Personal key"),uG(e)){case"env":$(" Personal gateway key present ($ANYRAY_CLIENT_KEY).");break;case"profile":$(" Personal gateway key present (enrolled via connect).");break;case"enrolled-no-key":N(" Enrolled, but no personal key is cached locally right now."),k(v(" Fix: re-run `anyray-connect` to re-mint it from your enrollment \u2014 no need to re-enroll. Claude Code and Codex are still attributed to you by name."));break;default:N(" Enrollment required \u2014 no personal gateway key is available."),k(v(` Fix: ${ty(e.enrollment.orgMode,e.enrollment.ssoLink)}, or set $ANYRAY_CLIENT_KEY to a minted ark_ key.`))}e.enrollment.enrolled&&(e.enrollment.expired?N(` Enrollment cert expired ${v(`(${e.enrollment.expiresAt})`)} \u2014 the next run re-enrolls.`):$(` Enrollment cert valid until ${e.enrollment.expiresAt} ${v(`(deployment ${e.enrollment.deploymentId})`)}`)),e.shell.staleExports.length>0&&(W("Shell"),_(" This terminal still exports Anyray, but the config is gone."),k(v(` Still set here: ${e.shell.staleExports.join(", ")}`)),k(v(` No Anyray block in ${e.shell.profilePath} \u2014 so these came from before a revert.`)),k(v(" Anything you start from this terminal keeps reaching the gateway with")),k(v(" no credential, and fails with 401.")),k(v(` Fix: unset ${e.shell.staleExports.join(" ")}`)),k(v(" Or open a new terminal. In VS Code, quit the app entirely (Cmd+Q) \u2014 it")),k(v(" reuses the environment it captured at launch, so a new terminal")),k(v(" (or Reload Window) keeps serving the old one.")));let t=e.tools.find(c=>c.installed&&c.claudeCodeHookPolicy!==void 0&&c.claudeCodeHookPolicy!=="fine");if(t?.claudeCodeHookPolicy){let c={state:t.claudeCodeHookPolicy};W("Claude Code hook policy"),_(` ${nc(c)}.`),k(v(` ${rc(c)}`))}W("Tools");let n=!1,r=!1,o=c=>{for(let l of c.routingOverrides??[])_(` ${c.title}: ${l.problem}.`),k(v(` ${l.fix}`))},a=c=>{c.mcp&&(c.mcp.registered?c.mcp.commandOk===!1?(_(` ${c.title}: retrieval MCP server registered, but its binary is gone (${c.mcp.command}).`),k(v(" Fix: re-run `anyray-connect` to re-register the current binary."))):$(` ${c.title}: retrieval MCP server registered ${v("(anyray_retrieve / anyray_recall)")}`):(N(` ${c.title}: retrieval MCP server not registered \u2014 externalized output can't be pulled back.`),k(v(" Fix: re-run `anyray-connect` from a durable install (registration is skipped for one-off npx runs)."))))};for(let c of e.tools){if(!c.installed){k(v(` ${c.title}: not installed (skipped)`));continue}if(c.pointedAt===null){k(v(` ${c.title}: installed (config not introspectable)`)),a(c);continue}if(c.pointedAt){if(n=!0,c.id==="cursor"&&c.nativeSubscription){$(` ${c.title}: native Cursor subscription; Anyray hooks/MCP active`),k(v(" Note: Claude/Opus model requests remain Cursor-hosted. Anyray can optimize and measure only the supported local Shell/MCP context seams.")),a(c);continue}$(` ${c.title}: pointed at ${e.gateway.origin}${e.fallbackProxy.enabled&&ki(c.id)?v(" (via key-refresh proxy)"):""}`),o(c),c.id==="claude-code"&&k(v(" Note: settings.json routing covers the Claude Code CLI and VS Code extension. For Claude Desktop, use the supported third-party Gateway setup; verified macOS builds can use the Claude Code subscription helper, while Windows remains API-billed.")),c.id===Ia&&k(v(` ${rA}`)),c.id==="codex"&&k(v(" Note: Codex app, CLI, and IDE extension share config.toml; Codex cloud/web tasks cannot route through a local gateway.")),a(c)}else{o(c);let l=A0(c);if(l==="not-routed"||l==="unverifiable"){let d=xd(l,{...c.inferenceUnverifiableReason?{reason:c.inferenceUnverifiableReason}:{},mcpRegistered:c.mcp?.registered===!0});N(` ${c.title}: ${d.headline}`);for(let u of d.detail)k(v(` ${u}`));l==="unverifiable"&&(r=!0)}else c.tombstoned?c.policyTier==="required"?(N(` ${c.title}: reverted locally against admin policy (out of compliance)`),k(v(` Re-enroll with \`anyray-connect --tools ${c.id}\`.`))):c.policyTier==="locked"?N(` ${c.title}: reverted locally but locked by admin policy \u2014 the next reconcile re-applies it`):k(v(` ${c.title}: reverted by you (not managed) \u2014 re-enroll with \`anyray-connect --tools ${c.id}\``)):c.routingPendingReload?(_(` ${c.title}: configured, but ${c.title} is still running the previous Anyray build`),k(v(" Fix: reload the app completely (quit and reopen \u2014 a window reload is not enough), then re-run `anyray-connect`."))):(_(` ${c.title}: installed but not pointed at ${e.gateway.origin}`),k(v(" Fix: run `anyray-connect` to (re)configure it.")))}}let s=(e.repairs?.length??0)>0;if(!n&&!r&&!s&&e.problems===0&&(N(" No tools are pointed at this gateway yet."),k(v(" Fix: run `anyray-connect` to configure your tools."))),e.pendingOps.length>0){W("Queued operations");for(let c of e.pendingOps){let l=Bt(c.adapter)?.title??c.adapter;c.watcherAlive?N(` ${l} ${c.op} queued since ${c.requestedAt} \u2014 completes automatically when ${l} quits.`):(_(` ${l} ${c.op} queued since ${c.requestedAt}, but its watcher is not running.`),k(v(` Fix: quit ${l} and re-run \`anyray-connect\` to complete it.`)))}}if(e.ambientRepairs.length>0){W("Ambient repairs");let c=l=>l==="hook_registration"?"hook re-installed":l==="mcp_registration"?"MCP registration re-installed":"hook binary repaired";for(let l of e.ambientRepairs){let d=Bt(l.tool)?.title??l.tool,u=l.repaired.map(({checkId:p,at:h})=>`${c(p)} ${new Date(h).toISOString().slice(0,10)}`);l.flapping&&u.push(`flapping since ${new Date(l.flapping.since).toISOString().slice(0,10)} (${l.flapping.reason})`);let f=` ${d}: ${u.join("; ")}`;l.flapping?N(f):k(f)}}let i=e.fleetPlan;if(i&&(i.freshIds.length>0||i.tombstonedIds.length>0)){W("Fleet policy");let c=l=>l.map(d=>Bt(d)?.title??d).join(", ");i.freshIds.length>0&&k(` Pending enrollment (the next policy sync applies): ${c(i.freshIds)}`),i.tombstonedIds.length>0&&N(` Out of compliance (reverted against required policy): ${c(i.tombstonedIds)}`)}if(e.verify)if(W("Auth probe"),e.verify.notApplicableSubscription)$(" Provider-key verification is not applicable to subscription/native inference lanes.");else if(e.verify.kind==="ok")$(` ${e.verify.detail}`);else{_(` ${e.verify.kind}: ${e.verify.detail}`);for(let c of e.verify.remedy)k(v(` ${c}`))}if(e.retrieval)if(W("Retrieval loop"),e.retrieval.kind==="ok")$(` ${e.retrieval.detail}`);else{_(` ${e.retrieval.kind}: ${e.retrieval.detail}`);for(let c of e.retrieval.remedy)k(v(` ${c}`))}if(e.hookLane){if(W("Hook lane"),e.hookLane.verdict==="live")$(` ${e.hookLane.detail}`);else if(e.hookLane.verdict==="dark"){_(` ${e.hookLane.reason}: ${e.hookLane.detail}`);for(let c of e.hookLane.remedy)k(v(` ${c}`))}else{N(` ${e.hookLane.reason}: ${e.hookLane.detail}`);for(let c of e.hookLane.remedy)k(v(` ${c}`))}e.hookLane.lastInvokedAt!==null&&k(v(` Last hook run: ${new Date(e.hookLane.lastInvokedAt).toISOString()}`))}W("Summary"),e.problems===0?(e.verify?$(" No problems found."):$(" No configuration problems found (no request was sent \u2014 drop `--no-verify` to test one)."),k(v(" Sharing with support? `anyray-connect doctor --json` prints this as a content-free report."))):_(` ${e.problems} problem(s) found \u2014 see fixes above.`)},kG=e=>({...e,verify:e.verify?{kind:e.verify.kind,detail:"",remedy:e.verify.remedy,...e.verify.notApplicableSubscription?{notApplicableSubscription:!0}:{}}:null,retrieval:e.retrieval?{kind:e.retrieval.kind,detail:"",remedy:e.retrieval.remedy}:null}),AG=async(e,t)=>{let n=e.hookLane;if(!n||n.verdict!=="dark"||n.reason!=="key_rejected")return null;if(!Fh(n.code))return{hookLane:n,note:`Hook lane: the gateway rejected this machine\u2019s key as '${n.code??"unclassified"}', which an automatic re-mint must never answer \u2014 no key was minted. Re-enroll (see the Hook lane fixes above).`};let r=t.probeHookLane??wa,o,a=async()=>(o??=await r().catch(()=>({verdict:"indeterminate",reason:"unreachable"})),o),s=await(t.refreshKey??Qe)({force:!0,hookLaneRepair:!0,probeHookLane:a}).catch(()=>"failed"),i=await a(),c=bn((await(t.readRefreshState??Ut)().catch(()=>({}))).hookLane),l=Kh(i,{hookRegistered:await v0(t.adapters??ae).catch(()=>!1),neverInvoked:Hh(c,Date.now())}),d=s==="disabled"?"Hook lane: key refresh is disabled here (ANYRAY_REFRESH_DISABLE), so no key was minted and the finding stands.":l.verdict==="live"?"Hook lane: re-minted the personal key and rewrote the configured tools \u2014 the lane answers again.":l.verdict==="indeterminate"?`Hook lane: re-mint reported '${s}', but the confirming probe could not establish the lane's state \u2014 nothing is proven fixed and the finding stands.`:`Hook lane: re-mint reported '${s}' and the lane is still not live \u2014 re-enroll (see the Hook lane fixes above).`;return{hookLane:{...l,lastInvokedAt:cd(c)},note:d}},CG=async(e,t,n={})=>{let r=n.adapters??ae,o=n.resolveTarget??_e,a=n.applyTools??wt,s=await AG(e,n).catch(()=>null),i=s&&e.hookLane?.verdict==="dark"&&s.hookLane?.verdict==="live"?1:0,c=s?{hookLane:s.hookLane,notes:[s.note]}:{notes:[]},l=e.tools.filter(y=>y.installed&&(Qm(y)||y.mcp?.commandOk===!1||y.routingOverrides?.some(b=>b.repairable)));if(l.length===0)return{entries:[],remainingProblems:Math.max(0,e.problems-i),refreshedTools:new Map,...c,notes:[...c.notes,"Nothing to repair \u2014 no tool has drifted."]};let d=await o(async()=>t,void 0,Ae);if(!d)return{entries:l.map(y=>({id:y.id,title:y.title,status:"skipped-not-enrolled"})),remainingProblems:Math.max(0,e.problems-i),refreshedTools:new Map,...c,notes:[...c.notes,`Repair needs an enrolled personal key \u2014 ${ty(e.enrollment?.orgMode??"unknown",e.enrollment?.ssoLink??null)}, then re-run.`]};let u=new Set(t.managedTools??[]),f=[],p=[...c.notes],h=[];for(let y of l){let b=r.find(C=>C.id===y.id);if(!u.has(y.id)||!b){f.push({id:y.id,title:y.title,status:"skipped-unmanaged"});continue}h.push(b)}f.length>0&&p.push("Drifted tools outside the managed record are never auto-repaired \u2014 run `anyray-connect` once to (re)configure and record them.");let m=await a(h,d.target),w=new Map,g=0;for(let y of m){if(f.push(y),!uo(y))continue;let b=e.tools.find(R=>R.id===y.id);if(!b)continue;let C=r.find(R=>R.id===y.id),S=b.mcp;if(C?.mcpStatus)try{let R=await C.mcpStatus();S={...R,commandOk:C0(R)}}catch{}let E=Qm(b)?!0:b.pointedAt;if(C?.pointsAt&&b.pointedAt!==null)try{E=await C.pointsAt(Ai(C.id,e.gateway.origin,e.toolOrigin))}catch{}let x=b.routingOverrides,A=b.claudeCodeHookPolicy;if(C?.runtimeDiagnostics)try{let R=await C.runtimeDiagnostics();x=R.routingOverrides.length?R.routingOverrides:void 0,A=R.claudeCodeHookPolicy}catch{}else if(C?.routingOverrides)try{let R=await C.routingOverrides();x=R.length?R:void 0}catch{}let I={...b,pointedAt:E,mcp:S,...x?{routingOverrides:x}:{},...A===void 0?{}:{claudeCodeHookPolicy:A}};x||delete I.routingOverrides,A===void 0&&delete I.claudeCodeHookPolicy,w.set(y.id,I),g+=ey(b)-ey(I)}return{entries:f,remainingProblems:Math.max(0,e.problems-g-i),refreshedTools:w,...s?{hookLane:s.hookLane}:{},notes:p}},vG=e=>{W("Repair"),e.entries.length===0&&$(" Nothing to repair.");for(let t of e.entries)t.status==="configured"||t.status==="reverted"?$(` ${t.title}: re-applied`):t.status==="queued"?$(` ${t.title}: re-apply queued (completes when the app quits)`):t.status.startsWith("skipped-")?k(v(` ${t.title}: ${t.status}`)):_(` ${t.title}: ${t.status}`);for(let t of e.notes)k(v(` ${t}`))},S0=async(e,t={})=>{let n=await P();if(e.securityReview){k(j("Anyray connect \u2014 security review"));for(let c of jS(n.fallbackPort??Ce))k(c?` ${c}`:"");return 0}let r;try{r=Er(e.gateway,n)}catch(c){return e.json?(console.log(JSON.stringify({error:c.message})),1):(k(j("Anyray connect \u2014 doctor")),_(` Gateway URL: ${c.message}`),k(v(" Fix: pass a gateway URL, e.g. `anyray-connect doctor http://localhost:8787`.")),1)}if(e.quick&&e.verify)return e.json?console.log(JSON.stringify({error:"--quick cannot be combined with --verify"})):(k(j("Anyray connect \u2014 doctor")),_(" --quick skips the network probes; it cannot be combined with --verify.")),1;let o=!e.noVerify&&!e.quick,a=await yG(r,n,!!e.verify&&!e.quick,t.adapters??ae,t.inferenceIntrospection??Sd,t.fleetBootstrap??Wt,o,t.verifyAuth??Ri,!e.quick,t.checkTray??wo,t.updateStatus??ko,t.readRefreshState??Ut,t.probeHookLane??wa);e.repair&&a.retiredFallbackState.length>0&&(await Vi(),a.retiredFallbackState=await wu(),a.retiredFallbackState.length===0&&(a.problems-=1));let s=e.repair?await CG(a,n,t):void 0,i=s?{...a,tools:a.tools.map(c=>s.refreshedTools.get(c.id)??c),...s.hookLane!==void 0?{hookLane:s.hookLane}:{},repairs:s.entries,problems:s.remainingProblems}:a;e.json?console.log(JSON.stringify(kG(i),null,2)):(bG(i),s&&vG(s));try{e.quick||await(t.reportHealth??Nv)(k0(i),i.connect.version)}catch{}return i.problems===0?0:1};var SG=()=>{let e=[];for(let t of ae){let n=t.skillsDir?.();n&&e.push(n)}return e},E0=async e=>{let t=await P();k(j("Anyray connect \u2014 sync"));let n;try{n=Er(e.gateway,t)}catch(s){return _(s.message),1}F(`Gateway: ${n}`);let r=bE(t.clientKey,"anyray-placeholder"),o;try{o=await od(n,r)}catch(s){return _(`Team policy sync failed: ${rd(s)}`),1}let a=SG();if(a.length===0)EG();else if(o.skills.length===0)F("No team skills published yet \u2014 nothing to sync.");else{let s=await yv(o,a,t.syncedSkills??{});W("Skills");for(let i of s.results)i.written?$(` ${i.name} ${v(`(${i.id}@${i.version})`)} \u2192 ${i.files.length} file(s)`):F(` ${i.name} ${v(`(${i.id}@${i.version})`)} \u2014 up to date`);try{await te({...t,syncedSkills:s.versions,syncedAt:s.updatedAt??new Date().toISOString()})}catch(i){F(`Could not record sync state: ${i instanceof Error?i.message:String(i)}`)}W("Summary"),k(` ${et(String(s.changed))} updated, ${s.unchanged} unchanged, across ${a.length} tool dir(s).`)}try{let s=await ad(o);(s.routingUpdated||s.teamUpdated||s.toolsRequested>0||s.toolsTombstoned.length>0)&&(k(`Fleet policy: routing ${s.routingUpdated?"updated":"unchanged"}, team ${s.teamUpdated?"updated":"unchanged"}, ${s.toolsApplied}/${s.toolsRequested} tool(s) reconciled${s.toolsEnrolled>0?` (${s.toolsEnrolled} newly enrolled)`:""}.`),s.toolsTombstoned.length>0&&F(` Locally reverted against admin policy (out of compliance): ${s.toolsTombstoned.join(", ")}. Re-run \`anyray-connect --tools <id>\` to re-enroll.`))}catch(s){F(`Fleet policy reconcile skipped: ${rd(s)}`)}return 0},EG=()=>{F("No installed tool exposes a skills directory \u2014 nothing to sync.")};import{gzip as Oj}from"node:zlib";import{promisify as Rj}from"node:util";var Or={maxChars:12e3,headChars:6e3,tailChars:4e3,middleWindows:3},ny=e=>({text:e,trimmed:!1,originalChars:e.length,trimmedChars:e.length,charsRemoved:0,estTokensSaved:0}),x0=e=>`
|
|
692
692
|
|
|
693
693
|
\u2026[anyray-hook trimmed ${e} chars (~${Math.round(e/3.3)} tokens) \u2014 elided locally, cache-safe]\u2026
|
|
694
694
|
|
|
@@ -699,29 +699,29 @@ ${d}`);s&&i.push(`--- MCP structuredContent ---
|
|
|
699
699
|
${JSON.stringify(t.structuredContent)}`);let c=a[0],l=new Set(a.map(({index:d})=>d));return{body:i.join(`
|
|
700
700
|
|
|
701
701
|
`),rebuild:d=>{let u={...t};return delete u.structuredContent,u.content=o.flatMap((f,p)=>l.has(p)?p!==c?.index?[]:[{...c.part,text:d}]:[f]),c||(u.content=[{type:"text",text:d},...u.content]),u}}}}let n=xG.find(o=>typeof t[o]=="string");if(!n){let o=-1;for(let[a,s]of Object.entries(t))typeof s=="string"&&s.length>o&&(n=a,o=s.length)}if(!n)return null;let r=n;return{body:t[r],rebuild:o=>({...t,[r]:o})}};var IG=e=>{let t=e.trim();return t?t.length>=200&&!/\s/.test(t.slice(0,200).replace(/[{}[\],":]/g,""))?!0:/^\[?\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}/.test(t)||/^\[?\d{2}:\d{2}:\d{2}/.test(t)||/^(ERROR|WARN|WARNING|INFO|DEBUG|TRACE|FATAL)\b/i.test(t)||/^\s*at\s+\S+\s+\(/.test(e)||/^\s*File ".+", line \d+/.test(e)||/^Traceback \(most recent call last\)/.test(t)||/^[{}[\]]/.test(t)||/[}\]],?$/.test(t)||/^"?[\w.-]+"?\s*[:=]\s+\S/.test(t):!1},_i={minChars:8e3,minDataLineRatio:.6,minDataLines:20},jd=(e,t={})=>{if(typeof e!="string")return!1;let n=t.minChars??_i.minChars;if(e.length<n)return!1;let r=t.minDataLineRatio??_i.minDataLineRatio,o=t.minDataLines??_i.minDataLines,a=e.split(`
|
|
702
|
-
`),s=0,i=0;for(let c of a)c.trim()&&(s++,IG(c)&&i++);return s===0||i<o?!1:i/s>=r};var Pi=(e,t=200)=>e.length>t?`${e.slice(0,t)}\u2026`:e,Vd={pytest:"test-run",jest:"test-run",vitest:"test-run",mocha:"test-run",cargo:"test-run",go:"test-run",rg:"grep",grep:"grep",egrep:"grep",fgrep:"grep",ag:"grep",ack:"grep"},_0=new Set(["npm","pnpm","yarn","bun"]),Yd=e=>{let t=e.lastIndexOf("/");return t===-1?e:e.slice(t+1)},OG=e=>{let t=e.trim().split(/\s+/).filter(Boolean),n=0;for(;n<t.length&&/^[A-Za-z_][A-Za-z0-9_]*=/.test(t[n]);)n++;let r=t.slice(n);if(r.length===0)return null;let o=Yd(r[0]);if(o in Vd)return Vd[o];if((o==="npx"||o==="bunx")&&r[1]){let a=Yd(r[1]);if(a in Vd)return Vd[a]}return o==="git"&&r[1]==="grep"?"grep":o==="node"&&r.includes("--test")||_0.has(o)&&(r[1]==="test"||r[1]==="t"||r[1]==="run"&&r[2]&&/test/i.test(r[2]))?"test-run":null},oy=e=>{if(typeof e!="string"||!e.trim())return null;for(let t of e.split(/\|\||&&|;|\||\n/)){let n=OG(t);if(n)return n}return null},RG={git:new Set(["log","diff","show","blame","shortlog","whatchanged"]),docker:new Set(["logs","ps","images","inspect","history","diff"]),podman:new Set(["logs","ps","images","inspect","history","diff"]),kubectl:new Set(["logs","get","describe"]),journalctl:null,dmesg:null,tsc:null,make:null,gradle:null,mvn:null,bazel:null},_G=/^(build|lint|typecheck|type-check|check|compile|tsc)/i,PG=(e,t,n)=>{let r=(...o)=>n.some(a=>o.includes(a));return(e==="docker"||e==="podman"||e==="kubectl")&&t==="logs"||e==="journalctl"?r("-f","--follow"):e==="kubectl"&&t==="get"||e==="tsc"?r("-w","--watch"):!1},P0=e=>{if(typeof e!="string"||!e.trim())return!1;let t=e.trim().split(/\s+/).filter(Boolean),n=0;for(;n<t.length&&/^[A-Za-z_][A-Za-z0-9_]*=/.test(t[n]);)n++;let r=t.slice(n);if(r.length===0)return!1;let o=Yd(r[0]);if(_0.has(o)){let i=r[1]==="run"?r[2]:r[1];return i!=null&&_G.test(i)}let a=r[1]?Yd(r[1]):void 0;if(PG(o,a,r))return!1;let s=RG[o];return s===void 0?!1:s===null||a!=null&&s.has(a)},TG=e=>{let t=e.trim();if(t.length<2)return!1;let n=t[0],r=t[t.length-1];return n==="{"&&r==="}"||n==="["&&r==="]"},LG=/^(import |export |from |const |let |var |function |class |def |async |await |#include |@charset |\/\/ |\/\* |\* )/,
|
|
703
|
-
${e.slice(-ry)}`:e;return
|
|
704
|
-
`),router:"test-run",stat:`test run: kept ${n} failure block(s)${a}`,kept:n,total:n+r}},
|
|
705
|
-
`),router:"grep",stat:`grep: ${o} hits in ${n.size} files, kept ${s}`,kept:s,total:o}},
|
|
702
|
+
`),s=0,i=0;for(let c of a)c.trim()&&(s++,IG(c)&&i++);return s===0||i<o?!1:i/s>=r};var Pi=(e,t=200)=>e.length>t?`${e.slice(0,t)}\u2026`:e,Vd={pytest:"test-run",jest:"test-run",vitest:"test-run",mocha:"test-run",cargo:"test-run",go:"test-run",rg:"grep",grep:"grep",egrep:"grep",fgrep:"grep",ag:"grep",ack:"grep"},_0=new Set(["npm","pnpm","yarn","bun"]),Yd=e=>{let t=e.lastIndexOf("/");return t===-1?e:e.slice(t+1)},OG=e=>{let t=e.trim().split(/\s+/).filter(Boolean),n=0;for(;n<t.length&&/^[A-Za-z_][A-Za-z0-9_]*=/.test(t[n]);)n++;let r=t.slice(n);if(r.length===0)return null;let o=Yd(r[0]);if(o in Vd)return Vd[o];if((o==="npx"||o==="bunx")&&r[1]){let a=Yd(r[1]);if(a in Vd)return Vd[a]}return o==="git"&&r[1]==="grep"?"grep":o==="node"&&r.includes("--test")||_0.has(o)&&(r[1]==="test"||r[1]==="t"||r[1]==="run"&&r[2]&&/test/i.test(r[2]))?"test-run":null},oy=e=>{if(typeof e!="string"||!e.trim())return null;for(let t of e.split(/\|\||&&|;|\||\n/)){let n=OG(t);if(n)return n}return null},RG={git:new Set(["log","diff","show","blame","shortlog","whatchanged"]),docker:new Set(["logs","ps","images","inspect","history","diff"]),podman:new Set(["logs","ps","images","inspect","history","diff"]),kubectl:new Set(["logs","get","describe"]),journalctl:null,dmesg:null,tsc:null,make:null,gradle:null,mvn:null,bazel:null},_G=/^(build|lint|typecheck|type-check|check|compile|tsc)/i,PG=(e,t,n)=>{let r=(...o)=>n.some(a=>o.includes(a));return(e==="docker"||e==="podman"||e==="kubectl")&&t==="logs"||e==="journalctl"?r("-f","--follow"):e==="kubectl"&&t==="get"||e==="tsc"?r("-w","--watch"):!1},P0=e=>{if(typeof e!="string"||!e.trim())return!1;let t=e.trim().split(/\s+/).filter(Boolean),n=0;for(;n<t.length&&/^[A-Za-z_][A-Za-z0-9_]*=/.test(t[n]);)n++;let r=t.slice(n);if(r.length===0)return!1;let o=Yd(r[0]);if(_0.has(o)){let i=r[1]==="run"?r[2]:r[1];return i!=null&&_G.test(i)}let a=r[1]?Yd(r[1]):void 0;if(PG(o,a,r))return!1;let s=RG[o];return s===void 0?!1:s===null||a!=null&&s.has(a)},TG=e=>{let t=e.trim();if(t.length<2)return!1;let n=t[0],r=t[t.length-1];return n==="{"&&r==="}"||n==="["&&r==="]"},LG=e=>{for(let t=1;t<e.length;t++){if(e[t]==="\\"){t++;continue}if(e[t]==='"')return t}return-1},DG=e=>{let t=e.trim();if(t==="")return!1;let n=!0;for(let o=0;o<t.length;o++){let a=t[o];if(a!=="{"&&a!=="}"&&a!=="["&&a!=="]"&&a!==","){n=!1;break}}if(n)return!0;if(t[0]!=='"')return!1;let r=LG(t);return r>0&&t[r+1]===":"},NG=80,$G=e=>{if(e.length===0)return!1;let t=Math.ceil(e.length/NG),n=0,r=0;for(let o=0;o<e.length;o+=t)n++,DG(e[o])&&r++;return n>0&&r/n>.3},MG=/^(import |export |from |const |let |var |function |class |def |async |await |#include |@charset |\/\/ |\/\* |\* )/,FG=e=>{let t=e.slice(0,80);if(t.length===0)return!1;let n=0;for(let r of t){let o=r.trim();(MG.test(o)||/[{};]$/.test(o))&&n++}return n/t.length>.3},BG=[/\b\d+\s+(passed|failed|errors?|skipped|xfailed|xpassed)\b.*\bin\s+[\d.]+\s*s/i,/^=+ FAILURES =+/m,/^=+ short test summary/im,/test session starts/i,/^Test Suites:\s+\d+/m,/^Tests:\s+\d+\s+(failed|passed|total)/m,/^test result:\s+(ok|FAILED)\b/m,/^running \d+ tests?$/m,/^--- (FAIL|PASS): /m,/^(ok|FAIL)\s+\S+\s+[\d.]+s/m],ry=8192,UG=e=>{let t=e.length>2*ry?`${e.slice(0,ry)}
|
|
703
|
+
${e.slice(-ry)}`:e;return BG.some(n=>n.test(t))},HG=e=>/^[=~_—-]{4,}$/.test(e)||/^=+ .* =+$/.test(e)||/test session starts/i.test(e)||/^platform /i.test(e)||/^(rootdir|cachedir|configfile|plugins):/i.test(e)||/^collected \d+ items?/i.test(e)||/^Ran all test suites/.test(e)||/^(Snapshots|Time):/.test(e)||/^running \d+ tests?$/.test(e)||/^=== RUN /.test(e),WG=e=>/\b\d+\s+(passed|failed|errors?|skipped|xfailed|xpassed)\b/i.test(e)&&/\bin\s+[\d.]+\s*s/i.test(e)||/^Test Suites:\s+\d+/.test(e)||/^Tests:\s+\d+/.test(e)||/^test result:\s+(ok|FAILED)\b/.test(e)||/^FAIL\s+\S+\s+[\d.]+s$/.test(e),KG=e=>{let t=/^_{2,}\s*(.+?)\s*_{2,}$/.exec(e);return t?`FAIL: ${t[1]}`:/^FAIL\s+\S+/.test(e)&&!/\s[\d.]+s$/.test(e)||/^--- FAIL: /.test(e)||/^---- .+ (stdout|stderr) ----$/.test(e)?e:null},GG=e=>/^(PASS|ok)\b/.test(e)||/^--- PASS: /.test(e)||/^\s*(✓|✔)/.test(e)||/\[\s*\d+%\]$/.test(e),O0=e=>{let t=[],n=0,r=0,o=0;for(let s of e){let i=s.trim();if(!i)continue;if(WG(i)){t.push(Pi(i));continue}let c=KG(i);if(c){if(n>=10){r++,o=0;continue}n++,t.push(Pi(c)),o=12;continue}HG(i)||GG(i)||o>0&&(t.push(Pi(s)),o--)}if(t.length===0)return null;let a=r>0?` (+${r} more)`:"";return{text:t.join(`
|
|
704
|
+
`),router:"test-run",stat:`test run: kept ${n} failure block(s)${a}`,kept:n,total:n+r}},jG=/^([^\s:]+):(\d+):(?:\d+:)?(.*)$/,T0=e=>{let t=jG.exec(e);return t&&/[/.]/.test(t[1])?t:null},VG=/^([^\s:]+)-(\d+)-/,YG=e=>{if(e==="--")return!0;let t=VG.exec(e);return t!=null&&/[/.]/.test(t[1])},ZG=e=>{let t=e.slice(0,50);if(t.length<3)return!1;let n=t.filter(r=>T0(r)!=null).length;return n>=3&&n/t.length>=.7},R0=(e,t)=>{let n=new Map,r=0,o=0;for(let c of e){let l=T0(c);if(!l){if(YG(c))return null;r++;continue}o++;let d=n.get(l[1])??[];d.push({line:l[2],content:l[3]}),n.set(l[1],d)}if(o===0||o/(o+r)<t)return null;let a=[`${o} matches in ${n.size} files:`],s=0,i=!1;for(let[c,l]of n){if(s>=200){i=!0;break}a.push("",`${c}:`);let d=Math.min(l.length,25,200-s);for(let u of l.slice(0,d))a.push(Pi(` ${u.line}: ${u.content.trim()}`)),s++;l.length>d&&a.push(` \u2026+${l.length-d} more in this file`)}return i&&a.push("",`\u2026+${o-s} more matches elided`),{text:a.join(`
|
|
705
|
+
`),router:"grep",stat:`grep: ${o} hits in ${n.size} files, kept ${s}`,kept:s,total:o}},XG=e=>e.replace(/\d{4}-\d\d-\d\d[T ]\d\d:\d\d:\d\d(?:\.\d+)?Z?/g,"<TS>").replace(/\b\d\d:\d\d:\d\d\b/g,"<TS>").replace(/\b[0-9a-f]{2,}(?:-[0-9a-f]{2,}){2,}\b/gi,"<ID>").replace(/\b0x[0-9a-f]+\b/gi,"<HEX>").replace(/\b\d{8,}\b/g,"<NUM>").trim(),JG=e=>{if(e.length<12)return null;let t=new Map,n=[];for(let o of e){let a=XG(o),s=t.get(a);s?s.n++:(t.set(a,{first:o,n:1}),n.push(a))}return n.length/e.length>.6?null:{text:n.map(o=>{let{first:a,n:s}=t.get(o),i=Pi(a.trim());return s>1?`[\xD7${s}] ${i}`:i}).join(`
|
|
706
706
|
`),router:"log-dedup",stat:`log: ${e.length} lines \u2192 ${n.length} unique`,kept:n.length,total:e.length}},L0=(e,t)=>{if(typeof t!="string"||t.length===0||TG(t))return null;let n=t.split(`
|
|
707
|
-
`).filter(s=>s.trim()!==""),r=oy(e),o
|
|
707
|
+
`).filter(s=>s.trim()!==""),r=oy(e),o=UG(t),a=null;return r==="test-run"&&o?a=O0(n):r==="grep"&&(a=R0(n,.5)),a||(o?a=O0(n):ZG(n)?a=R0(n,.7):!FG(n)&&!$G(n)&&(a=JG(n))),!a||a.text.length>=t.length?null:a},ay=(e,t)=>t?`
|
|
708
708
|
|
|
709
709
|
\u2026[anyray-hook digest \u2014 ${e}; full output: ${t}]\u2026`:`
|
|
710
710
|
|
|
711
|
-
\u2026[anyray-hook digest \u2014 ${e}]\u2026`;import{createHash as
|
|
712
|
-
`):"",
|
|
713
|
-
`).slice(0,V0)};var
|
|
714
|
-
`);i=l>=0?i.slice(l+1):""}let c=
|
|
715
|
-
`));return
|
|
716
|
-
`:"",cy=e=>Math.round(Math.max(0,e)/4),Z0=e=>typeof e=="string"?e:e!=null?JSON.stringify(e):"",
|
|
717
|
-
${Z0(r.tool_input)}`:Z0(r.tool_input),g=W0(o,w,u),y=async E=>{try{await t.cachePut(g,E)}catch{}},b=null;try{b=await t.cacheGet(g)}catch{b=null}if(b)return b.optimized&&b.output.length<u.length?h(b.output,b.tokensSaved):m();let C=null;try{C=
|
|
718
|
-
`}catch{return}},
|
|
711
|
+
\u2026[anyray-hook digest \u2014 ${e}]\u2026`;import{createHash as zG}from"node:crypto";import{homedir as qG}from"node:os";import{join as Zd}from"node:path";import{mkdir as QG,readdir as ej,stat as sy,unlink as D0,writeFile as tj}from"node:fs/promises";var nj=1440*60*1e3,N0=50,rj=()=>(process.env.ANYRAY_HOOK_TEE??"").trim().toLowerCase()==="off",oj=async()=>{let e=process.env.ANYRAY_HOOK_TEE_DIR;if(e)return e;let t=Q();try{if((await sy(t)).isDirectory())return Zd(t,"hook-tee")}catch{}return Zd(qG(),".anyray-hook-tee")},aj=async e=>{try{let t=Date.now(),n=[];for(let r of await ej(e)){let o=Zd(e,r);try{let a=await sy(o);if(!a.isFile())continue;t-a.mtimeMs>nj?await D0(o):n.push({path:o,mtimeMs:a.mtimeMs})}catch{}}if(n.length>N0){n.sort((r,o)=>r.mtimeMs-o.mtimeMs);for(let r of n.slice(0,n.length-N0))await D0(r.path).catch(()=>{})}}catch{}},$0=async e=>{if(rj())return null;try{let t=await oj();await QG(t,{recursive:!0,mode:448});let n=`${zG("sha256").update(e).digest("hex").slice(0,16)}.txt`,r=Zd(t,n);try{if((await sy(r)).isFile())return r}catch{}return await tj(r,e,{mode:384}),await aj(t),r}catch{return null}};import{createHash as sj}from"node:crypto";import{homedir as M0}from"node:os";import{join as iy}from"node:path";import{readFile as ij,writeFile as cj,chmod as lj,stat as dj,unlink as uj}from"node:fs/promises";var pj=200,fj=1440*60*1e3,hj=4e6,F0=()=>(process.env.ANYRAY_HOOK_CACHE??"").trim().toLowerCase()==="off",B0=(e,t)=>{let n=process.env[e];if(!n)return t;let r=Number(n);return Number.isFinite(r)&&r>0?r:t},mj=()=>B0("ANYRAY_HOOK_CACHE_MAX_ENTRIES",pj),U0=()=>B0("ANYRAY_HOOK_CACHE_TTL_MS",fj),H0=async()=>{let e=process.env.ANYRAY_HOOK_CACHE_FILE?.trim();if(e)return e;let t=iy(M0(),".anyray");try{if((await dj(t)).isDirectory())return iy(t,"hook-cache.json")}catch{}return iy(M0(),".anyray-hook-cache.json")},W0=(e,t,n)=>sj("sha256").update(`${e.length}:${e}`).update(`${t.length}:${t}`).update(n).digest("hex"),K0=async e=>{try{let t=JSON.parse(await ij(e,"utf-8"));if(t?.v===1&&t.entries&&typeof t.entries=="object")return t}catch{}return{v:1,entries:{}}},G0=async e=>{if(F0())return null;try{let n=(await K0(await H0())).entries[e];return!n||Date.now()-n.at>U0()?null:typeof n.o=="string"?{optimized:!0,output:n.o,tokensSaved:Number.isFinite(n.t)?n.t:0}:{optimized:!1}}catch{return null}},yj=e=>{let t=Date.now(),n=U0(),r=Object.entries(e).filter(([,i])=>t-i.at<=n);r.sort((i,c)=>c[1].at-i[1].at);let o=[],a=0,s=mj();for(let i of r){if(o.length>=s||(a+=i[1].o?.length??0,a>hj&&o.length>0))break;o.push(i)}return Object.fromEntries(o)},j0=async(e,t)=>{if(F0())return;let n;try{let r=await H0(),o=await K0(r);o.entries[e]=t.optimized?{o:t.output,t:t.tokensSaved,at:Date.now()}:{at:Date.now()},o.entries=yj(o.entries),n=`${r}.${process.pid}.tmp`,await cj(n,JSON.stringify(o),{mode:384}),await lj(n,384),await pe(n,r)}catch{if(n)try{await uj(n)}catch{}}};import{open as gj,stat as wj}from"node:fs/promises";var V0=600,bj=3,kj=256e3,Aj=e=>typeof e=="string"?e:Array.isArray(e)?e.filter(t=>!!t&&typeof t=="object"&&t.type==="text"&&typeof t.text=="string").map(t=>t.text).join(`
|
|
712
|
+
`):"",Cj=e=>e.startsWith("<command-name>")||e.startsWith("<command-message>")||e.startsWith("<local-command-"),vj=e=>{let t=[];for(let n of e)if(!(!n||!n.trim()))try{let r=JSON.parse(n);r&&typeof r=="object"&&!Array.isArray(r)&&t.push(r)}catch{}return t},Sj=e=>{let t=[],n=0;for(let r=e.length-1;r>=0;r--){let o=e[r];if(!o||o.type!=="user"||o.isMeta||o.isSidechain)continue;let a=Aj(o.message?.content).trim();if(!(!a||Cj(a))&&(t.unshift(a),n+=a.length,t.length>=bj||n>=V0))break}return t.join(`
|
|
713
|
+
`).slice(0,V0)};var Ej=e=>/(^|[\\/])subagents[\\/]/i.test(e),xj=e=>/\.jsonl$/i.test(e),Ij=e=>e.some(t=>(t.type==="user"||t.type==="assistant")&&t.message!==null&&typeof t.message=="object"),Y0=async e=>{let t={intent:"",kind:"unknown"};if(!e||!xj(e))return t;let n;try{let{size:r}=await wj(e),o=Math.max(0,r-kj),a=r-o;if(a<=0)return t;n=await gj(e,"r");let s=new Uint8Array(a);await n.read(s,0,a,o);let i=new TextDecoder().decode(s);if(o>0){let l=i.indexOf(`
|
|
714
|
+
`);i=l>=0?i.slice(l+1):""}let c=vj(i.split(`
|
|
715
|
+
`));return Ij(c)?{intent:Sj(c),kind:Ej(e)?"subagent":"main"}:t}catch{return t}finally{try{await n?.close()}catch{}}};var _j=3e3,Pj=1500,Tj=()=>{let e=Number(process.env.ANYRAY_HOOK_OPTIMIZE_TIMEOUT_MS);return Number.isFinite(e)&&e>0?e:_j},Lj={claude:"claude-code",codex:"codex",cursor:"cursor",opencode:"opencode"},Dj=new Set(["claude","opencode"]),Nj=(e,t)=>{let n={};if(e)try{let r=JSON.parse(e);r&&typeof r=="object"&&!Array.isArray(r)&&(n=r)}catch{}return JSON.stringify({...n,tool:Lj[t]})},$j={cacheGet:async()=>null,cachePut:async()=>{}},Mj=(e,t={cacheGet:G0,cachePut:j0,tee:$0})=>e==="claude"?t:$j,Fj=1e3,Bj=e=>JSON.stringify({hookSpecificOutput:{hookEventName:"PostToolUse",updatedToolOutput:e}}),Xd=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),Uj=e=>{try{let t=JSON.parse(e);if(!Xd(t)||typeof t.tool_name!="string"||!t.tool_name.startsWith("MCP:")||typeof t.tool_output!="string")return;let n=JSON.parse(t.tool_output);return Xd(n)?JSON.stringify({...t,tool_output:n}):void 0}catch{return}},Hj=e=>{try{let t=JSON.parse(e);return Xd(t)&&typeof t.tool_name=="string"&&t.tool_name.startsWith("MCP:")}catch{return!1}},Wj=e=>Xd(e)?`${JSON.stringify({updated_mcp_tool_output:e})}
|
|
716
|
+
`:"",cy=e=>Math.round(Math.max(0,e)/4),Z0=e=>typeof e=="string"?e:e!=null?JSON.stringify(e):"",Kj=new Set(["Edit","MultiEdit","Write","NotebookEdit","ExitPlanMode","TodoWrite"]),Gj=e=>/(^|[^a-z0-9])anyray_(retrieve|recall)$/i.test(e.trim()),jj=["tool_output","tool_response","tool_result"],Vj=e=>{for(let t of jj)if(t in e)return e[t]},Yj=(e,t)=>{if(e!=="Bash"||t==null||typeof t!="object")return"";let n=t.command;return typeof n=="string"?n:""},Zj=120,Xj=async(e,t,n)=>{if(!e.digestCommand||!t||n.length<(e.digestGate??Fj))return null;let r=null;try{r=e.digestCommand(t,n)}catch{return null}if(!r)return null;let o=ay(r.stat,null).length+Zj;if(r.text.length+o>=n.length)return null;let a=null;if(e.tee)try{a=await e.tee(n)}catch{a=null}let s=ay(r.stat,a);return r.text.length+s.length>=n.length?null:{body:r.text,marker:s,decision:{router:r.router,kept:r.kept,total:r.total,teed:a!=null}}},Jj=async(e,t)=>{let n={stdout:""};if(!e.trim())return n;let r;try{let E=JSON.parse(e);if(!E||typeof E!="object")return n;r=E}catch{return n}let o=typeof r.tool_name=="string"?r.tool_name:"unknown";if(Kj.has(o)||Gj(o))return n;let a=I0(Vj(r));if(!a)return n;let s=async E=>{try{await t.beacon(o,E)}catch{}},i=a.body,c=typeof r.transcript_path=="string"?r.transcript_path:"",l={intent:"",retrievalContext:t.defaultRetrievalContext??"unknown"};if(t.readContext&&c)try{l=await t.readContext(c)}catch{l={intent:"",retrievalContext:"unknown"}}if(X0(o)&&l.retrievalContext!=="available")return n;let d=await Xj(t,Yj(o,r.tool_input),i),u=d?.body??i,f=d?.marker??"";if(!d&&i.length<=t.sizeGate&&(!t.mediumBand||!jd(i,{minChars:Pj})))return n;let p=i.length-u.length-f.length,h=async(E,x,A=E.length+f.length)=>{let R=(d?.decision.teed?E.replaceAll("; not retrievable in this context]","]"):E)+f,B=R;if(t.finalizeOutput)try{let ie=t.finalizeOutput(R);ie.length<=R.length&&(B=ie)}catch{B=R}let V=R.length-B.length,H=cy(p)+x+cy(V);H>0&&await s({originalChars:i.length,trimmedChars:Math.max(0,A-V),estTokensSaved:H,...d&&{digest:d.decision}});let X=a.rebuild(B);return{stdout:Bj(X),replacement:X}},m=async()=>d?h(u,0):n;if(d&&u.length<=t.sizeGate)return h(u,0);let w=l.intent?`${l.intent}
|
|
717
|
+
${Z0(r.tool_input)}`:Z0(r.tool_input),g=W0(o,w,u),y=async E=>{try{await t.cachePut(g,E)}catch{}},b=null;try{b=await t.cacheGet(g)}catch{b=null}if(b)return b.optimized&&b.output.length<u.length?h(b.output,b.tokensSaved):m();let C=null;try{C=n2(o)?null:await t.optimize(o,r.tool_input,u,l.intent,l.retrievalContext)}catch{C=null}if(C&&!C.handled&&(C=null),C)return C.optimized&&C.output.length<u.length?(await y({optimized:!0,output:C.output,tokensSaved:cy(u.length-C.output.length)}),h(C.output,0,u.length+f.length)):(await y({optimized:!1}),m());let S;try{S=t.localTrim(u)}catch{return m()}return S.trimmed?h(S.text,S.estTokensSaved):m()},Ti=async()=>{let e=[];try{for await(let t of process.stdin)e.push(t)}catch{return""}return Buffer.concat(e).toString("utf-8")},zj=()=>{let e=n=>{let r=process.env[n];if(!r)return;let o=Number(r);return Number.isFinite(o)&&o>0?o:void 0},t=n=>{let r=process.env[n];if(!r)return;let o=Number(r);return Number.isFinite(o)&&o>=0?Math.floor(o):void 0};return{maxChars:e("ANYRAY_HOOK_MAX_CHARS"),headChars:e("ANYRAY_HOOK_HEAD_CHARS"),tailChars:e("ANYRAY_HOOK_TAIL_CHARS"),middleWindows:t("ANYRAY_HOOK_MIDDLE_WINDOWS")}},qj=Rj(Oj),Qj=async e=>{try{let t=await qj(e);return{body:new Uint8Array(t.buffer,t.byteOffset,t.byteLength),encoding:"gzip"}}catch{return{body:e}}},X0=e=>/(^|[^a-z0-9])anyray_read$/i.test(e.trim()),e2=e=>{let t=e.trim();return/anyray_/i.test(t)?!1:/(^|[^a-z0-9])(read|read_file|readfile)$/i.test(t)},t2=e=>/(^|[^a-z0-9])anyray_(search|read)$/i.test(e.trim()),n2=e=>/(^|[^a-z0-9])anyray_history$/i.test(e.trim()),r2=2048,o2=async e=>{try{let t=(await e.text().catch(()=>"")).slice(0,r2),n=id(t);if(!n)return;await sS({at:Date.now(),status:e.status,code:n})}catch{}},a2=async(e,t,n,r,o,a)=>{if(!e)return null;let s=new AbortController,i=setTimeout(()=>s.abort(),Tj());try{let c=await Qj(JSON.stringify({tool:t,toolInput:n,...o?{intent:o}:{},retrievalContext:a,...X0(t)||e2(t)&&a==="available"?{reversible:!0}:{},...t2(t)?{semanticRerank:!0}:{},output:r})),l=Yt(e);c.encoding&&(l["content-encoding"]=c.encoding);let d=await fetch(`${e.origin}/connect/optimize-output`,{method:"POST",headers:l,body:c.body,signal:s.signal});if(!d.ok)return(d.status===401||d.status===403)&&await o2(d),null;let u=await d.json();return{optimized:u?.optimized===!0&&typeof u?.output=="string",output:typeof u?.output=="string"?u.output:r,handled:u?.handled===!0}}catch{return null}finally{clearTimeout(i)}},J0=async(e="claude")=>{let t=await Ti();if(e!=="cursor"&&Hj(t))return 0;let n=e==="cursor"?Uj(t):t;if(n===void 0)return 0;let{stdout:r,replacement:o}=await ly(n,e);if(e==="cursor"){let a=Wj(o);return a&&process.stdout.write(a),0}return r&&process.stdout.write(r),0},ly=async(e,t="claude",n)=>{await Cr(),await aS(t);let r=zj(),o=await ot(),a=o&&{...o,metadata:Nj(o.metadata,t)},s=Mj(t);return Jj(e,{optimize:(i,c,l,d,u)=>a2(a,i,c,l,d,u),...t==="claude"?{readContext:async i=>{let c=await Y0(i);return{intent:c.intent,retrievalContext:c.kind==="main"?"available":c.kind==="subagent"?"unavailable":"unknown"}},defaultRetrievalContext:"unknown"}:{defaultRetrievalContext:"available"},localTrim:i=>Gd(i,r),beacon:(i,c)=>ac(a,"hook",c,i),cacheGet:s.cacheGet,cachePut:s.cachePut,sizeGate:r.maxChars??Or.maxChars,digestCommand:L0,tee:s.tee,mediumBand:Dj.has(t),finalizeOutput:n})};var z0=async()=>0;var s2=async(e,t)=>{let n={stdout:""};if(!e.trim())return n;let r;try{let a=JSON.parse(e);if(!a||typeof a!="object")return n;let s=a.prompt;if(typeof s!="string"||!s)return n;r=s}catch{return n}if(!t.isPaste(r))return n;let o=null;try{o=t.measure(r)}catch{o=null}if(!o||o.estTokensSaved<=0)return n;try{await t.beacon(o)}catch{}return n},i2=async(e,t={})=>{try{if(!e.trim())return;let n;try{n=JSON.parse(e)?.hook_event_name}catch{return}if(n!=="beforeSubmitPrompt")return;let r=await(t.readBootstrap??Wt)();if(!r)return;let o=await(t.ssoGate??Kn)({sso:r.sso,gateway:r.gateway},{routingIntact:async()=>!0,applyClaudeCode:async()=>{}});if(o.exitCode!==2||!o.stderr)return;let a=o.stderr.trim().replace(/Your prompt was not sent — complete sign-in, then resubmit it\.?/,"This request will fail until sign-in completes \u2014 then just continue chatting.");return`${JSON.stringify({continue:!0,user_message:a})}
|
|
718
|
+
`}catch{return}},c2=async()=>{let e=[];try{for await(let t of process.stdin)e.push(t)}catch{return""}return Buffer.concat(e).toString("utf-8")},l2=()=>{let e=t=>{let n=process.env[t];if(!n)return;let r=Number(n);return Number.isFinite(r)&&r>0?r:void 0};return{minChars:e("ANYRAY_PROMPT_PASTE_MIN_CHARS"),minDataLines:e("ANYRAY_PROMPT_PASTE_MIN_LINES")}},d2=(e,t)=>{let n=t.minChars??_i.minChars,r={maxChars:Math.min(Or.maxChars,n)},o=Gd(e,r);return!o.trimmed||o.estTokensSaved<=0?null:{originalChars:o.originalChars,trimmedChars:o.trimmedChars,estTokensSaved:o.estTokensSaved}},q0=async()=>{let e=await c2(),t=await i2(e);t&&process.stdout.write(t);let n=l2(),r=await ot();return await s2(e,{isPaste:o=>jd(o,n),measure:o=>d2(o,n),beacon:o=>ac(r,"prompt",o)}),0};import{spawn as u2}from"node:child_process";var Q0=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),p2=/[|&;<>`$()\n]/,ex=e=>{if(p2.test(e))return null;let t=[],n="",r=!1,o=null;for(let a of e){if(o){if(a===o)o=null;else{if(o==='"'&&a==="\\")return null;n+=a,r=!0}continue}if(a==='"'||a==="'"){o=a,r=!0;continue}if(a===" "||a===" "){r&&(t.push(n),n="",r=!1);continue}if("*?[]{}~#\\".includes(a))return null;n+=a,r=!0}return o||(r&&t.push(n),!t.length)||/^[A-Za-z_][A-Za-z0-9_]*=/.test(t[0])?null:t},f2=(e,t)=>{let n;try{n=JSON.parse(e)}catch{return""}if(!Q0(n)||n.tool_name!=="Shell")return"";let r=n.tool_input;if(!Q0(r)||typeof r.command!="string")return"";let o=r.command;return!o||o.includes(Ru)||!t.isRecognized(o)||ex(o)===null?"":JSON.stringify({updated_input:{...r,command:t.wrap(o)}})},h2=async(e,t)=>{let n="";try{n=Buffer.from(String(e??""),"base64").toString("utf8")}catch{n=""}let r=n?ex(n):null;if(!n||!r)return t.writeErr(`anyray: could not run wrapped command
|
|
719
719
|
`),1;let o;try{o=await t.exec(r)}catch{return t.writeErr(`anyray: failed to run wrapped command
|
|
720
|
-
`),1}if(o.alreadyWritten)return o.code;let a=o.output;try{a=await t.trim(n,o.output)}catch{a=o.output}return t.write(a),o.code},u2=16*1024*1024,p2=e=>new Promise(t=>{let n=[],r=0,o=!1,a=!1,s=new Map,i=c=>{if(!a){a=!0;for(let[l,d]of s)process.off(l,d);t({output:o?"":Buffer.concat(n).toString("utf8"),code:c,...o?{alreadyWritten:!0}:{}})}};try{let c=i2(e[0],e.slice(1),{stdio:["inherit","pipe","pipe"]});for(let d of["SIGINT","SIGTERM","SIGHUP"]){let u=()=>{if(c.exitCode===null&&c.signalCode===null)try{c.kill(d)}catch{}};s.set(d,u),process.on(d,u)}let l=d=>{if(o){process.stdout.write(d);return}if(r+d.byteLength>u2){for(let u of n)process.stdout.write(u);n.length=0,process.stdout.write(d),o=!0;return}n.push(d),r+=d.byteLength};c.stdout?.on("data",l),c.stderr?.on("data",l),c.on("error",()=>i(1)),c.on("close",(d,u)=>i(typeof d=="number"?d:u?1:0))}catch{i(1)}}),f2=async(e,t)=>{let n=JSON.stringify({tool_name:"Bash",tool_input:{command:e},tool_response:t}),{replacement:r}=await ly(n,"cursor");return typeof r=="string"?r:t},tx=e=>{let t=e[0]==="--b64"?e[1]:void 0;return d2(t,{exec:p2,trim:f2,write:n=>process.stdout.write(n),writeErr:n=>process.stderr.write(n)})},nx=async()=>{let e=await Ti();if(process.platform==="win32")return 0;let t=l2(e,{isRecognized:n=>oy(n)!==null||P0(n),wrap:n=>Rt(Ru,["--b64",Buffer.from(n,"utf8").toString("base64")])});return t&&process.stdout.write(t),0};import{createHash as h2}from"node:crypto";import{homedir as rx}from"node:os";import{extname as m2,isAbsolute as y2,join as dy,resolve as Li,sep as ox}from"node:path";import{chmod as g2,readFile as w2,stat as lx,unlink as b2,writeFile as k2}from"node:fs/promises";var py=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),A2=16*1024,ax=["path","file_path","target_file","targetFile","relative_workspace_path","relativeWorkspacePath","filePath"],C2=["pattern","query","regex","search"],v2=new Set([".png",".jpg",".jpeg",".gif",".webp",".ico",".pdf",".zip",".gz",".tar",".tgz",".woff",".woff2",".ttf",".otf",".mp3",".mp4",".mov",".wasm",".so",".dylib",".dll",".exe",".bin",".parquet",".sqlite",".db"]),S2=720*60*1e3,E2=512,uy=(e,t)=>{for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}return null},x2=e=>Array.isArray(e)?e.filter(t=>typeof t=="string"):[],sx=(e,t)=>t.some(n=>e===n||e.startsWith(n.endsWith(ox)?n:n+ox)),I2=(e,t,n)=>y2(e)?[Li(e)]:[...new Set([Li(t,e),...n.map(r=>Li(r,e))])],ix=(e,t,n)=>h2("sha256").update(`${e.length}:${e}`).update(`${t.length}:${t}`).update(n).digest("hex").slice(0,32),cx=e=>JSON.stringify({permission:"deny",agent_message:e,user_message:"Anyray routed this through its context tools to keep the request small."}),O2=async(e,t)=>{let n;try{n=JSON.parse(e)}catch{return""}if(!py(n))return"";let r=n.tool_name;if(r!=="Read"&&r!=="Grep")return"";let o=n.tool_input;if(!py(o))return"";let a=x2(n.workspace_roots).map(d=>Li(d));if(!a.length)return"";let s=typeof n.cwd=="string"&&n.cwd?n.cwd:a[0],i=typeof n.conversation_id=="string"&&n.conversation_id||typeof n.session_id=="string"&&n.session_id||"";if(r==="Grep"){let d=uy(o,C2);if(!d)return"";let u=uy(o,ax);return u&&!sx(Li(s,u),a)||!await t.remember(ix(i,"Grep",d))?"":cx(`Anyray: run this search with the anyray_search MCP tool instead of the built-in search. anyray_search ranks the matches by relevance and drops the noise, so the hits that answer the task reach you without the rest. Call anyray_search with query ${JSON.stringify(d)} now; do not retry the built-in search.`)}let c=uy(o,ax);if(!c||v2.has(m2(c).toLowerCase()))return"";let l=await t.resolveFile(I2(c,s,a));return!l||l.bytes<A2||!sx(l.path,a)||!await t.remember(ix(i,"Read",l.path))?"":cx(`Anyray: ${JSON.stringify(l.path)} is ${Math.round(l.bytes/1024)} KB \u2014 read it with the anyray_read MCP tool instead of the built-in read. anyray_read returns the part of the file that answers the task plus a retrieve handle (ctx_\u2026) you can pass to anyray_retrieve for any detail it elided, so the whole file never enters the context. Call anyray_read now; do not retry the built-in read.`)},R2=async e=>{for(let t of e)try{let n=await lx(t);if(n.isFile())return{path:t,bytes:n.size}}catch{}return null},_2=async()=>{let e=dy(rx(),".anyray");try{if((await lx(e)).isDirectory())return dy(e,"cursor-redirects.json")}catch{}return dy(rx(),".anyray-cursor-redirects.json")},P2=async e=>{let t;try{let n=await _2(),r=Date.now(),o={};try{let s=JSON.parse(await w2(n,"utf-8"));if(s?.v===1&&py(s.seen))for(let[i,c]of Object.entries(s.seen))typeof c=="number"&&r-c<=S2&&(o[i]=c)}catch{}if(o[e]!==void 0)return!1;o[e]=r;let a=Object.entries(o).sort((s,i)=>i[1]-s[1]).slice(0,E2);return t=`${n}.${process.pid}.tmp`,await k2(t,JSON.stringify({v:1,seen:Object.fromEntries(a)}),{mode:384}),await g2(t,384),await pe(t,n),!0}catch{if(t)try{await b2(t)}catch{}return!1}},dx=async()=>{let e=await Ti(),t="";try{t=await O2(e,{resolveFile:R2,remember:P2})}catch{t=""}return t&&process.stdout.write(t),0};var Di=(e,t)=>{let n=e[t];return typeof n=="string"&&n?n:void 0},fy=e=>typeof e=="string"&&e.trim()?e.trim():void 0,T2=e=>{try{let t=JSON.parse(e);if(t===null||typeof t!="object"||Array.isArray(t))return null;let n=t,r=Di(n,"deviceCode"),o=Di(n,"privateKeyPem"),a=Di(n,"publicKeyPem"),s=Di(n,"cpOrigin"),i=Di(n,"tenantId"),c=n.intervalMs,l=n.grantExpiresAt,d=n.startedAt;if(!r||!o||!a||!s||!i||typeof c!="number"||!Number.isFinite(c)||typeof l!="number"||!Number.isFinite(l)||typeof d!="number"||!Number.isFinite(d))return null;let u=fy(n.gatewayUrl),f=fy(n.gatewayOverride),p=fy(n.team);return{deviceCode:r,privateKeyPem:o,publicKeyPem:a,cpOrigin:s,tenantId:i,intervalMs:c,grantExpiresAt:l,startedAt:d,...u?{gatewayUrl:u}:{},...f?{gatewayOverride:f}:{},...p?{team:p}:{}}}catch{return null}},L2=e=>new Promise(t=>setTimeout(t,e)),D2=async(e,t)=>{let n=await t.readGateState()??{v:1};await t.writeGateState({v:1,lastAttemptAt:t.now(),failureCount:(n.failureCount??0)+1,lastFailure:e})},N2=async(e,t={})=>{let n=t.poll??qh,r=t.verify??rn,o=t.loadProfile??P,a=t.saveProfile??te,s=t.saveDevKey??Gi,i=t.readGateState??Sr,c=t.writeGateState??gd,l=t.clearGateState??yS,d=t.sleep??L2,u=t.now??Date.now,f=t.recordMint??ba,p=t.reserveMint??yo,h=t.applyClaudeCode??(async x=>{await Qn.apply(x,{dryRun:!1})}),m=x=>D2(x,{readGateState:i,writeGateState:c,now:u}),w={cpOrigin:e.cpOrigin,tenantId:e.tenantId,deviceCode:e.deviceCode,userCode:"",verificationUriComplete:"",intervalMs:e.intervalMs,grantExpiresAt:e.grantExpiresAt,startedAt:e.startedAt,privateKeyPem:e.privateKeyPem,publicKeyPem:e.publicKeyPem,gatewayUrl:e.gatewayUrl},g;try{g=await n(w,{gatewayUrl:e.gatewayOverride})}catch(x){let A=x instanceof vr?x.kind:"cp-unreachable";return await m(A),A}let y=e.gatewayOverride??g.gatewayUrl,b=await o(),C={...b,gateway:y??b.gateway,name:g.cert.payload.user||b.name,team:e.team??g.cert.payload.team??b.team,enrolledCert:g.cert,enrolledCertExpiry:g.cert.payload.expiresAt,ssoLink:`${e.cpOrigin}/sso/${e.tenantId}`,clientKey:void 0,clientKeyExpiresAt:void 0,authMode:"subscription"};try{await s(g.privateKeyPem),await a(C)}catch{return"failed"}if(!y)return await m("gateway-unreachable"),"gateway-unreachable";let S;await p();for(let x=0;x<3;x++)try{S=await r(y,g.cert,g.privateKeyPem,{timeoutMs:1e4});break}catch(A){if(A instanceof It||x===2)break;await d(1e3)}if(!S)return await m("gateway-unreachable"),"gateway-unreachable";let E={...C,gateway:y,name:S.user,team:e.team??S.team??C.team,clientKey:S.key,clientKeyExpiresAt:S.expiresAt,authMode:"subscription"};try{await a(E),await f({expiresAt:S.expiresAt});let x=me({origin:y,clientKey:S.key,subscription:!0,user:E.name,team:E.team});return await h(x),await l(),"enrolled"}catch{return await m("gateway-unreachable"),"failed"}},$2=async()=>{let e=[];try{for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}catch{return""}},ux=async()=>{let e=T2(await $2());if(e)try{await N2(e)}catch{}return 0};var M2=1e4,hy=/^[\w.:-]{1,64}$/,Gt=class extends Error{kind;constructor(t,n){super(n),this.kind=t,this.name="LoginError"}},my=e=>e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0,px=async(e,t,n)=>{let r=new AbortController,o=setTimeout(()=>r.abort(),M2);try{let a=await n(e,{...t,signal:r.signal}),s={};try{s=await a.json()}catch{s={}}return{status:a.status,body:s}}catch{throw new Gt("gateway-unreachable","Could not reach the Anyray gateway to sign in.")}finally{clearTimeout(o)}},F2=e=>{let t=my(e);if(!t)return;let n=t.browser_url;try{if(typeof n!="string")return;let r=new URL(n);if(r.protocol!=="http:"&&r.protocol!=="https:")return}catch{return}if(!(typeof t.id!="string"||!t.id||typeof t.user_code!="string"||!t.user_code||typeof t.poll_secret!="string"||!t.poll_secret||typeof t.interval!="number"||!Number.isFinite(t.interval)||t.interval<=0||typeof t.expires_in!="number"||!Number.isFinite(t.expires_in)||t.expires_in<=0))return{id:t.id,browser_url:n,user_code:t.user_code,poll_secret:t.poll_secret,interval:t.interval,expires_in:t.expires_in}},B2=e=>{let t=my(e);if(t?.status!=="team_selection"||typeof t.user!="string"||!Array.isArray(t.teams))return;let n=t.teams.filter(o=>typeof o=="string"&&hy.test(o));if(n.length===0||n.length!==t.teams.length)return;let r=typeof t.default_team=="string"&&hy.test(t.default_team)?t.default_team:void 0;return{status:"team_selection",user:t.user,teams:n,...r&&{default_team:r}}},U2=e=>{let t=my(e);if(!(t?.status!=="complete"||typeof t.key!="string"||!Ie(t.key)||typeof t.user!="string"||!t.user||typeof t.team!="string"||!hy.test(t.team)))return{status:"complete",key:t.key,user:t.user,team:t.team,...typeof t.expires_at=="string"&&{expires_at:t.expires_at}}},H2=e=>new Promise(t=>setTimeout(t,e)),W2=async(e,t,n)=>{if(e.length===1)return e[0];if(!n){if(t&&e.includes(t))return t;throw new Gt("invalid-team",`Multiple teams are available (${e.join(", ")}). Re-run with --team <name>.`)}k("Available teams:"),e.forEach((i,c)=>k(` ${c+1}. ${i}`));let r=t&&e.includes(t)?t:e[0],o=await xa("Choose a team",r),a=o?Number.parseInt(o,10):NaN,s=Number.isInteger(a)&&a>=1&&a<=e.length?e[a-1]:o;if(!s||!e.includes(s))throw new Gt("invalid-team","Choose one of the teams shown above.");return s},K2=async(e,t={})=>{let n=t.fetch??fetch,r=t.now??Date.now,o=t.sleep??H2,a=t.loadProfile??P,s=t.saveProfile??te,i=t.clearDevKey??Ka,c=t.chooseTeam??W2,l=t.apply??(async g=>{await Qn.apply(g,{dryRun:!1})}),d=t.log??F,u=await a(),f=Er(e.gateway,u),p=await px(`${f}/sso/cli/start`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"},n),h=F2(p.body);if(p.status!==200||!h)throw new Gt("login-failed","The gateway could not start SSO login.");d("Open this URL to sign in with your organization:"),d(` ${h.browser_url}`),d(`Enter this code in the browser: ${h.user_code}`),(t.openBrowser??wd)(h.browser_url);let m=r()+h.expires_in*1e3,w=e.team?.trim()||void 0;for(;r()<m;){let g=await px(`${f}/sso/cli/poll/${encodeURIComponent(h.id)}`,{method:"GET",headers:{"x-anyray-poll-secret":h.poll_secret,...w?{"x-anyray-team":w}:{}}},n);if(g.status===202){await o(h.interval*1e3);continue}if(g.status===401)throw new Gt("wrong-poll-secret","The gateway rejected this login session. Start a new login.");if(g.status===410)throw new Gt("expired","SSO login expired before it completed. Run anyray-connect login again.");let y=B2(g.body);if(g.status===200&&y){if(w&&!y.teams.includes(w))throw new Gt("invalid-team",`Team ${w} is not available for this account.`);w=await c(y.teams,y.default_team,e.interactive??Kt());continue}let b=U2(g.body);if(g.status!==200||!b)throw new Gt("login-failed","SSO login could not be completed.");let C={...u,gateway:f,name:b.user,team:b.team,clientKey:b.key,clientKeyExpiresAt:b.expires_at,enrolledCert:void 0,enrolledCertExpiry:void 0,enrolledTokenHash:void 0,ssoLink:void 0,authMode:"subscription"};return await i(),await s(C),await l(me({origin:f,clientKey:b.key,subscription:!0,user:b.user,team:b.team})),b}throw new Gt("expired","SSO login expired before it completed. Run anyray-connect login again.")},G2=`anyray-connect login [--gateway <url>] [--team <name>]
|
|
720
|
+
`),1}if(o.alreadyWritten)return o.code;let a=o.output;try{a=await t.trim(n,o.output)}catch{a=o.output}return t.write(a),o.code},m2=16*1024*1024,y2=e=>new Promise(t=>{let n=[],r=0,o=!1,a=!1,s=new Map,i=c=>{if(!a){a=!0;for(let[l,d]of s)process.off(l,d);t({output:o?"":Buffer.concat(n).toString("utf8"),code:c,...o?{alreadyWritten:!0}:{}})}};try{let c=u2(e[0],e.slice(1),{stdio:["inherit","pipe","pipe"]});for(let d of["SIGINT","SIGTERM","SIGHUP"]){let u=()=>{if(c.exitCode===null&&c.signalCode===null)try{c.kill(d)}catch{}};s.set(d,u),process.on(d,u)}let l=d=>{if(o){process.stdout.write(d);return}if(r+d.byteLength>m2){for(let u of n)process.stdout.write(u);n.length=0,process.stdout.write(d),o=!0;return}n.push(d),r+=d.byteLength};c.stdout?.on("data",l),c.stderr?.on("data",l),c.on("error",()=>i(1)),c.on("close",(d,u)=>i(typeof d=="number"?d:u?1:0))}catch{i(1)}}),g2=async(e,t)=>{let n=JSON.stringify({tool_name:"Bash",tool_input:{command:e},tool_response:t}),{replacement:r}=await ly(n,"cursor");return typeof r=="string"?r:t},tx=e=>{let t=e[0]==="--b64"?e[1]:void 0;return h2(t,{exec:y2,trim:g2,write:n=>process.stdout.write(n),writeErr:n=>process.stderr.write(n)})},nx=async()=>{let e=await Ti();if(process.platform==="win32")return 0;let t=f2(e,{isRecognized:n=>oy(n)!==null||P0(n),wrap:n=>Rt(Ru,["--b64",Buffer.from(n,"utf8").toString("base64")])});return t&&process.stdout.write(t),0};import{createHash as w2}from"node:crypto";import{homedir as rx}from"node:os";import{extname as b2,isAbsolute as k2,join as dy,resolve as Li,sep as ox}from"node:path";import{chmod as A2,readFile as C2,stat as lx,unlink as v2,writeFile as S2}from"node:fs/promises";var py=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),E2=16*1024,ax=["path","file_path","target_file","targetFile","relative_workspace_path","relativeWorkspacePath","filePath"],x2=["pattern","query","regex","search"],I2=new Set([".png",".jpg",".jpeg",".gif",".webp",".ico",".pdf",".zip",".gz",".tar",".tgz",".woff",".woff2",".ttf",".otf",".mp3",".mp4",".mov",".wasm",".so",".dylib",".dll",".exe",".bin",".parquet",".sqlite",".db"]),O2=720*60*1e3,R2=512,uy=(e,t)=>{for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}return null},_2=e=>Array.isArray(e)?e.filter(t=>typeof t=="string"):[],sx=(e,t)=>t.some(n=>e===n||e.startsWith(n.endsWith(ox)?n:n+ox)),P2=(e,t,n)=>k2(e)?[Li(e)]:[...new Set([Li(t,e),...n.map(r=>Li(r,e))])],ix=(e,t,n)=>w2("sha256").update(`${e.length}:${e}`).update(`${t.length}:${t}`).update(n).digest("hex").slice(0,32),cx=e=>JSON.stringify({permission:"deny",agent_message:e,user_message:"Anyray routed this through its context tools to keep the request small."}),T2=async(e,t)=>{let n;try{n=JSON.parse(e)}catch{return""}if(!py(n))return"";let r=n.tool_name;if(r!=="Read"&&r!=="Grep")return"";let o=n.tool_input;if(!py(o))return"";let a=_2(n.workspace_roots).map(d=>Li(d));if(!a.length)return"";let s=typeof n.cwd=="string"&&n.cwd?n.cwd:a[0],i=typeof n.conversation_id=="string"&&n.conversation_id||typeof n.session_id=="string"&&n.session_id||"";if(r==="Grep"){let d=uy(o,x2);if(!d)return"";let u=uy(o,ax);return u&&!sx(Li(s,u),a)||!await t.remember(ix(i,"Grep",d))?"":cx(`Anyray: run this search with the anyray_search MCP tool instead of the built-in search. anyray_search ranks the matches by relevance and drops the noise, so the hits that answer the task reach you without the rest. Call anyray_search with query ${JSON.stringify(d)} now; do not retry the built-in search.`)}let c=uy(o,ax);if(!c||I2.has(b2(c).toLowerCase()))return"";let l=await t.resolveFile(P2(c,s,a));return!l||l.bytes<E2||!sx(l.path,a)||!await t.remember(ix(i,"Read",l.path))?"":cx(`Anyray: ${JSON.stringify(l.path)} is ${Math.round(l.bytes/1024)} KB \u2014 read it with the anyray_read MCP tool instead of the built-in read. anyray_read returns the part of the file that answers the task plus a retrieve handle (ctx_\u2026) you can pass to anyray_retrieve for any detail it elided, so the whole file never enters the context. Call anyray_read now; do not retry the built-in read.`)},L2=async e=>{for(let t of e)try{let n=await lx(t);if(n.isFile())return{path:t,bytes:n.size}}catch{}return null},D2=async()=>{let e=dy(rx(),".anyray");try{if((await lx(e)).isDirectory())return dy(e,"cursor-redirects.json")}catch{}return dy(rx(),".anyray-cursor-redirects.json")},N2=async e=>{let t;try{let n=await D2(),r=Date.now(),o={};try{let s=JSON.parse(await C2(n,"utf-8"));if(s?.v===1&&py(s.seen))for(let[i,c]of Object.entries(s.seen))typeof c=="number"&&r-c<=O2&&(o[i]=c)}catch{}if(o[e]!==void 0)return!1;o[e]=r;let a=Object.entries(o).sort((s,i)=>i[1]-s[1]).slice(0,R2);return t=`${n}.${process.pid}.tmp`,await S2(t,JSON.stringify({v:1,seen:Object.fromEntries(a)}),{mode:384}),await A2(t,384),await pe(t,n),!0}catch{if(t)try{await v2(t)}catch{}return!1}},dx=async()=>{let e=await Ti(),t="";try{t=await T2(e,{resolveFile:L2,remember:N2})}catch{t=""}return t&&process.stdout.write(t),0};var Di=(e,t)=>{let n=e[t];return typeof n=="string"&&n?n:void 0},fy=e=>typeof e=="string"&&e.trim()?e.trim():void 0,$2=e=>{try{let t=JSON.parse(e);if(t===null||typeof t!="object"||Array.isArray(t))return null;let n=t,r=Di(n,"deviceCode"),o=Di(n,"privateKeyPem"),a=Di(n,"publicKeyPem"),s=Di(n,"cpOrigin"),i=Di(n,"tenantId"),c=n.intervalMs,l=n.grantExpiresAt,d=n.startedAt;if(!r||!o||!a||!s||!i||typeof c!="number"||!Number.isFinite(c)||typeof l!="number"||!Number.isFinite(l)||typeof d!="number"||!Number.isFinite(d))return null;let u=fy(n.gatewayUrl),f=fy(n.gatewayOverride),p=fy(n.team);return{deviceCode:r,privateKeyPem:o,publicKeyPem:a,cpOrigin:s,tenantId:i,intervalMs:c,grantExpiresAt:l,startedAt:d,...u?{gatewayUrl:u}:{},...f?{gatewayOverride:f}:{},...p?{team:p}:{}}}catch{return null}},M2=e=>new Promise(t=>setTimeout(t,e)),F2=async(e,t)=>{let n=await t.readGateState()??{v:1};await t.writeGateState({v:1,lastAttemptAt:t.now(),failureCount:(n.failureCount??0)+1,lastFailure:e})},B2=async(e,t={})=>{let n=t.poll??qh,r=t.verify??rn,o=t.loadProfile??P,a=t.saveProfile??te,s=t.saveDevKey??Gi,i=t.readGateState??Sr,c=t.writeGateState??gd,l=t.clearGateState??yS,d=t.sleep??M2,u=t.now??Date.now,f=t.recordMint??ba,p=t.reserveMint??yo,h=t.applyClaudeCode??(async x=>{await Qn.apply(x,{dryRun:!1})}),m=x=>F2(x,{readGateState:i,writeGateState:c,now:u}),w={cpOrigin:e.cpOrigin,tenantId:e.tenantId,deviceCode:e.deviceCode,userCode:"",verificationUriComplete:"",intervalMs:e.intervalMs,grantExpiresAt:e.grantExpiresAt,startedAt:e.startedAt,privateKeyPem:e.privateKeyPem,publicKeyPem:e.publicKeyPem,gatewayUrl:e.gatewayUrl},g;try{g=await n(w,{gatewayUrl:e.gatewayOverride})}catch(x){let A=x instanceof vr?x.kind:"cp-unreachable";return await m(A),A}let y=e.gatewayOverride??g.gatewayUrl,b=await o(),C={...b,gateway:y??b.gateway,name:g.cert.payload.user||b.name,team:e.team??g.cert.payload.team??b.team,enrolledCert:g.cert,enrolledCertExpiry:g.cert.payload.expiresAt,ssoLink:`${e.cpOrigin}/sso/${e.tenantId}`,clientKey:void 0,clientKeyExpiresAt:void 0,authMode:"subscription"};try{await s(g.privateKeyPem),await a(C)}catch{return"failed"}if(!y)return await m("gateway-unreachable"),"gateway-unreachable";let S;await p();for(let x=0;x<3;x++)try{S=await r(y,g.cert,g.privateKeyPem,{timeoutMs:1e4});break}catch(A){if(A instanceof It||x===2)break;await d(1e3)}if(!S)return await m("gateway-unreachable"),"gateway-unreachable";let E={...C,gateway:y,name:S.user,team:e.team??S.team??C.team,clientKey:S.key,clientKeyExpiresAt:S.expiresAt,authMode:"subscription"};try{await a(E),await f({expiresAt:S.expiresAt});let x=me({origin:y,clientKey:S.key,subscription:!0,user:E.name,team:E.team});return await h(x),await l(),"enrolled"}catch{return await m("gateway-unreachable"),"failed"}},U2=async()=>{let e=[];try{for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}catch{return""}},ux=async()=>{let e=$2(await U2());if(e)try{await B2(e)}catch{}return 0};var H2=1e4,hy=/^[\w.:-]{1,64}$/,Gt=class extends Error{kind;constructor(t,n){super(n),this.kind=t,this.name="LoginError"}},my=e=>e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0,px=async(e,t,n)=>{let r=new AbortController,o=setTimeout(()=>r.abort(),H2);try{let a=await n(e,{...t,signal:r.signal}),s={};try{s=await a.json()}catch{s={}}return{status:a.status,body:s}}catch{throw new Gt("gateway-unreachable","Could not reach the Anyray gateway to sign in.")}finally{clearTimeout(o)}},W2=e=>{let t=my(e);if(!t)return;let n=t.browser_url;try{if(typeof n!="string")return;let r=new URL(n);if(r.protocol!=="http:"&&r.protocol!=="https:")return}catch{return}if(!(typeof t.id!="string"||!t.id||typeof t.user_code!="string"||!t.user_code||typeof t.poll_secret!="string"||!t.poll_secret||typeof t.interval!="number"||!Number.isFinite(t.interval)||t.interval<=0||typeof t.expires_in!="number"||!Number.isFinite(t.expires_in)||t.expires_in<=0))return{id:t.id,browser_url:n,user_code:t.user_code,poll_secret:t.poll_secret,interval:t.interval,expires_in:t.expires_in}},K2=e=>{let t=my(e);if(t?.status!=="team_selection"||typeof t.user!="string"||!Array.isArray(t.teams))return;let n=t.teams.filter(o=>typeof o=="string"&&hy.test(o));if(n.length===0||n.length!==t.teams.length)return;let r=typeof t.default_team=="string"&&hy.test(t.default_team)?t.default_team:void 0;return{status:"team_selection",user:t.user,teams:n,...r&&{default_team:r}}},G2=e=>{let t=my(e);if(!(t?.status!=="complete"||typeof t.key!="string"||!Ie(t.key)||typeof t.user!="string"||!t.user||typeof t.team!="string"||!hy.test(t.team)))return{status:"complete",key:t.key,user:t.user,team:t.team,...typeof t.expires_at=="string"&&{expires_at:t.expires_at}}},j2=e=>new Promise(t=>setTimeout(t,e)),V2=async(e,t,n)=>{if(e.length===1)return e[0];if(!n){if(t&&e.includes(t))return t;throw new Gt("invalid-team",`Multiple teams are available (${e.join(", ")}). Re-run with --team <name>.`)}k("Available teams:"),e.forEach((i,c)=>k(` ${c+1}. ${i}`));let r=t&&e.includes(t)?t:e[0],o=await xa("Choose a team",r),a=o?Number.parseInt(o,10):NaN,s=Number.isInteger(a)&&a>=1&&a<=e.length?e[a-1]:o;if(!s||!e.includes(s))throw new Gt("invalid-team","Choose one of the teams shown above.");return s},Y2=async(e,t={})=>{let n=t.fetch??fetch,r=t.now??Date.now,o=t.sleep??j2,a=t.loadProfile??P,s=t.saveProfile??te,i=t.clearDevKey??Ka,c=t.chooseTeam??V2,l=t.apply??(async g=>{await Qn.apply(g,{dryRun:!1})}),d=t.log??F,u=await a(),f=Er(e.gateway,u),p=await px(`${f}/sso/cli/start`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"},n),h=W2(p.body);if(p.status!==200||!h)throw new Gt("login-failed","The gateway could not start SSO login.");d("Open this URL to sign in with your organization:"),d(` ${h.browser_url}`),d(`Enter this code in the browser: ${h.user_code}`),(t.openBrowser??wd)(h.browser_url);let m=r()+h.expires_in*1e3,w=e.team?.trim()||void 0;for(;r()<m;){let g=await px(`${f}/sso/cli/poll/${encodeURIComponent(h.id)}`,{method:"GET",headers:{"x-anyray-poll-secret":h.poll_secret,...w?{"x-anyray-team":w}:{}}},n);if(g.status===202){await o(h.interval*1e3);continue}if(g.status===401)throw new Gt("wrong-poll-secret","The gateway rejected this login session. Start a new login.");if(g.status===410)throw new Gt("expired","SSO login expired before it completed. Run anyray-connect login again.");let y=K2(g.body);if(g.status===200&&y){if(w&&!y.teams.includes(w))throw new Gt("invalid-team",`Team ${w} is not available for this account.`);w=await c(y.teams,y.default_team,e.interactive??Kt());continue}let b=G2(g.body);if(g.status!==200||!b)throw new Gt("login-failed","SSO login could not be completed.");let C={...u,gateway:f,name:b.user,team:b.team,clientKey:b.key,clientKeyExpiresAt:b.expires_at,enrolledCert:void 0,enrolledCertExpiry:void 0,enrolledTokenHash:void 0,ssoLink:void 0,authMode:"subscription"};return await i(),await s(C),await l(me({origin:f,clientKey:b.key,subscription:!0,user:b.user,team:b.team})),b}throw new Gt("expired","SSO login expired before it completed. Run anyray-connect login again.")},Z2=`anyray-connect login [--gateway <url>] [--team <name>]
|
|
721
721
|
|
|
722
722
|
Start browser SSO, choose a team, mint a personal gateway key, and configure
|
|
723
723
|
the subscription-backed Connect lane. In a non-interactive shell, --team may be
|
|
724
|
-
omitted only when the identity authority supplies a default or sole team.`,fx=async(e,t={})=>{let n,r;for(let o=0;o<e.length;o++){let a=e[o];if(a==="--help"||a==="-h")return k(
|
|
724
|
+
omitted only when the identity authority supplies a default or sole team.`,fx=async(e,t={})=>{let n,r;for(let o=0;o<e.length;o++){let a=e[o];if(a==="--help"||a==="-h")return k(Z2),0;if(a==="--gateway"||a==="--team"){let s=e[++o];if(!s)return _(`${a} requires a value.`),1;a==="--gateway"?n=s:r=s;continue}return _(`unknown login option: ${a}`),1}try{let o=await Y2({gateway:n,team:r},t);return $(`Signed in as ${o.user} for team ${o.team}. Your personal key was saved and configured.`),0}catch(o){if(o instanceof bt)throw o;return _(o instanceof Gt?o.message:"SSO login failed."),1}};var hx=`anyray-connect update [--check] [--auto on|off] [--json]
|
|
725
725
|
|
|
726
726
|
Keep this machine's anyray-connect binary on the published release. Runs
|
|
727
727
|
automatically about every 30 minutes; this command forces it now.
|
|
@@ -732,27 +732,27 @@ Options:
|
|
|
732
732
|
Off still accepts a release the Anyray team marks mandatory.
|
|
733
733
|
--json Emit the result as JSON.
|
|
734
734
|
--help Show this help.
|
|
735
|
-
`,
|
|
735
|
+
`,X2=e=>{let t={check:!1,json:!1,help:!1};for(let n=0;n<e.length;n++){let r=e[n];if(r==="--check")t.check=!0;else if(r==="--json")t.json=!0;else if(r==="--help"||r==="-h")t.help=!0;else if(r==="--auto"){let o=e[++n];if(o!=="on"&&o!=="off")throw new Error("--auto takes `on` or `off`.");t.auto=o==="on"}else throw new Error(`Unknown option: ${r}`)}return t},J2=e=>{switch(e.outcome){case"current":return`Already on the published version (${e.current}).`;case"available":return`Version ${e.latest} is published; this machine is on ${e.current}.`;case"updated":return`Updated ${e.current} \u2192 ${e.latest}. New commands run it immediately.`;case"migrated":return`Installed the managed ${e.latest} binary at ${e.managedPath}.`;case"migration-available":return`Version ${e.latest} will migrate this npm runtime to the managed standalone binary.`;case"migration-deferred":return`The published standalone binary (${e.latest}) is older than this npm runtime (${e.current}); migration was deferred.`;case"disabled":return`Automatic updates are off. Version ${e.latest} is published; this machine is on ${e.current}.`;case"unmanaged":return"This copy is not an Anyray-managed or npm runtime, so it updates elsewhere.";case"container":return"Self-update is skipped inside a container \u2014 it updates by rebuild, not by download-and-swap.";case"platform-unsupported":return"Self-update is unavailable because this platform has no published standalone binary.";case"unavailable":return"Could not reach the release feed to check for a newer version.";case"failed":return`Could not install ${e.latest??"the published version"} \u2014 staying on ${e.current}.`}},mx=async e=>{let t;try{t=X2(e)}catch(o){return _(o.message),process.stderr.write(hx),1}if(t.help)return process.stdout.write(hx),0;if(t.auto!==void 0){let o=await P();if(o.autoUpdate!==!1!==t.auto&&await te({...o,autoUpdate:t.auto}),t.json||($(`Automatic updates ${t.auto?"enabled":"disabled"}.`),t.auto||k("A release the Anyray team marks mandatory still installs \u2014 that lever is for security fixes.")),!t.auto)return t.json&&process.stdout.write(`${JSON.stringify({autoUpdate:!1},null,2)}
|
|
736
736
|
`),0}let n=await Ii({checkOnly:t.check,force:!t.check,allowNpmMigration:!0});if(t.json){let o=await ko();return process.stdout.write(`${JSON.stringify({...n,autoUpdate:o.autoUpdate,path:o.path,selfUpdateAvailable:o.available,selfUpdateState:o.state},null,2)}
|
|
737
|
-
`),n.outcome==="failed"?1:0}let r=
|
|
737
|
+
`),n.outcome==="failed"?1:0}let r=J2(n);switch(n.outcome){case"updated":case"migrated":$(r);break;case"current":$(r);break;case"available":case"migration-available":k(r),t.check&&k(`Run ${j("anyray-connect update")} to install it.`);break;case"migration-deferred":N(r),k(v("Use the newer npm runtime until that standalone release is published."));break;case"disabled":N(r),k(`Run ${j("anyray-connect update")} to install it now, or ${j("--auto on")} to resume.`);break;case"unmanaged":k(r),k(v("A copy your IT team placed is theirs to roll."));break;case"container":k(r);break;case"platform-unsupported":N(r),k(v("Keep using `npx anyray-connect@latest` on this platform."));break;case"unavailable":N(r);break;case"failed":return _(r),1}return 0};var z2=3e3,yx=async(e={})=>{let t=e.stdout??(i=>process.stdout.write(i)),n=e.stderr??(i=>process.stderr.write(i)),r=e.latestVersion??(()=>Gm(z2)),o=e.updateStatus??ko;t(`anyray-connect ${ke}
|
|
738
738
|
`);let[a,s]=await Promise.all([r().catch(()=>{}),o().catch(()=>{})]);if(a&&Pa(a,ke)>0){let i="Run `anyray-connect update` to install the latest version.";s?.state==="will-migrate"?i="Run `anyray-connect update` to install the managed standalone binary.":s?.state==="container"?i="Self-update is off in this container; updates arrive when it is rebuilt.":s?.state==="platform-unsupported"?i="Self-update is unavailable on this platform; run `npx anyray-connect@latest`.":s?.state==="unmanaged"&&(i="Update this copy with the method that installed it."),n(`Update available: ${ke} \u2192 ${a}
|
|
739
739
|
${i}
|
|
740
|
-
`)}else s?.state==="will-migrate"?n("This npm runtime will migrate to the managed standalone binary on the next persistent setup change.\nRun `anyray-connect update` to migrate now.\n"):s?.state==="container"?n("Self-update and the npm-to-managed-binary migration are off in this container.\nUpdates arrive when the container is rebuilt, not via `anyray-connect update`.\n"):s?.state==="platform-unsupported"&&n("Self-update is unavailable on this platform; use `npx anyray-connect@latest` to stay current.\n");return 0};var
|
|
741
|
-
`),0};var
|
|
742
|
-
`)},
|
|
743
|
-
If the user expected one, their export may predate it, or no export has been imported yet (\`anyray-connect history import <conversations.json>\`).`;let n=new Map;for(let a of t.matches){let s=n.get(a.file)??[];s.push(a),n.set(a.file,s)}let r=[...n.entries()].slice(0,
|
|
740
|
+
`)}else s?.state==="will-migrate"?n("This npm runtime will migrate to the managed standalone binary on the next persistent setup change.\nRun `anyray-connect update` to migrate now.\n"):s?.state==="container"?n("Self-update and the npm-to-managed-binary migration are off in this container.\nUpdates arrive when the container is rebuilt, not via `anyray-connect update`.\n"):s?.state==="platform-unsupported"&&n("Self-update is unavailable on this platform; use `npx anyray-connect@latest` to stay current.\n");return 0};var q2=e=>{if(typeof e!="string"||e.length===0||e.length>512)return!1;try{return new URL(e).protocol==="https:"}catch{return!1}},Q2=e=>typeof e=="string"&&/^[A-Za-z0-9-]{4,16}$/.test(e),eV=async(e={})=>{try{let t=await(e.readBootstrap??Wt)().catch(()=>{});if(!t)return{status:"noop"};await(e.refreshIfDue??Qe)().catch(()=>{});let n=await(e.loadProfile??P)();if(Ie(n.clientKey))return{status:"enrolled"};let r=await(e.ssoGate??Kn)({sso:t.sso,gateway:t.gateway??n.gateway},{routingIntact:async()=>!0,applyClaudeCode:async()=>{}});if(r.exitCode===0)return n=await(e.loadProfile??P)(),Ie(n.clientKey)?{status:"enrolled"}:{status:"noop"};if(r.exitCode!==2||!r.stderr)return{status:"noop"};let o=await(e.readState??Sr)().catch(()=>{}),a=o?.verificationUriComplete,s=o?.userCode;if(!q2(a)||!Q2(s))return{status:"noop"};let i=r.stderr.trim().replace(/Your prompt was not sent — complete sign-in, then resubmit it\.?/,"Anyray chat models appear after sign-in completes.");return{status:"blocked",url:a,code:s,message:i}}catch{return{status:"noop"}}},gx=async(e={})=>{let t=await eV(e);return process.stdout.write(`${JSON.stringify(t)}
|
|
741
|
+
`),0};var tV="2025-06-18",nV={name:"anyray",version:"1"},wx={name:"anyray_retrieve",description:'Get back the original of a tool output Anyray shortened. When a result left a marker like "\xB7 retrieve ctx_\u2026" or "[anyray: \u2026 ctx_\u2026]", pass that ctx_\u2026 handle here. For large outputs prefer grep or startLine/endLine to fetch just the part you need; no extra params returns the full content.',inputSchema:{type:"object",properties:{handle:{type:"string",description:"The ctx_\u2026 handle from an Anyray externalized/trimmed output marker."},startLine:{type:"integer",minimum:1,description:"First line to return (1-based)."},endLine:{type:"integer",minimum:1,description:"Last line to return (inclusive)."},grep:{type:"string",maxLength:256,description:"Literal text; returns matching lines with context."}},required:["handle"],additionalProperties:!1}},rV=20,bx={name:"anyray_recall",description:'Find an earlier tool output Anyray stashed, by meaning rather than by an exact handle. Pass a natural-language query (e.g. "the failing pytest run"); returns ranked ctx_\u2026 handles with short previews to pass to anyray_retrieve. Use when detail was elided earlier but its ctx_\u2026 marker has scrolled out of view. Matches may include the line range to pass to anyray_retrieve.',inputSchema:{type:"object",properties:{query:{type:"string",description:"Natural-language description of the stashed output to find."},k:{type:"number",description:"Max number of matches to return (default 5)."}},required:["query"],additionalProperties:!1}},vx=$m,oV=e=>{if(e==null||typeof e=="string"&&e.trim()==="")return;let t=typeof e=="number"?e:Number(e);if(!Number.isFinite(t))return;let n=Math.round(t);return n<1?1:Math.min(n,vx)},aV=e=>e==="paths"||e==="lines"||e==="full"?e:"full",kx={name:"anyray_search",description:"Search the workspace for a string; returns matching file:line results. Your DEFAULT way to find where something is defined or used \u2014 prefer it over the built-in codebase search and shell grep: Anyray ranks the matches by relevance to the task and trims the noise, so you get the pertinent hits instead of a raw dump. Pass an exact identifier, or a phrase \u2014 if no line contains the whole phrase the search widens to its terms and ranks the lines carrying most of them. Narrow with globs, and set maxResults when you only need the top few.",inputSchema:{type:"object",properties:{query:{type:"string",description:"What to find: an identifier, a phrase, or error text. Matched literally first; a phrase with no exact hit falls back to its terms. Lowercase matches any case."},globs:{type:"array",items:{type:"string"},description:'Optional include globs to restrict the search (e.g. ["*.ts"]).'},maxResults:{type:"number",description:`Cap matches returned (1-${vx}). Ask for fewer when you only need the top hits.`},resultShape:{type:"string",enum:["paths","lines","full"],description:"'paths' = matching files + counts; 'lines' = file:line only; 'full' (default) = file:line plus the matched text. Prefer 'paths' when you only need to know WHERE something lives."}},required:["query"],additionalProperties:!1}},Ax={name:"anyray_read",description:"Read a workspace file. Prefer this over the built-in file read, especially for large files: Anyray returns the task-relevant portion plus a `retrieve ctx_\u2026` handle for anyray_retrieve, so you spend context on the pertinent lines without losing access to the rest. Pass a path inside the workspace; optionally a 1-based line range.",inputSchema:{type:"object",properties:{path:{type:"string",description:"File path to read (workspace-relative or absolute)."},startLine:{type:"number",description:"Optional 1-based inclusive start line."},endLine:{type:"number",description:"Optional 1-based inclusive end line."},focus:{type:"string",description:'What you need from this file, in your own words (e.g. "the exported symbols", "where the retry budget is applied"). Anyray ranks the returned slice against it, so you get the pertinent lines rather than the head of the file.'}},required:["path"],additionalProperties:!1}},sV=8,iV=3,Cx={name:"anyray_history",description:'Search the user\'s imported Claude conversation history (past chats from their Claude account, imported with `anyray-connect history import`). Use whenever the user refers to an earlier conversation you cannot see ("what did we decide about X?"), especially in a client whose own history is unavailable. Call with `query` to find conversations, then `open` (a filename from those results) to read one in full.',inputSchema:{type:"object",properties:{query:{type:"string",description:"Words to look for in past conversations (topic, name, phrase)."},open:{type:"string",description:"Filename from a previous result, to read that conversation in full."}},additionalProperties:!1}},cV=e=>{if(e.length===0)return"No matching stashed outputs found.";let t=e.map((n,r)=>`${r+1}. ${n.handle} (score ${n.score.toFixed(2)})`+(typeof n.startLine=="number"&&typeof n.endLine=="number"?` (lines ${n.startLine}-${n.endLine})`:"")+(n.preview?` \u2014 ${n.preview}`:""));return[`Found ${e.length} matching stashed output${e.length===1?"":"s"} (ranked by relevance):`,...t,"Call anyray_retrieve with a handle above \u2014 pass its lines (startLine/endLine) to fetch just the matching part, or no extra params for the full original."].join(`
|
|
742
|
+
`)},lV=(e,t)=>{if(t.matches.length===0)return`No imported conversation mentions "${e}".
|
|
743
|
+
If the user expected one, their export may predate it, or no export has been imported yet (\`anyray-connect history import <conversations.json>\`).`;let n=new Map;for(let a of t.matches){let s=n.get(a.file)??[];s.push(a),n.set(a.file,s)}let r=[...n.entries()].slice(0,sV).map(([a,s])=>{let i=s.slice(0,iV).map(c=>` ${c.text.trim()}`);return[` ${a}`,...i].join(`
|
|
744
744
|
`)});return[t.matched==="tokens"&&t.tokens?.length?`No imported conversation contains "${e}"; ${n.size} mention${n.size===1?"s":""} some of its terms (${t.tokens.join(", ")}):`:`${n.size} imported conversation${n.size===1?"":"s"} mention "${e}":`,...r,'Call anyray_history({open: "<filename>"}) to read one in full.'].join(`
|
|
745
|
-
`)},Le=(e,t)=>({jsonrpc:"2.0",id:e,result:t}),yy=(e,t,n)=>({jsonrpc:"2.0",id:e,error:{code:t,message:n}}),Se=(e,t=!1)=>({content:[{type:"text",text:e}],...t?{isError:!0}:{}}),
|
|
746
|
-
${p.content}`))}return Le(n??null,Se(p.content))}if(a.name===bx.name){let i=typeof s.query=="string"?s.query.trim():"";if(!i)return Le(n??null,Se("query is required",!0));let c=typeof s.k=="number"?s.k:void 0,l;try{l=await t.recall(i,c)}catch(d){l={ok:!1,message:d instanceof Error?d.message:"recall failed"}}return Le(n??null,l.ok?Se(
|
|
747
|
-
`)}catch{}},l=async f=>{let p=f.trim();if(!p)return;let h;try{h=JSON.parse(p)}catch{console.error("anyray mcp: dropping unparseable frame");return}let m;try{m=await
|
|
748
|
-
`))>=0;){let h=u.slice(0,p);u=u.slice(p+1),await l(h)}}u.trim()&&await l(u)}catch(f){console.error("anyray mcp: stdin error",f instanceof Error?f.message:f)}finally{clearInterval(d)}return 0};import{spawn as
|
|
745
|
+
`)},Le=(e,t)=>({jsonrpc:"2.0",id:e,result:t}),yy=(e,t,n)=>({jsonrpc:"2.0",id:e,error:{code:t,message:n}}),Se=(e,t=!1)=>({content:[{type:"text",text:e}],...t?{isError:!0}:{}}),dV=async(e,t)=>{let n=e?.id,r=n===void 0,o=typeof e?.method=="string"?e.method:"";switch(o){case"initialize":try{t.heartbeat?.()}catch{}return Le(n??null,{protocolVersion:typeof e.params?.protocolVersion=="string"?e.params.protocolVersion:tV,capabilities:{tools:{}},serverInfo:nV});case"notifications/initialized":case"notifications/cancelled":return null;case"ping":return Le(n??null,{});case"tools/list":{let a=[wx,bx,kx,Ax],s=!1;try{s=await t.historyAvailable()}catch{s=!1}return s&&a.push(Cx),Le(n??null,{tools:a})}case"tools/call":{let a=e.params??{},s=a.arguments??{};if(a.name===wx.name){let i=typeof s.handle=="string"?s.handle.trim():"";if(!i)return Le(n??null,Se("handle is required",!0));let c=m=>{if(m!==void 0)return typeof m!="number"||!Number.isFinite(m)?null:Math.max(Math.round(m),1)},l=c(s.startLine),d=c(s.endLine);if(l===null||d===null)return Le(n??null,Se("startLine/endLine must be numbers",!0));let u;if(s.grep!==void 0){if(typeof s.grep!="string"||s.grep.trim()==="")return Le(n??null,Se("grep must be non-empty",!0));if(s.grep.length>256)return Le(n??null,Se("grep is limited to 256 characters",!0));u=s.grep}let f=l!==void 0||d!==void 0||u!==void 0,p;try{p=await t.retrieve(i,f?{startLine:l,endLine:d,grep:u}:void 0)}catch(m){p={ok:!1,message:m instanceof Error?m.message:"retrieve failed"}}let h="this gateway does not support partial retrieval yet \u2014 call again without startLine/endLine/grep for the full content";if(!p.ok)return Le(n??null,Se(p.kind==="slice-unsupported"?h:p.message,!0));if(f&&(p.partial===void 0||typeof p.totalLines!="number"))return Le(n??null,Se(h,!0));if(p.partial===!0&&typeof p.totalLines=="number"){let m=p.grepMatches!==void 0?`[anyray: partial \u2014 ${p.grepMatches} matching line(s) in lines ${p.startLine}-${p.endLine} of ${p.totalLines}`+(p.grepTruncated?`, windows around the first ${rV} matches shown \u2014 narrow the range or grep`:"")+` \xB7 retrieve ${i} again with startLine/endLine, another grep, or no params for full]`:`[anyray: partial \u2014 lines ${p.startLine}-${p.endLine} of ${p.totalLines} \xB7 retrieve ${i} again with other lines, grep, or no params for full]`;return Le(n??null,Se(`${m}
|
|
746
|
+
${p.content}`))}return Le(n??null,Se(p.content))}if(a.name===bx.name){let i=typeof s.query=="string"?s.query.trim():"";if(!i)return Le(n??null,Se("query is required",!0));let c=typeof s.k=="number"?s.k:void 0,l;try{l=await t.recall(i,c)}catch(d){l={ok:!1,message:d instanceof Error?d.message:"recall failed"}}return Le(n??null,l.ok?Se(cV(l.matches)):Se(l.message,!0))}if(a.name===kx.name){let i=typeof s.query=="string"?s.query.trim():"";if(!i)return Le(n??null,Se("query is required",!0));let c=Array.isArray(s.globs)?s.globs.filter(f=>typeof f=="string"):void 0,l=oV(s.maxResults),d=aV(s.resultShape),u;try{u=await t.search(i,c,l)}catch(f){u={ok:!1,matches:[],truncated:!1,engine:"ripgrep",message:f instanceof Error?f.message:"search failed"}}return Le(n??null,u.ok?Se(JE(i,u,d)):Se(u.message??"search failed",!0))}if(a.name===Cx.name){let i=typeof s.open=="string"?s.open.trim():"";if(i){let d;try{d=await t.historyOpen(i)}catch(u){d={ok:!1,content:"",path:i,lines:0,truncated:!1,message:u instanceof Error?u.message:"history open failed"}}return Le(n??null,d.ok?Se(Lm(d)):Se(d.message??"history open failed",!0))}let c=typeof s.query=="string"?s.query.trim():"";if(!c)return Le(n??null,Se("query (or open) is required",!0));let l;try{l=await t.historySearch(c)}catch(d){l={ok:!1,matches:[],truncated:!1,engine:"ripgrep",message:d instanceof Error?d.message:"history search failed"}}return Le(n??null,l.ok?Se(lV(c,l)):Se(l.message??"history search failed",!0))}if(a.name===Ax.name){let i=typeof s.path=="string"?s.path.trim():"";if(!i)return Le(n??null,Se("path is required",!0));let c={startLine:typeof s.startLine=="number"?s.startLine:void 0,endLine:typeof s.endLine=="number"?s.endLine:void 0},l;try{l=await t.read(i,c)}catch(d){l={ok:!1,content:"",path:i,lines:0,truncated:!1,message:d instanceof Error?d.message:"read failed"}}return Le(n??null,l.ok?Se(Lm(l)):Se(l.message??"read failed",!0))}return yy(n??null,-32602,`unknown tool: ${String(a.name)}`)}default:return r?null:yy(n??null,-32601,`method not found: ${o}`)}},uV=async e=>{if(!e)return;let t=new AbortController,n=setTimeout(()=>t.abort(),ld);try{await fetch(`${e.origin}/connect/mcp-heartbeat`,{method:"POST",headers:Yt(e),signal:t.signal})}catch{}finally{clearTimeout(n)}},pV=e=>({retrieve:async(t,n)=>ga(await e(),t,n),recall:async(t,n)=>dd(await e(),t,n),search:(t,n,r)=>Ld(t,{globs:n,...r?{maxMatches:r}:{}}),read:(t,n)=>Td(t,n),historySearch:t=>QE(t),historyOpen:t=>e0(t),historyAvailable:async()=>await Ra()>0,heartbeat:()=>{e().then(uV).catch(()=>{})}}),Sx=async(e="auto",t={})=>{let n=pV(()=>ot(e)),r=t.stdin??process.stdin,o=t.stdout??process.stdout,a=0,s=t.refreshTick??(()=>{let f=Date.now();f<a||(a=f+6e4,Cr().catch(()=>{}))}),i=()=>{try{s()}catch{}},c=f=>{try{o.write(JSON.stringify(f)+`
|
|
747
|
+
`)}catch{}},l=async f=>{let p=f.trim();if(!p)return;let h;try{h=JSON.parse(p)}catch{console.error("anyray mcp: dropping unparseable frame");return}let m;try{m=await dV(h,n)}catch(w){console.error("anyray mcp: dispatch error",w instanceof Error?w.message:w),m=h?.id===void 0?null:yy(h.id,-32603,"internal error")}m&&c(m),i()};i();let d=setInterval(i,30*6e4);d.unref?.();let u="";try{for await(let f of r){u+=f.toString("utf-8");let p;for(;(p=u.indexOf(`
|
|
748
|
+
`))>=0;){let h=u.slice(0,p);u=u.slice(p+1),await l(h)}}u.trim()&&await l(u)}catch(f){console.error("anyray mcp: stdin error",f instanceof Error?f.message:f)}finally{clearInterval(d)}return 0};import{spawn as fV}from"node:child_process";var hV=e=>e==="jetbrains"||e==="windsurf"?e:void 0,mV=async(e,t,n,r=1e4)=>{let o=await new Promise(a=>{let s="",i=!1,c=p=>{i||(i=!0,clearTimeout(l),t.off("data",d),t.off("error",u),t.off("end",f),a(p))},l=setTimeout(()=>c(void 0),r),d=p=>{s+=p.toString();let h=s.indexOf(`
|
|
749
749
|
`);h!==-1?c(s.slice(0,h)):s.length>65536&&c(void 0)},u=()=>c(void 0),f=()=>c(s.length>0?s:void 0);t.on("data",d),t.once("error",u),t.once("end",f)});if(o===void 0)return!1;try{let s=JSON.parse(o)?.id;return typeof s!="number"&&typeof s!="string"?!1:(n.write(`${JSON.stringify({jsonrpc:"2.0",id:s,error:{code:-32e3,message:e}})}
|
|
750
|
-
`),!0)}catch{return!1}},
|
|
750
|
+
`),!0)}catch{return!1}},yV={claude:["ANTHROPIC_AUTH_TOKEN","ANTHROPIC_API_KEY"],codex:["OPENAI_API_KEY"]},gV=(e,t,n)=>{let r=new Set(yV[e].map(s=>s.toUpperCase())),o=new Set(Object.keys(n).map(s=>s.toUpperCase())),a={...t};for(let s of Object.keys(a)){let i=s.toUpperCase();(r.has(i)||o.has(i)||i==="APP_SERVER_LOGS")&&delete a[s]}return{...a,...n}},Ex=async(e,t,n={})=>{let r=n.stderr??process.stderr;if(e!=="claude"&&e!=="codex")return r.write(`Unknown ACP agent.
|
|
751
751
|
`),1;let o=n.platform??process.platform,a=n.environment??process.env;if(!t||!Vl(t,o))return r.write(`Anyray ACP prerequisite is invalid; re-run anyray-connect with Node.js/npm available.
|
|
752
|
-
`),1;await(n.refreshIfDue??Qe)().catch(()=>{});let s=await(n.loadProfile??P)(),i=await(n.readBootstrap??Wt)().catch(()=>{});if(i){let y=await(n.ssoGate??Kn)({sso:i.sso,gateway:i.gateway??s.gateway},{routingIntact:async()=>!0,applyClaudeCode:async()=>{}});if(y.exitCode===2&&y.stderr)return await
|
|
753
|
-
`),1;let c=s.authMode??"auto",l=c==="auto"?await(n.detectSeatState??Tt)():void 0,d=me({origin:s.gateway,clientKey:s.clientKey,user:s.name,team:s.team,subscription:c==="subscription",placeholder:c==="placeholder",seat:l}),u=
|
|
754
|
-
`),1;w=n.comSpec??a.ComSpec??"cmd.exe",g=["/d","/s","/c",`"${h.command}" ${h.args.join(" ")}`]}return await new Promise(y=>{let b=
|
|
755
|
-
`),y(1)}),C.once("exit",(S,E)=>{y(typeof S=="number"?S:E?1:0)})})};import{createReadStream as
|
|
752
|
+
`),1;await(n.refreshIfDue??Qe)().catch(()=>{});let s=await(n.loadProfile??P)(),i=await(n.readBootstrap??Wt)().catch(()=>{});if(i){let y=await(n.ssoGate??Kn)({sso:i.sso,gateway:i.gateway??s.gateway},{routingIntact:async()=>!0,applyClaudeCode:async()=>{}});if(y.exitCode===2&&y.stderr)return await mV(y.stderr.trim(),n.stdin??process.stdin,n.stdout??process.stdout)||r.write(y.stderr),1;s=await(n.loadProfile??P)()}if(!s.gateway)return r.write(`Anyray ACP agent is not configured; run anyray-connect first.
|
|
753
|
+
`),1;let c=s.authMode??"auto",l=c==="auto"?await(n.detectSeatState??Tt)():void 0,d=me({origin:s.gateway,clientKey:s.clientKey,user:s.name,team:s.team,subscription:c==="subscription",placeholder:c==="placeholder",seat:l}),u=hV(n.clientTool);u&&(d.metadata.tool=u);let f=e==="claude"?"Anyray \xB7 Claude":"Anyray \xB7 Codex",p=(n.hookBinaryIsDurable??ce)(),h=QC(d,t,{mcpServer:p?Ge("profile"):void 0})[f],m=n.spawn??fV,w=h.command,g=h.args;if(o==="win32"){if(!h.args.every(y=>y==="--yes"||/^@agentclientprotocol\/(claude-agent-acp|codex-acp)@[0-9]+(?:\.[0-9]+){2}$/.test(y)))return r.write(`Anyray ACP adapter arguments are invalid.
|
|
754
|
+
`),1;w=n.comSpec??a.ComSpec??"cmd.exe",g=["/d","/s","/c",`"${h.command}" ${h.args.join(" ")}`]}return await new Promise(y=>{let b=gV(e,a,h.env),C=m(w,g,{env:b,stdio:"inherit",windowsHide:!0});C.once("error",()=>{r.write(`Could not start the ${e} ACP adapter.
|
|
755
|
+
`),y(1)}),C.once("exit",(S,E)=>{y(typeof S=="number"?S:E?1:0)})})};import{createReadStream as wV}from"node:fs";import{spawnSync as Mx}from"node:child_process";import{createHash as bV}from"node:crypto";import{access as Fx,chmod as by,copyFile as kV,lstat as AV,mkdir as CV,mkdtemp as Bx,readFile as eu,rename as vV,rm as Rr,stat as SV,writeFile as EV}from"node:fs/promises";import{constants as Ux}from"node:fs";import{platform as tu,tmpdir as xV}from"node:os";import{dirname as IV,isAbsolute as OV,join as zd}from"node:path";import{z as $e}from"zod";var RV="fleetd-installer-v4.89.2",xx=`https://github.com/anyrayHQ/install/releases/download/${RV}`,_V=1e4,PV=1e4,Ix=31,TV=1500,Hx=20*1024,gy=20,LV="0.25",DV="/var/tmp",Na="/Library/LaunchDaemons/com.fleetdm.orbit.plist",qd="/etc/default/orbit",$i="/opt/orbit/anyray-enroll-secret.txt",Wx="/opt/orbit/secret-orbit-node-key.txt",NV="/opt/orbit/bin/orbit/orbit",Mi="C:\\Program Files\\Orbit",$V=`${Mi}\\bin\\orbit`,Kx=`${Mi}\\secret-orbit-node-key.txt`,Ni=`${Mi}\\secret.txt`,MV=`${Mi}\\fleet_url.txt`,Gx=`${Mi}\\anyray-managed.txt`,Qd="Fleet osquery",ky="C:\\Windows\\System32\\sc.exe",FV="C:\\Windows\\System32\\whoami.exe",Jd="C:\\Windows\\System32\\icacls.exe",BV="C:\\Windows\\System32\\msiexec.exe",Ay="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",Ox=["-NoProfile","-NonInteractive","-Command","Start-Sleep -Milliseconds 250"],UV=e=>["-NoProfile","-NonInteractive","-Command",`$s = Get-Service -Name '${e}' -ErrorAction SilentlyContinue; if ($s) { $s.Status.ToString() } else { 'absent' }`],HV=`anyray-connect endpoint install
|
|
756
756
|
|
|
757
757
|
Install Fleet's signed endpoint agent and enroll this machine in Anyray.
|
|
758
758
|
|
|
@@ -760,11 +760,11 @@ Supported on macOS, Linux and Windows.
|
|
|
760
760
|
|
|
761
761
|
The command uses the current seat's stored gateway key. Administrator access is
|
|
762
762
|
required: on macOS and Linux Connect asks through sudo once when /dev/tty is
|
|
763
|
-
available; on Windows, run it from a shell started as Administrator.`,jx=e=>!!(e.endpoint&&!e.noEndpoint&&(e.sso||e.enroll)&&!e.revert&&!e.dryRun),se=class extends Error{publicMessage;constructor(t){super(t),this.publicMessage=t,this.name="EndpointInstallError"}},
|
|
764
|
-
`).some(o=>r===void 0?o.startsWith(`${n}=`):o.trim()===`${n}=${r}`);return t("ORBIT_FLEET_URL")&&t("ORBIT_ENROLL_SECRET_PATH",$i)&&!t("ORBIT_ENROLL_SECRET")&&!t("ORBIT_USE_SYSTEM_CONFIGURATION")},Cy=(e,t)=>{if(e==="win32"){let a="--fleet-url ",s=t.indexOf(a);if(s<0)return;let i=t.slice(s+a.length),c;if(i.startsWith('"')){let d=i.indexOf('"',1);if(d<0)return;c=i.slice(1,d)}else{let d=i.indexOf(" ");c=d<0?i:i.slice(0,d)}let l=c.trim();return l.length>0?l:void 0}if(e==="darwin"){let a=t.indexOf("<key>ORBIT_FLEET_URL</key>");if(a<0)return;let s=t.indexOf("<string>",a),i=t.indexOf("</string>",s);return s<0||i<0?void 0:t.slice(s+8,i).replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&").trim()}let n='Environment="ORBIT_FLEET_URL=',r=t.indexOf(n);if(r<0)return;let o=t.indexOf('"',r+n.length);return o<0?void 0:t.slice(r+n.length,o).trim()},Vx=e=>{let t=e(ky,["qc",Qd,"8192"]);return t.status===0?t.stdout:""},vy=e=>{let t=e(Ay
|
|
765
|
-
`&&r--;let o=n.end;for(;o<e.length&&/\s/.test(e[o]);)o++;if(e.startsWith("<string>",o)){let a=e.indexOf("</string>",o);return a<0?null:{start:r,end:a+9}}if(e.startsWith("<true",o)||e.startsWith("<false",o)){let a=e.indexOf("/>",o);return a<0?null:{start:r,end:a+2}}return null},
|
|
763
|
+
available; on Windows, run it from a shell started as Administrator.`,jx=e=>!!(e.endpoint&&!e.noEndpoint&&(e.sso||e.enroll)&&!e.revert&&!e.dryRun),se=class extends Error{publicMessage;constructor(t){super(t),this.publicMessage=t,this.name="EndpointInstallError"}},WV=$e.object({kind:$e.enum(["pkg","deb","rpm","msi"]),path:$e.string().min(1).refine(OV),sha256:$e.string().regex(/^[0-9a-f]{64}$/)}).strict(),KV=$e.object({action:$e.literal("restart"),os:$e.enum(["darwin","linux","win32"])}).strict(),GV=$e.object({action:$e.literal("configure"),os:$e.enum(["darwin","linux","win32"]),fleetUrl:$e.string().min(1).max(2048),enrollSecret:$e.string().min(1).max(4096),package:WV.optional()}).strict(),jV=$e.discriminatedUnion("action",[KV,GV]),Fi=(e,t)=>{let n=Mx(e,t,{encoding:"utf8",stdio:["ignore","pipe","pipe"],timeout:6e5,maxBuffer:1048576});return{status:n.status,stdout:typeof n.stdout=="string"?n.stdout:""}},Sy=async e=>{try{return await Fx(e,Ux.F_OK),!0}catch{return!1}},VV=async e=>{try{let t=await SV(e);return t.isFile()&&t.size>0}catch{return!1}},Ey=(e,t)=>{for(let n=0;;){let r=e.indexOf("<key>",n);if(r<0)return null;let o=e.indexOf("</key>",r);if(o<0)return null;if(e.slice(r+5,o).trim()===t)return{start:r,end:o+6};n=o+6}},wy=(e,t)=>Ey(e,t)!==null,Rx=e=>e==="win32"?Ni:$i,YV=e=>e==="win32"?Kx:Wx,ZV=e=>wy(e,"ORBIT_FLEET_URL")&&wy(e,"ORBIT_ENROLL_SECRET_PATH")&&e.includes(`<string>${$i}</string>`)&&!wy(e,"ORBIT_USE_SYSTEM_CONFIGURATION"),XV=e=>{let t=(n,r)=>e.split(`
|
|
764
|
+
`).some(o=>r===void 0?o.startsWith(`${n}=`):o.trim()===`${n}=${r}`);return t("ORBIT_FLEET_URL")&&t("ORBIT_ENROLL_SECRET_PATH",$i)&&!t("ORBIT_ENROLL_SECRET")&&!t("ORBIT_USE_SYSTEM_CONFIGURATION")},Cy=(e,t)=>{if(e==="win32"){let a="--fleet-url ",s=t.indexOf(a);if(s<0)return;let i=t.slice(s+a.length),c;if(i.startsWith('"')){let d=i.indexOf('"',1);if(d<0)return;c=i.slice(1,d)}else{let d=i.indexOf(" ");c=d<0?i:i.slice(0,d)}let l=c.trim();return l.length>0?l:void 0}if(e==="darwin"){let a=t.indexOf("<key>ORBIT_FLEET_URL</key>");if(a<0)return;let s=t.indexOf("<string>",a),i=t.indexOf("</string>",s);return s<0||i<0?void 0:t.slice(s+8,i).replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&").trim()}let n='Environment="ORBIT_FLEET_URL=',r=t.indexOf(n);if(r<0)return;let o=t.indexOf('"',r+n.length);return o<0?void 0:t.slice(r+n.length,o).trim()},Vx=e=>{let t=e(ky,["qc",Qd,"8192"]);return t.status===0?t.stdout:""},vy=e=>{let t=e(Ay,UV(Qd)),n=t.status===0?t.stdout.trim():"";return n.length>0?n:"absent"},JV=async e=>{try{return e==="win32"?Cy(e,Vx(Fi)):Cy(e,await eu(e==="darwin"?Na:qd,"utf8"))}catch{return}},zV=async e=>{try{if(e==="win32")return await Sy(Gx)&&Cy(e,Vx(Fi))!==void 0;let n=await eu(e==="darwin"?Na:qd,"utf8");return e==="darwin"?ZV(n):XV(n)}catch{return!1}},Yx=async(e,t={})=>{let n=t.exists??Sy,r=t.command??Fi,o,a="absent";if(e==="win32")a=vy(r),o=await n($V)&&a!=="absent";else{let l=e==="darwin"?await n(Na):await n("/etc/systemd/system/orbit.service")||await n("/usr/lib/systemd/system/orbit.service");o=await n(NV)&&l}let s=await(t.configured??zV)(e),i=await(t.hasNodeKey??(()=>VV(YV(e))))(),c=!1;if(o)if(e==="darwin"){let l=r("/bin/launchctl",["print","system/com.fleetdm.orbit"]);c=l.status===0&&/\bstate\s*=\s*running\b/.test(l.stdout)}else e==="linux"?c=r("systemctl",["is-active","--quiet","orbit"]).status===0:c=a==="Running";return{installed:o,configured:s,running:c,checkedIn:i}},qV=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),Zx=(e,t)=>{let n=Ey(e,t);if(!n)return null;let r=n.start;for(;r>0&&(e[r-1]===" "||e[r-1]===" ");)r--;r>0&&e[r-1]===`
|
|
765
|
+
`&&r--;let o=n.end;for(;o<e.length&&/\s/.test(e[o]);)o++;if(e.startsWith("<string>",o)){let a=e.indexOf("</string>",o);return a<0?null:{start:r,end:a+9}}if(e.startsWith("<true",o)||e.startsWith("<false",o)){let a=e.indexOf("/>",o);return a<0?null:{start:r,end:a+2}}return null},QV=(e,t)=>{let n=Zx(e,t);return n===null?e:e.slice(0,n.start)+e.slice(n.end)},_x=(e,t,n)=>{let r=`
|
|
766
766
|
<key>${t}</key>
|
|
767
|
-
<string>${
|
|
767
|
+
<string>${qV(n)}</string>`,o=Zx(e,t);if(o!==null)return e.slice(0,o.start)+r+e.slice(o.end);let a=Ey(e,"EnvironmentVariables"),s=a===null?-1:e.indexOf("<dict>",a.end);if(a===null||s<0)throw new se("The installed Orbit LaunchDaemon has no EnvironmentVariables dictionary; it was left unchanged.");let i=s+6;return e.slice(0,i)+r+e.slice(i)},eY=(e,t,n=$i)=>{let r=QV(e,"ORBIT_USE_SYSTEM_CONFIGURATION");return r=_x(r,"ORBIT_FLEET_URL",t),_x(r,"ORBIT_ENROLL_SECRET_PATH",n)},tY=(e,t,n=$i)=>{let r=new Set(["ORBIT_FLEET_URL","ORBIT_ENROLL_SECRET","ORBIT_ENROLL_SECRET_PATH","ORBIT_USE_SYSTEM_CONFIGURATION"]);return`${e.split(`
|
|
768
768
|
`).filter(a=>{let s=a.indexOf("=");return s<0?!0:!r.has(a.slice(0,s).trim())}).filter((a,s,i)=>a.trim()!==""||i[s-1]?.trim()!=="").join(`
|
|
769
769
|
`).trimEnd()}
|
|
770
770
|
|
|
@@ -774,13 +774,13 @@ available; on Windows, run it from a shell started as Administrator.`,jx=e=>!!(e
|
|
|
774
774
|
# file, never in this world-readable one.
|
|
775
775
|
ORBIT_FLEET_URL=${t}
|
|
776
776
|
ORBIT_ENROLL_SECRET_PATH=${n}
|
|
777
|
-
`},Xx=e=>{if(/[\u0000-\u0020\u007f]/.test(e)||/["'`\\^<>|{}]/.test(e))return!1;try{let t=new URL(e);return t.username||t.password?!1:t.protocol==="https:"?!0:t.protocol==="http:"&&(t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="::1")}catch{return!1}},
|
|
777
|
+
`},Xx=e=>{if(/[\u0000-\u0020\u007f]/.test(e)||/["'`\\^<>|{}]/.test(e))return!1;try{let t=new URL(e);return t.username||t.password?!1:t.protocol==="https:"?!0:t.protocol==="http:"&&(t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="::1")}catch{return!1}},nY=$e.object({code:$e.string().min(1).optional(),message:$e.string().min(1).optional()}).passthrough(),Px=e=>{let t=e.replace(/[\u0000-\u001f\u007f-\u009f]/g," ").replace(/ {2,}/g," ").trim();return t.length>300?`${t.slice(0,299)}\u2026`:t},rY=(e,t)=>{let n=`The gateway rejected endpoint enrollment (${e}).`,r=nY.safeParse(t);if(!r.success)return n;let o=Px(r.data.message??""),a=Px(r.data.code??"");return o?a?`${n} ${o} [${a}]`:`${n} ${o}`:a?`${n} [${a}]`:n},Tx=async(e,t,n={})=>{let r=new AbortController,o=setTimeout(()=>r.abort(),n.timeoutMs??PV),a;try{a=await(n.fetchResponse??fetch)(`${e}/connect/endpoint-enrollment`,{method:"POST",headers:{"content-type":"application/json","x-anyray-api-key":t,"x-anyray-connect-version":ke},body:"{}",signal:r.signal})}catch{throw new se("Could not reach the gateway for endpoint enrollment.")}finally{clearTimeout(o)}if(!a.ok){if(a.status===404)throw new se("This gateway does not provide endpoint enrollment yet.");let c;try{c=await a.json()}catch{c=void 0}throw new se(rY(a.status,c))}let s;try{s=await a.json()}catch{throw new se("The gateway returned malformed endpoint enrollment data.")}let i=$e.object({fleetUrl:$e.string().min(1).max(2048),enrollSecret:$e.string().min(1).max(4096)}).strict().safeParse(s);if(!i.success||!Xx(i.data.fleetUrl))throw new se("The gateway returned invalid endpoint enrollment data.");return i.data},oY=async(e={})=>{let t=e.exists??Sy;if(await t("/usr/bin/dpkg")||await t("/bin/dpkg"))return"deb";if(await t("/usr/bin/rpm")||await t("/bin/rpm"))return"rpm";throw new se("Linux endpoint installation requires either dpkg or rpm.")},aY=async e=>e==="darwin"?"pkg":e==="win32"?"msi":oY(),xy=e=>`fleetd.${e}`,sY=(e,t)=>e==="darwin"?t==="pkg":e==="win32"?t==="msi":t==="deb"||t==="rpm",iY=async(e,t)=>{let n=new AbortController,r=setTimeout(()=>n.abort(),_V);try{return await t(e,{signal:n.signal})}finally{clearTimeout(r)}},cY=async(e,t={})=>{let n=xy(e),r=t.fetchResponse??fetch,o;try{o=await iY(`${xx}/SHA256SUMS`,r)}catch{throw new se("Could not read the endpoint package checksums from GitHub.")}if(o.status===404)return;if(!o.ok)throw new se(`GitHub could not provide the endpoint package checksums (${o.status}).`);let a=Wm(await o.text(),n);if(!a)return;let s=t.makeTempDir?await t.makeTempDir():await Bx(zd(xV(),"anyray-endpoint-")),i=zd(s,n);try{await by(s,448),await(t.download??jm)(`${xx}/${n}`,i,a)}catch(c){if(await Rr(s,{recursive:!0,force:!0}).catch(()=>{}),c instanceof xi&&c.status===404)return;throw new se("The endpoint package download or checksum verification failed.")}return{kind:e,path:i,sha256:a,cleanup:()=>Rr(s,{recursive:!0,force:!0})}},lY=async(e,t,n)=>{await CV(IV(e),{recursive:!0,mode:493});let r=`${e}.anyray-${process.pid}`;await Rr(r,{force:!0});try{await EV(r,t,{encoding:"utf8",mode:n,flag:"wx"}),await vV(r,e)}catch(o){throw await Rr(r,{force:!0}).catch(()=>{}),o}},Lx=async e=>{let t=bV("sha256");for await(let n of wV(e))t.update(n);return t.digest("hex")},dY=async(e,t={})=>{let n=await AV(e.path).catch(()=>{});if(!n?.isFile()||n.isSymbolicLink())throw new se("The verified endpoint package staging file is no longer available.");if(e.kind==="msi"){if(await Lx(e.path)!==e.sha256)throw new se("The endpoint package changed after verification; installation was refused.");return{package:e,cleanup:async()=>{}}}let r=t.makeTempDir?await t.makeTempDir():await Bx(zd(DV,"anyray-endpoint-root-")),o=zd(r,xy(e.kind));try{if(await by(r,448),await kV(e.path,o),await by(o,384),await Lx(o)!==e.sha256)throw new se("The endpoint package changed after verification; installation was refused.");return{package:{...e,path:o},cleanup:()=>Rr(r,{recursive:!0,force:!0})}}catch(a){throw await Rr(r,{recursive:!0,force:!0}).catch(()=>{}),a}},Da=(e,t)=>{if(e.status!==0)throw new se(t)},Dx="com.fleetdm.fleetd.config",uY="com.fleetdm.fleetd.enroll.secret",pY=["/opt/orbit/secret.txt","/opt/orbit/fleet_url.txt",Wx],fY=[MV,Kx],hY=e=>{let t=e("/usr/bin/profiles",["show","-type","configuration"]);if(t.status===0&&t.stdout.includes(Dx))throw new se(`This machine already receives its endpoint configuration from an MDM profile (${Dx}), which takes precedence over anything installed here. Enrollment is managed by that profile; remove it first if this machine should enroll directly.`)},Nx=async(e,t,n)=>{let r=n.removeFile??(o=>Rr(o,{force:!0}));for(let o of e==="win32"?fY:pY)await r(o).catch(()=>{});e==="darwin"&&t("/usr/bin/security",["delete-generic-password","-s",uY,"/Library/Keychains/System.keychain"])},mY=e=>{e(Jd,[Ni,"/inheritance:r"]),e(Jd,[Ni,"/grant:r","*S-1-5-18:(F)"]),e(Jd,[Ni,"/grant:r","*S-1-5-32-544:(F)"]),e(Jd,[Ni,"/remove:g","*S-1-5-32-545"])},yY=(e,t,n)=>{if(e.kind==="pkg"){Da(t("/usr/sbin/installer",["-pkg",e.path,"-target","/"]),"The macOS endpoint package installer failed.");return}if(e.kind==="deb"){Da(t("dpkg",["-i",e.path]),"The Debian endpoint package installer failed.");return}if(e.kind==="rpm"){Da(t("rpm",["-U",e.path]),"The RPM endpoint package installer failed.");return}Da(t(BV,["/i",e.path,"/qn","/norestart",`FLEET_URL=${n}`,"ENABLE_SCRIPTS=true"]),"The Windows endpoint package installer failed.")},gY=(e,t)=>{if(e==="darwin"){t("/bin/launchctl",["bootout","system/com.fleetdm.orbit"]);let n;for(let r=0;r<gy;r++){if(n=t("/bin/launchctl",["bootstrap","system",Na]),n.status===0)return;t("/bin/sleep",[LV])}throw new se(`Orbit was configured, but launchd could not load the updated service definition${n?.stdout.trim()?`: ${n.stdout.trim()}`:""}.`)}if(e==="win32"){t(ky,["stop",Qd]);for(let n=0;n<gy;n++){let r=vy(t);if(r==="Stopped"||r==="absent")break;t(Ay,Ox)}for(let n=0;n<gy;n++){if(t(ky,["start",Qd]).status===0||vy(t)==="Running")return;t(Ay,Ox)}throw new se("Orbit was configured, but the Windows service could not be started.")}Da(t("systemctl",["daemon-reload"]),"Orbit was configured, but systemd could not reload its units."),Da(t("systemctl",["restart","orbit"]),"Orbit was configured, but systemd could not restart it.")},wY=e=>new Promise(t=>setTimeout(t,e)),Jx=async(e,t={})=>{let n=t.command??Fi,r=t.readText??(c=>eu(c,"utf8")),o=t.writeText??lY,a=t.removeSecret??(()=>Rr(Rx(e.os),{force:!0})),s=!1,i;try{if(e.action==="configure"){if(e.os==="darwin"&&hY(n),e.package&&!sY(e.os,e.package.kind))throw new se("The endpoint package does not match this operating system.");if(e.os==="win32"&&!e.package)throw new se("Reconfiguring the Windows endpoint agent requires the installer package.");if(e.os==="win32"&&await Nx(e.os,n,t),e.package){let d=await(t.preparePackage??dY)(e.package);i=d.cleanup,yY(d.package,n,e.fleetUrl)}if(e.os==="darwin"){let d=await r(Na);await o(Na,eY(d,e.fleetUrl),420)}else if(e.os==="linux"){let d=await r(qd);await o(qd,tY(d,e.fleetUrl),420)}else await o(Gx,`anyray
|
|
778
778
|
`,384);e.os!=="win32"&&await Nx(e.os,n,t),await o(Rx(e.os),`${e.enrollSecret}
|
|
779
|
-
`,384),e.os==="win32"&&
|
|
780
|
-
anyray-connect endpoint install`),"deferred");if((t.uid??(()=>process.getuid?.()??-1))()===0)return await e(),"direct";if(await(t.ttyReadable??
|
|
781
|
-
sudo anyray-connect endpoint install`),"deferred"},
|
|
782
|
-
`;if(Buffer.byteLength(t)>Hx)throw new se("The privileged endpoint plan is unexpectedly large.");let n=cn(["__anyray-endpoint-install"]);return Mx("sudo",[n.command,...n.args],{input:t,stdio:["pipe","inherit","inherit"],encoding:"utf8"}).status??1},
|
|
783
|
-
`).find(i=>i.split(":")[0]===e)?.split(":")[5];s?.startsWith("/")&&(t=s)}catch{}t??=tu()==="darwin"?`/Users/${e}`:`/home/${e}`;let n=process.env.HOME,r=process.env.USERPROFILE;process.env.HOME=t,process.env.USERPROFILE=t;try{return await P()}finally{n===void 0?delete process.env.HOME:process.env.HOME=n,r===void 0?delete process.env.USERPROFILE:process.env.USERPROFILE=r}},zx=async(e={},t={})=>{let n=t.os??tu();if(n!=="darwin"&&n!=="linux"&&n!=="win32")throw new se("`anyray-connect endpoint install` supports macOS, Linux and Windows only.");let r=n,o=await(t.probe??Yx)(r),a=!1;if(o.installed&&o.configured&&o.running&&o.checkedIn){let c=e.gateway&&e.clientKey?void 0:await(t.profile??$x)(),l=e.gateway??c?.gateway,d=e.clientKey??c?.clientKey,u=await(t.readFleetUrl??
|
|
779
|
+
`,384),e.os==="win32"&&mY(n),s=e.os!=="win32"}gY(e.os,n);let c=t.checkIn??(async d=>{let u=await Yx(d);return u.running&&u.checkedIn}),l=t.wait??wY;for(let d=0;d<(t.attempts??Ix);d++){if(await c(e.os))return;d+1<(t.attempts??Ix)&&await l(TV)}throw new se("The endpoint agent did not check in after restart. The package command succeeded, but enrollment was not confirmed.")}finally{s&&await a().catch(()=>{}),await i?.().catch(()=>{})}},bY=async()=>{try{return await Fx("/dev/tty",Ux.R_OK),!0}catch{return!1}},kY=12288,AY=e=>{let t=e(FV,["/groups"]);if(t.status!==0)return!1;let n=-1;for(let r=0;;){let o=t.stdout.indexOf("S-1-16-",r);if(o<0)break;r=o+7;let a=r;for(;a<t.stdout.length&&t.stdout[a]>="0"&&t.stdout[a]<="9";)a++;a>r&&(n=Math.max(n,Number(t.stdout.slice(r,a)))),r=a}return n>=kY},CY=async(e,t={})=>{if((t.os??tu())==="win32")return(t.elevated??(()=>AY(t.command??Fi)))()?(await e(),"direct"):((t.print??k)(`Administrator access is required. Open Windows Terminal or PowerShell as Administrator and run:
|
|
780
|
+
anyray-connect endpoint install`),"deferred");if((t.uid??(()=>process.getuid?.()??-1))()===0)return await e(),"direct";if(await(t.ttyReadable??bY)()){if(await(t.reexec??(async()=>1))()!==0)throw new se("Administrator access did not complete; the endpoint agent was not enrolled.");return"sudo"}return(t.print??k)(`Administrator access is required. Run:
|
|
781
|
+
sudo anyray-connect endpoint install`),"deferred"},vY=async e=>{let t=`${JSON.stringify(e)}
|
|
782
|
+
`;if(Buffer.byteLength(t)>Hx)throw new se("The privileged endpoint plan is unexpectedly large.");let n=cn(["__anyray-endpoint-install"]);return Mx("sudo",[n.command,...n.args],{input:t,stdio:["pipe","inherit","inherit"],encoding:"utf8"}).status??1},SY=async(e,t={})=>(t.withRoot??CY)(()=>(t.apply??Jx)(e),{...t.root,reexec:()=>(t.sudo??vY)(e)}),$x=async()=>{if((process.getuid?.()??-1)!==0||!process.env.SUDO_USER)return P();let e=process.env.SUDO_USER;if(!/^[A-Za-z0-9._-]{1,64}$/.test(e))return P();let t;try{let s=(await eu("/etc/passwd","utf8")).split(`
|
|
783
|
+
`).find(i=>i.split(":")[0]===e)?.split(":")[5];s?.startsWith("/")&&(t=s)}catch{}t??=tu()==="darwin"?`/Users/${e}`:`/home/${e}`;let n=process.env.HOME,r=process.env.USERPROFILE;process.env.HOME=t,process.env.USERPROFILE=t;try{return await P()}finally{n===void 0?delete process.env.HOME:process.env.HOME=n,r===void 0?delete process.env.USERPROFILE:process.env.USERPROFILE=r}},zx=async(e={},t={})=>{let n=t.os??tu();if(n!=="darwin"&&n!=="linux"&&n!=="win32")throw new se("`anyray-connect endpoint install` supports macOS, Linux and Windows only.");let r=n,o=await(t.probe??Yx)(r),a=!1;if(o.installed&&o.configured&&o.running&&o.checkedIn){let c=e.gateway&&e.clientKey?void 0:await(t.profile??$x)(),l=e.gateway??c?.gateway,d=e.clientKey??c?.clientKey,u=await(t.readFleetUrl??JV)(r);if(!l||!d||u===void 0)return{outcome:"already-enrolled",message:"Endpoint agent already running and enrolled; nothing to do."};let f=await(t.fetchEnrollment??Tx)(l,d);if(u===f.fleetUrl)return{outcome:"already-enrolled",message:"Endpoint agent already running and enrolled; nothing to do."};F("This machine points at a different Anyray endpoint server; re-pointing it."),a=!0}if(o.installed&&o.checkedIn&&!o.configured)throw new se("This machine is already enrolled in a different Fleet configuration; it was left unchanged.");let s,i;if(o.installed&&o.configured&&o.checkedIn&&!a)s={action:"restart",os:r};else{let c=e.gateway&&e.clientKey?void 0:await(t.profile??$x)(),l=e.gateway??c?.gateway,d=e.clientKey??c?.clientKey;if(!l||!d)throw new se("No enrolled seat key is available. Run anyray-connect with --sso first, then retry endpoint install.");let u=await(t.fetchEnrollment??Tx)(l.replace(/\/$/,""),d);if(!o.installed||r==="win32"){let f=await(t.packageKind??(()=>aY(r)))();if(i=await(t.stagePackage??cY)(f),!i)return{outcome:"release-unavailable",message:`Endpoint agent package ${xy(f)} is not published yet; skipping.`}}s={action:"configure",os:r,...u,...i?{package:{kind:i.kind,path:i.path,sha256:i.sha256}}:{}}}try{return await(t.execute??SY)(s)==="deferred"?{outcome:"needs-root"}:{outcome:"installed",message:"Endpoint agent is running and enrolled."}}finally{await i?.cleanup().catch(()=>{})}},Iy=e=>e instanceof se?e.publicMessage:"Endpoint agent installation failed locally; no enrollment was confirmed.",qx=async e=>{if(e.length===1&&(e[0]==="--help"||e[0]==="-h"))return k(HV),0;if(e.length!==1||e[0]!=="install")return _("Usage: anyray-connect endpoint install"),1;try{let t=await zx();return t.message&&(t.outcome==="installed"?$(t.message):F(t.message)),0}catch(t){return _(Iy(t)),1}},EY=async()=>{let e=[],t=0;for await(let o of process.stdin){let a=Buffer.isBuffer(o)?o:Buffer.from(o);if(t+=a.length,t>Hx)throw new se("The privileged endpoint plan is unexpectedly large.");e.push(a)}let n;try{n=JSON.parse(Buffer.concat(e).toString("utf8"))}catch{throw new se("The privileged endpoint plan is malformed.")}let r=jV.safeParse(n);if(!r.success||r.data.os!==tu()||r.data.action==="configure"&&!Xx(r.data.fleetUrl))throw new se("The privileged endpoint plan is invalid.");return r.data},Qx=async e=>{if((process.getuid?.()??-1)!==0)return _("The privileged endpoint step must run as root."),1;if(e.length!==0)return _("The privileged endpoint step does not accept arguments."),1;try{return await Jx(await EY()),0}catch(t){return _(Iy(t)),1}},eI=async(e,t=zx)=>{try{let n=await t(e);n.message&&(n.outcome==="installed"?$(n.message):F(n.message))}catch(n){F(`Endpoint agent: ${Iy(n)} Tool routing remains configured.`)}};import{execSync as Oy}from"node:child_process";import{hostname as xY}from"node:os";var IY=e=>{try{if(e==="darwin"){let t=Oy("ioreg -rd1 -c IOPlatformExpertDevice",{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return/"IOPlatformUUID"\s*=\s*"([^"]+)"/.exec(t)?.[1]??""}if(e==="win32"){let t=Oy('reg query "HKLM\\SOFTWARE\\Microsoft\\Cryptography" /v MachineGuid',{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return/MachineGuid\s+REG_SZ\s+([\w-]+)/.exec(t)?.[1]??""}return Oy("cat /etc/machine-id 2>/dev/null || cat /var/lib/dbus/machine-id 2>/dev/null",{encoding:"utf8",stdio:["ignore","pipe","ignore"]})}catch{return""}},nu=(e={platform:process.platform,read:()=>IY(process.platform),hostname:xY})=>e.read().trim()||e.hostname().trim();var OY=(e,t=Date.now())=>e.credentialProtocol==="stable-heartbeat-v1"||!hd(e,void 0,t),tI=async(e,t={})=>{if(!await(t.fleetdPresent??La)())return{retired:!1,reason:"no-fleetd",messages:[]};if(!OY(e,t.now??Date.now()))return{retired:!1,reason:"seat-could-lapse",messages:[]};let r=[],o=await(t.uninstallScheduler??or)();r.push(...o.messages);let a=await(t.uninstallProxy??Zt)();return r.push(...a.messages),{retired:!0,messages:r}};var nI=(e={})=>{let t=(e.envUuid??process.env.ANYRAY_MACHINE_UUID??"").trim();return t?t.toLowerCase():(e.platform??process.platform)==="darwin"?(e.readMacUuid??(()=>nu()))().trim().toLowerCase():""};var rI=["reapply_config","remint","revert","revert_tool"],RY=/^[a-z0-9][a-z0-9-]{0,31}$/;var _Y=e=>{if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.id!="string"||t.id.length===0||typeof t.kind!="string"||!rI.includes(t.kind)?!1:t.kind==="revert_tool"?typeof t.tool=="string"&&RY.test(t.tool):t.tool===void 0},Ry=e=>e?.name??"error",oI=async(e,t,n)=>{let r=n.fetchImpl??fetch,o=e.replace(/\/$/,""),a;try{let i=await r(`${o}/connect/directive`,{method:"GET",headers:{"x-anyray-api-key":t,"x-anyray-directive-kinds":rI.join(",")},signal:AbortSignal.timeout(1e4)});if(i.status===404||!i.ok)return null;let c=await i.json();if(!_Y(c.directive))return null;a=c.directive}catch(i){return console.error("connect directive pull skipped:",Ry(i)),null}let s;try{s=await n.execute(a.kind,a.tool)}catch(i){console.error("connect directive execution failed:",Ry(i)),s="failed"}try{await r(`${o}/connect/directive/ack`,{method:"POST",headers:{"x-anyray-api-key":t,"content-type":"application/json"},body:JSON.stringify({id:a.id,result:s}),signal:AbortSignal.timeout(1e4)})}catch(i){console.error("connect directive ack skipped:",Ry(i))}return a.kind};var PY=1e4,$a=e=>e?.name??"Error",_y=async(e,t=fetch)=>{let n=e.gateway?.replace(/\/+$/,""),r=e.clientKey;if(!(!n||!r))try{await t(`${n}/connect/offboard`,{method:"POST",headers:{"x-anyray-api-key":r},signal:AbortSignal.timeout(PY)})}catch(o){console.error(`anyray seat offboard report: ${$a(o)}`)}},TY=e=>e==="reverted"||e==="queued",aI=async(e={})=>{let t=e.loadProfile??P,n=e.clearDeviceTokenState??bd,r=e.reportSeatOffboarded??_y,o=e.clearEnrollment??ji,a=e.recordManagedTools??Vn,s=e.markSeatOffboarded??Yi,i=e.adapterById??Bt,c=e.uninstallProxy??Zt,l=e.uninstallScheduler??or,d=e.unitsPresent??bi,u=e.saveProfile??te,f=await t(),p=f.managedTools??[];await r(f).catch(()=>{}),await n().catch(()=>{});let h=!1,m=!1;try{h=await o()}catch(E){m=!0,console.error(`anyray offboard: clearing enrollment: ${$a(E)}`)}let w=[],g=[],y=[];for(let E of p){let x=i(E);if(!x){y.push(E);continue}try{let A=await x.revert({dryRun:!1,fullRevert:!0});w.push({id:E,status:A.status}),TY(A.status)?g.push(E):y.push(E)}catch(A){console.error(`anyray offboard: reverting ${E}: ${$a(A)}`),y.push(E)}}let b=!0;try{await a(w,!0,!0)}catch(E){b=!1,console.error(`anyray offboard: recording managed tools: ${$a(E)}`)}let C=y.length===0&&b,S=!1;if(C)try{await s(),S=!0}catch(E){console.error(`anyray offboard: stamping offboard: ${$a(E)}`)}try{let E=await t();(E.fallbackPort||await d("daemon"))&&await c(E.fallbackPort),(E.refreshSchedulerEnabled||await d("scheduler"))&&await l(),await u({...await t(),keyRefreshEnabled:!1,fallbackPort:void 0,refreshSchedulerEnabled:!1})}catch(E){console.error(`anyray offboard: unit teardown: ${$a(E)}`)}return{reverted:g,unresolved:y,enrollmentCleared:h,credentialHeld:m,recordPersisted:b,offboardMarked:S,ok:y.length===0&&!m&&b&&S}};var sI=e=>e?.name??"Error",iI=async(e,t={})=>{if(!e)return"failed";let n=t.loadProfile??P,r=t.recordManagedTools??Vn,o=t.adapterById??Bt,a=t.isLocked??ci,s=await n().catch(()=>{});if(!s)return"failed";if(!(s.managedTools??[]).includes(e))return"ok";if(a(s,e))return console.error(`anyray revert-tool: ${e} is locked by fleet policy`),"failed";let i=o(e);if(!i)return"failed";let c;try{c=(await i.revert({dryRun:!1,fullRevert:!1})).status}catch(l){return console.error(`anyray revert-tool: reverting ${e}: ${sI(l)}`),"failed"}try{await r([{id:e,status:c}],!0,!1)}catch(l){return console.error(`anyray revert-tool: recording ${e}: ${sI(l)}`),"failed"}return c==="reverted"||c==="queued"?"ok":"failed"};import{platform as DY}from"node:os";var dI=`${j("anyray-connect")} \u2014 point your local coding tools at the Anyray gateway
|
|
784
784
|
|
|
785
785
|
${j("Usage")}
|
|
786
786
|
npx anyray-connect [options]
|
|
@@ -1002,20 +1002,20 @@ ${j("What it does")}
|
|
|
1002
1002
|
key stays server-side (ANYRAY_PROVIDER_KEY_*); your tools never hold it. Only
|
|
1003
1003
|
metadata (user/team) is attached \u2014 never prompt content.
|
|
1004
1004
|
~/.anyray (mode 600) remembers your gateway, name/team, personal key, and the
|
|
1005
|
-
per-skill versions ${v("sync")} last wrote \u2014 for zero-question re-runs.`,
|
|
1006
|
-
${e.length===1?`${e[0]} is open and won't pick this up until it restarts. Quit it now?`:`${e.slice(0,-1).join(", ")} and ${e[e.length-1]} are open and won't pick this up until they restart. Quit them now?`}`,
|
|
1007
|
-
${o} ${n} tool target(s)?`;return await(r.confirm??Ea)(a)?"proceed":"declined"},oZ=async e=>{if(e[0]==="__anyray-hook"){let n=e[1]==="cursor"||e[1]==="opencode"?e[1]:"claude";return J0(n)}if(e[0]==="__anyray-codex-hook")return z0();if(e[0]==="__anyray-prompt-hook")return q0();if(e[0]==="__anyray-shell-pretool")return nx();if(e[0]==="__anyray-shell-run")return tx(e.slice(1));if(e[0]==="__anyray-read-pretool")return dx();if(e[0]==="__anyray-sso-gate")return kS(e.slice(1));if(e[0]==="__anyray-sso-poll")return ux();if(e[0]==="__anyray-vscode-gate")return gx();if(e[0]==="__anyray-spawn-refresh")return await Cr(),0;if(e[0]==="__anyray-mcp-server"){let n=e[1]==="claude"||e[1]==="profile"?e[1]:"auto";return Sx(n)}if(e[0]==="__anyray-acp-agent")return Ex(e[1],e[2],{clientTool:e[3]});if(e[0]==="__anyray-endpoint-install")return Qx(e.slice(1));if(e[0]==="__anyray-refresh"){await Vm(),await Qe({runAmbientSelfcheck:!0}),await sm(),await JY(),await iS(),await cS();let n=await P().catch(()=>{});if(n){process.env.ANYRAY_FLEET_MANAGED==="1"&&!n.anyrayFleetManaged&&(n.anyrayFleetManaged=!0,await te(n).catch(()=>{}));let r=n.anyrayFleetManaged===!0&&await La().catch(()=>!1);if(await tI(n,{fleetdPresent:async()=>r}).catch(()=>{}),r&&n.gateway&&n.clientKey){let o=n.gateway,a=n.clientKey,s=nI(),i=n.enrolledCert;if(s&&i){let l=await Me().catch(()=>{});l&&await bv(o,a,i,l,s).catch(()=>{})}await oI(o,a,{execute:async(l,d)=>l==="remint"||l==="reapply_config"?await Qe({force:!0})==="failed"?"failed":"ok":l==="revert_tool"?iI(d):(await aI()).ok?"ok":"failed"}).catch(()=>{})}}return await Ii(),0}if(e[0]==="__anyray-fallback-proxy")return FS();if(e[0]==="__anyray-persistence")return US(e.slice(1));if(e[0]==="__anyray-quit-watch")return YS(e.slice(1));if(e[0]===js)return IE(e.slice(1));if(e[0]==="--version"||e[0]==="-V")return yx();try{let n=await cg(e);if(n!==void 0)return n}catch(n){return _(`Could not persist anyray-connect for long-lived integrations: ${n instanceof Error?n.message:String(n)}`),1}if(nZ(e)){let n=tZ(await m0());n?.level==="warn"?N(n.message):n&&console.error(n.message)}if(e[0]==="managed")return oE(e.slice(1));if(e[0]==="endpoint")return qx(e.slice(1));if(e[0]==="print-key")return cE(e.slice(1));if(e[0]==="models")return dE(e.slice(1));if(e[0]==="copilot-login")return uE(e.slice(1));if(e[0]==="desktop"){let n=e.slice(1),r=_m(n);return r?Py(r,!1):HE(n)}if(e[0]==="retrieve")return KE(e.slice(1));if(e[0]==="recall")return GE(e.slice(1));if(e[0]==="history")return n0(e.slice(1));if(e[0]==="migrate")return o0(e.slice(1));if(e[0]==="login")return fx(e.slice(1));if(e[0]==="update")return mx(e.slice(1));let t=e[0];if(t&&QY.has(t)){let n=e.slice(1),r;try{r=pI(n)}catch(o){return _(o.message),k("\nRun `npx anyray-connect --help` for usage."),1}return r.help?(k(r.helpAll?uI:dI),0):t==="status"?b0({gateway:r.gateway}):t==="doctor"?S0({gateway:r.gateway,json:r.json,verify:r.verify,noVerify:r.noVerify,quick:r.quick,repair:r.repair,securityReview:r.securityReview}):t==="sync"?E0({gateway:r.gateway}):t==="device-url"?pE():Py(n,!0)}return Py(e,!1)},fI=async e=>{try{return await oZ(e)}catch(t){if(t instanceof bt)return console.error(v("Cancelled.")),130;throw t}},aZ=async(e,t,n={})=>{let r=n.isInteractive??Kt,o;try{o=pI(e)}catch(L){return _(L.message),k("\nRun `npx anyray-connect --help` for usage."),1}if(o.help)return k(o.helpAll?uI:dI),0;if(o.revert&&(o.sso||o.enroll))return _("--revert cannot be combined with --sso or --enroll. It removes Anyray configuration; re-run with --sso <link> --yes (without --revert) to configure a new CLI."),1;if(o.project)return o.sso||o.enroll||o.subscription||o.upstream?(_("--project cannot be combined with --sso/--enroll (per-machine enrollment) or --subscription/--upstream (per-dev credential lanes). It writes an org-lane, credential-free repo config."),1):SE({gateway:o.gateway,tools:o.tools,revert:o.revert,dryRun:o.dryRun,yes:o.yes});if(!!o.upstream!=!!o.upstreamKey)return _("--upstream and --upstream-key go together: the URL says where your personal key is valid, the key is what the gateway forwards there."),1;if(o.upstream&&(o.subscription||o.placeholder))return _("--upstream cannot be combined with --subscription or --org: BYO passthrough sends your personal upstream key \u2014 not a seat OAuth token, and never the org's server-held key."),1;let a;if(o.upstream){let L;try{L=new URL(o.upstream.trim())}catch{return _(`invalid --upstream URL: "${o.upstream}"`),1}if(L.protocol!=="http:"&&L.protocol!=="https:")return _(`invalid --upstream URL: "${o.upstream}" \u2014 must start with http:// or https://`),1;let T=o.upstreamKey.trim();if(!T)return _("--upstream-key must not be empty."),1;a={url:Ye(o.upstream),key:T}}let s=await P();if(!o.revert&&!o.dryRun&&o.noKeyRefresh!==!0){let L=await Vm();(L==="migrated"||L==="already-direct")&&(s=await P())}!a&&!o.subscription&&!o.placeholder&&!o.revert&&(a=s.byoUpstream),o.retiredFallbackFlag&&N("--fallback/--no-fallback are retired and ignored: the local daemon no longer routes around the gateway to the provider. Seamless key refresh is on by default (--no-key-refresh opts out).");let i=!t&&Kt()&&!o.gateway&&!o.revert&&!o.yes&&!o.dryRun&&!o.enroll&&!o.sso,c=!1;(t||i)&&r()&&(o=await(n.runWizard??GY)(o,s),c=!0);let l;try{l=TY(o.tools)}catch(L){return _(L.message),1}k(j(o.revert?"Anyray connect \u2014 revert":"Anyray connect")),o.gateway&&!o.enroll&&Fd(o.gateway)&&(o.enroll=o.gateway,o.gateway=void 0,k("That looks like an enrollment link \u2014 treating it as --enroll."));let d,u,f=!1;if(o.enroll&&(!o.gateway||s.enrolledCert)){let L=Md(o.enroll);if(L)try{let T=await Bd("Resolving enrollment link\u2026",()=>a0(L)),K=!o.gateway;K&&(o.gateway=T.gatewayUrl),d=T.deploymentId,u=T.email,f=!0,K&&F(`Enrollment link${T.org?` for ${T.org}`:""}: gateway ${T.gatewayUrl}`),T.seatMode&&!o.subscription&&(o.subscription=!0,F("Subscription org: using pass-through auth (--subscription) \u2014 your own seat sign-in is used."))}catch(T){let K=o.gateway||process.env.ANYRAY_GATEWAY_URL?.trim()||s.gateway;if(K)F(`Could not resolve the gateway from the enrollment link \u2014 using ${K}.`);else return _(T instanceof Error?T.message:String(T)),1}}let p;if(o.sso&&!o.revert)if(o.dryRun)F("dry run: not enrolled via SSO (skipped minting a personal key).");else{let L=Ht(o.sso);if(!L)return _("invalid --sso value: expected a https://\u2026/sso/<tenantId> link or a tnt_ id."),1;try{let T=await Bd("Waiting for SSO sign-in\u2026",()=>uS({cpOrigin:L.cpOrigin,tenantId:L.tenantId,gatewayUrl:o.gateway,log:K=>F(K)}));p={cert:T.cert,privateKeyPem:T.privateKeyPem},T.deploymentId&&(d=T.deploymentId),!o.gateway&&T.gatewayUrl&&(o.gateway=T.gatewayUrl)}catch(T){return _(T instanceof Error?T.message:String(T)),1}}let h=!o.gateway&&!process.env.ANYRAY_GATEWAY_URL?s.gateway:void 0;h&&(o.gateway=h);let m;try{m=sn(o.gateway)}catch(L){return _(L.message),1}let w,g;h&&!o.revert&&F(`Gateway: ${m} ${v("(cached in ~/.anyray \u2014 pass a URL to change)")}`),!o.revert&&Ly(m)&&N(`${m} is plaintext http over a network \u2014 connections can be reset by firewalls/VPNs and traffic is unencrypted. Prefer an https:// gateway URL (front it with the TLS edge).`);let y=process.env.ANYRAY_CLIENT_KEY?.trim(),b=y||DY(s),C,S,E,x,A,I,R=s.credentialProtocol==="stable-heartbeat-v1",B=async L=>{await yo();let T=wv(L.token),K=kv(s.enrolledCert,s.enrolledCertExpiry,L.deploymentId,Date.now(),T,s.enrolledTokenHash,L.expectedUser),J=K?await Me():void 0,ge=K&&J&&s.enrolledCert?{cert:s.enrolledCert,privateKeyPem:J,publicKeyPem:s.enrolledCert.payload.devPublicKey}:void 0,z=be=>Av({cpOrigin:L.cpOrigin,token:L.token,gatewayOrigin:m,email:L.email,team:L.team,machineId:L.machineId,deploymentId:L.deploymentId,reuse:be?ge:void 0}),Ve=!!ge,we=await(async()=>{try{return await z(Ve)}catch(be){if(ge&&be instanceof It)return F("your saved certificate was rejected by the gateway (it may have been rebuilt) \u2014 re-enrolling from scratch\u2026"),Ve=!1,await z(!1);throw be}})();b=we.clientKey,o.user||=we.user,o.team||=we.team,C=we.cert,S=we.cert.payload.expiresAt,I=we.expiresAt,R=we.capabilities?.includes(li)===!0,A=void 0,Ve||(E=we.privateKeyPem),Ve||(x=T),$(`Enrolled${we.user?` as ${we.user}`:""}${Ve?" (reused your saved cert)":""} \u2014 personal gateway key minted (not shown; it lands in your tool configs).`)};if(o.enroll&&!o.revert)if(o.dryRun)F("dry run: not enrolled (skipped minting a personal key).");else{let L=Md(o.enroll);if(!L)return _("invalid --enroll value: expected a https://\u2026/enroll/<token> link or a bare token."),1;try{let T=o.machine?nu():void 0,K=u??PY(o.user),J=o.machine?`machine:${T}`:f?K:void 0;await B({cpOrigin:L.cpOrigin,token:L.token,email:K,team:o.team,machineId:T,deploymentId:d,expectedUser:J})}catch(T){return _(T instanceof Error?T.message:String(T)),T instanceof It&&F("The gateway rejected this enrollment. Ask your admin to confirm the gateway is connected and entitled, and that your link targets the right gateway \u2014 the exact reason is in the gateway logs."),1}}if(p){await yo();try{let L=await rn(m,p.cert,p.privateKeyPem);b=L.key,o.user||=L.user,o.team||=L.team,C=p.cert,S=p.cert.payload.expiresAt,E=p.privateKeyPem,I=L.expiresAt,R=L.capabilities?.includes(li)===!0;let T=Ht(o.sso);A=T?`${T.cpOrigin}/sso/${T.tenantId}`:void 0,$(`Enrolled${L.user?` as ${L.user}`:""} via SSO \u2014 personal gateway key minted (not shown; it lands in your tool configs).`)}catch(L){return _(L instanceof Error?L.message:String(L)),L instanceof It&&F("The gateway rejected your SSO sign-in. Ask your admin to confirm the gateway is connected and entitled \u2014 the exact reason is in the gateway logs."),1}}if(!o.revert){let L=o.yes;w=await gE(o.user,s.name,L),g=await wE(o.team,s.team,L)}let V;!o.revert&&!o.subscription&&!o.placeholder&&(V=await Tt(),W("Detecting your sign-ins"),k(` Claude (Anthropic): ${a?et("BYO upstream key (passthrough)"):V.anthropic?et("signed in \u2192 your subscription"):v("not signed in \u2192 org key")}`),k(` Codex (ChatGPT): ${V.openai?et("signed in \u2192 your subscription"):v("not signed in \u2192 org key")}`),!V.anthropic&&!V.openai&&!V.copilot&&qa()&&(N(" No subscription sign-ins found on this host. Sign-ins do not cross the"),N(" Remote-SSH hop \u2014 your laptop's are invisible here, and these tools run"),N(" HERE. Sign in on this machine (`copilot` \u2192 /login, Claude Code, Codex)"),N(" and re-run, or everything below routes on the org key instead.")));let H=me({origin:m,placeholderKey:o.key,clientKey:b,subscription:o.subscription,placeholder:o.placeholder,byoUpstream:a,seat:V,user:w,team:g,intent:o.intent,intentLabel:o.intentLabel,session:o.session}),X=o.revert===!0&&(o.tools?.length??0)===0,ie={dryRun:o.dryRun,fullRevert:X};if(!o.revert&&H.clientKey&&!Ie(H.clientKey))return _("Invalid personal gateway key: expected a minted ark_ credential. Re-run with --enroll/--sso, or set ANYRAY_CLIENT_KEY to a valid key."),1;if(!o.revert&&!H.clientKey){W("Enrollment required");let L="A real apply requires a personal ark_ gateway key. Run with --enroll <link> or --sso <link>, then re-run Connect.";return o.dryRun?(N(` ${L}`),F(" Dry run only \u2014 no placeholder configuration will be written."),await cI(l,"after-enrollment"),F(`
|
|
1008
|
-
Dry run complete \u2014 no files were written.`),0):(_(` ${L}`),1)}o.revert||
|
|
1009
|
-
Dry run \u2014 no files will be written.`);let ye=await
|
|
1005
|
+
per-skill versions ${v("sync")} last wrote \u2014 for zero-question re-runs.`,NY=e=>{let t=e?.trim();return t||mE()},pI=e=>{let t={subscription:!1,placeholder:!1,dryRun:!1,yes:!1,revert:!1,force:!1,skipVerify:!1,verbose:!1,help:!1,helpAll:!1};for(let n=0;n<e.length;n++){let r=e[n],o=()=>e[++n];switch(r){case"--gateway":t.gateway=o();break;case"--user":t.user=o();break;case"--team":t.team=o();break;case"--intent":t.intent=o();break;case"--intent-label":t.intentLabel=o();break;case"--session":t.session=o();break;case"--key":t.key=o();break;case"--enroll":t.enroll=o();break;case"--sso":t.sso=o();break;case"--machine":t.machine=!0;break;case"--subscription":t.subscription=!0;break;case"--placeholder":case"--org":t.placeholder=!0;break;case"--upstream":t.upstream=o();break;case"--upstream-key":t.upstreamKey=o();break;case"--tools":t.tools=(o()??"").split(",").map(a=>a.trim()).filter(Boolean);break;case"--project":t.project=!0;break;case"--dry-run":t.dryRun=!0;break;case"--yes":case"-y":t.yes=!0;break;case"--force":t.force=!0;break;case"--skip-verify":t.skipVerify=!0;break;case"--fallback":case"--no-fallback":t.retiredFallbackFlag=!0;break;case"--no-key-refresh":t.noKeyRefresh=!0;break;case"--quit-apps":t.quitApps=!0;break;case"--no-quit-apps":t.noQuitApps=!0;break;case"--endpoint":t.endpoint=!0;break;case"--no-endpoint":t.noEndpoint=!0;break;case"--revert":t.revert=!0;break;case"--json":t.json=!0;break;case"--verify":t.verify=!0;break;case"--no-verify":t.noVerify=!0;break;case"--quick":t.quick=!0;break;case"--repair":t.repair=!0;break;case"--security-review":t.securityReview=!0;break;case"--verbose":t.verbose=!0;break;case"--help":case"-h":t.help=!0;break;case"--help-all":t.help=!0,t.helpAll=!0;break;case"--all":if(!e.includes("--help")&&!e.includes("-h"))throw new Error(`unknown option: ${r}`);t.helpAll=!0;break;default:if(!r.startsWith("-")&&t.gateway===void 0)t.gateway=r;else throw new Error(r.startsWith("-")?`unknown option: ${r}`:`unexpected argument: ${r} (gateway already set to ${t.gateway})`)}}return t},$Y=e=>!e||e.length===0?ae:e.map(t=>{let n=Bt(t);if(!n)throw new Error(`unknown tool "${t}". Known: ${ae.map(r=>r.id).join(", ")}`);return n}),MY=(e,t)=>{if(W("Gateway target"),k(` Origin: ${et(e.origin)}`),e.byoUpstream)k(` Auth: BYO upstream key ${v(`(passthrough to ${e.byoUpstream.url}; Claude Code, OpenCode)`)}`),e.clientKey&&k(` Client key: personal gateway key (${Lt(e.clientKey)}) ${v("rides x-anyray-api-key")}`);else if(e.authMode==="auto"){let n=q(e,"anthropic")?et("your subscription"):"org key",r=q(e,"openai")?et("your subscription"):"org key";k(` Auth: auto ${v("(per tool)")} \u2014 Claude: ${n}, Codex: ${r}`),e.clientKey&&k(` Client key: personal gateway key (${Lt(e.clientKey)})`)}else e.authMode==="subscription"?(k(` Auth: subscription pass-through ${v("(seat OAuth token; Claude Code + Codex + verified macOS Claude Desktop)")}`),e.clientKey&&k(` Client key: personal gateway key (${Lt(e.clientKey)}) ${v("rides x-anyray-api-key")}`)):e.clientKey?k(` Auth: personal gateway key (${Lt(e.clientKey)}) ${v("(replaces the placeholder)")}`):k(` Enrollment: ${v("required before a real apply (no configuration will be written)")}`);e.authMode!=="placeholder"&&t.some(n=>n.id==="cursor")&&k(` Cursor: ${et("native Team subscription")} ${v("(Claude/Opus inference remains Cursor-hosted; Anyray hooks/MCP optimize supported local context)")}`),t.some(n=>n.id==="claude-desktop")&&(q(e,"anthropic")?(k(` Claude Desktop: ${et("subscription-backed Gateway lane")} ${v("(verified macOS builds; Windows fails closed)")}`),k(` ${v("Uses the Claude Code Keychain credential on demand; the first-party Desktop lane remains direct.")}`)):(k(` Claude Desktop: ${et("third-party API lane")} ${v("(API-billed; switches the active local inference profile)")}`),k(` ${v("The first-party Claude subscription remains untouched.")}`))),k(` Attribution: ${le(e.metadata)??v("(none \u2014 pass --user)")}`)},cI=async(e,t)=>{W("Selected tools");for(let n of e){let r=await n.detect();r.installed?k(` ${n.title} ${v(`(${n.id})`)} \u2014 ${t==="plan"?"will configure":"would configure after enrollment"}${r.detail?`; ${r.detail}`:""}`):F(` ${n.title} ${v(`(${n.id})`)} \u2014 not found${r.detail?`; ${r.detail}`:""}`)}},FY=(e,t=Date.now())=>{let n=e.clientKey?.trim();if(!Ie(n))return;let r=e.clientKeyExpiresAt?.trim();if(!r)return n;let o=Date.parse(r);return Number.isFinite(o)&&o>t?n:void 0},BY={loadDevKey:Me,saveDevKey:Gi,clearDevKey:Ka,saveProfile:te},UY=async(e,t,n,r=BY,o=!1)=>{let a=!!n||o,s=a?await r.loadDevKey():void 0,i=!1,c=!1;try{a&&(i=!0,n?await r.saveDevKey(n):await r.clearDevKey()),c=!0,await r.saveProfile(t)}catch(l){throw i&&(s!==void 0?await r.saveDevKey(s).catch(()=>{}):await r.clearDevKey().catch(()=>{})),c&&await r.saveProfile(e).catch(()=>{}),l}},HY=async(e,t,n,r,o)=>{n.dryRun||await Vi();let a=0,s=[],i=[],c=[],l=[],d=[];for(let u of e){if(!(await u.detect()).installed&&!r){d.push(u.title);continue}W(`${u.title} ${v(`(${u.id})`)}`);try{let p=r?await u.revert(n):await u.apply(t,{...n,explicit:o?.has(u.id)===!0,reportsToUser:!0});for(let h of p.messages)k(` ${h}`);a+=p.changedFiles?.length??0,l.push({id:u.id,status:p.status}),p.status==="configured"||p.status==="reverted"?$(` ${p.status}`):p.status==="manual"?(s.push(u.title),p.manualAudience==="admin"?(i.push(u.title),c.push(u.id),N(" blocked by machine policy \u2014 your IT team owns this one")):N(" manual step required (see above)")):p.status==="held"?F(" left on its own plan (no change)"):F(` ${p.status}`)}catch(p){l.push({id:u.id,status:"failed"}),_(` failed: ${p instanceof Error?p.message:String(p)}`)}}if(d.length>0&&F(`Skipped ${d.length} not installed (${d.join(", ")})`),!n.dryRun){let u=await Ji().catch(()=>[]);u.length&&F(` Removed ${u.length} unused Anyray runtime copies.`)}return{changes:a,manual:s,manualAdminOnly:i,manualAdminOnlyIds:c,results:l}},WY=(e,t=[],n)=>{if(e.length===0)return[];if(t.length===e.length)return[`${e.length===1?`${e[0]} is`:`${e.join(", ")} are`} controlled by a machine policy your organization manages, so local setup cannot change it.`,...n==="darwin"?["Admin next step: on an unmanaged admin Mac, open Claude Desktop \u2192 Developer \u2192 Configure Third-Party Inference, complete and test the Anyray connection, connectors, and plugin marketplaces, then Export \u2192 .mobileconfig and deploy that complete profile through MDM.","The configuration window is read-only on managed endpoints; Connect will not create an incomplete replacement profile or supplement the managed source locally."]:n?["Your administrator must create and test the complete Claude Desktop third-party policy through Anthropic's enterprise configuration flow, then deploy it through your organization's device-management system.","Connect will not create an incomplete replacement policy or supplement the managed source locally."]:["Your Anyray administrator can see this state in the console's Connect coverage view."],"Everything else on this machine is configured and routing normally."];let o=[`${e.length===1?`${e[0]} needs`:`${e.length} tools need`} a remaining app action \u2014 Connect may already have written its automatic config.`,`Review and complete the steps shown above for: ${e.join(", ")}.`,"Then restart or reload the app as instructed; use `npx anyray-connect status` for the available route checks."];return t.length>0&&o.push(`Not yours to fix: ${t.join(", ")} \u2014 a machine policy your organization manages. Flagged for your Anyray administrator.`),o},KY=async(e,t,n=DY())=>{let r=[],o=new Set;for(let a of e){let s=a.quitGated,i=s?.quitTarget;if(!s||!i||!Zw(i,n)||!Yw(i,n))continue;let c=jw(i,n);if(!o.has(c)){try{if(!(await a.detect()).installed||!s.isRunning()||await a.pointsAt?.(t)===!0)continue}catch{continue}o.add(c),r.push({id:a.id,title:Vw(i),quitTarget:i,isRunning:()=>s.isRunning()})}}return r},GY=(e,t)=>e.noQuitApps===!0||e.dryRun?!1:e.quitApps===!0?!0:!e.yes&&t,jY=e=>`
|
|
1006
|
+
${e.length===1?`${e[0]} is open and won't pick this up until it restarts. Quit it now?`:`${e.slice(0,-1).join(", ")} and ${e[e.length-1]} are open and won't pick this up until they restart. Quit them now?`}`,VY=async(e,t={})=>{let n=t.requestQuit??(a=>Jw(a)),r=t.waitFor??(a=>zw(a)),o=[];for(let a of e){if(n(a.quitTarget)&&await r(a.isRunning)){o.push(a),$(` Closed ${a.title}.`);continue}N(` ${a.title} is still open \u2014 leaving it alone.`),F(` Its configuration is written either way; ${a.title} picks it up the next time you close it.`)}return o},YY=(e,t={})=>{let n=t.relaunch??(o=>qw(o)),r=[];for(let o of e)n(o.quitTarget)?(r.push(o.title),$(` Reopened ${o.title}.`)):N(` Could not reopen ${o.title} \u2014 start it when you're ready.`);return r},ru=e=>e.changesBilling!==!0,ZY=async(e,t,n={})=>{let r=n.hasEnrollment??gu,o=n.canMultiSelect??i0,a=n.multiSelect??c0,s=n.prompt??xa,i=n.registry??ae;if(k(j("Anyray connect \u2014 guided setup")),k(v("Point your local coding tools at the Anyray gateway. Ctrl-C to abort.")),await r())k("Stored enrollment will be reused. Run with --revert to clear it.");else if(!e.enroll&&!e.sso&&!e.gateway){W("How do you want to connect?");let c;for(let l=0;l<3&&!c;l++){if(o()){let d=await a({title:"Choose a connection method",single:!0,items:[{value:"enroll",label:"Paste an enrollment link",selected:!0},{value:"sso",label:"Sign in with SSO"},{value:"gateway",label:"I already have a gateway URL"}]});if(d.kind==="cancelled")throw new bt;c=d.values[0]}else{k(" 1. Paste an enrollment link"),k(" 2. Sign in with SSO"),k(" 3. I already have a gateway URL");let d=await s("? Connection method (1-3)","1");c=d==="1"?"enroll":d==="2"?"sso":d==="3"?"gateway":void 0}c||N("Choose one of the three connection methods.")}if(!c)throw new bt;for(let l=0;l<3;l++)if(c==="enroll"){let d=await s("? Enrollment link or token");if(d&&Fd(d)&&Md(d)){e.enroll=d;break}N("That is not a valid enrollment link or token. Try again.")}else if(c==="sso"){let d=await s("? SSO link or tenant id");if(d&&Ht(d)){e.sso=d;break}N("That is not a valid SSO link or tenant id. Try again.")}else{let d=await s("? Gateway URL",t.gateway||process.env.ANYRAY_GATEWAY_URL);if(d&&Fd(d)){e.enroll=d,k("That looks like an enrollment link \u2014 using passwordless enrollment.");break}try{if(!d)throw new Error("missing gateway");e.gateway=sn(d);break}catch{N("That is not a valid http(s) gateway URL. Try again.")}}if(!e.enroll&&!e.sso&&!e.gateway)throw new bt}if(!e.tools||e.tools.length===0){W("Tools detected");let c=[],l=[];for(let u of i){if(!(await u.detect()).installed){l.push(u);continue}c.push(u)}let d=c.filter(u=>ru(u)).map(u=>u.id);if(c.length>0){for(let u=0;u<3&&!e.tools;u++){let f;if(o()){let p=await a({title:"Tools to configure",items:c.map(h=>({value:h.id,label:`${h.title} (${h.id})`,hint:ru(h)?void 0:"moves inference spend from your subscription to the org API bill",selected:ru(h),requiresExplicitChoice:!ru(h)}))});if(p.kind==="cancelled")throw new bt;f=p.values}else{f=(await s("? Tools to configure (comma-separated, blank = all suggested)",d.join(",")||void 0)??"").split(",").map(w=>w.trim()).filter(Boolean);let h=new Set(c.map(w=>w.id)),m=f.filter(w=>!h.has(w));if(m.length>0){N(`Unknown or unavailable tool id${m.length===1?"":"s"}. Choose from: ${c.map(w=>w.id).join(", ")}.`);continue}}if(f.length===0){N("Choose at least one installed tool.");continue}e.tools=f}if(!e.tools)throw new bt}l.length>0&&F(`${l.length} others not installed (${l.map(u=>u.id).join(", ")})`)}return e},XY=async(e,t)=>{W("Verifying the connection");let n=await Bd("Checking the gateway\u2026",()=>Ri(e,{tools:t}));n.kind==="ok"?$(` ${n.detail}`):n.kind==="unreachable"||n.kind==="unknown"||n.kind==="enrollment-required"||n.kind==="provider-rejected"?N(` ${n.detail}`):_(` ${n.detail}`);for(let r of n.remedy)k(v(` ${r}`))},JY=5e3,zY=500,lI=3,qY=600*1e3,QY=async()=>{try{let e=await LY(await Eo());return Date.now()-e.mtimeMs}catch{return Number.POSITIVE_INFINITY}},eZ=async(e={})=>{try{let t=await(e.load??P)();if(t.keyRefreshEnabled!==!0){if((e.draining??Ku)()||!await(e.unitExists??Wg)()||await(e.profileAgeMs??QY)()<qY)return;await(e.uninstall??Zt)(t.fallbackPort??Ce);return}if(!t.gateway||t.persistenceOwner==="tray"&&await(e.checkTray??wo)(t)==="healthy")return;let n=t.fallbackPort??Ce,r=e.probe??Ae,o=e.probeGapMs??zY;for(let s=0;s<lI;s++){if(await r(n,s===0?void 0:JY)!==null)return;s<lI-1&&o>0&&await new Promise(c=>setTimeout(c,o))}if((e.draining??Ku)())return;let a=await(e.install??Pt)({port:n,remoteOrigin:new URL(t.gateway).origin});if(!a.ok)for(let s of a.messages)console.error(s)}catch{}},tZ=async(e,t,n={})=>{let r=n.install??Pt,o=n.probe??Ae,a=n.pollDelayMs??300;W("Seamless key refresh");let s=n.trayManaged?{ok:!0,messages:["Launch-at-login is managed by the Anyray Connect app \u2014 not re-registering the login service."]}:await r({port:t,remoteOrigin:e.origin});for(let l of s.messages)k(` ${l}`);let i=s.ok?10:1,c=null;for(let l=0;l<i&&!c;l++)c=await o(t),!c&&l<i-1&&await new Promise(d=>setTimeout(d,a));return c?($(` Running on 127.0.0.1:${t} \u2192 ${e.origin} \u2014 your key refreshes automatically, no restart needed.`),An(e,t)):(N(" Key-refresh proxy did not come up \u2014 pointing tools directly at the gateway for now."),k(v(s.ok?" It will retry on the next run; check the service logs if it persists.":At(gt())?" In a container the key refreshes via Claude Code's helper and on each `anyray-connect` run instead.":" Your key still refreshes on a schedule \u2014 no daemon needed here.")),e)},nZ=async(e,t={})=>{if(e.dryRun)return;let n=t.install??rr,r=t.uninstall??or;if(e.want&&e.trayManaged){e.announcePrimary&&(W("Automatic key refresh"),$(" Managed by the Anyray Connect app \u2014 it triggers the ~30-min key refresh."));return}if(e.want){let o=await n();if(e.announcePrimary){W("Automatic key refresh");for(let a of o.messages)k(` ${a}`);o.ok&&$(" Your gateway key now re-mints every ~30 min \u2014 no tool will 401 on a stale key mid-session.")}o.ok||await te({...await P(),refreshSchedulerEnabled:!1});return}if(!e.scopedRevert&&e.wasEnabled){W("Automatic key refresh");let o=await r();for(let a of o.messages)k(` ${a}`);await te({...await P(),refreshSchedulerEnabled:!1}),$(" Removed the automatic key-refresh schedule.")}},rZ=new Set(["login","wizard","status","doctor","sync","device-url"]),oZ=new Set(["managed","print-key","device-url","status","update","retrieve","recall","history","migrate","endpoint"]),aZ=e=>{if(e.outcome==="migrated"&&e.managedPath)return{level:"info",message:`Installed managed anyray-connect at ${e.managedPath}.`};if(e.outcome==="platform-unsupported")return{level:"warn",message:"Self-update is unavailable on this platform; keeping the durable npm runtime for persistent integrations."};if(e.outcome==="migration-deferred")return{level:"warn",message:`Managed install deferred because the published binary (${e.latest}) is older than this npm runtime (${e.current}).`};if(!(e.outcome==="current"||e.outcome==="unmanaged"||e.outcome==="updated"||e.outcome==="disabled"||e.outcome==="container"))return{level:"warn",message:"Could not install the managed anyray-connect binary; continuing with the current runtime \u2014 it migrates automatically on a later refresh."}},sZ=e=>{if(e.includes("--help")||e.includes("--help-all")||e.includes("-h"))return!1;if(e[0]==="managed")return e.includes("--write")&&!e.includes("--revert");if(e[0]==="desktop"){let t=_m(e.slice(1));return!!(t&&!t.includes("--dry-run")&&!t.includes("--revert"))}return e.includes("--dry-run")||e.includes("--revert")||e.includes("--project")?!1:e[0]==="doctor"?e.includes("--repair"):e[0]==="models"?e.slice(1).some(t=>!t.startsWith("-")):!e[0]||!oZ.has(e[0])},Py=async(e,t)=>{try{return await lZ(e,t)}catch(n){if(n instanceof bt)return console.error(v("Cancelled \u2014 nothing was written.")),130;throw n}},iZ=async(e,t,n,r={})=>{if(e.yes||e.dryRun)return"proceed";if(!(r.isInteractive??Kt)())return"non-interactive";let o=e.revert?"remove Anyray config from":"configure",a=t?"Apply this configuration?":`
|
|
1007
|
+
${o} ${n} tool target(s)?`;return await(r.confirm??Ea)(a)?"proceed":"declined"},cZ=async e=>{if(e[0]==="__anyray-hook"){let n=e[1]==="cursor"||e[1]==="opencode"?e[1]:"claude";return J0(n)}if(e[0]==="__anyray-codex-hook")return z0();if(e[0]==="__anyray-prompt-hook")return q0();if(e[0]==="__anyray-shell-pretool")return nx();if(e[0]==="__anyray-shell-run")return tx(e.slice(1));if(e[0]==="__anyray-read-pretool")return dx();if(e[0]==="__anyray-sso-gate")return kS(e.slice(1));if(e[0]==="__anyray-sso-poll")return ux();if(e[0]==="__anyray-vscode-gate")return gx();if(e[0]==="__anyray-spawn-refresh")return await Cr(),0;if(e[0]==="__anyray-mcp-server"){let n=e[1]==="claude"||e[1]==="profile"?e[1]:"auto";return Sx(n)}if(e[0]==="__anyray-acp-agent")return Ex(e[1],e[2],{clientTool:e[3]});if(e[0]==="__anyray-endpoint-install")return Qx(e.slice(1));if(e[0]==="__anyray-refresh"){await Vm(),await Qe({runAmbientSelfcheck:!0}),await sm(),await eZ(),await iS(),await cS();let n=await P().catch(()=>{});if(n){process.env.ANYRAY_FLEET_MANAGED==="1"&&!n.anyrayFleetManaged&&(n.anyrayFleetManaged=!0,await te(n).catch(()=>{}));let r=n.anyrayFleetManaged===!0&&await La().catch(()=>!1);if(await tI(n,{fleetdPresent:async()=>r}).catch(()=>{}),r&&n.gateway&&n.clientKey){let o=n.gateway,a=n.clientKey,s=nI(),i=n.enrolledCert;if(s&&i){let l=await Me().catch(()=>{});l&&await bv(o,a,i,l,s).catch(()=>{})}await oI(o,a,{execute:async(l,d)=>l==="remint"||l==="reapply_config"?await Qe({force:!0})==="failed"?"failed":"ok":l==="revert_tool"?iI(d):(await aI()).ok?"ok":"failed"}).catch(()=>{})}}return await Ii(),0}if(e[0]==="__anyray-fallback-proxy")return FS();if(e[0]==="__anyray-persistence")return US(e.slice(1));if(e[0]==="__anyray-quit-watch")return YS(e.slice(1));if(e[0]===js)return IE(e.slice(1));if(e[0]==="--version"||e[0]==="-V")return yx();try{let n=await cg(e);if(n!==void 0)return n}catch(n){return _(`Could not persist anyray-connect for long-lived integrations: ${n instanceof Error?n.message:String(n)}`),1}if(sZ(e)){let n=aZ(await m0());n?.level==="warn"?N(n.message):n&&console.error(n.message)}if(e[0]==="managed")return oE(e.slice(1));if(e[0]==="endpoint")return qx(e.slice(1));if(e[0]==="print-key")return cE(e.slice(1));if(e[0]==="models")return dE(e.slice(1));if(e[0]==="copilot-login")return uE(e.slice(1));if(e[0]==="desktop"){let n=e.slice(1),r=_m(n);return r?Py(r,!1):HE(n)}if(e[0]==="retrieve")return KE(e.slice(1));if(e[0]==="recall")return GE(e.slice(1));if(e[0]==="history")return n0(e.slice(1));if(e[0]==="migrate")return o0(e.slice(1));if(e[0]==="login")return fx(e.slice(1));if(e[0]==="update")return mx(e.slice(1));let t=e[0];if(t&&rZ.has(t)){let n=e.slice(1),r;try{r=pI(n)}catch(o){return _(o.message),k("\nRun `npx anyray-connect --help` for usage."),1}return r.help?(k(r.helpAll?uI:dI),0):t==="status"?b0({gateway:r.gateway}):t==="doctor"?S0({gateway:r.gateway,json:r.json,verify:r.verify,noVerify:r.noVerify,quick:r.quick,repair:r.repair,securityReview:r.securityReview}):t==="sync"?E0({gateway:r.gateway}):t==="device-url"?pE():Py(n,!0)}return Py(e,!1)},fI=async e=>{try{return await cZ(e)}catch(t){if(t instanceof bt)return console.error(v("Cancelled.")),130;throw t}},lZ=async(e,t,n={})=>{let r=n.isInteractive??Kt,o;try{o=pI(e)}catch(L){return _(L.message),k("\nRun `npx anyray-connect --help` for usage."),1}if(o.help)return k(o.helpAll?uI:dI),0;if(o.revert&&(o.sso||o.enroll))return _("--revert cannot be combined with --sso or --enroll. It removes Anyray configuration; re-run with --sso <link> --yes (without --revert) to configure a new CLI."),1;if(o.project)return o.sso||o.enroll||o.subscription||o.upstream?(_("--project cannot be combined with --sso/--enroll (per-machine enrollment) or --subscription/--upstream (per-dev credential lanes). It writes an org-lane, credential-free repo config."),1):SE({gateway:o.gateway,tools:o.tools,revert:o.revert,dryRun:o.dryRun,yes:o.yes});if(!!o.upstream!=!!o.upstreamKey)return _("--upstream and --upstream-key go together: the URL says where your personal key is valid, the key is what the gateway forwards there."),1;if(o.upstream&&(o.subscription||o.placeholder))return _("--upstream cannot be combined with --subscription or --org: BYO passthrough sends your personal upstream key \u2014 not a seat OAuth token, and never the org's server-held key."),1;let a;if(o.upstream){let L;try{L=new URL(o.upstream.trim())}catch{return _(`invalid --upstream URL: "${o.upstream}"`),1}if(L.protocol!=="http:"&&L.protocol!=="https:")return _(`invalid --upstream URL: "${o.upstream}" \u2014 must start with http:// or https://`),1;let T=o.upstreamKey.trim();if(!T)return _("--upstream-key must not be empty."),1;a={url:Ye(o.upstream),key:T}}let s=await P();if(!o.revert&&!o.dryRun&&o.noKeyRefresh!==!0){let L=await Vm();(L==="migrated"||L==="already-direct")&&(s=await P())}!a&&!o.subscription&&!o.placeholder&&!o.revert&&(a=s.byoUpstream),o.retiredFallbackFlag&&N("--fallback/--no-fallback are retired and ignored: the local daemon no longer routes around the gateway to the provider. Seamless key refresh is on by default (--no-key-refresh opts out).");let i=!t&&Kt()&&!o.gateway&&!o.revert&&!o.yes&&!o.dryRun&&!o.enroll&&!o.sso,c=!1;(t||i)&&r()&&(o=await(n.runWizard??ZY)(o,s),c=!0);let l;try{l=$Y(o.tools)}catch(L){return _(L.message),1}k(j(o.revert?"Anyray connect \u2014 revert":"Anyray connect")),o.gateway&&!o.enroll&&Fd(o.gateway)&&(o.enroll=o.gateway,o.gateway=void 0,k("That looks like an enrollment link \u2014 treating it as --enroll."));let d,u,f=!1;if(o.enroll&&(!o.gateway||s.enrolledCert)){let L=Md(o.enroll);if(L)try{let T=await Bd("Resolving enrollment link\u2026",()=>a0(L)),K=!o.gateway;K&&(o.gateway=T.gatewayUrl),d=T.deploymentId,u=T.email,f=!0,K&&F(`Enrollment link${T.org?` for ${T.org}`:""}: gateway ${T.gatewayUrl}`),T.seatMode&&!o.subscription&&(o.subscription=!0,F("Subscription org: using pass-through auth (--subscription) \u2014 your own seat sign-in is used."))}catch(T){let K=o.gateway||process.env.ANYRAY_GATEWAY_URL?.trim()||s.gateway;if(K)F(`Could not resolve the gateway from the enrollment link \u2014 using ${K}.`);else return _(T instanceof Error?T.message:String(T)),1}}let p;if(o.sso&&!o.revert)if(o.dryRun)F("dry run: not enrolled via SSO (skipped minting a personal key).");else{let L=Ht(o.sso);if(!L)return _("invalid --sso value: expected a https://\u2026/sso/<tenantId> link or a tnt_ id."),1;try{let T=await Bd("Waiting for SSO sign-in\u2026",()=>uS({cpOrigin:L.cpOrigin,tenantId:L.tenantId,gatewayUrl:o.gateway,log:K=>F(K)}));p={cert:T.cert,privateKeyPem:T.privateKeyPem},T.deploymentId&&(d=T.deploymentId),!o.gateway&&T.gatewayUrl&&(o.gateway=T.gatewayUrl)}catch(T){return _(T instanceof Error?T.message:String(T)),1}}let h=!o.gateway&&!process.env.ANYRAY_GATEWAY_URL?s.gateway:void 0;h&&(o.gateway=h);let m;try{m=sn(o.gateway)}catch(L){return _(L.message),1}let w,g;h&&!o.revert&&F(`Gateway: ${m} ${v("(cached in ~/.anyray \u2014 pass a URL to change)")}`),!o.revert&&Ly(m)&&N(`${m} is plaintext http over a network \u2014 connections can be reset by firewalls/VPNs and traffic is unencrypted. Prefer an https:// gateway URL (front it with the TLS edge).`);let y=process.env.ANYRAY_CLIENT_KEY?.trim(),b=y||FY(s),C,S,E,x,A,I,R=s.credentialProtocol==="stable-heartbeat-v1",B=async L=>{await yo();let T=wv(L.token),K=kv(s.enrolledCert,s.enrolledCertExpiry,L.deploymentId,Date.now(),T,s.enrolledTokenHash,L.expectedUser),J=K?await Me():void 0,ge=K&&J&&s.enrolledCert?{cert:s.enrolledCert,privateKeyPem:J,publicKeyPem:s.enrolledCert.payload.devPublicKey}:void 0,z=be=>Av({cpOrigin:L.cpOrigin,token:L.token,gatewayOrigin:m,email:L.email,team:L.team,machineId:L.machineId,deploymentId:L.deploymentId,reuse:be?ge:void 0}),Ve=!!ge,we=await(async()=>{try{return await z(Ve)}catch(be){if(ge&&be instanceof It)return F("your saved certificate was rejected by the gateway (it may have been rebuilt) \u2014 re-enrolling from scratch\u2026"),Ve=!1,await z(!1);throw be}})();b=we.clientKey,o.user||=we.user,o.team||=we.team,C=we.cert,S=we.cert.payload.expiresAt,I=we.expiresAt,R=we.capabilities?.includes(li)===!0,A=void 0,Ve||(E=we.privateKeyPem),Ve||(x=T),$(`Enrolled${we.user?` as ${we.user}`:""}${Ve?" (reused your saved cert)":""} \u2014 personal gateway key minted (not shown; it lands in your tool configs).`)};if(o.enroll&&!o.revert)if(o.dryRun)F("dry run: not enrolled (skipped minting a personal key).");else{let L=Md(o.enroll);if(!L)return _("invalid --enroll value: expected a https://\u2026/enroll/<token> link or a bare token."),1;try{let T=o.machine?nu():void 0,K=u??NY(o.user),J=o.machine?`machine:${T}`:f?K:void 0;await B({cpOrigin:L.cpOrigin,token:L.token,email:K,team:o.team,machineId:T,deploymentId:d,expectedUser:J})}catch(T){return _(T instanceof Error?T.message:String(T)),T instanceof It&&F("The gateway rejected this enrollment. Ask your admin to confirm the gateway is connected and entitled, and that your link targets the right gateway \u2014 the exact reason is in the gateway logs."),1}}if(p){await yo();try{let L=await rn(m,p.cert,p.privateKeyPem);b=L.key,o.user||=L.user,o.team||=L.team,C=p.cert,S=p.cert.payload.expiresAt,E=p.privateKeyPem,I=L.expiresAt,R=L.capabilities?.includes(li)===!0;let T=Ht(o.sso);A=T?`${T.cpOrigin}/sso/${T.tenantId}`:void 0,$(`Enrolled${L.user?` as ${L.user}`:""} via SSO \u2014 personal gateway key minted (not shown; it lands in your tool configs).`)}catch(L){return _(L instanceof Error?L.message:String(L)),L instanceof It&&F("The gateway rejected your SSO sign-in. Ask your admin to confirm the gateway is connected and entitled \u2014 the exact reason is in the gateway logs."),1}}if(!o.revert){let L=o.yes;w=await gE(o.user,s.name,L),g=await wE(o.team,s.team,L)}let V;!o.revert&&!o.subscription&&!o.placeholder&&(V=await Tt(),W("Detecting your sign-ins"),k(` Claude (Anthropic): ${a?et("BYO upstream key (passthrough)"):V.anthropic?et("signed in \u2192 your subscription"):v("not signed in \u2192 org key")}`),k(` Codex (ChatGPT): ${V.openai?et("signed in \u2192 your subscription"):v("not signed in \u2192 org key")}`),!V.anthropic&&!V.openai&&!V.copilot&&qa()&&(N(" No subscription sign-ins found on this host. Sign-ins do not cross the"),N(" Remote-SSH hop \u2014 your laptop's are invisible here, and these tools run"),N(" HERE. Sign in on this machine (`copilot` \u2192 /login, Claude Code, Codex)"),N(" and re-run, or everything below routes on the org key instead.")));let H=me({origin:m,placeholderKey:o.key,clientKey:b,subscription:o.subscription,placeholder:o.placeholder,byoUpstream:a,seat:V,user:w,team:g,intent:o.intent,intentLabel:o.intentLabel,session:o.session}),X=o.revert===!0&&(o.tools?.length??0)===0,ie={dryRun:o.dryRun,fullRevert:X};if(!o.revert&&H.clientKey&&!Ie(H.clientKey))return _("Invalid personal gateway key: expected a minted ark_ credential. Re-run with --enroll/--sso, or set ANYRAY_CLIENT_KEY to a valid key."),1;if(!o.revert&&!H.clientKey){W("Enrollment required");let L="A real apply requires a personal ark_ gateway key. Run with --enroll <link> or --sso <link>, then re-run Connect.";return o.dryRun?(N(` ${L}`),F(" Dry run only \u2014 no placeholder configuration will be written."),await cI(l,"after-enrollment"),F(`
|
|
1008
|
+
Dry run complete \u2014 no files were written.`),0):(_(` ${L}`),1)}o.revert||MY(H,l),c&&!o.revert&&await cI(l,"plan"),o.dryRun&&F(`
|
|
1009
|
+
Dry run \u2014 no files will be written.`);let ye=await iZ(o,c,l.length,{isInteractive:r,confirm:n.confirm});if(ye==="non-interactive")return _(`
|
|
1010
1010
|
Non-interactive session \u2014 cannot ask for confirmation. Pass --yes to proceed.`),1;if(ye==="declined")return F(c?"Nothing was written. Re-run `npx anyray-connect wizard` when you're ready.":"Aborted. Nothing changed."),0;if(!o.dryRun&&!o.revert&&!o.force){let L=await $d(H.origin);if(!L.reachable)return _(`
|
|
1011
1011
|
Gateway ${H.origin} is not reachable (${L.detail}).`),k(v(` Refusing to repoint your tools at a gateway that isn\u2019t responding \u2014
|
|
1012
1012
|
that would break them until you re-run with --revert.`)),k(`
|
|
1013
|
-
Start the gateway and try again, or pass --force to configure anyway.`),1;$(`Gateway reachable (${L.detail}).`)}let Ue=o.revert?[]:await
|
|
1014
|
-
Keeping the stored enrollment \u2014 the tools you did not name still need it.`),k("Run --revert with no --tools to remove it."));let Co=l;if(o.revert&&!X){let ue=l.filter(tt=>ci(s,tt.id));if(ue.length>0){W("Fleet policy");for(let tt of ue)N(` ${tt.id}: locked by your admin's fleet policy \u2014 leaving it configured. Ask an admin to change the tool's tier.`);Co=l.filter(tt=>!ci(s,tt.id))}}let{changes:an,manual:Ma,manualAdminOnly:Bi,manualAdminOnlyIds:ou,results:Fa}=await
|
|
1013
|
+
Start the gateway and try again, or pass --force to configure anyway.`),1;$(`Gateway reachable (${L.detail}).`)}let Ue=o.revert?[]:await KY(l,H.origin),re=[],je=()=>{re.length!==0&&(W("Reopening"),YY(re),re=[])};if(Ue.length>0){let L=Ue.map(K=>K.title),T=L.length===1?"it":"them";if(W("Open apps"),GY(o,Kt()))o.quitApps===!0||await Ea(jY(L))?re=await VY(Ue):F(` Leaving ${T} open \u2014 restart when convenient.`);else{let K=o.noQuitApps===!0?"":" (or pass --quit-apps)";F(o.dryRun?` Would offer to quit ${L.join(", ")} \u2014 dry run, nothing was closed.`:` ${L.join(", ")} ${L.length===1?"is":"are"} open; restart ${T} to pick this up${K}.`)}}try{if(!o.dryRun)try{await kt()}catch{return _("Could not prepare the owner-only Anyray state directory."),1}let L=l.some(ue=>ue.id==="claude-code")&&q(H,"anthropic")||l.some(ue=>ue.id==="codex")&&q(H,"openai"),T=hd(s,I),K=!o.revert&&o.noKeyRefresh!==!0&&L&&T&&!R,ge=!o.revert&&(o.tools?.length??0)>0&&o.noKeyRefresh!==!0&&!!s.keyRefreshEnabled,z=!!(y&&H.clientKey===y&&!C),Ve=!z&&!!(C??s.enrolledCert),we=l.some(ue=>oS.has(ue.id)),be=!o.revert&&o.noKeyRefresh!==!0&&Ve&&(T||!we),he=o.dryRun?await wo(s):await sm(),Y=he==="healthy";he==="healed"&&(delete s.persistenceOwner,delete s.trayAppPath);let De=H,He=K||ge,ht=He?s.fallbackPort:void 0;if(K&&!o.dryRun&&(ht=s.fallbackPort??await lc()),!o.revert&&!o.dryRun){let ue={...s,gateway:H.origin,name:w,team:g,clientKey:H.clientKey??s.clientKey,enrolledCert:z?void 0:C??s.enrolledCert,enrolledCertExpiry:z?void 0:S??s.enrolledCertExpiry,enrolledTokenHash:z?void 0:x??s.enrolledTokenHash,ssoLink:z?void 0:p?A:C?void 0:s.ssoLink,clientKeyExpiresAt:z?void 0:I??(H.clientKey===s.clientKey?.trim()?s.clientKeyExpiresAt:void 0),authMode:H.authMode,byoUpstream:H.byoUpstream,credentialProtocol:z?void 0:He?"rotating-proxy-v1":R?"stable-heartbeat-v1":s.credentialProtocol,directMigration:z?void 0:He?"pending":R?"complete":s.directMigration,keyRefreshEnabled:He,refreshSchedulerEnabled:be,fallbackPort:ht};try{await UY(s,ue,E,void 0,z)}catch{return _("Could not save the owner-only Anyray runtime profile. No tool configuration was changed."),1}I&&!z&&await ba({expiresAt:I})}if(K&&!o.dryRun&&(De=await tZ(H,ht,{trayManaged:Y})),X)if(o.dryRun)await gu()&&(W("Enrollment"),k(" would remove the stored gateway credential"));else{await _y(s),await bd().catch(()=>{});try{await ji()&&(W("Enrollment"),$(" Removed the stored gateway credential."),F(" Reconnect any time with `npx anyray-connect@latest --sso`."))}catch(ue){W("Enrollment"),N(" Could not remove the stored gateway credential."),N(` Delete ${Q()} by hand, or the key-refresh hook may restore your tool config.`)}}else o.revert&&!o.dryRun&&(k(`
|
|
1014
|
+
Keeping the stored enrollment \u2014 the tools you did not name still need it.`),k("Run --revert with no --tools to remove it."));let Co=l;if(o.revert&&!X){let ue=l.filter(tt=>ci(s,tt.id));if(ue.length>0){W("Fleet policy");for(let tt of ue)N(` ${tt.id}: locked by your admin's fleet policy \u2014 leaving it configured. Ask an admin to change the tool's tier.`);Co=l.filter(tt=>!ci(s,tt.id))}}let{changes:an,manual:Ma,manualAdminOnly:Bi,manualAdminOnlyIds:ou,results:Fa}=await HY(Co,De,ie,o.revert,new Set(o.tools??[]));if(jx(o)){W("Endpoint agent");try{await(n.installEndpointAfterEnrollment??eI)({gateway:m,clientKey:H.clientKey})}catch{F("Endpoint agent setup did not complete. Tool routing remains configured.")}}if(o.dryRun||(await Vn(Fa,o.revert,X).catch(()=>{}),X&&await Yi().catch(()=>{})),!He&&!o.dryRun&&(rt(s)||s.fallbackPort||await bi("daemon"))){W("Local loopback proxy");let ue=await Zt(s.fallbackPort);for(let tt of ue.messages)k(` ${tt}`);await te({...await P(),keyRefreshEnabled:!1,fallbackPort:void 0}),$(" Removed the local loopback proxy.")}if(await nZ({want:be,announcePrimary:!K,scopedRevert:!!o.revert&&!X,dryRun:!!o.dryRun,wasEnabled:!!s.refreshSchedulerEnabled||!be&&await bi("scheduler"),trayManaged:Y}),!o.revert&&!o.dryRun&&!z){let ue=E??await Me();ue&&await Jh(await P(),ue).catch(()=>{})}if(je(),W("Summary"),o.dryRun)F("Dry run complete \u2014 re-run without --dry-run to apply.");else if(o.revert){$(`Reverted (${an} file(s) touched).`),F("Restart any editor or agent that was running \u2014 it loaded our hooks at startup.");let ue=await vE();ue.length>0&&(W("This repo carries its own Anyray routing"),N(` Committed here: ${ue.join(", ")}`),N(" Those are tracked files, so they route every checkout of this"),N(" repo \u2014 this machine included, and your teammates' too. This"),N(" revert only removed THIS machine's own configuration."),k(`
|
|
1015
1015
|
Remove them from the repo (then commit):`),k(v(" anyray-connect --project --revert")));let tt=[H,...s.fallbackPort?[An(H,s.fallbackPort)]:[]],_r=yp(tt);_r.length>0&&(W("This terminal still points at the gateway"),N(` Still exported here: ${_r.join(", ")}`),N(" Removing the block from your shell profile cannot reach a shell"),N(" that already ran it. Until these are gone, your tools keep"),N(" reaching the gateway and now fail with 401."),k(`
|
|
1016
1016
|
Fix this terminal:`),k(v(` unset ${_r.join(" ")}`)),k(`
|
|
1017
|
-
Every other open terminal needs the same \u2014 or just open a new one.`),k(" VS Code injects a copy it captured when IT launched, so its"),k(" terminals stay stale even if you open a new one: quit the app"),k(" entirely (Cmd+Q). Reloading the window keeps the old copy."))}else{if($(`Done (${an} file(s) written).`),Ma.length>0){let nt=Bi.length===Ma.length;W(nt?"Blocked by machine policy \u2014 nothing for you to do":"Action required \u2014 manual steps");for(let Ty of
|
|
1018
|
-
Skipped the connection smoke test (--skip-verify).`):await
|
|
1017
|
+
Every other open terminal needs the same \u2014 or just open a new one.`),k(" VS Code injects a copy it captured when IT launched, so its"),k(" terminals stay stale even if you open a new one: quit the app"),k(" entirely (Cmd+Q). Reloading the window keeps the old copy."))}else{if($(`Done (${an} file(s) written).`),Ma.length>0){let nt=Bi.length===Ma.length;W(nt?"Blocked by machine policy \u2014 nothing for you to do":"Action required \u2014 manual steps");for(let Ty of WY(Ma,Bi,ou.includes("claude-desktop")?process.platform:void 0))N(Ty);Kt()&&!o.yes&&!nt&&(await Ea("Have you applied the manual settings shown above?")?$("Acknowledged."):N("Apply them before using the tool, or it will keep sending traffic straight to the provider (unattributed)."))}o.skipVerify?F(`
|
|
1018
|
+
Skipped the connection smoke test (--skip-verify).`):await XY(H,l.map(nt=>nt.id)),W("What's next");let ue=new Set(Fa.filter(nt=>nt.status==="configured").map(nt=>nt.id)),tt=l.filter(nt=>ue.has(nt.id)).map(nt=>nt.title);if(k(tt.length>0?` Connected: ${tt.join(", ")}`:" Connected: no tools completed automatic configuration."),k(" Restart any editor that was already running \u2014 it loaded our config at startup."),k(" If something looks wrong: npx anyray-connect doctor"),!o.verbose)return 0;k(`
|
|
1019
1019
|
Re-test by hand any time:`),H.authMode!=="placeholder"&&l.length===1&&l[0]?.id==="cursor"?(k(v(` curl -sS ${H.origin}/connect/savings \\
|
|
1020
1020
|
-H "x-anyray-api-key: $(anyray-connect print-key)"`)),k(v(" Validate Opus itself inside Cursor: keep the Team login, select a native Claude Opus model, and run an Agent prompt."))):k(v(` curl -sS ${H.openaiBaseUrl}/chat/completions \\
|
|
1021
1021
|
-H "Content-Type: application/json" \\
|