anyray-connect 0.11.126 → 0.11.127
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 +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ var sI="http://localhost:8787",Fa="anyray-placeholder",Ie=e=>{let t=e?.trim();re
|
|
|
4
4
|
`,{mode:384})}catch(a){throw await _r(e,{recursive:!0,force:!0}).catch(()=>{}),a}return async()=>{try{JSON.parse(await Ha(t,"utf-8")).nonce===r&&await _r(e,{recursive:!0,force:!0})}catch{}}}catch(a){if(a.code!=="EEXIST")throw a}if(!(await TI(e).catch(()=>!1)&&await _r(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,OI))}}},Jy=async e=>{let t=Object.fromEntries(Object.entries(e).filter(([,o])=>o!==void 0)),n=await vo(),r=`${n}.${process.pid}.${xI++}.tmp`;await Gi(r,`${JSON.stringify(t,null,2)}
|
|
5
5
|
`,{mode:384}),await pu(r,384);try{await pe(r,n)}catch(o){throw await _r(r,{force:!0}).catch(()=>{}),o}},te=async e=>{let t=await Xy();try{await Jy(e)}finally{await t()}},zy=async e=>{let t=await Xy();try{let n=await P(),{next:r,result:o}=e(n);return r&&await Jy(r),o}finally{await t()}},uu=["clientKey","clientKeyExpiresAt","enrolledCert","enrolledCertExpiry","enrolledCertLifetimeMs","enrolledTokenHash"],Vy="ssoLink",mu=async()=>{let e=await P();return uu.some(t=>e[t]!==void 0)?!0:await $e()!==void 0},Vi=async()=>{let e=await P(),t=uu.some(a=>e[a]!==void 0),n=e[Vy]!==void 0,r=e.byoUpstream!==void 0,o=await $e()!==void 0;if(!t&&!n&&!r&&!o)return!1;if(t||n||r){let a={...e};for(let s of uu)delete a[s];delete a[Vy],delete a.byoUpstream,delete a.anyrayFleetManaged,await te(a)}if(await Wa(),await $e())throw new Error(`could not remove the dev key from ${Q()}`);return!0},qy=["fallback-bundle.enc","fallback-key","fallback-usage-queue.jsonl"],Yi=async()=>{let e=Q();for(let t of qy)await _r(Cn(e,t),{force:!0}).catch(()=>{})},yu=async()=>{let e=Q(),t=[];for(let n of qy){let r=Cn(e,n);try{await vI(r),t.push(r)}catch{}}return t},jn=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})},Zi=async(e=new Date().toISOString())=>{await te({...await P(),offboardedAt:e})};var Eo=e=>HI(e).replace(/\\/g,"/").toLowerCase(),wu=(e=process.platform)=>e==="win32"?"anyray-connect.exe":"anyray-connect",Ga=e=>`${e}.source`,rg=e=>/(^|\/)_npx(\/|$)/.test(Eo(e)),ku=e=>/(^|\/)node_modules\/anyray-connect\/dist\/index\.js$/.test(Eo(e)),Au=e=>{let t=Eo(e),n=[UI(),"/tmp","/private/tmp","/var/folders","/private/var/folders"].map(Eo);return rg(t)||n.some(r=>t===r||t.startsWith(`${r}/`))},ht=()=>({execPath:process.execPath,scriptPath:process.argv[1]}),ja=e=>/[\\/](node|node\.exe)$/i.test(e),Vn=(e=ht())=>ja(e.execPath)&&e.scriptPath?e.scriptPath:e.execPath,eg=e=>{try{let t=tg(e);return t.isFile()?t.size:void 0}catch{return}},Cu=e=>{let t=He(e);if(So(t)==="versions")return t;let n=He(t);return So(n)==="versions"?n:void 0},Ji=(e,t)=>t!==void 0&&(He(e)===t||He(He(e))===t),WI=e=>{let t=Cu(e);if(!t)return;let n=Re(He(t),"bin",wu());try{let r=Ka(n);return r===Ka(e)||Ji(r,Ka(t))?n:void 0}catch{return}},xo=(e=Q(),t=process.platform)=>{let n=Re(e,"bin",wu(t));try{let r=Ka(n),o=Ka(Re(e,"versions"));if(Ji(r,o))return n;if(t==="win32"){let a=DI(Ga(n),"utf8").trim();if(!/^[0-9A-Za-z.-]+$/.test(a))return;let s=eg(Re(o,a,wu(t)))??eg(Re(o,a));if(s!==void 0&&s===tg(n).size)return n}}catch{return}},Pr=(e=ht())=>{let t=Vn(e),n=ku(t)||Su(t)?xo():void 0;return WI(e.execPath)??n??t},og=(e=ht())=>Pr(e)!==Vn(e),sn=(e,t=ht())=>{let n=Pr(t);return ja(t.execPath)&&t.scriptPath!==void 0&&n===Vn(t)?{command:t.execPath,args:[n,...e],entryPath:n}:{command:n,args:e,entryPath:n}},ag=(e=ht())=>{let t=Pr(e);return!ja(e.execPath)&&!Au(t)?He(t):Re(Q(),"bin")},Xi=async e=>{try{return await NI(e),!0}catch{return!1}},KI=async e=>{let t=await MI(e),n=He(t),r=He(n),o=Re(r,"package.json"),a=await bu(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 Xi(Re(n,"index.js")))throw new Error("published package is missing dist/index.js");return{root:r,dist:n,packageJson:o,version:s.version}},GI=async(e,t)=>{let n=t;for(;;){let r=Re(n,"node_modules",e);if(await Xi(Re(r,"package.json")))return r;let o=He(n);if(o===n)return;n=o}},jI=async(e,t)=>{let n=new Set,r=[e];for(;r.length>0;){let o=r.shift(),a=JSON.parse(await bu(Re(o,"package.json"),"utf8"));for(let s of Object.keys(a.dependencies??{})){if(n.has(s))continue;n.add(s);let i=await GI(s,o);if(!i)throw new Error(`runtime dependency "${s}" is not installed`);await ng(i,Re(t,s),{recursive:!0}),r.push(i)}}},VI=async(e=ht())=>{let t=xo();if(t)return{command:t,args:[],entryPath:t};if(!ja(e.execPath)||!e.scriptPath)return{command:e.execPath,args:[],entryPath:e.execPath};let n=await KI(e.scriptPath);await bt();let r=Re(Q(),"bin",`connect-runtime-${n.version}`),o=Re(r,"dist","index.js");if(!await Xi(o)){let a=`${r}.stage-${process.pid}-${Date.now()}`;await gu(a,{recursive:!0,force:!0}),await Qy(a,{recursive:!0,mode:448});try{await ng(n.dist,Re(a,"dist"),{recursive:!0}),await BI(Re(a,"package.json"),await bu(n.packageJson),{mode:384}),await jI(n.root,Re(a,"node_modules")),await Qy(He(r),{recursive:!0,mode:448});try{await FI(a,r)}catch(s){if(!await Xi(o))throw s}}finally{await gu(a,{recursive:!0,force:!0})}}return{command:e.execPath,args:[o],entryPath:o}},vu=/^connect-runtime-(?!.*\.stage-)[0-9A-Za-z][0-9A-Za-z.-]*$/,YI=e=>{let t=So(He(He(e)));return vu.test(t)?t:void 0},Su=(e,t=Q())=>{let n=He(He(e));return Eo(He(n))===Eo(Re(t,"bin"))&&vu.test(So(n))&&So(He(e))==="dist"&&So(e)==="index.js"},zi=async(e=ht())=>{let t=Re(Q(),"bin"),n=YI(Vn(e)),r=[];for(let o of await $I(t).catch(()=>[])){if(!vu.test(o)||o===n)continue;let a=Re(t,o);await gu(a,{recursive:!0,force:!0}).then(()=>!0,()=>!1)&&r.push(a)}return r},sg=async(e,t=ht())=>{let n=Vn(t);if(!ja(t.execPath)||!rg(n)||xo())return;let r=await VI(t),o=LI(r.command,[...r.args,...e],{stdio:"inherit",env:process.env});if(o.error)throw o.error;return o.status??1};var Eu=e=>/^[A-Za-z0-9_./:=-]+$/.test(e)?e:`"${e.replace(/"/g,'\\"')}"`,Va=(e,t)=>[e,...t].map(Eu).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}:{}}]}),Io=(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))},qi=(e,t,n,r,o="append")=>{let a=e.hooks??{},i=(Array.isArray(a[t])?a[t]:[]).filter(c=>!Io(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=>!Io(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)},xu=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=>!Io(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 mt="__anyray-hook",ig="__anyray-codex-hook",Yn="__anyray-prompt-hook",cg="__anyray-shell-pretool",Iu="__anyray-shell-run",lg="__anyray-read-pretool",Zn="__anyray-refresh",Ya=(e,t=[])=>{let{command:n,args:r}=sn([e,...t]);return{command:n,args:r}},Ot=(e,t=[])=>{let n=Ya(e,t);return[n.command,...n.args].map(Eu).join(" ")},Qi=(e,t,n=[])=>typeof e=="string"&&e.trim()===Ot(t,n),dg=()=>Ot("print-key"),Oe=()=>Pr(),We=Au,ie=()=>!We(Oe()),Tr=async()=>{if(!ie())return!1;try{return await ZI(Oe()),!0}catch{return!1}},Xn="__anyray-mcp-server",Ke=e=>Ya(Xn,[e]),XI=(e,t)=>Array.isArray(e)&&e.length===t.length&&e.every((n,r)=>n===t[r]),ec=(e,t)=>{if(!e||typeof e!="object"||Array.isArray(e))return!1;let n=e,r=Ke(t);return n.command===r.command&&XI(n.args,r.args)},jt=(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)===Xn&&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 Lr=["ANTHROPIC_BASE_URL","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_CUSTOM_HEADERS","ENABLE_TOOL_SEARCH","_CLAUDE_CODE_ASSUME_FIRST_PARTY_BASE_URL"],ug=["ENABLE_TOOL_SEARCH","_CLAUDE_CODE_ASSUME_FIRST_PARTY_BASE_URL"],tc=[...Lr,"CLAUDE_CODE_MAX_CONTEXT_TOKENS","CLAUDE_CODE_USE_BEDROCK","CLAUDE_CODE_USE_VERTEX"],JI=(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
|
`)},cn=(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=JI(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 Ru}from"zod";var zI=5e3,qI=1e3,QI=1e8,eR=Ru.object({modelContext:Ru.object({contextTokens:Ru.number().int().min(qI).max(QI)}).optional()}),pg=e=>{let t=e.model;if(typeof t!="string")return;let n=t.trim();return n.length>0?n:void 0},fg=async(e,t,n,r={})=>{if(!t||!n)return;let o=r.timeoutMs??zI,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=eR.safeParse(await c.json());return l.success?l.data.modelContext?.contextTokens:void 0}catch{return}finally{clearTimeout(s)}};var tR=1e6,Za="[1m]",nR=e=>{let t=e.trim().toLowerCase();return!(t.startsWith("claude-")||t.split(/[/.]/).some(r=>r.startsWith("claude-")))},hg=(e,t)=>!e||t===void 0?{}:nR(e)?{envTokens:t}:t<tR?{}:e.toLowerCase().endsWith(Za)?{}:{model:`${e}${Za}`},mg=(e,t)=>{if(!(!e||!e.toLowerCase().endsWith(Za))&&typeof t=="string"&&!t.trim().toLowerCase().endsWith(Za))return e.slice(0,-Za.length)};import{platform as rR}from"node:os";var ln=(e=rR())=>{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"}],nc=e=>typeof e=="string"&&e.trim()!=="",oR=(e,t)=>typeof e[t]=="string"&&!nc(e[t]),yg=e=>{let t=e.env;return t&&typeof t=="object"&&!Array.isArray(t)?t:{}},aR=()=>M(ln()).catch(()=>({})),Ou=async(e={})=>{let t=e.env??process.env,n=yg(e.userSettings??{}),r=yg(await(e.readManaged??aR)().catch(()=>({}))),o=[];for(let{name:a,cloud:s}of Sn)nc(r[a])?o.push({name:a,cloud:s,kind:"managed",source:`managed settings (${ln()})`,repairable:!1}):nc(n[a])?o.push({name:a,cloud:s,kind:"userSettings",source:"~/.claude/settings.json env block",repairable:!0}):!oR(n,a)&&nc(t[a])&&o.push({name:a,cloud:s,kind:"shell",source:"shell environment",repairable:!0});return o},_u=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`,Pu=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.",gg=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 sR=Sn.map(e=>e.name),iR=tc.filter(e=>!sR.includes(e)),wg=e=>typeof e=="string"&&e.trim()!=="",bg=e=>{let t=e.env;return t&&typeof t=="object"&&!Array.isArray(t)?t:{}},cR=(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)},lR=e=>{if(typeof e=="string")try{return new URL(e.trim()).origin}catch{return}},dR=()=>M(ln()).catch(()=>({})),kg=async(e={})=>{let t=bg(e.userSettings??{}),n=bg(await(e.readManaged??dR)().catch(()=>({}))),r=[];for(let o of iR){if(!wg(n[o])||!wg(t[o]))continue;let a=o==="ANTHROPIC_BASE_URL";if(cR(n[o],t[o],a))continue;let s=a?lR(n[o]):void 0;r.push({name:o,source:`managed settings (${ln()})`,routing:a,...s?{managedOrigin:s}:{}})}return r},Ag=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`,Cg=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 uR}from"node:os";import{join as pR}from"node:path";import{readFile as fR}from"node:fs/promises";var tt=e=>!!e.keyRefreshEnabled;var hR=400,vg=async()=>{try{let e=pR(uR(),".claude","settings.json"),n=JSON.parse(await fR(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}},Sg=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}},nt=async(e="auto")=>e==="profile"?Sg():e==="claude"?vg():await vg()??await Sg(),rc=async(e={})=>{let t=e.readTarget??nt,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 tt(r)&&r.fallbackPort&&a.add(`http://${ft}:${r.fallbackPort}`),a.has(o.origin)?"owned":"foreign"},Vt=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},oc=async(e,t,n,r)=>{if(!e)return;let o=new AbortController,a=setTimeout(()=>o.abort(),hR);try{await fetch(`${e.origin}/connect/hook-savings`,{method:"POST",headers:Vt(e),body:JSON.stringify({source:t,...r?{tool:r}:{},...n}),signal:o.signal})}catch{}finally{clearTimeout(a)}};var Jn=()=>sc(ac(),".claude","settings.json"),Xa=()=>sc(ac(),".claude.json"),mR=tc,zn="anyray",yR=()=>({type:"stdio",...Ke("claude"),alwaysLoad:!0}),Dr=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),gR=e=>{if("mcpServers"in e&&!Dr(e.mcpServers))return"conflict";let t=Dr(e.mcpServers)?{...e.mcpServers}:{},n=t[zn];return n!==void 0&&!jt(n,"claude")?"conflict":(t[zn]=yR(),e.mcpServers=t,"installed")},Eg=e=>{let t=e.mcpServers;return!t||!(zn in t)||!jt(t[zn],"claude")?!1:(delete t[zn],Object.keys(t).length===0&&delete e.mcpServers,!0)},wR=e=>{qi(e,"PostToolUse",mt,vn(Ot(mt),{matcher:"*"})),qi(e,"UserPromptSubmit",Yn,vn(Ot(Yn)))},bR=e=>{qi(e,"SessionStart",Zn,vn(Ot(Zn),{async:!0}))},Ig=e=>Ro(e,"SessionStart",Zn),xg=e=>{let t=Ro(e,"PostToolUse",mt),n=Ro(e,"UserPromptSubmit",Yn),r=Ig(e);return t||n||r},kR="print-key",AR=e=>e.includes("anyray-connect")||e.includes("connect-runtime")||e.includes(Oe()),Nr=e=>{let t=e.apiKeyHelper;if(typeof t!="string")return!1;let n=t.trim().split(/\s+/);return n[n.length-1]===kR&&AR(t)},CR=async(e,t)=>{let n=(await Or(e)).env,r=n&&typeof n=="object"&&!Array.isArray(n)?n:{},o=[];for(let a of mR){let s=r[a];typeof s=="string"?(t[a]=s,o.push(a)):delete t[a]}return o},vR=e=>typeof e.apiKeyHelper=="string"&&!Nr(e),qn={id:"claude-code",title:"Claude Code",automatic:!0,async detect(){let e=sc(ac(),".claude"),t=await R(e);return{installed:t,detail:t?Jn():"no ~/.claude directory"}},async apply(e,t){let n=Jn(),r=await M(n),o=pg(r),a=await fg(e.origin,e.clientKey,o),s=hg(o,a),{env:i,subscription:c,byoUpstream:l,meta:d,headers:u}=cn(e,{contextWindowTokens:s.envTokens}),f=await Ou({userSettings:r}),p=f.filter(A=>!A.repairable),h=f.filter(A=>A.repairable),m=[...p.map(A=>`WARNING: ${_u(A)}.`),...p.length?[Pu(p)]:[],...h.map(A=>gg(A)),`${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:m};s.model!==void 0&&(r.model=s.model);let w=r.env??{};r.env={...w,...i};let g=r.env;for(let{name:A}of Sn)h.some(I=>I.name===A)?g[A]="":g[A]===""&&(process.env[A]??"").trim()===""&&delete g[A];if(u||delete g.ANTHROPIC_CUSTOM_HEADERS,c&&(w.ANTHROPIC_AUTH_TOKEN&&m.push("Removed env.ANTHROPIC_AUTH_TOKEN \u2014 it would override your subscription sign-in."),delete g.ANTHROPIC_AUTH_TOKEN),l)for(let A of ug)delete g[A];let y=!!e.clientKey,b=ie(),v=vR(r);!c&&!l&&y&&b&&!v?(r.apiKeyHelper=dg(),delete g.ANTHROPIC_AUTH_TOKEN,m.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).")):Nr(r)&&delete r.apiKeyHelper,v&&!c&&!l&&y&&b&&m.push("Kept your existing apiKeyHelper; your gateway key stays in ANTHROPIC_AUTH_TOKEN (Anyray auto-refresh via the helper is off)."),(c||l)&&y&&b?(bR(r),m.push("Installed a SessionStart hook that refreshes your gateway key each session, so an idle subscription session no longer needs re-enrollment.")):Ig(r),ie()?(wR(r),m.push("Installed a PostToolUse hook (trims oversized tool outputs, cache-safe) and a UserPromptSubmit hook (beacons oversized pasted-data prompts) \u2014 both content-free.")):(xg(r),m.push(`Skipped the Anyray hooks \u2014 anyray-connect is running from a temporary path (${Oe()}). 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 Y(n,r);let S=[n],x=Xa();try{let A=await M(x),I=!1;ie()?gR(A)==="conflict"?m.push(`MCP name conflict in ${x}: mcpServers.${zn} is not owned by Anyray Connect, so it was left untouched.`):(I=!0,m.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.")):I=Eg(A),I&&(await Y(x,A),S.push(x))}catch(A){m.push(`Could not register the Anyray MCP server in ${x} (${A instanceof Error?A.message:String(A)}); retrieval via anyray_retrieve is unavailable until this is fixed.`)}return{status:"configured",messages:m,changedFiles:S}},skillsDir(){return sc(ac(),".claude","skills")},async watchPaths(){return[Jn(),Xa()]},async pointsAt(e){let t=Jn();if(!await R(t))return!1;try{let o=(await M(t)).env?.ANTHROPIC_BASE_URL;return typeof o=="string"&&o.replace(/\/+$/,"")===e}catch{return!1}},async routingOverrides(){let e=await M(Jn()).catch(()=>({})),t=await Ou({userSettings:e}),n=await kg({userSettings:e}).catch(()=>[]);if(t.length===0&&n.length===0)return[];let r=Pu(t),o=Cg(n);return[...t.map(a=>({problem:_u(a),fix:a.repairable?"Fix: run `anyray-connect doctor --repair` (or re-run `anyray-connect`) \u2014 apply disables this switch by pinning it empty in settings.json.":r,repairable:a.repairable})),...n.map(a=>({problem:Ag(a),fix:o,repairable:!1,bypass:a.routing}))]},async mcpStatus(){let e=Xa();if(!await R(e))return{registered:!1,command:null};try{let r=(await M(e)).mcpServers?.[zn];return!r||!jt(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=Jn();if(!await R(n))e="missing";else try{let s=await M(n);if(s.hooks===void 0)e="missing";else if(!Dr(s.hooks))e="unreadable";else{let i=s.hooks.PostToolUse;e=i===void 0?"missing":Array.isArray(i)?i.some(c=>Io(c,mt))?"owned":"missing":"unreadable",e==="owned"&&Array.isArray(i)&&(t=i.some(c=>Io(c,mt)&&Dr(c)&&Array.isArray(c.hooks)&&c.hooks.some(l=>Dr(l)&&Qi(l.command,mt))))}}catch{e="unreadable"}let r,o=!0,a=Xa();if(!await R(a))r="missing";else try{let s=await M(a);if(s.mcpServers===void 0)r="missing";else if(!Dr(s.mcpServers))r="unreadable";else{let i=s.mcpServers[zn];r=i===void 0?"missing":jt(i,"claude")?"owned":"foreign",r==="owned"&&(o=ec(i,"claude"))}}catch{r="unreadable"}return{hook_registration:e,mcp_registration:r,hook_binary:t&&o&&await Tr()?"owned":"missing",beacon_target:await rc().catch(()=>"unreadable")}},async inferenceAuthLanes(){try{let e=await M(Jn()),t=Dr(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=Jn();if(!await R(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=xg(n),a=Nr(n);a&&delete n.apiKeyHelper;let s=r?await CR(t,r):[],i=mg(typeof n.model=="string"?n.model:void 0,(await Or(t)).model);i!==void 0&&(n.model=i),r&&Object.keys(r).length===0&&delete n.env,(r||o||a||i!==void 0)&&await Y(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=Xa();try{let d=await M(l);Eg(d)&&(await Y(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.126";var dn=e=>{let{command:t,args:n}=sn([e]);return{command:t,args:n}},Qn=()=>Pr();import{homedir as Rg,userInfo as SR}from"node:os";var Ja=()=>{try{return Rg()!==SR().homedir}catch{return!1}},Oo=e=>[`Skipped ${e} \u2014 HOME (${Rg()}) 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 yt=(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,za=(e=process.env)=>yt(e)!==null,kt=e=>e==="codespaces"||e==="devcontainer",er=e=>{switch(e){case"codespaces":return"a GitHub Codespace";case"devcontainer":return"a dev container";case"ssh":return"an SSH session"}};var Nu="__anyray-fallback-proxy",es="ai.anyray.connect.fallback",tr="anyray-fallback",Lg=es,Ce=8785,ts=60,$u="x-anyray-local",Mu=()=>dn(Nu),Og=Qn,cc=async(e=Ce)=>{let t=n=>new Promise(r=>{let o=IR();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)}},Lo=()=>To(Qa(),"Library","LaunchAgents",`${Lg}.plist`),ns=()=>To(Qa(),".anyray","logs"),qa=()=>To(ns(),"connect-daemon.log"),Dg=async(e,t=1048576)=>{await Pg(e).then(r=>r.size,()=>0)>t&&await xR(e).catch(()=>{})},Do=()=>To(Qa(),".config","systemd","user",`${tr}.service`),Tu=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),rs=(e=Mu())=>{let{command:t,args:n}=e,r=[t,...n].map(o=>` <string>${Tu(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}},Sg=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}},nt=async(e="auto")=>e==="profile"?Sg():e==="claude"?vg():await vg()??await Sg(),rc=async(e={})=>{let t=e.readTarget??nt,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 tt(r)&&r.fallbackPort&&a.add(`http://${ft}:${r.fallbackPort}`),a.has(o.origin)?"owned":"foreign"},Vt=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},oc=async(e,t,n,r)=>{if(!e)return;let o=new AbortController,a=setTimeout(()=>o.abort(),hR);try{await fetch(`${e.origin}/connect/hook-savings`,{method:"POST",headers:Vt(e),body:JSON.stringify({source:t,...r?{tool:r}:{},...n}),signal:o.signal})}catch{}finally{clearTimeout(a)}};var Jn=()=>sc(ac(),".claude","settings.json"),Xa=()=>sc(ac(),".claude.json"),mR=tc,zn="anyray",yR=()=>({type:"stdio",...Ke("claude"),alwaysLoad:!0}),Dr=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),gR=e=>{if("mcpServers"in e&&!Dr(e.mcpServers))return"conflict";let t=Dr(e.mcpServers)?{...e.mcpServers}:{},n=t[zn];return n!==void 0&&!jt(n,"claude")?"conflict":(t[zn]=yR(),e.mcpServers=t,"installed")},Eg=e=>{let t=e.mcpServers;return!t||!(zn in t)||!jt(t[zn],"claude")?!1:(delete t[zn],Object.keys(t).length===0&&delete e.mcpServers,!0)},wR=e=>{qi(e,"PostToolUse",mt,vn(Ot(mt),{matcher:"*"})),qi(e,"UserPromptSubmit",Yn,vn(Ot(Yn)))},bR=e=>{qi(e,"SessionStart",Zn,vn(Ot(Zn),{async:!0}))},Ig=e=>Ro(e,"SessionStart",Zn),xg=e=>{let t=Ro(e,"PostToolUse",mt),n=Ro(e,"UserPromptSubmit",Yn),r=Ig(e);return t||n||r},kR="print-key",AR=e=>e.includes("anyray-connect")||e.includes("connect-runtime")||e.includes(Oe()),Nr=e=>{let t=e.apiKeyHelper;if(typeof t!="string")return!1;let n=t.trim().split(/\s+/);return n[n.length-1]===kR&&AR(t)},CR=async(e,t)=>{let n=(await Or(e)).env,r=n&&typeof n=="object"&&!Array.isArray(n)?n:{},o=[];for(let a of mR){let s=r[a];typeof s=="string"?(t[a]=s,o.push(a)):delete t[a]}return o},vR=e=>typeof e.apiKeyHelper=="string"&&!Nr(e),qn={id:"claude-code",title:"Claude Code",automatic:!0,async detect(){let e=sc(ac(),".claude"),t=await R(e);return{installed:t,detail:t?Jn():"no ~/.claude directory"}},async apply(e,t){let n=Jn(),r=await M(n),o=pg(r),a=await fg(e.origin,e.clientKey,o),s=hg(o,a),{env:i,subscription:c,byoUpstream:l,meta:d,headers:u}=cn(e,{contextWindowTokens:s.envTokens}),f=await Ou({userSettings:r}),p=f.filter(A=>!A.repairable),h=f.filter(A=>A.repairable),m=[...p.map(A=>`WARNING: ${_u(A)}.`),...p.length?[Pu(p)]:[],...h.map(A=>gg(A)),`${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:m};s.model!==void 0&&(r.model=s.model);let w=r.env??{};r.env={...w,...i};let g=r.env;for(let{name:A}of Sn)h.some(I=>I.name===A)?g[A]="":g[A]===""&&(process.env[A]??"").trim()===""&&delete g[A];if(u||delete g.ANTHROPIC_CUSTOM_HEADERS,c&&(w.ANTHROPIC_AUTH_TOKEN&&m.push("Removed env.ANTHROPIC_AUTH_TOKEN \u2014 it would override your subscription sign-in."),delete g.ANTHROPIC_AUTH_TOKEN),l)for(let A of ug)delete g[A];let y=!!e.clientKey,b=ie(),v=vR(r);!c&&!l&&y&&b&&!v?(r.apiKeyHelper=dg(),delete g.ANTHROPIC_AUTH_TOKEN,m.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).")):Nr(r)&&delete r.apiKeyHelper,v&&!c&&!l&&y&&b&&m.push("Kept your existing apiKeyHelper; your gateway key stays in ANTHROPIC_AUTH_TOKEN (Anyray auto-refresh via the helper is off)."),(c||l)&&y&&b?(bR(r),m.push("Installed a SessionStart hook that refreshes your gateway key each session, so an idle subscription session no longer needs re-enrollment.")):Ig(r),ie()?(wR(r),m.push("Installed a PostToolUse hook (trims oversized tool outputs, cache-safe) and a UserPromptSubmit hook (beacons oversized pasted-data prompts) \u2014 both content-free.")):(xg(r),m.push(`Skipped the Anyray hooks \u2014 anyray-connect is running from a temporary path (${Oe()}). 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 Y(n,r);let S=[n],x=Xa();try{let A=await M(x),I=!1;ie()?gR(A)==="conflict"?m.push(`MCP name conflict in ${x}: mcpServers.${zn} is not owned by Anyray Connect, so it was left untouched.`):(I=!0,m.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.")):I=Eg(A),I&&(await Y(x,A),S.push(x))}catch(A){m.push(`Could not register the Anyray MCP server in ${x} (${A instanceof Error?A.message:String(A)}); retrieval via anyray_retrieve is unavailable until this is fixed.`)}return{status:"configured",messages:m,changedFiles:S}},skillsDir(){return sc(ac(),".claude","skills")},async watchPaths(){return[Jn(),Xa()]},async pointsAt(e){let t=Jn();if(!await R(t))return!1;try{let o=(await M(t)).env?.ANTHROPIC_BASE_URL;return typeof o=="string"&&o.replace(/\/+$/,"")===e}catch{return!1}},async routingOverrides(){let e=await M(Jn()).catch(()=>({})),t=await Ou({userSettings:e}),n=await kg({userSettings:e}).catch(()=>[]);if(t.length===0&&n.length===0)return[];let r=Pu(t),o=Cg(n);return[...t.map(a=>({problem:_u(a),fix:a.repairable?"Fix: run `anyray-connect doctor --repair` (or re-run `anyray-connect`) \u2014 apply disables this switch by pinning it empty in settings.json.":r,repairable:a.repairable})),...n.map(a=>({problem:Ag(a),fix:o,repairable:!1,bypass:a.routing}))]},async mcpStatus(){let e=Xa();if(!await R(e))return{registered:!1,command:null};try{let r=(await M(e)).mcpServers?.[zn];return!r||!jt(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=Jn();if(!await R(n))e="missing";else try{let s=await M(n);if(s.hooks===void 0)e="missing";else if(!Dr(s.hooks))e="unreadable";else{let i=s.hooks.PostToolUse;e=i===void 0?"missing":Array.isArray(i)?i.some(c=>Io(c,mt))?"owned":"missing":"unreadable",e==="owned"&&Array.isArray(i)&&(t=i.some(c=>Io(c,mt)&&Dr(c)&&Array.isArray(c.hooks)&&c.hooks.some(l=>Dr(l)&&Qi(l.command,mt))))}}catch{e="unreadable"}let r,o=!0,a=Xa();if(!await R(a))r="missing";else try{let s=await M(a);if(s.mcpServers===void 0)r="missing";else if(!Dr(s.mcpServers))r="unreadable";else{let i=s.mcpServers[zn];r=i===void 0?"missing":jt(i,"claude")?"owned":"foreign",r==="owned"&&(o=ec(i,"claude"))}}catch{r="unreadable"}return{hook_registration:e,mcp_registration:r,hook_binary:t&&o&&await Tr()?"owned":"missing",beacon_target:await rc().catch(()=>"unreadable")}},async inferenceAuthLanes(){try{let e=await M(Jn()),t=Dr(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=Jn();if(!await R(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=xg(n),a=Nr(n);a&&delete n.apiKeyHelper;let s=r?await CR(t,r):[],i=mg(typeof n.model=="string"?n.model:void 0,(await Or(t)).model);i!==void 0&&(n.model=i),r&&Object.keys(r).length===0&&delete n.env,(r||o||a||i!==void 0)&&await Y(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=Xa();try{let d=await M(l);Eg(d)&&(await Y(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.127";var dn=e=>{let{command:t,args:n}=sn([e]);return{command:t,args:n}},Qn=()=>Pr();import{homedir as Rg,userInfo as SR}from"node:os";var Ja=()=>{try{return Rg()!==SR().homedir}catch{return!1}},Oo=e=>[`Skipped ${e} \u2014 HOME (${Rg()}) 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 yt=(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,za=(e=process.env)=>yt(e)!==null,kt=e=>e==="codespaces"||e==="devcontainer",er=e=>{switch(e){case"codespaces":return"a GitHub Codespace";case"devcontainer":return"a dev container";case"ssh":return"an SSH session"}};var Nu="__anyray-fallback-proxy",es="ai.anyray.connect.fallback",tr="anyray-fallback",Lg=es,Ce=8785,ts=60,$u="x-anyray-local",Mu=()=>dn(Nu),Og=Qn,cc=async(e=Ce)=>{let t=n=>new Promise(r=>{let o=IR();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)}},Lo=()=>To(Qa(),"Library","LaunchAgents",`${Lg}.plist`),ns=()=>To(Qa(),".anyray","logs"),qa=()=>To(ns(),"connect-daemon.log"),Dg=async(e,t=1048576)=>{await Pg(e).then(r=>r.size,()=>0)>t&&await xR(e).catch(()=>{})},Do=()=>To(Qa(),".config","systemd","user",`${tr}.service`),Tu=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),rs=(e=Mu())=>{let{command:t,args:n}=e,r=[t,...n].map(o=>` <string>${Tu(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">
|
|
@@ -761,7 +761,7 @@ Supported on macOS, Linux and Windows.
|
|
|
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
763
|
available; on Windows, run it from a shell started as Administrator.`,Mx=e=>!!(e.endpoint&&!e.noEndpoint&&(e.sso||e.enroll)&&!e.revert&&!e.dryRun),ce=class extends Error{publicMessage;constructor(t){super(t),this.publicMessage=t,this.name="EndpointInstallError"}},_V=Qe.object({kind:Qe.enum(["pkg","deb","rpm","msi"]),path:Qe.string().min(1).refine(yV),sha256:Qe.string().regex(/^[0-9a-f]{64}$/)}).strict(),PV=Qe.object({action:Qe.literal("restart"),os:Qe.enum(["darwin","linux","win32"])}).strict(),TV=Qe.object({action:Qe.literal("configure"),os:Qe.enum(["darwin","linux","win32"]),fleetUrl:Qe.string().min(1).max(2048),enrollSecret:Qe.string().min(1).max(4096),package:_V.optional()}).strict(),LV=Qe.discriminatedUnion("action",[PV,TV]),Mi=(e,t)=>{let n=Ox(e,t,{encoding:"utf8",stdio:["ignore","pipe","pipe"],timeout:6e5,maxBuffer:1048576});return{status:n.status,stdout:typeof n.stdout=="string"?n.stdout:""}},Cy=async e=>{try{return await _x(e,Tx.F_OK),!0}catch{return!1}},DV=async e=>{try{let t=await pV(e);return t.isFile()&&t.size>0}catch{return!1}},vy=(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}},yy=(e,t)=>vy(e,t)!==null,Cx=e=>e==="win32"?Di:Ni,NV=e=>e==="win32"?Nx:Dx,$V=e=>yy(e,"ORBIT_FLEET_URL")&&yy(e,"ORBIT_ENROLL_SECRET_PATH")&&e.includes(`<string>${Ni}</string>`)&&!yy(e,"ORBIT_USE_SYSTEM_CONFIGURATION"),MV=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",Ni)&&!t("ORBIT_ENROLL_SECRET")&&!t("ORBIT_USE_SYSTEM_CONFIGURATION")},ky=(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(/&
|
|
764
|
+
`).some(o=>r===void 0?o.startsWith(`${n}=`):o.trim()===`${n}=${r}`);return t("ORBIT_FLEET_URL")&&t("ORBIT_ENROLL_SECRET_PATH",Ni)&&!t("ORBIT_ENROLL_SECRET")&&!t("ORBIT_USE_SYSTEM_CONFIGURATION")},ky=(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()},Fx=e=>{let t=e(wy,["qc",qd,"8192"]);return t.status===0?t.stdout:""},Ay=e=>{let t=e(by,RV(qd)),n=t.status===0?t.stdout.trim():"";return n.length>0?n:"absent"},FV=async e=>{try{return e==="win32"?ky(e,Fx(Mi)):ky(e,await Qd(e==="darwin"?Da:zd,"utf8"))}catch{return}},BV=async e=>{try{if(e==="win32")return await Cy($x)&&ky(e,Fx(Mi))!==void 0;let n=await Qd(e==="darwin"?Da:zd,"utf8");return e==="darwin"?$V(n):MV(n)}catch{return!1}},Bx=async(e,t={})=>{let n=t.exists??Cy,r=t.command??Mi,o,a="absent";if(e==="win32")a=Ay(r),o=await n(SV)&&a!=="absent";else{let l=e==="darwin"?await n(Da):await n("/etc/systemd/system/orbit.service")||await n("/usr/lib/systemd/system/orbit.service");o=await n(vV)&&l}let s=await(t.configured??BV)(e),i=await(t.hasNodeKey??(()=>DV(NV(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}},UV=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),Ux=(e,t)=>{let n=vy(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
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},HV=(e,t)=>{let n=Ux(e,t);return n===null?e:e.slice(0,n.start)+e.slice(n.end)},vx=(e,t,n)=>{let r=`
|
|
766
766
|
<key>${t}</key>
|
|
767
767
|
<string>${UV(n)}</string>`,o=Ux(e,t);if(o!==null)return e.slice(0,o.start)+r+e.slice(o.end);let a=vy(e,"EnvironmentVariables"),s=a===null?-1:e.indexOf("<dict>",a.end);if(a===null||s<0)throw new ce("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)},WV=(e,t,n=Ni)=>{let r=HV(e,"ORBIT_USE_SYSTEM_CONFIGURATION");return r=vx(r,"ORBIT_FLEET_URL",t),vx(r,"ORBIT_ENROLL_SECRET_PATH",n)},KV=(e,t,n=Ni)=>{let r=new Set(["ORBIT_FLEET_URL","ORBIT_ENROLL_SECRET","ORBIT_ENROLL_SECRET_PATH","ORBIT_USE_SYSTEM_CONFIGURATION"]);return`${e.split(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anyray-connect",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.127",
|
|
4
4
|
"description": "Anyray connect \u2014 points local coding tools (Claude Code, Cursor, Windsurf, SDKs) at the Anyray gateway through supported configuration and enrolled personal authentication.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|