opencode-navigator 0.23.0 → 0.25.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.
@@ -1,23 +1,487 @@
1
1
  import {SIDEBAR_SECTIONS,SECTION_DEFINITIONS,PLUGIN_ID,DEFAULT_SEARCH_KEY
2
2
  } from "./chunk-bv0nm1tj.js"
3
+ import {isNewerVersion
4
+ } from "./chunk-fd7394y1.js"
3
5
  import"./chunk-qmntexwm.js";
6
+ import {use as _$use5} from "@opentui/solid"
7
+ import {createComponent as _$createComponent12} from "@opentui/solid"
4
8
  import {memo as _$memo4} from "@opentui/solid"
9
+ import {effect as _$effect10} from "@opentui/solid"
10
+ import {createTextNode as _$createTextNode9} from "@opentui/solid"
11
+ import {insertNode as _$insertNode9} from "@opentui/solid"
12
+ import {insert as _$insert8} from "@opentui/solid"
13
+ import {setProp as _$setProp10} from "@opentui/solid"
14
+ import {createElement as _$createElement11} from "@opentui/solid"
15
+ import {TextAttributes as TextAttributes3} from "@opentui/core"
16
+ import {For as For3,Show as Show5} from "solid-js"
17
+ import {DialogSurface as DialogSurface5,Tab} from "./tui.js"
18
+ import {createComponent as _$createComponent9} from "@opentui/solid"
19
+ import {useTerminalDimensions as useTerminalDimensions4} from "@opentui/solid"
20
+ import {createEffect as createEffect3,createMemo as createMemo3,onCleanup as onCleanup6} from "solid-js"
21
+ import {useDialogScroll as useDialogScroll2,useDialogState as useDialogState4,useDialogs as useDialogs4,useIcons as useIcons2} from "./tui.js"
22
+ import {use as _$use3} from "@opentui/solid"
23
+ import {effect as _$effect3} from "@opentui/solid"
24
+ import {insert as _$insert2} from "@opentui/solid"
25
+ import {setProp as _$setProp3} from "@opentui/solid"
26
+ import {createElement as _$createElement3} from "@opentui/solid"
27
+ import {createComponent as _$createComponent3} from "@opentui/solid"
28
+ import {useTerminalDimensions as useTerminalDimensions2} from "@opentui/solid"
29
+ import {For} from "solid-js"
30
+ import {DialogAction as DialogAction2,DialogHeader as DialogHeader2,DialogSurface as DialogSurface2} from "./tui.js"
31
+ import {createComponent as _$createComponent2} from "@opentui/solid"
32
+ import {createMemo,createSignal,onMount} from "solid-js"
33
+ import {useDialogState as useDialogState2,useDialogs} from "./tui.js"
5
34
  import {use as _$use} from "@opentui/solid"
6
- import {createComponent as _$createComponent6} from "@opentui/solid"
7
- import {effect as _$effect7} from "@opentui/solid"
8
- import {createTextNode as _$createTextNode7} from "@opentui/solid"
9
- import {insertNode as _$insertNode7} from "@opentui/solid"
10
- import {insert as _$insert5} from "@opentui/solid"
11
- import {setProp as _$setProp7} from "@opentui/solid"
12
- import {createElement as _$createElement7} from "@opentui/solid"
13
- import {TextAttributes as TextAttributes5} from "@opentui/core"
14
- import {For as For3} from "solid-js"
15
- import {DialogSurface as DialogSurface2,Tab} from "./tui.js"
35
+ import {effect as _$effect} from "@opentui/solid"
36
+ import {insert as _$insert} from "@opentui/solid"
37
+ import {createTextNode as _$createTextNode} from "@opentui/solid"
38
+ import {insertNode as _$insertNode} from "@opentui/solid"
39
+ import {setProp as _$setProp} from "@opentui/solid"
40
+ import {createElement as _$createElement} from "@opentui/solid"
41
+ import {mergeProps as _$mergeProps} from "@opentui/solid"
42
+ import {createComponent as _$createComponent} from "@opentui/solid"
16
43
  import {useTerminalDimensions} from "@opentui/solid"
