openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
241 lines • 31.8 kB
JavaScript
import{n as e}from"./rolldown-runtime-8BhlS34s.js";import{Ji as t,Ti as n,qr as r}from"./control-ui-foundation-ZY_Flbbd.js";import{Gl as i,Jc as a,P as o,R as s,Yc as c,bs as l,bu as ee,cc as u,hc as te,hu as d,lu as f,pa as ne,ql as p,sc as m,su as h,uu as g,xc as re,xu as ie,yc as ae}from"./control-ui-core-3P365fbR.js";import{$r as oe,Kr as _,Xi as v,Zi as y,_r as se,dr as ce,hr as le,rt as b,st as ue,ur as x}from"./control-ui-core-CFW9Qtjn.js";import{$ as S,F as de,M as fe,X as C,Y as w,c as pe,m as me,nt as T,p as he,s as ge,ut as E}from"./lit-runtime-P5vbNq6b.js";import{Ki as _e,Nr as ve,Pr as ye,qi as be}from"./control-ui-boot-shared-DoKu-5Ju.js";import{Xa as xe,Ya as Se}from"./control-ui-boot-shared-CG9HtEG-.js";import{t as Ce}from"./desktop-panel-B-wMMJaC.js";import{n as D,r as O}from"./system-info-CjVJMFLU.js";import{t as k}from"./sparkline-tile-Cq3j8Hqq.js";var A,j;function M(){return(M=e((()=>{ie(),A={systems:{title:`Systems`,inventory:`Machines`,search:`Find a machine…`,filterSort:`Filter & sort machines`,sortBy:`Sort by`,alphabetical:`Alphabetical`,onlineFirst:`Online first`,offlineFirst:`Offline first`,all:`All`,select:`Select a machine`,selectHint:`Choose a host, worker, or paired node to see its status and desktop.`,refresh:`Refresh machines`,loading:`Loading machines…`,empty:`No machines are available to this account.`,noMatches:`No machines match your search or filters.`,offlineGateway:`Gateway disconnected. Reconnect to refresh machines or open a desktop.`,offlineTitle:`This machine is offline`,offlineHint:`Its last reported information is shown. Reconnect the machine to open its desktop.`,noDesktopTitle:`No desktop available`,noDesktopHint:`This machine has not reported a desktop. Its other capabilities remain available.`,noHostDesktopHint:`Refresh machines to check screen-sharing availability on this Gateway.`,screenSharingDetected:`Screen Sharing is available`,desktopDetected:`A desktop is available`,managedDesktopConfigured:`A managed desktop is configured`,screenSharingNeeded:`Turn on Screen Sharing`,desktopServerNeeded:`Set up a desktop server`,desktopSetupAttention:`Screen sharing needs attention`,desktopSetupEnableHint:`Enable desktop access to view and control this machine in OpenClaw.`,screenSharingSetupHint:`On this Mac, open System Settings → General → Sharing. Turn on Screen Sharing, or allow this account to Observe and Control in Remote Management, then check again.`,desktopServerSetupHint:`Set up a password-protected VNC server on this machine, or configure a managed desktop on Linux, then check again.`,enableDesktopAccess:`Enable desktop access in OpenClaw`,desktopSetupEnabling:`Enabling desktop access…`,desktopSetupEnabled:`Desktop access is enabled`,desktopSetupConnecting:`Waiting for desktop access to become available.`,desktopSetupApplyHint:`Applies without restarting the Gateway.`,desktopSetupAdminHint:`A Gateway administrator can enable desktop access.`,desktopSetupCheckAgain:`Check again`,desktopSetupFailed:`Desktop access could not be enabled. Refresh machines and try again.`,accessTitle:`Desktop access unavailable`,accessHint:`Desktop viewing requires an advertised desktop service and administrator access.`,missingTitle:`This machine is no longer listed`,missingHint:`Refresh the inventory or choose another machine. Your selection has not been changed.`,details:`Machine details`,closeDetails:`Close details`,stats:`Show statistics`,hideStats:`Hide statistics`,online:`Online`,offline:`Offline`,unknown:`Unknown`,unavailable:`Unavailable`,desktop:`Desktop`,host:`Gateway host`,worker:`Worker`,node:`Paired node`,workers:`Workers`,nodes:`Paired nodes`,status:`Status`,platform:`Platform`,identifier:`Identifier`,capabilities:`Capabilities`,telemetry:`Reported statistics`,load:`Load (1 min)`,cpuCount:`{count} cores`,memory:`Memory used`,disk:`Disk available`,sampled:`Sampled {time}`,collectingHistory:`Collecting history…`,lastKnown:`Last reported {time}`,noTelemetry:`This machine has not reported resource statistics.`,attachedSessions:`Attached sessions`,attachedHint:`Attachment does not mean a session is currently executing on this machine.`,relatedSessions:`Related sessions`,relatedHint:`Bindings from the loaded session list. A binding is not proof that a turn executed here.`,noRelatedSessions:`No related sessions in the loaded list.`,relations:{placement:`Placed here`,"retained-placement":`Retained placement`,runner:`Runner`,"exec-binding":`Configured exec target`,gateway:`Local session context`},statuses:{starting:`Starting`,stopping:`Stopping`,error:`Error`},errors:`Some machine information could not be refreshed.`}},j=Object.assign(()=>Object.assign(ee,A),{catalog:A})})))()}async function we(e,t){let n=e.snapshot.client;if(!n||!t.isCurrent()||t.signal?.aborted)return;let r={signal:t.signal},[a,o,s]=await Promise.allSettled([n.request(`environments.list`,{includeDesktopSetup:!0},r),n.request(`node.list`,{},r),O(e,t.signal,{fresh:t.fresh})]);if(t.isCurrent()&&!t.signal?.aborted&&!(s.status===`rejected`&&s.reason instanceof DOMException&&s.reason.name===`AbortError`)){if(a.status===`rejected`)throw a.reason;return{environments:a.value.environments,nodes:o.status===`fulfilled`?o.value.nodes:[],gatewaySystemInfo:s.status===`fulfilled`?s.value.value:null,gatewaySampledAtMs:s.status===`fulfilled`?s.value.at:null,errors:{...o.status===`rejected`?{nodes:i(o.reason)}:{},...s.status===`rejected`?{systemInfo:i(s.reason)}:{}}}}}function Te(e,t){let n=new Map(e.nodes.map(e=>[`node:${e.nodeId}`,e])),r=new Map,i=(e,t,n)=>{let i=r.get(e),a={kind:t,session:n};i?i.push(a):r.set(e,[a])};for(let e of t){let t=e.placement;if(t&&t.state!==`local`){if(t.state===`requested`)continue;t.environmentId&&i(t.environmentId,t.state===`reclaimed`||t.state===`failed`?`retained-placement`:`placement`,e),t.state===`active`&&t.runner?.deviceId&&i(`node:${t.runner.deviceId}`,`runner`,e);continue}let n=e.execNode?.trim();i(n?`node:${n}`:`gateway`,n?`exec-binding`:`gateway`,e)}return e.environments.filter(e=>e.type!==`worker`||e.worker?.state!==`destroyed`&&e.worker?.state!==`failed`).map(t=>({environment:t,node:t.type===`node`?n.get(t.id):void 0,gatewaySystemInfo:t.id===`gateway`?e.gatewaySystemInfo??void 0:void 0,sessions:r.get(t.id)??[]}))}function N(){return(N=e((()=>{p(),D()})))()}function P(e){return e.gatewaySystemInfo??e.node?.hostStats}var F,I;function L(){return(L=e((()=>{F=3e4,I=12e4})))()}var R;function z(){return(z=e((()=>{ce(),se(),b(),g(),a(),p(),D(),N(),L(),R=class{constructor(e){this.context=e,this.inventory=null,this.rows=[],this.selectedId=null,this.query=``,this.sortMode=`online-first`,this.statusFilter=`all`,this.showStats=!0,this.showDetails=!1,this.loading=!1,this.error=null,this.sampledAtMs=null,this.desktopSetupError=null,this.telemetry=new Map,this.listeners=new Set,this.subscriptions=[],this.generation=0,this.presented=!1,this.scope=x(e.gateway),this.lifecycle=ne(e.gateway.snapshot)}get current(){return this.scope===x(this.context.gateway)}get connected(){return this.current&&this.context.gateway.snapshot.phase===`connected`}get needsInventoryRefresh(){return this.inventory===null||this.refreshQueued!==void 0}get desktopAvailable(){return this.current&&ue(this.context.gateway.snapshot)}get selected(){return this.current?this.rows.find(e=>e.environment.id===this.selectedId):void 0}get hostDesktopEnabled(){let e=c(this.context.runtimeConfig.state.configSnapshot)?.desktop;return t(e)&&t(e.host)&&e.host.enabled===!0}get desktopSetupBusy(){return this.desktopSetupRequest!==void 0}resetDesktopSetup(){this.desktopSetupRequest=void 0,this.desktopSetupError=null}get canEnableHostDesktop(){let e=this.selected?.environment.desktopSetup;return this.presented&&this.connected&&this.selectedId===`gateway`&&(e?.state===`ready`||e?.state===`managed`)&&!this.hostDesktopEnabled&&this.context.runtimeConfig.canPatch===!0}async enableHostDesktop(){let e=this.lifecycle.capture(),t=this.context.runtimeConfig;if(!e||!this.canEnableHostDesktop||this.desktopSetupBusy)return;let n=Symbol(`desktop-setup`),r=()=>this.desktopSetupRequest===n&&this.presented&&this.current&&this.lifecycle.isCurrent(e)&&this.context.runtimeConfig===t;this.desktopSetupRequest=n,this.desktopSetupError=null,this.notify();try{if(await t.ensureLoaded(),!r()||!this.canEnableHostDesktop)return;let e=await t.patch({raw:{desktop:{host:{enabled:!0}}},note:`systems: enable host desktop`,canDispatch:()=>r()&&this.canEnableHostDesktop});r()&&!e&&(this.desktopSetupError=t.state.lastError??d(`systems.desktopSetupFailed`)),r()&&e&&await this.refresh()}catch(e){r()&&(this.desktopSetupError=i(e))}finally{r()&&(this.desktopSetupRequest=void 0,this.notify())}}telemetryHistory(e){return this.current?this.telemetry.get(e)??[]:[]}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}notify(){for(let e of this.listeners)e()}projectRows(){this.rows=this.inventory&&this.current?Te(this.inventory,this.context.sessions.state.result?.sessions??[]):[]}recordTelemetry(e){let t=new Set(this.rows.map(e=>e.environment.id));for(let e of this.telemetry.keys())t.has(e)||this.telemetry.delete(e);for(let t of this.rows){let n=t.environment.id,r=P(t);if(!r){this.telemetry.delete(n);continue}let i=n===`gateway`;if(i&&!e)continue;let a=t.node?.hostStats?.updatedAtMs??this.sampledAtMs;if(a===null)continue;let o=this.telemetry.get(n)??[],s=o.at(-1);if(s&&a<=s.at)continue;let c=i?F:I,l=s&&a-s.at<=c?o:[];this.telemetry.set(n,[...l.slice(-119),{at:a,stats:r}])}}select(e){this.current&&e.trim()&&(this.telemetryRequest?.abort(),this.telemetryRequest=void 0,e!==this.selectedId&&this.resetDesktopSetup(),this.selectedId=e,this.notify())}search(e){this.query=e,this.notify()}setSortMode(e){this.sortMode=e,this.notify()}setStatusFilter(e){this.statusFilter=e,this.notify()}toggleStats(){this.showStats=!this.showStats,this.notify()}toggleDetails(){this.showDetails=!this.showDetails,this.notify()}setPresented(e){if(this.presented!==e){if(this.presented=e,!e){for(let e of this.subscriptions)e();this.subscriptions=[],this.cancelRefresh(),this.resetDesktopSetup();return}this.subscriptions=[this.context.gateway.subscribe(e=>{let t=this.lifecycle.transition(e);this.current?t&&(this.cancelRefresh(),this.resetDesktopSetup(),this.telemetry.clear(),e.phase===`connected`&&this.refresh()):this.clear(),this.notify()}),this.context.gateway.subscribeEvents(e=>{e.event===`presence`||e.event===`node.pair.resolved`||e.event===`node.runnerInventory.changed`||e.event===`config.changed`?this.refresh():e.event===`node.hostStats`&&t(e.payload)&&typeof e.payload.nodeId==`string`&&this.selectedId===`node:${e.payload.nodeId}`&&this.refreshTelemetry()}),this.context.sessions.subscribe(()=>{this.projectRows(),this.notify()}),this.context.runtimeConfig.subscribe(()=>this.notify())],this.lifecycle.transition(this.context.gateway.snapshot)&&this.telemetry.clear(),this.current?this.refresh():this.clear()}}cancelRefresh(){this.generation+=1,this.request?.abort(),this.telemetryRequest?.abort(),this.request=void 0,this.telemetryRequest=void 0,this.loading=!1,this.refreshQueued=void 0}clear(){this.cancelRefresh(),this.inventory=null,this.rows=[],this.selectedId=null,this.error=null,this.sampledAtMs=null,this.telemetry.clear(),this.resetDesktopSetup(),this.query=``}async refresh(e=`automatic`){let t=this.context.gateway.snapshot;this.lifecycle.transition(t)&&this.telemetry.clear();let n=this.lifecycle.capture();if(!this.presented||!this.current||!n||!le(t.hello?.auth??null))return;let r=this.refreshQueued===`manual`?`manual`:e;if(this.loading||document.visibilityState===`hidden`){this.refreshQueued=r;return}this.cancelRefresh();let a=this.generation,o=new AbortController;this.request=o;let s=()=>this.presented&&this.current&&a===this.generation&&this.lifecycle.isCurrent(n);this.loading=!0,this.error=null,this.notify();try{let e=await we(this.context.gateway,{signal:o.signal,isCurrent:s,fresh:r===`manual`});if(!e&&s()&&(this.refreshQueued=this.refreshQueued===`manual`?`manual`:r),!e||!s())return;let t=this.inventory===null;if(this.inventory=e,this.projectRows(),this.sampledAtMs=e.gatewaySampledAtMs,this.recordTelemetry(!0),t&&this.selectedId===null){let e=this.context.gateway.snapshot.sessionKey;this.selectedId=this.rows.find(t=>t.sessions.some(t=>t.session.key===e))?.environment.id??this.rows.find(e=>e.environment.id===`gateway`)?.environment.id??this.rows[0]?.environment.id??null}}catch(e){s()&&(this.error=i(e))}finally{s()&&(this.loading=!1,this.request=void 0,this.notify(),this.refreshQueued&&this.refresh())}}async refreshTelemetry(){let e=this.selected,t=this.inventory,n=this.lifecycle.capture();if(!this.presented||!this.current||!n||!e||!t||this.loading||this.telemetryRequest)return;let r=e.environment.id===`gateway`;if(!r&&e.environment.type!==`node`)return;let a=new AbortController;this.telemetryRequest=a;let o=this.generation,s=this.selectedId,c=()=>this.presented&&this.current&&this.lifecycle.isCurrent(n)&&this.telemetryRequest===a&&o===this.generation&&this.selectedId===s;try{if(r){let e=await O(this.context.gateway,a.signal);if(!c()||!this.inventory)return;let{systemInfo:t,...n}=this.inventory.errors;this.inventory={...this.inventory,gatewaySystemInfo:e.value,gatewaySampledAtMs:e.at,errors:n},this.sampledAtMs=e.at}else{let e=await n.client.request(`node.list`,{},{signal:a.signal});if(!c()||!this.inventory)return;let{nodes:t,...r}=this.inventory.errors;this.inventory={...this.inventory,nodes:e.nodes,errors:r}}this.projectRows(),this.recordTelemetry(r)}catch(e){if(e instanceof DOMException&&e.name===`AbortError`)return;c()&&this.inventory&&(this.inventory={...this.inventory,errors:{...this.inventory.errors,[r?`systemInfo`:`nodes`]:i(e)}})}finally{c()&&(this.telemetryRequest=void 0,this.notify())}}}})))()}function B(e,t,n){return S`<wa-dropdown-item
class="sidebar-session-sort-menu__item"
value=${e}
role="menuitemradio"
aria-checked=${String(n)}
${de(e=>xe(e,n))}
>
<span class="session-menu__text">${d(t)}</span>
<span slot="details" class="session-menu__check" aria-hidden="true"
>${n?v.check:C}</span
>
</wa-dropdown-item>`}function V(e){let t=e.gatewaySystemInfo?.machineName??e.environment.label??e.node?.displayName;if(t)return t;if(e.environment.id===`gateway`)return d(`systems.host`);let n=e.environment.worker;if(n){let t=e.sessions.find(e=>e.kind===`placement`)?.session;if(t)return t.displayName??t.label??t.key;if(n.profileId)return`${n.providerId} · ${n.profileId}`}return e.environment.id}function Ee(e){return e.slice(e.lastIndexOf(`:`)+1,e.lastIndexOf(`:`)+7)}function H(e){return e.environment.id===`gateway`?`host`:e.environment.type===`node`?`node`:`worker`}function U(e){return d(e.environment.status===`available`?`systems.online`:e.environment.status===`unavailable`?`systems.offline`:`systems.statuses.`+e.environment.status)}function W(e){let t=e.gatewaySystemInfo?.osLabel??e.environment.platform??e.node?.platform;return t?ye(t,e.node?.deviceFamily):void 0}var G,K,q;function J(){return(J=e((()=>{w(),T(),fe(),y(),Se(),g(),M(),ve(),f(),u(),j(),G=[{value:`name`,labelKey:`systems.alphabetical`},{value:`online-first`,labelKey:`systems.onlineFirst`},{value:`offline-first`,labelKey:`systems.offlineFirst`}],K=[{value:`all`,labelKey:`systems.all`},{value:`online`,labelKey:`systems.online`},{value:`offline`,labelKey:`systems.offline`}],q=class extends h{constructor(){super(),new m(this).watch(()=>this.controller,(e,t)=>e.subscribe(t))}render(){let e=this.controller;if(!e?.current)return C;let t=e.query.trim().toLocaleLowerCase(),n=e.rows.filter(n=>(e.statusFilter===`all`||n.environment.status===(e.statusFilter===`online`?`available`:`unavailable`))&&[V(n),n.environment.id,W(n)??``,n.environment.platform??n.node?.platform??``].some(e=>e.toLocaleLowerCase().includes(t))).toSorted((t,n)=>{if(e.sortMode!==`name`){let r=e.sortMode===`online-first`?`available`:`unavailable`,i=Number(n.environment.status===r)-Number(t.environment.status===r);if(i)return i}return V(t).localeCompare(V(n),void 0,{numeric:!0,sensitivity:`base`})||t.environment.id.localeCompare(n.environment.id)}),r=t=>{let n=t.environment.status===`available`,r=W(t),i=U(t);return S`<button
class="systems-machine"
type="button"
data-status=${t.environment.status}
aria-pressed=${t.environment.id===e.selectedId}
aria-description=${r?`${i} · ${r}`:i}
@click=${()=>e.select(t.environment.id)}
>
<i class="systems-machine__dot" aria-hidden="true"></i>
<span class="systems-machine__name">${V(t)}</span>
<span class="systems-machine__meta"
>${n?t.environment.worker?Ee(t.environment.id):r??C:i}</span
>
${t.environment.desktop?S`<span class="systems-machine__desktop"
>${v.monitor}<span class="sr-only">${d(`systems.desktop`)}</span></span
>`:C}
</button>`};return S`<section class="systems-sidebar" aria-label=${d(`systems.inventory`)}>
<div class="systems-filter">
<span aria-hidden="true">${v.search}</span>
<input
type="search"
aria-label=${d(`systems.search`)}
placeholder=${d(`systems.search`)}
.value=${e.query}
@input=${t=>{t.currentTarget instanceof HTMLInputElement&&e.search(t.currentTarget.value)}}
/>
<wa-dropdown
class="systems-filter-menu sidebar-session-sort-menu"
placement="bottom-end"
aria-label=${d(`systems.filterSort`)}
@wa-select=${t=>{let n=t.detail.item.value,r=G.find(e=>n===`sort:${e.value}`),i=K.find(e=>n===`status:${e.value}`);r?e.setSortMode(r.value):i&&e.setStatusFilter(i.value)}}
>
<button
slot="trigger"
type="button"
class="systems-filter__sort sidebar-session-sort ${e.statusFilter===`all`?``:`sidebar-session-sort--filtered`}"
aria-label=${d(`systems.filterSort`)}
title=${d(`systems.filterSort`)}
>
${v.listFilter}
</button>
<div class="sidebar-session-sort-menu__title">${d(`systems.sortBy`)}</div>
${G.map(t=>B(`sort:${t.value}`,t.labelKey,e.sortMode===t.value))}
<div class="session-menu__separator" role="separator"></div>
<div class="sidebar-session-sort-menu__title">${d(`systems.status`)}</div>
${K.map(t=>B(`status:${t.value}`,t.labelKey,e.statusFilter===t.value))}
</wa-dropdown>
<button
type="button"
class="systems-filter__refresh"
aria-label=${d(`systems.refresh`)}
title=${d(`systems.refresh`)}
?disabled=${e.loading||!e.connected}
@click=${()=>void e.refresh(`manual`)}
>
${v.refresh}
</button>
</div>
<div class="systems-sidebar__list" aria-busy=${e.loading}>
${e.loading&&!e.inventory?S`<p class="systems-sidebar__empty" role="status">${d(`systems.loading`)}</p>`:C}
${n.filter(e=>H(e)===`host`).map(r)}
${[`node`,`worker`].map(e=>{let t=n.filter(t=>H(t)===e);return t.length?S`<section class="systems-group">
<h3>
<span>${d(e===`node`?`systems.nodes`:`systems.workers`)}</span>
<span class="systems-group__count">${t.length}</span>
</h3>
${t.map(r)}
</section>`:C})}
${!e.loading&&n.length===0?S`<p class="systems-sidebar__empty">${d(t||e.statusFilter!==`all`?`systems.noMatches`:`systems.empty`)}</p>`:C}
</div>
</section>`}},r([E({attribute:!1})],q.prototype,`controller`,void 0),customElements.get(`openclaw-systems-sidebar`)||customElements.define(`openclaw-systems-sidebar`,q)})))()}function Y(e){return n(e,{style:`legacy-binary`,separator:` `,maxUnit:`tera`,fractionDigits:(e,t)=>+(t===`tera`||e<10)})}function X(e,t){let n=[];for(let{at:r,stats:i}of e){let e=t(i);e===void 0||!Number.isFinite(e)?n.length=0:n.push({at:r,value:e})}return n}function Z(e,t){let n=P(e);if(!n)return S`<p class="systems-no-telemetry">${d(`systems.noTelemetry`)}</p>`;let r=e.node?.hostStats?.updatedAtMs??t.sampledAtMs,i=e.environment.id===`gateway`,a=!t.connected||e.environment.status!==`available`||!!t.inventory?.errors[i?`systemInfo`:`nodes`]||r!==null&&Date.now()-r>(i?3e4:12e4),s=t.telemetryHistory(e.environment.id),c=s.length?s:[{at:r??0,stats:n}],l=(e,t)=>S`
<openclaw-sparkline
class="gateway-vital systems-vital systems-vital--disk"
title=${e??C}
.label=${e?`${d(`systems.disk`)} ${e}`:d(`systems.disk`)}
.sub=${t===void 0?``:`/ ${Y(t)}`}
.samples=${X(c,t=>e===void 0?t.disks===void 0?t.diskAvailableBytes:void 0:t.disks?.find(t=>t.path===e)?.availableBytes)}
.format=${Y}
.autorange=${!0}
></openclaw-sparkline>
`;return me(e.environment.id,S`<div class="systems-metrics" data-stale=${a}>
<div
class="systems-vitals ${n.disks&&n.disks.length!==1?`systems-vitals--volumes`:``}"
>
<openclaw-sparkline
class="gateway-vital systems-vital systems-vital--load"
.label=${d(`systems.load`)}
.sub=${d(`systems.cpuCount`,{count:String(n.cpuCount)})}
.samples=${X(c,e=>e.loadAverage?.[0])}
.format=${e=>e.toFixed(2)}
.floorMax=${n.cpuCount}
></openclaw-sparkline>
<openclaw-sparkline
class="gateway-vital systems-vital systems-vital--memory"
.label=${d(`systems.memory`)}
.sub=${`/ ${Y(n.memoryTotalBytes)}`}
.samples=${X(c,e=>e.memoryTotalBytes-e.memoryFreeBytes)}
.format=${Y}
.floorMax=${n.memoryTotalBytes}
></openclaw-sparkline>
${n.disks===void 0?l(void 0,n.diskTotalBytes):pe(n.disks,e=>e.path,e=>l(e.path,e.totalBytes))}
</div>
<div class="systems-metrics-caption">
${!a&&c.length<2?S`<span>${d(`systems.collectingHistory`)}</span>`:C}
${r===null?C:S`<span class="systems-sample-time">${d(a?`systems.lastKnown`:`systems.sampled`,{time:o(Math.max(0,Date.now()-r))})}</span>`}
</div>
</div>`)}function De(e,t,n=!0){return e?S`<openclaw-systems-page
.routeData=${e}
.presented=${n}
></openclaw-systems-page>`:C}function Oe(e){return e?S`<openclaw-systems-sidebar .controller=${e.controller}></openclaw-systems-sidebar>`:C}function ke(e){return{controller:new R(e)}}var Q;function $(){return($=e((()=>{w(),T(),he(),ge(),y(),k(),oe(),Ce(),g(),M(),s(),te(),f(),be(),u(),z(),J(),L(),j(),Q=class extends h{constructor(){super(),this.presented=!0,this.poll=new _e(this,15e3,()=>{let e=this.routeData?.controller;this.presented&&e&&(e.needsInventoryRefresh?e.refresh():(e.showStats||e.showDetails)&&e.refreshTelemetry())},!0,`visible`),this.handleDesktopToggle=e=>{let n=this.routeData?.controller;if(!this.presented||!n?.current||!(e instanceof CustomEvent))return;let r=t(e.detail)?e.detail:{},i=typeof r.environmentId==`string`?r.environmentId:void 0;if(e.preventDefault(),e.stopImmediatePropagation(),r?.open===!1){this.querySelector(`openclaw-desktop-panel`)?.handleToggleRequest(e);return}if(i&&i!==n.selectedId){n.select(i),n.rows.some(e=>e.environment.id===i)||n.refresh();return}i&&this.querySelector(`openclaw-desktop-panel`)?.handleToggleRequest(e)},this.poll,new m(this).watch(()=>this.routeData?.controller,(e,t)=>e.subscribe(t))}connectedCallback(){super.connectedCallback(),window.addEventListener(_,this.handleDesktopToggle)}disconnectedCallback(){window.removeEventListener(_,this.handleDesktopToggle),this.activeController?.setPresented(!1),this.activeController=void 0,super.disconnectedCallback()}updated(e){(e.has(`routeData`)||e.has(`presented`))&&(this.activeController!==this.routeData?.controller&&this.activeController?.setPresented(!1),this.activeController=this.routeData?.controller,this.activeController?.setPresented(this.presented))}renderDetails(e,t){let n=t.environment;return S`<aside class="systems-details" aria-label=${d(`systems.details`)}>
<header>
<h2>${d(`systems.details`)}</h2>
<button
class="systems-icon-button"
aria-label=${d(`systems.closeDetails`)}
@click=${()=>e.toggleDetails()}
>
${v.x}
</button>
</header>
<dl>
<dt>${d(`systems.identifier`)}</dt>
<dd>${n.id}</dd>
<dt>${d(`systems.status`)}</dt>
<dd>${e.connected?U(t):d(`systems.offline`)}</dd>
<dt>${d(`systems.platform`)}</dt>
<dd>${W(t)??d(`systems.unknown`)}</dd>
</dl>
<h3>${d(`systems.telemetry`)}</h3>
${Z(t,e)}
<h3>${d(`systems.relatedSessions`)}</h3>
<p class="systems-detail-hint">${d(`systems.relatedHint`)}</p>
${t.sessions.length?t.sessions.map(t=>{let n=t.session,r=ae(n),i=re({context:e.context,face:r,sessionKey:n.key,preferenceDerivedFace:!0});return S`<a
class="systems-session-link"
href=${i.href}
@click=${t=>{l(t)&&(t.preventDefault(),e.context.navigate(r,i.options))}}
><strong>${n.displayName??n.label??n.key}</strong
><span>${d(`systems.relations.`+t.kind)}</span></a
>`}):S`<p class="systems-detail-hint">${d(`systems.noRelatedSessions`)}</p>`}
${n.worker?.attachedSessionIds.length?S`<h3>${d(`systems.attachedSessions`)}</h3>
<p class="systems-detail-hint">${d(`systems.attachedHint`)}</p>
<ul>
${n.worker.attachedSessionIds.map(e=>S`<li>${e}</li>`)}
</ul>`:C}
<h3>${d(`systems.capabilities`)}</h3>
<div class="systems-capabilities">
${(n.capabilities??[]).map(e=>S`<span>${e}</span>`)}
</div>
</aside>`}renderHostDesktopSetup(e,t){let n=t.environment.desktopSetup,r=e.hostDesktopEnabled,i=W(t)?.startsWith(`macOS`)===!0,a=n?.state===`ready`||n?.state===`managed`,o=r?`systems.desktopSetupEnabled`:n?.state===`managed`?`systems.managedDesktopConfigured`:n?.state===`ready`?i?`systems.screenSharingDetected`:`systems.desktopDetected`:n?.state===`needs-server`?i?`systems.screenSharingNeeded`:`systems.desktopServerNeeded`:`systems.desktopSetupAttention`,s=r?`systems.desktopSetupConnecting`:a?`systems.desktopSetupEnableHint`:i&&n?.state===`needs-server`?`systems.screenSharingSetupHint`:`systems.desktopServerSetupHint`;return S`<div class="systems-state" role="status">
<span class="systems-state__icon" aria-hidden="true">${v.monitor}</span>
<h2>${d(o)}</h2>
<p>${d(s)}</p>
${n?.state===`unsupported`&&n.detail?S`<p>${n.detail}</p>`:C}
${e.desktopSetupError?S`<p class="systems-callout--error" role="alert">${e.desktopSetupError}</p>`:C}
${!r&&a?S`
<button
class="btn primary systems-text-button"
?disabled=${!e.canEnableHostDesktop||e.desktopSetupBusy}
@click=${()=>void e.enableHostDesktop()}
>
${d(e.desktopSetupBusy?`systems.desktopSetupEnabling`:`systems.enableDesktopAccess`)}
</button>
<p>
${d(e.context.runtimeConfig.canPatch===!0?`systems.desktopSetupApplyHint`:`systems.desktopSetupAdminHint`)}
</p>
`:C}
${!r&&!a?S`<button class="systems-text-button" ?disabled=${e.loading||!e.connected} @click=${()=>void e.refresh(`manual`)}>${d(`systems.desktopSetupCheckAgain`)}</button>`:C}
</div>`}render(){let e=this.routeData?.controller;if(!e?.current)return S`<p class="systems-state" role="status">${d(`systems.loading`)}</p>`;let t=e.selected,n=!!(t?.environment.desktop&&t.environment.status===`available`&&e.desktopAvailable&&this.presented),r=t?V(t):d(`systems.title`),i=Object.values(e.inventory?.errors??{}),a=e.connected?e.loading&&!e.inventory?d(`systems.loading`):e.selectedId&&!t?d(`systems.missingTitle`):t?t.environment.status===`available`?t.environment.desktop?d(`systems.accessTitle`):d(`systems.noDesktopTitle`):t.environment.status===`unavailable`?d(`systems.offlineTitle`):U(t):d(`systems.select`):d(`systems.offlineGateway`),o=e.selectedId&&!t?d(`systems.missingHint`):t?t.environment.status===`available`?t.environment.desktop?d(`systems.accessHint`):d(t.environment.id===`gateway`?`systems.noHostDesktopHint`:`systems.noDesktopHint`):d(`systems.offlineHint`):d(`systems.selectHint`);return S`<section class="systems-workspace" aria-label=${d(`systems.title`)}>
<header class="systems-toolbar">
<div class="systems-heading">
<h1>${r}</h1>
<span>${d(t?`systems.`+H(t):`systems.selectHint`)}</span>
</div>
<select
class="systems-mobile-picker"
aria-label=${d(`systems.select`)}
@change=${t=>{t.currentTarget instanceof HTMLSelectElement&&e.select(t.currentTarget.value)}}
>
<option value="" disabled .selected=${!t}>${d(`systems.select`)}</option>
${e.rows.map(t=>S`<option value=${t.environment.id} .selected=${t.environment.id===e.selectedId}>${V(t)}</option>`)}
</select>
<button
class="systems-icon-button"
title=${d(e.showStats?`systems.hideStats`:`systems.stats`)}
aria-label=${d(e.showStats?`systems.hideStats`:`systems.stats`)}
aria-pressed=${e.showStats}
@click=${()=>e.toggleStats()}
>
${v.activity}
</button>
<button
class="systems-icon-button"
title=${d(`systems.details`)}
aria-label=${d(`systems.details`)}
aria-pressed=${e.showDetails}
?disabled=${!t}
@click=${()=>e.toggleDetails()}
>
${v.panelRightOpen}
</button>
</header>
${e.error?S`<div class="systems-callout systems-callout--error" role="alert">${e.error}<button @click=${()=>void e.refresh(`manual`)} ?disabled=${e.loading}>${d(`common.retry`)}</button></div>`:C}
${e.connected?C:S`<div class="systems-callout" role="status">${d(`systems.offlineGateway`)}</div>`}
${i.length?S`<details class="systems-callout">
<summary>${d(`systems.errors`)}</summary>
${i.map(e=>S`<p>${e}</p>`)}
</details>`:C}
${e.showStats&&t?Z(t,e):C}
<div class="systems-body">
<div class="systems-desktop">
${n&&t?S`<openclaw-desktop-panel
embedded
data-chat-autotype-exempt
.client=${e.context.gateway.snapshot.client}
.available=${e.desktopAvailable}
.presented=${this.presented}
.workspaceControls=${!0}
.suppliedEnvironments=${e.inventory?.environments??[]}
.requestedSource=${t.environment.id}
.basePath=${e.context.basePath}
></openclaw-desktop-panel>`:t?.environment.id===`gateway`&&e.connected&&t.environment.status===`available`&&(t.environment.desktopSetup||t.environment.desktop&&e.hostDesktopEnabled&&e.context.runtimeConfig.canPatch===!0)?this.renderHostDesktopSetup(e,t):S`<div class="systems-state" role="status">
<span class="systems-state__icon" aria-hidden="true">${v.monitor}</span>
<h2>${a}</h2>
<p>${o}</p>
${t?S`<button class="systems-text-button" @click=${()=>e.toggleDetails()}>${d(`systems.details`)}</button>`:C}
</div>`}
</div>
${e.showDetails&&t?this.renderDetails(e,t):C}
</div>
</section>`}},r([E({attribute:!1})],Q.prototype,`routeData`,void 0),r([E({type:Boolean})],Q.prototype,`presented`,void 0),customElements.get(`openclaw-systems-page`)||customElements.define(`openclaw-systems-page`,Q)})))()}$();export{ke as load,De as render,Oe as renderSidebar};