mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-27 05:01:12 +00:00
* feat(browser): add copilot security contracts * fix(gateway): expose verified client identity to handlers * feat(browser): add secure per-tab copilot panel Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * refactor(browser): separate copilot gateway hint custody * fix(browser): preserve legacy pairing parse shape * fix(browser): harden copilot lifecycle custody Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * fix(browser): enforce copilot lifecycle boundaries Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * style(browser): format copilot sources Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * fix(browser): preserve copilot consent revocation Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * refactor(browser): split copilot custody owners Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * test(browser): normalize websocket array buffers Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * chore(protocol): regenerate Swift gateway models Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * refactor(browser): model copilot runtime entrypoints Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * fix(browser): honor extension build boundaries Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * test(gateway): assert targeted chat delivery Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * test(gateway): cover targeted delivery calls Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * fix(browser): declare copilot build dependencies Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * fix(ci): clear browser copilot gate failures Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * test(ci): cover copilot lint exclusion Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * fix(browser): gate copilot on relay custody Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> * test(browser): bound copilot relay frames Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com> --------- Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>
2 lines
26 KiB
JavaScript
2 lines
26 KiB
JavaScript
function fe(t){if(typeof t!="string")return"";let e=t.trim();return e?e.replace(/[A-Z]/g,n=>String.fromCharCode(n.charCodeAt(0)+32)):""}function ye(t){let e=t.scopes.join(","),n=t.token??"",o=fe(t.platform),i=fe(t.deviceFamily);return["v3",t.deviceId,t.clientId,t.clientMode,t.role,e,String(t.signedAtMs),n,t.nonce,o,i].join("|")}var g={AUTH_REQUIRED:"AUTH_REQUIRED",AUTH_UNAUTHORIZED:"AUTH_UNAUTHORIZED",AUTH_TOKEN_MISSING:"AUTH_TOKEN_MISSING",AUTH_TOKEN_MISMATCH:"AUTH_TOKEN_MISMATCH",AUTH_TOKEN_NOT_CONFIGURED:"AUTH_TOKEN_NOT_CONFIGURED",AUTH_PASSWORD_MISSING:"AUTH_PASSWORD_MISSING",AUTH_PASSWORD_MISMATCH:"AUTH_PASSWORD_MISMATCH",AUTH_PASSWORD_NOT_CONFIGURED:"AUTH_PASSWORD_NOT_CONFIGURED",AUTH_BOOTSTRAP_TOKEN_INVALID:"AUTH_BOOTSTRAP_TOKEN_INVALID",AUTH_DEVICE_TOKEN_MISMATCH:"AUTH_DEVICE_TOKEN_MISMATCH",AUTH_SCOPE_MISMATCH:"AUTH_SCOPE_MISMATCH",AUTH_RATE_LIMITED:"AUTH_RATE_LIMITED",AUTH_TAILSCALE_IDENTITY_MISSING:"AUTH_TAILSCALE_IDENTITY_MISSING",AUTH_TAILSCALE_PROXY_MISSING:"AUTH_TAILSCALE_PROXY_MISSING",AUTH_TAILSCALE_WHOIS_FAILED:"AUTH_TAILSCALE_WHOIS_FAILED",AUTH_TAILSCALE_IDENTITY_MISMATCH:"AUTH_TAILSCALE_IDENTITY_MISMATCH",CONTROL_UI_ORIGIN_NOT_ALLOWED:"CONTROL_UI_ORIGIN_NOT_ALLOWED",PROTOCOL_MISMATCH:"PROTOCOL_MISMATCH",CONTROL_UI_DEVICE_IDENTITY_REQUIRED:"CONTROL_UI_DEVICE_IDENTITY_REQUIRED",DEVICE_IDENTITY_REQUIRED:"DEVICE_IDENTITY_REQUIRED",DEVICE_AUTH_INVALID:"DEVICE_AUTH_INVALID",DEVICE_AUTH_DEVICE_ID_MISMATCH:"DEVICE_AUTH_DEVICE_ID_MISMATCH",DEVICE_AUTH_SIGNATURE_EXPIRED:"DEVICE_AUTH_SIGNATURE_EXPIRED",DEVICE_AUTH_NONCE_REQUIRED:"DEVICE_AUTH_NONCE_REQUIRED",DEVICE_AUTH_NONCE_MISMATCH:"DEVICE_AUTH_NONCE_MISMATCH",DEVICE_AUTH_SIGNATURE_INVALID:"DEVICE_AUTH_SIGNATURE_INVALID",DEVICE_AUTH_PUBLIC_KEY_INVALID:"DEVICE_AUTH_PUBLIC_KEY_INVALID",PAIRING_REQUIRED:"PAIRING_REQUIRED",CLIENT_VERSION_MISMATCH:"CLIENT_VERSION_MISMATCH"};function b(t){return typeof t=="string"&&t.trim()||void 0}function he(t){let e=b(t.token),n=b(t.bootstrapToken),o=b(t.deviceToken),i=b(t.password),r=b(t.storedToken),s={storedToken:r,storedScopes:t.storedScopes};if(t.preferBootstrapToken&&n)return{authBootstrapToken:n,authPassword:i,...s};let l=t.pendingDeviceTokenRetry===!0&&!o&&!!(e&&r&&t.trustedDeviceTokenRetry),d=o??(l||!(e||i)&&(!n||r)?r:void 0),c=!!(d&&!o&&r)&&d===r,u=e??d,p=!e&&!d&&!i?n:void 0;return{authToken:u,authBootstrapToken:p,authDeviceToken:l?r:void 0,authPassword:i,authApprovalRuntimeToken:b(t.approvalRuntimeToken),authAgentRuntimeIdentityToken:b(t.agentRuntimeIdentityToken),signatureToken:u??p,resolvedDeviceToken:d,usingStoredDeviceToken:c,...s}}function Z(t){let e={token:t.authToken,bootstrapToken:t.authBootstrapToken,deviceToken:t.authDeviceToken??t.resolvedDeviceToken,password:t.authPassword,approvalRuntimeToken:t.authApprovalRuntimeToken,agentRuntimeIdentityToken:t.authAgentRuntimeIdentityToken};return Object.values(e).some(Boolean)?e:void 0}function Te(t){return t.requestedScopes??(t.usingStoredDeviceToken&&t.storedScopes?.length?t.storedScopes:[...t.defaultScopes])}var Q=class{constructor(e){this.deps=e}async buildPlan(e){let n=await this.deps.loadIdentity(),o=n?await this.deps.tokenStore.load({clientId:e.client.id,deviceId:n.deviceId,role:e.role}):null,i=o?.token,r=he({token:e.token,bootstrapToken:e.bootstrapToken,password:e.password,storedToken:i,storedScopes:o?.scopes,pendingDeviceTokenRetry:e.pendingDeviceTokenRetry,trustedDeviceTokenRetry:e.trustedDeviceTokenRetry,preferBootstrapToken:e.preferBootstrapToken}),{usingStoredDeviceToken:s}=r,l=Te({requestedScopes:r.authBootstrapToken&&e.bootstrapScopes?[...e.bootstrapScopes]:void 0,usingStoredDeviceToken:s,storedScopes:r.storedScopes,defaultScopes:e.defaultScopes});if(!n)return{clientId:e.client.id,role:e.role,identity:n,selectedAuth:r,scopes:l,auth:Z(r)};let d=this.deps.nowMs?.()??Date.now(),c=e.nonce??"",{authBootstrapToken:u,signatureToken:p}=r,f=null;u?f=u:p&&(f=p);let h=ye({deviceId:n.deviceId,clientId:e.client.id,clientMode:e.client.mode,role:e.role,scopes:l,signedAtMs:d,token:f,nonce:c,platform:e.client.platform,deviceFamily:e.client.deviceFamily});return{clientId:e.client.id,role:e.role,identity:n,selectedAuth:r,scopes:l,auth:Z(r),device:{id:n.deviceId,publicKey:n.publicKey,signature:await n.sign(h),signedAt:d,nonce:c}}}async acceptHello(e,n){let o=e.auth?.deviceToken?.trim();!o||!n.identity||await this.deps.tokenStore.store({clientId:n.clientId,deviceId:n.identity.deviceId,role:e.auth?.role??n.role,token:o,scopes:e.auth?.scopes??[]})}async clearStoredToken(e){e.identity&&await this.deps.tokenStore.clear({clientId:e.clientId,deviceId:e.identity.deviceId,role:e.role})}};function $(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function B(t){return typeof t=="string"&&t.length>0}function me(t){return typeof t=="number"&&Number.isInteger(t)&&t>=0}function Ke(t){return!$(t)||!B(t.code)||!B(t.message)||t.retryable!==void 0&&typeof t.retryable!="boolean"?!1:t.retryAfterMs===void 0||me(t.retryAfterMs)}function Ee(t){return!$(t)||t.type!=="event"||!B(t.event)?!1:t.seq===void 0||me(t.seq)}function Ae(t){return!$(t)||t.type!=="res"||!B(t.id)||typeof t.ok!="boolean"?!1:t.error===void 0||Ke(t.error)}function Xe(t,e){let n=Math.min(t.maxMs,t.initialMs*t.factor**Math.max(e-1,0)),o=n*t.jitter*Math.random();return Math.min(t.maxMs,Math.round(n+o))}async function ge(t,e,n={}){if(!Number.isFinite(t)||t<=0)return;let o=Math.min(Math.max(Math.floor(t),1),2147e6);await new Promise((i,r)=>{let s=!1,l=null,d=()=>e?.removeEventListener("abort",c),c=()=>{s||(s=!0,l&&clearTimeout(l),l=null,d(),r(new Error("aborted",{cause:e?.reason??new Error("aborted")})))};if(e?.addEventListener("abort",c,{once:!0}),e?.aborted){c();return}l=setTimeout(()=>{s=!0,d(),l=null,i()},o),n.ref===!1&&l.unref?.(),e?.aborted&&c()})}var F=class{constructor(e,n=Number.POSITIVE_INFINITY){this.policy=e;this.maxAttempts=n;this.attempts=0;this.initialMs=e.initialMs}reset(e=this.policy.initialMs){this.cancel(),this.attempts=0,this.initialMs=e,this.nextDelayOverrideMs=void 0}cancel(e=new Error("retry cancelled")){this.pendingAbort?.abort(e),this.pendingAbort=void 0}next(e){let n=this.nextDelayOverrideMs;if(this.nextDelayOverrideMs=void 0,n===void 0&&++this.attempts>Math.ceil(this.maxAttempts))return;let o=Math.max(this.attempts,1),i=n??Xe({...this.policy,initialMs:this.initialMs},o);this.cancel();let r=new AbortController;return this.pendingAbort=r,{attempt:o,delayMs:i,signal:e?AbortSignal.any([r.signal,e]):r.signal}}},J={attempts:3,minDelayMs:300,maxDelayMs:3e4,jitter:0},ze=t=>new Promise(e=>{setTimeout(e,t)});function V(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function ee(t,e,n,o){let i=V(t);return i===void 0?e:Math.min(Math.max(i,n??Number.NEGATIVE_INFINITY),o??Number.POSITIVE_INFINITY)}function _e(t,e){return Math.max(1,Math.round(V(t)??e))}function q(t){let e=t===Number.POSITIVE_INFINITY?2147e6:V(t)??0;return Math.min(Math.max(Math.round(e),0),2147e6)}function je(t,e){if(t==="full")return"full";let n=V(t);return n===void 0?e:Math.min(Math.max(n,0),1)}function Ze(t=J,e){let n=_e(e?.attempts,t.attempts),o=q(ee(e?.minDelayMs,t.minDelayMs,0)),i=Math.max(o,q(ee(e?.maxDelayMs,t.maxDelayMs,0)));return{attempts:n,minDelayMs:o,maxDelayMs:i,jitter:je(e?.jitter,t.jitter)}}function Qe(t,e,n,o){if(e==="full")return n==="symmetric"?Math.max(0,Math.round(t*(.5+o()*.5))):Math.max(0,Math.ceil(t*(1+o())));if(e<=0)return n==="positive"?Math.ceil(t):t;let i=o(),r=n==="positive"?i*e:(i*2-1)*e,s=t*(1+r);return Math.max(0,n==="positive"?Math.ceil(s):Math.round(s))}function $e(t,e="Non-Error thrown"){if(t instanceof Error)return t;if(typeof t=="string")return new Error(t);let n=new Error(e,{cause:t});return(typeof t=="object"&&t!==null||typeof t=="function")&&Object.assign(n,t),n}function Je(t={}){let e=t.sleep??ze,n=t.random??Math.random,o=t.createFailure??(i=>$e(i.at(-1)??new Error("Retry failed")));return async function(r,s=3,l=300){let d=[];if(typeof s=="number"){let E=_e(s,J.attempts);for(let A=0;A<E;A+=1)try{return await r()}catch(N){if(d.push(N),A===E-1)break;await e(q(l*2**A))}throw o(d)}let c=s,u=Ze(J,c),p=u.attempts,f=u.minDelayMs,h=u.maxDelayMs>0?u.maxDelayMs:Number.POSITIVE_INFINITY,m=c.retryAfterMaxDelayMs===void 0?h:Math.max(f,q(ee(c.retryAfterMaxDelayMs,h,0))),C=c.random??n,S=c.sleep??e,D=c.shouldRetry??(()=>!0);for(let E=1;E<=p;E+=1)try{return await r()}catch(A){if(d.push(A),E>=p||!D(A,E))break;let N={attempt:E,maxAttempts:p,err:A,label:c.label},x=c.retryAfterMs?.(A),O=typeof x=="number"&&Number.isFinite(x),L=typeof c.delayMs=="function"?c.delayMs(N):c.delayMs,ue=L===void 0?void 0:q(L),Ve=O?Math.max(x,f):ue===void 0?f*2**(E-1):Math.max(ue,f),j=O?m:h,v=Math.min(Ve,j),pe=O&&(x??0)<=j,Ye=u.jitter==="full"&&!O||pe;v=Qe(v,u.jitter,Ye?"positive":"symmetric",C),v=Math.min(Math.max(v,f),j),await c.onRetry?.({...N,delayMs:v}),v>0&&await S(v)}throw o(d)}}var xt=Je();var G=class extends Error{constructor(e){super(e.message??"request failed"),this.name="GatewayProtocolRequestError",this.code=e.code??"UNAVAILABLE",this.gatewayCode=this.code,this.details=e.details,this.retryable=e.retryable===!0,this.retryAfterMs=e.retryAfterMs}},te=class{constructor(e){this.opts=e;this.socket=null;this.pending=new Map;this.listeners=new Set;this.stopped=!0;this.generation=0;this.lastSeq=null;this.connectNonce=null;this.connectSent=!1;this.connectRequestSent=!1;this.handshakeTimer=null;this.socketOpened=!1;this.helloReceived=!1;this.connectTiming=null;this.reconnectSupervisor=new F({initialMs:e.reconnect.initialMs,maxMs:e.reconnect.maxMs,factor:e.reconnect.multiplier,jitter:0})}get connected(){return this.socket?.isOpen()??!1}get hasPendingRequests(){return this.pending.size>0}get connecting(){return this.connectSent&&!this.helloReceived}get hasUnboundedPendingRequests(){return[...this.pending.values()].some(e=>e.unbounded)}start(){this.stopped=!1,this.reconnectSupervisor.cancel(),this.connect()}stop(){this.stopped=!0,this.clearHandshakeTimer(),this.reconnectSupervisor.reset();let e=this.socket;e&&this.opts.notifyStoppedClose&&(this.stoppedSocket={socket:e,context:this.closeContext()}),this.socket=null,this.connectFailure=void 0,this.connectTiming=null,this.flushRequests(new Error("gateway client stopped")),e?.close()}request(e,n,o){let i=this.socket;if(!i?.isOpen())return Promise.reject(new Error("gateway not connected"));if(typeof e!="string"||e.length===0)return Promise.reject(new Error("invalid request frame: method must be a non-empty string"));let r=this.opts.createRequestId(),s=o?.timeoutMs===null?void 0:o?.timeoutMs??this.opts.requestTimeoutMs;return new Promise((l,d)=>{let c,u={resolve:h=>l(h),reject:d,expectFinal:o?.expectFinal===!0,acceptedNotified:!1,onAccepted:o?.onAccepted,unbounded:s===void 0,method:e,startedAtMs:this.nowMs()},p=()=>{this.pending.delete(r),c&&clearTimeout(c),this.finishRequestTiming(r,u,!1,"CLIENT_ABORTED"),d(this.opts.createRequestAbortError?.(e)??new Error(`gateway request aborted for ${e}`))},f=()=>{c&&clearTimeout(c),o?.signal?.removeEventListener("abort",p)};if(o?.signal?.aborted){d(this.opts.createRequestAbortError?.(e)??new Error(`gateway request aborted for ${e}`));return}u.cleanup=f,s!==void 0&&s>=0&&(c=setTimeout(()=>{this.pending.delete(r),o?.signal?.removeEventListener("abort",p),this.finishRequestTiming(r,u,!1,"CLIENT_TIMEOUT"),d(this.opts.createRequestTimeoutError?.(e,s)??new Error(`gateway request timed out after ${s}ms: ${e}`))},s),c.unref?.()),o?.signal?.addEventListener("abort",p,{once:!0}),this.pending.set(r,u);try{i.send(JSON.stringify({type:"req",id:r,method:e,params:n}))}catch(h){this.pending.delete(r),f(),this.finishRequestTiming(r,u,!1,"CLIENT_SEND_ERROR"),d(h instanceof Error?h:new Error(String(h)))}})}addEventListener(e){return this.listeners.add(e),()=>this.listeners.delete(e)}closeSocket(e,n){this.socket?.close(e,n)}resetReconnectBackoff(e){this.reconnectSupervisor.reset(e)}recordTiming(e,n,o,i){let r=this.nowMs(),s=this.connectTiming;!s||s.generation!==n||(s.hasChallenge||=e==="challenge",s.usedFallback||=e==="fallback",this.invoke("connect timing",()=>this.opts.onTiming?.({phase:e,generation:n,durationMs:Math.max(0,r-s.startedAtMs),phaseDurationMs:Math.max(0,r-s.lastAtMs),hasChallenge:s.hasChallenge,usedFallback:s.usedFallback,plan:o,detail:i})),s.lastAtMs=r,(e==="hello"||e==="failed")&&(this.connectTiming=null))}connect(){if(this.stopped)return;let e=this.generation+1;this.connectNonce=null,this.connectSent=!1,this.connectRequestSent=!1,this.socketOpened=!1,this.helloReceived=!1,this.connectFailure=void 0;let n;try{n=this.opts.createSocket({open:()=>this.handleOpen(n,e),message:i=>this.handleMessage(n,e,i),close:(i,r)=>this.handleClose(n,e,i,r),error:i=>this.handleSocketError(n,e,i)})}catch(i){let r=i instanceof Error?i:new Error(String(i));if(this.opts.onSocketFactoryError?.(r),this.opts.onConnectError?.(r),this.opts.rethrowSocketFactoryError?.(r))throw r;return}this.generation=e,this.socket=n;let o=this.nowMs();this.connectTiming={generation:e,startedAtMs:o,lastAtMs:o,hasChallenge:!1,usedFallback:!1}}handleOpen(e,n){if(this.isActive(e,n)){if(this.socketOpened=!0,this.recordTiming("socket-open",n),this.connectNonce){this.sendConnect(e,n);return}this.armHandshakeTimer(e,n)}}armHandshakeTimer(e,n){this.clearHandshakeTimer();let o=Date.now();this.handshakeTimer=setTimeout(()=>{if(this.handshakeTimer=null,!this.isActive(e,n)||this.connectSent||!e.isOpen())return;if(this.opts.handshake.mode==="fallback"){this.recordTiming("fallback",n),this.sendConnect(e,n);return}let i=Date.now()-o,r=new Error(this.opts.handshake.timeoutMessage?.(i)??`gateway connect challenge timeout after ${i}ms`);this.opts.onConnectError?.(r),e.close(1008,"connect challenge timeout")},this.opts.handshake.timeoutMs),this.handshakeTimer.unref?.()}sendConnect(e,n){if(!this.isActive(e,n)||!e.isOpen()||this.connectSent)return;this.connectSent=!0,this.clearHandshakeTimer();let o;try{o=this.opts.buildConnectPlan({nonce:this.connectNonce,generation:n})}catch(i){this.handleConnectPlanError(e,n,i);return}if(o instanceof Promise){o.then(i=>this.sendConnectPlan(e,n,i)).catch(i=>this.handleConnectPlanError(e,n,i));return}this.sendConnectPlan(e,n,o)}handleConnectPlanError(e,n,o){if(!this.isActive(e,n))return;let i=o instanceof Error?o:new Error(String(o)),r=this.opts.onConnectPlanError?.(i)??{closeCode:1008,closeReason:"connect failed"};this.opts.onConnectError?.(r.error??i),r.stop&&(this.stopped=!0),e.close(r.closeCode,r.closeReason)}sendConnectPlan(e,n,o){if(!this.isActive(e,n)||!e.isOpen())return;let i={generation:n,nonce:this.connectNonce,plan:o};this.recordTiming("connect-plan-ready",n,o),this.recordTiming("request-sent",n,o),this.connectRequestSent=!0,this.request("connect",this.opts.buildConnectParams(o)).then(r=>{this.isActive(e,n)&&(this.helloReceived=!0,this.connectFailure=void 0,this.reconnectSupervisor.reset(),this.recordTiming("hello",n,o),this.opts.onConnectHello?.(r,i),this.invoke("hello",()=>this.opts.onHello?.(r)))}).catch(r=>{if(!this.isActive(e,n))return;let s=r instanceof G?r:new G({message:String(r)}),l=this.opts.onConnectFailure?.(s,i)??{closeCode:1008,closeReason:"connect failed"};this.connectFailure={error:s,reconnectDelayMs:l.reconnectDelayMs},l.stop&&(this.stopped=!0),e.close(l.closeCode,l.closeReason)})}handleMessage(e,n,o){if(!this.isActive(e,n))return;let i;try{i=JSON.parse(o)}catch(r){this.opts.onParseError?.(r);return}if(Ee(i)){if(this.opts.onActivity?.(),i.event==="connect.challenge"){let s=i.payload,l=typeof s?.nonce=="string"?s.nonce.trim():"";if(!l){if(this.opts.handshake.mode==="require-challenge"){let d=new Error("gateway connect challenge missing nonce");this.opts.onConnectError?.(d),e.close(1008,"connect challenge missing nonce")}return}this.connectNonce=l,this.recordTiming("challenge",n),this.sendConnect(e,n);return}let r=typeof i.seq=="number"?i.seq:null;if(r!==null){if(this.lastSeq!==null&&r>this.lastSeq+1){let s=this.lastSeq+1;this.invoke("gap",()=>this.opts.onGap?.({expected:s,received:r}))}this.lastSeq=r}this.invoke("event",()=>this.opts.onEvent?.(i));for(let s of this.listeners)this.invoke("event listener",()=>s(i));return}Ae(i)&&(this.opts.onActivity?.(),this.handleResponse(i))}handleResponse(e){let n=this.pending.get(e.id);if(!n)return;let o=e.payload?.status;if(n.expectFinal&&o==="accepted"){n.acceptedNotified||(n.acceptedNotified=!0,this.invoke("accepted",()=>n.onAccepted?.(e.payload)));return}if(this.pending.delete(e.id),n.cleanup?.(),e.ok){this.finishRequestTiming(e.id,n,!0),n.resolve(e.payload);return}this.finishRequestTiming(e.id,n,!1,e.error?.code),n.reject(this.opts.createRequestError?.(e.error??{})??new G(e.error??{}))}handleClose(e,n,o,i){if(this.socket!==e){if(this.stoppedSocket?.socket===e){let l={...this.stoppedSocket.context,code:o,reason:i};this.stoppedSocket=void 0,this.invoke("close",()=>this.opts.onClose?.(l,{retry:!1,notify:!0}))}return}this.socket=null,this.clearHandshakeTimer();let r={...this.closeContext(),code:o,reason:i,generation:n};this.connectFailure=void 0;let s=this.opts.resolveClose(r);this.flushRequests(s.pendingError??r.connectFailure?.error??new Error(`gateway closed (${o}): ${i}`)),this.invoke("close",()=>this.opts.onClose?.(r,s)),s.retry&&!this.stopped&&this.scheduleReconnect(s.reconnectDelayMs??r.connectFailure?.reconnectDelayMs)}handleSocketError(e,n,o){!this.isActive(e,n)||this.connectSent||this.opts.onConnectError?.(o)}flushRequests(e){for(let[n,o]of this.pending)this.finishRequestTiming(n,o,!1,"CLIENT_CLOSED"),o.cleanup?.(),o.reject(e);this.pending.clear()}finishRequestTiming(e,n,o,i){let r=this.nowMs();this.invoke("request timing",()=>this.opts.onRequestTiming?.({id:e,method:n.method,ok:o,durationMs:Math.max(0,r-n.startedAtMs),startedAtMs:n.startedAtMs,endedAtMs:r,errorCode:i}))}scheduleReconnect(e){e!==void 0&&(this.reconnectSupervisor.nextDelayOverrideMs=e);let n=this.reconnectSupervisor.next();n&&ge(n.delayMs,n.signal).then(()=>this.connect(),()=>{})}closeContext(){return{generation:this.generation,socketOpened:this.socketOpened,helloReceived:this.helloReceived,connectRequestSent:this.connectRequestSent,connectFailure:this.connectFailure}}isActive(e,n){return!this.stopped&&this.socket===e&&this.generation===n}nowMs(){return this.opts.nowMs?.()??Date.now()}clearHandshakeTimer(){this.handshakeTimer&&(clearTimeout(this.handshakeTimer),this.handshakeTimer=null)}invoke(e,n){try{n()}catch(o){this.opts.onCallbackError?.(e,o)}}};var Bt=new Set([g.AUTH_TOKEN_MISSING,g.AUTH_BOOTSTRAP_TOKEN_INVALID,g.AUTH_PASSWORD_MISSING,g.AUTH_PASSWORD_MISMATCH,g.AUTH_RATE_LIMITED,g.AUTH_DEVICE_TOKEN_MISMATCH,g.AUTH_SCOPE_MISMATCH,g.PAIRING_REQUIRED,g.CONTROL_UI_DEVICE_IDENTITY_REQUIRED,g.DEVICE_IDENTITY_REQUIRED]);var Re={WEBCHAT_UI:"webchat-ui",CONTROL_UI:"openclaw-control-ui",BROWSER_COPILOT:"openclaw-browser-copilot",TUI:"openclaw-tui",WEBCHAT:"webchat",CLI:"cli",GATEWAY_CLIENT:"gateway-client",MACOS_APP:"openclaw-macos",IOS_APP:"openclaw-ios",WATCHOS_APP:"openclaw-watchos",ANDROID_APP:"openclaw-android",NODE_HOST:"node-host",WORKER:"openclaw-worker",TEST:"test",FINGERPRINT:"fingerprint",PROBE:"openclaw-probe"};var Ie={WEBCHAT:"webchat",CLI:"cli",UI:"ui",BACKEND:"backend",NODE:"node",WORKER:"worker",PROBE:"probe",TEST:"test"},et={APPROVALS:"approvals",EXEC_APPROVALS:"exec-approvals",INLINE_WIDGETS:"inline-widgets",RUN_TOOL_BINDINGS:"run-tool-bindings",SESSION_SCOPED_EVENTS:"session-scoped-events",PLUGIN_APPROVALS:"plugin-approvals",TASK_SUGGESTIONS:"task-suggestions",TERMINAL_OFFSET_SEQ:"terminal-offset-seq",TOOL_EVENTS:"tool-events",UI_COMMANDS:"ui-commands"},Vt=new Set(Object.values(Re)),Yt=new Set(Object.values(Ie));var tt=4,nt=4;/*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) */var Pe=Object.freeze({p:0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn,n:0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3edn,h:8n,a:0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecn,d:0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3n,Gx:0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51an,Gy:0x6666666666666666666666666666666666666666666666666666666666666658n}),{p:W,n:Y,Gx:Ce,Gy:Se,a:ne,d:oe,h:ot}=Pe,U=32,rt=(...t)=>{"captureStackTrace"in Error&&typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(...t)},T=(t="")=>{let e=new Error(t);throw rt(e,T),e},it=t=>typeof t=="bigint",st=t=>typeof t=="string",at=t=>t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"&&"BYTES_PER_ELEMENT"in t&&t.BYTES_PER_ELEMENT===1,R=(t,e,n="")=>{let o=at(t),i=t?.length,r=e!==void 0;if(!o||r&&i!==e){let s=n&&`"${n}" `,l=r?` of length ${e}`:"",d=o?`length=${i}`:`type=${typeof t}`,c=s+"expected Uint8Array"+l+", got "+d;throw o?new RangeError(c):new TypeError(c)}return t},z=t=>new Uint8Array(t),ce=t=>Uint8Array.from(t),De=(t,e)=>t.toString(16).padStart(e,"0"),Ne=t=>Array.from(R(t)).map(e=>De(e,2)).join(""),I={_0:48,_9:57,A:65,F:70,a:97,f:102},ve=t=>{if(t>=I._0&&t<=I._9)return t-I._0;if(t>=I.A&&t<=I.F)return t-(I.A-10);if(t>=I.a&&t<=I.f)return t-(I.a-10)},xe=t=>{let e="hex invalid";if(!st(t))return T(e);let n=t.length,o=n/2;if(n%2)return T(e);let i=z(o);for(let r=0,s=0;r<o;r++,s+=2){let l=ve(t.charCodeAt(s)),d=ve(t.charCodeAt(s+1));if(l===void 0||d===void 0)return T(e);i[r]=l*16+d}return i},Oe=()=>globalThis?.crypto,ct=()=>Oe()?.subtle??T("crypto.subtle must be defined, consider polyfill"),H=(...t)=>{let e=0;for(let i of t)e+=R(i).length;let n=z(e),o=0;return t.forEach(i=>{n.set(i,o),o+=i.length}),n},dt=(t=U)=>Oe().getRandomValues(z(t)),K=BigInt,w=(t,e,n,o="bad number: out of range")=>{if(!it(t))throw new TypeError(o);if(e<=t&&t<n)return t;throw new RangeError(o)},y=(t,e=W)=>{let n=t%e;return n>=0n?n:e+n},be=(1n<<255n)-1n,a=t=>{t<0n&&T("negative coordinate");let e=(t>>255n)*19n+(t&be);return e=(e>>255n)*19n+(e&be),e%W},Ge=t=>y(t,Y),lt=(t,e)=>{(t===0n||e<=0n)&&T("no inverse n="+t+" mod="+e);let n=y(t,e),o=e,i=0n,r=1n,s=1n,l=0n;for(;n!==0n;){let d=o/n,c=o%n,u=i-s*d,p=r-l*d;o=n,n=c,i=s,r=l,s=u,l=p}return o===1n?y(i,e):T("no inverse")},Ue=t=>{let e=At[t];return typeof e!="function"&&T("hashes."+t+" not set"),e},qe=t=>R(t,64,"digest");var re=t=>t instanceof k?t:T("Point expected"),ie=2n**256n,k=class t{static BASE;static ZERO;X;Y;Z;T;constructor(e,n,o,i){let r=ie;this.X=w(e,0n,r),this.Y=w(n,0n,r),this.Z=w(o,1n,r),this.T=w(i,0n,r),Object.freeze(this)}static CURVE(){return Pe}static fromAffine(e){return new t(e.x,e.y,1n,a(e.x*e.y))}static fromBytes(e,n=!1){let o=oe,i=ce(R(e,U)),r=e[31];i[31]=r&-129;let s=Le(i);w(s,0n,n?ie:W);let d=a(s*s),c=y(d-1n),u=a(o*d+1n),{isValid:p,value:f}=pt(c,u);p||T("bad point: y not sqrt");let h=(f&1n)===1n,m=(r&128)!==0;return!n&&f===0n&&m&&T("bad point: x==0, isLastByteOdd"),m!==h&&(f=y(-f)),new t(f,s,1n,a(f*s))}static fromHex(e,n){return t.fromBytes(xe(e),n)}get x(){return this.toAffine().x}get y(){return this.toAffine().y}assertValidity(){let e=ne,n=oe,o=this;if(o.is0())return T("bad point: ZERO");let{X:i,Y:r,Z:s,T:l}=o,d=a(i*i),c=a(r*r),u=a(s*s),p=a(u*u),f=a(d*e),h=a(u*(f+c)),m=y(p+a(n*a(d*c)));if(h!==m)return T("bad point: equation left != right (1)");let C=a(i*r),S=a(s*l);return C!==S?T("bad point: equation left != right (2)"):this}equals(e){let{X:n,Y:o,Z:i}=this,{X:r,Y:s,Z:l}=re(e),d=a(n*l),c=a(r*i),u=a(o*l),p=a(s*i);return d===c&&u===p}is0(){return this.equals(M)}negate(){return new t(y(-this.X),this.Y,this.Z,y(-this.T))}double(){let{X:e,Y:n,Z:o}=this,i=ne,r=a(e*e),s=a(n*n),l=a(2n*o*o),d=a(i*r),c=y(e+n),u=y(a(c*c)-r-s),p=y(d+s),f=y(p-l),h=y(d-s),m=a(u*f),C=a(p*h),S=a(u*h),D=a(f*p);return new t(m,C,D,S)}add(e){let{X:n,Y:o,Z:i,T:r}=this,{X:s,Y:l,Z:d,T:c}=re(e),u=ne,p=oe,f=a(n*s),h=a(o*l),m=a(a(r*p)*c),C=a(i*d),S=y(a(y(n+o)*y(s+l))-f-h),D=y(C-m),E=y(C+m),A=y(h-a(u*f)),N=a(S*D),x=a(E*A),O=a(S*A),L=a(D*E);return new t(N,x,L,O)}subtract(e){return this.add(re(e).negate())}multiply(e,n=!0){if(!n&&e===0n||(w(e,1n,Y),!n&&this.is0()))return M;if(e===1n)return this;if(this.equals(P))return Ct(e).p;let o=M,i=P;for(let r=this;e>0n;r=r.double(),e>>=1n)e&1n?o=o.add(r):n&&(i=i.add(r));return o}multiplyUnsafe(e){return this.multiply(e,!1)}toAffine(){let{X:e,Y:n,Z:o}=this;if(this.equals(M))return{x:0n,y:1n};let i=lt(o,W);a(o*i)!==1n&&T("invalid inverse");let r=a(e*i),s=a(n*i);return{x:r,y:s}}toBytes(){let{x:e,y:n}=this.toAffine(),o=He(n);return o[31]|=e&1n?128:0,o}toHex(){return Ne(this.toBytes())}clearCofactor(){return this.multiply(K(ot),!1)}isSmallOrder(){return this.clearCofactor().is0()}isTorsionFree(){let e=this.multiply(Y/2n,!1).double();return Y%2n&&(e=e.add(this)),e.is0()}},P=new k(Ce,Se,1n,y(Ce*Se)),M=new k(0n,1n,1n,0n);k.BASE=P;k.ZERO=M;var He=t=>xe(De(w(t,0n,ie),64)).reverse(),Le=t=>K("0x"+Ne(ce(R(t)).reverse())),_=(t,e)=>{let n=t;for(;e-- >0n;)n=a(n*n);return n},ut=t=>{let e=a(t*t),n=a(e*t),o=a(_(n,2n)*n),i=a(_(o,1n)*t),r=a(_(i,5n)*i),s=a(_(r,10n)*r),l=a(_(s,20n)*s),d=a(_(l,40n)*l),c=a(_(d,80n)*d),u=a(_(c,80n)*d),p=a(_(u,10n)*r);return{pow_p_5_8:a(_(p,2n)*t),b2:n}},we=0x2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0n,pt=(t,e)=>{let n=a(e*a(e*e)),o=a(a(n*n)*e),i=ut(a(t*o)).pow_p_5_8,r=a(t*a(n*i)),s=a(e*a(r*r)),l=r,d=a(r*we),c=s===t,u=s===y(-t),p=s===y(-t*we);return c&&(r=l),(u||p)&&(r=d),(y(r)&1n)===1n&&(r=y(-r)),{isValid:c||u,value:r}},se=t=>Ge(Le(t)),de=(...t)=>Promise.resolve(Ue("sha512Async")(H(...t))).then(qe),ft=(...t)=>qe(Ue("sha512")(H(...t))),Be=t=>{let e=ce(t),n=e.slice(0,32);n[0]&=248,n[31]&=127,n[31]|=64;let o=e.slice(32,64),i=se(n),r=P.multiply(i),s=r.toBytes();return{head:n,prefix:o,scalar:i,point:r,pointBytes:s}},le=t=>de(R(t,U)).then(Be),yt=t=>Be(ft(R(t,U))),ht=t=>le(t).then(e=>e.pointBytes);var Tt=t=>de(t.hashable).then(t.finish);var mt=(t,e,n)=>{let{pointBytes:o,scalar:i}=t,r=se(e),s=P.multiply(r).toBytes();return{hashable:H(s,o,n),finish:c=>{let u=Ge(r+se(c)*i);return R(H(s,He(u)),64)}}},Et=async(t,e)=>{let n=R(t),o=await le(e),i=await de(o.prefix,n);return Tt(mt(o,i,n))};var At={sha512Async:async t=>{let e=ct(),n=H(t);return z(await e.digest("SHA-512",n.buffer))},sha512:void 0},gt=t=>(t=t===void 0?dt(U):t,R(t,U));var _t=Object.freeze({getExtendedPublicKeyAsync:le,getExtendedPublicKey:yt,randomSecretKey:gt}),X=8,Rt=256,Fe=Math.ceil(Rt/X)+1,ae=2**(X-1),It=()=>{let t=[],e=P,n=e;for(let o=0;o<Fe;o++){n=e,t.push(n);for(let i=1;i<ae;i++)n=n.add(e),t.push(n);e=n.double()}return t},Me,ke=(t,e)=>{let n=e.negate();return t?n:e},Ct=t=>{let e=Me||(Me=It()),n=M,o=P,i=2**X,r=i,s=K(i-1),l=K(X);for(let d=0;d<Fe;d++){let c=Number(t&s);t>>=l,c>ae&&(c-=r,t+=1n);let u=d*ae,p=u,f=u+Math.abs(c)-1,h=d%2!==0,m=c<0;c===0?o=o.add(ke(h,e[p])):n=n.add(ke(m,e[f]))}return t!==0n&&T("invalid wnaf"),{p:n,f:o}};export{et as GATEWAY_CLIENT_CAPS,Re as GATEWAY_CLIENT_IDS,Ie as GATEWAY_CLIENT_MODES,Q as GatewayBrowserDeviceAuthLifecycle,te as GatewayProtocolClient,G as GatewayProtocolRequestError,nt as MIN_CLIENT_PROTOCOL_VERSION,tt as PROTOCOL_VERSION,_t as ed25519Utils,ht as getPublicKeyAsync,Et as signAsync};
|