opencode-navigator 0.19.0 → 0.19.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## [0.19.1] - 2026-10-02
6
+
7
+ - Remember the OpenCode 1.x auto-approve mode as a user-wide default for new sessions, including changes made through the host's permission toggle.
8
+
5
9
  ## [0.19.0] - 2026-10-02
6
10
 
7
11
  - Connect or disconnect all eligible MCP servers in a group from its heading, including filtered-out items, with keyboard access and failed-only retry.
@@ -51,6 +55,7 @@
51
55
 
52
56
  Earlier release notes are available on [GitHub Releases](https://github.com/St1ggy/opencode-navigator/releases).
53
57
 
58
+ [0.19.1]: https://github.com/St1ggy/opencode-navigator/compare/v0.19.0...v0.19.1
54
59
  [0.19.0]: https://github.com/St1ggy/opencode-navigator/compare/v0.18.2...v0.19.0
55
60
  [0.18.2]: https://github.com/St1ggy/opencode-navigator/compare/v0.18.1...v0.18.2
56
61
  [0.18.1]: https://github.com/St1ggy/opencode-navigator/compare/v0.18.0...v0.18.1
package/README.md CHANGED
@@ -338,6 +338,15 @@ Search Everything. Usage never changes the order. Visibility remains independent
338
338
  so any action, including a bookmarked one, can be hidden from the sidebar while it
339
339
  remains searchable. Unavailable actions stay visible with a route- or host-specific reason.
340
340
 
341
+ In OpenCode 1.x, Navigator saves changes to the auto-approve mode as a user-wide
342
+ default, including changes made through OpenCode's own command palette. Set the
343
+ default under **Navigator Settings → Behavior → Default auto-approve permissions**;
344
+ new sessions restore it. Until you set a Navigator default, an explicit OpenCode
345
+ startup mode is respected. OpenCode 2.x owns this setting: use the host Settings
346
+ dialog for the current session and `session.permissions` in the user-wide
347
+ `cli.json` (`"prompt"` or `"autoaccept"`) for its startup default. Restart
348
+ OpenCode after changing `cli.json`.
349
+
341
350
  ## Configuration sources
342
351
 
343
352
  Navigator validates and deep-merges three simultaneous sources in this order:
package/dist/tui.js CHANGED
@@ -1,8 +1,9 @@
1
- import {insert as _$insert,setProp as _$setProp,createElement as _$createElement,createComponent as _$createComponent,mergeProps as _$mergeProps,effect as _$effect,createTextNode as _$createTextNode,insertNode as _$insertNode,memo as _$memo,use as _$use,spread as _$spread,useTerminalDimensions,useTerminalDimensions as useTerminalDimensions2,useTerminalDimensions as useTerminalDimensions3,useTerminalDimensions as useTerminalDimensions4,useTerminalDimensions as useTerminalDimensions5,useTerminalDimensions as useTerminalDimensions6,useTerminalDimensions as useTerminalDimensions7} from "@opentui/solid"
1
+ import {insert as _$insert,setProp as _$setProp,createElement as _$createElement,memo as _$memo,createComponent as _$createComponent,mergeProps as _$mergeProps,effect as _$effect,createTextNode as _$createTextNode,insertNode as _$insertNode,use as _$use,spread as _$spread,useTerminalDimensions,useTerminalDimensions as useTerminalDimensions2,useTerminalDimensions as useTerminalDimensions3,useTerminalDimensions as useTerminalDimensions4,useTerminalDimensions as useTerminalDimensions5,useTerminalDimensions as useTerminalDimensions6,useTerminalDimensions as useTerminalDimensions7} from "@opentui/solid"
2
2
 
3
3
 
4
4
 
5
- import {createSignal as createSignal2,createSignal,createEffect,onCleanup,createContext,useContext,createContext as createContext2,createSignal as createSignal3,useContext as useContext2,createEffect as createEffect2,splitProps,untrack,splitProps as splitProps2,For,createEffect as createEffect3,onCleanup as onCleanup2,Show,splitProps as splitProps3,createSignal as createSignal4,createSignal as createSignal5,createSignal as createSignal6,onCleanup as onCleanup3,batch,createSignal as createSignal8,createSignal as createSignal7,createEffect as createEffect4,createSignal as createSignal9,onCleanup as onCleanup4,createSignal as createSignal10,createSignal as createSignal11,Index,createSignal as createSignal12,onCleanup as onCleanup5,createEffect as createEffect6,onCleanup as onCleanup7,batch as batch2,createEffect as createEffect5,createMemo,createSignal as createSignal13,onCleanup as onCleanup6,onMount,For as For2,For as For3,Show as Show2,createMemo as createMemo2,Show as Show3,createSignal as createSignal14,onCleanup as onCleanup8,For as For4,For as For5,For as For8,createMemo as createMemo4,onMount as onMount3,For as For7,createMemo as createMemo3,onMount as onMount2,Show as Show5,createEffect as createEffect7,createSignal as createSignal15,onCleanup as onCleanup9,Show as Show4,For as For6,For as For9,createEffect as createEffect8,createMemo as createMemo5,onCleanup as onCleanup10,createEffect as createEffect9,createMemo as createMemo6,untrack as untrack2,For as For10,createEffect as createEffect10,createMemo as createMemo9,onCleanup as onCleanup11,onMount as onMount4,createMemo as createMemo7,createMemo as createMemo8,Show as Show6,onCleanup as onCleanup12,createSignal as createSignal16,createEffect as createEffect11,onCleanup as onCleanup13,onMount as onMount5,onCleanup as onCleanup14,onMount as onMount6,For as For11,createSignal as createSignal17,createSignal as createSignal18,Show as Show7,createSignal as createSignal20,createSignal as createSignal19,onCleanup as onCleanup15,For as For12,Show as Show10,createMemo as createMemo11,createComputed,createMemo as createMemo10,createSignal as createSignal21,untrack as untrack3,Show as Show8,createComputed as createComputed2,untrack as untrack4,Show as Show9,createEffect as createEffect12,createSignal as createSignal22,createMemo as createMemo13,createSignal as createSignal24,createMemo as createMemo12,For as For13,Show as Show14,Show as Show11,Show as Show12,Show as Show13,createSignal as createSignal23,onCleanup as onCleanup16,For as For14,Show as Show16,createMemo as createMemo15,Show as Show15,createMemo as createMemo14,createSignal as createSignal25,createEffect as createEffect13,onCleanup as onCleanup17,For as For19,Match,Switch,createMemo as createMemo19,onCleanup as onCleanup21,For as For15,Show as Show17,createSignal as createSignal26,createEffect as createEffect14,createMemo as createMemo16,onCleanup as onCleanup18,untrack as untrack5,For as For17,Show as Show20,createEffect as createEffect15,createMemo as createMemo17,createSignal as createSignal27,onCleanup as onCleanup19,untrack as untrack6,For as For16,Show as Show19,Show as Show18,Show as Show24,createEffect as createEffect16,createMemo as createMemo18,createSignal as createSignal28,onCleanup as onCleanup20,untrack as untrack7,For as For18,Show as Show22,Show as Show21,Show as Show23,createEffect as createEffect17,createMemo as createMemo20,onCleanup as onCleanup22,untrack as untrack8,Show as Show25,createMemo as createMemo21,onCleanup as onCleanup23,createSignal as createSignal29,onCleanup as onCleanup24,onMount as onMount7} from "solid-js"
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 createSignal24,createMemo as createMemo12,For as For13,Show as Show14,Show as Show11,Show as Show12,Show as Show13,createSignal as createSignal23,onCleanup as onCleanup17,For as For14,Show as Show16,createMemo as createMemo15,Show as Show15,createMemo as createMemo14,createSignal as createSignal25,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 createSignal26,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 createSignal27,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 createSignal28,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 createSignal29,onCleanup as onCleanup25,onMount as onMount7} from "solid-js"
6
7
  var SIDEBAR_SECTIONS=["todo","subagents","skills","quick_actions","lsp","mcp"]
