@@ -92,7 +92,7 @@ export function WorkspacesPage() {
9292
9393 const [ selected , setSelected ] = useState < Selected | null > ( null ) ;
9494 const [ searchQuery , setSearchQuery ] = useState ( '' ) ;
95- const [ filter , setFilter ] = useState < 'all' | 'live' | 'unmapped' > ( 'all' ) ;
95+ const [ filter , setFilter ] = useState < 'all' | 'live' | 'mapped' | ' unmapped'> ( 'all' ) ;
9696
9797 const loadData = useCallback ( async ( ) => {
9898 setError ( null ) ;
@@ -205,6 +205,7 @@ export function WorkspacesPage() {
205205 const q = searchQuery . trim ( ) . toLowerCase ( ) ;
206206 return entries . filter ( ( e ) => {
207207 if ( filter === 'live' && ! e . isLive ) return false ;
208+ if ( filter === 'mapped' && ! e . binding ) return false ;
208209 if ( filter === 'unmapped' && e . kind !== 'unmapped-live' ) return false ;
209210 if ( ! q ) return true ;
210211 const spaceName = e . binding ? spaceById . get ( e . binding . space_id ) ?. name ?? '' : '' ;
@@ -223,12 +224,14 @@ export function WorkspacesPage() {
223224
224225 const counts = useMemo ( ( ) => {
225226 let live = 0 ;
227+ let mapped = 0 ;
226228 let unmapped = 0 ;
227229 for ( const e of entries ) {
228230 if ( e . isLive ) live ++ ;
231+ if ( e . binding ) mapped ++ ;
229232 if ( e . kind === 'unmapped-live' ) unmapped ++ ;
230233 }
231- return { all : entries . length , live, unmapped } ;
234+ return { all : entries . length , live, mapped , unmapped } ;
232235 } , [ entries ] ) ;
233236
234237 const selectedEntry : Entry | null =
@@ -316,8 +319,9 @@ export function WorkspacesPage() {
316319 Map a folder to the tools it should get. When you open that
317320 folder in a connected app — Cursor, VS Code, Claude — McpMux
318321 serves exactly the tools you chose for it. Folders you
319- haven't mapped don't receive your tools until you map
320- them.
322+ haven't mapped fall back to your default Starter set, so
323+ they work out of the box — map one only when it should see
324+ something different.
321325 </ p >
322326 </ div >
323327 < div className = "flex-shrink-0 flex items-center gap-2" >
@@ -362,6 +366,7 @@ export function WorkspacesPage() {
362366 options = { [
363367 { value : 'all' , label : 'All' , count : counts . all } ,
364368 { value : 'live' , label : 'Live' , count : counts . live } ,
369+ { value : 'mapped' , label : 'Mapped' , count : counts . mapped } ,
365370 { value : 'unmapped' , label : 'Unmapped' , count : counts . unmapped } ,
366371 ] }
367372 />
@@ -408,9 +413,8 @@ export function WorkspacesPage() {
408413 const isSelected =
409414 selected ?. mode === 'entry' && selected . id === entry . id ;
410415 // Mapped entries show their bound Space + FeatureSet names.
411- // Unmapped entries deliberately show no preview — the card
412- // reads "Not mapped" because the folder genuinely gets no
413- // tools until the user maps it.
416+ // Unmapped entries read "Not mapped" — they fall back to the
417+ // default Starter set rather than to an explicit binding.
414418 const resolvedSpaceName = entry . binding
415419 ? spaceById . get ( entry . binding . space_id ) ?. name
416420 : undefined ;
@@ -522,6 +526,8 @@ function SegmentedFilter<T extends string>({
522526 key = { o . value }
523527 type = "button"
524528 onClick = { ( ) => onChange ( o . value ) }
529+ data-testid = { `workspace-filter-${ o . value } ` }
530+ aria-pressed = { active }
525531 className = { [
526532 'inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg transition-all' ,
527533 active
@@ -692,7 +698,7 @@ function EntryCard({
692698 ) : (
693699 < span className = "inline-flex items-center gap-1.5 font-medium text-amber-600 dark:text-amber-400" >
694700 < AlertCircle className = "h-3.5 w-3.5 flex-shrink-0" />
695- Not mapped — no tools until you map it
701+ Not mapped — using your default Starter tools
696702 </ span >
697703 ) }
698704 </ div >
@@ -980,7 +986,7 @@ function InspectorPanel({
980986 mode === 'create'
981987 ? 'Choose the folder and the tools it should get.'
982988 : mode === 'create-from-live'
983- ? 'This folder is open in an app but has no tools yet — map it.'
989+ ? 'This folder is open in an app and using your default Starter tools — map it to give it a specific set instead .'
984990 : isMapped && entry ?. binding
985991 ? `Gives ${
986992 formatFsList (
@@ -1280,7 +1286,7 @@ function EffectiveFeaturesContent({
12801286 title = {
12811287 data . source === 'binding'
12821288 ? 'A workspace binding matched this folder — live sessions reporting it route here.'
1283- : 'No binding matches this folder. A live roots-capable session would be denied; the FeatureSet shown is a preview of what binding here would expose .'
1289+ : 'No binding matches this folder, so it falls back to the default Starter set shown here. Map it to give this folder a different set .'
12841290 }
12851291 className = { [
12861292 'ml-auto text-[10px] px-2 py-0.5 rounded-full font-bold uppercase tracking-wider border' ,
0 commit comments