opencode-navigator 0.19.3 → 0.21.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
@@ -3,14 +3,14 @@ import {insert as _$insert,setProp as _$setProp,createElement as _$createElement
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,Show,splitProps as splitProps3,createSignal as createSignal4,createSignal as createSignal5,createSignal as createSignal6,onCleanup as onCleanup3,batch,createSignal as createSignal8,createSignal as createSignal7,createEffect as createEffect4,createSignal as createSignal9,onCleanup as onCleanup4,createSignal as createSignal10,createSignal as createSignal11,Index,createSignal as createSignal12,onCleanup as onCleanup5,createEffect as createEffect6,onCleanup as onCleanup7,batch as batch2,createEffect as createEffect5,createMemo,createSignal as createSignal13,onCleanup as onCleanup6,onMount,For as For2,For as For3,Show as Show2,createMemo as createMemo2,Show as Show3,createSignal as createSignal14,onCleanup as onCleanup8,For as For4,For as For5,For as For8,createMemo as createMemo4,onMount as onMount3,For as For7,createMemo as createMemo3,onMount as onMount2,Show as Show5,createEffect as createEffect7,createSignal as createSignal15,onCleanup as onCleanup9,Show as Show4,For as For6,For as For9,createEffect as createEffect8,createMemo as createMemo5,onCleanup as onCleanup10,createEffect as createEffect9,createMemo as createMemo6,untrack as untrack2,For as For10,createEffect as createEffect10,createMemo as createMemo9,onCleanup as onCleanup11,onMount as onMount4,createMemo as createMemo7,createMemo as createMemo8,Show as Show6,onCleanup as onCleanup12,createEffect as createEffect11,onCleanup as onCleanup13,createSignal as createSignal16,createEffect as createEffect12,onCleanup as onCleanup14,onMount as onMount5,onCleanup as onCleanup15,onMount as onMount6,For as For11,createSignal as createSignal17,createSignal as createSignal18,Show as Show7,createSignal as createSignal20,createSignal as createSignal19,onCleanup as onCleanup16,For as For12,Show as Show10,createMemo as createMemo11,createComputed,createMemo as createMemo10,createSignal as createSignal21,untrack as untrack3,Show as Show8,createComputed as createComputed2,untrack as untrack4,Show as Show9,createEffect as createEffect13,createSignal as createSignal22,createMemo as createMemo13,createSignal as createSignal25,createMemo as createMemo12,For as For13,Show as Show14,Show as Show11,Show as Show12,createSignal as createSignal23,createContext as createContext3,useContext as useContext3,Show as Show13,createSignal as createSignal24,onCleanup as onCleanup17,For as For14,Show as Show16,createMemo as createMemo15,Show as Show15,createMemo as createMemo14,createSignal as createSignal26,createEffect as createEffect14,onCleanup as onCleanup18,For as For19,Match,Switch,createMemo as createMemo19,onCleanup as onCleanup22,For as For15,Show as Show17,createSignal as createSignal27,createEffect as createEffect15,createMemo as createMemo16,onCleanup as onCleanup19,untrack as untrack5,For as For17,Show as Show20,createEffect as createEffect16,createMemo as createMemo17,createSignal as createSignal28,onCleanup as onCleanup20,untrack as untrack6,For as For16,Show as Show19,Show as Show18,Show as Show24,createEffect as createEffect17,createMemo as createMemo18,createSignal as createSignal29,onCleanup as onCleanup21,untrack as untrack7,For as For18,Show as Show22,Show as Show21,Show as Show23,createEffect as createEffect18,createMemo as createMemo20,onCleanup as onCleanup23,untrack as untrack8,Show as Show25,createMemo as createMemo21,onCleanup as onCleanup24,createSignal as createSignal30,onCleanup as onCleanup25,onMount as onMount7} from "solid-js"
7
- var SIDEBAR_SECTIONS=["todo","subagents","skills","quick_actions","lsp","mcp"]
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,createSignal as createSignal4,createSignal as createSignal5,createSignal as createSignal6,onCleanup as onCleanup3,batch,createSignal as createSignal8,createSignal as createSignal7,createEffect as createEffect5,createSignal as createSignal9,onCleanup as onCleanup4,createSignal as createSignal10,createSignal as createSignal11,Index,createSignal as createSignal12,onCleanup as onCleanup5,createEffect as createEffect7,onCleanup as onCleanup7,batch as batch2,createEffect as createEffect6,createMemo,createSignal as createSignal13,onCleanup as onCleanup6,onMount,For as For2,For as For3,Show as Show2,createMemo as createMemo2,Show as Show3,createSignal as createSignal14,onCleanup as onCleanup8,For as For4,For as For5,For as For8,createMemo as createMemo4,onMount as onMount3,For as For7,createMemo as createMemo3,onMount as onMount2,Show as Show5,createEffect as createEffect8,createSignal as createSignal15,onCleanup as onCleanup9,Show as Show4,For as For6,For as For9,createEffect as createEffect9,createMemo as createMemo5,onCleanup as onCleanup10,createEffect as createEffect10,createMemo as createMemo6,untrack as untrack2,For as For10,createEffect as createEffect11,createMemo as createMemo8,onCleanup as onCleanup11,onMount as onMount4,createMemo as createMemo7,Show as Show6,onCleanup as onCleanup12,createEffect as createEffect12,onCleanup as onCleanup13,createSignal as createSignal16,createMemo as createMemo9,createEffect as createEffect13,onCleanup as onCleanup14,onMount as onMount5,onCleanup as onCleanup15,onMount as onMount6,For as For11,createSignal as createSignal17,createSignal as createSignal18,Show as Show7,createSignal as createSignal20,createSignal as createSignal19,onCleanup as onCleanup16,For as For12,Show as Show10,createMemo as createMemo11,createComputed,createMemo as createMemo10,createSignal as createSignal21,untrack as untrack3,Show as Show8,createComputed as createComputed2,untrack as untrack4,Show as Show9,createEffect as createEffect14,createSignal as createSignal22,createMemo as createMemo13,createSignal as createSignal25,createMemo as createMemo12,For as For13,Show as Show14,Show as Show11,Show as Show12,createSignal as createSignal23,createContext as createContext3,useContext as useContext3,Show as Show13,createSignal as createSignal24,onCleanup as onCleanup17,Show as Show17,createSignal as createSignal26,untrack as untrack5,createSignal as createSignal27,createEffect as createEffect15,For as For14,createSignal as createSignal28,onMount as onMount7,Show as Show15,Show as Show16,For as For15,Show as Show19,createMemo as createMemo15,Show as Show18,createMemo as createMemo14,createSignal as createSignal29,createEffect as createEffect16,onCleanup as onCleanup18,For as For20,Match,Switch,createMemo as createMemo19,onCleanup as onCleanup22,For as For16,Show as Show20,createSignal as createSignal30,createEffect as createEffect17,createMemo as createMemo16,onCleanup as onCleanup19,untrack as untrack6,For as For18,Show as Show23,createEffect as createEffect18,createMemo as createMemo17,createSignal as createSignal31,onCleanup as onCleanup20,untrack as untrack7,For as For17,Show as Show22,Show as Show21,Show as Show27,createEffect as createEffect19,createMemo as createMemo18,createSignal as createSignal32,onCleanup as onCleanup21,untrack as untrack8,For as For19,Show as Show25,Show as Show24,Show as Show26,createEffect as createEffect20,createMemo as createMemo20,onCleanup as onCleanup23,untrack as untrack9,Show as Show28,createMemo as createMemo21,onCleanup as onCleanup24,createEffect as createEffect21,onCleanup as onCleanup25,untrack as untrack10,createSignal as createSignal33,onCleanup as onCleanup26,onMount as onMount8} from "solid-js"
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"
10
10
  }
11
- var DEFAULT_SECTION_EXPANSION={todo:true,subagents:false,skills:false,quick_actions:false,lsp:false,mcp:false
11
+ var DEFAULT_SECTION_EXPANSION={limits:true,todo:true,subagents:false,skills:false,quick_actions:false,lsp:false,mcp:false
12
12
  }
13
- var SECTION_DEFINITIONS=[{name:"todo",label:"Todo"},{name:"subagents",label:"Subagents"},{name:"skills",label:"Skills"},{name:"quick_actions",label:"Quick actions"},{name:"lsp",label:"LSP"},{name:"mcp",label:"MCP"}]
13
+ var SECTION_DEFINITIONS=[{name:"limits",label:"Limits"},{name:"todo",label:"Todo"},{name:"subagents",label:"Subagents"},{name:"skills",label:"Skills"},{name:"quick_actions",label:"Quick actions"},{name:"lsp",label:"LSP"},{name:"mcp",label:"MCP"}]
14
14
  function parseQuickActionOrder(value){if(!Array.isArray(value))
15
15
  return
16
16
  const order=[...new Set(value.filter((id)=>QUICK_ACTION_IDS.includes(id)))]
@@ -30,9 +30,11 @@ continue
30
30
  seen.add(candidate)
31
31
  order.push(candidate)
32
32
  }
33
- for(const section of SIDEBAR_SECTIONS){if(!seen.has(section))
33
+ for(const section of SIDEBAR_SECTIONS){if(!seen.has(section)){if(section==="limits")
34
+ order.unshift(section)
35
+ else
34
36
  order.push(section)
35
- }
37
+ }}
36
38
  return order
37
39
  }
38
40
  function parseSectionPreferences(value){if(!value||typeof value!=="object"||Array.isArray(value))
@@ -61,7 +63,7 @@ return defaults
61
63
  const input=value
62
64
  return Object.fromEntries(Object.entries(defaults).map(([name,visible])=>[name,typeof input[name]==="boolean"?input[name]:visible]))
63
65
  }