7
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"]
8
9
  function preferencesScope(path){return path.worktree||path.directory||"global"
@@ -1252,7 +1253,8 @@ const workspaceProfiles=parseWorkspaceProfiles(userInput?.workspaceProfiles)
1252
1253
  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
1253
1254
  },...typeof userInput?.lastNavigatorVersion==="string"&&{lastNavigatorVersion:userInput.lastNavigatorVersion
1254
1255
  },...typeof userInput?.previousNavigatorVersion==="string"&&{previousNavigatorVersion:userInput.previousNavigatorVersion
1255
- },...Object.keys(layoutPresets).length>0&&{layoutPresets},...Object.keys(mcpPresets).length>0&&{mcpPresets},...favoriteSkills&&{favoriteSkills},...favoriteMcpServers?.length&&{favoriteMcpServers},...favoriteQuickActions.length>0&&{favoriteQuickActions},...recentSkills.length>0&&{recentSkills},...recentQuickActions.length>0&&{recentQuickActions},...Object.keys(mcpServerGroups).length>0&&{mcpServerGroups},...Object.keys(skillGroups).length>0&&{skillGroups},...Object.keys(workspaceProfiles).length>0&&{workspaceProfiles}}}}
1256
+ },...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
1257
+ },...Object.keys(workspaceProfiles).length>0&&{workspaceProfiles}}}}
1256
1258
  function parseValues(value){if(!value)
1257
1259
  return{}
1258
1260
  return{behavior:parsePluginSettings(value.behavior),layout:{sections:parseSectionPreferences(value.layout?.sections),expanded:parseSectionPreferences(value.layout?.expanded),...parseSectionOrder(value.layout?.order)&&{order:parseSectionOrder(value.layout?.order)}},desiredMcpStates:parseDesiredMcpStates(value.desiredMcpStates)
@@ -1414,7 +1416,8 @@ return{global:target.kind==="global"?scope:current.global,worktrees,user:{...ski
1414
1416
  },...(update.user?.previousNavigatorVersion??current.user.previousNavigatorVersion)&&{previousNavigatorVersion:update.user?.previousNavigatorVersion??current.user.previousNavigatorVersion
1415
1417
  },...Object.keys(parsedLayoutPresets).length>0&&{layoutPresets:parsedLayoutPresets},...Object.keys(parsedMcpPresets).length>0&&{mcpPresets:parsedMcpPresets},...Object.keys(workspaceProfiles).length>0&&{workspaceProfiles:parseWorkspaceProfiles(workspaceProfiles)
1416
1418
  },...favoriteSkills.length>0&&{favoriteSkills},...favoriteMcpServers.size>0&&{favoriteMcpServers:[...favoriteMcpServers].sort()},...favoriteQuickActions.size>0&&{favoriteQuickActions:parseFavoriteQuickActions([...favoriteQuickActions])
1417
- },...recentSkills.length>0&&{recentSkills},...recentQuickActions.length>0&&{recentQuickActions},...Object.keys(mcpServerGroups).length>0&&{mcpServerGroups:parseMcpServerGroups(mcpServerGroups)},...Object.keys(skillGroups).length>0&&{skillGroups:parseSkillGroups(skillGroups)}}}}
1419
+ },...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
1420
+ }}}}
1418
1421
  function targetForLegacyScope(scope){return scope==="global"?{kind:"global"}:{kind:"worktree",key:scope}}
