opencode-navigator 0.22.0 → 0.24.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
@@ -1,9 +1,9 @@
1
- import {insert as _$insert,setProp as _$setProp,createElement as _$createElement,memo as _$memo,createComponent as _$createComponent,mergeProps as _$mergeProps,effect as _$effect,createTextNode as _$createTextNode,insertNode as _$insertNode,use as _$use,spread as _$spread,useTerminalDimensions,useTerminalDimensions as useTerminalDimensions2,useTerminalDimensions as useTerminalDimensions3,useTerminalDimensions as useTerminalDimensions4,useTerminalDimensions as useTerminalDimensions5,useTerminalDimensions as useTerminalDimensions6,useTerminalDimensions as useTerminalDimensions7,useTerminalDimensions as useTerminalDimensions8,useTerminalDimensions as useTerminalDimensions9} from "@opentui/solid"
1
+ import {insert as _$insert,setProp as _$setProp,createElement as _$createElement,memo as _$memo,createComponent as _$createComponent,mergeProps as _$mergeProps,useRenderer,effect as _$effect,createTextNode as _$createTextNode,insertNode as _$insertNode,use as _$use,spread as _$spread,useTerminalDimensions,useTerminalDimensions as useTerminalDimensions2,useTerminalDimensions as useTerminalDimensions3,useTerminalDimensions as useTerminalDimensions4,useRenderer as useRenderer2,useTerminalDimensions as useTerminalDimensions5,useTerminalDimensions as useTerminalDimensions6,useTerminalDimensions as useTerminalDimensions7,useTerminalDimensions as useTerminalDimensions8,useTerminalDimensions as useTerminalDimensions9} from "@opentui/solid"
2
2
 
3
3
 
4
4
 
5
5
 
6
- 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,createEffect as createEffect4,Show,splitProps as splitProps3,Suspense,lazy,createSignal as createSignal4,createSignal as createSignal5,onCleanup as onCleanup3,Show as Show2,batch,createSignal as createSignal7,createSignal as createSignal6,createEffect as createEffect5,createSignal as createSignal8,onCleanup as onCleanup4,createSignal as createSignal9,createSignal as createSignal10,Suspense as Suspense2,lazy as lazy2,Index,onCleanup as onCleanup5,createSignal as createSignal11,onCleanup as onCleanup6,createEffect as createEffect7,onCleanup as onCleanup8,batch as batch2,createEffect as createEffect6,createMemo,createSignal as createSignal12,onCleanup as onCleanup7,onMount,For as For2,For as For3,Show as Show3,createMemo as createMemo2,Show as Show4,createSignal as createSignal13,onCleanup as onCleanup9,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 Show6,createEffect as createEffect8,createSignal as createSignal14,onCleanup as onCleanup10,Show as Show5,For as For6,For as For9,createEffect as createEffect9,createMemo as createMemo5,onCleanup as onCleanup11,createEffect as createEffect10,createMemo as createMemo6,untrack as untrack2,Suspense as Suspense3,lazy as lazy3,onCleanup as onCleanup12,createEffect as createEffect11,onCleanup as onCleanup13,createSignal as createSignal15,createMemo as createMemo7,createSignal as createSignal16,lazy as lazy4,Show as Show9,For as For10,Show as Show8,Show as Show7,createEffect as createEffect12,onCleanup as onCleanup14,onMount as onMount4,onCleanup as onCleanup15,onMount as onMount5,For as For11,createSignal as createSignal17,createSignal as createSignal18,Show as Show10,createSignal as createSignal20,createSignal as createSignal19,onCleanup as onCleanup16,For as For12,Show as Show13,createMemo as createMemo9,createComputed,createMemo as createMemo8,createSignal as createSignal21,untrack as untrack3,Show as Show11,createComputed as createComputed2,untrack as untrack4,Show as Show12,createSignal as createSignal23,createEffect as createEffect13,createSignal as createSignal22,on,createMemo as createMemo11,createSignal as createSignal26,createMemo as createMemo10,For as For13,Show as Show17,Show as Show14,Show as Show15,createSignal as createSignal24,createContext as createContext3,useContext as useContext3,Show as Show16,createSignal as createSignal25,onCleanup as onCleanup17,Show as Show23,createSignal as createSignal27,untrack as untrack5,createSignal as createSignal28,createSignal as createSignal29,createEffect as createEffect14,For as For15,Show as Show18,For as For14,Show as Show19,Show as Show20,Show as Show21,Show as Show22,For as For16,Show as Show25,createMemo as createMemo13,Show as Show24,createMemo as createMemo12,createSignal as createSignal30,createContext as createContext4,useContext as useContext4,Show as Show26,Suspense as Suspense4,createEffect as createEffect15,onCleanup as onCleanup18,untrack as untrack6,For as For22,Match,Switch,createMemo as createMemo19,onCleanup as onCleanup24,For as For17,Show as Show27,createMemo as createMemo15,createSignal as createSignal32,createEffect as createEffect16,createMemo as createMemo14,onCleanup as onCleanup19,untrack as untrack7,createEffect as createEffect17,createSignal as createSignal31,onCleanup as onCleanup20,For as For18,Show as Show29,createSignal as createSignal33,createEffect as createEffect18,createMemo as createMemo16,onCleanup as onCleanup21,untrack as untrack8,Show as Show28,For as For20,Show as Show32,createEffect as createEffect19,createMemo as createMemo17,createSignal as createSignal34,onCleanup as onCleanup22,untrack as untrack9,For as For19,Show as Show31,Show as Show30,Show as Show36,createEffect as createEffect20,createMemo as createMemo18,createSignal as createSignal35,onCleanup as onCleanup23,untrack as untrack10,For as For21,Show as Show34,Show as Show33,Show as Show35,createEffect as createEffect21,createMemo as createMemo20,onCleanup as onCleanup25,untrack as untrack11,Show as Show37,createMemo as createMemo21,onCleanup as onCleanup26,createEffect as createEffect22,createMemo as createMemo22,on as on2,onCleanup as onCleanup27,createSignal as createSignal36,onCleanup as onCleanup28,onMount as onMount6} from "solid-js"
6
+ import {createSignal as createSignal2,createSignal,createEffect,onCleanup,createContext,useContext,createContext as createContext2,createSignal as createSignal3,onCleanup as onCleanup2,useContext as useContext2,createEffect as createEffect2,splitProps,untrack,splitProps as splitProps2,For,createEffect as createEffect3,onCleanup as onCleanup3,Show,createEffect as createEffect4,Show as Show2,splitProps as splitProps3,createEffect as createEffect5,createSignal as createSignal4,onCleanup as onCleanup4,onMount,Suspense,lazy,createSignal as createSignal5,createSignal as createSignal6,onCleanup as onCleanup5,Show as Show3,batch,createSignal as createSignal8,createSignal as createSignal7,createEffect as createEffect6,createSignal as createSignal9,onCleanup as onCleanup6,createSignal as createSignal10,createSignal as createSignal11,Suspense as Suspense2,lazy as lazy2,Index,onCleanup as onCleanup7,createSignal as createSignal12,onCleanup as onCleanup8,createEffect as createEffect8,onCleanup as onCleanup10,batch as batch2,createEffect as createEffect7,createMemo,createSignal as createSignal13,onCleanup as onCleanup9,onMount as onMount2,For as For2,For as For3,Show as Show4,createMemo as createMemo2,Show as Show5,createSignal as createSignal14,onCleanup as onCleanup11,For as For4,For as For5,For as For8,createMemo as createMemo4,onMount as onMount4,For as For7,createMemo as createMemo3,onMount as onMount3,Show as Show7,createEffect as createEffect9,createSignal as createSignal15,onCleanup as onCleanup12,Show as Show6,For as For6,For as For9,createEffect as createEffect10,createMemo as createMemo5,onCleanup as onCleanup13,createEffect as createEffect11,createMemo as createMemo6,untrack as untrack2,Suspense as Suspense3,lazy as lazy3,onCleanup as onCleanup14,createEffect as createEffect12,onCleanup as onCleanup15,createSignal as createSignal16,createMemo as createMemo7,createSignal as createSignal17,createSignal as createSignal18,lazy as lazy4,Show as Show10,For as For10,Show as Show9,Show as Show8,createEffect as createEffect13,onCleanup as onCleanup16,onMount as onMount5,onCleanup as onCleanup17,onMount as onMount6,For as For11,createSignal as createSignal19,createSignal as createSignal20,onCleanup as onCleanup18,createSignal as createSignal21,Show as Show11,createSignal as createSignal23,createSignal as createSignal22,onCleanup as onCleanup19,For as For12,Show as Show14,createMemo as createMemo9,createComputed,createMemo as createMemo8,createSignal as createSignal24,untrack as untrack3,Show as Show12,createComputed as createComputed2,untrack as untrack4,Show as Show13,createSignal as createSignal26,createEffect as createEffect14,createSignal as createSignal25,on,createMemo as createMemo11,createSignal as createSignal29,createMemo as createMemo10,For as For13,Show as Show18,Show as Show15,Show as Show16,createSignal as createSignal27,createContext as createContext3,useContext as useContext3,Show as Show17,createSignal as createSignal28,onCleanup as onCleanup20,Show as Show24,createSignal as createSignal30,untrack as untrack5,createSignal as createSignal31,createSignal as createSignal32,createEffect as createEffect15,For as For15,Show as Show19,For as For14,createSignal as createSignal33,Show as Show20,Show as Show21,Show as Show22,Show as Show23,For as For16,Show as Show26,createMemo as createMemo13,Show as Show25,createMemo as createMemo12,createSignal as createSignal34,createContext as createContext4,useContext as useContext4,Show as Show27,Suspense as Suspense4,createEffect as createEffect16,onCleanup as onCleanup21,untrack as untrack6,For as For22,Match,Switch,createMemo as createMemo19,onCleanup as onCleanup27,For as For17,Show as Show29,createMemo as createMemo15,createSignal as createSignal36,createEffect as createEffect17,createMemo as createMemo14,onCleanup as onCleanup22,untrack as untrack7,Show as Show28,createEffect as createEffect18,createSignal as createSignal35,onCleanup as onCleanup23,For as For18,Show as Show31,createSignal as createSignal37,createEffect as createEffect19,createMemo as createMemo16,onCleanup as onCleanup24,untrack as untrack8,Show as Show30,For as For20,Show as Show34,createEffect as createEffect20,createMemo as createMemo17,createSignal as createSignal38,onCleanup as onCleanup25,untrack as untrack9,For as For19,Show as Show33,Show as Show32,Show as Show38,createEffect as createEffect21,createMemo as createMemo18,createSignal as createSignal39,onCleanup as onCleanup26,untrack as untrack10,For as For21,Show as Show36,Show as Show35,Show as Show37,createEffect as createEffect22,createMemo as createMemo20,onCleanup as onCleanup28,untrack as untrack11,Show as Show39,createMemo as createMemo21,onCleanup as onCleanup29,createEffect as createEffect23,createMemo as createMemo22,on as on2,onCleanup as onCleanup30,createRoot,createSignal as createSignal40,getOwner,createSignal as createSignal41,onCleanup as onCleanup31,onMount as onMount7} from "solid-js"
7
7
  var SIDEBAR_SECTIONS=["limits","todo","subagents","skills","quick_actions","lsp","mcp"]
8
8
  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"]
9
9
  function preferencesScope(path){return path.worktree||path.directory||"global"
@@ -230,7 +230,7 @@ return
230
230
  const error=status.error
231
231
  return typeof error==="string"?error:undefined
232
232
  }
233
- function createMcpController(api,persist,preferences){const [snapshots,setSnapshots]=createSignal2({})
233
+ function createMcpController(api,persist,preferences,source){const [snapshots,setSnapshots]=createSignal2({})
234
234
  const [mutationCounts,setMutationCounts]=createSignal2({})
235
235
  const [bulkStates,setBulkStates]=createSignal2({})
236
236
  const [selectedPresets,setSelectedPresets]=createSignal2({})
@@ -303,7 +303,7 @@ const failed=state.failed.filter((candidate)=>candidate!==name)
303
303
  bulkRetries.set(current.key,(bulkRetries.get(current.key)??[]).filter((candidate)=>candidate.name!==name))
304
304
  return{...values,[current.key]:{...state,status:failed.length>0?"error":"ready",failed}}})
305
305
  }
