Commit Graph
125 Commits
Author SHA1 Message Date
Bohdan Triapitsyn 3afe0bb45d fix(desktop): respect local-origin tauri shell for directory access (#391)
* feat: enable local-origin desktop features and copy in terminal support

- Enable arbitrary web loads in desktop web content for TAURI apps.
- Guard directory dialog access behind local-origin origin check.
- Add copy-to-clipboard support for terminal selections via common shortcuts.

* fix: improve initial directory resolution and persistence in directory store
2026-02-11 20:07:44 +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 d801ba0abe feat(useConfigStore): disable TTS buttons by default until user change this 2026-02-10 13:00:16 +02:00
Bohdan Triapitsyn f91d048a2b fix(useConfigStore): align voiceModeEnabled with localStorage 2026-02-10 01:43:25 +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 75c548f2d5 refactor(ui): improve path normalization in FilesView 2026-02-09 11:50:21 +02:00
gsxdsmandBohdan Triapitsyn fbf0ec50ee feat: Improve notifications with templates, summarization, and more (#317)
* feat: Successfully added new notification settings to Zustand

* feat: Successfully implemented the Events subsection

* feat: Successfully wired new notification settings

* feat: Added notification template editor section to Notifications

* feat: Added server-side template resolution and summarize

* feat: Improve notifications with templates, summarization, and more

* fix: session not populated in messages

* fix notification template first-run defaults

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-02-09 03:58:29 +02:00
Nelson Pires baad4b6097 Enhance FilesView with breadcrumbs, drafts, and editor UX (#363)
* feat: enable search panel in CodeMirrorEditor

Add enableSearch and searchOpen props to toggle search UI
Wire CodeMirror search extension and keybindings into the editor
Automatically open or close the search panel based on searchOpen

* feat(files): add breadcrumb navigation and inline comments

Add breadcrumb trail derived from file path and root to navigate directories
Introduce inline comment UI with draft storage for per-file discussions
Enable long-press gestures on items to reveal quick actions

* feat: add useLongPress hook for long-press gestures

Provide a reusable long-press hook with onLongPress and onTap callbacks.
Support pointer and touch events with movement threshold to cancel.
Optionally vibrate on long press for haptic feedback.

* feat: add expandedPaths state and expand actions for file tabs

Introduce expandedPaths per root to remember expanded folders
Add actions to toggle, expand a path, and expand multiple paths
Initialize expandedPaths for new roots and clamp state to valid roots

* feat: add onSearchOpenChange prop to CodeMirrorEditor

Expose onSearchOpenChange callback prop for search state
Notify parent when search panel visibility toggles
2026-02-09 03:24:25 +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
Nelson Pires 7af81c2436 Add per-model quotas with collapsible model groups in header (#355)
* feat(ui): show per-model quota groups in header with collapsible families

Add per-model quota groups under each provider in the header
Introduce collapsible sections for model families to reveal models
Show all models when none are explicitly selected or respect explicit selections

* feat: add toggle to UsageCard for dropdown visibility

Introduce a switch in UsageCard to control inclusion in the dropdown
Hide the percent label when the toggle is visible

* feat(usage): enhance UsagePage with model grouping and collapsibles

Add model lists grouped by family for the selected provider
Enable collapsible sections per family to toggle visibility
Apply and persist default model selections on provider change

* feat(quota): add model family helpers

Add utilities to categorize models into families by provider
Enable grouping of models by family for header and usage pages
Define default models for Gemini 3.x and Claude families

* feat(desktop): extend settings with model grouping and selection

Track per-provider selected models for usage
Allow collapsing and expanding families in the usage page
Support per-provider custom model groups with labels and assignments

* feat: persist usage preferences in persistence

Persist usageSelectedModels per provider
Persist usageCollapsedFamilies and usageExpandedFamilies states
Support custom usageModelGroups with groups and assignments

* feat: track selected quota models and expanded families per provider

Initialize selectedModels and expandedFamilies state for quota providers
Add actions to set, toggle, and apply default model selections and expanded families
Persist selections to desktop settings and apply defaults on load

* feat(server): sanitize usage model configuration in settings update

Validate and sanitize usage selections per provider
Persist only valid usageCollapsedFamilies and usageExpandedFamilies in settings
Enforce limits on custom model groups and model assignments

* feat: add collapsible model families in header

Add collapsible sections for model families within each provider in the header
Show per-model usage with percent display and a progress bar
Toggle expansion via arrow icons and preserve expanded state per provider

* fix(ui): treat explicit per-provider model selections correctly in header

Enable showing all models by default when a provider has no explicit selection
Recognize an explicit per-provider selection when a provider key exists in selectedModels
Filter to selected models only if an explicit selection is present for the provider
2026-02-08 15:42:15 +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
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 0503f51357 refactor: simplify worktree management by removing legacy API
- Remove legacy worktree API usage and related state
- Add Manage Branches button in the Git header for quick access
- Introduce worktree status utilities to derive root branch hints
2026-02-06 12:38:09 +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
Nelson Pires 16d7a1820b Add edit comment in plan and diff panel (#328)
* feat: add view ready and destroy callbacks to CodeMirrorEditor

Provide onViewReady callback that receives the EditorView once created
Provide onViewDestroy callback invoked when the editor is destroyed

* feat: render inline drafts in PlanView with portal

Add editorView state to track the active CodeMirror instance
Render inline drafts through a portal anchored to the editor scroll container
Position drafts relative to the corresponding start line in the editor

* feat(PierreDiffViewer): enable editing inline diff drafts

Enable editing of existing inline diff drafts with draftID handling
Auto-focus comment input when opening editor and place cursor at end

* feat: enable editing inline drafts and auto focus

Enable editing of existing inline drafts via new editingDraftId state and updateDraft
Auto focus the comment input and place cursor at end when a line is selected
Add edit action button in the inline actions bar to start editing

* feat: add updateDraft to inline comment drafts store

Add updateDraft action to modify a specific draft by session and id
Merge updates into the target draft without altering other fields
Retains existing draft management actions like remove and clear
2026-02-06 02:51:03 +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
shekohex def6257985 feat(settings): add terminal font size controls (#294)
* feat(settings): add terminal font size configuration

* chore(desktop): drop terminal font size setting
2026-02-04 16:32:25 +02:00
gsxdsm a264393f1b feat: extend quota providers and add usage dropdown (#254) (#284)
* feat: extend quota providers and add usage dropdown

Add new quota providers:
- Claude (Anthropic API)
- Codex (OpenAI/ChatGPT)
- GitHub Copilot (base + add-on)
- Kimi for Coding
- OpenRouter

UI enhancements:
- Add rate limits dropdown in header with timer icon
- Desktop: sticky header with Used/Remaining toggle, refresh button
- Mobile: full-screen dropdown with same controls
- Per-provider sticky headers with provider logos
- Auto-refresh on open if no data exists

Usage settings page:
- Provider icon next to header
- Show in dropdown toggle per provider
- Global display selector (Usage vs Quota remaining)
- Auto-refresh controls in sidebar

Settings persistence:
- Add usageDisplayMode and usageDropdownProviders settings
- Server-side sanitization for new settings

Provider logo aliases:
- codex -> openai, claude -> anthropic

Bug fixes:
- Fix React error #310 by calling hooks before early returns
- Add aria-describedby to SettingsWindow dialog
- Remove horizontal scroll from dropdown

* fix: Remove duplicate github copilot declarations
2026-02-04 11:13:23 +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 df1858b424 fix(ui): stop persisting settings dialog state 2026-02-02 00:18:12 +02:00
Bohdan Triapitsyn b441d27e99 feat(files-view): add per-root open file tabs store
- Add per-root tab state to track open files and current selection
- Derive open file nodes for the active root and trim root paths
2026-02-01 21:43:49 +02:00
Bohdan Triapitsyn 3e145bdbd6 feat: added terminal tabs and resilient session storage (#265)
- Add per-directory tabbed terminal UI with separate buffers
- Persist and restore active tab per directory across sessions
- Fallback to in-memory storage when sessionStorage is unavailable
2026-02-01 19:28:05 +02:00
Nelson Pires 0981194eed feat: Multi-provider Usage Dashboard & Quota Monitoring (#259)
* feat(openchamber): persist usage auto-refresh settings

Enable a switch to toggle automatic usage refresh
Provide input to configure refresh interval in milliseconds
Persist changes to desktop settings and server API when changed

* feat: add UsageCard component

Add a new UsageCard component to display a usage window with title, optional subtitle, and a progress bar
Show current usage percentage and a reset time label for the window
Render a formatted window label and a compact subtitle for concise UI

* feat(usage): add UsagePage UI for quota usage

Add a dedicated UsagePage with provider-based usage details
Show last updated time and auto-refresh status
Handle empty, not configured, and error states with informative banners

* feat(usage): add UsageProgressBar component

Introduce a new UsageProgressBar component to visualize quota usage
Display a gradient fill that changes with critical, warn, or normal tones
Expose accessible progress attributes for screen readers

* feat(usage): add UsageSidebar component

Display quotas for all providers in a scrollable sidebar
Refresh quotas with a button and loading indicator
Colorize provider rows based on usage status and runtime context

* feat: add usage section to Settings

Add a new Usage item to the Settings sidebar for desktop and mobile
Render UsagePage when the Usage tab is selected in Settings
Wire up new UsageSidebar and UsagePage components under usage

* feat: add Usage section to sidebar

Add new Usage section in the sidebar for API quota monitoring.
Display a bar chart icon and description for the Usage item.
Monitor and display API quota usage across providers.

* feat(desktop): add usage auto-refresh settings

Enable automatic refresh for usage data with new settings
Store refresh interval in milliseconds for usage updates

* feat(persistence): support usageAutoRefresh and usageRefreshIntervalMs

Persist usageAutoRefresh in desktop settings
Persist usageRefreshIntervalMs in desktop settings
Validate types for new fields during sanitizeWebSettings

* feat(quota): export providers and utilities

Expose QUOTA_PROVIDERS and QUOTA_PROVIDER_MAP for consumers
Export QuotaProviderMeta type for user code
Make formatting and usage resolution utilities available from quota module

* feat(quota): define base quota provider interface

Define QuotaProvider interface with id, name, isConfigured, and fetchQuota
Expose ProviderResult type in fetchQuota contract

* feat: add quota providers index and map

Expose QUOTA_PROVIDERS with OpenAI, Google and z.ai
Provide QUOTA_PROVIDER_MAP for quick provider lookup by id

* feat: add quota utils for percent formatting and tone

Add clampPercent to sanitize and clamp numbers to 0-100
Add formatPercent to render '-' for null and 'x%' for values
Add resolveUsageTone to categorize percent as safe, warn, or critical

* feat: add useQuotaStore for quota data

Load usage settings from desktop, VSCode, or API at startup
Fetch quotas for all providers in parallel and update loading state
Expose lastUpdated timestamp and error state for UI feedback

* feat: export quota types from quota module

Expose quota-related types in UI type definitions
Allow downstream code to import QuotaProviderId and related types
Aggregate quota exports under the quota module in index

* feat: add quota types for usage providers

Add QuotaProviderId and UsageWindow shapes to model quota data
Add ProviderUsage, ProviderResult, and related usage mapping for providers

* feat: add quota provider endpoints API

List available quota providers via GET /api/quota/providers
Retrieve quota details for a specific provider with GET /api/quota/:providerId
Log errors and return 500 with error message on quota fetch failures

* feat: add quota providers discovery and formatting

Detect configured quota providers from auth and account files
Normalize auth entries to tokens or objects for API usage
Expose formatted reset times and remaining window metrics

* feat: persist usage settings in UsageSidebar and remove from defaults

Load usage settings on mount for the sidebar
Persist changes to auto-refresh and refresh interval to server
Remove usage settings state and effects from DefaultsSettings

* fix(usage): guard auto-select in UsagePage when results empty

Guard auto-select in UsagePage when results are empty
Prevent unexpected provider selection on initial render

* fix(quota): set error state during quota updates

Reset error to null when a new quota result is added
Set error to the error message on fetch failure or fallback
Keep error state alongside results in all update paths
2026-02-01 18:30:30 +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 f752e2d644 fix(worktree): normalize paths and improve worktree deletion workflow 2026-01-30 15:40:01 +02:00
Bohdan Triapitsyn b74ac777f5 Add terminal quick keys option and desktop toggle (#249)
* feat: add terminal quick keys toggle in OpenChamber UI

* feat: enhance mobile input handling in Terminal for Android devices
2026-01-30 14:48:53 +02:00
JovinesandJovines de468361ec feat: add notifyOnSubtasks setting to control subtask notifications (#227)
* feat: add notifyOnSubtasks setting to control subtask notifications

- Add notifyOnSubtasks toggle in NotificationSettings (moved to general section)
- Update useEventStream.ts to skip notifications for subtasks when disabled
- Add server-side push notification control for subtasks
- Update UI store, persistence, and desktop settings types

* feat: apply notifyOnSubtasks across web push + desktop notifications

---------

Co-authored-by: Jovines <jovines@qq.com>
2026-01-30 14:15:00 +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
Iuliia Ivashko dd6d78b0db fix(worktrees): default to HEAD when no startPoint provided
- Use git reset --hard HEAD by default when startPoint is not provided or is HEAD
- Preserve resetting to the provided startPoint when a concrete value is supplied
2026-01-29 21:34:24 +02:00
Bohdan Triapitsyn bc28fa9ac8 refactor(chat): replace message sync with soft resync scheduling
Remove useMessageSync hook from App initialization
Introduce scheduleSoftResync to respect cooldowns before resyncs
Preserve hasMoreAbove handling and totalAvailableMessages for loading older messages
2026-01-29 01:12:00 +02:00
Bohdan Triapitsyn 91e8b9e1f5 fix(ui): prevent memory leak in diff view with many modified files
- Add LRU eviction to diffCache (max 30 entries / 20MB)
- Single-file mode: render only selected diff, not all hidden ones
- Stacked mode: collapse files beyond first 10 by default
- Limit DiffWorkerProvider warmup to 10 files
- Reduce worker pool size (4 to 2) and AST cache (200 to 50)
2026-01-28 12:29:01 +02:00
Bohdan Triapitsyn 84e9391871 feat: add integrate commits to parental branch section and wired UI
Introduce IntegrateCommitsSection to plan and apply commits from source to target branch
Wire the integration panel into GitView so users can run integrate flow from the current worktree
2026-01-28 02:10:40 +02:00
Bohdan Triapitsyn 415b043326 feat: migrate to OpenCode SDK worktrees with per-project config
Add SDK-based worktree management that lists and starts SDK worktrees
Migrate per-project setup to ~/.config/openchamber/<projectId>.json
Deprecate .openchamber legacy paths and adapt UI to new config
2026-01-27 20:00:07 +02:00
Bohdan Triapitsyn 25525d5b1b feat: enhance ClawdHub integration with paging and retry
Add paging support when loading ClawdHub skills
Retry on API errors and throttle for ClawdHub requests
Load source content on source change and show loading indicators
2026-01-26 19:50:11 +02:00
Bohdan Triapitsyn a9952fd8da Refactor permission management across UI components and stores (#221)
* refactor: normalize permission rules and improve command draft handling

Add normalized rule set construction for permissions in Agents pages
Track initial command draft state to detect unsaved changes
Prefill draft fields when duplicating or selecting existing commands

* feat: add global session-level edit mode for agent permissions
2026-01-26 16:09:46 +02:00
Bohdan Triapitsyn 74511abfda Multi-account GitHub auth + UI polish (model logos, markdown, scroll behavior) (#219)
* feat: display provider logos for favorite/recent models

Show provider logo next to model name in favorites and recents
Render provider logos in ModelControls, ModelMultiSelect, and ModelSelector lists
Maintain zero-logo state for other sections to avoid clutter

* feat: render user message as markdown instead of plain text

Render agent mentions as markdown links in user text
Apply inside list style for chat content to fix list rendering
Rely on SimpleMarkdownRenderer for consistent rendering

* fix(openchamber): adjust layout and overscroll behavior

Enable overscroll-auto on overlay containers for smoother scrolling
Move page content to full-width wrapper and preserve section borders
Show AboutSettings inside its own bordered block when visible

* feat: integrate GitHub auth status store and UI

Introduce GitHubAuthStore to track connection status and polling
Show GitHub avatar in header when connected
Guard issue/pr dialogs behind GitHub auth status and show notices

* feat: add GitHub multi-account support

Add API and UI flow to activate a GitHub account
Show and switch between multiple GitHub accounts in header
Persist and normalize accounts list with current selection
2026-01-26 11:28:55 +02:00
Bohdan Triapitsyn efe9ad27b7 feat: add text truncation hook and marquee support (#217)
Introduce a hook to detect text truncation for dynamic UI updates
Replace static marquee spans with a reusable marquee component in files and labels
Enable copying of terminal selection on mouse up and touch end
2026-01-26 00:24:40 +02:00
杨巅峰andiiyangdianfeng adbc5af95f feat(ui): add configurable text justification activity setting (#212)
* fix(server): improve external server and error handling

- Skip OpenCode shutdown when using external server
  (OPENCODE_SKIP_START=true)
- Return 404 status for non-existent directories instead of
  empty array
- Move error logging before response handling

* feat(ui): add configurable text justification activity setting

- Replace hardcoded ENABLE_TEXT_JUSTIFICATION_ACTIVITY constant with
  dynamic showTextJustificationActivity setting in useUIStore
- Add toggle UI in Chat settings section (Settings > Chat)
- Add setting to DesktopSettings type for cross-runtime persistence
- Default value is false (matching original constant behavior)

---------

Co-authored-by: iiyangdianfeng <goodydfwow@gmail.com>
2026-01-25 19:09:31 +02:00
Bohdan Triapitsyn f4da45a8ad Add plan mode and plan view with per-session agent context (#210)
* feat: add plan/build mode switching and Plan view tab

Add PlanView view and integrate plan tab into main layout
Introduce plan_enter and plan_exit tools with icons and status strings
Persist per-session agent selections in context to reduce UI flicker during mode switches

* feat: enchanced plan discovery checks in header and plan view

* fix(ui): align PlanView and Header with sessionDirectory logic

Remove dependency on context store in header and compute sessionDirectory from session or currentDirectory
Compute display and repo paths using sessionDirectory for PlanView and update path resolution
Poll plan content every 3 seconds to reflect changes without heavy retries

* feat(ui): improve header tab switching and add copy buttons for plan

Switch header tab navigation to central UI store and auto-switch when plan is unavailable
Show checkmark icon after copying file contents or path with auto-hide timeout
Extend plan view path resolution to prefer session directory when present
2026-01-25 15:52:02 +02:00
Bohdan Triapitsyn 0e11ea3f83 feat: extend PR context to include check details
Add check details to PR context via includeCheckDetails flag
Open a checks dialog showing check run summaries and steps
Improve PR lookup for forked repos by matching head branch
2026-01-24 17:59:08 +02:00
syntextandBohdan Triapitsyn 2de0d9d3dd feat: allow control over displaying hidden/dotfiles and .gitignore matches (#179)
* feat: add chat setting to toggle hidden files (dotfiles)

* feat: add toggle to show/hide gitignored files in file browser

* refactor: don't reuse visibility setting for dotfiles toggle

* fix: honor hidden/gitignored toggles across runtimes

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-01-20 15:20:17 +02:00
Bohdan Triapitsyn 6544b12e78 refactor: streamline chat scroll manager
- Removed unused activeTurnAnchorId and activeTurnSpacerHeight from MemoryDebugPanel.
- Simplified useChatScrollManager by eliminating unnecessary state and functions related to active turn anchoring.
- Updated loadMessages function signatures to accept an optional limit parameter across message and session stores.
- Enhanced scroll behavior in useScrollEngine to support dynamic bottom tracking during animations.
- Improved event stream handling to allow for resyncing messages with a specified limit.
- Cleaned up session memory state to remove active turn properties, focusing on viewport anchoring.
2026-01-20 03:23:39 +02:00
Bohdan Triapitsyn 2743349b5e feat: add memory limits UI settings for messages in session 2026-01-19 14:56:27 +02:00
Bohdan Triapitsyn f59c7b2525 fix: skip trimming for active sessions to preserve anchor 2026-01-19 14:04:23 +02:00
Bohdan Triapitsyn 494da1315c refactoring: switched to gpt-5-nano for commit message generation
Remove commitMessageModel from persisted settings and defaults
Eliminate UI controls and state for commitMessageModel in GitSettings and config store
Update backend and persistence layers to stop reading or writing commitMessageModel
2026-01-19 03:42:34 +02:00
Bohdan Triapitsyn 85f41c39c1 refactor(chat): enhance scroll management (#174)
- Add bottom detection with epsilon tolerance for precise positioning
- Introduce pending anchor restoration for seamless session switching
Include active turn anchor and spacer height in message store
2026-01-18 18:00:19 +02:00
Bohdan Triapitsyn 24969ba856 feat: implement file editing capabilities with CodeMirror integration
- Added CodeMirror editor for file content editing in FilesView.
- Introduced draft saving functionality with unsaved changes confirmation dialog.
- Implemented file writing API to persist changes to the filesystem.
- Enhanced language support for syntax highlighting based on file extensions.
- Updated UI components to support new editing features, including save and discard options.
- Refactored line selection logic for improved user experience on both desktop and mobile.
- Added new utility functions for language detection by file extension.
- Introduced a new theme for CodeMirror to align with the application's design.
2026-01-18 17:29:31 +02:00
Ashik Ahmed 934df2b7e6 perf: stability and performance improvements with some minor UI issues resolved (#172)
* Stability and performance improvements. (#1)

## Changelog

### Performance Improvements

- **perf: make terminal creation cwd check async (#9)**  
  Replaced synchronous `fs.existsSync` with `fs.promises.access` in the terminal creation handler to prevent blocking the event loop.  
  Improves throughput under high load.

- **perf: optimize fuzzyMatchScore by avoiding redundant lowercasing (#8)**  
  Renamed `fuzzyMatchScore` to `fuzzyMatchScoreNormalized` and updated it to accept a pre-lowercased query, avoiding repeated string allocations.  
  Updated the call site in `searchFilesystemFiles`.  
  ~25% search performance improvement on large datasets.

- **perf: use async file read in update-install handler (#7)**  
  Replaced `fs.readFileSync` with `await fs.promises.readFile` to avoid blocking the event loop.  

  **Benchmark (10k ops):**
  - Sync: ~95ms (blocking)  
  - Async: ~1124ms (non-blocking)  

  Higher per-call overhead, but better server responsiveness.

- **perf(server): optimize mkdir endpoint with async fs (#6)**  
  Replaced `fs.mkdirSync` with `await fsPromises.mkdir` in `/api/fs/mkdir`.  
  Prevents event-loop blocking and improves concurrent performance.  

  **Result:** ~2× throughput improvement (100 concurrent requests).

- **perf: parallelize fs checks in validateProjectEntries (#4)**  
  Replaced serial `for...of` with `Promise.all + map`.  
  Reduced validation time for 500 projects from ~110ms to ~20ms (~5× speedup).

- **perf: cache getLoginShellPath result to avoid blocking event loop (#5)**  
  Cached `getLoginShellPath` result to avoid repeated `spawnSync` calls (~400ms each).  
  Subsequent calls reduced to <1ms.

---

### Server Fixes

- **fix(server): use async check for terminal restart endpoint (#3)**  
  Replaced `fs.existsSync` with `fs.promises.stat` in `/api/terminal/:sessionId/restart`.  
  Added directory validation for better robustness.

---

### UI & Accessibility

- **feat(ui): add aria-labels to git identities sidebar buttons (#1)**  
  - Added `aria-label="Create new profile"` to the create button  
  - Added `aria-label="Profile actions"` to the dropdown trigger  
  - Added `.Jules/palette.md` for UX/a11y learnings

---

### UI Performance (Bolt)

- ** Bolt: Optimize MessageList re-renders by preserving referential equality (#2)**
- ** Bolt: Optimize MessageList re-renders by preserving referential equality (#11)**
- ** Bolt: Optimize MessageList re-renders by preserving referential equality (#12)**

* stability and improvements (#17)

* feat: add corner radius setting and update snackbar actions

- Add `cornerRadius` to UI store and settings.
- Add Corner Radius slider to Visual Settings section.
- Apply corner radius to ChatInput component.
- Remove default close button from Snackbar (Sonner).
- Add "OK" action button to session deletion toasts.
- Ensure `cornerRadius` setting is visible in OpenChamberPage.

* fix(ui): add missing aria-label to radius slider and verify functionality

- Added `aria-label="Corner radius in pixels"` to the desktop version of the corner radius slider for accessibility.
- Verified functionality and accessibility compliance via script.

* fix(ui): restore input bar offset setting on desktop

- Restored the Input Bar Offset setting to be visible on desktop, not just mobile.
- Verified both Corner Radius and Input Bar Offset sliders are accessible.

* Fix mobile layout for chat input controls (#16)

* Fix mobile layout for chat input controls

- Reduced horizontal gaps in mobile model controls.
- Added max-width constraints to model, variant, and agent labels on mobile to prevent overflow and cramping.
- Optimized spacing for mobile view.

* feat(git): auto-select gitmoji for generated commit messages

When the "Generate commit message" feature is used and gitmoji is enabled, automatically prepend the appropriate gitmoji based on the commit subject keywords.

- Added `KEYWORD_MAP` to map commit types to gitmojis.
- Added `matchGitmojiFromSubject` helper.
- Updated `handleGenerateCommitMessage` to apply the gitmoji.

* feat(git): auto-select gitmoji for generated commit messages

- Added `KEYWORD_MAP` to map commit types to gitmojis.
- Added `matchGitmojiFromSubject` helper.
- Updated `handleGenerateCommitMessage` to apply the gitmoji.
- Fixed mobile layout for model controls.
2026-01-18 14:28:49 +02:00