Highlights
- CodeNomad now runs on OpenCode V2: Projects share the native OpenCode service, so desktop windows and terminal clients can work with the same session history. Closing CodeNomad leaves the shared service running.
- Long conversations stay usable: Transcript memory is bounded, full-history search finds content beyond the loaded messages, and the timeline lets you jump across an entire conversation with contextual previews.
- Move work between Git worktrees: Create and select native worktrees, move a session family together, and retain the right project and branch context as you switch tasks.
- Ask a quick side question with
/btw: Get a separate, temporary answer without interrupting the main session. - A more consistent workspace: New light/dark palettes, clearer conversation surfaces, responsive session actions, persistent search/command windows, and View-menu panel toggles make the interface easier to adapt.
- Better attachments and visual feedback: Device picking, drag-and-drop, and clipboard attachments share one workflow; project files remain available through
@references. Images returned by MCP and other tools now render directly in chat.
Upgrading from 0.19.x
- OpenCode V2 is required. The technical minimum is 2.0.7, which supplies the native step-start timestamp used by the current event reducer. 2.0.16 is the recommended and qualified runtime for this release. V1 runtimes and the former V2 beta protocol are not supported.
- Install and manage OpenCode from startup or Preferences. CodeNomad prefers an executable on PATH and can install into a shared user npm location using bundled Node/npm. Terminal clients can use the same installation.
- Runtime installation and service restart are separate actions. Updating the CLI does not silently restart an already-running OpenCode service. Compatible shared npm installations on OpenCode 2.0.15+ use native upgrade for version changes, including live Windows executable handling.
- Upgrade remote CodeNomad servers to 0.20.0 for the new UI. The published UI manifest now requires server 0.20.0 instead of advertising compatibility with the V1-based 0.19.x server.
- Git enables the complete project/worktree experience. If the backend cannot find Git, directory-scoped conversations remain available while Git-dependent functionality is unavailable.
Sessions, history, and worktrees
- Full-history search, counts, selective cleanup, and global timeline navigation work independently of the currently loaded transcript. Search includes edit diffs stored in tool metadata.
- Large transcripts load bounded windows while preserving access to complete content. Timeline markers retain tool identities, and hover/focus previews show bounded Markdown excerpts.
- Session search uses flat results with optional subsessions; normal browsing retains the parent/child hierarchy. Fork actions are available after both user and assistant messages.
- Native worktree creation, discovery, and family moves use repository ownership checks. Removing a worktree verifies and evacuates affected sessions before deleting it.
- Worktree selectors open without waiting for a fresh Git scan, and saved conversations restore before secondary Git panels and catalogs finish loading.
- Stop and double Escape no longer accidentally restart a parent session. Automatic empty-session cleanup verifies native content before removing anything.
- Active-session model choices survive prompt admission, catalog refreshes, and delayed responses instead of switching back unexpectedly.
Composer, tools, and plugins
- Attach local-device files with the native picker, paste, or drag-and-drop, and reference project files separately through
@. Attachment reads follow the active draft and session rather than spilling into a newly selected conversation. - MCP and specialized tool results can display returned images without inserting image bytes into copied text, search, or speech.
- Global and Project plugin activation switches are separate, making the scope of each change explicit. Plugin details are available from the name tooltip.
- Native Forms support provider authentication and interactive requests. Permission rejection feedback survives refreshes, and native background Shells remain separate from interactive terminals.
- Profile environment variables are refreshed before each prompt, custom command, or session shell request, including removal of previously configured values.
- Browser previews and desktop automation give agents a visible inspection-and-fix workflow with session/window targeting. Automation tools are available without a Developer Mode toggle.
Desktop continuity and interface
- Electron and Tauri support multiple UUID-backed windows with independent tabs, drafts, attachments, selection, and view state over one shared backend. Window restoration uses partitioned storage rather than one monolithic snapshot.
- Startup prioritizes the active project and conversation, including interrupted hydration and slow filesystem/Git discovery. Preferences retain their own geometry, zoom, and navigation.
- Browser authentication can recover in place after a server restart while preserving drafts, without replaying failed actions.
- Light/dark palette selections are independent of appearance mode. Settings, message cards, the composer, and panels use more consistent surfaces and controls.
- Search and command windows stay open during outside interactions. The native View menu exposes panel and timeline toggles.
- Thinking, tool visibility, token sections, and compact headers are clearer. System context updates are hidden by default; collapse preferences also apply to single-step reasoning.
- User-supplied HTML displays as literal source rather than being interpreted as chat markup.
- Turkish localization joins the existing languages, with updated coverage for V2 features.
Reliability and distribution
- Reconnection reconciles native session and pending-request state, while slow event routing no longer blocks the shared stream or other recipients.
- Windows Tauri fixes address window-state capture deadlocks, input reentrancy, and native focus/menu responsiveness. Desktop startup avoids interactive shell prompts that could block launch.
- Bundled Node is updated to 24.20.0 LTS, and desktop resources include the Node/npm tools needed for first-run runtime setup.
- OpenCode setup keeps executable selection, runtime status, installation/update, and service actions together in Preferences. Diagnostics include clearer cross-platform server information.
- Provider usage fixes include credit-based z.ai coding-plan quotas and refreshed session usage on native step/usage events.
Thanks for contributions
Thanks to @pascalandr, @markerikson, @fitzgpt, @Kondziosz, @shantur, and @bluelovers.
GitHub will append the complete merged pull request and contributor list to the generated release notes.
Full Changelog: v0.19.0...v0.20.0
What's Changed
- Release v0.15.0 - Git operations, Remote servers with self signed, Markdown previews, Apps don't need Node installed and more by @shantur in #387
- Release v0.16.0 - Web previews with direct page feedback, repository cloning, chat search and more by @shantur in #443
- Release v0.17.0 - Provider management, custom workspaces, faster sessions, safer settings, more languages and smoother desktop performance by @shantur in #534
- Release v0.18.0 - Compact mobile UI, tool expansion controls, smoother streaming, session fixes and Winget automation by @shantur in #568
- Release v0.19.0 - Persistent workspaces, customizable panels, provider controls, nested sessions and mobile reliability by @pascalandr in #656
- feat(ui): add Turkish localization by @fitzgpt in #662
- ci: add the OpenCode V2 prerelease channel by @pascalandr in #659
- fix(usage): parse credit-based quota limits for z.ai coding plans by @Kondziosz in #664
- fix(release): preserve PR notes and validate WinGet access by @pascalandr in #658
- feat(opencode): migrate CodeNomad to native V2 by @pascalandr in #647
- fix(tauri): prevent window-state capture deadlocks by @pascalandr in #677
- fix(desktop): avoid incompatible startup shells by @pascalandr in #674
- test(server): isolate automation registry on Linux by @pascalandr in #671
- fix(opencode): reject incompatible V1 binaries by @pascalandr in #672
- fix(ui): shorten chat labels and place general settings before tools by @pascalandr in #682
- fix(ui): preserve history on an empty older message page by @pascalandr in #680
- fix(desktop): prevent shell prompts from blocking startup (#681) by @pascalandr in #684
- fix(ui): follow up transcript rendering, undo and scroll stability by @pascalandr in #683
- chore(i18n): sync Turkish with V2 migration key changes by @fitzgpt in #685
- feat(ui): improve cross-platform server diagnostics by @pascalandr in #643
- fix(ui): restore migrated global subsessions by @pascalandr in #687
- fix(ui): preserve nested scroll gesture ownership by @pascalandr in #688
- feat(pruning): restore opt-in selective deletion through native plugin RPC by @pascalandr in #686
- V2(ui): progressively harmonize the CodeNomad interface by @pascalandr in #667
- fix(ui): compact palette swatches and restore arrow-key navigation by @pascalandr in #692
- fix(opencode): support earlier and modern V2 runtime contracts by @pascalandr in #695
- fix(opencode): support server.info discovery without breaking earlier V2 by @pascalandr in #697
- feat(v2): manage session families across worktrees by @pascalandr in #649
- feat(sessions): flat search results with optional subsessions by @pascalandr in #698
- feat(sessions): add main-session search toggle by @pascalandr in #699
- fix(desktop): persist Preferences window geometry, zoom and navigation by @pascalandr in #703
- fix(desktop): preserve shared OpenCode service after CodeNomad exits by @pascalandr in #702
- fix(ui): preserve permission rejection feedback during refresh by @pascalandr in #701
- test(server): stabilize Git status singleflight regression by @pascalandr in #704
- fix(server): keep filesystem requests responsive during slow disk I/O by @pascalandr in #700
- fix(ui): avoid workspace hydration in Preferences by @pascalandr in #705
- fix(ui): restore the active project before session hydration by @pascalandr in #707
- fix(worktrees): bound ownership refreshes and lazily cache inventories by @pascalandr in #708
- feat(browser): add autonomous native previews by @pascalandr in #666
- fix(ui): recover session startup reads raced by stream connection by @pascalandr in #710
- fix(startup): restore saved sessions promptly and stop plugin heartbeat reloads by @pascalandr in #712
- fix(browser): remove redundant web preview header by @pascalandr in #713
- fix(updates): migrate OpenCode to the stable CLI package by @pascalandr in #715
- fix(environment): refresh profile variables before each prompt by @pascalandr in #714
- fix(ui): hide the transcript scrollbar beside the timeline by @pascalandr in #716
- fix(ui): keep command and search windows non-modal and persistent by @pascalandr in #717
- feat(sessions): fork after user and assistant messages by @pascalandr in #718
- chore(desktop): upgrade bundled Node to 24.20.0 LTS by @pascalandr in #679
- fix(events): isolate slow routing from the shared native stream by @pascalandr in #719
- fix(ui): hide only the timeline scrollbar by @pascalandr in #720
- fix(issues): require CodeNomad and OpenCode versions by @pascalandr in #721
- fix(chat): hide system context updates by default by @pascalandr in #727
- fix(opencode): align client and plugin with 2.0.11 contracts by @pascalandr in #728
- docs(readme): replace stale star history with GitHub stars badge by @pascalandr in #732
- feat(history): add full-history search, cleanup and global timeline navigation by @pascalandr in #723
- docs(readme): restore live star history alongside the stars badge by @pascalandr in #734
- feat(opencode): add managed setup and stable runtime admission by @pascalandr in #696
- fix(history): search edit diffs stored in tool metadata by @markerikson in #735
- fix(ui): refresh session usage info on step and usage events by @markerikson in #731
- fix(ui): read edit tool diff from OpenCode 2.x metadata.files by @markerikson in #730
- fix(ui): update tool visibility settings for OpenCode 2.x tool names by @markerikson in #733
- fix(ui): restore a dedicated OpenCode setup and management dialog by @pascalandr in #736
- feat(menu): add panel and timeline toggles to View by @pascalandr in #737
- fix(worktrees): unblock existing-worktree selection on large repositories by @pascalandr in #740
- fix(i18n): add missing Turkish outline loading string by @fitzgpt in #742
- fix(ui): preserve semantic icons for historical timeline tools by @pascalandr in #738
- feat(chat): add native /btw side questions by @pascalandr in #741
- fix(startup): prioritize restored conversations over secondary hydration by @pascalandr in #743
- fix(settings): restore inline OpenCode executable management by @pascalandr in #744
- fix(startup): unblock restoration during worktree Git discovery by @pascalandr in #745
- fix(automation): remove the active-conversation targeting requirement by @pascalandr in #746
- fix(startup): keep Git panels from blocking conversation restoration by @pascalandr in #747
- fix(tauri): retain View menu state across native focus changes by @pascalandr in #748
- fix(auth): recover browser sessions after server restart by @pascalandr in #749
- fix(proxy): unblock message sends on session instruction sync by @pascalandr in #751
- fix(sessions): preserve populated sessions during automatic cleanup by @pascalandr in #755
- fix(opencode): qualify 2.0.15 and preserve generated proxy URLs by @pascalandr in #752
- fix(git): keep conversations usable without backend Git by @pascalandr in #757
- fix(opencode): share user installation with terminal clients by @pascalandr in #756
- fix(opencode): retire private runtime fallback and restore first-run setup by @pascalandr in #760
- feat(ui): add workspace-root navigation to directory browser by @bluelovers in #724
- fix(setup): keep startup service status consistent with fresh checks by @pascalandr in #765
- fix(ui): group legacy tools under Other and customize Status tokens by @pascalandr in #761
- fix(info): replace broken Dispose instance with V2 configuration reload by @pascalandr in #767
- fix(opencode): use native upgrade for live Windows runtime updates by @pascalandr in #769
- fix(chat): display images returned by MCP tools by @pascalandr in #766
- chore(opencode): qualify 2.0.16 with aligned clients and plugin by @pascalandr in #772
- fix(tauri): prevent Windows input reentrancy deadlocks by @pascalandr in #773
- fix(models): keep active-session model choices from switching back by @pascalandr in #771
- fix(sessions): keep Stop and double Escape from restarting the parent by @pascalandr in #770
- fix(ui): retain connection dot in compact message headers by @pascalandr in #774
- feat(chat): upload files from device alongside server attachments by @pascalandr in #729
- perf(V2): bound transcript memory by @pascalandr in #648
- feat(plugins): add scoped V2 plugin activation controls by @pascalandr in #726
- fix(chat): display user HTML as literal source by @pascalandr in #777
- fix(plugins): simplify activation controls UI (follow-up #726) by @pascalandr in #778
- fix(chat): honor collapse preference for single-step reasoning by @pascalandr in #779
- chore(release): prepare stable 0.20.0 by @pascalandr in #780
- Release v0.20.0 - OpenCode V2, full-history navigation, worktrees and native browser previews by @pascalandr in #781
New Contributors
- @fitzgpt made their first contribution in #662
- @Kondziosz made their first contribution in #664
- @markerikson made their first contribution in #735
Full Changelog: v0.19.0...v0.20.0