306
- function list(current=target()){return snapshots()[current.key]??api.state.mcp()
306
+ function list(current=target()){return source?source.list(current):snapshots()[current.key]??api.state.mcp()
307
307
  }
308
308
  async function refresh(current=target(),force=false){const pending=refreshing.get(current.key)
309
309
  if(pending&&!force)
@@ -311,8 +311,7 @@ return pending
311
311
  const requestState=requests.start(current.key,"refresh MCP servers",current.key in snapshots(),force)
312
312
  if(!requestState)
313
313
  return pending
314
- const request=api.client.mcp.status(current.routing,{throwOnError:true,signal:requestState.signal}).then((result)=>{const items=Object.entries(result.data??{}).map(([name,status])=>({name,status:status.status,error:statusError(status)})).sort((a,b)=>a.name.localeCompare(b.name))
315
- if(requestState.isCurrent())
314
+ const request=(source?source.refresh(current,force,requestState.signal):api.client.mcp.status(current.routing,{throwOnError:true,signal:requestState.signal}).then((result)=>Object.entries(result.data??{}).map(([name,status])=>({name,status:status.status,error:statusError(status)})).sort((a,b)=>a.name.localeCompare(b.name)))).then((items)=>{if(!source&&requestState.isCurrent())
316
315
  setSnapshots((value)=>({...value,[current.key]:items}))
317
316
  if(requestState.isCurrent())
318
317
  reconcileSelectedPreset(current,items)
@@ -501,7 +500,7 @@ return changeMany({action:state.action,...state.preset&&{preset:state.preset},..
501
500
 
502
501
 
503
502
 
504
- var ICONS={limits:["\uDB80\uDE9A","%"],todo:["\uEAB3","[T]"],subagents:["\uEA7E","[A]"],skills:["\uEAA4","[S]"],actions:["\uEB9E","[Q]"],lsp:["\uEAC4","{}"],mcp:["\uEB2D","[M]"],sections:["\uEBEB","[]"],scope:["\uEB01","@"],presets:["\uEBD2","#"],settings:["\uEAF8","[=]"],reset:["\uEB37","R"],save:["\uEB4B","S"],add:["\uEA60","+"],edit:["\uEA73","[R]"],history:["\uEA82","[T]"],copy:["\uEBCC","[C]"],export:["\uEBAC","[E]"],compact:["\uEAF5","[-]"],checked:["\uEBB3","[x]"],unchecked:["\uEBB5","[ ]"],selected:["\uEAB6",">"],expanded:["\uEAB4","v"],collapsed:["\uEAB6",">"],radioOn:["\uEA71","(*)"],radioOff:["\uEABC","( )"],done:["\uEAB2","v"],busy:["\uEA71","*"],idle:["\uEABC","-"],close:["\uEA76","x"],error:["\uEA87","!"],retry:["\uEA77","~"],pending:["\uDB86\uDD78","..."],connected:["\uDB81\uDC3E","(*)"],disconnected:["\uDB81\uDC3D","( )"],favorite:["\uEB59","*"],favoriteEmpty:["\uEA6A","+"],bookmark:["\uDB80\uDCC0","*"],bookmarkEmpty:["\uDB80\uDCC3","+"],mcpFavorite:["\uDB80\uDCC0","*"],mcpFavoriteEmpty:["\uDB80\uDCC3","+"],recent:["\uEA82","~"],info:["\uEA74","i"],search:["\uEA6D","/"],update:["\uDB80\uDC5F","^"],up:["\uEAA1","^"],down:["\uEA9A","v"],left:["\uEA9B","<"],right:["\uEA9C",">"],keyEnter:["\uEBEA","enter"],keyTab:["\uDB80\uDF12","tab"],keyEscape:["\uDB84\uDEB7","esc"],keySpace:["\uDB84\uDC50","space"],delete:["\uEA81","del"],priorityMedium:["\uEA71","-"],help:["\uEB32","?"],selectionLeft:["\uE0B6"," "],selectionRight:["\uE0B4"," "],selectionTopLeft:["\uDBFC\uDC04"," "],selectionTopRight:["\uDBFC\uDC05"," "],selectionBottomLeft:["\uDBFC\uDC06"," "],selectionBottomRight:["\uDBFC\uDC07"," "]
503
+ var ICONS={limits:["\uDB80\uDE9A","%"],todo:["\uEAB3","[T]"],subagents:["\uEA7E","[A]"],skills:["\uEAA4","[S]"],actions:["\uEB9E","[Q]"],lsp:["\uEAC4","{}"],mcp:["\uEB2D","[M]"],sections:["\uEBEB","[]"],scope:["\uEB01","@"],presets:["\uEBD2","#"],settings:["\uEAF8","[=]"],reset:["\uEB37","R"],save:["\uEB4B","S"],add:["\uEA60","+"],edit:["\uEA73","[R]"],history:["\uEA82","[T]"],copy:["\uEBCC","[C]"],export:["\uEBAC","[E]"],compact:["\uEAF5","[-]"],checked:["\uEBB3","[x]"],unchecked:["\uEBB5","[ ]"],selected:["\uEAB6",">"],expanded:["\uEAB4","v"],collapsed:["\uEAB6",">"],radioOn:["\uEA71","(*)"],radioOff:["\uEABC","( )"],done:["\uEAB2","v"],busy:["\uEA71","*"],idle:["\uEABC","-"],close:["\uEA76","x"],error:["\uEA87","!"],retry:["\uEA77","~"],pending:["\uDB86\uDD78","..."],connected:["\uDB81\uDC3E","(*)"],disconnected:["\uDB81\uDC3D","( )"],favorite:["\uEB59","*"],favoriteEmpty:["\uEA6A","+"],bookmark:["\uDB80\uDCC0","*"],bookmarkEmpty:["\uDB80\uDCC3","+"],mcpFavorite:["\uDB80\uDCC0","*"],mcpFavoriteEmpty:["\uDB80\uDCC3","+"],recent:["\uEA82","~"],info:["\uEA74","i"],bug:["\uEAAF","b"],search:["\uEA6D","/"],update:["\uDB80\uDC5F","^"],up:["\uEAA1","^"],down:["\uEA9A","v"],left:["\uEA9B","<"],right:["\uEA9C",">"],keyEnter:["\uEBEA","enter"],keyTab:["\uDB80\uDF12","tab"],keyEscape:["\uDB84\uDEB7","esc"],keySpace:["\uDB84\uDC50","space"],delete:["\uEA81","del"],priorityMedium:["\uEA71","-"],help:["\uEB32","?"],selectionLeft:["\uE0B6"," "],selectionRight:["\uE0B4"," "],selectionTopLeft:["\uDBFC\uDC04"," "],selectionTopRight:["\uDBFC\uDC05"," "],selectionBottomLeft:["\uDBFC\uDC06"," "],selectionBottomRight:["\uDBFC\uDC07"," "]
505
504
  }
506
505
  function uiIcon(name,style="nerd"){return ICONS[name][style==="text"?1:0]
507
506
  }
@@ -515,7 +514,7 @@ return icon?uiIcon(icon,style):key
515
514
  }
516
515
  function sectionIcon(section,style="nerd"){return uiIcon(section==="quick_actions"?"actions":section,style)
517
516
  }
518
- var SETTINGS_ICONS={sections:"sections",scope:"scope",presets:"presets",behavior:"settings",defaults:"reset"
517
+ var SETTINGS_ICONS={sections:"sections",scope:"scope",presets:"presets",behavior:"settings",defaults:"reset",about:"info"
519
518
  }
520
519
  function settingsTabIcon(tab,style="nerd"){return uiIcon(SETTINGS_ICONS[tab],style)
521
520
  }
@@ -684,6 +683,7 @@ return _$createComponent(DialogContext.Provider,{get value(){return props.scope
684
683
  }})
685
684
  }
686
685
 
686
+
687
687
  function useDialogs(api){const scope=useContext2(DialogContext)
688
688
  const icons=useIcons()
689
689
  if(scope?.api===api)
@@ -700,17 +700,31 @@ const state=createSignal3(initial)
700
700
  scope.frame.state.set(key,state)
701
701
  return state
702
702
  }
703
- function useDialogScroll(key="scroll"){const [position,setPosition]=useDialogState(key,0)
703
+ function useDialogScroll(key="scroll"){const renderer=useRenderer()
704
+ const [position,setPosition]=useDialogState(key,0)
704
705
  let body
705
706
  let isPending=true
706
- return{ref(node){body=node
707
- },restore(){if(!isPending||!body)
707
+ function restore(){if(!isPending||!body||body.isDestroyed)
708
+ return
709
+ if(position()>0&&body.scrollHeight===0)
708
710
  return
709
711
  isPending=false
710
712
  body.scrollTo(position())
711
- },save(){if(body&&!body.isDestroyed)
713
+ }
714
+ function save(){if(!isPending&&body&&!body.isDestroyed)
712
715
  setPosition(body.scrollTop)
713
- }}}
716
+ }
717
+ const frame=()=>{restore()
718
+ save()
719
+ }
720
+ renderer.on("frame",frame)
721
+ onCleanup2(()=>{save()
722
+ renderer.off("frame",frame)
723
+ })
724
+ return{ref(node){body=node
725
+ renderer.requestRender()
726
+ },restore,save
727
+ }}
714
728
 
715
729
 
716
730
 
@@ -724,40 +738,36 @@ setPosition(body.scrollTop)
724
738
 
725
739
 
726
740
 
727
- import {BoxRenderable,RGBA,TextAttributes,TextAttributes as TextAttributes2,TextAttributes as TextAttributes3,RGBA as RGBA2,parseColor,TextAttributes as TextAttributes4,TextAttributes as TextAttributes5,TextAttributes as TextAttributes6,TextAttributes as TextAttributes7,RGBA as RGBA3,parseColor as parseColor2,TextAttributes as TextAttributes8,TextAttributes as TextAttributes9,TextAttributes as TextAttributes12,TextAttributes as TextAttributes10,TextAttributes as TextAttributes11,TextAttributes as TextAttributes13,TextAttributes as TextAttributes14,TextAttributes as TextAttributes16,TextAttributes as TextAttributes15,TextAttributes as TextAttributes17,ScrollBoxRenderable,TextAttributes as TextAttributes18} from "@opentui/core"
741
+ import {RGBA,TextAttributes,TextAttributes as TextAttributes2,TextAttributes as TextAttributes3,RGBA as RGBA2,parseColor,TextAttributes as TextAttributes4,TextAttributes as TextAttributes5,TextAttributes as TextAttributes6,TextAttributes as TextAttributes7,RGBA as RGBA3,parseColor as parseColor2,TextAttributes as TextAttributes8,TextAttributes as TextAttributes9,TextAttributes as TextAttributes12,TextAttributes as TextAttributes10,TextAttributes as TextAttributes11,TextAttributes as TextAttributes13,TextAttributes as TextAttributes14,TextAttributes as TextAttributes16,TextAttributes as TextAttributes15,TextAttributes as TextAttributes17,ScrollBoxRenderable,TextAttributes as TextAttributes18} from "@opentui/core"
728
742
 
729
- function selectionBackdrop(node){for(let parent=node.parent;parent; parent=parent.parent){if(parent instanceof BoxRenderable&&parent.backgroundColor.a>0)
743
+ var transparent=RGBA.fromInts(0,0,0,0)
744
+ function selectionBackdrop(node){for(let parent=node.parent;parent; parent=parent.parent){if("backgroundColor" in parent&&parent.backgroundColor instanceof RGBA&&parent.backgroundColor.a>0&&(!("shouldFill" in parent)||parent.shouldFill!==false))
730
745
  return parent.backgroundColor
731
746
  }
732
- return RGBA.fromValues(0,0,0,1)
747
+ return transparent
733
748
  }
749
+ function paintCorners(node,buffer,icons){const backdrop=selectionBackdrop(node)
750
+ if(node.backgroundColor.equals(backdrop))
751
+ return
752
+ const left=node.screenX
753
+ const right=left + node.width-1
754
+ const top=node.screenY
755
+ const bottom=top + node.height-1
756
+ const multiline=node.height>1
757
+ const positions=multiline?[[left,top,"selectionTopLeft"],[right,top,"selectionTopRight"],[left,bottom,"selectionBottomLeft"],[right,bottom,"selectionBottomRight"]]:[[left,top,"selectionLeft"],[right,top,"selectionRight"]]
758
+ for(const [x,y,icon] of positions){if(x<0||y<0||x>=buffer.width||y>=buffer.height)
759
+ continue
760
+ buffer.setCell(x,y,icons.icon(icon),multiline?backdrop:node.backgroundColor,multiline?node.backgroundColor:backdrop)
761
+ }}
734
762
  function SelectionBox(props){const icons=useIcons()
735
763
  const [local,boxProps]=splitProps(props,["ref","iconOnly"])
736
764
  let node
737
- let corners=[]
738
765
  createEffect2(()=>{icons.style()
739
766
  icons.multilineCorners()
740
767
  node?.requestRender()
741
768
  })
742
- function before(buffer,delta){props.renderBefore?.call(this,buffer,delta)
743
- corners=[]
744
- if(this.buffered||this.width<3||this.height<1||this.backgroundColor.a===0||this.height>1&&!icons.multilineCorners())
745
- return
746
- const left=this.screenX
747
- const right=left + this.width-1
748
- const top=this.screenY
749
- const bottom=top + this.height-1
750
- const positions=this.height===1?[[left,top,"selectionLeft"],[right,top,"selectionRight"]]:[[left,top,"selectionTopLeft"],[right,top,"selectionTopRight"],[left,bottom,"selectionBottomLeft"],[right,bottom,"selectionBottomRight"]]
751
- const backdrop=selectionBackdrop(this)
752
- for(const [x,y,icon] of positions){if(x<0||y<0||x>=buffer.width||y>=buffer.height)
753
- continue
754
- if(!this.backgroundColor.equals(backdrop))
755
- corners.push({x,y,icon,backdrop
756
- })
757
- }}
758
- function after(buffer,delta){for(const corner of corners){const multiline=this.height>1
759
- buffer.setCell(corner.x,corner.y,icons.icon(corner.icon),multiline?corner.backdrop:this.backgroundColor,multiline?this.backgroundColor:corner.backdrop)
760
- }
769
+ function after(buffer,delta){if(!this.buffered&&this.width>=3&&this.height>=1&&this.backgroundColor.a>0&&(this.height===1||icons.multilineCorners()))
770
+ paintCorners(this,buffer,icons)
761
771
  props.renderAfter?.call(this,buffer,delta)
762
772
  }
763
773
  return(()=>{var _el$=_$createElement("box")
@@ -768,7 +778,6 @@ local.ref(value)
768
778
  },_el$)
769
779
  _$spread(_el$,_$mergeProps(boxProps,{get paddingLeft(){return props.paddingLeft??props.padding??(local.iconOnly&&icons.style()==="text"?0:1)
770
780
  },get paddingRight(){return props.paddingRight??props.padding??(local.iconOnly&&icons.style()==="text"?0:1)
771
- },get renderBefore(){return _$memo(()=>icons.style()==="nerd")()?before:props.renderBefore
772
781
  },get renderAfter(){return _$memo(()=>icons.style()==="nerd")()?after:props.renderAfter
773
782
  }}),false)
774
783
  return _el$
@@ -809,7 +818,7 @@ _$setProp(_el$2,"wrapMode","none")
809
818
  _$setProp(_el$2,"truncate",true)
810
819
  _$setProp(_el$2,"height",1)
811
820
  _$setProp(_el$2,"flexGrow",1)
812
- _$insert(_el$2,()=>icons.icon("presets"),_el$3)
821
+ _$insert(_el$2,()=>icons.icon(props.icon??"presets"),_el$3)
813
822
  _$insert(_el$2,()=>props.title,null)
814
823
  _$setProp(_el$4,"flexShrink",0)
815
824
  _$setProp(_el$4,"onMouseUp",(event)=>{event.stopPropagation()
@@ -951,7 +960,7 @@ const unregister=props.api.keymap.registerLayer({mode:"modal",priority:1000,comm
951
960
  },{key:"space",cmd:`${prefix}.select`
952
961
  }]
953
962
  })
954
- onCleanup2(unregister)
963
+ onCleanup3(unregister)
955
964
  return _$createComponent(DialogSurface,{get api(){return props.api
956
965
  },get lift(){return props.lift
957
966
  },get children(){return [(()=>{var _el$=_$createElement("box"),_el$2=_$createElement("text"),_el$3=_$createTextNode(` `),_el$4=_$createElement("text")
@@ -991,9 +1000,9 @@ _$insert(_el$1,(()=>{var _c$=_$memo(()=>!!option.icon)
991
1000
  return()=>_c$()?`${icons.icon(option.icon)} `:""
992
1001
  })(),null)
993
1002
  _$insert(_el$1,()=>option.title,null)
994
- _$effect((_p$)=>{var _v$8=active()===index()?TextAttributes2.BOLD:undefined,_v$9=theme().text
995
- _v$8!==_p$.e&&(_p$.e=_$setProp(_el$1,"attributes",_v$8,_p$.e))
996
- _v$9!==_p$.t&&(_p$.t=_$setProp(_el$1,"fg",_v$9,_p$.t))
1003
+ _$effect((_p$)=>{var _v$5=active()===index()?TextAttributes2.BOLD:undefined,_v$6=theme().text
1004
+ _v$5!==_p$.e&&(_p$.e=_$setProp(_el$1,"attributes",_v$5,_p$.e))
1005
+ _v$6!==_p$.t&&(_p$.t=_$setProp(_el$1,"fg",_v$6,_p$.t))
997
1006
  return _p$
998
1007
  },{e:undefined,t:undefined
999
1008
  })
@@ -1006,13 +1015,7 @@ return _el$10
1006
1015
  })()]
1007
1016
  }})
1008
1017
  }))
1009
- _$effect((_p$)=>{var{restore:_v$5,save:_v$6}=scroll,_v$7=props.adaptive?Math.min(props.height??Math.min(props.options.length*3,15),Math.max(2,Math.floor(dimensions().height*0.75)-8)):props.height??Math.min(props.options.length*3,15)
1010
- _v$5!==_p$.e&&(_p$.e=_$setProp(_el$5,"renderBefore",_v$5,_p$.e))
1011
- _v$6!==_p$.t&&(_p$.t=_$setProp(_el$5,"renderAfter",_v$6,_p$.t))
1012
- _v$7!==_p$.a&&(_p$.a=_$setProp(_el$5,"height",_v$7,_p$.a))
1013
- return _p$
1014
- },{e:undefined,t:undefined,a:undefined
1015
- })
1018
+ _$effect((_$p)=>_$setProp(_el$5,"height",props.adaptive?Math.min(props.height??Math.min(props.options.length*3,15),Math.max(2,Math.floor(dimensions().height*0.75)-8)):props.height??Math.min(props.options.length*3,15),_$p))
1016
1019
  return _el$5
1017
1020
  })(),(()=>{var _el$7=_$createElement("text"),_el$8=_$createTextNode(` navigate \xB7 `),_el$9=_$createTextNode(` select \xB7 `),_el$0=_$createTextNode(` close`)
1018
1021
  _$insertNode(_el$7,_el$8)
@@ -1032,12 +1035,17 @@ function GuardedConfirmation(props){const dialogs=useDialogs(props.api)
1032
1035
  createEffect4(()=>{if(!props.current())
1033
1036
  dialogs.close()
1034
1037
  })
1035
- return _$createComponent(props.api.ui.DialogConfirm,{get title(){return props.title
1036
- },get message(){return props.message
1037
- },onConfirm:()=>{if(props.current())
1038
+ const confirm=()=>{if(props.current())
1038
1039
  props.onConfirm()
1039
- },get onCancel(){return dialogs.back
1040
+ }
1041
+ return _$createComponent(Show,{get when(){return props.render
1042
+ },get fallback(){return _$createComponent(props.api.ui.DialogConfirm,{get title(){return props.title
1043
+ },get message(){return props.message
1044
+ },onConfirm:confirm,get onCancel(){return dialogs.back
1040
1045
  }})
1046
+ },children:(render)=>render()({confirm,cancel:dialogs.back
1047
+ })
1048
+ })
1041
1049
  }
1042
1050
 
1043
1051
 
@@ -1063,7 +1071,7 @@ _$setProp(_el$2,"wrapMode","none")
1063
1071
  _$setProp(_el$2,"truncate",true)
1064
1072
  _$setProp(_el$2,"height",1)
1065
1073
  _$insert(_el$2,()=>local.children)
1066
- _$insert(_el$,_$createComponent(Show,{get when(){return local.count!==undefined
1074
+ _$insert(_el$,_$createComponent(Show2,{get when(){return local.count!==undefined
1067
1075
  },get children(){var _el$3=_$createElement("text")
1068
1076
  _$setProp(_el$3,"flexShrink",0)
1069
1077
  _$setProp(_el$3,"wrapMode","none")
@@ -1087,6 +1095,85 @@ return _el$
1087
1095
  }}))
1088
1096
  }
1089
1097
 
1098
+
1099
+
1100
+
1101
+
1102
+
1103
+
1104
+
1105
+ function SingleLinePrompt(props){const theme=()=>props.api.theme.current
1106
+ const [value,setValue]=useDialogState("prompt-value",props.value??"")
1107
+ const [active,setActive]=useDialogState("prompt-control",0)
1108
+ const [hovered,setHovered]=createSignal4()
1109
+ let input
1110
+ let actions
1111
+ const confirm=()=>props.onConfirm?.(value())
1112
+ const cancel=()=>props.onCancel?.()
1113
+ const focus=(index)=>{setActive(index)
1114
+ setHovered(undefined)
1115
+ if(index===0)
1116
+ input?.focus()
1117
+ else
1118
+ actions?.focus()
1119
+ }
1120
+ const prefix="opencode-navigator.prompt"
1121
+ createEffect5(()=>{const actionsFocused=active()>0
1122
+ const unregister=props.api.keymap.registerLayer({mode:"modal",priority:1100,commands:[{name:`${prefix}.next`,run:()=>focus((active() + 1)%3)
1123
+ },{name:`${prefix}.previous`,run:()=>focus((active() + 2)%3)
1124
+ },{name:`${prefix}.activate`,run:()=>active()===2?cancel():confirm()
1125
+ },{name:`${prefix}.horizontal`,enabled:()=>active()>0,run:()=>focus(active()===1?2:1)
1126
+ }],bindings:[{key:"tab",cmd:`${prefix}.next`
1127
+ },{key:"shift+tab",cmd:`${prefix}.previous`
1128
+ },{key:"return",cmd:`${prefix}.activate`
1129
+ },...actionsFocused?[{key:"left",cmd:`${prefix}.horizontal`
1130
+ },{key:"right",cmd:`${prefix}.horizontal`
1131
+ }]:[]]
1132
+ })
1133
+ onCleanup4(unregister)
1134
+ })
1135
+ onMount(()=>queueMicrotask(()=>input?.focus()))
1136
+ return _$createComponent(DialogSurface,{get api(){return props.api
1137
+ },get children(){return [_$createComponent(DialogHeader,{get api(){return props.api
1138
+ },get title(){return props.title
1139
+ },onBack:cancel
1140
+ }),_$memo(()=>props.description?.()),(()=>{var _el$=_$createElement("input")
1141
+ _$use((node)=>{input=node
1142
+ },_el$)
1143
+ _$setProp(_el$,"onInput",setValue)
1144
+ _$setProp(_el$,"on:focused",()=>setActive(0))
1145
+ _$effect((_p$)=>{var _v$=value(),_v$2=props.placeholder,_v$3=theme().text,_v$4=theme().text,_v$5=theme().backgroundPanel,_v$6=theme().backgroundElement,_v$7=theme().primary,_v$8=theme().textMuted
1146
+ _v$!==_p$.e&&(_p$.e=_$setProp(_el$,"value",_v$,_p$.e))
1147
+ _v$2!==_p$.t&&(_p$.t=_$setProp(_el$,"placeholder",_v$2,_p$.t))
1148
+ _v$3!==_p$.a&&(_p$.a=_$setProp(_el$,"textColor",_v$3,_p$.a))
1149
+ _v$4!==_p$.o&&(_p$.o=_$setProp(_el$,"focusedTextColor",_v$4,_p$.o))
1150
+ _v$5!==_p$.i&&(_p$.i=_$setProp(_el$,"backgroundColor",_v$5,_p$.i))
1151
+ _v$6!==_p$.n&&(_p$.n=_$setProp(_el$,"focusedBackgroundColor",_v$6,_p$.n))
1152
+ _v$7!==_p$.s&&(_p$.s=_$setProp(_el$,"cursorColor",_v$7,_p$.s))
1153
+ _v$8!==_p$.h&&(_p$.h=_$setProp(_el$,"placeholderColor",_v$8,_p$.h))
1154
+ return _p$
1155
+ },{e:undefined,t:undefined,a:undefined,o:undefined,i:undefined,n:undefined,s:undefined,h:undefined
1156
+ })
1157
+ return _el$
1158
+ })(),(()=>{var _el$2=_$createElement("box")
1159
+ _$use((node)=>{actions=node
1160
+ },_el$2)
1161
+ _$setProp(_el$2,"flexDirection","row")
1162
+ _$setProp(_el$2,"gap",1)
1163
+ _$setProp(_el$2,"focusable",true)
1164
+ _$insert(_el$2,_$createComponent(DialogAction,{get api(){return props.api
1165
+ },id:`${prefix}.save`,label:"Save",icon:"save",get selected(){return(hovered()??active())===1
1166
+ },onSelect:()=>setHovered(1),onActivate:confirm
1167
+ }),null)
1168
+ _$insert(_el$2,_$createComponent(DialogAction,{get api(){return props.api
1169
+ },id:`${prefix}.cancel`,label:"Cancel",icon:"close",get selected(){return(hovered()??active())===2
1170
+ },onSelect:()=>setHovered(2),onActivate:cancel
1171
+ }),null)
1172
+ return _el$2
1173
+ })()]
1174
+ }})
1175
+ }
1176
+
1090
1177
  function subtleLineColor(background,border){const from=parseColor(background)
1091
1178
  const to=parseColor(border)
1092
1179
  return RGBA2.fromValues(from.r + (to.r-from.r)*0.45,from.g + (to.g-from.g)*0.45,from.b + (to.b-from.b)*0.45)
@@ -1247,13 +1334,34 @@ function toolbarPinKey(pin){return pin.kind==="action"?`action:${pin.id}`:`skill
1247
1334
  }
1248
1335
  function identifier(value){return typeof value==="string"&&/^[a-z][a-z\d-]{0,47}$/u.test(value)
1249
1336
  }
1337
+ function iconList(value){return Array.isArray(value)&&value.length<=3&&value.every((item)=>identifier(item))
1338
+ }
1339
+ function validToolbarPinText(text){return text.length<=128&&[...text].every((character)=>{const point=character.codePointAt(0)??0
1340
+ return point>=32&&point!==127&&point!==8232&&point!==8233
1341
+ })
1342
+ }
1343
+ function toolbarPinIcons(pin,state){if(state&&pin.stateIconLists?.[state])
1344
+ return pin.stateIconLists[state]
1345
+ if(state&&pin.stateIcons?.[state])
1346
+ return [pin.stateIcons[state]]
1347
+ return pin.icons??[pin.icon]
1348
+ }
1250
1349
  function parsePin(value){if(!value||typeof value!=="object")
1251
1350
  return
1252
1351
  const input=value
1253
1352
  if(!identifier(input.icon))
1254
1353
  return
1354
+ if(input.icons!==undefined&&!iconList(input.icons))
1355
+ return
1356
+ const text=typeof input.text==="string"?input.text.trim():""
1357
+ if(!validToolbarPinText(text))
1358
+ return
1255
1359
  const stateIcons=Object.fromEntries(Object.entries(input.stateIcons&&typeof input.stateIcons==="object"?input.stateIcons:{}).filter(([key,icon])=>identifier(key)&&identifier(icon)))
1256
- const icons={icon:input.icon,...Object.keys(stateIcons).length>0&&{stateIcons}}
1360
+ const stateIconLists=Object.fromEntries(Object.entries(input.stateIconLists&&typeof input.stateIconLists==="object"?input.stateIconLists:{}).filter(([key,entry])=>identifier(key)&&iconList(entry)))
1361
+ const base=input.icons
1362
+ if(!text&&(base?.length===0||Object.values(stateIconLists).some((list)=>list.length===0)))
1363
+ return
1364
+ const icons={icon:input.icon,...base&&{icons:[...base]},...text&&{text},...Object.keys(stateIcons).length>0&&{stateIcons},...Object.keys(stateIconLists).length>0&&{stateIconLists}}
1257
1365
  if(input.kind==="action"&&QUICK_ACTION_IDS.includes(input.id))
1258
1366
  return{kind:"action",id:input.id,...icons}
1259
1367
  if(input.kind==="skill"&&typeof input.location==="string"&&input.location.trim()&&typeof input.name==="string"&&input.name.trim())
@@ -1270,6 +1378,31 @@ keys.add(toolbarPinKey(pin))
1270
1378
  return [pin]
1271
1379
  })
1272
1380
  }
1381
+ function configurePin(current,change){if(change.expected&&change.expected!==JSON.stringify(current))
1382
+ throw new Error("Pin changed; reopen its configuration")
1383
+ const stateIcons={...current.stateIcons}
1384
+ const stateIconLists={...current.stateIconLists}
1385
+ const lists=Object.entries(change.stateIconLists??{})
1386
+ for(const [state,values] of lists){if(!identifier(state)||values!==null&&!iconList(values))
1387
+ throw new Error("Choose zero to three state icons")
1388
+ if(values===null)
1389
+ delete stateIconLists[state]
1390
+ else
1391
+ stateIconLists[state]=[...values]
1392
+ }
1393
+ const changes=Object.entries(change.stateIcons??{})
1394
+ for(const [state,icon] of changes){if(!identifier(state)||icon!==null&&!identifier(icon))
1395
+ throw new Error("Invalid state icon")
1396
+ if(icon===null)
1397
+ delete stateIcons[state]
1398
+ else
1399
+ stateIcons[state]=icon
1400
+ }
1401
+ const pin=parsePin({...current,icon:change.icon,stateIcons,stateIconLists,...change.icons!==undefined&&{icons:change.icons??undefined},...change.text!==undefined&&{text:change.text??undefined}})
1402
+ if(!pin)
1403
+ throw new Error("Choose up to three icons and a single-line label")
1404
+ return pin
1405
+ }
1273
1406
  function changeToolbarPins(current=[],change){const pins=parseToolbarPins(current)
1274
1407
  if(change.operation==="pin"){const pin=parsePin(change.pin)
1275
1408
  if(!pin)
@@ -1285,21 +1418,7 @@ if(index===-1){if(change.operation==="configure")
1285
1418
  throw new Error("Pin no longer exists; reopen the toolbar manager")
1286
1419
  return pins
1287
1420
  }
1288
- if(change.operation==="configure"){if(change.expected&&change.expected!==JSON.stringify(pins[index]))
1289
- throw new Error("Pin changed; reopen its configuration")
1290
- const stateIcons={...pins[index].stateIcons}
1291
- const changes=Object.entries(change.stateIcons??{})
1292
- for(const [state,icon] of changes){if(!identifier(state)||icon!==null&&!identifier(icon))
1293
- throw new Error("Invalid state icon")
1294
- if(icon===null)
1295
- delete stateIcons[state]
1296
- else
1297
- stateIcons[state]=icon
1298
- }
1299
- const pin=parsePin({...pins[index],icon:change.icon,stateIcons})
1300
- if(!pin)
1301
- throw new Error("Invalid toolbar icon")
1302
- pins[index]=pin
1421
+ if(change.operation==="configure"){pins[index]=configurePin(pins[index],change)
1303
1422
  return pins
1304
1423
  }
1305
1424
  const [pin]=pins.splice(index,1)
@@ -1754,25 +1873,25 @@ return{sections:{...base?.sections,...session.sections},expanded:{...base?.expan
1754
1873
  function createPreferencesController(api,defaults,store,configured={}){const builtIns={behavior:{toggleKey:defaults.toggleKey,focusKey:defaults.focusKey,searchKey:defaults.searchKey,persistMcp:defaults.persistMcp,limitsRefreshMinutes:defaults.limitsRefreshMinutes,startInChat:defaults.startInChat,showSessionTitle:defaults.showSessionTitle,showSessionDate:defaults.showSessionDate,cornerFont:defaults.cornerFont,lspIconStyle:defaults.lspIconStyle,rowDensity:defaults.rowDensity,toolbarOverflow:defaults.toolbarOverflow,sectionItemLimits:defaults.sectionItemLimits,quickActionOrder:defaults.quickActionOrder,quickActionVisibility:defaults.quickActionVisibility
1755
1874
  },layout:{sections:defaults.sections,expanded:DEFAULT_SECTION_EXPANSION,order:defaults.sectionOrder??[...SIDEBAR_SECTIONS]
1756
1875
  },desiredMcpStates:{}}
1757
- const [resolved,setResolved]=createSignal4(resolvePreferences({builtIns,pluginOptions:configured}))
1758
- const [skippedSkills,setSkippedSkills]=createSignal4(new Set)
1759
- const [onboardingCompleted,setOnboardingCompleted]=createSignal4(false)
1760
- const [activeTarget,setActiveTarget]=createSignal4({kind:"global"})
1761
- const [preferenceScope,setPreferenceScope]=createSignal4("global")
1762
- const [layoutPresets,setLayoutPresets]=createSignal4(configured.layoutPresets??{})
1763
- const [mcpPresets,setMcpPresets]=createSignal4(configured.mcpPresets??{})
1764
- const [favoriteSkills,setFavoriteSkills]=createSignal4(new Set)
1765
- const [favoriteMcpServers,setFavoriteMcpServers]=createSignal4(new Set)
1766
- const [favoriteQuickActions,setFavoriteQuickActions]=createSignal4(new Set)
1767
- const [recentSkills,setRecentSkills]=createSignal4([])
1768
- const [recentQuickActions,setRecentQuickActions]=createSignal4([])
1769
- const [mcpServerGroups,setMcpServerGroups]=createSignal4(configured.mcpServerGroups??{})
1770
- const [skillGroups,setSkillGroups]=createSignal4({})
1771
- const [autoApprovePermissions,setAutoApprovePermissions]=createSignal4()
1772
- const [codexAccountBindings,setCodexAccountBindings]=createSignal4({})
1773
- const [pendingResetAttempt,setPendingResetAttempt]=createSignal4()
1774
- const [ready,setReady]=createSignal4(false)
1775
- const [revision,setRevision]=createSignal4(0)
1876
+ const [resolved,setResolved]=createSignal5(resolvePreferences({builtIns,pluginOptions:configured}))
1877
+ const [skippedSkills,setSkippedSkills]=createSignal5(new Set)
1878
+ const [onboardingCompleted,setOnboardingCompleted]=createSignal5(false)
1879
+ const [activeTarget,setActiveTarget]=createSignal5({kind:"global"})
1880
+ const [preferenceScope,setPreferenceScope]=createSignal5("global")
1881
+ const [layoutPresets,setLayoutPresets]=createSignal5(configured.layoutPresets??{})
1882
+ const [mcpPresets,setMcpPresets]=createSignal5(configured.mcpPresets??{})
1883
+ const [favoriteSkills,setFavoriteSkills]=createSignal5(new Set)
1884
+ const [favoriteMcpServers,setFavoriteMcpServers]=createSignal5(new Set)
1885
+ const [favoriteQuickActions,setFavoriteQuickActions]=createSignal5(new Set)
1886
+ const [recentSkills,setRecentSkills]=createSignal5([])
1887
+ const [recentQuickActions,setRecentQuickActions]=createSignal5([])
1888
+ const [mcpServerGroups,setMcpServerGroups]=createSignal5(configured.mcpServerGroups??{})
1889
+ const [skillGroups,setSkillGroups]=createSignal5({})
1890
+ const [autoApprovePermissions,setAutoApprovePermissions]=createSignal5()
1891
+ const [codexAccountBindings,setCodexAccountBindings]=createSignal5({})
1892
+ const [pendingResetAttempt,setPendingResetAttempt]=createSignal5()
1893
+ const [ready,setReady]=createSignal5(false)
1894
+ const [revision,setRevision]=createSignal5(0)
1776
1895
  const sessionLayouts=new Map
1777
1896
  const pendingUpdates=[]
1778
1897
  let document=emptyPreferencesDocument()
@@ -2283,7 +2402,7 @@ return{behavior,layout:{sections,expanded:{},...sectionOrder&&{order:sectionOrde
2283
2402
  function configuredDefaultsFromPluginOptions(options){return mergeConfiguredDefaults(legacyDefaults(pluginConfig(options)),parseConfiguredDefaults(options??{}))
2284
2403
  }
2285
2404
 
2286
- function createSkillController(api){const [skills,setSkills]=createSignal5({})
2405
+ function createSkillController(api,source){const [skills,setSkills]=createSignal6({})
2287
2406
  const refreshing=new Map
2288
2407
  const targets=new Map
2289
2408
  const requests=createRequestState(api.lifecycle.signal)
@@ -2292,7 +2411,7 @@ let activeTarget
2292
2411
  let leases=new Set
2293
2412
  function target(){return currentLocation(api)
2294
2413
  }
2295
- function list(current=target()){return skills()[current.key]??[]
2414
+ function list(current=target()){return source?source.list(current):skills()[current.key]??[]
2296
2415
  }
2297
2416
  function error(current=target()){return requests.state(current.key).error?.message
2298
2417
  }
@@ -2303,8 +2422,8 @@ targets.set(current.key,current)
2303
2422
  const requestState=requests.start(current.key,"refresh skills",current.key in skills(),force)
2304
2423
  if(!requestState)
2305
2424
  return pending
2306
- const request=api.client.app.skills(current.routing,{throwOnError:true,signal:requestState.signal}).then((result)=>{const items=[...result.data??[]].sort((a,b)=>a.name.localeCompare(b.name))
2307
- if(requestState.isCurrent())
2425
+ const request=(source?source.refresh(current,force,requestState.signal).then((data)=>({data})):api.client.app.skills(current.routing,{throwOnError:true,signal:requestState.signal})).then((result)=>{const items=[...result.data??[]].sort((a,b)=>a.name.localeCompare(b.name))
2426
+ if(!source&&requestState.isCurrent())
2308
2427
  setSkills((value)=>({...value,[current.key]:items}))
2309
2428
  requestState.succeed()
2310
2429
  return items
@@ -2340,12 +2459,12 @@ targets.delete(current.key)
2340
2459
  requests.abortAll()
2341
2460
  promptRequests.abortAll()
2342
2461
  refreshing.clear()
2343
- }},async use(current,name){if(activeTarget&&activeTarget!==current.key||target().key!==current.key)
2462
+ }},async use(current,name,selected){if(activeTarget&&activeTarget!==current.key||target().key!==current.key)
2344
2463
  throw new DOMException("Sidebar context changed","AbortError")
2345
2464
  const request=promptRequests.start(current.key,"insert skill",false,true)
2346
2465
  if(!request)
2347
2466
  return false
2348
- try{const result=await api.client.tui.appendPrompt({...current.routing,text:`/${name} `},{throwOnError:true,signal:request.signal})
2467
+ try{const result=source&&selected?{data:await source.use(current,selected,request.signal)}:await api.client.tui.appendPrompt({...current.routing,text:`/${name} `},{throwOnError:true,signal:request.signal})
2349
2468
  if(!request.isCurrent())
2350
2469
  return false
2351
2470
  request.succeed()
@@ -2505,7 +2624,7 @@ _$insertNode(_el$4,_el$5)
2505
2624
  _$setProp(_el$4,"flexDirection","row")
2506
2625
  _$setProp(_el$4,"gap",1)
2507
2626
  _$setProp(_el$4,"alignItems","center")
2508
- _$insert(_el$4,_$createComponent(Show2,{get when(){return props.onConfigure
2627
+ _$insert(_el$4,_$createComponent(Show3,{get when(){return props.onConfigure
2509
2628
  },get children(){return _$createComponent(IconControl,{get icon(){return terminalIcon("pin",icons.style())
2510
2629
  },get foregroundColor(){return _$memo(()=>props.active==="configure")()?theme().selectedListItemText:theme().textMuted
2511
2630
  },get backgroundColor(){return _$memo(()=>props.active==="configure")()?theme().primary:undefined
@@ -2578,7 +2697,7 @@ const unregister=props.api.keymap.registerLayer({mode:"modal",priority:1000,comm
2578
2697
  },{key:"return",cmd:`${PLUGIN_ID}.skill-dialog.submit`
2579
2698
  }]
2580
2699
  })
2581
- onCleanup3(unregister)
2700
+ onCleanup5(unregister)
2582
2701
  return _$createComponent(DialogSurface,{get api(){return props.api
2583
2702
  },get children(){return [_$createComponent(SkillDialogHeader,{get api(){return props.api
2584
2703
  },get name(){return props.skill.name
@@ -2601,11 +2720,15 @@ return _$createComponent(DialogSurface,{get api(){return props.api
2601
2720
  function skillUnavailable(controller,skill){const list=controller.list()
2602
2721
  if(list.every((item)=>!(item.name===skill.name&&item.location===skill.location)))
2603
2722
  return "Skill is unavailable in this workspace"
2604
- if(list.filter((item)=>item.name===skill.name).length!==1)
2723
+ if(skill.id){if(list.every((item)=>item.id!==skill.id||item.location!==skill.location))
2724
+ return "Skill source changed"
2725
+ } else if(list.filter((item)=>item.name===skill.name).length!==1)
2605
2726
  return "Multiple sources share this skill name"
2606
2727
  return
2607
2728
  }
2608
- function activateSkill(input){const target=input.controller.target()
2729
+ function activateSkill(input){input={...input,skill:{...input.skill
2730
+ }}
2731
+ const target=input.controller.target()
2609
2732
  const route=JSON.stringify(input.api.route.current)
2610
2733
  const current=()=>target.key===input.controller.target().key&&route===JSON.stringify(input.api.route.current)
2611
2734
  const report=(error)=>{if(!isAbortError(error))
@@ -2622,7 +2745,7 @@ async function insert(skip=false){try{check()
2622
2745
  if(skip)
2623
2746
  input.access.skipSkillConfirmation(input.skill)
2624
2747
  input.beforeInsert?.()
2625
- if(await input.controller.use(target,input.skill.name))
2748
+ if(await input.controller.use(target,input.skill.name,input.skill))
2626
2749
  await input.access.recordSkillUse?.(input.skill)
2627
2750
  } catch(error){report(error)
2628
2751
  }}
@@ -2644,7 +2767,7 @@ input.dialogs.open(()=>_$createComponent(SkillDialog,{get api(){return input.api
2644
2767
 
2645
2768
 
2646
2769
  function createSubagentHistory({now=Date.now}={}){const targets=new Map
2647
- const [revision,setRevision]=createSignal6(0)
2770
+ const [revision,setRevision]=createSignal7(0)
2648
2771
  function state(key){let value=targets.get(key)
2649
2772
  if(!value){value={known:new Set,active:new Map,recent:[]}
2650
2773
  targets.set(key,value)
@@ -2699,19 +2822,21 @@ return targets.get(key)?.recent??[]
2699
2822
  var POLL_INTERVAL_MS=5000
2700
2823
  function activeStatus(status){return status?.type==="busy"||status?.type==="retry"
2701
2824
  }
2702
- function createSubagentController(api,options={}){const now=options.now??Date.now
2825
+ function createSubagentController(api,options={}){const source=options.source
2826
+ const now=options.now??Date.now
2703
2827
  const history=createSubagentHistory({now})
2704
- const [children,setChildren]=createSignal7({})
2705
- const [statuses,setStatuses]=createSignal7({})
2828
+ const [children,setChildren]=createSignal8({})
2829
+ const [statuses,setStatuses]=createSignal8({})
2706
2830
  const refreshing=new Map
2707
2831
  const journals=new Set
2708
- const [unavailable,setUnavailable]=createSignal7({})
2832
+ const [unavailable,setUnavailable]=createSignal8({})
2709
2833
  const targets=new Map
2710
2834
  const remoteFailures=new Map
2711
2835
  const remoteRetryAt=new Map
2712
2836
  const requests=createRequestState(api.lifecycle.signal)
2713
2837
  let activeTarget
2714
2838
  let pollTimer
2839
+ const snapshots=()=>source?Object.fromEntries([...targets].map(([key,current])=>[key,source.list(current.parentID)])):children()
2715
2840
  function target(parentID){const parent=api.state.session.get(parentID)
2716
2841
  const directory=parent?.directory??api.state.path.directory
2717
2842
  const workspace=parent?.workspaceID
@@ -2730,16 +2855,18 @@ history.remove(key,sessionID)
2730
2855
  }
2731
2856
  for(const journal of journals)
2732
2857
  journal.sessions.push(mutation)
2858
+ if(!source)
2733
2859
  setChildren((current)=>Object.fromEntries(Object.entries(current).map(([key,items])=>[key,applySession(items,targets.get(key).parentID,mutation)])))
2734
2860
  }
2735
2861
  function recordStatus(input){const mutation={...input,at:now(),observed:new Set}
2736
2862
  for(const journal of journals)
2737
2863
  journal.statuses.push(mutation)
2738
- batch(()=>{for(const [key,items] of Object.entries(children())){if(items.every((item)=>item.id!==mutation.sessionID))
2864
+ batch(()=>{for(const [key,items] of Object.entries(snapshots())){if(items.every((item)=>item.id!==mutation.sessionID))
2739
2865
  continue
2740
2866
  history.observeStatus(key,mutation.sessionID,mutation.status,mutation.at)
2741
2867
  mutation.observed.add(key)
2742
2868
  }
2869
+ if(!source)
2743
2870
  setStatuses((current)=>Object.fromEntries(Object.entries(current).map(([key,value])=>[key,applyStatus(value,mutation)])))
2744
2871
  })
2745
2872
  }
@@ -2748,7 +2875,7 @@ return
2748
2875
  const mutation={sessionID:input.sessionID,error:input.error,at:now(),observed:new Set}
2749
2876
  for(const journal of journals)
2750
2877
  journal.errors.push(mutation)
2751
- for(const [key,items] of Object.entries(children())){if(items.every((item)=>item.id!==mutation.sessionID))
2878
+ for(const [key,items] of Object.entries(snapshots())){if(items.every((item)=>item.id!==mutation.sessionID))
2752
2879
  continue
2753
2880
  history.observeError(key,mutation.sessionID,mutation.error,mutation.at)
2754
2881
  mutation.observed.add(key)
@@ -2765,12 +2892,13 @@ if(!requestState){journals.delete(journal)
2765
2892
  return pending
2766
2893
  }
2767
2894
  const signal=AbortSignal.any([requestState.signal,AbortSignal.timeout(5000)])
2768
- const request=Promise.all([api.client.session.children({sessionID:current.parentID,...current.routing},{throwOnError:true,signal}),api.client.session.status(current.routing,{throwOnError:true,signal})]).then(async ([childResult,statusResult])=>{let nextChildren=childResult.data??[]
2895
+ const request=(source?source.refresh(current.parentID,signal).then(()=>[{data:source.list(current.parentID)},{data:Object.fromEntries(source.list(current.parentID).map((item)=>[item.id,source.status(item.id)]))
2896
+ }]):Promise.all([api.client.session.children({sessionID:current.parentID,...current.routing},{throwOnError:true,signal}),api.client.session.status(current.routing,{throwOnError:true,signal})])).then(async ([childResult,statusResult])=>{let nextChildren=childResult.data??[]
2769
2897
  for(const mutation of journal.sessions)
2770
2898
  nextChildren=applySession(nextChildren,current.parentID,mutation)
2771
2899
  let nextStatuses={...statusResult.data}
2772
2900
  const missing={}
2773
- const remoteStatuses=await Promise.all(nextChildren.map((session)=>{const key=JSON.stringify([current.key,session.id])
2901
+ const remoteStatuses=source?[]:await Promise.all(nextChildren.map((session)=>{const key=JSON.stringify([current.key,session.id])
2774
2902
  return(remoteRetryAt.get(key)??0)<=now()?fetchDevTeamStatus(session,requestState.signal):{sessionID:session.id,failed:true,cooldown:true,status:undefined}}))
2775
2903
  if(!requestState.isCurrent())
2776
2904
  return
@@ -2807,8 +2935,9 @@ history.observeStatus(current.key,session.id,status)
2807
2935
  for(const mutation of journal.errors){if(mutation.sessionID===session.id&&!mutation.observed.has(current.key))
2808
2936
  history.observeError(current.key,session.id,mutation.error,mutation.at)
2809
2937
  }}
2810
- setChildren((value)=>({...value,[current.key]:nextChildren}))
2938
+ if(!source){setChildren((value)=>({...value,[current.key]:nextChildren}))
2811
2939
  setStatuses((value)=>({...value,[current.key]:nextStatuses}))
2940
+ }
2812
2941
  setUnavailable((value)=>({...value,[current.key]:missing}))
2813
2942
  })
2814
2943
  }
@@ -2826,13 +2955,13 @@ return request
2826
2955
  function refresh(parentID,force=false){return refreshTarget(target(parentID),force)
2827
2956
  }
2828
2957
  function list(parentID){const current=target(parentID)
2829
- const currentStatuses=statuses()[current.key]??{}
2830
- return(children()[current.key]??[]).map((session)=>({session,status:currentStatuses[session.id]??(unavailable()[current.key]?.[session.id]?undefined:api.state.session.status(session.id))
2958
+ const currentStatuses=source?Object.fromEntries(source.list(parentID).map((item)=>[item.id,source.status(item.id)])):statuses()[current.key]??{}
2959
+ return(snapshots()[current.key]??[]).map((session)=>({session,status:currentStatuses[session.id]??(unavailable()[current.key]?.[session.id]?undefined:api.state.session.status(session.id))
2831
2960
  })).filter((item)=>activeStatus(item.status)).map((item)=>({...item,run:history.active(current.key,item.session.id),unavailable:unavailable()[current.key]?.[item.session.id]
2832
2961
  }))
2833
2962
  }
2834
2963
  function recent(parentID){const current=target(parentID)
2835
- const sessions=new Map((children()[current.key]??[]).map((session)=>[session.id,session]))
2964
+ const sessions=new Map((snapshots()[current.key]??[]).map((session)=>[session.id,session]))
2836
2965
  return history.recent(current.key).flatMap((run)=>{const session=sessions.get(run.sessionID)
2837
2966
  return session?[{session,status:{type:"idle"},run,unavailable:false}]:[]
2838
2967
  })
@@ -2862,6 +2991,7 @@ return
2862
2991
  refreshTarget(current).catch(()=>{})
2863
2992
  pollTimer=setTimeout(poll,POLL_INTERVAL_MS)
2864
2993
  }
2994
+ if(!source)
2865
2995
  pollTimer=setTimeout(poll,POLL_INTERVAL_MS)
2866
2996
  }
2867
2997
  return()=>{if(activeTarget!==current.key)
@@ -2924,17 +3054,17 @@ else if(seconds>=60)
2924
3054
  value=`${Math.floor(seconds / 60)}m ${String(seconds % 60).padStart(2, "0")}s`
2925
3055
  return value
2926
3056
  }
2927
- function createSubagentClock(key){const [now,setNow]=createSignal8(Date.now())
2928
- createEffect5(()=>{if(key()===undefined)
3057
+ function createSubagentClock(key){const [now,setNow]=createSignal9(Date.now())
3058
+ createEffect6(()=>{if(key()===undefined)
2929
3059
  return
2930
3060
  setNow(Date.now())
2931
3061
  const timer=setInterval(()=>setNow(Date.now()),1000)
2932
- onCleanup4(()=>clearInterval(timer))
3062
+ onCleanup6(()=>clearInterval(timer))
2933
3063
  })
2934
3064
  return now
2935
3065
  }
2936
3066
 
2937
- function createTodoController(api){const [sessions,setSessions]=createSignal9({})
3067
+ function createTodoController(api){const [sessions,setSessions]=createSignal10({})
2938
3068
  const refreshing=new Map
2939
3069
  const revisions=new Map
2940
3070
  const requests=createRequestState(api.lifecycle.signal)
@@ -3026,6 +3156,21 @@ function openKeyboardHelp(api,iconStyle=()=>"nerd",multilineCorners=()=>true,sho
3026
3156
 
3027
3157
 
3028
3158
 
3159
+ var defaults={todo:true,lsp:true}
3160
+ var capabilities=new WeakMap
3161
+ function setHostCapabilities(api,value){capabilities.set(api,value)
3162
+ }
3163
+ function hostCapabilities(api){return capabilities.get(api)??defaults
3164
+ }
3165
+ function hostCapabilityUnavailable(api,section){return section==="todo"||section==="lsp"?hostCapabilities(api).unavailable?.[section]:undefined
3166
+ }
3167
+ function supportsSidebarSection(api,section){const current=hostCapabilities(api)
3168
+ return section!=="todo"&&section!=="lsp"?true:current[section]
3169
+ }
3170
+ function supportsTitleVisibility(api){return hostCapabilities(api).titleVisibility!==false
3171
+ }
3172
+ function supportsPermissionMode(api){return hostCapabilities(api).permissionMode!==false
3173
+ }
3029
3174
  var QUICK_ACTION_METADATA=[["\uEA73","Rename"],["\uEA82","Timeline"],["\uEBCC","Copy transcript"],["\uEBAC","Export"],["\uEAF5","Compact"],["\uEBEB","Switch session"],["\uEA60","New session"],["\uEB9E","Fork session"],["\uEBCC","Copy last response"],["\uEAA1","First message"],["\uEA9A","Last message"],["\uEA82","Last user message"],["\uEA9A","Next message"],["\uEAA1","Previous message"],["\uEBB3","Auto-approve permissions"]]
3030
3175
  var QUICK_ACTIONS=QUICK_ACTION_IDS.map((command,index)=>({command,icon:QUICK_ACTION_METADATA[index][0],label:QUICK_ACTION_METADATA[index][1]
3031
3176
  }))
@@ -3036,10 +3181,10 @@ return action.label
3036
3181
  const command=api.keymap.getCommands?.({visibility:"registered"}).find((candidate)=>candidate.name===action.command)
3037
3182
  return typeof command?.title==="string"?command.title:action.label
3038
3183
  }
3039
- function createQuickActionRevision(api){const [revision,setRevision]=createSignal11(0)
3184
+ function createQuickActionRevision(api){const [revision,setRevision]=createSignal12(0)
3040
3185
  const unsubscribe=api.keymap.on?.("state",()=>setRevision((value)=>value + 1))
3041
3186
  if(unsubscribe)
3042
- onCleanup6(unsubscribe)
3187
+ onCleanup8(unsubscribe)
3043
3188
  return revision
3044
3189
  }
3045
3190
  function orderQuickActionIds(order,favorites){return [...order.filter((id)=>favorites.has(id)),...order.filter((id)=>!favorites.has(id))]
@@ -3052,7 +3197,7 @@ if(!getCommands)
3052
3197
  return
3053
3198
  const command=getCommands({visibility:"registered"}).find((candidate)=>candidate.name===action.command)
3054
3199
  if(!command)
3055
- return "Unavailable in this OpenCode version"
3200
+ return hostCapabilities(api).commandsReachableOnly?"Unavailable in the current session":"Unavailable in this OpenCode version"
3056
3201
  const enabled=command.enabled
3057
3202
  if(enabled===false||typeof enabled==="function"&&!enabled())
3058
3203
  return "Unavailable in the current session"
@@ -3155,7 +3300,7 @@ const [selectedID,setSelectedID]=useDialogState("selection",undefined)
3155
3300
  const [views]=useDialogState("tab-views",new Map)
3156
3301
  const tabViews=views()
3157
3302
  const [scrollTop,setScrollTop]=useDialogState("scroll",0)
3158
- const [refreshing,setRefreshing]=createSignal12(false)
3303
+ const [refreshing,setRefreshing]=createSignal13(false)
3159
3304
  const theme=()=>props.api.theme.current
3160
3305
  const icons=useIcons()
3161
3306
  const commandRevision=createQuickActionRevision(props.api)
@@ -3165,11 +3310,24 @@ const contrast=background.r*0.299 + background.g*0.587 + background.b*0.114>0.5?
3165
3310
  return{title:mixColor(parseColor2(theme().text),RGBA3.fromValues(contrast,contrast,contrast),0.45),description:mixColor(parseColor2(theme().textMuted),background,0.4)
3166
3311
  }})
3167
3312
  const dimensions=useTerminalDimensions5()
3313
+ const renderer=useRenderer2()
3168
3314
  let input
3169
3315
  let body
3170
3316
  let pendingScroll=scrollTop()
3171
3317
  let isDisposed=false
3172
3318
  let refreshGeneration=0
3319
+ const onFrame=()=>{if(!body||body.isDestroyed)
3320
+ return
3321
+ const position=pendingScroll
3322
+ pendingScroll=undefined
3323
+ if(typeof position==="number")
3324
+ body.scrollTo(position)
3325
+ else if(typeof position==="string")
3326
+ body.scrollChildIntoView(`${prefix}.${position}`)
3327
+ setScrollTop(body.scrollTop)
3328
+ }
3329
+ renderer.on("frame",onFrame)
3330
+ onCleanup9(()=>renderer.off("frame",onFrame))
3173
3331
  const sameContext=()=>searchContext(props.api).key===context.key
3174
3332
  const candidates=createMemo(()=>{commandRevision()
3175
3333
  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)
@@ -3275,14 +3433,14 @@ const unregister=props.api.keymap.registerLayer({mode:"modal",priority:1000,comm
3275
3433
  },{key:"ctrl+r",cmd:`${prefix}.retry`
3276
3434
  }]
3277
3435
  })
3278
- onCleanup7(()=>{isDisposed=true
3436
+ onCleanup9(()=>{isDisposed=true
3279
3437
  unregister()
3280
3438
  })
3281
- onCleanup7(props.skills.activate?.(skillTarget)??(()=>{}))
3282
- onMount(()=>{input?.focus()
3439
+ onCleanup9(props.skills.activate?.(skillTarget)??(()=>{}))
3440
+ onMount2(()=>{input?.focus()
3283
3441
  refresh().catch(report)
3284
3442
  })
3285
- createEffect6(()=>{if(!sameContext())
3443
+ createEffect7(()=>{if(!sameContext())
3286
3444
  dialogs.close()
3287
3445
  })
3288
3446
  return{active,activeTab,activate,allErrors,byID,dialogs,errors,icons,loading,matches,prefix,query,queryScope,resultColors,results,selectTab,setBody(node){body=node
@@ -3291,17 +3449,7 @@ return{active,activeTab,activate,allErrors,byID,dialogs,errors,icons,loading,mat
3291
3449
  pendingScroll=0
3292
3450
  setQueryValue(value)
3293
3451
  setSelectedID(undefined)
3294
- },setSelectedID,renderBefore(){const position=pendingScroll
3295
- pendingScroll=undefined
3296
- if(!body||position===undefined)
3297
- return
3298
- if(typeof position==="number")
3299
- body.scrollTo(position)
3300
- else
3301
- body.scrollChildIntoView(`${prefix}.${position}`)
3302
- },renderAfter(){if(body)
3303
- setScrollTop(body.scrollTop)
3304
- },resultHeight:()=>Math.min(Math.max(3,Math.min(16,Math.floor(dimensions().height*0.5)-9)),Math.max(1,results().length*3 + errors().length*2)),theme
3452
+ },setSelectedID,resultHeight:()=>Math.min(Math.max(3,Math.min(16,Math.floor(dimensions().height*0.5)-9)),Math.max(1,results().length*3 + errors().length*2)),theme
3305
3453
  }}
3306
3454
 
3307
3455
 
@@ -3455,7 +3603,7 @@ _$effect((_$p)=>_$setProp(_el$2,"fg",model.theme().error,_$p))
3455
3603
  return _el$2
3456
3604
  })()
3457
3605
  }),null)
3458
- _$insert(_el$,_$createComponent(Show3,{get when(){return model.results().length
3606
+ _$insert(_el$,_$createComponent(Show4,{get when(){return model.results().length
3459
3607
  },get fallback(){return(()=>{var _el$8=_$createElement("text"),_el$9=_$createTextNode(` `)
3460
3608
  _$insertNode(_el$8,_el$9)
3461
3609
  _$insert(_el$8,()=>model.icons.icon(model.loading()?"pending":"search"),_el$9)
@@ -3463,20 +3611,18 @@ _$insert(_el$8,()=>model.loading()?"Loading sources\u2026":"No matching results"
3463
3611
  _$effect((_$p)=>_$setProp(_el$8,"fg",model.theme().textMuted,_$p))
3464
3612
  return _el$8
3465
3613
  })()
3466
- },get children(){return _$createComponent(Show3,{keyed:true,get when(){return model.queryScope()
3614
+ },get children(){return _$createComponent(Show4,{keyed:true,get when(){return model.queryScope()
3467
3615
  },children:(_scope)=>_$createComponent(For3,{get each(){return model.results().map((item)=>item.id)
3468
3616
  },children:(id)=>_$createComponent(SearchResultRow,{model,id
3469
3617
  })
3470
3618
  })
3471
3619
  })
3472
3620
  }}),null)
3473
- _$effect((_p$)=>{var _v$=`${model.prefix}.results`,{renderBefore:_v$2,renderAfter:_v$3}=model,_v$4=model.resultHeight()
3621
+ _$effect((_p$)=>{var _v$=`${model.prefix}.results`,_v$2=model.resultHeight()
3474
3622
  _v$!==_p$.e&&(_p$.e=_$setProp(_el$,"id",_v$,_p$.e))
3475
- _v$2!==_p$.t&&(_p$.t=_$setProp(_el$,"renderBefore",_v$2,_p$.t))
3476
- _v$3!==_p$.a&&(_p$.a=_$setProp(_el$,"renderAfter",_v$3,_p$.a))
3477
- _v$4!==_p$.o&&(_p$.o=_$setProp(_el$,"height",_v$4,_p$.o))
3623
+ _v$2!==_p$.t&&(_p$.t=_$setProp(_el$,"height",_v$2,_p$.t))
3478
3624
  return _p$
3479
- },{e:undefined,t:undefined,a:undefined,o:undefined
3625
+ },{e:undefined,t:undefined
3480
3626
  })
3481
3627
  return _el$
3482
3628
  })()
@@ -3519,13 +3665,13 @@ timers.add(timer)
3519
3665
  }},{name:`${LEGACY_PLUGIN_ID}.search`,run(){props.api.keymap.dispatchCommand(SEARCH_COMMAND)
3520
3666
  }}]
3521
3667
  })
3522
- createEffect7(()=>{const key=props.preferences.searchKey()
3668
+ createEffect8(()=>{const key=props.preferences.searchKey()
3523
3669
  const remove=props.api.keymap.registerLayer({mode:"base",bindings:[{key,cmd:SEARCH_COMMAND
3524
3670
  }]
3525
3671
  })
3526
- onCleanup8(remove)
3672
+ onCleanup10(remove)
3527
3673
  })
3528
- onCleanup8(()=>{isDisposed=true
3674
+ onCleanup10(()=>{isDisposed=true
3529
3675
  unregister()
3530
3676
  for(const timer of timers)
3531
3677
  clearTimeout(timer)
@@ -3562,21 +3708,6 @@ return value&&valid()&&!blocked()?controller.applyPreset(name,value,target):unde
3562
3708
 
3563
3709
 
3564
3710
 
3565
- var defaults={todo:true,lsp:true}
3566
- var capabilities=new WeakMap
3567
- function setHostCapabilities(api,value){capabilities.set(api,value)
3568
- }
3569
- function hostCapabilities(api){return capabilities.get(api)??defaults
3570
- }
3571
- function hostCapabilityUnavailable(api,section){return section==="todo"||section==="lsp"?hostCapabilities(api).unavailable?.[section]:undefined
3572
- }
3573
- function supportsSidebarSection(api,section){const current=hostCapabilities(api)
3574
- return section!=="todo"&&section!=="lsp"?true:current[section]
3575
- }
3576
- function supportsTitleVisibility(api){return hostCapabilities(api).titleVisibility!==false
3577
- }
3578
- function supportsPermissionMode(api){return hostCapabilities(api).permissionMode!==false
3579
- }
3580
3711
  var ONBOARDING_STEPS=[{title:"A control center that stays compact",summary:"Navigator brings session state, search, and controls into OpenCode's existing sidebar.",icon:"help",features:[{icon:"sections",title:"Progressive disclosure",description:"Expand only the context you need right now."},{icon:"scope",title:"Current context",description:"Follow the active session, workspace, and worktree."},{icon:"actions",title:"Mouse and keyboard",description:"Use the same controls with either input method."}]
3581
3712
  },{title:"Stay oriented while agents work",summary:"Keep current work visible without turning the sidebar into another dashboard.",icon:"todo",features:[{icon:"todo",title:"Todo filters",description:"Separate active, finished, and cancelled work."},{icon:"subagents",title:"Live subagents",description:"See running, retrying, recent, and failed child sessions; open them directly."
3582
3713
  },{icon:"info",title:"Provider limits",description:"Link a matching Codex account for model quotas and confirmed banked resets."
@@ -3756,8 +3887,8 @@ return _el$
3756
3887
  }
3757
3888
  function FirstRunWizard(props){const icons=useIcons()
3758
3889
  const dialogs=useDialogs(props.api)
3759
- const [active,setActive]=createSignal13(0)
3760
- const [step,setStep]=createSignal13(0)
3890
+ const [active,setActive]=createSignal14(0)
3891
+ const [step,setStep]=createSignal14(0)
3761
3892
  const theme=()=>props.api.theme.current
3762
3893
  const sections=SECTION_DEFINITIONS.filter((section)=>supportsSidebarSection(props.api,section.name))
3763
3894
  const finishIndex=sections.length
@@ -3798,7 +3929,7 @@ const unregister=props.api.keymap.registerLayer({mode:"modal",priority:1000,comm
3798
3929
  },{key:"return",cmd:`${PLUGIN_ID}.wizard.select`
3799
3930
  }]
3800
3931
  })
3801
- onCleanup9(unregister)
3932
+ onCleanup11(unregister)
3802
3933
  return _$createComponent(DialogSurface,{get api(){return props.api
3803
3934
  },get children(){return [(()=>{var _el$=_$createElement("box"),_el$2=_$createElement("text"),_el$3=_$createTextNode(` Navigator setup`),_el$4=_$createElement("text"),_el$5=_$createTextNode(`Step `),_el$6=_$createTextNode(`/`),_el$7=_$createTextNode(` \xB7 `)
3804
3935
  _$insertNode(_el$,_el$2)
@@ -3825,7 +3956,7 @@ return _p$
3825
3956
  },{e:undefined,t:undefined,a:undefined
3826
3957
  })
3827
3958
  return _el$
3828
- })(),_$createComponent(Show4,{get when(){return configuring()
3959
+ })(),_$createComponent(Show5,{get when(){return configuring()
3829
3960
  },get fallback(){return _$createComponent(OnboardingStep,{get api(){return props.api
3830
3961
  },get preferences(){return props.preferences
3831
3962
  },get step(){return ONBOARDING_STEPS[step()]
@@ -3882,7 +4013,7 @@ _$insertNode(_el$,_el$6)
3882
4013
  _$setProp(_el$,"flexDirection","row")
3883
4014
  _$setProp(_el$,"justifyContent","space-between")
3884
4015
  _$setProp(_el$2,"flexGrow",1)
3885
- _$insert(_el$2,_$createComponent(Show5,{get when(){return props.onRefresh
4016
+ _$insert(_el$2,_$createComponent(Show6,{get when(){return props.onRefresh
3886
4017
  },get children(){var _el$3=_$createElement("text"),_el$4=_$createTextNode(` Refresh (`),_el$5=_$createTextNode(`)`)
3887
4018
  _$insertNode(_el$3,_el$4)
3888
4019
  _$insertNode(_el$3,_el$5)
@@ -3945,7 +4076,7 @@ const dialogs=useDialogs(props.api)
3945
4076
  const theme=()=>props.api.theme.current
3946
4077
  const dimensions=useTerminalDimensions6()
3947
4078
  const scroll=useDialogScroll()
3948
- const [active,setActive]=createSignal14("apply")
4079
+ const [active,setActive]=createSignal15("apply")
3949
4080
  let body
3950
4081
  const prefix=`${PLUGIN_ID}.preset-preview`
3951
4082
  function activate(action){if(!props.valid()){dialogs.close()
@@ -3974,8 +4105,8 @@ const unregister=props.api.keymap.registerLayer({mode:"modal",priority:1000,comm
3974
4105
  },{key:"ctrl+r",cmd:`${prefix}.refresh`
3975
4106
  }]
3976
4107
  })
3977
- onCleanup10(unregister)
3978
- createEffect8(()=>{if(!props.valid())
4108
+ onCleanup12(unregister)
4109
+ createEffect9(()=>{if(!props.valid())
3979
4110
  dialogs.close()
3980
4111
  })
3981
4112
  return _$createComponent(DialogSurface,{get api(){return props.api
@@ -4014,15 +4145,9 @@ _$setProp(_el$5,"contentOptions",{minHeight:0
4014
4145
  })
4015
4146
  _$setProp(_el$6,"gap",1)
4016
4147
  _$insert(_el$6,()=>props.children)
4017
- _$effect((_p$)=>{var{restore:_v$3,save:_v$4}=scroll,_v$5=Math.min(Math.max(2,Math.floor(dimensions().height*0.75)-14),Math.max(1,props.rowCount*3-1))
4018
- _v$3!==_p$.e&&(_p$.e=_$setProp(_el$5,"renderBefore",_v$3,_p$.e))
4019
- _v$4!==_p$.t&&(_p$.t=_$setProp(_el$5,"renderAfter",_v$4,_p$.t))
4020
- _v$5!==_p$.a&&(_p$.a=_$setProp(_el$5,"height",_v$5,_p$.a))
4021
- return _p$
4022
- },{e:undefined,t:undefined,a:undefined
4023
- })
4148
+ _$effect((_$p)=>_$setProp(_el$5,"height",Math.min(Math.max(2,Math.floor(dimensions().height*0.75)-14),Math.max(1,props.rowCount*3-1)),_$p))
4024
4149
  return _el$5
4025
- })(),_$createComponent(Show6,{get when(){return props.blocked||props.notice
4150
+ })(),_$createComponent(Show7,{get when(){return props.blocked||props.notice
4026
4151
  },get children(){var _el$7=_$createElement("box"),_el$8=_$createElement("text"),_el$9=_$createElement("text")
4027
4152
  _$insertNode(_el$7,_el$8)
4028
4153
  _$insertNode(_el$7,_el$9)
@@ -4034,9 +4159,9 @@ _$setProp(_el$9,"flexGrow",1)
4034
4159
  _$setProp(_el$9,"wrapMode","word")
4035
4160
  _$setProp(_el$9,"height",2)
4036
4161
  _$insert(_el$9,()=>props.blocked||props.notice)
4037
- _$effect((_p$)=>{var _v$6=props.blocked?theme().warning:theme().accent,_v$7=props.blocked?theme().warning:theme().textMuted
4038
- _v$6!==_p$.e&&(_p$.e=_$setProp(_el$8,"fg",_v$6,_p$.e))
4039
- _v$7!==_p$.t&&(_p$.t=_$setProp(_el$9,"fg",_v$7,_p$.t))
4162
+ _$effect((_p$)=>{var _v$3=props.blocked?theme().warning:theme().accent,_v$4=props.blocked?theme().warning:theme().textMuted
4163
+ _v$3!==_p$.e&&(_p$.e=_$setProp(_el$8,"fg",_v$3,_p$.e))
4164
+ _v$4!==_p$.t&&(_p$.t=_$setProp(_el$9,"fg",_v$4,_p$.t))
4040
4165
  return _p$
4041
4166
  },{e:undefined,t:undefined
4042
4167
  })
@@ -4113,7 +4238,7 @@ return _el$6
4113
4238
  function McpPresetPreview(props){const dialogs=useDialogs(props.api)
4114
4239
  const icons=useIcons()
4115
4240
  const model=createMcpPresetPreview(props.controller,props.preferences,props.name)
4116
- onMount2(model.refresh)
4241
+ onMount3(model.refresh)
4117
4242
  const rows=createMemo3(()=>mcpPreviewRows(model,icons))
4118
4243
  const count=(change)=>model.preview().rows.filter((row)=>row.change===change).length
4119
4244
  return _$createComponent(PresetPreviewFrame,{get api(){return props.api
@@ -4274,14 +4399,14 @@ function SettingsBinding(props){const unregister=props.api.keymap.registerLayer(
4274
4399
  },cmd:`${PLUGIN_ID}.settings`
4275
4400
  }]
4276
4401
  })
4277
- onCleanup12(unregister)
4402
+ onCleanup14(unregister)
4278
4403
  return _$createElement("box")
4279
4404
  }
4280
4405
 
4281
4406
 
4282
4407
  function PermissionModeBinding(props){let applying=false
4283
4408
  let observed
4284
- createEffect11(()=>{if(!props.preferences.ready())
4409
+ createEffect12(()=>{if(!props.preferences.ready())
4285
4410
  return
4286
4411
  const preferred=props.preferences.autoApprovePermissions()
4287
4412
  const current=currentPermissionMode(props.api)
@@ -4302,14 +4427,14 @@ observed=current
4302
4427
  props.preferences.setAutoApprovePermissions(current)
4303
4428
  })
4304
4429
  if(unsubscribe)
4305
- onCleanup13(unsubscribe)
4430
+ onCleanup15(unsubscribe)
4306
4431
  return _$createElement("box")
4307
4432
  }
4308
4433
 
4309
4434
 
4310
4435
 
4311
4436
  function SettingsFooterButton(props){const icons=useIcons()
4312
- const [hovered,setHovered]=createSignal15(false)
4437
+ const [hovered,setHovered]=createSignal16(false)
4313
4438
  const theme=()=>props.api.theme.current
4314
4439
  return _$createComponent(IconControl,{id:`${PLUGIN_ID}.settings.footer`,get icon(){return icons.icon("settings")
4315
4440
  },get foregroundColor(){return _$memo(()=>!!hovered())()?theme().text:theme().textMuted
@@ -4320,6 +4445,23 @@ return _$createComponent(IconControl,{id:`${PLUGIN_ID}.settings.footer`,get icon
4320
4445
 
4321
4446
 
4322
4447
 
4448
+ var services=new WeakMap
4449
+ function createSlot(){const [read,write]=createSignal17()
4450
+ return{read,write}}
4451
+ function slot(api){let entry=services.get(api)
4452
+ if(!entry){entry=createSlot()
4453
+ services.set(api,entry)
4454
+ }
4455
+ return entry
4456
+ }
4457
+ function registerNavigatorAboutServices(api,value){const entry=slot(api)
4458
+ entry.write(value)
4459
+ return()=>{if(entry.read()===value)
4460
+ entry.write(undefined)
4461
+ }}
4462
+ function getNavigatorAboutServices(api){return slot(api).read()
4463
+ }
4464
+
4323
4465
  var ACTIONS=[{key:"h",label:"Toggle sidebar",icon:"sections",group:"navigate",command:"session.sidebar.toggle",section:undefined
4324
4466
  },{key:"t",label:"Todo",icon:"todo",group:"navigate",command:`${PLUGIN_ID}.focus.todo`,section:"todo"},{key:"a",label:"Subagents",icon:"subagents",group:"navigate",command:`${PLUGIN_ID}.focus.subagents`,section:"subagents"
4325
4467
  },{key:"s",label:"Skills",icon:"skills",group:"navigate",command:`${PLUGIN_ID}.focus.skills`,section:"skills"
@@ -4334,7 +4476,7 @@ var CANCEL_COMMAND=`${PLUGIN_ID}.sidebar-shortcuts.cancel`
4334
4476
  var MODE=`${PLUGIN_ID}.sidebar-shortcuts`
4335
4477
  var DEFAULT_TIMEOUT_MS=5000
4336
4478
  function createSidebarShortcutMode(api,options={}){const actions=sidebarShortcutActions(api)
4337
- const [active,setActive]=createSignal16(false)
4479
+ const [active,setActive]=createSignal18(false)
4338
4480
  const timeoutMs=options.timeoutMs??DEFAULT_TIMEOUT_MS
4339
4481
  let shortcutKey=""
4340
4482
  let unregisterBinding
@@ -4474,133 +4616,25 @@ function StartupSessionBinding(props){if(props.api.keymap.on){const unregister=p
4474
4616
  return
4475
4617
  queueMicrotask(()=>void props.controller.start())
4476
4618
  })
4477
- onCleanup14(unregister)
4619
+ onCleanup16(unregister)
4478
4620
  } else
4479
- createEffect12(()=>{if(!props.controller.enabled())
4621
+ createEffect13(()=>{if(!props.controller.enabled())
4480
4622
  return
4481
4623
  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()
4482
4624
  }]
4483
4625
  })
4484
- onCleanup14(unregister)
4626
+ onCleanup16(unregister)
4485
4627
  })
4486
- onMount4(()=>void props.controller.initialize())
4487
- onCleanup14(props.controller.dispose)
4628
+ onMount5(()=>void props.controller.initialize())
4629
+ onCleanup16(props.controller.dispose)
4488
4630
  return _$createElement("box")
4489
4631
  }
4490
- function versionParts(value){const match=/^v?(\d+)\.(\d+)\.(\d+)(?:-([^+]+))?/.exec(value)
4491
- return match?{numbers:match.slice(1,4).map(Number),prerelease:match[4]||undefined}:undefined
4492
- }
4493
- function isNewerVersion(latest,current){const next=versionParts(latest)
4494
- const installed=versionParts(current)
4495
- if(!next||!installed)
4496
- return false
4497
- for(let index=0;index<3; index++){if(next.numbers[index]!==installed.numbers[index])
4498
- return next.numbers[index]>installed.numbers[index]
4499
- }
4500
- return installed.prerelease!==undefined&&next.prerelease===undefined
4501
- }
4502
- function changesSince(source,previous,current){const entries=[]
4503
- let entry
4504
- for(const line of source.split(/\r?\n/)){const heading=/^## \[(\d+\.\d+\.\d+(?:-[\w.-]+)?)\]/.exec(line)
4505
- if(heading){entry=isNewerVersion(heading[1],previous)&&!isNewerVersion(heading[1],current)?{version:heading[1],changes:[]}:undefined
4506
- if(entry)
4507
- entries.push(entry)
4508
- continue
4509
- }
4510
- if(entry&&line.startsWith("- "))
4511
- entry.changes.push(line.slice(2))
4512
- }
4513
- return entries.filter((candidate)=>candidate.changes.length>0)
4514
- }
4515
- async function readBundledChangelog(){const packaged=Bun.file(new URL("../CHANGELOG.md",import.meta.url))
4516
- if(await packaged.exists())
4517
- return packaged.text()
4518
- return Bun.file(new URL("../../../../CHANGELOG.md",import.meta.url)).text()
4519
- }
4520
-
4521
-
4522
-
4523
-
4524
-
4525
4632
 
4526
4633
 
4527
4634
 
4528
-
4529
-
4530
-
4531
-
4532
-
4533
- function UpgradeNotesDialog(props){const dimensions=useTerminalDimensions9()
4534
- const dialogs=useDialogs(props.api)
4535
- const icons=useIcons()
4536
- const theme=()=>props.api.theme.current
4537
- return _$createComponent(DialogSurface,{get api(){return props.api
4538
- },lift:true,get children(){return [(()=>{var _el$=_$createElement("text"),_el$2=_$createTextNode(` Navigator updated`)
4539
- _$insertNode(_el$,_el$2)
4540
- _$insert(_el$,()=>icons.icon("update"),_el$2)
4541
- _$effect((_p$)=>{var _v$=theme().text,_v$2=TextAttributes17.BOLD
4542
- _v$!==_p$.e&&(_p$.e=_$setProp(_el$,"fg",_v$,_p$.e))
4543
- _v$2!==_p$.t&&(_p$.t=_$setProp(_el$,"attributes",_v$2,_p$.t))
4544
- return _p$
4545
- },{e:undefined,t:undefined
4546
- })
4547
- return _el$
4548
- })(),(()=>{var _el$3=_$createElement("text"),_el$4=_$createTextNode(`Changes from `),_el$5=_$createTextNode(` to `)
4549
- _$insertNode(_el$3,_el$4)
4550
- _$insertNode(_el$3,_el$5)
4551
- _$insert(_el$3,()=>props.previous,_el$5)
4552
- _$insert(_el$3,()=>props.current,null)
4553
- _$effect((_$p)=>_$setProp(_el$3,"fg",theme().textMuted,_$p))
4554
- return _el$3
4555
- })(),(()=>{var _el$6=_$createElement("scrollbox"),_el$7=_$createElement("box")
4556
- _$insertNode(_el$6,_el$7)
4557
- _$setProp(_el$6,"scrollX",false)
4558
- _$setProp(_el$6,"horizontalScrollbarOptions",{visible:false
4559
- })
4560
- _$setProp(_el$6,"verticalScrollbarOptions",{visible:true
4561
- })
4562
- _$setProp(_el$7,"gap",1)
4563
- _$setProp(_el$7,"paddingRight",1)
4564
- _$insert(_el$7,_$createComponent(For11,{get each(){return props.entries
4565
- },children:(entry)=>(()=>{var _el$0=_$createElement("box"),_el$1=_$createElement("text"),_el$10=_$createTextNode(`Navigator `)
4566
- _$insertNode(_el$0,_el$1)
4567
- _$setProp(_el$0,"gap",1)
4568
- _$insertNode(_el$1,_el$10)
4569
- _$insert(_el$1,()=>entry.version,null)
4570
- _$insert(_el$0,_$createComponent(For11,{get each(){return entry.changes
4571
- },children:(change)=>(()=>{var _el$11=_$createElement("text"),_el$12=_$createTextNode(` `)
4572
- _$insertNode(_el$11,_el$12)
4573
- _$setProp(_el$11,"wrapMode","word")
4574
- _$insert(_el$11,()=>icons.icon("selected"),_el$12)
4575
- _$insert(_el$11,change,null)
4576
- _$effect((_$p)=>_$setProp(_el$11,"fg",theme().text,_$p))
4577
- return _el$11
4578
- })()
4579
- }),null)
4580
- _$effect((_p$)=>{var _v$3=theme().accent,_v$4=TextAttributes17.BOLD
4581
- _v$3!==_p$.e&&(_p$.e=_$setProp(_el$1,"fg",_v$3,_p$.e))
4582
- _v$4!==_p$.t&&(_p$.t=_$setProp(_el$1,"attributes",_v$4,_p$.t))
4583
- return _p$
4584
- },{e:undefined,t:undefined
4585
- })
4586
- return _el$0
4587
- })()
4588
- }))
4589
- _$effect((_$p)=>_$setProp(_el$6,"height",Math.max(4,Math.min(16,Math.floor(dimensions().height / 2))),_$p))
4590
- return _el$6
4591
- })(),_$createComponent(SelectionBox,{get backgroundColor(){return theme().primary
4592
- },paddingLeft:1,paddingRight:1,onMouseDown:(event)=>event.stopPropagation(),onMouseUp:(event)=>{event.stopPropagation()
4593
- dialogs.back()
4594
- },get children(){var _el$8=_$createElement("text")
4595
- _$insertNode(_el$8,_$createTextNode(`Continue`))
4596
- _$effect((_$p)=>_$setProp(_el$8,"fg",theme().selectedListItemText,_$p))
4597
- return _el$8
4598
- }})]
4599
- }})
4600
- }
4601
4635
  function UpgradeNotesBinding(props){let pending
4602
4636
  let disposed=false
4603
- onMount5(async ()=>{const previous=await props.preferences.claimNavigatorUpgrade(props.version)
4637
+ onMount6(async ()=>{const previous=await props.preferences.claimNavigatorUpgrade(props.version)
4604
4638
  if(!previous||disposed)
4605
4639
  return
4606
4640
  try{let show=function(){if(disposed||props.api.lifecycle.signal?.aborted)
@@ -4613,12 +4647,15 @@ createDialogStack(props.api,props.preferences.lspIconStyle,()=>true,props.prefer
4613
4647
  },entries
4614
4648
  }),"large")
4615
4649
  }
4650
+ const path=import.meta.url.includes("/dist/")?"./upgrade-notes.js":"./upgrade-notes-content"
4651
+ const{changesSince,readBundledChangelog,UpgradeNotesDialog
4652
+ }=await import(path)
4616
4653
  const entries=changesSince(await (props.read??readBundledChangelog)(),previous,props.version)
4617
4654
  if(entries.length===0||disposed)
4618
4655
  return
4619
4656
  show()
4620
4657
  } catch{}})
4621
- onCleanup15(()=>{disposed=true
4658
+ onCleanup17(()=>{disposed=true
4622
4659
  clearTimeout(pending)
4623
4660
  })
4624
4661
  return _$createElement("box")
@@ -4633,6 +4670,16 @@ return _$createElement("box")
4633
4670
 
4634
4671
 
4635
4672
 
4673
+
4674
+
4675
+
4676
+
4677
+
4678
+
4679
+
4680
+
4681
+
4682
+
4636
4683
 
4637
4684
 
4638
4685
 
@@ -4713,6 +4760,9 @@ return _el$
4713
4760
  })()
4714
4761
  }
4715
4762
 
4763
+
4764
+
4765
+
4716
4766
  function matchesFilter(query,...values){const needle=query.trim().toLocaleLowerCase()
4717
4767
  return !needle||values.some((value)=>value?.toLocaleLowerCase().includes(needle))
4718
4768
  }
@@ -4736,9 +4786,9 @@ return false
4736
4786
  return true
4737
4787
  }
4738
4788
  function createSidebarInteraction(api,showHelp=()=>openKeyboardHelp(api)){const descriptors=new Map
4739
- const [selectedId,setSelectedId]=createSignal18()
4740
- const [focusWithin,setFocusWithin]=createSignal18(false)
4741
- const [revision,setRevision]=createSignal18(0)
4789
+ const [selectedId,setSelectedId]=createSignal21()
4790
+ const [focusWithin,setFocusWithin]=createSignal21(false)
4791
+ const [revision,setRevision]=createSignal21(0)
4742
4792
  let titleRoot
4743
4793
  let contentRoot
4744
4794
  let targetedRoot
@@ -5007,14 +5057,14 @@ else if(highlighted)
5007
5057
  foregroundColor=theme.selectedListItemText
5008
5058
  return{backgroundColor,foregroundColor}}
5009
5059
  function useSidebarItem(api,interaction,descriptor,normalColor=()=>api.theme.current.text,mode="row"){let unregister
5010
- const [hovered,setHovered]=createSignal19(false)
5060
+ const [hovered,setHovered]=createSignal22(false)
5011
5061
  const disabled=()=>descriptor.disabled?.()===true
5012
5062
  const focused=()=>Boolean(interaction?.ownsFocus()&&interaction.isSelected(descriptor.id))
5013
5063
  const colors=()=>sidebarInteractiveColors(api.theme.current,{focused:focused(),hovered:hovered(),disabled:disabled()},normalColor(),mode)
5014
5064
  const ref=(renderable)=>{unregister?.()
5015
5065
  unregister=interaction?.register({...descriptor,renderable})
5016
5066
  }
5017
- onCleanup16(()=>unregister?.())
5067
+ onCleanup19(()=>unregister?.())
5018
5068
  return{ref,disabled,focused,backgroundColor:()=>colors().backgroundColor,foregroundColor:()=>colors().foregroundColor,onMouseOver:()=>setHovered(true),onMouseOut:()=>setHovered(false),select(event){interaction?.mouseSelect(descriptor.id,event)
5019
5069
  },activate(event){if(interaction)
5020
5070
  return interaction.mouseActivate(descriptor.id,event)
@@ -5025,7 +5075,7 @@ return true
5025
5075
  }}}
5026
5076
  function LspBadge(props){const icons=useIcons()
5027
5077
  const isKnown=lspIconName(props.id)!==undefined
5028
- const [showName,setShowName]=createSignal20(false)
5078
+ const [showName,setShowName]=createSignal23(false)
5029
5079
  const statusColor=()=>props.status==="connected"?props.api.theme.current.success:props.api.theme.current.error
5030
5080
  if(!isKnown){return(()=>{var _el$=_$createElement("text")
5031
5081
  _$setProp(_el$,"flexShrink",1)
@@ -5050,7 +5100,7 @@ _$setProp(_el$2,"flexShrink",0)
5050
5100
  _$insert(_el$2,()=>lspIcon(props.id,props.iconStyle??icons.style()))
5051
5101
  _$effect((_$p)=>_$setProp(_el$2,"fg",item.foregroundColor(),_$p))
5052
5102
  return _el$2
5053
- })(),_$createComponent(Show10,{get when(){return showName()
5103
+ })(),_$createComponent(Show11,{get when(){return showName()
5054
5104
  },get children(){var _el$3=_$createElement("text")
5055
5105
  _$setProp(_el$3,"flexShrink",0)
5056
5106
  _$setProp(_el$3,"wrapMode","none")
@@ -5068,7 +5118,7 @@ return _el$3
5068
5118
 
5069
5119
 
5070
5120
 
5071
- function createListVisibility(options){const [expanded,setExpanded]=createSignal21(false)
5121
+ function createListVisibility(options){const [expanded,setExpanded]=createSignal24(false)
5072
5122
  let previousKey
5073
5123
  let previousLimit
5074
5124
  const canToggle=createMemo8(()=>options.limit()>0&&options.items().length>options.limit())
@@ -5105,7 +5155,7 @@ else
5105
5155
  props.visibility.showAll()
5106
5156
  queueMicrotask(()=>props.interaction?.select(id))
5107
5157
  }})
5108
- return _$createComponent(Show11,{get when(){return props.visibility.canToggle()
5158
+ return _$createComponent(Show12,{get when(){return props.visibility.canToggle()
5109
5159
  },get children(){return _$createComponent(SelectionBox,{ref(r$){var _ref$=item.ref
5110
5160
  typeof _ref$==="function"?_ref$(r$):item.ref=r$
5111
5161
  },id,paddingLeft:1,paddingRight:1,get backgroundColor(){return item.backgroundColor()
@@ -5155,10 +5205,10 @@ result += segment
5155
5205
  }
5156
5206
  return result + ellipsis
5157
5207
  }
5158
- function SectionHeaderControl(props){const [width,setWidth]=createSignal22()
5208
+ function SectionHeaderControl(props){const [width,setWidth]=createSignal25()
5159
5209
  const control=useSidebarItem(props.api,props.interaction,{id:props.action.id,position:()=>props.position,disabled:props.action.disabled,activate:props.action.onActivate
5160
5210
  },()=>props.api.theme.current.accent,"control")
5161
- createEffect13(on(()=>[props.action.label(),props.resetWidth],()=>setWidth(undefined)))
5211
+ createEffect14(on(()=>[props.action.label(),props.resetWidth],()=>setWidth(undefined)))
5162
5212
  const label=()=>width()===undefined||props.iconOnly?props.action.label():truncateEnd(props.action.label(),width()-2)
5163
5213
  return _$createComponent(SelectionBox,{ref:(node)=>control.ref(node),get id(){return props.action.id
5164
5214
  },get iconOnly(){return props.iconOnly
@@ -5180,7 +5230,7 @@ return _el$
5180
5230
  }})
5181
5231
  }
5182
5232
  function Section(props){const icons=useIcons()
5183
- const [headerWidth,setHeaderWidth]=createSignal23(0)
5233
+ const [headerWidth,setHeaderWidth]=createSignal26(0)
5184
5234
  const icon=()=>props.section?icons.section(props.section):props.icon
5185
5235
  const theme=()=>props.api.theme.current
5186
5236
  const item=useSidebarItem(props.api,props.interaction,{id:props.sectionId??`section.${props.title}`,position:()=>({section:props.navigationSection??0,row:0,column:0
@@ -5222,7 +5272,7 @@ _$setProp(_el$7,"flexGrow",1)
5222
5272
  _$setProp(_el$7,"minWidth",0)
5223
5273
  _$setProp(_el$7,"justifyContent","flex-end")
5224
5274
  _$insert(_el$7,()=>props.headerControls,null)
5225
- _$insert(_el$7,_$createComponent(Show12,{get when(){return props.headerAction
5275
+ _$insert(_el$7,_$createComponent(Show13,{get when(){return props.headerAction
5226
5276
  },children:(action)=>_$createComponent(SectionHeaderControl,{get api(){return props.api
5227
5277
  },get interaction(){return props.interaction
5228
5278
  },get action(){return action()
@@ -5230,7 +5280,7 @@ _$insert(_el$7,_$createComponent(Show12,{get when(){return props.headerAction
5230
5280
  },get position(){return{section:props.navigationSection??0,row:0,column:1
5231
5281
  }}})
5232
5282
  }),null)
5233
- _$insert(_el$7,_$createComponent(Show12,{get when(){return props.summary
5283
+ _$insert(_el$7,_$createComponent(Show13,{get when(){return props.summary
5234
5284
  },get children(){var _el$8=_$createElement("text")
5235
5285
  _$setProp(_el$8,"wrapMode","none")
5236
5286
  _$setProp(_el$8,"truncate",true)
@@ -5247,7 +5297,7 @@ return _el$8
5247
5297
  return _el$7
5248
5298
  })()]
5249
5299
  }}),null)
5250
- _$insert(_el$,_$createComponent(Show12,{get when(){return props.open
5300
+ _$insert(_el$,_$createComponent(Show13,{get when(){return props.open
5251
5301
  },get children(){return props.children
5252
5302
  }}),null)
5253
5303
  return _el$
@@ -5265,7 +5315,7 @@ return _$createComponent(Section,{get api(){return props.api
5265
5315
  },sectionId:`${PLUGIN_ID}.section.lsp`,get navigationSection(){return navigationSection()
5266
5316
  },title:"LSP",section:"lsp",get summary(){return `${connected()}/${list().length}`
5267
5317
  },get open(){return props.preferences.expanded().lsp
5268
- },onToggle:()=>props.preferences.toggleSectionExpanded("lsp"),get children(){return [_$createComponent(Show13,{get when(){return list().length>0
5318
+ },onToggle:()=>props.preferences.toggleSectionExpanded("lsp"),get children(){return [_$createComponent(Show14,{get when(){return list().length>0
5269
5319
  },get fallback(){return(()=>{var _el$2=_$createElement("text")
5270
5320
  _$insert(_el$2,()=>disabled()?"LSP is disabled":"Activates as files are read")
5271
5321
  _$effect((_$p)=>_$setProp(_el$2,"fg",props.api.theme.current.textMuted,_$p))
@@ -5390,7 +5440,7 @@ _$insert(_el$,_$createComponent(McpBulkAction,{get api(){return props.api
5390
5440
  }),null)
5391
5441
  _$effect((_$p)=>_$setProp(_el$,"paddingBottom",model.bulkRunning()||model.bulk().status==="error"?1:0,_$p))
5392
5442
  return _el$
5393
- })(),_$createComponent(Show14,{get when(){return model.bulkRunning()
5443
+ })(),_$createComponent(Show15,{get when(){return model.bulkRunning()
5394
5444
  },get children(){var _el$2=_$createElement("text"),_el$3=_$createTextNode(` `),_el$4=_$createTextNode(`/`),_el$5=_$createTextNode(`\u2026`)
5395
5445
  _$insertNode(_el$2,_el$3)
5396
5446
  _$insertNode(_el$2,_el$4)
@@ -5400,7 +5450,7 @@ _$insert(_el$2,()=>model.bulk().completed,_el$4)
5400
5450
  _$insert(_el$2,()=>model.bulk().total,_el$5)
5401
5451
  _$effect((_$p)=>_$setProp(_el$2,"fg",props.api.theme.current.textMuted,_$p))
5402
5452
  return _el$2
5403
- }}),_$createComponent(Show14,{get when(){return model.bulk().status==="error"
5453
+ }}),_$createComponent(Show15,{get when(){return model.bulk().status==="error"
5404
5454
  },get children(){return _$createComponent(McpBulkAction,{get api(){return props.api
5405
5455
  },get interaction(){return props.interaction
5406
5456
  },id:`${PLUGIN_ID}.mcp.retry-all`,get position(){return{section:props.navigationSection,row:3,column:0
@@ -5480,7 +5530,7 @@ return _el$4
5480
5530
  function RequestErrorRow(props){const icons=useIcons()
5481
5531
  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
5482
5532
  })
5483
- return _$createComponent(Show15,{get when(){return props.state.error
5533
+ return _$createComponent(Show16,{get when(){return props.state.error
5484
5534
  },children:(error)=>_$createComponent(SelectionBox,{ref:(node)=>item.ref(node),get id(){return props.id
5485
5535
  },flexDirection:"row",gap:1,paddingLeft:1,paddingRight:1,get backgroundColor(){return item.backgroundColor()
5486
5536
  },get onMouseOver(){return item.onMouseOver
@@ -5495,7 +5545,7 @@ _$insert(_el$,()=>icons.icon("error"),_el$2)
5495
5545
  _$insert(_el$,()=>error().message,null)
5496
5546
  _$effect((_$p)=>_$setProp(_el$,"fg",item.focused()?item.foregroundColor():props.api.theme.current.error,_$p))
5497
5547
  return _el$
5498
- })(),_$createComponent(Show15,{get when(){return error().retryable
5548
+ })(),_$createComponent(Show16,{get when(){return error().retryable
5499
5549
  },get children(){var _el$3=_$createElement("text"),_el$4=_$createTextNode(` Retry`)
5500
5550
  _$insertNode(_el$3,_el$4)
5501
5551
  _$setProp(_el$3,"flexShrink",0)
@@ -5510,7 +5560,7 @@ function SectionRequestBody(props){const icons=useIcons()
5510
5560
  const pending=()=>props.state.status==="loading"
5511
5561
  return(()=>{var _el$5=_$createElement("box")
5512
5562
  _$insert(_el$5,_$createComponent(RequestErrorRow,props),null)
5513
- _$insert(_el$5,_$createComponent(Show15,{get when(){return _$memo(()=>!!pending())()&&!props.hasItems
5563
+ _$insert(_el$5,_$createComponent(Show16,{get when(){return _$memo(()=>!!pending())()&&!props.hasItems
5514
5564
  },get children(){var _el$6=_$createElement("text"),_el$7=_$createTextNode(` `)
5515
5565
  _$insertNode(_el$6,_el$7)
5516
5566
  _$insert(_el$6,()=>icons.icon("pending"),_el$7)
@@ -5518,10 +5568,10 @@ _$insert(_el$6,()=>props.loading,null)
5518
5568
  _$effect((_$p)=>_$setProp(_el$6,"fg",props.api.theme.current.textMuted,_$p))
5519
5569
  return _el$6
5520
5570
  }}),null)
5521
- _$insert(_el$5,_$createComponent(Show15,{get when(){return props.hasItems
5571
+ _$insert(_el$5,_$createComponent(Show16,{get when(){return props.hasItems
5522
5572
  },get children(){return props.children
5523
5573
  }}),null)
5524
- _$insert(_el$5,_$createComponent(Show15,{get when(){return _$memo(()=>!!((props.state.status==="ready"||props.state.status==="refreshing")&&!props.hasItems))()&&!props.state.error
5574
+ _$insert(_el$5,_$createComponent(Show16,{get when(){return _$memo(()=>!!((props.state.status==="ready"||props.state.status==="refreshing")&&!props.hasItems))()&&!props.state.error
5525
5575
  },get children(){var _el$8=_$createElement("text"),_el$9=_$createTextNode(` `)
5526
5576
  _$insertNode(_el$8,_el$9)
5527
5577
  _$insert(_el$8,()=>icons.icon("info"),_el$9)
@@ -5538,8 +5588,8 @@ return _el$5
5538
5588
  function createSidebarBookmark(input){const{api,interaction,row,position,favorite,disabled,onToggle
5539
5589
  }=input
5540
5590
  const id=`${input.id}.favorite`
5541
- const [rowHovered,setRowHovered]=createSignal24(false)
5542
- const [controlHovered,setControlHovered]=createSignal24(false)
5591
+ const [rowHovered,setRowHovered]=createSignal27(false)
5592
+ const [controlHovered,setControlHovered]=createSignal27(false)
5543
5593
  const control=useSidebarItem(api,interaction,{id,position:()=>({...position(),column:0
5544
5594
  }),disabled,activate:()=>{onToggle()
5545
5595
  queueMicrotask(()=>interaction?.select(id))
@@ -5655,7 +5705,7 @@ return _el$2
5655
5705
  function SectionFilter(props){const icons=useIcons()
5656
5706
  let input
5657
5707
  let unregisterInput
5658
- const [inputFocused,setInputFocused]=createSignal25(false)
5708
+ const [inputFocused,setInputFocused]=createSignal28(false)
5659
5709
  const theme=()=>props.api.theme.current
5660
5710
  const item=useSidebarItem(props.api,props.interaction,{id:props.id??`filter.${props.placeholder}`,position:()=>props.position??{section:0,row:0,column:0
5661
5711
  },activate:()=>{if(!input)
@@ -5676,7 +5726,7 @@ props.interaction.leaveFilter(input)
5676
5726
  else
5677
5727
  input?.blur()
5678
5728
  }
5679
- onCleanup17(()=>unregisterInput?.())
5729
+ onCleanup20(()=>unregisterInput?.())
5680
5730
  return _$createComponent(SelectionBox,{ref:(node)=>item.ref(node),get id(){return props.id
5681
5731
  },flexDirection:"row",gap:1,marginTop:1,marginBottom:1,paddingLeft:1,paddingRight:1,get backgroundColor(){return _$memo(()=>!!highlighted())()?theme().primary:item.backgroundColor()
5682
5732
  },get onMouseOver(){return item.onMouseOver
@@ -5714,7 +5764,7 @@ return _p$
5714
5764
  },{e:undefined,t:undefined,a:undefined,o:undefined,i:undefined,n:undefined,s:undefined,h:undefined
5715
5765
  })
5716
5766
  return _el$2
5717
- })(),_$createComponent(Show16,{get when(){return props.query
5767
+ })(),_$createComponent(Show17,{get when(){return props.query
5718
5768
  },get children(){var _el$3=_$createElement("text")
5719
5769
  _$setProp(_el$3,"flexShrink",0)
5720
5770
  _$setProp(_el$3,"onMouseDown",()=>props.onInput(""))
@@ -5743,7 +5793,7 @@ _$insert(_el$,_$createComponent(SectionFilter,{get api(){return props.api
5743
5793
  }},get query(){return props.query
5744
5794
  },placeholder:"Filter MCP...",get onInput(){return props.onQuery
5745
5795
  }}),null)
5746
- _$insert(_el$,_$createComponent(Show17,{get when(){return model.filtered().length>0
5796
+ _$insert(_el$,_$createComponent(Show18,{get when(){return model.filtered().length>0
5747
5797
  },get fallback(){return(()=>{var _el$2=_$createElement("text")
5748
5798
  _$insertNode(_el$2,_$createTextNode(`No matching MCP servers`))
5749
5799
  _$effect((_$p)=>_$setProp(_el$2,"fg",props.api.theme.current.textMuted,_$p))
@@ -5754,7 +5804,7 @@ return _el$2
5754
5804
  },get grouped(){return model.grouped
5755
5805
  },get density(){return props.preferences.rowDensity?.()??"compact"
5756
5806
  },get children(){return _$createComponent(For13,{get each(){return model.visibility.visible()
5757
- },children:(item,index)=>[_$createComponent(Show17,{get when(){return _$memo(()=>!!model.grouped())()&&(index()===0||model.visibility.visible()[index()-1]?.bucket!==item.bucket)
5807
+ },children:(item,index)=>[_$createComponent(Show18,{get when(){return _$memo(()=>!!model.grouped())()&&(index()===0||model.visibility.visible()[index()-1]?.bucket!==item.bucket)
5758
5808
  },get children(){return _$createComponent(McpGroupHeader,{get api(){return props.api
5759
5809
  },get interaction(){return props.interaction
5760
5810
  },get bucket(){return item.bucket
@@ -5785,7 +5835,7 @@ return _el$
5785
5835
  }})
5786
5836
  }
5787
5837
  function McpSection(props){const icons=useIcons()
5788
- const [query,setQuery]=createSignal26("")
5838
+ const [query,setQuery]=createSignal29("")
5789
5839
  const model=createMcpSectionModel(props,query)
5790
5840
  const navigationSection=()=>props.navigationSection??6
5791
5841
  const summary=createMemo11(()=>`${model.active()}/${model.list().length}${model.errors() ? ` \xB7 ${model.errors()} ${icons.icon("error")}` : ""}`)
@@ -5886,6 +5936,7 @@ return _$createComponent(SectionWithHeaderAction,{get api(){return props.api
5886
5936
 
5887
5937
 
5888
5938
 
5939
+
5889
5940
 
5890
5941
 
5891
5942
  var ToolbarContext=createContext4()
@@ -5924,7 +5975,7 @@ function QuickActionRow(props){const{api,interaction
5924
5975
  const icons=useIcons()
5925
5976
  const toolbar=useToolbar()
5926
5977
  const theme=()=>api.theme.current
5927
- const [width,setWidth]=createSignal30(0)
5978
+ const [width,setWidth]=createSignal34(0)
5928
5979
  const shortcut=createMemo12(()=>{const bindings=api.keymap.getCommandBindings({visibility:"registered",commands:[props.action.command]
5929
5980
  })
5930
5981
  return api.keys.formatBindings(bindings.get(props.action.command))
@@ -5968,7 +6019,7 @@ _$insert(_el$2,()=>props.action.label)
5968
6019
  _$effect((_$p)=>_$setProp(_el$2,"fg",row.foregroundColor(),_$p))
5969
6020
  return _el$2
5970
6021
  })()
5971
- },get metadata(){return _$createComponent(Show24,{get when(){return visibleShortcut()
6022
+ },get metadata(){return _$createComponent(Show25,{get when(){return visibleShortcut()
5972
6023
  },children:(value)=>(()=>{var _el$3=_$createElement("text")
5973
6024
  _$setProp(_el$3,"flexShrink",0)
5974
6025
  _$setProp(_el$3,"wrapMode","none")
@@ -5977,12 +6028,12 @@ _$effect((_$p)=>_$setProp(_el$3,"fg",row.focused()?row.foregroundColor():theme()
5977
6028
  return _el$3
5978
6029
  })()
5979
6030
  })
5980
- },get trailing(){return _$createComponent(Show24,{when:toolbar,get children(){return _$createComponent(SidebarPinControl,{get id(){return id()
6031
+ },get trailing(){return _$createComponent(Show25,{when:toolbar,get children(){return _$createComponent(SidebarPinControl,{get id(){return id()
5981
6032
  },get position(){return props.position
5982
6033
  },get pin(){return{kind:"action",id:props.action.command,icon:"bolt"
5983
6034
  }}})
5984
6035
  }})
5985
- },get details(){return _$createComponent(Show24,{get when(){return props.disabled
6036
+ },get details(){return _$createComponent(Show25,{get when(){return props.disabled
5986
6037
  },children:(reason)=>(()=>{var _el$4=_$createElement("text")
5987
6038
  _$setProp(_el$4,"wrapMode","word")
5988
6039
  _$insert(_el$4,reason)
@@ -6010,18 +6061,19 @@ return _$createComponent(Section,{get api(){return props.api
6010
6061
  },onToggle:()=>props.preferences.toggleSectionExpanded("quick_actions"),get children(){return [_$createComponent(SidebarRowList,{get api(){return props.api
6011
6062
  },get interaction(){return props.interaction
6012
6063
  },get density(){return props.preferences.rowDensity?.()??"compact"
6013
- },get children(){return [_$createComponent(Show25,{get when(){return actions().length===0
6064
+ },get children(){return [_$createComponent(Show26,{get when(){return actions().length===0
6014
6065
  },get children(){var _el$=_$createElement("text")
6015
6066
  _$insertNode(_el$,_$createTextNode(`No quick actions selected`))
6016
6067
  _$effect((_$p)=>_$setProp(_el$,"fg",props.api.theme.current.textMuted,_$p))
6017
6068
  return _el$
6018
- }}),_$createComponent(For16,{get each(){return visibility.visible()
6019
- },children:(action,index)=>_$createComponent(QuickActionRow,{get onNewSession(){return props.onNewSession
6020
- },action,get disabled(){return action.disabled
6021
- },get favorite(){return props.preferences.favoriteQuickActions?.().has(action.command)??false
6069
+ }}),_$createComponent(For16,{get each(){return visibility.visible().map((action)=>action.command)
6070
+ },children:(id,index)=>_$createComponent(QuickActionRow,{get onNewSession(){return props.onNewSession
6071
+ },get action(){return visibility.visible()[index()]
6072
+ },get disabled(){return visibility.visible()[index()].disabled
6073
+ },get favorite(){return props.preferences.favoriteQuickActions?.().has(id)??false
6022
6074
  },get favoriteDisabled(){return _$memo(()=>!!props.preferences.ready)()?!props.preferences.ready():false
6023
- },get separator(){return _$memo(()=>!!(index()>0&&(props.preferences.favoriteQuickActions?.().has(visibility.visible()[index()-1].command)??false)))()&&!(props.preferences.favoriteQuickActions?.().has(action.command)??false)
6024
- },onToggleFavorite:()=>props.preferences.toggleFavoriteQuickAction?.(action.command),get position(){return{section:navigationSection(),row:10 + index(),column:0
6075
+ },get separator(){return _$memo(()=>!!(index()>0&&(props.preferences.favoriteQuickActions?.().has(visibility.visible()[index()-1].command)??false)))()&&!(props.preferences.favoriteQuickActions?.().has(id)??false)
6076
+ },onToggleFavorite:()=>props.preferences.toggleFavoriteQuickAction?.(id),get position(){return{section:navigationSection(),row:10 + index(),column:0
6025
6077
  }}})
6026
6078
  })]
6027
6079
  }}),_$createComponent(ListVisibilityControl,{get api(){return props.api
@@ -6076,20 +6128,20 @@ item.activate(event)
6076
6128
 
6077
6129
 
6078
6130
  function SidebarToggleBinding(props){const shortcuts=createSidebarShortcutMode(props.api)
6079
- createEffect15(()=>{const key=props.preferences.toggleKey()
6131
+ createEffect16(()=>{const key=props.preferences.toggleKey()
6080
6132
  untrack6(()=>shortcuts.bind(key))
6081
6133
  })
6082
- createEffect15(()=>{if(shortcuts.active()&&(props.api.route.current.name!=="session"||props.api.ui.dialog.open||props.api.mode.current()==="modal"))
6134
+ createEffect16(()=>{if(shortcuts.active()&&(props.api.route.current.name!=="session"||props.api.ui.dialog.open||props.api.mode.current()==="modal"))
6083
6135
  untrack6(shortcuts.cancel)
6084
6136
  })
6085
- onCleanup18(shortcuts.dispose)
6137
+ onCleanup21(shortcuts.dispose)
6086
6138
  return(()=>{var _el$=_$createElement("box")
6087
6139
  _$setProp(_el$,"position","absolute")
6088
6140
  _$setProp(_el$,"top",0)
6089
6141
  _$setProp(_el$,"left",0)
6090
6142
  _$setProp(_el$,"width","100%")
6091
6143
  _$setProp(_el$,"height","100%")
6092
- _$insert(_el$,_$createComponent(Show26,{get when(){return shortcuts.active()
6144
+ _$insert(_el$,_$createComponent(Show27,{get when(){return shortcuts.active()
6093
6145
  },get children(){return _$createComponent(Suspense4,{get children(){return _$createComponent(SidebarShortcutHint,{get api(){return props.api
6094
6146
  },get actions(){return shortcuts.actions
6095
6147
  }})
@@ -6104,11 +6156,11 @@ const unregisterCommands=props.api.keymap.registerLayer({commands:[...commands,.
6104
6156
  })=>({name:name.replace(PLUGIN_ID,()=>LEGACY_PLUGIN_ID),run,enabled
6105
6157
  }))]
6106
6158
  })
6107
- onCleanup18(unregisterCommands)
6108
- createEffect15(()=>{const unregister=props.api.keymap.registerLayer({bindings:[{key:props.preferences.focusKey(),cmd:FOCUS_COMMAND
6159
+ onCleanup21(unregisterCommands)
6160
+ createEffect16(()=>{const unregister=props.api.keymap.registerLayer({bindings:[{key:props.preferences.focusKey(),cmd:FOCUS_COMMAND
6109
6161
  }]
6110
6162
  })
6111
- onCleanup18(unregister)
6163
+ onCleanup21(unregister)
6112
6164
  })
6113
6165
  return _$createElement("box")
6114
6166
  }
@@ -6128,24 +6180,53 @@ return _$createElement("box")
6128
6180
 
6129
6181
 
6130
6182
 
6131
- function toolbarLayout(keys,width,mode){const columns=Math.max(1,Math.floor((Math.max(3,width) + 1) / 4))
6132
- const shown=mode==="wrap"||keys.length<=columns?keys.length:Math.max(0,columns-1)
6133
- const visible=keys.slice(0,shown)
6134
- const overflow=keys.slice(shown)
6135
- const controls=[...visible,...overflow.length>0?["toolbar:more"]:[]]
6136
- return{columns,overflow,rows:Array.from({length:Math.ceil(controls.length / columns)},(_,row)=>controls.slice(row*columns,(row + 1)*columns))
6137
- }}
6183
+ function toolbarLayout(keys,width,mode,widths){const capacity=Math.max(3,Math.floor(width))
6184
+ const columns=Math.max(1,Math.floor((capacity + 1) / 4))
6185
+ const sizes={}
6186
+ const size=(key)=>Math.max(3,Math.min(capacity,widths?.get(key)??3))
6187
+ const rows=[]
6188
+ let overflow=[]
6189
+ if(mode==="wrap"){let used=0
6190
+ for(const key of keys){const value=size(key)
6191
+ if(rows.length===0||used>0&&used + 1 + value>capacity){rows.push([])
6192
+ used=0
6193
+ }
6194
+ rows.at(-1).push(key)
6195
+ sizes[key]=value
6196
+ used += (used?1:0) + value
6197
+ }} else if(keys.length>0){const fits=keys.reduce((total,key)=>total + size(key),0) + keys.length-1<=capacity
6198
+ const visible=[]
6199
+ let used=0
6200
+ for(const key of keys){const remaining=(fits?capacity:capacity-4)-used-(visible.length>0?1:0)
6201
+ if(remaining<3)
6202
+ break
6203
+ sizes[key]=Math.min(size(key),remaining)
6204
+ used += (visible.length>0?1:0) + sizes[key]
6205
+ visible.push(key)
6206
+ }
6207
+ overflow=keys.slice(visible.length)
6208
+ if(overflow.length>0){visible.push("toolbar:more")
6209
+ sizes["toolbar:more"]=3
6210
+ }
6211
+ rows.push(visible)
6212
+ }
6213
+ return{columns,overflow,rows,...widths&&{sizes}}}
6138
6214
 
6215
+ function toolbarPinWidth(pin){const states=Object.keys({...pin.stateIcons,...pin.stateIconLists})
6216
+ const count=Math.max(toolbarPinIcons(pin).length,...states.map((state)=>toolbarPinIcons(pin,state).length))
6217
+ const iconsWidth=Math.max(0,count*2-1)
6218
+ return 2 + Math.max(1,iconsWidth + (count&&pin.text?1:0) + Bun.stringWidth(pin.text??""))
6219
+ }
6139
6220
  function createToolbarModel(props){const icons=useIcons()
6140
6221
  const revision=createQuickActionRevision(props.api)
6141
6222
  const pins=()=>props.preferences.toolbarPins?.()??[]
6142
6223
  const needsSkills=createMemo14(()=>pins().some((pin)=>pin.kind==="skill"))
6143
6224
  const target=createMemo14(()=>props.skills.target())
6144
- createEffect16(()=>{if(!needsSkills())
6225
+ createEffect17(()=>{if(!needsSkills())
6145
6226
  return
6146
6227
  const current=target()
6147
6228
  const release=untrack7(()=>props.skills.activate(current))
6148
- onCleanup19(release)
6229
+ onCleanup22(release)
6149
6230
  untrack7(()=>{props.skills.refresh(current).catch(()=>{})
6150
6231
  })
6151
6232
  })
@@ -6153,12 +6234,12 @@ function view(pin){revision()
6153
6234
  if(pin.kind==="action"){const action=QUICK_ACTIONS.find((item)=>item.command===pin.id)
6154
6235
  const state=quickActionState(props.api,pin.id)
6155
6236
  const stateLabel=quickActionStates(props.api,pin.id).find((item)=>item.id===state)?.label
6156
- return{label:quickActionLabel(props.api,action),stateLabel,icon:state?pin.stateIcons?.[state]??pin.icon:pin.icon,reason:quickActionDisabledReason(props.api,action)
6237
+ return{label:quickActionLabel(props.api,action),stateLabel,icons:toolbarPinIcons(pin,state),text:pin.text,reason:quickActionDisabledReason(props.api,action)
6157
6238
  }}
6158
6239
  const skill=props.skills.list(target()).find((item)=>item.location===pin.location&&item.name===pin.name)
6159
6240
  const request=props.skills.state(target())
6160
6241
  const unavailable=request.status==="loading"?"Loading Skills":"Skill is unavailable in this workspace"
6161
- return{label:pin.name,icon:pin.icon,stateLabel:undefined,reason:request.error?.message??(skill?skillUnavailable(props.skills,skill):unavailable)
6242
+ return{label:pin.name,icons:toolbarPinIcons(pin),text:pin.text,stateLabel:undefined,reason:request.error?.message??(skill?skillUnavailable(props.skills,skill):unavailable)
6162
6243
  }}
6163
6244
  function run(key){const pin=pins().find((item)=>toolbarPinKey(item)===key)
6164
6245
  if(!pin)
@@ -6181,36 +6262,68 @@ const route=JSON.stringify(props.api.route.current)
6181
6262
  const dialogs=createDialogStack(props.api,icons.style,()=>route===JSON.stringify(props.api.route.current),icons.multilineCorners)
6182
6263
  activateSkill({api:props.api,controller:props.skills,access:props.preferences,skill,dialogs})
6183
6264
  }
6184
- return{pins,view,run}}
6265
+ return{pins,view,run,width:toolbarPinWidth}}
6266
+
6267
+
6268
+
6269
+
6185
6270
 
6186
6271
 
6187
6272
 
6188
6273
  function ToolbarButton(props){const icons=useIcons()
6189
- const [hovered,setHovered]=createSignal31(false)
6274
+ const foreground=()=>props.reason?props.api.theme.current.textMuted:item.foregroundColor()
6275
+ const [hovered,setHovered]=createSignal35(false)
6190
6276
  const item=useSidebarItem(props.api,props.interaction,{id:props.id,position:()=>({section:0,row:props.row + 1,column:props.column
6191
6277
  }),activate:props.onRun
6192
6278
  },()=>props.reason?props.api.theme.current.textMuted:props.api.theme.current.accent,"control")
6193
- createEffect17(()=>props.onDetails(props.id,item.focused()||hovered()))
6194
- onCleanup20(()=>props.onDetails(props.id,false))
6195
- return _$createComponent(IconControl,{get id(){return props.id
6279
+ const content=()=>[props.icons.map((icon)=>terminalIcon(icon,icons.style())).join(" "),props.text].filter(Boolean).join(" ")
6280
+ createEffect18(()=>props.onDetails(props.id,item.focused()||hovered()))
6281
+ onCleanup23(()=>props.onDetails(props.id,false))
6282
+ return _$createComponent(Show28,{get when(){return _$memo(()=>!!(props.width===3&&props.icons.length===1))()&&!props.text
6283
+ },get fallback(){return _$createComponent(SelectionBox,{get id(){return props.id
6284
+ },ref(r$){var _ref$2=item.ref
6285
+ typeof _ref$2==="function"?_ref$2(r$):item.ref=r$
6286
+ },get width(){return props.width
6287
+ },height:1,flexShrink:0,alignItems:"center",justifyContent:"center",get backgroundColor(){return item.backgroundColor()
6288
+ },onMouseOver:(event)=>{event.stopPropagation()
6289
+ item.onMouseOver()
6290
+ setHovered(true)
6291
+ },onMouseOut:(event)=>{event.stopPropagation()
6292
+ item.onMouseOut()
6293
+ setHovered(false)
6294
+ },onMouseDown:(event)=>event.stopPropagation(),onMouseUp:(event)=>{event.stopPropagation()
6295
+ item.activate(event)
6296
+ },get children(){var _el$=_$createElement("text")
6297
+ _$setProp(_el$,"height",1)
6298
+ _$setProp(_el$,"minWidth",0)
6299
+ _$setProp(_el$,"maxWidth","100%")
6300
+ _$setProp(_el$,"truncate",true)
6301
+ _$setProp(_el$,"wrapMode","none")
6302
+ _$insert(_el$,content)
6303
+ _$effect((_$p)=>_$setProp(_el$,"fg",foreground(),_$p))
6304
+ return _el$
6305
+ }})
6306
+ },get children(){return _$createComponent(IconControl,{get id(){return props.id
6196
6307
  },ref(r$){var _ref$=item.ref
6197
6308
  typeof _ref$==="function"?_ref$(r$):item.ref=r$
6198
- },get icon(){return terminalIcon(props.icon,icons.style())
6309
+ },get icon(){return terminalIcon(props.icons[0]??"bolt",icons.style())
6199
6310
  },get backgroundColor(){return item.backgroundColor()
6200
- },get foregroundColor(){return _$memo(()=>!!props.reason)()?props.api.theme.current.textMuted:item.foregroundColor()
6311
+ },get foregroundColor(){return foreground()
6201
6312
  },onMouseOver:()=>{item.onMouseOver()
6202
6313
  setHovered(true)
6203
6314
  },onMouseOut:()=>{item.onMouseOut()
6204
6315
  setHovered(false)
6205
6316
  },onMouseUp:(event)=>item.activate(event)
6206
6317
  })
6318
+ }})
6207
6319
  }
6208
6320
  function SidebarToolbar(props){const model=createToolbarModel(props)
6209
6321
  const icons=useIcons()
6210
- const [width,setWidth]=createSignal32(3)
6211
- const [detail,setDetail]=createSignal32()
6322
+ const [width,setWidth]=createSignal36(3)
6323
+ const [detail,setDetail]=createSignal36()
6212
6324
  const keys=createMemo15(()=>model.pins().map((pin)=>toolbarPinKey(pin)))
6213
- const layout=createMemo15(()=>toolbarLayout(keys(),width(),props.preferences.toolbarOverflow?.()??"menu"))
6325
+ const widths=createMemo15(()=>new Map(model.pins().map((pin)=>[toolbarPinKey(pin),model.width(pin)])))
6326
+ const layout=createMemo15(()=>toolbarLayout(keys(),width(),props.preferences.toolbarOverflow?.()??"menu",widths()))
6214
6327
  const rows=createMemo15(()=>layout().rows.map((_,index)=>index))
6215
6328
  const byKey=createMemo15(()=>new Map(model.pins().map((pin)=>[toolbarPinKey(pin),pin])))
6216
6329
  const view=(key)=>{const pin=byKey().get(key)
@@ -6235,9 +6348,10 @@ dialogs.close()
6235
6348
  model.run(option.value)
6236
6349
  }}))
6237
6350
  }
6238
- return _$createComponent(Show27,{get when(){return keys().length>0
6351
+ return _$createComponent(Show29,{get when(){return keys().length>0
6239
6352
  },get children(){var _el$=_$createElement("box")
6240
6353
  _$setProp(_el$,"id","opencode-navigator.toolbar")
6354
+ _$setProp(_el$,"overflow","visible")
6241
6355
  _$setProp(_el$,"onSizeChange",function(){setWidth(this.width)
6242
6356
  })
6243
6357
  _$insert(_el$,_$createComponent(For17,{get each(){return rows()
@@ -6247,7 +6361,9 @@ _$setProp(_el$2,"gap",1)
6247
6361
  _$insert(_el$2,_$createComponent(For17,{get each(){return layout().rows[row]
6248
6362
  },children:(key,column)=>_$createComponent(ToolbarButton,_$mergeProps(props,{id:`opencode-navigator.toolbar.${key}`,row,get column(){return column()
6249
6363
  },get label(){return view(key)?.label??"More"
6250
- },get icon(){return key==="toolbar:more"?"list":view(key)?.icon??"bolt"
6364
+ },get icons(){return key==="toolbar:more"?["list"]:view(key)?.icons??["bolt"]
6365
+ },get text(){return view(key)?.text
6366
+ },get width(){return layout().sizes?.[key]??3
6251
6367
  },get reason(){return view(key)?.reason
6252
6368
  },onRun:()=>key==="toolbar:more"?showMore():model.run(key),onDetails:(_id,active)=>setDetail((current)=>active?key:current===key?undefined:current)
6253
6369
  }))
@@ -6255,13 +6371,21 @@ _$insert(_el$2,_$createComponent(For17,{get each(){return layout().rows[row]
6255
6371
  return _el$2
6256
6372
  })()
6257
6373
  }),null)
6258
- _$insert(_el$,_$createComponent(Show27,{get when(){return details()
6374
+ _$insert(_el$,_$createComponent(Show29,{get when(){return details()
6259
6375
  },children:(text)=>(()=>{var _el$3=_$createElement("text")
6376
+ _$setProp(_el$3,"position","absolute")
6377
+ _$setProp(_el$3,"left",0)
6378
+ _$setProp(_el$3,"width","100%")
6260
6379
  _$setProp(_el$3,"height",1)
6261
6380
  _$setProp(_el$3,"truncate",true)
6262
6381
  _$setProp(_el$3,"wrapMode","none")
6263
6382
  _$insert(_el$3,text)
6264
- _$effect((_$p)=>_$setProp(_el$3,"fg",props.api.theme.current.textMuted,_$p))
6383
+ _$effect((_p$)=>{var _v$=rows().length,_v$2=props.api.theme.current.textMuted
6384
+ _v$!==_p$.e&&(_p$.e=_$setProp(_el$3,"top",_v$,_p$.e))
6385
+ _v$2!==_p$.t&&(_p$.t=_$setProp(_el$3,"fg",_v$2,_p$.t))
6386
+ return _p$
6387
+ },{e:undefined,t:undefined
6388
+ })
6265
6389
  return _el$3
6266
6390
  })()
6267
6391
  }),null)
@@ -6287,9 +6411,9 @@ const filtered=createMemo16(()=>list().filter((item)=>matchesFilter(query(),item
6287
6411
  const visibility=createListVisibility({items:filtered,limit:()=>props.preferences.sectionItemLimit?.("skills")??0,resetKey:()=>JSON.stringify([target().key,query()])
6288
6412
  })
6289
6413
  const state=createMemo16(()=>props.controller.state(target()))
6290
- createEffect18(()=>{const current=target()
6414
+ createEffect19(()=>{const current=target()
6291
6415
  const deactivate=untrack8(()=>props.controller.activate?.(current)??(()=>{}))
6292
- onCleanup21(deactivate)
6416
+ onCleanup24(deactivate)
6293
6417
  untrack8(()=>void props.controller.refresh(current).catch(()=>{}))
6294
6418
  })
6295
6419
  async function useSkill(item){try{const isInserted=await props.controller.use(target(),item.name)
@@ -6341,7 +6465,7 @@ _$insert(_el$,()=>props.item.name,null)
6341
6465
  _$effect((_$p)=>_$setProp(_el$,"fg",row.foregroundColor(),_$p))
6342
6466
  return _el$
6343
6467
  })()
6344
- },get trailing(){return _$createComponent(Show28,{when:toolbar,get children(){return _$createComponent(SidebarPinControl,{get id(){return id()
6468
+ },get trailing(){return _$createComponent(Show30,{when:toolbar,get children(){return _$createComponent(SidebarPinControl,{get id(){return id()
6345
6469
  },get position(){return props.position
6346
6470
  },get pin(){return{kind:"skill",name:props.item.name,location:props.item.location,icon:"book"
6347
6471
  }}})
@@ -6350,7 +6474,7 @@ return _el$
6350
6474
  }
6351
6475
  function SkillsSection(props){const dialogs=useDialogs(props.api)
6352
6476
  const toolbar=useToolbar()
6353
- const [query,setQuery]=createSignal33("")
6477
+ const [query,setQuery]=createSignal37("")
6354
6478
  const model=createSkillSectionModel(props,query)
6355
6479
  const navigationSection=()=>props.navigationSection??3
6356
6480
  function selectSkill(item){activateSkill({api:props.api,controller:props.controller,access:props.preferences,dialogs,skill:item,onConfigure:toolbar?(navigation)=>toolbar.configure({kind:"skill",name:item.name,location:item.location,icon:"book"
@@ -6374,7 +6498,7 @@ _$insert(_el$,_$createComponent(SectionFilter,{get api(){return props.api
6374
6498
  }},get query(){return query()
6375
6499
  },placeholder:"Filter skills...",onInput:setQuery
6376
6500
  }),null)
6377
- _$insert(_el$,_$createComponent(Show29,{get when(){return model.filtered().length>0
6501
+ _$insert(_el$,_$createComponent(Show31,{get when(){return model.filtered().length>0
6378
6502
  },get fallback(){return(()=>{var _el$2=_$createElement("text")
6379
6503
  _$insertNode(_el$2,_$createTextNode(`No matching skills`))
6380
6504
  _$effect((_$p)=>_$setProp(_el$2,"fg",props.api.theme.current.textMuted,_$p))
@@ -6385,7 +6509,7 @@ return _el$2
6385
6509
  },get grouped(){return model.grouped
6386
6510
  },get density(){return props.preferences.rowDensity?.()??"compact"
6387
6511
  },get children(){return _$createComponent(For18,{get each(){return model.visibility.visible()
6388
- },children:(item,index)=>[_$createComponent(Show29,{get when(){return _$memo(()=>!!model.grouped())()&&(index()===0||model.visibility.visible()[index()-1]?.bucket!==item.bucket)
6512
+ },children:(item,index)=>[_$createComponent(Show31,{get when(){return _$memo(()=>!!model.grouped())()&&(index()===0||model.visibility.visible()[index()-1]?.bucket!==item.bucket)
6389
6513
  },get children(){var _el$4=_$createElement("text")
6390
6514
  _$setProp(_el$4,"height",1)
6391
6515
  _$setProp(_el$4,"wrapMode","none")
@@ -6430,18 +6554,18 @@ return _el$
6430
6554
  function createSubagentSectionModel(props){const list=createMemo17(()=>props.controller.list(props.sessionID))
6431
6555
  const recent=createMemo17(()=>props.controller.recent?.(props.sessionID)??[])
6432
6556
  const rows=createMemo17(()=>buildSubagentView(list(),recent()))
6433
- const [query,setQuery]=createSignal34("")
6434
- const [mode,setMode]=createSignal34("all")
6557
+ const [query,setQuery]=createSignal38("")
6558
+ const [mode,setMode]=createSignal38("all")
6435
6559
  const counts=createMemo17(()=>countSubagentView(rows(),query()))
6436
6560
  const tabs=createMemo17(()=>["all","active","recent",...counts().errors>0?["errors"]:[]])
6437
6561
  const filtered=createMemo17(()=>filterSubagentView(rows(),mode(),query()))
6438
6562
  const parentID=createMemo17(()=>props.api.state?.session?.get(props.sessionID)?.parentID)
6439
6563
  const targetKey=createMemo17(()=>props.controller.target?.(props.sessionID).key??props.sessionID)
6440
- createEffect19(()=>{targetKey()
6564
+ createEffect20(()=>{targetKey()
6441
6565
  setQuery("")
6442
6566
  setMode("all")
6443
6567
  })
6444
- createEffect19(()=>{if(mode()!=="all"&&counts()[mode()]===0)
6568
+ createEffect20(()=>{if(mode()!=="all"&&counts()[mode()]===0)
6445
6569
  setMode("all")
6446
6570
  })
6447
6571
  const visibility=createListVisibility({items:filtered,limit:()=>props.preferences.sectionItemLimit?.("subagents")??0,resetKey:()=>JSON.stringify([targetKey(),query(),mode()])
@@ -6451,10 +6575,10 @@ const now=createSubagentClock(clockKey)
6451
6575
  const byId=createMemo17(()=>new Map(visibility.visible().map((item)=>[item.session.id,item])))
6452
6576
  const ids=createMemo17(()=>visibility.visible().map((item)=>item.session.id))
6453
6577
  const state=createMemo17(()=>props.controller.state(props.sessionID))
6454
- createEffect19(()=>{const sessionID=props.sessionID
6578
+ createEffect20(()=>{const sessionID=props.sessionID
6455
6579
  targetKey()
6456
6580
  const deactivate=untrack9(()=>props.controller.activate?.(sessionID)??(()=>{}))
6457
- onCleanup22(deactivate)
6581
+ onCleanup25(deactivate)
6458
6582
  untrack9(()=>void props.controller.refresh(sessionID).catch(()=>{}))
6459
6583
  })
6460
6584
  return{list,recent,rows,query,setQuery,mode,setMode,counts,tabs,filtered,parentID,visibility,now,byId,ids,state
@@ -6512,7 +6636,7 @@ return()=>_c$()?`${props.item.run.startedBeforeObservation ? `${icons.icon("rece
6512
6636
  _$effect((_$p)=>_$setProp(_el$3,"fg",row.focused()?row.foregroundColor():theme().textMuted,_$p))
6513
6637
  return _el$3
6514
6638
  })()
6515
- },get details(){return [_$createComponent(Show30,{get when(){return props.item.run?.errorMessage
6639
+ },get details(){return [_$createComponent(Show32,{get when(){return props.item.run?.errorMessage
6516
6640
  },get children(){var _el$4=_$createElement("text"),_el$5=_$createTextNode(`: `)
6517
6641
  _$insertNode(_el$4,_el$5)
6518
6642
  _$setProp(_el$4,"wrapMode","word")
@@ -6520,12 +6644,12 @@ _$insert(_el$4,()=>cancelled()?"Cancelled":"Error",_el$5)
6520
6644
  _$insert(_el$4,()=>props.item.run?.errorMessage,null)
6521
6645
  _$effect((_$p)=>_$setProp(_el$4,"fg",row.focused()?row.foregroundColor():failed()?theme().error:theme().textMuted,_$p))
6522
6646
  return _el$4
6523
- }}),_$createComponent(Show30,{get when(){return props.item.unavailable
6647
+ }}),_$createComponent(Show32,{get when(){return props.item.unavailable
6524
6648
  },get children(){var _el$6=_$createElement("text")
6525
6649
  _$insertNode(_el$6,_$createTextNode(`Worker status unavailable`))
6526
6650
  _$effect((_$p)=>_$setProp(_el$6,"fg",theme().warning,_$p))
6527
6651
  return _el$6
6528
- }}),_$createComponent(Show30,{get when(){return _$memo(()=>props.item.status.type==="retry")()?props.item.status:undefined
6652
+ }}),_$createComponent(Show32,{get when(){return _$memo(()=>props.item.status.type==="retry")()?props.item.status:undefined
6529
6653
  },children:(status)=>(()=>{var _el$0=_$createElement("text"),_el$1=_$createTextNode(`Retry #`),_el$10=_$createTextNode(` \xB7 `),_el$11=_$createTextNode(`s \xB7 `)
6530
6654
  _$insertNode(_el$0,_el$1)
6531
6655
  _$insertNode(_el$0,_el$10)
@@ -6537,7 +6661,7 @@ _$insert(_el$0,()=>status().message,null)
6537
6661
  _$effect((_$p)=>_$setProp(_el$0,"fg",row.focused()?row.foregroundColor():theme().warning,_$p))
6538
6662
  return _el$0
6539
6663
  })()
6540
- }),_$createComponent(Show30,{get when(){return _$memo(()=>!!idle())()&&!props.item.run?.errorMessage
6664
+ }),_$createComponent(Show32,{get when(){return _$memo(()=>!!idle())()&&!props.item.run?.errorMessage
6541
6665
  },get children(){var _el$8=_$createElement("text")
6542
6666
  _$insertNode(_el$8,_$createTextNode(`Finished`))
6543
6667
  _$effect((_$p)=>_$setProp(_el$8,"fg",theme().textMuted,_$p))
@@ -6553,7 +6677,7 @@ function SubagentList(props){return _$createComponent(SidebarRowList,{get api(){
6553
6677
  const item=()=>props.itemById(id)??initial
6554
6678
  const startsGroup=()=>index()===0||props.visible[index()-1]?.group!==item().group
6555
6679
  return(()=>{var _el$=_$createElement("box")
6556
- _$insert(_el$,_$createComponent(Show31,{get when(){return startsGroup()
6680
+ _$insert(_el$,_$createComponent(Show33,{get when(){return startsGroup()
6557
6681
  },get children(){var _el$2=_$createElement("text"),_el$3=_$createElement("b")
6558
6682
  _$insertNode(_el$2,_el$3)
6559
6683
  _$insert(_el$3,()=>item().group)
@@ -6579,7 +6703,7 @@ return _$createComponent(Section,{get api(){return props.api
6579
6703
  },sectionId:`${PLUGIN_ID}.section.subagents`,get navigationSection(){return navigationSection()
6580
6704
  },title:"SUBAGENTS",section:"subagents",get summary(){return `${model.list().length} active \xB7 ${model.recent().length} recent`
6581
6705
  },get open(){return props.preferences.expanded().subagents
6582
- },onToggle:()=>props.preferences.toggleSectionExpanded("subagents"),get children(){return [_$createComponent(Show32,{get when(){return model.parentID()
6706
+ },onToggle:()=>props.preferences.toggleSectionExpanded("subagents"),get children(){return [_$createComponent(Show34,{get when(){return model.parentID()
6583
6707
  },children:(id)=>_$createComponent(McpBulkAction,{get api(){return props.api
6584
6708
  },get interaction(){return props.interaction
6585
6709
  },id:`${PLUGIN_ID}.subagents.parent`,get position(){return{section:navigationSection(),row:1,column:0
@@ -6613,7 +6737,7 @@ _$insert(_el$2,_$createComponent(For20,{get each(){return model.tabs()
6613
6737
  },onActivate:()=>model.setMode(value)
6614
6738
  })
6615
6739
  }))
6616
- _$insert(_el$,_$createComponent(Show32,{get when(){return model.filtered().length===0
6740
+ _$insert(_el$,_$createComponent(Show34,{get when(){return model.filtered().length===0
6617
6741
  },get children(){var _el$3=_$createElement("text")
6618
6742
  _$insertNode(_el$3,_$createTextNode(`No matching subagents`))
6619
6743
  _$effect((_$p)=>_$setProp(_el$3,"fg",props.api.theme.current.textMuted,_$p))
@@ -6714,7 +6838,7 @@ _$insert(_el$2,()=>icons.icon(done()?"done":active()?"busy":cancelled()?"close":
6714
6838
  _$setProp(_el$3,"flexGrow",1)
6715
6839
  _$setProp(_el$3,"wrapMode","word")
6716
6840
  _$insert(_el$3,()=>props.item.content)
6717
- _$insert(_el$,_$createComponent(Show33,{get when(){return props.item.priority==="high"||props.item.priority==="medium"||props.item.priority==="low"
6841
+ _$insert(_el$,_$createComponent(Show35,{get when(){return props.item.priority==="high"||props.item.priority==="medium"||props.item.priority==="low"
6718
6842
  },get children(){var _el$4=_$createElement("text"),_el$5=_$createElement("b"),_el$6=_$createTextNode(` `)
6719
6843
  _$insertNode(_el$4,_el$5)
6720
6844
  _$setProp(_el$4,"width",2)
@@ -6750,7 +6874,7 @@ _$insert(_el$2,_$createComponent(For21,{each:["all","active","finished"],childre
6750
6874
  },onActivate:()=>props.setMode(value)
6751
6875
  })
6752
6876
  }))
6753
- _$insert(_el$,_$createComponent(Show34,{get when(){return props.view.rows.length>0
6877
+ _$insert(_el$,_$createComponent(Show36,{get when(){return props.view.rows.length>0
6754
6878
  },get fallback(){return _$createComponent(EmptyTodo,{get api(){return props.api
6755
6879
  },get mode(){return props.mode
6756
6880
  }})
@@ -6760,7 +6884,7 @@ _$insert(_el$,_$createComponent(Show34,{get when(){return props.view.rows.length
6760
6884
  },get children(){return _$createComponent(For21,{get each(){return props.visibility.visible()
6761
6885
  },children:(row,index)=>{const startsGroup=()=>index()===0||props.visibility.visible()[index()-1].group!==row.group
6762
6886
  return(()=>{var _el$3=_$createElement("box")
6763
- _$insert(_el$3,_$createComponent(Show34,{get when(){return startsGroup()
6887
+ _$insert(_el$3,_$createComponent(Show36,{get when(){return startsGroup()
6764
6888
  },get children(){var _el$4=_$createElement("text"),_el$5=_$createElement("b")
6765
6889
  _$insertNode(_el$4,_el$5)
6766
6890
  _$insert(_el$5,()=>row.group)
@@ -6797,7 +6921,7 @@ return _el$6
6797
6921
 
6798
6922
 
6799
6923
  function TodoGuidanceControl(props){const state=()=>props.controller.guidance(props.sessionID)
6800
- return _$createComponent(Show35,{get when(){return state().available
6924
+ return _$createComponent(Show37,{get when(){return state().available
6801
6925
  },get children(){var _el$=_$createElement("box")
6802
6926
  _$insert(_el$,_$createComponent(SectionTab,{get api(){return props.api
6803
6927
  },get interaction(){return props.interaction
@@ -6807,7 +6931,7 @@ _$insert(_el$,_$createComponent(SectionTab,{get api(){return props.api
6807
6931
  },get disabled(){return state().saving
6808
6932
  },onActivate:()=>void props.controller.setGuidance(props.sessionID,!state().enabled)
6809
6933
  }),null)
6810
- _$insert(_el$,_$createComponent(Show35,{get when(){return state().error
6934
+ _$insert(_el$,_$createComponent(Show37,{get when(){return state().error
6811
6935
  },children:(message)=>(()=>{var _el$2=_$createElement("text")
6812
6936
  _$setProp(_el$2,"wrapMode","word")
6813
6937
  _$insert(_el$2,message)
@@ -6823,21 +6947,21 @@ const icons=useIcons()
6823
6947
  const unavailable=()=>hostCapabilityUnavailable(props.api,"todo")
6824
6948
  const managed=()=>("guidance" in props.controller)?props.controller:undefined
6825
6949
  const native=()=>("source" in props.controller)&&props.controller.source==="native"
6826
- const [mode,setMode]=createSignal35("all")
6950
+ const [mode,setMode]=createSignal39("all")
6827
6951
  const targetKey=createMemo18(()=>props.controller.target?.(props.sessionID).key??props.sessionID)
6828
- createEffect20(()=>{targetKey()
6952
+ createEffect21(()=>{targetKey()
6829
6953
  setMode("all")
6830
6954
  })
6831
6955
  const view=createMemo18(()=>buildTodoView(list(),mode()))
6832
6956
  const visibility=createListVisibility({items:()=>view().rows,limit:()=>props.preferences.sectionItemLimit?.("todo")??0,resetKey:()=>JSON.stringify([targetKey(),mode()])
6833
6957
  })
6834
6958
  const state=createMemo18(()=>props.controller.state(props.sessionID))
6835
- createEffect20(()=>{const sessionID=props.sessionID
6959
+ createEffect21(()=>{const sessionID=props.sessionID
6836
6960
  targetKey()
6837
6961
  if(unavailable())
6838
6962
  return
6839
6963
  const deactivate=untrack10(()=>props.controller.activate?.(sessionID)??(()=>{}))
6840
- onCleanup23(deactivate)
6964
+ onCleanup26(deactivate)
6841
6965
  untrack10(()=>void props.controller.refresh(sessionID).catch(()=>{}))
6842
6966
  })
6843
6967
  const navigationSection=()=>props.navigationSection??1
@@ -6848,15 +6972,15 @@ return _$createComponent(Section,{get api(){return props.api
6848
6972
  },get headerAction(){return native()?{id:`${PLUGIN_ID}.todo.refresh`,label:()=>`${icons.icon("retry")} Refresh`,disabled:()=>state().status==="loading"||state().status==="refreshing",onActivate:()=>{props.controller.refresh(props.sessionID).catch(()=>{})
6849
6973
  }}:undefined
6850
6974
  },get open(){return props.preferences.expanded().todo
6851
- },onToggle:()=>props.preferences.toggleSectionExpanded("todo"),get children(){return _$createComponent(Show36,{get when(){return unavailable()
6975
+ },onToggle:()=>props.preferences.toggleSectionExpanded("todo"),get children(){return _$createComponent(Show38,{get when(){return unavailable()
6852
6976
  },get fallback(){return(()=>{var _el$=_$createElement("box")
6853
6977
  _$setProp(_el$,"gap",1)
6854
- _$insert(_el$,_$createComponent(Show36,{get when(){return native()
6978
+ _$insert(_el$,_$createComponent(Show38,{get when(){return native()
6855
6979
  },get children(){return _$createComponent(NativeTodoNotice,{get api(){return props.api
6856
6980
  },get empty(){return list().length===0
6857
6981
  }})
6858
6982
  }}),null)
6859
- _$insert(_el$,_$createComponent(Show36,{get when(){return managed()?.guidance(props.sessionID).available
6983
+ _$insert(_el$,_$createComponent(Show38,{get when(){return managed()?.guidance(props.sessionID).available
6860
6984
  },get children(){return _$createComponent(TodoGuidanceControl,{get api(){return props.api
6861
6985
  },get controller(){return managed()
6862
6986
  },get sessionID(){return props.sessionID
@@ -6864,7 +6988,7 @@ _$insert(_el$,_$createComponent(Show36,{get when(){return managed()?.guidance(pr
6864
6988
  },get navigationSection(){return navigationSection()
6865
6989
  }})
6866
6990
  }}),null)
6867
- _$insert(_el$,_$createComponent(Show36,{get when(){return managed()?.missing(props.sessionID)
6991
+ _$insert(_el$,_$createComponent(Show38,{get when(){return managed()?.missing(props.sessionID)
6868
6992
  },get fallback(){return _$createComponent(SectionRequestBody,{get api(){return props.api
6869
6993
  },get interaction(){return props.interaction
6870
6994
  },id:`${PLUGIN_ID}.retry.todo`,get position(){return{section:navigationSection(),row:1,column:0
@@ -6901,7 +7025,7 @@ return _el$4
6901
7025
  }
6902
7026
  function SidebarContent(props){const sections=props.preferences.sections
6903
7027
  const visibleSections=createMemo19(()=>props.preferences.sectionOrder().filter((section)=>sections()[section]&&supportsSidebarSection(props.api,section)))
6904
- onCleanup24(()=>props.interaction.setContentRoot(undefined))
7028
+ onCleanup27(()=>props.interaction.setContentRoot(undefined))
6905
7029
  return _$createComponent(ToolbarProvider,{get api(){return props.api
6906
7030
  },get preferences(){return props.preferences
6907
7031
  },get skills(){return props.skills
@@ -6953,7 +7077,7 @@ return _el$
6953
7077
 
6954
7078
 
6955
7079
  function McpPersistence(props){const persist=createMemo20(()=>props.controller.persist())
6956
- createEffect21(()=>{if(!props.api.state.ready)
7080
+ createEffect22(()=>{if(!props.api.state.ready)
6957
7081
  return
6958
7082
  persist()
6959
7083
  const route=props.api.route.current
@@ -6961,12 +7085,12 @@ const params="params" in route?route.params:undefined
6961
7085
  if(typeof params?.sessionID!=="string")
6962
7086
  return
6963
7087
  const current=props.controller.target()
6964
- onCleanup25(()=>props.controller.deactivate(current))
7088
+ onCleanup28(()=>props.controller.deactivate(current))
6965
7089
  untrack11(()=>void props.controller.activate(current).catch(()=>{}))
6966
7090
  })
6967
7091
  return _$createElement("box")
6968
7092
  }
6969
- function PreferencesPersistence(props){createEffect21(()=>{const location=currentLocation(props.api)
7093
+ function PreferencesPersistence(props){createEffect22(()=>{const location=currentLocation(props.api)
6970
7094
  untrack11(()=>props.controller.setActiveScope(preferencesScope({directory:location.routing.directory,worktree:props.api.state.path.worktree
6971
7095
  })))
6972
7096
  props.controller.load()
@@ -6974,7 +7098,7 @@ props.controller.load()
6974
7098
  return _$createElement("box")
6975
7099
  }
6976
7100
  function FirstRunWizardPersistence(props){let isChecked=false
6977
- createEffect21(()=>{if(isChecked)
7101
+ createEffect22(()=>{if(isChecked)
6978
7102
  return
6979
7103
  isChecked=true
6980
7104
  showFirstRunWizard(props.api,props.preferences).catch(()=>{})
@@ -7001,7 +7125,7 @@ const settingsId=`${PLUGIN_ID}.settings`
7001
7125
  const settings=useSidebarItem(props.api,props.interaction,{id:settingsId,position:{section:0,row:0,column:0
7002
7126
  },activate:()=>openSettings(props.api,props.preferences,undefined,props.mcp,props.skills)
7003
7127
  },()=>theme().textMuted,"control")
7004
- onCleanup26(()=>props.interaction.setTitleRoot(undefined))
7128
+ onCleanup29(()=>props.interaction.setTitleRoot(undefined))
7005
7129
  return(()=>{var _el$=_$createElement("box"),_el$2=_$createElement("box"),_el$3=_$createElement("box")
7006
7130
  _$insertNode(_el$,_el$2)
7007
7131
  _$use((node)=>props.interaction.setTitleRoot(node),_el$)
@@ -7012,7 +7136,7 @@ _$setProp(_el$2,"flexDirection","row")
7012
7136
  _$setProp(_el$2,"justifyContent","space-between")
7013
7137
  _$setProp(_el$2,"gap",1)
7014
7138
  _$setProp(_el$3,"flexGrow",1)
7015
- _$insert(_el$3,_$createComponent(Show37,{get when(){return props.preferences.showSessionTitle()
7139
+ _$insert(_el$3,_$createComponent(Show39,{get when(){return props.preferences.showSessionTitle()
7016
7140
  },get children(){var _el$4=_$createElement("text"),_el$5=_$createElement("b")
7017
7141
  _$insertNode(_el$4,_el$5)
7018
7142
  _$setProp(_el$4,"wrapMode","word")
@@ -7020,7 +7144,7 @@ _$insert(_el$5,()=>props.title)
7020
7144
  _$effect((_$p)=>_$setProp(_el$4,"fg",theme().text,_$p))
7021
7145
  return _el$4
7022
7146
  }}),null)
7023
- _$insert(_el$3,_$createComponent(Show37,{get when(){return _$memo(()=>!!props.preferences.showSessionDate())()&&created()
7147
+ _$insert(_el$3,_$createComponent(Show39,{get when(){return _$memo(()=>!!props.preferences.showSessionDate())()&&created()
7024
7148
  },children:(value)=>(()=>{var _el$6=_$createElement("text")
7025
7149
  _$insert(_el$6,value)
7026
7150
  _$effect((_$p)=>_$setProp(_el$6,"fg",theme().textMuted,_$p))
@@ -7069,11 +7193,11 @@ function createLimitsRefresh(options,schedule=scheduleInterval){let disposed=fal
7069
7193
  const selectedKey=createMemo22(()=>JSON.stringify(options.selectedModel?.()))
7070
7194
  const targetKey=createMemo22(()=>JSON.stringify(options.controller.current().model))
7071
7195
  const interval=createMemo22(()=>(parseLimitsRefreshMinutes(options.refreshMinutes?.())??DEFAULT_LIMITS_REFRESH_MINUTES)*60000)
7072
- createEffect22(on2(selectedKey,()=>{const model=options.selectedModel?.()
7196
+ createEffect23(on2(selectedKey,()=>{const model=options.selectedModel?.()
7073
7197
  if(model&&options.accountSource)
7074
7198
  options.accountSource.refresh(model).catch(()=>{})
7075
7199
  }))
7076
- createEffect22(on2(targetKey,()=>{const{model,adapter}=options.controller.current()
7200
+ createEffect23(on2(targetKey,()=>{const{model,adapter}=options.controller.current()
7077
7201
  if(model&&adapter)
7078
7202
  options.controller.refresh()
7079
7203
  }))
@@ -7086,32 +7210,35 @@ await options.accountSource.refresh(model)
7086
7210
  if(!disposed&&target===targetKey())
7087
7211
  await options.controller.refresh()
7088
7212
  }
7089
- createEffect22(on2(interval,(milliseconds)=>{onCleanup27(schedule(()=>void refresh().catch(()=>{}),milliseconds))
7213
+ createEffect23(on2(interval,(milliseconds)=>{onCleanup30(schedule(()=>void refresh().catch(()=>{}),milliseconds))
7090
7214
  }))
7091
- onCleanup27(()=>{disposed=true
7215
+ onCleanup30(()=>{disposed=true
7092
7216
  })
7093
7217
  }
7094
7218
  function LimitsPersistence(props){createLimitsRefresh(props)
7095
7219
  return _$createElement("box")
7096
7220
  }
7221
+ function bindNavigatorAbout(api,status,updates,notes){const dispose=registerNavigatorAboutServices(api,{navigatorVersion:"0.24.0",openCodeVersion:api.app.version,checkState:()=>status.navigatorCheckState?.()??{status:"idle"},checking:()=>status.navigatorCheckState?.().status==="checking",updating:updates.navigatorUpdating,installed:updates.navigatorInstalled,check:()=>status.refreshNavigator?.()??Promise.resolve("unavailable"),update(dialogs){const target=status.navigatorUpdate()
7222
+ if(target)
7223
+ updates.navigator(target,dialogs)
7224
+ },changelog:async ()=>notes.parseChangelog(await notes.readBundledChangelog())
7225
+ })
7226
+ api.lifecycle.onDispose(dispose)
7227
+ }
7097
7228
  import {homedir} from "os"
7098
7229
 
7099
7230
  function location(input){return input.directory?{location:{directory:input.directory}}:{}}
7100
7231
  function mcpItem(server){return{name:server.name,status:server.status.status,...server.status.error&&{error:server.status.error}}}
7101
- function skillKey(directory,name){return `${directory}\x00${name}`
7102
- }
7103
- function createV2ClientAdapter(context){const skillIDs=new Map
7104
- return{state:{mcp:()=>(context.data.location.mcp.server.list(context.location)??[]).map((server)=>mcpItem(server))
7232
+ function createV2ClientAdapter(context){return{state:{mcp:()=>(context.data.location.mcp.server.list(context.location)??[]).map((server)=>mcpItem(server))
7105
7233
  },client:{app:{async skills(input,options={}){const response=await context.client.skill.list(location(input),{signal:options.signal})
7106
- const directory=input.directory??response.location.directory
7107
- const data=response.data.map((skill)=>{skillIDs.set(skillKey(directory,skill.name),skill.id)
7108
- return{name:skill.name,description:skill.description,location:skill.path,content:skill.content
7109
- }})
7234
+ const data=response.data.map((skill)=>({name:skill.name,description:skill.description,location:skill.path,content:skill.content
7235
+ }))
7110
7236
  return{data}}},tui:{async appendPrompt(input,options={}){const route=context.ui.router.current()
7111
7237
  const name=/^\/([^\s]+)\s*$/u.exec(input.text)?.[1]
7112
7238
  const directory=input.directory??context.location?.directory??context.data.location.default().directory
7113
7239
  const session=route.type==="session"?context.data.session.get(route.sessionID):undefined
7114
- const id=name?skillIDs.get(skillKey(directory,name)):undefined
7240
+ const candidates=context.data.location.skill.list({directory})?.filter((skill)=>skill.name===name)??[]
7241
+ const id=candidates.length===1?candidates[0].id:undefined
7115
7242
  if(route.type!=="session"||session?.location.directory!==directory||!id)
7116
7243
  return{data:false}
7117
7244
  await context.client.session.skill({sessionID:route.sessionID,id},{signal:options.signal})
@@ -7129,77 +7256,79 @@ if(name!=="session.status"&&(name!=="session.idle"||started))
7129
7256
  return
7130
7257
  const status=started?{type:"busy"}:{type:"idle"}
7131
7258
  return{sessionID,status,properties:{sessionID,...name==="session.status"&&{status}}}}
7132
- var SESSION_UPDATE_EVENTS=new Set(["session.agent.selected","session.model.selected","session.moved","session.renamed","session.permissions","session.metadata.updated"])
7133
- function createV2EventAdapter(context,sessions){return{on(name,handler){let active=true
7134
- const unsubscribe=context.data.listen(({details})=>{const event=details
7135
- const execution=executionStatus(name,event)
7136
- if(execution){sessions.setStatus(execution.sessionID,execution.status)
7137
- handler({type:name,properties:execution.properties
7138
- })
7139
- return
7259
+ var updates=["session.agent.selected","session.model.selected","session.moved","session.renamed","session.permissions","session.metadata.updated"]
7260
+ var executions=["session.execution.started","session.execution.succeeded","session.execution.failed","session.execution.interrupted"]
7261
+ function eventTypes(name){if(name==="session.updated")
7262
+ return updates
7263
+ if(name==="session.status")
7264
+ return ["session.status","session.retry.scheduled",...executions]
7265
+ if(name==="session.idle")
7266
+ return ["session.idle",...executions.slice(1)]
7267
+ if(name==="session.error")
7268
+ return ["session.execution.failed"]
7269
+ if(name==="mcp.tools.changed")
7270
+ return ["mcp.status.changed","mcp.resources.changed"]
7271
+ if(["session.created","session.deleted","server.connected","installation.update-available"].includes(name))
7272
+ return [name]
7273
+ return []
7140
7274
  }
7141
- if(name==="server.connected"&&event.type==="server.connected"){handler({type:name,properties:{}})
7142
- return
7275
+ function statusFor(name,event){if(name==="session.idle")
7276
+ return{type:"idle"}
7277
+ if(event.type==="session.retry.scheduled")
7278
+ return{type:"retry",attempt:Number(event.data.attempt),next:Number(event.data.at),message:event.data.error?.message??"Retrying"
7143
7279
  }
7144
- if(name==="mcp.tools.changed"&&event.type.startsWith("mcp.")){handler({type:name,properties:event.data})
7145
- return
7280
+ return event.data.status
7146
7281
  }
7147
- if(name==="installation.update-available"&&event.type==="installation.update-available"){if(typeof event.data.version==="string"){handler({type:name,properties:{version:event.data.version}})
7282
+ function createV2EventAdapter(context,sessions){return{on(name,handler){let active=true
7283
+ const disposers=eventTypes(name).map((type)=>context.data.on(type,(value)=>{const event=value
7284
+ const data=event.data??{}
7285
+ const emit=(properties)=>{if(active)
7286
+ handler({type:name,properties})
7148
7287
  }
7288
+ const execution=executionStatus(name,{type:event.type,data})
7289
+ if(execution){sessions.setStatus(execution.sessionID,execution.status)
7290
+ emit(execution.properties)
7149
7291
  return
7150
7292
  }
7151
- if(name==="session.deleted"&&event.type==="session.deleted"){handler({type:name,properties:{sessionID:event.data.sessionID}})
7293
+ if(name==="server.connected"||name==="mcp.tools.changed"){emit(data)
7152
7294
  return
7153
7295
  }
7154
- if(name==="session.status"&&event.type==="session.status"){const sessionID=event.data.sessionID
7155
- const status=event.data.status
7156
- if(typeof sessionID!=="string"||!status||typeof status!=="object")
7157
- return
7158
- sessions.setStatus(sessionID,status)
7159
- handler({type:name,properties:{sessionID,status}})
7296
+ if(name==="installation.update-available"){if(typeof data.version==="string")
7297
+ emit({version:data.version})
7160
7298
  return
7161
7299
  }
7162
- if(name==="session.idle"&&event.type==="session.idle"){const sessionID=event.data.sessionID
7300
+ const sessionID=data.sessionID
7163
7301
  if(typeof sessionID!=="string")
7164
7302
  return
7165
- sessions.setStatus(sessionID,{type:"idle"})
7166
- handler({type:name,properties:{sessionID}})
7167
- return
7303
+ if(name==="session.status"||name==="session.idle"){const status=statusFor(name,{type:event.type,data})
7304
+ if(status&&typeof status==="object"){sessions.setStatus(sessionID,status)
7305
+ emit(name==="session.idle"?{sessionID}:{sessionID,status})
7168
7306
  }
7169
- if(name==="session.error"&&event.type==="session.execution.failed"){const error=event.data.error
7170
- handler({type:name,properties:{sessionID:event.data.sessionID,error:error&&{name:error.type??"Error",data:{message:error.message??"Session error"}}}})
7171
7307
  return
7172
7308
  }
7173
- const isCreated=name==="session.created"&&event.type==="session.created"
7174
- const isUpdated=name==="session.updated"&&SESSION_UPDATE_EVENTS.has(event.type)
7175
- if(!isCreated&&!isUpdated)
7309
+ if(name==="session.deleted"){emit({sessionID})
7176
7310
  return
7177
- const sessionID=event.data.sessionID
7178
- const info=typeof sessionID==="string"?context.data.session.get(sessionID):undefined
7179
- if(info){handler({type:name,properties:{info:sessions.normalize(info)}})
7311
+ }
7312
+ if(name==="session.error"){const error=data.error
7313
+ emit({sessionID,error:error&&{name:error.type??"Error",data:{message:error.message??"Session error"}}})
7180
7314
  return
7181
7315
  }
7182
- if(typeof sessionID!=="string")
7316
+ const info=context.data.session.get(sessionID)
7317
+ if(info){emit({info:sessions.project(info)})
7183
7318
  return
7319
+ }
7184
7320
  context.data.session.sync(sessionID).then(()=>{const synced=context.data.session.get(sessionID)
7185
- if(active&&synced)
7186
- handler({type:name,properties:{info:sessions.normalize(synced)}})
7321
+ if(synced)
7322
+ emit({info:sessions.project(synced)})
7187
7323
  }).catch(()=>{})
7188
- })
7324
+ }))
7189
7325
  return()=>{active=false
7190
- unsubscribe()
7326
+ for(const dispose of disposers)
7327
+ dispose()
7191
7328
  }}}}
7192
7329
 
7193
-
7194
7330
  function enabled(value){return typeof value==="function"?value():value!==false
7195
7331
  }
7196
- function belongsTo2(renderable,ancestor){if(!renderable||!ancestor)
7197
- return false
7198
- for(let current=renderable;current; current=current.parent){if(current===ancestor)
7199
- return true
7200
- }
7201
- return false
7202
- }
7203
7332
  function v2LayerCommands(id,layer,available,run,dispatch){const named=(layer.commands??[]).map((command)=>({id:command.name,bind:command.name==="session.new"?"<leader>n":undefined,title:command.title,description:command.desc,group:command.category,palette:command.namespace==="palette"?true:undefined,suggested:command.suggested,enabled:()=>available()&&enabled(command.enabled),run:(input,event)=>run(command,input,event)
7204
7333
  }))
7205
7334
  const bindings=(layer.bindings??[]).flatMap((binding,index)=>typeof binding.key==="string"?[{id:`${PLUGIN_ID}.v2-binding.${id}.${index}`,bind:binding.key,enabled:available,run:()=>dispatch(String(binding.cmd))
@@ -7208,98 +7337,112 @@ return [...named,...bindings]
7208
7337
  }
7209
7338
  var SETTINGS_COMMAND="opencode.settings"
7210
7339
  var PERMISSIONS_ACTION="permission.mode"
7211
- function createV2Keymap(context){const [revision,setRevision]=createSignal36(0)
7212
- const layers=new Map
7340
+ function createV2Keymap(context){const cleanups=new Set
7213
7341
  let sequence=0
7214
- function layerActive(layer){const mode=layer.mode??"base"
7215
- const target=layer.target
7216
- return(mode==="global"||context.keymap.mode.current()===mode)&&enabled(layer.enabled)&&(!target||belongsTo2(context.renderer.currentFocusedRenderable,target))
7217
- }
7218
- function legacyCommand(name){return [...layers].sort(([leftID,left],[rightID,right])=>(right.priority??0)-(left.priority??0)||rightID-leftID).flatMap(([,layer])=>layerActive(layer)?[layer]:[]).flatMap((layer)=>layer.commands??[]).find((command)=>command.name===name&&enabled(command.enabled))
7219
- }
7220
- function run(command,input="",event){return command.run({keymap,event,focused:context.renderer.currentFocusedRenderable,target:context.renderer.currentFocusedRenderable,data:{},command,input,payload:undefined
7342
+ async function run(command,input="",event){await command.run({keymap,event,focused:context.renderer.currentFocusedRenderable,target:context.renderer.currentFocusedRenderable,data:{},command,input,payload:undefined
7221
7343
  })
7222
7344
  }
7223
- async function runV2(command,input="",event){await run(command,input,event)
7224
- }
7225
7345
  const onKeypress=(event)=>{if(event.name!==","||!event.ctrl||event.shift||event.meta||event.super||event.hyper)
7226
7346
  return
7227
- const command=legacyCommand(`${PLUGIN_ID}.settings`)
7228
- if(!command)
7347
+ const command=context.keymap.commands().find((item)=>item.id===`${PLUGIN_ID}.settings`)
7348
+ if(!command||!enabled(command.enabled))
7229
7349
  return
7230
7350
  event.preventDefault()
7231
7351
  event.stopPropagation()
7232
- runV2(command,"",event)
7352
+ context.keymap.dispatch(command.id)
7233
7353
  }
7234
7354
  context.renderer.keyInput.on("keypress",onKeypress)
7235
- function layerCommands([id,layer]){return v2LayerCommands(id,layer,()=>layerActive(layer),runV2,context.keymap.dispatch)
7355
+ const keymap={registerLayer(layer){const id=++sequence
7356
+ const owner=getOwner()
7357
+ const [active,setActive]=createSignal40(true)
7358
+ const install=()=>{context.keymap.layer(()=>({mode:typeof layer.mode==="string"?layer.mode:"base",priority:layer.priority,enabled:()=>active()&&enabled(layer.enabled),target:layer.target?()=>layer.target:undefined,commands:v2LayerCommands(id,layer,()=>true,run,context.keymap.dispatch)
7359
+ }))
7236
7360
  }
7237
- function Bridge(){context.keymap.layer(()=>{revision()
7238
- const current=[...layers].sort(([leftID,left],[rightID,right])=>(right.priority??0)-(left.priority??0)||rightID-leftID)
7239
- const commands=current.flatMap((entry)=>layerCommands(entry))
7240
- const bindings=commands.flatMap((command)=>command.id?[command.id]:[])
7241
- return{mode:"global",priority:2000,commands,bindings
7242
- }})
7243
- return _$createElement("box")
7361
+ let release
7362
+ if(owner)
7363
+ release=createRoot((cleanup)=>{install()
7364
+ return cleanup
7365
+ },owner)
7366
+ else
7367
+ install()
7368
+ const dispose=()=>{setActive(false)
7369
+ release?.()
7244
7370
  }
7245
- const keymap={registerLayer(layer){const id=++sequence
7246
- layers.set(id,layer)
7247
- setRevision((value)=>value + 1)
7248
- return()=>{if(!layers.delete(id))
7249
- return
7250
- setRevision((value)=>value + 1)
7251
- }},dispatchCommand(name,options){const command=context.keymap.commands().find((candidate)=>candidate.id===(name===PERMISSIONS_ACTION?SETTINGS_COMMAND:name))
7252
- if(command){if(!enabled(command.enabled))
7371
+ cleanups.add(dispose)
7372
+ return()=>{cleanups.delete(dispose)
7373
+ dispose()
7374
+ }},dispatchCommand(name,options){const target=options?.focused??options?.target
7375
+ if(target?.parent&&!target.isDestroyed)
7376
+ target.focus()
7377
+ const command=context.keymap.commands().find((item)=>item.id===(name===PERMISSIONS_ACTION?SETTINGS_COMMAND:name))
7378
+ if(!command)
7379
+ return{ok:false,reason:"not-found"
7380
+ }
7381
+ if(!enabled(command.enabled))
7253
7382
  return{ok:false,reason:"disabled",command
7254
7383
  }
7255
7384
  context.keymap.dispatch(command.id,typeof options?.payload==="string"?options.payload:undefined)
7256
7385
  return{ok:true,command
7257
- }}
7258
- const fallback=legacyCommand(name)
7259
- if(!fallback)
7260
- return{ok:false,reason:"not-found"
7261
- }
7262
- run(fallback)
7263
- return{ok:true,command:fallback
7264
7386
  }},getCommands(){const commands=context.keymap.commands()
7265
- const result=commands.flatMap((command)=>{if(!command.id)
7266
- return []
7267
- const name=command.id
7268
- return [{...command,name,run:()=>context.keymap.dispatch(name)
7269
- }]
7270
- })
7271
- const settings=commands.find((command)=>command.id===SETTINGS_COMMAND)
7387
+ const result=commands.flatMap((command)=>command.id?[{...command,name:command.id,run:()=>context.keymap.dispatch(command.id)
7388
+ }]:[])
7389
+ const settings=commands.find((item)=>item.id===SETTINGS_COMMAND)
7272
7390
  if(settings)
7273
7391
  result.push({...settings,id:PERMISSIONS_ACTION,name:PERMISSIONS_ACTION,title:"Permissions settings",run:()=>context.keymap.dispatch(SETTINGS_COMMAND)
7274
7392
  })
7275
7393
  return result
7276
7394
  },getCommandBindings(input){return new Map(input.commands.map((name)=>[name,[...context.keymap.shortcuts(name)]]))
7277
- },parseKeySequence(value){return value.trim()?value.trim().split(/\s+/u):[]
7278
7395
  }}
7279
- return{keymap,Bridge,dispose:()=>{context.renderer.keyInput.off("keypress",onKeypress)
7396
+ return{keymap,dispose(){for(const cleanup of cleanups)
7397
+ cleanup()
7398
+ cleanups.clear()
7399
+ context.renderer.keyInput.off("keypress",onKeypress)
7280
7400
  }}}
7281
- function createV2SessionAdapter(context){const statuses=new Map
7401
+
7402
+ function createV2SessionAdapter(context){const [retryDetails,setRetryDetails]=createSignal41({})
7403
+ const projections=new WeakMap
7282
7404
  function normalize(info){const directory=info.location.directory
7283
7405
  const workspaceID=context.location?.directory===directory?context.location.workspaceID:undefined
7284
7406
  return{id:info.id,slug:info.id,projectID:info.projectID,...workspaceID&&{workspaceID},directory,...info.parentID&&{parentID:info.parentID},cost:Number(info.cost),tokens:info.tokens,title:info.title??"Untitled session",...info.agent&&{agent:info.agent},...info.model&&{model:info.model},version:context.app.version,metadata:info.metadata,time:{created:info.time.created,updated:info.time.updated,...info.time.archived&&{archived:info.time.archived}}}}
7285
- function status(sessionID){const cached=statuses.get(sessionID)
7286
- if(cached)
7287
- return cached
7288
- return context.data.session.status(sessionID)==="running"?{type:"busy"}:{type:"idle"}}
7289
- return{normalize,setStatus(sessionID,value){statuses.set(sessionID,value)
7407
+ function status(sessionID){if(context.data.session.status(sessionID)!=="running")
7408
+ return{type:"idle"}
7409
+ const messages=context.data.session.message?.list?.(sessionID)??[]
7410
+ let message
7411
+ for(let index=messages.length-1;index>=0; index--){const candidate=messages[index]
7412
+ if(candidate.type==="assistant"&&!candidate.time.completed){message=candidate
7413
+ break
7414
+ }}
7415
+ if(message?.type==="assistant"&&message.retry)
7416
+ return{type:"retry",attempt:message.retry.attempt,next:message.retry.at,message:message.retry.error.message
7417
+ }
7418
+ return retryDetails()[sessionID]??{type:"busy"}}
7419
+ function project(info){let value=projections.get(info)
7420
+ if(!value){value=normalize(info)
7421
+ for(const key of ["id","slug","projectID","workspaceID","directory","parentID","cost","tokens","title","agent","model","version","metadata","time"])
7422
+ Object.defineProperty(value,key,{enumerable:true,get:()=>normalize(info)[key]})
7423
+ projections.set(info,value)
7424
+ }
7425
+ return value
7426
+ }
7427
+ return{normalize,project,status,setStatus(sessionID,value){setRetryDetails((current)=>{const next={...current}
7428
+ if(value.type==="retry")
7429
+ next[sessionID]=value
7430
+ else
7431
+ delete next[sessionID]
7432
+ return next
7433
+ })
7290
7434
  },state:{count:()=>context.data.session.list().length,get:(sessionID)=>{const value=context.data.session.get(sessionID)
7291
- return value?normalize(value):undefined
7435
+ return value?project(value):undefined
7292
7436
  },todo:()=>[],status
7293
7437
  },client:{async create(input,options={}){const directory=input.directory??context.location?.directory??context.data.location.default().directory
7294
7438
  const session=await context.client.session.create({location:{directory}},{signal:options.signal})
7295
7439
  return{data:normalize(session)}},async children(input,options={}){const response=await context.client.session.list({parentID:input.sessionID,...input.directory&&{directory:input.directory}},{signal:options.signal})
7296
7440
  return{data:response.data.map((session)=>normalize(session))}},async status(_input,options={}){const active=await context.client.session.active({signal:options.signal})
7297
- const data=Object.fromEntries(context.data.session.list().map((session)=>[session.id,statuses.get(session.id)??(active[session.id]?{type:"busy"}:{type:"idle"})]))
7441
+ const data=Object.fromEntries(context.data.session.list().map((session)=>[session.id,active[session.id]?retryDetails()[session.id]??{type:"busy"}:{type:"idle"}]))
7298
7442
  return{data}},async todo(){return{data:[]}}}}}
7299
7443
 
7300
-
7301
- function createV2Slots(context,keymap,onDispose){return{register(plugin){const slots=plugin.slots
7302
- const cleanups=[context.ui.slot({append:"app",render:()=>[_$createComponent(keymap.Bridge,{}),_$memo(()=>slots.app?.(undefined,{}))]
7444
+ function createV2Slots(context,onDispose){return{register(plugin){const slots=plugin.slots
7445
+ const cleanups=[context.ui.slot({append:"app",render:()=>_$memo(()=>slots.app?.(undefined,{}))
7303
7446
  }),context.ui.slot({replace:"sidebar.content",render:(input)=>{const sessionID=input.sessionID
7304
7447
  return slots.sidebar_content?.(undefined,{session_id:sessionID
7305
7448
  })
@@ -7319,25 +7462,16 @@ return context.data.session.message.list(route.sessionID).some((message)=>(!reve
7319
7462
  }
7320
7463
 
7321
7464
 
7322
- function createV2UI(context){let dialogOpen=false
7323
- function DialogPrompt(props){let active=true
7324
- onCleanup28(()=>{active=false
7325
- })
7326
- onMount6(async ()=>{const value=await context.ui.dialog.prompt({title:props.title,placeholder:props.placeholder,value:props.value
7327
- })
7328
- if(!active)
7329
- return
7330
- if(value===undefined)
7331
- props.onCancel?.()
7332
- else
7333
- props.onConfirm?.(value)
7334
- })
7335
- return _$createElement("box")
7465
+
7466
+
7467
+ function createV2UI(context,api){let dialogOpen=false
7468
+ function DialogPrompt(props){return _$createComponent(SingleLinePrompt,_$mergeProps({get api(){return api()
7469
+ }},props))
7336
7470
  }
7337
7471
  function DialogConfirm(props){let active=true
7338
- onCleanup28(()=>{active=false
7472
+ onCleanup31(()=>{active=false
7339
7473
  })
7340
- onMount6(async ()=>{const confirmed=await context.ui.dialog.confirm({title:props.title,message:props.message
7474
+ onMount7(async ()=>{const confirmed=await context.ui.dialog.confirm({title:props.title,message:props.message
7341
7475
  })
7342
7476
  if(!active)
7343
7477
  return
@@ -7377,7 +7511,7 @@ const keymap=createV2Keymap(context)
7377
7511
  disposers.push(keymap.dispose)
7378
7512
  const sessions=createV2SessionAdapter(context)
7379
7513
  const remote=createV2ClientAdapter(context)
7380
- const ui=createV2UI(context)
7514
+ const ui=createV2UI(context,()=>api)
7381
7515
  const onDispose=(dispose)=>{disposers.push(dispose)
7382
7516
  return()=>{const index=disposers.indexOf(dispose)
7383
7517
  if(index!==-1)
@@ -7397,10 +7531,10 @@ context.ui.router.navigate({type:"plugin",name,data:params})
7397
7531
  },client:{...remote.client,session:sessions.client
7398
7532
  },event:createV2EventAdapter(context,sessions),theme:{get current(){return legacyTheme(context.theme)
7399
7533
  },ready:true,mode:()=>context.themeMode
7400
- },attention:context.attention,lifecycle:{signal:controller.signal,onDispose},slots:createV2Slots(context,keymap,(dispose)=>{onDispose(dispose)
7534
+ },attention:context.attention,lifecycle:{signal:controller.signal,onDispose},slots:createV2Slots(context,(dispose)=>{onDispose(dispose)
7401
7535
  })
7402
7536
  }
7403
- setHostCapabilities(api,{todo:true,lsp:false,titleVisibility:false,permissionMode:false
7537
+ setHostCapabilities(api,{todo:true,lsp:false,titleVisibility:false,permissionMode:false,commandsReachableOnly:true
7404
7538
  })
7405
7539
  bindToolbarActionState(context,api)
7406
7540
  return{api,async dispose(){controller.abort()
@@ -7470,28 +7604,91 @@ activeTarget=undefined
7470
7604
  requests.abortAll()
7471
7605
  pending.clear()
7472
7606
  }}}}
7607
+ function collectionLocation(target){return{directory:target.routing.directory??"",...target.routing.workspace&&{workspaceID:target.routing.workspace}}}
7608
+ async function syncCollection(collection,target,force,signal){signal.throwIfAborted()
7609
+ const ref=collectionLocation(target)
7610
+ if(force)
7611
+ collection.invalidate(ref)
7612
+ await collection.sync(ref)
7613
+ signal.throwIfAborted()
7614
+ }
7615
+ function createV2McpSource(context){const collection=context.data.location.mcp.server
7616
+ const projections=new WeakMap
7617
+ const list=(target)=>(collection.list(collectionLocation(target))??[]).map((server)=>{let item=projections.get(server)
7618
+ if(!item){item={get name(){return server.name
7619
+ },get title(){return server.title
7620
+ },get status(){return server.status.status
7621
+ },get error(){return "error" in server.status?server.status.error:undefined
7622
+ }}
7623
+ projections.set(server,item)
7624
+ }
7625
+ return item
7626
+ })
7627
+ return{list,async refresh(target,force,signal){await syncCollection(collection,target,force,signal)
7628
+ return list(target)
7629
+ }}}
7630
+ function createV2SkillSource(context){const projections=new WeakMap
7631
+ const collection=context.data.location.skill
7632
+ const list=(target)=>(collection.list(collectionLocation(target))??[]).map((skill)=>{let item=projections.get(skill)
7633
+ if(!item){item={get id(){return skill.id
7634
+ },get name(){return skill.name
7635
+ },get description(){return skill.description
7636
+ },get location(){return skill.path
7637
+ },get content(){return skill.content
7638
+ }}
7639
+ projections.set(skill,item)
7640
+ }
7641
+ return item
7642
+ })
7643
+ return{list,async refresh(target,force,signal){await syncCollection(collection,target,force,signal)
7644
+ return list(target)
7645
+ },async use(target,skill,signal){signal.throwIfAborted()
7646
+ const route=context.ui.router.current()
7647
+ const session=route.type==="session"&&context.data.session.get(route.sessionID)
7648
+ const actual=list(target).find((item)=>item.id===skill.id&&item.location===skill.location)
7649
+ if(route.type!=="session"||!session||session.location.directory!==target.routing.directory||!actual?.id)
7650
+ throw new Error("Skill target changed; select the source again")
7651
+ await context.client.session.skill({sessionID:route.sessionID,id:actual.id},{signal})
7652
+ return !signal.aborted
7653
+ }}}
7654
+ function createV2SubagentSource(context,api){return{list:(parentID)=>context.data.session.list().filter((item)=>item.parentID===parentID).flatMap((item)=>{const value=api.state.session.get(item.id)
7655
+ return value?[value]:[]
7656
+ }),status:(id)=>api.state.session.status(id)??{type:"idle"},async refresh(parentID,signal){signal.throwIfAborted()
7657
+ let cursor
7658
+ do{const page=await context.client.session.list(cursor?{cursor,limit:100}:{parentID,limit:100},{signal
7659
+ })
7660
+ await Promise.all(page.data.filter((item)=>!context.data.session.get(item.id)).map((item)=>context.data.session.sync(item.id)))
7661
+ cursor=page.cursor.next??undefined
7662
+ signal.throwIfAborted()
7663
+ } while(cursor)
7664
+ }}}
7665
+ function createOpenCodeV2Sources(context,api){return{skills:createV2SkillSource(context),mcp:createV2McpSource(context),subagents:createV2SubagentSource(context,api)
7666
+ }}
7473
7667
  function loadNavigatorUpdates(){const path=import.meta.url.includes("/dist/tui.js")?"./navigator-updates.js":"../navigator-updates"
7474
7668
  return import(path)
7475
7669
  }
7476
7670
  async function setupNavigator(api,options,readProject,todoController,hostContext){const config=pluginConfig(undefined)
7477
7671
  const configured=await loadConfiguredDefaults(api,options,readProject)
7478
7672
  const todo=todoController??createTodoController(api)
7479
- const subagents=createSubagentController(api)
7480
- const skills=createSkillController(api)
7673
+ const nativeSources=hostContext&&createOpenCodeV2Sources(hostContext,api)
7674
+ const subagents=createSubagentController(api,{source:nativeSources?.subagents
7675
+ })
7676
+ const skills=createSkillController(api,nativeSources?.skills)
7481
7677
  const preferences=createPreferencesController(api,config,createPreferencesStore(api.state.path.state),configured)
7482
7678
  const limitsPath=import.meta.url.includes("/dist/tui.js")?"./provider-limits.js":"../provider-limits"
7483
7679
  const limitsModule=await import(limitsPath)
7484
7680
  const LimitsSection=limitsModule.ProviderLimitsSection
7485
7681
  const{controller:limits,codex,accountSource,selectModel,modelSelection
7486
- }=limitsModule.createProviderQuotaIntegration(api,preferences,"0.22.0",hostContext)
7487
- const mcp=createMcpController(api,preferences.persistMcp,preferences)
7682
+ }=limitsModule.createProviderQuotaIntegration(api,preferences,"0.24.0",hostContext)
7683
+ const mcp=createMcpController(api,preferences.persistMcp,preferences,nativeSources?.mcp)
7488
7684
  const interaction=createSidebarInteraction(api,()=>openKeyboardHelp(api,preferences.lspIconStyle,preferences.cornerFont,sidebarShortcutActions(api)))
7489
7685
  const startup=createStartupSessionController(api,preferences)
7490
7686
  api.lifecycle.onDispose(()=>preferences.flush())
7491
7687
  api.lifecycle.onDispose(()=>limits.dispose())
7492
7688
  api.lifecycle.onDispose(()=>accountSource?.dispose())
7493
7689
  api.lifecycle.onDispose(()=>interaction.dispose())
7494
- const unsubscribeMcp=api.event.on("mcp.tools.changed",()=>{mcp.refresh().catch(()=>{})
7690
+ const unsubscribeMcp=api.event.on("mcp.tools.changed",()=>{if(!nativeSources)
7691
+ mcp.refresh().catch(()=>{})
7495
7692
  })
7496
7693
  const unsubscribeConnected=api.event.on("server.connected",()=>{if(!api.state.ready||!api.kv.ready)
7497
7694
  return
@@ -7511,7 +7708,7 @@ api.slots.register({order:100,slots:{app(){return _$createComponent(IconProvider
7511
7708
  },interaction,skills,subagents,mcp
7512
7709
  }),_$createComponent(FirstRunWizardPersistence,{api,preferences
7513
7710
  }),_$createComponent(StartupSessionBinding,{api,controller:startup
7514
- }),_$createComponent(UpgradeNotesBinding,{api,preferences,version:"0.22.0"
7711
+ }),_$createComponent(UpgradeNotesBinding,{api,preferences,version:"0.24.0"
7515
7712
  }),_$createComponent(McpPersistence,{api,controller:mcp
7516
7713
  })]
7517
7714
  }})
@@ -7542,14 +7739,16 @@ throw result.error
7542
7739
  }
7543
7740
  return result.data?.type==="text"?result.data.content:undefined
7544
7741
  })
7742
+ const updateServices=await loadNavigatorUpdates()
7545
7743
  const{createVersionStatus,createVersionUpdateActions,createOpenCodeV1VersionUpdater
7546
- }=await loadNavigatorUpdates()
7547
- const versionStatus=createVersionStatus(api,"0.22.0")
7548
- const versionUpdates=createVersionUpdateActions(api,versionStatus,createOpenCodeV1VersionUpdater(api,meta),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.22.0"))
7744
+ }=updateServices
7745
+ const versionStatus=createVersionStatus(api,"0.24.0")
7746
+ const versionUpdates=createVersionUpdateActions(api,versionStatus,createOpenCodeV1VersionUpdater(api,meta),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.24.0"))
7747
+ bindNavigatorAbout(api,versionStatus,versionUpdates,updateServices)
7549
7748
  api.slots.register({order:90,slots:{sidebar_footer(_context,props){return _$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7550
7749
  },get multilineCorners(){return preferences.cornerFont
7551
7750
  },get children(){return _$createComponent(VersionFooter,{api,get sessionID(){return props.session_id
7552
- },navigatorVersion:"0.22.0",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7751
+ },navigatorVersion:"0.24.0",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7553
7752
  },get onNavigatorUpdate(){return versionUpdates.navigator
7554
7753
  }})
7555
7754
  }})
@@ -7563,17 +7762,19 @@ return
7563
7762
  return new TextDecoder().decode(await context.client.file.read({location:context.location,path:".opencode/navigator.json"
7564
7763
  }))
7565
7764
  },todo,context)
7765
+ const updateServices=await loadNavigatorUpdates()
7566
7766
  const{createVersionStatus,createVersionUpdateActions,createOpenCodeV2VersionUpdater
7567
- }=await loadNavigatorUpdates()
7568
- const versionStatus=createVersionStatus(adapter.api,"0.22.0")
7569
- const versionUpdates=createVersionUpdateActions(adapter.api,versionStatus,createOpenCodeV2VersionUpdater(context),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.22.0"))
7767
+ }=updateServices
7768
+ const versionStatus=createVersionStatus(adapter.api,"0.24.0")
7769
+ const versionUpdates=createVersionUpdateActions(adapter.api,versionStatus,createOpenCodeV2VersionUpdater(context),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.24.0"))
7770
+ bindNavigatorAbout(adapter.api,versionStatus,versionUpdates,updateServices)
7570
7771
  const disposeFooter=context.ui.slot({append:"sidebar.footer",render:()=>_$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7571
7772
  },get multilineCorners(){return preferences.cornerFont
7572
7773
  },get children(){var _el$=_$createElement("box")
7573
7774
  _$setProp(_el$,"flexDirection","row")
7574
7775
  _$setProp(_el$,"justifyContent","space-between")
7575
7776
  _$insert(_el$,_$createComponent(VersionSummary,{get api(){return adapter.api
7576
- },navigatorVersion:"0.22.0",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7777
+ },navigatorVersion:"0.24.0",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7577
7778
  },get onNavigatorUpdate(){return versionUpdates.navigator
7578
7779
  }}),null)
7579
7780
  _$insert(_el$,_$createComponent(SettingsFooterButton,{get api(){return adapter.api
@@ -7588,5 +7789,5 @@ await adapter.dispose()
7588
7789
  var plugin={id:PLUGIN_ID,tui:setupOpenCodeV1,setup:setupOpenCodeV2
7589
7790
  }
7590
7791
  var plugin_default=plugin
7591
- export{DEFAULT_SECTION_EXPANSION,DialogAction,DialogHeader,DialogSurface,FOCUS_COMMAND,FirstRunWizard,GuardedConfirmation,IconControl,IconPicker,KeyboardHelpDialog,LspBadge,McpSection,SelectionMenu as PresetMenu,QUICK_ACTIONS,QUICK_ACTION_IDS,Section,SectionFilter,SelectionBox,SelectionMenu,SettingsDialog,SidebarFocusBinding,SidebarToggleBinding,SkillsSection,Tab,TodoSection,createDialogStack,createMcpController,createNativeTodoController,createPreferencesController,createQuickActionRevision,createSidebarInteraction,createSkillController,createSubagentController,createTodoController,currentPermissionMode,plugin_default as default,hostCapabilities,hostCapabilityUnavailable,isEffectivelyVisible,lspIcon,matchesFilter,openFirstRunWizard,openKeyboardHelp,openSettings,orderQuickActionIds,parseQuickActionOrder,parseQuickActionVisibility,quickActionDisabledReason,quickActionLabel,quickActionRequiresSession,quickActionState,quickActionStates,setHostCapabilities,setQuickActionStateSource,showFirstRunWizard,subtleLineColor,supportsPermissionMode,supportsSidebarSection,supportsTitleVisibility,terminalIcon,terminalIconIDs,terminalIconLabel,useDialogScroll,useDialogState,useDialogs,useIcons
7792
+ export{DEFAULT_SECTION_EXPANSION,DialogAction,DialogHeader,DialogSurface,FOCUS_COMMAND,FirstRunWizard,GuardedConfirmation,IconControl,IconPicker,KeyboardHelpDialog,LspBadge,McpSection,SelectionMenu as PresetMenu,QUICK_ACTIONS,QUICK_ACTION_IDS,Section,SectionFilter,SelectionBox,SelectionMenu,SettingsDialog,SidebarFocusBinding,SidebarToggleBinding,SkillsSection,Tab,TodoSection,createDialogStack,createMcpController,createNativeTodoController,createPreferencesController,createQuickActionRevision,createSidebarInteraction,createSkillController,createSubagentController,createTodoController,currentPermissionMode,plugin_default as default,getNavigatorAboutServices,hostCapabilities,hostCapabilityUnavailable,isEffectivelyVisible,lspIcon,matchesFilter,openFirstRunWizard,openKeyboardHelp,openSettings,orderQuickActionIds,parseQuickActionOrder,parseQuickActionVisibility,quickActionDisabledReason,quickActionLabel,quickActionRequiresSession,quickActionState,quickActionStates,registerNavigatorAboutServices,setHostCapabilities,setQuickActionStateSource,showFirstRunWizard,subtleLineColor,supportsPermissionMode,supportsSidebarSection,supportsTitleVisibility,terminalIcon,terminalIconIDs,terminalIconLabel,useDialogScroll,useDialogState,useDialogs,useIcons
7592
7793
  }