Attachment pickers now share an allowlist for supported file types
Local attachments are normalized to consistent MIME types before upload
VS Code file picker now respects extension filters and larger files are allowed
* preserve attachments in UI and materializer
* add support for non-image attachments
* preserve attachments in UI and materializer
* improve attachment rendering and state synchronization
* simplify attachment filtering and key handling
* prevent rendering tool attachments without URLs
* require `f.url` in `imageAttachments` to match gallery indices
Adds a General settings switch to show or hide the macOS menu bar item.
Persists the new desktopMacMenuBarEnabled setting and passes tray state into Electron.
Disables tray sync and native tray setup when the menu bar is turned off.
Allow Desktop to skip its in-process OpenChamber server with OPENCHAMBER_SKIP_LOCAL_SERVER=1 while continuing to load the packaged UI shell.
Carry local runtime availability through the boot contract so unavailable or unconfigured remotes enter a remote-only chooser instead of offering broken local recovery actions. The chooser can select saved instances, add a server by URL, or redeem an OpenChamber pairing link over direct or E2EE relay transports.
Keep additional windows, Mini Chat, background startup, and unreachable-host recovery functional without a local origin. Render boot and recovery surfaces with the active theme background rather than exposing the native vibrancy backing.
Document the environment variable and cover serverless boot routing plus malformed pairing imports with focused tests.
Improve OpenChamber responsiveness under large session workloads while fixing
cache, synchronization, and persistence correctness across runtimes, projects,
directories, and worktrees.
- prioritize selected and visible sessions during bootstrap and defer
non-critical enrichment work
- reduce redundant message loading, event processing, store publication, and
hidden sidebar work
- prevent stale session and message requests from overwriting newer
authoritative state
- preserve existing data when authoritative fetches fail instead of treating
failures as successful empty responses
- scope session materialization, messages, drafts, queues, todos, pins,
permissions, folders, tabs, Git state, and pull request data by runtime and
directory identity
- harden runtime switching, reconnect, cleanup, mutation reconciliation, and
persisted-state ordering
- preserve live subagent Task linkage when metadata arrives after an older
message request or while streaming parts are suspended
- coalesce overlapping tail refreshes without losing newer refresh demand
- improve cold-session loading by moving deferrable work out of the critical
bootstrap path
- isolate URL authentication, mobile credentials, native secrets, and other
runtime-owned state across endpoint changes
- bound long-lived caches and remove avoidable allocations from event and
rendering hot paths
- limit virtualization to archive collections where it improves rendering
without disrupting active sidebar layout
- stabilize session folders, pin ordering, expanded state, and persisted
sidebar behavior
- open skill files through the same secure editor and outside-workspace grant
flow used by file navigation, including worktree sessions
- expand regression coverage for stale completions, runtime collisions,
reconnect behavior, persistence races, authoritative empty results, and
subagent refresh ordering
- document the updated synchronization, cache ownership, performance, and
runtime-isolation invariants
On mobile web/PWA, useTouchTerminalInput is true, which gated the
autoFocus prop behind !useTouchTerminalInput, causing autoFocus to be
false and the hidden input overlay to never receive focus. The user
had to manually tap the terminal to trigger focus.
Remove the !useTouchTerminalInput condition so autoFocus works on
mobile the same way it does on desktop: when the terminal becomes
visible, focusTerminalInput() -> focusHiddenInput() is called,
positioning and focusing the hidden textarea/input portal that
captures virtual keyboard events.
Co-authored-by: bashrusakh <bashrusakh@users.noreply.github.com>
Adds a new `hmr-react-scan` web dev option in `oc-dev`
Turns on React Scan via `VITE_ENABLE_REACT_SCAN` for that mode
Documents Electron workspace trust so fresh installs fetch the runtime automatically
- Assistant turn bottom padding pb-8 -> pb-2, desktop user message top
padding pt-6 -> pt-4 (footer-to-bubble gap 60px -> 28px)
- Drop the recap note's -mt-6 that compensated the old large padding
- Working indicator shows provider icon and model name with the live
status (e.g. 'Fable 5 is reading file'), localized via
chat.statusRow.modelStatus
- Pin auto-follow to the exact fractional scroll maximum and re-pin on
every passive follow instead of skipping within tolerance
- Round message text line-height to whole pixels so streamed content
grows on the pixel grid; kills the 1px vertical jitter of
bottom-anchored rows during streaming
- Remove assistant message headers; show provider icon, model, agent,
thinking variant, duration and time in the turn footer (metadata left,
hover-revealed actions right)
- Merge turns started by hidden user messages (subagent nudges) into the
previous turn so Activity, footer and spacing stay continuous
- Treat compaction summary text (info.summary) as justification activity
in sorted mode and skip it when picking the turn summary
- Interleave activity segments with standalone tool rows so Agent Task
sits chronologically between activity sections
Use dedicated access and refresh token labels for Cursor quota credentials.
Add localized token placeholder strings across supported settings languages.
Loads sessions from the active workspace directory
Fetches session messages using both session ID and directory
Resets expanded raw messages when the directory changes
Add a root-session action that creates a generated worktree from the session directory's current branch, transfers uncommitted changes, and moves the parent session plus its descendants through OpenCode's control-plane API.
Reuse existing project/worktree topology and quick-create behavior, keep the UI non-blocking, reconcile live and global session state across directories, and roll back partial moves and failed worktree creation safely.
Split worktree bootstrap readiness into directory-created, git-ready, and setup-ready phases across web and VS Code. Session moves wait for Git readiness while existing setup-aware flows continue waiting for full setup completion, and worktree removal is serialized with active bootstrap tasks.
Expose the move only for idle root sessions, show localized progress and explanatory tooltips in the sidebar, and keep pending/ready worktree metadata synchronized with authoritative session attachments to avoid stale setup indicators.
Add coverage for control-plane payloads, session-state migration, bootstrap phase ordering and compatibility, removal races, progress metadata, and fast-ready attachment races.
Retries transient index.lock conflicts during worktree population
Removes unchanged stale locks automatically and continues bootstrap
Adds coverage for stale lock recovery
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.
* Group settings navigation menu
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Revert "Group settings navigation menu"
This reverts commit 5983a4e82074b8dab1084af1cadd803ba28ea65d.
* Standardize settings layout feedback
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Fix settings save status timer typing
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Retain settings save status
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Report color mode save state
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Match Appearance settings to two-column layout
Rebuild Appearance into Color mode & Theme, Localization, and Density & type sections with responsive two-column grids, consistent section headers, page description, and green save status.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Migrate settings pages to SettingsPageLayout and SettingsSection
Replace ScrollableOverlay/max-w-3xl shells with the shared settings
layout primitives across entity and static settings pages, normalize
section headers, and add settings.page.behavior.description locales.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Unify remaining settings pages on shared section chrome
Wire Appearance, Projects, and Remote Instances through SettingsSection/SettingsPageLayout so every settings surface shares the same header, divider, and page shell treatment.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Align settings UI with OpenChamber design system kit
Apply kit geometry and control specs: 840px content width, 32/48 padding, fixed 260/280 sidebars, radius/spacing tokens, settings select height, stepper dimensions, and shared field/link typography.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Migrate OpenChamberVisualSettings to shared settings primitives
Replace ad-hoc radio/checkbox/chip/field layouts with SettingsSection
shared chrome for Appearance, Density, Navigation, Chat/behavior, and
Privacy while preserving handlers and data-settings-item anchors.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Migrate settings pages to shared field/checkbox/radio primitives
Unify Defaults, Notifications, Behavior, Git, Session Retention, Passkeys,
OpenCode CLI, Commands, About, Keyboard Shortcuts, and Desktop Network on
SettingsFieldRow / SettingsCheckboxRow / SettingsRadioGroup / SettingsChipGroup
for consistent grid, spacing, and DRY layout. Also remove the GitPage double
SettingsSection wrap around GitHubSettings.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Unify remaining settings pages onto shared field primitives
Migrate Agents, Snippets, Skills, Usage, MCP identity rows and selects to
SettingsFieldRow/CheckboxRow/ChipGroup and SETTINGS_SELECT_*; align page
titles; light-touch Voice/Tunnel/Providers/Plugins without rewriting
complex OAuth, permissions, or tunnel flows.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Polish settings section dividers and transport helper text
Slightly stronger section borders for clearer group separation, and keep
message-stream transport description under the chip control.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Fix settings grid alignment, control heights, and Chat section titles
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Tighten settings grid: flat Chat 2x2 and full-width stacked selects
Message options use a flat two-column grid so row headers share a baseline.
Stacked selects fill their column; field-row selects keep a fixed sm:w-56 width.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Align mixed settings controls to shared FieldRow/CheckboxRow grid
Separate FieldRows from CheckboxRows with SettingsInset, move enum
radios into ControlGroups, and convert misplaced StackedFields to
full-width FieldRows so left edges no longer clash.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Translate Behavior response-style preset labels for es and pl
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Group settings nav into categories and improve icons/order
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Fix settings layout: fewer hrs, shared control widths, chat transport section
Remove SettingsInset top borders, align App install/Density controls to full cluster width, give Message Stream Transport its own Chat section, and fold Sessions Small Model into the first section to cut extra dividers.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Align Voice and MCP settings labels with shared heading classes
Swap form field labels to SETTINGS_FIELD_LABEL_CLASS and use
SettingsGroupTitle for MCP control-group headings (manual auth fallback,
request headers).
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Differentiate settings heading levels by context
Page titles are larger and quieter than section titles; group and field
labels use dedicated shared classes so hierarchy is consistent across
settings surfaces without ad-hoc typography mixes.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Use shared settings title classes in SettingsView home
Wire home and unavailable headings through the shared L1/L2 class
constants so they stay aligned with SettingsPageLayout.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Keep settings number steppers from stretching +/- buttons
Density & type NumberInputs no longer flex-grow across the row, and
NumberInput locks minus/plus to fixed width so the plus side cannot
inflate when the control is placed in a full-width cluster.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Place spacing and input-bar offset on their own row
Density & type now lays out as font families, then font sizes, then
Spacing Density / Input Bar Offset on the row below.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Regroup settings nav and improve Voice layout
Drop Advanced/Usage/Git nav categories: Voice and About under
Interface, Usage under OpenCode, Git under Workspace. Voice provider
chips and STT model cards use shared settings primitives with roomier
spacing and a two-column model grid.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* Space out chat feature groups in visual settings
* Polish settings: save-state wiring, container-query layouts, unified dropdown triggers
- Wire shared save indicator into Behavior page saves and git identity CRUD
- Convert settings layout primitives and page rows from viewport to container
queries so narrow panes stack instead of clipping
- Unify custom dropdown triggers (model/agent/provider pickers) and remaining
page selects on the settings control size
- Bump global radius scale by 1px; align variant input with select size
- Migrate stray raw controls (MCP OAuth checkbox, worktree remove button,
git identity dialog rows, skills dialog labels) onto shared primitives
- Make settings nav items span full sidebar width; trim nav to 240px
* Add General settings page, regroup nav, cap control widths, promote chat feature headers
* Mobile settings nav: plain background and touch-sized rows
* Hide secondary settings descriptions behind clickable info hints
* Move quota credentials to Usage, navigation settings to General, rename External Tunnel
* Quiet settings save indicator: silent success, delayed spinner, visible errors
* Rewrite settings-ui-patterns skill around shared primitives and refactored conventions
* Remove settings starter page; open last visited page, defaulting to General
* Settings polish: spacing, control sizes, trigger widths, readable model names, device dates
* Centralize dropdown trigger chrome, settings nav polish, mobile-only input bar offset
* Fix global line-height regression, auto-hide first-section divider, shortcut row spacing
* Global line-height 1.45, align scheduled tasks header button with select
* Hide editor toolbar and About in VS Code, animate chat render preview outside desktop dialog
* Rebuild agent tool permissions on source-of-truth model
Edit the agent's own permission map verbatim (inherit vs explicit actions, pattern rules only for pattern-capable keys), save permission-only, drop the server-side non-wildcard re-merge that resurrected deleted rules, and surface session-granted rules as read-only.
* Agents model parameters polish: row spacing, variant dropdown, unified widths, dash for unset numbers
---------
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Replace the legacy terminal flow with a shared authenticated WebSocket
runtime used across web, desktop, relay, and mobile surfaces.
- introduce the v3 terminal protocol with scoped attachments, snapshots,
ordered output, bounded replay history, reconnects, and explicit lifecycle
- harden PTY creation, restart, resize, close, force-kill, idle cleanup,
shell selection, login mode, environment sanitization, and appearance sync
- add runtime-aware terminal APIs with relay authentication and Electron parity
- add a fullscreen mobile terminal workspace with touch scrolling,
long-press selection, safe-area controls, quick keys, and Ctrl/Alt input
- add terminal selection attachments, preview detection, project actions,
shell settings, and localized UI
- harden Ghostty rendering, resize recovery, Unicode handling, block
characters, line height, and stale-row behavior
- remove the obsolete terminal SSE path and update reverse-proxy guidance
- expand terminal runtime, transport, input, selection, and store coverage
- avoid duplicate web builds when preparing mobile assets in root CI builds
* fix(sessions): route new sessions to the correct project when server omits directory
createSession() passed the server response's `directory` field to
setCurrentSession as `directoryHint`. When the server response omitted
the field (a common path), `directoryHint` was `null` and
setCurrentSession fell back to `opencodeClient.getDirectory()`, which
could still hold a stale directory from a different project.
That fallback caused:
- #1637: clicking `+` on one project while browsing another created
a session grouped under the wrong project.
- #2270: in a parent Git repo with multiple child projects (some
without their own Git), sessions from a child with its own Git were
grouped under a sibling child without Git.
Capture the effective directory passed to the SDK and reuse it as the
fallback for the server response. This guarantees `setCurrentSession`
and `registerSessionDirectory` always see the directory the user
explicitly selected for the new session.
Add regression tests covering both reported topologies and the
no-override / no-server-directory preservation path.
* fix(sessions): prefer registered project paths
---------
Co-authored-by: bashrusakh <bashrusakh@users.noreply.github.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Add a VS Code-specific foreground permission responder while preserving the server-owned implementation for web, desktop, and mobile runtimes.
Persist the authoritative VS Code policy in extension global state and expose matching GET/PUT bridge routes. Broadcast policy updates to the sidebar, session editor panels, and agent manager so every active webview observes the same explicit per-session policy.
Resolve missing child-session lineage through OpenCode, honor nearest explicit ancestor overrides, deduplicate concurrent requests, retry transient replies, and reconcile pending permissions after enablement, bootstrap, and reconnect. Treat resolved requests as handled and route notification suppression through the same responder outcome.
Keep post-toggle reconciliation failures non-fatal after policy persistence and fail closed when lineage or replies cannot be confirmed. Document that auto-accept intentionally cannot run while every OpenChamber webview is closed or suspended.
Regenerate the shared UI icon sprite from current source usages. The video-chat icon is no longer referenced anywhere under packages/ui/src, so the generator removes its stale SVG path from the generated asset.
Keep the new-session draft open until the backend confirms that the session was created successfully. This prevents a failed request from closing the draft and discarding the user's creation context.
Restore the exact submitted composer text after a new-session send failure and persist it as the draft. Only restore when the composer is still empty or unchanged, so text entered while the request is pending is not overwritten.
Add regression coverage that simulates an offline session creation request and verifies that the draft remains open with its title intact.
Add pin and unpin actions for user and assistant text messages, with clear compaction-survival labels, localized tooltips, status-info active styling, and VS Code gating where the server runtime is unavailable.
Persist pinned message IDs, creation timestamps, and roles under the OpenChamber session metadata namespace using fresh-read merge updates so goal, review, and other metadata remain intact.
Introduce a server runtime that reacts to OpenCode's dedicated session.compacted event, fetches pinned messages by ID, extracts and chronologically orders their text parts, and injects them as hidden synthetic context through prompt_async. The restoration prompt tells the agent to use the context silently while work remains and limits idle summaries to one short paragraph.
Track the last handled compaction summary to avoid replay duplication, tolerate individually missing pinned messages, integrate runtime shutdown, document ownership and limitations, and cover metadata round trips plus compaction injection behavior with focused tests.
Supports {env:NAME} and {file:path} apiKey substitutions in provider config.
Keeps resolved credentials and file contents server-side.
Adds coverage for env and file-based credential resolution.
Uses thinkingLevel for Gemini 3 Flash models
Keeps older Gemini Flash models on thinkingBudget: 0
Updates docs and tests for the new Google request payload
New drafts now receive the active project ID from sidebar project actions.
Project-group draft creation also forwards the selected project.
Aligns draft opening behavior across project and session selection flows.
Shows the evaluation provider/model used for the latest successful goal audit in the UI.
Persists evaluation model metadata on session goals and covers it in tests.
Adds diagnostic logging for small-model calls and session-goal audit parsing.
The editor font size setting controls code editors and should not also resize the chat composer. Code and conversational input have different readability and layout requirements, so forcing them to share one size is not appropriate.
Delete the share opinion dialog and its sidebar trigger.
Remove the related toast and footer action wiring.
Clean up unused i18n entries in all supported languages.
Commit 5c6546245 removed the editorFontSize reading and inline font-size
styling from ChatInput, calling it 'unused'. However this code was the
core of the editor font size feature (feat/e0229917f) — it applies the
user's chosen font size to the chat input textarea.
Without it, changing Settings > Appearance > Editor font size has no
effect on the chat input textarea. The CodeMirror editor (FilesView,
PlanView) was unaffected because its font size path was not touched.
This reverts the ChatInput portion of 5c6546245, restoring:
- useUIStore selector for editorFontSize
- inline fontSize style on the textarea element
Co-authored-by: bashrusakh <bashrusakh@users.noreply.github.com>