@@ -96,6 +96,8 @@ class WorkspaceV2SessionProducer {
9696 this . diffOutputSelectionKey = "" ;
9797 this . recentSessionInventory = [ ] ;
9898 this . workspaceManifestGames = [ ] ;
99+ this . workspaceImportedToolEntries = { } ;
100+ this . workspaceToolsSummaryNode = null ;
99101 this . loadFixtureButton . addEventListener ( "click" , ( ) => {
100102 this . loadSelectedFixture ( ) ;
101103 } ) ;
@@ -219,6 +221,7 @@ class WorkspaceV2SessionProducer {
219221 this . applyDefaultWorkspaceToolSelection ( ) ;
220222 this . registerScrollTextColorRule ( ) ;
221223 this . initializeImportExportSectionStatusNode ( ) ;
224+ this . initializeWorkspaceToolsSummaryNode ( ) ;
222225 this . initializeHiddenImportFileInput ( ) ;
223226 this . initializeImportTextareaButton ( ) ;
224227 this . decodeSessionParamFromUrl ( ) ;
@@ -281,10 +284,75 @@ class WorkspaceV2SessionProducer {
281284 this . importExportStatusNode = statusNode ;
282285 }
283286
287+ initializeWorkspaceToolsSummaryNode ( ) {
288+ const heading = Array . from ( document . querySelectorAll ( "h2" ) ) . find ( ( node ) => {
289+ return node . textContent && node . textContent . trim ( ) === "Import / Export Session JSON" ;
290+ } ) ;
291+ if ( ! heading ) {
292+ return ;
293+ }
294+ const section = heading . closest ( "section" ) ;
295+ if ( ! section ) {
296+ return ;
297+ }
298+ const existingNode = document . getElementById ( "workspaceV2WorkspaceToolsSummary" ) ;
299+ if ( existingNode ) {
300+ this . workspaceToolsSummaryNode = existingNode ;
301+ this . renderWorkspaceToolsSummary ( ) ;
302+ return ;
303+ }
304+ const summaryNode = document . createElement ( "p" ) ;
305+ summaryNode . id = "workspaceV2WorkspaceToolsSummary" ;
306+ section . appendChild ( summaryNode ) ;
307+ this . workspaceToolsSummaryNode = summaryNode ;
308+ this . renderWorkspaceToolsSummary ( ) ;
309+ }
310+
311+ readWorkspaceToolsFromTextarea ( ) {
312+ const rawJson = typeof this . workspaceJsonNode . value === "string" ? this . workspaceJsonNode . value . trim ( ) : "" ;
313+ if ( ! rawJson ) {
314+ return [ ] ;
315+ }
316+ const parsed = this . safeParseJson ( rawJson ) ;
317+ if ( ! parsed . ok || ! parsed . value || typeof parsed . value !== "object" || Array . isArray ( parsed . value ) ) {
318+ return [ ] ;
319+ }
320+ if ( ! parsed . value . tools || typeof parsed . value . tools !== "object" || Array . isArray ( parsed . value . tools ) ) {
321+ return [ ] ;
322+ }
323+ return Object . keys ( parsed . value . tools ) . sort ( ( left , right ) => left . localeCompare ( right ) ) ;
324+ }
325+
326+ workspaceToolSummaryEntries ( ) {
327+ const fromTextarea = this . readWorkspaceToolsFromTextarea ( ) ;
328+ if ( fromTextarea . length > 0 ) {
329+ return fromTextarea ;
330+ }
331+ const entries = [ "palette-browser" , "workspace-v2" ] ;
332+ const importedToolIds = Object . keys ( this . workspaceImportedToolEntries || { } ) . sort ( ( left , right ) => left . localeCompare ( right ) ) ;
333+ importedToolIds . forEach ( ( toolId ) => {
334+ if ( ! entries . includes ( toolId ) ) {
335+ entries . push ( toolId ) ;
336+ }
337+ } ) ;
338+ return entries ;
339+ }
340+
341+ renderWorkspaceToolsSummary ( ) {
342+ if ( ! this . workspaceToolsSummaryNode ) {
343+ return ;
344+ }
345+ const entries = this . workspaceToolSummaryEntries ( ) ;
346+ this . workspaceToolsSummaryNode . textContent = entries . length > 0
347+ ? `Workspace Tools: ${ entries . join ( ", " ) } `
348+ : "Workspace Tools: none" ;
349+ }
350+
284351 setImportExportStatus ( message ) {
285352 if ( this . importExportStatusNode ) {
286353 this . importExportStatusNode . textContent = message ;
287354 }
355+ this . renderWorkspaceToolsSummary ( ) ;
288356 this . statusNode . textContent = message ;
289357 }
290358
@@ -3104,6 +3172,7 @@ class WorkspaceV2SessionProducer {
31043172 this . resetUrlState ( false ) ;
31053173 this . currentHostContextId = "" ;
31063174 this . workspaceActivePalette = null ;
3175+ this . workspaceImportedToolEntries = { } ;
31073176 this . setCurrentSessionPayload ( null , "" ) ;
31083177 this . initializeWorkspaceProducerSession ( ) ;
31093178 this . refreshPaletteOwnershipStateAndUi ( ) ;
@@ -3122,6 +3191,7 @@ class WorkspaceV2SessionProducer {
31223191 this . renderSessionLibrary ( ) ;
31233192 this . renderErrorLogsViewer ( ) ;
31243193 this . renderDiagnosticsPanel ( ) ;
3194+ this . renderWorkspaceToolsSummary ( ) ;
31253195 this . statusNode . textContent = "Workspace V2 full reset complete. Workspace manifest baseline restored." ;
31263196 }
31273197
@@ -3507,6 +3577,7 @@ class WorkspaceV2SessionProducer {
35073577 return false ;
35083578 }
35093579 this . workspaceJsonNode . value = JSON . stringify ( workspaceSchemaDocument , null , 2 ) ;
3580+ this . renderWorkspaceToolsSummary ( ) ;
35103581 return true ;
35113582 }
35123583
@@ -3551,24 +3622,28 @@ class WorkspaceV2SessionProducer {
35513622 name : "Workspace V2 Session"
35523623 } ;
35533624 }
3625+ const manifestTools = { } ;
3626+ const importedToolIds = Object . keys ( this . workspaceImportedToolEntries || { } ) . sort ( ( left , right ) => left . localeCompare ( right ) ) ;
3627+ importedToolIds . forEach ( ( toolId ) => {
3628+ manifestTools [ toolId ] = this . cloneSessionValue ( this . workspaceImportedToolEntries [ toolId ] ) ;
3629+ } ) ;
3630+ manifestTools [ "palette-browser" ] = this . cloneSessionValue ( activePaletteResolution . paletteBrowserPayload ) ;
3631+ manifestTools [ "workspace-v2" ] = {
3632+ schema : "html-js-gaming.workspace-v2-session/1" ,
3633+ game : workspaceGame ,
3634+ defaultToolId : "palette-manager-v2" ,
3635+ activeToolId,
3636+ activeHostContextId,
3637+ activeSession : this . cloneSessionValue ( activePayload ) ,
3638+ savedSessions : this . cloneSessionValue ( library )
3639+ } ;
35543640 const workspaceDocument = {
35553641 documentKind : "workspace-manifest" ,
35563642 schema : "html-js-gaming.project" ,
35573643 version : 1 ,
35583644 id : `workspace-v2-${ activeHostContextId } ` ,
35593645 name : `Workspace V2 Session ${ activeToolId } ` ,
3560- tools : {
3561- "palette-browser" : this . cloneSessionValue ( activePaletteResolution . paletteBrowserPayload ) ,
3562- "workspace-v2" : {
3563- schema : "html-js-gaming.workspace-v2-session/1" ,
3564- game : workspaceGame ,
3565- defaultToolId : "palette-manager-v2" ,
3566- activeToolId,
3567- activeHostContextId,
3568- activeSession : this . cloneSessionValue ( activePayload ) ,
3569- savedSessions : this . cloneSessionValue ( library )
3570- }
3571- }
3646+ tools : manifestTools
35723647 } ;
35733648 return workspaceDocument ;
35743649 }
@@ -3690,13 +3765,6 @@ class WorkspaceV2SessionProducer {
36903765 if ( Object . prototype . hasOwnProperty . call ( workspaceDocument . tools , "palette" ) ) {
36913766 return { ok : false , message : "Use tools.palette-browser. Workspace supports one active palette tool entry." } ;
36923767 }
3693- const toolsKeys = Object . keys ( workspaceDocument . tools ) ;
3694- const allowedToolsKeys = new Set ( [ "palette-browser" , "workspace-v2" ] ) ;
3695- for ( const key of toolsKeys ) {
3696- if ( ! allowedToolsKeys . has ( key ) ) {
3697- return { ok : false , message : `tools.${ key } is not allowed.` } ;
3698- }
3699- }
37003768 if ( ! Object . prototype . hasOwnProperty . call ( workspaceDocument . tools , "palette-browser" ) ) {
37013769 return { ok : false , message : "tools.palette-browser is required." } ;
37023770 }
@@ -3834,6 +3902,14 @@ class WorkspaceV2SessionProducer {
38343902 this . setImportExportStatus ( `Import error: ${ validation . message } ` ) ;
38353903 return ;
38363904 }
3905+ this . workspaceImportedToolEntries = { } ;
3906+ const importedToolIds = Object . keys ( parsed . tools ) . sort ( ( left , right ) => left . localeCompare ( right ) ) ;
3907+ importedToolIds . forEach ( ( toolId ) => {
3908+ if ( toolId === "palette-browser" || toolId === "workspace-v2" ) {
3909+ return ;
3910+ }
3911+ this . workspaceImportedToolEntries [ toolId ] = this . cloneSessionValue ( parsed . tools [ toolId ] ) ;
3912+ } ) ;
38373913 const workspaceV2Tool = parsed . tools [ "workspace-v2" ] ;
38383914 this . workspaceManifestGames = [ this . cloneSessionValue ( workspaceV2Tool . game ) ] ;
38393915 const activeHostContextId = workspaceV2Tool . activeHostContextId . trim ( ) ;
@@ -3856,6 +3932,7 @@ class WorkspaceV2SessionProducer {
38563932 this . refreshPaletteOwnershipStateAndUi ( ) ;
38573933 this . refreshWorkspaceSessionUiStateModel ( "refresh_load" ) ;
38583934 this . renderDiagnosticsPanel ( ) ;
3935+ this . renderWorkspaceToolsSummary ( ) ;
38593936 this . setImportExportStatus ( "Workspace session imported." ) ;
38603937 } catch ( error ) {
38613938 this . setImportExportStatus ( `Import error: ${ error instanceof Error ? error . message : "unknown error" } ` ) ;
0 commit comments