604da92fd9ccbdca6b6b992646c2e7d3625c026f
17
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
604da92fd9 |
fix(sidebar): keep permission badge and hover actions from overlapping (#2284)
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com> |
||
|
|
c1ba631964 |
feat(sessions): show a pending-question indicator on session rows
Adds a per-session pending-question badge to sidebar rows, driven by the live directory-store question state through a dedicated per-session subscription channel so unrelated streaming never re-renders rows. Collapsed parent rows roll up pending questions of hidden descendants from their owning directory stores without bootstrapping them. Question state is cloned on session delete/archive so badges clear when sessions disappear. Adds the questionChangeCallbacks sync performance counter, i18n keys for all locales, and unit tests for the subscription channel and scope selection. Fixes #2634 |
||
|
|
094f728777 |
perf(ui): swap the session activity spinner for a dot and a turn timer
The spinner ran a CSS animation on every active row for the whole turn, repainting a composited layer at frame rate. Rows now carry a static dot — primary while running, info while unread — and the metadata slot on the right shows how long the turn has been going, updating once per second in the dot's colour. The counter is the motion the spinner used to provide, at 1 fps. Collapsed groups, folders and projects take the dot only, since one counter cannot speak for several running turns. Elapsed time is measured client-side because SessionStatus carries no timestamps, and starts are persisted so a reload resumes the same count. Two rules keep that honest. Only a liveness stamp — refreshed while a session is observed active, stamped as the page hides, and compared against the page's navigation start so a slow bootstrap is not charged to the absence — and a 90s adoption window may expire a record; a snapshot that cannot yet see a session is not evidence its turn ended. And a busy event is never read as a turn boundary, because OpenCode republishes busy at every step of the agent loop, so after a reload one of those repeats normally beats the first status snapshot. Idle and error events do end a turn, and retire the record with it. Snapshot reconciliation walks the running turns and asks whether the snapshot covers each one, rather than being handed everything it covers: only a live start can settle, so the pass scales with timing work instead of with the directory's session list, and allocates nothing per poll. Also applied to the mobile sessions sheet and session switcher. The shared duration ticker moves to hooks/ now that it has a second consumer. |
||
|
|
577aca0437 |
feat: add restore/unarchive for archived sessions
Archived sessions had no way back to the active list: the only available action was "Delete permanently". Add restore per session (sidebar context menu, Archive page row) and in bulk (sidebar selection bar). The OpenCode server cannot clear time.archived over HTTP — session.update only applies the field for a finite number, so an omitted key is a no-op and null is silently ignored (verified against opencode 1.18.12). Restore therefore writes time.archived = 0: every client-side reader classifies archive state by truthiness, so 0 reads as active in the UI, the event reducer, and the OpenCode app/TUI. The server's time_archived IS NULL list filter still excludes such rows, so the global session cache no longer issues an archived:false request for its active list. Full and per-directory loads now fetch once with the inclusive flag and split client-side via splitGlobalSessionsByArchived, which also halves per-directory refresh requests. Directory bootstrap keeps the server filter because live child stores must not hold archived sessions; a restored session re-enters its live store through the authoritative session.updated event. unarchiveSession/unarchiveSessions follow the archiveSession contract: wait for server confirmation before reconciling stores, runtime-guard every reconciliation, preserve partial batch results, and fail loudly when the server keeps the session archived instead of toasting a successful no-op. Closes #2346 |
||
|
|
5d24d6cb2a |
fix: dedupe shared worktree ownership
Cherry-picked from claude branch 7b3bec48 (fix: dedupe shared worktree ownership and title sessions immediately). Only the worktree-dedupe half applies to main: partitionWorktreesByRegisteredProject and its callers (SessionSidebar, ElectronMiniChatApp, MobileApp, MobileSessionsSheet) plus tests and sidebar docs. The session-title half (title sessions immediately) remains on the claude branch: the session-title runtime and its claude-code transcript translator imports do not exist on main and cannot build there until the Claude harness lands. |
||
|
|
8130381f6c |
fix(ui): smooth desktop sidebar sticky transitions (#2528)
* fix(ui): blend vibrant sidebar transitions * fix(ui): fade sidebar content below header * fix(ui): smooth vibrant sidebar sticky headers * fix(ui): scope sticky fade to desktop * fix(ui): respect sticky header preference |
||
|
|
1291cde5c2 |
feat(ui): sidebar redesign — project zones, grouping modes, full-page surfaces (#2480)
* checkpoint: flatten sidebar core (flat sessions, zones, single mode, folders flat) * checkpoint: sidebar nav + scheduled/archive full-page surfaces, recent zone header * checkpoint: worktrees management surface via project menu * checkpoint: docs, i18n, validation for sidebar redesign * checkpoint: unified row/zone geometry, recent backfill, tooltips everywhere, primary spinner * checkpoint: branch icon marker, date moved to rich tooltip, recent back to pure time window * checkpoint: PR state on branch markers + tooltip, no reserved right space, aligned show-more, instant tooltips * checkpoint: reserve hover-action space so title text is not overlapped * checkpoint: tighten hover-action reserve * checkpoint: color-only unread emphasis to avoid title reflow * checkpoint: drop new-subfolder action, folder actions overlay on hover * checkpoint: fix sticky project headers (sticky on trigger div), stuck elevation * checkpoint: full-bleed semibold zone headers, no top scroll fade * checkpoint: headers without background tint (typography-only emphasis) * checkpoint: recent header flush with scroll top (no pre-stick bump) * checkpoint: shared tooltip provider with grouping (instant handoff between rows) * checkpoint: blur pointer-click focus so hover chrome hides on mouse-leave * checkpoint: tooltip closeDelay bridges inter-row gap * checkpoint: nav above controls, merged view dropdown, project-scoped bulk selection, cross-worktree folders * checkpoint: folder header tooltip with full path name * checkpoint: true page surfaces (hidden chat, header title, close-on-select), multirun page, run-now jump, folders on top, controls row polish * checkpoint: rename mode — dual-instance outside-click fix, no vertical shift * checkpoint: session grouping mode toggle (by-worktree default, flat option) * checkpoint: worktree header — hover padding reserve + delete worktree action * checkpoint: frosted sticky header backing under desktop vibrancy * checkpoint: align worktree sub-header with project header icon column * checkpoint: restore worktree group DnD reorder; dense vibrancy header tint (Chromium mask+backdrop-filter) * checkpoint: vibrancy — drop scroller mask so backdrop-filter samples rows (Chromium backdrop-root limitation) * checkpoint: vibrancy headers use opaque sidebar tone (Electron transparent-window backdrop-filter bug) * checkpoint: nav collapsed to one row (New session + surface icons), mirrors Add project row * checkpoint: raise sticky zone headers above row action layers (z-20) * checkpoint: New session as full-width CTA + single quiet toolbar row * checkpoint: New session row back to quiet text form above the toolbar * checkpoint: align toolbar left icon with New session icon column * checkpoint: hoverless flat header controls (color-only hover states) * checkpoint: sticky project headers toggle in view dropdown (default on) * checkpoint: full-page surfaces adapted — archive directory filter panel, scheduled master-detail, multirun without duplicate title bar * checkpoint: multirun joins mutually exclusive surface set * checkpoint: surfaces leave via navigation only (no close/cancel buttons), robust close-on-new-session, drop dead MultiRunWindow * checkpoint: no scheduled header description, aligned empty-worktree note, collapse/expand covers worktree groups * checkpoint: overlay scrollbar above sticky zone headers * checkpoint: archive delete icons reveal on hover with padding shift * checkpoint: new worktrees surface at top of the worktree list * checkpoint: no grab cursor on worktree headers * checkpoint: worktrees page list-only with inline action, no worktrees in edit dialog, drop menu ellipsis * checkpoint: worktrees page uses full content width * checkpoint: worktrees header — 'in' instead of em dash, no description * checkpoint: drop legacy OpenCode badge from worktree list, tooltip without OpenCode mention * review: bound pr summary cache |
||
|
|
e908db637b |
feat: agent and CLI control plane for sessions, worktrees, and scheduled tasks (#2408)
Add a shared OpenChamber control service with two thin adapters — a native `openchamber` tool injected into managed OpenCode, and new CLI commands — so users can manage parallel sessions, worktrees, and scheduled tasks conversationally through agents or from the terminal. Control plane: - New openchamber-control service owning a fixed action contract: projects.list, models.list, session list/create/send/fork/status/messages, and schedule list/create/run/delete/toggle. Session and worktree deletion and project registration are deliberately not exposed. - New openchamber-sessions module owning create/worktree/prompt orchestration, Goal Mode dispatch, wait semantics (initial idle never counts as completion; timeout and cancellation are failures), and explicit partial-failure results. - Scheduled-task logic extracted into a service shared by routes, CLI, and the agent tool. Agent tool: - Managed OpenCode gets a materialized plugin registering one typed tool with a loopback-only callback, per-child ephemeral bearer (timing-safe, never persisted or logged), and abort propagation into the service. - The ~1.5k-token schema applies progressive disclosure: short descriptions, server-side validation returning actionable usage errors, and intent guardrails — created sessions/tasks are user-facing work (not age self-delegation); worktree/goal/agent/variant/wait are omit-by-default; dispatches produce no completion notification, and later result r to session.messages, which now returns the authoritative sessionStatus. - session.create without a user-named model picks from favorites/re send/fork omit the selection and the service reuses the target session's last user-message model, agent, and variant before falling back t - An "Agent control tool" setting (default on, Save + Reload to apply) disables plugin injection entirely. CLI: - New `openchamber session`, `schedule`, `projects`, and `models` commands with automatic instance targeting, --wait/--timeout/--last-assist worktree flags, and Goal Mode, preserving interactive, non-TTY, --quiet, and --json contracts. The control HTTP timeout derives from the w instead of the 4-second default. UI: - New built-in "Schedule a Task" starter (/schedule-task) running a dialogue that defines a task and offers to create it via the tool after explicit confirmation; Craft a Goal and Feature Planning gain the handoff offer, and guided starters reserve the question tool for concrete option choices. Localized in all 10 locales, migrated into custom starter lists, hidden on VS Code. - Sidebar shows CLI/agent-created sessions live via the control eve - openchamber tool calls render with per-action titles and metadata. |
||
|
|
38222d07c8 |
fix: include active root sessions in Recent sidebar
Recent now shows active root sessions immediately, even if they are older than 48 hours Archived sessions and subtasks still stay out of Recent Added coverage and documentation for the new recency rules |
||
|
|
89f7c37d60 |
fix: make session ordering follow activity lifecycle
Session lists now promote a conversation when it starts working and again when it settles, instead of reacting to every streaming timestamp update. This keeps ordering responsive without bringing back the sidebar churn removed by the recent performance work. Apply the same user-visible order across Recent, project and worktree groups, session switchers, mobile navigation, widgets, the command palette, and the desktop tray. Preserve pinned priority, freeze timestamp fallback ordering, and keep child-session activity scoped to siblings under the same parent so it never moves the root conversation. Seed reconnect snapshots without synthetic jumps, clear ephemeral ranks on deletion and runtime changes, and cover lifecycle transitions, mixed root/child trees, metadata-only updates, and project-group ordering with regression tests. |
||
|
|
85400459e9 |
perf: overhaul session loading, caching, and runtime isolation (#2360)
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 |
||
|
|
3fd6627196 |
feat: move sessions to new worktrees
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. |
||
|
|
b36afbf5ee |
perf(sidebar): index session ownership and narrow live subscriptions
Replace repeated project-by-session directory matching across sidebar hooks with a shared ownership index that resolves each unique directory once and exposes direct project and folder-scope buckets. Gate destructive folder reconciliation on authoritative session data and topology readiness, preserve last-known worktrees after discovery failures, and retain nested-project, VS Code, active/archive dedupe, and Windows drive-root semantics. Narrow cross-directory subscriptions to session and status slices so streaming deltas no longer trigger global aggregation. Reuse a cached session ID index for permission lineage checks instead of rebuilding it on every session switch. On the reported 15-project, 67-worktree, 14,561-session shape, ownership indexing averages 3.81 ms versus roughly 450 ms for the cache-only hotfix. Validation: 28 targeted tests, UI type-check, UI lint, and dead-code analysis. |
||
|
|
d909c43979 |
refactor(sidebar): remove dead directoryStatus probe artifact (#1660)
Commit
|
||
|
|
c73ab9cbd5 |
feat(vscode): startup parity + workspace-grouped session list (#1658)
* perf(vscode): gate API readiness and coalesce duplicate startup reads Bring the VS Code bridge runtime to parity with the web startup optimizations (PR #1650), which were web/desktop-only. waitForApiUrl now hands out the OpenCode API URL only once the manager reports 'connected', instead of as soon as getApiUrl() exposes server.url. The URL is available the moment the process is spawned — before waitForReady confirms it can serve and during a workspace-switch restart (stale port) — so URL-presence alone let the bridge forward to a not-yet-ready OpenCode and surface 502s. Gating on connected status mirrors the web proxy's isOpenCodeReady hold. Also fail fast on 'error' status so a missing CLI doesn't burn the full 30s timeout. Coalesce concurrent identical GET reads (config/path/agents/agent/ project/command) at the bridge proxy so the single OpenCode process serves them once. On cold start the webview's sync bootstrap and config store fire these reads in parallel with no shared dedup; this is the extension-host analog of the runtimeFetch coalescer. Shared reads carry no AbortController so one caller's abort can't strand the others, and the entry clears as soon as it settles (never serves stale). * perf(vscode): fade the startup splash once mounted + connected, not on live fetch The webview's initial-loading overlay held until a successful live /api/config/providers AND /api/agent fetch completed. After the cache hydration work those live reads are the slowest cold-start tail — the UI underneath already paints pickers and the sidebar from cache and refreshes in the background — so gating the splash on them kept it spinning long after the app was usable. Fade the overlay as soon as the UI is mounted and OpenCode is connected. Per-widget loaders convey any remaining background refresh, matching how web/desktop (which have no such splash) already behave. Removes the now -obsolete bootstrapProvidersReady/AgentsReady/Failed tracking and recordBootstrapFetch. Connection error/disconnected splash messages are unchanged. * fix(vscode): include captured OpenCode output in spawn-timeout error When the managed OpenCode server fails to emit its 'listening' line within the start timeout, the error discarded everything the process printed to stdout/stderr — so the status report showed a bare 'Timeout waiting for server to start' with no clue whether the process hung, crashed silently, or printed a config/auth error. The exit path already includes the output; the timeout path now does too (or notes that nothing was printed). * feat(vscode): workspace-grouped session list with working folders, pinning, and archived toggle Replace the flat multi-workspace session list with the grouped project view, using each open VS Code workspace folder as a header (no per-worktree subgroups). This restores native folder and pin support, which the flat list silently dropped, and fixes the clipped left padding on session rows. - Group sessions strictly by open workspace; funnel all non-archived sessions into the workspace's group so they no longer fall into the archived bucket. - Keep the project/group/folder + buttons but make them open a draft in the correct workspace and navigate to chat; hide the project actions (...) menu, which isn't relevant in VS Code. - Force the minimal single-line row layout (the second metadata row is redundant under workspace headers) and drop the per-row tooltip. - Add a show/hide archived toggle next to the archive-all control, since the VS Code header has no display-mode menu. - Size the hover action reveal so the timestamp clears the row buttons. |
||
|
|
321cc7252a |
Major UI refresh: sidebar redesign, theme expansion, and chat performance optimizations (#706)
## Summary Complete sidebar redesign and comprehensive UI polish pass with performance optimizations, theme system refinements, and desktop integration improvements. ## Key Changes **Sidebar & Navigation Redesign** - Redesigned sessions sidebar layout with unified button primitives - Added activity sections with project grouping and improved session organization - Refined sidebar corners, spacing, and visual hierarchy - Removed NavRail component in favor of streamlined sidebar - Stabilized sessions bar toggle position in fullscreen mode **Performance Optimizations** - Reduced chat streaming CPU usage and storage churn - Optimized task tool polling and live timers with debouncing - Prevented chat state races and reduced background request load - Debounced draft writes and coalesced session reloads - Optimized message store updates and turn tracking **Theme & Visual System** - Added theme-aware window corners (desktop) and border radius tokens - Introduced glassmorphism effects on desktop sidebar - Added backdrop blur to UI elements **Chat Experience** - Added session-based permission auto-accept toggle in chat input - Polished permission shield UX with improved icon sizing and spacing - Fixed chat scroll-to-bottom behavior and timeline tracking - Enhanced tool output display with better path label detection - Removed duplicate draft context details in chat header - Added text selection menu to chat messages **Git Improvements** - Refreshed git history visual design with cleaner dividers - Added remote removal action in sync selector - Stabilized git polling to prevent excessive requests - Improved tool output rendering for git operations **Settings & Panels** - Fixed mobile scrolling on settings pages - Made outside-click settings close instantly - Reduced settings load churn and CPU spikes - Improved services dropdown layout and spacing - Softened panel resize handles **Desktop Integration** - Synced macOS window theme with app theme - Restored window dragging in sidebar header zones - Fixed system window corners on macOS - Improved header session metadata and action controls **Button & Component Standardization** - Unified button primitives across all components - Standardized destructive action patterns - Removed unused button variants (button-large, button-small) - Aligned context tab close hit areas --------- Co-authored-by: Iuliia Ivashko <yulia.ivashko@gmail.com> |
||
|
|
a7f11121e8 |
refactor: modularize session sidebar and add GitHub PR tracking (#610)
* feat: switch sessions sidebar to global paginated loading with archived flow Load sessions via global endpoint with progressive 500-item pagination and legacy fallback Add dedicated archived sidebar section for archived and unassigned sessions Change remove behavior to archive outside archived and hard-delete inside archived * feat: improve archived sessions UX and folder persistence Archive sessions on worktree removal while keeping worktree deletion Streamline archived sidebar actions, icons, metadata, and tooltips Persist session folders to ~/.config/openchamber/sessions-directories.json with startup hydration * fix: align archived session actions and clean empty archived folders Apply archived dropdown behavior consistently for folder-contained sessions Remove archived-only folder actions while keeping standard folder behavior elsewhere Auto-prune empty archived folders during session cleanup and persistence sync * refactor: modularize session sidebar and stabilize behavior Split monolithic sidebar logic into focused hooks and components Kept session, archive, folder, and project interactions working with cleaner state persistence Added sidebar DOCUMENTATION.md summarizing file roles and refactor outcomes * fix: improve fork PR detection and smart remote tracking Added centralized PR status store for shared polling and refresh Auto-selects the remote that has an existing PR when current remote has none Stops periodic polling for closed or merged PRs to reduce unnecessary requests * fix: make chat and toast corners follow active theme radius Toast corners now use theme radius tokens instead of hardcoded rounding User message bubble now uses theme-configured max radius with preserved tail corner Square-corner themes now consistently affect both toasts and chat bubbles * feat: show live PR status across git view and session sidebar Added a shared GitHub PR status store with adaptive background polling and terminal-state pause Improved fork remote detection and auto-selection so existing PRs are found more reliably Updated session group headers to show clickable PR number with branch and state-colored branch icon * feat: centralize GitHub PR tracking and enrich session sidebar PR details Moved PR status polling to a single global pipeline keyed by directory and branch Improved fork-aware PR resolution and reduced duplicate GitHub status fetches across views Added richer session sidebar PR display with clickable number, state-aware styling, and structured tooltip details * fix: adjust PR indicator icon vertical alignment Fine-tuned PR indicator icon vertical alignment in session sidebar Reduced icon translate-y from 2px to 0.5px for better visual balance * feat: improve session sidebar status display * feat: enhance session display logic for minimal mode and improve dropdown menu accessibility * feat: refactor session row to include tooltip for minimal display mode |