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.
- package/CHANGELOG.md +14 -1
- package/README.md +101 -21
- package/dist/{chunk-d1bws32s.js → chunk-dz8cfnfs.js} +4 -3
- package/dist/chunk-qmntexwm.js +0 -0
- package/dist/chunk-v6bz59xn.js +20 -0
- package/dist/icon-picker.js +175 -0
- package/dist/layout-preset-actions.js +4 -20
- package/dist/navigator-updates.js +12 -4
- package/dist/project-profile.js +12 -4
- package/dist/provider-limits.js +34 -26
- package/dist/quick-actions-settings.js +5 -13
- package/dist/rpc.js +1 -0
- package/dist/runtime-dependencies.json +10 -0
- package/dist/server.js +16 -54
- package/dist/settings-import.js +4 -3
- package/dist/sidebar-settings.js +828 -0
- package/dist/sidebar-shortcuts.js +261 -0
- package/dist/toolbar-settings.js +161 -0
- package/dist/tui.js +955 -992
- package/package.json +8 -7
- package/scripts/snapshot-runtime.mjs +32 -0
- package/scripts/update-local-snapshot.mjs +14 -3
package/dist/provider-limits.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {PLUGIN_ID
|
|
2
|
-
} from "./chunk-
|
|
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
|
|
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
|
|
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("
|
|
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$
|
|
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
|
-
_$
|
|
418
|
-
_$insertNode(_el$
|
|
419
|
-
_$
|
|
420
|
-
_$setProp(_el$
|
|
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,"
|
|
427
|
-
_$setProp(_el$4,"
|
|
428
|
-
_$
|
|
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().
|
|
433
|
-
_$
|
|
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$
|
|
436
|
-
_v$3!==_p$.a&&(_p$.a=_$setProp(_el$
|
|
437
|
-
_v$4!==_p$.o&&(_p$.o=_$setProp(_el$5,"
|
|
438
|
-
_v$5!==_p$.i&&(_p$.i=_$setProp(_el$
|
|
439
|
-
_v$6!==_p$.n&&(_p$.n=_$setProp(_el$
|
|
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 {
|
|
2
|
-
} from "./chunk-
|
|
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
|
|
15
|
-
import {
|
|
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
|
-
|
|
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
|
}
|
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
|
|
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
|
|
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
|
|
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=
|
|
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:
|
|
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||
|
|
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
|
|
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
|
|
656
|
-
await tools.dispose()
|
|
657
|
-
await rpc.dispose()
|
|
619
|
+
await archive.dispose()
|
|
658
620
|
}}})
|
|
659
|
-
export{
|
|
621
|
+
export{server_plugin_default as default
|
|
660
622
|
}
|
package/dist/settings-import.js
CHANGED
|
@@ -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.
|
|
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:"
|
|
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
|