64
- function parseSectionVisibility(value){return resolveSectionVisibility({todo:true,subagents:true,skills:true,quick_actions:true,lsp:true,mcp:true
66
+ function parseSectionVisibility(value){return resolveSectionVisibility({limits:true,todo:true,subagents:true,skills:true,quick_actions:true,lsp:true,mcp:true
65
67
  },value)
66
68
  }
67
69
  var PLUGIN_ID="opencode-navigator"
@@ -495,7 +497,7 @@ return changeMany({action:state.action,...state.preset&&{preset:state.preset},..
495
497
 
496
498
 
497
499
 
498
- var ICONS={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"," "]
500
+ 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"," "]
499
501
  }
500
502
  function uiIcon(name,style="nerd"){return ICONS[name][style==="text"?1:0]
501
503
  }
@@ -915,13 +917,13 @@ return _el$
915
917
 
916
918
 
917
919
 
918
- function PresetMenu(props){const icons=useIcons()
920
+ function SelectionMenu(props){const icons=useIcons()
919
921
  const dialogs=useDialogs(props.api)
920
922
  const scroll=useDialogScroll()
921
923
  const [active,setActive]=useDialogState("selection",0)
922
924
  const theme=()=>props.api.theme.current
923
925
  let body
924
- const prefix=`${PLUGIN_ID}.mcp-preset-menu`
926
+ const prefix=`${PLUGIN_ID}.selection-menu`
925
927
  createEffect3(()=>{if(active()>=props.options.length)
926
928
  setActive(Math.max(0,props.options.length-1))
927
929
  })
@@ -1016,6 +1018,19 @@ return _el$7
1016
1018
  }
1017
1019
 
1018
1020
 
1021
+ function GuardedConfirmation(props){const dialogs=useDialogs(props.api)
1022
+ createEffect4(()=>{if(!props.current())
1023
+ dialogs.close()
1024
+ })
1025
+ return _$createComponent(props.api.ui.DialogConfirm,{get title(){return props.title
1026
+ },get message(){return props.message
1027
+ },onConfirm:()=>{if(props.current())
1028
+ props.onConfirm()
1029
+ },get onCancel(){return dialogs.back
1030
+ }})
1031
+ }
1032
+
1033
+
1019
1034
 
1020
1035
 
1021
1036
 
@@ -1061,13 +1076,43 @@ return _p$
1061
1076
  return _el$
1062
1077
  }}))
1063
1078
  }
1064
- function McpErrorDialog(props){return _$createComponent(PresetMenu,{get api(){return props.api
1079
+ function McpErrorDialog(props){return _$createComponent(SelectionMenu,{get api(){return props.api
1065
1080
  },get title(){return `MCP error \xB7 ${props.name}`
1066
1081
  },height:12,get options(){return [{title:`Status \xB7 ${props.status}`,value:"error",description:props.error,icon:"error"
1067
1082
  }]
1068
1083
  },onSelect:()=>{}})
1069
1084
  }
1070
1085
 
1086
+ function codexBindingKey(target){return JSON.stringify([target.providerID,target.connectionID?{connectionID:target.connectionID}:null])
1087
+ }
1088
+ function legacyKey(key){try{const value=JSON.parse(key)
1089
+ return Array.isArray(value)&&value.length===2&&value.every((part)=>typeof part==="string"&&part)?value:undefined
1090
+ } catch{return
1091
+ }}
1092
+ function migrateCodexAccountBindings(value){if(!value||typeof value!=="object"||Array.isArray(value))
1093
+ return{}
1094
+ return Object.fromEntries(Object.entries(value).filter(([key,account])=>key&&typeof account==="string"&&account.trim()))
1095
+ }
1096
+ function codexBindingAccount(bindings,target,modelID){const confirmed=bindings[codexBindingKey(target)]
1097
+ if(confirmed||target.connectionID)
1098
+ return confirmed
1099
+ const legacy=Object.entries(bindings).filter(([key])=>legacyKey(key)?.[0]===target.providerID)
1100
+ const accounts=new Set(legacy.map(([,account])=>account))
1101
+ if(accounts.size===1)
1102
+ return [...accounts][0]
1103
+ return modelID?bindings[JSON.stringify([target.providerID,modelID])]:undefined
1104
+ }
1105
+ function changeCodexBinding(current,target,accountID){const next=migrateCodexAccountBindings(current)
1106
+ if(!target.connectionID){for(const key of Object.keys(next)){if(legacyKey(key)?.[0]===target.providerID)
1107
+ delete next[key]
1108
+ }}
1109
+ const key=codexBindingKey(target)
1110
+ if(accountID)
1111
+ next[key]=accountID
1112
+ else
1113
+ delete next[key]
1114
+ return next
1115
+ }
1071
1116
  function assignGroup(groups,key,value){const next={...groups}
1072
1117
  if(!key)
1073
1118
  return next
@@ -1222,6 +1267,10 @@ return server.trim()&&group?[[server,group]]:[]
1222
1267
  }))
1223
1268
  }
1224
1269
  var parseSkillGroups=parseMcpServerGroups
1270
+ function parsePendingResetAttempt(value){const input=record(value)
1271
+ if(!input||typeof input.providerID!=="string"||typeof input.modelID!=="string"||typeof input.accountID!=="string"||typeof input.idempotencyKey!=="string"||!/^[\da-f]{8}(?:-[\da-f]{4}){3}-[\da-f]{12}$/iu.test(input.idempotencyKey)||typeof input.createdAt!=="number"||!Number.isFinite(input.createdAt)||input.creditID!==undefined&&typeof input.creditID!=="string"||input.connectionID!==undefined&&(typeof input.connectionID!=="string"||!input.connectionID))
1272
+ return
1273
+ return{providerID:input.providerID,modelID:input.modelID,accountID:input.accountID,idempotencyKey:input.idempotencyKey,createdAt:input.createdAt,...input.creditID&&{creditID:input.creditID},...input.connectionID&&{connectionID:input.connectionID}}}
1225
1274
  function parseWorkspaceProfiles(value){return Object.fromEntries(Object.entries(record(value)??{}).flatMap(([layout,rawMcp])=>{const layoutName=layout.trim().slice(0,64)
1226
1275
  const mcpName=typeof rawMcp==="string"?rawMcp.trim().slice(0,64):""
1227
1276
  return layoutName&&mcpName?[[layoutName,mcpName]]:[]
@@ -1256,11 +1305,13 @@ const recentSkills=parseRecentSkills(userInput?.recentSkills)
1256
1305
  const recentQuickActions=parseRecentQuickActions(userInput?.recentQuickActions)
1257
1306
  const mcpServerGroups=parseMcpServerGroups(userInput?.mcpServerGroups)
1258
1307
  const skillGroups=parseSkillGroups(userInput?.skillGroups)
1308
+ const codexAccountBindings=migrateCodexAccountBindings(userInput?.codexAccountBindings)
1309
+ const pendingResetAttempt=parsePendingResetAttempt(userInput?.pendingResetAttempt)
1259
1310
  const workspaceProfiles=parseWorkspaceProfiles(userInput?.workspaceProfiles)
1260
1311
  return{global:{...Object.keys(behavior).length>0&&{behavior},...layout&&{layout},...Object.keys(globalMcp).length>0&&{mcp:globalMcp}},worktrees,user:{...skippedSkillConfirmations&&{skippedSkillConfirmations},...typeof userInput?.onboardingCompleted==="boolean"&&{onboardingCompleted:userInput.onboardingCompleted
1261
1312
  },...typeof userInput?.lastNavigatorVersion==="string"&&{lastNavigatorVersion:userInput.lastNavigatorVersion
1262
1313
  },...typeof userInput?.previousNavigatorVersion==="string"&&{previousNavigatorVersion:userInput.previousNavigatorVersion
1263
- },...Object.keys(layoutPresets).length>0&&{layoutPresets},...Object.keys(mcpPresets).length>0&&{mcpPresets},...favoriteSkills&&{favoriteSkills},...favoriteMcpServers?.length&&{favoriteMcpServers},...favoriteQuickActions.length>0&&{favoriteQuickActions},...recentSkills.length>0&&{recentSkills},...recentQuickActions.length>0&&{recentQuickActions},...Object.keys(mcpServerGroups).length>0&&{mcpServerGroups},...Object.keys(skillGroups).length>0&&{skillGroups},...typeof userInput?.autoApprovePermissions==="boolean"&&{autoApprovePermissions:userInput.autoApprovePermissions
1314
+ },...Object.keys(layoutPresets).length>0&&{layoutPresets},...Object.keys(mcpPresets).length>0&&{mcpPresets},...favoriteSkills&&{favoriteSkills},...favoriteMcpServers?.length&&{favoriteMcpServers},...favoriteQuickActions.length>0&&{favoriteQuickActions},...recentSkills.length>0&&{recentSkills},...recentQuickActions.length>0&&{recentQuickActions},...Object.keys(mcpServerGroups).length>0&&{mcpServerGroups},...Object.keys(skillGroups).length>0&&{skillGroups},...Object.keys(codexAccountBindings).length>0&&{codexAccountBindings},...pendingResetAttempt&&{pendingResetAttempt},...typeof userInput?.autoApprovePermissions==="boolean"&&{autoApprovePermissions:userInput.autoApprovePermissions
1264
1315
  },...Object.keys(workspaceProfiles).length>0&&{workspaceProfiles}}}}
1265
1316
  function parseValues(value){if(!value)
1266
1317
  return{}
@@ -1408,6 +1459,16 @@ const recentSkills=parseRecentSkills([...update.user?.recentSkill?[update.user.r
1408
1459
  const recentQuickActions=parseRecentQuickActions([...update.user?.recentQuickAction?[update.user.recentQuickAction]:[],...current.user.recentQuickActions??[]])
1409
1460
  const mcpServerGroups=assignGroup(current.user.mcpServerGroups,update.user?.mcpServerGroup?.name,update.user?.mcpServerGroup?.group)
1410
1461
  const skillGroups=assignGroup(current.user.skillGroups,update.user?.skillGroup?.location,update.user?.skillGroup?.group)
1462
+ const binding=update.user?.codexAccountBinding
1463
+ const legacyBindingKey=binding?.providerID&&binding.modelID?JSON.stringify([binding.providerID,binding.modelID]):undefined
1464
+ const codexAccountBindings=binding?.providerID&&!binding.modelID?changeCodexBinding(current.user.codexAccountBindings,binding,binding.accountID):assignGroup(current.user.codexAccountBindings,legacyBindingKey,binding?.accountID)
1465
+ const pendingUpdate=update.user?.pendingResetAttempt
1466
+ const currentAttempt=current.user.pendingResetAttempt
1467
+ if(pendingUpdate&&currentAttempt&&currentAttempt.idempotencyKey!==pendingUpdate.idempotencyKey){throw new Error("Another reset attempt is still unresolved")
1468
+ }
1469
+ if(update.user?.clearPendingResetAttempt&&currentAttempt?.idempotencyKey!==update.user.clearPendingResetAttempt){throw new Error("Reset attempt changed; refresh before retrying")
1470
+ }
1471
+ const pendingResetAttempt=update.user?.clearPendingResetAttempt?undefined:pendingUpdate??currentAttempt
1411
1472
  const favoriteSkills=update.user?.favoriteSkills?parseSkillConfirmations(update.user.favoriteSkills):[...current.user.favoriteSkills??[]]
1412
1473
  const favoriteSkill=update.user?.favoriteSkill
1413
1474
  if(favoriteSkill?.location){const index=favoriteSkills.indexOf(favoriteSkill.location)
@@ -1423,7 +1484,8 @@ return{global:target.kind==="global"?scope:current.global,worktrees,user:{...ski
1423
1484
  },...(update.user?.previousNavigatorVersion??current.user.previousNavigatorVersion)&&{previousNavigatorVersion:update.user?.previousNavigatorVersion??current.user.previousNavigatorVersion
1424
1485
  },...Object.keys(parsedLayoutPresets).length>0&&{layoutPresets:parsedLayoutPresets},...Object.keys(parsedMcpPresets).length>0&&{mcpPresets:parsedMcpPresets},...Object.keys(workspaceProfiles).length>0&&{workspaceProfiles:parseWorkspaceProfiles(workspaceProfiles)
1425
1486
  },...favoriteSkills.length>0&&{favoriteSkills},...favoriteMcpServers.size>0&&{favoriteMcpServers:[...favoriteMcpServers].sort()},...favoriteQuickActions.size>0&&{favoriteQuickActions:parseFavoriteQuickActions([...favoriteQuickActions])
1426
- },...recentSkills.length>0&&{recentSkills},...recentQuickActions.length>0&&{recentQuickActions},...Object.keys(mcpServerGroups).length>0&&{mcpServerGroups:parseMcpServerGroups(mcpServerGroups)},...Object.keys(skillGroups).length>0&&{skillGroups:parseSkillGroups(skillGroups)},...typeof (update.user?.autoApprovePermissions??current.user.autoApprovePermissions)==="boolean"&&{autoApprovePermissions:update.user?.autoApprovePermissions??current.user.autoApprovePermissions
1487
+ },...recentSkills.length>0&&{recentSkills},...recentQuickActions.length>0&&{recentQuickActions},...Object.keys(mcpServerGroups).length>0&&{mcpServerGroups:parseMcpServerGroups(mcpServerGroups)},...Object.keys(skillGroups).length>0&&{skillGroups:parseSkillGroups(skillGroups)},...Object.keys(codexAccountBindings).length>0&&{codexAccountBindings:migrateCodexAccountBindings(codexAccountBindings)
1488
+ },...pendingResetAttempt&&{pendingResetAttempt},...typeof (update.user?.autoApprovePermissions??current.user.autoApprovePermissions)==="boolean"&&{autoApprovePermissions:update.user?.autoApprovePermissions??current.user.autoApprovePermissions
1427
1489
  }}}}
1428
1490
  function targetForLegacyScope(scope){return scope==="global"?{kind:"global"}:{kind:"worktree",key:scope}}
1429
1491
  function createPreferencesStore(stateDirectory){const directory=join(stateDirectory,LEGACY_PLUGIN_ID)
@@ -1594,6 +1656,8 @@ const [recentQuickActions,setRecentQuickActions]=createSignal4([])
1594
1656
  const [mcpServerGroups,setMcpServerGroups]=createSignal4(configured.mcpServerGroups??{})
1595
1657
  const [skillGroups,setSkillGroups]=createSignal4({})
1596
1658
  const [autoApprovePermissions,setAutoApprovePermissions]=createSignal4()
1659
+ const [codexAccountBindings,setCodexAccountBindings]=createSignal4({})
1660
+ const [pendingResetAttempt,setPendingResetAttempt]=createSignal4()
1597
1661
  const [ready,setReady]=createSignal4(false)
1598
1662
  const [revision,setRevision]=createSignal4(0)
1599
1663
  const sessionLayouts=new Map
@@ -1663,6 +1727,8 @@ setRecentQuickActions(value.user.recentQuickActions??[])
1663
1727
  setMcpServerGroups({...configured.mcpServerGroups,...value.user.mcpServerGroups})
1664
1728
  setSkillGroups(value.user.skillGroups??{})
1665
1729
  setAutoApprovePermissions(value.user.autoApprovePermissions)
1730
+ setCodexAccountBindings(value.user.codexAccountBindings??{})
1731
+ setPendingResetAttempt(value.user.pendingResetAttempt)
1666
1732
  setReady(true)
1667
1733
  refreshResolved()
1668
1734
  }
@@ -1783,6 +1849,14 @@ return
1783
1849
  setAutoApprovePermissions(value)
1784
1850
  update({user:{autoApprovePermissions:value}})
1785
1851
  }
1852
+ function changeCodexConnectionBinding(providerID,connectionID,accountID){if(!isHydrated){load().then(()=>changeCodexConnectionBinding(providerID,connectionID,accountID))
1853
+ return
1854
+ }
1855
+ if(!providerID)
1856
+ return
1857
+ setCodexAccountBindings((bindings)=>changeCodexBinding(bindings,{providerID,connectionID},accountID))
1858
+ update({user:{codexAccountBinding:{providerID,connectionID,accountID}}})
1859
+ }
1786
1860
  function toggleFavoriteMcpServer(name){if(!isHydrated){load().then(()=>toggleFavoriteMcpServer(name))
1787
1861
  return
1788
1862
  }
@@ -1853,7 +1927,13 @@ throw new Error("MCP preset no longer exists")
1853
1927
  update({user:{workspaceProfile:{layout,mcp}}})
1854
1928
  },favoriteSkills,favoriteMcpServers,favoriteQuickActions,toggleFavoriteMcpServer,toggleFavoriteQuickAction,recentSkills,recentQuickActions,mcpServerGroups,setMcpServerGroup(name,value){setMcpServerGroups(assignGroup(mcpServerGroups(),name,value))
1855
1929
  update({user:{mcpServerGroup:{name,group:value}}})
1856
- },skillGroups,setSkillGroup:changeSkillGroup,autoApprovePermissions,setAutoApprovePermissions:changeAutoApprovePermissions,async recordSkillUse(skill){await load()
1930
+ },skillGroups,setSkillGroup:changeSkillGroup,autoApprovePermissions,setAutoApprovePermissions:changeAutoApprovePermissions,codexAccountForModel:(providerID,modelID)=>codexBindingAccount(codexAccountBindings(),{providerID},modelID),setCodexAccountBinding:(providerID,_modelID,accountID)=>changeCodexConnectionBinding(providerID,undefined,accountID),codexAccountForConnection:(providerID,connectionID,modelID)=>codexBindingAccount(codexAccountBindings(),{providerID,connectionID},modelID),setCodexConnectionBinding:changeCodexConnectionBinding,pendingResetAttempt,async beginResetAttempt(attempt){await load()
1931
+ await store.update({user:{pendingResetAttempt:attempt}})
1932
+ const current=await store.load()
1933
+ setPendingResetAttempt(current.user.pendingResetAttempt)
1934
+ },async finishResetAttempt(idempotencyKey){await store.update({user:{clearPendingResetAttempt:idempotencyKey}})
1935
+ setPendingResetAttempt(undefined)
1936
+ },async recordSkillUse(skill){await load()
1857
1937
  if(!skill.location)
1858
1938
  return
1859
1939
  setRecentSkills(parseRecentSkills([skill.location,...recentSkills()]))
@@ -2016,8 +2096,7 @@ update({target:selectedTarget(),clearMcp:true})
2016
2096
  },shouldConfirmSkill(skill){load()
2017
2097
  return !skippedSkills().has(skillKey(skill))
2018
2098
  },skipSkillConfirmation(skill){load()
2019
- const next=new Set(skippedSkills())
2020
- next.add(skillKey(skill))
2099
+ const next=new Set([...skippedSkills(),skillKey(skill)])
2021
2100
  setSkippedSkills(next)
2022
2101
  update({user:{skillConfirmation:{location:skillKey(skill),skipped:true}}})
2023
2102
  },revokeSkillConfirmation(location){load()
@@ -2643,7 +2722,7 @@ value=`${Math.floor(seconds / 60)}m ${String(seconds % 60).padStart(2, "0")}s`
2643
2722
  return value
2644
2723
  }
2645
2724
  function createSubagentClock(key){const [now,setNow]=createSignal9(Date.now())
2646
- createEffect4(()=>{if(key()===undefined)
2725
+ createEffect5(()=>{if(key()===undefined)
2647
2726
  return
2648
2727
  setNow(Date.now())
2649
2728
  const timer=setInterval(()=>setNow(Date.now()),1000)
@@ -3101,7 +3180,7 @@ unregister()
3101
3180
  onMount(()=>{input?.focus()
3102
3181
  refresh().catch(report)
3103
3182
  })
3104
- createEffect5(()=>{if(!sameContext())
3183
+ createEffect6(()=>{if(!sameContext())
3105
3184
  dialogs.close()
3106
3185
  })
3107
3186
  return{active,activeTab,activate,allErrors,byID,dialogs,errors,icons,loading,matches,prefix,query,queryScope,resultColors,results,selectTab,setBody(node){body=node
@@ -3338,7 +3417,7 @@ timers.add(timer)
3338
3417
  }},{name:`${LEGACY_PLUGIN_ID}.search`,run(){props.api.keymap.dispatchCommand(SEARCH_COMMAND)
3339
3418
  }}]
3340
3419
  })
3341
- createEffect6(()=>{const key=props.preferences.searchKey()
3420
+ createEffect7(()=>{const key=props.preferences.searchKey()
3342
3421
  const remove=props.api.keymap.registerLayer({mode:"base",bindings:[{key,cmd:SEARCH_COMMAND
3343
3422
  }]
3344
3423
  })
@@ -3352,18 +3431,6 @@ clearTimeout(timer)
3352
3431
  return _$createElement("box")
3353
3432
  }
3354
3433
 
3355
- function createLayoutPresetPreview(preferences,name){const scope=preferences.selectedScopeKey()
3356
- const valid=()=>preferences.selectedScopeKey()===scope
3357
- const preset=createMemo2(()=>preferences.layoutPresets()[name])
3358
- const preview=createMemo2(()=>{const value=preset()
3359
- return value?preferences.previewLayoutPreset(value):undefined
3360
- })
3361
- return{valid,preview,scope:preferences.preferenceScopeLabel,blocked:()=>preset()?"":"Preset no longer exists.",apply(){const value=preset()
3362
- if(!valid()||!value)
3363
- return false
3364
- preferences.applyLayoutPreset(value)
3365
- return true
3366
- }}}
3367
3434
  function createMcpPresetPreview(controller,preferences,name){const target=controller.target()
3368
3435
  const valid=()=>{const current=controller.target()
3369
3436
  return current.key===target.key&&current.scope===target.scope
@@ -3409,8 +3476,8 @@ function supportsTitleVisibility(api){return hostCapabilities(api).titleVisibili
3409
3476
  function supportsPermissionMode(api){return hostCapabilities(api).permissionMode!==false
3410
3477
  }
3411
3478
  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."}]
3412
- },{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."
3413
- },{icon:"history",title:"Direct navigation",description:"Open a child session without leaving your workflow."
3479
+ },{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."
3480
+ },{icon:"info",title:"Provider limits",description:"Link a matching Codex account for model quotas and confirmed banked resets."
3414
3481
  }]
3415
3482
  },{title:"Find anything and launch Skills safely",summary:"Search complete source lists without expanding every sidebar section.",icon:"search",features:[{icon:"search",title:"Search Everything",description:"Search Skills, Subagents, MCP, and Actions in shared tabs."
3416
3483
  },{icon:"search",title:"Full source lists",description:"Search beyond sidebar visibility and item limits."},{icon:"skills",title:"Skill confirmation",description:"Review a skill and its source before inserting its command."
@@ -3806,7 +3873,7 @@ const unregister=props.api.keymap.registerLayer({mode:"modal",priority:1000,comm
3806
3873
  }]
3807
3874
  })
3808
3875
  onCleanup9(unregister)
3809
- createEffect7(()=>{if(!props.valid())
3876
+ createEffect8(()=>{if(!props.valid())
3810
3877
  dialogs.close()
3811
3878
  })
3812
3879
  return _$createComponent(DialogSurface,{get api(){return props.api
@@ -3980,55 +4047,6 @@ const description=row.desired?{missing:`Not available in this workspace \xB7 tar
3980
4047
  return{icon:icons.icon("mcp"),title:row.name,description,changed:row.change==="connect"||row.change==="disconnect",skipped:row.change==="missing"||row.change==="unavailable",status:row.change==="connect"||row.change==="disconnect"?"changed":row.change==="missing"||row.change==="unavailable"?"skipped":"unchanged",statusIcon:row.change==="connect"?"connected":row.change==="disconnect"?"disconnected":row.change==="missing"||row.change==="unavailable"?"pending":"done",statusLabel:row.change==="connect"?"CONNECT":row.change==="disconnect"?"DISCONNECT":row.change==="missing"||row.change==="unavailable"?"SKIPPED":"UNCHANGED"
3981
4048
  }}).sort((a,b)=>Number(b.changed)-Number(a.changed)||Number(b.skipped)-Number(a.skipped))
3982
4049
  }
3983
- function LayoutPresetPreview(props){const dialogs=useDialogs(props.api)
3984
- const icons=useIcons()
3985
- const model=createLayoutPresetPreview(props.preferences,props.name)
3986
- const linked=props.preferences.workspaceProfiles?.()[props.name]
3987
- const mcpModel=props.controller&&linked?createMcpPresetPreview(props.controller,props.preferences,linked):undefined
3988
- const rows=createMemo4(()=>model.preview()?.rows.map((row)=>{const changes=[]
3989
- if(row.visibility[0]!==row.visibility[1])
3990
- changes.push(`${row.visibility[0] ? "visible" : "hidden"} -> ${row.visibility[1] ? "visible" : "hidden"}`)
3991
- if(row.expansion[0]!==row.expansion[1])
3992
- changes.push(`${row.expansion[0] ? "expanded" : "collapsed"} -> ${row.expansion[1] ? "expanded" : "collapsed"}`)
3993
- if(row.position[0]!==row.position[1])
3994
- changes.push(`position ${row.position[0]} -> ${row.position[1]}`)
3995
- return{icon:icons.section(row.section),title:`${row.position[1]}. ${SECTION_DEFINITIONS.find((section) => section.name === row.section).label}`,description:changes.join(" \xB7 ")||"No changes",changed:changes.length>0,status:changes.length>0?"changed":"unchanged",statusIcon:changes.length>0?"edit":"done",statusLabel:changes.length>0?"CHANGED":"UNCHANGED"
3996
- }}).sort((a,b)=>Number(b.changed)-Number(a.changed))??[])
3997
- const mcpRows=createMemo4(()=>mcpModel?mcpPreviewRows(mcpModel,icons):[])
3998
- const changed=()=>rows().filter((row)=>row.changed).length
3999
- onMount3(()=>mcpModel?.refresh())
4000
- return _$createComponent(PresetPreviewFrame,{get api(){return props.api
4001
- },get title(){return `${mcpModel ? "Workspace profile" : "Layout preview"}: ${props.name}`
4002
- },get scope(){return mcpModel?`${model.scope()} \xB7 MCP ${mcpModel.scope}`:model.scope()
4003
- },get stats(){return [{icon:"edit",label:`${changed()} layout changed`,tone:"accent"
4004
- },{icon:"done",label:`${rows().length - changed()} layout unchanged`,tone:"muted"
4005
- }]
4006
- },get rowCount(){return rows().length + mcpRows().length
4007
- },valid:()=>model.valid()&&(!mcpModel||mcpModel.valid()),get blocked(){return model.blocked()||mcpModel?.blocked()
4008
- },get onRefresh(){return mcpModel?.refresh
4009
- },notice:mcpModel?"Applies both presets; layout stays session-only.":"Applies layout changes. Save current layout as default to persist them.",onApply:()=>{const request=mcpModel?.apply()
4010
- if(mcpModel&&!request)
4011
- return
4012
- if(!model.apply())
4013
- return
4014
- if(mcpModel)
4015
- dialogs.close()
4016
- else{dialogs.back()
4017
- dialogs.back()
4018
- }
4019
- props.api.ui.toast({variant:"success",title:mcpModel?"Workspace profile":"Layout presets",message:`${props.name} applied to ${model.scope()}`,duration:3000
4020
- })
4021
- if(request)
4022
- reportMcpApplyError(props.api,request)
4023
- },get children(){return [_$createComponent(For8,{get each(){return rows()
4024
- },children:(row)=>_$createComponent(PresetPreviewRow,_$mergeProps({get api(){return props.api
4025
- }},row))
4026
- }),_$createComponent(For8,{get each(){return mcpRows()
4027
- },children:(row)=>_$createComponent(PresetPreviewRow,_$mergeProps({get api(){return props.api
4028
- }},row))
4029
- })]
4030
- }})
4031
- }
4032
4050
 
4033
4051
 
4034
4052
 
@@ -4058,7 +4076,7 @@ if(renameFrom)
4058
4076
  dialogs.back()
4059
4077
  }})
4060
4078
  }
4061
- function actions(name){dialogs.open(()=>_$createComponent(PresetMenu,{api,title:name,options:[{title:"Preview & apply",value:"apply",description:"review server changes before applying",icon:"info"
4079
+ function actions(name){dialogs.open(()=>_$createComponent(SelectionMenu,{api,title:name,options:[{title:"Preview & apply",value:"apply",description:"review server changes before applying",icon:"info"
4062
4080
  },{title:"Update from current",value:"update",description:"replace the saved states",icon:"save"
4063
4081
  },{title:"Rename",value:"rename",description:"change the preset name",icon:"edit"
4064
4082
  },{title:"Delete",value:"delete",description:"remove this preset",icon:"delete"
@@ -4090,7 +4108,7 @@ notify(`Deleted ${name}`)
4090
4108
  dialogs.back()
4091
4109
  }}))
4092
4110
  }
4093
- dialogs.open(()=>_$createComponent(PresetMenu,{api,title:"MCP presets",get options(){return [{title:"Save current",value:"save",description:"Create a preset from the current server states",icon:"save"
4111
+ dialogs.open(()=>_$createComponent(SelectionMenu,{api,title:"MCP presets",get options(){return [{title:"Save current",value:"save",description:"Create a preset from the current server states",icon:"save"
4094
4112
  },...Object.entries(preferences.mcpPresets()).map(([name,states])=>({title:name,value:`preset:${name}`,icon:"presets",description:`${Object.values(states).filter((state) => state === "enabled").length}/${Object.keys(states).length} enabled`
4095
4113
  }))]
4096
4114
  },onSelect:(option)=>option.value==="save"?prompt():actions(option.value.slice("preset:".length))
@@ -4123,61 +4141,6 @@ dialogs.open(()=>_$createComponent(PresetMenu,{api,title:"MCP presets",get optio
4123
4141
 
4124
4142
 
4125
4143
 
4126
-
4127
-
4128
-
4129
-
4130
-
4131
-
4132
- function createLayoutPresetActions(input){function prompt(value="",renameFrom){input.dialogs.prompt({title:renameFrom?"Rename layout preset":"Save layout preset",description:()=>(()=>{var _el$=_$createElement("text")
4133
- _$insertNode(_el$,_$createTextNode(`Save the current visible, expanded, and ordered sections.`))
4134
- _$effect((_$p)=>_$setProp(_el$,"fg",input.api.theme.current.textMuted,_$p))
4135
- return _el$
4136
- })(),placeholder:"Preset name",value,onConfirm(nameInput){const name=renameFrom?input.preferences.renameLayoutPreset(renameFrom,nameInput):input.preferences.saveLayoutPreset(nameInput)
4137
- input.dialogs.back()
4138
- if(renameFrom)
4139
- input.dialogs.back()
4140
- input.api.ui.toast({variant:"success",title:"Layout presets",message:renameFrom?`Renamed to ${name}`:`Saved ${name}`,duration:3000
4141
- })
4142
- }})
4143
- }
4144
- function open(name){const linked=input.preferences.workspaceProfiles?.()[name]
4145
- const link=()=>input.dialogs.prompt({title:`Link MCP \xB7 ${name}`,placeholder:"Preset; empty unlinks",value:linked??"",onConfirm(value){input.preferences.linkWorkspaceProfile?.(name,value.trim()||undefined)
4146
- input.dialogs.back()
4147
- input.dialogs.back()
4148
- }})
4149
- input.dialogs.open(()=>_$createComponent(PresetMenu,{get api(){return input.api
4150
- },title:name,get options(){return [{title:"Preview & apply",value:"apply",icon:"info",description:linked?`profile \xB7 ${linked}`:"review layout changes"
4151
- },{title:"Update from current",value:"update",icon:"save",description:"replace saved layout"
4152
- },{title:"Rename\u2026",value:"rename",description:"change preset name",icon:"edit"
4153
- },...input.mcp?[{title:linked?"Change MCP link\u2026":"Link MCP preset\u2026",value:"link",icon:"mcp",description:linked?`${linked} \xB7 empty unlinks`:"pair layout and MCP"
4154
- }]:[],{title:"Delete",value:"delete",description:"remove preset",icon:"delete"
4155
- }]
4156
- },onSelect:(option)=>{switch(option.value){case "apply":{input.dialogs.open(()=>_$createComponent(LayoutPresetPreview,{get api(){return input.api
4157
- },get preferences(){return input.preferences
4158
- },get controller(){return input.mcp
4159
- },name
4160
- }),"large")
4161
- break
4162
- }
4163
- case "update":{input.preferences.updateLayoutPreset(name)
4164
- input.dialogs.back()
4165
- input.api.ui.toast({variant:"success",title:"Layout presets",message:`Updated ${name}`,duration:3000
4166
- })
4167
- break
4168
- }
4169
- case "rename":{prompt(name,name)
4170
- break
4171
- }
4172
- case "link":{link()
4173
- break
4174
- }
4175
- default:{input.preferences.deleteLayoutPreset(name)
4176
- input.dialogs.back()
4177
- }}}}))
4178
- }
4179
- return{open,prompt
4180
- }}
4181
4144
 
4182
4145
  function titleVisibilityOptions(api,preferences,icons){if(!supportsTitleVisibility(api))
4183
4146
  return []
@@ -4246,25 +4209,6 @@ input.openLimitPrompt(section)
4246
4209
 
4247
4210
 
4248
4211
 
4249
-
4250
-
4251
- var RESET_ALL="__reset_all__"
4252
- function TrustedSkillsDialog(props){const options=createMemo8(()=>{const locations=props.preferences.trustedSkillLocations()
4253
- if(locations.length===0)
4254
- return [{title:"Every skill requires confirmation",value:"empty",description:"No trusted skills",icon:"info"
4255
- }]
4256
- return [{title:"Require confirmation for all",value:RESET_ALL,description:`Revoke trust for ${locations.length} skill${locations.length === 1 ? "" : "s"}`,icon:"reset"
4257
- },...locations.map((location)=>({title:location.split("/").at(-2)??location,value:location,description:location,icon:"checked"
4258
- }))]
4259
- })
4260
- return _$createComponent(PresetMenu,{get api(){return props.api
4261
- },title:"Trusted skills",get options(){return options()
4262
- },onSelect:(option)=>{if(option.value===RESET_ALL)
4263
- props.preferences.resetSkillConfirmations()
4264
- else if(option.value!=="empty")
4265
- props.preferences.revokeSkillConfirmation(option.value)
4266
- }})
4267
- }
4268
4212
  function createSettingsSelection(input){const dialogClosed=()=>("open" in input.api.ui.dialog)&&!input.api.ui.dialog.open
4269
4213
  function openLimitPrompt(section){const index=input.options().findIndex((option)=>option.value===section)
4270
4214
  if(index!==-1)
@@ -4300,36 +4244,11 @@ function exportSettings(){const copied=input.api.renderer.copyToClipboardOSC52(i
4300
4244
  input.api.ui.toast({variant:copied?"success":"warning",title:"Portable settings",message:copied?"Layout and MCP settings copied as JSON":"Terminal clipboard is unavailable",duration:4000
4301
4245
  })
4302
4246
  }
4303
- function importSettings(){input.dialogs.prompt({title:"Import portable settings",description:()=>(()=>{var _el$5=_$createElement("text")
4304
- _$insertNode(_el$5,_$createTextNode(`Paste versioned Navigator JSON.`))
4305
- _$effect((_$p)=>_$setProp(_el$5,"fg",input.api.theme.current.textMuted,_$p))
4306
- return _el$5
4307
- })(),onConfirm(source){const preview=input.preferences.previewPortableSettings(source)
4308
- const options=[...preview.settings.layout?[{title:`Layout \xB7 ${preview.layoutChanged ? "CHANGED" : "UNCHANGED"}`,value:"status",description:`${Object.keys(preview.settings.layout.sections).length} visibility \xB7 ${Object.keys(preview.settings.layout.expanded).length} expansion values`,icon:preview.layoutChanged?"edit":"done"
4309
- }]:[],...preview.settings.mcp?[{title:`MCP \xB7 ${preview.mcpChanged ? "CHANGED" : "UNCHANGED"}`,value:"status",description:`${Object.keys(preview.settings.mcp).length} remembered server states`,icon:preview.mcpChanged?"edit":"done"
4310
- }]:[],...preview.unsupported.map((path)=>({title:"Unsupported field \xB7 SKIPPED",value:"status",description:path,icon:"error"
4311
- })),...preview.layoutChanged||preview.mcpChanged?[{title:"Apply imported settings",value:"apply",description:preview.target,icon:"done"
4312
- }]:[],{title:"Cancel",value:"cancel",description:"return without changes",icon:"close"
4313
- }]
4314
- let applying=false
4315
- async function apply(){applying=true
4316
- try{await input.preferences.applyPortableSettings(preview)
4317
- input.api.ui.toast({variant:"success",title:"Portable settings",message:"Layout and MCP settings imported",duration:3000
4318
- })
4319
- input.dialogs.back()
4320
- } catch(error){applying=false
4321
- input.api.ui.toast({variant:"error",title:"Portable settings",message:error instanceof Error?error.message:"Could not import settings",duration:5000
4322
- })
4323
- }}
4324
- input.dialogs.replace(()=>_$createComponent(PresetMenu,{get api(){return input.api
4325
- },title:"Settings import preview",options,get height(){return Math.min(options.length*3,18)
4326
- },onSelect:(option)=>{if(option.value==="cancel")
4327
- input.dialogs.back()
4328
- if(option.value!=="apply"||applying)
4329
- return
4330
- apply()
4331
- }}))
4332
- }})
4247
+ function importSettings(){const path=import.meta.url.includes("/dist/tui.js")?"./settings-import.js":"../ui/settings-import-dialog"
4248
+ import(path).then((module)=>{if(!dialogClosed())
4249
+ module.openSettingsImport(input)
4250
+ }).catch((error)=>input.api.ui.toast({variant:"error",title:"Portable settings",message:String(error)
4251
+ }))
4333
4252
  }
4334
4253
  function select(value=input.options()[input.active()]?.value){if(!value)
4335
4254
  return
@@ -4400,9 +4319,16 @@ break
4400
4319
  case "reset_mcp":{input.preferences.resetMcpStates()
4401
4320
  break
4402
4321
  }
4403
- case "trusted_skills":{input.dialogs.open(()=>_$createComponent(TrustedSkillsDialog,{get api(){return input.api
4322
+ case "trusted_skills":{const path=import.meta.url.includes("/dist/tui.js")?"./trusted-skills.js":"../ui/trusted-skills-dialog"
4323
+ import(path).then((module)=>{if(dialogClosed())
4324
+ return
4325
+ const{TrustedSkillsDialog
4326
+ }=module
4327
+ input.dialogs.open(()=>_$createComponent(TrustedSkillsDialog,{get api(){return input.api
4404
4328
  },get preferences(){return input.preferences
4405
4329
  }}))
4330
+ }).catch((error)=>input.api.ui.toast({variant:"error",title:"Trusted skills",message:String(error)
4331
+ }))
4406
4332
  break
4407
4333
  }
4408
4334
  case "wizard":{input.dialogs.open(()=>_$createComponent(FirstRunWizard,{get api(){return input.api
@@ -4465,19 +4391,19 @@ const icons=useIcons()
4465
4391
  const dialogs=useDialogs(props.api)
4466
4392
  const scroll=useDialogScroll()
4467
4393
  const dimensions=useTerminalDimensions6()
4468
- const bodyHeight=createMemo9(()=>Math.max(4,Math.floor(dimensions().height*0.75)-10))
4394
+ const bodyHeight=createMemo8(()=>Math.max(4,Math.floor(dimensions().height*0.75)-10))
4469
4395
  const orderedGroups=createSettingsGroups(props.api,props.preferences,icons)
4470
4396
  const initialGroup=orderedGroups().find((group)=>group.options.some((option)=>option.value===props.activeValue))
4471
4397
  const [activeGroup,setActiveGroup]=useDialogState("tab",initialGroup?.id??orderedGroups()[0].id)
4472
- const options=createMemo9(()=>orderedGroups().find((group)=>group.id===activeGroup())?.options??[])
4398
+ const options=createMemo8(()=>orderedGroups().find((group)=>group.id===activeGroup())?.options??[])
4473
4399
  const optionId=(value)=>`${PLUGIN_ID}.settings.${value}`
4474
4400
  const initialActive=options().findIndex((option)=>option.value===props.activeValue)
4475
4401
  const [active,setActive]=useDialogState("selection",Math.max(0,initialActive))
4476
- createEffect10(()=>{if(active()>=options().length)
4402
+ createEffect11(()=>{if(active()>=options().length)
4477
4403
  setActive(Math.max(0,options().length-1))
4478
4404
  })
4479
- const contentHeight=createMemo9(()=>Math.min(bodyHeight(),Math.max(1,options().length*2-1)))
4480
- const footerHint=createMemo9(()=>{const common=`${icons.key("tab")} switch \xB7 ${icons.key("up/down")} navigate`
4405
+ const contentHeight=createMemo8(()=>Math.min(bodyHeight(),Math.max(1,options().length*2-1)))
4406
+ const footerHint=createMemo8(()=>{const common=`${icons.key("tab")} switch \xB7 ${icons.key("up/down")} navigate`
4481
4407
  if(activeGroup()==="sections")
4482
4408
  return `${common} \xB7 ${icons.key("enter")} toggle \xB7 l item limit${options()[active()]?.value === "quick_actions" ? " \xB7 a actions" : ""}${["mcp", "skills"].includes(options()[active()]?.value ?? "") ? " \xB7 g groups" : ""} \xB7 ${icons.key("left/right")} or ${icons.key("shift+up/down")} reorder`
4483
4409
  if(activeGroup()==="presets")
@@ -4518,9 +4444,20 @@ setActive(next)
4518
4444
  body?.scrollChildIntoView(optionId(value))
4519
4445
  })
4520
4446
  }
4521
- const presetActions=createLayoutPresetActions({api:props.api,preferences:props.preferences,mcp:props.mcp,dialogs
4447
+ function runPresetAction(action,name){const path=import.meta.url.includes("/dist/tui.js")?"./layout-preset-actions.js":"./layout-preset-actions"
4448
+ import(path).then((module)=>{if("open" in props.api.ui.dialog&&!props.api.ui.dialog.open)
4449
+ return
4450
+ const factory=module.createLayoutPresetActions
4451
+ const actions=factory({api:props.api,preferences:props.preferences,mcp:props.mcp,dialogs
4522
4452
  })
4523
- const selection=createSettingsSelection({api:props.api,preferences:props.preferences,mcp:props.mcp,skills:props.skills,dialogs,options,active,setActive,openPreset:presetActions.open,promptPreset:presetActions.prompt
4453
+ if(action==="open"&&name)
4454
+ actions.open(name)
4455
+ else
4456
+ actions.prompt()
4457
+ }).catch((error)=>props.api.ui.toast({variant:"error",title:"Layout presets",message:String(error)
4458
+ }))
4459
+ }
4460
+ const selection=createSettingsSelection({api:props.api,preferences:props.preferences,mcp:props.mcp,skills:props.skills,dialogs,options,active,setActive,openPreset:(name)=>runPresetAction("open",name),promptPreset:()=>runPresetAction("prompt")
4524
4461
  })
4525
4462
  const unregister=registerSettingsKeymap({api:props.api,active,activeGroup,options,move,switchGroup,reorder,select:selection.select,openQuickActions:selection.openQuickActions,openMcpGroups:selection.openMcpGroups,openSkillGroups:selection.openSkillGroups,openLimitPrompt:selection.openLimitPrompt
4526
4463
  })
@@ -4715,7 +4652,7 @@ return title.startsWith("Enable auto-approve permissions")?false:undefined
4715
4652
  }
4716
4653
  function PermissionModeBinding(props){let applying=false
4717
4654
  let observed
4718
- createEffect11(()=>{if(!props.preferences.ready())
4655
+ createEffect12(()=>{if(!props.preferences.ready())
4719
4656
  return
4720
4657
  const preferred=props.preferences.autoApprovePermissions()
4721
4658
  const current=currentPermissionMode(props.api)
@@ -4751,6 +4688,8 @@ return _$createComponent(IconControl,{id:`${PLUGIN_ID}.settings.footer`,get icon
4751
4688
  },onMouseOver:()=>setHovered(true),onMouseOut:()=>setHovered(false),onMouseUp:()=>openSettings(props.api,props.preferences,undefined,props.mcp,props.skills)
4752
4689
  })
4753
4690
  }
4691
+
4692
+
4754
4693
  import {realpathSync} from "fs"
4755
4694
  function routeKey(api){const route=api.route.current
4756
4695
  return `${route.name}:${"params" in route ? route.params?.sessionID ?? "" : ""}`
@@ -4814,7 +4753,7 @@ queueMicrotask(()=>void props.controller.start())
4814
4753
  })
4815
4754
  onCleanup14(unregister)
4816
4755
  } else
4817
- createEffect12(()=>{if(!props.controller.enabled())
4756
+ createEffect13(()=>{if(!props.controller.enabled())
4818
4757
  return
4819
4758
  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()
4820
4759
  }]
@@ -5112,7 +5051,7 @@ return !needle||values.some((value)=>value?.toLocaleLowerCase().includes(needle)
5112
5051
 
5113
5052
  function position(descriptor){return typeof descriptor.position==="function"?descriptor.position():descriptor.position
5114
5053
  }
5115
- var SECTION_COMMANDS=[{section:"todo",title:"Focus Todo"},{section:"subagents",title:"Focus Subagents"},{section:"skills",title:"Focus Skills"},{section:"quick_actions",title:"Focus Quick Actions"},{section:"lsp",title:"Focus LSP"},{section:"mcp",title:"Focus MCP"}]
5054
+ var SECTION_COMMANDS=[{section:"limits",title:"Focus Limits"},{section:"todo",title:"Focus Todo"},{section:"subagents",title:"Focus Subagents"},{section:"skills",title:"Focus Skills"},{section:"quick_actions",title:"Focus Quick Actions"},{section:"lsp",title:"Focus LSP"},{section:"mcp",title:"Focus MCP"}]
5116
5055
  function belongsTo(renderable,ancestor){if(!renderable||!ancestor)
5117
5056
  return false
5118
5057
  for(let current=renderable;current; current=current.parent){if(current===ancestor)
@@ -5551,7 +5490,7 @@ const item=useSidebarItem(props.api,props.interaction,{id:props.sectionId??`sect
5551
5490
  const action=props.headerAction?useSidebarItem(props.api,props.interaction,{id:props.headerAction.id,position:()=>({section:props.navigationSection??0,row:0,column:1
5552
5491
  }),disabled:props.headerAction.disabled,activate:props.headerAction.onActivate
5553
5492
  },()=>theme().accent,"control"):undefined
5554
- createEffect13(()=>{props.headerAction?.label()
5493
+ createEffect14(()=>{props.headerAction?.label()
5555
5494
  setActionWidth(undefined)
5556
5495
  })
5557
5496
  const actionLabel=()=>{const label=props.headerAction?.label()??""
@@ -6194,11 +6133,68 @@ return _$createComponent(SectionWithHeaderAction,{get api(){return props.api
6194
6133
 
6195
6134
 
6196
6135
 
6136
+
6137
+
6138
+
6139
+
6140
+
6141
+
6142
+
6143
+
6144
+
6145
+
6146
+
6147
+
6148
+
6149
+
6150
+
6151
+
6152
+
6153
+
6154
+
6155
+
6156
+
6157
+
6158
+
6159
+
6160
+
6161
+
6162
+
6163
+
6164
+
6165
+
6166
+
6167
+
6168
+
6169
+
6170
+
6171
+
6172
+
6173
+
6174
+
6175
+
6176
+
6177
+
6178
+
6179
+
6180
+
6181
+
6182
+
6183
+
6184
+
6185
+
6186
+
6187
+
6188
+
6189
+
6190
+
6191
+
6192
+
6197
6193
  function QuickActionRow(props){const{api,interaction
6198
6194
  }=useSidebarList()
6199
6195
  const icons=useIcons()
6200
6196
  const theme=()=>api.theme.current
6201
- const [width,setWidth]=createSignal26(0)
6197
+ const [width,setWidth]=createSignal29(0)
6202
6198
  const shortcut=createMemo14(()=>{const bindings=api.keymap.getCommandBindings({visibility:"registered",commands:[props.action.command]
6203
6199
  })
6204
6200
  return api.keys.formatBindings(bindings.get(props.action.command))
@@ -6242,7 +6238,7 @@ _$insert(_el$2,()=>props.action.label)
6242
6238
  _$effect((_$p)=>_$setProp(_el$2,"fg",row.foregroundColor(),_$p))
6243
6239
  return _el$2
6244
6240
  })()
6245
- },get metadata(){return _$createComponent(Show15,{get when(){return visibleShortcut()
6241
+ },get metadata(){return _$createComponent(Show18,{get when(){return visibleShortcut()
6246
6242
  },children:(value)=>(()=>{var _el$3=_$createElement("text")
6247
6243
  _$setProp(_el$3,"flexShrink",0)
6248
6244
  _$setProp(_el$3,"wrapMode","none")
@@ -6251,7 +6247,7 @@ _$effect((_$p)=>_$setProp(_el$3,"fg",row.focused()?row.foregroundColor():theme()
6251
6247
  return _el$3
6252
6248
  })()
6253
6249
  })
6254
- },get details(){return _$createComponent(Show15,{get when(){return props.disabled
6250
+ },get details(){return _$createComponent(Show18,{get when(){return props.disabled
6255
6251
  },children:(reason)=>(()=>{var _el$4=_$createElement("text")
6256
6252
  _$setProp(_el$4,"wrapMode","word")
6257
6253
  _$insert(_el$4,reason)
@@ -6279,12 +6275,12 @@ return _$createComponent(Section,{get api(){return props.api
6279
6275
  },onToggle:()=>props.preferences.toggleSectionExpanded("quick_actions"),get children(){return [_$createComponent(SidebarRowList,{get api(){return props.api
6280
6276
  },get interaction(){return props.interaction
6281
6277
  },get density(){return props.preferences.rowDensity?.()??"compact"
6282
- },get children(){return [_$createComponent(Show16,{get when(){return actions().length===0
6278
+ },get children(){return [_$createComponent(Show19,{get when(){return actions().length===0
6283
6279
  },get children(){var _el$=_$createElement("text")
6284
6280
  _$insertNode(_el$,_$createTextNode(`No quick actions selected`))
6285
6281
  _$effect((_$p)=>_$setProp(_el$,"fg",props.api.theme.current.textMuted,_$p))
6286
6282
  return _el$
6287
- }}),_$createComponent(For14,{get each(){return visibility.visible()
6283
+ }}),_$createComponent(For15,{get each(){return visibility.visible()
6288
6284
  },children:(action,index)=>_$createComponent(QuickActionRow,{get onNewSession(){return props.onNewSession
6289
6285
  },action,get disabled(){return action.disabled
6290
6286
  },get favorite(){return props.preferences.favoriteQuickActions?.().has(action.command)??false
@@ -6394,7 +6390,7 @@ unregisterBinding=undefined
6394
6390
  unregisterCommands()
6395
6391
  }}}
6396
6392
  function SidebarToggleBinding(props){const shortcuts=createSidebarShortcutMode(props.api)
6397
- createEffect14(()=>shortcuts.bind(props.preferences.toggleKey()))
6393
+ createEffect16(()=>shortcuts.bind(props.preferences.toggleKey()))
6398
6394
  onCleanup18(shortcuts.dispose)
6399
6395
  return _$createElement("box")
6400
6396
  }
@@ -6404,7 +6400,7 @@ const unregisterCommands=props.api.keymap.registerLayer({commands:[...commands,.
6404
6400
  }))]
6405
6401
  })
6406
6402
  onCleanup18(unregisterCommands)
6407
- createEffect14(()=>{const unregister=props.api.keymap.registerLayer({bindings:[{key:props.preferences.focusKey(),cmd:FOCUS_COMMAND
6403
+ createEffect16(()=>{const unregister=props.api.keymap.registerLayer({bindings:[{key:props.preferences.focusKey(),cmd:FOCUS_COMMAND
6408
6404
  }]
6409
6405
  })
6410
6406
  onCleanup18(unregister)
@@ -6438,10 +6434,10 @@ const filtered=createMemo16(()=>list().filter((item)=>matchesFilter(query(),item
6438
6434
  const visibility=createListVisibility({items:filtered,limit:()=>props.preferences.sectionItemLimit?.("skills")??0,resetKey:()=>JSON.stringify([target().key,query()])
6439
6435
  })
6440
6436
  const state=createMemo16(()=>props.controller.state(target()))
6441
- createEffect15(()=>{const current=target()
6442
- const deactivate=untrack5(()=>props.controller.activate?.(current)??(()=>{}))
6437
+ createEffect17(()=>{const current=target()
6438
+ const deactivate=untrack6(()=>props.controller.activate?.(current)??(()=>{}))
6443
6439
  onCleanup19(deactivate)
6444
- untrack5(()=>void props.controller.refresh(current).catch(()=>{}))
6440
+ untrack6(()=>void props.controller.refresh(current).catch(()=>{}))
6445
6441
  })
6446
6442
  async function useSkill(item){try{const isInserted=await props.controller.use(target(),item.name)
6447
6443
  if(isInserted)
@@ -6493,7 +6489,7 @@ return _el$
6493
6489
  }})
6494
6490
  }
6495
6491
  function SkillsSection(props){const dialogs=useDialogs(props.api)
6496
- const [query,setQuery]=createSignal27("")
6492
+ const [query,setQuery]=createSignal30("")
6497
6493
  const model=createSkillSectionModel(props,query)
6498
6494
  const navigationSection=()=>props.navigationSection??3
6499
6495
  function selectSkill(item){if(!props.preferences.shouldConfirmSkill(item)){model.useSkill(item)
@@ -6526,7 +6522,7 @@ _$insert(_el$,_$createComponent(SectionFilter,{get api(){return props.api
6526
6522
  }},get query(){return query()
6527
6523
  },placeholder:"Filter skills...",onInput:setQuery
6528
6524
  }),null)
6529
- _$insert(_el$,_$createComponent(Show17,{get when(){return model.filtered().length>0
6525
+ _$insert(_el$,_$createComponent(Show20,{get when(){return model.filtered().length>0
6530
6526
  },get fallback(){return(()=>{var _el$2=_$createElement("text")
6531
6527
  _$insertNode(_el$2,_$createTextNode(`No matching skills`))
6532
6528
  _$effect((_$p)=>_$setProp(_el$2,"fg",props.api.theme.current.textMuted,_$p))
@@ -6536,8 +6532,8 @@ return _el$2
6536
6532
  },get interaction(){return props.interaction
6537
6533
  },get grouped(){return model.grouped
6538
6534
  },get density(){return props.preferences.rowDensity?.()??"compact"
6539
- },get children(){return _$createComponent(For15,{get each(){return model.visibility.visible()
6540
- },children:(item,index)=>[_$createComponent(Show17,{get when(){return _$memo(()=>!!model.grouped())()&&(index()===0||model.visibility.visible()[index()-1]?.bucket!==item.bucket)
6535
+ },get children(){return _$createComponent(For16,{get each(){return model.visibility.visible()
6536
+ },children:(item,index)=>[_$createComponent(Show20,{get when(){return _$memo(()=>!!model.grouped())()&&(index()===0||model.visibility.visible()[index()-1]?.bucket!==item.bucket)
6541
6537
  },get children(){var _el$4=_$createElement("text")
6542
6538
  _$setProp(_el$4,"height",1)
6543
6539
  _$setProp(_el$4,"wrapMode","none")
@@ -6582,18 +6578,18 @@ return _el$
6582
6578
  function createSubagentSectionModel(props){const list=createMemo17(()=>props.controller.list(props.sessionID))
6583
6579
  const recent=createMemo17(()=>props.controller.recent?.(props.sessionID)??[])
6584
6580
  const rows=createMemo17(()=>buildSubagentView(list(),recent()))
6585
- const [query,setQuery]=createSignal28("")
6586
- const [mode,setMode]=createSignal28("all")
6581
+ const [query,setQuery]=createSignal31("")
6582
+ const [mode,setMode]=createSignal31("all")
6587
6583
  const counts=createMemo17(()=>countSubagentView(rows(),query()))
6588
6584
  const tabs=createMemo17(()=>["all","active","recent",...counts().errors>0?["errors"]:[]])
6589
6585
  const filtered=createMemo17(()=>filterSubagentView(rows(),mode(),query()))
6590
6586
  const parentID=createMemo17(()=>props.api.state?.session?.get(props.sessionID)?.parentID)
6591
6587
  const targetKey=createMemo17(()=>props.controller.target?.(props.sessionID).key??props.sessionID)
6592
- createEffect16(()=>{targetKey()
6588
+ createEffect18(()=>{targetKey()
6593
6589
  setQuery("")
6594
6590
  setMode("all")
6595
6591
  })
6596
- createEffect16(()=>{if(mode()!=="all"&&counts()[mode()]===0)
6592
+ createEffect18(()=>{if(mode()!=="all"&&counts()[mode()]===0)
6597
6593
  setMode("all")
6598
6594
  })
6599
6595
  const visibility=createListVisibility({items:filtered,limit:()=>props.preferences.sectionItemLimit?.("subagents")??0,resetKey:()=>JSON.stringify([targetKey(),query(),mode()])
@@ -6603,11 +6599,11 @@ const now=createSubagentClock(clockKey)
6603
6599
  const byId=createMemo17(()=>new Map(visibility.visible().map((item)=>[item.session.id,item])))
6604
6600
  const ids=createMemo17(()=>visibility.visible().map((item)=>item.session.id))
6605
6601
  const state=createMemo17(()=>props.controller.state(props.sessionID))
6606
- createEffect16(()=>{const sessionID=props.sessionID
6602
+ createEffect18(()=>{const sessionID=props.sessionID
6607
6603
  targetKey()
6608
- const deactivate=untrack6(()=>props.controller.activate?.(sessionID)??(()=>{}))
6604
+ const deactivate=untrack7(()=>props.controller.activate?.(sessionID)??(()=>{}))
6609
6605
  onCleanup20(deactivate)
6610
- untrack6(()=>void props.controller.refresh(sessionID).catch(()=>{}))
6606
+ untrack7(()=>void props.controller.refresh(sessionID).catch(()=>{}))
6611
6607
  })
6612
6608
  return{list,recent,rows,query,setQuery,mode,setMode,counts,tabs,filtered,parentID,visibility,now,byId,ids,state
6613
6609
  }}
@@ -6664,7 +6660,7 @@ return()=>_c$()?`${props.item.run.startedBeforeObservation ? `${icons.icon("rece
6664
6660
  _$effect((_$p)=>_$setProp(_el$3,"fg",row.focused()?row.foregroundColor():theme().textMuted,_$p))
6665
6661
  return _el$3
6666
6662
  })()
6667
- },get details(){return [_$createComponent(Show18,{get when(){return props.item.run?.errorMessage
6663
+ },get details(){return [_$createComponent(Show21,{get when(){return props.item.run?.errorMessage
6668
6664
  },get children(){var _el$4=_$createElement("text"),_el$5=_$createTextNode(`: `)
6669
6665
  _$insertNode(_el$4,_el$5)
6670
6666
  _$setProp(_el$4,"wrapMode","word")
@@ -6672,12 +6668,12 @@ _$insert(_el$4,()=>cancelled()?"Cancelled":"Error",_el$5)
6672
6668
  _$insert(_el$4,()=>props.item.run?.errorMessage,null)
6673
6669
  _$effect((_$p)=>_$setProp(_el$4,"fg",row.focused()?row.foregroundColor():failed()?theme().error:theme().textMuted,_$p))
6674
6670
  return _el$4
6675
- }}),_$createComponent(Show18,{get when(){return props.item.unavailable
6671
+ }}),_$createComponent(Show21,{get when(){return props.item.unavailable
6676
6672
  },get children(){var _el$6=_$createElement("text")
6677
6673
  _$insertNode(_el$6,_$createTextNode(`Worker status unavailable`))
6678
6674
  _$effect((_$p)=>_$setProp(_el$6,"fg",theme().warning,_$p))
6679
6675
  return _el$6
6680
- }}),_$createComponent(Show18,{get when(){return _$memo(()=>props.item.status.type==="retry")()?props.item.status:undefined
6676
+ }}),_$createComponent(Show21,{get when(){return _$memo(()=>props.item.status.type==="retry")()?props.item.status:undefined
6681
6677
  },children:(status)=>(()=>{var _el$0=_$createElement("text"),_el$1=_$createTextNode(`Retry #`),_el$10=_$createTextNode(` \xB7 `),_el$11=_$createTextNode(`s \xB7 `)
6682
6678
  _$insertNode(_el$0,_el$1)
6683
6679
  _$insertNode(_el$0,_el$10)
@@ -6689,7 +6685,7 @@ _$insert(_el$0,()=>status().message,null)
6689
6685
  _$effect((_$p)=>_$setProp(_el$0,"fg",row.focused()?row.foregroundColor():theme().warning,_$p))
6690
6686
  return _el$0
6691
6687
  })()
6692
- }),_$createComponent(Show18,{get when(){return _$memo(()=>!!idle())()&&!props.item.run?.errorMessage
6688
+ }),_$createComponent(Show21,{get when(){return _$memo(()=>!!idle())()&&!props.item.run?.errorMessage
6693
6689
  },get children(){var _el$8=_$createElement("text")
6694
6690
  _$insertNode(_el$8,_$createTextNode(`Finished`))
6695
6691
  _$effect((_$p)=>_$setProp(_el$8,"fg",theme().textMuted,_$p))
@@ -6700,12 +6696,12 @@ return _el$8
6700
6696
  function SubagentList(props){return _$createComponent(SidebarRowList,{get api(){return props.api
6701
6697
  },get interaction(){return props.interaction
6702
6698
  },get density(){return props.density
6703
- },get children(){return _$createComponent(For16,{get each(){return props.ids
6699
+ },get children(){return _$createComponent(For17,{get each(){return props.ids
6704
6700
  },children:(id,index)=>{const initial=props.itemById(id)
6705
6701
  const item=()=>props.itemById(id)??initial
6706
6702
  const startsGroup=()=>index()===0||props.visible[index()-1]?.group!==item().group
6707
6703
  return(()=>{var _el$=_$createElement("box")
6708
- _$insert(_el$,_$createComponent(Show19,{get when(){return startsGroup()
6704
+ _$insert(_el$,_$createComponent(Show22,{get when(){return startsGroup()
6709
6705
  },get children(){var _el$2=_$createElement("text"),_el$3=_$createElement("b")
6710
6706
  _$insertNode(_el$2,_el$3)
6711
6707
  _$insert(_el$3,()=>item().group)
@@ -6731,7 +6727,7 @@ return _$createComponent(Section,{get api(){return props.api
6731
6727
  },sectionId:`${PLUGIN_ID}.section.subagents`,get navigationSection(){return navigationSection()
6732
6728
  },title:"SUBAGENTS",section:"subagents",get summary(){return `${model.list().length} active \xB7 ${model.recent().length} recent`
6733
6729
  },get open(){return props.preferences.expanded().subagents
6734
- },onToggle:()=>props.preferences.toggleSectionExpanded("subagents"),get children(){return [_$createComponent(Show20,{get when(){return model.parentID()
6730
+ },onToggle:()=>props.preferences.toggleSectionExpanded("subagents"),get children(){return [_$createComponent(Show23,{get when(){return model.parentID()
6735
6731
  },children:(id)=>_$createComponent(McpBulkAction,{get api(){return props.api
6736
6732
  },get interaction(){return props.interaction
6737
6733
  },id:`${PLUGIN_ID}.subagents.parent`,get position(){return{section:navigationSection(),row:1,column:0
@@ -6754,7 +6750,7 @@ _$insert(_el$,_$createComponent(SectionFilter,{get api(){return props.api
6754
6750
  }}),_el$2)
6755
6751
  _$setProp(_el$2,"flexDirection","row")
6756
6752
  _$setProp(_el$2,"flexWrap","wrap")
6757
- _$insert(_el$2,_$createComponent(For17,{get each(){return model.tabs()
6753
+ _$insert(_el$2,_$createComponent(For18,{get each(){return model.tabs()
6758
6754
  },children:(value,index)=>_$createComponent(SectionTab,{get api(){return props.api
6759
6755
  },get interaction(){return props.interaction
6760
6756
  },id:`${PLUGIN_ID}.subagents.filter.${value}`,get position(){return{section:navigationSection(),row:4,column:index()
@@ -6765,7 +6761,7 @@ _$insert(_el$2,_$createComponent(For17,{get each(){return model.tabs()
6765
6761
  },onActivate:()=>model.setMode(value)
6766
6762
  })
6767
6763
  }))
6768
- _$insert(_el$,_$createComponent(Show20,{get when(){return model.filtered().length===0
6764
+ _$insert(_el$,_$createComponent(Show23,{get when(){return model.filtered().length===0
6769
6765
  },get children(){var _el$3=_$createElement("text")
6770
6766
  _$insertNode(_el$3,_$createTextNode(`No matching subagents`))
6771
6767
  _$effect((_$p)=>_$setProp(_el$3,"fg",props.api.theme.current.textMuted,_$p))
@@ -6849,7 +6845,7 @@ _$insert(_el$2,()=>icons.icon(done()?"done":active()?"busy":cancelled()?"close":
6849
6845
  _$setProp(_el$3,"flexGrow",1)
6850
6846
  _$setProp(_el$3,"wrapMode","word")
6851
6847
  _$insert(_el$3,()=>props.item.content)
6852
- _$insert(_el$,_$createComponent(Show21,{get when(){return props.item.priority==="high"||props.item.priority==="medium"||props.item.priority==="low"
6848
+ _$insert(_el$,_$createComponent(Show24,{get when(){return props.item.priority==="high"||props.item.priority==="medium"||props.item.priority==="low"
6853
6849
  },get children(){var _el$4=_$createElement("text"),_el$5=_$createElement("b"),_el$6=_$createTextNode(` `)
6854
6850
  _$insertNode(_el$4,_el$5)
6855
6851
  _$setProp(_el$4,"width",2)
@@ -6876,7 +6872,7 @@ _$insertNode(_el$,_el$2)
6876
6872
  _$setProp(_el$,"gap",1)
6877
6873
  _$setProp(_el$2,"flexDirection","row")
6878
6874
  _$setProp(_el$2,"flexWrap","wrap")
6879
- _$insert(_el$2,_$createComponent(For18,{each:["all","active","finished"],children:(value,index)=>_$createComponent(SectionTab,{get api(){return props.api
6875
+ _$insert(_el$2,_$createComponent(For19,{each:["all","active","finished"],children:(value,index)=>_$createComponent(SectionTab,{get api(){return props.api
6880
6876
  },get interaction(){return props.interaction
6881
6877
  },id:`${PLUGIN_ID}.todo.filter.${value}`,get position(){return{section:navigationSection(),row:tabsRow(),column:index()
6882
6878
  }},get label(){return value[0].toUpperCase() + value.slice(1)
@@ -6885,17 +6881,17 @@ _$insert(_el$2,_$createComponent(For18,{each:["all","active","finished"],childre
6885
6881
  },onActivate:()=>props.setMode(value)
6886
6882
  })
6887
6883
  }))
6888
- _$insert(_el$,_$createComponent(Show22,{get when(){return props.view.rows.length>0
6884
+ _$insert(_el$,_$createComponent(Show25,{get when(){return props.view.rows.length>0
6889
6885
  },get fallback(){return _$createComponent(EmptyTodo,{get api(){return props.api
6890
6886
  },get mode(){return props.mode
6891
6887
  }})
6892
6888
  },get children(){return _$createComponent(SidebarRowList,{get api(){return props.api
6893
6889
  },get interaction(){return props.interaction
6894
6890
  },get density(){return props.density
6895
- },get children(){return _$createComponent(For18,{get each(){return props.visibility.visible()
6891
+ },get children(){return _$createComponent(For19,{get each(){return props.visibility.visible()
6896
6892
  },children:(row,index)=>{const startsGroup=()=>index()===0||props.visibility.visible()[index()-1].group!==row.group
6897
6893
  return(()=>{var _el$3=_$createElement("box")
6898
- _$insert(_el$3,_$createComponent(Show22,{get when(){return startsGroup()
6894
+ _$insert(_el$3,_$createComponent(Show25,{get when(){return startsGroup()
6899
6895
  },get children(){var _el$4=_$createElement("text"),_el$5=_$createElement("b")
6900
6896
  _$insertNode(_el$4,_el$5)
6901
6897
  _$insert(_el$5,()=>row.group)
@@ -6932,7 +6928,7 @@ return _el$6
6932
6928
 
6933
6929
 
6934
6930
  function TodoGuidanceControl(props){const state=()=>props.controller.guidance(props.sessionID)
6935
- return _$createComponent(Show23,{get when(){return state().available
6931
+ return _$createComponent(Show26,{get when(){return state().available
6936
6932
  },get children(){var _el$=_$createElement("box")
6937
6933
  _$insert(_el$,_$createComponent(SectionTab,{get api(){return props.api
6938
6934
  },get interaction(){return props.interaction
@@ -6942,7 +6938,7 @@ _$insert(_el$,_$createComponent(SectionTab,{get api(){return props.api
6942
6938
  },get disabled(){return state().saving
6943
6939
  },onActivate:()=>void props.controller.setGuidance(props.sessionID,!state().enabled)
6944
6940
  }),null)
6945
- _$insert(_el$,_$createComponent(Show23,{get when(){return state().error
6941
+ _$insert(_el$,_$createComponent(Show26,{get when(){return state().error
6946
6942
  },children:(message)=>(()=>{var _el$2=_$createElement("text")
6947
6943
  _$setProp(_el$2,"wrapMode","word")
6948
6944
  _$insert(_el$2,message)
@@ -6957,22 +6953,22 @@ function TodoSection(props){const list=createMemo18(()=>props.controller.list(pr
6957
6953
  const icons=useIcons()
6958
6954
  const unavailable=()=>hostCapabilityUnavailable(props.api,"todo")
6959
6955
  const managed=()=>("guidance" in props.controller)?props.controller:undefined
6960
- const [mode,setMode]=createSignal29("all")
6956
+ const [mode,setMode]=createSignal32("all")
6961
6957
  const targetKey=createMemo18(()=>props.controller.target?.(props.sessionID).key??props.sessionID)
6962
- createEffect17(()=>{targetKey()
6958
+ createEffect19(()=>{targetKey()
6963
6959
  setMode("all")
6964
6960
  })
6965
6961
  const view=createMemo18(()=>buildTodoView(list(),mode()))
6966
6962
  const visibility=createListVisibility({items:()=>view().rows,limit:()=>props.preferences.sectionItemLimit?.("todo")??0,resetKey:()=>JSON.stringify([targetKey(),mode()])
6967
6963
  })
6968
6964
  const state=createMemo18(()=>props.controller.state(props.sessionID))
6969
- createEffect17(()=>{const sessionID=props.sessionID
6965
+ createEffect19(()=>{const sessionID=props.sessionID
6970
6966
  targetKey()
6971
6967
  if(unavailable())
6972
6968
  return
6973
- const deactivate=untrack7(()=>props.controller.activate?.(sessionID)??(()=>{}))
6969
+ const deactivate=untrack8(()=>props.controller.activate?.(sessionID)??(()=>{}))
6974
6970
  onCleanup21(deactivate)
6975
- untrack7(()=>void props.controller.refresh(sessionID).catch(()=>{}))
6971
+ untrack8(()=>void props.controller.refresh(sessionID).catch(()=>{}))
6976
6972
  })
6977
6973
  const navigationSection=()=>props.navigationSection??1
6978
6974
  return _$createComponent(Section,{get api(){return props.api
@@ -6980,10 +6976,10 @@ return _$createComponent(Section,{get api(){return props.api
6980
6976
  },sectionId:`${PLUGIN_ID}.section.todo`,get navigationSection(){return navigationSection()
6981
6977
  },title:"TODO",section:"todo",get summary(){return _$memo(()=>!!(unavailable()||managed()?.missing(props.sessionID)))()?"\u2014":`${view().counts.completed}/${list().length}`
6982
6978
  },get open(){return props.preferences.expanded().todo
6983
- },onToggle:()=>props.preferences.toggleSectionExpanded("todo"),get children(){return _$createComponent(Show24,{get when(){return unavailable()
6979
+ },onToggle:()=>props.preferences.toggleSectionExpanded("todo"),get children(){return _$createComponent(Show27,{get when(){return unavailable()
6984
6980
  },get fallback(){return(()=>{var _el$=_$createElement("box")
6985
6981
  _$setProp(_el$,"gap",1)
6986
- _$insert(_el$,_$createComponent(Show24,{get when(){return managed()?.guidance(props.sessionID).available
6982
+ _$insert(_el$,_$createComponent(Show27,{get when(){return managed()?.guidance(props.sessionID).available
6987
6983
  },get children(){return _$createComponent(TodoGuidanceControl,{get api(){return props.api
6988
6984
  },get controller(){return managed()
6989
6985
  },get sessionID(){return props.sessionID
@@ -6991,7 +6987,7 @@ _$insert(_el$,_$createComponent(Show24,{get when(){return managed()?.guidance(pr
6991
6987
  },get navigationSection(){return navigationSection()
6992
6988
  }})
6993
6989
  }}),null)
6994
- _$insert(_el$,_$createComponent(Show24,{get when(){return managed()?.missing(props.sessionID)
6990
+ _$insert(_el$,_$createComponent(Show27,{get when(){return managed()?.missing(props.sessionID)
6995
6991
  },get fallback(){return _$createComponent(SectionRequestBody,{get api(){return props.api
6996
6992
  },get interaction(){return props.interaction
6997
6993
  },id:`${PLUGIN_ID}.retry.todo`,get position(){return{section:navigationSection(),row:1,column:0
@@ -7040,10 +7036,11 @@ event.preventDefault()
7040
7036
  event.stopPropagation()
7041
7037
  props.interaction.leave()
7042
7038
  })
7043
- _$insert(_el$,_$createComponent(For19,{get each(){return visibleSections()
7039
+ _$insert(_el$,_$createComponent(For20,{get each(){return visibleSections()
7044
7040
  },children:(section,index)=>_$createComponent(SectionBoundary,{get api(){return props.api
7045
7041
  },get divided(){return index()<visibleSections().length-1
7046
- },get children(){return _$createComponent(Switch,{get children(){return [_$createComponent(Match,{when:section==="todo",get children(){return _$createComponent(TodoSection,_$mergeProps(props,{get navigationSection(){return index() + 1
7042
+ },get children(){return _$createComponent(Switch,{get children(){return [_$createComponent(Match,{when:section==="limits",get children(){return props.limitsSection(index() + 1)
7043
+ }}),_$createComponent(Match,{when:section==="todo",get children(){return _$createComponent(TodoSection,_$mergeProps(props,{get navigationSection(){return index() + 1
7047
7044
  },get controller(){return props.todo
7048
7045
  }}))
7049
7046
  }}),_$createComponent(Match,{when:section==="subagents",get children(){return _$createComponent(SubagentSection,_$mergeProps(props,{get navigationSection(){return index() + 1
@@ -7075,7 +7072,7 @@ return _el$
7075
7072
 
7076
7073
 
7077
7074
  function McpPersistence(props){const persist=createMemo20(()=>props.controller.persist())
7078
- createEffect18(()=>{if(!props.api.state.ready)
7075
+ createEffect20(()=>{if(!props.api.state.ready)
7079
7076
  return
7080
7077
  persist()
7081
7078
  const route=props.api.route.current
@@ -7084,19 +7081,19 @@ if(typeof params?.sessionID!=="string")
7084
7081
  return
7085
7082
  const current=props.controller.target()
7086
7083
  onCleanup23(()=>props.controller.deactivate(current))
7087
- untrack8(()=>void props.controller.activate(current).catch(()=>{}))
7084
+ untrack9(()=>void props.controller.activate(current).catch(()=>{}))
7088
7085
  })
7089
7086
  return _$createElement("box")
7090
7087
  }
7091
- function PreferencesPersistence(props){createEffect18(()=>{const location=currentLocation(props.api)
7092
- untrack8(()=>props.controller.setActiveScope(preferencesScope({directory:location.routing.directory,worktree:props.api.state.path.worktree
7088
+ function PreferencesPersistence(props){createEffect20(()=>{const location=currentLocation(props.api)
7089
+ untrack9(()=>props.controller.setActiveScope(preferencesScope({directory:location.routing.directory,worktree:props.api.state.path.worktree
7093
7090
  })))
7094
7091
  props.controller.load()
7095
7092
  })
7096
7093
  return _$createElement("box")
7097
7094
  }
7098
7095
  function FirstRunWizardPersistence(props){let isChecked=false
7099
- createEffect18(()=>{if(isChecked)
7096
+ createEffect20(()=>{if(isChecked)
7100
7097
  return
7101
7098
  isChecked=true
7102
7099
  showFirstRunWizard(props.api,props.preferences).catch(()=>{})
@@ -7134,7 +7131,7 @@ _$setProp(_el$2,"flexDirection","row")
7134
7131
  _$setProp(_el$2,"justifyContent","space-between")
7135
7132
  _$setProp(_el$2,"gap",1)
7136
7133
  _$setProp(_el$3,"flexGrow",1)
7137
- _$insert(_el$3,_$createComponent(Show25,{get when(){return props.preferences.showSessionTitle()
7134
+ _$insert(_el$3,_$createComponent(Show28,{get when(){return props.preferences.showSessionTitle()
7138
7135
  },get children(){var _el$4=_$createElement("text"),_el$5=_$createElement("b")
7139
7136
  _$insertNode(_el$4,_el$5)
7140
7137
  _$setProp(_el$4,"wrapMode","word")
@@ -7142,7 +7139,7 @@ _$insert(_el$5,()=>props.title)
7142
7139
  _$effect((_$p)=>_$setProp(_el$4,"fg",theme().text,_$p))
7143
7140
  return _el$4
7144
7141
  }}),null)
7145
- _$insert(_el$3,_$createComponent(Show25,{get when(){return _$memo(()=>!!props.preferences.showSessionDate())()&&created()
7142
+ _$insert(_el$3,_$createComponent(Show28,{get when(){return _$memo(()=>!!props.preferences.showSessionDate())()&&created()
7146
7143
  },children:(value)=>(()=>{var _el$6=_$createElement("text")
7147
7144
  _$insert(_el$6,value)
7148
7145
  _$effect((_$p)=>_$setProp(_el$6,"fg",theme().textMuted,_$p))
@@ -7182,6 +7179,26 @@ return
7182
7179
  const [user,project]=await Promise.all([safe(userPath?readSource(userPath,()=>readFile2(userPath,"utf8")):undefined),safe(readProject?readSource(".opencode/navigator.json",readProject):undefined)])
7183
7180
  return mergeConfiguredDefaults(configuredDefaultsFromPluginOptions(options),user,project)
7184
7181
  }
7182
+
7183
+
7184
+ function LimitsPersistence(props){createEffect21(()=>{const model=props.selectedModel?.()
7185
+ if(model&&props.accountSource)
7186
+ untrack10(()=>void props.accountSource.refresh(model))
7187
+ })
7188
+ createEffect21(()=>{const{model,adapter
7189
+ }=props.controller.current()
7190
+ if(model&&adapter)
7191
+ untrack10(()=>void props.controller.refresh(true))
7192
+ })
7193
+ const timer=setInterval(()=>{const model=props.selectedModel?.()
7194
+ if(model&&props.accountSource)
7195
+ props.accountSource.refresh(model).then(()=>untrack10(()=>props.controller.refresh()))
7196
+ else
7197
+ props.controller.refresh()
7198
+ },5000)
7199
+ onCleanup25(()=>clearInterval(timer))
7200
+ return _$createElement("box")
7201
+ }
7185
7202
  import {homedir,homedir as homedir2} from "os"
7186
7203
 
7187
7204
  function location(input){return input.directory?{location:{directory:input.directory}}:{}}
@@ -7275,7 +7292,7 @@ return false
7275
7292
  }
7276
7293
  function enabled(value){return typeof value==="function"?value():value!==false
7277
7294
  }
7278
- function createV2Keymap(context){const [revision,setRevision]=createSignal30(0)
7295
+ function createV2Keymap(context){const [revision,setRevision]=createSignal33(0)
7279
7296
  const layers=new Map
7280
7297
  let sequence=0
7281
7298
  function layerActive(layer){const mode=layer.mode??"base"
@@ -7386,9 +7403,9 @@ function legacyTheme(theme){return{primary:theme.hue.interactive[200],secondary:
7386
7403
 
7387
7404
  function createV2UI(context){let dialogOpen=false
7388
7405
  function DialogPrompt(props){let active=true
7389
- onCleanup25(()=>{active=false
7406
+ onCleanup26(()=>{active=false
7390
7407
  })
7391
- onMount7(async ()=>{const value=await context.ui.dialog.prompt({title:props.title,placeholder:props.placeholder,value:props.value
7408
+ onMount8(async ()=>{const value=await context.ui.dialog.prompt({title:props.title,placeholder:props.placeholder,value:props.value
7392
7409
  })
7393
7410
  if(!active)
7394
7411
  return
@@ -7400,9 +7417,9 @@ props.onConfirm?.(value)
7400
7417
  return _$createElement("box")
7401
7418
  }
7402
7419
  function DialogConfirm(props){let active=true
7403
- onCleanup25(()=>{active=false
7420
+ onCleanup26(()=>{active=false
7404
7421
  })
7405
- onMount7(async ()=>{const confirmed=await context.ui.dialog.confirm({title:props.title,message:props.message
7422
+ onMount8(async ()=>{const confirmed=await context.ui.dialog.confirm({title:props.title,message:props.message
7406
7423
  })
7407
7424
  if(!active)
7408
7425
  return
@@ -7462,9 +7479,9 @@ context.ui.router.navigate({type:"plugin",name,data:params})
7462
7479
  },client:{...remote.client,session:sessions.client
7463
7480
  },event:createV2EventAdapter(context,sessions),theme:{get current(){return legacyTheme(context.theme)
7464
7481
  },ready:true,mode:()=>context.themeMode
7465
- },attention:context.attention,lifecycle:{signal:controller.signal,onDispose}}
7466
- api.slots=createV2Slots(context,keymap,(dispose)=>{onDispose(dispose)
7482
+ },attention:context.attention,lifecycle:{signal:controller.signal,onDispose},slots:createV2Slots(context,keymap,(dispose)=>{onDispose(dispose)
7467
7483
  })
7484
+ }
7468
7485
  setHostCapabilities(api,{todo:true,lsp:false,titleVisibility:false,permissionMode:false
7469
7486
  })
7470
7487
  return{api,async dispose(){controller.abort()
@@ -7538,16 +7555,23 @@ if(item.source.target.startsWith("."))
7538
7555
  throw new Error("Unrecognized local Navigator source")
7539
7556
  await context.client.plugin.update({location:response.location,targets:[item.source.target]})
7540
7557
  }}}
7541
- async function setupNavigator(api,options,readProject,managedTodo){const config=pluginConfig(undefined)
7558
+ async function setupNavigator(api,options,readProject,managedTodo,hostContext){const config=pluginConfig(undefined)
7542
7559
  const configured=await loadConfiguredDefaults(api,options,readProject)
7543
7560
  const todo=managedTodo??createTodoController(api)
7544
7561
  const subagents=createSubagentController(api)
7545
7562
  const skills=createSkillController(api)
7546
7563
  const preferences=createPreferencesController(api,config,createPreferencesStore(api.state.path.state),configured)
7564
+ const limitsPath=import.meta.url.includes("/dist/tui.js")?"./provider-limits.js":"../provider-limits"
7565
+ const limitsModule=await import(limitsPath)
7566
+ const LimitsSection=limitsModule.ProviderLimitsSection
7567
+ const{controller:limits,codex,accountSource,selectModel,capabilities
7568
+ }=limitsModule.createProviderQuotaIntegration(api,preferences,"0.21.0",hostContext)
7547
7569
  const mcp=createMcpController(api,preferences.persistMcp,preferences)
7548
7570
  const interaction=createSidebarInteraction(api,()=>openKeyboardHelp(api,preferences.lspIconStyle,preferences.cornerFont))
7549
7571
  const startup=createStartupSessionController(api,preferences)
7550
7572
  api.lifecycle.onDispose(()=>preferences.flush())
7573
+ api.lifecycle.onDispose(()=>limits.dispose())
7574
+ api.lifecycle.onDispose(()=>accountSource?.dispose())
7551
7575
  api.lifecycle.onDispose(()=>interaction.dispose())
7552
7576
  const unsubscribeMcp=api.event.on("mcp.tools.changed",()=>{mcp.refresh().catch(()=>{})
7553
7577
  })
@@ -7560,6 +7584,7 @@ api.lifecycle.onDispose(unsubscribeConnected)
7560
7584
  api.slots.register({order:100,slots:{app(){return _$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7561
7585
  },get multilineCorners(){return preferences.cornerFont
7562
7586
  },get children(){return [_$createComponent(PreferencesPersistence,{api,controller:preferences
7587
+ }),_$createComponent(LimitsPersistence,{controller:limits,accountSource,selectedModel:selectModel
7563
7588
  }),_$memo(()=>_$memo(()=>!!supportsPermissionMode(api))()&&_$createComponent(PermissionModeBinding,{api,preferences
7564
7589
  })),_$createComponent(SettingsBinding,{api,preferences,mcp,skills
7565
7590
  }),_$createComponent(SidebarToggleBinding,{api,preferences
@@ -7568,7 +7593,7 @@ api.slots.register({order:100,slots:{app(){return _$createComponent(IconProvider
7568
7593
  },interaction,skills,subagents,mcp
7569
7594
  }),_$createComponent(FirstRunWizardPersistence,{api,preferences
7570
7595
  }),_$createComponent(StartupSessionBinding,{api,controller:startup
7571
- }),_$createComponent(UpgradeNotesBinding,{api,preferences,version:"0.19.3"
7596
+ }),_$createComponent(UpgradeNotesBinding,{api,preferences,version:"0.21.0"
7572
7597
  }),_$createComponent(McpPersistence,{api,controller:mcp
7573
7598
  })]
7574
7599
  }})
@@ -7581,7 +7606,8 @@ api.slots.register({order:100,slots:{app(){return _$createComponent(IconProvider
7581
7606
  },sidebar_content(_context,props){return _$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7582
7607
  },get multilineCorners(){return preferences.cornerFont
7583
7608
  },get children(){return _$createComponent(SidebarContent,{api,get onNewSession(){return startup.handleNewSession
7584
- },mcp,todo,subagents,skills,preferences,interaction,get sessionID(){return props.session_id
7609
+ },mcp,limitsSection:(navigationSection)=>_$createComponent(LimitsSection,{api,preferences,interaction,controller:limits,codex,capabilities,navigationSection
7610
+ }),todo,subagents,skills,preferences,interaction,get sessionID(){return props.session_id
7585
7611
  }})
7586
7612
  }})
7587
7613
  }}})
@@ -7598,12 +7624,12 @@ throw result.error
7598
7624
  }
7599
7625
  return result.data?.type==="text"?result.data.content:undefined
7600
7626
  })
7601
- const versionStatus=createVersionStatus(api,"0.19.3")
7602
- const versionUpdates=createVersionUpdateActions(api,versionStatus,createOpenCodeV1VersionUpdater(api,meta),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.19.3"))
7627
+ const versionStatus=createVersionStatus(api,"0.21.0")
7628
+ const versionUpdates=createVersionUpdateActions(api,versionStatus,createOpenCodeV1VersionUpdater(api,meta),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.21.0"))
7603
7629
  api.slots.register({order:90,slots:{sidebar_footer(_context,props){return _$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7604
7630
  },get multilineCorners(){return preferences.cornerFont
7605
7631
  },get children(){return _$createComponent(VersionFooter,{api,get sessionID(){return props.session_id
7606
- },navigatorVersion:"0.19.3",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7632
+ },navigatorVersion:"0.21.0",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7607
7633
  },get onNavigatorUpdate(){return versionUpdates.navigator
7608
7634
  }})
7609
7635
  }})
@@ -7616,16 +7642,16 @@ const{mcp,skills,preferences
7616
7642
  return
7617
7643
  return new TextDecoder().decode(await context.client.file.read({location:context.location,path:".opencode/navigator.json"
7618
7644
  }))
7619
- },todo)
7620
- const versionStatus=createVersionStatus(adapter.api,"0.19.3")
7621
- const versionUpdates=createVersionUpdateActions(adapter.api,versionStatus,createOpenCodeV2VersionUpdater(context),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.19.3"))
7645
+ },todo,context)
7646
+ const versionStatus=createVersionStatus(adapter.api,"0.21.0")
7647
+ const versionUpdates=createVersionUpdateActions(adapter.api,versionStatus,createOpenCodeV2VersionUpdater(context),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.21.0"))
7622
7648
  const disposeFooter=context.ui.slot({append:"sidebar.footer",render:()=>_$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7623
7649
  },get multilineCorners(){return preferences.cornerFont
7624
7650
  },get children(){var _el$=_$createElement("box")
7625
7651
  _$setProp(_el$,"flexDirection","row")
7626
7652
  _$setProp(_el$,"justifyContent","space-between")
7627
7653
  _$insert(_el$,_$createComponent(VersionSummary,{get api(){return adapter.api
7628
- },navigatorVersion:"0.19.3",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7654
+ },navigatorVersion:"0.21.0",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7629
7655
  },get onNavigatorUpdate(){return versionUpdates.navigator
7630
7656
  }}),null)
7631
7657
  _$insert(_el$,_$createComponent(SettingsFooterButton,{get api(){return adapter.api
@@ -7640,5 +7666,5 @@ await adapter.dispose()
7640
7666
  var plugin={id:PLUGIN_ID,tui:setupOpenCodeV1,setup:setupOpenCodeV2
7641
7667
  }
7642
7668
  var plugin_default=plugin
7643
- export{DEFAULT_SECTION_EXPANSION,DialogSurface,FOCUS_COMMAND,FirstRunWizard,KeyboardHelpDialog,LspBadge,McpSection,PresetMenu,QUICK_ACTIONS,Section,SectionFilter,SelectionBox,SettingsDialog,SidebarFocusBinding,SidebarToggleBinding,SkillsSection,createDialogStack,createMcpController,createPreferencesController,createSidebarInteraction,createSkillController,createSubagentController,createTodoController,plugin_default as default,isEffectivelyVisible,lspIcon,matchesFilter,openFirstRunWizard,openKeyboardHelp,openSettings,showFirstRunWizard,useDialogScroll,useDialogState,useDialogs,useIcons
7669
+ export{DEFAULT_SECTION_EXPANSION,DialogAction,DialogHeader,DialogSurface,FOCUS_COMMAND,FirstRunWizard,GuardedConfirmation,KeyboardHelpDialog,LspBadge,McpSection,SelectionMenu as PresetMenu,QUICK_ACTIONS,Section,SectionFilter,SelectionBox,SelectionMenu,SettingsDialog,SidebarFocusBinding,SidebarToggleBinding,SkillsSection,createDialogStack,createMcpController,createPreferencesController,createSidebarInteraction,createSkillController,createSubagentController,createTodoController,plugin_default as default,isEffectivelyVisible,lspIcon,matchesFilter,openFirstRunWizard,openKeyboardHelp,openSettings,showFirstRunWizard,useDialogScroll,useDialogState,useDialogs,useIcons
7644
7670
  }