@@ -59,6 +59,7 @@ import { ScenarioArt } from './home-hero/ScenarioArt';
5959import { useEdgeAutoScroll , EdgeScrollZones } from './home-hero/EdgeAutoScroll' ;
6060import {
6161 isSubChipParent ,
62+ prototypeSubChipForSlug ,
6263 subChipsForChip ,
6364 type HomeHeroSubChip ,
6465} from './home-hero/sub-chips' ;
@@ -165,6 +166,9 @@ interface Props {
165166 activePluginIsExplicit ?: boolean ;
166167 activePluginRecord ?: InstalledPluginRecord | null ;
167168 activeChipId : string | null ;
169+ // Prototype's selected second-level scene is owned by HomeView so action
170+ // metadata and persistence stay aligned with the visible filter selection.
171+ activePrototypeSubtypeId ?: string | null ;
168172 onClearActivePlugin : ( ) => void ;
169173 onClearActiveChip ?: ( ) => void ;
170174 activeSkillId ?: string | null ;
@@ -229,6 +233,7 @@ interface Props {
229233 onPickMcp ?: ( server : McpServerConfig , nextPrompt : string ) => void ;
230234 onPickConnector ?: ( connector : ConnectorDetail , nextPrompt : string ) => void ;
231235 onPickChip : ( chip : HomeHeroChip ) => void ;
236+ onPickPrototypeSubtype ?: ( sub : HomeHeroSubChip | null ) => void ;
232237 contextItemCount : number ;
233238 error : string | null ;
234239 showActivePluginChip ?: boolean ;
@@ -357,6 +362,8 @@ export const HomeHero = forwardRef<HomeHeroHandle, Props>(function HomeHero(
357362 onPickMcp = ( ) => undefined ,
358363 onPickConnector = ( ) => undefined ,
359364 onPickChip,
365+ activePrototypeSubtypeId,
366+ onPickPrototypeSubtype,
360367 contextItemCount,
361368 error,
362369 showActivePluginChip = true ,
@@ -392,9 +399,14 @@ export const HomeHero = forwardRef<HomeHeroHandle, Props>(function HomeHero(
392399 const [ guidePulseChipId , setGuidePulseChipId ] = useState < string | null > ( null ) ;
393400 const [ guidePulseFirstPreset , setGuidePulseFirstPreset ] = useState ( false ) ;
394401 // Selected second-level sub-category slug (Prototype / Slide deck rail).
395- // Local-only: it filters the example-prompt cards below the rail. It never
396- // binds a plugin or stamps an active badge.
397- const [ selectedSubcategory , setSelectedSubcategory ] = useState < string | null > ( null ) ;
402+ // Deck remains a local example filter. Prototype is controlled by HomeView:
403+ // every scene binds the Prototype action, while Mobile/Wireframe additionally
404+ // retain the project metadata from their former top-level actions.
405+ const [ localSelectedSubcategory , setLocalSelectedSubcategory ] = useState < string | null > ( null ) ;
406+ const selectedSubcategory =
407+ activeChipId === 'prototype' && activePrototypeSubtypeId !== undefined
408+ ? activePrototypeSubtypeId
409+ : localSelectedSubcategory ;
398410 // Footer Template pill preview: the create-rail card the pointer is over,
399411 // so hovering a card below previews it in the pill (cleared on rail-leave).
400412 const [ previewTemplateId , setPreviewTemplateId ] = useState < string | null > ( null ) ;
@@ -439,13 +451,17 @@ export const HomeHero = forwardRef<HomeHeroHandle, Props>(function HomeHero(
439451 // with nothing bound we cycle the full set. Memoised by chip + locale so the
440452 // reference only changes on a real switch, which restarts the carousel.
441453 const carouselScenarios = useMemo < PlaceholderScenario [ ] > ( ( ) => {
454+ const nestedActionChipId =
455+ activeChipId === 'prototype'
456+ ? prototypeSubChipForSlug ( activePrototypeSubtypeId ?? null ) ?. actionChipId ?? null
457+ : null ;
442458 return buildPlaceholderScenarios ( {
443- activeChipId,
459+ activeChipId : nestedActionChipId ?? activeChipId ,
444460 resolveTextKey : ( key ) => t ( key ) ,
445461 examplesForChip : ( chipId ) => homeHeroChipPromptExamples ( chipId , locale ) ,
446462 fallbackForChip : ( chipId ) => fallbackPlaceholderScenarioText ( chipId , locale , t ) ,
447463 } ) ;
448- } , [ activeChipId , locale , t ] ) ;
464+ } , [ activeChipId , activePrototypeSubtypeId , locale , t ] ) ;
449465 // The placeholder carousel runs while the composer is empty and nothing
450466 // OTHER than a create-template chip is bound. A selected template keeps it
451467 // alive (showing that template's scenarios); only an explicit plugin/skill
@@ -738,9 +754,19 @@ export const HomeHero = forwardRef<HomeHeroHandle, Props>(function HomeHero(
738754 // deck/image plugin that merely carries a "brand" tag is not pulled in.
739755 const filteredExamplePlugins = useMemo ( ( ) => {
740756 if ( ! selectedSubcategory || ! isSubChipParent ( activeChipId ) ) return activeExamplePlugins ;
757+ // Mobile shares the existing Apps facet. Wireframe is a generation
758+ // constraint rather than a plugin taxonomy, so keep the Prototype starter
759+ // pool visible while the selected action carries its lo-fi metadata.
760+ const facetSubcategory =
761+ activeChipId === 'prototype' && selectedSubcategory === 'mobile'
762+ ? 'app-prototypes'
763+ : activeChipId === 'prototype' && selectedSubcategory === 'wireframe'
764+ ? null
765+ : selectedSubcategory ;
766+ if ( ! facetSubcategory ) return activeExamplePlugins ;
741767 const pool = pluginOptions . filter ( ( plugin ) => plugin . manifest ?. od ?. kind !== 'atom' ) ;
742768 return sortByVisualAppeal (
743- applyFacetSelection ( pool , { category : activeChipId , subcategory : selectedSubcategory } ) ,
769+ applyFacetSelection ( pool , { category : activeChipId , subcategory : facetSubcategory } ) ,
744770 ) ;
745771 } , [ activeExamplePlugins , activeChipId , selectedSubcategory , pluginOptions ] ) ;
746772
@@ -853,7 +879,7 @@ export const HomeHero = forwardRef<HomeHeroHandle, Props>(function HomeHero(
853879
854880 useEffect ( ( ) => {
855881 setSelectedPromptExample ( null ) ;
856- setSelectedSubcategory ( null ) ;
882+ setLocalSelectedSubcategory ( null ) ;
857883 } , [ activeChipId ] ) ;
858884
859885 useEffect ( ( ) => {
@@ -1270,7 +1296,7 @@ export const HomeHero = forwardRef<HomeHeroHandle, Props>(function HomeHero(
12701296 < PixelScanLogo className = "home-hero__logo home-hero__logo--tiles" />
12711297 </ span >
12721298
1273- { /* Capsule type row: the 12 create-scenario types as pill chips above
1299+ { /* Capsule type row: the 10 top-level create-scenario types as pill chips above
12741300 the composer (per product — replaces the fanned card carousel); the
12751301 selected pill carries the accent tint, click switches. */ }
12761302 < TypePillRow
@@ -2103,7 +2129,9 @@ export const HomeHero = forwardRef<HomeHeroHandle, Props>(function HomeHero(
21032129 chip_id : activeChipId ?? undefined ,
21042130 subcategory : sub . slug ,
21052131 } ) ;
2106- setSelectedSubcategory ( ( current ) => ( current === sub . slug ? null : sub . slug ) ) ;
2132+ const next = selectedSubcategory === sub . slug ? null : sub ;
2133+ setLocalSelectedSubcategory ( next ?. slug ?? null ) ;
2134+ if ( activeChipId === 'prototype' ) onPickPrototypeSubtype ?.( next ) ;
21072135 } }
21082136 onSelectAll = { ( ) => {
21092137 trackHomeChatComposerClick ( analytics . track , {
@@ -2113,7 +2141,8 @@ export const HomeHero = forwardRef<HomeHeroHandle, Props>(function HomeHero(
21132141 chip_id : activeChipId ?? undefined ,
21142142 subcategory : 'all' ,
21152143 } ) ;
2116- setSelectedSubcategory ( null ) ;
2144+ setLocalSelectedSubcategory ( null ) ;
2145+ if ( activeChipId === 'prototype' ) onPickPrototypeSubtype ?.( null ) ;
21172146 } }
21182147 />
21192148 ) : null }
@@ -3409,7 +3438,7 @@ function SubTypeChip({
34093438 >
34103439 < Icon name = { sub . icon } size = { 13 } className = "home-hero__subtype-chip-icon" />
34113440 < span className = "home-hero__subtype-chip-label" >
3412- { pluginSubfacetLabel ( sub . slug , sub . label , t ) }
3441+ { homeHeroSubChipLabel ( sub , t ) }
34133442 </ span >
34143443 </ button >
34153444 ) ;
@@ -3570,7 +3599,7 @@ function SubTypeRow({
35703599 >
35713600 < Icon name = { sub . icon } size = { 13 } className = "home-hero__subtype-chip-icon" />
35723601 < span className = "home-hero__subtype-chip-label" >
3573- { pluginSubfacetLabel ( sub . slug , sub . label , t ) }
3602+ { homeHeroSubChipLabel ( sub , t ) }
35743603 </ span >
35753604 { isActive ? < Icon name = "check" size = { 13 } /> : null }
35763605 </ button >
@@ -3590,7 +3619,7 @@ function SubTypeRow({
35903619 < span key = { sub . slug } className = "home-hero__subtype-chip" data-measure = "chip" >
35913620 < Icon name = { sub . icon } size = { 13 } className = "home-hero__subtype-chip-icon" />
35923621 < span className = "home-hero__subtype-chip-label" >
3593- { pluginSubfacetLabel ( sub . slug , sub . label , t ) }
3622+ { homeHeroSubChipLabel ( sub , t ) }
35943623 </ span >
35953624 </ span >
35963625 ) ) }
@@ -3603,6 +3632,15 @@ function SubTypeRow({
36033632 ) ;
36043633}
36053634
3635+ function homeHeroSubChipLabel (
3636+ sub : HomeHeroSubChip ,
3637+ t : ReturnType < typeof useT > ,
3638+ ) : string {
3639+ if ( sub . slug === 'mobile' ) return t ( 'homeHero.chip.mobile' ) ;
3640+ if ( sub . slug === 'wireframe' ) return t ( 'homeHero.chip.wireframe' ) ;
3641+ return pluginSubfacetLabel ( sub . slug , sub . label , t ) ;
3642+ }
3643+
36063644interface ShortcutsMenuProps {
36073645 activeChipId : string | null ;
36083646 pendingChipId : string | null ;
0 commit comments