opencode-navigator 0.27.4 → 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,14 @@
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
+
3
12
  ## [0.27.4] - 2026-11-12
4
13
 
5
14
  - Show banked-reset expiry progress in the terminal, with readable remaining time and explicit missing or invalid dates. Keep credit use separately confirmed.
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.
@@ -173,6 +179,7 @@ justify bypassing a native API.
173
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. |
174
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. |
175
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. |
176
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. |
177
184
 
178
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
@@ -337,6 +349,9 @@ contains independent TUI, server, RPC and GUI entries.
337
349
  or private binding. Banked resets always require separate confirmation.
338
350
  Both terminal and Desktop credit lists show provider-dated expiry progress and
339
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.
340
355
  Successful quota reads show only their update time above the data; account/model
341
356
  scope remains in the quota model rather than a persistent explanatory sentence.
342
357
  Model and reasoning-effort selection stays in the native chat controls, not
@@ -677,6 +692,17 @@ worktree scope. Hiding or collapsing it does not stop background refreshes, and
677
692
  does not grant permission to spend a reset credit. **Focus Limits** is also
678
693
  available from the command palette.
679
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
+
680
706
  ![Codex quota windows and reset times](screenshots/39-provider-limits.png)
681
707
 
682
708
  ![Native Console workspace budgets](screenshots/63-native-workspace-budgets.png)
@@ -1116,14 +1142,34 @@ bun run check
1116
1142
 
1117
1143
  `bun run check` runs the TUI and browser-conditioned GUI tests, separate JSX
1118
1144
  typechecks, Oxlint, bundle-size guards, and Oxfmt. The unminified TUI bundle is
1119
- limited to 360,000 bytes; the independent single-file GUI budget is 600,000 bytes
1120
- (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
1121
1147
  to GUI modules, never to terminal renderables.
1122
1148
  Font generation is a separate development task: `bun run font:build` and
1123
1149
  `bun run font:check` use `uv` and the pinned FontTools dependency. Users install
1124
1150
  the already generated font; Python and FontTools are not needed at runtime.
1125
1151
  CI checks that the bundled font matches its generator.
1126
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
+
1127
1173
  `bun run screenshots` builds a pinned Linux ARM64 image and captures the real TUI
1128
1174
  through Ghostty on Xvfb. The image includes the bundled corner font and a pinned
1129
1175
  JetBrainsMono Nerd Font; every displayed task, session, workspace, path, skill,
@@ -1163,3 +1209,13 @@ The workflow uses npm Trusted Publishing with provenance. Configure
1163
1209
  publisher in the package settings on npmjs.com before publishing a release.
1164
1210
  The new npm package needs its own trusted-publisher configuration; the old
1165
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}