Commit Graph
2240 Commits
Author SHA1 Message Date
Bohdan Triapitsyn 89399ec1c2 fix(ui): simplify walkthrough action label 2026-08-02 21:17:39 +03:00
Bohdan Triapitsyn 9d48d5d02b fix(git): clean up in-progress merge/rebase banner
Use the real status-warning tokens (--status-warning-bg did not exist, so
the card rendered without a fill), drop the decorative icons, and fold the
conflict count into the title as a single full-message key per locale.
The operation description now wraps instead of truncating, and both the
conflict and ready-to-continue states share the same action layout.
2026-08-02 20:27:05 +03:00
Bohdan Triapitsyn 25e22f007a perf: fix bundle chunking to slash initial load #1846 2026-08-02 20:26:01 +03:00
Bohdan Triapitsyn 3a50bfb6f9 Merge main and fix lazy image export loading 2026-08-02 20:17:37 +03:00
Bohdan Triapitsyn 728bf54825 refactor: remove unused delete session worktree options 2026-08-02 19:47:00 +03:00
Bohdan Triapitsyn 75606a4ecd chore: update changelogs with recent mobile and UI fixes 2026-08-02 19:38:23 +03:00
Bohdan Triapitsyn bc7ef044b7 fix(sync): guard delete actions by default #2578 2026-08-02 19:37:04 +03:00
Bohdan Triapitsyn 39a321a29b fix(mobile): widen Android edge swipe zones 2026-08-02 19:31:22 +03:00
Bohdan Triapitsyn a96a2310a9 fix(mobile): support QR scanning without Play Services 2026-08-02 19:09:46 +03:00
Bohdan Triapitsyn 2b446dd164 fix(ui): avoid clipping session titles 2026-08-02 18:39:53 +03:00
Alexandre Reyes Martins d19ff96c02 fix(sync): guard delete actions by default
Follow-up to #2574 and f95f1ab18, which guarded the archive path. The
delete path had the same two defects and worse consequences.

`useSessionUIStore.deleteSession`/`deleteSessions` declared an `options`
parameter and discarded it on both paths, so a caller-supplied runtime
key was a silent no-op. `SessionDialogs.tsx:416` already passes options
today and they never reach the action.

The delete path also never rechecked the runtime. Session IDs are not
unique across runtimes, so a response produced by a previous runtime
could commit `finalizeConfirmedSessionDeletion` against the runtime the
user switched to: evicting an unrelated session from the live and global
stores and calling `cleanupPersistedSessionState`, which erases queued
messages, todos, folder membership, inline-comment drafts, chat draft,
and pins. That is user data loss, not stale cache.

`cleanupPersistedSessionState` already rejects an identity whose runtime
is no longer active, but `finalizeConfirmedSessionDeletion` defeated that
check by passing the live `getRuntimeKey()` at commit time, comparing a
value with itself. It now forwards the captured key.

Adopt the default-on shape from f95f1ab18: `expectedRuntimeKey` defaults
to the active runtime in `deleteSession`, `deleteSessionInDirectory` and
the new canonical `deleteSessions` action, and is rechecked before the
request and before every reconciliation. A `404` still means "already
deleted" and commits cleanup, but only while the captured runtime is
active; after a switch it describes the wrong runtime and the action
reports failure instead of committing.

