Commit Graph
179 Commits
Author SHA1 Message Date
Bohdan Triapitsyn 844052e599 fix: restore desktop startup and align tool previews with SDK updates
Add reflect-metadata bootstrap so desktop sidecar no longer crashes on startup.
Update SDK v1.4 compatibility for model variant and diff payload handling.
Unify write/edit/apply patch expanded previews and hide write success output noise.
2026-04-12 00:40:49 +03:00
Dave OteroandBohdan Triapitsyn 75a10ea66c Add passkey login for protected UI (#845)
* feat(auth): add passkey login for protected UI

* fix: polish passkey setup and correct WebAuthn user IDs

* feat: improve passkey login management

* build: align passkey deps with upstream main

* refactor: move ui auth out of opencode module

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-04-11 22:36:02 +03:00
Paul Mourer 37cf7d9c79 Adds 1w, 30d session token expirations (#853) 2026-04-11 22:33:38 +03:00
Dr. ZedandBohdan Triapitsyn 636dcd5314 fix: improve Windows managed OpenCode shutdown and launch behavior (#844)
* fix: windows shutdown and restart orphaned cleanup

* fix: launch managed OpenCode directly on Windows
Unwrap OpenCode wrappers to launch directly on Windows, improving shutdown reliability and avoid orphans.

* fix: restore desktopNotifyEnabled in health snapshot

---------

Signed-off-by: Dr. Zed <142888684+DocterZed@users.noreply.github.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-04-11 22:29:09 +03:00
Bohdan Triapitsyn 2e5b02e753 test: cover external OpenCode proxy routing
- Expose external OpenCode base URL to proxy runtime
- Add regression coverage for provider requests through external OpenCode hosts
2026-04-07 22:48:17 +03:00
Bohdan Triapitsyn 9254ec0783 fix desktop notifications and chat scroll stability 2026-04-06 17:36:08 +03:00
Bohdan Triapitsyn 4663abd6f3 refactor: isolate chat hot paths and lazy server watchers
Split static history from live tail, stabilize chat data identities, and reduce scroll-shell churn so old viewport content stops waking on stream deltas. Also defer watcher startup and health polling so idle runtime work better matches actual usage.
2026-04-05 15:36:11 +03:00
Bohdan Triapitsyn 5045d21821 perf: reduce idle desktop load by gating plan-mode checks
- Add startup feature flag for plan mode from OPENCODE_EXPERIMENTAL* env vars.
- Stop recurring app health polling and keep a one-time startup check.
- Skip plan-mode synthetic parsing and plan tab/file work when flag is off.
2026-04-03 13:59:10 +03:00
Bohdan TriapitsynandIuliia Ivashko c9e31a0e6c perf: harden sync architecture and modularize runtimes (#803)
* fix: added desktop app background throttling

* perf: add streaming debug metrics panel

- Show streaming performance metrics in the debug panel
- Auto-enable stream profiling while the panel is open
- Add JSON export for sharing UI and VS Code metrics

* perf: batch streaming updates more aggressively

- Buffer message deltas and metadata updates to cut render churn
- Skip no-op part updates before they touch the message store
- Fix the desktop debug panel shortcut binding

* perf: split streaming event handling and coalesce deltas

- Move streaming content events onto a dedicated fast path
- Defer non-critical stream side effects off the hot path
- Merge repeated message delta events before they reach the UI

* perf: isolate streaming rows from chat rerenders

- Memoize chat rows against render-relevant message changes only
- Read live assistant text directly from store to narrow streaming updates
- Split the active streaming entry from the stable message list path

* perf: streamline chat streaming and SSE proxying

- Reduce chat rerenders around the active streaming path
- Simplify server SSE forwarding to avoid duplicate proxy work

* fix: preserve the first streaming text chunk

- Show the initial text chunk immediately before batched deltas arrive
- Bypass batching for the first text or reasoning part update
- Keep later streaming updates buffered for performance

* perf: align streaming/render hot paths with opencode parity

* perf: harden turn/cache stability and stale delta suppression

* fix: stabilize chat rendering and disable timeline interactions

- Disabled timeline dialog access from shortcuts, commands, and chat input
- Reduced chat render churn by simplifying message list and turn staging behavior
- Improved session-switch stability to prevent update-depth crashes

* perf: track static message rerenders during streaming

* perf: reduce sorted-mode activity rerender fanout

* perf: reduce chat rerender fanout and add active-turn metrics

- Reduced sorted-mode rerender coupling by tightening turn context propagation
- Added a metric for static rerenders outside the active turn during streaming
- Exposed new chat render counters in the debug panel for parity tracking

* fix: keep sorted activity mounted while stream grows

* fix: stabilize session and history scroll rendering

* refactor: decouple server routes from index

* refactor: extract fs module from server index

* refactor: move opencode route ownership into module

* refactor: extract notification route registration

* refactor: extract opencode and notification runtimes from index

* refactor: extract settings runtime and complete server modularization pass

* refactor: modularize server config, skills, icons, and tunnel routes

* refactor: extract server modules from monolithic index.js

Split proxy, routes, runtime helpers, and notification emitter
into dedicated modules under packages/web/server/lib/.

* refactor: replace session/message stores with SSE-driven sync layer

Delete ~9200 lines of old architecture (useEventStream, messageStore,
sessionStore, useSessionStore, questionStore, useTodoStore, client SSE).

New sync layer: event pipeline with coalescing + 16ms flush, pure event
reducer, per-directory child stores with LRU eviction, cursor pagination,
optimistic updates, deferred timeline staging, text throttle.

Migrate all UI consumers to sync hooks (useSessionMessages,
useSessionMessageRecords, useSessionStatus, useSessionPermissions, etc).

Strip session-ui-store to UI-only state, delegate SDK ops to
session-actions with abort-if-busy, optimistic store updates, and
response merging for revert/fork/archive/delete.

Add notification-store for SSE-driven session attention tracking,
cross-directory GlobalSessionStatusStore for sidebar indicators,
client-side diff snapshot sanitization to prevent memory bloat,
and revert message filtering via useVisibleSessionMessages.

* feat: notification store, session actions, activity detection

Add notification-store.ts for SSE-driven attention tracking.
Add sanitize.ts to strip diff snapshot memory bloat.
Add session-actions.ts with optimistic revert/fork/archive/delete.
Improve useSessionActivity with incomplete-message fallback.
Delete useServerSessionStatus polling hook.

* fix: add directory param to all SDK calls, fix command/shell/abort routing

All SDK calls in session-actions.ts now pass directory parameter —
required by OpenCode server to scope session operations. Without it,
abort, commands, revert, fork, and other operations returned 500.

Add routeMessage() in session-ui-store for shell mode (session.shell),
slash commands (session.command), and normal prompts. Command lookup
checks both sync child store and useCommandsStore. Handle /compact
locally via session.summarize().

Implement getContextUsage() to restore header context usage display —
reads token counts from last assistant message in sync store.

* refactor: replace custom API proxy with http-proxy-middleware

Remove ~280 lines of custom proxy code: forwardSseRequest,
forwardGenericApiRequest, collectRequestBodyBuffer, header
manipulation, hop-by-hop filtering, SSE block buffering.

Replace with single createProxyMiddleware() call that handles
SSE streaming, large bodies, and timeouts out of the box.
Dynamic router for OpenCode port changes after restarts.
Auth headers injected via proxyReq hook.

Keep: readiness gate, Windows session merge, API prefix detection.

* perf: targeted event draft cloning to fix streaming render cascade

Event handler was eagerly cloning all state slices on every event,
breaking Zustand selector referential equality. During streaming
(~60 events/sec), this caused every subscriber to re-render regardless
of which slice actually changed.

Now only clones fields the specific event type mutates. Also extracts
StatusRowContainer to isolate high-frequency useAssistantStatus
subscription, removes dead messageStreamStatesMap subscription from
ChatContainer, and narrows useAssistantStatus to only track last
assistant message parts.

MessageList renders: 1972 → 296 per streaming session (-85%).

* fix: null safety for sync state slices

Add defensive ?? {} guards on permission, question, session_status,
and message record access. Prevents crashes when child store state
is partially initialized during bootstrap.

* perf: dedup inflight SDK calls, extract concurrency util, delay PR tracking

Extract mapWithConcurrency to shared lib/concurrency.ts. Add in-flight
dedup for loadProviders/loadAgents to prevent concurrent duplicate SDK
calls. Delay initial PR background tracking by 5s to reduce startup
CPU burst.

* fix: header session lookup across all child stores

Session title and context panel click failed when session belonged to
a different directory than the current child store. Fall back to
getAllSyncSessions() to search all initialized stores.

* chore: bump @opencode-ai/sdk to 1.3.5

* docs: add sync event handling guide

* Optimize session prefetch and improve delete/archive UX

- Add settlement delay to session prefetch to avoid race conditions on
  rapid session switches
- Reduce git diff prefetch and session cache limits for better performance
- Implement optimistic UI updates for session delete/archive operations
  with proper rollback on failure
- Wire session prefetch hook into SessionSidebar with sync integration

* Add file content cache and sync optimizations

- Wrap FilesAPI with in-memory LRU cache for file content with dual
  constraints (entry count and byte size)
- Optimize chat timeline scroll restoration using useLayoutEffect
- Preserve React references in message and part arrays to prevent
  unnecessary re-renders when prepending history
- Add session prefetch TTL cache to prevent redundant fetches
- Integrate session prefetch cache clearing with eviction flow

* Improve session sidebar error handling and add diff prefetch filtering

Load active and archived sessions independently using Promise.allSettled
to prevent one failure from blocking the other. Add retry logic to session
API calls and skip large files during diff prefetch to improve performance.

* Replace sendMessage with optimisticSend wrapper

Introduces optimistic UI updates for normal chat messages to provide
instant feedback. Messages appear immediately in the UI while the API
call executes in the background, with automatic rollback on errors.

* perf: split stores, proper optimistic send, fix revert/directory bugs

- split session-ui-store into voice/input/selection/viewport stores
  to reduce subscriber re-evaluation during streaming
- wire optimisticSend through useSync shadow Map infrastructure
  matching OpenCode's pattern (no heuristic part detection)
- port OpenCode Identifier.ascending ID format for correct sorting
- pass messageID to promptAsync to prevent duplicate messages
- fix worktree directory not propagating to session actions
  (dynamic dir() via opencodeClient.getDirectory)
- fix setCurrentSession accepting directoryHint for new sessions
- fix revert not hiding messages (session limit was 5, bumped to match loaded count)
- fix revert optimistic message removal from store
- fix load-more flicker (useLayoutEffect scroll compensation)
- add prefetch TTL cache, file content LRU cache
- add session prefetch for adjacent sessions
- add instant archive/delete (optimistic before SDK call)
- migrate legacy window.__zustand_session_store__ to session-ui-store
- add retry + independent error handling for archived sessions
- add AGENTS.md performance rules

* perf: startup optimization — dedup, caching, light git status, diff rendering gates

- defer diff prefetch to git tab open, reduce concurrency 4→2, skip >500 changed lines
- cap project git checks concurrency (2), directory status probe (3)
- dedup provider/agent loading, github auth, worktree list (in-flight + TTL caches)
- delay PR tracking 5s, cache 403 search failures per-repo
- coalesce settings PUT (200ms debounce), cache settings GET (2s TTL)
- cache canonical directory resolution (60s TTL)
- persist missing directory status to localStorage (10min TTL)
- light/heavy git status: polling skips numstat+line counting+rev-list
- large diff rendering gate (>500 lines → "render anyway" button)
- tokenization degradation for >500KB files in Pierre
- parallelize main.tsx pre-render awaits
- batch sidebar file tree expanded paths restoration (3 at a time)
- remove bare useConfigStore() subscription in AgentsPage
- sync worktree sandboxes to OpenCode SQLite DB
- fix RightSidebarTabs ternary → explicit tab matching
- defensive guards on sync state (session_status, permission, question, message)

* fix: add defensive guards on remaining sync state field accesses

guard session_status, permission, message, todo, part, config with ?? {}
in useDirectorySync selectors, session-cache, and bootstrap

* fix: add missing directory dep to useCallback in use-sync.ts

* fix: preserve diffStats when light-mode polling overwrites status

* perf: optimize startup git status polling and diff rendering

Preserves diff stats when lightweight polling updates repository status
Reduces startup overhead with smarter git polling and store updates
Adds detailed optimization and migration docs for next performance steps

* fix: keep chat diff stats stable during git status updates

Prevents lightweight git polling from dropping diff statistics
Keeps MessageList diff indicators consistent while status refreshes
Improves reliability of git-aware chat rendering

* fix: user animation replay, queued message variant, startup provider loading

- consume animation ID after first play to prevent re-animation
  on neighbor assistant message completion
- capture send config (model/agent/variant) at queue time matching
  OpenCode's FollowupDraft pattern instead of re-resolving at send time
- replace one-shot startup recovery effect with polling interval
  that retries every 2s until providers and agents load
- fix optimistic bridge to avoid re-render loop (stable ref wrappers)

* chore: update tauri to 2.10.3 and all plugins to latest

- tauri 2.9.4 → 2.10.3
- tauri-build 2.5.3 → 2.5.6
- tauri-plugin-dialog 2.4.2 → 2.6.0
- tauri-plugin-log 2.7.1 → 2.8.0
- tauri-plugin-shell 2.3.3 → 2.3.5
- tauri-plugin-updater 2 (floating) → 2.10.0 (pinned)
- @tauri-apps/api ^2.9.0 → ^2.10.1
- wry 0.53.5 → 0.54.4 (transitive)

* refactor: decouple web server index orchestration runtimes

* fix: align VS Code runtime behavior with web and reduce draft view CPU load

- Queue VS Code bridge and SSE startup requests until API readiness to avoid false bootstrap failures
- Make agent manager actions directory-aware and remove real worktrees with safer partial-failure handling
- Replace heavy logo animation path with a lightweight pulse to cut draft-session CPU usage

* fix: restore auto-selected file sending in chat input

- Send server-selected files as proper file URLs in the message payload
- Include server-backed attachments in submit flow instead of dropping them
- Restore queued-message attachments through the refactored input store

* fix: restore session model selection consistently on session switch

- Restore agent, model, and variant from the latest loaded user message for each session
- Wait for session messages before applying restored selections to avoid stale or missing state
- Remove legacy session-choice inference paths that caused overlap and instability

* fix: restore permission replies and auto-accept across sessions

- Scope permission and question replies to the target session directory so answers take effect reliably
- Make permission auto-accept immediately handle pending requests and react to new permission prompts
- Keep parent-session handling working for child-session requests through the shared response path

* feat: add reusable fuzzy branch fuzzy-search helper and dialog integration (#798)

* feat: add reusable fuzzy branch search for worktrees

* chore: drop planning docs from feature branch

* feat: make worktree branch refresh manual

* feat: add configurable session retention action

* refactor: centralize global session state in ui store

* fix: cancel debounced permission push after reply

* docs: clarify global and directory session store architecture

* docs: refine agent development rules and session activity guidance

- Clarify agent code of conduct and durable development patterns
- Add explicit shared-store rerender and live-state guidance
- Narrow session activity fallback to avoid stale working state

* chore: updated .gitignore

---------

Co-authored-by: Iuliia Ivashko <yulia.ivashko@gmail.com>
2026-03-31 18:47:00 +03:00
Bohdan Triapitsyn 1231fd773e feat: improve VS Code dev flow and stabilize sidebar/chat behavior (#754)
* fix: improve session sidebar tooltip and truncation behavior

- Keep new-draft tooltip anchored to its trigger button
- Fix minimal-mode worktree/group header text truncation
- Tune minimal-mode right padding to reduce early label clipping

* fix: render reasoning through markdown pipeline

- Use Streamdown rendering for reasoning in live chat mode
- Remove italic styling from reasoning text
- Render expanded reasoning content with MarkdownRenderer

* chore: remove legacy electron dependencies

- Removed unused Electron packages from root and UI manifests
- Deleted obsolete Electron context menu type declaration
- Regenerated lockfile after dependency cleanup

* fix: handle non-repository folders in git status API

- Prevent 500 errors when status is requested outside a valid Git repo
- Improve repository detection using `git rev-parse --git-dir`
- Reduce noisy server logs for expected non-repo status checks

* fix unloaded session chat layout flicker

* fix: reduce noisy TTS status polling

Cache and dedupe TTS status requests, and only check provider availability when the related voice features are enabled so disabled voice setups stay quiet.

* perf: throttle background PR git status refreshes

* fix: improve VS Code Explorer file drop mentions in chat

- Add Explorer context action to insert selected files as @mentions.
- Handle Explorer drag-and-drop to prefill @file mentions instead of attachments.
- Prevent duplicate plain-path text when dropping multiple files.

* fix: deduplicate recent sessions in VS Code sidebar

- Hide sessions from main list when already shown in recent
- Apply dedup only in VS Code runtime
- Keep session search behavior unchanged

* feat: add true HMR dev flow for VS Code extension

- Load VS Code webview from Vite dev server with React refresh preamble
- Add `vscode:dev` runner that starts watchers and opens Extension Development Host
- Update VS Code dev docs and scripts to use the new HMR startup flow

* feat: polish VS Code session sidebar and attachment UX

- Add resizable sessions sidebar in VS Code layout
- Tighten session list spacing and hover behavior in VS Code
- Remove bulk file/image attach success toasts while keeping error toasts
2026-03-23 23:51:55 +02:00
yslee ea6d4c4d43 feat(server): support configurable hostname for managed OpenCode server spawn (#599)
* feat(server): support configurable hostname for managed OpenCode server spawn

Allow the managed OpenCode server bind hostname to be configured via
OPENCHAMBER_OPENCODE_HOSTNAME environment variable (default: 127.0.0.1).

This enables LAN/Tailscale access without a reverse proxy by setting
the hostname to 0.0.0.0.

Closes #597

* fix: address review feedback — input validation, port probe hostname, security docs

- Add defensive parsing for OPENCHAMBER_OPENCODE_HOSTNAME with trim/empty
  check and warning log, matching OPENCODE_HOST validation pattern
- Pass configured hostname to resolveManagedOpenCodePort() so port
  availability is probed on the actual bind address, avoiding EADDRINUSE
- Add security note in README docs warning about 0.0.0.0 exposure on
  untrusted networks
2026-03-23 15:48:04 +02:00
Iuliia Ivashko dc100ed0da fix: bind web server to 127.0.0.1 by default and add --host CLI flag (#750)
## Summary

Fixes #736 — OpenChamber listens on `0.0.0.0` (all interfaces) by default, exposing the server to the network without warning. The log output shows `visit: http://127.0.0.1:...` which is misleading.

## Changes

- **Default bind address changed to `127.0.0.1`** — server is only accessible locally unless explicitly configured otherwise
- **New `--host` CLI flag** — `openchamber --host 0.0.0.0 -p 8080` to listen on all interfaces
- **`OPENCHAMBER_HOST` env var** — documented in help text and docker-compose.yml as an alternative to `--host`
- **Docker entrypoint** defaults to `OPENCHAMBER_HOST=0.0.0.0` so container port mapping continues to work
- **Startup logs** show the actual bind address instead of hardcoded `localhost`

### Resolution priority

```
--host flag  >  OPENCHAMBER_HOST env var  >  127.0.0.1 (default)
```

### What doesn't break

- **Desktop app** — already forces `OPENCHAMBER_HOST=127.0.0.1` via Tauri
- **VS Code extension** — doesn't use the web server
- **Docker** — entrypoint sets `OPENCHAMBER_HOST=0.0.0.0`, preserving current behavior
- **Tunnels** — cloudflared connects to `127.0.0.1` origin internally, works regardless of bind address

## Testing

Automated:
- `bun run type-check` / `bun run lint` — pass

Manual (CLI, direct `node` execution):
- Default bind → `127.0.0.1` (verified via `lsof`/netstat)
- `--host 0.0.0.0` → binds all interfaces
- `--host=0.0.0.0` (inline) → works
- `--host` without value → error exit 2
- `OPENCHAMBER_HOST` env var → respected
- `--host` flag overrides env var
- IPv6 `::1` → correct bracketed URL, health check 200
- CLI daemon start/stop → works
- `visit:` URL → correct
- Help text → `--host` in OPTIONS, `OPENCHAMBER_HOST` in ENVIRONMENT
- Browser UI → loads and works
- Tunnel via UI → works
- Desktop app → no regression

Docker (tested on Ubuntu with native Docker):
- SSH key generated successfully
- `OpenChamber server listening on 0.0.0.0:3000`
- Health check 200
- `uid=1000(openchamber)` confirmed
2026-03-23 15:07:16 +02:00
Bohdan Triapitsyn 64b55025e1 feat: Add opt-out setting for anonymous usage reporting (#743)
* refactor: align VS Code update checks with web runtime parity

- VS Code now uses file-based installId (shared with web server)
- Accepts platform/arch from webview for consistent behavior
- Usage data collection now matches web implementation

* feat: Add opt-out setting for anonymous usage reporting in Appearance

- Add privacy control in Appearance settings to opt-out of anonymous usage reports
- Usage data includes only app version, platform, and runtime - no personal data or code collected
- Setting persists across all runtimes and controls the reportUsage parameter in update checks
2026-03-22 23:02:53 +02:00
Bohdan Triapitsyn 53c2a0d919 feat: instant draft-first worktree creation and multi-run launcher redesign (#741)
## Summary

- **Instant worktree creation from chat draft**: selecting "+ New worktree" in the draft branch selector immediately creates a session draft and bootstraps the worktree in the background — no modal interruption
- **Redesigned multi-run launcher**: compact 2-column grid layout in a right-sized dialog with scroll shadow, sticky footer, tooltips replacing verbose descriptions, and project icons in the selector
- **Branch selector aligned across surfaces**: multi-run and agent manager branch pickers now use the shared git store and match NewWorktreeDialog behavior (same default resolution cascade, no synthetic HEAD option, all branches shown)
- **Opaque model multi-select dropdown**: fixes text bleed-through on translucent backgrounds by compositing `--surface-elevated` over `--surface-background`
- **"+ New" inline button in sidebar worktree headers** for faster worktree creation

## Why

Worktree creation was behind modal flow that interrupted the user's train of thought. The draft-first approach lets users start typing immediately while the worktree bootstraps. The multi-run launcher had an oversized form layout with redundant explanations, and its branch picker behaved differently from the main worktree dialog - causing confusion about which branches were available and what the default was.
2026-03-22 22:31:29 +02:00
Bohdan TriapitsynandIuliia Ivashko 321cc7252a Major UI refresh: sidebar redesign, theme expansion, and chat performance optimizations (#706)
## Summary
Complete sidebar redesign and comprehensive UI polish pass with performance optimizations, theme system refinements, and desktop integration improvements.

## Key Changes

**Sidebar & Navigation Redesign**
- Redesigned sessions sidebar layout with unified button primitives
- Added activity sections with project grouping and improved session organization
- Refined sidebar corners, spacing, and visual hierarchy
- Removed NavRail component in favor of streamlined sidebar
- Stabilized sessions bar toggle position in fullscreen mode

**Performance Optimizations**
- Reduced chat streaming CPU usage and storage churn
- Optimized task tool polling and live timers with debouncing
- Prevented chat state races and reduced background request load
- Debounced draft writes and coalesced session reloads
- Optimized message store updates and turn tracking

**Theme & Visual System**
- Added theme-aware window corners (desktop) and border radius tokens
- Introduced glassmorphism effects on desktop sidebar
- Added backdrop blur to UI elements

**Chat Experience**
- Added session-based permission auto-accept toggle in chat input
- Polished permission shield UX with improved icon sizing and spacing
- Fixed chat scroll-to-bottom behavior and timeline tracking
- Enhanced tool output display with better path label detection
- Removed duplicate draft context details in chat header
- Added text selection menu to chat messages

**Git Improvements**
- Refreshed git history visual design with cleaner dividers
- Added remote removal action in sync selector
- Stabilized git polling to prevent excessive requests
- Improved tool output rendering for git operations

**Settings & Panels**
- Fixed mobile scrolling on settings pages
- Made outside-click settings close instantly
- Reduced settings load churn and CPU spikes
- Improved services dropdown layout and spacing
- Softened panel resize handles

**Desktop Integration**
- Synced macOS window theme with app theme
- Restored window dragging in sidebar header zones
- Fixed system window corners on macOS
- Improved header session metadata and action controls

**Button & Component Standardization**
- Unified button primitives across all components
- Standardized destructive action patterns
- Removed unused button variants (button-large, button-small)
- Aligned context tab close hit areas

---------

Co-authored-by: Iuliia Ivashko <yulia.ivashko@gmail.com>
2026-03-20 01:01:03 +02:00
Bohdan Triapitsyn 74ef18dd4f fix: tighten server update check handling (#694)
Refine server update-check flow in runtime endpoints
Improve package-manager update detection consistency
2026-03-17 13:25:55 +02:00
Bohdan Triapitsyn 3123de5f43 fix: improve Windows UX and stabilize chat/session behavior across runtimes (#693)
* fix: preserve unsent prompt when adding editor context in VS Code

* fix: append Add to chat selections as markdown blocks with stable spacing

Convert selected assistant content to markdown before appending
Wrap each Add to chat selection in an `md` fenced block
Preserve multiline composer formatting across repeated appends

* fix: normalize persisted Windows paths to prevent identity mismatches

* fix: hide Windows subprocess console popups across server tasks

Hide OpenCode startup and shell command child windows in the web server
Apply windowsHide to cloudflared and skills-catalog git subprocesses
Cover remaining git service exec paths that could surface console windows

* fix: restore chat auto re-pin when reaching bottom

Re-pin now triggers when scrolling back into the bottom zone, not only via the button.
Upward user scroll intent still unpins immediately and is not overridden by re-pin.
Unified bottom/re-pin threshold logic to reduce sensitivity mismatches.

* fix: restore chat scroll release on mobile during streaming

Restores pinned-scroll release on touch scroll up so mobile users can leave auto-follow while streaming.
Improves re-pin behavior near bottom to avoid sticky or inconsistent pin states.
Includes related chat UI and dependency updates in the same change set.

* fix: hide daemon startup probe consoles on Windows

* fix: prevent pinned scroll tug-of-war during streaming

* fix: prefer git.exe to avoid Windows diff popup flashes

* fix: prefer git.exe discovery in Windows git flows

* fix: avoid where probes in Windows git resolution

* fix: avoid update-check subprocess flashes on Windows

* fix: normalize read file path labels

* feat: add OpenChamber defaults and improve theme ports

Add new OpenChamber light and dark themes
Regenerate imported themes with stronger surface mapping
Set OpenChamber themes as the default top options

* fix: stabilize chat pin and unpin behavior during streaming

Restores reliable unpin on upward wheel and touch gestures while auto-follow is active.
Prevents immediate re-pin while the user is actively scrolling upward near the bottom.
Keeps smooth follow-to-bottom behavior while reducing scroll tug-of-war.

* fix: suppress Windows command popups in VSCode runtime processes

Hide spawned git and server process windows in VS Code runtime
Extend hidden-window handling to server port cleanup and reveal commands
Keep behavior unchanged on non-Windows platforms
2026-03-17 13:18:54 +02:00
Bohdan Triapitsyn 7f37256e96 fix: unify update-check API flow across runtimes (#672)
* fix: align update flow across web, desktop, and vscode

Unify runtime update handling in shared UI update state
Adjust desktop and VS Code bridge integration for consistent behavior
Improve server package-manager update plumbing for safer checks

* fix: sync update checks between vscode and server

Align VS Code bridge behavior with server package-manager logic
Reduce mismatches in update detection across runtimes

* fix: stabilize update checks across ui and server
2026-03-15 23:14:37 +02:00
Sergio 875491c438 fix(web): hide daemon/git console windows on Windows (#653) 2026-03-13 11:13:36 +02:00
Bohdan Triapitsyn fab32ca992 refactor(chat): complete turn-based pipeline and stabilize streaming, scroll, and tool UX (#629)
* refactor: add canonical turn projection pipeline for chat

Centralizes turn/activity/summary derivation, migrates render consumers to shared projection sources, and adds projector regression coverage for retries, malformed parent fallbacks, and activity segmentation.

* refactor: stream assistant text live in turn-first render path

* refactor: complete phase-3 turn timeline history/navigation

* refactor: complete phase-4 turn pipeline cutover

Remove legacy grouping adapters and lock key edge cases with executable regression tests so turn-centric rendering stays stable across retry/history/navigation flows.

* fix: align chat history loading path with opencode parity

* fix: stabilize chat streaming and reduce render churn

* feat: add blurIn streaming text animation and smooth lerp-based auto-scroll

Streaming markdown now uses Streamdown blurIn animation (150ms, ease-out) for per-word reveal
Auto-scroll during streaming uses continuous exponential smoothing (lerp) instead of restarting spring animations
One-shot scroll-to-bottom (button click) uses motion spring for natural deceleration

* fix: respect user scroll-up during streaming and re-pin on scroll back to bottom

* fix: stabilize activity stream and tool progress rendering

Activity now stays chronologically consistent and avoids duplicate reasoning/justification.
Tool rows show running state and duration earlier with smoother pending behavior.
Removed legacy trim/timestamp paths to prevent message drops and simplify Activity UI.

* fix: reverted regression of revert functionality

* fix: stabilize chat activity layout and tool progress behavior

Stopped user messages from re-animating when new user messages appear.
Made Activity and aggregated tool rows wrap inline consistently without misaligned headers/icons.
Fixed tool part matching so duration and shine no longer reset across pending/in-progress status updates.

* fix: restore activity mode behavior and stabilize tool rendering

Re-enabled Collapsed/Summary/Detailed/Changes defaults for Activity and tool expansion.
Fixed tool row wrapping/alignment, removed user fade re-animations, and disabled FadeInOnReveal animations.
Improved tool status handling to reduce timer/shine resets and made reasoning bold render as normal text.

* refactor: simplify chat tool and message rendering

Replace activity-group rendering with flat inline part rendering
Remove obsolete tool output and justification activity settings
Keep user message animation and improve edit/apply-patch file path headers

* style: narrow chat and composer columns equally

* fix: Tool status checks and abort flow regression

* fix: improve multi-file apply patch header rendering

* fix: make timeline message jump scroll to selected chat entry

Conversation Timeline clicks now reliably scroll to the selected message in chat
Timeline dialog waits for navigation result before closing to avoid silent failures
Chat message scrolling now resolves the active chat scroller consistently

* chore: remove branch-added chat tests and clean lint leftovers

Removes newly added chat and message test files from this branch
Fixes lint blockers in ProgressiveGroup, ToolPart, and messageStore
Keeps type-check, lint, and build passing after cleanup

* fix: keep composer status row closest to the input

Status/todo row now renders below queued messages and attachments.
Linked GitHub issue/PR chips stay above status so input context order is consistent.
Improves chat composer readability while assistant is working.

* fix: disable assistant header animations and polish chat status behavior

Assistant message header now renders without transition effects
Removed a lint issue from the working placeholder props
Chat status and message flow updates improve consistency during active turns

* feat: increase bottom spacer in mobile chat for better scrolling

* feat: add sorted chat mode with progressive activity rendering

Adds global chat render mode settings for sorted and live behavior
Renders non-stop assistant output in Activity as messages complete
Disables streaming text animation in sorted mode and restores classic reasoning/justification blocks

* fix: stabilize chat timeline navigation and older history loading

Prevents auto-loading older history from scroll and keeps loading behind the button
Fixes timeline jump-to-message behavior that snapped back to the bottom
Reduces chat list flicker and empty-state glitches on large session pagination

* fix: stabilize sorted activity text and hide reasoning timers

Prevented sorted justification from appearing before message completion by requiring explicit non-stop finish.
Removed duration values for sorted Thinking and Justification blocks.
Kept smooth sorted auto-follow behavior tuned to reduce bottom-jump jitter.

* refactor: simplify chat tool rendering paths and add parts docs

Centralized tool icon mapping into a shared presentation helper used by grouped and expandable rows.
Removed static-tool-specific branches from ToolPart to keep it focused on expandable tools.
Added a new DOCUMENTATION.md explaining where to change tool descriptions and rendering behavior.

* feat: enhance event stream handling for message parts

- Refactor event key building functions to improve clarity and reduce redundancy.
- Introduce `applyPartDelta` method in message store for handling delta updates to message parts.
- Update `useEventStream` to utilize the new `applyPartDelta` method for processing incoming deltas.
- Enhance text extraction logic to accommodate new part types and improve merging behavior.
- Implement logic to skip delta-driven updates for ongoing text/reasoning parts to prevent overwriting.
- Adjust server-side text merging logic to handle trimmed text comparisons and improve consistency.

* feat: enhance OpencodeService with delta handling and stale delta management

- Introduced globalSseStaleDeltas to track stale deltas.
- Added methods to generate keys for delta and updated part events.
- Updated global SSE loop to skip processing stale deltas.
- Refactored global SSE event handling to improve performance and reliability.

refactor: remove unused streaming part handling in messageStore

- Eliminated streaming part queue and associated logic.
- Simplified message merging logic by removing redundant checks.
- Streamlined message handling to improve clarity and maintainability.

chore: clean up unused streaming text normalization functions

- Removed deprecated functions related to streaming text identity and merging.
- Simplified normalizeStreamingTextPayload to focus on current functionality.

* refactor: simplify streaming event passthrough

Use SDK-native global event streaming in the UI client
Remove dead server-side SSE normalization helpers
Keep streaming payloads closer to upstream behavior

* revert: remove message memory settings UI

Drop the restored message memory settings screen
Keep session settings focused on current defaults
Preserve chat history limits as internal behavior

* feat: add compact collapsed Activity preview in sorted mode

Collapsed Activity now shows a live preview of the latest 7 entries
Older activity rows roll up behind a +N more indicator
The +N more indicator is clickable to expand the full Activity

* fix: adjusted activity changed files text prominence

* fix: make sorted mode snap to bottom when not streaming

* perf: show chat scrollbar only on user-driven scrolling

Chat scrollbar now stays hidden during automatic follow-to-bottom
Scrollbar visibility is gated by real user scroll intent
Reduced scroll overhead by removing timer-based intent tracking

* refactor: align web and vscode session activity streaming

Route VS Code SSE through SDK-based proxy flow
Restore controlled web session activity tracking and cooldowns
Keep chat activity behavior consistent across runtimes

* fix: adjusted muted foreground themes color

* fix: stabilize session activity and attention updates

Keep streamed chat state in sync as sessions complete
Restore reliable attention indicators for inactive sessions
Tighten server and UI event handling for chat updates

* feat: add chat render previews and file icon visibility setting

Added animated chat render mode previews in Chat settings.
Added a new toggle to show or hide file icons across tool rows.
Persisted chat render, activity, and mermaid modes to shared settings file.

* fix: update default GitHub OAuth client ID

Use the new OpenChamber org GitHub OAuth app ID by default.
Keep web server and VS Code auth defaults in sync.

* fix: sync chat settings across VS Code chat views

Broadcast settings changes to both sidebar and editor chat webviews.
Apply synced settings in each webview via shared settings refresh.
Ensures chat render mode updates appear immediately in editor tabs.

* fix: stop writing session folders file in VS Code workspaces

Disable disk persistence for session folders in VS Code webview runtime
Keep session folder state in VS Code/webview storage instead of project files
Preserve existing behavior for non-VS Code runtimes

* style: polish expanded tool panels and bash output readability

Removed extra borders/labels in expanded tool cards for a cleaner UI
Added softer scroll shadows and full-height decorative activity line
Switched bash command/output to code-style typography with tighter spacing

* feat: add default-open tool controls for chat activity

Added Chat settings toggles to open Bash and Edit tools by default
Default-open behavior now applies across both sorted and live activity rendering
Users can still manually collapse default-open tools, plus bash output height was reduced

* fix: align chat loading skeleton with message layout

Match skeleton width and horizontal alignment to chat message column
Add one-line tool-style skeleton rows with subtle circular placeholders
Increase top spacing so loading state no longer touches chat header

* fix: prevent blank screen when adding inline diff comments

Sanitize persisted inline comment drafts to ignore invalid data
Harden diff annotations against malformed line numbers
Fail safely when annotation updates error instead of crashing the view

* fix: streamline VS Code archived sessions sidebar

Show archived sessions in VS Code only for the active workspace directory.
Render archived sessions as a flat list in VS Code without project-root subfolders.
Hide the "Open in Side Panel" session action in VS Code.
2026-03-12 23:45:45 +02:00
Iuliia Ivashko 63f1698cdd Epic: grand tunnel restructuring and CLI UX (#640)
* feat: restructure tunnel handling around provider-based service model" -m "Introduce tunnel service/registry/provider architecture and move Cloudflare handling behind provider adapter." -m "Add canonical tunnel modes (quick, managed-remote, managed-local) with legacy named/try-cf-tunnel compatibility mapping." -m "Add managed-local config-path support, normalized API response fields, tunnel-focused tests, and shell aliases for tunnel test workflows.

* feat(tunnels): harden managed startup and decouple runtime APIs

Improve managed Cloudflare startup reliability with explicit config validation, YAML diagnostics, and readiness detection based on process output instead of fixed delay assumptions.

Refactor server tunnel lifecycle around provider-aware runtime state and API responses while keeping legacy Cloudflare token endpoint compatibility, and add coverage for unsupported mode validation plus managed-local startup cases.

* feat: remove named tunnel mode and standardize managed modes

Replace named tunnel terminology with managed-remote and managed-local across API, server state, and UI settings without legacy aliases.

Add provider capability discovery endpoint and descriptor-based mode validation, including explicit mode_unsupported errors for removed mode values.

* feat(tunnels): finalize provider-aware tunnel UX and managed-local safety

Restructure tunnel settings with provider selection, mode chips, persisted managed-local config path, and clearer session badges while preserving existing tunnel flows.

Add legacy named-data migration, provider discovery CLI, and user-friendly managed-local config validation/error messaging with updated API/CLI/server tests.

* Add provider icon to tunnel settings

* Add control+C to stop tunnel

* feat(cli): add tunnel lifecycle profiles and preserve preset naming

Replace legacy tunnel flags with explicit tunnel lifecycle commands, daemon-by-default startup, and file-backed log tailing so tunnel operations are predictable and provider-agnostic.

Add managed-remote profile storage/migration for start-by-name workflows and propagate preset summaries to settings so user-defined profile names are preserved instead of falling back to Default.

* feat: improve tunnel CLI safety and startup UX

Add interactive TTL support and per-start TTL overrides for tunnel start
Strengthen port safety and instance validation with clearer startup and error guidance
Refine tunnel doctor and CLI output formatting for clearer, less noisy diagnostics

* feat: add TTL support, safety gates, and polished tunnel CLI output

* fix: harden tunnel doctor checks and CLI port handling

* fix: improve tunnel CLI diagnostics and profile output

* fix: streamline tunnel profile UX and doctor diagnostics

* fix: clarify tunnel replacement behavior across CLI and UI

* Upd docs

* docs: add mandatory clack CLI skill guidance. cleanup

* fix: standardize tunnel CLI mode parity and prompt UX

* fix: align CLI quiet and JSON output behavior

* feat/web-serve: in-progress animation

* fix: tunnel doctor managed remote validation

* Fix: security tightening

* fix: instance restart ux

* fix: tighten tunnel doctor input handling and CLI port/prompt validation

* chore: remove tunnel test suites per owner request

---------

Signed-off-by: Iuliia Ivashko <yulia.ivashko@gmail.com>
2026-03-12 19:40:22 +02:00
Bohdan Triapitsyn d1650343b1 refactor: make GitHub PR status more reliable and up to date (#613)
* fix: avoid incorrect PR status on default branch

Hide sidebar PR status when current branch is the repo default branch.
Tighten PR fallback matching to avoid picking unrelated PRs with the same branch name.

* fix: make sidebar PR status more reliable

Resolve PRs more reliably across remotes and repo networks.
Persist sidebar PR status across tab reloads while keeping updates fresh.
Reduce noisy GitHub errors and correct blocked styling in PR view.

* fix: correct blocked PR styling in sidebar

Stop treating missing merge permissions as a blocked PR state in the sidebar.
Align sidebar PR status colors and labels with the main PR view.

* refactor: make GitHub PR status updates feel more current

Refresh PR state on focus, visibility, and repo changes
Add follow-up PR refreshes after create, merge, ready, and update actions
Document GitHub PR resolution, consumers, polling, and triggers
2026-03-11 23:52:31 +02:00
Dr. Zed e103c2c429 Feat: spell check toggle for desktop (#626)
* feat: (desktop) add spellcheck toggle for text inputs

* fix: show spellcheck toggle only on desktop

* fix: apply the preference consistently to chat and commit inputs
2026-03-11 00:35:43 +02:00
Bohdan Triapitsyn a7f11121e8 refactor: modularize session sidebar and add GitHub PR tracking (#610)
* feat: switch sessions sidebar to global paginated loading with archived flow

Load sessions via global endpoint with progressive 500-item pagination and legacy fallback
Add dedicated archived sidebar section for archived and unassigned sessions
Change remove behavior to archive outside archived and hard-delete inside archived

* feat: improve archived sessions UX and folder persistence

Archive sessions on worktree removal while keeping worktree deletion
Streamline archived sidebar actions, icons, metadata, and tooltips
Persist session folders to ~/.config/openchamber/sessions-directories.json with startup hydration

* fix: align archived session actions and clean empty archived folders

Apply archived dropdown behavior consistently for folder-contained sessions
Remove archived-only folder actions while keeping standard folder behavior elsewhere
Auto-prune empty archived folders during session cleanup and persistence sync

* refactor: modularize session sidebar and stabilize behavior

Split monolithic sidebar logic into focused hooks and components
Kept session, archive, folder, and project interactions working with cleaner state persistence
Added sidebar DOCUMENTATION.md summarizing file roles and refactor outcomes

* fix: improve fork PR detection and smart remote tracking

Added centralized PR status store for shared polling and refresh
Auto-selects the remote that has an existing PR when current remote has none
Stops periodic polling for closed or merged PRs to reduce unnecessary requests

* fix: make chat and toast corners follow active theme radius

Toast corners now use theme radius tokens instead of hardcoded rounding
User message bubble now uses theme-configured max radius with preserved tail corner
Square-corner themes now consistently affect both toasts and chat bubbles

* feat: show live PR status across git view and session sidebar

Added a shared GitHub PR status store with adaptive background polling and terminal-state pause
Improved fork remote detection and auto-selection so existing PRs are found more reliably
Updated session group headers to show clickable PR number with branch and state-colored branch icon

* feat: centralize GitHub PR tracking and enrich session sidebar PR details

Moved PR status polling to a single global pipeline keyed by directory and branch
Improved fork-aware PR resolution and reduced duplicate GitHub status fetches across views
Added richer session sidebar PR display with clickable number, state-aware styling, and structured tooltip details

* fix: adjust PR indicator icon vertical alignment

Fine-tuned PR indicator icon vertical alignment in session sidebar
Reduced icon translate-y from 2px to 0.5px for better visual balance

* feat: improve session sidebar status display

* feat: enhance session display logic for minimal mode and improve dropdown menu accessibility

* feat: refactor session row to include tooltip for minimal display mode
2026-03-06 17:22:59 +02:00
Bohdan Triapitsyn d1a41000ca perf: speed up desktop startup and unify theme-aware branding (#596)
* fix: unify startup logo and loading theme behavior

Show desktop window immediately with animated splash logo
Align splash/logo colors with selected app theme and default themes
Keep auth loading state on full-screen logo without size jump
Make project SVG icons follow active app theme
Use the active theme foreground color for project icons discovered from favicons
Apply server-side SVG color overrides for currentColor icons via icon request params
Keep non-SVG project icons unchanged while preserving existing fallback behavior

* perf: speed up desktop startup and unify loading logo visuals

Desktop startup now shows UI sooner while backend boot continues in background
Startup host probing uses a faster local path with safer remote fallback retries
OpenChamber logo cube highlights now match splash screens consistently

* fix: keep macOS traffic-light buttons in the correct position on load

Stop native window title updates on macOS during app initialization
Prevent title bar relayout that reset custom traffic-light positioning

* fix: recover missing providers and agents after fast startup

Retries provider/agent loading when connection is up but core config is still empty
Prevents cold-start state where models/agents appear only after manual project switch
Keeps startup responsive with throttled background recovery in app bootstrap
2026-03-04 19:16:45 +02:00
plfavreau 0b3d0378d4 fix(cli): surface tunnel bootstrap connect URL for --try-cf-tunnel (#561)
The CLI tunnel startup generated a bootstrap token but discarded it,
then built a URL with ?token=<uiPassword> which the tunnel auth system
ignores. Remote users always saw 'Tunnel access required' with no way
to authenticate.

Capture the bootstrap token, build the /connect?t=... URL, and pass it
through onTunnelReady so the CLI prints the correct one-time connect
link (and QR code).
2026-03-04 14:54:29 +02:00
Bohdan Triapitsyn 79143bff4c feat: massive chat reliability + UX pass (web/desktop/mobile/vscode) (#593)
## Added Features
- Add VS Code save-as-image flow for assistant messages via webview bridge + native save dialog.
- Add hourly desktop update checks after startup.
- Add new tool output display mode: `Changes` (auto-expand edit/write/patch only; keep activity expanded; mode guidance text).
- Add GitHub PR attachment flow in chat input with PR picker + attached PR chip/details.
- Add mobile overlay presentation for GitHub Issue and PR pickers (shared with desktop picker content).

## Fixes
- Save-gate project icon updates until explicit Save; allow icon removal with same save-gated behavior.
- Restore clickable chat action buttons in sticky header mode (desktop + Firefox hit-target issue).
- Clamp sticky user messages to bounded chat height and allow internal scrolling.
- Prevent drawer context crash during iPad/tablet orientation switching.
- Improve text-selection action menu placement on narrow screens.
- Move assistant message time into clock tooltip; keep duration display clean.
- Hide `Link GitHub Issue` row in VS Code chat input area (GitHub flow is not yet ready there).
- Remove laggy close animation in text-selection popover; keep open motion/positioning behavior.
- Fetch branches when picker opens and cache empty; show loading state instead of false “No branches found”.
- Fix share-image export metadata rendering (theme background resolution, timestamp rendering, footer alignment).
- Scope MCP services status/toggles to active directory to avoid cross-project leakage.
- Improve long user-message clamp behavior (40% cap variant, hidden scrollbar, scroll shadows, expansion detection).
- Fix desktop `Check for Updates` menu handler; prevent duplicate checks; show clear success/error toasts.
- Stabilize long user-message scrolling behavior (follow-up hardening).
- Avoid premature web update failure on slower servers.
- Restore user message image previews + fullscreen gallery navigation payload.
- Repair desktop chat drag-and-drop image attachments when native drop coords are missing.
- Move GitHub issue linking entry into Add attachment menu.
- Align header context usage percentage visuals with context panel.
- Align `@` file search with active project in all runtimes.
- Route `@` file discovery through OpenCode SDK `find.files`; remove legacy `/api/fs/search` reliance.
- Make chat `@` mention behavior consistent with files-style behavior.
- Keep status-row todos in stable order after status changes; add compact status icons; replace noisy priority labels.

## Refactors / UX Consistency
- Simplify chat attachment model and remove project file picker path.
- Keep composer focused on `@` mention file flow.
- Use direct `Attach files` action in VS Code instead of attachment dropdown path.
- Unify issue/PR picker behavior between desktop and mobile overlays.
2026-03-04 01:41:01 +02:00
shekohexandBohdan Triapitsyn ca18b8be0f feat(pwa): pre-install naming, install UX, and manifest shortcuts (#554)
* feat(web-pwa): add dynamic manifest endpoint with blob fallback

* feat(ui-pwa): add install prompt and manifest sync hooks

* feat(settings): add web-only preinstall app name preference

* fix(web-pwa): scope recent shortcuts to active project sessions

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-03-04 00:32:23 +02:00
Iuliia Ivashko d4269a1cc8 fix: harden terminal auth, skill file access, and sensitive request logging (#575)
* fix: enforce terminal websocket authentication on upgrade

* fix: block path traversal in skill supporting file APIs

* fix: redact voice token request logs

* fix: block skill file path traversal
2026-03-02 18:25:55 +02:00
Bohdan Triapitsyn b4cd16f55b feat(ui): polish chat and git workflows with mobile UX and reliability fixes (#569)
* feat: add chat option for user message rendering mode

* feat: add chat option to toggle sticky user header

* feat(ui): overhaul context panel with reusable tabs and embedded session chat

Enable parallel context workflows with persistent tabbed views and isolated session chat while reducing resize and background runtime overhead.

* feat: polish context panel and git sidebar tabs

Refined context panel tab behavior and visuals for smoother switching and resizing
Reused the new tabs component in right sidebar and git sidebar with fit layout
Improved git section spacing, selection controls, and bulk revert confirmation flow

* feat: open diff files in editor at changed lines

Add edit actions in diff views to open files at the first changed line
Support per-file open-in-editor from All Files headers and icon-only action in single-file view
Improve file jump UX with load-aware navigation and reduced visual blink during line targeting

* fix: stabilize pill tabs and prevent git commit pathspec failures

Unified sortable tab variants to match animated styling behavior with responsive spacing and cleaner sidebar chrome
Fixed active tab pill measurement so size/position recalculates correctly when dropdowns reopen
Commit API now filters stale file paths before staging to avoid pathspec errors on deleted files

* fix: align user message action row spacing and hover behavior

* fix: persist user message view preferences in settings

Save plain-text and sticky-header toggles to settings.json when changed
Restore both chat display preferences from settings.json on startup
Validate and accept both preference fields in the settings API

* fix: improve git and sidebar tab layout on mobile

* fix: refine mobile user message action row spacing

Show mobile user-message actions in a consistent external row for sticky and non-sticky modes
Tune button row height and vertical position to match both mobile variants
Reduce sticky-header gradient tail and tighten assistant gap after user messages

* fix: improve chat action hover zones and mobile top shadow logic

Expand desktop trigger area so user action buttons reveal across the full row
Add sticky-header phantom hover row so inline actions appear from the whole button lane
Hide chat top scroll shadow on mobile only when sticky user headers are enabled

* fix: remove commit message input scrollbar flicker

Added optional scrollbar class support to shared textarea wrapper.
Disabled overlay scrollbar for Git commit message input.
Kept auto-resize behavior while preventing one-line empty-state micro-scroll.

* feat: make model provider groups collapsible in selector

Add collapsible provider headers in the chat model dropdown
Persist expanded/collapsed provider state across sessions
Refine provider header UX with inline chevrons and no hover highlight

* feat: arrange chat settings into a compact two-column layout

Places User Message Rendering next to Mermaid Rendering.
Places Diff Layout next to Diff View Mode.
Reduces right-column spacing to better match other settings sections.

* fix: show worktree branch edit controls in draft sessions

Detect worktree mode from current directory when session metadata is not yet bound
Enable immediate branch rename UI in Git sidebar without session switching

* feat: add beta badge to side panel menu action
2026-03-02 02:11:33 +02:00
Bohdan Triapitsyn 8bfbed0e68 fix: harden self-update flow and improve chat message readability (#562)
* fix: resolve Windows CLI module loading on absolute paths

* fix: improve chat tool rows layout and timestamp readability

* fix: make web update restart more reliable

* fix: make web self-update detect package manager correctly
2026-03-01 01:21:01 +02:00
Nelson Pires a1f01cf5bd refactor(tts): consolidate TTS services under lib/tts with stable entrypoint (#551)
* refactor(tts): move service module into domain folder

* refactor(tts): move summarization helpers into domain folder

* refactor(tts): add module entrypoint exports

* docs(tts): add module documentation

* refactor(web): route TTS imports through tts entrypoint

* docs(agents): map TTS module documentation
2026-02-28 16:00:39 +02:00
Bohdan Triapitsyn 6eb5d1afa9 Fix Windows path/spawn regressions and session visibility (#552)
* Update OpenCode CLI detection

* fix(windows): handle cli file-url import and cmd shim spawn

Fixes #533 and #521.

* fix(windows): stabilize api path rewrite and session merge

Fixes #548.
2026-02-28 16:00:10 +02:00
Iuliia IvashkoandBrian-Hwang d5d0d35083 feat: redesign remote tunnel settings and named tunnel workflow (#546)
* feat: add Cloudflare Tunnel settings for desktop app

Add a 'Remote Tunnel' section in Settings (desktop-only) that lets users
start/stop a Cloudflare quick tunnel on demand, with auto-generated
password protection and a QR code for easy mobile access.

- Server: 4 new API endpoints (check/status/start/stop) reusing the
  existing cloudflare-tunnel module
- UI: TunnelSettings component with full state machine
  (checking → idle/not-available → starting → active → stopping)
- QR code rendered via the qrcode package for in-app display
- Hidden from VS Code extension (desktop/web only)

* fix: use ?token= instead of ?p= in tunnel password URLs

REST API endpoints were building passwordUrl with ?p=<token> but
SessionAuthGate reads the ?token= query param, causing QR code
auto-login to fail — the password was never extracted from the URL.

Standardize all three tunnel URL construction sites to use ?token=
so scanning the QR code correctly pre-fills and submits the password.

* feat: secure remote tunnel access with one-time connect links

* feat: redesign remote tunnel settings and access flow

* fix: cleaned up unused desktop close code path

* feat: overhaul named tunnel setup and persistence flow

* chore: align codemirror language dependency resolution

---------

Co-authored-by: Brian-Hwang <brian.hwang@cornelisnetworks.com>
2026-02-28 04:21:46 +02:00
Bohdan Triapitsyn 95c71789c4 Project actions: run commands from header on web + mobile, with SSH-forward URL opening (#542)
* feat: add project actions in header with reliable terminal run flow

- Add per-project Actions settings with icons, platform filters, and default action
- Run/stop actions from header using terminal tabs, including Ctrl+C then force-kill fallback
- Improve terminal UX with stable selection, resize handling, and smarter URL auto-open for localhost ports

* feat: add project actions UI with refined header dropdown behavior

* feat: add parent-session back button in chat

* fix: make web and desktop dev modes reliable and conflict-free

- Separate desktop and web dev ports to avoid collisions
- Add robust process-tree shutdown so Ctrl+C cleans sidecars
- Add true web HMR mode and keep service worker out of dev

* fix: linux safe scripts for dev

* feat: run project actions on web and add desktop SSH forward URL opening

* feat: add mobile project actions button with terminal tabs and tighter tab UI

* revert: remove experimental mobile terminal selection UI

* feat: show Add action button in header when empty

* fix: make retry countdown human-readable in status row

* fix: prevent nav rail actions from firing through overlays
2026-02-27 20:45:03 +02:00
shekohexandBohdan Triapitsyn 1d8ff97c95 feat(ui): add dynamic window title and sprite-based project/file icons (#529)
* feat(ui): add dynamic titles and sprite-based project/file icons

* feat(files): add viewer syntax fallback and tab file icons

* fix(files): restore file viewer highlighting and add diff file icons

* feat(git): add file icons and async file-viewer syntax fallback

* fix(files): force codemirror token colors in file viewer

* feat(files): add shiki view mode for file viewer

* fix(files): force codemirror parse after programmatic content updates

* feat(files): support markdown frontmatter preview

* feat(chat): use pierre diffs for tool previews

* feat(chat): add configurable beautiful-mermaid rendering

* feat(perf): virtualize chat rendering and add react-scan toggle

* feat(build): enable React Compiler in Vite React apps

* fix(chat): reduce rerenders from tooltips and streamed activity

* fix(ui): make MessageList React Compiler safe

* chore(ui): batch commit remaining pending ui updates

* fix: polish chat and diff preview rendering

- Keep Mermaid action buttons fixed while diagram content scrolls
- Align Diff All Files headers and match Git-style path truncation
- Default chat tool diffs to unified view with lightweight indicators disabled

* fix: preserve file tree expansion and delay git action label collapse

* fix: refine project icon controls in settings

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-02-27 20:03:42 +02:00
Nelson Pires d6b8f28e6f refactor(skills-catalog): formalize module entrypoint and consolidate server imports (#537)
* refactor(skills-catalog): add module entrypoint exports

* refactor(web): use skills-catalog module entrypoint import

* docs(skills-catalog): add module documentation

* docs(agents): add skills-catalog docs map entry
2026-02-27 14:40:43 +02:00
Jovines 17734a6c65 fix(notification): cache parentID from session events to fix subtask notification detection (#530) 2026-02-27 09:32:20 +02:00
shekohexandBohdan Triapitsyn 27321d454b feat(remote): add desktop SSH remote instances lifecycle and UX (#515)
* feat(remote): add desktop SSH remote instances lifecycle and settings UX

* fix(remote): cancel SSH modal connect and correct desktop runtime detection

* fix(remote): unblock ssh auth flow and disconnect on instance removal

* fix(remote-ssh): harden remote lifecycle, auth probing, and port forwarding reliability

Improve SSH remote stability by correctly handling authenticated external probes, accepting ControlMaster handoff behavior, making reconnect detection tunnel-aware, and applying extra forwards through the shared master connection with local listener validation.

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-02-26 20:26:12 +02:00
marco mereuandClaude Opus 4.6 dc0f9b3e62 Fix Windows compatibility: git status check, OpenCode spawn, path normalization, session merge (#527)
- Add isGitRepository check before getStatus() to prevent noisy errors on non-git directories
- Resolve npm shell wrapper shims on Windows so Bun can spawn OpenCode via node interpreter
- Add Win32PathFix middleware to normalize forward slashes to backslashes in directory params
- Merge sessions from all project directories on bare GET /session for Windows path compat

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:21:31 +02:00
nzlov 6ca2b0da05 feat(container): add Docker deployment and terminal shell fallback (#520)
* feat(container): add Docker deployment and terminal shell fallback

Add Docker runtime assets (Dockerfile, compose file, and entrypoint) to run OpenChamber in containers with persistent config/data mounts.

Improve terminal PTY startup reliability by probing multiple shell candidates and falling back automatically across Unix and Windows environments.

* fix: add OMO install env

* docs: add Docker Compose instructions to README
2026-02-26 20:13:23 +02:00
Bohdan Triapitsyn a1bd2bbab8 fix: make in-app web updates apply reliably in containers 2026-02-25 19:53:20 +02:00
Colin MollenhourandCopilot e02002bc9f feat(server): add OPENCODE_HOST env var for external OpenCode connections (#499)
* feat(server): add OPENCODE_HOST env var for external OpenCode connections

Allows specifying a full base URL (e.g. https://hostname:4096) for external
OpenCode connections, supporting custom hostnames and HTTPS. When set,
OPENCODE_HOST overrides OPENCODE_PORT. Malformed values are fatal at startup.

* docs: document OPENCODE_HOST env var in README and AGENTS

* Fatal error when OPENCODE_HOST has path, search or hash

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Colin Mollenhour <colin@mollenhour.com>

* fix(server): use external origin when re-probing OpenCode

---------

Signed-off-by: Colin Mollenhour <colin@mollenhour.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-25 19:42:32 +02:00
JovinesandJovines 7a151290be refactor(auth): migrate session storage to JWT with persistent secret (#508)
- Replace in-memory session Map with stateless JWT tokens
- Add jose library for JWT signing and verification
- Implement persistent JWT secret storage in ~/.config/openchamber
- Support OPENCODE_JWT_SECRET environment variable override
- Update SessionAuthGate and useServerSessionStatus hooks
- Remove session cleanup timer (JWTs are stateless)

Co-authored-by: Jovines <jovines@qq.com>
2026-02-25 19:40:28 +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
Bohdan Triapitsyn 9462ac8498 feat: add usage display mode options to settings update 2026-02-24 13:33:23 +02:00
Nelson PiresandBohdan Triapitsyn 7a11867a19 Unify utility model settings and align git generation (#486)
* refactor(api): extend git generation payload types

* refactor(settings): add git provider model fields

* feat(config): persist git provider model defaults

* feat(git-api): send provider and model ids

* fix(git-api): forward generation options in runtime

* feat(git-view): use configured model for commit generation

* feat(git-view): pass configured model for PR generation

* feat(vscode): forward model selection in git bridge payload

* feat(vscode): align PR generation with session model flow

* feat(web): resolve and generate git text with provider model

* refactor(settings): unify utility model picker across providers

* chore(settings): rename sidebar item to utility model

* fix(git-model): validate and auto-heal stale utility selections

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-02-24 10:23:57 +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