1419
1422
  function createPreferencesStore(stateDirectory){const directory=join(stateDirectory,LEGACY_PLUGIN_ID)
1420
1423
  const file=join(directory,"preferences.json")
@@ -1583,6 +1586,7 @@ const [recentSkills,setRecentSkills]=createSignal4([])
1583
1586
  const [recentQuickActions,setRecentQuickActions]=createSignal4([])
1584
1587
  const [mcpServerGroups,setMcpServerGroups]=createSignal4(configured.mcpServerGroups??{})
1585
1588
  const [skillGroups,setSkillGroups]=createSignal4({})
1589
+ const [autoApprovePermissions,setAutoApprovePermissions]=createSignal4()
1586
1590
  const [ready,setReady]=createSignal4(false)
1587
1591
  const [revision,setRevision]=createSignal4(0)
1588
1592
  const sessionLayouts=new Map
@@ -1651,6 +1655,7 @@ setRecentSkills(value.user.recentSkills??[])
1651
1655
  setRecentQuickActions(value.user.recentQuickActions??[])
1652
1656
  setMcpServerGroups({...configured.mcpServerGroups,...value.user.mcpServerGroups})
1653
1657
  setSkillGroups(value.user.skillGroups??{})
1658
+ setAutoApprovePermissions(value.user.autoApprovePermissions)
1654
1659
  setReady(true)
1655
1660
  refreshResolved()
1656
1661
  }
@@ -1763,6 +1768,14 @@ return
1763
1768
  setSkillGroups(assignGroup(skillGroups(),location,value))
1764
1769
  update({user:{skillGroup:{location,group:value}}})
1765
1770
  }
1771
+ function changeAutoApprovePermissions(value){if(!isHydrated){load().then(()=>changeAutoApprovePermissions(value))
1772
+ return
1773
+ }
1774
+ if(autoApprovePermissions()===value)
1775
+ return
1776
+ setAutoApprovePermissions(value)
1777
+ update({user:{autoApprovePermissions:value}})
1778
+ }
1766
1779
  function toggleFavoriteMcpServer(name){if(!isHydrated){load().then(()=>toggleFavoriteMcpServer(name))
1767
1780
  return
1768
1781
  }
@@ -1833,7 +1846,7 @@ throw new Error("MCP preset no longer exists")
1833
1846
  update({user:{workspaceProfile:{layout,mcp}}})
1834
1847
  },favoriteSkills,favoriteMcpServers,favoriteQuickActions,toggleFavoriteMcpServer,toggleFavoriteQuickAction,recentSkills,recentQuickActions,mcpServerGroups,setMcpServerGroup(name,value){setMcpServerGroups(assignGroup(mcpServerGroups(),name,value))
1835
1848
  update({user:{mcpServerGroup:{name,group:value}}})
1836
- },skillGroups,setSkillGroup:changeSkillGroup,async recordSkillUse(skill){await load()
1849
+ },skillGroups,setSkillGroup:changeSkillGroup,autoApprovePermissions,setAutoApprovePermissions:changeAutoApprovePermissions,async recordSkillUse(skill){await load()
1837
1850
  if(!skill.location)
1838
1851
  return
1839
1852
  setRecentSkills(parseRecentSkills([skill.location,...recentSkills()]))
@@ -3386,6 +3399,8 @@ return section!=="todo"&&section!=="lsp"?true:current[section]
3386
3399
  }
3387
3400
  function supportsTitleVisibility(api){return hostCapabilities(api).titleVisibility!==false
3388
3401
  }
3402
+ function supportsPermissionMode(api){return hostCapabilities(api).permissionMode!==false
3403
+ }
3389
3404
  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."}]
3390
3405
  },{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."
3391
3406
  },{icon:"history",title:"Direct navigation",description:"Open a child session without leaving your workflow."
@@ -4166,6 +4181,11 @@ return [{title:`${icons.icon(title ? "checked" : "unchecked")} Session title`,va
4166
4181
  }]
4167
4182
  }
