opencode-navigator 0.27.3 → 0.27.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.27.5] - 2026-11-12
4
+
5
+ - Show quota remaining and blue time-remaining scales in Limits, with live reset countdowns. Quota pace turns yellow, orange or red when the allowance is running ahead of the period; missing provider dates or durations stay explicit.
6
+ - Show the available Banked Resets count and separate compact credit cards with icons, readable expiry and provider details on demand. Credit use still needs a separate confirmation.
7
+ - Add native icons beside Desktop sidebar section titles, independently of their disclosure arrows.
8
+ - Combine About's update check, update offer, installation progress and restart guidance in one stable control. Fix skipped exact-version checks and the historical plugin-ID lookup while preserving the installation source and configuration options.
9
+ - Recognize ChatGPT token-sharing connections and allow an explicit Codex account link without treating the client ID as an account identity.
10
+ - Preserve native confirmation results and externally opened dialogs when returning to Navigator in OpenCode 2.
11
+
12
+ ## [0.27.4] - 2026-11-12
13
+
14
+ - Show banked-reset expiry progress in the terminal, with readable remaining time and explicit missing or invalid dates. Keep credit use separately confirmed.
15
+ - Use native Desktop switches for individual MCP connections, whole groups and Search Everything results, with pending feedback and separate error information.
16
+ - Split Desktop Settings into Layout, Behavior, Quick Actions, Skills, MCP, Presets and About categories. Keep scoped preferences, existing actions and unsaved drafts when switching categories.
17
+ - Move between Desktop category buttons with Left/Right from the currently focused button, even when it is not the selected category.
18
+
3
19
  ## [0.27.3] - 2026-11-12
4
20
 
5
21
  - Keep the Desktop session title on its own full-width row in both the panel and floating mini-window, with readable wrapping instead of squeezing it between action labels.
package/HOST_API.md CHANGED
@@ -67,6 +67,12 @@ icon. Those focused semantic controls remain plugin-owned, using the host theme'
67
67
  surface, text, focus and elevation tokens. Remove these fallbacks when equivalent
68
68
  public controls preserve their multiline, expanded/selected and progress semantics.
69
69
 
70
+ Reset-credit cards are semantic list-item layouts with host-themed borders; the
71
+ public facade has no generic card component. Their actions, detail disclosure and
72
+ icons use public `Ui.Button` and `Ui.Icon`. Expiry progress keeps the existing
73
+ provider-timestamp model and accessible progress semantics rather than implying
74
+ that a missing date means unlimited credit lifetime.
75
+
70
76
  Desktop model and reasoning-effort selection belongs to the native chat controls.
71
77
  Navigator does not duplicate these selectors in its sidebar. Limits continue to
72
78
  follow the host's reactive selected model; the TUI retains its model/variant controls.
@@ -78,6 +84,16 @@ list row: the host requires it to render inside a menu. Section disclosure keeps
78
84
  `aria-expanded` on its semantic button and uses a native icon with fixed geometry.
79
85
  Revisit these wrappers when the host exposes equivalent accessible components.
80
86
 
87
+ Desktop's Extensions page does have native pill tabs: the packaged 2.2.6 renderer
88
+ uses its internal Tabs root, List, Trigger and Content components. They are not
89
+ exported by the plugin UI facade. Navigator therefore composes its category
90
+ navigation from public small neutral/ghost-muted Buttons, matching its Todo filters,
91
+ without importing the private Tabs module or copying the host DOM. Settings panels
92
+ mount on first visit and remain hidden rather than unmounting on category changes,
93
+ preserving drafts. Settings search passes the public `SettingsPage.render.target`
94
+ through to reveal the Behavior category for the registered entries. Replace this
95
+ wrapper when public tabs support selection, keyboard navigation and retained panels.
96
+
81
97
  The native Todo popover has no public content slot. Composer pill contributions
82
98
  are adjacent pills, not extensions of native Todo, so Navigator cannot add search
83
99
  or tabs there through Desktop 2.2.6's public API. Its read-only Todo rows follow
