* feat: add Windows ARM64 support with x64-baseline CLI workaround
Windows ARM64 native opencode.exe fails with a Bun FFI/TinyCC dlopen
error (anomalyco/opencode#19130). As a temporary workaround:
- Bundle x64-baseline OpenCode CLI on ARM64 instead of native ARM64
(prepare-opencode-cli.mjs, env-runtime.js)
- Disable OpenCode self-upgrade on ARM64 in server, VS Code, and UI
(upgrade-capability.js, opencode-upgrade-runtime.ts, useUIStore.ts,
OpenCodeCliSettings.tsx, search.ts, SettingsView.tsx, platform.ts)
- Add ARM64 Windows cross-compile builds to release and smoke workflows
(release.yml, release-desktop-smoke.yml)
- Refactor Windows latest.yml to use combine-electron-manifests pattern
matching macOS, since two arches now produce per-arch manifests
The CI ARM64 build itself is permanent; only the x64-baseline CLI
bundling and upgrade disablement are temporary and should be reverted
when the upstream issue is resolved.
* fix(desktop): select Windows updater by architecture
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Adds an opt-in input to build Linux Electron artifacts in the smoke workflow
Builds and validates AppImage releases for x64 and arm64
Uploads Linux AppImage and update manifest artifacts
Complete rebuild of voice input on a server-authoritative streaming
architecture, replacing the legacy Web Speech / whole-blob / WASM engines
and the dead voice-agent layer (~4k lines removed).
Speech-to-text (dictation):
- Client streams 16 kHz mono PCM16 chunks over /api/dictation/ws with
seq/ack ordering; buffered audio is retained and replayed on reconnect
- Server transcribes and streams live partial transcripts back;
segments auto-commit every ~15s with silence suppression and adaptive
finalization timeouts
- Local provider (default, zero config): sherpa-onnx models in a forked
worker process — auto-download with progress, staged extraction with
verification, corrupt-model auto-recovery, idle shutdown after 5 min
- Model catalog with settings picker (accuracy/speed ratings, sizes,
download/delete): Parakeet TDT v2 (English) and v3 (25 European
languages, auto-detected), Whisper base and tiny (multilingual, light)
- OpenAI-compatible provider for any Whisper endpoint
- Composer overlay with live transcript, volume meter, timer, and
cancel / insert / insert-and-send actions; failed transcriptions keep
their audio for retry or accepting the partial text as-is
- Configurable keyboard shortcut (default mod+alt+v) toggles dictation;
Enter confirms and Escape cancels while recording
- Overlay is pixel-aligned with the composer (measured footer height,
matching paddings/typography/gaps) — no layout shift when toggling
Text-to-speech:
- Local Kokoro provider (English, 11 voices) synthesized in the same
worker via /api/dictation/tts/speak, managed by the shared model
pipeline; sentence-pipelined playback keeps time-to-first-audio at
~1 sentence regardless of message length, and stop cancels in-flight
synthesis
- Sanitizer keeps inline-code content (strips backticks only), reads
interword slashes aloud, and removes only absolute file paths
Settings:
- Voice page unified: a single read-aloud toggle owns all playback
options (the confusing "Enable Voice Mode" is gone); a new "Enable
voice input" toggle (default on, persisted to settings.json) hides
the composer mic entirely when disabled
Mobile and transport:
- iOS/Android microphone permissions added (dictation was previously
impossible on mobile)
- Fixed Android WebSocket upgrades: the Capacitor WebView origin
(https://localhost) was missing from the packaged-client allowlist,
403-ing every WS connection — root cause of the old mobile SSE lock,
which is now removed for all transports
Security and conventions:
- All HTTP routes sit behind the global /api auth gate; the WS upgrade
explicitly validates the UI session and origin, with oc_url_token
narrowly allowlisted and covered by tests; the dictation socket mints
a fresh URL token before connecting
- Routes register before the generic OpenCode proxy; the client goes
through runtimeFetch/getRuntimeUrlResolver, and runtime switches
reset the dictation socket
- VS Code deliberately reports dictation as unavailable (no server
process in that runtime)
CI: workflow Node bumped 20 -> 22 to match the repo engines and fix
better-sqlite3 installs broken by node-gyp@latest on Node 20.
New dependency: sherpa-onnx-node (prebuilt N-API; macOS/Linux x64+arm64,
Windows x64 — Windows-on-ARM falls back to the OpenAI-compatible provider)
Bundle the official OpenCode CLI into Electron desktop builds instead of relying on whichever opencode executable happens to be first on PATH. Pin @opencode-ai/sdk to an exact version and use that version as the source of truth for the downloaded CLI artifact.
Add an Electron prepare script that maps the current platform/arch to the official OpenCode release artifact, downloads it from GitHub releases, caches the archive under packages/electron/.cache, stages the binary under resources/opencode-cli, verifies opencode --version, and skips work when the staged binary already matches.
Prefer explicit OpenCode binary overrides first, then the bundled Electron CLI, then PATH/system installs. Keep rejecting the Windows OpenCode desktop app executable as a CLI candidate and add resolver tests for bundled priority, explicit override priority, resourcesPath lookup, and desktop-app rejection.
Suppress OpenCode CLI update prompts when the active CLI source is bundled. The server now reports upgrade-status as unavailable for bundled CLI while still returning the current OpenCode version for About, and rejects direct upgrade attempts with a 409 instead of trying to mutate the bundled binary.
Update desktop release, smoke, and manual macOS DMG workflows to prepare and verify the bundled CLI before packaging, verify the packaged app contains the expected CLI, cache downloads by OS/arch/OpenCode version, and align the Windows smoke runner with production windows-2022.
Document desktop bundling behavior, ignore generated CLI/cache files, add oc-dev helpers, and keep Web/VS Code behavior dependent on installed OpenCode CLI rather than desktop bundled resources.
* fix: make upstream sync actions target the selected remote
Ensure fetch and pull actually honor upstream selection so fork maintenance works from the Git sidebar, and surface upstream branch status alongside the primary origin-tracking indicators.
* feat: add Windows Electron desktop foundation
* fix(electron): stabilize Windows desktop packaging
* fix(electron): stabilize Windows desktop chrome
Use native Windows titlebar behavior with an Alt-accessible hidden menu, and harden Windows dev command launching so the desktop app follows platform conventions.
* fix(electron): stabilize Windows dev startup
* fix(electron): clarify desktop artifact names
* fix(electron): harden Windows desktop release and launch
* fix(electron): address Windows release review
* fix(electron): point updater and release links to org repo
* Fix Windows settings persistence fallback
* Fix Windows Electron dev startup
* Add Windows Electron window controls
* Fix Windows Electron install and opencode launch
* fix: resolve git status for repositories without upstream
Fixes repository detection stuck on Checking repository
Handles git status when no upstream is configured
Adds regression coverage for git status loading
* Add Windows app menu button
* fix: preserve file editor line endings
* ci: add desktop release smoke workflow
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>