Find a file
Pascal André e9e94a6723
fix(opencode): reject incompatible V1 binaries (#672)
## Summary

Closes #669.

CodeNomad V2 requires the official OpenCode V2 shared-service lifecycle.
A legacy binary must not be accepted merely because `--version`
succeeds, nor should opening a folder display a raw legacy CLI help
dump. This is an actionable compatibility fix, **not V1 runtime support
or automatic installation**: install/select `opencode2` to open the
workspace.

- Validate the selected executable using only `--version` and `service
--help`; neither probe starts or changes the daemon.
- Require positive service-help evidence for `start`, `status`, and
`get`, without pinning a release number or rejecting custom version
labels.
- Recognize legacy root help, including ANSI/CRLF, stdout/stderr, and
exit-zero wrappers. Preserve the localized V2 diagnosis for previously
saved incompatible paths during the actual host/WSL lifecycle.
- Run both validation probes asynchronously with a 5-second subprocess
timeout and 64 KiB output limit, leaving the shared backend responsive
while a CLI is slow.
- Treat saved versions as display metadata only: explicit add/browse
always validates the path again.
- Match the compatibility error code precisely, including its JSON HTTP
envelope, so unrelated missing-file/configuration errors are not hidden
by a matching filename.
- Reuse the existing translated message in all ten locales. No daemon
ownership, V1 fallback, package update, or native-shell-selection
change.

## Follow-up verification of the original PR

The original head `226e2d7b` already fixed the exact reported failure
with a real V1 binary. Independent rechecking found and corrected
adjacent gaps in this same PR:

| Check | Original PR | Completed PR |
| --- | --- | --- |
| Real OpenCode 1.18.25 rejected; real V2 accepted | PASS | PASS |
| Empty/unrelated successful help rejected | FAIL | PASS |
| Legacy help with exit zero localized at launch | FAIL | PASS |
| Other backend work proceeds during slow probes | FAIL | PASS |
| Explicit add rechecks a persisted V1 version | FAIL | PASS |
| Unrelated diagnostic mentioning `opencode_v2_required` retained | FAIL
| PASS |

The new regression tests were run against the old production code first:
three assertions failed (false capability acceptance, exit-zero help,
unrelated-error masking), then passed after the fix. A separate
source-extraction check executes the unchanged published probe and
component validation body: two 250 ms subprocess delays block the old
probe for about 638 ms, versus a Promise returned in about 5 ms after
the fix; a cached V1 version previously produced zero validation calls
and now produces one and rejects the path.

## Validation of the compatibility fix (`903d9159`)

- Full server suite on Windows: **391 passed, 2 skipped**.
- Electron native suite: **189 passed**.
- Focused compatibility/lifecycle/updater/HTTP/UI diagnostic suite: **79
passed** on Windows.
- Server, UI and Electron typechecks passed; server and UI production
builds passed.
- `git diff --check` and workflow YAML validation passed.
- Real CLI checks: V1 **1.18.25** refused with `opencode_v2_required`;
V2 beta builds **19151/19192** accepted; authenticated discovery of the
existing shared daemon succeeds. No service stop/restart or settings
mutation was performed.
- Actual subprocess fixtures exercise spaced/apostrophe/Unicode paths,
stdout/stderr and exit codes. HTTP integration proves that validation
neither mutates preferences nor blocks another request.
- Existing regressions retain stopped/running daemon discovery, startup
environment isolation, password-error redaction, deadlines, WSL command
forwarding, authenticated health, shared-service ownership and updater
behavior.
- Independent focused CI matrix passed on **Linux and macOS 26 ARM64**
(77 passed, 2 Windows-only skips each) and **Windows** (79 passed), in
run `34036886140`.

## Update with current `dev` / conflict resolution

Updated this branch with `dev` at `81aa4d24`, which now includes **#671,
#674 and #677**. The only textual conflict was in
`.github/workflows/pr-build.yml`, where #672 and #677 added CI jobs at
the same location. Both the OpenCode compatibility matrix and the macOS
ARM64 Tauri tests are retained, with both required by the package-build
gate. Parsed workflow comparisons verify that every non-build job is
identical to its originating parent and no build dependency was dropped.

The previously blocking Linux automation-registry fix **#671 is now
included through `dev`**, rather than duplicated. The full CI matrix is
rerunning on this combined state; require that result before merge.

Local checks after resolving the conflict: **391 server tests passed, 2
skipped; 192 Electron tests passed; server/UI/Electron typechecks
passed; workflow parent-preservation assertions and `git diff --check`
passed**. The conflict resolution itself changes no application code.

Automated CLI/HTTP tests are not an interactive Electron/macOS ARM64
smoke test on the reporter's machine, and cannot establish the absolute
absence of every possible side effect.

Maintenance: files already touched by the original PR remain oversized:
`packages/server/src/api-types.ts` (536 lines) and
`packages/ui/src/App.tsx` (855 lines). This follow-up does not grow
those files.
2026-09-06 22:40:11 +02:00
.github fix(opencode): reject incompatible V1 binaries (#672) 2026-09-06 22:40:11 +02:00
.opencode feat(opencode): migrate CodeNomad to native V2 (#647) 2026-09-04 11:36:11 +01:00
dev-docs feat(opencode): migrate CodeNomad to native V2 (#647) 2026-09-04 11:36:11 +01:00
docs fix(release): preserve PR notes and validate WinGet access (#658) 2026-08-29 16:02:35 +01:00
images Move screenshots to correct folder 2025-11-21 21:59:58 +00:00
packages fix(opencode): reject incompatible V1 binaries (#672) 2026-09-06 22:40:11 +02:00
scripts feat(opencode): migrate CodeNomad to native V2 (#647) 2026-09-04 11:36:11 +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 feat(opencode): migrate CodeNomad to native V2 (#647) 2026-09-04 11:36:11 +01:00
BUILD.md build: publish deb and portable tar.gz Linux artifacts (#492) 2026-07-12 19:29:33 +02:00
CONTRIBUTING.md feat(opencode): migrate CodeNomad to native V2 (#647) 2026-09-04 11:36:11 +01:00
DESKTOP_V2_COMPARISON.md feat(opencode): migrate CodeNomad to native V2 (#647) 2026-09-04 11:36:11 +01:00
LICENSE chore(license): add MIT license 2026-02-02 11:22:49 +00:00
MIGRATION_V2.md feat(opencode): migrate CodeNomad to native V2 (#647) 2026-09-04 11:36:11 +01:00
package-lock.json feat(opencode): migrate CodeNomad to native V2 (#647) 2026-09-04 11:36:11 +01:00
package.json feat(opencode): migrate CodeNomad to native V2 (#647) 2026-09-04 11:36:11 +01:00
README.md feat(opencode): migrate CodeNomad to native V2 (#647) 2026-09-04 11:36:11 +01: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.

Previews use token-scoped URLs inside opaque-origin sandboxes. Loopback HTTP native previews receive a dedicated .preview.localhost origin so root routes, POSTs, and live reload behave normally; HTTPS, LAN, and web hosts use the capability path. Element comments use a source-checked message bridge.

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