17
- import {createEffect,createMemo as createMemo2,onCleanup as onCleanup2,onMount} from "solid-js"
18
- import {useDialogScroll,useDialogState,useDialogs as useDialogs2,useIcons as useIcons4} from "./tui.js"
19
- import {createMemo} from "solid-js"
44
+ import {onCleanup} from "solid-js"
45
+ import {DialogAction,DialogHeader,DialogSurface,GuardedConfirmation,useDialogState} from "./tui.js"
46
+ async function runProcessCommand(command,input="",signal,timeoutMs=15000,environment){if(signal?.aborted)
47
+ return{code:-1,stdout:"",timedOut:true}
48
+ let child
49
+ try{child=Bun.spawn([...command],{stdin:"pipe",stdout:"pipe",stderr:"ignore",env:environment?{...process.env,...environment}:undefined
50
+ })
51
+ } catch{return{code:-1,stdout:""}}
52
+ child.stdin.write(input)
53
+ child.stdin.end()
54
+ let timer
55
+ const chunks=[]
56
+ const output=()=>new TextDecoder().decode(Buffer.concat(chunks))
57
+ let cancel
58
+ const cancelled=new Promise((resolve)=>{cancel=()=>{try{child.kill("SIGKILL")
59
+ } catch{}
60
+ resolve({code:-1,stdout:output(),timedOut:true})
61
+ }
62
+ timer=setTimeout(cancel,timeoutMs)
63
+ signal?.addEventListener("abort",cancel,{once:true})
64
+ if(signal?.aborted)
65
+ cancel()
66
+ })
67
+ const read=async ()=>{const reader=child.stdout.getReader()
68
+ let size=0
69
+ try{while(true){const part=await reader.read()
70
+ if(part.done)
71
+ break
72
+ size += part.value.byteLength
73
+ if(size>65536){child.kill()
74
+ throw new Error("Command output exceeded its limit")
75
+ }
76
+ chunks.push(part.value)
77
+ }
78
+ return{code:await child.exited,stdout:output()}} finally{reader.releaseLock()
79
+ }}
80
+ try{return await Promise.race([read(),cancelled])
81
+ } catch{return{code:-1,stdout:""}} finally{clearTimeout(timer)
82
+ signal?.removeEventListener("abort",cancel)
83
+ }}
84
+ async function openExternalUrl(url,signal){const target=new URL(url)
85
+ if(!["https:","http:"].includes(target.protocol)||target.username||target.password)
86
+ return false
87
+ const programs={darwin:["open",url],linux:["xdg-open",url],win32:["rundll32.exe","url.dll,FileProtocolHandler",url]
88
+ }
89
+ const command=programs[process.platform]
90
+ if(!command)
91
+ return false
92
+ const result=await runProcessCommand(command,"",signal,4000)
93
+ return result.code===0
94
+ }
95
+ var BUG_REPORT_REPOSITORY="St1ggy/opencode-navigator"
96
+ var BUG_REPORT_BASE=`https://github.com/${BUG_REPORT_REPOSITORY}/issues`
97
+ function bugReportBrowserTarget(draft){const target=new URL(`${BUG_REPORT_BASE}/new`)
98
+ target.searchParams.set("template","bug_report.yml")
99
+ target.searchParams.set("title",draft.title)
100
+ target.searchParams.set("report",draft.body)
101
+ const needsCopy=target.href.length>7000
102
+ if(needsCopy)
103
+ target.searchParams.delete("report")
104
+ const copyTitle=target.href.length>7000
105
+ if(copyTitle)
106
+ target.searchParams.delete("title")
107
+ return{url:target.href,needsCopy,copyText:copyTitle?`${draft.title}
108
+
109
+ ${draft.body}`:draft.body}}
110
+ function BugReportConfirmation(props){return _$createComponent(GuardedConfirmation,{get api(){return props.api
111
+ },title:"Send Bug report",get message(){return props.draft.title
112
+ },get current(){return props.current
113
+ },get onConfirm(){return props.onConfirm
114
+ },render:(actions)=>_$createComponent(BugReportReview,_$mergeProps({get api(){return props.api
115
+ },get draft(){return props.draft
116
+ }},actions))
117
+ })
118
+ }
119
+ function BugReportReview(props){const dimensions=useTerminalDimensions()
120
+ const [selected,setSelected]=useDialogState("confirm-report",0)
121
+ let body
122
+ const prefix="opencode-navigator.bug-report.confirm"
123
+ const unregister=props.api.keymap.registerLayer({mode:"modal",priority:1200,commands:[{name:`${prefix}.switch`,run:()=>setSelected((value)=>1-value)
124
+ },{name:`${prefix}.activate`,run:()=>selected()?props.confirm():props.cancel()
125
+ },{name:`${prefix}.up`,run:()=>body?.scrollBy(-1)
126
+ },{name:`${prefix}.down`,run:()=>body?.scrollBy(1)
127
+ }],bindings:[...["tab","shift+tab","left","right"].map((key)=>({key,cmd:`${prefix}.switch`
128
+ })),{key:"return",cmd:`${prefix}.activate`
129
+ },{key:"up",cmd:`${prefix}.up`
130
+ },{key:"down",cmd:`${prefix}.down`
131
+ }]
132
+ })
133
+ onCleanup(unregister)
134
+ return _$createComponent(DialogSurface,{get api(){return props.api
135
+ },lift:true,get children(){return [_$createComponent(DialogHeader,{get api(){return props.api
136
+ },title:"Send Bug report",icon:"bug",get onBack(){return props.cancel
137
+ }}),(()=>{var _el$=_$createElement("text"),_el$2=_$createTextNode(`Public issue in `),_el$3=_$createTextNode(` \xB7 Type: Bug`)
138
+ _$insertNode(_el$,_el$2)
139
+ _$insertNode(_el$,_el$3)
140
+ _$setProp(_el$,"wrapMode","word")
141
+ _$insert(_el$,BUG_REPORT_REPOSITORY,_el$3)
142
+ _$effect((_$p)=>_$setProp(_el$,"fg",props.api.theme.current.textMuted,_$p))
143
+ return _el$
144
+ })(),(()=>{var _el$4=_$createElement("scrollbox"),_el$5=_$createElement("text"),_el$6=_$createTextNode(`
145
+
146
+ `)
147
+ _$insertNode(_el$4,_el$5)
148
+ _$use((node)=>{body=node
149
+ },_el$4)
150
+ _$setProp(_el$4,"scrollX",false)
151
+ _$insertNode(_el$5,_el$6)
152
+ _$setProp(_el$5,"wrapMode","word")
153
+ _$insert(_el$5,()=>props.draft.title,_el$6)
154
+ _$insert(_el$5,()=>props.draft.body,null)
155
+ _$effect((_p$)=>{var _v$=Math.max(3,Math.min(12,dimensions().height-15)),_v$2=props.api.theme.current.text
156
+ _v$!==_p$.e&&(_p$.e=_$setProp(_el$4,"height",_v$,_p$.e))
157
+ _v$2!==_p$.t&&(_p$.t=_$setProp(_el$5,"fg",_v$2,_p$.t))
158
+ return _p$
159
+ },{e:undefined,t:undefined
160
+ })
161
+ return _el$4
162
+ })(),(()=>{var _el$7=_$createElement("box")
163
+ _$setProp(_el$7,"flexDirection","row")
164
+ _$setProp(_el$7,"gap",1)
165
+ _$insert(_el$7,_$createComponent(DialogAction,{get api(){return props.api
166
+ },id:`${prefix}.cancel`,label:"Cancel",icon:"close",get selected(){return selected()===0
167
+ },onSelect:()=>setSelected(0),get onActivate(){return props.cancel
168
+ }}),null)
169
+ _$insert(_el$7,_$createComponent(DialogAction,{get api(){return props.api
170
+ },id:`${prefix}.send`,label:"Send report",icon:"export",get selected(){return selected()===1
171
+ },onSelect:()=>setSelected(1),get onActivate(){return props.confirm
172
+ }}),null)
173
+ return _el$7
174
+ })()]
175
+ }})
176
+ }
177
+ import {createEffect,onCleanup as onCleanup2} from "solid-js"
178
+ function registerBugReportNavigation(input){const prefix="opencode-navigator.bug-report"
179
+ createEffect(()=>{const actionsFocused=input.active()>=2
180
+ const unregister=input.api.keymap.registerLayer({mode:"modal",priority:1100,commands:[{name:`${prefix}.next`,run:()=>input.focus((input.active() + 1)%6)},{name:`${prefix}.previous`,run:()=>input.focus((input.active() + 5)%6)},{name:`${prefix}.send`,run:input.send},{name:`${prefix}.title-next`,run:()=>input.focus(1)},{name:`${prefix}.activate`,enabled:()=>input.active()>=2,run:()=>input.activate(input.active()-2)
181
+ },{name:`${prefix}.up`,enabled:()=>input.active()>=2,run:()=>input.focus(input.active()===2?5:input.active()-1)
182
+ },{name:`${prefix}.down`,enabled:()=>input.active()>=2,run:()=>input.focus(input.active()===5?2:input.active() + 1)
183
+ }],bindings:[{key:"tab",cmd:`${prefix}.next`},{key:"shift+tab",cmd:`${prefix}.previous`},{key:"ctrl+return",cmd:`${prefix}.send`},...input.active()===0?[{key:"return",cmd:`${prefix}.title-next`}]:[],...actionsFocused?[{key:"return",cmd:`${prefix}.activate`},{key:"up",cmd:`${prefix}.up`},{key:"down",cmd:`${prefix}.down`}]:[]]
184
+ })
185
+ onCleanup2(unregister)
186
+ })
187
+ }
188
+ function createBugReportDialogController(api,model){const dialogs=useDialogs(api)
189
+ const [active,setActive]=useDialogState2("report-field",0)
190
+ const [notice,setNotice]=useDialogState2("report-notice","")
191
+ const [copyLink,setCopyLink]=useDialogState2("browser-failed",false)
192
+ const [cursor,setCursor]=useDialogState2("report-cursor",0)
193
+ const [hovered,setHovered]=createSignal()
194
+ let title
195
+ let body
196
+ let actions
197
+ const focus=(index)=>{setActive(index)
198
+ setHovered(undefined)
199
+ if(index===0)
200
+ title?.focus()
201
+ else if(index===1)
202
+ body?.focus()
203
+ else
204
+ actions?.focus()
205
+ }
206
+ const send=()=>{if(!model.canSend())
207
+ return
208
+ const draft={...model.draft()
209
+ }
210
+ dialogs.open(()=>_$createComponent2(BugReportConfirmation,{api,draft,current:()=>model.canSend()&&JSON.stringify(draft)===JSON.stringify(model.draft()),onConfirm:()=>{dialogs.back()
211
+ model.send(draft).then(()=>{const result=model.result()
212
+ if(api.lifecycle.signal?.aborted||!result||api.ui.dialog.open)
213
+ return
214
+ api.ui.toast({variant:result.status==="created"?"success":"warning",title:"Bug report",message:result.url??result.message,duration:6000
215
+ })
216
+ })
217
+ }}))
218
+ }
219
+ const browse=async ()=>{if(!model.canBrowse())
220
+ return
221
+ const target=model.browser()
222
+ if(copyLink()){const copied=api.renderer.copyToClipboardOSC52(target.url)
223
+ setNotice(copied?"Browser link copied.":"Clipboard unavailable. The full draft remains in the editor.")
224
+ return
225
+ }
226
+ if(target.needsCopy&&!api.renderer.copyToClipboardOSC52(target.copyText)){setNotice("Clipboard unavailable. Shorten the report URL or copy the draft manually.")
227
+ return
228
+ }
229
+ setCopyLink(!await model.open(target.url))
230
+ }
231
+ function browserLabel(){if(copyLink())
232
+ return "Copy browser link"
233
+ if(model.result()?.status==="uncertain")
234
+ return "Check GitHub issues in browser"
235
+ return model.browser().needsCopy?"Copy report & open browser":"Open in browser"
236
+ }
237
+ function maintenanceLabel(){const status=model.result()?.status
238
+ if(status==="uncertain")
239
+ return "Retry after checking GitHub"
240
+ return status==="created"||status==="partial"?"New report":"Check GitHub CLI"
241
+ }
242
+ function maintain(){const status=model.result()?.status
243
+ setNotice("")
244
+ setCopyLink(false)
245
+ if(status==="uncertain")
246
+ model.retryAfterReview()
247
+ else if(status==="created"||status==="partial"){model.newReport()
248
+ body?.setText(model.draft().body)
249
+ setCursor(0)
250
+ focus(0)
251
+ } else
252
+ model.probe(true)
253
+ }
254
+ const options=createMemo(()=>[{label:model.busy()?"Sending\u2026":"Send to GitHub\u2026",icon:"export",disabled:!model.canSend(),run:send
255
+ },{label:browserLabel(),icon:"right",disabled:!model.canBrowse(),run:()=>void browse()
256
+ },{label:maintenanceLabel(),icon:"retry",disabled:model.busy()||model.readiness().status==="checking",run:maintain
257
+ },{label:model.busy()?"Back (sending continues)":"Cancel",icon:"close",disabled:false,run:dialogs.back
258
+ }])
259
+ function activate(index){const option=options()[index]
260
+ if(option&&!option.disabled)
261
+ option.run()
262
+ }
263
+ registerBugReportNavigation({api,active,focus,activate,send
264
+ })
265
+ onMount(()=>{model.probe()
266
+ queueMicrotask(()=>focus(active()))
267
+ })
268
+ return{dialogs,options,setHovered,setCursor,status:()=>notice()||model.result()?.message||model.message()||model.readiness().message,selected:(index)=>(hovered()??active()-2)===index,activate(index){focus(index + 2)
269
+ activate(index)
270
+ },editorFocus(index){setActive(index)
271
+ setHovered(undefined)
272
+ },titleSubmit:()=>focus(1),titleRef(node){title=node
273
+ },bodyRef(node){body=node
274
+ body.cursorOffset=cursor()
275
+ },actionsRef(node){actions=node
276
+ }}}
277
+ import {effect as _$effect2} from "@opentui/solid"
278
+ import {use as _$use2} from "@opentui/solid"
279
+ import {setProp as _$setProp2} from "@opentui/solid"
280
+ import {createTextNode as _$createTextNode2} from "@opentui/solid"
281
+ import {insertNode as _$insertNode2} from "@opentui/solid"
282
+ import {createElement as _$createElement2} from "@opentui/solid"
283
+ import {untrack} from "solid-js"
284
+ function BugReportEditor(props){let body
285
+ const initialBody=untrack(()=>props.draft.body)
286
+ const theme=()=>props.api.theme.current
287
+ return [(()=>{var _el$=_$createElement2("box"),_el$2=_$createElement2("text"),_el$4=_$createElement2("input")
288
+ _$insertNode2(_el$,_el$2)
289
+ _$insertNode2(_el$,_el$4)
290
+ _$insertNode2(_el$2,_$createTextNode2(`Issue title`))
291
+ var _ref$=props.titleRef
292
+ typeof _ref$==="function"?_$use2(_ref$,_el$4):props.titleRef=_el$4
293
+ _$setProp2(_el$4,"id","opencode-navigator.bug-report.title")
294
+ _$setProp2(_el$4,"placeholder","Describe the problem briefly")
295
+ _$setProp2(_el$4,"on:focused",()=>props.focus(0))
296
+ _$setProp2(_el$4,"onInput",(title)=>props.change({title
297
+ }))
298
+ _$effect2((_p$)=>{var _v$=theme().textMuted,_v$2=props.draft.title,_v$3=theme().text,_v$4=theme().text,_v$5=theme().backgroundPanel,_v$6=theme().backgroundElement,_v$7=theme().textMuted,_v$8=theme().primary,_v$9=props.titleSubmit
299
+ _v$!==_p$.e&&(_p$.e=_$setProp2(_el$2,"fg",_v$,_p$.e))
300
+ _v$2!==_p$.t&&(_p$.t=_$setProp2(_el$4,"value",_v$2,_p$.t))
301
+ _v$3!==_p$.a&&(_p$.a=_$setProp2(_el$4,"textColor",_v$3,_p$.a))
302
+ _v$4!==_p$.o&&(_p$.o=_$setProp2(_el$4,"focusedTextColor",_v$4,_p$.o))
303
+ _v$5!==_p$.i&&(_p$.i=_$setProp2(_el$4,"backgroundColor",_v$5,_p$.i))
304
+ _v$6!==_p$.n&&(_p$.n=_$setProp2(_el$4,"focusedBackgroundColor",_v$6,_p$.n))
305
+ _v$7!==_p$.s&&(_p$.s=_$setProp2(_el$4,"placeholderColor",_v$7,_p$.s))
306
+ _v$8!==_p$.h&&(_p$.h=_$setProp2(_el$4,"cursorColor",_v$8,_p$.h))
307
+ _v$9!==_p$.r&&(_p$.r=_$setProp2(_el$4,"onSubmit",_v$9,_p$.r))
308
+ return _p$
309
+ },{e:undefined,t:undefined,a:undefined,o:undefined,i:undefined,n:undefined,s:undefined,h:undefined,r:undefined
310
+ })
311
+ return _el$
312
+ })(),(()=>{var _el$5=_$createElement2("box"),_el$6=_$createElement2("text"),_el$8=_$createElement2("textarea")
313
+ _$insertNode2(_el$5,_el$6)
314
+ _$insertNode2(_el$5,_el$8)
315
+ _$insertNode2(_el$6,_$createTextNode2(`Description, reproduction, and expected behavior`))
316
+ _$use2((node)=>{body=node
317
+ untrack(()=>props.bodyRef(node))
318
+ },_el$8)
319
+ _$setProp2(_el$8,"id","opencode-navigator.bug-report.body")
320
+ _$setProp2(_el$8,"initialValue",initialBody)
321
+ _$setProp2(_el$8,"wrapMode","word")
322
+ _$setProp2(_el$8,"on:focused",()=>props.focus(1))
323
+ _$setProp2(_el$8,"onContentChange",()=>{if(body)
324
+ props.change({body:body.plainText
325
+ })
326
+ })
327
+ _$setProp2(_el$8,"onCursorChange",()=>{if(body)
328
+ props.cursor(body.cursorOffset)
329
+ })
330
+ _$effect2((_p$)=>{var _v$0=theme().textMuted,_v$1=props.height,_v$10=theme().text,_v$11=theme().text,_v$12=theme().backgroundPanel,_v$13=theme().backgroundElement,_v$14=theme().primary
331
+ _v$0!==_p$.e&&(_p$.e=_$setProp2(_el$6,"fg",_v$0,_p$.e))
332
+ _v$1!==_p$.t&&(_p$.t=_$setProp2(_el$8,"height",_v$1,_p$.t))
333
+ _v$10!==_p$.a&&(_p$.a=_$setProp2(_el$8,"textColor",_v$10,_p$.a))
334
+ _v$11!==_p$.o&&(_p$.o=_$setProp2(_el$8,"focusedTextColor",_v$11,_p$.o))
335
+ _v$12!==_p$.i&&(_p$.i=_$setProp2(_el$8,"backgroundColor",_v$12,_p$.i))
336
+ _v$13!==_p$.n&&(_p$.n=_$setProp2(_el$8,"focusedBackgroundColor",_v$13,_p$.n))
337
+ _v$14!==_p$.s&&(_p$.s=_$setProp2(_el$8,"cursorColor",_v$14,_p$.s))
338
+ return _p$
339
+ },{e:undefined,t:undefined,a:undefined,o:undefined,i:undefined,n:undefined,s:undefined
340
+ })
341
+ return _el$5
342
+ })()]
343
+ }
344
+ function BugReportDialog(props){const model=createBugReportDialogController(props.api,props.controller)
345
+ const dimensions=useTerminalDimensions2()
346
+ return _$createComponent3(DialogSurface2,{get api(){return props.api
347
+ },lift:true,get children(){return [_$createComponent3(DialogHeader2,{get api(){return props.api
348
+ },title:"Report a bug",icon:"bug",get onBack(){return model.dialogs.back
349
+ }}),_$createComponent3(BugReportEditor,{get api(){return props.api
350
+ },get draft(){return props.controller.draft()
351
+ },get height(){return Math.max(3,Math.min(8,dimensions().height-21))
352
+ },get titleRef(){return model.titleRef
353
+ },get bodyRef(){return model.bodyRef
354
+ },get change(){return props.controller.change
355
+ },get cursor(){return model.setCursor
356
+ },get focus(){return model.editorFocus
357
+ },get titleSubmit(){return model.titleSubmit
358
+ }}),(()=>{var _el$=_$createElement3("text")
359
+ _$setProp3(_el$,"height",1)
360
+ _$setProp3(_el$,"truncate",true)
361
+ _$setProp3(_el$,"wrapMode","none")
362
+ _$insert2(_el$,()=>model.status())
363
+ _$effect3((_$p)=>_$setProp3(_el$,"fg",props.api.theme.current.textMuted,_$p))
364
+ return _el$
365
+ })(),(()=>{var _el$2=_$createElement3("box")
366
+ var _ref$=model.actionsRef
367
+ typeof _ref$==="function"?_$use3(_ref$,_el$2):model.actionsRef=_el$2
368
+ _$setProp3(_el$2,"id","opencode-navigator.bug-report.actions")
369
+ _$setProp3(_el$2,"focusable",true)
370
+ _$insert2(_el$2,_$createComponent3(For,{each:[0,1,2,3],children:(index)=>_$createComponent3(DialogAction2,{get api(){return props.api
371
+ },id:`opencode-navigator.bug-report.action.${index}`,get label(){return model.options()[index].label
372
+ },get icon(){return model.options()[index].icon
373
+ },get disabled(){return model.options()[index].disabled
374
+ },get selected(){return model.selected(index)
375
+ },onSelect:()=>model.setHovered(index),onActivate:()=>model.activate(index)
376
+ })
377
+ }))
378
+ return _el$2
379
+ })()]
380
+ }})
381
+ }
382
+ import {getNavigatorAboutServices as getNavigatorAboutServices3} from "./tui.js"
383
+ import {createSignal as createSignal2} from "solid-js"
384
+ function initialBugReport(environment){return{title:"",body:`## What happened
385
+
386
+ ## Steps to reproduce
387
+
388
+ ## Expected behavior
389
+
390
+ ## Environment
391
+ - Navigator: ${environment.navigatorVersion}
392
+ - OpenCode: ${environment.openCodeVersion}
393
+ - Platform: ${environment.platform}
394
+ - Runtime: ${environment.runtime}
395
+ `
396
+ }}
397
+ function validBugReport(draft){return Boolean(draft.title.trim()&&draft.body.trim())
398
+ }
399
+ function runGitHubCommand(command,input,signal){return runProcessCommand(command,input,signal,15000,{GH_PROMPT_DISABLED:"1",GH_HOST:"github.com",GH_PAGER:"cat"
400
+ })
401
+ }
402
+ function createGitHubBugReportTransport(open,run=runGitHubCommand){return{open,async probe(signal){const version=await run(["gh","--version"],"",signal)
403
+ if(version.code!==0)
404
+ return{status:"missing",message:"Install GitHub CLI for direct sending, or open the browser."}
405
+ const auth=await run(["gh","auth","status","--active","--hostname","github.com"],"",signal)
406
+ if(auth.code!==0)
407
+ return{status:"unauthenticated",message:"Sign in with gh auth login, or open the browser."}
408
+ const help=await run(["gh","issue","create","--help"],"",signal)
409
+ return help.code===0&&help.stdout.includes("--type")?{status:"ready",message:"Ready to send through your authenticated GitHub CLI."}:{status:"unsupported",message:"Update gh to support the Bug issue type, or use the browser."}},async send(draft,signal){const result=await run(["gh","issue","create","--repo",`github.com/${BUG_REPORT_REPOSITORY}`,"--type","Bug",`--title=${draft.title.trim()}`,"--body-file","-"],draft.body,signal)
410
+ const url=/^https:\/\/github\.com\/St1ggy\/opencode-navigator\/issues\/\d+\s*$/m.exec(result.stdout)?.[0].trim()
411
+ if(url)
412
+ return result.code===0?{status:"created",message:"Bug report created.",url}:{status:"partial",message:"Issue created; open it to review the Bug type.",url}
413
+ if(result.timedOut||![-1,4,127].includes(result.code))
414
+ return{status:"uncertain",message:"Outcome unknown. Check GitHub before sending again."}
415
+ return{status:"failed",message:"Could not send. Check GitHub access, then retry."}}}}
416
+ function createBugReportController(environment,transport=createGitHubBugReportTransport(openExternalUrl),signal){const [draft,setDraft]=createSignal2(initialBugReport(environment))
417
+ const [readiness,setReadiness]=createSignal2({status:"checking",message:"Checking GitHub CLI\u2026"
418
+ })
419
+ const [busy,setBusy]=createSignal2(false)
420
+ const [result,setResult]=createSignal2()
421
+ const [message,setMessage]=createSignal2("")
422
+ let probing
423
+ let checked=false
424
+ const locked=()=>busy()||result()&&result().status!=="failed"
425
+ function probe(force=false){if(probing)
426
+ return probing
427
+ if(checked&&!force)
428
+ return Promise.resolve()
429
+ setReadiness({status:"checking",message:"Checking GitHub CLI\u2026"})
430
+ probing=transport.probe(signal).then(setReadiness).catch(()=>setReadiness({status:"missing",message:"Could not check gh. The browser remains available."})).then(()=>{checked=true
431
+ }).finally(()=>{probing=undefined
432
+ })
433
+ return probing
434
+ }
435
+ return{draft,readiness,busy,result,message,probe,change(value){setDraft((previous)=>({...previous,...value}))
436
+ },canSend:()=>readiness().status==="ready"&&validBugReport(draft())&&!locked(),canBrowse:()=>result()?.status==="uncertain"||Boolean(result()?.url)||validBugReport(draft()),browser:()=>{if(result()?.url)
437
+ return{url:result().url,needsCopy:false,copyText:""}
438
+ if(result()?.status==="uncertain")
439
+ return{url:BUG_REPORT_BASE,needsCopy:false,copyText:""}
440
+ return bugReportBrowserTarget(draft())
441
+ },retryAfterReview(){if(busy()||result()?.status!=="uncertain")
442
+ return
443
+ setResult(undefined)
444
+ setMessage("Review your report, then confirm another send.")
445
+ },newReport(){if(busy())
446
+ return
447
+ setResult(undefined)
448
+ setMessage("")
449
+ setDraft(initialBugReport(environment))
450
+ },async send(confirmed){if(readiness().status!=="ready"||!validBugReport(confirmed)||locked()||JSON.stringify(confirmed)!==JSON.stringify(draft()))
451
+ return
452
+ setBusy(true)
453
+ setResult(undefined)
454
+ setMessage("Sending your Bug report\u2026")
455
+ try{setResult(await transport.send({...confirmed},signal))
456
+ } catch{setResult({status:"uncertain",message:"Outcome unknown. Check GitHub before sending again."})
457
+ } finally{setBusy(false)
458
+ }},async open(url){if(url!==BUG_REPORT_BASE&&!url.startsWith(`${BUG_REPORT_BASE}/`))
459
+ return false
460
+ try{const opened=await transport.open(url,signal)
461
+ setMessage(opened?"Opened in your browser.":`Browser unavailable. Copy this URL: ${url}`)
462
+ return opened
463
+ } catch{setMessage(`Browser unavailable. Copy this URL: ${url}`)
464
+ return false
465
+ }}}}
466
+ import {createMemo as createMemo2} from "solid-js"
20
467
  import {supportsSidebarSection} from "./tui.js"