Also documents the throw contract of `patchSessionMetadata`, a
non-blocking nit raised by the review bot on #2574.
2026-08-02 15:13:06 +00:00
Bohdan Triapitsyn ad862d4025 docs: update changelogs for walkthrough and UI changes
Adds an unreleased summary for the new guided walkthrough and mobile/tablet layout.
Documents session, sidebar, chat, and VS Code fixes.
2026-08-02 17:48:50 +03:00
Bohdan Triapitsyn e59f6dff66 fix(vscode): open apply_patch diffs at the correct path #2567 2026-08-02 17:32:27 +03:00
Bohdan Triapitsyn c6ab199fef Merge pull request #2573 from alexandrereyes/fix/archived-session-query-boundary
fix(sync): narrow the archived session query at the data boundary
2026-08-02 17:09:32 +03:00
Bohdan Triapitsyn f95f1ab18f fix(sync): guard archive actions by default 2026-08-02 16:48:02 +03:00
Bohdan Triapitsyn 4748c3362f Merge pull request #2574 from alexandrereyes/fix/archive-runtime-guard
fix(sync): honor expectedRuntimeKey in archive actions
2026-08-02 16:45:02 +03:00
Bohdan Triapitsyn 4fae2d79a0 fix: adjust openchamber light theme colors 2026-08-02 16:40:02 +03:00
Bohdan Triapitsyn 96c011a8ef feat(mobile): tablet layout pass and foldable-ready size class (#2569)
The tablet ran the phone layout with a half-finished iPad draft on top: two
custom sidebars, a leftover overflow menu, split Files/Changes header buttons,
and phone-width sheets stretched across a 13" screen. This brings it onto the
phone's navigation model and keeps only the differences a large screen earns.

- Sessions are a persistent resizable left sidebar; the overflow menu is gone
  and its destinations moved into that sidebar's footer (connected instance,
  settings, pending web update) and into the workspace drawer.
- The workspace (Changes / Files / Terminal / Notes / MCP) is the phone's
  drawer everywhere: a resizable right sidebar where the screen can host one
  (up to 900px) and the full-cover drawer otherwise, with its mounted panes —
  an open diff, an edited file, an attached terminal — surviving rotation.
- Header dropdowns are anchored popovers: the recents switcher mirrors the
  usage overlay on the left, and its trigger is sized to the title rather than
  to the free width.
- App-level pages (settings, instances, update, an opened plan) render as
  centered dialogs instead of covering the screen.
- Overlays center on the chat column through published insets, so the model
  and directory pickers no longer sit off-centre; the directory picker also
  stops overriding the shared width clamp.
- Wide chat layout applies to mobile surfaces, where a tablet chat column is
  finally wide enough for the setting to mean anything.

The layout gate is a live size class rather than a device check, so Android
tablets and foldables are covered by the same code:

- `enabled` when the shortest viewport side is at le
  sw600dp). The short side is what makes this a size question instead of a
  device question — a phone reports ~360-430 whichev
  unfolded book foldable ~600+, and folding shut drops back under it. iPads
  also answer on identity, since iPadOS hands out od
- `roomyForPanels` when landscape and at least 1000px wide, which is what it
  takes to host the sidebar, the panel and a readabl
  foldables miss it in BOTH orientations — their long side is barely wider
  than a tablet's short one — so they keep the portr

Every consumer re-decides instead of remembering wha
open sidebar closes if the device folds shut under it. iPad behaviour is
unchanged: its landscape widths all clear the panel
ones do not, exactly as the previous orientation check did.

Hardware keyboards are read natively. iOS reports them through GCKeyboard,
published to the web layer at document start and kep
disconnect and foregrounding; the layer stops inferring once that answers. A
single early publish was not enough — the connect no
already-attached keyboard fires before the page exists, and GameController can
populate late — so the state is re-published across
resume. With a keyboard attached the draft screen keeps its starter chips and
the composer never collapses; tablets skip the colla
Runtimes with no native answer fall back to inferring it from the keyboard
bridge, and only ever conclude "hardware" from silen

Also: sidebar rows no longer sit on a differently ti
footer is no longer clipped by an over-tall content box, the resize handles
moved above the panes' own overlays so they can actu
now-unreachable overflow menu, fullscreen terminal/MCP/notes surfaces and their
locale key are deleted.

