opencode-navigator 0.25.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.27.0] - 2026-11-11
4
+
5
+ - Add an experimental OpenCode Desktop interface with a native panel, narrow-screen drawer, and opt-in in-app mini-window. Move, resize, reset and redock it with the mouse or keyboard while keeping the selected session and filters.
6
+ - Bring Search Everything, Skills, MCP groups and presets, Quick Actions, and customizable toolbar pins to Desktop. Share private favorites, trust decisions and preferences with local TUI instances without duplicating monitoring.
7
+ - Add native Desktop settings with scoped section controls, groups, reviewed presets and project profiles, portable import/export, a seven-slide setup guide, About, browsable release history and editable GitHub Bug reports.
8
+ - Keep superseded Desktop configuration reads from showing a false error after a newer refresh, while preserving genuine failures and retry guidance.
9
+ - Show verified provider/account quotas in Desktop with explicit account linking and separately confirmed banked resets. Keep remote sessions isolated from local accounts and preserve unresolved reset attempts across retries.
10
+ - Support OpenCode 1.19.5 and 2.2.6 while preserving both TUI adapters, existing settings, pinned-source updates and read-only legacy Todo archives.
11
+
12
+ ## [0.26.0] - 2026-11-06
13
+
14
+ - Prevent background retries from accumulating cancellation listeners and preferences loading from waiting indefinitely on recovery markers.
15
+ - Show exact active Subagent durations from OpenCode 2's native execution start time, preserving the observation fallback when timing is unavailable. Keep interrupted executions marked as cancelled in recent history.
16
+
3
17
  ## [0.25.0] - 2026-10-31
4
18
 
5
19
  - Offer Enable Todo when OpenCode 2's native tool is disabled, with an existing server-config picker, exact change preview and separate confirmation. Preserve unrelated JSONC content and refuse stale targets; distinguish disabled Todo from an enabled empty list.
package/HOST_API.md CHANGED
@@ -1,17 +1,117 @@
1
1
  # Public Host APIs And Remaining Gaps
2
2
 
3
- Navigator supports only OpenCode **1.19.5** and **2.2.5**, the current stable
3
+ Navigator supports only OpenCode **1.19.5** and **2.2.6**, the current stable
4
4
  release in each major line. Published SDK declarations and real-host checks
5
5
  define the boundary; internal host components are not plugin APIs.
6
6
 