4168
4183
  function createSettingsGroups(api,preferences,icons){const supportedSections=()=>SIDEBAR_SECTIONS.filter((name)=>supportsSidebarSection(api,name))
4184
+ const permissionDefaultDescription=()=>{const value=preferences.autoApprovePermissions()
4185
+ if(value===undefined)
4186
+ return "follow OpenCode startup mode"
4187
+ return value?"on for new sessions":"off for new sessions"
4188
+ }
4169
4189
  const groups=createMemo7(()=>[{id:"scope",tab:"Scope",title:"Preference scope",options:[{title:`${icons.icon(preferences.preferenceScope() === "global" ? "radioOn" : "radioOff")} Global`,value:"scope:global",description:"applies to every worktree"
4170
4190
  },{title:`${icons.icon(preferences.preferenceScope() === "worktree" ? "radioOn" : "radioOff")} Current worktree`,value:"scope:worktree",description:preferences.canUseWorktreeScope()?preferences.preferenceScopeLabel():"unavailable outside a worktree"
4171
4191
  }]
@@ -4175,7 +4195,8 @@ const groups=createMemo7(()=>[{id:"scope",tab:"Scope",title:"Preference scope",o
4175
4195
  },{id:"sections",tab:"Sections",title:"Sections & order",options:[...titleVisibilityOptions(api,preferences,icons),...preferences.selectedSectionOrder().filter((name)=>supportsSidebarSection(api,name)).map((name,index)=>{const section=SECTION_DEFINITIONS.find((candidate)=>candidate.name===name)
4176
4196
  return{title:`${icons.icon(preferences.selectedSections()[section.name] ? "checked" : "unchecked")} ${index + 1}. ${icons.section(section.name)} ${section.label}`,value:section.name,description:preferences.selectedSections()[section.name]?"visible":"hidden"
4177
4197
  }})]
4178
- },{id:"behavior",tab:"Behavior",title:"Behavior",options:[{title:`${icons.icon(preferences.selectedStartInChat() ? "checked" : "unchecked")} Start new sessions in chat`,value:"start_in_chat",description:preferences.selectedStartInChat()?"skip Home \xB7 on":"show Home \xB7 off"
4198
+ },{id:"behavior",tab:"Behavior",title:"Behavior",options:[...supportsPermissionMode(api)?[{title:`${icons.icon(preferences.autoApprovePermissions() === true ? "checked" : "unchecked")} Default auto-approve permissions`,value:"auto_approve_permissions",description:permissionDefaultDescription()
4199
+ }]:[],{title:`${icons.icon(preferences.selectedStartInChat() ? "checked" : "unchecked")} Start new sessions in chat`,value:"start_in_chat",description:preferences.selectedStartInChat()?"skip Home \xB7 on":"show Home \xB7 off"
4179
4200
  },{title:`${icons.icon(preferences.selectedPersistMcp() ? "checked" : "unchecked")} Remember MCP states`,value:"persist_mcp",description:preferences.selectedPersistMcp()?"on":"off"
4180
4201
  },{title:`${icons.icon("settings")} Icon style`,value:"lsp_icon_style",description:preferences.selectedLspIconStyle()==="nerd"?"Nerd Font":"Text fallback"
4181
4202
  },{title:`${icons.icon(preferences.selectedCornerFont() ? "checked" : "unchecked")} Multiline corner font`,value:"corner_font",description:preferences.selectedCornerFont()?"Installed":"Not installed \xB7 rectangular highlights"
@@ -4345,6 +4366,9 @@ break
4345
4366
  case "start_in_chat":{input.preferences.toggleStartInChat()
4346
4367
  break
4347
4368
  }
4369
+ case "auto_approve_permissions":{input.preferences.setAutoApprovePermissions(input.preferences.autoApprovePermissions()!==true)
4370
+ break
4371
+ }
4348
4372
  case "lsp_icon_style":{input.preferences.toggleLspIconStyle()
4349
4373
  break
4350
4374
  }
@@ -4674,6 +4698,42 @@ return _$createElement("box")
4674
4698
  }
4675
4699
 
4676
4700
 
4701
+ function currentPermissionMode(api){const title=api.keymap.getCommands?.({visibility:"registered"
4702
+ }).find((command)=>command.name==="permission.mode")?.title
4703
+ if(typeof title!=="string")
4704
+ return
4705
+ if(title.startsWith("Disable auto-approve permissions"))
4706
+ return true
4707
+ return title.startsWith("Enable auto-approve permissions")?false:undefined
4708
+ }
4709
+ function PermissionModeBinding(props){let applying=false
4710
+ let observed
4711
+ createEffect11(()=>{if(!props.preferences.ready())
4712
+ return
4713
+ const preferred=props.preferences.autoApprovePermissions()
4714
+ const current=currentPermissionMode(props.api)
4715
+ observed=current
4716
+ if(preferred===undefined||current===undefined||current===preferred)
4717
+ return
4718
+ applying=true
4719
+ try{props.api.keymap.dispatchCommand("permission.mode")
4720
+ observed=currentPermissionMode(props.api)
4721
+ } finally{applying=false
4722
+ }})
4723
+ const unsubscribe=props.api.keymap.on?.("state",()=>{if(applying||!props.preferences.ready())
4724
+ return
4725
+ const current=currentPermissionMode(props.api)
4726
+ if(current===undefined||current===observed)
4727
+ return
4728
+ observed=current
4729
+ props.preferences.setAutoApprovePermissions(current)
4730
+ })
4731
+ if(unsubscribe)
4732
+ onCleanup13(unsubscribe)
4733
+ return _$createElement("box")
4734
+ }
4735
+
4736
+
4677
4737
 
4678
4738
  function SettingsFooterButton(props){const icons=useIcons()
4679
4739
  const [hovered,setHovered]=createSignal16(false)
@@ -4745,17 +4805,17 @@ function StartupSessionBinding(props){if(props.api.keymap.on){const unregister=p
4745
4805
  return
4746
4806
  queueMicrotask(()=>void props.controller.start())
4747
4807
  })
4748
- onCleanup13(unregister)
4808
+ onCleanup14(unregister)
4749
4809
  } else
4750
- createEffect11(()=>{if(!props.controller.enabled())
4810
+ createEffect12(()=>{if(!props.controller.enabled())
4751
4811
  return
4752
4812
  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()
4753
4813
  }]
4754
4814
  })
4755
- onCleanup13(unregister)
4815
+ onCleanup14(unregister)
4756
4816
  })
4757
4817
  onMount5(()=>void props.controller.initialize())
4758
- onCleanup13(props.controller.dispose)
4818
+ onCleanup14(props.controller.dispose)
4759
4819
  return _$createElement("box")
4760
4820
  }
4761
4821
  function versionParts(value){const match=/^v?(\d+)\.(\d+)\.(\d+)(?:-([^+]+))?/.exec(value)
@@ -4889,7 +4949,7 @@ if(entries.length===0||disposed)
4889
4949
  return
4890
4950
  show()
4891
4951
  } catch{}})
4892
- onCleanup14(()=>{disposed=true
4952
+ onCleanup15(()=>{disposed=true
4893
4953
  clearTimeout(pending)
4894
4954
  })
4895
4955
  return _$createElement("box")
@@ -5339,7 +5399,7 @@ const colors=()=>sidebarInteractiveColors(api.theme.current,{focused:focused(),h
5339
5399
  const ref=(renderable)=>{unregister?.()
5340
5400
  unregister=interaction?.register({...descriptor,renderable})
5341
5401
  }
5342
- onCleanup15(()=>unregister?.())
5402
+ onCleanup16(()=>unregister?.())
5343
5403
  return{ref,disabled,focused,backgroundColor:()=>colors().backgroundColor,foregroundColor:()=>colors().foregroundColor,onMouseOver:()=>setHovered(true),onMouseOut:()=>setHovered(false),select(event){interaction?.mouseSelect(descriptor.id,event)
5344
5404
  },activate(event){if(interaction)
5345
5405
  return interaction.mouseActivate(descriptor.id,event)
@@ -5484,7 +5544,7 @@ const item=useSidebarItem(props.api,props.interaction,{id:props.sectionId??`sect
5484
5544
  const action=props.headerAction?useSidebarItem(props.api,props.interaction,{id:props.headerAction.id,position:()=>({section:props.navigationSection??0,row:0,column:1
5485
5545
  }),disabled:props.headerAction.disabled,activate:props.headerAction.onActivate
5486
5546
  },()=>theme().accent,"control"):undefined
5487
- createEffect12(()=>{props.headerAction?.label()
5547
+ createEffect13(()=>{props.headerAction?.label()
5488
5548
  setActionWidth(undefined)
5489
5549
  })
5490
5550
  const actionLabel=()=>{const label=props.headerAction?.label()??""
@@ -5946,7 +6006,7 @@ props.interaction.leaveFilter(input)
5946
6006
  else
5947
6007
  input?.blur()
5948
6008
  }
5949
- onCleanup16(()=>unregisterInput?.())
6009
+ onCleanup17(()=>unregisterInput?.())
5950
6010
  return _$createComponent(SelectionBox,{ref:(node)=>item.ref(node),get id(){return props.id
5951
6011
  },flexDirection:"row",gap:1,marginTop:1,marginBottom:1,paddingLeft:1,paddingRight:1,get backgroundColor(){return _$memo(()=>!!highlighted())()?theme().primary:item.backgroundColor()
5952
6012
  },get onMouseOver(){return item.onMouseOver
@@ -6309,8 +6369,8 @@ unregisterBinding=undefined
6309
6369
  unregisterCommands()
6310
6370
  }}}
6311
6371
  function SidebarToggleBinding(props){const shortcuts=createSidebarShortcutMode(props.api)
6312
- createEffect13(()=>shortcuts.bind(props.preferences.toggleKey()))
6313
- onCleanup17(shortcuts.dispose)
6372
+ createEffect14(()=>shortcuts.bind(props.preferences.toggleKey()))
6373
+ onCleanup18(shortcuts.dispose)
6314
6374
  return _$createElement("box")
6315
6375
  }
6316
6376
  function SidebarFocusBinding(props){const commands=props.interaction.baseCommands()
@@ -6318,11 +6378,11 @@ const unregisterCommands=props.api.keymap.registerLayer({commands:[...commands,.
6318
6378
  })=>({name:name.replace(PLUGIN_ID,()=>LEGACY_PLUGIN_ID),run,enabled
6319
6379
  }))]
6320
6380
  })
6321
- onCleanup17(unregisterCommands)
6322
- createEffect13(()=>{const unregister=props.api.keymap.registerLayer({bindings:[{key:props.preferences.focusKey(),cmd:FOCUS_COMMAND
6381
+ onCleanup18(unregisterCommands)
6382
+ createEffect14(()=>{const unregister=props.api.keymap.registerLayer({bindings:[{key:props.preferences.focusKey(),cmd:FOCUS_COMMAND
6323
6383
  }]
6324
6384
  })
6325
- onCleanup17(unregister)
6385
+ onCleanup18(unregister)
6326
6386
  })
6327
6387
  return _$createElement("box")
6328
6388
  }
@@ -6353,9 +6413,9 @@ const filtered=createMemo16(()=>list().filter((item)=>matchesFilter(query(),item
6353
6413
  const visibility=createListVisibility({items:filtered,limit:()=>props.preferences.sectionItemLimit?.("skills")??0,resetKey:()=>JSON.stringify([target().key,query()])
6354
6414
  })
6355
6415
  const state=createMemo16(()=>props.controller.state(target()))
6356
- createEffect14(()=>{const current=target()
6416
+ createEffect15(()=>{const current=target()
6357
6417
  const deactivate=untrack5(()=>props.controller.activate?.(current)??(()=>{}))
6358
- onCleanup18(deactivate)
6418
+ onCleanup19(deactivate)
6359
6419
  untrack5(()=>void props.controller.refresh(current).catch(()=>{}))
6360
6420
  })
6361
6421
  async function useSkill(item){try{const isInserted=await props.controller.use(target(),item.name)
@@ -6516,11 +6576,11 @@ const tabs=createMemo17(()=>["all","active","recent",...counts().errors>0?["erro
6516
6576
  const filtered=createMemo17(()=>filterSubagentView(rows(),mode(),query()))
6517
6577
  const parentID=createMemo17(()=>props.api.state?.session?.get(props.sessionID)?.parentID)
6518
6578
  const targetKey=createMemo17(()=>props.controller.target?.(props.sessionID).key??props.sessionID)
6519
- createEffect15(()=>{targetKey()
6579
+ createEffect16(()=>{targetKey()
6520
6580
  setQuery("")
6521
6581
  setMode("all")
6522
6582
  })
6523
- createEffect15(()=>{if(mode()!=="all"&&counts()[mode()]===0)
6583
+ createEffect16(()=>{if(mode()!=="all"&&counts()[mode()]===0)
6524
6584
  setMode("all")
6525
6585
  })
6526
6586
  const visibility=createListVisibility({items:filtered,limit:()=>props.preferences.sectionItemLimit?.("subagents")??0,resetKey:()=>JSON.stringify([targetKey(),query(),mode()])
@@ -6530,10 +6590,10 @@ const now=createSubagentClock(clockKey)
6530
6590
  const byId=createMemo17(()=>new Map(visibility.visible().map((item)=>[item.session.id,item])))
6531
6591
  const ids=createMemo17(()=>visibility.visible().map((item)=>item.session.id))
6532
6592
  const state=createMemo17(()=>props.controller.state(props.sessionID))
6533
- createEffect15(()=>{const sessionID=props.sessionID
6593
+ createEffect16(()=>{const sessionID=props.sessionID
6534
6594
  targetKey()
6535
6595
  const deactivate=untrack6(()=>props.controller.activate?.(sessionID)??(()=>{}))
6536
- onCleanup19(deactivate)
6596
+ onCleanup20(deactivate)
6537
6597
  untrack6(()=>void props.controller.refresh(sessionID).catch(()=>{}))
6538
6598
  })
6539
6599
  return{list,recent,rows,query,setQuery,mode,setMode,counts,tabs,filtered,parentID,visibility,now,byId,ids,state
@@ -6880,19 +6940,19 @@ const unavailable=()=>hostCapabilityUnavailable(props.api,"todo")
6880
6940
  const managed=()=>("guidance" in props.controller)?props.controller:undefined
6881
6941
  const [mode,setMode]=createSignal28("all")
6882
6942
  const targetKey=createMemo18(()=>props.controller.target?.(props.sessionID).key??props.sessionID)
6883
- createEffect16(()=>{targetKey()
6943
+ createEffect17(()=>{targetKey()
6884
6944
  setMode("all")
6885
6945
  })
6886
6946
  const view=createMemo18(()=>buildTodoView(list(),mode()))
6887
6947
  const visibility=createListVisibility({items:()=>view().rows,limit:()=>props.preferences.sectionItemLimit?.("todo")??0,resetKey:()=>JSON.stringify([targetKey(),mode()])
6888
6948
  })
6889
6949
  const state=createMemo18(()=>props.controller.state(props.sessionID))
6890
- createEffect16(()=>{const sessionID=props.sessionID
6950
+ createEffect17(()=>{const sessionID=props.sessionID
6891
6951
  targetKey()
6892
6952
  if(unavailable())
6893
6953
  return
6894
6954
  const deactivate=untrack7(()=>props.controller.activate?.(sessionID)??(()=>{}))
6895
- onCleanup20(deactivate)
6955
+ onCleanup21(deactivate)
6896
6956
  untrack7(()=>void props.controller.refresh(sessionID).catch(()=>{}))
6897
6957
  })
6898
6958
  const navigationSection=()=>props.navigationSection??1
@@ -6949,7 +7009,7 @@ return _el$4
6949
7009
  }
6950
7010
  function SidebarContent(props){const sections=props.preferences.sections
6951
7011
  const visibleSections=createMemo19(()=>props.preferences.sectionOrder().filter((section)=>sections()[section]&&supportsSidebarSection(props.api,section)))
6952
- onCleanup21(()=>props.interaction.setContentRoot(undefined))
7012
+ onCleanup22(()=>props.interaction.setContentRoot(undefined))
6953
7013
  return(()=>{var _el$=_$createElement("box")
6954
7014
  _$use((node)=>props.interaction.setContentRoot(node),_el$)
6955
7015
  _$setProp(_el$,"id",`${PLUGIN_ID}.root`)
@@ -6996,7 +7056,7 @@ return _el$
6996
7056
 
6997
7057
 
6998
7058
  function McpPersistence(props){const persist=createMemo20(()=>props.controller.persist())
6999
- createEffect17(()=>{if(!props.api.state.ready)
7059
+ createEffect18(()=>{if(!props.api.state.ready)
7000
7060
  return
7001
7061
  persist()
7002
7062
  const route=props.api.route.current
@@ -7004,12 +7064,12 @@ const params="params" in route?route.params:undefined
7004
7064
  if(typeof params?.sessionID!=="string")
7005
7065
  return
7006
7066
  const current=props.controller.target()
7007
- onCleanup22(()=>props.controller.deactivate(current))
7067
+ onCleanup23(()=>props.controller.deactivate(current))
7008
7068
  untrack8(()=>void props.controller.activate(current).catch(()=>{}))
7009
7069
  })
7010
7070
  return _$createElement("box")
7011
7071
  }
7012
- function PreferencesPersistence(props){createEffect17(()=>{const location=currentLocation(props.api)
7072
+ function PreferencesPersistence(props){createEffect18(()=>{const location=currentLocation(props.api)
7013
7073
  untrack8(()=>props.controller.setActiveScope(preferencesScope({directory:location.routing.directory,worktree:props.api.state.path.worktree
7014
7074
  })))
7015
7075
  props.controller.load()
@@ -7017,7 +7077,7 @@ props.controller.load()
7017
7077
  return _$createElement("box")
7018
7078
  }
7019
7079
  function FirstRunWizardPersistence(props){let isChecked=false
7020
- createEffect17(()=>{if(isChecked)
7080
+ createEffect18(()=>{if(isChecked)
7021
7081
  return
7022
7082
  isChecked=true
7023
7083
  showFirstRunWizard(props.api,props.preferences).catch(()=>{})
@@ -7044,7 +7104,7 @@ const settingsId=`${PLUGIN_ID}.settings`
7044
7104
  const settings=useSidebarItem(props.api,props.interaction,{id:settingsId,position:{section:0,row:0,column:0
7045
7105
  },activate:()=>openSettings(props.api,props.preferences,undefined,props.mcp,props.skills)
7046
7106
  },()=>theme().textMuted,"control")
7047
- onCleanup23(()=>props.interaction.setTitleRoot(undefined))
7107
+ onCleanup24(()=>props.interaction.setTitleRoot(undefined))
7048
7108
  return(()=>{var _el$=_$createElement("box"),_el$2=_$createElement("box"),_el$3=_$createElement("box")
7049
7109
  _$insertNode(_el$,_el$2)
7050
7110
  _$use((node)=>props.interaction.setTitleRoot(node),_el$)
@@ -7307,7 +7367,7 @@ function legacyTheme(theme){return{primary:theme.hue.interactive[200],secondary:
7307
7367
 
7308
7368
  function createV2UI(context){let dialogOpen=false
7309
7369
  function DialogPrompt(props){let active=true
7310
- onCleanup24(()=>{active=false
7370
+ onCleanup25(()=>{active=false
7311
7371
  })
7312
7372
  onMount7(async ()=>{const value=await context.ui.dialog.prompt({title:props.title,placeholder:props.placeholder,value:props.value
7313
7373
  })
@@ -7321,7 +7381,7 @@ props.onConfirm?.(value)
7321
7381
  return _$createElement("box")
7322
7382
  }
7323
7383
  function DialogConfirm(props){let active=true
7324
- onCleanup24(()=>{active=false
7384
+ onCleanup25(()=>{active=false
7325
7385
  })
7326
7386
  onMount7(async ()=>{const confirmed=await context.ui.dialog.confirm({title:props.title,message:props.message
7327
7387
  })
@@ -7386,7 +7446,7 @@ context.ui.router.navigate({type:"plugin",name,data:params})
7386
7446
  },attention:context.attention,lifecycle:{signal:controller.signal,onDispose}}
7387
7447
  api.slots=createV2Slots(context,keymap,(dispose)=>{onDispose(dispose)
7388
7448
  })
7389
- setHostCapabilities(api,{todo:true,lsp:false,titleVisibility:false
7449
+ setHostCapabilities(api,{todo:true,lsp:false,titleVisibility:false,permissionMode:false
7390
7450
  })
7391
7451
  return{api,async dispose(){controller.abort()
7392
7452
  for(let index=disposers.length-1;index>=0; index--)
@@ -7481,14 +7541,15 @@ api.lifecycle.onDispose(unsubscribeConnected)
7481
7541
  api.slots.register({order:100,slots:{app(){return _$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7482
7542
  },get multilineCorners(){return preferences.cornerFont
7483
7543
  },get children(){return [_$createComponent(PreferencesPersistence,{api,controller:preferences
7484
- }),_$createComponent(SettingsBinding,{api,preferences,mcp,skills
7544
+ }),_$memo(()=>_$memo(()=>!!supportsPermissionMode(api))()&&_$createComponent(PermissionModeBinding,{api,preferences
7545
+ })),_$createComponent(SettingsBinding,{api,preferences,mcp,skills
7485
7546
  }),_$createComponent(SidebarToggleBinding,{api,preferences
7486
7547
  }),_$createComponent(SidebarFocusBinding,{api,preferences,interaction
7487
7548
  }),_$createComponent(SearchBinding,{api,preferences,get onNewSession(){return startup.handleNewSession
7488
7549
  },interaction,skills,subagents,mcp
7489
7550
  }),_$createComponent(FirstRunWizardPersistence,{api,preferences
7490
7551
  }),_$createComponent(StartupSessionBinding,{api,controller:startup
7491
- }),_$createComponent(UpgradeNotesBinding,{api,preferences,version:"0.19.0"
7552
+ }),_$createComponent(UpgradeNotesBinding,{api,preferences,version:"0.19.1"
7492
7553
  }),_$createComponent(McpPersistence,{api,controller:mcp
7493
7554
  })]
7494
7555
  }})
@@ -7518,12 +7579,12 @@ throw result.error
7518
7579
  }
7519
7580
  return result.data?.type==="text"?result.data.content:undefined
7520
7581
  })
7521
- const versionStatus=createVersionStatus(api,"0.19.0")
7522
- const versionUpdates=createVersionUpdateActions(api,versionStatus,createOpenCodeV1VersionUpdater(api,meta),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.19.0"))
7582
+ const versionStatus=createVersionStatus(api,"0.19.1")
7583
+ const versionUpdates=createVersionUpdateActions(api,versionStatus,createOpenCodeV1VersionUpdater(api,meta),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.19.1"))
7523
7584
  api.slots.register({order:90,slots:{sidebar_footer(_context,props){return _$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7524
7585
  },get multilineCorners(){return preferences.cornerFont
7525
7586
  },get children(){return _$createComponent(VersionFooter,{api,get sessionID(){return props.session_id
7526
- },navigatorVersion:"0.19.0",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7587
+ },navigatorVersion:"0.19.1",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7527
7588
  },get onNavigatorUpdate(){return versionUpdates.navigator
7528
7589
  }})
7529
7590
  }})
@@ -7537,15 +7598,15 @@ return
7537
7598
  return new TextDecoder().decode(await context.client.file.read({location:context.location,path:".opencode/navigator.json"
7538
7599
  }))
7539
7600
  },todo)
7540
- const versionStatus=createVersionStatus(adapter.api,"0.19.0")
7541
- const versionUpdates=createVersionUpdateActions(adapter.api,versionStatus,createOpenCodeV2VersionUpdater(context),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.19.0"))
7601
+ const versionStatus=createVersionStatus(adapter.api,"0.19.1")
7602
+ const versionUpdates=createVersionUpdateActions(adapter.api,versionStatus,createOpenCodeV2VersionUpdater(context),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.19.1"))
7542
7603
  const disposeFooter=context.ui.slot({append:"sidebar.footer",render:()=>_$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
7543
7604
  },get multilineCorners(){return preferences.cornerFont
7544
7605
  },get children(){var _el$=_$createElement("box")
7545
7606
  _$setProp(_el$,"flexDirection","row")
7546
7607
  _$setProp(_el$,"justifyContent","space-between")
7547
7608
  _$insert(_el$,_$createComponent(VersionSummary,{get api(){return adapter.api
7548
- },navigatorVersion:"0.19.0",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7609
+ },navigatorVersion:"0.19.1",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
7549
7610
  },get onNavigatorUpdate(){return versionUpdates.navigator
7550
7611
  }}),null)
7551
7612
  _$insert(_el$,_$createComponent(SettingsFooterButton,{get api(){return adapter.api
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "opencode-navigator",
4
- "version": "0.19.0",
4
+ "version": "0.19.1",
5
5
  "description": "Search, navigate, and manage OpenCode sessions from the TUI",
6
6
  "type": "module",
7
7
  "packageManager": "bun@1.4.2",