Skip to content

fix(opencode): reject incompatible V1 binaries - #672

Merged
pascalandr merged 3 commits into
devfrom
fix/issue-669-opencode-v1-detection
Sep 6, 2026
Merged

fix(opencode): reject incompatible V1 binaries#672
pascalandr merged 3 commits into
devfrom
fix/issue-669-opencode-v1-detection

Conversation

@pascalandr

@pascalandr pascalandr commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

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.

Probe the selected CLI for the non-mutating OpenCode V2 service capability before accepting it in settings. Detect legacy root-help output, including ANSI-decorated stderr, without introducing a brittle exact-version gate or starting the shared daemon.

Translate the compatibility failure into an actionable opencode2 message across every supported locale. Existing saved V1 selections receive the same focused launch error instead of the full CLI usage dump, while compatible host and WSL lifecycle behavior remains unchanged.

Cover both validation-time and launch-time detection and verify the real V1/V2 binaries alongside the complete server suite, desktop typechecks, and production server/UI build.
@pascalandr

Copy link
Copy Markdown
Contributor Author

CI note: the Linux failure is the baseline registry-path test introduced on dev, not this PR. It is fixed independently in #675; that PR's Linux and Windows test jobs are green. Please rerun this PR after #675 lands.

@pascalandr pascalandr left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gatekeeper review of 226e2d7b

No blocking code findings were found in the binary capability probe, launch-time fallback, API contract, localized UI error handling, or secret/error sanitization.

The implementation checks the actual V2 service lifecycle instead of imposing an exact version gate, recognizes the successful root-help behavior of V1, bounds the capability probe, and preserves actionable generic failures for non-V1 errors.

Validation

  • Root UI/Electron typecheck passed.
  • 29 focused server/UI tests passed.
  • git diff --check passed.

Gate status

Code-approved, CI-blocked. The current Linux failure is the inherited automation-registry test fixed by #671, not a defect in this branch. Rerun the complete PR matrix after #671 lands before merging.

Complete #669's compatibility diagnosis without blocking the shared backend while checking a selected executable. Run bounded asynchronous version/help subprocesses and require positive service command evidence, rather than accepting arbitrary exit-zero output. Keep the updater's independent version-only contract and custom version labels unchanged.

Recognize legacy root help from successful wrappers as well as failed status commands on host and WSL. Revalidate explicit binary additions even when an older version is cached, and match the launch-error marker precisely so ordinary missing-file and configuration diagnostics cannot be hidden by a matching path.

Add real subprocess and HTTP regressions for backend responsiveness, read-only validation, quoted/Unicode paths, stdout/stderr and exit codes. Cover capability parsing, execution failures, updater behavior and unrelated launch errors; add a focused Linux/Windows/macOS ARM64 CI matrix without folding in #671's separate registry fix.

Validation: 391 server tests passed with 2 skipped, 189 Electron tests passed, and 79 focused tests passed on Windows. Server/UI/Electron typechecks, production server/UI builds and diff/workflow checks pass. Real V1 1.18.25 is rejected and V2 beta 19151/19192 connects to the existing authenticated service without changing the daemon. Negative controls reproduce the published head's missed diagnostics, cached-version bypass and synchronous probe stall. Interactive Electron/macOS verification remains outstanding.
@pascalandr

Copy link
Copy Markdown
Contributor Author

Independent verification and follow-up published as 903d915, fast-forward in this same PR. The exact reported V1 failure was already fixed, but the review reproduced five adjacent gaps: false acceptance of empty successful help; missing localization for exit-zero legacy wrappers; synchronous backend stalls; persisted-version bypass on explicit add; and unrelated-error masking by substring matching. All are addressed and documented in the updated description. Local validation: 391 server tests passed (2 skipped), 189 Electron tests passed, 79 focused tests passed in 10/10 repetitions, all typechecks and server/UI builds passed. Real timeout/output-limit probes also passed: version/help sleepers are stopped around 5 seconds while the event loop remains responsive, and oversized help is rejected. Real V1 1.18.25 is refused; real V2 beta 19151/19192 validation and authenticated shared-service discovery pass without daemon mutation. The new Linux/Windows/macOS ARM64 focused CI matrix is running. This is an actionable V2 requirement, not automatic installation or V1 runtime support; a graphical test on the reporter's Mac remains outstanding.

@pascalandr

Copy link
Copy Markdown
Contributor Author

CI verification is complete for 903d915: https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/34036886140 . The focused compatibility/lifecycle/updater/HTTP/diagnostic suite passes on Ubuntu (77 passed, 2 Windows-only skips), macOS 26 ARM64 (77 passed, 2 Windows-only skips), and Windows (79 passed). The Windows Tauri job also passes all 139 applicable Rust tests. The full Linux server suite fails only the inherited 'prunes stale registry pressure before limiting discovery' test, with ENOENT on /tmp/codenomad-automation-stale-*/CodeNomad/automation-bridges (390 passed, 1 failed, 2 skipped), confirming the separate #671 prerequisite. Packaging is skipped and the artifact-comment job fails as a consequence of that run's failure. The extra red, unexpanded 'tests-opencode-compatibility' check belongs to superseded run 34036885601, cancelled before any test steps executed; all three actual matrix jobs are green. No additional production defect is indicated by these logs. Integrate #671 and require a complete green matrix before merge; an interactive Electron/macOS smoke test remains recommended.