468
+ import {getNavigatorAboutServices} from "./tui.js"
469
+ function aboutSettingsOptions(api,icons){const service=getNavigatorAboutServices(api)
470
+ const state=service?.checkState()
471
+ const busy=!service||service.checking()||service.updating()
472
+ let updateDescription="No confirmed update available"
473
+ if(service?.installed?.())
474
+ updateDescription="Installed; restart OpenCode"
475
+ else if(service?.updating())
476
+ updateDescription="Installing\u2026"
477
+ else if(state?.status==="available")
478
+ updateDescription=`Install ${state.latest}`
479
+ return [{title:`${icons.icon("retry")} Check for updates`,value:"about:check",description:service?.checking()?"Checking\u2026":"Check the published Navigator version",disabled:busy
480
+ },{title:`${icons.icon("update")} Update Navigator\u2026`,value:"about:update",description:updateDescription,disabled:busy||state?.status!=="available"||Boolean(service?.installed?.())
481
+ },{title:`${icons.icon("history")} Changelog by version\u2026`,value:"about:changelog",description:"Browse the bundled release history",disabled:!service
482
+ },{title:`${icons.icon("bug")} Report a bug\u2026`,value:"about:bug-report",description:"Edit a Bug report; send with gh or open your browser",disabled:!service
483
+ }]
484
+ }
21
485
  import {supportsPermissionMode} from "./tui.js"
22
486
  function behaviorSettingsOptions(api,preferences,icons){const permission=preferences.autoApprovePermissions()
23
487
  const permissionDescription=permission?"on for new sessions":"off for new sessions"
@@ -45,7 +509,7 @@ return [{title:`${icons.icon(title ? "checked" : "unchecked")} Session title`,va
45
509
  }]
46
510
  }
