opencode-navigator 0.21.7 → 0.22.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,5 +1,5 @@
1
1
  import {PLUGIN_ID
2
- } from "./chunk-d1bws32s.js";
2
+ } from "./chunk-dz8cfnfs.js";
3
3
  function createCodexAppServerClient(input){const command=input.command??["codex","app-server","--stdio"]
4
4
  const timeoutMs=input.timeoutMs??1e4
5
5
  const pending=new Map
@@ -365,7 +365,7 @@ import {insert as _$insert} from "@opentui/solid"
365
365
  import {setProp as _$setProp} from "@opentui/solid"
366
366
  import {createElement as _$createElement} from "@opentui/solid"
367
367
  import {createSignal as createSignal4} from "solid-js"
368
- import {useIcons} from "./tui.js"
368
+ import {subtleLineColor,useIcons} from "./tui.js"
369
369
  function measurement(window,remaining){if(remaining!==undefined)
370
370
  return `${remaining}${window.unit === "%" ? "" : " "}${window.unit} left`
371
371
  if(window.used!==undefined)
@@ -389,18 +389,20 @@ const [columns,setColumns]=createSignal4(0)
389
389
  const view=()=>quotaPresentation(props.window)
390
390
  const scale=()=>{const ratio=view().ratio
391
391
  if(ratio===undefined)
392
- return "Scale unknown"
392
+ return{filled:"Scale unknown",unfilled:""
393
+ }
393
394
  const width=columns()
394
395
  const filled=Math.round(ratio*width)
395
396
  const symbols=icons.style()==="text"?["=","-"]:["\u2501","\u2500"]
396
- return symbols[0].repeat(filled) + symbols[1].repeat(width-filled)
397
- }
397
+ return{filled:symbols[0].repeat(filled),unfilled:symbols[1].repeat(width-filled)
398
+ }}
399
+ const unfilledColor=()=>subtleLineColor(props.api.theme.current.backgroundPanel,props.api.theme.current.borderSubtle)
398
400
  const valueWidth=()=>Math.min(columns(),Bun.stringWidth(view().value))
399
401
  const gap=()=>columns()>valueWidth()?1:0
400
402
  const resetWidth=()=>Math.max(0,columns()-valueWidth()-gap())
401
- return(()=>{var _el$=_$createElement("box"),_el$2=_$createElement("text"),_el$3=_$createElement("box"),_el$4=_$createElement("text"),_el$5=_$createElement("text")
403
+ return(()=>{var _el$=_$createElement("box"),_el$2=_$createElement("text"),_el$3=_$createElement("span"),_el$4=_$createElement("box"),_el$5=_$createElement("text"),_el$6=_$createElement("text")
402
404
  _$insertNode(_el$,_el$2)
403
- _$insertNode(_el$,_el$3)
405
+ _$insertNode(_el$,_el$4)
404
406
  _$setProp(_el$,"width","100%")
405
407
  _$setProp(_el$,"minWidth",0)
406
408
  _$setProp(_el$,"flexShrink",1)
@@ -408,37 +410,41 @@ _$setProp(_el$,"height",2)
408
410
  _$setProp(_el$,"overflow","hidden")
409
411
  _$setProp(_el$,"onSizeChange",function(){setColumns(this.width)
410
412
  })
413
+ _$insertNode(_el$2,_el$3)
411
414
  _$setProp(_el$2,"width","100%")
412
415
  _$setProp(_el$2,"minWidth",0)
413
416
  _$setProp(_el$2,"height",1)
414
417
  _$setProp(_el$2,"wrapMode","none")
415
418
  _$setProp(_el$2,"truncate",true)
416
- _$insert(_el$2,scale)
417
- _$insertNode(_el$3,_el$4)
418
- _$insertNode(_el$3,_el$5)
419
- _$setProp(_el$3,"width","100%")
420
- _$setProp(_el$3,"minWidth",0)
421
- _$setProp(_el$3,"height",1)
422
- _$setProp(_el$3,"flexDirection","row")
423
- _$setProp(_el$3,"overflow","hidden")
419
+ _$insert(_el$2,()=>scale().filled,_el$3)
420
+ _$insert(_el$3,()=>scale().unfilled)
421
+ _$insertNode(_el$4,_el$5)
422
+ _$insertNode(_el$4,_el$6)
423
+ _$setProp(_el$4,"width","100%")
424
424
  _$setProp(_el$4,"minWidth",0)
425
425
  _$setProp(_el$4,"height",1)
426
- _$setProp(_el$4,"wrapMode","none")
427
- _$setProp(_el$4,"truncate",true)
428
- _$insert(_el$4,()=>view().reset)
426
+ _$setProp(_el$4,"flexDirection","row")
427
+ _$setProp(_el$4,"overflow","hidden")
428
+ _$setProp(_el$5,"minWidth",0)
429
429
  _$setProp(_el$5,"height",1)
430
430
  _$setProp(_el$5,"wrapMode","none")
431
431
  _$setProp(_el$5,"truncate",true)
432
- _$insert(_el$5,()=>view().value)
433
- _$effect((_p$)=>{var _v$=props.api.theme.current.textMuted,_v$2=resetWidth(),_v$3=props.api.theme.current.textMuted,_v$4=valueWidth(),_v$5=gap(),_v$6=props.api.theme.current.text
432
+ _$insert(_el$5,()=>view().reset)
433
+ _$setProp(_el$6,"height",1)
434
+ _$setProp(_el$6,"wrapMode","none")
435
+ _$setProp(_el$6,"truncate",true)
436
+ _$insert(_el$6,()=>view().value)
437
+ _$effect((_p$)=>{var _v$=props.api.theme.current.textMuted,_v$2={fg:unfilledColor()
438
+ },_v$3=resetWidth(),_v$4=props.api.theme.current.textMuted,_v$5=valueWidth(),_v$6=gap(),_v$7=props.api.theme.current.text
434
439
  _v$!==_p$.e&&(_p$.e=_$setProp(_el$2,"fg",_v$,_p$.e))
435
- _v$2!==_p$.t&&(_p$.t=_$setProp(_el$4,"width",_v$2,_p$.t))
436
- _v$3!==_p$.a&&(_p$.a=_$setProp(_el$4,"fg",_v$3,_p$.a))
437
- _v$4!==_p$.o&&(_p$.o=_$setProp(_el$5,"width",_v$4,_p$.o))
438
- _v$5!==_p$.i&&(_p$.i=_$setProp(_el$5,"marginLeft",_v$5,_p$.i))
439
- _v$6!==_p$.n&&(_p$.n=_$setProp(_el$5,"fg",_v$6,_p$.n))
440
+ _v$2!==_p$.t&&(_p$.t=_$setProp(_el$3,"style",_v$2,_p$.t))
441
+ _v$3!==_p$.a&&(_p$.a=_$setProp(_el$5,"width",_v$3,_p$.a))
442
+ _v$4!==_p$.o&&(_p$.o=_$setProp(_el$5,"fg",_v$4,_p$.o))
443
+ _v$5!==_p$.i&&(_p$.i=_$setProp(_el$6,"width",_v$5,_p$.i))
444
+ _v$6!==_p$.n&&(_p$.n=_$setProp(_el$6,"marginLeft",_v$6,_p$.n))
445
+ _v$7!==_p$.s&&(_p$.s=_$setProp(_el$6,"fg",_v$7,_p$.s))
440
446
  return _p$
441
- },{e:undefined,t:undefined,a:undefined,o:undefined,i:undefined,n:undefined
447
+ },{e:undefined,t:undefined,a:undefined,o:undefined,i:undefined,n:undefined,s:undefined
442
448
  })
443
449
  return _el$
444
450
  })()
@@ -1023,6 +1029,8 @@ if(active.length!==1)
1023
1029
  return{status:"unavailable"}
1024
1030
  const credential=active[0]
1025
1031
  const id=`credential:${credential.id}`
1032
+ if(credential.value.type==="external")
1033
+ return{status:"unsupported",id}
1026
1034
  const providerID=provider.canonical??provider.id
1027
1035
  if(credential.value.type==="key")
1028
1036
  return{status:"ready",id,method:"api",providerID}
@@ -1,5 +1,5 @@
1
- import {QUICK_ACTION_IDS,PLUGIN_ID
2
- } from "./chunk-d1bws32s.js";
1
+ import {PLUGIN_ID
2
+ } from "./chunk-dz8cfnfs.js";
3
3
  import {memo as _$memo} from "@opentui/solid"
4
4
  import {createComponent as _$createComponent} from "@opentui/solid"
5
5
  import {use as _$use} from "@opentui/solid"
@@ -11,16 +11,8 @@ import {setProp as _$setProp} from "@opentui/solid"
11
11
  import {createElement as _$createElement} from "@opentui/solid"
12
12
  import {TextAttributes} from "@opentui/core"
13
13
  import {useTerminalDimensions} from "@opentui/solid"
14
- import {For,createEffect,createMemo,onCleanup as onCleanup2} from "solid-js"
15
- import {createSignal,onCleanup} from "solid-js"
16
- var QUICK_ACTION_METADATA=[["\uEA73","Rename"],["\uEA82","Timeline"],["\uEBCC","Copy transcript"],["\uEBAC","Export"],["\uEAF5","Compact"],["\uEBEB","Switch session"],["\uEA60","New session"],["\uEB9E","Fork session"],["\uEBCC","Copy last response"],["\uEAA1","First message"],["\uEA9A","Last message"],["\uEA82","Last user message"],["\uEA9A","Next message"],["\uEAA1","Previous message"],["\uEBB3","Auto-approve permissions"]]
17
- var QUICK_ACTIONS=QUICK_ACTION_IDS.map((command,index)=>({command,icon:QUICK_ACTION_METADATA[index][0],label:QUICK_ACTION_METADATA[index][1]
18
- }))
19
- function quickActionLabel(api,action){if(action.command!=="permission.mode")
20
- return action.label
21
- const command=api.keymap.getCommands?.({visibility:"registered"}).find((candidate)=>candidate.name===action.command)
22
- return typeof command?.title==="string"?command.title:action.label
23
- }
14
+ import {For,createEffect,createMemo,onCleanup} from "solid-js"
15
+ import {QUICK_ACTIONS,quickActionLabel} from "./tui.js"
24
16
  import {DialogSurface,SelectionBox,useDialogScroll,useDialogState,useDialogs,useIcons} from "./tui.js"
25
17
  function QuickActionsDialog(props){const order=props.preferences.selectedQuickActionOrder
26
18
  const dialogs=useDialogs(props.api)
@@ -59,7 +51,7 @@ const unregister=props.api.keymap.registerLayer({mode:"modal",priority:1000,comm
59
51
  },{key:"escape",cmd:`${prefix}.back`
60
52
  }]
61
53
  })
62
- onCleanup2(unregister)
54
+ onCleanup(unregister)
63
55
  return _$createComponent(DialogSurface,{get api(){return props.api
64
56
  },id:prefix,lift:true,get children(){return [(()=>{var _el$=_$createElement("box"),_el$2=_$createElement("text"),_el$3=_$createTextNode(` Quick actions`),_el$4=_$createElement("text"),_el$5=_$createTextNode(` Back (`),_el$6=_$createTextNode(`)`)
65
57
  _$insertNode(_el$,_el$2)
package/dist/rpc.js CHANGED
@@ -11,6 +11,7 @@ var NavigatorTodoRpc={id:"opencode-navigator.todo",methods:{list:{input:{type:"o
11
11
  },output
12
12
  }},events:{updated:{schema:{type:"object",properties:{sessionID,todos,guidance:{type:"boolean"}},required:["sessionID","todos","guidance"],additionalProperties:false
13
13
  }}}};
14
+ var LegacyTodoArchiveRpc={id:NavigatorTodoRpc.id,methods:{list:NavigatorTodoRpc.methods.list},events:{}};
14
15
  var text={type:"string",minLength:1,maxLength:512}
15
16
  var model={type:"object",properties:{providerID:text,modelID:text,sessionID:text,connectionID:text,variant:text,force:{type:"boolean"}},required:["providerID","modelID","sessionID"],additionalProperties:false
16
17
  }
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 1,
3
+ "dependencies": {
4
+ "@opencode/plugin": "2.1.0",
5
+ "@opentui/core": "0.6.6",
6
+ "@opentui/keymap": "0.6.6",
7
+ "@opentui/solid": "0.6.6",
8
+ "solid-js": "1.9.15"
9
+ }
10
+ }
package/dist/server.js CHANGED
@@ -6,30 +6,6 @@ const statuses=new Set(["pending","in_progress","completed","cancelled"])
6
6
  const priorities=new Set(["high","medium","low"])
7
7
  const todos=Array.isArray(state.todos)?state.todos.filter((item)=>item&&typeof item.content==="string"&&item.content.trim().length>0&&item.content.length<=512&&statuses.has(item.status)).slice(0,100).map((item)=>({content:item.content.trim(),status:item.status,...priorities.has(item.priority??"")&&{priority:item.priority}})):[]
8
8
  return{todos,guidance:state.guidance===true}}
9
- function todoGuidance(state){const lines=state.todos.map((todo)=>`- [${todo.status}] ${todo.content}`)
10
- return ["Navigator Todo: when work has multiple steps, use navigator_todo_write to keep the session Todo list current.","Mark work in progress, completed, or cancelled as it changes; avoid claiming unfinished work is done.",...lines.length>0?["Current Navigator Todo items:",...lines]:[]].join(`
11
- `)
12
- }
13
- function key(sessionID){return `session.todo.${sessionID}`
14
- }
15
- function createManagedTodos(storage,onChange){const pending=new Map
16
- async function list(sessionID){return normalizeTodoState(await storage.get(key(sessionID)))
17
- }
18
- function change(sessionID,apply){const request=(pending.get(sessionID)??Promise.resolve()).catch(()=>{}).then(async ()=>{const next=apply(await list(sessionID))
19
- await storage.set(key(sessionID),next)
20
- await onChange(sessionID,next)
21
- return next
22
- })
23
- pending.set(sessionID,request)
24
- const clear=()=>{if(pending.get(sessionID)===request)
25
- pending.delete(sessionID)
26
- }
27
- request.then(clear).catch(clear)
28
- return request
29
- }
30
- return{list,replace(sessionID,todos){return change(sessionID,(current)=>({...current,todos:normalizeTodoState({todos}).todos}))
31
- },guidance(sessionID,enabled){return change(sessionID,(current)=>({...current,guidance:enabled}))
32
- }}}
33
9
  var item={type:"object",properties:{content:{type:"string",minLength:1,maxLength:512},status:{type:"string",enum:["pending","in_progress","completed","cancelled"]},priority:{type:"string",enum:["high","medium","low"]}},required:["content","status"],additionalProperties:false
34
10
  }
35
11
  var todos={type:"array",items:item,maxItems:100}
@@ -43,6 +19,9 @@ var NavigatorTodoRpc={id:"opencode-navigator.todo",methods:{list:{input:{type:"o
43
19
  },output
44
20
  }},events:{updated:{schema:{type:"object",properties:{sessionID,todos,guidance:{type:"boolean"}},required:["sessionID","todos","guidance"],additionalProperties:false
45
21
  }}}};
22
+ var LegacyTodoArchiveRpc={id:NavigatorTodoRpc.id,methods:{list:NavigatorTodoRpc.methods.list},events:{}}
23
+ async function readLegacyTodoArchive(get,sessionID){return normalizeTodoState(await get(`session.todo.${sessionID}`))
24
+ }
46
25
  var text={type:"string",minLength:1,maxLength:512}
47
26
  var model={type:"object",properties:{providerID:text,modelID:text,sessionID:text,connectionID:text,variant:text,force:{type:"boolean"}},required:["providerID","modelID","sessionID"],additionalProperties:false
48
27
  }
@@ -484,6 +463,10 @@ const windows=openRouterFreeWindow(body,input.model.modelID,input.apiModelID)
484
463
  const id=typeof data.organization_id==="string"?data.organization_id:undefined
485
464
  return{...balanceSnapshot(input.model,input.provider.name,balances,Date.now(),id),windows,...windows.length>0&&{availability:"ready"},message:data.is_management_key===true?undefined:"Key budget, not account balance. Reading account credits requires a management key."
486
465
  }}
466
+ function credentialToken(credential){if(!credential||credential.type==="external")
467
+ return
468
+ return credential.type==="oauth"?credential.access:credential.key
469
+ }
487
470
  async function nativeQuotaContext(host,model,signal,fetcher){const [provider,catalog]=await Promise.all([host.provider.get({providerID:model.providerID}),host.model.list()])
488
471
  const selected=catalog.data.find((entry)=>entry.providerID===model.providerID&&entry.id===model.modelID&&entry.enabled)
489
472
  if(!selected||!provider.data.integrationID||provider.data.activation==="disabled")
@@ -492,7 +475,7 @@ const connection=await host.integration.connection.active(provider.data.integrat
492
475
  if(!connection)
493
476
  return
494
477
  const credential=await host.integration.connection.resolve(connection)
495
- const token=credential?.type==="oauth"?credential.access:credential?.key
478
+ const token=credentialToken(credential)
496
479
  if(!credential||!token)
497
480
  return
498
481
  signal.throwIfAborted()
@@ -502,7 +485,7 @@ async function sameNativeConnection(host,input){const current=input.provider.int
502
485
  if(!current||connectionKey(current)!==input.connectionID)
503
486
  return false
504
487
  const credential=await host.integration.connection.resolve(current)
505
- const token=credential?.type==="oauth"?credential.access:credential?.key
488
+ const token=credentialToken(credential)
506
489
  return token===input.token
507
490
  }
508
491
  function requestUsesCredential(request,input){const url=new URL(request.url)
@@ -518,7 +501,7 @@ if(["x-api-key","api-key","x-goog-api-key"].some((header)=>request.headers.get(h
518
501
  return true
519
502
  return url.hostname==="generativelanguage.googleapis.com"&&url.searchParams.get("key")===input.token
520
503
  }
521
- function key2(input){return JSON.stringify([input.model.providerID,input.model.modelID,input.model.variant,input.connectionID,createHash("sha256").update(input.token).digest("hex")])
504
+ function key(input){return JSON.stringify([input.model.providerID,input.model.modelID,input.model.variant,input.connectionID,createHash("sha256").update(input.token).digest("hex")])
522
505
  }
523
506
  function modelForEvent(event){return{providerID:event.model.providerID,modelID:event.model.id,sessionID:event.sessionID}}
524
507
  function rejectedRead(model,error,input){const status=error instanceof QuotaReadError?error.status:undefined
@@ -540,7 +523,7 @@ if(input.canonical==="github-copilot")
540
523
  return copilot.read(input)
541
524
  return readNativeRest(input)
542
525
  }
543
- async function currentResult(input,force){const identity=key2(input)
526
+ async function currentResult(input,force){const identity=key(input)
544
527
  const headers=observed.get(identity)
545
528
  const existing=cached.get(identity)
546
529
  let result=!force&&existing&&Date.now()-existing.fetchedAt<30000?existing:undefined
@@ -561,13 +544,13 @@ const epoch=generation
561
544
  const observation=AbortSignal.any([lifecycle,AbortSignal.timeout(1000)])
562
545
  try{const input=await withinQuotaSignal(observation,()=>nativeQuotaContext(host,modelForEvent(event),observation,fetcher))
563
546
  if(input&&epoch===generation&&requestUsesCredential(event.request,input)&&await withinQuotaSignal(observation,()=>sameNativeConnection(host,input)))
564
- captured.set(event.request,{key:key2(input),generation:epoch})
547
+ captured.set(event.request,{key:key(input),generation:epoch})
565
548
  } catch{}},async response(event){const request=captured.get(event.request)
566
549
  if(!request||request.generation!==generation||lifecycle.aborted)
567
550
  return false
568
551
  const observation=AbortSignal.any([lifecycle,AbortSignal.timeout(1000)])
569
552
  try{const input=await withinQuotaSignal(observation,()=>nativeQuotaContext(host,modelForEvent(event),observation,fetcher))
570
- if(!input||key2(input)!==request.key||!await withinQuotaSignal(observation,()=>sameNativeConnection(host,input)))
553
+ if(!input||key(input)!==request.key||!await withinQuotaSignal(observation,()=>sameNativeConnection(host,input)))
571
554
  return false
572
555
  let windows=nativeHeaderWindows(input.canonical,input.model.modelID,event.response.headers)
573
556
  if(windows.length===0&&event.response.status===429&&["google","google-vertex"].includes(input.canonical)&&event.response.headers.get("content-type")?.includes("json"))
@@ -629,32 +612,11 @@ await response.dispose()
629
612
  await rpc.dispose()
630
613
  await service.dispose()
631
614
  }}
632
- var input={type:"object",properties:{todos:NavigatorTodoRpc.methods.replace.input.properties.todos
633
- },required:["todos"],additionalProperties:false
634
- }
635
- var noNotify=async ()=>{}
636
- var todo_server_default=Plugin.define({id:"opencode-navigator.todo-server",async setup(host){let notify=noNotify
637
- const todos=createManagedTodos({get:(key)=>host.storage.get(key),set:(key,value)=>host.storage.set(key,value)
638
- },(sessionID,state)=>notify(sessionID,state))
639
- const rpc=await host.rpc.register(NavigatorTodoRpc,{list:async (value)=>todos.list(value.sessionID),replace:async (value)=>{const{sessionID,todos:items}=value
640
- return todos.replace(sessionID,items)
641
- },guidance:async (value)=>{const{sessionID,enabled}=value
642
- return todos.guidance(sessionID,enabled)
643
- }})
644
- notify=(sessionID,state)=>rpc.events.emit("updated",{sessionID,...state})
645
- const tools=await host.tool.transform((editor)=>{editor.namespace({name:"navigator",description:"Navigator session tasks"})
646
- editor.add({name:"todo_write",description:"Replace the Navigator Todo list for this session with the current tasks and their statuses.",input,options:{namespace:"navigator"},execute:async (value,context)=>{const state=await todos.replace(context.sessionID,value.todos)
647
- return{content:`Navigator Todo updated: ${state.todos.length} tasks.`}}})
648
- })
649
- const context=await host.session.hook("context",async (event)=>{const state=await todos.list(event.sessionID)
650
- if(state.guidance)
651
- event.system.push({type:"text",text:todoGuidance(state)})
615
+ var server_plugin_default=Plugin.define({id:"opencode-navigator.todo-server",async setup(host){const archive=await host.rpc.register(LegacyTodoArchiveRpc,{list:async (value)=>readLegacyTodoArchive((key)=>host.storage.get(key),value.sessionID)
652
616
  })
653
617
  const quotaCleanup=typeof host.integration?.connection?.active==="function"&&typeof host.provider?.get==="function"?await setupProviderQuotaServer(host):undefined
654
618
  return async ()=>{await quotaCleanup?.()
655
- await context.dispose()
656
- await tools.dispose()
657
- await rpc.dispose()
619
+ await archive.dispose()
658
620
  }}})
659
- export{todo_server_default as default
621
+ export{server_plugin_default as default
660
622
  }
@@ -10,16 +10,17 @@ _$insertNode(_el$,_$createTextNode(`Paste versioned Navigator JSON.`))
10
10
  _$effect((_$p)=>_$setProp(_el$,"fg",input.api.theme.current.textMuted,_$p))
11
11
  return _el$
12
12
  })(),onConfirm(source){const preview=input.preferences.previewPortableSettings(source)
13
- const options=[...preview.settings.layout?[{title:`Layout \xB7 ${preview.layoutChanged ? "CHANGED" : "UNCHANGED"}`,value:"status",description:`${Object.keys(preview.settings.layout.sections).length} visibility \xB7 ${Object.keys(preview.settings.layout.expanded).length} expansion values`,icon:preview.layoutChanged?"edit":"done"
13
+ const options=[...preview.settings.behavior?[{title:`Toolbar overflow \xB7 ${preview.behaviorChanged ? "CHANGED" : "UNCHANGED"}`,value:"status",description:preview.settings.behavior.toolbarOverflow??"unchanged",icon:"settings"
14
+ }]:[],...preview.settings.layout?[{title:`Layout \xB7 ${preview.layoutChanged ? "CHANGED" : "UNCHANGED"}`,value:"status",description:`${Object.keys(preview.settings.layout.sections).length} visibility \xB7 ${Object.keys(preview.settings.layout.expanded).length} expansion values`,icon:preview.layoutChanged?"edit":"done"
14
15
  }]:[],...preview.settings.mcp?[{title:`MCP \xB7 ${preview.mcpChanged ? "CHANGED" : "UNCHANGED"}`,value:"status",description:`${Object.keys(preview.settings.mcp).length} remembered server states`,icon:preview.mcpChanged?"edit":"done"
15
16
  }]:[],...preview.unsupported.map((path)=>({title:"Unsupported field \xB7 SKIPPED",value:"status",description:path,icon:"error"
16
- })),...preview.layoutChanged||preview.mcpChanged?[{title:"Apply imported settings",value:"apply",description:preview.target,icon:"done"
17
+ })),...preview.layoutChanged||preview.mcpChanged||preview.behaviorChanged?[{title:"Apply imported settings",value:"apply",description:preview.target,icon:"done"
17
18
  }]:[],{title:"Cancel",value:"cancel",description:"return without changes",icon:"close"
18
19
  }]
19
20
  let applying=false
20
21
  async function apply(){applying=true
21
22
  try{await input.preferences.applyPortableSettings(preview)
22
- input.api.ui.toast({variant:"success",title:"Portable settings",message:"Layout and MCP settings imported",duration:3000
23
+ input.api.ui.toast({variant:"success",title:"Portable settings",message:"Supported settings imported",duration:3000
23
24
  })
24
25
  input.dialogs.back()
25
26
  } catch(error){applying=false