* 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
## 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
* 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
## 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.
Route shared URL opening through VS Code host instead of webview window APIs
Add a VS Code runtime URL-open API and bridge handler using vscode.env.openExternal
Keep shared URL helper behavior unchanged for desktop and web
* fix: make textarea focus highlight render inside
Apply inset focus ring to shared textarea component
Prevent focus border from appearing clipped near container edges
* fix: build desktop sidecar with target-matched architecture
Map Tauri target triples to Bun compile targets
Pass explicit Bun compile target for sidecar builds
Prevent x86_64 releases from shipping arm64 sidecar binaries
* fix: allow Windows git custom binary paths
Enable safe use of resolved custom git executable paths
Prevent git status failures when path contains restricted characters
Keep default behavior unchanged for plain git invocations
* fix: allow toggling diff line wrap on mobile
Stops forcing wrapped lines in mobile diff view
Line-wrap button now reflects and applies user preference
* fix: align VS Code managed server env with shell settings
Import login-shell environment variables before starting managed OpenCode
Apply Windows and Unix shell snapshot resolution for parity
Improve proxy-dependent provider connectivity in VS Code extension
* fix: respect user scope when adding MCP servers
Prevent user-scope MCP entries from being written to project config
Keep project writes only for explicit project scope
* fix: show linked GitHub issues and PRs as user message attachments
Preserve synthetic issue/PR context parts during message filtering.
Convert synthetic GitHub context JSON into attachment-style user parts.
Open issue/PR attachment links via shared external URL helper.
* fix: restore and polish project notes in sessions sidebar
Restored the Notes button in the left sessions sidebar header
Improved notes panel layout with wider dialog, larger notes area, and project name in the header
Refined todo rows with inline expand/collapse text and stable action/checkbox alignment
* fix: hide sidebar footer actions in VS Code runtime
Remove Settings, About, and Shortcuts buttons from the sessions sidebar footer in VS Code
Keep update button behavior unchanged across runtimes
* fix: normalize Windows paths for VS Code session loading
Canonicalize drive-letter casing in session path normalization
Align VS Code workspace path persistence with the same Windows path format
Normalize client directory context before API calls to keep session filtering consistent
* fix: open linked GitHub attachments with shared URL helper
Use runtime-aware external URL opening for issue/PR attachment links.
Keep GitHub attachment labels readable without altering normal file name rendering.
* fix: keep user MCP config writes out of project files
Respect user scope when selecting config write target
Prevent MCP user entries from being written to project opencode.json
* fix: prevent project menu from overlapping new session button
Align project menu positioning for non-git and git project rows
Avoid kebab-menu and plus-button overlap in sessions sidebar
Replace the full-tree nuke-and-reload in refreshRoot() with a targeted
refreshDirectory(parentPath) that only evicts and reloads the single
parent directory whose contents changed.
Before: every create/rename/delete call cleared the entire childrenByDir
cache and reloaded only the root, causing all expanded subdirectories to
flash empty and visually reset.
After: only the parent directory of the affected entry is reloaded in-place;
every other expanded directory keeps its cached children, so the tree state
is preserved and there is no visible flash or scroll-position reset.
Applies to both FilesView and SidebarFilesTree.
When updating OpenChamber, stale openchamber-server processes from previous
versions can prevent the new version from starting. The app shows a loading
screen indefinitely with no error message.
This change adds a kill_stale_sidecar_processes() function that terminates
any existing openchamber-server processes before spawning a new one, ensuring
a clean startup every time.
- macOS/Linux: uses pkill -x for exact process name match
- Windows: uses taskkill /F /IM
Fixes startup issues after version updates.
* fix: allow native context menu on links in chat messages
The desktop app was blocking the context menu on all elements except
specific allowlisted ones (terminal, input, textarea, etc.). This
prevented users from right-clicking on HTTP links in chat messages
to access the 'Open Link' option.
Added 'a' (anchor) tag to the allowlist to restore native context
menu functionality for links.
Fixes#708
* fix: use tauri.shell.open for external links in desktop app
- Add global window.open override to init_script that routes HTTP/HTTPS
URLs through tauri.shell.open() instead of window.open()
- Add openExternalUrl utility that prefers tauri.shell.open with window.open fallback
- Add openExternalUrl to MarkdownRenderer for link safety.onLinkCheck
- Replace window.open with openExternalUrl in ProvidersPage for OAuth URLs
Fixes#708
* fix: unify external link opening across desktop and UI
Added a shared URL opener that only allows http/https links.
Replaced duplicated Tauri/window link-open logic in key UI sections.
Removed fragile desktop window.open override and markdown external-link modal behavior.
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
* fix(sidebar): show sessions in both Recent and Project sections
Previously, sessions displayed in the Recent section were filtered out of
their Project section (dedup logic). This meant users could only see a
session in one place, making it hard to find sessions within their project
context.
Now sessions appear in both:
- Recent section: with project name tag for quick identification
- Project section: in their normal grouped position
The project tag (secondaryMeta.projectLabel) was already implemented in
SessionNodeItem but never visible because the dedup logic removed sessions
from project sections before metadata could be populated.
Co-investigated-by: @huylamnguyen
* feat(sidebar): add collapse/expand all projects toggle
When many projects are open, collapsing them one by one is tedious. Add
'Collapse all' and 'Expand all' options to the sidebar display mode dropdown
menu (gear icon).
- Add collapseAllProjects/expandAllProjects callbacks in SessionSidebar
- Pass to SidebarHeader and render in the existing dropdown menu
- Persist collapsed state to localStorage and server settings
- Uses RiContractUpDownLine/RiExpandUpDownLine icons from Remixicon
Co-investigated-by: @huylamnguyen
* refactor: simplify session sidebar section rendering
Remove redundant filtered section aliases in SessionSidebar
Pass project and render sections directly for clearer code
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Show Update button in sidebar only when an update is available
Support update button on mobile sidebar and remove duplicate mobile Settings entry
Force desktop Tauri recheck and preflight before download to avoid missing pending updates
The desktop app builds and runs correctly on macOS Ventura (13.x).
Lowering minimumSystemVersion from 14.0 to 13.0 allows users on
Ventura to build and use the desktop app.
Co-authored-by: Craig Harman <craigharman@transdigital.com.au>
* 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
On Windows, VS Code's uri.fsPath returns a lowercase drive letter
(e.g. d:\MyProject) while the OpenCode server stores paths using
process.cwd() which returns uppercase (D:\MyProject). This caused
session queries to return empty results due to case-sensitive string
comparison.
Normalize drive letters to uppercase in both the VS Code extension
(opencode.ts) and the shared UI client (client.ts) so that directory
paths match regardless of the source casing.
Fixes#670
* feat(git): show current branch boundary in commit history
* style(git): round commit cards around branch divider
* style(git): refine branch divider visual boundary
packages/ui/src/components/chat/message/TextSelectionMenu.tsx
- What: Wrap selectedText in ```md fenced block before appending to composer.
- Why: Selections were appended as raw inline text with no visual distinction.
packages/ui/src/components/chat/ChatInput.tsx
- What: Replace trimEnd()/trim() + single-space join with raw prev + \n\n separator in append branch.
- Why: Existing composer newlines were being destroyed and multiple appends ran together.
packages/ui/src/components/session/ProjectNotesTodoPanel.tsx
- What: Wrap todoText in ```md fenced block before appending to composer.
- Why: Todo text sent to current session should have the same fenced formatting.
Reduce layout thrashing during virtual keyboard open/close on mobile by
batching resize and visualViewport event handlers to once per animation
frame. No visual or behavioral changes — desktop is unaffected.
- MainLayout: rAF-batch visualViewport resize/scroll and window resize
listeners (was firing 10-20x per frame during keyboard animation)
- Header: rAF-batch ResizeObserver and resize/orientationchange callbacks
- ChatContainer: rAF-batch ResizeObserver and resize fallback callbacks
- useDeviceInfo: 150ms debounce on resize listener (device type does not
change during keyboard transitions)
* 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
Add a new tunnels page with verified, up-to-date CLI examples
Remove deprecated `--daemon` usage and clarify QR/password behavior
Add docs validation tooling and docs-source workflow for packaging and sync
* fix: project label text hidden by selection overlay in dark mode
In NavRail's ProjectTile, the expanded active item renders an absolutely
positioned background overlay (--interactive-selection) that visually
covers the text label. The label span was missing 'relative z-10',
unlike NavRailActionButton which correctly uses it.
Fixes text being invisible on selected project in dark themes
(nord-dark, dracula-dark, monokai-dark, gruvbox-dark, etc.)
* feat: auto-save file editor with 1.5s debounce
Add debounced auto-save to the file editor so users no longer need to
manually save with Cmd/Ctrl+S or the save button. Files are automatically
saved 1.5 seconds after the user stops typing.
- Debounced auto-save effect that triggers on draft content changes
- Cmd/Ctrl+S still works for immediate save (cancels pending debounce)
- Updated save button UI with contextual status indicators:
'Saving...' spinner, 'Saved' checkmark, or save icon when dirty
- Reset auto-save status when switching between files
- Applied consistently to both normal and fullscreen editor views
In NavRail's ProjectTile, the expanded active item renders an absolutely
positioned background overlay (--interactive-selection) that visually
covers the text label. The label span was missing 'relative z-10',
unlike NavRailActionButton which correctly uses it.
Fixes text being invisible on selected project in dark themes
(nord-dark, dracula-dark, monokai-dark, gruvbox-dark, etc.)
* fix: polish activity tool rows and message spacing
Show each tool call as its own row in live and activity views
Keep tool descriptions inline with truncation and cleaner read-file paths
Tune spacing, todo counts, and bash timing display for clearer chat flow
* fix: refine activity tool rows and truncation behavior
Make activity collapse behavior consistent across modes and rename default mode label to Expanded
Show tool descriptions inline with improved spacing and one-row-per-tool rendering
Fix read/edit path truncation to clip from the start while keeping edit filenames highlighted
* fix: resolve chat activity lint regressions
Remove unused activity render mode state in message body
Mark path helper animation arg as intentionally unused to satisfy lint