Skip to content

Client 1.3.0

Choose a tag to compare

@github-actions github-actions released this 19 Jul 00:00
63e78aa

Added

  • Multi-session board: open and use up to six sessions at once without archiving, interrupting, or otherwise changing the underlying sessions. Two or three sessions share one row; four to six sessions use a 3-column, 2-row board. Each pane keeps its own transcript, message input, queue, usage, selected model and variant, preconfig, compaction state, streaming state, and session controls.
  • Open alongside: open another session without replacing the focused pane from the session actions menu, with Cmd/Ctrl+Click, or with Cmd/Ctrl+Enter on a keyboard-focused session in the sidebar. Selecting a session that is already open focuses its existing pane instead of creating a duplicate.
  • Cross-workspace boards in Overview: Overview can display sessions from different workspaces on the same board. Shared files and terminal surfaces follow the focused session's workspace, while every visible session remains active and interactive.
  • Pane reordering: drag the grip in a pane header to reorder sessions across the 3-by-2 board. The compact session switcher is sortable as well. Keyboard users can focus a grip, press Space or Enter to pick up the pane, use the arrow keys to move it, and press Space or Enter to drop it. Escape cancels the reorder.
  • Pane keyboard navigation: Option/Alt+1-6 focuses a pane and its chat input. Option/Alt+Shift+Left and Option/Alt+Shift+Right move to the previous or next pane, wrap at the ends, and focus the destination input. Cmd/Ctrl+Shift+F toggles follow/free mode for the focused pane.
  • File editor with CodeMirror 6 (components/editor/): a persistent, multi-tab code editor with syntax highlighting for JavaScript/TypeScript/JSX, JSON, Markdown, CSS/SCSS, HTML/XML, Go, Python, PHP, Kotlin, Java, and SQL. Features compartment-based theme/language/read-only switching, CSS variable-driven light/dark themes, and safe document switching via view.setState() that prevents undo-history leakage across files.
  • Git diff decorations in editor (components/editor/gitDiffExtension.ts): inline line background colors for added/modified lines, gutter markers (colored dots), and block widgets showing removed line content (capped at 500 blocks), all auto-mapped through editor transactions.
  • File editor surface (components/editor/FileEditorSurface.tsx): tab-based multi-document editor with dirty indicators, active file toolbar (path, Git diff +/- counts, diff toggle/refresh, Markdown source/preview tabs, Save button), conflict resolution banner (side-by-side compare, Overwrite/Reload/Cancel), unsaved-changes close dialog, and keyboard shortcuts (Cmd/Ctrl+S to save, Cmd/Ctrl+W to close tab). All open docs stay mounted (hidden) to preserve cursor, scroll, and undo history across tab switches.
  • File editor store (stores/fileEditorStore.ts): Zustand store tracking per-document state (revision, base content, edited content, status, conflict) with identity-based deduplication (serverId + workspaceId + root + path), dirty tracking, and full save/conflict lifecycle.
  • Terminal workspace restoration (components/layout/TerminalPanel.tsx): per-workspace active terminal tab memory (remembers which terminal was active per workspace and restores it on switch), automatic reconnection with exponential backoff when the terminal events WebSocket drops (up to 5 retries), and click-to-reconnect on a disconnected active tab.
  • OAuth reauthentication UI (components/modals/configuration/OAuthProvidersPanel.tsx): three-state provider rendering with amber "Reauthentication required" indicator, error text, and a prominent Reconnect button (plus secondary Disconnect) when the server reports reauthRequired.
  • Real-time provider status refresh (handlers/serverMessage/providerHandlers.ts): provider.status and provider.connected WebSocket events now update provider status state and invalidate TanStack Query caches, so the provider settings UI updates automatically after OAuth flows complete or connection status changes.
  • PWA update flow (pwa/, components/app/PWAUpdateBanner.tsx): service worker registration with periodic and event-driven update checks (polls every 60 minutes, checks on visibilitychange and online), user-facing update banner with dismiss/restart, stale build error detection and cache cleanup recovery, and foreground re-display of dismissed updates.
  • Syntax highlighting (components/editor/CodeMirrorEditor.tsx): CodeMirror editor now maps 15+ token types (comment, keyword, string, number, function, type, property, operator, etc.) to CSS custom properties that adapt per theme.
  • Edit button in file preview (components/files/FilePreviewOverlay.tsx): "Edit" button (disabled for deleted files) opens the file in the new editor.

Changed

  • Board order and focus persist in the URL: open sessions are stored as an ordered open search parameter while the focused session remains in the route path. Refreshing restores the same sessions, focus, and pane order. Focus and reorder operations replace route history instead of adding noisy navigation entries.
  • Responsive multi-session layout: when the available width cannot fit all required columns, the board shows the focused session with a compact switcher instead of shrinking panes below their usable width or silently dropping sessions. Returning to a wider layout restores the complete board.
  • Single-session presentation stays full-width: boards with one open session retain the standard workspace header and chat presentation. Per-pane headers, borders, remove controls, and focus rings appear only when multiple sessions are open.
  • Workspace content layout (components/app/WorkspaceContentArea.tsx): file editor rendered alongside the session board. Desktop: resizable side-by-side split with pointer-drag divider (25-80% editor width, persisted in localStorage). Mobile: editor overlays chat when a file is active with a "Chat" back button. beforeunload warning added when any editor doc has unsaved changes.
  • Removed unmaintained provider UI: deleted configuration UI for providers no longer maintained in the server.

Fixed

  • Escape now focuses the correct chat input: pressing Escape after clicking a transcript, pane header, sidebar, or another non-chat surface now focuses the input for the focused session, including grid and compact layouts.
  • Focused pane removal no longer reopens the removed session: removing the first or currently focused pane now selects a remaining neighbor and updates the route correctly instead of leaving stale focus that could restore the removed pane.
  • Multi-session updates remain session-scoped: transcript parts, queue changes, usage, model selection, compaction state, streaming events, and session commands are routed to their target session instead of leaking through single-session compatibility state.
  • Partial assistant response no longer disappears on error — when an AI provider error occurred mid-stream (rate limit, server error, timeout, etc.), the already-generated text, reasoning, and tool calls were hidden from the transcript and replaced with only the error banner, even though the content was persisted on the server. Messages with accumulated content parts now render both the partial response and the error indicator below it. Messages with no content (error before any tokens streamed) still show only the error banner as before.
  • Git diff extension decoration sorting (components/editor/gitDiffExtension.ts): replaced manual RangeSetBuilder with Decoration.set(..., true) (pre-sorted ranges) and switched from EditorView.decorations.of() callback to EditorView.decorations.from() facet, fixing decoration ordering issues.
  • Terminal stale closure bug: sdkClient and workspaceId are now captured into local constants at the top of the events effect, preventing stale references when the async subscribeEvents() resolves after a workspace switch. Status change handler now only sets 'exited' on explicit exit events instead of unconditionally toggling.
  • Stale reauthentication state on reconnect: handleProviderConnected() explicitly clears error and reauthRequired when a provider.connected event arrives, preventing stale failure state from surviving a successful reconnect.