* feat(ui): add cache hit rate to context sidebar with verified formula
Add a Cache Hit row to the last-assistant-message token breakdown in
the context sidebar. The percentage is computed by the new
computeCacheHitRate utility:
cache.read / (input + cache.read + cache.write) x 100
The formula was verified against the SDK source
(packages/opencode/src/session/session.ts:getUsage), which reports
input as the non-cached portion only
(totalInputTokens - cacheReadInputTokens - cacheWriteInputTokens).
Also export sumTokenBreakdown from tokenUtils for reuse, and fix the
event-reducer test type errors (setDelta/getText helpers, toBeCloseTo
replacement).
Closes: #
* fix: wire i18n key for Cache Hit label, fix formatNumber type, drop unintended event-reducer changes
* chore: remove unused cacheHitRate and cacheHitRateTooltip i18n keys from en.ts
* fix: correct cache hit token display
* fix: add French cache hit label
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
* feat: add French locale runtime
Add French to OpenChamber's shared i18n runtime, dictionaries, and parity tests so the existing language picker can load a complete fr locale across shared UI surfaces.
* fix: localize shared UI formatting
Remove remaining shared UI locale hardcodings so dates, numbers, and first-party helper copy follow the active app locale instead of leaking English on French surfaces.
* feat: localize VS Code French surfaces
Localize VS Code bootstrap, native runtime messages, panel titles, and manifest contribution strings so French users get consistent first-party copy across the extension experience.
* fix: TASK-2026-05-30-008 correct French review findings
Fix broken French relative-time and weekday strings reported on PR #1482 and restore proper import order in quota utils without broadening scope.
* fix: TASK-2026-05-30-008 address final PR review comments
Capture the localized More Info label once in the VS Code CLI-missing flow and replace the remaining inline French-only utility strings with dictionary-driven copy plus required locale keys.
* fix: TASK-2026-05-30-008 normalize French glossary
Correct glossary-level French terminology on the live PR branch, keeping canonical technical terms like PR, worktree, stash, HEAD, Mermaid, Markdown, remote, and session while replacing misleading literal translations.
* fix: TASK-2026-05-30-008 refine French terminology pass
Clean up remaining glossary mistakes on the French PR branch, especially around Mermaid, Markdown, PR, worktree, stash, branch, remote, and commit terminology, while keeping behavior unchanged.
* fix: TASK-2026-05-30-008 clean remaining French false friends
Correct the SOCKS5 mistranslation and a final small set of obvious false-friend technical nouns on the French branch without changing behavior.
* fix: TASK-2026-05-30-008 correct French glossary terms
Replace remaining false-friend translations in the French UI dictionaries and normalize technical labels for the French PR branch.
* fix: TASK-2026-05-30-008 remove remaining French Mermaid false friend
Replace the last confirmed Sirène translation with Mermaid and re-run the requested blacklist and build verification on the PR branch.
* fix: TASK-2026-05-30-008 enforce French glossary policy
Keep skill/PR/worktree/remote terminology developer-credible in French and remove remaining machine-translated Git and settings copy.
* fix: TASK-2026-05-30-008 keep prompt terminology in French
Replace remaining technical invite translations with prompt wording across scheduled tasks, multi-run, prompt templates, and Magic Prompts.
* fix: TASK-2026-05-30-008 finalize French terminology cleanup
Polish remaining worktree/remote wording, remove visible metadata leakage, and correct final Git and settings labels on the French PR branch.
* fix: TASK-2026-05-30-008 polish final French strings
Correct the last aria-like artifacts and awkward worktree/remote/GitHub URL phrasing in the French dictionaries.
* fix: TASK-2026-05-30-008 normalize final French glossary framing
Tighten the last worktree/remote/checkout wording and fix remaining French grammar around canonical technical terms.
* fix: TASK-2026-05-30-008 align final developer glossary wording
Normalize the last French framing around canonical developer terms like worktree, remote, prompt, and checkout.
* fix: TASK-2026-05-30-008 harmonize final French sentence framing
Replace the last raw franglais around checkout, remote, worktree, and prompt-facing labels with more natural French framing while keeping the chosen technical terms.
* fix: TASK-2026-05-30-008 add compact relative date keys
Replace French-specific prefix stripping in compact session date labels with dedicated i18n keys across locale dictionaries, preserving existing compact label output while making French wording robust.
* docs: add French documentation
* docs: mention French locale folder
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Added a mobile MCP overlay so MCP tools can be opened and managed from the mobile UI without relying on desktop-only dropdown behavior.
Improved mobile session panel touch handling so tapping the status/session area opens the right panel reliably on phones and tablets.
Cleaned up mobile usage provider metadata by removing duplicate rows, hiding unset providers, and showing provider logos consistently.
Added eager loading for provider logos used in mobile usage views to avoid delayed or missing icons when the panel opens.
Refined the mobile update and about flows in OpenChamber settings so release/update information is easier to read on small screens.
Adjusted related layout, header, VS Code layout, command palette, and settings text/localization details needed for the mobile polish.
Add native macOS vibrancy behind the left sidebar (the only translucent
surface; header/chat/right sidebar stay opaque), plus a setting to turn it off.
- Window created with vibrancy applied after first show (avoids the cold-launch
no-composite quirk); minimize/restore suppress the frost during the genie
animation. Renderer frosts the sidebar via --sidebar-vibrancy-overlay once
data-oc-vibrancy[-ready] are set; project-actions pill matches when open.
- data-oc-vibrancy-ready defaults are set in cssGenerator (DOM guaranteed),
not the preload (document-start race left the sidebar un-frosted on launch).
- prefers-reduced-transparency falls back to solid surfaces.
- Appearance settings (macOS desktop only): a checkbox to enable/disable
vibrancy, persisted to settings.json and applied via a Save & restart button
(vibrancy is a window-creation option, so it needs a relaunch).
Rework the desktop layout so the left sidebar spans the full window
height and reads as a distinct column, separate from the header.
- Persistent top-left controls (sidebar toggle + project actions) as a
single overlay that no longer migrates between header and sidebar, so
it stays put while panels animate. Drag regions carve out only under
the buttons so the strip stays draggable and the buttons clickable.
- Header sits in the content column (bg-background); the divider lives
on the chat content (border-t) so it doesn't run between header and
right sidebar. Right sidebar gets a top border + small content padding.
- Drop the rounded chat card and corner masks for flat 1px borders.
- Right sidebar, context panel and git/files views inherit the
background color instead of bg-sidebar.
- Remove hover background from Changes/Staged rows.
- Mini-chat header: borderless, bg-background.
* feat: add draw.io diagram editor integration
Embed draw.io editor via react-drawio (MIT, zero deps) for inline
editing of .drawio files. Changes auto-save to disk. Includes
inline editor in FilesView with Visual/Source toggle, dark mode
support, template picker for new files, and chat file attachment
integration.
* fix: debounce diagram autosave to prevent reload loop
* fix: ignore watcher-triggered xml prop changes to prevent reload loop
* fix: remove auto-save-to-disk, add manual save button for diagrams
Autosave writes triggered file watcher cascade that reloaded the
draw.io iframe and reset zoom. Replaced with explicit Save button
in the toolbar (floppy disk icon). Editor XML is stable on mount
and ignores watcher-triggered prop changes.
* fix: remove auto-save write from DiagramView, add save button
* fix: hide draw.io save/exit buttons in editor
* fix: also hide save-and-exit button
* fix: brighten save button styling, add saved confirmation
* fix: remove autoSaveStatus toggle on diagram save to prevent toolbar collapse
* fix: add local save confirmation state for diagram button
* fix: remount drawio iframe on theme change, persisting XML across mounts
* fix: clear persisted xml on mount to prevent leaking between files
* fix: initialize dark mode synchronously, preserve edits across theme remount
* fix: auto-focus drawio iframe on mount/theme-change for keyboard shortcuts
* fix: add diagram i18n keys to Traditional Chinese locale
* fix: restore upstream HMR host and LAN address support
* fix: load sub-agent sessions on bootstrap for sidebar visibility
Two-phase session load: first fetch root sessions (for accurate
sessionTotal), then fetch all sessions and include child sessions
(sub-agent delegations). This ensures sub-agent sessions appear
in the sidebar immediately instead of relying on the async global
session store.
* remove opencode-drawio from PR branch
* fix: atomic file writes to prevent concurrent read/write truncation
Three-layer defense against the O_TRUNC race:
1. Write side (server): replace direct writeFile with write-to-temp-
then-rename. fs.rename is atomic on POSIX.
2. Read side (server): retry up to 3 times with 50ms backoff when
readFile returns empty but stat reported non-zero size.
3. FilesView client: refuse to save empty draftContent when the
original fileContent was non-empty.
* fix(dev): clean up orphaned OpenCode processes on Ctrl+C
* fix: allow empty file saves, log warning instead of blocking
Replaces the hard block on saving empty content with a console.warn.
The atomic write + read retry on the server side handle the O_TRUNC
race properly. The previous guard caused a UX regression by silently
preventing users from clearing a file and saving.
* fix: remove time window from sub-agent fallback for live tasks
While a task tool is active, the fallback now matches any session
with the correct parentID regardless of creation time. This allows
late-appearing child sessions to be found when the OpenCode server
is slow or the SSE event pipeline is delayed. The time window is
still applied once the task tool has completed, as a final sanity
check.
* fix: three diagram editor bugs from Greptile review
1. stableXmlRef now resets when xml prop changes — switching
between .drawio files renders the correct content.
2. Focus effect only runs on mount, not on isDark changes —
theme toggle no longer steals keyboard focus 600ms later.
3. saveDiagram updates xml state after writing — dirty-check
guard works correctly for subsequent saves.
* fix: route session.created SSE events to correct directory
Three-layer fix for sub-agent sessions not appearing in sidebar and
inline chat:
1. protocol.js: parseSseEventEnvelope now extracts directory from
properties.info.directory (where session.created/updated events
carry it) in addition to properties.directory. WS frames relayed
to the browser now carry the real directory instead of 'global',
so child sessions routed to the correct directory store.
2. event-pipeline.ts: same fallback in resolveEventDirectory for
defense-in-depth when SSE events bypass the WS relay.
3. resolveFallbackTaskSessionId.ts: time window lower bound now
allows 2s grace before taskStartTime to accommodate server timing
jitter (child session creation timestamps consistently precede the
tool's recorded start by ~6-9ms), fixing the 'Open subtask'
button not rendering in OpenChamber's inline chat.
* fix: sub-agent sidebar visibility, file zeroing guard, inline badge fallback
- Sync watchdog: periodic child session discovery poll (every 15s) detects
sessions created by other OpenCode instances, triggers parent materialization
- protocol.js: parseSseEventEnvelope extracts directory from
properties.info.directory for session.created/updated events
- event-pipeline.ts: same fallback in resolveEventDirectory for defense-in-depth
- resolveFallbackTaskSessionId: don't require taskStartTime (cross-OpenCode);
pick most recent child when multiple idle candidates exist
- readTaskSessionIdFromOutput: parse <task id="ses_xxx"> format from output
- FilesView: reinstate empty-draft guard (block save when draftContent='' but
fileContent had content) to prevent file zeroing on tab switch
* Fix diagram autosave reload loop
* Highlight drawio files as XML
* Use diff-compatible highlighting for drawio files
* Restore drawio file icon mapping
* Stabilize drawio source preview toggle
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
* feat(vscode): add archive all sessions action
* Update packages/ui/src/components/layout/VSCodeLayout.tsx
Signed-off-by: Jake <101855602+jjdubski@users.noreply.github.com>
* fix: Fail-open default archives all sessions when workspace can't be resolved
* fix: Already-archived descendants are included in the archive call
* fix: add i18n for the newly added toasts
* Restore icon name from 'add-line' to 'add'
Signed-off-by: Jake <101855602+jjdubski@users.noreply.github.com>
* update: fix merge conflict and update code structure into components
---------
Signed-off-by: Jake <101855602+jjdubski@users.noreply.github.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Add a directory-created fast path for worktree creation so session and send flows can continue once the target directory exists while Git attachment and bootstrap finish in the background.
Track bootstrap status explicitly in shared UI contracts, including pending, ready, and failed states. Background watchers now surface failures and timeouts, update stored worktree metadata, and keep web and VS Code runtime behavior in parity.
Move GitHub issue/PR worktree sessions and assistant-answer fork sessions onto the unified send path so provider, model, agent, and variant selections are preserved. The assistant-answer fork dialog can optionally create a worktree outside VS Code.
Make worktree deletion dialogs close after linked-session cleanup while removing the worktree in the background, and clean up failed fast-create artifacts safely without recursively deleting user or agent-written files.
Validation: bun test packages/ui/src/lib/worktrees/worktreeBootstrap.test.ts packages/ui/src/lib/worktrees/worktreeManager.test.ts; bun run type-check; bun run lint.
Add shared time formatting helpers that apply the Appearance time format preference consistently. Update visible time labels across chat, quota usage, scheduled tasks, tunnels, context details, git views, PR metadata, and passkey settings to use the selected 12-hour, 24-hour, or automatic format. Leave date-only and non-UI formatting untouched so unrelated behavior does not change.
Electron updater now uses Electron release metadata only
Removed legacy Tauri package and migration workflow
Replaced Tauri shim usage with the desktop bridge
Add a packaged-client runtime boundary so the shared UI can talk to local,
desktop, remote, and VS Code runtimes through the right transport instead of
assuming one same-origin web server.
Centralize OpenChamber-owned API access behind RuntimeAPIs, runtimeFetch, and
runtime URL helpers, while keeping official OpenCode traffic on the SDK path.
Support runtime switching, remote host selection, desktop client credentials,
and headless connection links for pairing packaged clients with remote
OpenChamber servers.
Harden the new auth model by moving long-lived client tokens out of browser
URLs, introducing short-lived scoped URL tokens for browser-owned transports,
restricting URL-token access to explicit readable/realtime routes, and making
client-token management session-scoped or self-scoped as appropriate.
Update browser-owned assets and preview proxy flows to work with the split
runtime model, including authenticated project icons, preview token propagation,
CSP-safe preview bridge injection, and preview proxy auth that survives
short-lived URL-token expiry.
Tighten Electron security boundaries for packaged clients by gating privileged
preload state to trusted origins and requiring explicit confirmation before
connect deep-links import or switch remote runtimes.
Also refresh agent guidance and project skills so future runtime/API, auth,
preview, UI, CLI, settings, locale, and drag-to-reorder work follows the new
architecture.
Capture the preview/browser iframe DOM with snapDOM (html-to-image
fallback) so web annotation screenshots match the visible viewport,
without a headless Chromium dependency.
- Preserve document scroll via viewport crop and re-bake nested scroll
(e.g. the Starlight sidebar) deterministically on the clone
- Pin position:fixed elements to their measured viewport rect so headers
and sidebars land correctly in the crop
- Extract preview capture/proxy helpers into
lib/preview/screenshot-capture.ts to slim down ContextPanel
- Guard the external preview proxy against SSRF to private, loopback and
reserved/link-local addresses (incl. cloud metadata)
- Fully validate preview bridge messages before formatting/use
- Warn on the empty browser tab that pages run with full access, so
users browse untrusted sites knowingly
* fix: make upstream sync actions target the selected remote
Ensure fetch and pull actually honor upstream selection so fork maintenance works from the Git sidebar, and surface upstream branch status alongside the primary origin-tracking indicators.
* feat: add Windows Electron desktop foundation
* fix(electron): stabilize Windows desktop packaging
* fix(electron): stabilize Windows desktop chrome
Use native Windows titlebar behavior with an Alt-accessible hidden menu, and harden Windows dev command launching so the desktop app follows platform conventions.
* fix(electron): stabilize Windows dev startup
* fix(electron): clarify desktop artifact names
* fix(electron): harden Windows desktop release and launch
* fix(electron): address Windows release review
* fix(electron): point updater and release links to org repo
* Fix Windows settings persistence fallback
* Fix Windows Electron dev startup
* Add Windows Electron window controls
* Fix Windows Electron install and opencode launch
* fix: resolve git status for repositories without upstream
Fixes repository detection stuck on Checking repository
Handles git status when no upstream is configured
Adds regression coverage for git status loading
* Add Windows app menu button
* fix: preserve file editor line endings
* ci: add desktop release smoke workflow
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Prevents the context panel from overflowing past the right edge
Clamps resize width to the available layout space
Handles previously saved oversized panel widths
Use browser keyboard resizing by default on mobile
Remove mobile-only autocomplete button and tabs
Keep autocomplete behavior consistent across mobile and desktop
Keep the left sidebar open when the context panel opens
Reduce right sidebar and context panel default widths
Collapse only the sync button label at medium widths
Replace the prompt-template workflow with snippet support that is compatible with opencode snippet conventions. Snippets are now stored and loaded from global and project snippet directories, including legacy pluralized paths, with frontmatter metadata for aliases and descriptions. Snippet expansion supports recursive references plus prepend and append sections, while inject sections are treated as unsupported no-ops so OpenChamber remains compatible without requiring an external plugin.
Add the snippets settings experience and remove the old prompt-template settings surface. The new settings page and sidebar support creating, editing, deleting, selecting, and describing snippets, with localized copy across every supported locale. The settings navigation now exposes Snippets with a dedicated icon and metadata.
Wire snippets into all prompt-entry surfaces that need them. Chat, multi-run groups, and scheduled task prompts now offer hash-trigger snippet autocomplete and expand snippets before sending work to OpenCode. Chat also uses an adaptive compact placeholder on mobile or narrow composer widths so helper trigger guidance stays readable in constrained layouts.
Keep multi-run aligned with grouped prompts. Multi-run sessions now use a shared title builder that handles both legacy titles and the newer g1, g2 prompt-group title format. Fusion parsing now recognizes grouped multi-run titles, scopes fusion sources to the same prompt group, and creates fusion sessions under the matching group so outputs from different prompts are not mixed accidentally.
Harden the icon sprite pipeline. The sprite generator now discovers icon names used through typed icon maps, JSX icon props, IconName returns, and generated-value flows without scanning unrelated string literals or the generated sprite itself. The generated sprite is strictly typed so invalid icon names are caught by type checking, and existing invalid or unsafe icon references were cleaned up across settings, provider, Git identity, scheduled task, voice, header, and sidebar surfaces.
Update backend configuration routes and documentation for snippets. The OpenCode config route layer now exposes snippet CRUD and expansion endpoints, accepts JSON bodies for snippet writes, and removes the old prompt-template provider. Scheduled task runtime expansion now uses snippets before dispatching messages.
Add regression coverage for snippet storage and expansion, config-route JSON handling, and multi-run title parsing. Validated with full type checking, full linting, targeted multi-run title tests, and targeted OpenCode snippet/config route tests.
Improve chat session switching and history pagination, with most of the aggressive limits scoped to the VS Code webview where the freezes were observed.
Session history loading and pagination:
- Reduce the VS Code message page size to 30 records so switching sessions does not immediately hydrate large histories into the webview.
- Keep manual Load older messages in VS Code fixed at 30 records per request instead of growing the request size over time.
- Add a bounded VS Code initial-tail expansion path from 30 to 50, 80, and 120 records only when the initial page has no user-message turn boundary, preventing large final turns from rendering as an empty chat.
- Lower the normal web message page size from 200 to 150 for a mild shared optimization without adopting the aggressive VS Code limits.
- Make session pagination metadata reactive per session so ChatContainer receives cursor updates from materialization and reconnect paths without requiring a switch away and back.
- Write pagination metadata before publishing newly materialized messages so the first render sees the correct has-more state.
- Store cursor information from direct materialization and reconnect message fetches in the shared session prefetch metadata cache.
VS Code cache and memory pressure reductions:
- Use a shared per-directory session recency map so cache eviction is based on app-level recency instead of whichever useSync instance happened to run.
- Limit VS Code warm session cache retention to 4 sessions and evict heavy inactive message caches after switching away from a large session.
- Disable sidebar session prefetch in VS Code because warming extra sessions was increasing webview memory and GC pressure during navigation.
- Remove dropdown background message prefetch so opening the switcher does not start additional session materialization work.
- Drop cached session-message-record snapshots when evicting session data so stale derived records do not remain after the raw session cache is cleared.
- Add bounded LRU caching for session message record snapshots, with much smaller VS Code limits and a VS Code cap that avoids caching snapshots above 30 messages.
- Bound the turn-window model cache in VS Code and avoid caching turn models for sessions above the VS Code message-page size.
Chat render-path reductions:
- Reuse ChatContainer's already-materialized message records in plan detection instead of adding a second active-session message subscription.
- Add a no-op guard when marking session plan availability so repeated detections do not create new Map references and fan out renders.
- Add no-op guards for session switcher and dropdown open state updates to avoid unnecessary store updates and renders.
- Convert several session-specific hooks to useSyncExternalStore with empty-session no-subscribe behavior so empty IDs do not subscribe to broad store updates.
- Remount the chat viewport when the current session changes, isolating per-session viewport and list state.
- Change the virtualized message-list fallback to render only a tail window when the virtualizer has not produced rows yet, instead of rendering an entire large history.
VS Code layout and header improvements:
- Remove the broad useSessions subscription from the VS Code layout header path and subscribe only to the active session title and initial-session existence.
- Unmount the compact VS Code session sidebar when the user is in chat view instead of keeping the hidden session list mounted and subscribed.
- Compute the latest assistant model and latest context-token usage in a single reverse scan of current-session messages instead of scanning the same list twice.
- Remove switcher git-status warmup work so the switcher reads already-loaded branch labels without starting extra background git status requests.
Markdown and file-reference safeguards:
- Skip expensive syntax highlighting for very large code blocks, with a 200-line cap in VS Code and a softer 1200-line cap in web.
- Add an LRU cap to file-reference stat lookups so the cache cannot grow without bound across many rendered messages.
- Limit the number of file references annotated per render to 40 in VS Code and 200 in web to prevent large assistant outputs from spawning too many stat checks.
- Clear file-link annotations when file-reference mode is disabled so stale attributes and handlers do not remain on previously annotated nodes.
Assistant-message action and preview reductions:
- Skip preview URL scanning on VS Code, mobile, and mini-chat surfaces so assistant text and tool output are not scanned where the preview action is unavailable.
- Skip Save-as-Plan project lookup on VS Code, mini-chat, and mobile surfaces.
- Hide Save-as-Plan and Start MultiRun assistant-message actions on VS Code, mini-chat, and mobile surfaces.
- Resolve the current session directory on demand for assistant actions instead of subscribing each assistant message to the full session list.
Tool and task rendering optimizations:
- Prefer finalized task metadata summaries without fetching child-session messages when the summary is already present.
- Avoid polling or final-fetching task child sessions once a final metadata summary is available.
- Use VS Code-specific task child fetch limits of 30 records for initial, active, and idle fetches.
- Parse diff stats by scanning patch text line-by-line instead of splitting large patches into arrays.
- Count write-tool lines by scanning content instead of allocating a split array for large files.
- Avoid trimming large patch strings just to test whether they contain content.
- Memoize diff and write statistics so unchanged tool parts do not recalculate them on every render.
VS Code bridge improvements:
- Return JSON and text proxy responses through the VS Code bridge as bodyText instead of base64 so the webview avoids synchronous base64 decoding for common API responses.
- Keep binary responses on the base64 path while making bodyBase64 optional in the bridge contract.
- Strip content-length, content-encoding, and transfer-encoding headers from proxied responses because the bridge reconstructs the Response body.
Validation:
- bun run type-check
- bun run lint
- bun run vscode:build
Inner sidebar content was pinned to a fixed openWidth (derived from store state) so it kept its full size during open/close animation. But store state only updates on pointer-release during a drag, which meant inner content didn't reflow while the user was actively dragging — only after they let go.
Keep openWidth as the inner width when the sidebar is idle (so slide-out animation still shows full-width content under the clipping aside), but during an active resize bind the inner content to a CSS variable that applyLiveWidth updates on every pointermove. The aside continues to use direct px width for transition reliability; the variable is just a side channel for the inner element.
OpenInAppButton and ProjectActionsButton now render icon-only triggers in the header instead of icon + text. Padding is tightened accordingly and the now-unused selectedButtonLabel / formatActionButtonLabel helpers are gone.
With narrower triggers the previous center-aligned dropdown with translate -30px started overflowing the viewport on the left edge for ProjectActions. Switched ProjectActions dropdown to align="start" and OpenInApp dropdown to align="end" (matching their positions in the header) and removed the manual translate offset.
Also fixed a long-standing inconsistency where clicking an already-running action in the ProjectActions dropdown re-ran it instead of stopping; the non-compact branch was missing toggleStopIfRunning=true that the compact branch already passed.
MiniChat header now uses bg-sidebar to match the main desktop header palette.
Sidebars now slide open/closed with a 200ms cubic-bezier(0.22, 1, 0.36, 1) transition on width. Inline transitionProperty/Duration/TimingFunction are used directly on the aside so the change is browser-driven rather than relying on Tailwind arbitrary classes that didn't reliably trigger the width transition.
Inner sidebar content is pinned to the open width with shrink-0 so it stays full-size while the outer aside collapses around it, eliminating the vertical jitter that came from content reflowing when its container shrank. The chat-frame keeps a constant 1px border and 10px radius on all four sides — only the left/right border color toggles between border/50 and transparent — so no layout reflow happens when sidebars open. Mask-corner overlays are always mounted and animate their left/right offset and opacity in lockstep with the sidebars instead of mounting/unmounting.
Header now spans the full window width above the [sidebar | chat | right-sidebar] row instead of nesting inside the central column. The chat area becomes a self-contained framed window with its own border and rounded corners on all four sides, and sidebars sit flush against the header sharing its bg-sidebar so the seam is invisible.
Removed the duplicated shell controls the old layout needed to fake header-height inside sidebars: portal host on RightSidebar, paddingTop reservation, top drag overlay, duplicated layout-left / chat-new buttons in SidebarHeader, the showDesktopSidebarChrome block in SessionSidebar, and the conditional traffic-lights inset on the desktop header. Mac WCO inset now lives only on the header.
Moved the new-session action into the SessionSwitcher dropdown as its first item, removed the standalone chat-new button from the header, relocated scheduled-tasks into the left action group of the sidebar header, and bumped ContextPanel tab strip to h-10 to balance the more prominent header.
Targets active editor chat before falling back to sidebar
Adds session open-in-editor action in the VS Code sidebar
Uses attachment badges for VS Code file and selection context
* fix: prevent mobile keyboard from occluding terminal viewport
On mobile, 100dvh does not shrink when the soft keyboard opens, causing
the terminal and other absolute-inset-0 views to extend behind the keyboard.
Add useVisualViewport hook that tracks window.visualViewport.resize/scroll
via RAF. On mobile, use the visual viewport height (actual visible area)
for the root container instead of 100dvh, so content resizes above the
keyboard when it opens.
* fix: skip unchanged visual viewport updates
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Adds read-only embedded chat mode without hiding permission prompts
Opens subagent sessions in the context panel instead of replacing the main chat
Fixes context panel message loading for embedded sessions