47
511
  function createSettingsGroups(api,preferences,icons){const supportedSections=()=>SIDEBAR_SECTIONS.filter((name)=>supportsSidebarSection(api,name))
48
- const groups=createMemo(()=>[{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"
512
+ const groups=createMemo2(()=>[{id:"about",tab:"About",title:"About Navigator",options:aboutSettingsOptions(api,icons)},{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"
49
513
  },{title:`${icons.icon(preferences.preferenceScope() === "worktree" ? "radioOn" : "radioOff")} Current worktree`,value:"scope:worktree",description:preferences.canUseWorktreeScope()?preferences.preferenceScopeLabel():"unavailable outside a worktree"
50
514
  }]
51
515
  },{id:"presets",tab:"Presets",title:"Layout presets",options:[...Object.keys(preferences.layoutPresets()).sort((left,right)=>left.localeCompare(right)).map((name)=>({title:`${icons.icon("presets")} ${name}`,value:`preset:custom:${encodeURIComponent(name)}`,description:preferences.workspaceProfiles?.()[name]?`profile \xB7 ${preferences.workspaceProfiles()[name]}`:"enter to apply or edit"
@@ -66,7 +530,7 @@ return{title:`${icons.icon(preferences.selectedSections()[section.name] ? "check
66
530
  },{title:`${icons.icon("help")} Open quick setup guide`,value:"wizard",description:"tips and section settings"
67
531
  }]
68
532
  }])
69
- const orderedGroups=createMemo(()=>["sections","scope","presets","behavior","defaults"].map((id)=>groups().find((group)=>group.id===id)))
533
+ const orderedGroups=createMemo2(()=>["sections","scope","presets","behavior","defaults","about"].map((id)=>groups().find((group)=>group.id===id)))
70
534
  return orderedGroups
71
535
  }
72
536
  function registerSettingsKeymap(input){return input.api.keymap.registerLayer({mode:"modal",priority:1000,commands:[{name:`${PLUGIN_ID}.settings.previous`,run:()=>input.move(-1)},{name:`${PLUGIN_ID}.settings.next`,run:()=>input.move(1)},{name:`${PLUGIN_ID}.settings.select`,run:()=>input.select()},{name:`${PLUGIN_ID}.settings.groups`,run:()=>{if(input.activeGroup()!=="sections")
@@ -83,298 +547,212 @@ input.openLimitPrompt(section)
83
547
  }},{name:`${PLUGIN_ID}.settings.previous-tab`,run:()=>input.switchGroup(-1)},{name:`${PLUGIN_ID}.settings.next-tab`,run:()=>input.switchGroup(1)},{name:`${PLUGIN_ID}.settings.move-up`,run:()=>input.reorder(input.options()[input.active()]?.value,-1)},{name:`${PLUGIN_ID}.settings.move-down`,run:()=>input.reorder(input.options()[input.active()]?.value,1)}],bindings:[{key:"up",cmd:`${PLUGIN_ID}.settings.previous`},{key:"down",cmd:`${PLUGIN_ID}.settings.next`},{key:"tab",cmd:`${PLUGIN_ID}.settings.next-tab`},{key:"shift+tab",cmd:`${PLUGIN_ID}.settings.previous-tab`},{key:"space",cmd:`${PLUGIN_ID}.settings.select`},{key:"return",cmd:`${PLUGIN_ID}.settings.select`},{key:"l",cmd:`${PLUGIN_ID}.settings.item-limit`},{key:"a",cmd:`${PLUGIN_ID}.settings.quick-actions`},{key:"g",cmd:`${PLUGIN_ID}.settings.groups`},{key:"left",cmd:`${PLUGIN_ID}.settings.move-up`},{key:"right",cmd:`${PLUGIN_ID}.settings.move-down`},{key:"shift+up",cmd:`${PLUGIN_ID}.settings.move-up`},{key:"shift+down",cmd:`${PLUGIN_ID}.settings.move-down`}]
84
548
  })
85
549
  }
550
+ import {useRenderer} from "@opentui/solid"
551
+ import {createEffect as createEffect2,onCleanup as onCleanup3} from "solid-js"
552
+ function useSettingsReveal(input){const renderer=useRenderer()
553
+ let pending=true
554
+ createEffect2(()=>{input.active()
555
+ input.group()
556
+ pending=true
557
+ })
558
+ const reveal=()=>{if(!pending)
559
+ return
560
+ const body=input.body()
561
+ const option=input.options()[input.active()]
562
+ if(!body||body.isDestroyed||body.scrollHeight===0||!option)
563
+ return
564
+ pending=false
565
+ body.scrollChildIntoView(input.optionId(option.value))
566
+ }
567
+ renderer.on("frame",reveal)
568
+ onCleanup3(()=>renderer.off("frame",reveal))
569
+ }
570
+ import {createComponent as _$createComponent8} from "@opentui/solid"
571
+ import {setProp as _$setProp7} from "@opentui/solid"
572
+ import {effect as _$effect7} from "@opentui/solid"
573
+ import {createTextNode as _$createTextNode6} from "@opentui/solid"
574
+ import {insertNode as _$insertNode6} from "@opentui/solid"
575
+ import {createElement as _$createElement8} from "@opentui/solid"
576
+ import {insert as _$insert3} from "@opentui/solid"
86
577
  import {createComponent as _$createComponent4} from "@opentui/solid"
87
- import {setProp as _$setProp5} from "@opentui/solid"
578
+ import {createElement as _$createElement4} from "@opentui/solid"
579
+ import {Suspense,lazy} from "solid-js"
580
+ import {createDialogStack} from "./tui.js"
581
+ var Content=lazy(async ()=>{const path=import.meta.url.includes("/dist/")?"./onboarding.js":"./first-run-wizard-content"
582
+ const module=await import(path)
583
+ return{default:module.FirstRunWizard
584
+ }})
585
+ function FirstRunWizard(props){return(()=>{var _el$=_$createElement4("box")
586
+ _$insert3(_el$,_$createComponent4(Suspense,{get children(){return _$createComponent4(Content,props)
587
+ }}))
588
+ return _el$
589
+ })()
590
+ }
591
+ import {createComponent as _$createComponent7} from "@opentui/solid"
592
+ import {createTextNode as _$createTextNode4} from "@opentui/solid"
593
+ import {insertNode as _$insertNode4} from "@opentui/solid"
88
594
  import {effect as _$effect5} from "@opentui/solid"
89
- import {createTextNode as _$createTextNode5} from "@opentui/solid"
90
- import {insertNode as _$insertNode5} from "@opentui/solid"
91
- import {createElement as _$createElement5} from "@opentui/solid"
92
- import {createComponent as _$createComponent3} from "@opentui/solid"
93
- import {effect as _$effect3} from "@opentui/solid"
595
+ import {insert as _$insert5} from "@opentui/solid"
596
+ import {memo as _$memo} from "@opentui/solid"
597
+ import {setProp as _$setProp5} from "@opentui/solid"
598
+ import {createElement as _$createElement6} from "@opentui/solid"
599
+ import {createComponent as _$createComponent6} from "@opentui/solid"
600
+ import {Show as Show2,onCleanup as onCleanup5,onMount as onMount2} from "solid-js"
601
+ import {DialogAction as DialogAction3,DialogHeader as DialogHeader4,DialogSurface as DialogSurface4,SelectionMenu,useDialogState as useDialogState3,useDialogs as useDialogs3} from "./tui.js"
602
+ import {insert as _$insert4} from "@opentui/solid"
603
+ import {use as _$use4} from "@opentui/solid"
604
+ import {setProp as _$setProp4} from "@opentui/solid"
605
+ import {effect as _$effect4} from "@opentui/solid"
94
606
  import {createTextNode as _$createTextNode3} from "@opentui/solid"
95
607
  import {insertNode as _$insertNode3} from "@opentui/solid"
96
- import {insert as _$insert3} from "@opentui/solid"
97
- import {setProp as _$setProp3} from "@opentui/solid"
98
- import {createElement as _$createElement3} from "@opentui/solid"
99
- import {TextAttributes as TextAttributes3} from "@opentui/core"
100
- import {Show,createSignal,onCleanup} from "solid-js"
101
- import {supportsSidebarSection as supportsSidebarSection3} from "./tui.js"
102
- import {DialogSurface,createDialogStack,useDialogs,useIcons as useIcons3} from "./tui.js"
103
- 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."}]
104
- },{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."
105
- },{icon:"info",title:"Provider limits",description:"Link a matching Codex account for model quotas and confirmed banked resets."
106
- }]
107
- },{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."
108
- },{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."
109
- }]
110
- },{title:"Run actions and check language tools",summary:"Keep frequent OpenCode commands and LSP health within one compact section.",icon:"actions",features:[{icon:"actions",title:"Quick Actions",description:"Rename, inspect timelines, copy, export, or compact the session."
111
- },{icon:"lsp",title:"Compact LSP status",description:"Spot connected and failed language servers at a glance."
112
- },{icon:"settings",title:"Configurable commands",description:"Choose action visibility, order, and shortcuts."
113
- }]
114
- },{title:"Control MCP without losing context",summary:"Manage individual servers or entire working sets directly from Navigator.",icon:"mcp",features:[{icon:"mcp",title:"Live server controls",description:"Connect, disconnect, filter, and favorite servers."},{icon:"actions",title:"Bulk operations",description:"Change eligible servers together and retry failures."
115
- },{icon:"presets",title:"Safe presets",description:"Preview connections and disconnections before Apply."}]
116
- },{title:"Make Navigator fit each workspace",summary:"Use the same controls with mouse or keyboard and keep only the context you need.",icon:"settings",features:[{icon:"sections",title:"Flexible layout",description:"Choose section visibility, order, expansion, and item limits."
117
- },{icon:"presets",title:"Scoped presets",description:"Save layouts globally or for the current worktree."},{icon:"settings",title:"Accessible controls",description:"Change shortcuts or use Text fallback without a restart."
118
- }]
119
- }];
120
- import {effect as _$effect} from "@opentui/solid"
121
- import {memo as _$memo} from "@opentui/solid"
122
- import {createComponent as _$createComponent} from "@opentui/solid"
123
- import {createTextNode as _$createTextNode} from "@opentui/solid"
124
- import {insertNode as _$insertNode} from "@opentui/solid"
125
- import {insert as _$insert} from "@opentui/solid"
126
- import {setProp as _$setProp} from "@opentui/solid"
127
- import {createElement as _$createElement} from "@opentui/solid"
128
- import {TextAttributes} from "@opentui/core"
129
- import {For} from "solid-js"
130
- import {SelectionBox,useIcons} from "./tui.js"
131
- function OnboardingStep(props){const icons=useIcons()
132
- const theme=()=>props.api.theme.current
133
- return(()=>{var _el$=_$createElement("box"),_el$2=_$createElement("text"),_el$3=_$createTextNode(` `),_el$4=_$createElement("text"),_el$5=_$createElement("box"),_el$6=_$createElement("text"),_el$7=_$createTextNode(`Toggle: `),_el$8=_$createTextNode(` \xB7 Focus: `),_el$9=_$createTextNode(` \xB7 Icons: `),_el$1=_$createElement("box")
134
- _$insertNode(_el$,_el$2)
135
- _$insertNode(_el$,_el$4)
136
- _$insertNode(_el$,_el$5)
137
- _$insertNode(_el$,_el$6)
138
- _$insertNode(_el$,_el$1)
139
- _$setProp(_el$,"gap",1)
140
- _$insertNode(_el$2,_el$3)
141
- _$insert(_el$2,()=>icons.icon(props.step.icon),_el$3)
142
- _$insert(_el$2,()=>props.step.title,null)
143
- _$setProp(_el$4,"wrapMode","word")
144
- _$insert(_el$4,()=>props.step.summary)
145
- _$setProp(_el$5,"border",["top","bottom"])
146
- _$setProp(_el$5,"paddingTop",1)
147
- _$setProp(_el$5,"paddingBottom",1)
148
- _$setProp(_el$5,"gap",1)
149
- _$insert(_el$5,_$createComponent(For,{get each(){return props.step.features
150
- },children:(feature)=>(()=>{var _el$14=_$createElement("box"),_el$15=_$createElement("text"),_el$16=_$createElement("text"),_el$17=_$createElement("b"),_el$18=_$createTextNode(` \xB7 `)
151
- _$insertNode(_el$14,_el$15)
152
- _$insertNode(_el$14,_el$16)
153
- _$setProp(_el$14,"flexDirection","row")
154
- _$setProp(_el$14,"gap",1)
155
- _$setProp(_el$15,"flexShrink",0)
156
- _$insert(_el$15,()=>icons.icon(feature.icon))
157
- _$insertNode(_el$16,_el$17)
158
- _$insertNode(_el$16,_el$18)
159
- _$setProp(_el$16,"flexGrow",1)
160
- _$setProp(_el$16,"minWidth",0)
161
- _$setProp(_el$16,"wrapMode","word")
162
- _$insert(_el$17,()=>feature.title)
163
- _$insert(_el$16,()=>feature.description,null)
164
- _$effect((_p$)=>{var _v$6=theme().accent,_v$7=theme().textMuted
165
- _v$6!==_p$.e&&(_p$.e=_$setProp(_el$15,"fg",_v$6,_p$.e))
166
- _v$7!==_p$.t&&(_p$.t=_$setProp(_el$16,"fg",_v$7,_p$.t))
167
- return _p$
168
- },{e:undefined,t:undefined
169
- })
170
- return _el$14
171
- })()
608
+ import {createElement as _$createElement5} from "@opentui/solid"
609
+ import {createComponent as _$createComponent5} from "@opentui/solid"
610
+ import {useTerminalDimensions as useTerminalDimensions3} from "@opentui/solid"
611
+ import {For as For2,Show,onCleanup as onCleanup4} from "solid-js"
612
+ import {DialogHeader as DialogHeader3,DialogSurface as DialogSurface3,useDialogScroll,useDialogs as useDialogs2,useIcons} from "./tui.js"
613
+ function ChangelogVersionDialog(props){const dialogs=useDialogs2(props.api)
614
+ const icons=useIcons()
615
+ const dimensions=useTerminalDimensions3()
616
+ const scroll=useDialogScroll()
617
+ let body
618
+ const keys=["up","down","pageup","pagedown"]
619
+ const unregister=props.api.keymap.registerLayer({mode:"modal",commands:keys.map((_key,index)=>({name:`opencode-navigator.changelog.scroll.${index}`,run:()=>body?.scrollBy([-1,1,-8,8][index])
620
+ })),bindings:keys.map((key,index)=>({key,cmd:`opencode-navigator.changelog.scroll.${index}`
172
621
  }))
173
- _$insertNode(_el$6,_el$7)
174
- _$insertNode(_el$6,_el$8)
175
- _$insertNode(_el$6,_el$9)
176
- _$setProp(_el$6,"wrapMode","word")
177
- _$insert(_el$6,()=>props.preferences.toggleKey(),_el$8)
178
- _$insert(_el$6,()=>props.preferences.focusKey(),_el$9)
179
- _$insert(_el$6,()=>icons.style()==="text"?"Text fallback":"Nerd Font",null)
180
- _$setProp(_el$1,"flexDirection","row")
181
- _$setProp(_el$1,"justifyContent","space-between")
182
- _$insert(_el$1,_$createComponent(SelectionBox,{paddingLeft:1,paddingRight:1,onMouseDown:(event)=>event.stopPropagation(),onMouseUp:(event)=>{event.stopPropagation()
183
- props.onBack()
184
- },get children(){var _el$10=_$createElement("text"),_el$11=_$createTextNode(` Back`)
185
- _$insertNode(_el$10,_el$11)
186
- _$insert(_el$10,()=>icons.icon("left"),_el$11)
187
- _$effect((_$p)=>_$setProp(_el$10,"fg",theme().textMuted,_$p))
188
- return _el$10
189
- }}),null)
190
- _$insert(_el$1,_$createComponent(SelectionBox,{paddingLeft:1,paddingRight:1,get backgroundColor(){return theme().primary
191
- },onMouseDown:(event)=>event.stopPropagation(),onMouseUp:(event)=>{event.stopPropagation()
192
- props.onAdvance()
193
- },get children(){var _el$12=_$createElement("text"),_el$13=_$createTextNode(` `)
194
- _$insertNode(_el$12,_el$13)
195
- _$insert(_el$12,()=>props.final?"Configure sidebar":"Next",_el$13)
196
- _$insert(_el$12,()=>icons.icon("right"),null)
197
- _$effect((_$p)=>_$setProp(_el$12,"fg",theme().selectedListItemText,_$p))
198
- return _el$12
199
- }}),null)
200
- _$effect((_p$)=>{var _v$=theme().accent,_v$2=TextAttributes.BOLD,_v$3=theme().textMuted,_v$4=theme().borderSubtle,_v$5=theme().textMuted
201
- _v$!==_p$.e&&(_p$.e=_$setProp(_el$2,"fg",_v$,_p$.e))
202
- _v$2!==_p$.t&&(_p$.t=_$setProp(_el$2,"attributes",_v$2,_p$.t))
203
- _v$3!==_p$.a&&(_p$.a=_$setProp(_el$4,"fg",_v$3,_p$.a))
204
- _v$4!==_p$.o&&(_p$.o=_$setProp(_el$5,"borderColor",_v$4,_p$.o))
205
- _v$5!==_p$.i&&(_p$.i=_$setProp(_el$6,"fg",_v$5,_p$.i))
206
- return _p$
207
- },{e:undefined,t:undefined,a:undefined,o:undefined,i:undefined
208
622
  })
623
+ onCleanup4(unregister)
624
+ return _$createComponent5(DialogSurface3,{get api(){return props.api
625
+ },lift:true,get children(){return [_$createComponent5(DialogHeader3,{get api(){return props.api
626
+ },get title(){return `Navigator ${props.entry.version}`
627
+ },get onBack(){return dialogs.back
628
+ }}),(()=>{var _el$=_$createElement5("text")
629
+ _$insertNode3(_el$,_$createTextNode3(`Release notes`))
630
+ _$effect4((_$p)=>_$setProp4(_el$,"fg",props.api.theme.current.textMuted,_$p))
209
631
  return _el$
632
+ })(),(()=>{var _el$3=_$createElement5("scrollbox"),_el$4=_$createElement5("box")
633
+ _$insertNode3(_el$3,_el$4)
634
+ _$use4((node)=>{body=node
635
+ scroll.ref(node)
636
+ },_el$3)
637
+ _$setProp4(_el$3,"id","opencode-navigator.changelog.body")
638
+ _$setProp4(_el$3,"scrollX",false)
639
+ _$setProp4(_el$4,"gap",1)
640
+ _$setProp4(_el$4,"paddingRight",1)
641
+ _$insert4(_el$4,_$createComponent5(Show,{get when(){return props.entry.changes.length>0
642
+ },get fallback(){return(()=>{var _el$8=_$createElement5("text")
643
+ _$insertNode3(_el$8,_$createTextNode3(`No user-facing changes in this version.`))
644
+ _$effect4((_$p)=>_$setProp4(_el$8,"fg",props.api.theme.current.textMuted,_$p))
645
+ return _el$8
210
646
  })()
211
- }
212
- import {memo as _$memo2} from "@opentui/solid"
213
- import {effect as _$effect2} from "@opentui/solid"
214
- import {createComponent as _$createComponent2} from "@opentui/solid"
215
- import {createTextNode as _$createTextNode2} from "@opentui/solid"
216
- import {insertNode as _$insertNode2} from "@opentui/solid"
217
- import {insert as _$insert2} from "@opentui/solid"
218
- import {setProp as _$setProp2} from "@opentui/solid"
219
- import {createElement as _$createElement2} from "@opentui/solid"
220
- import {TextAttributes as TextAttributes2} from "@opentui/core"
221
- import {For as For2} from "solid-js"
222
- import {supportsSidebarSection as supportsSidebarSection2} from "./tui.js"
223
- import {SelectionBox as SelectionBox2,useIcons as useIcons2} from "./tui.js"
224
- function SectionConfig(props){const icons=useIcons2()
225
- const theme=()=>props.api.theme.current
226
- const sections=SECTION_DEFINITIONS.filter((section)=>supportsSidebarSection2(props.api,section.name))
227
- const finishIndex=sections.length
228
- return(()=>{var _el$=_$createElement2("box"),_el$2=_$createElement2("text"),_el$3=_$createTextNode2(` Choose your sidebar sections`),_el$4=_$createElement2("text"),_el$6=_$createElement2("box")
229
- _$insertNode2(_el$,_el$2)
230
- _$insertNode2(_el$,_el$4)
231
- _$insertNode2(_el$,_el$6)
232
- _$setProp2(_el$,"gap",1)
233
- _$insertNode2(_el$2,_el$3)
234
- _$insert2(_el$2,()=>icons.icon("sections"),_el$3)
235
- _$insertNode2(_el$4,_$createTextNode2(`Select what appears now. You can change visibility, order, limits, scope, and presets later with the gear button.`))
236
- _$setProp2(_el$4,"wrapMode","word")
237
- _$insert2(_el$,_$createComponent2(For2,{each:sections,children:(section,index)=>_$createComponent2(SelectionBox2,{flexDirection:"row",gap:1,paddingLeft:1,paddingRight:1,get backgroundColor(){return _$memo2(()=>props.active===index())()?theme().backgroundElement:undefined
238
- },onMouseOver:()=>props.onActive(index()),onMouseDown:(event)=>event.stopPropagation(),onMouseUp:(event)=>{event.stopPropagation()
239
- props.preferences.toggleSection(section.name)
240
- },get children(){return [(()=>{var _el$1=_$createElement2("text")
241
- _$setProp2(_el$1,"flexShrink",0)
242
- _$insert2(_el$1,()=>icons.icon(props.preferences.sections()[section.name]?"checked":"unchecked"))
243
- _$effect2((_$p)=>_$setProp2(_el$1,"fg",props.preferences.sections()[section.name]?theme().accent:theme().textMuted,_$p))
244
- return _el$1
245
- })(),(()=>{var _el$10=_$createElement2("text"),_el$11=_$createTextNode2(` `)
246
- _$insertNode2(_el$10,_el$11)
247
- _$insert2(_el$10,()=>icons.section(section.name),_el$11)
248
- _$insert2(_el$10,()=>section.label,null)
249
- _$effect2((_$p)=>_$setProp2(_el$10,"fg",props.active===index()?theme().text:theme().textMuted,_$p))
250
- return _el$10
647
+ },get children(){return _$createComponent5(For2,{get each(){return props.entry.changes
648
+ },children:(change)=>(()=>{var _el$0=_$createElement5("text"),_el$1=_$createTextNode3(` `)
649
+ _$insertNode3(_el$0,_el$1)
650
+ _$setProp4(_el$0,"wrapMode","word")
651
+ _$insert4(_el$0,()=>icons.icon("selected"),_el$1)
652
+ _$insert4(_el$0,change,null)
653
+ _$effect4((_$p)=>_$setProp4(_el$0,"fg",props.api.theme.current.text,_$p))
654
+ return _el$0
655
+ })()
656
+ })
657
+ }}))
658
+ _$effect4((_$p)=>_$setProp4(_el$3,"height",Math.max(3,Math.min(16,dimensions().height-13)),_$p))
659
+ return _el$3
660
+ })(),(()=>{var _el$5=_$createElement5("text"),_el$6=_$createTextNode3(` scroll \xB7 `),_el$7=_$createTextNode3(` back`)
661
+ _$insertNode3(_el$5,_el$6)
662
+ _$insertNode3(_el$5,_el$7)
663
+ _$insert4(_el$5,()=>icons.key("up/down"),_el$6)
664
+ _$insert4(_el$5,()=>icons.key("esc"),_el$7)
665
+ _$effect4((_$p)=>_$setProp4(_el$5,"fg",props.api.theme.current.textMuted,_$p))
666
+ return _el$5
251
667
  })()]
252
668
  }})
253
- }),_el$6)
254
- _$setProp2(_el$6,"flexDirection","row")
255
- _$setProp2(_el$6,"justifyContent","space-between")
256
- _$insert2(_el$6,_$createComponent2(SelectionBox2,{paddingLeft:1,paddingRight:1,onMouseDown:(event)=>event.stopPropagation(),onMouseUp:(event)=>{event.stopPropagation()
257
- props.onBack()
258
- },get children(){var _el$7=_$createElement2("text"),_el$8=_$createTextNode2(` Back`)
259
- _$insertNode2(_el$7,_el$8)
260
- _$insert2(_el$7,()=>icons.icon("left"),_el$8)
261
- _$effect2((_$p)=>_$setProp2(_el$7,"fg",theme().textMuted,_$p))
262
- return _el$7
263
- }}),null)
264
- _$insert2(_el$6,_$createComponent2(SelectionBox2,{paddingLeft:2,paddingRight:2,get backgroundColor(){return _$memo2(()=>props.active===finishIndex)()?theme().primary:undefined
265
- },onMouseOver:()=>props.onActive(finishIndex),onMouseDown:(event)=>event.stopPropagation(),onMouseUp:(event)=>{event.stopPropagation()
266
- props.onFinish()
267
- },get children(){var _el$9=_$createElement2("text"),_el$0=_$createTextNode2(` Finish`)
268
- _$insertNode2(_el$9,_el$0)
269
- _$insert2(_el$9,()=>icons.icon("done"),_el$0)
270
- _$effect2((_$p)=>_$setProp2(_el$9,"fg",props.active===finishIndex?theme().selectedListItemText:theme().textMuted,_$p))
271
- return _el$9
272
- }}),null)
273
- _$effect2((_p$)=>{var _v$=theme().accent,_v$2=TextAttributes2.BOLD,_v$3=theme().textMuted
274
- _v$!==_p$.e&&(_p$.e=_$setProp2(_el$2,"fg",_v$,_p$.e))
275
- _v$2!==_p$.t&&(_p$.t=_$setProp2(_el$2,"attributes",_v$2,_p$.t))
276
- _v$3!==_p$.a&&(_p$.a=_$setProp2(_el$4,"fg",_v$3,_p$.a))
277
- return _p$
278
- },{e:undefined,t:undefined,a:undefined
279
- })
280
- return _el$
281
- })()
282
- }
283
- function FirstRunWizard(props){const icons=useIcons3()
284
- const dialogs=useDialogs(props.api)
285
- const [active,setActive]=createSignal(0)
286
- const [step,setStep]=createSignal(0)
287
- const theme=()=>props.api.theme.current
288
- const sections=SECTION_DEFINITIONS.filter((section)=>supportsSidebarSection3(props.api,section.name))
289
- const finishIndex=sections.length
290
- const stepCount=ONBOARDING_STEPS.length + 1
291
- const configuring=()=>step()===ONBOARDING_STEPS.length
292
- function finish(){dialogs.back()
293
- }
294
- function move(offset){if(configuring())
295
- setActive((value)=>(value + offset + finishIndex + 1)%(finishIndex + 1))
296
- else
297
- setStep((value)=>Math.max(0,Math.min(ONBOARDING_STEPS.length,value + offset)))
298
- }
299
- function back(){setStep((value)=>Math.max(0,value-1))
300
- }
301
- function advance(){if(!configuring())
302
- setStep((value)=>Math.min(ONBOARDING_STEPS.length,value + 1))
303
669
  }
304
- function select(){if(!configuring()){advance()
305
- return
306
- }
307
- const index=active()
308
- if(index===finishIndex)
309
- finish()
310
- else
311
- props.preferences.toggleSection(sections[index].name)
312
- }
313
- const unregister=props.api.keymap.registerLayer({mode:"modal",priority:1000,commands:[{name:`${PLUGIN_ID}.wizard.previous`,run(){move(-1)
314
- }},{name:`${PLUGIN_ID}.wizard.next`,run(){move(1)
315
- }},{name:`${PLUGIN_ID}.wizard.select`,run:select
316
- },{name:`${PLUGIN_ID}.wizard.back`,run:back
317
- },{name:`${PLUGIN_ID}.wizard.forward`,run:advance
318
- }],bindings:[{key:"up",cmd:`${PLUGIN_ID}.wizard.previous`
319
- },{key:"down",cmd:`${PLUGIN_ID}.wizard.next`
320
- },{key:"tab",cmd:`${PLUGIN_ID}.wizard.next`
321
- },{key:"left",cmd:`${PLUGIN_ID}.wizard.back`
322
- },{key:"right",cmd:`${PLUGIN_ID}.wizard.forward`
323
- },{key:"space",cmd:`${PLUGIN_ID}.wizard.select`
324
- },{key:"return",cmd:`${PLUGIN_ID}.wizard.select`
325
- }]
670
+ function ChangelogVersionsDialog(props){const dialogs=useDialogs3(props.api)
671
+ const [entries,setEntries]=useDialogState3("releases",undefined)
672
+ const [error,setError]=useDialogState3("read-error","")
673
+ let disposed=false
674
+ const load=async ()=>{setError("")
675
+ try{const result=await props.service.changelog()
676
+ if(!disposed)
677
+ setEntries(result.filter((entry)=>!isNewerVersion(entry.version,props.service.navigatorVersion)))
678
+ } catch{if(!disposed)
679
+ setError("Could not read the bundled changelog. Retry to read it again.")
680
+ }}
681
+ onMount2(()=>{if(!entries())
682
+ load()
326
683
  })
327
- onCleanup(unregister)
328
- return _$createComponent3(DialogSurface,{get api(){return props.api
329
- },get children(){return [(()=>{var _el$=_$createElement3("box"),_el$2=_$createElement3("text"),_el$3=_$createTextNode3(` Navigator setup`),_el$4=_$createElement3("text"),_el$5=_$createTextNode3(`Step `),_el$6=_$createTextNode3(`/`),_el$7=_$createTextNode3(` \xB7 `)
330
- _$insertNode3(_el$,_el$2)
331
- _$insertNode3(_el$,_el$4)
332
- _$setProp3(_el$,"flexDirection","row")
333
- _$setProp3(_el$,"justifyContent","space-between")
334
- _$insertNode3(_el$2,_el$3)
335
- _$insert3(_el$2,()=>icons.icon("help"),_el$3)
336
- _$insertNode3(_el$4,_el$5)
337
- _$insertNode3(_el$4,_el$6)
338
- _$insertNode3(_el$4,_el$7)
339
- _$setProp3(_el$4,"onMouseDown",(event)=>event.stopPropagation())
340
- _$setProp3(_el$4,"onMouseUp",(event)=>{event.stopPropagation()
341
- finish()
342
- })
343
- _$insert3(_el$4,()=>step() + 1,_el$6)
344
- _$insert3(_el$4,stepCount,_el$7)
345
- _$insert3(_el$4,()=>icons.key("esc"),null)
346
- _$effect3((_p$)=>{var _v$=TextAttributes3.BOLD,_v$2=theme().text,_v$3=theme().textMuted
347
- _v$!==_p$.e&&(_p$.e=_$setProp3(_el$2,"attributes",_v$,_p$.e))
348
- _v$2!==_p$.t&&(_p$.t=_$setProp3(_el$2,"fg",_v$2,_p$.t))
349
- _v$3!==_p$.a&&(_p$.a=_$setProp3(_el$4,"fg",_v$3,_p$.a))
350
- return _p$
351
- },{e:undefined,t:undefined,a:undefined
684
+ onCleanup5(()=>{disposed=true
685
+ })
686
+ const unregister=props.api.keymap.registerLayer({mode:"modal",commands:[{name:"opencode-navigator.changelog.retry",enabled:()=>Boolean(error())&&!entries(),run:()=>void load()
687
+ }],bindings:[{key:"return",cmd:"opencode-navigator.changelog.retry"
688
+ }]
352
689
  })
690
+ onCleanup5(unregister)
691
+ return _$createComponent6(Show2,{get when(){return entries()
692
+ },get fallback(){return _$createComponent6(DialogSurface4,{get api(){return props.api
693
+ },lift:true,get children(){return [_$createComponent6(DialogHeader4,{get api(){return props.api
694
+ },title:"Navigator changelog",get onBack(){return dialogs.back
695
+ }}),(()=>{var _el$=_$createElement6("text")
696
+ _$setProp5(_el$,"wrapMode","word")
697
+ _$insert5(_el$,()=>error()||"Loading bundled release notes\u2026")
698
+ _$effect5((_$p)=>_$setProp5(_el$,"fg",props.api.theme.current.textMuted,_$p))
353
699
  return _el$
354
- })(),_$createComponent3(Show,{get when(){return configuring()
355
- },get fallback(){return _$createComponent3(OnboardingStep,{get api(){return props.api
356
- },get preferences(){return props.preferences
357
- },get step(){return ONBOARDING_STEPS[step()]
358
- },get final(){return step()===ONBOARDING_STEPS.length-1
359
- },onBack:back,onAdvance:advance
360
- })
361
- },get children(){return _$createComponent3(SectionConfig,{get api(){return props.api
362
- },get preferences(){return props.preferences
363
- },get active(){return active()
364
- },onActive:setActive,onBack:back,onFinish:finish
700
+ })(),_$createComponent6(Show2,{get when(){return error()
701
+ },get children(){return _$createComponent6(DialogAction3,{get api(){return props.api
702
+ },id:"opencode-navigator.changelog.retry",label:"Retry",icon:"retry",selected:true,onSelect:()=>{},onActivate:()=>void load()
365
703
  })
366
704
  }})]
367
705
  }})
706
+ },children:(versions)=>_$createComponent6(Show2,{get when(){return versions().length>0
707
+ },get fallback(){return _$createComponent6(DialogSurface4,{get api(){return props.api
708
+ },lift:true,get children(){return [_$createComponent6(DialogHeader4,{get api(){return props.api
709
+ },title:"Navigator changelog",get onBack(){return dialogs.back
710
+ }}),(()=>{var _el$2=_$createElement6("text")
711
+ _$insertNode4(_el$2,_$createTextNode4(`No release notes are bundled with this installation.`))
712
+ _$effect5((_$p)=>_$setProp5(_el$2,"fg",props.api.theme.current.textMuted,_$p))
713
+ return _el$2
714
+ })()]
715
+ }})
716
+ },get children(){return _$createComponent6(SelectionMenu,{get api(){return props.api
717
+ },title:"Navigator changelog",get options(){return versions().map((entry)=>({title:`Navigator ${entry.version}`,value:entry.version,description:entry.changes.length>0?`${entry.changes.length} changes`:"No user-facing changes"
718
+ }))
719
+ },onSelect:(option)=>{const entry=versions().find((item)=>item.version===option.value)
720
+ if(entry)
721
+ dialogs.open(()=>_$createComponent6(ChangelogVersionDialog,{get api(){return props.api
722
+ },entry
723
+ }))
724
+ }})
725
+ }})
726
+ })
368
727
  }
369
- import {setProp as _$setProp4} from "@opentui/solid"
370
- import {effect as _$effect4} from "@opentui/solid"
371
- import {createTextNode as _$createTextNode4} from "@opentui/solid"
372
- import {insertNode as _$insertNode4} from "@opentui/solid"
373
- import {createElement as _$createElement4} from "@opentui/solid"
728
+ import {getNavigatorAboutServices as getNavigatorAboutServices2} from "./tui.js"
729
+ function selectAboutAction(api,dialogs,value,openBugReport){const service=getNavigatorAboutServices2(api)
730
+ if(!service)
731
+ return
732
+ switch(value){case "about:check":{if(!service.checking()&&!service.updating())
733
+ service.check()
734
+ break
735
+ }
736
+ case "about:update":{if(service.checkState().status==="available"&&!service.updating())
737
+ service.update(dialogs)
738
+ break
739
+ }
740
+ case "about:changelog":{dialogs.open(()=>_$createComponent7(ChangelogVersionsDialog,{api,service
741
+ }))
742
+ break
743
+ }
744
+ case "about:bug-report":{openBugReport()
745
+ break
746
+ }}}
747
+ import {setProp as _$setProp6} from "@opentui/solid"
748
+ import {effect as _$effect6} from "@opentui/solid"
749
+ import {createTextNode as _$createTextNode5} from "@opentui/solid"
750
+ import {insertNode as _$insertNode5} from "@opentui/solid"
751
+ import {createElement as _$createElement7} from "@opentui/solid"
374
752
  function openLimitsRefreshPrompt(api,preferences,dialogs){const scope=preferences.preferenceScopeLabel()
375
- dialogs.prompt({title:"Limits refresh interval",description:()=>(()=>{var _el$=_$createElement4("text")
376
- _$insertNode4(_el$,_$createTextNode4(`Automatic refresh in minutes (minimum 1; default 5). Manual Refresh stays immediate.`))
377
- _$effect4((_$p)=>_$setProp4(_el$,"fg",api.theme.current.textMuted,_$p))
753
+ dialogs.prompt({title:"Limits refresh interval",description:()=>(()=>{var _el$=_$createElement7("text")
754
+ _$insertNode5(_el$,_$createTextNode5(`Automatic refresh in minutes (minimum 1; default 5). Manual Refresh stays immediate.`))
755
+ _$effect6((_$p)=>_$setProp6(_el$,"fg",api.theme.current.textMuted,_$p))
378
756
  return _el$
379
757
  })(),value:String(preferences.selectedLimitsRefreshMinutes()),onConfirm(value){if(preferences.preferenceScopeLabel()!==scope)
380
758
  throw new Error("Preference scope changed; reopen this setting")
@@ -400,9 +778,9 @@ function createSettingsSelection(input){const dialogClosed=()=>("open" in input.
400
778
  function openLimitPrompt(section){const index=input.options().findIndex((option)=>option.value===section)
401
779
  if(index!==-1)
402
780
  input.setActive(index)
403
- input.dialogs.prompt({title:`${SECTION_DEFINITIONS.find((item) => item.name === section).label} item limit`,description:()=>(()=>{var _el$=_$createElement5("text")
404
- _$insertNode5(_el$,_$createTextNode5(`Visible items before Show all. Enter 0 for All.`))
405
- _$effect5((_$p)=>_$setProp5(_el$,"fg",input.api.theme.current.textMuted,_$p))
781
+ input.dialogs.prompt({title:`${SECTION_DEFINITIONS.find((item) => item.name === section).label} item limit`,description:()=>(()=>{var _el$=_$createElement8("text")
782
+ _$insertNode6(_el$,_$createTextNode6(`Visible items before Show all. Enter 0 for All.`))
783
+ _$effect7((_$p)=>_$setProp7(_el$,"fg",input.api.theme.current.textMuted,_$p))
406
784
  return _el$
407
785
  })(),value:String(input.preferences.selectedSectionItemLimit(section)),onConfirm(value){if(!/^\d+$/.test(value.trim()))
408
786
  throw new Error("Enter a non-negative whole number (0 for All)")
@@ -415,9 +793,9 @@ function openShortcut(value){const bindings={toggle_key:{title:"Sidebar shortcut
415
793
  },search_key:{title:"Search Everything shortcut",get:input.preferences.selectedSearchKey,set:input.preferences.setSearchKey
416
794
  }}
417
795
  const binding=bindings[value]
418
- input.dialogs.prompt({title:binding.title,description:()=>(()=>{var _el$3=_$createElement5("text")
419
- _$insertNode5(_el$3,_$createTextNode5(`Use OpenCode key syntax, for example alt+s.`))
420
- _$effect5((_$p)=>_$setProp5(_el$3,"fg",input.api.theme.current.textMuted,_$p))
796
+ input.dialogs.prompt({title:binding.title,description:()=>(()=>{var _el$3=_$createElement8("text")
797
+ _$insertNode6(_el$3,_$createTextNode6(`Use OpenCode key syntax, for example alt+s.`))
798
+ _$effect7((_$p)=>_$setProp7(_el$3,"fg",input.api.theme.current.textMuted,_$p))
421
799
  return _el$3
422
800
  })(),value:binding.get(),onConfirm(key){binding.set(key)
423
801
  input.dialogs.back()
@@ -439,6 +817,11 @@ module.openSettingsImport(input)
439
817
  }
440
818
  function select(value=input.options()[input.active()]?.value){if(!value)
441
819
  return
820
+ if(input.options().find((option)=>option.value===value)?.disabled)
821
+ return
822
+ if(value.startsWith("about:")){selectAboutAction(input.api,input.dialogs,value,input.openBugReport)
823
+ return
824
+ }
442
825
  const index=input.options().findIndex((option)=>option.value===value)
443
826
  if(index!==-1)
444
827
  input.setActive(index)
@@ -520,14 +903,14 @@ import(path).then((module)=>{if(dialogClosed())
520
903
  return
521
904
  const{TrustedSkillsDialog
522
905
  }=module
523
- input.dialogs.open(()=>_$createComponent4(TrustedSkillsDialog,{get api(){return input.api
906
+ input.dialogs.open(()=>_$createComponent8(TrustedSkillsDialog,{get api(){return input.api
524
907
  },get preferences(){return input.preferences
525
908
  }}))
526
909
  }).catch((error)=>input.api.ui.toast({variant:"error",title:"Trusted skills",message:String(error)
527
910
  }))
528
911
  break
529
912
  }
530
- case "wizard":{input.dialogs.open(()=>_$createComponent4(FirstRunWizard,{get api(){return input.api
913
+ case "wizard":{input.dialogs.open(()=>_$createComponent8(FirstRunWizard,{get api(){return input.api
531
914
  },get preferences(){return input.preferences
532
915
  }}))
533
916
  break
@@ -540,7 +923,7 @@ import(path).then((module)=>{if(dialogClosed())
540
923
  return
541
924
  const{QuickActionsDialog
542
925
  }=module
543
- input.dialogs.open(()=>_$createComponent4(QuickActionsDialog,{get api(){return input.api
926
+ input.dialogs.open(()=>_$createComponent8(QuickActionsDialog,{get api(){return input.api
544
927
  },get preferences(){return input.preferences
545
928
  }}))
546
929
  }).catch((error)=>{input.api.ui.toast({variant:"error",title:"Quick actions",message:String(error),duration:4000
@@ -555,7 +938,7 @@ import(path).then((module)=>{if(dialogClosed())
555
938
  return
556
939
  const{McpGroupsDialog
557
940
  }=module
558
- input.dialogs.open(()=>_$createComponent4(McpGroupsDialog,{get api(){return input.api
941
+ input.dialogs.open(()=>_$createComponent8(McpGroupsDialog,{get api(){return input.api
559
942
  },get preferences(){return input.preferences
560
943
  },get mcp(){return input.mcp
561
944
  }}))
@@ -571,7 +954,7 @@ import(path).then((module)=>{if(dialogClosed())
571
954
  return
572
955
  const{SkillGroupsDialog
573
956
  }=module
574
- input.dialogs.open(()=>_$createComponent4(SkillGroupsDialog,{get api(){return input.api
957
+ input.dialogs.open(()=>_$createComponent8(SkillGroupsDialog,{get api(){return input.api
575
958
  },get preferences(){return input.preferences
576
959
  },get skills(){return input.skills
577
960
  }}))
@@ -583,23 +966,26 @@ return{openLimitPrompt,openMcpGroups,openSkillGroups,openQuickActions,select
583
966
  }}
584
967
  function createSettingsDialogController(props){let body
585
968
  const theme=()=>props.api.theme.current
586
- const icons=useIcons4()
587
- const dialogs=useDialogs2(props.api)
588
- const scroll=useDialogScroll()
589
- const dimensions=useTerminalDimensions()
590
- const bodyHeight=createMemo2(()=>Math.max(4,Math.floor(dimensions().height*0.75)-10))
969
+ const icons=useIcons2()
970
+ const dialogs=useDialogs4(props.api)
971
+ const [report,setReport]=useDialogState4("bug-report",undefined)
972
+ const scroll=useDialogScroll2()
973
+ const dimensions=useTerminalDimensions4()
974
+ const bodyHeight=createMemo3(()=>Math.max(4,Math.floor(dimensions().height*0.75)-10))
591
975
  const orderedGroups=createSettingsGroups(props.api,props.preferences,icons)
592
976
  const initialGroup=orderedGroups().find((group)=>group.options.some((option)=>option.value===props.activeValue))
593
- const [activeGroup,setActiveGroup]=useDialogState("tab",initialGroup?.id??orderedGroups()[0].id)
594
- const options=createMemo2(()=>orderedGroups().find((group)=>group.id===activeGroup())?.options??[])
977
+ const [activeGroup,setActiveGroup]=useDialogState4("tab",initialGroup?.id??orderedGroups()[0].id)
978
+ const options=createMemo3(()=>orderedGroups().find((group)=>group.id===activeGroup())?.options??[])
595
979
  const optionId=(value)=>`${PLUGIN_ID}.settings.${value}`
596
980
  const initialActive=options().findIndex((option)=>option.value===props.activeValue)
597
- const [active,setActive]=useDialogState("selection",Math.max(0,initialActive))
598
- createEffect(()=>{if(active()>=options().length)
981
+ const [active,setActive]=useDialogState4("selection",Math.max(0,initialActive))
982
+ useSettingsReveal({body:()=>body,options,active,group:activeGroup,optionId
983
+ })
984
+ createEffect3(()=>{if(active()>=options().length)
599
985
  setActive(Math.max(0,options().length-1))
600
986
  })
601
- const contentHeight=createMemo2(()=>Math.min(bodyHeight(),Math.max(1,options().length*2-1)))
602
- const footerHint=createMemo2(()=>{const common=`${icons.key("tab")} switch \xB7 ${icons.key("up/down")} navigate`
987
+ const contentHeight=createMemo3(()=>Math.min(bodyHeight(),Math.max(1,options().length*2-1 + (activeGroup()==="about"?5:0))))
988
+ const footerHint=createMemo3(()=>{const common=`${icons.key("tab")} switch \xB7 ${icons.key("up/down")} navigate`
603
989
  if(activeGroup()==="sections")
604
990
  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`
605
991
  if(activeGroup()==="presets")
@@ -610,11 +996,6 @@ if(activeGroup()==="defaults")
610
996
  return `${common} \xB7 ${icons.key("enter")} run`
611
997
  return `${common} \xB7 ${icons.key("enter")} select`
612
998
  })
613
- onMount(()=>{queueMicrotask(()=>{const option=options()[active()]
614
- if(option)
615
- body?.scrollChildIntoView(optionId(option.value))
616
- })
617
- })
618
999
  function move(offset){const next=(active() + offset + options().length)%options().length
619
1000
  setActive(next)
620
1001
  const option=options()[next]
@@ -653,101 +1034,195 @@ actions.prompt()
653
1034
  }).catch((error)=>props.api.ui.toast({variant:"error",title:"Layout presets",message:String(error)
654
1035
  }))
655
1036
  }
656
- 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")
657
- })
1037
+ 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"),openBugReport(){let controller=report()
1038
+ if(!controller){const service=getNavigatorAboutServices3(props.api)
1039
+ if(!service)
1040
+ return
1041
+ controller=createBugReportController({navigatorVersion:service.navigatorVersion,openCodeVersion:service.openCodeVersion,platform:process.platform,runtime:`Bun ${Bun.version}`
1042
+ },service.bugReportTransport,props.api.lifecycle.signal)
1043
+ setReport(controller)
1044
+ }
1045
+ const selected=controller
1046
+ dialogs.open(()=>_$createComponent9(BugReportDialog,{get api(){return props.api
1047
+ },controller:selected
1048
+ }))
1049
+ }})
658
1050
  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
659
1051
  })