Device behaviour is unverified — the tablet layout,
keyboard bridge and the foldable size class have not been exercised on
hardware, and the 600/1000 thresholds are derived fr
rather than measured on a foldable.
2026-08-02 16:25:16 +03:00
Bohdan Triapitsyn 34d0ff7383 feat(walkthrough): guided AI walkthrough for diffs, branches, and PRs (#2572)
A diff is ordered by file path, which is almost never the order in which a
change makes sense. This adds a Walkthrough surface that reorders it: the model
groups related hunks into stops, explains what each group changes about
behavior, and orders the stops so each builds on the last. It explains and
orders; judging code stays with the existing Review action.

Reviews uncommitted work (all, staged, unstaged), a branch against its base, or
a pull request. Generation is always user-initiated — nothing runs on a timer,
on a file change, or as a side effect of opening a panel.

Invariants worth preserving:

- Hunk identity is derived on the server and only there. Ids are content
  hashes, so an anchor that no longer resolves is proof the code it described
  changed, and staleness needs no heuristics. The client matches ids to ids and
  never recomputes them; two implementations would have to agree forever.
- The digest is never truncated. A diff that does not fit the model's context
  is refused with an actionable reason, because a walkthrough written against
  half a diff reads as confident and is wrong.
- Nothing disappears. Lockfiles and other generated output are excluded from
  the model's input by name — never by size — and everything no stop covers is
  listed at the end, so "have I seen all of it" stays answerable.
- Cost is explicit. Results are content-addressed, so returning the working
  tree to an earlier state costs nothing; generation outlives its request, so a
  refresh detaches the client rather than discarding paid-for work, and only an
  explicit cancel stops it.

Supporting changes to shared modules:

- git: expose the existing getRangeDiff as GET /api/git
  listUntrackedPaths and getUntrackedDiffs. The latter resolve the repository
  once for a batch instead of per file, taking a panel
  ~340ms on an 80-file working tree.
- small-model: structured output across four wire forma
  and abort signal, and an onOverflow policy so an oversized prompt fails
  loudly instead of being silently clipped. A provider
  remembered so the prompt-side fallback goes first next time.
- models.dev metadata: surface structured_output as tri
  false blocks a model, a missing field does not, because the catalog omits it
  for roughly half of all models.

Desktop and tablet only: VS Code serves Git through its
these routes, and the mobile shell does not consume the surface registry.

Docs: packages/docs walkthrough page in English and all eight locales.
2026-08-02 16:22:55 +03:00
Bohdan Triapitsyn b1ec34162e fix(ui): block active HTML in assistant markdown 2026-08-02 16:12:23 +03:00
Alexandre Reyes Martins 2e8fc6e192 fix(sync): honor expectedRuntimeKey in archive actions
`useSessionUIStore.archiveSessions` declared an `options` parameter and
discarded it, so any caller passing a captured runtime key got a silent
no-op. The archive path also never rechecked the runtime, letting a
response produced by a previous runtime reconcile the live and global
session stores of the runtime the user had switched to.

Move the batch to a canonical `archiveSessions()` action, add an optional
`expectedRuntimeKey` to `archiveSession()`, `patchSessionMetadata()`, and
`cleanupReviewMetadataBeforeDelete()`, and recheck that key before every
store reconciliation. A guarded batch stops at the first observed runtime
change: server-confirmed sessions stay in `archivedIds` and every
unconfirmed ID is returned in `failedIds`, so existing partial-failure
feedback stays truthful. Callers that pass no key keep prior behavior.

Type the store option as `ArchiveSessionsOptions` instead of
`Record<string, unknown>`, since the loose type allowed the drop.
2026-08-02 11:55:02 +00:00
Alexandre Reyes Martins b54741bab5 test(sync): cover the archived session query boundary
Add coverage for the archived-only narrowing: mixed pages return archived
records only, active pages stay unfiltered, a page that is full upstream
but fully filtered out keeps paginating, onPage receives only accepted
records, and id dedupe still stops a repeating page.

Document the OpenCode `archived` flag semantics in the owning store
documentation.
2026-08-02 11:51:25 +00:00
Alexandre Reyes Martins 7eb43fc5d5 fix(sync): narrow the archived session query at the data boundary
OpenCode's `archived` flag drops the `time_archived IS NULL` condition
instead of selecting archived rows, so the archived list came back with
active sessions mixed in. Filter at the boundary and keep pagination
progress measured on the raw response.
2026-08-02 11:45:40 +00:00
Serhii Dziupin 7afec99f80 Merge pull request #2551 from openchamber/feat/git-session-context-5ef9
fix(git): pin simple-git to opened project path for session discovery
2026-08-02 13:05:15 +03:00
Serhii Dziupin 5d24d6cb2a fix: dedupe shared worktree ownership
Cherry-picked from claude branch 7b3bec48 (fix: dedupe shared worktree ownership and title sessions immediately).

Only the worktree-dedupe half applies to main: partitionWorktreesByRegisteredProject and its callers (SessionSidebar, ElectronMiniChatApp, MobileApp, MobileSessionsSheet) plus tests and sidebar docs.

The session-title half (title sessions immediately) remains on the claude branch: the session-title runtime and its claude-code transcript translator imports do not exist on main and cannot build there until the Claude harness lands.
2026-08-02 09:34:49 +03:00
Bohdan Triapitsyn 37ff3a8164 release v1.17.2 2026-08-01 23:17:28 +03:00
Nabeel Siddiqui d45b8065b0 Merge remote-tracking branch 'upstream/main' into fix/2566-apply-patch-vscode-diff
# Conflicts:
#	packages/ui/src/components/chat/message/parts/ToolPart.tsx
2026-08-01 16:15:42 -04:00
Bohdan Triapitsyn c1a74c195b fix(electron): preserve HMR connection limits 2026-08-01 21:32:06 +03:00
Bohdan Triapitsyn 4cab15605a fix(ui): show glob pattern in tool description 2026-08-01 21:32:06 +03:00
Bohdan Triapitsyn 86ef96302d feat(mobile): mobile app navigation rework and beta-feedback closeout (#2561)
Navigation model rebuilt around two full-width drawers and a minimal
header (sessions / title-switcher / usage ring / workspace):

- Left sessions drawer: cross-project tree with live status indicators,
  swipe actions on sessions (rename/archive/delete) and on group headers
  (project edit / two-step close, worktree delete), reorder-only edit
  mode with collapsible project cards and draggable worktrees, app-level
  footer (connected instance, settings, pending web update).
- Right workspace drawer: Changes / Files / Terminal / Notes / MCP as
  pill tabs (inactive tabs icon-only); panes stay mounted once visited.
  The full desktop file editor serves the Files tab; read/skill tool taps
  in chat open the file there at the requested line.
- Header session switcher on title tap: 10 cross-project recents with
  live busy/attention indicators and project · branch metadata; the
  usage ring opens a metadata overlay with an explicit loading state.
- The overflow menu is gone on phones (its destinations moved into the
  drawers); iPad keeps it until its dedicated layout pass.

Correctness and continuity:

- /auth/session answers bearer-first, so a stale WebView cookie can no
  longer mask a revoked device token; cold launches classify failures
  fast and land on an explicit connect screen.
- Authoritative session snapshots raise frozen ordering baselines and
  stale live ranks — recents stay truthful after the app slept.
- Cold launches reopen the last active session per instance (persisted
  pointer, confirmed against a sessions snapshot; a user-opened draft
  clears it), with a logo hold instead of a draft flash.

Also: collapsed pill composer gains the stop control; chat tool rows
share one 36px rhythm; Task subtool rows truncate; larger bottom safe
area so the composer clears big-screen corner radii; Capacitor build
hides About/Update (store updates apply there); widgets link to the
sessions drawer with a list icon; MobileApp split into focused modules;
five mobile-surface detectors unified; translucent borders normalized to
70%; all new strings translated across the 10 locales.

iPad and foldable layouts are intentionally untouched - separate next version PR.
2026-08-01 21:16:36 +03:00
Nabeel Siddiqui 8eee5b27cd fix(vscode): open each apply patch file 2026-08-01 13:58:48 -04:00
Nabeel Siddiqui 9f60375cac fix(vscode): resolve apply patch diff paths 2026-08-01 13:39:11 -04:00
Bohdan Triapitsyn ea8cc5d7b0 feat: represent symlink diffs as link targets
Untracked symlinks now show as link entries in diff output.
File diffs display symlink targets instead of following them.
Added tests for patch and split diff behavior.
2026-08-01 10:44:45 +03:00
Bohdan Triapitsyn f1e8e03c31 fix(vscode): restore permission auto-accept replies
Route live VS Code permission requests directly to directory-scoped permission replies instead of blocking on the refresh-only state preflight.

When auto-accept is enabled after prompts are already visible, reply to the authoritative local requests first, then reconcile and deduplicate the server pending list. Keep state verification for reconnect and refresh flows so stale resolved requests are not resurrected.

Add regression coverage for live events, existing prompts, directory routing, retry behavior, stale reconciliation, and network failures.
2026-08-01 03:14:59 +03:00
Bohdan Triapitsyn 4f63dbf96c feat(ui): add llmapi provider logos 2026-08-01 03:14:09 +03:00
Bohdan Triapitsyn fd8ec60a6a feat: add move current session to worktree action
Adds a header menu item to move the current root session to a worktree
Collects descendant sessions so the full session tree moves together
Disables the action while the session is busy or a move is already pending
2026-07-31 21:24:17 +03:00
Bohdan Triapitsyn a6fb7193dc feat(ui): expose desktop session actions in header
Add a dedicated desktop header menu for the active session while keeping recent-session switching available when the sidebar is closed. Match inline rename behavior with the sidebar and expose rename, copy ID, share, export, archive, and delete actions with localized feedback.

Automatically copy newly created share links, keep share/unshare state synchronized across live and global stores, and normalize stale upstream unshare responses so the UI immediately reflects successful unsharing.

Require Markdown exports to load every available message page before formatting the conversation. Abort incomplete root exports, retain explicit child-session skip warnings, and guard complete-history pagination against failures and cursor cycles.
2026-07-31 21:02:23 +03:00
Cursor AgentandSerhii Dziupin d839c8b0f8 fix(git): pin simple-git to project path for session discovery
simple-git without baseDir inherits process.cwd(), so launching
OpenChamber from a neutral directory (e.g. $HOME) and opening a git
project elsewhere produced repeated "not a git repository" status
errors and could abort project/session enumeration. Always require an
explicit baseDir, soft-handle non-repo GitErrors on status/check
routes, and cover non-git, foreign-cwd, and nested-repo cases.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-07-31 09:53:09 +00:00
𝖎𝖚𝖑𝖎𝖎𝖆andBohdan Triapitsyn aae889b904 perf: optimize session loading and desktop startup (#2545)
* perf: optimize session loading and startup

* fix(chat): stabilize history prepend virtualization

* perf: unblock first session open from startup network contention

Opening the first session after app start waited seconds for its message
fetch. Three independent contributors, each measured via CDP network
capture and Chromium net-log against the packaged desktop app:

- The active-session watchdog fired an uncapped per-directory status poll
  and child-session discovery burst at startup, and other subsystems
  (git checks, global session pages, command/skill discovery) fanned out
  alongside it, saturating the browser's ~6 HTTP/1.1 sockets per origin.
  Add a shared background-network gate (concurrency 3) and route the
  watchdog, poll-shaped git reads (also priority: low), global session
  pages, command/skill loads, and the background update check through it.

- The packaged renderer is cross-origin to the loopback backend, so every
  API call needs a CORS preflight; a few slow OpenCode-proxied requests
  held the whole pool while preflights and interactive traffic queued
  behind them. Lift Chromium's per-host connection cap for loopback via
  ignore-connections-limit in the Electron shell.

- OpenCode initializes each directory lazily on its first request, so the
  first click paid that cost interactively. Warm the last-used directory
  and the three most recently opened projects right after OpenCode
  readiness, sequentially and best-effort, overlapping UI startup.

Validation: new background-network tests, lifecycle warmup test, focused
store/sync tests, UI type-check and lint, dead-code report, node --check
plus electron type-check/lint, and CDP first-open measurements on the
packaged app (message fetch socket queue 5.4s -> 0.03s).

* fix(ui): keep interactive git reads out of background queue

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-07-31 12:51:15 +03:00
Howon LeeandBohdan Triapitsyn 09f0c64839 feat: add Windows ARM64 support with x64-baseline CLI workaround (#2537)
* 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>
2026-07-30 20:07:08 +03:00
Ibrahim Khan 5792a3d2e2 fix(ui): paint composer caret on first padding click (#2509) 2026-07-30 19:44:52 +03:00
Bohdan Triapitsyn 80d939cccd fix(telemetry): report real VS Code platform and honor usage opt-out
The VS Code bridge re-mapped the already-mapped platform value from the
webview, collapsing every install to platform "web"; it also sent the
installId even when usage reporting was disabled. The remote-instance
update poll in the header and the post-update wait poll now send
reportUsage=false so status checks no longer count as activity.
2026-07-30 19:19:43 +03:00
Bohdan Triapitsyn 5328245b63 fix(ui): remove blink and shift in desktop sidebar sticky headers
- Drive the sticky-fade identity overlay's visibility synchronously from the scroller's top-scroll attribute (CSS :has), and seed its leading project synchronously, so it appears in the same frame the mask hides the real header instead of a React commit later (removes the one-frame blink)

- Match the overlay's vertical box to the real header rows (py-1 instead of a centered h-7) so the identity does not shift a few pixels on the sticky handoff
2026-07-30 18:46:53 +03:00
ChangeHow 8130381f6c fix(ui): smooth desktop sidebar sticky transitions (#2528)
* fix(ui): blend vibrant sidebar transitions

* fix(ui): fade sidebar content below header

* fix(ui): smooth vibrant sidebar sticky headers

* fix(ui): scope sticky fade to desktop

* fix(ui): respect sticky header preference
2026-07-30 17:51:23 +03:00
Bohdan Triapitsyn 83a66d0a6d feat(theme): add OpenChamber hybrid theme and make it the default
- Add OpenChamber brand theme (dark+light): Vitesse syntax over OpenCode-deep neutrals with Flexoki accents, harmonized in OKLCH

- Add scripts/harmonize-theme.mjs: align accent saturation/lightness and boost syntax chroma via OKLCH

- Set default theme to OpenChamber (was Flexoki)

- Rename fields-of-the-shire off the openchamber-* id; keep it as a normal preset

- Remove OpenCode and OC-2 ports and all disabled theme JSON definitions

- Make panel/header/sidebar borders opaque and theme-driven; global default border now uses --border instead of hardcoded rgba
2026-07-30 17:43:39 +03:00
Bohdan Triapitsyn 74e7fe0707 fix(desktop): hot-reload development themes 2026-07-30 17:43:39 +03:00
Bohdan Triapitsyn ededdc14f9 fix(sync): preserve loader through Strict Mode probe 2026-07-30 17:43:39 +03:00
Bohdan Triapitsyn 7a16290ff3 fix(mobile): ignore cancelled password completions
Track each native mobile password-unlock operation with a monotonic generation. Cancelling the password prompt immediately invalidates the active operation and releases the busy state.\n\nEvery asynchronous login boundary now verifies that its operation is still current before reporting errors, writing a client token, persisting connection metadata, switching the active runtime, or notifying the connected surface. A stale relay login still closes its unadopted tunnel, while its finally block cannot clear the busy state of a newer password attempt.\n\nAdd a focused regression test that models a deferred password completion after cancellation and verifies it cannot apply the runtime-switch side effect.
2026-07-30 17:43:39 +03:00
Bohdan Triapitsyn 3b00c91893 fix(desktop): isolate remote runtime auth and embeds
Fix remote Desktop runtime bootstrapping across context-panel session chats, additional windows, and host switches.\n\n- Bootstrap embedded session-chat frames through a same-origin parent handshake that supplies the active endpoint, bearer token, runtime headers, local origin, and a credential-free relay descriptor.\n- Keep relay pairing grants out of iframe state and explicitly rebind the SDK after embedded bootstrap or relay restoration.\n- Preserve each additional and Mini Chat window's own init script instead of overwriting it when the main window's host configuration changes.\n- Replace direct iframe global calls with same-origin postMessage synchronization for theme, chat settings, and visibility.\n\nHarden Desktop host authentication and probing.\n\n- Bind password, passkey, session-status, and token-persistence completions to the runtime identity that started them, so a late result cannot alter a newly selected host.\n- Cancel active passkey operations and reset transient auth UI state on endpoint changes.\n- Verify stored client authentication via /auth/session for direct and relay host probes, distinguishing reachable hosts from hosts that require re-authentication.\n- Bound every relay probe request with an aborting timeout so a stalled auth request cannot hang refresh or host switching.\n\nAdd regression coverage for the embedded bootstrap handshake, credential-free relay descriptor exposure, runtime configuration, stale password completion after an A-to-B switch, and SDK errors that carry a zero response status.\n\nAlso preserve SDK response status on session-message loader errors so callers can distinguish transport and server failures.
2026-07-30 17:43:39 +03:00
Serhii Dziupin 4ae3debf54 Merge pull request #2534 from openchamber/feat/bc-38abb61a-bce6-4a01-a189-c569346927fa-33b6
fix(files): stop autosave data loss on load lag and binary files
2026-07-30 16:21:59 +03:00