@@ -163,6 +179,7 @@ justify bypassing a native API.
163
179
  | Console/Go request lifecycle and projection | `client.experimental.usage.limits` is public, but the internal usage cache and budget selectors are not in published Plugin Context. Workspace IDs are not provider account IDs. | Equivalent public cache and selector on the plugin interface. |
164
180
  | External quotas / reset credits | Console/Go is not a universal provider API and has no Codex reset-credit consume operation. Sources stay documented, account-bound and portable. Native auth/request errors never enable a bypass reader. | Host APIs matching provider/account/units/resets and idempotent consume semantics. |
165
181
  | Pinned-file snapshot installer | Native package updates do not implement the recognized versioned wrapper/staging layout. Preserve installation source and scope. | A public atomic file-snapshot update API with equivalent verification. |
182
+ | Exact npm revision updates | Native `plugin.check`/`plugin.update` skip exact revisions. After a successful native check, query the public npm latest record; confirmed updates replace only the owning JSONC string, retaining options and scope. TUI uses its global `cli.json` first; server-owned entries use public server file APIs. Reject ambiguous owners, changed files, clients and locations. Server writes have no CAS: preflight checks and readback are safeguards, not an atomic transaction. A changed pin is prepared configuration, not evidence that the new runtime is loaded. | A native exact-revision update API preserving source, options, scope and stale-target protection. |
166
183
  | Corner masks and product UI | Multiline shape, three-cell controls, filters, groups, presets and pins are product features. Paint hooks only draw; scroll restoration runs outside paint. | Equivalent public primitives preserving geometry, behavior and fallback mode. |
167
184
 
168
185
  ## Unavailable Features
package/PROVIDERS.md CHANGED
@@ -85,6 +85,10 @@ network failure does not switch to a credential-based or external reader.
85
85
  - OpenCode 2 metadata matching uses public provider/credential APIs and the built-in
86
86
  ChatGPT OAuth `metadata.accountID`. Account IDs are compared with Codex's own
87
87
  reported identity; a provider name or model-name similarity is not proof.
88
+ - ChatGPT token-sharing OAuth is recognized, but its `metadata.clientID` is not an
89
+ account ID. Without `accountID`, explicitly confirm the Codex account link once
90
+ per connection. The displayed quotas belong to that Codex account, not a separately
91
+ verified token-sharing allowance.
88
92
  - A confirmation is saved once per connection, or per provider when the host has
89
93
  no connection API. Models do not need separate confirmations. Conflicting older
90
94
  model-specific records remain isolated until an explicit relink.
package/README.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # OpenCode Navigator
2
2
 