660
- onCleanup2(unregister)
1052
+ onCleanup6(unregister)
661
1053
  return{active,activeGroup,contentHeight,dialogs,footerHint,icons,openLimitPrompt:selection.openLimitPrompt,openQuickActions:selection.openQuickActions,openMcpGroups:selection.openMcpGroups,openSkillGroups:selection.openSkillGroups,options,optionId,orderedGroups,reorder,select:selection.select,setActive,setActiveGroup,setBody(node){body=node
662
1054
  scroll.ref(node)
663
1055
  },restoreScroll:scroll.restore,saveScroll:scroll.save,theme
664
1056
  }}
665
- import {createComponent as _$createComponent5} from "@opentui/solid"
666
- import {createTextNode as _$createTextNode6} from "@opentui/solid"
667
- import {insertNode as _$insertNode6} from "@opentui/solid"
668
- import {effect as _$effect6} from "@opentui/solid"
669
- import {insert as _$insert4} from "@opentui/solid"
670
- import {setProp as _$setProp6} from "@opentui/solid"
671
- import {createElement as _$createElement6} from "@opentui/solid"
1057
+ import {effect as _$effect8} from "@opentui/solid"
1058
+ import {createComponent as _$createComponent10} from "@opentui/solid"
1059
+ import {insert as _$insert6} from "@opentui/solid"
1060
+ import {createTextNode as _$createTextNode7} from "@opentui/solid"
1061
+ import {insertNode as _$insertNode7} from "@opentui/solid"
1062
+ import {memo as _$memo2} from "@opentui/solid"
1063
+ import {setProp as _$setProp8} from "@opentui/solid"
1064
+ import {createElement as _$createElement9} from "@opentui/solid"
1065
+ import {TextAttributes} from "@opentui/core"
1066
+ import {Show as Show3} from "solid-js"
1067
+ import {getNavigatorAboutServices as getNavigatorAboutServices4} from "./tui.js"
1068
+ function AboutVersionStatus(props){const service=()=>getNavigatorAboutServices4(props.api)
1069
+ const status=()=>{const state=service()?.checkState()
1070
+ if(!state)
1071
+ return "Version information is loading\u2026"
1072
+ switch(state.status){case "checking":{return "Checking for Navigator updates\u2026"
1073
+ }
1074
+ case "current":{return "Navigator is up to date."
1075
+ }
1076
+ case "available":{return `Navigator ${state.latest} is available.`
1077
+ }
1078
+ case "error":{return "Could not check updates. Check again to retry."
1079
+ }
1080
+ case "idle":{return "Updates have not been checked yet."
1081
+ }}}
1082
+ return(()=>{var _el$=_$createElement9("box"),_el$2=_$createElement9("text"),_el$3=_$createTextNode7(`Navigator `),_el$4=_$createElement9("text"),_el$5=_$createTextNode7(`OpenCode `),_el$6=_$createElement9("text"),_el$7=_$createElement9("text")
1083
+ _$insertNode7(_el$,_el$2)
1084
+ _$insertNode7(_el$,_el$4)
1085
+ _$insertNode7(_el$,_el$6)
1086
+ _$insertNode7(_el$,_el$7)
1087
+ _$setProp8(_el$,"width","100%")
1088
+ _$setProp8(_el$,"minWidth",0)
1089
+ _$setProp8(_el$,"gap",0)
1090
+ _$insertNode7(_el$2,_el$3)
1091
+ _$setProp8(_el$2,"height",1)
1092
+ _$setProp8(_el$2,"truncate",true)
1093
+ _$setProp8(_el$2,"wrapMode","none")
1094
+ _$insert6(_el$2,()=>service()?.navigatorVersion??"version unavailable",null)
1095
+ _$insertNode7(_el$4,_el$5)
1096
+ _$setProp8(_el$4,"height",1)
1097
+ _$setProp8(_el$4,"truncate",true)
1098
+ _$setProp8(_el$4,"wrapMode","none")
1099
+ _$insert6(_el$4,()=>service()?.openCodeVersion??props.api.app?.version??"version unavailable",null)
1100
+ _$setProp8(_el$6,"height",1)
1101
+ _$setProp8(_el$6,"truncate",true)
1102
+ _$setProp8(_el$6,"wrapMode","none")
1103
+ _$insert6(_el$6,(()=>{var _c$=_$memo2(()=>!!service()?.updating())
1104
+ return()=>_c$()?"Installing Navigator. Restart OpenCode after completion.":status()
1105
+ })())
1106
+ _$setProp8(_el$7,"height",1)
1107
+ _$setProp8(_el$7,"truncate",true)
1108
+ _$setProp8(_el$7,"wrapMode","none")
1109
+ _$insert6(_el$7,(()=>{var _c$2=_$memo2(()=>!!service()?.checkState().checkedAt)
1110
+ return()=>_c$2()?`Last check: ${new Date(service().checkState().checkedAt).toLocaleTimeString()}`:"Check manually when needed."
1111
+ })())
1112
+ _$insert6(_el$,_$createComponent10(Show3,{get when(){return service()?.installed?.()
1113
+ },children:(version)=>(()=>{var _el$8=_$createElement9("text"),_el$9=_$createTextNode7(`Restart OpenCode to use Navigator `),_el$0=_$createTextNode7(`.`)
1114
+ _$insertNode7(_el$8,_el$9)
1115
+ _$insertNode7(_el$8,_el$0)
1116
+ _$setProp8(_el$8,"height",1)
1117
+ _$setProp8(_el$8,"truncate",true)
1118
+ _$setProp8(_el$8,"wrapMode","none")
1119
+ _$insert6(_el$8,version,_el$0)
1120
+ _$effect8((_$p)=>_$setProp8(_el$8,"fg",props.api.theme.current.textMuted,_$p))
1121
+ return _el$8
1122
+ })()
1123
+ }),null)
1124
+ _$effect8((_p$)=>{var _v$=TextAttributes.BOLD,_v$2=props.api.theme.current.text,_v$3=props.api.theme.current.textMuted,_v$4=service()?.checkState().status==="error"?props.api.theme.current.warning:props.api.theme.current.textMuted,_v$5=props.api.theme.current.textMuted
1125
+ _v$!==_p$.e&&(_p$.e=_$setProp8(_el$2,"attributes",_v$,_p$.e))
1126
+ _v$2!==_p$.t&&(_p$.t=_$setProp8(_el$2,"fg",_v$2,_p$.t))
1127
+ _v$3!==_p$.a&&(_p$.a=_$setProp8(_el$4,"fg",_v$3,_p$.a))
1128
+ _v$4!==_p$.o&&(_p$.o=_$setProp8(_el$6,"fg",_v$4,_p$.o))
1129
+ _v$5!==_p$.i&&(_p$.i=_$setProp8(_el$7,"fg",_v$5,_p$.i))
1130
+ return _p$
1131
+ },{e:undefined,t:undefined,a:undefined,o:undefined,i:undefined
1132
+ })
1133
+ return _el$
1134
+ })()
1135
+ }
1136
+ import {createComponent as _$createComponent11} from "@opentui/solid"
1137
+ import {createTextNode as _$createTextNode8} from "@opentui/solid"
1138
+ import {insertNode as _$insertNode8} from "@opentui/solid"
1139
+ import {effect as _$effect9} from "@opentui/solid"
1140
+ import {insert as _$insert7} from "@opentui/solid"
1141
+ import {setProp as _$setProp9} from "@opentui/solid"
1142
+ import {createElement as _$createElement10} from "@opentui/solid"
672
1143
  import {memo as _$memo3} from "@opentui/solid"
