@@ -25,6 +25,7 @@ import type {
2525} from "../../lib/board/view-types.ts" ;
2626import { OpenClawLightDomElement } from "../../lit/openclaw-element.ts" ;
2727import "../../styles/board.css" ;
28+ import { McpAppUnmountGate } from "../mcp-app-unmount.ts" ;
2829import "../web-awesome-tabs.ts" ;
2930import "../web-awesome.ts" ;
3031import type { BoardWidgetCellCallbacks } from "./board-widget-cell.ts" ;
@@ -85,6 +86,7 @@ class OpenClawBoardView extends OpenClawLightDomElement {
8586 private mutationRequestId = 0 ;
8687 private stableCellOrder = new Map < string , number > ( ) ;
8788 private stableCellOrderSequence = 0 ;
89+ private readonly mcpAppUnmountGate = new McpAppUnmountGate ( this ) ;
8890
8991 override willUpdate ( changed : PropertyValues < this> ) : void {
9092 if ( changed . has ( "snapshot" ) ) {
@@ -207,6 +209,12 @@ class OpenClawBoardView extends OpenClawLightDomElement {
207209 frameLoadFailed : async ( name ) => {
208210 await this . callbacks ?. frameLoadFailed ?.( name ) ;
209211 } ,
212+ widgetAppView : async ( name , revision , refresh ) => {
213+ if ( ! this . callbacks ?. widgetAppView ) {
214+ return { status : "stale" , error : t ( "board.widget.appUnavailable" ) } ;
215+ }
216+ return await this . callbacks . widgetAppView ( name , revision , refresh ) ;
217+ } ,
210218 } ;
211219
212220 private beginGesture (
@@ -592,7 +600,7 @@ class OpenClawBoardView extends OpenClawLightDomElement {
592600 const activeTab = this . activeTab ( tabs ) ;
593601 const activeTabId = activeTab ?. tabId ?? this . activeTabId ;
594602 const widgets = activeTab ? orderedWidgets ( snapshot , activeTab . tabId ) : [ ] ;
595- return html `
603+ const rendered = html `
596604 < section class ="board-view " aria-label =${ t ( "board.label" ) } >
597605 ${ this . renderTabs ( tabs , activeTabId ) } ${ this . renderGrid ( widgets , tabs , snapshot . sessionKey ) }
598606 ${ this . actionError
@@ -610,6 +618,18 @@ class OpenClawBoardView extends OpenClawLightDomElement {
610618 </ div >
611619 </ section >
612620 ` ;
621+ const nextMcpAppKeys = new Set (
622+ widgets
623+ . filter ( ( widget ) => widget . contentKind === "mcp-app" )
624+ . map ( ( widget ) => `${ snapshot . sessionKey } \0${ widget . name } ` ) ,
625+ ) ;
626+ return this . mcpAppUnmountGate . render ( JSON . stringify ( [ ...nextMcpAppKeys ] ) , rendered , ( ) =>
627+ [ ...this . querySelectorAll ( "openclaw-board-widget-cell" ) ] . filter (
628+ ( cell ) =>
629+ cell . widget ?. contentKind === "mcp-app" &&
630+ ! nextMcpAppKeys . has ( `${ cell . sessionKey } \0${ cell . widget . name } ` ) ,
631+ ) ,
632+ ) ;
613633 }
614634}
615635
0 commit comments