3
+ [![GitHub Release](https://img.shields.io/github/v/release/St1ggy/opencode-navigator?display_name=tag&label=release)](https://github.com/St1ggy/opencode-navigator/releases/latest)
4
+ [![CI: tests, builds, types, lint and host smokes](https://github.com/St1ggy/opencode-navigator/actions/workflows/ci.yml/badge.svg?branch=main&event=push)](https://github.com/St1ggy/opencode-navigator/actions/workflows/ci.yml)
5
+ [![Publish](https://github.com/St1ggy/opencode-navigator/actions/workflows/publish.yml/badge.svg?event=release)](https://github.com/St1ggy/opencode-navigator/actions/workflows/publish.yml)
6
+ [![License](https://img.shields.io/github/license/St1ggy/opencode-navigator)](LICENSE)
7
+
8
+ [![OpenCode 1.x compatibility](https://img.shields.io/badge/OpenCode%201.x-1.19.5-4c8bf5)](#installation)
9
+ [![OpenCode 2.x compatibility](https://img.shields.io/badge/OpenCode%202.x-2.2.6-4c8bf5)](#installation)
10
+ [![Desktop experimental](https://img.shields.io/badge/Desktop-experimental-orange)](#experimental-opencode-desktop)
11
+ [![Monthly npm downloads](https://img.shields.io/npm/dm/opencode-navigator?label=npm%20downloads%2Fmonth)](https://www.npmjs.com/package/opencode-navigator)
12
+
13
+ [Unit coverage reports](https://github.com/St1ggy/opencode-navigator/actions/workflows/ci.yml)
14
+
3
15
  Search, navigate, and manage OpenCode sessions from the TUI, with an experimental
4
16
  OpenCode Desktop interface. Navigator combines
5
17
  Search Everything, task and subagent views, skills, MCP presets, and quick actions
@@ -309,9 +321,14 @@ contains independent TUI, server, RPC and GUI entries.
309
321
  Familiar actions use native icon buttons with tooltips and accessible names;
310
322
  account linking, Banked Resets and other ambiguous operations retain text.
311
323
  - **Navigator settings** opens native Settings with Global/Worktree scope,
312
- section controls, groups, trust, presets, portable/project profiles, About,
313
- release history and reviewed Bug reports. **Reload preferences** imports
324
+ categories for Layout, Behavior, Quick Actions, Skills, MCP, Presets and About.
325
+ Groups, trust, portable/project profiles, release history and reviewed Bug
326
+ reports remain available. Category changes preserve unsaved drafts; Left/Right
327
+ navigates the category buttons. **Reload preferences** imports
314
328
  changes from other local Navigator instances explicitly.
329
+ - MCP connections use native switches for individual servers and whole groups,
330
+ including members hidden by filters. Pending operations disable duplicate changes;
331
+ connection errors remain available through a separate information action.
315
332
  - Reorder sections, Quick Actions, toolbar pins and button icons by dragging
316
333
  their handles. With the keyboard, focus a handle, press Space, use Up/Down,
317
334
  then press Space to drop or Escape to cancel. Icon changes remain drafts until saved.
@@ -330,6 +347,11 @@ contains independent TUI, server, RPC and GUI entries.
330
347
  - Provider quotas retain verified account scope. Local Codex access requires a
331
348
  verified same-machine connection; a remote session never borrows its credentials
332
349
  or private binding. Banked resets always require separate confirmation.
350
+ Both terminal and Desktop credit lists show provider-dated expiry progress and
351
+ readable remaining time. Missing or invalid dates never imply an unlimited lifetime.
352
+ Each credit has its own compact card with a status and review action. Desktop
353
+ provider messages expand under **Provider details**; the terminal keeps them in
354
+ the separate review step rather than repeating them throughout the list.
333
355
  Successful quota reads show only their update time above the data; account/model
334
356
  scope remains in the quota model rather than a persistent explanatory sentence.
335
357
  Model and reasoning-effort selection stays in the native chat controls, not
@@ -344,7 +366,7 @@ Linux ARM64 Desktop package on Xvfb. Native macOS/Windows, browser Web and multi
344
366
  live Desktop windows are not claimed as real-host verification targets. Local,
345
367
  remote and multi-consumer guards have separate synthetic contract tests.
346
368
  See [Host API boundaries](HOST_API.md) for the native command-palette limitation.
347
- The manual Prepare Release workflow generated and byte-verified all 31 GUI
369
+ The manual Prepare Release workflow generates and byte-verifies the GUI
348
370
  captures using the real Desktop renderer on a virtual display. The terminal
349
371
  gallery above is rendered separately through Ghostty.
350
372
 
@@ -356,6 +378,10 @@ gallery above is rendered separately through Ghostty.
356
378
 
357
379
  ![Production update indicators with synthetic transfer and installation stages](screenshots/gui/31-desktop-update-stages.png)
358
380
 
381
+ ![Desktop Settings categories and scoped behavior controls](https://raw.githubusercontent.com/St1ggy/opencode-navigator/main/screenshots/gui/33-desktop-settings-behavior.png)
382
+
383
+ ![Native Desktop MCP connection switches and separate error information](https://raw.githubusercontent.com/St1ggy/opencode-navigator/main/screenshots/gui/32-desktop-mcp-switches.png)
384
+
359
385
  ![Desktop layout preview with a separate Apply action](screenshots/gui/07-desktop-layout-preview.png)
360
386
 
361
387
  See the [Desktop gallery](screenshots/README.md#experimental-desktop) for account
@@ -666,6 +692,17 @@ worktree scope. Hiding or collapsing it does not stop background refreshes, and
666
692
  does not grant permission to spend a reset credit. **Focus Limits** is also
667
693
  available from the command palette.
668
694
 
695
+ Each quota window shows two scales: quota remaining and a blue time-remaining
696
+ scale. The quota scale keeps its normal theme color while quota remaining is at
697
+ least the remaining share of the period. It turns yellow below that pace, orange
698
+ at a 15-percentage-point deficit, and red at 30 points. This comparison is a pace
699
+ indicator, not a forecast. It requires a provider-supplied reset time and window
700
+ duration; missing duration is shown as unknown rather than inferred from a label.
701
+ The reset countdown updates locally without extra quota requests. An elapsed
702
+ window stays due until a provider refresh confirms the next one. Native credit
703
+ balances retain their units; the Banked Resets action shows its separate available
704
+ reset-credit count.
705
+
669
706
  ![Codex quota windows and reset times](screenshots/39-provider-limits.png)
670
707
 
671
708
  ![Native Console workspace budgets](screenshots/63-native-workspace-budgets.png)
@@ -1105,14 +1142,34 @@ bun run check
1105
1142
 
1106
1143
  `bun run check` runs the TUI and browser-conditioned GUI tests, separate JSX
1107
1144
  typechecks, Oxlint, bundle-size guards, and Oxfmt. The unminified TUI bundle is
1108
- limited to 360,000 bytes; the independent single-file GUI budget is 600,000 bytes
1109
- (stage-10 measured baseline: about 554 kB). DOM accessibility checks apply only
1145
+ limited to 360,000 bytes; the independent single-file GUI budget is 620,000 bytes
1146
+ (two-scale quota presentation: about 612 kB). DOM accessibility checks apply only
1110
1147
  to GUI modules, never to terminal renderables.
1111
1148
  Font generation is a separate development task: `bun run font:build` and
1112
1149
  `bun run font:check` use `uv` and the pinned FontTools dependency. Users install
1113
1150
  the already generated font; Python and FontTools are not needed at runtime.
1114
1151
  CI checks that the bundled font matches its generator.
1115
1152
 
1153
+ ### Coverage
1154
+
1155
+ Run `bun run test:coverage` to measure the primary TUI and browser-conditioned
1156
+ GUI unit/render suites separately. LCOV reports are written to
1157
+ `coverage/tui/lcov.info` and `coverage/gui/lcov.info`; `coverage/summary.md` and
1158
+ `coverage/summary.json` report each suite and their unique source-line union.
1159
+ Shared lines count once and are covered when either suite executes them.
1160
+
1161
+ This is coverage of executable `src/` lines loaded by those suites, not every
1162
+ source file in the repository. It excludes generated bundles, test fixtures,
1163
+ dependencies and packaged-host smoke runs. These Bun LCOV reports do not provide
1164
+ branch coverage. The separate host checks remain mandatory. Coverage is
1165
+ reporting-only; no minimum threshold or additional status gate is enabled.
1166
+
1167
+ CI retains the reports for 14 days as the `unit-coverage` artifact and adds the
1168
+ line summary to the check job's summary on pushes, pull requests and submitted
1169
+ reviews. The coverage link above opens those CI runs; it is not a separate
1170
+ pass/fail or percentage badge. No external coverage account, upload token,
1171
+ OIDC permission or automated PR comment is needed.
1172
+
1116
1173
  `bun run screenshots` builds a pinned Linux ARM64 image and captures the real TUI
1117
1174
  through Ghostty on Xvfb. The image includes the bundled corner font and a pinned
1118
1175
  JetBrainsMono Nerd Font; every displayed task, session, workspace, path, skill,
@@ -1152,3 +1209,13 @@ The workflow uses npm Trusted Publishing with provenance. Configure
1152
1209
  publisher in the package settings on npmjs.com before publishing a release.
1153
1210
  The new npm package needs its own trusted-publisher configuration; the old
1154
1211
  package's settings are not transferred by renaming the GitHub repository.
1212
+
1213
+ ## Star History
1214
+
1215
+ <a href="https://www.star-history.com/?repos=St1ggy%2Fopencode-navigator&amp;type=date&amp;legend=top-left">
1216
+ <picture>
1217
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=St1ggy/opencode-navigator&amp;type=date&amp;theme=dark&amp;legend=top-left" />
1218
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=St1ggy/opencode-navigator&amp;type=date&amp;legend=top-left" />
1219
+ <img alt="Star history for OpenCode Navigator" src="https://api.star-history.com/chart?repos=St1ggy/opencode-navigator&amp;type=date&amp;legend=top-left" width="800" />
1220
+ </picture>
1221
+ </a>
@@ -14,4 +14,18 @@ function isSameMajorVersion(left,right){const first=versionParts(left)
14
14
  const second=versionParts(right)
15
15
  return Boolean(first&&second&&first.numbers[0]===second.numbers[0])
16
16
  }
17
- export{isNewerVersion,isSameMajorVersion}
17
+ function parseChangelog2(source){const entries=[]
18
+ let entry
19
+ for(const line of source.split(/\r?\n/)){const heading=/^## \[(\d+\.\d+\.\d+(?:-[\w.-]+)?)\]/.exec(line)
20
+ if(heading){entry={version:heading[1],changes:[]}
21
+ entries.push(entry)
22
+ } else if(line.startsWith("## "))
23
+ entry=undefined
24
+ else if(entry&&line.startsWith("- "))
25
+ entry.changes.push(line.slice(2))
26
+ }
27
+ return entries
28
+ }
29
+ function changesSince2(source,previous,current){return parseChangelog2(source).filter((entry)=>entry.changes.length>0&&isNewerVersion(entry.version,previous)&&!isNewerVersion(entry.version,current))
30
+ }
31
+ export{isNewerVersion,isSameMajorVersion,parseChangelog2,changesSince2}
@@ -0,0 +1,6 @@
1
+ async function readBundledChangelog2(){const packaged=Bun.file(new URL("../CHANGELOG.md",import.meta.url))
2
+ if(await packaged.exists())
3
+ return packaged.text()
4
+ return Bun.file(new URL("../../../../CHANGELOG.md",import.meta.url)).text()
5
+ }
6
+ export{readBundledChangelog2}
@@ -0,0 +1,23 @@
1
+ function updateProgressView(progress){const labels={preparing:"Preparing",downloading:"Downloading",installing:"Downloading / installing",verifying:"Verifying"
2
+ }
3
+ const known=progress.total!==undefined&&Number.isFinite(progress.total)&&progress.total>0&&progress.received!==undefined&&Number.isFinite(progress.received)&&progress.received>=0
4
+ const fraction=known?Math.min(1,progress.received / progress.total):undefined
5
+ const label=fraction===undefined?labels[progress.phase]:`${labels[progress.phase]} ${Math.floor(fraction * 100)}%`
6
+ return{label,fraction}}
7
+ function navigatorUpdateAction(input){if(input.restart)
8
+ return{kind:"restart",label:"Restart OpenCode",detail:typeof input.restart==="string"?`Load Navigator ${input.restart} after restarting`:"Restart to load the updated Navigator"
9
+ }
10
+ if(input.progress)
11
+ return{kind:"waiting",label:updateProgressView(input.progress).label,detail:"Keep OpenCode open until this step finishes"
12
+ }
13
+ if(input.checking)
14
+ return{kind:"waiting",label:"Checking for updates\u2026",detail:"Checking the published Navigator version"
15
+ }
16
+ if(input.busy)
17
+ return{kind:"waiting",label:"Waiting for confirmation\u2026",detail:"No update starts before confirmation"
18
+ }
19
+ if(input.available)
20
+ return{kind:"update",label:"Update Navigator\u2026",detail:input.latest?`Install ${input.latest}`:"Review and confirm the available update"
21
+ }
22
+ return{kind:"check",label:"Check for updates",detail:"Check the published Navigator version"}}
23
+ export{navigatorUpdateAction}