Update #672 with dev at 81aa4d2, including the integrated #671 registry isolation, #674 POSIX shell selection and #677 window persistence fixes. This brings in the previously missing Linux CI prerequisite without duplicating its patch.

Resolve the sole conflict in pr-build.yml by retaining both the OpenCode compatibility matrix and macOS ARM64 Tauri test job, and requiring both before packaging. Every non-build job is structurally identical to its originating parent and every parent build dependency is preserved. No application code needed manual conflict resolution.

Validation after integration: 391 server tests passed with 2 skipped, all 192 Electron tests passed, and server/UI/Electron typechecks passed. YAML parsing, exact parent-job comparisons and git diff --check pass. The complete remote matrix must rerun on the combined branch before merging the PR.
@pascalandr

Copy link
Copy Markdown
Contributor Author

Resolved the conflict with current dev in merge commit 2e33cf8 (no force-push). The only conflict was pr-build.yml: both the #672 OpenCode compatibility matrix and #677 macOS ARM64 Tauri tests are retained, together with every build dependency. Parsed comparisons confirm every non-build job is identical to its originating parent. Application code needed no manual resolution. dev now includes #671, #674 and #677, so the previously missing Linux registry prerequisite is incorporated normally. Post-merge local validation passes 391 server tests (2 skipped), all 192 Electron tests, server/UI/Electron typechecks, workflow assertions and diff checks. The PR remains open and the complete CI matrix is rerunning; no PR merge was performed.

@pascalandr
pascalandr requested review from a team and removed request for a team September 6, 2026 20:26
@pascalandr
pascalandr merged commit e9e94a6 into dev Sep 6, 2026
17 checks passed
@pascalandr
pascalandr deleted the fix/issue-669-opencode-v1-detection branch September 6, 2026 20:40
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown

PR builds are available as GitHub Actions artifacts:

https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/34057639873

Artifacts expire in 7 days.
Artifacts:

  • pr-672-2e33cf8bc49c62271c88052125011b2d6dea52e2-tauri-macos
  • pr-672-2e33cf8bc49c62271c88052125011b2d6dea52e2-tauri-windows
  • pr-672-2e33cf8bc49c62271c88052125011b2d6dea52e2-electron-macos
  • pr-672-2e33cf8bc49c62271c88052125011b2d6dea52e2-electron-linux
  • pr-672-2e33cf8bc49c62271c88052125011b2d6dea52e2-tauri-linux
  • pr-672-2e33cf8bc49c62271c88052125011b2d6dea52e2-tauri-macos-arm64
  • pr-672-2e33cf8bc49c62271c88052125011b2d6dea52e2-electron-windows

pascalandr pushed a commit that referenced this pull request Sep 9, 2026
## Summary

Follow-up to #662 (Turkish localization). The native V2 migration (#647)
and the follow-up commits (#672, #682) changed the i18n key set without
updating `tr/`, so the Turkish UI currently renders 76 English strings
and carries 35 stale keys.

This PR brings `tr/` back to 1:1 key parity with `en/` (1721 = 1721
leaves, verified programmatically):

**Added (76 keys) across 5 files:**
- `instance.ts` — background shell statuses
(running/exited/timeout/killed), PID/exit-code labels, stop-and-remove +
remove confirmation dialog
- `messaging.ts` — search failure/retry, reasoning step counters,
remove-tools-and-reasoning flow (replaces the old
delete-message/bulk-delete keys), prompt background action, prompt queue
(steer/queue delivery, actions, errors)
- `toolCall.ts` — `permissionApproval.kind.form` + new `formRequest.*`
block (submit/cancel/errors/validation)
- `settings.ts` — V2 update notice, provider command-auth method +
waiting dialog, provider credit balance, follow-up behavior (steer vs
queue)
- `commands.ts` — stop-workspace and remove-session-technical-parts
commands (labels/descriptions/keywords, keywords translated per existing
convention)

**Removed (35 keys)** that no longer exist in `en/`: old
delete-message/bulk-delete block, `messageBlock.tool.deletePart.*`,
`tauriNativeEventTransport`, old background-process
status/output/notify/stop/terminate keys.

## Verification
- Leaf-level parity check via direct module import: `EN 1721 = TR 1721`,
missing 0, extra 0 (script in PR discussion)
- `{count}`/`{pid}`/`{toolCount}` style placeholders preserved 1:1
- Terminology consistent with the shipped glossary: "ek" (attachment),
"Prompt" kept literal, "workspace" kept literal, keywords translated
like existing entries

---------

Co-authored-by: fitzgpt <fitz@gpt.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Can not open a folder -> Opencode throws an error when executing opencode service status

1 participant