Find a file
Pascal André 4c50829da0
fix(ui): defer session virtualization for closed left panel (#612)
## Summary
- do not mount SessionList while the temporary left drawer is floating
and closed
- keep the session-list error state mutually exclusive with virtualized
rows
- register focused visibility-policy tests in the PR workflow

## Root cause
SUID constructs temporary Drawer children while open is false. This
occurs both after restarting with a persisted closed panel and when
narrowing the window into mobile mode, which forces the left panel to
become unpinned and closed. SessionSidebar then mounted the virtua
Virtualizer in a detached staging document. virtua resolves
ResizeObserver through ownerDocument.defaultView, which is null for that
document.

The failure is timing-dependent: if session hydration publishes rows
while that closed mobile Drawer is detached, the synchronous render
exception escapes through setSessionPage and is caught by fetchSessions
as if the successful API request had failed. Opening the panel later
therefore reveals an empty list or the misleading Unable to load
sessions error. If hydration finishes under a different drawer
lifecycle, the bug does not appear.

Because the error UI and virtualized rows were both mounted, Retry
cleared the error and immediately hit the same poisoned lifecycle again.

## Behavior
Session fetching and startup restore continue while the panel is closed.
The virtualized DOM is created only after the panel is open or pinned.
Genuine list errors dispose the rows; Retry can then mount a clean
virtualizer after succeeding.

## Reproduction
1. Narrow the window until CodeNomad enters mobile mode and the left
panel can no longer remain pinned.
2. Leave the sessions panel closed while sessions hydrate, or restart in
that state.
3. Open the left panel.
4. Before this fix, the list may be empty or show Unable to load
sessions with a ResizeObserver null error.

## Validation
- 19 focused session visibility, tree, and pagination tests
- UI TypeScript typecheck
- production Vite build
- full Windows Tauri release build
- NSIS installer bundle
- regression test included in PR CI
2026-07-19 17:19:32 +01:00
.github fix(ui): defer session virtualization for closed left panel (#612) 2026-07-19 17:19:32 +01:00
.opencode feat(yolo): move permission auto-accept (Yolo) to the server (#561) 2026-07-08 21:13:44 +02:00
dev-docs build: publish deb and portable tar.gz Linux artifacts (#492) 2026-07-12 19:29:33 +02:00
docs feat(ui): support bracket math delimiters (#588) 2026-07-14 14:00:26 +02:00
images Move screenshots to correct folder 2025-11-21 21:59:58 +00:00
packages fix(ui): defer session virtualization for closed left panel (#612) 2026-07-19 17:19:32 +01:00
scripts chore: TASK-075 automate Winget updates on release (#513) 2026-06-03 09:03:46 +02:00
temp Bump to v0.11.2 2026-02-17 18:47:21 +00:00
.gitignore chore: ignore local artifacts and add cloudflare lockfile 2026-01-22 16:42:47 +00:00
AGENTS.md Improve compact mobile UI controls (#564) 2026-06-19 13:52:26 +01:00
BUILD.md build: publish deb and portable tar.gz Linux artifacts (#492) 2026-07-12 19:29:33 +02:00
CONTRIBUTING.md docs: add CONTRIBUTING.md guide for new contributors (#484) 2026-06-13 14:01:04 +02:00
LICENSE chore(license): add MIT license 2026-02-02 11:22:49 +00:00
package-lock.json feat(desktop): persist and restore UI state across restarts (#578) 2026-07-15 10:22:23 +01:00
package.json Bump version to 0.18.0 2026-06-19 13:55:00 +01:00
README.md build: publish deb and portable tar.gz Linux artifacts (#492) 2026-07-12 19:29:33 +02:00
THIRD_PARTY_NOTICES.md feat(usage): show provider quota in session status (#584) 2026-07-15 10:25:00 +01:00

CodeNomad

The AI Coding Cockpit for OpenCode

CodeNomad transforms OpenCode from a terminal tool into a premium desktop workspace — built for developers who live inside AI coding sessions for hours and need control, speed, and clarity.

OpenCode gives you the engine. CodeNomad gives you the cockpit.

Multi-instance workspace


Features

  • 🚀 Multi-Instance Workspace
  • 🌐 Remote Access
  • 🧠 Session Management
  • 🎙️ Voice Input & Speech
  • 🌳 Git Worktrees
  • 💬 Rich Message Experience
  • 🧩 SideCars
  • ⌨️ Command Palette
  • 📁 File System Browser
  • 🔐 Authentication & Security
  • 🔔 Notifications
  • 🎨 Theming
  • 🌍 Internationalization

Getting Started

🖥️ Desktop App

Available as both Electron and Tauri builds — choose based on your preference.

Download the latest installer for your platform from Releases.

Platform Formats
macOS DMG, ZIP (Universal: Intel + Apple Silicon)
Windows NSIS Installer, ZIP (x64, ARM64)
Linux Tauri deb, Electron portable tar.gz (x64)

The Tauri deb is currently built and installation-tested on Ubuntu 24.04. Compatibility with older Debian-based distributions is not yet guaranteed.

💻 CodeNomad Server

Run as a local server and access via browser. Perfect for remote development.

npx @neuralnomads/codenomad --password <your-password> --launch

Authentication required: The server requires a password on first run. You can pass it via --password, the CODENOMAD_SERVER_PASSWORD environment variable, or create an auth.json file (see Server Documentation).

Self-signed certificate: On first launch with HTTPS enabled (the default), your browser will show a "Your connection is not private" warning. This is expected — the server generates a local self-signed certificate automatically. Click Advanced → Proceed to localhost to continue. For local-only use without the warning, run with --https=false --http=true.

See Server Documentation for flags, TLS, auth, and remote access.

🧪 Dev Releases

Bleeding-edge builds from the dev branch:

npx @neuralnomads/codenomad-dev --password <your-password> --launch

SideCars

SideCars let you open local web tools inside CodeNomad as tabs.

Configuration
  • Name: Display name used in CodeNomad
  • Port: Local HTTP or HTTPS service running on 127.0.0.1:<port>
  • Base path: Mounted under /sidecars/:id
  • Prefix mode:
    • Preserve prefix forwards the full /sidecars/:id/... path upstream
    • Strip prefix removes /sidecars/:id before forwarding the request upstream
VSCode (OpenVSCode Server)

Run with Docker:

docker run -it --init -p 8000:3000 -v "${HOME}:${HOME}:cached" -e HOME=${HOME} gitpod/openvscode-server --server-base-path /sidecars/vscode

Add SideCar as:

  • Name: VSCode
  • Port: http://127.0.0.1:8000
  • Base path: /sidecars/vscode
  • Prefix mode: Preserve prefix
Terminal (ttyd)

Run with:

ttyd --writable zsh

Add SideCar as:

  • Name: Terminal
  • Port: http://127.0.0.1:7681
  • Base path: /sidecars/terminal
  • Prefix mode: Strip prefix

Requirements

  • OpenCode CLI — must be installed and in your PATH
  • Node.js 18+ — for server mode or building from source

Development

CodeNomad is a monorepo built with:

Package Description
packages/server Core logic & CLI — workspaces, OpenCode proxy, API, auth, speech
packages/ui SolidJS frontend — reactive, fast, beautiful
packages/electron-app Desktop shell — process management, IPC, native dialogs
packages/tauri-app Tauri desktop shell (experimental)

Quick Start

git clone https://github.com/NeuralNomadsAI/CodeNomad.git
cd CodeNomad
npm install
npm run dev

Troubleshooting

macOS: "CodeNomad.app is damaged and can't be opened"

Gatekeeper flag due to missing notarization. Clear the quarantine attribute:

xattr -dr com.apple.quarantine /Applications/CodeNomad.app

On Intel Macs, also check System Settings → Privacy & Security on first launch.

Linux (Wayland + NVIDIA): Tauri App closes immediately

WebKitGTK DMA-BUF/GBM issue. Run with:

WEBKIT_DISABLE_DMABUF_RENDERER=1 codenomad-tauri

See full workaround in the original README.


Community

Star History


Built with ♥ by Neural Nomads · MIT License