anyray-connect 0.11.185 → 0.11.186
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 +137 -137
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -91,7 +91,7 @@ ${a}${s},`,d=`${i}${l}${c}`;try{let u=bt(d);if(!sA(u))return{ok:!1,reason:"unsup
|
|
|
91
91
|
`,{mode:384}),await ye(a,o)}catch{}finally{await SA(a,{force:!0})}},FD=async(e,t)=>{await il(mf(e,t)).catch(()=>{})},PA=async(e,t,n,r={},o={mode:"copilot-seat"})=>{let a={...xA,...r,home:r.home??Qo()},s=_n[e];if(n==="configure"&&!t?.clientKey)return{ok:!1,reason:"failed"};if(n==="configure"&&!IA(t.origin))return{ok:!1,reason:"unsafe-gateway"};let i=(o.gatewayModels??[]).filter((b,k,C)=>typeof b.id=="string"&&b.id.length>0&&b.id.length<=200&&!/[\u0000-\u001f\u007f]/.test(b.id)&&typeof b.name=="string"&&b.name.length>0&&b.name.length<=200&&!/[\u0000-\u001f\u007f]/.test(b.name)&&C.findIndex(S=>S.id===b.id)===k);if(n==="configure"&&o.mode==="gateway-api"&&i.length===0)return{ok:!1,reason:"failed"};let c=await RA(e,a);if(!c)return{ok:!1,reason:"cli-not-found"};if(n==="configure"&&c.version&&!nf(c.version))return{ok:!1,reason:"unsupported-version"};let{command:l}=c,u=await(a.listProfiles??(b=>mA(b,pf(),a.home)))(e).catch(()=>[]);if(n==="configure"&&await MD(e,t,o,u,s.slug,a).catch(()=>!1))return{ok:!0,receipt:to(a.home,s.slug),profiles:{installed:[],failed:[]},alreadyCurrent:!0};let p=a.extensionPath;if(n==="configure"){try{p??=await $D(a.home)}catch{return{ok:!1,reason:"extension-missing"}}if(!await ND(p))return{ok:!1,reason:"extension-missing"}}let m=a.nonce(),f=At(a.home,".anyray",ff,`${m}.json`),h=to(a.home,s.slug);await df(af(f),{recursive:!0,mode:448});let w=await vA(af(f)).catch(()=>[]);await uf(f,`${JSON.stringify({version:Ls,action:n,nonce:m,variant:s.slug,...n==="configure"&&{gatewayUrl:t.origin,clientKey:t.clientKey,metadata:t.metadata,mode:o.mode,gatewayModels:i},expectedExtensionVersion:un,expectedExtensionDistSha256:hr})}
|
|
92
92
|
`,{mode:384}),await RD(a.home,s.slug,w).catch(()=>{});let y={installed:[],failed:[]},g=!1;try{if(n==="configure"){let k=await TD(a.home,s.slug);if(k||await sf(l,a)!==!0)try{await a.run(l,["--install-extension",p,"--force"])}catch(C){return g=!0,{ok:!1,reason:"install-failed",detail:bA(C,m)}}for(let C of u)try{(k||await sf(l,a,C)!==!0)&&await a.run(l,["--profile",C,"--install-extension",p,"--force"]),y.installed.push(C)}catch{y.failed.push(C)}}try{await a.run(l,["--open-url",`${s.scheme}://${q}/configure?nonce=${encodeURIComponent(m)}`])}catch(k){return{ok:!1,reason:"handoff-undeliverable",detail:bA(k,m)}}let b=await DD(h,m,n,a);if(b!=="confirmed")return{ok:!1,reason:b==="reload-required"?"reload-required":"activation-timeout"};if(g=!0,n==="configure")y.failed.length===0&&await BD(a.home,s.slug,_A(t,o,u),m);else{await FD(a.home,s.slug),await OD(a.home,s.slug).catch(()=>{});for(let k of[void 0,...u])try{await a.run(l,[...k?["--profile",k]:[],"--uninstall-extension",q])}catch{}}return{ok:!0,receipt:h,profiles:y}}catch{return{ok:!1,reason:"failed"}}finally{g&&await il(f).catch(()=>{})}},cl=async(e,t=Qo())=>{try{let n=JSON.parse(await pn(to(t,_n[e].slug),"utf8"));return n.action==="reload-required"?!0:n.action==="configure"&&(n.extensionVersion!==un||n.extensionDistSha256!==hr)}catch{return!1}},ll=async(e,t=Qo())=>{try{let n=JSON.parse(await pn(to(t,_n[e].slug),"utf8"));return n.version!==Ls||n.action!=="configure"?void 0:n.mode==="copilot-seat"||n.mode==="gateway-api"?n.mode:void 0}catch{return}},DA=async(e,t,n=Qo(),r={})=>{try{let o=Ns(t);if(!o)return!1;let a=JSON.parse(await pn(to(n,_n[e].slug),"utf8"));if(!(a.version===Ls&&a.action==="configure"&&a.gatewayUrl===o&&a.extensionVersion===un&&a.extensionDistSha256===hr))return!1;let i={...xA,...r,home:n};return await OA(e,i)===!0}catch{return!1}};var fn="extensions.supportAgentsWindow",mn="chat.agentHost.byokModels.enabled",$s=e=>GD(Ne(e),"User","settings.json"),LA=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),KD=e=>LA(e)&&e[q]===!0,NA=async(e,t={})=>{let n=$s(e),r=t.read??(m=>WD(m,"utf-8")),o=t.exists??x,a=t.write??(async(m,f)=>{await VD(HD(m),{recursive:!0}),await UD(m,f,"utf-8")}),s=await o(n)?await r(n).catch(()=>{}):"{}";if(s===void 0)return{status:"manual",reason:`could not read ${n}`};s.trim()===""&&(s="{}");let i;try{i=bt(s)}catch{return{status:"manual",reason:`${n} is not valid JSON/JSONC, so it was left untouched`}}if(!LA(i))return{status:"manual",reason:`${n} is not a JSON object`};let c=s,l=!1;if(!(fn in i)){let m=ef(c,fn,{[q]:!0});if(!m.ok)return{status:"manual",reason:`could not add ${fn} to ${n} without rewriting it`};c=m.text,l=!0}if(!(mn in i)){let m=ef(c,mn,!0);if(!m.ok)return{status:"manual",reason:`could not add ${mn} to ${n} without rewriting it`};c=m.text,l=!0}l&&await a(n,c);let d=l?bt(c):i,u=KD(d[fn]),p=d[mn]===!0;return!u||!p?{status:"manual",reason:`${n} already sets ${u?mn:fn} to something else; left as it is`}:{status:"enabled",changed:l}},hf=(e,t)=>t?"Agents window: it runs on your laptop with the extensions installed there, and VS Code registers no model bridge while the agent host is remote, so this run cannot reach it. Run anyray-connect on your laptop too. Chat in this window is already routed.":e.status==="manual"?`Agents window: not enabled (${e.reason}). Add "${fn}": {"${q}": true} and "${mn}": true to that file to use Anyray models there.`:e.changed?"Agents window: enabled. It takes effect the next time VS Code starts.":"Agents window: already enabled.";import{spawnSync as jD}from"node:child_process";import{platform as ZD}from"node:os";var $A={encoding:"utf-8",windowsHide:!0,timeout:2e3,maxBuffer:64*1024},YD=(e,t,n)=>jD(e,t,n),MA=YD,JD,XD=()=>{let e=JD??ZD();if(e==="win32"){let n=MA(Rs("tasklist.exe"),["/FI","IMAGENAME eq Code.exe","/FO","CSV","/NH"],$A);return n.error||n.signal||n.status!==0?!0:/(?:^|\r?\n)"Code\.exe",/iu.test(n.stdout??"")}let t=e==="linux"?[["-f","Visual Studio Code"],["-x","code"]]:[["-f","Visual Studio Code"]];for(let[n,r]of t){let o=MA("pgrep",[n,r],$A);if(o.error||o.signal||o.status===null||o.status===0)return!0}return!1},zD=XD,Ms=()=>zD();var dl={darwinAppName:"Visual Studio Code",darwinBundleId:"com.microsoft.VSCode",win32Image:"Code.exe",linuxProcess:"code",win32Install:[{root:"localAppData",path:"Programs\\Microsoft VS Code\\Code.exe"},{root:"programFiles",path:"Microsoft VS Code\\Code.exe"},{root:"programFilesX86",path:"Microsoft VS Code\\Code.exe"}]};var yr="Anyray",hn="anyray",GA="--anyray-owner=vscode-profile-v1",Bs=e=>HA(Ne(e),"User","chatLanguageModels.json"),oL=e=>HA(Ne(e),"User","settings.json"),Fs="github.copilot.advanced",pl="debug.overrideCapiUrl",Ct=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),aL=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}},VA=e=>{let t=e[Fs];if(!Ct(t)||!aL(t[pl]))return{next:e,removed:!1};let n={...t};delete n[pl];let r={...e};return Object.keys(n).length>0?r[Fs]=n:delete r[Fs],{next:r,removed:!0}},Ws="anyray-default",Us=()=>{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:[Ws]},KA=e=>e===Ws?"Anyray Gateway":`Anyray \xB7 ${e}`.slice(0,200),ul=async e=>{if(!await x(e))return{kind:"missing"};try{let t=await UA(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"}}},jA=async(e,t)=>{await QD(rL(e),{recursive:!0});let n=`${e}.anyray-tmp-${process.pid}-${nL()}`;try{await tL(n,`${JSON.stringify(t,null,2)}
|
|
93
93
|
`,{flag:"wx",mode:384}),await ye(n,e),await qD(e,384)}finally{await eL(n,{force:!0}).catch(()=>{})}},yf=e=>{if(!Ct(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!==yr||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(!Ct(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!==KA(o.id)||typeof o.url!="string"||o.toolCalling!==!0||o.vision!==!0||o.maxInputTokens!==128e3||o.maxOutputTokens!==16e3||o.requestHeaders!==void 0&&(!Ct(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}})},gf=e=>{let t=e.filter(n=>!yf(n));return{next:t,removed:t.length!==e.length}},sL=async(e,t)=>{let n=Bs(e),r=await ul(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 "${yr}" Custom Endpoint manually if it is still listed.`]};let{next:o,removed:a}=gf(r.entries);if(!a)return{changedFiles:[],messages:[],manual:!1};if(t)return{changedFiles:[],manual:!1,messages:[`Would remove the obsolete "${yr}" Custom Endpoint from ${n}.`]};try{return await jA(n,o),await ie(n),{changedFiles:[n],manual:!1,messages:[`Removed the obsolete "${yr}" Custom Endpoint from ${n}.`]}}catch{return{changedFiles:[],manual:!0,messages:[`Could not remove the obsolete "${yr}" Custom Endpoint from ${n}; remove it manually from Manage Language Models.`]}}},iL=async e=>{try{let t=bt(await UA(e,"utf-8"));if(Ct(t))return VA(t).removed?{changedFiles:[],manual:!0,messages:[`Found the retired Anyray ${Fs}.${pl} 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 ${Fs}.${pl} value manually if present.`]}},ZA=async(e,t)=>{let n=oL(e),r;try{r=await M(n)}catch{return iL(n)}let{next:o,removed:a}=VA(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 J(n,o,{backup:!1}),await ie(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.`]}}},cL=async(e,t)=>{let n=await sL(e,t),r=await ZA(e,t);return{changedFiles:[...n.changedFiles,...r.changedFiles],messages:[...n.messages,...r.messages],manual:n.manual||r.manual}},YA=e=>{let t=e.mcpServerCommand("profile");return{type:"stdio",command:t.command,args:[...t.args,GA]}},JA=(e,t)=>{let n=Object.keys(e).sort(),r=[...t].sort();return n.length===r.length&&n.every((o,a)=>o===r[a])},XA=(e,t)=>Array.isArray(e)&&Array.isArray(t)&&e.length===t.length&&e.every((n,r)=>typeof n=="string"&&n===t[r]),lL=e=>Array.isArray(e.args)&&e.args.at(-1)===GA,zA=(e,t)=>{if(!t.hookBinaryIsDurable()||!Ct(e)||!JA(e,["type","command","args"]))return!1;let n=YA(t);return e.type==="stdio"&&e.command===n.command&&XA(e.args,n.args)},dL=(e,t)=>{if(!Ct(e)||!JA(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&&XA(e.args,n.args))return!0;if(tt(e.command))return!1;let r=e.args;if(!((r.length===2||r.length===3)&&r.at(-2)===er&&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!tt(s)&&(/(?:^|\/)anyray-connect(?:\/|$)/.test(s)||/(?:^|\/)\.anyray\/bin\/connect-runtime-[0-9A-Za-z][0-9A-Za-z.-]*\/dist\/index\.js$/.test(s))},fl=(e,t)=>zA(e,t)?"exact":Ct(e)&&lL(e)||dL(e,t)?"stale-owned":"foreign",BA=e=>`MCP name conflict in ${e}: servers.${hn} is not owned by Anyray Connect, so it was left untouched. Rename that existing server, then re-run anyray-connect to register Anyray retrieval.`,uL=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,p=[];for(let m of a)try{let f=await Ke(m),h=f.data;if(i){if("servers"in h&&!Ct(h.servers)){u=!0,l.push(`Could not register Anyray retrieval in ${m} because its servers value is not an object; left the file untouched. Repair that value, then re-run anyray-connect.`);continue}let b=Ct(h.servers)?{...h.servers}:{},k=YA(o),C=b[hn],S=C===void 0?void 0:fl(C,o);if(S==="exact"){d+=1;continue}if(S==="foreign"){u=!0,l.push(BA(m));continue}if(t){d+=1;continue}b[hn]=k,p.push({path:m,document:f,next:{...h,servers:b},backup:S!=="stale-owned",clearBackupAfter:!1});continue}if(!Ct(h.servers)||!(hn in h.servers))continue;if(fl(h.servers[hn],o)==="foreign"){u=!0,l.push(BA(m));continue}if(t)continue;let y={...h.servers};delete y[hn];let g={...h};Object.keys(y).length===0?delete g.servers:g.servers=y,p.push({path:m,document:f,next:g,backup:!1,clearBackupAfter:!0})}catch(f){u=!0,l.push(`Could not update the Anyray MCP server in ${m} (${f instanceof Error?f.name:"unknown error"}); retrieval via anyray_retrieve is unavailable in that profile.`)}if(!u&&!t)for(let m of p)try{await dn(m.path,m.document,m.next,m.backup),m.clearBackupAfter&&await ie(m.path),c.push(m.path),i&&(d+=1)}catch(f){u=!0,l.push(`Could not update the Anyray MCP server in ${m.path} (${f instanceof Error?f.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 (${uA}+).`),{changedFiles:c,messages:l,manual:u}},pL=async(e,t,n,r)=>{let o=await r.vscodeUserMcpConfigPaths(e,n),a=[],s=[],i=0;for(let c of o)if(await x(c))try{let l=await Ke(c),d=l.data;if(!Ct(d.servers)||!(hn in d.servers)||fl(d.servers[hn],r)==="foreign"||(i+=1,t))continue;let u={...d.servers};delete u[hn];let p={...d};Object.keys(u).length===0?delete p.servers:p.servers=u,await dn(c,l,p,!1),await ie(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}},qA=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.`]:[]],QA=()=>`${q} 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.)`,FA=e=>[`${q} 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."],eC=(e,t,n,r)=>({runMcp:o=>uL(e,o,t,n,r),runLegacy:o=>n?Promise.resolve({changedFiles:[],messages:[],manual:!1}):cL(e,o)}),tC=(e,t,n,r,o)=>{let a=o?` (${o})`:"";switch(e){case"install-failed":return`${t} refused to install the bundled ${q} VSIX${a}. Nothing was configured. Run \`${n?"code":t.toLowerCase()} --install-extension\` by hand on that VSIX to see the full error.`;case"handoff-undeliverable":return n?`Installed ${q} and staged its configuration, but could not hand it over${a}. A remote VS Code server's command-line launcher exposes only a subset of the desktop flags, and this step needs \`--open-url\`. Reload the VS Code window attached to this machine (Developer: Reload Window): the extension applies the staged configuration as it loads, so there is nothing to re-run.`:`Installed ${q} and staged its configuration, but could not hand it to ${t}${a}. Reload ${t} (quit and reopen): the extension applies the staged configuration as it loads, so there is nothing to re-run.`;case"reload-required":return`A newer ${q} build was installed, but ${t} is still running the previous build. Reload VS Code completely \u2014 the new build applies the staged configuration as it loads, so there is nothing to re-run.`;case"cli-not-found":return n?`Could not reach the VS Code server's command-line launcher on this machine. Run anyray-connect from the integrated terminal of the VS Code window attached here (Terminal \u2192 New Terminal in that window) \u2014 a plain SSH shell has no "code" on PATH and cannot hand the key to a running window. No VS Code configuration was written.`:`The ${t} data directory exists, but its command-line launcher was not found. Install the \u201Ccode\u201D command in PATH and re-run anyray-connect.`;case"unsupported-version":return`The Anyray language-model provider requires VS Code ${tf} or newer. Upgrade ${t}, then re-run anyray-connect; no extension configuration was written.`;case"unsafe-gateway":return"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.";case"extension-missing":return`This anyray-connect installation is missing its bundled ${q} VSIX. Reinstall a complete anyray-connect release; no Marketplace fallback was attempted.`;case"activation-timeout":return n?`${q} installed and VS Code accepted the ${r}, but its extension host never confirmed. Reload the VS Code window attached to this machine (Developer: Reload Window): the staged configuration applies as it loads.`:`${q} installed and ${t} accepted the ${r}, but its extension host never confirmed. Reload ${t} completely (quit and reopen): the staged configuration applies as it loads.`;default:return n?`VS Code did not confirm the one-time ${q} ${r}${a}. The configuration is staged: reload the VS Code window attached to this machine (Developer: Reload Window) and the extension applies it as it loads.`:`VS Code did not confirm the one-time ${q} ${r}${a}. The configuration is staged: reload ${t} (quit and reopen) and the extension applies it as it loads.`}},fL=(e,t,n,r)=>{let o=r?` (${r})`:"",a=`${q} still holds its SecretStorage configuration`;switch(e){case"cli-not-found":return n?`Could not reach the VS Code server's command-line launcher, so Anyray could not ask ${q} to clear its SecretStorage configuration. Re-run revert from the integrated terminal of the VS Code window attached to this machine.`:`The ${t} command-line launcher was not found, so Anyray could not ask ${q} to clear its SecretStorage configuration. Install the launcher and re-run revert.`;case"handoff-undeliverable":return n?`Could not hand the ${q} reset to VS Code${o}, so ${a} until it reloads. A remote VS Code server's launcher exposes only a subset of the desktop flags, and this step needs \`--open-url\` \u2014 but the reset is staged: reload the VS Code window attached to this machine (Developer: Reload Window) and the extension clears the configuration as it loads.`:`Could not hand the ${q} reset to ${t}${o}, so ${a} until it reloads. The reset is staged: quit and reopen ${t} and the extension clears the configuration as it loads.`;case"activation-timeout":return n?`VS Code accepted the ${q} reset but its extension host never confirmed, so ${a} until it reloads. The reset is staged: reload the VS Code window attached to this machine (Developer: Reload Window) and the extension clears the configuration as it loads.`:`${t} accepted the ${q} reset but its extension host never confirmed, so ${a} until it reloads. The reset is staged: quit and reopen ${t} and the extension clears the configuration as it loads.`;default:return n?`VS Code did not confirm the ${q} reset${o}, so ${a} until it reloads. The reset is staged: reload the VS Code window attached to this machine (Developer: Reload Window) and the extension clears the configuration as it loads.`:`VS Code did not confirm the ${q} reset${o}, so ${a} until it reloads. The reset is staged: quit and reopen ${t} and the extension clears the configuration as it loads.`}},mL=async(e,t,n,r,o,a,s)=>{let{runMcp:i,runLegacy:c}=eC(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 f=await c(!0),h=await i(!0);return{status:f.manual||h.manual?"manual":"configured",messages:[`Would install the bundled ${q} VSIX with the ${e} CLI and configure it through VS Code SecretStorage.`,...FA(t),a?hf({status:"enabled",changed:!0},!0):`Would enable the VS Code Agents window in ${e}'s settings.json (two keys, each added only if absent).`,...h.messages,...f.messages]}}let l=await i(!0);if(l.manual)return{status:"manual",messages:[`Did not configure ${q}; 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:[tC(d.reason,e,a,"configuration",d.detail)]};let u=await c(!1),p=await i(!1),m=a?void 0:await NA(e).catch(()=>({status:"manual",reason:"the settings file could not be read"}));return{status:u.manual||p.manual?"manual":"configured",changedFiles:[d.receipt,...p.changedFiles,...u.changedFiles,...m?.status==="enabled"&&m.changed?[$s(e)]:[]],messages:[...d.alreadyCurrent?[QA()]:[],...FA(t),hf(m??{status:"enabled",changed:!1},a),...d.alreadyCurrent?[]:qA(d.profiles),...p.messages,...u.messages]}},WA=e=>[`${q} 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: ${Us().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."],hL=async(e,t,n,r,o,a,s)=>{let{runMcp:i,runLegacy:c}=eC(e,o,a,s);if(!t.clientKey)return{status:"manual",messages:["A personal gateway key is required."]};if(n.dryRun){let m=await c(!0),f=await i(!0);return{status:m.manual||f.manual?"manual":"configured",messages:[`Would install the bundled ${q} VSIX with the ${e} CLI and configure gateway API mode through VS Code SecretStorage.`,...WA(t),...f.messages,...m.messages]}}let l=await i(!0);if(l.manual)return{status:"manual",messages:[`Did not configure ${q}; resolve the retrieval MCP profile conflicts first.`,...l.messages]};let d=await r(e,t,"configure",{},{mode:"gateway-api",gatewayModels:Us().map(m=>({id:m,name:KA(m)}))});if(!d.ok)return{status:"manual",messages:[tC(d.reason,e,a,"gateway API configuration",d.detail)]};let u=await c(!1),p=await i(!1);return{status:u.manual||p.manual?"manual":"configured",changedFiles:[d.receipt,...p.changedFiles,...u.changedFiles],messages:[...d.alreadyCurrent?[QA()]:[],...WA(t),...d.alreadyCurrent?[]:qA(d.profiles),...p.messages,...u.messages]}},yL=async(e,t,n)=>{if(!n.hookBinaryIsDurable())return{registered:!1,command:null,reason:"ephemeral-runtime"};let r=await n.vscodeUserMcpConfigPaths(e,t);if(r.length===0)return{registered:!1,command:null,reason:"no-config"};let o=[];for(let s of r){if(!await x(s))return{registered:!1,command:null,reason:"no-config"};try{let{data:i}=await Ke(s),c=Ct(i.servers)?i.servers[hn]:void 0;if(!zA(c,n))return{registered:!1,command:null,reason:c===void 0?"absent":fl(c,n)==="stale-owned"?"stale":"foreign"};o.push(c.command)}catch{return{registered:!1,command:null,reason:"unreadable"}}}let a=o[0]||null;return{registered:!0,command:o.every(s=>s===a)?a:null}};var gL=async(e={installedVariant:qo,remoteServerVariant:of,isRemoteDevContext:Gr})=>{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}},wL={installedVariant:qo,remoteServerVariant:of,detectVscodeLmProviderEligibility:gA,configureVscodeExtension:PA,vscodeExtensionPointsAt:DA,vscodeExtensionAwaitingReload:cl,vscodeExtensionReceiptMode:ll,hookBinaryIsDurable:oe,hookBinaryPath:Pe,mcpServerCommand:Ge,vscodeUserMcpConfigPaths:hA,isRemoteDevContext:Gr},bL=(e={})=>{let t={...wL,...e},n=()=>gL(t);return{id:"copilot",title:"GitHub Copilot Chat",automatic:!0,quitGated:{isRunning:Ms,quitTarget:dl},async detect(){let{variant:r,remote:o}=await n();return r?{installed:!0,detail:o?`remote server at ${zo(r,!0)}`:Bs(r)}:{installed:!1,detail:"no VS Code install found"}},async apply(r,o){if(!be(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 ${tf} or newer, then re-run anyray-connect; no extension configuration was written.`]};let c=i.version===void 0||pA(i.version);return te(r,"copilot")?mL(a,r,o,t.configureVscodeExtension,c,s,t):hL(a,r,o,t.configureVscodeExtension,c,s,t)},async mcpStatus(){let{variant:r,remote:o}=await n();return r?yL(r,o,t):{registered:!1,command:null,reason:"no-config"}},async pointsAt(r){let{variant:o}=await n();if(!o)return!1;let a=Ns(r);if(!a)return!1;if(await t.vscodeExtensionPointsAt(o,a))return!0;let s=await ul(Bs(o));if(s.kind==="array"){let c=s.entries.find(yf)?.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 ul(Bs(r));if(o.kind==="array"&&o.entries.some(yf))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 pL(o,r.dryRun,a,t),i=a?{changedFiles:[],messages:[],manual:!1}:await ZA(o,r.dryRun),c=!1,l=!1,d,u=[...i.messages];if(r.dryRun)u.push(`would ask ${q} to clear its global configuration and SecretStorage key`);else{let g=await t.configureVscodeExtension(o,void 0,"reset");g.ok?(c=!0,d=g.receipt,u.push(`Cleared ${q} gateway configuration and secret.`)):(l=!0,u.push(fL(g.reason,o,a,g.detail)))}let p=Bs(o),m=await ul(p),f=m.kind==="missing"||m.kind==="array"&&!gf(m.entries).removed,h=[...s.changedFiles,...i.changedFiles,...d?[d]:[]];if(u.push(...s.messages),f)return r.dryRun||c?{status:i.manual?"manual":"reverted",changedFiles:h.length?h:void 0,messages:u}:l||i.manual?{status:"manual",changedFiles:h.length?h:void 0,messages:u}:i.changedFiles.length||s.changedFiles.length?{status:"reverted",changedFiles:h,messages:u}:{status:"not-found",messages:["nothing to revert"]};if(m.kind==="unrecognized")return{status:"manual",changedFiles:h.length?h:void 0,messages:[...u,`Couldn't recognize ${p} \u2014 remove the "${yr}" Custom Endpoint by hand: Chat model picker \u2192 "Manage Language Models\u2026".`]};let{next:w}=gf(m.entries);if(r.dryRun)return{status:"reverted",messages:[...u,`would remove the ${yr} Custom Endpoint from ${p}`]};await jA(p,w);let y=[...u,`Removed the ${yr} Custom Endpoint from ${p}.`];return await ie(p),{status:l||i.manual?"manual":"reverted",changedFiles:[...h,p],messages:y}}}},nC=bL();import{accessSync as JL,constants as yC,statSync as XL}from"node:fs";import{readFile as gC,rm as Gs}from"node:fs/promises";import{homedir as xf,platform as EC}from"node:os";import{delimiter as zL,join as Rf,resolve as qL}from"node:path";import{execFile as SL}from"node:child_process";import{readFile as EL}from"node:fs/promises";import{homedir as Af,platform as IL}from"node:os";import{join as Hs}from"node:path";import{join as AL}from"node:path";var wf="Iv1.b507a08c87ecfe98",CL="https://github.com/login/device/code",kL="https://github.com/login/oauth/access_token",vL="read:user",rC=1e4,ea=()=>AL(ee(),"copilot-seat-login.json"),oC={fetch:(...e)=>fetch(...e),now:()=>Date.now(),sleep:e=>new Promise(t=>setTimeout(t,e))},bf=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),aC=async(e={})=>{let t={...oC,...e};try{let n=await t.fetch(CL,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({client_id:wf,scope:vL}),signal:AbortSignal.timeout(rC)});if(!n.ok)return;let r=await n.json();if(!bf(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}},sC=async(e,t={})=>{let n={...oC,...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(kL,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({client_id:wf,device_code:e.deviceCode,grant_type:"urn:ietf:params:oauth:grant-type:device_code"}),signal:AbortSignal.timeout(rC)})).json();if(!bf(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"}},iC=async(e,t)=>{let n=ea();return await we(n,`${JSON.stringify({token:e,clientId:wf,mintedAtIso:t},null,2)}
|
|
94
|
-
`),n},ml=async()=>{try{let e=await M(ea());if(!bf(e))return;let t=e.token;return typeof t=="string"&&t.length>0?t:void 0}catch{return}};var xL=5e3,Cf=5e3,RL=["copilot-cli","CopilotCLI"],OL="https://api.github.com/copilot_internal/user",lC="~/.copilot/config.json",dC="macOS Keychain (Copilot CLI)",uC=e=>e===lC||e===dC,ta=e=>typeof e=="string"&&/^[\x21-\x7e]{20,255}$/.test(e),Yt=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),TL=()=>process.env.XDG_CONFIG_HOME?.trim()||Hs(Af(),".config"),_L=()=>process.env.XDG_DATA_HOME?.trim()||Hs(Af(),".local","share"),PL=async()=>{try{let e=await EL(Hs(Af(),".copilot","config.json"),"utf-8"),t=/\bgh[ou]_[A-Za-z0-9_]{16,251}/.exec(e)?.[0];return ta(t)?t:void 0}catch{}},DL=async e=>{try{let t=await M(Hs(TL(),"github-copilot",e));if(!Yt(t))return;for(let n of Object.values(t))if(Yt(n)&&ta(n.oauth_token))return n.oauth_token}catch{}},LL=async()=>{try{let e=await M(Hs(_L(),"opencode","auth.json")),t=Yt(e)?e["github-copilot"]:void 0;if(!Yt(t)||t.type!=="oauth")return;if(ta(t.access))return t.access;if(ta(t.refresh))return t.refresh}catch{}},NL=(e,t)=>new Promise((n,r)=>{try{SL(e,[...t],{timeout:xL},(a,s)=>{a?r(a):n({stdout:s})}).on("error",r)}catch(o){r(o)}}),$L=async(e,t)=>{try{let{stdout:n}=await t("security",["find-generic-password","-s",e,"-w"]),r=n?.trim();return ta(r)?r:void 0}catch{return}},ML=async(e=NL)=>{for(let t of RL){let n=await $L(t,e);if(n)return n}};var hl={env:process.env,platform:IL,tokenFromDeviceLogin:ml,tokenFromCopilotCliConfig:PL,tokenFromSharedConfig:DL,tokenFromOpenCode:LL,tokenFromKeychain:ML,fetch:(...e)=>fetch(...e)},BL=new Set([401,403,404]),yl=/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/,pC=e=>{let t=e?.trim().toLowerCase()??"";return t&&t!=="default"&&yl.test(t)?t:"default"},FL=e=>e!=="default"&&yl.test(e)?`https://api.${e}.githubcopilot.com`:"https://api.githubcopilot.com",WL=e=>{if(typeof e!="string")return"default";let t=e.trim().match(/^https:\/\/api\.([a-z0-9-]{1,63})\.githubcopilot\.com\/?$/)?.[1];return t&&yl.test(t)?t:"default"},kf=async(e,t={})=>{let n={...hl,...t},r=new AbortController,o=setTimeout(()=>r.abort(),Cf);try{let a=await n.fetch(OL,{headers:{authorization:`Bearer ${e}`},signal:r.signal});if(a.ok){let s;try{let i=await a.json();s=Yt(i)&&Yt(i.endpoints)?i.endpoints.api:void 0}catch{}return{verdict:"valid",capiSegment:WL(s)}}return{verdict:BL.has(a.status)?"no-copilot":"unreachable",capiSegment:"default"}}catch{return{verdict:"unreachable",capiSegment:"default"}}finally{clearTimeout(o)}};var na=async(e,t={},n="default",r)=>{if(r){let o=`${r.laneOrigin.replace(/\/+$/,"")}/v1/copilot/${yl.test(n)?n:"default"}/header/models`,a=await cC(o,e,r.clientKey,t);if(a.length>0)return a}return cC(`${FL(n)}/models`,e,void 0,t)},cC=async(e,t,n,r={})=>{let o={...hl,...r},a=new AbortController,s=setTimeout(()=>a.abort(),Cf);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=Yt(c)?c.data:void 0;if(!Array.isArray(l))return[];let d=[];for(let u of l){if(!Yt(u))continue;let p=u.id;if(typeof p!="string"||p.length===0||u.model_picker_enabled!==!0)continue;let m=u.policy;if(Yt(m)&&m.state!=="enabled")continue;let f=u.supported_endpoints,h=Array.isArray(f)?f.filter(S=>typeof S=="string"):[],w=u.capabilities,y=Yt(w)?w.limits:void 0,g=S=>{let E=Yt(y)?y[S]:void 0;return typeof E=="number"&&Number.isFinite(E)&&E>0?Math.floor(E):void 0},b={id:p,endpoints:h},k=g("max_prompt_tokens"),C=g("max_output_tokens");k!==void 0&&(b.maxPromptTokens=k),C!==void 0&&(b.maxOutputTokens=C),d.push(b)}return d}catch{return[]}finally{clearTimeout(s)}},gl=async(e,t,n,r={})=>{let o={...hl,...r},a=new AbortController,s=setTimeout(()=>a.abort(),Cf);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)}},wl=async(e={},t={})=>{let n={...hl,...t},r=[{source:"COPILOT_GITHUB_TOKEN",read:async()=>{let a=n.env.COPILOT_GITHUB_TOKEN?.trim();return ta(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:dC,read:()=>n.tokenFromKeychain()}]:[],{source:lC,read:()=>n.tokenFromCopilotCliConfig()}],o=[];for(let a of r){let s=await a.read();if(!s)continue;let i=await kf(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}};import{homedir as bl,platform as mC}from"node:os";import{join as st}from"node:path";import{execFile as UL}from"node:child_process";import{readFile as HL,readdir as GL}from"node:fs/promises";var VL=3e3,KL="Claude Code-credentials",jL=["copilot-cli","CopilotCLI"],hC=e=>new Promise(t=>{try{UL("security",["find-generic-password","-s",e],{timeout:VL},r=>t(!r)).on("error",()=>t(!1))}catch{t(!1)}}),ZL=async()=>{if(process.env.CLAUDE_CODE_OAUTH_TOKEN?.trim())return!0;let e=st(bl(),".claude");return!!(await x(st(e,".oauth_token"))||await x(st(e,".credentials.json"))||mC()==="darwin"&&await hC(KL))},YL=async()=>{let e=st(process.env.CODEX_HOME?.trim()||st(bl(),".codex"),"auth.json");if(!await x(e))return!1;try{let t=JSON.parse(await HL(e,"utf-8"));return typeof t.tokens?.access_token=="string"&&t.tokens.access_token.trim()!==""}catch{return!1}},fC=async e=>{try{return(await GL(e)).some(n=>n.startsWith("github.copilot-chat-"))}catch{return!1}},vf=async()=>{if(process.env.COPILOT_GITHUB_TOKEN?.trim())return!0;for(let t of eo){let n=st(Ne(t),"User","globalStorage");if(await x(st(n,"github.copilot-chat"))||await x(st(n,"github.copilot")))return!0}let e=st(bl(),".config","github-copilot");if(await x(st(e,"apps.json"))||await x(st(e,"hosts.json")))return!0;for(let t of[".vscode",".vscode-insiders"])if(await fC(st(bl(),t,"extensions")))return!0;for(let t of eo){if(await fC(yA(t)))return!0;let n=st(zo(t,!0),"globalStorage");if(await x(st(n,"github.copilot-chat"))||await x(st(n,"github.copilot")))return!0}if(mC()==="darwin"){for(let t of jL)if(await hC(t))return!0}return!1},yn=async()=>{let[e,t,n]=await Promise.all([ZL(),YL(),vf()]);return{anthropic:e,openai:t,copilot:n}};var oo="copilot-cli",gn="copilot-cli",QL=Ms,eN=()=>QL()?["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."]:[],IC=["Editor-Version: vscode/1.99.0","Editor-Plugin-Version: copilot-chat/0.26.7","Copilot-Integration-Id: vscode-chat"],Of=()=>Object.fromEntries(IC.map(e=>{let t=e.indexOf(": ");return[e.slice(0,t).toLowerCase(),e.slice(t+2)]})),wC=()=>Rf(xf(),".anyray","copilot-cli.sh"),xC="# Managed by anyray-connect. Do not source this file anywhere else.",bC=e=>e.split(/\r?\n/,1)[0]===xC,tN=["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"],Al="COPILOT_PROVIDER_API_KEY",AC=e=>e.startsWith(`export ${Al}=`)||e.startsWith("export COPILOT_PROVIDER_HEADERS=")&&e.includes("x-anyray-api-key:"),Dn=e=>/(^|\/)(gpt-5|o[1-9])[\w.-]*$/.test(e)?"responses":"completions",nN=()=>Us()[0],Vs=(e="default")=>`/copilot/${e}/header`,
|
|
94
|
+
`),n},ml=async()=>{try{let e=await M(ea());if(!bf(e))return;let t=e.token;return typeof t=="string"&&t.length>0?t:void 0}catch{return}};var xL=5e3,Cf=5e3,RL=["copilot-cli","CopilotCLI"],OL="https://api.github.com/copilot_internal/user",lC="~/.copilot/config.json",dC="macOS Keychain (Copilot CLI)",uC=e=>e===lC||e===dC,ta=e=>typeof e=="string"&&/^[\x21-\x7e]{20,255}$/.test(e),Yt=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),TL=()=>process.env.XDG_CONFIG_HOME?.trim()||Hs(Af(),".config"),_L=()=>process.env.XDG_DATA_HOME?.trim()||Hs(Af(),".local","share"),PL=async()=>{try{let e=await EL(Hs(Af(),".copilot","config.json"),"utf-8"),t=/\bgh[ou]_[A-Za-z0-9_]{16,251}/.exec(e)?.[0];return ta(t)?t:void 0}catch{}},DL=async e=>{try{let t=await M(Hs(TL(),"github-copilot",e));if(!Yt(t))return;for(let n of Object.values(t))if(Yt(n)&&ta(n.oauth_token))return n.oauth_token}catch{}},LL=async()=>{try{let e=await M(Hs(_L(),"opencode","auth.json")),t=Yt(e)?e["github-copilot"]:void 0;if(!Yt(t)||t.type!=="oauth")return;if(ta(t.access))return t.access;if(ta(t.refresh))return t.refresh}catch{}},NL=(e,t)=>new Promise((n,r)=>{try{SL(e,[...t],{timeout:xL},(a,s)=>{a?r(a):n({stdout:s})}).on("error",r)}catch(o){r(o)}}),$L=async(e,t)=>{try{let{stdout:n}=await t("security",["find-generic-password","-s",e,"-w"]),r=n?.trim();return ta(r)?r:void 0}catch{return}},ML=async(e=NL)=>{for(let t of RL){let n=await $L(t,e);if(n)return n}};var hl={env:process.env,platform:IL,tokenFromDeviceLogin:ml,tokenFromCopilotCliConfig:PL,tokenFromSharedConfig:DL,tokenFromOpenCode:LL,tokenFromKeychain:ML,fetch:(...e)=>fetch(...e)},BL=new Set([401,403,404]),yl=/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/,pC=e=>{let t=e?.trim().toLowerCase()??"";return t&&t!=="default"&&yl.test(t)?t:"default"},FL=e=>e!=="default"&&yl.test(e)?`https://api.${e}.githubcopilot.com`:"https://api.githubcopilot.com",WL=e=>{if(typeof e!="string")return"default";let t=e.trim().match(/^https:\/\/api\.([a-z0-9-]{1,63})\.githubcopilot\.com\/?$/)?.[1];return t&&yl.test(t)?t:"default"},kf=async(e,t={})=>{let n={...hl,...t},r=new AbortController,o=setTimeout(()=>r.abort(),Cf);try{let a=await n.fetch(OL,{headers:{authorization:`Bearer ${e}`},signal:r.signal});if(a.ok){let s;try{let i=await a.json();s=Yt(i)&&Yt(i.endpoints)?i.endpoints.api:void 0}catch{}return{verdict:"valid",capiSegment:WL(s)}}return{verdict:BL.has(a.status)?"no-copilot":"unreachable",capiSegment:"default"}}catch{return{verdict:"unreachable",capiSegment:"default"}}finally{clearTimeout(o)}};var na=async(e,t={},n="default",r)=>{if(r){let o=`${r.laneOrigin.replace(/\/+$/,"")}/v1/copilot/${yl.test(n)?n:"default"}/header/models`,a=await cC(o,e,r.clientKey,t);if(a.length>0)return a}return cC(`${FL(n)}/models`,e,void 0,t)},cC=async(e,t,n,r={})=>{let o={...hl,...r},a=new AbortController,s=setTimeout(()=>a.abort(),Cf);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=Yt(c)?c.data:void 0;if(!Array.isArray(l))return[];let d=[];for(let u of l){if(!Yt(u))continue;let p=u.id;if(typeof p!="string"||p.length===0||u.model_picker_enabled!==!0)continue;let m=u.policy;if(Yt(m)&&m.state!=="enabled")continue;let f=u.supported_endpoints,h=Array.isArray(f)?f.filter(S=>typeof S=="string"):[],w=u.capabilities,y=Yt(w)?w.limits:void 0,g=S=>{let E=Yt(y)?y[S]:void 0;return typeof E=="number"&&Number.isFinite(E)&&E>0?Math.floor(E):void 0},b={id:p,endpoints:h},k=g("max_prompt_tokens"),C=g("max_output_tokens");k!==void 0&&(b.maxPromptTokens=k),C!==void 0&&(b.maxOutputTokens=C),d.push(b)}return d}catch{return[]}finally{clearTimeout(s)}},gl=async(e,t,n,r={})=>{let o={...hl,...r},a=new AbortController,s=setTimeout(()=>a.abort(),Cf);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)}},wl=async(e={},t={})=>{let n={...hl,...t},r=[{source:"COPILOT_GITHUB_TOKEN",read:async()=>{let a=n.env.COPILOT_GITHUB_TOKEN?.trim();return ta(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:dC,read:()=>n.tokenFromKeychain()}]:[],{source:lC,read:()=>n.tokenFromCopilotCliConfig()}],o=[];for(let a of r){let s=await a.read();if(!s)continue;let i=await kf(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}};import{homedir as bl,platform as mC}from"node:os";import{join as st}from"node:path";import{execFile as UL}from"node:child_process";import{readFile as HL,readdir as GL}from"node:fs/promises";var VL=3e3,KL="Claude Code-credentials",jL=["copilot-cli","CopilotCLI"],hC=e=>new Promise(t=>{try{UL("security",["find-generic-password","-s",e],{timeout:VL},r=>t(!r)).on("error",()=>t(!1))}catch{t(!1)}}),ZL=async()=>{if(process.env.CLAUDE_CODE_OAUTH_TOKEN?.trim())return!0;let e=st(bl(),".claude");return!!(await x(st(e,".oauth_token"))||await x(st(e,".credentials.json"))||mC()==="darwin"&&await hC(KL))},YL=async()=>{let e=st(process.env.CODEX_HOME?.trim()||st(bl(),".codex"),"auth.json");if(!await x(e))return!1;try{let t=JSON.parse(await HL(e,"utf-8"));return typeof t.tokens?.access_token=="string"&&t.tokens.access_token.trim()!==""}catch{return!1}},fC=async e=>{try{return(await GL(e)).some(n=>n.startsWith("github.copilot-chat-"))}catch{return!1}},vf=async()=>{if(process.env.COPILOT_GITHUB_TOKEN?.trim())return!0;for(let t of eo){let n=st(Ne(t),"User","globalStorage");if(await x(st(n,"github.copilot-chat"))||await x(st(n,"github.copilot")))return!0}let e=st(bl(),".config","github-copilot");if(await x(st(e,"apps.json"))||await x(st(e,"hosts.json")))return!0;for(let t of[".vscode",".vscode-insiders"])if(await fC(st(bl(),t,"extensions")))return!0;for(let t of eo){if(await fC(yA(t)))return!0;let n=st(zo(t,!0),"globalStorage");if(await x(st(n,"github.copilot-chat"))||await x(st(n,"github.copilot")))return!0}if(mC()==="darwin"){for(let t of jL)if(await hC(t))return!0}return!1},yn=async()=>{let[e,t,n]=await Promise.all([ZL(),YL(),vf()]);return{anthropic:e,openai:t,copilot:n}};var oo="copilot-cli",gn="copilot-cli",QL=Ms,eN=()=>QL()?["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."]:[],IC=["Editor-Version: vscode/1.99.0","Editor-Plugin-Version: copilot-chat/0.26.7","Copilot-Integration-Id: vscode-chat"],Of=()=>Object.fromEntries(IC.map(e=>{let t=e.indexOf(": ");return[e.slice(0,t).toLowerCase(),e.slice(t+2)]})),wC=()=>Rf(xf(),".anyray","copilot-cli.sh"),xC="# Managed by anyray-connect. Do not source this file anywhere else.",bC=e=>e.split(/\r?\n/,1)[0]===xC,tN=["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"],Al="COPILOT_PROVIDER_API_KEY",AC=e=>e.startsWith(`export ${Al}=`)||e.startsWith("export COPILOT_PROVIDER_HEADERS=")&&e.includes("x-anyray-api-key:"),Dn=e=>/(^|\/)(gpt-5|o[1-9])[\w.-]*$/.test(e)?"responses":"completions",nN=()=>Us()[0],Vs=(e="default")=>`/copilot/${e}/header`,Qq=Vs(),no=e=>e.replace(/\/+$/,""),rN=(e,t="default")=>`${no(e.openaiBaseUrl)}${Vs(t)}`,Sf=e=>/\/v1\/copilot\/[^/]+\/header\/?$/.test(e),If="claude-sonnet-5",oN=()=>{let e=Us()[0];return e===Ws?If:e},RC=e=>e.endpoints.includes(Dn(e.id)==="responses"?"/responses":"/chat/completions"),Tf=e=>{let t=e.filter(RC),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)=>CC(a.version,s.version)?-1:CC(s.version,a.version)?1:0).map(a=>a.m),o=t.filter(a=>!n(a.id));return[...r,...o]};var CC=(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},kC=(e,t,n,r,o,a="default")=>{let s=fe({...e.metadata,tool:oo}),i=[...r?[`x-anyray-api-key: ${r}`]:[],...s?[`x-anyray-metadata: ${s}`]:[],...IC];return["export COPILOT_PROVIDER_TYPE='openai'",`export COPILOT_PROVIDER_BASE_URL=${Ie(rN(e,a))}`,`export COPILOT_PROVIDER_WIRE_API='${Dn(t)}'`,`export COPILOT_MODEL=${Ie(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=${Ie(i.join(`
|
|
95
95
|
`))}`]:[],`export ${Al}=${Ie(n)}`]},Ef=(e,t,n)=>{let r=fe({...e.metadata,tool:oo});return["export COPILOT_PROVIDER_TYPE='openai'",`export COPILOT_PROVIDER_BASE_URL=${Ie(e.openaiBaseUrl)}`,`export COPILOT_PROVIDER_WIRE_API='${Dn(t)}'`,`export COPILOT_MODEL=${Ie(t)}`,...r?[`export COPILOT_PROVIDER_HEADERS=${Ie(`x-anyray-metadata: ${r}`)}`]:[],...n?[`export ${Al}=${Ie(n)}`]:[]]},aN=(e,t)=>t||!te(e,"copilot"),vC=()=>{let e=tN.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).`]},SC=(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 ${oo}\`), 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`."],sN=(e=process.env.PATH,t=EC())=>{if(!e)return;let n=t==="win32"?"copilot.exe":"copilot";for(let r of e.split(zL)){let o=r.trim().replace(/^"|"$/g,"");if(!o)continue;let a=qL(o,n);try{if(!XL(a).isFile())continue;return JL(a,t==="win32"?yC.F_OK:yC.X_OK),a}catch{}}},iN=()=>Rf(xf(),".copilot","config.json"),Pn=()=>Rf(xf(),".copilot","mcp-config.json"),ro="anyray",cN=()=>({type:"local",...Ge("profile"),tools:["*"]}),gr=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),lN=async()=>{let e=Pn(),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&&!gr(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=(gr(t.mcpServers)?t.mcpServers:{})[ro];return r!==void 0&&!Tt(r,"profile")?{status:"skipped",message:`MCP name conflict in ${e}: mcpServers.${ro} is not owned by Anyray Connect, so retrieval was skipped and the existing server was left untouched.`}:{status:"installable",json:t}},dN=async e=>{let t=Pn(),n=e.json,r=gr(n.mcpServers)?n.mcpServers:{};r[ro]=cN(),n.mcpServers=r,await J(t,n)},uN=async()=>{let e=Pn(),t;try{let r=await M(e);if(!gr(r))return!1;t=r}catch{return!1}let n=t.mcpServers;return!gr(n)||!(ro in n)||!Tt(n[ro],"profile")?!1:(delete n[ro],Object.keys(n).length===0&&delete t.mcpServers,Object.keys(t).length===0?await Gs(e,{force:!0}):await J(e,t,{backup:!1}),await ie(e),!0)},pN={resolveCopilotCommand:sN,platform:EC,detectCopilotSeat:vf,discoverSeatToken:wl,readDeviceLoginToken:ml,fetchSeatModelCatalog:na,probeSeatChatModel:gl},fN=e=>`'${e.replace(/'/g,"''")}'`,mN=e=>e.split(`
|
|
96
96
|
`).map(fN).join(" + [Environment]::NewLine + "),hN=(e={})=>{let t={...pN,...e},n=()=>t.platform()==="win32",r=async()=>{let i=(await Wc(wt(),gn))?.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&&no(s)===`${no(i)}/v1`,a=(s,i)=>s!==void 0&&Sf(s)&&no(s).startsWith(`${no(i)}/v1/copilot/`);return{id:oo,title:"GitHub Copilot CLI",automatic:!0,changesBilling:!1,quitGated:{isRunning:Ms,quitTarget:dl},async detect(){let s=t.resolveCopilotCommand();if(s)return{installed:!0,detail:s};let i=iN();return await x(i)?{installed:!0,detail:i}:{installed:!1,detail:"no `copilot` on PATH and no ~/.copilot state"}},async apply(s,i){let c=wt(),l=async(S,E,I)=>{let _=S.filter(AC),T=S.filter(re=>!AC(re)),W=wC(),Q=[...T,..._.length>0?[`[ -r ${Ie(W)} ] && . ${Ie(W)}`]:[]],G=await x(W),ne=G?await gC(W,"utf8"):void 0,z=ne===void 0||bC(ne);if(_.length>0&&!z)return{status:"manual",messages:[`Refused to overwrite user-managed ${W}; move or rename that file, then run Connect again.`]};let j=oe(),le=j?await lN():void 0,U=[`${c} \u2190 managed Anyray block (${gn})`,...E.map(re=>` ${re}`),..._.length>0?[`${W} \u2190 owner-only credential (mode 0600)`]:[],...I,le?.status==="skipped"?le.message:j?`${Pn()} \u2190 Anyray retrieval MCP server (anyray_retrieve / anyray_recall)`:`Skipped the Anyray MCP server \u2014 anyray-connect is running from a temporary path (${Pe()}). 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.`,...eN()];if(i.dryRun)return{status:"configured",messages:U};let Y=!1;le?.status==="installable"&&(await dN(le),Y=!0);try{_.length>0?await we(W,[xC,..._,""].join(`
|
|
97
97
|
`)):G&&z&&await Gs(W,{force:!0}),await Fc(c,Q,gn)}catch(re){try{ne!==void 0&&z?await we(W,ne):z&&await Gs(W,{force:!0})}catch{throw new Error("Copilot CLI environment update failed and credential rollback could not be completed")}throw re}return{status:"configured",messages:U,changedFiles:[c,..._.length>0||G&&z?[W]:[],...Y?[Pn()]:[]]}},d=await r(),u=d!==void 0&&!Sf(d),p=s.authMode==="placeholder",m=u,f=u&&(!m||!te(s,"copilot")),h=p?void 0:await t.readDeviceLoginToken().catch(()=>{}),w=p||f&&!h?{rejected:[]}:await t.discoverSeatToken({allowKeychainPrompt:i.explicit===!0&&!i.dryRun}),y=w.token,g=w.rejected;if(y){let S=w.capiSegment??"default",E=oN(),I=E!==If||!!process.env.ANYRAY_COPILOT_MODEL,_=await t.fetchSeatModelCatalog(y.token,{},S,{laneOrigin:no(s.origin),...s.clientKey?{clientKey:s.clientKey}:{}}),T=_.find(U=>U.id===E);if(!I){let U=Tf(_);if(T=U[0],!i.dryRun&&U.length>0){let Y=ve=>`${no(s.origin)}/v1${Vs(S)}/${Dn(ve)==="responses"?"responses":"chat/completions"}`,re={...Of(),authorization:`Bearer ${y.token}`,...s.clientKey?{"x-anyray-api-key":s.clientKey}:{}},Qe=new Set,Oe;for(let ve of U.slice(0,4)){let ut=await t.probeSeatChatModel(Y(ve.id),re,ve.id);if(ut==="ok"){Oe=ve;break}if(ut==="unreachable")break;Qe.add(ve.id)}T=Oe??U.find(ve=>!Qe.has(ve.id))??U[0]}E=T?.id??If}let W=s.clientKey??s.placeholderKey,Q=W&&s.clientKey?Pt(W):W,G=kC(s,E,y.token,W,T,S),ne=kC(s,E,Pt(y.token),Q,T,S),z=Dn(E),j=_.filter(U=>RC(U)&&Dn(U.id)===z).map(U=>U.id).filter(U=>U!==E),le=[`Mode: Copilot seat \u2014 requests route through the gateway's Copilot carrier lane and stay billed to your Copilot plan (seat token from ${y.source}).`,`Model: ${E}${I?" (pinned via ANYRAY_COPILOT_MODEL)":_.length>0?" (your plan's default class; pin via ANYRAY_COPILOT_MODEL)":" (seat-lane fallback; pin via ANYRAY_COPILOT_MODEL)"}.`,..._.length===0&&uC(y.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."]:[],...j.length>0?[`Your plan also serves: ${j.slice(0,8).join(", ")}${j.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",...ne.map(U=>{let Y=U.indexOf("="),re=U.slice(7,Y),Qe=U.slice(Y+1).replace(/^'|'$/g,"");return` [Environment]::SetEnvironmentVariable('${re}', ${mN(Qe)}, 'User')`}),`(secrets are shown masked \u2014 substitute the Copilot token from ${y.source}, and the gateway key from \`anyray-connect print-key\`.)`,...le]}:l(G,ne,le)}if(!aN(s,f)){if(m&&!i.dryRun){let S=wt();if(await vs(S,gn))return{status:"reverted",changedFiles:[S],messages:[`removed a stale Anyray ${gn} block from ${S}`,"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:",...SC(t.platform(),g),...vC()]}}return{status:"held",messages:[...m&&i.dryRun?[`would remove a stale Anyray ${gn} block from ${wt()} (org lane, not chosen)`]:[],...SC(t.platform(),g)]}}let b=nN(),k=s.clientKey??s.placeholderKey,C=k&&s.clientKey?Pt(k):k;return n()?{status:"manual",messages:["Windows: set these for your user, then restart your terminal \u2014",...Ef(s,b,C).map(S=>{let[E,...I]=S.replace(/^export /,"").split("=");return` setx ${E} "${I.join("=").replace(/^'|'$/g,"")}"`}),...s.clientKey?[`(${Al} is shown masked \u2014 substitute the real one from \`anyray-connect print-key\`.)`]:[]]}:l(Ef(s,b,k),Ef(s,b,C),["Mode: BYOK \u2014 Copilot CLI requests are billed as org API usage through the gateway, not against your Copilot subscription.",`Model: ${b}${b===Ws?" (the gateway resolves the org default)":" (pinned via ANYRAY_COPILOT_MODEL)"}.`])},async revert(s){let i=wt(),c=wC(),l=await x(c),d=l?bC(await gC(c,"utf8")):!1;if(s.dryRun)return{status:"reverted",messages:[`would remove the Anyray ${gn} block from ${i}`,...d?[`would remove owner-only credential ${c}`]:l?[`would preserve user-managed ${c}`]:[],`would remove the Anyray MCP server from ${Pn()} if registered`,...await x(ea())?[`would remove the Copilot sign-in Connect minted (${ea()})`]:[]]};let u=await vs(i,gn);d&&await Gs(c,{force:!0});let p=await uN(),m=ea(),f=await x(m);f&&await Gs(m,{force:!0});let h=[...u?[i]:[],...d?[c]:[],...p?[Pn()]:[],...f?[m]:[]];return{status:h.length>0?"reverted":"not-found",messages:[u?`removed the Anyray ${gn} block from ${i}`:`no Anyray ${gn} block found in ${i}`,...d?[`removed owner-only credential ${c}`]:l?[`preserved user-managed ${c}`]:[],...f?[`removed the Copilot sign-in Connect minted (${m})`]:[],...p?[`removed the Anyray MCP server from ${Pn()}`]:[],...vC()],changedFiles:h.length>0?h:void 0}},async pointsAt(s){let i=await r();return o(i,s)||a(i,s)},async mcpStatus(){if(!oe())return{registered:!1,command:null,reason:"ephemeral-runtime"};let s=Pn();if(!await x(s))return{registered:!1,command:null,reason:"no-config"};try{let i=await M(s),c=gr(i)?i.mcpServers:void 0,l=gr(c)?c[ro]:void 0;return!gr(l)||!Tt(l,"profile")?{registered:!1,command:null,reason:l===void 0?"absent":"foreign"}:{registered:!0,command:typeof l.command=="string"?l.command:null}}catch{return{registered:!1,command:null,reason:"unreadable"}}},async inferenceAuthLanes(){try{let s=await r();return s===void 0?["native"]:Sf(s)?["subscription"]:["api_key"]}catch{return["unknown"]}},async routingExpected(s){return s.includes(oo)?!0:!await t.detectCopilotSeat()}}},OC=hN();import{homedir as $C}from"node:os";import{join as br}from"node:path";import{readFile as MC}from"node:fs/promises";import{readFile as TC,rm as yN}from"node:fs/promises";var _C="// Managed by anyray-connect: OpenCode trim carrier v1",gN=5e3,_f=e=>`${_C}
|
|
@@ -167,22 +167,22 @@ export const AnyrayTrimPlugin = async () => ({
|
|
|
167
167
|
})
|
|
168
168
|
`,Ks=async e=>await x(e)?(await TC(e,"utf-8")).startsWith(`${_C}
|
|
169
169
|
`)?"owned":"foreign":"absent",PC=async(e,t)=>{let n=_f(t),r=await Ks(e);return r==="foreign"?"foreign":r==="owned"&&await TC(e,"utf-8")===n?"unchanged":(await we(e,n),"installed")},Pf=async e=>{let t=await Ks(e);return t!=="owned"?t:(await yN(e,{force:!0}),"removed")};var Df="https://opencode.ai/config.json",$n="x-anyray-metadata",Lt="x-anyray-api-key",Lf=["x-anyray-provider","x-anyray-auth-mode","x-anyray-custom-host"],Ln="Authorization",wr=["anthropic","openai"],Mn="github-copilot",wN="header",Nn="anyray",bN=()=>process.env.XDG_CONFIG_HOME?.trim()||br($C(),".config"),AN=()=>process.env.XDG_DATA_HOME?.trim()||br($C(),".local","share"),vl=()=>br(bN(),"opencode"),Cl=()=>br(vl(),"plugins","anyrayTrim.js"),BC=()=>br(AN(),"opencode"),FC=async()=>{try{let e=await MC(br(BC(),"auth.json"),"utf-8"),t=e.trim()?JSON.parse(e):{};return F(t)?{chatGptOAuth:F(t.openai)&&t.openai.type==="oauth",readable:!0}:{chatGptOAuth:!1,readable:!1}}catch(e){return e.code==="ENOENT"?{chatGptOAuth:!1,readable:!0}:{chatGptOAuth:!1,readable:!1}}},DC=async()=>(await FC()).chatGptOAuth,CN=["opencode.jsonc","opencode.json","config.json"],ra=async()=>{let e=vl(),t=[];for(let n of CN){let r=br(e,n);await x(r)&&t.push(r)}return t},LC=async()=>(await ra())[0]??br(vl(),"opencode.json"),Nf=()=>pC(process.env.ANYRAY_COPILOT_PLAN),$f=e=>`${e.origin.replace(/\/+$/,"")}/v1/copilot/${Nf()}/${wN}`,F=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),Uf=(e,t)=>{if(typeof e!="string")return!1;let n=e.replace(/\/+$/,""),r=t.replace(/\/+$/,"");return n===r||n.startsWith(`${r}/`)},kN=(e,t)=>Object.entries(e).flatMap(([n,r])=>n===wr[0]||n===wr[1]||n===Mn?[]:F(r)&&F(r.options)&&Uf(r.options.baseURL,t)?[n]:[]),Mf=/claude/i,Hf=["model","small_model"],WC=(e,t)=>{if(typeof e!="string")return;let n=e.indexOf("/");if(n<=0)return;let r=e.slice(0,n),o=e.slice(n+1);if(!(!t.includes(r)||!Mf.test(o)))return`${wr[0]}/${o}`},Bf=(e,t=[])=>{if(Array.isArray(e)){for(let n of e)Bf(n,t);return t}if(!F(e))return t;for(let[n,r]of Object.entries(e))Hf.includes(n)&&typeof r=="string"?t.push(r):Bf(r,t);return t},vN=(e,t,n)=>{if(!F(e)||!F(e.models))return!1;let r=Object.keys(e.models);if(r.length===0||!r.every(a=>Mf.test(a)))return!1;let o=`${n}/`;return Bf(t).filter(a=>a.startsWith(o)).every(a=>Mf.test(a.slice(o.length)))},Ff=(e,t,n)=>{if(Array.isArray(e))return e.map(o=>Ff(o,t,n));if(!F(e))return e;let r={};for(let[o,a]of Object.entries(e)){let s=Hf.includes(o)?WC(a,t):void 0;s!==void 0?(r[o]=s,n.push(`${String(a)} \u2192 ${s}`)):r[o]=Ff(a,t,n)}return r},Wf=(e,t,n)=>{if(Array.isArray(e)&&Array.isArray(t))return e.map((o,a)=>Wf(o,t[a],n));if(!F(e)||!F(t))return e;let r={};for(let[o,a]of Object.entries(e))Hf.includes(o)&&typeof a=="string"&&WC(t[o],n)===a?r[o]=t[o]:r[o]=Wf(a,t[o],n);return r},SN=e=>{if(F(e))for(let t of wr){let n=e[t];if(F(n)&&F(n.options)&&typeof n.options.baseURL=="string")return n.options.baseURL.replace(/\/+$/,"").replace(/\/v1$/,"")}},js=e=>{if(!F(e)||!Array.isArray(e.command))return!1;let[t,...n]=e.command;return typeof t=="string"&&Tt({command:t,args:n},"profile")},kl=e=>typeof e=="string"&&(e.startsWith("ark_")||e==="anyray-placeholder"),EN=e=>{if(typeof e!="string")return!1;try{let t=JSON.parse(e);return F(t)&&t.tool==="opencode"}catch{return!1}},Gf=e=>te(e,"copilot")&&!!e.clientKey,IN=e=>e.byoUpstream?[]:te(e,"anthropic")?[`Note: OpenCode can't route your personal Claude subscription \u2014 its Anthropic provider is api-key only, so this uses the gateway's server-held provider key (API billing). For your personal subscription use Claude Code; otherwise make sure an org provider key is set on the gateway, or requests will fail upstream with "invalid x-api-key".`]:[],xN=(e,t)=>te(e,"openai")?[`OpenAI subscription: OpenCode's built-in ChatGPT Pro/Plus OAuth is ${t?"detected":"not signed in yet (run `opencode auth login`)"}. Its Codex endpoint is hard-coded to chatgpt.com, so provider.baseURL cannot redirect it. Connect leaves machine networking untouched. Use the Codex app/CLI/IDE for ChatGPT subscription pass-through, or sign OpenCode into an API-key/Copilot provider that Connect can route.`]:[],RN=e=>Gf(e)?["Tip: to spend your Copilot subscription (incl. Claude & GPT), pick the github-copilot/* models in OpenCode \u2014 e.g. github-copilot/claude-sonnet-4.5. The anthropic/* and openai/* entries are the direct providers (api-key mode, separate billing) \u2014 not your Copilot plan."]:[],ON=(e,t,n)=>{let r={...e};Object.keys(e).length===0&&(r.$schema=Df);let o=!1;if(n)if("mcp"in r&&!F(r.mcp))o=!0;else{let g=F(r.mcp)?{...r.mcp}:{},b=g[Nn];b!==void 0&&!js(b)?o=!0:(g[Nn]={type:"local",command:[n.command,...n.args],enabled:!0},r.mcp=g)}else if(F(r.mcp)&&js(r.mcp[Nn])){let g={...r.mcp};delete g[Nn],Object.keys(g).length===0?delete r.mcp:r.mcp=g}let a=F(r.provider)?{...r.provider}:{},s=kN(a,t.origin),i=s.every(g=>vN(a[g],e,g))?s:[],c=s.filter(g=>!i.includes(g)),l=[];if(i.length>0){for(let g of i)delete a[g];r=Ff(r,i,l)}let d=[],u=[],p=t.openaiBaseUrl,m=t.clientKey??t.placeholderKey,f=fe({...t.metadata,tool:"opencode"});for(let g of c){let b={...a[g]},k={...b.options};if("headers"in k&&!F(k.headers)){u.push(g);continue}let C=F(k.headers)?{...k.headers}:{},S=!1;for(let[E,I]of[[Lt,m],...f?[[$n,f]]:[]])E in C?(typeof C[E]!="string"||C[E].trim()==="")&&u.push(`${g}.${E}`):(C[E]=I,d.push(`${g}.${E}`),S=!0);S&&(k.headers=C,b.options=k,a[g]=b)}let h=c.length>0?[]:wr.filter(g=>g!=="openai"||!te(t,"openai")),w=t.byoUpstream;for(let g of h){let b=F(a[g])?{...a[g]}:{},k=F(b.options)?{...b.options}:{};k.baseURL=p;let C=F(k.headers)?{...k.headers}:{};if(g==="anthropic"&&w)k.apiKey=w.key,C[Ln]=`Bearer ${w.key}`,C["x-anyray-provider"]="anthropic",C["x-anyray-auth-mode"]="passthrough",C["x-anyray-custom-host"]=w.url;else{k.apiKey=m,"x-anyray-custom-host"in C&&delete C[Ln];for(let S of Lf)delete C[S]}C[Lt]=m,f&&(C[$n]=f),k.headers=C,b.options=k,a[g]=b}let y=c.length===0&&Gf(t);if(y){let g=F(a[Mn])?{...a[Mn]}:{},b=F(g.options)?{...g.options}:{};b.baseURL=$f(t);let k=F(b.headers)?{...b.headers}:{};k[Lt]=t.clientKey,f&&(k[$n]=f),b.headers=k,g.options=b,a[Mn]=g}return Object.keys(a).length>0&&(r.provider=a),{next:r,copilot:y,customProviders:c,migratedProviders:i,modelRefsRemapped:l,customHeadersAdded:d,customHeaderConflicts:u,mcpConflict:o}},TN=["baseURL","apiKey"],NC=(e,t,n,r,o=!1,a=!1)=>{let s=e[t];if(!F(s)||!F(s.options))return!1;let i={...s},c={...s.options},l=!1;if(n){let d=typeof c.baseURL=="string"&&c.baseURL.includes("/v1/copilot/"),u=F(c.headers)?{...c.headers}:void 0,p=u?.[Lt],m=kl(p);if(d&&(delete c.baseURL,l=!0),u&&(d||m)){let f=u,h=F(r)?r.options:void 0,w=F(h)&&F(h.headers)?h.headers:void 0;for(let y of[Lt,$n])w&&y in w?f[y]!==w[y]&&(f[y]=w[y],l=!0):y in f&&(delete f[y],l=!0);Object.keys(f).length===0?delete c.headers:c.headers=f}}else{let d=F(r)?r.options:void 0,u=F(d)?d:{},p=F(c.headers)?c.headers:{},m=c.apiKey==="anyray-placeholder"||a&&typeof c.apiKey=="string"&&c.apiKey.startsWith("ark_")||typeof p[Lt]=="string"||typeof p[$n]=="string"||Lf.some(f=>f in p);if(!o&&!m)return!1;for(let f of TN)f in u?c[f]!==u[f]&&(c[f]=u[f],l=!0):f in c&&(delete c[f],l=!0);if(F(c.headers)){let f={...c.headers},h=F(u.headers)?u.headers:{};"x-anyray-custom-host"in f&&Ln in f&&(Ln in h?f[Ln]!==h[Ln]&&(f[Ln]=h[Ln],l=!0):(delete f[Ln],l=!0));for(let w of[Lt,$n,...Lf])w in h?f[w]!==h[w]&&(f[w]=h[w],l=!0):w in f&&(delete f[w],l=!0);Object.keys(f).length===0?delete c.headers:c.headers=f}}return l?(Object.keys(c).length===0?delete i.options:i.options=c,Object.keys(i).length===0?delete e[t]:e[t]=i,!0):!1},_N=(e,t,n)=>{let r=e[t];if(!F(r)||!F(r.options)||!F(n)||!F(n.options))return!1;let o={...r.options};if(!F(o.headers)||"headers"in n.options&&!F(n.options.headers))return!1;let a={...o.headers},s=F(n.options.headers)?n.options.headers:{},i=!1;return!(Lt in s)&&kl(a[Lt])&&(delete a[Lt],i=!0),!($n in s)&&EN(a[$n])&&(delete a[$n],i=!0),i?(Object.keys(a).length===0?"headers"in n.options?o.headers=s:delete o.headers:o.headers=a,e[t]={...r,options:o},!0):!1},PN=(e,t)=>{let n={...e},r=!1,o=SN(e.provider);if(F(n.mcp)&&js(n.mcp[Nn])){let c={...n.mcp};delete c[Nn],Object.keys(c).length===0?delete n.mcp:n.mcp=c,r=!0}if(!F(n.provider))return{next:n,removed:r};let a={...n.provider},s=F(t?.provider)?t.provider:{},i=t===void 0&&n.$schema===Df&&wr.every(c=>{let l=a[c];return F(l)&&F(l.options)&&typeof l.options.baseURL=="string"&&typeof l.options.apiKey=="string"&&l.options.apiKey.startsWith("ark_")});for(let c of wr)NC(a,c,!1,s[c],t!==void 0,i)&&(r=!0);if(t!==void 0){let c=new Set([...wr,Mn]),l=[];for(let d of Object.keys(s)){if(c.has(d))continue;_N(a,d,s[d])&&(r=!0);let u=s[d];!(d in a)&&o!==void 0&&F(u)&&F(u.options)&&Uf(u.options.baseURL,o)&&(a[d]=u,l.push(d),r=!0)}l.length>0&&(n=Wf(n,t,l))}return NC(a,Mn,!0,s[Mn])&&(r=!0),Object.keys(a).length===0?delete n.provider:n.provider=a,t!==void 0&&!("$schema"in t)&&n.$schema===Df&&(delete n.$schema,r=!0),{next:n,removed:r}},UC={id:"opencode",title:"OpenCode",automatic:!0,async detect(){let e=vl(),t=BC(),n=await x(e)||await x(t),r=n&&await DC();return{installed:n,detail:n?`${await LC()}${r?" (ChatGPT Pro/Plus OAuth detected)":""}`:"no ~/.config/opencode or ~/.local/share/opencode"}},async apply(e,t){let n=await LC(),r=e.openaiBaseUrl,o=fe({...e.metadata,tool:"opencode"}),a=Gf(e),s=te(e,"openai"),i=await DC(),c;try{c=await Ke(n)}catch{return e.clientKey?{status:"manual",messages:[`Couldn't parse ${n} \u2014 set it by hand. Under "provider", add:`,e.byoUpstream?` "anthropic": { "options": { "baseURL": ${JSON.stringify(r)}, "apiKey": "<your upstream key>", "headers": { "Authorization": "Bearer <your upstream key>", "x-anyray-auth-mode": "passthrough", "x-anyray-provider": "anthropic", "x-anyray-custom-host": ${JSON.stringify(e.byoUpstream.url)}, "x-anyray-api-key": "<your personal ark_ key>" } } }`:` "anthropic": { "options": { "baseURL": ${JSON.stringify(r)}, "apiKey": "<your personal ark_ key>" } }`,...s?[]:[` "openai": { "options": { "baseURL": ${JSON.stringify(r)}, "apiKey": "<your personal ark_ key>" } }`],...a?[` "github-copilot": { "options": { "baseURL": ${JSON.stringify($f(e))}, "headers": { "${Lt}": "<your personal ark_ key>" } } }`]:[]]}:{status:"manual",messages:[`Couldn't parse ${n}; left it untouched. Enroll with --enroll or --sso before configuring OpenCode.`]}}let l=await Wr()?Ge("profile"):void 0,{next:d,customProviders:u,migratedProviders:p,modelRefsRemapped:m,customHeadersAdded:f,customHeaderConflicts:h,mcpConflict:w}=ON(c.data,e,l),y=u.length>0,g=p.length>0?[`${t.dryRun?"Would migrate":"Migrated"} ${p.map(I=>`provider.${I}`).join(", ")} \u2014 a hand-rolled ${e.origin} route serving only Claude models \u2014 onto the managed anthropic lane; pick models under anthropic/* from now on.`,...m.length>0?[`Updated model references: ${m.join(", ")}.`]:[],"The original block is kept in the .anyray-bak backup; `anyray-connect revert` restores it."]:[],b=y?[`${n} already routes through ${e.origin} via ${u.map(I=>`provider.${I}`).join(", ")}; existing provider values were preserved.`,f.length>0?`${t.dryRun?"Would add":"Added"} only the missing Anyray authentication/attribution headers: ${f.join(", ")}.`:"Existing Anyray authentication and attribution headers were preserved.",...h.length>0?[`Could not safely add required headers at ${h.join(", ")} because the existing values have incompatible shapes. Fix those values manually; no existing value was replaced.`]:[],"Canonical anthropic, openai, and github-copilot provider blocks were left untouched.","Restart OpenCode (or start a new session) to pick up the change."]:[...g,s?`${n} \u2192 provider.anthropic options.baseURL = ${r}; provider.openai left untouched because OpenCode's ChatGPT OAuth loader has no configurable endpoint.`:`${n} \u2192 provider.anthropic + provider.openai options.baseURL = ${r}`,e.byoUpstream?`Auth (anthropic): your personal upstream key (written to the config, not shown here) \u2014 the gateway forwards it verbatim to ${e.byoUpstream.url} (must be in the gateway's custom-host allowlist).`:e.clientKey?"Auth: your personal gateway key (written to the config, not shown here) \u2014 the gateway swaps in the server-held provider key.":"Enrollment required before a real apply; the gateway does not accept a shared placeholder.",`Attribution: ${o??"(none \u2014 pass --user, or --enroll for a per-user key)"}`,...IN(e),...xN(e,i),a?`provider.github-copilot options.baseURL \u2192 ${$f(e)} with the personal gateway key in options.headers (never the URL). OpenCode keeps its Copilot sign-in, GitHub bills your plan, and the gateway meters it. ${Nf()==="default"?"Uses GitHub\u2019s documented all-plan Copilot API host automatically.":`Uses the ${Nf()} plan-specific host selected by ANYRAY_COPILOT_PLAN.`}`:"GitHub Copilot: not routed \u2014 needs a Copilot seat plus enrollment (a detected Copilot plan or --subscription, and --enroll for the seat key).",...RN(e),"Restart OpenCode (or start a new session) to pick up the change."];w?b.push(`MCP name conflict in ${n}: mcp.${Nn} is not owned by Anyray Connect, so it was left untouched.`):l&&b.push("Registered the Anyray retrieval MCP server (anyray_retrieve) for explicit recovery of stashed context.");let k=h.length>0?"manual":"configured";if(t.dryRun)return{status:k,messages:b};let S=await dn(n,c,d,!0)?[n]:[],E=Cl();if(oe())try{let I=await PC(E,fs(Je,["opencode"]));I==="foreign"?b.push(`Skipped the OpenCode trim carrier because ${E} already exists and is not owned by Anyray.`):(I==="installed"&&S.push(E),b.push(`The OpenCode tool.execute.after carrier is active in ${E}; oversized string tool outputs run through the shared __anyray-hook before OpenCode stores them.`))}catch{b.push(`Could not install the OpenCode trim carrier in ${E}. Gateway-side optimization remains active.`)}else{try{await Pf(E)==="removed"&&S.push(E)}catch{}b.push(`Skipped the OpenCode trim carrier \u2014 anyray-connect is running from a temporary path (${Pe()}). Re-run via the installer or a global install to enable cache-safe source trimming.`)}return{status:k,messages:b,changedFiles:S}},async pointsAt(e){for(let t of await ra())try{let{data:n}=await Ke(t);if(!F(n.provider))continue;for(let r of Object.values(n.provider))if(!(!F(r)||!F(r.options))&&Uf(r.options.baseURL,e))return!0}catch{}return!1},async mcpStatus(){if(!oe())return{registered:!1,command:null,reason:"ephemeral-runtime"};let e=await ra();if(e.length===0)return{registered:!1,command:null,reason:"no-config"};let t=!1,n=!1;for(let r of e)try{let{data:o}=await Ke(r);if(!F(o.mcp))continue;let a=o.mcp[Nn];if(!js(a)||!F(a)){a!==void 0&&(t=!0);continue}return{registered:!0,command:Array.isArray(a.command)&&typeof a.command[0]=="string"?a.command[0]:null}}catch{n=!0}return{registered:!1,command:null,reason:t?"foreign":n?"unreadable":"absent"}},async integrationStatus(){let e,t=!0;try{let i=await Ks(Cl());e=i==="absent"?"missing":i,e==="owned"&&(t=await MC(Cl(),"utf-8")===_f(fs(Je,["opencode"])))}catch{e="unreadable"}let n=!1,r=!1,o=!1,a=!0;for(let i of await ra()){let c;try{c=await Ke(i)}catch{o=!0;continue}if(c.data.mcp===void 0)continue;if(!F(c.data.mcp)){o=!0;continue}let l=c.data.mcp[Nn];if(l!==void 0)if(js(l))if(n=!0,!F(l)||!Array.isArray(l.command))a=!1;else{let[d,...u]=l.command;uc({command:d,args:u},"profile")||(a=!1)}else r=!0}return{hook_registration:e,mcp_registration:o?"unreadable":r?"foreign":n?"owned":"missing",hook_binary:t&&a&&await Wr()?"owned":"missing"}},async inferenceAuthLanes(){let e=new Set;try{let t=await FC(),n=t.chatGptOAuth;t.readable||e.add("unknown"),n&&e.add("native");for(let r of await ra()){let{data:o}=await Ke(r);if(F(o.provider))for(let[a,s]of Object.entries(o.provider)){if(!F(s)||!F(s.options)){e.add("unknown");continue}let i=s.options,c=F(i.headers)?i.headers:{};if(a===Mn&&typeof i.baseURL=="string"&&i.baseURL.includes("/v1/copilot/")){e.add("subscription");continue}if(a==="openai"&&n&&i.baseURL===void 0&&i.apiKey===void 0){e.add("native");continue}if(a===Mn&&i.baseURL===void 0&&i.apiKey===void 0){e.add("native");continue}if(typeof c["x-anyray-custom-host"]=="string"){e.add("byo");continue}if(c["x-anyray-auth-mode"]==="passthrough"){e.add("subscription");continue}if(kl(c[Lt])||kl(i.apiKey)||typeof i.apiKey=="string"&&i.apiKey.length>0||typeof c.Authorization=="string"&&c.Authorization.length>0){e.add("api_key");continue}e.add("unknown")}}}catch{e.add("unknown")}return e.size>0?[...e]:["unknown"]},async revert(e){let t=await ra(),n=Cl(),r="absent";try{r=await Ks(n)}catch{}if(t.length===0&&r!=="owned")return{status:"not-found",messages:["nothing to revert"]};if(e.dryRun)return{status:"reverted",messages:[...t.map(i=>`would remove Anyray provider settings from ${i}`),...r==="owned"?[`would remove the Anyray OpenCode trim carrier from ${n}`]:[]]};let o=[],a=[],s=[];for(let i of t){let c;try{c=await Ke(i)}catch{s.push(i);continue}let{next:l,removed:d}=PN(c.data,await Jo(i));d&&(await dn(i,c,l,!1),a.push(i),o.push(`removed Anyray provider settings from ${i}`)),await ie(i)}for(let i of s)o.push(`Couldn't parse ${i} \u2014 if you added Anyray settings there by hand, remove the baseURL/apiKey from provider.anthropic, provider.openai, and provider.github-copilot yourself.`);if(r==="owned")try{await Pf(n)==="removed"&&(a.push(n),o.push(`removed the Anyray OpenCode trim carrier from ${n}`))}catch{o.push(`Could not remove the Anyray OpenCode trim carrier from ${n}. Remove that file manually.`)}return a.length===0&&s.length===0&&o.push("no Anyray provider settings found"),{status:a.length===0&&s.length>0?"manual":"reverted",messages:o,changedFiles:a.length?a:void 0}}};import{homedir as Xf}from"node:os";import{join as Ol}from"node:path";import{homedir as DN}from"node:os";import{dirname as LN,join as Ar}from"node:path";import{mkdir as NN,readdir as $N,readFile as GC,rm as VC}from"node:fs/promises";var Vf="48ff8bb9a7afde1d9e8468d632f84b46f199e6a28657833b113de93698d9ac63",HC=[{path:"openclaw.plugin.json",contentBase64:"ewogICJpZCI6ICJhbnlyYXkiLAogICJuYW1lIjogIkFueXJheSIsCiAgImRlc2NyaXB0aW9uIjogIlJvdXRlIE9wZW5DbGF3J3MgbW9kZWwgY2FsbHMgdGhyb3VnaCB5b3VyIG9yZ2FuaXphdGlvbidzIEFueXJheSBnYXRld2F5IHdpdGggcGVyLXNlc3Npb24gaWRlbnRpdHkgYW5kIGNvbnRlbnQtZnJlZSBhdHRyaWJ1dGlvbi4iLAogICJhY3RpdmF0aW9uIjogewogICAgIm9uU3RhcnR1cCI6IHRydWUKICB9LAogICJwcm92aWRlcnMiOiBbImFueXJheSJdLAogICJzZXR1cCI6IHsKICAgICJwcm92aWRlcnMiOiBbCiAgICAgIHsKICAgICAgICAiaWQiOiAiYW55cmF5IiwKICAgICAgICAiZW52VmFycyI6IFsiQU5ZUkFZX0FQSV9LRVkiLCAiQU5ZUkFZX0NMSUVOVF9LRVkiXQogICAgICB9CiAgICBdCiAgfSwKICAicHJvdmlkZXJBdXRoQ2hvaWNlcyI6IFsKICAgIHsKICAgICAgInByb3ZpZGVyIjogImFueXJheSIsCiAgICAgICJtZXRob2QiOiAiYXBpLWtleSIsCiAgICAgICJjaG9pY2VJZCI6ICJhbnlyYXktYXBpLWtleSIsCiAgICAgICJjaG9pY2VMYWJlbCI6ICJBbnlyYXkgY2xpZW50IGtleSIsCiAgICAgICJjaG9pY2VIaW50IjogIlBlcnNvbmFsIGFya18ga2V5IGZyb20gYW55cmF5LWNvbm5lY3QgZW5yb2xsbWVudCIsCiAgICAgICJncm91cElkIjogImFueXJheSIsCiAgICAgICJncm91cExhYmVsIjogIkFueXJheSIsCiAgICAgICJvcHRpb25LZXkiOiAiYW55cmF5QXBpS2V5IiwKICAgICAgImNsaUZsYWciOiAiLS1hbnlyYXktYXBpLWtleSIKICAgIH0KICBdLAogICJtb2RlbENhdGFsb2ciOiB7CiAgICAiZGlzY292ZXJ5IjogewogICAgICAiYW55cmF5IjogInJlZnJlc2hhYmxlIgogICAgfSwKICAgICJwcm92aWRlcnMiOiB7CiAgICAgICJhbnlyYXkiOiB7CiAgICAgICAgImJhc2VVcmwiOiAiaHR0cHM6Ly91bmNvbmZpZ3VyZWQuZ2F0ZXdheS5pbnZhbGlkIiwKICAgICAgICAiYXBpIjogImFudGhyb3BpYy1tZXNzYWdlcyIsCiAgICAgICAgImRlZmF1bHRNb2RlbCI6ICJjbGF1ZGUtc29ubmV0LTQtNSIsCiAgICAgICAgIm1vZGVscyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImlkIjogImNsYXVkZS1zb25uZXQtNC01IiwKICAgICAgICAgICAgIm5hbWUiOiAiQ2xhdWRlIFNvbm5ldCA0LjUgKEFueXJheSkiLAogICAgICAgICAgICAicmVhc29uaW5nIjogdHJ1ZSwKICAgICAgICAgICAgImlucHV0IjogWyJ0ZXh0IiwgImltYWdlIl0sCiAgICAgICAgICAgICJjb250ZXh0V2luZG93IjogMjAwMDAwLAogICAgICAgICAgICAibWF4VG9rZW5zIjogNjQwMDAKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICJjbGF1ZGUtaGFpa3UtNC01IiwKICAgICAgICAgICAgIm5hbWUiOiAiQ2xhdWRlIEhhaWt1IDQuNSAoQW55cmF5KSIsCiAgICAgICAgICAgICJyZWFzb25pbmciOiB0cnVlLAogICAgICAgICAgICAiaW5wdXQiOiBbInRleHQiLCAiaW1hZ2UiXSwKICAgICAgICAgICAgImNvbnRleHRXaW5kb3ciOiAyMDAwMDAsCiAgICAgICAgICAgICJtYXhUb2tlbnMiOiA2NDAwMAogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImlkIjogImNsYXVkZS1vcHVzLTQtOCIsCiAgICAgICAgICAgICJuYW1lIjogIkNsYXVkZSBPcHVzIDQuOCAoQW55cmF5KSIsCiAgICAgICAgICAgICJyZWFzb25pbmciOiB0cnVlLAogICAgICAgICAgICAiaW5wdXQiOiBbInRleHQiLCAiaW1hZ2UiXSwKICAgICAgICAgICAgImNvbnRleHRXaW5kb3ciOiAyMDAwMDAsCiAgICAgICAgICAgICJtYXhUb2tlbnMiOiAzMjAwMAogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgImlkIjogImdyb2stNC42IiwKICAgICAgICAgICAgIm5hbWUiOiAiR3JvayA0LjYgKEFueXJheSkiLAogICAgICAgICAgICAicmVhc29uaW5nIjogdHJ1ZSwKICAgICAgICAgICAgImlucHV0IjogWyJ0ZXh0IiwgImltYWdlIl0sCiAgICAgICAgICAgICJjb250ZXh0V2luZG93IjogNTAwMDAwLAogICAgICAgICAgICAibWF4VG9rZW5zIjogMTI4MDAwCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiZ3Jvay00LjMiLAogICAgICAgICAgICAibmFtZSI6ICJHcm9rIDQuMyAoQW55cmF5KSIsCiAgICAgICAgICAgICJyZWFzb25pbmciOiB0cnVlLAogICAgICAgICAgICAiaW5wdXQiOiBbInRleHQiLCAiaW1hZ2UiXSwKICAgICAgICAgICAgImNvbnRleHRXaW5kb3ciOiAxMDAwMDAwLAogICAgICAgICAgICAibWF4VG9rZW5zIjogMTI4MDAwCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiZ3Jvay1idWlsZC0wLjEiLAogICAgICAgICAgICAibmFtZSI6ICJHcm9rIEJ1aWxkIDAuMSAoQW55cmF5KSIsCiAgICAgICAgICAgICJyZWFzb25pbmciOiB0cnVlLAogICAgICAgICAgICAiaW5wdXQiOiBbInRleHQiLCAiaW1hZ2UiXSwKICAgICAgICAgICAgImNvbnRleHRXaW5kb3ciOiAyNTYwMDAsCiAgICAgICAgICAgICJtYXhUb2tlbnMiOiAxMjgwMDAKICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0KICAgIH0KICB9LAogICJjb25maWdTY2hlbWEiOiB7CiAgICAidHlwZSI6ICJvYmplY3QiLAogICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogZmFsc2UsCiAgICAicmVxdWlyZWQiOiBbImdhdGV3YXlVcmwiXSwKICAgICJwcm9wZXJ0aWVzIjogewogICAgICAiZ2F0ZXdheVVybCI6IHsKICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJBbnlyYXkgZ2F0ZXdheSBvcmlnaW4sIGUuZy4gaHR0cHM6Ly9nYXRld2F5LmV4YW1wbGUuYW55cmF5LmFpIChubyAvdjEgc3VmZml4KS4iCiAgICAgIH0sCiAgICAgICJhcGlLZXkiOiB7CiAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiUGVyc29uYWwgQW55cmF5IGNsaWVudCBrZXkgKGFya1/igKYpLiBTdXBwb3J0cyAke0VOVl9WQVJ9IHN1YnN0aXR1dGlvbjsgZGVmYXVsdHMgdG8gJHtBTllSQVlfQ0xJRU5UX0tFWX0uIgogICAgICB9LAogICAgICAidXNlciI6IHsKICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJBdHRyaWJ1dGlvbiB1c2VyIChjb250ZW50LWZyZWU7IHVzdWFsbHkgYW4gZW1haWwpLiBPcHRpb25hbCDigJQgdGhlIGNsaWVudCBrZXkgYWxyZWFkeSBhdHRyaWJ1dGVzIHRoZSBlbnJvbGxlZCB1c2VyLiIKICAgICAgfSwKICAgICAgInRlYW0iOiB7CiAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiQXR0cmlidXRpb24gdGVhbSAoY29udGVudC1mcmVlKS4gT3B0aW9uYWwuIgogICAgICB9CiAgICB9LAogICAgInVpSGludHMiOiB7CiAgICAgICJnYXRld2F5VXJsIjogewogICAgICAgICJsYWJlbCI6ICJHYXRld2F5IFVSTCIsCiAgICAgICAgImhlbHAiOiAiWW91ciBvcmdhbml6YXRpb24ncyBBbnlyYXkgZ2F0ZXdheSBvcmlnaW4uIgogICAgICB9LAogICAgICAiYXBpS2V5IjogewogICAgICAgICJsYWJlbCI6ICJDbGllbnQga2V5IiwKICAgICAgICAiaGVscCI6ICJQZXJzb25hbCBhcmtfIGtleSBmcm9tIGFueXJheS1jb25uZWN0IGVucm9sbG1lbnQuIExlYXZlIHVuc2V0IHRvIHJlYWQgJEFOWVJBWV9DTElFTlRfS0VZLiIKICAgICAgfQogICAgfQogIH0KfQo="},{path:"package.json",contentBase64:"ewogICJuYW1lIjogIkBhbnlyYXkvb3BlbmNsYXctcGx1Z2luIiwKICAidmVyc2lvbiI6ICIwLjMuMCIsCiAgInByaXZhdGUiOiB0cnVlLAogICJkZXNjcmlwdGlvbiI6ICJPcGVuQ2xhdyBwcm92aWRlciBwbHVnaW4gZm9yIHRoZSBBbnlyYXkgZ2F0ZXdheSDigJQgcGVyLXNlc3Npb24gaWRlbnRpdHksIGF0dHJpYnV0aW9uLCBhbmQgY2FjaGUtc2FmZSBkZWZhdWx0cyBvbiBldmVyeSBtb2RlbCBjYWxsLiIsCiAgInR5cGUiOiAibW9kdWxlIiwKICAibWFpbiI6ICIuL3NyYy9pbmRleC50cyIsCiAgInNjcmlwdHMiOiB7CiAgICAiYnVpbGQiOiAidHNjIC1wIHRzY29uZmlnLmpzb24iLAogICAgInRlc3QiOiAibm9kZSAtLXRlc3QgLS1pbXBvcnQgdHN4ICdzcmMvKi50ZXN0LnRzJyIKICB9LAogICJvcGVuY2xhdyI6IHsKICAgICJleHRlbnNpb25zIjogWyIuL3NyYy9pbmRleC50cyJdLAogICAgImNvbXBhdCI6IHsKICAgICAgIm1pbkdhdGV3YXlWZXJzaW9uIjogIjIwMjYuNy4xIgogICAgfQogIH0sCiAgInBlZXJEZXBlbmRlbmNpZXMiOiB7CiAgICAib3BlbmNsYXciOiAiPj0yMDI2LjcuMSIKICB9LAogICJkZXZEZXBlbmRlbmNpZXMiOiB7CiAgICAidHN4IjogIl40LjIzLjEyIiwKICAgICJ0eXBlc2NyaXB0IjogIl41LjYuMyIKICB9Cn0K"},{path:"src/index.ts",contentBase64:"LyoqCiAqIEFueXJheSBPcGVuQ2xhdyBwbHVnaW4g4oCUIHJvdXRlcyBPcGVuQ2xhdydzIG1vZGVsIGNhbGxzIHRocm91Z2ggYW4gb3JnJ3MKICogQW55cmF5IGdhdGV3YXkgYXMgdGhlIGBhbnlyYXlgIHByb3ZpZGVyLgogKgogKiBXaGF0IGl0IGFkZHMgb3ZlciB0aGUgcGxhaW4gYG1vZGVscy5wcm92aWRlcnNgIGNvbmZpZyB0aGUgY29ubmVjdCBhZGFwdGVyCiAqIHdyaXRlczoKICogIC0gcGVyLWNhbGwgc2Vzc2lvbiBpZGVudGl0eSAoYG1ldGFkYXRhLnVzZXJfaWRgKSB2aWEgdGhlIHN0cmVhbSB3cmFwcGVyLCBzbwogKiAgICB0aGUgZ2F0ZXdheSBnZXRzIENsYXVkZSBDb2RlLWdyYWRlIHBlci1jb252ZXJzYXRpb24gb3B0aW1pemVyIHNlc3Npb25zCiAqICAgIGluc3RlYWQgb2YgYW5jaG9yIGZpbmdlcnByaW50czsKICogIC0gYSBjYWNoZS1yZXRlbnRpb24gZGVmYXVsdCBvbiBldmVyeSBjYWxsIChPcGVuQ2xhdyBoYXMgbm8gYXV0by1zZWVkIG9uCiAqICAgIGN1c3RvbSBob3N0cyk7CiAqICAtIHRoZSB3aG9sZSBwcm92aWRlciBlbnRyeSAoYmFzZSBVUkwsIGFwaSBraW5kLCBwZXItbW9kZWwgbWF4VG9rZW5zLCBiZXRhCiAqICAgIHJlc3RvcmUsIGF0dHJpYnV0aW9uIGhlYWRlcnMpIGNvbnRyaWJ1dGVkIGZyb20gb25lIHBsdWdpbiBjb25maWcgYmxvY2suCiAqCiAqIFRoZSBtYW5pZmVzdCdzIHN0YXRpYyBgbW9kZWxDYXRhbG9nYCBibG9jayBpcyB3aGF0IE9wZW5DbGF3IG1hdGVyaWFsaXplcyBmb3IKICogbW9kZWwgZGlzY292ZXJ5IGJlZm9yZSB0aGlzIHJ1bnRpbWUgY2F0YWxvZyByZXNvbHZlcyAobGl2ZS1jb250YWluZXIgZmFjdDoKICogd2l0aG91dCBpdCwgYGFueXJheS8qYCByZWZzIGFyZSB1bmtub3duIHRvIHRoZSBhZ2VudCBydW50aW1lKTsgdGhlIHJ1bnRpbWUKICogYGNhdGFsb2cucnVuYCB0aGVuIHN1cHBsaWVzIHRoZSByZWFsIGdhdGV3YXkgY29vcmRpbmF0ZXMgZnJvbSBwbHVnaW4gY29uZmlnLgogKgogKiBQUklWQUNZOiBldmVyeXRoaW5nIGluamVjdGVkIGlzIGNvbnRlbnQtZnJlZSDigJQgYW4gb3BhcXVlIHNlc3Npb24gaWQgaGFzaCwKICogdGhlIGVucm9sbG1lbnQga2V5LCBhbmQgdXNlci90ZWFtIGF0dHJpYnV0aW9uIHRoZSBvcGVyYXRvciBjb25maWd1cmVkLgogKi8KCmltcG9ydCB7IGRlZmluZVNpbmdsZVByb3ZpZGVyUGx1Z2luRW50cnkgfSBmcm9tICdvcGVuY2xhdy9wbHVnaW4tc2RrL3Byb3ZpZGVyLWVudHJ5JzsKaW1wb3J0IHR5cGUgeyBQcm92aWRlckNhdGFsb2dDb250ZXh0IH0gZnJvbSAnb3BlbmNsYXcvcGx1Z2luLXNkay9wcm92aWRlci10eXBlcyc7CmltcG9ydCBtYW5pZmVzdCBmcm9tICcuLi9vcGVuY2xhdy5wbHVnaW4uanNvbicgd2l0aCB7IHR5cGU6ICdqc29uJyB9OwppbXBvcnQgeyBidWlsZEFueXJheVByb3ZpZGVyLCBwbHVnaW5Db25maWdGcm9tIH0gZnJvbSAnLi9jYXRhbG9nLmpzJzsKaW1wb3J0IHsgY3JlYXRlQW55cmF5U3RyZWFtV3JhcHBlciB9IGZyb20gJy4vc3RyZWFtV3JhcHBlci5qcyc7CgovKiogVGhlIHBsdWdpbidzIG93biBgcGx1Z2lucy5lbnRyaWVzLmFueXJheS5jb25maWdgIGJsb2NrIGZyb20gdGhlIHJlc29sdmVkCiAqICBnYXRld2F5IGNvbmZpZy4gVGhlIHBsYWluLW9iamVjdCBgcHJvdmlkZXJgIGZvcm0gKHRoZSBzaGFwZSB0aGUgc2hpcHBlZAogKiAgMjAyNi43LnggU0RLIG5vcm1hbGl6ZXM7IHRoZSBgKGFwaSkgPT4g4oCmYCBmdW5jdGlvbiBmb3JtIGlzIG5ld2VyKSBoYXMgbm8KICogIGBhcGkucGx1Z2luQ29uZmlnYCBjbG9zdXJlLCBzbyB0aGUgY2F0YWxvZyByZWFkcyBpdCBmcm9tIGBjdHguY29uZmlnYC4gKi8KY29uc3QgcGx1Z2luQ29uZmlnT2YgPSAoY3R4OiBQcm92aWRlckNhdGFsb2dDb250ZXh0KSA9PgogIHBsdWdpbkNvbmZpZ0Zyb20oY3R4LmNvbmZpZyk7CgpleHBvcnQgZGVmYXVsdCBkZWZpbmVTaW5nbGVQcm92aWRlclBsdWdpbkVudHJ5KHsKICBpZDogJ2FueXJheScsCiAgbmFtZTogJ0FueXJheScsCiAgZGVzY3JpcHRpb246CiAgICAiUm91dGUgT3BlbkNsYXcncyBtb2RlbCBjYWxscyB0aHJvdWdoIHlvdXIgb3JnYW5pemF0aW9uJ3MgQW55cmF5IGdhdGV3YXkgd2l0aCBwZXItc2Vzc2lvbiBpZGVudGl0eSBhbmQgY29udGVudC1mcmVlIGF0dHJpYnV0aW9uLiIsCiAgbWFuaWZlc3QsCiAgcHJvdmlkZXI6IHsKICAgIGxhYmVsOiAnQW55cmF5JywKICAgIGRvY3NQYXRoOiAnaHR0cHM6Ly9kb2NzLmFueXJheS5haS9pbnRlZ3JhdGlvbnMvb3BlbmNsYXcnLAogICAgY2F0YWxvZzogewogICAgICBydW46IGFzeW5jIChjdHg6IFByb3ZpZGVyQ2F0YWxvZ0NvbnRleHQpID0+ICh7CiAgICAgICAgcHJvdmlkZXI6IGJ1aWxkQW55cmF5UHJvdmlkZXIocGx1Z2luQ29uZmlnT2YoY3R4KSwgY3R4LmVudiksCiAgICAgIH0pLAogICAgfSwKICAgIHdyYXBTdHJlYW1GbjogY3JlYXRlQW55cmF5U3RyZWFtV3JhcHBlciwKICB9LAp9KTsK"},{path:"src/catalog.ts",contentBase64:"LyoqCiAqIEFueXJheSBwcm92aWRlciBjYXRhbG9nIOKAlCB0aGUgYG1vZGVscy5wcm92aWRlcnMuYW55cmF5YCBlbnRyeSB0aGlzIHBsdWdpbgogKiBjb250cmlidXRlcyBmcm9tIGl0cyBvd24gY29uZmlnLCByZXBsYWNpbmcgdGhlIGhhbmQtd3JpdHRlbiBKU09OIHRoZSBjb25uZWN0CiAqIGFkYXB0ZXIgb3RoZXJ3aXNlIG1haW50YWlucyAoYmFzZSBVUkwsIGFwaSBraW5kLCBwZXItbW9kZWwgbWF4VG9rZW5zLCB0aGUKICogb2ZmLWhvc3QgYmV0YS1oZWFkZXIgcmVzdG9yZSkuCiAqCiAqIFB1cmU6IGNvbmZpZyBpbiwgTW9kZWxQcm92aWRlckNvbmZpZyBvdXQuIFRoZSBFMkUtcHJvdmVuIGxhbmRtaW5lcyBmcm9tIHRoZQogKiBjb25maWctZmlsZSBpbnRlZ3JhdGlvbiBhcmUgZW5jb2RlZCBoZXJlIG9uY2U6IGV4cGxpY2l0IGBhcGlgIChhIGN1c3RvbWl6ZWQKICogZW50cnkgb3RoZXJ3aXNlIHNpbGVudGx5IGZhbGxzIHRvIHRoZSBPcGVuQUktY29tcGF0aWJsZSBkaWFsZWN0KSBhbmQKICogcGVyLW1vZGVsIGBtYXhUb2tlbnNgIChhIGN1c3RvbWl6ZWQgZW50cnkgc3RvcHMgaW5oZXJpdGluZyB0aGUgY2F0YWxvZydzKS4KICovCgppbXBvcnQgdHlwZSB7IE1vZGVsUHJvdmlkZXJDb25maWcgfSBmcm9tICdvcGVuY2xhdy9wbHVnaW4tc2RrL3Byb3ZpZGVyLXR5cGVzJzsKCmV4cG9ydCBpbnRlcmZhY2UgQW55cmF5UGx1Z2luQ29uZmlnIHsKICBnYXRld2F5VXJsPzogdW5rbm93bjsKICBhcGlLZXk/OiB1bmtub3duOwogIHVzZXI/OiB1bmtub3duOwogIHRlYW0/OiB1bmtub3duOwogIGdhdGV3YXlSb3V0aW5nPzogdW5rbm93bjsKfQoKLyoqCiAqIE9wdC1pbjogYGdhdGV3YXlSb3V0aW5nOiB0cnVlYCBzdG9wcyB0aGUgd3JhcHBlciBmcm9tIG5hbWluZyBhIHByb3ZpZGVyIG9uCiAqIG5vbi1BbnRocm9waWMgbW9kZWxzIChHcm9rKSwgc28gdGhlIG9yZydzIEFETUlOLXN0b3JlZCByb3V0aW5nIGNvbmZpZwogKiBnb3Zlcm5zIHRoZW0g4oCUIHJlcXVpcmVkIGZvciBwZXIta2V5IHJvdXRpbmcgKGBwcm92aWRlcl9rZXlfaWRgLCBlLmcuIHR3bwogKiB4QUkgYWNjb3VudHMpIGFuZCBjb25kaXRpb25hbCBkaXNwYXRjaC4gT2ZmIGJ5IGRlZmF1bHQgYmVjYXVzZSB3aXRob3V0IGEKICogcm91dGluZy1jb25maWcgcnVsZSBtYXRjaGluZyBgcGFyYW1zLm1vZGVsYCAoZ3Jvay0qKSwgYW4gdW5zdGFtcGVkIEdyb2sKICogcmVxdWVzdCBmYWxscyB0byB0aGUgb3JnJ3MgZGVmYXVsdCBwcm92aWRlciBhbmQgZmFpbHMgdGhlcmUg4oCUIHRoZSBvcGVyYXRvcgogKiBtdXN0IHNldCB1cCB0aGUgZ2F0ZXdheSBydWxlIGZpcnN0LCB0aGVuIGZsaXAgdGhpcyBmbGFnLiBTdHJpY3RseSBgdHJ1ZWAKICogb25seTogYW55IG90aGVyIHZhbHVlIGtlZXBzIHRoZSBzYWZlIHN0YW1waW5nIGJlaGF2aW9yLgogKi8KZXhwb3J0IGNvbnN0IGdhdGV3YXlSb3V0aW5nRW5hYmxlZCA9IChjb25maWc6IEFueXJheVBsdWdpbkNvbmZpZyk6IGJvb2xlYW4gPT4KICBjb25maWcuZ2F0ZXdheVJvdXRpbmcgPT09IHRydWU7CgovKiogRGlnIGBwbHVnaW5zLmVudHJpZXMuYW55cmF5LmNvbmZpZ2Agb3V0IG9mIGEgcmVzb2x2ZWQgT3BlbkNsYXcgY29uZmlnLgogKiAgU2hhcmVkIGJ5IHRoZSBjYXRhbG9nICh3aGljaCBidWlsZHMgdGhlIHByb3ZpZGVyIGVudHJ5KSBhbmQgdGhlIHN0cmVhbQogKiAgd3JhcHBlciAod2hpY2ggcmUtc3RhbXBzIHBlciBjYWxsLCBiZWNhdXNlIHRoZSB0cmFuc3BvcnQgZHJvcHMgdGhlCiAqICBjYXRhbG9nJ3MgcHJvdmlkZXItbGV2ZWwgaGVhZGVycyBmb3IgcGx1Z2luIHByb3ZpZGVycykuIEV2ZXJ5IHN0ZXAgaXMKICogIHNoYXBlLWNoZWNrZWQ6IGEgZm9yZWlnbiBvciBoYWxmLXdyaXR0ZW4gY29uZmlnIHlpZWxkcyBge31gLCBuZXZlciBhIHRocm93CiAqICBvbiB0aGUgaG90IHBhdGguICovCmV4cG9ydCBjb25zdCBwbHVnaW5Db25maWdGcm9tID0gKGNvbmZpZzogdW5rbm93bik6IEFueXJheVBsdWdpbkNvbmZpZyA9PiB7CiAgaWYgKHR5cGVvZiBjb25maWcgIT09ICdvYmplY3QnIHx8IGNvbmZpZyA9PT0gbnVsbCkgcmV0dXJuIHt9OwogIGNvbnN0IHBsdWdpbnMgPSAoY29uZmlnIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5wbHVnaW5zOwogIGlmICh0eXBlb2YgcGx1Z2lucyAhPT0gJ29iamVjdCcgfHwgcGx1Z2lucyA9PT0gbnVsbCkgcmV0dXJuIHt9OwogIGNvbnN0IGVudHJpZXMgPSAocGx1Z2lucyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikuZW50cmllczsKICBpZiAodHlwZW9mIGVudHJpZXMgIT09ICdvYmplY3QnIHx8IGVudHJpZXMgPT09IG51bGwpIHJldHVybiB7fTsKICBjb25zdCBlbnRyeSA9IChlbnRyaWVzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5hbnlyYXk7CiAgaWYgKHR5cGVvZiBlbnRyeSAhPT0gJ29iamVjdCcgfHwgZW50cnkgPT09IG51bGwpIHJldHVybiB7fTsKICBjb25zdCBvd24gPSAoZW50cnkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLmNvbmZpZzsKICBpZiAodHlwZW9mIG93biAhPT0gJ29iamVjdCcgfHwgb3duID09PSBudWxsKSByZXR1cm4ge307CiAgcmV0dXJuIG93biBhcyBBbnlyYXlQbHVnaW5Db25maWc7Cn07CgovKiogT3BlbkNsYXcgc3VwcHJlc3NlcyBpbXBsaWNpdCBiZXRhIGhlYWRlcnMgb2ZmLWhvc3Q7IHJlc3RvcmUgdGhlIEFQSS1rZXkgc2V0LiAqLwpjb25zdCBBTlRIUk9QSUNfQkVUQSA9ICdpbnRlcmxlYXZlZC10aGlua2luZy0yMDI1LTA1LTE0JzsKCi8qKiBEZWZhdWx0IGtleSByZWZlcmVuY2Ug4oCUIE9wZW5DbGF3IHN1YnN0aXR1dGVzICR7RU5WfSBpbiBjb25maWcgc3RyaW5ncywgYnV0CiAqICBwbHVnaW4gY29uZmlnIGFycml2ZXMgcmVzb2x2ZWQsIHNvIGFuIHVuc2V0IGtleSBmYWxscyBiYWNrIHRvIHRoZSBlbnYgdmFyCiAqICB0aGUgY29ubmVjdCBlbnJvbGxtZW50IHdyaXRlcy4gKi8KY29uc3QgS0VZX0VOViA9ICdBTllSQVlfQ0xJRU5UX0tFWSc7Cgpjb25zdCBNT0RFTFM6IFJlYWRvbmx5QXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+ID0gWwogIHsKICAgIGlkOiAnY2xhdWRlLXNvbm5ldC00LTUnLAogICAgbmFtZTogJ0NsYXVkZSBTb25uZXQgNC41IChBbnlyYXkpJywKICAgIHJlYXNvbmluZzogdHJ1ZSwKICAgIGlucHV0OiBbJ3RleHQnLCAnaW1hZ2UnXSwKICAgIGNvbnRleHRXaW5kb3c6IDIwMDAwMCwKICAgIG1heFRva2VuczogNjQwMDAsCiAgfSwKICB7CiAgICBpZDogJ2NsYXVkZS1oYWlrdS00LTUnLAogICAgbmFtZTogJ0NsYXVkZSBIYWlrdSA0LjUgKEFueXJheSknLAogICAgcmVhc29uaW5nOiB0cnVlLAogICAgaW5wdXQ6IFsndGV4dCcsICdpbWFnZSddLAogICAgY29udGV4dFdpbmRvdzogMjAwMDAwLAogICAgbWF4VG9rZW5zOiA2NDAwMCwKICB9LAogIHsKICAgIGlkOiAnY2xhdWRlLW9wdXMtNC04JywKICAgIG5hbWU6ICdDbGF1ZGUgT3B1cyA0LjggKEFueXJheSknLAogICAgcmVhc29uaW5nOiB0cnVlLAogICAgaW5wdXQ6IFsndGV4dCcsICdpbWFnZSddLAogICAgY29udGV4dFdpbmRvdzogMjAwMDAwLAogICAgbWF4VG9rZW5zOiAzMjAwMCwKICB9LAogIC8vIHhBSSBHcm9rLiBTYW1lIGdhdGV3YXkgVVJMIGFuZCB0aGUgc2FtZSBhbnRocm9waWMtbWVzc2FnZXMgd2lyZSBhcyB0aGUKICAvLyBDbGF1ZGUgaWRzIGFib3ZlIOKAlCB0aGUgZ2F0ZXdheSB0cmFuc2xhdGVzIHRvIHhBSSdzIGNoYXQvY29tcGxldGlvbnMgcGF0aCDigJQKICAvLyBidXQgdGhlIHByb3ZpZGVyIGlzIG5hbWVkIHBlciBjYWxsIGJ5IHRoZSBzdHJlYW0gd3JhcHBlciwgc2luY2UgdGhlIGdhdGV3YXkKICAvLyBoYXMgbm8gYnVpbHQtaW4gbW9kZWwtPnByb3ZpZGVyIG1hcCB0byBpbmZlciBgeC1haWAgZnJvbSB0aGUgaWQuCiAgLy8gYG1heFRva2Vuc2AgaXMgeEFJJ3Mgb3duIGRvY3VtZW50ZWQgZGVmYXVsdCBmb3IgYG1heF9jb21wbGV0aW9uX3Rva2Vuc2AKICAvLyAoMTI4aywgdmlzaWJsZSBvdXRwdXQgb25seTsgcmVhc29uaW5nIHRva2VucyBkb24ndCBjb3VudCBhZ2FpbnN0IGl0KSwgYW5kCiAgLy8gYGNvbnRleHRXaW5kb3dgIGlzIGVhY2ggbW9kZWwncyBwdWJsaXNoZWQgYG1heFByb21wdExlbmd0aGAuCiAgewogICAgaWQ6ICdncm9rLTQuNicsCiAgICBuYW1lOiAnR3JvayA0LjYgKEFueXJheSknLAogICAgcmVhc29uaW5nOiB0cnVlLAogICAgaW5wdXQ6IFsndGV4dCcsICdpbWFnZSddLAogICAgY29udGV4dFdpbmRvdzogNTAwMDAwLAogICAgbWF4VG9rZW5zOiAxMjgwMDAsCiAgfSwKICB7CiAgICBpZDogJ2dyb2stNC4zJywKICAgIG5hbWU6ICdHcm9rIDQuMyAoQW55cmF5KScsCiAgICByZWFzb25pbmc6IHRydWUsCiAgICBpbnB1dDogWyd0ZXh0JywgJ2ltYWdlJ10sCiAgICBjb250ZXh0V2luZG93OiAxMDAwMDAwLAogICAgbWF4VG9rZW5zOiAxMjgwMDAsCiAgfSwKICB7CiAgICBpZDogJ2dyb2stYnVpbGQtMC4xJywKICAgIG5hbWU6ICdHcm9rIEJ1aWxkIDAuMSAoQW55cmF5KScsCiAgICByZWFzb25pbmc6IHRydWUsCiAgICBpbnB1dDogWyd0ZXh0JywgJ2ltYWdlJ10sCiAgICBjb250ZXh0V2luZG93OiAyNTYwMDAsCiAgICBtYXhUb2tlbnM6IDEyODAwMCwKICB9LApdOwoKLyoqIFRoZSBnYXRld2F5IHByb3ZpZGVyIHNsdWcgYSBjYXRhbG9nIG1vZGVsIG11c3QgYmUgcm91dGVkIHRvLCBvciB1bmRlZmluZWQgdG8KICogIGxlYXZlIHRoZSByZXF1ZXN0IHVuc3RhbXBlZCBzbyB0aGUgb3JnJ3Mgb3duIGRlZmF1bHQgcm91dGluZyBwaWNrcyAod2hhdCB0aGUKICogIENsYXVkZSBpZHMgaGF2ZSBhbHdheXMgZG9uZSkuIEFuY2hvcmVkIHRvIHRoZSBpZCdzIGxhc3QgcGF0aCBzZWdtZW50LCBub3QgYQogKiAgc3Vic3RyaW5nLCBzbyBhbiBgYW55cmF5L2AtcXVhbGlmaWVkIGlkIHJlc29sdmVzIHRoZSBzYW1lIHdheSBhIGJhcmUgb25lIGRvZXMuICovCmV4cG9ydCBjb25zdCBnYXRld2F5UHJvdmlkZXJGb3JNb2RlbCA9ICgKICBtb2RlbElkOiB1bmtub3duCik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7CiAgaWYgKHR5cGVvZiBtb2RlbElkICE9PSAnc3RyaW5nJykgcmV0dXJuIHVuZGVmaW5lZDsKICBjb25zdCBiYXJlID0gbW9kZWxJZC5zbGljZShtb2RlbElkLmxhc3RJbmRleE9mKCcvJykgKyAxKTsKICByZXR1cm4gYmFyZS5zdGFydHNXaXRoKCdncm9rLScpID8gJ3gtYWknIDogdW5kZWZpbmVkOwp9OwoKY29uc3QgdHJpbW1lZFN0cmluZyA9ICh2OiB1bmtub3duKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+CiAgdHlwZW9mIHYgPT09ICdzdHJpbmcnICYmIHYudHJpbSgpICE9PSAnJyA/IHYudHJpbSgpIDogdW5kZWZpbmVkOwoKLyoqIENvbnRlbnQtZnJlZSBhdHRyaWJ1dGlvbiBoZWFkZXIgdmFsdWU7IHVuZGVmaW5lZCB3aGVuIG5vdGhpbmcgdG8gYXR0cmlidXRlLiAqLwpleHBvcnQgY29uc3QgYXR0cmlidXRpb25IZWFkZXJWYWx1ZSA9ICgKICBjb25maWc6IEFueXJheVBsdWdpbkNvbmZpZwopOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4gewogIGNvbnN0IHVzZXIgPSB0cmltbWVkU3RyaW5nKGNvbmZpZy51c2VyKTsKICBjb25zdCB0ZWFtID0gdHJpbW1lZFN0cmluZyhjb25maWcudGVhbSk7CiAgaWYgKCF1c2VyICYmICF0ZWFtKSByZXR1cm4gdW5kZWZpbmVkOwogIHJldHVybiBKU09OLnN0cmluZ2lmeSh7CiAgICAuLi4odXNlciA/IHsgdXNlciB9IDoge30pLAogICAgLi4uKHRlYW0gPyB7IHRlYW0gfSA6IHt9KSwKICAgIHRvb2w6ICdvcGVuY2xhdycsCiAgfSk7Cn07CgovKiogQnVpbGQgdGhlIHByb3ZpZGVyIGVudHJ5LiBUaHJvd3Mgb24gYSBtaXNzaW5nIGdhdGV3YXlVcmwg4oCUIHRoZSBwbHVnaW4gaXMKICogIG1pc2NvbmZpZ3VyZWQgYW5kIGEgaGFsZi1jb25maWd1cmVkIHByb3ZpZGVyIHdvdWxkIHJvdXRlIG5vd2hlcmUuICovCmV4cG9ydCBjb25zdCBidWlsZEFueXJheVByb3ZpZGVyID0gKAogIGNvbmZpZzogQW55cmF5UGx1Z2luQ29uZmlnLAogIGVudjogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiA9IHByb2Nlc3MuZW52Cik6IE1vZGVsUHJvdmlkZXJDb25maWcgPT4gewogIGNvbnN0IGdhdGV3YXlVcmwgPSB0cmltbWVkU3RyaW5nKGNvbmZpZy5nYXRld2F5VXJsKTsKICBpZiAoIWdhdGV3YXlVcmwpIHsKICAgIHRocm93IG5ldyBFcnJvcigKICAgICAgJ2FueXJheSBwbHVnaW46IHBsdWdpbnMuZW50cmllcy5hbnlyYXkuY29uZmlnLmdhdGV3YXlVcmwgaXMgcmVxdWlyZWQnCiAgICApOwogIH0KICBjb25zdCBhcGlLZXkgPSB0cmltbWVkU3RyaW5nKGNvbmZpZy5hcGlLZXkpID8/IGVudltLRVlfRU5WXTsKICBjb25zdCBhdHRyaWJ1dGlvbiA9IGF0dHJpYnV0aW9uSGVhZGVyVmFsdWUoY29uZmlnKTsKICByZXR1cm4gewogICAgLy8gQmFyZSBvcmlnaW46IHRoZSBhbnRocm9waWMtbWVzc2FnZXMgdHJhbnNwb3J0IGFwcGVuZHMgL3YxL21lc3NhZ2VzLgogICAgYmFzZVVybDogZ2F0ZXdheVVybC5yZXBsYWNlKC9cLyskLywgJycpLAogICAgYXBpOiAnYW50aHJvcGljLW1lc3NhZ2VzJywKICAgIC4uLihhcGlLZXkgPyB7IGFwaUtleSB9IDoge30pLAogICAgaGVhZGVyczogewogICAgICAnYW50aHJvcGljLWJldGEnOiBBTlRIUk9QSUNfQkVUQSwKICAgICAgLi4uKGFwaUtleSA/IHsgJ3gtYW55cmF5LWFwaS1rZXknOiBhcGlLZXkgfSA6IHt9KSwKICAgICAgLi4uKGF0dHJpYnV0aW9uID8geyAneC1hbnlyYXktbWV0YWRhdGEnOiBhdHRyaWJ1dGlvbiB9IDoge30pLAogICAgfSwKICAgIG1vZGVsczogTU9ERUxTLAogIH07Cn07Cg=="},{path:"src/sessionIdentity.ts",contentBase64:"LyoqCiAqIFBlci1zZXNzaW9uIGlkZW50aXR5IGZvciB0aGUgQW55cmF5IGdhdGV3YXksIGluamVjdGVkIGludG8gdGhlIEFudGhyb3BpYwogKiBNZXNzYWdlcyBib2R5IGFzIGBtZXRhZGF0YS51c2VyX2lkYC4KICoKICogVGhlIGdhdGV3YXkgZGVyaXZlcyBpdHMgb3B0aW1pemVyIHNlc3Npb24gZnJvbSBhIGBfc2Vzc2lvbl88dXVpZD5gIHN1ZmZpeCBvbgogKiBgbWV0YWRhdGEudXNlcl9pZGAgKHRoZSBDbGF1ZGUgQ29kZSBjb252ZW50aW9uOyBnYXRld2F5CiAqIGBjbGllbnRTZXNzaW9uLnRzI21ldGFkYXRhU2Vzc2lvblV1aWRgKS4gV2l0aG91dCBpdCwgT3BlbkNsYXcgdHJhZmZpYyBmYWxscwogKiB0byBhIGNvbnZlcnNhdGlvbi1hbmNob3IgZmluZ2VycHJpbnQsIGFuZCBjb25jdXJyZW50IGNvbnZlcnNhdGlvbnMgdGhhdCBvcGVuCiAqIGlkZW50aWNhbGx5IHNoYXJlIG9uZSBzZXNzaW9uIOKAlCBvbmUgb3B0aW1pemVyIGZhaWwtb3BlbiB0aGVuIHBhdXNlcwogKiBvcHRpbWl6YXRpb24gZm9yIGFsbCBvZiB0aGVtICh0aGUgY29vbG9mZi1hbXBsaWZpY2F0aW9uIGZhaWx1cmUgbW9kZSkuCiAqCiAqIE9wZW5DbGF3J3Mgc3RyZWFtIGxheWVyIGhhbmRzIHVzIGFuIG9wYXF1ZSBgc2Vzc2lvbklkYCBwZXIgY2FsbC4gV2hlbiBpdCBpcwogKiBhbHJlYWR5IGEgVVVJRCBpdCBpcyB1c2VkIGFzLWlzOyBhbnl0aGluZyBlbHNlIGlzIGZvbGRlZCBpbnRvIGEgc3RhYmxlCiAqIFVVSUQtc2hhcGVkIHZhbHVlIHZpYSBTSEEtMjU2IHNvIHRoZSBzYW1lIHNlc3Npb24gYWx3YXlzIG1hcHMgdG8gdGhlIHNhbWUKICogaWQuIFRoZSB2YWx1ZSBpcyBhbiBvcGFxdWUgaWRlbnRpZmllciBlaXRoZXIgd2F5IOKAlCBubyBjb250ZW50LCBubyB1c2VyIGRhdGEuCiAqLwoKaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gJ25vZGU6Y3J5cHRvJzsKCmNvbnN0IFVVSURfUkUgPQogIC9eWzAtOWEtZl17OH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17MTJ9JC9pOwoKLyoqIFByZWZpeCBtYXJraW5nIGdhdGV3YXktdmlzaWJsZSB1c2VyX2lkcyBhcyBvdXJzIChjb250ZW50LWZyZWUpLiAqLwpjb25zdCBVU0VSX0lEX1BSRUZJWCA9ICdvcGVuY2xhdyc7CgovKiogQSBzdGFibGUgVVVJRC1zaGFwZWQgdmFsdWUgZm9yIGFueSBvcGFxdWUgc2Vzc2lvbiBrZXkuICovCmV4cG9ydCBjb25zdCBzZXNzaW9uVXVpZEZvciA9IChzZXNzaW9uSWQ6IHN0cmluZyk6IHN0cmluZyA9PiB7CiAgaWYgKFVVSURfUkUudGVzdChzZXNzaW9uSWQpKSByZXR1cm4gc2Vzc2lvbklkLnRvTG93ZXJDYXNlKCk7CiAgY29uc3QgaGV4ID0gY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKHNlc3Npb25JZCwgJ3V0ZjgnKS5kaWdlc3QoJ2hleCcpOwogIHJldHVybiBbCiAgICBoZXguc2xpY2UoMCwgOCksCiAgICBoZXguc2xpY2UoOCwgMTIpLAogICAgaGV4LnNsaWNlKDEyLCAxNiksCiAgICBoZXguc2xpY2UoMTYsIDIwKSwKICAgIGhleC5zbGljZSgyMCwgMzIpLAogIF0uam9pbignLScpOwp9OwoKLyoqIFRoZSBgbWV0YWRhdGEudXNlcl9pZGAgdmFsdWUgdGhlIGdhdGV3YXkncyBzZXNzaW9uIGV4dHJhY3RvciByZWNvZ25pemVzLiAqLwpleHBvcnQgY29uc3QgYW55cmF5VXNlcklkRm9yID0gKHNlc3Npb25JZDogc3RyaW5nKTogc3RyaW5nID0+CiAgYCR7VVNFUl9JRF9QUkVGSVh9X3Nlc3Npb25fJHtzZXNzaW9uVXVpZEZvcihzZXNzaW9uSWQpfWA7CgovKioKICogUGF0Y2ggYW4gb3V0Ym91bmQgQW50aHJvcGljIE1lc3NhZ2VzIHBheWxvYWQgaW4gcGxhY2Ugd2l0aCB0aGUgc2Vzc2lvbgogKiBpZGVudGl0eS4gRXhpc3RpbmcgYG1ldGFkYXRhLnVzZXJfaWRgIHZhbHVlcyBhcmUgbmV2ZXIgb3ZlcndyaXR0ZW4gKGEgdmFsdWUKICogcHJlc2VudCBtZWFucyBzb21lb25lIHVwc3RyZWFtIOKAlCBjb25maWcsIGFub3RoZXIgcGx1Z2luIOKAlCBtYWRlIGEgY2hvaWNlKSwKICogYW5kIGEgbWFsZm9ybWVkIGBtZXRhZGF0YWAgc2hhcGUgaXMgbGVmdCB1bnRvdWNoZWQgcmF0aGVyIHRoYW4gcmVwYWlyZWQuCiAqLwpleHBvcnQgY29uc3QgcGF0Y2hQYXlsb2FkU2Vzc2lvbklkZW50aXR5ID0gKAogIHBheWxvYWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LAogIHNlc3Npb25JZDogc3RyaW5nIHwgdW5kZWZpbmVkCik6IHZvaWQgPT4gewogIGlmICghc2Vzc2lvbklkKSByZXR1cm47CiAgY29uc3QgbWV0YWRhdGEgPSBwYXlsb2FkLm1ldGFkYXRhOwogIGlmIChtZXRhZGF0YSA9PT0gdW5kZWZpbmVkKSB7CiAgICBwYXlsb2FkLm1ldGFkYXRhID0geyB1c2VyX2lkOiBhbnlyYXlVc2VySWRGb3Ioc2Vzc2lvbklkKSB9OwogICAgcmV0dXJuOwogIH0KICBpZiAodHlwZW9mIG1ldGFkYXRhICE9PSAnb2JqZWN0JyB8fCBtZXRhZGF0YSA9PT0gbnVsbCB8fCBBcnJheS5pc0FycmF5KG1ldGFkYXRhKSkKICAgIHJldHVybjsKICBjb25zdCByZWNvcmQgPSBtZXRhZGF0YSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjsKICBpZiAocmVjb3JkLnVzZXJfaWQgPT09IHVuZGVmaW5lZCkgewogICAgcmVjb3JkLnVzZXJfaWQgPSBhbnlyYXlVc2VySWRGb3Ioc2Vzc2lvbklkKTsKICB9Cn07Cg=="},{path:"src/streamWrapper.ts",contentBase64:"LyoqCiAqIFRoZSBwZXItY2FsbCBzZWFtOiB3cmFwcyB0aGUgYnVpbHQtaW4gYW50aHJvcGljLW1lc3NhZ2VzIHRyYW5zcG9ydCBzbyBldmVyeQogKiBvdXRib3VuZCBjYWxsIHRvIHRoZSBBbnlyYXkgZ2F0ZXdheSBjYXJyaWVzIHBlci1zZXNzaW9uIGlkZW50aXR5LCBhbmQgcHJvbXB0CiAqIGNhY2hpbmcgaXMgbmV2ZXIgc2lsZW50bHkgb2ZmLgogKgogKiBEZWxlZ2F0aW9uIGNvbnRyYWN0IChtaXJyb3JzIE9wZW5DbGF3J3Mgb3duIGJ1bmRsZWQgd3JhcHBlcnMpOiByZXR1cm4gYQogKiBTdHJlYW1GbiB0aGF0IGNoYWlucyBhbnkgY2FsbGVyLXN1cHBsaWVkIGBvblBheWxvYWRgIGFmdGVyIG91cnMsIGFuZCBhbHdheXMKICogaGFuZCBvZmYgdG8gYGN0eC5zdHJlYW1GbmAg4oCUIHRoaXMgd3JhcHBlciBvbmx5IGRlY29yYXRlcywgaXQgbmV2ZXIKICogdHJhbnNwb3J0cy4gR3VhcmRlZCB0byBvdXIgcHJvdmlkZXIgKyBhcGkgc28gYSBtaXMtcmVnaXN0cmF0aW9uIGNhbiBuZXZlcgogKiB0b3VjaCBzb21lb25lIGVsc2UncyB0cmFmZmljLgogKi8KCmltcG9ydCB0eXBlIHsKICBQcm92aWRlcldyYXBTdHJlYW1GbkNvbnRleHQsCiAgU3RyZWFtRm4sCiAgU3RyZWFtT3B0aW9ucywKfSBmcm9tICdvcGVuY2xhdy9wbHVnaW4tc2RrL3Byb3ZpZGVyLXR5cGVzJzsKaW1wb3J0IHsgcGF0Y2hQYXlsb2FkU2Vzc2lvbklkZW50aXR5IH0gZnJvbSAnLi9zZXNzaW9uSWRlbnRpdHkuanMnOwppbXBvcnQgewogIGF0dHJpYnV0aW9uSGVhZGVyVmFsdWUsCiAgZ2F0ZXdheVByb3ZpZGVyRm9yTW9kZWwsCiAgZ2F0ZXdheVJvdXRpbmdFbmFibGVkLAogIHBsdWdpbkNvbmZpZ0Zyb20sCn0gZnJvbSAnLi9jYXRhbG9nLmpzJzsKCmV4cG9ydCBjb25zdCBBTllSQVlfUFJPVklERVJfSUQgPSAnYW55cmF5JzsKCi8qKiBBdHRyaWJ1dGlvbiBmYWxsYmFjayB3aGVuIHRoZSBvcGVyYXRvciBjb25maWd1cmVkIG5vIHVzZXIvdGVhbTogdGhlIHRvb2wKICogIG5hbWUgYWxvbmUgc3RpbGwgc2VwYXJhdGVzIE9wZW5DbGF3IHRyYWZmaWMgZnJvbSBldmVyeXRoaW5nIGVsc2UuICovCmNvbnN0IFRPT0xfT05MWV9BVFRSSUJVVElPTiA9ICd7InRvb2wiOiJvcGVuY2xhdyJ9JzsKCi8qKiBDYWNoZSByZXRlbnRpb24gZGVmYXVsdCBmb3IgdGhlIGdhdGV3YXkgaG9zdDogT3BlbkNsYXcgYXV0by1zZWVkcyBwcm9tcHQKICogIGNhY2hpbmcgb25seSBvbiBhcGkuYW50aHJvcGljLmNvbS9WZXJ0ZXgsIHNvIHVuc2V0IGhlcmUgbWVhbnMgIm5vCiAqICBjYWNoZV9jb250cm9sIGF0IGFsbCIg4oCUIGEgY29sZCBwcm92aWRlciBjYWNoZSBvbiBldmVyeSB3YXJtIHR1cm4uICovCmNvbnN0IENBQ0hFX1JFVEVOVElPTl9ERUZBVUxUID0gJ3Nob3J0JzsKCmV4cG9ydCBjb25zdCBjcmVhdGVBbnlyYXlTdHJlYW1XcmFwcGVyID0gKAogIGN0eDogUHJvdmlkZXJXcmFwU3RyZWFtRm5Db250ZXh0Cik6IFN0cmVhbUZuIHwgdW5kZWZpbmVkID0+IHsKICBjb25zdCBpbm5lciA9IGN0eC5zdHJlYW1GbjsKICBpZiAoIWlubmVyKSByZXR1cm4gdW5kZWZpbmVkOwogIGlmIChjdHgucHJvdmlkZXIgIT09IEFOWVJBWV9QUk9WSURFUl9JRCkgcmV0dXJuIHVuZGVmaW5lZDsKCiAgLy8gUmVzb2x2ZWQgb25jZSBhdCB3cmFwIHRpbWUsIG5vdCBwZXIgY2FsbDogYGN0eC5jb25maWdgIGlzIHRoZSBzYW1lCiAgLy8gcmVzb2x2ZWQgY29uZmlnIHRoZSBjYXRhbG9nIHJlYWRzLCBhbmQgT3BlbkNsYXcgcmUtcnVucyB0aGUgd3JhcHBlcgogIC8vIGZhY3Rvcnkgd2hlbiBjb25maWcgcmVsb2Fkcy4KICBjb25zdCBwbHVnaW5Db25maWcgPSBwbHVnaW5Db25maWdGcm9tKGN0eC5jb25maWcpOwogIGNvbnN0IGF0dHJpYnV0aW9uID0KICAgIGF0dHJpYnV0aW9uSGVhZGVyVmFsdWUocGx1Z2luQ29uZmlnKSA/PyBUT09MX09OTFlfQVRUUklCVVRJT047CiAgLy8gT3B0LWluIChnYXRld2F5Um91dGluZzogdHJ1ZSk6IGxlYXZlIG5vbi1BbnRocm9waWMgbW9kZWxzIHVuc3RhbXBlZCBzbyB0aGUKICAvLyBvcmcncyBhZG1pbi1zdG9yZWQgcm91dGluZyBjb25maWcgZGlzcGF0Y2hlcyB0aGVtIOKAlCB0aGUgb25seSBwYXRoIHRoYXQKICAvLyBzdXBwb3J0cyBwZXIta2V5IHJvdXRpbmcgKHByb3ZpZGVyX2tleV9pZCksIHNpbmNlIGEgcHJvdmlkZXIgaGVhZGVyCiAgLy8gYnlwYXNzZXMgdGhlIHN0b3JlZCBjb25maWcgb24gdGhlIGdhdGV3YXkuIE9mZiBieSBkZWZhdWx0OiB1bnN0YW1wZWQgR3JvawogIC8vIHRyYWZmaWMgUkVRVUlSRVMgYSByb3V0aW5nLWNvbmZpZyBydWxlIG1hdGNoaW5nIHRoZSBtb2RlbCBpZCwgb3IgaXQgbGFuZHMKICAvLyBvbiB0aGUgb3JnJ3MgZGVmYXVsdCBwcm92aWRlci4KICBjb25zdCBzdGFtcFByb3ZpZGVyID0gIWdhdGV3YXlSb3V0aW5nRW5hYmxlZChwbHVnaW5Db25maWcpOwoKICBjb25zdCB3cmFwcGVkOiBTdHJlYW1GbiA9IChtb2RlbCwgY29udGV4dCwgb3B0aW9ucykgPT4gewogICAgaWYgKG1vZGVsLnByb3ZpZGVyICE9PSBBTllSQVlfUFJPVklERVJfSUQgfHwgbW9kZWwuYXBpICE9PSAnYW50aHJvcGljLW1lc3NhZ2VzJykgewogICAgICByZXR1cm4gaW5uZXIobW9kZWwsIGNvbnRleHQsIG9wdGlvbnMpOwogICAgfQogICAgY29uc3Qgb3B0czogU3RyZWFtT3B0aW9ucyA9IHsgLi4uKG9wdGlvbnMgPz8ge30pIH07CiAgICBpZiAob3B0cy5jYWNoZVJldGVudGlvbiA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIG9wdHMuY2FjaGVSZXRlbnRpb24gPSBDQUNIRV9SRVRFTlRJT05fREVGQVVMVDsKICAgIH0KICAgIC8vIExpdmUtY29udGFpbmVyIGZhY3QgKDIwMjYuNy4xKTogdGhlIHRyYW5zcG9ydCBkcm9wcyB0aGUgY2F0YWxvZydzCiAgICAvLyBwcm92aWRlci1sZXZlbCBgaGVhZGVyc2AgZm9yIHBsdWdpbiBwcm92aWRlcnMsIHNvIHRoZSBjb250ZW50LWZyZWUKICAgIC8vIGF0dHJpYnV0aW9uIHJpZGVzIHRoZSBwZXItY2FsbCBoZWFkZXIgbGV2ZXIgaW5zdGVhZC4gVGhlIEFueXJheSBnYXRld2F5CiAgICAvLyBuZWVkcyBubyBhbnRocm9waWMtYmV0YSBmcm9tIHVzIChpdHMgb3JnIGxhbmUgbWludHMgcHJvdmlkZXIgaGVhZGVycwogICAgLy8gc2VydmVyLXNpZGUpLCBhbmQgYXV0aCBhbHJlYWR5IHJpZGVzIHgtYXBpLWtleTsgdGhpcyBpcyBkaWFnbm9zdGljcwogICAgLy8gYXR0cmlidXRpb24gb25seS4gRXhpc3RpbmcgdmFsdWVzIGFyZSBuZXZlciBvdmVyd3JpdHRlbi4KICAgIC8vCiAgICAvLyBUaGUgdmFsdWUgTVVTVCBjb21lIGZyb20gcGx1Z2luIGNvbmZpZywgbm90IGEgaGFyZGNvZGVkIHRvb2wgbmFtZTogdGhlCiAgICAvLyBkcm9wcGVkIGNhdGFsb2cgaGVhZGVycyBhcmUgdGhlIG9ubHkgb3RoZXIgY2FycmllciBvZiB0aGUgb3BlcmF0b3IncwogICAgLy8gdXNlci90ZWFtLCBzbyBzdGFtcGluZyBgeyJ0b29sIjoib3BlbmNsYXcifWAgaGVyZSBsZWZ0IGV2ZXJ5IE9wZW5DbGF3CiAgICAvLyByZXF1ZXN0IHVuYXR0cmlidXRlZCBpbiB0aGUgc3BlbmQgc3RvcmUgKHdpcmUtY2FwdHVyZWQgMjAyNi0wOC0xNykuCiAgICBjb25zdCBoZWFkZXJzID0geyAuLi4ob3B0cy5oZWFkZXJzID8/IHt9KSB9OwogICAgaWYgKGhlYWRlcnNbJ3gtYW55cmF5LW1ldGFkYXRhJ10gPT09IHVuZGVmaW5lZCkgewogICAgICBoZWFkZXJzWyd4LWFueXJheS1tZXRhZGF0YSddID0gYXR0cmlidXRpb247CiAgICB9CiAgICBpZiAoCiAgICAgIGhlYWRlcnNbJ3gtYW55cmF5LWFwaS1rZXknXSA9PT0gdW5kZWZpbmVkICYmCiAgICAgIHR5cGVvZiBvcHRzLmFwaUtleSA9PT0gJ3N0cmluZycgJiYKICAgICAgb3B0cy5hcGlLZXkuc3RhcnRzV2l0aCgnYXJrXycpCiAgICApIHsKICAgICAgaGVhZGVyc1sneC1hbnlyYXktYXBpLWtleSddID0gb3B0cy5hcGlLZXk7CiAgICB9CiAgICAvLyBOb24tQW50aHJvcGljIG1vZGVscyBpbiBvdXIgY2F0YWxvZyAoR3JvaykgcmlkZSB0aGUgc2FtZSBnYXRld2F5IFVSTCBhbmQKICAgIC8vIHRoZSBzYW1lIHdpcmUsIHNvIHRoZSBtb2RlbCBpZCBpcyBhbGwgdGhhdCBkaXN0aW5ndWlzaGVzIHRoZW0g4oCUIGFuZCB0aGUKICAgIC8vIGdhdGV3YXkgaGFzIG5vIGJ1aWx0LWluIG1vZGVsLT5wcm92aWRlciBtYXAgdG8gcmVhZCBpdCBmcm9tLiBOYW1lIHRoZQogICAgLy8gcHJvdmlkZXIgcGVyIGNhbGwgaW5zdGVhZC4gQ2xhdWRlIGlkcyBzdGF5IHVuc3RhbXBlZCBzbyBhbiBvcmcncyBkZWZhdWx0CiAgICAvLyByb3V0aW5nIGNvbmZpZyBzdGlsbCBnb3Zlcm5zIHRoZW0sIGFuZCBhbiBleHBsaWNpdCBjYWxsZXIgdmFsdWUgd2lucy4KICAgIGNvbnN0IGdhdGV3YXlQcm92aWRlciA9IHN0YW1wUHJvdmlkZXIKICAgICAgPyBnYXRld2F5UHJvdmlkZXJGb3JNb2RlbChtb2RlbC5pZCkKICAgICAgOiB1bmRlZmluZWQ7CiAgICBpZiAoZ2F0ZXdheVByb3ZpZGVyICYmIGhlYWRlcnNbJ3gtYW55cmF5LXByb3ZpZGVyJ10gPT09IHVuZGVmaW5lZCkgewogICAgICBoZWFkZXJzWyd4LWFueXJheS1wcm92aWRlciddID0gZ2F0ZXdheVByb3ZpZGVyOwogICAgfQogICAgb3B0cy5oZWFkZXJzID0gaGVhZGVyczsKICAgIGNvbnN0IHNlc3Npb25JZCA9CiAgICAgIHR5cGVvZiBvcHRzLnNlc3Npb25JZCA9PT0gJ3N0cmluZycgPyBvcHRzLnNlc3Npb25JZCA6IHVuZGVmaW5lZDsKICAgIGNvbnN0IGNhbGxlck9uUGF5bG9hZCA9IG9wdHMub25QYXlsb2FkOwogICAgb3B0cy5vblBheWxvYWQgPSBhc3luYyAocGF5bG9hZCwgcGF5bG9hZE1vZGVsKSA9PiB7CiAgICAgIGlmIChwYXlsb2FkICYmIHR5cGVvZiBwYXlsb2FkID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheShwYXlsb2FkKSkgewogICAgICAgIHBhdGNoUGF5bG9hZFNlc3Npb25JZGVudGl0eSgKICAgICAgICAgIHBheWxvYWQgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4sCiAgICAgICAgICBzZXNzaW9uSWQKICAgICAgICApOwogICAgICB9CiAgICAgIHJldHVybiBjYWxsZXJPblBheWxvYWQgPyBjYWxsZXJPblBheWxvYWQocGF5bG9hZCwgcGF5bG9hZE1vZGVsKSA6IHBheWxvYWQ7CiAgICB9OwogICAgcmV0dXJuIGlubmVyKG1vZGVsLCBjb250ZXh0LCBvcHRzKTsKICB9OwogIHJldHVybiB3cmFwcGVkOwp9Owo="}];var Kf=".anyray-source-sha",wn=()=>Ar(DN(),".anyray","openclaw-plugin"),KC=async(e=wn())=>{try{if((await GC(Ar(e,Kf),"utf8")).trim()===Vf)return"current"}catch{}for(let t of HC){let n=Ar(e,t.path);await NN(LN(n),{recursive:!0,mode:448}),await we(n,Buffer.from(t.contentBase64,"base64").toString("utf8"))}return await we(Ar(e,Kf),`${Vf}
|
|
170
|
-
`),"installed"},Zs=async(e,t=[])=>{let n=[],r=async a=>{let s=Ar(a,"plugins","anyray","catalog.json");try{await VC(s),n.push(s)}catch{}};for(let a of t)await r(a);let o=[];try{o=(await $N(Ar(e,"agents"),{withFileTypes:!0})).filter(a=>a.isDirectory()).map(a=>a.name)}catch{}for(let a of o)await r(Ar(e,"agents",a,"agent"));return n},Sl=async(e=wn())=>{try{await GC(Ar(e,Kf),"utf8")}catch{return!1}return await VC(e,{recursive:!0,force:!0}),!0};var Zf="x-anyray-metadata",sa="x-anyray-api-key",Yf=["x-anyray-provider","x-anyray-auth-mode","x-anyray-custom-host"],ao="Authorization",so="anthropic-beta",Il="interleaved-thinking-2025-05-14",xl=["anthropic","openai"],ZC="short",zf="anthropic-messages",qf=32e3,Rl="anthropic/claude-sonnet-4-5",Qf=["anthropic/claude-haiku-4-5"],em="anyray/claude-sonnet-4-5",tm=["anyray/claude-haiku-4-5"],MN=[Rl,em],BN=[Qf,tm],Xe="anyray",Cr="ANYRAY_API_KEY",Ys="openclaw",aa=()=>process.env.OPENCLAW_STATE_DIR?.trim()||Ol(Xf(),".openclaw"),oa=()=>process.env.OPENCLAW_CONFIG_PATH?.trim()||Ol(aa(),"openclaw.json"),N=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),jC=(e,t)=>{if(typeof e!="string")return!1;try{return new URL(e).origin===new URL(t).origin}catch{return!1}},Jf=e=>{if(!N(e))return{};let t=e.models;return!N(t)||!N(t.providers)?{}:t.providers},FN=e=>e==="~"||e.startsWith("~/")?Ol(Xf(),e.slice(1)):e,El=e=>{if(!N(e))return[];let t=e.agents;if(!N(t)||!Array.isArray(t.list))return[];let n=[];for(let r of t.list){if(!N(r))continue;let o=typeof r.agentDir=="string"?r.agentDir.trim():"";o&&n.push(FN(o))}return n},WN=(e,t,n)=>{let r=t.clientKey??t.placeholderKey,o=fe({...t.metadata,tool:Ys}),a=t.byoUpstream,s=[],i=[],c=!1,l={...e},d=[];"models"in l&&!N(l.models)&&d.push("models");let u=N(l.models)?{...l.models}:{};if("providers"in u&&!N(u.providers)&&d.push("models.providers"),d.length>0)return{next:e,routed:[],cacheRetentionSeeded:!1,betaPreserved:!1,headerConflicts:[],primarySeeded:!1,fallbacksSeeded:!1,unroutedFallbacks:[],structureConflicts:d,pluginConfigured:!1};let p=N(u.providers)?{...u.providers}:{},m=!1;if(n){let C=N(l.plugins)?{...l.plugins}:{},S=N(C.load)?{...C.load}:{},E=N(C.entries)?{...C.entries}:{},I=N(E[Xe])?{...E[Xe]}:{},_=N(I.config)?{...I.config}:{};if("plugins"in l&&!N(l.plugins)||"load"in C&&!N(C.load)||"paths"in S&&!Array.isArray(S.paths)||"entries"in C&&!N(C.entries)||Xe in E&&!N(E[Xe])||"config"in I&&!N(I.config)||"env"in l&&!N(l.env))d.push("plugins");else{let T=Array.isArray(S.paths)?[...S.paths]:[];T.includes(n)||T.push(n),S.paths=T,C.load=S,I.enabled=!0,_.gatewayUrl=t.anthropicBaseUrl,_.apiKey=r;let W=t.metadata.user,Q=t.metadata.team;W&&(_.user=W),Q&&(_.team=Q),I.config=_,E[Xe]=I,C.entries=E,l.plugins=C;let G=N(l.env)?{...l.env}:{};G[Cr]=r,l.env=G,m=!0}}let f=xl.filter(C=>C!=="openai"||!te(t,"openai"));for(let C of f){if(C in p&&!N(p[C])){d.push(`models.providers.${C}`);continue}let S=N(p[C])?{...p[C]}:{};if("headers"in S&&!N(S.headers)){i.push(C);continue}let E=N(S.headers)?{...S.headers}:{};if(S.baseUrl=C==="anthropic"?t.anthropicBaseUrl:t.openaiBaseUrl,C==="anthropic"&&(S.api=zf,(typeof S.maxTokens!="number"||S.maxTokens<=0)&&(S.maxTokens=qf)),C==="anthropic"&&a)S.apiKey=a.key,E[ao]=`Bearer ${a.key}`,E["x-anyray-provider"]="anthropic",E["x-anyray-auth-mode"]="passthrough",E["x-anyray-custom-host"]=a.url;else{S.apiKey=r,"x-anyray-custom-host"in E&&delete E[ao];for(let I of Yf)delete E[I]}E[sa]=r,o&&(E[Zf]=o),C==="anthropic"&&(so in E?c=E[so]!==Il:E[so]=Il),S.headers=E,p[C]=S,s.push(C)}u.providers=p,l.models=u;let h=!1,w=!1,y=!1,g,b=[],k="agents"in l&&!N(l.agents)||N(l.agents)&&"defaults"in l.agents&&!N(l.agents.defaults)||N(l.agents)&&N(l.agents.defaults)&&("params"in l.agents.defaults&&!N(l.agents.defaults.params)||"model"in l.agents.defaults&&!N(l.agents.defaults.model));if(k&&d.push("agents.defaults"),s.includes("anthropic")&&!k){let C=N(l.agents)?{...l.agents}:{},S=N(C.defaults)?{...C.defaults}:{},E=N(S.params)?{...S.params}:{};"cacheRetention"in E||(E.cacheRetention=ZC,h=!0,S.params=E);let I=N(S.model)?{...S.model}:{},_=m?[...s,Xe]:s,T=W=>typeof W=="string"&&_.some(Q=>W.startsWith(`${Q}/`));typeof I.primary!="string"||I.primary.trim()===""?(I.primary=m?em:Rl,w=!0,S.model=I,"fallbacks"in I||(I.fallbacks=m?[...tm]:[...Qf],y=!0)):T(I.primary)||(g=I.primary),b=(Array.isArray(I.fallbacks)?I.fallbacks:[]).filter(W=>typeof W=="string"&&!T(W)),(h||w)&&(C.defaults=S,l.agents=C)}return{next:l,routed:s,cacheRetentionSeeded:h,betaPreserved:c,headerConflicts:i,primarySeeded:w,fallbacksSeeded:y,unroutedPrimary:g,unroutedFallbacks:b,structureConflicts:d,pluginConfigured:m}},UN=["baseUrl","apiKey","api","maxTokens"],jf=(e,t,n=xl,r)=>{let o={...e},a=!("models"in o)||N(o.models)&&(!("providers"in o.models)||N(o.models.providers)),s=N(o.models)?{...o.models}:{},i=N(s.providers)?{...s.providers}:{},c=Jf(t),l=!1;for(let u of a?n:[]){let p=i[u];if(!N(p))continue;let m={...p},f=N(m.headers)?{...m.headers}:{};if(!(t!==void 0||typeof f[sa]=="string"||typeof f[Zf]=="string"||typeof m.apiKey=="string"&&m.apiKey.startsWith("ark_")||Yf.some(C=>C in f)))continue;let w=N(c[u])?c[u]:{},y=N(w.headers)?w.headers:{},g="x-anyray-custom-host"in f,b=C=>C==="api"?m.api===zf:C==="maxTokens"?m.maxTokens===qf:C==="apiKey"?g||typeof m.apiKey=="string"&&m.apiKey.startsWith("ark_"):!0;for(let C of UN)b(C)&&(C in w?m[C]!==w[C]&&(m[C]=w[C],l=!0):C in m&&(delete m[C],l=!0));let k=[sa,Zf,...Yf,..."x-anyray-custom-host"in f?[ao]:[]];f[so]===Il&&k.push(so);for(let C of k)C in y?f[C]!==y[C]&&(f[C]=y[C],l=!0):C in f&&(delete f[C],l=!0);ao in y&&!(ao in f)&&(f[ao]=y[ao],l=!0),Object.keys(f).length===0?delete m.headers:m.headers=f,Object.keys(m).length===0?delete i[u]:i[u]=m}if(a&&(Object.keys(i).length===0?delete s.providers:s.providers=i,Object.keys(s).length===0?delete o.models:o.models=s),r&&n.includes("anthropic")){let u=N(o.plugins)?{...o.plugins}:{},p=N(u.load)?{...u.load}:{},m=N(u.entries)?{...u.entries}:{};if((!("plugins"in o)||N(o.plugins))&&(!("load"in u)||N(u.load))&&(!("paths"in p)||Array.isArray(p.paths))&&(!("entries"in u)||N(u.entries))){if(Array.isArray(p.paths)&&p.paths.includes(r)){let w=p.paths.filter(y=>y!==r);w.length===0?delete p.paths:p.paths=w,l=!0}let h=m[Xe];if(N(h)){let w=N(h.config)?h.config:{};if(t!==void 0||typeof w.apiKey=="string"&&w.apiKey.startsWith("ark_")){let g=N(t?.plugins)?t.plugins:{},b=N(g.entries)?g.entries:{};Xe in b?JSON.stringify(m[Xe])!==JSON.stringify(b[Xe])&&(m[Xe]=b[Xe],l=!0):(delete m[Xe],l=!0)}}if(Object.keys(p).length===0?delete u.load:u.load=p,Object.keys(m).length===0?delete u.entries:u.entries=m,Object.keys(u).length===0?delete o.plugins:o.plugins=u,N(o.env)){let w={...o.env},y=w[Cr];if(typeof y=="string"&&y.startsWith("ark_")){let g=N(t?.env)?t.env:{};Cr in g?w[Cr]!==g[Cr]&&(w[Cr]=g[Cr],l=!0):(delete w[Cr],l=!0),Object.keys(w).length===0?delete o.env:o.env=w}}}}let d=!("agents"in o)||N(o.agents)&&(!("defaults"in o.agents)||N(o.agents.defaults)&&(!("params"in o.agents.defaults)||N(o.agents.defaults.params))&&(!("model"in o.agents.defaults)||N(o.agents.defaults.model)));if(t!==void 0&&n.includes("anthropic")&&d){let u=N(o.agents)?{...o.agents}:{},p=N(u.defaults)?{...u.defaults}:{},m=N(p.params)?{...p.params}:{},f=N(t.agents)?t.agents:{},h=N(f.defaults)?f.defaults:{},w=N(h.params)?h.params:{};m.cacheRetention===ZC&&("cacheRetention"in w?m.cacheRetention!==w.cacheRetention&&(m.cacheRetention=w.cacheRetention,l=!0):(delete m.cacheRetention,l=!0));let y=N(p.model)?{...p.model}:{},g=N(h.model)?h.model:{};MN.includes(y.primary)&&("primary"in g?y.primary!==g.primary&&(y.primary=g.primary,l=!0):(delete y.primary,l=!0)),BN.some(b=>JSON.stringify(y.fallbacks)===JSON.stringify(b))&&("fallbacks"in g?JSON.stringify(y.fallbacks)!==JSON.stringify(g.fallbacks)&&(y.fallbacks=g.fallbacks,l=!0):(delete y.fallbacks,l=!0)),Object.keys(y).length===0?delete p.model:p.model=y,Object.keys(m).length===0?delete p.params:p.params=m,Object.keys(p).length===0?delete u.defaults:u.defaults=p,Object.keys(u).length===0?delete o.agents:o.agents=u}return{next:o,removed:l}},YC={id:Ys,title:"OpenClaw",automatic:!0,async detect(){let e=await x(oa())||await x(aa());return{installed:e,detail:e?oa():`no ${Ol(Xf(),".openclaw")} state dir`}},async apply(e,t){let n=oa();if(!e.byoUpstream&&te(e,"anthropic")){let S=["OpenClaw stays on its native Claude sign-in \u2014 the Anyray seat","passthrough lane for OpenClaw is not yet supported, and routing it","would move inference onto the org API bill. Opt in explicitly with",`\`--org --tools ${Ys}\` if that is intended.`,"Agents on the claude-cli runtime already follow the machine's","Claude Code settings, which Connect manages separately."],E;try{E=await Ke(n)}catch{return{status:"held",messages:S}}let{next:I,removed:_}=jf(E.data,await Jo(n),xl,wn());return _?t.dryRun?{status:"held",messages:[`would remove the stale Anyray route from ${n} (org lane, not the lane in effect for this seat)`,...S]}:(await dn(n,E,I,!1),await ie(n),await Sl(),await Zs(aa(),El(I)),{status:"reverted",changedFiles:[n],messages:[`removed a stale Anyray route from ${n} \u2014 it routed OpenClaw on org API billing, which is not the lane in effect for this seat.`,...S]}):(t.dryRun||(await Sl(),await Zs(aa(),El(I))),{status:"held",messages:S})}let r=wn(),o=!1;if(!t.dryRun)try{await KC(r)}catch{r=void 0,o=!0}let a;try{a=await Ke(n)}catch{return{status:"manual",messages:[`Couldn't parse ${n}; left it untouched. Under "models.providers", add:`,` "anthropic": { "baseUrl": ${JSON.stringify(e.anthropicBaseUrl)}, "api": "${zf}", "maxTokens": ${qf}, "apiKey": "<your personal ark_ key>", "headers": { "${sa}": "<your personal ark_ key>", "${so}": "${Il}" } }`,` "openai": { "baseUrl": ${JSON.stringify(e.openaiBaseUrl)}, "apiKey": "<your personal ark_ key>", "headers": { "${sa}": "<your personal ark_ key>" } }`,`Set "agents.defaults.model.primary" to a routed model (e.g. "${Rl}") if none is set,`,'and under "agents.defaults.params" set "cacheRetention": "short" \u2014',"custom Anthropic-compatible hosts get no prompt-cache auto-seed, and","an unset value would leave the provider cache permanently cold.","Then run `openclaw config validate`."]}}let{next:s,routed:i,cacheRetentionSeeded:c,betaPreserved:l,headerConflicts:d,primarySeeded:u,fallbacksSeeded:p,unroutedPrimary:m,unroutedFallbacks:f,structureConflicts:h,pluginConfigured:w}=WN(a.data,e,r),y=s,g=!1;if(!i.includes("openai")){let S=jf(y,await Jo(n),["openai"]);S.removed&&(y=S.next,g=!0)}let b=[i.includes("openai")?`${n} \u2192 models.providers.anthropic baseUrl = ${e.anthropicBaseUrl}; models.providers.openai baseUrl = ${e.openaiBaseUrl}`:`${n} \u2192 models.providers.anthropic baseUrl = ${e.anthropicBaseUrl}; openai left on its native ChatGPT sign-in`,e.byoUpstream?`Auth (anthropic): your personal upstream key (written to the config, not shown here) \u2014 the gateway forwards it verbatim to ${e.byoUpstream.url} (must be in the gateway's custom-host allowlist).`:e.clientKey?"Auth: your personal gateway key (written to the config, not shown here) \u2014 the gateway swaps in the server-held provider key.":"Enrollment required before a real apply; the gateway does not accept a shared placeholder.",`Attribution: ${fe({...e.metadata,tool:Ys})??"(none \u2014 pass --user, or --enroll for a per-user key)"}`,...c?['Seeded agents.defaults.params.cacheRetention = "short": OpenClaw',"skips its prompt-cache auto-seed on custom hosts, and an unset","value would leave the provider cache permanently cold."]:["Kept your existing cacheRetention setting."],...l?[`Kept your existing ${so} header value (OpenClaw suppresses its implicit beta headers off-host; yours replaces our default restore).`]:[],...d.length>0?[`Could not add headers on models.providers.${d.join(", ")}: the existing "headers" value is not an object. Fix it manually; nothing there was replaced.`]:[],...u?[`Seeded agents.defaults.model.primary = ${w?em:Rl} (none was set; routing is inert until the primary resolves to a routed provider).`,...p?[`Seeded agents.defaults.model.fallbacks = [${(w?tm:Qf).join(", ")}] so failover stays on a routed provider.`]:[]]:[],...m!==void 0?[`Your primary model (${m}) resolves to a provider Connect does not route, so those requests bypass the gateway. Pick an anthropic/* or openai/* model to route them; your setting was kept.`]:[],...f.length>0?[`Fallback model(s) ${f.join(", ")} resolve to unrouted providers: a failover would bypass the gateway. Your settings were kept.`]:[],...g?["Removed the earlier Anyray route from models.providers.openai \u2014 your ChatGPT sign-in keeps that lane native now."]:[],...w?[`${t.dryRun?"Would install":"Installed"} the Anyray OpenClaw plugin (${wn()}) and registered it under plugins.entries.${Xe}: anyray/* models get per-conversation optimization sessions. Restart the OpenClaw gateway once to load it.`]:[],...o?[`Could not write the Anyray OpenClaw plugin to ${wn()}; routing continues via the provider entries alone (anthropic/* models).`]:[],...h.length>0?[`Left ${h.join(", ")} untouched: the existing value has the wrong shape (array or null where an object belongs), and OpenClaw's strict schema will refuse it as-is. Fix the shape and re-run.`]:[],"OpenClaw hot-reloads model config; run `openclaw config validate` to confirm the merged config passes its strict schema."],k=d.length>0||h.length>0?"manual":"configured";if(t.dryRun)return{status:k,messages:b};let C=await dn(n,a,y,!0);return w&&await Zs(aa(),El(y)),{status:k,messages:b,changedFiles:C?[n]:[]}},async pointsAt(e){try{let{data:t}=await Ke(oa());for(let a of Object.values(Jf(t)))if(N(a)&&jC(a.baseUrl,e))return!0;let n=N(t.plugins)?t.plugins:{},o=(N(n.entries)?n.entries:{})[Xe];if(N(o)&&N(o.config)&&jC(o.config.gatewayUrl,e))return!0}catch{}return!1},async routingExpected(e){return e.includes(Ys)},async inferenceAuthLanes(){let e=new Set;try{let{data:t}=await Ke(oa());for(let a of Object.values(Jf(t))){if(!N(a))continue;let s=N(a.headers)?a.headers:{};typeof s["x-anyray-custom-host"]=="string"?e.add("byo"):(typeof s[sa]=="string"||typeof a.apiKey=="string"&&a.apiKey.startsWith("ark_"))&&e.add("api_key")}let n=N(t.plugins)?t.plugins:{},o=(N(n.entries)?n.entries:{})[Xe];if(N(o)&&N(o.config)){let a=o.config.apiKey;typeof a=="string"&&a.startsWith("ark_")&&e.add("api_key")}}catch{e.add("unknown")}return e.size>0?[...e]:["unknown"]},async revert(e){let t=oa();if(!await x(t))return{status:"not-found",messages:["nothing to revert"]};if(e.dryRun)return{status:"reverted",messages:[`would remove Anyray provider settings from ${t}`]};let n;try{n=await Ke(t)}catch{return{status:"manual",messages:[`Couldn't parse ${t} \u2014 if you added Anyray settings there by hand, remove baseUrl/apiKey and the x-anyray-* headers from models.providers.anthropic and models.providers.openai yourself.`]}}let{next:r,removed:o}=jf(n.data,await Jo(t),xl,wn()),a=await Sl();return await Zs(aa(),El(r)),o?(await dn(t,n,r,!1),await ie(t),{status:"reverted",messages:[`removed Anyray provider settings from ${t}`,...a?[`removed the Anyray OpenClaw plugin from ${wn()}`]:[]],changedFiles:[t]}):(await ie(t),{status:"reverted",messages:["no Anyray provider settings found",...a?[`removed the Anyray OpenClaw plugin from ${wn()}`]:[]]})}};import{execFile as _B}from"node:child_process";import{readFile as PB}from"node:fs/promises";import{homedir as fi,platform as Er}from"node:os";import{join as kn}from"node:path";import{isDeepStrictEqual as Um,promisify as DB}from"node:util";var Js=e=>{if(!/^\d+(?:\.\d+)+$/.test(e))return;let t=e.split(".").map(Number);return t.every(Number.isSafeInteger)?t:void 0},Tl=(e,t)=>{let n=Js(e),r=Js(t);if(!(!n||!r)){for(let o=0;o<Math.max(n.length,r.length);o+=1){let a=(n[o]??0)-(r[o]??0);if(a!==0)return a}return 0}};import{randomUUID as YM}from"node:crypto";import{promises as sv}from"node:fs";import{platform as JM,tmpdir as XM}from"node:os";import{join as Yl}from"node:path";import{execFile as HN}from"node:child_process";import{promises as Xs}from"node:fs";import{homedir as GN,platform as VN}from"node:os";import{delimiter as KN,join as _l}from"node:path";import{promisify as jN}from"node:util";var ZN=jN(HN),YN=15*6e4,JN=64*1024*1024,XN=e=>e==="win32"?[".exe",".cmd",".bat"]:[""],JC=async(e={})=>{let t=(e.home??GN)(),n=e.env??process.env,r=XN(e.runtimePlatform??VN()),o=[_l(t,".local","bin"),_l(t,".claude","local"),...(n.PATH??"").split(KN).filter(a=>a.length>0)];for(let a of o)for(let s of r){let i=_l(a,`claude${s}`);try{return await Xs.access(i),i}catch{}}return null},zN=e=>{if(!Array.isArray(e))return[];let t=[];for(let n of e){if(typeof n!="object"||n===null)continue;let{uuid:r,name:o,dirName:a}=n;typeof r!="string"||typeof a!="string"||a.length===0||a.includes("/")||a.includes("\\")||a==="."||a===".."||t.push({uuid:r,name:typeof o=="string"&&o.length>0?o:"Project",dirName:a})}return t},qN=async e=>{let t=_l(e,"projects"),n;try{n=(await Xs.readdir(t,{withFileTypes:!0})).filter(o=>o.isDirectory()).map(o=>o.name)}catch{return[]}let r=[];for(let o of n){let a=o.slice(-36);if(!t$.test(a))continue;let s=o.slice(0,-37).split("-").filter(i=>i.length>0).map(i=>i[0].toUpperCase()+i.slice(1)).join(" ");r.push({uuid:a,name:s.length>0?s:"Project",dirName:o})}return r},QN=e=>{if(!e||!e.startsWith("{"))return null;let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!="object"||t===null)return null;let n=t,r=n.sessionIds,o=n.jsonlPaths;if(!Array.isArray(r)||!Array.isArray(o))return null;let a=Array.isArray(n.titles)?n.titles:[],s=Array.isArray(n.createdAts)?n.createdAts:[],i=Array.isArray(n.updatedAts)?n.updatedAts:[],c=d=>typeof d=="number"&&Number.isFinite(d)?d:void 0,l=[];for(let d=0;d<r.length;d+=1){let u=r[d],p=o[d];if(typeof u!="string"||typeof p!="string"||u.length===0||p.length===0)continue;let m=a[d];l.push({sessionId:u,transcriptPath:p,title:typeof m=="string"&&m.length>0?m:"Imported conversation",createdAt:c(s[d]),lastActivityAt:c(i[d])})}return{conversations:l,projects:zN(n.projectList)}},e$=async e=>{let t,n;try{let r=await Xs.readFile(e,"utf8");for(let o of r.split(`
|
|
170
|
+
`),"installed"},Zs=async(e,t=[])=>{let n=[],r=async a=>{let s=Ar(a,"plugins","anyray","catalog.json");try{await VC(s),n.push(s)}catch{}};for(let a of t)await r(a);let o=[];try{o=(await $N(Ar(e,"agents"),{withFileTypes:!0})).filter(a=>a.isDirectory()).map(a=>a.name)}catch{}for(let a of o)await r(Ar(e,"agents",a,"agent"));return n},Sl=async(e=wn())=>{try{await GC(Ar(e,Kf),"utf8")}catch{return!1}return await VC(e,{recursive:!0,force:!0}),!0};var Zf="x-anyray-metadata",sa="x-anyray-api-key",Yf=["x-anyray-provider","x-anyray-auth-mode","x-anyray-custom-host"],ao="Authorization",so="anthropic-beta",Il="interleaved-thinking-2025-05-14",xl=["anthropic","openai"],ZC="short",zf="anthropic-messages",qf=32e3,Rl="anthropic/claude-sonnet-4-5",Qf=["anthropic/claude-haiku-4-5"],em="anyray/claude-sonnet-4-5",tm=["anyray/claude-haiku-4-5"],MN=[Rl,em],BN=[Qf,tm],Xe="anyray",Cr="ANYRAY_API_KEY",Ys="openclaw",aa=()=>process.env.OPENCLAW_STATE_DIR?.trim()||Ol(Xf(),".openclaw"),oa=()=>process.env.OPENCLAW_CONFIG_PATH?.trim()||Ol(aa(),"openclaw.json"),N=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),jC=(e,t)=>{if(typeof e!="string")return!1;try{return new URL(e).origin===new URL(t).origin}catch{return!1}},Jf=e=>{if(!N(e))return{};let t=e.models;return!N(t)||!N(t.providers)?{}:t.providers},FN=e=>e==="~"||e.startsWith("~/")?Ol(Xf(),e.slice(1)):e,El=e=>{if(!N(e))return[];let t=e.agents;if(!N(t)||!Array.isArray(t.list))return[];let n=[];for(let r of t.list){if(!N(r))continue;let o=typeof r.agentDir=="string"?r.agentDir.trim():"";o&&n.push(FN(o))}return n},WN=(e,t,n)=>{let r=t.clientKey??t.placeholderKey,o=fe({...t.metadata,tool:Ys}),a=t.byoUpstream,s=[],i=[],c=!1,l={...e},d=[];"models"in l&&!N(l.models)&&d.push("models");let u=N(l.models)?{...l.models}:{};if("providers"in u&&!N(u.providers)&&d.push("models.providers"),d.length>0)return{next:e,routed:[],cacheRetentionSeeded:!1,betaPreserved:!1,headerConflicts:[],primarySeeded:!1,fallbacksSeeded:!1,unroutedFallbacks:[],structureConflicts:d,pluginConfigured:!1};let p=N(u.providers)?{...u.providers}:{},m=!1;if(n){let C=N(l.plugins)?{...l.plugins}:{},S=N(C.load)?{...C.load}:{},E=N(C.entries)?{...C.entries}:{},I=N(E[Xe])?{...E[Xe]}:{},_=N(I.config)?{...I.config}:{};if("plugins"in l&&!N(l.plugins)||"load"in C&&!N(C.load)||"paths"in S&&!Array.isArray(S.paths)||"entries"in C&&!N(C.entries)||Xe in E&&!N(E[Xe])||"config"in I&&!N(I.config)||"env"in l&&!N(l.env))d.push("plugins");else{let T=Array.isArray(S.paths)?[...S.paths]:[];T.includes(n)||T.push(n),S.paths=T,C.load=S,I.enabled=!0,_.gatewayUrl=t.anthropicBaseUrl,_.apiKey=r;let W=t.metadata.user,Q=t.metadata.team;W&&(_.user=W),Q&&(_.team=Q),I.config=_,E[Xe]=I,C.entries=E,l.plugins=C;let G=N(l.env)?{...l.env}:{};G[Cr]=r,l.env=G,m=!0}}let f=xl.filter(C=>C!=="openai"||!te(t,"openai"));for(let C of f){if(C in p&&!N(p[C])){d.push(`models.providers.${C}`);continue}let S=N(p[C])?{...p[C]}:{};if("headers"in S&&!N(S.headers)){i.push(C);continue}let E=N(S.headers)?{...S.headers}:{};if(S.baseUrl=C==="anthropic"?t.anthropicBaseUrl:t.openaiBaseUrl,C==="anthropic"&&(S.api=zf,(typeof S.maxTokens!="number"||S.maxTokens<=0)&&(S.maxTokens=qf)),C==="anthropic"&&a)S.apiKey=a.key,E[ao]=`Bearer ${a.key}`,E["x-anyray-provider"]="anthropic",E["x-anyray-auth-mode"]="passthrough",E["x-anyray-custom-host"]=a.url;else{S.apiKey=r,"x-anyray-custom-host"in E&&delete E[ao];for(let I of Yf)delete E[I]}E[sa]=r,o&&(E[Zf]=o),C==="anthropic"&&(so in E?c=E[so]!==Il:E[so]=Il),S.headers=E,p[C]=S,s.push(C)}u.providers=p,l.models=u;let h=!1,w=!1,y=!1,g,b=[],k="agents"in l&&!N(l.agents)||N(l.agents)&&"defaults"in l.agents&&!N(l.agents.defaults)||N(l.agents)&&N(l.agents.defaults)&&("params"in l.agents.defaults&&!N(l.agents.defaults.params)||"model"in l.agents.defaults&&!N(l.agents.defaults.model));if(k&&d.push("agents.defaults"),s.includes("anthropic")&&!k){let C=N(l.agents)?{...l.agents}:{},S=N(C.defaults)?{...C.defaults}:{},E=N(S.params)?{...S.params}:{};"cacheRetention"in E||(E.cacheRetention=ZC,h=!0,S.params=E);let I=N(S.model)?{...S.model}:{},_=m?[...s,Xe]:s,T=W=>typeof W=="string"&&_.some(Q=>W.startsWith(`${Q}/`));typeof I.primary!="string"||I.primary.trim()===""?(I.primary=m?em:Rl,w=!0,S.model=I,"fallbacks"in I||(I.fallbacks=m?[...tm]:[...Qf],y=!0)):T(I.primary)||(g=I.primary),b=(Array.isArray(I.fallbacks)?I.fallbacks:[]).filter(W=>typeof W=="string"&&!T(W)),(h||w)&&(C.defaults=S,l.agents=C)}return{next:l,routed:s,cacheRetentionSeeded:h,betaPreserved:c,headerConflicts:i,primarySeeded:w,fallbacksSeeded:y,unroutedPrimary:g,unroutedFallbacks:b,structureConflicts:d,pluginConfigured:m}},UN=["baseUrl","apiKey","api","maxTokens"],jf=(e,t,n=xl,r)=>{let o={...e},a=!("models"in o)||N(o.models)&&(!("providers"in o.models)||N(o.models.providers)),s=N(o.models)?{...o.models}:{},i=N(s.providers)?{...s.providers}:{},c=Jf(t),l=!1;for(let u of a?n:[]){let p=i[u];if(!N(p))continue;let m={...p},f=N(m.headers)?{...m.headers}:{};if(!(t!==void 0||typeof f[sa]=="string"||typeof f[Zf]=="string"||typeof m.apiKey=="string"&&m.apiKey.startsWith("ark_")||Yf.some(C=>C in f)))continue;let w=N(c[u])?c[u]:{},y=N(w.headers)?w.headers:{},g="x-anyray-custom-host"in f,b=C=>C==="api"?m.api===zf:C==="maxTokens"?m.maxTokens===qf:C==="apiKey"?g||typeof m.apiKey=="string"&&m.apiKey.startsWith("ark_"):!0;for(let C of UN)b(C)&&(C in w?m[C]!==w[C]&&(m[C]=w[C],l=!0):C in m&&(delete m[C],l=!0));let k=[sa,Zf,...Yf,..."x-anyray-custom-host"in f?[ao]:[]];f[so]===Il&&k.push(so);for(let C of k)C in y?f[C]!==y[C]&&(f[C]=y[C],l=!0):C in f&&(delete f[C],l=!0);ao in y&&!(ao in f)&&(f[ao]=y[ao],l=!0),Object.keys(f).length===0?delete m.headers:m.headers=f,Object.keys(m).length===0?delete i[u]:i[u]=m}if(a&&(Object.keys(i).length===0?delete s.providers:s.providers=i,Object.keys(s).length===0?delete o.models:o.models=s),r&&n.includes("anthropic")){let u=N(o.plugins)?{...o.plugins}:{},p=N(u.load)?{...u.load}:{},m=N(u.entries)?{...u.entries}:{};if((!("plugins"in o)||N(o.plugins))&&(!("load"in u)||N(u.load))&&(!("paths"in p)||Array.isArray(p.paths))&&(!("entries"in u)||N(u.entries))){if(Array.isArray(p.paths)&&p.paths.includes(r)){let w=p.paths.filter(y=>y!==r);w.length===0?delete p.paths:p.paths=w,l=!0}let h=m[Xe];if(N(h)){let w=N(h.config)?h.config:{};if(t!==void 0||typeof w.apiKey=="string"&&w.apiKey.startsWith("ark_")){let g=N(t?.plugins)?t.plugins:{},b=N(g.entries)?g.entries:{};Xe in b?JSON.stringify(m[Xe])!==JSON.stringify(b[Xe])&&(m[Xe]=b[Xe],l=!0):(delete m[Xe],l=!0)}}if(Object.keys(p).length===0?delete u.load:u.load=p,Object.keys(m).length===0?delete u.entries:u.entries=m,Object.keys(u).length===0?delete o.plugins:o.plugins=u,N(o.env)){let w={...o.env},y=w[Cr];if(typeof y=="string"&&y.startsWith("ark_")){let g=N(t?.env)?t.env:{};Cr in g?w[Cr]!==g[Cr]&&(w[Cr]=g[Cr],l=!0):(delete w[Cr],l=!0),Object.keys(w).length===0?delete o.env:o.env=w}}}}let d=!("agents"in o)||N(o.agents)&&(!("defaults"in o.agents)||N(o.agents.defaults)&&(!("params"in o.agents.defaults)||N(o.agents.defaults.params))&&(!("model"in o.agents.defaults)||N(o.agents.defaults.model)));if(t!==void 0&&n.includes("anthropic")&&d){let u=N(o.agents)?{...o.agents}:{},p=N(u.defaults)?{...u.defaults}:{},m=N(p.params)?{...p.params}:{},f=N(t.agents)?t.agents:{},h=N(f.defaults)?f.defaults:{},w=N(h.params)?h.params:{};m.cacheRetention===ZC&&("cacheRetention"in w?m.cacheRetention!==w.cacheRetention&&(m.cacheRetention=w.cacheRetention,l=!0):(delete m.cacheRetention,l=!0));let y=N(p.model)?{...p.model}:{},g=N(h.model)?h.model:{};MN.includes(y.primary)&&("primary"in g?y.primary!==g.primary&&(y.primary=g.primary,l=!0):(delete y.primary,l=!0)),BN.some(b=>JSON.stringify(y.fallbacks)===JSON.stringify(b))&&("fallbacks"in g?JSON.stringify(y.fallbacks)!==JSON.stringify(g.fallbacks)&&(y.fallbacks=g.fallbacks,l=!0):(delete y.fallbacks,l=!0)),Object.keys(y).length===0?delete p.model:p.model=y,Object.keys(m).length===0?delete p.params:p.params=m,Object.keys(p).length===0?delete u.defaults:u.defaults=p,Object.keys(u).length===0?delete o.agents:o.agents=u}return{next:o,removed:l}},YC={id:Ys,title:"OpenClaw",automatic:!0,async detect(){let e=await x(oa())||await x(aa());return{installed:e,detail:e?oa():`no ${Ol(Xf(),".openclaw")} state dir`}},async apply(e,t){let n=oa();if(!e.byoUpstream&&te(e,"anthropic")){let S=["OpenClaw stays on its native Claude sign-in \u2014 the Anyray seat","passthrough lane for OpenClaw is not yet supported, and routing it","would move inference onto the org API bill. Opt in explicitly with",`\`--org --tools ${Ys}\` if that is intended.`,"Agents on the claude-cli runtime already follow the machine's","Claude Code settings, which Connect manages separately."],E;try{E=await Ke(n)}catch{return{status:"held",messages:S}}let{next:I,removed:_}=jf(E.data,await Jo(n),xl,wn());return _?t.dryRun?{status:"held",messages:[`would remove the stale Anyray route from ${n} (org lane, not the lane in effect for this seat)`,...S]}:(await dn(n,E,I,!1),await ie(n),await Sl(),await Zs(aa(),El(I)),{status:"reverted",changedFiles:[n],messages:[`removed a stale Anyray route from ${n} \u2014 it routed OpenClaw on org API billing, which is not the lane in effect for this seat.`,...S]}):(t.dryRun||(await Sl(),await Zs(aa(),El(I))),{status:"held",messages:S})}let r=wn(),o=!1;if(!t.dryRun)try{await KC(r)}catch{r=void 0,o=!0}let a;try{a=await Ke(n)}catch{return{status:"manual",messages:[`Couldn't parse ${n}; left it untouched. Under "models.providers", add:`,` "anthropic": { "baseUrl": ${JSON.stringify(e.anthropicBaseUrl)}, "api": "${zf}", "maxTokens": ${qf}, "apiKey": "<your personal ark_ key>", "headers": { "${sa}": "<your personal ark_ key>", "${so}": "${Il}" } }`,` "openai": { "baseUrl": ${JSON.stringify(e.openaiBaseUrl)}, "apiKey": "<your personal ark_ key>", "headers": { "${sa}": "<your personal ark_ key>" } }`,`Set "agents.defaults.model.primary" to a routed model (e.g. "${Rl}") if none is set,`,'and under "agents.defaults.params" set "cacheRetention": "short" \u2014',"custom Anthropic-compatible hosts get no prompt-cache auto-seed, and","an unset value would leave the provider cache permanently cold.","Then run `openclaw config validate`."]}}let{next:s,routed:i,cacheRetentionSeeded:c,betaPreserved:l,headerConflicts:d,primarySeeded:u,fallbacksSeeded:p,unroutedPrimary:m,unroutedFallbacks:f,structureConflicts:h,pluginConfigured:w}=WN(a.data,e,r),y=s,g=!1;if(!i.includes("openai")){let S=jf(y,await Jo(n),["openai"]);S.removed&&(y=S.next,g=!0)}let b=[i.includes("openai")?`${n} \u2192 models.providers.anthropic baseUrl = ${e.anthropicBaseUrl}; models.providers.openai baseUrl = ${e.openaiBaseUrl}`:`${n} \u2192 models.providers.anthropic baseUrl = ${e.anthropicBaseUrl}; openai left on its native ChatGPT sign-in`,e.byoUpstream?`Auth (anthropic): your personal upstream key (written to the config, not shown here) \u2014 the gateway forwards it verbatim to ${e.byoUpstream.url} (must be in the gateway's custom-host allowlist).`:e.clientKey?"Auth: your personal gateway key (written to the config, not shown here) \u2014 the gateway swaps in the server-held provider key.":"Enrollment required before a real apply; the gateway does not accept a shared placeholder.",`Attribution: ${fe({...e.metadata,tool:Ys})??"(none \u2014 pass --user, or --enroll for a per-user key)"}`,...c?['Seeded agents.defaults.params.cacheRetention = "short": OpenClaw',"skips its prompt-cache auto-seed on custom hosts, and an unset","value would leave the provider cache permanently cold."]:["Kept your existing cacheRetention setting."],...l?[`Kept your existing ${so} header value (OpenClaw suppresses its implicit beta headers off-host; yours replaces our default restore).`]:[],...d.length>0?[`Could not add headers on models.providers.${d.join(", ")}: the existing "headers" value is not an object. Fix it manually; nothing there was replaced.`]:[],...u?[`Seeded agents.defaults.model.primary = ${w?em:Rl} (none was set; routing is inert until the primary resolves to a routed provider).`,...p?[`Seeded agents.defaults.model.fallbacks = [${(w?tm:Qf).join(", ")}] so failover stays on a routed provider.`]:[]]:[],...m!==void 0?[`Your primary model (${m}) resolves to a provider Connect does not route, so those requests bypass the gateway. Pick an anthropic/* or openai/* model to route them; your setting was kept.`]:[],...f.length>0?[`Fallback model(s) ${f.join(", ")} resolve to unrouted providers: a failover would bypass the gateway. Your settings were kept.`]:[],...g?["Removed the earlier Anyray route from models.providers.openai \u2014 your ChatGPT sign-in keeps that lane native now."]:[],...w?[`${t.dryRun?"Would install":"Installed"} the Anyray OpenClaw plugin (${wn()}) and registered it under plugins.entries.${Xe}: anyray/* models get per-conversation optimization sessions. Restart the OpenClaw gateway once to load it.`]:[],...o?[`Could not write the Anyray OpenClaw plugin to ${wn()}; routing continues via the provider entries alone (anthropic/* models).`]:[],...h.length>0?[`Left ${h.join(", ")} untouched: the existing value has the wrong shape (array or null where an object belongs), and OpenClaw's strict schema will refuse it as-is. Fix the shape and re-run.`]:[],"OpenClaw hot-reloads model config; run `openclaw config validate` to confirm the merged config passes its strict schema."],k=d.length>0||h.length>0?"manual":"configured";if(t.dryRun)return{status:k,messages:b};let C=await dn(n,a,y,!0);return w&&await Zs(aa(),El(y)),{status:k,messages:b,changedFiles:C?[n]:[]}},async pointsAt(e){try{let{data:t}=await Ke(oa());for(let a of Object.values(Jf(t)))if(N(a)&&jC(a.baseUrl,e))return!0;let n=N(t.plugins)?t.plugins:{},o=(N(n.entries)?n.entries:{})[Xe];if(N(o)&&N(o.config)&&jC(o.config.gatewayUrl,e))return!0}catch{}return!1},async routingExpected(e){return e.includes(Ys)},async inferenceAuthLanes(){let e=new Set;try{let{data:t}=await Ke(oa());for(let a of Object.values(Jf(t))){if(!N(a))continue;let s=N(a.headers)?a.headers:{};typeof s["x-anyray-custom-host"]=="string"?e.add("byo"):(typeof s[sa]=="string"||typeof a.apiKey=="string"&&a.apiKey.startsWith("ark_"))&&e.add("api_key")}let n=N(t.plugins)?t.plugins:{},o=(N(n.entries)?n.entries:{})[Xe];if(N(o)&&N(o.config)){let a=o.config.apiKey;typeof a=="string"&&a.startsWith("ark_")&&e.add("api_key")}}catch{e.add("unknown")}return e.size>0?[...e]:["unknown"]},async revert(e){let t=oa();if(!await x(t))return{status:"not-found",messages:["nothing to revert"]};if(e.dryRun)return{status:"reverted",messages:[`would remove Anyray provider settings from ${t}`]};let n;try{n=await Ke(t)}catch{return{status:"manual",messages:[`Couldn't parse ${t} \u2014 if you added Anyray settings there by hand, remove baseUrl/apiKey and the x-anyray-* headers from models.providers.anthropic and models.providers.openai yourself.`]}}let{next:r,removed:o}=jf(n.data,await Jo(t),xl,wn()),a=await Sl();return await Zs(aa(),El(r)),o?(await dn(t,n,r,!1),await ie(t),{status:"reverted",messages:[`removed Anyray provider settings from ${t}`,...a?[`removed the Anyray OpenClaw plugin from ${wn()}`]:[]],changedFiles:[t]}):(await ie(t),{status:"reverted",messages:["no Anyray provider settings found",...a?[`removed the Anyray OpenClaw plugin from ${wn()}`]:[]]})}};import{execFile as PB}from"node:child_process";import{readFile as DB}from"node:fs/promises";import{homedir as fi,platform as Er}from"node:os";import{join as kn}from"node:path";import{isDeepStrictEqual as Um,promisify as LB}from"node:util";var Js=e=>{if(!/^\d+(?:\.\d+)+$/.test(e))return;let t=e.split(".").map(Number);return t.every(Number.isSafeInteger)?t:void 0},Tl=(e,t)=>{let n=Js(e),r=Js(t);if(!(!n||!r)){for(let o=0;o<Math.max(n.length,r.length);o+=1){let a=(n[o]??0)-(r[o]??0);if(a!==0)return a}return 0}};import{randomUUID as JM}from"node:crypto";import{promises as sv}from"node:fs";import{platform as XM,tmpdir as zM}from"node:os";import{join as Yl}from"node:path";import{execFile as HN}from"node:child_process";import{promises as Xs}from"node:fs";import{homedir as GN,platform as VN}from"node:os";import{delimiter as KN,join as _l}from"node:path";import{promisify as jN}from"node:util";var ZN=jN(HN),YN=15*6e4,JN=64*1024*1024,XN=e=>e==="win32"?[".exe",".cmd",".bat"]:[""],JC=async(e={})=>{let t=(e.home??GN)(),n=e.env??process.env,r=XN(e.runtimePlatform??VN()),o=[_l(t,".local","bin"),_l(t,".claude","local"),...(n.PATH??"").split(KN).filter(a=>a.length>0)];for(let a of o)for(let s of r){let i=_l(a,`claude${s}`);try{return await Xs.access(i),i}catch{}}return null},zN=e=>{if(!Array.isArray(e))return[];let t=[];for(let n of e){if(typeof n!="object"||n===null)continue;let{uuid:r,name:o,dirName:a}=n;typeof r!="string"||typeof a!="string"||a.length===0||a.includes("/")||a.includes("\\")||a==="."||a===".."||t.push({uuid:r,name:typeof o=="string"&&o.length>0?o:"Project",dirName:a})}return t},qN=async e=>{let t=_l(e,"projects"),n;try{n=(await Xs.readdir(t,{withFileTypes:!0})).filter(o=>o.isDirectory()).map(o=>o.name)}catch{return[]}let r=[];for(let o of n){let a=o.slice(-36);if(!t$.test(a))continue;let s=o.slice(0,-37).split("-").filter(i=>i.length>0).map(i=>i[0].toUpperCase()+i.slice(1)).join(" ");r.push({uuid:a,name:s.length>0?s:"Project",dirName:o})}return r},QN=e=>{if(!e||!e.startsWith("{"))return null;let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!="object"||t===null)return null;let n=t,r=n.sessionIds,o=n.jsonlPaths;if(!Array.isArray(r)||!Array.isArray(o))return null;let a=Array.isArray(n.titles)?n.titles:[],s=Array.isArray(n.createdAts)?n.createdAts:[],i=Array.isArray(n.updatedAts)?n.updatedAts:[],c=d=>typeof d=="number"&&Number.isFinite(d)?d:void 0,l=[];for(let d=0;d<r.length;d+=1){let u=r[d],p=o[d];if(typeof u!="string"||typeof p!="string"||u.length===0||p.length===0)continue;let m=a[d];l.push({sessionId:u,transcriptPath:p,title:typeof m=="string"&&m.length>0?m:"Imported conversation",createdAt:c(s[d]),lastActivityAt:c(i[d])})}return{conversations:l,projects:zN(n.projectList)}},e$=async e=>{let t,n;try{let r=await Xs.readFile(e,"utf8");for(let o of r.split(`
|
|
171
171
|
`)){if(o.length===0)continue;let a;try{a=JSON.parse(o).timestamp}catch{continue}if(typeof a!="string")continue;let s=Date.parse(a);Number.isFinite(s)&&(t??=s,n=s)}}catch{return{}}return{createdAt:t,lastActivityAt:n??t}},t$=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,n$=/\.(?:cmd|bat)$/i,r$=(e,t)=>n$.test(e)?{file:"cmd.exe",args:["/d","/s","/c",`"${[e,...t].map(r=>`"${r}"`).join(" ")}"`],verbatim:!0}:{file:e,args:[...t],verbatim:!1},XC=async(e,t={})=>{let n=t.exec??ZN,r=["import-conversations",e.exportPath,"--cwd",e.workDir];if([e.binary,...r].some(d=>d.includes('"')))return{ok:!1,reason:"the export path contains an unsupported character"};await Xs.mkdir(e.configDir,{recursive:!0,mode:448}),await Xs.mkdir(e.workDir,{recursive:!0,mode:448});let o=r$(e.binary,r),a;try{a=(await n(o.file,o.args,{env:{...process.env,CLAUDE_IMPORT_CONVERSATIONS:"1",CLAUDE_CONFIG_DIR:e.configDir},timeout:YN,maxBuffer:JN,windowsVerbatimArguments:o.verbatim})).stdout}catch(d){let u=d.code;return{ok:!1,reason:typeof u=="number"?`the Claude Code importer exited with status ${u}`:"the Claude Code importer could not be run"}}let s=a.split(`
|
|
172
|
-
`).filter(d=>d.trim().length>0),i=QN(s.at(-1));if(!i)return{ok:!1,reason:"the Claude Code importer produced no readable summary"};let c=await Promise.all(i.conversations.map(async d=>{if(d.createdAt!==void 0)return d;let u=await e$(d.transcriptPath);return{...d,...u}})),l=i.projects.length>0?i.projects:await qN(e.workDir);return{ok:!0,conversations:c,projects:l}};import{randomUUID as o$}from"node:crypto";import{promises as Bn}from"node:fs";import{homedir as a$,platform as s$}from"node:os";import{join as kt}from"node:path";var zC=448,Fn="local_",i$="local-agent-mode-sessions",nm="-3p",c$="cowork_account_settings.json",io=(e={})=>{let t=(e.home??a$)(),n=e.runtimePlatform??s$(),r=e.env??process.env;if(n==="darwin")return kt(t,"Library","Application Support",`Claude${nm}`);if(n==="win32"){let o=r.LOCALAPPDATA??kt(t,"AppData","Local");return kt(o,`Claude${nm}`)}return null},zs=(e={})=>{let t=io(e);return t?t.slice(0,-nm.length):null},rm=e=>{let t=e.replace(/[^a-zA-Z0-9]/g,"-");if(t.length<=200)return t;let n=0;for(let r=0;r<e.length;r+=1)n=Math.imul(n,31)+e.charCodeAt(r)|0;return`${t.slice(0,200)}-${Math.abs(n).toString(36)}`},Pl=async e=>{let t=kt(e,i$),n;try{n=(await Bn.readdir(t,{withFileTypes:!0})).filter(o=>o.isDirectory()).map(o=>o.name)}catch{return{ok:!1,reason:"no-profile",found:[]}}let r=[];for(let o of n){let a;try{a=(await Bn.readdir(kt(t,o),{withFileTypes:!0})).filter(s=>s.isDirectory()).map(s=>s.name)}catch{continue}for(let s of a){let i=kt(t,o,s);try{await Bn.access(kt(i,c$)),r.push(i)}catch{}}}return r.length===0?{ok:!1,reason:"no-account",found:[]}:r.length>1?{ok:!1,reason:"ambiguous",found:r}:{ok:!0,dir:r[0]}},om=async e=>{try{let t=await Bn.readdir(e);return new Set(t.filter(n=>n.startsWith(Fn)&&n.endsWith(".json")).map(n=>n.slice(Fn.length,-5)))}catch{return new Set}},ia=e=>/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e),l$=async(e,t)=>{let n=`${Fn}${t.sessionId}`,r=kt(e,n),o=kt(r,"outputs"),a=kt(r,".claude"),s=kt(a,"projects",rm(o));await Bn.mkdir(o,{recursive:!0,mode:zC}),await Bn.mkdir(s,{recursive:!0,mode:zC});let i=kt(s,`${t.sessionId}.jsonl`),c=`${i}.anyray-tmp-${process.pid}-${o$()}`;await Bn.copyFile(t.transcriptPath,c),await Bn.chmod(c,384),await Bn.rename(c,i);let l=t.createdAt??Date.now();await J(kt(e,`${n}.json`),{sessionId:n,cliSessionId:t.sessionId,processName:"claude-ai-import",cwd:o,hostLoopMode:!0,title:t.title,createdAt:l,lastActivityAt:t.lastActivityAt??l,isArchived:!1,userSelectedFolders:[],pendingNotifications:[]},{backup:!1})},qC=async(e,t)=>{let n=await om(e),r={registered:0,skipped:0,failed:0};for(let o of t){if(!ia(o.sessionId)){r.failed+=1;continue}if(n.has(o.sessionId)){r.skipped+=1;continue}try{await l$(e,o),n.add(o.sessionId),r.registered+=1}catch{r.failed+=1}}return r};import{promises as ca}from"node:fs";import{homedir as d$}from"node:os";import{dirname as u$,join as qs}from"node:path";var p$=448,f$=["Documents","Claude","Projects"],m$="spaces.json",h$=(e={})=>qs((e.home??d$)(),...f$),y$=async e=>{try{let t=JSON.parse(await ca.readFile(e,"utf8"));if(!t||typeof t!="object")return{spaces:[],readable:!1};let n=t.spaces;return Array.isArray(n)?{spaces:n.filter(r=>!!r&&typeof r=="object"&&typeof r.id=="string"),readable:!0}:{spaces:[],readable:!1}}catch(t){return t.code==="ENOENT"?{spaces:[],readable:!0}:{spaces:[],readable:!1}}},g$=e=>{let t=e.replace(/[/\\:*?"<>|\x00-\x1f]/g," ").replace(/\s+/g," ").replace(/^[.\s]+/,"").slice(0,60).trim();return t.length>0?t:"Project"},am=async e=>{try{return await ca.access(e),!0}catch{return!1}},w$=async(e,t,n)=>{let r=qs(t,g$(n.name)),o=`${r} (${n.uuid.slice(0,8)})`,a=await am(r)?o:r;return a===o&&await am(o)?null:(await ca.mkdir(u$(a),{recursive:!0}),await ca.cp(e,a,{recursive:!0}),a)},b$=async e=>{try{let t=(await ca.readFile(qs(e,"CLAUDE.md"),"utf8")).trim();return t.length>0?t:void 0}catch{return}},QC=async e=>{let t=h$({home:e.home}),n={imported:0,alreadyPresent:0,skippedCollision:0,failed:0,root:t},r=e.projects??[];if(r.length===0)return n;let o=qs(e.storageDir,m$),{spaces:a,readable:s}=await y$(o);if(!s)return n.failed=r.length,n;let i=new Set(a.map(l=>l.id)),c=[];for(let l of r){if(i.has(l.uuid)){n.alreadyPresent+=1;continue}let d=qs(e.stagedProjectsDir,l.dirName);try{if(!await am(d)){n.failed+=1;continue}let u=await w$(d,t,l);if(!u){n.skippedCollision+=1;continue}let p=await b$(u);c.push({id:l.uuid,name:l.name,folders:[{path:u}],projects:[],links:[],...p?{instructions:p}:{},origin:"user",createdAt:e.now,updatedAt:e.now}),n.imported+=1}catch{n.failed+=1}}return c.length>0&&(await ca.mkdir(e.storageDir,{recursive:!0,mode:p$}),await J(o,{spaces:[...a,...c]},{backup:!1})),n};import{randomUUID as v$}from"node:crypto";import{execFile as S$,spawnSync as dk}from"node:child_process";import{constants as uk}from"node:fs";import{access as Bl,chmod as E$,mkdir as I$,readdir as x$,readFile as im,rename as R$,rm as la,stat as pk,writeFile as O$}from"node:fs/promises";import{homedir as T$,platform as _$,userInfo as P$}from"node:os";import{basename as D$,dirname as fk,isAbsolute as da,join as Nt,resolve as ok}from"node:path";import{isDeepStrictEqual as ei,promisify as L$}from"node:util";var kr="__anyray-claude-desktop-credential",Qs="__anyray-claude-desktop-bootstrap-headers";var Dl=["Heads up: Claude Desktop's third-party mode uses its own app profile, so it opens signed out with empty conversation lists. Nothing is deleted and your Claude account is unchanged \u2014 sign back in with the account you already use.","Your Claude Code sessions and Cowork tasks come across on their own once this new profile has been signed in to and the app is fully quit \u2014 no second command.","Your claude.ai chats live on your Claude account rather than this machine, so those need your data export: `anyray-connect migrate --export <file.zip>`."],Ll=["Your Claude account conversations are reachable in the app again once it reopens.","Chats made while third-party mode was active stay in its separate profile and come back if you configure it again."],ek="Note: third-party mode runs in a separate app profile, so Claude Desktop starts with empty conversation lists while it is active. Nothing is lost \u2014 local sessions come across on their own once the profile is signed in to and Claude Desktop is fully quit (see any queued migration above), claude.ai chats need your data export via `anyray-connect migrate --export <file.zip>`, and `anyray-connect desktop disconnect` restores the first-party profile.";var Nl=["disableAutoUpdates","autoUpdaterEnforcementHours","disableWslSessions"],tk=["allowOptionalClientAuth","allowedPluginMarketplaces","allowedWorkspaceFolders","autoModeEnabled","autoUpdaterEnforcementHours","banner","bootstrapEnabled","bootstrapHeaders","bootstrapHeadersHelper","bootstrapOidc","bootstrapUrl","builtinToolPolicy","chatAdvancedFileAnalysisEnabled","chatTabEnabled","claudeAiImport","coworkEgressAllowedHosts","coworkTabEnabled","deploymentDisplayName","deploymentDisplaySubtitle","deploymentOrganizationUuid","disableAutoUpdates","disableBundledSkills","disableDeepLinkRegistration","disableDeploymentModeChooser","disableEssentialTelemetry","disableFeatureDiscovery","disableNonessentialServices","disableNonessentialTelemetry","disableWslSessions","disabledBuiltinTools","enduserAttribution","forceLoginOrgUUID","hardwareBuddyEnabled","inferenceAnthropicApiKey","inferenceBedrockAwsCliPath","inferenceBedrockAwsDir","inferenceBedrockBaseUrl","inferenceBedrockBearerToken","inferenceBedrockProfile","inferenceBedrockRegion","inferenceBedrockServiceTier","inferenceBedrockSsoAccountId","inferenceBedrockSsoRegion","inferenceBedrockSsoRoleName","inferenceBedrockSsoStartUrl","inferenceCredentialHelper","inferenceCredentialHelperSilentRefreshEnabled","inferenceCredentialHelperTimeoutSec","inferenceCredentialHelperTtlSec","inferenceCredentialKind","inferenceCustomHeaders","inferenceFoundryApiKey","inferenceFoundryAuthFlow","inferenceFoundryClientId","inferenceFoundryResource","inferenceFoundryTenantId","inferenceGatewayApiKey","inferenceGatewayAuthScheme","inferenceGatewayBaseUrl","inferenceGatewayOidc","inferenceMaxTokensPerWindow","inferenceModels","inferenceProvider","inferenceSessionLifetimeSec","inferenceTokenWindowHours","inferenceVertexBaseUrl","inferenceVertexCredentialsFile","inferenceVertexOAuthClientId","inferenceVertexOAuthClientSecret","inferenceVertexOAuthLoginHint","inferenceVertexOAuthScopes","inferenceVertexProjectId","inferenceVertexRegion","inferenceVertexWorkforceAudience","inferenceVertexWorkforceOidc","inferenceVertexWorkforceUserProject","isClaudeCodeForDesktopEnabled","isDesktopExtensionDirectoryEnabled","isDesktopExtensionEnabled","isDesktopExtensionSignatureRequired","isLocalDevMcpEnabled","loginSsoOrgDomain","managedMcpServers","mcpPersistentAlwaysAllowEnabled","microsoftAuthBroker","modelDiscoveryEnabled","orgPluginSettings","organizationPluginsUrl","otlpContentCapture","otlpDesktopLogLevel","otlpEndpoint","otlpHeaders","otlpProtocol","otlpResourceAttributes","otlpTracesEnabled","requireCoworkFullVmSandbox","secureVmFeaturesEnabled","toolSearchEnabled","userContentRendererUrl"],A$=new Set(tk),C$=new Set(tk.map(e=>e.toLowerCase())),k$=new Set(Nl.map(e=>e.toLowerCase())),$l=(e,t=!1)=>(t?C$:A$).has(t?e.toLowerCase():e),nk=(e,t=!1)=>t?k$.has(e.toLowerCase()):Nl.some(n=>n===e),rk=["*"],co=(e,t)=>({inferenceProvider:"gateway",inferenceGatewayBaseUrl:e.anthropicBaseUrl,inferenceGatewayAuthScheme:"bearer",inferenceCredentialKind:"helper-script",inferenceCredentialHelper:t,chatTabEnabled:!0,coworkEgressAllowedHosts:[...rk]}),vr=e=>Object.fromEntries(Object.entries(e).map(([t,n])=>[t,typeof n=="object"?JSON.stringify(n):String(n)]));var ti=/^[a-f0-9-]{36}$/,mk="Anyray",cm=4,oi=["inferenceProvider","inferenceGatewayBaseUrl","inferenceGatewayAuthScheme","inferenceCredentialKind","inferenceCredentialHelper","chatTabEnabled","coworkEgressAllowedHosts","inferenceGatewayApiKey"],ai=["deploymentMode","awaitingSignIn"],hk=[...oi,...ai,"configLibrary","_meta.json"],bn=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),it=e=>structuredClone(e),ni=async e=>{try{return await Bl(e),!0}catch{return!1}},N$=async e=>{try{let t=await x$(fk(e)),n=D$(e).toLowerCase();return t.some(r=>r.toLowerCase()===n)?"unreadable":"absent"}catch{return"unreadable"}},$$=async e=>{try{return await Bl(e),"present"}catch(t){return(t instanceof Error&&"code"in t?t.code:void 0)==="ENOENT"?"absent":N$(e)}},Jt=(e={})=>{let t=(e.home??T$)(),n=(e.username??(()=>P$().username))(),r=Nt(t,"Library","Application Support","Claude-3p"),o=e.managedPolicyPaths?e.managedPolicyPaths():["/Library/Managed Preferences/com.anthropic.claudefordesktop.plist",Nt("/Library/Managed Preferences",n,"com.anthropic.claudefordesktop.plist")];return{root:r,library:Nt(r,"configLibrary"),meta:Nt(r,"configLibrary","_meta.json"),appConfig:Nt(r,"claude_desktop_config.json"),helper:Nt(t,".anyray","bin","claude-desktop-credential-helper"),journal:Nt(t,".anyray","claude-desktop-native.json"),managedPolicies:o}},Fl=()=>{let e=dk("pgrep",["-x","Claude"],{stdio:"ignore",timeout:2e3,windowsHide:!0});return!!e.error||e.status!==1},yk=e=>["print-key",e==="passthrough"?"--passthrough-headers":"--json"],M$=(e,t)=>{let n=e.args.lastIndexOf("print-key"),r=n>=0?e.args.slice(0,n):e.args;return{...e,args:[...r,...yk(t)]}},lm=(e="json")=>{let t=nn(yk(e)),n=ok(t.command),r=ok(t.entryPath),o=/[\\/](node|node\.exe)$/i.test(n);return{command:n,args:o&&r!==n?[r,...t.args.slice(1)]:t.args,durable:oe()&&(!o||r!==n)}},B$=e=>`'${e.replace(/'/g,`'"'"'`)}'`,dm=e=>[e.command,...e.args].map(B$).join(" "),F$=e=>{if(!e.durable)throw new Error("the anyray-connect runtime is temporary");if(!da(e.command))throw new Error("the credential helper executable is not absolute")},gk=(e,t)=>{F$(e);let n=Wl(e.command);if(e.args.at(-2)!=="print-key"||e.args.at(-1)!==t||(n?e.args.length!==3||!da(e.args[0]):e.args.length!==2))throw new Error(`the credential helper does not use print-key ${t}`)},wk=e=>(gk(e,"--json"),`#!/bin/sh
|
|
172
|
+
`).filter(d=>d.trim().length>0),i=QN(s.at(-1));if(!i)return{ok:!1,reason:"the Claude Code importer produced no readable summary"};let c=await Promise.all(i.conversations.map(async d=>{if(d.createdAt!==void 0)return d;let u=await e$(d.transcriptPath);return{...d,...u}})),l=i.projects.length>0?i.projects:await qN(e.workDir);return{ok:!0,conversations:c,projects:l}};import{randomUUID as o$}from"node:crypto";import{promises as Bn}from"node:fs";import{homedir as a$,platform as s$}from"node:os";import{join as kt}from"node:path";var zC=448,Fn="local_",i$="local-agent-mode-sessions",nm="-3p",c$="cowork_account_settings.json",io=(e={})=>{let t=(e.home??a$)(),n=e.runtimePlatform??s$(),r=e.env??process.env;if(n==="darwin")return kt(t,"Library","Application Support",`Claude${nm}`);if(n==="win32"){let o=r.LOCALAPPDATA??kt(t,"AppData","Local");return kt(o,`Claude${nm}`)}return null},zs=(e={})=>{let t=io(e);return t?t.slice(0,-nm.length):null},rm=e=>{let t=e.replace(/[^a-zA-Z0-9]/g,"-");if(t.length<=200)return t;let n=0;for(let r=0;r<e.length;r+=1)n=Math.imul(n,31)+e.charCodeAt(r)|0;return`${t.slice(0,200)}-${Math.abs(n).toString(36)}`},Pl=async e=>{let t=kt(e,i$),n;try{n=(await Bn.readdir(t,{withFileTypes:!0})).filter(o=>o.isDirectory()).map(o=>o.name)}catch{return{ok:!1,reason:"no-profile",found:[]}}let r=[];for(let o of n){let a;try{a=(await Bn.readdir(kt(t,o),{withFileTypes:!0})).filter(s=>s.isDirectory()).map(s=>s.name)}catch{continue}for(let s of a){let i=kt(t,o,s);try{await Bn.access(kt(i,c$)),r.push(i)}catch{}}}return r.length===0?{ok:!1,reason:"no-account",found:[]}:r.length>1?{ok:!1,reason:"ambiguous",found:r}:{ok:!0,dir:r[0]}},om=async e=>{try{let t=await Bn.readdir(e);return new Set(t.filter(n=>n.startsWith(Fn)&&n.endsWith(".json")).map(n=>n.slice(Fn.length,-5)))}catch{return new Set}},ia=e=>/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e),l$=async(e,t)=>{let n=`${Fn}${t.sessionId}`,r=kt(e,n),o=kt(r,"outputs"),a=kt(r,".claude"),s=kt(a,"projects",rm(o));await Bn.mkdir(o,{recursive:!0,mode:zC}),await Bn.mkdir(s,{recursive:!0,mode:zC});let i=kt(s,`${t.sessionId}.jsonl`),c=`${i}.anyray-tmp-${process.pid}-${o$()}`;await Bn.copyFile(t.transcriptPath,c),await Bn.chmod(c,384),await Bn.rename(c,i);let l=t.createdAt??Date.now();await J(kt(e,`${n}.json`),{sessionId:n,cliSessionId:t.sessionId,processName:"claude-ai-import",cwd:o,hostLoopMode:!0,title:t.title,createdAt:l,lastActivityAt:t.lastActivityAt??l,isArchived:!1,userSelectedFolders:[],pendingNotifications:[]},{backup:!1})},qC=async(e,t)=>{let n=await om(e),r={registered:0,skipped:0,failed:0};for(let o of t){if(!ia(o.sessionId)){r.failed+=1;continue}if(n.has(o.sessionId)){r.skipped+=1;continue}try{await l$(e,o),n.add(o.sessionId),r.registered+=1}catch{r.failed+=1}}return r};import{promises as ca}from"node:fs";import{homedir as d$}from"node:os";import{dirname as u$,join as qs}from"node:path";var p$=448,f$=["Documents","Claude","Projects"],m$="spaces.json",h$=(e={})=>qs((e.home??d$)(),...f$),y$=async e=>{try{let t=JSON.parse(await ca.readFile(e,"utf8"));if(!t||typeof t!="object")return{spaces:[],readable:!1};let n=t.spaces;return Array.isArray(n)?{spaces:n.filter(r=>!!r&&typeof r=="object"&&typeof r.id=="string"),readable:!0}:{spaces:[],readable:!1}}catch(t){return t.code==="ENOENT"?{spaces:[],readable:!0}:{spaces:[],readable:!1}}},g$=e=>{let t=e.replace(/[/\\:*?"<>|\x00-\x1f]/g," ").replace(/\s+/g," ").replace(/^[.\s]+/,"").slice(0,60).trim();return t.length>0?t:"Project"},am=async e=>{try{return await ca.access(e),!0}catch{return!1}},w$=async(e,t,n)=>{let r=qs(t,g$(n.name)),o=`${r} (${n.uuid.slice(0,8)})`,a=await am(r)?o:r;return a===o&&await am(o)?null:(await ca.mkdir(u$(a),{recursive:!0}),await ca.cp(e,a,{recursive:!0}),a)},b$=async e=>{try{let t=(await ca.readFile(qs(e,"CLAUDE.md"),"utf8")).trim();return t.length>0?t:void 0}catch{return}},QC=async e=>{let t=h$({home:e.home}),n={imported:0,alreadyPresent:0,skippedCollision:0,failed:0,root:t},r=e.projects??[];if(r.length===0)return n;let o=qs(e.storageDir,m$),{spaces:a,readable:s}=await y$(o);if(!s)return n.failed=r.length,n;let i=new Set(a.map(l=>l.id)),c=[];for(let l of r){if(i.has(l.uuid)){n.alreadyPresent+=1;continue}let d=qs(e.stagedProjectsDir,l.dirName);try{if(!await am(d)){n.failed+=1;continue}let u=await w$(d,t,l);if(!u){n.skippedCollision+=1;continue}let p=await b$(u);c.push({id:l.uuid,name:l.name,folders:[{path:u}],projects:[],links:[],...p?{instructions:p}:{},origin:"user",createdAt:e.now,updatedAt:e.now}),n.imported+=1}catch{n.failed+=1}}return c.length>0&&(await ca.mkdir(e.storageDir,{recursive:!0,mode:p$}),await J(o,{spaces:[...a,...c]},{backup:!1})),n};import{randomUUID as v$}from"node:crypto";import{execFile as S$,spawnSync as dk}from"node:child_process";import{constants as uk}from"node:fs";import{access as Bl,chmod as E$,mkdir as I$,readdir as x$,readFile as im,rename as R$,rm as la,stat as pk,writeFile as O$}from"node:fs/promises";import{homedir as T$,platform as _$,userInfo as P$}from"node:os";import{basename as D$,dirname as fk,isAbsolute as da,join as Nt,resolve as ok}from"node:path";import{isDeepStrictEqual as ei,promisify as L$}from"node:util";var kr="__anyray-claude-desktop-credential",Qs="__anyray-claude-desktop-bootstrap-headers";var Dl=["Heads up: Claude Desktop's third-party mode uses its own app profile, so it opens signed out with empty conversation lists. Nothing is deleted and your Claude account is unchanged \u2014 sign back in with the account you already use.","Your Claude Code sessions and Cowork tasks come across on their own once this new profile has been signed in to and the app is fully quit \u2014 no second command.","Your claude.ai chats live on your Claude account rather than this machine, so those need your data export: `anyray-connect migrate --export <file.zip>`."],Ll=["Your Claude account conversations are reachable in the app again once it reopens.","Chats made while third-party mode was active stay in its separate profile and come back if you configure it again."],ek="Note: third-party mode runs in a separate app profile, so Claude Desktop starts with empty conversation lists while it is active. Nothing is lost \u2014 local sessions come across on their own once the profile is signed in to and Claude Desktop is fully quit (see any queued migration above), claude.ai chats need your data export via `anyray-connect migrate --export <file.zip>`, and `anyray-connect desktop disconnect` restores the first-party profile.";var Nl=["disableAutoUpdates","autoUpdaterEnforcementHours","disableWslSessions"],tk=["allowOptionalClientAuth","allowedPluginMarketplaces","allowedWorkspaceFolders","autoModeEnabled","autoUpdaterEnforcementHours","banner","bootstrapEnabled","bootstrapHeaders","bootstrapHeadersHelper","bootstrapOidc","bootstrapUrl","builtinToolPolicy","chatAdvancedFileAnalysisEnabled","chatTabEnabled","claudeAiImport","coworkEgressAllowedHosts","coworkTabEnabled","deploymentDisplayName","deploymentDisplaySubtitle","deploymentOrganizationUuid","disableAutoUpdates","disableBundledSkills","disableDeepLinkRegistration","disableDeploymentModeChooser","disableEssentialTelemetry","disableFeatureDiscovery","disableNonessentialServices","disableNonessentialTelemetry","disableWslSessions","disabledBuiltinTools","enduserAttribution","forceLoginOrgUUID","hardwareBuddyEnabled","inferenceAnthropicApiKey","inferenceBedrockAwsCliPath","inferenceBedrockAwsDir","inferenceBedrockBaseUrl","inferenceBedrockBearerToken","inferenceBedrockProfile","inferenceBedrockRegion","inferenceBedrockServiceTier","inferenceBedrockSsoAccountId","inferenceBedrockSsoRegion","inferenceBedrockSsoRoleName","inferenceBedrockSsoStartUrl","inferenceCredentialHelper","inferenceCredentialHelperSilentRefreshEnabled","inferenceCredentialHelperTimeoutSec","inferenceCredentialHelperTtlSec","inferenceCredentialKind","inferenceCustomHeaders","inferenceFoundryApiKey","inferenceFoundryAuthFlow","inferenceFoundryClientId","inferenceFoundryResource","inferenceFoundryTenantId","inferenceGatewayApiKey","inferenceGatewayAuthScheme","inferenceGatewayBaseUrl","inferenceGatewayOidc","inferenceMaxTokensPerWindow","inferenceModels","inferenceProvider","inferenceSessionLifetimeSec","inferenceTokenWindowHours","inferenceVertexBaseUrl","inferenceVertexCredentialsFile","inferenceVertexOAuthClientId","inferenceVertexOAuthClientSecret","inferenceVertexOAuthLoginHint","inferenceVertexOAuthScopes","inferenceVertexProjectId","inferenceVertexRegion","inferenceVertexWorkforceAudience","inferenceVertexWorkforceOidc","inferenceVertexWorkforceUserProject","isClaudeCodeForDesktopEnabled","isDesktopExtensionDirectoryEnabled","isDesktopExtensionEnabled","isDesktopExtensionSignatureRequired","isLocalDevMcpEnabled","loginSsoOrgDomain","managedMcpServers","mcpPersistentAlwaysAllowEnabled","microsoftAuthBroker","modelDiscoveryEnabled","orgPluginSettings","organizationPluginsUrl","otlpContentCapture","otlpDesktopLogLevel","otlpEndpoint","otlpHeaders","otlpProtocol","otlpResourceAttributes","otlpTracesEnabled","requireCoworkFullVmSandbox","secureVmFeaturesEnabled","toolSearchEnabled","userContentRendererUrl"],A$=new Set(tk),C$=new Set(tk.map(e=>e.toLowerCase())),k$=new Set(Nl.map(e=>e.toLowerCase())),$l=(e,t=!1)=>(t?C$:A$).has(t?e.toLowerCase():e),nk=(e,t=!1)=>t?k$.has(e.toLowerCase()):Nl.some(n=>n===e),rk=["*"],co=(e,t)=>({inferenceProvider:"gateway",inferenceGatewayBaseUrl:e.anthropicBaseUrl,inferenceGatewayAuthScheme:"bearer",inferenceCredentialKind:"helper-script",inferenceCredentialHelper:t,chatTabEnabled:!0,coworkEgressAllowedHosts:[...rk]}),vr=e=>Object.fromEntries(Object.entries(e).map(([t,n])=>[t,typeof n=="object"?JSON.stringify(n):String(n)]));var ti=/^[a-f0-9-]{36}$/,mk="Anyray",cm=4,oi=["inferenceProvider","inferenceGatewayBaseUrl","inferenceGatewayAuthScheme","inferenceCredentialKind","inferenceCredentialHelper","chatTabEnabled","coworkEgressAllowedHosts","inferenceGatewayApiKey"],ai=["deploymentMode","awaitingSignIn"],N$=["inferenceGatewayApiKey","awaitingSignIn"],hk=[...[...oi,...ai].filter(e=>!N$.includes(e)),"configLibrary","_meta.json"],bn=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),it=e=>structuredClone(e),ni=async e=>{try{return await Bl(e),!0}catch{return!1}},$$=async e=>{try{let t=await x$(fk(e)),n=D$(e).toLowerCase();return t.some(r=>r.toLowerCase()===n)?"unreadable":"absent"}catch{return"unreadable"}},M$=async e=>{try{return await Bl(e),"present"}catch(t){return(t instanceof Error&&"code"in t?t.code:void 0)==="ENOENT"?"absent":$$(e)}},Jt=(e={})=>{let t=(e.home??T$)(),n=(e.username??(()=>P$().username))(),r=Nt(t,"Library","Application Support","Claude-3p"),o=e.managedPolicyPaths?e.managedPolicyPaths():["/Library/Managed Preferences/com.anthropic.claudefordesktop.plist",Nt("/Library/Managed Preferences",n,"com.anthropic.claudefordesktop.plist")];return{root:r,library:Nt(r,"configLibrary"),meta:Nt(r,"configLibrary","_meta.json"),appConfig:Nt(r,"claude_desktop_config.json"),helper:Nt(t,".anyray","bin","claude-desktop-credential-helper"),journal:Nt(t,".anyray","claude-desktop-native.json"),managedPolicies:o}},Fl=()=>{let e=dk("pgrep",["-x","Claude"],{stdio:"ignore",timeout:2e3,windowsHide:!0});return!!e.error||e.status!==1},yk=e=>["print-key",e==="passthrough"?"--passthrough-headers":"--json"],B$=(e,t)=>{let n=e.args.lastIndexOf("print-key"),r=n>=0?e.args.slice(0,n):e.args;return{...e,args:[...r,...yk(t)]}},lm=(e="json")=>{let t=nn(yk(e)),n=ok(t.command),r=ok(t.entryPath),o=/[\\/](node|node\.exe)$/i.test(n);return{command:n,args:o&&r!==n?[r,...t.args.slice(1)]:t.args,durable:oe()&&(!o||r!==n)}},F$=e=>`'${e.replace(/'/g,`'"'"'`)}'`,dm=e=>[e.command,...e.args].map(F$).join(" "),W$=e=>{if(!e.durable)throw new Error("the anyray-connect runtime is temporary");if(!da(e.command))throw new Error("the credential helper executable is not absolute")},gk=(e,t)=>{W$(e);let n=Wl(e.command);if(e.args.at(-2)!=="print-key"||e.args.at(-1)!==t||(n?e.args.length!==3||!da(e.args[0]):e.args.length!==2))throw new Error(`the credential helper does not use print-key ${t}`)},wk=e=>(gk(e,"--json"),`#!/bin/sh
|
|
173
173
|
exec ${dm(e)}
|
|
174
|
-
`),
|
|
174
|
+
`),U$=`#!/bin/sh
|
|
175
175
|
# Anyray subscription pass-through credential helper v2 for Claude Desktop`,bk=e=>{gk(e,"--passthrough-headers");let t={...e,args:[...e.args.slice(0,-2),kr]};return["#!/bin/sh","# Anyray subscription pass-through credential helper v2 for Claude Desktop.","# The durable credential runtime reads and validates the Keychain JSON,","# combines it with Anyray headers, and writes one credential response.",`exec ${dm(t)}`,""].join(`
|
|
176
|
-
`)},
|
|
176
|
+
`)},H$=e=>e.args.at(-1)==="--passthrough-headers"?bk(e):wk(e),Wl=e=>/[\\/](node|node\.exe)$/i.test(e),um=e=>{let t=[],n=0;for(;n<e.length;){if(e[n]!=="'")return;n++;let r="";for(;n<e.length;){let o=e.indexOf("'",n);if(o<0)return;if(r+=e.slice(n,o),e.startsWith(`'"'"'`,o)){r+="'",n=o+5;continue}n=o+1;break}if(t.push(r),n===e.length)return t;if(e[n]!==" "||n+1===e.length)return;n++}},G$=e=>{let t=`#!/bin/sh
|
|
177
177
|
exec `;if(!e.startsWith(t)||!e.endsWith(`
|
|
178
178
|
`))return;let n=e.slice(t.length,-1);if(n.includes(`
|
|
179
|
-
`)||n.includes("\r"))return;let r=um(n);if(!r||r.length!==3&&r.length!==4)return;let[o,...a]=r,s=Wl(o);if(!da(o)||a.at(-2)!=="print-key"||a.at(-1)!=="--json"||(s?a.length!==3||!da(a[0]):a.length!==2))return;let i={command:o,args:a,durable:!0};try{return wk(i)===e?i:void 0}catch{return}},
|
|
180
|
-
# Anyray subscription pass-through credential helper`,
|
|
181
|
-
`)},
|
|
182
|
-
`,384)},An=async e=>{if(!await ni(e))return{present:!1,value:{}};let t;try{t=JSON.parse(await im(e,"utf-8"))}catch{throw new Error(`${e} is not valid JSON`)}if(!bn(t))throw new Error(`${e} is not a JSON object`);return{present:!0,value:t}},si=async e=>{if(!await ni(e))return{present:!1};let t=await pk(e);return{present:!0,content:await im(e,"utf-8"),mode:t.mode&511}},Ck=(e,t)=>Object.prototype.hasOwnProperty.call(e,t)?{present:!0,value:it(e[t])}:{present:!1},sm=(e,t,n)=>{n.present?e[t]=it(n.value):delete e[t]},ak=e=>bn(e)&&typeof e.present=="boolean"&&(!e.present||Object.prototype.hasOwnProperty.call(e,"value")),
|
|
183
|
-
`,384)},ri=e=>{let{appliedId:t,entries:n}=e;if(typeof t!="string"||!ti.test(t)||!Array.isArray(n))throw new Error("Claude config-library metadata has an invalid shape");let r=new Set;for(let o of n){if(!bn(o)||typeof o.id!="string"||!ti.test(o.id)||typeof o.name!="string"||r.has(o.id))throw new Error("Claude config-library metadata has an invalid entry");r.add(o.id)}if(!r.has(t))throw new Error("Claude config-library appliedId is not in entries");return t},oM=async(e,t,n)=>{let r=await An(e.meta);if(t){if(!r.present){if(t.metaFileExisted)throw new Error("Claude config-library metadata disappeared after apply");return{configId:t.configId,meta:r,metaFileExisted:!1,metaEntry:it(t.metaEntry),metaToWrite:{appliedId:t.configId,entries:[it(t.metaEntry)]}}}let c=ri(r.value),d=r.value.entries.find(u=>u.id===t.configId);if(!d||!ei(d,t.metaEntry))throw new Error("Claude changed the Anyray config-library entry after apply");return{configId:t.configId,meta:r,metaFileExisted:t.metaFileExisted,originalAppliedId:t.originalAppliedId,metaEntry:it(t.metaEntry),...c===t.configId?{}:{metaToWrite:{...it(r.value),appliedId:t.configId}}}}let o,a=[];if(r.present){o=ri(r.value);let c=Nt(e.library,`${o}.json`);if(!await ni(c))throw new Error(`Claude's applied configuration ${o} is missing`);a=it(r.value.entries)}let s=n();if(!ti.test(s))throw new Error("could not create a valid config id");if(a.some(c=>c.id===s)||await ni(Nt(e.library,`${s}.json`)))throw new Error("could not create a unique Anyray config id");let i={id:s,name:mk};return{configId:s,meta:r,metaFileExisted:r.present,originalAppliedId:o,metaEntry:i,metaToWrite:{...r.present?it(r.value):{},appliedId:s,entries:[...a,i]}}},aM=(e,t)=>{let n=co(e,t);return{...Object.fromEntries(Object.entries(n).map(([r,o])=>[r,{present:!0,value:o}])),inferenceGatewayApiKey:{present:!1}}},kk=()=>({deploymentMode:{present:!0,value:"3p"},awaitingSignIn:{present:!1}}),sM=async(e,t,n,r,o,a,s)=>{let i=kk(),c=Object.fromEntries(oi.map(d=>[d,{original:s?.config[d].original??{present:!1},lastWritten:a[d]}])),l=Object.fromEntries(ai.map(d=>[d,{original:s?.deployment[d].original??Ck(r.value,d),lastWritten:i[d]}]));return{version:cm,configId:t.configId,metaFileExisted:s?.metaFileExisted??t.metaFileExisted,originalAppliedId:s?.originalAppliedId??t.originalAppliedId,metaEntry:s?.metaEntry??it(t.metaEntry),configFileExisted:!1,config:c,deploymentFileExisted:s?.deploymentFileExisted??r.present,deployment:l,helper:{path:e.helper,original:s?.helper.original??await si(e.helper),lastWritten:o,...s?.helper.previousWritten!==void 0?{previousWritten:s.helper.previousWritten}:s&&s.helper.lastWritten!==o?{previousWritten:s.helper.lastWritten}:{}}}},Ml=e=>({status:"manual",messages:[e]}),iM=e=>{let t=[...e.filter(n=>n.audience==="user"),...e.filter(n=>n.audience==="admin")];return{status:"manual",manualAudience:t.some(n=>n.audience==="user")?"user":"admin",messages:t.length===1?[t[0].message]:[`Not configured \u2014 ${t.length} things are in the way:`,...t.map((n,r)=>`${r+1}. ${n.message}`)]}},cM=L$(S$),lM=new Set(Nl),dM=async e=>{try{let{stdout:t}=await cM("/usr/bin/plutil",["-convert","json","-o","-",e],{timeout:2e3,maxBuffer:262144}),n=JSON.parse(t);return bn(n)?Object.keys(n):void 0}catch{return}},lo=async(e,t={})=>{let n=t.readManagedPolicyKeys??dM;for(let r of e.managedPolicies){let o=await $$(r);if(o==="absent")continue;if(o==="unreadable")return{path:r,keys:[],unreadable:!0};let a=await n(r);if(a===void 0)return{path:r,keys:[],unreadable:!0};let s=a.filter(i=>$l(i)&&!lM.has(i));if(s.length>0)return{path:r,keys:s,unreadable:!1}}},mm=e=>{if(e.unreadable)return`Claude Desktop may be centrally managed by ${e.path}, which could not be read; Connect did not change its inference configuration.`;let t=e.keys.slice(0,8).map(o=>/^[A-Za-z][A-Za-z0-9]{0,63}$/u.test(o)?o:"<unrecognized key>"),n=e.keys.length-t.length,r=`${t.join(", ")}${n>0?`, +${n} more`:""}`;return`Claude Desktop is centrally managed by ${e.path} (${r}); Connect did not change that managed configuration.`},hm=e=>(e.platform??_$)()==="darwin",vk=async(e,t,n={})=>{if(!hm(n))return Ml("Automatic Claude Desktop local setup is available on macOS.");let r=[];(n.appRunning??Fl)()&&r.push({audience:"user",message:"Claude Desktop is running. Fully quit it, then re-run connect so its cached state cannot overwrite the change."});let o=Jt(n),a=await lo(o,n);if(a&&r.push({audience:"admin",message:mm(a)}),r.length>0)return iM(r);let s=!1,i=!1,c=[o.journal];try{let l=te(e,"anthropic");if(l&&!await(n.subscriptionCredentialAvailable??Z$)())throw new Error("Claude subscription mode requires a readable Claude Code sign-in in the macOS Keychain; run `claude` and sign in, then re-run Connect");let d=l?"passthrough":"json",u=M$((n.credentialCommand??(()=>lm(d)))(),d),p=U$(u),m=await fm(o),f=await si(o.helper);if(m&&f.present&&f.content!==m.helper.lastWritten&&f.content!==m.helper.previousWritten)throw new Error("Claude Desktop credential helper changed after Connect configured it");if(!m&&f.present&&f.content!==p)throw new Error("the Claude Desktop credential helper path contains a foreign file");let h=await oM(o,m,n.randomUUID??v$),w=Nt(o.library,`${h.configId}.json`);c=[o.journal,o.helper,w,...h.metaToWrite?[o.meta]:[],o.appConfig];let y=await An(w),g=await An(o.appConfig),b=aM(e,o.helper),k=await sM(o,h,y,g,p,b,m);if(t.dryRun)return{status:"configured",messages:[`Would create or update Claude Desktop's dedicated Anyray profile ${h.configId} for ${e.anthropicBaseUrl}, activate it in third-party mode, and install a ${l?"subscription pass-through":"dynamic API-billed"} credential helper at ${o.helper}.`]};s=!0,await ck(o.journal,k),i=!0,await Ul(o.helper,p,448),k.helper.previousWritten!==void 0&&(delete k.helper.previousWritten,await ck(o.journal,k));let C=it(y.value);for(let I of oi)sm(C,I,b[I]);await Wn(w,C),h.metaToWrite&&await Wn(o.meta,h.metaToWrite);let S=it(g.value),E=kk();for(let I of ai)sm(S,I,E[I]);return await Wn(o.appConfig,S),{status:"configured",changedFiles:[o.journal,o.helper,w,...h.metaToWrite?[o.meta]:[],o.appConfig],messages:[`Configured Claude Desktop's native local gateway profile \u2192 ${e.anthropicBaseUrl}.`,l?`Installed a subscription pass-through credential helper at ${o.helper}; the helper reads your Claude Code subscription token on demand and no credential is stored in Claude's config.`:`Installed a dynamic credential helper at ${o.helper}; no gateway key is stored in Claude's config.`,l?"Claude Desktop Gateway requests now ride your Claude subscription through Anyray for content-free metering and optimization. Stay signed in to Claude Code so the token remains available.":"Claude Desktop uses its API-billed third-party inference lane; its first-party subscription remains separate.","Fully quit and reopen Claude Desktop to load the change.",...Dl]}}catch(l){let d=l instanceof Error?l.message:String(l);return s?{status:"manual",changedFiles:c,messages:[i?`Claude Desktop setup stopped after its ownership journal was written (${d}). Some listed files may contain a partial Anyray configuration.`:`Claude Desktop setup stopped while writing its ownership journal (${d}). No app configuration write was attempted, but the journal path may need cleanup.`,i?"Re-run connect to converge the journaled setup, or run --revert to restore the pre-Anyray values.":`Inspect ${o.journal}, then re-run connect.`]}:Ml(`Could not safely configure Claude Desktop (${d}). Claude Desktop configuration was unchanged.`)}},lk=(e,t,n,r)=>{let o=it(e);for(let a of n){let s=t[a];ei(Ck(e,a),s.lastWritten)?sm(o,a,s.original):r.push(a)}return o},Sk=async(e,t={})=>{if(!hm(t))return{status:"not-found",messages:[]};if((t.appRunning??Fl)())return Ml("Claude Desktop is running. Fully quit it, then re-run --revert.");let n=Jt(t);try{let r=await fm(n);if(!r)return{status:"not-found",messages:["No native Claude Desktop setup to revert."]};let o=Nt(n.library,`${r.configId}.json`);if(e.dryRun)return{status:"reverted",messages:[`Would restore Anyray-owned Claude Desktop fields from ${n.journal}, preserving user changes.`]};let a=[],s=await An(o),i=s.value;s.present&&(i=lk(s.value,r.config,oi,a));let c=!r.configFileExisted&&Object.keys(i).length===0,l=await An(n.meta),d=l.value,u=!1;if(!l.present)r.metaFileExisted&&(a.push("config-library metadata"),c=!1);else{let f=ri(l.value),h=it(l.value.entries),w=h.findIndex(b=>b.id===r.configId),y=w>=0?h[w]:void 0,g=y!==void 0&&ei(y,r.metaEntry);if(y!==void 0&&!g&&(a.push("Anyray config-library entry"),c=!1),r.metaFileExisted){if(d=it(l.value),f===r.configId){let b=r.originalAppliedId;b&&h.some(k=>k.id===b)?d.appliedId=b:(a.push("applied profile"),c=!1)}c&&g?(h.splice(w,1),d.entries=h):c&&y===void 0&&(d.entries=h)}else{let b=ei(l.value,{appliedId:r.configId,entries:[r.metaEntry]});c&&b?u=!0:c&&f!==r.configId?(g&&h.splice(w,1),d={...it(l.value),entries:h}):(c&&a.push("config-library metadata"),c=!1)}}s.present&&(c?await la(o,{force:!0}):await Wn(o,i)),l.present&&(u?await la(n.meta,{force:!0}):ei(l.value,d)||await Wn(n.meta,d));let p=await An(n.appConfig);if(p.present){let f=lk(p.value,r.deployment,ai,a);!r.deploymentFileExisted&&Object.keys(f).length===0?await la(n.appConfig,{force:!0}):await Wn(n.appConfig,f)}else r.deploymentFileExisted&&a.push("deployment config file");let m=await si(n.helper);return m.present&&(m.content===r.helper.lastWritten||m.content===r.helper.previousWritten)?r.helper.original.present?await Ul(n.helper,r.helper.original.content??"",r.helper.original.mode??448):await la(n.helper,{force:!0}):(m.present||r.helper.original.present)&&a.push("credential helper"),await la(n.journal,{force:!0}),{status:"reverted",changedFiles:[o,n.meta,n.appConfig,n.helper,n.journal],messages:["Restored Claude Desktop fields owned by Anyray.",...a.length>0?[`Preserved values changed after connect: ${[...new Set(a)].join(", ")}.`]:[],"Fully quit and reopen Claude Desktop to load the restored configuration.",...a.length>0?[]:Ll]}}catch(r){return Ml(`Could not safely revert Claude Desktop (${r instanceof Error?r.message:String(r)}). Existing config was left in place where ownership could not be proven.`)}},ym=async(e,t={})=>{if(!hm(t))return!1;let n=Jt(t);if(await lo(n,t))return!1;try{let r=await An(n.meta);if(!r.present)return!1;let o=ri(r.value),a=await An(Nt(n.library,`${o}.json`)),s=await An(n.appConfig);if(!a.present||!s.present)return!1;await Bl(n.helper,uk.X_OK);let i=Vt(e);return a.value.inferenceProvider==="gateway"&&a.value.inferenceGatewayBaseUrl===i&&a.value.inferenceGatewayAuthScheme==="bearer"&&a.value.inferenceCredentialKind==="helper-script"&&a.value.inferenceCredentialHelper===n.helper&&!Object.prototype.hasOwnProperty.call(a.value,"inferenceGatewayApiKey")&&s.value.deploymentMode==="3p"&&!Object.prototype.hasOwnProperty.call(s.value,"awaitingSignIn")}catch{return!1}},Ek=async(e={})=>{try{let t=Jt(e),n=await si(t.helper);if(!n.present||typeof n.content!="string")return;let r=Ak(n.content);return r?r.args.at(-1)==="--passthrough-headers"?"subscription":"api_key":void 0}catch{return}},Ik=async(e,t={})=>{if(!await ym(e,t))return!1;let n=Jt(t);try{let r=await fm(n);if(!r)return!1;let o=await An(n.meta);if(!o.present||ri(o.value)!==r.configId)return!1;let a=await si(n.helper);if(!a.present||a.content!==r.helper.lastWritten)return!1;let s=Ak(a.content??"");return s?await(t.helperLauncherAvailable??Y$)(s):!1}catch{return!1}};import{createHash as Hk,randomUUID as Gk}from"node:crypto";import{spawn as uM,spawnSync as pM}from"node:child_process";import{link as vm,mkdir as gm,open as Vk,readFile as wm,readdir as Kk,rename as jk,rm as Xt,stat as Zk}from"node:fs/promises";import{homedir as Sm}from"node:os";import{basename as Yk,dirname as ci,join as ga,win32 as fM}from"node:path";import{isDeepStrictEqual as ua}from"node:util";var De="HKCU\\SOFTWARE\\Policies\\Claude",ii="HKLM\\SOFTWARE\\Policies\\Claude",Kl=5,wa="inferenceGatewayApiKey",$e=["inferenceProvider","inferenceGatewayBaseUrl","inferenceGatewayAuthScheme","inferenceCredentialKind","inferenceCredentialHelper","chatTabEnabled","coworkEgressAllowedHosts",wa],xk=["inferenceProvider","inferenceGatewayBaseUrl","inferenceGatewayAuthScheme",wa],Rk=["inferenceProvider","inferenceGatewayBaseUrl","inferenceGatewayAuthScheme","inferenceCredentialKind","inferenceCredentialHelper",wa],Ok=["inferenceProvider","inferenceGatewayBaseUrl","inferenceGatewayAuthScheme","inferenceCredentialKind","inferenceCredentialHelper","chatTabEnabled",wa],Jk="Managed by anyray-connect; dynamic credential only.",mM=e=>/^[A-Za-z]:[\\/]/.test(e)&&fM.isAbsolute(e),Tk=e=>{if(!mM(e)||/[\0\r\n"]/u.test(e))return!1;let t=e.replace(/\\/g,"/").toLowerCase();return!/(^|\/)_npx(\/|$)/u.test(t)&&!/\/appdata\/local\/temp(\/|$)/u.test(t)&&!/(^|\/)temp(\/|$)/u.test(t)},Xk=e=>{if(!e.durable)throw new Error("the anyray-connect runtime is temporary");if(!Tk(e.command)||!/\.exe$/iu.test(e.command))throw new Error("the credential helper executable is not durable");if(e.args.length<2||e.args.length>3||e.args.at(-2)!=="print-key"||e.args.at(-1)!=="--json"||e.args.length===3&&!Tk(e.args[0]))throw new Error("the credential helper does not use print-key --json")},Em=(e={})=>ga((e.home??Sm)(),".anyray","bin","claude-desktop-credential-helper.cmd"),hM=e=>{if(/[\0\r\n"]/.test(e))throw new Error("the credential helper command contains unsafe characters");return`"${e.replace(/%/g,"%%")}"`},yM=e=>(Xk(e),["@echo off",`REM ${Jk}`,"setlocal DisableDelayedExpansion",[e.command,...e.args].map(hM).join(" "),"exit /b %ERRORLEVEL%",""].join(`\r
|
|
184
|
-
`)),
|
|
185
|
-
`);if(t.length!==6||t[0]!=="@echo off"||t[1]!==`REM ${Jk}`||t[2]!=="setlocal DisableDelayedExpansion"||t[4]!=="exit /b %ERRORLEVEL%"||t[5]!==""||!t[3].startsWith('"')||!t[3].endsWith('"'))return;let r=t[3].slice(1,-1).split('" "').map(
|
|
179
|
+
`)||n.includes("\r"))return;let r=um(n);if(!r||r.length!==3&&r.length!==4)return;let[o,...a]=r,s=Wl(o);if(!da(o)||a.at(-2)!=="print-key"||a.at(-1)!=="--json"||(s?a.length!==3||!da(a[0]):a.length!==2))return;let i={command:o,args:a,durable:!0};try{return wk(i)===e?i:void 0}catch{return}},V$=e=>{if(!e.startsWith(U$))return;let t=e.match(/^exec (.*)$/m);if(!t)return;let n=um(t[1]);if(!n)return;let[r,...o]=n;if(o.at(-1)!==kr)return;let a={command:r,args:[...o.slice(0,-1),"print-key","--passthrough-headers"],durable:!0};try{return bk(a)===e?a:void 0}catch{return}},K$=`#!/bin/sh
|
|
180
|
+
# Anyray subscription pass-through credential helper`,j$=e=>{let t=Wl(e.command);if(!(!da(e.command)||e.args.at(-2)!=="print-key"||e.args.at(-1)!=="--passthrough-headers"||(t?e.args.length!==3||!da(e.args[0]):e.args.length!==2)))return["#!/bin/sh","# Anyray subscription pass-through credential helper for Claude Desktop.","# Reads the Claude subscription token from the login keychain at request","# time and wraps it with Anyray pass-through headers. connect never stores","# the token; only this on-machine helper reads it.","set -eu",`headers=$(${dm(e)})`,'if [ -z "${headers}" ]; then'," echo 'Anyray: could not resolve gateway headers; is this machine enrolled? Run: anyray-connect' >&2"," exit 1","fi","token=$(security find-generic-password -s 'Claude Code-credentials' -w 2>/dev/null | grep -oE 'sk-ant-oat[0-9A-Za-z._-]+' | head -n1)",'if [ -z "${token}" ]; then'," echo 'Anyray: no Claude subscription sign-in found; run: claude' >&2"," exit 1","fi",'printf \'{"token":"%s","headers":%s}\\n\' "${token}" "${headers}"',""].join(`
|
|
181
|
+
`)},Z$=e=>{if(!e.startsWith(K$))return;let t=e.match(/^headers=\$\((.*)\)$/m);if(!t)return;let n=um(t[1]);if(!n)return;let[r,...o]=n,a={command:r,args:o,durable:!0};return j$(a)===e?a:void 0},Ak=e=>G$(e)??V$(e)??Z$(e),Y$=async()=>{let e=dk("/usr/bin/security",["find-generic-password","-s","Claude Code-credentials"],{stdio:"ignore",timeout:3e3});return!e.error&&e.status===0},J$=async e=>{let t=[e.command,...Wl(e.command)?[e.args[0]]:[]];try{return(await Promise.all(t.map(r=>pk(r)))).every(r=>r.isFile())?(await Bl(e.command,uk.X_OK),!0):!1}catch{return!1}},X$=0,Ul=async(e,t,n)=>{await I$(fk(e),{recursive:!0,mode:448});let r=`${e}.anyray-${process.pid}-${X$++}.tmp`;try{await O$(r,t,{mode:n}),await E$(r,n),await R$(r,e)}catch(o){throw await la(r,{force:!0}).catch(()=>{}),o}},Wn=async(e,t)=>{await Ul(e,`${JSON.stringify(t,null,2)}
|
|
182
|
+
`,384)},An=async e=>{if(!await ni(e))return{present:!1,value:{}};let t;try{t=JSON.parse(await im(e,"utf-8"))}catch{throw new Error(`${e} is not valid JSON`)}if(!bn(t))throw new Error(`${e} is not a JSON object`);return{present:!0,value:t}},si=async e=>{if(!await ni(e))return{present:!1};let t=await pk(e);return{present:!0,content:await im(e,"utf-8"),mode:t.mode&511}},Ck=(e,t)=>Object.prototype.hasOwnProperty.call(e,t)?{present:!0,value:it(e[t])}:{present:!1},sm=(e,t,n)=>{n.present?e[t]=it(n.value):delete e[t]},ak=e=>bn(e)&&typeof e.present=="boolean"&&(!e.present||Object.prototype.hasOwnProperty.call(e,"value")),z$=e=>bn(e)&&ak(e.original)&&ak(e.lastWritten),q$=e=>bn(e)&&typeof e.present=="boolean"&&(!e.present||typeof e.content=="string"&&typeof e.mode=="number"&&Number.isInteger(e.mode)&&e.mode>=0&&e.mode<=511),sk=(e,t)=>bn(e)&&t.every(n=>z$(e[n])),Q$=["inferenceProvider","inferenceGatewayBaseUrl","inferenceGatewayAuthScheme","inferenceCredentialKind","inferenceCredentialHelper","inferenceGatewayApiKey"],eM=["inferenceProvider","inferenceGatewayBaseUrl","inferenceGatewayAuthScheme","inferenceCredentialKind","inferenceCredentialHelper","chatTabEnabled","inferenceGatewayApiKey"],pm=(e,t,n,r)=>!(!bn(e)||e.version!==n||typeof e.configId!="string"||!ti.test(e.configId)||typeof e.metaFileExisted!="boolean"||e.originalAppliedId!==void 0&&(typeof e.originalAppliedId!="string"||!ti.test(e.originalAppliedId))||e.metaFileExisted!==(e.originalAppliedId!==void 0)||!bn(e.metaEntry)||e.metaEntry.id!==e.configId||e.metaEntry.name!==mk||Object.keys(e.metaEntry).length!==2||typeof e.configFileExisted!="boolean"||e.configFileExisted||typeof e.deploymentFileExisted!="boolean"||!sk(e.config,r)||r.some(o=>e.config[o].original.present)||!sk(e.deployment,ai)||!bn(e.helper)||e.helper.path!==t.helper||!q$(e.helper.original)||typeof e.helper.lastWritten!="string"||e.helper.previousWritten!==void 0&&typeof e.helper.previousWritten!="string"),tM=(e,t)=>pm(e,t,cm,oi),nM=(e,t)=>pm(e,t,2,Q$),rM=(e,t)=>pm(e,t,3,eM),oM=e=>({...e,version:3,config:{...e.config,chatTabEnabled:{original:{present:!1},lastWritten:{present:!1}}}}),ik=e=>({...e,version:cm,config:{...e.config,coworkEgressAllowedHosts:{original:{present:!1},lastWritten:{present:!1}}}}),fm=async e=>{if(!await ni(e.journal))return;let t;try{t=JSON.parse(await im(e.journal,"utf-8"))}catch{throw new Error(`${e.journal} is not valid JSON`)}if(tM(t,e))return t;if(rM(t,e))return ik(t);if(nM(t,e))return ik(oM(t));throw new Error(`${e.journal} is not a valid ownership journal`)},ck=async(e,t)=>{await Ul(e,`${JSON.stringify(t,null,2)}
|
|
183
|
+
`,384)},ri=e=>{let{appliedId:t,entries:n}=e;if(typeof t!="string"||!ti.test(t)||!Array.isArray(n))throw new Error("Claude config-library metadata has an invalid shape");let r=new Set;for(let o of n){if(!bn(o)||typeof o.id!="string"||!ti.test(o.id)||typeof o.name!="string"||r.has(o.id))throw new Error("Claude config-library metadata has an invalid entry");r.add(o.id)}if(!r.has(t))throw new Error("Claude config-library appliedId is not in entries");return t},aM=async(e,t,n)=>{let r=await An(e.meta);if(t){if(!r.present){if(t.metaFileExisted)throw new Error("Claude config-library metadata disappeared after apply");return{configId:t.configId,meta:r,metaFileExisted:!1,metaEntry:it(t.metaEntry),metaToWrite:{appliedId:t.configId,entries:[it(t.metaEntry)]}}}let c=ri(r.value),d=r.value.entries.find(u=>u.id===t.configId);if(!d||!ei(d,t.metaEntry))throw new Error("Claude changed the Anyray config-library entry after apply");return{configId:t.configId,meta:r,metaFileExisted:t.metaFileExisted,originalAppliedId:t.originalAppliedId,metaEntry:it(t.metaEntry),...c===t.configId?{}:{metaToWrite:{...it(r.value),appliedId:t.configId}}}}let o,a=[];if(r.present){o=ri(r.value);let c=Nt(e.library,`${o}.json`);if(!await ni(c))throw new Error(`Claude's applied configuration ${o} is missing`);a=it(r.value.entries)}let s=n();if(!ti.test(s))throw new Error("could not create a valid config id");if(a.some(c=>c.id===s)||await ni(Nt(e.library,`${s}.json`)))throw new Error("could not create a unique Anyray config id");let i={id:s,name:mk};return{configId:s,meta:r,metaFileExisted:r.present,originalAppliedId:o,metaEntry:i,metaToWrite:{...r.present?it(r.value):{},appliedId:s,entries:[...a,i]}}},sM=(e,t)=>{let n=co(e,t);return{...Object.fromEntries(Object.entries(n).map(([r,o])=>[r,{present:!0,value:o}])),inferenceGatewayApiKey:{present:!1}}},kk=()=>({deploymentMode:{present:!0,value:"3p"},awaitingSignIn:{present:!1}}),iM=async(e,t,n,r,o,a,s)=>{let i=kk(),c=Object.fromEntries(oi.map(d=>[d,{original:s?.config[d].original??{present:!1},lastWritten:a[d]}])),l=Object.fromEntries(ai.map(d=>[d,{original:s?.deployment[d].original??Ck(r.value,d),lastWritten:i[d]}]));return{version:cm,configId:t.configId,metaFileExisted:s?.metaFileExisted??t.metaFileExisted,originalAppliedId:s?.originalAppliedId??t.originalAppliedId,metaEntry:s?.metaEntry??it(t.metaEntry),configFileExisted:!1,config:c,deploymentFileExisted:s?.deploymentFileExisted??r.present,deployment:l,helper:{path:e.helper,original:s?.helper.original??await si(e.helper),lastWritten:o,...s?.helper.previousWritten!==void 0?{previousWritten:s.helper.previousWritten}:s&&s.helper.lastWritten!==o?{previousWritten:s.helper.lastWritten}:{}}}},Ml=e=>({status:"manual",messages:[e]}),cM=e=>{let t=[...e.filter(n=>n.audience==="user"),...e.filter(n=>n.audience==="admin")];return{status:"manual",manualAudience:t.some(n=>n.audience==="user")?"user":"admin",messages:t.length===1?[t[0].message]:[`Not configured \u2014 ${t.length} things are in the way:`,...t.map((n,r)=>`${r+1}. ${n.message}`)]}},lM=L$(S$),dM=new Set(Nl),uM=async e=>{try{let{stdout:t}=await lM("/usr/bin/plutil",["-convert","json","-o","-",e],{timeout:2e3,maxBuffer:262144}),n=JSON.parse(t);return bn(n)?Object.keys(n):void 0}catch{return}},lo=async(e,t={})=>{let n=t.readManagedPolicyKeys??uM;for(let r of e.managedPolicies){let o=await M$(r);if(o==="absent")continue;if(o==="unreadable")return{path:r,keys:[],unreadable:!0};let a=await n(r);if(a===void 0)return{path:r,keys:[],unreadable:!0};let s=a.filter(i=>$l(i)&&!dM.has(i));if(s.length>0)return{path:r,keys:s,unreadable:!1}}},mm=e=>{if(e.unreadable)return`Claude Desktop may be centrally managed by ${e.path}, which could not be read; Connect did not change its inference configuration.`;let t=e.keys.slice(0,8).map(o=>/^[A-Za-z][A-Za-z0-9]{0,63}$/u.test(o)?o:"<unrecognized key>"),n=e.keys.length-t.length,r=`${t.join(", ")}${n>0?`, +${n} more`:""}`;return`Claude Desktop is centrally managed by ${e.path} (${r}); Connect did not change that managed configuration.`},hm=e=>(e.platform??_$)()==="darwin",vk=async(e,t,n={})=>{if(!hm(n))return Ml("Automatic Claude Desktop local setup is available on macOS.");let r=[];(n.appRunning??Fl)()&&r.push({audience:"user",message:"Claude Desktop is running. Fully quit it, then re-run connect so its cached state cannot overwrite the change."});let o=Jt(n),a=await lo(o,n);if(a&&r.push({audience:"admin",message:mm(a)}),r.length>0)return cM(r);let s=!1,i=!1,c=[o.journal];try{let l=te(e,"anthropic");if(l&&!await(n.subscriptionCredentialAvailable??Y$)())throw new Error("Claude subscription mode requires a readable Claude Code sign-in in the macOS Keychain; run `claude` and sign in, then re-run Connect");let d=l?"passthrough":"json",u=B$((n.credentialCommand??(()=>lm(d)))(),d),p=H$(u),m=await fm(o),f=await si(o.helper);if(m&&f.present&&f.content!==m.helper.lastWritten&&f.content!==m.helper.previousWritten)throw new Error("Claude Desktop credential helper changed after Connect configured it");if(!m&&f.present&&f.content!==p)throw new Error("the Claude Desktop credential helper path contains a foreign file");let h=await aM(o,m,n.randomUUID??v$),w=Nt(o.library,`${h.configId}.json`);c=[o.journal,o.helper,w,...h.metaToWrite?[o.meta]:[],o.appConfig];let y=await An(w),g=await An(o.appConfig),b=sM(e,o.helper),k=await iM(o,h,y,g,p,b,m);if(t.dryRun)return{status:"configured",messages:[`Would create or update Claude Desktop's dedicated Anyray profile ${h.configId} for ${e.anthropicBaseUrl}, activate it in third-party mode, and install a ${l?"subscription pass-through":"dynamic API-billed"} credential helper at ${o.helper}.`]};s=!0,await ck(o.journal,k),i=!0,await Ul(o.helper,p,448),k.helper.previousWritten!==void 0&&(delete k.helper.previousWritten,await ck(o.journal,k));let C=it(y.value);for(let I of oi)sm(C,I,b[I]);await Wn(w,C),h.metaToWrite&&await Wn(o.meta,h.metaToWrite);let S=it(g.value),E=kk();for(let I of ai)sm(S,I,E[I]);return await Wn(o.appConfig,S),{status:"configured",changedFiles:[o.journal,o.helper,w,...h.metaToWrite?[o.meta]:[],o.appConfig],messages:[`Configured Claude Desktop's native local gateway profile \u2192 ${e.anthropicBaseUrl}.`,l?`Installed a subscription pass-through credential helper at ${o.helper}; the helper reads your Claude Code subscription token on demand and no credential is stored in Claude's config.`:`Installed a dynamic credential helper at ${o.helper}; no gateway key is stored in Claude's config.`,l?"Claude Desktop Gateway requests now ride your Claude subscription through Anyray for content-free metering and optimization. Stay signed in to Claude Code so the token remains available.":"Claude Desktop uses its API-billed third-party inference lane; its first-party subscription remains separate.","Fully quit and reopen Claude Desktop to load the change.",...Dl]}}catch(l){let d=l instanceof Error?l.message:String(l);return s?{status:"manual",changedFiles:c,messages:[i?`Claude Desktop setup stopped after its ownership journal was written (${d}). Some listed files may contain a partial Anyray configuration.`:`Claude Desktop setup stopped while writing its ownership journal (${d}). No app configuration write was attempted, but the journal path may need cleanup.`,i?"Re-run connect to converge the journaled setup, or run --revert to restore the pre-Anyray values.":`Inspect ${o.journal}, then re-run connect.`]}:Ml(`Could not safely configure Claude Desktop (${d}). Claude Desktop configuration was unchanged.`)}},lk=(e,t,n,r)=>{let o=it(e);for(let a of n){let s=t[a];ei(Ck(e,a),s.lastWritten)?sm(o,a,s.original):r.push(a)}return o},Sk=async(e,t={})=>{if(!hm(t))return{status:"not-found",messages:[]};if((t.appRunning??Fl)())return Ml("Claude Desktop is running. Fully quit it, then re-run --revert.");let n=Jt(t);try{let r=await fm(n);if(!r)return{status:"not-found",messages:["No native Claude Desktop setup to revert."]};let o=Nt(n.library,`${r.configId}.json`);if(e.dryRun)return{status:"reverted",messages:[`Would restore Anyray-owned Claude Desktop fields from ${n.journal}, preserving user changes.`]};let a=[],s=await An(o),i=s.value;s.present&&(i=lk(s.value,r.config,oi,a));let c=!r.configFileExisted&&Object.keys(i).length===0,l=await An(n.meta),d=l.value,u=!1;if(!l.present)r.metaFileExisted&&(a.push("config-library metadata"),c=!1);else{let f=ri(l.value),h=it(l.value.entries),w=h.findIndex(b=>b.id===r.configId),y=w>=0?h[w]:void 0,g=y!==void 0&&ei(y,r.metaEntry);if(y!==void 0&&!g&&(a.push("Anyray config-library entry"),c=!1),r.metaFileExisted){if(d=it(l.value),f===r.configId){let b=r.originalAppliedId;b&&h.some(k=>k.id===b)?d.appliedId=b:(a.push("applied profile"),c=!1)}c&&g?(h.splice(w,1),d.entries=h):c&&y===void 0&&(d.entries=h)}else{let b=ei(l.value,{appliedId:r.configId,entries:[r.metaEntry]});c&&b?u=!0:c&&f!==r.configId?(g&&h.splice(w,1),d={...it(l.value),entries:h}):(c&&a.push("config-library metadata"),c=!1)}}s.present&&(c?await la(o,{force:!0}):await Wn(o,i)),l.present&&(u?await la(n.meta,{force:!0}):ei(l.value,d)||await Wn(n.meta,d));let p=await An(n.appConfig);if(p.present){let f=lk(p.value,r.deployment,ai,a);!r.deploymentFileExisted&&Object.keys(f).length===0?await la(n.appConfig,{force:!0}):await Wn(n.appConfig,f)}else r.deploymentFileExisted&&a.push("deployment config file");let m=await si(n.helper);return m.present&&(m.content===r.helper.lastWritten||m.content===r.helper.previousWritten)?r.helper.original.present?await Ul(n.helper,r.helper.original.content??"",r.helper.original.mode??448):await la(n.helper,{force:!0}):(m.present||r.helper.original.present)&&a.push("credential helper"),await la(n.journal,{force:!0}),{status:"reverted",changedFiles:[o,n.meta,n.appConfig,n.helper,n.journal],messages:["Restored Claude Desktop fields owned by Anyray.",...a.length>0?[`Preserved values changed after connect: ${[...new Set(a)].join(", ")}.`]:[],"Fully quit and reopen Claude Desktop to load the restored configuration.",...a.length>0?[]:Ll]}}catch(r){return Ml(`Could not safely revert Claude Desktop (${r instanceof Error?r.message:String(r)}). Existing config was left in place where ownership could not be proven.`)}},ym=async(e,t={})=>{if(!hm(t))return!1;let n=Jt(t);if(await lo(n,t))return!1;try{let r=await An(n.meta);if(!r.present)return!1;let o=ri(r.value),a=await An(Nt(n.library,`${o}.json`)),s=await An(n.appConfig);if(!a.present||!s.present)return!1;await Bl(n.helper,uk.X_OK);let i=Vt(e);return a.value.inferenceProvider==="gateway"&&a.value.inferenceGatewayBaseUrl===i&&a.value.inferenceGatewayAuthScheme==="bearer"&&a.value.inferenceCredentialKind==="helper-script"&&a.value.inferenceCredentialHelper===n.helper&&!Object.prototype.hasOwnProperty.call(a.value,"inferenceGatewayApiKey")&&s.value.deploymentMode==="3p"&&!Object.prototype.hasOwnProperty.call(s.value,"awaitingSignIn")}catch{return!1}},Ek=async(e={})=>{try{let t=Jt(e),n=await si(t.helper);if(!n.present||typeof n.content!="string")return;let r=Ak(n.content);return r?r.args.at(-1)==="--passthrough-headers"?"subscription":"api_key":void 0}catch{return}},Ik=async(e,t={})=>{if(!await ym(e,t))return!1;let n=Jt(t);try{let r=await fm(n);if(!r)return!1;let o=await An(n.meta);if(!o.present||ri(o.value)!==r.configId)return!1;let a=await si(n.helper);if(!a.present||a.content!==r.helper.lastWritten)return!1;let s=Ak(a.content??"");return s?await(t.helperLauncherAvailable??J$)(s):!1}catch{return!1}};import{createHash as Hk,randomUUID as Gk}from"node:crypto";import{spawn as pM,spawnSync as fM}from"node:child_process";import{link as vm,mkdir as gm,open as Vk,readFile as wm,readdir as Kk,rename as jk,rm as Xt,stat as Zk}from"node:fs/promises";import{homedir as Sm}from"node:os";import{basename as Yk,dirname as ci,join as ga,win32 as mM}from"node:path";import{isDeepStrictEqual as ua}from"node:util";var De="HKCU\\SOFTWARE\\Policies\\Claude",ii="HKLM\\SOFTWARE\\Policies\\Claude",Kl=5,wa="inferenceGatewayApiKey",$e=["inferenceProvider","inferenceGatewayBaseUrl","inferenceGatewayAuthScheme","inferenceCredentialKind","inferenceCredentialHelper","chatTabEnabled","coworkEgressAllowedHosts",wa],xk=["inferenceProvider","inferenceGatewayBaseUrl","inferenceGatewayAuthScheme",wa],Rk=["inferenceProvider","inferenceGatewayBaseUrl","inferenceGatewayAuthScheme","inferenceCredentialKind","inferenceCredentialHelper",wa],Ok=["inferenceProvider","inferenceGatewayBaseUrl","inferenceGatewayAuthScheme","inferenceCredentialKind","inferenceCredentialHelper","chatTabEnabled",wa],Jk="Managed by anyray-connect; dynamic credential only.",hM=e=>/^[A-Za-z]:[\\/]/.test(e)&&mM.isAbsolute(e),Tk=e=>{if(!hM(e)||/[\0\r\n"]/u.test(e))return!1;let t=e.replace(/\\/g,"/").toLowerCase();return!/(^|\/)_npx(\/|$)/u.test(t)&&!/\/appdata\/local\/temp(\/|$)/u.test(t)&&!/(^|\/)temp(\/|$)/u.test(t)},Xk=e=>{if(!e.durable)throw new Error("the anyray-connect runtime is temporary");if(!Tk(e.command)||!/\.exe$/iu.test(e.command))throw new Error("the credential helper executable is not durable");if(e.args.length<2||e.args.length>3||e.args.at(-2)!=="print-key"||e.args.at(-1)!=="--json"||e.args.length===3&&!Tk(e.args[0]))throw new Error("the credential helper does not use print-key --json")},Em=(e={})=>ga((e.home??Sm)(),".anyray","bin","claude-desktop-credential-helper.cmd"),yM=e=>{if(/[\0\r\n"]/.test(e))throw new Error("the credential helper command contains unsafe characters");return`"${e.replace(/%/g,"%%")}"`},gM=e=>(Xk(e),["@echo off",`REM ${Jk}`,"setlocal DisableDelayedExpansion",[e.command,...e.args].map(yM).join(" "),"exit /b %ERRORLEVEL%",""].join(`\r
|
|
184
|
+
`)),wM=e=>{let t="";for(let n=0;n<e.length;n++){if(e[n]!=="%"){t+=e[n];continue}if(e[n+1]!=="%")return;t+="%",n++}return t},zk=e=>{let t=e.split(`\r
|
|
185
|
+
`);if(t.length!==6||t[0]!=="@echo off"||t[1]!==`REM ${Jk}`||t[2]!=="setlocal DisableDelayedExpansion"||t[4]!=="exit /b %ERRORLEVEL%"||t[5]!==""||!t[3].startsWith('"')||!t[3].endsWith('"'))return;let r=t[3].slice(1,-1).split('" "').map(wM);if(r.some(i=>i===void 0))return;let[o,...a]=r,s={command:o,args:a,durable:!0};try{return Xk(s),s}catch{return}},bM=async e=>{let t=[e.command,...e.args.length===3?[e.args[0]]:[]];try{return(await Promise.all(t.map(r=>Zk(r)))).every(r=>r.isFile())}catch{return!1}},AM=async(e,t)=>{let n=zk(e.content);if(!n)return!1;try{return await(t.helperLauncherAvailable??bM)(n)}catch{return!1}},bm=e=>({sha256:uo(e),content:e}),_k=e=>{if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e;return $t(t,["sha256","content"])&&RM(t.sha256)&&typeof t.content=="string"&&uo(t.content)===t.sha256&&zk(t.content)!==void 0},Im=()=>{let e=fM("tasklist.exe",["/FI","IMAGENAME eq Claude.exe","/FO","CSV","/NH"],{encoding:"utf8",windowsHide:!0,timeout:2e3,maxBuffer:65536});return e.error||e.signal||e.status!==0?!0:/(?:^|\r?\n)"Claude\.exe",/iu.test(e.stdout??"")},CM=async(e,t)=>{await gm(ci(e),{recursive:!0,mode:448});let n=`${e}.anyray-tmp-${process.pid}-${Date.now()}`;try{let r=await Vk(n,"wx",384);try{await r.writeFile(t,"utf8"),await r.sync()}finally{await r.close()}await vm(n,e)}finally{await Xt(n,{force:!0}).catch(()=>{})}},kM=e=>`${Yk(e)}.anyray-old-`,vM=e=>`${e}.anyray-old-${process.pid}-${Gk()}`,qk=async(e,t)=>{try{await vm(t,e)}catch(n){if(n.code==="EEXIST")return!1;throw n}return await Xt(t,{force:!0}),!0},Gl=async(e,t,n,r,o)=>{let a=vM(e),s=n===void 0?void 0:uo(n),i=n===void 0?void 0:`${e}.anyray-tmp-${process.pid}-${Gk()}`,c=!1;try{if(i&&n!==void 0){let d=await Vk(i,"wx",384);try{await d.writeFile(n,"utf8"),await d.sync()}finally{await d.close()}}await o.helperFileOperationHook?.({operation:r,phase:"before-move",path:e,recoveryPath:a}),await jk(e,a),c=!0,await o.helperFileOperationHook?.({operation:r,phase:"after-move",path:e,recoveryPath:a});let l=await ha(a);if(!l||l.sha256!==t)throw new Error("credential helper changed during operation");if(i&&n!==void 0&&(await vm(i,e),await o.helperFileOperationHook?.({operation:r,phase:"after-publish",path:e,recoveryPath:a}),await ya(e)!==s))throw new Error("credential helper publication verification failed");await Xt(a,{force:!0}),c=!1}catch(l){throw c&&await qk(e,a).catch(()=>!1),l}finally{i&&await Xt(i,{force:!0}).catch(()=>{})}},Am=e=>`reg failed to spawn (${e.code??e.signal??e.name??"unknown"})`,SM=String.raw`
|
|
186
186
|
$ErrorActionPreference = 'Stop'
|
|
187
187
|
try {
|
|
188
188
|
$request = ConvertFrom-Json ([Console]::In.ReadToEnd())
|
|
@@ -251,16 +251,16 @@ try {
|
|
|
251
251
|
exit 5
|
|
252
252
|
} catch {
|
|
253
253
|
exit 6
|
|
254
|
-
}`,Hn=async e=>new Promise((t,n)=>{let r=
|
|
255
|
-
`)}catch(a){if(a.code!=="EEXIST")throw await Xt(t,{recursive:!0,force:!0}).catch(()=>{}),a;let s=!1;try{let i=JSON.parse(await wm(o,"utf8"));s=typeof i.pid=="number"&&Number.isSafeInteger(i.pid)&&i.pid>0&&!
|
|
256
|
-
`;t.writeJournalFile?await t.writeJournalFile(n,r):await we(n,r)},NM=/^(\S+)\s+(REG_[A-Z_]+)(?:\s+(.*))?$/,$M=new Set(["REG_SZ","REG_EXPAND_SZ","REG_DWORD"]),MM=new Set(["REG_QWORD","REG_MULTI_SZ","REG_BINARY","REG_NONE"]),BM=e=>e.replace(/^HKCU\\/i,"HKEY_CURRENT_USER\\").replace(/^HKLM\\/i,"HKEY_LOCAL_MACHINE\\"),FM=(e,t)=>e.toUpperCase()===t.toUpperCase()||e.toUpperCase()===BM(t).toUpperCase(),Wk=(e,t,n,r,o)=>{let a=$e.find(i=>i.toLowerCase()===t.toLowerCase());if(!a)return!1;let s=n==="String"?"REG_SZ":n==="ExpandString"?"REG_EXPAND_SZ":n;if(s!=="REG_SZ"&&s!=="REG_EXPAND_SZ"){if(o)throw new Error("an owned Claude policy value has an unsupported type");return!1}if(e[a].present)throw new Error("a Claude policy value was returned more than once");return e[a]={present:!0,type:s,value:r},!0},WM=e=>e==="String"?"REG_SZ":e==="ExpandString"?"REG_EXPAND_SZ":e==="DWord"?"REG_DWORD":e==="QWord"?"REG_QWORD":e==="MultiString"?"REG_MULTI_SZ":e==="Binary"?"REG_BINARY":e==="None"?"REG_NONE":e,UM=(e,t)=>{if(!$l(e,!0))return!1;let n=WM(t);if(MM.has(n))return!1;if($M.has(n))return n==="REG_EXPAND_SZ"?!0:!nk(e,!0)},HM=(e,t)=>{let n=Qk(),r=!1,o=!1,a=!1,s=t.toUpperCase()===ii.toUpperCase(),i=(l,d)=>{if(!s)return;let u=UM(l,d);u===void 0?a=!0:u&&(o=!0)},c=e.trim();if(c.startsWith("{")){let l=JSON.parse(c);if(l.anyrayRegistry!==1||typeof l.key!="string"||l.key.toUpperCase()!==t.toUpperCase()||!Array.isArray(l.values))throw new Error("invalid registry bridge response");for(let d of l.values){if(!d||typeof d!="object"||Array.isArray(d))throw new Error("invalid registry bridge value");let u=d;if(typeof u.name!="string"||typeof u.kind!="string"||typeof u.value!="string")throw new Error("invalid registry bridge value");i(u.name,u.kind),Wk(n,u.name,u.kind,u.value,!s)||(r=!0)}return{keyPresent:!0,values:n,foreignState:r,machinePolicyActive:o,unparsed:a}}for(let l of e.split(/\r?\n/)){let d=l.trim();if(!d||FM(d,t))continue;let u=NM.exec(d);if(!u){r=!0,a=!0;continue}u[1]==="(Default)"&&(u[3]??"")==="(value not set)"||(i(u[1],u[2]),Wk(n,u[1],u[2],u[3]??"",!s)||(r=!0))}return{keyPresent:!0,values:n,foreignState:r,machinePolicyActive:o,unparsed:a}},Un=async(e,t=De)=>{let n=await e(["query",t]);if(n.code!==0){if(n.missing===!0)return{keyPresent:!1,values:Qk(),foreignState:!1,machinePolicyActive:!1,unparsed:!1};throw new Error("registry query failed without proving the key is absent")}return HM(n.stdout,t)},Sr=async e=>{let t=await Un(e,ii);return t.keyPresent?t.unparsed?{names:[],unparsed:!0}:t.machinePolicyActive?{names:[...$e.filter(r=>t.values[r].present)],unparsed:!1}:void 0:void 0},_m=e=>e.unparsed?`This machine may have a Claude policy under ${ii} that could not be read; it would shadow HKCU, so local configuration was left unchanged.`:e.names.length>0?`A Claude policy under ${ii} sets ${e.names.join(", ")}; Claude treats HKLM as the complete configuration and shadows HKCU, so local configuration was left unchanged.`:`A Claude policy under ${ii} contains a recognized configuration value; Claude treats HKLM as the complete configuration and shadows HKCU, so local configuration was left unchanged.`;var Zl=(e,t)=>vr(co(e,t)),ev=(e,t,n,r="REG_SZ")=>["add",e,"/v",t,"/t",r,"/d",n,"/f"],GM=(e,t)=>{let n=Zl(e,t);return Object.fromEntries($e.map(r=>{let o=n[r];return[r,o===void 0?{present:!1}:{present:!0,type:"REG_SZ",value:o}]}))},VM=(e,t)=>({inferenceProvider:{present:!0,type:"REG_SZ",value:"gateway"},inferenceGatewayBaseUrl:{present:!0,type:"REG_SZ",value:e.anthropicBaseUrl},inferenceGatewayAuthScheme:{present:!0,type:"REG_SZ",value:"bearer"},chatTabEnabled:{present:!1},coworkEgressAllowedHosts:{present:!1},inferenceCredentialKind:{present:!1},inferenceCredentialHelper:{present:!1},inferenceGatewayApiKey:{present:!0,type:"REG_SZ",value:t}}),KM=e=>e.helper.lastWritten===void 0&&e.helper.pending===void 0&&e.lastWritten.inferenceGatewayApiKey.present,Cm=e=>Object.fromEntries($e.map(t=>[t,IM(t,e[t])])),Uk=(e,t,n,r)=>({version:Kl,registryKey:De,keyExisted:e,lastWritten:Cm(t),helper:{path:n,lastWritten:bm(r)}}),jM=(e,t,n,r,o,a)=>({version:Kl,registryKey:De,keyExisted:e,lastWritten:Cm(t),pending:Cm(n),helper:{path:r,...o?{lastWritten:bm(o)}:{},pending:bm(a)}}),km=(e,t,n)=>pa(n,e.lastWritten[t])||e.pending!==void 0&&pa(n,e.pending[t]),ha=async e=>{try{let t=await wm(e,"utf8");return{content:t,sha256:uo(t)}}catch(t){if(t.code==="ENOENT")return;throw t}},ya=async e=>(await ha(e))?.sha256,fa=(e,t)=>t===e.helper.lastWritten?.sha256||t===e.helper.pending?.sha256,Vl=async(e,t)=>{let n=CM(e),r;try{r=await Kk(ci(e))}catch(c){if(c.code==="ENOENT")return;throw c}let o=r.filter(c=>c.startsWith(n)).map(c=>ga(ci(e),c));if(o.length===0)return;if(o.length!==1)throw new Error("ambiguous credential helper recovery files");let a=o[0],[s,i]=await Promise.all([ha(e),ha(a)]);if(!i)throw new Error("credential helper recovery file disappeared");if(!s){if(!t||!fa(t,i.sha256))throw new Error("credential helper recovery is not journal-owned");if(!await qk(e,a))throw new Error("credential helper changed during recovery");return}if(t&&fa(t,s.sha256)&&fa(t,i.sha256)){await Xt(a,{force:!0});return}throw new Error("credential helper recovery conflicts with current file")},Pm=async(e,t,n)=>(n.present?await e(ev(De,t,n.value??"",n.type??"REG_SZ")):await e(["delete",De,"/v",t,"/f"])).code===0,ZM=async(e,t,n)=>{let r=!0,o=await Un(e);for(let a of $e)if(!ua(o.values[a],t[a])){if(!ua(o.values[a],n[a])){r=!1;continue}await Pm(e,a,t[a])||(r=!1),o=await Un(e)}return r&&$e.every(a=>ua(o.values[a],t[a]))},ze=(e,t=!1,n={})=>({status:"manual",messages:[e],...t&&{changedFiles:[Mt(n)]}}),tv=async(e,t,n,r={})=>{if(!be(t))return ze("A valid personal ark_ gateway key is required.",!1,r);let o=Em(r),a;try{a=yM((r.credentialCommand??lm)())}catch{return ze("A durable local anyray-connect runtime is required for Claude Desktop's automatic credential helper.",!1,r)}let s=uo(a),i=r.runReg??Hn,c=Mt(r),l;if(!n.dryRun)try{l=await xm(r)}catch(h){return ze(h instanceof ma?"Another Claude Desktop policy operation is already in progress; retry shortly.":"Could not acquire the owner-only Claude Desktop policy lock; the registry was left unchanged.",!1,r)}let d,u,p,m,f=!1;try{let h=await Sr(i);if(h)return ze(_m(h),!1,r);let w=await Tm(r,!n.dryRun);n.dryRun||await Vl(o,w);let y=await Un(i),g=GM(e,o),b=await ha(o),k=b?.sha256,C=!1;if(d=w,u=y,p=g,w){let I=$e.find(_=>!km(w,_,y.values[_]));if(I)return ze(`Claude's ${I} policy changed after Connect configured it; the existing value was preserved. Revert or remove that value before reapplying.`,!1,r);if(k!==void 0&&!fa(w,k))return ze(`Claude's credential helper changed after Connect configured it; ${o} was preserved. Revert or remove it before reapplying.`,!1,r);C=KM(w)}else{if(k!==void 0&&k!==s)return ze(`Existing file ${o} is not the Anyray helper for this runtime. It was left unchanged.`,!1,r);let I=y.foreignState||$e.some(W=>y.values[W].present),_=$e.every(W=>ua(y.values[W],g[W])),T=$e.every(W=>ua(y.values[W],VM(e,t.trim())[W]));if(I&&!_&&!T)return ze(`Existing Claude third-party-inference policy values under ${De} are not owned by Anyray. They were left unchanged to avoid copying or overwriting another provider credential.`,!1,r);if(C=T,_&&k===s)return n.dryRun?{status:"configured",messages:[`Would adopt the exact dynamic-helper values under ${De} into an owner-only journal without rewriting them.`]}:(await Hl(Uk(y.keyPresent,g,o,a),r),{status:"configured",changedFiles:[c],messages:[`Adopted the exact dynamic-helper values under ${De} into the ownership journal.`]})}if(C){let I=!0;try{I=(r.appRunning??Im)()}catch{}if(I)return ze("Claude Desktop is running. Fully quit it, then re-run Connect to migrate the legacy static credential safely.",!1,r)}let S=jM(w?.keyExisted??y.keyPresent,y.values,g,o,b?.content,a);if(m=S,n.dryRun)return{status:"configured",messages:[`Would atomically configure Claude Desktop through ${De}, install a dynamic credential helper at ${o}, and create an owner-only rollback journal.`]};await Hl(S,r),f=!0;for(let I of $e){let _=await Un(i);if(!pa(_.values[I],S.lastWritten[I])&&!pa(_.values[I],S.pending[I]))throw new Error("registry value changed during apply");if(!ua(_.values[I],g[I])&&!await Pm(i,I,g[I]))throw new Error("registry write failed")}let E=await Un(i);if(!$e.every(I=>pa(E.values[I],S.pending[I])))throw new Error("registry verification failed");if(k!==s&&(k===void 0?await AM(o,a):await Gl(o,k,a,"apply",r)),await ya(o)!==s)throw new Error("credential helper verification failed");return await Hl(Uk(S.keyExisted,g,o,a),r),{status:"configured",changedFiles:[c,o],messages:[`Configured Claude Desktop through ${De}.`,`Installed or updated the dynamic credential helper at ${o}; no personal key is stored in policy or the ownership journal.`,"Fully quit and reopen Claude Desktop to load the policy.",...Dl]}}catch{if(!f||!u||!p||!m)return ze("Could not safely inspect or begin Claude Desktop's HKCU policy transaction; the registry was left unchanged.",!1,r);try{await Vl(o,m);let h=!0,w=await ha(o),y=m.helper.pending;if(w?.sha256!==m.helper.lastWritten?.sha256&&(y!==void 0&&w?.sha256===y.sha256?m.helper.lastWritten?(await Gl(o,y.sha256,m.helper.lastWritten.content,"rollback",r),h=await ya(o)===m.helper.lastWritten.sha256):await Gl(o,y.sha256,void 0,"rollback",r):h=w===void 0&&m.helper.lastWritten===void 0),h&&await ZM(i,u.values,p))return d?await Hl(d,r):await Xt(c,{force:!0}),ze("Claude Desktop's HKCU policy update failed and was rolled back to its exact pre-apply state.",!1,r)}catch{}return ze("Could not complete or fully roll back Claude Desktop's HKCU policy transaction. The owner-only journal was preserved; run `anyray-connect desktop disconnect` to recover safely.",!0,r)}finally{await l?.()}},nv=async(e,t={})=>{let n=t.runReg??Hn,r=Mt(t),o;if(!e.dryRun)try{o=await xm(t)}catch(a){return ze(a instanceof ma?"Another Claude Desktop policy operation is already in progress; retry shortly.":"Could not acquire the owner-only Claude Desktop policy lock; no registry value was removed.",!1,t)}try{let a=await Tm(t,!e.dryRun);a&&!e.dryRun&&await Vl(a.helper.path,a);let s=await Un(n);if(!a)return $e.filter(f=>s.values[f].present).length>0?ze(`Claude policy values exist under ${De}, but Anyray has no ownership journal. Remove them manually only if you know they came from an older Connect run.`,!1,t):{status:"not-found",messages:["No Windows Claude setup to revert."]};let i=$e.filter(m=>s.values[m].present&&!km(a,m,s.values[m])),c=await ya(a.helper.path),l=c!==void 0&&!fa(a,c);if(e.dryRun)return{status:i.length||l?"manual":"reverted",messages:[`Would remove Anyray-owned values from ${De}.`,`Would remove the Anyray-owned credential helper at ${a.helper.path}.`,...i.length||l?[`Would preserve changed values: ${[...i,...l?["credential helper"]:[]].join(", ")}.`]:[]]};let d=!1,u=new Set(i);for(let m of $e){let h=(await Un(n)).values[m];if(h.present){if(!km(a,m,h)){u.add(m);continue}await Pm(n,m,{present:!1})||(d=!0)}}let p=await ya(a.helper.path);if(p!==void 0)if(fa(a,p))try{await Gl(a.helper.path,p,void 0,"revert",t)}catch{d=!0,u.add("credential helper")}else u.add("credential helper");return d?ze(`Could not remove every Anyray-owned Claude policy value or credential-helper file. The ownership journal remains at ${r}; re-run revert.`,!0,t):(await Xt(r,{force:!0}),{status:u.size?"manual":"reverted",changedFiles:[r],messages:[`Removed Anyray-owned Claude Desktop values from ${De}.`,"Removed the Anyray-owned dynamic credential helper when its content still matched the journal.",...u.size?[`Preserved values changed after Connect: ${[...u].join(", ")}.`]:[],...u.size?[]:Ll]})}catch{return ze(`Could not safely inspect or revert ${De}; no unproven value was removed.`,!1,t)}finally{await o?.()}},rv=async(e,t={})=>{let n=t.runReg??Hn;if(!await x(Mt(t)))return;let r;try{r=await xm(t);let o=await Tm(t);if(o&&await Vl(o.helper.path,o),!o||o.pending||await Sr(n)!==void 0)return;let a=await Un(n);if(!(a.values.inferenceProvider.value==="gateway"&&a.values.inferenceGatewayBaseUrl.value===Vt(e)&&a.values.inferenceGatewayAuthScheme.value==="bearer"&&$e.every(l=>pa(a.values[l],o.lastWritten[l]))))return;let i=await ya(o.helper.path),c=o.helper.lastWritten;return a.values.inferenceCredentialKind.value==="helper-script"&&a.values.inferenceCredentialHelper.value===o.helper.path&&!a.values.inferenceGatewayApiKey.present&&c!==void 0&&i===c.sha256&&await bM(c,t)?"dynamic":o.helper.lastWritten===void 0&&!a.values.inferenceCredentialKind.present&&!a.values.inferenceCredentialHelper.present&&a.values.inferenceGatewayApiKey.present?"legacy-static":void 0}catch{return}finally{await r?.()}},ov=async(e,t={})=>await rv(e,t)!==void 0,av=async(e,t={})=>await rv(e,t)==="dynamic";var ba=(e=JM())=>e==="win32"?Im:Fl,Dm="You can still make this export searchable with `anyray-connect history import <conversations.json>`.",Jl=async(e,t={})=>{let n=(t.profileRoot??io)();if(!n)return{ok:!1,reason:"this platform has no Claude Desktop third-party profile",remedy:Dm};if((t.appRunning??ba(t.runtimePlatform))())return{ok:!1,reason:"Claude Desktop is running",remedy:"Fully quit Claude Desktop, then run this again."};try{await sv.access(e)}catch{return{ok:!1,reason:`no such file: ${e}`,remedy:"Point at the .zip Anthropic emailed you (claude.ai -> Settings -> Privacy -> Export data)."}}let r=await Pl(n);if(!r.ok)return r.reason==="ambiguous"?{ok:!1,reason:"this Claude Desktop profile holds more than one account",remedy:"Choosing which one gets the history is your call, not ours \u2014 "+Dm}:{ok:!1,reason:"no Claude Desktop third-party session store found \u2014 the app has not run in this mode yet",remedy:"Open Claude Desktop with Anyray configured, sign in with your usual Claude account, quit it, then run this again."};let o=await(t.findBinary??JC)();if(!o)return{ok:!1,reason:"the Claude Code CLI was not found",remedy:"Install Claude Code (the conversion step uses its importer), then run this again."};let a=Yl(t.stagingRoot??XM(),`anyray-history-${process.pid}-${YM()}`);try{let s=await(t.runImporter??XC)({binary:o,exportPath:e,configDir:Yl(a,"config"),workDir:Yl(a,"work")});if(!s.ok)return{ok:!1,reason:s.reason,remedy:"This step uses an unsupported Claude Code subcommand, so a version change can break it. "+Dm};if(s.conversations.length===0)return{ok:!1,reason:"that export contains no conversations",remedy:"Check you pointed at the export archive itself."};let i=await qC(r.dir,s.conversations),c=await QC({stagedProjectsDir:Yl(a,"work","projects"),storageDir:r.dir,projects:s.projects,now:t.now?.()??Date.now()});return{ok:!0,storageDir:r.dir,...i,projects:c}}finally{await sv.rm(a,{recursive:!0,force:!0}).catch(()=>{})}};import{promises as St}from"node:fs";import{homedir as wB}from"node:os";import{join as qt,sep as bB}from"node:path";import{isDeepStrictEqual as Ql}from"node:util";import{constants as zM}from"node:fs";import{promises as V}from"node:fs";import{dirname as Aa,isAbsolute as Nm,join as ae,relative as Xl,resolve as zt,sep as li}from"node:path";import{randomUUID as ed}from"node:crypto";var Cn=448,di=384,dv=448,qM=4,$m=3e4,uv=5e3,QM=10*6e4,Lm=e=>({kind:e,migrated:0,alreadyPresent:0,conflicts:0,invalid:0,failed:0}),ct=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),ui=e=>typeof e=="string"&&e.length>0&&e.length<=255&&e!=="."&&e!==".."&&!e.includes("/")&&!e.includes("\\")&&!e.includes("\0"),pv=(e,t)=>{let n=Xl(zt(e),zt(t));return n===""||!n.startsWith(`..${li}`)&&n!==".."&&!Nm(n)},po=async e=>{try{let t=await V.readFile(e,"utf8"),n=JSON.parse(t);return ct(n)?{raw:t,value:n}:void 0}catch(t){return vt(t)&&t.code==="ENOENT"?{raw:void 0,value:{}}:void 0}},vt=e=>e instanceof Error&&"code"in e,eB=e=>{try{return process.kill(e,0),!0}catch(t){return vt(t)&&t.code==="EPERM"}},fv=e=>e===0?"owner.json":`owner.${e}.json`,zl=async e=>{let t;try{t=await V.readdir(e)}catch{return}let r=t.map(d=>{if(d==="owner.json")return{name:d,generation:0};let u=/^owner\.(\d+)\.json$/.exec(d);if(!u)return;let p=Number(u[1]);return Number.isSafeInteger(p)&&p>0?{name:d,generation:p}:void 0}).filter(d=>!!d).sort((d,u)=>u.generation-d.generation)[0];if(!r)return;let o=ae(e,r.name),a,s,i;try{let d=JSON.parse(await V.readFile(o,"utf8"));ct(d)&&typeof d.pid=="number"&&Number.isSafeInteger(d.pid)&&d.pid>0&&typeof d.nonce=="string"&&d.nonce.length>0&&(a=d.pid,s=d.nonce,typeof d.createdAt=="number"&&Number.isFinite(d.createdAt)&&d.createdAt>=0&&(i=d.createdAt))}catch{}let c=await V.stat(o).then(d=>d.mtimeMs),l=i!==void 0&&i<=Date.now()+6e4?i:c;return{generation:r.generation,pid:a,nonce:s,createdAtMs:l,mtimeMs:c}},mv=e=>{if(e.pid===void 0||!eB(e.pid))return!0;let t=Date.now();return t-e.mtimeMs>$m&&t-e.createdAtMs>QM},tB=async e=>{let t=`${e}.anyray-lock`;await V.mkdir(Aa(t),{recursive:!0,mode:Cn});let n=ed(),r,o=!1;try{await V.mkdir(t,{mode:Cn}),o=!0}catch(i){if(!vt(i)||i.code!=="EEXIST")throw i}for(let i=0;i<3&&!r;i+=1){let c=0;if(!o){let d=await zl(t);if(d){if(!mv(d)||!Number.isSafeInteger(d.generation+1))return;c=d.generation+1}else if(await V.stat(t).then(p=>Date.now()-p.mtimeMs).catch(()=>0)<=$m)return}let l=ae(t,fv(c));try{await V.writeFile(l,`${JSON.stringify({pid:process.pid,nonce:n,createdAt:Date.now()})}
|
|
257
|
-
`,{flag:"wx",mode:di}),r=l}catch(d){if(vt(d)&&d.code==="EEXIST"){o=!1;continue}throw o&&await V.rm(t,{recursive:!0,force:!0}).catch(()=>{}),d}}if(!r)return;let a=r,s=setInterval(()=>{(async()=>{try{let i=JSON.parse(await V.readFile(a,"utf8"));if(!ct(i)||i.nonce!==n)return;let c=new Date;await V.utimes(a,c,c)}catch{}})()},uv);return s.unref(),async()=>{clearInterval(s);try{(await zl(t))?.nonce===n&&await V.rm(t,{recursive:!0,force:!0})}catch{}}},
|
|
258
|
-
`,{mode:di,flag:"wx"}),await V.rename(a,e)}catch(s){try{await V.rm(a,{force:!0})}catch{}throw s}return!0}finally{await r()}},td=async(e,t)=>{for(let n=0;n<
|
|
259
|
-
`,{flag:"wx",mode:di}),o=u}catch(p){if(vt(p)&&p.code==="EEXIST"){n=!1;continue}n&&await V.rm(e,{recursive:!0,force:!0}).catch(()=>{});return}}if(!o)return;let a=o,s=setInterval(()=>{(async()=>{try{let l=JSON.parse(await V.readFile(a,"utf8"));if(!ct(l)||l.nonce!==r)return;let d=new Date;await V.utimes(a,d,d)}catch{}})()},uv);s.unref();let i=!1,c=()=>{i||(i=!0,clearInterval(s))};return{abandon:c,complete:async()=>{c();try{(await zl(e))?.nonce===r&&await V.rm(e,{recursive:!0,force:!0})}catch{}}}},bv=async e=>{let t=await wv(e,!1);t&&await t.complete()},
|
|
260
|
-
`)}},Fm=e=>new Set(e.flatMap(t=>t.sources.map(n=>n.account))),xv=async e=>{let t=[];for(let n of kB)t.push({lane:n,sources:await SB(e,n)});return t},Rv=async(e={})=>{let t=(e.firstPartyRoot??(()=>zs()))();if(!t)return{sessions:0,accounts:0,userSkills:0,userPlugins:0,localMcpServers:0};let[n,r]=await Promise.all([xv(t),Mm(t)]),o=n.reduce((s,i)=>s+i.sources.reduce((c,l)=>c+l.ids.length,0),0),a=Fm(n);for(let s of r.accounts)a.add(s);return{sessions:o,accounts:a.size,userSkills:r.skills,userPlugins:r.plugins,localMcpServers:r.localMcpServers}},fo=async(e={})=>{let t=(e.home??wB)(),n=(e.firstPartyRoot??(()=>zs()))(),r=(e.thirdPartyRoot??(()=>io()))();if(!n||!r)return{ok:!1,kind:"platform-unsupported",reason:"this platform has no Claude Desktop third-party profile",remedy:"Migration applies to macOS and Windows, where Desktop runs third-party mode in its own profile."};if((e.appRunning??ba())())return{ok:!1,kind:"app-running",reason:"Claude Desktop is running",remedy:"Fully quit Claude Desktop and run this again \u2014 it rewrites its session list on exit, which would undo the migration."};let[o,a]=await Promise.all([xv(n),Mm(n)]),s;if(e.account){let m=e.account;for(let w of o)w.sources=w.sources.filter(y=>y.account.startsWith(m));let f=a.accounts.filter(w=>w.startsWith(m));if(o.every(w=>w.sources.length===0)&&f.length===0)return{ok:!1,kind:"account-unmatched",reason:`no account in the previous profile starts with "${m}"`,remedy:`Run \`${e.command??"anyray-connect desktop --migrate"}\` with no flags to list the accounts.`};let h=Fm(o);for(let w of f)h.add(w);if(h.size>1)return Sv(o,e.command??"anyray-connect desktop --migrate",`"${m}" matches ${h.size} accounts`,f);s=[...h]}else if(!e.allAccounts){let m=Fm(o);for(let f of a.accounts)m.add(f);if(m.size>1)return Sv(o,e.command??"anyray-connect desktop --migrate",`the previous Claude Desktop profile holds local data for ${m.size} accounts`,a.accounts);s=[...m]}let i=e.command??"anyray-connect desktop --migrate",c=!await AB(r),l=await kv(n,r,{account:e.account,allAccounts:e.allAccounts,allowedAccounts:s});if(l.sourceChanged)return{ok:!1,kind:"account-ambiguous",reason:"the previous Claude Desktop profile changed during migration and now holds local data for another account",remedy:`Re-run \`${i}\` so the account choice is made from a fresh snapshot.`};let d=[],u=[];for(let{lane:m,sources:f}of o){if(f.length===0){d.push(Bm(m));continue}let h=await EB(r,m);if("missing"in h){u.push({lane:m,reason:h.missing,waiting:f.reduce((w,y)=>w+y.ids.length,0)}),d.push(Bm(m));continue}d.push(await RB(m,f,h.dir,t))}if(!(d.some(m=>m.migrated>0||m.alreadyPresent>0)||l.outcomes.some(m=>m.migrated>0||m.alreadyPresent>0||m.conflicts>0))&&(u.length>0||l.blocked.length>0)){let m=u[0];return m?{ok:!1,kind:m.reason==="ambiguous"?"account-ambiguous":"store-missing",reason:m.reason==="ambiguous"?`Claude Desktop's third-party profile holds more than one ${m.lane} store`:`Claude Desktop has no ${m.lane} store in its third-party profile yet`,remedy:Wm(m.reason,m.lane,i,c)}:{ok:!1,kind:"store-missing",reason:"Claude Desktop's third-party profile has no extension store yet",remedy:"Open Claude Desktop once after connecting it to Anyray, then fully quit it so the portable extensions can be copied safely."}}return{ok:!0,lanes:d,portableAssets:l.outcomes,...u.length>0?{blocked:u}:{},...l.blocked.length>0?{blockedAssets:l.blocked}:{},...l.ambiguous.length>0?{ambiguousAssets:l.ambiguous}:{},...l.retryable.length>0?{retryableAssets:l.retryable}:{}}};var TB=e=>[Ne(e)],Ov=e=>({id:e.id,title:e.title,automatic:!1,async detect(){let t=[...TB(e.appDir),...e.detectPaths?.()??[]];for(let n of t)if(await x(n))return{installed:!0,detail:n};return{installed:!1,detail:`${e.appDir} not found`}},async apply(t){return{status:"manual",messages:e.steps(t)}},async revert(t){return{status:"manual",messages:e.revertMessages??[`${e.title}: clear the custom OpenAI base URL / key in its settings to revert.`]}}});var Tv="1.21459.0",LB=DB(_B),NB=async e=>{try{let{stdout:t}=await LB("/usr/bin/plutil",["-extract","CFBundleShortVersionString","raw","-o","-",e],{timeout:2e3,maxBuffer:4096});return String(t).trim()||void 0}catch{return}},$B=async e=>{try{return await PB(e)}catch{return}},_v="No native config was written; use Developer \u2192 Configure Third-Party Inference \u2192 Apply locally.",MB=["Admin policy setup (no JSON): open Developer \u2192 Configure Third-Party Inference; the Anyray connection is already filled in.",'Add approved remote MCP connectors under "Connectors & extensions" and use "Test this connection"; add approved Git marketplaces under "Plugins & skills".',`Choose "Apply locally" to test. For Jamf, first select IT's fleet-wide credential-helper path, then choose Export \u2192 .mobileconfig and deploy the complete profile.`,"If Claude Desktop is already MDM-managed, this window is read-only. Author and export on an unmanaged admin Mac, then redeploy through Jamf."],Ca=async(e={})=>!e.home&&!e.readClaudeAppVersion&&!e.readClaudeAppBundle?(Pv??=Dv({}),Pv):Dv(e),Pv,Dv=async e=>{let t=(e.home??fi)(),n=["/Applications/Claude.app",kn(t,"Applications","Claude.app")],r=e.readClaudeAppVersion??NB,o=e.readClaudeAppBundle??$B;for(let a of n){let s=await r(kn(a,"Contents","Info.plist"));if(!s)continue;let i=d=>({supported:!1,detectedVersion:s,appPath:a,message:`Claude Desktop ${s} is installed, but ${d} ${_v}`}),c=Tl(s,Tv);if(c===void 0)return i("its version string could not be interpreted.");if(c<0)return i(`automatic local setup requires ${Tv} or newer.`);let l=await o(kn(a,"Contents","Resources","app.asar"));return l?hk.some(d=>!l.includes(d))?i("its local config seam no longer matches the shape Connect writes."):{supported:!0,detectedVersion:s,appPath:a}:i("its app bundle could not be read to verify the local config seam.")}return{supported:!1,message:`Could not verify the installed Claude Desktop version. ${_v}`}},rd="anyray",$v="--anyray-owner=claude-desktop-v1",od=(e={})=>{let t=(e.platform??Er)(),n=(e.home??fi)();return t==="darwin"?Jt(e).appConfig:t==="win32"?kn(process.env.APPDATA??kn(n,"AppData","Roaming"),"Claude","claude_desktop_config.json"):kn(n,".config","Claude","claude_desktop_config.json")},Km=(e={})=>kn((e.home??fi)(),"Library","Application Support","Claude","claude_desktop_config.json"),Mv=()=>{let e=Ge("profile");return{command:e.command,args:[...e.args,$v]}},mo=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),Bv=(e,t)=>{let n=Object.keys(e).sort(),r=[...t].sort();return n.length===r.length&&n.every((o,a)=>o===r[a])},BB=(e,t)=>Array.isArray(e)&&e.length===t.length&&e.every((n,r)=>typeof n=="string"&&n===t[r]),FB=e=>{if(!mo(e)||!Bv(e,["command","args"]))return!1;let t=Mv();return e.command===t.command&&BB(e.args,t.args)},WB=e=>mo(e)&&Array.isArray(e.args)&&e.args.at(-1)===$v,UB=e=>{if(!mo(e)||!Bv(e,["command","args"])||typeof e.command!="string"||!Array.isArray(e.args)||!e.args.every(a=>typeof a=="string")||tt(e.command))return!1;let t=e.args;if(!(t.length>=2&&t.at(-2)===er&&t.at(-1)==="profile"))return!1;let r=e.command.replaceAll("\\","/");if(/(?:^|\/)anyray-connect(?:\.exe)?$/.test(r))return t.length===2;if(!/(?:^|\/)node(?:\.exe)?$/.test(r)||t.length!==3)return!1;let o=t[0].replaceAll("\\","/");return!tt(t[0])&&(/(?:^|\/)anyray-connect(?:\/|$)/.test(o)||/(?:^|\/)\.anyray\/bin\/connect-runtime-[0-9A-Za-z][0-9A-Za-z.-]*\/dist\/index\.js$/.test(o))},HB=e=>e===void 0?"absent":FB(e)?"exact":WB(e)||UB(e)?"stale-owned":"foreign",We=class extends Error{changedFiles;constructor(t,n=[]){super(t),this.changedFiles=n}},ho=async e=>{let t=await x(e),n;try{n=await M(e)}catch{throw new We(`Could not parse ${e}; it was left unchanged.`)}if("mcpServers"in n&&!mo(n.mcpServers))throw new We(`Could not update ${e} because mcpServers is not an object; it was left unchanged.`);let o=(mo(n.mcpServers)?n.mcpServers:void 0)?.[rd];return{path:e,fileExisted:t,json:n,entry:o,ownership:HB(o)}},ad=e=>{if(e.ownership==="foreign")throw new We(`MCP name conflict in ${e.path}: mcpServers.${rd} is not owned by Anyray Connect, so it was left untouched. Rename that existing server, then re-run Connect.`)},Fv=(e,t)=>{let n={...e},r=mo(e.mcpServers)?{...e.mcpServers}:{};return t===void 0?delete r[rd]:r[rd]=t,Object.keys(r).length===0?delete n.mcpServers:n.mcpServers=r,n},Hm=async(e,t)=>{if(Um(e.entry,t))return;let n=await ho(e.path);if(!Um(n.entry,e.entry))throw new We(`The MCP configuration in ${e.path} changed during setup; it was left untouched. Re-run Connect.`);return await Wn(e.path,Fv(n.json,t)),{reading:e,afterEntry:t}},Gm=async e=>{let t=await ho(e.reading.path);if(!Um(t.entry,e.afterEntry))throw new We(`The MCP configuration in ${e.reading.path} changed before rollback; the newer value was preserved.`);let n=Fv(t.json,e.reading.entry);await Wn(e.reading.path,n)},GB=async e=>{if(!oe())throw new We(`A durable anyray-connect runtime is required for Claude Desktop retrieval (${Pe()} is temporary); no inference setting was changed.`);let t=await ho(od(e));ad(t);let n=Km(e),r=(e.platform??Er)()==="darwin"&&n!==t.path?await ho(n):void 0;return r&&ad(r),{active:t,...r?{legacy:r}:{}}},Lv=async e=>{let t=await ho(od(e));ad(t);let n=Km(e),r=(e.platform??Er)()==="darwin"&&n!==t.path?await ho(n):void 0;return r&&ad(r),{active:t,...r?{legacy:r}:{}}},VB=async e=>{let t=[];try{let n=await Hm(e.active,Mv());if(n&&t.push(n),e.legacy&&e.legacy.ownership!=="absent"){let r=await Hm(e.legacy,void 0);r&&t.push(r)}}catch(n){let r=[];for(let o of[...t].reverse())await Gm(o).catch(()=>{r.push(o.reading.path)});throw r.length>0?new We(`Claude Desktop MCP setup failed and could not restore ${r.join(", ")}. Re-run \`anyray-connect desktop disconnect\` to recover safely.`,r):n}return{changedFiles:t.map(n=>n.reading.path),async rollback(){let n=[];for(let r of[...t].reverse())await Gm(r).catch(()=>{n.push(r.reading.path)});if(n.length>0)throw new We(`Claude Desktop MCP rollback could not restore ${n.join(", ")}. Newer values were preserved; re-run revert after resolving the conflict.`,n)}}},KB=async e=>{let t=[];try{for(let n of[e.active,e.legacy].filter(r=>!!r)){if(n.ownership==="absent")continue;let r=await Hm(n,void 0);r&&t.push(r)}}catch(n){let r=[];for(let o of[...t].reverse())await Gm(o).catch(()=>{r.push(o.reading.path)});throw r.length>0?new We(`Claude Desktop MCP cleanup failed and could not restore ${r.join(", ")}. Re-run revert after resolving the file conflict.`,r):n}return t.map(n=>n.reading.path)},Nv=e=>{let t=e.clientKey?`${e.clientKey} (your personal gateway key - keep it private)`:`${e.placeholderKey} (placeholder - the gateway holds the real key)`;return["Step 1 - Turn on Developer Mode."," In the menu bar at the VERY TOP of the screen (NOT the in-app help panel):"," Help -> Troubleshooting -> Enable Developer Mode"," (Windows: open the menu at the top-left of the sign-in screen.)",' A "Developer" menu then appears in that same top-of-screen menu bar.',"","Step 2 - Open the Developer MENU in the menu bar (shown below) - NOT Settings:",""," +----------------------------------------------------------------+"," | Claude File Edit View Window [Developer] Help | <- macOS menu bar (very top of screen)"," +-------------------------------------^--------------------------+"," |",' click Developer -> "Configure Third-Party Inference..."',"",' Heads up: use the "Developer" MENU in the bar above - NOT',' Settings -> Developer, which is the "Local MCP servers" pane'," (that's where Anyray's retrieval server appears, not inference)."," A separate setup window then opens.","","Step 3 - In that window's Connection section, paste:",""," Inference provider: Gateway",` Gateway base URL: ${e.anthropicBaseUrl}`," Auth scheme: Bearer",` API key: ${t}`,"",'Step 4 - Click "Apply locally", then fully quit and reopen Claude'," (the config is read once at launch).","","Billing: this route uses an Anyray gateway credential and provider/API billing, not a Claude subscription allowance.","Fleet/MDM: generate a managed profile with `anyray-connect desktop claude --mobileconfig` (applies with no Developer Mode and no paste)."]},jB={darwinAppName:"Claude",darwinBundleId:"com.anthropic.claudefordesktop",win32Image:"Claude.exe",win32Install:[{root:"localAppData",path:"Programs\\Claude\\Claude.exe"}]},sd="claude-desktop",Vm="migrate",Wv=new Set(["app-running","store-missing"]),ZB={code:{one:"Claude Code session",many:"Claude Code sessions"},cowork:{one:"Cowork task",many:"Cowork tasks"}},YB={skill:{one:"user-created skill",many:"user-created skills"},plugin:{one:"user-installed plugin",many:"user-installed plugins"},"local-mcp":{one:"local MCP server",many:"local MCP servers"}},JB="Claude Desktop machine policy could not be read; Connect left inference and retrieval configuration unchanged.",Uv=e=>{let t=(e.platform??Er)(),n=e.home??fi;return{home:n,appRunning:e.appRunning??ba(t),firstPartyRoot:()=>zs({home:n,runtimePlatform:t}),thirdPartyRoot:()=>io({home:n,runtimePlatform:t}),command:"anyray-connect migrate"}},Hv=e=>{let t=e.filter(a=>a.migrated>0);if(t.length===0)return;let n=e.reduce((a,s)=>a+s.skippedNoTranscript,0),r=e.reduce((a,s)=>a+s.failed,0);return`Brought your existing Claude Desktop sessions into its third-party profile: ${t.map(a=>{let s=ZB[a.lane];return`${a.migrated} ${a.migrated===1?s.one:s.many}`}).join(", ")}.`+(n>0?` ${n} skipped \u2014 the transcript is no longer on disk.`:"")+(r>0?` ${r} could not be copied.`:"")},Gv=e=>{let t=e.filter(s=>s.migrated>0),n=e.reduce((s,i)=>s+i.conflicts,0),r=e.reduce((s,i)=>s+i.invalid,0),o=e.reduce((s,i)=>s+i.failed,0);if(t.length===0&&n+r+o===0)return;let a=t.map(s=>{let i=YB[s.kind];return`${s.migrated} ${s.migrated===1?i.one:i.many}`});return(a.length>0?`Brought your portable Claude Desktop configuration across: ${a.join(", ")}.`:"Portable Claude Desktop configuration was checked; existing target entries were kept.")+(n>0?` ${n} conflicting target ${n===1?"entry was":"entries were"} preserved.`:"")+(r>0?` ${r} unsafe or incomplete ${r===1?"entry was":"entries were"} skipped.`:"")+(o>0?` ${o} could not be copied.`:"")},pi=async(e,t)=>{if(!t.reportsToUser)return[];try{let n=Uv(e),r=await(e.pendingDesktopMigrationCount??Rv)(n),o=r.userSkills+r.userPlugins+r.localMcpServers;if(r.sessions+o===0)return[];if(t.dryRun)return[`Would bring ${[r.sessions>0?`${r.sessions} existing Claude Desktop session${r.sessions===1?"":"s"}`:"",o>0?`${o} portable configuration ${o===1?"entry":"entries"}`:""].filter(Boolean).join(" and ")} into Claude Desktop's third-party profile, now or automatically the next time Claude Desktop is fully quit.`];let a=await(e.migrateDesktopProfile??fo)(n);if(a.ok){let c=Hv(a.lanes),l=Gv(a.portableAssets),d=a.ambiguousAssets??[],u=d.length>0?`Claude Desktop has more than one target ${d.join(" and ")} store. No store was chosen and every target was preserved. Leave only the intended third-party account/workspace active, then run the migration again.`:void 0,p=(a.blocked??[]).filter(g=>g.reason!=="ambiguous"),m=a.blockedAssets??[],f=a.retryableAssets??[];if(p.length===0&&m.length===0&&f.length===0)return[c,l,u].filter(g=>!!g);if(t.preservePendingOp)return[c,l,u].filter(g=>!!g);await xs(sd,Vm);let h=p.reduce((g,b)=>g+b.waiting,0),w=[h>0?`${h} more session${h===1?"":"s"}`:"",m.length>0?`${m.length} extension ${m.length===1?"store":"stores"}`:""].filter(Boolean),y=[...w.length>0?[`Queued: ${w.join(" and ")} move across once Claude Desktop creates the required third-party stores and the app is fully quit.`]:[],...f.length>0?[`Queued: ${f.length} portable configuration ${f.length===1?"type":"types"} will retry automatically after a recoverable local-copy interruption.`]:[]];return[...c?[c]:[],...l?[l]:[],...u?[u]:[],...y]}if(!Wv.has(a.kind))return[`Your existing Claude Desktop local data was left where it is: ${a.reason}.
|
|
261
|
-
${a.remedy}`];if(t.preservePendingOp)return[];await xs(sd,Vm);let s=r.sessions+o,i=`${s} Claude Desktop local ${s===1?"item":"items"}`;return[a.kind==="store-missing"?`Queued: the ${i} still in your previous profile move across once Claude Desktop's new profile has been signed in to and the app is fully quit.`:`Queued: the ${i} still in your previous profile will move across the next time you fully quit Claude Desktop.`]}catch{return["Could not check whether Claude Desktop had existing sessions to bring across; run `anyray-connect migrate` if its lists look empty."]}},XB=async e=>{if(!e.fullRevert||e.dryRun)return[];try{return await ur(sd),[]}catch{return["Could not clear Claude Desktop's queued profile-migration marker; a background watcher may still be waiting for the app to quit. Delete it by hand if it persists."]}},zB=e=>Ov({id:sd,title:"Claude desktop",appDir:"Claude",detectPaths:()=>{let t=(e.platform??Er)(),n=(e.home??fi)();return t==="darwin"?["/Applications/Claude.app",kn(n,"Applications","Claude.app")]:t==="win32"?[kn(process.env.LOCALAPPDATA??kn(n,"AppData","Local"),"Programs","Claude","Claude.exe")]:[]},steps:t=>te(t,"anthropic")?["Claude Desktop subscription routing requires automatic setup on a verified macOS build and a Claude Code sign-in in Keychain.","This platform/build has no verified subscription helper seam, so Connect left inference unchanged instead of silently switching you to API billing.","To opt into the API-billed Gateway lane instead, re-run Connect in org/API mode and use:",...Nv(t)]:["Claude desktop org/API lane:",...Nv(t),"This Gateway route uses provider/API billing. On verified macOS builds, subscription mode instead installs the Keychain-backed Claude Code credential helper automatically."],revertMessages:["Claude Desktop third-party inference: switch back to the first-party Claude provider in Developer settings (or remove the managed profile). Native setup is restored automatically by `--revert`."]}),qB=(e={})=>{let t=zB(e),n=()=>(e.platform??Er)()==="darwin",r=()=>(e.platform??Er)()==="win32",o=(s,i)=>n()?vk(s,i,e):tv(s,s.clientKey??"",i,e),a=s=>n()?Sk(s,e):nv(s,e);return{...t,automatic:!0,changesOrgManagement:!0,quitGated:{isRunning:()=>(e.appRunning??ba((e.platform??Er)()))(),quitTarget:jB,needsTarget:()=>!1,async complete(s){if(s!==Vm)return{status:"manual",messages:[`Claude Desktop could not service a queued "${s}" operation it does not recognise; the queue entry was dropped.`]};let i=await(e.migrateDesktopProfile??fo)(Uv(e));if(i.ok){let c=Hv(i.lanes),l=Gv(i.portableAssets),d=i.ambiguousAssets??[];if(d.length>0)return{status:"manual",messages:[...c?[c]:[],...l?[l]:[],`Claude Desktop has more than one target ${d.join(" and ")} store. No store was chosen and every target was preserved. Leave only the intended third-party account/workspace active, then run the migration again.`]};let p=(i.blocked??[]).filter(h=>h.reason!=="ambiguous"),m=i.blockedAssets??[],f=i.retryableAssets??[];return p.length>0||m.length>0||f.length>0?{status:"queued",messages:[...c?[c]:[],...l?[l]:[],...p.length>0||m.length>0?["Still waiting on Claude Desktop to create the remaining third-party stores, which appear the first time those parts of the app are opened."]:[],...f.length>0?["A recoverable local-copy interruption remains; the migration will retry automatically."]:[]]}:{status:"configured",messages:c||l?[c,l].filter(h=>!!h):["No portable Claude Desktop data was left to bring across."]}}return Wv.has(i.kind)?{status:"queued",messages:[i.reason]}:{status:"manual",messages:[i.reason,i.remedy]}}},async usesDynamicCredential(s){return n()?Ik(s,e):r()?av(s,e):!1},async apply(s,i){if(!n()&&!r())return t.apply(s,i);if(n()){let p=Jt(e),m=await lo(p,e);if(m)return{status:"manual",manualAudience:"admin",messages:[mm(m),...await pi(e,i)]}}if(r()){let p;try{p=await Sr(e.runReg??Hn)}catch{return{status:"manual",manualAudience:"admin",messages:[JB,...await pi(e,i)]}}if(p)return{status:"manual",manualAudience:"admin",messages:[_m(p),...await pi(e,i)]}}if(r()&&te(s,"anthropic"))return{status:"manual",messages:["Claude Desktop subscription routing is not available on Windows: Connect could not verify a supported Claude subscription credential source, so inference was left unchanged instead of switching to API billing.","Use org/API mode for the Windows Gateway lane, or run subscription mode on a verified macOS build after signing in to Claude Code."]};if(n()){let p=await Ca(e);if(!p.supported)return{status:"manual",messages:[p.message??"Claude Desktop version is unsupported."]}}let c;try{c=await GB(e)}catch(p){let m=p instanceof We?p.changedFiles:[];return{status:"manual",...m.length>0?{changedFiles:m}:{},messages:[p instanceof We?p.message:"Could not safely inspect Claude Desktop's retrieval MCP configuration; no inference setting was changed."]}}let l=await o(s,{dryRun:!0});if(l.status!=="configured")return l;if(i.dryRun){let p=c.legacy;return{...l,messages:[...l.messages,`Would register the ownership-marked Anyray retrieval MCP server in ${c.active.path}.`,...p&&p.ownership!=="absent"?[`Would remove the legacy owned Anyray MCP registration from ${p.path}.`]:[],...await pi(e,i)]}}let d;try{d=await VB(c)}catch(p){let m=p instanceof We?p.changedFiles:[];return{status:"manual",...m.length>0?{changedFiles:m}:{},messages:[p instanceof We?p.message:"Could not safely register Claude Desktop retrieval; the inference route was left unchanged."]}}let u;try{u=await o(s,{dryRun:!1})}catch{u={status:"manual",messages:["Claude Desktop inference setup failed before it returned a result."]}}if(u.status!=="configured")try{return await d.rollback(),{...u,changedFiles:[...new Set([...u.changedFiles??[],...d.changedFiles])],messages:[...u.messages,"Restored the prior Claude Desktop MCP registration because inference setup did not complete. A config file that was absent before setup may remain as an inert object to avoid racing unrelated concurrent writes."]}}catch{return{status:"manual",changedFiles:[...u.changedFiles??[],...d.changedFiles],messages:[...u.messages,"Inference setup did not complete, and the prior MCP registration could not be fully restored. Re-run `anyray-connect desktop disconnect` to recover safely."]}}return{...u,messages:[...u.messages,"Registered the Anyray retrieval MCP server (anyray_retrieve / anyray_recall) with an ownership marker.",...await pi(e,i),...!i.dryRun&&i.reportsToUser&&i.explicit&&n()?MB:[]],changedFiles:[...new Set([...u.changedFiles??[],...d.changedFiles])]}},async revert(s){let i=od(e),c=await XB(s),l=h=>c.length===0?h:{...h,messages:[...h.messages,...c]};if(!n()&&!r())return l(await t.revert(s));let d;try{d=await Lv(e)}catch(h){return l({status:"manual",messages:[h instanceof We?h.message:"Could not safely inspect Claude Desktop's retrieval MCP configuration; no setting was removed."]})}let u=await a({dryRun:!0});if(s.dryRun){let h=d.legacy;return l({...u,messages:[...u.messages,...d.active.ownership!=="absent"?[`Would remove the owned Anyray retrieval MCP server from ${i}.`]:[],...h&&h.ownership!=="absent"?[`Would remove the legacy owned Anyray MCP registration from ${h.path}.`]:[]]})}let p=await a({dryRun:!1});if(p.status==="manual"){let h=r()?Mt(e):void 0;if(!(h!==void 0&&p.changedFiles?.includes(h)===!0&&!await x(h)))return l(p)}let m;try{m=await KB(await Lv(e))}catch(h){let w=h instanceof We?h.changedFiles:[];return l({status:"manual",changedFiles:[...new Set([...p.changedFiles??[],...w])],messages:[...p.messages,h instanceof We?h.message:"Restored Claude Desktop inference, but could not safely remove its retrieval MCP registration. Re-run revert."]})}await ie(i);let f=Km(e);return n()&&f!==i&&await ie(f),l({...p,messages:[...p.messages,...m.length>0?["Removed the Anyray retrieval MCP server (anyray_retrieve / anyray_recall)."]:[]],changedFiles:[...new Set([...p.changedFiles??[],...m])]})},async mcpStatus(){if(!oe())return{registered:!1,command:null,reason:"ephemeral-runtime"};try{let s=await ho(od(e));return s.ownership!=="exact"||!mo(s.entry)?{registered:!1,command:null,reason:s.fileExisted?s.ownership==="absent"?"absent":s.ownership==="stale-owned"?"stale":"foreign":"no-config"}:{registered:!0,command:typeof s.entry.command=="string"?s.entry.command:null}}catch{return{registered:!1,command:null,reason:"unreadable"}}},async pointsAt(s){return n()?(await Ca(e)).supported?ym(s,e):!1:r()?ov(s,e):!1},async inferenceAuthLanes(){try{if(n()){if(!(await Ca(e)).supported)return["unknown"];let s=await Ek(e);return s?[s]:["unknown"]}if(r())return await x(Mt(e))?await Sr(e.runReg??Hn)?["unknown"]:["api_key"]:["unknown"]}catch{}return["unknown"]},async automaticRepairAllowed(){try{if(n()){let s=Jt(e);return!await x(s.journal)||await lo(s,e)?!1:(await Ca(e)).supported}return r()&&await x(Mt(e))?!await Sr(e.runReg??Hn):!1}catch{return!1}}}},Vv=qB();import{homedir as IF}from"node:os";import{join as xF}from"node:path";import{rm as hd}from"node:fs/promises";import{constants as Kv,accessSync as QB,statSync as eF}from"node:fs";import{platform as jm}from"node:os";import{delimiter as tF,posix as nF,resolve as rF,win32 as oF}from"node:path";var aF="0.59.0",sF="1.1.4",Gn="Anyray \xB7 Claude",Vn="Anyray \xB7 Codex",id="__anyray-acp-agent",jv=(e,t,n)=>{let{command:r,args:o}=nn([id,e,t,n]);return{command:r,args:o,env:{}}},cd=(e=jm())=>e==="win32"?"npx.cmd":"npx",ld=(e=process.env.PATH,t=jm())=>{if(!e)return;let n=cd(t);for(let r of e.split(tF)){let o=r.trim().replace(/^"|"$/g,"");if(!o)continue;let a=rF(o,n);try{if(!eF(a).isFile())continue;return QB(a,t==="win32"?Kv.F_OK:Kv.X_OK),a}catch{}}},dd=(e,t=jm())=>{let n=t==="win32"?oF:nF;return!n.isAbsolute(e)||n.basename(e).toLowerCase()!==cd(t)?!1:t!=="win32"||!/["&|<>^%!\r\n]/.test(e)},iF="https://chatgpt.com/backend-api/codex",cF="chatgpt-account-id,originator,session_id,user-agent,x-codex-turn-metadata,x-codex-window-id,x-client-request-id",Zv="ANYRAY_ACP_CODEX_AUTHORIZATION",Yv="ANYRAY_ACP_CODEX_CLIENT_KEY",Jv="ANYRAY_ACP_CODEX_METADATA",Xv=e=>fe({...e.metadata,tool:e.metadata.tool??"codex",intent:e.metadata.intent??"jetbrains-acp",intentLabel:e.metadata.intentLabel??"JetBrains / Devin via Codex ACP"}),lF=(e,t={})=>{let n=te(e,"openai"),r=n?{"x-anyray-auth-mode":"passthrough","x-anyray-custom-host":iF,"x-anyray-forward-headers":cF}:{},o=n?{...e.clientKey?{"x-anyray-api-key":Yv}:{}}:{Authorization:Zv};return Xv(e)&&(o["x-anyray-metadata"]=Jv),{model_provider:"anyray",model_providers:{anyray:{name:"Anyray Gateway",base_url:e.openaiBaseUrl,wire_api:"responses",...n?{requires_openai_auth:!0}:{},http_headers:r,env_http_headers:o}},...t.mcpServer?{mcp_servers:{anyray:{command:t.mcpServer.command,args:t.mcpServer.args}}}:{}}},dF=e=>{let t=te(e,"openai"),n=Xv(e);return{...t?e.clientKey?{[Yv]:e.clientKey}:{}:{[Zv]:`Bearer ${e.clientKey??e.placeholderKey}`},...n?{[Jv]:n}:{}}},zv=(e,t=cd(),n={})=>({[Gn]:{command:t,args:["--yes",`@agentclientprotocol/claude-agent-acp@${aF}`],env:rn(e).env},[Vn]:{command:t,args:["--yes",`@agentclientprotocol/codex-acp@${sF}`],env:{CODEX_CONFIG:JSON.stringify(lF(e,n)),...dF(e)}}}),mi=(e=cd(),t="jetbrains")=>({[Gn]:jv("claude",e,t),[Vn]:jv("codex",e,t)}),yo=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),ud=(e,t)=>JSON.stringify(e)===JSON.stringify(t);import{inflateRawSync as uF}from"node:zlib";import{open as pF,readFile as zm,readdir as md}from"node:fs/promises";import{dirname as qv,join as me}from"node:path";import{homedir as nS,platform as qm}from"node:os";var pd="2025.3.2",ka="253.30387.147",hi="com.intellij.ml.llm",Zm=new Set(["ml-llm","llm","aia","ai-assistant","jetbrains-ai-assistant"]),fF=1e4,mF=256*1024*1024,hF=16*1024*1024,Ym=1024*1024,Jm=22,yF=Jm+65535,Xm=Tl,gF=()=>{let e=nS(),t=me(e,".cache","JetBrains","RemoteDev");switch(qm()){case"darwin":return[{path:"/Applications",layout:"app-bundles"},{path:me(e,"Applications"),layout:"app-bundles"},{path:me(e,"Library","Application Support","JetBrains","Toolbox"),layout:"recursive"},{path:t,layout:"recursive"}];case"win32":return[{path:me(process.env.LOCALAPPDATA??me(e,"AppData","Local"),"Programs"),layout:"children"},{path:me(process.env.LOCALAPPDATA??me(e,"AppData","Local"),"JetBrains","Toolbox"),layout:"recursive"},{path:me(process.env.ProgramFiles??"C:\\Program Files","JetBrains"),layout:"children"}];default:return[{path:"/opt",layout:"children"},{path:me(e,".local","share","JetBrains","Toolbox"),layout:"recursive"},{path:t,layout:"recursive"}]}},wF=()=>qm()==="linux"?me(nS(),".local","share","JetBrains"):Ne("JetBrains"),bF=()=>qm()==="linux"&&!!(process.env.WSL_DISTRO_NAME||process.env.WSL_INTEROP),AF=async(e,t=fF)=>{let n=[];for(let r of e){if(r.layout!=="recursive"){let s;try{s=await md(r.path,{withFileTypes:!0})}catch{continue}for(let i of s.slice(0,t)){if(!i.isDirectory()&&!i.isSymbolicLink())continue;let c=me(r.path,i.name),l=r.layout==="app-bundles"?me(c,"Contents","Resources","product-info.json"):me(c,"product-info.json");await x(l)&&n.push(l)}continue}let o=0,a=async(s,i)=>{if(i<0||o>=t)return;let c=me(s,"product-info.json"),l=me(s,"Contents","Resources","product-info.json");if(await x(c)){n.push(c);return}if(await x(l)){n.push(l);return}let d;try{d=await md(s,{withFileTypes:!0})}catch{return}for(let u of d){if(o>=t)return;o+=1;let p=me(s,u.name);(u.isDirectory()||u.isSymbolicLink())&&!["bin","jbr","lib","plugins","Contents"].includes(u.name)&&await a(p,i-1)}};await a(r.path,7)}return[...new Set(n)]},CF=e=>{let t=qv(e);return t.endsWith(`${me("Contents","Resources")}`)?qv(t):t},kF=async e=>{try{let t=JSON.parse(await zm(e,"utf8"));if(!t||typeof t!="object"||typeof t.version!="string"||typeof t.dataDirectoryName!="string")return;let n=t;return!Js(n.version)||!/^[A-Za-z0-9._-]+$/.test(n.dataDirectoryName)?void 0:{version:n.version,dataDirectoryName:n.dataDirectoryName,root:CF(e)}}catch{return}},fd=async(e,t,n)=>{let r=Buffer.alloc(t),{bytesRead:o}=await e.read(r,0,t,n);return o===t?r:void 0},vF=async(e,t)=>{let n;try{n=await pF(e,"r");let{size:r}=await n.stat();if(r<Jm||r>mF)return;let o=Math.min(r,yF),a=await fd(n,o,r-o);if(!a)return;let s=-1;for(let u=a.length-Jm;u>=0;u-=1)if(a.readUInt32LE(u)===101010256){s=u;break}if(s<0)return;let i=a.readUInt32LE(s+12),c=a.readUInt32LE(s+16);if(i>hF||c+i>r)return;let l=await fd(n,i,c);if(!l)return;let d=0;for(;d+46<=l.length;){if(l.readUInt32LE(d)!==33639248)return;let u=l.readUInt16LE(d+10),p=l.readUInt32LE(d+20),m=l.readUInt32LE(d+24),f=l.readUInt16LE(d+28),h=l.readUInt16LE(d+30),w=l.readUInt16LE(d+32),y=l.readUInt32LE(d+42),g=d+46+f+h+w;if(g>l.length)return;let b=l.subarray(d+46,d+46+f).toString("utf8");if(d=g,b!==t)continue;if(p===4294967295||m===4294967295||p>Ym||m>Ym)return;let k=await fd(n,30,y);if(!k||k.readUInt32LE(0)!==67324752)return;let C=k.readUInt16LE(26),S=k.readUInt16LE(28),E=await fd(n,p,y+30+C+S);return E?u===0?E.toString("utf8"):u===8?uF(E,{maxOutputLength:Ym}).toString("utf8"):void 0:void 0}return}catch{return}finally{await n?.close().catch(()=>{})}},Qv=e=>{let t=e.match(/<id>\s*([^<]+?)\s*<\/id>/)?.[1]?.trim(),n=e.match(/<version>\s*([^<]+?)\s*<\/version>/)?.[1]?.trim();if(!(!t||!n||!Js(n)))return{id:t,version:n}},SF=async(e,t)=>{let n=me(e,"META-INF","plugin.xml");if(await x(n))try{let o=Qv(await zm(n,"utf8"));return{present:o?.id===hi||t,descriptor:o?.id===hi?o:void 0}}catch{return{present:t}}let r=[];try{r=(await md(me(e,"lib"),{withFileTypes:!0})).filter(o=>o.isFile()&&o.name.endsWith(".jar")&&/(?:^|[-_.])(ml-?llm|llm|aia|ai[-_.]?assistant)(?:[-_.]|$)/i.test(o.name)).slice(0,32).map(o=>me(e,"lib",o.name))}catch{return{present:!1}}for(let o of r){let a=await vF(o,"META-INF/plugin.xml"),s=a?Qv(a):void 0;if(s?.id===hi)return{present:!0,descriptor:s}}return{present:t&&r.length>0}},eS=async e=>{let t;try{t=await md(e,{withFileTypes:!0})}catch{return{present:!1}}let n=t.filter(o=>o.isDirectory()||o.isSymbolicLink()).sort((o,a)=>{let s=Zm.has(o.name.toLowerCase()),i=Zm.has(a.name.toLowerCase());return Number(i)-Number(s)}).slice(0,512),r=!1;for(let o of n){let a=Zm.has(o.name.toLowerCase());if(!a){let i=me(e,o.name,"META-INF","plugin.xml");if(!await x(i))continue}let s=await SF(me(e,o.name),a);if(s.descriptor)return s;s.present&&(r=!0)}return{present:r}},EF=async e=>{try{return(await zm(me(e,"disabled_plugins.txt"),"utf8")).split(/\r?\n/).map(n=>n.trim()).includes(hi)}catch{return!1}},tS=e=>e.reduce((t,n)=>t?(Xm(n,t)??-1)>0?n:t:n,void 0),rS=async(e={})=>{let t=e.configRoot??Ne("JetBrains"),n=e.userPluginsRoot??wF(),r=await AF(e.productRoots?e.productRoots.map(f=>({path:f,layout:"recursive"})):gF(),e.scanBudget),o=(await Promise.all(r.map(f=>kF(f)))).filter(f=>f!==void 0),a=o.length>0||await x(t);if(e.wsl??bF())return{installed:a,capable:!1,detail:"JetBrains AI Assistant does not support ACP in WSL; no ACP config was written."};let s=o.filter(f=>(Xm(f.version,pd)??-1)>=0),i=[],c=!1,l=!1,d=!1;for(let f of s){let h=me(t,f.dataDirectoryName);if(!await x(h)){d=!0;continue}let w=[me(h,"plugins"),me(n,f.dataDirectoryName),me(n,f.dataDirectoryName,"plugins")],y;for(let g of[...new Set(w)]){let b=await eS(g);if(b.present){y=b;break}}if(y??=await eS(me(f.root,"plugins")),y.present&&!y.descriptor){l=!0;continue}if(!(!y.descriptor||y.descriptor.id!==hi)){if(i.push(y.descriptor.version),await EF(h)){c=!0;continue}if(!((Xm(y.descriptor.version,ka)??-1)<0))return{installed:!0,capable:!0,detail:`JetBrains IDE ${f.version}; AI Assistant ${y.descriptor.version}; ACP supported`,ideVersion:f.version,pluginVersion:y.descriptor.version}}}let u=tS(o.map(f=>f.version)),p=tS(i),m;return a?u?s.length===0?m=`JetBrains IDE ${u} is below the ACP minimum ${pd}; no ACP config was written.`:d?m=`Could not prove that JetBrains AI Assistant is enabled for this user; start IDE ${pd}+ once, enable AI Assistant ${ka}+, then run Connect again. No ACP config was written.`:c?m=`JetBrains AI Assistant is disabled; enable version ${ka}+ and run Connect again. No ACP config was written.`:p?m=`JetBrains AI Assistant ${p} is below the ACP minimum ${ka}; no ACP config was written.`:l?m=`Could not verify the local JetBrains AI Assistant version; require ${ka}+ before running Connect. No ACP config was written.`:m=`JetBrains AI Assistant ${ka}+ was not found; install or enable it, then run Connect again. No ACP config was written.`:m=`Could not prove JetBrains IDE ${pd}+ from local product-info.json; no ACP config was written.`:m="JetBrains IDE config or installation not found",{installed:a,capable:!1,detail:m,ideVersion:u,pluginVersion:p}};var RF=[Gn,Vn],Qm=()=>xF(IF(),".jetbrains","acp.json"),go=()=>`${Qm()}.anyray-state`,OF=(e,t,n="npx")=>{let r=yo(e.agent_servers)?{...e.agent_servers}:{};return Object.assign(r,mi(n,"jetbrains")),{...e,agent_servers:r}},TF=(e,t,n)=>{if(!yo(e.agent_servers))return{next:e,removed:[],conflicts:[]};let r={...e.agent_servers},o=yo(t.agent_servers)?t.agent_servers:{},a=[],s=[];for(let c of RF)if(c in r){if(!ud(r[c],n[c])){s.push(c);continue}c in o?r[c]=o[c]:delete r[c],a.push(c)}let i={...e};return Object.keys(r).length>0?i.agent_servers=r:delete i.agent_servers,{next:i,removed:a,conflicts:s}},_F=(e=rS)=>({id:"jetbrains",title:"JetBrains AI Assistant",automatic:!0,async detect(){let t=await e();return{installed:t.installed,detail:t.detail}},async apply(t,n){let r=Qm(),o=await e();if(!o.capable)return{status:o.installed?"manual":"not-found",messages:[o.detail]};let a=ld();if(!a)return{status:"manual",messages:["JetBrains ACP requires Node.js with npm/npx. Install that prerequisite, then run Connect again; no ACP config was written."]};let s=[`${r} \u2190 documented JetBrains ACP custom-agent configuration`,`${o.detail}.`,"Registered Claude and Codex ACP agents with Anyray routing; no IDE proxy, certificate, DNS, or private Copilot endpoint is changed.","Claude keeps Anthropic subscription auth when selected; Codex keeps ChatGPT subscription auth when selected. Org/API mode uses the enrolled personal gateway key.","The agents appear in AI Chat after the IDE reloads. Their first launch may ask for the provider sign-in if that seat is not already authenticated.","JetBrains Copilot remains a separate closed client; its content-free usage is covered by the Copilot usage connector, not endpoint interception."];if(n.dryRun)return{status:"configured",messages:s};let i=await x(r),c;try{c=await M(r)}catch{return{status:"manual",messages:[`Refused to overwrite malformed ${r}; fix or replace the file, then run Connect again.`]}}let l=mi(a,"jetbrains");return await tc({configPath:r,current:c,next:OF(c,t,a),journalPath:go(),journal:{version:2,fileExisted:i,entries:l},fileExisted:i}),{status:"configured",messages:s,changedFiles:[r,go()]}},async revert(t){let n=Qm(),r=async()=>{if(!await x(n))return t.dryRun||(await ie(n),await hd(go(),{force:!0}).catch(()=>{})),{status:"reverted",messages:["No JetBrains ACP config to remove."]};let o;try{o=await M(n)}catch{return t.dryRun||(await ie(n),await hd(go(),{force:!0}).catch(()=>{})),{status:"manual",messages:[`Could not parse ${n}; remove the two \u201CAnyray \xB7 \u2026\u201D agent entries manually.`]}}let a={},s=!1,i=!1;try{let u=await M(go());(u.version===1||u.version===2)&&yo(u.entries)&&(a=u.entries,s=u.version===2&&u.fileExisted===!1,i=u.version===2&&u.fileExisted===!0)}catch{}let c;if(i){let u=`${n}.anyray-bak`;if(!await x(u))return{status:"manual",messages:[`Refused to remove JetBrains ACP entries because the original backup for ${n} is missing. Restore or remove the entries manually.`]};try{c=await M(u)}catch{return{status:"manual",messages:[`Refused to remove JetBrains ACP entries because the original backup for ${n} is malformed. Repair it or remove the entries manually.`]}}}else c=await Mr(n);let l=TF(o,c,a),d=[];return l.removed.length&&d.push(`Removed ${l.removed.join(", ")} from ${n}.`),l.conflicts.length&&d.push(`Preserved user-modified ACP entries: ${l.conflicts.join(", ")}.`),!t.dryRun&&l.removed.length&&(s&&Object.keys(l.next).length===0?await hd(n,{force:!0}):await J(n,l.next,{backup:!1})),t.dryRun||(await ie(n),await hd(go(),{force:!0}).catch(()=>{})),{status:l.conflicts.length?"manual":"reverted",messages:d.length?d:["No Anyray ACP entries found."],changedFiles:!t.dryRun&&l.removed.length?[n]:void 0}};return t.dryRun?r():ec(n,go(),r)}}),oS=_F();import{homedir as gd}from"node:os";import{join as wd}from"node:path";import{rm as eh}from"node:fs/promises";var th="1.0.0",bd=["anyray-claude-acp","anyray-codex-acp"],PF=["darwin-aarch64","darwin-x86_64","linux-aarch64","linux-x86_64","windows-aarch64","windows-x86_64"],nh=()=>wd(gd(),".windsurf","acp","registry.json"),rh=()=>wd(gd(),".windsurf-next","acp","registry.json"),va=e=>`${e}.anyray-state`,aS=e=>({binary:Object.fromEntries(PF.map(t=>[t,{archive:"",cmd:e.command,args:e.args}]))}),iS=(e="npx")=>{let t=mi(e,"windsurf");return[{id:bd[0],name:Gn,version:"1.0.0",description:"Claude through the Anyray gateway via ACP",authors:["Anyray","Agent Client Protocol"],license:"Apache-2.0",distribution:aS(t[Gn])},{id:bd[1],name:Vn,version:"1.0.0",description:"Codex through the Anyray gateway via ACP",authors:["Anyray","Agent Client Protocol"],license:"Apache-2.0",distribution:aS(t[Vn])}]},yd=e=>!Array.isArray(e)||e.some(t=>!yo(t)||typeof t.id!="string")?null:e,DF=(e,t="npx")=>{if(e.version!==void 0&&e.version!==th||e.extensions!==void 0&&!Array.isArray(e.extensions))return null;let n=e.agents===void 0?[]:yd(e.agents);if(!n)return null;let r=new Set(bd);return{...e,version:typeof e.version=="string"?e.version:th,agents:[...n.filter(o=>!r.has(o.id)),...iS(t)],extensions:e.extensions??[]}},LF=(e,t,n)=>{let r=yd(e.agents);if(!r)return null;let o=yd(t.agents)??[],a=new Map((yd(n)??[]).map(u=>[u.id,u])),s=new Map(o.map(u=>[u.id,u])),i=[],c=[],l=[];for(let u of r){if(!bd.includes(u.id)){l.push(u);continue}if(!ud(u,a.get(u.id))){c.push(u.id),l.push(u);continue}let p=s.get(u.id);p&&l.push(p),i.push(u.id)}let d={...e,agents:l};return!Object.prototype.hasOwnProperty.call(t,"agents")&&l.length===0&&delete d.agents,!Object.prototype.hasOwnProperty.call(t,"version")&&d.version===th&&delete d.version,!Object.prototype.hasOwnProperty.call(t,"extensions")&&Array.isArray(d.extensions)&&d.extensions.length===0&&delete d.extensions,{next:d,removed:i,conflicts:c}},sS=async()=>{let e=[];return(await x(rh())||await x(wd(gd(),".windsurf-next")))&&e.push(rh()),(await x(nh())||await x(wd(gd(),".windsurf"))||await x(Ne("Devin"))||await x(Ne("Windsurf")))&&e.push(nh()),e},cS={id:"windsurf",title:"Devin Desktop",automatic:!0,async detect(){let e=await sS();return e.length?{installed:!0,detail:e.join(", ")}:{installed:!1,detail:"Devin Desktop not found"}},async apply(e,t){let n=await sS();if(!n.length)return{status:"not-found",messages:["Devin Desktop is not installed; no ACP registry was written."]};let r=ld();if(!r)return{status:"manual",messages:["Devin ACP requires Node.js with npm/npx. Install that prerequisite, then run Connect again; no ACP registry was written."]};let o=[],a=[];for(let s of n){let i;try{i=await M(s)}catch{o.push(`Refused to overwrite malformed ${s}; fix or replace the file, then run Connect again.`);continue}let c=DF(i,r);if(!c){o.push(`Refused unrecognized ACP registry shape in ${s}.`);continue}if(o.push(`${s} \u2190 registered Anyray Claude and Codex ACP agents.`),!t.dryRun){let l=await x(s),d=iS(r);await tc({configPath:s,current:i,next:c,journalPath:va(s),journal:{version:2,fileExisted:l,agents:d},fileExisted:l}),a.push(s,va(s))}}return o.push("Devin requires a one-time vendor UI enablement for local registry agents: Devin Settings \u2192 Agents \u2192 enable the two Anyray agents, then restart Devin Desktop."),o.push("Native Devin/Cascade subscription requests are not redirected. The official enterprise consumption connector imports content-free usage instead."),o.push("No proxy, certificate, DNS, DEVIN_API_URL, or private first-party endpoint was changed."),{status:"manual",messages:o,changedFiles:a.length?a:void 0}},async revert(e){let t=[nh(),rh()],n=[],r=[],o=!1;for(let a of t){let s=async()=>{if(!await x(a)){e.dryRun||(await ie(a),await eh(va(a),{force:!0}).catch(()=>{}));return}let i;try{i=await M(a)}catch{n.push(`Could not parse ${a}; remove the anyray-* ACP agents manually.`),o=!0;return}let c=[],l=!1,d=!1;try{let m=await M(va(a));(m.version===1||m.version===2)&&Array.isArray(m.agents)&&(c=m.agents,l=m.version===2&&m.fileExisted===!1,d=m.version===2&&m.fileExisted===!0)}catch{}let u;if(d){let m=`${a}.anyray-bak`;if(!await x(m)){n.push(`Refused to remove Devin ACP agents because the original backup for ${a} is missing. Restore it or remove the agents manually.`),o=!0;return}try{u=await M(m)}catch{n.push(`Refused to remove Devin ACP agents because the original backup for ${a} is malformed. Repair it or remove the agents manually.`),o=!0;return}}else u=await Mr(a);let p=LF(i,u,c);if(!p){n.push(`Unrecognized ACP registry shape in ${a}; left it unchanged.`),o=!0;return}p.removed.length&&(n.push(`Removed ${p.removed.join(", ")} from ${a}.`),e.dryRun||(l&&Object.keys(p.next).length===0?await eh(a,{force:!0}):await J(a,p.next,{backup:!1}),r.push(a))),p.conflicts.length?(n.push(`Preserved user-modified agents: ${p.conflicts.join(", ")}.`),o=!0):e.dryRun||(await ie(a),await eh(va(a),{force:!0}).catch(()=>{}))};e.dryRun?await s():await ec(a,va(a),s)}return{status:o?"manual":"reverted",messages:n.length?n:["No Anyray Devin ACP agents found."],changedFiles:r.length?r:void 0}}};var pe=[rr,eb,Ps,nC,OC,UC,YC,oS,Vv,cS,cb],mt=e=>pe.find(t=>t.id===e);var Ue=async(e=P,t=yn)=>{let n=await e();if(!n.gateway||!n.clientKey)return;let r=await t().catch(()=>{});return{target:Ee({origin:n.gateway,clientKey:n.clientKey,subscription:n.authMode==="subscription",placeholder:n.authMode==="placeholder",byoUpstream:n.byoUpstream,seat:r,user:n.name,team:n.team})}};var oh=5e3,lS=3e4,NF=1440*60*1e3,$F=e=>new Promise(t=>setTimeout(t,e)),MF=async(e=P,t=yn)=>(await Ue(e,t))?.target,BF=e=>mt(e)?.quitGated,dS=async(e,t={})=>{let n=e[0];if(!n)return 0;let r=t.resolveSeam??BF,o=t.readPending??Yc,a=t.clearPending??Gp,s=t.targetFromProfile??MF,i=t.sleep??$F,c=t.now??Date.now,l=t.maxWaitMs??NF;try{let d=r(n);if(!d?.complete)return await a(n),0;let u=d.complete.bind(d),p=c(),m=oh;for(;;){let f=await o(n);if(!f||c()-p>l)return 0;if(d.isRunning()){await i(m),m=Math.min(lS,m*2);continue}let h;if(d.needsTarget?.(f.op)&&(h=await s(),!h)){if(await a(n,f)!=="superseded")return 0;await i(m),m=oh;continue}if((await u(f.op,h,{dryRun:!1,preservePendingOp:!0})).status==="queued"){await i(m),m=Math.min(lS,m*2);continue}if(await a(n,f)!=="superseded")return 0;await i(m),m=oh}}catch{return 0}};import{writeFileSync as IW}from"node:fs";import{chmod as yh,stat as xW}from"node:fs/promises";import{platform as US}from"node:os";import{dirname as HS,isAbsolute as RW}from"node:path";var FF="https://app.anyray.ai",WF=new Set(["localhost","::1","[::1]"]),UF=/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/,HF=e=>WF.has(e)||UF.test(e),ah=e=>{let t;try{t=new URL(e)}catch{return!1}return t.protocol==="https:"?!0:t.protocol==="http:"&&HF(t.hostname)},GF=e=>{let t=e.length;for(;t>0&&e[t-1]==="/";)t-=1;return e.slice(0,t)},Kn=()=>{let e=process.env.ANYRAY_CP_ORIGIN?.trim();return!e||!ah(e)?FF:GF(e)};import{createHash as nW,generateKeyPairSync as rW,randomBytes as ch}from"node:crypto";import{createPrivateKey as VF,sign as KF}from"node:crypto";var Ir=async(e,t)=>{let n=VF(t);return KF(null,new TextEncoder().encode(e),n).toString("base64url")};var jF=["HTTPS_PROXY","https_proxy"],uS=new Set(["SELF_SIGNED_CERT_IN_CHAIN","DEPTH_ZERO_SELF_SIGNED_CERT","UNABLE_TO_VERIFY_LEAF_SIGNATURE","UNABLE_TO_GET_ISSUER_CERT","UNABLE_TO_GET_ISSUER_CERT_LOCALLY","CERT_UNTRUSTED"]),pS=new Set(["CERT_HAS_EXPIRED","CERT_NOT_YET_VALID","ERR_TLS_CERT_ALTNAME_INVALID","ERR_SSL_WRONG_VERSION_NUMBER","EPROTO"]),fS=new Set(["ENOTFOUND","EAI_AGAIN"]),mS=new Set(["ECONNREFUSED","ECONNRESET","EPIPE","ENETDOWN","ENETUNREACH","EHOSTUNREACH","EHOSTDOWN"]),hS=new Set(["ETIMEDOUT","UND_ERR_CONNECT_TIMEOUT","UND_ERR_HEADERS_TIMEOUT","UND_ERR_BODY_TIMEOUT"]),ZF=e=>{let t=e;for(let n=0;n<5&&t;n++){let r=t.code;if(typeof r=="string"&&r)return r;t=t.cause}return YF(e)},YF=e=>{let t=e?.message;if(!(typeof t!="string"||!t)){for(let n of[...uS,...pS,...fS,...mS,...hS])if(t.includes(n))return n}},JF=e=>e?.name==="AbortError"||e?.name==="TimeoutError",XF=e=>jF.filter(t=>(e[t]??"").trim()!==""),zF=(e,t=process.env)=>{let n=ZF(e),r=XF(t);return{kind:n&&uS.has(n)?"tls-unknown-issuer":n&&pS.has(n)?"tls-invalid-cert":n&&fS.has(n)?"dns":JF(e)||n&&hS.has(n)?"timeout":n&&mS.has(n)?"refused":"unknown",...n?{code:n}:{},proxyVars:r}},qF=e=>{let t=e.proxyVars.length>0?` ${e.proxyVars.join(" and ")} ${e.proxyVars.length>1?"are":"is"} set \u2014 if that proxy is stale or unreachable, unset it and re-run.`:"";switch(e.kind){case"tls-unknown-issuer":return` (TLS certificate signed by an unknown authority: ${e.code}). Your network appears to inspect TLS traffic. curl trusts your system keychain and this binary does not, which is why the download worked and this step did not. Point NODE_EXTRA_CA_CERTS at your organization root certificate (PEM) and re-run.`+t;case"tls-invalid-cert":return` (TLS certificate rejected: ${e.code}). Check this machine's clock and date, and whether a proxy is rewriting HTTPS traffic, then re-run.`+t;case"dns":return` (DNS lookup failed: ${e.code}). Check your VPN or DNS, then re-run.`+t;case"refused":return` (connection failed: ${e.code}).`+(t||" Check your network or firewall, then re-run.");case"timeout":return" (timed out before the control plane answered)."+(t||" Check your connection and re-run.");default:return e.code?` (${e.code}).${t}`:t}},ht=(e,t=process.env)=>qF(zF(e,t));var QF="enl_",yS="enp_",gS=e=>e.startsWith(QF)||e.startsWith(yS),sh=e=>e.startsWith(yS),eW=[{prefix:"tnt_",flag:"--sso",what:"an SSO link"},{prefix:"sdc_",flag:"--claim",what:"a one-time enrollment code"}],ih=e=>eW.find(t=>e.startsWith(t.prefix)),wS=/^\/enroll\/([^/]+)\/?$/,bS=/^\/i\/([^/]+)\/?$/,AS=e=>{let t=e.match(wS);if(t)return ih(t[1])?void 0:t[1];let n=e.match(bS);return n&&gS(n[1])?n[1]:void 0},tW=1e4,Ad=e=>{let t=e.trim();if(!t)return;let n;try{n=new URL(t)}catch{n=void 0}if(n){if(n.protocol!=="http:"&&n.protocol!=="https:")return;let r=AS(n.pathname);return r?{cpOrigin:n.origin,token:r}:void 0}if(!ih(t))return{cpOrigin:Kn(),token:t}},CS=e=>{let t=e.trim();if(!t)return;let n=t;try{let o=new URL(t),a=o.pathname.match(wS)??o.pathname.match(bS);if(!a)return;n=a[1]}catch{}let r=ih(n);return r?{flag:r.flag,what:r.what}:void 0},gi=e=>{let t=e.trim();if(!t)return!1;try{let n=new URL(t);return n.protocol!=="http:"&&n.protocol!=="https:"?!1:AS(n.pathname)!==void 0}catch{return gS(t)}},Sa=class extends Error{constructor(t){super(t),this.name="EnrollmentPermanentError"}},yi=e=>typeof e=="string"&&e.trim()?e.trim():void 0,kS=async(e,t={})=>{let n=t.timeoutMs??tW,r=`${e.cpOrigin}/enroll-info/${e.token}`,o=new AbortController,a=setTimeout(()=>o.abort(),n),s;try{s=await fetch(r,{method:"GET",signal:o.signal})}catch(u){let p=u instanceof Error&&u.name==="AbortError"?` no response within ${n}ms.`:ht(u);throw new Error(`could not reach the enrollment page at ${e.cpOrigin}.${p}`)}finally{clearTimeout(a)}if(!s.ok){let u=`enrollment link lookup failed: ${e.cpOrigin} responded ${s.status} \u2014 the link may be expired or revoked; ask your admin for a fresh one.`;throw s.status>=400&&s.status<500&&s.status!==429?new Sa(u):new Error(u)}let i;try{i=await s.json()}catch{throw new Error(`enrollment link lookup failed: ${e.cpOrigin} returned a malformed response`)}let l=(Array.isArray(i?.gateways)?i.gateways:[]).find(u=>u!==null&&typeof u=="object"&&yi(u.url)!==void 0),d=yi(l?.url);if(!d)throw new Error(i.connected===!0?"this enrollment link's gateway is running but hasn't advertised its public URL yet \u2014 ask your admin to set ANYRAY_GATEWAY_PUBLIC_URL (Helm: gateway.publicUrl), then re-run.":"this enrollment link has no gateway configured yet \u2014 ask your admin to confirm the gateway is deployed, then re-run.");return{gatewayUrl:d,deploymentId:yi(l?.deploymentId),org:yi(i.org),email:yi(i.email),seatMode:i.seatMode===!0,...i.provisioningKind==="manual"||i.provisioningKind==="mdm"?{provisioningKind:i.provisioningKind}:{},...i.provisioningProofMode==="managed-preference"?{provisioningProofMode:i.provisioningProofMode}:{},...Array.isArray(i.allowedDomains)?{allowedDomains:i.allowedDomains.filter(u=>typeof u=="string"&&u.length>0)}:{}}};var ke="0.11.185";var lh=1e4,wo=e=>e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(wo).join(",")}]`:`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${wo(e[n])}`).join(",")}}`,vS="stable-key-heartbeat-v1",SS="key-heartbeat",oW=["reapply_config","remint","revert"],dh=(e,t)=>t&&e.payload.source==="mdm"?{machineUuid:t}:{};var ES=e=>nW("sha256").update(e).digest("hex"),je=e=>typeof e=="string"&&e.trim()?e.trim():void 0,aW=e=>Array.isArray(e)?e.filter(t=>typeof t=="string"&&/^[a-z0-9-]{1,64}$/.test(t)):[],IS={no_mdm_server_registered:"no MDM server is registered in the Anyray console",agent_missing:"the Anyray endpoint agent is not reporting for this machine",mdm_not_verified:"this machine is not enrolled in the registered MDM",endpoint_unreachable:"the endpoint service could not be reached"},sW=e=>`This organization requires a managed (MDM-enrolled) device for this enrollment: ${IS[e]}. Ask your IT admin.`,iW=e=>typeof e=="string"&&e in IS,uh=async e=>{try{let t=await e.json(),n=je(t?.message),r=je(t?.error),o=iW(t?.reason)?t.reason:void 0;if(r==="managed_device_required"&&o)return{message:sW(o),code:r,reason:o};if(n)return{message:n,...r?{code:r}:{}}}catch{}return{message:`gateway responded ${e.status}`}},cW=async e=>(await uh(e)).message,lt=class extends Error{status;policyCode;reason;constructor(t,n){let r=typeof n=="string"?{message:n}:n;super(r.code==="managed_device_required"?r.message:`the gateway rejected this enrollment (HTTP ${t}): ${r.message}`),this.name="GatewayVerifyError",this.status=t,this.policyCode=r.code,this.reason=r.reason}},xS=e=>e instanceof Sa||e instanceof lt&&e.policyCode==="sso_required",Ea=class extends Error{status;policyCode;reason;constructor(t,n){let r=typeof n=="string"?{message:n}:n;super(r.code==="managed_device_required"?r.message:`the gateway rejected this credential heartbeat (HTTP ${t}): ${r.message}`),this.name="GatewayHeartbeatError",this.status=t,this.policyCode=r.code,this.reason=r.reason}},ph=async(e,t,n,r)=>{try{return await r(wo(e),t)}catch{throw new Error(`developer ${n} failed: could not sign the challenge with the provided private key`)}},Cd=()=>{let{publicKey:e,privateKey:t}=rW("ed25519",{publicKeyEncoding:{type:"spki",format:"pem"},privateKeyEncoding:{type:"pkcs8",format:"pem"}});return{publicKeyPem:e,privateKeyPem:t}},Qt=async(e,t,n,r={})=>{let o=r.timeoutMs??lh,a=`${e}/connect/verify`,s=je(t?.payload?.deploymentId);if(!s)throw new Error("developer verification failed: the cert is missing payload.deploymentId");let i={deploymentId:s,issuedAt:new Date().toISOString(),nonce:ch(16).toString("hex"),...dh(t,r.machineUuid)},c=await ph(i,n,"verification",r.signer??Ir),l=new AbortController,d=setTimeout(()=>l.abort(),o),u;try{u=await fetch(a,{method:"POST",headers:{"content-type":"application/json","x-anyray-connect-version":ke},body:JSON.stringify({cert:t,challenge:i,sig:c,...r.health?{health:r.health}:{},...r.ack?{ack:r.ack}:{},...r.telemetryOnly?{telemetryOnly:!0}:{}}),signal:l.signal})}catch(g){let b=g instanceof Error&&g.name==="AbortError"?` no response within ${o}ms.`:ht(g);throw new Error(`could not reach the gateway at ${a}.${b}`,{cause:g})}finally{clearTimeout(d)}if(!u.ok)throw new lt(u.status,await uh(u));let p;try{p=await u.text()}catch{p=""}let m;try{m=JSON.parse(p)}catch{let g=u.headers.get("content-type")??"",b=/\btext\/html\b/i.test(g)||/^\s*<(?:!doctype|html)/i.test(p);throw new Error(b?`developer verification failed: ${a} returned an HTML page, not the gateway \u2014 /connect/* is being routed to the console/proxy. Ask your admin to route /connect/* to the gateway service (:8787), the same as /v1/*.`:"developer verification failed: the gateway returned a malformed response")}let f=je(m?.key);if(!f)throw new Error("developer verification failed: the gateway response is missing the key");if(!/^[A-Za-z0-9._-]{1,256}$/.test(f))throw new Error("developer verification failed: the gateway returned a malformed key");let h=je(m.user);if(!h)throw new Error("developer verification failed: the gateway response is missing the user");let w=lW(m.directive),y=aW(m.capabilities);return{key:f,user:h,team:je(m.team),expiresAt:je(m.expiresAt),...y.length>0?{capabilities:y}:{},...w?{directive:w}:{}}},RS=async(e,t,n,r,o={})=>{let a=o.timeoutMs??lh,s=`${e}/connect/key/heartbeat`,i=je(n?.payload?.deploymentId);if(!i)throw new Error("developer heartbeat failed: the cert is missing payload.deploymentId");let c={deploymentId:i,issuedAt:new Date().toISOString(),nonce:ch(16).toString("hex"),purpose:SS,...dh(n,o.machineUuid)},l=await ph(c,r,"heartbeat",o.signer??Ir),d=new AbortController,u=setTimeout(()=>d.abort(),a),p;try{p=await fetch(s,{method:"POST",headers:{"content-type":"application/json","x-anyray-api-key":t,"x-anyray-connect-version":ke},body:JSON.stringify({cert:n,challenge:c,sig:l}),signal:d.signal})}catch(h){let w=h instanceof Error&&h.name==="AbortError"?` no response within ${a}ms.`:ht(h);throw new Error(`could not reach the gateway at ${s}.${w}`,{cause:h})}finally{clearTimeout(u)}if(!p.ok)throw new Ea(p.status,await uh(p));let m;try{m=await p.json()}catch{throw new Error("developer heartbeat failed: the gateway returned a malformed response")}let f=je(m.expiresAt);if(!f||!Number.isFinite(Date.parse(f))||m.credentialMode!==vS||m.key!==void 0)throw new Error("developer heartbeat failed: the gateway returned an unexpected response");return{expiresAt:f,credentialMode:vS}},OS=async(e,t,n,r,o,a={})=>{let s=a.timeoutMs??lh,i=`${e.replace(/\/$/,"")}/connect/machine`,c=je(n?.payload?.deploymentId);if(!c||!o)return!1;let l={deploymentId:c,issuedAt:new Date().toISOString(),nonce:ch(16).toString("hex"),purpose:SS,...dh(n,o)},d=await ph(l,r,"heartbeat",a.signer??Ir),u=new AbortController,p=setTimeout(()=>u.abort(),s);try{return(await fetch(i,{method:"POST",headers:{"content-type":"application/json","x-anyray-api-key":t,"x-anyray-connect-version":ke},body:JSON.stringify({cert:n,challenge:l,sig:d,machineUuid:o}),signal:u.signal})).ok}catch(m){return console.error("connect machine report skipped:",m instanceof Error?m.name:"error"),!1}finally{clearTimeout(p)}},lW=e=>{if(e===null||typeof e!="object")return null;let t=e,n=je(t.id),r=t.kind;return!n||!/^[A-Za-z0-9_-]{1,128}$/.test(n)||typeof r!="string"||!oW.includes(r)?null:{id:n,kind:r}},dW=1e4,uW=e=>{if(e===null||typeof e!="object")return!1;let t=e;if(t.alg!=="Ed25519"||!je(t.sig))return!1;let n=t.payload;if(n===null||typeof n!="object")return!1;let r=n;return typeof r.v=="number"&&!!je(r.deploymentId)&&!!je(r.user)&&!!je(r.devPublicKey)&&!!je(r.issuedAt)&&!!je(r.expiresAt)},pW=async(e,t,n,r={},o={})=>{let a=o.timeoutMs??dW,s=`${e}/v1/enroll`,i=new AbortController,c=setTimeout(()=>i.abort(),a),l;try{l=await fetch(s,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({token:t,devPublicKey:n,...r.email?{email:r.email}:{},...r.team?{team:r.team}:{},...r.machineId?{machineId:r.machineId}:{},...r.deploymentId?{deploymentId:r.deploymentId}:{}}),signal:i.signal})}catch(u){let p=u instanceof Error&&u.name==="AbortError"?` no response within ${a}ms.`:ht(u);throw new Error(`could not reach the control plane at ${s}.${p}`)}finally{clearTimeout(c)}if(!l.ok){let u=`enrollment failed: ${await cW(l)}`;throw l.status>=400&&l.status<500&&l.status!==429?new Sa(u):new Error(u)}let d;try{d=await l.json()}catch{throw new Error("enrollment failed: the control plane returned a malformed response")}if(!uW(d))throw new Error("enrollment failed: the control plane returned an unexpected cert shape");return d},TS=(e,t,n,r,o,a,s)=>{if(!e)return!1;let i=t?Date.parse(t):NaN;return!(!Number.isFinite(i)||i<=r||n&&e.payload.deploymentId!==n||o&&o!==a||s&&e.payload.user.trim().toLowerCase()!==s.trim().toLowerCase())},_S=async e=>{let t={timeoutMs:e.timeoutMs,machineUuid:e.machineUuid,signer:e.signer},{cert:n,privateKeyPem:r,publicKeyPem:o}=e.reuse?e.reuse:await(async()=>{let s=Cd();return{cert:await pW(e.cpOrigin,e.token,s.publicKeyPem,{email:e.email,team:e.team,machineId:e.machineId,deploymentId:e.deploymentId},t),...s}})(),a=await Qt(e.gatewayOrigin,n,r,t);return{clientKey:a.key,user:a.user,team:a.team,expiresAt:a.expiresAt,...a.capabilities?{capabilities:a.capabilities}:{},cert:n,privateKeyPem:r,publicKeyPem:o}};var fh=1e4,fW=900*1e3,DS="tnt_",mW=/^\/sso\/([^/]+)\/?$/,hW=/^\/i\/([^/]+)\/?$/,yW=e=>{let t=e.match(mW);if(t)return t[1];let n=e.match(hW);return n?.[1].startsWith(DS)?n[1]:void 0},Et=e=>{let t=e.trim();if(!t)return;let n;try{n=new URL(t)}catch{n=void 0}if(n){if(n.protocol!=="http:"&&n.protocol!=="https:")return;let r=yW(n.pathname);return r?{cpOrigin:n.origin,tenantId:r}:void 0}if(t.startsWith(DS))return{cpOrigin:Kn(),tenantId:t}},bo=class extends Error{kind;status;constructor(t,n,r){super(n),this.name="SsoStartError",this.kind=t,this.status=r}},Bt=class extends Error{kind;constructor(t,n){super(n),this.name="SsoPollError",this.kind=t}},mh=async(e,t,n,r)=>{let o=new AbortController,a=setTimeout(()=>o.abort(),n);try{let s=await r(e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t),signal:o.signal}),i={};try{i=await s.json()}catch{}return{status:s.status,json:i}}finally{clearTimeout(a)}},gW=e=>new Promise(t=>setTimeout(t,e)),kd=async e=>{let t=e.now??Date.now,n=e.fetch??fetch,{publicKeyPem:r,privateKeyPem:o}=(e.generateKeypair??Cd)(),a;try{a=await mh(`${e.cpOrigin}/sso/device`,{tenantId:e.tenantId,devPublicKey:r},fh,n)}catch(f){throw new bo("cp-unreachable",`could not reach the control plane at ${e.cpOrigin}${ht(f)}`)}if(a.status!==200){let f=a.status===404,h=typeof a.json.error=="string"?a.json.error:`status ${a.status}`;throw new bo(f?"sso-unavailable":"cp-unreachable",`SSO is not available for this organization (${h}). Ask your admin to confirm SSO is configured.`,a.status)}let s=a.json;if(!s.device_code||!s.user_code||!s.verification_uri_complete)throw new bo("cp-unreachable","SSO start failed: the control plane returned an incomplete response.");let i=t(),c=e.deadlineMs??fW,l=typeof s.expires_in=="number"&&s.expires_in>0?s.expires_in*1e3:c,d=typeof s.verification_uri=="string"?s.verification_uri:void 0,u=e.gatewayUrl??(typeof s.gateway_url=="string"?s.gateway_url:void 0),p={cpOrigin:e.cpOrigin,tenantId:e.tenantId,deviceCode:s.device_code,userCode:s.user_code,verificationUri:d,verificationUriComplete:s.verification_uri_complete,intervalMs:Math.max(1,s.interval||5)*1e3,grantExpiresAt:i+Math.min(c,l),startedAt:i,privateKeyPem:o,publicKeyPem:r,gatewayUrl:u},m=e.log??(()=>{});return m("To finish, sign in with your organization at:"),m(` ${p.verificationUriComplete}`),m(`Confirm this code matches your browser: ${p.userCode}`),wW(p.verificationUriComplete,e.cpOrigin)&&e.open?.(p.verificationUriComplete),p},wW=(e,t)=>{try{return new URL(e).origin===new URL(t).origin}catch{return!1}},vd=async(e,t={})=>{let n=t.now??Date.now,r=t.sleep??gW,o=t.fetch??fetch,a=t.pollIntervalMs??e.intervalMs;for(;n()<e.grantExpiresAt&&(await r(Math.min(a,e.grantExpiresAt-n())),!(n()>=e.grantExpiresAt));){let s;try{s=await mh(`${e.cpOrigin}/sso/device/token`,{deviceCode:e.deviceCode,devPublicKey:e.publicKeyPem},fh,o)}catch(c){throw new Bt("cp-unreachable",`could not reach the control plane at ${e.cpOrigin}${ht(c)}`)}if(s.status===200&&s.json.cert)return{cert:s.json.cert,privateKeyPem:e.privateKeyPem,gatewayUrl:t.gatewayUrl??(typeof s.json.gatewayUrl=="string"?s.json.gatewayUrl:e.gatewayUrl),deploymentId:typeof s.json.deploymentId=="string"?s.json.deploymentId:""};let i=typeof s.json.error=="string"?s.json.error:"";if(i!=="authorization_pending"){if(i==="slow_down"){a+=5e3;continue}throw i==="expired_token"?new Bt("expired","SSO sign-in timed out before you finished. Re-run anyray-connect --sso to try again."):new Bt("denied","SSO sign-in was not completed. Re-run anyray-connect --sso to try again.")}}throw new Bt("expired","SSO sign-in timed out. Re-run anyray-connect --sso to try again.")};var PS="sdc_",LS=e=>{let t=e.trim();if(!t)return;if(t.startsWith(PS))return{cpOrigin:Kn(),claim:t};let n;try{n=new URL(t)}catch{return}if(!ah(n.origin))return;let r=n.searchParams.get("claim")?.trim();if(!(!r||!r.startsWith(PS)))return{cpOrigin:n.origin,claim:r}},NS=async e=>{let t=e.fetch??fetch,{publicKeyPem:n,privateKeyPem:r}=(e.generateKeypair??Cd)(),o;try{o=await mh(`${e.cpOrigin}/sso/device/token`,{deviceCode:e.claim,devPublicKey:n},fh,t)}catch(s){throw new Bt("cp-unreachable",`could not reach the control plane at ${e.cpOrigin}${ht(s)}`)}if(o.status===200&&o.json.cert)return{cert:o.json.cert,privateKeyPem:r,gatewayUrl:e.gatewayUrl??(typeof o.json.gatewayUrl=="string"?o.json.gatewayUrl:void 0),deploymentId:typeof o.json.deploymentId=="string"?o.json.deploymentId:"",...typeof o.json.ssoLink=="string"&&o.json.ssoLink?{ssoLink:o.json.ssoLink}:{}};let a=typeof o.json.error=="string"?o.json.error:"";throw a==="expired_token"?new Bt("expired","This enrollment link has expired. Open your organization\u2019s Anyray link again to get a new one."):a==="authorization_pending"?new Bt("denied","This enrollment link is not ready yet. Finish signing in in your browser, then run the command it gives you."):new Bt("denied","This enrollment link was already used or is not valid. Open your organization\u2019s Anyray link again to get a new one.")};import{readFile as bW}from"node:fs/promises";import{isAbsolute as AW,posix as $S,win32 as hh}from"node:path";var wi=(e=process.platform,t=process.env)=>e==="darwin"?$S.join("/Library","Application Support","Anyray","bootstrap.json"):e==="win32"?hh.join(t.ProgramData??"C:\\ProgramData","Anyray","bootstrap.json"):$S.join("/etc","anyray","bootstrap.json"),CW=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),MS=e=>typeof e=="string"&&e.length>0&&e.length<=512&&[...e].every(t=>{let n=t.charCodeAt(0);return n>=32&&n!==127})&&(AW(e)||hh.isAbsolute(e))&&!/ark_[A-Za-z0-9_-]{20,}|-----BEGIN/.test(e),kW=e=>{if(typeof e!="string"||e.length===0||e.length>512)return!1;try{let t=new URL(e);return(t.protocol==="https:"||t.protocol==="http:")&&!t.username&&!t.password}catch{return!1}},xr=async(e=wi())=>{try{let t=await bW(e,"utf-8");if(t.length>4096)return;let n=JSON.parse(t);if(!CW(n)||n.v!==1||typeof n.sso!="string")return;let r=Et(n.sso);if(!r)return;let o=kW(n.gateway)?n.gateway:void 0,a=MS(n.bin)?n.bin:void 0;return{sso:`${r.cpOrigin}/sso/${r.tenantId}`,gateway:o,bin:a}}catch{return}},BS=(e,t,n)=>{let r=Et(e);if(!r)throw new Error("invalid --sso link");if(n!==void 0&&!MS(n))throw new Error("--bin must be an absolute fleet-stable path");if(n!==void 0&&hh.isAbsolute(n)&&/^[A-Za-z]:\\/.test(n)&&!/^[A-Za-z]:\\Program Files( \(x86\))?\\/i.test(n))throw new Error("--bin on Windows must live under Program Files (admin-only writable)");return`${JSON.stringify({v:1,sso:`${r.cpOrigin}/sso/${r.tenantId}`,...t?{gateway:t}:{},...n?{bin:n}:{}},null,2)}
|
|
262
|
-
`};var Ia=(e,t)=>t.NO_COLOR?!1:t.FORCE_COLOR&&t.FORCE_COLOR!=="0"?!0:!!e.isTTY,Sd=Ia(process.stdout,process.env),FS=Ia(process.stderr,process.env),xa=(e,t,n)=>n?`\x1B[${e}m${t}\x1B[0m`:t,K=e=>xa("1",e,Sd),v=e=>xa("2",e,Sd),
|
|
263
|
-
${K(e)}`),L=e=>console.log(v(e)),B=e=>console.log(`${
|
|
254
|
+
}`,Hn=async e=>new Promise((t,n)=>{let r=pM("powershell.exe",["-NoLogo","-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command",SM],{windowsHide:!0,stdio:["pipe","pipe","pipe"]}),o="",a=!1,s=!1;r.stdout.setEncoding("utf8"),r.stdout.on("data",i=>{o+=i,o.length>1024*1024&&(a=!0,r.kill())}),r.stderr.resume(),r.on("error",i=>{s||(s=!0,n(new Error(Am(i))))}),r.on("close",(i,c)=>{if(!s){if(s=!0,a){n(new Error("registry query output exceeded the safety limit"));return}if(i===null){n(new Error(Am({signal:c??void 0})));return}t({code:i,stdout:o,missing:i===3})}}),r.stdin.on("error",()=>{}),r.stdin.end(JSON.stringify(e))}),Mt=(e={})=>ga((e.home??Sm)(),".anyray","claude-desktop-windows.json"),EM=e=>ga((e.home??Sm)(),".anyray","claude-desktop-windows.lock"),ma=class extends Error{},IM=e=>{try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}},xm=async e=>{let t=EM(e);await gm(ci(t),{recursive:!0,mode:448});for(let n=0;n<2;n++){let r=Hk("sha256").update(`${process.pid}:${Date.now()}:${Math.random()}`).digest("hex"),o=ga(t,"owner.json");try{await gm(t,{mode:448}),await we(o,`${JSON.stringify({pid:process.pid,nonce:r,createdAt:Date.now()})}
|
|
255
|
+
`)}catch(a){if(a.code!=="EEXIST")throw await Xt(t,{recursive:!0,force:!0}).catch(()=>{}),a;let s=!1;try{let i=JSON.parse(await wm(o,"utf8"));s=typeof i.pid=="number"&&Number.isSafeInteger(i.pid)&&i.pid>0&&!IM(i.pid)}catch{try{s=Date.now()-(await Zk(t)).mtimeMs>3e4}catch{s=!1}}if(!s||n>0)throw new ma;await Xt(t,{recursive:!0,force:!0});continue}return async()=>{try{JSON.parse(await wm(o,"utf8")).nonce===r&&await Xt(t,{recursive:!0,force:!0})}catch{}}}throw new ma},Qk=()=>Object.fromEntries($e.map(e=>[e,{present:!1}])),uo=e=>Hk("sha256").update(e).digest("hex"),xM=(e,t)=>t.present?e===wa?{present:!0,type:t.type,sha256:uo(t.value??"")}:{present:!0,type:t.type,value:t.value??""}:{present:!1},pa=(e,t)=>e.present!==t.present?!1:e.present?e.type!==t.type?!1:t.sha256!==void 0?uo(e.value??"")===t.sha256:e.value===t.value:!0,$t=(e,t)=>Object.keys(e).length===t.length&&t.every(n=>Object.hasOwn(e,n)),jl=(e,t)=>{if(!e||typeof e!="object"||Array.isArray(e))return!1;let n=e;return typeof n.present!="boolean"?!1:n.present?n.type!=="REG_SZ"&&n.type!=="REG_EXPAND_SZ"?!1:t===wa?$t(n,["present","type","sha256"])&&typeof n.sha256=="string"&&/^[a-f0-9]{64}$/.test(n.sha256)&&n.value===void 0:$t(n,["present","type","value"])&&typeof n.value=="string"&&n.sha256===void 0:Object.keys(n).length===1},Pk=e=>!!e&&typeof e=="object"&&!Array.isArray(e)&&$t(e,$e)&&$e.every(t=>jl(e[t],t)),Dk=e=>!!e&&typeof e=="object"&&!Array.isArray(e)&&$t(e,xk)&&xk.every(t=>jl(e[t],t)),RM=e=>typeof e=="string"&&/^[a-f0-9]{64}$/.test(e),Rm=(e,t)=>{if(!e||typeof e!="object"||Array.isArray(e))return!1;let n=e,r=["path",...n.lastWritten===void 0?[]:["lastWritten"],...n.pending===void 0?[]:["pending"]];return $t(n,r)&&n.path===Em(t)&&(n.lastWritten===void 0||_k(n.lastWritten))&&(n.pending===void 0||_k(n.pending))&&(n.lastWritten!==void 0||n.pending!==void 0)},OM=(e,t)=>$t(e,e.pending===void 0?["version","registryKey","keyExisted","lastWritten","helper"]:["version","registryKey","keyExisted","lastWritten","pending","helper"])&&e.version===Kl&&e.registryKey===De&&typeof e.keyExisted=="boolean"&&Pk(e.lastWritten)&&(e.pending===void 0||Pk(e.pending))&&Rm(e.helper,t)&&(e.pending===void 0&&e.helper.pending===void 0||e.pending!==void 0&&e.helper.pending!==void 0),TM=e=>$t(e,e.pending===void 0?["version","registryKey","keyExisted","lastWritten"]:["version","registryKey","keyExisted","lastWritten","pending"])&&e.version===2&&e.registryKey===De&&typeof e.keyExisted=="boolean"&&Dk(e.lastWritten)&&(e.pending===void 0||Dk(e.pending)),Lk=e=>!!e&&typeof e=="object"&&!Array.isArray(e)&&$t(e,Rk)&&Rk.every(t=>jl(e[t],t)),_M=(e,t)=>$t(e,e.pending===void 0?["version","registryKey","keyExisted","lastWritten","helper"]:["version","registryKey","keyExisted","lastWritten","pending","helper"])&&e.version===3&&e.registryKey===De&&typeof e.keyExisted=="boolean"&&Lk(e.lastWritten)&&(e.pending===void 0||Lk(e.pending))&&Rm(e.helper,t)&&(e.pending===void 0&&e.helper.pending===void 0||e.pending!==void 0&&e.helper.pending!==void 0),Nk=e=>!!e&&typeof e=="object"&&!Array.isArray(e)&&$t(e,Ok)&&Ok.every(t=>jl(e[t],t)),PM=(e,t)=>$t(e,e.pending===void 0?["version","registryKey","keyExisted","lastWritten","helper"]:["version","registryKey","keyExisted","lastWritten","pending","helper"])&&e.version===4&&e.registryKey===De&&typeof e.keyExisted=="boolean"&&Nk(e.lastWritten)&&(e.pending===void 0||Nk(e.pending))&&Rm(e.helper,t)&&(e.pending===void 0&&e.helper.pending===void 0||e.pending!==void 0&&e.helper.pending!==void 0),$k=e=>({...e,coworkEgressAllowedHosts:{present:!1}}),Om=e=>{let{pending:t,...n}=e;return{...n,version:Kl,lastWritten:$k(e.lastWritten),...t?{pending:$k(t)}:{}}},Mk=e=>({...e,chatTabEnabled:{present:!1}}),DM=e=>{let{pending:t,...n}=e;return Om({...n,version:4,lastWritten:Mk(e.lastWritten),...t?{pending:Mk(t)}:{}})},Bk=e=>({inferenceProvider:e.inferenceProvider,inferenceGatewayBaseUrl:e.inferenceGatewayBaseUrl,inferenceGatewayAuthScheme:e.inferenceGatewayAuthScheme,inferenceCredentialKind:{present:!1},inferenceCredentialHelper:{present:!1},chatTabEnabled:{present:!1},inferenceGatewayApiKey:e.inferenceGatewayApiKey}),LM=(e,t)=>Om({version:4,registryKey:De,keyExisted:e.keyExisted,lastWritten:Bk(e.lastWritten),...e.pending?{pending:Bk(e.pending)}:{},helper:{path:Em(t)}}),Tm=async(e,t=!0)=>{let n=Mt(e),r=ci(n),o=`${Yk(n)}.anyray-old-`,a=(await Kk(r).catch(()=>[])).filter(l=>l.startsWith(o)).map(l=>ga(r,l)),s=n;if(!await x(n)){if(a.length===0)return;if(a.length!==1)throw new Error("ambiguous Windows ownership journal recovery files");t?await jk(a[0],n):s=a[0]}let i=await M(s),c=TM(i)?LM(i,e):_M(i,e)?DM(i):PM(i,e)?Om(i):OM(i,e)?i:void 0;if(!c)throw new Error("invalid Windows ownership journal");return t&&await Promise.all(a.map(l=>Xt(l,{force:!0}))),c},Fk=e=>({inferenceProvider:e.inferenceProvider,inferenceGatewayBaseUrl:e.inferenceGatewayBaseUrl,inferenceGatewayAuthScheme:e.inferenceGatewayAuthScheme,inferenceGatewayApiKey:e.inferenceGatewayApiKey}),NM=e=>e.helper.lastWritten===void 0&&e.helper.pending===void 0?{version:2,registryKey:De,keyExisted:e.keyExisted,lastWritten:Fk(e.lastWritten),...e.pending?{pending:Fk(e.pending)}:{}}:e,Hl=async(e,t)=>{let n=Mt(t),r=`${JSON.stringify(NM(e),null,2)}
|
|
256
|
+
`;t.writeJournalFile?await t.writeJournalFile(n,r):await we(n,r)},$M=/^(\S+)\s+(REG_[A-Z_]+)(?:\s+(.*))?$/,MM=new Set(["REG_SZ","REG_EXPAND_SZ","REG_DWORD"]),BM=new Set(["REG_QWORD","REG_MULTI_SZ","REG_BINARY","REG_NONE"]),FM=e=>e.replace(/^HKCU\\/i,"HKEY_CURRENT_USER\\").replace(/^HKLM\\/i,"HKEY_LOCAL_MACHINE\\"),WM=(e,t)=>e.toUpperCase()===t.toUpperCase()||e.toUpperCase()===FM(t).toUpperCase(),Wk=(e,t,n,r,o)=>{let a=$e.find(i=>i.toLowerCase()===t.toLowerCase());if(!a)return!1;let s=n==="String"?"REG_SZ":n==="ExpandString"?"REG_EXPAND_SZ":n;if(s!=="REG_SZ"&&s!=="REG_EXPAND_SZ"){if(o)throw new Error("an owned Claude policy value has an unsupported type");return!1}if(e[a].present)throw new Error("a Claude policy value was returned more than once");return e[a]={present:!0,type:s,value:r},!0},UM=e=>e==="String"?"REG_SZ":e==="ExpandString"?"REG_EXPAND_SZ":e==="DWord"?"REG_DWORD":e==="QWord"?"REG_QWORD":e==="MultiString"?"REG_MULTI_SZ":e==="Binary"?"REG_BINARY":e==="None"?"REG_NONE":e,HM=(e,t)=>{if(!$l(e,!0))return!1;let n=UM(t);if(BM.has(n))return!1;if(MM.has(n))return n==="REG_EXPAND_SZ"?!0:!nk(e,!0)},GM=(e,t)=>{let n=Qk(),r=!1,o=!1,a=!1,s=t.toUpperCase()===ii.toUpperCase(),i=(l,d)=>{if(!s)return;let u=HM(l,d);u===void 0?a=!0:u&&(o=!0)},c=e.trim();if(c.startsWith("{")){let l=JSON.parse(c);if(l.anyrayRegistry!==1||typeof l.key!="string"||l.key.toUpperCase()!==t.toUpperCase()||!Array.isArray(l.values))throw new Error("invalid registry bridge response");for(let d of l.values){if(!d||typeof d!="object"||Array.isArray(d))throw new Error("invalid registry bridge value");let u=d;if(typeof u.name!="string"||typeof u.kind!="string"||typeof u.value!="string")throw new Error("invalid registry bridge value");i(u.name,u.kind),Wk(n,u.name,u.kind,u.value,!s)||(r=!0)}return{keyPresent:!0,values:n,foreignState:r,machinePolicyActive:o,unparsed:a}}for(let l of e.split(/\r?\n/)){let d=l.trim();if(!d||WM(d,t))continue;let u=$M.exec(d);if(!u){r=!0,a=!0;continue}u[1]==="(Default)"&&(u[3]??"")==="(value not set)"||(i(u[1],u[2]),Wk(n,u[1],u[2],u[3]??"",!s)||(r=!0))}return{keyPresent:!0,values:n,foreignState:r,machinePolicyActive:o,unparsed:a}},Un=async(e,t=De)=>{let n=await e(["query",t]);if(n.code!==0){if(n.missing===!0)return{keyPresent:!1,values:Qk(),foreignState:!1,machinePolicyActive:!1,unparsed:!1};throw new Error("registry query failed without proving the key is absent")}return GM(n.stdout,t)},Sr=async e=>{let t=await Un(e,ii);return t.keyPresent?t.unparsed?{names:[],unparsed:!0}:t.machinePolicyActive?{names:[...$e.filter(r=>t.values[r].present)],unparsed:!1}:void 0:void 0},_m=e=>e.unparsed?`This machine may have a Claude policy under ${ii} that could not be read; it would shadow HKCU, so local configuration was left unchanged.`:e.names.length>0?`A Claude policy under ${ii} sets ${e.names.join(", ")}; Claude treats HKLM as the complete configuration and shadows HKCU, so local configuration was left unchanged.`:`A Claude policy under ${ii} contains a recognized configuration value; Claude treats HKLM as the complete configuration and shadows HKCU, so local configuration was left unchanged.`;var Zl=(e,t)=>vr(co(e,t)),ev=(e,t,n,r="REG_SZ")=>["add",e,"/v",t,"/t",r,"/d",n,"/f"],VM=(e,t)=>{let n=Zl(e,t);return Object.fromEntries($e.map(r=>{let o=n[r];return[r,o===void 0?{present:!1}:{present:!0,type:"REG_SZ",value:o}]}))},KM=(e,t)=>({inferenceProvider:{present:!0,type:"REG_SZ",value:"gateway"},inferenceGatewayBaseUrl:{present:!0,type:"REG_SZ",value:e.anthropicBaseUrl},inferenceGatewayAuthScheme:{present:!0,type:"REG_SZ",value:"bearer"},chatTabEnabled:{present:!1},coworkEgressAllowedHosts:{present:!1},inferenceCredentialKind:{present:!1},inferenceCredentialHelper:{present:!1},inferenceGatewayApiKey:{present:!0,type:"REG_SZ",value:t}}),jM=e=>e.helper.lastWritten===void 0&&e.helper.pending===void 0&&e.lastWritten.inferenceGatewayApiKey.present,Cm=e=>Object.fromEntries($e.map(t=>[t,xM(t,e[t])])),Uk=(e,t,n,r)=>({version:Kl,registryKey:De,keyExisted:e,lastWritten:Cm(t),helper:{path:n,lastWritten:bm(r)}}),ZM=(e,t,n,r,o,a)=>({version:Kl,registryKey:De,keyExisted:e,lastWritten:Cm(t),pending:Cm(n),helper:{path:r,...o?{lastWritten:bm(o)}:{},pending:bm(a)}}),km=(e,t,n)=>pa(n,e.lastWritten[t])||e.pending!==void 0&&pa(n,e.pending[t]),ha=async e=>{try{let t=await wm(e,"utf8");return{content:t,sha256:uo(t)}}catch(t){if(t.code==="ENOENT")return;throw t}},ya=async e=>(await ha(e))?.sha256,fa=(e,t)=>t===e.helper.lastWritten?.sha256||t===e.helper.pending?.sha256,Vl=async(e,t)=>{let n=kM(e),r;try{r=await Kk(ci(e))}catch(c){if(c.code==="ENOENT")return;throw c}let o=r.filter(c=>c.startsWith(n)).map(c=>ga(ci(e),c));if(o.length===0)return;if(o.length!==1)throw new Error("ambiguous credential helper recovery files");let a=o[0],[s,i]=await Promise.all([ha(e),ha(a)]);if(!i)throw new Error("credential helper recovery file disappeared");if(!s){if(!t||!fa(t,i.sha256))throw new Error("credential helper recovery is not journal-owned");if(!await qk(e,a))throw new Error("credential helper changed during recovery");return}if(t&&fa(t,s.sha256)&&fa(t,i.sha256)){await Xt(a,{force:!0});return}throw new Error("credential helper recovery conflicts with current file")},Pm=async(e,t,n)=>(n.present?await e(ev(De,t,n.value??"",n.type??"REG_SZ")):await e(["delete",De,"/v",t,"/f"])).code===0,YM=async(e,t,n)=>{let r=!0,o=await Un(e);for(let a of $e)if(!ua(o.values[a],t[a])){if(!ua(o.values[a],n[a])){r=!1;continue}await Pm(e,a,t[a])||(r=!1),o=await Un(e)}return r&&$e.every(a=>ua(o.values[a],t[a]))},ze=(e,t=!1,n={})=>({status:"manual",messages:[e],...t&&{changedFiles:[Mt(n)]}}),tv=async(e,t,n,r={})=>{if(!be(t))return ze("A valid personal ark_ gateway key is required.",!1,r);let o=Em(r),a;try{a=gM((r.credentialCommand??lm)())}catch{return ze("A durable local anyray-connect runtime is required for Claude Desktop's automatic credential helper.",!1,r)}let s=uo(a),i=r.runReg??Hn,c=Mt(r),l;if(!n.dryRun)try{l=await xm(r)}catch(h){return ze(h instanceof ma?"Another Claude Desktop policy operation is already in progress; retry shortly.":"Could not acquire the owner-only Claude Desktop policy lock; the registry was left unchanged.",!1,r)}let d,u,p,m,f=!1;try{let h=await Sr(i);if(h)return ze(_m(h),!1,r);let w=await Tm(r,!n.dryRun);n.dryRun||await Vl(o,w);let y=await Un(i),g=VM(e,o),b=await ha(o),k=b?.sha256,C=!1;if(d=w,u=y,p=g,w){let I=$e.find(_=>!km(w,_,y.values[_]));if(I)return ze(`Claude's ${I} policy changed after Connect configured it; the existing value was preserved. Revert or remove that value before reapplying.`,!1,r);if(k!==void 0&&!fa(w,k))return ze(`Claude's credential helper changed after Connect configured it; ${o} was preserved. Revert or remove it before reapplying.`,!1,r);C=jM(w)}else{if(k!==void 0&&k!==s)return ze(`Existing file ${o} is not the Anyray helper for this runtime. It was left unchanged.`,!1,r);let I=y.foreignState||$e.some(W=>y.values[W].present),_=$e.every(W=>ua(y.values[W],g[W])),T=$e.every(W=>ua(y.values[W],KM(e,t.trim())[W]));if(I&&!_&&!T)return ze(`Existing Claude third-party-inference policy values under ${De} are not owned by Anyray. They were left unchanged to avoid copying or overwriting another provider credential.`,!1,r);if(C=T,_&&k===s)return n.dryRun?{status:"configured",messages:[`Would adopt the exact dynamic-helper values under ${De} into an owner-only journal without rewriting them.`]}:(await Hl(Uk(y.keyPresent,g,o,a),r),{status:"configured",changedFiles:[c],messages:[`Adopted the exact dynamic-helper values under ${De} into the ownership journal.`]})}if(C){let I=!0;try{I=(r.appRunning??Im)()}catch{}if(I)return ze("Claude Desktop is running. Fully quit it, then re-run Connect to migrate the legacy static credential safely.",!1,r)}let S=ZM(w?.keyExisted??y.keyPresent,y.values,g,o,b?.content,a);if(m=S,n.dryRun)return{status:"configured",messages:[`Would atomically configure Claude Desktop through ${De}, install a dynamic credential helper at ${o}, and create an owner-only rollback journal.`]};await Hl(S,r),f=!0;for(let I of $e){let _=await Un(i);if(!pa(_.values[I],S.lastWritten[I])&&!pa(_.values[I],S.pending[I]))throw new Error("registry value changed during apply");if(!ua(_.values[I],g[I])&&!await Pm(i,I,g[I]))throw new Error("registry write failed")}let E=await Un(i);if(!$e.every(I=>pa(E.values[I],S.pending[I])))throw new Error("registry verification failed");if(k!==s&&(k===void 0?await CM(o,a):await Gl(o,k,a,"apply",r)),await ya(o)!==s)throw new Error("credential helper verification failed");return await Hl(Uk(S.keyExisted,g,o,a),r),{status:"configured",changedFiles:[c,o],messages:[`Configured Claude Desktop through ${De}.`,`Installed or updated the dynamic credential helper at ${o}; no personal key is stored in policy or the ownership journal.`,"Fully quit and reopen Claude Desktop to load the policy.",...Dl]}}catch{if(!f||!u||!p||!m)return ze("Could not safely inspect or begin Claude Desktop's HKCU policy transaction; the registry was left unchanged.",!1,r);try{await Vl(o,m);let h=!0,w=await ha(o),y=m.helper.pending;if(w?.sha256!==m.helper.lastWritten?.sha256&&(y!==void 0&&w?.sha256===y.sha256?m.helper.lastWritten?(await Gl(o,y.sha256,m.helper.lastWritten.content,"rollback",r),h=await ya(o)===m.helper.lastWritten.sha256):await Gl(o,y.sha256,void 0,"rollback",r):h=w===void 0&&m.helper.lastWritten===void 0),h&&await YM(i,u.values,p))return d?await Hl(d,r):await Xt(c,{force:!0}),ze("Claude Desktop's HKCU policy update failed and was rolled back to its exact pre-apply state.",!1,r)}catch{}return ze("Could not complete or fully roll back Claude Desktop's HKCU policy transaction. The owner-only journal was preserved; run `anyray-connect desktop disconnect` to recover safely.",!0,r)}finally{await l?.()}},nv=async(e,t={})=>{let n=t.runReg??Hn,r=Mt(t),o;if(!e.dryRun)try{o=await xm(t)}catch(a){return ze(a instanceof ma?"Another Claude Desktop policy operation is already in progress; retry shortly.":"Could not acquire the owner-only Claude Desktop policy lock; no registry value was removed.",!1,t)}try{let a=await Tm(t,!e.dryRun);a&&!e.dryRun&&await Vl(a.helper.path,a);let s=await Un(n);if(!a)return $e.filter(f=>s.values[f].present).length>0?ze(`Claude policy values exist under ${De}, but Anyray has no ownership journal. Remove them manually only if you know they came from an older Connect run.`,!1,t):{status:"not-found",messages:["No Windows Claude setup to revert."]};let i=$e.filter(m=>s.values[m].present&&!km(a,m,s.values[m])),c=await ya(a.helper.path),l=c!==void 0&&!fa(a,c);if(e.dryRun)return{status:i.length||l?"manual":"reverted",messages:[`Would remove Anyray-owned values from ${De}.`,`Would remove the Anyray-owned credential helper at ${a.helper.path}.`,...i.length||l?[`Would preserve changed values: ${[...i,...l?["credential helper"]:[]].join(", ")}.`]:[]]};let d=!1,u=new Set(i);for(let m of $e){let h=(await Un(n)).values[m];if(h.present){if(!km(a,m,h)){u.add(m);continue}await Pm(n,m,{present:!1})||(d=!0)}}let p=await ya(a.helper.path);if(p!==void 0)if(fa(a,p))try{await Gl(a.helper.path,p,void 0,"revert",t)}catch{d=!0,u.add("credential helper")}else u.add("credential helper");return d?ze(`Could not remove every Anyray-owned Claude policy value or credential-helper file. The ownership journal remains at ${r}; re-run revert.`,!0,t):(await Xt(r,{force:!0}),{status:u.size?"manual":"reverted",changedFiles:[r],messages:[`Removed Anyray-owned Claude Desktop values from ${De}.`,"Removed the Anyray-owned dynamic credential helper when its content still matched the journal.",...u.size?[`Preserved values changed after Connect: ${[...u].join(", ")}.`]:[],...u.size?[]:Ll]})}catch{return ze(`Could not safely inspect or revert ${De}; no unproven value was removed.`,!1,t)}finally{await o?.()}},rv=async(e,t={})=>{let n=t.runReg??Hn;if(!await x(Mt(t)))return;let r;try{r=await xm(t);let o=await Tm(t);if(o&&await Vl(o.helper.path,o),!o||o.pending||await Sr(n)!==void 0)return;let a=await Un(n);if(!(a.values.inferenceProvider.value==="gateway"&&a.values.inferenceGatewayBaseUrl.value===Vt(e)&&a.values.inferenceGatewayAuthScheme.value==="bearer"&&$e.every(l=>pa(a.values[l],o.lastWritten[l]))))return;let i=await ya(o.helper.path),c=o.helper.lastWritten;return a.values.inferenceCredentialKind.value==="helper-script"&&a.values.inferenceCredentialHelper.value===o.helper.path&&!a.values.inferenceGatewayApiKey.present&&c!==void 0&&i===c.sha256&&await AM(c,t)?"dynamic":o.helper.lastWritten===void 0&&!a.values.inferenceCredentialKind.present&&!a.values.inferenceCredentialHelper.present&&a.values.inferenceGatewayApiKey.present?"legacy-static":void 0}catch{return}finally{await r?.()}},ov=async(e,t={})=>await rv(e,t)!==void 0,av=async(e,t={})=>await rv(e,t)==="dynamic";var ba=(e=XM())=>e==="win32"?Im:Fl,Dm="You can still make this export searchable with `anyray-connect history import <conversations.json>`.",Jl=async(e,t={})=>{let n=(t.profileRoot??io)();if(!n)return{ok:!1,reason:"this platform has no Claude Desktop third-party profile",remedy:Dm};if((t.appRunning??ba(t.runtimePlatform))())return{ok:!1,reason:"Claude Desktop is running",remedy:"Fully quit Claude Desktop, then run this again."};try{await sv.access(e)}catch{return{ok:!1,reason:`no such file: ${e}`,remedy:"Point at the .zip Anthropic emailed you (claude.ai -> Settings -> Privacy -> Export data)."}}let r=await Pl(n);if(!r.ok)return r.reason==="ambiguous"?{ok:!1,reason:"this Claude Desktop profile holds more than one account",remedy:"Choosing which one gets the history is your call, not ours \u2014 "+Dm}:{ok:!1,reason:"no Claude Desktop third-party session store found \u2014 the app has not run in this mode yet",remedy:"Open Claude Desktop with Anyray configured, sign in with your usual Claude account, quit it, then run this again."};let o=await(t.findBinary??JC)();if(!o)return{ok:!1,reason:"the Claude Code CLI was not found",remedy:"Install Claude Code (the conversion step uses its importer), then run this again."};let a=Yl(t.stagingRoot??zM(),`anyray-history-${process.pid}-${JM()}`);try{let s=await(t.runImporter??XC)({binary:o,exportPath:e,configDir:Yl(a,"config"),workDir:Yl(a,"work")});if(!s.ok)return{ok:!1,reason:s.reason,remedy:"This step uses an unsupported Claude Code subcommand, so a version change can break it. "+Dm};if(s.conversations.length===0)return{ok:!1,reason:"that export contains no conversations",remedy:"Check you pointed at the export archive itself."};let i=await qC(r.dir,s.conversations),c=await QC({stagedProjectsDir:Yl(a,"work","projects"),storageDir:r.dir,projects:s.projects,now:t.now?.()??Date.now()});return{ok:!0,storageDir:r.dir,...i,projects:c}}finally{await sv.rm(a,{recursive:!0,force:!0}).catch(()=>{})}};import{promises as St}from"node:fs";import{homedir as bB}from"node:os";import{join as qt,sep as AB}from"node:path";import{isDeepStrictEqual as Ql}from"node:util";import{constants as qM}from"node:fs";import{promises as V}from"node:fs";import{dirname as Aa,isAbsolute as Nm,join as ae,relative as Xl,resolve as zt,sep as li}from"node:path";import{randomUUID as ed}from"node:crypto";var Cn=448,di=384,dv=448,QM=4,$m=3e4,uv=5e3,eB=10*6e4,Lm=e=>({kind:e,migrated:0,alreadyPresent:0,conflicts:0,invalid:0,failed:0}),ct=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),ui=e=>typeof e=="string"&&e.length>0&&e.length<=255&&e!=="."&&e!==".."&&!e.includes("/")&&!e.includes("\\")&&!e.includes("\0"),pv=(e,t)=>{let n=Xl(zt(e),zt(t));return n===""||!n.startsWith(`..${li}`)&&n!==".."&&!Nm(n)},po=async e=>{try{let t=await V.readFile(e,"utf8"),n=JSON.parse(t);return ct(n)?{raw:t,value:n}:void 0}catch(t){return vt(t)&&t.code==="ENOENT"?{raw:void 0,value:{}}:void 0}},vt=e=>e instanceof Error&&"code"in e,tB=e=>{try{return process.kill(e,0),!0}catch(t){return vt(t)&&t.code==="EPERM"}},fv=e=>e===0?"owner.json":`owner.${e}.json`,zl=async e=>{let t;try{t=await V.readdir(e)}catch{return}let r=t.map(d=>{if(d==="owner.json")return{name:d,generation:0};let u=/^owner\.(\d+)\.json$/.exec(d);if(!u)return;let p=Number(u[1]);return Number.isSafeInteger(p)&&p>0?{name:d,generation:p}:void 0}).filter(d=>!!d).sort((d,u)=>u.generation-d.generation)[0];if(!r)return;let o=ae(e,r.name),a,s,i;try{let d=JSON.parse(await V.readFile(o,"utf8"));ct(d)&&typeof d.pid=="number"&&Number.isSafeInteger(d.pid)&&d.pid>0&&typeof d.nonce=="string"&&d.nonce.length>0&&(a=d.pid,s=d.nonce,typeof d.createdAt=="number"&&Number.isFinite(d.createdAt)&&d.createdAt>=0&&(i=d.createdAt))}catch{}let c=await V.stat(o).then(d=>d.mtimeMs),l=i!==void 0&&i<=Date.now()+6e4?i:c;return{generation:r.generation,pid:a,nonce:s,createdAtMs:l,mtimeMs:c}},mv=e=>{if(e.pid===void 0||!tB(e.pid))return!0;let t=Date.now();return t-e.mtimeMs>$m&&t-e.createdAtMs>eB},nB=async e=>{let t=`${e}.anyray-lock`;await V.mkdir(Aa(t),{recursive:!0,mode:Cn});let n=ed(),r,o=!1;try{await V.mkdir(t,{mode:Cn}),o=!0}catch(i){if(!vt(i)||i.code!=="EEXIST")throw i}for(let i=0;i<3&&!r;i+=1){let c=0;if(!o){let d=await zl(t);if(d){if(!mv(d)||!Number.isSafeInteger(d.generation+1))return;c=d.generation+1}else if(await V.stat(t).then(p=>Date.now()-p.mtimeMs).catch(()=>0)<=$m)return}let l=ae(t,fv(c));try{await V.writeFile(l,`${JSON.stringify({pid:process.pid,nonce:n,createdAt:Date.now()})}
|
|
257
|
+
`,{flag:"wx",mode:di}),r=l}catch(d){if(vt(d)&&d.code==="EEXIST"){o=!1;continue}throw o&&await V.rm(t,{recursive:!0,force:!0}).catch(()=>{}),d}}if(!r)return;let a=r,s=setInterval(()=>{(async()=>{try{let i=JSON.parse(await V.readFile(a,"utf8"));if(!ct(i)||i.nonce!==n)return;let c=new Date;await V.utimes(a,c,c)}catch{}})()},uv);return s.unref(),async()=>{clearInterval(s);try{(await zl(t))?.nonce===n&&await V.rm(t,{recursive:!0,force:!0})}catch{}}},rB=async(e,t,n)=>{await V.mkdir(Aa(e),{recursive:!0,mode:Cn});let r=await nB(e);if(!r)return!1;try{let o;try{o=await V.readFile(e,"utf8")}catch(s){if(!vt(s)||s.code!=="ENOENT")throw s}if(o!==t)return!1;let a=`${e}.anyray-tmp-${process.pid}-${ed()}`;try{await V.writeFile(a,`${JSON.stringify(n,null,2)}
|
|
258
|
+
`,{mode:di,flag:"wx"}),await V.rename(a,e)}catch(s){try{await V.rm(a,{force:!0})}catch{}throw s}return!0}finally{await r()}},td=async(e,t)=>{for(let n=0;n<QM;n+=1){let r=await po(e);if(!r)return"failed";let o=t(r.value);if(!o||Ql(o,r.value))return"unchanged";try{if(await rB(e,r.raw,o))return"written"}catch{return"failed"}}return"failed"},iv=async e=>{try{return(await V.readdir(e,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name)}catch{return[]}},nd=async e=>{let t=[];for(let n of await iv(e))for(let r of await iv(ae(e,n)))t.push(ae(e,n,r));return t},oB=e=>Array.isArray(e.skills)?e.skills.filter(t=>ct(t)&&ui(t.name)&&t.creatorType==="user"&&t.syncManaged===!1):[],aB=async e=>{let t=ae(e,"local-agent-mode-sessions","skills-plugin"),n=[];for(let r of await nd(t)){let o=await po(ae(r,"manifest.json"));if(!o)continue;let a=r.split(li).at(-1)??"";for(let s of oB(o.value))n.push({account:a,packageDir:r,entry:s})}return n},sB=async e=>{let t=await po(ae(e,".claude-plugin","plugin.json"));return!!t&&ui(t.value.name)},iB=(e,t)=>{let n=Nm(t)?zt(t):zt(e,t);if(!pv(e,n)||n===zt(e))return;let r=Xl(zt(e),n);return r.length>0?{absolute:n,relative:r}:void 0},cB=async e=>{let t=await nd(ae(e,"local-agent-mode-sessions")),n=[];for(let r of t){if(r.split(li).includes("skills-plugin"))continue;let o=ae(r,"cowork_plugins"),a=await po(ae(o,"installed_plugins.json"));if(!a||!ct(a.value.plugins))continue;let s=r.split(li).at(-2)??"";for(let[i,c]of Object.entries(a.value.plugins))if(!(!ui(i)||!Array.isArray(c)))for(let l of c){if(!ct(l)||l.scope!=="user"||typeof l.installPath!="string")continue;let d=iB(o,l.installPath);!d||!await sB(d.absolute)||n.push({account:s,id:i,entry:l,packageDir:d.absolute,relativeInstallPath:d.relative,settingsFile:ae(r,"cowork_account_settings.json")})}}return n},lB=async e=>{let t=await po(ae(e,"claude_desktop_config.json"));return!t||!ct(t.value.mcpServers)?{}:Object.fromEntries(Object.entries(t.value.mcpServers).filter(([n,r])=>ui(n)&&n.toLowerCase()!=="anyray"&&ct(r)))},hv=async e=>{let[t,n,r]=await Promise.all([aB(e),cB(e),lB(e)]);return{skills:t,plugins:n,localMcpServers:r}},Mm=async e=>{let t=await hv(e);return{skills:t.skills.length,plugins:t.plugins.length,localMcpServers:Object.keys(t.localMcpServers).length,accounts:[...new Set([...t.skills.map(n=>n.account),...t.plugins.map(n=>n.account)])].filter(n=>n.length>0)}},cv=async e=>{try{let n=await V.lstat(e);if(!n.isDirectory()||n.isSymbolicLink())return!1}catch{return!1}let t=async n=>{let r;try{r=await V.readdir(n,{withFileTypes:!0})}catch{return!1}for(let o of r){if(!ui(o.name))return!1;let a=ae(n,o.name);if(o.isSymbolicLink())return!1;if(o.isDirectory()){if(!await t(a))return!1}else if(!o.isFile())return!1}return!0};return t(e)},dB=async e=>{let t=async n=>{let r=await V.readdir(n,{withFileTypes:!0});for(let o of r){let a=ae(n,o.name);if(o.isDirectory())await t(a),await V.chmod(a,Cn);else if(o.isFile()){let s=await V.stat(a);await V.chmod(a,(s.mode&73)!==0?dv:di)}}};await t(e),await V.chmod(e,Cn)},yv=async(e,t)=>{try{let[n,r]=await Promise.all([V.readFile(e),V.readFile(t)]);return n.equals(r)}catch{return!1}},ql=async(e,t)=>{try{let[n,r]=await Promise.all([V.readdir(e,{withFileTypes:!0}),V.readdir(t,{withFileTypes:!0})]),o=n.map(s=>s.name).sort(),a=r.map(s=>s.name).sort();if(!Ql(o,a))return!1;for(let s of o){let i=n.find(l=>l.name===s),c=r.find(l=>l.name===s);if(!i||!c||i.isDirectory()!==c.isDirectory()||i.isFile()!==c.isFile())return!1;if(i.isDirectory()){if(!await ql(ae(e,s),ae(t,s)))return!1}else if(!i.isFile()||!await yv(ae(e,s),ae(t,s)))return!1}return!0}catch{return!1}},gv=e=>`${e}.anyray-incomplete`,wv=async(e,t)=>{let n=!1;if(t){await V.mkdir(Aa(e),{recursive:!0,mode:Cn});try{await V.mkdir(e,{mode:Cn}),n=!0}catch(l){if(!vt(l)||l.code!=="EEXIST")return}}else try{let l=await V.lstat(e);if(!l.isDirectory()||l.isSymbolicLink())return}catch{return}let r=ed(),o;for(let l=0;l<3&&!o;l+=1){let d=0;if(!n){let p;try{p=await zl(e)}catch{return}if(p){if(!mv(p)||!Number.isSafeInteger(p.generation+1))return;d=p.generation+1}else if(await V.stat(e).then(f=>Date.now()-f.mtimeMs).catch(()=>0)<=$m)return}let u=ae(e,fv(d));try{await V.writeFile(u,`${JSON.stringify({pid:process.pid,nonce:r,createdAt:Date.now()})}
|
|
259
|
+
`,{flag:"wx",mode:di}),o=u}catch(p){if(vt(p)&&p.code==="EEXIST"){n=!1;continue}n&&await V.rm(e,{recursive:!0,force:!0}).catch(()=>{});return}}if(!o)return;let a=o,s=setInterval(()=>{(async()=>{try{let l=JSON.parse(await V.readFile(a,"utf8"));if(!ct(l)||l.nonce!==r)return;let d=new Date;await V.utimes(a,d,d)}catch{}})()},uv);s.unref();let i=!1,c=()=>{i||(i=!0,clearInterval(s))};return{abandon:c,complete:async()=>{c();try{(await zl(e))?.nonce===r&&await V.rm(e,{recursive:!0,force:!0})}catch{}}}},bv=async e=>{let t=await wv(e,!1);t&&await t.complete()},uB=async(e,t,n)=>{let r=gv(t),o=!1;try{let c=await V.lstat(t);if(!c.isDirectory()||c.isSymbolicLink())return"conflict";if(o=!0,await ql(e,t))return await bv(r),"present"}catch(c){if(!vt(c)||c.code!=="ENOENT")return"failed"}if(o)try{let c=await V.lstat(r);if(!c.isDirectory()||c.isSymbolicLink())return"conflict"}catch{return"conflict"}let a=await wv(r,!o);if(!a)return"failed";try{await n?.(t)}catch{return a.abandon(),"failed"}if(!o)try{await V.mkdir(t,{mode:Cn})}catch(c){if(!vt(c)||c.code!=="EEXIST")return a.abandon(),"failed";try{let l=await V.lstat(t);if(!l.isDirectory()||l.isSymbolicLink())return await a.complete(),"conflict"}catch{return a.abandon(),"failed"}}let s=async(c,l)=>{let d;try{d=await V.readdir(c,{withFileTypes:!0})}catch{return"failed"}for(let u of d){let p=ae(c,u.name),m=ae(l,u.name);try{if(u.isDirectory()){try{await V.mkdir(m,{mode:Cn})}catch(h){if(!vt(h)||h.code!=="EEXIST")throw h;let w=await V.lstat(m);if(!w.isDirectory()||w.isSymbolicLink())return"conflict"}let f=await s(p,m);if(f!=="copied")return f}else if(u.isFile())try{await V.copyFile(p,m,qM.COPYFILE_EXCL);let f=await V.stat(p);await V.chmod(m,(f.mode&73)!==0?dv:di)}catch(f){if(!vt(f)||f.code!=="EEXIST")throw f;if(!await yv(p,m))return"conflict"}else return"failed"}catch(f){return vt(f)&&f.code==="EEXIST"?"conflict":"failed"}}return"copied"},i=await s(e,t);return i==="failed"?(a.abandon(),"failed"):i==="conflict"?(await a.complete(),"conflict"):await ql(e,t)?(await a.complete(),"copied"):(await a.complete(),"conflict")},Av=async(e,t,n,r)=>{if(!await cv(e))return"invalid";try{let a=await V.lstat(t);if(!a.isDirectory()||a.isSymbolicLink())return"conflict";if(await ql(e,t))return await bv(gv(t)),"present"}catch(a){if(!vt(a)||a.code!=="ENOENT")return"failed"}await V.mkdir(Aa(t),{recursive:!0,mode:Cn});let o=ae(Aa(t),`.anyray-stage-${ed()}`);try{return await V.cp(e,o,{recursive:!0,force:!1,errorOnExist:!0}),await cv(o)?(await dB(o),await n?.(t),await uB(o,t,r)):"invalid"}catch{return"failed"}finally{try{await V.rm(o,{recursive:!0,force:!0})}catch{}}},lv=(e,t,n)=>n||!t?e:e.filter(r=>r.account.startsWith(t)),pB=async e=>{let t=await nd(ae(e,"local-agent-mode-sessions","skills-plugin")),n=[];for(let r of t)(await po(ae(r,"manifest.json")))?.raw!==void 0&&n.push(r);return n.length===1?{state:"found",path:n[0]}:{state:n.length===0?"missing":"ambiguous"}},fB=async e=>{let t=await nd(ae(e,"local-agent-mode-sessions")),n=[];for(let r of t)if(!r.split(li).includes("skills-plugin"))try{await V.access(ae(r,"cowork_account_settings.json")),n.push(r)}catch{}return n.length===1?{state:"found",path:n[0]}:{state:n.length===0?"missing":"ambiguous"}},mB=async(e,t,n,r,o)=>{let a=ae(t,"manifest.json");for(let s of e){let i=ae(s.packageDir,"skills",s.entry.name);try{await V.access(ae(i,"SKILL.md"))}catch{n.invalid+=1;continue}let c=ae(t,"skills",s.entry.name),l=await Av(i,c,r,o);if(l==="conflict"){n.conflicts+=1;continue}if(l==="invalid"){n.invalid+=1;continue}if(l==="failed"){n.failed+=1;continue}let d=!1;await td(a,p=>{let m=Array.isArray(p.skills)?p.skills:[];if(m.find(h=>ct(h)&&typeof h.name=="string"&&h.name.toLowerCase()===s.entry.name.toLowerCase())){d=!0;return}return{...p,skills:[...m,s.entry]}})==="failed"?n.failed+=1:d||l==="present"?n.alreadyPresent+=1:n.migrated+=1}},Cv=(e,t)=>({...e,installPath:t}),hB=(e,t,n,r,o)=>{if(typeof r.installPath!="string")return!1;let a=Nm(r.installPath)?zt(r.installPath):zt(o,r.installPath),s=Cv(e,Xl(zt(t),zt(n))),i={...r,installPath:Xl(zt(o),a)};return Ql(s,i)},yB=async(e,t,n)=>{let r=await po(e);if(!r||!ct(r.value.enabledPlugins))return"unchanged";let o=r.value.enabledPlugins[n];return typeof o!="boolean"?"unchanged":td(t,a=>{let s=ct(a.enabledPlugins)?a.enabledPlugins:{};if(!(n in s))return{...a,enabledPlugins:{...s,[n]:o}}})},gB=async(e,t,n,r,o)=>{let a=ae(t,"cowork_plugins"),s=ae(a,"installed_plugins.json"),i=ae(t,"cowork_account_settings.json");for(let c of e){let l=ae(a,c.relativeInstallPath);if(!pv(a,l)){n.invalid+=1;continue}let d=await Av(c.packageDir,l,r,o);if(d==="conflict"){n.conflicts+=1;continue}if(d==="invalid"){n.invalid+=1;continue}if(d==="failed"){n.failed+=1;continue}let u=!1,p=!1;await td(s,f=>{let h=ct(f.plugins)?f.plugins:{},w=h[c.id],y=Array.isArray(w)?w:[],g=y.find(k=>ct(k)&&k.scope==="user");if(g){u=hB(c.entry,Aa(c.settingsFile),c.packageDir,g,t),p=!u;return}let b=Cv(c.entry,l);return{...f,version:typeof f.version=="number"?f.version:2,plugins:{...h,[c.id]:[...y,b]}}})==="failed"?n.failed+=1:p?n.conflicts+=1:await yB(c.settingsFile,i,c.id)==="failed"?n.failed+=1:u||d==="present"?n.alreadyPresent+=1:n.migrated+=1}},wB=async(e,t,n)=>{let r=ae(t,"claude_desktop_config.json");for(let[o,a]of Object.entries(e)){let s={value:"migrated"};await td(r,c=>{let l=ct(c.mcpServers)?c.mcpServers:{};if(o in l){s.value=Ql(l[o],a)?"present":"conflict";return}return{...c,mcpServers:{...l,[o]:a}}})==="failed"?n.failed+=1:s.value==="present"?n.alreadyPresent+=1:s.value==="conflict"?n.conflicts+=1:n.migrated+=1}},kv=async(e,t,n={})=>{let r=await hv(e),o=Lm("skill"),a=Lm("plugin"),s=Lm("local-mcp"),i=[],c=[],l=lv(r.skills,n.account,n.allAccounts),d=lv(r.plugins,n.account,n.allAccounts);if(n.allowedAccounts&&!n.allAccounts){let p=new Set(n.allowedAccounts);if([...new Set([...l.map(f=>f.account),...d.map(f=>f.account)])].some(f=>!p.has(f)))return{outcomes:[o,a,s],blocked:i,ambiguous:c,sourceChanged:!0,retryable:[]}}if(l.length>0){let p=await pB(t);p.state==="found"?await mB(l,p.path,o,n.beforeDirectoryPublish,n.afterDirectoryClaim):p.state==="missing"?i.push("skill"):(o.conflicts+=l.length,c.push("skill"))}if(d.length>0){let p=await fB(t);p.state==="found"?await gB(d,p.path,a,n.beforeDirectoryPublish,n.afterDirectoryClaim):p.state==="missing"?i.push("plugin"):(a.conflicts+=d.length,c.push("plugin"))}await wB(r.localMcpServers,t,s);let u=[o,a,s];return{outcomes:u,blocked:i,ambiguous:c,sourceChanged:!1,retryable:u.filter(p=>p.failed>0).map(p=>p.kind)}};var CB=async e=>{try{return await St.access(e),!0}catch{return!1}},vv=448,kB=384,Ev={code:"claude-code-sessions",cowork:"local-agent-mode-sessions"},vB=["code","cowork"],Wm=(e,t,n,r=!1)=>r?"Claude Desktop has not been set up on Anyray yet \u2014 run `anyray-connect desktop` first, then open Claude Desktop once and fully quit it.":e==="ambiguous"?`Claude Desktop's third-party profile holds more than one ${t} store, so which one to fill is your call \u2014 re-run \`${n}\` with \`--account <id>\`.`:t==="cowork"?"Open Claude Desktop, sign in, and open the Cowork tab once \u2014 that is what creates the store \u2014 then fully quit it and run this again.":"Open Claude Desktop, sign in, and start a Claude Code session once \u2014 that is what creates the store \u2014 then fully quit it and run this again.",Bm=e=>({lane:e,migrated:0,alreadyPresent:0,skippedNoTranscript:0,failed:0}),Iv=async e=>{let t;try{t=(await St.readdir(e,{withFileTypes:!0})).filter(r=>r.isDirectory()&&ia(r.name)).map(r=>r.name)}catch{return[]}let n=[];for(let r of t)try{let o=(await St.readdir(qt(e,r),{withFileTypes:!0})).filter(a=>a.isDirectory()&&ia(a.name)).map(a=>a.name);for(let a of o)n.push(qt(e,r,a))}catch{}return n},SB=async e=>{try{return(await St.readdir(e)).filter(t=>t.startsWith(Fn)&&t.endsWith(".json")).map(t=>t.slice(Fn.length,-5)).filter(ia)}catch{return[]}},EB=async(e,t)=>{let n=await Iv(qt(e,Ev[t])),r=[];for(let o of n){let a=await SB(o);a.length>0&&r.push({dir:o,ids:a,account:o.split(AB).slice(-2)[0]})}return r},IB=async(e,t)=>{if(t==="cowork"){let r=await Pl(e);return r.ok?{dir:r.dir}:{missing:r.reason}}let n=await Iv(qt(e,Ev.code));return n.length===1?{dir:n[0]}:{missing:n.length===0?"no-account":"ambiguous"}},xB=async(e,t)=>{let n=`${t}.anyray-tmp-${process.pid}`;await St.copyFile(e,n),await St.chmod(n,kB),await St.rename(n,t)},RB=async(e,t)=>{try{let n=JSON.parse(await St.readFile(e,"utf8"));if(!n||typeof n!="object")return!1;let{cwd:r,cliSessionId:o}=n;return typeof r!="string"||typeof o!="string"||r.length===0||!ia(o)?!1:(await St.access(qt(t,".claude","projects",rm(r),`${o}.jsonl`)),!0)}catch{return!1}},OB=async(e,t,n,r)=>{let o=Bm(e),a=await om(n);for(let s of t)await TB(e,s,n,r,a,o);return o},TB=async(e,t,n,r,o,a)=>{for(let s of t.ids){if(o.has(s)){a.alreadyPresent+=1;continue}let i=`${Fn}${s}.json`,c=qt(t.dir,i);try{if(e==="code"){if(!await RB(c,r)){a.skippedNoTranscript+=1;continue}}else{let l=qt(t.dir,`${Fn}${s}`),d=qt(n,`${Fn}${s}`),u=await St.readdir(l);await St.mkdir(d,{mode:vv});for(let p of u)await St.cp(qt(l,p),qt(d,p),{recursive:!0,force:!1,errorOnExist:!0});await St.chmod(d,vv)}await xB(c,qt(n,i)),o.add(s),a.migrated+=1}catch{a.failed+=1}}},Sv=(e,t,n,r=[])=>{let o=new Map;for(let{sources:s}of e)for(let i of s){let c=o.get(i.account)??{sessions:0,portable:!1};c.sessions+=i.ids.length,o.set(i.account,c)}for(let s of r){let i=o.get(s)??{sessions:0,portable:!1};i.portable=!0,o.set(s,i)}let a=[...o.entries()].sort((s,i)=>i[1].sessions-s[1].sessions).map(([s,i])=>{let c=i.sessions===0?"portable configuration":`${i.sessions} session${i.sessions===1?"":"s"}${i.portable?" plus portable configuration":""}`;return` ${t} --account ${s.slice(0,8)} (${c})`});return{ok:!1,kind:"account-ambiguous",reason:n,remedy:["Pick the one you want, or take everything:",...a,` ${t} --all-accounts`].join(`
|
|
260
|
+
`)}},Fm=e=>new Set(e.flatMap(t=>t.sources.map(n=>n.account))),xv=async e=>{let t=[];for(let n of vB)t.push({lane:n,sources:await EB(e,n)});return t},Rv=async(e={})=>{let t=(e.firstPartyRoot??(()=>zs()))();if(!t)return{sessions:0,accounts:0,userSkills:0,userPlugins:0,localMcpServers:0};let[n,r]=await Promise.all([xv(t),Mm(t)]),o=n.reduce((s,i)=>s+i.sources.reduce((c,l)=>c+l.ids.length,0),0),a=Fm(n);for(let s of r.accounts)a.add(s);return{sessions:o,accounts:a.size,userSkills:r.skills,userPlugins:r.plugins,localMcpServers:r.localMcpServers}},fo=async(e={})=>{let t=(e.home??bB)(),n=(e.firstPartyRoot??(()=>zs()))(),r=(e.thirdPartyRoot??(()=>io()))();if(!n||!r)return{ok:!1,kind:"platform-unsupported",reason:"this platform has no Claude Desktop third-party profile",remedy:"Migration applies to macOS and Windows, where Desktop runs third-party mode in its own profile."};if((e.appRunning??ba())())return{ok:!1,kind:"app-running",reason:"Claude Desktop is running",remedy:"Fully quit Claude Desktop and run this again \u2014 it rewrites its session list on exit, which would undo the migration."};let[o,a]=await Promise.all([xv(n),Mm(n)]),s;if(e.account){let m=e.account;for(let w of o)w.sources=w.sources.filter(y=>y.account.startsWith(m));let f=a.accounts.filter(w=>w.startsWith(m));if(o.every(w=>w.sources.length===0)&&f.length===0)return{ok:!1,kind:"account-unmatched",reason:`no account in the previous profile starts with "${m}"`,remedy:`Run \`${e.command??"anyray-connect desktop --migrate"}\` with no flags to list the accounts.`};let h=Fm(o);for(let w of f)h.add(w);if(h.size>1)return Sv(o,e.command??"anyray-connect desktop --migrate",`"${m}" matches ${h.size} accounts`,f);s=[...h]}else if(!e.allAccounts){let m=Fm(o);for(let f of a.accounts)m.add(f);if(m.size>1)return Sv(o,e.command??"anyray-connect desktop --migrate",`the previous Claude Desktop profile holds local data for ${m.size} accounts`,a.accounts);s=[...m]}let i=e.command??"anyray-connect desktop --migrate",c=!await CB(r),l=await kv(n,r,{account:e.account,allAccounts:e.allAccounts,allowedAccounts:s});if(l.sourceChanged)return{ok:!1,kind:"account-ambiguous",reason:"the previous Claude Desktop profile changed during migration and now holds local data for another account",remedy:`Re-run \`${i}\` so the account choice is made from a fresh snapshot.`};let d=[],u=[];for(let{lane:m,sources:f}of o){if(f.length===0){d.push(Bm(m));continue}let h=await IB(r,m);if("missing"in h){u.push({lane:m,reason:h.missing,waiting:f.reduce((w,y)=>w+y.ids.length,0)}),d.push(Bm(m));continue}d.push(await OB(m,f,h.dir,t))}if(!(d.some(m=>m.migrated>0||m.alreadyPresent>0)||l.outcomes.some(m=>m.migrated>0||m.alreadyPresent>0||m.conflicts>0))&&(u.length>0||l.blocked.length>0)){let m=u[0];return m?{ok:!1,kind:m.reason==="ambiguous"?"account-ambiguous":"store-missing",reason:m.reason==="ambiguous"?`Claude Desktop's third-party profile holds more than one ${m.lane} store`:`Claude Desktop has no ${m.lane} store in its third-party profile yet`,remedy:Wm(m.reason,m.lane,i,c)}:{ok:!1,kind:"store-missing",reason:"Claude Desktop's third-party profile has no extension store yet",remedy:"Open Claude Desktop once after connecting it to Anyray, then fully quit it so the portable extensions can be copied safely."}}return{ok:!0,lanes:d,portableAssets:l.outcomes,...u.length>0?{blocked:u}:{},...l.blocked.length>0?{blockedAssets:l.blocked}:{},...l.ambiguous.length>0?{ambiguousAssets:l.ambiguous}:{},...l.retryable.length>0?{retryableAssets:l.retryable}:{}}};var _B=e=>[Ne(e)],Ov=e=>({id:e.id,title:e.title,automatic:!1,async detect(){let t=[..._B(e.appDir),...e.detectPaths?.()??[]];for(let n of t)if(await x(n))return{installed:!0,detail:n};return{installed:!1,detail:`${e.appDir} not found`}},async apply(t){return{status:"manual",messages:e.steps(t)}},async revert(t){return{status:"manual",messages:e.revertMessages??[`${e.title}: clear the custom OpenAI base URL / key in its settings to revert.`]}}});var Tv="1.21459.0",NB=LB(PB),$B=async e=>{try{let{stdout:t}=await NB("/usr/bin/plutil",["-extract","CFBundleShortVersionString","raw","-o","-",e],{timeout:2e3,maxBuffer:4096});return String(t).trim()||void 0}catch{return}},MB=async e=>{try{return await DB(e)}catch{return}},_v="No native config was written; use Developer \u2192 Configure Third-Party Inference \u2192 Apply locally.",BB=["Admin policy setup (no JSON): open Developer \u2192 Configure Third-Party Inference; the Anyray connection is already filled in.",'Add approved remote MCP connectors under "Connectors & extensions" and use "Test this connection"; add approved Git marketplaces under "Plugins & skills".',`Choose "Apply locally" to test. For Jamf, first select IT's fleet-wide credential-helper path, then choose Export \u2192 .mobileconfig and deploy the complete profile.`,"If Claude Desktop is already MDM-managed, this window is read-only. Author and export on an unmanaged admin Mac, then redeploy through Jamf."],Ca=async(e={})=>!e.home&&!e.readClaudeAppVersion&&!e.readClaudeAppBundle?(Pv??=Dv({}),Pv):Dv(e),Pv,Dv=async e=>{let t=(e.home??fi)(),n=["/Applications/Claude.app",kn(t,"Applications","Claude.app")],r=e.readClaudeAppVersion??$B,o=e.readClaudeAppBundle??MB;for(let a of n){let s=await r(kn(a,"Contents","Info.plist"));if(!s)continue;let i=d=>({supported:!1,detectedVersion:s,appPath:a,message:`Claude Desktop ${s} is installed, but ${d} ${_v}`}),c=Tl(s,Tv);if(c===void 0)return i("its version string could not be interpreted.");if(c<0)return i(`automatic local setup requires ${Tv} or newer.`);let l=await o(kn(a,"Contents","Resources","app.asar"));return l?hk.some(d=>!l.includes(d))?i("its local config seam no longer matches the shape Connect writes."):{supported:!0,detectedVersion:s,appPath:a}:i("its app bundle could not be read to verify the local config seam.")}return{supported:!1,message:`Could not verify the installed Claude Desktop version. ${_v}`}},rd="anyray",$v="--anyray-owner=claude-desktop-v1",od=(e={})=>{let t=(e.platform??Er)(),n=(e.home??fi)();return t==="darwin"?Jt(e).appConfig:t==="win32"?kn(process.env.APPDATA??kn(n,"AppData","Roaming"),"Claude","claude_desktop_config.json"):kn(n,".config","Claude","claude_desktop_config.json")},Km=(e={})=>kn((e.home??fi)(),"Library","Application Support","Claude","claude_desktop_config.json"),Mv=()=>{let e=Ge("profile");return{command:e.command,args:[...e.args,$v]}},mo=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),Bv=(e,t)=>{let n=Object.keys(e).sort(),r=[...t].sort();return n.length===r.length&&n.every((o,a)=>o===r[a])},FB=(e,t)=>Array.isArray(e)&&e.length===t.length&&e.every((n,r)=>typeof n=="string"&&n===t[r]),WB=e=>{if(!mo(e)||!Bv(e,["command","args"]))return!1;let t=Mv();return e.command===t.command&&FB(e.args,t.args)},UB=e=>mo(e)&&Array.isArray(e.args)&&e.args.at(-1)===$v,HB=e=>{if(!mo(e)||!Bv(e,["command","args"])||typeof e.command!="string"||!Array.isArray(e.args)||!e.args.every(a=>typeof a=="string")||tt(e.command))return!1;let t=e.args;if(!(t.length>=2&&t.at(-2)===er&&t.at(-1)==="profile"))return!1;let r=e.command.replaceAll("\\","/");if(/(?:^|\/)anyray-connect(?:\.exe)?$/.test(r))return t.length===2;if(!/(?:^|\/)node(?:\.exe)?$/.test(r)||t.length!==3)return!1;let o=t[0].replaceAll("\\","/");return!tt(t[0])&&(/(?:^|\/)anyray-connect(?:\/|$)/.test(o)||/(?:^|\/)\.anyray\/bin\/connect-runtime-[0-9A-Za-z][0-9A-Za-z.-]*\/dist\/index\.js$/.test(o))},GB=e=>e===void 0?"absent":WB(e)?"exact":UB(e)||HB(e)?"stale-owned":"foreign",We=class extends Error{changedFiles;constructor(t,n=[]){super(t),this.changedFiles=n}},ho=async e=>{let t=await x(e),n;try{n=await M(e)}catch{throw new We(`Could not parse ${e}; it was left unchanged.`)}if("mcpServers"in n&&!mo(n.mcpServers))throw new We(`Could not update ${e} because mcpServers is not an object; it was left unchanged.`);let o=(mo(n.mcpServers)?n.mcpServers:void 0)?.[rd];return{path:e,fileExisted:t,json:n,entry:o,ownership:GB(o)}},ad=e=>{if(e.ownership==="foreign")throw new We(`MCP name conflict in ${e.path}: mcpServers.${rd} is not owned by Anyray Connect, so it was left untouched. Rename that existing server, then re-run Connect.`)},Fv=(e,t)=>{let n={...e},r=mo(e.mcpServers)?{...e.mcpServers}:{};return t===void 0?delete r[rd]:r[rd]=t,Object.keys(r).length===0?delete n.mcpServers:n.mcpServers=r,n},Hm=async(e,t)=>{if(Um(e.entry,t))return;let n=await ho(e.path);if(!Um(n.entry,e.entry))throw new We(`The MCP configuration in ${e.path} changed during setup; it was left untouched. Re-run Connect.`);return await Wn(e.path,Fv(n.json,t)),{reading:e,afterEntry:t}},Gm=async e=>{let t=await ho(e.reading.path);if(!Um(t.entry,e.afterEntry))throw new We(`The MCP configuration in ${e.reading.path} changed before rollback; the newer value was preserved.`);let n=Fv(t.json,e.reading.entry);await Wn(e.reading.path,n)},VB=async e=>{if(!oe())throw new We(`A durable anyray-connect runtime is required for Claude Desktop retrieval (${Pe()} is temporary); no inference setting was changed.`);let t=await ho(od(e));ad(t);let n=Km(e),r=(e.platform??Er)()==="darwin"&&n!==t.path?await ho(n):void 0;return r&&ad(r),{active:t,...r?{legacy:r}:{}}},Lv=async e=>{let t=await ho(od(e));ad(t);let n=Km(e),r=(e.platform??Er)()==="darwin"&&n!==t.path?await ho(n):void 0;return r&&ad(r),{active:t,...r?{legacy:r}:{}}},KB=async e=>{let t=[];try{let n=await Hm(e.active,Mv());if(n&&t.push(n),e.legacy&&e.legacy.ownership!=="absent"){let r=await Hm(e.legacy,void 0);r&&t.push(r)}}catch(n){let r=[];for(let o of[...t].reverse())await Gm(o).catch(()=>{r.push(o.reading.path)});throw r.length>0?new We(`Claude Desktop MCP setup failed and could not restore ${r.join(", ")}. Re-run \`anyray-connect desktop disconnect\` to recover safely.`,r):n}return{changedFiles:t.map(n=>n.reading.path),async rollback(){let n=[];for(let r of[...t].reverse())await Gm(r).catch(()=>{n.push(r.reading.path)});if(n.length>0)throw new We(`Claude Desktop MCP rollback could not restore ${n.join(", ")}. Newer values were preserved; re-run revert after resolving the conflict.`,n)}}},jB=async e=>{let t=[];try{for(let n of[e.active,e.legacy].filter(r=>!!r)){if(n.ownership==="absent")continue;let r=await Hm(n,void 0);r&&t.push(r)}}catch(n){let r=[];for(let o of[...t].reverse())await Gm(o).catch(()=>{r.push(o.reading.path)});throw r.length>0?new We(`Claude Desktop MCP cleanup failed and could not restore ${r.join(", ")}. Re-run revert after resolving the file conflict.`,r):n}return t.map(n=>n.reading.path)},Nv=e=>{let t=e.clientKey?`${e.clientKey} (your personal gateway key - keep it private)`:`${e.placeholderKey} (placeholder - the gateway holds the real key)`;return["Step 1 - Turn on Developer Mode."," In the menu bar at the VERY TOP of the screen (NOT the in-app help panel):"," Help -> Troubleshooting -> Enable Developer Mode"," (Windows: open the menu at the top-left of the sign-in screen.)",' A "Developer" menu then appears in that same top-of-screen menu bar.',"","Step 2 - Open the Developer MENU in the menu bar (shown below) - NOT Settings:",""," +----------------------------------------------------------------+"," | Claude File Edit View Window [Developer] Help | <- macOS menu bar (very top of screen)"," +-------------------------------------^--------------------------+"," |",' click Developer -> "Configure Third-Party Inference..."',"",' Heads up: use the "Developer" MENU in the bar above - NOT',' Settings -> Developer, which is the "Local MCP servers" pane'," (that's where Anyray's retrieval server appears, not inference)."," A separate setup window then opens.","","Step 3 - In that window's Connection section, paste:",""," Inference provider: Gateway",` Gateway base URL: ${e.anthropicBaseUrl}`," Auth scheme: Bearer",` API key: ${t}`,"",'Step 4 - Click "Apply locally", then fully quit and reopen Claude'," (the config is read once at launch).","","Billing: this route uses an Anyray gateway credential and provider/API billing, not a Claude subscription allowance.","Fleet/MDM: generate a managed profile with `anyray-connect desktop claude --mobileconfig` (applies with no Developer Mode and no paste)."]},ZB={darwinAppName:"Claude",darwinBundleId:"com.anthropic.claudefordesktop",win32Image:"Claude.exe",win32Install:[{root:"localAppData",path:"Programs\\Claude\\Claude.exe"}]},sd="claude-desktop",Vm="migrate",Wv=new Set(["app-running","store-missing"]),YB={code:{one:"Claude Code session",many:"Claude Code sessions"},cowork:{one:"Cowork task",many:"Cowork tasks"}},JB={skill:{one:"user-created skill",many:"user-created skills"},plugin:{one:"user-installed plugin",many:"user-installed plugins"},"local-mcp":{one:"local MCP server",many:"local MCP servers"}},XB="Claude Desktop machine policy could not be read; Connect left inference and retrieval configuration unchanged.",Uv=e=>{let t=(e.platform??Er)(),n=e.home??fi;return{home:n,appRunning:e.appRunning??ba(t),firstPartyRoot:()=>zs({home:n,runtimePlatform:t}),thirdPartyRoot:()=>io({home:n,runtimePlatform:t}),command:"anyray-connect migrate"}},Hv=e=>{let t=e.filter(a=>a.migrated>0);if(t.length===0)return;let n=e.reduce((a,s)=>a+s.skippedNoTranscript,0),r=e.reduce((a,s)=>a+s.failed,0);return`Brought your existing Claude Desktop sessions into its third-party profile: ${t.map(a=>{let s=YB[a.lane];return`${a.migrated} ${a.migrated===1?s.one:s.many}`}).join(", ")}.`+(n>0?` ${n} skipped \u2014 the transcript is no longer on disk.`:"")+(r>0?` ${r} could not be copied.`:"")},Gv=e=>{let t=e.filter(s=>s.migrated>0),n=e.reduce((s,i)=>s+i.conflicts,0),r=e.reduce((s,i)=>s+i.invalid,0),o=e.reduce((s,i)=>s+i.failed,0);if(t.length===0&&n+r+o===0)return;let a=t.map(s=>{let i=JB[s.kind];return`${s.migrated} ${s.migrated===1?i.one:i.many}`});return(a.length>0?`Brought your portable Claude Desktop configuration across: ${a.join(", ")}.`:"Portable Claude Desktop configuration was checked; existing target entries were kept.")+(n>0?` ${n} conflicting target ${n===1?"entry was":"entries were"} preserved.`:"")+(r>0?` ${r} unsafe or incomplete ${r===1?"entry was":"entries were"} skipped.`:"")+(o>0?` ${o} could not be copied.`:"")},pi=async(e,t)=>{if(!t.reportsToUser)return[];try{let n=Uv(e),r=await(e.pendingDesktopMigrationCount??Rv)(n),o=r.userSkills+r.userPlugins+r.localMcpServers;if(r.sessions+o===0)return[];if(t.dryRun)return[`Would bring ${[r.sessions>0?`${r.sessions} existing Claude Desktop session${r.sessions===1?"":"s"}`:"",o>0?`${o} portable configuration ${o===1?"entry":"entries"}`:""].filter(Boolean).join(" and ")} into Claude Desktop's third-party profile, now or automatically the next time Claude Desktop is fully quit.`];let a=await(e.migrateDesktopProfile??fo)(n);if(a.ok){let c=Hv(a.lanes),l=Gv(a.portableAssets),d=a.ambiguousAssets??[],u=d.length>0?`Claude Desktop has more than one target ${d.join(" and ")} store. No store was chosen and every target was preserved. Leave only the intended third-party account/workspace active, then run the migration again.`:void 0,p=(a.blocked??[]).filter(g=>g.reason!=="ambiguous"),m=a.blockedAssets??[],f=a.retryableAssets??[];if(p.length===0&&m.length===0&&f.length===0)return[c,l,u].filter(g=>!!g);if(t.preservePendingOp)return[c,l,u].filter(g=>!!g);await xs(sd,Vm);let h=p.reduce((g,b)=>g+b.waiting,0),w=[h>0?`${h} more session${h===1?"":"s"}`:"",m.length>0?`${m.length} extension ${m.length===1?"store":"stores"}`:""].filter(Boolean),y=[...w.length>0?[`Queued: ${w.join(" and ")} move across once Claude Desktop creates the required third-party stores and the app is fully quit.`]:[],...f.length>0?[`Queued: ${f.length} portable configuration ${f.length===1?"type":"types"} will retry automatically after a recoverable local-copy interruption.`]:[]];return[...c?[c]:[],...l?[l]:[],...u?[u]:[],...y]}if(!Wv.has(a.kind))return[`Your existing Claude Desktop local data was left where it is: ${a.reason}.
|
|
261
|
+
${a.remedy}`];if(t.preservePendingOp)return[];await xs(sd,Vm);let s=r.sessions+o,i=`${s} Claude Desktop local ${s===1?"item":"items"}`;return[a.kind==="store-missing"?`Queued: the ${i} still in your previous profile move across once Claude Desktop's new profile has been signed in to and the app is fully quit.`:`Queued: the ${i} still in your previous profile will move across the next time you fully quit Claude Desktop.`]}catch{return["Could not check whether Claude Desktop had existing sessions to bring across; run `anyray-connect migrate` if its lists look empty."]}},zB=async e=>{if(!e.fullRevert||e.dryRun)return[];try{return await ur(sd),[]}catch{return["Could not clear Claude Desktop's queued profile-migration marker; a background watcher may still be waiting for the app to quit. Delete it by hand if it persists."]}},qB=e=>Ov({id:sd,title:"Claude desktop",appDir:"Claude",detectPaths:()=>{let t=(e.platform??Er)(),n=(e.home??fi)();return t==="darwin"?["/Applications/Claude.app",kn(n,"Applications","Claude.app")]:t==="win32"?[kn(process.env.LOCALAPPDATA??kn(n,"AppData","Local"),"Programs","Claude","Claude.exe")]:[]},steps:t=>te(t,"anthropic")?["Claude Desktop subscription routing requires automatic setup on a verified macOS build and a Claude Code sign-in in Keychain.","This platform/build has no verified subscription helper seam, so Connect left inference unchanged instead of silently switching you to API billing.","To opt into the API-billed Gateway lane instead, re-run Connect in org/API mode and use:",...Nv(t)]:["Claude desktop org/API lane:",...Nv(t),"This Gateway route uses provider/API billing. On verified macOS builds, subscription mode instead installs the Keychain-backed Claude Code credential helper automatically."],revertMessages:["Claude Desktop third-party inference: switch back to the first-party Claude provider in Developer settings (or remove the managed profile). Native setup is restored automatically by `--revert`."]}),QB=(e={})=>{let t=qB(e),n=()=>(e.platform??Er)()==="darwin",r=()=>(e.platform??Er)()==="win32",o=(s,i)=>n()?vk(s,i,e):tv(s,s.clientKey??"",i,e),a=s=>n()?Sk(s,e):nv(s,e);return{...t,automatic:!0,changesOrgManagement:!0,quitGated:{isRunning:()=>(e.appRunning??ba((e.platform??Er)()))(),quitTarget:ZB,needsTarget:()=>!1,async complete(s){if(s!==Vm)return{status:"manual",messages:[`Claude Desktop could not service a queued "${s}" operation it does not recognise; the queue entry was dropped.`]};let i=await(e.migrateDesktopProfile??fo)(Uv(e));if(i.ok){let c=Hv(i.lanes),l=Gv(i.portableAssets),d=i.ambiguousAssets??[];if(d.length>0)return{status:"manual",messages:[...c?[c]:[],...l?[l]:[],`Claude Desktop has more than one target ${d.join(" and ")} store. No store was chosen and every target was preserved. Leave only the intended third-party account/workspace active, then run the migration again.`]};let p=(i.blocked??[]).filter(h=>h.reason!=="ambiguous"),m=i.blockedAssets??[],f=i.retryableAssets??[];return p.length>0||m.length>0||f.length>0?{status:"queued",messages:[...c?[c]:[],...l?[l]:[],...p.length>0||m.length>0?["Still waiting on Claude Desktop to create the remaining third-party stores, which appear the first time those parts of the app are opened."]:[],...f.length>0?["A recoverable local-copy interruption remains; the migration will retry automatically."]:[]]}:{status:"configured",messages:c||l?[c,l].filter(h=>!!h):["No portable Claude Desktop data was left to bring across."]}}return Wv.has(i.kind)?{status:"queued",messages:[i.reason]}:{status:"manual",messages:[i.reason,i.remedy]}}},async usesDynamicCredential(s){return n()?Ik(s,e):r()?av(s,e):!1},async apply(s,i){if(!n()&&!r())return t.apply(s,i);if(n()){let p=Jt(e),m=await lo(p,e);if(m)return{status:"manual",manualAudience:"admin",messages:[mm(m),...await pi(e,i)]}}if(r()){let p;try{p=await Sr(e.runReg??Hn)}catch{return{status:"manual",manualAudience:"admin",messages:[XB,...await pi(e,i)]}}if(p)return{status:"manual",manualAudience:"admin",messages:[_m(p),...await pi(e,i)]}}if(r()&&te(s,"anthropic"))return{status:"manual",messages:["Claude Desktop subscription routing is not available on Windows: Connect could not verify a supported Claude subscription credential source, so inference was left unchanged instead of switching to API billing.","Use org/API mode for the Windows Gateway lane, or run subscription mode on a verified macOS build after signing in to Claude Code."]};if(n()){let p=await Ca(e);if(!p.supported)return{status:"manual",messages:[p.message??"Claude Desktop version is unsupported."]}}let c;try{c=await VB(e)}catch(p){let m=p instanceof We?p.changedFiles:[];return{status:"manual",...m.length>0?{changedFiles:m}:{},messages:[p instanceof We?p.message:"Could not safely inspect Claude Desktop's retrieval MCP configuration; no inference setting was changed."]}}let l=await o(s,{dryRun:!0});if(l.status!=="configured")return l;if(i.dryRun){let p=c.legacy;return{...l,messages:[...l.messages,`Would register the ownership-marked Anyray retrieval MCP server in ${c.active.path}.`,...p&&p.ownership!=="absent"?[`Would remove the legacy owned Anyray MCP registration from ${p.path}.`]:[],...await pi(e,i)]}}let d;try{d=await KB(c)}catch(p){let m=p instanceof We?p.changedFiles:[];return{status:"manual",...m.length>0?{changedFiles:m}:{},messages:[p instanceof We?p.message:"Could not safely register Claude Desktop retrieval; the inference route was left unchanged."]}}let u;try{u=await o(s,{dryRun:!1})}catch{u={status:"manual",messages:["Claude Desktop inference setup failed before it returned a result."]}}if(u.status!=="configured")try{return await d.rollback(),{...u,changedFiles:[...new Set([...u.changedFiles??[],...d.changedFiles])],messages:[...u.messages,"Restored the prior Claude Desktop MCP registration because inference setup did not complete. A config file that was absent before setup may remain as an inert object to avoid racing unrelated concurrent writes."]}}catch{return{status:"manual",changedFiles:[...u.changedFiles??[],...d.changedFiles],messages:[...u.messages,"Inference setup did not complete, and the prior MCP registration could not be fully restored. Re-run `anyray-connect desktop disconnect` to recover safely."]}}return{...u,messages:[...u.messages,"Registered the Anyray retrieval MCP server (anyray_retrieve / anyray_recall) with an ownership marker.",...await pi(e,i),...!i.dryRun&&i.reportsToUser&&i.explicit&&n()?BB:[]],changedFiles:[...new Set([...u.changedFiles??[],...d.changedFiles])]}},async revert(s){let i=od(e),c=await zB(s),l=h=>c.length===0?h:{...h,messages:[...h.messages,...c]};if(!n()&&!r())return l(await t.revert(s));let d;try{d=await Lv(e)}catch(h){return l({status:"manual",messages:[h instanceof We?h.message:"Could not safely inspect Claude Desktop's retrieval MCP configuration; no setting was removed."]})}let u=await a({dryRun:!0});if(s.dryRun){let h=d.legacy;return l({...u,messages:[...u.messages,...d.active.ownership!=="absent"?[`Would remove the owned Anyray retrieval MCP server from ${i}.`]:[],...h&&h.ownership!=="absent"?[`Would remove the legacy owned Anyray MCP registration from ${h.path}.`]:[]]})}let p=await a({dryRun:!1});if(p.status==="manual"){let h=r()?Mt(e):void 0;if(!(h!==void 0&&p.changedFiles?.includes(h)===!0&&!await x(h)))return l(p)}let m;try{m=await jB(await Lv(e))}catch(h){let w=h instanceof We?h.changedFiles:[];return l({status:"manual",changedFiles:[...new Set([...p.changedFiles??[],...w])],messages:[...p.messages,h instanceof We?h.message:"Restored Claude Desktop inference, but could not safely remove its retrieval MCP registration. Re-run revert."]})}await ie(i);let f=Km(e);return n()&&f!==i&&await ie(f),l({...p,messages:[...p.messages,...m.length>0?["Removed the Anyray retrieval MCP server (anyray_retrieve / anyray_recall)."]:[]],changedFiles:[...new Set([...p.changedFiles??[],...m])]})},async mcpStatus(){if(!oe())return{registered:!1,command:null,reason:"ephemeral-runtime"};try{let s=await ho(od(e));return s.ownership!=="exact"||!mo(s.entry)?{registered:!1,command:null,reason:s.fileExisted?s.ownership==="absent"?"absent":s.ownership==="stale-owned"?"stale":"foreign":"no-config"}:{registered:!0,command:typeof s.entry.command=="string"?s.entry.command:null}}catch{return{registered:!1,command:null,reason:"unreadable"}}},async pointsAt(s){return n()?(await Ca(e)).supported?ym(s,e):!1:r()?ov(s,e):!1},async inferenceAuthLanes(){try{if(n()){if(!(await Ca(e)).supported)return["unknown"];let s=await Ek(e);return s?[s]:["unknown"]}if(r())return await x(Mt(e))?await Sr(e.runReg??Hn)?["unknown"]:["api_key"]:["unknown"]}catch{}return["unknown"]},async automaticRepairAllowed(){try{if(n()){let s=Jt(e);return!await x(s.journal)||await lo(s,e)?!1:(await Ca(e)).supported}return r()&&await x(Mt(e))?!await Sr(e.runReg??Hn):!1}catch{return!1}}}},Vv=QB();import{homedir as xF}from"node:os";import{join as RF}from"node:path";import{rm as hd}from"node:fs/promises";import{constants as Kv,accessSync as eF,statSync as tF}from"node:fs";import{platform as jm}from"node:os";import{delimiter as nF,posix as rF,resolve as oF,win32 as aF}from"node:path";var sF="0.59.0",iF="1.1.4",Gn="Anyray \xB7 Claude",Vn="Anyray \xB7 Codex",id="__anyray-acp-agent",jv=(e,t,n)=>{let{command:r,args:o}=nn([id,e,t,n]);return{command:r,args:o,env:{}}},cd=(e=jm())=>e==="win32"?"npx.cmd":"npx",ld=(e=process.env.PATH,t=jm())=>{if(!e)return;let n=cd(t);for(let r of e.split(nF)){let o=r.trim().replace(/^"|"$/g,"");if(!o)continue;let a=oF(o,n);try{if(!tF(a).isFile())continue;return eF(a,t==="win32"?Kv.F_OK:Kv.X_OK),a}catch{}}},dd=(e,t=jm())=>{let n=t==="win32"?aF:rF;return!n.isAbsolute(e)||n.basename(e).toLowerCase()!==cd(t)?!1:t!=="win32"||!/["&|<>^%!\r\n]/.test(e)},cF="https://chatgpt.com/backend-api/codex",lF="chatgpt-account-id,originator,session_id,user-agent,x-codex-turn-metadata,x-codex-window-id,x-client-request-id",Zv="ANYRAY_ACP_CODEX_AUTHORIZATION",Yv="ANYRAY_ACP_CODEX_CLIENT_KEY",Jv="ANYRAY_ACP_CODEX_METADATA",Xv=e=>fe({...e.metadata,tool:e.metadata.tool??"codex",intent:e.metadata.intent??"jetbrains-acp",intentLabel:e.metadata.intentLabel??"JetBrains / Devin via Codex ACP"}),dF=(e,t={})=>{let n=te(e,"openai"),r=n?{"x-anyray-auth-mode":"passthrough","x-anyray-custom-host":cF,"x-anyray-forward-headers":lF}:{},o=n?{...e.clientKey?{"x-anyray-api-key":Yv}:{}}:{Authorization:Zv};return Xv(e)&&(o["x-anyray-metadata"]=Jv),{model_provider:"anyray",model_providers:{anyray:{name:"Anyray Gateway",base_url:e.openaiBaseUrl,wire_api:"responses",...n?{requires_openai_auth:!0}:{},http_headers:r,env_http_headers:o}},...t.mcpServer?{mcp_servers:{anyray:{command:t.mcpServer.command,args:t.mcpServer.args}}}:{}}},uF=e=>{let t=te(e,"openai"),n=Xv(e);return{...t?e.clientKey?{[Yv]:e.clientKey}:{}:{[Zv]:`Bearer ${e.clientKey??e.placeholderKey}`},...n?{[Jv]:n}:{}}},zv=(e,t=cd(),n={})=>({[Gn]:{command:t,args:["--yes",`@agentclientprotocol/claude-agent-acp@${sF}`],env:rn(e).env},[Vn]:{command:t,args:["--yes",`@agentclientprotocol/codex-acp@${iF}`],env:{CODEX_CONFIG:JSON.stringify(dF(e,n)),...uF(e)}}}),mi=(e=cd(),t="jetbrains")=>({[Gn]:jv("claude",e,t),[Vn]:jv("codex",e,t)}),yo=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),ud=(e,t)=>JSON.stringify(e)===JSON.stringify(t);import{inflateRawSync as pF}from"node:zlib";import{open as fF,readFile as zm,readdir as md}from"node:fs/promises";import{dirname as qv,join as me}from"node:path";import{homedir as nS,platform as qm}from"node:os";var pd="2025.3.2",ka="253.30387.147",hi="com.intellij.ml.llm",Zm=new Set(["ml-llm","llm","aia","ai-assistant","jetbrains-ai-assistant"]),mF=1e4,hF=256*1024*1024,yF=16*1024*1024,Ym=1024*1024,Jm=22,gF=Jm+65535,Xm=Tl,wF=()=>{let e=nS(),t=me(e,".cache","JetBrains","RemoteDev");switch(qm()){case"darwin":return[{path:"/Applications",layout:"app-bundles"},{path:me(e,"Applications"),layout:"app-bundles"},{path:me(e,"Library","Application Support","JetBrains","Toolbox"),layout:"recursive"},{path:t,layout:"recursive"}];case"win32":return[{path:me(process.env.LOCALAPPDATA??me(e,"AppData","Local"),"Programs"),layout:"children"},{path:me(process.env.LOCALAPPDATA??me(e,"AppData","Local"),"JetBrains","Toolbox"),layout:"recursive"},{path:me(process.env.ProgramFiles??"C:\\Program Files","JetBrains"),layout:"children"}];default:return[{path:"/opt",layout:"children"},{path:me(e,".local","share","JetBrains","Toolbox"),layout:"recursive"},{path:t,layout:"recursive"}]}},bF=()=>qm()==="linux"?me(nS(),".local","share","JetBrains"):Ne("JetBrains"),AF=()=>qm()==="linux"&&!!(process.env.WSL_DISTRO_NAME||process.env.WSL_INTEROP),CF=async(e,t=mF)=>{let n=[];for(let r of e){if(r.layout!=="recursive"){let s;try{s=await md(r.path,{withFileTypes:!0})}catch{continue}for(let i of s.slice(0,t)){if(!i.isDirectory()&&!i.isSymbolicLink())continue;let c=me(r.path,i.name),l=r.layout==="app-bundles"?me(c,"Contents","Resources","product-info.json"):me(c,"product-info.json");await x(l)&&n.push(l)}continue}let o=0,a=async(s,i)=>{if(i<0||o>=t)return;let c=me(s,"product-info.json"),l=me(s,"Contents","Resources","product-info.json");if(await x(c)){n.push(c);return}if(await x(l)){n.push(l);return}let d;try{d=await md(s,{withFileTypes:!0})}catch{return}for(let u of d){if(o>=t)return;o+=1;let p=me(s,u.name);(u.isDirectory()||u.isSymbolicLink())&&!["bin","jbr","lib","plugins","Contents"].includes(u.name)&&await a(p,i-1)}};await a(r.path,7)}return[...new Set(n)]},kF=e=>{let t=qv(e);return t.endsWith(`${me("Contents","Resources")}`)?qv(t):t},vF=async e=>{try{let t=JSON.parse(await zm(e,"utf8"));if(!t||typeof t!="object"||typeof t.version!="string"||typeof t.dataDirectoryName!="string")return;let n=t;return!Js(n.version)||!/^[A-Za-z0-9._-]+$/.test(n.dataDirectoryName)?void 0:{version:n.version,dataDirectoryName:n.dataDirectoryName,root:kF(e)}}catch{return}},fd=async(e,t,n)=>{let r=Buffer.alloc(t),{bytesRead:o}=await e.read(r,0,t,n);return o===t?r:void 0},SF=async(e,t)=>{let n;try{n=await fF(e,"r");let{size:r}=await n.stat();if(r<Jm||r>hF)return;let o=Math.min(r,gF),a=await fd(n,o,r-o);if(!a)return;let s=-1;for(let u=a.length-Jm;u>=0;u-=1)if(a.readUInt32LE(u)===101010256){s=u;break}if(s<0)return;let i=a.readUInt32LE(s+12),c=a.readUInt32LE(s+16);if(i>yF||c+i>r)return;let l=await fd(n,i,c);if(!l)return;let d=0;for(;d+46<=l.length;){if(l.readUInt32LE(d)!==33639248)return;let u=l.readUInt16LE(d+10),p=l.readUInt32LE(d+20),m=l.readUInt32LE(d+24),f=l.readUInt16LE(d+28),h=l.readUInt16LE(d+30),w=l.readUInt16LE(d+32),y=l.readUInt32LE(d+42),g=d+46+f+h+w;if(g>l.length)return;let b=l.subarray(d+46,d+46+f).toString("utf8");if(d=g,b!==t)continue;if(p===4294967295||m===4294967295||p>Ym||m>Ym)return;let k=await fd(n,30,y);if(!k||k.readUInt32LE(0)!==67324752)return;let C=k.readUInt16LE(26),S=k.readUInt16LE(28),E=await fd(n,p,y+30+C+S);return E?u===0?E.toString("utf8"):u===8?pF(E,{maxOutputLength:Ym}).toString("utf8"):void 0:void 0}return}catch{return}finally{await n?.close().catch(()=>{})}},Qv=e=>{let t=e.match(/<id>\s*([^<]+?)\s*<\/id>/)?.[1]?.trim(),n=e.match(/<version>\s*([^<]+?)\s*<\/version>/)?.[1]?.trim();if(!(!t||!n||!Js(n)))return{id:t,version:n}},EF=async(e,t)=>{let n=me(e,"META-INF","plugin.xml");if(await x(n))try{let o=Qv(await zm(n,"utf8"));return{present:o?.id===hi||t,descriptor:o?.id===hi?o:void 0}}catch{return{present:t}}let r=[];try{r=(await md(me(e,"lib"),{withFileTypes:!0})).filter(o=>o.isFile()&&o.name.endsWith(".jar")&&/(?:^|[-_.])(ml-?llm|llm|aia|ai[-_.]?assistant)(?:[-_.]|$)/i.test(o.name)).slice(0,32).map(o=>me(e,"lib",o.name))}catch{return{present:!1}}for(let o of r){let a=await SF(o,"META-INF/plugin.xml"),s=a?Qv(a):void 0;if(s?.id===hi)return{present:!0,descriptor:s}}return{present:t&&r.length>0}},eS=async e=>{let t;try{t=await md(e,{withFileTypes:!0})}catch{return{present:!1}}let n=t.filter(o=>o.isDirectory()||o.isSymbolicLink()).sort((o,a)=>{let s=Zm.has(o.name.toLowerCase()),i=Zm.has(a.name.toLowerCase());return Number(i)-Number(s)}).slice(0,512),r=!1;for(let o of n){let a=Zm.has(o.name.toLowerCase());if(!a){let i=me(e,o.name,"META-INF","plugin.xml");if(!await x(i))continue}let s=await EF(me(e,o.name),a);if(s.descriptor)return s;s.present&&(r=!0)}return{present:r}},IF=async e=>{try{return(await zm(me(e,"disabled_plugins.txt"),"utf8")).split(/\r?\n/).map(n=>n.trim()).includes(hi)}catch{return!1}},tS=e=>e.reduce((t,n)=>t?(Xm(n,t)??-1)>0?n:t:n,void 0),rS=async(e={})=>{let t=e.configRoot??Ne("JetBrains"),n=e.userPluginsRoot??bF(),r=await CF(e.productRoots?e.productRoots.map(f=>({path:f,layout:"recursive"})):wF(),e.scanBudget),o=(await Promise.all(r.map(f=>vF(f)))).filter(f=>f!==void 0),a=o.length>0||await x(t);if(e.wsl??AF())return{installed:a,capable:!1,detail:"JetBrains AI Assistant does not support ACP in WSL; no ACP config was written."};let s=o.filter(f=>(Xm(f.version,pd)??-1)>=0),i=[],c=!1,l=!1,d=!1;for(let f of s){let h=me(t,f.dataDirectoryName);if(!await x(h)){d=!0;continue}let w=[me(h,"plugins"),me(n,f.dataDirectoryName),me(n,f.dataDirectoryName,"plugins")],y;for(let g of[...new Set(w)]){let b=await eS(g);if(b.present){y=b;break}}if(y??=await eS(me(f.root,"plugins")),y.present&&!y.descriptor){l=!0;continue}if(!(!y.descriptor||y.descriptor.id!==hi)){if(i.push(y.descriptor.version),await IF(h)){c=!0;continue}if(!((Xm(y.descriptor.version,ka)??-1)<0))return{installed:!0,capable:!0,detail:`JetBrains IDE ${f.version}; AI Assistant ${y.descriptor.version}; ACP supported`,ideVersion:f.version,pluginVersion:y.descriptor.version}}}let u=tS(o.map(f=>f.version)),p=tS(i),m;return a?u?s.length===0?m=`JetBrains IDE ${u} is below the ACP minimum ${pd}; no ACP config was written.`:d?m=`Could not prove that JetBrains AI Assistant is enabled for this user; start IDE ${pd}+ once, enable AI Assistant ${ka}+, then run Connect again. No ACP config was written.`:c?m=`JetBrains AI Assistant is disabled; enable version ${ka}+ and run Connect again. No ACP config was written.`:p?m=`JetBrains AI Assistant ${p} is below the ACP minimum ${ka}; no ACP config was written.`:l?m=`Could not verify the local JetBrains AI Assistant version; require ${ka}+ before running Connect. No ACP config was written.`:m=`JetBrains AI Assistant ${ka}+ was not found; install or enable it, then run Connect again. No ACP config was written.`:m=`Could not prove JetBrains IDE ${pd}+ from local product-info.json; no ACP config was written.`:m="JetBrains IDE config or installation not found",{installed:a,capable:!1,detail:m,ideVersion:u,pluginVersion:p}};var OF=[Gn,Vn],Qm=()=>RF(xF(),".jetbrains","acp.json"),go=()=>`${Qm()}.anyray-state`,TF=(e,t,n="npx")=>{let r=yo(e.agent_servers)?{...e.agent_servers}:{};return Object.assign(r,mi(n,"jetbrains")),{...e,agent_servers:r}},_F=(e,t,n)=>{if(!yo(e.agent_servers))return{next:e,removed:[],conflicts:[]};let r={...e.agent_servers},o=yo(t.agent_servers)?t.agent_servers:{},a=[],s=[];for(let c of OF)if(c in r){if(!ud(r[c],n[c])){s.push(c);continue}c in o?r[c]=o[c]:delete r[c],a.push(c)}let i={...e};return Object.keys(r).length>0?i.agent_servers=r:delete i.agent_servers,{next:i,removed:a,conflicts:s}},PF=(e=rS)=>({id:"jetbrains",title:"JetBrains AI Assistant",automatic:!0,async detect(){let t=await e();return{installed:t.installed,detail:t.detail}},async apply(t,n){let r=Qm(),o=await e();if(!o.capable)return{status:o.installed?"manual":"not-found",messages:[o.detail]};let a=ld();if(!a)return{status:"manual",messages:["JetBrains ACP requires Node.js with npm/npx. Install that prerequisite, then run Connect again; no ACP config was written."]};let s=[`${r} \u2190 documented JetBrains ACP custom-agent configuration`,`${o.detail}.`,"Registered Claude and Codex ACP agents with Anyray routing; no IDE proxy, certificate, DNS, or private Copilot endpoint is changed.","Claude keeps Anthropic subscription auth when selected; Codex keeps ChatGPT subscription auth when selected. Org/API mode uses the enrolled personal gateway key.","The agents appear in AI Chat after the IDE reloads. Their first launch may ask for the provider sign-in if that seat is not already authenticated.","JetBrains Copilot remains a separate closed client; its content-free usage is covered by the Copilot usage connector, not endpoint interception."];if(n.dryRun)return{status:"configured",messages:s};let i=await x(r),c;try{c=await M(r)}catch{return{status:"manual",messages:[`Refused to overwrite malformed ${r}; fix or replace the file, then run Connect again.`]}}let l=mi(a,"jetbrains");return await tc({configPath:r,current:c,next:TF(c,t,a),journalPath:go(),journal:{version:2,fileExisted:i,entries:l},fileExisted:i}),{status:"configured",messages:s,changedFiles:[r,go()]}},async revert(t){let n=Qm(),r=async()=>{if(!await x(n))return t.dryRun||(await ie(n),await hd(go(),{force:!0}).catch(()=>{})),{status:"reverted",messages:["No JetBrains ACP config to remove."]};let o;try{o=await M(n)}catch{return t.dryRun||(await ie(n),await hd(go(),{force:!0}).catch(()=>{})),{status:"manual",messages:[`Could not parse ${n}; remove the two \u201CAnyray \xB7 \u2026\u201D agent entries manually.`]}}let a={},s=!1,i=!1;try{let u=await M(go());(u.version===1||u.version===2)&&yo(u.entries)&&(a=u.entries,s=u.version===2&&u.fileExisted===!1,i=u.version===2&&u.fileExisted===!0)}catch{}let c;if(i){let u=`${n}.anyray-bak`;if(!await x(u))return{status:"manual",messages:[`Refused to remove JetBrains ACP entries because the original backup for ${n} is missing. Restore or remove the entries manually.`]};try{c=await M(u)}catch{return{status:"manual",messages:[`Refused to remove JetBrains ACP entries because the original backup for ${n} is malformed. Repair it or remove the entries manually.`]}}}else c=await Mr(n);let l=_F(o,c,a),d=[];return l.removed.length&&d.push(`Removed ${l.removed.join(", ")} from ${n}.`),l.conflicts.length&&d.push(`Preserved user-modified ACP entries: ${l.conflicts.join(", ")}.`),!t.dryRun&&l.removed.length&&(s&&Object.keys(l.next).length===0?await hd(n,{force:!0}):await J(n,l.next,{backup:!1})),t.dryRun||(await ie(n),await hd(go(),{force:!0}).catch(()=>{})),{status:l.conflicts.length?"manual":"reverted",messages:d.length?d:["No Anyray ACP entries found."],changedFiles:!t.dryRun&&l.removed.length?[n]:void 0}};return t.dryRun?r():ec(n,go(),r)}}),oS=PF();import{homedir as gd}from"node:os";import{join as wd}from"node:path";import{rm as eh}from"node:fs/promises";var th="1.0.0",bd=["anyray-claude-acp","anyray-codex-acp"],DF=["darwin-aarch64","darwin-x86_64","linux-aarch64","linux-x86_64","windows-aarch64","windows-x86_64"],nh=()=>wd(gd(),".windsurf","acp","registry.json"),rh=()=>wd(gd(),".windsurf-next","acp","registry.json"),va=e=>`${e}.anyray-state`,aS=e=>({binary:Object.fromEntries(DF.map(t=>[t,{archive:"",cmd:e.command,args:e.args}]))}),iS=(e="npx")=>{let t=mi(e,"windsurf");return[{id:bd[0],name:Gn,version:"1.0.0",description:"Claude through the Anyray gateway via ACP",authors:["Anyray","Agent Client Protocol"],license:"Apache-2.0",distribution:aS(t[Gn])},{id:bd[1],name:Vn,version:"1.0.0",description:"Codex through the Anyray gateway via ACP",authors:["Anyray","Agent Client Protocol"],license:"Apache-2.0",distribution:aS(t[Vn])}]},yd=e=>!Array.isArray(e)||e.some(t=>!yo(t)||typeof t.id!="string")?null:e,LF=(e,t="npx")=>{if(e.version!==void 0&&e.version!==th||e.extensions!==void 0&&!Array.isArray(e.extensions))return null;let n=e.agents===void 0?[]:yd(e.agents);if(!n)return null;let r=new Set(bd);return{...e,version:typeof e.version=="string"?e.version:th,agents:[...n.filter(o=>!r.has(o.id)),...iS(t)],extensions:e.extensions??[]}},NF=(e,t,n)=>{let r=yd(e.agents);if(!r)return null;let o=yd(t.agents)??[],a=new Map((yd(n)??[]).map(u=>[u.id,u])),s=new Map(o.map(u=>[u.id,u])),i=[],c=[],l=[];for(let u of r){if(!bd.includes(u.id)){l.push(u);continue}if(!ud(u,a.get(u.id))){c.push(u.id),l.push(u);continue}let p=s.get(u.id);p&&l.push(p),i.push(u.id)}let d={...e,agents:l};return!Object.prototype.hasOwnProperty.call(t,"agents")&&l.length===0&&delete d.agents,!Object.prototype.hasOwnProperty.call(t,"version")&&d.version===th&&delete d.version,!Object.prototype.hasOwnProperty.call(t,"extensions")&&Array.isArray(d.extensions)&&d.extensions.length===0&&delete d.extensions,{next:d,removed:i,conflicts:c}},sS=async()=>{let e=[];return(await x(rh())||await x(wd(gd(),".windsurf-next")))&&e.push(rh()),(await x(nh())||await x(wd(gd(),".windsurf"))||await x(Ne("Devin"))||await x(Ne("Windsurf")))&&e.push(nh()),e},cS={id:"windsurf",title:"Devin Desktop",automatic:!0,async detect(){let e=await sS();return e.length?{installed:!0,detail:e.join(", ")}:{installed:!1,detail:"Devin Desktop not found"}},async apply(e,t){let n=await sS();if(!n.length)return{status:"not-found",messages:["Devin Desktop is not installed; no ACP registry was written."]};let r=ld();if(!r)return{status:"manual",messages:["Devin ACP requires Node.js with npm/npx. Install that prerequisite, then run Connect again; no ACP registry was written."]};let o=[],a=[];for(let s of n){let i;try{i=await M(s)}catch{o.push(`Refused to overwrite malformed ${s}; fix or replace the file, then run Connect again.`);continue}let c=LF(i,r);if(!c){o.push(`Refused unrecognized ACP registry shape in ${s}.`);continue}if(o.push(`${s} \u2190 registered Anyray Claude and Codex ACP agents.`),!t.dryRun){let l=await x(s),d=iS(r);await tc({configPath:s,current:i,next:c,journalPath:va(s),journal:{version:2,fileExisted:l,agents:d},fileExisted:l}),a.push(s,va(s))}}return o.push("Devin requires a one-time vendor UI enablement for local registry agents: Devin Settings \u2192 Agents \u2192 enable the two Anyray agents, then restart Devin Desktop."),o.push("Native Devin/Cascade subscription requests are not redirected. The official enterprise consumption connector imports content-free usage instead."),o.push("No proxy, certificate, DNS, DEVIN_API_URL, or private first-party endpoint was changed."),{status:"manual",messages:o,changedFiles:a.length?a:void 0}},async revert(e){let t=[nh(),rh()],n=[],r=[],o=!1;for(let a of t){let s=async()=>{if(!await x(a)){e.dryRun||(await ie(a),await eh(va(a),{force:!0}).catch(()=>{}));return}let i;try{i=await M(a)}catch{n.push(`Could not parse ${a}; remove the anyray-* ACP agents manually.`),o=!0;return}let c=[],l=!1,d=!1;try{let m=await M(va(a));(m.version===1||m.version===2)&&Array.isArray(m.agents)&&(c=m.agents,l=m.version===2&&m.fileExisted===!1,d=m.version===2&&m.fileExisted===!0)}catch{}let u;if(d){let m=`${a}.anyray-bak`;if(!await x(m)){n.push(`Refused to remove Devin ACP agents because the original backup for ${a} is missing. Restore it or remove the agents manually.`),o=!0;return}try{u=await M(m)}catch{n.push(`Refused to remove Devin ACP agents because the original backup for ${a} is malformed. Repair it or remove the agents manually.`),o=!0;return}}else u=await Mr(a);let p=NF(i,u,c);if(!p){n.push(`Unrecognized ACP registry shape in ${a}; left it unchanged.`),o=!0;return}p.removed.length&&(n.push(`Removed ${p.removed.join(", ")} from ${a}.`),e.dryRun||(l&&Object.keys(p.next).length===0?await eh(a,{force:!0}):await J(a,p.next,{backup:!1}),r.push(a))),p.conflicts.length?(n.push(`Preserved user-modified agents: ${p.conflicts.join(", ")}.`),o=!0):e.dryRun||(await ie(a),await eh(va(a),{force:!0}).catch(()=>{}))};e.dryRun?await s():await ec(a,va(a),s)}return{status:o?"manual":"reverted",messages:n.length?n:["No Anyray Devin ACP agents found."],changedFiles:r.length?r:void 0}}};var pe=[rr,eb,Ps,nC,OC,UC,YC,oS,Vv,cS,cb],mt=e=>pe.find(t=>t.id===e);var Ue=async(e=P,t=yn)=>{let n=await e();if(!n.gateway||!n.clientKey)return;let r=await t().catch(()=>{});return{target:Ee({origin:n.gateway,clientKey:n.clientKey,subscription:n.authMode==="subscription",placeholder:n.authMode==="placeholder",byoUpstream:n.byoUpstream,seat:r,user:n.name,team:n.team})}};var oh=5e3,lS=3e4,$F=1440*60*1e3,MF=e=>new Promise(t=>setTimeout(t,e)),BF=async(e=P,t=yn)=>(await Ue(e,t))?.target,FF=e=>mt(e)?.quitGated,dS=async(e,t={})=>{let n=e[0];if(!n)return 0;let r=t.resolveSeam??FF,o=t.readPending??Yc,a=t.clearPending??Gp,s=t.targetFromProfile??BF,i=t.sleep??MF,c=t.now??Date.now,l=t.maxWaitMs??$F;try{let d=r(n);if(!d?.complete)return await a(n),0;let u=d.complete.bind(d),p=c(),m=oh;for(;;){let f=await o(n);if(!f||c()-p>l)return 0;if(d.isRunning()){await i(m),m=Math.min(lS,m*2);continue}let h;if(d.needsTarget?.(f.op)&&(h=await s(),!h)){if(await a(n,f)!=="superseded")return 0;await i(m),m=oh;continue}if((await u(f.op,h,{dryRun:!1,preservePendingOp:!0})).status==="queued"){await i(m),m=Math.min(lS,m*2);continue}if(await a(n,f)!=="superseded")return 0;await i(m),m=oh}}catch{return 0}};import{writeFileSync as xW}from"node:fs";import{chmod as yh,stat as RW}from"node:fs/promises";import{platform as US}from"node:os";import{dirname as HS,isAbsolute as OW}from"node:path";var WF="https://app.anyray.ai",UF=new Set(["localhost","::1","[::1]"]),HF=/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/,GF=e=>UF.has(e)||HF.test(e),ah=e=>{let t;try{t=new URL(e)}catch{return!1}return t.protocol==="https:"?!0:t.protocol==="http:"&&GF(t.hostname)},VF=e=>{let t=e.length;for(;t>0&&e[t-1]==="/";)t-=1;return e.slice(0,t)},Kn=()=>{let e=process.env.ANYRAY_CP_ORIGIN?.trim();return!e||!ah(e)?WF:VF(e)};import{createHash as rW,generateKeyPairSync as oW,randomBytes as ch}from"node:crypto";import{createPrivateKey as KF,sign as jF}from"node:crypto";var Ir=async(e,t)=>{let n=KF(t);return jF(null,new TextEncoder().encode(e),n).toString("base64url")};var ZF=["HTTPS_PROXY","https_proxy"],uS=new Set(["SELF_SIGNED_CERT_IN_CHAIN","DEPTH_ZERO_SELF_SIGNED_CERT","UNABLE_TO_VERIFY_LEAF_SIGNATURE","UNABLE_TO_GET_ISSUER_CERT","UNABLE_TO_GET_ISSUER_CERT_LOCALLY","CERT_UNTRUSTED"]),pS=new Set(["CERT_HAS_EXPIRED","CERT_NOT_YET_VALID","ERR_TLS_CERT_ALTNAME_INVALID","ERR_SSL_WRONG_VERSION_NUMBER","EPROTO"]),fS=new Set(["ENOTFOUND","EAI_AGAIN"]),mS=new Set(["ECONNREFUSED","ECONNRESET","EPIPE","ENETDOWN","ENETUNREACH","EHOSTUNREACH","EHOSTDOWN"]),hS=new Set(["ETIMEDOUT","UND_ERR_CONNECT_TIMEOUT","UND_ERR_HEADERS_TIMEOUT","UND_ERR_BODY_TIMEOUT"]),YF=e=>{let t=e;for(let n=0;n<5&&t;n++){let r=t.code;if(typeof r=="string"&&r)return r;t=t.cause}return JF(e)},JF=e=>{let t=e?.message;if(!(typeof t!="string"||!t)){for(let n of[...uS,...pS,...fS,...mS,...hS])if(t.includes(n))return n}},XF=e=>e?.name==="AbortError"||e?.name==="TimeoutError",zF=e=>ZF.filter(t=>(e[t]??"").trim()!==""),qF=(e,t=process.env)=>{let n=YF(e),r=zF(t);return{kind:n&&uS.has(n)?"tls-unknown-issuer":n&&pS.has(n)?"tls-invalid-cert":n&&fS.has(n)?"dns":XF(e)||n&&hS.has(n)?"timeout":n&&mS.has(n)?"refused":"unknown",...n?{code:n}:{},proxyVars:r}},QF=e=>{let t=e.proxyVars.length>0?` ${e.proxyVars.join(" and ")} ${e.proxyVars.length>1?"are":"is"} set \u2014 if that proxy is stale or unreachable, unset it and re-run.`:"";switch(e.kind){case"tls-unknown-issuer":return` (TLS certificate signed by an unknown authority: ${e.code}). Your network appears to inspect TLS traffic. curl trusts your system keychain and this binary does not, which is why the download worked and this step did not. Point NODE_EXTRA_CA_CERTS at your organization root certificate (PEM) and re-run.`+t;case"tls-invalid-cert":return` (TLS certificate rejected: ${e.code}). Check this machine's clock and date, and whether a proxy is rewriting HTTPS traffic, then re-run.`+t;case"dns":return` (DNS lookup failed: ${e.code}). Check your VPN or DNS, then re-run.`+t;case"refused":return` (connection failed: ${e.code}).`+(t||" Check your network or firewall, then re-run.");case"timeout":return" (timed out before the control plane answered)."+(t||" Check your connection and re-run.");default:return e.code?` (${e.code}).${t}`:t}},ht=(e,t=process.env)=>QF(qF(e,t));var eW="enl_",yS="enp_",gS=e=>e.startsWith(eW)||e.startsWith(yS),sh=e=>e.startsWith(yS),tW=[{prefix:"tnt_",flag:"--sso",what:"an SSO link"},{prefix:"sdc_",flag:"--claim",what:"a one-time enrollment code"}],ih=e=>tW.find(t=>e.startsWith(t.prefix)),wS=/^\/enroll\/([^/]+)\/?$/,bS=/^\/i\/([^/]+)\/?$/,AS=e=>{let t=e.match(wS);if(t)return ih(t[1])?void 0:t[1];let n=e.match(bS);return n&&gS(n[1])?n[1]:void 0},nW=1e4,Ad=e=>{let t=e.trim();if(!t)return;let n;try{n=new URL(t)}catch{n=void 0}if(n){if(n.protocol!=="http:"&&n.protocol!=="https:")return;let r=AS(n.pathname);return r?{cpOrigin:n.origin,token:r}:void 0}if(!ih(t))return{cpOrigin:Kn(),token:t}},CS=e=>{let t=e.trim();if(!t)return;let n=t;try{let o=new URL(t),a=o.pathname.match(wS)??o.pathname.match(bS);if(!a)return;n=a[1]}catch{}let r=ih(n);return r?{flag:r.flag,what:r.what}:void 0},gi=e=>{let t=e.trim();if(!t)return!1;try{let n=new URL(t);return n.protocol!=="http:"&&n.protocol!=="https:"?!1:AS(n.pathname)!==void 0}catch{return gS(t)}},Sa=class extends Error{constructor(t){super(t),this.name="EnrollmentPermanentError"}},yi=e=>typeof e=="string"&&e.trim()?e.trim():void 0,kS=async(e,t={})=>{let n=t.timeoutMs??nW,r=`${e.cpOrigin}/enroll-info/${e.token}`,o=new AbortController,a=setTimeout(()=>o.abort(),n),s;try{s=await fetch(r,{method:"GET",signal:o.signal})}catch(u){let p=u instanceof Error&&u.name==="AbortError"?` no response within ${n}ms.`:ht(u);throw new Error(`could not reach the enrollment page at ${e.cpOrigin}.${p}`)}finally{clearTimeout(a)}if(!s.ok){let u=`enrollment link lookup failed: ${e.cpOrigin} responded ${s.status} \u2014 the link may be expired or revoked; ask your admin for a fresh one.`;throw s.status>=400&&s.status<500&&s.status!==429?new Sa(u):new Error(u)}let i;try{i=await s.json()}catch{throw new Error(`enrollment link lookup failed: ${e.cpOrigin} returned a malformed response`)}let l=(Array.isArray(i?.gateways)?i.gateways:[]).find(u=>u!==null&&typeof u=="object"&&yi(u.url)!==void 0),d=yi(l?.url);if(!d)throw new Error(i.connected===!0?"this enrollment link's gateway is running but hasn't advertised its public URL yet \u2014 ask your admin to set ANYRAY_GATEWAY_PUBLIC_URL (Helm: gateway.publicUrl), then re-run.":"this enrollment link has no gateway configured yet \u2014 ask your admin to confirm the gateway is deployed, then re-run.");return{gatewayUrl:d,deploymentId:yi(l?.deploymentId),org:yi(i.org),email:yi(i.email),seatMode:i.seatMode===!0,...i.provisioningKind==="manual"||i.provisioningKind==="mdm"?{provisioningKind:i.provisioningKind}:{},...i.provisioningProofMode==="managed-preference"?{provisioningProofMode:i.provisioningProofMode}:{},...Array.isArray(i.allowedDomains)?{allowedDomains:i.allowedDomains.filter(u=>typeof u=="string"&&u.length>0)}:{}}};var ke="0.11.186";var lh=1e4,wo=e=>e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(wo).join(",")}]`:`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${wo(e[n])}`).join(",")}}`,vS="stable-key-heartbeat-v1",SS="key-heartbeat",aW=["reapply_config","remint","revert"],dh=(e,t)=>t&&e.payload.source==="mdm"?{machineUuid:t}:{};var ES=e=>rW("sha256").update(e).digest("hex"),je=e=>typeof e=="string"&&e.trim()?e.trim():void 0,sW=e=>Array.isArray(e)?e.filter(t=>typeof t=="string"&&/^[a-z0-9-]{1,64}$/.test(t)):[],IS={no_mdm_server_registered:"no MDM server is registered in the Anyray console",agent_missing:"the Anyray endpoint agent is not reporting for this machine",mdm_not_verified:"this machine is not enrolled in the registered MDM",endpoint_unreachable:"the endpoint service could not be reached"},iW=e=>`This organization requires a managed (MDM-enrolled) device for this enrollment: ${IS[e]}. Ask your IT admin.`,cW=e=>typeof e=="string"&&e in IS,uh=async e=>{try{let t=await e.json(),n=je(t?.message),r=je(t?.error),o=cW(t?.reason)?t.reason:void 0;if(r==="managed_device_required"&&o)return{message:iW(o),code:r,reason:o};if(n)return{message:n,...r?{code:r}:{}}}catch{}return{message:`gateway responded ${e.status}`}},lW=async e=>(await uh(e)).message,lt=class extends Error{status;policyCode;reason;constructor(t,n){let r=typeof n=="string"?{message:n}:n;super(r.code==="managed_device_required"?r.message:`the gateway rejected this enrollment (HTTP ${t}): ${r.message}`),this.name="GatewayVerifyError",this.status=t,this.policyCode=r.code,this.reason=r.reason}},xS=e=>e instanceof Sa||e instanceof lt&&e.policyCode==="sso_required",Ea=class extends Error{status;policyCode;reason;constructor(t,n){let r=typeof n=="string"?{message:n}:n;super(r.code==="managed_device_required"?r.message:`the gateway rejected this credential heartbeat (HTTP ${t}): ${r.message}`),this.name="GatewayHeartbeatError",this.status=t,this.policyCode=r.code,this.reason=r.reason}},ph=async(e,t,n,r)=>{try{return await r(wo(e),t)}catch{throw new Error(`developer ${n} failed: could not sign the challenge with the provided private key`)}},Cd=()=>{let{publicKey:e,privateKey:t}=oW("ed25519",{publicKeyEncoding:{type:"spki",format:"pem"},privateKeyEncoding:{type:"pkcs8",format:"pem"}});return{publicKeyPem:e,privateKeyPem:t}},Qt=async(e,t,n,r={})=>{let o=r.timeoutMs??lh,a=`${e}/connect/verify`,s=je(t?.payload?.deploymentId);if(!s)throw new Error("developer verification failed: the cert is missing payload.deploymentId");let i={deploymentId:s,issuedAt:new Date().toISOString(),nonce:ch(16).toString("hex"),...dh(t,r.machineUuid)},c=await ph(i,n,"verification",r.signer??Ir),l=new AbortController,d=setTimeout(()=>l.abort(),o),u;try{u=await fetch(a,{method:"POST",headers:{"content-type":"application/json","x-anyray-connect-version":ke},body:JSON.stringify({cert:t,challenge:i,sig:c,...r.health?{health:r.health}:{},...r.ack?{ack:r.ack}:{},...r.telemetryOnly?{telemetryOnly:!0}:{}}),signal:l.signal})}catch(g){let b=g instanceof Error&&g.name==="AbortError"?` no response within ${o}ms.`:ht(g);throw new Error(`could not reach the gateway at ${a}.${b}`,{cause:g})}finally{clearTimeout(d)}if(!u.ok)throw new lt(u.status,await uh(u));let p;try{p=await u.text()}catch{p=""}let m;try{m=JSON.parse(p)}catch{let g=u.headers.get("content-type")??"",b=/\btext\/html\b/i.test(g)||/^\s*<(?:!doctype|html)/i.test(p);throw new Error(b?`developer verification failed: ${a} returned an HTML page, not the gateway \u2014 /connect/* is being routed to the console/proxy. Ask your admin to route /connect/* to the gateway service (:8787), the same as /v1/*.`:"developer verification failed: the gateway returned a malformed response")}let f=je(m?.key);if(!f)throw new Error("developer verification failed: the gateway response is missing the key");if(!/^[A-Za-z0-9._-]{1,256}$/.test(f))throw new Error("developer verification failed: the gateway returned a malformed key");let h=je(m.user);if(!h)throw new Error("developer verification failed: the gateway response is missing the user");let w=dW(m.directive),y=sW(m.capabilities);return{key:f,user:h,team:je(m.team),expiresAt:je(m.expiresAt),...y.length>0?{capabilities:y}:{},...w?{directive:w}:{}}},RS=async(e,t,n,r,o={})=>{let a=o.timeoutMs??lh,s=`${e}/connect/key/heartbeat`,i=je(n?.payload?.deploymentId);if(!i)throw new Error("developer heartbeat failed: the cert is missing payload.deploymentId");let c={deploymentId:i,issuedAt:new Date().toISOString(),nonce:ch(16).toString("hex"),purpose:SS,...dh(n,o.machineUuid)},l=await ph(c,r,"heartbeat",o.signer??Ir),d=new AbortController,u=setTimeout(()=>d.abort(),a),p;try{p=await fetch(s,{method:"POST",headers:{"content-type":"application/json","x-anyray-api-key":t,"x-anyray-connect-version":ke},body:JSON.stringify({cert:n,challenge:c,sig:l}),signal:d.signal})}catch(h){let w=h instanceof Error&&h.name==="AbortError"?` no response within ${a}ms.`:ht(h);throw new Error(`could not reach the gateway at ${s}.${w}`,{cause:h})}finally{clearTimeout(u)}if(!p.ok)throw new Ea(p.status,await uh(p));let m;try{m=await p.json()}catch{throw new Error("developer heartbeat failed: the gateway returned a malformed response")}let f=je(m.expiresAt);if(!f||!Number.isFinite(Date.parse(f))||m.credentialMode!==vS||m.key!==void 0)throw new Error("developer heartbeat failed: the gateway returned an unexpected response");return{expiresAt:f,credentialMode:vS}},OS=async(e,t,n,r,o,a={})=>{let s=a.timeoutMs??lh,i=`${e.replace(/\/$/,"")}/connect/machine`,c=je(n?.payload?.deploymentId);if(!c||!o)return!1;let l={deploymentId:c,issuedAt:new Date().toISOString(),nonce:ch(16).toString("hex"),purpose:SS,...dh(n,o)},d=await ph(l,r,"heartbeat",a.signer??Ir),u=new AbortController,p=setTimeout(()=>u.abort(),s);try{return(await fetch(i,{method:"POST",headers:{"content-type":"application/json","x-anyray-api-key":t,"x-anyray-connect-version":ke},body:JSON.stringify({cert:n,challenge:l,sig:d,machineUuid:o}),signal:u.signal})).ok}catch(m){return console.error("connect machine report skipped:",m instanceof Error?m.name:"error"),!1}finally{clearTimeout(p)}},dW=e=>{if(e===null||typeof e!="object")return null;let t=e,n=je(t.id),r=t.kind;return!n||!/^[A-Za-z0-9_-]{1,128}$/.test(n)||typeof r!="string"||!aW.includes(r)?null:{id:n,kind:r}},uW=1e4,pW=e=>{if(e===null||typeof e!="object")return!1;let t=e;if(t.alg!=="Ed25519"||!je(t.sig))return!1;let n=t.payload;if(n===null||typeof n!="object")return!1;let r=n;return typeof r.v=="number"&&!!je(r.deploymentId)&&!!je(r.user)&&!!je(r.devPublicKey)&&!!je(r.issuedAt)&&!!je(r.expiresAt)},fW=async(e,t,n,r={},o={})=>{let a=o.timeoutMs??uW,s=`${e}/v1/enroll`,i=new AbortController,c=setTimeout(()=>i.abort(),a),l;try{l=await fetch(s,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({token:t,devPublicKey:n,...r.email?{email:r.email}:{},...r.team?{team:r.team}:{},...r.machineId?{machineId:r.machineId}:{},...r.deploymentId?{deploymentId:r.deploymentId}:{}}),signal:i.signal})}catch(u){let p=u instanceof Error&&u.name==="AbortError"?` no response within ${a}ms.`:ht(u);throw new Error(`could not reach the control plane at ${s}.${p}`)}finally{clearTimeout(c)}if(!l.ok){let u=`enrollment failed: ${await lW(l)}`;throw l.status>=400&&l.status<500&&l.status!==429?new Sa(u):new Error(u)}let d;try{d=await l.json()}catch{throw new Error("enrollment failed: the control plane returned a malformed response")}if(!pW(d))throw new Error("enrollment failed: the control plane returned an unexpected cert shape");return d},TS=(e,t,n,r,o,a,s)=>{if(!e)return!1;let i=t?Date.parse(t):NaN;return!(!Number.isFinite(i)||i<=r||n&&e.payload.deploymentId!==n||o&&o!==a||s&&e.payload.user.trim().toLowerCase()!==s.trim().toLowerCase())},_S=async e=>{let t={timeoutMs:e.timeoutMs,machineUuid:e.machineUuid,signer:e.signer},{cert:n,privateKeyPem:r,publicKeyPem:o}=e.reuse?e.reuse:await(async()=>{let s=Cd();return{cert:await fW(e.cpOrigin,e.token,s.publicKeyPem,{email:e.email,team:e.team,machineId:e.machineId,deploymentId:e.deploymentId},t),...s}})(),a=await Qt(e.gatewayOrigin,n,r,t);return{clientKey:a.key,user:a.user,team:a.team,expiresAt:a.expiresAt,...a.capabilities?{capabilities:a.capabilities}:{},cert:n,privateKeyPem:r,publicKeyPem:o}};var fh=1e4,mW=900*1e3,DS="tnt_",hW=/^\/sso\/([^/]+)\/?$/,yW=/^\/i\/([^/]+)\/?$/,gW=e=>{let t=e.match(hW);if(t)return t[1];let n=e.match(yW);return n?.[1].startsWith(DS)?n[1]:void 0},Et=e=>{let t=e.trim();if(!t)return;let n;try{n=new URL(t)}catch{n=void 0}if(n){if(n.protocol!=="http:"&&n.protocol!=="https:")return;let r=gW(n.pathname);return r?{cpOrigin:n.origin,tenantId:r}:void 0}if(t.startsWith(DS))return{cpOrigin:Kn(),tenantId:t}},bo=class extends Error{kind;status;constructor(t,n,r){super(n),this.name="SsoStartError",this.kind=t,this.status=r}},Bt=class extends Error{kind;constructor(t,n){super(n),this.name="SsoPollError",this.kind=t}},mh=async(e,t,n,r)=>{let o=new AbortController,a=setTimeout(()=>o.abort(),n);try{let s=await r(e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t),signal:o.signal}),i={};try{i=await s.json()}catch{}return{status:s.status,json:i}}finally{clearTimeout(a)}},wW=e=>new Promise(t=>setTimeout(t,e)),kd=async e=>{let t=e.now??Date.now,n=e.fetch??fetch,{publicKeyPem:r,privateKeyPem:o}=(e.generateKeypair??Cd)(),a;try{a=await mh(`${e.cpOrigin}/sso/device`,{tenantId:e.tenantId,devPublicKey:r},fh,n)}catch(f){throw new bo("cp-unreachable",`could not reach the control plane at ${e.cpOrigin}${ht(f)}`)}if(a.status!==200){let f=a.status===404,h=typeof a.json.error=="string"?a.json.error:`status ${a.status}`;throw new bo(f?"sso-unavailable":"cp-unreachable",`SSO is not available for this organization (${h}). Ask your admin to confirm SSO is configured.`,a.status)}let s=a.json;if(!s.device_code||!s.user_code||!s.verification_uri_complete)throw new bo("cp-unreachable","SSO start failed: the control plane returned an incomplete response.");let i=t(),c=e.deadlineMs??mW,l=typeof s.expires_in=="number"&&s.expires_in>0?s.expires_in*1e3:c,d=typeof s.verification_uri=="string"?s.verification_uri:void 0,u=e.gatewayUrl??(typeof s.gateway_url=="string"?s.gateway_url:void 0),p={cpOrigin:e.cpOrigin,tenantId:e.tenantId,deviceCode:s.device_code,userCode:s.user_code,verificationUri:d,verificationUriComplete:s.verification_uri_complete,intervalMs:Math.max(1,s.interval||5)*1e3,grantExpiresAt:i+Math.min(c,l),startedAt:i,privateKeyPem:o,publicKeyPem:r,gatewayUrl:u},m=e.log??(()=>{});return m("To finish, sign in with your organization at:"),m(` ${p.verificationUriComplete}`),m(`Confirm this code matches your browser: ${p.userCode}`),bW(p.verificationUriComplete,e.cpOrigin)&&e.open?.(p.verificationUriComplete),p},bW=(e,t)=>{try{return new URL(e).origin===new URL(t).origin}catch{return!1}},vd=async(e,t={})=>{let n=t.now??Date.now,r=t.sleep??wW,o=t.fetch??fetch,a=t.pollIntervalMs??e.intervalMs;for(;n()<e.grantExpiresAt&&(await r(Math.min(a,e.grantExpiresAt-n())),!(n()>=e.grantExpiresAt));){let s;try{s=await mh(`${e.cpOrigin}/sso/device/token`,{deviceCode:e.deviceCode,devPublicKey:e.publicKeyPem},fh,o)}catch(c){throw new Bt("cp-unreachable",`could not reach the control plane at ${e.cpOrigin}${ht(c)}`)}if(s.status===200&&s.json.cert)return{cert:s.json.cert,privateKeyPem:e.privateKeyPem,gatewayUrl:t.gatewayUrl??(typeof s.json.gatewayUrl=="string"?s.json.gatewayUrl:e.gatewayUrl),deploymentId:typeof s.json.deploymentId=="string"?s.json.deploymentId:""};let i=typeof s.json.error=="string"?s.json.error:"";if(i!=="authorization_pending"){if(i==="slow_down"){a+=5e3;continue}throw i==="expired_token"?new Bt("expired","SSO sign-in timed out before you finished. Re-run anyray-connect --sso to try again."):new Bt("denied","SSO sign-in was not completed. Re-run anyray-connect --sso to try again.")}}throw new Bt("expired","SSO sign-in timed out. Re-run anyray-connect --sso to try again.")};var PS="sdc_",LS=e=>{let t=e.trim();if(!t)return;if(t.startsWith(PS))return{cpOrigin:Kn(),claim:t};let n;try{n=new URL(t)}catch{return}if(!ah(n.origin))return;let r=n.searchParams.get("claim")?.trim();if(!(!r||!r.startsWith(PS)))return{cpOrigin:n.origin,claim:r}},NS=async e=>{let t=e.fetch??fetch,{publicKeyPem:n,privateKeyPem:r}=(e.generateKeypair??Cd)(),o;try{o=await mh(`${e.cpOrigin}/sso/device/token`,{deviceCode:e.claim,devPublicKey:n},fh,t)}catch(s){throw new Bt("cp-unreachable",`could not reach the control plane at ${e.cpOrigin}${ht(s)}`)}if(o.status===200&&o.json.cert)return{cert:o.json.cert,privateKeyPem:r,gatewayUrl:e.gatewayUrl??(typeof o.json.gatewayUrl=="string"?o.json.gatewayUrl:void 0),deploymentId:typeof o.json.deploymentId=="string"?o.json.deploymentId:"",...typeof o.json.ssoLink=="string"&&o.json.ssoLink?{ssoLink:o.json.ssoLink}:{}};let a=typeof o.json.error=="string"?o.json.error:"";throw a==="expired_token"?new Bt("expired","This enrollment link has expired. Open your organization\u2019s Anyray link again to get a new one."):a==="authorization_pending"?new Bt("denied","This enrollment link is not ready yet. Finish signing in in your browser, then run the command it gives you."):new Bt("denied","This enrollment link was already used or is not valid. Open your organization\u2019s Anyray link again to get a new one.")};import{readFile as AW}from"node:fs/promises";import{isAbsolute as CW,posix as $S,win32 as hh}from"node:path";var wi=(e=process.platform,t=process.env)=>e==="darwin"?$S.join("/Library","Application Support","Anyray","bootstrap.json"):e==="win32"?hh.join(t.ProgramData??"C:\\ProgramData","Anyray","bootstrap.json"):$S.join("/etc","anyray","bootstrap.json"),kW=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),MS=e=>typeof e=="string"&&e.length>0&&e.length<=512&&[...e].every(t=>{let n=t.charCodeAt(0);return n>=32&&n!==127})&&(CW(e)||hh.isAbsolute(e))&&!/ark_[A-Za-z0-9_-]{20,}|-----BEGIN/.test(e),vW=e=>{if(typeof e!="string"||e.length===0||e.length>512)return!1;try{let t=new URL(e);return(t.protocol==="https:"||t.protocol==="http:")&&!t.username&&!t.password}catch{return!1}},xr=async(e=wi())=>{try{let t=await AW(e,"utf-8");if(t.length>4096)return;let n=JSON.parse(t);if(!kW(n)||n.v!==1||typeof n.sso!="string")return;let r=Et(n.sso);if(!r)return;let o=vW(n.gateway)?n.gateway:void 0,a=MS(n.bin)?n.bin:void 0;return{sso:`${r.cpOrigin}/sso/${r.tenantId}`,gateway:o,bin:a}}catch{return}},BS=(e,t,n)=>{let r=Et(e);if(!r)throw new Error("invalid --sso link");if(n!==void 0&&!MS(n))throw new Error("--bin must be an absolute fleet-stable path");if(n!==void 0&&hh.isAbsolute(n)&&/^[A-Za-z]:\\/.test(n)&&!/^[A-Za-z]:\\Program Files( \(x86\))?\\/i.test(n))throw new Error("--bin on Windows must live under Program Files (admin-only writable)");return`${JSON.stringify({v:1,sso:`${r.cpOrigin}/sso/${r.tenantId}`,...t?{gateway:t}:{},...n?{bin:n}:{}},null,2)}
|
|
262
|
+
`};var Ia=(e,t)=>t.NO_COLOR?!1:t.FORCE_COLOR&&t.FORCE_COLOR!=="0"?!0:!!e.isTTY,Sd=Ia(process.stdout,process.env),FS=Ia(process.stderr,process.env),xa=(e,t,n)=>n?`\x1B[${e}m${t}\x1B[0m`:t,K=e=>xa("1",e,Sd),v=e=>xa("2",e,Sd),SW=e=>xa("32",e,Sd),EW=e=>xa("33",e,FS),IW=e=>xa("31",e,FS),qe=e=>xa("36",e,Sd),A=e=>console.log(e),H=e=>console.log(`
|
|
263
|
+
${K(e)}`),L=e=>console.log(v(e)),B=e=>console.log(`${SW("\u2713")} ${e}`),O=e=>console.error(`${EW("!")} ${e}`),R=e=>console.error(`${IW("\u2717")} ${e}`);var gh=`${K("anyray-connect managed")} \u2014 fleet-wide Claude Code routing via managed-settings.json
|
|
264
264
|
|
|
265
265
|
Emit or install the OS \`managed-settings.json\` that points a managed fleet's
|
|
266
266
|
Claude Code at the Anyray gateway. It reads at a HIGHER precedence than a user's
|
|
@@ -343,15 +343,15 @@ ${K("Examples")}
|
|
|
343
343
|
anyray-connect managed --print --tool jetbrains --bin /usr/local/bin/anyray-connect --npx /usr/local/bin/npx > acp.json
|
|
344
344
|
|
|
345
345
|
# Shell/SDK fleet snippet (base URLs only; keys stay per-user):
|
|
346
|
-
anyray-connect managed --print --tool shell --gateway https://gw.acme.com > /tmp/anyray.sh # deploy to /etc/profile.d`,WS=["claude-code","jetbrains","shell","bootstrap"],
|
|
347
|
-
`)},Id=(e,t)=>{if(e.out===void 0){process.stdout.write(t);return}
|
|
348
|
-
`),
|
|
349
|
-
`),Ze(v("# acp.json for ~/.jetbrains/acp.json (per user).")),Ze(v(`# Push the binary to ${e.bin} (and npx to ${e.npx}) first.`)),Ze(v("# Credentialless: each user still enrolls once (--enroll / --sso) before first agent use.")),Ze(v("# An MDM file drop REPLACES the file \u2014 deploy at provision time, or merge agent_servers in your config tool if devs add their own agents.")),0}
|
|
350
|
-
`),Ze(v(`# managed-settings.json for ${_t()}`)),n)Ze(v("# Deferred SSO: hooks only; no credential or managed env block.")),Ze(v(`# Push the binary to ${n.binaryPath} before this file.`)),Ze(v("# Configure SSO in the portal BEFORE pushing; sign-in happens in-tool on first prompt."));else{for(let o of YS(t))Ze(v(`# ${o}`));Ah(t,Ze)}return 0},
|
|
346
|
+
anyray-connect managed --print --tool shell --gateway https://gw.acme.com > /tmp/anyray.sh # deploy to /etc/profile.d`,WS=["claude-code","jetbrains","shell","bootstrap"],TW=e=>{let t={help:!1};for(let n=0;n<e.length;n++){let r=e[n],o=()=>{let a=e[++n];if(!a)throw new Error(`missing value for ${r}`);return a};switch(r){case"--print":t.mode="print";break;case"--write":t.mode="write";break;case"--revert":t.mode="revert";break;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":throw new Error("--key is not valid for managed settings: fleet files never embed credentials; enroll each user instead");case"--scrub-direct-mode":t.scrubDirectMode=!0;break;case"--sso":t.sso=o();break;case"--bin":t.bin=o();break;case"--npx":t.npx=o();break;case"--out":t.out=o();break;case"--tool":{let a=o();if(!WS.includes(a))throw new Error(`unknown --tool ${a} (expected ${WS.join(" | ")}; Codex fleets use \`anyray-connect desktop codex\`)`);t.tool=a;break}case"--subscription":throw new Error("--subscription cannot produce a valid credentialless managed file; use --sso <link> so each user enrolls and receives a personal gateway key");case"--placeholder":case"--org":throw new Error(`${r} is a legacy no-op for managed settings; omit it and enroll each user`);case"--yes":case"-y":break;case"--help":case"-h":t.help=!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})`)}}if(t.sso&&!Et(t.sso))throw new Error("invalid --sso link (expected <origin>/sso/tnt_\u2026 or tnt_\u2026)");return t};function Ed(e,t,n={}){if(!t&&e.authMode==="subscription")throw new Error("subscription managed settings require deferred SSO; a seat OAuth token does not replace the required personal gateway key");if(t){let o=["__anyray-sso-gate","--sso",t.sso,...t.gateway?["--gateway",t.gateway]:[],...t.team?["--team",t.team]:[]];return{hooks:{PostToolUse:[En(ps(t.binaryPath,[Je]),{matcher:"*"})],UserPromptSubmit:[En(ps(t.binaryPath,o),{timeout:30}),En(ps(t.binaryPath,[qn]))],SessionStart:[En(ps(t.binaryPath,[...o,"--session-start"]),{async:!0})]}}}let{env:r}=rn(e,{includeAuthToken:!1,includeClientKey:!1});return n.scrubDirectMode?{env:{...Object.fromEntries(In.map(o=>[o.name,""])),...r}}:{env:r}}var _W=(e,t)=>{let n="env"in t||"hooks"in t?t:{env:t},r={...e};e.env&&typeof e.env=="object"&&(r.env={...e.env}),e.hooks&&typeof e.hooks=="object"&&(r.hooks=Object.fromEntries(Object.entries(e.hooks).map(([a,s])=>[a,Array.isArray(s)?[...s]:s])));let o=r.env??{};for(let a of Ur)delete o[a];if(Object.keys(o).length?r.env=o:delete r.env,tp(r),n.env&&(r.env={...o,...n.env}),n.hooks){let a=r.hooks??{};for(let[s,i]of Object.entries(n.hooks)){let c=Array.isArray(a[s])?a[s]:[];a[s]=[...c,...i]}r.hooks=a}return r},PW=e=>{let t=e.env,n=tp(e);if(t){for(let r of Ur)r in t&&(delete t[r],n=!0);for(let{name:r}of In)t[r]===""&&(delete t[r],n=!0);Object.keys(t).length===0&&delete e.env}return n},GS=async e=>{let t=async n=>{try{return(await RW(n)).mode&511}catch{return}};return{mode:await t(e),dirExisted:await t(HS(e))!==void 0}},VS=async(e,t)=>(t.dirExisted||await yh(HS(e),493).catch(()=>{}),t.mode===void 0||t.mode&4?(await yh(e,420),{mode:420,keptRestricted:!1}):(await yh(e,t.mode),{mode:t.mode,keptRestricted:!0})),KS=(e,t)=>{t.keptRestricted&&(O(`${e} was already restricted to mode ${t.mode.toString(8).padStart(3,"0")} and keeps it \u2014 widening it would expose whatever else that file holds to every local account.`),A(v(" Claude Code reads this file as the developer, so the routing will NOT take effect until it is readable. Move any secret out of it, then `chmod 644` it.")))},jS=()=>process.getuid?.()===0,Ze=e=>{process.stderr.write(`${e}
|
|
347
|
+
`)},Id=(e,t)=>{if(e.out===void 0){process.stdout.write(t);return}xW(e.out,t,"utf8"),Ze(v(`# Wrote ${e.out}`))},wh=e=>Ee({origin:e.gateway??"http://localhost:8787",subscription:!!e.sso,user:e.user,team:e.team,intent:e.intent??"",intentLabel:e.intentLabel??"",session:e.session??""}),bh=e=>OW(e)||/^[A-Za-z]:[\\/]/.test(e),ZS=e=>{if(!e.sso)return;let t=Et(e.sso);if(!t)throw new Error("invalid --sso link");let n=e.bin??Pe();if(!e.bin&&!oe())throw new Error("--bin is required because the running binary path is temporary; use a fleet-stable path such as /usr/local/bin/anyray-connect");if(!bh(n))throw new Error("--bin must be an absolute fleet-stable path");return{sso:`${t.cpOrigin}/sso/${t.tenantId}`,binaryPath:n,gateway:e.gateway,team:e.team}},YS=e=>[`Gateway: ${e.origin}`,"Fleet mode: api-key (routing + headers only \u2014 per-dev keys stay in user settings)",`Attribution: ${fe(e.metadata)??"(none \u2014 pass --team)"}`],Ah=(e,t)=>{try{let{hostname:n}=new URL(e.origin);["localhost","127.0.0.1","::1","0.0.0.0"].includes(n)&&t(`! Gateway is ${e.origin} \u2014 a fleet managed file almost certainly wants your real gateway URL (pass --gateway).`)}catch{}},DW=(e,t)=>({agent_servers:{[Gn]:{command:e,args:[id,"claude",t,"jetbrains"],env:{}},[Vn]:{command:e,args:[id,"codex",t,"jetbrains"],env:{}}}}),LW=e=>["# Managed by anyray-connect (fleet). Routes shell/SDK traffic through the Anyray gateway.","# Per-user keys come from enrollment (`anyray-connect --enroll/--sso`); never add a key here.",`export OPENAI_BASE_URL=${Ie(e.openaiBaseUrl)}`,`export ANTHROPIC_BASE_URL=${Ie(e.anthropicBaseUrl)}`,""].join(`
|
|
348
|
+
`),NW=e=>{if(e.sso||e.gateway||e.user||e.team||e.intent||e.intentLabel||e.session)throw new Error("--tool jetbrains takes only --bin and --npx: gateway, attribution, and auth all resolve from each user\u2019s own enrollment at agent launch");if(!e.bin)throw new Error("--bin <absolute path> is required (fleet-stable anyray-connect binary, e.g. /usr/local/bin/anyray-connect)");if(!bh(e.bin))throw new Error("--bin must be an absolute fleet-stable path");if(!e.npx)throw new Error("--npx <absolute path> is required (fleet-stable npx, e.g. /usr/local/bin/npx) \u2014 a fleet artifact must not absorb the admin machine\u2019s PATH");if(!dd(e.npx))throw new Error("--npx must be an absolute path to an npx executable");return Id(e,`${JSON.stringify(DW(e.bin,e.npx),null,2)}
|
|
349
|
+
`),Ze(v("# acp.json for ~/.jetbrains/acp.json (per user).")),Ze(v(`# Push the binary to ${e.bin} (and npx to ${e.npx}) first.`)),Ze(v("# Credentialless: each user still enrolls once (--enroll / --sso) before first agent use.")),Ze(v("# An MDM file drop REPLACES the file \u2014 deploy at provision time, or merge agent_servers in your config tool if devs add their own agents.")),0},$W=e=>{if(e.npx||e.user||e.team||e.intent||e.intentLabel||e.session)throw new Error("--tool bootstrap takes only --sso, --gateway, and --bin: it carries the enrollment link, never attribution");if(!e.sso)throw new Error("--sso <link> is required: the bootstrap file exists to hand the org SSO link to unenrolled machines");if(e.bin&&!bh(e.bin))throw new Error("--bin must be an absolute fleet-stable path");return Id(e,BS(e.sso,e.gateway,e.bin)),Ze(v(`# Fleet bootstrap for ${wi("linux")}`)),Ze(v(`# macOS: ${wi("darwin")}`)),Ze(v(`# Windows: ${wi("win32",{ProgramData:"C:\\ProgramData"})}`)),Ze(v("# Content-free (SSO link + gateway origin + optional binary path). World-readable is fine; deploy via MDM.")),0},MW=e=>{if(e.sso||e.bin||e.npx||e.user||e.team||e.intent||e.intentLabel||e.session)throw new Error("--tool shell takes only --gateway: the snippet carries base URLs only (keys and attribution ride each user\u2019s enrollment)");let t=wh(e);return Id(e,LW(t)),Ze(v("# Shell fleet snippet for /etc/profile.d/anyray.sh (or an MDM shell include).")),Ah(t,Ze),0},BW=e=>{let t=wh(e),n=ZS(e),r=n?Ed(t,n):Ed(t,void 0,{scrubDirectMode:e.scrubDirectMode});if(Id(e,`${JSON.stringify(r,null,2)}
|
|
350
|
+
`),Ze(v(`# managed-settings.json for ${_t()}`)),n)Ze(v("# Deferred SSO: hooks only; no credential or managed env block.")),Ze(v(`# Push the binary to ${n.binaryPath} before this file.`)),Ze(v("# Configure SSO in the portal BEFORE pushing; sign-in happens in-tool on first prompt."));else{for(let o of YS(t))Ze(v(`# ${o}`));Ah(t,Ze)}return 0},FW=async e=>{let t=US();if(t!=="darwin"&&t!=="linux")return R("`managed --write` is supported on macOS and Linux only. Use `managed --print` and deploy the JSON via your MDM."),1;if(!jS())return R("Refusing to write the system managed-settings.json without root \u2014 re-run with `sudo` (it lives under a system-owned path)."),A(v(" For MDM packaging, use `managed --print` instead and push the file with Jamf / Intune / Ansible.")),1;let n=wh(e),r=ZS(e);r||Ah(n,u=>O(u.replace(/^!\s*/,"")));let o=_t(t),a=await M(o),s=r?Ed(n,r):Ed(n,void 0,{scrubDirectMode:e.scrubDirectMode}),i=e.scrubDirectMode?In.filter(({name:u})=>{let p=a.env?.[u];return typeof p=="string"&&p.trim()!==""}):[],c=_W(a,s),l=await GS(o);await J(o,c);let d=await VS(o,l);B(`Wrote ${o}`),KS(o,d);for(let{name:u,cloud:p}of i)O(`${u} was set in this file and is now pinned empty \u2014 Claude Code no longer talks to ${p} directly. The gateway serves it instead; re-add the key here to undo.`);if(r)A(v(` Push the binary to ${r.binaryPath} first; no credential is embedded.`)),A(v(" Configure SSO in the portal before rollout; first-prompt sign-in happens inside Claude Code."));else for(let u of YS(n))A(` ${v(u)}`);return A(v(" Managed settings outrank a user\u2019s ~/.claude/settings.json. Restart Claude Code sessions to pick it up.")),0},WW=async()=>{let e=US();if(e!=="darwin"&&e!=="linux")return R("`managed --revert` is supported on macOS and Linux only (remove the deployed file via your MDM elsewhere)."),1;if(!jS())return R("Refusing to edit the system managed-settings.json without root \u2014 re-run with `sudo`."),1;let t=_t(e);if(!await x(t))return A(`Nothing to revert \u2014 ${t} does not exist.`),0;let n=await M(t);if(!PW(n))return A(`No Anyray-owned keys found in ${t} \u2014 left unchanged.`),0;let r=await GS(t);await J(t,n);let o=await VS(t,r);return B(`Removed Anyray-owned keys from ${t} (other keys left intact).`),KS(t,o),0},JS=async e=>{let t;try{t=TW(e)}catch(n){return R(n instanceof Error?n.message:"invalid managed arguments"),A(`
|
|
351
351
|
`+gh),1}if(t.help||e.length===0&&!t.mode)return A(gh),0;if(!t.mode)return R("Specify a mode: --print, --write, or --revert."),A(`
|
|
352
|
-
`+gh),1;if(t.out!==void 0&&t.mode!=="print")return R(`--out is valid with --print only, not --${t.mode}.`),1;if(t.scrubDirectMode){let n=t.sso!==void 0?"--sso emits a hooks-only file with no env block":(t.tool??"claude-code")!=="claude-code"?`--tool ${t.tool} does not write Claude Code env`:t.mode==="revert"?"--revert already removes the pin (and leaves a truthy value alone)":void 0;if(n)return R(`--scrub-direct-mode cannot be combined with this mode: ${n}.`),1}try{let n=t.tool??"claude-code";return n!=="claude-code"?t.mode!=="print"?(R(`--tool ${n} supports --print only; deploy the artifact with your MDM.`),1):n==="jetbrains"?
|
|
352
|
+
`+gh),1;if(t.out!==void 0&&t.mode!=="print")return R(`--out is valid with --print only, not --${t.mode}.`),1;if(t.scrubDirectMode){let n=t.sso!==void 0?"--sso emits a hooks-only file with no env block":(t.tool??"claude-code")!=="claude-code"?`--tool ${t.tool} does not write Claude Code env`:t.mode==="revert"?"--revert already removes the pin (and leaves a truthy value alone)":void 0;if(n)return R(`--scrub-direct-mode cannot be combined with this mode: ${n}.`),1}try{let n=t.tool??"claude-code";return n!=="claude-code"?t.mode!=="print"?(R(`--tool ${n} supports --print only; deploy the artifact with your MDM.`),1):n==="jetbrains"?NW(t):n==="bootstrap"?$W(t):MW(t):t.mode==="print"?BW(t):t.mode==="write"?await FW(t):await WW()}catch(n){return R(n instanceof Error?n.message:"managed settings failed"),1}};import{spawn as YU}from"node:child_process";import{homedir as JU}from"node:os";import{join as LE}from"node:path";import{readFile as XU,writeFile as NE,chmod as zU,stat as qU,unlink as SE}from"node:fs/promises";var UW=["hook_registration","mcp_registration","hook_binary","beacon_target"],Ao=e=>e.status==="configured"||e.status==="queued",Co=async(e,t=pe)=>{let n=new Set(e),r=[];for(let o of t)if(n.has(o.id))try{(await o.detect()).installed&&r.push(o)}catch{}return r},Ra=async(e,t,n=pe)=>{let r=[];for(let o of await Co(e,n))if(o.pointsAt)try{if(o.automaticRepairAllowed&&!await o.automaticRepairAllowed())continue;await o.pointsAt(t)||r.push(o)}catch{}return r},Ch=async(e,t=pe)=>{let n=[];for(let r of await Co(e,t))if(r.integrationStatus)try{n.push({adapter:r,checks:await r.integrationStatus()})}catch{n.push({adapter:r,checks:Object.fromEntries(UW.map(o=>[o,"unreadable"]))})}return n},XS=e=>e.filter(t=>!t.integrationStatus),HW=e=>{let t=e?.code;return t==="EACCES"||t==="EPERM"||t==="EROFS"?"settings_not_writable":"apply_threw"},Ft=async(e,t)=>{let n=[];for(let r of e)try{let o=await r.apply(t,{dryRun:!1});n.push({id:r.id,title:r.title,status:o.status,...o.errorClass?{errorClass:o.errorClass}:{}})}catch(o){let a=HW(o);if(r.classifyApplyError)try{a=r.classifyApplyError(o)}catch{}n.push({id:r.id,title:r.title,status:"failed",errorClass:a})}return n};import{mkdir as VW,writeFile as KW}from"node:fs/promises";import{join as qS}from"node:path";import{z as xe}from"zod";var Oa="required",GW=e=>e==="subscription"?"subscription":"placeholder",zS=(e,t)=>{let n=t.routingOrigin!=null&&t.routingOrigin!==e.gateway,r=!!t.team&&t.team!==e.team,o=t.lane?GW(t.lane):void 0,a=o!=null&&o!==e.authMode;return{routingUpdated:n,teamUpdated:r,laneUpdated:a,...n?{gateway:t.routingOrigin}:{},...r?{team:t.team}:{},...a?{authMode:o}:{}}},xd=(e,t,n)=>{let r=new Set(t.enabled??[]),o=e.managedTools??[],a=o.filter(u=>r.has(u)||n),s=new Set(e.revertedTools??[]),i=e.revertedTools!=null,c=u=>t.tiers?.[u]??Oa,l=[],d=[];for(let u of r){if(o.includes(u))continue;let p=c(u);if(p!=="optional"){if(p!=="locked"){if(!i)continue;if(s.has(u)){p==="required"&&d.push(u);continue}}l.push(u)}}return{candidateIds:a,freshIds:l,tombstonedIds:d}};var jW=1e4,ZW=1,YW=xe.string().min(1).regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/).refine(e=>e!=="."&&e!==".."),JW=xe.object({id:YW,name:xe.string().min(1),version:xe.string().min(1),body:xe.string()}),XW=xe.object({version:xe.literal(ZW).optional(),skills:xe.array(JW),updatedAt:xe.string().min(1).optional(),routing:xe.object({origin:xe.string().min(1)}).optional(),team:xe.string().min(1).optional(),lane:xe.enum(["subscription","org"]).optional().catch(void 0),tools:xe.object({enabled:xe.array(xe.string().min(1)),tiers:xe.record(xe.string().min(1),xe.enum(["locked","required","recommended","optional"]).catch("optional")).optional()}).optional(),updates:xe.object({mode:xe.enum(["auto","directed","off"]).catch("directed")}).optional()}),Ta=class extends Error{kind;constructor(t,n){super(n),this.kind=t,this.name="TeamPolicyFetchError"}},kh=e=>e instanceof Ta&&e.kind==="auth",zW=e=>/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(e)&&e!=="."&&e!=="..",vh=e=>e&&typeof e=="object"&&"name"in e&&typeof e.name=="string"?e.name:"Error",_a=async(e,t,n={})=>{let r=n.timeoutMs??jW,o=`${e}/connect/policy`,a=new AbortController,s=setTimeout(()=>a.abort(),r),i;try{i=await fetch(o,{method:"GET",headers:{"x-anyray-api-key":t},signal:a.signal})}catch(l){let d=l instanceof Error&&l.name==="AbortError"?` no response within ${r}ms.`:ht(l);throw new Ta("unavailable",`could not reach the gateway at ${o}.${d}`)}finally{clearTimeout(s)}if(!i.ok)throw new Ta(i.status===401||i.status===403?"auth":"unavailable",`team policy fetch failed: the gateway responded ${i.status} at ${o}`);let c;try{c=await i.json()}catch{throw new Ta("malformed","team policy fetch failed: the gateway returned a malformed response")}return XW.parse(c)},QS=/^[a-z0-9][a-z0-9-]{0,31}$/,eE=64,qW=e=>{let t=e.tools;if(!t)return;let n=t.enabled.filter(o=>QS.test(o)).slice(0,eE).sort(),r=Object.entries(t.tiers??{}).filter(([o])=>QS.test(o)).slice(0,eE).sort(([o],[a])=>o.localeCompare(a));return{enabled:n,...r.length>0?{tiers:Object.fromEntries(r)}:{}}},QW=e=>e.updates?{mode:e.updates.mode}:void 0,bi=(e,t)=>{let n=e.fleetToolPolicy;return n?.enabled.includes(t)?(n.tiers?.[t]??Oa)==="locked":!1},Pa=async(e,t={})=>{let n=t.loadProfile??P,r=t.saveProfile??ce,o=t.targetFromProfile??Ue,a=t.adapters??pe,s=t.repairTools??Ft,i=t.recordManaged??Jn,c=await n(),l={...c},d=zS(c,{routingOrigin:e.routing?.origin?Kt(e.routing.origin):void 0,team:e.team,lane:e.lane}),{routingUpdated:u,teamUpdated:p,laneUpdated:m}=d;(u||p||m)&&(l={...await n()},d.gateway!=null&&(l.gateway=d.gateway),d.team!=null&&(l.team=d.team),d.authMode!=null&&(l.authMode=d.authMode),await r(l));let f=xd(l,{enabled:e.tools?.enabled,tiers:e.tools?.tiers},u||p||m),{candidateIds:h,freshIds:w}=f,y=0,g=0,b=0;if(h.length>0||w.length>0){let _=await o(async()=>l);if(_){let T;if(u||p||m){let G=new Set(h);T=[];for(let ne of a)if(G.has(ne.id))try{(await ne.detect()).installed&&T.push(ne)}catch{}}else T=await Ra(h,_.target.origin,a);let W=new Set(w),Q=[];for(let G of a)if(W.has(G.id))try{(await G.detect()).installed&&Q.push(G)}catch{}if(y=T.length+Q.length,y>0){let G=await s([...T,...Q],_.target);g=G.filter(Ao).length;let ne=G.filter(z=>W.has(z.id));if(b=ne.filter(Ao).length,ne.length>0)try{await i(ne,!1)}catch{}}}}let k=qW(e),C=QW(e),S=await n(),E=JSON.stringify(k??null)!==JSON.stringify(S.fleetToolPolicy??null),I=JSON.stringify(C??null)!==JSON.stringify(S.fleetUpdatePolicy??null);if(E||I){let{fleetToolPolicy:_,fleetUpdatePolicy:T,...W}=S;await r({...W,...k?{fleetToolPolicy:k}:{},...C?{fleetUpdatePolicy:C}:{}})}return{routingUpdated:u,teamUpdated:p,laneUpdated:m,toolsRequested:y,toolsApplied:g,toolsEnrolled:b,toolsTombstoned:f.tombstonedIds,profileUpdated:u||p||m,updatesMode:C?.mode??"auto",updatesUpdated:I}},tE=async(e,t,n)=>{let r=[],o={},a=0,s=0;for(let i of e.skills){if(!zW(i.id))continue;if(o[i.id]=i.version,n[i.id]===i.version){s+=1,r.push({id:i.id,name:i.name,version:i.version,written:!1,files:[]});continue}let l=[];for(let d of t){let u=qS(d,i.id),p=qS(u,"SKILL.md");await VW(u,{recursive:!0}),await KW(p,eU(i.body),"utf-8"),l.push(p)}a+=1,r.push({id:i.id,name:i.name,version:i.version,written:!0,files:l})}return{results:r,changed:a,unchanged:s,versions:o,updatedAt:e.updatedAt}},eU=e=>e.endsWith(`
|
|
353
353
|
`)?e:`${e}
|
|
354
|
-
`;import{randomBytes as eU}from"node:crypto";var tU=1e4,nU="machine:",nE=e=>e.startsWith(nU),rU="cert-renew",oU=e=>{if(e===null||typeof e!="object")return!1;let t=e;if(t.alg!=="Ed25519"||typeof t.sig!="string"||!t.sig.trim())return!1;let n=t.payload;if(n===null||typeof n!="object")return!1;let r=n,o=a=>typeof a=="string"&&!!a.trim();return typeof r.v=="number"&&o(r.deploymentId)&&o(r.user)&&o(r.devPublicKey)&&o(r.issuedAt)&&o(r.expiresAt)},rE=async(e,t,n={})=>{let r=n.fetchImpl??fetch,o=n.now??Date.now,a=n.origin??Kn();try{let s=e?.payload?.deploymentId;if(!s)return{ok:!1,refused:!1};let i={deploymentId:s,issuedAt:new Date(o()).toISOString(),nonce:eU(16).toString("hex"),purpose:rU},c;try{c=await(n.signer??Ir)(wo(i),t)}catch{return{ok:!1,refused:!1}}let l=new AbortController,d=setTimeout(()=>l.abort(),tU),u;try{u=await r(`${a}/v1/cert/renew`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({cert:e,challenge:i,sig:c}),signal:l.signal})}finally{clearTimeout(d)}if(!u.ok)return{ok:!1,refused:u.status>=400&&u.status<500&&u.status!==429};let m=(await u.json().catch(()=>null))?.cert;return oU(m)?{ok:!0,cert:m}:{ok:!1,refused:!1}}catch{return{ok:!1,refused:!1}}};var Sh=async(e,t=e.origin,n=pe)=>{let r=0,o=0,a=!0;for(let s of n)try{if(!s.pointsAt||!await s.pointsAt(t)||await s.usesDynamicCredential?.(t))continue;r+=1,(await s.apply(e,{dryRun:!1})).status==="configured"?o+=1:a=!1}catch{a=!1}return{matched:r,rewritten:o,complete:a}},Eh=async(e,t=e.origin,n=pe)=>(await Sh(e,t,n)).complete;var aU=["claude","codex","cursor","opencode"],sU=["missing_key","key_invalid","key_unknown","key_expired","key_revoked","user_deactivated"],iU=new Set(["missing_key","key_expired"]);var cU=600*1e3,lU=600*1e3,oE=1440*60*1e3,dU=1440*60*1e3,uU=10080*60*1e3,pU=3600*1e3,fU=720*60*1e3,mU=e=>Math.min(fU,pU*2**Math.max(0,e-1)),Ai=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),Da=e=>typeof e=="number"&&Number.isSafeInteger(e)&&e>=0,aE=e=>typeof e=="string"&&sU.includes(e),vn=e=>{if(!Ai(e))return{};let t={};if(Da(e.watchSince)&&(t.watchSince=e.watchSince),Ai(e.invoked)){let n={};for(let r of aU){let o=e.invoked[r];Da(o)&&(n[r]=o)}Object.keys(n).length>0&&(t.invoked=n)}return Ai(e.authFailure)&&Da(e.authFailure.at)&&typeof e.authFailure.status=="number"&&Number.isSafeInteger(e.authFailure.status)&&(t.authFailure={at:e.authFailure.at,status:e.authFailure.status,...aE(e.authFailure.code)?{code:e.authFailure.code}:{}}),Ai(e.repair)&&Da(e.repair.at)&&(e.repair.outcome==="repaired"||e.repair.outcome==="repair_failed"||e.repair.outcome==="unverified")&&(t.repair={at:e.repair.at,outcome:e.repair.outcome,...Da(e.repair.failures)&&e.repair.failures>0?{failures:e.repair.failures}:{}}),t},Rd=e=>{try{let n=JSON.parse(e);if(Ai(n)&&aE(n.code)&&n.code!=="key_invalid")return n.code}catch{}let t=e.toLowerCase();if(t.includes("valid client key required"))return"key_invalid";if(t.includes("client key required"))return"missing_key"},Ih=e=>e!==void 0&&iU.has(e),xh=(e,t,n)=>{let r=e.invoked?.[t];return r===void 0?!0:r>n||n-r>=cU},sE=(e,t,n)=>({...e,watchSince:e.watchSince??n,invoked:{...e.invoked??{},[t]:n}}),Rh=(e,t)=>{let n=e.authFailure?.at;return n===void 0?!0:n>t||t-n>=lU},iE=(e,t)=>({...e,watchSince:e.watchSince??t.at,authFailure:t}),cE=(e,t)=>e.watchSince===void 0?{...e,watchSince:t}:e,lE=(e,t,n)=>{if(n==="repair_failed"||n==="unverified")return{...e,repair:{at:t,outcome:n,failures:(e.repair?.failures??0)+1}};let{authFailure:r,...o}=e;return n==="repaired"?{...o,repair:{at:t,outcome:n}}:o},dE=(e,t)=>{let n=e?.authFailure;if(!n||n.at>t||t-n.at>oE||!Ih(n.code))return!1;let r=e?.repair;return!(r&&r.outcome!=="repaired"&&r.at<=t&&t-r.at<mU(r.failures??1))},Od=e=>{let t=Object.values(e?.invoked??{}).filter(Da);return t.length>0?Math.max(...t):null},Oh=(e,t)=>{if(Od(e)!==null)return!1;let n=e?.watchSince;return n===void 0||n>t?!1:t-n>=uU},uE=(e,t)=>{let n=e?.repair;if(n&&n.outcome!=="unverified"&&n.at<=t&&t-n.at<=dU)return{status:n.outcome,...e?.authFailure?.code?{errorClass:e.authFailure.code}:{}};let r=e?.authFailure;if(r&&r.at<=t&&t-r.at<=oE)return{status:"key_rejected",...r.code?{errorClass:r.code}:{}}};var Th="x-anyray-retrieve-probe",Td=8e3,hU=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string",pE=(e,t)=>{let n=Zt(e);return t?.probe&&(n[Th]="1"),n},La=async(e,t,n)=>{if(!e)return{ok:!1,kind:"unconfigured",message:"Anyray gateway not configured (run `anyray-connect` to point your tools at it)."};let r=new AbortController,o=setTimeout(()=>r.abort(),Td);try{let a=await fetch(`${e.origin}/connect/retrieve`,{method:"POST",headers:pE(e,n),body:JSON.stringify({handle:t,...n?.startLine!==void 0&&{startLine:n.startLine},...n?.endLine!==void 0&&{endLine:n.endLine},...n?.grep!==void 0&&{grep:n.grep}}),signal:r.signal});if(a.status===404)return await a.json().then(c=>typeof c=="object"&&c!==null).catch(()=>!1)?{ok:!1,kind:"not-found",message:`No stashed content for handle ${t} (unknown or expired).`}:{ok:!1,kind:"unsupported",message:"Gateway has no /connect/retrieve route (update the gateway image)."};if(!a.ok){let i=await a.json().catch(()=>{}),c=hU(i)&&i.code==="slice_unsupported";return{ok:!1,kind:a.status===401||a.status===403?"auth":c?"slice-unsupported":"unavailable",message:`Retrieval unavailable (gateway returned HTTP ${a.status}).`}}let s;try{s=await a.json()}catch{return{ok:!1,kind:"malformed",message:"Retrieval returned malformed JSON."}}return typeof s?.content!="string"?{ok:!1,kind:"malformed",message:"Retrieval returned no content."}:{ok:!0,content:s.content,...typeof s.totalLines=="number"&&{totalLines:s.totalLines},...typeof s.totalChars=="number"&&{totalChars:s.totalChars},...typeof s.partial=="boolean"&&{partial:s.partial},...typeof s.startLine=="number"&&{startLine:s.startLine},...typeof s.endLine=="number"&&{endLine:s.endLine},...typeof s.grepMatches=="number"&&{grepMatches:s.grepMatches},...typeof s.grepTruncated=="boolean"&&{grepTruncated:s.grepTruncated}}}catch(a){let s=a instanceof Error&&a.name==="AbortError";return{ok:!1,kind:s?"timeout":"network",message:s?"Retrieval timed out.":`Retrieval failed: ${a instanceof Error?a.message:String(a)}`}}finally{clearTimeout(o)}},_d=async(e,t,n,r)=>{if(!e)return{ok:!1,kind:"unconfigured",message:"Anyray gateway not configured (run `anyray-connect` to point your tools at it)."};let o=new AbortController,a=setTimeout(()=>o.abort(),Td);try{let s=await fetch(`${e.origin}/connect/recall`,{method:"POST",headers:pE(e,r),body:JSON.stringify({query:t,...typeof n=="number"?{k:n}:{}}),signal:o.signal});if(!s.ok)return{ok:!1,kind:s.status===401||s.status===403?"auth":"unavailable",message:`Recall unavailable (gateway returned HTTP ${s.status}).`};let i;try{i=await s.json()}catch{return{ok:!1,kind:"malformed",message:"Recall returned malformed JSON."}}return Array.isArray(i?.matches)?{ok:!0,matches:i.matches}:{ok:!1,kind:"malformed",message:"Recall returned no matches list."}}catch(s){let i=s instanceof Error&&s.name==="AbortError";return{ok:!1,kind:i?"timeout":"network",message:i?"Recall timed out.":`Recall failed: ${s instanceof Error?s.message:String(s)}`}}finally{clearTimeout(a)}};var yU=5e3,gU=2048,wU=e=>{let t=e.toLowerCase();return t.includes("client key required")?!0:["missing_key","key_unknown","key_expired","key_revoked"].some(n=>t.includes(`"${n}"`))},Na=async(e={})=>{let t=e.readTarget??nt,n=e.fetch??fetch,r=e.timeoutMs??yU,o=null;try{o=await t()}catch{o=null}if(!o)return{verdict:"dark",reason:"target_null"};let a=new AbortController,s=setTimeout(()=>a.abort(),r);try{let i=Zt(o);i["content-type"]="application/json",i[Th]="1";let c=await n(`${o.origin}/connect/optimize-output`,{method:"POST",headers:i,body:JSON.stringify({}),signal:a.signal});if(c.status===401||c.status===403){let u=(await c.text().catch(()=>"")).slice(0,gU);if(!wU(u))return{verdict:"indeterminate",reason:"unsupported",status:c.status};let p=Rd(u);return{verdict:"dark",reason:"key_rejected",status:c.status,...p?{code:p}:{}}}if(!c.ok)return{verdict:"indeterminate",reason:c.status>=500?"unreachable":"unsupported",status:c.status};let l;try{l=await c.json()}catch{return{verdict:"indeterminate",reason:"unsupported",status:c.status}}return typeof l=="object"&&l!==null&&l.handled===!0?{verdict:"live",reason:"ok",status:c.status}:{verdict:"indeterminate",reason:"gateway_mismatch",status:c.status}}catch{return{verdict:"indeterminate",reason:"unreachable"}}finally{clearTimeout(s)}},_h=(e,t)=>e.verdict==="dark"?e.reason==="target_null"?{...e,detail:"Hook lane dark: no gateway target resolves on this machine, so the hook sends nothing.",remedy:["Fix: run `anyray-connect` once to (re)write the tool settings and the connect profile.","A hand-templated machine has no ~/.anyray profile and no base URL in the client settings \u2014 the hook silently no-ops."]}:{...e,detail:"Hook lane dark: the gateway rejected this machine\u2019s client key on /connect/optimize-output.",remedy:["The next scheduled refresh re-mints from the enrollment cert automatically and rewrites the tool configs.","If it keeps failing (revoked key, deactivated user, or a key pasted from elsewhere), re-enroll: run `anyray-connect` and follow the enrollment steer above."]}:e.verdict==="live"&&t.hookRegistered&&t.neverInvoked?{verdict:"dark",reason:"never_invoked",...e.status!==void 0?{status:e.status}:{},detail:"Hook lane dark: the hook is installed and the gateway answers, but nothing has invoked the hook here.",remedy:["Installed is not the same as firing \u2014 this seat has produced no hook run in the observation window.","OpenCode: its plugin turns a spawn failure into empty output silently \u2014 check the binary path in the generated plugin and restart OpenCode.","Claude Code / Codex: restart the tool so it re-reads its settings, then run a tool call that produces a large output."]}:e.verdict==="live"?{...e,detail:"Hook lane live: the gateway accepted this machine\u2019s key and answered the optimize probe.",remedy:[]}:{...e,detail:e.reason==="gateway_mismatch"?"Hook lane undetermined: the gateway answered but did not confirm it read the request (it predates the current hook protocol).":e.reason==="unreachable"?"Hook lane undetermined: could not reach the gateway for the probe.":"Hook lane undetermined: the response did not come from a gateway that serves /connect/optimize-output.",remedy:[e.reason==="gateway_mismatch"?"Fix: update the gateway image \u2014 this one predates the gzip-aware optimize-output contract.":"Not counted as a problem. Check the gateway origin and any proxy in front of it (see the Gateway section above)."]};import{randomBytes as CU}from"node:crypto";import{execSync as Ph}from"node:child_process";import{hostname as bU}from"node:os";var AU=e=>{try{if(e==="darwin"){let t=Ph("ioreg -rd1 -c IOPlatformExpertDevice",{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return/"IOPlatformUUID"\s*=\s*"([^"]+)"/.exec(t)?.[1]??""}if(e==="win32"){let t=Ph('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 Ph("cat /etc/machine-id 2>/dev/null || cat /var/lib/dbus/machine-id 2>/dev/null",{encoding:"utf8",stdio:["ignore","pipe","ignore"]})}catch{return""}},Pd=(e={platform:process.platform,read:()=>AU(process.platform),hostname:bU})=>e.read().trim()||e.hostname().trim();var Wt=(e={})=>{let t=(e.envUuid??process.env.ANYRAY_MACHINE_UUID??"").trim();if(t)return t.toLowerCase();if((e.platform??process.platform)==="darwin"){let r=e.readMacUuid??(()=>Pd());try{return r().trim().toLowerCase()}catch{return""}}return""};var kU=500,fE=2e3,vU=2e3,SU=250,mE=async(e,t,n,r)=>{let o=new AbortController,a=setTimeout(()=>o.abort(),kU);try{return(await fetch(`${e}/connect/health`,{method:"POST",headers:{...t,"x-anyray-connect-version":r},body:JSON.stringify({events:n}),signal:o.signal})).ok}catch{return!1}finally{clearTimeout(a)}},EU=e=>{let t=e.headers?.get?.("retry-after");if(!t)return;let n=Number(t.trim());return Number.isFinite(n)&&n>=0?n*1e3:void 0},IU=e=>new Promise(t=>setTimeout(t,e)),xU=async(e,t,n=IU)=>{for(let r=0;;r++){let o=new AbortController,a=setTimeout(()=>o.abort(),fE),s;try{let i=await fetch(e,{method:"POST",headers:{"content-type":"application/json"},body:t,signal:o.signal});if(i.ok)return!0;let c=i.status===429||i.status>=500;if(r>0||!c||(s=EU(i)??SU,s>vU))return!1}finally{clearTimeout(a)}await n(s)}},RU=async(e,t={})=>{try{let r=(await(t.loadProfile??P)()).enrolledCert,o=await(t.loadDevKey??Fe)(),a=r?.payload?.deploymentId;if(!r||!o||!a)return!1;let s={deploymentId:a,issuedAt:new Date().toISOString(),nonce:CU(16).toString("hex"),events:e},i;try{i=await(t.signer??Ir)(wo(s),o)}catch{return!1}return await(t.post??xU)(`${t.origin??Kn()}/v1/connect-events`,JSON.stringify({cert:r,challenge:s,sig:i}))}catch{return!1}},OU=async(e,t,n={})=>{try{let o=(await(n.loadProfile??P)()).enrolledCert,a=await(n.loadDevKey??Fe)();if(!o||!a)return;await(n.verify??Qt)(e,o,a,{timeoutMs:fE,machineUuid:(n.machineUuid??Wt)()||void 0,health:{events:t},telemetryOnly:!0})}catch{}},hE=async(e,t)=>{if(e.length!==0)try{let n=await nt(),r=n&&await mE(n.origin,Zt(n),e,t);if(n&&await OU(n.origin,e),r)return;await RU(e)}catch{}},Dh=async(e,t,n={readTarget:()=>nt("profile"),post:mE})=>{if(e.length===0)return!1;try{let r=await n.readTarget();return r?await n.post(r.origin,{"content-type":"application/json"},e,t):!1}catch{return!1}};var vo=["hook_registration","mcp_registration","hook_binary","beacon_target"];var gE=128,wE=300*1e3,TU=["repaired","repair_failed","flapping","pending"],_U=["settings_not_writable","mcp_unreadable","mcp_not_writable","mcp_foreign","mcp_not_persisted","apply_unconfirmed","apply_threw"],bE=["rebroke_same_day","repeat_days"],AE=new Set(pe.map(e=>e.id)),ko=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),ki=(e,t)=>typeof e=="string"&&t.some(n=>n===e),CE=e=>ki(e,vo),Dd=e=>{if(typeof e!="string"||!/^\d{4}-\d{2}-\d{2}$/.test(e))return!1;let t=Date.parse(`${e}T00:00:00.000Z`);return Number.isFinite(t)&&new Date(t).toISOString().slice(0,10)===e},Rr=e=>typeof e=="number"&&Number.isSafeInteger(e)&&e>=0,Ci=e=>{if(!(!Array.isArray(e)||!e.every(CE)))return jn(e)},PU=e=>{if(!ko(e))return;let t=Ci(e.checks);if(!(!Rr(e.since)||!ki(e.reason,bE)||!t?.length))return{since:e.since,reason:e.reason,checks:t}},DU=e=>{if(!ko(e))return;let t={};Dd(e.day)&&(t.day=e.day),Rr(e.attempts)&&(t.attempts=e.attempts);let n=Ci(e.attemptedChecks);n&&(t.attemptedChecks=n);let r=Ci(e.confirmedChecks);r&&(t.confirmedChecks=r);let o=Ci(e.brokenReportedChecks);o&&(t.brokenReportedChecks=o);let a=Ci(e.awaiting);if(a&&(t.awaiting=a),typeof e.dayHadNeed=="boolean"&&(t.dayHadNeed=e.dayHadNeed),Dd(e.lastConfirmedDay)&&(t.lastConfirmedDay=e.lastConfirmedDay),Rr(e.consecutiveRepairDays)&&(t.consecutiveRepairDays=e.consecutiveRepairDays),ko(e.lastRepaired)){let i={};for(let c of vo){let l=e.lastRepaired[c];Rr(l)&&(i[c]=l)}Object.keys(i).length>0&&(t.lastRepaired=i)}let s=PU(e.flapping);return s&&(t.flapping=s),t},LU=e=>{if(!ko(e)||!Dd(e.day)||!Rr(e.sequence)||e.sequence===0||typeof e.tool!="string"||!AE.has(e.tool)||!CE(e.checkId)||!ki(e.status,TU)||typeof e.delivered!="boolean")return;let t;if(e.status==="repair_failed"){if(!ki(e.errorClass,_U))return;t=e.errorClass}else if(e.status==="flapping"){if(!ki(e.errorClass,bE))return;t=e.errorClass}else if(e.errorClass!==void 0)return;return{day:e.day,sequence:e.sequence,tool:e.tool,checkId:e.checkId,status:e.status,...t?{errorClass:t}:{},delivered:e.delivered,...Rr(e.attemptedAt)?{attemptedAt:e.attemptedAt}:{}}},yE=e=>{if(!ko(e))return{};let t={};if(ko(e.adapters)){let n={};for(let r of AE){let o=DU(e.adapters[r]);o&&(n[r]=o)}Object.keys(n).length>0&&(t.adapters=n)}return Array.isArray(e.events)&&(t.events=e.events.map(LU).filter(n=>n!==void 0).slice(-gE)),Rr(e.nextSequence)&&e.nextSequence>0&&(t.nextSequence=e.nextSequence),ko(e.report)&&Dd(e.report.day)&&typeof e.report.delivered=="boolean"&&(t.report={day:e.report.day,delivered:e.report.delivered,...Rr(e.report.attemptedAt)?{attemptedAt:e.report.attemptedAt}:{}}),t},NU=e=>new Date(e).toISOString().slice(0,10),$U=(e,t)=>e!==void 0&&Date.parse(`${t}T00:00:00.000Z`)-Date.parse(`${e}T00:00:00.000Z`)===1440*60*1e3,jn=e=>[...new Set(e)],Ld=(e,t)=>{let n=e??{};if(n.day===t)return n;let r=n.day!==void 0&&n.dayHadNeed===!1;return{...n,day:t,attempts:0,attemptedChecks:[],confirmedChecks:[],brokenReportedChecks:[],dayHadNeed:!1,...r?{consecutiveRepairDays:0,lastConfirmedDay:void 0,flapping:void 0}:{}}},vi=(e,t,n)=>{let r=e.nextSequence??1,o=n.map(a=>({...a,day:t,sequence:r++,delivered:!1}));return{...e,events:[...(e.events??[]).filter(a=>a.day===t),...o].slice(-gE),nextSequence:r}},MU=e=>({tool:e.tool,checkId:e.checkId,status:e.status,...e.errorClass?{errorClass:e.errorClass}:{}}),BU=async e=>await Ue(async()=>e)??null,FU=async(e,t,n)=>{let r=new Map(e.map(({adapter:o,checks:a})=>[o.id,Object.values(a).some(s=>s==="missing")]));await n.claimState(o=>{let a={...o.adapters??{}};for(let{adapter:s}of e){let i=Ld(a[s.id],t);a[s.id]={...i,dayHadNeed:!!(i.dayHadNeed||r.get(s.id))}}return{next:{...o,adapters:a,events:(o.events??[]).filter(s=>s.day===t)},result:void 0}},void 0)},kE=(e,t,n,r)=>{if(t.length===0)return{adapter:e,slowFlap:!1};let o=e.lastConfirmedDay===n?e.consecutiveRepairDays??1:$U(e.lastConfirmedDay,n)?(e.consecutiveRepairDays??0)+1:1,a=o>=3,s={...e.lastRepaired??{}};for(let c of t)s[c]=r;let i=e.flapping;return{adapter:{...e,confirmedChecks:jn([...e.confirmedChecks??[],...t]),brokenReportedChecks:(e.brokenReportedChecks??[]).filter(c=>!t.includes(c)),lastConfirmedDay:n,consecutiveRepairDays:o,lastRepaired:s,...a?{flapping:{since:i?.since??r,reason:"repeat_days",checks:jn([...i?.checks??[],...t])}}:{}},slowFlap:a}},WU=async(e,t,n,r,o)=>{let a=new Map(e.map(s=>[s.adapter.id,s]));await o.claimState(s=>{let i=s,c={...s.adapters??{}};for(let[l,d]of Object.entries(c)){let u=Ld(d,n),p=u.awaiting??[],m=a.get(l);if(p.length===0||t.has(l)||!m){c[l]=u;continue}let f=p.filter(g=>m.checks[g]==="owned"),h=p.filter(g=>{let b=m.checks[g];return b==="missing"||b==="foreign"}),w=p.filter(g=>{let b=m.checks[g];return b===void 0||b==="unreadable"}),y=kE(u,f,n,r);c[l]={...y.adapter,awaiting:w.length>0?w:void 0},i=vi(i,n,[...f.map(g=>({tool:l,checkId:g,status:"repaired"})),...h.map(g=>({tool:l,checkId:g,status:"repair_failed",errorClass:"apply_unconfirmed"})),...y.slowFlap?f.map(g=>({tool:l,checkId:g,status:"flapping",errorClass:"repeat_days"})):[]])}return{next:{...i,adapters:c},result:void 0}},void 0)},UU=async(e,t,n,r,o,a,s)=>s.claimState(i=>{let c={...i.adapters??{}},l=Ld(c[e],o);if(r&&(l.awaiting?.length??0)>0)return{result:void 0};let d=l.attemptedChecks??[],u=l.confirmedChecks??[],p=t.filter(y=>!d.includes(y)||u.includes(y)),m=p.filter(y=>u.includes(y)),f=l.attempts??0;if(f>=2||p.length===0&&!n){let y=m.filter(k=>!(l.brokenReportedChecks??[]).includes(k));if(y.length===0)return{result:void 0};let g=l.flapping;return c[e]={...l,brokenReportedChecks:jn([...l.brokenReportedChecks??[],...y]),flapping:{since:g?.since??a,reason:"rebroke_same_day",checks:jn([...g?.checks??[],...y])}},{next:vi({...i,adapters:c},o,y.map(k=>({tool:e,checkId:k,status:"flapping",errorClass:"rebroke_same_day"}))),result:void 0}}let h=l.flapping;return c[e]={...l,attempts:f+1,attemptedChecks:jn([...d,...p]),confirmedChecks:u.filter(y=>!p.includes(y)),brokenReportedChecks:jn([...l.brokenReportedChecks??[],...m]),...m.length>0?{flapping:{since:h?.since??a,reason:"rebroke_same_day",checks:jn([...h?.checks??[],...m])}}:{}},{next:vi({...i,adapters:c},o,m.map(y=>({tool:e,checkId:y,status:"flapping",errorClass:"rebroke_same_day"}))),result:{checks:p,fastFlaps:m}}},void 0),HU=async(e,t,n,r,o,a,s)=>{await s.claimState(i=>{let c={...i.adapters??{}},l=Ld(c[e],o);if(n.status==="queued")return c[e]={...l,awaiting:jn([...l.awaiting??[],...t])},{next:vi({...i,adapters:c},o,t.map(f=>({tool:e,checkId:f,status:"pending"}))),result:void 0};let d=n.status==="configured"&&r?t.filter(f=>r[f]==="owned"):[],u=n.status==="configured"&&r?t.filter(f=>{let h=r[f];return h==="missing"||h==="foreign"}):n.status==="failed"||n.status!=="configured"?t:[],p=kE(l,d,o,a);c[e]=p.adapter;let m=n.status==="failed"?n.errorClass??"apply_threw":n.errorClass??"apply_unconfirmed";return{next:vi({...i,adapters:c},o,[...d.map(f=>({tool:e,checkId:f,status:"repaired"})),...u.map(f=>({tool:e,checkId:f,status:"repair_failed",errorClass:m})),...p.slowFlap?d.map(f=>({tool:e,checkId:f,status:"flapping",errorClass:"repeat_days"})):[]]),result:void 0}},void 0)},GU=async(e,t,n,r)=>{let o=await r.claimState(i=>{let c=(i.events??[]).filter(u=>u.day===e&&!u.delivered&&(u.attemptedAt===void 0||u.attemptedAt>t||t-u.attemptedAt>=wE));if(c.length===0)return{result:[]};let l=new Set(c.map(u=>`${u.day}:${u.sequence}`)),d=(i.events??[]).map(u=>l.has(`${u.day}:${u.sequence}`)?{...u,attemptedAt:t}:u);return{next:{...i,events:d},result:c.map(u=>({...u,attemptedAt:t}))}},[]);if(o.length===0||!await(r.report??Dh)(o.map(MU),n).catch(()=>!1))return;let s=new Set(o.map(i=>`${i.day}:${i.sequence}`));await r.claimState(i=>({next:{...i,events:(i.events??[]).map(c=>s.has(`${c.day}:${c.sequence}`)?{...c,delivered:!0}:c)},result:void 0}),void 0)},VU=async(e,t,n,r,o,a)=>{let s=[],i=!1,c=new Set(n.map(u=>u.adapter));for(let{adapter:u,checks:p}of t){let m=r.adapters?.[u.id];for(let f of vo){let h=p[f];if(!h||h==="unreadable")continue;let w,y;m?.awaiting?.includes(f)&&c.has(u.id)?w="pending":h==="missing"&&m?.flapping?.checks.includes(f)?(w="flapping",y=m.flapping.reason):w=h==="owned"?"ok":h,w!=="ok"&&w!=="pending"&&(i=!0),s.push({tool:u.id,checkId:f,status:w,...y?{errorClass:y}:{}})}}let l=Date.parse(e.enrolledCert?.payload.expiresAt??e.enrolledCertExpiry??"");e.enrolledCert&&Number.isFinite(l)&&(l<=o?(i=!0,s.push({tool:"connect",checkId:"enrollment_cert",status:"expired"})):l-o<=336*60*60*1e3&&(i=!0,s.push({tool:"connect",checkId:"enrollment_cert",status:"problems",errorClass:"cert_expiring"}))),e.refreshSchedulerEnabled&&e.persistenceOwner!=="tray"&&!await(a.schedulerInstalled??Ho)()&&(i=!0,s.push({tool:"connect",checkId:"refresh_scheduler",status:"missing",errorClass:"refresh_scheduler_missing"})),(a.deadWatcherObserved||n.some(u=>!(a.pidAlive??pr)(u.watcherPid)))&&(i=!0,s.push({tool:"connect",checkId:"pending_op",status:"problems",errorClass:"watcher_dead"}));let d=uE(await a.readHookLane?.().catch(()=>({})),o);return d&&(d.status!=="repaired"&&(i=!0),s.push({tool:"connect",checkId:"hook_lane",status:d.status,...d.errorClass?{errorClass:d.errorClass}:{}})),s.push({tool:"connect",checkId:"selfcheck_report",status:i?"problems":"ok"}),s},KU=async(e,t,n,r,o,a,s)=>{if(!await s.claimState(u=>u.report?.day===r&&u.report.delivered?{result:!1}:u.report?.day===r&&u.report.attemptedAt!==void 0&&u.report.attemptedAt<=o&&o-u.report.attemptedAt<wE?{result:!1}:{next:{...u,report:{day:r,delivered:!1,attemptedAt:o}},result:!0},!1))return;let c=await s.readState().catch(()=>({})),l=await VU(e,t,n,c,o,s);await(s.report??Dh)(l,a).catch(()=>!1)&&await s.claimState(u=>u.report?.day===r?{next:{...u,report:{day:r,delivered:!0}},result:void 0}:{result:void 0},void 0)},vE=async(e,t,n)=>{let r=n.now??Date.now,o=NU(r()),a=e.managedTools??[],s={...n,readState:async()=>yE(await n.readState()),claimState:async(i,c)=>n.claimState(l=>i(yE(l)),c)};try{let i=await(s.findIntegrations??Ch)(a);await FU(i,o,s);let c=await(s.listPending??dr)().catch(()=>[]),l=new Set(c.map(y=>y.adapter));await WU(i,l,o,r(),s);let d=await(s.resolveTarget??BU)(e),u=d?await(s.findDrifted??Ra)(a,d.target.origin):[],p=new Set(u.map(y=>y.id)),m=new Map(i.map(y=>[y.adapter.id,y]));for(let y of u)m.has(y.id)||m.set(y.id,{adapter:y,checks:{}});let f=!1,h=(s.runtimeDurable??oe)();if(d)for(let{adapter:y,checks:g}of m.values()){let b=h?vo.filter(T=>g[T]==="missing"):[];if(b.length===0&&!p.has(y.id))continue;let k=g;if(y.integrationStatus)try{k=await y.integrationStatus()}catch{k=Object.fromEntries(vo.map(T=>[T,"unreadable"]))}let C=b.filter(T=>k[T]==="missing"),S=p.has(y.id);if(S&&y.pointsAt&&(S=!await y.pointsAt(d.target.origin).catch(()=>!0)),C.length===0&&!S)continue;let E=await UU(y.id,C,S,l.has(y.id),o,r(),s);if(!E)continue;let[I]=await(s.repair??Ft)([y],d.target);if(!I)continue;f=!0;let _;I.status==="configured"&&y.integrationStatus&&(_=await y.integrationStatus().catch(()=>{})),await HU(y.id,E.checks,I,_,o,r(),s)}await GU(o,r(),t,s),i=await(s.findIntegrations??Ch)(a);let w=await(s.listPending??dr)().catch(()=>[]);return await KU(e,i,w,o,r(),t,s),f}catch{return!1}};var qU=14,QU=.35,eH=900*1e3,EE=360*60*1e3,tH=.2,nH=1800*1e3,IE=3600*1e3,rH=new Set(["ENOTFOUND","EAI_AGAIN","ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENETDOWN","ENETUNREACH","EHOSTUNREACH","EPIPE","UND_ERR_CONNECT_TIMEOUT","UND_ERR_SOCKET"]),oH=300*1e3,aH=30*1e3,sH=900*1e3,iH=(e=0)=>Math.min(sH,aH*2**Math.max(0,e)),xE=e=>{let t=e;for(let n=0;n<5&&t;n++){let r=t.code;if(typeof r=="string")return r;t=t.cause}},RE=1440*60*1e3,cH=300*1e3,lH=.25,dH=.5,OE=3600*1e3,uH=720*60*60*1e3,pH=360*60*1e3,fH=1440*60*1e3,mH=()=>LE(YU(),".anyray"),Lh=()=>LE(mH(),"refresh-state.json"),Nh=e=>process.env?.[e],$E=()=>Nh("ANYRAY_REFRESH_DISABLE")==="true",$h=()=>{let e=Nh("ANYRAY_REFRESH_WINDOW_DAYS"),t=e?Number.parseInt(e,10):NaN;return(Number.isFinite(t)&&t>0?t:qU)*fH},$d=e=>{let t=e.enrolledCert?.payload.keyTtlSeconds;return typeof t=="number"&&Number.isFinite(t)&&t>0?t*1e3:void 0},ME=new Set(["claude-code","codex","opencode","cursor","copilot","copilot-cli","claude-desktop","jetbrains","windsurf"]),hH=10080*60*1e3,BE=(e,t,n=Date.now())=>{let r=[],o=$d(e);o!==void 0&&r.push(o);let a=Date.parse(t??e.clientKeyExpiresAt??"");Number.isFinite(a)&&r.push(a-n);let s=Date.parse(e.enrolledCertExpiry??e.enrolledCert?.payload.expiresAt??"");return Number.isFinite(s)&&r.push(s-n),r.length===0?!1:Math.min(...r)<=hH},Mh=e=>{let t=$h(),n=e?$d(e):void 0;if(!n)return t;let r=Math.max(eH,Math.round(n*QU));return Math.min(t,r)},yH=e=>{let t=Nh("ANYRAY_REFRESH_THROTTLE_MS"),n=t?Number.parseInt(t,10):NaN;return Number.isFinite(n)&&n>0?n:typeof e=="number"&&Number.isFinite(e)&&e>0?Math.min(EE,Math.max(nH,Math.round(e*tH))):EE},It=async()=>{try{let e=await JU(Lh(),"utf-8"),t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}},Md=async e=>{try{let t=Lh(),n=`${t}.${process.pid}.tmp`;await NE(n,JSON.stringify(e),{mode:384}),await ye(n,t),await XU(t,384).catch(()=>{})}catch{}},gH=3e4,wH=()=>`${Lh()}.lock`,TE=async e=>{try{return await NE(e,String(process.pid),{flag:"wx",mode:384}),!0}catch(t){if(t.code!=="EEXIST")throw t;return!1}},dt=async(e,t,n={})=>{let r=n.now??Date.now,o=n.readState??It,a=n.writeState??Md,s=wH(),i=!1;try{if(i=await TE(s),!i){if(await zU(s).then(l=>r()-l.mtimeMs).catch(()=>1/0)<gH)return t;await SE(s).catch(()=>{}),i=await TE(s).catch(()=>!1)}}catch{}try{let c=await o(),{next:l,result:d}=e(c);return l&&await a(l),d}finally{i&&await SE(s).catch(()=>{})}},Nd=async(e,t={})=>{await dt(n=>({next:e(n),result:void 0}),void 0,t).catch(()=>{})},$a=async(e={},t={})=>{let n=t.now??Date.now,r=e.expiresAt?Date.parse(e.expiresAt):NaN,o=e.keyTtlMs??(Number.isFinite(r)&&r-n()>0?r-n():void 0);await dt(({lastError:a,...s})=>({next:{...s,lastAttemptAt:n(),lastSuccessAt:n(),failureCount:0,keyTtlMs:o??s.keyTtlMs},result:void 0}),void 0,t).catch(()=>{})},So=async(e={})=>{let t=e.now??Date.now;await dt(n=>({next:{...n,lastAttemptAt:t()},result:void 0}),void 0,e).catch(()=>{})},bH=e=>{let t=e.enrolledCertLifetimeMs,n=Date.parse(e.enrolledCert?.payload.issuedAt??""),r=Date.parse(e.enrolledCertExpiry??e.enrolledCert?.payload.expiresAt??""),o=typeof t=="number"&&Number.isFinite(t)&&t>0?t:Number.isFinite(n)&&Number.isFinite(r)&&r>n?r-n:void 0;return o?Math.min(uH,Math.max(OE,Math.round(o*dH))):OE},FE=async(e,t,n,r)=>e.enrolledCert?.sig!==t?!1:await r().catch(()=>{})===n,Bh=async(e,t,n={})=>{let r=n.now??Date.now,o=n.saveProfile??ce,a=n.loadProfile??P,s=n.loadDevKey??Fe,i=n.renew??rE,c=e.enrolledCert;if(!c)return{outcome:"not-due",profile:e};if(nE(c.payload.user))return{outcome:"not-due",profile:e};let l=Date.parse(e.enrolledCertExpiry??c.payload.expiresAt??"");if(!Number.isFinite(l))return{outcome:"not-due",profile:e};if(l-r()>bH(e))return{outcome:"not-due",profile:e};if(!await dt(w=>r()-(w.lastCertRenewAt??0)<pH?{result:!1}:{next:{...w,lastCertRenewAt:r()},result:!0},!1,n).catch(()=>!1))return{outcome:"throttled",profile:e};let u=await i(c,t);if(!u.ok)return{outcome:u.refused?"refused":"failed",profile:e};let p=await a().catch(()=>e);if(!p.enrolledCert)return{outcome:"failed",profile:e};if(!await FE(p,c.sig,t,s))return{outcome:"superseded",profile:p};let m=u.cert.payload.expiresAt,f=Date.parse(m)-r(),h={...p,enrolledCert:u.cert,enrolledCertExpiry:m,...Number.isFinite(f)&&f>0?{enrolledCertLifetimeMs:f}:{}};return await o(h),{outcome:"renewed",profile:h}},_E=(e,t)=>{let n=t!==void 0&&Number.isFinite(t)&&t>0?Math.round(t*lH):RE,r=Math.min(RE,n);return Math.min(r,cH*2**Math.max(0,e-1))},AH=()=>{let{command:e,args:t}=or(Qn);return{exe:e,args:t}},Or=async(e={})=>{if($E())return;let t=e.now??Date.now,n=e.readState??It,r=e.writeState??Md,o=e.spawnRefresh??(()=>{let{exe:a,args:s}=AH();ZU(a,s,{detached:!0,stdio:"ignore"}).unref()});try{if(!await dt(s=>t()-(s.lastSpawnAt??0)<yH(s.keyTtlMs)?{result:!1}:{next:{...s,lastSpawnAt:t()},result:!0},!1,{now:t,readState:n,writeState:r}))return;o()}catch{}},CH=Eh,kH=async(e,t=!1)=>{try{let n=e.managedTools??[];if(n.length===0)return!1;let r=await Ue(async()=>e);if(!r)return!1;let o=await Ra(n,r.target.origin),a=t?XS(o):o;return a.length===0?!1:(await Ft(a,r.target),!0)}catch{return!1}},vH=async(e,t,n,r,o)=>{try{let a=new Set(e.managedTools??[]),s=pe.filter(d=>a.has(d.id));if(s.length===0)return!1;let i=await r().catch(()=>{}),c=Ee({origin:t,clientKey:n,subscription:e.authMode==="subscription",placeholder:e.authMode==="placeholder",byoUpstream:e.byoUpstream,seat:i,user:e.name,team:e.team}),l=await o(c,c.origin,s);return l.matched>0&&l.complete}catch{return!1}},SH=async(e,t,n)=>{let r=t.now??Date.now,o=t.readState??It,a=t.writeState??Md;return vE(e,ke,{now:r,deadWatcherObserved:n,readHookLane:()=>Bd({now:r,readState:o,writeState:a}),readState:async()=>(await o()).selfcheck??{},claimState:async(s,i)=>dt(c=>{let l=s(c.selfcheck??{});return{...l.next?{next:{...c,selfcheck:l.next}}:{},result:l.result}},i,{now:r,readState:o,writeState:a})})},Bd=async(e={})=>{let n=await(e.readState??It)().catch(()=>({}));return vn(n.hookLane)},WE=async(e,t={})=>{try{let n=t.now??Date.now,r=await Bd(t);if(!xh(r,e,n()))return;await dt(o=>{let a=vn(o.hookLane);return xh(a,e,n())?{next:{...o,hookLane:sE(a,e,n())},result:void 0}:{result:void 0}},void 0,t)}catch{}},UE=async(e,t={})=>{try{let n=t.now??Date.now,r=await Bd(t);if(!Rh(r,n()))return;await dt(o=>{let a=vn(o.hookLane);return Rh(a,n())?{next:{...o,hookLane:iE(a,e)},result:void 0}:{result:void 0}},void 0,t)}catch{}},EH=async(e={})=>{try{let t=e.now??Date.now;if((await Bd(e)).watchSince!==void 0)return;await dt(n=>{let r=vn(n.hookLane);return r.watchSince!==void 0?{result:void 0}:{next:{...n,hookLane:cE(r,t())},result:void 0}},void 0,e)}catch{}},PE=async(e,t={})=>{try{let n=t.now??Date.now;await dt(r=>{let o=vn(r.hookLane),a=lE(o,n(),e);return JSON.stringify(a)===JSON.stringify(o)?{result:void 0}:{next:{...r,hookLane:a},result:void 0}},void 0,t)}catch{}},HE=async(e={})=>{try{if((await(e.readState??It)()).repathedAt)return"skipped";let n=e.now??Date.now,r=async()=>dt(c=>c.repathedAt?{result:!1}:{next:{...c,repathedAt:n()},result:!0},!1,e).catch(()=>!1);if(!(e.launcherBacked??nw)())return await r()?"stamped":"skipped";let o=await(e.load??P)(),s=await(e.findTools??Co)(o.managedTools??[]);if(s.length===0)return await r()?"stamped":"skipped";let i=await Ue(async()=>o);return!i||!await r()?"skipped":(await(e.repair??Ft)(s,i.target),"repathed")}catch{return"skipped"}},GE=async(e={})=>{try{let t=e.revision??1,r=(await(e.readState??It)()).appliedRevision;if((r??0)>=t)return"skipped";let o=async()=>dt(d=>(d.appliedRevision??0)>=t?{result:!1}:{next:{...d,appliedRevision:t},result:!0},!1,e).catch(()=>!1),a=await(e.load??P)(),i=await(e.findTools??Co)(a.managedTools??[]);if(i.length===0)return await o()?"stamped":"skipped";let c=await Ue(async()=>a);return!c||!await o()?"skipped":(await(e.repair??Ft)(i,c.target)).some(d=>d.status==="failed")?(await dt(d=>{if(d.appliedRevision!==t)return{result:void 0};let u={...d};return r===void 0?delete u.appliedRevision:u.appliedRevision=r,{next:u,result:void 0}},void 0,e).catch(()=>{}),"retry"):"swept"}catch{return"skipped"}},IH=async e=>{if(!e.gateway||!e.clientKey)return!1;try{let t=await _a(e.gateway,e.clientKey),n=await Pa(t);return n.profileUpdated||n.toolsApplied>0}catch{return!1}},DE=async(e,t,n)=>{let o=await(t.reconcilePolicy??IH)(e).catch(()=>!1),a=o?await n().catch(()=>e):e,i=await(t.repairDrift??(c=>kH(c,t.runAmbientSelfcheck===!0)))(a).catch(()=>!1);return o||i},Ut=async(e={})=>{if($E())return"disabled";let t=e.now??Date.now,n=e.loadProfile??P,r=e.saveProfile??ce,o=e.loadDevKey??Fe,a=e.readState??It,s=e.writeState??Md,i=e.remint??Qt,c=e.heartbeat??RS,l=e.detectSeat??yn,d=e.rewriteTools??CH,u=e.rewriteHookLaneTools??Sh,p=e.probeHookLane??Na,m=e.classifyBeacon??yc,f=e.force===!0,h=!1,w=!1,y=!1,g=!1;e.hookLaneRepair===!0&&(f=!0,g=!0);let b=async C=>{if(!g){C==="repaired"&&await PE("none",{now:t,readState:a,writeState:s});return}let S=C;if(C==="repaired"){let E=await p().catch(()=>({verdict:"indeterminate",reason:"unreachable"}));S=E.verdict==="live"?"repaired":E.verdict==="dark"?"repair_failed":"unverified"}await PE(S,{now:t,readState:a,writeState:s})},k=async()=>{if(!e.runAmbientSelfcheck||w||!h)return!1;w=!0;let C;try{C=await n()}catch{return!1}return(e.ambientSelfcheck??(E=>SH(E,{now:t,readState:a,writeState:s},y)))(C).catch(()=>!1)};try{e.runAmbientSelfcheck&&(y=await dr().then(U=>U.some(Y=>!pr(Y.watcherPid))).catch(()=>!1),await EH({now:t,readState:a,writeState:s})),await(e.revivePendingWatchers??kb)();let C=await n();if(h=!0,!C.gateway||!C.enrolledCert)return"not-enrolled";let S=C.gateway,E=C.enrolledCertExpiry?Date.parse(C.enrolledCertExpiry):Date.parse(C.enrolledCert.payload.expiresAt);if(!Number.isFinite(E)||E<=t())return"cert-expired";let I=await o();if(!I)return"not-enrolled";let _=(e.resolveMachineUuid??Wt)()||void 0,T=await Bh(C,I,{now:t,loadProfile:n,saveProfile:r,loadDevKey:o,readState:a,writeState:s,...e.renewCert?{renew:e.renewCert}:{}});C=T.profile;let W=T.outcome==="renewed",Q=C.enrolledCert;if(!Q)return"not-enrolled";let G=Date.parse(C.clientKeyExpiresAt??""),ne=Number.isFinite(G)?G-t():0,z=await a(),j=!C.clientKey||ne<=Mh(C);if(!f&&dE(vn(z.hookLane),t())&&await m().catch(()=>"unreadable")!=="foreign"&&(f=!0,g=!0),C.clientKey&&(f||j)){let U=await dt(Y=>{let re=t()-(Y.lastAttemptAt??0);return re<IE?{result:"throttled"}:Y.failureCount&&re<_E(Y.failureCount,Y.keyTtlMs)?{result:"backoff"}:{next:{...Y,lastAttemptAt:t()},result:"ok"}},"throttled",{now:t,readState:a,writeState:s});if(U!=="ok")return U;try{let Y=await c(S,C.clientKey,Q,I,{machineUuid:_}),re=await n().catch(()=>C);return re.clientKey!==C.clientKey||re.enrolledCert?.sig!==Q.sig?"failed":(await r({...re,clientKeyExpiresAt:Y.expiresAt}),await Nd(({lastError:Qe,...Oe})=>({...Oe,lastAttemptAt:t(),lastSuccessAt:t(),failureCount:0,keyTtlMs:$d(C)??Oe.keyTtlMs}),{now:t,readState:a,writeState:s}),g?await b(await vH(C,S,C.clientKey,l,u)?"repaired":"repair_failed"):await b("repaired"),"heartbeat-refreshed")}catch(Y){let re=xE(Y);return await Nd(Qe=>({...Qe,lastAttemptAt:t(),failureCount:(Qe.failureCount??0)+1,lastError:{name:Y instanceof Error?Y.name:"Error",...re!==void 0?{code:re}:{}}}),{now:t,readState:a,writeState:s}),await b("repair_failed"),Y instanceof Ea&&Y.policyCode==="managed_device_required"&&console.error(Y.message),Y instanceof Ea?Y.status===404?"gateway-incompatible":"cert-rejected":"failed"}}if(!f&&C.clientKey&&!j){let U=await DE(C,e,n),Y=await k();return U||Y?"repaired":W?"cert-renewed":"not-due"}let le=await dt(U=>{let Y=t()-(U.lastAttemptAt??0);if(f)return Y<iH(U.failureCount)?{result:"throttled"}:{next:{...U,lastAttemptAt:t()},result:"ok"};let re=U.lastError?.code!==void 0&&rH.has(U.lastError.code)?oH:IE;return Y<re?{result:"throttled"}:U.failureCount&&Y<_E(U.failureCount,U.keyTtlMs)?{result:"backoff"}:{next:{...U,lastAttemptAt:t()},result:"ok"}},"throttled",{now:t,readState:a,writeState:s});if(le!=="ok")return le;try{let U=await i(S,Q,I,{machineUuid:_}),Y=await l().catch(()=>{}),re=Ee({origin:S,clientKey:U.key,subscription:C.authMode==="subscription",placeholder:C.authMode==="placeholder",byoUpstream:C.byoUpstream,seat:Y,user:C.name,team:C.team});if(await d(re,re.origin)===!1)throw new Error("one or more configured tools rejected the refreshed key");let Oe=await n().catch(()=>C),ve=null;Oe.enrolledCert&&await FE(Oe,Q.sig,I,o)&&(ve={...Oe,clientKey:U.key,clientKeyExpiresAt:U.expiresAt??Oe.clientKeyExpiresAt},await r(ve));let ut=U.expiresAt?Date.parse(U.expiresAt):NaN,D=$d(C)??(Number.isFinite(ut)&&ut-t()>0?ut-t():void 0);return await Nd(({lastError:$,...X})=>({...X,lastAttemptAt:t(),lastSuccessAt:t(),failureCount:0,keyTtlMs:D??X.keyTtlMs}),{now:t,readState:a,writeState:s}),ve&&await DE(ve,e,n),await b(ve?"repaired":"repair_failed"),await k(),"refreshed"}catch(U){let Y=xE(U);return await Nd(re=>({...re,lastAttemptAt:t(),failureCount:(re.failureCount??0)+1,lastError:{name:U instanceof Error?U.name:"Error",...Y!==void 0?{code:Y}:{}}}),{now:t,readState:a,writeState:s}),await b("repair_failed"),U instanceof lt&&U.policyCode==="managed_device_required"&&console.error(U.message),U instanceof lt?"cert-rejected":"failed"}}catch{return"failed"}finally{try{await k()}catch{}}};var xH=`anyray-connect print-key [--json | --passthrough-headers]
|
|
354
|
+
`;import{randomBytes as tU}from"node:crypto";var nU=1e4,rU="machine:",nE=e=>e.startsWith(rU),oU="cert-renew",aU=e=>{if(e===null||typeof e!="object")return!1;let t=e;if(t.alg!=="Ed25519"||typeof t.sig!="string"||!t.sig.trim())return!1;let n=t.payload;if(n===null||typeof n!="object")return!1;let r=n,o=a=>typeof a=="string"&&!!a.trim();return typeof r.v=="number"&&o(r.deploymentId)&&o(r.user)&&o(r.devPublicKey)&&o(r.issuedAt)&&o(r.expiresAt)},rE=async(e,t,n={})=>{let r=n.fetchImpl??fetch,o=n.now??Date.now,a=n.origin??Kn();try{let s=e?.payload?.deploymentId;if(!s)return{ok:!1,refused:!1};let i={deploymentId:s,issuedAt:new Date(o()).toISOString(),nonce:tU(16).toString("hex"),purpose:oU},c;try{c=await(n.signer??Ir)(wo(i),t)}catch{return{ok:!1,refused:!1}}let l=new AbortController,d=setTimeout(()=>l.abort(),nU),u;try{u=await r(`${a}/v1/cert/renew`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({cert:e,challenge:i,sig:c}),signal:l.signal})}finally{clearTimeout(d)}if(!u.ok)return{ok:!1,refused:u.status>=400&&u.status<500&&u.status!==429};let m=(await u.json().catch(()=>null))?.cert;return aU(m)?{ok:!0,cert:m}:{ok:!1,refused:!1}}catch{return{ok:!1,refused:!1}}};var Sh=async(e,t=e.origin,n=pe)=>{let r=0,o=0,a=!0;for(let s of n)try{if(!s.pointsAt||!await s.pointsAt(t)||await s.usesDynamicCredential?.(t))continue;r+=1,(await s.apply(e,{dryRun:!1})).status==="configured"?o+=1:a=!1}catch{a=!1}return{matched:r,rewritten:o,complete:a}},Eh=async(e,t=e.origin,n=pe)=>(await Sh(e,t,n)).complete;var sU=["claude","codex","cursor","opencode"],iU=["missing_key","key_invalid","key_unknown","key_expired","key_revoked","user_deactivated"],cU=new Set(["missing_key","key_expired"]);var lU=600*1e3,dU=600*1e3,oE=1440*60*1e3,uU=1440*60*1e3,pU=10080*60*1e3,fU=3600*1e3,mU=720*60*1e3,hU=e=>Math.min(mU,fU*2**Math.max(0,e-1)),Ai=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),Da=e=>typeof e=="number"&&Number.isSafeInteger(e)&&e>=0,aE=e=>typeof e=="string"&&iU.includes(e),vn=e=>{if(!Ai(e))return{};let t={};if(Da(e.watchSince)&&(t.watchSince=e.watchSince),Ai(e.invoked)){let n={};for(let r of sU){let o=e.invoked[r];Da(o)&&(n[r]=o)}Object.keys(n).length>0&&(t.invoked=n)}return Ai(e.authFailure)&&Da(e.authFailure.at)&&typeof e.authFailure.status=="number"&&Number.isSafeInteger(e.authFailure.status)&&(t.authFailure={at:e.authFailure.at,status:e.authFailure.status,...aE(e.authFailure.code)?{code:e.authFailure.code}:{}}),Ai(e.repair)&&Da(e.repair.at)&&(e.repair.outcome==="repaired"||e.repair.outcome==="repair_failed"||e.repair.outcome==="unverified")&&(t.repair={at:e.repair.at,outcome:e.repair.outcome,...Da(e.repair.failures)&&e.repair.failures>0?{failures:e.repair.failures}:{}}),t},Rd=e=>{try{let n=JSON.parse(e);if(Ai(n)&&aE(n.code)&&n.code!=="key_invalid")return n.code}catch{}let t=e.toLowerCase();if(t.includes("valid client key required"))return"key_invalid";if(t.includes("client key required"))return"missing_key"},Ih=e=>e!==void 0&&cU.has(e),xh=(e,t,n)=>{let r=e.invoked?.[t];return r===void 0?!0:r>n||n-r>=lU},sE=(e,t,n)=>({...e,watchSince:e.watchSince??n,invoked:{...e.invoked??{},[t]:n}}),Rh=(e,t)=>{let n=e.authFailure?.at;return n===void 0?!0:n>t||t-n>=dU},iE=(e,t)=>({...e,watchSince:e.watchSince??t.at,authFailure:t}),cE=(e,t)=>e.watchSince===void 0?{...e,watchSince:t}:e,lE=(e,t,n)=>{if(n==="repair_failed"||n==="unverified")return{...e,repair:{at:t,outcome:n,failures:(e.repair?.failures??0)+1}};let{authFailure:r,...o}=e;return n==="repaired"?{...o,repair:{at:t,outcome:n}}:o},dE=(e,t)=>{let n=e?.authFailure;if(!n||n.at>t||t-n.at>oE||!Ih(n.code))return!1;let r=e?.repair;return!(r&&r.outcome!=="repaired"&&r.at<=t&&t-r.at<hU(r.failures??1))},Od=e=>{let t=Object.values(e?.invoked??{}).filter(Da);return t.length>0?Math.max(...t):null},Oh=(e,t)=>{if(Od(e)!==null)return!1;let n=e?.watchSince;return n===void 0||n>t?!1:t-n>=pU},uE=(e,t)=>{let n=e?.repair;if(n&&n.outcome!=="unverified"&&n.at<=t&&t-n.at<=uU)return{status:n.outcome,...e?.authFailure?.code?{errorClass:e.authFailure.code}:{}};let r=e?.authFailure;if(r&&r.at<=t&&t-r.at<=oE)return{status:"key_rejected",...r.code?{errorClass:r.code}:{}}};var Th="x-anyray-retrieve-probe",Td=8e3,yU=e=>typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string",pE=(e,t)=>{let n=Zt(e);return t?.probe&&(n[Th]="1"),n},La=async(e,t,n)=>{if(!e)return{ok:!1,kind:"unconfigured",message:"Anyray gateway not configured (run `anyray-connect` to point your tools at it)."};let r=new AbortController,o=setTimeout(()=>r.abort(),Td);try{let a=await fetch(`${e.origin}/connect/retrieve`,{method:"POST",headers:pE(e,n),body:JSON.stringify({handle:t,...n?.startLine!==void 0&&{startLine:n.startLine},...n?.endLine!==void 0&&{endLine:n.endLine},...n?.grep!==void 0&&{grep:n.grep}}),signal:r.signal});if(a.status===404)return await a.json().then(c=>typeof c=="object"&&c!==null).catch(()=>!1)?{ok:!1,kind:"not-found",message:`No stashed content for handle ${t} (unknown or expired).`}:{ok:!1,kind:"unsupported",message:"Gateway has no /connect/retrieve route (update the gateway image)."};if(!a.ok){let i=await a.json().catch(()=>{}),c=yU(i)&&i.code==="slice_unsupported";return{ok:!1,kind:a.status===401||a.status===403?"auth":c?"slice-unsupported":"unavailable",message:`Retrieval unavailable (gateway returned HTTP ${a.status}).`}}let s;try{s=await a.json()}catch{return{ok:!1,kind:"malformed",message:"Retrieval returned malformed JSON."}}return typeof s?.content!="string"?{ok:!1,kind:"malformed",message:"Retrieval returned no content."}:{ok:!0,content:s.content,...typeof s.totalLines=="number"&&{totalLines:s.totalLines},...typeof s.totalChars=="number"&&{totalChars:s.totalChars},...typeof s.partial=="boolean"&&{partial:s.partial},...typeof s.startLine=="number"&&{startLine:s.startLine},...typeof s.endLine=="number"&&{endLine:s.endLine},...typeof s.grepMatches=="number"&&{grepMatches:s.grepMatches},...typeof s.grepTruncated=="boolean"&&{grepTruncated:s.grepTruncated}}}catch(a){let s=a instanceof Error&&a.name==="AbortError";return{ok:!1,kind:s?"timeout":"network",message:s?"Retrieval timed out.":`Retrieval failed: ${a instanceof Error?a.message:String(a)}`}}finally{clearTimeout(o)}},_d=async(e,t,n,r)=>{if(!e)return{ok:!1,kind:"unconfigured",message:"Anyray gateway not configured (run `anyray-connect` to point your tools at it)."};let o=new AbortController,a=setTimeout(()=>o.abort(),Td);try{let s=await fetch(`${e.origin}/connect/recall`,{method:"POST",headers:pE(e,r),body:JSON.stringify({query:t,...typeof n=="number"?{k:n}:{}}),signal:o.signal});if(!s.ok)return{ok:!1,kind:s.status===401||s.status===403?"auth":"unavailable",message:`Recall unavailable (gateway returned HTTP ${s.status}).`};let i;try{i=await s.json()}catch{return{ok:!1,kind:"malformed",message:"Recall returned malformed JSON."}}return Array.isArray(i?.matches)?{ok:!0,matches:i.matches}:{ok:!1,kind:"malformed",message:"Recall returned no matches list."}}catch(s){let i=s instanceof Error&&s.name==="AbortError";return{ok:!1,kind:i?"timeout":"network",message:i?"Recall timed out.":`Recall failed: ${s instanceof Error?s.message:String(s)}`}}finally{clearTimeout(a)}};var gU=5e3,wU=2048,bU=e=>{let t=e.toLowerCase();return t.includes("client key required")?!0:["missing_key","key_unknown","key_expired","key_revoked"].some(n=>t.includes(`"${n}"`))},Na=async(e={})=>{let t=e.readTarget??nt,n=e.fetch??fetch,r=e.timeoutMs??gU,o=null;try{o=await t()}catch{o=null}if(!o)return{verdict:"dark",reason:"target_null"};let a=new AbortController,s=setTimeout(()=>a.abort(),r);try{let i=Zt(o);i["content-type"]="application/json",i[Th]="1";let c=await n(`${o.origin}/connect/optimize-output`,{method:"POST",headers:i,body:JSON.stringify({}),signal:a.signal});if(c.status===401||c.status===403){let u=(await c.text().catch(()=>"")).slice(0,wU);if(!bU(u))return{verdict:"indeterminate",reason:"unsupported",status:c.status};let p=Rd(u);return{verdict:"dark",reason:"key_rejected",status:c.status,...p?{code:p}:{}}}if(!c.ok)return{verdict:"indeterminate",reason:c.status>=500?"unreachable":"unsupported",status:c.status};let l;try{l=await c.json()}catch{return{verdict:"indeterminate",reason:"unsupported",status:c.status}}return typeof l=="object"&&l!==null&&l.handled===!0?{verdict:"live",reason:"ok",status:c.status}:{verdict:"indeterminate",reason:"gateway_mismatch",status:c.status}}catch{return{verdict:"indeterminate",reason:"unreachable"}}finally{clearTimeout(s)}},_h=(e,t)=>e.verdict==="dark"?e.reason==="target_null"?{...e,detail:"Hook lane dark: no gateway target resolves on this machine, so the hook sends nothing.",remedy:["Fix: run `anyray-connect` once to (re)write the tool settings and the connect profile.","A hand-templated machine has no ~/.anyray profile and no base URL in the client settings \u2014 the hook silently no-ops."]}:{...e,detail:"Hook lane dark: the gateway rejected this machine\u2019s client key on /connect/optimize-output.",remedy:["The next scheduled refresh re-mints from the enrollment cert automatically and rewrites the tool configs.","If it keeps failing (revoked key, deactivated user, or a key pasted from elsewhere), re-enroll: run `anyray-connect` and follow the enrollment steer above."]}:e.verdict==="live"&&t.hookRegistered&&t.neverInvoked?{verdict:"dark",reason:"never_invoked",...e.status!==void 0?{status:e.status}:{},detail:"Hook lane dark: the hook is installed and the gateway answers, but nothing has invoked the hook here.",remedy:["Installed is not the same as firing \u2014 this seat has produced no hook run in the observation window.","OpenCode: its plugin turns a spawn failure into empty output silently \u2014 check the binary path in the generated plugin and restart OpenCode.","Claude Code / Codex: restart the tool so it re-reads its settings, then run a tool call that produces a large output."]}:e.verdict==="live"?{...e,detail:"Hook lane live: the gateway accepted this machine\u2019s key and answered the optimize probe.",remedy:[]}:{...e,detail:e.reason==="gateway_mismatch"?"Hook lane undetermined: the gateway answered but did not confirm it read the request (it predates the current hook protocol).":e.reason==="unreachable"?"Hook lane undetermined: could not reach the gateway for the probe.":"Hook lane undetermined: the response did not come from a gateway that serves /connect/optimize-output.",remedy:[e.reason==="gateway_mismatch"?"Fix: update the gateway image \u2014 this one predates the gzip-aware optimize-output contract.":"Not counted as a problem. Check the gateway origin and any proxy in front of it (see the Gateway section above)."]};import{randomBytes as kU}from"node:crypto";import{execSync as Ph}from"node:child_process";import{hostname as AU}from"node:os";var CU=e=>{try{if(e==="darwin"){let t=Ph("ioreg -rd1 -c IOPlatformExpertDevice",{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return/"IOPlatformUUID"\s*=\s*"([^"]+)"/.exec(t)?.[1]??""}if(e==="win32"){let t=Ph('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 Ph("cat /etc/machine-id 2>/dev/null || cat /var/lib/dbus/machine-id 2>/dev/null",{encoding:"utf8",stdio:["ignore","pipe","ignore"]})}catch{return""}},Pd=(e={platform:process.platform,read:()=>CU(process.platform),hostname:AU})=>e.read().trim()||e.hostname().trim();var Wt=(e={})=>{let t=(e.envUuid??process.env.ANYRAY_MACHINE_UUID??"").trim();if(t)return t.toLowerCase();if((e.platform??process.platform)==="darwin"){let r=e.readMacUuid??(()=>Pd());try{return r().trim().toLowerCase()}catch{return""}}return""};var vU=500,fE=2e3,SU=2e3,EU=250,mE=async(e,t,n,r)=>{let o=new AbortController,a=setTimeout(()=>o.abort(),vU);try{return(await fetch(`${e}/connect/health`,{method:"POST",headers:{...t,"x-anyray-connect-version":r},body:JSON.stringify({events:n}),signal:o.signal})).ok}catch{return!1}finally{clearTimeout(a)}},IU=e=>{let t=e.headers?.get?.("retry-after");if(!t)return;let n=Number(t.trim());return Number.isFinite(n)&&n>=0?n*1e3:void 0},xU=e=>new Promise(t=>setTimeout(t,e)),RU=async(e,t,n=xU)=>{for(let r=0;;r++){let o=new AbortController,a=setTimeout(()=>o.abort(),fE),s;try{let i=await fetch(e,{method:"POST",headers:{"content-type":"application/json"},body:t,signal:o.signal});if(i.ok)return!0;let c=i.status===429||i.status>=500;if(r>0||!c||(s=IU(i)??EU,s>SU))return!1}finally{clearTimeout(a)}await n(s)}},OU=async(e,t={})=>{try{let r=(await(t.loadProfile??P)()).enrolledCert,o=await(t.loadDevKey??Fe)(),a=r?.payload?.deploymentId;if(!r||!o||!a)return!1;let s={deploymentId:a,issuedAt:new Date().toISOString(),nonce:kU(16).toString("hex"),events:e},i;try{i=await(t.signer??Ir)(wo(s),o)}catch{return!1}return await(t.post??RU)(`${t.origin??Kn()}/v1/connect-events`,JSON.stringify({cert:r,challenge:s,sig:i}))}catch{return!1}},TU=async(e,t,n={})=>{try{let o=(await(n.loadProfile??P)()).enrolledCert,a=await(n.loadDevKey??Fe)();if(!o||!a)return;await(n.verify??Qt)(e,o,a,{timeoutMs:fE,machineUuid:(n.machineUuid??Wt)()||void 0,health:{events:t},telemetryOnly:!0})}catch{}},hE=async(e,t)=>{if(e.length!==0)try{let n=await nt(),r=n&&await mE(n.origin,Zt(n),e,t);if(n&&await TU(n.origin,e),r)return;await OU(e)}catch{}},Dh=async(e,t,n={readTarget:()=>nt("profile"),post:mE})=>{if(e.length===0)return!1;try{let r=await n.readTarget();return r?await n.post(r.origin,{"content-type":"application/json"},e,t):!1}catch{return!1}};var vo=["hook_registration","mcp_registration","hook_binary","beacon_target"];var gE=128,wE=300*1e3,_U=["repaired","repair_failed","flapping","pending"],PU=["settings_not_writable","mcp_unreadable","mcp_not_writable","mcp_foreign","mcp_not_persisted","apply_unconfirmed","apply_threw"],bE=["rebroke_same_day","repeat_days"],AE=new Set(pe.map(e=>e.id)),ko=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),ki=(e,t)=>typeof e=="string"&&t.some(n=>n===e),CE=e=>ki(e,vo),Dd=e=>{if(typeof e!="string"||!/^\d{4}-\d{2}-\d{2}$/.test(e))return!1;let t=Date.parse(`${e}T00:00:00.000Z`);return Number.isFinite(t)&&new Date(t).toISOString().slice(0,10)===e},Rr=e=>typeof e=="number"&&Number.isSafeInteger(e)&&e>=0,Ci=e=>{if(!(!Array.isArray(e)||!e.every(CE)))return jn(e)},DU=e=>{if(!ko(e))return;let t=Ci(e.checks);if(!(!Rr(e.since)||!ki(e.reason,bE)||!t?.length))return{since:e.since,reason:e.reason,checks:t}},LU=e=>{if(!ko(e))return;let t={};Dd(e.day)&&(t.day=e.day),Rr(e.attempts)&&(t.attempts=e.attempts);let n=Ci(e.attemptedChecks);n&&(t.attemptedChecks=n);let r=Ci(e.confirmedChecks);r&&(t.confirmedChecks=r);let o=Ci(e.brokenReportedChecks);o&&(t.brokenReportedChecks=o);let a=Ci(e.awaiting);if(a&&(t.awaiting=a),typeof e.dayHadNeed=="boolean"&&(t.dayHadNeed=e.dayHadNeed),Dd(e.lastConfirmedDay)&&(t.lastConfirmedDay=e.lastConfirmedDay),Rr(e.consecutiveRepairDays)&&(t.consecutiveRepairDays=e.consecutiveRepairDays),ko(e.lastRepaired)){let i={};for(let c of vo){let l=e.lastRepaired[c];Rr(l)&&(i[c]=l)}Object.keys(i).length>0&&(t.lastRepaired=i)}let s=DU(e.flapping);return s&&(t.flapping=s),t},NU=e=>{if(!ko(e)||!Dd(e.day)||!Rr(e.sequence)||e.sequence===0||typeof e.tool!="string"||!AE.has(e.tool)||!CE(e.checkId)||!ki(e.status,_U)||typeof e.delivered!="boolean")return;let t;if(e.status==="repair_failed"){if(!ki(e.errorClass,PU))return;t=e.errorClass}else if(e.status==="flapping"){if(!ki(e.errorClass,bE))return;t=e.errorClass}else if(e.errorClass!==void 0)return;return{day:e.day,sequence:e.sequence,tool:e.tool,checkId:e.checkId,status:e.status,...t?{errorClass:t}:{},delivered:e.delivered,...Rr(e.attemptedAt)?{attemptedAt:e.attemptedAt}:{}}},yE=e=>{if(!ko(e))return{};let t={};if(ko(e.adapters)){let n={};for(let r of AE){let o=LU(e.adapters[r]);o&&(n[r]=o)}Object.keys(n).length>0&&(t.adapters=n)}return Array.isArray(e.events)&&(t.events=e.events.map(NU).filter(n=>n!==void 0).slice(-gE)),Rr(e.nextSequence)&&e.nextSequence>0&&(t.nextSequence=e.nextSequence),ko(e.report)&&Dd(e.report.day)&&typeof e.report.delivered=="boolean"&&(t.report={day:e.report.day,delivered:e.report.delivered,...Rr(e.report.attemptedAt)?{attemptedAt:e.report.attemptedAt}:{}}),t},$U=e=>new Date(e).toISOString().slice(0,10),MU=(e,t)=>e!==void 0&&Date.parse(`${t}T00:00:00.000Z`)-Date.parse(`${e}T00:00:00.000Z`)===1440*60*1e3,jn=e=>[...new Set(e)],Ld=(e,t)=>{let n=e??{};if(n.day===t)return n;let r=n.day!==void 0&&n.dayHadNeed===!1;return{...n,day:t,attempts:0,attemptedChecks:[],confirmedChecks:[],brokenReportedChecks:[],dayHadNeed:!1,...r?{consecutiveRepairDays:0,lastConfirmedDay:void 0,flapping:void 0}:{}}},vi=(e,t,n)=>{let r=e.nextSequence??1,o=n.map(a=>({...a,day:t,sequence:r++,delivered:!1}));return{...e,events:[...(e.events??[]).filter(a=>a.day===t),...o].slice(-gE),nextSequence:r}},BU=e=>({tool:e.tool,checkId:e.checkId,status:e.status,...e.errorClass?{errorClass:e.errorClass}:{}}),FU=async e=>await Ue(async()=>e)??null,WU=async(e,t,n)=>{let r=new Map(e.map(({adapter:o,checks:a})=>[o.id,Object.values(a).some(s=>s==="missing")]));await n.claimState(o=>{let a={...o.adapters??{}};for(let{adapter:s}of e){let i=Ld(a[s.id],t);a[s.id]={...i,dayHadNeed:!!(i.dayHadNeed||r.get(s.id))}}return{next:{...o,adapters:a,events:(o.events??[]).filter(s=>s.day===t)},result:void 0}},void 0)},kE=(e,t,n,r)=>{if(t.length===0)return{adapter:e,slowFlap:!1};let o=e.lastConfirmedDay===n?e.consecutiveRepairDays??1:MU(e.lastConfirmedDay,n)?(e.consecutiveRepairDays??0)+1:1,a=o>=3,s={...e.lastRepaired??{}};for(let c of t)s[c]=r;let i=e.flapping;return{adapter:{...e,confirmedChecks:jn([...e.confirmedChecks??[],...t]),brokenReportedChecks:(e.brokenReportedChecks??[]).filter(c=>!t.includes(c)),lastConfirmedDay:n,consecutiveRepairDays:o,lastRepaired:s,...a?{flapping:{since:i?.since??r,reason:"repeat_days",checks:jn([...i?.checks??[],...t])}}:{}},slowFlap:a}},UU=async(e,t,n,r,o)=>{let a=new Map(e.map(s=>[s.adapter.id,s]));await o.claimState(s=>{let i=s,c={...s.adapters??{}};for(let[l,d]of Object.entries(c)){let u=Ld(d,n),p=u.awaiting??[],m=a.get(l);if(p.length===0||t.has(l)||!m){c[l]=u;continue}let f=p.filter(g=>m.checks[g]==="owned"),h=p.filter(g=>{let b=m.checks[g];return b==="missing"||b==="foreign"}),w=p.filter(g=>{let b=m.checks[g];return b===void 0||b==="unreadable"}),y=kE(u,f,n,r);c[l]={...y.adapter,awaiting:w.length>0?w:void 0},i=vi(i,n,[...f.map(g=>({tool:l,checkId:g,status:"repaired"})),...h.map(g=>({tool:l,checkId:g,status:"repair_failed",errorClass:"apply_unconfirmed"})),...y.slowFlap?f.map(g=>({tool:l,checkId:g,status:"flapping",errorClass:"repeat_days"})):[]])}return{next:{...i,adapters:c},result:void 0}},void 0)},HU=async(e,t,n,r,o,a,s)=>s.claimState(i=>{let c={...i.adapters??{}},l=Ld(c[e],o);if(r&&(l.awaiting?.length??0)>0)return{result:void 0};let d=l.attemptedChecks??[],u=l.confirmedChecks??[],p=t.filter(y=>!d.includes(y)||u.includes(y)),m=p.filter(y=>u.includes(y)),f=l.attempts??0;if(f>=2||p.length===0&&!n){let y=m.filter(k=>!(l.brokenReportedChecks??[]).includes(k));if(y.length===0)return{result:void 0};let g=l.flapping;return c[e]={...l,brokenReportedChecks:jn([...l.brokenReportedChecks??[],...y]),flapping:{since:g?.since??a,reason:"rebroke_same_day",checks:jn([...g?.checks??[],...y])}},{next:vi({...i,adapters:c},o,y.map(k=>({tool:e,checkId:k,status:"flapping",errorClass:"rebroke_same_day"}))),result:void 0}}let h=l.flapping;return c[e]={...l,attempts:f+1,attemptedChecks:jn([...d,...p]),confirmedChecks:u.filter(y=>!p.includes(y)),brokenReportedChecks:jn([...l.brokenReportedChecks??[],...m]),...m.length>0?{flapping:{since:h?.since??a,reason:"rebroke_same_day",checks:jn([...h?.checks??[],...m])}}:{}},{next:vi({...i,adapters:c},o,m.map(y=>({tool:e,checkId:y,status:"flapping",errorClass:"rebroke_same_day"}))),result:{checks:p,fastFlaps:m}}},void 0),GU=async(e,t,n,r,o,a,s)=>{await s.claimState(i=>{let c={...i.adapters??{}},l=Ld(c[e],o);if(n.status==="queued")return c[e]={...l,awaiting:jn([...l.awaiting??[],...t])},{next:vi({...i,adapters:c},o,t.map(f=>({tool:e,checkId:f,status:"pending"}))),result:void 0};let d=n.status==="configured"&&r?t.filter(f=>r[f]==="owned"):[],u=n.status==="configured"&&r?t.filter(f=>{let h=r[f];return h==="missing"||h==="foreign"}):n.status==="failed"||n.status!=="configured"?t:[],p=kE(l,d,o,a);c[e]=p.adapter;let m=n.status==="failed"?n.errorClass??"apply_threw":n.errorClass??"apply_unconfirmed";return{next:vi({...i,adapters:c},o,[...d.map(f=>({tool:e,checkId:f,status:"repaired"})),...u.map(f=>({tool:e,checkId:f,status:"repair_failed",errorClass:m})),...p.slowFlap?d.map(f=>({tool:e,checkId:f,status:"flapping",errorClass:"repeat_days"})):[]]),result:void 0}},void 0)},VU=async(e,t,n,r)=>{let o=await r.claimState(i=>{let c=(i.events??[]).filter(u=>u.day===e&&!u.delivered&&(u.attemptedAt===void 0||u.attemptedAt>t||t-u.attemptedAt>=wE));if(c.length===0)return{result:[]};let l=new Set(c.map(u=>`${u.day}:${u.sequence}`)),d=(i.events??[]).map(u=>l.has(`${u.day}:${u.sequence}`)?{...u,attemptedAt:t}:u);return{next:{...i,events:d},result:c.map(u=>({...u,attemptedAt:t}))}},[]);if(o.length===0||!await(r.report??Dh)(o.map(BU),n).catch(()=>!1))return;let s=new Set(o.map(i=>`${i.day}:${i.sequence}`));await r.claimState(i=>({next:{...i,events:(i.events??[]).map(c=>s.has(`${c.day}:${c.sequence}`)?{...c,delivered:!0}:c)},result:void 0}),void 0)},KU=async(e,t,n,r,o,a)=>{let s=[],i=!1,c=new Set(n.map(u=>u.adapter));for(let{adapter:u,checks:p}of t){let m=r.adapters?.[u.id];for(let f of vo){let h=p[f];if(!h||h==="unreadable")continue;let w,y;m?.awaiting?.includes(f)&&c.has(u.id)?w="pending":h==="missing"&&m?.flapping?.checks.includes(f)?(w="flapping",y=m.flapping.reason):w=h==="owned"?"ok":h,w!=="ok"&&w!=="pending"&&(i=!0),s.push({tool:u.id,checkId:f,status:w,...y?{errorClass:y}:{}})}}let l=Date.parse(e.enrolledCert?.payload.expiresAt??e.enrolledCertExpiry??"");e.enrolledCert&&Number.isFinite(l)&&(l<=o?(i=!0,s.push({tool:"connect",checkId:"enrollment_cert",status:"expired"})):l-o<=336*60*60*1e3&&(i=!0,s.push({tool:"connect",checkId:"enrollment_cert",status:"problems",errorClass:"cert_expiring"}))),e.refreshSchedulerEnabled&&e.persistenceOwner!=="tray"&&!await(a.schedulerInstalled??Ho)()&&(i=!0,s.push({tool:"connect",checkId:"refresh_scheduler",status:"missing",errorClass:"refresh_scheduler_missing"})),(a.deadWatcherObserved||n.some(u=>!(a.pidAlive??pr)(u.watcherPid)))&&(i=!0,s.push({tool:"connect",checkId:"pending_op",status:"problems",errorClass:"watcher_dead"}));let d=uE(await a.readHookLane?.().catch(()=>({})),o);return d&&(d.status!=="repaired"&&(i=!0),s.push({tool:"connect",checkId:"hook_lane",status:d.status,...d.errorClass?{errorClass:d.errorClass}:{}})),s.push({tool:"connect",checkId:"selfcheck_report",status:i?"problems":"ok"}),s},jU=async(e,t,n,r,o,a,s)=>{if(!await s.claimState(u=>u.report?.day===r&&u.report.delivered?{result:!1}:u.report?.day===r&&u.report.attemptedAt!==void 0&&u.report.attemptedAt<=o&&o-u.report.attemptedAt<wE?{result:!1}:{next:{...u,report:{day:r,delivered:!1,attemptedAt:o}},result:!0},!1))return;let c=await s.readState().catch(()=>({})),l=await KU(e,t,n,c,o,s);await(s.report??Dh)(l,a).catch(()=>!1)&&await s.claimState(u=>u.report?.day===r?{next:{...u,report:{day:r,delivered:!0}},result:void 0}:{result:void 0},void 0)},vE=async(e,t,n)=>{let r=n.now??Date.now,o=$U(r()),a=e.managedTools??[],s={...n,readState:async()=>yE(await n.readState()),claimState:async(i,c)=>n.claimState(l=>i(yE(l)),c)};try{let i=await(s.findIntegrations??Ch)(a);await WU(i,o,s);let c=await(s.listPending??dr)().catch(()=>[]),l=new Set(c.map(y=>y.adapter));await UU(i,l,o,r(),s);let d=await(s.resolveTarget??FU)(e),u=d?await(s.findDrifted??Ra)(a,d.target.origin):[],p=new Set(u.map(y=>y.id)),m=new Map(i.map(y=>[y.adapter.id,y]));for(let y of u)m.has(y.id)||m.set(y.id,{adapter:y,checks:{}});let f=!1,h=(s.runtimeDurable??oe)();if(d)for(let{adapter:y,checks:g}of m.values()){let b=h?vo.filter(T=>g[T]==="missing"):[];if(b.length===0&&!p.has(y.id))continue;let k=g;if(y.integrationStatus)try{k=await y.integrationStatus()}catch{k=Object.fromEntries(vo.map(T=>[T,"unreadable"]))}let C=b.filter(T=>k[T]==="missing"),S=p.has(y.id);if(S&&y.pointsAt&&(S=!await y.pointsAt(d.target.origin).catch(()=>!0)),C.length===0&&!S)continue;let E=await HU(y.id,C,S,l.has(y.id),o,r(),s);if(!E)continue;let[I]=await(s.repair??Ft)([y],d.target);if(!I)continue;f=!0;let _;I.status==="configured"&&y.integrationStatus&&(_=await y.integrationStatus().catch(()=>{})),await GU(y.id,E.checks,I,_,o,r(),s)}await VU(o,r(),t,s),i=await(s.findIntegrations??Ch)(a);let w=await(s.listPending??dr)().catch(()=>[]);return await jU(e,i,w,o,r(),t,s),f}catch{return!1}};var QU=14,eH=.35,tH=900*1e3,EE=360*60*1e3,nH=.2,rH=1800*1e3,IE=3600*1e3,oH=new Set(["ENOTFOUND","EAI_AGAIN","ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENETDOWN","ENETUNREACH","EHOSTUNREACH","EPIPE","UND_ERR_CONNECT_TIMEOUT","UND_ERR_SOCKET"]),aH=300*1e3,sH=30*1e3,iH=900*1e3,cH=(e=0)=>Math.min(iH,sH*2**Math.max(0,e)),xE=e=>{let t=e;for(let n=0;n<5&&t;n++){let r=t.code;if(typeof r=="string")return r;t=t.cause}},RE=1440*60*1e3,lH=300*1e3,dH=.25,uH=.5,OE=3600*1e3,pH=720*60*60*1e3,fH=360*60*1e3,mH=1440*60*1e3,hH=()=>LE(JU(),".anyray"),Lh=()=>LE(hH(),"refresh-state.json"),Nh=e=>process.env?.[e],$E=()=>Nh("ANYRAY_REFRESH_DISABLE")==="true",$h=()=>{let e=Nh("ANYRAY_REFRESH_WINDOW_DAYS"),t=e?Number.parseInt(e,10):NaN;return(Number.isFinite(t)&&t>0?t:QU)*mH},$d=e=>{let t=e.enrolledCert?.payload.keyTtlSeconds;return typeof t=="number"&&Number.isFinite(t)&&t>0?t*1e3:void 0},ME=new Set(["claude-code","codex","opencode","cursor","copilot","copilot-cli","claude-desktop","jetbrains","windsurf"]),yH=10080*60*1e3,BE=(e,t,n=Date.now())=>{let r=[],o=$d(e);o!==void 0&&r.push(o);let a=Date.parse(t??e.clientKeyExpiresAt??"");Number.isFinite(a)&&r.push(a-n);let s=Date.parse(e.enrolledCertExpiry??e.enrolledCert?.payload.expiresAt??"");return Number.isFinite(s)&&r.push(s-n),r.length===0?!1:Math.min(...r)<=yH},Mh=e=>{let t=$h(),n=e?$d(e):void 0;if(!n)return t;let r=Math.max(tH,Math.round(n*eH));return Math.min(t,r)},gH=e=>{let t=Nh("ANYRAY_REFRESH_THROTTLE_MS"),n=t?Number.parseInt(t,10):NaN;return Number.isFinite(n)&&n>0?n:typeof e=="number"&&Number.isFinite(e)&&e>0?Math.min(EE,Math.max(rH,Math.round(e*nH))):EE},It=async()=>{try{let e=await XU(Lh(),"utf-8"),t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}},Md=async e=>{try{let t=Lh(),n=`${t}.${process.pid}.tmp`;await NE(n,JSON.stringify(e),{mode:384}),await ye(n,t),await zU(t,384).catch(()=>{})}catch{}},wH=3e4,bH=()=>`${Lh()}.lock`,TE=async e=>{try{return await NE(e,String(process.pid),{flag:"wx",mode:384}),!0}catch(t){if(t.code!=="EEXIST")throw t;return!1}},dt=async(e,t,n={})=>{let r=n.now??Date.now,o=n.readState??It,a=n.writeState??Md,s=bH(),i=!1;try{if(i=await TE(s),!i){if(await qU(s).then(l=>r()-l.mtimeMs).catch(()=>1/0)<wH)return t;await SE(s).catch(()=>{}),i=await TE(s).catch(()=>!1)}}catch{}try{let c=await o(),{next:l,result:d}=e(c);return l&&await a(l),d}finally{i&&await SE(s).catch(()=>{})}},Nd=async(e,t={})=>{await dt(n=>({next:e(n),result:void 0}),void 0,t).catch(()=>{})},$a=async(e={},t={})=>{let n=t.now??Date.now,r=e.expiresAt?Date.parse(e.expiresAt):NaN,o=e.keyTtlMs??(Number.isFinite(r)&&r-n()>0?r-n():void 0);await dt(({lastError:a,...s})=>({next:{...s,lastAttemptAt:n(),lastSuccessAt:n(),failureCount:0,keyTtlMs:o??s.keyTtlMs},result:void 0}),void 0,t).catch(()=>{})},So=async(e={})=>{let t=e.now??Date.now;await dt(n=>({next:{...n,lastAttemptAt:t()},result:void 0}),void 0,e).catch(()=>{})},AH=e=>{let t=e.enrolledCertLifetimeMs,n=Date.parse(e.enrolledCert?.payload.issuedAt??""),r=Date.parse(e.enrolledCertExpiry??e.enrolledCert?.payload.expiresAt??""),o=typeof t=="number"&&Number.isFinite(t)&&t>0?t:Number.isFinite(n)&&Number.isFinite(r)&&r>n?r-n:void 0;return o?Math.min(pH,Math.max(OE,Math.round(o*uH))):OE},FE=async(e,t,n,r)=>e.enrolledCert?.sig!==t?!1:await r().catch(()=>{})===n,Bh=async(e,t,n={})=>{let r=n.now??Date.now,o=n.saveProfile??ce,a=n.loadProfile??P,s=n.loadDevKey??Fe,i=n.renew??rE,c=e.enrolledCert;if(!c)return{outcome:"not-due",profile:e};if(nE(c.payload.user))return{outcome:"not-due",profile:e};let l=Date.parse(e.enrolledCertExpiry??c.payload.expiresAt??"");if(!Number.isFinite(l))return{outcome:"not-due",profile:e};if(l-r()>AH(e))return{outcome:"not-due",profile:e};if(!await dt(w=>r()-(w.lastCertRenewAt??0)<fH?{result:!1}:{next:{...w,lastCertRenewAt:r()},result:!0},!1,n).catch(()=>!1))return{outcome:"throttled",profile:e};let u=await i(c,t);if(!u.ok)return{outcome:u.refused?"refused":"failed",profile:e};let p=await a().catch(()=>e);if(!p.enrolledCert)return{outcome:"failed",profile:e};if(!await FE(p,c.sig,t,s))return{outcome:"superseded",profile:p};let m=u.cert.payload.expiresAt,f=Date.parse(m)-r(),h={...p,enrolledCert:u.cert,enrolledCertExpiry:m,...Number.isFinite(f)&&f>0?{enrolledCertLifetimeMs:f}:{}};return await o(h),{outcome:"renewed",profile:h}},_E=(e,t)=>{let n=t!==void 0&&Number.isFinite(t)&&t>0?Math.round(t*dH):RE,r=Math.min(RE,n);return Math.min(r,lH*2**Math.max(0,e-1))},CH=()=>{let{command:e,args:t}=or(Qn);return{exe:e,args:t}},Or=async(e={})=>{if($E())return;let t=e.now??Date.now,n=e.readState??It,r=e.writeState??Md,o=e.spawnRefresh??(()=>{let{exe:a,args:s}=CH();YU(a,s,{detached:!0,stdio:"ignore"}).unref()});try{if(!await dt(s=>t()-(s.lastSpawnAt??0)<gH(s.keyTtlMs)?{result:!1}:{next:{...s,lastSpawnAt:t()},result:!0},!1,{now:t,readState:n,writeState:r}))return;o()}catch{}},kH=Eh,vH=async(e,t=!1)=>{try{let n=e.managedTools??[];if(n.length===0)return!1;let r=await Ue(async()=>e);if(!r)return!1;let o=await Ra(n,r.target.origin),a=t?XS(o):o;return a.length===0?!1:(await Ft(a,r.target),!0)}catch{return!1}},SH=async(e,t,n,r,o)=>{try{let a=new Set(e.managedTools??[]),s=pe.filter(d=>a.has(d.id));if(s.length===0)return!1;let i=await r().catch(()=>{}),c=Ee({origin:t,clientKey:n,subscription:e.authMode==="subscription",placeholder:e.authMode==="placeholder",byoUpstream:e.byoUpstream,seat:i,user:e.name,team:e.team}),l=await o(c,c.origin,s);return l.matched>0&&l.complete}catch{return!1}},EH=async(e,t,n)=>{let r=t.now??Date.now,o=t.readState??It,a=t.writeState??Md;return vE(e,ke,{now:r,deadWatcherObserved:n,readHookLane:()=>Bd({now:r,readState:o,writeState:a}),readState:async()=>(await o()).selfcheck??{},claimState:async(s,i)=>dt(c=>{let l=s(c.selfcheck??{});return{...l.next?{next:{...c,selfcheck:l.next}}:{},result:l.result}},i,{now:r,readState:o,writeState:a})})},Bd=async(e={})=>{let n=await(e.readState??It)().catch(()=>({}));return vn(n.hookLane)},WE=async(e,t={})=>{try{let n=t.now??Date.now,r=await Bd(t);if(!xh(r,e,n()))return;await dt(o=>{let a=vn(o.hookLane);return xh(a,e,n())?{next:{...o,hookLane:sE(a,e,n())},result:void 0}:{result:void 0}},void 0,t)}catch{}},UE=async(e,t={})=>{try{let n=t.now??Date.now,r=await Bd(t);if(!Rh(r,n()))return;await dt(o=>{let a=vn(o.hookLane);return Rh(a,n())?{next:{...o,hookLane:iE(a,e)},result:void 0}:{result:void 0}},void 0,t)}catch{}},IH=async(e={})=>{try{let t=e.now??Date.now;if((await Bd(e)).watchSince!==void 0)return;await dt(n=>{let r=vn(n.hookLane);return r.watchSince!==void 0?{result:void 0}:{next:{...n,hookLane:cE(r,t())},result:void 0}},void 0,e)}catch{}},PE=async(e,t={})=>{try{let n=t.now??Date.now;await dt(r=>{let o=vn(r.hookLane),a=lE(o,n(),e);return JSON.stringify(a)===JSON.stringify(o)?{result:void 0}:{next:{...r,hookLane:a},result:void 0}},void 0,t)}catch{}},HE=async(e={})=>{try{if((await(e.readState??It)()).repathedAt)return"skipped";let n=e.now??Date.now,r=async()=>dt(c=>c.repathedAt?{result:!1}:{next:{...c,repathedAt:n()},result:!0},!1,e).catch(()=>!1);if(!(e.launcherBacked??nw)())return await r()?"stamped":"skipped";let o=await(e.load??P)(),s=await(e.findTools??Co)(o.managedTools??[]);if(s.length===0)return await r()?"stamped":"skipped";let i=await Ue(async()=>o);return!i||!await r()?"skipped":(await(e.repair??Ft)(s,i.target),"repathed")}catch{return"skipped"}},GE=async(e={})=>{try{let t=e.revision??1,r=(await(e.readState??It)()).appliedRevision;if((r??0)>=t)return"skipped";let o=async()=>dt(d=>(d.appliedRevision??0)>=t?{result:!1}:{next:{...d,appliedRevision:t},result:!0},!1,e).catch(()=>!1),a=await(e.load??P)(),i=await(e.findTools??Co)(a.managedTools??[]);if(i.length===0)return await o()?"stamped":"skipped";let c=await Ue(async()=>a);return!c||!await o()?"skipped":(await(e.repair??Ft)(i,c.target)).some(d=>d.status==="failed")?(await dt(d=>{if(d.appliedRevision!==t)return{result:void 0};let u={...d};return r===void 0?delete u.appliedRevision:u.appliedRevision=r,{next:u,result:void 0}},void 0,e).catch(()=>{}),"retry"):"swept"}catch{return"skipped"}},xH=async e=>{if(!e.gateway||!e.clientKey)return!1;try{let t=await _a(e.gateway,e.clientKey),n=await Pa(t);return n.profileUpdated||n.toolsApplied>0}catch{return!1}},DE=async(e,t,n)=>{let o=await(t.reconcilePolicy??xH)(e).catch(()=>!1),a=o?await n().catch(()=>e):e,i=await(t.repairDrift??(c=>vH(c,t.runAmbientSelfcheck===!0)))(a).catch(()=>!1);return o||i},Ut=async(e={})=>{if($E())return"disabled";let t=e.now??Date.now,n=e.loadProfile??P,r=e.saveProfile??ce,o=e.loadDevKey??Fe,a=e.readState??It,s=e.writeState??Md,i=e.remint??Qt,c=e.heartbeat??RS,l=e.detectSeat??yn,d=e.rewriteTools??kH,u=e.rewriteHookLaneTools??Sh,p=e.probeHookLane??Na,m=e.classifyBeacon??yc,f=e.force===!0,h=!1,w=!1,y=!1,g=!1;e.hookLaneRepair===!0&&(f=!0,g=!0);let b=async C=>{if(!g){C==="repaired"&&await PE("none",{now:t,readState:a,writeState:s});return}let S=C;if(C==="repaired"){let E=await p().catch(()=>({verdict:"indeterminate",reason:"unreachable"}));S=E.verdict==="live"?"repaired":E.verdict==="dark"?"repair_failed":"unverified"}await PE(S,{now:t,readState:a,writeState:s})},k=async()=>{if(!e.runAmbientSelfcheck||w||!h)return!1;w=!0;let C;try{C=await n()}catch{return!1}return(e.ambientSelfcheck??(E=>EH(E,{now:t,readState:a,writeState:s},y)))(C).catch(()=>!1)};try{e.runAmbientSelfcheck&&(y=await dr().then(U=>U.some(Y=>!pr(Y.watcherPid))).catch(()=>!1),await IH({now:t,readState:a,writeState:s})),await(e.revivePendingWatchers??kb)();let C=await n();if(h=!0,!C.gateway||!C.enrolledCert)return"not-enrolled";let S=C.gateway,E=C.enrolledCertExpiry?Date.parse(C.enrolledCertExpiry):Date.parse(C.enrolledCert.payload.expiresAt);if(!Number.isFinite(E)||E<=t())return"cert-expired";let I=await o();if(!I)return"not-enrolled";let _=(e.resolveMachineUuid??Wt)()||void 0,T=await Bh(C,I,{now:t,loadProfile:n,saveProfile:r,loadDevKey:o,readState:a,writeState:s,...e.renewCert?{renew:e.renewCert}:{}});C=T.profile;let W=T.outcome==="renewed",Q=C.enrolledCert;if(!Q)return"not-enrolled";let G=Date.parse(C.clientKeyExpiresAt??""),ne=Number.isFinite(G)?G-t():0,z=await a(),j=!C.clientKey||ne<=Mh(C);if(!f&&dE(vn(z.hookLane),t())&&await m().catch(()=>"unreadable")!=="foreign"&&(f=!0,g=!0),C.clientKey&&(f||j)){let U=await dt(Y=>{let re=t()-(Y.lastAttemptAt??0);return re<IE?{result:"throttled"}:Y.failureCount&&re<_E(Y.failureCount,Y.keyTtlMs)?{result:"backoff"}:{next:{...Y,lastAttemptAt:t()},result:"ok"}},"throttled",{now:t,readState:a,writeState:s});if(U!=="ok")return U;try{let Y=await c(S,C.clientKey,Q,I,{machineUuid:_}),re=await n().catch(()=>C);return re.clientKey!==C.clientKey||re.enrolledCert?.sig!==Q.sig?"failed":(await r({...re,clientKeyExpiresAt:Y.expiresAt}),await Nd(({lastError:Qe,...Oe})=>({...Oe,lastAttemptAt:t(),lastSuccessAt:t(),failureCount:0,keyTtlMs:$d(C)??Oe.keyTtlMs}),{now:t,readState:a,writeState:s}),g?await b(await SH(C,S,C.clientKey,l,u)?"repaired":"repair_failed"):await b("repaired"),"heartbeat-refreshed")}catch(Y){let re=xE(Y);return await Nd(Qe=>({...Qe,lastAttemptAt:t(),failureCount:(Qe.failureCount??0)+1,lastError:{name:Y instanceof Error?Y.name:"Error",...re!==void 0?{code:re}:{}}}),{now:t,readState:a,writeState:s}),await b("repair_failed"),Y instanceof Ea&&Y.policyCode==="managed_device_required"&&console.error(Y.message),Y instanceof Ea?Y.status===404?"gateway-incompatible":"cert-rejected":"failed"}}if(!f&&C.clientKey&&!j){let U=await DE(C,e,n),Y=await k();return U||Y?"repaired":W?"cert-renewed":"not-due"}let le=await dt(U=>{let Y=t()-(U.lastAttemptAt??0);if(f)return Y<cH(U.failureCount)?{result:"throttled"}:{next:{...U,lastAttemptAt:t()},result:"ok"};let re=U.lastError?.code!==void 0&&oH.has(U.lastError.code)?aH:IE;return Y<re?{result:"throttled"}:U.failureCount&&Y<_E(U.failureCount,U.keyTtlMs)?{result:"backoff"}:{next:{...U,lastAttemptAt:t()},result:"ok"}},"throttled",{now:t,readState:a,writeState:s});if(le!=="ok")return le;try{let U=await i(S,Q,I,{machineUuid:_}),Y=await l().catch(()=>{}),re=Ee({origin:S,clientKey:U.key,subscription:C.authMode==="subscription",placeholder:C.authMode==="placeholder",byoUpstream:C.byoUpstream,seat:Y,user:C.name,team:C.team});if(await d(re,re.origin)===!1)throw new Error("one or more configured tools rejected the refreshed key");let Oe=await n().catch(()=>C),ve=null;Oe.enrolledCert&&await FE(Oe,Q.sig,I,o)&&(ve={...Oe,clientKey:U.key,clientKeyExpiresAt:U.expiresAt??Oe.clientKeyExpiresAt},await r(ve));let ut=U.expiresAt?Date.parse(U.expiresAt):NaN,D=$d(C)??(Number.isFinite(ut)&&ut-t()>0?ut-t():void 0);return await Nd(({lastError:$,...X})=>({...X,lastAttemptAt:t(),lastSuccessAt:t(),failureCount:0,keyTtlMs:D??X.keyTtlMs}),{now:t,readState:a,writeState:s}),ve&&await DE(ve,e,n),await b(ve?"repaired":"repair_failed"),await k(),"refreshed"}catch(U){let Y=xE(U);return await Nd(re=>({...re,lastAttemptAt:t(),failureCount:(re.failureCount??0)+1,lastError:{name:U instanceof Error?U.name:"Error",...Y!==void 0?{code:Y}:{}}}),{now:t,readState:a,writeState:s}),await b("repair_failed"),U instanceof lt&&U.policyCode==="managed_device_required"&&console.error(U.message),U instanceof lt?"cert-rejected":"failed"}}catch{return"failed"}finally{try{await k()}catch{}}};var RH=`anyray-connect print-key [--json | --passthrough-headers]
|
|
355
355
|
|
|
356
356
|
Print the current short-lived Anyray client key for a consuming app.
|
|
357
357
|
|
|
@@ -363,8 +363,8 @@ Options:
|
|
|
363
363
|
"x-anyray-provider":"anthropic","x-anyray-metadata":"..."}).
|
|
364
364
|
Carries the client key, never the seat OAuth token.
|
|
365
365
|
--help Show this help.
|
|
366
|
-
`,
|
|
367
|
-
`);let s=o.passthroughHeaders?
|
|
366
|
+
`,OH=e=>{let t=!1,n=!1,r=!1;for(let o of e)if(o==="--json")t=!0;else if(o==="--passthrough-headers")n=!0;else if(o==="--help"||o==="-h")r=!0;else throw new Error(`Unknown option: ${o}`);if(t&&n)throw new Error("Use only one of --json or --passthrough-headers.");return{json:t,passthroughHeaders:n,help:r}},TH=(e,t)=>{let n=Date.parse(e.clientKeyExpiresAt??"");return Number.isFinite(n)?n-t()<=Mh(e):!0},VE=e=>{if(!e.gateway)throw new Error("Not enrolled or configured. Run `anyray-connect` before `anyray-connect print-key`.")},KE=(e,t)=>{if(!be(e.clientKey))return!1;if(!e.clientKeyExpiresAt)return!0;let n=Date.parse(e.clientKeyExpiresAt);return Number.isFinite(n)&&n>t()},Fh=e=>`npx anyray-connect@latest --sso ${e.ssoLink??"<link>"}`,_H=(e,t)=>{switch(e){case"cert-expired":return t.ssoLink?`Your SSO reconnect credential expired. Reconnect with \`${Fh(t)}\`.`:"Enrollment certificate expired. Re-run `npx anyray-connect@latest --enroll <link>`, or for an SSO-managed organization run `npx anyray-connect@latest --sso <link>`.";case"cert-rejected":return t.ssoLink?`Your SSO reconnect credential is no longer valid. Reconnect with \`${Fh(t)}\`.`:"Your enrollment certificate is no longer valid. Reconnect with `npx anyray-connect@latest --enroll <link>`, or for an SSO-managed organization run `npx anyray-connect@latest --sso <link>`.";case"gateway-incompatible":return"The gateway key-renewal route is unavailable (HTTP 404). Check the deployment version and routing; your enrollment certificate was not rejected.";case"failed":return"Could not refresh the Anyray client key.";case"not-enrolled":return t.ssoLink?`Not enrolled. Reconnect with \`${Fh(t)}\`.`:"Not enrolled. Run `npx anyray-connect@latest --enroll <link>` first.";case"disabled":return"Automatic key refresh is disabled.";case"backoff":case"throttled":return"Key refresh is temporarily unavailable; retry shortly.";case"not-due":case"repaired":case"cert-renewed":case"heartbeat-refreshed":case"refreshed":return""}},Si=async(e={})=>{let t=e.loadProfile??P,n=e.refreshIfDue??Ut,r=e.now??Date.now,o=await t();if(VE(o),!o.enrolledCert){if(!KE(o,r))throw new Error("No valid Anyray client key is stored. Set ANYRAY_CLIENT_KEY to a minted ark_ key or enroll this machine.");return{profile:o,token:o.clientKey}}let a;if(!o.clientKey||TH(o,r)){let i=_H(await n(),o);if(i){if(!KE(o,r))throw new Error(i);a=`${i} Using the stored key (valid until ${o.clientKeyExpiresAt}).`}}let s=await t();if(VE(s),!be(s.clientKey))throw new Error("No Anyray client key is stored for this enrollment.");return{profile:s,token:s.clientKey,warning:a}},jE=e=>fe({user:e.name,team:e.team}),Fd=({profile:e,token:t})=>{let n={},r=jE(e);return r&&(n["x-anyray-metadata"]=r),JSON.stringify({token:t,headers:n})},Wh=({profile:e,token:t})=>{let n={"x-anyray-api-key":t,"x-anyray-auth-mode":"passthrough","x-anyray-provider":"anthropic"},r=jE(e);return r&&(n["x-anyray-metadata"]=r),n},PH=e=>JSON.stringify(Wh(e)),ZE=async(e=process.argv.slice(2),t={})=>{let n=t.stdout??process.stdout,r=t.stderr??process.stderr;try{let o=OH(e);if(o.help)return n.write(RH),0;let a=await Si(t);a.warning&&r.write(`${a.warning}
|
|
367
|
+
`);let s=o.passthroughHeaders?PH(a):o.json?Fd(a):a.token;return n.write(`${s}
|
|
368
368
|
`),0}catch(o){let a=o instanceof Error?o.message:String(o);return r.write(`${a}
|
|
369
369
|
`),1}};var YE=`anyray-connect models [<model-id>] [--json]
|
|
370
370
|
|
|
@@ -378,8 +378,8 @@ Options:
|
|
|
378
378
|
--json Emit {"origin","current","models":[{"id","wire",...caps}]} instead
|
|
379
379
|
of the table (listing only).
|
|
380
380
|
--help Show this help.
|
|
381
|
-
`,
|
|
382
|
-
`),0;A(K(`Copilot models your seat serves (via ${o.origin})`));for(let f of l){let h=f.id===m?"*":" ",w=
|
|
381
|
+
`,DH=e=>{let t={json:!1,help:!1};for(let n of e)n==="--help"||n==="-h"?t.help=!0:n==="--json"?t.json=!0:n.startsWith("-")?t.error=`unknown option: ${n}`:t.modelId?t.error=`unexpected argument: ${n}`:t.modelId=n;return t},LH=e=>{let t=pe.find(n=>n.id===oo);if(!t)throw new Error("copilot-cli adapter missing from REGISTRY");return t.apply(e,{dryRun:!1,explicit:!0})},NH=e=>{let t=r=>r>=1e3?`${Math.round(r/1e3)}k`:String(r);return[...e.maxPromptTokens?[`${t(e.maxPromptTokens)} in`]:[],...e.maxOutputTokens?[`${t(e.maxOutputTokens)} out`]:[]].join(" / ")},$H=(e,t,n)=>`${e.origin.replace(/\/+$/,"")}/v1${Vs(t)}/${Dn(n)==="responses"?"responses":"chat/completions"}`,JE=async(e=[],t={})=>{let n=DH(e);if(n.help)return process.stdout.write(YE),0;if(n.error)return R(n.error),process.stdout.write(YE),1;let r=await(t.loadTarget??Ue)();if(!r)return R("Not enrolled \u2014 run `anyray-connect` first."),1;let{target:o}=r,a=await(t.discoverSeatToken??wl)({allowKeychainPrompt:!0});if(!a.token)return R("No Copilot sign-in Connect can read \u2014 run `copilot` once and `/login` (say YES to storing credentials locally), then retry."),1;let s=a.token.token,i=a.capiSegment??"default",c=await(t.fetchCatalog??na)(s,{},i,{laneOrigin:o.origin.replace(/\/+$/,""),...o.clientKey?{clientKey:o.clientKey}:{}}),l=Tf(c);if(l.length===0)return R("Could not fetch your seat's model catalog from GitHub (offline, or the sign-in lost its Copilot seat)."),1;if(!n.modelId){let m=process.env.COPILOT_MODEL?.trim();if(n.json)return process.stdout.write(`${JSON.stringify({origin:o.origin,current:m??null,models:l.map(f=>({id:f.id,wire:Dn(f.id),...f.maxPromptTokens?{maxPromptTokens:f.maxPromptTokens}:{},...f.maxOutputTokens?{maxOutputTokens:f.maxOutputTokens}:{}}))})}
|
|
382
|
+
`),0;A(K(`Copilot models your seat serves (via ${o.origin})`));for(let f of l){let h=f.id===m?"*":" ",w=NH(f);A(` ${h} ${f.id.padEnd(24)}${w?v(w):""}`)}return L("Switch the startup model: `anyray-connect models <id>` (per launch: `copilot --model <id>`)."),L("The CLI's own /models cannot list models on a custom provider \u2014 this list is the picker."),0}let d=l.find(m=>m.id===n.modelId);if(!d)return R(`'${n.modelId}' is not in your seat's catalog \u2014 run \`anyray-connect models\` to list it.`),1;let u=await(t.probeChat??gl)($H(o,i,d.id),{...Of(),authorization:`Bearer ${s}`,...o.clientKey?{"x-anyray-api-key":o.clientKey}:{}},d.id);if(u==="rejected")return R(`GitHub refuses chat as '${d.id}' for this sign-in (it is in the catalog, but chat entitlement is narrower). Pick another id from \`anyray-connect models\`.`),1;u==="unreachable"?O("Could not verify the model over the lane (offline?) \u2014 applying anyway."):B(`'${d.id}' answers on your lane.`);let p=process.env.ANYRAY_COPILOT_MODEL;process.env.ANYRAY_COPILOT_MODEL=d.id;try{let m=await(t.applyCopilotCli??LH)(o);if(m.status!=="configured"){for(let f of m.messages)A(f);return R("Apply did not complete \u2014 see above."),1}}finally{p===void 0?delete process.env.ANYRAY_COPILOT_MODEL:process.env.ANYRAY_COPILOT_MODEL=p}return B(`Copilot CLI startup model \u2192 ${d.id}`),L("Open a fresh terminal (or re-source your profile), then run `copilot`."),0};var MH=`anyray-connect copilot-login
|
|
383
383
|
|
|
384
384
|
Sign Anyray in to GitHub Copilot (device flow) so the Copilot CLI seat lane
|
|
385
385
|
can run your plan's current models. Opens no browser for you: it prints a
|
|
@@ -387,23 +387,23 @@ code to type at github.com/login/device.
|
|
|
387
387
|
|
|
388
388
|
Options:
|
|
389
389
|
--help Show this help.
|
|
390
|
-
`,XE=async(e=[],t={})=>{if(e.includes("--help")||e.includes("-h"))return process.stdout.write(
|
|
391
|
-
`,{mode:384}),await
|
|
390
|
+
`,XE=async(e=[],t={})=>{if(e.includes("--help")||e.includes("-h"))return process.stdout.write(MH),0;A(K("Anyray connect \u2014 Copilot sign-in"));let n=await(t.start??aC)();if(!n)return R("Could not reach GitHub to start the sign-in. Check connectivity and retry."),1;A(` 1. Open ${qe(n.verificationUri)}`),A(` 2. Enter the code: ${K(n.userCode)}`),L(" Waiting for you to finish in the browser\u2026");let r=await(t.poll??sC)(n);if(r.status!=="ok")return R(r.status==="denied"?"Sign-in was declined in the browser.":r.status==="expired"?"The code expired before sign-in completed \u2014 run the command again.":"GitHub refused the sign-in. Run the command again."),1;let o=(t.now??(()=>new Date))().toISOString(),a=await(t.save??iC)(r.token,o);B(`Signed in. Stored owner-only at ${a}`);let s=await(t.probeAccess??kf)(r.token);if(s.verdict==="no-copilot")return R("That GitHub account holds no Copilot seat."),1;let i=await(t.loadTarget??Ue)(),c=i?{laneOrigin:i.target.origin.replace(/\/+$/,""),...i.target.clientKey?{clientKey:i.target.clientKey}:{}}:void 0,l=await(t.fetchCatalog??na)(r.token,{},s.capiSegment,c);return l.length===0?O("Signed in, but no model list came back \u2014 that is usually this machine or its network, not the sign-in. Continue with `anyray-connect --tools copilot-cli`; it verifies the model with a live check of its own."):B(`${l.length} models available (e.g. ${l[0].id}).`),L("Now run: anyray-connect --tools copilot-cli"),0};import{randomBytes as BH}from"node:crypto";import{chmod as FH,readFile as WH,rm as qE,writeFile as UH}from"node:fs/promises";import{join as HH}from"node:path";var GH=/^[A-Za-z0-9_-]{43}$/,zE=3900,VH=1e4,Uh=()=>HH(ee(),"device-token.json"),KH=e=>{if(e===null||typeof e!="object"||Array.isArray(e))return!1;let t=e;return t.v===1&&typeof t.token=="string"&&GH.test(t.token)&&typeof t.expiresAt=="number"&&Number.isFinite(t.expiresAt)},QE=async()=>{try{let e=JSON.parse(await WH(Uh(),"utf-8"));return KH(e)?e:null}catch{return null}},jH=0,ZH=async e=>{await et();let t=Uh(),n=`${t}.${process.pid}.${jH++}.tmp`;try{await UH(n,`${JSON.stringify(e)}
|
|
391
|
+
`,{mode:384}),await FH(n,384),await ye(n,t)}catch(r){throw await qE(n,{force:!0}).catch(()=>{}),r}},Wd=async()=>{await qE(Uh(),{force:!0}).catch(()=>{})},YH=()=>BH(32).toString("base64url"),JH=e=>e instanceof Error?e.name:"UnknownError",eI=async(e={})=>{let t=e.now??Date.now,n=e.fetchFn??fetch;try{let r=await(e.loadProfile??P)(),o=r.gateway?.replace(/\/+$/,""),a=r.clientKey;if(!o||!a)return!1;let s=YH(),i=new AbortController,c=setTimeout(()=>i.abort(),VH),l;try{l=await n(`${o}/connect/device-token`,{method:"POST",headers:{"content-type":"application/json","x-anyray-api-key":a},body:JSON.stringify({token:s,ttlSeconds:zE}),signal:i.signal})}finally{clearTimeout(c)}return l.ok?(await ZH({v:1,token:s,expiresAt:t()+zE*1e3}),!0):(l.status!==503&&console.error(`anyray device-token registration: HTTP ${l.status}`),!1)}catch(r){return console.error(`anyray device-token registration: ${JH(r)}`),!1}};var tI=async(e={})=>{let t=e.stdout??process.stdout,n=e.stderr??process.stderr,r=e.now??Date.now,o;try{o=await(e.loadProfile??P)()}catch{o={}}let a=o.gateway?.replace(/\/+$/,"");if(!a||!o.clientKey)return n.write("Not enrolled on this machine \u2014 run `npx anyray-connect` first.\n"),1;let s=e.readState??QE,i=await s();return(!i||i.expiresAt<=r())&&(await(e.rotateToken??eI)(),i=await s()),!i||i.expiresAt<=r()?(n.write(`Could not register a device token \u2014 retry after checking gateway connectivity.
|
|
392
392
|
`),1):(t.write(`${a}/device?dt=${i.token}
|
|
393
|
-
`),0)};import{join as cI,dirname as
|
|
393
|
+
`),0)};import{join as cI,dirname as sG}from"node:path";import{mkdir as iG,readFile as Jh,rm as lI,writeFile as dI}from"node:fs/promises";import{fstatSync as QH,openSync as eG,statSync as tG}from"node:fs";import{createInterface as nG}from"node:readline/promises";import{ReadStream as rG}from"node:tty";import{execFileSync as nI}from"node:child_process";import XH from"node:os";var Hh=e=>{try{return nI("git",["config","--get",e],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}},zH=e=>{try{return nI("git",["config","--global","--get",e],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}},qH=new Set(["root","unknown","user","admin","administrator","developer","dev","node","ubuntu","debian","ec2-user","vagrant","docker","container","vscode","codespace","devcontainer","runner","builder","jenkins","build","ci"]),Gh=e=>{let t=e.trim().toLowerCase();return t?t.includes("@")?!1:qH.has(t):!0},Ud=()=>{try{return XH.userInfo().username||void 0}catch{return}},rI=()=>Hh("user.name")??Hh("user.email")??Ud()??"unknown",oI=e=>{let t=e.gitConfig??e.globalGitConfig;return{local:e.gitConfig??(t||Hh),global:e.globalGitConfig??(t||zH)}},Eo=e=>{try{return e()?.trim()||void 0}catch{return}},Vh=(e={})=>{let t=oI(e),n=Eo(e.osUsername??Ud),r=Eo(()=>t.global("user.email"))??Eo(()=>t.local("user.email"));return r||(Eo(()=>t.global("user.name"))??Eo(()=>t.local("user.name"))??n??"unknown")},aI=(e={})=>{let t=Vh(e);if(Gh(t))return{identity:t,distinct:!1,reason:"machine_default"};let n=oI(e);return!!(Eo(()=>n.global("user.email"))??Eo(()=>n.local("user.email")))?{identity:t,distinct:!0}:{identity:t,distinct:!1,reason:"no_git_email"}};var gt=()=>!!process.stdin.isTTY,oG=()=>{try{let e=QH(0);return e.isCharacterDevice()&&e.rdev===tG("/dev/tty").rdev}catch{return!1}},Kh=()=>{if(oG()){for(let[e,t]of[[1,process.stdout],[2,process.stderr]])if(t.isTTY)try{let n=new rG(eG(`/dev/fd/${e}`,"r"));return{stream:n,close:()=>n.destroy()}}catch{}}return{stream:process.stdin,close:()=>{}}},yt=class extends Error{constructor(){super("prompt cancelled"),this.name="PromptCancelledError"}},sI=async(e,t)=>{let n=t.input??Kh(),r=t.output??process.stdout,o=nG({input:n.stream,output:r});try{return await new Promise((a,s)=>{let i=!1,c=!1,l=d=>{i||(i=!0,d())};o.once("line",()=>{c=!0}),o.once("SIGINT",()=>o.close()),o.once("close",()=>{c||l(()=>s(new yt))}),o.question(e).then(d=>l(()=>a(d)),d=>l(()=>s(c?d:new yt)))})}finally{o.close(),n.close()}},Io=async(e,t={})=>{let n=(await sI(`${e} ${v("[y/N]")} `,t)).trim();return/^y(es)?$/i.test(n)},Ma=async(e,t,n={})=>{let r=t?` ${v(`[${t}]`)}`:"";return(await sI(`${e}${r}: `,n)).trim()||t},jh=async(e,t,n)=>{if(e!==void 0)return e.trim()||void 0;if(t)return L(`Your name: ${t} ${v("(cached \u2014 pass --user to change)")}`),t;let r=rI();return n||!gt()?(L(`Your name: ${r} ${v("(auto-detected \u2014 pass --user to change)")}`),r):Ma("? Your name",r)},Zh=async(e,t,n)=>{if(e!==void 0)return e.trim()||void 0;if(t)return L(`Team: ${t} ${v("(cached \u2014 pass --team to change)")}`),t;if(!(n||!gt()))return Ma("? Team (optional)")},Tr=(e,t)=>{let n=!e&&!process.env.ANYRAY_GATEWAY_URL?t.gateway:void 0;return Kt(e??n)},iI=(e,t)=>process.env.ANYRAY_CLIENT_KEY?.trim()||e?.trim()||t,Ba="claude-desktop",Hd=async(e={})=>{let t=(e.platform??(()=>process.platform))(),n=r=>({authoritative:!1,reason:r});try{if(t==="win32"){try{if(await Sr(e.runReg??Hn))return n("managed-policy")}catch{return n("policy-unreadable")}let s=Mt({home:e.home});return await x(s)?{authoritative:!0}:n("no-local-record")}if(t!=="darwin")return n("manual-platform");let r={home:e.home,managedPolicyPaths:e.managedPolicyPaths,readManagedPolicyKeys:e.readManagedPolicyKeys},o=Jt(r);return await lo(o,r)?n("managed-policy"):(await Ca({home:e.home,readClaudeAppVersion:e.readClaudeAppVersion,readClaudeAppBundle:e.readClaudeAppBundle})).supported?await x(o.journal)?{authoritative:!0}:n("no-local-record"):n("unverified-build")}catch{return n("no-local-record")}},Gd=e=>e.id!==Ba||!e.installed?null:e.pointedAt===!0?"routed":e.pointedAt!==!1?null:e.introspectable?e.mcpRegistered?"not-routed":null:"unverifiable",aG={"manual-platform":"Claude Desktop setup is manual on this platform","unverified-build":"this Claude Desktop build's automatic-setup seam is unverified","managed-policy":"Claude Desktop's inference settings are centrally managed on this machine","policy-unreadable":"Claude Desktop's Windows machine-policy ownership could not be read","no-local-record":"connect has no record of configuring Claude Desktop inference on this machine"},Vd=(e,t)=>{if(e==="not-routed")return{headline:"retrieval MCP server registered, but inference is not routed through the gateway \u2014 Claude Desktop model traffic is NOT optimized.",detail:["Fix: fully quit Claude Desktop, then run `anyray-connect desktop` and complete any printed inference steps."]};let n=aG[t.reason??"no-local-record"],r=t.mcpRegistered?`retrieval MCP server registered, but inference routing can't be verified (${n}).`:`inference routing can't be verified (${n}), and the retrieval MCP server is not registered.`;return t.reason==="managed-policy"?{headline:r,detail:["Managed policy is authoritative; Connect will not overwrite or auto-repair it. Update the organization MDM profile or bootstrap service.","Bootstrap changes need no MDM redeployment; Claude applies the refreshed configuration on the next app launch."]}:t.reason==="policy-unreadable"?{headline:r,detail:["Connect could not prove whether HKLM policy is authoritative, so it will not overwrite or auto-repair the per-user route.","Check the organization policy and registry-read permissions, then run `anyray-connect doctor` again."]}:{headline:r,detail:["If Claude Desktop's third-party inference setup was never completed, its traffic bypasses the gateway and is NOT optimized.","Check: Claude Desktop \u2192 Developer \u2192 Configure Third-Party Inference; re-run `anyray-connect desktop` to reprint the steps.",...t.mcpRegistered?[]:["Re-running from a durable install also registers the retrieval MCP server."]]}};var Yh=["claude-code","codex"],cG="anyray-connect print-key",Xh=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),lG=e=>({origin:e,anthropicBaseUrl:e,openaiBaseUrl:`${e}/v1`,placeholderKey:os,authMode:"placeholder",metadata:{}}),zh=e=>cI(e,".claude","settings.json"),dG=async(e,t,n)=>{let r=zh(e),o=await M(r),{env:a}=rn(t,{includeAuthToken:!1,includeClientKey:!1}),s=Xh(o.env)?{...o.env}:{};Object.assign(s,a),o.env=s;let i=[];return typeof o.apiKeyHelper=="string"&&!Hr(o)?i.push(`Kept the existing apiKeyHelper in ${r} \u2014 make sure it prints an Anyray client key, or remove it and re-run.`):o.apiKeyHelper=cG,n||await J(r,o,{backup:!1}),i.unshift(`${n?"Would write":"Wrote"} ${r} \u2014 base URL + a PATH-resolved key helper (no credential, no identity).`),{messages:i,changedFiles:n?[]:[r]}},uI=async(e=process.cwd())=>{let t=[],n=zh(e);try{if(await x(n)){let o=await M(n),a=Xh(o.env)?o.env:{};(Ur.some(s=>s in a)||Hr(o))&&t.push(n)}}catch{}let r=qh(e);try{if(await x(r)){let o=await Jh(r,"utf-8");xp(o)&&t.push(r)}}catch{}return t},uG=async(e,t)=>{let n=zh(e);if(!await x(n))return{messages:[`No ${n} \u2014 nothing to remove.`],changedFiles:[]};let r=await M(n),o=!1;if(Xh(r.env)){let s={...r.env};for(let i of Ur)i in s&&(delete s[i],o=!0);Object.keys(s).length===0?delete r.env:r.env=s}if(Hr(r)&&(delete r.apiKeyHelper,o=!0),!o)return{messages:[`No Anyray keys in ${n} \u2014 nothing to remove.`],changedFiles:[]};let a=Object.keys(r).length===0;return t||(a?await lI(n,{force:!0}):await J(n,r,{backup:!1})),{messages:[`${t?"Would remove":"Removed"} the Anyray routing from ${n}${a?" (file was only ours \u2014 deleted)":""}.`],changedFiles:t?[]:[n]}},qh=e=>cI(e,".codex","config.toml"),pG=async(e,t,n)=>{let r=qh(e),o=await Jh(r,"utf-8").catch(()=>""),a=Dc(o,Cs(t,{auth:"command",authCommand:"anyray-connect",authArgs:["print-key"],ignoreEnv:!0}),["model_provider"]);return n||(await iG(sG(r),{recursive:!0}),await dI(r,a)),{messages:[`${n?"Would write":"Wrote"} ${r} \u2014 gateway provider with command-backed auth (no credential serialized).`,"Codex asks for project-config trust on first launch in a fresh checkout \u2014 that prompt is expected."],changedFiles:n?[]:[r]}},fG=async(e,t)=>{let n=qh(e);if(!await x(n))return{messages:[`No ${n} \u2014 nothing to remove.`],changedFiles:[]};let r=await Jh(n,"utf-8"),o=Lc(r);if(o===null)return{messages:[`No Anyray block in ${n} \u2014 nothing to remove.`],changedFiles:[]};let a=!o.trim();return t||(a?await lI(n,{force:!0}):await dI(n,o)),{messages:[`${t?"Would remove":"Removed"} the Anyray block from ${n}${a?" (file was only ours \u2014 deleted)":""}.`],changedFiles:t?[]:[n]}},pI=async e=>{let t=process.cwd(),n=e.tools&&e.tools.length>0?e.tools:[...Yh],r=n.filter(s=>!Yh.includes(s));if(r.length>0)return R(`--project supports ${Yh.join(", ")} \u2014 not: ${r.join(", ")}. Other tools keep per-machine state (run anyray-connect without --project there).`),1;let o;if(!e.revert){let s=await P(),i=e.gateway??s.gateway;if(!i)return R("--project needs a gateway: pass --gateway <url>, or run `anyray-connect` once on this machine so it is cached."),1;try{let c=new URL(i.trim());if(c.protocol!=="http:"&&c.protocol!=="https:")throw new Error("not http(s)")}catch{return R(`invalid gateway URL: "${i}" \u2014 must start with http:// or https://`),1}o=lG(Vt(i))}if(A(K(e.revert?"Anyray connect \u2014 remove project config":"Anyray connect \u2014 project config")),H("Project"),A(` Directory: ${t}`),o&&A(` Gateway: ${o.origin}`),A(` Tools: ${n.join(", ")}`),e.revert||(O(`
|
|
394
394
|
A committed project config routes these tools through the org API lane on EVERY machine that opens this repo \u2014 subscription seats included.`),L(" Each machine still needs `anyray-connect` on PATH and a one-time enrollment (--sso/--enroll); the files carry no credential and no identity.")),!e.yes&&!e.dryRun){if(!gt())return R(`
|
|
395
395
|
Non-interactive session \u2014 cannot ask for confirmation. Pass --yes to proceed.`),1;let s=e.revert?"remove Anyray project config for":"write committable project config for";if(!await Io(`
|
|
396
396
|
${s} ${n.length} tool(s)?`))return L("Aborted. Nothing changed."),0}e.dryRun&&L(`
|
|
397
|
-
Dry run \u2014 no files will be written.`);let a=[];for(let s of n){H(s==="claude-code"?"Claude Code":"Codex");let i=o?s==="claude-code"?await
|
|
397
|
+
Dry run \u2014 no files will be written.`);let a=[];for(let s of n){H(s==="claude-code"?"Claude Code":"Codex");let i=o?s==="claude-code"?await dG(t,o,e.dryRun):await pG(t,o,e.dryRun):s==="claude-code"?await uG(t,e.dryRun):await fG(t,e.dryRun);for(let c of i.messages)A(` ${c}`);a.push(...i.changedFiles)}if(a.length>0)if(H("Next"),e.revert)B(" Project config removed. Commit the change to propagate it.");else{B(" Commit these files to route every checkout of this repo:");for(let s of a)A(` ${s}`);A(v(" On each machine: install anyray-connect (PATH) and enroll once \u2014 `anyray-connect --sso <link> --yes`."))}return 0};import{execFile as mG}from"node:child_process";var hG="/usr/bin/security",yG=["find-generic-password","-s","Claude Code-credentials","-w"],gG=1e4,wG=64*1024,bG=/^sk-ant-oat[0-9A-Za-z._-]{16,8192}$/,Qh="Anyray: could not resolve the Claude subscription credential. Sign in with Claude Code and try again.",AG=(e,t,n)=>new Promise((r,o)=>{mG(e,t,n,(a,s)=>{if(a){o(new Error("keychain credential unavailable"));return}r({stdout:s})})}),fI=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),CG=e=>{let t=JSON.parse(e);if(!fI(t)||!fI(t.claudeAiOauth))throw new Error("unexpected keychain credential shape");let n=t.claudeAiOauth.accessToken;if(typeof n!="string"||!bG.test(n))throw new Error("unexpected keychain access token");return n},kG=async(e,t)=>{let n=Wh(e),r=await(t.execSecurity??AG)(hG,[...yG],{encoding:"utf8",timeout:gG,maxBuffer:wG,shell:!1});return JSON.stringify({token:CG(r.stdout),headers:n})},mI=async(e=[],t={})=>{let n=t.stdout??process.stdout,r=t.stderr??process.stderr;if(e.length>0)return r.write(`${Qh}
|
|
398
398
|
`),1;let o;try{o=await Si(t)}catch(i){let c=i instanceof Error&&i.message?i.message:Qh;return r.write(`${c}
|
|
399
|
-
`),1}let a=o.profile.authMode??"auto",s;if(a==="placeholder")s=Fd(o);else try{s=await
|
|
399
|
+
`),1}let a=o.profile.authMode??"auto",s;if(a==="placeholder")s=Fd(o);else try{s=await kG(o,t)}catch{if(a==="subscription")return r.write(`${Qh}
|
|
400
400
|
`),1;s=Fd(o)}return o.warning&&r.write(`${o.warning}
|
|
401
401
|
`),n.write(`${s}
|
|
402
402
|
`),0};var hI="Anyray: could not resolve the Anyray client key for the Claude Desktop bootstrap fetch. Run `anyray-connect` and try again.",yI=async(e=[],t={})=>{let n=t.stdout??process.stdout,r=t.stderr??process.stderr;if(e.length>0)return r.write(`${hI}
|
|
403
403
|
`),1;try{let o=await Si(t);return o.warning&&r.write(`${o.warning}
|
|
404
404
|
`),n.write(`${JSON.stringify({Authorization:`Bearer ${o.token}`})}
|
|
405
405
|
`),0}catch{return r.write(`${hI}
|
|
406
|
-
`),1}};import{mkdir as
|
|
406
|
+
`),1}};import{mkdir as ZG,writeFile as YG}from"node:fs/promises";import{dirname as JG}from"node:path";import{Buffer as XG}from"node:buffer";import{constants as gI}from"node:fs";import{access as vG,chmod as SG,lstat as EG,mkdir as IG,open as xG,readFile as RG,realpath as OG,rm as TG,stat as bI,writeFile as _G}from"node:fs/promises";import{randomUUID as PG}from"node:crypto";import{platform as ty}from"node:os";import{dirname as DG,join as LG,posix as NG,win32 as AI}from"node:path";var xi="/usr/local/bin/anyray-credential-helper",Ri="C:\\Program Files\\Anyray\\anyray-credential-helper.cmd",Kd="/usr/local/bin/anyray-bootstrap-headers-helper",jd="C:\\Program Files\\Anyray\\anyray-bootstrap-headers-helper.cmd",Ii="Managed by anyray-connect desktop helper; do not edit.",$G=`anyray-connect desktop helper <--write|--print> --bin <absolute> [options]
|
|
407
407
|
|
|
408
408
|
Create the helpers required by Claude Desktop and Codex fleet artifacts: the
|
|
409
409
|
credential helper (inferenceCredentialHelper, also used by Codex) and the
|
|
@@ -445,15 +445,15 @@ Examples:
|
|
|
445
445
|
anyray-connect desktop helper --print --wrapper bootstrap-headers \\
|
|
446
446
|
--platform posix --bin /usr/local/bin/anyray-connect \\
|
|
447
447
|
> anyray-bootstrap-headers-helper
|
|
448
|
-
`,ey=(e=ty())=>e==="win32"?"windows":"posix",CI=e=>e==="windows"?Ri:xi,kI=e=>e==="windows"?jd:Kd,wI=(e,t)=>{if(e.mode)throw new Error("pick exactly one helper mode: --write or --print");e.mode=t}
|
|
448
|
+
`,ey=(e=ty())=>e==="win32"?"windows":"posix",CI=e=>e==="windows"?Ri:xi,kI=e=>e==="windows"?jd:Kd,wI=(e,t)=>{if(e.mode)throw new Error("pick exactly one helper mode: --write or --print");e.mode=t},MG=e=>{let t={help:!1};for(let n=0;n<e.length;n++){let r=e[n],o=()=>{let a=e[++n];if(!a)throw new Error(`missing value for ${r}`);return a};switch(r){case"--write":wI(t,"write");break;case"--print":wI(t,"print");break;case"--bin":t.binaryPath=o();break;case"--path":t.helperPath=o();break;case"--bootstrap-headers-path":t.bootstrapHeadersHelperPath=o();break;case"--wrapper":{let a=o();if(a!=="credential"&&a!=="bootstrap-headers")throw new Error("--wrapper must be credential or bootstrap-headers");t.wrapper=a;break}case"--platform":{let a=o();if(a!=="posix"&&a!=="windows")throw new Error("--platform must be posix or windows");t.targetPlatform=a;break}case"--help":case"-h":t.help=!0;break;default:throw new Error(r.startsWith("-")?`unknown option: ${r}`:`unexpected argument: ${r}`)}}return t},BG=e=>/[\0\r\n]/.test(e),FG=e=>/^[A-Za-z]:[\\/]/.test(e)&&AI.isAbsolute(e),Oi=(e,t)=>!BG(e)&&(t==="windows"?FG(e):NG.isAbsolute(e)),Ei=e=>e.replace(/\\/g,"/").toLowerCase(),Zd=(e,t)=>{if(!Oi(e,t))return!1;let n=Ei(e);return!(/(^|\/)_npx(\/|$)/.test(n)||n==="/tmp"||n.startsWith("/tmp/")||n==="/private/tmp"||n.startsWith("/private/tmp/")||n==="/var/tmp"||n.startsWith("/var/tmp/")||n.startsWith("/var/folders/")||n.startsWith("/private/var/folders/")||/\/appdata\/local\/temp(\/|$)/.test(n)||t==="windows"&&(/[%!^&|<>()"]/.test(e)||!/\.exe$/i.test(e)))},Ti=(e,t)=>t==="windows"?AI.normalize(e):e,ny=e=>`'${e.replace(/'/g,`'"'"'`)}'`,vI=(e,t)=>{if(!Zd(t,e))throw new Error("--bin must be an absolute, fleet-stable anyray-connect executable outside npm/npx and temporary paths");let n=Ti(t,e);if(e==="windows")return["@echo off",`REM ${Ii}`,'if "%~1"=="" goto json','if not "%~2"=="" exit /b 64','if "%~1"=="--token" goto token',"exit /b 64",":json",`"${n}" ${kr}`,"exit /b %ERRORLEVEL%",":token",`"${n}" print-key`,"exit /b %ERRORLEVEL%",""].join(`\r
|
|
449
449
|
`);let r=ny(n);return["#!/bin/sh",`# ${Ii}`,'if [ "$#" -eq 0 ]; then',` exec ${r} ${kr}`,"fi",'if [ "$#" -eq 1 ] && [ "$1" = "--token" ]; then',` exec ${r} print-key`,"fi","exit 64",""].join(`
|
|
450
450
|
`)},SI=(e,t)=>{if(!Zd(t,e))throw new Error("--bin must be an absolute, fleet-stable anyray-connect executable outside npm/npx and temporary paths");let n=Ti(t,e);return e==="windows"?["@echo off",`REM ${Ii}`,'if not "%~1"=="" exit /b 64',`"${n}" ${Qs}`,"exit /b %ERRORLEVEL%",""].join(`\r
|
|
451
451
|
`):["#!/bin/sh",`# ${Ii}`,'if [ "$#" -eq 0 ]; then',` exec ${ny(n)} ${Qs}`,"fi","exit 64",""].join(`
|
|
452
|
-
`)},Yd=(e,t)=>{if(!Oi(t,e))throw new Error(`--helper-path must be an absolute ${e} path`);let n=Ti(t,e);if(e==="windows"){if(/[%!^&|<>()"]/.test(n)||!/\.cmd$/i.test(n))throw new Error("Windows --helper-path must be a safe absolute .cmd path without batch metacharacters");return{command:"C:\\Windows\\System32\\cmd.exe",args:["/d","/s","/c",`call "${n}" --token`]}}return{command:n,args:["--token"]}},EI=async e=>{try{return await
|
|
453
|
-
`),0}if(s!==ey(a))throw new Error(`--write cannot install a ${s} helper on this ${a} host; use --print for cross-platform packaging`);await
|
|
452
|
+
`)},Yd=(e,t)=>{if(!Oi(t,e))throw new Error(`--helper-path must be an absolute ${e} path`);let n=Ti(t,e);if(e==="windows"){if(/[%!^&|<>()"]/.test(n)||!/\.cmd$/i.test(n))throw new Error("Windows --helper-path must be a safe absolute .cmd path without batch metacharacters");return{command:"C:\\Windows\\System32\\cmd.exe",args:["/d","/s","/c",`call "${n}" --token`]}}return{command:n,args:["--token"]}},EI=async e=>{try{return await RG(e,"utf8")}catch(t){if(t.code==="ENOENT")return;throw new Error(`could not inspect existing helper at ${e}`)}},WG=async(e,t)=>{try{let n=await OG(e),r=t==="windows"?n.replace(/^\\\\\?\\/,""):n;if(!Zd(r,t))throw new Error;if(!(await bI(n)).isFile())throw new Error;await vG(n,t==="posix"?gI.X_OK:gI.F_OK)}catch{throw new Error("--bin must resolve to an accessible, regular"+(t==="posix"?", executable":"")+" fleet-stable file")}},II=e=>e.slice(0,300).includes(Ii),xI=async(e,t,n)=>{let r=await EI(e);if(r!==void 0&&r!==t&&!II(r))throw new Error(`refusing to replace non-Anyray file at ${e}; choose another --path`);if(r===t){if(n==="windows")return"unchanged";try{if(((await bI(e)).mode&511)===493)return"unchanged"}catch{}}let o=DG(e);try{await IG(o,{recursive:!0,mode:493})}catch{throw new Error(`could not create helper directory ${o}`)}let a=LG(o,`.anyray-helper.${process.pid}.${PG()}.tmp`),s=!1;try{await _G(a,t,{encoding:"utf8",mode:n==="posix"?493:420,flag:"wx"}),n==="posix"&&await SG(a,493);let i=await xG(a,"r");try{await Yn(i)}finally{await i.close()}await ye(a,e),s=!0}catch{throw new Error(`could not install helper at ${e}`)}finally{s||await TG(a,{force:!0}).catch(()=>{})}return r===void 0?"installed":"updated"},UG=(e,t,n)=>{let r=n==="windows"?`"${Ti(t,n)}" `:` exec ${ny(t)} `;return e.split(/\r?\n/).some(o=>o.startsWith(r)&&o.length>r.length)},Jd=async(e,t={})=>{let n=ey((t.platform??ty)());if(!Zd(e,n))return;let r=[{path:t.helperPath??CI(n),content:vI(n,e)},{path:t.bootstrapHeadersHelperPath??kI(n),content:SI(n,e)}];for(let o of r)try{if((await EG(o.path).catch(()=>{}))?.isSymbolicLink())continue;let a=await EI(o.path);if(a===void 0||a===o.content||!II(a)||!UG(a,e,n))continue;await xI(o.path,o.content,n)}catch{}},RI=async(e,t={})=>{let n=t.stdout??process.stdout,r=t.stderr??process.stderr;try{let o=MG(e);if(o.help)return n.write($G),0;if(!o.mode)throw new Error("pick exactly one helper mode: --write or --print");if(!o.binaryPath)throw new Error("--bin is required");if(o.wrapper&&o.mode!=="print")throw new Error("--wrapper applies to --print only; --write installs both helpers");let a=(t.platform??ty)(),s=o.targetPlatform??ey(a),i=o.binaryPath,c=(d,u,p)=>{let m=Ti(u??p,s);if(!Oi(m,s))throw new Error(`${d} must be an absolute ${s} path`);if(s==="windows"&&Yd("windows",m),Ei(m)===Ei(i))throw new Error(`${d} must differ from --bin (the helper cannot invoke itself)`);return m},l=[{kind:"credential",label:"credential helper",path:c("--path",o.helperPath,CI(s)),content:vI(s,i)},{kind:"bootstrap-headers",label:"bootstrap-headers helper",path:c("--bootstrap-headers-path",o.bootstrapHeadersHelperPath,kI(s)),content:SI(s,i)}];if(Ei(l[0].path)===Ei(l[1].path))throw new Error("--path and --bootstrap-headers-path must differ");if(o.mode==="print"){let d=o.wrapper??"credential",u=l.find(p=>p.kind===d);return n.write(u.content),r.write(`Deploy this wrapper at ${u.path} after deploying the binary at ${i}.
|
|
453
|
+
`),0}if(s!==ey(a))throw new Error(`--write cannot install a ${s} helper on this ${a} host; use --print for cross-platform packaging`);await WG(i,s);for(let d of l){let u=await xI(d.path,d.content,s),p=d.label[0].toUpperCase()+d.label.slice(1);r.write(u==="unchanged"?`${p} already current at ${d.path}.
|
|
454
454
|
`:`${u==="installed"?"Installed":"Updated"} ${d.label} at ${d.path}.
|
|
455
455
|
`)}return 0}catch(o){let a=o instanceof Error?o.message:String(o);return r.write(`${a}
|
|
456
|
-
`),1}};var
|
|
456
|
+
`),1}};var HG=new Set(["clientId","issuer","authorizationUrl","tokenUrl","scopes","redirectPort","additionalRedirectReferrerHosts"]),GG=/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/iu,VG=e=>{let t=e.toLowerCase();return t.startsWith("[")&&t.endsWith("]")&&(t=t.slice(1,-1)),t.endsWith(".")&&(t=t.slice(0,-1)),t==="localhost"||t.endsWith(".localhost")||t==="::1"||t.startsWith("127.")},KG=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),Xd=(e,t)=>{let n;try{n=new URL(e)}catch{throw new Error(`${t} must be a valid HTTPS URL.`)}if(n.protocol!=="https:"||n.username!==""||n.password!==""||n.hash!==""||VG(n.hostname))throw new Error(`${t} must be a non-loopback HTTPS URL without credentials or a fragment.`);return n.toString()},Fa=(e,t,n)=>{if(!(e===void 0&&!n)){if(typeof e!="string"||e.trim()==="")throw new Error(`--bootstrap-oidc ${t} must be a non-empty string.`);return e.trim()}},OI=e=>{if(!KG(e))throw new Error("--bootstrap-oidc must be a JSON object.");let t=Object.keys(e).filter(l=>!HG.has(l));if(t.length>0)throw new Error(`--bootstrap-oidc contains unsupported fields: ${t.join(", ")}.`);let n=Fa(e.clientId,"clientId",!0),r=Fa(e.scopes,"scopes",!0),o=Fa(e.issuer,"issuer",!1),a=Fa(e.authorizationUrl,"authorizationUrl",!1),s=Fa(e.tokenUrl,"tokenUrl",!1),i=Fa(e.additionalRedirectReferrerHosts,"additionalRedirectReferrerHosts",!1);if(!o&&!(a&&s))throw new Error("--bootstrap-oidc requires issuer, or both authorizationUrl and tokenUrl.");let c=e.redirectPort;if(c!==void 0&&(typeof c!="number"||!Number.isInteger(c)||c<1||c>65535))throw new Error("--bootstrap-oidc redirectPort must be an integer from 1 to 65535.");return{clientId:n,scopes:r,...o?{issuer:Xd(o,"bootstrap OIDC issuer")}:{},...a?{authorizationUrl:Xd(a,"bootstrap OIDC authorizationUrl")}:{},...s?{tokenUrl:Xd(s,"bootstrap OIDC tokenUrl")}:{},...c===void 0?{}:{redirectPort:c},...i?{additionalRedirectReferrerHosts:i}:{}}},TI=e=>{let t;try{t=JSON.parse(e)}catch{throw new Error("--bootstrap-oidc must be valid JSON.")}return OI(t)},ry=e=>e==="windows"?jd:Kd,jG=(e,t)=>{let n=new URL(e);return n.searchParams.set("os",t),n.toString()},zd=(e,t)=>{let n=jG(Xd(e.url,"--bootstrap-url"),t),r=e.oidc?OI(e.oidc):void 0,o;if(e.deploymentOrganizationUuid!==void 0&&(o=e.deploymentOrganizationUuid.trim(),!GG.test(o)))throw new Error("--deployment-organization-uuid must be a UUID without braces.");return{bootstrapEnabled:!0,bootstrapUrl:n,bootstrapHeadersHelper:ry(t),...r?{bootstrapOidc:r}:{},...o?{deploymentOrganizationUuid:o}:{}}},_I=(e,t)=>vr(zd(e,t));var zG=`anyray-connect desktop [disconnect] [options]
|
|
457
457
|
|
|
458
458
|
The minimum Claude Desktop workflow:
|
|
459
459
|
anyray-connect desktop Connect this machine
|
|
@@ -498,8 +498,8 @@ Options:
|
|
|
498
498
|
|
|
499
499
|
Older flag-based Claude artifacts and Codex fleet output remain accepted for
|
|
500
500
|
compatibility, but are not part of the recommended Claude Desktop workflow.
|
|
501
|
-
`,
|
|
502
|
-
<string>${Zn(t)}</string>`,ay=(e,t,n,r,o,a)=>{let s=Object.entries(a).map(([i,c])=>
|
|
501
|
+
`,qG=e=>e==="macos"?"--mobileconfig":e==="windows"?"--reg":"--json",QG=e=>e.map(t=>t==="--oidc"?"--bootstrap-oidc":t==="--organization"?"--deployment-organization-uuid":t),e1=e=>{if(e[0]!=="fleet")return e;if(e.includes("--help")||e.includes("-h"))return["--help"];let t=e[1];if(t!=="bootstrap"&&t!=="static")throw new Error("desktop fleet requires bootstrap or static.");let n=e[2];if(n!=="macos"&&n!=="windows"&&n!=="linux")throw new Error("desktop fleet target must be macos, windows, or linux.");let r=e[3];if(!r||r.startsWith("-"))throw new Error(t==="bootstrap"?"desktop fleet bootstrap requires an HTTPS URL.":"desktop fleet static requires an absolute credential-helper path.");let o=e.slice(4),a=o[0]&&!o[0].startsWith("-")?o.shift():void 0;return[qG(n),...a?[a]:[],t==="bootstrap"?"--bootstrap-url":"--helper-path",r,...QG(o)]},t1=new Set(["--help","-h","--migrate","--account","--all-accounts","--mobileconfig","--reg","--json","--helper-path","--bootstrap-url","--bootstrap-oidc","--deployment-organization-uuid","--tools"]),oy=e=>{let t=e[0]==="claude"?e.slice(1):[...e],n=t[0];if(!(n!==void 0&&!n.startsWith("-")&&n!=="disconnect"||t.some(r=>t1.has(r))||t.includes("--apply")&&t.includes("--revert")||n==="disconnect"&&t.includes("--apply")))return n==="disconnect"&&(t=["--revert",...t.slice(1)]),t=t.filter(r=>r!=="--apply"),[...t,"--tools","claude-desktop"]},Zn=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),PI=e=>e.replace(/\\/g,"\\\\").replace(/"/g,'\\"'),n1=(e,t)=>` <key>${Zn(e)}</key>
|
|
502
|
+
<string>${Zn(t)}</string>`,ay=(e,t,n,r,o,a)=>{let s=Object.entries(a).map(([i,c])=>n1(i,c)).join(`
|
|
503
503
|
`);return`<?xml version="1.0" encoding="UTF-8"?>
|
|
504
504
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
505
505
|
<plist version="1.0">
|
|
@@ -532,21 +532,21 @@ ${s}
|
|
|
532
532
|
<string>${Zn(n)}</string>
|
|
533
533
|
</dict>
|
|
534
534
|
</plist>
|
|
535
|
-
`},_i={disableDeploymentModeChooser:!0},LI=(e,t)=>ay("com.anthropic.claudefordesktop","ai.anyray.claude-desktop.gateway","Anyray Claude Desktop Gateway","5C26E2C1-B0D9-4C0E-9E26-7A7C9408B410","1E7C6758-6415-49E7-A368-D5FD4E7AE389",vr({...co(e,t),..._i})),
|
|
536
|
-
`,
|
|
535
|
+
`},_i={disableDeploymentModeChooser:!0},LI=(e,t)=>ay("com.anthropic.claudefordesktop","ai.anyray.claude-desktop.gateway","Anyray Claude Desktop Gateway","5C26E2C1-B0D9-4C0E-9E26-7A7C9408B410","1E7C6758-6415-49E7-A368-D5FD4E7AE389",vr({...co(e,t),..._i})),r1=(e,t)=>`${JSON.stringify({...co(e,t),..._i},null,2)}
|
|
536
|
+
`,o1=e=>ay("com.anthropic.claudefordesktop","ai.anyray.claude-desktop.bootstrap","Anyray Claude Desktop Bootstrap","47D58D65-92C5-4E5C-B5F8-B6D25CC64383","890F9670-57D5-487D-88E8-D3321E73F564",vr({...zd(e,"macos"),..._i})),a1=e=>`${JSON.stringify({...zd(e,"linux"),..._i},null,2)}
|
|
537
537
|
`,NI=e=>["Windows Registry Editor Version 5.00","","[HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Claude]",...Object.entries({...e,...vr(_i)}).map(([n,r])=>`"${PI(n)}"="${PI(r)}"`),""].join(`
|
|
538
|
-
`),$I=(e,t)=>{let n=Zl(e,t);return NI(Object.fromEntries(Object.entries(n).filter(r=>r[1]!==void 0)))},
|
|
538
|
+
`),$I=(e,t)=>{let n=Zl(e,t);return NI(Object.fromEntries(Object.entries(n).filter(r=>r[1]!==void 0)))},s1=e=>NI(_I(e,"windows")),MI=(e,t,n)=>{if(t==="darwin"){let r=xi;return{path:`${n}/claude-desktop-anyray.mobileconfig`,content:LI(e,r),helperPath:r}}if(t==="win32"){let r=Ri;return{path:`${n}\\claude-desktop-anyray.reg`,content:$I(e,r),helperPath:r}}},BI=(e,t)=>[`Generated the complete Claude Desktop profile your administrator can deploy: ${e.path}`,t==="darwin"?"Send it to IT to push through MDM (Jamf, Intune, Kandji). It carries the full Anyray connection \u2014 no hand-merging, and no Developer Mode on the target machines.":"Send it to IT to import into machine policy (HKLM\\SOFTWARE\\Policies\\Claude), or push it through your device-management system.",`It references the shared credential helper at ${e.helperPath}, which IT deploys once per machine with \`anyray-connect desktop helper --write\`. The profile contains no credential.`,"Nothing on this machine changed; the managed policy stays authoritative until IT deploys it."],i1=(e,t)=>{if(e.authMode==="subscription")throw new Error("Codex subscription managed config is not supported: ChatGPT OAuth still requires a personal gateway key in x-anyray-api-key; run per-user Connect enrollment instead");let n=/^[A-Za-z]:[\\/]/.test(t)?"windows":"posix",r=Yd(n,t),o={auth:"command",authCommand:r.command,authArgs:r.args,ignoreEnv:!0};return`${Cs(e,o).join(`
|
|
539
539
|
`)}
|
|
540
|
-
`},
|
|
540
|
+
`},c1=e=>ay("com.openai.codex","ai.anyray.codex.gateway","Anyray Codex Gateway","F99FB627-DF28-4C90-A253-00B0B62F6B1A","817E3D74-0362-4A27-A7D6-4A74EB316527",{config_toml_base64:XG.from(e,"utf-8").toString("base64")}),l1=e=>{let t={target:e[0]==="codex"?"codex":"claude",migrate:!1,allAccounts:!1,help:!1},n=e[0]==="codex"||e[0]==="claude"?1:0,r=()=>e[++n],o=()=>{let a=e[n+1];if(a&&!a.startsWith("-"))return n++,a};for(;n<e.length;n++){let a=e[n];switch(a){case"--mobileconfig":t.artifact="mobileconfig",t.path=o();break;case"--reg":t.artifact="reg",t.path=o();break;case"--json":t.artifact="json",t.path=o();break;case"--migrate":t.migrate=!0;break;case"--account":t.account=r();break;case"--all-accounts":t.allAccounts=!0;break;case"--gateway":t.gateway=r();break;case"--helper-path":t.helperPath=r()??"";break;case"--bootstrap-url":t.bootstrapUrl=r()??"";break;case"--bootstrap-oidc":t.bootstrapOidc=r()??"";break;case"--deployment-organization-uuid":t.deploymentOrganizationUuid=r()??"";break;case"--team":t.team=r();break;case"--intent":t.intent=r();break;case"--intent-label":t.intentLabel=r();break;case"--subscription":throw new Error("--subscription cannot produce a valid credentialless Codex fleet artifact; run normal per-user Connect enrollment so x-anyray-api-key is available");case"--placeholder":case"--org":throw new Error(`${a} is a legacy no-op for Codex fleet artifacts; omit it and enroll each user`);case"--help":case"-h":t.help=!0;break;default:throw new Error(a.startsWith("-")?`unknown option: ${a}`:`unexpected argument: ${a}`)}}return t},d1=e=>{if(!e.gateway?.trim())throw new Error("--gateway is required for static fleet artifacts; local profile and environment values are intentionally ignored.");let t=Kt(e.gateway);return{origin:t,anthropicBaseUrl:t,openaiBaseUrl:`${t}/v1`,placeholderKey:os,authMode:"placeholder",metadata:{team:e.team?.trim()||void 0,intent:e.intent?.trim()||void 0,intentLabel:e.intentLabel?.trim()||void 0}}},DI=async(e,t,n)=>{if(!t){(n.stdout??process.stdout).write(e);return}let r=n.mkdir??ZG,o=n.writeFile??YG;await r(JG(t),{recursive:!0}),await o(t,e)},u1=(e,t,n,r,o)=>{o.write(`This artifact requires the credential helper at ${n}; the artifact does not install or update it. Deploy a stable anyray-connect binary through your software-distribution system first, then install/package the helper with:
|
|
541
541
|
`),o.write(r==="windows"?` anyray-connect desktop helper --write --platform windows --bin "C:\\Program Files\\Anyray\\anyray-connect.exe" --path "${n}"
|
|
542
542
|
`:` sudo anyray-connect desktop helper --write --platform posix --bin /usr/local/bin/anyray-connect --path '${n.replace(/'/g,`'"'"'`)}'
|
|
543
543
|
`),e==="codex"?o.write(`Non-MDM Codex fleets can place this TOML at /etc/codex/managed_config.toml on Unix or %ProgramData%\\OpenAI\\Codex\\managed_config.toml on Windows.
|
|
544
544
|
`):t==="json"&&o.write(`Deploy this file to /etc/claude-desktop/managed-settings.json.
|
|
545
|
-
`)},
|
|
545
|
+
`)},p1=(e,t)=>{t.write(`This artifact is a stable MDM trust anchor; it contains no inference credential. Claude Desktop authenticates the user and fetches the effective configuration from the bootstrap service at launch.
|
|
546
546
|
`),t.write(`The bootstrap fetch is authenticated by the bootstrap-headers helper at ${ry(e)}, and the response names the credential helper; install both on every managed machine first with \`anyray-connect desktop helper --write\` (deploy a stable anyray-connect binary through your software-distribution system before that).
|
|
547
547
|
`),t.write(`Update the bootstrap response instead of redeploying MDM. Claude polls every 30 minutes, then applies changed values on the next Claude Desktop launch; no managed action is required for each policy update.
|
|
548
548
|
`),t.write(`Each bootstrap response replaces the allowed managed configuration; omitted keys are unset.
|
|
549
|
-
`)},
|
|
549
|
+
`)},f1=async(e,t)=>{let n=t.stdout??process.stdout,r=t.stderr??process.stderr,o=await(t.migrateProfile??fo)({account:e.account,allAccounts:e.allAccounts});if(!o.ok)return r.write(`Cannot migrate: ${o.reason}.
|
|
550
550
|
${o.remedy}
|
|
551
551
|
`),1;let a=o.lanes.reduce((c,l)=>c+l.migrated,0),s=o.portableAssets.reduce((c,l)=>c+l.migrated,0),i={code:"Claude Code sessions",cowork:"Cowork tasks"};for(let c of o.lanes){let l=[c.alreadyPresent>0?`${c.alreadyPresent} already there`:"",c.skippedNoTranscript>0?`${c.skippedNoTranscript} skipped, transcript no longer on disk`:"",c.failed>0?`${c.failed} failed`:""].filter(Boolean);n.write(` ${i[c.lane]}: ${c.migrated} migrated`+(l.length>0?` (${l.join("; ")})`:"")+`
|
|
552
552
|
`)}for(let c of o.portableAssets){let l=c.migrated+c.alreadyPresent,d=c.conflicts+c.invalid+c.failed;if(l+d===0)continue;let u=c.kind==="skill"?"User-created skills":c.kind==="plugin"?"User-installed plugins":"Local MCP servers";n.write(` ${u}: ${c.migrated} migrated`+(c.alreadyPresent>0?` (${c.alreadyPresent} already there)`:"")+(d>0?` (${d} preserved or skipped)`:"")+`
|
|
@@ -557,10 +557,10 @@ Reopen Claude Desktop \u2014 migrated ${c} available in the Anyray profile.
|
|
|
557
557
|
Your previous profile is untouched, so \`desktop disconnect\` still works.
|
|
558
558
|
`)}else n.write(`
|
|
559
559
|
Nothing new to migrate \u2014 no local sessions or portable local data needed copying.
|
|
560
|
-
`);return n.write(" claude.ai chats live on your account, not this machine: bring those\n over with `anyray-connect history restore <export.zip>`.\n"),0},FI=async(e,t={})=>{let n=t.stdout??process.stdout,r=t.stderr??process.stderr;try{let o=
|
|
561
|
-
`),0}if(!a.helperPath?.trim())throw new Error(`--helper-path is required for fleet artifacts. Deploy it first with \`anyray-connect desktop helper --write\`; use ${xi} on macOS/Linux or ${Ri} on Windows.`);if(a.target==="claude"&&(a.team!==void 0||a.intent!==void 0||a.intentLabel!==void 0))throw new Error("--team and --intent flags do not belong in a Claude Desktop static artifact; each user's enrolled profile supplies attribution.");let i=a.helperPath,c=a.artifact==="reg"||/^[A-Za-z]:[\\/]/.test(i)?"windows":"posix";if(!Oi(i,c))throw new Error(`--helper-path must be an absolute ${c} path for this artifact.`);if(a.artifact==="mobileconfig"&&c!=="posix")throw new Error("--mobileconfig requires a POSIX --helper-path.");a.artifact==="reg"&&Yd("windows",i);let l=
|
|
560
|
+
`);return n.write(" claude.ai chats live on your account, not this machine: bring those\n over with `anyray-connect history restore <export.zip>`.\n"),0},FI=async(e,t={})=>{let n=t.stdout??process.stdout,r=t.stderr??process.stderr;try{let o=e1(e);if(o[0]==="helper")return RI(o.slice(1),t);let a=l1(o);if(a.help)return n.write(zG),0;let s=a.bootstrapUrl!==void 0||a.bootstrapOidc!==void 0||a.deploymentOrganizationUuid!==void 0;if(s){if(a.target!=="claude")throw new Error("--bootstrap-url is for Claude Desktop only.");if(a.migrate)throw new Error("Bootstrap options emit an MDM artifact; they cannot be combined with --migrate.");if(!a.artifact)throw new Error("--bootstrap-url requires --mobileconfig, --reg or --json to emit the trust anchor.");if(a.bootstrapUrl===void 0){let u=a.bootstrapOidc!==void 0?"--bootstrap-oidc":"--deployment-organization-uuid";throw new Error(`${u} requires --bootstrap-url.`)}if(a.helperPath!==void 0)throw new Error("--bootstrap-url cannot be combined with --helper-path; the bootstrap response supplies the effective inference configuration.");if(a.gateway!==void 0)throw new Error("--bootstrap-url cannot be combined with --gateway; return the inference gateway URL from the bootstrap response.");if(a.team!==void 0||a.intent!==void 0||a.intentLabel!==void 0)throw new Error("--bootstrap-url cannot be combined with --team or --intent flags; return per-user attribution from the bootstrap response.")}if(a.migrate){if(a.artifact)throw new Error("--migrate moves this machine's own sessions; drop --reg/--mobileconfig.");if(a.target==="codex")throw new Error("`desktop --migrate` applies only to Claude Desktop.");return await f1(a,t)}if(a.target==="codex"&&a.artifact==="reg")throw new Error("Codex fleet config does not use a Windows .reg file.");if(a.target==="codex"&&a.artifact==="json")throw new Error("Codex fleet config is managed_config.toml, not Claude's Linux managed-settings.json.");if(a.target==="claude"&&!a.artifact)throw new Error("Local Claude Desktop connect/disconnect is owned by the main Connect lifecycle.");if(s){let u={url:a.bootstrapUrl,...a.bootstrapOidc===void 0?{}:{oidc:TI(a.bootstrapOidc)},...a.deploymentOrganizationUuid===void 0?{}:{deploymentOrganizationUuid:a.deploymentOrganizationUuid}},p=a.artifact==="reg"?s1(u):a.artifact==="json"?a1(u):o1(u);return await DI(p,a.path,t),p1(a.artifact==="reg"?"windows":a.artifact==="json"?"linux":"macos",r),a.path&&n.write(`Wrote ${a.path}
|
|
561
|
+
`),0}if(!a.helperPath?.trim())throw new Error(`--helper-path is required for fleet artifacts. Deploy it first with \`anyray-connect desktop helper --write\`; use ${xi} on macOS/Linux or ${Ri} on Windows.`);if(a.target==="claude"&&(a.team!==void 0||a.intent!==void 0||a.intentLabel!==void 0))throw new Error("--team and --intent flags do not belong in a Claude Desktop static artifact; each user's enrolled profile supplies attribution.");let i=a.helperPath,c=a.artifact==="reg"||/^[A-Za-z]:[\\/]/.test(i)?"windows":"posix";if(!Oi(i,c))throw new Error(`--helper-path must be an absolute ${c} path for this artifact.`);if(a.artifact==="mobileconfig"&&c!=="posix")throw new Error("--mobileconfig requires a POSIX --helper-path.");a.artifact==="reg"&&Yd("windows",i);let l=d1(a),d;if(a.target==="claude")d=a.artifact==="reg"?$I(l,i):a.artifact==="json"?r1(l,i):LI(l,i);else{let u=i1(l,i);d=a.artifact==="mobileconfig"?c1(u):u}return await DI(d,a.path,t),u1(a.target,a.artifact,i,c,r),a.path&&n.write(`Wrote ${a.path}
|
|
562
562
|
`),0}catch(o){let a=o instanceof Error?o.message:String(o);return r.write(`${a}
|
|
563
|
-
`),1}};var
|
|
563
|
+
`),1}};var m1=`anyray-connect retrieve <handle> [--source auto|claude|profile]
|
|
564
564
|
|
|
565
565
|
Print the original content Anyray externalized behind a "\xB7 retrieve ctx_\u2026"
|
|
566
566
|
marker. The content is written to stdout byte-for-byte (no trailing newline
|
|
@@ -570,7 +570,7 @@ Options:
|
|
|
570
570
|
--source <s> Which client config resolves the gateway: auto (default),
|
|
571
571
|
claude (~/.claude/settings.json), or profile (~/.anyray).
|
|
572
572
|
--help Show this help.
|
|
573
|
-
`,
|
|
573
|
+
`,h1=`anyray-connect recall <query> [--k N] [--source auto|claude|profile]
|
|
574
574
|
|
|
575
575
|
Semantic search over your externalized tool outputs. Prints one match per line
|
|
576
576
|
to stdout as: handle<TAB>score<TAB>preview. Fetch a full original with
|
|
@@ -581,36 +581,36 @@ Options:
|
|
|
581
581
|
--source <s> Which client config resolves the gateway: auto (default),
|
|
582
582
|
claude (~/.claude/settings.json), or profile (~/.anyray).
|
|
583
583
|
--help Show this help.
|
|
584
|
-
`,WI=(e,t)=>{let n={source:"auto",help:!1};for(let r=0;r<e.length;r++){let o=e[r];if(o==="--help"||o==="-h")n.help=!0;else if(o==="--source"){let a=e[++r];if(a!=="auto"&&a!=="claude"&&a!=="profile")throw new Error("--source must be auto, claude, or profile.");n.source=a}else if(o==="--k"&&t){let a=Number(e[++r]);if(!Number.isInteger(a)||a<1||a>20)throw new Error("--k must be an integer between 1 and 20.");n.k=a}else if(!o.startsWith("-")&&n.positional===void 0)n.positional=o;else throw new Error(`Unknown option: ${o}`)}return n},
|
|
584
|
+
`,WI=(e,t)=>{let n={source:"auto",help:!1};for(let r=0;r<e.length;r++){let o=e[r];if(o==="--help"||o==="-h")n.help=!0;else if(o==="--source"){let a=e[++r];if(a!=="auto"&&a!=="claude"&&a!=="profile")throw new Error("--source must be auto, claude, or profile.");n.source=a}else if(o==="--k"&&t){let a=Number(e[++r]);if(!Number.isInteger(a)||a<1||a>20)throw new Error("--k must be an integer between 1 and 20.");n.k=a}else if(!o.startsWith("-")&&n.positional===void 0)n.positional=o;else throw new Error(`Unknown option: ${o}`)}return n},y1=e=>e.replace(/[\t\r\n]+/g," ").trim(),UI=async(e,t={})=>{let n=t.stdout??process.stdout,r=t.stderr??process.stderr;try{let o=WI(e,!1);if(o.help)return n.write(m1),0;let a=o.positional?.trim();if(!a)return r.write(`A handle is required: anyray-connect retrieve ctx_\u2026 (see --help)
|
|
585
585
|
`),1;let s=await(t.readTarget??nt)(o.source),i=await(t.retrieve??La)(s,a,{probe:!0});return i.ok?(n.write(i.content),0):(r.write(`${i.message}
|
|
586
586
|
`),1)}catch(o){return r.write(`${o instanceof Error?o.message:String(o)}
|
|
587
|
-
`),1}},HI=async(e,t={})=>{let n=t.stdout??process.stdout,r=t.stderr??process.stderr;try{let o=WI(e,!0);if(o.help)return n.write(
|
|
587
|
+
`),1}},HI=async(e,t={})=>{let n=t.stdout??process.stdout,r=t.stderr??process.stderr;try{let o=WI(e,!0);if(o.help)return n.write(h1),0;let a=o.positional?.trim();if(!a)return r.write(`A query is required: anyray-connect recall "what to find" (see --help)
|
|
588
588
|
`),1;let s=await(t.readTarget??nt)(o.source),i=await(t.recall??_d)(s,a,o.k,{probe:!0});if(!i.ok)return r.write(`${i.message}
|
|
589
589
|
`),1;if(i.matches.length===0)return r.write(`No matching externalized outputs found.
|
|
590
|
-
`),1;for(let c of i.matches){let l=Number.isFinite(c.score)?c.score.toFixed(3):"?";n.write(`${c.handle} ${l} ${
|
|
590
|
+
`),1;for(let c of i.matches){let l=Number.isFinite(c.score)?c.score.toFixed(3):"?";n.write(`${c.handle} ${l} ${y1(c.preview)}
|
|
591
591
|
`)}return r.write(`Fetch a full original: anyray-connect retrieve <handle>
|
|
592
592
|
`),0}catch(o){return r.write(`${o instanceof Error?o.message:String(o)}
|
|
593
|
-
`),1}};import{promises as
|
|
593
|
+
`),1}};import{promises as H1}from"node:fs";var Sn=e=>typeof e=="string"?e:"",g1=e=>{let t=Sn(e.text).trim();if(t)return t;let n=e.content;if(!Array.isArray(n))return"";let r=[];for(let o of n){if(!o||typeof o!="object")continue;let a=Sn(o.text).trim();a&&r.push(a)}return r.join(`
|
|
594
594
|
|
|
595
|
-
`).trim()},
|
|
595
|
+
`).trim()},w1=e=>{let t=Sn(e.sender).trim().toLowerCase();return t==="human"||t==="user"?"user":"assistant"},b1=e=>{if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n,o=g1(r);if(!o)continue;let a=Sn(r.created_at).trim();t.push({role:w1(r),text:o,...a?{createdAt:a}:{}})}return t},qd=e=>{let t;try{t=JSON.parse(e)}catch{return{ok:!1,conversations:[],skipped:0,message:"the file is not valid JSON"}}let n=Array.isArray(t)?t:t&&typeof t=="object"&&Array.isArray(t.conversations)?t.conversations:null;if(!n)return{ok:!1,conversations:[],skipped:0,message:"expected a list of conversations \u2014 is this the conversations.json from a Claude data export?"};let r=[],o=0;for(let a of n){if(!a||typeof a!="object"){o+=1;continue}let s=a,i=b1(s.chat_messages??s.messages);if(i.length===0){o+=1;continue}let c=(Sn(s.uuid)||Sn(s.id)).trim(),l=(Sn(s.name)||Sn(s.title)).trim()||"Untitled conversation",d=Sn(s.created_at).trim(),u=Sn(s.updated_at).trim();r.push({uuid:c,title:l,...d?{createdAt:d}:{},...u?{updatedAt:u}:{},messages:i})}return{ok:!0,conversations:r,skipped:o}};import{createHash as $1}from"node:crypto";import{promises as Li}from"node:fs";import{homedir as JI}from"node:os";import{join as eu}from"node:path";import{promises as GI}from"node:fs";import sy from"node:path";var A1=4e4,C1=16*1024*1024,Pi=(e,t)=>({ok:!1,content:"",path:e,lines:0,truncated:!1,message:t}),Di=async(e,t={})=>{let n=(e??"").trim();if(!n)return Pi("","path is required");let r=t.cwd??process.cwd(),o=sy.resolve(r,n),a=sy.relative(r,o);if(a.startsWith("..")||sy.isAbsolute(a))return Pi(n,"path is outside the workspace");let s=t.maxBytes??A1,i;try{let w=await GI.stat(o);if(!w.isFile())return Pi(n,"not a regular file");let y=t.maxFileBytes??C1;if(w.size>y)return Pi(n,`file too large to read (${w.size} bytes; limit ${y})`);i=await GI.readFile(o,"utf8")}catch(w){return Pi(n,w instanceof Error?w.message:"read failed")}let c=i.split(`
|
|
596
596
|
`),l=Math.max(1,t.startLine??1),d=Math.min(c.length,t.endLine??c.length),u=l<=d?c.slice(l-1,d):[],p=u.join(`
|
|
597
597
|
`),m=l<=d?d:l,f=!1,h=!1;if(Buffer.byteLength(p,"utf8")>s){let w=0,y=0;for(let g of u){let b=Buffer.byteLength(g,"utf8")+(y===0?0:1);if(w+b>s)break;w+=b,y+=1}y===0?(p=Buffer.from(u[0]??"","utf8").subarray(0,s).toString("utf8").replace(/\uFFFD$/,""),m=l,f=!0):(p=u.slice(0,y).join(`
|
|
598
598
|
`),m=l+y-1),h=!0}return{ok:!0,content:p,path:n,lines:c.length,truncated:h,span:{startLine:l,endLine:m,...f?{partialLine:!0}:{}}}},iy=e=>{if(!e.ok)return`Read failed: ${e.message??"unknown error"}`;if(!e.truncated)return`${e.path}:
|
|
599
599
|
${e.content}`;let t=e.span?`lines ${e.span.startLine}-${e.span.endLine}`:"a prefix",n=e.span&&!e.span.partialLine&&e.span.endLine<e.lines?` Continue with anyray_read(path="${e.path}", startLine=${e.span.endLine+1}).`:"";return`${e.path} (truncated \u2014 showing ${t} of ${e.lines}).${n}
|
|
600
|
-
${e.content}`};import{spawn as
|
|
601
|
-
`)){if(r.length>=n)break;if(!o)continue;let a=o.indexOf(":");if(a<=0)continue;let s=o.indexOf(":",a+1);if(s<0)continue;let i=o.slice(0,a).replace(/^\.\//,""),c=Number(o.slice(a+1,s));if(!Number.isInteger(c)||c<=0)continue;let l=o.slice(s+1);r.push({file:i,line:c,text:KI(l,t)})}return r},
|
|
602
|
-
`);for(let C=0;C<k.length;C+=1){let S=c(k[C]);if(l.some(E=>S.includes(E))&&(u.push({file:ly.relative(t,g),line:C+1,text:KI(k[C],o)}),u.length>=r)){m=!0;return}}}}};return await f(t),{ok:!0,matches:u,truncated:m,engine:"walk"}},Qd=async(e,t={})=>{let n=e.trim();if(!n)return{ok:!1,matches:[],truncated:!1,engine:"ripgrep",message:"query is required"};let r=t.cwd??process.cwd(),o=t.globs??[],a=t.maxMatches??dy,s=t.maxColumns??
|
|
600
|
+
${e.content}`};import{spawn as k1}from"node:child_process";import{promises as cy}from"node:fs";import ly from"node:path";var dy=400,v1=240,S1=4e3,E1=4e3,I1=512*1024,x1=new Set([".git","node_modules","dist","build","out",".next","coverage",".turbo","vendor","__pycache__",".venv",".cache",".idea",".gradle",".pytest_cache",".mypy_cache"]),KI=(e,t)=>e.length>t?e.slice(0,t):e,R1=new Set(["a","about","an","and","are","as","at","be","been","but","by","can","could","did","do","does","for","from","had","has","have","here","how","if","in","is","it","me","my","of","on","or","our","should","so","that","the","their","there","this","to","us","was","we","were","what","when","where","which","who","why","with","would","you","your"]),O1=8,T1=2e3,_1=["!.env*","!*.pem","!*.key","!*.p12","!*.pfx","!id_rsa*","!id_ed25519*","!*secret*","!*credential*","!**/.ssh/**","!**/.aws/**","!**/.gnupg/**"],P1=e=>{let t=e.toLowerCase(),n=t.split(/[\\/]/).pop()??t;return/(^|[\\/])\.(ssh|aws|gnupg)([\\/]|$)/.test(t)||n.startsWith(".env")||n.startsWith("id_rsa")||n.startsWith("id_ed25519")||/\.(pem|key|p12|pfx)$/.test(n)?!0:n.includes("secret")||n.includes("credential")},jI=e=>{let t=new Set,n=[];for(let r of e.trim().split(/\s+/)){if(r.length<2)continue;let o=r.toLowerCase();if(!R1.has(o)&&!t.has(o)&&(t.add(o),n.push(r),n.length>=O1))break}return n},ZI=e=>{let t=Array.isArray(e)?e.join(" "):e;return new RegExp("\\p{Lu}","u").test(t)},D1=(e,t,n)=>{if(t.length<2)return e;let r=n?t:t.map(a=>a.toLowerCase()),o=a=>{let s=n?a.text:a.text.toLowerCase(),i=0;for(let c of r)s.includes(c)&&(i+=1);return i};return e.map((a,s)=>({m:a,i:s,s:o(a)})).sort((a,s)=>s.s-a.s||a.i-s.i).map(a=>a.m)},VI=(e,t,n)=>{let r=[];for(let o of e.split(`
|
|
601
|
+
`)){if(r.length>=n)break;if(!o)continue;let a=o.indexOf(":");if(a<=0)continue;let s=o.indexOf(":",a+1);if(s<0)continue;let i=o.slice(0,a).replace(/^\.\//,""),c=Number(o.slice(a+1,s));if(!Number.isInteger(c)||c<=0)continue;let l=o.slice(s+1);r.push({file:i,line:c,text:KI(l,t)})}return r},L1=(e,t,n,r,o,a,s)=>new Promise(i=>{let c=["--line-number","--no-heading","--color","never","--max-columns",String(o),"--max-columns-preview","--smart-case","--max-count","20","--fixed-strings"];for(let f of n)c.push("-g",f);for(let f of _1)c.push("-g",f);if(s?.length){for(let f of s)c.push("-e",f);c.push("--",".")}else c.push("--",e,".");let l;try{l=k1("rg",c,{cwd:t})}catch{i({ok:!1,matches:[],truncated:!1,engine:"ripgrep",message:"ripgrep unavailable"});return}let d="",u=!1,p=f=>{u||(u=!0,clearTimeout(m),i(f))},m=setTimeout(()=>{try{l.kill("SIGKILL")}catch{}let f=VI(d,o,r);p({ok:!0,matches:f,truncated:!0,engine:"ripgrep"})},a);l.stdout?.setEncoding("utf8"),l.stdout?.on("data",f=>{if(d+=f,d.length>r*(o+64))try{l.kill("SIGKILL")}catch{}}),l.on("error",()=>{p({ok:!1,matches:[],truncated:!1,engine:"ripgrep",message:"ripgrep unavailable"})}),l.on("close",f=>{if(typeof f=="number"&&f>=2){p({ok:!1,matches:[],truncated:!1,engine:"ripgrep",message:"ripgrep unavailable"});return}let h=VI(d,o,r+1),w=h.length>r;p({ok:!0,matches:w?h.slice(0,r):h,truncated:w,engine:"ripgrep"})})}),N1=async(e,t,n,r,o,a,s)=>{let i=ZI(s?.length?s:e),c=h=>i?h:h.toLowerCase(),l=(s?.length?s:[e]).map(c),d=n.map(h=>h.replace(/^\*+/,"")).filter(h=>h.startsWith(".")),u=[],p=0,m=!1,f=async h=>{if(u.length>=r||Date.now()>a){m=!0;return}let w;try{w=await cy.readdir(h,{withFileTypes:!0})}catch{return}for(let y of w){if(u.length>=r||Date.now()>a){m=!0;return}let g=ly.join(h,y.name);if(y.isDirectory()){if(x1.has(y.name))continue;await f(g)}else if(y.isFile()){if(p>=E1){m=!0;return}if(d.length&&!d.some(C=>y.name.endsWith(C))||P1(ly.relative(t,g)))continue;p+=1;let b;try{if((await cy.stat(g)).size>I1)continue;b=await cy.readFile(g,"utf8")}catch{continue}if(b.indexOf("\0")>=0)continue;let k=b.split(`
|
|
602
|
+
`);for(let C=0;C<k.length;C+=1){let S=c(k[C]);if(l.some(E=>S.includes(E))&&(u.push({file:ly.relative(t,g),line:C+1,text:KI(k[C],o)}),u.length>=r)){m=!0;return}}}}};return await f(t),{ok:!0,matches:u,truncated:m,engine:"walk"}},Qd=async(e,t={})=>{let n=e.trim();if(!n)return{ok:!1,matches:[],truncated:!1,engine:"ripgrep",message:"query is required"};let r=t.cwd??process.cwd(),o=t.globs??[],a=t.maxMatches??dy,s=t.maxColumns??v1,i=t.timeoutMs??S1,c=Date.now()+i,l=jI(n),d=l.length>1,u=Math.min(a*4,T1),p=(y,g)=>N1(n,r,o,y,s,c,g),m=async y=>{let g=await y(u,l);if(!g.ok)return g;let b=D1(g.matches,l,ZI(l)),k=b.length>a;return{...g,matches:k?b.slice(0,a):b,truncated:g.truncated||k,matched:"tokens",tokens:l}};if(t.engine==="walk"){let y=await p(a);return y.matches.length>0||!d?y:m((g,b)=>p(g,b))}let f=(y,g)=>L1(n,r,o,y,s,Math.max(0,c-Date.now()),g),h=await f(a);if(h.ok){if(h.matches.length>0||!d)return h;let y=await m((g,b)=>f(g,b));return y.ok?y:m((g,b)=>p(g,b))}let w=await p(a);return w.matches.length>0||!d?w:m((y,g)=>p(y,g))},YI=(e,t,n="full")=>{if(!t.ok)return`Search failed: ${t.message??"unknown error"}`;if(t.matches.length===0){if(t.truncated)return`Search for "${e}" hit its time limit before finishing, and found nothing in what it covered. This is NOT proof the term is absent \u2014 narrow it with globs (e.g. ["*.ts"]) and search again.`;let d=jI(e).length>1?" Searched the phrase and each word separately. Try one identifier on its own (a function, type, or error string), or narrow with globs.":" Try a shorter or differently-cased fragment, or narrow with globs.";return`No matches for "${e}".${d}`}let r=t.matched==="tokens"&&t.tokens?.length?`No line contains "${e}"; showing lines matching its terms (${t.tokens.join(", ")}), most complete first.
|
|
603
603
|
`:"";if(n==="paths"){let d=new Map;for(let p of t.matches)d.set(p.file,(d.get(p.file)??0)+1);let u=[...d].map(([p,m])=>`${p} (${m} match${m===1?"":"es"})`);return[`${r}${d.size}${t.truncated?"+":""} file${d.size===1?"":"s"} match "${e}":`,...u].join(`
|
|
604
604
|
`)}let o=`${r}${t.matches.length}${t.truncated?"+":""} matches for "${e}":`,a=t.matches.map(d=>n==="lines"?`${d.file}:${d.line}`:`${d.file}:${d.line}: ${d.text}`),s=d=>`\u2026 ${d} more match${d===1?"":"es"} not shown (output limit). Narrow with globs or a more specific query, or set resultShape:"paths" to see every file.`,i=s(a.length).length+1,c=o.length,l=0;for(let d of a){if(c+1+d.length+i>4e4)break;c+=1+d.length,l+=1}return l>=a.length?[o,...a].join(`
|
|
605
605
|
`):[o,...a.slice(0,Math.max(1,l)),s(a.length-Math.max(1,l))].join(`
|
|
606
|
-
`)};var XI=448
|
|
606
|
+
`)};var XI=448,M1=384,B1=4e4,Pr=async()=>{let e=process.env.ANYRAY_HISTORY_DIR;if(e)return e;let t=eu(JI(),".anyray");try{if((await Li.stat(t)).isDirectory())return eu(t,"history")}catch{}return eu(JI(),".anyray-history")},F1=e=>{let t=e.title.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,60),n=(e.createdAt??"").slice(0,10),r=(e.uuid||"").replace(/[^a-zA-Z0-9-]/g,"").slice(0,65),o=r.length>0&&r.length<=64?r:W1(e);return`${[n,t||"untitled",o].filter(Boolean).join("_")}.md`},W1=e=>{let t=$1("sha256");t.update(e.title),t.update("\0"),t.update(e.createdAt??""),t.update("\0");for(let n of e.messages)t.update(n.role),t.update("\0"),t.update(n.text),t.update("\0");return t.digest("hex").slice(0,16)},U1=e=>{let t=[`# ${e.title}`,"",e.createdAt?`- Created: ${e.createdAt}`:"",e.updatedAt?`- Updated: ${e.updatedAt}`:"",e.uuid?`- Claude conversation id: ${e.uuid}`:"",""].filter((r,o,a)=>!(r===""&&a[o-1]==="")),n=e.messages.map(r=>{let o=r.role==="user"?"User":"Claude",a=r.createdAt?` (${r.createdAt})`:"";return`## ${o}${a}
|
|
607
607
|
|
|
608
608
|
${r.text}
|
|
609
609
|
`});return[...t,...n].join(`
|
|
610
610
|
`).replace(/\n{3,}/g,`
|
|
611
611
|
|
|
612
612
|
`)+`
|
|
613
|
-
`},tu=async e=>{let t=await Pr();await Li.mkdir(t,{recursive:!0,mode:XI});try{await Li.chmod(t,XI)}catch{}let n=0,r=0;for(let o of e)try{await Li.writeFile(eu(t,
|
|
613
|
+
`},tu=async e=>{let t=await Pr();await Li.mkdir(t,{recursive:!0,mode:XI});try{await Li.chmod(t,XI)}catch{}let n=0,r=0;for(let o of e)try{await Li.writeFile(eu(t,F1(o)),U1(o),{mode:M1}),n+=1}catch{r+=1}return{dir:t,written:n,failed:r}},Wa=async()=>{try{let e=await Pr();return(await Li.readdir(e)).filter(n=>n.endsWith(".md")).length}catch{return 0}},zI=async e=>{let t=await Pr();return Qd(e,{cwd:t,globs:["*.md"]})},qI=async e=>{let t=await Pr();return Di(e,{cwd:t,maxBytes:B1})};var QI=`anyray-connect history <command>
|
|
614
614
|
|
|
615
615
|
Make past Claude conversations searchable from any Anyray-connected client.
|
|
616
616
|
|
|
@@ -631,7 +631,7 @@ Which one you want:
|
|
|
631
631
|
conversation into the chat when you ask for it. Recall, not a list.
|
|
632
632
|
|
|
633
633
|
Running both is fine, and gets you both.
|
|
634
|
-
`,
|
|
634
|
+
`,G1=async e=>{try{return{raw:await H1.readFile(e,"utf8")}}catch(t){let n=t?.code;return n==="ENOENT"?{error:`no such file: ${e}`}:n==="EACCES"?{error:`not readable: ${e}`}:n==="EISDIR"?{error:`${e} is a directory \u2014 point at the conversations.json inside it`}:{error:`could not read ${e} (${n??"read failed"})`}}},V1=async e=>{let t=e.find(a=>!a.startsWith("-"));if(!t)return R("Usage: anyray-connect history import <conversations.json>"),A(v("Get the file from claude.ai \u2192 Settings \u2192 Privacy \u2192 Export data.")),1;let n=await G1(t);if("error"in n)return R(n.error),1;let r=qd(n.raw);if(!r.ok)return R(`Could not read that export: ${r.message??"unrecognized format"}`),A(v("Expected the conversations.json from a Claude data export (claude.ai \u2192 Settings \u2192 Privacy \u2192 Export data).")),1;if(r.conversations.length===0)return R("That export contains no conversations with readable messages."),1;let o;try{o=await tu(r.conversations)}catch(a){let s=a?.code;return R(`Could not create the history archive (${s??"write failed"}).`),A(v("Check that ~/.anyray is a writable directory, then try again.")),1}return B(`Imported ${o.written} conversation${o.written===1?"":"s"} into ${o.dir}`),r.skipped>0&&A(v(` ${r.skipped} entr${r.skipped===1?"y":"ies"} skipped (no readable messages).`)),o.failed>0&&O(`${o.failed} conversation${o.failed===1?"":"s"} could not be written.`),A(""),A(K("Your history is now searchable from any Anyray-connected client.")),A(v(' Ask about a past conversation \u2014 e.g. "what did we decide about the pricing model?" \u2014')),A(v(" and the assistant can search this archive and pull it up.")),A(v(" This is recall, not the Claude Desktop sidebar: past chats come back when you ask")),A(v(" for them, they do not reappear as a clickable list in the app.")),0},K1=async e=>{let t=e.find(r=>!r.startsWith("-"));if(!t)return R("Usage: anyray-connect history restore <export.zip>"),A(v("Get the .zip from claude.ai \u2192 Settings \u2192 Privacy \u2192 Export data.")),1;let n=await Jl(t);return n.ok?(B(`Restored ${n.registered} conversation${n.registered===1?"":"s"} into Claude Desktop`),n.skipped>0&&A(v(` ${n.skipped} already present, left untouched.`)),n.failed>0&&O(`${n.failed} conversation${n.failed===1?"":"s"} could not be written.`),A(""),A(K("Open Claude Desktop \u2014 they are in the sidebar again.")),A(v(" Anyray stays configured; this changed nothing about your routing.")),A(v(" Heads up: this writes into Claude Desktop\u2019s own session storage, which is")),A(v(" undocumented. A future Desktop release could stop reading it \u2014 your export")),A(v(" file still works, and `history import` remains a second copy.")),0):(R(`Could not restore into Claude Desktop: ${n.reason}`),A(v(` ${n.remedy}`)),1)},j1=async()=>{let e=await Pr(),t=await Wa();return t===0?(A(`No conversations imported yet. Archive would live at ${e}`),A(v(" Import one with: anyray-connect history import <conversations.json>")),0):(B(`${t} conversation${t===1?"":"s"} in ${e}`),0)},ex=async e=>{let t=e[0];return!t||t==="--help"||t==="-h"||t==="help"?(console.log(QI),0):t==="import"?V1(e.slice(1)):t==="restore"?K1(e.slice(1)):t==="status"?j1():(R(`Unknown history command: ${t}`),console.log(QI),1)};import{promises as Z1}from"node:fs";var Y1=`anyray-connect migrate [options]
|
|
635
635
|
|
|
636
636
|
Bring what Claude Desktop was showing you onto Anyray. Quit Claude Desktop first.
|
|
637
637
|
|
|
@@ -660,57 +660,57 @@ Getting the export (you do this, not Anyray \u2014 it needs your Claude login):
|
|
|
660
660
|
Open claude.ai -> Settings -> Privacy -> Export data. Anthropic emails a link.
|
|
661
661
|
Pass the .zip to --export, and the conversations.json inside it to
|
|
662
662
|
--conversations. Both are safe to re-run; they skip what is already there.
|
|
663
|
-
`,
|
|
664
|
-
`).filter(Boolean))A(` ${s}`);return!1}for(let s of n.lanes)A(` ${
|
|
663
|
+
`,J1=e=>{let t={allAccounts:!1,help:!1};for(let n=0;n<e.length;n++){let r=e[n];if(r==="--export")t.exportZip=e[++n];else if(r==="--conversations")t.conversations=e[++n];else if(r==="--account")t.account=e[++n];else if(r==="--all-accounts")t.allAccounts=!0;else if(r==="--help"||r==="-h")t.help=!0;else if(!(r==="--yes"||r==="-y"))if(!r.startsWith("-")&&!t.exportZip)r.endsWith(".json")?t.conversations=r:t.exportZip=r;else throw new Error(`unexpected argument: ${r}`)}return t},tx={code:"Claude Code sessions",cowork:"Cowork tasks"},X1=e=>{let t=[e.alreadyPresent>0?`${e.alreadyPresent} already there`:"",e.skippedNoTranscript>0?`${e.skippedNoTranscript} skipped, transcript no longer on disk`:"",e.failed>0?`${e.failed} failed`:""].filter(Boolean);return`${tx[e.lane]}: ${e.migrated} migrated`+(t.length>0?` (${t.join("; ")})`:"")},z1=async(e,t)=>{A(K("1. Local Claude Desktop data on this machine"));let n=await(t.migrateProfile??fo)({account:e.account,allAccounts:e.allAccounts,command:"anyray-connect migrate"});if(!n.ok){R(` ${n.reason}`);for(let s of n.remedy.split(`
|
|
664
|
+
`).filter(Boolean))A(` ${s}`);return!1}for(let s of n.lanes)A(` ${X1(s)}`);for(let s of n.portableAssets){let i=s.migrated+s.alreadyPresent,c=s.conflicts+s.invalid+s.failed;if(i+c===0)continue;let l=s.kind==="skill"?"User-created skills":s.kind==="plugin"?"User-installed plugins":"Local MCP servers";A(` ${l}: ${s.migrated} migrated`+(s.alreadyPresent>0?` (${s.alreadyPresent} already there)`:"")),c>0&&O(` ${c} preserved or skipped because the target wins or no single target store could be selected.`)}let r=n.ambiguousAssets??[];r.length>0&&O(` Claude Desktop has more than one target ${r.join(" and ")} store. No store was chosen and every target was preserved. Leave only the intended third-party account/workspace active, then run this again.`);let o=n.retryableAssets??[];o.length>0&&O(` ${o.length} portable configuration ${o.length===1?"type needs":"types need"} another local-copy attempt; no existing target entry was replaced.`);for(let s of n.blocked??[])O(` ${tx[s.lane]}: ${s.waiting} still waiting \u2014 no ${s.lane} store in the new profile yet.`),A(` ${Wm(s.reason,s.lane,"anyray-connect migrate")}`);return(n.blocked??[]).length===0&&n.lanes.every(s=>s.migrated+s.alreadyPresent+s.skippedNoTranscript+s.failed===0)&&A(v(" Nothing to copy \u2014 the previous profile held no sessions.")),r.length===0&&o.length===0},q1=async(e,t)=>{if(A(""),A(K("2. Your claude.ai chats")),t){A(v(" Waiting on step 1 \u2014 this writes into the same app store."));return}if(!e.exportZip){A(" These live on your Claude account, not this machine, so they need"),A(" an export. Anyray cannot fetch them: the only credential that could"),A(" is your claude.ai session, which Connect never holds."),A(v(" claude.ai -> Settings -> Privacy -> Export data, then:")),A(v(" anyray-connect migrate --export ~/Downloads/claude-export.zip"));return}let n=await Jl(e.exportZip);if(!n.ok){R(` ${n.reason}`),A(` ${n.remedy}`);return}B(` Restored ${n.registered} conversation${n.registered===1?"":"s"}`+(n.skipped>0?` (${n.skipped} already there)`:"")+(n.failed>0?`, ${n.failed} failed`:"")),A(v(" They are listed under Cowork \u2014 the Chat tab has no local store."));let r=n.projects;if(r.imported+r.alreadyPresent+r.skippedCollision+r.failed>0){let a=[r.alreadyPresent>0?`${r.alreadyPresent} already there`:"",r.skippedCollision>0?`${r.skippedCollision} skipped, a folder of that name already exists`:"",r.failed>0?`${r.failed} failed`:""].filter(Boolean);B(` Restored ${r.imported} project${r.imported===1?"":"s"}`+(a.length>0?` (${a.join("; ")})`:"")),r.imported>0&&A(v(` Instructions and docs are in ${r.root}, listed under Projects.`))}},Q1=async e=>{if(A(""),A(K("3. Searchable from every Anyray client")),!e.conversations){let o=await Wa();o>0?A(` Archive already holds ${o} conversation${o===1?"":"s"}.`):(A(v(" Optional. Pass the conversations.json inside the export:")),A(v(" anyray-connect migrate --conversations <path>/conversations.json")));return}let t;try{t=await Z1.readFile(e.conversations,"utf8")}catch{R(` could not read ${e.conversations}`);return}let n=qd(t);if(!n.ok){R(` ${n.message??"that file is not a Claude conversations export"}`);return}let r=await tu(n.conversations);B(` Archived ${r.written} conversation${r.written===1?"":"s"}`+(n.skipped>0?` (${n.skipped} unreadable, skipped)`:"")+(r.failed>0?`, ${r.failed} failed to write`:"")),A(v(` Ask any Anyray-connected client about a past chat. ${await Pr()}`))},eV=e=>{A(""),A(K("Next")),A(" Reopen Claude Desktop. Chat, Cowork and Code should all be there."),e.exportZip||O(" Your claude.ai chats are still only on claude.ai \u2014 see step 2."),A(v(" No Chat tab? Configured before this Connect version: run `anyray-connect desktop`."))},nx=async(e,t={})=>{let n;try{n=J1(e)}catch(o){return R(o instanceof Error?o.message:"could not read the arguments"),1}if(n.help)return process.stdout.write(Y1),0;A(K("Migrating Claude Desktop onto Anyray")),A(v("Claude Desktop must be fully quit.")),A("");let r=await z1(n,t);return await q1(n,!r),await Q1(n),r?(eV(n),0):(A(""),O("Fix the item above and re-run to finish the migration."),1)};var tV=3e3,nu=async(e,t={})=>{let n=t.timeoutMs??tV,r=`${e}/`,o=new AbortController,a=setTimeout(()=>o.abort(),n);try{let s=await fetch(r,{method:"GET",signal:o.signal});return s.ok?{reachable:!0,detail:`responded ${s.status}`}:{reachable:!1,detail:`responded ${s.status} at ${r} \u2014 a healthy gateway answers 200 there`}}catch(s){return{reachable:!1,detail:s instanceof Error&&s.name==="AbortError"?`no response within ${n}ms`:ht(s).trim()||"connection failed"}}finally{clearTimeout(a)}};import{execFileSync as ax}from"node:child_process";import{lstatSync as nV,readFileSync as rV}from"node:fs";import oV from"node:os";var sx="ai.anyray.connect",fy="EnrollmentEmail",my="EnrollmentUrl",aV="HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Anyray\\Connect",rx="/etc/anyray/anyray-enroll.json",sV=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,iV=254,cV=2048,lV=64*1024,dV=e=>e.isFile()&&e.uid===0&&(e.mode&63)===0&&e.size<=lV,uV=()=>`/Library/Managed Preferences/${sx}.plist`,pV=e=>`/Library/Managed Preferences/${e}/${sx}.plist`;var uy=e=>{try{let t=JSON.parse(e);return{...typeof t[fy]=="string"?{email:t[fy]}:{},...typeof t[my]=="string"?{enrollmentUrl:t[my]}:{}}}catch{return{}}},ox=(e,t)=>{for(let n of e.split(/\r?\n/u)){let r=/^\s*(\S+)\s+REG_SZ\s+([^\r\n]+)$/u.exec(n);if(r?.[1]===t)return r[2]?.trim()||void 0}},ix=e=>{if(!e)return;let t=e.trim().toLowerCase();if(!(!t||t.length>iV))return sV.test(t)?t:void 0},fV=e=>{if(!e)return;let t=e.trim();if(!(!t||t.length>cV))try{let n=new URL(t);return n.protocol==="https:"&&n.username===""&&n.password===""&&n.search===""&&n.hash===""&&/^\/enroll\/enp_[A-Za-z0-9_-]{43}$/.test(n.pathname)?n.toString():void 0}catch{return}},mV=e=>{try{return ax("plutil",["-convert","json","-o","-",e],{encoding:"utf8",stdio:["ignore","pipe","ignore"]})}catch{return}},hV=()=>{try{return oV.userInfo().username||void 0}catch{return}},yV=()=>{try{return ax("reg",["query",aV],{encoding:"utf8",stdio:["ignore","pipe","ignore"]})}catch{return}},gV=()=>{try{let e=nV(rx);return dV(e)?rV(rx,"utf8"):void 0}catch{return}},cx={platform:process.platform,readMacPlistJson:mV,username:hV,readWindowsRegQuery:yV,readLinuxJson:gV},py=(e,t)=>{let n=e.map(ix).find(o=>o!==void 0),r=fV(t);return{...n?{email:n}:{},...r?{enrollmentUrl:r}:{}}},xo=(e=cx)=>{try{if(e.platform==="darwin"){let t=e.username(),n=t?uy(e.readMacPlistJson(pV(t))??""):{},r=uy(e.readMacPlistJson(uV())??"");return py([n.email,r.email],r.enrollmentUrl)}if(e.platform==="win32"){let t=e.readWindowsRegQuery();return t?py([ox(t,fy)],ox(t,my)):{}}if(e.platform==="linux"){let t=uy(e.readLinuxJson?.()??"");return py([t.email],t.enrollmentUrl)}return{}}catch{return{}}},lx=(e,t)=>{if(!e?.length)return;let n=t?.trim().split(/[\\/]/).at(-1)?.toLowerCase();if(n)return ix(`${n}@${e[0]}`)},dx=(e=cx)=>xo(e).email;import{spawn as wV}from"node:child_process";import{platform as bV}from"node:os";var Ua=e=>{try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")return;let n=bV(),r=n==="darwin"?"open":n==="win32"?"cmd":"xdg-open",o=n==="win32"?["/c","start",'""',`"${t.href}"`]:[t.href],a=wV(r,o,{detached:!0,stdio:"ignore",windowsHide:!0,windowsVerbatimArguments:n==="win32"});a.on("error",()=>{}),a.unref()}catch{}};var ux=()=>Kh(),px=(e={})=>{if(!(e.output??process.stderr).isTTY)return!1;let t=(e.openInput??ux)();try{return typeof t.stream.setRawMode=="function"}finally{t.close()}},AV=e=>{let t=String(e),n=[];for(let r=0;r<t.length;r++)t[r]==="\x1B"&&t[r+1]==="["&&t[r+2]?(n.push(t.slice(r,r+3)),r+=2):n.push(t[r]);return n},fx=async(e,t={})=>{let n=(t.openInput??ux)(),r=n.stream,o=t.output??process.stderr;if(typeof r.setRawMode!="function")throw n.close(),new Error("raw terminal input is unavailable");let a=e.items.map(f=>f.selected===!0&&f.requiresExplicitChoice!==!0),s=0,i=0,c=Ia(o,t.env??process.env),l=(f,h)=>c?`\x1B[${f}m${h}\x1B[0m`:h,d=()=>{let f=[l("1",e.title)];for(let h=0;h<e.items.length;h++){let w=e.items[h],y=h===s?l("36","\u276F"):" ",g=e.single?a[h]?"(\u25CF)":"(\u25CB)":a[h]?"[x]":"[ ]",b=w.hint?` ${l("2",w.hint)}`:"";f.push(`${y} ${g} ${w.label}${b}`)}f.push(l("2",e.single?"\u2191/\u2193 move \xB7 space choose \xB7 enter accept \xB7 q cancel":"\u2191/\u2193 move \xB7 space toggle \xB7 a toggle all \xB7 enter accept \xB7 q cancel")),i>0&&o.write(`\x1B[${i}A`),o.write(f.map(h=>`\r\x1B[2K${h}`).join(`
|
|
665
665
|
`)),o.write(`
|
|
666
666
|
`),i=f.length},u=()=>{i!==0&&(o.write(`\x1B[${i}A`),o.write(Array.from({length:i},()=>`\r\x1B[2K
|
|
667
|
-
`).join("")),o.write(`\x1B[${i}A`))},p=!!r.isRaw,m=!1;try{return m=!0,r.setRawMode(!0),r.setEncoding?.("utf8"),r.resume?.(),o.write("\x1B[?25l"),d(),await new Promise((f,h)=>{let w=()=>{r.off("data",C),r.off("end",b),r.off("close",b),r.off("error",k)},y=S=>{w(),f(S)},g=S=>{w(),h(S)},b=()=>y({kind:"cancelled"}),k=S=>g(S),C=S=>{try{for(let E of
|
|
667
|
+
`).join("")),o.write(`\x1B[${i}A`))},p=!!r.isRaw,m=!1;try{return m=!0,r.setRawMode(!0),r.setEncoding?.("utf8"),r.resume?.(),o.write("\x1B[?25l"),d(),await new Promise((f,h)=>{let w=()=>{r.off("data",C),r.off("end",b),r.off("close",b),r.off("error",k)},y=S=>{w(),f(S)},g=S=>{w(),h(S)},b=()=>y({kind:"cancelled"}),k=S=>g(S),C=S=>{try{for(let E of AV(S)){if(E===""||E==="\x1B"||E==="q"){y({kind:"cancelled"});return}if(e.items.length===0){(E==="\r"||E===`
|
|
668
668
|
`)&&y({kind:"ok",values:[]});continue}if(E==="\x1B[A"||E==="k")s=(s-1+e.items.length)%e.items.length,d();else if(E==="\x1B[B"||E==="j")s=(s+1)%e.items.length,d();else if(E===" "){if(e.single){let I=!a[s];a.fill(!1),a[s]=I}else a[s]=!a[s];d()}else if(E==="a"&&!e.single){let I=e.items.map((T,W)=>({item:T,index:W})).filter(({item:T})=>T.requiresExplicitChoice!==!0),_=!I.every(({index:T})=>a[T]);for(let{index:T}of I)a[T]=_;d()}else if(E==="\r"||E===`
|
|
669
|
-
`){y({kind:"ok",values:e.items.filter((I,_)=>a[_]).map(I=>I.value)});return}}}catch(E){g(E)}};r.on("data",C),r.on("end",b),r.on("close",b),r.on("error",k)})}finally{try{u(),o.write("\x1B[?25h")}catch{}try{r.pause?.(),m&&r.setRawMode(p)}catch{}n.close()}};var mx=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],
|
|
670
|
-
`),t();let a=0,s=()=>{r.write(`\r${mx[a++%mx.length]} ${e}`)};s();let i=setInterval(s,
|
|
671
|
-
`)){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()}},DV=e=>e.mode==="off"?{allow:!1,outcome:"fleet-off"}:e.mode==="directed"&&e.initiator==="tick"?{allow:!1,outcome:"fleet-directed"}:{allow:!0},LV=e=>e==="auto",wx=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&&Ga(e.current,e.minVersion)<0&&Ga(e.latest,e.minVersion)>=0;return{apply:t,mandatory:t}},NV=e=>Ga(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}:{...wx(e),downgradeBlocked:!1},$V=(e=process.execPath)=>{let t=zu(e);return t?en(t):en(en(e))},MV=async(e=ft())=>{if(/[\\/]node(\.exe)?$/i.test(e.execPath))return;let t=cr($V(e.execPath)).launcher;try{if(await su(t)!==await su(e.execPath))return}catch{return}return t},Ay=async(e=ft(),t=ee())=>{let n=await MV(e);if(n)return{kind:"managed",root:en(en(n)),link:n,entryPath:Xn(e)};let r=Xn(e);return Qu(r,t)?{kind:"durable",root:t,entryPath:r}:Ju(r)?{kind:"npm",root:t,entryPath:r}:{kind:"unmanaged",root:t,entryPath:r}},cu=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)}},Cy=async(e=Bi)=>{let t=await cu(`${ir}/latest`,e,{redirect:"manual"});return PV(t.headers.get("location"))},BV=async e=>{try{let t=await cu(`${e}/connect-update.json`,Bi);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}},Mi=class extends Error{status;constructor(t){super(`download failed (${t})`),this.status=t,this.name="DownloadHttpError"}},ky=async(e,t,n)=>{let r=await cu(e,OV);if(!r.ok||!r.body)throw new Mi(r.status);let o=SV("sha256"),a=0;if(await IV(EV.fromWeb(r.body),async function*(s){for await(let i of s){let c=i;if(a+=c.length,a>RV)throw new Error("asset exceeds size cap");o.update(c),yield c}},CV(t,{mode:493})),o.digest("hex")!==n)throw new Error("checksum mismatch")},FV=e=>ou(e)===Yr()?ou(en(e)):ou(e),WV=async e=>{let t=await iu(e).catch(()=>[]);for(let n of t)/\.part-\d+$/.test(n)&&await xt(Ha(e,n),{force:!0}).catch(()=>{})},bx=async(e,t)=>{if(process.platform==="win32"){let r=`${e}.old-${process.pid}`;await xt(r,{force:!0}).catch(()=>{});let o=!1;try{await ru(e,r),o=!0}catch{}try{await yy(t,e),await vV(ds(e),FV(t))}catch(a){throw o&&await ru(r,e).catch(()=>{}),a}await xt(r,{force:!0}).catch(()=>{});return}let n=`${e}.new-${process.pid}`;await xt(n,{force:!0}),await kV(t,n),await ru(n,e)},vy=(e,t)=>e===t||ou(e)===Cp?448:493,$i=async(e,t)=>{let n=(await gx(e).catch(()=>{}))?.mode;n===void 0||(n&t)===t||await yx(e,n&4095|t).catch(()=>{})},au=async(e,t)=>{await wy(e,{recursive:!0,mode:t}),await $i(e,t)},UV=async(e,t,n)=>{let r=vy(e,ee());if(r!==448){let o=cr(e),a=o.versionsDir;await $i(e,r),await $i(en(o.launcher),r),await $i(a,r);for(let s of await iu(a).catch(()=>[]))await $i(Ha(a,s),r)}await(n.refreshDesktopHelpers??Jd)(t)},HV=async(e,t={})=>{let n=cr(e.root),r=en(n.launcher),{versionsDir:o,launcher:a}=n,s=vy(e.root,(t.privateRoot??ee)());await au(r,s),await au(o,s);let i=Ha(o,e.version),l=(await gy(i).catch(()=>{}))?.isFile()?i:Ha(i,Yr());if(!(await gy(l).catch(()=>{}))?.isFile()){let u=await(t.fetchResponse??cu)(`${e.tagUrl}/SHA256SUMS`,Bi),p=u.ok?by(await u.text(),e.asset):void 0;if(!p)throw new Error("no published checksum");await au(en(l),s),await WV(en(l));let m=`${l}.part-${process.pid}`;try{await(t.download??ky)(`${e.tagUrl}/${e.asset}`,m,p),await yx(m,493),await ru(m,l)}catch(f){throw await xt(m,{force:!0}).catch(()=>{}),f}}return await(t.activate??bx)(a,l),{link:a,target:l,versionsDir:o}},GV=async e=>{hx(e.target,[Zr,e.link],{stdio:"ignore",timeout:Bi})},VV=async e=>{if(process.platform==="darwin"){let t=hx("/usr/bin/codesign",["--verify","--strict",e],{stdio:"ignore",timeout:Bi});return!t.error&&t.status===0}return!0},KV=async(e,t={})=>{let n=e.managedTools??[];if(n.length>0){let r=await(t.findTools??Co)(n);if(r.length>0){let o=await(t.resolveTarget??Ue)(async()=>e);if(!o||!(await(t.repair??Ft)(r,o.target)).every(Ao))return!1}}return e.persistenceOwner==="tray"?!0:!(e.refreshSchedulerEnabled&&!(await(t.installScheduler??ar)()).ok)},jV=async e=>{let t=await e.install();if(!await(e.smoke??VV)(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},ZV=async(e,t)=>{let n=await iu(e).catch(()=>[]);for(let r of n)t.includes(r)||await xt(Ha(e,r),{force:!0,recursive:!0}).catch(()=>{})},YV=async e=>{let t=await iu(e).catch(()=>[]);for(let n of t)/\.(new|old|rollback)-\d+$/.test(n)&&await xt(Ha(e,n),{force:!0}).catch(()=>{})},JV=async(e,t)=>{let n=async()=>{await xt(e,{recursive:!0,force:!0}).catch(()=>{})};try{return await wy(e,{recursive:!1}),n}catch{}let r=await gx(e).catch(()=>{});if(!(!r||t-r.mtimeMs<_V)){await n();try{return await wy(e,{recursive:!1}),n}catch{return}}},hy=e=>cr(e).state,XV=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}},Va=async(e={})=>{let t=e.now??Date.now,n=ke;if(Rn(on(e.env??process.env)))return{outcome:"container",current:n};let r=e.context??ft(),o=e.root??ee(),a;try{let s=await Ay(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=e.force===!0,l=await(e.load??P)().catch(()=>({})),d=l.autoUpdate!==!1,u=l.fleetUpdatePolicy?.mode??"auto",p=DV({mode:u,initiator:e.initiator??"tick"});if(!p.allow)return{outcome:p.outcome,current:n};!i&&s.link&&!e.checkOnly&&(d||c)&&await UV(o,s.link,e).catch(()=>{});let m=bs(e.platform??process.platform,e.arch??process.arch);if(!m)return{outcome:"platform-unsupported",current:n};if(a=await(e.latestVersion??Cy)().catch(()=>{}),!a)return{outcome:"unavailable",current:n};let f=a;if(!i&&f===n)return{outcome:"current",current:n,latest:f};if(i&&Ga(f,n)<0)return{outcome:"migration-deferred",current:n,latest:f};let h=await XV(hy(o));if((e.respectFailureBackoff===!0||!c)&&h.failedVersion===f&&h.failedAt!==void 0&&t()-h.failedAt<TV)return{outcome:"failed",current:n,latest:f};let w=`${ir}/download/${jr}${f}`,y=d||c||!LV(u)?void 0:await(e.minimumVersion??BV)(w),g={current:n,latest:f,autoUpdate:d,forced:c,minVersion:y},b=i?NV(g):{...wx(g),downgradeBlocked:!1};if(b.downgradeBlocked)return{outcome:"migration-deferred",current:n,latest:f};if(!b.apply)return{outcome:"disabled",current:n,latest:f};if(e.checkOnly)return{outcome:i?"migration-available":"available",current:n,latest:f,mandatory:b.mandatory};o===ee()?await et():await au(o,vy(o,ee()));let k=cr(o),C=await JV(k.lock,t());if(!C)return{outcome:i?"migration-available":"available",current:n,latest:f};let S,E;try{await YV(en(k.launcher));let I=await su(k.versionsDir).catch(()=>{}),_=await su(k.launcher).catch(()=>{}),T=_&&ic(_,I)?_:void 0,W=k.launcher;i&&process.platform==="win32"&&(await gy(W).catch(()=>{}))?.isFile()&&(E=`${W}.rollback-${process.pid}`,await yy(W,E));let Q=()=>(e.installBinary??HV)({root:o,version:f,asset:m,tagUrl:w});i?S=await jV({install:Q,smoke:e.smoke,rollback:async({link:G,target:ne})=>{E?(await yy(E,G),await xt(ds(G),{force:!0}).catch(()=>{})):T&&T!==ne?await bx(G,T):(await xt(G,{force:!0}),await xt(ds(G),{force:!0}).catch(()=>{}))},repoint:async G=>e.repoint?e.repoint(l,G):KV(l),prune:async()=>{await(e.pruneDurable??(G=>cc(G)))(r)}}):S=await Q(),await ZV(S.versionsDir,[f,n]),await(e.refreshHelpersFromInstalled??GV)(S).catch(()=>{}),await xt(hy(o),{force:!0}).catch(()=>{})}finally{E&&await xt(E,{force:!0}).catch(()=>{}),await C()}return{outcome:i?"migrated":"updated",current:n,latest:f,managedPath:S.link,mandatory:b.mandatory}}catch{return a&&await J(hy(o),{failedVersion:a,failedAt:t()},{backup:!1}).catch(()=>{}),{outcome:"failed",current:n,latest:a}}},Ax=async(e={})=>{let t=e.context??ft(),n=await Ay(t,e.root??ee()),r=Bo(e.root??ee());return n.kind==="managed"||(n.kind==="npm"||n.kind==="durable")&&r?{outcome:"current",current:ke,managedPath:n.link??r}:Va({initiator:"human",...e,context:t,allowNpmMigration:!0})},Ro=async(e={})=>{let t=e.context??ft(),n=e.root??ee(),r=await Ay(t,n),o=r.kind==="npm"||r.kind==="durable"?Bo(n):void 0,a=await(e.load??P)().catch(()=>({})),s=r.kind==="managed"||r.kind==="durable"||r.kind==="npm"||!!o,i=s&&!!bs(e.platform??process.platform,e.arch??process.arch),c=r.link??o,l=Rn(on(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,fleetMode:a.fleetUpdatePolicy?.mode??"auto"}};import{z as Cx}from"zod";var zV=5e3,qV=Cx.object({lane:Cx.enum(["subscription","org"]).optional().catch(void 0)}),kx=async(e,t,n={})=>{if(!t?.trim())return;let r=new AbortController,o=setTimeout(()=>r.abort(),n.timeoutMs??zV);try{let a=await(n.fetchResponse??fetch)(`${e.replace(/\/$/,"")}/connect/policy`,{headers:{"x-anyray-api-key":t.trim()},signal:r.signal});if(!a.ok)return;let s=qV.safeParse(await a.json());return s.success?s.data.lane:void 0}catch{return}finally{clearTimeout(o)}},vx=(e,t)=>{if(!e||t.byoUpstream)return{overrodeFlag:!1};let n=t.subscription?"subscription":t.org?"org":void 0;return{lane:e,overrodeFlag:n!=null&&n!==e}};var QV=12e3,eK="anyray-wiring-probe-not-a-real-token",tK={model:"anyray-default",messages:[{role:"user",content:"ping"}],max_tokens:1},Ey={model:"claude-3-5-haiku-20241022",max_tokens:1,messages:[{role:"user",content:"ping"}]},Oo=e=>{let t=e.replace(/\s+/g," ").trim();return t.length>160?`${t.slice(0,157)}\u2026`:t},Ex=e=>{let t=e.toLowerCase();return t.includes("bedrock")||t.includes("unsupported model")},Iy=e=>{let t=e.toLowerCase();return t.includes("client key required")||["missing_key","key_unknown","key_expired","key_revoked"].some(n=>t.includes(`"${n}"`))},Sx=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."],nK=e=>e.includes("no provider key configured for"),xy=e=>{let t=e.toLowerCase();return t.includes("verified_dev_required")||t.includes("verified developers")},Ry=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>"]}),Fi=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."]}),rK=(e,t,n=[])=>e>=200&&e<300?{kind:"ok",detail:"gateway served a completion with the org key \u2014 traffic flows.",remedy:[]}:nK(t)?{kind:"provider-rejected",providerKeyAbsent:!0,detail:`gateway has no server-side provider key for this lane (HTTP ${e}): ${Oo(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")?Sx([" \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."]]}:e===401||e===403?xy(t)?Ry(e):Iy(t)?Fi(e):Ex(t)?{kind:"routed-elsewhere",detail:`gateway routed to the org provider and it rejected the request: ${Oo(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)."]}:{kind:"provider-rejected",detail:`gateway accepted your key but the model provider rejected the request (HTTP ${e}): ${Oo(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).",...Sx([" \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}: ${Oo(t)}`,remedy:[]},oK=(e,t)=>{if(Iy(t))return Fi(e);if(xy(t))return Ry(e);if(Ex(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}: ${Oo(t)}`,remedy:[]}},aK=e=>e.includes("anthropic_messages:")||e.includes("invalid model name passed in model=")||e.includes("to view available models"),sK=(e,t)=>{if(Iy(t))return Fi(e);if(xy(t))return Ry(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:","set it as the gateway upstream (console \u2192 Routing), or for a","caller-supplied host add it to ANYRAY_CUSTOM_HOST_ALLOWLIST."]};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")||aK(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}: ${Oo(t)}`,remedy:[`The probe asks for a fixed model (${Ey.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."]}},Sy=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)}},iK=async(e,t)=>{if(!e.clientKey)return Fi(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?Fi(o.status):{kind:"unknown",detail:`Cursor hook-auth probe got HTTP ${o.status}: ${Oo(a)}`,remedy:o.status===404?["Update the gateway image \u2014 this one predates the content-free /connect/savings key check."]:[]}}finally{clearTimeout(r)}},cK=(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."]}},lK=e=>e.providerKeyAbsent===!0?!1:e.kind==="ok"?!0:null,Ix=async(e,t={})=>{try{return lK(await Ka(e,t))}catch{return null}},Ka=async(e,t={})=>{let n=t.timeoutMs??QV,r=fe(e.metadata);try{if(e.authMode!=="placeholder"&&t.tools?.length===1&&t.tools[0]==="cursor")return await iK(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 Sy(`${e.anthropicBaseUrl}/v1/messages`,l,Ey,n);return sK(d,u)}if(te(e,"anthropic")){let l={Authorization:`Bearer ${eK}`,"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 Sy(`${e.anthropicBaseUrl}/v1/messages`,l,Ey,n);return oK(d,u)}let s={Authorization:`Bearer ${e.clientKey??e.placeholderKey}`};r&&(s["x-anyray-metadata"]=r);let{status:i,bodyText:c}=await Sy(`${e.openaiBaseUrl}/chat/completions`,s,tK,n);return rK(i,c,t.tools??[])}catch(o){return cK(n,o)}};var xx=async(e,t={})=>{let n=await P(),r=!n.enrolledCert&&n.managedEnrollmentDisabled!==!0&&!!(t.managedEnrollment??xo)().enrollmentUrl,o;try{o=Tr(e.gateway,n)}catch(s){return A(K("Anyray connect \u2014 status")),L(`Gateway: ${s.message}`),0}A(K("Anyray connect \u2014 status")),H("Gateway"),A(` Origin: ${qe(o)}`),n.gateway?L(" (cached in ~/.anyray)"):process.env.ANYRAY_GATEWAY_URL?L(" (from $ANYRAY_GATEWAY_URL)"):r?L(" (default \u2014 enrollment is managed by your organization and re-enrolls on the next refresh)"):e.gateway||L(" (default \u2014 not yet connected; run `anyray-connect` to set up)"),H("Identity"),A(` Name: ${n.name??v("(not set)")}`),A(` Team: ${n.team??v("(not set)")}`);let a=on();a&&(H("Environment"),A(` Remote dev context: ${Uo(a)}`),Rn(a)&&L(" No per-user service manager here \u2014 key refresh rides the Claude Code helper and `anyray-connect` runs, not an OS schedule."),L(" VS Code tools configure the remote server variant backing this window.")),n.enrolledCert&&n.clientKey&&(H("Credential renewal"),B(" Direct gateway routing with a proof-backed key heartbeat."),L(" Renewal extends the same key; tool configuration is not rewritten.")),H("Tools");for(let s of pe){if(!(await s.detect()).installed){L(` ${s.title}: not installed`);continue}if(!s.pointsAt){L(` ${s.title}: installed ${v("(status not introspectable)")}`);continue}let c=await s.pointsAt(o);if(c){if(s.id==="cursor"&&(n.authMode==="auto"||n.authMode==="subscription")){B(` ${s.title}: native Cursor subscription; Anyray hooks/MCP active`),A(v(" Claude/Opus model requests remain Cursor-hosted; only supported local Shell/MCP context is optimized by Anyray."));continue}B(` ${s.title}: pointed at Anyray`)}else{let l=null,d=null;if(s.id===Ba&&s.mcpStatus)try{let u=(await s.mcpStatus()).registered,p=await Hd();l=Gd({id:s.id,installed:!0,pointedAt:c,mcpRegistered:u,introspectable:p.authoritative}),d={...p.authoritative?{}:{reason:p.reason},mcpRegistered:u}}catch{l=null,d=null}if((l==="not-routed"||l==="unverifiable")&&d){let u=Vd(l,d);O(` ${s.title}: ${u.headline}`);for(let p of u.detail)A(v(` ${p}`))}else L(` ${s.title}: installed, not pointed at this gateway`)}}return 0};import{existsSync as PK}from"node:fs";import{isAbsolute as DK}from"node:path";import{homedir as LK}from"node:os";import{readFile as dK,stat as uK}from"node:fs/promises";import{homedir as pK,platform as fK}from"node:os";var mK=e=>e.replace(/\\(\d{3})/g,(t,n)=>String.fromCharCode(parseInt(n,8))),hK=e=>e.split(`
|
|
672
|
-
`).map(t=>t.split(" ")[4]).filter(t=>!!t).map(
|
|
673
|
-
`)){let o=new RegExp(`${RK}=(\\w*)`).exec(r);if(!o)continue;let a=r.replace(/\bVSCODE_[A-Z0-9_]*=\S*/g,"");if(/Code Helper|MacOS\/Code|VSCodium|Visual Studio Code|agentHost/i.test(a)&&(n=!0,o[1]==="true"))return"on"}return n?"off":"unknown"},_K=e=>e.mode!=="copilot-seat"?"not-applicable":e.settings.readable?e.settings.supportsAnyray!==!0||e.settings.bridgeEnabled!==!0?"not-configured":e.bridge==="off"?"awaiting-relaunch":"ready":"unknown",du=(e,t)=>{switch(e){case"ready":return t==="on"?"Agents window: Anyray models available (agent host is running with the model bridge on).":"Agents window: configured. No running agent host was found to confirm it, so it applies from the next VS Code start.";case"awaiting-relaunch":return"Agents window: configured, but the agent host running right now started before it. Quit and relaunch VS Code once; a window reload will not do it, because that process outlives every window.";case"not-configured":return`Agents window: not enabled. Re-run anyray-connect --tools copilot, then quit and relaunch VS Code (it sets ${fn} and ${mn}; if you switched either off yourself, that choice is left alone).`;case"unknown":return"Agents window: could not read VS Code settings.json, so its state is unknown. Nothing is reported as missing on that basis.";case"not-applicable":return"Agents window: not applicable on this machine."}},Ox=async(e={})=>{let{installedVariant:t=qo,receiptMode:n=ll,awaitingReload:r=cl,readSettings:o=OK,probeBridge:a=TK,home:s=SK()}=e;try{let i=await t();if(!i)return{state:"not-applicable",bridge:"unknown",detail:du("not-applicable","unknown")};let c=await n(i,s);if(c!=="copilot-seat"){let p=c===void 0&&await r(i,s);return{state:p?"unknown":"not-applicable",bridge:"unknown",detail:p?"Agents window: VS Code has an Anyray configuration staged but not applied yet, so its state is unknown. Restart VS Code to finish.":du("not-applicable","unknown")}}let l=await o($s(i)),d=await a(),u=_K({mode:c,settings:l,bridge:d});return{state:u,bridge:d,detail:du(u,d)}}catch{return{state:"not-applicable",bridge:"unknown",detail:du("not-applicable","unknown")}}};var tn="connect",uu=e=>e.replace(/-/g,"_"),Tx=e=>{let t=[];e.gateway.reachable!==null&&t.push({tool:tn,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:tn,checkId:"enrollment_cert",status:e.enrollment.expired?"expired":o?"problems":e.enrollment.enrolled?"ok":"unenrolled",...o?{errorClass:"cert_expiring"}:{}}),t.push({tool:tn,checkId:"shell_exports",status:e.shell.staleExports.length?"stale":"ok"}),e.refreshScheduler.enabled){let i=e.refreshScheduler.owner==="tray"?e.refreshScheduler.trayHealthy===!0:e.refreshScheduler.installed;t.push({tool:tn,checkId:"refresh_scheduler",status:i?"ok":"missing",...i?{}:{errorClass:e.serviceRemoval?.removed&&e.serviceRemoval.kinds.includes("scheduler")?"unit_deleted":"refresh_scheduler_missing"}})}if(e.identity.sharedIdentityRisk&&t.push({tool:tn,checkId:"identity_distinct",status:"problems",errorClass:e.identity.sharedIdentityRisk}),e.pendingOps.some(i=>!i.watcherAlive)&&t.push({tool:tn,checkId:"pending_op",status:"problems",errorClass:"watcher_dead"}),e.retrieval){let i=uu(e.retrieval.kind);t.push({tool:tn,checkId:"retrieval_loop",status:i,...i==="ok"?{}:{errorClass:`retrieval_${i}`}})}if(e.verify){let i=e.verify.notApplicableSubscription===!0,c=i?"ok":uu(e.verify.kind);t.push({tool:tn,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:tn,checkId:"hook_lane",status:i?"dark":"ok",...i?{errorClass:uu(e.hookLane.reason)}:{}})}t.push({tool:tn,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)if(i.installed){if(i.pointedAt!==null?t.push({tool:i.id,checkId:"routing",status:i.inferenceIntrospectable===!1&&i.pointedAt===!1?"held":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){let c=!i.mcp.registered&&!i.routingHeld;t.push({tool:i.id,checkId:"mcp_registration",status:i.mcp.registered?i.mcp.commandOk===!1?"command_gone":"ok":i.routingHeld?"held":"missing",...c&&i.mcp.reason?{errorClass:uu(i.mcp.reason)}:{}})}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:tn,checkId:"doctor_report",status:e.problems===0?"ok":"problems"}),t};var NK=e=>{let t=LK();return e.startsWith(`${t}/`)?`~${e.slice(t.length)}`:e};function $K(){return ke}var MK="ctx_doctor-probe-synthetic",BK=(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: ${_y(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 FK(e){return e.identity.personalKeySource==="env"?"env":e.identity.personalKeySource==="profile"?"profile":e.enrollment.enrolled?"enrolled-no-key":"none"}function WK(e){return e.ssoLink?"sso":e.enrolledViaToken?"passwordless":"unknown"}function _y(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 _x=e=>Gd({id:e.id,installed:e.installed,pointedAt:e.pointedAt,mcpRegistered:e.mcp?.registered===!0,introspectable:e.inferenceIntrospectable===!0}),Oy=e=>e.pointedAt===!1&&e.tombstoned!==!0&&_x(e)!=="unverifiable",Px=e=>e.registered&&e.command&&DK(e.command)?PK(e.command):null,UK=e=>{switch(e.mcp?.reason){case"ephemeral-runtime":return"this Connect is running from a temporary npx/cache path, so a registration naming it would rot \u2014 install it durably (`curl -fsSL https://app.anyray.ai/connect.sh | sh`) and re-run.";case"no-config":return`${e.title} has not written its config yet \u2014 launch it once, then re-run \`anyray-connect\`.`;case"stale":return"the entry was written by an older Connect \u2014 re-run `anyray-connect` to refresh it.";case"foreign":return"an MCP server named `anyray` that Connect did not write is already there, and it was left untouched. Rename or remove it, then re-run `anyray-connect`.";case"unreadable":return`${e.title}'s config could not be read or parsed \u2014 repair it (or check its permissions), then re-run \`anyray-connect\`.`;case"absent":return"re-run `anyray-connect` to register it.";default:return"re-run `anyray-connect` to register it."}},Ty=e=>(Oy(e)?1:0)+(e.mcp?.commandOk===!1?1:0)+(e.routingOverrides?.length?1:0)+(e.claudeCodeHookPolicy&&e.claudeCodeHookPolicy!=="fine"?1:0),HK=async(e,t,n)=>e===!1&&t.routingExpected&&!await t.routingExpected(n)?null:e,GK=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},Dx=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},VK=(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(vo),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,y])=>({checkId:w,at:y})),p=n(l.flapping)?l.flapping:void 0,m=Array.isArray(p?.checks)?p.checks.filter(w=>typeof w=="string"&&a.has(w)):[],f=p?.reason==="rebroke_same_day"||p?.reason==="repeat_days"?p.reason:void 0,h=p&&r(p.since)&&f&&m.length>0?{since:p.since,reason:f,checks:m}:void 0;(u.length>0||h)&&s.push({tool:c,repaired:u,...h?{flapping:h}:{}})}return s},KK=async(e,t,n,r,o,a,s,i=n,c=Ka,l=!0,d=Go,u=Ro,p=It,m=Na)=>{let f=l?await nu(e):null,h=process.env.ANYRAY_CLIENT_KEY?.trim()?"env":t.clientKey?"profile":null,w=Z=>Z&&Gh(Z)?"machine_default":null,y=t.enrolledCert?.payload,g=y?.expiresAt??t.enrolledCertExpiry??null,k=(await a())?.sso??null,C=WK({ssoLink:k,enrolledViaToken:!!t.enrolledTokenHash}),S=!y&&t.managedEnrollmentDisabled!==!0&&!!s().enrollmentUrl,E=wt(),I=await rb(E),_=I?[]:Uc(Ee({origin:e})),T=[];for(let Z of r){let Le=await Z.detect(),Se=null;if(Le.installed&&Z.mcpStatus)try{let rs=await Z.mcpStatus();Se={...rs,commandOk:Px(rs)}}catch{}let Ye=Le.installed&&Z.id===Ba?await o():void 0,pt=Le.installed&&Z.pointsAt?await Z.pointsAt(e):null,$r=await HK(pt,Z,t.managedTools??[]),zi=pt===!1&&$r===null,Qa=$r===!1&&Z.routingPendingReload?await Z.routingPendingReload().catch(()=>!1):!1,qi=Le.installed?Z.runtimeDiagnostics?await Z.runtimeDiagnostics().catch(()=>({routingOverrides:[]})):{routingOverrides:Z.routingOverrides?await Z.routingOverrides().catch(()=>[]):[]}:{routingOverrides:[]},{routingOverrides:es,claudeCodeHookPolicy:ts}=qi,ns=t.fleetToolPolicy,Po=ns?.enabled.includes(Z.id)?ns.tiers?.[Z.id]??Oa:void 0;T.push({id:Z.id,title:Z.title,installed:Le.installed,...Le.detail?{detail:Le.detail}:{},pointedAt:$r,...zi?{routingHeld:!0}:{},...Qa?{routingPendingReload:!0}:{},...es.length?{routingOverrides:es}:{},...ts===void 0?{}:{claudeCodeHookPolicy:ts},mcp:Se,...Po?{policyTier:Po}:{},...t.revertedTools?.includes(Z.id)?{tombstoned:!0}:{},...Z.id==="cursor"&&(t.authMode==="auto"||t.authMode==="subscription")?{nativeSubscription:!0}:{},...Ye===void 0?{}:{inferenceIntrospectable:Ye.authoritative,...Ye.authoritative?{}:{inferenceUnverifiableReason:Ye.reason}}})}let W=i?await(async()=>{let{kind:Z,detail:Le,remedy:Se}=await c(Ee({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:Z,detail:Le,remedy:Se}})():null,Q=W?.kind==="provider-rejected"&&await GK(t.managedTools??[],r),G=W?{...W,...Q?{notApplicableSubscription:!0}:{}}:null,ne=n?BK(await La({origin:e,apiKey:process.env.ANYRAY_CLIENT_KEY?.trim()||t.clientKey||void 0,metadata:fe({user:t.name,team:t.team})},MK,{probe:!0}),{mode:C,ssoLink:k}):null,z=await p().catch(()=>({})),j=vn(z.hookLane),le=i?await Dx(r):!1,U=le?await(async()=>{let Z=await m().catch(()=>({verdict:"indeterminate",reason:"unreachable"}));return{..._h(Z,{hookRegistered:le,neverInvoked:Oh(j,Date.now())}),lastInvokedAt:Od(j)}})():null,Y=(await dr()).map(Z=>({adapter:Z.adapter,op:Z.op,requestedAt:Z.requestedAt,watcherAlive:pr(Z.watcherPid)})),re=Y.find(Z=>Z.adapter==="cursor"),Qe=re?{op:re.op,requestedAt:re.requestedAt,watcherAlive:re.watcherAlive}:null,Oe=!!t.refreshSchedulerEnabled,ve=await Ho(),ut=await u(),D=t.persistenceOwner==="tray",$=D?await d(t)==="healthy":null,X=await Vw({schedulerEnabled:Oe&&!D,schedulerInstalled:ve,binaryDurable:!tt(Wo()),schedulerInstalledOnce:t.refreshSchedulerInstalledOnce===!0,trayManaged:D}),he=0;f&&!f.reachable&&(he+=1),D?Oe&&!$&&(he+=1):Oe&&!ve&&(he+=1);for(let Z of T)he+=Ty(Z);G&&G.kind!=="ok"&&!G.notApplicableSubscription&&(he+=1),ne&&ne.kind!=="ok"&&(he+=1),U?.verdict==="dark"&&(he+=1),_.length>0&&(he+=1),he+=Y.filter(Z=>!Z.watcherAlive).length;let Gt=await Ox();return{report:{format:1,generatedAt:new Date().toISOString()},connect:{version:$K(),node:process.versions.node,platform:`${process.platform}/${process.arch}`,remoteContext:on(),fileBindMounts:await lu(),selfUpdate:{managed:ut.managed,available:ut.available,autoUpdate:ut.autoUpdate,state:ut.state,fleetMode:ut.fleetMode}},gateway:{origin:e,reachable:f?f.reachable:null,detail:f?f.detail:"not probed (--quick)"},refreshScheduler:{enabled:Oe,installed:ve,owner:D?"tray":"os",...D?{trayHealthy:!!$}:{}},serviceRemoval:X,fleetdPresent:await To(),identity:{user:t.name??null,team:t.team??null,authMode:t.authMode??null,personalKeySource:h,clientKeyExpiresAt:t.clientKeyExpiresAt??null,sharedIdentityRisk:w(t.name)},enrollment:{enrolled:!!y,deploymentId:y?.deploymentId??null,issuedAt:y?.issuedAt??null,expiresAt:g,expired:g?Date.parse(g)<Date.now():null,orgMode:C,ssoLink:k,managedPending:S},shell:{profilePath:E,blockPresent:I,staleExports:_},tools:T,...t.fleetToolPolicy?{fleetPlan:xd(t,t.fleetToolPolicy,!1)}:{},cursorQueue:Qe,pendingOps:Y,ambientRepairs:VK(z,r),verify:G,retrieval:ne,hookLane:U,agentsWindow:Gt,problems:he}},jK=e=>{if(e.serviceRemoval.suspected){if(!e.serviceRemoval.removed){H("Automatic key refresh"),O(" This seat expects the key-refresh schedule, but no unit is installed and"),O(" Anyray has no record of ever installing one here. Re-run `anyray-connect`"),O(" to install it.");for(let t of e.serviceRemoval.missingPaths)A(v(` expected: ${t}`));return}H("Endpoint security"),O(" Anyray installed these background services, but their files are gone from disk \u2014"),O(" endpoint-security software (SentinelOne, CrowdStrike, Defender \u2026) quarantines them"),O(" as suspected persistence. Re-running connect just rewrites them.");for(let t of e.serviceRemoval.missingPaths)A(v(` missing: ${t}`));A(v(" Fix now: `anyray-connect --no-key-refresh` \u2014 installs no background service, points")),A(v(" tools straight at the gateway (your key then needs a periodic re-run).")),A(v(" Fix properly: `anyray-connect doctor --security-review` prints the allow-list your")),A(v(" security team needs; once approved, `anyray-connect --yes` restores auto-refresh."))}},ZK=e=>{if(A(K("Anyray connect \u2014 doctor")),e.connect.remoteContext||e.connect.fileBindMounts.length>0){H("Environment"),e.connect.remoteContext&&(A(` Remote dev context: ${Uo(e.connect.remoteContext)}`),Rn(e.connect.remoteContext)&&A(v(" No per-user service manager here \u2014 key refresh rides the Claude Code helper and `anyray-connect` runs, not an OS schedule.")));for(let c of e.connect.fileBindMounts)A(` Bind-mounted config file: ${NK(c)}`),A(v(" A file mounted into this container cannot be replaced atomically; connect writes it in place (verified). Mount the parent directory instead to restore atomic writes."))}switch(H("CLI updates"),e.connect.selfUpdate.state){case"managed":B(" Managed standalone binary installed; one updater owns this seat."),e.connect.selfUpdate.fleetMode==="off"?A(v(" Your organization manages Connect updates; this machine downloads nothing.")):e.connect.selfUpdate.fleetMode==="directed"?A(v(" Your organization applies Connect updates centrally; an administrator pushes new versions.")):e.connect.selfUpdate.autoUpdate||O(" Automatic CLI updates are off (`anyray-connect update --auto on`).");break;case"will-migrate":O(" This npm runtime will migrate to the managed standalone binary on the next persistent setup change."),A(v(" Run `anyray-connect update` to migrate now."));break;case"platform-unsupported":O(" Self-update is unavailable on this platform because no standalone binary is published."),A(v(" Use `npx anyray-connect@latest` to stay current."));break;case"unmanaged":A(v(" This copy is externally managed; update it with the method that installed it."));break;case"container":A(v(" Self-update is off in this container; updates arrive when it is rebuilt."));break}switch(H("Gateway"),e.gateway.reachable===null?A(v(` Probe skipped (--quick): ${e.gateway.origin} not contacted.`)):e.gateway.reachable?B(` Reachable: ${e.gateway.origin} ${v(`(${e.gateway.detail})`)}`):(R(` Unreachable: ${e.gateway.origin} (${e.gateway.detail})`),A(v(" Fix: start the gateway, or check the URL with `anyray-connect status`."))),e.refreshScheduler.enabled&&(H("Automatic key refresh"),e.refreshScheduler.owner==="tray"?e.refreshScheduler.trayHealthy?B(" Managed by the Anyray Connect app \u2014 it triggers the ~30-min key refresh."):(R(" The Anyray Connect app owns the background services on this machine, but it is missing or no longer passes its signature check."),A(v(" Fix: run `anyray-connect` to restore the background services (it reinstalls the OS schedule and clears the app takeover)."))):e.refreshScheduler.installed?B(" Scheduled \u2014 your gateway key re-mints every ~30 min, so no tool 401s on a stale key mid-session."):(R(" Enabled but the OS schedule is missing \u2014 a long session can still 401 when your key lapses."),e.serviceRemoval.kinds.includes("scheduler")||A(v(" Fix: re-run `anyray-connect` to reinstall it, or `anyray-connect --no-key-refresh` to opt out.")))),jK(e),H("Personal key"),FK(e)){case"env":B(" Personal gateway key present ($ANYRAY_CLIENT_KEY).");break;case"profile":B(" Personal gateway key present (enrolled via connect).");break;case"enrolled-no-key":O(" Enrolled, but no personal key is cached locally right now."),A(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:if(e.enrollment.managedPending){O(" Enrollment is managed by your organization, but this machine holds no local enrollment state."),A(v(" Fix: none needed \u2014 it re-enrolls unattended on the next refresh; run `anyray-connect refresh` to do it now."));break}O(" Enrollment required \u2014 no personal gateway key is available."),A(v(` Fix: ${_y(e.enrollment.orgMode,e.enrollment.ssoLink)}, or set $ANYRAY_CLIENT_KEY to a minted ark_ key.`))}e.enrollment.enrolled&&(e.enrollment.expired?O(` Enrollment cert expired ${v(`(${e.enrollment.expiresAt})`)} \u2014 the next run re-enrolls.`):B(` Enrollment cert valid until ${e.enrollment.expiresAt} ${v(`(deployment ${e.enrollment.deploymentId})`)}`)),e.shell.staleExports.length>0&&(H("Shell"),R(" This terminal still exports Anyray, but the config is gone."),A(v(` Still set here: ${e.shell.staleExports.join(", ")}`)),A(v(` No Anyray block in ${e.shell.profilePath} \u2014 so these came from before a revert.`)),A(v(" Anything you start from this terminal keeps reaching the gateway with")),A(v(" no credential, and fails with 401.")),A(v(` Fix: unset ${e.shell.staleExports.join(" ")}`)),A(v(" Or open a new terminal. In VS Code, quit the app entirely (Cmd+Q) \u2014 it")),A(v(" reuses the environment it captured at launch, so a new terminal")),A(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};H("Claude Code hook policy"),R(` ${mc(c)}.`),A(v(` ${hc(c)}`))}H("Tools");let n=!1,r=!1,o=c=>{for(let l of c.routingOverrides??[])R(` ${c.title}: ${l.problem}.`),A(v(` ${l.fix}`))},a=c=>{c.mcp&&(c.mcp.registered?c.mcp.commandOk===!1?(R(` ${c.title}: retrieval MCP server registered, but its binary is gone (${c.mcp.command}).`),A(v(" Fix: re-run `anyray-connect` to re-register the current binary."))):B(` ${c.title}: retrieval MCP server registered ${v("(anyray_retrieve / anyray_recall)")}`):(O(` ${c.title}: retrieval MCP server not registered \u2014 externalized output can't be pulled back.`),A(v(` Fix: ${UK(c)}`))))};for(let c of e.tools){if(!c.installed){A(v(` ${c.title}: not installed (skipped)`));continue}if(c.pointedAt===null){A(v(` ${c.title}: installed (config not introspectable)`)),a(c);continue}if(c.pointedAt){if(n=!0,c.id==="cursor"&&c.nativeSubscription){B(` ${c.title}: native Cursor subscription; Anyray hooks/MCP active`),A(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}B(` ${c.title}: pointed at ${e.gateway.origin}`),o(c),c.id==="claude-code"&&A(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===Ba&&A(v(` ${ek}`)),c.id==="codex"&&A(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=_x(c);if(l==="not-routed"||l==="unverifiable"){let d=Vd(l,{...c.inferenceUnverifiableReason?{reason:c.inferenceUnverifiableReason}:{},mcpRegistered:c.mcp?.registered===!0});O(` ${c.title}: ${d.headline}`);for(let u of d.detail)A(v(` ${u}`));l==="unverifiable"&&(r=!0)}else c.tombstoned?c.policyTier==="required"?(O(` ${c.title}: reverted locally against admin policy (out of compliance)`),A(v(` Re-enroll with \`anyray-connect --tools ${c.id}\`.`))):c.policyTier==="locked"?O(` ${c.title}: reverted locally but locked by admin policy \u2014 the next reconcile re-applies it`):A(v(` ${c.title}: reverted by you (not managed) \u2014 re-enroll with \`anyray-connect --tools ${c.id}\``)):c.routingPendingReload?(R(` ${c.title}: configured, but ${c.title} is still running the previous Anyray build`),A(v(" Fix: reload the app completely (quit and reopen \u2014 a window reload is not enough), then re-run `anyray-connect`."))):(R(` ${c.title}: installed but not pointed at ${e.gateway.origin}`),A(v(" Fix: run `anyray-connect` to (re)configure it.")))}}let s=(e.repairs?.length??0)>0;if(!n&&!r&&!s&&e.problems===0&&(O(" No tools are pointed at this gateway yet."),A(v(" Fix: run `anyray-connect` to configure your tools."))),e.pendingOps.length>0){H("Queued operations");for(let c of e.pendingOps){let l=mt(c.adapter)?.title??c.adapter;c.watcherAlive?O(` ${l} ${c.op} queued since ${c.requestedAt} \u2014 completes automatically when ${l} quits.`):(R(` ${l} ${c.op} queued since ${c.requestedAt}, but its watcher is not running.`),A(v(` Fix: quit ${l} and re-run \`anyray-connect\` to complete it.`)))}}if(e.ambientRepairs.length>0){H("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=mt(l.tool)?.title??l.tool,u=l.repaired.map(({checkId:m,at:f})=>`${c(m)} ${new Date(f).toISOString().slice(0,10)}`);l.flapping&&u.push(`flapping since ${new Date(l.flapping.since).toISOString().slice(0,10)} (${l.flapping.reason})`);let p=` ${d}: ${u.join("; ")}`;l.flapping?O(p):A(p)}}let i=e.fleetPlan;if(i&&(i.freshIds.length>0||i.tombstonedIds.length>0)){H("Fleet policy");let c=l=>l.map(d=>mt(d)?.title??d).join(", ");i.freshIds.length>0&&A(` Pending enrollment (the next policy sync applies): ${c(i.freshIds)}`),i.tombstonedIds.length>0&&O(` Out of compliance (reverted against required policy): ${c(i.tombstonedIds)}`)}if(e.verify)if(H("Auth probe"),e.verify.notApplicableSubscription)B(" Provider-key verification is not applicable to subscription/native inference lanes.");else if(e.verify.kind==="ok")B(` ${e.verify.detail}`);else{R(` ${e.verify.kind}: ${e.verify.detail}`);for(let c of e.verify.remedy)A(v(` ${c}`))}if(e.retrieval)if(H("Retrieval loop"),e.retrieval.kind==="ok")B(` ${e.retrieval.detail}`);else{R(` ${e.retrieval.kind}: ${e.retrieval.detail}`);for(let c of e.retrieval.remedy)A(v(` ${c}`))}if(e.hookLane){if(H("Hook lane"),e.hookLane.verdict==="live")B(` ${e.hookLane.detail}`);else if(e.hookLane.verdict==="dark"){R(` ${e.hookLane.reason}: ${e.hookLane.detail}`);for(let c of e.hookLane.remedy)A(v(` ${c}`))}else{O(` ${e.hookLane.reason}: ${e.hookLane.detail}`);for(let c of e.hookLane.remedy)A(v(` ${c}`))}e.hookLane.lastInvokedAt!==null&&A(v(` Last hook run: ${new Date(e.hookLane.lastInvokedAt).toISOString()}`))}e.agentsWindow&&e.agentsWindow.state!=="not-applicable"&&e.agentsWindow.state!=="ready"?(H("VS Code Agents window"),O(` ${e.agentsWindow.detail}`)):e.agentsWindow?.state==="ready"&&(H("VS Code Agents window"),B(` ${e.agentsWindow.detail}`)),H("Summary"),e.problems===0?(e.verify?B(" No problems found."):B(" No configuration problems found (no request was sent \u2014 drop `--no-verify` to test one)."),A(v(" Sharing with support? `anyray-connect doctor --json` prints this as a content-free report."))):R(` ${e.problems} problem(s) found \u2014 see fixes above.`)},YK=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}),JK=async(e,t)=>{let n=e.hookLane;if(!n||n.verdict!=="dark"||n.reason!=="key_rejected")return null;if(!Ih(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??Na,o,a=async()=>(o??=await r().catch(()=>({verdict:"indeterminate",reason:"unreachable"})),o),s=await(t.refreshKey??Ut)({force:!0,hookLaneRepair:!0,probeHookLane:a}).catch(()=>"failed"),i=await a(),c=vn((await(t.readRefreshState??It)().catch(()=>({}))).hookLane),l=_h(i,{hookRegistered:await Dx(t.adapters??pe).catch(()=>!1),neverInvoked:Oh(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:Od(c)},note:d}},XK=async(e,t,n={})=>{let r=n.adapters??pe,o=n.resolveTarget??Ue,a=n.applyTools??Ft,s=await JK(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(g=>g.installed&&(Oy(g)||g.mcp?.commandOk===!1||g.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);if(!d)return{entries:l.map(g=>({id:g.id,title:g.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 ${_y(e.enrollment?.orgMode??"unknown",e.enrollment?.ssoLink??null)}, then re-run.`]};let u=new Set(t.managedTools??[]),p=[],m=[...c.notes],f=[];for(let g of l){let b=r.find(k=>k.id===g.id);if(!u.has(g.id)||!b){p.push({id:g.id,title:g.title,status:"skipped-unmanaged"});continue}f.push(b)}p.length>0&&m.push("Drifted tools outside the managed record are never auto-repaired \u2014 run `anyray-connect` once to (re)configure and record them.");let h=await a(f,d.target),w=new Map,y=0;for(let g of h){if(p.push(g),!Ao(g))continue;let b=e.tools.find(T=>T.id===g.id);if(!b)continue;let k=r.find(T=>T.id===g.id),C=b.mcp;if(k?.mcpStatus)try{let T=await k.mcpStatus();C={...T,commandOk:Px(T)}}catch{}let S=Oy(b)?!0:b.pointedAt;if(k?.pointsAt&&b.pointedAt!==null)try{S=await k.pointsAt(e.gateway.origin)}catch{}let E=b.routingOverrides,I=b.claudeCodeHookPolicy;if(k?.runtimeDiagnostics)try{let T=await k.runtimeDiagnostics();E=T.routingOverrides.length?T.routingOverrides:void 0,I=T.claudeCodeHookPolicy}catch{}else if(k?.routingOverrides)try{let T=await k.routingOverrides();E=T.length?T:void 0}catch{}let _={...b,pointedAt:S,mcp:C,...E?{routingOverrides:E}:{},...I===void 0?{}:{claudeCodeHookPolicy:I}};E||delete _.routingOverrides,I===void 0&&delete _.claudeCodeHookPolicy,w.set(g.id,_),y+=Ty(b)-Ty(_)}return{entries:p,remainingProblems:Math.max(0,e.problems-y-i),refreshedTools:w,...s?{hookLane:s.hookLane}:{},notes:m}},zK=e=>{H("Repair"),e.entries.length===0&&B(" Nothing to repair.");for(let t of e.entries)t.status==="configured"||t.status==="reverted"?B(` ${t.title}: re-applied`):t.status==="queued"?B(` ${t.title}: re-apply queued (completes when the app quits)`):t.status.startsWith("skipped-")?A(v(` ${t.title}: ${t.status}`)):R(` ${t.title}: ${t.status}`);for(let t of e.notes)A(v(` ${t}`))},pu=async(e,t={})=>{let n=await P();if(e.securityReview){if(!e.silent){A(K("Anyray connect \u2014 security review"));for(let c of Kw())A(c?` ${c}`:"")}return 0}let r;try{r=Tr(e.gateway,n)}catch(c){return e.silent?1:e.json?(console.log(JSON.stringify({error:c.message})),1):(A(K("Anyray connect \u2014 doctor")),R(` Gateway URL: ${c.message}`),A(v(" Fix: pass a gateway URL, e.g. `anyray-connect doctor http://localhost:8787`.")),1)}if(e.quick&&e.verify)return e.silent||(e.json?console.log(JSON.stringify({error:"--quick cannot be combined with --verify"})):(A(K("Anyray connect \u2014 doctor")),R(" --quick skips the network probes; it cannot be combined with --verify."))),1;let o=!e.noVerify&&!e.quick,a=await KK(r,n,!!e.verify&&!e.quick,t.adapters??pe,t.inferenceIntrospection??Hd,t.fleetBootstrap??xr,t.managedEnrollment??xo,o,t.verifyAuth??Ka,!e.quick,t.checkTray??Go,t.updateStatus??Ro,t.readRefreshState??It,t.probeHookLane??Na),s=e.repair?await XK(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;t.captureReport?.(i),e.silent||(e.json?console.log(JSON.stringify(YK(i),null,2)):(ZK(i),s&&zK(s)));try{e.quick||await(t.reportHealth??hE)(Tx(i),i.connect.version)}catch{}return i.problems===0?0:1};var qK=()=>{let e=[];for(let t of pe){let n=t.skillsDir?.();n&&e.push(n)}return e},Lx=async e=>{let t=await P();A(K("Anyray connect \u2014 sync"));let n;try{n=Tr(e.gateway,t)}catch(s){return R(s.message),1}L(`Gateway: ${n}`);let r=iI(t.clientKey,"anyray-placeholder"),o;try{o=await _a(n,r)}catch(s){return R(`Team policy sync failed: ${vh(s)}`),1}let a=qK();if(a.length===0)QK();else if(o.skills.length===0)L("No team skills published yet \u2014 nothing to sync.");else{let s=await tE(o,a,t.syncedSkills??{});H("Skills");for(let i of s.results)i.written?B(` ${i.name} ${v(`(${i.id}@${i.version})`)} \u2192 ${i.files.length} file(s)`):L(` ${i.name} ${v(`(${i.id}@${i.version})`)} \u2014 up to date`);try{await ce({...t,syncedSkills:s.versions,syncedAt:s.updatedAt??new Date().toISOString()})}catch(i){L(`Could not record sync state: ${i instanceof Error?i.message:String(i)}`)}H("Summary"),A(` ${qe(String(s.changed))} updated, ${s.unchanged} unchanged, across ${a.length} tool dir(s).`)}try{let s=await Pa(o);(s.routingUpdated||s.teamUpdated||s.toolsRequested>0||s.toolsTombstoned.length>0)&&(A(`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&&L(` Locally reverted against admin policy (out of compliance): ${s.toolsTombstoned.join(", ")}. Re-run \`anyray-connect --tools <id>\` to re-enroll.`))}catch(s){L(`Fleet policy reconcile skipped: ${vh(s)}`)}return 0},QK=()=>{L("No installed tool exposes a skills directory \u2014 nothing to sync.")};import{gzip as rj}from"node:zlib";import{promisify as oj}from"node:util";var Dr={maxChars:12e3,headChars:6e3,tailChars:4e3,middleWindows:3},Py=e=>({text:e,trimmed:!1,originalChars:e.length,trimmedChars:e.length,charsRemoved:0,estTokensSaved:0}),Nx=e=>`
|
|
669
|
+
`){y({kind:"ok",values:e.items.filter((I,_)=>a[_]).map(I=>I.value)});return}}}catch(E){g(E)}};r.on("data",C),r.on("end",b),r.on("close",b),r.on("error",k)})}finally{try{u(),o.write("\x1B[?25h")}catch{}try{r.pause?.(),m&&r.setRawMode(p)}catch{}n.close()}};var mx=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],CV=80,Ni=async(e,t,n={})=>{let r=n.output??process.stderr;if(!(!!r.isTTY&&Ia(r,n.env??process.env)))return r.write(`${e}
|
|
670
|
+
`),t();let a=0,s=()=>{r.write(`\r${mx[a++%mx.length]} ${e}`)};s();let i=setInterval(s,CV);i.unref();try{return await t()}finally{try{clearInterval(i),r.write("\r\x1B[2K")}catch{}}};import{createWriteStream as kV}from"node:fs";import{spawnSync as hx}from"node:child_process";import{chmod as yx,copyFile as yy,lstat as gy,mkdir as wy,readdir as iu,realpath as su,rename as ru,rm as xt,stat as gx,symlink as vV,writeFile as SV}from"node:fs/promises";import{createHash as EV}from"node:crypto";import{basename as ou,dirname as en,join as Ha}from"node:path";import{Readable as IV}from"node:stream";import{pipeline as xV}from"node:stream/promises";var RV=new RegExp(`/releases/tag/${jr}([0-9][0-9A-Za-z.-]*)$`),OV=300*1024*1024,Bi=1e4,TV=5*6e4,_V=360*6e4,PV=30*6e4,Ga=(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)};var DV=e=>{if(e)return RV.exec(e.trim())?.[1]},by=(e,t)=>{for(let n of e.split(`
|
|
671
|
+
`)){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()}},LV=e=>e.mode==="off"?{allow:!1,outcome:"fleet-off"}:e.mode==="directed"&&e.initiator==="tick"?{allow:!1,outcome:"fleet-directed"}:{allow:!0},NV=e=>e==="auto",wx=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&&Ga(e.current,e.minVersion)<0&&Ga(e.latest,e.minVersion)>=0;return{apply:t,mandatory:t}},$V=e=>Ga(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}:{...wx(e),downgradeBlocked:!1},MV=(e=process.execPath)=>{let t=zu(e);return t?en(t):en(en(e))},BV=async(e=ft())=>{if(/[\\/]node(\.exe)?$/i.test(e.execPath))return;let t=cr(MV(e.execPath)).launcher;try{if(await su(t)!==await su(e.execPath))return}catch{return}return t},Ay=async(e=ft(),t=ee())=>{let n=await BV(e);if(n)return{kind:"managed",root:en(en(n)),link:n,entryPath:Xn(e)};let r=Xn(e);return Qu(r,t)?{kind:"durable",root:t,entryPath:r}:Ju(r)?{kind:"npm",root:t,entryPath:r}:{kind:"unmanaged",root:t,entryPath:r}},cu=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)}},Cy=async(e=Bi)=>{let t=await cu(`${ir}/latest`,e,{redirect:"manual"});return DV(t.headers.get("location"))},FV=async e=>{try{let t=await cu(`${e}/connect-update.json`,Bi);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}},Mi=class extends Error{status;constructor(t){super(`download failed (${t})`),this.status=t,this.name="DownloadHttpError"}},ky=async(e,t,n)=>{let r=await cu(e,TV);if(!r.ok||!r.body)throw new Mi(r.status);let o=EV("sha256"),a=0;if(await xV(IV.fromWeb(r.body),async function*(s){for await(let i of s){let c=i;if(a+=c.length,a>OV)throw new Error("asset exceeds size cap");o.update(c),yield c}},kV(t,{mode:493})),o.digest("hex")!==n)throw new Error("checksum mismatch")},WV=e=>ou(e)===Yr()?ou(en(e)):ou(e),UV=async e=>{let t=await iu(e).catch(()=>[]);for(let n of t)/\.part-\d+$/.test(n)&&await xt(Ha(e,n),{force:!0}).catch(()=>{})},bx=async(e,t)=>{if(process.platform==="win32"){let r=`${e}.old-${process.pid}`;await xt(r,{force:!0}).catch(()=>{});let o=!1;try{await ru(e,r),o=!0}catch{}try{await yy(t,e),await SV(ds(e),WV(t))}catch(a){throw o&&await ru(r,e).catch(()=>{}),a}await xt(r,{force:!0}).catch(()=>{});return}let n=`${e}.new-${process.pid}`;await xt(n,{force:!0}),await vV(t,n),await ru(n,e)},vy=(e,t)=>e===t||ou(e)===Cp?448:493,$i=async(e,t)=>{let n=(await gx(e).catch(()=>{}))?.mode;n===void 0||(n&t)===t||await yx(e,n&4095|t).catch(()=>{})},au=async(e,t)=>{await wy(e,{recursive:!0,mode:t}),await $i(e,t)},HV=async(e,t,n)=>{let r=vy(e,ee());if(r!==448){let o=cr(e),a=o.versionsDir;await $i(e,r),await $i(en(o.launcher),r),await $i(a,r);for(let s of await iu(a).catch(()=>[]))await $i(Ha(a,s),r)}await(n.refreshDesktopHelpers??Jd)(t)},GV=async(e,t={})=>{let n=cr(e.root),r=en(n.launcher),{versionsDir:o,launcher:a}=n,s=vy(e.root,(t.privateRoot??ee)());await au(r,s),await au(o,s);let i=Ha(o,e.version),l=(await gy(i).catch(()=>{}))?.isFile()?i:Ha(i,Yr());if(!(await gy(l).catch(()=>{}))?.isFile()){let u=await(t.fetchResponse??cu)(`${e.tagUrl}/SHA256SUMS`,Bi),p=u.ok?by(await u.text(),e.asset):void 0;if(!p)throw new Error("no published checksum");await au(en(l),s),await UV(en(l));let m=`${l}.part-${process.pid}`;try{await(t.download??ky)(`${e.tagUrl}/${e.asset}`,m,p),await yx(m,493),await ru(m,l)}catch(f){throw await xt(m,{force:!0}).catch(()=>{}),f}}return await(t.activate??bx)(a,l),{link:a,target:l,versionsDir:o}},VV=async e=>{hx(e.target,[Zr,e.link],{stdio:"ignore",timeout:Bi})},KV=async e=>{if(process.platform==="darwin"){let t=hx("/usr/bin/codesign",["--verify","--strict",e],{stdio:"ignore",timeout:Bi});return!t.error&&t.status===0}return!0},jV=async(e,t={})=>{let n=e.managedTools??[];if(n.length>0){let r=await(t.findTools??Co)(n);if(r.length>0){let o=await(t.resolveTarget??Ue)(async()=>e);if(!o||!(await(t.repair??Ft)(r,o.target)).every(Ao))return!1}}return e.persistenceOwner==="tray"?!0:!(e.refreshSchedulerEnabled&&!(await(t.installScheduler??ar)()).ok)},ZV=async e=>{let t=await e.install();if(!await(e.smoke??KV)(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},YV=async(e,t)=>{let n=await iu(e).catch(()=>[]);for(let r of n)t.includes(r)||await xt(Ha(e,r),{force:!0,recursive:!0}).catch(()=>{})},JV=async e=>{let t=await iu(e).catch(()=>[]);for(let n of t)/\.(new|old|rollback)-\d+$/.test(n)&&await xt(Ha(e,n),{force:!0}).catch(()=>{})},XV=async(e,t)=>{let n=async()=>{await xt(e,{recursive:!0,force:!0}).catch(()=>{})};try{return await wy(e,{recursive:!1}),n}catch{}let r=await gx(e).catch(()=>{});if(!(!r||t-r.mtimeMs<PV)){await n();try{return await wy(e,{recursive:!1}),n}catch{return}}},hy=e=>cr(e).state,zV=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}},Va=async(e={})=>{let t=e.now??Date.now,n=ke;if(Rn(on(e.env??process.env)))return{outcome:"container",current:n};let r=e.context??ft(),o=e.root??ee(),a;try{let s=await Ay(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=e.force===!0,l=await(e.load??P)().catch(()=>({})),d=l.autoUpdate!==!1,u=l.fleetUpdatePolicy?.mode??"auto",p=LV({mode:u,initiator:e.initiator??"tick"});if(!p.allow)return{outcome:p.outcome,current:n};!i&&s.link&&!e.checkOnly&&(d||c)&&await HV(o,s.link,e).catch(()=>{});let m=bs(e.platform??process.platform,e.arch??process.arch);if(!m)return{outcome:"platform-unsupported",current:n};if(a=await(e.latestVersion??Cy)().catch(()=>{}),!a)return{outcome:"unavailable",current:n};let f=a;if(!i&&f===n)return{outcome:"current",current:n,latest:f};if(i&&Ga(f,n)<0)return{outcome:"migration-deferred",current:n,latest:f};let h=await zV(hy(o));if((e.respectFailureBackoff===!0||!c)&&h.failedVersion===f&&h.failedAt!==void 0&&t()-h.failedAt<_V)return{outcome:"failed",current:n,latest:f};let w=`${ir}/download/${jr}${f}`,y=d||c||!NV(u)?void 0:await(e.minimumVersion??FV)(w),g={current:n,latest:f,autoUpdate:d,forced:c,minVersion:y},b=i?$V(g):{...wx(g),downgradeBlocked:!1};if(b.downgradeBlocked)return{outcome:"migration-deferred",current:n,latest:f};if(!b.apply)return{outcome:"disabled",current:n,latest:f};if(e.checkOnly)return{outcome:i?"migration-available":"available",current:n,latest:f,mandatory:b.mandatory};o===ee()?await et():await au(o,vy(o,ee()));let k=cr(o),C=await XV(k.lock,t());if(!C)return{outcome:i?"migration-available":"available",current:n,latest:f};let S,E;try{await JV(en(k.launcher));let I=await su(k.versionsDir).catch(()=>{}),_=await su(k.launcher).catch(()=>{}),T=_&&ic(_,I)?_:void 0,W=k.launcher;i&&process.platform==="win32"&&(await gy(W).catch(()=>{}))?.isFile()&&(E=`${W}.rollback-${process.pid}`,await yy(W,E));let Q=()=>(e.installBinary??GV)({root:o,version:f,asset:m,tagUrl:w});i?S=await ZV({install:Q,smoke:e.smoke,rollback:async({link:G,target:ne})=>{E?(await yy(E,G),await xt(ds(G),{force:!0}).catch(()=>{})):T&&T!==ne?await bx(G,T):(await xt(G,{force:!0}),await xt(ds(G),{force:!0}).catch(()=>{}))},repoint:async G=>e.repoint?e.repoint(l,G):jV(l),prune:async()=>{await(e.pruneDurable??(G=>cc(G)))(r)}}):S=await Q(),await YV(S.versionsDir,[f,n]),await(e.refreshHelpersFromInstalled??VV)(S).catch(()=>{}),await xt(hy(o),{force:!0}).catch(()=>{})}finally{E&&await xt(E,{force:!0}).catch(()=>{}),await C()}return{outcome:i?"migrated":"updated",current:n,latest:f,managedPath:S.link,mandatory:b.mandatory}}catch{return a&&await J(hy(o),{failedVersion:a,failedAt:t()},{backup:!1}).catch(()=>{}),{outcome:"failed",current:n,latest:a}}},Ax=async(e={})=>{let t=e.context??ft(),n=await Ay(t,e.root??ee()),r=Bo(e.root??ee());return n.kind==="managed"||(n.kind==="npm"||n.kind==="durable")&&r?{outcome:"current",current:ke,managedPath:n.link??r}:Va({initiator:"human",...e,context:t,allowNpmMigration:!0})},Ro=async(e={})=>{let t=e.context??ft(),n=e.root??ee(),r=await Ay(t,n),o=r.kind==="npm"||r.kind==="durable"?Bo(n):void 0,a=await(e.load??P)().catch(()=>({})),s=r.kind==="managed"||r.kind==="durable"||r.kind==="npm"||!!o,i=s&&!!bs(e.platform??process.platform,e.arch??process.arch),c=r.link??o,l=Rn(on(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,fleetMode:a.fleetUpdatePolicy?.mode??"auto"}};import{z as Cx}from"zod";var qV=5e3,QV=Cx.object({lane:Cx.enum(["subscription","org"]).optional().catch(void 0)}),kx=async(e,t,n={})=>{if(!t?.trim())return;let r=new AbortController,o=setTimeout(()=>r.abort(),n.timeoutMs??qV);try{let a=await(n.fetchResponse??fetch)(`${e.replace(/\/$/,"")}/connect/policy`,{headers:{"x-anyray-api-key":t.trim()},signal:r.signal});if(!a.ok)return;let s=QV.safeParse(await a.json());return s.success?s.data.lane:void 0}catch{return}finally{clearTimeout(o)}},vx=(e,t)=>{if(!e||t.byoUpstream)return{overrodeFlag:!1};let n=t.subscription?"subscription":t.org?"org":void 0;return{lane:e,overrodeFlag:n!=null&&n!==e}};var eK=12e3,tK="anyray-wiring-probe-not-a-real-token",nK={model:"anyray-default",messages:[{role:"user",content:"ping"}],max_tokens:1},Ey={model:"claude-3-5-haiku-20241022",max_tokens:1,messages:[{role:"user",content:"ping"}]},Oo=e=>{let t=e.replace(/\s+/g," ").trim();return t.length>160?`${t.slice(0,157)}\u2026`:t},Ex=e=>{let t=e.toLowerCase();return t.includes("bedrock")||t.includes("unsupported model")},Iy=e=>{let t=e.toLowerCase();return t.includes("client key required")||["missing_key","key_unknown","key_expired","key_revoked"].some(n=>t.includes(`"${n}"`))},Sx=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."],rK=e=>e.includes("no provider key configured for"),xy=e=>{let t=e.toLowerCase();return t.includes("verified_dev_required")||t.includes("verified developers")},Ry=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>"]}),Fi=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."]}),oK=(e,t,n=[])=>e>=200&&e<300?{kind:"ok",detail:"gateway served a completion with the org key \u2014 traffic flows.",remedy:[]}:rK(t)?{kind:"provider-rejected",providerKeyAbsent:!0,detail:`gateway has no server-side provider key for this lane (HTTP ${e}): ${Oo(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")?Sx([" \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."]]}:e===401||e===403?xy(t)?Ry(e):Iy(t)?Fi(e):Ex(t)?{kind:"routed-elsewhere",detail:`gateway routed to the org provider and it rejected the request: ${Oo(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)."]}:{kind:"provider-rejected",detail:`gateway accepted your key but the model provider rejected the request (HTTP ${e}): ${Oo(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).",...Sx([" \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}: ${Oo(t)}`,remedy:[]},aK=(e,t)=>{if(Iy(t))return Fi(e);if(xy(t))return Ry(e);if(Ex(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}: ${Oo(t)}`,remedy:[]}},sK=e=>e.includes("anthropic_messages:")||e.includes("invalid model name passed in model=")||e.includes("to view available models"),iK=(e,t)=>{if(Iy(t))return Fi(e);if(xy(t))return Ry(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:","set it as the gateway upstream (console \u2192 Routing), or for a","caller-supplied host add it to ANYRAY_CUSTOM_HOST_ALLOWLIST."]};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")||sK(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}: ${Oo(t)}`,remedy:[`The probe asks for a fixed model (${Ey.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."]}},Sy=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)}},cK=async(e,t)=>{if(!e.clientKey)return Fi(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?Fi(o.status):{kind:"unknown",detail:`Cursor hook-auth probe got HTTP ${o.status}: ${Oo(a)}`,remedy:o.status===404?["Update the gateway image \u2014 this one predates the content-free /connect/savings key check."]:[]}}finally{clearTimeout(r)}},lK=(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."]}},dK=e=>e.providerKeyAbsent===!0?!1:e.kind==="ok"?!0:null,Ix=async(e,t={})=>{try{return dK(await Ka(e,t))}catch{return null}},Ka=async(e,t={})=>{let n=t.timeoutMs??eK,r=fe(e.metadata);try{if(e.authMode!=="placeholder"&&t.tools?.length===1&&t.tools[0]==="cursor")return await cK(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 Sy(`${e.anthropicBaseUrl}/v1/messages`,l,Ey,n);return iK(d,u)}if(te(e,"anthropic")){let l={Authorization:`Bearer ${tK}`,"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 Sy(`${e.anthropicBaseUrl}/v1/messages`,l,Ey,n);return aK(d,u)}let s={Authorization:`Bearer ${e.clientKey??e.placeholderKey}`};r&&(s["x-anyray-metadata"]=r);let{status:i,bodyText:c}=await Sy(`${e.openaiBaseUrl}/chat/completions`,s,nK,n);return oK(i,c,t.tools??[])}catch(o){return lK(n,o)}};var xx=async(e,t={})=>{let n=await P(),r=!n.enrolledCert&&n.managedEnrollmentDisabled!==!0&&!!(t.managedEnrollment??xo)().enrollmentUrl,o;try{o=Tr(e.gateway,n)}catch(s){return A(K("Anyray connect \u2014 status")),L(`Gateway: ${s.message}`),0}A(K("Anyray connect \u2014 status")),H("Gateway"),A(` Origin: ${qe(o)}`),n.gateway?L(" (cached in ~/.anyray)"):process.env.ANYRAY_GATEWAY_URL?L(" (from $ANYRAY_GATEWAY_URL)"):r?L(" (default \u2014 enrollment is managed by your organization and re-enrolls on the next refresh)"):e.gateway||L(" (default \u2014 not yet connected; run `anyray-connect` to set up)"),H("Identity"),A(` Name: ${n.name??v("(not set)")}`),A(` Team: ${n.team??v("(not set)")}`);let a=on();a&&(H("Environment"),A(` Remote dev context: ${Uo(a)}`),Rn(a)&&L(" No per-user service manager here \u2014 key refresh rides the Claude Code helper and `anyray-connect` runs, not an OS schedule."),L(" VS Code tools configure the remote server variant backing this window.")),n.enrolledCert&&n.clientKey&&(H("Credential renewal"),B(" Direct gateway routing with a proof-backed key heartbeat."),L(" Renewal extends the same key; tool configuration is not rewritten.")),H("Tools");for(let s of pe){if(!(await s.detect()).installed){L(` ${s.title}: not installed`);continue}if(!s.pointsAt){L(` ${s.title}: installed ${v("(status not introspectable)")}`);continue}let c=await s.pointsAt(o);if(c){if(s.id==="cursor"&&(n.authMode==="auto"||n.authMode==="subscription")){B(` ${s.title}: native Cursor subscription; Anyray hooks/MCP active`),A(v(" Claude/Opus model requests remain Cursor-hosted; only supported local Shell/MCP context is optimized by Anyray."));continue}B(` ${s.title}: pointed at Anyray`)}else{let l=null,d=null;if(s.id===Ba&&s.mcpStatus)try{let u=(await s.mcpStatus()).registered,p=await Hd();l=Gd({id:s.id,installed:!0,pointedAt:c,mcpRegistered:u,introspectable:p.authoritative}),d={...p.authoritative?{}:{reason:p.reason},mcpRegistered:u}}catch{l=null,d=null}if((l==="not-routed"||l==="unverifiable")&&d){let u=Vd(l,d);O(` ${s.title}: ${u.headline}`);for(let p of u.detail)A(v(` ${p}`))}else L(` ${s.title}: installed, not pointed at this gateway`)}}return 0};import{existsSync as DK}from"node:fs";import{isAbsolute as LK}from"node:path";import{homedir as NK}from"node:os";import{readFile as uK,stat as pK}from"node:fs/promises";import{homedir as fK,platform as mK}from"node:os";var hK=e=>e.replace(/\\(\d{3})/g,(t,n)=>String.fromCharCode(parseInt(n,8))),yK=e=>e.split(`
|
|
672
|
+
`).map(t=>t.split(" ")[4]).filter(t=>!!t).map(hK),gK=async(e,t,n=async r=>(await pK(r)).isFile())=>{let r=t.endsWith("/")?t:`${t}/`,o=[];for(let a of e)a.startsWith(r)&&await n(a).catch(()=>!1)&&o.push(a);return o},lu=async()=>{if(mK()!=="linux")return[];try{let e=await uK("/proc/self/mountinfo","utf-8");return await gK(yK(e),fK())}catch{return[]}};import{access as wK}from"node:fs/promises";import{constants as bK}from"node:fs";import{platform as AK}from"node:os";var CK=async e=>{try{return await wK(e,bK.F_OK),!0}catch{return!1}},kK=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"]:[],To=async(e={})=>{let t=e.os??AK(),n=e.exists??CK;for(let r of kK(t))if(await n(r))return!0;return!1};import{execFile as vK}from"node:child_process";import{readFile as SK}from"node:fs/promises";import{homedir as EK,platform as IK}from"node:os";import{promisify as xK}from"node:util";var RK=xK(vK),OK="VSCODE_AGENT_HOST_BYOK_MODELS_ENABLED",Rx=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),TK=async e=>{let t;try{t=await SK(e,"utf-8")}catch(n){return n?.code==="ENOENT"?{readable:!0}:{readable:!1}}try{if(t.trim()==="")return{readable:!0};let n=bt(t);if(!Rx(n))return{readable:!1};let r=n[fn],o=n[mn];return{readable:!0,supportsAnyray:Rx(r)?r[q]===!0:void 0,bridgeEnabled:typeof o=="boolean"?o:void 0}}catch{return{readable:!1}}},_K=async(e=async()=>(await RK("ps",["ewwx"],{maxBuffer:64*1024*1024})).stdout)=>{if(IK()==="win32")return"unknown";let t;try{t=await e()}catch{return"unknown"}let n=!1;for(let r of t.split(`
|
|
673
|
+
`)){let o=new RegExp(`${OK}=(\\w*)`).exec(r);if(!o)continue;let a=r.replace(/\bVSCODE_[A-Z0-9_]*=\S*/g,"");if(/Code Helper|MacOS\/Code|VSCodium|Visual Studio Code|agentHost/i.test(a)&&(n=!0,o[1]==="true"))return"on"}return n?"off":"unknown"},PK=e=>e.mode!=="copilot-seat"?"not-applicable":e.settings.readable?e.settings.supportsAnyray!==!0||e.settings.bridgeEnabled!==!0?"not-configured":e.bridge==="off"?"awaiting-relaunch":"ready":"unknown",du=(e,t)=>{switch(e){case"ready":return t==="on"?"Agents window: Anyray models available (agent host is running with the model bridge on).":"Agents window: configured. No running agent host was found to confirm it, so it applies from the next VS Code start.";case"awaiting-relaunch":return"Agents window: configured, but the agent host running right now started before it. Quit and relaunch VS Code once; a window reload will not do it, because that process outlives every window.";case"not-configured":return`Agents window: not enabled. Re-run anyray-connect --tools copilot, then quit and relaunch VS Code (it sets ${fn} and ${mn}; if you switched either off yourself, that choice is left alone).`;case"unknown":return"Agents window: could not read VS Code settings.json, so its state is unknown. Nothing is reported as missing on that basis.";case"not-applicable":return"Agents window: not applicable on this machine."}},Ox=async(e={})=>{let{installedVariant:t=qo,receiptMode:n=ll,awaitingReload:r=cl,readSettings:o=TK,probeBridge:a=_K,home:s=EK()}=e;try{let i=await t();if(!i)return{state:"not-applicable",bridge:"unknown",detail:du("not-applicable","unknown")};let c=await n(i,s);if(c!=="copilot-seat"){let p=c===void 0&&await r(i,s);return{state:p?"unknown":"not-applicable",bridge:"unknown",detail:p?"Agents window: VS Code has an Anyray configuration staged but not applied yet, so its state is unknown. Restart VS Code to finish.":du("not-applicable","unknown")}}let l=await o($s(i)),d=await a(),u=PK({mode:c,settings:l,bridge:d});return{state:u,bridge:d,detail:du(u,d)}}catch{return{state:"not-applicable",bridge:"unknown",detail:du("not-applicable","unknown")}}};var tn="connect",uu=e=>e.replace(/-/g,"_"),Tx=e=>{let t=[];e.gateway.reachable!==null&&t.push({tool:tn,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:tn,checkId:"enrollment_cert",status:e.enrollment.expired?"expired":o?"problems":e.enrollment.enrolled?"ok":"unenrolled",...o?{errorClass:"cert_expiring"}:{}}),t.push({tool:tn,checkId:"shell_exports",status:e.shell.staleExports.length?"stale":"ok"}),e.refreshScheduler.enabled){let i=e.refreshScheduler.owner==="tray"?e.refreshScheduler.trayHealthy===!0:e.refreshScheduler.installed;t.push({tool:tn,checkId:"refresh_scheduler",status:i?"ok":"missing",...i?{}:{errorClass:e.serviceRemoval?.removed&&e.serviceRemoval.kinds.includes("scheduler")?"unit_deleted":"refresh_scheduler_missing"}})}if(e.identity.sharedIdentityRisk&&t.push({tool:tn,checkId:"identity_distinct",status:"problems",errorClass:e.identity.sharedIdentityRisk}),e.pendingOps.some(i=>!i.watcherAlive)&&t.push({tool:tn,checkId:"pending_op",status:"problems",errorClass:"watcher_dead"}),e.retrieval){let i=uu(e.retrieval.kind);t.push({tool:tn,checkId:"retrieval_loop",status:i,...i==="ok"?{}:{errorClass:`retrieval_${i}`}})}if(e.verify){let i=e.verify.notApplicableSubscription===!0,c=i?"ok":uu(e.verify.kind);t.push({tool:tn,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:tn,checkId:"hook_lane",status:i?"dark":"ok",...i?{errorClass:uu(e.hookLane.reason)}:{}})}t.push({tool:tn,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)if(i.installed){if(i.pointedAt!==null?t.push({tool:i.id,checkId:"routing",status:i.inferenceIntrospectable===!1&&i.pointedAt===!1?"held":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){let c=!i.mcp.registered&&!i.routingHeld;t.push({tool:i.id,checkId:"mcp_registration",status:i.mcp.registered?i.mcp.commandOk===!1?"command_gone":"ok":i.routingHeld?"held":"missing",...c&&i.mcp.reason?{errorClass:uu(i.mcp.reason)}:{}})}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:tn,checkId:"doctor_report",status:e.problems===0?"ok":"problems"}),t};var $K=e=>{let t=NK();return e.startsWith(`${t}/`)?`~${e.slice(t.length)}`:e};function MK(){return ke}var BK="ctx_doctor-probe-synthetic",FK=(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: ${_y(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 WK(e){return e.identity.personalKeySource==="env"?"env":e.identity.personalKeySource==="profile"?"profile":e.enrollment.enrolled?"enrolled-no-key":"none"}function UK(e){return e.ssoLink?"sso":e.enrolledViaToken?"passwordless":"unknown"}function _y(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 _x=e=>Gd({id:e.id,installed:e.installed,pointedAt:e.pointedAt,mcpRegistered:e.mcp?.registered===!0,introspectable:e.inferenceIntrospectable===!0}),Oy=e=>e.pointedAt===!1&&e.tombstoned!==!0&&_x(e)!=="unverifiable",Px=e=>e.registered&&e.command&&LK(e.command)?DK(e.command):null,HK=e=>{switch(e.mcp?.reason){case"ephemeral-runtime":return"this Connect is running from a temporary npx/cache path, so a registration naming it would rot \u2014 install it durably (`curl -fsSL https://app.anyray.ai/connect.sh | sh`) and re-run.";case"no-config":return`${e.title} has not written its config yet \u2014 launch it once, then re-run \`anyray-connect\`.`;case"stale":return"the entry was written by an older Connect \u2014 re-run `anyray-connect` to refresh it.";case"foreign":return"an MCP server named `anyray` that Connect did not write is already there, and it was left untouched. Rename or remove it, then re-run `anyray-connect`.";case"unreadable":return`${e.title}'s config could not be read or parsed \u2014 repair it (or check its permissions), then re-run \`anyray-connect\`.`;case"absent":return"re-run `anyray-connect` to register it.";default:return"re-run `anyray-connect` to register it."}},Ty=e=>(Oy(e)?1:0)+(e.mcp?.commandOk===!1?1:0)+(e.routingOverrides?.length?1:0)+(e.claudeCodeHookPolicy&&e.claudeCodeHookPolicy!=="fine"?1:0),GK=async(e,t,n)=>e===!1&&t.routingExpected&&!await t.routingExpected(n)?null:e,VK=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},Dx=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},KK=(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(vo),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,y])=>({checkId:w,at:y})),p=n(l.flapping)?l.flapping:void 0,m=Array.isArray(p?.checks)?p.checks.filter(w=>typeof w=="string"&&a.has(w)):[],f=p?.reason==="rebroke_same_day"||p?.reason==="repeat_days"?p.reason:void 0,h=p&&r(p.since)&&f&&m.length>0?{since:p.since,reason:f,checks:m}:void 0;(u.length>0||h)&&s.push({tool:c,repaired:u,...h?{flapping:h}:{}})}return s},jK=async(e,t,n,r,o,a,s,i=n,c=Ka,l=!0,d=Go,u=Ro,p=It,m=Na)=>{let f=l?await nu(e):null,h=process.env.ANYRAY_CLIENT_KEY?.trim()?"env":t.clientKey?"profile":null,w=Z=>Z&&Gh(Z)?"machine_default":null,y=t.enrolledCert?.payload,g=y?.expiresAt??t.enrolledCertExpiry??null,k=(await a())?.sso??null,C=UK({ssoLink:k,enrolledViaToken:!!t.enrolledTokenHash}),S=!y&&t.managedEnrollmentDisabled!==!0&&!!s().enrollmentUrl,E=wt(),I=await rb(E),_=I?[]:Uc(Ee({origin:e})),T=[];for(let Z of r){let Le=await Z.detect(),Se=null;if(Le.installed&&Z.mcpStatus)try{let rs=await Z.mcpStatus();Se={...rs,commandOk:Px(rs)}}catch{}let Ye=Le.installed&&Z.id===Ba?await o():void 0,pt=Le.installed&&Z.pointsAt?await Z.pointsAt(e):null,$r=await GK(pt,Z,t.managedTools??[]),zi=pt===!1&&$r===null,Qa=$r===!1&&Z.routingPendingReload?await Z.routingPendingReload().catch(()=>!1):!1,qi=Le.installed?Z.runtimeDiagnostics?await Z.runtimeDiagnostics().catch(()=>({routingOverrides:[]})):{routingOverrides:Z.routingOverrides?await Z.routingOverrides().catch(()=>[]):[]}:{routingOverrides:[]},{routingOverrides:es,claudeCodeHookPolicy:ts}=qi,ns=t.fleetToolPolicy,Po=ns?.enabled.includes(Z.id)?ns.tiers?.[Z.id]??Oa:void 0;T.push({id:Z.id,title:Z.title,installed:Le.installed,...Le.detail?{detail:Le.detail}:{},pointedAt:$r,...zi?{routingHeld:!0}:{},...Qa?{routingPendingReload:!0}:{},...es.length?{routingOverrides:es}:{},...ts===void 0?{}:{claudeCodeHookPolicy:ts},mcp:Se,...Po?{policyTier:Po}:{},...t.revertedTools?.includes(Z.id)?{tombstoned:!0}:{},...Z.id==="cursor"&&(t.authMode==="auto"||t.authMode==="subscription")?{nativeSubscription:!0}:{},...Ye===void 0?{}:{inferenceIntrospectable:Ye.authoritative,...Ye.authoritative?{}:{inferenceUnverifiableReason:Ye.reason}}})}let W=i?await(async()=>{let{kind:Z,detail:Le,remedy:Se}=await c(Ee({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:Z,detail:Le,remedy:Se}})():null,Q=W?.kind==="provider-rejected"&&await VK(t.managedTools??[],r),G=W?{...W,...Q?{notApplicableSubscription:!0}:{}}:null,ne=n?FK(await La({origin:e,apiKey:process.env.ANYRAY_CLIENT_KEY?.trim()||t.clientKey||void 0,metadata:fe({user:t.name,team:t.team})},BK,{probe:!0}),{mode:C,ssoLink:k}):null,z=await p().catch(()=>({})),j=vn(z.hookLane),le=i?await Dx(r):!1,U=le?await(async()=>{let Z=await m().catch(()=>({verdict:"indeterminate",reason:"unreachable"}));return{..._h(Z,{hookRegistered:le,neverInvoked:Oh(j,Date.now())}),lastInvokedAt:Od(j)}})():null,Y=(await dr()).map(Z=>({adapter:Z.adapter,op:Z.op,requestedAt:Z.requestedAt,watcherAlive:pr(Z.watcherPid)})),re=Y.find(Z=>Z.adapter==="cursor"),Qe=re?{op:re.op,requestedAt:re.requestedAt,watcherAlive:re.watcherAlive}:null,Oe=!!t.refreshSchedulerEnabled,ve=await Ho(),ut=await u(),D=t.persistenceOwner==="tray",$=D?await d(t)==="healthy":null,X=await Vw({schedulerEnabled:Oe&&!D,schedulerInstalled:ve,binaryDurable:!tt(Wo()),schedulerInstalledOnce:t.refreshSchedulerInstalledOnce===!0,trayManaged:D}),he=0;f&&!f.reachable&&(he+=1),D?Oe&&!$&&(he+=1):Oe&&!ve&&(he+=1);for(let Z of T)he+=Ty(Z);G&&G.kind!=="ok"&&!G.notApplicableSubscription&&(he+=1),ne&&ne.kind!=="ok"&&(he+=1),U?.verdict==="dark"&&(he+=1),_.length>0&&(he+=1),he+=Y.filter(Z=>!Z.watcherAlive).length;let Gt=await Ox();return{report:{format:1,generatedAt:new Date().toISOString()},connect:{version:MK(),node:process.versions.node,platform:`${process.platform}/${process.arch}`,remoteContext:on(),fileBindMounts:await lu(),selfUpdate:{managed:ut.managed,available:ut.available,autoUpdate:ut.autoUpdate,state:ut.state,fleetMode:ut.fleetMode}},gateway:{origin:e,reachable:f?f.reachable:null,detail:f?f.detail:"not probed (--quick)"},refreshScheduler:{enabled:Oe,installed:ve,owner:D?"tray":"os",...D?{trayHealthy:!!$}:{}},serviceRemoval:X,fleetdPresent:await To(),identity:{user:t.name??null,team:t.team??null,authMode:t.authMode??null,personalKeySource:h,clientKeyExpiresAt:t.clientKeyExpiresAt??null,sharedIdentityRisk:w(t.name)},enrollment:{enrolled:!!y,deploymentId:y?.deploymentId??null,issuedAt:y?.issuedAt??null,expiresAt:g,expired:g?Date.parse(g)<Date.now():null,orgMode:C,ssoLink:k,managedPending:S},shell:{profilePath:E,blockPresent:I,staleExports:_},tools:T,...t.fleetToolPolicy?{fleetPlan:xd(t,t.fleetToolPolicy,!1)}:{},cursorQueue:Qe,pendingOps:Y,ambientRepairs:KK(z,r),verify:G,retrieval:ne,hookLane:U,agentsWindow:Gt,problems:he}},ZK=e=>{if(e.serviceRemoval.suspected){if(!e.serviceRemoval.removed){H("Automatic key refresh"),O(" This seat expects the key-refresh schedule, but no unit is installed and"),O(" Anyray has no record of ever installing one here. Re-run `anyray-connect`"),O(" to install it.");for(let t of e.serviceRemoval.missingPaths)A(v(` expected: ${t}`));return}H("Endpoint security"),O(" Anyray installed these background services, but their files are gone from disk \u2014"),O(" endpoint-security software (SentinelOne, CrowdStrike, Defender \u2026) quarantines them"),O(" as suspected persistence. Re-running connect just rewrites them.");for(let t of e.serviceRemoval.missingPaths)A(v(` missing: ${t}`));A(v(" Fix now: `anyray-connect --no-key-refresh` \u2014 installs no background service, points")),A(v(" tools straight at the gateway (your key then needs a periodic re-run).")),A(v(" Fix properly: `anyray-connect doctor --security-review` prints the allow-list your")),A(v(" security team needs; once approved, `anyray-connect --yes` restores auto-refresh."))}},YK=e=>{if(A(K("Anyray connect \u2014 doctor")),e.connect.remoteContext||e.connect.fileBindMounts.length>0){H("Environment"),e.connect.remoteContext&&(A(` Remote dev context: ${Uo(e.connect.remoteContext)}`),Rn(e.connect.remoteContext)&&A(v(" No per-user service manager here \u2014 key refresh rides the Claude Code helper and `anyray-connect` runs, not an OS schedule.")));for(let c of e.connect.fileBindMounts)A(` Bind-mounted config file: ${$K(c)}`),A(v(" A file mounted into this container cannot be replaced atomically; connect writes it in place (verified). Mount the parent directory instead to restore atomic writes."))}switch(H("CLI updates"),e.connect.selfUpdate.state){case"managed":B(" Managed standalone binary installed; one updater owns this seat."),e.connect.selfUpdate.fleetMode==="off"?A(v(" Your organization manages Connect updates; this machine downloads nothing.")):e.connect.selfUpdate.fleetMode==="directed"?A(v(" Your organization applies Connect updates centrally; an administrator pushes new versions.")):e.connect.selfUpdate.autoUpdate||O(" Automatic CLI updates are off (`anyray-connect update --auto on`).");break;case"will-migrate":O(" This npm runtime will migrate to the managed standalone binary on the next persistent setup change."),A(v(" Run `anyray-connect update` to migrate now."));break;case"platform-unsupported":O(" Self-update is unavailable on this platform because no standalone binary is published."),A(v(" Use `npx anyray-connect@latest` to stay current."));break;case"unmanaged":A(v(" This copy is externally managed; update it with the method that installed it."));break;case"container":A(v(" Self-update is off in this container; updates arrive when it is rebuilt."));break}switch(H("Gateway"),e.gateway.reachable===null?A(v(` Probe skipped (--quick): ${e.gateway.origin} not contacted.`)):e.gateway.reachable?B(` Reachable: ${e.gateway.origin} ${v(`(${e.gateway.detail})`)}`):(R(` Unreachable: ${e.gateway.origin} (${e.gateway.detail})`),A(v(" Fix: start the gateway, or check the URL with `anyray-connect status`."))),e.refreshScheduler.enabled&&(H("Automatic key refresh"),e.refreshScheduler.owner==="tray"?e.refreshScheduler.trayHealthy?B(" Managed by the Anyray Connect app \u2014 it triggers the ~30-min key refresh."):(R(" The Anyray Connect app owns the background services on this machine, but it is missing or no longer passes its signature check."),A(v(" Fix: run `anyray-connect` to restore the background services (it reinstalls the OS schedule and clears the app takeover)."))):e.refreshScheduler.installed?B(" Scheduled \u2014 your gateway key re-mints every ~30 min, so no tool 401s on a stale key mid-session."):(R(" Enabled but the OS schedule is missing \u2014 a long session can still 401 when your key lapses."),e.serviceRemoval.kinds.includes("scheduler")||A(v(" Fix: re-run `anyray-connect` to reinstall it, or `anyray-connect --no-key-refresh` to opt out.")))),ZK(e),H("Personal key"),WK(e)){case"env":B(" Personal gateway key present ($ANYRAY_CLIENT_KEY).");break;case"profile":B(" Personal gateway key present (enrolled via connect).");break;case"enrolled-no-key":O(" Enrolled, but no personal key is cached locally right now."),A(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:if(e.enrollment.managedPending){O(" Enrollment is managed by your organization, but this machine holds no local enrollment state."),A(v(" Fix: none needed \u2014 it re-enrolls unattended on the next refresh; run `anyray-connect refresh` to do it now."));break}O(" Enrollment required \u2014 no personal gateway key is available."),A(v(` Fix: ${_y(e.enrollment.orgMode,e.enrollment.ssoLink)}, or set $ANYRAY_CLIENT_KEY to a minted ark_ key.`))}e.enrollment.enrolled&&(e.enrollment.expired?O(` Enrollment cert expired ${v(`(${e.enrollment.expiresAt})`)} \u2014 the next run re-enrolls.`):B(` Enrollment cert valid until ${e.enrollment.expiresAt} ${v(`(deployment ${e.enrollment.deploymentId})`)}`)),e.shell.staleExports.length>0&&(H("Shell"),R(" This terminal still exports Anyray, but the config is gone."),A(v(` Still set here: ${e.shell.staleExports.join(", ")}`)),A(v(` No Anyray block in ${e.shell.profilePath} \u2014 so these came from before a revert.`)),A(v(" Anything you start from this terminal keeps reaching the gateway with")),A(v(" no credential, and fails with 401.")),A(v(` Fix: unset ${e.shell.staleExports.join(" ")}`)),A(v(" Or open a new terminal. In VS Code, quit the app entirely (Cmd+Q) \u2014 it")),A(v(" reuses the environment it captured at launch, so a new terminal")),A(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};H("Claude Code hook policy"),R(` ${mc(c)}.`),A(v(` ${hc(c)}`))}H("Tools");let n=!1,r=!1,o=c=>{for(let l of c.routingOverrides??[])R(` ${c.title}: ${l.problem}.`),A(v(` ${l.fix}`))},a=c=>{c.mcp&&(c.mcp.registered?c.mcp.commandOk===!1?(R(` ${c.title}: retrieval MCP server registered, but its binary is gone (${c.mcp.command}).`),A(v(" Fix: re-run `anyray-connect` to re-register the current binary."))):B(` ${c.title}: retrieval MCP server registered ${v("(anyray_retrieve / anyray_recall)")}`):(O(` ${c.title}: retrieval MCP server not registered \u2014 externalized output can't be pulled back.`),A(v(` Fix: ${HK(c)}`))))};for(let c of e.tools){if(!c.installed){A(v(` ${c.title}: not installed (skipped)`));continue}if(c.pointedAt===null){A(v(` ${c.title}: installed (config not introspectable)`)),a(c);continue}if(c.pointedAt){if(n=!0,c.id==="cursor"&&c.nativeSubscription){B(` ${c.title}: native Cursor subscription; Anyray hooks/MCP active`),A(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}B(` ${c.title}: pointed at ${e.gateway.origin}`),o(c),c.id==="claude-code"&&A(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===Ba&&A(v(` ${ek}`)),c.id==="codex"&&A(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=_x(c);if(l==="not-routed"||l==="unverifiable"){let d=Vd(l,{...c.inferenceUnverifiableReason?{reason:c.inferenceUnverifiableReason}:{},mcpRegistered:c.mcp?.registered===!0});O(` ${c.title}: ${d.headline}`);for(let u of d.detail)A(v(` ${u}`));l==="unverifiable"&&(r=!0)}else c.tombstoned?c.policyTier==="required"?(O(` ${c.title}: reverted locally against admin policy (out of compliance)`),A(v(` Re-enroll with \`anyray-connect --tools ${c.id}\`.`))):c.policyTier==="locked"?O(` ${c.title}: reverted locally but locked by admin policy \u2014 the next reconcile re-applies it`):A(v(` ${c.title}: reverted by you (not managed) \u2014 re-enroll with \`anyray-connect --tools ${c.id}\``)):c.routingPendingReload?(R(` ${c.title}: configured, but ${c.title} is still running the previous Anyray build`),A(v(" Fix: reload the app completely (quit and reopen \u2014 a window reload is not enough), then re-run `anyray-connect`."))):(R(` ${c.title}: installed but not pointed at ${e.gateway.origin}`),A(v(" Fix: run `anyray-connect` to (re)configure it.")))}}let s=(e.repairs?.length??0)>0;if(!n&&!r&&!s&&e.problems===0&&(O(" No tools are pointed at this gateway yet."),A(v(" Fix: run `anyray-connect` to configure your tools."))),e.pendingOps.length>0){H("Queued operations");for(let c of e.pendingOps){let l=mt(c.adapter)?.title??c.adapter;c.watcherAlive?O(` ${l} ${c.op} queued since ${c.requestedAt} \u2014 completes automatically when ${l} quits.`):(R(` ${l} ${c.op} queued since ${c.requestedAt}, but its watcher is not running.`),A(v(` Fix: quit ${l} and re-run \`anyray-connect\` to complete it.`)))}}if(e.ambientRepairs.length>0){H("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=mt(l.tool)?.title??l.tool,u=l.repaired.map(({checkId:m,at:f})=>`${c(m)} ${new Date(f).toISOString().slice(0,10)}`);l.flapping&&u.push(`flapping since ${new Date(l.flapping.since).toISOString().slice(0,10)} (${l.flapping.reason})`);let p=` ${d}: ${u.join("; ")}`;l.flapping?O(p):A(p)}}let i=e.fleetPlan;if(i&&(i.freshIds.length>0||i.tombstonedIds.length>0)){H("Fleet policy");let c=l=>l.map(d=>mt(d)?.title??d).join(", ");i.freshIds.length>0&&A(` Pending enrollment (the next policy sync applies): ${c(i.freshIds)}`),i.tombstonedIds.length>0&&O(` Out of compliance (reverted against required policy): ${c(i.tombstonedIds)}`)}if(e.verify)if(H("Auth probe"),e.verify.notApplicableSubscription)B(" Provider-key verification is not applicable to subscription/native inference lanes.");else if(e.verify.kind==="ok")B(` ${e.verify.detail}`);else{R(` ${e.verify.kind}: ${e.verify.detail}`);for(let c of e.verify.remedy)A(v(` ${c}`))}if(e.retrieval)if(H("Retrieval loop"),e.retrieval.kind==="ok")B(` ${e.retrieval.detail}`);else{R(` ${e.retrieval.kind}: ${e.retrieval.detail}`);for(let c of e.retrieval.remedy)A(v(` ${c}`))}if(e.hookLane){if(H("Hook lane"),e.hookLane.verdict==="live")B(` ${e.hookLane.detail}`);else if(e.hookLane.verdict==="dark"){R(` ${e.hookLane.reason}: ${e.hookLane.detail}`);for(let c of e.hookLane.remedy)A(v(` ${c}`))}else{O(` ${e.hookLane.reason}: ${e.hookLane.detail}`);for(let c of e.hookLane.remedy)A(v(` ${c}`))}e.hookLane.lastInvokedAt!==null&&A(v(` Last hook run: ${new Date(e.hookLane.lastInvokedAt).toISOString()}`))}e.agentsWindow&&e.agentsWindow.state!=="not-applicable"&&e.agentsWindow.state!=="ready"?(H("VS Code Agents window"),O(` ${e.agentsWindow.detail}`)):e.agentsWindow?.state==="ready"&&(H("VS Code Agents window"),B(` ${e.agentsWindow.detail}`)),H("Summary"),e.problems===0?(e.verify?B(" No problems found."):B(" No configuration problems found (no request was sent \u2014 drop `--no-verify` to test one)."),A(v(" Sharing with support? `anyray-connect doctor --json` prints this as a content-free report."))):R(` ${e.problems} problem(s) found \u2014 see fixes above.`)},JK=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}),XK=async(e,t)=>{let n=e.hookLane;if(!n||n.verdict!=="dark"||n.reason!=="key_rejected")return null;if(!Ih(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??Na,o,a=async()=>(o??=await r().catch(()=>({verdict:"indeterminate",reason:"unreachable"})),o),s=await(t.refreshKey??Ut)({force:!0,hookLaneRepair:!0,probeHookLane:a}).catch(()=>"failed"),i=await a(),c=vn((await(t.readRefreshState??It)().catch(()=>({}))).hookLane),l=_h(i,{hookRegistered:await Dx(t.adapters??pe).catch(()=>!1),neverInvoked:Oh(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:Od(c)},note:d}},zK=async(e,t,n={})=>{let r=n.adapters??pe,o=n.resolveTarget??Ue,a=n.applyTools??Ft,s=await XK(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(g=>g.installed&&(Oy(g)||g.mcp?.commandOk===!1||g.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);if(!d)return{entries:l.map(g=>({id:g.id,title:g.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 ${_y(e.enrollment?.orgMode??"unknown",e.enrollment?.ssoLink??null)}, then re-run.`]};let u=new Set(t.managedTools??[]),p=[],m=[...c.notes],f=[];for(let g of l){let b=r.find(k=>k.id===g.id);if(!u.has(g.id)||!b){p.push({id:g.id,title:g.title,status:"skipped-unmanaged"});continue}f.push(b)}p.length>0&&m.push("Drifted tools outside the managed record are never auto-repaired \u2014 run `anyray-connect` once to (re)configure and record them.");let h=await a(f,d.target),w=new Map,y=0;for(let g of h){if(p.push(g),!Ao(g))continue;let b=e.tools.find(T=>T.id===g.id);if(!b)continue;let k=r.find(T=>T.id===g.id),C=b.mcp;if(k?.mcpStatus)try{let T=await k.mcpStatus();C={...T,commandOk:Px(T)}}catch{}let S=Oy(b)?!0:b.pointedAt;if(k?.pointsAt&&b.pointedAt!==null)try{S=await k.pointsAt(e.gateway.origin)}catch{}let E=b.routingOverrides,I=b.claudeCodeHookPolicy;if(k?.runtimeDiagnostics)try{let T=await k.runtimeDiagnostics();E=T.routingOverrides.length?T.routingOverrides:void 0,I=T.claudeCodeHookPolicy}catch{}else if(k?.routingOverrides)try{let T=await k.routingOverrides();E=T.length?T:void 0}catch{}let _={...b,pointedAt:S,mcp:C,...E?{routingOverrides:E}:{},...I===void 0?{}:{claudeCodeHookPolicy:I}};E||delete _.routingOverrides,I===void 0&&delete _.claudeCodeHookPolicy,w.set(g.id,_),y+=Ty(b)-Ty(_)}return{entries:p,remainingProblems:Math.max(0,e.problems-y-i),refreshedTools:w,...s?{hookLane:s.hookLane}:{},notes:m}},qK=e=>{H("Repair"),e.entries.length===0&&B(" Nothing to repair.");for(let t of e.entries)t.status==="configured"||t.status==="reverted"?B(` ${t.title}: re-applied`):t.status==="queued"?B(` ${t.title}: re-apply queued (completes when the app quits)`):t.status.startsWith("skipped-")?A(v(` ${t.title}: ${t.status}`)):R(` ${t.title}: ${t.status}`);for(let t of e.notes)A(v(` ${t}`))},pu=async(e,t={})=>{let n=await P();if(e.securityReview){if(!e.silent){A(K("Anyray connect \u2014 security review"));for(let c of Kw())A(c?` ${c}`:"")}return 0}let r;try{r=Tr(e.gateway,n)}catch(c){return e.silent?1:e.json?(console.log(JSON.stringify({error:c.message})),1):(A(K("Anyray connect \u2014 doctor")),R(` Gateway URL: ${c.message}`),A(v(" Fix: pass a gateway URL, e.g. `anyray-connect doctor http://localhost:8787`.")),1)}if(e.quick&&e.verify)return e.silent||(e.json?console.log(JSON.stringify({error:"--quick cannot be combined with --verify"})):(A(K("Anyray connect \u2014 doctor")),R(" --quick skips the network probes; it cannot be combined with --verify."))),1;let o=!e.noVerify&&!e.quick,a=await jK(r,n,!!e.verify&&!e.quick,t.adapters??pe,t.inferenceIntrospection??Hd,t.fleetBootstrap??xr,t.managedEnrollment??xo,o,t.verifyAuth??Ka,!e.quick,t.checkTray??Go,t.updateStatus??Ro,t.readRefreshState??It,t.probeHookLane??Na),s=e.repair?await zK(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;t.captureReport?.(i),e.silent||(e.json?console.log(JSON.stringify(JK(i),null,2)):(YK(i),s&&qK(s)));try{e.quick||await(t.reportHealth??hE)(Tx(i),i.connect.version)}catch{}return i.problems===0?0:1};var QK=()=>{let e=[];for(let t of pe){let n=t.skillsDir?.();n&&e.push(n)}return e},Lx=async e=>{let t=await P();A(K("Anyray connect \u2014 sync"));let n;try{n=Tr(e.gateway,t)}catch(s){return R(s.message),1}L(`Gateway: ${n}`);let r=iI(t.clientKey,"anyray-placeholder"),o;try{o=await _a(n,r)}catch(s){return R(`Team policy sync failed: ${vh(s)}`),1}let a=QK();if(a.length===0)e2();else if(o.skills.length===0)L("No team skills published yet \u2014 nothing to sync.");else{let s=await tE(o,a,t.syncedSkills??{});H("Skills");for(let i of s.results)i.written?B(` ${i.name} ${v(`(${i.id}@${i.version})`)} \u2192 ${i.files.length} file(s)`):L(` ${i.name} ${v(`(${i.id}@${i.version})`)} \u2014 up to date`);try{await ce({...t,syncedSkills:s.versions,syncedAt:s.updatedAt??new Date().toISOString()})}catch(i){L(`Could not record sync state: ${i instanceof Error?i.message:String(i)}`)}H("Summary"),A(` ${qe(String(s.changed))} updated, ${s.unchanged} unchanged, across ${a.length} tool dir(s).`)}try{let s=await Pa(o);(s.routingUpdated||s.teamUpdated||s.toolsRequested>0||s.toolsTombstoned.length>0)&&(A(`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&&L(` Locally reverted against admin policy (out of compliance): ${s.toolsTombstoned.join(", ")}. Re-run \`anyray-connect --tools <id>\` to re-enroll.`))}catch(s){L(`Fleet policy reconcile skipped: ${vh(s)}`)}return 0},e2=()=>{L("No installed tool exposes a skills directory \u2014 nothing to sync.")};import{gzip as oj}from"node:zlib";import{promisify as aj}from"node:util";var Dr={maxChars:12e3,headChars:6e3,tailChars:4e3,middleWindows:3},Py=e=>({text:e,trimmed:!1,originalChars:e.length,trimmedChars:e.length,charsRemoved:0,estTokensSaved:0}),Nx=e=>`
|
|
674
674
|
|
|
675
675
|
\u2026[anyray-hook trimmed ${e} chars (~${Math.round(e/3.3)} tokens) \u2014 elided locally, cache-safe]\u2026
|
|
676
676
|
|
|
677
677
|
`,fu=(e,t={})=>{if(typeof e!="string")return Py(String(e??""));let n=Math.max(1,t.maxChars??Dr.maxChars);if(e.length<=n)return Py(e);let r=e.length,o=Math.max(0,t.headChars??Dr.headChars),a=Math.max(0,t.tailChars??Dr.tailChars),s=Math.max(0,t.middleWindows??Dr.middleWindows),i=100*(s+2),c=Math.max(1,n-1-i);o+a>c&&(a=Math.min(a,c),o=Math.max(0,c-a));let l=o,d=r-a,u=[];o>0&&u.push([0,o]);let p=c-o-a;if(s>0&&p>0&&d>l){let y=d-l,g=Math.max(1,Math.floor(p/s));for(let b=0;b<s;b++){let k=l+Math.round((b+.5)/s*y),C=Math.min(d,Math.max(l,k)+Math.ceil(g/2)),S=Math.max(l,C-g),E=e.lastIndexOf(`
|
|
678
678
|
`,S);E>=l&&(S=E+1);let I=e.indexOf(`
|
|
679
|
-
`,C);I!==-1&&I<d&&(C=I),C>S&&u.push([S,C])}}a>0&&u.push([d,r]),u.sort((y,g)=>y[0]-g[0]);let m=[];for(let[y,g]of u){let b=m[m.length-1];b&&y<=b[1]?b[1]=Math.max(b[1],g):m.push([y,g])}let f="",h=0;for(let[y,g]of m)y>h&&(f+=Nx(y-h)),f+=e.slice(y,g),h=g;if(r>h&&(f+=Nx(r-h)),f.length>=r)return Py(e);let w=r-f.length;return{text:f,trimmed:!0,originalChars:r,trimmedChars:f.length,charsRemoved:w,estTokensSaved:Math.round(w/3.3)}},
|
|
679
|
+
`,C);I!==-1&&I<d&&(C=I),C>S&&u.push([S,C])}}a>0&&u.push([d,r]),u.sort((y,g)=>y[0]-g[0]);let m=[];for(let[y,g]of u){let b=m[m.length-1];b&&y<=b[1]?b[1]=Math.max(b[1],g):m.push([y,g])}let f="",h=0;for(let[y,g]of m)y>h&&(f+=Nx(y-h)),f+=e.slice(y,g),h=g;if(r>h&&(f+=Nx(r-h)),f.length>=r)return Py(e);let w=r-f.length;return{text:f,trimmed:!0,originalChars:r,trimmedChars:f.length,charsRemoved:w,estTokensSaved:Math.round(w/3.3)}},t2=["stdout","content","output","text","result"],$x=e=>{if(typeof e=="string")return{body:e,rebuild:o=>o};if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;if(Array.isArray(t.content)){let o=t.content,a=[];for(let[i,c]of o.entries())c&&typeof c=="object"&&!Array.isArray(c)&&typeof c.text=="string"&&a.push({index:i,part:c,text:c.text});let s=Object.prototype.hasOwnProperty.call(t,"structuredContent")&&t.structuredContent!==void 0;if(a.length===1&&!s){let i=a[0];return{body:i.text,rebuild:c=>({...t,content:o.map((l,d)=>d===i.index?{...i.part,text:c}:l)})}}if(a.length>0||s){let i=a.map(({text:d},u)=>`--- MCP text part ${u+1} ---
|
|
680
680
|
${d}`);s&&i.push(`--- MCP structuredContent ---
|
|
681
681
|
${JSON.stringify(t.structuredContent)}`);let c=a[0],l=new Set(a.map(({index:d})=>d));return{body:i.join(`
|
|
682
682
|
|
|
683
|
-
`),rebuild:d=>{let u={...t};return delete u.structuredContent,u.content=o.flatMap((p,m)=>l.has(m)?m!==c?.index?[]:[{...c.part,text:d}]:[p]),c||(u.content=[{type:"text",text:d},...u.content]),u}}}}let n=
|
|
684
|
-
`),s=0,i=0;for(let c of a)c.trim()&&(s++,
|
|
685
|
-
${e.slice(-Dy)}`:e;return
|
|
686
|
-
`),router:"test-run",stat:`test run: kept ${n} failure block(s)${a}`,kept:n,total:n+r}},
|
|
687
|
-
`),router:"grep",stat:`grep: ${o} hits in ${n.size} files, kept ${s}`,kept:s,total:o}},
|
|
688
|
-
`),router:"log-dedup",stat:`log: ${e.length} lines \u2192 ${n.length} unique`,kept:n.length,total:e.length}},Hx=(e,t)=>{if(typeof t!="string"||t.length===0||
|
|
689
|
-
`).filter(s=>s.trim()!==""),r=Ly(e),o=
|
|
683
|
+
`),rebuild:d=>{let u={...t};return delete u.structuredContent,u.content=o.flatMap((p,m)=>l.has(m)?m!==c?.index?[]:[{...c.part,text:d}]:[p]),c||(u.content=[{type:"text",text:d},...u.content]),u}}}}let n=t2.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 n2=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},Wi={minChars:8e3,minDataLineRatio:.6,minDataLines:20},mu=(e,t={})=>{if(typeof e!="string")return!1;let n=t.minChars??Wi.minChars;if(e.length<n)return!1;let r=t.minDataLineRatio??Wi.minDataLineRatio,o=t.minDataLines??Wi.minDataLines,a=e.split(`
|
|
684
|
+
`),s=0,i=0;for(let c of a)c.trim()&&(s++,n2(c)&&i++);return s===0||i<o?!1:i/s>=r};var Ui=(e,t=200)=>e.length>t?`${e.slice(0,t)}\u2026`:e,hu={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"},Fx=new Set(["npm","pnpm","yarn","bun"]),yu=e=>{let t=e.lastIndexOf("/");return t===-1?e:e.slice(t+1)},r2=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=yu(r[0]);if(o in hu)return hu[o];if((o==="npx"||o==="bunx")&&r[1]){let a=yu(r[1]);if(a in hu)return hu[a]}return o==="git"&&r[1]==="grep"?"grep":o==="node"&&r.includes("--test")||Fx.has(o)&&(r[1]==="test"||r[1]==="t"||r[1]==="run"&&r[2]&&/test/i.test(r[2]))?"test-run":null},Ly=e=>{if(typeof e!="string"||!e.trim())return null;for(let t of e.split(/\|\||&&|;|\||\n/)){let n=r2(t);if(n)return n}return null},o2={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},a2=/^(build|lint|typecheck|type-check|check|compile|tsc)/i,s2=(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},Wx=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=yu(r[0]);if(Fx.has(o)){let i=r[1]==="run"?r[2]:r[1];return i!=null&&a2.test(i)}let a=r[1]?yu(r[1]):void 0;if(s2(o,a,r))return!1;let s=o2[o];return s===void 0?!1:s===null||a!=null&&s.has(a)},i2=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==="]"},c2=e=>{for(let t=1;t<e.length;t++){if(e[t]==="\\"){t++;continue}if(e[t]==='"')return t}return-1},l2=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=c2(t);return r>0&&t[r+1]===":"},d2=80,u2=e=>{if(e.length===0)return!1;let t=Math.ceil(e.length/d2),n=0,r=0;for(let o=0;o<e.length;o+=t)n++,l2(e[o])&&r++;return n>0&&r/n>.3},p2=/^(import |export |from |const |let |var |function |class |def |async |await |#include |@charset |\/\/ |\/\* |\* )/,f2=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();(p2.test(o)||/[{};]$/.test(o))&&n++}return n/t.length>.3},m2=[/\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],Dy=8192,h2=e=>{let t=e.length>2*Dy?`${e.slice(0,Dy)}
|
|
685
|
+
${e.slice(-Dy)}`:e;return m2.some(n=>n.test(t))},y2=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),g2=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),w2=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},b2=e=>/^(PASS|ok)\b/.test(e)||/^--- PASS: /.test(e)||/^\s*(✓|✔)/.test(e)||/\[\s*\d+%\]$/.test(e),Mx=e=>{let t=[],n=0,r=0,o=0;for(let s of e){let i=s.trim();if(!i)continue;if(g2(i)){t.push(Ui(i));continue}let c=w2(i);if(c){if(n>=10){r++,o=0;continue}n++,t.push(Ui(c)),o=12;continue}y2(i)||b2(i)||o>0&&(t.push(Ui(s)),o--)}if(t.length===0)return null;let a=r>0?` (+${r} more)`:"";return{text:t.join(`
|
|
686
|
+
`),router:"test-run",stat:`test run: kept ${n} failure block(s)${a}`,kept:n,total:n+r}},A2=/^([^\s:]+):(\d+):(?:\d+:)?(.*)$/,Ux=e=>{let t=A2.exec(e);return t&&/[/.]/.test(t[1])?t:null},C2=/^([^\s:]+)-(\d+)-/,k2=e=>{if(e==="--")return!0;let t=C2.exec(e);return t!=null&&/[/.]/.test(t[1])},v2=e=>{let t=e.slice(0,50);if(t.length<3)return!1;let n=t.filter(r=>Ux(r)!=null).length;return n>=3&&n/t.length>=.7},Bx=(e,t)=>{let n=new Map,r=0,o=0;for(let c of e){let l=Ux(c);if(!l){if(k2(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(Ui(` ${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(`
|
|
687
|
+
`),router:"grep",stat:`grep: ${o} hits in ${n.size} files, kept ${s}`,kept:s,total:o}},S2=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(),E2=e=>{if(e.length<12)return null;let t=new Map,n=[];for(let o of e){let a=S2(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=Ui(a.trim());return s>1?`[\xD7${s}] ${i}`:i}).join(`
|
|
688
|
+
`),router:"log-dedup",stat:`log: ${e.length} lines \u2192 ${n.length} unique`,kept:n.length,total:e.length}},Hx=(e,t)=>{if(typeof t!="string"||t.length===0||i2(t))return null;let n=t.split(`
|
|
689
|
+
`).filter(s=>s.trim()!==""),r=Ly(e),o=h2(t),a=null;return r==="test-run"&&o?a=Mx(n):r==="grep"&&(a=Bx(n,.5)),a||(o?a=Mx(n):v2(n)?a=Bx(n,.7):!f2(n)&&!u2(n)&&(a=E2(n))),!a||a.text.length>=t.length?null:a},Gx=e=>`full output: Read ${e}`,Ny=(e,t)=>t?`
|
|
690
690
|
|
|
691
691
|
\u2026[anyray-hook digest \u2014 ${e}; ${Gx(t)}]\u2026`:`
|
|
692
692
|
|
|
693
693
|
\u2026[anyray-hook digest \u2014 ${e}]\u2026`,Vx=e=>`
|
|
694
694
|
|
|
695
|
-
\u2026[anyray-hook \u2014 ${Gx(e)}]\u2026`;import{createHash as
|
|
696
|
-
`):"",
|
|
697
|
-
`).slice(0,c0)};var
|
|
698
|
-
`);i=l>=0?i.slice(l+1):""}let c=
|
|
699
|
-
`));return
|
|
700
|
-
`:"",Vy=e=>Math.round(Math.max(0,e)/4),d0=e=>typeof e=="string"?e:e!=null?JSON.stringify(e):"",
|
|
701
|
-
${d0(r.tool_input)}`:d0(r.tool_input),y=o0(o,w,u),g=async S=>{try{await t.cachePut(y,S)}catch{}},b=null;try{b=await t.cacheGet(y)}catch{b=null}if(b)return b.optimized&&b.output.length<u.length?f(b.output,b.tokensSaved):h();let k=null;try{k=
|
|
702
|
-
`,{mode:384}),await
|
|
695
|
+
\u2026[anyray-hook \u2014 ${Gx(e)}]\u2026`;import{createHash as I2}from"node:crypto";import{homedir as x2}from"node:os";import{join as Lr}from"node:path";import{chmod as R2,mkdir as O2,readdir as Yx,stat as Gi,unlink as Hi,utimes as T2,writeFile as My}from"node:fs/promises";var gu={ttlMs:720*60*60*1e3,maxAgeMs:2160*60*60*1e3,maxTotalBytes:128*1024*1024,maxFiles:2e4,sweepIntervalMs:3600*1e3,writeGraceMs:30*1e3},Jx=".swept",_2=".sweeping",Kx=64,jx=448,By=384,Fy=()=>(process.env.ANYRAY_HOOK_TEE??"").trim().toLowerCase()==="off",Xx=e=>Number.isFinite(e.birthtimeMs)&&e.birthtimeMs>0?e.birthtimeMs:e.mtimeMs,Wy=async()=>{let e=process.env.ANYRAY_HOOK_TEE_DIR;if(e)return e;let t=ee();try{if((await Gi(t)).isDirectory())return Lr(t,"hook-tee")}catch{}return Lr(x2(),".anyray-hook-tee")},P2=/^(?:ctx_)?([0-9a-f]{16})$/,Uy=e=>e.trim().match(P2)?.[1]??null,Hy=async e=>{let t=Uy(e);return t?Lr(await Wy(),`${t}.txt`):null},D2=async(e,t={})=>{let n=t.limits??gu;try{let r=Date.now(),o=(await Yx(e)).filter(c=>c.endsWith(".txt")),a=[];for(let c=0;c<o.length;c+=Kx)await Promise.all(o.slice(c,c+Kx).map(async l=>{let d=Lr(e,l);try{let u=await Gi(d);if(!u.isFile())return;let p=r-u.mtimeMs>n.ttlMs||r-Xx(u)>n.maxAgeMs;if(d!==t.protect&&p){await Hi(d);return}a.push({path:d,mtimeMs:u.mtimeMs,size:u.size})}catch{}}));a.sort((c,l)=>l.mtimeMs-c.mtimeMs);let s=0,i=0;for(let c of a){let l=s<n.maxFiles&&i+c.size<=n.maxTotalBytes,d=r-c.mtimeMs<n.writeGraceMs;if(l||s===0||c.path===t.protect||d){s+=1,i+=c.size;continue}await Hi(c.path).catch(()=>{})}}catch{}},zx=async e=>{try{return Date.now()-(await Gi(e)).mtimeMs}catch{return Number.POSITIVE_INFINITY}},Zx=async e=>{try{return await My(e,"",{mode:By,flag:"wx"}),!0}catch{return!1}},L2=async(e,t)=>{let n=gu,r=Lr(e,_2),o=Lr(e,Jx);if(!await Zx(r)){let a=0;try{a=Date.now()-(await Gi(r)).mtimeMs}catch{return!1}if(a<=n.sweepIntervalMs||(await Hi(r).catch(()=>{}),!await Zx(r)))return!1}try{return await zx(o)<n.sweepIntervalMs?!1:(await My(o,"",{mode:By}).catch(()=>{}),await D2(e,{protect:t}),!0)}finally{await Hi(r).catch(()=>{})}},$y=async(e,t)=>await zx(Lr(e,Jx))<gu.sweepIntervalMs?!1:L2(e,t),N2=async()=>{try{let e=await Wy();if(!(await Yx(e)).some(t=>t.endsWith(".txt")))return;await $y(e)}catch{}},qx=async e=>{if(Fy())return await N2(),null;try{let t=await Wy();await O2(t,{recursive:!0,mode:jx}),await R2(t,jx).catch(()=>{});let n=`${I2("sha256").update(e).digest("hex").slice(0,16)}.txt`,r=Lr(t,n),o=Date.now();try{let a=await Gi(r);if(a.isFile()){if(o-Xx(a)<=gu.maxAgeMs){let s=new Date(o);return await T2(r,s,s).catch(()=>{}),await $y(t,r),r}await Hi(r).catch(()=>{})}}catch{}return await My(r,e,{mode:By}),await $y(t,r),r}catch{return null}};import{createHash as $2}from"node:crypto";import{homedir as Qx}from"node:os";import{join as Gy}from"node:path";import{readFile as M2,writeFile as B2,chmod as F2,stat as W2,unlink as U2}from"node:fs/promises";var H2=200,G2=1440*60*1e3,V2=4e6,e0=()=>(process.env.ANYRAY_HOOK_CACHE??"").trim().toLowerCase()==="off",t0=(e,t)=>{let n=process.env[e];if(!n)return t;let r=Number(n);return Number.isFinite(r)&&r>0?r:t},K2=()=>t0("ANYRAY_HOOK_CACHE_MAX_ENTRIES",H2),n0=()=>t0("ANYRAY_HOOK_CACHE_TTL_MS",G2),r0=async()=>{let e=process.env.ANYRAY_HOOK_CACHE_FILE?.trim();if(e)return e;let t=Gy(Qx(),".anyray");try{if((await W2(t)).isDirectory())return Gy(t,"hook-cache.json")}catch{}return Gy(Qx(),".anyray-hook-cache.json")},o0=(e,t,n)=>$2("sha256").update(`${e.length}:${e}`).update(`${t.length}:${t}`).update(n).digest("hex"),a0=async e=>{try{let t=JSON.parse(await M2(e,"utf-8"));if(t?.v===1&&t.entries&&typeof t.entries=="object")return t}catch{}return{v:1,entries:{}}},s0=async e=>{if(e0())return null;try{let n=(await a0(await r0())).entries[e];return!n||Date.now()-n.at>n0()?null:typeof n.o=="string"?{optimized:!0,output:n.o,tokensSaved:Number.isFinite(n.t)?n.t:0}:{optimized:!1}}catch{return null}},j2=e=>{let t=Date.now(),n=n0(),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=K2();for(let i of r){if(o.length>=s||(a+=i[1].o?.length??0,a>V2&&o.length>0))break;o.push(i)}return Object.fromEntries(o)},i0=async(e,t)=>{if(e0())return;let n;try{let r=await r0(),o=await a0(r);o.entries[e]=t.optimized?{o:t.output,t:t.tokensSaved,at:Date.now()}:{at:Date.now()},o.entries=j2(o.entries),n=`${r}.${process.pid}.tmp`,await B2(n,JSON.stringify(o),{mode:384}),await F2(n,384),await ye(n,r)}catch{if(n)try{await U2(n)}catch{}}};import{open as Z2,stat as Y2}from"node:fs/promises";var c0=600,J2=3,X2=256e3,z2=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(`
|
|
696
|
+
`):"",q2=e=>e.startsWith("<command-name>")||e.startsWith("<command-message>")||e.startsWith("<local-command-"),Q2=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},ej=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=z2(o.message?.content).trim();if(!(!a||q2(a))&&(t.unshift(a),n+=a.length,t.length>=J2||n>=c0))break}return t.join(`
|
|
697
|
+
`).slice(0,c0)};var tj=e=>/(^|[\\/])subagents[\\/]/i.test(e),nj=e=>/\.jsonl$/i.test(e),rj=e=>e.some(t=>(t.type==="user"||t.type==="assistant")&&t.message!==null&&typeof t.message=="object"),l0=async e=>{let t={intent:"",kind:"unknown"};if(!e||!nj(e))return t;let n;try{let{size:r}=await Y2(e),o=Math.max(0,r-X2),a=r-o;if(a<=0)return t;n=await Z2(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(`
|
|
698
|
+
`);i=l>=0?i.slice(l+1):""}let c=Q2(i.split(`
|
|
699
|
+
`));return rj(c)?{intent:ej(c),kind:tj(e)?"subagent":"main"}:t}catch{return t}finally{try{await n?.close()}catch{}}};var sj=3e3,ij=1500,cj=()=>{let e=Number(process.env.ANYRAY_HOOK_OPTIMIZE_TIMEOUT_MS);return Number.isFinite(e)&&e>0?e:sj},lj={claude:"claude-code",codex:"codex",cursor:"cursor",opencode:"opencode"},dj=new Set(["claude","opencode"]),uj=(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]})},pj={cacheGet:async()=>null,cachePut:async()=>{}},fj=(e,t={cacheGet:s0,cachePut:i0,tee:qx})=>e==="claude"?t:pj,mj=1e3,hj=e=>JSON.stringify({hookSpecificOutput:{hookEventName:"PostToolUse",updatedToolOutput:e}}),wu=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),yj=e=>{try{let t=JSON.parse(e);if(!wu(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 wu(n)?JSON.stringify({...t,tool_output:n}):void 0}catch{return}},gj=e=>{try{let t=JSON.parse(e);return wu(t)&&typeof t.tool_name=="string"&&t.tool_name.startsWith("MCP:")}catch{return!1}},wj=e=>wu(e)?`${JSON.stringify({updated_mcp_tool_output:e})}
|
|
700
|
+
`:"",Vy=e=>Math.round(Math.max(0,e)/4),d0=e=>typeof e=="string"?e:e!=null?JSON.stringify(e):"",bj=new Set(["Edit","MultiEdit","Write","NotebookEdit","ExitPlanMode","TodoWrite"]),Aj=e=>/(^|[^a-z0-9])anyray_(retrieve|recall)$/i.test(e.trim()),Cj=["tool_output","tool_response","tool_result"],kj=e=>{for(let t of Cj)if(t in e)return e[t]},vj=(e,t)=>{if(e!=="Bash"||t==null||typeof t!="object")return"";let n=t.command;return typeof n=="string"?n:""},Sj=120,Ej=async(e,t,n)=>{if(!e.digestCommand||!t||n.length<(e.digestGate??mj))return null;let r=null;try{r=e.digestCommand(t,n)}catch{return null}if(!r)return null;let o=Ny(r.stat,null).length+Sj;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=Ny(r.stat,a);return r.text.length+s.length>=n.length?null:{body:r.text,marker:s,teePath:a,decision:{router:r.router,kept:r.kept,total:r.total,teed:a!=null}}},Ij=async(e,t)=>{let n={stdout:""};if(!e.trim())return n;let r;try{let S=JSON.parse(e);if(!S||typeof S!="object")return n;r=S}catch{return n}let o=typeof r.tool_name=="string"?r.tool_name:"unknown";if(bj.has(o)||Aj(o))return n;let a=$x(kj(r));if(!a)return n;let s=async S=>{try{await t.beacon(o,S)}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(u0(o)&&l.retrievalContext!=="available")return n;let d=await Ej(t,vj(o,r.tool_input),i),u=d?.body??i,p=d?.marker??"";if(!d&&i.length<=t.sizeGate&&(!t.mediumBand||!mu(i,{minChars:ij})))return n;let m=i.length-u.length-p.length,f=async(S,E,I=S.length+p.length)=>{let _=d?.teePath??null;if(!_&&t.tee)try{_=await t.tee(i)}catch{_=null}let T=_?S.replaceAll("; not retrievable in this context]","]"):S,W=_&&!p?Vx(_):"",Q=T+p+W,G=W.length,ne=Q;if(t.finalizeOutput)try{let U=t.finalizeOutput(Q);U.length<=Q.length&&(ne=U)}catch{ne=Q}let z=Q.length-ne.length,j=Vy(Math.max(0,m-G))+E+Vy(z);j>0&&await s({originalChars:i.length,trimmedChars:Math.max(0,I+G-z),estTokensSaved:j,...d&&{digest:d.decision}});let le=a.rebuild(ne);return{stdout:hj(le),replacement:le}},h=async()=>d?f(u,0):n;if(d&&u.length<=t.sizeGate)return f(u,0);let w=l.intent?`${l.intent}
|
|
701
|
+
${d0(r.tool_input)}`:d0(r.tool_input),y=o0(o,w,u),g=async S=>{try{await t.cachePut(y,S)}catch{}},b=null;try{b=await t.cacheGet(y)}catch{b=null}if(b)return b.optimized&&b.output.length<u.length?f(b.output,b.tokensSaved):h();let k=null;try{k=Pj(o)?null:await t.optimize(o,r.tool_input,u,l.intent,l.retrievalContext)}catch{k=null}if(k&&!k.handled&&(k=null),k)return k.optimized&&k.output.length<u.length?(await g({optimized:!0,output:k.output,tokensSaved:Vy(u.length-k.output.length)}),f(k.output,0,u.length+p.length)):(await g({optimized:!1}),h());let C;try{C=t.localTrim(u)}catch{return h()}return C.trimmed?f(C.text,C.estTokensSaved):h()},Vi=async()=>{let e=[];try{for await(let t of process.stdin)e.push(t)}catch{return""}return Buffer.concat(e).toString("utf-8")},xj=()=>{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")}},Rj=aj(oj),Oj=async e=>{try{let t=await Rj(e);return{body:new Uint8Array(t.buffer,t.byteOffset,t.byteLength),encoding:"gzip"}}catch{return{body:e}}},u0=e=>/(^|[^a-z0-9])anyray_read$/i.test(e.trim()),Tj=e=>{let t=e.trim();return/anyray_/i.test(t)?!1:/(^|[^a-z0-9])(read|read_file|readfile)$/i.test(t)},_j=e=>/(^|[^a-z0-9])anyray_(search|read)$/i.test(e.trim()),Pj=e=>/(^|[^a-z0-9])anyray_history$/i.test(e.trim()),Dj=2048,Lj=async e=>{try{let t=(await e.text().catch(()=>"")).slice(0,Dj),n=Rd(t);if(!n)return;await UE({at:Date.now(),status:e.status,code:n})}catch{}},Nj=async(e,t,n,r,o,a)=>{if(!e)return null;let s=new AbortController,i=setTimeout(()=>s.abort(),cj());try{let c=await Oj(JSON.stringify({tool:t,toolInput:n,...o?{intent:o}:{},retrievalContext:a,...u0(t)||Tj(t)&&a==="available"?{reversible:!0}:{},..._j(t)?{semanticRerank:!0}:{},output:r})),l=Zt(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 Lj(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)}},p0=async(e="claude")=>{let t=await Vi();if(e!=="cursor"&&gj(t))return 0;let n=e==="cursor"?yj(t):t;if(n===void 0)return 0;let{stdout:r,replacement:o}=await Ky(n,e);if(e==="cursor"){let a=wj(o);return a&&process.stdout.write(a),0}return r&&process.stdout.write(r),0},Ky=async(e,t="claude",n)=>{await Or(),await WE(t);let r=xj(),o=await nt(),a=o&&{...o,metadata:uj(o.metadata,t)},s=fj(t);return Ij(e,{optimize:(i,c,l,d,u)=>Nj(a,i,c,l,d,u),...t==="claude"?{readContext:async i=>{let c=await l0(i);return{intent:c.intent,retrievalContext:c.kind==="main"?"available":c.kind==="subagent"?"unavailable":"unknown"}},defaultRetrievalContext:"unknown"}:{defaultRetrievalContext:"available"},localTrim:i=>fu(i,r),beacon:(i,c)=>gc(a,"hook",c,i),cacheGet:s.cacheGet,cachePut:s.cachePut,sizeGate:r.maxChars??Dr.maxChars,digestCommand:Hx,tee:s.tee,mediumBand:dj.has(t),finalizeOutput:n})};var f0=async()=>0;import{spawn as Hj}from"node:child_process";import{homedir as Gj}from"node:os";import{join as Vj}from"node:path";import{chmod as $j,readFile as Mj,rm as m0,writeFile as Bj}from"node:fs/promises";import{join as Fj}from"node:path";var jy=()=>Fj(ee(),"sso-gate.json"),Wj=e=>{if(e===null||typeof e!="object"||Array.isArray(e))return!1;let t=e,n=a=>t[a]===void 0||typeof t[a]=="number"&&Number.isFinite(t[a]),r=a=>t[a]===void 0||typeof t[a]=="string",o=new Set(["cp-unreachable","sso-unavailable","denied","expired","gateway-unreachable"]);return t.v===1&&(t.status===void 0||t.status==="pending")&&r("userCode")&&r("verificationUriComplete")&&n("grantExpiresAt")&&n("startedAt")&&n("pollerPid")&&n("lastAttemptAt")&&n("failureCount")&&(t.lastFailure===void 0||typeof t.lastFailure=="string"&&o.has(t.lastFailure))},ja=async()=>{try{let e=JSON.parse(await Mj(jy(),"utf-8"));return Wj(e)?e:null}catch{return null}},Uj=0,bu=async e=>{await et();let t=jy(),n=`${t}.${process.pid}.${Uj++}.tmp`;try{await Bj(n,`${JSON.stringify(e)}
|
|
702
|
+
`,{mode:384}),await $j(n,384),await ye(n,t)}catch(r){throw await m0(n,{force:!0}).catch(()=>{}),r}},h0=async()=>{await m0(jy(),{force:!0}).catch(()=>{})},y0=e=>{if(!e||!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t instanceof Error&&"code"in t&&t.code==="EPERM"}};var Kj=3e4,jj=5*6e4,Zj=30*6e4,Yj=e=>{let t={};for(let n=0;n<e.length;n++){let r=e[n],o=()=>{let a=e[++n];if(!a)throw new Error(`missing value for ${r}`);return a};switch(r){case"--sso":t.sso=o();break;case"--gateway":t.gateway=o();break;case"--team":t.team=o();break;case"--session-start":t.sessionStart=!0;break;default:throw new Error("invalid SSO gate arguments")}}if(!t.sso)throw new Error("missing --sso");return t},Jj=()=>Vj(Gj(),".claude","settings.json"),Xj=async e=>{try{let n=(await M(Jj())).env;if(!n)return!1;let r=rn(e).env;for(let[o,a]of Object.entries(r))if(n[o]!==a)return!1;return n.ANTHROPIC_AUTH_TOKEN===void 0}catch{return!1}},zj=async e=>{await rr.apply(e,{dryRun:!1})},qj=()=>{let{command:e,args:t}=or("__anyray-sso-poll");return{exe:e,args:t}},Qj=()=>{let{exe:e,args:t}=qj(),n=Hj(e,t,{detached:!0,stdio:["pipe","ignore","ignore"]});return n.on("error",()=>{}),n.unref(),n.stdin?.on("error",()=>{}),{pid:n.pid,handoff:r=>{n.stdin?.end(JSON.stringify(r))}}},eZ=e=>{let t=Date.parse(e.enrolledCert?.payload.expiresAt??""),n=Date.parse(e.enrolledCertExpiry??"");return Number.isFinite(n)?Math.min(t,n):t},g0=(e,t,n,r)=>Ee({origin:e,clientKey:r,subscription:!0,user:t.name??t.enrolledCert?.payload.user,team:n??t.team??t.enrolledCert?.payload.team}),Za=(e,t)=>e.sessionStart?{exitCode:0}:{exitCode:2,stderr:t},w0=e=>`Anyray: one-time sign-in required to use AI tools on this device.
|
|
703
703
|
1. Open ${e.verificationUriComplete}
|
|
704
704
|
2. Confirm code ${e.userCode}
|
|
705
705
|
Your prompt was not sent \u2014 complete sign-in, then resubmit it.
|
|
706
706
|
`,Zy=(e,t)=>e==="sso-unavailable"?`Anyray: SSO isn't configured \u2014 ask your Anyray admin.
|
|
707
707
|
`:e==="gateway-unreachable"?`Anyray: can't reach the gateway \u2014 check your network/VPN, then resubmit your prompt.
|
|
708
708
|
`:`Anyray: can't reach ${t} \u2014 check your network/VPN, then resubmit your prompt.
|
|
709
|
-
`,
|
|
710
|
-
`))}let z;await h();let j=(t.resolveMachineUuid??Wt)()||void 0;try{z=await d(I,b.enrolledCert,C,{timeoutMs:1e4,machineUuid:j})}catch(le){if(!(le instanceof lt))return Za(e,Zy("gateway-unreachable",g.cpOrigin));await o({...b,enrolledCert:void 0,enrolledCertExpiry:void 0,clientKey:void 0,clientKeyExpiresAt:void 0})}if(z){let le={...b,gateway:I,name:z.user,team:e.team??z.team??b.team,clientKey:z.key,clientKeyExpiresAt:z.expiresAt,authMode:"subscription"};return await o(le),await f({expiresAt:z.expiresAt}),await p(g0(I,le,e.team,z.key)),{exitCode:0}}}if(k?.status==="pending"&&(k.userCode&&k.verificationUriComplete)&&(k.grantExpiresAt??0)>n()&&c(k.pollerPid)){if(e.sessionStart&&k.verificationUriComplete)try{y(k.verificationUriComplete)}catch{}return Za(e,w0(k))}if(k){let G=
|
|
711
|
-
`}catch{return}},
|
|
709
|
+
`,tZ=e=>Math.min(jj,Kj*2**Math.max(0,e-1)),nZ=(e,t)=>{if(e.lastFailure!=="cp-unreachable"&&e.lastFailure!=="sso-unavailable")return;let n=e.lastFailure==="sso-unavailable"?Zj:tZ(e.failureCount??1);return t-(e.lastAttemptAt??0)<n?e.lastFailure:void 0},_o=async(e,t={})=>{let n=t.now??Date.now,r=t.loadProfile??P,o=t.saveProfile??ce,a=t.loadDevKey??Fe,s=t.readGateState??ja,i=t.writeGateState??bu,c=t.isProcessAlive??y0,l=t.startGrant??kd,d=t.verify??Qt,u=t.routingIntact??Xj,p=t.applyClaudeCode??zj,m=t.maybeSpawnRefresh??Or,f=t.recordMint??$a,h=t.reserveMint??So,w=t.spawnPoller??Qj,y=t.openBrowser??Ua;try{let g=Et(e.sso);if(!g)return{exitCode:0};let b=await r(),k=await s(),C=b.enrolledCert?await a():void 0,S=eZ(b),E=!!(b.enrolledCert&&C)&&Number.isFinite(S)&&S>n(),I=e.gateway??b.gateway;if(E&&b.enrolledCert&&C&&I){let G=Date.parse(b.clientKeyExpiresAt??"");if(!!b.clientKey?.startsWith("ark_")&&Number.isFinite(G)&&G>n()&&b.clientKey){let le=g0(I,b,e.team,b.clientKey);return await u(le)?(G-n()<=$h()&&await m(),{exitCode:0}):(await p(le),Za(e,`Anyray: routing restored \u2014 restart this Claude Code session, then resubmit your prompt.
|
|
710
|
+
`))}let z;await h();let j=(t.resolveMachineUuid??Wt)()||void 0;try{z=await d(I,b.enrolledCert,C,{timeoutMs:1e4,machineUuid:j})}catch(le){if(!(le instanceof lt))return Za(e,Zy("gateway-unreachable",g.cpOrigin));await o({...b,enrolledCert:void 0,enrolledCertExpiry:void 0,clientKey:void 0,clientKeyExpiresAt:void 0})}if(z){let le={...b,gateway:I,name:z.user,team:e.team??z.team??b.team,clientKey:z.key,clientKeyExpiresAt:z.expiresAt,authMode:"subscription"};return await o(le),await f({expiresAt:z.expiresAt}),await p(g0(I,le,e.team,z.key)),{exitCode:0}}}if(k?.status==="pending"&&(k.userCode&&k.verificationUriComplete)&&(k.grantExpiresAt??0)>n()&&c(k.pollerPid)){if(e.sessionStart&&k.verificationUriComplete)try{y(k.verificationUriComplete)}catch{}return Za(e,w0(k))}if(k){let G=nZ(k,n());if(G)return Za(e,Zy(G,g.cpOrigin))}let _;try{_=await l({cpOrigin:g.cpOrigin,tenantId:g.tenantId,gatewayUrl:e.gateway,now:n})}catch(G){let ne=G instanceof bo?G.kind:"cp-unreachable";return await i({v:1,lastAttemptAt:n(),failureCount:k?.lastFailure===ne?(k.failureCount??0)+1:1,lastFailure:ne}),Za(e,Zy(ne,g.cpOrigin))}let T={v:1,status:"pending",userCode:_.userCode,verificationUriComplete:_.verificationUriComplete,grantExpiresAt:_.grantExpiresAt,startedAt:_.startedAt,lastAttemptAt:n(),failureCount:0};await i(T);let W=w(),Q={...T,pollerPid:W.pid};if(await i(Q),W.handoff({deviceCode:_.deviceCode,privateKeyPem:_.privateKeyPem,publicKeyPem:_.publicKeyPem,cpOrigin:_.cpOrigin,tenantId:_.tenantId,intervalMs:_.intervalMs,grantExpiresAt:_.grantExpiresAt,startedAt:_.startedAt,gatewayUrl:_.gatewayUrl,gatewayOverride:e.gateway,team:e.team}),e.sessionStart)try{y(_.verificationUriComplete)}catch{}return Za(e,w0(Q))}catch{return{exitCode:0}}},rZ=async()=>{try{for await(let e of process.stdin);}catch{}},b0=async e=>{await rZ();try{let t=await _o(Yj(e));return t.stderr&&process.stderr.write(t.stderr),t.exitCode}catch{return 0}};var oZ=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},aZ=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??xr)();if(!r)return;let o=await(t.ssoGate??_o)({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})}
|
|
711
|
+
`}catch{return}},sZ=async()=>{let e=[];try{for await(let t of process.stdin)e.push(t)}catch{return""}return Buffer.concat(e).toString("utf-8")},iZ=()=>{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")}},cZ=(e,t)=>{let n=t.minChars??Wi.minChars,r={maxChars:Math.min(Dr.maxChars,n)},o=fu(e,r);return!o.trimmed||o.estTokensSaved<=0?null:{originalChars:o.originalChars,trimmedChars:o.trimmedChars,estTokensSaved:o.estTokensSaved}},A0=async()=>{let e=await sZ(),t=await aZ(e);t&&process.stdout.write(t);let n=iZ(),r=await nt();return await oZ(e,{isPaste:o=>mu(o,n),measure:o=>cZ(o,n),beacon:o=>gc(r,"prompt",o)}),0};import{spawn as lZ}from"node:child_process";var C0=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),dZ=/[|&;<>`$()\n]/,k0=e=>{if(dZ.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},uZ=(e,t)=>{let n;try{n=JSON.parse(e)}catch{return""}if(!C0(n)||n.tool_name!=="Shell")return"";let r=n.tool_input;if(!C0(r)||typeof r.command!="string")return"";let o=r.command;return!o||o.includes(np)||!t.isRecognized(o)||k0(o)===null?"":JSON.stringify({updated_input:{...r,command:t.wrap(o)}})},pZ=async(e,t)=>{let n="";try{n=Buffer.from(String(e??""),"base64").toString("utf8")}catch{n=""}let r=n?k0(n):null;if(!n||!r)return t.writeErr(`anyray: could not run wrapped command
|
|
712
712
|
`),1;let o;try{o=await t.exec(r)}catch{return t.writeErr(`anyray: failed to run wrapped command
|
|
713
|
-
`),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},
|
|
713
|
+
`),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},fZ=16*1024*1024,mZ=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=lZ(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>fZ){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)}}),hZ=async(e,t)=>{let n=JSON.stringify({tool_name:"Bash",tool_input:{command:e},tool_response:t}),{replacement:r}=await Ky(n,"cursor");return typeof r=="string"?r:t},v0=e=>{let t=e[0]==="--b64"?e[1]:void 0;return pZ(t,{exec:mZ,trim:hZ,write:n=>process.stdout.write(n),writeErr:n=>process.stderr.write(n)})},S0=async()=>{let e=await Vi();if(process.platform==="win32")return 0;let t=uZ(e,{isRecognized:n=>Ly(n)!==null||Wx(n),wrap:n=>Ot(np,["--b64",Buffer.from(n,"utf8").toString("base64")])});return t&&process.stdout.write(t),0};import{createHash as yZ}from"node:crypto";import{homedir as E0}from"node:os";import{extname as gZ,isAbsolute as wZ,join as Yy,resolve as Ki,sep as I0}from"node:path";import{chmod as bZ,readFile as AZ,stat as _0,unlink as CZ,writeFile as kZ}from"node:fs/promises";var Xy=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),vZ=16*1024,x0=["path","file_path","target_file","targetFile","relative_workspace_path","relativeWorkspacePath","filePath"],SZ=["pattern","query","regex","search"],EZ=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"]),IZ=720*60*1e3,xZ=512,Jy=(e,t)=>{for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}return null},RZ=e=>Array.isArray(e)?e.filter(t=>typeof t=="string"):[],R0=(e,t)=>t.some(n=>e===n||e.startsWith(n.endsWith(I0)?n:n+I0)),OZ=(e,t,n)=>wZ(e)?[Ki(e)]:[...new Set([Ki(t,e),...n.map(r=>Ki(r,e))])],O0=(e,t,n)=>yZ("sha256").update(`${e.length}:${e}`).update(`${t.length}:${t}`).update(n).digest("hex").slice(0,32),T0=e=>JSON.stringify({permission:"deny",agent_message:e,user_message:"Anyray routed this through its context tools to keep the request small."}),TZ=async(e,t)=>{let n;try{n=JSON.parse(e)}catch{return""}if(!Xy(n))return"";let r=n.tool_name;if(r!=="Read"&&r!=="Grep")return"";let o=n.tool_input;if(!Xy(o))return"";let a=RZ(n.workspace_roots).map(d=>Ki(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=Jy(o,SZ);if(!d)return"";let u=Jy(o,x0);return u&&!R0(Ki(s,u),a)||!await t.remember(O0(i,"Grep",d))?"":T0(`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=Jy(o,x0);if(!c||EZ.has(gZ(c).toLowerCase()))return"";let l=await t.resolveFile(OZ(c,s,a));return!l||l.bytes<vZ||!R0(l.path,a)||!await t.remember(O0(i,"Read",l.path))?"":T0(`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.`)},_Z=async e=>{for(let t of e)try{let n=await _0(t);if(n.isFile())return{path:t,bytes:n.size}}catch{}return null},PZ=async()=>{let e=Yy(E0(),".anyray");try{if((await _0(e)).isDirectory())return Yy(e,"cursor-redirects.json")}catch{}return Yy(E0(),".anyray-cursor-redirects.json")},DZ=async e=>{let t;try{let n=await PZ(),r=Date.now(),o={};try{let s=JSON.parse(await AZ(n,"utf-8"));if(s?.v===1&&Xy(s.seen))for(let[i,c]of Object.entries(s.seen))typeof c=="number"&&r-c<=IZ&&(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,xZ);return t=`${n}.${process.pid}.tmp`,await kZ(t,JSON.stringify({v:1,seen:Object.fromEntries(a)}),{mode:384}),await bZ(t,384),await ye(t,n),!0}catch{if(t)try{await CZ(t)}catch{}return!1}},P0=async()=>{let e=await Vi(),t="";try{t=await TZ(e,{resolveFile:_Z,remember:DZ})}catch{t=""}return t&&process.stdout.write(t),0};import{execFileSync as UY}from"node:child_process";import{createReadStream as LZ}from"node:fs";import{spawnSync as V0}from"node:child_process";import{createHash as NZ}from"node:crypto";import{access as K0,chmod as Qy,copyFile as $Z,lstat as MZ,mkdir as BZ,mkdtemp as j0,readFile as Su,rename as FZ,rm as Nr,stat as WZ,writeFile as UZ}from"node:fs/promises";import{constants as Z0}from"node:fs";import{platform as Xa,tmpdir as HZ}from"node:os";import{dirname as GZ,isAbsolute as VZ,join as Cu}from"node:path";import{z as Me}from"zod";var KZ="fleetd-installer-v4.89.2",D0=`https://github.com/anyrayHQ/install/releases/download/${KZ}`,jZ=1e4,ZZ=1e4,L0=31,YZ=1500,Y0=20*1024,zy=20,JZ="0.25",XZ="/var/tmp",Ja="/Library/LaunchDaemons/com.fleetdm.orbit.plist",ku="/etc/default/orbit",Zi="/opt/orbit/anyray-enroll-secret.txt",J0="/opt/orbit/secret-orbit-node-key.txt",zZ="/opt/orbit/bin/orbit/orbit",Yi="C:\\Program Files\\Orbit",qZ=`${Yi}\\bin\\orbit`,X0=`${Yi}\\secret-orbit-node-key.txt`,ji=`${Yi}\\secret.txt`,QZ=`${Yi}\\fleet_url.txt`,z0=`${Yi}\\anyray-managed.txt`,vu="Fleet osquery",eg="C:\\Windows\\System32\\sc.exe",og="C:\\Windows\\System32\\whoami.exe",Au="C:\\Windows\\System32\\icacls.exe",eY="C:\\Windows\\System32\\msiexec.exe",tg="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",N0=["-NoProfile","-NonInteractive","-Command","Start-Sleep -Milliseconds 250"],tY=e=>["-NoProfile","-NonInteractive","-Command",`$s = Get-Service -Name '${e}' -ErrorAction SilentlyContinue; if ($s) { $s.Status.ToString() } else { 'absent' }`],nY=`anyray-connect endpoint install
|
|
714
714
|
|
|
715
715
|
Install Fleet's signed endpoint agent and enroll this machine in Anyray.
|
|
716
716
|
|
|
@@ -718,11 +718,11 @@ Supported on macOS, Linux and Windows.
|
|
|
718
718
|
|
|
719
719
|
The command uses the current seat's stored gateway key. Administrator access is
|
|
720
720
|
required: on macOS and Linux Connect asks through sudo once when /dev/tty is
|
|
721
|
-
available; on Windows, run it from a shell started as Administrator.`,ag=e=>!!(e.endpoint&&!e.noEndpoint&&(e.sso||e.enroll||e.claim)&&!e.revert&&!e.dryRun),q0=(e,t=Xa())=>t!=="win32"&&(e==="installed"||e==="already-enrolled"),Q0=(e,t=Xa(),n=!1)=>(ag(e)||n)&&t!=="win32",de=class extends Error{publicMessage;constructor(t){super(t),this.publicMessage=t,this.name="EndpointInstallError"}},
|
|
722
|
-
`).some(o=>r===void 0?o.startsWith(`${n}=`):o.trim()===`${n}=${r}`);return t("ORBIT_FLEET_URL")&&t("ORBIT_ENROLL_SECRET_PATH",Zi)&&!t("ORBIT_ENROLL_SECRET")&&!t("ORBIT_USE_SYSTEM_CONFIGURATION")},ng=(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()},eR=e=>{let t=e(eg,["qc",vu,"8192"]);return t.status===0?t.stdout:""},rg=e=>{let t=e(tg,
|
|
723
|
-
`&&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},
|
|
721
|
+
available; on Windows, run it from a shell started as Administrator.`,ag=e=>!!(e.endpoint&&!e.noEndpoint&&(e.sso||e.enroll||e.claim)&&!e.revert&&!e.dryRun),q0=(e,t=Xa())=>t!=="win32"&&(e==="installed"||e==="already-enrolled"),Q0=(e,t=Xa(),n=!1)=>(ag(e)||n)&&t!=="win32",de=class extends Error{publicMessage;constructor(t){super(t),this.publicMessage=t,this.name="EndpointInstallError"}},rY=Me.object({kind:Me.enum(["pkg","deb","rpm","msi"]),path:Me.string().min(1).refine(VZ),sha256:Me.string().regex(/^[0-9a-f]{64}$/)}).strict(),oY=Me.object({action:Me.literal("restart"),os:Me.enum(["darwin","linux","win32"])}).strict(),aY=Me.object({action:Me.literal("configure"),os:Me.enum(["darwin","linux","win32"]),fleetUrl:Me.string().min(1).max(2048),enrollSecret:Me.string().min(1).max(4096),package:rY.optional()}).strict(),sY=Me.discriminatedUnion("action",[oY,aY]),Ji=(e,t)=>{let n=V0(e,t,{encoding:"utf8",stdio:["ignore","pipe","pipe"],timeout:6e5,maxBuffer:1048576});return{status:n.status,stdout:typeof n.stdout=="string"?n.stdout:""}},sg=async e=>{try{return await K0(e,Z0.F_OK),!0}catch{return!1}},iY=async e=>{try{let t=await WZ(e);return t.isFile()&&t.size>0}catch{return!1}},ig=(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}},qy=(e,t)=>ig(e,t)!==null,$0=e=>e==="win32"?ji:Zi,cY=e=>e==="win32"?X0:J0,lY=e=>qy(e,"ORBIT_FLEET_URL")&&qy(e,"ORBIT_ENROLL_SECRET_PATH")&&e.includes(`<string>${Zi}</string>`)&&!qy(e,"ORBIT_USE_SYSTEM_CONFIGURATION"),dY=e=>{let t=(n,r)=>e.split(`
|
|
722
|
+
`).some(o=>r===void 0?o.startsWith(`${n}=`):o.trim()===`${n}=${r}`);return t("ORBIT_FLEET_URL")&&t("ORBIT_ENROLL_SECRET_PATH",Zi)&&!t("ORBIT_ENROLL_SECRET")&&!t("ORBIT_USE_SYSTEM_CONFIGURATION")},ng=(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()},eR=e=>{let t=e(eg,["qc",vu,"8192"]);return t.status===0?t.stdout:""},rg=e=>{let t=e(tg,tY(vu)),n=t.status===0?t.stdout.trim():"";return n.length>0?n:"absent"},uY=async e=>{try{return e==="win32"?ng(e,eR(Ji)):ng(e,await Su(e==="darwin"?Ja:ku,"utf8"))}catch{return}},pY=async e=>{try{if(e==="win32")return await sg(z0)&&ng(e,eR(Ji))!==void 0;let n=await Su(e==="darwin"?Ja:ku,"utf8");return e==="darwin"?lY(n):dY(n)}catch{return!1}},tR=async(e,t={})=>{let n=t.exists??sg,r=t.command??Ji,o,a="absent";if(e==="win32")a=rg(r),o=await n(qZ)&&a!=="absent";else{let l=e==="darwin"?await n(Ja):await n("/etc/systemd/system/orbit.service")||await n("/usr/lib/systemd/system/orbit.service");o=await n(zZ)&&l}let s=await(t.configured??pY)(e),i=await(t.hasNodeKey??(()=>iY(cY(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}},fY=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),nR=(e,t)=>{let n=ig(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]===`
|
|
723
|
+
`&&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},mY=(e,t)=>{let n=nR(e,t);return n===null?e:e.slice(0,n.start)+e.slice(n.end)},M0=(e,t,n)=>{let r=`
|
|
724
724
|
<key>${t}</key>
|
|
725
|
-
<string>${
|
|
725
|
+
<string>${fY(n)}</string>`,o=nR(e,t);if(o!==null)return e.slice(0,o.start)+r+e.slice(o.end);let a=ig(e,"EnvironmentVariables"),s=a===null?-1:e.indexOf("<dict>",a.end);if(a===null||s<0)throw new de("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)},hY=(e,t,n=Zi)=>{let r=mY(e,"ORBIT_USE_SYSTEM_CONFIGURATION");return r=M0(r,"ORBIT_FLEET_URL",t),M0(r,"ORBIT_ENROLL_SECRET_PATH",n)},yY=(e,t,n=Zi)=>{let r=new Set(["ORBIT_FLEET_URL","ORBIT_ENROLL_SECRET","ORBIT_ENROLL_SECRET_PATH","ORBIT_USE_SYSTEM_CONFIGURATION"]);return`${e.split(`
|
|
726
726
|
`).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(`
|
|
727
727
|
`).trimEnd()}
|
|
728
728
|
|
|
@@ -732,17 +732,17 @@ available; on Windows, run it from a shell started as Administrator.`,ag=e=>!!(e
|
|
|
732
732
|
# file, never in this world-readable one.
|
|
733
733
|
ORBIT_FLEET_URL=${t}
|
|
734
734
|
ORBIT_ENROLL_SECRET_PATH=${n}
|
|
735
|
-
`},rR=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}},
|
|
735
|
+
`},rR=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}},gY=Me.object({code:Me.string().min(1).optional(),message:Me.string().min(1).optional()}).passthrough(),B0=e=>{let t=e.replace(/[\u0000-\u001f\u007f-\u009f]/g," ").replace(/ {2,}/g," ").trim();return t.length>300?`${t.slice(0,299)}\u2026`:t},wY=(e,t)=>{let n=`The gateway rejected endpoint enrollment (${e}).`,r=gY.safeParse(t);if(!r.success)return n;let o=B0(r.data.message??""),a=B0(r.data.code??"");return o?a?`${n} ${o} [${a}]`:`${n} ${o}`:a?`${n} [${a}]`:n},F0=async(e,t,n={})=>{let r=new AbortController,o=setTimeout(()=>r.abort(),n.timeoutMs??ZZ),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 de("Could not reach the gateway for endpoint enrollment.")}finally{clearTimeout(o)}if(!a.ok){if(a.status===404)throw new de("This gateway does not provide endpoint enrollment yet.");let c;try{c=await a.json()}catch{c=void 0}throw new de(wY(a.status,c))}let s;try{s=await a.json()}catch{throw new de("The gateway returned malformed endpoint enrollment data.")}let i=Me.object({fleetUrl:Me.string().min(1).max(2048),enrollSecret:Me.string().min(1).max(4096)}).strict().safeParse(s);if(!i.success||!rR(i.data.fleetUrl))throw new de("The gateway returned invalid endpoint enrollment data.");return i.data},bY=async(e={})=>{let t=e.exists??sg;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 de("Linux endpoint installation requires either dpkg or rpm.")},AY=async e=>e==="darwin"?"pkg":e==="win32"?"msi":bY(),cg=e=>`fleetd.${e}`,CY=(e,t)=>e==="darwin"?t==="pkg":e==="win32"?t==="msi":t==="deb"||t==="rpm",kY=async(e,t)=>{let n=new AbortController,r=setTimeout(()=>n.abort(),jZ);try{return await t(e,{signal:n.signal})}finally{clearTimeout(r)}},vY=async(e,t={})=>{let n=cg(e),r=t.fetchResponse??fetch,o;try{o=await kY(`${D0}/SHA256SUMS`,r)}catch{throw new de("Could not read the endpoint package checksums from GitHub.")}if(o.status===404)return;if(!o.ok)throw new de(`GitHub could not provide the endpoint package checksums (${o.status}).`);let a=by(await o.text(),n);if(!a)return;let s=t.makeTempDir?await t.makeTempDir():await j0(Cu(HZ(),"anyray-endpoint-")),i=Cu(s,n);try{await Qy(s,448),await(t.download??ky)(`${D0}/${n}`,i,a)}catch(c){if(await Nr(s,{recursive:!0,force:!0}).catch(()=>{}),c instanceof Mi&&c.status===404)return;throw new de("The endpoint package download or checksum verification failed.")}return{kind:e,path:i,sha256:a,cleanup:()=>Nr(s,{recursive:!0,force:!0})}},SY=async(e,t,n)=>{await BZ(GZ(e),{recursive:!0,mode:493});let r=`${e}.anyray-${process.pid}`;await Nr(r,{force:!0});try{await UZ(r,t,{encoding:"utf8",mode:n,flag:"wx"}),await FZ(r,e)}catch(o){throw await Nr(r,{force:!0}).catch(()=>{}),o}},W0=async e=>{let t=NZ("sha256");for await(let n of LZ(e))t.update(n);return t.digest("hex")},EY=async(e,t={})=>{let n=await MZ(e.path).catch(()=>{});if(!n?.isFile()||n.isSymbolicLink())throw new de("The verified endpoint package staging file is no longer available.");if(e.kind==="msi"){if(await W0(e.path)!==e.sha256)throw new de("The endpoint package changed after verification; installation was refused.");return{package:e,cleanup:async()=>{}}}let r=t.makeTempDir?await t.makeTempDir():await j0(Cu(XZ,"anyray-endpoint-root-")),o=Cu(r,cg(e.kind));try{if(await Qy(r,448),await $Z(e.path,o),await Qy(o,384),await W0(o)!==e.sha256)throw new de("The endpoint package changed after verification; installation was refused.");return{package:{...e,path:o},cleanup:()=>Nr(r,{recursive:!0,force:!0})}}catch(a){throw await Nr(r,{recursive:!0,force:!0}).catch(()=>{}),a}},Ya=(e,t)=>{if(e.status!==0)throw new de(t)},U0="com.fleetdm.fleetd.config",IY="com.fleetdm.fleetd.enroll.secret",xY=["/opt/orbit/secret.txt","/opt/orbit/fleet_url.txt",J0],RY=[QZ,X0],OY=e=>{let t=e("/usr/bin/profiles",["show","-type","configuration"]);if(t.status===0&&t.stdout.includes(U0))throw new de(`This machine already receives its endpoint configuration from an MDM profile (${U0}), which takes precedence over anything installed here. Enrollment is managed by that profile; remove it first if this machine should enroll directly.`)},H0=async(e,t,n)=>{let r=n.removeFile??(o=>Nr(o,{force:!0}));for(let o of e==="win32"?RY:xY)await r(o).catch(()=>{});e==="darwin"&&t("/usr/bin/security",["delete-generic-password","-s",IY,"/Library/Keychains/System.keychain"])},TY=e=>{e(Au,[ji,"/inheritance:r"]),e(Au,[ji,"/grant:r","*S-1-5-18:(F)"]),e(Au,[ji,"/grant:r","*S-1-5-32-544:(F)"]),e(Au,[ji,"/remove:g","*S-1-5-32-545"])},_Y=(e,t,n)=>{if(e.kind==="pkg"){Ya(t("/usr/sbin/installer",["-pkg",e.path,"-target","/"]),"The macOS endpoint package installer failed.");return}if(e.kind==="deb"){Ya(t("dpkg",["-i",e.path]),"The Debian endpoint package installer failed.");return}if(e.kind==="rpm"){Ya(t("rpm",["-U",e.path]),"The RPM endpoint package installer failed.");return}Ya(t(eY,["/i",e.path,"/qn","/norestart",`FLEET_URL=${n}`,"ENABLE_SCRIPTS=true"]),"The Windows endpoint package installer failed.")},PY=(e,t)=>{if(e==="darwin"){t("/bin/launchctl",["bootout","system/com.fleetdm.orbit"]);let n;for(let r=0;r<zy;r++){if(n=t("/bin/launchctl",["bootstrap","system",Ja]),n.status===0)return;t("/bin/sleep",[JZ])}throw new de(`Orbit was configured, but launchd could not load the updated service definition${n?.stdout.trim()?`: ${n.stdout.trim()}`:""}.`)}if(e==="win32"){t(eg,["stop",vu]);for(let n=0;n<zy;n++){let r=rg(t);if(r==="Stopped"||r==="absent")break;t(tg,N0)}for(let n=0;n<zy;n++){if(t(eg,["start",vu]).status===0||rg(t)==="Running")return;t(tg,N0)}throw new de("Orbit was configured, but the Windows service could not be started.")}Ya(t("systemctl",["daemon-reload"]),"Orbit was configured, but systemd could not reload its units."),Ya(t("systemctl",["restart","orbit"]),"Orbit was configured, but systemd could not restart it.")},DY=e=>new Promise(t=>setTimeout(t,e)),oR=async(e,t={})=>{let n=t.command??Ji,r=t.readText??(c=>Su(c,"utf8")),o=t.writeText??SY,a=t.removeSecret??(()=>Nr($0(e.os),{force:!0})),s=!1,i;try{if(e.action==="configure"){if(e.os==="darwin"&&OY(n),e.package&&!CY(e.os,e.package.kind))throw new de("The endpoint package does not match this operating system.");if(e.os==="win32"&&!e.package)throw new de("Reconfiguring the Windows endpoint agent requires the installer package.");if(e.os==="win32"&&await H0(e.os,n,t),e.package){let d=await(t.preparePackage??EY)(e.package);i=d.cleanup,_Y(d.package,n,e.fleetUrl)}if(e.os==="darwin"){let d=await r(Ja);await o(Ja,hY(d,e.fleetUrl),420)}else if(e.os==="linux"){let d=await r(ku);await o(ku,yY(d,e.fleetUrl),420)}else await o(z0,`anyray
|
|
736
736
|
`,384);e.os!=="win32"&&await H0(e.os,n,t),await o($0(e.os),`${e.enrollSecret}
|
|
737
|
-
`,384),e.os==="win32"&&
|
|
738
|
-
anyray-connect endpoint install`),"deferred");if((t.uid??(()=>process.getuid?.()??-1))()===0)return await e(),"direct";if(await(t.ttyReadable??
|
|
739
|
-
sudo anyray-connect endpoint install`),"deferred"},
|
|
740
|
-
`;if(Buffer.byteLength(t)>Y0)throw new de("The privileged endpoint plan is unexpectedly large.");let n=nn(["__anyray-endpoint-install"]);return V0("sudo",[n.command,...n.args],{input:t,stdio:["pipe","inherit","inherit"],encoding:"utf8"}).status??1},
|
|
741
|
-
`).find(i=>i.split(":")[0]===e)?.split(":")[5];s?.startsWith("/")&&(t=s)}catch{}t??=Xa()==="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}},aR=async(e={},t={})=>{let n=t.os??Xa();if(n!=="darwin"&&n!=="linux"&&n!=="win32")throw new de("`anyray-connect endpoint install` supports macOS, Linux and Windows only.");let r=n,o=await(t.probe??tR)(r),a=!1;if(o.installed&&o.configured&&o.running&&o.checkedIn){let c=e.gateway&&e.clientKey?void 0:await(t.profile??G0)(),l=e.gateway??c?.gateway,d=e.clientKey??c?.clientKey,u=await(t.readFleetUrl??dY)(r);if(!l||!d||u===void 0)return{outcome:"already-enrolled",message:"Endpoint agent already running and enrolled; nothing to do."};let p=await(t.fetchEnrollment??F0)(l,d);if(u===p.fleetUrl)return{outcome:"already-enrolled",message:"Endpoint agent already running and enrolled; nothing to do."};L("This machine points at a different Anyray endpoint server; re-pointing it."),a=!0}if(o.installed&&o.checkedIn&&!o.configured)throw new de("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??G0)(),l=e.gateway??c?.gateway,d=e.clientKey??c?.clientKey;if(!l||!d)throw new de("No enrolled seat key is available. Run anyray-connect with --sso first, then retry endpoint install.");let u=await(t.fetchEnrollment??F0)(l.replace(/\/$/,""),d);if(!o.installed||r==="win32"){let p=await(t.packageKind??(()=>bY(r)))();if(i=await(t.stagePackage??kY)(p),!i)return{outcome:"release-unavailable",message:`Endpoint agent package ${cg(p)} 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??BY)(s)==="deferred"?{outcome:"needs-root"}:{outcome:"installed",message:"Endpoint agent is running and enrolled."}}finally{await i?.cleanup().catch(()=>{})}},lg=e=>e instanceof de?e.publicMessage:"Endpoint agent installation failed locally; no enrollment was confirmed.",sR=async e=>{if(e.length===1&&(e[0]==="--help"||e[0]==="-h"))return A(tY),0;if(e.length!==1||e[0]!=="install")return R("Usage: anyray-connect endpoint install"),1;try{let t=await aR();return t.message&&(t.outcome==="installed"?B(t.message):L(t.message)),0}catch(t){return R(lg(t)),1}},FY=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>Y0)throw new de("The privileged endpoint plan is unexpectedly large.");e.push(a)}let n;try{n=JSON.parse(Buffer.concat(e).toString("utf8"))}catch{throw new de("The privileged endpoint plan is malformed.")}let r=aY.safeParse(n);if(!r.success||r.data.os!==Xa()||r.data.action==="configure"&&!rR(r.data.fleetUrl))throw new de("The privileged endpoint plan is invalid.");return r.data},iR=async e=>{if((process.getuid?.()??-1)!==0)return R("The privileged endpoint step must run as root."),1;if(e.length!==0)return R("The privileged endpoint step does not accept arguments."),1;try{return await oR(await FY()),0}catch(t){return R(lg(t)),1}},cR=async(e,t=aR)=>{try{let n=await t(e);return n.message&&(n.outcome==="installed"?B(n.message):L(n.message)),n.outcome}catch(n){L(`Endpoint agent: ${lg(n)} Tool routing remains configured.`);return}};var UY=new Set(["darwin","win32","linux"]),HY=new Set(["S-1-5-18","S-1-5-19","S-1-5-20"]),GY=e=>{let t=e.match(/S-\d(?:-\d+)+/i)?.[0]?.toUpperCase();return t!==void 0&&!HY.has(t)},lR=(e,t)=>{let n=new Set(t);return e.filter(r=>!n.has(r.id))},dg=async e=>{try{if(!UY.has(e.platform)||e.isUserSession?.()===!1)return 0;let t=await e.loadProfile();if(t.managedEnrollmentDisabled===!0)return 0;let n=e.readManagedEnrollment().enrollmentUrl;return n?await e.runApply(["--enroll",n,"--yes"],t.revertedTools??[]):0}catch{return 1}},dR=async(e,t)=>{if(e!=="not-enrolled")return e;try{return!t.readManagedEnrollment().enrollmentUrl||(await t.loadProfile()).managedEnrollmentDisabled===!0||await dg(t)!==0?e:await t.refresh()}catch{return e}},ug=e=>({platform:process.platform,readManagedEnrollment:xo,loadProfile:P,isUserSession:()=>{try{if(process.platform==="win32"){let t=WY(og,["/user","/fo","csv","/nh"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return GY(t)}return process.getuid?.()!==0}catch{return!1}},runApply:e});var Xi=(e,t)=>{let n=e[t];return typeof n=="string"&&n?n:void 0},pg=e=>typeof e=="string"&&e.trim()?e.trim():void 0,VY=e=>{try{let t=JSON.parse(e);if(t===null||typeof t!="object"||Array.isArray(t))return null;let n=t,r=Xi(n,"deviceCode"),o=Xi(n,"privateKeyPem"),a=Xi(n,"publicKeyPem"),s=Xi(n,"cpOrigin"),i=Xi(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=pg(n.gatewayUrl),p=pg(n.gatewayOverride),m=pg(n.team);return{deviceCode:r,privateKeyPem:o,publicKeyPem:a,cpOrigin:s,tenantId:i,intervalMs:c,grantExpiresAt:l,startedAt:d,...u?{gatewayUrl:u}:{},...p?{gatewayOverride:p}:{},...m?{team:m}:{}}}catch{return null}},KY=e=>new Promise(t=>setTimeout(t,e)),jY=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})},ZY=async(e,t={})=>{let n=t.poll??vd,r=t.verify??Qt,o=t.loadProfile??P,a=t.saveProfile??ce,s=t.saveDevKey??rc,i=t.readGateState??ja,c=t.writeGateState??bu,l=t.clearGateState??h0,d=t.sleep??KY,u=t.now??Date.now,p=t.recordMint??$a,m=t.reserveMint??So,f=t.applyClaudeCode??(async I=>{await rr.apply(I,{dryRun:!1})}),h=I=>jY(I,{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},y;try{y=await n(w,{gatewayUrl:e.gatewayOverride})}catch(I){let _=I instanceof Bt?I.kind:"cp-unreachable";return await h(_),_}let g=e.gatewayOverride??y.gatewayUrl,b=await o(),k={...b,gateway:g??b.gateway,name:y.cert.payload.user||b.name,team:e.team??y.cert.payload.team??b.team,enrolledCert:y.cert,enrolledCertExpiry:y.cert.payload.expiresAt,ssoLink:`${e.cpOrigin}/sso/${e.tenantId}`,clientKey:void 0,clientKeyExpiresAt:void 0,authMode:"subscription"};try{await s(y.privateKeyPem),await a(k)}catch{return"failed"}if(!g)return await h("gateway-unreachable"),"gateway-unreachable";let C;await m();let S=(t.resolveMachineUuid??Wt)()||void 0;for(let I=0;I<3;I++)try{C=await r(g,y.cert,y.privateKeyPem,{timeoutMs:1e4,machineUuid:S});break}catch(_){if(_ instanceof lt||I===2)break;await d(1e3)}if(!C)return await h("gateway-unreachable"),"gateway-unreachable";let E={...k,gateway:g,name:C.user,team:e.team??C.team??k.team,clientKey:C.key,clientKeyExpiresAt:C.expiresAt,authMode:"subscription"};try{await a(E),await p({expiresAt:C.expiresAt});let I=Ee({origin:g,clientKey:C.key,subscription:!0,user:E.name,team:E.team});return await f(I),await l(),"enrolled"}catch{return await h("gateway-unreachable"),"failed"}},YY=async()=>{let e=[];try{for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}catch{return""}},uR=async()=>{let e=VY(await YY());if(e)try{await ZY(e)}catch{}return 0};var JY=1e4,fg=/^[\w.:-]{1,64}$/,Ht=class extends Error{kind;constructor(t,n){super(n),this.kind=t,this.name="LoginError"}},mg=e=>e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0,pR=async(e,t,n)=>{let r=new AbortController,o=setTimeout(()=>r.abort(),JY);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 Ht("gateway-unreachable","Could not reach the Anyray gateway to sign in.")}finally{clearTimeout(o)}},XY=e=>{let t=mg(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}},zY=e=>{let t=mg(e);if(t?.status!=="team_selection"||typeof t.user!="string"||!Array.isArray(t.teams))return;let n=t.teams.filter(o=>typeof o=="string"&&fg.test(o));if(n.length===0||n.length!==t.teams.length)return;let r=typeof t.default_team=="string"&&fg.test(t.default_team)?t.default_team:void 0;return{status:"team_selection",user:t.user,teams:n,...r&&{default_team:r}}},qY=e=>{let t=mg(e);if(!(t?.status!=="complete"||typeof t.key!="string"||!be(t.key)||typeof t.user!="string"||!t.user||typeof t.team!="string"||!fg.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}}},QY=e=>new Promise(t=>setTimeout(t,e)),eJ=async(e,t,n)=>{if(e.length===1)return e[0];if(!n){if(t&&e.includes(t))return t;throw new Ht("invalid-team",`Multiple teams are available (${e.join(", ")}). Re-run with --team <name>.`)}A("Available teams:"),e.forEach((i,c)=>A(` ${c+1}. ${i}`));let r=t&&e.includes(t)?t:e[0],o=await Ma("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 Ht("invalid-team","Choose one of the teams shown above.");return s},tJ=async(e,t={})=>{let n=t.fetch??fetch,r=t.now??Date.now,o=t.sleep??QY,a=t.loadProfile??P,s=t.saveProfile??ce,i=t.clearDevKey??is,c=t.chooseTeam??eJ,l=t.apply??(async y=>{await rr.apply(y,{dryRun:!1})}),d=t.log??L,u=await a(),p=Tr(e.gateway,u),m=await pR(`${p}/sso/cli/start`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"},n),f=XY(m.body);if(m.status!==200||!f)throw new Ht("login-failed","The gateway could not start SSO login.");d("Open this URL to sign in with your organization:"),d(` ${f.browser_url}`),d(`Enter this code in the browser: ${f.user_code}`),(t.openBrowser??Ua)(f.browser_url);let h=r()+f.expires_in*1e3,w=e.team?.trim()||void 0;for(;r()<h;){let y=await pR(`${p}/sso/cli/poll/${encodeURIComponent(f.id)}`,{method:"GET",headers:{"x-anyray-poll-secret":f.poll_secret,...w?{"x-anyray-team":w}:{}}},n);if(y.status===202){await o(f.interval*1e3);continue}if(y.status===401)throw new Ht("wrong-poll-secret","The gateway rejected this login session. Start a new login.");if(y.status===410)throw new Ht("expired","SSO login expired before it completed. Run anyray-connect login again.");let g=zY(y.body);if(y.status===200&&g){if(w&&!g.teams.includes(w))throw new Ht("invalid-team",`Team ${w} is not available for this account.`);w=await c(g.teams,g.default_team,e.interactive??gt());continue}let b=qY(y.body);if(y.status!==200||!b)throw new Ht("login-failed","SSO login could not be completed.");let k={...u,gateway:p,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(k),await l(Ee({origin:p,clientKey:b.key,subscription:!0,user:b.user,team:b.team})),b}throw new Ht("expired","SSO login expired before it completed. Run anyray-connect login again.")},nJ=`anyray-connect login [--gateway <url>] [--team <name>]
|
|
737
|
+
`,384),e.os==="win32"&&TY(n),s=e.os!=="win32"}PY(e.os,n);let c=t.checkIn??(async d=>{let u=await tR(d);return u.running&&u.checkedIn}),l=t.wait??DY;for(let d=0;d<(t.attempts??L0);d++){if(await c(e.os))return;d+1<(t.attempts??L0)&&await l(YZ)}throw new de("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(()=>{})}},LY=async()=>{try{return await K0("/dev/tty",Z0.R_OK),!0}catch{return!1}},NY=12288,$Y=e=>{let t=e(og,["/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>=NY},MY=async(e,t={})=>{if((t.os??Xa())==="win32")return(t.elevated??(()=>$Y(t.command??Ji)))()?(await e(),"direct"):((t.print??A)(`Administrator access is required. Open Windows Terminal or PowerShell as Administrator and run:
|
|
738
|
+
anyray-connect endpoint install`),"deferred");if((t.uid??(()=>process.getuid?.()??-1))()===0)return await e(),"direct";if(await(t.ttyReadable??LY)()){if(await(t.reexec??(async()=>1))()!==0)throw new de("Administrator access did not complete; the endpoint agent was not enrolled.");return"sudo"}return(t.print??A)(`Administrator access is required. Run:
|
|
739
|
+
sudo anyray-connect endpoint install`),"deferred"},BY=async e=>{let t=`${JSON.stringify(e)}
|
|
740
|
+
`;if(Buffer.byteLength(t)>Y0)throw new de("The privileged endpoint plan is unexpectedly large.");let n=nn(["__anyray-endpoint-install"]);return V0("sudo",[n.command,...n.args],{input:t,stdio:["pipe","inherit","inherit"],encoding:"utf8"}).status??1},FY=async(e,t={})=>(t.withRoot??MY)(()=>(t.apply??oR)(e),{...t.root,reexec:()=>(t.sudo??BY)(e)}),G0=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 Su("/etc/passwd","utf8")).split(`
|
|
741
|
+
`).find(i=>i.split(":")[0]===e)?.split(":")[5];s?.startsWith("/")&&(t=s)}catch{}t??=Xa()==="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}},aR=async(e={},t={})=>{let n=t.os??Xa();if(n!=="darwin"&&n!=="linux"&&n!=="win32")throw new de("`anyray-connect endpoint install` supports macOS, Linux and Windows only.");let r=n,o=await(t.probe??tR)(r),a=!1;if(o.installed&&o.configured&&o.running&&o.checkedIn){let c=e.gateway&&e.clientKey?void 0:await(t.profile??G0)(),l=e.gateway??c?.gateway,d=e.clientKey??c?.clientKey,u=await(t.readFleetUrl??uY)(r);if(!l||!d||u===void 0)return{outcome:"already-enrolled",message:"Endpoint agent already running and enrolled; nothing to do."};let p=await(t.fetchEnrollment??F0)(l,d);if(u===p.fleetUrl)return{outcome:"already-enrolled",message:"Endpoint agent already running and enrolled; nothing to do."};L("This machine points at a different Anyray endpoint server; re-pointing it."),a=!0}if(o.installed&&o.checkedIn&&!o.configured)throw new de("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??G0)(),l=e.gateway??c?.gateway,d=e.clientKey??c?.clientKey;if(!l||!d)throw new de("No enrolled seat key is available. Run anyray-connect with --sso first, then retry endpoint install.");let u=await(t.fetchEnrollment??F0)(l.replace(/\/$/,""),d);if(!o.installed||r==="win32"){let p=await(t.packageKind??(()=>AY(r)))();if(i=await(t.stagePackage??vY)(p),!i)return{outcome:"release-unavailable",message:`Endpoint agent package ${cg(p)} 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??FY)(s)==="deferred"?{outcome:"needs-root"}:{outcome:"installed",message:"Endpoint agent is running and enrolled."}}finally{await i?.cleanup().catch(()=>{})}},lg=e=>e instanceof de?e.publicMessage:"Endpoint agent installation failed locally; no enrollment was confirmed.",sR=async e=>{if(e.length===1&&(e[0]==="--help"||e[0]==="-h"))return A(nY),0;if(e.length!==1||e[0]!=="install")return R("Usage: anyray-connect endpoint install"),1;try{let t=await aR();return t.message&&(t.outcome==="installed"?B(t.message):L(t.message)),0}catch(t){return R(lg(t)),1}},WY=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>Y0)throw new de("The privileged endpoint plan is unexpectedly large.");e.push(a)}let n;try{n=JSON.parse(Buffer.concat(e).toString("utf8"))}catch{throw new de("The privileged endpoint plan is malformed.")}let r=sY.safeParse(n);if(!r.success||r.data.os!==Xa()||r.data.action==="configure"&&!rR(r.data.fleetUrl))throw new de("The privileged endpoint plan is invalid.");return r.data},iR=async e=>{if((process.getuid?.()??-1)!==0)return R("The privileged endpoint step must run as root."),1;if(e.length!==0)return R("The privileged endpoint step does not accept arguments."),1;try{return await oR(await WY()),0}catch(t){return R(lg(t)),1}},cR=async(e,t=aR)=>{try{let n=await t(e);return n.message&&(n.outcome==="installed"?B(n.message):L(n.message)),n.outcome}catch(n){L(`Endpoint agent: ${lg(n)} Tool routing remains configured.`);return}};var HY=new Set(["darwin","win32","linux"]),GY=new Set(["S-1-5-18","S-1-5-19","S-1-5-20"]),VY=e=>{let t=e.match(/S-\d(?:-\d+)+/i)?.[0]?.toUpperCase();return t!==void 0&&!GY.has(t)},lR=(e,t)=>{let n=new Set(t);return e.filter(r=>!n.has(r.id))},dg=async e=>{try{if(!HY.has(e.platform)||e.isUserSession?.()===!1)return 0;let t=await e.loadProfile();if(t.managedEnrollmentDisabled===!0)return 0;let n=e.readManagedEnrollment().enrollmentUrl;return n?await e.runApply(["--enroll",n,"--yes"],t.revertedTools??[]):0}catch{return 1}},dR=async(e,t)=>{if(e!=="not-enrolled")return e;try{return!t.readManagedEnrollment().enrollmentUrl||(await t.loadProfile()).managedEnrollmentDisabled===!0||await dg(t)!==0?e:await t.refresh()}catch{return e}},ug=e=>({platform:process.platform,readManagedEnrollment:xo,loadProfile:P,isUserSession:()=>{try{if(process.platform==="win32"){let t=UY(og,["/user","/fo","csv","/nh"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return VY(t)}return process.getuid?.()!==0}catch{return!1}},runApply:e});var Xi=(e,t)=>{let n=e[t];return typeof n=="string"&&n?n:void 0},pg=e=>typeof e=="string"&&e.trim()?e.trim():void 0,KY=e=>{try{let t=JSON.parse(e);if(t===null||typeof t!="object"||Array.isArray(t))return null;let n=t,r=Xi(n,"deviceCode"),o=Xi(n,"privateKeyPem"),a=Xi(n,"publicKeyPem"),s=Xi(n,"cpOrigin"),i=Xi(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=pg(n.gatewayUrl),p=pg(n.gatewayOverride),m=pg(n.team);return{deviceCode:r,privateKeyPem:o,publicKeyPem:a,cpOrigin:s,tenantId:i,intervalMs:c,grantExpiresAt:l,startedAt:d,...u?{gatewayUrl:u}:{},...p?{gatewayOverride:p}:{},...m?{team:m}:{}}}catch{return null}},jY=e=>new Promise(t=>setTimeout(t,e)),ZY=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})},YY=async(e,t={})=>{let n=t.poll??vd,r=t.verify??Qt,o=t.loadProfile??P,a=t.saveProfile??ce,s=t.saveDevKey??rc,i=t.readGateState??ja,c=t.writeGateState??bu,l=t.clearGateState??h0,d=t.sleep??jY,u=t.now??Date.now,p=t.recordMint??$a,m=t.reserveMint??So,f=t.applyClaudeCode??(async I=>{await rr.apply(I,{dryRun:!1})}),h=I=>ZY(I,{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},y;try{y=await n(w,{gatewayUrl:e.gatewayOverride})}catch(I){let _=I instanceof Bt?I.kind:"cp-unreachable";return await h(_),_}let g=e.gatewayOverride??y.gatewayUrl,b=await o(),k={...b,gateway:g??b.gateway,name:y.cert.payload.user||b.name,team:e.team??y.cert.payload.team??b.team,enrolledCert:y.cert,enrolledCertExpiry:y.cert.payload.expiresAt,ssoLink:`${e.cpOrigin}/sso/${e.tenantId}`,clientKey:void 0,clientKeyExpiresAt:void 0,authMode:"subscription"};try{await s(y.privateKeyPem),await a(k)}catch{return"failed"}if(!g)return await h("gateway-unreachable"),"gateway-unreachable";let C;await m();let S=(t.resolveMachineUuid??Wt)()||void 0;for(let I=0;I<3;I++)try{C=await r(g,y.cert,y.privateKeyPem,{timeoutMs:1e4,machineUuid:S});break}catch(_){if(_ instanceof lt||I===2)break;await d(1e3)}if(!C)return await h("gateway-unreachable"),"gateway-unreachable";let E={...k,gateway:g,name:C.user,team:e.team??C.team??k.team,clientKey:C.key,clientKeyExpiresAt:C.expiresAt,authMode:"subscription"};try{await a(E),await p({expiresAt:C.expiresAt});let I=Ee({origin:g,clientKey:C.key,subscription:!0,user:E.name,team:E.team});return await f(I),await l(),"enrolled"}catch{return await h("gateway-unreachable"),"failed"}},JY=async()=>{let e=[];try{for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}catch{return""}},uR=async()=>{let e=KY(await JY());if(e)try{await YY(e)}catch{}return 0};var XY=1e4,fg=/^[\w.:-]{1,64}$/,Ht=class extends Error{kind;constructor(t,n){super(n),this.kind=t,this.name="LoginError"}},mg=e=>e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0,pR=async(e,t,n)=>{let r=new AbortController,o=setTimeout(()=>r.abort(),XY);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 Ht("gateway-unreachable","Could not reach the Anyray gateway to sign in.")}finally{clearTimeout(o)}},zY=e=>{let t=mg(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}},qY=e=>{let t=mg(e);if(t?.status!=="team_selection"||typeof t.user!="string"||!Array.isArray(t.teams))return;let n=t.teams.filter(o=>typeof o=="string"&&fg.test(o));if(n.length===0||n.length!==t.teams.length)return;let r=typeof t.default_team=="string"&&fg.test(t.default_team)?t.default_team:void 0;return{status:"team_selection",user:t.user,teams:n,...r&&{default_team:r}}},QY=e=>{let t=mg(e);if(!(t?.status!=="complete"||typeof t.key!="string"||!be(t.key)||typeof t.user!="string"||!t.user||typeof t.team!="string"||!fg.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}}},eJ=e=>new Promise(t=>setTimeout(t,e)),tJ=async(e,t,n)=>{if(e.length===1)return e[0];if(!n){if(t&&e.includes(t))return t;throw new Ht("invalid-team",`Multiple teams are available (${e.join(", ")}). Re-run with --team <name>.`)}A("Available teams:"),e.forEach((i,c)=>A(` ${c+1}. ${i}`));let r=t&&e.includes(t)?t:e[0],o=await Ma("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 Ht("invalid-team","Choose one of the teams shown above.");return s},nJ=async(e,t={})=>{let n=t.fetch??fetch,r=t.now??Date.now,o=t.sleep??eJ,a=t.loadProfile??P,s=t.saveProfile??ce,i=t.clearDevKey??is,c=t.chooseTeam??tJ,l=t.apply??(async y=>{await rr.apply(y,{dryRun:!1})}),d=t.log??L,u=await a(),p=Tr(e.gateway,u),m=await pR(`${p}/sso/cli/start`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"},n),f=zY(m.body);if(m.status!==200||!f)throw new Ht("login-failed","The gateway could not start SSO login.");d("Open this URL to sign in with your organization:"),d(` ${f.browser_url}`),d(`Enter this code in the browser: ${f.user_code}`),(t.openBrowser??Ua)(f.browser_url);let h=r()+f.expires_in*1e3,w=e.team?.trim()||void 0;for(;r()<h;){let y=await pR(`${p}/sso/cli/poll/${encodeURIComponent(f.id)}`,{method:"GET",headers:{"x-anyray-poll-secret":f.poll_secret,...w?{"x-anyray-team":w}:{}}},n);if(y.status===202){await o(f.interval*1e3);continue}if(y.status===401)throw new Ht("wrong-poll-secret","The gateway rejected this login session. Start a new login.");if(y.status===410)throw new Ht("expired","SSO login expired before it completed. Run anyray-connect login again.");let g=qY(y.body);if(y.status===200&&g){if(w&&!g.teams.includes(w))throw new Ht("invalid-team",`Team ${w} is not available for this account.`);w=await c(g.teams,g.default_team,e.interactive??gt());continue}let b=QY(y.body);if(y.status!==200||!b)throw new Ht("login-failed","SSO login could not be completed.");let k={...u,gateway:p,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(k),await l(Ee({origin:p,clientKey:b.key,subscription:!0,user:b.user,team:b.team})),b}throw new Ht("expired","SSO login expired before it completed. Run anyray-connect login again.")},rJ=`anyray-connect login [--gateway <url>] [--team <name>]
|
|
742
742
|
|
|
743
743
|
Start browser SSO, choose a team, mint a personal gateway key, and configure
|
|
744
744
|
the subscription-backed Connect lane. In a non-interactive shell, --team may be
|
|
745
|
-
omitted only when the identity authority supplies a default or sole team.`,fR=async(e,t={})=>{let n,r;for(let o=0;o<e.length;o++){let a=e[o];if(a==="--help"||a==="-h")return A(
|
|
745
|
+
omitted only when the identity authority supplies a default or sole team.`,fR=async(e,t={})=>{let n,r;for(let o=0;o<e.length;o++){let a=e[o];if(a==="--help"||a==="-h")return A(rJ),0;if(a==="--gateway"||a==="--team"){let s=e[++o];if(!s)return R(`${a} requires a value.`),1;a==="--gateway"?n=s:r=s;continue}return R(`unknown login option: ${a}`),1}try{let o=await nJ({gateway:n,team:r},t);return B(`Signed in as ${o.user} for team ${o.team}. Your personal key was saved and configured.`),0}catch(o){if(o instanceof yt)throw o;return R(o instanceof Ht?o.message:"SSO login failed."),1}};var mR=`anyray-connect update [--check] [--auto on|off] [--json]
|
|
746
746
|
|
|
747
747
|
Keep this machine's anyray-connect binary on the published release. Runs
|
|
748
748
|
automatically about every 30 minutes; this command forces it now.
|
|
@@ -753,34 +753,34 @@ Options:
|
|
|
753
753
|
Off still accepts a release the Anyray team marks mandatory.
|
|
754
754
|
--json Emit the result as JSON.
|
|
755
755
|
--help Show this help.
|
|
756
|
-
`,
|
|
756
|
+
`,oJ=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},aJ=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"fleet-directed":return"Your organization applies Connect updates centrally. This machine does not update on its own; an administrator pushes new versions.";case"fleet-off":return"Your organization manages Connect updates outside Anyray. This machine does not download binaries; new versions arrive through your own deployment tooling.";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}.`}},hR=async e=>{let t;try{t=oJ(e)}catch(o){return R(o.message),process.stderr.write(mR),1}if(t.help)return process.stdout.write(mR),0;if(t.auto!==void 0){let o=await P();if(o.autoUpdate!==!1!==t.auto&&await ce({...o,autoUpdate:t.auto}),t.json||(B(`Automatic updates ${t.auto?"enabled":"disabled"}.`),t.auto||A("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)}
|
|
757
757
|
`),0}let n=await Va({checkOnly:t.check,force:!t.check,allowNpmMigration:!0,initiator:"human"});if(t.json){let o=await Ro();return process.stdout.write(`${JSON.stringify({...n,autoUpdate:o.autoUpdate,path:o.path,selfUpdateAvailable:o.available,selfUpdateState:o.state,fleetUpdateMode:o.fleetMode},null,2)}
|
|
758
|
-
`),n.outcome==="failed"?1:0}let r=
|
|
758
|
+
`),n.outcome==="failed"?1:0}let r=aJ(n);switch(n.outcome){case"updated":case"migrated":B(r);break;case"current":B(r);break;case"available":case"migration-available":A(r),t.check&&A(`Run ${K("anyray-connect update")} to install it.`);break;case"migration-deferred":O(r),A(v("Use the newer npm runtime until that standalone release is published."));break;case"disabled":O(r),A(`Run ${K("anyray-connect update")} to install it now, or ${K("--auto on")} to resume.`);break;case"fleet-directed":case"fleet-off":A(r),A(v("Ask your Anyray administrator if you need a newer version."));break;case"unmanaged":A(r),A(v("A copy your IT team placed is theirs to roll."));break;case"container":A(r);break;case"platform-unsupported":O(r),A(v("Keep using `npx anyray-connect@latest` on this platform."));break;case"unavailable":O(r);break;case"failed":return R(r),1}return 0};var sJ=3e3,yR=async(e={})=>{let t=e.stdout??(i=>process.stdout.write(i)),n=e.stderr??(i=>process.stderr.write(i)),r=e.latestVersion??(()=>Cy(sJ)),o=e.updateStatus??Ro;t(`anyray-connect ${ke}
|
|
759
759
|
`);let[a,s]=await Promise.all([r().catch(()=>{}),o().catch(()=>{})]);if(a&&Ga(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}
|
|
760
760
|
${i}
|
|
761
|
-
`)}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
|
|
762
|
-
`),0};import
|
|
763
|
-
`)},
|
|
764
|
-
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,
|
|
761
|
+
`)}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 iJ=e=>{if(typeof e!="string"||e.length===0||e.length>512)return!1;try{return new URL(e).protocol==="https:"}catch{return!1}},cJ=e=>typeof e=="string"&&/^[A-Za-z0-9-]{4,16}$/.test(e),lJ=async(e={})=>{try{let t=await(e.readBootstrap??xr)().catch(()=>{});if(!t)return{status:"noop"};await(e.refreshIfDue??Ut)().catch(()=>{});let n=await(e.loadProfile??P)();if(be(n.clientKey))return{status:"enrolled"};let r=await(e.ssoGate??_o)({sso:t.sso,gateway:t.gateway??n.gateway},{routingIntact:async()=>!0,applyClaudeCode:async()=>{}});if(r.exitCode===0)return n=await(e.loadProfile??P)(),be(n.clientKey)?{status:"enrolled"}:{status:"noop"};if(r.exitCode!==2||!r.stderr)return{status:"noop"};let o=await(e.readState??ja)().catch(()=>{}),a=o?.verificationUriComplete,s=o?.userCode;if(!iJ(a)||!cJ(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"}}},gR=async(e={})=>{let t=await lJ(e);return process.stdout.write(`${JSON.stringify(t)}
|
|
762
|
+
`),0};import dJ from"node:path";var uJ="2025-06-18",pJ={name:"anyray",version:"1"},wR={name:"anyray_retrieve",description:'Read back the full original of a tool output Anyray shortened. Whenever you see a marker like "\xB7 retrieve ctx_\u2026 via anyray_retrieve" or "[anyray: \u2026 ctx_\u2026]" and you need what it replaced, call this with that ctx_\u2026 handle. It is a fast lookup of bytes Anyray already stored, so prefer it over re-running the tool, re-reading the file, or searching for the same content again \u2014 those cost far more and may not reproduce it. For large outputs pass 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}},fJ=20,bR={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}},SR=dy,mJ=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,SR)},hJ=e=>e==="paths"||e==="lines"||e==="full"?e:"full",AR={name:"anyray_search",description:"Search the workspace for a string; returns matching file:line results. Use it for broad or noisy searches where relevance ranking is useful: 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-${SR}). 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}},CR={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}},yJ=8,gJ=3,kR={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}},wJ=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(`
|
|
763
|
+
`)},bJ=(e,t)=>{if(t.matches.length===0)return`No imported conversation mentions "${e}".
|
|
764
|
+
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,yJ).map(([a,s])=>{let i=s.slice(0,gJ).map(c=>` ${c.text.trim()}`);return[` ${a}`,...i].join(`
|
|
765
765
|
`)});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(`
|
|
766
766
|
`)},Ae=(e,t)=>({jsonrpc:"2.0",id:e,result:t}),hg=(e,t,n)=>({jsonrpc:"2.0",id:e,error:{code:t,message:n}}),vR=e=>e?.name??"error",ge=(e,t=!1)=>{let n=e;if(n.length>4e4){let r=t?`
|
|
767
767
|
|
|
768
768
|
[anyray: error output cut to fit the tool-result limit \u2014 ${n.length} chars total.]`:`
|
|
769
769
|
|
|
770
770
|
[anyray: output cut to fit the tool-result limit \u2014 ${n.length} chars total. Re-run narrowed (globs, a line range, or grep) to see the rest.]`,o=n.slice(0,4e4-r.length),a=o.lastIndexOf(`
|
|
771
|
-
`);n=(a>0?o.slice(0,a):o)+r}return{content:[{type:"text",text:n}],...t?{isError:!0}:{}}},
|
|
772
|
-
`+y.content))}let g=y!==null;return Ae(n??null,ge(`${i} is a hook-tee file id, not a stash handle`+(g&&w?`, and ${w} is not readable`+(y?.message?` (${y.message})`:"")+". The hook writes these files when it trims a tool output; this one has been swept, or the tee is off. Re-run the command to regenerate its output.":`. Read ${w??"the path in its footer"} directly.`),!0))}let f;try{f=await t.retrieve(i,p?{startLine:l,endLine:d,grep:u}:void 0)}catch(w){f={ok:!1,message:w instanceof Error?w.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(!f.ok)return Ae(n??null,ge(f.kind==="slice-unsupported"?h:f.message,!0));if(p&&(f.partial===void 0||typeof f.totalLines!="number"))return Ae(n??null,ge(h,!0));if(f.partial===!0&&typeof f.totalLines=="number"){let w=f.grepMatches!==void 0?`[anyray: partial \u2014 ${f.grepMatches} matching line(s) in lines ${f.startLine}-${f.endLine} of ${f.totalLines}`+(f.grepTruncated?`, windows around the first ${
|
|
773
|
-
${f.content}`))}return Ae(n??null,ge(f.content))}if(a.name===bR.name){let i=typeof s.query=="string"?s.query.trim():"";if(!i)return Ae(n??null,ge("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 Ae(n??null,l.ok?ge(
|
|
774
|
-
`)}catch{}},l=async p=>{let m=p.trim();if(!m)return;let f;try{f=JSON.parse(m)}catch{console.error("anyray mcp: dropping unparseable frame");return}let h;try{h=await
|
|
775
|
-
`))>=0;){let f=u.slice(0,m);u=u.slice(m+1),await l(f)}}u.trim()&&await l(u)}catch(p){console.error("anyray mcp: stdin error",vR(p))}finally{clearInterval(d)}return 0};import{spawn as
|
|
771
|
+
`);n=(a>0?o.slice(0,a):o)+r}return{content:[{type:"text",text:n}],...t?{isError:!0}:{}}},AJ=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 Ae(n??null,{protocolVersion:typeof e.params?.protocolVersion=="string"?e.params.protocolVersion:uJ,capabilities:{tools:{}},serverInfo:pJ});case"notifications/initialized":case"notifications/cancelled":return null;case"ping":return Ae(n??null,{});case"tools/list":{let a=[wR,bR];t.advertiseContextTools!==!1&&a.push(AR,CR);let s=!1;try{s=await t.historyAvailable()}catch{s=!1}return s&&a.push(kR),Ae(n??null,{tools:a})}case"tools/call":{let a=e.params??{},s=a.arguments??{};if(a.name===wR.name){let i=typeof s.handle=="string"?s.handle.trim():"";if(!i)return Ae(n??null,ge("handle is required",!0));let c=w=>{if(w!==void 0)return typeof w!="number"||!Number.isFinite(w)?null:Math.max(Math.round(w),1)},l=c(s.startLine),d=c(s.endLine);if(l===null||d===null)return Ae(n??null,ge("startLine/endLine must be numbers",!0));let u;if(s.grep!==void 0){if(typeof s.grep!="string"||s.grep.trim()==="")return Ae(n??null,ge("grep must be non-empty",!0));if(s.grep.length>256)return Ae(n??null,ge("grep is limited to 256 characters",!0));u=s.grep}let p=l!==void 0||d!==void 0||u!==void 0,m=Uy(i);if(m){let w=await Hy(m);if(u!==void 0)return Ae(n??null,ge(`${i} is a local hook-tee file, not a stash handle, and grep is not supported on these \u2014 re-call with startLine/endLine, or Read ${w??"the path in the footer"} directly.`,!0));let y=t.readTee?await t.readTee(m,{startLine:l,endLine:d}).catch(b=>({ok:!1,content:"",path:w??m,lines:0,truncated:!1,message:b instanceof Error?b.message:"tee read failed"})):null;if(y?.ok){let b=y.span?`lines ${y.span.startLine}-${y.span.endLine} of ${y.lines}`:`${y.lines} line(s)`,k=y.truncated&&!y.span?.partialLine&&y.span?` Continue with anyray_retrieve(handle="${i}", startLine=${y.span.endLine+1}).`:"";return Ae(n??null,ge(`[anyray: ${i} is a local hook-tee file, not a stash handle \u2014 served ${b} from ${y.teePath??w}.${k} Read that path directly next time.]
|
|
772
|
+
`+y.content))}let g=y!==null;return Ae(n??null,ge(`${i} is a hook-tee file id, not a stash handle`+(g&&w?`, and ${w} is not readable`+(y?.message?` (${y.message})`:"")+". The hook writes these files when it trims a tool output; this one has been swept, or the tee is off. Re-run the command to regenerate its output.":`. Read ${w??"the path in its footer"} directly.`),!0))}let f;try{f=await t.retrieve(i,p?{startLine:l,endLine:d,grep:u}:void 0)}catch(w){f={ok:!1,message:w instanceof Error?w.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(!f.ok)return Ae(n??null,ge(f.kind==="slice-unsupported"?h:f.message,!0));if(p&&(f.partial===void 0||typeof f.totalLines!="number"))return Ae(n??null,ge(h,!0));if(f.partial===!0&&typeof f.totalLines=="number"){let w=f.grepMatches!==void 0?`[anyray: partial \u2014 ${f.grepMatches} matching line(s) in lines ${f.startLine}-${f.endLine} of ${f.totalLines}`+(f.grepTruncated?`, windows around the first ${fJ} 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 ${f.startLine}-${f.endLine} of ${f.totalLines} \xB7 retrieve ${i} again with other lines, grep, or no params for full]`;return Ae(n??null,ge(`${w}
|
|
773
|
+
${f.content}`))}return Ae(n??null,ge(f.content))}if(a.name===bR.name){let i=typeof s.query=="string"?s.query.trim():"";if(!i)return Ae(n??null,ge("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 Ae(n??null,l.ok?ge(wJ(l.matches)):ge(l.message,!0))}if(a.name===AR.name){let i=typeof s.query=="string"?s.query.trim():"";if(!i)return Ae(n??null,ge("query is required",!0));let c=Array.isArray(s.globs)?s.globs.filter(p=>typeof p=="string"):void 0,l=mJ(s.maxResults),d=hJ(s.resultShape),u;try{u=await t.search(i,c,l)}catch(p){u={ok:!1,matches:[],truncated:!1,engine:"ripgrep",message:p instanceof Error?p.message:"search failed"}}return Ae(n??null,u.ok?ge(YI(i,u,d)):ge(u.message??"search failed",!0))}if(a.name===kR.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 Ae(n??null,d.ok?ge(iy(d)):ge(d.message??"history open failed",!0))}let c=typeof s.query=="string"?s.query.trim():"";if(!c)return Ae(n??null,ge("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 Ae(n??null,l.ok?ge(bJ(c,l)):ge(l.message??"history search failed",!0))}if(a.name===CR.name){let i=typeof s.path=="string"?s.path.trim():"";if(!i)return Ae(n??null,ge("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 Ae(n??null,l.ok?ge(iy(l)):ge(l.message??"read failed",!0))}return hg(n??null,-32602,`unknown tool: ${String(a.name)}`)}default:return r?null:hg(n??null,-32601,`method not found: ${o}`)}},CJ=async e=>{if(!e)return;let t=new AbortController,n=setTimeout(()=>t.abort(),Td);try{await fetch(`${e.origin}/connect/mcp-heartbeat`,{method:"POST",headers:Zt(e),signal:t.signal})}catch{}finally{clearTimeout(n)}},kJ=(e,t=!0)=>({retrieve:async(n,r)=>La(await e(),n,r),recall:async(n,r)=>_d(await e(),n,r),search:(n,r,o)=>Qd(n,{globs:r,...o?{maxMatches:o}:{}}),read:(n,r)=>Di(n,r),readTee:async(n,r)=>{if(Fy())return{ok:!1,content:"",path:n,lines:0,truncated:!1,message:"the hook tee is off (ANYRAY_HOOK_TEE=off)"};let o=await Hy(n);return o?{...await Di(o,{cwd:dJ.dirname(o),...r}),teePath:o}:{ok:!1,content:"",path:n,lines:0,truncated:!1,message:"not a tee id"}},historySearch:n=>zI(n),historyOpen:n=>qI(n),historyAvailable:async()=>await Wa()>0,advertiseContextTools:t,heartbeat:()=>{e().then(CJ).catch(()=>{})}}),ER=async(e="auto",t={})=>{let n=kJ(()=>nt(e),e!=="claude"),r=t.stdin??process.stdin,o=t.stdout??process.stdout,a=0,s=t.refreshTick??(()=>{let p=Date.now();p<a||(a=p+6e4,Or().catch(()=>{}))}),i=()=>{try{s()}catch{}},c=p=>{try{o.write(JSON.stringify(p)+`
|
|
774
|
+
`)}catch{}},l=async p=>{let m=p.trim();if(!m)return;let f;try{f=JSON.parse(m)}catch{console.error("anyray mcp: dropping unparseable frame");return}let h;try{h=await AJ(f,n)}catch(w){console.error("anyray mcp: dispatch error",vR(w)),h=f?.id===void 0?null:hg(f.id,-32603,"internal error")}h&&c(h),i()};i();let d=setInterval(i,30*6e4);d.unref?.();let u="";try{for await(let p of r){u+=p.toString("utf-8");let m;for(;(m=u.indexOf(`
|
|
775
|
+
`))>=0;){let f=u.slice(0,m);u=u.slice(m+1),await l(f)}}u.trim()&&await l(u)}catch(p){console.error("anyray mcp: stdin error",vR(p))}finally{clearInterval(d)}return 0};import{spawn as vJ}from"node:child_process";var SJ=e=>e==="jetbrains"||e==="windsurf"?e:void 0,EJ=async(e,t,n,r=1e4)=>{let o=await new Promise(a=>{let s="",i=!1,c=m=>{i||(i=!0,clearTimeout(l),t.off("data",d),t.off("error",u),t.off("end",p),a(m))},l=setTimeout(()=>c(void 0),r),d=m=>{s+=m.toString();let f=s.indexOf(`
|
|
776
776
|
`);f!==-1?c(s.slice(0,f)):s.length>65536&&c(void 0)},u=()=>c(void 0),p=()=>c(s.length>0?s:void 0);t.on("data",d),t.once("error",u),t.once("end",p)});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}})}
|
|
777
|
-
`),!0)}catch{return!1}},
|
|
777
|
+
`),!0)}catch{return!1}},IJ={claude:["ANTHROPIC_AUTH_TOKEN","ANTHROPIC_API_KEY"],codex:["OPENAI_API_KEY"]},xJ=(e,t,n)=>{let r=new Set(IJ[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}},IR=async(e,t,n={})=>{let r=n.stderr??process.stderr;if(e!=="claude"&&e!=="codex")return r.write(`Unknown ACP agent.
|
|
778
778
|
`),1;let o=n.platform??process.platform,a=n.environment??process.env;if(!t||!dd(t,o))return r.write(`Anyray ACP prerequisite is invalid; re-run anyray-connect with Node.js/npm available.
|
|
779
|
-
`),1;await(n.refreshIfDue??Ut)().catch(()=>{});let s=await(n.loadProfile??P)(),i=await(n.readBootstrap??xr)().catch(()=>{});if(i){let g=await(n.ssoGate??_o)({sso:i.sso,gateway:i.gateway??s.gateway},{routingIntact:async()=>!0,applyClaudeCode:async()=>{}});if(g.exitCode===2&&g.stderr)return await
|
|
780
|
-
`),1;let c=s.authMode??"auto",l=c==="auto"?await(n.detectSeatState??yn)():void 0,d=Ee({origin:s.gateway,clientKey:s.clientKey,user:s.name,team:s.team,subscription:c==="subscription",placeholder:c==="placeholder",seat:l}),u=
|
|
781
|
-
`),1;w=n.comSpec??a.ComSpec??"cmd.exe",y=["/d","/s","/c",`"${f.command}" ${f.args.join(" ")}`]}return await new Promise(g=>{let b=
|
|
782
|
-
`),g(1)}),k.once("exit",(C,S)=>{g(typeof C=="number"?C:S?1:0)})})};import{randomUUID as
|
|
783
|
-
`,"utf8"),await a.chmod(384),await Yn(a),await a.close(),a=void 0,await(t.publish??ye)(o,r)}catch(s){throw a&&await a.close().catch(()=>{}),await
|
|
779
|
+
`),1;await(n.refreshIfDue??Ut)().catch(()=>{});let s=await(n.loadProfile??P)(),i=await(n.readBootstrap??xr)().catch(()=>{});if(i){let g=await(n.ssoGate??_o)({sso:i.sso,gateway:i.gateway??s.gateway},{routingIntact:async()=>!0,applyClaudeCode:async()=>{}});if(g.exitCode===2&&g.stderr)return await EJ(g.stderr.trim(),n.stdin??process.stdin,n.stdout??process.stdout)||r.write(g.stderr),1;s=await(n.loadProfile??P)()}if(!s.gateway)return r.write(`Anyray ACP agent is not configured; run anyray-connect first.
|
|
780
|
+
`),1;let c=s.authMode??"auto",l=c==="auto"?await(n.detectSeatState??yn)():void 0,d=Ee({origin:s.gateway,clientKey:s.clientKey,user:s.name,team:s.team,subscription:c==="subscription",placeholder:c==="placeholder",seat:l}),u=SJ(n.clientTool);u&&(d.metadata.tool=u);let p=e==="claude"?"Anyray \xB7 Claude":"Anyray \xB7 Codex",m=(n.hookBinaryIsDurable??oe)(),f=zv(d,t,{mcpServer:m?Ge("profile"):void 0})[p],h=n.spawn??vJ,w=f.command,y=f.args;if(o==="win32"){if(!f.args.every(g=>g==="--yes"||/^@agentclientprotocol\/(claude-agent-acp|codex-acp)@[0-9]+(?:\.[0-9]+){2}$/.test(g)))return r.write(`Anyray ACP adapter arguments are invalid.
|
|
781
|
+
`),1;w=n.comSpec??a.ComSpec??"cmd.exe",y=["/d","/s","/c",`"${f.command}" ${f.args.join(" ")}`]}return await new Promise(g=>{let b=xJ(e,a,f.env),k=h(w,y,{env:b,stdio:"inherit",windowsHide:!0});k.once("error",()=>{r.write(`Could not start the ${e} ACP adapter.
|
|
782
|
+
`),g(1)}),k.once("exit",(C,S)=>{g(typeof C=="number"?C:S?1:0)})})};import{randomUUID as RJ}from"node:crypto";import{open as OJ,rm as TJ}from"node:fs/promises";import{join as _J}from"node:path";import{z as Re}from"zod";var Eu=Re.string().min(1).refine(e=>Number.isFinite(Date.parse(e)),"expected an ISO-8601 timestamp"),PJ=Re.enum(["reconcile","refresh","repair","status","offboard"]),yg=Re.union([Re.literal(0),Re.literal(1),Re.literal(2),Re.literal(3),Re.literal(4)]),DJ=Re.enum(["locked","required","recommended","optional"]),Iu=Re.object({schemaVersion:Re.literal(1),generatedAt:Eu,connectVersion:Re.string().min(1),fleetManaged:Re.boolean(),enrollment:Re.object({state:Re.enum(["enrolled","degraded","broken","none"]),lastRefreshAt:Eu.optional(),lastRefreshOutcome:Re.enum(["ok","failed"]).optional()}).strict(),keyExpiresAt:Eu.optional(),tools:Re.array(Re.object({id:Re.string().min(1),tier:DJ,routed:Re.boolean()}).strict()),lastVerb:Re.object({verb:PJ,exitCode:yg,at:Eu}).strict()}).strict(),xR=(e,t)=>{if(!e)return!1;let n=Date.parse(e);return Number.isFinite(n)&&n>t},LJ=(e,t,n=Date.now())=>{if(!!!(e.clientKey||e.enrolledCert||t))return"none";let o=e.enrolledCertExpiry??e.enrolledCert?.payload.expiresAt;return!e.gateway||!e.enrolledCert||!t||!xR(o,n)?"broken":!e.clientKey||e.clientKeyExpiresAt&&!xR(e.clientKeyExpiresAt,n)?"degraded":"enrolled"},NJ=e=>{let t=e.lastSuccessAt,n=e.lastAttemptAt;if(t===void 0&&n===void 0)return{};let r=Math.max(t??0,n??0);return!Number.isFinite(r)||r<=0?{}:{lastRefreshAt:new Date(r).toISOString(),lastRefreshOutcome:t!==void 0&&t>=(n??0)?"ok":"failed"}},RR=(e,t)=>e.fleetToolPolicy?.tiers?.[t]??"required",$J=async(e,t)=>{let n=new Set(e.managedTools??[]),r=new Set(e.revertedTools??[]),o=(e.fleetToolPolicy?.enabled??[]).filter(c=>{let l=RR(e,c);return l==="locked"||l==="required"||l==="recommended"&&!r.has(c)}),a=[...new Set([...n,...o])].sort();if(a.length===0)return[];let s=e.gateway,i=[];for(let c of a){let l=t(c),d=!1;if(l&&s&&l.pointsAt)try{let u=await l.detect();if(!u.installed&&!n.has(c))continue;u.installed&&(d=await l.pointsAt(s))}catch{d=!1}i.push({id:c,tier:RR(e,c),routed:d})}return i},OR=async(e,t={})=>{let n=t.now??Date.now,r=await(t.loadProfile??P)(),o=await(t.loadDevKey??Fe)().catch(()=>{}),a=await(t.readRefreshState??It)().catch(()=>({})),s={schemaVersion:1,generatedAt:new Date(n()).toISOString(),connectVersion:ke,fleetManaged:r.anyrayFleetManaged===!0,enrollment:{state:LJ(r,!!o,n()),...NJ(a)},...r.clientKeyExpiresAt&&Number.isFinite(Date.parse(r.clientKeyExpiresAt))?{keyExpiresAt:r.clientKeyExpiresAt}:{},tools:await $J(r,t.toolById??mt),lastVerb:e};return Iu.parse(s)},MJ=()=>_J(ee(),"status.json"),TR=async(e,t={})=>{let n=Iu.parse(e);await(t.ensureStateDir??et)();let r=MJ(),o=`${r}.${process.pid}.${RJ()}.tmp`,a;try{a=await OJ(o,"wx",384),await a.writeFile(`${JSON.stringify(n,null,2)}
|
|
783
|
+
`,"utf8"),await a.chmod(384),await Yn(a),await a.close(),a=void 0,await(t.publish??ye)(o,r)}catch(s){throw a&&await a.close().catch(()=>{}),await TJ(o,{force:!0}).catch(()=>{}),s}},gg=e=>e.enrollment.state==="none"||e.enrollment.state==="broken"?3:e.enrollment.state==="degraded"?4:e.tools.every(t=>t.routed)?0:4;var BJ=1e4,za=e=>e?.name??"Error",wg=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(BJ)})}catch(o){console.error(`anyray seat offboard report: ${za(o)}`)}},FJ=e=>e==="reverted"||e==="queued",xu=async(e={})=>{let t=e.loadProfile??P,n=e.clearDeviceTokenState??Wd,r=e.reportSeatOffboarded??wg,o=e.clearEnrollment??oc,a=e.recordManagedTools??Jn,s=e.markSeatOffboarded??ac,i=e.adapterById??mt,c=e.uninstallScheduler??sr,l=e.unitsPresent??Rc,d=e.saveProfile??ce,u=await t(),p=u.managedTools??[];await r(u).catch(()=>{}),await n().catch(()=>{});let m=!1,f=!1;try{m=await o()}catch(C){f=!0,console.error(`anyray offboard: clearing enrollment: ${za(C)}`)}let h=[],w=[],y=[];for(let C of p){let S=i(C);if(!S){y.push(C);continue}try{let E=await S.revert({dryRun:!1,fullRevert:!0});h.push({id:C,status:E.status}),FJ(E.status)?w.push(C):y.push(C)}catch(E){console.error(`anyray offboard: reverting ${C}: ${za(E)}`),y.push(C)}}let g=!0;try{await a(h,!0,!0)}catch(C){g=!1,console.error(`anyray offboard: recording managed tools: ${za(C)}`)}let b=y.length===0&&g,k=!1;if(b)try{await s(),k=!0}catch(C){console.error(`anyray offboard: stamping offboard: ${za(C)}`)}try{((await t()).refreshSchedulerEnabled||await l())&&await c(),await d({...await t(),refreshSchedulerEnabled:!1})}catch(C){console.error(`anyray offboard: unit teardown: ${za(C)}`)}return{reverted:w,unresolved:y,enrollmentCleared:m,credentialHeld:f,recordPersisted:g,offboardMarked:k,ok:y.length===0&&!f&&g&&k}};var ue={success:0,unexpected:1,usage:2,authBroken:3,partial:4},WJ=`Stable non-interactive runtime commands:
|
|
784
784
|
anyray-connect reconcile
|
|
785
785
|
anyray-connect refresh
|
|
786
786
|
anyray-connect repair
|
|
@@ -796,12 +796,12 @@ Exit codes:
|
|
|
796
796
|
1 unexpected error
|
|
797
797
|
2 usage error (unknown flag or argument)
|
|
798
798
|
3 authentication broken; re-enrollment required
|
|
799
|
-
4 partial; the command ran but drift remains`,
|
|
799
|
+
4 partial; the command ran but drift remains`,UJ={reconcile:"reconcile",__anyray_reconcile:"reconcile",refresh:"refresh",__anyray_refresh:"refresh",repair:"repair",__anyray_repair:"repair",status:"status",__anyray_status:"status",offboard:"offboard",__anyray_offboard:"offboard"},HJ=e=>e.replaceAll("-","_"),DR=e=>{let t=e[0];if(!t)return;let n=UJ[HJ(t)];if(!n)return;let r=e.slice(1);if(n==="status"&&t==="status"&&!r.includes("--json"))return;if(r.length===1&&(r[0]==="--help"||r[0]==="-h"))return{verb:n,help:!0,usageError:!1};let a=n==="status"?t==="status"?r.length===1&&r[0]==="--json":r.length===0||r.length===1&&r[0]==="--json":r.length===0;return{verb:n,help:!1,usageError:!a}},bg=e=>{let t=e?.name;return typeof t=="string"&&/^[A-Za-z][A-Za-z0-9]{0,63}$/.test(t)?t:"Error"},GJ=async(e=P,t=Date.now())=>{let n=await e(),r=Date.parse(n.enrolledCertExpiry??n.enrolledCert?.payload.expiresAt??""),o=!!n.enrolledCert&&Number.isFinite(r)&&r>t,a=Date.parse(n.clientKeyExpiresAt??""),s=n.clientKeyExpiresAt!==void 0&&(!Number.isFinite(a)||a<=t);if(!n.gateway)return"auth-broken";if(!n.clientKey||s)return o?"credential-degraded":"auth-broken";try{let i=await _a(n.gateway,n.clientKey);return await Pa(i)}catch(i){if(kh(i))return o?"credential-degraded":"auth-broken";throw i}},VJ=e=>e==="auth-broken"?ue.authBroken:e==="credential-degraded"||e.toolsApplied<e.toolsRequested||e.toolsTombstoned.length>0?ue.partial:ue.success,KJ=e=>e.refresh==="not-enrolled"||e.refresh==="cert-expired"||e.refresh==="cert-rejected"?ue.authBroken:e.refresh==="failed"?ue.unexpected:e.partial||e.refresh==="disabled"||e.refresh==="backoff"||e.refresh==="throttled"||e.refresh==="gateway-incompatible"?ue.partial:ue.success,jJ=e=>!e.enrollment.enrolled||e.enrollment.expired===!0||e.verify?.kind==="enrollment-required",_R=async e=>{let t;return{code:await pu({repair:e,quick:!e,silent:!0},{captureReport:r=>t=r}),authBroken:t?jJ(t):!1}},PR=e=>typeof e!="number"&&e.authBroken?ue.authBroken:(typeof e=="number"?e:e.code)===0?ue.success:ue.partial,ZJ=(e,t)=>{let n=gg(t);return n===ue.authBroken?n:e!==0||n===ue.partial?ue.partial:ue.success},YJ=async(e,t)=>{if(e==="reconcile")return VJ(await(t.reconcile??(()=>GJ(t.loadProfile)))());if(e==="refresh"){if(!t.refresh)throw new Error("refresh runtime is unavailable");return KJ(await t.refresh())}return e==="repair"?PR(await(t.repair??(()=>_R(!0)))()):e==="status"?PR(await(t.status??(()=>_R(!1)))()):(await(t.offboard??xu)()).ok?ue.success:ue.partial},Ag=(e,t)=>Iu.parse({...e,lastVerb:{...e.lastVerb,exitCode:t}}),LR=async(e,t={})=>{let n=t.stdout??console.log,r=t.stderr??console.error;if(e.help)return n(WJ),ue.success;let o=t.now??Date.now,a=new Date(o()).toISOString(),s=t.withProfileLock??cs,i=t.buildStatus??OR,c=t.writeStatus??TR,l,d=e.usageError?ue.usage:ue.unexpected;e.usageError&&r(`anyray-connect ${e.verb}: UsageError`);try{await s(async()=>{if(!e.usageError)try{d=yg.parse(await YJ(e.verb,t))}catch(u){d=kh(u)?ue.authBroken:ue.unexpected,r(`anyray-connect ${e.verb}: ${bg(u)}`)}if(l=await i({verb:e.verb,exitCode:d,at:a},{now:o}),(e.verb==="repair"||e.verb==="status")&&d!==ue.unexpected&&d!==ue.usage&&d!==ue.authBroken)d=ZJ(d===0?0:1,l);else if(e.verb!=="offboard"&&d!==ue.unexpected&&d!==ue.usage){let u=gg(l);(u===ue.authBroken||d===ue.success)&&(d=u)}l=Ag(l,d);try{await c(l)}catch(u){d=ue.unexpected,l=Ag(l,d),r(`anyray-connect ${e.verb}: ${bg(u)}`)}})}catch(u){d=ue.unexpected,r(`anyray-connect ${e.verb}: ${bg(u)}`);try{l=Ag(await i({verb:e.verb,exitCode:d,at:a},{now:o}),d)}catch{l=void 0}}return n(JSON.stringify(l||{schemaVersion:1,generatedAt:a,connectVersion:"unknown",fleetManaged:!1,enrollment:{state:"broken"},tools:[],lastVerb:{verb:e.verb,exitCode:d,at:a}})),d};var JJ=new Set(["not-due","repaired","cert-renewed","heartbeat-refreshed","refreshed"]),NR=async(e,t={})=>await(t.fleetdPresent??To)()?JJ.has(e)?{retired:!0,messages:(await(t.uninstallScheduler??sr)()).messages}:{retired:!1,reason:"refresh-unhealthy",messages:[]}:{retired:!1,reason:"no-fleetd",messages:[]};var $R=["reapply_config","remint","revert","revert_tool","update"],XJ=/^[a-z0-9][a-z0-9-]{0,31}$/;var zJ=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"||!$R.includes(t.kind)?!1:t.kind==="revert_tool"?typeof t.tool=="string"&&XJ.test(t.tool):t.tool===void 0},Cg=e=>e?.name??"error",MR=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":$R.join(",")},signal:AbortSignal.timeout(1e4)});if(i.status===404||!i.ok)return null;let c=await i.json();if(!zJ(c.directive))return null;a=c.directive}catch(i){return console.error("connect directive pull skipped:",Cg(i)),null}let s;try{s=await n.execute(a.kind,a.tool)}catch(i){console.error("connect directive execution failed:",Cg(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:",Cg(i))}return a.kind};var BR=e=>e?.name??"Error",FR=async(e,t={})=>{if(!e)return"failed";let n=t.loadProfile??P,r=t.recordManagedTools??Jn,o=t.adapterById??mt,a=t.isLocked??bi,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}: ${BR(l)}`),"failed"}try{await r([{id:e,status:c}],!0,!1)}catch(l){return console.error(`anyray revert-tool: recording ${e}: ${BR(l)}`),"failed"}return c==="reverted"||c==="queued"?"ok":"failed"};import{basename as qJ}from"node:path";import{join as WR}from"node:path";var QJ="history.recentlyOpenedPathsList",e5={"ssh-remote":"ssh","dev-container":"devcontainer","attached-container":"attached-container",wsl:"wsl",codespaces:"codespace",tunnel:"tunnel"},t5=e=>{try{let t=JSON.parse(Buffer.from(e,"hex").toString("utf-8"));if(typeof t.hostPath=="string"&&t.hostPath)return{name:qJ(t.hostPath),hostPath:t.hostPath};if(typeof t.containerName=="string"&&t.containerName)return{name:t.containerName.replace(/^\//,"")}}catch{}return{name:"container"}},n5=e=>{let t=/^vscode-remote:\/\/([^/]+)/.exec(e);if(!t)return;let n;try{n=decodeURIComponent(t[1])}catch{return}let r=n.indexOf("+");if(r<=0)return;let o=e5[n.slice(0,r)];if(!o)return;let a=n.slice(r+1);if(a){if(o==="devcontainer"||o==="attached-container"){let s=t5(a);return{kind:o,name:s.name,...o==="devcontainer"&&s.hostPath?{ref:s.hostPath}:{}}}return{kind:o,name:a}}},r5=e=>{let t;try{t=JSON.parse(e).entries}catch{return[]}if(!Array.isArray(t))return[];let n=[],r=new Set;for(let o of t){if(typeof o!="object"||o===null)continue;let a=o,s=[a.folderUri,a.fileUri,a.workspace?.configPath].filter(i=>typeof i=="string");for(let i of s){let c=n5(i);if(!c)continue;let l=`${c.kind}|${c.ref??c.name}`;r.has(l)||(r.add(l),n.push(c))}}return n},o5=()=>[...eo.map(e=>WR(sl(e),"User","globalStorage","state.vscdb")),WR(Ne("Cursor"),"User","globalStorage","state.vscdb")],kg=async(e={})=>{let t=e.readItem??(()=>{let o=lr();return o?o.readItem.bind(o):void 0})();if(!t)return[];let n=[],r=new Set;for(let o of e.dbPaths??o5()){let a;try{a=t(o,QJ)}catch{continue}if(a)for(let s of r5(a)){let i=`${s.kind}|${s.ref??s.name}`;r.has(i)||(r.add(i),n.push(s))}}return n};import{execFile as a5,spawn as s5}from"node:child_process";import{promisify as i5}from"node:util";var c5="https://app.anyray.ai/connect.sh",l5=".anyray/bin/anyray-connect",qa=e=>`'${e.replaceAll("'",`'"'"'`)}'`,d5=e=>{let n=`${["set -eu","if command -v anyray-connect >/dev/null 2>&1; then"," command -v anyray-connect"," exit 0","fi",`ANYRAY_CONNECT_TAG=${qa(`connect-v${ke}`)} \\`,` sh -c ${qa(`curl -fsSL ${c5} | sh`)} >&2 </dev/null`,`echo "$HOME/${l5}"`].join(`
|
|
800
800
|
`)}
|
|
801
|
-
`;switch(e.kind){case"ssh":return{command:"ssh",args:["-T","--",e.name,"sh","-s"],stdin:n};case"devcontainer":return{command:"docker",args:["exec","-i",e.name,"sh","-s"],stdin:n};case"wsl":return{command:"wsl.exe",args:["-d",e.name,"--","sh","-s"],stdin:n};case"codespace":return{command:"gh",args:["codespace","ssh","-c",e.name,"--","sh -s"],stdin:n}}},
|
|
802
|
-
`;switch(e.kind){case"ssh":return{command:"ssh",args:["-T","--",e.name,o],stdin:a};case"devcontainer":return{command:"docker",args:["exec","-i",e.name,...r],stdin:a};case"wsl":return{command:"wsl.exe",args:["-d",e.name,"--",...r],stdin:a};case"codespace":return{command:"gh",args:["codespace","ssh","-c",e.name,"--",o],stdin:a}}},
|
|
803
|
-
`).map(s=>s.trim()).filter(Boolean);if(a.length===0)throw new Error("No running dev container matches the discovered workspace.");if(a.length>1)throw new Error(`${a.length} running dev containers match this workspace; stop the stale one (docker ps --filter label=devcontainer.local_folder=...) and re-run.`);return a[0]},UR=(e,t,n)=>new Promise(r=>{let o;try{o=t(e.command,e.args,{stdio:["pipe",n?"pipe":"inherit","inherit"]})}catch{r({code:1,stdout:""});return}let a="",s=!1,i=c=>{s||(s=!0,r({code:c,stdout:a}))};if(o.stdout?.on("data",c=>{a+=c.toString("utf-8")}),o.once("error",()=>i(1)),o.once("close",c=>i(c??1)),!o.stdin){i(1);return}o.stdin.end(e.stdin)}),Sg=async(e,t,n={})=>{let r=n.spawn??
|
|
804
|
-
`).map(c=>c.trim()).filter(Boolean).at(-1);return s?(await UR(
|
|
801
|
+
`;switch(e.kind){case"ssh":return{command:"ssh",args:["-T","--",e.name,"sh","-s"],stdin:n};case"devcontainer":return{command:"docker",args:["exec","-i",e.name,"sh","-s"],stdin:n};case"wsl":return{command:"wsl.exe",args:["-d",e.name,"--","sh","-s"],stdin:n};case"codespace":return{command:"gh",args:["codespace","ssh","-c",e.name,"--","sh -s"],stdin:n}}},u5=(e,t,n)=>{let r=[n,"--yes","--key-stdin","--gateway",t.gateway,...t.user!==void 0?["--user",t.user]:[],...t.team!==void 0?["--team",t.team]:[]],o=[qa(n),"--yes","--key-stdin","--gateway",qa(t.gateway),...t.user!==void 0?["--user",qa(t.user)]:[],...t.team!==void 0?["--team",qa(t.team)]:[]].join(" "),a=`${t.clientKey}
|
|
802
|
+
`;switch(e.kind){case"ssh":return{command:"ssh",args:["-T","--",e.name,o],stdin:a};case"devcontainer":return{command:"docker",args:["exec","-i",e.name,...r],stdin:a};case"wsl":return{command:"wsl.exe",args:["-d",e.name,"--",...r],stdin:a};case"codespace":return{command:"gh",args:["codespace","ssh","-c",e.name,"--",o],stdin:a}}},p5=i5(a5),f5=async(e,t)=>(await p5(e,[...t],{encoding:"utf8"})).stdout.toString(),vg=async(e,t={})=>{let n=typeof e=="string"?{name:e}:e,r=n.ref??(/[/\\]/.test(n.name)?n.name:void 0);if(!r)throw new Error("Cannot resolve a dev container by its bare name; use its full host path.");let a=(await(t.exec??f5)("docker",["ps","--filter",`label=devcontainer.local_folder=${r}`,"--format","{{.ID}}"])).split(`
|
|
803
|
+
`).map(s=>s.trim()).filter(Boolean);if(a.length===0)throw new Error("No running dev container matches the discovered workspace.");if(a.length>1)throw new Error(`${a.length} running dev containers match this workspace; stop the stale one (docker ps --filter label=devcontainer.local_folder=...) and re-run.`);return a[0]},UR=(e,t,n)=>new Promise(r=>{let o;try{o=t(e.command,e.args,{stdio:["pipe",n?"pipe":"inherit","inherit"]})}catch{r({code:1,stdout:""});return}let a="",s=!1,i=c=>{s||(s=!0,r({code:c,stdout:a}))};if(o.stdout?.on("data",c=>{a+=c.toString("utf-8")}),o.once("error",()=>i(1)),o.once("close",c=>i(c??1)),!o.stdin){i(1);return}o.stdin.end(e.stdin)}),Sg=async(e,t,n={})=>{let r=n.spawn??s5,o=e.kind==="devcontainer"&&e.ref?{...e,name:await vg(e,n)}:e,a=await UR(d5(o),r,!0);if(a.code!==0)return a.code;let s=a.stdout.split(`
|
|
804
|
+
`).map(c=>c.trim()).filter(Boolean).at(-1);return s?(await UR(u5(o,t,s),r,!1)).code:1};import{spawnSync as m5}from"node:child_process";import{platform as Tu}from"node:os";import{basename as h5}from"node:path";import{createInterface as y5}from"node:readline";var GR=`${K("anyray-connect")} \u2014 point your local coding tools at the Anyray gateway
|
|
805
805
|
|
|
806
806
|
${K("Usage")}
|
|
807
807
|
npx anyray-connect [options]
|
|
@@ -1056,22 +1056,22 @@ ${K("What it does")}
|
|
|
1056
1056
|
key stays server-side (ANYRAY_PROVIDER_KEY_*); your tools never hold it. Only
|
|
1057
1057
|
metadata (user/team) is attached \u2014 never prompt content.
|
|
1058
1058
|
~/.anyray (mode 600) remembers your gateway, name/team, personal key, and the
|
|
1059
|
-
per-skill versions ${v("sync")} last wrote \u2014 for zero-question re-runs.`,
|
|
1060
|
-
${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?`}`,
|
|
1061
|
-
${o} ${n} tool target(s)?`;return await(r.confirm??Io)(a)?"proceed":"declined"},U5=async(e=Va)=>{let t=await e({force:!0,respectFailureBackoff:!0,allowNpmMigration:!0,initiator:"directive"});switch(t.outcome){case"current":case"updated":case"migrated":case"container":case"unmanaged":return"ok";case"available":case"migration-available":case"migration-deferred":case"disabled":case"platform-unsupported":case"unavailable":case"failed":return"failed";case"fleet-off":return"failed";case"fleet-directed":return"failed";default:return t.outcome}},JR=(e,t)=>qR(e,!1,{managedEnrollmentRevertedTools:t}),H5=()=>dg(ug(JR)),G5=async()=>{let e=!1,t=await dR(await Ut({runAmbientSelfcheck:!0}),{...ug(JR),refresh:()=>Ut({})});await bp(),await HE(),await GE()==="retry"&&(e=!0);let n=await P().catch(()=>{});if(n&&process.env.ANYRAY_FLEET_MANAGED==="1"&&!n.anyrayFleetManaged){n.anyrayFleetManaged=!0;try{await ce(n)}catch{e=!0}}let r=n?.anyrayFleetManaged===!0&&await To().catch(()=>!1);if(n&&(await NR(t,{fleetdPresent:async()=>r}).catch(()=>{}),r&&n.gateway&&n.clientKey)){let o=n.gateway,a=n.clientKey,s=Wt(),i=n.enrolledCert;if(s&&i){let l=await Fe().catch(()=>{});l&&await OS(o,a,i,l,s).catch(()=>{})}await MR(o,a,{execute:async(l,d)=>{let u;return l==="remint"||l==="reapply_config"?u=await Ut({force:!0})==="failed"?"failed":"ok":l==="revert_tool"?u=await FR(d):l==="update"?u=await U5():u=(await xu()).ok?"ok":"failed",u==="failed"&&(e=!0),u}}).catch(()=>{})}return r||await Va(),{refresh:t,...e?{partial:!0}:{}}},V5=async e=>{if(e[0]==="__anyray-hook"){let r=e[1]==="cursor"||e[1]==="opencode"?e[1]:"claude";return p0(r)}if(e[0]==="__anyray-codex-hook")return f0();if(e[0]==="__anyray-prompt-hook")return A0();if(e[0]==="__anyray-shell-pretool")return S0();if(e[0]==="__anyray-shell-run")return v0(e.slice(1));if(e[0]==="__anyray-read-pretool")return P0();if(e[0]==="__anyray-sso-gate")return b0(e.slice(1));if(e[0]==="__anyray-sso-poll")return uR();if(e[0]==="__anyray-managed-enroll")try{return await cs(H5,{waitMs:YR})}catch{return 1}if(e[0]==="__anyray-vscode-gate")return gR();if(e[0]==="__anyray-spawn-refresh")return await Or(),0;if(e[0]==="__anyray-mcp-server"){let r=e[1]==="claude"||e[1]==="profile"?e[1]:"auto";return ER(r)}if(e[0]==="__anyray-acp-agent")return IR(e[1],e[2],{clientTool:e[3]});if(e[0]==="__anyray-endpoint-install")return iR(e.slice(1));let t=DR(e);if(t)return LR(t,{refresh:G5});if(e[0]==="__anyray-persistence")return Bw(e.slice(1));if(e[0]==="__anyray-quit-watch")return dS(e.slice(1));if(e[0]===kr)return mI(e.slice(1));if(e[0]===Qs)return yI(e.slice(1));if(e[0]===Zr){let r=e[1];return r&&await Jd(r),0}if(e[0]==="--version"||e[0]==="-V")return yR();try{let r=await ow(e);if(r!==void 0)return r}catch(r){return R(`Could not persist anyray-connect for long-lived integrations: ${r instanceof Error?r.message:String(r)}`),1}if(B5(e)){let r=M5(await Ax());r?.level==="warn"?O(r.message):r&&console.error(r.message)}if(e[0]==="managed")return JS(e.slice(1));if(e[0]==="endpoint")return sR(e.slice(1));if(e[0]==="print-key")return ZE(e.slice(1));if(e[0]==="models")return JE(e.slice(1));if(e[0]==="copilot-login")return XE(e.slice(1));if(e[0]==="desktop"){let r=e.slice(1),o=oy(r);return o?Ig(o,!1):FI(r)}if(e[0]==="retrieve")return UI(e.slice(1));if(e[0]==="recall")return HI(e.slice(1));if(e[0]==="history")return ex(e.slice(1));if(e[0]==="migrate")return nx(e.slice(1));if(e[0]==="login")return fR(e.slice(1));if(e[0]==="update")return hR(e.slice(1));if(e[0]==="remote")return Q5(e.slice(1));let n=e[0];if(n&&N5.has(n)){let r=e.slice(1),o;try{o=xg(r)}catch(a){return R(a.message),A("\nRun `npx anyray-connect --help` for usage."),1}return o.help?(A(o.helpAll?Ou:GR),0):n==="status"?xx({gateway:o.gateway}):n==="doctor"?pu({gateway:o.gateway,json:o.json,verify:o.verify,noVerify:o.noVerify,quick:o.quick,repair:o.repair,securityReview:o.securityReview}):n==="sync"?Lx({gateway:o.gateway}):n==="device-url"?tI():Ig(r,!0)}return Ig(e,!1)},XR=async e=>{try{return await V5(e)}catch(t){if(t instanceof yt)return console.error(v("Cancelled.")),130;throw t}},K5=e=>{let t=process.platform==="win32"?"where":"which";try{return f5(t,[e],{stdio:"ignore"}).status===0}catch{return!1}},j5=(e,t={})=>{let n=t.which??K5,r=t.platform??Tu;switch(e.kind){case"ssh":return!0;case"devcontainer":return n("docker");case"wsl":return r()==="win32"&&n("wsl.exe");case"codespace":return n("gh")}},Z5=e=>{switch(e.kind){case"ssh":case"devcontainer":case"wsl":case"codespace":return{kind:e.kind,name:e.name,...e.kind==="devcontainer"&&e.ref?{ref:e.ref}:{}};case"attached-container":case"tunnel":return}},Y5=(e,t)=>{switch(e.kind){case"ssh":return`Configure \`${t}\` over SSH now?`;case"devcontainer":return`Configure \`${t}\` in this dev container now?`;case"wsl":return`Configure \`${t}\` in WSL now?`;case"codespace":return`Configure Codespace \`${t}\` now?`}},J5=e=>e.interactive&&!e.managed&&!e.yes&&!e.revert&&!e.dryRun,X5=async(e,t={})=>{if(!J5(e)||!be(e.clientKey))return;let n=t.discoverRemoteEnvironments??kg,r;try{r=await n()}catch{return}let o=t.confirm??Io,a=t.runRemoteApply??Sg,s=t.isCarrierAvailable??j5,i=t.resolveDevcontainer??vg;for(let c of r){let l=Z5(c);if(!l)continue;let d=l;try{if(!await s(d))continue;d.kind==="devcontainer"&&(d={kind:"devcontainer",name:await i(d)})}catch{continue}if(!await o(Y5(d,c.name)))continue;let u=await a(d,{gateway:e.gateway,user:e.user,team:e.team,clientKey:e.clientKey});if(u===0){L(`Remote \`${c.name}\` exited with code 0.`);continue}O(`Remote \`${c.name}\` exited with code ${u}.`),L(zR(d.kind))}},zR=e=>{switch(e){case"ssh":return"Fix: ssh in and run `anyray-connect doctor`.";case"devcontainer":return"Fix: open a shell in the container and run `anyray-connect doctor`.";case"wsl":return"Fix: open the distro and run `anyray-connect doctor`.";case"codespace":return"Fix: `gh codespace ssh` in and run `anyray-connect doctor`."}},z5="usage: anyray-connect remote <ssh-host> [--yes] [--dry-run] | remote --devcontainer <host-path> | --wsl <distro> | --codespace <name> [--yes] [--dry-run]",q5=e=>{let t=/[/\\]/.test(e);return{kind:"devcontainer",name:t?m5(e.replaceAll("\\","/")):e,...t?{ref:e}:{}}},Q5=async(e,t={})=>{if(e[0]==="--help"||e[0]==="-h")return console.log(Ou),0;let n=e[0]&&!e[0].startsWith("-")?e[0]:void 0,r;try{r=xg(n?e.slice(1):e)}catch(h){return R(h instanceof Error?h.message:String(h)),1}if(r.help)return console.log(Ou),0;let o=[r.devcontainer,r.wsl,r.codespace].filter(h=>h!==void 0);if(n&&o.length>0||!n&&o.length!==1)return R(z5),1;let a=n?{kind:"ssh",name:n}:r.devcontainer!==void 0?q5(r.devcontainer):r.wsl!==void 0?{kind:"wsl",name:r.wsl}:{kind:"codespace",name:r.codespace};if(a.kind==="devcontainer"&&!a.ref)return R("Cannot resolve a dev container by its bare name; use its full host path."),1;if(a.kind==="wsl"&&(t.platform??Tu)()!=="win32")return R("--wsl is available only on Windows (win32)."),1;let s=t.isInteractive??gt;if(!r.yes&&!s())return R("remote requires a TTY; pass --yes only when you explicitly intend to configure that target."),1;if(r.revert||r.enroll||r.sso||r.claim||r.project||r.upstream||r.upstreamKey)return R("remote supports --gateway, --user, --team, --yes, --dry-run, and --key-stdin only."),1;if(r.dryRun)return L(`Dry run: would configure \`${a.name}\` remotely.`),0;let i;if(r.keyStdin)try{i=await VR()}catch{return R("could not read the personal gateway key from stdin."),1}let c=await(t.loadProfile??P)(),l=!r.gateway&&!process.env.ANYRAY_GATEWAY_URL?c.gateway:void 0,d=Kt(r.gateway??l),u=i||process.env.ANYRAY_CLIENT_KEY?.trim()||KR(c);if(!be(u))return R("A personal gateway key is required. Enroll locally first or provide ANYRAY_CLIENT_KEY (or --key-stdin)."),1;let p=await jh(r.user,c.name,r.yes),m=await Zh(r.team,c.team,r.yes),f;try{f=await(t.runRemoteApply??Sg)(a,{gateway:d,user:p,team:m,clientKey:u})}catch(h){return R(h instanceof Error?h.message:String(h)),1}return f===0?L(`Remote \`${a.name}\` exited with code 0.`):(O(`Remote \`${a.name}\` exited with code ${f}.`),L(zR(a.kind))),f},qR=async(e,t,n={})=>{let r=n.isInteractive??gt,o;try{o=xg(e)}catch(D){return R(D.message),A("\nRun `npx anyray-connect --help` for usage."),1}if(o.help)return A(o.helpAll?Ou:GR),0;if(o.revert&&(o.sso||o.enroll||o.claim))return R("--revert cannot be combined with --sso, --enroll or --claim. 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?(R("--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):pI({gateway:o.gateway,tools:o.tools,revert:o.revert,dryRun:o.dryRun,yes:o.yes});if(!!o.upstream!=!!o.upstreamKey)return R("--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 R("--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 D;try{D=new URL(o.upstream.trim())}catch{return R(`invalid --upstream URL: "${o.upstream}"`),1}if(D.protocol!=="http:"&&D.protocol!=="https:")return R(`invalid --upstream URL: "${o.upstream}" \u2014 must start with http:// or https://`),1;let $=o.upstreamKey.trim();if(!$)return R("--upstream-key must not be empty."),1;a={url:Vt(o.upstream),key:$}}let s=await P(),i;if(o.keyStdin)try{i=await VR()}catch{return R("could not read the personal gateway key from stdin."),1}!a&&!o.subscription&&!o.placeholder&&!o.revert&&(a=s.byoUpstream);let c=!t&>()&&!o.gateway&&!o.revert&&!o.yes&&!o.dryRun&&!o.enroll&&!o.sso,l=!1;(t||c)&&r()&&(o=await(n.runWizard??P5)(o,s),l=!0);let d;try{if(d=g5(o.tools),n.managedEnrollmentRevertedTools){let D=[...n.managedEnrollmentRevertedTools,...s.revertedTools??[]];d=lR(d,D)}}catch(D){return R(D.message),1}A(K(o.revert?"Anyray connect \u2014 revert":"Anyray connect")),o.gateway&&!o.enroll&&gi(o.gateway)&&(o.enroll=o.gateway,o.gateway=void 0,A("That looks like an enrollment link \u2014 treating it as --enroll."));let u,p,m,f,h=!1;if(o.enroll){let D=Ad(o.enroll);if(D&&(!o.gateway||s.enrolledCert||sh(D.token)))try{let $=await Ni("Resolving enrollment link\u2026",()=>kS(D)),X=!o.gateway;X&&(o.gateway=$.gatewayUrl),u=$.deploymentId,p=$.email,m=$.provisioningKind,f=$.allowedDomains,h=!0,X&&L(`Enrollment link${$.org?` for ${$.org}`:""}: gateway ${$.gatewayUrl}`),$.seatMode&&!o.subscription&&(o.subscription=!0,L("Subscription org: using pass-through auth (--subscription) \u2014 your own seat sign-in is used."))}catch($){if(sh(D.token))return R($ instanceof Error?$.message:String($)),1;let X=o.gateway||process.env.ANYRAY_GATEWAY_URL?.trim()||s.gateway;if(X)L(`Could not resolve the gateway from the enrollment link \u2014 using ${X}.`);else return R($ instanceof Error?$.message:String($)),1}}let w,y;if(o.claim&&!o.revert)if(o.dryRun)L("dry run: not enrolled (skipped redeeming the enrollment link).");else{let D=LS(o.claim);if(!D)return R("invalid --claim value: expected the sdc_ code from your organization's Anyray page."),1;try{let $=await Ni("Connecting this machine\u2026",()=>NS({cpOrigin:D.cpOrigin,claim:D.claim,gatewayUrl:o.gateway}));w={cert:$.cert,privateKeyPem:$.privateKeyPem},$.deploymentId&&(u=$.deploymentId),!o.gateway&&$.gatewayUrl&&(o.gateway=$.gatewayUrl),y=$.ssoLink}catch($){return R($ instanceof Error?$.message:String($)),1}}if(o.sso&&!w&&!o.revert)if(o.dryRun)L("dry run: not enrolled via SSO (skipped minting a personal key).");else{let D=Et(o.sso);if(!D)return R(gi(o.sso)?"that is an enrollment link, not an SSO link \u2014 re-run with --enroll instead of --sso.":"invalid --sso value: expected a https://\u2026/sso/<tenantId> link or a tnt_ id."),1;try{let $=await kd({cpOrigin:D.cpOrigin,tenantId:D.tenantId,gatewayUrl:o.gateway,log:he=>L(he),open:r()?Ua:void 0}),X=await Ni("Waiting for SSO sign-in\u2026",()=>vd($,{gatewayUrl:o.gateway}));w={cert:X.cert,privateKeyPem:X.privateKeyPem},X.deploymentId&&(u=X.deploymentId),!o.gateway&&X.gatewayUrl&&(o.gateway=X.gatewayUrl)}catch($){return R($ instanceof Error?$.message:String($)),1}}let g=!o.gateway&&!process.env.ANYRAY_GATEWAY_URL?s.gateway:void 0;g&&(o.gateway=g);let b;try{b=Kt(o.gateway)}catch(D){return R(D.message),1}let k,C;g&&!o.revert&&L(`Gateway: ${b} ${v("(cached in ~/.anyray \u2014 pass a URL to change)")}`),!o.revert&&Og(b)&&O(`${b} 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 S=i??process.env.ANYRAY_CLIENT_KEY?.trim(),E=S||KR(s),I,_,T,W,Q,G,ne=async D=>{await So();let $=ES(D.token),X=TS(s.enrolledCert,s.enrolledCertExpiry,D.deploymentId,Date.now(),$,s.enrolledTokenHash,D.expectedUser),he=X?await Fe():void 0,Gt=Wt()||void 0,Z=X&&he&&s.enrolledCert?{cert:s.enrolledCert,privateKeyPem:he,publicKeyPem:s.enrolledCert.payload.devPublicKey}:void 0,Le=pt=>_S({cpOrigin:D.cpOrigin,token:D.token,gatewayOrigin:b,email:D.email,team:D.team,machineId:D.machineId,deploymentId:D.deploymentId,machineUuid:Gt,reuse:pt?Z:void 0}),Se=!!Z,Ye=await(async()=>{try{return await Le(Se)}catch(pt){if(Z&&pt instanceof lt&&pt.policyCode!=="managed_device_required")return L("your saved certificate was rejected by the gateway (it may have been rebuilt) \u2014 re-enrolling from scratch\u2026"),Se=!1,await Le(!1);throw pt}})();E=Ye.clientKey,o.user=Ru(o.user,Ye.user),o.team=Ru(o.team,Ye.team),I=Ye.cert,_=Ye.cert.payload.expiresAt,G=Ye.expiresAt,Q=void 0,Se||(T=Ye.privateKeyPem),Se||(W=$),B(`Enrolled${Ye.user?` as ${Ye.user}`:""}${Se?" (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)L("dry run: not enrolled (skipped minting a personal key).");else{let D=Ad(o.enroll);if(!D){let $=CS(o.enroll);return R($?`that is ${$.what}, not an enrollment link \u2014 re-run with ${$.flag} instead of --enroll.`:Et(o.enroll)?"that is an SSO link, not an enrollment link \u2014 re-run with --sso instead of --enroll.":"invalid --enroll value: expected a https://\u2026/enroll/<token> link or a bare token."),1}try{let $=o.machine?Pd():void 0,X=m==="mdm"&&!p?dx():void 0,he=m==="mdm"&&!p&&!X?lx(f,Ud()):void 0,Gt=X??he;if(Gt){let Se=X?"the email your MDM assigned to this machine":`${Gt} (this Mac's login name at the first allowed domain)`;A(o.user?.trim()&&o.user.trim()!==Gt?`Ignoring --user: enrolling as ${Se}.`:`Enrolling as ${Se}.`)}let Z=p??Gt??y5(o.user);if(!o.machine&&!o.user&&!p&&!Gt){let Se=aI();Se.distinct||(O(` Enrolling as "${Se.identity}" \u2014 this may not be unique to you.`),O(Se.reason==="machine_default"?" That looks like a machine or container default, so every developer on":" No personal git email is set, so machines sharing this image can"),O(Se.reason==="machine_default"?" this image would enroll as the same person and their spend would merge.":" enroll under the same name and their spend would merge."),O(" Re-run with `--user you@company.com` (or set `git config --global"),O(" user.email`) so your usage is attributed to you."))}let Le=o.machine?`machine:${$}`:h?Z:void 0;await ne({cpOrigin:D.cpOrigin,token:D.token,email:Z,team:o.team,machineId:$,deploymentId:u,expectedUser:Le})}catch($){return R($ instanceof Error?$.message:String($)),$ instanceof lt&&$.policyCode!=="managed_device_required"&&L("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."),xS($)?3:1}}if(w){await So();try{let D=Wt()||void 0,$=await Qt(b,w.cert,w.privateKeyPem,{machineUuid:D});E=$.key,o.user=Ru(o.user,$.user),o.team=Ru(o.team,$.team),I=w.cert,_=w.cert.payload.expiresAt,T=w.privateKeyPem,G=$.expiresAt;let X=o.sso?Et(o.sso):void 0;Q=X?`${X.cpOrigin}/sso/${X.tenantId}`:y,B(`Enrolled${$.user?` as ${$.user}`:""} via SSO \u2014 personal gateway key minted (not shown; it lands in your tool configs).`)}catch(D){return R(D instanceof Error?D.message:String(D)),D instanceof lt&&D.policyCode!=="managed_device_required"&&L("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 D=o.yes;k=await jh(o.user,s.name,D),C=await Zh(o.team,s.team,D)}if(!o.revert&&!o.dryRun){let D=vx(await kx(b,E),{subscription:o.subscription,org:o.placeholder,byoUpstream:!!a});if(D.lane){let $=D.lane==="subscription";o.subscription=$,o.placeholder=!$;let X=$?"your own subscription seat":"the organization's provider account";D.overrodeFlag?L(`Your administrator assigns this machine to ${X}, so that is what was applied (it overrides the lane flag you passed).`):L(`Billing lane set by your administrator: ${X}.`)}}let z;!o.revert&&!o.subscription&&!o.placeholder&&(z=await yn(),H("Detecting your sign-ins"),A(` Claude (Anthropic): ${a?qe("BYO upstream key (passthrough)"):z.anthropic?qe("signed in \u2192 your subscription"):v("not signed in \u2192 org key")}`),A(` Codex (ChatGPT): ${z.openai?qe("signed in \u2192 your subscription"):v("not signed in \u2192 org key")}`),(!z.anthropic||!z.openai)&&E&&await Ix(Ee({origin:b,placeholderKey:o.key,clientKey:E,subscription:!1,placeholder:!0,byoUpstream:a,user:k,team:C,intent:o.intent}))===!1&&(O(" This gateway holds NO server-side provider key, so the org-key"),O(" fallback above cannot serve a request \u2014 it answers 424, not 401."),z.copilot?(O(" Your Copilot seat DOES work and never touches the org key: prefer"),O(" `github-copilot/...` models in OpenCode and Copilot Chat until an"),O(" admin adds a provider key in the console \u2192 Providers.")):(O(" No subscription seat here works either. Sign in to Copilot or"),O(" Claude, or have an admin add a provider key in console \u2192 Providers."))),!z.anthropic&&!z.openai&&!z.copilot&&Gr()&&(O(" No subscription sign-ins found on this host. Sign-ins do not cross the"),O(" Remote-SSH hop \u2014 your laptop's are invisible here, and these tools run"),O(" HERE. Sign in on this machine (`copilot` \u2192 /login, Claude Code, Codex)"),O(" and re-run, or everything below routes on the org key instead.")));let j=Ee({origin:b,placeholderKey:o.key,clientKey:E,subscription:o.subscription,placeholder:o.placeholder,byoUpstream:a,seat:z,user:k,team:C,intent:o.intent,intentLabel:o.intentLabel,session:o.session}),le=o.revert===!0&&(o.tools?.length??0)===0,U={dryRun:o.dryRun,fullRevert:le};if(!o.revert&&j.clientKey&&!be(j.clientKey))return R("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&&!j.clientKey){H("Enrollment required");let D="A real apply requires a personal ark_ gateway key. Run with --enroll <link> or --sso <link>, then re-run Connect.";return o.dryRun?(O(` ${D}`),L(" Dry run only \u2014 no placeholder configuration will be written."),await HR(d,"after-enrollment"),L(`
|
|
1062
|
-
Dry run complete \u2014 no files were written.`),0):(R(` ${D}`),1)}o.revert||
|
|
1063
|
-
Dry run \u2014 no files will be written.`);let re=await
|
|
1059
|
+
per-skill versions ${v("sync")} last wrote \u2014 for zero-question re-runs.`,g5=e=>{let t=e?.trim();return t||Vh()},VR=(e=process.stdin)=>new Promise((t,n)=>{let r=y5({input:e,crlfDelay:1/0}),o=!1,a=i=>{o||(o=!0,e.removeListener("error",s),r.close(),t(i))},s=i=>{o||(o=!0,r.close(),n(i))};r.once("line",i=>a(i.trim())),r.once("close",()=>a("")),e.once("error",s)}),Ru=(e,t)=>t||e,xg=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"--key-stdin":t.keyStdin=!0;break;case"--devcontainer":t.devcontainer=o();break;case"--wsl":t.wsl=o();break;case"--codespace":t.codespace=o();break;case"--enroll":t.enroll=o();break;case"--sso":t.sso=o();break;case"--claim":t.claim=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"--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},w5=e=>!e||e.length===0?pe:e.map(t=>{let n=mt(t);if(!n)throw new Error(`unknown tool "${t}". Known: ${pe.map(r=>r.id).join(", ")}`);return n}),b5=(e,t)=>{if(H("Gateway target"),A(` Origin: ${qe(e.origin)}`),e.byoUpstream)A(` Auth: BYO upstream key ${v(`(passthrough to ${e.byoUpstream.url}; Claude Code, OpenCode)`)}`),e.clientKey&&A(` Client key: personal gateway key (${Pt(e.clientKey)}) ${v("rides x-anyray-api-key")}`);else if(e.authMode==="auto"){let n=te(e,"anthropic")?qe("your subscription"):"org key",r=te(e,"openai")?qe("your subscription"):"org key";A(` Auth: auto ${v("(per tool)")} \u2014 Claude: ${n}, Codex: ${r}`),e.clientKey&&A(` Client key: personal gateway key (${Pt(e.clientKey)})`)}else e.authMode==="subscription"?(A(` Auth: subscription pass-through ${v("(seat OAuth token; Claude Code + Codex + verified macOS Claude Desktop)")}`),e.clientKey&&A(` Client key: personal gateway key (${Pt(e.clientKey)}) ${v("rides x-anyray-api-key")}`)):e.clientKey?A(` Auth: personal gateway key (${Pt(e.clientKey)}) ${v("(replaces the placeholder)")}`):A(` Enrollment: ${v("required before a real apply (no configuration will be written)")}`);e.authMode!=="placeholder"&&t.some(n=>n.id==="cursor")&&A(` Cursor: ${qe("native Team subscription")} ${v("(Claude/Opus inference remains Cursor-hosted; Anyray hooks/MCP optimize supported local context)")}`),t.some(n=>n.id==="claude-desktop")&&(te(e,"anthropic")?(A(` Claude Desktop: ${qe("subscription-backed Gateway lane")} ${v("(verified macOS builds; Windows fails closed)")}`),A(` ${v("Uses the Claude Code Keychain credential on demand; the first-party Desktop lane remains direct.")}`)):(A(` Claude Desktop: ${qe("third-party API lane")} ${v("(API-billed; switches the active local inference profile)")}`),A(` ${v("The first-party Claude subscription remains untouched.")}`))),A(` Attribution: ${fe(e.metadata)??v("(none \u2014 pass --user)")}`)},A5=e=>{switch(e.kind){case"ssh":return`SSH remote \`${e.name}\``;case"devcontainer":return`dev container \`${e.name}\``;case"attached-container":return`attached container \`${e.name}\``;case"wsl":return`WSL distro \`${e.name}\``;case"codespace":return`Codespace \`${e.name}\``;case"tunnel":return`remote tunnel \`${e.name}\``}},C5=async()=>{let[e,t]=await Promise.all([lu().catch(()=>[]),kg().catch(()=>[])]);for(let n of e)A(` Bind-mounted config file: ${n} ${v("(cannot be replaced atomically; connect writes it in place, verified)")}`);if(t.length>0){H("Other environments you work in");for(let n of t)L(` ${A5(n)}`);A(v(" This run configures only this machine. Run `anyray-connect` inside each of these too \u2014 see docs.anyray.ai/get-started/remote-environments."))}},HR=async(e,t)=>{H("Selected tools");for(let n of e){let r=await n.detect();r.installed?A(` ${n.title} ${v(`(${n.id})`)} \u2014 ${t==="plan"?"will configure":"would configure after enrollment"}${r.detail?`; ${r.detail}`:""}`):L(` ${n.title} ${v(`(${n.id})`)} \u2014 not found${r.detail?`; ${r.detail}`:""}`)}},KR=(e,t=Date.now())=>{let n=e.clientKey?.trim();if(!be(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},k5={loadDevKey:Fe,saveDevKey:rc,clearDevKey:is,saveProfile:ce},v5=async(e,t,n,r=k5,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}},S5=async(e,t,n,r,o)=>{let a=0,s=[],i=[],c=[],l=[],d=[];for(let u of e){if(!(await u.detect()).installed&&!r){d.push(u.title);continue}H(`${u.title} ${v(`(${u.id})`)}`);try{let m=r?await u.revert(n):await u.apply(t,{...n,explicit:o?.has(u.id)===!0,reportsToUser:!0});for(let f of m.messages)A(` ${f}`);a+=m.changedFiles?.length??0,l.push({id:u.id,status:m.status}),m.status==="configured"||m.status==="reverted"?B(` ${m.status}`):m.status==="manual"?(s.push(u.title),m.manualAudience==="admin"?(i.push(u.title),c.push(u.id),O(" blocked by machine policy \u2014 your IT team owns this one")):O(" manual step required (see above)")):m.status==="held"?L(" left on its own plan (no change)"):L(` ${m.status}`)}catch(m){l.push({id:u.id,status:"failed"}),R(` failed: ${m instanceof Error?m.message:String(m)}`)}}if(d.length>0&&L(`Skipped ${d.length} not installed (${d.join(", ")})`),!n.dryRun){let u=await cc().catch(()=>[]);u.length&&L(` Removed ${u.length} unused Anyray runtime copies.`)}return{changes:a,manual:s,manualAdminOnly:i,manualAdminOnlyIds:c,results:l}},E5=(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},I5=(e,t,n)=>{if(t.revert)return[];if((t.tools?.length??0)>0)return[];let r=new Set(n??[]);return e.filter(o=>jR(o)&&!r.has(o.id))},x5=async e=>{let t=MI(e,process.platform,ee());if(t){await we(t.path,t.content);for(let n of BI(t,process.platform))A(` ${n}`)}},R5=async(e,t,n=Tu())=>{let r=[],o=new Set;for(let a of e){let s=a.quitGated,i=s?.quitTarget;if(!s||!i||!Tb(i,n)||!Ob(i,n))continue;let c=xb(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:Rb(i),quitTarget:i,isRunning:()=>s.isRunning()})}}return r},O5=(e,t)=>e.noQuitApps===!0||e.dryRun?!1:e.quitApps===!0?!0:!e.yes&&t,T5=e=>`
|
|
1060
|
+
${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?`}`,_5=async(e,t={})=>{let n=t.requestQuit??(a=>Pb(a)),r=t.waitFor??(a=>Db(a)),o=[];for(let a of e){if(n(a.quitTarget)&&await r(a.isRunning)){o.push(a),B(` Closed ${a.title}.`);continue}O(` ${a.title} is still open \u2014 leaving it alone.`),L(` Its configuration is written either way; ${a.title} picks it up the next time you close it.`)}return o},P5=(e,t={})=>{let n=t.relaunch??(o=>Lb(o)),r=[];for(let o of e)n(o.quitTarget)?(r.push(o.title),B(` Reopened ${o.title}.`)):O(` Could not reopen ${o.title} \u2014 start it when you're ready.`);return r},jR=e=>e.changesBilling===!0||e.changesOrgManagement===!0,ZR=e=>e.changesBilling===!0?"moves inference spend from your subscription to the org API bill":e.changesOrgManagement===!0?"switches the app to third-party mode; claude.ai Enterprise org settings stop applying":void 0,Eg=e=>!jR(e),D5=async(e,t,n={})=>{let r=n.hasEnrollment??Ku,o=n.canMultiSelect??px,a=n.multiSelect??fx,s=n.prompt??Ma,i=n.registry??pe;if(A(K("Anyray connect \u2014 guided setup")),A(v("Point your local coding tools at the Anyray gateway. Ctrl-C to abort.")),await r())A("Stored enrollment will be reused. Run with --revert to clear it.");else if(!e.enroll&&!e.sso&&!e.gateway){H("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 yt;c=d.values[0]}else{A(" 1. Paste an enrollment link"),A(" 2. Sign in with SSO"),A(" 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||O("Choose one of the three connection methods.")}if(!c)throw new yt;for(let l=0;l<3;l++)if(c==="enroll"){let d=await s("? Enrollment link or token");if(d&&gi(d)&&Ad(d)){e.enroll=d;break}O("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&&Et(d)){e.sso=d;break}O("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&&gi(d)){e.enroll=d,A("That looks like an enrollment link \u2014 using passwordless enrollment.");break}try{if(!d)throw new Error("missing gateway");e.gateway=Kt(d);break}catch{O("That is not a valid http(s) gateway URL. Try again.")}}if(!e.enroll&&!e.sso&&!e.gateway)throw new yt}if(!e.tools||e.tools.length===0){H("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=>Eg(u)).map(u=>u.id);if(c.length>0){for(let u=0;u<3&&!e.tools;u++){let p;if(o()){let m=await a({title:"Tools to configure",items:c.map(f=>({value:f.id,label:`${f.title} (${f.id})`,hint:ZR(f),selected:Eg(f),requiresExplicitChoice:!Eg(f)}))});if(m.kind==="cancelled")throw new yt;p=m.values}else{p=(await s("? Tools to configure (comma-separated, blank = all suggested)",d.join(",")||void 0)??"").split(",").map(w=>w.trim()).filter(Boolean);let f=new Set(c.map(w=>w.id)),h=p.filter(w=>!f.has(w));if(h.length>0){O(`Unknown or unavailable tool id${h.length===1?"":"s"}. Choose from: ${c.map(w=>w.id).join(", ")}.`);continue}}if(p.length===0){O("Choose at least one installed tool.");continue}e.tools=p}if(!e.tools)throw new yt}l.length>0&&L(`${l.length} others not installed (${l.map(u=>u.id).join(", ")})`)}return e},L5=async(e,t)=>{H("Verifying the connection");let n=await Ni("Checking the gateway\u2026",()=>Ka(e,{tools:t}));n.kind==="ok"?B(` ${n.detail}`):n.kind==="unreachable"||n.kind==="unknown"||n.kind==="enrollment-required"||n.kind==="provider-rejected"?O(` ${n.detail}`):R(` ${n.detail}`);for(let r of n.remedy)A(v(` ${r}`))},N5=async(e,t={})=>{if(e.dryRun)return;let n=t.install??ar,r=t.uninstall??sr;if(e.want&&e.trayManaged){H("Automatic key refresh"),B(" Managed by the Anyray Connect app \u2014 it triggers the ~30-min key refresh.");return}if(e.want){let o=await n();H("Automatic key refresh");for(let a of o.messages)A(` ${a}`);o.ok&&B(" Your gateway key now renews every ~30 min \u2014 no tool will 401 on a stale key mid-session."),o.ok?await ce({...await P(),refreshSchedulerInstalledOnce:!0}):await ce({...await P(),refreshSchedulerEnabled:!1});return}if(!e.scopedRevert&&e.wasEnabled){H("Automatic key refresh");let o=await r();for(let a of o.messages)A(` ${a}`);await ce({...await P(),refreshSchedulerEnabled:!1,refreshSchedulerInstalledOnce:!1}),B(" Removed the automatic key-refresh schedule.")}},$5=new Set(["login","wizard","status","doctor","sync","device-url"]),M5=new Set(["managed","print-key","device-url","status","update","retrieve","recall","history","migrate","endpoint","remote"]),B5=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==="fleet-off"||e.outcome==="fleet-directed")return{level:"warn",message:"Your organization manages anyray-connect updates, so this run did not download a binary; continuing with the current runtime."};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."}},F5=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=oy(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]||!M5.has(e[0])},Ig=async(e,t)=>{try{return await qR(e,t)}catch(n){if(n instanceof yt)return console.error(v("Cancelled \u2014 nothing was written.")),130;if(n instanceof Error&&n.message==="connect profile is busy; retry the command")return R("Another Connect update is in progress. Try again."),1;throw n}},YR=12e4,W5=async(e,t,n,r=cs)=>e&&!t?r(n,{waitMs:YR}):n(),U5=async(e,t,n,r={})=>{if(e.yes||e.dryRun)return"proceed";if(!(r.isInteractive??gt)())return"non-interactive";let o=e.revert?"remove Anyray config from":"configure",a=t?"Apply this configuration?":`
|
|
1061
|
+
${o} ${n} tool target(s)?`;return await(r.confirm??Io)(a)?"proceed":"declined"},H5=async(e=Va)=>{let t=await e({force:!0,respectFailureBackoff:!0,allowNpmMigration:!0,initiator:"directive"});switch(t.outcome){case"current":case"updated":case"migrated":case"container":case"unmanaged":return"ok";case"available":case"migration-available":case"migration-deferred":case"disabled":case"platform-unsupported":case"unavailable":case"failed":return"failed";case"fleet-off":return"failed";case"fleet-directed":return"failed";default:return t.outcome}},JR=(e,t)=>qR(e,!1,{managedEnrollmentRevertedTools:t}),G5=()=>dg(ug(JR)),V5=async()=>{let e=!1,t=await dR(await Ut({runAmbientSelfcheck:!0}),{...ug(JR),refresh:()=>Ut({})});await bp(),await HE(),await GE()==="retry"&&(e=!0);let n=await P().catch(()=>{});if(n&&process.env.ANYRAY_FLEET_MANAGED==="1"&&!n.anyrayFleetManaged){n.anyrayFleetManaged=!0;try{await ce(n)}catch{e=!0}}let r=n?.anyrayFleetManaged===!0&&await To().catch(()=>!1);if(n&&(await NR(t,{fleetdPresent:async()=>r}).catch(()=>{}),r&&n.gateway&&n.clientKey)){let o=n.gateway,a=n.clientKey,s=Wt(),i=n.enrolledCert;if(s&&i){let l=await Fe().catch(()=>{});l&&await OS(o,a,i,l,s).catch(()=>{})}await MR(o,a,{execute:async(l,d)=>{let u;return l==="remint"||l==="reapply_config"?u=await Ut({force:!0})==="failed"?"failed":"ok":l==="revert_tool"?u=await FR(d):l==="update"?u=await H5():u=(await xu()).ok?"ok":"failed",u==="failed"&&(e=!0),u}}).catch(()=>{})}return r||await Va(),{refresh:t,...e?{partial:!0}:{}}},K5=async e=>{if(e[0]==="__anyray-hook"){let r=e[1]==="cursor"||e[1]==="opencode"?e[1]:"claude";return p0(r)}if(e[0]==="__anyray-codex-hook")return f0();if(e[0]==="__anyray-prompt-hook")return A0();if(e[0]==="__anyray-shell-pretool")return S0();if(e[0]==="__anyray-shell-run")return v0(e.slice(1));if(e[0]==="__anyray-read-pretool")return P0();if(e[0]==="__anyray-sso-gate")return b0(e.slice(1));if(e[0]==="__anyray-sso-poll")return uR();if(e[0]==="__anyray-managed-enroll")try{return await cs(G5,{waitMs:YR})}catch{return 1}if(e[0]==="__anyray-vscode-gate")return gR();if(e[0]==="__anyray-spawn-refresh")return await Or(),0;if(e[0]==="__anyray-mcp-server"){let r=e[1]==="claude"||e[1]==="profile"?e[1]:"auto";return ER(r)}if(e[0]==="__anyray-acp-agent")return IR(e[1],e[2],{clientTool:e[3]});if(e[0]==="__anyray-endpoint-install")return iR(e.slice(1));let t=DR(e);if(t)return LR(t,{refresh:V5});if(e[0]==="__anyray-persistence")return Bw(e.slice(1));if(e[0]==="__anyray-quit-watch")return dS(e.slice(1));if(e[0]===kr)return mI(e.slice(1));if(e[0]===Qs)return yI(e.slice(1));if(e[0]===Zr){let r=e[1];return r&&await Jd(r),0}if(e[0]==="--version"||e[0]==="-V")return yR();try{let r=await ow(e);if(r!==void 0)return r}catch(r){return R(`Could not persist anyray-connect for long-lived integrations: ${r instanceof Error?r.message:String(r)}`),1}if(F5(e)){let r=B5(await Ax());r?.level==="warn"?O(r.message):r&&console.error(r.message)}if(e[0]==="managed")return JS(e.slice(1));if(e[0]==="endpoint")return sR(e.slice(1));if(e[0]==="print-key")return ZE(e.slice(1));if(e[0]==="models")return JE(e.slice(1));if(e[0]==="copilot-login")return XE(e.slice(1));if(e[0]==="desktop"){let r=e.slice(1),o=oy(r);return o?Ig(o,!1):FI(r)}if(e[0]==="retrieve")return UI(e.slice(1));if(e[0]==="recall")return HI(e.slice(1));if(e[0]==="history")return ex(e.slice(1));if(e[0]==="migrate")return nx(e.slice(1));if(e[0]==="login")return fR(e.slice(1));if(e[0]==="update")return hR(e.slice(1));if(e[0]==="remote")return eX(e.slice(1));let n=e[0];if(n&&$5.has(n)){let r=e.slice(1),o;try{o=xg(r)}catch(a){return R(a.message),A("\nRun `npx anyray-connect --help` for usage."),1}return o.help?(A(o.helpAll?Ou:GR),0):n==="status"?xx({gateway:o.gateway}):n==="doctor"?pu({gateway:o.gateway,json:o.json,verify:o.verify,noVerify:o.noVerify,quick:o.quick,repair:o.repair,securityReview:o.securityReview}):n==="sync"?Lx({gateway:o.gateway}):n==="device-url"?tI():Ig(r,!0)}return Ig(e,!1)},XR=async e=>{try{return await K5(e)}catch(t){if(t instanceof yt)return console.error(v("Cancelled.")),130;throw t}},j5=e=>{let t=process.platform==="win32"?"where":"which";try{return m5(t,[e],{stdio:"ignore"}).status===0}catch{return!1}},Z5=(e,t={})=>{let n=t.which??j5,r=t.platform??Tu;switch(e.kind){case"ssh":return!0;case"devcontainer":return n("docker");case"wsl":return r()==="win32"&&n("wsl.exe");case"codespace":return n("gh")}},Y5=e=>{switch(e.kind){case"ssh":case"devcontainer":case"wsl":case"codespace":return{kind:e.kind,name:e.name,...e.kind==="devcontainer"&&e.ref?{ref:e.ref}:{}};case"attached-container":case"tunnel":return}},J5=(e,t)=>{switch(e.kind){case"ssh":return`Configure \`${t}\` over SSH now?`;case"devcontainer":return`Configure \`${t}\` in this dev container now?`;case"wsl":return`Configure \`${t}\` in WSL now?`;case"codespace":return`Configure Codespace \`${t}\` now?`}},X5=e=>e.interactive&&!e.managed&&!e.yes&&!e.revert&&!e.dryRun,z5=async(e,t={})=>{if(!X5(e)||!be(e.clientKey))return;let n=t.discoverRemoteEnvironments??kg,r;try{r=await n()}catch{return}let o=t.confirm??Io,a=t.runRemoteApply??Sg,s=t.isCarrierAvailable??Z5,i=t.resolveDevcontainer??vg;for(let c of r){let l=Y5(c);if(!l)continue;let d=l;try{if(!await s(d))continue;d.kind==="devcontainer"&&(d={kind:"devcontainer",name:await i(d)})}catch{continue}if(!await o(J5(d,c.name)))continue;let u=await a(d,{gateway:e.gateway,user:e.user,team:e.team,clientKey:e.clientKey});if(u===0){L(`Remote \`${c.name}\` exited with code 0.`);continue}O(`Remote \`${c.name}\` exited with code ${u}.`),L(zR(d.kind))}},zR=e=>{switch(e){case"ssh":return"Fix: ssh in and run `anyray-connect doctor`.";case"devcontainer":return"Fix: open a shell in the container and run `anyray-connect doctor`.";case"wsl":return"Fix: open the distro and run `anyray-connect doctor`.";case"codespace":return"Fix: `gh codespace ssh` in and run `anyray-connect doctor`."}},q5="usage: anyray-connect remote <ssh-host> [--yes] [--dry-run] | remote --devcontainer <host-path> | --wsl <distro> | --codespace <name> [--yes] [--dry-run]",Q5=e=>{let t=/[/\\]/.test(e);return{kind:"devcontainer",name:t?h5(e.replaceAll("\\","/")):e,...t?{ref:e}:{}}},eX=async(e,t={})=>{if(e[0]==="--help"||e[0]==="-h")return console.log(Ou),0;let n=e[0]&&!e[0].startsWith("-")?e[0]:void 0,r;try{r=xg(n?e.slice(1):e)}catch(h){return R(h instanceof Error?h.message:String(h)),1}if(r.help)return console.log(Ou),0;let o=[r.devcontainer,r.wsl,r.codespace].filter(h=>h!==void 0);if(n&&o.length>0||!n&&o.length!==1)return R(q5),1;let a=n?{kind:"ssh",name:n}:r.devcontainer!==void 0?Q5(r.devcontainer):r.wsl!==void 0?{kind:"wsl",name:r.wsl}:{kind:"codespace",name:r.codespace};if(a.kind==="devcontainer"&&!a.ref)return R("Cannot resolve a dev container by its bare name; use its full host path."),1;if(a.kind==="wsl"&&(t.platform??Tu)()!=="win32")return R("--wsl is available only on Windows (win32)."),1;let s=t.isInteractive??gt;if(!r.yes&&!s())return R("remote requires a TTY; pass --yes only when you explicitly intend to configure that target."),1;if(r.revert||r.enroll||r.sso||r.claim||r.project||r.upstream||r.upstreamKey)return R("remote supports --gateway, --user, --team, --yes, --dry-run, and --key-stdin only."),1;if(r.dryRun)return L(`Dry run: would configure \`${a.name}\` remotely.`),0;let i;if(r.keyStdin)try{i=await VR()}catch{return R("could not read the personal gateway key from stdin."),1}let c=await(t.loadProfile??P)(),l=!r.gateway&&!process.env.ANYRAY_GATEWAY_URL?c.gateway:void 0,d=Kt(r.gateway??l),u=i||process.env.ANYRAY_CLIENT_KEY?.trim()||KR(c);if(!be(u))return R("A personal gateway key is required. Enroll locally first or provide ANYRAY_CLIENT_KEY (or --key-stdin)."),1;let p=await jh(r.user,c.name,r.yes),m=await Zh(r.team,c.team,r.yes),f;try{f=await(t.runRemoteApply??Sg)(a,{gateway:d,user:p,team:m,clientKey:u})}catch(h){return R(h instanceof Error?h.message:String(h)),1}return f===0?L(`Remote \`${a.name}\` exited with code 0.`):(O(`Remote \`${a.name}\` exited with code ${f}.`),L(zR(a.kind))),f},qR=async(e,t,n={})=>{let r=n.isInteractive??gt,o;try{o=xg(e)}catch(D){return R(D.message),A("\nRun `npx anyray-connect --help` for usage."),1}if(o.help)return A(o.helpAll?Ou:GR),0;if(o.revert&&(o.sso||o.enroll||o.claim))return R("--revert cannot be combined with --sso, --enroll or --claim. 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?(R("--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):pI({gateway:o.gateway,tools:o.tools,revert:o.revert,dryRun:o.dryRun,yes:o.yes});if(!!o.upstream!=!!o.upstreamKey)return R("--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 R("--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 D;try{D=new URL(o.upstream.trim())}catch{return R(`invalid --upstream URL: "${o.upstream}"`),1}if(D.protocol!=="http:"&&D.protocol!=="https:")return R(`invalid --upstream URL: "${o.upstream}" \u2014 must start with http:// or https://`),1;let $=o.upstreamKey.trim();if(!$)return R("--upstream-key must not be empty."),1;a={url:Vt(o.upstream),key:$}}let s=await P(),i;if(o.keyStdin)try{i=await VR()}catch{return R("could not read the personal gateway key from stdin."),1}!a&&!o.subscription&&!o.placeholder&&!o.revert&&(a=s.byoUpstream);let c=!t&>()&&!o.gateway&&!o.revert&&!o.yes&&!o.dryRun&&!o.enroll&&!o.sso,l=!1;(t||c)&&r()&&(o=await(n.runWizard??D5)(o,s),l=!0);let d;try{if(d=w5(o.tools),n.managedEnrollmentRevertedTools){let D=[...n.managedEnrollmentRevertedTools,...s.revertedTools??[]];d=lR(d,D)}}catch(D){return R(D.message),1}A(K(o.revert?"Anyray connect \u2014 revert":"Anyray connect")),o.gateway&&!o.enroll&&gi(o.gateway)&&(o.enroll=o.gateway,o.gateway=void 0,A("That looks like an enrollment link \u2014 treating it as --enroll."));let u,p,m,f,h=!1;if(o.enroll){let D=Ad(o.enroll);if(D&&(!o.gateway||s.enrolledCert||sh(D.token)))try{let $=await Ni("Resolving enrollment link\u2026",()=>kS(D)),X=!o.gateway;X&&(o.gateway=$.gatewayUrl),u=$.deploymentId,p=$.email,m=$.provisioningKind,f=$.allowedDomains,h=!0,X&&L(`Enrollment link${$.org?` for ${$.org}`:""}: gateway ${$.gatewayUrl}`),$.seatMode&&!o.subscription&&(o.subscription=!0,L("Subscription org: using pass-through auth (--subscription) \u2014 your own seat sign-in is used."))}catch($){if(sh(D.token))return R($ instanceof Error?$.message:String($)),1;let X=o.gateway||process.env.ANYRAY_GATEWAY_URL?.trim()||s.gateway;if(X)L(`Could not resolve the gateway from the enrollment link \u2014 using ${X}.`);else return R($ instanceof Error?$.message:String($)),1}}let w,y;if(o.claim&&!o.revert)if(o.dryRun)L("dry run: not enrolled (skipped redeeming the enrollment link).");else{let D=LS(o.claim);if(!D)return R("invalid --claim value: expected the sdc_ code from your organization's Anyray page."),1;try{let $=await Ni("Connecting this machine\u2026",()=>NS({cpOrigin:D.cpOrigin,claim:D.claim,gatewayUrl:o.gateway}));w={cert:$.cert,privateKeyPem:$.privateKeyPem},$.deploymentId&&(u=$.deploymentId),!o.gateway&&$.gatewayUrl&&(o.gateway=$.gatewayUrl),y=$.ssoLink}catch($){return R($ instanceof Error?$.message:String($)),1}}if(o.sso&&!w&&!o.revert)if(o.dryRun)L("dry run: not enrolled via SSO (skipped minting a personal key).");else{let D=Et(o.sso);if(!D)return R(gi(o.sso)?"that is an enrollment link, not an SSO link \u2014 re-run with --enroll instead of --sso.":"invalid --sso value: expected a https://\u2026/sso/<tenantId> link or a tnt_ id."),1;try{let $=await kd({cpOrigin:D.cpOrigin,tenantId:D.tenantId,gatewayUrl:o.gateway,log:he=>L(he),open:r()?Ua:void 0}),X=await Ni("Waiting for SSO sign-in\u2026",()=>vd($,{gatewayUrl:o.gateway}));w={cert:X.cert,privateKeyPem:X.privateKeyPem},X.deploymentId&&(u=X.deploymentId),!o.gateway&&X.gatewayUrl&&(o.gateway=X.gatewayUrl)}catch($){return R($ instanceof Error?$.message:String($)),1}}let g=!o.gateway&&!process.env.ANYRAY_GATEWAY_URL?s.gateway:void 0;g&&(o.gateway=g);let b;try{b=Kt(o.gateway)}catch(D){return R(D.message),1}let k,C;g&&!o.revert&&L(`Gateway: ${b} ${v("(cached in ~/.anyray \u2014 pass a URL to change)")}`),!o.revert&&Og(b)&&O(`${b} 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 S=i??process.env.ANYRAY_CLIENT_KEY?.trim(),E=S||KR(s),I,_,T,W,Q,G,ne=async D=>{await So();let $=ES(D.token),X=TS(s.enrolledCert,s.enrolledCertExpiry,D.deploymentId,Date.now(),$,s.enrolledTokenHash,D.expectedUser),he=X?await Fe():void 0,Gt=Wt()||void 0,Z=X&&he&&s.enrolledCert?{cert:s.enrolledCert,privateKeyPem:he,publicKeyPem:s.enrolledCert.payload.devPublicKey}:void 0,Le=pt=>_S({cpOrigin:D.cpOrigin,token:D.token,gatewayOrigin:b,email:D.email,team:D.team,machineId:D.machineId,deploymentId:D.deploymentId,machineUuid:Gt,reuse:pt?Z:void 0}),Se=!!Z,Ye=await(async()=>{try{return await Le(Se)}catch(pt){if(Z&&pt instanceof lt&&pt.policyCode!=="managed_device_required")return L("your saved certificate was rejected by the gateway (it may have been rebuilt) \u2014 re-enrolling from scratch\u2026"),Se=!1,await Le(!1);throw pt}})();E=Ye.clientKey,o.user=Ru(o.user,Ye.user),o.team=Ru(o.team,Ye.team),I=Ye.cert,_=Ye.cert.payload.expiresAt,G=Ye.expiresAt,Q=void 0,Se||(T=Ye.privateKeyPem),Se||(W=$),B(`Enrolled${Ye.user?` as ${Ye.user}`:""}${Se?" (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)L("dry run: not enrolled (skipped minting a personal key).");else{let D=Ad(o.enroll);if(!D){let $=CS(o.enroll);return R($?`that is ${$.what}, not an enrollment link \u2014 re-run with ${$.flag} instead of --enroll.`:Et(o.enroll)?"that is an SSO link, not an enrollment link \u2014 re-run with --sso instead of --enroll.":"invalid --enroll value: expected a https://\u2026/enroll/<token> link or a bare token."),1}try{let $=o.machine?Pd():void 0,X=m==="mdm"&&!p?dx():void 0,he=m==="mdm"&&!p&&!X?lx(f,Ud()):void 0,Gt=X??he;if(Gt){let Se=X?"the email your MDM assigned to this machine":`${Gt} (this Mac's login name at the first allowed domain)`;A(o.user?.trim()&&o.user.trim()!==Gt?`Ignoring --user: enrolling as ${Se}.`:`Enrolling as ${Se}.`)}let Z=p??Gt??g5(o.user);if(!o.machine&&!o.user&&!p&&!Gt){let Se=aI();Se.distinct||(O(` Enrolling as "${Se.identity}" \u2014 this may not be unique to you.`),O(Se.reason==="machine_default"?" That looks like a machine or container default, so every developer on":" No personal git email is set, so machines sharing this image can"),O(Se.reason==="machine_default"?" this image would enroll as the same person and their spend would merge.":" enroll under the same name and their spend would merge."),O(" Re-run with `--user you@company.com` (or set `git config --global"),O(" user.email`) so your usage is attributed to you."))}let Le=o.machine?`machine:${$}`:h?Z:void 0;await ne({cpOrigin:D.cpOrigin,token:D.token,email:Z,team:o.team,machineId:$,deploymentId:u,expectedUser:Le})}catch($){return R($ instanceof Error?$.message:String($)),$ instanceof lt&&$.policyCode!=="managed_device_required"&&L("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."),xS($)?3:1}}if(w){await So();try{let D=Wt()||void 0,$=await Qt(b,w.cert,w.privateKeyPem,{machineUuid:D});E=$.key,o.user=Ru(o.user,$.user),o.team=Ru(o.team,$.team),I=w.cert,_=w.cert.payload.expiresAt,T=w.privateKeyPem,G=$.expiresAt;let X=o.sso?Et(o.sso):void 0;Q=X?`${X.cpOrigin}/sso/${X.tenantId}`:y,B(`Enrolled${$.user?` as ${$.user}`:""} via SSO \u2014 personal gateway key minted (not shown; it lands in your tool configs).`)}catch(D){return R(D instanceof Error?D.message:String(D)),D instanceof lt&&D.policyCode!=="managed_device_required"&&L("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 D=o.yes;k=await jh(o.user,s.name,D),C=await Zh(o.team,s.team,D)}if(!o.revert&&!o.dryRun){let D=vx(await kx(b,E),{subscription:o.subscription,org:o.placeholder,byoUpstream:!!a});if(D.lane){let $=D.lane==="subscription";o.subscription=$,o.placeholder=!$;let X=$?"your own subscription seat":"the organization's provider account";D.overrodeFlag?L(`Your administrator assigns this machine to ${X}, so that is what was applied (it overrides the lane flag you passed).`):L(`Billing lane set by your administrator: ${X}.`)}}let z;!o.revert&&!o.subscription&&!o.placeholder&&(z=await yn(),H("Detecting your sign-ins"),A(` Claude (Anthropic): ${a?qe("BYO upstream key (passthrough)"):z.anthropic?qe("signed in \u2192 your subscription"):v("not signed in \u2192 org key")}`),A(` Codex (ChatGPT): ${z.openai?qe("signed in \u2192 your subscription"):v("not signed in \u2192 org key")}`),(!z.anthropic||!z.openai)&&E&&await Ix(Ee({origin:b,placeholderKey:o.key,clientKey:E,subscription:!1,placeholder:!0,byoUpstream:a,user:k,team:C,intent:o.intent}))===!1&&(O(" This gateway holds NO server-side provider key, so the org-key"),O(" fallback above cannot serve a request \u2014 it answers 424, not 401."),z.copilot?(O(" Your Copilot seat DOES work and never touches the org key: prefer"),O(" `github-copilot/...` models in OpenCode and Copilot Chat until an"),O(" admin adds a provider key in the console \u2192 Providers.")):(O(" No subscription seat here works either. Sign in to Copilot or"),O(" Claude, or have an admin add a provider key in console \u2192 Providers."))),!z.anthropic&&!z.openai&&!z.copilot&&Gr()&&(O(" No subscription sign-ins found on this host. Sign-ins do not cross the"),O(" Remote-SSH hop \u2014 your laptop's are invisible here, and these tools run"),O(" HERE. Sign in on this machine (`copilot` \u2192 /login, Claude Code, Codex)"),O(" and re-run, or everything below routes on the org key instead.")));let j=Ee({origin:b,placeholderKey:o.key,clientKey:E,subscription:o.subscription,placeholder:o.placeholder,byoUpstream:a,seat:z,user:k,team:C,intent:o.intent,intentLabel:o.intentLabel,session:o.session}),le=o.revert===!0&&(o.tools?.length??0)===0,U={dryRun:o.dryRun,fullRevert:le};if(!o.revert&&j.clientKey&&!be(j.clientKey))return R("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&&!j.clientKey){H("Enrollment required");let D="A real apply requires a personal ark_ gateway key. Run with --enroll <link> or --sso <link>, then re-run Connect.";return o.dryRun?(O(` ${D}`),L(" Dry run only \u2014 no placeholder configuration will be written."),await HR(d,"after-enrollment"),L(`
|
|
1062
|
+
Dry run complete \u2014 no files were written.`),0):(R(` ${D}`),1)}o.revert||b5(j,d);let Y=!o.revert&&!o.yes&&r();(l||Y)&&!o.revert&&await HR(d,"plan"),Y&&await C5(),o.dryRun&&L(`
|
|
1063
|
+
Dry run \u2014 no files will be written.`);let re=await U5(o,l,d.length,{isInteractive:r,confirm:n.confirm});if(re==="non-interactive")return R(`
|
|
1064
1064
|
Non-interactive session \u2014 cannot ask for confirmation. Pass --yes to proceed.`),1;if(re==="declined")return L(l?"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 D=await nu(j.origin);if(!D.reachable)return R(`
|
|
1065
1065
|
Gateway ${j.origin} is not reachable (${D.detail}).`),A(v(` Refusing to repoint your tools at a gateway that isn\u2019t responding \u2014
|
|
1066
1066
|
that would break them until you re-run with --revert.`)),A(`
|
|
1067
|
-
Start the gateway and try again, or pass --force to configure anyway.`),1;B(`Gateway reachable (${D.detail}).`)}let Qe=o.revert?[]:await
|
|
1068
|
-
Keeping the stored enrollment \u2014 the tools you did not name still need it.`),A("Run --revert with no --tools to remove it."));let pt=d,$r=
|
|
1067
|
+
Start the gateway and try again, or pass --force to configure anyway.`),1;B(`Gateway reachable (${D.detail}).`)}let Qe=o.revert?[]:await R5(d,j.origin),Oe=[],ve=()=>{Oe.length!==0&&(H("Reopening"),P5(Oe),Oe=[])};if(Qe.length>0){let D=Qe.map(X=>X.title),$=D.length===1?"it":"them";if(H("Open apps"),O5(o,gt()))o.quitApps===!0||await Io(T5(D))?Oe=await _5(Qe):L(` Leaving ${$} open \u2014 restart when convenient.`);else{let X=o.noQuitApps===!0?"":" (or pass --quit-apps)";L(o.dryRun?` Would offer to quit ${D.join(", ")} \u2014 dry run, nothing was closed.`:` ${D.join(", ")} ${D.length===1?"is":"are"} open; restart ${$} to pick this up${X}.`)}}let ut=async()=>{if(!o.dryRun)try{await et()}catch{return R("Could not prepare the owner-only Anyray state directory."),1}let D=BE(s,G),$=s.anyrayFleetManaged===!0&&await To().catch(()=>!1),X=Q0(o,Tu(),$),he=!!(S&&j.clientKey===S&&!I),Gt=!he&&!!(I??s.enrolledCert),Z=d.some(Be=>ME.has(Be.id)),Le=!o.revert&&o.noKeyRefresh!==!0&&Gt&&(D||!Z),Se=o.dryRun?await Go(s):await bp(),Ye=Se==="healthy";if(Se==="healed"&&(delete s.persistenceOwner,delete s.trayAppPath),!o.revert&&!o.dryRun){let Be={...s,managedEnrollmentDisabled:void 0,gateway:j.origin,name:k,team:C,clientKey:j.clientKey??s.clientKey,enrolledCert:he?void 0:I??s.enrolledCert,enrolledCertExpiry:he?void 0:_??s.enrolledCertExpiry,enrolledTokenHash:he?void 0:W??s.enrolledTokenHash,ssoLink:he?void 0:w?Q:I?void 0:s.ssoLink,clientKeyExpiresAt:he?void 0:G??(j.clientKey===s.clientKey?.trim()?s.clientKeyExpiresAt:void 0),authMode:j.authMode,byoUpstream:j.byoUpstream,refreshSchedulerEnabled:Le};try{await v5(s,Be,T,void 0,he)}catch{return R("Could not save the owner-only Anyray runtime profile. No tool configuration was changed."),1}G&&!he&&await $a({expiresAt:G})}if(le)if(o.dryRun)await Ku()&&(H("Enrollment"),A(" would remove the stored gateway credential"));else{await wg(s),await Wd().catch(()=>{});try{await oc()&&(H("Enrollment"),B(" Removed the stored gateway credential."),L(" Reconnect any time with `npx anyray-connect@latest --sso`."))}catch(Be){H("Enrollment"),O(" Could not remove the stored gateway credential."),O(` Delete ${ee()} by hand, or a credential refresh may restore your tool config.`)}}else o.revert&&!o.dryRun&&(A(`
|
|
1068
|
+
Keeping the stored enrollment \u2014 the tools you did not name still need it.`),A("Run --revert with no --tools to remove it."));let pt=d,$r=I5(pt,o,s.managedTools);if($r.length>0){H("Not configured \u2014 needs your say-so");for(let Te of $r)O(` ${Te.id}: ${ZR(Te)??"changes where inference is billed"}.`),A(` Configure it deliberately with \`npx anyray-connect --tools ${Te.id}\`.`);let Be=new Set($r.map(Te=>Te.id));pt=pt.filter(Te=>!Be.has(Te.id))}if(o.revert&&!le){let Be=d.filter(Te=>bi(s,Te.id));if(Be.length>0){H("Fleet policy");for(let Te of Be)O(` ${Te.id}: locked by your admin's fleet policy \u2014 leaving it configured. Ask an admin to change the tool's tier.`);pt=d.filter(Te=>!bi(s,Te.id))}}let{changes:zi,manual:Qa,manualAdminOnly:qi,manualAdminOnlyIds:es,results:ts}=await S5(pt,j,U,o.revert,new Set(o.tools??[])),ns;if(ag(o)){H("Endpoint agent");try{ns=await(n.installEndpointAfterEnrollment??cR)({gateway:b,clientKey:j.clientKey})}catch{L("Endpoint agent setup did not complete. Tool routing remains configured.")}}let Po=X&&q0(ns),rs=Le&&!Po;if(X&&!Po&&Le&&!o.dryRun&&L(" The machine is not under endpoint policy, so automatic key refresh stays on this seat."),Po&&!o.dryRun&&await ce({...await P(),refreshSchedulerEnabled:!1}).catch(()=>{}),o.dryRun||(await Jn(ts,o.revert,le).catch(()=>{}),le&&await ac().catch(()=>{})),await N5({want:rs,scopedRevert:!!o.revert&&!le,dryRun:!!o.dryRun,wasEnabled:!!s.refreshSchedulerEnabled||!rs&&await Rc(),trayManaged:Ye}),!o.revert&&!o.dryRun&&!he){let Be=T??await Fe();Be&&await Bh(await P(),Be).catch(()=>{})}if(ve(),H("Summary"),o.dryRun)L("Dry run complete \u2014 re-run without --dry-run to apply.");else if(o.revert){B(`Reverted (${zi} file(s) touched).`),L("Restart any editor or agent that was running \u2014 it loaded our hooks at startup.");let Be=await uI();Be.length>0&&(H("This repo carries its own Anyray routing"),O(` Committed here: ${Be.join(", ")}`),O(" Those are tracked files, so they route every checkout of this"),O(" repo \u2014 this machine included, and your teammates' too. This"),O(" revert only removed THIS machine's own configuration."),A(`
|
|
1069
1069
|
Remove them from the repo (then commit):`),A(v(" anyray-connect --project --revert")));let Te=Uc(j);Te.length>0&&(H("This terminal still points at the gateway"),O(` Still exported here: ${Te.join(", ")}`),O(" Removing the block from your shell profile cannot reach a shell"),O(" that already ran it. Until these are gone, your tools keep"),O(" reaching the gateway and now fail with 401."),A(`
|
|
1070
1070
|
Fix this terminal:`),A(v(` unset ${Te.join(" ")}`)),A(`
|
|
1071
|
-
Every other open terminal needs the same \u2014 or just open a new one.`),A(" VS Code injects a copy it captured when IT launched, so its"),A(" terminals stay stale even if you open a new one: quit the app"),A(" entirely (Cmd+Q). Reloading the window keeps the old copy."))}else{if(B(`Done (${zi} file(s) written).`),Qa.length>0){let Rt=qi.length===Qa.length;H(Rt?"Blocked by machine policy \u2014 nothing for you to do":"Action required \u2014 manual steps");for(let Rg of
|
|
1072
|
-
Skipped the connection smoke test (--skip-verify).`):await
|
|
1071
|
+
Every other open terminal needs the same \u2014 or just open a new one.`),A(" VS Code injects a copy it captured when IT launched, so its"),A(" terminals stay stale even if you open a new one: quit the app"),A(" entirely (Cmd+Q). Reloading the window keeps the old copy."))}else{if(B(`Done (${zi} file(s) written).`),Qa.length>0){let Rt=qi.length===Qa.length;H(Rt?"Blocked by machine policy \u2014 nothing for you to do":"Action required \u2014 manual steps");for(let Rg of E5(Qa,qi,es.includes("claude-desktop")?process.platform:void 0))O(Rg);if(es.includes("claude-desktop")&&!o.dryRun)try{await x5(j)}catch{O(" Could not write the administrator profile locally. Your admin can generate it with `anyray-connect desktop fleet static macos <helper-path> --gateway <url>`.")}gt()&&!o.yes&&!Rt&&(await Io("Have you applied the manual settings shown above?")?B("Acknowledged."):O("Apply them before using the tool, or it will keep sending traffic straight to the provider (unattributed)."))}o.skipVerify?L(`
|
|
1072
|
+
Skipped the connection smoke test (--skip-verify).`):await L5(j,d.map(Rt=>Rt.id)),H("What's next");let Be=new Set(ts.filter(Rt=>Rt.status==="configured").map(Rt=>Rt.id)),Te=d.filter(Rt=>Be.has(Rt.id)).map(Rt=>Rt.title);if(A(Te.length>0?` Connected: ${Te.join(", ")}`:" Connected: no tools completed automatic configuration."),A(" Restart any editor that was already running \u2014 it loaded our config at startup."),A(" If something looks wrong: npx anyray-connect doctor"),be(j.clientKey)&&await z5({interactive:gt(),managed:n.managedEnrollmentRevertedTools!==void 0,yes:!!o.yes,revert:!!o.revert,dryRun:!!o.dryRun,gateway:j.origin,user:j.metadata.user,team:j.metadata.team,clientKey:j.clientKey}),!o.verbose)return 0;A(`
|
|
1073
1073
|
Re-test by hand any time:`),j.authMode!=="placeholder"&&d.length===1&&d[0]?.id==="cursor"?(A(v(` curl -sS ${j.origin}/connect/savings \\
|
|
1074
1074
|
-H "x-anyray-api-key: $(anyray-connect print-key)"`)),A(v(" Validate Opus itself inside Cursor: keep the Team login, select a native Claude Opus model, and run an Agent prompt."))):A(v(` curl -sS ${j.openaiBaseUrl}/chat/completions \\
|
|
1075
1075
|
-H "Content-Type: application/json" \\
|
|
1076
1076
|
-H "Authorization: Bearer ${j.clientKey?`<your personal key (${Pt(j.clientKey)}) \u2014 see your tool config>`:"<enrollment required>"}" \\
|
|
1077
|
-
-d '{"model":"anyray-default","messages":[{"role":"user","content":"ping"}],"max_tokens":16}'`)),A(v(" Revert: npx anyray-connect --revert"))}return 0};try{return await
|
|
1077
|
+
-d '{"model":"anyray-default","messages":[{"role":"user","content":"ping"}],"max_tokens":16}'`)),A(v(" Revert: npx anyray-connect --revert"))}return 0};try{return await W5(o.revert,o.dryRun,ut,n.withProfileLock)}catch(D){if(D instanceof Error&&D.message==="connect profile is busy; retry the command")return R("Another Connect update is in progress. Try again."),1;throw D}finally{ve()}};XR(process.argv.slice(2)).then(e=>{process.exitCode=e}).catch(e=>{console.error(e),process.exitCode=1});
|