Commit Graph
3432 Commits
Author SHA1 Message Date
Bohdan Triapitsyn 8afec51480 fix: switch new installs to OpenChamber themes
New installs now default to OpenChamber light and dark themes.
Existing Flexoki theme preferences continue to be preserved during migration.
2026-09-04 12:51:49 +03:00
hehuaiyu 0dafc512a6 fix(tooling): resolve Bun executable on Windows 2026-09-04 14:34:34 +08:00
hehuaiyu 63df14e985 fix(vscode): support custom provider protocols 2026-09-04 13:23:39 +08:00
hehuaiyu c6755768b8 fix(providers): preserve custom model metadata on edit 2026-09-04 13:11:55 +08:00
Iuliia Ivashko 74e8d522b9 fix(ui): hold the changed-files gate until post-bootstrap status lands
Refresh hints fired while setup commands run can cache a mid-creation
dirty snapshot; lifting the gate the moment bootstrap settles flashed
that stale snapshot until the forced fetch resolved. The gate now stays
down until the post-bootstrap status fetch completes.
2026-09-04 07:10:23 +03:00
Iuliia Ivashko 7519167031 fix(ui): stop restoring inherited effort from history as an explicit choice
Message metadata records the effective effort, inherited defaults
included. The history-restore effect re-applied it as an explicit
override and re-pinned it per session one render after every send, so
the picker still jumped from Default to the settings default despite the
send-time fix. Only an effort deviating from what the model would
inherit is restored as a choice; the preserve-manual-override branch
follows the same rule.
2026-09-04 07:10:23 +03:00
Iuliia Ivashko f2853490de fix(ui): open a chat draft when a chat scratch directory is forwarded
'New session in the current directory' callers (shortcut, menu, composer)
forward the current session's directory even when that session is a
chat. Its managed scratch directory names no project, but it counted as
an explicit project target, so a plus pressed inside a chat session
opened a project draft. Chat scratch overrides now resolve to a chat
draft.
2026-09-04 07:10:23 +03:00
Iuliia Ivashko acdf0c2e1f fix(ui): hide transient dirty state while a worktree bootstraps
A freshly created worktree transiently looks dirty until its setup
commands and initial git reset finish. The work status panel showed
those files as changes on the branch and the draft's worktree dropdown
flashed its dirty warning, and both then froze on that state because
nothing refetched after bootstrap. Make the bootstrap state (the
existing authority on unfinished creation) subscribable, suppress the
dirty probe and the changed-files row while it is pending, and force one
status fetch when it settles so the lifted gate shows the reset tree.
2026-09-04 02:35:56 +03:00
Iuliia Ivashko 0a47b306d6 fix(ui): stop pinning inherited effort as a session choice on send
Sending recorded the effective variant - inherited settings/agent
defaults included - as the session's explicit per-session choice, so the
picker jumped from Default to the inherited effort right after the send
and the session stopped following later default changes. Record only an
explicit picker override when the send reflects the live selection;
sends carrying a captured configuration for another session keep their
captured variant.
2026-09-04 02:16:21 +03:00
Iuliia Ivashko bbb97f7e66 fix(ui): keep New Worktree form state when worktree topology changes
The reset-on-open effect also depended on generateUniqueSlug, which is
derived from the available-worktree list, so a worktree appearing or
disappearing while the dialog was open wiped the form (branch name,
linked issue). Initialize once per open via a ref guard, pinned by a
behavior test. Also tightens CreateWorktreeArgs/GitHub selection typing
in place of type assertions.
2026-09-04 02:10:22 +03:00
Iuliia Ivashko 35875e818c revert(ui): restore inherited semantics for Default thinking effort
The explicit-Default behavior from 77d756aeb (Default = send no effort)
was based on a misdiagnosis: the tester did not know a default effort was
configured in settings, so the settings default applying under Default is
the intended behavior, not a bug. Restores the pre-fix effort resolution,
tests, and documentation.
2026-09-04 02:10:17 +03:00
Iuliia Ivashko 77d756aebb fix(ui): preserve draft and effort selections 2026-09-03 17:32:24 +03:00
𝖎𝖚𝖑𝖎𝖎𝖆 0d8709a72e fix(worktrees): remove worktrees in the background (#3319)
* refactor(worktrees): fetch source once during creation

* fix(worktrees): remove worktrees in background

* fix(worktrees): show background removal progress

* fix(worktrees): name the worktree in removal toasts
2026-09-03 15:17:28 +03:00
James Tatum 5995802fe3 feat(worktrees): fetch remote source branch before worktree creation (#3296)
* feat(worktrees): fetch remote source branch before worktree creation

New worktrees based on a local branch that is behind its upstream now
fetch first and branch from the remote-tracking ref, so they are not
born stale. A global setting (on by default) in Settings > Behavior
controls this, and fetch failures toast a warning and fall back to
local state instead of blocking creation.

* fix(worktrees): wire fetch-source toggle to store and honor failed runtime fetches

The Behavior toggle only persisted the setting; the consumer reads the
config store at creation time, so a just-toggled-off setting kept
fetching until the next hydration. Update the store optimistically on
toggle and on page load, and roll it back when the save fails.

The VS Code runtime bridge resolves git fetches with { success: false }
instead of throwing, which the consumer read as success and silently
based the worktree on the stale remote ref. Treat any non-success
result as a failed fetch: warn and fall back to local state, matching
the web/desktop/mobile path.

* fix(worktrees): stop new remote-based worktrees from tracking the base branch

Creating a worktree with a remote start ref made git auto-track the
base branch (branch.autoSetupMerge), so with the new remote fetch every
behind-root worktree was born with upstream origin/<base> and plain
git push refused under push.default=simple.

The new branch's own upstream does not exist until its first push, and
the bootstrap deliberately refuses to write tracking config for refs
that were never fetched, so --set-upstream-to cannot re-point it.
Suppress the auto-track with --no-track on new-mode creation from a
remote ref: the branch ships with no upstream, matching the behavior
before the remote fetch until the first push sets it. Explicit
upstream keys now also win over the remote start ref inference,
aligning the create path with the validate path and the VS Code
runtime.

* fix(worktrees): keep the pre-create remote ref refresh soft

The client fetch and the server's pre-create fetchRemoteBranchRef both
refresh the same branch, and the second fetch throws on failure — so a
connection dropped between the two turned the promised soft fallback
into a rejected creation even though the remote-tracking ref was
already available locally.

The refresh is now best-effort when the ref exists locally (creation
proceeds from it) and still mandatory when the ref was never fetched,
preserving the materialization behavior for remote-only branches.
Applied to both the web server and the VS Code runtime.

* chore: ignore the .openchamber app runtime state directory
2026-09-03 14:03:32 +03:00
Bohdan Triapitsyn 40f5ed73c9 Merge pull request #3274 from kydorn/fix/theme-save-echo-clobber
fix(ui): stop settings save echoes from clobbering theme preferences
2026-09-03 13:01:27 +03:00
Bohdan Triapitsyn 2a0672e3a6 fix(ui): preserve VS Code themes during settings broadcasts 2026-09-03 12:41:59 +03:00
Bohdan Triapitsyn 85bf0a99de fix: identify OpenCode Go requests by session 2026-09-03 11:49:35 +03:00
Bohdan Triapitsyn 76128b615f feat: add Fixel font support
Adds Fixel Text as a new UI font option
Allows font sources to load from direct URLs
Keeps existing fontsource-based loading working
2026-09-03 11:49:35 +03:00
Bohdan Triapitsyn 0107abb32d fix: order concurrent instance probes and honour the probe budget
Startup warm-up, opening the switcher and the refresh button can all probe at
once, and a relay host working through tunnel retries takes an order of
magnitude longer than a loopback one — so a slow older run landed last and
replaced a fresh "ok" with its own stale "unreachable". Each host now records
which run owns its status; a status from the switch flow outranks any probe
still running for it.

Each relay attempt is also capped by what is left of the 15s budget rather than
the full per-request timeout, so an attempt started just under the deadline can
no longer run the whole 8s past it.
2026-09-03 11:49:35 +03:00
Bohdan Triapitsyn f0ced9d361 fix: reject instance-served responses that outlive their instance
MCP status and skills were cleared on a switch but their in-flight requests
were not, so a response for the previous instance could still write itself over
the new one's — the same race the quota store already guards. Both now carry a
generation.

Usage also claimed an instance as loaded before it had answered, so a load that
failed on a cold or briefly unreachable instance was never attempted again, and
the previous instance's display mode and provider selection survived a switch —
which decided what the new instance was even asked for.
2026-09-03 11:49:34 +03:00
Bohdan Triapitsyn 17fd46d4e5 fix: keep instance statuses between switcher opens
The switcher held reachability in component state and replaced the whole map at
the end of a probe run. It ran once per open before the config had loaded — with
Local as the only host — so that pass wiped every other instance's status and
each open started on "Checking", including for the instance the app was
connected to and actively talking to.

Statuses move to their own module: startup warms them so the switcher opens on
real values, a re-probe replaces each value in place as it lands rather than
blanking them first, and stale entries are dropped against the loaded config
instead of a partial host list. The connected instance never reads "Checking" —
the live connection already answers what the probe would ask.
2026-09-03 11:49:34 +03:00
Bohdan Triapitsyn 8f1e0c8b5f fix: retry the relay instance probe before reporting it unreachable
The tunnel rejects everything waiting on its channel the moment one connect
attempt fails, even though it has already scheduled the next one with backoff.
That is right for app traffic, which retries for itself, but it made the
one-shot probe report a durable red "Unreachable" for a host that answers when
the user presses refresh a second later — a cold start is exactly when that
first attempt loses.

The probe now spans the tunnel's own reconnects within a 15s budget, and ends
immediately on a terminal tunnel state (auth failed, duplicate client, limit),
which waiting cannot resolve.
2026-09-03 11:49:34 +03:00
Bohdan Triapitsyn 6fa2cb66d0 fix: scope instance-served state to the connected instance
Linear and GitHub logins, quotas, MCP status, skills and agent memory are
served by whichever instance is connected, but each was cached globally or
by directory alone — which two instances can share. Switching instances left
the previous instance's answers on screen and its Linear login usable against
a runtime that has no Linear.

Reset them all through runtimeEndpointReset, each store guarding its in-flight
requests with a generation so a response for the previous instance cannot land
in the new one. The Linear team filter is now persisted per instance: a team
belongs to one workspace, so carrying it across filtered the new instance's
issue list down to nothing.

Usage also waits for the instance to report itself initialised before loading.
Providers report themselves as configured only once the instance can read their
credentials, so a fetch fired at mount answered "nothing configured" for every
provider and cached it — which is why Usage stayed missing from the work-status
panel until Settings -> Usage forced a fresh fetch.
2026-09-03 11:49:34 +03:00
Bohdan Triapitsyn e8ba8e996f fix: show full desktop instance label in header 2026-09-03 11:49:34 +03:00
Bohdan Triapitsyn a87f068256 fix: support dev server previews over relay 2026-09-03 11:49:34 +03:00
Bohdan Triapitsyn da6ab52a65 feat: add exe.dev usage tracking 2026-09-03 11:49:34 +03:00
Bohdan Triapitsyn 62a18f07a0 feat: add exe.dev provider logo 2026-09-03 11:49:34 +03:00
Bohdan Triapitsyn 29ca970362 fix: refresh terminal renderer after fonts load 2026-09-03 11:49:34 +03:00
Bohdan Triapitsyn 6c4923b8c8 fix: support Bun-only remote dev deployments 2026-09-03 11:49:34 +03:00
Bohdan Triapitsyn dfb3c614c8 fix: authenticate terminal WebSockets synchronously on Bun 2026-09-03 11:49:34 +03:00
𝖎𝖚𝖑𝖎𝖎𝖆 e885afbe89 Improve branch switch safety and recent branch status (#3302)
* feat(ui): block branch switches on dirty trees

* feat(ui): show unpushed commits in git branch selector

* feat(ui): show recent branches in git selector

* fix(ui): persist recent branch status

* feat(ui): add mobile branch picker

* fix(ui): guard mobile branch checkout

* fix(i18n): restore Turkish git empty state labels

* feat(ui): flag dirty draft directories on the branch selector

Replaces the draft dirty-directory banner with an indicator on the branch
selector: a warning icon plus a hover tooltip that opens by itself for five
seconds when the dirty state first appears, then stays hover-only. The copy
states the situation and the options (commit or worktree) without prescribing
either.

* feat(ui): optional push in the dirty branch switch dialog

Commit-and-switch gains an opt-in "Push after commit" checkbox. When the
push fails the commit stands but the switch is cancelled with an explicit
toast, so the user is never moved off a branch without knowing its push did
not happen. Without the checkbox the toast states the commit is local only.

* fix(i18n): align dirty-directory copy across locales

* fix(a11y): name the unpushed-commit badge in the branch picker

The badge showed a bare arrow and number with no accessible name or tooltip.
Both the desktop recents list and the mobile picker now carry a localized
"N commits not pushed" title and aria-label.

* fix(mobile): push before switching dirty branches

Honor the dirty-switch dialog's push option on the mobile Changes surface.
A failed push leaves the new commit on its source branch, refreshes state, and
cancels checkout. Mobile branch selection now also shows the existing dirty
switch notice.
2026-09-03 01:42:50 +03:00
Bohdan Triapitsyn 40e4b6f857 fix: allow external host origin behind HTTP proxy
Accept browser https origins when TLS terminates before an HTTP proxy hop
Honor forwarded external host while rejecting mismatched origins
Add tests for proxy and host matching behavior
2026-09-01 14:38:44 +03:00
Bohdan Triapitsyn bec7a82568 fix: reserve space for project action buttons
Prevents the project label area from shifting when actions appear
Matches spacing behavior with the collapse-toggle branch
Keeps hover and focus states aligned
2026-09-01 10:51:08 +03:00
Pablo 97b89cbe85 fix(i18n): restore tr locale key parity for gitView.empty discovery keys
The parity test fails on main: tr.ts is missing discoverFailed,
discoveringRepositories, retryDiscovery and selectRepositoryPlaceholder,
so 'all locales stay in key parity with english' is red on every run.
Carried in this PR to turn the checks green; drop it if you'd rather
land it separately.
2026-08-31 21:56:04 +02:00
Pablo a42fb91daf fix(ui): stop settings save echoes from clobbering theme preferences
Every updateDesktopSettings PUT replays the server's full settings
document as an openchamber:settings-synced event, and the theme listener
adopted it unconditionally - so switching sessions across directories
(any lastDirectory/activeProjectId write) could flip the theme to
whatever the server document held at that moment. A bootstrap GET with
missing theme fields made it worse: materializeAuthoritativeUiSettings
invented useSystemTheme + openchamber defaults and the persist effect
wrote them back to the server and the scoped localStorage entry.

Theme is now adopted only from bootstrap-grade syncs (the renamed
bootstrap flag, formerly adoptWorkspace), missing fields mean 'not set'
and keep the current preference, and the materializer no longer invents
theme defaults. Cross-window same-instance theme sync still rides the
scoped-key storage event; runtime endpoint switches still adopt the new
instance's server theme.

Closes the 'theme flashes to OpenChamber when switching sessions' report;
same family as the pre-#2897 'color mode forced to light' symptom.
2026-08-31 21:18:43 +02:00
Bohdan Triapitsyn 715c33b83c fix: preserve chat timeline pinning during width resize
Keeps idle readers from snapping back to the end while rows re-wrap
Releases the pin instead of scrolling if a resize moves an idle view off the end
Re-asserts the live edge after resize settle for active streaming sessions
2026-08-31 00:42:37 +03:00
Bohdan Triapitsyn 8372285718 docs: add vacation notice to README
Announces reduced review activity from 31 Aug to 4 Sep
Sets expectations for issue and PR responses while away
2026-08-30 19:50:49 +03:00
Bohdan Triapitsyn bdda3c36bc release v1.22.0 2026-08-30 19:24:09 +03:00
Bohdan Triapitsyn b97f2d05bb fix(chat): restore a message's attached context on revert and fork
Review comments, quotes, terminal selections and annotations were consumed
at send and never put back, so reverting pulled the message into the
composer without the context it was sent with.

Claude-Session: https://claude.ai/code/session_01TwLFeTfBnWdvbg9XyezZQx
2026-08-30 18:32:45 +03:00
Bohdan Triapitsyn 356c99ce24 docs: update changelog highlights
Clarify chat session switching is visually stable
Note GitHub account connection moved to Settings → Integrations
Update VS Code changelog wording for session switching
2026-08-30 18:17:48 +03:00
Bohdan Triapitsyn d0a5538bff feat: tune session sidebar tooltip timing
Adds a shared sidebar tooltip provider with delayed open and instant close behavior
Removes per-button tooltip delays so sidebar actions feel more consistent
Aligns session sidebar hover interactions with the opencode-style tooltip experience
2026-08-30 18:03:29 +03:00
Bohdan Triapitsyn 654b3d2441 fix(chat): keep the outgoing conversation still until the next one replaces it
Switching sessions moved the conversation on screen before the swap: the
composer and the status chip followed the live selection and re-shaped a
commit ahead of the timeline, so the pinned outgoing chat jumped; and the
reveal effect re-ran for the outgoing session when its waited flag flipped,
hiding it a few frames before the next one mounted. The chat column now
reads one deferred session, and the reveal runs once per opened session.
2026-08-30 16:54:41 +03:00
Bohdan Triapitsyn 02b1ee637d feat(ui): move project actions from the titlebar overlay into the header before Open in 2026-08-30 14:28:22 +03:00
Bohdan Triapitsyn 65054a5f4a feat(ui): gate the pull-request surface on GitHub, move the account into it, and GitHub sign-in into Integrations
The pull-request rail icon now appears only while GitHub is connected
(OAuth or gh CLI), like Linear; Linear sits after the walkthrough in the
default rail order. The GitHub account avatar and switcher leave the
header for the pull-request panel, where the walkthrough, refresh, and
account controls share one row and one height, and the account stays
visible on the panel's empty state. A manual refresh keeps its spinner on
screen long enough to read as work done.

GitHub sign-in moves from Settings → Git to Settings → Integrations →
Built-in integrations as a card before Linear; search and the connect
buttons follow it.
2026-08-30 14:17:12 +03:00
Bohdan Triapitsyn 9847ef179f chore: changelog for per-instance themes and scheduled-task settings retention 2026-08-30 13:33:36 +03:00
Bohdan Triapitsyn 6eec839fbf refactor(ui): parse the scoped theme entry at the boundary; runtime-switch owns transient keys
The scoped theme entry is now parsed by one boundary parser with a
stated invariant instead of ad hoc typeof narrowing, and the runtime
keys that mean "no instance connected" live next to the code that
produces them so a new sentinel cannot miss the theme-storage guard.
2026-08-30 13:29:52 +03:00
Pablo Gonzalez 73fd2e9d9d fix(ui): scope theme settings per runtime instance (#2897)
Closes #2958
2026-08-30 13:26:57 +03:00
Bohdan Triapitsyn db0bf115ad fix(scheduled-tasks): keep task fields a server build does not know
Every project-config write re-serialized normalized tasks, so a server
that shares the config file but predates a field (goal, auto-accept)
stripped it the first time any task ran. Untouched tasks now go back to
disk verbatim, a state update swaps only `state`, and only a deliberately
replaced task is serialized from the normalized shape.
2026-08-30 13:19:45 +03:00
Bohdan Triapitsyn 5fabeccd2d chore: highlight multi-repository projects in the changelog 2026-08-30 11:34:29 +03:00
Bohdan Triapitsyn 1423fc57b8 fix: use delete icon for context preview remove action
Updates the context preview remove button icon
Makes the control better match its delete behavior
2026-08-30 11:30:07 +03:00