673
- import {TextAttributes as TextAttributes4} from "@opentui/core"
674
- import {Show as Show2} from "solid-js"
675
- import {SelectionBox as SelectionBox3} from "./tui.js"
1144
+ import {TextAttributes as TextAttributes2} from "@opentui/core"
1145
+ import {Show as Show4} from "solid-js"
1146
+ import {SelectionBox} from "./tui.js"
676
1147
  function SettingsOptionRow(props){const model=props.controller
677
1148
  const index=()=>model.options().findIndex((candidate)=>candidate.value===props.option.value)
678
1149
  const selected=()=>model.active()===index()
679
1150
  const section=()=>props.option.value
680
- return _$createComponent5(SelectionBox3,{get id(){return model.optionId(props.option.value)
1151
+ return _$createComponent11(SelectionBox,{get id(){return model.optionId(props.option.value)
681
1152
  },flexDirection:"row",gap:2,paddingLeft:1,paddingRight:1,get backgroundColor(){return _$memo3(()=>!!selected())()?model.theme().backgroundElement:undefined
682
1153
  },onMouseOver:()=>model.setActive(index()),onMouseDown:(event)=>event.stopPropagation(),onMouseUp:(event)=>{event.stopPropagation()
1154
+ if(!props.option.disabled)
683
1155
  model.select(props.option.value)
684
- },get children(){return [(()=>{var _el$=_$createElement6("text")
685
- _$setProp6(_el$,"flexShrink",0)
686
- _$insert4(_el$,()=>props.option.title)
687
- _$effect6((_p$)=>{var _v$=selected()?TextAttributes4.BOLD:undefined,_v$2=model.theme().text
688
- _v$!==_p$.e&&(_p$.e=_$setProp6(_el$,"attributes",_v$,_p$.e))
689
- _v$2!==_p$.t&&(_p$.t=_$setProp6(_el$,"fg",_v$2,_p$.t))
1156
+ },get children(){return [(()=>{var _el$=_$createElement10("text")
1157
+ _$setProp9(_el$,"flexShrink",0)
1158
+ _$insert7(_el$,()=>props.option.title)
1159
+ _$effect9((_p$)=>{var _v$=selected()?TextAttributes2.BOLD:undefined,_v$2=props.option.disabled?model.theme().textMuted:model.theme().text
1160
+ _v$!==_p$.e&&(_p$.e=_$setProp9(_el$,"attributes",_v$,_p$.e))
1161
+ _v$2!==_p$.t&&(_p$.t=_$setProp9(_el$,"fg",_v$2,_p$.t))
690
1162
  return _p$
691
1163
  },{e:undefined,t:undefined
692
1164
  })
693
1165
  return _el$
694
- })(),(()=>{var _el$2=_$createElement6("text")
695
- _$setProp6(_el$2,"flexGrow",1)
696
- _$insert4(_el$2,()=>props.option.description)
697
- _$effect6((_$p)=>_$setProp6(_el$2,"fg",model.theme().borderSubtle,_$p))
1166
+ })(),(()=>{var _el$2=_$createElement10("text")
1167
+ _$setProp9(_el$2,"flexGrow",1)
1168
+ _$setProp9(_el$2,"minWidth",0)
1169
+ _$setProp9(_el$2,"truncate",true)
1170
+ _$setProp9(_el$2,"wrapMode","none")
1171
+ _$insert7(_el$2,()=>props.option.description)
1172
+ _$effect9((_$p)=>_$setProp9(_el$2,"fg",model.theme().borderSubtle,_$p))
698
1173
  return _el$2
699
- })(),_$createComponent5(Show2,{get when(){return SIDEBAR_SECTIONS.includes(section())
700
- },get children(){var _el$3=_$createElement6("box"),_el$8=_$createElement6("text"),_el$9=_$createTextNode6(` Items: `),_el$0=_$createElement6("text"),_el$1=_$createElement6("text")
701
- _$insertNode6(_el$3,_el$8)
702
- _$insertNode6(_el$3,_el$0)
703
- _$insertNode6(_el$3,_el$1)
704
- _$setProp6(_el$3,"flexDirection","row")
705
- _$setProp6(_el$3,"flexShrink",0)
706
- _$setProp6(_el$3,"gap",1)
707
- _$insert4(_el$3,_$createComponent5(Show2,{get when(){return props.option.value==="quick_actions"
708
- },get children(){var _el$4=_$createElement6("text"),_el$5=_$createTextNode6(` Actions`)
709
- _$insertNode6(_el$4,_el$5)
710
- _$setProp6(_el$4,"onMouseDown",(event)=>event.stopPropagation())
711
- _$setProp6(_el$4,"onMouseUp",(event)=>{event.stopPropagation()
1174
+ })(),_$createComponent11(Show4,{get when(){return SIDEBAR_SECTIONS.includes(section())
1175
+ },get children(){var _el$3=_$createElement10("box"),_el$8=_$createElement10("text"),_el$9=_$createTextNode8(` Items: `),_el$0=_$createElement10("text"),_el$1=_$createElement10("text")
1176
+ _$insertNode8(_el$3,_el$8)
1177
+ _$insertNode8(_el$3,_el$0)
1178
+ _$insertNode8(_el$3,_el$1)
1179
+ _$setProp9(_el$3,"flexDirection","row")
1180
+ _$setProp9(_el$3,"flexShrink",0)
1181
+ _$setProp9(_el$3,"gap",1)
1182
+ _$insert7(_el$3,_$createComponent11(Show4,{get when(){return props.option.value==="quick_actions"
1183
+ },get children(){var _el$4=_$createElement10("text"),_el$5=_$createTextNode8(` Actions`)
1184
+ _$insertNode8(_el$4,_el$5)
1185
+ _$setProp9(_el$4,"onMouseDown",(event)=>event.stopPropagation())
1186
+ _$setProp9(_el$4,"onMouseUp",(event)=>{event.stopPropagation()
712
1187
  model.openQuickActions()
713
1188
  })
714
- _$insert4(_el$4,()=>model.icons.icon("actions"),_el$5)
715
- _$effect6((_$p)=>_$setProp6(_el$4,"fg",model.theme().accent,_$p))
1189
+ _$insert7(_el$4,()=>model.icons.icon("actions"),_el$5)
1190
+ _$effect9((_$p)=>_$setProp9(_el$4,"fg",model.theme().accent,_$p))
716
1191
  return _el$4
717
1192
  }}),_el$8)
718
- _$insert4(_el$3,_$createComponent5(Show2,{get when(){return props.option.value==="mcp"||props.option.value==="skills"
719
- },get children(){var _el$6=_$createElement6("text"),_el$7=_$createTextNode6(` Groups`)
720
- _$insertNode6(_el$6,_el$7)
721
- _$setProp6(_el$6,"onMouseDown",(event)=>event.stopPropagation())
722
- _$setProp6(_el$6,"onMouseUp",(event)=>{event.stopPropagation()
1193
+ _$insert7(_el$3,_$createComponent11(Show4,{get when(){return props.option.value==="mcp"||props.option.value==="skills"
1194
+ },get children(){var _el$6=_$createElement10("text"),_el$7=_$createTextNode8(` Groups`)
1195
+ _$insertNode8(_el$6,_el$7)
1196
+ _$setProp9(_el$6,"onMouseDown",(event)=>event.stopPropagation())
1197
+ _$setProp9(_el$6,"onMouseUp",(event)=>{event.stopPropagation()
723
1198
  if(props.option.value==="skills")
724
1199
  model.openSkillGroups()
725
1200
  else
726
1201
  model.openMcpGroups()
727
1202
  })
728
- _$insert4(_el$6,()=>model.icons.icon("sections"),_el$7)
729
- _$effect6((_$p)=>_$setProp6(_el$6,"fg",model.theme().accent,_$p))
1203
+ _$insert7(_el$6,()=>model.icons.icon("sections"),_el$7)
1204
+ _$effect9((_$p)=>_$setProp9(_el$6,"fg",model.theme().accent,_$p))
730
1205
  return _el$6
731
1206
  }}),_el$8)
732
- _$insertNode6(_el$8,_el$9)
733
- _$setProp6(_el$8,"onMouseDown",(event)=>event.stopPropagation())
734
- _$setProp6(_el$8,"onMouseUp",(event)=>{event.stopPropagation()
1207
+ _$insertNode8(_el$8,_el$9)
1208
+ _$setProp9(_el$8,"onMouseDown",(event)=>event.stopPropagation())
1209
+ _$setProp9(_el$8,"onMouseUp",(event)=>{event.stopPropagation()
735
1210
  model.openLimitPrompt(section())
736
1211
  })
737
- _$insert4(_el$8,()=>model.icons.icon("todo"),_el$9)
738
- _$insert4(_el$8,()=>props.preferences.selectedSectionItemLimit?.(section())||"All",null)
739
- _$setProp6(_el$0,"onMouseDown",(event)=>{event.stopPropagation()
1212
+ _$insert7(_el$8,()=>model.icons.icon("todo"),_el$9)
1213
+ _$insert7(_el$8,()=>props.preferences.selectedSectionItemLimit?.(section())||"All",null)
1214
+ _$setProp9(_el$0,"onMouseDown",(event)=>{event.stopPropagation()
740
1215
  model.reorder(props.option.value,-1)
741
1216
  })
742
- _$insert4(_el$0,()=>model.icons.icon("up"))
743
- _$setProp6(_el$1,"onMouseDown",(event)=>{event.stopPropagation()
1217
+ _$insert7(_el$0,()=>model.icons.icon("up"))
1218
+ _$setProp9(_el$1,"onMouseDown",(event)=>{event.stopPropagation()
744
1219
  model.reorder(props.option.value,1)
745
1220
  })
746
- _$insert4(_el$1,()=>model.icons.icon("down"))
747
- _$effect6((_p$)=>{var _v$3=model.theme().accent,_v$4=model.theme().accent,_v$5=model.theme().accent
748
- _v$3!==_p$.e&&(_p$.e=_$setProp6(_el$8,"fg",_v$3,_p$.e))
749
- _v$4!==_p$.t&&(_p$.t=_$setProp6(_el$0,"fg",_v$4,_p$.t))
750
- _v$5!==_p$.a&&(_p$.a=_$setProp6(_el$1,"fg",_v$5,_p$.a))
1221
+ _$insert7(_el$1,()=>model.icons.icon("down"))
1222
+ _$effect9((_p$)=>{var _v$3=model.theme().accent,_v$4=model.theme().accent,_v$5=model.theme().accent
1223
+ _v$3!==_p$.e&&(_p$.e=_$setProp9(_el$8,"fg",_v$3,_p$.e))
1224
+ _v$4!==_p$.t&&(_p$.t=_$setProp9(_el$0,"fg",_v$4,_p$.t))
1225
+ _v$5!==_p$.a&&(_p$.a=_$setProp9(_el$1,"fg",_v$5,_p$.a))
751
1226
  return _p$
752
1227
  },{e:undefined,t:undefined,a:undefined
753
1228
  })
@@ -756,65 +1231,71 @@ return _el$3
756
1231
  }})
757
1232
  }
758
1233
  function SettingsDialog(props){const model=createSettingsDialogController(props)
759
- return _$createComponent6(DialogSurface2,{get api(){return props.api
760
- },get children(){return [(()=>{var _el$=_$createElement7("box"),_el$2=_$createElement7("text"),_el$3=_$createTextNode7(` Navigator settings`),_el$4=_$createElement7("text")
761
- _$insertNode7(_el$,_el$2)
762
- _$insertNode7(_el$,_el$4)
763
- _$setProp7(_el$,"flexDirection","row")
764
- _$setProp7(_el$,"justifyContent","space-between")
765
- _$insertNode7(_el$2,_el$3)
766
- _$insert5(_el$2,()=>model.icons.icon("settings"),_el$3)
767
- _$setProp7(_el$4,"onMouseDown",(event)=>event.stopPropagation())
768
- _$setProp7(_el$4,"onMouseUp",(event)=>{event.stopPropagation()
1234
+ return _$createComponent12(DialogSurface5,{get api(){return props.api
1235
+ },get children(){return [(()=>{var _el$=_$createElement11("box"),_el$2=_$createElement11("text"),_el$3=_$createTextNode9(` Navigator settings`),_el$4=_$createElement11("text")
1236
+ _$insertNode9(_el$,_el$2)
1237
+ _$insertNode9(_el$,_el$4)
1238
+ _$setProp10(_el$,"flexDirection","row")
1239
+ _$setProp10(_el$,"justifyContent","space-between")
1240
+ _$insertNode9(_el$2,_el$3)
1241
+ _$insert8(_el$2,()=>model.icons.icon("settings"),_el$3)
1242
+ _$setProp10(_el$4,"onMouseDown",(event)=>event.stopPropagation())
1243
+ _$setProp10(_el$4,"onMouseUp",(event)=>{event.stopPropagation()
769
1244
  model.dialogs.back()
770
1245
  })
771
- _$insert5(_el$4,()=>model.icons.key("esc"))
772
- _$effect7((_p$)=>{var _v$=TextAttributes5.BOLD,_v$2=model.theme().text,_v$3=model.theme().textMuted
773
- _v$!==_p$.e&&(_p$.e=_$setProp7(_el$2,"attributes",_v$,_p$.e))
774
- _v$2!==_p$.t&&(_p$.t=_$setProp7(_el$2,"fg",_v$2,_p$.t))
775
- _v$3!==_p$.a&&(_p$.a=_$setProp7(_el$4,"fg",_v$3,_p$.a))
1246
+ _$insert8(_el$4,()=>model.icons.key("esc"))
1247
+ _$effect10((_p$)=>{var _v$=TextAttributes3.BOLD,_v$2=model.theme().text,_v$3=model.theme().textMuted
1248
+ _v$!==_p$.e&&(_p$.e=_$setProp10(_el$2,"attributes",_v$,_p$.e))
1249
+ _v$2!==_p$.t&&(_p$.t=_$setProp10(_el$2,"fg",_v$2,_p$.t))
1250
+ _v$3!==_p$.a&&(_p$.a=_$setProp10(_el$4,"fg",_v$3,_p$.a))
776
1251
  return _p$
777
1252
  },{e:undefined,t:undefined,a:undefined
778
1253
  })
779
1254
  return _el$
780
- })(),(()=>{var _el$5=_$createElement7("text")
781
- _$insertNode7(_el$5,_$createTextNode7(`Adjust sections and behavior. Changes apply immediately.`))
782
- _$effect7((_$p)=>_$setProp7(_el$5,"fg",model.theme().textMuted,_$p))
1255
+ })(),(()=>{var _el$5=_$createElement11("text")
1256
+ _$insert8(_el$5,()=>model.activeGroup()==="about"?"Version, updates, release history, and support.":"Adjust sections and behavior. Changes apply immediately.")
1257
+ _$effect10((_$p)=>_$setProp10(_el$5,"fg",model.theme().textMuted,_$p))
783
1258
  return _el$5
784
- })(),(()=>{var _el$7=_$createElement7("box")
785
- _$setProp7(_el$7,"flexDirection","row")
786
- _$setProp7(_el$7,"gap",1)
787
- _$insert5(_el$7,_$createComponent6(For3,{get each(){return model.orderedGroups()
788
- },children:(group)=>_$createComponent6(Tab,{get api(){return props.api
789
- },get selected(){return model.activeGroup()===group.id
790
- },paddingLeft:1,paddingRight:1,onMouseDown:()=>{model.setActiveGroup(group.id)
1259
+ })(),(()=>{var _el$6=_$createElement11("box")
1260
+ _$setProp10(_el$6,"flexDirection","row")
1261
+ _$setProp10(_el$6,"flexWrap","wrap")
1262
+ _$setProp10(_el$6,"columnGap",1)
1263
+ _$setProp10(_el$6,"rowGap",0)
1264
+ _$insert8(_el$6,_$createComponent12(For3,{get each(){return model.orderedGroups().map((group)=>group.id)
1265
+ },children:(id)=>_$createComponent12(Tab,{get api(){return props.api
1266
+ },get selected(){return model.activeGroup()===id
1267
+ },paddingLeft:1,paddingRight:1,onMouseDown:()=>{model.setActiveGroup(id)
791
1268
  model.setActive(0)
792
- },get children(){return [_$memo4(()=>model.icons.tab(group.id))," ",_$memo4(()=>group.tab)]
1269
+ },get children(){return [_$memo4(()=>model.icons.tab(id))," ",_$memo4(()=>model.orderedGroups().find((group)=>group.id===id)?.tab)]
793
1270
  }})
794
1271
  }))
795
- return _el$7
796
- })(),(()=>{var _el$8=_$createElement7("scrollbox"),_el$9=_$createElement7("box")
797
- _$insertNode7(_el$8,_el$9)
1272
+ return _el$6
1273
+ })(),(()=>{var _el$7=_$createElement11("scrollbox"),_el$8=_$createElement11("box")
1274
+ _$insertNode9(_el$7,_el$8)
798
1275
  var _ref$=model.setBody
799
- typeof _ref$==="function"?_$use(_ref$,_el$8):model.setBody=_el$8
800
- _$setProp7(_el$8,"id",`${PLUGIN_ID}.settings.body`)
801
- _$setProp7(_el$8,"scrollX",false)
802
- _$setProp7(_el$8,"verticalScrollbarOptions",{visible:true
1276
+ typeof _ref$==="function"?_$use5(_ref$,_el$7):model.setBody=_el$7
1277
+ _$setProp10(_el$7,"id",`${PLUGIN_ID}.settings.body`)
1278
+ _$setProp10(_el$7,"scrollX",false)
1279
+ _$setProp10(_el$7,"verticalScrollbarOptions",{visible:true
803
1280
  })
804
- _$setProp7(_el$8,"horizontalScrollbarOptions",{visible:false
1281
+ _$setProp10(_el$7,"horizontalScrollbarOptions",{visible:false
805
1282
  })
806
- _$setProp7(_el$9,"gap",1)
807
- _$insert5(_el$9,_$createComponent6(For3,{get each(){return model.options()
808
- },children:(option)=>_$createComponent6(SettingsOptionRow,{get preferences(){return props.preferences
809
- },controller:model,option
810
- })
811
- }))
812
- _$effect7((_$p)=>_$setProp7(_el$8,"height",model.contentHeight(),_$p))
813
- return _el$8
814
- })(),(()=>{var _el$0=_$createElement7("text")
815
- _$insert5(_el$0,()=>model.footerHint())
816
- _$effect7((_$p)=>_$setProp7(_el$0,"fg",model.theme().textMuted,_$p))
817
- return _el$0
1283
+ _$setProp10(_el$8,"gap",1)
1284
+ _$insert8(_el$8,_$createComponent12(Show5,{get when(){return model.activeGroup()==="about"
1285
+ },get children(){return _$createComponent12(AboutVersionStatus,{get api(){return props.api
1286
+ }})
1287
+ }}),null)
1288
+ _$insert8(_el$8,_$createComponent12(For3,{get each(){return model.options().map((option)=>option.value)
1289
+ },children:(value)=>_$createComponent12(SettingsOptionRow,{get preferences(){return props.preferences
1290
+ },controller:model,get option(){return model.options().find((option)=>option.value===value)
1291
+ }})
1292
+ }),null)
1293
+ _$effect10((_$p)=>_$setProp10(_el$7,"height",model.contentHeight(),_$p))
1294
+ return _el$7
1295
+ })(),(()=>{var _el$9=_$createElement11("text")
1296
+ _$insert8(_el$9,()=>model.footerHint())
1297
+ _$effect10((_$p)=>_$setProp10(_el$9,"fg",model.theme().textMuted,_$p))
1298
+ return _el$9
818
1299
  })()]
819
1300
  }})
820
1301
  }