opencode-navigator 0.21.2 → 0.21.4
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 +11 -0
- package/PROVIDERS.md +1 -1
- package/README.md +26 -5
- package/dist/navigator-updates.js +237 -0
- package/dist/provider-limits.js +32 -25
- package/dist/tui.js +29 -140
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## [0.21.4] - 2026-10-07
|
|
6
|
+
|
|
7
|
+
- Add `c` to Navigator shortcuts for a manual update check and `u` to check then confirm a Navigator update. Report available, current, or unavailable results, preserve the installation method and scope, and require a restart after updating.
|
|
8
|
+
- Ignore cancelled, outdated, and repeated update confirmations, and recover from stalled update checks without blocking later checks.
|
|
9
|
+
|
|
10
|
+
## [0.21.3] - 2026-10-06
|
|
11
|
+
|
|
12
|
+
- Replace block quota meters with full-width adaptive thin-line scales and keep quota rows inside the sidebar's padding after resize. Show only reset time below each meter, removing technical account and window-duration suffixes.
|
|
13
|
+
|
|
5
14
|
## [0.21.2] - 2026-10-06
|
|
6
15
|
|
|
7
16
|
- Make Limits compact with clickable provider/model and variant controls, remaining-headroom progress rows, and muted reset times. Move Refresh and Banked Resets into the section header, remove the section counter and Provider sources action, and keep reset consumption behind a separate confirmation.
|
|
@@ -86,6 +95,8 @@
|
|
|
86
95
|
|
|
87
96
|
Earlier release notes are available on [GitHub Releases](https://github.com/St1ggy/opencode-navigator/releases).
|
|
88
97
|
|
|
98
|
+
[0.21.4]: https://github.com/St1ggy/opencode-navigator/compare/v0.21.3...v0.21.4
|
|
99
|
+
[0.21.3]: https://github.com/St1ggy/opencode-navigator/compare/v0.21.2...v0.21.3
|
|
89
100
|
[0.21.2]: https://github.com/St1ggy/opencode-navigator/compare/v0.21.1...v0.21.2
|
|
90
101
|
[0.21.1]: https://github.com/St1ggy/opencode-navigator/compare/v0.21.0...v0.21.1
|
|
91
102
|
[0.21.0]: https://github.com/St1ggy/opencode-navigator/compare/v0.20.0...v0.21.0
|
package/PROVIDERS.md
CHANGED
|
@@ -14,7 +14,7 @@ permissions, region, transport, and supported host APIs.
|
|
|
14
14
|
|
|
15
15
|
| Provider | Native source | Scope and prerequisites | Reference |
|
|
16
16
|
| --- | --- | --- | --- |
|
|
17
|
-
| OpenAI / Codex ChatGPT | Codex app-server account/rate-limit RPC and manual reset credits | Verified account identity; ordinary `codex` quota
|
|
17
|
+
| OpenAI / Codex ChatGPT | Codex app-server account/rate-limit RPC and manual reset credits | Verified account identity; ordinary `codex` quota is account-scoped even with null model metadata; separate model buckets need explicit association; native durations describe quota windows, not time until reset | [Codex protocol](https://github.com/openai/codex/tree/main/codex-rs/app-server-protocol) |
|
|
18
18
|
| OpenAI API | HTTP request/token/project-token rate-limit headers | Actual response for the selected model/account; HTTP transport | [Rate limits](https://developers.openai.com/api/docs/guides/rate-limits) |
|
|
19
19
|
| Anthropic API | Native response headers and organization rate-limits API | Per-model headers; configured limits need an eligible org/admin credential and explicit model association | [Rate limits API](https://platform.claude.com/docs/en/manage-claude/rate-limits-api) |
|
|
20
20
|
| Azure OpenAI | Native remaining request/token headers | Actual deployment response; does not expose a ChatGPT subscription | [Quotas and limits](https://learn.microsoft.com/en-us/azure/ai-foundry/openai/quotas-limits) |
|
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ See the [changelog](CHANGELOG.md) for release-by-release changes.
|
|
|
33
33
|
- Save visibility, expansion, and order globally or for the current worktree
|
|
34
34
|
- Copy the selected scope's layout and MCP states as versioned JSON, then validate and preview imports
|
|
35
35
|
- Focus the sidebar with `Ctrl+Shift+F`, then navigate with arrows or `j`/`k`
|
|
36
|
-
- Open sidebar shortcut mode with `Ctrl+Shift+B`; press `h` to toggle the panel
|
|
36
|
+
- Open sidebar shortcut mode with `Ctrl+Shift+B`; press `h` to toggle the panel, `c` to check Navigator updates, or `u` to check and confirm an update
|
|
37
37
|
- Optionally open new sessions directly in an empty chat with the sidebar, skipping Home on startup and from New session
|
|
38
38
|
- Keep OpenCode's compact footer while showing host and Navigator versions with independent update indicators; click a version label or its update icon to confirm an in-place update through the current installation method and scope
|
|
39
39
|
|
|
@@ -365,7 +365,7 @@ Codex 0.160.0 protocol also exposes the separate
|
|
|
365
365
|
`account/rateLimitResetCredit/consume` RPC. Navigator requires explicit
|
|
366
366
|
confirmation before using it and never redeems credits in the background.
|
|
367
367
|
Limits follows the model and verified connection selected in the current OpenCode
|
|
368
|
-
session. Codex's ordinary `codex` windows
|
|
368
|
+
session. Codex's ordinary `codex` windows describe verified account quota shared
|
|
369
369
|
across models. The protocol can return `normalModelSlug: null` for this ordinary
|
|
370
370
|
bucket; that field is display metadata for quota aliases, not a prerequisite for
|
|
371
371
|
account usage. Separate model-specific buckets require explicit model association.
|
|
@@ -428,9 +428,11 @@ bindings are reused; conflicting bindings remain isolated until a deliberate rel
|
|
|
428
428
|
|
|
429
429
|
Limits starts with **[Provider name] Model name · variant**. Activate the model or
|
|
430
430
|
variant with the mouse or keyboard to open OpenCode's native selector. Each quota
|
|
431
|
-
window uses two compact rows: remaining headroom with
|
|
432
|
-
|
|
433
|
-
|
|
431
|
+
window uses two compact rows: remaining headroom with an adaptive muted thin-line
|
|
432
|
+
scale spanning the available sidebar content width, then a muted reset time.
|
|
433
|
+
Both rows stay within the sidebar's padding when it resizes. Healthy views omit
|
|
434
|
+
account IDs, technical scope/window-duration suffixes, source explanations, and update timestamps. Account scope and native window durations remain in the data model;
|
|
435
|
+
durations describe provider quota windows, not time remaining until reset. Balances retain their native
|
|
434
436
|
currency or point unit; a missing total does not become a full progress scale.
|
|
435
437
|
|
|
436
438
|
The header has no section counter. Its compact **Refresh** control requests a
|
|
@@ -634,6 +636,25 @@ The command palette also exposes `Focus sidebar` and direct commands for Todo,
|
|
|
634
636
|
Subagents, Skills, Quick Actions, LSP, and MCP. Both sidebar shortcuts can be
|
|
635
637
|
changed at runtime in settings.
|
|
636
638
|
|
|
639
|
+
Press `Ctrl+Shift+B` to enter Navigator shortcuts, then choose an action:
|
|
640
|
+
|
|
641
|
+
| Key | Action |
|
|
642
|
+
| --- | --- |
|
|
643
|
+
| `h` | Toggle sidebar visibility |
|
|
644
|
+
| `t` / `a` / `s` / `q` / `l` / `m` | Focus Todo / Subagents / Skills / Quick Actions / LSP / MCP |
|
|
645
|
+
| `c` | Check for a Navigator update and report whether one is available |
|
|
646
|
+
| `u` | Check for a Navigator update, then open its confirmation if available |
|
|
647
|
+
| `Escape` | Cancel shortcut mode |
|
|
648
|
+
|
|
649
|
+
The mode ends after an action or five seconds of inactivity. Its toast lists only
|
|
650
|
+
actions supported by the current host; LSP is omitted on OpenCode 2.x. Change the
|
|
651
|
+
entry shortcut under **Settings → Behavior**. The command palette also offers
|
|
652
|
+
**Check Navigator updates** and **Update Navigator**.
|
|
653
|
+
|
|
654
|
+
Manual checks report when Navigator is current or the update source is unavailable.
|
|
655
|
+
Updates require confirmation, preserve the existing installation method and scope,
|
|
656
|
+
and show a restart reminder after completion. Background check failures stay quiet.
|
|
657
|
+
|
|
637
658
|
### Search Everything
|
|
638
659
|
|
|
639
660
|
Press `Ctrl+Shift+K` or run **Search Everything** from the command palette. Use
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import {PLUGIN_ID
|
|
2
|
+
} from "./chunk-cmmnfes2.js";
|
|
3
|
+
import {createSignal} from "solid-js"
|
|
4
|
+
function versionParts(value){const match=/^v?(\d+)\.(\d+)\.(\d+)(?:-([^+]+))?/.exec(value)
|
|
5
|
+
return match?{numbers:match.slice(1,4).map(Number),prerelease:match[4]||undefined}:undefined
|
|
6
|
+
}
|
|
7
|
+
function isNewerVersion(latest,current){const next=versionParts(latest)
|
|
8
|
+
const installed=versionParts(current)
|
|
9
|
+
if(!next||!installed)
|
|
10
|
+
return false
|
|
11
|
+
for(let index=0;index<3; index++){if(next.numbers[index]!==installed.numbers[index])
|
|
12
|
+
return next.numbers[index]>installed.numbers[index]
|
|
13
|
+
}
|
|
14
|
+
return installed.prerelease!==undefined&&next.prerelease===undefined
|
|
15
|
+
}
|
|
16
|
+
var NAVIGATOR_PACKAGE_URL="https://registry.npmjs.org/opencode-navigator/latest"
|
|
17
|
+
var REQUEST_TIMEOUT_MS=5000
|
|
18
|
+
async function readNavigatorVersion(request,signal){const response=await request(NAVIGATOR_PACKAGE_URL,{headers:{accept:"application/json"},signal})
|
|
19
|
+
if(!response.ok)
|
|
20
|
+
throw new Error("Update source unavailable")
|
|
21
|
+
const metadata=await response.json()
|
|
22
|
+
if(typeof metadata.version!=="string"||!/^\d+\.\d+\.\d+(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(metadata.version))
|
|
23
|
+
throw new Error("Invalid update version")
|
|
24
|
+
return metadata.version
|
|
25
|
+
}
|
|
26
|
+
function createVersionStatus(api,navigatorVersion,request=fetch,timeoutMs=REQUEST_TIMEOUT_MS){const [openCodeUpdate,setOpenCodeUpdate]=createSignal()
|
|
27
|
+
const [navigatorUpdate,setNavigatorUpdate]=createSignal()
|
|
28
|
+
let controller
|
|
29
|
+
let pending
|
|
30
|
+
let disposed=false
|
|
31
|
+
const unsubscribe=api.event.on("installation.update-available",(event)=>{const version=event.properties.version
|
|
32
|
+
setOpenCodeUpdate(isNewerVersion(version,api.app.version)?version:undefined)
|
|
33
|
+
})
|
|
34
|
+
api.lifecycle.onDispose(()=>{disposed=true
|
|
35
|
+
controller?.abort()
|
|
36
|
+
unsubscribe()
|
|
37
|
+
})
|
|
38
|
+
function refreshNavigator(){if(disposed)
|
|
39
|
+
return Promise.resolve("unavailable")
|
|
40
|
+
if(pending)
|
|
41
|
+
return pending
|
|
42
|
+
const active=new AbortController
|
|
43
|
+
controller=active
|
|
44
|
+
const timeout=setTimeout(()=>active.abort(),timeoutMs)
|
|
45
|
+
let abort
|
|
46
|
+
const cancelled=new Promise((_,reject)=>{abort=()=>reject(new Error("Update check interrupted"))
|
|
47
|
+
active.signal.addEventListener("abort",abort,{once:true})
|
|
48
|
+
})
|
|
49
|
+
const reading=Promise.race([readNavigatorVersion(request,active.signal),cancelled]).then((version)=>{if(disposed||active.signal.aborted)
|
|
50
|
+
return "unavailable"
|
|
51
|
+
const newer=isNewerVersion(version,navigatorVersion)
|
|
52
|
+
setNavigatorUpdate(newer?version:undefined)
|
|
53
|
+
return newer?"update":"current"
|
|
54
|
+
}).catch(()=>"unavailable").finally(()=>{clearTimeout(timeout)
|
|
55
|
+
active.signal.removeEventListener("abort",abort)
|
|
56
|
+
if(controller===active)
|
|
57
|
+
controller=undefined
|
|
58
|
+
if(pending===reading)
|
|
59
|
+
pending=undefined
|
|
60
|
+
})
|
|
61
|
+
pending=reading
|
|
62
|
+
return reading
|
|
63
|
+
}
|
|
64
|
+
refreshNavigator()
|
|
65
|
+
return{openCodeUpdate,navigatorUpdate,refreshNavigator}}
|
|
66
|
+
import {effect as _$effect3} from "@opentui/solid"
|
|
67
|
+
import {insertNode as _$insertNode3} from "@opentui/solid"
|
|
68
|
+
import {createComponent as _$createComponent2} from "@opentui/solid"
|
|
69
|
+
import {insert as _$insert3} from "@opentui/solid"
|
|
70
|
+
import {setProp as _$setProp3} from "@opentui/solid"
|
|
71
|
+
import {createElement as _$createElement3} from "@opentui/solid"
|
|
72
|
+
import {effect as _$effect2} from "@opentui/solid"
|
|
73
|
+
import {insert as _$insert2} from "@opentui/solid"
|
|
74
|
+
import {createTextNode as _$createTextNode2} from "@opentui/solid"
|
|
75
|
+
import {insertNode as _$insertNode2} from "@opentui/solid"
|
|
76
|
+
import {createComponent as _$createComponent} from "@opentui/solid"
|
|
77
|
+
import {setProp as _$setProp2} from "@opentui/solid"
|
|
78
|
+
import {createElement as _$createElement2} from "@opentui/solid"
|
|
79
|
+
import {effect as _$effect} from "@opentui/solid"
|
|
80
|
+
import {memo as _$memo} from "@opentui/solid"
|
|
81
|
+
import {createTextNode as _$createTextNode} from "@opentui/solid"
|
|
82
|
+
import {insertNode as _$insertNode} from "@opentui/solid"
|
|
83
|
+
import {insert as _$insert} from "@opentui/solid"
|
|
84
|
+
import {setProp as _$setProp} from "@opentui/solid"
|
|
85
|
+
import {createElement as _$createElement} from "@opentui/solid"
|
|
86
|
+
import {useIcons} from "./tui.js"
|
|
87
|
+
import {createComponent as _$createComponent3} from "@opentui/solid"
|
|
88
|
+
function createManualUpdateCheck(api,status,current,onUpdate){let checking=false
|
|
89
|
+
async function read(){try{return await status.refreshNavigator?.()??"unavailable"
|
|
90
|
+
} catch{return "unavailable"
|
|
91
|
+
}}
|
|
92
|
+
return{checking:()=>checking,async run(offerUpdate=false){if(!current()||checking)
|
|
93
|
+
return
|
|
94
|
+
checking=true
|
|
95
|
+
api.ui.toast({variant:"info",title:"Navigator update",message:"Checking for updates\u2026"})
|
|
96
|
+
try{const result=await read()
|
|
97
|
+
if(!current())
|
|
98
|
+
return
|
|
99
|
+
if(result==="update"&&offerUpdate){onUpdate()
|
|
100
|
+
return
|
|
101
|
+
}
|
|
102
|
+
api.ui.toast({variant:result==="unavailable"?"warning":"info",title:"Navigator update",message:{update:`Navigator ${status.navigatorUpdate()} is available. Use u in Navigator shortcuts to update.`,current:"Navigator is up to date.",unavailable:"Could not check Navigator updates. Try again."
|
|
103
|
+
}[result]
|
|
104
|
+
})
|
|
105
|
+
} finally{checking=false
|
|
106
|
+
}}}}
|
|
107
|
+
function createVersionUpdateActions(api,status,updater,rememberNavigatorVersion){const busy=new Set
|
|
108
|
+
const installed={}
|
|
109
|
+
let disposed=false
|
|
110
|
+
let confirmation=0
|
|
111
|
+
function target(kind){return kind==="openCode"?status.openCodeUpdate():status.navigatorUpdate()
|
|
112
|
+
}
|
|
113
|
+
function label(kind){return kind==="openCode"?"OpenCode":"Navigator"
|
|
114
|
+
}
|
|
115
|
+
function update(kind,version){if(disposed||busy.has(kind))
|
|
116
|
+
return
|
|
117
|
+
if(version!==target(kind)){api.ui.toast({variant:"warning",title:"Update changed",message:"Check for updates again before confirming."
|
|
118
|
+
})
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
api.ui.dialog.clear()
|
|
122
|
+
busy.add(kind)
|
|
123
|
+
api.ui.toast({variant:"info",title:`Updating ${label(kind)}`,message:`Installing ${version}...`
|
|
124
|
+
});
|
|
125
|
+
(async ()=>{if(kind==="navigator")
|
|
126
|
+
await rememberNavigatorVersion?.()
|
|
127
|
+
if(disposed||version!==target(kind))
|
|
128
|
+
throw new Error("Update target changed; check again")
|
|
129
|
+
await updater[kind](version)
|
|
130
|
+
})().then(()=>{installed[kind]=version
|
|
131
|
+
if(disposed)
|
|
132
|
+
return
|
|
133
|
+
api.ui.toast({variant:"success",title:`${label(kind)} updated`,message:"Restart OpenCode to use the new version.",duration:6000
|
|
134
|
+
})
|
|
135
|
+
}).catch((error)=>{if(disposed)
|
|
136
|
+
return
|
|
137
|
+
api.ui.toast({variant:"error",title:`Could not update ${label(kind)}`,message:error instanceof Error?error.message:"Update failed",duration:6000
|
|
138
|
+
})
|
|
139
|
+
}).finally(()=>busy.delete(kind))
|
|
140
|
+
}
|
|
141
|
+
function open(kind,version=target(kind)){if(disposed||!version||version!==target(kind)||busy.has(kind))
|
|
142
|
+
return
|
|
143
|
+
if(installed[kind]===version){api.ui.toast({variant:"info",title:`${label(kind)} updated`,message:"Restart OpenCode to use the installed update."
|
|
144
|
+
})
|
|
145
|
+
return
|
|
146
|
+
}
|
|
147
|
+
const id=++confirmation
|
|
148
|
+
api.ui.dialog.replace(()=>_$createComponent3(api.ui.DialogConfirm,{get title(){return `Update ${label(kind)}`
|
|
149
|
+
},message:`Update to ${version} using the current installation method? OpenCode must be restarted afterward.`,onConfirm:()=>{if(id!==confirmation)
|
|
150
|
+
return
|
|
151
|
+
confirmation++
|
|
152
|
+
update(kind,version)
|
|
153
|
+
},onCancel:()=>{if(id!==confirmation)
|
|
154
|
+
return
|
|
155
|
+
confirmation++
|
|
156
|
+
api.ui.dialog.clear()
|
|
157
|
+
}}))
|
|
158
|
+
}
|
|
159
|
+
const manual=createManualUpdateCheck(api,status,()=>!disposed&&!busy.has("navigator"),()=>open("navigator"))
|
|
160
|
+
const unregister=api.keymap.registerLayer({commands:[{name:`${PLUGIN_ID}.check-update`,title:"Check Navigator updates",category:"Navigator",namespace:"palette",enabled:()=>!manual.checking()&&!busy.has("navigator"),run:()=>void manual.run()
|
|
161
|
+
},{name:`${PLUGIN_ID}.update-opencode`,title:"Update OpenCode",category:"Navigator",namespace:"palette",enabled:()=>Boolean(target("openCode"))&&!busy.has("openCode"),run:()=>open("openCode")
|
|
162
|
+
},{name:`${PLUGIN_ID}.update-navigator`,title:"Update Navigator",category:"Navigator",namespace:"palette",enabled:()=>!manual.checking()&&!busy.has("navigator"),run:()=>void manual.run(true)
|
|
163
|
+
}]
|
|
164
|
+
})
|
|
165
|
+
api.lifecycle.onDispose(()=>{disposed=true
|
|
166
|
+
unregister()
|
|
167
|
+
})
|
|
168
|
+
return{openCode:(version)=>open("openCode",version),navigator:(version)=>open("navigator",version)
|
|
169
|
+
}}
|
|
170
|
+
import {homedir} from "os"
|
|
171
|
+
import {basename,dirname,isAbsolute,join} from "path"
|
|
172
|
+
import {fileURLToPath} from "url"
|
|
173
|
+
var run=async (command)=>{const child=Bun.spawn([...command],{stdout:"ignore",stderr:"pipe"})
|
|
174
|
+
const error=new Response(child.stderr).text()
|
|
175
|
+
const exitCode=await child.exited
|
|
176
|
+
if(exitCode===0)
|
|
177
|
+
return
|
|
178
|
+
const message=await error
|
|
179
|
+
throw new Error(message.trim()||`Command failed with exit code ${child.exitCode}`)
|
|
180
|
+
}
|
|
181
|
+
var readConfig=async (path)=>{const file=Bun.file(path)
|
|
182
|
+
return await file.exists()?Bun.JSONC.parse(await file.text()):undefined
|
|
183
|
+
}
|
|
184
|
+
function pinnedUpdate(wrapper,target,execute){if(basename(wrapper)!=="tui.js"||basename(dirname(wrapper))!=="opencode-navigator")
|
|
185
|
+
throw new Error("Unrecognized local Navigator source")
|
|
186
|
+
const installer=fileURLToPath(new URL("../scripts/update-local-snapshot.mjs",import.meta.url))
|
|
187
|
+
return execute(["node",installer,wrapper,target])
|
|
188
|
+
}
|
|
189
|
+
function configHasPlugin(value,spec){if(!value||typeof value!=="object")
|
|
190
|
+
return false
|
|
191
|
+
const plugins=value.plugin
|
|
192
|
+
return Array.isArray(plugins)&&plugins.some((item)=>{let configured=item
|
|
193
|
+
if(Array.isArray(item))
|
|
194
|
+
configured=item[0]
|
|
195
|
+
else if(item&&typeof item==="object")
|
|
196
|
+
configured=item.package
|
|
197
|
+
return configured===spec
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
async function v1Global(api,spec,read){const configRoot=process.env.OPENCODE_CONFIG_DIR??join(process.env.XDG_CONFIG_HOME??join(homedir(),".config"),"opencode")
|
|
201
|
+
const global=join(configRoot,"tui.json")
|
|
202
|
+
const configured=api.state.path.config.endsWith(".json")?api.state.path.config:join(api.state.path.config,"tui.json")
|
|
203
|
+
const local=new Set([configured,join(api.state.path.worktree,".opencode","tui.json")])
|
|
204
|
+
local.delete(global)
|
|
205
|
+
for(const path of local)
|
|
206
|
+
if(configHasPlugin(await read(path),spec))
|
|
207
|
+
return false
|
|
208
|
+
return configHasPlugin(await read(global),spec)
|
|
209
|
+
}
|
|
210
|
+
function createOpenCodeV1VersionUpdater(api,meta,execute=run,read=readConfig){return{openCode:(target)=>execute([process.execPath,"upgrade",target]),async navigator(target){if(meta.source==="file"){const wrapper=meta.spec.startsWith("file://")?fileURLToPath(meta.spec):meta.spec
|
|
211
|
+
return pinnedUpdate(wrapper,target,execute)
|
|
212
|
+
}
|
|
213
|
+
if(meta.source!=="npm")
|
|
214
|
+
throw new Error("Unrecognized local Navigator source")
|
|
215
|
+
const result=await api.plugins.install(`opencode-navigator@${target}`,{global:await v1Global(api,meta.spec,read)
|
|
216
|
+
})
|
|
217
|
+
if(!result.ok)
|
|
218
|
+
throw new Error(result.message)
|
|
219
|
+
}}}
|
|
220
|
+
function createOpenCodeV2VersionUpdater(context,execute=run){return{openCode:(target)=>execute([process.execPath,"upgrade",target]),async navigator(target){const response=await context.client.plugin.list(context.location?{location:context.location}:{})
|
|
221
|
+
const item=response.data.find((plugin)=>plugin.id===PLUGIN_ID)
|
|
222
|
+
if(!item)
|
|
223
|
+
throw new Error("Navigator is not in the active plugin list")
|
|
224
|
+
if(item.source.type==="local")
|
|
225
|
+
return pinnedUpdate(basename(item.source.path)==="tui.js"?item.source.path:join(item.source.path,"tui.js"),target,execute)
|
|
226
|
+
if(item.source.type!=="package")
|
|
227
|
+
throw new Error("Unrecognized local Navigator source")
|
|
228
|
+
if(isAbsolute(item.source.target))
|
|
229
|
+
return pinnedUpdate(join(item.source.target,"tui.js"),target,execute)
|
|
230
|
+
if(item.source.target.startsWith("file://"))
|
|
231
|
+
return pinnedUpdate(join(fileURLToPath(item.source.target),"tui.js"),target,execute)
|
|
232
|
+
if(item.source.target.startsWith("."))
|
|
233
|
+
throw new Error("Unrecognized local Navigator source")
|
|
234
|
+
await context.client.plugin.update({location:response.location,targets:[item.source.target]})
|
|
235
|
+
}}}
|
|
236
|
+
export{createOpenCodeV1VersionUpdater,createOpenCodeV2VersionUpdater,createVersionStatus,createVersionUpdateActions
|
|
237
|
+
}
|
package/dist/provider-limits.js
CHANGED
|
@@ -364,15 +364,8 @@ import {insertNode as _$insertNode} from "@opentui/solid"
|
|
|
364
364
|
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
|
+
import {createSignal as createSignal4} from "solid-js"
|
|
367
368
|
import {useIcons} from "./tui.js"
|
|
368
|
-
function duration(minutes){if(minutes%10080===0)
|
|
369
|
-
return `${minutes / 10080}w`
|
|
370
|
-
if(minutes%1440===0)
|
|
371
|
-
return `${minutes / 1440}d`
|
|
372
|
-
if(minutes%60===0)
|
|
373
|
-
return `${minutes / 60}h`
|
|
374
|
-
return `${minutes}m`
|
|
375
|
-
}
|
|
376
369
|
function measurement(window,remaining){if(remaining!==undefined)
|
|
377
370
|
return `${remaining}${window.unit === "%" ? "" : " "}${window.unit} left`
|
|
378
371
|
if(window.used!==undefined)
|
|
@@ -390,28 +383,38 @@ return `Resets ${date.toLocaleDateString(undefined, { month: "short", day: "nume
|
|
|
390
383
|
function quotaPresentation(window,now=Date.now()){const total=window.unit==="%"?100:window.total
|
|
391
384
|
const remaining=window.remaining??(total!==undefined&&window.used!==undefined?total-window.used:undefined)
|
|
392
385
|
const ratio=remaining!==undefined&&total!==undefined&&total>0?Math.max(0,Math.min(1,remaining / total)):undefined
|
|
393
|
-
|
|
394
|
-
const scope=window.kind==="rate_limit"?"API":account
|
|
395
|
-
const period=window.durationMinutes?duration(window.durationMinutes):undefined
|
|
396
|
-
const context=[scope,window.kind?window.label:period??window.label,window.kind?period:undefined].filter(Boolean).join(" \xB7 ")
|
|
397
|
-
return{value:measurement(window,remaining),ratio,reset:`${resetTime(window.resetsAt, now)} \xB7 ${context}`}}
|
|
386
|
+
return{value:measurement(window,remaining),ratio,reset:resetTime(window.resetsAt,now)}}
|
|
398
387
|
function QuotaWindowRow(props){const icons=useIcons()
|
|
388
|
+
const [columns,setColumns]=createSignal4(0)
|
|
399
389
|
const view=()=>quotaPresentation(props.window)
|
|
400
390
|
const scale=()=>{const ratio=view().ratio
|
|
401
391
|
if(ratio===undefined)
|
|
402
392
|
return " \xB7 scale unknown"
|
|
403
|
-
const
|
|
404
|
-
const
|
|
405
|
-
|
|
393
|
+
const width=Math.max(0,columns()-Bun.stringWidth(view().value)-1)
|
|
394
|
+
const filled=Math.round(ratio*width)
|
|
395
|
+
const symbols=icons.style()==="text"?["=","-"]:["\u2501","\u2500"]
|
|
396
|
+
return width?` ${symbols[0].repeat(filled)}${symbols[1].repeat(width - filled)}`:""
|
|
406
397
|
}
|
|
407
398
|
return(()=>{var _el$=_$createElement("box"),_el$2=_$createElement("text"),_el$3=_$createElement("span"),_el$4=_$createElement("text")
|
|
408
399
|
_$insertNode(_el$,_el$2)
|
|
409
400
|
_$insertNode(_el$,_el$4)
|
|
401
|
+
_$setProp(_el$,"width","100%")
|
|
402
|
+
_$setProp(_el$,"minWidth",0)
|
|
403
|
+
_$setProp(_el$,"flexShrink",1)
|
|
404
|
+
_$setProp(_el$,"overflow","hidden")
|
|
405
|
+
_$setProp(_el$,"onSizeChange",function(){setColumns(this.width)
|
|
406
|
+
})
|
|
410
407
|
_$insertNode(_el$2,_el$3)
|
|
408
|
+
_$setProp(_el$2,"width","100%")
|
|
409
|
+
_$setProp(_el$2,"minWidth",0)
|
|
410
|
+
_$setProp(_el$2,"height",1)
|
|
411
411
|
_$setProp(_el$2,"wrapMode","none")
|
|
412
412
|
_$setProp(_el$2,"truncate",true)
|
|
413
413
|
_$insert(_el$3,()=>view().value)
|
|
414
414
|
_$insert(_el$2,scale,null)
|
|
415
|
+
_$setProp(_el$4,"width","100%")
|
|
416
|
+
_$setProp(_el$4,"minWidth",0)
|
|
417
|
+
_$setProp(_el$4,"height",1)
|
|
415
418
|
_$setProp(_el$4,"wrapMode","none")
|
|
416
419
|
_$setProp(_el$4,"truncate",true)
|
|
417
420
|
_$insert(_el$4,()=>view().reset)
|
|
@@ -613,7 +616,7 @@ import {insert as _$insert3} from "@opentui/solid"
|
|
|
613
616
|
import {setProp as _$setProp3} from "@opentui/solid"
|
|
614
617
|
import {createElement as _$createElement3} from "@opentui/solid"
|
|
615
618
|
import {SelectionBox} from "./tui.js"
|
|
616
|
-
import {createSignal as
|
|
619
|
+
import {createSignal as createSignal5,onCleanup} from "solid-js"
|
|
617
620
|
function sidebarInteractiveColors(theme,state,normalColor=theme.text,mode="row"){const highlighted=!state.disabled&&(state.focused||mode==="control"&&state.hovered)
|
|
618
621
|
let backgroundColor=theme.backgroundPanel
|
|
619
622
|
let foregroundColor=normalColor
|
|
@@ -629,7 +632,7 @@ else if(highlighted)
|
|
|
629
632
|
foregroundColor=theme.selectedListItemText
|
|
630
633
|
return{backgroundColor,foregroundColor}}
|
|
631
634
|
function useSidebarItem(api,interaction,descriptor,normalColor=()=>api.theme.current.text,mode="row"){let unregister
|
|
632
|
-
const [hovered,setHovered]=
|
|
635
|
+
const [hovered,setHovered]=createSignal5(false)
|
|
633
636
|
const disabled=()=>descriptor.disabled?.()===true
|
|
634
637
|
const focused=()=>Boolean(interaction?.ownsFocus()&&interaction.isSelected(descriptor.id))
|
|
635
638
|
const colors=()=>sidebarInteractiveColors(api.theme.current,{focused:focused(),hovered:hovered(),disabled:disabled()},normalColor(),mode)
|
|
@@ -696,7 +699,7 @@ import {insert as _$insert4} from "@opentui/solid"
|
|
|
696
699
|
import {setProp as _$setProp5} from "@opentui/solid"
|
|
697
700
|
import {createElement as _$createElement5} from "@opentui/solid"
|
|
698
701
|
import {memo as _$memo3} from "@opentui/solid"
|
|
699
|
-
import {createEffect as createEffect2,createSignal as
|
|
702
|
+
import {createEffect as createEffect2,createSignal as createSignal6,on} from "solid-js"
|
|
700
703
|
import {SelectionBox as SelectionBox2} from "./tui.js"
|
|
701
704
|
var graphemes=new Intl.Segmenter(undefined,{granularity:"grapheme"
|
|
702
705
|
})
|
|
@@ -713,7 +716,7 @@ result += segment
|
|
|
713
716
|
}
|
|
714
717
|
return result + ellipsis
|
|
715
718
|
}
|
|
716
|
-
function SectionHeaderControl(props){const [width,setWidth]=
|
|
719
|
+
function SectionHeaderControl(props){const [width,setWidth]=createSignal6()
|
|
717
720
|
const control=useSidebarItem(props.api,props.interaction,{id:props.action.id,position:()=>props.position,disabled:props.action.disabled,activate:props.action.onActivate
|
|
718
721
|
},()=>props.api.theme.current.accent,"control")
|
|
719
722
|
createEffect2(on(()=>[props.action.label(),props.resetWidth],()=>setWidth(undefined)))
|
|
@@ -842,10 +845,10 @@ import {memo as _$memo6} from "@opentui/solid"
|
|
|
842
845
|
import {insert as _$insert7} from "@opentui/solid"
|
|
843
846
|
import {setProp as _$setProp8} from "@opentui/solid"
|
|
844
847
|
import {createElement as _$createElement8} from "@opentui/solid"
|
|
845
|
-
import {Show as Show5,createSignal as
|
|
848
|
+
import {Show as Show5,createSignal as createSignal7} from "solid-js"
|
|
846
849
|
import {SelectionBox as SelectionBox3,useIcons as useIcons4} from "./tui.js"
|
|
847
850
|
function Section(props){const icons=useIcons4()
|
|
848
|
-
const [headerWidth,setHeaderWidth]=
|
|
851
|
+
const [headerWidth,setHeaderWidth]=createSignal7(0)
|
|
849
852
|
const icon=()=>props.section?icons.section(props.section):props.icon
|
|
850
853
|
const theme=()=>props.api.theme.current
|
|
851
854
|
const item=useSidebarItem(props.api,props.interaction,{id:props.sectionId??`section.${props.title}`,position:()=>({section:props.navigationSection??0,row:0,column:0
|
|
@@ -854,7 +857,7 @@ const item=useSidebarItem(props.api,props.interaction,{id:props.sectionId??`sect
|
|
|
854
857
|
return(()=>{var _el$=_$createElement8("box")
|
|
855
858
|
_$setProp8(_el$,"gap",1)
|
|
856
859
|
_$insert7(_el$,_$createComponent11(SelectionBox3,{ref:(node)=>item.ref(node),get id(){return props.sectionId
|
|
857
|
-
},flexDirection:"row",height:1,justifyContent:"space-between",gap:1,
|
|
860
|
+
},flexDirection:"row",height:1,justifyContent:"space-between",gap:1,get backgroundColor(){return item.backgroundColor()
|
|
858
861
|
},get onMouseOver(){return item.onMouseOver
|
|
859
862
|
},get onMouseOut(){return item.onMouseOut
|
|
860
863
|
},onMouseDown:(event)=>item.activate(event),onSizeChange:function(){setHeaderWidth(this.width)
|
|
@@ -949,6 +952,10 @@ _$effect9((_$p)=>_$setProp9(_el$,"fg",props.api.theme.current.textMuted,_$p))
|
|
|
949
952
|
return _el$
|
|
950
953
|
})()
|
|
951
954
|
},children:(selected)=>(()=>{var _el$3=_$createElement9("box")
|
|
955
|
+
_$setProp9(_el$3,"width","100%")
|
|
956
|
+
_$setProp9(_el$3,"minWidth",0)
|
|
957
|
+
_$setProp9(_el$3,"flexShrink",1)
|
|
958
|
+
_$setProp9(_el$3,"overflow","hidden")
|
|
952
959
|
_$insert8(_el$3,_$createComponent12(LimitsModelRow,_$mergeProps(props,{get model(){return selected()
|
|
953
960
|
},get selection(){return props.modelSelection
|
|
954
961
|
}})),null)
|
|
@@ -975,7 +982,7 @@ const model=api.state.session.get(sessionID)?.model
|
|
|
975
982
|
if(!model)
|
|
976
983
|
return
|
|
977
984
|
return{sessionID,providerID:model.providerID,modelID:model.id,...model.variant&&{variant:model.variant}}}
|
|
978
|
-
import {createSignal as
|
|
985
|
+
import {createSignal as createSignal8,untrack as untrack2} from "solid-js"
|
|
979
986
|
var CHATGPT_METHODS=new Set(["chatgpt-browser","chatgpt-headless"])
|
|
980
987
|
function providerAccountIdentity(provider,credentials){if(!provider.integrationID||provider.activation==="disabled")
|
|
981
988
|
return{status:"unsupported"}
|
|
@@ -997,7 +1004,7 @@ const header=Object.entries(provider.headers??{}).find(([name])=>name.toLowerCas
|
|
|
997
1004
|
if(accountID&&header&&header!==accountID)
|
|
998
1005
|
return{status:"loading"}
|
|
999
1006
|
return{status:"ready",id,method:"oauth",providerID,...accountID&&{accountID}}}
|
|
1000
|
-
function createOpenCodeV2AccountSource(context,lifecycle){const [connections,setConnections]=
|
|
1007
|
+
function createOpenCodeV2AccountSource(context,lifecycle){const [connections,setConnections]=createSignal8({})
|
|
1001
1008
|
let generation=0
|
|
1002
1009
|
let disposed=false
|
|
1003
1010
|
let lastModel
|
package/dist/tui.js
CHANGED
|
@@ -3,7 +3,7 @@ import {insert as _$insert,setProp as _$setProp,createElement as _$createElement
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
import {createSignal as createSignal2,createSignal,createEffect,onCleanup,createContext,useContext,createContext as createContext2,createSignal as createSignal3,useContext as useContext2,createEffect as createEffect2,splitProps,untrack,splitProps as splitProps2,For,createEffect as createEffect3,onCleanup as onCleanup2,createEffect as createEffect4,Show,splitProps as splitProps3,createSignal as createSignal4,createSignal as createSignal5,createSignal as createSignal6,onCleanup as onCleanup3,batch,createSignal as createSignal8,createSignal as createSignal7,createEffect as createEffect5,createSignal as createSignal9,onCleanup as onCleanup4,createSignal as createSignal10,createSignal as createSignal11,Index,createSignal as createSignal12,onCleanup as onCleanup5,createEffect as createEffect7,onCleanup as onCleanup7,batch as batch2,createEffect as createEffect6,createMemo,createSignal as createSignal13,onCleanup as onCleanup6,onMount,For as For2,For as For3,Show as Show2,createMemo as createMemo2,Show as Show3,createSignal as createSignal14,onCleanup as onCleanup8,For as For4,For as For5,For as For8,createMemo as createMemo4,onMount as onMount3,For as For7,createMemo as createMemo3,onMount as onMount2,Show as Show5,createEffect as createEffect8,createSignal as createSignal15,onCleanup as onCleanup9,Show as Show4,For as For6,For as For9,createEffect as createEffect9,createMemo as createMemo5,onCleanup as onCleanup10,createEffect as createEffect10,createMemo as createMemo6,untrack as untrack2,For as For10,createEffect as createEffect11,createMemo as createMemo8,onCleanup as onCleanup11,onMount as onMount4,createMemo as createMemo7,Show as Show6,onCleanup as onCleanup12,createEffect as createEffect12,onCleanup as onCleanup13,createSignal as createSignal16,createMemo as createMemo9,createEffect as createEffect13,onCleanup as onCleanup14,onMount as onMount5,onCleanup as onCleanup15,onMount as onMount6,For as For11,createSignal as createSignal17,createSignal as createSignal18,Show as Show7,createSignal as createSignal20,createSignal as createSignal19,onCleanup as onCleanup16,For as For12,Show as Show10,createMemo as createMemo11,createComputed,createMemo as createMemo10,createSignal as createSignal21,untrack as untrack3,Show as Show8,createComputed as createComputed2,untrack as untrack4,Show as Show9,createSignal as createSignal23,createEffect as createEffect14,createSignal as createSignal22,on,createMemo as createMemo13,createSignal as createSignal26,createMemo as createMemo12,For as For13,Show as Show14,Show as Show11,Show as Show12,createSignal as createSignal24,createContext as createContext3,useContext as useContext3,Show as Show13,createSignal as createSignal25,onCleanup as onCleanup17,Show as Show19,createSignal as createSignal27,untrack as untrack5,createSignal as createSignal28,createEffect as createEffect15,For as For14,Show as Show15,Show as Show16,Show as Show17,Show as Show18,For as For15,Show as Show21,createMemo as createMemo15,Show as Show20,createMemo as createMemo14,createSignal as
|
|
6
|
+
import {createSignal as createSignal2,createSignal,createEffect,onCleanup,createContext,useContext,createContext as createContext2,createSignal as createSignal3,useContext as useContext2,createEffect as createEffect2,splitProps,untrack,splitProps as splitProps2,For,createEffect as createEffect3,onCleanup as onCleanup2,createEffect as createEffect4,Show,splitProps as splitProps3,createSignal as createSignal4,createSignal as createSignal5,createSignal as createSignal6,onCleanup as onCleanup3,batch,createSignal as createSignal8,createSignal as createSignal7,createEffect as createEffect5,createSignal as createSignal9,onCleanup as onCleanup4,createSignal as createSignal10,createSignal as createSignal11,Index,createSignal as createSignal12,onCleanup as onCleanup5,createEffect as createEffect7,onCleanup as onCleanup7,batch as batch2,createEffect as createEffect6,createMemo,createSignal as createSignal13,onCleanup as onCleanup6,onMount,For as For2,For as For3,Show as Show2,createMemo as createMemo2,Show as Show3,createSignal as createSignal14,onCleanup as onCleanup8,For as For4,For as For5,For as For8,createMemo as createMemo4,onMount as onMount3,For as For7,createMemo as createMemo3,onMount as onMount2,Show as Show5,createEffect as createEffect8,createSignal as createSignal15,onCleanup as onCleanup9,Show as Show4,For as For6,For as For9,createEffect as createEffect9,createMemo as createMemo5,onCleanup as onCleanup10,createEffect as createEffect10,createMemo as createMemo6,untrack as untrack2,For as For10,createEffect as createEffect11,createMemo as createMemo8,onCleanup as onCleanup11,onMount as onMount4,createMemo as createMemo7,Show as Show6,onCleanup as onCleanup12,createEffect as createEffect12,onCleanup as onCleanup13,createSignal as createSignal16,createMemo as createMemo9,createEffect as createEffect13,onCleanup as onCleanup14,onMount as onMount5,onCleanup as onCleanup15,onMount as onMount6,For as For11,createSignal as createSignal17,createSignal as createSignal18,Show as Show7,createSignal as createSignal20,createSignal as createSignal19,onCleanup as onCleanup16,For as For12,Show as Show10,createMemo as createMemo11,createComputed,createMemo as createMemo10,createSignal as createSignal21,untrack as untrack3,Show as Show8,createComputed as createComputed2,untrack as untrack4,Show as Show9,createSignal as createSignal23,createEffect as createEffect14,createSignal as createSignal22,on,createMemo as createMemo13,createSignal as createSignal26,createMemo as createMemo12,For as For13,Show as Show14,Show as Show11,Show as Show12,createSignal as createSignal24,createContext as createContext3,useContext as useContext3,Show as Show13,createSignal as createSignal25,onCleanup as onCleanup17,Show as Show19,createSignal as createSignal27,untrack as untrack5,createSignal as createSignal28,createSignal as createSignal29,createEffect as createEffect15,For as For14,Show as Show15,Show as Show16,Show as Show17,Show as Show18,For as For15,Show as Show21,createMemo as createMemo15,Show as Show20,createMemo as createMemo14,createSignal as createSignal30,createEffect as createEffect16,onCleanup as onCleanup18,For as For20,Match,Switch,createMemo as createMemo19,onCleanup as onCleanup22,For as For16,Show as Show22,createSignal as createSignal31,createEffect as createEffect17,createMemo as createMemo16,onCleanup as onCleanup19,untrack as untrack6,For as For18,Show as Show25,createEffect as createEffect18,createMemo as createMemo17,createSignal as createSignal32,onCleanup as onCleanup20,untrack as untrack7,For as For17,Show as Show24,Show as Show23,Show as Show29,createEffect as createEffect19,createMemo as createMemo18,createSignal as createSignal33,onCleanup as onCleanup21,untrack as untrack8,For as For19,Show as Show27,Show as Show26,Show as Show28,createEffect as createEffect20,createMemo as createMemo20,onCleanup as onCleanup23,untrack as untrack9,Show as Show30,createMemo as createMemo21,onCleanup as onCleanup24,createEffect as createEffect21,onCleanup as onCleanup25,untrack as untrack10,createSignal as createSignal34,onCleanup as onCleanup26,onMount as onMount7} from "solid-js"
|
|
7
7
|
var SIDEBAR_SECTIONS=["limits","todo","subagents","skills","quick_actions","lsp","mcp"]
|
|
8
8
|
var QUICK_ACTION_IDS=["session.rename","session.timeline","session.copy","session.export","session.compact","session.list","session.new","session.fork","messages.copy","session.first","session.last","session.messages_last_user","session.message.next","session.message.previous","permission.mode"]
|
|
9
9
|
function preferencesScope(path){return path.worktree||path.directory||"global"
|
|
@@ -1337,7 +1337,7 @@ Object.assign(desiredMcpStates,layer.desiredMcpStates)
|
|
|
1337
1337
|
return{behavior,layout:{sections,expanded,order},desiredMcpStates}}
|
|
1338
1338
|
import {randomUUID} from "crypto"
|
|
1339
1339
|
import {link,mkdir,readFile,readdir,rename,rm,unlink,writeFile,readFile as readFile2} from "fs/promises"
|
|
1340
|
-
import {join,dirname,join as join2,join as join3
|
|
1340
|
+
import {join,dirname,join as join2,join as join3} from "path"
|
|
1341
1341
|
var LOCK_TIMEOUT_MS=3000
|
|
1342
1342
|
function errno(error,code){return error instanceof Error&&"code" in error&&error.code===code
|
|
1343
1343
|
}
|
|
@@ -2904,7 +2904,7 @@ return{groups,rows:groups.flatMap((group)=>group.items.map((item)=>({item,group:
|
|
|
2904
2904
|
|
|
2905
2905
|
function KeyboardHelpDialog(props){const icons=useIcons()
|
|
2906
2906
|
const theme=()=>props.api.theme.current
|
|
2907
|
-
const hints=()=>[`${icons.key("up")}/k and ${icons.key("down")}/j move \xB7 ${icons.key("enter")} activates`,`${icons.key("enter")} on a filter starts typing \xB7 ${icons.key("esc")} returns`,`Todo: ${icons.key("enter")} on All / Active / Finished changes the view`,`MCP: ${icons.key("enter")} toggles a group`,"Show all / Show less expands or limits the filtered list",`Skills: ${icons.icon("info")} opens source \xB7 ${icons.icon("recent")} marks recent skills`,"Navigator Settings: Ctrl+,",`Search Everything: shortcut in Settings ${icons.icon("right")} Behavior`,`Search: type \xB7 ${icons.key("up/down")} results \xB7 ${icons.key("tab/shift+tab")} tabs \xB7 ${icons.key("enter")} run`,`${icons.key("esc")} leaves the sidebar \xB7 ${icons.key("?")} opens this help`]
|
|
2907
|
+
const hints=()=>[`${icons.key("up")}/k and ${icons.key("down")}/j move \xB7 ${icons.key("enter")} activates`,`${icons.key("enter")} on a filter starts typing \xB7 ${icons.key("esc")} returns`,`Todo: ${icons.key("enter")} on All / Active / Finished changes the view`,`MCP: ${icons.key("enter")} toggles a group`,"Show all / Show less expands or limits the filtered list",`Skills: ${icons.icon("info")} opens source \xB7 ${icons.icon("recent")} marks recent skills`,"Navigator Settings: Ctrl+,","Navigator shortcuts: c checks for updates \xB7 u updates Navigator after confirmation",`Search Everything: shortcut in Settings ${icons.icon("right")} Behavior`,`Search: type \xB7 ${icons.key("up/down")} results \xB7 ${icons.key("tab/shift+tab")} tabs \xB7 ${icons.key("enter")} run`,`${icons.key("esc")} leaves the sidebar \xB7 ${icons.key("?")} opens this help`]
|
|
2908
2908
|
return _$createComponent(DialogSurface,{get api(){return props.api
|
|
2909
2909
|
},get children(){return [(()=>{var _el$=_$createElement("text"),_el$2=_$createTextNode(` Navigator keyboard help`)
|
|
2910
2910
|
_$insertNode(_el$,_el$2)
|
|
@@ -4901,27 +4901,6 @@ clearTimeout(pending)
|
|
|
4901
4901
|
return _$createElement("box")
|
|
4902
4902
|
}
|
|
4903
4903
|
|
|
4904
|
-
var NAVIGATOR_PACKAGE_URL="https://registry.npmjs.org/opencode-navigator/latest"
|
|
4905
|
-
var REQUEST_TIMEOUT_MS=5000
|
|
4906
|
-
function createVersionStatus(api,navigatorVersion,request=fetch){const [openCodeUpdate,setOpenCodeUpdate]=createSignal17()
|
|
4907
|
-
const [navigatorUpdate,setNavigatorUpdate]=createSignal17()
|
|
4908
|
-
const controller=new AbortController
|
|
4909
|
-
const timeout=setTimeout(()=>controller.abort(),REQUEST_TIMEOUT_MS)
|
|
4910
|
-
const unsubscribe=api.event.on("installation.update-available",(event)=>{const version=event.properties.version
|
|
4911
|
-
setOpenCodeUpdate(isNewerVersion(version,api.app.version)?version:undefined)
|
|
4912
|
-
})
|
|
4913
|
-
api.lifecycle.onDispose(()=>{clearTimeout(timeout)
|
|
4914
|
-
controller.abort()
|
|
4915
|
-
unsubscribe()
|
|
4916
|
-
})
|
|
4917
|
-
request(NAVIGATOR_PACKAGE_URL,{headers:{accept:"application/json"},signal:controller.signal
|
|
4918
|
-
}).then(async (response)=>{if(!response.ok)
|
|
4919
|
-
return
|
|
4920
|
-
const metadata=await response.json()
|
|
4921
|
-
if(typeof metadata.version==="string")
|
|
4922
|
-
setNavigatorUpdate(isNewerVersion(metadata.version,navigatorVersion)?metadata.version:undefined)
|
|
4923
|
-
}).catch(()=>{}).finally(()=>clearTimeout(timeout))
|
|
4924
|
-
return{openCodeUpdate,navigatorUpdate}}
|
|
4925
4904
|
|
|
4926
4905
|
|
|
4927
4906
|
|
|
@@ -5011,39 +4990,6 @@ return _el$
|
|
|
5011
4990
|
})()
|
|
5012
4991
|
}
|
|
5013
4992
|
|
|
5014
|
-
function createVersionUpdateActions(api,status,updater,rememberNavigatorVersion){const busy=new Set
|
|
5015
|
-
function target(kind){return kind==="openCode"?status.openCodeUpdate():status.navigatorUpdate()
|
|
5016
|
-
}
|
|
5017
|
-
function label(kind){return kind==="openCode"?"OpenCode":"Navigator"
|
|
5018
|
-
}
|
|
5019
|
-
function update(kind,version){if(busy.has(kind))
|
|
5020
|
-
return
|
|
5021
|
-
api.ui.dialog.clear()
|
|
5022
|
-
busy.add(kind)
|
|
5023
|
-
api.ui.toast({variant:"info",title:`Updating ${label(kind)}`,message:`Installing ${version}...`
|
|
5024
|
-
});
|
|
5025
|
-
(async ()=>{if(kind==="navigator")
|
|
5026
|
-
await rememberNavigatorVersion?.()
|
|
5027
|
-
await updater[kind](version)
|
|
5028
|
-
})().then(()=>{api.ui.toast({variant:"success",title:`${label(kind)} updated`,message:"Restart OpenCode to use the new version.",duration:6000
|
|
5029
|
-
})
|
|
5030
|
-
}).catch((error)=>{api.ui.toast({variant:"error",title:`Could not update ${label(kind)}`,message:error instanceof Error?error.message:"Update failed",duration:6000
|
|
5031
|
-
})
|
|
5032
|
-
}).finally(()=>busy.delete(kind))
|
|
5033
|
-
}
|
|
5034
|
-
function open(kind,version=target(kind)){if(!version||busy.has(kind))
|
|
5035
|
-
return
|
|
5036
|
-
api.ui.dialog.replace(()=>_$createComponent(api.ui.DialogConfirm,{get title(){return `Update ${label(kind)}`
|
|
5037
|
-
},message:`Update to ${version} using the current installation method? OpenCode must be restarted afterward.`,onConfirm:()=>update(kind,version),onCancel:()=>api.ui.dialog.clear()
|
|
5038
|
-
}))
|
|
5039
|
-
}
|
|
5040
|
-
const unregister=api.keymap.registerLayer({commands:[{name:`${PLUGIN_ID}.update-opencode`,title:"Update OpenCode",category:"Navigator",namespace:"palette",enabled:()=>Boolean(target("openCode"))&&!busy.has("openCode"),run:()=>open("openCode")
|
|
5041
|
-
},{name:`${PLUGIN_ID}.update-navigator`,title:"Update Navigator",category:"Navigator",namespace:"palette",enabled:()=>Boolean(target("navigator"))&&!busy.has("navigator"),run:()=>open("navigator")
|
|
5042
|
-
}]
|
|
5043
|
-
})
|
|
5044
|
-
api.lifecycle.onDispose(unregister)
|
|
5045
|
-
return{openCode:(version)=>open("openCode",version),navigator:(version)=>open("navigator",version)
|
|
5046
|
-
}}
|
|
5047
4993
|
function matchesFilter(query,...values){const needle=query.trim().toLocaleLowerCase()
|
|
5048
4994
|
return !needle||values.some((value)=>value?.toLocaleLowerCase().includes(needle))
|
|
5049
4995
|
}
|
|
@@ -5520,7 +5466,7 @@ const item=useSidebarItem(props.api,props.interaction,{id:props.sectionId??`sect
|
|
|
5520
5466
|
return(()=>{var _el$=_$createElement("box")
|
|
5521
5467
|
_$setProp(_el$,"gap",1)
|
|
5522
5468
|
_$insert(_el$,_$createComponent(SelectionBox,{ref:(node)=>item.ref(node),get id(){return props.sectionId
|
|
5523
|
-
},flexDirection:"row",height:1,justifyContent:"space-between",gap:1,
|
|
5469
|
+
},flexDirection:"row",height:1,justifyContent:"space-between",gap:1,get backgroundColor(){return item.backgroundColor()
|
|
5524
5470
|
},get onMouseOver(){return item.onMouseOver
|
|
5525
5471
|
},get onMouseOut(){return item.onMouseOut
|
|
5526
5472
|
},onMouseDown:(event)=>item.activate(event),onSizeChange:function(){setHeaderWidth(this.width)
|
|
@@ -6209,13 +6155,14 @@ return _$createComponent(SectionWithHeaderAction,{get api(){return props.api
|
|
|
6209
6155
|
|
|
6210
6156
|
|
|
6211
6157
|
|
|
6158
|
+
|
|
6212
6159
|
|
|
6213
6160
|
|
|
6214
6161
|
function QuickActionRow(props){const{api,interaction
|
|
6215
6162
|
}=useSidebarList()
|
|
6216
6163
|
const icons=useIcons()
|
|
6217
6164
|
const theme=()=>api.theme.current
|
|
6218
|
-
const [width,setWidth]=
|
|
6165
|
+
const [width,setWidth]=createSignal30(0)
|
|
6219
6166
|
const shortcut=createMemo14(()=>{const bindings=api.keymap.getCommandBindings({visibility:"registered",commands:[props.action.command]
|
|
6220
6167
|
})
|
|
6221
6168
|
return api.keys.formatBindings(bindings.get(props.action.command))
|
|
@@ -6362,8 +6309,9 @@ var ENTRY_COMMAND=`${PLUGIN_ID}.sidebar-shortcuts.enter`
|
|
|
6362
6309
|
var CANCEL_COMMAND=`${PLUGIN_ID}.sidebar-shortcuts.cancel`
|
|
6363
6310
|
var MODE=`${PLUGIN_ID}.sidebar-shortcuts`
|
|
6364
6311
|
var DEFAULT_TIMEOUT_MS=5000
|
|
6365
|
-
var ACTIONS=[{key:"h",command:"session.sidebar.toggle",section:undefined},{key:"t",command:`${PLUGIN_ID}.focus.todo`,section:"todo"},{key:"a",command:`${PLUGIN_ID}.focus.subagents`,section:"subagents"},{key:"s",command:`${PLUGIN_ID}.focus.skills`,section:"skills"},{key:"q",command:`${PLUGIN_ID}.focus.quick_actions`,section:"quick_actions"},{key:"l",command:`${PLUGIN_ID}.focus.lsp`,section:"lsp"},{key:"m",command:`${PLUGIN_ID}.focus.mcp`,section:"mcp"}]
|
|
6312
|
+
var ACTIONS=[{key:"h",hint:"toggle",command:"session.sidebar.toggle",section:undefined},{key:"t",hint:"todo",command:`${PLUGIN_ID}.focus.todo`,section:"todo"},{key:"a",hint:"agents",command:`${PLUGIN_ID}.focus.subagents`,section:"subagents"},{key:"s",hint:"skills",command:`${PLUGIN_ID}.focus.skills`,section:"skills"},{key:"q",hint:"actions",command:`${PLUGIN_ID}.focus.quick_actions`,section:"quick_actions"},{key:"l",hint:"LSP",command:`${PLUGIN_ID}.focus.lsp`,section:"lsp"},{key:"m",hint:"MCP",command:`${PLUGIN_ID}.focus.mcp`,section:"mcp"},{key:"c",hint:"check update",command:`${PLUGIN_ID}.check-update`,section:undefined},{key:"u",hint:"update",command:`${PLUGIN_ID}.update-navigator`,section:undefined}]
|
|
6366
6313
|
function createSidebarShortcutMode(api,options={}){const actions=ACTIONS.filter(({section})=>!section||supportsSidebarSection(api,section))
|
|
6314
|
+
const hints=actions.map(({key,hint})=>`${key} ${hint}`).join(" | ")
|
|
6367
6315
|
const timeoutMs=options.timeoutMs??DEFAULT_TIMEOUT_MS
|
|
6368
6316
|
let shortcutKey=""
|
|
6369
6317
|
let unregisterBinding
|
|
@@ -6390,7 +6338,7 @@ unregisterMode=api.keymap.registerLayer({mode:MODE,priority:2000,commands:[{name
|
|
|
6390
6338
|
})
|
|
6391
6339
|
leaveMode=api.mode.push(MODE)
|
|
6392
6340
|
timeout=setTimeout(cancel,timeoutMs)
|
|
6393
|
-
api.ui?.toast?.({variant:"info",title:"Navigator shortcuts",message
|
|
6341
|
+
api.ui?.toast?.({variant:"info",title:"Navigator shortcuts",message:`${hints} | Esc cancel`,duration:timeoutMs
|
|
6394
6342
|
})
|
|
6395
6343
|
return true
|
|
6396
6344
|
}
|
|
@@ -6510,7 +6458,7 @@ return _el$
|
|
|
6510
6458
|
}})
|
|
6511
6459
|
}
|
|
6512
6460
|
function SkillsSection(props){const dialogs=useDialogs(props.api)
|
|
6513
|
-
const [query,setQuery]=
|
|
6461
|
+
const [query,setQuery]=createSignal31("")
|
|
6514
6462
|
const model=createSkillSectionModel(props,query)
|
|
6515
6463
|
const navigationSection=()=>props.navigationSection??3
|
|
6516
6464
|
function selectSkill(item){if(!props.preferences.shouldConfirmSkill(item)){model.useSkill(item)
|
|
@@ -6599,8 +6547,8 @@ return _el$
|
|
|
6599
6547
|
function createSubagentSectionModel(props){const list=createMemo17(()=>props.controller.list(props.sessionID))
|
|
6600
6548
|
const recent=createMemo17(()=>props.controller.recent?.(props.sessionID)??[])
|
|
6601
6549
|
const rows=createMemo17(()=>buildSubagentView(list(),recent()))
|
|
6602
|
-
const [query,setQuery]=
|
|
6603
|
-
const [mode,setMode]=
|
|
6550
|
+
const [query,setQuery]=createSignal32("")
|
|
6551
|
+
const [mode,setMode]=createSignal32("all")
|
|
6604
6552
|
const counts=createMemo17(()=>countSubagentView(rows(),query()))
|
|
6605
6553
|
const tabs=createMemo17(()=>["all","active","recent",...counts().errors>0?["errors"]:[]])
|
|
6606
6554
|
const filtered=createMemo17(()=>filterSubagentView(rows(),mode(),query()))
|
|
@@ -6974,7 +6922,7 @@ function TodoSection(props){const list=createMemo18(()=>props.controller.list(pr
|
|
|
6974
6922
|
const icons=useIcons()
|
|
6975
6923
|
const unavailable=()=>hostCapabilityUnavailable(props.api,"todo")
|
|
6976
6924
|
const managed=()=>("guidance" in props.controller)?props.controller:undefined
|
|
6977
|
-
const [mode,setMode]=
|
|
6925
|
+
const [mode,setMode]=createSignal33("all")
|
|
6978
6926
|
const targetKey=createMemo18(()=>props.controller.target?.(props.sessionID).key??props.sessionID)
|
|
6979
6927
|
createEffect19(()=>{targetKey()
|
|
6980
6928
|
setMode("all")
|
|
@@ -7220,7 +7168,7 @@ props.controller.refresh()
|
|
|
7220
7168
|
onCleanup25(()=>clearInterval(timer))
|
|
7221
7169
|
return _$createElement("box")
|
|
7222
7170
|
}
|
|
7223
|
-
import {homedir
|
|
7171
|
+
import {homedir} from "os"
|
|
7224
7172
|
|
|
7225
7173
|
function location(input){return input.directory?{location:{directory:input.directory}}:{}}
|
|
7226
7174
|
function mcpItem(server){return{name:server.name,status:server.status.status,...server.status.error&&{error:server.status.error}}}
|
|
@@ -7313,7 +7261,7 @@ return false
|
|
|
7313
7261
|
}
|
|
7314
7262
|
function enabled(value){return typeof value==="function"?value():value!==false
|
|
7315
7263
|
}
|
|
7316
|
-
function createV2Keymap(context){const [revision,setRevision]=
|
|
7264
|
+
function createV2Keymap(context){const [revision,setRevision]=createSignal34(0)
|
|
7317
7265
|
const layers=new Map
|
|
7318
7266
|
let sequence=0
|
|
7319
7267
|
function layerActive(layer){const mode=layer.mode??"base"
|
|
@@ -7510,72 +7458,9 @@ for(let index=disposers.length-1;index>=0; index--)
|
|
|
7510
7458
|
await disposers[index]()
|
|
7511
7459
|
disposers.length=0
|
|
7512
7460
|
}}}
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
import {fileURLToPath} from "url"
|
|
7516
|
-
var run=async (command)=>{const child=Bun.spawn([...command],{stdout:"ignore",stderr:"pipe"})
|
|
7517
|
-
const error=new Response(child.stderr).text()
|
|
7518
|
-
const exitCode=await child.exited
|
|
7519
|
-
if(exitCode===0)
|
|
7520
|
-
return
|
|
7521
|
-
const message=await error
|
|
7522
|
-
throw new Error(message.trim()||`Command failed with exit code ${child.exitCode}`)
|
|
7523
|
-
}
|
|
7524
|
-
var readConfig=async (path)=>{const file=Bun.file(path)
|
|
7525
|
-
return await file.exists()?Bun.JSONC.parse(await file.text()):undefined
|
|
7461
|
+
function loadNavigatorUpdates(){const path=import.meta.url.includes("/dist/tui.js")?"./navigator-updates.js":"../navigator-updates"
|
|
7462
|
+
return import(path)
|
|
7526
7463
|
}
|
|
7527
|
-
function pinnedUpdate(wrapper,target,execute){if(basename(wrapper)!=="tui.js"||basename(dirname2(wrapper))!=="opencode-navigator")
|
|
7528
|
-
throw new Error("Unrecognized local Navigator source")
|
|
7529
|
-
const installer=fileURLToPath(new URL("../scripts/update-local-snapshot.mjs",import.meta.url))
|
|
7530
|
-
return execute(["node",installer,wrapper,target])
|
|
7531
|
-
}
|
|
7532
|
-
function configHasPlugin(value,spec){if(!value||typeof value!=="object")
|
|
7533
|
-
return false
|
|
7534
|
-
const plugins=value.plugin
|
|
7535
|
-
return Array.isArray(plugins)&&plugins.some((item)=>{let configured=item
|
|
7536
|
-
if(Array.isArray(item))
|
|
7537
|
-
configured=item[0]
|
|
7538
|
-
else if(item&&typeof item==="object")
|
|
7539
|
-
configured=item.package
|
|
7540
|
-
return configured===spec
|
|
7541
|
-
})
|
|
7542
|
-
}
|
|
7543
|
-
async function v1Global(api,spec,read){const configRoot=process.env.OPENCODE_CONFIG_DIR??join4(process.env.XDG_CONFIG_HOME??join4(homedir2(),".config"),"opencode")
|
|
7544
|
-
const global=join4(configRoot,"tui.json")
|
|
7545
|
-
const configured=api.state.path.config.endsWith(".json")?api.state.path.config:join4(api.state.path.config,"tui.json")
|
|
7546
|
-
const local=new Set([configured,join4(api.state.path.worktree,".opencode","tui.json")])
|
|
7547
|
-
local.delete(global)
|
|
7548
|
-
for(const path of local)
|
|
7549
|
-
if(configHasPlugin(await read(path),spec))
|
|
7550
|
-
return false
|
|
7551
|
-
return configHasPlugin(await read(global),spec)
|
|
7552
|
-
}
|
|
7553
|
-
function createOpenCodeV1VersionUpdater(api,meta,execute=run,read=readConfig){return{openCode:(target)=>execute([process.execPath,"upgrade",target]),async navigator(target){if(meta.source==="file"){const wrapper=meta.spec.startsWith("file://")?fileURLToPath(meta.spec):meta.spec
|
|
7554
|
-
return pinnedUpdate(wrapper,target,execute)
|
|
7555
|
-
}
|
|
7556
|
-
if(meta.source!=="npm")
|
|
7557
|
-
throw new Error("Unrecognized local Navigator source")
|
|
7558
|
-
const result=await api.plugins.install(`opencode-navigator@${target}`,{global:await v1Global(api,meta.spec,read)
|
|
7559
|
-
})
|
|
7560
|
-
if(!result.ok)
|
|
7561
|
-
throw new Error(result.message)
|
|
7562
|
-
}}}
|
|
7563
|
-
function createOpenCodeV2VersionUpdater(context,execute=run){return{openCode:(target)=>execute([process.execPath,"upgrade",target]),async navigator(target){const response=await context.client.plugin.list(context.location?{location:context.location}:{})
|
|
7564
|
-
const item=response.data.find((plugin)=>plugin.id===PLUGIN_ID)
|
|
7565
|
-
if(!item)
|
|
7566
|
-
throw new Error("Navigator is not in the active plugin list")
|
|
7567
|
-
if(item.source.type==="local")
|
|
7568
|
-
return pinnedUpdate(basename(item.source.path)==="tui.js"?item.source.path:join4(item.source.path,"tui.js"),target,execute)
|
|
7569
|
-
if(item.source.type!=="package")
|
|
7570
|
-
throw new Error("Unrecognized local Navigator source")
|
|
7571
|
-
if(isAbsolute(item.source.target))
|
|
7572
|
-
return pinnedUpdate(join4(item.source.target,"tui.js"),target,execute)
|
|
7573
|
-
if(item.source.target.startsWith("file://"))
|
|
7574
|
-
return pinnedUpdate(join4(fileURLToPath(item.source.target),"tui.js"),target,execute)
|
|
7575
|
-
if(item.source.target.startsWith("."))
|
|
7576
|
-
throw new Error("Unrecognized local Navigator source")
|
|
7577
|
-
await context.client.plugin.update({location:response.location,targets:[item.source.target]})
|
|
7578
|
-
}}}
|
|
7579
7464
|
async function setupNavigator(api,options,readProject,managedTodo,hostContext){const config=pluginConfig(undefined)
|
|
7580
7465
|
const configured=await loadConfiguredDefaults(api,options,readProject)
|
|
7581
7466
|
const todo=managedTodo??createTodoController(api)
|
|
@@ -7586,7 +7471,7 @@ const limitsPath=import.meta.url.includes("/dist/tui.js")?"./provider-limits.js"
|
|
|
7586
7471
|
const limitsModule=await import(limitsPath)
|
|
7587
7472
|
const LimitsSection=limitsModule.ProviderLimitsSection
|
|
7588
7473
|
const{controller:limits,codex,accountSource,selectModel,modelSelection
|
|
7589
|
-
}=limitsModule.createProviderQuotaIntegration(api,preferences,"0.21.
|
|
7474
|
+
}=limitsModule.createProviderQuotaIntegration(api,preferences,"0.21.4",hostContext)
|
|
7590
7475
|
const mcp=createMcpController(api,preferences.persistMcp,preferences)
|
|
7591
7476
|
const interaction=createSidebarInteraction(api,()=>openKeyboardHelp(api,preferences.lspIconStyle,preferences.cornerFont))
|
|
7592
7477
|
const startup=createStartupSessionController(api,preferences)
|
|
@@ -7614,7 +7499,7 @@ api.slots.register({order:100,slots:{app(){return _$createComponent(IconProvider
|
|
|
7614
7499
|
},interaction,skills,subagents,mcp
|
|
7615
7500
|
}),_$createComponent(FirstRunWizardPersistence,{api,preferences
|
|
7616
7501
|
}),_$createComponent(StartupSessionBinding,{api,controller:startup
|
|
7617
|
-
}),_$createComponent(UpgradeNotesBinding,{api,preferences,version:"0.21.
|
|
7502
|
+
}),_$createComponent(UpgradeNotesBinding,{api,preferences,version:"0.21.4"
|
|
7618
7503
|
}),_$createComponent(McpPersistence,{api,controller:mcp
|
|
7619
7504
|
})]
|
|
7620
7505
|
}})
|
|
@@ -7645,12 +7530,14 @@ throw result.error
|
|
|
7645
7530
|
}
|
|
7646
7531
|
return result.data?.type==="text"?result.data.content:undefined
|
|
7647
7532
|
})
|
|
7648
|
-
const
|
|
7649
|
-
|
|
7533
|
+
const{createVersionStatus,createVersionUpdateActions,createOpenCodeV1VersionUpdater
|
|
7534
|
+
}=await loadNavigatorUpdates()
|
|
7535
|
+
const versionStatus=createVersionStatus(api,"0.21.4")
|
|
7536
|
+
const versionUpdates=createVersionUpdateActions(api,versionStatus,createOpenCodeV1VersionUpdater(api,meta),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.21.4"))
|
|
7650
7537
|
api.slots.register({order:90,slots:{sidebar_footer(_context,props){return _$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
|
|
7651
7538
|
},get multilineCorners(){return preferences.cornerFont
|
|
7652
7539
|
},get children(){return _$createComponent(VersionFooter,{api,get sessionID(){return props.session_id
|
|
7653
|
-
},navigatorVersion:"0.21.
|
|
7540
|
+
},navigatorVersion:"0.21.4",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
|
|
7654
7541
|
},get onNavigatorUpdate(){return versionUpdates.navigator
|
|
7655
7542
|
}})
|
|
7656
7543
|
}})
|
|
@@ -7664,15 +7551,17 @@ return
|
|
|
7664
7551
|
return new TextDecoder().decode(await context.client.file.read({location:context.location,path:".opencode/navigator.json"
|
|
7665
7552
|
}))
|
|
7666
7553
|
},todo,context)
|
|
7667
|
-
const
|
|
7668
|
-
|
|
7554
|
+
const{createVersionStatus,createVersionUpdateActions,createOpenCodeV2VersionUpdater
|
|
7555
|
+
}=await loadNavigatorUpdates()
|
|
7556
|
+
const versionStatus=createVersionStatus(adapter.api,"0.21.4")
|
|
7557
|
+
const versionUpdates=createVersionUpdateActions(adapter.api,versionStatus,createOpenCodeV2VersionUpdater(context),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.21.4"))
|
|
7669
7558
|
const disposeFooter=context.ui.slot({append:"sidebar.footer",render:()=>_$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
|
|
7670
7559
|
},get multilineCorners(){return preferences.cornerFont
|
|
7671
7560
|
},get children(){var _el$=_$createElement("box")
|
|
7672
7561
|
_$setProp(_el$,"flexDirection","row")
|
|
7673
7562
|
_$setProp(_el$,"justifyContent","space-between")
|
|
7674
7563
|
_$insert(_el$,_$createComponent(VersionSummary,{get api(){return adapter.api
|
|
7675
|
-
},navigatorVersion:"0.21.
|
|
7564
|
+
},navigatorVersion:"0.21.4",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
|
|
7676
7565
|
},get onNavigatorUpdate(){return versionUpdates.navigator
|
|
7677
7566
|
}}),null)
|
|
7678
7567
|
_$insert(_el$,_$createComponent(SettingsFooterButton,{get api(){return adapter.api
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "opencode-navigator",
|
|
4
|
-
"version": "0.21.
|
|
4
|
+
"version": "0.21.4",
|
|
5
5
|
"description": "Search, navigate, and manage OpenCode sessions from the TUI",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"packageManager": "bun@1.4.2",
|