Find a file
Omer Cohen 681755888f
fix(mobile): tappable instance/project tab bar while session drawer is open (#459)
## Summary

Fixes a mobile UX bug where, with the session list (left drawer) open on
phone layout, the still-visible instance/project tab bar at the top was
non-interactive. Tapping a tab did nothing — users had to close the
drawer first and then switch projects/instances.

After this change, tapping a tab in that bar switches the
instance/project **and** the drawer auto-closes in a single gesture,
matching user expectation.

## Root cause

On phone (`max-width: 767px`), `InstanceShell` renders the left session
sidebar via MUI's `Drawer variant="temporary"`. The drawer paper is
offset down to `floatingTopPx()` so the instance tab bar remains
visually visible above it. However, MUI's `Modal` Backdrop is `position:
fixed; inset: 0` and covers the entire viewport — including the area
over the tab bar. The backdrop is styled `backgroundColor: transparent`
(so it's invisible) but it still captures pointer events at `z-index:
60`. Taps over the tab bar hit the transparent backdrop → MUI calls
`onClose` (closing the drawer) but the tab's click handler never fires.

## Implementation

1. **`packages/ui/src/components/instance/instance-shell2.tsx`** —
Constrain the MUI Drawer Backdrop via `sx` overrides on both the left
(session list) and right drawers so the backdrop is bound to the drawer
paper's vertical range (`top: floatingTopPx(); height:
floatingHeight();`) instead of fullscreen. Taps over the tab bar now
reach the tab buttons.

2. **`packages/ui/src/styles/panels/tabs.css`** — Lift
`.tab-bar-instance` to `position: relative; z-index: 70` so it stacks
deterministically above the drawer (z-index 60) across browsers as
defense-in-depth.

3. **`packages/ui/src/components/instance/shell/useDrawerChrome.ts` +
`instance-shell2.tsx`** — Expose `closeFloatingDrawersIfAny` from
`useDrawerChrome` and call it from an `InstanceShell` effect that fires
when `props.isActiveInstance` flips `true → false`. This closes any open
floating drawer on the instance the user just switched away from, so its
previously-open state doesn't bleed back when the user returns to that
tab later.

Tablet (>=768px) and desktop (>=1280px) layouts use pinned drawers (no
temporary modal), so the backdrop constraint and z-index lift are inert
there. The fix applies symmetrically to the right drawer on phone.

## Verification

- `tsc --noEmit` clean.
- `vite build` clean.
- Manual mobile-emulation checklist in the task file
(`tasks/done/058-mobile-session-list-blocks-tab-switch.md`) and SUMMARY
in `evidences/058-mobile-session-list-blocks-tab-switch/`.

## Reviewer manual check (phone viewport <=767px)

- Open session list drawer. Tap a different instance tab → it activates
AND drawer closes.
- Tap "+" while drawer open → folder picker opens, drawer closes.
- Tap Settings / Notifications / Remote while drawer open → action
fires, drawer closes.
- Same checks against the right drawer.
- Tap area below tab bar but outside drawer paper → drawer still closes
(existing backdrop dismissal preserved).
- Resize to tablet and desktop widths → pinned drawers unaffected.
- No visual regression in light or dark theme.

---------

Co-authored-by: Ubuntu <omer@Omer.dn3uxh3znnmu5eefnjnut0i1af.tlvx.internal.cloudapp.net>
Co-authored-by: Shantur Rathore <i@shantur.com>
2026-05-16 16:07:46 +01:00
.github build: bundle node runtime for desktop packages 2026-05-04 20:08:04 +01:00
.nomadworks Disable NomadWorks for now 2026-05-07 17:57:22 +01:00
.opencode Use never release notes format 2026-05-14 10:38:03 +01:00
dev-docs refactor message stream layout 2025-12-02 19:23:05 +00:00
docs Init nomadworks 2026-04-26 12:06:06 +01:00
images Move screenshots to correct folder 2025-11-21 21:59:58 +00:00
packages fix(mobile): tappable instance/project tab bar while session drawer is open (#459) 2026-05-16 16:07:46 +01:00
scripts Reduce App package sizes (#453) 2026-05-15 19:13:13 +01:00
tasks Init nomadworks 2026-04-26 12:06:06 +01: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 docs: require detailed commit messages 2026-05-07 17:45:31 +01:00
BUILD.md Rename electron app package to @neuralnomads/codenomad-electron-app 2025-11-21 00:10:31 +00:00
codemap.yml Init nomadworks 2026-04-26 12:06:06 +01:00
LICENSE chore(license): add MIT license 2026-02-02 11:22:49 +00:00
package-lock.json Reduce App package sizes (#453) 2026-05-15 19:13:13 +01:00
package.json Increment version to 0.16.0 2026-05-14 10:40:21 +01:00
PROGRESS.md chore: rebrand client and add icon tooling 2025-11-13 22:58:57 +00:00
README.md docs: add SideCars README section 2026-04-16 09:59:53 +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 AppImage, deb, tar.gz (x64, ARM64)

💻 CodeNomad Server

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

npx @neuralnomads/codenomad --launch

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

🧪 Dev Releases

Bleeding-edge builds from the dev branch:

npx @neuralnomads/codenomad-dev --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

See full workaround in the original README.


Community

Star History


Built with ♥ by Neural Nomads · MIT License