Use a shorter comment placeholder on mobile (drop the Cmd+Enter hint that has
no touch equivalent) so it no longer clips in the auto-sized textarea.
Add a remove (x) button to the review comments pill, matching the annotation
and dev-server-log pills, and stop the mobile touch-target min-height/width
from inflating the pill close buttons.
Center PWA dialogs again by dropping the stale iOS offset that pushed a
flex-centered (position: relative) dialog down by half the viewport.
Seat the mobile overlay panel flush to the bottom (drop the float margin),
drop its bottom border in favor of a scroll shadow on the content, and raise
it above sheets (z-60) so an overlay opened over a surface sheet renders on
top instead of behind it.
Defer mounting heavy sheet content until the enter slide finishes (revealed on
the slide's transitionend, with a timer fallback) so the animation no longer
competes with a large content render. Shorten the slide to a quick rise from a
small offset, and seat the sheet a few px below the top safe area.
Revert the 100dvh sizing back to inset-0/100% — it did not fix the bottom inset
and reintroduced intermittent top safe-area dimming.
Drop the safe-area-bottom padding inside the sheet and size the surface from
100dvh (instead of fixed inset:0 / 100%, which on iOS 26 stops above the bottom
safe area), and avoid keeping the sheet on a compositing layer when settled.
Tightens the bottom gap so the sheets sit close to the bottom edge like the
chat composer.
Use a dark scrim for MobileOverlayPanel instead of a translucent background so
it dims the rest of the screen like the sessions sheet.
Rework MobileSurfaceShell to mirror that structure: the scrim is the fixed
parent's background with a quick fade (keeping it on a compositing layer iOS
Safari clips to the viewport), and the sheet is a flex child sized to leave the
top safe area dimmed — dropping the old top shadow that pooled at the corners.
Mount Files/Changes/Settings only while open so each recomputes its
safe-area layout fresh, fixing intermittent top-inset dimming, and drop the
dim behind the header overflow menu to avoid a scrim-to-scrim flicker on
select.
Nest child sessions (by parentID) under their parent in the mobile sessions
list, with a chevron in the row's left gutter to expand/collapse them
recursively. Top-level pagination counts only parent sessions; children whose
parent isn't in the same bucket stay top-level so nothing is hidden.
Expansion state lives in an in-memory store that survives closing and
reopening the sheet but resets on a full page reload.
Restructure the changes list so the staged/changed file list scrolls inside
ChangesPanel while the commit message and actions stay pinned to the bottom,
matching the desktop git sidebar instead of letting the commit box scroll out
of view with the list.
Remove the per-row agent color dot (and its now-unused helpers), keeping only
the status indicator. Add a "+" button to the panel header that opens a new
session draft targeting the filtered project (or the most recently active
session's project under "All", falling back to the default target), and
restyle the close button to match it.
Show the context token usage next to the percentage (e.g. 5.1% 20.4K/400.0K)
at a larger, consistent size, and compute the percentage with a fraction
instead of the store's integer-rounded value.
Add a two-step archive affordance to each mobile session row, mirroring the
project remove confirmation: tapping the archive icon arms an inline confirm
(with cancel), and confirming archives the session. Only one row can be in
the confirming state at a time.
Also relabel the project remove confirmation from "Delete" to "Close"
across all locales, since removing a project closes it from the app rather
than deleting anything.
Replace the up/down arrows in the mobile project reorder list (drag already
covers reordering) with an edit button that opens a dedicated project editor
surface: rename, pick icon and color, and discover a favicon (no upload).
The editor lists the project's worktrees with drag-to-reorder (persisted per
project, like project order) and a delete button that opens a mobile
confirmation built on the shared worktree primitives — archiving attached
sessions and optionally removing the local/remote branch.
Persist project/worktree expand state across restarts and decouple it from
the active directory — projects default expanded, worktree groups collapsed,
and the user's explicit toggles are remembered.
Selecting a session now switches the active project (not just the draft),
following the session's directory.
Replace all-or-nothing session pagination with incremental +7 loading that
resets when a group or project is toggled, matching the desktop sidebar.
Always render root (project-level) sessions as a flat list above worktree
groups, and vertically center the session row status dot.
Add a toggle for displaying archived sessions in the sidebar menu
Load more sessions in smaller increments
Reset expanded session counts when collapsing groups or projects
* feat: add dialog for "Start new session from this answer"
Replace the one-click fork action on assistant messages with a dialog
(ForkSessionDialog) that lets the user pick model, thinking level, and
agent, plus edit the instructions sent to the new session.
The instructions field is prefilled with the previous fixed fork prompt
and is mandatory. The composed message is now fully visible (no synthetic
preface): the user's instructions sit above a short fixed connective that
opens the assistant content. createSessionFromAssistantMessage takes the
chosen execution params instead of reading from config.
Also fix TodoSendDialog visuals: narrower vertical layout, model trigger
no longer stretches with centered text, and the agent/thinking dropdowns
portal to body so opening them no longer nudges the dialog height. Extract
the shared ThinkingPill into its own component.
* fix: address review feedback on fork session dialog
- Fix "bellow" -> "below" typo in the fork content preface (now user-visible
since the message is no longer synthetic)
- Reset ForkSessionDialog state only on open transition, reading the config
store snapshot via getState() so background store refreshes can't discard
in-progress instruction edits
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.
Loading screens: drop the internal-jargon progress text on the opencode
reload overlay (ConfigUpdateOverlay) and the vscode init splash — show
text only on errors. Replace it with a glow pulse on the OpenCode mark on
the cube's top face; OpenChamberLogo's isAnimated prop was a no-op and now
actually animates. vscode shows the glow on the inline splash logo and the
React app stops writing 'Loading data (… Providers, … Agents)…'.
Restart API: 'OpenChamber: Restart API Connection' now runs the same full
reload flow used after an OpenCode update — the command asks the chat
webview to call reloadOpenCodeConfiguration() (overlay + managed restart
via the bridge + config/data refresh) instead of a bare manager restart,
falling back to the old restart when no webview is open. Mounts
ConfigUpdateOverlay in the vscode app so the overlay actually shows there.
On refresh the auto-open draft opens in an effect (after first paint), so
ChatContainer briefly rendered ChatEmptyState (logo + 'start a new chat')
before the welcome screen. When a draft is about to auto-open and there's
no init error, render a neutral background instead — the empty state stays
for the cases where it's actually meaningful (no auto-open, or init error).
Capture the @dnd-kit setup that works for both desktop and mobile —
the Translate-not-Transform stretch fix, rectSortingStrategy for wrapping
rows, MouseSensor + long-press TouchSensor, touch-action none, and the
pitfalls we hit (onDragOver live-reorder infinite loop, offset overlay).
References DraftPresetChips and sortable-tabs-strip.
Let users curate the draft welcome chips: pin existing commands and skills
as starters, remove them, and drag to reorder — all inline on the draft
screen via a '+' picker dialog and per-chip remove, with no separate
settings UI.
A starter references a command or skill; its scope is inherited from the
item (user-scope -> global, project-scope -> per-project). Global starters
persist to settings.json (useUIStore + client/server sanitizers); project
starters persist to the project config alongside worktree setup commands.
The two scopes form ordered namespaces shown global-first then project,
reorderable only within each group.
The six built-in Session magic-prompt commands are the default global set
and stay available in the picker for re-pinning if removed; they keep their
bespoke icons, while user commands/skills fall back to the Commands/Skills
section icons. Chip labels are normalized (/simplify-code -> 'Simplify
code'). Missing commands/skills are skipped rather than shown broken.
Drag-to-reorder works on desktop and mobile: rectSortingStrategy for the
wrapping multi-row layout, CSS.Translate (no scale) so the lifted chip
doesn't stretch, and MouseSensor + long-press TouchSensor so taps still
submit and swipes still scroll. The '+' picker is a searchable dialog on
every surface.
Mini-chat uses the same centered-welcome compact layout, so the preset chips fit fine under the welcome message there as well. Drop the mini-chat exclusion.
On narrow surfaces (mobile, vscode) the composer sits at the bottom and
only the welcome message is centered, so the preset chips had nowhere
sensible to live and were desktop-only. Render them under the centered
welcome message there instead.
Extract the shared preset list (draftPresets.ts) and chip row
(DraftPresetChips) so both layouts reuse them. Since the command-aware
submit lives in ChatInput, ChatContainer triggers it through a new
input-store channel (requestPresetSubmit / consumePendingPresetSubmit)
that ChatInput consumes. Mini-chat stays excluded — too small for the row.
The old workspace-review prompt only hunted for catastrophic bugs and
omitted everything it wasn't highly certain about, so it usually returned
'No high-signal issues found' and felt useless.
Rework it to first understand the diff's intent and judge whether the
implementation actually achieves it and is adequate (smallest correct
solution, completeness), then review correctness across concrete failure
modes (concurrency, lifecycle, state fanout, comparators, a11y,
regressions, targeted-test gaps) plus a security/supply-chain lens, and
classify findings by severity (blocker / non-blocker / nit). Keeps the
existing false-positive discipline (diff is source of truth, validation
pass, no nitpicks, cite rules) and stays review-only by default.
Adapted from a battle-tested PR-review prompt, minus the GitHub-specific
parts that don't apply to a local workspace diff. Updates command and
settings descriptions across locales.
Reword the /catch-up prompt and its Magic Prompts settings descriptions to
emphasize an easy-to-digest summary rather than a 'warm'/'friendly' tone —
the goal is ease of comprehension, not friendliness. Updated across all
locales.
Rework the /catch-up decision tree from mutually-exclusive cases into
complementary layers. It now determines whether the current branch is the
repo's default branch and builds context accordingly: on a feature branch
it reads enough of the branch's own commits to grasp the intent and checks
the branch's PR even when there are uncommitted changes (so in-progress
work is understood as part of the larger effort); on the default branch it
lightly skims recent commits. Uncommitted changes remain the focal point
but are interpreted through that context.
The suggested next step now favors continuing the actual work over
housekeeping — since running catch-up implies the user stepped away and
the work is likely unfinished, push/PR/checks are only a fallback. Updates
the Magic Prompts settings descriptions across locales to match.
Promote the last plain-prompt draft chip into a proper /explore command so
all draft welcome presets are now commands. Its hidden prompt investigates
the repository and gives a structured orientation — big picture, main
modules, how they connect, conventions, and where to start — instead of a
file-by-file dump.
Follows the established pattern: visible + hidden magic prompts wired into
command autocomplete, the submit handler, the draft chip, and the Magic
Prompts settings page, with i18n across all locales. Drops the now-unused
explore prompt string.
Rework the /weigh hidden prompt so the recommendation is driven by what
best serves the user's actual goal — not by what is fastest or least
effort. Effort and complexity are surfaced as honest consequences rather
than reasons to steer toward a weaker option, strong-but-harder
approaches that fully cover the idea must be included and discussed, and
a watered-down solution is never recommended just because the proper one
is more work.
Add /weigh as a draft chip and command for the moment before planning —
when you know what to build but not how. Its hidden prompt investigates
the code, then lays out 2-3 genuinely distinct approaches with trade-offs
(complexity, risk, blast radius, effort) and a clear recommendation,
without writing a plan or code.
Follows the established command pattern: visible + hidden magic prompts
wired into command autocomplete, the submit handler, draft preset chips,
and the Magic Prompts settings page, with i18n across all locales. Adds a
scales-3 icon to the sprite.
Rework the /catch-up hidden instructions: write like a teammate catching
you up rather than a CI summary, scope strictly to the current branch,
and never surface unrelated branches, other people's PRs, or review
requests. When the current branch has no PR of its own, skip pull-request
talk entirely and just recap recent work plus a next step.
Replace the 'What changed recently' draft chip with /catch-up, a command
whose hidden prompt branches on git state: reconstruct intent from an
in-progress diff, check an open PR's review state, or summarize recent
commits.
Add /debug as a new draft chip and command: a guided root-cause
investigation that captures the symptom, forms hypotheses, checks them
against the code, and confirms the cause before proposing a fix.
Both follow the /workspace-review pattern — visible + hidden magic
prompts wired into command autocomplete, the submit handler, draft preset
chips, and the Magic Prompts settings page, with i18n across all locales.
Add starter preset chips under the composer on the desktop draft welcome
screen (explore, what changed, plan, review). Clicking a chip submits
immediately; prompt chips send a natural-language prompt, command chips
reuse built-in slash commands.
Add a new /plan-feature built-in command, modeled on /workspace-review:
visible + hidden magic prompts that run a guided, batched-question
planning dialogue (investigate the code, ask up to 3 clarifying
questions at a time, surface pitfalls, then produce an implementation
plan). Wired into command autocomplete, the submit handler, the draft
plan chip, and the Magic Prompts settings page, with i18n across all
locales.
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 chat history pagination and scroll preservation
Align session history loading with the expected scroll-up pagination UX while
keeping OpenChamber-specific initial message limits for constrained runtimes.
- Separate initial load sizes from older-history pagination size
- Load older messages automatically when scrolling near the top
- Continue fetching history until a visible older turn is available
- Preserve the current viewport synchronously during prepends
- Prevent history loading from fighting pinned-to-bottom follow behavior
- Remove delayed scroll-to-bottom correction that caused jumpbacks
- Fix the virtualizer fallback path that could render a large blank spacer
- Track oldest loaded message per pagination iteration to avoid redundant fetches
Only auto-send queued messages after an active session becomes idle
Avoid treating missing initial status as safe to send
Add coverage for queue auto-send status transitions
Queued messages now match the reverted message dock style
Added per-message edit and send actions
Sending one queued message no longer sends the full queue