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
Clarify chat session switching is visually stable
Note GitHub account connection moved to Settings → Integrations
Update VS Code changelog wording for session switching
Reverts #2687. In real use the injected small_model behaves poorly with
OpenCode: its internal small-model consumers and OpenChamber's own small
model are different things and must stay configured separately.
Resolvesopenchamber/openchamber#3123.
The right panel's tab strip (browser, files, chat, and other
multi-instance surfaces) now supports a right-click context menu with
Close, Close others, Close to the left, Close to the right, and Close
all. These act on the current surface's tabs and reuse the new bulk
close action, so closing the active surface's last tab still closes the
panel while other surfaces remain.
- Add closeContextPanelTabs(directory, ids) to useUIStore
- Add opt-in tabContextMenu prop to SortableTabsStrip (no impact on other consumers)
- Wire the menu in ContextPanel with full i18n coverage across 11 locales
- Cover the bulk close with store tests
CodeMirror collapses a CRLF pair into one line break, so the document is
shorter than the string it was given. The composer derived the caret from
the JS string length, which put it past the end of the document and made
dispatch throw `RangeError: Selection points outside of document`.
Because the exception fires before the transaction applies, the document
never updates, the un-normalized text stays in React state, and the draft
persists as-is: every later visit to the session restores it and crashes
again, with no way out from the UI.
Derive the caret from the change set instead, in the controlled writeback
and in the imperative insert/replace handles.
fixes#3013
# Conflicts:
# CHANGELOG.md
# packages/vscode/CHANGELOG.md
Since opencode 1.18.x, `POST /global/upgrade` requires a `target` semver in
the body. OpenChamber sent an empty object, so every "Update OpenCode" click
came back 400. The rejection arrives as `{name, data:{message}}`, which has
no `error` field, so the user was left with the bare status text: "Bad
Request".
Resolve the target from the latest release — the same lookup the upgrade
prompt already uses to decide there is anything to offer — and fail with an
explicit code when it cannot be resolved, rather than sending a body opencode
is guaranteed to reject. Read the upstream rejection message so a refused
upgrade explains itself.
The VS Code extension carries its own copy of this flow and had the same two
defects; both are fixed there.
fixes#3121
"Restart to Update" answered the renderer with null before the install was
attempted, so a rejected install only reached main.log and the button looked
dead. The apply-update path now keeps the IPC call open until the app quits or
autoUpdater reports the failure, rolls the quit/install flags back when the app
stays up, and the update dialog shows the real reason with a translated hint for
a rejected code signature.
Also settle the download promise on downloadUpdate() itself: an already cached
payload emits no 'update-downloaded', which left that promise pending with its
listeners attached on every retry.
Follow-ups promised on merge, plus review findings on the batch itself:
- chat: task-tool output now respects the 512KiB render cap; quick-open
icon is visible at rest on coarse pointers and reachable by keyboard
(row keydown no longer swallows inner-button Enter/Space); composer
inline-code decoration drops the metric-shifting padding; a btw fork
send carries only the boundary instruction, never the promotion notice
- sync: cascade revert/unrevert aborts busy descendants, busy state is
read from every child store at the moment of use; rule 9 documents
redo clearing all descendant revert markers
- electron: renderer recovery keeps memory-eviction (a valid
render-process-gone reason) and both windows share one
attachRendererRecovery helper
- vscode: process registry is a thin re-export of the web module
(provider-env-aliases precedent) with ordered register/unregister
writes and an awaited close
- server/cli: managed-process registry takes injectable deps (fixes the
unreaped-orphans ReferenceError), corrupt settings errors name the
file, getWorktrees test restores console.warn
- tests: module-mock harnesses removed (AgentsSidebar, SettingsView
mobile focus — behaviors stay live but uncovered, accepted trade),
QuestionMarkdown asserts rendered DOM
- i18n: German gains the debug-panel request keys, Japanese/German drop
removed worktree keys, Ukrainian unit spacing fixed
- changelog: Copilot AI Credits entries (main + VS Code)
The startup path probed a relay host's stored direct URL — often the
pairing creator's own loopback — and any failure landed on the Remote
Server Unreachable screen before the renderer's relay restore could run.
A relay-capable default host now boots to main on the local substrate for
any failed direct probe (unreachable, wrong-service, incompatible), skips
the 10s second probe, and lets the renderer's existing restore pick
direct-or-relay.
The eslint pass in release:prepare caught what the package-scoped checks
did not: Header's handleOpenContextPlan and servicesTabs lost their last
callers with the removed shortcuts, the settings-synced listeners no
longer need the DesktopSettings import, and the store's openContextPlan
action itself went unused once the plan surface was reachable only through
the digit switcher and the rail.
The agent's browser.open used to force the context panel open and steal
the active surface, which read as panels opening by themselves. Tab
upserts now take a reveal option: the agent's opener passes reveal: false,
so the tab mounts invisibly (panes are kept alive regardless of
visibility, so agent control still works) while the panel and the active
tab stay exactly as the user left them. Manual opens are unchanged.
Aborting a run now just ends it quietly: the status chip and the composer
bar no longer flash an Aborted notice, and the indicator state machine and
its timer are gone from the composer. Acknowledging the session abort
record stays — it is what lets the working chip resume on the next run.
Command Code's official API has no usage endpoints; the old usage source
was the unofficial studio API reached through a now-archived plugin, so
the tile could only ever fail for officially configured users. Removed
across server, shared UI, and the VS Code extension; the provider logo
fallback stays — it serves the model picker, not usage.