@reason-machines/cli-linux-x64 0.2.415 → 0.2.418
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/bin/reason +1 -1
- package/bin/runtime/srt/sandbox-runtime.mjs +38 -38
- package/bin/vm-hands/api-18d75dfn.js +2 -0
- package/bin/vm-hands/api-credentials-3vhge1ap.js +2 -0
- package/bin/vm-hands/connect-cli-pn1h0b08.js +2 -0
- package/bin/vm-hands/custom-endpoint-device-17t4efc4.js +2 -0
- package/bin/vm-hands/desktop-account-6sjrxy69.js +2 -0
- package/bin/vm-hands/device-workspace-s50q53sz.js +2 -0
- package/bin/vm-hands/{fsevents-ekt70rcc.js → fsevents-p3d8kd0p.js} +1 -1
- package/bin/vm-hands/hands-worker-source-kddz4y15.js +2 -0
- package/bin/vm-hands/{index-k8kcz8a3.js → index-wrw65904.js} +35 -35
- package/bin/vm-hands/install-receipt-ysa70fvh.js +2 -0
- package/bin/vm-hands/local-automation-7nc6cgjp.js +2 -0
- package/bin/vm-hands/local-capabilities-5f36fr9x.js +2 -0
- package/bin/vm-hands/local-desktop-users-cppjjr81.js +2 -0
- package/bin/vm-hands/local-display-mac-0qz3b627.js +2 -0
- package/bin/vm-hands/local-display-session-zg4dpnf1.js +2 -0
- package/bin/vm-hands/local-display-video-remg1c30.js +2 -0
- package/bin/vm-hands/local-managed-process-gjc8gvgb.js +2 -0
- package/bin/vm-hands/local-pty-session-rpk05ap5.js +2 -0
- package/bin/vm-hands/managed-runtime-f85h6h7f.js +2 -0
- package/bin/vm-hands/network-contract-trkxqc0w.js +2 -0
- package/bin/vm-hands/package-xqbhdf15.js +2 -0
- package/bin/vm-hands/permissions-bhbnb1bp.js +2 -0
- package/bin/vm-hands/reason-hands-protocol-xn3ddz70.js +2 -0
- package/bin/vm-hands/serve-service-58ea9cwx.js +2 -0
- package/bin/vm-hands/status-z9r8nq3y.js +10 -0
- package/bin/vm-hands/version-p0g28erd.js +2 -0
- package/bin/vm-hands/{vm-hands-entry-lite-bdhjpv7g.js → vm-hands-entry-lite-21qpxvt8.js} +2 -2
- package/bin/vm-hands/vm-hands-entry-lite-2nkj0dpx.js +539 -0
- package/bin/vm-hands/vm-hands-entry-lite-2wzsnnsp.js +3 -0
- package/bin/vm-hands/{vm-hands-entry-lite-8t9xssf9.js → vm-hands-entry-lite-3krzmhkk.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-k278g9kj.js → vm-hands-entry-lite-4vks5phw.js} +5 -5
- package/bin/vm-hands/{vm-hands-entry-lite-1cwqa4jr.js → vm-hands-entry-lite-50zbqwkv.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-1rrb66r9.js → vm-hands-entry-lite-5dtfehjv.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-6aeea05q.js → vm-hands-entry-lite-60pg3wxj.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-9ay6f56v.js → vm-hands-entry-lite-6c67a3jc.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-txn44020.js → vm-hands-entry-lite-6wt5ja1k.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-zg36myyf.js → vm-hands-entry-lite-8r31b0ps.js} +4 -4
- package/bin/vm-hands/vm-hands-entry-lite-ah6fwqxp.js +128 -0
- package/bin/vm-hands/{vm-hands-entry-lite-ckv17tn8.js → vm-hands-entry-lite-aj139v8j.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-907pa7f9.js → vm-hands-entry-lite-avc65bd7.js} +6 -6
- package/bin/vm-hands/{vm-hands-entry-lite-9c95p6n9.js → vm-hands-entry-lite-beyyy1gz.js} +37 -37
- package/bin/vm-hands/{vm-hands-entry-lite-ab2m9erf.js → vm-hands-entry-lite-bx5zy5bd.js} +1 -1
- package/bin/vm-hands/{vm-hands-entry-lite-pgb514h0.js → vm-hands-entry-lite-dk79tnax.js} +2 -2
- package/bin/vm-hands/vm-hands-entry-lite-ec9jemny.js +5 -0
- package/bin/vm-hands/{vm-hands-entry-lite-gvwdy3rf.js → vm-hands-entry-lite-fbhqfzbq.js} +3 -3
- package/bin/vm-hands/{vm-hands-entry-lite-t7an5zg2.js → vm-hands-entry-lite-fcvf8md1.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-qysyf65v.js → vm-hands-entry-lite-g4zd2d5n.js} +1 -1
- package/bin/vm-hands/{vm-hands-entry-lite-0xrsph3r.js → vm-hands-entry-lite-hbs3tpdg.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-f5e3dbgk.js → vm-hands-entry-lite-hk6trmwa.js} +3 -3
- package/bin/vm-hands/{vm-hands-entry-lite-2hvbgp1n.js → vm-hands-entry-lite-hn76pcgk.js} +5 -5
- package/bin/vm-hands/vm-hands-entry-lite-j43nqe8y.js +452 -0
- package/bin/vm-hands/{vm-hands-entry-lite-89z488gz.js → vm-hands-entry-lite-jev771b3.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-eqgj4acy.js → vm-hands-entry-lite-jzz73e3f.js} +10 -10
- package/bin/vm-hands/vm-hands-entry-lite-m8nqnd9j.js +126 -0
- package/bin/vm-hands/vm-hands-entry-lite-mmdwr0mf.js +2 -0
- package/bin/vm-hands/{vm-hands-entry-lite-2wgdvb15.js → vm-hands-entry-lite-nefcet81.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-hj8n59y9.js → vm-hands-entry-lite-np07qyeq.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-1rtkf2xm.js → vm-hands-entry-lite-nzmkyezg.js} +2 -2
- package/bin/vm-hands/{vm-hands-entry-lite-q0k6kx6d.js → vm-hands-entry-lite-pf5qtbj5.js} +4 -4
- package/bin/vm-hands/{vm-hands-entry-lite-qxchbbew.js → vm-hands-entry-lite-ppmvge7n.js} +5 -5
- package/bin/vm-hands/{vm-hands-entry-lite-m11j0f9q.js → vm-hands-entry-lite-rfz60hb3.js} +2 -2
- package/bin/vm-hands/vm-hands-entry-lite-s3cg1dsk.js +52 -0
- package/bin/vm-hands/vm-hands-entry-lite-s4bharcb.js +9 -0
- package/bin/vm-hands/{vm-hands-entry-lite-88swf2qr.js → vm-hands-entry-lite-s5qkb1fk.js} +3 -3
- package/bin/vm-hands/{vm-hands-entry-lite-cc2tgsqp.js → vm-hands-entry-lite-stmbekq0.js} +16 -16
- package/bin/vm-hands/{vm-hands-entry-lite-kq0qmsw8.js → vm-hands-entry-lite-svvysppj.js} +4 -4
- package/bin/vm-hands/{vm-hands-entry-lite-22kfyvnk.js → vm-hands-entry-lite-tdgtpx8e.js} +1 -1
- package/bin/vm-hands/{vm-hands-entry-lite-b885gwfh.js → vm-hands-entry-lite-vpz54vwj.js} +6 -6
- package/bin/vm-hands/vm-hands-entry-lite-w8w451gj.js +4 -0
- package/bin/vm-hands/{vm-hands-entry-lite-09m2cdkw.js → vm-hands-entry-lite-wx4ax7wg.js} +3 -3
- package/bin/vm-hands/vm-hands-entry-lite-yretc2th.js +3 -0
- package/bin/vm-hands/vm-hands-entry-lite-z76nfb19.js +3 -0
- package/bin/vm-hands/vm-hands-entry-lite-zp6naptr.js +3 -0
- package/bin/vm-hands/vm-hands-entry-lite.js +2 -2
- package/bin/vm-hands/vm-hands-executor-73b49jkg.js +11 -0
- package/bin/vm-hands/vm-hands-op-runner-ef9ts9c6.js +2 -0
- package/bin/vm-hands/vm-hands-runtime-8z6rx1fj.js +4 -0
- package/bin/vm-hands/worker-preview-readiness-w62n91kr.js +2 -0
- package/bin/vm-hands/worker-sandbox-2r5nseff.js +2 -0
- package/package.json +1 -1
- package/bin/vm-hands/api-cjv8m2zy.js +0 -2
- package/bin/vm-hands/api-credentials-m5akr9fv.js +0 -2
- package/bin/vm-hands/connect-cli-d60gmgnx.js +0 -2
- package/bin/vm-hands/custom-endpoint-device-dkqb4rqy.js +0 -2
- package/bin/vm-hands/desktop-account-5v7x0ajx.js +0 -2
- package/bin/vm-hands/device-workspace-p9q9dckg.js +0 -2
- package/bin/vm-hands/hands-worker-source-cgrpm21b.js +0 -2
- package/bin/vm-hands/install-receipt-7vt2y2vh.js +0 -2
- package/bin/vm-hands/local-automation-4htjhv65.js +0 -2
- package/bin/vm-hands/local-capabilities-c04tbapa.js +0 -2
- package/bin/vm-hands/local-desktop-users-q886k0mm.js +0 -2
- package/bin/vm-hands/local-display-mac-w85956f1.js +0 -2
- package/bin/vm-hands/local-display-session-pkz7a5q9.js +0 -2
- package/bin/vm-hands/local-pty-session-5f50sqq0.js +0 -2
- package/bin/vm-hands/managed-runtime-ppypxbh9.js +0 -2
- package/bin/vm-hands/network-contract-9x9kc5vv.js +0 -2
- package/bin/vm-hands/package-78fkast4.js +0 -2
- package/bin/vm-hands/permissions-xt02c6dh.js +0 -2
- package/bin/vm-hands/reason-hands-protocol-2tnghj3b.js +0 -2
- package/bin/vm-hands/serve-service-wanptaqv.js +0 -2
- package/bin/vm-hands/status-gt7c4ke0.js +0 -10
- package/bin/vm-hands/version-bq5j7cqg.js +0 -2
- package/bin/vm-hands/vm-hands-entry-lite-2wvsyggd.js +0 -540
- package/bin/vm-hands/vm-hands-entry-lite-463m6ejk.js +0 -458
- package/bin/vm-hands/vm-hands-entry-lite-8ns59paz.js +0 -3
- package/bin/vm-hands/vm-hands-entry-lite-ewwx4fr3.js +0 -250
- package/bin/vm-hands/vm-hands-entry-lite-grtycq6y.js +0 -52
- package/bin/vm-hands/vm-hands-entry-lite-pmcz7j7t.js +0 -3
- package/bin/vm-hands/vm-hands-entry-lite-qq9w7wq6.js +0 -3
- package/bin/vm-hands/vm-hands-entry-lite-rwxbhwky.js +0 -2
- package/bin/vm-hands/vm-hands-entry-lite-vrqzr15t.js +0 -3
- package/bin/vm-hands/vm-hands-executor-7k9z9988.js +0 -11
- package/bin/vm-hands/vm-hands-op-runner-n8p81rwm.js +0 -2
- package/bin/vm-hands/vm-hands-runtime-bqsz7h0h.js +0 -4
- package/bin/vm-hands/worker-sandbox-smqj3mbe.js +0 -2
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{ct,Lt,Cr,Sn,Ar,En,xn,kn}from"./vm-hands-entry-lite-bx5zy5bd.js";import{Pe,ir,Qn,yt,No,oe,Lo,Mo,et,Te,rn,ti,bt,Re,vt,ni,ii,oi,si,ai,ci,li,ui,di,pi,hi,fi,mi,gi,_i,pe,Y,Oe,q,yi,wi,bi,vi,Si,Ei,xi,ki,St,Ci}from"./vm-hands-entry-lite-4vks5phw.js";import{ue,Z,O}from"./vm-hands-entry-lite-3krzmhkk.js";import{P,Wt}from"./vm-hands-entry-lite-tdgtpx8e.js";import{dr,Hi,zi,it,qi,Wi,Vi,Gi,Ki,Ji,fr,mr,gr,hn,fn,_r,Xi,mn,yr,me,ge,Rt,wr,vr,Ot}from"./vm-hands-entry-lite-j43nqe8y.js";import{D,R,b}from"./vm-hands-entry-lite-beyyy1gz.js";import{Bi,Fi,dn,ji,pn,Ui,nt,ur}from"./vm-hands-entry-lite-w8w451gj.js";import{K}from"./vm-hands-entry-lite-hk6trmwa.js";import{ze}from"./vm-hands-entry-lite-s5qkb1fk.js";import{j}from"./vm-hands-entry-lite-pf5qtbj5.js";import{Er,wn,no}from"./vm-hands-entry-lite-vpz54vwj.js";import{bo,vo,ft,So,Eo,xo,ko,Co}from"./vm-hands-entry-lite-jzz73e3f.js";import{Rr,jt,Or,Dn,Nn}from"./vm-hands-entry-lite-nzmkyezg.js";import{$t,qe,Bt}from"./vm-hands-entry-lite-ah6fwqxp.js";import{In,x,co}from"./vm-hands-entry-lite-m8nqnd9j.js";import{yo,wo}from"./vm-hands-entry-lite-nefcet81.js";import{Mt,Cn,An}from"./vm-hands-entry-lite-ppmvge7n.js";import{ye,Qi,eo}from"./vm-hands-entry-lite-s4bharcb.js";import{be}from"./vm-hands-entry-lite-yretc2th.js";import{Nt}from"./vm-hands-entry-lite-np07qyeq.js";import{ke,Zt,Xt,Yt,E}from"./vm-hands-entry-lite-dk79tnax.js";import{a,ie}from"./vm-hands-entry-lite-jev771b3.js";import{t,k,o,d,u,i,W,_,ee,s,n,Fo}from"./vm-hands-entry-lite-avc65bd7.js";import{fe,Le,Me,$e,sn}from"./vm-hands-entry-lite-6c67a3jc.js";import{Be}from"./vm-hands-entry-lite-zp6naptr.js";import{r}from"./vm-hands-entry-lite-qy9xg6em.js";import{request as Ul}from"http";import{request as Hl}from"https";import{lookup as jl}from"dns/promises";import{isIP as ql}from"net";async function Wl(e){let l=new URL(e.url);return await new Promise((c,p)=>{let m=(l.protocol==="https:"?Hl:Ul)(l,{method:"POST",headers:{...e.headers,"accept-encoding":"identity"},signal:e.signal,timeout:Sn},(f)=>c({response:f,close:()=>{f.destroy(),m.destroy(),f.socket?.destroy()}}));m.once("error",p),m.once("timeout",()=>m.destroy(Object.assign(Error("custom_endpoint_timeout"),{code:"ETIMEDOUT"}))),m.end(e.body)})}var os=new Set(["ENOTFOUND","EAI_AGAIN","EAI_NONAME","EAI_NODATA","EAI_FAIL","DNSException"]),Gl=new Set(["ECONNREFUSED","ETIMEDOUT","ECONNRESET","EHOSTUNREACH","ENETUNREACH","EHOSTDOWN","ENETDOWN","EPIPE","ECONNABORTED","EADDRNOTAVAIL","ConnectionRefused","ConnectionClosed","ConnectionTimedOut","Timeout"]);function is(e,l=0){if(!e||typeof e!=="object"||l>3)return null;let c=e.code;if(typeof c==="string"){if(os.has(c))return"custom_endpoint_host_not_found";if(Gl.has(c))return"custom_endpoint_connection_failed";if(/^(?:ERR_TLS_|ERR_SSL_|CERT_|UNABLE_TO_(?:GET|VERIFY|DECRYPT)|DEPTH_ZERO_SELF_SIGNED|SELF_SIGNED_CERT|HOSTNAME_MISMATCH|EPROTO$)/.test(c))return"custom_endpoint_tls_failed"}for(let p of[...e instanceof AggregateError?e.errors:[],e.cause]){let m=is(p,l+1);if(m)return m}return null}async function zl(e,l){let c=is(e),p=new URL(l).hostname.replace(/^\[|\]$/g,"");if(c!==null&&c!=="custom_endpoint_connection_failed"||ql(p)!==0)return c;let m;return await Promise.race([jl(p).then(()=>!0,(h)=>!os.has(String(h?.code))),new Promise((h)=>{m=setTimeout(()=>h(!0),5000)})]).finally(()=>clearTimeout(m))?c:"custom_endpoint_host_not_found"}function Vl(e){for(let l=42;;l++){if(l===127)l=256;let c=String.fromCodePoint(l);if(!e.includes(c))return c}}function Kl(e,l){let c=Buffer.from(e),p=Buffer.from(l),m=new Uint32Array(c.length);for(let h=1,y=0;h<c.length;h++){while(y&&c[h]!==c[y])y=m[y-1];if(c[h]===c[y])y++;m[h]=y}let f=0;return(h,y=!1)=>{let S=Buffer.allocUnsafe(h.length*p.length+f),w=0;for(let g of h){while(f&&c[f]!==g){let v=m[f-1];w+=c.copy(S,w,0,f-v),f=v}if(c[f]===g){if(f++,f===c.length)w+=p.copy(S,w),f=0}else S[w++]=g}if(y)w+=c.copy(S,w,0,f),f=0;return S.subarray(0,w)}}async function ss(e){e.signal.throwIfAborted();let l=En.safeParse(e.payload);if(!l.success)throw new r("custom_endpoint_invalid_request","Invalid local model request.");let c=l.data,p=xn.parse(await e.credential(e.signal));if(!Ar(c,{baseUrl:c.baseUrl,api:p.api,execution:"device"}))throw new r("custom_endpoint_invalid_request","The request does not match the configured API.");e.signal.throwIfAborted();let m,f,h=0,y=0,S=0,w=Vl(p.apiKey),g=Kl(p.apiKey,w),v=async(A,I)=>{e.signal.throwIfAborted(),await new Promise((M,N)=>{let L=()=>{e.signal.removeEventListener("abort",L),N(e.signal.reason)};if(e.signal.addEventListener("abort",L,{once:!0}),e.signal.aborted){L();return}Promise.resolve().then(()=>(e.signal.throwIfAborted(),e.emit(A,I))).then(()=>{e.signal.removeEventListener("abort",L),M()},(B)=>{e.signal.removeEventListener("abort",L),N(B)})})},C=async(A)=>{if(h+=A.length,h>Lt)throw new r("custom_endpoint_response_too_large","Local model response exceeds the transport limit.");for(let I=0;I<A.length;I+=ct){if(S>=Cr)throw new r("custom_endpoint_response_too_large","Local model response exceeds the chunk limit.");await v(`custom_endpoint.chunk.${S++}`,{eof:!1,data:A.subarray(I,I+ct).toString("base64")})}};try{let A=await Wl({url:c.url,body:c.body,signal:e.signal,headers:{...c.headers,...p.api==="anthropic-messages"?{"x-api-key":p.apiKey}:{authorization:`Bearer ${p.apiKey}`}}});m=A.response,f=A.close;let I=m.statusCode??500;if(I>=300&&I<400)throw new r("custom_endpoint_redirect_refused","Local model redirects are not followed.");if(m.headers["content-encoding"]&&m.headers["content-encoding"]!=="identity")throw new r("custom_endpoint_encoding_unsupported","The local server must honor identity encoding.");let M={};for(let N of["content-type","retry-after","x-request-id","request-id"]){let L=m.headers[N];if(typeof L==="string")M[N]=L.replaceAll(p.apiKey,w).slice(0,4096)}await v("custom_endpoint.headers",{status:I,statusText:(m.statusMessage??"").replaceAll(p.apiKey,w).slice(0,256),headers:M});for await(let N of m){e.signal.throwIfAborted();let L=Buffer.isBuffer(N)?N:Buffer.from(N);if(y+=L.length,y>Lt)throw new r("custom_endpoint_response_too_large","Local model response exceeds the transport limit.");await C(g(L))}return await C(g(Buffer.alloc(0),!0)),await v(`custom_endpoint.chunk.${S}`,{eof:!0}),{bytes:h,chunks:S}}catch(A){if(e.signal.throwIfAborted(),A instanceof r)throw A;throw new r((m?null:await zl(A,c.url))??"custom_endpoint_request_failed","The local model server could not complete the request.")}finally{f?.()}}import{join as as}from"path";function Yl(e,l){return e===as(l,".ara","workspace")||e===as(l,".reason","workspace")}function ls(e,l){let c=e.filter((p)=>Yl(p.path,l));return c.length===1?c[0].path:null}var Xl=/^[a-f0-9]{64}$/;var gn=32,Jl=/^\/[^\x00-\x1f\x7f\\]*$/;function kr(e){if(typeof e!=="string"||e.length>4096||!Jl.test(e))return!1;if(e==="/")return!0;return e.split("/").slice(1).every((l)=>l!==""&&l!=="."&&l!=="..")}function Tr(e,l){let c=l==="win32"?/^([A-Za-z]):[\\/]*(.*)$/.exec(e):null;if(!c)return e;let p=c[2].split(/[\\/]+/).filter(Boolean).join("/");return`/${c[1].toUpperCase()}:${p?`/${p}`:""}`}function _n(e){if(!e||typeof e!=="object"||Array.isArray(e))return;let l=e;if(!kr(l.home)||!Array.isArray(l.roots)||l.roots.length>gn)return;let c=[];for(let p of l.roots){if(!p||typeof p!=="object"||Array.isArray(p))return;let{path_fingerprint:m,path:f}=p;if(typeof m!=="string"||!Xl.test(m)||!kr(f))return;c.push({path_fingerprint:m,path:f})}return{home:l.home,roots:c}}function Zl(e){let l=/^Reason contributor (rc_[0-9a-f]{32})$/.exec(e.name)?.[1];return e.email.toLowerCase()==="343777287+reason-contributors@users.noreply.github.com"&&l?l:void 0}function Ql(e){return Zl(e)??e.email.toLowerCase()}function yn(e){let l=/^Co-authored-by:\s*([^<>\r\n]+) <([^<>\s]+)>$/i.exec(e.trim());return l?Ql({name:l[1],email:l[2]}):e.trim().toLowerCase()}var zt=(e)=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/[a-z]/gi,(l)=>`[${l.toLowerCase()}${l.toUpperCase()}]`),ec=[...ke.map((e)=>`/(${e.map(zt).join("/")})(/|$)`),...Zt.map((e)=>`/(${e.map(zt).join("/")})(/|$)`),...[...Xt].map((e)=>`/(${zt(e)})$`),`/${zt(".env.")}[^/]*$`,...Yt.map((e)=>`/[^/]*${zt(e)}$`)],cs=`function localGithubSandboxProfile(root, temporary) {
|
|
3
|
+
return ['(version 1)','(deny default)','(import "system.sb")','(allow process-exec process-fork)',
|
|
4
|
+
'(allow file-read* (subpath "/bin") (subpath "/sbin") (subpath "/usr/bin") (subpath "/usr/sbin") (subpath "/usr/libexec") (subpath "/usr/share") (subpath "/private/var/select") (literal "/private/var/db/xcode_select_link"))',
|
|
5
|
+
'(allow file-read-metadata (path-ancestors "/opt/homebrew/bin") (path-ancestors "/usr/local/bin") (path-ancestors "/Library/Developer/CommandLineTools"))',
|
|
6
|
+
'(allow file-read* (subpath "/opt/homebrew/Cellar") (subpath "/opt/homebrew/opt") (subpath "/opt/homebrew/bin") (subpath "/opt/homebrew/lib") (subpath "/opt/homebrew/share") (subpath "/opt/homebrew/include") (subpath "/usr/local/Cellar") (subpath "/usr/local/opt") (subpath "/usr/local/bin") (subpath "/usr/local/lib") (subpath "/usr/local/share") (subpath "/usr/local/include") (subpath "/Library/Developer/CommandLineTools"))',
|
|
7
|
+
'(allow file-read* file-write* (subpath '+JSON.stringify(root)+') (subpath '+JSON.stringify(temporary)+'))',
|
|
8
|
+
'(allow file-read-metadata (path-ancestors '+JSON.stringify(root)+') (path-ancestors '+JSON.stringify(temporary)+'))',
|
|
9
|
+
'(deny file-read* file-write* (subpath "/opt/homebrew/etc") (subpath "/usr/local/etc") (literal "/private/etc/master.passwd"))',
|
|
10
|
+
'(deny file-write* (subpath "/opt/homebrew") (subpath "/usr/local") (subpath "/Library/Developer") (subpath "/cores"))',
|
|
11
|
+
...${JSON.stringify(ec)}.map(pattern => '(deny file-read* file-write* (regex #"'+pattern+'"))'),
|
|
12
|
+
'(deny network*)','(deny mach-lookup)','(deny process-info*)','(allow process-info* (target same-sandbox))','(allow process-info-listpids)','(allow file-read-metadata (subpath "/dev"))','(deny signal)','(allow signal (target same-sandbox))'].join('\\n');
|
|
13
|
+
}`;import{spawn as rc,spawnSync as nc}from"child_process";import*as V from"fs";import*as se from"path";import{homedir as oc}from"os";function us(e,l,c,p="gh"){if(!["gh","git"].includes(p))throw Error("local_device_gh_unavailable");let m=e.realpathSync(c);if(process.platform==="win32"){let h=(y)=>y.toLowerCase()===m.toLowerCase()||y.toLowerCase().startsWith(m.toLowerCase()+l.sep);for(let y of new Set([process.env.ProgramW6432,process.env.ProgramFiles])){if(!y)continue;try{let S=e.realpathSync(p==="gh"?`${y}\\GitHub CLI\\gh.exe`:`${y}\\Git\\cmd\\git.exe`);if(!h(S)&&S.toLowerCase().startsWith(y.toLowerCase()+"\\")&&e.statSync(S).isFile())return S}catch{}}throw Error("local_device_gh_unavailable")}let f=p==="git"&&process.platform==="darwin"?"/Library/Developer/CommandLineTools/usr/bin/git":"/usr/bin/"+p;for(let h of["/opt/homebrew/bin/"+p,"/usr/local/bin/"+p,f])try{let y=e.realpathSync(h);if(y===m||y.startsWith(m+l.sep)||!["/opt/homebrew/","/usr/local/","/usr/bin/",...p==="git"?["/Library/Developer/CommandLineTools/"]:[]].some((w)=>y.startsWith(w)))continue;let S=e.statSync(y);if(!S.isFile()||(S.mode&18)!==0||![0,process.getuid()].includes(S.uid))continue;return e.accessSync(y,e.constants.X_OK),y}catch{continue}throw Error("local_device_gh_unavailable")}function ds(e,l){let c=1;for(let p=0;p<l;p+=1)if(e.charCodeAt(p)===10)c+=1;return c}var ps=[{name:"private_key",regex:/-----BEGIN\s+(?:[A-Z0-9_-]+\s+)?PRIVATE\s+KEY-----/i},{name:"github_pat",regex:/\bgh[pousr]_[A-Za-z0-9_]{36,}\b/},{name:"github_fine_grained_pat",regex:/\bgithub_pat_[A-Za-z0-9_]{36,}\b/},{name:"gitlab_pat",regex:/\bglpat-[0-9a-zA-Z_-]{20,}\b/},{name:"slack_token",regex:/\bxox[baprs]-[0-9]{10,}-[0-9]{10,}-[0-9a-zA-Z]{24}\b/},{name:"stripe_live_key",regex:/\b[sr]k_live_[0-9a-zA-Z]{24,}\b/},{name:"bearer_jwt",regex:/\bBearer\s+ey[A-Za-z0-9_-]{20,}\.ey[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\b/}];function bn(e){let l=e.trim().replaceAll("\\","/");if(!l)return{valid:!1,reason:"empty_path"};if(l.startsWith("/"))return{valid:!1,reason:"absolute_path_forbidden"};if(l.split("/").includes("..")||l.includes("../")||l.endsWith("/.."))return{valid:!1,reason:"path_traversal_forbidden"};if(l===".git"||l.startsWith(".git/")||l.includes("/.git/"))return{valid:!1,reason:"git_directory_entry_forbidden"};return{valid:!0}}function ms(e){return[...new Set(e.map((l)=>l.trim()).filter((l)=>l.length>=8))]}function fs(e,l){return[...l.matchAll(new RegExp(e.regex.source,`${e.regex.flags}g`))]}function Dr(e,l=[],c={}){let p=[],m=c.published??new Set,f=ms(l).filter((h)=>!m.has(h));for(let h of e){let y=bn(h.path);if(!y.valid){p.push({path:h.path,reason:y.reason??"invalid_path"});continue}let S=h.content??"",w=f.map((g)=>({secret:g,offset:S.indexOf(g)})).filter((g)=>g.offset>=0).sort((g,v)=>g.offset-v.offset);if(w.length>0){let g=[...new Set(w.flatMap((v)=>c.secretNames?.(v.secret)??[]))];p.push({path:h.path,reason:"literal_secret_detected",ruleId:"forbidden_secret_value",line:ds(S,w[0].offset),...g.length>0?{secretNames:g}:{}})}for(let g of ps){let v=fs(g,S).find((C)=>!m.has(C[0]));if(v){p.push({path:h.path,reason:`credential_pattern_detected: ${g.name}`,pattern:g.name,ruleId:g.name,line:ds(S,v.index)});break}}}return{clean:p.length===0,violations:p,scannedObjectCount:e.length}}function hs(e,l=[]){let c=ms(l),p=new Set;for(let{content:m}of e){for(let f of c)if(m.includes(f))p.add(f);for(let f of ps)for(let h of fs(f,m))p.add(h[0])}return[...p]}function tc(e,l){let c=0;for(let p=e.indexOf(l);p>=0;p=e.indexOf(l,p+l.length))c+=1;return c}function gs(e,l,c){let p=(m,f)=>m.reduce((h,y)=>h+tc(y,f),0);return new Set(e.filter((m)=>p(l,m)<=p(c,m)))}var gt=4194304,Ye=process.platform==="win32",Kt=process.env.SystemRoot??"C:\\Windows",ic=(e)=>Ye?nc(se.win32.join(Kt,"System32","taskkill.exe"),["/PID",String(e),"/T","/F"],{stdio:"ignore",windowsHide:!0}):process.kill(-e,"SIGKILL"),Vt=Ye?[se.win32.join(Kt,"System32"),Kt].join(";"):"/usr/bin:/bin:/usr/sbin:/sbin",Nr=Ye?{SystemRoot:Kt,WINDIR:Kt}:{},sc=(e)=>Ye?se.win32.resolve(e,"..","..","bin","sh.exe"):"/bin/sh",_s=536870912,vn=/^[a-f0-9]{40}$/,ac=(e,l,c)=>new Promise((p)=>{if(c.signal?.aborted){p({status:null,error:Error("cancelled"),stdout:Buffer.alloc(0),stderr:Buffer.alloc(0)});return}let m;try{m=rc(e,l,{cwd:c.cwd,env:c.env,...Ye?{windowsHide:!0}:{detached:!0},stdio:["pipe","pipe","pipe"]})}catch{p({status:null,error:Error("spawn_failed"),stdout:Buffer.alloc(0),stderr:Buffer.alloc(0)});return}let f=Buffer.alloc(0),h=Buffer.alloc(0),y,S=!1,w=(A)=>{if(y??=Error(A),m.pid)try{ic(m.pid)}catch{}},g=()=>w("cancelled"),v=setTimeout(()=>w("timeout"),c.timeout);c.signal?.addEventListener("abort",g,{once:!0});let C=(A)=>{if(S)return;S=!0,clearTimeout(v),c.signal?.removeEventListener("abort",g),p({status:A,stdout:f,stderr:h,...y?{error:y}:{}})};if(m.stdout.on("data",(A)=>{if(f.length+h.length+A.length>c.maxBuffer)w("output_limit");else f=Buffer.concat([f,A])}),m.stderr.on("data",(A)=>{if(f.length+h.length+A.length>c.maxBuffer)w("output_limit");else h=Buffer.concat([h,A])}),m.on("error",()=>{if(w("spawn_failed"),!m.pid)C(null)}),m.on("close",(A)=>C(A)),m.stdin.on("error",()=>w("input_failed")),m.stdin.end(c.input),c.signal?.aborted)g()}),lc={command:ac,gh:(e,l)=>us(V,se,e,l),home:oc};function U(e){throw Error(e)}function Rn(e,l){let[c,p]=Ye?[e.toLowerCase(),l.toLowerCase()]:[e,l];return p===c||p.startsWith(c+se.sep)}function cc(e,l){let c=new Set(e.split(/\r?\n/).map(yn));return l.filter((p)=>{let m=yn(p);if(c.has(m))return!1;return c.add(m),!0})}var uc=new Set(["repoFullName","branch","head","base","defaultBranch","expectedBaseRef","baseSha","remoteHeadSha","expectedHeadSha"]),dc=(e)=>JSON.stringify(e,(l,c)=>uc.has(l)?void 0:c);function ys(e,l,c){let p=[...new Set(e.map((f)=>`${l(f.path)}${f.line?`:${f.line}`:""} (${f.reason==="literal_secret_detected"?`value of ${f.secretNames?.length?f.secretNames.slice(0,3).join(", "):"a session variable"}`:`${f.ruleId??"credential"} credential`})`))].slice(0,10),m=e.some((f)=>f.reason==="literal_secret_detected");U(`local_device_gh_secret_scan_failed: the change adds text matching a secret that the base does not already contain: ${p.join("; ")}. Nothing was sent. ${c}${m?" If the line is ordinary code, that variable's value is too generic to tell apart from code: tell the person which variable matched so they can change its value.":""}`)}async function bs(e,l,c=lc){let p=Pe.parse(e),m="local_device_gh_prepare_setup";try{if(!["darwin","linux","win32"].includes(process.platform))U("local_device_gh_platform_unavailable");l.assertCurrent();let f=V.realpathSync(l.root);if(f===se.parse(f).root)U("local_device_gh_root_unavailable");if(!et(p)&&!l.forbiddenSecretValues)U("local_device_gh_secret_scope_unavailable");if(!et(p)&&l.readOnly)U("local_device_gh_read_only");if(!et(p)){let T=Dr([{path:"github-operation",content:dc(p)}],l.forbiddenSecretValues,l.secretNames?{secretNames:l.secretNames}:{});if(!T.clean)ys(T.violations,()=>`the ${p.kind} request text`,"Remove it from the pull request text and try again.")}let h=c.gh(f),y=c.home(),S=c.gh(f,"git"),w=l.privateDirectory?V.realpathSync(l.privateDirectory):V.realpathSync(y);if(!et(p)&&(!l.privateDirectory||Rn(f,w)))U("local_device_gh_private_scope_unavailable");let g={...Nr,PATH:Ye?[se.dirname(S),Vt].join(";"):Vt,HOME:y,GH_CONFIG_DIR:Ye&&process.env.APPDATA?se.join(process.env.APPDATA,"GitHub CLI"):se.join(y,".config","gh"),GH_PROMPT_DISABLED:"1",GH_PAGER:Ye?"":"/bin/cat",GH_HOST:"github.com",GIT_CONFIG_NOSYSTEM:"1",GIT_CONFIG_SYSTEM:"/dev/null",GIT_CONFIG_GLOBAL:"/dev/null",GIT_TERMINAL_PROMPT:"0",GIT_NO_REPLACE_OBJECTS:"1",GIT_LFS_SKIP_SMUDGE:"1",...process.platform==="linux"?Object.fromEntries(["DBUS_SESSION_BUS_ADDRESS","XDG_RUNTIME_DIR"].flatMap((T)=>process.env[T]?[[T,process.env[T]]]:[])):{}},v=async(T,G,z=w,Q,ae=gt)=>{l.assertCurrent();let le=await c.command(T,G,{cwd:z,env:g,input:Q,maxBuffer:ae,timeout:Math.max(1,Math.min(60000,(l.deadlineMs??Date.now()+60000)-Date.now())),signal:l.signal});if(l.assertCurrent(),le.error||le.status!==0)U("local_device_gh_command_failed");return le.stdout},C=async(T)=>(await v(h,T)).toString("utf8").trim(),A=async(T,G="application/vnd.github+json")=>{Lo(p.repoFullName,T,{headers:{accept:G}}),l.assertCurrent();let z=await c.command(h,["api","--hostname","github.com","--method","GET","--include","-H",`Accept: ${G}`,T],{cwd:w,env:g,maxBuffer:gt,timeout:Math.max(1,Math.min(25000,(l.deadlineMs??Date.now()+25000)-Date.now())),signal:l.signal});if(l.assertCurrent(),z.error&&z.status===null)U("local_device_gh_response_unavailable");let Q=z.stdout.toString("utf8").match(/^HTTP\/[^ ]+ ([0-9]{3})[^\r\n]*\r?\n([\s\S]*?)\r?\n\r?\n([\s\S]*)$/);if(!Q)U("local_device_gh_response_invalid");let ae=Number(Q[1]);if(ae>=200&&ae<300&&z.status!==0)U("local_device_gh_response_unavailable");if(Buffer.byteLength(Q[3])>yt)U("local_device_gh_response_too_large");let le={};for(let Ae of Q[2].split(/\r?\n/)){let Ne=Ae.indexOf(":"),at=Ae.slice(0,Ne).toLowerCase();if(["link","content-type"].includes(at))le[at]=Ae.slice(Ne+1).trim().slice(0,8192)}return{kind:"read",status:ae,headers:le,body:ae>=200&&ae<300?Q[3]:JSON.stringify({message:"local_device_gh_request_failed"})}};if(p.kind==="read")return A(p.path,p.accept);if(p.kind==="pr_review_context"){let[T,G]=p.repoFullName.split("/"),z=await C(["api","graphql","--hostname","github.com","-f",`query=${Mo}`,"-f",`owner=${T}`,"-f",`repo=${G}`,"-F",`number=${p.number}`,...p.after?["-f",`after=${p.after}`]:[]]);if(Buffer.byteLength(z)>yt)U("local_device_gh_response_too_large");let Q=JSON.parse(z);if(Q.errors||Q.data?.repository?.nameWithOwner?.toLowerCase()!==p.repoFullName.toLowerCase()||Q.data.repository.pullRequest?.number!==p.number)U("local_device_gh_response_invalid");return{kind:"pr_review_context",body:z}}if(p.kind==="pr_merge"){let T=await A(`/repos/${p.repoFullName}/pulls/${p.number}`),G=JSON.parse(T.body),z=(le)=>le.number===p.number&&le.html_url===`https://github.com/${p.repoFullName}/pull/${p.number}`&&le.base?.repo?.full_name?.toLowerCase()===p.repoFullName.toLowerCase()&&le.base?.ref===p.expectedBaseRef&&le.head?.sha===p.expectedHeadSha;if(T.status!==200||!z(G)||G.state!=="open"||G.draft!==!1||G.head?.sha!==p.expectedHeadSha||G.base?.repo?.full_name?.toLowerCase()!==p.repoFullName.toLowerCase())U("local_device_gh_merge_target_changed");await C(["pr","merge",String(p.number),`--repo=${p.repoFullName}`,`--${p.method}`,"--match-head-commit",p.expectedHeadSha,...p.commitBody!==void 0&&p.method!=="rebase"?[`--body=${p.commitBody}`]:[]]);let Q=await A(`/repos/${p.repoFullName}/pulls/${p.number}`),ae=JSON.parse(Q.body);if(Q.status!==200||!z(ae)||ae.merged!==!0)U("local_device_gh_merge_unconfirmed");return{kind:"pr_merge",number:p.number,merged:!0}}if(p.kind==="pr_create"){if(p.head===p.base)U("local_device_gh_default_branch");let T=await C(["pr","create","--repo",p.repoFullName,"--head",p.head,"--base",p.base,`--title=${p.title}`,`--body=${p.body}`,...p.draft?["--draft"]:[]]);if(!new RegExp("^https://github\\.com/"+p.repoFullName.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")+"/pull/[1-9][0-9]*$").test(T))U("local_device_gh_mutation_unconfirmed");return{kind:"pr_create",url:T}}if(p.kind==="pr_mutation"){let T=p.mutation,G=T.action==="edit"?["edit",...T.title!==void 0?[`--title=${T.title}`]:[],...T.body!==void 0?[`--body=${T.body}`]:[],...T.base?[`--base=${T.base}`]:[]]:T.action==="metadata"?["edit",`--${T.change}-${T.field}=${T.value}`]:T.action==="ready"?["ready"]:T.action==="draft"?["ready","--undo"]:["close"];return await C(["pr",...G,String(p.number),"--repo",p.repoFullName]),{kind:"pr_mutation",number:p.number,applied:!0}}if(!l.repoPath)U("local_device_gh_workspace_unavailable");let I=V.realpathSync(l.repoPath);if(!Rn(f,I))U("local_device_gh_workspace_unavailable");let M=`https://github.com/${p.repoFullName}.git`,N="!'"+(Ye?h.replace(/\\/g,"/"):h).replace(/'/g,"'\\''")+"' auth git-credential",L=Be(cs),B=(T,G,z)=>process.platform==="darwin"?["/usr/bin/sandbox-exec",["-p",T,G,...z]]:[G,z],F=async(T,G,z,Q=gt)=>{let ae=Rn(w,T),le=["-c","core.hooksPath=/dev/null","-c","core.fsmonitor=false","-c","credential.helper=","-c","http.extraheader=",...ae?["-c",`credential.https://github.com.helper=${N}`]:[],"-c","protocol.ext.allow=never","-c","protocol.file.allow=never","-c","protocol.ssh.allow=never",...G];if(ae)return v(S,le,T,z,Q);let Ae=se.join(I,".ara-local-gh-tmp");if(V.mkdirSync(Ae,{recursive:!0,mode:448}),V.lstatSync(Ae).isSymbolicLink()||V.realpathSync(Ae)!==Ae)U("local_device_gh_workspace_unavailable");l.assertCurrent();let Ne=await c.command(...B(L(I,Ae),S,le),{cwd:T,input:z,maxBuffer:Q,timeout:Math.max(1,Math.min(25000,(l.deadlineMs??Date.now()+25000)-Date.now())),signal:l.signal,env:{...Nr,PATH:Vt,HOME:I,TMPDIR:Ae,GIT_CONFIG_NOSYSTEM:"1",GIT_CONFIG_SYSTEM:"/dev/null",GIT_CONFIG_GLOBAL:"/dev/null",GIT_TERMINAL_PROMPT:"0",GIT_NO_REPLACE_OBJECTS:"1",GIT_LFS_SKIP_SMUDGE:"1"}});if(l.assertCurrent(),Ne.error||Ne.status!==0)U("local_device_gh_collection_failed");return Ne.stdout},H=async(T,G)=>(await F(T,G)).toString("utf8").trim(),ne=async(T,G)=>{let z=se.join(T,".ara-local-gh-tmp");if(V.mkdirSync(z,{recursive:!0,mode:448}),V.lstatSync(z).isSymbolicLink()||V.realpathSync(z)!==z)U("local_device_gh_workspace_unavailable");l.assertCurrent();let Q=await c.command(...B(L(T,z),sc(S),["-c",'printf "%s\\n" "$1" > .git/shallow',"sh",G]),{cwd:T,maxBuffer:65536,timeout:Math.max(1,Math.min(25000,(l.deadlineMs??Date.now()+25000)-Date.now())),signal:l.signal,env:{...Nr,PATH:Vt,HOME:T,TMPDIR:z}});if(l.assertCurrent(),Q.error||Q.status!==0)U("local_device_gh_materialization_failed")},_e=async(T)=>{let G=new Map;if(T.length===0)return G;let z=await F(he,["cat-file","--batch"],[...new Set(T)].join(`
|
|
14
|
+
`)+`
|
|
15
|
+
`,gt*8);for(let Q=0;Q<z.length;){let ae=z.indexOf(10,Q),[le,Ae,Ne]=z.subarray(Q,ae).toString("utf8").split(" ");if(ae<0||!le||Ae!=="blob"||!/^[0-9]+$/.test(Ne??""))U("local_device_gh_object_invalid");G.set(le,z.subarray(ae+1,ae+1+Number(Ne)).toString("utf8")),Q=ae+1+Number(Ne)+1}return G},xe=async(T,G,z)=>{let Q=se.join(I,".ara-local-gh-tmp"),ae=L(I,Q)+`
|
|
16
|
+
(allow file-read* file-write* (subpath ${JSON.stringify(I)}))
|
|
17
|
+
(allow file-read* (subpath ${JSON.stringify(T)}))
|
|
18
|
+
(allow file-read-metadata (path-ancestors ${JSON.stringify(T)}))`,le=async(Ne,at)=>{l.assertCurrent();let Ht=await c.command(...B(ae,Ne,at),{cwd:I,maxBuffer:gt,timeout:Math.max(1,Math.min(25000,(l.deadlineMs??Date.now()+25000)-Date.now())),signal:l.signal,env:{...Nr,PATH:Vt,HOME:I,TMPDIR:Q,GIT_INDEX_FILE:se.join(I,".git","index"),OPENSSL_CONF:"/dev/null",GIT_CONFIG_NOSYSTEM:"1",GIT_CONFIG_SYSTEM:"/dev/null",GIT_CONFIG_GLOBAL:"/dev/null",GIT_TERMINAL_PROMPT:"0",GIT_NO_REPLACE_OBJECTS:"1",GIT_LFS_SKIP_SMUDGE:"1"}});if(l.assertCurrent(),Ht.error||Ht.status!==0)U("local_device_gh_materialization_failed")},Ae=["--git-dir="+T,"--work-tree="+I,"-c","core.hooksPath=/dev/null","-c","core.fsmonitor=false","-c","credential.helper=","-c","http.extraheader=","-c","protocol.allow=never"];await le(S,[...Ae,"read-tree",G]),await le(S,[...Ae,"checkout-index","--all","--index"]),await F(I,["update-ref","refs/heads/"+z,G]),await F(I,["symbolic-ref","HEAD","refs/heads/"+z])};m="local_device_gh_prepare_metadata";let Qe=await A(`/repos/${p.repoFullName}`);if(Qe.status!==200)U("local_device_gh_repository_unavailable");let st=JSON.parse(Qe.body);if(st.full_name?.toLowerCase()!==p.repoFullName.toLowerCase()||st.default_branch!==p.defaultBranch||p.kind==="publish"&&st.permissions?.push!==!0)U("local_device_gh_repository_authority_changed");if(p.branch===p.defaultBranch)U("local_device_gh_default_branch");m="local_device_gh_prepare_private_init";let he=V.mkdtempSync(se.join(w,"github-publication-"));V.chmodSync(he,448);let Ir=!1;try{if(await F(he,["init","--bare","--template="]),p.kind==="prepare"){if(m="local_device_gh_prepare_fetch",await F(he,["fetch","--depth=1","--no-tags","--no-recurse-submodules",M,p.baseSha]),await H(he,["rev-parse","FETCH_HEAD"])!==p.baseSha)m="local_device_gh_prepare_base_mismatch",U("local_device_gh_base_changed");m="local_device_gh_prepare_checkout_validation";let we=se.join(I,".git"),Ge=!1;if(V.existsSync(we)){if(!V.lstatSync(we).isDirectory()||V.lstatSync(we).isSymbolicLink()||["objects/info/alternates","info/grafts"].some((Ee)=>V.existsSync(se.join(we,Ee))))U("local_device_gh_repository_layout_invalid");let De=await F(I,["rev-parse","--verify","-q","HEAD"]).then((Ee)=>Ee.toString("utf8").trim(),()=>null),Ve=await F(I,["config","--local","--get","remote.origin.url"]).then((Ee)=>Ee.toString("utf8").trim(),()=>"");if(De!==null||Ve){if(De!==p.baseSha||await H(I,["branch","--show-current"])!==p.branch)U("local_device_gh_checkout_exists");return{kind:"prepare",headSha:p.baseSha}}Ge=!0}let Fe=V.readdirSync(I).filter((De)=>!(Ge&&De===".git")),Je=[".ara-local-gh-tmp",".reason-local-gh-tmp"];if(Fe.some((De)=>!Je.includes(De))||Fe.some((De)=>{let Ve=se.join(I,De);return!V.lstatSync(Ve).isDirectory()||V.lstatSync(Ve).isSymbolicLink()||V.readdirSync(Ve).length>0}))U("local_device_gh_checkout_not_empty");if(m="local_device_gh_prepare_checkout_init",!Ge)await F(I,["init","--template="]);m="local_device_gh_prepare_materialization";let tt=await F(he,["pack-objects","--stdout","--revs"],p.baseSha+`
|
|
19
|
+
`,_s);return await ne(I,p.baseSha),await F(I,["index-pack","--strict","--stdin"],tt,65536),await F(I,["remote","add","origin",M]),await xe(he,p.baseSha,p.branch),{kind:"prepare",headSha:p.baseSha}}let T=se.join(I,".git");if(!V.lstatSync(T).isDirectory()||V.lstatSync(T).isSymbolicLink()||["objects/info/alternates","info/grafts"].some((we)=>V.existsSync(se.join(T,we))))U("local_device_gh_repository_layout_invalid");if(await H(I,["branch","--show-current"])!==p.branch)U("local_device_gh_branch_changed");let G=await H(I,["rev-parse","--verify","HEAD"]);if(!vn.test(G))U("local_device_gh_head_invalid");let z=await A(`/repos/${p.repoFullName}/commits/${p.baseSha}`);if(z.status!==200||JSON.parse(z.body).sha!==p.baseSha)U("local_device_gh_base_unverified");let Q=await A(`/repos/${p.repoFullName}/git/ref/heads/${encodeURIComponent(p.branch)}`);if(p.remoteHeadSha===null?Q.status!==404:Q.status!==200||JSON.parse(Q.body).object?.sha!==p.remoteHeadSha)U("local_device_gh_remote_changed");let ae=[...(await H(I,["rev-list","--objects","--no-object-names",G,"--not",p.baseSha])).split(`
|
|
20
|
+
`),...(await H(I,["rev-list","--objects","--no-object-names","--no-walk",p.baseSha])).split(`
|
|
21
|
+
`)].filter(Boolean);if(ae.some((we)=>!vn.test(we)))U("local_device_gh_object_invalid");let le=await F(I,["pack-objects","--stdout"],[...new Set(ae)].join(`
|
|
22
|
+
`)+`
|
|
23
|
+
`,_s);if(V.writeFileSync(se.join(he,"shallow"),p.baseSha+`
|
|
24
|
+
`,{flag:"wx",mode:384}),await F(he,["index-pack","--strict","--stdin"],le,65536),await F(he,["merge-base","--is-ancestor",p.baseSha,G]),p.remoteHeadSha)await F(he,["merge-base","--is-ancestor",p.remoteHeadSha,G]);let Ae=await F(he,["show","-s","--format=%B",G]),Ne=(await F(he,["interpret-trailers","--parse"],Ae)).toString("utf8"),at=p.contributorTrailers?{expectedTrailers:p.contributorTrailers,missingFromHead:cc(Ne,p.contributorTrailers)}:void 0,Ht=(await H(he,["rev-list","--objects","--no-object-names",G,"--not",p.baseSha,...p.remoteHeadSha?[p.remoteHeadSha]:[]])).split(`
|
|
25
|
+
`).filter(Boolean);if(Ht.length>5000)U("local_device_gh_collection_too_large");let qt=[],es=0;for(let we of Ht){if(!vn.test(we))U("local_device_gh_object_invalid");let Ge=await H(he,["cat-file","-t",we]);if(!["blob","commit","tree"].includes(Ge))U("local_device_gh_object_invalid");let Fe=await F(he,["cat-file",Ge,we]);if(es+=Fe.length,es>gt)U("local_device_gh_collection_too_large");if(Ge==="tree"){let Je=0;while(Je<Fe.length){let tt=Fe.indexOf(32,Je),De=Fe.indexOf(0,tt+1);if(tt<Je||De<=tt||De+21>Fe.length)U("local_device_gh_object_invalid");let Ve=Fe.subarray(tt+1,De).toString("utf8");if(Ve.includes("/")||!bn(Ve).valid)U("local_device_gh_object_invalid");Je=De+21}}qt.push({path:`object-${we}`,content:Fe.toString("utf8")})}let ts=l.secretNames?{secretNames:l.secretNames}:{},Gt=Dr(qt,l.forbiddenSecretValues,ts),rs=new Map;if(!Gt.clean)try{let we=(await F(he,["diff","--no-renames","--no-abbrev","--raw","-z",p.baseSha,G])).toString("utf8").split("\x00"),Ge=[],Fe=[];for(let Ee=0;Ee+1<we.length;Ee+=2){let[,Bl,Fl,cn,Lr]=we[Ee].slice(1).match(/^([0-7]{6}) ([0-7]{6}) ([0-9a-f]{40}) ([0-9a-f]{40}) /)??[];if(!cn||!Lr)continue;if(Bl!=="160000"&&!/^0+$/.test(cn))Ge.push(cn);if(Fl!=="160000"&&!/^0+$/.test(Lr))Fe.push(Lr),rs.set(`object-${Lr}`,we[Ee+1])}let Je=await _e([...Ge,...Fe]),tt=new Set(Gt.violations.map((Ee)=>Ee.path)),De=hs(qt.filter((Ee)=>tt.has(Ee.path)),l.forbiddenSecretValues),Ve=gs(De,Fe.map((Ee)=>Je.get(Ee)??""),Ge.map((Ee)=>Je.get(Ee)??""));if(Ve.size>0)Gt=Dr(qt,l.forbiddenSecretValues,{...ts,published:Ve})}catch{}if(!Gt.clean)ys(Gt.violations,(we)=>rs.get(we)??`an object in the pushed history (${we})`,"Remove it from the files and commit again; a commit or message in the pushed history that holds it must be amended before this branch can be pushed.");await F(he,["push","--no-recurse-submodules",M,`${G}:refs/heads/${p.branch}`]);let ns=await A(`/repos/${p.repoFullName}/git/ref/heads/${encodeURIComponent(p.branch)}`);if(ns.status!==200||JSON.parse(ns.body).object?.sha!==G)U("local_device_gh_push_unconfirmed");return{kind:"publish",headSha:G,scannedObjectCount:qt.length,...at?{attribution:at}:{}}}catch(T){throw Ir=!0,T}finally{try{V.rmSync(he,{recursive:!0,force:!0})}catch(T){if(!Ir||p.kind!=="prepare")throw m=null,T}}}catch(f){if(p.kind==="prepare"&&p.diagnosticsVersion===1&&m&&!l.signal?.aborted)throw new ir(m);throw f}}var _t=i({profile:t().regex(/^(Default|Profile [0-9]+)$/),extension_instance_id:t().min(1).max(1024)}).strict(),On={ready:n(!0),boot_generation:t().uuid(),proof_ready:n(!1),result:n("metadata_only")},pc=i({...On,version:n(2),development_only:n(!1),image:n(!0),video:n(!1),source_bound:n(!1),profiles:u(_t.shape.profile).min(1).max(16),extension_instance_ids:u(_t.shape.extension_instance_id.max(512)).min(1).max(16)}).strict().refine((e)=>new Set(e.profiles).size===e.profiles.length&&e.profiles.length===e.extension_instance_ids.length),mc=i({...On,version:n(3),development_only:n(!1),image:n(!0),video:n(!0),source_bound:n(!1),max_seconds:n(15),profiles:u(_t.shape.profile).min(1).max(16),extension_instance_ids:u(_t.shape.extension_instance_id.max(512)).min(1).max(16)}).strict().refine((e)=>new Set(e.profiles).size===e.profiles.length&&e.profiles.length===e.extension_instance_ids.length),Ln=W([pc,mc]),Im=W([i({...On,version:n(1),development_only:n(!0),profile:_t.shape.profile,extension_instance_id:_t.shape.extension_instance_id,max_seconds:n(15)}).strict(),Ln]);import{createServer as fc,request as hc}from"http";import{connect as gc,isIP as _c}from"net";var Rs=120000,yc=15000;function bc(e,l,c){let p=_r(l).toLowerCase().replace(/\.$/,"");if(!p||_c(p))return!1;return e.some((m)=>{if(!pn.test(m))return!1;let f=m.lastIndexOf(":"),h=f>0?m.slice(0,f):m;if(f>0&&Number(m.slice(f+1))!==c)return!1;return h.startsWith("*.")?p.endsWith(h.slice(1)):p===h})}function wc(e,l){let c=/^\[?([^\]]+?)\]?:([0-9]{1,5})$/.exec(e),p=c?c[1]:e,m=c?Number(c[2]):l;return p&&m>=1&&m<=65535?{host:p,port:m}:null}async function Tn(e,l,c){if(!bc(c,e,l))return null;let p=await Xi(e);return p.ok?p.addresses[0]:null}function Jt(e,l){e.end(`HTTP/1.1 ${l} ${l===403?"Forbidden":"Bad Gateway"}\r
|
|
26
|
+
Connection: close\r
|
|
27
|
+
Content-Length: 0\r
|
|
28
|
+
\r
|
|
29
|
+
`)}function ws(e,l){return new Promise((c,p)=>{let m=gc({host:e,port:l}),f=setTimeout(()=>m.destroy(Error("connect_timeout")),yc);m.once("connect",()=>{clearTimeout(f),c(m)}),m.once("error",(h)=>{clearTimeout(f),p(h)})})}function Ss(e,l,c){for(let p of[e,l])p.on("error",()=>{e.destroy(),l.destroy()}),p.on("close",()=>{e.destroy(),l.destroy()});if(l.setTimeout(Rs,()=>l.destroy()),c.length)l.write(c);e.pipe(l).pipe(e)}function vs(e,l){let c={...e,host:l};return delete c["proxy-authorization"],delete c["proxy-connection"],c}async function Os(e,l=()=>{}){let c=[...e],p=new Set,m=(y)=>{p.add(y),y.once("close",()=>p.delete(y))},f=fc((y,S)=>{(async()=>{let w;try{w=new URL(y.url??"")}catch{w=new URL("invalid:")}let g=Number(w.port||80),v=w.protocol==="http:"?await Tn(w.hostname,g,c):null;if(!v){l(),S.writeHead(403,{connection:"close"}).end();return}let C=hc({host:v,port:g,method:y.method,path:`${w.pathname}${w.search}`,headers:vs(y.headers,w.host),agent:!1,timeout:Rs},(A)=>{S.writeHead(A.statusCode??502,A.headers),A.pipe(S)});C.on("timeout",()=>C.destroy()),C.on("error",()=>{if(!S.headersSent)S.writeHead(502);S.end()}),S.on("close",()=>C.destroy()),y.pipe(C)})().catch(()=>{if(!S.headersSent)S.writeHead(502);S.end()})});f.on("connection",m),f.on("connect",(y,S,w)=>{m(S),S.on("error",()=>S.destroy()),(async()=>{let g=wc(y.url??"",443),v=g?await Tn(g.host,g.port,c):null;if(!g||!v){l(),Jt(S,403);return}let C=await ws(v,g.port).catch(()=>null);if(!C){Jt(S,502);return}if(S.destroyed){C.destroy();return}m(C),S.write(`HTTP/1.1 200 Connection Established\r
|
|
30
|
+
\r
|
|
31
|
+
`),Ss(S,C,w)})().catch(()=>S.destroy())}),f.on("upgrade",(y,S,w)=>{m(S),S.on("error",()=>S.destroy()),(async()=>{let g;try{g=new URL(y.url??"")}catch{Jt(S,403);return}let v=Number(g.port||80),C=["http:","ws:"].includes(g.protocol)?await Tn(g.hostname,v,c):null;if(!C){l(),Jt(S,403);return}let A=await ws(C,v).catch(()=>null);if(!A){Jt(S,502);return}m(A);let I=vs(y.headers,g.host),M=[`${y.method} ${g.pathname}${g.search} HTTP/1.1`];for(let[N,L]of Object.entries(I))for(let B of Array.isArray(L)?L:L===void 0?[]:[L])M.push(`${N}: ${B}`);A.write(`${M.join(`\r
|
|
32
|
+
`)}\r
|
|
33
|
+
\r
|
|
34
|
+
`),Ss(S,A,w)})().catch(()=>S.destroy())}),await new Promise((y,S)=>{f.once("error",S),f.listen(0,"127.0.0.1",()=>y())});let{port:h}=f.address();return{url:`http://127.0.0.1:${h}`,close(){f.close();for(let y of p)y.destroy()}}}import{createHash as Gn,randomUUID as xc}from"crypto";import{closeSync as jr,constants as Ue,fchownSync as Ec,fstatSync as lt,fsyncSync as Cc,linkSync as js,lstatSync as Hn,mkdirSync as qs,openSync as Ur,readSync as zs,realpathSync as jn,unlinkSync as Ws,writeSync as Pc}from"fs";import{isAbsolute as Oc,join as Ac,relative as Ic,sep as Lc}from"path";import{platform as qn}from"os";import{getSystemErrorName as kc}from"util";var Is={type:"string",format:"uuid"},Ns=String.raw`^(?![\\/])(?![A-Za-z]:[\\/])(?!.*(?:^|[\\/])\.\.(?:[\\/]|$))(?!.*\u0000)(?=.*\S)[\s\S]+$`,Mr={type:"string",minLength:1,maxLength:4096,pattern:Ns},Mn=t().min(1).max(4096).regex(new RegExp(Ns)),$r={device_id:t().uuid(),root_id:t().uuid(),timeout_ms:o().int().min(1000).max(60000).optional()},Br={device_id:Is,root_id:Is,timeout_ms:{type:"integer",minimum:1000,maximum:60000}},Bm={read:{schema:i({...$r,path:Mn,offset:o().int().min(0).optional(),max_bytes:o().int().min(1).max(131072).optional()}).strict(),inputSchema:{type:"object",required:["device_id","root_id","path"],properties:{...Br,path:Mr,offset:{type:"integer",minimum:0},max_bytes:{type:"integer",minimum:1,maximum:131072}},additionalProperties:!1}},write:{schema:i({...$r,path:Mn,content:t().max(131072),mode:s(["overwrite","append"]).optional(),create_parents:d().optional()}).strict(),inputSchema:{type:"object",required:["device_id","root_id","path","content"],properties:{...Br,path:Mr,content:{type:"string",maxLength:131072},mode:{type:"string",enum:["overwrite","append"]},create_parents:{type:"boolean"}},additionalProperties:!1}},exec:{schema:i({...$r,command:t().min(1).max(16000),cwd:Mn.optional(),mode:s(["confined","host"]).optional()}).strict(),inputSchema:{type:"object",required:["device_id","root_id","command"],properties:{...Br,command:{type:"string",minLength:1,maxLength:16000},cwd:Mr,mode:{type:"string",enum:["confined","host"],description:"Defaults to host: the existing permitted login shell with OS/account access, requiring execute and environment-discovery permission. Request confined explicitly for a scrubbed shell without network."}},additionalProperties:!1}}},Ze=1073741824,Qt=600000,Ls=String.raw`(?!\.{1,2}(?:/|(?![\s\S])))[^/\\\u0000]+`,Ms=String.raw`^(?![A-Za-z]:/)(?=[\s\S]*\S)${Ls}(?:/${Ls})*(?![\s\S])`,$s=new RegExp(Ms);function Bs(e){return typeof e==="string"&&e.length>0&&e.length<=4096&&$s.test(e)}var $n=t().min(1).max(4096).regex($s),Bn={...Mr,pattern:Ms},Fs=t().regex(/^[a-f0-9]{64}$/),Us=i({kind:n("workspace"),path:$n}).strict(),Sc=_("kind",[Us,i({kind:n("attachment"),attachment_id:t().min(1).max(120),sha256:Fs}).strict()]),Fr=1,er="cloud_workspace_id",Fn="cloud_workspace",Un=1,vc=_("kind",[Us,i({kind:n("attachment"),download_url:t().min(1).max(16384),size_bytes:o().int().min(0).max(Ze),sha256:Fs}).strict()]),Hs=i({source_version:n(Fr),source:vc,url:t().min(1).max(16384),transfer_cloud_scope:i({sandboxId:t().min(1).max(256),revision:o().int().nonnegative(),brainFence:t().uuid()}).strict().optional(),[er]:t().min(1).max(160).optional()}).strict(),Fm=i({ready:n(!0),cloud_source_version:n(Fr),source_kinds:u(s(["workspace","attachment"]))});var Ts=i({...$r,timeout_ms:o().int().min(1000).max(Qt).optional(),source_path:$n,destination_path:$n,idempotency_key:t().min(1).max(160).regex(/^[A-Za-z0-9._:-]+$/).optional()}).strict(),Ds={type:"object",required:["device_id","root_id","source_path","destination_path"],properties:{...Br,timeout_ms:{type:"integer",minimum:1000,maximum:Qt},source_path:Bn,destination_path:Bn,idempotency_key:{type:"string",minLength:1,maxLength:160,pattern:"^[A-Za-z0-9._:-]+$"}},additionalProperties:!1},Rc={oneOf:[{type:"object",required:["kind","path"],properties:{kind:{type:"string",const:"workspace"},path:Bn},additionalProperties:!1},{type:"object",required:["kind","attachment_id","sha256"],properties:{kind:{type:"string",const:"attachment"},attachment_id:{type:"string",minLength:1,maxLength:120},sha256:{type:"string",pattern:"^[a-f0-9]{64}$"}},additionalProperties:!1}]},Um=W([Ts,Ts.omit({source_path:!0}).extend({source:Sc}).strict()]),Hm={...Ds,required:["device_id","root_id","destination_path"],properties:{...Ds.properties,source:Rc},oneOf:[{required:["source_path"],not:{required:["source"]}},{required:["source"],not:{required:["source_path"]}}]};var zn=65536;function Se(e){throw new r(e,e)}function qr(e){return typeof e==="object"&&e!==null&&"code"in e&&typeof e.code==="string"?e.code:void 0}function Hr(e,l,c){if(l.throwIfAborted(),e instanceof r||e instanceof Error&&e.name==="AbortError")throw e;return Se(c)}function Tc(e,l,c){let p;switch(qr(e)){case"ENOENT":p=c==="export"?"transfer_source_missing":"transfer_path_unavailable";break;case"EACCES":case"EPERM":case"EROFS":p="transfer_permission_denied";break;case"ELOOP":case"ENOTDIR":p="transfer_path_unsafe";break;case"EEXIST":p="transfer_destination_exists";break;default:p="transfer_path_unavailable"}return Hr(e,l,p)}function Dc(e){if(typeof e!=="string"||e.length>16384)return Se("transfer_url_invalid");let l;try{l=new URL(e)}catch{return Se("transfer_url_invalid")}if(l.protocol!=="https:"||l.username||l.password||l.hash)return Se("transfer_url_invalid");return l.href}var Wn=Ue.O_RDONLY|Ue.O_DIRECTORY|Ue.O_NOFOLLOW;async function Nc(){if(qn()==="win32"){let w=new Map,g,v=-1,C=()=>Object.assign(Error("transfer_path_unsafe"),{code:"ELOOP"}),A=(L)=>{let B=Ic(g,L);return B===""||B!==".."&&!B.startsWith(`..${Lc}`)&&!Oc(B)},I=(L)=>{let B=Hn(L);if(B.isSymbolicLink())throw C();if(!B.isDirectory())throw Object.assign(Error("transfer_path_unsafe"),{code:"ENOTDIR"});let F=jn(L);if(g??=F,!A(F))throw C();return w.set(v,{path:L,real:F}),v--},M=(L)=>{let B=w.get(L);if(jn(B.path)!==B.real)throw C();return B.path},N=(L,B)=>{if(sn(B))throw Object.assign(Error("transfer_path_invalid"),{code:"ENOTDIR"});return Ac(w.get(L).path,B)};return{root:I,openDirectory:(L,B)=>I(N(L,B)),open:(L,B,F,H=384)=>{let ne=N(L,B);if(Hn(ne,{throwIfNoEntry:!1})?.isSymbolicLink())throw C();M(L);let _e=Ur(ne,F,H);try{let xe=lt(_e),Qe=Hn(ne);if(Qe.isSymbolicLink()||xe.ino!==Qe.ino||xe.dev!==Qe.dev||!A(jn(ne)))throw C()}catch(xe){throw jr(_e),xe}return _e},mkdir:(L,B)=>{let F=N(L,B);M(L),qs(F)},link:(L,B,F)=>{let H=N(L,B),ne=N(L,F);M(L),js(H,ne)},unlink:(L,B)=>Ws(N(L,B)),closeDirectory:(L)=>{w.delete(L)},inherit:()=>{},close:()=>{}}}let e={root:(w)=>Ur(w,Wn),closeDirectory:jr,inherit:Mc};if(qn()==="linux")return{...e,openDirectory:(w,g)=>Ur(`/proc/self/fd/${w}/${g}`,Wn),open:(w,g,v,C=384)=>Ur(`/proc/self/fd/${w}/${g}`,v,C),mkdir:(w,g)=>qs(`/proc/self/fd/${w}/${g}`,{mode:448}),link:(w,g,v)=>js(`/proc/self/fd/${w}/${g}`,`/proc/self/fd/${w}/${v}`),unlink:(w,g)=>Ws(`/proc/self/fd/${w}/${g}`),close:()=>{}};if(qn()!=="darwin")return Se("transfer_platform_unsupported");let{dlopen:l,FFIType:c,ptr:p,read:m}=await import("bun:ffi"),f=l("/usr/lib/libSystem.B.dylib",{__error:{args:[],returns:c.ptr},openat:{args:[c.i32,c.ptr,c.i32,c.i32,c.i32,c.i32,c.i32,c.i32,c.i32],returns:c.i32},mkdirat:{args:[c.i32,c.ptr,c.i32],returns:c.i32},linkat:{args:[c.i32,c.ptr,c.i32,c.ptr,c.i32],returns:c.i32},unlinkat:{args:[c.i32,c.ptr,c.i32],returns:c.i32}}),h=f.symbols.__error();if(h===null)return f.close(),Se("transfer_path_unavailable");let y=(w)=>{if(w<0){let g=kc(-m.i32(h));throw Object.assign(Error("transfer_path_unavailable"),{code:g})}return w},S=(w,g,v,C=384)=>y(f.symbols.openat(w,p(Buffer.from(`${g}\x00`)),v,C,0,0,0,0,C));return{...e,openDirectory:(w,g)=>S(w,g,Wn),open:S,mkdir:(w,g)=>{y(f.symbols.mkdirat(w,p(Buffer.from(`${g}\x00`)),448))},link:(w,g,v)=>{y(f.symbols.linkat(w,p(Buffer.from(`${g}\x00`)),w,p(Buffer.from(`${v}\x00`)),0))},unlink:(w,g)=>{y(f.symbols.unlinkat(w,p(Buffer.from(`${g}\x00`)),0))},close:()=>f.close()}}function Mc(e,l){let c=lt(e),p=lt(l);if(p.uid!==c.uid||p.gid!==c.gid)Ec(l,c.uid,c.gid)}function $c(e,l,c,p){if(!Bs(c))return Se("transfer_path_invalid");let m=c.split("/"),f=e.root(l);try{for(let h of m.slice(0,-1)){let y;try{y=e.openDirectory(f,h)}catch(S){if(!p||qr(S)!=="ENOENT")throw S;try{e.mkdir(f,h)}catch(w){if(qr(w)!=="EEXIST")throw w}y=e.openDirectory(f,h),e.inherit(f,y)}e.closeDirectory(f),f=y}return{fd:f,leaf:m.at(-1)}}catch(h){throw e.closeDirectory(f),h}}function Gs(e,l){let c=lt(e,{bigint:!0});if(!c.isFile()||c.size>Ze)return Se("transfer_file_invalid");let p=Gn("sha256"),m=Buffer.alloc(zn),f=0;while(!0){l.throwIfAborted();let y=zs(e,m,0,m.length,f);if(!y)break;if(f+=y,f>Ze)return Se("transfer_size_exceeded");p.update(m.subarray(0,y))}let h=lt(e,{bigint:!0});if(BigInt(f)!==c.size||h.size!==c.size||h.mtimeNs!==c.mtimeNs||h.ctimeNs!==c.ctimeNs)return Se("transfer_source_changed");return{size_bytes:f,sha256:p.digest("hex")}}async function wt(e){e.signal.throwIfAborted();try{let l=Dc(e.payload.url),c=await Nc(),p,m,f;try{if(p=$c(c,e.root,e.path,e.direction==="import"),e.direction==="export"){m=c.open(p.fd,p.leaf,Ue.O_RDONLY|Ue.O_NOFOLLOW|Ue.O_NONBLOCK);let C=lt(m,{bigint:!0});if(!C.isFile()||C.size>Ze)return Se("transfer_file_invalid");let A=Gn("sha256"),I=0,M=m,N,L=new ReadableStream({pull(ne){try{e.signal.throwIfAborted();let _e=Buffer.alloc(zn),xe=zs(M,_e,0,_e.length,I);if(!xe){ne.close();return}if(I+=xe,I>C.size)return Se("transfer_source_changed");A.update(_e.subarray(0,xe)),ne.enqueue(_e.subarray(0,xe))}catch(_e){throw N=_e,_e}}});try{let ne=await(e.fetchImpl??fetch)(l,Object.assign({method:"PUT",body:L,redirect:"error",signal:e.signal,headers:{"content-type":"application/octet-stream","content-length":String(C.size)}},{duplex:"half"}));if(N!==void 0)throw N;if(!ne.ok)return Se("transfer_upload_failed");await ne.body?.cancel()}catch(ne){if(N!==void 0)throw N;return Hr(ne,e.signal,"transfer_upload_failed")}let B=lt(m,{bigint:!0});if(BigInt(I)!==C.size||B.size!==C.size||B.mtimeNs!==C.mtimeNs||B.ctimeNs!==C.ctimeNs)return Se("transfer_source_changed");let F=A.digest("hex"),H=Gs(m,e.signal);if(H.size_bytes!==I||H.sha256!==F)return Se("transfer_source_changed");return{size_bytes:I,sha256:F,outcome:"copied"}}let h=e.payload.size_bytes,y=e.payload.sha256;if(typeof h!=="number"||!Number.isSafeInteger(h)||h<0||h>Ze||typeof y!=="string"||!/^[a-f0-9]{64}$/.test(y))return Se("transfer_receipt_invalid");let S;try{S=c.open(p.fd,p.leaf,Ue.O_RDONLY|Ue.O_NOFOLLOW|Ue.O_NONBLOCK)}catch(C){if(qr(C)!=="ENOENT")throw C}if(S!==void 0){try{let C=Gs(S,e.signal);if(C.size_bytes===h&&C.sha256===y)return{...C,outcome:"already_present"}}finally{jr(S)}return Se("transfer_destination_exists")}f=`.reason-copy-${xc()}`,m=c.open(p.fd,f,Ue.O_CREAT|Ue.O_EXCL|Ue.O_WRONLY|Ue.O_NOFOLLOW,384),c.inherit(p.fd,m);let w;try{let C=await(e.fetchImpl??fetch)(l,{redirect:"error",signal:e.signal});if(!C.ok||!C.body)return Se("transfer_download_failed");w=C.body.getReader()}catch(C){return Hr(C,e.signal,"transfer_download_failed")}let g=Gn("sha256"),v=0;try{while(!0){e.signal.throwIfAborted();let C=await w.read().catch((A)=>Hr(A,e.signal,"transfer_download_failed"));if(C.done)break;if(v+=C.value.length,v>h)return Se("transfer_size_mismatch");g.update(C.value);for(let A=0;A<C.value.length;)e.signal.throwIfAborted(),A+=Pc(m,C.value,A,Math.min(zn,C.value.length-A))}}finally{await w.cancel().catch(()=>{})}if(v!==h||g.digest("hex")!==y)return Se("transfer_hash_mismatch");return Cc(m),await e.beforeCommit?.(),e.signal.throwIfAborted(),c.link(p.fd,f,p.leaf),{size_bytes:h,sha256:y,outcome:"copied"}}finally{try{if(m!==void 0)jr(m)}finally{try{if(p){if(f)try{c.unlink(p.fd,f)}catch{}c.closeDirectory(p.fd)}}finally{c.close()}}}}catch(l){return Tc(l,e.signal,e.direction)}}import{spawn as Fc}from"child_process";import{mkdtempSync as Uc,rmSync as Hc,writeFileSync as jc}from"fs";import{constants as qc,platform as Wc,tmpdir as Gc}from"os";import{join as Xs}from"path";import{gunzipSync as Bc,gzipSync as Qm}from"zlib";var Ks=900000,tf=Ks+60000,tr=49152,Vs=(e)=>t().min(1).max(e).regex(/^[A-Za-z0-9+/]+=*$/),Ys=i({version:n(1),script_gzip:Vs(163840),stdin_gzip:Vs(65536),cwd:t().min(1).max(4096).startsWith("/"),env:ee(t().regex(/^[A-Z_][A-Z0-9_]{0,63}$/),t().max(4096)).refine((e)=>Object.keys(e).length<=16,"too many variables"),timeout_ms:o().int().min(1000).max(Ks)}).strict(),Vn=t().max(tr+256),rf=i({exit_code:o().int().min(0).max(255),stdout:Vn,stderr:Vn,combined:Vn.optional()}).strict();function Kn(e){return Bc(Buffer.from(e,"base64")).toString("utf8")}var zc="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",Vc=["RUSTUP_HOME","TZ","LC_ALL"],Kc=2000,Yc=100;function Xn(){return Wc()==="linux"&&process.geteuid?.()===0}function Yn(e){let l=Math.floor(e/2),c=[],p=0,m=Buffer.alloc(0),f=0;return{push(h){f+=h.length;let y=h;if(p<l){let S=y.subarray(0,l-p);c.push(S),p+=S.length,y=y.subarray(S.length)}if(y.length)m=Buffer.concat([m,y]).subarray(-l)},text(){let h=f-p-m.length;return Buffer.concat(c).toString("utf8")+(h>0?`
|
|
35
|
+
[reason: ${h} bytes of output omitted]
|
|
36
|
+
`:"")+m.toString("utf8")}}}async function Js(e,l){if(!Xn())throw new r("workspace_setup_requires_root","Workspace setup runs only on a root Linux worker.");let c=Ys.safeParse(e);if(!c.success)throw new r("invalid_request","Reason sent an invalid workspace setup.");let p=c.data,m,f;try{m=Kn(p.script_gzip),f=Kn(p.stdin_gzip)}catch{throw new r("invalid_request","Reason sent an unreadable workspace setup.")}l.throwIfAborted();let h=Uc(Xs(Gc(),"reason-workspace-setup-"));try{let y=Xs(h,"setup.sh");jc(y,m,{mode:384});let S={PATH:zc,LANG:"C.UTF-8",HOME:"/root",USER:"root",LOGNAME:"root",SHELL:"/bin/bash",TMPDIR:"/tmp"};for(let H of Vc)if(process.env[H])S[H]=process.env[H];Object.assign(S,p.env);let w=Fc("/bin/bash",[y],{cwd:p.cwd,env:S,detached:!0,stdio:["pipe","pipe","pipe"]}),g=Yn(tr),v=Yn(tr),C=Yn(tr);w.stdout.on("data",(H)=>{g.push(H),C.push(H)}),w.stderr.on("data",(H)=>{v.push(H),C.push(H)}),w.stdin.on("error",()=>{}),w.stdin.end(f);let A=(H)=>{try{if(w.pid)process.kill(-w.pid,H)}catch{}},I=!1,M,N=()=>{A("SIGTERM"),M??=setTimeout(()=>A("SIGKILL"),Kc)},L=setTimeout(()=>{I=!0,N()},p.timeout_ms);l.addEventListener("abort",N,{once:!0});let B=await new Promise((H,ne)=>{w.once("error",()=>ne(new r("workspace_setup_start_failed","The workspace setup did not start."))),w.once("exit",(_e,xe)=>H({code:_e,signal:xe}))}).finally(()=>{clearTimeout(L),clearTimeout(M),l.removeEventListener("abort",N)});await new Promise((H)=>{let ne=setTimeout(H,Yc);w.once("close",()=>{clearTimeout(ne),H()})}),w.stdout.destroy(),w.stderr.destroy(),l.throwIfAborted();let F=I?124:B.signal?128+(qc.signals[B.signal]??0):B.code??1;return{exit_code:Math.min(255,F),stdout:g.text(),stderr:v.text(),...F!==0?{combined:C.text()}:{}}}finally{Hc(h,{recursive:!0,force:!0})}}import{chmodSync as Xc,mkdtempSync as Jc,realpathSync as Zs,rmSync as Zc}from"fs";import{tmpdir as Qc}from"os";import{dirname as eu,join as Jn,sep as tu}from"path";function Zn(e){return vr(e,yr(e)!==null).repoPath}function Qs(e,l){let c;try{if(typeof l!=="string")throw Error("invalid");c=[Z,void 0].map((m)=>eu(O({kind:"managed",workspaceId:l,...m?{layout:m}:{}})))}catch{throw new r("cloud_copy_workspace_invalid","The Cloud copy workspace is invalid.")}let p;for(let m of c)try{p=Zs(Jn(e,m));break}catch{}if(p===void 0)throw new r("cloud_copy_workspace_unavailable","The Session workspace is not on this computer.");if(!p.startsWith(`${e}${tu}`))throw new r("cloud_copy_workspace_invalid","The Cloud copy workspace is outside this worker's root.");return p}async function ea(e){e.signal.throwIfAborted();let l=e.source;if(l.kind==="workspace"){let p=Zn(e.runtimeRoot);if(E(p)||E(Jn(p,l.path)))throw new r("protected_path","Credential and secret paths are unavailable to local tasks.");return wt({direction:"export",root:p,path:l.path,payload:{url:e.url},signal:e.signal,fetchImpl:e.fetchImpl})}let c=Jc(Jn(Qc(),`reason-cloud-copy-${process.pid}-`));try{Xc(c,448);let p=Zs(c);await wt({direction:"import",root:p,path:"source",payload:{url:l.download_url,size_bytes:l.size_bytes,sha256:l.sha256},signal:e.signal,fetchImpl:e.fetchImpl});let m=await wt({direction:"export",root:p,path:"source",payload:{url:e.url},signal:e.signal,fetchImpl:e.fetchImpl});if(m.size_bytes!==l.size_bytes||m.sha256!==l.sha256)throw new r("transfer_source_changed","The verified attachment changed before export.");return m}finally{Zc(c,{recursive:!0,force:!0})}}import{constants as We}from"fs";import{closeSync as vl,existsSync as Xe,fstatSync as Rl,ftruncateSync as bp,lstatSync as Ii,mkdirSync as wp,mkdtempSync as Sp,openSync as xl,readSync as vp,realpathSync as Ke,rmSync as Rp,statSync as Pr,writeSync as xp}from"fs";import{homedir as hr,platform as X,tmpdir as Ep}from"os";import{dirname as br,isAbsolute as Cp,join as El,relative as Li,resolve as Pp,sep as Op}from"path";import{spawn as Ap}from"child_process";var Rf=rn+15000;var ta=["fs.read","fs.write","fs.export","fs.import","exec.run","exec.full","process.run.v1","process.full.v1","preview.serve.v1","pty.start","git.run","process.list","ports.list","computer.use","browser.use","browser.recording.v1","browser.pr-proof.v1","hands.connect","jobs.control","environment.install","github.local.v1","inference.custom.v1","display.stream.v1","automation.call.v1","simulator.call.v1","simulator.stream.v1","tunnel.open","tunnel.close","workspace.setup.v1"];var nu=new Set(["process.run.v1","process.full.v1","computer.use","browser.use"]),rr=new Set(["jobs.control","environment.install","tunnel.open","tunnel.close","display.stream.v1","automation.call.v1","workspace.setup.v1","simulator.call.v1","simulator.stream.v1"]);function Wr(e,l){if(nu.has(e))return!1;if(rr.has(e)&&!l.runtimeDirectory)return!1;if((e==="inference.custom.v1"||e==="preview.serve.v1"||e==="simulator.call.v1"||e==="simulator.stream.v1")&&(l.executionMode!=="unsandboxed"||!l.runtimeDirectory))return!1;if(l.executionMode!=="unsandboxed"&&(["exec.full","hands.connect","pty.start","browser.pr-proof.v1"].includes(e)||rr.has(e)))return!1;return!0}import{accessSync as ou,constants as iu,existsSync as su,statSync as au}from"fs";import{basename as lu,isAbsolute as cu}from"path";var nr=["-lic"],ra="/bin/zsh",uu=new Set(["zsh","bash"]),na=20000,to=60000,du=65536,pu=64,mu=8192,fu=new Set(["NODE_OPTIONS","PATH","ZDOTDIR","BASH_ENV","ENV"]),hu=["DYLD_","LD_"];function gu(e){let l=e.toUpperCase();return fu.has(l)||hu.some((c)=>l.startsWith(c))}function oa(e=process.env){return!0}function _u(e){if(!cu(e)||e.includes("\x00"))return!1;if(!uu.has(lu(e)))return!1;try{if(!au(e).isFile())return!1;return ou(e,iu.X_OK),!0}catch{return!1}}function xt(e=process.env){if(process.platform==="win32")return fe()??ra;let l=e.SHELL?.trim();if(l&&_u(l))return l;return ra}function ro(e=process.env){return oa(e)&&su(xt(e))}function oo(e=process.env){if(!oa(e))throw new r("full_control_disabled","Full-control execution is unavailable on this Reason Device.")}function io(e){if(typeof e!=="string"||e.length===0||e.includes("\x00")||Buffer.byteLength(e,"utf8")>du)throw new r("invalid_payload","command is missing or too large.");return e}function so(e){if(e===void 0||e===null)return{forwarded:{},ignored:[]};if(typeof e!=="object"||Array.isArray(e))throw new r("invalid_payload","env must be an object of strings.");let l=Object.entries(e);if(l.length>pu)throw new r("invalid_payload","env has too many entries.");let c={},p=[];for(let[m,f]of l){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(m)||typeof f!=="string"||f.includes("\x00")||Buffer.byteLength(f,"utf8")>mu)throw new r("invalid_payload","env entry is invalid or too large.");if(gu(m)){p.push(m);continue}c[m]=f}return{forwarded:c,ignored:p}}async function ia(e){let l=e.processEnv??process.env;if(oo(l),e.signal.aborted)throw new r("cancelled","Operation was cancelled.");let c=io(e.command),p=xt(l),{forwarded:m,ignored:f}=so(e.requestEnv),h=await e.spawn(p,[...nr,c],{cwd:e.cwd,timeoutMs:e.timeoutMs,signal:e.signal,env:{...l,...m}});return{exit_code:h.exitCode,signal:h.signal,stdout:h.stdout,stderr:h.stderr,timed_out:h.timedOut,truncated:h.truncated,shell:p,shell_flags:[...nr],login:!0,interactive:!0,sandbox:"none",ignored_env:f}}function sa(e=process.env){return{transport:"shell",shell:`${xt(e)} ${nr.join(" ")}`,login_shell:!0,interactive_shell:!0,rc_files_loaded:!0,sandbox:"none",network:!0,environment:"inherited",privilege:"user",sudo:"argv_exact_nopasswd_only",activation:"explicit_device_grant",max_timeout_ms:to}}import{readFile as yu,readdir as bu,readlink as wu,realpath as Su}from"fs/promises";import{basename as vu,relative as Ru,sep as xu}from"path";var ut="/proc",Eu=250,aa=500,Cu=50,Pu=250,Ou=1024,la=4096,Au=1,Iu=3,ca=9,Lu="0A",ku=/^socket:\[(\d+)\]$/,ao={readDirectory:(e)=>bu(e),readLink:(e)=>wu(e),readTextFile:(e)=>yu(e,"utf8"),realPath:(e)=>Su(e)};function da(e,l){return l===e||l.startsWith(`${e}${xu}`)}function Tu(e,l){return Ru(e,l)||"."}async function pa(e){let l;try{l=await e.readDirectory(ut)}catch{return[]}return l.filter((c)=>/^[0-9]+$/.test(c)).map((c)=>Number(c)).filter((c)=>Number.isSafeInteger(c)&&c>0).sort((c,p)=>c-p)}async function ma(e,l){try{let p=(await l.readTextFile(`${ut}/${e}/comm`)).slice(0,la).split(`
|
|
37
|
+
`,1)[0]?.trim();if(p)return p}catch{}try{let p=(await l.readTextFile(`${ut}/${e}/cmdline`)).slice(0,la).split("\x00",1)[0]?.trim();return p?vu(p):null}catch{return null}}async function fa(e,l=ao){let c;try{c=await l.readLink(`${ut}/${e}/cwd`)}catch{return null}if(!c)return null;try{return await l.realPath(c)}catch{return null}}async function ha(e,l=ao){let c=[];for(let p of await pa(l)){if(c.length>=Eu)break;let m=await fa(p,l);if(!m||!da(e,m))continue;c.push({pid:p,command:await ma(p,l),cwd:Tu(e,m)})}return{processes:c}}function ua(e){let l=[];for(let c=0;c<8;c+=2)l.unshift(Number.parseInt(e.slice(c,c+2),16));return l}function Du(e){let l=[];for(let S=0;S<16;S+=2)l.push(e[S]<<8|e[S+1]);if(l.slice(0,5).every((S)=>S===0)&&l[5]===65535)return`::ffff:${e.slice(12).join(".")}`;let c=-1,p=0,m=-1;for(let S=0;S<=l.length;S+=1){if(S<l.length&&l[S]===0){if(m<0)m=S;continue}if(m>=0){let w=S-m;if(w>p)c=m,p=w;m=-1}}let f=l.map((S)=>S.toString(16));if(p<2)return f.join(":");let h=f.slice(0,c).join(":"),y=f.slice(c+p).join(":");return`${h}::${y}`}function Nu(e,l){if(/^[0-9A-Fa-f]{8}$/.test(e)){let c=ua(e);if(c.every((p)=>p===0))return`*:${l}`;return`${c.join(".")}:${l}`}if(/^[0-9A-Fa-f]{32}$/.test(e)){let c=[];for(let p=0;p<4;p+=1)c.push(...ua(e.slice(p*8,p*8+8)));if(c.every((p)=>p===0))return`*:${l}`;return`[${Du(c)}]:${l}`}return null}function Mu(e,l){let c=[];for(let p of e.split(`
|
|
38
|
+
`).slice(1)){if(c.length>=l)break;let m=p.trim().split(/\s+/);if(m.length<=ca)continue;if(m[Iu]?.toUpperCase()!==Lu)continue;let f=m[Au]??"",h=f.lastIndexOf(":");if(h<0)continue;let y=Number.parseInt(f.slice(h+1),16);if(!Number.isInteger(y)||y<=0||y>65535)continue;let S=Nu(f.slice(0,h),y),w=m[ca];if(!S||!w||!/^[0-9]+$/.test(w))continue;c.push({inode:w,port:y,address:S})}return c}async function $u(e){let l=[];for(let c of["tcp","tcp6"]){if(l.length>=aa)break;let p;try{p=await e.readTextFile(`${ut}/net/${c}`)}catch{continue}l.push(...Mu(p,aa-l.length))}return l}async function Bu(e,l){let c=new Map;if(e.size===0)return c;for(let p of await pa(l)){if(c.size>=e.size)break;let m;try{m=await l.readDirectory(`${ut}/${p}/fd`)}catch{continue}for(let f of m.slice(0,Ou)){let h;try{h=await l.readLink(`${ut}/${p}/fd/${f}`)}catch{continue}let y=h.match(ku)?.[1];if(!y||!e.has(y)||c.has(y))continue;c.set(y,p)}}return c}async function ga(e,l=ao){let c=await $u(l),p=await Bu(new Set(c.map((g)=>g.inode)),l),m=[];for(let g of c){let v=p.get(g.inode);if(v===void 0)continue;m.push({pid:v,port:g.port,address:g.address})}m.sort((g,v)=>g.pid-v.pid||g.port-v.port||(g.address<v.address?-1:g.address>v.address?1:0));let f=[...new Set(m.map((g)=>g.pid))].slice(0,Cu),h=await Promise.all(f.map(async(g)=>[g,await fa(g,l)])),y=new Map(h),S=m.filter((g)=>{let v=y.get(g.pid);return Boolean(v&&da(e,v))}),w=new Map(await Promise.all([...new Set(S.map((g)=>g.pid))].map(async(g)=>[g,await ma(g,l)])));return{ports:S.slice(0,Pu).map((g)=>({pid:g.pid,command:w.get(g.pid)??null,address:g.address}))}}import{posix as uo}from"path";var Gr=200,Fu=250,Uu=250;async function zr(e,l){let c=await e(l);if(c.timedOut||c.truncated||c.exitCode!==0&&c.exitCode!==1)throw new r("process_inspection_failed","Reading this Mac's processes did not complete.");let p=[],m=null;for(let f of c.stdout.split(/\r?\n/))if(f.startsWith("p")){let h=Number(f.slice(1));if(m=Number.isInteger(h)&&h>0?{pid:h,command:null,names:[]}:null,m)p.push(m)}else if(m&&f.startsWith("c"))m.command=f.slice(1)||null;else if(m&&f.startsWith("n"))m.names.push(f.slice(1));return p}function lo(e,l){return l===e||l.startsWith(e==="/"?e:`${e}/`)}var _a="/System/Volumes/Data",Hu=["/tmp","/var","/etc"];function po(e){let l=uo.normalize(e);if(l.startsWith(`${_a}/`))l=l.slice(_a.length);return Hu.find((p)=>l===p||l.startsWith(`${p}/`))?`/private${l}`:l}function ya(e){return e&&uo.isAbsolute(e)?po(e):null}async function ba(e,l){let c=new Map;for(let p=0;p<l.length;p+=Gr){let m=l.slice(p,p+Gr).join(",");for(let f of await zr(e,["-a","-p",m,"-d","cwd","-Fpcn"]))c.set(f.pid,{command:f.command,cwd:ya(f.names[0])})}return c}async function wa(e,l){let c=po(e),p=(await zr(l,["-d","cwd","-Fpn"])).filter((f)=>{let h=ya(f.names[0]);return h!==null&&lo(c,h)}).map((f)=>f.pid).slice(0,Fu),m=await ba(l,p);return{processes:p.flatMap((f)=>{let h=m.get(f);return h?.cwd&&lo(c,h.cwd)?[{pid:f,command:h.command,cwd:uo.relative(c,h.cwd)||"."}]:[]})}}async function Sa(e,l){let c=po(e),p=["-nP","-iTCP","-sTCP:LISTEN","-Fpcn"],m=await zr(l,p),f=await ba(l,m.map((w)=>w.pid)),h=m.map((w)=>w.pid).filter((w)=>{let g=f.get(w)?.cwd;return Boolean(g&&lo(c,g))});if(h.length===0)return{ports:[]};let y=new Set(m.flatMap((w)=>w.names.map((g)=>`${w.pid} ${g}`))),S=[];for(let w=0;w<h.length;w+=Gr){let g=h.slice(w,w+Gr).join(",");for(let v of await zr(l,["-a","-p",g,...p]))for(let C of v.names)if(y.has(`${v.pid} ${C}`))S.push({pid:v.pid,command:v.command,address:C})}return{ports:S.slice(0,Uu)}}import{join as Qu}from"path";import{spawn as Vu}from"child_process";import{randomUUID as Ku}from"crypto";import{chmodSync as xa,lstatSync as Ea,mkdirSync as Yu,readdirSync as Xu,statSync as Ju,unlinkSync as Zu}from"fs";import{join as fo}from"path";var mo={targets:24,assets:128,sourceFiles:2000,sourceBytes:20000000,outputBytes:20000000};var Vr=(e,l=0,c=1e6)=>typeof e==="number"&&Number.isFinite(e)&&e>=l&&e<=c;var dt=()=>{throw Error("proof_visual_contract_invalid")};class va extends Error{constructor(){super("proof_visual_contract_invalid")}}function ln(e){if(!be(e)||e.version!==1)return dt();if(typeof e.route!=="string"||!e.route.startsWith("/")||e.route.length>512||/[\x00-\x20\x7f\\?#%]/.test(e.route)||e.route.startsWith("//"))throw new va;if(!be(e.viewport)||!Vr(e.viewport.width,1,4096)||!Vr(e.viewport.height,1,4096)||!Array.isArray(e.targets)||e.targets.length<1||e.targets.length>mo.targets||Object.keys(e).some((p)=>!["version","route","viewport","targets","additionalViewports"].includes(p)))return dt();let l=e.targets.map((p)=>{if(!be(p)||typeof p.id!=="string"||!/^[a-zA-Z0-9_-]{1,64}$/.test(p.id)||typeof p.selector!=="string"||!p.selector.trim()||p.selector.length>256||/[\x00-\x1f\x7f]/.test(p.selector)||Object.keys(p).some((m)=>!["id","selector"].includes(m)))return dt();return{id:p.id,selector:p.selector}});if(new Set(l.map((p)=>p.id)).size!==l.length)return dt();let c;if(e.additionalViewports!==void 0){if(!Array.isArray(e.additionalViewports)||e.additionalViewports.length<1||e.additionalViewports.length>3)return dt();c=e.additionalViewports.map((m)=>{if(!be(m)||!Vr(m.width,1,4096)||!Number.isInteger(m.width)||!Vr(m.height,1,4096)||!Number.isInteger(m.height)||Object.keys(m).some((f)=>!["width","height"].includes(f)))return dt();return{width:m.width,height:m.height}});let p=[e.viewport,...c].map((m)=>`${m.width}x${m.height}`);if(new Set(p).size!==p.length)return dt()}return{version:1,route:e.route,viewport:{width:e.viewport.width,height:e.viewport.height},targets:l,...c?{additionalViewports:c}:{}}}var Wu=["organizationId","userId","sessionId","runId"],Gu=[...Wu,"prUrl","headSha","skillDigest","evidenceKind"],mh=[...Gu,"contextId","preparedAt","captureId","startedAt","finishedAt","sha256","kind","visualPlan","visualObservation"];var zu={"image/png":{kind:"image",directory:"/tmp/ara-public-screenshots",extension:"png",maxBytes:8388608},"video/webm":{kind:"video",directory:"/tmp/ara-public-recordings",extension:"webm",maxBytes:10551296}};function Ra(e){return zu[e].directory}var Ca=10485760;function Pa(e={}){let l=e.directory??Ra("video/webm"),c=null;return{async start(p){if(c)throw Error("cloud_browser_recording_active");let m=p?.seconds;if(!Number.isInteger(m)||Number(m)<1||Number(m)>15||!p||Object.keys(p).some((N)=>N!=="seconds"))throw Error("cloud_browser_recording_seconds_1_to_15_required");Yu(l,{recursive:!0,mode:457});let f=Ea(l);if(!f.isDirectory()||f.isSymbolicLink()||f.uid!==process.getuid?.())throw Error("cloud_browser_recording_directory_invalid");xa(l,457);let h=Xu(l).filter((N)=>/^[a-f0-9-]{36}\.webm$/.test(N)).map((N)=>({name:N,time:Ju(fo(l,N)).mtimeMs})).sort((N,L)=>L.time-N.time);for(let N of h.slice(9))Zu(fo(l,N.name));let y=fo(l,`${Ku()}.webm`),S=["-f","x11grab","-framerate","12","-i",e.display??":99"],w=(e.spawn??Vu)(e.ffmpeg??"ffmpeg",["-nostdin","-hide_banner","-loglevel","error","-y",...S,"-t",String(m),"-vf","scale=1280:-2","-c:v","libvpx","-deadline","realtime","-b:v","700k","-an","-fs",String(Ca),"-progress","pipe:1",y],{stdio:["ignore","pipe","ignore"],...e.env?{env:e.env}:{}}),g,v,C=!1,A=new Promise((N,L)=>{g=N,v=L});w.stdout.on("data",(N)=>{if(/frame=\s*[1-9]/.test(String(N)))C=!0,g()});let I=new Promise((N,L)=>{w.once("error",()=>{v(Error("cloud_browser_recording_unavailable")),L(Error("cloud_browser_recording_unavailable"))}),w.once("exit",(B)=>{try{if(B!==0&&B!==255)throw Error();let F=Ea(y);if(!C||!F.isFile()||F.isSymbolicLink()||F.uid!==process.getuid?.()||F.size<128||F.size>Ca+65536)throw Error();xa(y,420),g(),N({path:y,mimeType:"video/webm"})}catch{v(Error("cloud_browser_recording_failed")),L(Error("cloud_browser_recording_failed"))}})});I.catch(()=>{});let M=setTimeout(()=>w.kill("SIGKILL"),(Number(m)+5)*1000);I.finally(()=>clearTimeout(M)).catch(()=>{}),c={done:I,stop:()=>(w.kill("SIGINT"),I)};try{await A}catch(N){throw c=null,N}return{recording:!0,seconds:Number(m)}},async stop(){if(!c)throw Error("cloud_browser_recording_not_started");let p=c;return c=null,p.stop()},async close(){if(c)await this.stop().catch(()=>{})}}}function Oa(e,l={}){if(e.executionMode!=="unsandboxed"||!e.runtimeDirectory||(l.platform??process.platform)!=="linux")return null;let c=(l.components??x)(),p=c?.features.display?c.ffmpeg:null;if(!p)return null;let m=Qu(e.runtimeDirectory,"recordings"),f=null;return{async start(h){let y=await(l.desktop??qe)();return f??=Pa({directory:m,display:y.display,ffmpeg:p,env:{HOME:a(),PATH:"/usr/local/bin:/usr/bin:/bin",XAUTHORITY:y.xauthority},...l.spawn?{spawn:l.spawn}:{}}),f.start(h)},async stop(){if(!f)throw Error("cloud_browser_recording_not_started");return f.stop()},async close(){await f?.close()}}}import{spawn as Xo}from"child_process";import{createHash as bd,randomUUID as wd}from"crypto";import{existsSync as je,mkdirSync as Ho,mkdtempSync as Zo,readdirSync as nn,readFileSync as Qo,renameSync as Sd,rmSync as ar,statSync as Zr,writeFileSync as vd}from"fs";import{homedir as ei,tmpdir as Ya}from"os";import{basename as Xa,dirname as jo,join as J,relative as Ja,resolve as qo,sep as Za}from"path";var Ce=t().min(1).max(200),He=o().finite().min(0).max(1e4),Kr=t().min(1).max(4096).refine((e)=>!e.includes("\x00")),Aa=t().regex(/^[A-Za-z0-9][A-Za-z0-9.-]{0,254}$/),go=i({id:t().min(1).max(500).optional(),label:t().min(1).max(500).optional()}).strict(),_o=["home","lock","side_button","siri","apple_pay"],ed=s(["tree","screenshot","both","none"]),td=i({...go.shape,gone:d().optional()}).strict().refine((e)=>Boolean(e.id||e.label),"wait_for needs an id or label"),rt={observe:ed.optional(),wait_for:td.optional(),timeout:o().min(0).max(20).optional()},ho=_("action",[i({action:n("tap"),x:He.optional(),y:He.optional(),...go.shape,duration:o().min(0).max(10).optional()}).strict().refine((e)=>e.x!==void 0&&e.y!==void 0||Boolean(e.id||e.label),"pass x and y, or an id or label"),i({action:n("swipe"),x:He,y:He,x2:He,y2:He,duration:o().min(0.05).max(5).optional()}).strict(),i({action:n("type"),text:t().min(1).max(4000)}).strict(),i({action:n("button"),name:s(_o)}).strict(),i({action:n("sleep"),seconds:o().min(0).max(10)}).strict()]),Ro=_("action",[i({action:n("devices")}).strict(),i({action:n("boot"),device:Ce}).strict(),i({action:n("shutdown"),device:Ce}).strict(),i({action:n("build"),path:Kr.optional(),scheme:t().min(1).max(200).optional(),configuration:t().min(1).max(100).optional(),device:Ce.optional(),wait:d().optional()}).strict(),i({action:n("run"),path:Kr.optional(),scheme:t().min(1).max(200).optional(),configuration:t().min(1).max(100).optional(),device:Ce.optional(),steps:u(Fo(()=>ho)).max(30).optional(),...rt}).strict(),i({action:n("build_status"),build_id:t().regex(/^build-[0-9a-z-]{4,64}$/),device:Ce.optional(),wait:d().optional()}).strict(),i({action:n("launch"),device:Ce.optional(),app_path:Kr.optional(),bundle_id:Aa.optional(),steps:u(Fo(()=>ho)).max(30).optional(),...rt}).strict().refine((e)=>Boolean(e.app_path)!==Boolean(e.bundle_id),"pass exactly one of app_path or bundle_id"),i({action:n("terminate"),device:Ce.optional(),bundle_id:Aa}).strict(),i({action:n("logs"),device:Ce.optional(),after:o().int().min(0).optional()}).strict(),i({action:n("screenshot"),device:Ce.optional(),scale:W([n(1),n(2)]).optional(),save_path:Kr.optional()}).strict(),i({action:n("chrome"),device:Ce.optional()}).strict(),i({action:n("inspect"),device:Ce.optional()}).strict(),i({action:n("tap"),device:Ce.optional(),x:He.optional(),y:He.optional(),...go.shape,duration:o().min(0).max(10).optional(),...rt}).strict().refine((e)=>e.x!==void 0&&e.y!==void 0||Boolean(e.id||e.label),"pass x and y, or an id or label"),i({action:n("swipe"),device:Ce.optional(),x:He,y:He,x2:He,y2:He,duration:o().min(0.05).max(5).optional(),...rt}).strict(),i({action:n("type"),device:Ce.optional(),text:t().min(1).max(4000),...rt}).strict(),i({action:n("button"),device:Ce.optional(),name:s(_o),...rt}).strict(),i({action:n("open_url"),device:Ce.optional(),url:t().min(1).max(4000),...rt}).strict(),i({action:n("steps"),device:Ce.optional(),steps:u(ho).min(1).max(30),...rt}).strict(),i({action:n("appearance"),device:Ce.optional(),mode:s(["light","dark"])}).strict()]),Ia=i({udid:t(),name:t(),runtime:t(),state:s(["booted","shutdown","booting","shutting_down"]),kind:s(["iphone","ipad","other"])}).strict(),kh=i({text:t(),error:t().optional(),device:Ia.optional(),devices:u(Ia).optional(),image:i({mime:n("image/jpeg"),data:t(),width:o(),height:o()}).strict().optional(),build:i({id:t(),status:s(["running","succeeded","failed"]),app_path:t().optional(),bundle_id:t().optional(),errors:u(t()),log_tail:t(),elapsed_ms:o()}).strict().optional(),logs:i({lines:u(t()),next:o()}).strict().optional(),screen:t().optional(),chrome:i({identifier:t(),screen:i({width:o(),height:o()}).strict(),inset:i({top:o(),left:o(),bottom:o(),right:o()}).strict(),padding:i({top:o(),left:o(),bottom:o(),right:o()}).strict(),screen_mask:t().optional(),pieces:ee(s(["topLeft","top","topRight","right","bottomRight","bottom","bottomLeft","left"]),i({image:t(),width:o(),height:o()}).strict()),buttons:u(i({name:t(),image:t(),x:o(),y:o(),width:o(),height:o()}).strict())}).strict().optional()}).strict();var Th=i({device_id:k().optional(),root_id:k().optional()}),Yr={device_id:{type:"string",format:"uuid",description:"Reason machine id from devices.list; omit for the machine this Session runs on."},root_id:{type:"string",format:"uuid"},device:{type:"string",description:"Simulator UDID or exact name. Required for boot and shutdown; for other actions omit it for the booted one."},path:{type:"string",description:"build or run: a .xcodeproj, .xcworkspace, or a folder holding one (project.yml is generated with XcodeGen), absolute or relative to the Session's folder. Omit it when the folder holds one app project."},scheme:{type:"string"},configuration:{type:"string"},build_id:{type:"string",description:"build_status (required): the build_id a build or run returned."},app_path:{type:"string",description:"launch: the built .app from build_status (or pass bundle_id instead)."},bundle_id:{type:"string",description:"terminate (required); launch: an installed app's bundle id instead of app_path."},after:{type:"integer",minimum:0,description:"logs: only lines after this sequence number."},x:{type:"number",description:"tap (with y, unless id or label is given) or swipe (required): start point in device points."},y:{type:"number"},x2:{type:"number",description:"swipe (required, with y2): end point in device points."},y2:{type:"number"},id:{type:"string",description:"tap: accessibility identifier from inspect (instead of x and y)."},label:{type:"string",description:"tap: accessibility label from inspect (instead of x and y)."},duration:{type:"number",description:"tap: seconds held (above 0.5 is a long press); swipe: seconds."},text:{type:"string",description:"type (required): the text to type."},name:{type:"string",enum:[..._o],description:"button (required)."},url:{type:"string",description:"open_url (required): the URL or deep link."},mode:{type:"string",enum:["light","dark"],description:"appearance (required)."},steps:{type:"array",maxItems:30,description:"steps (required, at least one) or launch and run: run in order in one call (after launch, once the app is up). Each item is {action:'tap', id|label|x,y} | {action:'swipe', x,y,x2,y2} | {action:'type', text} | {action:'button', name} | {action:'sleep', seconds}. Taps by id or label wait for their element to appear.",items:{type:"object"}},observe:{type:"string",enum:["tree","screenshot","both","none"],description:"After tap, swipe, type, button, open_url, launch or steps: what to return about the settled screen. Default tree (the accessibility tree, so no separate inspect is needed); screenshot or both to see it."},wait_for:{type:"object",description:"After the action, wait until this element is on screen: {id} or {label}; add gone:true to wait for it to disappear.",properties:{id:{type:"string"},label:{type:"string"},gone:{type:"boolean"}},additionalProperties:!1},timeout:{type:"number",description:"Seconds to wait for wait_for (default 5, max 20)."},wait:{type:"boolean",description:"build or build_status: wait for the build to finish (up to ~45 s) instead of returning at once."},save_path:{type:"string",description:"screenshot: also save the full-resolution PNG at this path (absolute or relative to the Session's folder), for example to show the user."}},ka=Ro.options.map((e)=>e.shape).filter((e)=>e.action.value!=="chrome"),rd={tap:[{required:["x","y"]},{required:["id"]},{required:["label"]}],launch:[{required:["app_path"],without:["bundle_id"]},{required:["bundle_id"],without:["app_path"]}]},La=new Set;function nd(e,l){let{description:c,...p}=e==="steps"&&l==="steps"?{...Yr.steps,minItems:1}:Yr[e];if(c===void 0||La.has(e))return p;return La.add(e),{...p,description:c}}var od=ka.flatMap((e)=>{let l=e.action.value,c=Object.keys(e).filter((m)=>Object.hasOwn(Yr,m)),p=c.filter((m)=>!e[m].safeParse(void 0).success);return(rd[l]??[{required:[]}]).map((m)=>({type:"object",properties:Object.fromEntries([["action",{type:"string",const:l}],...["device_id","root_id",...c].filter((f)=>!m.without?.includes(f)).map((f)=>[f,nd(f,l)])]),required:["action",...p,...m.required],additionalProperties:!1}))}),id={type:"object",properties:{action:{type:"string",enum:ka.map((e)=>e.action.value)},...Yr},required:["action"],additionalProperties:!1},Dh={...id,anyOf:od};import{spawn as Io}from"child_process";import{createHash as ad}from"crypto";import{existsSync as Oo,mkdirSync as Xr,mkdtempSync as ld,readdirSync as Ta,readFileSync as Da,renameSync as cd,rmSync as Na,symlinkSync as Ao,writeFileSync as or}from"fs";import{homedir as ud}from"os";import{dirname as Fa,join as re}from"path";import{createInterface as dd}from"readline";var Po=`// Reason's simulator host: one warm process per booted iOS Simulator.
|
|
39
|
+
//
|
|
40
|
+
// Built on the Mac on first use (cli/simulator-host.ts) against the MIT
|
|
41
|
+
// FBSimulatorControl frameworks that the pinned AXe ships, so loading
|
|
42
|
+
// SimulatorKit and connecting to the simulator happen once per process
|
|
43
|
+
// instead of once per action (about a second each, three under load).
|
|
44
|
+
//
|
|
45
|
+
// simulator-host serve <udid>
|
|
46
|
+
// Newline JSON requests on stdin, one newline JSON reply each on stdout,
|
|
47
|
+
// in order: {"id":1,"op":"tap","x":100,"y":200} -> {"id":1,"ok":true}.
|
|
48
|
+
// Ops: touch (phase down|move|up), tap, swipe, button, text, key, tree.
|
|
49
|
+
// Coordinates are device points. \`tree\` answers AXe describe-ui's JSON.
|
|
50
|
+
// simulator-host stream <udid> <fps> <max pixels> <kbps>
|
|
51
|
+
// H.264 (Main, level 4.2) as Annex-B on stdout, encoded with VideoToolbox
|
|
52
|
+
// straight from the simulator's framebuffer. Every keyframe carries
|
|
53
|
+
// SPS/PPS, and every access unit is followed by an AUD, so a reader that
|
|
54
|
+
// splits at AUDs has each frame as soon as it is written.
|
|
55
|
+
//
|
|
56
|
+
// Both modes exit when stdin closes, so they never outlive the worker.
|
|
57
|
+
|
|
58
|
+
import CoreMedia
|
|
59
|
+
import CoreVideo
|
|
60
|
+
import Darwin
|
|
61
|
+
import FBControlCore
|
|
62
|
+
import FBSimulatorControl
|
|
63
|
+
import Foundation
|
|
64
|
+
import IOSurface
|
|
65
|
+
import VideoToolbox
|
|
66
|
+
|
|
67
|
+
@objc final class SilentReporter: NSObject, FBEventReporter {
|
|
68
|
+
var metadata: [String: String] = [:]
|
|
69
|
+
func report(_ subject: FBEventReporterSubject) {}
|
|
70
|
+
func addMetadata(_ metadata: [String: String]) {}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let logger: FBControlCoreLogger = FBControlCoreLoggerFactory.systemLoggerWriting(toStderr: false, withDebugLogging: false)
|
|
74
|
+
|
|
75
|
+
func fail(_ message: String) -> Never {
|
|
76
|
+
FileHandle.standardError.write(Data((message + "\\n").utf8))
|
|
77
|
+
exit(1)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/// Writes all of \`data\` to stdout; a closed reader ends the process.
|
|
81
|
+
func writeOut(_ data: Data) {
|
|
82
|
+
data.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) in
|
|
83
|
+
var offset = 0
|
|
84
|
+
while offset < buffer.count {
|
|
85
|
+
let written = Darwin.write(1, buffer.baseAddress!.advanced(by: offset), buffer.count - offset)
|
|
86
|
+
if written <= 0 {
|
|
87
|
+
if written < 0 && errno == EINTR { continue }
|
|
88
|
+
exit(0)
|
|
89
|
+
}
|
|
90
|
+
offset += written
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@MainActor
|
|
96
|
+
func simulator(_ udid: String) async throws -> FBSimulator {
|
|
97
|
+
try FBSimulatorControlFrameworkLoader.essentialFrameworks.loadPrivateFrameworks(logger)
|
|
98
|
+
try FBSimulatorControlFrameworkLoader.xcodeFrameworks.loadPrivateFrameworks(logger)
|
|
99
|
+
FBControlCoreGlobalConfiguration.defaultLogger = logger
|
|
100
|
+
let configuration = FBSimulatorControlConfiguration(deviceSetPath: nil, logger: logger, reporter: SilentReporter())
|
|
101
|
+
let set = try FBSimulatorControl.withConfiguration(configuration).set
|
|
102
|
+
guard let target = set.allSimulators.first(where: { $0.udid == udid }) else { fail("simulator_not_found") }
|
|
103
|
+
guard target.state == .booted else { fail("simulator_not_booted") }
|
|
104
|
+
return target
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// MARK: - serve
|
|
108
|
+
|
|
109
|
+
/// US keyboard: character -> (HID usage, shift).
|
|
110
|
+
let keyboard: [Character: (UInt32, Bool)] = {
|
|
111
|
+
var map: [Character: (UInt32, Bool)] = [:]
|
|
112
|
+
for (index, letter) in "abcdefghijklmnopqrstuvwxyz".enumerated() {
|
|
113
|
+
map[letter] = (UInt32(4 + index), false)
|
|
114
|
+
map[Character(letter.uppercased())] = (UInt32(4 + index), true)
|
|
115
|
+
}
|
|
116
|
+
for (index, digit) in "1234567890".enumerated() { map[digit] = (UInt32(30 + index), false) }
|
|
117
|
+
for (index, symbol) in "!@#$%^&*()".enumerated() { map[symbol] = (UInt32(30 + index), true) }
|
|
118
|
+
let plain: [(Character, UInt32)] = [("\\n", 40), ("\\t", 43), (" ", 44), ("-", 45), ("=", 46), ("[", 47), ("]", 48),
|
|
119
|
+
("\\\\", 49), (";", 51), ("'", 52), ("\`", 53), (",", 54), (".", 55), ("/", 56)]
|
|
120
|
+
let shifted: [(Character, UInt32)] = [("_", 45), ("+", 46), ("{", 47), ("}", 48), ("|", 49), (":", 51), ("\\"", 52),
|
|
121
|
+
("~", 53), ("<", 54), (">", 55), ("?", 56)]
|
|
122
|
+
for (character, usage) in plain { map[character] = (usage, false) }
|
|
123
|
+
for (character, usage) in shifted { map[character] = (usage, true) }
|
|
124
|
+
return map
|
|
125
|
+
}()
|
|
126
|
+
|
|
127
|
+
let buttons: [String: FBSimulatorHIDButton] = [
|
|
128
|
+
"home": .homeButton, "lock": .lock, "side_button": .sideButton, "siri": .siri, "apple_pay": .applePay,
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
/// AXe describe-ui's keys (its schema), so the worker parses one format either way.
|
|
132
|
+
let treeKeys: Set<FBAXKeys> = [.label, .frame, .value, .uniqueID, .type, .title, .frameDict, .help, .enabled,
|
|
133
|
+
.customActions, .role, .roleDescription, .subrole, .contentRequired, .pid]
|
|
134
|
+
|
|
135
|
+
func withTraits(_ value: Any) -> Any {
|
|
136
|
+
if let list = value as? [Any] { return list.map(withTraits) }
|
|
137
|
+
guard var element = value as? [String: Any] else { return value }
|
|
138
|
+
for (key, child) in element { element[key] = withTraits(child) }
|
|
139
|
+
if element["type"] != nil && element["traits"] == nil { element["traits"] = [String]() }
|
|
140
|
+
return element
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
func hasChildren(_ value: Any) -> Bool {
|
|
144
|
+
let roots = (value as? [[String: Any]]) ?? ((value as? [String: Any]).map { [$0] } ?? [])
|
|
145
|
+
return roots.contains { (($0["children"] as? [Any])?.isEmpty == false) }
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@MainActor
|
|
149
|
+
func readTree(_ target: FBSimulator) async throws -> String {
|
|
150
|
+
var latest: Any = []
|
|
151
|
+
for attempt in 0..<4 {
|
|
152
|
+
let element = try await target.accessibilityElementForFrontmostApplication()
|
|
153
|
+
defer { element.close() }
|
|
154
|
+
let response = try element.serialize(with: FBAccessibilityRequestOptions(nestedFormat: true, keys: treeKeys))
|
|
155
|
+
latest = withTraits(response.elements)
|
|
156
|
+
if hasChildren(latest) { break }
|
|
157
|
+
if attempt < 3 { try await Task.sleep(for: .milliseconds(50 << attempt)) }
|
|
158
|
+
}
|
|
159
|
+
let data = try JSONSerialization.data(withJSONObject: latest)
|
|
160
|
+
return String(decoding: data, as: UTF8.self)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
@MainActor
|
|
164
|
+
func handle(_ request: [String: Any], target: FBSimulator, hid: FBSimulatorHID) async throws -> [String: Any] {
|
|
165
|
+
let number = { (key: String) -> Double in
|
|
166
|
+
guard let value = request[key] as? Double else { throw NSError(domain: "simulator-host", code: 1, userInfo: [NSLocalizedDescriptionKey: "missing \\(key)"]) }
|
|
167
|
+
return value
|
|
168
|
+
}
|
|
169
|
+
switch request["op"] as? String {
|
|
170
|
+
case "touch":
|
|
171
|
+
let direction: FBSimulatorHIDDirection = (request["phase"] as? String) == "up" ? .up : .down
|
|
172
|
+
try await hid.send(event: .touch(direction: direction, x: try number("x"), y: try number("y")), logger: logger)
|
|
173
|
+
case "tap":
|
|
174
|
+
let duration = request["duration"] as? Double ?? 0
|
|
175
|
+
let event: FBSimulatorHIDEvent = duration > 0
|
|
176
|
+
? .tapAt(x: try number("x"), y: try number("y"), duration: duration) : .tapAt(x: try number("x"), y: try number("y"))
|
|
177
|
+
try await hid.send(event: event, logger: logger)
|
|
178
|
+
case "swipe":
|
|
179
|
+
try await hid.send(event: .swipe(try number("x"), yStart: try number("y"), xEnd: try number("x2"), yEnd: try number("y2"),
|
|
180
|
+
delta: request["delta"] as? Double ?? 10, duration: request["duration"] as? Double ?? 0.3), logger: logger)
|
|
181
|
+
case "button":
|
|
182
|
+
guard let button = buttons[request["name"] as? String ?? ""] else { throw NSError(domain: "simulator-host", code: 1, userInfo: [NSLocalizedDescriptionKey: "unknown button"]) }
|
|
183
|
+
try await hid.send(event: .shortButtonPress(button), logger: logger)
|
|
184
|
+
case "text":
|
|
185
|
+
var events: [FBSimulatorHIDEvent] = []
|
|
186
|
+
for character in request["text"] as? String ?? "" {
|
|
187
|
+
guard let (usage, shift) = keyboard[character] else {
|
|
188
|
+
throw NSError(domain: "simulator-host", code: 2, userInfo: [NSLocalizedDescriptionKey: "unsupported character"])
|
|
189
|
+
}
|
|
190
|
+
if shift { events.append(.keyboard(direction: .down, keyCode: 225)) }
|
|
191
|
+
events.append(.keyboard(direction: .down, keyCode: usage))
|
|
192
|
+
events.append(.keyboard(direction: .up, keyCode: usage))
|
|
193
|
+
if shift { events.append(.keyboard(direction: .up, keyCode: 225)) }
|
|
194
|
+
}
|
|
195
|
+
if !events.isEmpty { try await hid.send(event: .composite(events), logger: logger) }
|
|
196
|
+
case "key":
|
|
197
|
+
let direction: FBSimulatorHIDDirection = (request["down"] as? Bool) == false ? .up : .down
|
|
198
|
+
try await hid.send(event: .keyboard(direction: direction, keyCode: UInt32(try number("usage"))), logger: logger)
|
|
199
|
+
case "tree":
|
|
200
|
+
return ["tree": try await readTree(target)]
|
|
201
|
+
default:
|
|
202
|
+
throw NSError(domain: "simulator-host", code: 1, userInfo: [NSLocalizedDescriptionKey: "unknown op"])
|
|
203
|
+
}
|
|
204
|
+
return [:]
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
@MainActor
|
|
208
|
+
func serve(_ udid: String) async {
|
|
209
|
+
let target: FBSimulator
|
|
210
|
+
let hid: FBSimulatorHID
|
|
211
|
+
do {
|
|
212
|
+
target = try await simulator(udid)
|
|
213
|
+
hid = try await target.connectToHID()
|
|
214
|
+
} catch {
|
|
215
|
+
fail("connect_failed: \\(error.localizedDescription)")
|
|
216
|
+
}
|
|
217
|
+
writeOut(Data("{\\"ready\\":true}\\n".utf8))
|
|
218
|
+
do {
|
|
219
|
+
for try await line in FileHandle.standardInput.bytes.lines {
|
|
220
|
+
guard let request = (try? JSONSerialization.jsonObject(with: Data(line.utf8))) as? [String: Any] else { continue }
|
|
221
|
+
var reply: [String: Any]
|
|
222
|
+
do {
|
|
223
|
+
reply = try await handle(request, target: target, hid: hid)
|
|
224
|
+
reply["ok"] = true
|
|
225
|
+
} catch {
|
|
226
|
+
reply = ["ok": false, "error": error.localizedDescription]
|
|
227
|
+
}
|
|
228
|
+
reply["id"] = request["id"] ?? 0
|
|
229
|
+
var data = (try? JSONSerialization.data(withJSONObject: reply)) ?? Data("{\\"ok\\":false}".utf8)
|
|
230
|
+
data.append(0x0A)
|
|
231
|
+
writeOut(data)
|
|
232
|
+
}
|
|
233
|
+
} catch {}
|
|
234
|
+
exit(0)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// MARK: - stream
|
|
238
|
+
|
|
239
|
+
let startCode = Data([0, 0, 0, 1])
|
|
240
|
+
let accessUnitDelimiter = Data([0, 0, 0, 1, 0x09, 0xF0])
|
|
241
|
+
|
|
242
|
+
struct BitReader {
|
|
243
|
+
let bytes: [UInt8]
|
|
244
|
+
var position = 0
|
|
245
|
+
mutating func bit() -> UInt32? {
|
|
246
|
+
guard position < bytes.count * 8 else { return nil }
|
|
247
|
+
defer { position += 1 }
|
|
248
|
+
return UInt32(bytes[position >> 3] >> (7 - UInt8(position & 7)) & 1)
|
|
249
|
+
}
|
|
250
|
+
mutating func bits(_ count: Int) -> UInt32? {
|
|
251
|
+
var value: UInt32 = 0
|
|
252
|
+
for _ in 0..<count { guard let next = bit() else { return nil }; value = value << 1 | next }
|
|
253
|
+
return value
|
|
254
|
+
}
|
|
255
|
+
mutating func ue() -> UInt32? {
|
|
256
|
+
var zeros = 0
|
|
257
|
+
while true { guard let next = bit() else { return nil }; if next == 1 { break }; zeros += 1; if zeros > 31 { return nil } }
|
|
258
|
+
guard let rest = bits(zeros) else { return nil }
|
|
259
|
+
return (1 << zeros) - 1 + rest
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
struct BitWriter {
|
|
264
|
+
var bytes: [UInt8] = []
|
|
265
|
+
var count = 0
|
|
266
|
+
mutating func bit(_ value: UInt32) {
|
|
267
|
+
if count & 7 == 0 { bytes.append(0) }
|
|
268
|
+
if value & 1 == 1 { bytes[bytes.count - 1] |= 1 << (7 - UInt8(count & 7)) }
|
|
269
|
+
count += 1
|
|
270
|
+
}
|
|
271
|
+
mutating func bits(_ value: UInt32, _ width: Int) { for shift in stride(from: width - 1, through: 0, by: -1) { bit(value >> UInt32(shift)) } }
|
|
272
|
+
mutating func ue(_ value: UInt32) {
|
|
273
|
+
let coded = value + 1
|
|
274
|
+
let width = 32 - coded.leadingZeroBitCount
|
|
275
|
+
bits(0, width - 1)
|
|
276
|
+
bits(coded, width)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/// The SPS with a VUI that says frames come out in decode order, one at a time. VideoToolbox writes no
|
|
281
|
+
/// bitstream restriction, so a browser decoder may hold the newest frames back for reordering; on a
|
|
282
|
+
/// screen that stops changing, the last one would never be shown. Any SPS this does not expect is kept.
|
|
283
|
+
func lowDelaySps(_ nal: Data) -> Data {
|
|
284
|
+
var raw: [UInt8] = []
|
|
285
|
+
var zeros = 0
|
|
286
|
+
for byte in nal.dropFirst() {
|
|
287
|
+
if zeros >= 2 && byte == 3 { zeros = 0; continue }
|
|
288
|
+
raw.append(byte)
|
|
289
|
+
zeros = byte == 0 ? zeros + 1 : 0
|
|
290
|
+
}
|
|
291
|
+
var reader = BitReader(bytes: raw)
|
|
292
|
+
var writer = BitWriter()
|
|
293
|
+
func copyBits(_ width: Int) -> UInt32? { guard let value = reader.bits(width) else { return nil }; writer.bits(value, width); return value }
|
|
294
|
+
func copyUe() -> UInt32? { guard let value = reader.ue() else { return nil }; writer.ue(value); return value }
|
|
295
|
+
guard let profile = copyBits(8), copyBits(16) != nil, copyUe() != nil else { return nal }
|
|
296
|
+
if [100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 139, 134, 135].contains(profile) {
|
|
297
|
+
guard let chroma = copyUe() else { return nal }
|
|
298
|
+
if chroma == 3 { guard copyBits(1) != nil else { return nal } }
|
|
299
|
+
guard copyUe() != nil, copyUe() != nil, copyBits(1) != nil, let scaling = copyBits(1), scaling == 0 else { return nal }
|
|
300
|
+
}
|
|
301
|
+
guard copyUe() != nil, let pocType = copyUe() else { return nal }
|
|
302
|
+
if pocType == 0 { guard copyUe() != nil else { return nal } } else if pocType != 2 { return nal }
|
|
303
|
+
guard let references = copyUe(), copyBits(1) != nil, copyUe() != nil, copyUe() != nil, let frameOnly = copyBits(1) else { return nal }
|
|
304
|
+
if frameOnly == 0 { guard copyBits(1) != nil else { return nal } }
|
|
305
|
+
guard copyBits(1) != nil, let cropping = copyBits(1) else { return nal }
|
|
306
|
+
if cropping == 1 { for _ in 0..<4 { guard copyUe() != nil else { return nal } } }
|
|
307
|
+
guard reader.bits(1) == 0 else { return nal }
|
|
308
|
+
writer.bit(1) // vui_parameters_present_flag
|
|
309
|
+
writer.bits(0, 6) // aspect ratio, overscan, video signal, chroma location, timing, NAL HRD
|
|
310
|
+
writer.bit(0) // VCL HRD
|
|
311
|
+
writer.bit(0) // pic_struct_present_flag
|
|
312
|
+
writer.bit(1) // bitstream_restriction_flag
|
|
313
|
+
writer.bit(1) // motion_vectors_over_pic_boundaries_flag
|
|
314
|
+
writer.ue(2); writer.ue(1); writer.ue(16); writer.ue(16)
|
|
315
|
+
writer.ue(0) // max_num_reorder_frames
|
|
316
|
+
writer.ue(max(1, references)) // max_dec_frame_buffering
|
|
317
|
+
writer.bit(1) // rbsp_stop_one_bit
|
|
318
|
+
while writer.count & 7 != 0 { writer.bit(0) }
|
|
319
|
+
var out = Data([nal.first!])
|
|
320
|
+
zeros = 0
|
|
321
|
+
for byte in writer.bytes {
|
|
322
|
+
if zeros >= 2 && byte <= 3 { out.append(3); zeros = 0 }
|
|
323
|
+
out.append(byte)
|
|
324
|
+
zeros = byte == 0 ? zeros + 1 : 0
|
|
325
|
+
}
|
|
326
|
+
return out
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
final class Encoder: NSObject, FBFramebufferConsumer, @unchecked Sendable {
|
|
330
|
+
let queue = DispatchQueue(label: "simulator-host.encode")
|
|
331
|
+
let fps: Int
|
|
332
|
+
let maxPixels: Double
|
|
333
|
+
let kbps: Int
|
|
334
|
+
var surface: IOSurface?
|
|
335
|
+
var dirty = true
|
|
336
|
+
var forceKey = true
|
|
337
|
+
var session: VTCompressionSession?
|
|
338
|
+
var transfer: VTPixelTransferSession?
|
|
339
|
+
var size = (width: 0, height: 0)
|
|
340
|
+
var frames: Int64 = 0
|
|
341
|
+
|
|
342
|
+
init(fps: Int, maxPixels: Double, kbps: Int) {
|
|
343
|
+
self.fps = fps
|
|
344
|
+
self.maxPixels = maxPixels
|
|
345
|
+
self.kbps = kbps
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
func didChange(_ surface: IOSurface?) {
|
|
349
|
+
self.surface = surface
|
|
350
|
+
dirty = true
|
|
351
|
+
forceKey = true
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
func didReceiveDamageRect() { dirty = true }
|
|
355
|
+
|
|
356
|
+
/// The encoded picture: the framebuffer scaled to stay within \`maxPixels\`, even sides.
|
|
357
|
+
func outputSize(_ surface: IOSurface) -> (width: Int, height: Int) {
|
|
358
|
+
let width = Double(IOSurfaceGetWidth(surface)), height = Double(IOSurfaceGetHeight(surface))
|
|
359
|
+
let fit = min(1, (maxPixels / (width * height)).squareRoot())
|
|
360
|
+
let even = { (value: Double) in max(2, Int(value * fit) / 2 * 2) }
|
|
361
|
+
return (even(width), even(height))
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
func makeSession(_ width: Int, _ height: Int) {
|
|
365
|
+
if let session { VTCompressionSessionInvalidate(session) }
|
|
366
|
+
var created: VTCompressionSession?
|
|
367
|
+
let status = VTCompressionSessionCreate(allocator: nil, width: Int32(width), height: Int32(height),
|
|
368
|
+
codecType: kCMVideoCodecType_H264, encoderSpecification: nil, imageBufferAttributes: nil,
|
|
369
|
+
compressedDataAllocator: nil, outputCallback: nil, refcon: nil, compressionSessionOut: &created)
|
|
370
|
+
guard status == noErr, let created else { fail("encoder_failed \\(status)") }
|
|
371
|
+
let set = { (key: CFString, value: CFTypeRef) in _ = VTSessionSetProperty(created, key: key, value: value) }
|
|
372
|
+
set(kVTCompressionPropertyKey_RealTime, kCFBooleanTrue)
|
|
373
|
+
set(kVTCompressionPropertyKey_ProfileLevel, kVTProfileLevel_H264_Main_4_2)
|
|
374
|
+
set(kVTCompressionPropertyKey_AllowFrameReordering, kCFBooleanFalse)
|
|
375
|
+
set(kVTCompressionPropertyKey_MaxFrameDelayCount, 0 as CFNumber)
|
|
376
|
+
set(kVTCompressionPropertyKey_ExpectedFrameRate, fps as CFNumber)
|
|
377
|
+
set(kVTCompressionPropertyKey_AverageBitRate, (kbps * 1000) as CFNumber)
|
|
378
|
+
// Keyframes come from a (re)start or a framebuffer change; this is only a safety net.
|
|
379
|
+
set(kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, 60 as CFNumber)
|
|
380
|
+
VTCompressionSessionPrepareToEncodeFrames(created)
|
|
381
|
+
session = created
|
|
382
|
+
size = (width, height)
|
|
383
|
+
var createdTransfer: VTPixelTransferSession?
|
|
384
|
+
VTPixelTransferSessionCreate(allocator: nil, pixelTransferSessionOut: &createdTransfer)
|
|
385
|
+
transfer = createdTransfer
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
func tick() {
|
|
389
|
+
guard dirty, let surface else { return }
|
|
390
|
+
dirty = false
|
|
391
|
+
let wanted = outputSize(surface)
|
|
392
|
+
if session == nil || wanted.width != size.width || wanted.height != size.height { makeSession(wanted.width, wanted.height) }
|
|
393
|
+
guard let session, let transfer, let pool = VTCompressionSessionGetPixelBufferPool(session) else { return }
|
|
394
|
+
var source: Unmanaged<CVPixelBuffer>?
|
|
395
|
+
guard CVPixelBufferCreateWithIOSurface(nil, surface, nil, &source) == kCVReturnSuccess, let source else { return }
|
|
396
|
+
let input = source.takeRetainedValue()
|
|
397
|
+
var output: CVPixelBuffer?
|
|
398
|
+
guard CVPixelBufferPoolCreatePixelBuffer(nil, pool, &output) == kCVReturnSuccess, let output else { return }
|
|
399
|
+
guard VTPixelTransferSessionTransferImage(transfer, from: input, to: output) == noErr else { return }
|
|
400
|
+
let time = CMTime(value: frames, timescale: CMTimeScale(fps))
|
|
401
|
+
frames += 1
|
|
402
|
+
let options = forceKey ? [kVTEncodeFrameOptionKey_ForceKeyFrame: kCFBooleanTrue] as CFDictionary : nil
|
|
403
|
+
forceKey = false
|
|
404
|
+
VTCompressionSessionEncodeFrame(session, imageBuffer: output, presentationTimeStamp: time, duration: .invalid,
|
|
405
|
+
frameProperties: options, infoFlagsOut: nil) { status, _, sample in
|
|
406
|
+
guard status == noErr, let sample else { return }
|
|
407
|
+
Encoder.write(sample)
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/// One access unit as Annex-B, then the next unit's AUD: the reader splits at AUDs, so the unit is complete now.
|
|
412
|
+
static func write(_ sample: CMSampleBuffer) {
|
|
413
|
+
guard let block = CMSampleBufferGetDataBuffer(sample), let format = CMSampleBufferGetFormatDescription(sample) else { return }
|
|
414
|
+
let attachments = CMSampleBufferGetSampleAttachmentsArray(sample, createIfNecessary: false) as? [[CFString: Any]]
|
|
415
|
+
let key = !((attachments?.first?[kCMSampleAttachmentKey_NotSync] as? Bool) ?? false)
|
|
416
|
+
var unit = Data()
|
|
417
|
+
if key {
|
|
418
|
+
var count = 0
|
|
419
|
+
CMVideoFormatDescriptionGetH264ParameterSetAtIndex(format, parameterSetIndex: 0, parameterSetPointerOut: nil,
|
|
420
|
+
parameterSetSizeOut: nil, parameterSetCountOut: &count, nalUnitHeaderLengthOut: nil)
|
|
421
|
+
for index in 0..<count {
|
|
422
|
+
var pointer: UnsafePointer<UInt8>?
|
|
423
|
+
var length = 0
|
|
424
|
+
CMVideoFormatDescriptionGetH264ParameterSetAtIndex(format, parameterSetIndex: index, parameterSetPointerOut: &pointer,
|
|
425
|
+
parameterSetSizeOut: &length, parameterSetCountOut: nil, nalUnitHeaderLengthOut: nil)
|
|
426
|
+
guard let pointer, length > 0 else { continue }
|
|
427
|
+
let set = Data(bytes: pointer, count: length)
|
|
428
|
+
unit.append(startCode)
|
|
429
|
+
unit.append(set[set.startIndex] & 0x1F == 7 ? lowDelaySps(set) : set)
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
var total = 0
|
|
433
|
+
var base: UnsafeMutablePointer<CChar>?
|
|
434
|
+
guard CMBlockBufferGetDataPointer(block, atOffset: 0, lengthAtOffsetOut: nil, totalLengthOut: &total, dataPointerOut: &base) == noErr,
|
|
435
|
+
let base else { return }
|
|
436
|
+
var offset = 0
|
|
437
|
+
while offset + 4 <= total {
|
|
438
|
+
var length: UInt32 = 0
|
|
439
|
+
memcpy(&length, base.advanced(by: offset), 4)
|
|
440
|
+
let nal = Int(CFSwapInt32BigToHost(length))
|
|
441
|
+
offset += 4
|
|
442
|
+
guard offset + nal <= total else { break }
|
|
443
|
+
unit.append(startCode)
|
|
444
|
+
base.advanced(by: offset).withMemoryRebound(to: UInt8.self, capacity: nal) { unit.append($0, count: nal) }
|
|
445
|
+
offset += nal
|
|
446
|
+
}
|
|
447
|
+
unit.append(accessUnitDelimiter)
|
|
448
|
+
writeOut(unit)
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
@MainActor
|
|
453
|
+
func stream(_ udid: String, fps: Int, maxPixels: Double, kbps: Int) async {
|
|
454
|
+
let target: FBSimulator
|
|
455
|
+
let framebuffer: FBFramebuffer
|
|
456
|
+
do {
|
|
457
|
+
target = try await simulator(udid)
|
|
458
|
+
framebuffer = try FBFramebuffer.mainScreenSurface(for: target, logger: logger)
|
|
459
|
+
} catch {
|
|
460
|
+
fail("connect_failed: \\(error.localizedDescription)")
|
|
461
|
+
}
|
|
462
|
+
let encoder = Encoder(fps: fps, maxPixels: maxPixels, kbps: kbps)
|
|
463
|
+
let first = framebuffer.attach(encoder, on: encoder.queue)
|
|
464
|
+
encoder.queue.async { if let first, encoder.surface == nil { encoder.surface = first } }
|
|
465
|
+
writeOut(accessUnitDelimiter)
|
|
466
|
+
let timer = DispatchSource.makeTimerSource(queue: encoder.queue)
|
|
467
|
+
timer.schedule(deadline: .now(), repeating: .nanoseconds(1_000_000_000 / max(1, fps)))
|
|
468
|
+
timer.setEventHandler { encoder.tick() }
|
|
469
|
+
timer.resume()
|
|
470
|
+
// "key" on stdin asks for a keyframe; end of stdin ends the stream.
|
|
471
|
+
do {
|
|
472
|
+
for try await line in FileHandle.standardInput.bytes.lines where line == "key" {
|
|
473
|
+
encoder.queue.async { encoder.forceKey = true; encoder.dirty = true }
|
|
474
|
+
}
|
|
475
|
+
} catch {}
|
|
476
|
+
framebuffer.detach(encoder)
|
|
477
|
+
_ = target
|
|
478
|
+
exit(0)
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// MARK: - main
|
|
482
|
+
|
|
483
|
+
signal(SIGPIPE, SIG_IGN)
|
|
484
|
+
let arguments = CommandLine.arguments
|
|
485
|
+
guard arguments.count >= 3 else { fail("usage: simulator-host serve|stream <udid> ...") }
|
|
486
|
+
switch arguments[1] {
|
|
487
|
+
case "serve":
|
|
488
|
+
await serve(arguments[2])
|
|
489
|
+
case "stream":
|
|
490
|
+
guard arguments.count == 6, let fps = Int(arguments[3]), let maxPixels = Double(arguments[4]), let kbps = Int(arguments[5]) else {
|
|
491
|
+
fail("usage: simulator-host stream <udid> <fps> <max pixels> <kbps>")
|
|
492
|
+
}
|
|
493
|
+
await stream(arguments[2], fps: fps, maxPixels: maxPixels, kbps: kbps)
|
|
494
|
+
default:
|
|
495
|
+
fail("usage: simulator-host serve|stream <udid> ...")
|
|
496
|
+
}
|
|
497
|
+
`;var Ma=process.arch==="arm64"?"arm64-apple-macos":"x86_64-apple-macos",pd=180000,md=15000,fd=30000,hd=600000,gd=["SimDevice","SimDeviceSet","SimDeviceType","SimRuntime"].map((e)=>`@interface ${e} : NSObject
|
|
498
|
+
@end
|
|
499
|
+
`).join("");function $a(e,l,c){return new Promise((p)=>{let m=Io(e,l,{stdio:["ignore","pipe","pipe"],timeout:c}),f="";m.stdout.on("data",(h)=>{f+=h}),m.stderr.on("data",(h)=>{f+=h}),m.once("error",(h)=>p({code:-1,output:String(h)})),m.once("close",(h)=>p({code:h??-1,output:f}))})}var Ba=new Map;function To(e){let l=re(Fa(e),"Frameworks"),c=Ba.get(l);if(!c)Ba.set(l,c=_d(l));return c}async function _d(e){if(process.platform!=="darwin"||!Oo(re(e,"FBSimulatorControl.framework")))return null;let l=await $a("xcrun",["swiftc","--version"],30000);if(l.code!==0)return null;let c=ad("sha256").update(Po).update(l.output).update(e).digest("hex").slice(0,16),p=re(ud(),".local","share","reason","simulator","host"),m=re(p,c,"simulator-host");if(Oo(m))return m;Xr(p,{recursive:!0,mode:448});let f=ld(re(p,".staging-"));try{let h=re(f,"Frameworks"),y=re(h,"FBSimulatorControl.framework"),S=re(y,"Modules","FBSimulatorControl.swiftmodule");Xr(S,{recursive:!0});for(let M of Ta(e))if(M!=="FBSimulatorControl.framework")Ao(re(e,M),re(h,M));let w=re(e,"FBSimulatorControl.framework");Ao(re(w,"FBSimulatorControl"),re(y,"FBSimulatorControl")),Ao(re(w,"Headers"),re(y,"Headers")),or(re(y,"Modules","module.modulemap"),Da(re(w,"Modules","module.modulemap")));let g=Da(re(w,"Modules","FBSimulatorControl.swiftmodule",`${Ma}.swiftinterface`),"utf8");or(re(S,`${Ma}.swiftinterface`),g.replace(/FBSimulatorControl\.(?=[A-Za-z_])/g,"").replace(/IOSurface\.IOSurface/g,"IOSurface"));let v=re(f,"include","CoreSimulator");Xr(v,{recursive:!0}),or(re(v,"module.modulemap"),`module CoreSimulator {
|
|
500
|
+
header "CoreSimulator.h"
|
|
501
|
+
export *
|
|
502
|
+
}
|
|
503
|
+
`),or(re(v,"CoreSimulator.h"),`#import <Foundation/Foundation.h>
|
|
504
|
+
${gd}`);let C=re(f,"main.swift");or(C,Po);let A=re(f,"simulator-host"),I=await $a("xcrun",["swiftc","-O","-F",h,"-I",re(f,"include"),"-module-cache-path",re(f,"cache"),"-Xlinker","-rpath","-Xlinker",e,C,"-o",A],pd);if(I.code!==0||!Oo(A))return process.stderr.write(`Reason: the simulator host did not build; simulator actions use AXe.
|
|
505
|
+
${I.output.slice(-2000)}
|
|
506
|
+
`),null;Xr(Fa(m),{recursive:!0}),cd(A,m);for(let M of Ta(p))if(M!==c&&!M.startsWith(".staging-"))Na(re(p,M),{recursive:!0,force:!0});return m}catch{return null}finally{Na(f,{recursive:!0,force:!0})}}class sr extends Error{}class Ct extends Error{}class Ua{child;onGone;nextId=1;pending=new Map;idle;gone=!1;constructor(e,l){this.child=e;this.onGone=l;dd({input:e.stdout}).on("line",(p)=>{let m;try{m=JSON.parse(p)}catch{return}let f=this.pending.get(Number(m.id));if(!f)return;if(this.pending.delete(Number(m.id)),clearTimeout(f.timer),m.ok===!0)f.resolve(m);else f.reject(new sr(String(m.error??"The simulator refused the action.")))}),e.once("exit",()=>this.end()),e.once("error",()=>this.end()),this.touch()}call(e){if(this.gone)return Promise.reject(new Ct("The simulator host has exited."));this.touch();let l=this.nextId++;return new Promise((c,p)=>{let m=setTimeout(()=>{this.pending.delete(l),p(new Ct("The simulator host did not answer.")),this.close()},fd);this.pending.set(l,{resolve:c,reject:p,timer:m}),this.child.stdin.write(`${JSON.stringify({id:l,...e})}
|
|
507
|
+
`)})}close(){if(this.child.exitCode===null&&this.child.signalCode===null)this.child.kill("SIGTERM");this.end()}touch(){clearTimeout(this.idle),this.idle=setTimeout(()=>this.close(),hd),this.idle.unref?.()}end(){if(this.gone)return;this.gone=!0,clearTimeout(this.idle);for(let e of this.pending.values())clearTimeout(e.timer),e.reject(new Ct("The simulator host has exited."));this.pending.clear(),this.onGone()}}var Et=new Map;async function Jr(e,l,c=!1){let p=Et.get(l);if(!p){let m={started:yd(e,l)};Et.set(l,p=m),m.started.then((f)=>{if(m.host=f,!f&&Et.get(l)===m)Et.delete(l)})}if(p.host!==void 0)return p.host;return c?p.started:null}async function yd(e,l){let c=await To(e);if(!c)return null;let p=Io(c,["serve",l],{stdio:["pipe","pipe","ignore"]});if(!await new Promise((h)=>{let y=setTimeout(()=>h(!1),md);p.stdout.once("data",(S)=>{clearTimeout(y),h(String(S).includes('"ready":true'))}),p.once("exit",()=>{clearTimeout(y),h(!1)}),p.once("error",()=>{clearTimeout(y),h(!1)})})){if(p.exitCode===null)p.kill("SIGTERM");return null}let f=new Ua(p,()=>{let h=Et.get(l);if(h&&(h.host===f||h.host===void 0))Et.delete(l)});return f}function Ha(e,l,c,p,m){return Io(e,["stream",l,String(c),String(Math.round(p)),String(m)],{stdio:["pipe","pipe","ignore"]})}var Pt={version:"1.8.0",url:"https://github.com/cameroncooke/AXe/releases/download/v1.8.0/AXe-macOS-v1.8.0-universal.tar.gz",sha256:"7b76340b72e90d0f211bc7c4636f15009076eff07acef2f2b632b175debd8834"},Rd=50000,xd=112640,Ed=174080,Do=2,Cd=60000,Pd=2000,Od=300,Ad=40,Id=new Set(["file:","javascript:","data:","vbscript:","blob:"]);function kt(e,l,c={}){return new Promise((p,m)=>{let f=Xo(e,l,{cwd:c.cwd,stdio:["ignore","pipe","pipe"],signal:c.signal}),h=[],y=[];f.stdout.on("data",(w)=>h.push(w)),f.stderr.on("data",(w)=>y.push(w));let S=setTimeout(()=>f.kill("SIGKILL"),c.timeoutMs??Rd);f.on("error",(w)=>{clearTimeout(S),m(w)}),f.on("close",(w)=>{clearTimeout(S),p({code:w??-1,stdout:Buffer.concat(h).toString("utf8"),stderr:Buffer.concat(y).toString("utf8")})})})}function te(e,l){throw new r(e,l)}async function ve(e,l,c,p={}){let m=await kt(e,l,p);if(m.code!==0)te("simulator_command_failed",`${c} failed: ${(m.stderr||m.stdout).trim().slice(-1500)}`);return m.stdout}function lr(){return process.platform==="darwin"&&je("/Library/Developer/PrivateFrameworks/CoreSimulator.framework")&&je("/usr/bin/xcrun")}var $o=null;function pt(){return J(ei(),".local","share","reason","simulator","axe")}function ri(){let e=J(pt(),Pt.version,"axe");if(je(e))return Promise.resolve(e);return $o??=(async()=>{Ho(pt(),{recursive:!0,mode:448});let l=Zo(J(pt(),".staging-"));try{let c=J(l,"axe.tgz");await co(Pt.url,Pt.sha256,c);let p=J(l,"tree");if(Ho(p),await ve("tar",["-xzf",c,"-C",p],"Extracting AXe"),!je(J(p,"axe"))||!je(J(p,"Frameworks")))te("simulator_axe_missing","The AXe archive has an unexpected layout.");ar(J(pt(),Pt.version),{recursive:!0,force:!0}),Sd(p,J(pt(),Pt.version));for(let m of nn(pt()))if(m!==Pt.version&&!m.startsWith(".staging-"))ar(J(pt(),m),{recursive:!0,force:!0});return e}finally{ar(l,{recursive:!0,force:!0}),$o=null}})(),$o}var Qa=ri;async function el(e){let l=await ri().catch(()=>null);return l?Jr(l,e.udid).catch(()=>null):null}async function Qr(e,l,c){let p=await ri().catch(()=>te("simulator_axe_missing","AXe could not be installed on this Mac.")),m=await kt(p,[...e,"--udid",l]);if(m.code===0)return m.stdout;let f=(m.stderr||m.stdout).trim();if(/no (matching |accessibility )?element|element not found|could not find|no elements? match/i.test(f))te("simulator_element_not_found",f.slice(-500));return te("simulator_command_failed",`${c} failed: ${f.slice(-1500)}`)}function Ld(e){let l=e.match(/SimRuntime\.([A-Za-z]+)-(\d+)-(\d+)(?:-(\d+))?$/);return l?`${l[1]} ${l[2]}.${l[3]}${l[4]?`.${l[4]}`:""}`:e}function kd(e){switch(e){case"Booted":return"booted";case"Booting":return"booting";case"Shutting Down":return"shutting_down";default:return"shutdown"}}async function Ri(){let l=JSON.parse(await ve("xcrun",["simctl","list","devices","available","-j"],"Listing simulators")).devices??{},c=[];for(let[p,m]of Object.entries(l)){if(!p.includes("SimRuntime.iOS"))continue;for(let f of m){if(f.isAvailable===!1)continue;let h=f.name.toLowerCase();if(f.deviceTypeIdentifier)zo.set(f.udid,f.deviceTypeIdentifier);c.push({udid:f.udid,name:f.name,runtime:Ld(p),state:kd(f.state),kind:h.includes("iphone")?"iphone":h.includes("ipad")?"ipad":"other"})}}return c.sort((p,m)=>Number(m.state==="booted")-Number(p.state==="booted")||m.runtime.localeCompare(p.runtime,void 0,{numeric:!0})||p.name.localeCompare(m.name))}var zo=new Map,Yo=null;async function Ie(e,l){let c=await Ri(),p;if(e){let m=c.filter((f)=>f.udid===e||f.name===e);if(p=m.find((f)=>f.state==="booted")??m[0],!p)te("simulator_device_not_found",`No simulator named "${e}". Call devices to list them.`)}else{let m=c.filter((f)=>f.state==="booted");if(p=m.find((f)=>f.udid===Yo)??m.find((f)=>f.kind==="iphone")??m[0],!p)te("simulator_not_booted","No simulator is booted. Call devices, then boot one.")}if(l.booted&&p.state!=="booted")te("simulator_not_booted",`${p.name} is not booted. Boot it first.`);return Yo=p.udid,p}function ce(e){return`${e.name} (${e.runtime})`}async function Td(e){if(e.state!=="booted"){let l=await kt("xcrun",["simctl","boot",e.udid]);if(l.code!==0&&!/current state: Booted/i.test(l.stderr))te("simulator_command_failed",`Booting ${e.name} failed: ${l.stderr.trim().slice(-1000)}`);await ve("xcrun",["simctl","bootstatus",e.udid,"-b"],`Waiting for ${e.name} to boot`,{timeoutMs:45000})}return Yo=e.udid,{...e,state:"booted"}}function Pi(e,l){let c=qo(e,l),p=Ja(e,c);if(p.startsWith("..")||p.startsWith(Za)||qo(e,p)!==c)te("simulator_path_outside_root",`${l} is outside this machine's granted folder (${e}). Pass a path inside it, or one relative to it.`);return c}var ja=4,Dd=new Set(["node_modules","Pods","DerivedData","build","Carthage","vendor"]);function Nd(e){let l=[],c=(p,m)=>{let f;try{f=nn(p)}catch{return}if(f.includes("project.yml")||f.some((h)=>h.endsWith(".xcworkspace")||h.endsWith(".xcodeproj"))){l.push(p);return}if(m>=ja)return;for(let h of f.sort()){if(h.startsWith(".")||Dd.has(h))continue;let y=J(p,h);try{if(Zr(y).isDirectory())c(y,m+1)}catch{}}};if(c(e,0),l.length===1)return l[0];if(!l.length)te("simulator_project_not_found",`No Xcode project or project.yml within ${ja} folders of ${e}; pass path.`);return te("simulator_project_not_found",`${e} holds several Xcode projects; pass path as one of: ${l.map((p)=>Ja(e,p)||".").join(", ")}.`)}var It=new Map;async function Md(e){if(e.endsWith(".xcworkspace"))return{flag:"-workspace",path:e,dir:jo(e)};if(e.endsWith(".xcodeproj"))return{flag:"-project",path:e,dir:jo(e)};if(!Zr(e).isDirectory())te("simulator_project_not_found",`${e} is not a project, workspace or folder.`);let l=(m)=>nn(e).filter((f)=>f.endsWith(m)).sort();if(je(J(e,"project.yml")))await ve("xcodegen",["generate","--quiet"],"xcodegen generate",{cwd:e,timeoutMs:45000}).catch((m)=>je("/opt/homebrew/bin/xcodegen")?ve("/opt/homebrew/bin/xcodegen",["generate","--quiet"],"xcodegen generate",{cwd:e,timeoutMs:45000}):Promise.reject(m));let c=l(".xcworkspace")[0];if(c)return{flag:"-workspace",path:J(e,c),dir:e};let p=l(".xcodeproj")[0];if(p)return{flag:"-project",path:J(e,p),dir:e};return te("simulator_project_not_found",`No .xcodeproj or .xcworkspace in ${e}.`)}async function tl(e){let l=JSON.parse(await ve("xcodebuild",["-list","-json",e.flag,e.path],"Listing schemes"));return l.workspace?.schemes??l.project?.schemes??[]}async function $d(e){let l=(await tl(e))[0];if(!l)te("simulator_build_no_scheme",`${e.path} has no schemes; pass scheme.`);return l}function Bd(e){let l=[],c=new Set;return e.forEach((p,m)=>{if(l.length>=20||!/(^|\s)error: /.test(p)||p.startsWith("note:")||c.has(p))return;c.add(p);let f=e.slice(m+1,m+3).filter((h)=>h.trim()!==""&&!/(^|\s)(error|warning|note): /.test(h));l.push([p,...f].join(`
|
|
508
|
+
`).slice(0,800))}),l}async function Fd(e,l,c){if(e.ended=Date.now(),l!==0){if(e.log.some((f)=>f.includes("does not contain a scheme named"))){let f=await tl(c).catch(()=>[]);if(f.length)e.log.push(`error: this project's schemes are: ${f.join(", ")}`)}e.status="failed";return}let p=J(e.productsDir,`${e.configuration}-iphonesimulator`),m=je(p)?nn(p).filter((f)=>f.endsWith(".app")).map((f)=>J(p,f)).sort((f,h)=>Zr(h).mtimeMs-Zr(f).mtimeMs):[];if(e.appPath=m[0],e.appPath)e.bundleId=await ol(e.appPath).catch(()=>{return});if(e.status=e.appPath?"succeeded":"failed",!e.appPath)e.log.push("error: the build succeeded but produced no .app for the iOS Simulator")}async function qa(e,l){let c=e.path?Pi(l,e.path):Nd(l),p=await Md(c),m=e.scheme??await $d(p),f=e.configuration??"Debug",h=await Ie(e.device,{booted:!1}).catch(()=>null),y=h?`platform=iOS Simulator,id=${h.udid}`:"generic/platform=iOS Simulator",S=bd("sha256").update(p.path).digest("hex").slice(0,16),w=J(ei(),"Library","Caches","reason","simulator-builds",S),g={id:`build-${wd().slice(0,8)}`,status:"running",started:Date.now(),log:[],productsDir:J(w,"Build","Products"),configuration:f};It.set(g.id,g);for(let[I,M]of It)if(It.size>20&&M.status!=="running")It.delete(I);let v=Xo("xcodebuild",[p.flag,p.path,"-scheme",m,"-configuration",f,"-destination",y,"-derivedDataPath",w,"-skipMacroValidation","build"],{cwd:p.dir,stdio:["ignore","pipe","pipe"]}),C="",A=(I)=>{let M=(C+I.toString("utf8")).split(`
|
|
509
|
+
`);if(C=M.pop()??"",g.log.push(...M),g.log.length>5000)g.log.splice(0,g.log.length-5000)};return v.stdout.on("data",A),v.stderr.on("data",A),v.on("error",(I)=>{g.log.push(`error: ${I.message}`),g.status="failed",g.ended=Date.now()}),v.on("close",(I)=>{if(C)g.log.push(C);Fd(g,I??-1,p)}),{text:`Build ${g.id} started: ${m} (${f}) for ${h?ce(h):"the iOS Simulator"}. Poll build_status with this build_id; a first build can take minutes, later ones are incremental.`,build:rl(g)}}function rl(e){return{id:e.id,status:e.status,errors:Bd(e.log),log_tail:e.log.slice(-Ad).join(`
|
|
510
|
+
`).slice(-4000),elapsed_ms:(e.ended??Date.now())-e.started,...e.appPath?{app_path:e.appPath}:{},...e.bundleId?{bundle_id:e.bundleId}:{}}}var Ud=45000,Hd=30000;async function Bo(e,l=Ud){let c=Date.now()+l;while(It.get(e)?.status==="running"&&Date.now()<c)await Bun.sleep(500);let p=nl(e);return p.build?.status==="running"?{...p,text:`${p.text} Still running: call build_status with wait again.`}:p}function nl(e){let l=It.get(e);if(!l)te("simulator_build_not_found",`No build ${e} on this Mac (a worker restart forgets builds); start a new one.`);let c=rl(l);return{text:l.status==="running"?`Build ${e} is running (${Math.round(c.elapsed_ms/1000)} s).`:l.status==="succeeded"?`Build ${e} succeeded: ${l.appPath}. Launch it with app_path.`:`Build ${e} failed with ${c.errors.length} error(s).`,build:c}}async function ol(e){return(await ve("plutil",["-extract","CFBundleIdentifier","raw","-o","-",J(e,"Info.plist")],"Reading the bundle id")).trim()}var ot=new Map;function jd(e,l){ot.get(e.udid)?.stop();let c=Xo("script",["-q","/dev/null","xcrun","simctl","launch","--console-pty","--terminate-running-process",e.udid,l],{stdio:["ignore","pipe","pipe"]}),p={udid:e.udid,bundleId:l,lines:[],first:0,stop:()=>c.kill("SIGTERM")};ot.set(e.udid,p);let m="",f=(h)=>{let y=(m+h.toString("utf8").replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\r]/g,"")).split(`
|
|
511
|
+
`);m=y.pop()??"",p.lines.push(...y);let S=p.lines.length-Pd;if(S>0)p.lines.splice(0,S),p.first+=S};return c.stdout.on("data",f),c.stderr.on("data",f),new Promise((h)=>{let y=setTimeout(()=>h(null),15000),S=()=>{let w=p.lines.concat(m).join(`
|
|
512
|
+
`).match(new RegExp(`${l.replace(/\./g,"\\.")}: (\\d+)`))?.[1];if(w)clearTimeout(y),h(Number(w))};c.stdout.on("data",S),c.on("close",()=>{clearTimeout(y),h(null)})})}async function qd(e,l){let c=await Ie(e.device,{booted:!0}),p=e.bundle_id;if(e.app_path){let f=Wd(l,e.app_path);await ve("xcrun",["simctl","install",c.udid,f],`Installing ${Xa(f)}`),p=await ol(f)}if(e.bundle_id){if((await kt("xcrun",["simctl","get_app_container",c.udid,e.bundle_id])).code!==0)te("simulator_app_not_installed",`${e.bundle_id} is not installed on ${ce(c)}.`)}let m=await jd(c,p);if(m===null){let f=ot.get(c.udid)?.lines.slice(-20).join(`
|
|
513
|
+
`)??"";te("simulator_launch_failed",`${p} did not start on ${ce(c)}.${f?`
|
|
514
|
+
${f}`:""}`)}return{text:`Launched ${p} on ${ce(c)} (pid ${m}). Its console is captured; read it with logs.`,device:c}}function Wd(e,l){let c=qo(l),p=J(ei(),"Library","Caches","reason","simulator-builds")+Za;return c.startsWith(p)&&c.endsWith(".app")?c:Pi(e,c)}function Gd(e,l){let c=ot.get(e.udid);if(!c)return{text:`No app launched by Reason is running on ${ce(e)}; launch one to capture its capture.`,logs:{lines:[],next:0}};let p=Math.max(l??0,c.first,c.first+c.lines.length-Od),m=c.lines.slice(p-c.first).map((f)=>f.slice(0,2000));return{text:`${m.length} console line(s) from ${c.bundleId} on ${ce(e)}.`,logs:{lines:m,next:c.first+c.lines.length}}}var en=new Map;function Wa(e,...l){let c=en.get(e.udid);if(!c)return;for(let[p,m]of l)if(p>c.width||m>c.height)te("simulator_point_off_screen",`(${p}, ${m}) is off ${e.name}'s ${c.width}x${c.height}-point screen.`)}function Ga(e,l){if(e.kind==="ipad")return 2;return l===750||l===828||l===640?2:3}async function Oi(e,l=1,c){let p=Zo(J(Ya(),"reason-sim-"));try{let m=J(p,"screen.png");if(await ve("xcrun",["simctl","io",e.udid,"screenshot","--type=png",m],"Taking a screenshot"),c){Ho(jo(c),{recursive:!0});let A=await ve("sips",["-g","pixelWidth","-g","pixelHeight",m],"Reading the screenshot size"),I=Number(A.match(/pixelWidth: (\d+)/)?.[1]),M=Number(A.match(/pixelHeight: (\d+)/)?.[1]),N=2/Ga(e,I);await ve("sips",["-z",String(Math.round(M*N)),String(Math.round(I*N)),m,"--out",c],"Saving the screenshot")}let f=await ve("sips",["-g","pixelWidth","-g","pixelHeight",m],"Reading the screenshot size"),h=Number(f.match(/pixelWidth: (\d+)/)?.[1]),y=Number(f.match(/pixelHeight: (\d+)/)?.[1]),S=Ga(e,h),w=Math.round(h/S),g=Math.round(y/S);en.set(e.udid,{width:w,height:g});let v=Buffer.alloc(0),C=l===2?Ed:xd;for(let A of[70,50,35]){let I=J(p,`screen-${A}.jpg`);if(await ve("sips",["-z",String(g*l),String(w*l),"-s","format","jpeg","-s","formatOptions",String(A),m,"--out",I],"Encoding the screenshot"),v=Qo(I),v.byteLength<=C)break}return{text:`Screenshot of ${ce(e)} at ${w}x${g} points: image pixels are tap coordinates.`+(c?` Saved at ${c}.`:""),device:e,image:{mime:"image/jpeg",data:v.toString("base64"),width:w,height:g}}}finally{ar(p,{recursive:!0,force:!0})}}async function zd(e){let l=await el(e);if(l)try{return String((await l.call({op:"tree"})).tree)}catch{}return Qr(["describe-ui"],e.udid,"Reading the accessibility tree")}async function tn(e){let l=JSON.parse(await zd(e)),c={lines:[],compact:[],ids:new Set,labels:new Set,targets:[]},p=(m,f,h="")=>{let y=(m.role??m.type??"?").replace(/^AX/,""),S=m.AXLabel||m.title||"",w=m.AXValue?` value="${String(m.AXValue).slice(0,120)}"`:"",g=m.AXUniqueId?` id=${m.AXUniqueId}`:"";if(m.AXUniqueId)c.ids.add(m.AXUniqueId);if(S)c.labels.add(S);let v=m.frame;if(y==="Application"&&v&&!c.bounds)c.bounds={width:v.width,height:v.height};if(v&&v.width>0&&v.height>0&&(m.AXUniqueId||m.AXLabel))c.targets.push({...m.AXUniqueId?{id:m.AXUniqueId.trim()}:{},...m.AXLabel?{label:m.AXLabel.trim()}:{},role:y,frame:v});let C=Boolean(S||g||w||!["Group","Other"].includes(y));if(C){let A=`${" ".repeat(Math.min(f,12))}${y} "${S.slice(0,160)}"${g}${w}`+(v?` (${Math.round(v.x)},${Math.round(v.y)} ${Math.round(v.width)}x${Math.round(v.height)})`:"")+(m.enabled===!1?" disabled":"");c.lines.push(A);let I=y==="Image"&&!g,M=(y==="StaticText"||y==="Image")&&!g&&S!==""&&h.includes(S);if(!I&&!M)c.compact.push(A)}for(let A of m.children??[])p(A,C?f+1:f,S||h)};for(let m of l)p(m,0);return c}function il(e,l,c=!1){let p=(c?e.compact:e.lines).join(`
|
|
515
|
+
`);return p.length>l?`${p.slice(0,l)}
|
|
516
|
+
\u2026 (truncated)`:p}async function Vd(e){let l=await tn(e);return{text:`Accessibility tree of ${ce(e)} (frames in points; tap by id or label):
|
|
517
|
+
${il(l,Cd)}`,device:e}}var Kd=450,Yd=1e4;function Xd(e,l){let c=l.id?e.ids.has(l.id):[...e.labels].some((p)=>p===l.label||p.includes(l.label));return l.gone?!c:c}async function mt(e,l,c){let p=l.observe??"tree";if(p==="none"&&!l.wait_for)return c;let m=null,f="";if(l.wait_for){let y=Date.now()+(l.timeout??5)*1000,S=l.wait_for,w=S.id?`id ${S.id}`:`"${S.label}"`;for(;;){if(m=await tn(e),Xd(m,S)){f=` ${w} is ${S.gone?"gone":"on screen"}.`;break}if(Date.now()>=y){f=S.gone?` Waited ${l.timeout??5} s: ${w} is still on screen.`:` Waited ${l.timeout??5} s: ${w} is not in the visible accessibility tree. Lists only build their visible rows, so check the screen below: it may be open with that element further down (scroll to it), or wait for something at its top.`;break}await Bun.sleep(250)}}else await Bun.sleep(Kd);let h={...c,text:`${c.text}${f}`};if(p==="tree"||p==="both")m??=await tn(e),h.screen=il(m,Yd,!0),h.text+=`
|
|
518
|
+
Screen now:
|
|
519
|
+
${h.screen}`;if(p==="screenshot"||p==="both"){let y=await Oi(e);h.image=y.image}return h}function za(e){return`'${e.replace(/'/g,"'\\''")}'`}function Jd(e){switch(e.action){case"tap":if(e.x!==void 0&&e.y!==void 0)return e.duration?`touch -x ${e.x} -y ${e.y} --down --up --delay ${e.duration}`:`tap -x ${e.x} -y ${e.y}`;return e.id?`tap --id ${za(e.id)}`:`tap --label ${za(e.label)}`;case"swipe":return`swipe --start-x ${e.x} --start-y ${e.y} --end-x ${e.x2} --end-y ${e.y2} --duration ${e.duration??0.3}`;case"button":return`button ${e.name.replace("_","-")}`;case"sleep":return`sleep ${e.seconds}`}}var sl=0.35,Zd=new Set(["Button","Link","Cell","MenuItem","Switch","Toggle","CheckBox","PopUpButton","TextField","SecureTextField","SearchField","TextArea","Slider","Tab","RadioButton"]);function Qd(e,l){let c=e.targets.filter((w)=>l.id!==void 0?w.id===l.id.trim():w.label===l.label?.trim()),p=(w)=>({x:w.frame.x+w.frame.width/2,y:w.frame.y+w.frame.height/2}),m=e.bounds,f=m?c.filter((w)=>{let{x:g,y:v}=p(w);return g>=0&&v>=0&&g<=m.width&&v<=m.height}):c,h=f.length?f:c,y=h.filter((w)=>Zd.has(w.role)),S=(y.length?y:h)[0];return S?p(S):null}async function ep(e,l,c,p,m){let f=Date.now()+c*1000;for(;;){let h=Qd(await tn(e),l);if(h)return h;if(Date.now()>=f){let y=l.id!==void 0?`--id '${l.id}'`:`--label '${l.label}'`;return te("simulator_element_not_found",`Error: Step ${p} failed: [tap]
|
|
520
|
+
No accessibility element matched ${y}. Make sure the app is on the expected screen, then inspect it and prefer an id when there is one.
|
|
521
|
+
(${p-1} of ${m} steps had completed.)`)}await Bun.sleep(250)}}async function At(e,l,c){let p=await el(e);if(!p)return Va(e,l,c);for(let[m,f]of l.entries()){try{switch(f.action){case"tap":{let y=f.x!==void 0&&f.y!==void 0?{x:f.x,y:f.y}:await ep(e,f,c,m+1,l.length);await p.call(f.duration?{op:"tap",...y,duration:f.duration}:{op:"tap",...y});break}case"swipe":await p.call({op:"swipe",x:f.x,y:f.y,x2:f.x2,y2:f.y2,duration:f.duration??0.3});break;case"button":await p.call({op:"button",name:f.name});break;case"type":await p.call({op:"text",text:f.text}).catch((y)=>y instanceof sr?Qr(["type",f.text],e.udid,`Step ${m+1} (typing)`):Promise.reject(y));break;case"sleep":await Bun.sleep(f.seconds*1000);break}}catch(y){if(y instanceof Ct)return await Va(e,l.slice(m),c),`Ran ${l.length} step(s) on ${ce(e)}.`;if(y instanceof sr)te("simulator_command_failed",`Step ${m+1} failed: ${y.message}
|
|
522
|
+
(${m} of ${l.length} steps had completed.)`);throw y}let h=l[m+1];if(f.action!=="sleep"&&h&&h.action!=="sleep")await Bun.sleep(sl*1000)}return`Ran ${l.length} step(s) on ${ce(e)}.`}async function Va(e,l,c){let p=[],m=[],f=0,h=0,y=async()=>{if(p.length===0)return;let S=["batch","--ax-cache","perStep","--wait-timeout",String(c)];for(let w of p)S.push("--step",w);try{await Qr(S,e.udid,`Steps ${h+1}-${h+f}`)}catch(w){if(w instanceof r){let g=w.message.replace(/Step (\d+) failed/,(v,C)=>{let A=m[Number(C)-1];return A?`Step ${A} failed`:v});te(w.code,`${g}
|
|
523
|
+
(${h} of ${l.length} steps had completed before this batch.)`)}throw w}h+=f,p=[],m=[],f=0};for(let[S,w]of l.entries()){if(w.action==="type"){await y(),await Qr(["type",w.text],e.udid,`Step ${h+1} (typing)`),h+=1;continue}p.push(Jd(w)),f+=1,m.push(S+1);let g=l[S+1];if(w.action!=="sleep"&&g&&g.action!=="sleep")p.push(`sleep ${sl}`),m.push(S+1)}return await y(),`Ran ${l.length} step(s) on ${ce(e)}.`}var tp=["topLeft","top","topRight","right","bottomRight","bottom","bottomLeft","left"],Ka=new Map,rp=`ObjC.import("AppKit");
|
|
524
|
+
function run(argv) {
|
|
525
|
+
const [input, output, width, height] = argv;
|
|
526
|
+
const w = Number(width), h = Number(height);
|
|
527
|
+
const image = $.NSImage.alloc.initWithContentsOfFile(input);
|
|
528
|
+
const rep = $.NSBitmapImageRep.alloc.initWithBitmapDataPlanesPixelsWidePixelsHighBitsPerSampleSamplesPerPixelHasAlphaIsPlanarColorSpaceNameBytesPerRowBitsPerPixel(
|
|
529
|
+
null, w, h, 8, 4, true, false, $.NSDeviceRGBColorSpace, 0, 0);
|
|
530
|
+
$.NSGraphicsContext.saveGraphicsState;
|
|
531
|
+
$.NSGraphicsContext.setCurrentContext($.NSGraphicsContext.graphicsContextWithBitmapImageRep(rep));
|
|
532
|
+
image.drawInRectFromRectOperationFraction($.NSMakeRect(0, 0, w, h), $.NSZeroRect, $.NSCompositingOperationCopy, 1);
|
|
533
|
+
$.NSGraphicsContext.restoreGraphicsState;
|
|
534
|
+
rep.representationUsingTypeProperties($.NSBitmapImageFileTypePNG, $()).writeToFileAtomically(output, true);
|
|
535
|
+
}`;async function Uo(e,l,c){let p=await ve("sips",["-g","pixelWidth","-g","pixelHeight",e],"Reading the frame size"),m=Number(p.match(/pixelWidth: ([\d.]+)/)?.[1]),f=Number(p.match(/pixelHeight: ([\d.]+)/)?.[1]);if(c!==void 0)m=m*c/f,f=c;let h=Zo(J(Ya(),"reason-chrome-"));try{let y=J(h,"render.js"),S=J(h,"out.png");if(vd(y,rp),await ve("osascript",["-l","JavaScript",y,e,S,String(Math.max(1,Math.round(m*l))),String(Math.max(1,Math.round(f*l)))],"Rendering the frame"),!je(S))te("simulator_command_failed",`Rendering ${Xa(e)} produced no image.`);return{image:Qo(S).toString("base64"),width:m,height:f}}finally{ar(h,{recursive:!0,force:!0})}}async function np(e){if(!zo.has(e.udid))await Ri();let l=zo.get(e.udid),p=JSON.parse(await ve("xcrun",["simctl","list","devicetypes","-j"],"Listing device types")).devicetypes?.find((m)=>m.identifier===l)?.bundlePath;if(!p)te("simulator_command_failed",`No device type bundle for ${e.name}.`);return p}async function op(e){let l=await np(e),c=en.get(e.udid)??(e.state==="booted"?(await Oi(e),en.get(e.udid)):void 0);if(!c)te("simulator_not_booted",`${e.name} is not booted.`);let p=Ka.get(l);if(p)return{text:`Frame of ${ce(e)}.`,device:e,chrome:p};let m=J(l,"Contents","Resources"),f=JSON.parse(await ve("plutil",["-convert","json","-o","-",J(m,"profile.plist")],"Reading the device profile")),h=f.framebufferMask?J(m,`${f.framebufferMask}.pdf`):null,y=h&&je(h)?await Uo(h,Do,c.height):null,S=f.chromeIdentifier?.split(".").pop(),w=S?J("/Library/Developer/DeviceKit/Chrome",`${S}.devicechrome`,"Contents","Resources"):"";if(!S||!je(J(w,"chrome.json")))te("simulator_command_failed",`${e.name} has no device frame in this Xcode.`);let g=JSON.parse(Qo(J(w,"chrome.json"),"utf8")),v={};for(let B of tp){let F=g.images[B];if(!F)te("simulator_command_failed",`${e.name}'s frame has no ${B} piece.`);v[B]=await Uo(J(w,`${F}.pdf`),Do)}let{sizing:C}=g.images,A={top:C.topHeight,left:C.leftWidth,bottom:C.bottomHeight,right:C.rightWidth},I=c.width+A.left+A.right,M=c.height+A.top+A.bottom,N=[];for(let B of g.inputs??[]){let F=J(w,`${B.image}.pdf`);if(!je(F))continue;let H=await Uo(F,Do),{x:ne,y:_e}=B.offsets.normal,xe=(st,he,Ir)=>st<0?he+st-Ir:st,Qe=B.anchor==="left"?{x:ne-H.width,y:xe(_e,M,H.height)}:B.anchor==="right"?{x:I+ne,y:xe(_e,M,H.height)}:B.anchor==="top"?{x:xe(ne,I,H.width),y:_e-H.height}:{x:xe(ne,I,H.width),y:M+_e};N.push({name:B.name,image:H.image,...Qe,width:H.width,height:H.height})}let L={identifier:g.identifier,screen:{width:c.width,height:c.height},inset:A,padding:g.images.devicePadding??{top:0,left:0,bottom:0,right:0},pieces:v,buttons:N,...y?{screen_mask:y.image}:{}};return Ka.set(l,L),{text:`Frame of ${ce(e)}.`,device:e,chrome:L}}var ip=new Set(["simulator_command_failed","simulator_launch_failed","simulator_point_off_screen","simulator_build_no_scheme","simulator_element_not_found","simulator_path_outside_root","simulator_project_not_found"]);async function cr(e){try{return await al(e)}catch(l){if(l instanceof r&&ip.has(l.code))return{text:l.message,error:l.code};throw l}}async function al(e){if(!lr())te("simulator_xcode_missing","Xcode's iOS Simulator is not available on this Mac.");let l=Ro.safeParse(e.payload);if(!l.success)te("simulator_invalid_request",l.error.issues.map((p)=>p.message).join("; "));let c=l.data;switch(c.action){case"devices":{let p=await Ri(),m=p.filter((f)=>f.state==="booted");return{text:`${m.length} booted (${m.map(ce).join(", ")||"none"}), ${p.length} available.`,devices:p}}case"boot":{let p=await Td(await Ie(c.device,{booted:!1}));return{text:`${ce(p)} is booted.`,device:p}}case"shutdown":{let p=await Ie(c.device,{booted:!1});ot.get(p.udid)?.stop(),ot.delete(p.udid);let m=await kt("xcrun",["simctl","shutdown",p.udid]);if(m.code!==0&&!/current state: Shutdown/i.test(m.stderr))te("simulator_command_failed",m.stderr.trim().slice(-1000));return{text:`${ce(p)} is shut down.`,device:{...p,state:"shutdown"}}}case"build":{let p=await qa(c,e.root);return c.wait&&p.build?Bo(p.build.id):p}case"build_status":return c.wait?Bo(c.build_id):nl(c.build_id);case"run":{let p=await qa({...c,action:"build"},e.root),m=await Bo(p.build.id,Hd);if(m.build?.status!=="succeeded"||!m.build.app_path)return m;let f=await al({root:e.root,payload:{action:"launch",app_path:m.build.app_path,...c.device?{device:c.device}:{},...c.steps?{steps:c.steps}:{},...c.observe?{observe:c.observe}:{},...c.wait_for?{wait_for:c.wait_for}:{},...c.timeout!==void 0?{timeout:c.timeout}:{}}});return{...f,text:`Built in ${Math.round(m.build.elapsed_ms/1000)} s. ${f.text}`,build:m.build}}case"launch":{let p=await qd(c,e.root);if(!p.device)return p;if(c.steps?.length)p.text+=` ${await At(p.device,c.steps,c.timeout??8)}`;else if(!c.wait_for)await Bun.sleep(1000);return mt(p.device,c,p)}case"steps":{let p=await Ie(c.device,{booted:!0});return mt(p,c,{text:await At(p,c.steps,c.timeout??5),device:p})}case"terminate":{let p=await Ie(c.device,{booted:!0});if(ot.get(p.udid)?.bundleId===c.bundle_id)ot.get(p.udid)?.stop();return await kt("xcrun",["simctl","terminate",p.udid,c.bundle_id]),{text:`Terminated ${c.bundle_id} on ${ce(p)}.`,device:p}}case"logs":return Gd(await Ie(c.device,{booted:!1}),c.after);case"screenshot":return Oi(await Ie(c.device,{booted:!0}),c.scale,c.save_path?Pi(e.root,c.save_path):void 0);case"chrome":return op(await Ie(c.device,{booted:!1}));case"inspect":return Vd(await Ie(c.device,{booted:!0}));case"tap":{let p=await Ie(c.device,{booted:!0}),m=c.x!==void 0&&c.y!==void 0;if(m)Wa(p,[c.x,c.y]);await At(p,[m?{action:"tap",x:c.x,y:c.y,...c.duration&&c.duration>0?{duration:c.duration}:{}}:c.id?{action:"tap",id:c.id}:{action:"tap",label:c.label}],3);let f=m?`(${c.x}, ${c.y})`:c.id?`id ${c.id}`:`"${c.label}"`;return mt(p,c,{text:`Tapped ${f} on ${ce(p)}.`,device:p})}case"swipe":{let p=await Ie(c.device,{booted:!0});return Wa(p,[c.x,c.y],[c.x2,c.y2]),await At(p,[{action:"swipe",x:c.x,y:c.y,x2:c.x2,y2:c.y2,...c.duration!==void 0?{duration:c.duration}:{}}],3),mt(p,c,{text:`Swiped (${c.x}, ${c.y}) \u2192 (${c.x2}, ${c.y2}) on ${ce(p)}.`,device:p})}case"type":{let p=await Ie(c.device,{booted:!0});return await At(p,[{action:"type",text:c.text}],3),mt(p,c,{text:`Typed ${c.text.length} character(s) on ${ce(p)}.`,device:p})}case"button":{let p=await Ie(c.device,{booted:!0});return await At(p,[{action:"button",name:c.name}],3),mt(p,c,{text:`Pressed ${c.name} on ${ce(p)}.`,device:p})}case"open_url":{let p=await Ie(c.device,{booted:!0}),m;try{m=new URL(c.url)}catch{te("simulator_invalid_request","open_url needs an absolute URL.")}if(Id.has(m.protocol))te("simulator_invalid_request",`${m.protocol} URLs are not allowed.`);return await ve("xcrun",["simctl","openurl",p.udid,m.href],"Opening the URL"),mt(p,c,{text:`Opened ${m.href} on ${ce(p)}.`,device:p})}case"appearance":{let p=await Ie(c.device,{booted:!0});return await ve("xcrun",["simctl","ui",p.udid,"appearance",c.mode],"Setting the appearance"),{text:`${ce(p)} is in ${c.mode} mode.`,device:p}}}}import{mkdtempSync as sp,readFileSync as ap,rmSync as lp}from"fs";import{tmpdir as cp}from"os";import{join as ll}from"path";import{spawn as dl}from"child_process";var up=/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i,pr=1,dp=[{bit:8,dx:0,dy:1},{bit:16,dx:0,dy:-1},{bit:32,dx:1,dy:0},{bit:64,dx:-1,dy:0}],cl=60,pp=8,pl=lr;var ul={65293:40,65421:40,65307:41,65288:42,65289:43,65535:76,65360:74,65367:77,65365:75,65366:78,65361:80,65362:82,65363:79,65364:81,65505:225,65506:229,65507:224,65508:228,65513:226,65514:230,65515:227,65516:231,65511:227,65512:231,65509:57},mp=(()=>{let e={" ":44};"abcdefghijklmnopqrstuvwxyz".split("").forEach((c,p)=>{e[c]=4+p,e[c.toUpperCase()]=4+p}),"1234567890".split("").forEach((c,p)=>{e[c]=30+p}),"!@#$%^&*()".split("").forEach((c,p)=>{e[c]=30+p});let l=[["-","_",45],["=","+",46],["[","{",47],["]","}",48],["\\","|",49],[";",":",51],["'",'"',52],["`","~",53],[",","<",54],[".",">",55],["/","?",56]];for(let[c,p,m]of l)e[c]=m,e[p]=m;return e})();function fp(e){if(ul[e]!==void 0)return ul[e];return e>=32&&e<=126?mp[String.fromCharCode(e)]??null:null}function ml(e,l){let c=dl("xcrun",["simctl","pbcopy",e],{stdio:["pipe","ignore","ignore"]});c.once("error",()=>{}),c.stdin.end(l)}function hp(e,l){let c=0,p={x:0,y:0},m=(f)=>{l.call(f).catch(()=>{})};return{pointer(f,h,y){let S=(y&pr)!==0;if(S&&!(c&pr))m({op:"touch",phase:"down",x:f,y:h});else if(S&&(f!==p.x||h!==p.y))m({op:"touch",phase:"move",x:f,y:h});else if(!S&&c&pr)m({op:"touch",phase:"up",x:f,y:h});for(let w of dp)if(y&w.bit&&!(c&w.bit))m({op:"swipe",x:f,y:h,x2:f+w.dx*cl,y2:h+w.dy*cl,duration:0.08});c=y,p={x:f,y:h}},key(f,h){let y=fp(h);if(y!==null)m({op:"key",usage:y,down:f})},clipboard(f){ml(e,f)},close(){if(c&pr)m({op:"touch",phase:"up",...p});c=0}}}function gp(e,l){let c=null,p="",m,f=(h)=>{cr({payload:{...h,device:e,observe:"none"},root:l}).catch(()=>{})};return{pointer(h,y,S){let w=(S&pr)!==0;if(w&&!c)c={x:h,y,at:Date.now()};if(!w&&c){let g=(Date.now()-c.at)/1000;if(Math.hypot(h-c.x,y-c.y)>pp)f({action:"swipe",x:c.x,y:c.y,x2:h,y2:y,duration:Math.min(Math.max(g,0.05),1)});else f({action:"tap",x:c.x,y:c.y,...g>0.5?{duration:Math.min(g,10)}:{}});c=null}},key(h,y){if(!h)return;let S=y===65293?`
|
|
536
|
+
`:y>=32&&y<=126?String.fromCharCode(y):null;if(S===null)return;p+=S,clearTimeout(m),m=setTimeout(()=>{let w=p;p="",f({action:"type",text:w})},250)},clipboard(h){ml(e,h)},close(){clearTimeout(m),c=null}}}function _p(e,l,c){return new Promise((p,m)=>{let f=dl(e,l,{stdio:"ignore",signal:c});f.once("error",m),f.once("exit",(h)=>p(h??-1))})}async function yp(e,l){let c=sp(ll(cp(),"reason-simulator-stream-"));try{let p=ll(c,"screen.png");if(await _p("xcrun",["simctl","io",e,"screenshot","--type=png",p],l)!==0)throw new r("simulator_not_booted","That simulator is not booted.");let m=ap(p).subarray(16,24);return{width:m.readUInt32BE(0),height:m.readUInt32BE(4)}}finally{lp(c,{recursive:!0,force:!0})}}async function fl(e,l={}){let{udid:c,...p}=e.payload;if(typeof c!=="string"||!up.test(c)||!p.video)throw new r("invalid_display_request","Reason simulator stream request is malformed.");let m=await Qa().catch(()=>{throw new r("simulator_axe_missing","AXe could not be installed on this Mac.")}),f=await cr({payload:{action:"screenshot",device:c},root:e.root});if(f.error||!f.image)throw new r("simulator_not_booted","That simulator is not booted.");let h={width:f.image.width,height:f.image.height},y=await To(m),S=y?await Jr(m,c,!0):null,w=y?null:await In();if(!y&&!w)throw new r("display_video_unsupported","This Mac can build neither the simulator host nor find an H.264 ffmpeg.");let g={kind:"simulator",udid:c,axe:m,points:h,sound:null,size:y?h:await yp(c,e.signal),stream:y?(v,C,A)=>Ha(y,c,Math.min(v,60),A,C):null,input:S?hp(c,S):gp(c,e.root)};return await Bt({payload:p,signal:e.signal},{...l,video:{desktop:async()=>g,...w?{ffmpeg:()=>w}:{}}})}var Cl=131072,Ip=131072,Lp=128,Pl=8192,Ni=30000,Mi=15000,kp=/^[a-z][a-z0-9_]{0,63}$/,Wo=new Set(["jobs.control","fs.read","fs.write"]),hl=new Set(["cancelled","run_finished","run_cancelled","driver_handoff","driver_stopped"]);function on(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/[a-z]/gi,(l)=>`[${l.toLowerCase()}${l.toUpperCase()}]`)}function gl(e){return e.map(on).join("/")}function Ai(e,l){let c=[];for(let p=0;p<e.length;p+=l)c.push(e.slice(p,p+l));return c}var Tp=[...Ai(ke,4).map((e)=>`/(${e.map(gl).join("|")})(/|$)`),...Ai(Zt,4).map((e)=>`/(${e.map(gl).join("|")})$`),...Ai([...Xt],6).map((e)=>`/(${e.map(on).join("|")})$`),`/${on(".env")}\\.[^/]+$`,`/[^/]+(${Yt.map(on).join("|")})$`],Ti=new Set(["add","am","apply","branch","checkout","cherry-pick","clean","commit","merge","mv","rebase","remote","reset","restore","revert","rm","stash","switch","tag"]),Ol=new Set(["blame","diff","for-each-ref","grep","log","ls-files","rev-list","rev-parse","shortlog","show","status"]);function Al(e){return[e.requiredPermission,...e.additionalPermissions??[]]}function Dp(e){return Nt(e)}function Di(){if(X()==="darwin")return Xe("/usr/bin/sandbox-exec");if(X()==="linux"||X()==="win32")return Er();return!1}function _l(){if(X()==="linux")return Xe("/proc");if(X()==="win32")return ye()!==null;if(!Di())return!1;if(X()==="darwin")return Xe("/usr/sbin/lsof");return!1}function $i(){return X()==="darwin"?"/bin/zsh":wn()}function Sr(e){return Boolean(e)&&typeof e==="object"&&!Array.isArray(e)}function Np(e){if(!Sr(e))throw new r("invalid_payload","Operation payload must be an object.");if(Buffer.byteLength(JSON.stringify(e),"utf8")>Te)throw new r("payload_too_large","Operation payload exceeds 256 KB.");return e}function Ut(e,l){let c=e[l];if(c===void 0||c===null)return;if(typeof c!=="string")throw new r("invalid_payload",`${l} must be a string.`);return c}function an(e,l,c=Pl){let p=Ut(e,l);if(!p||Buffer.byteLength(p,"utf8")>c||p.includes("\x00"))throw new r("invalid_payload",`${l} is missing or too large.`);return p}function Mp(e,l,c){let p=e[l];if(typeof p!=="string"||p.includes("\x00")||Buffer.byteLength(p,"utf8")>c)throw new r("invalid_payload",`${l} is missing or too large.`);return p}function xr(e,l,c,p){if(e===void 0||e===null)return l;if(typeof e!=="number"||!Number.isInteger(e))throw new r("invalid_payload","Expected a bounded integer.");return Math.min(Math.max(e,c),p)}function ht(e,l){if(X()==="win32")[e,l]=[e.toLowerCase(),l.toLowerCase()];return l===e||l.startsWith(`${e}${Op}`)}function Tt(e){if(yo(e))throw new r("protected_path","This path is on Reason's credential denylist. The Mac's owner can allow it with `reason permissions protected allow <path>` or Request permission in Files.")}function de(e){let l;try{l=Ke(e.path)}catch(c){if(process.platform==="darwin"&&hn(c))throw fn(e.path);throw new r("root_unavailable","The granted root is unavailable.")}if(l!==e.path||!Pr(l).isDirectory())throw new r("root_changed","The granted root changed after registration.");return Tt(l),l}function Yi(e,l="."){if(!l||l.includes("\x00")||Cp(l))throw new r("path_outside_root","Paths must be relative to the granted root.");if(X()==="win32"&&l.split(/[\\/]/).some(sn))throw new r("invalid_path","Windows reserves this file name.");let c=Pp(e,l);if(!ht(e,c))throw new r("path_outside_root","Path escapes the granted root.");return c}function Ft(e,l=".",c=!1){let p=Yi(e,l),m;try{m=Ke(p)}catch(f){if(Tl(f))throw Dl();throw new r("path_not_found","Path does not exist.")}if(!ht(e,m))throw new r("symlink_escape","Path resolves outside the granted root.");if(!c)Tt(m);return m}function $p(e,l){let c=Yi(e,l);if(Tt(c),Xe(c)){let f=Ke(c);if(!ht(e,f))throw new r("symlink_escape","Write target resolves outside the granted root.");if(Ii(c).isSymbolicLink())throw new r("symlink_escape","Writing through a symlink is not allowed.");return Tt(f),f}let p=br(c);while(!Xe(p)){let f=br(p);if(f===p)throw new r("path_outside_root","No safe write parent.");p=f}let m=Ke(p);if(!ht(e,m))throw new r("symlink_escape","Write parent resolves outside the granted root.");return Tt(m),c}function Il(e,l){return Li(e,l)||"."}function Bp(e,l=Cl){let c=Buffer.from(e,"utf8");if(c.byteLength<=l)return{value:e,truncated:!1};return{value:c.subarray(0,l).toString("utf8"),truncated:!0}}function Ll(e,l){return{...ze({home:e,temporaryDirectory:l}),ZDOTDIR:l,BASH_ENV:"/dev/null",ENV:"/dev/null",GIT_CONFIG_NOSYSTEM:"1",GIT_CONFIG_GLOBAL:"/dev/null",GIT_TERMINAL_PROMPT:"0",GIT_OPTIONAL_LOCKS:"0"}}function Fp(e,l,c,p=!1){return["(version 1)","(deny default)",'(import "system.sb")',"(allow process*)",'(allow file-read* (subpath "/opt/homebrew") (subpath "/usr/local"))',...p?['(allow file-read* (subpath "/dev"))']:[],`(allow file-read* (subpath ${JSON.stringify(e)}))`,`(allow file-read* file-write* (subpath ${JSON.stringify(l)}))`,...c?[`(allow file-write* (subpath ${JSON.stringify(e)}))`]:[],...Tp.map((m)=>`(deny file-read* file-write* (regex #"${m}"))`),...wo(e,c),"(deny network*)"].join(`
|
|
537
|
+
`)}async function un(e,l,c){return new Promise((p,m)=>{let f="",h="",y=!1,S=!1,w=!1,g;try{g=Ap(e,l,{cwd:c.cwd,env:c.env,shell:!1,stdio:["ignore","pipe","pipe"],...Le()}),Me(g)}catch(M){m(M);return}let v=(M,N)=>{if(w)return;w=!0,clearTimeout(I),c.signal.removeEventListener("abort",A),p({exitCode:M,signal:N,stdout:f,stderr:h,timedOut:S,truncated:y})},C=(M,N)=>{let L=`${M}${String(N)}`,B=Bp(L);return y||=B.truncated,B.value};g.stdout.on("data",(M)=>{f=C(f,M)}),g.stderr.on("data",(M)=>{h=C(h,M)}),g.once("error",m),g.once("exit",v);let A=()=>{try{if(X()==="win32"&&g.pid)$e(g.pid);else g.kill("SIGTERM")}catch{}};c.signal.addEventListener("abort",A,{once:!0});let I=setTimeout(()=>{S=!0,A()},c.timeoutMs)})}var yl=null;function Up(){return yl??=no({scrubEnvironment:Ll,spawnCaptured:un,isProtectedPath:E}),yl}var Vo=async(e,l,c)=>{if(X()==="linux"||X()==="win32")return Up()(e,l,c);if(X()!=="darwin"||!Xe("/usr/bin/sandbox-exec"))throw new r("sandbox_unavailable","Confined command execution is unavailable on this operating system.");let p=Sp(El(Ep(),"reason-device-"));try{return await un("/usr/bin/sandbox-exec",["-p",Fp(c.root,p,c.allowWrite,c.allowProcessInspection===!0),e,...l],{cwd:c.cwd,timeoutMs:c.timeoutMs,signal:c.signal,env:Ll(c.root,p)})}finally{Rp(p,{recursive:!0,force:!0})}};function Hp(e){let l=e.args;if(l===void 0)return[];if(!Array.isArray(l)||l.length>Lp)throw new r("invalid_payload","args must be a bounded string array.");return l.map((c)=>{if(typeof c!=="string"||c.includes("\x00")||Buffer.byteLength(c,"utf8")>Pl)throw new r("invalid_payload","Command argument is invalid or too large.");return c})}async function kl(e,l,c,p={}){if(e.signal.aborted)throw new r("cancelled","Operation was cancelled.");let m=de(e.root),f=p.cwd??m,h=await e.runCommand(l,c,{cwd:f,root:m,allowWrite:p.allowWrite===!0,timeoutMs:p.timeoutMs??Mi,signal:e.signal});if(h.exitCode!==0&&/permission denied|operation not permitted|EACCES|EPERM/i.test(h.stderr))await e.emit("permission.denied",{operation:"bash",provenance:e.worker?.executionMode==="unsandboxed"?"os_permission_unknown":"sandbox_policy"});return{exit_code:h.exitCode,signal:h.signal,stdout:h.stdout,stderr:h.stderr,timed_out:h.timedOut,truncated:h.truncated}}function Tl(e){let l=e instanceof Error&&"code"in e?e.code:null;return l==="EACCES"||l==="EPERM"}var Dl=()=>new r("path_unreadable","The path is not readable.");function jp(e){try{return xl(e,We.O_RDONLY)}catch(l){throw Tl(l)?Dl():l}}function bl(e,l){let c=ge()?K():null;return c?Mt(c,{op:"fs",capability:e,root:l.root,payload:l.payload},l.signal).then((p)=>p.value):Go(e,l)}function Go(e,l){return e==="fs.read"?qp(l):Gp(l)}async function qp(e){let l=de(e.root),c=Ft(l,an(e.payload,"path"));if(!Pr(c).isFile())throw new r("not_a_file","Read target is not a file.");let p=xr(e.payload.offset,0,0,Number.MAX_SAFE_INTEGER),m=xr(e.payload.max_bytes,65536,1,Cl),f=Ut(e.payload,"encoding");if(f!==void 0&&f!=="base64")throw new r("invalid_payload","encoding must be base64.");let h=jp(c),y,S;try{y=Rl(h).size;let g=Buffer.alloc(Math.max(0,Math.min(m,y-p)));S=g.subarray(0,g.byteLength?vp(h,g,0,g.byteLength,p):0)}finally{vl(h)}let w=f==="base64"||S.includes(0);return{path:Il(l,c),content:w?S.toString("base64"):S.toString("utf8"),encoding:w?"base64":"utf8",offset:p,bytes:S.byteLength,size:y,truncated:p+S.byteLength<y}}function Wp(e,l,c=X()){let p=e==="append"?We.O_APPEND:We.O_TRUNC;if(c==="win32")return l?We.O_WRONLY|(e==="append"?We.O_APPEND:0):We.O_WRONLY|We.O_CREAT|We.O_EXCL;return We.O_WRONLY|We.O_NOFOLLOW|p|(l?0:We.O_CREAT|We.O_EXCL)}async function Gp(e){let l=de(e.root),c=an(e.payload,"path"),p=Mp(e.payload,"content",Ip),m=Ut(e.payload,"mode")??"overwrite";if(!["create","overwrite","append"].includes(m))throw new r("invalid_payload","mode must be create, overwrite, or append.");let f=$p(l,c);if(e.payload.create_parents===!0||e.payload.create_directories===!0){wp(br(f),{recursive:!0,mode:448});let w=Ke(br(f));if(!ht(l,w))throw new r("symlink_escape","Write parent escaped root.")}if(!Xe(br(f)))throw new r("path_not_found","Write parent does not exist.");if(m==="create"&&Xe(f))throw new r("path_exists","Create mode will not overwrite an existing file.");let h=Xe(f),y=h?Ii(f):null,S=xl(f,Wp(m,h),384);try{let w=Rl(S),g=y??(X()==="win32"?Ii(f):null);if(g&&(w.ino!==g.ino||w.dev!==g.dev||X()==="win32"&&!ht(l,Ke(f))))throw new r("symlink_escape","The write target changed between validation and opening.");if(X()==="win32"&&y&&m!=="append")bp(S,0);xp(S,p,null,"utf8")}finally{vl(S)}return{path:Il(l,f),bytes_written:Buffer.byteLength(p,"utf8"),mode:m}}async function zp(e){let l=de(e.root),c=an(e.payload,"command",65536),p=Ft(l,Ut(e.payload,"cwd")??".");if(!Pr(p).isDirectory())throw new r("invalid_cwd","cwd is not a directory.");let m=xr(e.payload.timeout_ms,Mi,100,Ni);return kl(e,$i(),["-lc",c],{cwd:p,allowWrite:e.root.permissions.write,timeoutMs:m})}async function Vp(e){let l=Ui.safeParse(e.payload),c=e.worker;if(!l.success||!e.claimOwner||(c?!c.runtimeDirectory:X()!=="darwin"))throw new r("preview_unavailable","Preview servers are unavailable on this computer.");let p=de(e.root),m=ie(p,l.data.workspace),f=m.boundary===p?p:Ft(m.anchor,Li(m.anchor,m.boundary)||"."),h=Ft(f,Li(f,m.path)||".");if(!Pr(h).isDirectory())throw new r("invalid_cwd","The Session checkout is not a directory.");let y=Math.min(Date.parse(l.data.expires_at),Date.now()+Fi);if(!(y>Date.now()))throw new r("process_authority_lost","The preview server lease is unavailable.");let S=(L)=>e.emit("progress",{process:L});if(!c?.runtimeDirectory){if(e.claim.local_github_authority)throw new r("local_device_gh_confinement_unavailable","Only a worker runs a local GitHub Session's dev server.");return{...await ur({claim:e.claim,root:f,cwd:h,command:l.data.command,mode:"host",shell:xt(),environment:process.env,expiresAtMs:y,signal:e.signal,emit:S})}}let w={directory:El(c.runtimeDirectory,"processes")},g={deniedPorts:dr([e.apiOrigin])},v=mr(),C=gr(),A=ge(),I=l.data.egress?Rt(A):null;if(l.data.egress&&(I===null||!me(c.executionMode==="unsandboxed")))throw new r("preview_egress_unavailable","This computer cannot hold a dev server to the run's network allowlist; no command was dispatched.");let M=l.data.egress?await Os(l.data.egress.allowed_domains):null,N=M?[`export ${["HTTP_PROXY","HTTPS_PROXY","http_proxy","https_proxy"].map((L)=>`${L}=${M.url}`).join(" ")}`,"export NO_PROXY=localhost,127.0.0.1,::1 no_proxy=localhost,127.0.0.1,::1 NODE_USE_ENV_PROXY=1",l.data.command].join(`
|
|
538
|
+
`):l.data.command;try{return{...await ur({claim:e.claim,root:h,cwd:h,command:N,mode:"host",shell:C,expiresAtMs:y,signal:e.signal,emit:S,...A?{jobsUser:{...A,...I!==null?{modelGid:I}:{}}}:{},environment:{...v.variables,HOME:v.home,PATH:v.path,TMPDIR:v.temporaryDirectory,SHELL:C},journals:w,preview:g})}}finally{M?.close()}}async function Kp(e){oo();let l=de(e.root),c=io(e.payload.command),p=Ft(l,Ut(e.payload,"cwd")??".");if(!Pr(p).isDirectory())throw new r("invalid_cwd","cwd is not a directory.");let m=xr(e.payload.timeout_ms,na,100,to),{ignored:f}=so(e.payload.env);return await e.emit("progress",{shell:xt(),shell_flags:[...nr],sandbox:"none",ignored_env:f}),ia({command:c,cwd:p,timeoutMs:m,signal:e.signal,spawn:e.spawnFullControl,requestEnv:e.payload.env})}async function Yp(e){let l=de(e.root),c=Hp(e.payload),p=c[0];if(!p||!Ol.has(p)&&!Ti.has(p))throw new r("git_command_not_allowed","Git subcommand is not in the Device allowlist.");if(c.some((h)=>h==="-C"||h==="-c"||h.startsWith("--git-dir")||h.startsWith("--work-tree")||h.startsWith("--config-env")||h.startsWith("--exec-path")))throw new r("git_argument_not_allowed","Git path/config overrides are not allowed.");let m=Ti.has(p);if(m&&!e.root.permissions.write)throw new r("permission_denied","Mutating Git commands require the write grant.");let f=Ft(l,Ut(e.payload,"cwd")??".");return kl(e,"git",["-c","core.hooksPath=/dev/null","-c","credential.helper=",...c],{cwd:f,allowWrite:m||process.platform==="win32"&&e.root.permissions.write,timeoutMs:xr(e.payload.timeout_ms,Mi,100,Ni)})}function Nl(e,l){return async(c)=>{let p=await e.runCommand("/usr/sbin/lsof",c,{cwd:l,root:l,allowWrite:!1,allowProcessInspection:!0,timeoutMs:1e4,signal:e.signal});if(e.signal.aborted)throw new r("cancelled","Operation was cancelled.");return p}}async function Xp(e){let l=de(e.root);if(X()==="linux")return ha(l);if(X()==="win32")return Qi(l);return wa(l,Nl(e,l))}async function Jp(e){let l=de(e.root);if(X()==="linux")return ga(l);if(X()==="win32")return eo(l);return Sa(l,Nl(e,l))}var Dt=new Map;function Ml(e){let l,c={promise:new Promise((p)=>{l=p}),grant:l};return Dt.set(e,c),()=>{if(Dt.get(e)===c)Dt.delete(e)}}function Es(e){if(e.capability!=="hands.connect"||!Sr(e.payload)||e.payload[Re]!==!0)return()=>{};return Ml(e.operation_id)}function xs(e,l){if(e.capability!=="hands.connect"||l.kind!==vt||!Sr(e.payload)||e.payload[Re]!==!0)return!1;return Dt.get(e.operation_id)?.grant(),!0}async function Zp(e){let{[Re]:l,...c}=e.payload;if(l!==void 0&&(l!==!0||!e.worker))throw new r("invalid_payload","Reason sent an invalid workspace grant request.");let p=l===!0&&!Dt.has(e.operationId)?Ml(e.operationId):()=>{};try{return await Qp({...e,payload:c},l===!0?Dt.get(e.operationId).promise:void 0)}finally{p()}}async function Qp(e,l){let c=e.worker?Oa(e.worker):null,p=e.claim.environment;delete e.claim.environment;let m=e.worker&&p&&Zi({deviceId:e.deviceId},e.root.id,e.runId,p.payload,p.authority)?p.payload:void 0;return e.runHandsRelay({...l?{workspaceGrant:l}:{},...e.claimedAtMs===void 0?{}:{claimedAtMs:e.claimedAtMs},claimOwner:e.claimOwner,...m?{claimEnvironment:m}:{},localGithubConfinement:Boolean(e.claim.local_github_authority),...e.worker?{headless:!0,runtimeDirectory:e.worker.runtimeDirectory,...e.worker.handsSlots?{handsSlots:e.worker.handsSlots}:{},...e.worker.ownComputer?{ownComputer:!0}:{},hostExecution:e.worker.executionMode==="unsandboxed",...e.worker.executionMode==="unsandboxed"&&e.worker.readiness?.["pty.start"]===!0?{managedPty:{version:1,startupVerified:!0}}:{},deviceIdentity:{deviceId:e.deviceId,rootId:e.root.id,apiOrigin:e.apiOrigin},...c?{desktopRecording:c}:{}}:{},root:de(e.root),runId:e.runId,operationId:e.operationId,attemptId:e.attemptId,payload:e.payload,signal:e.signal,emitEvent:(f,h,y)=>e.emit(f,h,y)})}async function em(e){if(e.worker){if(!e.root.permissions.read||!e.root.permissions.write)throw new r("permission_denied","Bound Hands terminals require the workspace read/write grants.");let{workspace:l,session:c}=Hi(e.payload,e.operationId);return Vi({root:de(e.root),runId:e.runId,deviceId:e.deviceId,rootId:e.root.id,workspace:l,session:c,owner:e.claimOwner,authority:e.claimAuthority,signal:e.signal,emit:(p,m)=>e.emit(p,m)})}return e.runPtySession({root:de(e.root),runId:e.runId,operationId:e.operationId,payload:e.payload,signal:e.signal,emitEvent:(l,c)=>e.emit(l,c)})}function wl(e,l){let c=ge()?K():null;return c?Mt(c,{op:"transfer",direction:l,root:e.root,payload:e.payload,worker:Boolean(e.worker)},e.signal).then((p)=>p.value):Ko(l,{root:e.root,payload:e.payload,signal:e.signal,worker:Boolean(e.worker),fetchImpl:e.fetchImpl,beforeCommit:()=>e.emit("progress",{phase:"file_transfer_verified"})})}async function Ko(e,l){let c=de(l.root),p=er in l.payload;if(p&&!l.worker)throw new r("cloud_copy_workspace_invalid","Only a worker resolves a Cloud copy workspace.");let m=p?Qs(c,l.payload[er]):c;if("source"in l.payload||"source_version"in l.payload){if(e!=="export"||!p)throw new r("cloud_copy_source_unsupported","Explicit sources require the private Cloud exporter.");let y=Hs.safeParse(l.payload);if(!y.success)throw new r("invalid_payload","Invalid Cloud export request.");return ea({runtimeRoot:m,source:y.data.source,url:y.data.url,signal:l.signal,fetchImpl:l.fetchImpl})}let f=an(l.payload,"path",4096),h=e==="import"&&p?Zn(m):m;return Tt(Yi(h,f)),wt({direction:e,root:h,path:f,payload:l.payload,signal:l.signal,fetchImpl:l.fetchImpl,beforeCommit:l.beforeCommit})}var $l={"inference.custom.v1":{requiredPermission:"read",additionalPermissions:["execute","discover_environment"],execute:(e)=>{if(!e.customEndpointCredential||!e.claimOwner)throw new r("custom_endpoint_credential_unavailable","Local model credentials require a signed Device claim.");return ss({payload:e.payload,signal:e.signal,credential:e.customEndpointCredential,emit:(l,c)=>e.emit(l,c,e.signal)})}},"fs.read":{requiredPermission:"read",execute:(e)=>bl("fs.read",e)},"fs.write":{requiredPermission:"write",execute:(e)=>bl("fs.write",e)},"fs.export":{requiredPermission:"read",execute:(e)=>wl(e,"export")},"fs.import":{requiredPermission:"write",execute:(e)=>wl(e,"import")},"preview.serve.v1":{requiredPermission:"execute",additionalPermissions:["discover_environment"],available:()=>X()==="darwin"&&ro(),execute:Vp},"exec.run":{requiredPermission:"execute",available:Di,execute:zp},"exec.full":{requiredPermission:"execute",additionalPermissions:["discover_environment"],available:()=>ro(),execute:Kp},"git.run":{requiredPermission:"execute",available:()=>Di()&&Dp("git"),execute:Yp},"process.list":{requiredPermission:"read",additionalPermissions:["discover_environment"],available:_l,execute:Xp},"ports.list":{requiredPermission:"read",additionalPermissions:["discover_environment"],available:_l,execute:Jp},"hands.connect":{requiredPermission:"execute",additionalPermissions:["read","write","discover_environment"],available:()=>X()==="darwin"||Boolean(mn()),execute:Zp},"pty.start":{requiredPermission:"execute",additionalPermissions:["discover_environment"],available:Dn,execute:em},"display.stream.v1":{requiredPermission:"execute",additionalPermissions:["discover_environment"],available:$t,execute:(e)=>{let l=K();return l?Mt(l,{op:"display",payload:e.payload,proxy:(e.relay.loadProxy??j)()},e.signal):Bt({payload:e.payload,signal:e.signal},e.relay)}},"automation.call.v1":{requiredPermission:"execute",additionalPermissions:["read","discover_environment"],available:()=>Cn(),execute:(e)=>An({runId:e.runId,payload:e.payload,signal:e.signal,...e.worker?.userChrome?{userChrome:e.worker.userChrome}:{}})},"simulator.call.v1":{requiredPermission:"execute",additionalPermissions:["read","discover_environment"],available:lr,execute:(e)=>cr({payload:e.payload,root:de(e.root)})},"simulator.stream.v1":{requiredPermission:"execute",additionalPermissions:["read","discover_environment"],available:pl,execute:(e)=>fl({payload:e.payload,root:de(e.root),signal:e.signal},e.relay)},"jobs.control":{requiredPermission:"execute",additionalPermissions:["read","write","discover_environment"],available:()=>!0,execute:(e)=>Gi({root:de(e.root),runId:e.runId,payload:e.payload,signal:e.signal})},"github.local.v1":{requiredPermission:"read",additionalPermissions:["execute","discover_environment"],available:()=>X()==="darwin"?Xe("/usr/bin/sandbox-exec"):X()==="linux"||X()==="win32",execute:async(e)=>{let l=Pe.parse(e.payload),c=oe.parse(e.claim.local_github_authority);if(c.userId!==e.claimOwner?.user_id||c.deviceId!==e.deviceId||c.rootId!==e.root.id||c.runId!==e.runId||c.repoFullName!==l.repoFullName||!c.readOnly&&!e.root.permissions.write||!et(l)&&(c.readOnly||c.generation===null&&!(l.kind==="pr_merge"&&c.merge?.source==="human")&&!(l.kind==="pr_mutation"&&c.contributorRefresh)))throw Error("local_device_gh_authority_changed");return Ki({root:de(e.root),runId:e.runId,request:l,authority:c,signal:e.signal,leaseUntil:e.claim.lease_until},(p)=>bs(l,p))}},"environment.install":{requiredPermission:"execute",additionalPermissions:["read","write","discover_environment"],execute:async(e)=>it({root:de(e.root),runId:e.runId,payload:e.payload})},"browser.pr-proof.v1":{requiredPermission:"read",additionalPermissions:["execute"],available:()=>!1,execute:async(e)=>{if(!e.proveMac)throw new r("capability_unsupported","PR proof host is not installed.");return e.proveMac()}},"tunnel.open":{requiredPermission:"execute",additionalPermissions:["read","write","discover_environment"],execute:(e)=>qi({root:de(e.root),runId:e.runId,owner:e.claimOwner,payload:e.payload,signal:e.signal})},"tunnel.close":{requiredPermission:"execute",additionalPermissions:["read","write","discover_environment"],execute:(e)=>Wi({root:de(e.root),runId:e.runId,owner:e.claimOwner,payload:e.payload,signal:e.signal})},"workspace.setup.v1":{requiredPermission:"execute",additionalPermissions:["read","write"],available:Xn,execute:(e)=>Js(e.payload,e.signal)}};function tm(e,l){try{let c=ls(e,Ke(l)),p=c?e.find((m)=>m.path===c):void 0;return p&&/^[a-f0-9]{64}$/.test(p.pathFingerprint)?p.pathFingerprint:void 0}catch{return}}function rm(e,l){try{let c=Ke(l);return e.some((p)=>p.path===c)?Tr(c,X()):void 0}catch{return}}function nm(e,l){try{let c=Ke(l),p=e.find((m)=>m.path===c);return p&&/^[a-f0-9]{64}$/.test(p.pathFingerprint)?p.pathFingerprint:void 0}catch{return}}function om(e,l){try{let c=Ke(l);if(!e.some((p)=>p.path===c))return;return e.filter((p)=>p.path!==c&&ht(c,p.path)&&/^[a-f0-9]{64}$/.test(p.pathFingerprint)).map((p)=>p.pathFingerprint)}catch{return}}function Jo(e,l,c=X()){try{return _n({home:Tr(Ke(l),c),roots:e.map((p)=>({path_fingerprint:p.pathFingerprint,path:Tr(p.path,c)})).filter((p)=>/^[a-f0-9]{64}$/.test(p.path_fingerprint)&&kr(p.path)).slice(0,gn)})}catch{return}}function ks(e,l={}){let c=l.worker?l.worker.handsSlots??1:l.handsSlots===1?1:void 0,p=Boolean(l.worker)||X()==="darwin",m=p?nm(e,hr()):void 0,f=!l.worker&&X()==="darwin"?tm(e,hr()):void 0,h=p?rm(e,hr()):void 0,y=!l.worker&&X()==="darwin"?om(e,hr()):void 0,S=p?Jo(e,hr()):void 0,w=ta.filter((g)=>{if(rr.has(g)&&!l.worker)return!1;if(l.worker&&!Wr(g,l.worker))return!1;let v=$l[g];if(!v)return!1;return(g==="hands.connect"&&(l.terminalOnlyHands===!0||Boolean(l.worker))||(g==="pty.start"||g==="preview.serve.v1")&&Boolean(l.worker)||g==="browser.pr-proof.v1"&&Boolean(l.productionProof)?!0:v.available?.()??!0)&&e.some((A)=>(!l.worker||g!=="pty.start"||A.permissions.read&&A.permissions.write)&&Al(v).every((I)=>A.permissions[I]))});return{supported_operations:w,...m?{account_root_fingerprint:m}:{},...f?{workspace_root_fingerprint:f}:{},...h?{account_root_path:h}:{},...y?{home_contained_root_fingerprints:y}:{},...S?{root_paths:S}:{},...w.includes("hands.connect")?{hands_worker_artifact_sha256:b,hands_worker_entrypoint:R,...c?{hands_slots:c}:{}}:{},max_payload_bytes:Te,max_result_bytes:Te,operation_constraints:{...w.includes("browser.pr-proof.v1")&&l.productionProof?{"browser.pr-proof.v1":Ln.parse(l.productionProof)}:{},...w.includes("exec.run")?{"exec.run":{transport:"shell",shell:$i(),sandbox:X()==="linux"?"linux_sandbox_runtime":X()==="win32"?"windows_srt":"macos_seatbelt",network:!1,max_timeout_ms:Ni}}:{},...w.includes("exec.full")?{"exec.full":sa()}:{},"git.run":{read_only_subcommands:[...Ol].sort(),mutating_subcommands:[...Ti].sort(),push:!1,credential_helpers:!1},"fs.export":{transport:"https_signed_url",max_bytes:Ze,max_timeout_ms:Qt,result:"sha256_and_size"},"fs.import":{transport:"https_signed_url",max_bytes:Ze,max_timeout_ms:Qt,atomic:!0,overwrite:!1},"hands.connect":{transport:"wss_relay",worker:"ara_hands",worker_version:D,protocol_version:P,worker_artifact_sha256:b,worker_entrypoint:R,policy_mode:"full_access",policy_version:1,workspace_base:ue,workspace_layout:Z,...c?{slots:c}:{},browser_state:l.worker?"optional_headless":l.terminalOnlyHands===!0?"disabled_terminal_only":X()==="darwin"?"optional_isolated_per_session":"isolated_per_session",max_session_ms:43200000},...w.includes("pty.start")?{"pty.start":{transport:"wss_relay",shell:"login_shell",resize:!0,slots:Or,max_session_ms:Rr,max_buffered_output_bytes:jt}}:{},...l.worker?Object.fromEntries(w.filter((g)=>g!=="browser.pr-proof.v1").map((g)=>[g,{ready:l.worker?.readiness?.[g]===!0,...l.worker?.readiness?.[g]!==!0&&l.worker?.probing?.includes(g)?{probing:!0}:{},execution_mode:Wr(g,{...l.worker,executionMode:"sandboxed"})?"confined":"host",...g==="pty.start"?{transport:"wss_relay",worker:"ara_hands",shell:"bound_job",protocol_version:Wt,environment:"private_snapshot",receipt:"metadata_only",...l.worker?.persistentTerminals&&!ge()?{persistent_terminals:!0}:{}}:{},...g==="github.local.v1"?{contributor_attribution:2,prepare_diagnostics:1,...l.worker?.githubSignedIn!==void 0?{gh_authenticated:l.worker.githubSignedIn}:{}}:{},...g==="hands.connect"?{transport:"wss_relay",worker:"ara_hands",slots:c,session_group:bi,...l.worker?.ownComputer?{[vi]:Si}:{},workspace_base:ue,workspace_layout:Z,browser_state:"optional_headless",desktop:!1,worker_version:D,protocol_version:P,...l.worker?.readiness?.["environment.install"]===!0&&w.includes("environment.install")?{environment_delivery:ti,[ii]:ni}:{},...l.worker?{[ui]:ai}:{},...l.worker?{[si]:oi}:{},...l.worker?{[li]:ci}:{},...l.worker?.handsBrowser?{[mi]:fi}:{},[hi]:pi,[_i]:gi,...me(l.worker?.executionMode==="unsandboxed")?{[Y]:pe}:{},...me(l.worker?.executionMode==="unsandboxed")&&Rt()!==null?{[q]:Oe}:{},...me(l.worker?.executionMode==="unsandboxed")&&ge()?{[wi]:yi}:{}}:{},...g==="fs.export"?{cloud_source_version:Fr,source_kinds:["workspace","attachment"],[Fn]:Un}:{},...g==="fs.import"?{[Fn]:Un}:{},...g===Bi&&Rt()!==null&&me(l.worker?.executionMode==="unsandboxed")?{[ji]:dn}:{},...g==="tunnel.open"?{carried_jobs:Ei}:{},...g==="jobs.control"?{[ki]:xi}:{},...g==="display.stream.v1"&&l.worker?.displayVideo?{[vo]:bo,[So]:ft.join(","),[Eo]:xo,[ko]:Co}:{},...g==="automation.call.v1"&&l.worker?.userChrome?{[St]:!0}:{},...g==="automation.call.v1"&&l.worker?.cloudSessions?{[Ci]:!0}:{}}])):{}}}}function Zi(e,l,c,p,m){let f=fr.safeParse(p);return f.success&&m!==void 0&&m.device_id===e.deviceId&&f.data.device_id===e.deviceId&&f.data.root_id===l&&f.data.run_id===c&&f.data.binding.kind===m.binding&&f.data.binding.target_revision===m.target_revision&&f.data.binding.root_grant_revision===m.root_grant_revision&&f.data.binding.target_generation===m.target_generation&&f.data.binding.target_fence_id===m.target_fence_id}async function Cs(e,l,c,p,m){if(l.capability!=="hands.connect"||c.kind!==bt||!p.operationEnvironment||!p.acknowledgeOperationEnvironment)return!1;let f=c.payload.snapshot_id;if(c.payload.version!==1||typeof f!=="string"||Object.keys(c.payload).length!==2)throw new r("environment_unavailable","Reason sent an invalid environment delivery.");let h=e.roots.find((w)=>w.id===l.root_id);if(!h)throw new r("root_not_granted","The Hands root is no longer granted.");let y=await p.operationEnvironment(e,l,f,m);if(!Zi(e,h.id,l.run_id,y.payload,y.authority)||y.payload.snapshot_id!==f)throw new r("environment_unavailable","The delivered environment does not match this Hands.");let S=it({root:de(h),operationId:l.operation_id,payload:y.payload});return await p.acknowledgeOperationEnvironment(e,l,{snapshot_id:S.snapshot_id,installed_revision:S.installed_revision,installed:!0},m),!0}async function As(e,l,c,p){if(l.capability!=="hands.connect"||c.kind!==di)return!1;let{version:m,run_id:f,target_generation:h,target_fence_id:y}=c.payload;if(m!==1||Object.keys(c.payload).length!==4||typeof f!=="string"||typeof h!=="number"||typeof y!=="string")throw new r("hands_rebind_unavailable","Reason sent an invalid Hands rebind.");let S=e.roots.find((w)=>w.id===l.root_id);if(!S)throw new r("root_not_granted","The Hands root is no longer granted.");return await zi({operationId:l.operation_id,root:de(S),runId:f,targetGeneration:h,fenceId:y,...p?{signal:p}:{}}),!0}async function Ps(e,l,c){if(l.capability!=="github.local.v1")return Sl(e,l,c);try{let p=await Sl(e,l,c);if(p.status==="succeeded"||Qn(l.payload,p.status,p.error_code))return p;return{status:p.status,error_code:p.status==="cancelled"?"operation_cancelled":"local_github_unavailable"}}catch{return{status:c.signal.aborted?"cancelled":"failed",error_code:c.signal.aborted?"operation_cancelled":"local_github_unavailable"}}}async function Sl(e,l,c){if(rr.has(l.capability)&&!c.worker)return{status:"failed",error_code:"capability_not_granted"};if(c.worker&&!Wr(l.capability,c.worker))return{status:"failed",error_code:"capability_not_granted"};if(c.worker&&c.worker.readiness?.[l.capability]!==!0)return{status:"failed",error_code:"capability_unavailable"};if(l.local_github_authority){let g=oe.safeParse(l.local_github_authority);if(!g.success||g.data.deviceId!==e.deviceId||g.data.rootId!==l.root_id||g.data.runId!==l.run_id||g.data.userId!==l.owner?.user_id||!["github.local.v1","hands.connect","environment.install","jobs.control","preview.serve.v1"].includes(l.capability))return{status:"failed",error_code:"local_device_gh_capability_denied"}}let p=$l[l.capability];if(!p)return{status:"failed",error_code:"capability_unsupported"};if(p.available&&!p.available()&&!(["hands.connect","pty.start","preview.serve.v1"].includes(l.capability)&&c.worker)&&!c.runCommand&&!c.runHandsRelay&&!c.spawnFullControl&&!c.runPtySession&&!(l.capability==="browser.pr-proof.v1"&&c.proveMac))return{status:"failed",error_code:"capability_unavailable"};if(l.protocol_version!==2)return{status:"failed",error_code:"protocol_unsupported"};let m=e.roots.find((g)=>g.id===l.root_id);if(!m)return{status:"failed",error_code:"root_not_granted"};if((l.capability==="fs.export"||l.capability==="fs.import")&&Sr(l.payload)&&(("source"in l.payload)||("source_version"in l.payload))){let g=Boolean(c.worker||e.worker)&&er in l.payload;if(l.capability!=="fs.export"||!g)return{status:"failed",error_code:"cloud_copy_source_unsupported"}}if(l.owner&&(l.owner.device_id!==e.deviceId||l.owner.organization_id!==e.orgId))return{status:"failed",error_code:"capability_not_granted"};if((l.capability==="tunnel.open"||l.capability==="tunnel.close")&&!l.owner)return{status:"failed",error_code:"preview_unavailable"};if(l.capability==="environment.install"&&!Zi(e,m.id,l.run_id,l.payload,l.authority))return{status:"failed",error_code:"environment_unavailable"};if(Al(p).some((g)=>!m.permissions[g]))return{status:"failed",error_code:"permission_denied"};let f=0,h=async(g,v,C)=>{if(["environment.install","github.local.v1"].includes(l.capability)||l.capability==="inference.custom.v1"&&(g==="started"||g==="completed"))return;await c.emit?.({sequence:f++,kind:g,capability:l.capability,data:v,...(g==="hands.reconnected"||l.capability==="inference.custom.v1")&&C?{deliverySignal:C}:{}})},y=l.capability==="hands.connect"||l.capability==="display.stream.v1"||l.capability==="simulator.stream.v1"||Wo.has(l.capability)||l.capability==="pty.start",S,w=async(g,v,C)=>{let A=S;S=void 0,await Promise.all([A,h(g,v,C)])};try{if(y)S=h("started"),S.catch(()=>{return});else await h("started");let g={...c.proxy===void 0?{}:{loadProxy:()=>c.proxy??null},...c.handsLaunch?.takePrespawnedWorker?{takePrespawnedWorker:c.handsLaunch.takePrespawnedWorker}:{},...c.handsLaunch?.adoptSpawnedWorker?{adoptSpawnedWorker:c.handsLaunch.adoptSpawnedWorker}:{}},v=await p.execute({...c.proveMac?{proveMac:()=>c.proveMac(l,c.signal,(C)=>h("pr-proof.started.v1",C))}:{},claim:l,worker:c.worker,claimOwner:l.owner,claimAuthority:l.authority,organizationId:e.orgId,deviceId:e.deviceId,apiOrigin:e.apiOrigin,root:m,payload:Np(l.payload),runId:l.run_id,operationId:l.operation_id,attemptId:l.attempt_id,...c.handsLaunch?{claimedAtMs:c.handsLaunch.claimedAtMs}:{},signal:c.signal,...c.customEndpointCredential?{customEndpointCredential:c.customEndpointCredential}:{},fetchImpl:c.fetchImpl??fetch,relay:g,runCommand:c.runCommand??Vo,spawnFullControl:c.spawnFullControl??un,emit:y?w:h,runHandsRelay:c.runHandsRelay??((C)=>Ot(C,g)),runPtySession:c.runPtySession??Nn});if(l.capability==="github.local.v1")No.parse(v);if(!Sr(v))throw new r("invalid_result","Operation result must be a JSON object.");if(Buffer.byteLength(JSON.stringify(v)??"null","utf8")>Te)throw new r("result_too_large","Operation result exceeds 256 KB.");return await(y?w:h)("completed",{ok:!0}),{status:"succeeded",result:v,error_code:null}}catch(g){let v=c.signal.reason instanceof r&&hl.has(c.signal.reason.code)?c.signal.reason.code:g instanceof r&&hl.has(g.code)?g.code:null;if(c.signal.aborted||v)return{status:"cancelled",...g instanceof nt?{result:{process_terminal_observation:g.observation}}:{},error_code:["environment.install","github.local.v1","inference.custom.v1"].includes(l.capability)?"operation_cancelled":v??"cancelled"};if(["fs.read","fs.write"].includes(l.capability)&&g instanceof Error&&"code"in g&&["EACCES","EPERM"].includes(String(g.code)))await h("permission.denied",{operation:l.capability==="fs.read"?"read":"write",provenance:"os_permission_unknown"});let C=l.capability==="inference.custom.v1"?g instanceof r&&kn(g.code)?g.code:"custom_endpoint_unavailable":l.capability==="github.local.v1"?g instanceof ir&&Qn(l.payload,"failed",g.code)?g.code:"local_github_unavailable":l.capability==="environment.install"?"environment_install_failed":g instanceof r&&kp.test(g.code)?g.code:"capability_failed",A=l.capability==="hands.connect"&&g instanceof wr?Ji(g.expiryDiagnostic):null;return await h("completed",{ok:!1,error_code:C,...A?{expiry_diagnostic:A}:{}}),{status:"failed",error_code:C}}}
|
|
539
|
+
export{ln,Wo,$i,un,Vo,Go,Es,xs,Ko,Jo,ks,Cs,As,Ps};
|