Commit Graph
150 Commits
Author SHA1 Message Date
fc06a9c499 fix(chat): reduce user message padding and hide top scroll shadow on mobile (#496)
* fix(chat): reduce user message padding on mobile

* fix(mobile): limit drawer swipe gesture to status bar only

* fix(chat): hide top scroll shadow on mobile

* fix: add mobile edge-swipe drawer fallback and normalize comments

- Adds narrow left/right mobile edge swipe zones for drawer gestures
- Keeps drawer swipe access even when the mobile status bar is hidden
- Replaces remaining non-English comments in touched chat/layout files

* fix: remove edge swipe settings and tighten mobile chat spacing

---------

Co-authored-by: Jovines <jovines@qq.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-02-24 17:38:12 +02:00
Bohdan Triapitsyn 100d6d33a1 feat: show structured output value in tool description 2026-02-24 15:53:19 +02:00
Bohdan Triapitsyn 4a8c69e36a refactor: move git generation to session structured output
- Use active session prompts for commit/PR generation and drop backend git generation routes.
- Improve tool activity UX with Structured Output rendering, description styling tweaks, and detailed-mode expansion fixes.
2026-02-24 15:37:35 +02:00
25d616f009 feat(mobile): refactor drawer system and session status bar (#494)
* feat(mobile): refactor drawer system with swipe gestures and improved status bar

- Add DrawerContext for centralized drawer state management
- Implement swipe gesture support for left/right drawers
- Refactor MobileSessionStatusBar with token usage indicator
- Update Header component with drawer toggle props
- Improve RightSidebar touch handling
- Add mobile-specific styling improvements
- Update UI store for drawer state management

* feat(mobile): update empty session hint text to clarify swipe gesture area

* fix(mobile): restore MobileAgentButton tap-to-cycle and long-press behavior

- Revert removal of tap-to-cycle agent switching functionality
- Re-add onCycleAgent prop and long-press detection (500ms)
- Click now cycles through primary agents, long-press opens selector panel
- Fixes regression from commit 569cc411

* feat(mobile): add project switcher bar and fix button interactions

- Add ProjectBar component to MobileSessionStatusBar for quick project switching
- Add useProjectStatus hook to track project-level session indicators
- Integrate project store with directory store for project management
- Add project status indicators (running/unread) to session status bar
- Fix MobileAgentButton pointer event handling with preventDefault
- Support horizontal scroll in project bar with touch gesture isolation

* feat(mobile): add long-press to remove projects and filter sessions by project

* fix: improve mobile agent switching UX

* fix: move drawer swipe hook to dedicated file

* refactor(mobile): simplify session status bar, remove More/Less toggle button

* fix: git diff navigation on mobile in sidebar mode

* feat(mobile): add configurable status bar and refine mobile chat controls

---------

Co-authored-by: Jovines <jovines@qq.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-02-24 11:44:43 +02:00
Bohdan Triapitsyn d2358c2c03 feat: redesign settings pages to match canonical flat UI patterns (#493)
* refactor(settings): new IA shell + projects section + skills catalog discoverability

* chore(settings): split providers list by scope; show user before project

* fix: navigation flow in mobile Settings

* feat: redesign settings pages to use modern elevated surface patterns

* feat: replace helper text with tooltips in settings

* ui: redesign update dialog and fix external link routing

- Restructures UpdateDialog to focus on changelog readability with a wider max-w-4xl canvas
- Highlights @username contributor mentions with theme primary color
- Strips excessive vertical padding and right-aligns compact action buttons
- Disables streamdown's internal link safety dialog in favor of direct Tauri shell routing

* feat: refactor Git identities into dedicated Git settings page

* feat: unify sidebar background styling across VS Code and web/mobile

* fix: adjust button styling and layout for mobile settings pages

* feat: add MCP settings page and sidebar

* feat: hide models in provider view (thanks to @nguyenngothuong)

* feat: add "Add new provider" option to model selector dropdown

* fix: local evroc logo + provider dropdown icons

* fix: increase width of provider menu

* fix: dark theme background color for better contrast

* feat: update @opencode-ai/sdk dependency to v1.2.10

* fix: restore session sorting to only use updated time

* fix: added settings for sessions deletion dialog

* fix: adjust padding on settings pages for better layout

* fix: standardize select dropdown height across UI

* fix: agent selector UI and notification settings

* fix: remove redundant helper text from settings pages

* fix: update UI layout for description fields

* fix: remove border-none and shadow-none from textarea classes

* fix: enable context menu on sidebar items

* feat: refactor UI controls and layout patterns across settings pages

* fix: use headerless blocks when page title already provides context

* fix: remove subtask option from command settings

* fix: refactor mcp page settings

* fix: reduce spacing in skills configuration pages

* feat: refactor voice settings

* feat: refactor settings sidebar sections
2026-02-24 03:28:30 +02:00
Iuliia Ivashko d2d39c48ac feat(chat): add Mermaid fullscreen preview and harden file preview paths (#490)
* feat(chat): add mermaid preview popups and fullscreen diagram viewer

Enable opening Mermaid diagrams from markdown and file attachments with a dedicated fullscreen dialog, while tightening preview loading behavior and sizing for more reliable interaction.

* refactor(chat): extract shared preview overlay hooks

Centralize fullscreen preview transition and viewport lifecycle logic so image and Mermaid dialogs stay behaviorally aligned while reducing maintenance overhead.

* fix(security): enforce workspace boundaries for fs read endpoints

Validate /api/fs/read and /api/fs/raw paths against active workspace roots and canonical realpaths to block traversal and symlink escapes before serving file contents.

* fix(chat): remove dead Mermaid copy component

Drop an unused merge-leftover component in MarkdownRenderer to keep lint clean without changing Mermaid preview behavior.
2026-02-24 01:49:06 +02:00
Nguyễn Ngô ThượngandBohdan Triapitsyn 3cd6d051cb perf: fix streaming lag, memory leaks, stuck spinners, and proxy timeout (#483)
* perf: fix streaming lag, memory leaks, and proxy timeout

- PERF-001: Batch all streaming parts via requestAnimationFrame instead of
  per-token Zustand set() calls (~100/sec → 1 per frame)
- PERF-002: Fix direct state.sessionMemoryState mutation inside set() callback
- PERF-003: Debounce messageStore→sessionStore subscription via rAF + 500ms
  title computation delay
- PERF-004: Stabilize SSE callbacks with refs to prevent reconnection storms;
  add 5-min stuck session idle timeout
- PERF-005: Bound messageCache (500 max, LRU eviction), cap registry Maps,
  cleanup on session eviction
- PERF-006: Replace toast duration: Infinity with 30s + id-based dedup
- Fix proxy timeout: POST /session/:id/message 45s → 4min (matches CLI)
- Add vitest + jsdom test infrastructure (61 tests across 7 files)

Addresses: #476 (stuck spinner), #358 (34GB memory leak), #190 (browser lag)

* perf: virtualize tool output rendering (read, edit, write)

- PERF-007: Replace per-line <SyntaxHighlighter> with VirtualizedCodeBlock:
  - ONE Prism.highlight() call for entire file instead of N per-line calls
  - @tanstack/react-virtual renders only visible rows (~30 vs 2000+)
  - Applied to: ToolPart (read, DiffPreview, WriteInputPreview) and
    ToolOutputDialog (unified diff, read content)
- PERF-008: Memoize parseReadToolOutput/parseDiffToUnified via useMemo
  to prevent re-parsing on every re-render

A 2000-line file read now mounts ~30 DOM nodes instead of 2000
SyntaxHighlighter instances, eliminating the main-thread blocking
that caused UI freezes during file operations.

* fix: resolve lint errors (unused vars in tests and VirtualizedCodeBlock)

* chore: trim PR scope to core perf fixes

* fix: restore tool-card highlight stability

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-02-23 12:05:53 +02:00
Nguyễn Ngô ThượngandBohdan Triapitsyn 74fa09225a feat(chat): per-session draft persistence + expandable input focus mode (#480)
* feat(session-folders): drag-to-folder DnD, sort by activity, and UX improvements

- Add DraggableSessionRow wrapping each session row so the whole row is
  draggable; stopPropagation prevents outer group-reorder DnD from firing
- Add DroppableFolderWrapper + SessionFolderDndScope (inner DndContext
  scoped per group) with closestCenter collision detection
- DragOverlay matches exact width/height of dragged row so cursor stays
  aligned
- Folder header highlights (ring + primary colour) when a session hovers
  over it during drag
- + button on folder header opens a dropdown: 'New session' / 'New folder'
- + button on each folder row creates a session scoped to that folder
- Empty folders are no longer auto-deleted (removed .filter(sessionIds.length>0)
  from addSessionToFolder / removeSessionFromFolder / cleanupSessions)
- Sessions inside a folder are sorted by most-recent activity (same
  compareSessionsByPinnedAndTime logic used everywhere else)
- Sort comparator now takes sessionAttentionStates so lastUserMessageAt /
  lastStatusChangeAt is used when newer than session.time.updated; all
  sort call-sites and their useMemo/useCallback deps updated accordingly
- Remove foldersMap from cleanup effect deps to prevent cascade re-renders
  when folders change; read current value via getState() instead

* fix(session-folders): new session is placed into the correct folder

sendMessage() was calling useSessionManagementStore.createSession()
directly, bypassing the targetFolderId logic in useSessionStore.createSession.

Fix: read targetFolderId from draft at the top of the draft branch in
sendMessage, then call addSessionToFolder immediately after the session
is created and before the draft is closed. Also propagate targetFolderId
through openNewSessionDraft options and NewSessionDraftState type.

* feat(session-folders): add sub-folder support (one level deep)

- SessionFolder gains optional parentId field for hierarchy
- createFolder accepts parentId to create sub-folders
- deleteFolder cascades to remove all child sub-folders
- SessionFolderItem renders sub-folders before sessions in body;
  new sub-folder button (RiFolderAddLine) visible at depth 0 only
- renderOneFolderItem in SessionSidebar builds the tree recursively;
  sub-folders are indented via depth prop (ml-3 on root's children)
- Persist/hydrate parentId correctly from localStorage

* feat(session): add delete confirm dialogs and improve subtitle UX

- Add confirmation dialogs before deleting sessions or folders
- Show relative time (e.g., '2h ago', '35min ago') for recent sessions
- Replace +/- diff numbers with file change count (e.g., '3 files changed')
- New folders use default name without forcing rename
- Cleaner, less cluttered session list UI

* fix(session-folders): skip folder cleanup while sessions are loading

Prevents race condition on reload where cleanupSessions() runs before
the server returns the full session list, causing folder-session
assignments to be incorrectly wiped from localStorage.

* feat(chat): per-session draft persistence and expandable input focus mode

- Feature 1 (#478): preserve chat draft per session when switching projects
  - Replace global localStorage key with per-session key (draft_${sessionId})
  - Save draft for old session on switch, restore draft for new session
  - Clear draft on submit

- Feature 2 (#479): expandable chat input focus mode (⌘⇧E / Ctrl+Shift+E)
  - Add isExpandedInput state to useUIStore
  - Register expand_input shortcut (mod+shift+e, customizable)
  - Wire shortcut in useKeyboardShortcuts
  - Overlay portal with full-height textarea, Esc to close, auto-close on submit
  - Expand button with tooltip showing keyboard shortcut hint

* fix(chat): switch to in-place desktop focus mode, caret-anchored autocomplete, and no-focus-jump toggle

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-02-23 00:04:25 +02:00
Nguyễn Ngô Thượng 62e5c3edfe fix(notifications): improve agent progress notifications and permission handling (#459)
* fix(notifications): dismiss cross-window permissions, retry countdown, subtask filter
2026-02-21 00:46:15 +02:00
Bohdan Triapitsyn 47cecfc356 refactor: unify clipboard copy flow across desktop/web/vscode runtimes (#458)
* fix: prevent copying incomplete diagnostics report

* refactoring: clipboard writes to unified cross-runtime fallback helper
2026-02-20 14:50:26 +02:00
Bohdan Triapitsyn 22255cf2c0 Fix session/tool-question UX regressions and stabilize streaming activity rendering (#451)
* fix: stale model variants in chat controls in draft session

* fix: attention indicator for project tabs

* fix: use part index and type for consistent IDs

* fix question card navigation for unanswered questions
2026-02-20 01:47:33 +02:00
Iuliia Ivashko 50a66bb6f1 fix(auth): show actionable provider re-auth errors (#450) 2026-02-20 00:34:34 +02:00
Bohdan Triapitsyn 135b2c89be fix: auto-send queue to check session status before sending (#447) 2026-02-19 11:55:42 +02:00
Bohdan Triapitsyn 85f21cb945 feat(chat): align command, shell, and subtask UX (#444)
* feat: reload interface after skills operations

- Adds configurable delay before interface reload after skills changes
- Introduces polling to wait for application health after reload
- Updates UI to show reload message when installing or modifying skills

* feat: distinguish skills from commands in UI

- Displays skill badge for commands that are registered skills
- Prevents editing skills through command management interface
- Triggers interface reload after skill operations to reflect changes

* feat(chat): align command and subtask UX with opencode parity

Route commands/shell via parity paths, render delegated subtasks cleanly, and surface child-session permission/question prompts in parent chat.

* fix(ProjectEditDialog): improve layout consistency

* fix: update task icon and session handling in ToolPart

* feat(chat): add shell-mode input and collapse shell bridge output

Switch leading ! to shell mode UX and fold synthetic shell bridge assistant messages into the user shell bubble with inline output actions.

* fix: remove AI agent icon from file mention autocomplete

* fix: remove unused icon import from file mention component
2026-02-18 20:08:42 +02:00
shekohex 7eba5141fa fix(chat): prevent accidental abort on mobile touch send (#440)
Mobile touch send was firing on pointerdown and then same gesture click landed on stop button after UI switched to abort state. Removed pointerdown-based send/queue handlers and dedupe ref. Mobile send/queue now trigger from click path, avoiding retargeted click to stop.
2026-02-18 11:51:25 +02:00
Bohdan Triapitsyn 4d71bb27eb feat: improve chat streaming UX and add Mermaid diagram rendering (#438)
* feat: show current branch in empty chat state

* fix: display current git branch for worktrees and update them with branch change

* refactor: improve read tool output parsing with structured data

* feat: add support for message part delta events

* fix(chat): improve streaming rendering, scroll behavior, and assistant action visibility

* feat: Add mermaid diagram support to chat markdown rendering

* fix: update table download functionality to include success notification and remove unused MarkdownRenderer import

* refactor: streamline Streamdown component props for improved readability

* fix: preserve Streamdown code-block markers and use native Tauri cache clearing

* feat: add context overview panel to view conversation details
2026-02-17 18:25:03 +02:00
Bohdan Triapitsyn 47c943b487 feat(ui): redesign workspace shell with context panel, tabbed sidebars, and faster diff UX (#433)
* feat: tabbed right sidebar, context panel, floating diff comments

* fix: auto-close left sidebar when context panel opens

- Increase default context panel width from 520 to 600 pixels
- Increase sidebar minimum width from 200 to 300 pixels
- Replace collapsible component with custom button in diff view

* refactoring: rework sidebars, tabs, and file tree layout

- Rewrite AnimatedTabs as segment-style with sliding indicator
- Upgrade SidebarFilesTree to match FilesView features (context menus,
  git status, file icons, CRUD dialogs, fuzzy search ranking)
- Restructure FilesView header: tabs row + actions row, remove breadcrumbs
- Show relative path in context panel header, track active tab
- Allow left sidebar to stay open alongside context panel
- Hide diff/files tabs from header on desktop (mobile-only)
- Move chevron after group name in session sidebar
- Compact tab heights in right sidebar and git view
- Size PreviewToggleButton to match other action buttons
- Remove directory loading spinner from folder icons

* feat: add project icon and color customization

- Enable users to assign custom icons to projects
- Allow users to choose accent colors for projects
- Stabilize repo status UI during project switching

* feat: add scroll fade indicators to editor tabs

* style: reduce spacing and icon sizes in header

* style: adjust tab component padding from uniform to vertical-horizontal

* feat: Add session state indicators to project tabs

* feat: Enhance session status handling and improve UI responsiveness

* fix: preserve upstream tracking on branch rename

* fix: improve initial remote selection for pull requests

- Uses saved remote name from previous session when available
- Selects remote based on tracking branch when possible
- Falls back to origin or first available remote

* perf(diff): faster highlight, stable stacked scroll

- split/unified Pierre worker pools; prefer shiki-wasm
- align diff CSS line-height; disable scroll anchoring; drop WebKit compositing hacks
- harden stacked pin/align (cancel on user scroll/input); prevent overscroll
- make overlay scrollbar MutationObserver optional; disable for diff container

* feat: handle binary files in diff view

* fix: adjust project tabs layout and drag regions

* style: update drag overlay visual styling

* feat: enable number keys to switch projects in the sidebar

* fix: recognize octet-stream as text-based MIME type

* feat: add keyboard navigation to context panel

* feat: add session pinning to sidebar

- Pin important sessions to keep them at the top
- Pinned sessions persist across browser sessions

* refactor: move context usage display from chat input to header
2026-02-16 14:15:19 +02:00
Nelson Pires 08f6bef405 feat(model-cost-info): show compact price and capability icons in ModelControls (#425)
* feat: add compact price display and capability slides in ModelControls

Show compact price text on desktop in ModelControls.
Render slides for price and capability icons in a rotating metadata section.
Rotate metadata only on non-VSCode runtimes.

* feat: prefer capabilities over price in static runtimes for ModelControls
2026-02-14 23:56:08 +02:00
gsxdsm 569cc411c3 refactor: simplify mobile agent button interaction (#416) 2026-02-13 19:20:13 +02:00
Nelson Pires d54f0b92e6 feat: apply rounded corners to mobile session status bar (#412) 2026-02-13 05:32:20 +02:00
Bohdan Triapitsyn 252d4bd5ab refactor: message list optimizations and single messageLimit setting (#409)
* feat: message list refactoring and optimizations

* refactor: collapse 3 memory-limit settings into single messageLimit

- Replace memoryLimitHistorical/Viewport/ActiveSession with one `messageLimit` (default 200)
- Background trim derived automatically (limit * 0.6), not user-facing
- Fix stale historyLimit overriding current messageLimit on session reload
- Remove streaming cap that reduced fetch to VIEWPORT_MESSAGES during active streams
- Deduplicate detectTurns() call in TurnGroupingContext (reuse staticValue.turns)
- Zustand v3 migration: collapse old fields, preserve user-customized values
- Server: sanitize single messageLimit field (10-500)
2026-02-12 20:36:02 +02:00
gsxdsm d94d688112 Fix/Autocorrect On Git And Message Overlap (#401)
* hive(01-add-mobile-autocorrect-to-commit-message-input): Added mobile autocorrect to commit message input.

* hive(02-add-mobile-autocorrect-to-pr-title-inputs): Added mobile autocorrect to PR title inputs in Pul

* hive(03-add-mobile-autocorrect-to-pr-description-textareas): Added mobile autocorrect to PR description textare

* Fix chat last message overlap
2026-02-12 09:54:06 +02:00
gsxdsm b9d2142b1e fix(files): unify context menu trigger on mobile and desktop (#396)
* refactor: use explicit menu button for file row context menu

* fix: ensure model variants are computed from current source only
2026-02-12 09:52:13 +02:00
Bohdan Triapitsyn bc41f727fa fix: search agents by name or description using fuzzy matching 2026-02-12 00:26:55 +02:00
gsxdsm eaf19cc62f fix(chat): fix session return button on mobile. add double-click to switch to chat and auto-focus draft (#384) 2026-02-11 20:08:15 +02:00
Bohdan Triapitsyn 844562749d feat(ui): enable drag-and-drop attachments and image previews in chat (#390)
* feat(BottomTerminalDock): add close button next to the fullscreen toggle in the dock

* style: replace hardcoded gradient with theme value in shine text variant

* fix(header): adapt instance button for desktop only

* refactor(chat): polish sticky turn UX and message action rows for better readability

Switch to stable sticky-only turn behavior and redesign user/assistant action controls (placement, hover rules, ordering, spacing, selection-safe clamp) to reduce visual noise and improve interaction flow.

* feat(chat/message): refactor buttons in messages footer

* feat: enhance image preview functionality in chat messages

- Added a new ImagePreviewDialog component to handle image previews with navigation support.
- Updated ToolOutputDialog to utilize the new ImagePreviewDialog for displaying images.
- Modified the ToolPopupContent type to include a gallery of images and an index for the current image.
- Removed the old inline image display logic from ToolOutputDialog.
- Improved file handling in the file store, including better MIME type guessing and handling of server paths.
- Introduced a new API endpoint for handling large session message payloads, allowing for better management of multi-file attachments.
- Updated the VSCode bridge to support session message requests with appropriate headers and body handling.

* feat(proxy): implement SSE forwarding and enhance generic API request handling

* feat(chat): support submitting only queued messages

* feat: add image preview transition state

* fix: default VSCode view to draft and fixed sessions list regression
2026-02-11 19:28:22 +02:00
Bohdan Triapitsyn 0a47bc058c fix: simplify message loading guards 2026-02-10 01:37:37 +02:00
gsxdsmandBohdan Triapitsyn 1ed5316ac7 feat(voice): add voice input/output support with multiple providers (#281)
* feat(voice): add voice input/output support with multiple providers

- Add BrowserVoiceButton component for Web Speech API voice input
- Add VoiceProvider context for managing voice state across the app
- Add TTS (Text-to-Speech) support with browser, macOS Say, and OpenAI providers
- Add message TTS buttons to read assistant messages aloud
- Add VoiceSettings page in OpenChamber settings
- Add server endpoints for TTS and summarization services
- Include slider component for voice rate/pitch/volume controls
- Add hidden session support for background voice operations
- Add Caddyfile for HTTPS support (required for microphone access)

* fix: Build errors fixed and removed outdated ElevenLabs test code.

* refactor(voice): use zen API with gpt-5-nano for TTS summarization

Replace the hidden session + OpenCode SDK approach with direct calls
to the opencode.ai zen API (same pattern used for commit message and
PR description generation).

- Rewrite summarization-service.js to call zen/v1/responses with gpt-5-nano
- Remove hidden session logic (hiddenSession.ts, sessionStore filtering)
- Remove summarizeModel setting and model selector from VoiceSettings
- Simplify client-side summarize.ts to no longer pass model params
- Clean up callers in useMessageTTS and useBrowserVoice

* fix(voice): remove false 'voice not supported' warning in settings

Mobile Safari does support voice but the isSupported check was
incorrectly flagging it. Remove the warning banner entirely.

* feat(voice): add configurable summary length limit for TTS output

Add a slider (50-2000 chars) in voice settings to control max summary
length. The limit is passed through the summarize endpoint and speak
endpoint to the zen API prompt, with token budget scaled accordingly.

* fix(voice): add diagnostic logging and sanitize TTS fallback

Add console logging throughout the summarization flow (client + server)
to trace why text may not be summarized. Fix silent error swallowing in
/api/tts/speak. Always apply sanitizeForTTS even when summarization is
disabled so raw markdown/code is never spoken verbatim.

* fix(voice): fix token budget starving model of output tokens

max_output_tokens includes both reasoning and output tokens. With
effort:'low', reasoning alone consumes ~128 tokens, so a budget of
100 left zero tokens for the actual summary text. Use a fixed 1000
token budget (matching commit message generation) and control output
length via the prompt's character limit instruction instead.

* chore(voice): remove diagnostic logging from summarization flow

* fix(voice): don't request mic permission on mobile page load

Remove the useEffect that pre-requested microphone permission when the
BrowserVoiceButton component mounted on mobile. This caused an unwanted
permission prompt immediately on page load before the user tapped the
mic icon. Permission is now only requested on explicit user interaction.

* fix(voice): remove unused BrowserVoiceButton binding

* fix(voice): desktop mic flow + non-continuous draft mode

* fix(voice): stabilize continuous loop and polish controls

* feat(settings): mark voice section experimental

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-02-09 23:55:10 +02:00
Bohdan Triapitsyn 5b0a97d170 feat(ui): add desktop git sidebar + terminal dock and improve in-app PR workflow (#362)
* feat: add unified dropdown with services content in header

* feat: add right Git sidebar with resizable panel

* feat: implement responsive panel auto-toggle and terminal rehydration

- Auto-close the right sidebar when width is below a threshold and auto-open it when space permits
- Auto-close the bottom terminal when height is below a threshold and auto-open it when enough space
- Apply a dedicated rehydrated streaming configuration for terminal sessions to optimize reconnect behavior

* feat: enhance PR view with status caching and annotations

* feat(ui): enable chat dispatch in PullRequestSection

* feat(TerminalView): adjust layout

* feat: refine chat input layout and text selection menu

* fix(ui): show empty state in GitView when no changes

* feat(git): update PR actions styling and create PR button
2026-02-09 03:13:34 +02:00
gsxdsm 9534e3d016 Feat: add push to and pull from git with remote selection, along with rebase and merge options (#345)
* Add getRemotes API endpoint

- Add getRemotes() function to git-service.js using simple-git's getRemotes(true)
- Returns array of {name, fetchUrl, pushUrl} for each remote
- Add GET /api/git/remotes endpoint to server/index.js
- Follows existing patterns for git endpoints (directory query param, error handling)

* Add merge and rebase API endpoints

- Add rebase(), abortRebase(), merge(), abortMerge() to git-service.js
- Add POST /api/git/rebase, /api/git/rebase/abort endpoints
- Add POST /api/git/merge, /api/git/merge/abort endpoints
- All functions return { success, conflict?, conflictFiles? }
- Conflict detection via error message parsing and git status

* Add client API functions for git remotes, merge, and rebase

- Added GitRemote, GitMergeResult, GitRebaseResult interfaces to types.ts
- Added getRemotes(), rebase(), abortRebase(), merge(), abortMerge() to gitApiHttp.ts
- Added corresponding exports and runtime wrappers to gitApi.ts
- All functions follow existing patterns with proper error handling
- Lint and type-check pass

* feat(git): add remote selection dropdown to SyncActions

- Add remotes prop to SyncActions component
- Change callbacks to accept GitRemote parameter
- Show dropdown menu when multiple remotes exist
- Execute immediately for single remote repos
- Display remote name and fetch URL in dropdown items

* feat: add BranchIntegrationSection component

- Branch selector dropdown (local + remote branches)
- Merge and Rebase buttons with loading states
- Props: currentBranch, localBranches, remoteBranches, onMerge, onRebase, disabled, isOperating
- Follows existing UI patterns (Command + DropdownMenu)
- Tooltips for all interactive elements

* Add ConflictDialog component for merge/rebase conflicts

- Shows when merge/rebase returns conflict
- Three action options: Resolve in New Session, Abort, Continue Later
- Resolve in New Session opens OpenChamber session in conflict directory
- Displays list of conflicted files
- Uses theme tokens for colors
- Follows existing dialog patterns from AboutDialog.tsx

* Integrate git remote selection and branch operations into GitView

- Fetch remotes on mount and store in state
- Pass remotes to SyncActions and update handleSyncAction to accept GitRemote parameter
- Add BranchIntegrationSection component below sync actions for merge/rebase operations
- Add ConflictDialog to handle merge/rebase conflicts with option to resolve in new session
- Export BranchIntegrationSection and ConflictDialog from git/index.ts
- Update GitHeader to accept remotes prop and pass to SyncActions
- Handle single vs multiple remote scenarios (immediate action vs dropdown)
- Fix React hooks exhaustive-deps warnings by capturing status in local variable

* fix: add missing git API methods to web and vscode packages

* feat: extend VSCode bridge with git remote/rebase/merge endpoints

* feat: add stash support for git operations across UI and API

* hive(01-add-types-for-conflict-details): Added MergeConflictDetails interface to packages/u

* hive(02-add-server-side-conflict-details-function): Added `getConflictDetails(directory)` function to

* hive(03-add-server-endpoint-for-conflict-details): Added GET /api/git/conflict-details endpoint to pa

* hive(04-add-client-side-api-for-conflict-details): Added client-side API for conflict details:

1. **

* hive(05-enhance-conflictdialog-with-rich-context): Enhanced ConflictDialog to fetch and use rich conf

* hive(06-add-state-persistence-for-conflicts): Added state persistence for merge/rebase conflicts

* feat: add conflict details API and AI resolve flow

* fix: improve focus handling in git UI and adjust web dev server port

* feat: add continue merge/rebase support and logs

* fix: address bugs in git merge/rebase feature

- Add explicit parentheses to hasUnresolvedConflicts logic for clarity
- Add error handling for stash operation in handleStashAndRetry
- Fix SSH key path escaping on Windows by normalizing before validation

* fix: add default value for remotes prop to prevent crash

When remotes is undefined, accessing .length throws TypeError.
Add default empty array to handle undefined case gracefully.

* fix: replace DialogFooter with plain div for proper button layout

DialogFooter's default flex-col-reverse and sm:flex-row styles
were conflicting with the intended vertical button stack layout,
causing buttons to not display properly.

* Fix lint erorr

* fix: remove duplicate BranchIntegrationSection and fix broken vscode bridge

- Remove duplicate BranchIntegrationSection from GitView.tsx (already in GitHeader)
- Fix vscode bridge calling non-existent ensureOpenChamberIgnored function
  (legacy worktree function was removed, make api:git/ignore-openchamber a no-op)

* fix: handleResolveWithAIFromBanner now properly detects conflicts from status

The function was checking conflictFiles state which may be empty when
the banner is shown. Now it extracts conflict files directly from the
git status (files with 'U' status) and properly sets up the conflict
dialog state before opening it.
2026-02-07 11:33:17 +02:00
Nelson Pires d0df6ccd71 Fix mobile chat input layout (#344)
* refactor(chat): adjust mobile controls layout

Improve alignment of mobile model and agent buttons with action buttons
Constrain mobile controls to a max width to prevent overflow on small screens

* fix: improve MobileAgentButton mobile interaction

Replace touch-none with touch-pan-x to enable horizontal swipe
Wrap the agent label in a scrollable container to prevent truncation

* fix(ui): allow horizontal scroll for model label

Enable horizontal scrolling for long model labels on mobile
Prevent truncation by letting the label overflow horizontally
Improve visibility by keeping the full label accessible without clipping
2026-02-07 11:30:08 +02:00
d5a2e49ae8 feat(session-status): mobile session quick switch with running/unread indicators (#340)
* feat(session-status): implement server-authoritative session status tracking

- Add server-side session states and attention tracking with Map storage
- Implement SSE event broadcasting (openchamber:session-status)
- Add REST API endpoints for status/attention queries
- Replace client-side polling with HTTP polling + SSE push
- Track needsAttention based on user message + completion + unviewed
- Add MobileSessionStatusBar for mobile UI
- Handle session view/unview/message-sent state transitions
- Add 24h cleanup for old session states

* feat(session-status): add unread indicator to mobile session status bar

* refactor(session-status): extract SessionStatusHeader component

Extract the session status header into a reusable component and improve
layout structure in CollapsedView and ExpandedView.

* feat(session-status): optimize mobile session status bar UI

* refactor(session-status): remove interval polling, use snapshot sync on reconnect/visibility

- unifies session status/attention sync with existing SSE lifecycle, fixes no-op store churn bug, and drops duplicated client activity state while preserving mobile unread/running UX.

---------

Co-authored-by: Jovines <jovines@qq.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-02-07 03:11:55 +02:00
Bohdan Triapitsyn b166d831ce refactor(ui): unify primary agent filtering for mentions and UI (#339) 2026-02-06 15:27:16 +02:00
gsxdsm 2f336a0716 fix: Make thinking/reasoning blocks display consistently and make the show justification setting work. (#332) 2026-02-06 12:30:00 +02:00
gsxdsm af0dc11773 feat: Add ability to navigate through message history with arrows and persist message draft setting (#335)
* feat(chat): add message history navigation in ChatInput

* feat: Adds settng to persist draft of messages to local storage to save work if page refreshes or crashes
2026-02-06 11:14:09 +02:00
Bohdan Triapitsyn d5661f91b9 fix: brought back inline comment drafts in ChatInput 2026-02-05 03:14:26 +02:00
Bohdan Triapitsyn 83ffb1af34 refactor(desktop): make Tauri thin shell running web sidecar (#273)
## What / Why
This PR finishes the desktop refactor: the Tauri app is now a thin shell that launches the web server as a sidecar and loads the UI from `http://127.0.0.1:<port>`. All real backend logic lives in `packages/web/server/index.js`; desktop Rust keeps only native integrations (menu/dialog/notifications/updater/deep-link + window chrome).
This unblocks:
- consistent behavior across web/desktop/vscode (single backend)
- simpler desktop maintenance (no duplicated Rust backend)
- host switching between Local + remote instances in desktop
- reliable cold-start behavior on slow machines (VSCode + desktop)
## Key changes
- Desktop sidecar runtime
  - build pipeline to bundle web dist + `openchamber-server` sidecar (`packages/desktop/scripts/build-sidecar.mjs`)
  - robust local port selection (prefer saved/default, fallback to random; persisted in `~/.config/openchamber/settings.json`)
  - improved PATH handling so the sidecar can locate `opencode` CLI (incl `~/.opencode/bin`, overrides, common bins)
  - disable native right-click context menu in production builds (dev keeps it)
- Desktop instance switcher (Tauri-only)
  - header button + modal to add/edit/delete remote hosts, set default, probe status/ping, switch back to Local escape hatch
  - auth gate includes host switcher so you can recover when a remote host is broken/auth-required
  - host list stored desktop-locally (not tied to the currently selected remote server)
- Notifications
  - decision logic moved server-side; desktop notifications emitted via sidecar stdout and shown natively by Tauri
  - prevent double-notifications on desktop Local origin (UI ignores SSE notification when native path is active)
  - restore macOS notification sound
- Updates
  - Tauri updater used only when viewing Local instance in desktop shell (avoid “remote web update” triggering desktop restart)
- Settings persistence & UX polish
  - persist model favorites/recents via `/api/config/settings` (works for web + desktop; not origin-dependent)
  - persist per-project sidebar collapse state in `projects[].sidebarCollapsed` via `/api/config/settings` (with debounce on toggles)
  - macOS header sizing/traffic-lights offsets fixed (marketing macOS major injected from desktop; MultiRun header aligned)
  - VSCode cold-start: keep retrying provider/agent loads after connection to avoid empty UI on slow machines
  - misc lint/type fixes + bun.lock sync
- Desktop bootstrap / resiliency
  - show onboarding screen when OpenCode CLI is missing (desktop Local origin), with retry hook to restart OpenCode after install
## Testing notes
- Desktop (macOS): switch Local <-> remote, set default host, verify auth gate recovery, native notifications (with sound), updater gated to Local
- Web: favorites/recents + per-project collapsed state persist across reload/restart
- VSCode: slow startup no longer results in missing providers/agents/models
2026-02-05 01:59:49 +02:00
JovinesandJovines b733f26aed feat(mobile): split controls into separate Agent and Model buttons (#293)
* feat(mobile): split controls into separate Agent and Model buttons

- Add MobileAgentButton with tap-to-cycle and long-press-to-open behavior
- Add MobileModelButton for direct model panel access
- Remove agent selection from UnifiedControlsDrawer for cleaner mobile UX
- Agent cycling accessible via Tab key shortcut

* fix(mobile): optimize controls layout and touch handling

---------

Co-authored-by: Jovines <jovines@qq.com>
2026-02-04 18:07:24 +02:00
gsxdsm ea0deec14d Feat/mobile quick actions (#282)
* feat(mobile): add quick actions button and improve mobile UX

Add mobile-optimized quick action buttons and improve autocomplete UX.

- Add quick command button (/) in mobile chat footer
- Add tabbed autocomplete interface for Commands/Agents/Files
- Fix agent selector conflict with model selector
- Improve TerminalViewport Android IME support
- Add reusable Slider component for settings
- Update StatusChip styling for mobile layout

Files changed:
- ChatInput.tsx: Mobile quick actions, command menu, autocomplete tabs
- AgentMentionAutocomplete.tsx: Tab support for mobile
- CommandAutocomplete.tsx: Tab support and touch handling
- FileMentionAutocomplete.tsx: Tab support for mobile
- ModelControls.tsx: Agent selector fix
- StatusChip.tsx: Mobile layout improvements
- TerminalViewport.tsx: Android IME improvements
- ui/slider.tsx: New reusable slider component

* feat(chat): remove unused BrowserVoiceButton component from ChatInput

* fix: Resolve linter errors
2026-02-04 11:14:10 +02:00
gsxdsm 66da4ad8f4 feat(text-selection): add text selection menu with quick actions (#283)
Add TextSelectionMenu component that appears when selecting text in messages.
Provides quick actions: Add to chat, New session, Copy.

- Add TextSelectionMenu.tsx component with desktop and mobile layouts
- Integrate menu into MessageBody with message-content-text ref
- Add mobile CSS for text selection behavior
2026-02-04 11:13:49 +02:00
Nelson Pires c119d89084 Introduce inline comment in plan and diff panel (#277)
* feat(chat): support inline comment drafts in chat input

Add per-session inline comment draft tracking
Append inline drafts to outgoing messages when queuing
Consume drafts after sending to clear state

* feat: add actions menu to PierreDiffViewer

Add a dropdown actions menu in the diff viewer with More and Delete options
Enable inline comment drafting support and selection synchronization to prevent loops
Replace previous action icon with contextual actions in the header

* feat(plan): enable inline comment drafting in PlanView

Add inline comment draft support with addDraft, removeDraft and drafts state
Compute session key for drafts based on currentSessionId and draft state
Prepare dropdown and toast utilities for draft actions in PlanView

* feat: add inline comment formatting utilities

Introduce formatInlineCommentDraft to render inline comments for diff and plan views
Add appendInlineComments to attach comments to existing messages with proper separation
Provide hasInlineComments to detect inline comment blocks in text

* feat: add inline comment draft store

Persist drafts per session key for inline comments
Add, remove, and clear drafts with unique IDs per session
Consume drafts to move them out of store after submission
2026-02-03 20:05:01 +02:00
Bohdan Triapitsyn d846f039e6 chat: redesign chat input stop/send buttons
- stop button replaces send button in footer instead of overlay
- floating queue button above stop when input has content
- buttons same size, stop icon larger for emphasis
2026-02-01 22:43:46 +02:00
Bohdan Triapitsyn ddedc02687 feat: introduced a token-based theming system across the UI
* feat: added themes system

* feat: smart sidebar auto-hide for files/diff tabs + lower files sidebar threshold

* feat: added Checkbox component and update theming

- Add reusable Checkbox component for toggles across UI
- Replace several inputs with Checkbox in settings and commands panels
- Add DiffIcon and apply surface/border theming to key UI areas

* feat: Add convert-vscode-theme.cjs to convert VS Code themes to OpenChamber format

* refactor: remove unused permission logic from ChatInput

- Remove unused permission rules parsing logic from ChatInput
- Memoize renderTheme in DiffWorkerProvider to avoid unnecessary recalculations
- Remove forceOpaque helper in vscode theme adapter

* fix: guard VSCode theme loading in MarkdownRenderer

* feat: add custom user themes loading and reload

- Load user themes from ~/.config/openchamber/themes at runtime
- Expose /api/config/themes to fetch custom themes
- Allow theme reloading from Settings → Theme → Reload themes in the UI
2026-02-01 18:29:34 +02:00
Bohdan Triapitsyn 344f369093 Refactor chat UI controls and overlays for mobile adjustments (#248)
* feat(mobile): refine status chip and control layouts

* fix(vscode): open file from apply_patch tool in editor
2026-01-30 13:23:50 +02:00
Nelson Pires 2ed1a73d3c Add new mobile chat controls (#247)
* chore: upgrade @opencode-ai/sdk to 1.1.40

* chore(ui): bump @opencode-ai/sdk to 1.1.40

* feat(chat): add mobile controls drawer and panel switching

Add mobile-only controls drawer with open/close and panel switching
Introduce state and handlers for mobile controls and panels
Reset mobile UI state when switching to non-mobile or returning to unified controls

* feat: add mobile chat controls utilities

Add utilities to compute and display the selected agent and model names in mobile chat controls.
Add effort variant formatting, serialization, parsing, and ranking helpers for quick options.
Expose helpers to build quick effort option lists for the UI

* feat(ModelControls): allow external mobile panel control

Initialize mobile panel state from external props when provided
Fall back to internal mobile panel state when external control is absent
Notify parent on panel changes via onMobilePanelChange callback

* feat(chat): add StatusChip component

Add StatusChip button that displays agent, model, and effort
Show marquee animation when the label is truncated
Bind to config and session stores to reflect current context

* feat: add UnifiedControlsDrawer chat controls

Add a side panel to switch agent, model, and effort quickly
Show recent agents and models for faster reselect
Persist agent/model/variant selections in session

* fix(openchamber): correct base64 to Uint8Array typing

* feat: add reduced-motion support for marquee animations

Add marquee-text--auto to enable continuous scrolling
Introduce prefers-reduced-motion media query to disable animations
Apply reduced-motion rules to active marquee and hover states

* feat[worktrees]: enhance sdk worktree removal with fallbacks

Add dynamic resolution of remove/delete/archive methods for worktrees
Fallback to delete or archive when remove is not available
Throw clear error when SDK version does not support worktree removal

* feat(ui): track recent agents and efforts in UI store

Add recentAgents array to UI state for quick access
Track up to 5 variants per provider/model in recentEfforts
Expose addRecentAgent and addRecentEffort actions to update history

* fix(deps): upgrade @opencode-ai/sdk to 1.1.42

Upgrade the OpenCode AI SDK to 1.1.42 across packages
Refresh lockfile entries to reflect the new SDK version and integrity hash
Ensure downstream packages consume the latest SDK and remain compatible

* refactor: simplify agent overflow logic in UnifiedControlsDrawer
2026-01-30 11:13:37 +02:00
Bohdan Triapitsyn 2d305d18c6 feat(desktop): enable macOS version awareness for UI adjustments
- Fetch macOS major version from Rust to determine layout
- Adjust header padding and height for macOS versions
2026-01-30 02:46:43 +02:00
Bohdan Triapitsyn 520dd8c900 style: update section model selection headers to micro typography with uppercase and sticky behavior 2026-01-29 23:34:28 +02:00
Iuliia Ivashko 2acb7ef0d0 fix: control elements padding in chatbox 2026-01-29 22:27:26 +02:00
Bohdan Triapitsyn c5158ff52c Chat input updates with Stop button and update dialog changelog UI (#241)
* feat: re-organizaed input footer UI in chat

Add StopIcon component and use it for aborting generation in chat controls
Introduce ProviderLogoOrFallback to show provider logo or fallback icon in model controls
Remove mobile-only abort button in StatusRow and simplify abort handling

* feat: improved render of changelog in UpdateDialog
2026-01-29 18:23:43 +02:00
Bohdan Triapitsyn b861e4abf1 feat: introduce useEffectiveDirectory hook and adopt across views (#226)
Add a centralized useEffectiveDirectory hook to resolve the active directory
Use the hook across DiffView, FilesView, GitView, and TerminalView
Fix list styling by rendering ul/ol bullets outside
2026-01-27 11:57:56 +02:00