7
+ ## Approved Desktop Integration Contract
8
+
9
+ Desktop support uses the independent `./gui-experimental` entry available from
10
+ Navigator 0.27.0, not the TUI entrypoint. Earlier packages do not include this GUI.
11
+ The approved target is OpenCode Desktop 2.2.6, with TUI 1.19.5 and 2.2.6 kept
12
+ behind explicit adapters. The published 2.2.6 plugin package preserves every TUI
13
+ declaration from 2.2.5; its changed declarations are GUI-specific.
14
+
15
+ | Capability | Published Desktop contract | Navigator integration constraint |
16
+ | --- | --- | --- |
17
+ | GUI loading | `./gui-experimental`, `@opencode/plugin/gui`, one CJS bundle through `gui/vite` | Load from global server configuration; a CLI-only plugin entry does not enable Desktop. Preserve the server plugin's historical identity. |
18
+ | Data and requests | Reactive session `server.data` and live `server.client` | Resolve the selected session's server on every operation; the plugin-level client is the desktop sidecar, not an arbitrary remote session. |
19
+ | Session identity | Host session keys include server identity; location can be unavailable during reconnect | Partition domain state and reject stale actions by server/session/location; never put credentials in cache keys. |
20
+ | Layout | Native side panels, host-controlled bottom placement, narrow drawers, panel-specific width | Use native containers first. The optional floating view is an in-app presentation of the same state, not a detached OS window. |
21
+ | Commands and composer | Native command registry and reactive routed composer/model | Map verified commands explicitly; never emulate GUI actions by fabricating terminal command events. |
22
+ | Dialogs and settings | Native nested dialogs, SettingsPage and settings/menu components | Share validation and action state, not terminal dialog renderers or focus loops. |
23
+ | Local operations | Desktop main, validated IPC, Node/Electron only in main | Renderer models have no filesystem, subprocess or token access. Preserve the existing private store and lock rather than copying preferences to GUI storage. |
24
+ | Remote operations | The selected server's public client and existing plugin RPC | Do not read local project files or use local provider credentials for a remote target. Missing server capabilities remain explicit. |
25
+ | Native windows | Public main context can inspect existing windows; no panel detach operation | Detached OS windows are outside this delivery. Do not mutate host DOM or use private app internals to simulate support. |
26
+
27
+ The GUI API is experimental. Browser Web is not a verified target in this cycle.
28
+ The renderer and headless models must remain independent of Electron so a later
29
+ Web adapter does not require a second implementation of product rules.
30
+
31
+ Verification uses an npm-style tarball in the official checksum-verified Linux
32
+ ARM64 Desktop 2.2.6 package under Xvfb. Native macOS/Windows and multiple live
33
+ Desktop windows are not claimed as real-host coverage; remote identity, independent
34
+ window leases and concurrent shared-store writes are synthetic contracts. The
35
+ unminified TUI remains limited to 360,000 bytes; the single-file GUI has its own
36
+ 600,000-byte budget (about 554 kB at the stage-10 baseline).
37
+
38
+ Native Settings temporarily has no mounted session and may have no active tab.
39
+ Navigator retains only a previously observed public session reference still
40
+ confirmed by the public tab list, server and location; Home, closing that tab or
41
+ changing its target clears it. Settings/profile operations use that reference's
42
+ live client/cache rather than substituting the sidecar.
43
+
44
+ Private favorites, trust, presets, account bindings and reset attempts remain in
45
+ the established filesystem preferences store/lock via typed main IPC. Native GUI
46
+ storage holds presentation only. Explicit Reload flushes writes, refreshes private
47
+ preferences and selected-server configured defaults, and clears temporary layout
48
+ overrides. Project profiles use the selected server RPC with exact file previews
49
+ and stale-file checks; workspace-placed filesystems are rejected until the public
50
+ server contract provides a verified placement-aware atomic write operation.
51
+
52
+ GUI permission actions open native Settings. No supported Desktop startup/Home
53
+ interception or LSP status contract was found; those terminal capabilities are not
54
+ simulated. Revisit the gaps when equivalent public APIs become available. Changelog
55
+ browsing is independent of the one-time version claim used by startup notes.
56
+
57
+ On narrow Desktop windows, Navigator uses **More → Navigator**, the host's
58
+ native drawer. The floating view redocks when the viewport becomes narrow.
59
+ Desktop 2.2.6 keeps drawer opening in its own mobile navigation; Navigator does
60
+ not click or move host elements to force it open. Revisit automatic drawer
61
+ opening when the public layout API exposes that operation.
62
+
63
+ The Desktop model controls use the verified 2.2.6 commands `model.choose` and
64
+ `model.variant.cycle`. These IDs are version-audited mappings, not portable
65
+ TUI command names; a rejected dispatch reports that the control is unavailable.
66
+
67
+ The isolated Desktop 2.2.6 host also has a native dialog-context defect: opening
68
+ its command palette after a plugin dialog in a session can fail with
69
+ `Command context must be used within a context provider`. The same minimal
70
+ fixture reproduces this with Navigator disabled; Home does not reproduce it.
71
+ Navigator does not patch host contexts. Interaction smokes keep this native-only
72
+ probe separate and exercise subsequent plugin commands through the public
73
+ `commands.run` API. Recheck this limitation on the next audited Desktop target.
74
+
75
+ Sources: [GUI plugins](https://opencode.ai/docs/build/plugins/gui),
76
+ [TUI plugins](https://opencode.ai/docs/build/plugins/cli),
77
+ [RPC](https://opencode.ai/docs/build/plugins/rpc), and the published
78
+ `@opencode/plugin@2.2.6` declaration archive, audited on 2026-11-10.
79
+
7
80
  ## Host-Owned Services
8
81
 
9
- | Capability | OpenCode 1.19.5 | OpenCode 2.2.5 |
82
+ ### Dependency audit limits
83
+
84
+ The candidate's frozen install and peer graph pass, but its security audit is
85
+ not clean. The supported 1.x plugin pins an older Effect beta and Zod; its Effect
86
+ graph also carries TOML denial-of-service advisories. The supported 2.x utility
87
+ package pins Glob and Minimatch versions with denial-of-service advisories.
88
+ Navigator does not force incompatible transitive-major overrides or suppress the
89
+ audit. Removal depends on compatible upstream fixes in the supported host graph;
90
+ review these advisories again before publication.
91
+
92
+ ### Selected-server quota services
93
+
94
+ Desktop Codex reads and reset submissions run behind typed main-process IPC,
95
+ only for the host-verified `sameMachine` sidecar. Main rechecks the session
96
+ directory, live client, active connection and private account binding; it never
97
+ returns credentials or provider headers to the renderer. Remote sessions use
98
+ their selected server's quota RPC and never borrow the Desktop's local account.
99
+ Public session and quota-event locations expose only a directory, not a workspace
100
+ ID. Workspace requests retain explicit location guards, and quota observations
101
+ without sufficient workspace identity do not trigger an automatic read.
102
+
103
+ The ordinary Codex bucket is account-scoped even when `normalModelSlug` is null.
104
+ Missing reset-credit details do not erase the provider's available count. Reset
105
+ submission requires a separate confirmation and an authoritative persisted
106
+ attempt; uncertain retries retain its idempotency key. No credit is spent during
107
+ review, refresh or account linking.
108
+
109
+ | Capability | OpenCode 1.19.5 | OpenCode 2.2.6 |
10
110
  | --- | --- | --- |
11
111
  | Todo | Supported host Todo source/events | Public message cache, completed `todowrite` and revert boundary |
12
- | Skills | Host discovery and prompt insertion | Native Skill cache and `session.skill` with exact ID |
13
- | MCP | Host status and connection API | Native cache, sync/invalidate and connect/disconnect |
14
- | Subagents | Supported child/status API and events | Native session cache/status and typed execution events |
112
+ | Skills | Host discovery and prompt insertion | Native Skill cache and `experimental.session.skill` with exact ID |
113
+ | MCP | Host status and connection API | Native cache, sync/invalidate and `experimental.mcp.connect/disconnect` |
114
+ | Subagents | Supported child/status API and events | Native session cache/status, execution start time and typed execution events |
15
115
  | Commands | Public keymap | Public owned layers, targets, priorities, modes, discovery and dispatch |
16
116
  | Dialogs/toasts | Public dialog components and mounting | Public show/prompt/confirm/set/clear and toast |
17
117
  | Model/variant | Saved session model and host pickers | Reactive prompt model, variant API and host pickers |
@@ -31,10 +131,10 @@ justify bypassing a native API.
31
131
  | Bug-report transport and external browser launch | Neither supported public TUI contract provides GitHub issue creation or an external browser opener. Direct sending uses the user's authenticated `gh` without reading credential files; a `type: Bug` repository form handles browser reports. Bounded argv-based OS launch has a visible link/clipboard fallback on remote or headless hosts. | Equivalent public host issue/browser APIs preserving authentication ownership, editable draft, real issue type and confirmation semantics. |
32
132
  | Literal Ctrl+, hook on 2.x | Public plugin bindings are strings; the comma expander splits literal commas into alternatives. The named parser does not normalize `comma` to the actual comma event. Dispatch still uses the native command API. | A documented literal-comma binding passing the real Settings smoke. |
33
133
  | Subagent child discovery | Published TUI Data caches sessions but has no complete children-sync operation. Initial/manual/reconnect discovery uses the public paginated API and syncs unknown IDs into the host cache. | A complete children-sync/query on the supplied public Data interface. |
34
- | Subagent observation history and retry details | Native status and cached transcript retry data are used first; recent runs, pre-observation clock markers, errors and unloaded-child retry detail remain observation history. | Equivalent public observed-run/retry history without loading every transcript. |
134
+ | Subagent observation history and retry details | Native status, `SessionInfo.time.busy` and cached retry data are used first. Valid current-execution start times give exact active durations without a pre-observation marker; missing/invalid timing keeps the observed fallback. Recent runs, errors and unloaded-child retry details remain observation history. The prior execution's `idle`/`outcome` never completes a currently running execution. | Equivalent public observed-run/retry history without loading every transcript. |
35
135
  | Read-only Todo projection | Native completed tool calls and revert are public; the host's `sessionTodos` helper is not exported. No direct CRUD/priority API exists. | A public equivalent projection; editing also requires an explicitly selected interaction and supported API. |
36
136
  | Native Todo enablement | `config.get` exposes ordered sources, but `experimental.config.update` supports only shell. The setup feature previews and confirms a JSONC leaf edit in an existing discovered source through public server file APIs. File reads are location-confined, so selected-file IO is routed to its server-side parent; the original session/location remains the stale-target guard. Reads immediately before writes reject changed previews, and readback verifies the file and effective flag. The public write API has no CAS, so this is not an atomic transaction against concurrent external writers; uncertain outcomes require Refresh before retry. No model, shell or Todo event is used. | A public Todo config patch API preserving source precedence, unrelated JSONC content and conditional-write semantics. |
37
- | Console/Go request lifecycle and projection | `client.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. |
137
+ | 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. |
38
138
  | 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. |
39
139
  | 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. |
40
140
  | 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. |
@@ -52,10 +152,10 @@ justify bypassing a native API.
52
152
 
53
153
  Both current hosts have isolated real-host checks. Historical installer fixtures
54
154
  exercise migration only; they do not extend the supported host matrix.
55
- The published 2.2.5 TUI context, plugin, index and Solid declarations are identical
56
- to 2.2.0. OpenTUI 0.8 retains the drawing-only paint-hook contract; renderer tests,
155
+ The published 2.2.6 TUI declarations are identical to 2.2.5. OpenTUI 0.8 retains
156
+ the drawing-only paint-hook contract; renderer tests,
57
157
  nested dialogs and frame-level typing probes run against the updated runtime.
58
- Development uses Bun 1.4.4 and OpenTUI 0.8.1, leaving Solid/OpenTUI external so the
158
+ Development uses Bun 1.4.4 and OpenTUI 0.8.3, leaving Solid/OpenTUI external so the
59
159
  host owns its runtime. The 1.x host ships older runtime modules; its actual smoke
60
160
  must pass rather than injecting the development modules into it.
61
161
 
@@ -67,13 +167,22 @@ renderer/FFI support. CI and package verification use Node 26.12.1.
67
167
  ### Deliberate Compatibility Pins
68
168
 
69
169
  - `web-tree-sitter` stays at **0.25.10**, the exact peer required by OpenTUI
70
- 0.8.0. Upgrade it when the supported host runtime publishes a compatible peer
170
+ 0.8.3. Upgrade it when the supported host runtime publishes a compatible peer
71
171
  contract; the independent 0.27 line is not a compatible substitution.
72
- - `typescript` is **7.0.2** throughout the resolved project graph. The shared
73
- preset's legacy compiler dependency is overridden to TS7; its incompatible
74
- SonarJS and typescript-eslint JS plugins are not loaded. Native replacements,
75
- retained compatible plugins and the explicitly approved coverage loss are
76
- documented in [Lint coverage](LINT_COVERAGE.md). No TS6 compatibility copy is used.
172
+ - `typescript` is **6.0.3**, selected to match the complete published
173
+ `@st1ggy/linter-config` **10.0.0** preset. SonarJS and typescript-eslint JS
174
+ plugins remain enabled without the former TS7 projection or override.
175
+ [Lint coverage](LINT_COVERAGE.md) records the current setup and historical exclusions.
176
+ - Oxlint **1.90.0**, Oxfmt **0.75.0** and oxlint-tsgolint **7.0.2005** match the
177
+ preset's exact peer versions. Advance them when the preset supports newer engines.
178
+ - OpenTUI's transitive `bun-ffi-structs` **0.3.1** declares the outdated compiler
179
+ peer `typescript: ^5`. A root-only Bun metadata patch expands it to `^5 || ^6`;
180
+ no runtime bytes or declarations change. Strict declaration compilation with
181
+ library checks enabled, packing regressions and the resolved compiler graph
182
+ verify the selected TS6 use. Remove the patch when upstream accepts TS6.
183
+ Bun patches apply only in this repository, not transitively in consumer projects
184
+ or the separately generated snapshot runtime manifest. Those installations may
185
+ still report the upstream peer warning; this is not an upstream fix.
77
186
  - Bun remains pinned at **1.4.4**, the current stable release. Direct dependencies
78
187
  otherwise use their latest compatible stable releases; transitive updates stay
79
188
  within upstream ranges. Runtime peers remain host-owned and are not bundled.
package/LINT_COVERAGE.md CHANGED
@@ -1,39 +1,42 @@
1
- # TypeScript 7 Lint Coverage
1
+ # Lint Coverage
2
2
 
3
- Project type checking uses stable TypeScript 7. The lockfile resolves every
4
- TypeScript dependency, including the shared preset's dependency tree, to that
5
- version. There is no TypeScript 6 compatibility installation.
3
+ Project type checking uses stable TypeScript 6.0.3, matching the compiler API
4
+ used by the published shared preset. The user selected this compatibility-first
5
+ setup instead of extending the previous TypeScript 7 coverage exclusions.
6
6
 
7
7
  Oxlint uses `@st1ggy/linter-config/solid-ox` with type-aware analysis. Oxfmt uses
8
- `@st1ggy/linter-config/oxfmt-common`. `scripts/native-lint-config.ts` adapts the
9
- published preset without editing installed packages. The user explicitly approved
10
- the uncovered SonarJS checks below after reviewing the TS7 incompatibility.
8
+ `@st1ggy/linter-config/oxfmt-common`. The version 10 preset is extended directly,
9
+ including its SonarJS and typescript-eslint JS plugins. No compiler-compatibility
10
+ projection filters its rules. Deliberate project exceptions remain documented
11
+ beside their individual settings in `oxlint.config.ts`.
11
12
 
12
13
  ## Preserved Checks
13
14
 
15
+ - GUI-only overrides add native JSX accessibility checks for ARIA, labels/content,
16
+ keyboard parity and focusability while retaining every native plugin from the
17
+ published Solid preset. OpenTUI JSX is excluded from these HTML-specific rules.
18
+ Native host controls retain their own semantics; real Desktop keyboard checks
19
+ complement source linting.
14
20
  - Native ESLint, TypeScript, import and Unicorn rules remain enabled.
15
- - The compatible Solid, ESLint-core, import-x, stylistic and Unicorn JS plugins
16
- remain enabled. There is no blanket removal of JS plugins.
17
- - `typescript-js/array-type` and `typescript-js/prefer-as-const` use their native
18
- `typescript/` equivalents. The legacy typescript-eslint plugin is not loaded.
19
- - Six SonarJS checks use native ESLint equivalents: `block-scoped-var`,
20
- `no-delete-var`, `no-fallthrough`, `no-labels`, `no-unused-vars` and
21
- `no-useless-catch`. Existing native options take precedence.
21
+ - All published Solid, ESLint-core, import-x, stylistic, Unicorn, SonarJS and
22
+ typescript-eslint JS plugins remain enabled.
23
+ - Promise handling and strict equality follow the version 10 preset.
24
+ - Bun 1.4.4 can return undefined from `rejects`/`resolves` matchers for already
25
+ settled promises. Tests normalize matcher results through `Promise.resolve`
26
+ before awaiting, preserving pending assertions and satisfying both the native
27
+ thenable rule and SonarJS assertion handling without disabling either rule.
22
28
  - Oxfmt still checks formatting separately. This migration does not configure
23
29
  Stylelint for the CSS-free TUI project.
24
30
 
25
- ## Approved Coverage Loss
31
+ ## Historical TypeScript 7 Coverage Exclusions
26
32
 
27
- The published preset configures 161 SonarJS rule names. Six have the direct
28
- native mappings above. The following 155 preset checks are not loaded after
29
- removing the TS6-dependent SonarJS plugin. Some overlap with other retained rules,
30
- but that is not claimed as complete semantic equivalence. The list includes
31
- checks for frameworks and services this project does not use; it describes the
32
- preset, not 155 distinct bugs or applicable findings in Navigator.
33
+ Navigator 0.25.0 used native substitutions for six SonarJS rules and excluded
34
+ the following 155 rule names from preset 8 for TS7 compatibility. This list is
35
+ historical, not the current configuration. Preset 10 now supplies its complete
36
+ rule set, subject only to the documented project-specific exceptions.
33
37
 
34
- In particular, native cyclomatic complexity is not a replacement for SonarJS
35
- cognitive complexity. Identical-function detection, several security/regex
36
- checks and SonarJS-specific test heuristics lose their dedicated coverage.
38
+ Native cyclomatic complexity was not considered a replacement for SonarJS
39
+ cognitive complexity. The compiler-driven exclusions are no longer applied.
37
40
 
38
41
  ```text
39
42
  sonarjs/assertions-in-test-cases
@@ -193,9 +196,9 @@ sonarjs/x-powered-by
193
196
  sonarjs/xml-parser-xxe
194
197
  ```
195
198
 
196
- ## Removing The Adapter
199
+ ## Future Compiler Upgrades
197
200
 
198
- Replace the compatibility projection when the shared preset offers a TS7-only
199
- stack with equivalent native rules or compatible public plugin APIs. Keep the
200
- coverage inventory explicit when upgrading that preset; do not label a removed
201
- check as preserved merely because a similarly named rule exists.
201
+ The compatibility projection has been removed. Reconsider TypeScript 7 only when
202
+ the complete published lint stack supports its compiler API. Keep coverage
203
+ explicit; do not label a removed check as preserved merely because a similarly
204
+ named rule exists.
package/PROVIDERS.md CHANGED
@@ -5,6 +5,15 @@ It never treats session token/cost totals as remaining provider quota. Subscript
5
5
  windows, API rate limits, configured capacities, and monetary balances are different
6
6
  measurements and are labelled separately.
7
7
 
8
+ The experimental Desktop entry shares quota normalization, refresh scheduling,
9
+ account binding and reset-attempt rules with TUI. Its renderer uses the selected
10
+ session's live server client/cache. Local Codex subprocess access is restricted to
11
+ typed Desktop-main IPC for a host-verified same-machine connection; remote or
12
+ unverified targets never borrow the Desktop's local account or binding. No tokens
13
+ or credential files are returned to the renderer. Remote provider reads use the
14
+ selected server's existing quota RPC. Missing capabilities and authentication
15
+ failures remain explicit rather than enabling an alternate credential reader.
16
+
8
17
  The external provider contracts were rechecked on 2026-10-06; the public
9
18
  OpenCode Console/Go contract was added on 2026-10-28. The runtime also includes providers from
10
19
  the host catalog; an unrecognized provider gets an explicit unverified-source state
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # OpenCode Navigator
2
2
 
3
- Search, navigate, and manage OpenCode sessions from the TUI. Navigator combines
3
+ Search, navigate, and manage OpenCode sessions from the TUI, with an experimental
4
+ OpenCode Desktop interface. Navigator combines
4
5
  Search Everything, task and subagent views, skills, MCP presets, and quick actions
5
6
  with a configurable sidebar.
6
7
 
@@ -44,7 +45,7 @@ collapsed. Use `Save current layout as default` in sidebar settings to reuse the
44
45
  current visible/hidden, expanded/collapsed, and ordering states in new sessions.
45
46
 
46
47
  **Only the latest stable release in each major line is supported: OpenCode
47
- 1.19.5 and 2.2.5.** Both have separate real-host checks. Older releases are not
48
+ 1.19.5 and 2.2.6.** Both have separate real-host checks. Older releases are not
48
49
  part of the supported compatibility matrix. The 2.2 integration uses OpenTUI 0.8
49
50
  and public host caches, events, keymap layers, and client APIs while retaining
50
51
  the separate 1.x adapter. See [Host API boundaries](HOST_API.md) for remaining
@@ -52,7 +53,7 @@ capability gaps and removal conditions. On OpenCode 2, Navigator reads the same
52
53
  the host sidebar, including completed `todowrite` calls and the current revert
53
54
  boundary. Viewing Todo needs no Navigator server plugin. OpenCode 2.1 exposes
54
55
  content and four statuses, without priorities or direct Todo CRUD. LSP is hidden on 2.x while retaining Subagents,
55
- Skills, Quick Actions, MCP, Search, settings, and presets. All interface icons use Nerd Font glyphs by
56
+ Skills, Quick Actions, MCP, Search, settings, and presets. All TUI interface icons use Nerd Font glyphs by
56
57
  default (Codicons for controls, keyboard symbols for hints, language logos for LSP). Use a Nerd Fonts v3
57
58
  terminal font, or select **Settings → Behavior → Icon style → Text fallback**.
58
59
  The switch applies to the entire interface, including Quick Actions, search
@@ -271,6 +272,72 @@ in a separate JSON file and set `OPENCODE_CONFIG` to its path **only when
271
272
  launching OpenCode 2.x**. The TUI configuration in `cli.json` remains separate;
272
273
  the OpenCode 1.x launch must not load Navigator's 2.x server plugin.
273
274
 
275
+ ### Experimental OpenCode Desktop
276
+
277
+ Navigator 0.27.0 and newer also export `./gui-experimental` for **OpenCode Desktop
278
+ 2.2.6**. This is not browser Web support or a detached operating-system window.
279
+ Earlier Navigator versions do not include the GUI export.
280
+
281
+ Desktop discovers the GUI from its **global server plugin configuration**,
282
+ `~/.config/opencode/opencode.json` (or the equivalent XDG location), not from
283
+ `cli.json` or `tui.json`. Merge its package entry with existing plugins rather
284
+ than replacing the configuration:
285
+
286
+ ```jsonc
287
+ {
288
+ "$schema": "https://opencode.ai/config.json",
289
+ "plugins": [{ "package": "opencode-navigator" }],
290
+ }
291
+ ```
292
+
293
+ For a pinned local installation, use its reviewed package directory instead of
294
+ the npm package name; that directory must include its runtime dependencies.
295
+ Do not add this v2 server package to a configuration shared with OpenCode 1.x;
296
+ keep the separate v2 launch configuration described above. The same package
297
+ contains independent TUI, server, RPC and GUI entries.
298
+
299
+ - Open **Open Navigator** from the command palette after selecting a session.
300
+ The native panel can be placed beside or below the chat with host controls.
301
+ Narrow windows use **More → Navigator**.
302
+ - Choose **Float** for an opt-in mini-window inside the application. It follows
303
+ the selected session, hides on Home and yields to native dialogs. Move, resize,
304
+ reset and redock controls support keyboard input too. Both placements share
305
+ one monitoring runtime and filters; switching does not duplicate polling.
306
+ - **Navigator settings** opens native Settings with Global/Worktree scope,
307
+ section controls, groups, trust, presets, portable/project profiles, About,
308
+ release history and reviewed Bug reports. **Reload preferences** imports
309
+ changes from other local Navigator instances explicitly.
310
+ - Favorites, trust, account bindings, reset attempts and presets use the existing
311
+ private preferences file and lock shared with local TUI instances. Only window
312
+ placement lives in the native GUI store. Project profiles and configuration
313
+ requests use the selected server, including remote servers.
314
+ - Todo is native and read-only; chat owns edits. Legacy Navigator tasks remain a
315
+ read-only archive. LSP and startup/Home interception are not exposed by this
316
+ Desktop contract. Permissions opens native host Settings rather than toggling
317
+ a simulated mode. Terminal fonts, corner masks and terminal shortcuts are not
318
+ GUI settings; Desktop does not need a Nerd Font or the corner font.
319
+ - Provider quotas retain verified account scope. Local Codex access requires a
320
+ verified same-machine connection; a remote session never borrows its credentials
321
+ or private binding. Banked resets always require separate confirmation.
322
+
323
+ The candidate is tested as an npm-style tarball in the official checksum-verified
324
+ Linux ARM64 Desktop package on Xvfb. Native macOS/Windows, browser Web and multiple
325
+ live Desktop windows are not claimed as real-host verification targets. Local,
326
+ remote and multi-consumer guards have separate synthetic contract tests.
327
+ See [Host API boundaries](HOST_API.md) for the native command-palette limitation.
328
+ The manual Prepare Release workflow generated and byte-verified all 27 GUI
329
+ captures using the real Desktop renderer on a virtual display. The terminal
330
+ gallery above is rendered separately through Ghostty.
331
+
332
+ ![Desktop Search Everything with a synthetic Skill](screenshots/gui/02-desktop-search-skills.png)
333
+
334
+ ![Desktop mini-window preserving the current Todo filter](screenshots/gui/14-desktop-mini-window.png)
335
+
336
+ ![Desktop layout preview with a separate Apply action](screenshots/gui/07-desktop-layout-preview.png)
337
+
338
+ See the [Desktop gallery](screenshots/README.md#experimental-desktop) for account
339
+ linking, quotas, reviewed resets, profiles, onboarding and Bug reports.
340
+
274
341
  ### Install the corner font
275
342
 
276
343
  **Required for rounded multiline selections in Nerd Font mode.** Run the font
@@ -936,9 +1003,11 @@ tasks before pending tasks. Finished contains separate Completed and Cancelled
936
1003
  groups. The selected view is temporary and resets to All when changing sessions.
937
1004
  The header always reports completed tasks against the full task count.
938
1005
 
939
- Subagents show observed run duration, retry countdowns, and execution errors. An
940
- already-running child discovered by the sidebar uses a clock icon (`~` in Text
941
- fallback) because its exact start time is unknown. Recent keeps the last 10 observed
1006
+ Subagents show run duration, retry countdowns, and execution errors. OpenCode 2
1007
+ uses its public execution-start timestamp for exact active durations, including
1008
+ children already running when Navigator opens. Missing or invalid native timing
1009
+ and OpenCode 1 retain observed durations. An already-running child whose exact
1010
+ start is unknown has a clock icon (`~` in Text fallback). Recent keeps the last 10 observed
942
1011
  finished runs per parent session in memory across navigation, until OpenCode exits.
943
1012
  An idle transition is labelled Finished, not a guarantee of successful task
944
1013
  completion; errors and cancellations retain their own labels. A worker timeout
@@ -974,7 +1043,7 @@ session or workspace dismisses the entire search dialog chain.
974
1043
 
975
1044
  ## Scripts
976
1045
 
977
- Development uses Bun 1.4.4 and stable TypeScript 7. Standalone Node/OpenTUI paths
1046
+ Development uses Bun 1.4.4 and stable TypeScript 6.0.3. Standalone Node/OpenTUI paths
978
1047
  require Node.js 26.4 or newer; CI pins Node 26.12.1. Install dependencies with
979
1048
  `bun install --frozen-lockfile`.
980
1049
 
@@ -984,13 +1053,17 @@ Oxlint uses the `solid-ox` preset from
984
1053
  OpenTUI callbacks, SDK compatibility, and test fixtures. Type-aware analysis uses
985
1054
  `oxlint-tsgolint`; `tsconfig.lint.json` covers application code, tests, build scripts,
986
1055
  and configuration files. Formatter exclusions are maintained in `oxfmt.config.ts`.
987
- The resolved dependency tree contains TS7 only. The approved removal of
988
- incompatible SonarJS checks and native replacements is documented in
989
- [Lint coverage](LINT_COVERAGE.md); compatible Solid and other JS checks remain.
1056
+ The complete version 10 preset includes SonarJS and typescript-eslint checks;
1057
+ the former TS7 compatibility projection is removed. See [Lint coverage](LINT_COVERAGE.md)
1058
+ for current exceptions and historical exclusions. A tested root-only Bun metadata
1059
+ patch corrects the legacy TypeScript 5 peer in OpenTUI's FFI helper for this repo.
1060
+ Consumer installations retain upstream metadata; see [Host APIs](HOST_API.md).
990
1061
 
991
1062
  ```sh
992
1063
  bun run test
993
1064
  bun run test:e2e
1065
+ bun run test:gui
1066
+ bun run test:e2e:gui
994
1067
  bun run typecheck
995
1068
  bun run lint
996
1069
  bun run lint:fix
@@ -1004,8 +1077,11 @@ bun run screenshots:verify
1004
1077
  bun run check
1005
1078
  ```
1006
1079
 
1007
- `bun run check` runs the tests, TypeScript, Oxlint, bundle-size guard, and Oxfmt
1008
- check. The unminified TUI bundle is limited to 360,000 bytes.
1080
+ `bun run check` runs the TUI and browser-conditioned GUI tests, separate JSX
1081
+ typechecks, Oxlint, bundle-size guards, and Oxfmt. The unminified TUI bundle is
1082
+ limited to 360,000 bytes; the independent single-file GUI budget is 600,000 bytes
1083
+ (stage-10 measured baseline: about 554 kB). DOM accessibility checks apply only
1084
+ to GUI modules, never to terminal renderables.
1009
1085
  Font generation is a separate development task: `bun run font:build` and
1010
1086
  `bun run font:check` use `uv` and the pinned FontTools dependency. Users install
1011
1087
  the already generated font; Python and FontTools are not needed at runtime.
@@ -1022,6 +1098,15 @@ requires Docker with Linux ARM64 support. These commands are available for harne
1022
1098
  development; the committed release captures are generated by the manual
1023
1099
  `Prepare Release` GitHub Actions workflow.
1024
1100
 
1101
+ That workflow also runs `bun run screenshots:gui` and
1102
+ `bun run screenshots:gui:verify`. They use the real packaged Desktop renderer on
1103
+ Xvfb, not Ghostty, with synthetic sessions, providers and reports. The second run
1104
+ compares the PNGs byte-for-byte. Fixed renderer and synthetic main clocks,
1105
+ full software rasterization and disabled capture-time animations stabilize scenes
1106
+ without stopping interaction timers or adding comparison tolerances. GUI
1107
+ capture commands reject non-CI invocation; ordinary Desktop smoke tests never
1108
+ take screenshots. New captures and their visual review remain a pre-release gate.
1109
+
1025
1110
  ## Publishing
1026
1111
 
1027
1112
  Publishing is handled by `.github/workflows/publish.yml` when a GitHub Release
@@ -1,4 +1,5 @@
1
1
  var SIDEBAR_SECTIONS=["limits","todo","subagents","skills","quick_actions","lsp","mcp"]
2
+ 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"]
2
3
  var SECTION_DEFINITIONS=[{name:"limits",label:"Limits"},{name:"todo",label:"Todo"},{name:"subagents",label:"Subagents"},{name:"skills",label:"Skills"},{name:"quick_actions",label:"Quick actions"},{name:"lsp",label:"LSP"},{name:"mcp",label:"MCP"}];
3
4
  var MAX_LIMITS_REFRESH_MINUTES=Math.floor(2147483647 / 60000);
4
5
  var PLUGIN_ID="opencode-navigator"
@@ -6,4 +7,4 @@ var TOGGLE_COMMAND=`${PLUGIN_ID}.toggle`
6
7
  var FOCUS_COMMAND=`${PLUGIN_ID}.focus`
7
8
  var SEARCH_COMMAND=`${PLUGIN_ID}.search`
8
9
  var DEFAULT_SEARCH_KEY="ctrl+shift+k"
9
- export{SIDEBAR_SECTIONS,SECTION_DEFINITIONS,PLUGIN_ID,DEFAULT_SEARCH_KEY}
10
+ export{SIDEBAR_SECTIONS,QUICK_ACTION_IDS,SECTION_DEFINITIONS,PLUGIN_ID,DEFAULT_SEARCH_KEY}