clawpad 0.4.14 → 0.4.16
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +7 -7
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_global-error.html +2 -2
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/ai/write/route.js +2 -2
- package/.next/standalone/.next/server/app/api/chat/route.js +3 -3
- package/.next/standalone/.next/server/app/api/gateway/detect/route.js +2 -2
- package/.next/standalone/.next/server/app/api/gateway/history/route.js +1 -1
- package/.next/standalone/.next/server/app/api/gateway/sessions/route.js +1 -2
- package/.next/standalone/.next/server/app/api/gateway/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/gateway/status/route.js +2 -2
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/connection.html +1 -1
- package/.next/standalone/.next/server/app/settings/connection.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/connection.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/connection.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/connection.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/connection.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/connection.segments/settings/connection/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/connection.segments/settings/connection.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/connection.segments/settings.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/relay.html +1 -1
- package/.next/standalone/.next/server/app/settings/relay.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/relay.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/relay.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/relay.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/relay.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/relay.segments/settings/relay/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/relay.segments/settings/relay.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings/relay.segments/settings.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.html +1 -1
- package/.next/standalone/.next/server/app/settings.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.html +1 -1
- package/.next/standalone/.next/server/app/setup.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.segments/setup.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/waitlist.html +1 -1
- package/.next/standalone/.next/server/app/waitlist.rsc +1 -1
- package/.next/standalone/.next/server/app/waitlist.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/waitlist.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/waitlist.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/waitlist.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/waitlist.segments/waitlist/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/waitlist.segments/waitlist.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspace/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspace/search/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspace/search.html +2 -2
- package/.next/standalone/.next/server/app/workspace/search.rsc +2 -2
- package/.next/standalone/.next/server/app/workspace/search.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/workspace/search.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace/search.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace/search.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace/search.segments/workspace/search/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace/search.segments/workspace/search.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace/search.segments/workspace.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/workspace.html +2 -2
- package/.next/standalone/.next/server/app/workspace.rsc +2 -2
- package/.next/standalone/.next/server/app/workspace.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/workspace.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace.segments/workspace/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/workspace.segments/workspace.segment.rsc +2 -2
- package/.next/standalone/.next/server/app-paths-manifest.json +7 -7
- package/.next/standalone/.next/server/chunks/1210.js +2 -2
- package/.next/standalone/.next/server/chunks/3251.js +1 -1
- package/.next/standalone/.next/server/chunks/8353.js +1 -1
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +2 -2
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/package.json +1 -1
- package/.next/static/chunks/app/workspace/{layout-10e6e52da47d81e4.js → layout-be10d7f09b35ca6d.js} +1 -1
- package/bin/clawpad.js +6 -0
- package/package.json +1 -1
- /package/.next/static/{1E6zfk_m1pZXKb_d0xUT- → MLsn_n4XcPWPE4HF1L3qC}/_buildManifest.js +0 -0
- /package/.next/static/{1E6zfk_m1pZXKb_d0xUT- → MLsn_n4XcPWPE4HF1L3qC}/_ssgManifest.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"/_not-found/page": "app/_not-found/page.js",
|
|
3
|
-
"/api/ai/write/route": "app/api/ai/write/route.js",
|
|
4
3
|
"/_global-error/page": "app/_global-error/page.js",
|
|
4
|
+
"/api/ai/write/route": "app/api/ai/write/route.js",
|
|
5
5
|
"/api/chat/abort/route": "app/api/chat/abort/route.js",
|
|
6
6
|
"/api/chat/route": "app/api/chat/route.js",
|
|
7
7
|
"/api/files/pages/[...path]/route": "app/api/files/pages/[...path]/route.js",
|
|
@@ -13,24 +13,24 @@
|
|
|
13
13
|
"/api/gateway/config/route": "app/api/gateway/config/route.js",
|
|
14
14
|
"/api/gateway/detect/route": "app/api/gateway/detect/route.js",
|
|
15
15
|
"/api/gateway/features/route": "app/api/gateway/features/route.js",
|
|
16
|
-
"/api/gateway/resolve/route": "app/api/gateway/resolve/route.js",
|
|
17
16
|
"/api/gateway/history/route": "app/api/gateway/history/route.js",
|
|
18
|
-
"/api/gateway/
|
|
17
|
+
"/api/gateway/resolve/route": "app/api/gateway/resolve/route.js",
|
|
19
18
|
"/api/gateway/status/route": "app/api/gateway/status/route.js",
|
|
19
|
+
"/api/gateway/sessions/route": "app/api/gateway/sessions/route.js",
|
|
20
20
|
"/api/openclaw/commands/route": "app/api/openclaw/commands/route.js",
|
|
21
21
|
"/api/search/route": "app/api/search/route.js",
|
|
22
22
|
"/api/settings/search-status/route": "app/api/settings/search-status/route.js",
|
|
23
|
-
"/api/setup/bootstrap/route": "app/api/setup/bootstrap/route.js",
|
|
24
|
-
"/api/setup/status/route": "app/api/setup/status/route.js",
|
|
25
23
|
"/api/setup/bootstrap-workspace/route": "app/api/setup/bootstrap-workspace/route.js",
|
|
24
|
+
"/api/setup/status/route": "app/api/setup/status/route.js",
|
|
25
|
+
"/api/setup/bootstrap/route": "app/api/setup/bootstrap/route.js",
|
|
26
26
|
"/api/setup/trigger-onboarding/route": "app/api/setup/trigger-onboarding/route.js",
|
|
27
27
|
"/api/version/route": "app/api/version/route.js",
|
|
28
28
|
"/favicon.ico/route": "app/favicon.ico/route.js",
|
|
29
29
|
"/api/changes/[id]/route": "app/api/changes/[id]/route.js",
|
|
30
|
+
"/api/changes/run/route": "app/api/changes/run/route.js",
|
|
30
31
|
"/api/changes/route": "app/api/changes/route.js",
|
|
31
|
-
"/api/changes/revert/route": "app/api/changes/revert/route.js",
|
|
32
32
|
"/api/changes/record/route": "app/api/changes/record/route.js",
|
|
33
|
-
"/api/changes/
|
|
33
|
+
"/api/changes/revert/route": "app/api/changes/revert/route.js",
|
|
34
34
|
"/api/gateway/events/route": "app/api/gateway/events/route.js",
|
|
35
35
|
"/page": "app/page.js",
|
|
36
36
|
"/settings/connection/page": "app/settings/connection/page.js",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";exports.id=1210,exports.ids=[1210],exports.modules={81210:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{t:()=>m});var e=c(48161),f=c.n(e),g=c(56220),h=c(94615),i=a([g]);g=(i.then?(await i)():i)[0];let j={id:"webchat-ui",version:"clawpad",platform:"web",mode:"webchat"},k=["operator.read","operator.write","operator.admin"];class l{get status(){return this._status}getLastError(){return this.lastError}getLastErrorCode(){return this.lastErrorCode}getFeatures(){return this.features}async connect(a,b){if(a&&this.applyPreferredGatewayUrl(a),arguments.length>=2){let a=this.normalizeToken(b);this.configuredToken=a,this.token=a}"connected"!==this._status&&"connecting"!==this._status&&this.doConnect()}disconnect(a){this.cancelReconnect(),this.reconnectAttempts=0,this.ws&&(this.ws.removeAllListeners(),this.ws.close(),this.ws=null),this.setStatus("disconnected"),a?.reconnect&&this.scheduleReconnect(a.reason)}onEvent(a){return this.eventListeners.add(a),()=>{this.eventListeners.delete(a)}}onStatus(a){return this.statusListeners.add(a),a(this._status),()=>{this.statusListeners.delete(a)}}get listenerCount(){return this.eventListeners.size}sendRPC(a,b,c=3e4){return new Promise((d,e)=>{if("connected"!==this._status||!this.ws)return void e(Error(`Cannot send RPC: WS status is "${this._status}"`));let f=String(++this.requestId),g=setTimeout(()=>{this.pendingRPC.delete(f),e(Error(`RPC "${a}" timed out after ${c}ms`))},c);this.pendingRPC.set(f,{resolve:d,reject:e,timer:g});try{this.ws.send(JSON.stringify({type:"req",id:f,method:a,params:b}))}catch(a){this.pendingRPC.delete(f),clearTimeout(g),e(Error(`Failed to send RPC: ${a}`))}})}async ensureConnected(a=1e4){if("connected"!==this._status){if("disconnected"===this._status){let{detectGateway:a}=await c.e(4526).then(c.bind(c,4526)),b=await a();if(b){let a=b.url.replace(/^http/,"ws");await this.connect(a,b.token)}}return new Promise((b,c)=>{if("connected"===this._status)return void b();let d=setTimeout(()=>{e(),c(Error("WS connect timed out"))},a),e=this.onStatus(a=>{"connected"===a&&(clearTimeout(d),e(),b())})})}}normalizeToken(a){return a?.trim()||void 0}buildOrigin(a){if(!a)return null;let b=a.replace(/^ws/i,"http");try{return new URL(b).origin}catch{return null}}normalizeHost(a){return a.trim().toLowerCase()}getLocalHostAliases(){let a=Date.now();if(this.localHostAliases&&a-this.localHostAliasesAtMs<6e4)return this.localHostAliases;let b=new Set(["localhost","127.0.0.1","::1"]),c=this.normalizeHost(f().hostname());for(let a of(c&&(b.add(c),b.add(`${c}.local`)),Object.values(f().networkInterfaces())))for(let c of a??[]){let a=this.normalizeHost(c.address??"");a&&b.add(a)}return this.localHostAliases=b,this.localHostAliasesAtMs=a,b}resolveLoopbackUrl(a){if(!a)return null;let b=a.replace(/^ws/i,"http");try{let a=new URL(b),c=this.normalizeHost(a.hostname);if(!c||"localhost"===c||"127.0.0.1"===c||"::1"===c||!this.getLocalHostAliases().has(c))return null;let d="https:"===a.protocol?"https:":"http:",e=a.port||("https:"===d?"443":"80"),f=a.pathname&&"/"!==a.pathname?a.pathname:"";return`${d}//127.0.0.1:${e}${f}${a.search}`}catch{return null}}applyPreferredGatewayUrl(a){let b=a.trim();if(!b)return;this.configuredUrl=b;let c=this.resolveLoopbackUrl(b);if(c&&c!==b){this.url=c,this.fallbackUrl=b;return}this.url=b,this.fallbackUrl=null}isAuthError(a,b){let c=(a??"").toUpperCase();if("NOT_PAIRED"===c||"AUTH_REQUIRED"===c||"UNAUTHORIZED"===c)return!0;let d=(b??"").toLowerCase();return!!d&&(d.includes("device identity required")||d.includes("not paired"))}async refreshConfig(a){let b=Date.now();return this.configRefreshInFlight?this.configRefreshInFlight:b-this.lastConfigRefreshAt<5e3?void 0:(this.configRefreshInFlight=(async()=>{this.lastConfigRefreshAt=Date.now();try{let{detectGateway:a}=await c.e(4526).then(c.bind(c,4526)),b=await a();if(b){this.applyPreferredGatewayUrl(b.url);let a=this.normalizeToken(b.token);this.configuredToken=a,this.token=a}}catch(b){console.warn("[gateway-ws] Config refresh failed:",a,b)}finally{this.configRefreshInFlight=null}})(),this.configRefreshInFlight)}setStatus(a){if(this._status!==a)for(let b of(this._status=a,"connected"===a&&(this.reconnectAttempts=0),this.statusListeners))try{b(a)}catch{}}doConnect(){this.setStatus("connecting");let a=!1;try{let a=this.url.replace(/^http/,"ws"),b=this.buildOrigin(this.url);this.ws=new g.default(a,b?{origin:b}:void 0)}catch(a){console.error("[gateway-ws] Failed to create WebSocket:",a),this.scheduleReconnect();return}this.ws.on("open",()=>{a=!0,console.log("[gateway-ws] WebSocket opened, waiting for challenge..."),this.lastPongAt=Date.now(),this.pingInterval||(this.pingInterval=setInterval(()=>{if(this.ws){if(Date.now()-this.lastPongAt>6e4){try{this.ws.terminate()}catch{}return}try{this.ws.ping()}catch{}}},3e4))}),this.ws.on("message",a=>{this.handleMessage(String(a))}),this.ws.on("error",a=>{console.error("[gateway-ws] WebSocket error:",a.message),this.lastError=a.message,this.lastErrorCode=null}),this.ws.on("close",()=>{for(let[a,b]of(this.ws=null,this.pingInterval&&(clearInterval(this.pingInterval),this.pingInterval=null),this.pendingRPC))clearTimeout(b.timer),b.reject(Error("WebSocket closed"));this.pendingRPC.clear(),!a&&this.fallbackUrl&&this.url!==this.fallbackUrl&&(this.lastError="localhost probe failed; retrying configured gateway address",this.lastErrorCode="GATEWAY_URL_FALLBACK",this.url=this.fallbackUrl,this.fallbackUrl=null,this.lastAuthRetryAt=null),this.setStatus("disconnected"),this.scheduleReconnect()}),this.ws.on("pong",()=>{this.lastPongAt=Date.now()})}handleMessage(a){let b;try{b=JSON.parse(a)}catch{console.warn("[gateway-ws] Failed to parse frame:",a.slice(0,200));return}if("event"===b.type){let a=b;if("connect.challenge"===a.event){console.log("[gateway-ws] Received challenge, sending connect...");let b=a.payload;this.handleChallenge(b.nonce);return}for(let b of this.eventListeners)try{b(a)}catch(a){console.error("[gateway-ws] Listener error:",a)}}else if("res"===b.type){let a=b,c=this.pendingRPC.get(a.id);if(c){this.pendingRPC.delete(a.id),clearTimeout(c.timer),a.ok?c.resolve(a.payload):c.reject(Error(`RPC error: ${JSON.stringify(a.error)}`));return}if(a.ok){console.log("[gateway-ws] Connected to gateway, payload:",JSON.stringify(a.payload)),this.lastError=null,this.lastErrorCode=null,this.lastAuthError=null,this.lastAuthErrorAt=null,this.lastAuthRetryAt=null;let b=a.payload&&"object"==typeof a.payload?a.payload:void 0,c="string"==typeof b?.auth?.deviceToken?b.auth.deviceToken:null,d="string"==typeof b?.auth?.role?b.auth.role:"operator",e=Array.isArray(b?.auth?.scopes)?b.auth.scopes.filter(a=>"string"==typeof a):[],f=!(e.length>0)||(0,h.PP)(e,h.qq);if(c){let a=(0,h.aZ)();f?((0,h.HQ)({deviceId:a.deviceId,role:d,token:c,scopes:e,gatewayUrl:this.url}),this.token=c):(0,h.Sm)({deviceId:a.deviceId,role:d,gatewayUrl:this.url,includeLegacyRoleEntry:!0})}if(f)this.lastScopeRecoveryAt=null;else{let a=new Set(e.map(a=>a.toLowerCase())),b=h.qq.filter(b=>!a.has(b)),c=`gateway issued device token without required scopes (${b.join(", ")||"unknown"})`;this.lastError=c,this.lastErrorCode="MISSING_SCOPE";let d=Date.now();if(!this.lastScopeRecoveryAt||d-this.lastScopeRecoveryAt>6e4){this.lastScopeRecoveryAt=d,this.forceConfigTokenOnNextChallenge=!0,console.warn("[gateway-ws] Missing required scopes in issued token. Retrying with configured token."),this.disconnect({reconnect:!0,reason:"scope-recovery"});return}console.warn("[gateway-ws] Missing required scopes in issued token; recovery recently attempted.")}this.updateFeatures(a.payload),this.setStatus("connected")}else{let b=a.error?.code,c=a.error?.message??"connect rejected",d=(()=>{let b=a.error;if(b&&"object"==typeof b){if(b.details&&"object"==typeof b.details)return b.details;if(b.data&&"object"==typeof b.data&&"details"in b.data&&"object"==typeof b.data.details)return b.data.details}})(),e="string"==typeof d?.code?d.code.trim().toUpperCase():void 0,f="string"==typeof d?.requestId&&d.requestId.trim()?d.requestId.trim():void 0,g="string"==typeof b?b:"number"==typeof b?String(b):null;console.error("[gateway-ws] Connect rejected:",a.error);let i=(g??"").toUpperCase();if(this.lastError=c,this.lastErrorCode=g,this.isAuthError(g,c)){if(this.lastAuthError=c,this.lastAuthErrorAt=Date.now(),"stored"===this.lastConnectTokenSource){let a=(0,h.aZ)();(0,h.Sm)({deviceId:a.deviceId,role:"operator",gatewayUrl:this.url,includeLegacyRoleEntry:!0}),this.configuredToken&&this.configuredToken!==this.lastConnectToken&&(this.forceConfigTokenOnNextChallenge=!0,this.token=this.configuredToken,this.lastError="cached device token rejected; retrying with gateway token",this.lastErrorCode="AUTH_RECOVERY")}if("NOT_PAIRED"===i)if("PAIRING_REQUIRED"===e||c.toLowerCase().includes("pairing required")){let a=this.resolveLoopbackUrl(this.configuredUrl);a&&a!==this.url?(this.fallbackUrl=this.configuredUrl,this.url=a,this.lastError="pairing required on gateway address; retrying localhost",this.lastErrorCode="PAIRING_LOCAL_RETRY",this.lastAuthRetryAt=null):(this.configuredToken,this.lastError=f?`pairing required (request ${f})`:"pairing required")}else"DEVICE_IDENTITY_REQUIRED"===e&&(this.lastError=this.configuredToken?"device identity required":"device identity required (gateway token not detected)",this.lastErrorCode="DEVICE_IDENTITY_REQUIRED");else"AUTH_REQUIRED"!==i||this.configuredToken||(this.lastError="gateway token missing")}this.disconnect({reconnect:!0,reason:"connect-rejected"})}}}async handleChallenge(a){if(!this.ws)return;this.token||this.configuredToken||await this.refreshConfig("challenge");let b="operator",c=(0,h.aZ)(),d=this.normalizeToken(this.configuredToken??this.token),e=this.forceConfigTokenOnNextChallenge?void 0:(0,h.vM)({deviceId:c.deviceId,role:b,gatewayUrl:this.url,requiredScopes:h.qq})?.token,f=this.normalizeToken(e??d);this.forceConfigTokenOnNextChallenge=!1,f||(this.lastAuthError="token missing",this.lastAuthErrorAt=Date.now(),this.lastError="device identity required",this.lastErrorCode="AUTH_REQUIRED");let g="string"==typeof a&&a.trim()?a.trim():void 0,i=(0,h.n3)({identity:c,clientId:j.id,clientMode:j.mode,role:b,scopes:k,token:f,nonce:g}),l={type:"req",id:String(++this.requestId),method:"connect",params:{minProtocol:3,maxProtocol:3,client:j,role:b,scopes:k,caps:[],commands:[],permissions:{},auth:f?{token:f}:{},device:i}};this.token=f,this.lastConnectToken=f,this.lastConnectTokenSource=e?"stored":f?"config":"none";try{this.ws.send(JSON.stringify(l))}catch(a){console.error("[gateway-ws] Failed to send connect:",a)}}updateFeatures(a){if(!a||"object"!=typeof a)return;let b=a.features;if(!b||"object"!=typeof b)return;let c=b.methods,d=b.events,e=Array.isArray(c)?c.filter(a=>"string"==typeof a):[],f=Array.isArray(d)?d.filter(a=>"string"==typeof a):[];(e.length||f.length)&&(this.features={methods:e,events:f})}scheduleReconnect(a){if("connected"===this._status||"connecting"===this._status)return;this.cancelReconnect(),this.setStatus("reconnecting");let b=Date.now();if(this.isAuthError(this.lastErrorCode,this.lastError)){let a=this.token&&this.token!==this.lastConnectToken;if(this.lastAuthRetryAt&&b-this.lastAuthRetryAt<3e4&&!a)return;this.lastAuthRetryAt=b}let c=this.reconnectAttempts,d=Math.min(3e4,2e3*Math.pow(1.8,c)),e=.25*d*(2*Math.random()-1),f=Math.max(500,Math.round(d+e));this.reconnectAttempts+=1,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,"disconnected"===this._status&&(this.reconnectInFlight||(this.reconnectInFlight=!0,this.refreshConfig("reconnect").catch(()=>{}).finally(()=>{this.reconnectInFlight=!1,"disconnected"===this._status&&this.doConnect()})))},f)}cancelReconnect(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}constructor(){this.ws=null,this._status="disconnected",this.configuredUrl="http://127.0.0.1:18789",this.fallbackUrl=null,this.localHostAliases=null,this.localHostAliasesAtMs=0,this.url="http://127.0.0.1:18789",this.reconnectTimer=null,this.requestId=0,this.lastError=null,this.lastErrorCode=null,this.lastAuthError=null,this.lastAuthErrorAt=null,this.lastAuthRetryAt=null,this.lastConnectTokenSource="none",this.configRefreshInFlight=null,this.lastConfigRefreshAt=0,this.reconnectInFlight=!1,this.reconnectAttempts=0,this.pingInterval=null,this.lastPongAt=0,this.features=null,this.forceConfigTokenOnNextChallenge=!1,this.lastScopeRecoveryAt=null,this.eventListeners=new Set,this.statusListeners=new Set,this.pendingRPC=new Map}}let m=new l;d()}catch(a){d(a)}})},94615:(a,b,c)=>{c.d(b,{HQ:()=>G,PP:()=>x,Sm:()=>H,aZ:()=>u,n3:()=>C,qq:()=>l,vM:()=>F});var d=c(55511),e=c.n(d),f=c(29021),g=c.n(f),h=c(33873),i=c.n(h),j=c(27843);let k=Buffer.from("302a300506032b6570032100","hex"),l=["operator.read","operator.write"];function m(a=process.env){return i().join((0,j.We)(a),"identity")}function n(a=process.env){return i().join(m(a),"device-auth.json")}function o(a){return a.toString("base64").replaceAll("+","-").replaceAll("/","_").replace(/=+$/g,"")}function p(a){if("string"==typeof a)return a.trim()||void 0}function q(a){if("string"==typeof a)return a.trim().toLowerCase()||void 0}function r(a){let b=e().createPublicKey(a).export({type:"spki",format:"der"});return b.length===k.length+32&&b.subarray(0,k.length).equals(k)?b.subarray(k.length):b}function s(a){let b=r(a);return e().createHash("sha256").update(b).digest("hex")}function t(a,b){g().mkdirSync(i().dirname(a),{recursive:!0}),g().writeFileSync(a,`${JSON.stringify(b,null,2)}
|
|
2
|
-
`,{mode:384});try{g().chmodSync(a,384)}catch{}}function u(a=process.env){let b=function(a=process.env){return i().join(m(a),"device.json")}(a);try{if(g().existsSync(b)){let a=g().readFileSync(b,"utf8"),c=JSON.parse(a);if(c?.version===1&&"string"==typeof c.deviceId&&"string"==typeof c.publicKeyPem&&"string"==typeof c.privateKeyPem){let a=s(c.publicKeyPem);if(a!==c.deviceId)return t(b,{version:1,deviceId:a,publicKeyPem:c.publicKeyPem,privateKeyPem:c.privateKeyPem,createdAtMs:Date.now()}),{deviceId:a,publicKeyPem:c.publicKeyPem,privateKeyPem:c.privateKeyPem};return{deviceId:c.deviceId,publicKeyPem:c.publicKeyPem,privateKeyPem:c.privateKeyPem}}}}catch{}let c=function(){let{publicKey:a,privateKey:b}=e().generateKeyPairSync("ed25519"),c=a.export({type:"spki",format:"pem"}).toString(),d=b.export({type:"pkcs8",format:"pem"}).toString();return{deviceId:s(c),publicKeyPem:c,privateKeyPem:d}}();return t(b,{version:1,deviceId:c.deviceId,publicKeyPem:c.publicKeyPem,privateKeyPem:c.privateKeyPem,createdAtMs:Date.now()}),c}function v(a){let b=new Set,c=[];for(let d of a){let a=q(d);!a||b.has(a)||(b.add(a),c.push(a))}return c}function w(a){return v(a).sort()}function x(a,b=l){if(!Array.isArray(a)||0===a.length)return!1;let c=new Set;for(let b of a){let a=q(b);a&&c.add(a)}for(let a of b){let b=q(a);if(b&&!c.has(b))return!1}return!0}function y(a){if(!Array.isArray(a)||0===a.length)return 0;let b=new Set;for(let c of a){let a=q(c);a&&b.add(a)}let c=0;return b.has("operator.read")&&(c+=100),b.has("operator.write")&&(c+=200),b.has("operator.admin")&&(c+=30),b.has("operator.approvals")&&(c+=5),b.has("operator.pairing")&&(c+=5),c}function z(a){if(!a)return;let b=a.trim();if(b)try{let a=new URL(/^wss?:\/\//i.test(b)?b.replace(/^wss?/i,"http"):/^https?:\/\//i.test(b)?b:`http://${b}`),c=a.port||("https:"===a.protocol?"443":"80");return`${a.hostname.toLowerCase()}:${c}`}catch{return b.toLowerCase()}}function A(a,b){return b?`${a}::${b}`:a}function B(a,b){if(!b||"object"!=typeof b)return null;let c=function(a){let b=a.indexOf("::");if(-1===b)return{role:a.trim()};let c=a.slice(0,b).trim(),d=z(a.slice(b+2));return{role:c,...d?{gatewayKey:d}:{}}}(a),d=p(b.token);if(!d)return null;let e="string"==typeof b.role&&b.role.trim()?b.role.trim():c.role;if(!e)return null;let f=z("string"==typeof b.gatewayKey?b.gatewayKey:c.gatewayKey),g=Array.isArray(b.scopes)?b.scopes.filter(a=>"string"==typeof a):[],h="number"==typeof b.updatedAtMs&&Number.isFinite(b.updatedAtMs)?b.updatedAtMs:0;return{token:d,role:e,scopes:w(g),updatedAtMs:h,...f?{gatewayKey:f}:{}}}function C(a){var b,c;let d,f,g,h=v(a.scopes),i=Date.now(),j=(f=[d=(b={deviceId:a.identity.deviceId,clientId:a.clientId,clientMode:a.clientMode,role:a.role,scopes:h,signedAtMs:i,token:a.token,nonce:a.nonce}).nonce?"v2":"v1",b.deviceId,b.clientId,b.clientMode,b.role,b.scopes.join(","),String(b.signedAtMs),b.token??""],"v2"===d&&f.push(b.nonce??""),f.join("|"));return{id:a.identity.deviceId,publicKey:o(r(a.identity.publicKeyPem)),signature:(c=a.identity.privateKeyPem,g=e().createPrivateKey(c),o(e().sign(null,Buffer.from(j,"utf8"),g))),signedAt:i,...a.nonce?{nonce:a.nonce}:{}}}function D(a=process.env){let b=n(a);try{if(!g().existsSync(b))return null;let a=g().readFileSync(b,"utf8"),c=JSON.parse(a);if(!c||1!==c.version&&2!==c.version||"string"!=typeof c.deviceId||!c.tokens||"object"!=typeof c.tokens)return null;return c}catch{return null}}function E(a,b=process.env){t(n(b),a)}function F(a){let b=D(a.env);if(!b||b.deviceId!==a.deviceId)return null;let c=a.role.trim();if(!c)return null;let d=z(a.gatewayUrl),e=w((a.requiredScopes??[]).filter(a=>"string"==typeof a)),f=[];for(let[a,g]of Object.entries(b.tokens)){let b=B(a,g);if(!b||b.role!==c||d&&b.gatewayKey&&b.gatewayKey!==d||e.length>0&&!x(b.scopes,e))continue;let h=d?b.gatewayKey===d?2:+!b.gatewayKey:+!!b.gatewayKey;f.push({...b,gatewayMatch:h,scopeScore:y(b.scopes)})}if(0===f.length)return null;f.sort((a,b)=>b.gatewayMatch-a.gatewayMatch||b.scopeScore-a.scopeScore||b.updatedAtMs-a.updatedAtMs);let g=f[0];return{token:g.token,role:g.role,scopes:g.scopes,updatedAtMs:g.updatedAtMs,...g.gatewayKey?{gatewayKey:g.gatewayKey}:{}}}function G(a){let b=a.role.trim(),c=p(a.token);if(!b||!c)return!1;let d=z(a.gatewayUrl),e=A(b,d),f=D(a.env),g=f&&f.deviceId===a.deviceId&&f.tokens&&"object"==typeof f.tokens?f:{version:2,deviceId:a.deviceId,tokens:{}};g.version=2;let h={token:c,role:b,scopes:w(a.scopes),updatedAtMs:Date.now(),...d?{gatewayKey:d}:{}},i=B(e,g.tokens[e]);if(i&&y(i.scopes)>y(h.scopes))return!1;return g.tokens[e]=h,E(g,a.env),!0}function H(a){let b=a.role.trim();if(!b)return!1;let c=D(a.env);if(!c||c.deviceId!==a.deviceId)return!1;let d=A(b,z(a.gatewayUrl)),e=!1;return c.tokens[d]&&(delete c.tokens[d],e=!0),a.includeLegacyRoleEntry&&c.tokens[b]&&(delete c.tokens[b],e=!0),e&&(c.version=2,E(c,a.env)),e}}};
|
|
1
|
+
"use strict";exports.id=1210,exports.ids=[1210],exports.modules={81210:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{t:()=>m});var e=c(48161),f=c.n(e),g=c(56220),h=c(94615),i=a([g]);g=(i.then?(await i)():i)[0];let j={id:"webchat-ui",version:"clawpad",platform:"web",mode:"webchat"},k=["operator.read","operator.write","operator.admin"];class l{get status(){return this._status}getLastError(){return this.lastError}getLastErrorCode(){return this.lastErrorCode}getFeatures(){return this.features}async connect(a,b){if(a&&this.applyPreferredGatewayUrl(a),arguments.length>=2){let a=this.normalizeToken(b);this.configuredToken=a,this.token=a}"connected"!==this._status&&"connecting"!==this._status&&this.doConnect()}disconnect(a){this.cancelReconnect(),this.reconnectAttempts=0,this.ws&&(this.ws.removeAllListeners(),this.ws.close(),this.ws=null),this.setStatus("disconnected"),a?.reconnect&&this.scheduleReconnect(a.reason)}onEvent(a){return this.eventListeners.add(a),()=>{this.eventListeners.delete(a)}}onStatus(a){return this.statusListeners.add(a),a(this._status),()=>{this.statusListeners.delete(a)}}get listenerCount(){return this.eventListeners.size}sendRPC(a,b,c=3e4){return new Promise((d,e)=>{if("connected"!==this._status||!this.ws)return void e(Error(`Cannot send RPC: WS status is "${this._status}"`));let f=String(++this.requestId),g=setTimeout(()=>{this.pendingRPC.delete(f),e(Error(`RPC "${a}" timed out after ${c}ms`))},c);this.pendingRPC.set(f,{resolve:d,reject:e,timer:g});try{this.ws.send(JSON.stringify({type:"req",id:f,method:a,params:b}))}catch(a){this.pendingRPC.delete(f),clearTimeout(g),e(Error(`Failed to send RPC: ${a}`))}})}async ensureConnected(a=1e4){if("connected"!==this._status){if("disconnected"===this._status){let{detectGateway:a}=await c.e(4526).then(c.bind(c,4526)),b=await a();if(b){let a=b.url.replace(/^http/,"ws");await this.connect(a,b.token)}}return new Promise((b,c)=>{if("connected"===this._status)return void b();let d=setTimeout(()=>{e(),c(Error("WS connect timed out"))},a),e=this.onStatus(a=>{"connected"===a&&(clearTimeout(d),e(),b())})})}}normalizeToken(a){return a?.trim()||void 0}buildOrigin(a){if(!a)return null;let b=a.replace(/^ws/i,"http");try{return new URL(b).origin}catch{return null}}normalizeHost(a){return a.trim().toLowerCase()}getLocalHostAliases(){let a=Date.now();if(this.localHostAliases&&a-this.localHostAliasesAtMs<6e4)return this.localHostAliases;let b=new Set(["localhost","127.0.0.1","::1"]),c=this.normalizeHost(f().hostname());for(let a of(c&&(b.add(c),b.add(`${c}.local`)),Object.values(f().networkInterfaces())))for(let c of a??[]){let a=this.normalizeHost(c.address??"");a&&b.add(a)}return this.localHostAliases=b,this.localHostAliasesAtMs=a,b}resolveLoopbackUrl(a){if(!a)return null;let b=a.replace(/^ws/i,"http");try{let a=new URL(b),c=this.normalizeHost(a.hostname);if(!c||"localhost"===c||"127.0.0.1"===c||"::1"===c||!this.getLocalHostAliases().has(c))return null;let d="https:"===a.protocol?"https:":"http:",e=a.port||("https:"===d?"443":"80"),f=a.pathname&&"/"!==a.pathname?a.pathname:"";return`${d}//127.0.0.1:${e}${f}${a.search}`}catch{return null}}applyPreferredGatewayUrl(a){let b=a.trim();if(!b)return;this.configuredUrl=b;let c=this.resolveLoopbackUrl(b);if(c&&c!==b){this.url=c,this.fallbackUrl=b;return}this.url=b,this.fallbackUrl=null}isAuthError(a,b){let c=(a??"").toUpperCase();if("NOT_PAIRED"===c||"AUTH_REQUIRED"===c||"UNAUTHORIZED"===c)return!0;let d=(b??"").toLowerCase();return!!d&&(d.includes("device identity required")||d.includes("not paired"))}async refreshConfig(a){let b=Date.now();return this.configRefreshInFlight?this.configRefreshInFlight:b-this.lastConfigRefreshAt<5e3?void 0:(this.configRefreshInFlight=(async()=>{this.lastConfigRefreshAt=Date.now();try{let{detectGateway:a}=await c.e(4526).then(c.bind(c,4526)),b=await a();if(b){this.applyPreferredGatewayUrl(b.url);let a=this.normalizeToken(b.token);this.configuredToken=a,this.token=a}}catch(b){console.warn("[gateway-ws] Config refresh failed:",a,b)}finally{this.configRefreshInFlight=null}})(),this.configRefreshInFlight)}setStatus(a){if(this._status!==a)for(let b of(this._status=a,"connected"===a&&(this.reconnectAttempts=0),this.statusListeners))try{b(a)}catch{}}doConnect(){this.setStatus("connecting");let a=!1;try{let a=this.url.replace(/^http/,"ws"),b=this.buildOrigin(this.url);this.ws=new g.default(a,b?{origin:b}:void 0)}catch(a){console.error("[gateway-ws] Failed to create WebSocket:",a),this.scheduleReconnect();return}this.ws.on("open",()=>{a=!0,console.log("[gateway-ws] WebSocket opened, waiting for challenge..."),this.lastPongAt=Date.now(),this.pingInterval||(this.pingInterval=setInterval(()=>{if(this.ws){if(Date.now()-this.lastPongAt>6e4){try{this.ws.terminate()}catch{}return}try{this.ws.ping()}catch{}}},3e4))}),this.ws.on("message",a=>{this.handleMessage(String(a))}),this.ws.on("error",a=>{console.error("[gateway-ws] WebSocket error:",a.message),this.lastError=a.message,this.lastErrorCode=null}),this.ws.on("close",()=>{for(let[a,b]of(this.ws=null,this.pingInterval&&(clearInterval(this.pingInterval),this.pingInterval=null),this.pendingRPC))clearTimeout(b.timer),b.reject(Error("WebSocket closed"));this.pendingRPC.clear(),!a&&this.fallbackUrl&&this.url!==this.fallbackUrl&&(this.lastError="localhost probe failed; retrying configured gateway address",this.lastErrorCode="GATEWAY_URL_FALLBACK",this.url=this.fallbackUrl,this.fallbackUrl=null,this.lastAuthRetryAt=null),this.setStatus("disconnected"),this.scheduleReconnect()}),this.ws.on("pong",()=>{this.lastPongAt=Date.now()})}handleMessage(a){let b;try{b=JSON.parse(a)}catch{console.warn("[gateway-ws] Failed to parse frame:",a.slice(0,200));return}if("event"===b.type){let a=b;if("connect.challenge"===a.event){console.log("[gateway-ws] Received challenge, sending connect...");let b=a.payload;this.handleChallenge(b.nonce);return}for(let b of this.eventListeners)try{b(a)}catch(a){console.error("[gateway-ws] Listener error:",a)}}else if("res"===b.type){let a=b,c=this.pendingRPC.get(a.id);if(c){this.pendingRPC.delete(a.id),clearTimeout(c.timer),a.ok?c.resolve(a.payload):c.reject(Error(`RPC error: ${JSON.stringify(a.error)}`));return}if(a.ok){console.log("[gateway-ws] Connected to gateway, payload:",JSON.stringify(a.payload)),this.lastError=null,this.lastErrorCode=null,this.lastAuthError=null,this.lastAuthErrorAt=null,this.lastAuthRetryAt=null;let b=a.payload&&"object"==typeof a.payload?a.payload:void 0,c="string"==typeof b?.auth?.deviceToken?b.auth.deviceToken:null,d="string"==typeof b?.auth?.role?b.auth.role:"operator",e=Array.isArray(b?.auth?.scopes)?b.auth.scopes.filter(a=>"string"==typeof a):[],f=!(e.length>0)||(0,h.PP)(e,h.qq);if(c){let a=(0,h.aZ)();f?((0,h.HQ)({deviceId:a.deviceId,role:d,token:c,scopes:e,gatewayUrl:this.url}),this.token=c):(0,h.Sm)({deviceId:a.deviceId,role:d,gatewayUrl:this.url,includeLegacyRoleEntry:!0})}if(f)this.lastScopeRecoveryAt=null;else{let a=new Set(e.map(a=>a.toLowerCase())),b=h.qq.filter(b=>!a.has(b)),c=`gateway issued device token without required scopes (${b.join(", ")||"unknown"})`;this.lastError=c,this.lastErrorCode="MISSING_SCOPE";let d=Date.now();if(!this.lastScopeRecoveryAt||d-this.lastScopeRecoveryAt>6e4){this.lastScopeRecoveryAt=d,this.forceConfigTokenOnNextChallenge=!0,console.warn("[gateway-ws] Missing required scopes in issued token. Retrying with configured token."),this.disconnect({reconnect:!0,reason:"scope-recovery"});return}console.warn("[gateway-ws] Missing required scopes in issued token; recovery recently attempted.")}this.updateFeatures(a.payload),this.setStatus("connected")}else{let b=a.error?.code,c=a.error?.message??"connect rejected",d=(()=>{let b=a.error;if(b&&"object"==typeof b){if(b.details&&"object"==typeof b.details)return b.details;if(b.data&&"object"==typeof b.data&&"details"in b.data&&"object"==typeof b.data.details)return b.data.details}})(),e="string"==typeof d?.code?d.code.trim().toUpperCase():void 0,f="string"==typeof d?.requestId&&d.requestId.trim()?d.requestId.trim():void 0,g="string"==typeof b?b:"number"==typeof b?String(b):null;console.error("[gateway-ws] Connect rejected:",a.error);let i=(g??"").toUpperCase();if(this.lastError=c,this.lastErrorCode=g,this.isAuthError(g,c)){if(this.lastAuthError=c,this.lastAuthErrorAt=Date.now(),"stored"===this.lastConnectTokenSource){let a=(0,h.aZ)();(0,h.Sm)({deviceId:a.deviceId,role:"operator",gatewayUrl:this.url,includeLegacyRoleEntry:!0}),this.configuredToken&&this.configuredToken!==this.lastConnectToken&&(this.forceConfigTokenOnNextChallenge=!0,this.token=this.configuredToken,this.lastError="cached device token rejected; retrying with gateway token",this.lastErrorCode="AUTH_RECOVERY")}if("NOT_PAIRED"===i)if("PAIRING_REQUIRED"===e||c.toLowerCase().includes("pairing required")){let a=this.resolveLoopbackUrl(this.configuredUrl);a&&a!==this.url?(this.fallbackUrl=this.configuredUrl,this.url=a,this.lastError="pairing required on gateway address; retrying localhost",this.lastErrorCode="PAIRING_LOCAL_RETRY",this.lastAuthRetryAt=null):(this.configuredToken,this.lastError=f?`pairing required (request ${f})`:"pairing required")}else"DEVICE_IDENTITY_REQUIRED"===e&&(this.lastError=this.configuredToken?"device identity required":"device identity required (gateway token not detected)",this.lastErrorCode="DEVICE_IDENTITY_REQUIRED");else"AUTH_REQUIRED"!==i||this.configuredToken||(this.lastError="gateway token missing")}this.disconnect({reconnect:!0,reason:"connect-rejected"})}}}async handleChallenge(a){if(!this.ws)return;this.token||this.configuredToken||await this.refreshConfig("challenge");let b="operator",c=(0,h.aZ)(),d=this.normalizeToken(this.configuredToken??this.token),e=this.forceConfigTokenOnNextChallenge?void 0:(0,h.vM)({deviceId:c.deviceId,role:b,gatewayUrl:this.url,requiredScopes:h.qq})?.token,f=this.normalizeToken(e??d);this.forceConfigTokenOnNextChallenge=!1,f||(this.lastAuthError="token missing",this.lastAuthErrorAt=Date.now(),this.lastError="device identity required",this.lastErrorCode="AUTH_REQUIRED");let g="string"==typeof a&&a.trim()?a.trim():void 0,i=(0,h.n3)({identity:c,clientId:j.id,clientMode:j.mode,role:b,scopes:k,token:f,nonce:g}),l={type:"req",id:String(++this.requestId),method:"connect",params:{minProtocol:3,maxProtocol:3,client:j,role:b,scopes:k,caps:[],commands:[],permissions:{},auth:f?{token:f}:{},device:i}};this.token=f,this.lastConnectToken=f,this.lastConnectTokenSource=e?"stored":f?"config":"none";try{this.ws.send(JSON.stringify(l))}catch(a){console.error("[gateway-ws] Failed to send connect:",a)}}updateFeatures(a){if(!a||"object"!=typeof a)return;let b=a.features;if(!b||"object"!=typeof b)return;let c=b.methods,d=b.events,e=Array.isArray(c)?c.filter(a=>"string"==typeof a):[],f=Array.isArray(d)?d.filter(a=>"string"==typeof a):[];(e.length||f.length)&&(this.features={methods:e,events:f})}scheduleReconnect(a){if("connected"===this._status||"connecting"===this._status)return;this.cancelReconnect(),this.setStatus("reconnecting");let b=Date.now();if(this.isAuthError(this.lastErrorCode,this.lastError)){let a=this.token&&this.token!==this.lastConnectToken;if(this.lastAuthRetryAt&&b-this.lastAuthRetryAt<3e4&&!a)return;this.lastAuthRetryAt=b}let c=this.reconnectAttempts,d=Math.min(3e4,2e3*Math.pow(1.8,c)),e=.25*d*(2*Math.random()-1),f=Math.max(500,Math.round(d+e));this.reconnectAttempts+=1,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,"disconnected"===this._status&&(this.reconnectInFlight||(this.reconnectInFlight=!0,this.refreshConfig("reconnect").catch(()=>{}).finally(()=>{this.reconnectInFlight=!1,"disconnected"===this._status&&this.doConnect()})))},f)}cancelReconnect(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}constructor(){this.ws=null,this._status="disconnected",this.configuredUrl="http://127.0.0.1:18789",this.fallbackUrl=null,this.localHostAliases=null,this.localHostAliasesAtMs=0,this.url="http://127.0.0.1:18789",this.reconnectTimer=null,this.requestId=0,this.lastError=null,this.lastErrorCode=null,this.lastAuthError=null,this.lastAuthErrorAt=null,this.lastAuthRetryAt=null,this.lastConnectTokenSource="none",this.configRefreshInFlight=null,this.lastConfigRefreshAt=0,this.reconnectInFlight=!1,this.reconnectAttempts=0,this.pingInterval=null,this.lastPongAt=0,this.features=null,this.forceConfigTokenOnNextChallenge=!1,this.lastScopeRecoveryAt=null,this.eventListeners=new Set,this.statusListeners=new Set,this.pendingRPC=new Map}}let m=new l;d()}catch(a){d(a)}})},94615:(a,b,c)=>{c.d(b,{HQ:()=>G,PP:()=>x,Sm:()=>H,aZ:()=>u,n3:()=>C,qq:()=>l,vM:()=>F});var d=c(55511),e=c.n(d),f=c(29021),g=c.n(f),h=c(33873),i=c.n(h),j=c(27843);let k=Buffer.from("302a300506032b6570032100","hex"),l=["operator.read","operator.write"];function m(a=process.env){return i().join((0,j.We)(a),"identity")}function n(a=process.env){return i().join(m(a),"clawpad-device-auth.json")}function o(a){return a.toString("base64").replaceAll("+","-").replaceAll("/","_").replace(/=+$/g,"")}function p(a){if("string"==typeof a)return a.trim()||void 0}function q(a){if("string"==typeof a)return a.trim().toLowerCase()||void 0}function r(a){let b=e().createPublicKey(a).export({type:"spki",format:"der"});return b.length===k.length+32&&b.subarray(0,k.length).equals(k)?b.subarray(k.length):b}function s(a){let b=r(a);return e().createHash("sha256").update(b).digest("hex")}function t(a,b){g().mkdirSync(i().dirname(a),{recursive:!0}),g().writeFileSync(a,`${JSON.stringify(b,null,2)}
|
|
2
|
+
`,{mode:384});try{g().chmodSync(a,384)}catch{}}function u(a=process.env){let b=function(a=process.env){return i().join(m(a),"clawpad-device.json")}(a);try{if(g().existsSync(b)){let a=g().readFileSync(b,"utf8"),c=JSON.parse(a);if(c?.version===1&&"string"==typeof c.deviceId&&"string"==typeof c.publicKeyPem&&"string"==typeof c.privateKeyPem){let a=s(c.publicKeyPem);if(a!==c.deviceId)return t(b,{version:1,deviceId:a,publicKeyPem:c.publicKeyPem,privateKeyPem:c.privateKeyPem,createdAtMs:Date.now()}),{deviceId:a,publicKeyPem:c.publicKeyPem,privateKeyPem:c.privateKeyPem};return{deviceId:c.deviceId,publicKeyPem:c.publicKeyPem,privateKeyPem:c.privateKeyPem}}}}catch{}let c=function(){let{publicKey:a,privateKey:b}=e().generateKeyPairSync("ed25519"),c=a.export({type:"spki",format:"pem"}).toString(),d=b.export({type:"pkcs8",format:"pem"}).toString();return{deviceId:s(c),publicKeyPem:c,privateKeyPem:d}}();return t(b,{version:1,deviceId:c.deviceId,publicKeyPem:c.publicKeyPem,privateKeyPem:c.privateKeyPem,createdAtMs:Date.now()}),c}function v(a){let b=new Set,c=[];for(let d of a){let a=q(d);!a||b.has(a)||(b.add(a),c.push(a))}return c}function w(a){return v(a).sort()}function x(a,b=l){if(!Array.isArray(a)||0===a.length)return!1;let c=new Set;for(let b of a){let a=q(b);a&&c.add(a)}for(let a of b){let b=q(a);if(b&&!c.has(b))return!1}return!0}function y(a){if(!Array.isArray(a)||0===a.length)return 0;let b=new Set;for(let c of a){let a=q(c);a&&b.add(a)}let c=0;return b.has("operator.read")&&(c+=100),b.has("operator.write")&&(c+=200),b.has("operator.admin")&&(c+=30),b.has("operator.approvals")&&(c+=5),b.has("operator.pairing")&&(c+=5),c}function z(a){if(!a)return;let b=a.trim();if(b)try{let a=new URL(/^wss?:\/\//i.test(b)?b.replace(/^wss?/i,"http"):/^https?:\/\//i.test(b)?b:`http://${b}`),c=a.port||("https:"===a.protocol?"443":"80");return`${a.hostname.toLowerCase()}:${c}`}catch{return b.toLowerCase()}}function A(a,b){return b?`${a}::${b}`:a}function B(a,b){if(!b||"object"!=typeof b)return null;let c=function(a){let b=a.indexOf("::");if(-1===b)return{role:a.trim()};let c=a.slice(0,b).trim(),d=z(a.slice(b+2));return{role:c,...d?{gatewayKey:d}:{}}}(a),d=p(b.token);if(!d)return null;let e="string"==typeof b.role&&b.role.trim()?b.role.trim():c.role;if(!e)return null;let f=z("string"==typeof b.gatewayKey?b.gatewayKey:c.gatewayKey),g=Array.isArray(b.scopes)?b.scopes.filter(a=>"string"==typeof a):[],h="number"==typeof b.updatedAtMs&&Number.isFinite(b.updatedAtMs)?b.updatedAtMs:0;return{token:d,role:e,scopes:w(g),updatedAtMs:h,...f?{gatewayKey:f}:{}}}function C(a){var b,c;let d,f,g,h=v(a.scopes),i=Date.now(),j=(f=[d=(b={deviceId:a.identity.deviceId,clientId:a.clientId,clientMode:a.clientMode,role:a.role,scopes:h,signedAtMs:i,token:a.token,nonce:a.nonce}).nonce?"v2":"v1",b.deviceId,b.clientId,b.clientMode,b.role,b.scopes.join(","),String(b.signedAtMs),b.token??""],"v2"===d&&f.push(b.nonce??""),f.join("|"));return{id:a.identity.deviceId,publicKey:o(r(a.identity.publicKeyPem)),signature:(c=a.identity.privateKeyPem,g=e().createPrivateKey(c),o(e().sign(null,Buffer.from(j,"utf8"),g))),signedAt:i,...a.nonce?{nonce:a.nonce}:{}}}function D(a=process.env){let b=n(a);try{if(!g().existsSync(b))return null;let a=g().readFileSync(b,"utf8"),c=JSON.parse(a);if(!c||1!==c.version&&2!==c.version||"string"!=typeof c.deviceId||!c.tokens||"object"!=typeof c.tokens)return null;return c}catch{return null}}function E(a,b=process.env){t(n(b),a)}function F(a){let b=D(a.env);if(!b||b.deviceId!==a.deviceId)return null;let c=a.role.trim();if(!c)return null;let d=z(a.gatewayUrl),e=w((a.requiredScopes??[]).filter(a=>"string"==typeof a)),f=[];for(let[a,g]of Object.entries(b.tokens)){let b=B(a,g);if(!b||b.role!==c||d&&b.gatewayKey&&b.gatewayKey!==d||e.length>0&&!x(b.scopes,e))continue;let h=d?b.gatewayKey===d?2:+!b.gatewayKey:+!!b.gatewayKey;f.push({...b,gatewayMatch:h,scopeScore:y(b.scopes)})}if(0===f.length)return null;f.sort((a,b)=>b.gatewayMatch-a.gatewayMatch||b.scopeScore-a.scopeScore||b.updatedAtMs-a.updatedAtMs);let g=f[0];return{token:g.token,role:g.role,scopes:g.scopes,updatedAtMs:g.updatedAtMs,...g.gatewayKey?{gatewayKey:g.gatewayKey}:{}}}function G(a){let b=a.role.trim(),c=p(a.token);if(!b||!c)return!1;let d=z(a.gatewayUrl),e=A(b,d),f=D(a.env),g=f&&f.deviceId===a.deviceId&&f.tokens&&"object"==typeof f.tokens?f:{version:2,deviceId:a.deviceId,tokens:{}};g.version=2;let h={token:c,role:b,scopes:w(a.scopes),updatedAtMs:Date.now(),...d?{gatewayKey:d}:{}},i=B(e,g.tokens[e]);if(i&&y(i.scopes)>y(h.scopes))return!1;return g.tokens[e]=h,E(g,a.env),!0}function H(a){let b=a.role.trim();if(!b)return!1;let c=D(a.env);if(!c||c.deviceId!==a.deviceId)return!1;let d=A(b,z(a.gatewayUrl)),e=!1;return c.tokens[d]&&(delete c.tokens[d],e=!0),a.includeLegacyRoleEntry&&c.tokens[b]&&(delete c.tokens[b],e=!0),e&&(c.version=2,E(c,a.env)),e}}};
|