opencode-navigator 0.18.1 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tui.js CHANGED
@@ -2,7 +2,7 @@ import {insert as _$insert,setProp as _$setProp,createElement as _$createElement
2
2
 
3
3
 
4
4
 
5
- import {createSignal as createSignal2,createSignal,createEffect,onCleanup,createContext,useContext,createContext as createContext2,createSignal as createSignal3,useContext as useContext2,createEffect as createEffect2,splitProps,untrack,splitProps as splitProps2,For,createEffect as createEffect3,onCleanup as onCleanup2,Show,splitProps as splitProps3,createSignal as createSignal4,createSignal as createSignal5,createSignal as createSignal6,onCleanup as onCleanup3,batch,createSignal as createSignal8,createSignal as createSignal7,createEffect as createEffect4,createSignal as createSignal9,onCleanup as onCleanup4,createSignal as createSignal10,createSignal as createSignal11,Index,createSignal as createSignal12,onCleanup as onCleanup5,createEffect as createEffect6,onCleanup as onCleanup7,batch as batch2,createEffect as createEffect5,createMemo,createSignal as createSignal13,onCleanup as onCleanup6,onMount,For as For2,For as For3,Show as Show2,createMemo as createMemo2,Show as Show3,createSignal as createSignal14,onCleanup as onCleanup8,For as For4,For as For5,For as For8,createMemo as createMemo4,onMount as onMount3,For as For7,createMemo as createMemo3,onMount as onMount2,Show as Show5,createEffect as createEffect7,createSignal as createSignal15,onCleanup as onCleanup9,Show as Show4,For as For6,For as For9,createEffect as createEffect8,createMemo as createMemo5,onCleanup as onCleanup10,For as For10,createEffect as createEffect9,createMemo as createMemo8,onCleanup as onCleanup11,onMount as onMount4,createMemo as createMemo6,createMemo as createMemo7,Show as Show6,onCleanup as onCleanup12,createSignal as createSignal16,createEffect as createEffect10,onCleanup as onCleanup13,onMount as onMount5,onCleanup as onCleanup14,onMount as onMount6,For as For11,createSignal as createSignal17,createSignal as createSignal18,Show as Show7,createSignal as createSignal20,createSignal as createSignal19,onCleanup as onCleanup15,For as For12,Show as Show10,createMemo as createMemo10,createComputed,createMemo as createMemo9,createSignal as createSignal21,untrack as untrack2,Show as Show8,createComputed as createComputed2,untrack as untrack3,Show as Show9,createEffect as createEffect11,createSignal as createSignal22,createMemo as createMemo12,createSignal as createSignal24,createMemo as createMemo11,For as For13,Show as Show13,Show as Show11,Show as Show12,createSignal as createSignal23,onCleanup as onCleanup16,For as For14,Show as Show15,createMemo as createMemo14,Show as Show14,createMemo as createMemo13,createSignal as createSignal25,createEffect as createEffect12,onCleanup as onCleanup17,For as For19,Match,Switch,createMemo as createMemo18,onCleanup as onCleanup21,For as For15,Show as Show16,createSignal as createSignal26,createEffect as createEffect13,createMemo as createMemo15,onCleanup as onCleanup18,untrack as untrack4,For as For17,Show as Show19,createEffect as createEffect14,createMemo as createMemo16,createSignal as createSignal27,onCleanup as onCleanup19,untrack as untrack5,For as For16,Show as Show18,Show as Show17,Show as Show23,createEffect as createEffect15,createMemo as createMemo17,createSignal as createSignal28,onCleanup as onCleanup20,untrack as untrack6,For as For18,Show as Show21,Show as Show20,Show as Show22,createEffect as createEffect16,createMemo as createMemo19,onCleanup as onCleanup22,untrack as untrack7,Show as Show24,createMemo as createMemo20,onCleanup as onCleanup23,createSignal as createSignal29,onCleanup as onCleanup24,onMount as onMount7} from "solid-js"
5
+ import {createSignal as createSignal2,createSignal,createEffect,onCleanup,createContext,useContext,createContext as createContext2,createSignal as createSignal3,useContext as useContext2,createEffect as createEffect2,splitProps,untrack,splitProps as splitProps2,For,createEffect as createEffect3,onCleanup as onCleanup2,Show,splitProps as splitProps3,createSignal as createSignal4,createSignal as createSignal5,createSignal as createSignal6,onCleanup as onCleanup3,batch,createSignal as createSignal8,createSignal as createSignal7,createEffect as createEffect4,createSignal as createSignal9,onCleanup as onCleanup4,createSignal as createSignal10,createSignal as createSignal11,Index,createSignal as createSignal12,onCleanup as onCleanup5,createEffect as createEffect6,onCleanup as onCleanup7,batch as batch2,createEffect as createEffect5,createMemo,createSignal as createSignal13,onCleanup as onCleanup6,onMount,For as For2,For as For3,Show as Show2,createMemo as createMemo2,Show as Show3,createSignal as createSignal14,onCleanup as onCleanup8,For as For4,For as For5,For as For8,createMemo as createMemo4,onMount as onMount3,For as For7,createMemo as createMemo3,onMount as onMount2,Show as Show5,createEffect as createEffect7,createSignal as createSignal15,onCleanup as onCleanup9,Show as Show4,For as For6,For as For9,createEffect as createEffect8,createMemo as createMemo5,onCleanup as onCleanup10,createEffect as createEffect9,createMemo as createMemo6,untrack as untrack2,For as For10,createEffect as createEffect10,createMemo as createMemo9,onCleanup as onCleanup11,onMount as onMount4,createMemo as createMemo7,createMemo as createMemo8,Show as Show6,onCleanup as onCleanup12,createSignal as createSignal16,createEffect as createEffect11,onCleanup as onCleanup13,onMount as onMount5,onCleanup as onCleanup14,onMount as onMount6,For as For11,createSignal as createSignal17,createSignal as createSignal18,Show as Show7,createSignal as createSignal20,createSignal as createSignal19,onCleanup as onCleanup15,For as For12,Show as Show10,createMemo as createMemo11,createComputed,createMemo as createMemo10,createSignal as createSignal21,untrack as untrack3,Show as Show8,createComputed as createComputed2,untrack as untrack4,Show as Show9,createEffect as createEffect12,createSignal as createSignal22,createMemo as createMemo13,createSignal as createSignal24,createMemo as createMemo12,For as For13,Show as Show14,Show as Show11,Show as Show12,Show as Show13,createSignal as createSignal23,onCleanup as onCleanup16,For as For14,Show as Show16,createMemo as createMemo15,Show as Show15,createMemo as createMemo14,createSignal as createSignal25,createEffect as createEffect13,onCleanup as onCleanup17,For as For19,Match,Switch,createMemo as createMemo19,onCleanup as onCleanup21,For as For15,Show as Show17,createSignal as createSignal26,createEffect as createEffect14,createMemo as createMemo16,onCleanup as onCleanup18,untrack as untrack5,For as For17,Show as Show20,createEffect as createEffect15,createMemo as createMemo17,createSignal as createSignal27,onCleanup as onCleanup19,untrack as untrack6,For as For16,Show as Show19,Show as Show18,Show as Show24,createEffect as createEffect16,createMemo as createMemo18,createSignal as createSignal28,onCleanup as onCleanup20,untrack as untrack7,For as For18,Show as Show22,Show as Show21,Show as Show23,createEffect as createEffect17,createMemo as createMemo20,onCleanup as onCleanup22,untrack as untrack8,Show as Show25,createMemo as createMemo21,onCleanup as onCleanup23,createSignal as createSignal29,onCleanup as onCleanup24,onMount as onMount7} from "solid-js"
6
6
  var SIDEBAR_SECTIONS=["todo","subagents","skills","quick_actions","lsp","mcp"]
7
7
  var QUICK_ACTION_IDS=["session.rename","session.timeline","session.copy","session.export","session.compact","session.list","session.new","session.fork","messages.copy","session.first","session.last","session.messages_last_user","session.message.next","session.message.previous","permission.mode"]
8
8
  function preferencesScope(path){return path.worktree||path.directory||"global"
@@ -189,6 +189,23 @@ function mcpToggleAction2(status){if(status==="pending")
189
189
  return
190
190
  return status==="connected"?"disconnect":"connect"
191
191
  }
192
+ var BUCKET_RANK={Favorites:0,Ungrouped:2}
193
+ function mcpGroupToggleAction(items){if(items.some((item)=>mcpToggleAction2(item.status)==="connect"))
194
+ return "connect"
195
+ return items.some((item)=>mcpToggleAction2(item.status)==="disconnect")?"disconnect":undefined
196
+ }
197
+ function buildMcpGroupedView(items,favorites,assignments){return items.map((item)=>({...item,assignedGroup:assignments[item.name],bucket:favorites.has(item.name)?"Favorites":assignments[item.name]??"Ungrouped"
198
+ })).sort((left,right)=>{const leftRank=BUCKET_RANK[left.bucket]??1
199
+ const rightRank=BUCKET_RANK[right.bucket]??1
200
+ return leftRank-rightRank||left.bucket.localeCompare(right.bucket)||left.name.localeCompare(right.name)
201
+ })
202
+ }
203
+ function bulkDescription(operation,action){if(operation.action==="preset")
204
+ return `apply ${operation.preset} MCP preset`
205
+ if(operation.group)
206
+ return `${action} ${operation.group} MCP group`
207
+ return `${action} all MCP servers`
208
+ }
192
209
  function matchingMcpPreset(items,presets){if(items.length===0)
193
210
  return
194
211
  return Object.keys(presets).sort((left,right)=>left.localeCompare(right)).find((name)=>{const states=presets[name]
@@ -377,8 +394,7 @@ const failed=[]
377
394
  const retry=[]
378
395
  await Promise.all(changes.map(async ({name,action})=>{if(operation.action!=="preset")
379
396
  save(current,name,action==="disconnect")
380
- try{const description=operation.action==="preset"?`apply ${operation.preset} MCP preset`:`${action} all MCP servers`
381
- await changeServer(current,name,action,description,false)
397
+ try{await changeServer(current,name,action,bulkDescription(operation,action),false)
382
398
  } catch(error){if(!isAbortError(error)){failed.push(name)
383
399
  retry.push({name,action})
384
400
  }} finally{setBulkStates((values)=>{if(bulkGenerations.get(current.key)!==generation)
@@ -396,7 +412,9 @@ await refresh(current,true).catch(()=>{})
396
412
  failed.sort((left,right)=>left.localeCompare(right))
397
413
  setBulkStates((values)=>({...values,[current.key]:{...operation,status:failed.length>0?"error":"ready",completed:changes.length,total:changes.length,failed
398
414
  }}))
399
- if(failed.length>0&&activeTarget===current.key){const action=operation.action==="preset"?`apply ${operation.preset}`:operation.action
415
+ if(failed.length>0&&activeTarget===current.key){let action=operation.action==="preset"?`apply ${operation.preset}`:operation.action
416
+ if(operation.group)
417
+ action += ` ${operation.group}`
400
418
  api.ui.toast({variant:"warning",title:"MCP servers",message:`Could not ${action}: ${failed.join(", ")}`,duration:4000
401
419
  })
402
420
  }}
@@ -445,19 +463,25 @@ return changeMany({action:"connect"},list(current).filter((item)=>mcpToggleActio
445
463
  return
446
464
  resetSelectedPreset(current)
447
465
  return changeMany({action:"disconnect"},list(current).filter((item)=>mcpToggleAction2(item.status)==="disconnect").map((item)=>({name:item.name,action:"disconnect"})),current)
466
+ },toggleGroup(group,names,current=target()){if(target().key!==current.key||mutating(current)||bulkState(current).status==="running")
467
+ return
468
+ const selected=new Set(names)
469
+ const items=list(current).filter((item)=>selected.has(item.name))
470
+ const action=mcpGroupToggleAction(items)
471
+ if(!action)
472
+ return
473
+ resetSelectedPreset(current)
474
+ if(action==="connect"){for(const item of items)
475
+ if(item.status==="connected")
476
+ save(current,item.name,false)
477
+ }
478
+ return changeMany({action,group},items.filter((item)=>mcpToggleAction2(item.status)===action).map((item)=>({name:item.name,action})),current)
448
479
  },retryBulk(current=target()){const state=bulkState(current)
449
480
  if(state.status!=="error"||state.failed.length===0)
450
481
  return
451
482
  const changes=bulkRetries.get(current.key)??[]
452
- return changeMany({action:state.action,...state.preset&&{preset:state.preset}},changes,current)
483
+ return changeMany({action:state.action,...state.preset&&{preset:state.preset},...state.group&&{group:state.group}},changes,current)
453
484
  }}}
454
- var BUCKET_RANK={Favorites:0,Ungrouped:2}
455
- function buildMcpGroupedView(items,favorites,assignments){return items.map((item)=>({...item,assignedGroup:assignments[item.name],bucket:favorites.has(item.name)?"Favorites":assignments[item.name]??"Ungrouped"
456
- })).sort((left,right)=>{const leftRank=BUCKET_RANK[left.bucket]??1
457
- const rightRank=BUCKET_RANK[right.bucket]??1
458
- return leftRank-rightRank||left.bucket.localeCompare(right.bucket)||left.name.localeCompare(right.name)
459
- })
460
- }
461
485
 
462
486
 
463
487
 
@@ -1036,6 +1060,17 @@ function McpErrorDialog(props){return _$createComponent(PresetMenu,{get api(){re
1036
1060
  },onSelect:()=>{}})
1037
1061
  }
1038
1062
 
1063
+ function assignGroup(groups,key,value){const next={...groups}
1064
+ if(!key)
1065
+ return next
1066
+ const group=value?.trim().slice(0,64)
1067
+ if(!group){delete next[key]
1068
+ return next
1069
+ }
1070
+ const canonical=Object.values(next).find((item)=>item.toLocaleLowerCase()===group.toLocaleLowerCase())
1071
+ next[key]=canonical??group
1072
+ return next
1073
+ }
1039
1074
  var PORTABLE_SETTINGS_FORMAT="opencode-navigator/settings"
1040
1075
  function object(value,path){if(!value||typeof value!=="object"||Array.isArray(value))
1041
1076
  throw new Error(`${path} must be an object`)
@@ -1178,6 +1213,7 @@ return Object.fromEntries(Object.entries(input).flatMap(([server,rawGroup])=>{co
1178
1213
  return server.trim()&&group?[[server,group]]:[]
1179
1214
  }))
1180
1215
  }
1216
+ var parseSkillGroups=parseMcpServerGroups
1181
1217
  function parseWorkspaceProfiles(value){return Object.fromEntries(Object.entries(record(value)??{}).flatMap(([layout,rawMcp])=>{const layoutName=layout.trim().slice(0,64)
1182
1218
  const mcpName=typeof rawMcp==="string"?rawMcp.trim().slice(0,64):""
1183
1219
  return layoutName&&mcpName?[[layoutName,mcpName]]:[]
@@ -1211,11 +1247,12 @@ const favoriteQuickActions=parseFavoriteQuickActions(userInput?.favoriteQuickAct
1211
1247
  const recentSkills=parseRecentSkills(userInput?.recentSkills)
1212
1248
  const recentQuickActions=parseRecentQuickActions(userInput?.recentQuickActions)
1213
1249
  const mcpServerGroups=parseMcpServerGroups(userInput?.mcpServerGroups)
1250
+ const skillGroups=parseSkillGroups(userInput?.skillGroups)
1214
1251
  const workspaceProfiles=parseWorkspaceProfiles(userInput?.workspaceProfiles)
1215
1252
  return{global:{...Object.keys(behavior).length>0&&{behavior},...layout&&{layout},...Object.keys(globalMcp).length>0&&{mcp:globalMcp}},worktrees,user:{...skippedSkillConfirmations&&{skippedSkillConfirmations},...typeof userInput?.onboardingCompleted==="boolean"&&{onboardingCompleted:userInput.onboardingCompleted
1216
1253
  },...typeof userInput?.lastNavigatorVersion==="string"&&{lastNavigatorVersion:userInput.lastNavigatorVersion
1217
1254
  },...typeof userInput?.previousNavigatorVersion==="string"&&{previousNavigatorVersion:userInput.previousNavigatorVersion
1218
- },...Object.keys(layoutPresets).length>0&&{layoutPresets},...Object.keys(mcpPresets).length>0&&{mcpPresets},...favoriteSkills&&{favoriteSkills},...favoriteMcpServers?.length&&{favoriteMcpServers},...favoriteQuickActions.length>0&&{favoriteQuickActions},...recentSkills.length>0&&{recentSkills},...recentQuickActions.length>0&&{recentQuickActions},...Object.keys(mcpServerGroups).length>0&&{mcpServerGroups},...Object.keys(workspaceProfiles).length>0&&{workspaceProfiles}}}}
1255
+ },...Object.keys(layoutPresets).length>0&&{layoutPresets},...Object.keys(mcpPresets).length>0&&{mcpPresets},...favoriteSkills&&{favoriteSkills},...favoriteMcpServers?.length&&{favoriteMcpServers},...favoriteQuickActions.length>0&&{favoriteQuickActions},...recentSkills.length>0&&{recentSkills},...recentQuickActions.length>0&&{recentQuickActions},...Object.keys(mcpServerGroups).length>0&&{mcpServerGroups},...Object.keys(skillGroups).length>0&&{skillGroups},...Object.keys(workspaceProfiles).length>0&&{workspaceProfiles}}}}
1219
1256
  function parseValues(value){if(!value)
1220
1257
  return{}
1221
1258
  return{behavior:parsePluginSettings(value.behavior),layout:{sections:parseSectionPreferences(value.layout?.sections),expanded:parseSectionPreferences(value.layout?.expanded),...parseSectionOrder(value.layout?.order)&&{order:parseSectionOrder(value.layout?.order)}},desiredMcpStates:parseDesiredMcpStates(value.desiredMcpStates)
@@ -1360,14 +1397,8 @@ favoriteQuickActions.delete(quickActionFavorite.id)
1360
1397
  }
1361
1398
  const recentSkills=parseRecentSkills([...update.user?.recentSkill?[update.user.recentSkill]:[],...current.user.recentSkills??[]])
1362
1399
  const recentQuickActions=parseRecentQuickActions([...update.user?.recentQuickAction?[update.user.recentQuickAction]:[],...current.user.recentQuickActions??[]])
1363
- const mcpServerGroups={...current.user.mcpServerGroups}
1364
- const groupUpdate=update.user?.mcpServerGroup
1365
- if(groupUpdate?.name){const group=groupUpdate.group?.trim().slice(0,64)
1366
- if(group){const canonical=Object.values(mcpServerGroups).find((value)=>value.toLocaleLowerCase()===group.toLocaleLowerCase())
1367
- mcpServerGroups[groupUpdate.name]=canonical??group
1368
- } else
1369
- delete mcpServerGroups[groupUpdate.name]
1370
- }
1400
+ const mcpServerGroups=assignGroup(current.user.mcpServerGroups,update.user?.mcpServerGroup?.name,update.user?.mcpServerGroup?.group)
1401
+ const skillGroups=assignGroup(current.user.skillGroups,update.user?.skillGroup?.location,update.user?.skillGroup?.group)
1371
1402
  const favoriteSkills=update.user?.favoriteSkills?parseSkillConfirmations(update.user.favoriteSkills):[...current.user.favoriteSkills??[]]
1372
1403
  const favoriteSkill=update.user?.favoriteSkill
1373
1404
  if(favoriteSkill?.location){const index=favoriteSkills.indexOf(favoriteSkill.location)
@@ -1383,7 +1414,7 @@ return{global:target.kind==="global"?scope:current.global,worktrees,user:{...ski
1383
1414
  },...(update.user?.previousNavigatorVersion??current.user.previousNavigatorVersion)&&{previousNavigatorVersion:update.user?.previousNavigatorVersion??current.user.previousNavigatorVersion
1384
1415
  },...Object.keys(parsedLayoutPresets).length>0&&{layoutPresets:parsedLayoutPresets},...Object.keys(parsedMcpPresets).length>0&&{mcpPresets:parsedMcpPresets},...Object.keys(workspaceProfiles).length>0&&{workspaceProfiles:parseWorkspaceProfiles(workspaceProfiles)
1385
1416
  },...favoriteSkills.length>0&&{favoriteSkills},...favoriteMcpServers.size>0&&{favoriteMcpServers:[...favoriteMcpServers].sort()},...favoriteQuickActions.size>0&&{favoriteQuickActions:parseFavoriteQuickActions([...favoriteQuickActions])
1386
- },...recentSkills.length>0&&{recentSkills},...recentQuickActions.length>0&&{recentQuickActions},...Object.keys(mcpServerGroups).length>0&&{mcpServerGroups:parseMcpServerGroups(mcpServerGroups)}}}}
1417
+ },...recentSkills.length>0&&{recentSkills},...recentQuickActions.length>0&&{recentQuickActions},...Object.keys(mcpServerGroups).length>0&&{mcpServerGroups:parseMcpServerGroups(mcpServerGroups)},...Object.keys(skillGroups).length>0&&{skillGroups:parseSkillGroups(skillGroups)}}}}
1387
1418
  function targetForLegacyScope(scope){return scope==="global"?{kind:"global"}:{kind:"worktree",key:scope}}
1388
1419
  function createPreferencesStore(stateDirectory){const directory=join(stateDirectory,LEGACY_PLUGIN_ID)
1389
1420
  const file=join(directory,"preferences.json")
@@ -1551,6 +1582,7 @@ const [favoriteQuickActions,setFavoriteQuickActions]=createSignal4(new Set)
1551
1582
  const [recentSkills,setRecentSkills]=createSignal4([])
1552
1583
  const [recentQuickActions,setRecentQuickActions]=createSignal4([])
1553
1584
  const [mcpServerGroups,setMcpServerGroups]=createSignal4(configured.mcpServerGroups??{})
1585
+ const [skillGroups,setSkillGroups]=createSignal4({})
1554
1586
  const [ready,setReady]=createSignal4(false)
1555
1587
  const [revision,setRevision]=createSignal4(0)
1556
1588
  const sessionLayouts=new Map
@@ -1560,6 +1592,8 @@ let isHydrated=false
1560
1592
  let hydration
1561
1593
  let mcpPresetRevision=0
1562
1594
  let mcpPresetReconciliation=Promise.resolve()
1595
+ let updateRevision=0
1596
+ let reloading
1563
1597
  let isPersistenceWarningShown=false
1564
1598
  function skillKey(skill){return skill.location
1565
1599
  }
@@ -1597,13 +1631,29 @@ return{...configured.workspaceProfiles,...document.user.workspaceProfiles}}
1597
1631
  function scopeSnapshot(target=selectedTarget()){const scope=target.kind==="global"?document.global:document.worktrees[target.key]
1598
1632
  return JSON.stringify({layout:scope?.layout,mcp:scope?.mcp})
1599
1633
  }
1600
- function update(change){document=applyPreferencesUpdate(document,change)
1634
+ function update(change){updateRevision++
1635
+ document=applyPreferencesUpdate(document,change)
1601
1636
  if(isHydrated)
1602
1637
  persist(store.update(change))
1603
1638
  else
1604
1639
  pendingUpdates.push(change)
1605
1640
  refreshResolved()
1606
1641
  }
1642
+ function applyDocument(value){document=value
1643
+ setSkippedSkills(new Set(value.user.skippedSkillConfirmations))
1644
+ setOnboardingCompleted(value.user.onboardingCompleted===true)
1645
+ setLayoutPresets({...configured.layoutPresets,...value.user.layoutPresets})
1646
+ setMcpPresets({...configured.mcpPresets,...value.user.mcpPresets})
1647
+ setFavoriteSkills(new Set(value.user.favoriteSkills))
1648
+ setFavoriteMcpServers(new Set(value.user.favoriteMcpServers))
1649
+ setFavoriteQuickActions(new Set(value.user.favoriteQuickActions))
1650
+ setRecentSkills(value.user.recentSkills??[])
1651
+ setRecentQuickActions(value.user.recentQuickActions??[])
1652
+ setMcpServerGroups({...configured.mcpServerGroups,...value.user.mcpServerGroups})
1653
+ setSkillGroups(value.user.skillGroups??{})
1654
+ setReady(true)
1655
+ refreshResolved()
1656
+ }
1607
1657
  function load(){if(isHydrated)
1608
1658
  return Promise.resolve()
1609
1659
  if(hydration)
@@ -1618,21 +1668,28 @@ const queued=[...pendingUpdates]
1618
1668
  pendingUpdates.length=0
1619
1669
  for(const change of queued)
1620
1670
  persist(store.update(change))
1621
- setSkippedSkills(new Set(document.user.skippedSkillConfirmations))
1622
- setOnboardingCompleted(document.user.onboardingCompleted===true)
1623
- setLayoutPresets({...configured.layoutPresets,...document.user.layoutPresets})
1624
- setMcpPresets({...configured.mcpPresets,...document.user.mcpPresets})
1625
- setFavoriteSkills(new Set(document.user.favoriteSkills))
1626
- setFavoriteMcpServers(new Set(document.user.favoriteMcpServers))
1627
- setFavoriteQuickActions(new Set(document.user.favoriteQuickActions))
1628
- setRecentSkills(document.user.recentSkills??[])
1629
- setRecentQuickActions(document.user.recentQuickActions??[])
1630
- setMcpServerGroups({...configured.mcpServerGroups,...document.user.mcpServerGroups})
1631
- setReady(true)
1632
- refreshResolved()
1671
+ applyDocument(document)
1633
1672
  })
1634
1673
  return hydration
1635
1674
  }
1675
+ async function reloadFromFile(){if(reloading)
1676
+ return reloading
1677
+ const request=(async ()=>{await load()
1678
+ while(true){const observedRevision=updateRevision
1679
+ await store.flush()
1680
+ await mcpPresetReconciliation
1681
+ const latest=await store.load()
1682
+ if(observedRevision!==updateRevision)
1683
+ continue
1684
+ sessionLayouts.clear()
1685
+ applyDocument(latest)
1686
+ return
1687
+ }})()
1688
+ reloading=request
1689
+ try{await request
1690
+ } finally{if(reloading===request)
1691
+ reloading=undefined
1692
+ }}
1636
1693
  function setKey(value,name){load()
1637
1694
  const next=value.trim()
1638
1695
  if(!validKey(next))
@@ -1698,6 +1755,14 @@ next.add(key)
1698
1755
  setFavoriteSkills(next)
1699
1756
  update({user:{favoriteSkill:{location:key,favorite:next.has(key)}}})
1700
1757
  }
1758
+ function changeSkillGroup(location,value){if(!location)
1759
+ return
1760
+ if(!isHydrated){load().then(()=>changeSkillGroup(location,value))
1761
+ return
1762
+ }
1763
+ setSkillGroups(assignGroup(skillGroups(),location,value))
1764
+ update({user:{skillGroup:{location,group:value}}})
1765
+ }
1701
1766
  function toggleFavoriteMcpServer(name){if(!isHydrated){load().then(()=>toggleFavoriteMcpServer(name))
1702
1767
  return
1703
1768
  }
@@ -1755,6 +1820,7 @@ const target=selectedTarget()
1755
1820
  if(preview.target!==targetKey(target))
1756
1821
  throw new Error("Preference scope changed; reopen the import preview")
1757
1822
  const change={target,expectedScope:preview.expectedScope,...preview.settings.layout&&{layout:preview.settings.layout,clearLayout:true},...preview.settings.mcp&&{mcp:{states:preview.settings.mcp},clearMcp:true}}
1823
+ updateRevision++
1758
1824
  await store.update(change)
1759
1825
  document=await store.load()
1760
1826
  sessionLayouts.delete(targetKey(target))
@@ -1765,15 +1831,9 @@ throw new Error("Layout preset no longer exists")
1765
1831
  if(mcp&&!mcpPresets()[mcp])
1766
1832
  throw new Error("MCP preset no longer exists")
1767
1833
  update({user:{workspaceProfile:{layout,mcp}}})
1768
- },favoriteSkills,favoriteMcpServers,favoriteQuickActions,toggleFavoriteMcpServer,toggleFavoriteQuickAction,recentSkills,recentQuickActions,mcpServerGroups,setMcpServerGroup(name,value){const group=value?.trim().slice(0,64)
1769
- const next={...mcpServerGroups()}
1770
- if(group){const canonical=Object.values(next).find((item)=>item.toLocaleLowerCase()===group.toLocaleLowerCase())
1771
- next[name]=canonical??group
1772
- } else
1773
- delete next[name]
1774
- setMcpServerGroups(next)
1775
- update({user:{mcpServerGroup:{name,group}}})
1776
- },async recordSkillUse(skill){await load()
1834
+ },favoriteSkills,favoriteMcpServers,favoriteQuickActions,toggleFavoriteMcpServer,toggleFavoriteQuickAction,recentSkills,recentQuickActions,mcpServerGroups,setMcpServerGroup(name,value){setMcpServerGroups(assignGroup(mcpServerGroups(),name,value))
1835
+ update({user:{mcpServerGroup:{name,group:value}}})
1836
+ },skillGroups,setSkillGroup:changeSkillGroup,async recordSkillUse(skill){await load()
1777
1837
  if(!skill.location)
1778
1838
  return
1779
1839
  setRecentSkills(parseRecentSkills([skill.location,...recentSkills()]))
@@ -1795,7 +1855,7 @@ setRevision((value)=>value + 1)
1795
1855
  },async flush(){await hydration
1796
1856
  await store.flush()
1797
1857
  await mcpPresetReconciliation
1798
- },async claimNavigatorUpgrade(version){await load()
1858
+ },reloadFromFile,async claimNavigatorUpgrade(version){await load()
1799
1859
  const previous=document.user.lastNavigatorVersion
1800
1860
  if(previous===version)
1801
1861
  return
@@ -1904,6 +1964,7 @@ return true
1904
1964
  },async saveLayoutAsDefault(){await load()
1905
1965
  const target=selectedTarget()
1906
1966
  const layout=resolveTarget(target).layout
1967
+ updateRevision++
1907
1968
  document=applyPreferencesUpdate(document,{target,layout})
1908
1969
  await store.update({target,layout})
1909
1970
  refreshResolved()
@@ -2063,6 +2124,12 @@ return result.data
2063
2124
  throw error_
2064
2125
  } finally{request.finish()
2065
2126
  }}}}
2127
+ var BUCKET_RANK2={Favorites:0,Ungrouped:2}
2128
+ function buildSkillGroupedView(items,favorites,groups,recent){return items.map((item)=>({...item,assignedGroup:groups[item.location],bucket:favorites.has(item.location)?"Favorites":groups[item.location]??"Ungrouped"
2129
+ })).sort((left,right)=>{const rank=(BUCKET_RANK2[left.bucket]??1)-(BUCKET_RANK2[right.bucket]??1)
2130
+ return rank||left.bucket.localeCompare(right.bucket)||(left.bucket==="Favorites"?0:(recent.get(left.location)??Infinity)-(recent.get(right.location)??Infinity))||left.name.localeCompare(right.name)
2131
+ })
2132
+ }
2066
2133
 
2067
2134
 
2068
2135
 
@@ -2738,7 +2805,7 @@ return{groups,rows:groups.flatMap((group)=>group.items.map((item)=>({item,group:
2738
2805
 
2739
2806
  function KeyboardHelpDialog(props){const icons=useIcons()
2740
2807
  const theme=()=>props.api.theme.current
2741
- const hints=()=>[`${icons.key("up")}/k and ${icons.key("down")}/j move \xB7 ${icons.key("enter")} activates`,`${icons.key("enter")} on a filter starts typing \xB7 ${icons.key("esc")} returns`,`Todo: ${icons.key("enter")} on All / Active / Finished changes the view`,"Show all / Show less expands or limits the filtered list",`Skills: ${icons.icon("info")} opens source \xB7 ${icons.icon("recent")} marks recent skills`,"Navigator Settings: Ctrl+,",`Search Everything: shortcut in Settings ${icons.icon("right")} Behavior`,`Search: type \xB7 ${icons.key("up/down")} results \xB7 ${icons.key("tab/shift+tab")} tabs \xB7 ${icons.key("enter")} run`,`${icons.key("esc")} leaves the sidebar \xB7 ${icons.key("?")} opens this help`]
2808
+ const hints=()=>[`${icons.key("up")}/k and ${icons.key("down")}/j move \xB7 ${icons.key("enter")} activates`,`${icons.key("enter")} on a filter starts typing \xB7 ${icons.key("esc")} returns`,`Todo: ${icons.key("enter")} on All / Active / Finished changes the view`,`MCP: ${icons.key("enter")} toggles a group`,"Show all / Show less expands or limits the filtered list",`Skills: ${icons.icon("info")} opens source \xB7 ${icons.icon("recent")} marks recent skills`,"Navigator Settings: Ctrl+,",`Search Everything: shortcut in Settings ${icons.icon("right")} Behavior`,`Search: type \xB7 ${icons.key("up/down")} results \xB7 ${icons.key("tab/shift+tab")} tabs \xB7 ${icons.key("enter")} run`,`${icons.key("esc")} leaves the sidebar \xB7 ${icons.key("?")} opens this help`]
2742
2809
  return _$createComponent(DialogSurface,{get api(){return props.api
2743
2810
  },get children(){return [(()=>{var _el$=_$createElement("text"),_el$2=_$createTextNode(` Navigator keyboard help`)
2744
2811
  _$insertNode(_el$,_el$2)
@@ -2806,7 +2873,7 @@ return{sessionID,location,key:JSON.stringify([route.name,sessionID??null,locatio
2806
2873
  function buildSearchCandidates(input){const recent=new Map(input.recentSkills.map((location,index)=>[location,index]))
2807
2874
  const skills=[...input.skills].sort((a,b)=>Number(input.favoriteSkills.has(b.location))-Number(input.favoriteSkills.has(a.location))||(recent.get(a.location)??Infinity)-(recent.get(b.location)??Infinity)||a.name.localeCompare(b.name))
2808
2875
  const mcp=[...input.mcp].sort((a,b)=>Number(input.favoriteMcp.has(b.name))-Number(input.favoriteMcp.has(a.name))||a.name.localeCompare(b.name))
2809
- const results=[...skills.map((skill)=>({id:`skill:${skill.location || skill.name}`,group:"Skills",title:skill.name,description:skill.description?.trim()||skill.location,keywords:skill.location,skill
2876
+ const results=[...skills.map((skill)=>({id:`skill:${skill.location || skill.name}`,group:"Skills",title:skill.name,description:[input.skillGroups?.[skill.location],skill.description?.trim()||skill.location].filter(Boolean).join(" \xB7 "),keywords:`${skill.location} ${input.skillGroups?.[skill.location] ?? ""}`,skill
2810
2877
  })),...input.subagents.map((item)=>({id:`subagent:${item.session.id}`,group:"Subagents",title:item.session.title,description:[item.run?.outcome??item.status.type,item.run?.errorMessage].filter(Boolean).join(" \xB7 "),keywords:item.session.id,sessionID:item.session.id
2811
2878
  })),...mcp.map((item)=>({id:`mcp:${item.name}`,group:"MCP",title:item.name,description:[input.mcpGroups?.[item.name],mcpToggleAction2(item.status)==="disconnect"?"Disconnect":"Connect",item.status,item.error].filter(Boolean).join(" \xB7 "),keywords:input.mcpGroups?.[item.name],disabled:input.mcpBusy||!mcpToggleAction2(item.status)?"MCP operation in progress":undefined,server:item.name
2812
2879
  })),...orderQuickActionIds(input.actionOrder,input.favoriteQuickActions??new Set).flatMap((id)=>{const action=QUICK_ACTIONS.find((item)=>item.command===id)
@@ -2889,7 +2956,7 @@ let isDisposed=false
2889
2956
  let refreshGeneration=0
2890
2957
  const sameContext=()=>searchContext(props.api).key===context.key
2891
2958
  const candidates=createMemo(()=>{commandRevision()
2892
- return buildSearchCandidates({skills:props.skills.list(skillTarget),subagents:context.sessionID?buildSubagentView(props.subagents.list(context.sessionID),props.subagents.recent(context.sessionID)):[],mcp:props.mcp.list(mcpTarget),actionOrder:props.preferences.quickActionOrder?.()??QUICK_ACTION_IDS,favoriteQuickActions:props.preferences.favoriteQuickActions?.()??new Set,favoriteSkills:props.preferences.favoriteSkills(),recentSkills:props.preferences.recentSkills(),favoriteMcp:props.preferences.favoriteMcpServers(),mcpGroups:props.preferences.mcpServerGroups?.()??{},hasSession:Boolean(context.sessionID),mcpBusy:props.mcp.mutating(mcpTarget)||props.mcp.bulkState(mcpTarget).status==="running",actionDisabledReason:(action)=>quickActionDisabledReason(props.api,action),actionLabel:(action)=>quickActionLabel(props.api,action)
2959
+ return buildSearchCandidates({skills:props.skills.list(skillTarget),subagents:context.sessionID?buildSubagentView(props.subagents.list(context.sessionID),props.subagents.recent(context.sessionID)):[],mcp:props.mcp.list(mcpTarget),actionOrder:props.preferences.quickActionOrder?.()??QUICK_ACTION_IDS,favoriteQuickActions:props.preferences.favoriteQuickActions?.()??new Set,favoriteSkills:props.preferences.favoriteSkills(),skillGroups:props.preferences.skillGroups?.()??{},recentSkills:props.preferences.recentSkills(),favoriteMcp:props.preferences.favoriteMcpServers(),mcpGroups:props.preferences.mcpServerGroups?.()??{},hasSession:Boolean(context.sessionID),mcpBusy:props.mcp.mutating(mcpTarget)||props.mcp.bulkState(mcpTarget).status==="running",actionDisabledReason:(action)=>quickActionDisabledReason(props.api,action),actionLabel:(action)=>quickActionLabel(props.api,action)
2893
2960
  })
2894
2961
  })
2895
2962
  const matches=createMemo(()=>searchResults(candidates(),query()))
@@ -3942,42 +4009,7 @@ reportMcpApplyError(props.api,request)
3942
4009
  }
3943
4010
 
3944
4011
 
3945
- function McpGroupAssignmentDialog(props){const dialogs=useDialogs(props.api)
3946
- const options=()=>{const assigned=props.preferences.mcpServerGroups?.()[props.server]
3947
- const groups=[...new Set(Object.values(props.preferences.mcpServerGroups?.()??{}))].sort((a,b)=>a.localeCompare(b))
3948
- return [...groups.map((group)=>({title:group,value:`:${group}`,description:group===assigned?"Current":"Existing group"
3949
- })),{title:"Create new group",value:"+",description:"Type a name"
3950
- },{title:"Ungrouped",value:":",description:assigned?"Remove assignment":"No group"
3951
- }]
3952
- }
3953
- return _$createComponent(PresetMenu,{get api(){return props.api
3954
- },get title(){return `Group for ${props.server}`
3955
- },get options(){return options()
3956
- },onSelect:(option)=>{if(option.value!=="+"){props.preferences.setMcpServerGroup?.(props.server,option.value.slice(1)||undefined)
3957
- dialogs.back()
3958
- return
3959
- }
3960
- dialogs.prompt({title:`New group for ${props.server}`,value:"",onConfirm(value){if(!value.trim())
3961
- throw new Error("Group name is required")
3962
- props.preferences.setMcpServerGroup?.(props.server,value)
3963
- dialogs.back()
3964
- dialogs.back()
3965
- }})
3966
- }})
3967
- }
3968
- function McpGroupsDialog(props){const dialogs=useDialogs(props.api)
3969
- const options=()=>{const live=new Set(props.mcp.list(props.mcp.target()).map((item)=>item.name))
3970
- return [...new Set([...live,...Object.keys(props.preferences.mcpServerGroups?.()??{})])].sort((a,b)=>a.localeCompare(b)).map((name)=>({title:name,value:name,description:[props.preferences.mcpServerGroups?.()[name]??"Ungrouped",!live.has(name)&&"not in workspace"].filter(Boolean).join(" \xB7 ")
3971
- }))
3972
- }
3973
- return _$createComponent(PresetMenu,{get api(){return props.api
3974
- },title:"MCP groups \xB7 user-wide",get options(){return options()
3975
- },onSelect:(option)=>dialogs.open(()=>_$createComponent(McpGroupAssignmentDialog,{get api(){return props.api
3976
- },get preferences(){return props.preferences
3977
- },get server(){return option.value
3978
- }}))
3979
- })
3980
- }
4012
+
3981
4013
 
3982
4014
 
3983
4015
 
@@ -4054,139 +4086,8 @@ dialogs.open(()=>_$createComponent(PresetMenu,{api,title:"MCP presets",get optio
4054
4086
 
4055
4087
 
4056
4088
 
4057
- function QuickActionsDialog(props){const order=props.preferences.selectedQuickActionOrder
4058
- const dialogs=useDialogs(props.api)
4059
- const scroll=useDialogScroll()
4060
- const [selected,setSelected]=useDialogState("selection",order()[0])
4061
- const actions=createMemo5(()=>order().map((id)=>({...QUICK_ACTIONS.find((action)=>action.command===id)
4062
- })))
4063
- const theme=()=>props.api.theme.current
4064
- const icons=useIcons()
4065
- const dimensions=useTerminalDimensions5()
4066
- let body
4067
- function move(offset){const index=order().indexOf(selected())
4068
- setSelected(order()[(index + offset + order().length)%order().length])
4069
- }
4070
- const prefix=`${PLUGIN_ID}.quick-actions-settings`
4071
- createEffect8(()=>{order()
4072
- const id=selected()
4073
- queueMicrotask(()=>{if(body&&!body.isDestroyed)
4074
- body.scrollChildIntoView(`${prefix}.${id}`)
4075
- })
4076
- })
4077
- const unregister=props.api.keymap.registerLayer({mode:"modal",priority:1000,commands:[{name:`${prefix}.previous`,run:()=>move(-1)
4078
- },{name:`${prefix}.next`,run:()=>move(1)
4079
- },{name:`${prefix}.toggle`,run:()=>props.preferences.toggleQuickAction(selected())
4080
- },{name:`${prefix}.up`,run:()=>props.preferences.moveQuickAction(selected(),-1)
4081
- },{name:`${prefix}.down`,run:()=>props.preferences.moveQuickAction(selected(),1)
4082
- },{name:`${prefix}.back`,run:dialogs.back
4083
- }],bindings:[{key:"up",cmd:`${prefix}.previous`
4084
- },{key:"down",cmd:`${prefix}.next`
4085
- },{key:"return",cmd:`${prefix}.toggle`
4086
- },{key:"space",cmd:`${prefix}.toggle`
4087
- },{key:"left",cmd:`${prefix}.up`
4088
- },{key:"right",cmd:`${prefix}.down`
4089
- },{key:"shift+up",cmd:`${prefix}.up`
4090
- },{key:"shift+down",cmd:`${prefix}.down`
4091
- },{key:"escape",cmd:`${prefix}.back`
4092
- }]
4093
- })
4094
- onCleanup10(unregister)
4095
- return _$createComponent(DialogSurface,{get api(){return props.api
4096
- },id:prefix,lift:true,get children(){return [(()=>{var _el$=_$createElement("box"),_el$2=_$createElement("text"),_el$3=_$createTextNode(` Quick actions`),_el$4=_$createElement("text"),_el$5=_$createTextNode(` Back (`),_el$6=_$createTextNode(`)`)
4097
- _$insertNode(_el$,_el$2)
4098
- _$insertNode(_el$,_el$4)
4099
- _$setProp(_el$,"flexDirection","row")
4100
- _$setProp(_el$,"justifyContent","space-between")
4101
- _$insertNode(_el$2,_el$3)
4102
- _$insert(_el$2,()=>icons.icon("actions"),_el$3)
4103
- _$insertNode(_el$4,_el$5)
4104
- _$insertNode(_el$4,_el$6)
4105
- _$setProp(_el$4,"onMouseUp",(event)=>{event.stopPropagation()
4106
- dialogs.back()
4107
- })
4108
- _$insert(_el$4,()=>icons.icon("left"),_el$5)
4109
- _$insert(_el$4,()=>icons.key("esc"),_el$6)
4110
- _$effect((_p$)=>{var _v$=TextAttributes14.BOLD,_v$2=theme().text,_v$3=theme().textMuted
4111
- _v$!==_p$.e&&(_p$.e=_$setProp(_el$2,"attributes",_v$,_p$.e))
4112
- _v$2!==_p$.t&&(_p$.t=_$setProp(_el$2,"fg",_v$2,_p$.t))
4113
- _v$3!==_p$.a&&(_p$.a=_$setProp(_el$4,"fg",_v$3,_p$.a))
4114
- return _p$
4115
- },{e:undefined,t:undefined,a:undefined
4116
- })
4117
- return _el$
4118
- })(),(()=>{var _el$7=_$createElement("text"),_el$8=_$createTextNode(`Scope: `),_el$9=_$createTextNode(`. Changes save immediately.`)
4119
- _$insertNode(_el$7,_el$8)
4120
- _$insertNode(_el$7,_el$9)
4121
- _$setProp(_el$7,"wrapMode","word")
4122
- _$insert(_el$7,()=>props.preferences.preferenceScopeLabel(),_el$9)
4123
- _$effect((_$p)=>_$setProp(_el$7,"fg",theme().textMuted,_$p))
4124
- return _el$7
4125
- })(),(()=>{var _el$0=_$createElement("scrollbox"),_el$1=_$createElement("box")
4126
- _$insertNode(_el$0,_el$1)
4127
- _$use((node)=>{body=node
4128
- scroll.ref(node)
4129
- },_el$0)
4130
- _$setProp(_el$0,"scrollX",false)
4131
- _$setProp(_el$1,"gap",1)
4132
- _$insert(_el$1,_$createComponent(For9,{get each(){return actions()
4133
- },children:(action,index)=>_$createComponent(SelectionBox,{get id(){return `${prefix}.${action.command}`
4134
- },flexDirection:"row",gap:1,paddingLeft:1,paddingRight:1,get backgroundColor(){return _$memo(()=>selected()===action.command)()?theme().backgroundElement:undefined
4135
- },onMouseOver:()=>setSelected(action.command),onMouseDown:()=>{setSelected(action.command)
4136
- props.preferences.toggleQuickAction(action.command)
4137
- },get children(){return [(()=>{var _el$16=_$createElement("text"),_el$17=_$createTextNode(` `),_el$18=_$createTextNode(`. `),_el$19=_$createTextNode(` `)
4138
- _$insertNode(_el$16,_el$17)
4139
- _$insertNode(_el$16,_el$18)
4140
- _$insertNode(_el$16,_el$19)
4141
- _$setProp(_el$16,"flexGrow",1)
4142
- _$insert(_el$16,()=>icons.icon(props.preferences.selectedQuickActionVisible(action.command)?"checked":"unchecked"),_el$17)
4143
- _$insert(_el$16,()=>index() + 1,_el$18)
4144
- _$insert(_el$16,()=>icons.action(action.command),_el$19)
4145
- _$insert(_el$16,()=>action.label,null)
4146
- _$effect((_$p)=>_$setProp(_el$16,"fg",theme().text,_$p))
4147
- return _el$16
4148
- })(),(()=>{var _el$20=_$createElement("text")
4149
- _$setProp(_el$20,"onMouseDown",(event)=>{event.stopPropagation()
4150
- setSelected(action.command)
4151
- props.preferences.moveQuickAction(action.command,-1)
4152
- })
4153
- _$insert(_el$20,()=>icons.icon("up"))
4154
- _$effect((_$p)=>_$setProp(_el$20,"fg",theme().accent,_$p))
4155
- return _el$20
4156
- })(),(()=>{var _el$21=_$createElement("text")
4157
- _$setProp(_el$21,"onMouseDown",(event)=>{event.stopPropagation()
4158
- setSelected(action.command)
4159
- props.preferences.moveQuickAction(action.command,1)
4160
- })
4161
- _$insert(_el$21,()=>icons.icon("down"))
4162
- _$effect((_$p)=>_$setProp(_el$21,"fg",theme().accent,_$p))
4163
- return _el$21
4164
- })()]
4165
- }})
4166
- }))
4167
- _$effect((_p$)=>{var{restore:_v$4,save:_v$5}=scroll,_v$6=Math.min(actions().length*2-1,Math.max(3,Math.floor(dimensions().height*0.75)-8))
4168
- _v$4!==_p$.e&&(_p$.e=_$setProp(_el$0,"renderBefore",_v$4,_p$.e))
4169
- _v$5!==_p$.t&&(_p$.t=_$setProp(_el$0,"renderAfter",_v$5,_p$.t))
4170
- _v$6!==_p$.a&&(_p$.a=_$setProp(_el$0,"height",_v$6,_p$.a))
4171
- return _p$
4172
- },{e:undefined,t:undefined,a:undefined
4173
- })
4174
- return _el$0
4175
- })(),(()=>{var _el$10=_$createElement("text"),_el$11=_$createTextNode(` navigate \xB7 `),_el$12=_$createTextNode(` toggle \xB7 `),_el$13=_$createTextNode(` or `),_el$15=_$createTextNode(` reorder`)
4176
- _$insertNode(_el$10,_el$11)
4177
- _$insertNode(_el$10,_el$12)
4178
- _$insertNode(_el$10,_el$13)
4179
- _$insertNode(_el$10,_el$15)
4180
- _$setProp(_el$10,"wrapMode","word")
4181
- _$insert(_el$10,()=>icons.key("up/down"),_el$11)
4182
- _$insert(_el$10,()=>icons.key("enter"),_el$12)
4183
- _$insert(_el$10,()=>icons.key("left/right"),_el$13)
4184
- _$insert(_el$10,()=>icons.key("shift+up/down"),_el$15)
4185
- _$effect((_$p)=>_$setProp(_el$10,"fg",theme().textMuted,_$p))
4186
- return _el$10
4187
- })()]
4188
- }})
4189
- }
4089
+
4090
+
4190
4091
 
4191
4092
 
4192
4093
 
@@ -4265,7 +4166,7 @@ return [{title:`${icons.icon(title ? "checked" : "unchecked")} Session title`,va
4265
4166
  }]
4266
4167
  }
4267
4168
  function createSettingsGroups(api,preferences,icons){const supportedSections=()=>SIDEBAR_SECTIONS.filter((name)=>supportsSidebarSection(api,name))
4268
- const groups=createMemo6(()=>[{id:"scope",tab:"Scope",title:"Preference scope",options:[{title:`${icons.icon(preferences.preferenceScope() === "global" ? "radioOn" : "radioOff")} Global`,value:"scope:global",description:"applies to every worktree"
4169
+ const groups=createMemo7(()=>[{id:"scope",tab:"Scope",title:"Preference scope",options:[{title:`${icons.icon(preferences.preferenceScope() === "global" ? "radioOn" : "radioOff")} Global`,value:"scope:global",description:"applies to every worktree"
4269
4170
  },{title:`${icons.icon(preferences.preferenceScope() === "worktree" ? "radioOn" : "radioOff")} Current worktree`,value:"scope:worktree",description:preferences.canUseWorktreeScope()?preferences.preferenceScopeLabel():"unavailable outside a worktree"
4270
4171
  }]
4271
4172
  },{id:"presets",tab:"Presets",title:"Layout presets",options:[...Object.keys(preferences.layoutPresets()).sort((left,right)=>left.localeCompare(right)).map((name)=>({title:`${icons.icon("presets")} ${name}`,value:`preset:custom:${encodeURIComponent(name)}`,description:preferences.workspaceProfiles?.()[name]?`profile \xB7 ${preferences.workspaceProfiles()[name]}`:"enter to apply or edit"
@@ -4286,6 +4187,7 @@ return{title:`${icons.icon(preferences.selectedSections()[section.name] ? "check
4286
4187
  },{id:"defaults",tab:"Defaults",title:"Defaults & help",options:[{title:`${icons.icon("save")} Save current layout as default`,value:"save_layout",description:`${supportedSections().filter((name) => preferences.selectedSections()[name]).length} visible \xB7 ${supportedSections().filter((name) => preferences.selectedExpanded()[name]).length} expanded`
4287
4188
  },{title:`${icons.icon("export")} Copy portable settings`,value:"export_settings",description:"versioned layout and MCP JSON"
4288
4189
  },{title:`${icons.icon("add")} Import portable settings\u2026`,value:"import_settings",description:"preview pasted JSON before applying"
4190
+ },{title:`${icons.icon("retry")} Reload settings from file`,value:"reload_settings",description:"sync saved changes from other OpenCode sessions"
4289
4191
  },{title:`${icons.icon("reset")} Restore configured layout`,value:"reset_sections",description:"visibility and expansion"
4290
4192
  },{title:`${icons.icon("reset")} Restore configured behavior`,value:"reset_settings",description:"startup, MCP memory, icons, shortcuts, limits, actions"
4291
4193
  },{title:`${icons.icon("reset")} Clear remembered MCP states`,value:"reset_mcp",description:`scope: ${preferences.preferenceScopeLabel()}`
@@ -4293,17 +4195,21 @@ return{title:`${icons.icon(preferences.selectedSections()[section.name] ? "check
4293
4195
  },{title:`${icons.icon("help")} Open quick setup guide`,value:"wizard",description:"tips and section settings"
4294
4196
  }]
4295
4197
  }])
4296
- const orderedGroups=createMemo6(()=>["sections","scope","presets","behavior","defaults"].map((id)=>groups().find((group)=>group.id===id)))
4198
+ const orderedGroups=createMemo7(()=>["sections","scope","presets","behavior","defaults"].map((id)=>groups().find((group)=>group.id===id)))
4297
4199
  return orderedGroups
4298
4200
  }
4299
- function registerSettingsKeymap(input){return input.api.keymap.registerLayer({mode:"modal",priority:1000,commands:[{name:`${PLUGIN_ID}.settings.previous`,run:()=>input.move(-1)},{name:`${PLUGIN_ID}.settings.next`,run:()=>input.move(1)},{name:`${PLUGIN_ID}.settings.select`,run:()=>input.select()},{name:`${PLUGIN_ID}.settings.mcp-groups`,run:()=>{if(input.activeGroup()==="sections"&&input.options()[input.active()]?.value==="mcp")
4201
+ function registerSettingsKeymap(input){return input.api.keymap.registerLayer({mode:"modal",priority:1000,commands:[{name:`${PLUGIN_ID}.settings.previous`,run:()=>input.move(-1)},{name:`${PLUGIN_ID}.settings.next`,run:()=>input.move(1)},{name:`${PLUGIN_ID}.settings.select`,run:()=>input.select()},{name:`${PLUGIN_ID}.settings.groups`,run:()=>{if(input.activeGroup()!=="sections")
4202
+ return
4203
+ if(input.options()[input.active()]?.value==="mcp")
4300
4204
  input.openMcpGroups()
4205
+ if(input.options()[input.active()]?.value==="skills")
4206
+ input.openSkillGroups()
4301
4207
  }},{name:`${PLUGIN_ID}.settings.quick-actions`,run:()=>{if(input.activeGroup()==="sections"&&input.options()[input.active()]?.value==="quick_actions")
4302
4208
  input.openQuickActions()
4303
4209
  }},{name:`${PLUGIN_ID}.settings.item-limit`,run:()=>{const section=input.options()[input.active()]?.value
4304
4210
  if(input.activeGroup()==="sections"&&SIDEBAR_SECTIONS.includes(section))
4305
4211
  input.openLimitPrompt(section)
4306
- }},{name:`${PLUGIN_ID}.settings.previous-tab`,run:()=>input.switchGroup(-1)},{name:`${PLUGIN_ID}.settings.next-tab`,run:()=>input.switchGroup(1)},{name:`${PLUGIN_ID}.settings.move-up`,run:()=>input.reorder(input.options()[input.active()]?.value,-1)},{name:`${PLUGIN_ID}.settings.move-down`,run:()=>input.reorder(input.options()[input.active()]?.value,1)}],bindings:[{key:"up",cmd:`${PLUGIN_ID}.settings.previous`},{key:"down",cmd:`${PLUGIN_ID}.settings.next`},{key:"tab",cmd:`${PLUGIN_ID}.settings.next-tab`},{key:"shift+tab",cmd:`${PLUGIN_ID}.settings.previous-tab`},{key:"space",cmd:`${PLUGIN_ID}.settings.select`},{key:"return",cmd:`${PLUGIN_ID}.settings.select`},{key:"l",cmd:`${PLUGIN_ID}.settings.item-limit`},{key:"a",cmd:`${PLUGIN_ID}.settings.quick-actions`},{key:"g",cmd:`${PLUGIN_ID}.settings.mcp-groups`},{key:"left",cmd:`${PLUGIN_ID}.settings.move-up`},{key:"right",cmd:`${PLUGIN_ID}.settings.move-down`},{key:"shift+up",cmd:`${PLUGIN_ID}.settings.move-up`},{key:"shift+down",cmd:`${PLUGIN_ID}.settings.move-down`}]
4212
+ }},{name:`${PLUGIN_ID}.settings.previous-tab`,run:()=>input.switchGroup(-1)},{name:`${PLUGIN_ID}.settings.next-tab`,run:()=>input.switchGroup(1)},{name:`${PLUGIN_ID}.settings.move-up`,run:()=>input.reorder(input.options()[input.active()]?.value,-1)},{name:`${PLUGIN_ID}.settings.move-down`,run:()=>input.reorder(input.options()[input.active()]?.value,1)}],bindings:[{key:"up",cmd:`${PLUGIN_ID}.settings.previous`},{key:"down",cmd:`${PLUGIN_ID}.settings.next`},{key:"tab",cmd:`${PLUGIN_ID}.settings.next-tab`},{key:"shift+tab",cmd:`${PLUGIN_ID}.settings.previous-tab`},{key:"space",cmd:`${PLUGIN_ID}.settings.select`},{key:"return",cmd:`${PLUGIN_ID}.settings.select`},{key:"l",cmd:`${PLUGIN_ID}.settings.item-limit`},{key:"a",cmd:`${PLUGIN_ID}.settings.quick-actions`},{key:"g",cmd:`${PLUGIN_ID}.settings.groups`},{key:"left",cmd:`${PLUGIN_ID}.settings.move-up`},{key:"right",cmd:`${PLUGIN_ID}.settings.move-down`},{key:"shift+up",cmd:`${PLUGIN_ID}.settings.move-up`},{key:"shift+down",cmd:`${PLUGIN_ID}.settings.move-down`}]
4307
4213
  })
4308
4214
  }
4309
4215
 
@@ -4315,7 +4221,7 @@ input.openLimitPrompt(section)
4315
4221
 
4316
4222
 
4317
4223
  var RESET_ALL="__reset_all__"
4318
- function TrustedSkillsDialog(props){const options=createMemo7(()=>{const locations=props.preferences.trustedSkillLocations()
4224
+ function TrustedSkillsDialog(props){const options=createMemo8(()=>{const locations=props.preferences.trustedSkillLocations()
4319
4225
  if(locations.length===0)
4320
4226
  return [{title:"Every skill requires confirmation",value:"empty",description:"No trusted skills",icon:"info"
4321
4227
  }]
@@ -4331,7 +4237,8 @@ else if(option.value!=="empty")
4331
4237
  props.preferences.revokeSkillConfirmation(option.value)
4332
4238
  }})
4333
4239
  }
4334
- function createSettingsSelection(input){function openLimitPrompt(section){const index=input.options().findIndex((option)=>option.value===section)
4240
+ function createSettingsSelection(input){const dialogClosed=()=>("open" in input.api.ui.dialog)&&!input.api.ui.dialog.open
4241
+ function openLimitPrompt(section){const index=input.options().findIndex((option)=>option.value===section)
4335
4242
  if(index!==-1)
4336
4243
  input.setActive(index)
4337
4244
  input.dialogs.prompt({title:`${SECTION_DEFINITIONS.find((item) => item.name === section).label} item limit`,description:()=>(()=>{var _el$=_$createElement("text")
@@ -4418,6 +4325,11 @@ break
4418
4325
  case "import_settings":{importSettings()
4419
4326
  break
4420
4327
  }
4328
+ case "reload_settings":{input.preferences.reloadFromFile().then(()=>input.api.ui.toast({variant:"success",title:"Navigator settings",message:"Saved settings reloaded",duration:3000
4329
+ })).catch((error)=>input.api.ui.toast({variant:"error",title:"Navigator settings",message:error instanceof Error?error.message:"Could not reload saved settings",duration:5000
4330
+ }))
4331
+ break
4332
+ }
4421
4333
  case "reset_sections":{input.preferences.resetSections()
4422
4334
  break
4423
4335
  }
@@ -4470,19 +4382,51 @@ break
4470
4382
  default:{input.preferences.toggleSelectedSection(value)
4471
4383
  }}}
4472
4384
  function openQuickActions(){input.setActive(input.options().findIndex((option)=>option.value==="quick_actions"))
4385
+ const path=import.meta.url.includes("/dist/tui.js")?"./quick-actions-settings.js":"../ui/quick-actions-dialog"
4386
+ import(path).then((module)=>{if(dialogClosed())
4387
+ return
4388
+ const{QuickActionsDialog
4389
+ }=module
4473
4390
  input.dialogs.open(()=>_$createComponent(QuickActionsDialog,{get api(){return input.api
4474
4391
  },get preferences(){return input.preferences
4475
4392
  }}))
4393
+ }).catch((error)=>{input.api.ui.toast({variant:"error",title:"Quick actions",message:String(error),duration:4000
4394
+ })
4395
+ })
4476
4396
  }
4477
4397
  function openMcpGroups(){if(!input.mcp)
4478
4398
  return
4479
4399
  input.setActive(input.options().findIndex((option)=>option.value==="mcp"))
4400
+ const path=import.meta.url.includes("/dist/tui.js")?"./mcp-groups.js":"../ui/mcp-groups-dialog"
4401
+ import(path).then((module)=>{if(dialogClosed())
4402
+ return
4403
+ const{McpGroupsDialog
4404
+ }=module
4480
4405
  input.dialogs.open(()=>_$createComponent(McpGroupsDialog,{get api(){return input.api
4481
4406
  },get preferences(){return input.preferences
4482
4407
  },get mcp(){return input.mcp
4483
4408
  }}))
4409
+ }).catch((error)=>{input.api.ui.toast({variant:"error",title:"MCP groups",message:String(error),duration:4000
4410
+ })
4411
+ })
4412
+ }
4413
+ function openSkillGroups(){if(!input.skills)
4414
+ return
4415
+ input.setActive(input.options().findIndex((option)=>option.value==="skills"))
4416
+ const path=import.meta.url.includes("/dist/tui.js")?"./skill-groups.js":"../ui/skill-groups-dialog"
4417
+ import(path).then((module)=>{if(dialogClosed())
4418
+ return
4419
+ const{SkillGroupsDialog
4420
+ }=module
4421
+ input.dialogs.open(()=>_$createComponent(SkillGroupsDialog,{get api(){return input.api
4422
+ },get preferences(){return input.preferences
4423
+ },get skills(){return input.skills
4424
+ }}))
4425
+ }).catch((error)=>{input.api.ui.toast({variant:"error",title:"Skill groups",message:String(error),duration:4000
4426
+ })
4427
+ })
4484
4428
  }
4485
- return{openLimitPrompt,openMcpGroups,openQuickActions,select
4429
+ return{openLimitPrompt,openMcpGroups,openSkillGroups,openQuickActions,select
4486
4430
  }}
4487
4431
  function createSettingsDialogController(props){let body
4488
4432
  const theme=()=>props.api.theme.current
@@ -4490,21 +4434,21 @@ const icons=useIcons()
4490
4434
  const dialogs=useDialogs(props.api)
4491
4435
  const scroll=useDialogScroll()
4492
4436
  const dimensions=useTerminalDimensions6()
4493
- const bodyHeight=createMemo8(()=>Math.max(4,Math.floor(dimensions().height*0.75)-10))
4437
+ const bodyHeight=createMemo9(()=>Math.max(4,Math.floor(dimensions().height*0.75)-10))
4494
4438
  const orderedGroups=createSettingsGroups(props.api,props.preferences,icons)
4495
4439
  const initialGroup=orderedGroups().find((group)=>group.options.some((option)=>option.value===props.activeValue))
4496
4440
  const [activeGroup,setActiveGroup]=useDialogState("tab",initialGroup?.id??orderedGroups()[0].id)
4497
- const options=createMemo8(()=>orderedGroups().find((group)=>group.id===activeGroup())?.options??[])
4441
+ const options=createMemo9(()=>orderedGroups().find((group)=>group.id===activeGroup())?.options??[])
4498
4442
  const optionId=(value)=>`${PLUGIN_ID}.settings.${value}`
4499
4443
  const initialActive=options().findIndex((option)=>option.value===props.activeValue)
4500
4444
  const [active,setActive]=useDialogState("selection",Math.max(0,initialActive))
4501
- createEffect9(()=>{if(active()>=options().length)
4445
+ createEffect10(()=>{if(active()>=options().length)
4502
4446
  setActive(Math.max(0,options().length-1))
4503
4447
  })
4504
- const contentHeight=createMemo8(()=>Math.min(bodyHeight(),Math.max(1,options().length*2-1)))
4505
- const footerHint=createMemo8(()=>{const common=`${icons.key("tab")} switch \xB7 ${icons.key("up/down")} navigate`
4448
+ const contentHeight=createMemo9(()=>Math.min(bodyHeight(),Math.max(1,options().length*2-1)))
4449
+ const footerHint=createMemo9(()=>{const common=`${icons.key("tab")} switch \xB7 ${icons.key("up/down")} navigate`
4506
4450
  if(activeGroup()==="sections")
4507
- return `${common} \xB7 ${icons.key("enter")} toggle \xB7 l item limit${options()[active()]?.value === "quick_actions" ? " \xB7 a actions" : ""}${options()[active()]?.value === "mcp" ? " \xB7 g groups" : ""} \xB7 ${icons.key("left/right")} or ${icons.key("shift+up/down")} reorder`
4451
+ return `${common} \xB7 ${icons.key("enter")} toggle \xB7 l item limit${options()[active()]?.value === "quick_actions" ? " \xB7 a actions" : ""}${["mcp", "skills"].includes(options()[active()]?.value ?? "") ? " \xB7 g groups" : ""} \xB7 ${icons.key("left/right")} or ${icons.key("shift+up/down")} reorder`
4508
4452
  if(activeGroup()==="presets")
4509
4453
  return `${common} \xB7 ${icons.key("enter")} manage`
4510
4454
  if(activeGroup()==="behavior")
@@ -4545,12 +4489,12 @@ body?.scrollChildIntoView(optionId(value))
4545
4489
  }
4546
4490
  const presetActions=createLayoutPresetActions({api:props.api,preferences:props.preferences,mcp:props.mcp,dialogs
4547
4491
  })
4548
- const selection=createSettingsSelection({api:props.api,preferences:props.preferences,mcp:props.mcp,dialogs,options,active,setActive,openPreset:presetActions.open,promptPreset:presetActions.prompt
4492
+ const selection=createSettingsSelection({api:props.api,preferences:props.preferences,mcp:props.mcp,skills:props.skills,dialogs,options,active,setActive,openPreset:presetActions.open,promptPreset:presetActions.prompt
4549
4493
  })
4550
- const unregister=registerSettingsKeymap({api:props.api,active,activeGroup,options,move,switchGroup,reorder,select:selection.select,openQuickActions:selection.openQuickActions,openMcpGroups:selection.openMcpGroups,openLimitPrompt:selection.openLimitPrompt
4494
+ const unregister=registerSettingsKeymap({api:props.api,active,activeGroup,options,move,switchGroup,reorder,select:selection.select,openQuickActions:selection.openQuickActions,openMcpGroups:selection.openMcpGroups,openSkillGroups:selection.openSkillGroups,openLimitPrompt:selection.openLimitPrompt
4551
4495
  })
4552
4496
  onCleanup11(unregister)
4553
- return{active,activeGroup,contentHeight,dialogs,footerHint,icons,openLimitPrompt:selection.openLimitPrompt,openQuickActions:selection.openQuickActions,openMcpGroups:selection.openMcpGroups,options,optionId,orderedGroups,reorder,select:selection.select,setActive,setActiveGroup,setBody(node){body=node
4497
+ return{active,activeGroup,contentHeight,dialogs,footerHint,icons,openLimitPrompt:selection.openLimitPrompt,openQuickActions:selection.openQuickActions,openMcpGroups:selection.openMcpGroups,openSkillGroups:selection.openSkillGroups,options,optionId,orderedGroups,reorder,select:selection.select,setActive,setActiveGroup,setBody(node){body=node
4554
4498
  scroll.ref(node)
4555
4499
  },restoreScroll:scroll.restore,saveScroll:scroll.save,theme
4556
4500
  }}
@@ -4606,11 +4550,14 @@ _$insert(_el$4,()=>model.icons.icon("actions"),_el$5)
4606
4550
  _$effect((_$p)=>_$setProp(_el$4,"fg",model.theme().accent,_$p))
4607
4551
  return _el$4
4608
4552
  }}),_el$8)
4609
- _$insert(_el$3,_$createComponent(Show6,{get when(){return props.option.value==="mcp"
4553
+ _$insert(_el$3,_$createComponent(Show6,{get when(){return props.option.value==="mcp"||props.option.value==="skills"
4610
4554
  },get children(){var _el$6=_$createElement("text"),_el$7=_$createTextNode(` Groups`)
4611
4555
  _$insertNode(_el$6,_el$7)
4612
4556
  _$setProp(_el$6,"onMouseDown",(event)=>event.stopPropagation())
4613
4557
  _$setProp(_el$6,"onMouseUp",(event)=>{event.stopPropagation()
4558
+ if(props.option.value==="skills")
4559
+ model.openSkillGroups()
4560
+ else
4614
4561
  model.openMcpGroups()
4615
4562
  })
4616
4563
  _$insert(_el$6,()=>model.icons.icon("sections"),_el$7)
@@ -4712,12 +4659,12 @@ return _el$0
4712
4659
  })()]
4713
4660
  }})
4714
4661
  }
4715
- function openSettings(api,preferences,activeValue,mcp){createDialogStack(api,preferences.lspIconStyle,()=>true,preferences.cornerFont).open(()=>_$createComponent(SettingsDialog,{api,preferences,mcp,activeValue
4662
+ function openSettings(api,preferences,activeValue,mcp,skills){createDialogStack(api,preferences.lspIconStyle,()=>true,preferences.cornerFont).open(()=>_$createComponent(SettingsDialog,{api,preferences,mcp,skills,activeValue
4716
4663
  }),"xlarge")
4717
4664
  }
4718
4665
 
4719
4666
 
4720
- function SettingsBinding(props){const unregister=props.api.keymap.registerLayer({mode:"base",commands:[{name:`${PLUGIN_ID}.settings`,title:"Navigator settings",category:"Navigator",namespace:"palette",enabled:()=>["home","session"].includes(props.api.route.current.name),run:()=>openSettings(props.api,props.preferences,undefined,props.mcp)
4667
+ function SettingsBinding(props){const unregister=props.api.keymap.registerLayer({mode:"base",commands:[{name:`${PLUGIN_ID}.settings`,title:"Navigator settings",category:"Navigator",namespace:"palette",enabled:()=>["home","session"].includes(props.api.route.current.name),run:()=>openSettings(props.api,props.preferences,undefined,props.mcp,props.skills)
4721
4668
  }],bindings:[{key:{name:",",ctrl:true
4722
4669
  },cmd:`${PLUGIN_ID}.settings`
4723
4670
  }]
@@ -4734,7 +4681,7 @@ const theme=()=>props.api.theme.current
4734
4681
  return _$createComponent(IconControl,{id:`${PLUGIN_ID}.settings.footer`,get icon(){return icons.icon("settings")
4735
4682
  },get foregroundColor(){return _$memo(()=>!!hovered())()?theme().text:theme().textMuted
4736
4683
  },get backgroundColor(){return _$memo(()=>!!hovered())()?theme().backgroundElement:theme().backgroundPanel
4737
- },onMouseOver:()=>setHovered(true),onMouseOut:()=>setHovered(false),onMouseUp:()=>openSettings(props.api,props.preferences,undefined,props.mcp)
4684
+ },onMouseOver:()=>setHovered(true),onMouseOut:()=>setHovered(false),onMouseUp:()=>openSettings(props.api,props.preferences,undefined,props.mcp,props.skills)
4738
4685
  })
4739
4686
  }
4740
4687
  import {realpathSync} from "fs"
@@ -4800,7 +4747,7 @@ queueMicrotask(()=>void props.controller.start())
4800
4747
  })
4801
4748
  onCleanup13(unregister)
4802
4749
  } else
4803
- createEffect10(()=>{if(!props.controller.enabled())
4750
+ createEffect11(()=>{if(!props.controller.enabled())
4804
4751
  return
4805
4752
  const unregister=props.api.keymap.registerLayer({mode:"global",priority:2001,commands:[{name:"session.new",title:"New session",category:"Session",namespace:"palette",enabled:props.controller.enabled,run:()=>void props.controller.start()
4806
4753
  }]
@@ -5449,16 +5396,16 @@ return _el$3
5449
5396
  function createListVisibility(options){const [expanded,setExpanded]=createSignal21(false)
5450
5397
  let previousKey
5451
5398
  let previousLimit
5452
- const canToggle=createMemo9(()=>options.limit()>0&&options.items().length>options.limit())
5399
+ const canToggle=createMemo10(()=>options.limit()>0&&options.items().length>options.limit())
5453
5400
  createComputed(()=>{const key=options.resetKey()
5454
5401
  const limit=options.limit()
5455
5402
  const isToggle=canToggle()
5456
5403
  if(key!==previousKey||limit!==previousLimit||!isToggle)
5457
- untrack2(()=>setExpanded(false))
5404
+ untrack3(()=>setExpanded(false))
5458
5405
  previousKey=key
5459
5406
  previousLimit=limit
5460
5407
  })
5461
- const visible=createMemo9(()=>!canToggle()||expanded()?options.items():options.items().slice(0,options.limit()))
5408
+ const visible=createMemo10(()=>!canToggle()||expanded()?options.items():options.items().slice(0,options.limit()))
5462
5409
  return{visible,expanded,canToggle,hiddenCount:()=>options.items().length-visible().length,showAll:()=>setExpanded(canToggle()),showLess:()=>setExpanded(false)
5463
5410
  }}
5464
5411
 
@@ -5473,7 +5420,7 @@ return{visible,expanded,canToggle,hiddenCount:()=>options.items().length-visible
5473
5420
  function ListVisibilityControl(props){const icons=useIcons()
5474
5421
  const id=`${PLUGIN_ID}.list.${props.section}`
5475
5422
  createComputed2(()=>{const isVisible=props.visibility.canToggle()
5476
- untrack3(()=>{if(!isVisible&&props.interaction?.selectedId()===id){props.interaction.select(`${PLUGIN_ID}.section.${props.section}`)
5423
+ untrack4(()=>{if(!isVisible&&props.interaction?.selectedId()===id){props.interaction.select(`${PLUGIN_ID}.section.${props.section}`)
5477
5424
  }})
5478
5425
  })
5479
5426
  const item=useSidebarItem(props.api,props.interaction,{id,position:()=>({section:props.navigationSection,row:props.row,column:0
@@ -5537,7 +5484,7 @@ const item=useSidebarItem(props.api,props.interaction,{id:props.sectionId??`sect
5537
5484
  const action=props.headerAction?useSidebarItem(props.api,props.interaction,{id:props.headerAction.id,position:()=>({section:props.navigationSection??0,row:0,column:1
5538
5485
  }),disabled:props.headerAction.disabled,activate:props.headerAction.onActivate
5539
5486
  },()=>theme().accent,"control"):undefined
5540
- createEffect11(()=>{props.headerAction?.label()
5487
+ createEffect12(()=>{props.headerAction?.label()
5541
5488
  setActionWidth(undefined)
5542
5489
  })
5543
5490
  const actionLabel=()=>{const label=props.headerAction?.label()??""
@@ -5614,11 +5561,11 @@ return _el$
5614
5561
  })()
5615
5562
  }
5616
5563
  var SectionWithHeaderAction=Section;
5617
- function LspSection(props){const list=createMemo10(()=>[...props.api.state.lsp()].sort((a,b)=>Number(b.status==="error")-Number(a.status==="error")||a.id.localeCompare(b.id)||a.root.localeCompare(b.root)))
5564
+ function LspSection(props){const list=createMemo11(()=>[...props.api.state.lsp()].sort((a,b)=>Number(b.status==="error")-Number(a.status==="error")||a.id.localeCompare(b.id)||a.root.localeCompare(b.root)))
5618
5565
  const visibility=createListVisibility({items:list,limit:()=>props.preferences.sectionItemLimit?.("lsp")??0,resetKey:()=>currentLocation(props.api).key
5619
5566
  })
5620
- const connected=createMemo10(()=>list().filter((item)=>item.status==="connected").length)
5621
- const disabled=createMemo10(()=>props.api.state.config.lsp===false)
5567
+ const connected=createMemo11(()=>list().filter((item)=>item.status==="connected").length)
5568
+ const disabled=createMemo11(()=>props.api.state.config.lsp===false)
5622
5569
  const navigationSection=()=>props.navigationSection??5
5623
5570
  return _$createComponent(Section,{get api(){return props.api
5624
5571
  },get interaction(){return props.interaction
@@ -5657,28 +5604,31 @@ return _el$
5657
5604
 
5658
5605
 
5659
5606
 
5660
- function createMcpSectionModel(props,query){const target=createMemo11(()=>props.controller.target())
5661
- const favorites=createMemo11(()=>props.preferences.favoriteMcpServers?.()??new Set)
5662
- const groups=createMemo11(()=>props.preferences.mcpServerGroups?.()??{})
5663
- const grouped=createMemo11(()=>Object.keys(groups()).length>0)
5664
- const list=createMemo11(()=>buildMcpGroupedView(props.controller.list(target()),favorites(),groups()))
5665
- const filtered=createMemo11(()=>list().filter((item)=>matchesFilter(query(),`${item.name} ${item.assignedGroup ?? ""}`)))
5607
+ function createMcpSectionModel(props,query){const target=createMemo12(()=>props.controller.target())
5608
+ const favorites=createMemo12(()=>props.preferences.favoriteMcpServers?.()??new Set)
5609
+ const groups=createMemo12(()=>props.preferences.mcpServerGroups?.()??{})
5610
+ const grouped=createMemo12(()=>Object.keys(groups()).length>0)
5611
+ const list=createMemo12(()=>buildMcpGroupedView(props.controller.list(target()),favorites(),groups()))
5612
+ const groupItems=(bucket)=>list().filter((item)=>item.bucket===bucket)
5613
+ const filtered=createMemo12(()=>list().filter((item)=>matchesFilter(query(),`${item.name} ${item.assignedGroup ?? ""}`)))
5666
5614
  const visibility=createListVisibility({items:filtered,limit:()=>props.preferences.sectionItemLimit?.("mcp")??0,resetKey:()=>JSON.stringify([target().key,query()])
5667
5615
  })
5668
- const active=createMemo11(()=>list().filter((item)=>item.status==="connected").length)
5669
- const state=createMemo11(()=>props.controller.state(target()))
5670
- const bulk=createMemo11(()=>props.controller.bulkState?.(target())??{action:"connect",status:"idle",completed:0,total:0,failed:[]
5616
+ const active=createMemo12(()=>list().filter((item)=>item.status==="connected").length)
5617
+ const state=createMemo12(()=>props.controller.state(target()))
5618
+ const bulk=createMemo12(()=>props.controller.bulkState?.(target())??{action:"connect",status:"idle",completed:0,total:0,failed:[]
5671
5619
  })
5672
- const bulkRunning=createMemo11(()=>bulk().status==="running")
5673
- const mutationRunning=createMemo11(()=>props.controller.mutating?.(target()))
5674
- const connectable=createMemo11(()=>list().filter((item)=>mcpToggleAction2(item.status)==="connect").length)
5675
- const disconnectable=createMemo11(()=>list().filter((item)=>mcpToggleAction2(item.status)==="disconnect").length)
5676
- const errors=createMemo11(()=>list().filter((item)=>item.status==="failed"||item.status==="needs_auth"||item.status==="needs_client_registration").length)
5677
- const presetName=createMemo11(()=>{const presets=props.preferences.mcpPresets?.()??{}
5620
+ const bulkRunning=createMemo12(()=>bulk().status==="running")
5621
+ const mutationRunning=createMemo12(()=>props.controller.mutating?.(target()))
5622
+ const connectable=createMemo12(()=>list().filter((item)=>mcpToggleAction2(item.status)==="connect").length)
5623
+ const disconnectable=createMemo12(()=>list().filter((item)=>mcpToggleAction2(item.status)==="disconnect").length)
5624
+ const errors=createMemo12(()=>list().filter((item)=>item.status==="failed"||item.status==="needs_auth"||item.status==="needs_client_registration").length)
5625
+ const presetName=createMemo12(()=>{const presets=props.preferences.mcpPresets?.()??{}
5678
5626
  const selected=props.controller.selectedPreset?.(target())
5679
5627
  return selected&&Object.hasOwn(presets,selected)?selected:matchingMcpPreset(list(),presets)
5680
5628
  })
5681
- return{target,favorites,groups,grouped,list,filtered,visibility,active,state,bulk,bulkRunning,mutationRunning,connectable,disconnectable,errors,presetName
5629
+ return{target,favorites,groups,grouped,list,groupNames(bucket){return groupItems(bucket).map((item)=>item.name)
5630
+ },groupAction(bucket){return mcpGroupToggleAction(groupItems(bucket))
5631
+ },filtered,visibility,active,state,bulk,bulkRunning,mutationRunning,connectable,disconnectable,errors,presetName
5682
5632
  }}
5683
5633
 
5684
5634
 
@@ -5691,6 +5641,15 @@ return{target,favorites,groups,grouped,list,filtered,visibility,active,state,bul
5691
5641
 
5692
5642
 
5693
5643
 
5644
+
5645
+
5646
+
5647
+
5648
+
5649
+
5650
+
5651
+
5652
+
5694
5653
 
5695
5654
 
5696
5655
 
@@ -5709,6 +5668,93 @@ _$effect((_$p)=>_$setProp(_el$,"fg",item.foregroundColor(),_$p))
5709
5668
  return _el$
5710
5669
  }})
5711
5670
  }
5671
+ function McpBulkControls(props){const icons=useIcons()
5672
+ const model=props.model
5673
+ const progress=()=>{const state=model.bulk()
5674
+ if(state.action==="preset")
5675
+ return `Applying ${state.preset}`
5676
+ return state.action==="connect"?"Connecting":"Disconnecting"
5677
+ }
5678
+ return [(()=>{var _el$=_$createElement("box")
5679
+ _$setProp(_el$,"flexDirection","row")
5680
+ _$setProp(_el$,"gap",1)
5681
+ _$insert(_el$,_$createComponent(McpBulkAction,{get api(){return props.api
5682
+ },get interaction(){return props.interaction
5683
+ },id:`${PLUGIN_ID}.mcp.connect-all`,get position(){return{section:props.navigationSection,row:2,column:0
5684
+ }},get label(){return `${icons.icon("connected")} Connect all`
5685
+ },get disabled(){return model.bulkRunning()||model.mutationRunning()||model.connectable()===0
5686
+ },onActivate:()=>void props.controller.connectAll(model.target())
5687
+ }),null)
5688
+ _$insert(_el$,_$createComponent(McpBulkAction,{get api(){return props.api
5689
+ },get interaction(){return props.interaction
5690
+ },id:`${PLUGIN_ID}.mcp.disconnect-all`,get position(){return{section:props.navigationSection,row:2,column:1
5691
+ }},get label(){return `${icons.icon("disconnected")} Disconnect all`
5692
+ },get disabled(){return model.bulkRunning()||model.mutationRunning()||model.disconnectable()===0
5693
+ },onActivate:()=>void props.controller.disconnectAll(model.target())
5694
+ }),null)
5695
+ _$effect((_$p)=>_$setProp(_el$,"paddingBottom",model.bulkRunning()||model.bulk().status==="error"?1:0,_$p))
5696
+ return _el$
5697
+ })(),_$createComponent(Show11,{get when(){return model.bulkRunning()
5698
+ },get children(){var _el$2=_$createElement("text"),_el$3=_$createTextNode(` `),_el$4=_$createTextNode(`/`),_el$5=_$createTextNode(`\u2026`)
5699
+ _$insertNode(_el$2,_el$3)
5700
+ _$insertNode(_el$2,_el$4)
5701
+ _$insertNode(_el$2,_el$5)
5702
+ _$insert(_el$2,progress,_el$3)
5703
+ _$insert(_el$2,()=>model.bulk().completed,_el$4)
5704
+ _$insert(_el$2,()=>model.bulk().total,_el$5)
5705
+ _$effect((_$p)=>_$setProp(_el$2,"fg",props.api.theme.current.textMuted,_$p))
5706
+ return _el$2
5707
+ }}),_$createComponent(Show11,{get when(){return model.bulk().status==="error"
5708
+ },get children(){return _$createComponent(McpBulkAction,{get api(){return props.api
5709
+ },get interaction(){return props.interaction
5710
+ },id:`${PLUGIN_ID}.mcp.retry-all`,get position(){return{section:props.navigationSection,row:3,column:0
5711
+ }},get label(){return `${icons.icon("retry")} Retry ${model.bulk().failed.length} failed`
5712
+ },disabled:false,onActivate:()=>void props.controller.retryBulk(model.target())
5713
+ })
5714
+ }})]
5715
+ }
5716
+
5717
+
5718
+
5719
+
5720
+
5721
+
5722
+
5723
+
5724
+ function McpGroupHeader(props){const icons=useIcons()
5725
+ const theme=()=>props.api.theme.current
5726
+ const id=()=>`${PLUGIN_ID}.mcp.group.${props.bucket}`
5727
+ const item=useSidebarItem(props.api,props.interaction,{id:id(),position:()=>props.position,disabled:()=>props.disabled||!props.action,activate:props.onToggle
5728
+ })
5729
+ return _$createComponent(SelectionBox,{ref:(node)=>item.ref(node),get id(){return id()
5730
+ },height:1,get marginTop(){return props.marginTop
5731
+ },flexDirection:"row",justifyContent:"space-between",gap:1,get backgroundColor(){return item.backgroundColor()
5732
+ },get onMouseOver(){return item.onMouseOver
5733
+ },get onMouseOut(){return item.onMouseOut
5734
+ },onMouseUp:(event)=>{event.stopPropagation()
5735
+ item.activate(event)
5736
+ },get children(){return [(()=>{var _el$=_$createElement("text"),_el$2=_$createTextNode(` (`),_el$3=_$createTextNode(`)`)
5737
+ _$insertNode(_el$,_el$2)
5738
+ _$insertNode(_el$,_el$3)
5739
+ _$setProp(_el$,"flexGrow",1)
5740
+ _$setProp(_el$,"minWidth",0)
5741
+ _$setProp(_el$,"wrapMode","none")
5742
+ _$setProp(_el$,"truncate",true)
5743
+ _$insert(_el$,()=>props.bucket,_el$2)
5744
+ _$insert(_el$,()=>props.count,_el$3)
5745
+ _$effect((_$p)=>_$setProp(_el$,"fg",item.focused()?item.foregroundColor():theme().textMuted,_$p))
5746
+ return _el$
5747
+ })(),(()=>{var _el$4=_$createElement("text")
5748
+ _$setProp(_el$4,"flexShrink",0)
5749
+ _$setProp(_el$4,"wrapMode","none")
5750
+ _$insert(_el$4,(()=>{var _c$=_$memo(()=>!!props.action)
5751
+ return()=>_c$()?`${icons.icon(props.action === "connect" ? "connected" : "disconnected")} ${props.action === "connect" ? "Connect" : "Disconnect"}`:""
5752
+ })())
5753
+ _$effect((_$p)=>_$setProp(_el$4,"fg",item.focused()?item.foregroundColor():props.disabled?theme().textMuted:theme().accent,_$p))
5754
+ return _el$4
5755
+ })()]
5756
+ }})
5757
+ }
5712
5758
 
5713
5759
 
5714
5760
 
@@ -5741,7 +5787,7 @@ return status==="connected"?"connected":"disconnected"
5741
5787
  function RequestErrorRow(props){const icons=useIcons()
5742
5788
  const item=useSidebarItem(props.api,props.interaction,{id:props.id,position:()=>props.position,disabled:()=>!props.state.error?.retryable||props.state.status==="loading"||props.state.status==="refreshing",activate:props.onRetry
5743
5789
  })
5744
- return _$createComponent(Show11,{get when(){return props.state.error
5790
+ return _$createComponent(Show12,{get when(){return props.state.error
5745
5791
  },children:(error)=>_$createComponent(SelectionBox,{ref:(node)=>item.ref(node),get id(){return props.id
5746
5792
  },flexDirection:"row",gap:1,paddingLeft:1,paddingRight:1,get backgroundColor(){return item.backgroundColor()
5747
5793
  },get onMouseOver(){return item.onMouseOver
@@ -5756,7 +5802,7 @@ _$insert(_el$,()=>icons.icon("error"),_el$2)
5756
5802
  _$insert(_el$,()=>error().message,null)
5757
5803
  _$effect((_$p)=>_$setProp(_el$,"fg",item.focused()?item.foregroundColor():props.api.theme.current.error,_$p))
5758
5804
  return _el$
5759
- })(),_$createComponent(Show11,{get when(){return error().retryable
5805
+ })(),_$createComponent(Show12,{get when(){return error().retryable
5760
5806
  },get children(){var _el$3=_$createElement("text"),_el$4=_$createTextNode(` Retry`)
5761
5807
  _$insertNode(_el$3,_el$4)
5762
5808
  _$setProp(_el$3,"flexShrink",0)
@@ -5771,7 +5817,7 @@ function SectionRequestBody(props){const icons=useIcons()
5771
5817
  const pending=()=>props.state.status==="loading"
5772
5818
  return(()=>{var _el$5=_$createElement("box")
5773
5819
  _$insert(_el$5,_$createComponent(RequestErrorRow,props),null)
5774
- _$insert(_el$5,_$createComponent(Show11,{get when(){return _$memo(()=>!!pending())()&&!props.hasItems
5820
+ _$insert(_el$5,_$createComponent(Show12,{get when(){return _$memo(()=>!!pending())()&&!props.hasItems
5775
5821
  },get children(){var _el$6=_$createElement("text"),_el$7=_$createTextNode(` `)
5776
5822
  _$insertNode(_el$6,_el$7)
5777
5823
  _$insert(_el$6,()=>icons.icon("pending"),_el$7)
@@ -5779,10 +5825,10 @@ _$insert(_el$6,()=>props.loading,null)
5779
5825
  _$effect((_$p)=>_$setProp(_el$6,"fg",props.api.theme.current.textMuted,_$p))
5780
5826
  return _el$6
5781
5827
  }}),null)
5782
- _$insert(_el$5,_$createComponent(Show11,{get when(){return props.hasItems
5828
+ _$insert(_el$5,_$createComponent(Show12,{get when(){return props.hasItems
5783
5829
  },get children(){return props.children
5784
5830
  }}),null)
5785
- _$insert(_el$5,_$createComponent(Show11,{get when(){return _$memo(()=>!!((props.state.status==="ready"||props.state.status==="refreshing")&&!props.hasItems))()&&!props.state.error
5831
+ _$insert(_el$5,_$createComponent(Show12,{get when(){return _$memo(()=>!!((props.state.status==="ready"||props.state.status==="refreshing")&&!props.hasItems))()&&!props.state.error
5786
5832
  },get children(){var _el$8=_$createElement("text"),_el$9=_$createTextNode(` `)
5787
5833
  _$insertNode(_el$8,_el$9)
5788
5834
  _$insert(_el$8,()=>icons.icon("info"),_el$9)
@@ -5938,7 +5984,7 @@ return _p$
5938
5984
  },{e:undefined,t:undefined,a:undefined,o:undefined,i:undefined,n:undefined,s:undefined,h:undefined
5939
5985
  })
5940
5986
  return _el$2
5941
- })(),_$createComponent(Show12,{get when(){return props.query
5987
+ })(),_$createComponent(Show13,{get when(){return props.query
5942
5988
  },get children(){var _el$3=_$createElement("text")
5943
5989
  _$setProp(_el$3,"flexShrink",0)
5944
5990
  _$setProp(_el$3,"onMouseDown",()=>props.onInput(""))
@@ -5958,82 +6004,47 @@ _$effect((_$p)=>_$setProp(_el$,"gap",props.density==="comfortable"?1:0,_$p))
5958
6004
  return _el$
5959
6005
  })()
5960
6006
  }
5961
- function McpSectionContent(props){const icons=useIcons()
5962
- const model=props.model
6007
+ function McpSectionContent(props){const model=props.model
5963
6008
  return _$createComponent(SectionRequestBody,{get api(){return props.api
5964
6009
  },get interaction(){return props.interaction
5965
6010
  },id:`${PLUGIN_ID}.retry.mcp`,get position(){return{section:props.navigationSection,row:1,column:0
5966
6011
  }},get state(){return model.state()
5967
6012
  },get hasItems(){return model.list().length>0
5968
- },empty:"No MCP servers",loading:"Loading MCP servers\u2026",onRetry:()=>void props.controller.retry(model.target()),get children(){var _el$=_$createElement("box"),_el$2=_$createElement("box")
5969
- _$insertNode(_el$,_el$2)
5970
- _$setProp(_el$2,"flexDirection","row")
5971
- _$setProp(_el$2,"gap",1)
5972
- _$insert(_el$2,_$createComponent(McpBulkAction,{get api(){return props.api
6013
+ },empty:"No MCP servers",loading:"Loading MCP servers\u2026",onRetry:()=>void props.controller.retry(model.target()),get children(){var _el$=_$createElement("box")
6014
+ _$insert(_el$,_$createComponent(McpBulkControls,{get api(){return props.api
5973
6015
  },get interaction(){return props.interaction
5974
- },id:`${PLUGIN_ID}.mcp.connect-all`,get position(){return{section:props.navigationSection,row:2,column:0
5975
- }},get label(){return `${icons.icon("connected")} Connect all`
5976
- },get disabled(){return model.bulkRunning()||model.mutationRunning()||model.connectable()===0
5977
- },onActivate:()=>void props.controller.connectAll(model.target())
5978
- }),null)
5979
- _$insert(_el$2,_$createComponent(McpBulkAction,{get api(){return props.api
5980
- },get interaction(){return props.interaction
5981
- },id:`${PLUGIN_ID}.mcp.disconnect-all`,get position(){return{section:props.navigationSection,row:2,column:1
5982
- }},get label(){return `${icons.icon("disconnected")} Disconnect all`
5983
- },get disabled(){return model.bulkRunning()||model.mutationRunning()||model.disconnectable()===0
5984
- },onActivate:()=>void props.controller.disconnectAll(model.target())
6016
+ },get controller(){return props.controller
6017
+ },get navigationSection(){return props.navigationSection
6018
+ },model
5985
6019
  }),null)
5986
- _$insert(_el$,_$createComponent(Show13,{get when(){return model.bulkRunning()
5987
- },get children(){var _el$3=_$createElement("text"),_el$4=_$createTextNode(` `),_el$5=_$createTextNode(`/`),_el$6=_$createTextNode(`\u2026`)
5988
- _$insertNode(_el$3,_el$4)
5989
- _$insertNode(_el$3,_el$5)
5990
- _$insertNode(_el$3,_el$6)
5991
- _$insert(_el$3,(()=>{var _c$=_$memo(()=>model.bulk().action==="connect")
5992
- return()=>_c$()?"Connecting":_$memo(()=>model.bulk().action==="disconnect")()?"Disconnecting":`Applying ${model.bulk().preset}`
5993
- })(),_el$4)
5994
- _$insert(_el$3,()=>model.bulk().completed,_el$5)
5995
- _$insert(_el$3,()=>model.bulk().total,_el$6)
5996
- _$effect((_$p)=>_$setProp(_el$3,"fg",props.api.theme.current.textMuted,_$p))
5997
- return _el$3
5998
- }}),null)
5999
- _$insert(_el$,_$createComponent(Show13,{get when(){return model.bulk().status==="error"
6000
- },get children(){return _$createComponent(McpBulkAction,{get api(){return props.api
6001
- },get interaction(){return props.interaction
6002
- },id:`${PLUGIN_ID}.mcp.retry-all`,get position(){return{section:props.navigationSection,row:3,column:0
6003
- }},get label(){return `${icons.icon("retry")} Retry ${model.bulk().failed.length} failed`
6004
- },disabled:false,onActivate:()=>void props.controller.retryBulk(model.target())
6005
- })
6006
- }}),null)
6007
6020
  _$insert(_el$,_$createComponent(SectionFilter,{get api(){return props.api
6008
6021
  },get interaction(){return props.interaction
6009
6022
  },id:`${PLUGIN_ID}.filter.mcp`,get position(){return{section:props.navigationSection,row:4,column:0
6010
6023
  }},get query(){return props.query
6011
6024
  },placeholder:"Filter MCP...",get onInput(){return props.onQuery
6012
6025
  }}),null)
6013
- _$insert(_el$,_$createComponent(Show13,{get when(){return model.filtered().length>0
6014
- },get fallback(){return(()=>{var _el$7=_$createElement("text")
6015
- _$insertNode(_el$7,_$createTextNode(`No matching MCP servers`))
6016
- _$effect((_$p)=>_$setProp(_el$7,"fg",props.api.theme.current.textMuted,_$p))
6017
- return _el$7
6026
+ _$insert(_el$,_$createComponent(Show14,{get when(){return model.filtered().length>0
6027
+ },get fallback(){return(()=>{var _el$2=_$createElement("text")
6028
+ _$insertNode(_el$2,_$createTextNode(`No matching MCP servers`))
6029
+ _$effect((_$p)=>_$setProp(_el$2,"fg",props.api.theme.current.textMuted,_$p))
6030
+ return _el$2
6018
6031
  })()
6019
6032
  },get children(){return [_$createComponent(SidebarRowList,{get density(){return props.preferences.rowDensity?.()??"compact"
6020
6033
  },get children(){return _$createComponent(For13,{get each(){return model.visibility.visible()
6021
- },children:(item,index)=>[_$createComponent(Show13,{get when(){return _$memo(()=>!!model.grouped())()&&(index()===0||model.visibility.visible()[index()-1]?.bucket!==item.bucket)
6022
- },get children(){var _el$9=_$createElement("text")
6023
- _$setProp(_el$9,"height",1)
6024
- _$setProp(_el$9,"wrapMode","none")
6025
- _$setProp(_el$9,"truncate",true)
6026
- _$insert(_el$9,()=>item.bucket)
6027
- _$effect((_p$)=>{var _v$=index()>0?1:0,_v$2=props.api.theme.current.textMuted
6028
- _v$!==_p$.e&&(_p$.e=_$setProp(_el$9,"marginTop",_v$,_p$.e))
6029
- _v$2!==_p$.t&&(_p$.t=_$setProp(_el$9,"fg",_v$2,_p$.t))
6030
- return _p$
6031
- },{e:undefined,t:undefined
6034
+ },children:(item,index)=>[_$createComponent(Show14,{get when(){return _$memo(()=>!!model.grouped())()&&(index()===0||model.visibility.visible()[index()-1]?.bucket!==item.bucket)
6035
+ },get children(){return _$createComponent(McpGroupHeader,{get api(){return props.api
6036
+ },get interaction(){return props.interaction
6037
+ },get bucket(){return item.bucket
6038
+ },get count(){return model.groupNames(item.bucket).length
6039
+ },get action(){return model.groupAction(item.bucket)
6040
+ },get disabled(){return model.bulkRunning()||model.mutationRunning()
6041
+ },get marginTop(){return index()>0?1:0
6042
+ },get position(){return{section:props.navigationSection,row:9 + index()*3,column:0
6043
+ }},onToggle:()=>void props.controller.toggleGroup(item.bucket,model.groupNames(item.bucket),model.target())
6032
6044
  })
6033
- return _el$9
6034
6045
  }}),_$createComponent(McpRow,{get api(){return props.api
6035
6046
  },get interaction(){return props.interaction
6036
- },item,get position(){return{section:props.navigationSection,row:10 + index()*2,column:0
6047
+ },item,get position(){return{section:props.navigationSection,row:10 + index()*3,column:0
6037
6048
  }},get state(){return props.controller.serverState(item.name,model.target())
6038
6049
  },get disabled(){return model.bulkRunning()
6039
6050
  },onToggle:()=>void props.controller.toggle(item.name).catch(()=>{}),onRetry:()=>void props.controller.retryServer(item.name,model.target())?.catch(()=>{}),get favorite(){return model.favorites().has(item.name)
@@ -6045,11 +6056,10 @@ return _el$9
6045
6056
  }}),_$createComponent(ListVisibilityControl,{get api(){return props.api
6046
6057
  },get interaction(){return props.interaction
6047
6058
  },section:"mcp",get navigationSection(){return props.navigationSection
6048
- },get row(){return 10 + model.visibility.visible().length*2
6059
+ },get row(){return 10 + model.visibility.visible().length*3
6049
6060
  },get visibility(){return model.visibility
6050
6061
  }})]
6051
6062
  }}),null)
6052
- _$effect((_$p)=>_$setProp(_el$2,"paddingBottom",model.bulkRunning()||model.bulk().status==="error"?1:0,_$p))
6053
6063
  return _el$
6054
6064
  }})
6055
6065
  }
@@ -6057,7 +6067,7 @@ function McpSection(props){const icons=useIcons()
6057
6067
  const [query,setQuery]=createSignal24("")
6058
6068
  const model=createMcpSectionModel(props,query)
6059
6069
  const navigationSection=()=>props.navigationSection??6
6060
- const summary=createMemo12(()=>`${model.active()}/${model.list().length}${model.errors() ? ` \xB7 ${model.errors()} ${icons.icon("error")}` : ""}`)
6070
+ const summary=createMemo13(()=>`${model.active()}/${model.list().length}${model.errors() ? ` \xB7 ${model.errors()} ${icons.icon("error")}` : ""}`)
6061
6071
  return _$createComponent(SectionWithHeaderAction,{get api(){return props.api
6062
6072
  },get interaction(){return props.interaction
6063
6073
  },sectionId:`${PLUGIN_ID}.section.mcp`,get navigationSection(){return navigationSection()
@@ -6092,11 +6102,11 @@ return _$createComponent(SectionWithHeaderAction,{get api(){return props.api
6092
6102
  function QuickActionRow(props){const icons=useIcons()
6093
6103
  const theme=()=>props.api.theme.current
6094
6104
  const [width,setWidth]=createSignal25(0)
6095
- const shortcut=createMemo13(()=>{const bindings=props.api.keymap.getCommandBindings({visibility:"registered",commands:[props.action.command]
6105
+ const shortcut=createMemo14(()=>{const bindings=props.api.keymap.getCommandBindings({visibility:"registered",commands:[props.action.command]
6096
6106
  })
6097
6107
  return props.api.keys.formatBindings(bindings.get(props.action.command))
6098
6108
  })
6099
- const visibleShortcut=createMemo13(()=>{const value=shortcut()
6109
+ const visibleShortcut=createMemo14(()=>{const value=shortcut()
6100
6110
  return value&&width()>=Bun.stringWidth(props.action.label) + Bun.stringWidth(value) + 9?value:undefined
6101
6111
  })
6102
6112
  function run(){if(props.action.command==="session.new"&&props.onNewSession?.())
@@ -6123,7 +6133,9 @@ return _$createComponent(ListRow,{ref:(node)=>row.ref(node),get id(){return id()
6123
6133
  },get backgroundColor(){return row.backgroundColor()
6124
6134
  },get onMouseOver(){return row.onMouseOver
6125
6135
  },get onMouseOut(){return row.onMouseOut
6126
- },onMouseUp:(event)=>row.activate(event),get leading(){return(()=>{var _el$=_$createElement("text")
6136
+ },onMouseUp:(event)=>{event.stopPropagation()
6137
+ row.activate(event)
6138
+ },get leading(){return(()=>{var _el$=_$createElement("text")
6127
6139
  _$setProp(_el$,"flexShrink",0)
6128
6140
  _$insert(_el$,()=>icons.action(props.action.command))
6129
6141
  _$effect((_$p)=>_$setProp(_el$,"fg",props.disabled?theme().textMuted:row.focused()?row.foregroundColor():theme().accent,_$p))
@@ -6137,7 +6149,7 @@ _$insert(_el$2,()=>props.action.label)
6137
6149
  _$effect((_$p)=>_$setProp(_el$2,"fg",row.foregroundColor(),_$p))
6138
6150
  return _el$2
6139
6151
  })()
6140
- },get metadata(){return _$createComponent(Show14,{get when(){return visibleShortcut()
6152
+ },get metadata(){return _$createComponent(Show15,{get when(){return visibleShortcut()
6141
6153
  },children:(value)=>(()=>{var _el$3=_$createElement("text")
6142
6154
  _$setProp(_el$3,"flexShrink",0)
6143
6155
  _$setProp(_el$3,"wrapMode","none")
@@ -6146,7 +6158,7 @@ _$effect((_$p)=>_$setProp(_el$3,"fg",row.focused()?row.foregroundColor():theme()
6146
6158
  return _el$3
6147
6159
  })()
6148
6160
  })
6149
- },get details(){return _$createComponent(Show14,{get when(){return props.disabled
6161
+ },get details(){return _$createComponent(Show15,{get when(){return props.disabled
6150
6162
  },children:(reason)=>(()=>{var _el$4=_$createElement("text")
6151
6163
  _$setProp(_el$4,"wrapMode","word")
6152
6164
  _$insert(_el$4,reason)
@@ -6165,7 +6177,7 @@ return _el$4
6165
6177
  }})
6166
6178
  }
6167
6179
  function QuickActionsSection(props){const commandRevision=createQuickActionRevision(props.api)
6168
- const actions=createMemo14(()=>{commandRevision()
6180
+ const actions=createMemo15(()=>{commandRevision()
6169
6181
  return orderQuickActionIds(props.preferences.quickActionOrder?.()??QUICK_ACTIONS.map((action)=>action.command),props.preferences.favoriteQuickActions?.()??new Set).flatMap((id)=>{const action=QUICK_ACTIONS.find((candidate)=>candidate.command===id)
6170
6182
  return action&&props.preferences.quickActionVisible?.(id)!==false?[{...action,label:quickActionLabel(props.api,action),disabled:quickActionDisabledReason(props.api,action)
6171
6183
  }]:[]
@@ -6180,7 +6192,7 @@ return _$createComponent(Section,{get api(){return props.api
6180
6192
  },title:"QUICK ACTIONS",section:"quick_actions",get summary(){return String(actions().length)
6181
6193
  },get open(){return props.preferences.expanded().quick_actions
6182
6194
  },onToggle:()=>props.preferences.toggleSectionExpanded("quick_actions"),get children(){return [_$createComponent(SidebarRowList,{get density(){return props.preferences.rowDensity?.()??"compact"
6183
- },get children(){return [_$createComponent(Show15,{get when(){return actions().length===0
6195
+ },get children(){return [_$createComponent(Show16,{get when(){return actions().length===0
6184
6196
  },get children(){var _el$=_$createElement("text")
6185
6197
  _$insertNode(_el$,_$createTextNode(`No quick actions selected`))
6186
6198
  _$effect((_$p)=>_$setProp(_el$,"fg",props.api.theme.current.textMuted,_$p))
@@ -6297,7 +6309,7 @@ unregisterBinding=undefined
6297
6309
  unregisterCommands()
6298
6310
  }}}
6299
6311
  function SidebarToggleBinding(props){const shortcuts=createSidebarShortcutMode(props.api)
6300
- createEffect12(()=>shortcuts.bind(props.preferences.toggleKey()))
6312
+ createEffect13(()=>shortcuts.bind(props.preferences.toggleKey()))
6301
6313
  onCleanup17(shortcuts.dispose)
6302
6314
  return _$createElement("box")
6303
6315
  }
@@ -6307,7 +6319,7 @@ const unregisterCommands=props.api.keymap.registerLayer({commands:[...commands,.
6307
6319
  }))]
6308
6320
  })
6309
6321
  onCleanup17(unregisterCommands)
6310
- createEffect12(()=>{const unregister=props.api.keymap.registerLayer({bindings:[{key:props.preferences.focusKey(),cmd:FOCUS_COMMAND
6322
+ createEffect13(()=>{const unregister=props.api.keymap.registerLayer({bindings:[{key:props.preferences.focusKey(),cmd:FOCUS_COMMAND
6311
6323
  }]
6312
6324
  })
6313
6325
  onCleanup17(unregister)
@@ -6332,22 +6344,19 @@ return _$createElement("box")
6332
6344
 
6333
6345
 
6334
6346
 
6335
- function createSkillSectionModel(props,query){const target=createMemo15(()=>props.controller.target())
6336
- const recent=createMemo15(()=>new Map((props.preferences.recentSkills?.()??[]).map((location,index)=>[location,index])))
6337
- const list=createMemo15(()=>{const favorites=props.preferences.favoriteSkills?.()??new Set
6338
- return [...props.controller.list(target())].sort((left,right)=>{const isLeftFavorite=favorites.has(left.location)
6339
- const isRightFavorite=favorites.has(right.location)
6340
- return Number(isRightFavorite)-Number(isLeftFavorite)||(isLeftFavorite?0:(recent().get(left.location)??Infinity)-(recent().get(right.location)??Infinity))||left.name.localeCompare(right.name)
6341
- }).map((item)=>({...item}))
6342
- })
6343
- const filtered=createMemo15(()=>list().filter((item)=>matchesFilter(query(),item.name,item.description)))
6347
+ function createSkillSectionModel(props,query){const target=createMemo16(()=>props.controller.target())
6348
+ const recent=createMemo16(()=>new Map((props.preferences.recentSkills?.()??[]).map((location,index)=>[location,index])))
6349
+ const groups=createMemo16(()=>props.preferences.skillGroups?.()??{})
6350
+ const grouped=createMemo16(()=>Object.keys(groups()).length>0)
6351
+ const list=createMemo16(()=>buildSkillGroupedView(props.controller.list(target()),props.preferences.favoriteSkills?.()??new Set,groups(),recent()))
6352
+ const filtered=createMemo16(()=>list().filter((item)=>matchesFilter(query(),item.name,item.description,item.assignedGroup)))
6344
6353
  const visibility=createListVisibility({items:filtered,limit:()=>props.preferences.sectionItemLimit?.("skills")??0,resetKey:()=>JSON.stringify([target().key,query()])
6345
6354
  })
6346
- const state=createMemo15(()=>props.controller.state(target()))
6347
- createEffect13(()=>{const current=target()
6348
- const deactivate=untrack4(()=>props.controller.activate?.(current)??(()=>{}))
6355
+ const state=createMemo16(()=>props.controller.state(target()))
6356
+ createEffect14(()=>{const current=target()
6357
+ const deactivate=untrack5(()=>props.controller.activate?.(current)??(()=>{}))
6349
6358
  onCleanup18(deactivate)
6350
- untrack4(()=>void props.controller.refresh(current).catch(()=>{}))
6359
+ untrack5(()=>void props.controller.refresh(current).catch(()=>{}))
6351
6360
  })
6352
6361
  async function useSkill(item){try{const isInserted=await props.controller.use(target(),item.name)
6353
6362
  if(isInserted)
@@ -6357,11 +6366,13 @@ return
6357
6366
  props.api.ui.toast({variant:"error",title:"Skills",message:error instanceof Error?error.message:`Failed to insert /${item.name}`,duration:5000
6358
6367
  })
6359
6368
  }}
6360
- function skillGroup(item){if(props.preferences.isFavoriteSkill?.(item))
6369
+ function skillGroup(item){if(grouped())
6370
+ return item.bucket
6371
+ if(props.preferences.isFavoriteSkill?.(item))
6361
6372
  return "favorite"
6362
6373
  return recent().has(item.location)?"recent":"other"
6363
6374
  }
6364
- return{target,recent,list,filtered,visibility,state,useSkill,skillGroup}}
6375
+ return{target,recent,grouped,list,filtered,visibility,state,useSkill,skillGroup}}
6365
6376
 
6366
6377
 
6367
6378
 
@@ -6443,7 +6454,7 @@ _$insert(_el$,_$createComponent(SectionFilter,{get api(){return props.api
6443
6454
  }},get query(){return query()
6444
6455
  },placeholder:"Filter skills...",onInput:setQuery
6445
6456
  }),null)
6446
- _$insert(_el$,_$createComponent(Show16,{get when(){return model.filtered().length>0
6457
+ _$insert(_el$,_$createComponent(Show17,{get when(){return model.filtered().length>0
6447
6458
  },get fallback(){return(()=>{var _el$2=_$createElement("text")
6448
6459
  _$insertNode(_el$2,_$createTextNode(`No matching skills`))
6449
6460
  _$effect((_$p)=>_$setProp(_el$2,"fg",props.api.theme.current.textMuted,_$p))
@@ -6451,20 +6462,33 @@ return _el$2
6451
6462
  })()
6452
6463
  },get children(){return [_$createComponent(SidebarRowList,{get density(){return props.preferences.rowDensity?.()??"compact"
6453
6464
  },get children(){return _$createComponent(For15,{get each(){return model.visibility.visible()
6454
- },children:(item,index)=>_$createComponent(SkillRow,{get api(){return props.api
6465
+ },children:(item,index)=>[_$createComponent(Show17,{get when(){return _$memo(()=>!!model.grouped())()&&(index()===0||model.visibility.visible()[index()-1]?.bucket!==item.bucket)
6466
+ },get children(){var _el$4=_$createElement("text")
6467
+ _$setProp(_el$4,"height",1)
6468
+ _$setProp(_el$4,"wrapMode","none")
6469
+ _$setProp(_el$4,"truncate",true)
6470
+ _$insert(_el$4,()=>item.bucket)
6471
+ _$effect((_p$)=>{var _v$=index()>0?1:0,_v$2=props.api.theme.current.textMuted
6472
+ _v$!==_p$.e&&(_p$.e=_$setProp(_el$4,"marginTop",_v$,_p$.e))
6473
+ _v$2!==_p$.t&&(_p$.t=_$setProp(_el$4,"fg",_v$2,_p$.t))
6474
+ return _p$
6475
+ },{e:undefined,t:undefined
6476
+ })
6477
+ return _el$4
6478
+ }}),_$createComponent(SkillRow,{get api(){return props.api
6455
6479
  },get interaction(){return props.interaction
6456
- },item,get position(){return{section:navigationSection(),row:10 + index(),column:0
6480
+ },item,get position(){return{section:navigationSection(),row:10 + index()*(model.grouped()?2:1),column:0
6457
6481
  }},onUse:()=>selectSkill(item),get recent(){return model.recent().has(item.location)
6458
6482
  },get favorite(){return props.preferences.isFavoriteSkill?.(item)??false
6459
6483
  },get favoriteDisabled(){return props.preferences.ready?.()===false
6460
- },get separator(){return _$memo(()=>index()>0)()&&model.skillGroup(model.visibility.visible()[index()-1])!==model.skillGroup(item)
6484
+ },get separator(){return _$memo(()=>!!(!model.grouped()&&index()>0))()&&model.skillGroup(model.visibility.visible()[index()-1])!==model.skillGroup(item)
6461
6485
  },onToggleFavorite:()=>props.preferences.toggleFavoriteSkill?.(item)
6462
- })
6486
+ })]
6463
6487
  })
6464
6488
  }}),_$createComponent(ListVisibilityControl,{get api(){return props.api
6465
6489
  },get interaction(){return props.interaction
6466
6490
  },section:"skills",get navigationSection(){return navigationSection()
6467
- },get row(){return 10 + model.visibility.visible().length
6491
+ },get row(){return 10 + model.visibility.visible().length*(model.grouped()?2:1)
6468
6492
  },get visibility(){return model.visibility
6469
6493
  }})]
6470
6494
  }}),null)
@@ -6482,35 +6506,35 @@ return _el$
6482
6506
 
6483
6507
 
6484
6508
 
6485
- function createSubagentSectionModel(props){const list=createMemo16(()=>props.controller.list(props.sessionID))
6486
- const recent=createMemo16(()=>props.controller.recent?.(props.sessionID)??[])
6487
- const rows=createMemo16(()=>buildSubagentView(list(),recent()))
6509
+ function createSubagentSectionModel(props){const list=createMemo17(()=>props.controller.list(props.sessionID))
6510
+ const recent=createMemo17(()=>props.controller.recent?.(props.sessionID)??[])
6511
+ const rows=createMemo17(()=>buildSubagentView(list(),recent()))
6488
6512
  const [query,setQuery]=createSignal27("")
6489
6513
  const [mode,setMode]=createSignal27("all")
6490
- const counts=createMemo16(()=>countSubagentView(rows(),query()))
6491
- const tabs=createMemo16(()=>["all","active","recent",...counts().errors>0?["errors"]:[]])
6492
- const filtered=createMemo16(()=>filterSubagentView(rows(),mode(),query()))
6493
- const parentID=createMemo16(()=>props.api.state?.session?.get(props.sessionID)?.parentID)
6494
- const targetKey=createMemo16(()=>props.controller.target?.(props.sessionID).key??props.sessionID)
6495
- createEffect14(()=>{targetKey()
6514
+ const counts=createMemo17(()=>countSubagentView(rows(),query()))
6515
+ const tabs=createMemo17(()=>["all","active","recent",...counts().errors>0?["errors"]:[]])
6516
+ const filtered=createMemo17(()=>filterSubagentView(rows(),mode(),query()))
6517
+ const parentID=createMemo17(()=>props.api.state?.session?.get(props.sessionID)?.parentID)
6518
+ const targetKey=createMemo17(()=>props.controller.target?.(props.sessionID).key??props.sessionID)
6519
+ createEffect15(()=>{targetKey()
6496
6520
  setQuery("")
6497
6521
  setMode("all")
6498
6522
  })
6499
- createEffect14(()=>{if(mode()!=="all"&&counts()[mode()]===0)
6523
+ createEffect15(()=>{if(mode()!=="all"&&counts()[mode()]===0)
6500
6524
  setMode("all")
6501
6525
  })
6502
6526
  const visibility=createListVisibility({items:filtered,limit:()=>props.preferences.sectionItemLimit?.("subagents")??0,resetKey:()=>JSON.stringify([targetKey(),query(),mode()])
6503
6527
  })
6504
- const clockKey=createMemo16(()=>props.preferences.expanded().subagents&&visibility.visible().some((item)=>item.status.type!=="idle")?targetKey():undefined)
6528
+ const clockKey=createMemo17(()=>props.preferences.expanded().subagents&&visibility.visible().some((item)=>item.status.type!=="idle")?targetKey():undefined)
6505
6529
  const now=createSubagentClock(clockKey)
6506
- const byId=createMemo16(()=>new Map(visibility.visible().map((item)=>[item.session.id,item])))
6507
- const ids=createMemo16(()=>visibility.visible().map((item)=>item.session.id))
6508
- const state=createMemo16(()=>props.controller.state(props.sessionID))
6509
- createEffect14(()=>{const sessionID=props.sessionID
6530
+ const byId=createMemo17(()=>new Map(visibility.visible().map((item)=>[item.session.id,item])))
6531
+ const ids=createMemo17(()=>visibility.visible().map((item)=>item.session.id))
6532
+ const state=createMemo17(()=>props.controller.state(props.sessionID))
6533
+ createEffect15(()=>{const sessionID=props.sessionID
6510
6534
  targetKey()
6511
- const deactivate=untrack5(()=>props.controller.activate?.(sessionID)??(()=>{}))
6535
+ const deactivate=untrack6(()=>props.controller.activate?.(sessionID)??(()=>{}))
6512
6536
  onCleanup19(deactivate)
6513
- untrack5(()=>void props.controller.refresh(sessionID).catch(()=>{}))
6537
+ untrack6(()=>void props.controller.refresh(sessionID).catch(()=>{}))
6514
6538
  })
6515
6539
  return{list,recent,rows,query,setQuery,mode,setMode,counts,tabs,filtered,parentID,visibility,now,byId,ids,state
6516
6540
  }}
@@ -6565,7 +6589,7 @@ return()=>_c$()?`${props.item.run.startedBeforeObservation ? `${icons.icon("rece
6565
6589
  _$effect((_$p)=>_$setProp(_el$3,"fg",row.focused()?row.foregroundColor():theme().textMuted,_$p))
6566
6590
  return _el$3
6567
6591
  })()
6568
- },get details(){return [_$createComponent(Show17,{get when(){return props.item.run?.errorMessage
6592
+ },get details(){return [_$createComponent(Show18,{get when(){return props.item.run?.errorMessage
6569
6593
  },get children(){var _el$4=_$createElement("text"),_el$5=_$createTextNode(`: `)
6570
6594
  _$insertNode(_el$4,_el$5)
6571
6595
  _$setProp(_el$4,"wrapMode","word")
@@ -6573,12 +6597,12 @@ _$insert(_el$4,()=>cancelled()?"Cancelled":"Error",_el$5)
6573
6597
  _$insert(_el$4,()=>props.item.run?.errorMessage,null)
6574
6598
  _$effect((_$p)=>_$setProp(_el$4,"fg",row.focused()?row.foregroundColor():failed()?theme().error:theme().textMuted,_$p))
6575
6599
  return _el$4
6576
- }}),_$createComponent(Show17,{get when(){return props.item.unavailable
6600
+ }}),_$createComponent(Show18,{get when(){return props.item.unavailable
6577
6601
  },get children(){var _el$6=_$createElement("text")
6578
6602
  _$insertNode(_el$6,_$createTextNode(`Worker status unavailable`))
6579
6603
  _$effect((_$p)=>_$setProp(_el$6,"fg",theme().warning,_$p))
6580
6604
  return _el$6
6581
- }}),_$createComponent(Show17,{get when(){return _$memo(()=>props.item.status.type==="retry")()?props.item.status:undefined
6605
+ }}),_$createComponent(Show18,{get when(){return _$memo(()=>props.item.status.type==="retry")()?props.item.status:undefined
6582
6606
  },children:(status)=>(()=>{var _el$0=_$createElement("text"),_el$1=_$createTextNode(`Retry #`),_el$10=_$createTextNode(` \xB7 `),_el$11=_$createTextNode(`s \xB7 `)
6583
6607
  _$insertNode(_el$0,_el$1)
6584
6608
  _$insertNode(_el$0,_el$10)
@@ -6590,7 +6614,7 @@ _$insert(_el$0,()=>status().message,null)
6590
6614
  _$effect((_$p)=>_$setProp(_el$0,"fg",row.focused()?row.foregroundColor():theme().warning,_$p))
6591
6615
  return _el$0
6592
6616
  })()
6593
- }),_$createComponent(Show17,{get when(){return _$memo(()=>!!idle())()&&!props.item.run?.errorMessage
6617
+ }),_$createComponent(Show18,{get when(){return _$memo(()=>!!idle())()&&!props.item.run?.errorMessage
6594
6618
  },get children(){var _el$8=_$createElement("text")
6595
6619
  _$insertNode(_el$8,_$createTextNode(`Finished`))
6596
6620
  _$effect((_$p)=>_$setProp(_el$8,"fg",theme().textMuted,_$p))
@@ -6604,7 +6628,7 @@ function SubagentList(props){return _$createComponent(SidebarRowList,{get densit
6604
6628
  const item=()=>props.itemById(id)??initial
6605
6629
  const startsGroup=()=>index()===0||props.visible[index()-1]?.group!==item().group
6606
6630
  return(()=>{var _el$=_$createElement("box")
6607
- _$insert(_el$,_$createComponent(Show18,{get when(){return startsGroup()
6631
+ _$insert(_el$,_$createComponent(Show19,{get when(){return startsGroup()
6608
6632
  },get children(){var _el$2=_$createElement("text"),_el$3=_$createElement("b")
6609
6633
  _$insertNode(_el$2,_el$3)
6610
6634
  _$insert(_el$3,()=>item().group)
@@ -6632,7 +6656,7 @@ return _$createComponent(Section,{get api(){return props.api
6632
6656
  },sectionId:`${PLUGIN_ID}.section.subagents`,get navigationSection(){return navigationSection()
6633
6657
  },title:"SUBAGENTS",section:"subagents",get summary(){return `${model.list().length} active \xB7 ${model.recent().length} recent`
6634
6658
  },get open(){return props.preferences.expanded().subagents
6635
- },onToggle:()=>props.preferences.toggleSectionExpanded("subagents"),get children(){return [_$createComponent(Show19,{get when(){return model.parentID()
6659
+ },onToggle:()=>props.preferences.toggleSectionExpanded("subagents"),get children(){return [_$createComponent(Show20,{get when(){return model.parentID()
6636
6660
  },children:(id)=>_$createComponent(McpBulkAction,{get api(){return props.api
6637
6661
  },get interaction(){return props.interaction
6638
6662
  },id:`${PLUGIN_ID}.subagents.parent`,get position(){return{section:navigationSection(),row:1,column:0
@@ -6666,7 +6690,7 @@ _$insert(_el$2,_$createComponent(For17,{get each(){return model.tabs()
6666
6690
  },onActivate:()=>model.setMode(value)
6667
6691
  })
6668
6692
  }))
6669
- _$insert(_el$,_$createComponent(Show19,{get when(){return model.filtered().length===0
6693
+ _$insert(_el$,_$createComponent(Show20,{get when(){return model.filtered().length===0
6670
6694
  },get children(){var _el$3=_$createElement("text")
6671
6695
  _$insertNode(_el$3,_$createTextNode(`No matching subagents`))
6672
6696
  _$effect((_$p)=>_$setProp(_el$3,"fg",props.api.theme.current.textMuted,_$p))
@@ -6747,7 +6771,7 @@ _$insert(_el$2,()=>icons.icon(done()?"done":active()?"busy":cancelled()?"close":
6747
6771
  _$setProp(_el$3,"flexGrow",1)
6748
6772
  _$setProp(_el$3,"wrapMode","word")
6749
6773
  _$insert(_el$3,()=>props.item.content)
6750
- _$insert(_el$,_$createComponent(Show20,{get when(){return props.item.priority==="high"||props.item.priority==="medium"||props.item.priority==="low"
6774
+ _$insert(_el$,_$createComponent(Show21,{get when(){return props.item.priority==="high"||props.item.priority==="medium"||props.item.priority==="low"
6751
6775
  },get children(){var _el$4=_$createElement("text"),_el$5=_$createElement("b"),_el$6=_$createTextNode(` `)
6752
6776
  _$insertNode(_el$4,_el$5)
6753
6777
  _$setProp(_el$4,"width",2)
@@ -6783,7 +6807,7 @@ _$insert(_el$2,_$createComponent(For18,{each:["all","active","finished"],childre
6783
6807
  },onActivate:()=>props.setMode(value)
6784
6808
  })
6785
6809
  }))
6786
- _$insert(_el$,_$createComponent(Show21,{get when(){return props.view.rows.length>0
6810
+ _$insert(_el$,_$createComponent(Show22,{get when(){return props.view.rows.length>0
6787
6811
  },get fallback(){return _$createComponent(EmptyTodo,{get api(){return props.api
6788
6812
  },get mode(){return props.mode
6789
6813
  }})
@@ -6791,7 +6815,7 @@ _$insert(_el$,_$createComponent(Show21,{get when(){return props.view.rows.length
6791
6815
  },get children(){return _$createComponent(For18,{get each(){return props.visibility.visible()
6792
6816
  },children:(row,index)=>{const startsGroup=()=>index()===0||props.visibility.visible()[index()-1].group!==row.group
6793
6817
  return(()=>{var _el$3=_$createElement("box")
6794
- _$insert(_el$3,_$createComponent(Show21,{get when(){return startsGroup()
6818
+ _$insert(_el$3,_$createComponent(Show22,{get when(){return startsGroup()
6795
6819
  },get children(){var _el$4=_$createElement("text"),_el$5=_$createElement("b")
6796
6820
  _$insertNode(_el$4,_el$5)
6797
6821
  _$insert(_el$5,()=>row.group)
@@ -6829,7 +6853,7 @@ return _el$6
6829
6853
 
6830
6854
 
6831
6855
  function TodoGuidanceControl(props){const state=()=>props.controller.guidance(props.sessionID)
6832
- return _$createComponent(Show22,{get when(){return state().available
6856
+ return _$createComponent(Show23,{get when(){return state().available
6833
6857
  },get children(){var _el$=_$createElement("box")
6834
6858
  _$insert(_el$,_$createComponent(SectionTab,{get api(){return props.api
6835
6859
  },get interaction(){return props.interaction
@@ -6839,7 +6863,7 @@ _$insert(_el$,_$createComponent(SectionTab,{get api(){return props.api
6839
6863
  },get disabled(){return state().saving
6840
6864
  },onActivate:()=>void props.controller.setGuidance(props.sessionID,!state().enabled)
6841
6865
  }),null)
6842
- _$insert(_el$,_$createComponent(Show22,{get when(){return state().error
6866
+ _$insert(_el$,_$createComponent(Show23,{get when(){return state().error
6843
6867
  },children:(message)=>(()=>{var _el$2=_$createElement("text")
6844
6868
  _$setProp(_el$2,"wrapMode","word")
6845
6869
  _$insert(_el$2,message)
@@ -6850,26 +6874,26 @@ return _el$2
6850
6874
  return _el$
6851
6875
  }})
6852
6876
  }
6853
- function TodoSection(props){const list=createMemo17(()=>props.controller.list(props.sessionID))
6877
+ function TodoSection(props){const list=createMemo18(()=>props.controller.list(props.sessionID))
6854
6878
  const icons=useIcons()
6855
6879
  const unavailable=()=>hostCapabilityUnavailable(props.api,"todo")
6856
6880
  const managed=()=>("guidance" in props.controller)?props.controller:undefined
6857
6881
  const [mode,setMode]=createSignal28("all")
6858
- const targetKey=createMemo17(()=>props.controller.target?.(props.sessionID).key??props.sessionID)
6859
- createEffect15(()=>{targetKey()
6882
+ const targetKey=createMemo18(()=>props.controller.target?.(props.sessionID).key??props.sessionID)
6883
+ createEffect16(()=>{targetKey()
6860
6884
  setMode("all")
6861
6885
  })
6862
- const view=createMemo17(()=>buildTodoView(list(),mode()))
6886
+ const view=createMemo18(()=>buildTodoView(list(),mode()))
6863
6887
  const visibility=createListVisibility({items:()=>view().rows,limit:()=>props.preferences.sectionItemLimit?.("todo")??0,resetKey:()=>JSON.stringify([targetKey(),mode()])
6864
6888
  })
6865
- const state=createMemo17(()=>props.controller.state(props.sessionID))
6866
- createEffect15(()=>{const sessionID=props.sessionID
6889
+ const state=createMemo18(()=>props.controller.state(props.sessionID))
6890
+ createEffect16(()=>{const sessionID=props.sessionID
6867
6891
  targetKey()
6868
6892
  if(unavailable())
6869
6893
  return
6870
- const deactivate=untrack6(()=>props.controller.activate?.(sessionID)??(()=>{}))
6894
+ const deactivate=untrack7(()=>props.controller.activate?.(sessionID)??(()=>{}))
6871
6895
  onCleanup20(deactivate)
6872
- untrack6(()=>void props.controller.refresh(sessionID).catch(()=>{}))
6896
+ untrack7(()=>void props.controller.refresh(sessionID).catch(()=>{}))
6873
6897
  })
6874
6898
  const navigationSection=()=>props.navigationSection??1
6875
6899
  return _$createComponent(Section,{get api(){return props.api
@@ -6877,10 +6901,10 @@ return _$createComponent(Section,{get api(){return props.api
6877
6901
  },sectionId:`${PLUGIN_ID}.section.todo`,get navigationSection(){return navigationSection()
6878
6902
  },title:"TODO",section:"todo",get summary(){return _$memo(()=>!!(unavailable()||managed()?.missing(props.sessionID)))()?"\u2014":`${view().counts.completed}/${list().length}`
6879
6903
  },get open(){return props.preferences.expanded().todo
6880
- },onToggle:()=>props.preferences.toggleSectionExpanded("todo"),get children(){return _$createComponent(Show23,{get when(){return unavailable()
6904
+ },onToggle:()=>props.preferences.toggleSectionExpanded("todo"),get children(){return _$createComponent(Show24,{get when(){return unavailable()
6881
6905
  },get fallback(){return(()=>{var _el$=_$createElement("box")
6882
6906
  _$setProp(_el$,"gap",1)
6883
- _$insert(_el$,_$createComponent(Show23,{get when(){return managed()?.guidance(props.sessionID).available
6907
+ _$insert(_el$,_$createComponent(Show24,{get when(){return managed()?.guidance(props.sessionID).available
6884
6908
  },get children(){return _$createComponent(TodoGuidanceControl,{get api(){return props.api
6885
6909
  },get controller(){return managed()
6886
6910
  },get sessionID(){return props.sessionID
@@ -6888,7 +6912,7 @@ _$insert(_el$,_$createComponent(Show23,{get when(){return managed()?.guidance(pr
6888
6912
  },get navigationSection(){return navigationSection()
6889
6913
  }})
6890
6914
  }}),null)
6891
- _$insert(_el$,_$createComponent(Show23,{get when(){return managed()?.missing(props.sessionID)
6915
+ _$insert(_el$,_$createComponent(Show24,{get when(){return managed()?.missing(props.sessionID)
6892
6916
  },get fallback(){return _$createComponent(SectionRequestBody,{get api(){return props.api
6893
6917
  },get interaction(){return props.interaction
6894
6918
  },id:`${PLUGIN_ID}.retry.todo`,get position(){return{section:navigationSection(),row:1,column:0
@@ -6924,7 +6948,7 @@ return _el$4
6924
6948
  }})
6925
6949
  }
6926
6950
  function SidebarContent(props){const sections=props.preferences.sections
6927
- const visibleSections=createMemo18(()=>props.preferences.sectionOrder().filter((section)=>sections()[section]&&supportsSidebarSection(props.api,section)))
6951
+ const visibleSections=createMemo19(()=>props.preferences.sectionOrder().filter((section)=>sections()[section]&&supportsSidebarSection(props.api,section)))
6928
6952
  onCleanup21(()=>props.interaction.setContentRoot(undefined))
6929
6953
  return(()=>{var _el$=_$createElement("box")
6930
6954
  _$use((node)=>props.interaction.setContentRoot(node),_el$)
@@ -6971,8 +6995,8 @@ return _el$
6971
6995
  }
6972
6996
 
6973
6997
 
6974
- function McpPersistence(props){const persist=createMemo19(()=>props.controller.persist())
6975
- createEffect16(()=>{if(!props.api.state.ready)
6998
+ function McpPersistence(props){const persist=createMemo20(()=>props.controller.persist())
6999
+ createEffect17(()=>{if(!props.api.state.ready)
6976
7000
  return
6977
7001
  persist()
6978
7002
  const route=props.api.route.current
@@ -6981,19 +7005,19 @@ if(typeof params?.sessionID!=="string")
6981
7005
  return
6982
7006
  const current=props.controller.target()
6983
7007
  onCleanup22(()=>props.controller.deactivate(current))
6984
- untrack7(()=>void props.controller.activate(current).catch(()=>{}))
7008
+ untrack8(()=>void props.controller.activate(current).catch(()=>{}))
6985
7009
  })
6986
7010
  return _$createElement("box")
6987
7011
  }
6988
- function PreferencesPersistence(props){createEffect16(()=>{const location=currentLocation(props.api)
6989
- untrack7(()=>props.controller.setActiveScope(preferencesScope({directory:location.routing.directory,worktree:props.api.state.path.worktree
7012
+ function PreferencesPersistence(props){createEffect17(()=>{const location=currentLocation(props.api)
7013
+ untrack8(()=>props.controller.setActiveScope(preferencesScope({directory:location.routing.directory,worktree:props.api.state.path.worktree
6990
7014
  })))
6991
7015
  props.controller.load()
6992
7016
  })
6993
7017
  return _$createElement("box")
6994
7018
  }
6995
7019
  function FirstRunWizardPersistence(props){let isChecked=false
6996
- createEffect16(()=>{if(isChecked)
7020
+ createEffect17(()=>{if(isChecked)
6997
7021
  return
6998
7022
  isChecked=true
6999
7023
  showFirstRunWizard(props.api,props.preferences).catch(()=>{})
@@ -7011,14 +7035,14 @@ return _$createElement("box")
7011
7035
 
7012
7036
  function SidebarTitle(props){const icons=useIcons()
7013
7037
  const theme=()=>props.api.theme.current
7014
- const created=createMemo20(()=>{const value=props.api.state.session.get(props.sessionID)?.time?.created
7038
+ const created=createMemo21(()=>{const value=props.api.state.session.get(props.sessionID)?.time?.created
7015
7039
  return value===undefined?undefined:`Created ${new Date(value).toLocaleDateString("en", {
7016
7040
  dateStyle: "medium"
7017
7041
  })}`
7018
7042
  })
7019
7043
  const settingsId=`${PLUGIN_ID}.settings`
7020
7044
  const settings=useSidebarItem(props.api,props.interaction,{id:settingsId,position:{section:0,row:0,column:0
7021
- },activate:()=>openSettings(props.api,props.preferences,undefined,props.mcp)
7045
+ },activate:()=>openSettings(props.api,props.preferences,undefined,props.mcp,props.skills)
7022
7046
  },()=>theme().textMuted,"control")
7023
7047
  onCleanup23(()=>props.interaction.setTitleRoot(undefined))
7024
7048
  return(()=>{var _el$=_$createElement("box"),_el$2=_$createElement("box"),_el$3=_$createElement("box")
@@ -7031,7 +7055,7 @@ _$setProp(_el$2,"flexDirection","row")
7031
7055
  _$setProp(_el$2,"justifyContent","space-between")
7032
7056
  _$setProp(_el$2,"gap",1)
7033
7057
  _$setProp(_el$3,"flexGrow",1)
7034
- _$insert(_el$3,_$createComponent(Show24,{get when(){return props.preferences.showSessionTitle()
7058
+ _$insert(_el$3,_$createComponent(Show25,{get when(){return props.preferences.showSessionTitle()
7035
7059
  },get children(){var _el$4=_$createElement("text"),_el$5=_$createElement("b")
7036
7060
  _$insertNode(_el$4,_el$5)
7037
7061
  _$setProp(_el$4,"wrapMode","word")
@@ -7039,7 +7063,7 @@ _$insert(_el$5,()=>props.title)
7039
7063
  _$effect((_$p)=>_$setProp(_el$4,"fg",theme().text,_$p))
7040
7064
  return _el$4
7041
7065
  }}),null)
7042
- _$insert(_el$3,_$createComponent(Show24,{get when(){return _$memo(()=>!!props.preferences.showSessionDate())()&&created()
7066
+ _$insert(_el$3,_$createComponent(Show25,{get when(){return _$memo(()=>!!props.preferences.showSessionDate())()&&created()
7043
7067
  },children:(value)=>(()=>{var _el$6=_$createElement("text")
7044
7068
  _$insert(_el$6,value)
7045
7069
  _$effect((_$p)=>_$setProp(_el$6,"fg",theme().textMuted,_$p))
@@ -7161,6 +7185,8 @@ unsubscribe()
7161
7185
  }}}}
7162
7186
 
7163
7187
 
7188
+ var SETTINGS_COMMAND="opencode.settings"
7189
+ var PERMISSIONS_ACTION="permission.mode"
7164
7190
  function belongsTo2(renderable,ancestor){if(!renderable||!ancestor)
7165
7191
  return false
7166
7192
  for(let current=renderable;current; current=current.parent){if(current===ancestor)
@@ -7215,11 +7241,11 @@ setRevision((value)=>value + 1)
7215
7241
  return()=>{if(!layers.delete(id))
7216
7242
  return
7217
7243
  setRevision((value)=>value + 1)
7218
- }},dispatchCommand(name,options){const command=context.keymap.commands().find((candidate)=>candidate.id===name)
7244
+ }},dispatchCommand(name,options){const command=context.keymap.commands().find((candidate)=>candidate.id===(name===PERMISSIONS_ACTION?SETTINGS_COMMAND:name))
7219
7245
  if(command){if(!enabled(command.enabled))
7220
7246
  return{ok:false,reason:"disabled",command
7221
7247
  }
7222
- context.keymap.dispatch(name,typeof options?.payload==="string"?options.payload:undefined)
7248
+ context.keymap.dispatch(command.id,typeof options?.payload==="string"?options.payload:undefined)
7223
7249
  return{ok:true,command
7224
7250
  }}
7225
7251
  const fallback=legacyCommand(name)
@@ -7228,12 +7254,18 @@ return{ok:false,reason:"not-found"
7228
7254
  }
7229
7255
  run(fallback)
7230
7256
  return{ok:true,command:fallback
7231
- }},getCommands(){return context.keymap.commands().flatMap((command)=>{if(!command.id)
7257
+ }},getCommands(){const commands=context.keymap.commands()
7258
+ const result=commands.flatMap((command)=>{if(!command.id)
7232
7259
  return []
7233
7260
  const name=command.id
7234
7261
  return [{...command,name,run:()=>context.keymap.dispatch(name)
7235
7262
  }]
7236
7263
  })
7264
+ const settings=commands.find((command)=>command.id===SETTINGS_COMMAND)
7265
+ if(settings)
7266
+ result.push({...settings,id:PERMISSIONS_ACTION,name:PERMISSIONS_ACTION,title:"Permissions settings",run:()=>context.keymap.dispatch(SETTINGS_COMMAND)
7267
+ })
7268
+ return result
7237
7269
  },getCommandBindings(input){return new Map(input.commands.map((name)=>[name,[...context.keymap.shortcuts(name)]]))
7238
7270
  },parseKeySequence(value){return value.trim()?value.trim().split(/\s+/u):[]
7239
7271
  }}
@@ -7449,20 +7481,20 @@ api.lifecycle.onDispose(unsubscribeConnected)
7449
7481
  api.slots.register({order:100,slots:{app(){return _$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7450
7482
  },get multilineCorners(){return preferences.cornerFont
7451
7483
  },get children(){return [_$createComponent(PreferencesPersistence,{api,controller:preferences
7452
- }),_$createComponent(SettingsBinding,{api,preferences,mcp
7484
+ }),_$createComponent(SettingsBinding,{api,preferences,mcp,skills
7453
7485
  }),_$createComponent(SidebarToggleBinding,{api,preferences
7454
7486
  }),_$createComponent(SidebarFocusBinding,{api,preferences,interaction
7455
7487
  }),_$createComponent(SearchBinding,{api,preferences,get onNewSession(){return startup.handleNewSession
7456
7488
  },interaction,skills,subagents,mcp
7457
7489
  }),_$createComponent(FirstRunWizardPersistence,{api,preferences
7458
7490
  }),_$createComponent(StartupSessionBinding,{api,controller:startup
7459
- }),_$createComponent(UpgradeNotesBinding,{api,preferences,version:"0.18.1"
7491
+ }),_$createComponent(UpgradeNotesBinding,{api,preferences,version:"0.19.0"
7460
7492
  }),_$createComponent(McpPersistence,{api,controller:mcp
7461
7493
  })]
7462
7494
  }})
7463
7495
  },sidebar_title(_context,props){return _$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7464
7496
  },get multilineCorners(){return preferences.cornerFont
7465
- },get children(){return _$createComponent(SidebarTitle,{api,preferences,mcp,interaction,get sessionID(){return props.session_id
7497
+ },get children(){return _$createComponent(SidebarTitle,{api,preferences,mcp,skills,interaction,get sessionID(){return props.session_id
7466
7498
  },get title(){return props.title
7467
7499
  }})
7468
7500
  }})
@@ -7473,7 +7505,7 @@ api.slots.register({order:100,slots:{app(){return _$createComponent(IconProvider
7473
7505
  }})
7474
7506
  }})
7475
7507
  }}})
7476
- return{mcp,preferences
7508
+ return{mcp,skills,preferences
7477
7509
  }}
7478
7510
  var setupOpenCodeV1=async (api,options,meta)=>{const{preferences
7479
7511
  }=await setupNavigator(api,options,async ()=>{if(!api.client?.file?.read||!api.state.path.worktree)
@@ -7486,12 +7518,12 @@ throw result.error
7486
7518
  }
7487
7519
  return result.data?.type==="text"?result.data.content:undefined
7488
7520
  })
7489
- const versionStatus=createVersionStatus(api,"0.18.1")
7490
- const versionUpdates=createVersionUpdateActions(api,versionStatus,createOpenCodeV1VersionUpdater(api,meta),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.18.1"))
7521
+ const versionStatus=createVersionStatus(api,"0.19.0")
7522
+ const versionUpdates=createVersionUpdateActions(api,versionStatus,createOpenCodeV1VersionUpdater(api,meta),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.19.0"))
7491
7523
  api.slots.register({order:90,slots:{sidebar_footer(_context,props){return _$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7492
7524
  },get multilineCorners(){return preferences.cornerFont
7493
7525
  },get children(){return _$createComponent(VersionFooter,{api,get sessionID(){return props.session_id
7494
- },navigatorVersion:"0.18.1",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7526
+ },navigatorVersion:"0.19.0",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7495
7527
  },get onNavigatorUpdate(){return versionUpdates.navigator
7496
7528
  }})
7497
7529
  }})
@@ -7499,25 +7531,25 @@ api.slots.register({order:90,slots:{sidebar_footer(_context,props){return _$crea
7499
7531
  }
7500
7532
  var setupOpenCodeV2=async (context)=>{const adapter=createOpenCodeV2Api(context)
7501
7533
  const todo=createNavigatorTodoController(context,adapter.api)
7502
- const{mcp,preferences
7534
+ const{mcp,skills,preferences
7503
7535
  }=await setupNavigator(adapter.api,context.options,async ()=>{if(!context.client.file?.read)
7504
7536
  return
7505
7537
  return new TextDecoder().decode(await context.client.file.read({location:context.location,path:".opencode/navigator.json"
7506
7538
  }))
7507
7539
  },todo)
7508
- const versionStatus=createVersionStatus(adapter.api,"0.18.1")
7509
- const versionUpdates=createVersionUpdateActions(adapter.api,versionStatus,createOpenCodeV2VersionUpdater(context),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.18.1"))
7540
+ const versionStatus=createVersionStatus(adapter.api,"0.19.0")
7541
+ const versionUpdates=createVersionUpdateActions(adapter.api,versionStatus,createOpenCodeV2VersionUpdater(context),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.19.0"))
7510
7542
  const disposeFooter=context.ui.slot({append:"sidebar.footer",render:()=>_$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7511
7543
  },get multilineCorners(){return preferences.cornerFont
7512
7544
  },get children(){var _el$=_$createElement("box")
7513
7545
  _$setProp(_el$,"flexDirection","row")
7514
7546
  _$setProp(_el$,"justifyContent","space-between")
7515
7547
  _$insert(_el$,_$createComponent(VersionSummary,{get api(){return adapter.api
7516
- },navigatorVersion:"0.18.1",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7548
+ },navigatorVersion:"0.19.0",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7517
7549
  },get onNavigatorUpdate(){return versionUpdates.navigator
7518
7550
  }}),null)
7519
7551
  _$insert(_el$,_$createComponent(SettingsFooterButton,{get api(){return adapter.api
7520
- },preferences,mcp
7552
+ },preferences,mcp,skills
7521
7553
  }),null)
7522
7554
  return _el$
7523
7555
  }})
@@ -7528,5 +7560,5 @@ await adapter.dispose()
7528
7560
  var plugin={id:PLUGIN_ID,tui:setupOpenCodeV1,setup:setupOpenCodeV2
7529
7561
  }
7530
7562
  var plugin_default=plugin
7531
- export{DEFAULT_SECTION_EXPANSION,FOCUS_COMMAND,FirstRunWizard,KeyboardHelpDialog,LspBadge,McpSection,QUICK_ACTIONS,Section,SectionFilter,SettingsDialog,SidebarFocusBinding,SidebarToggleBinding,SkillsSection,createMcpController,createPreferencesController,createSidebarInteraction,createSkillController,createSubagentController,createTodoController,plugin_default as default,isEffectivelyVisible,lspIcon,matchesFilter,openFirstRunWizard,openKeyboardHelp,openSettings,showFirstRunWizard
7563
+ export{DEFAULT_SECTION_EXPANSION,DialogSurface,FOCUS_COMMAND,FirstRunWizard,KeyboardHelpDialog,LspBadge,McpSection,PresetMenu,QUICK_ACTIONS,Section,SectionFilter,SelectionBox,SettingsDialog,SidebarFocusBinding,SidebarToggleBinding,SkillsSection,createDialogStack,createMcpController,createPreferencesController,createSidebarInteraction,createSkillController,createSubagentController,createTodoController,plugin_default as default,isEffectivelyVisible,lspIcon,matchesFilter,openFirstRunWizard,openKeyboardHelp,openSettings,showFirstRunWizard,useDialogScroll,useDialogState,useDialogs,useIcons
7532
7564
  }