path-open-utils.mjs and its smoke test are byte-for-byte identical to
his PR #1335 (opened 2026-05-19, review findings addressed the same
day, community-verified on CachyOS but never given a maintainer
review), and linux-app-discovery.mjs retains most of that PR's
implementation. The [1.17.0] changelog entry credited the PR that
carried this work forward but omitted the original author.
A guided explanation is only useful in a language the reader reads, so the
panel header gets a language picker alongside the model one, defaulting to
the interface language. Like the model, it is request state rather than a
setting: the language travels with the read and the generation, and the one
a walkthrough was written in is stored with it, so reopening a review
describes what is there instead of what a fresh one would be.
Only prose is translated. Hunk aliases resolve back to hunk ids and
icon/importance are validated against fixed English values, so a translated
one would be dropped by the normalizer — silently losing an anchor or a
style. Identifiers and paths stay as they appear in the code.
The language is part of the cache key, and a read now asks the cache for the
exact request it was given before falling back to the pointer. Without that
the panel answered a request to switch languages with the text it already
had, leaving the other language unused in the cache.
Alongside it:
- The answer budget is derived from the resolved model instead of a flat 24k.
That number was the same for a 64k-context model and for one that admits to
384k output tokens, and on the latter it was the only reason generation
failed: the model spent the whole allowance reasoning and returned nothing.
It is now min(96k, max(24k, a quarter of the context)) capped by the
catalog's output limit, decided once so the input reserve and the request
cannot drift apart.
- A read no longer offers Cancel. It is a few hundred milliseconds of git with
nothing to cancel, and the button flickered on every model or language
change. When the panel is showing a fallback, a banner names what is on
screen versus what was asked for — only once the read has settled.
- The header keeps one 32px control height and drops its labels below 680px
instead of squeezing them to two letters and an ellipsis.
Docs and module documentation updated in every locale.
Added new CLI and managed-instance session capabilities
Documented chat, settings, shortcut, and mobile fixes
Noted small model, desktop, and iOS updates
* feat(electron): add Linux AppImage releases
* ci: cache Linux OpenCode CLI artifacts
* fix(ci): await Linux release inventory check
* fix(electron): add frameless window controls on Linux desktop
Linux AppImages were created without native WM decorations and without
in-app controls, leaving users unable to close the window with a mouse.
Treat Linux like Windows: frameless BrowserWindow plus the existing
WindowsWindowControls header buttons and app-menu entry. macOS keeps
hidden title bar with traffic lights unchanged.
Shared usesFramelessElectronChrome() helper drives main window, mini
chat, header insets, and titlebar controls.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Linux desktop feature parity: Open in, background start, tray, multi-window (#2392)
* feat(electron): Linux parity for Open in, background start, and tray
Enable Linux desktop feature parity with macOS/Windows: open projects in
the default file manager and discovered apps, XDG autostart with
--background launches, system tray (including minimize-to-tray), and
tray sync from the renderer.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* fix(electron): allow packaged UI protocol navigations on Linux
Prevent openchamber-ui:// navigations from being handed to
shell.openExternal, which fails on Linux and blocked desktop UI flows.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* fix(ui): surface Linux tray settings in settings search
Include isLinux in settings search runtime context so minimize-to-tray
is discoverable on Linux desktop, matching Windows search behavior.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* fix(electron): stop Linux AppImage Waiting-for-OpenCode flicker
Sync updated boot-outcome init scripts to all BrowserWindows after
desktop_hosts_set, and prefer state.initScript on dom-ready so chooser
reloads inject local/ok instead of a stale not-configured outcome.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* fix(desktop): restore Linux AppImage updater feed and error UX (#2396)
Treat missing latest-linux*.yml (404) as no update available instead of a
hard failure, and stop swallowing updater capability/download errors in the
desktop bridge so About/sidebar can show actionable messages.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* docs: credit Linux AppImage contributors in changelog
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
---------
Co-authored-by: jibanez-staticduo <staticduo@gmail.com>
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Updates the SDK dependency across web, UI, and VS Code packages.
Refreshes the lockfile and package versions to match the release.
Adds unreleased changelog notes for the current set of user-facing changes.
* feat(electron): add Linux AppImage releases
* ci: cache Linux OpenCode CLI artifacts
* fix(ci): await Linux release inventory check
* fix(electron): add frameless window controls on Linux desktop
Linux AppImages were created without native WM decorations and without
in-app controls, leaving users unable to close the window with a mouse.
Treat Linux like Windows: frameless BrowserWindow plus the existing
WindowsWindowControls header buttons and app-menu entry. macOS keeps
hidden title bar with traffic lights unchanged.
Shared usesFramelessElectronChrome() helper drives main window, mini
chat, header insets, and titlebar controls.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* feat(desktop): add configurable window controls position by OS
Add desktopWindowControlsPosition setting (auto/left/right) with OS-aware
defaults: Linux left, Windows right. Wire frameless chrome controls in
Header, TitlebarLeftControls, and MiniChatLayout, plus a Sessions settings
control for Windows and Linux desktop shells.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* fix(desktop): address Linux AppImage release review findings
Propagate updater capability errors to the UI, treat missing
latest-linux.yml feeds as no-update, stop installed-apps IPC spam on
Linux, document FUSE/AppImage limits, add CHANGELOG entry, migrate
remaining btriapitsyn URLs, and run Electron Linux unit tests on PRs.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
---------
Co-authored-by: jibanez-staticduo <staticduo@gmail.com>
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Tool JSON output now starts with a compact navigable summary view.
Expandable tool output includes quick open-file and diff actions for changed files.
Reasoning headers strip stray HTML comments, and navigation tools stay compact.
Changelog leads with the private relay and the native mobile apps (TestFlight
beta + Android APK links), followed by pairing v2 and the device management,
desktop multi-transport, and chat items; VS Code changelog gets the shared
chat-render entries.
Reworks how devices connect to an OpenChamber server, end to end.
Pairing v2:
- One-time pairing links/QR codes (openchamber://connect?v=2) carrying a set of transport candidates (LAN/tunnel/relay) and a single-use secret redeemed server-side; no tokens embedded in links
- Add-a-device dialog written for first-time users: intent-based transport choice (Anywhere / Home network only / This computer only) with plain-language descriptions, transparent fallback checkboxes, server-authoritative LAN detection, high-res QR dialog
- Private relay folded into pairing as a transport candidate with a demand-driven lifecycle (enables when a relay device is paired, disables when none remain)
Multi-transport devices:
- A saved device holds all its transports and one token; mobile re-probes on connect, resume, and network change and hot-switches LAN<->relay seamlessly (no re-pairing, no remount, session preserved)
- Desktop can import relay pairing links, switch to relay hosts through the E2EE tunnel, and restore a relay default host after relaunch
Device management:
- Device list (web + desktop) shows live per-device connectivity with the active transport (Connected - Local network / Relay) and platform badges (iOS/Android/macOS/Windows/Linux)
- One physical device = one record: stable per-install dedupe keys across pairing and password re-login; typed pairing label names the device, paired devices name the connection by the issuing server hostname
- Trusted desktop-local client manages all devices (list, revoke, clear revoked); relay host reaps dead client sockets after 3 missed keepalives
Android:
- LAN transport unblocked (cleartext + mixed content, mirroring iOS ATS exceptions); resume re-probe retries through network flux and silently auto-reconnects from a disconnected state
Adds OpenChamber Relay — an opt-in way to reach an instance from a phone,
browser, or another desktop from anywhere, with no open inbound ports, no
tunnel, and no shared LAN. The instance dials outbound to a relay; all app
traffic (HTTP, the event stream, terminal, dictation) is multiplexed and
encrypted through a single connection per client, so the relay only ever
forwards opaque ciphertext.
Transport
- End-to-end-encrypted channel over WebCrypto (ECDH P-256 -> HKDF ->
AES-256-GCM) with a capability-negotiated handshake and a small
HTTP/SSE/WebSocket multiplexing protocol. A byte-compatible JS host mirror
is cross-checked by tests.
- Host: outbound connection manager, per-client tunnel dispatcher to the local
server over loopback, reuse of the existing instance identity key, and
management routes. Disabled by default; explicit opt-in.
- Client: plugs into the existing runtime layer (runtime-fetch/-url/-switch/
-auth, event pipeline, terminal, dictation) so features work over the relay
unchanged; direct-URL and Electron realtime-proxy paths are untouched.
Pairing & UX
- Relay section in Settings -> Remote Instances (live status, QR/link pairing,
revocation via the existing client-token list) and the mobile connect flow.
- Frame batching and idle-gated keepalive keep tunnel message volume low
without affecting streaming smoothness.
Security
- The tunnel is transport only; the server authenticates every tunneled
request exactly as for a direct remote client.
fragments only. The relay stores no keys, tokens, or payloads.
Operability
- The endpoint can be pinned to a self-hosted rel
paired clients inherit it from the offer automatically.
- Relay module DOCUMENTATION.md and a relay-trans
invariants that future WebSocket/streaming changes must follow.
The relay transport is complete and tested; the UI for enabling and pairing
is gated behind openchamber_relay_gate and stays
Adds a Last turn scope to DiffView that renders OpenCode snapshot diffs from the latest user message summary without re-fetching git contents. The view hides Review in that mode and carries the selected diff scope through main and context-panel navigation.
Connects latest-turn changed-file chips in chat to the snapshot diff view on desktop and mobile, while keeping older turn chips static/read-only to avoid misleading affordances and extra subscriptions. Updates localized labels and empty states plus changelog.
Validation: bun run type-check (packages/ui); bun run lint (packages/ui).
Drop bullets that fixed bugs introduced within the same unreleased range,
fold the load-older button into its feature description, and group the
Capacitor-only keyboard/draft/instance polish under the pre-release
mobile-apps bullet like the 1.13.9 entry did.
The pill's expand focused the textarea from a rAF, outside the user
gesture — mobile browsers only show the soft keyboard for synchronous
focus, so the composer expanded silently. The expand now flushes the
render and focuses in the same gesture, and preventScroll applies only
inside the Capacitor shell so browsers keep their native reveal that
lifts the field above the keyboard (same for the post-overlay keyboard
restore). Also drafts the [Unreleased] changelog entries for everything
since v1.13.9.
The mobile stylesheet at packages/ui/src/styles/mobile.css defines a
@media (max-width: 1024px) block that overrides the --text-ui-header,
--text-ui-label, --text-meta, and --text-micro custom properties to
shrink labels on phones. The values it was setting were equal to (or
only 1px smaller than) the desktop defaults, so the model selector,
agent selector, and any other element using these classes rendered at
the same size on a 360px-wide phone as on a 1920px desktop.
Fix: tighten the mobile values to 0.875rem (ui-header), 0.75rem
(ui-label, meta), and 0.6875rem (micro), so that mobile is genuinely
smaller than desktop. The same change is applied to the iOS PWA
standalone block lower in the file so both code paths produce the same
size.
Fixes#504
Signed-off-by: Bohdan Triapitsyn <artmore@protonmail.com>
Co-authored-by: James Pinnell <james@example.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>