* feat: implement desktop boot outcome architecture
- Add structured DesktopBootOutcome with target/status fields
- Implement boot outcome computation and validation
- Add desktop hosts configuration management (Tauri + TypeScript)
- Add desktop hosts probing with timeout and retry logic
- Support local/remote host classification and health checks
This provides the foundational infrastructure for desktop onboarding
flow to determine whether to show local setup, remote connection,
or recovery screens based on OpenCode availability and remote host
reachability.
* feat: add desktop onboarding UI components
Add comprehensive onboarding flow for desktop app:
- ChooserScreen: First-launch local/remote selection
- LocalSetupScreen: CLI installation guidance and manual detection
- RecoveryScreen: Recovery mode with routing to local/remote
- RemoteConnectionForm: Remote host connection with validation
- DesktopConnectionRecovery: Recovery variants and routing logic
- ConnectionSettingsPage: Manage remote connections
Components handle:
- Local vs remote choice persistence
- Recovery scenarios (unreachable, wrong-service, missing)
- Manual CLI detection (replaced auto-polling)
- Back navigation and state preservation
* feat: integrate desktop onboarding with app shell
- Update App.tsx to handle onboarding routing and recovery
- Add onboarding mode switching (first-launch/local-setup/recovery)
- Integrate desktop hosts in SettingsView
- Update DesktopHostSwitcher with recovery routing
- Add desktop shell utilities for onboarding detection
- Update web manifest for desktop app metadata
Completes the desktop onboarding feature integration,
allowing users to choose local or remote OpenCode on
first launch and recover from connection failures.
* fix: hide back button in remote connection form for first-launch chooser
In first-launch chooser mode, the back button is redundant since users
can simply click the "Local Install" tab. The back button is still shown
in recovery mode where there's no tab interface.
Changes:
- Add showBackButton prop to RemoteConnectionForm (default: true)
- Set showBackButton={false} in ChooserScreen remote tab
- Keep showBackButton={true} in RecoveryScreen for navigation
* refactor: remove Connection Settings page and simplify recovery UI
Remove the Connection Settings page as it was redundant:
- Local server is single-instance (no need to "choose")
- Remote servers are one-time setup (first-launch chooser)
- SSH Instances remain for multi-instance management
Changes:
- Remove ConnectionSettingsPage component and directory
- Remove 'connection' from Settings metadata
- Remove "Open Settings" button from recovery screens
- Remove desktopBootBypassToSettings state and logic
- Update recovery config to use 'local' icon instead of 'settings'
- Update tests to reflect removed showOpenSettings field
This simplifies the UX by focusing on:
- First-launch chooser for initial local/remote decision
- Remote Instances (SSH) for managing multiple remote machines
- No persistent "server management" needed for typical desktop usage
* fix: remove unused enableCliPolling prop and clean up TypeScript errors
Remove the obsolete enableCliPolling prop that was used for auto-
polling CLI detection. We replaced this with manual "Check and Continue"
button in a previous commit, so this prop is no longer needed.
Changes:
- Remove enableCliPolling from OnboardingScreen props and usage
- Remove enableCliPolling from App.tsx calls
- Remove unused 'connection' case from getSettingsNavIcon()
- Remove unused RiGlobalLine import
This resolves all TypeScript compilation errors reported by Copilot.
* fix: remove unused onChooseLocal prop and CLI_MISSING_ERROR_REGEX
These were left over from the refactoring:
- onChooseLocal in RecoveryScreen was defined but never used
- CLI_MISSING_ERROR_REGEX in App.tsx was leftover from removed enableCliPolling code
* fix: remove unused variables and fix React Hook dependency warnings
Remove unused memoized components and variables that were causing
lint errors in packages/ui:
- MainLayout.tsx: Remove unused MemoHeader, MemoChatView, MemoPlanView,
MemoGitView, MemoDiffView, MemoTerminalView, MemoFilesView,
MemoRightSidebarTabs, DesktopLeftSidebar, and DesktopRightPanel
- useGitHubPrStatusStore.ts: Remove unused prVisualPriority function
- useChatScrollManager.ts: Add missing markProgrammaticScroll dependency
to React.useEffect hook
These fixes resolve the CI lint failures in PR 850.
* chore: remove local claude settings from repo
* refactor(desktop): drop vibrancy code from onboarding PR
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Run OpenChamber and OpenCode as separate persistent services — useful when you want to access your
dev machine over a VPN (e.g. Tailscale) or LAN without a Cloudflare tunnel.
How it works:
OpenCode runs as its own service, binding only to localhost.
OpenChamber connects to it via OPENCODE_HOST and --host 0.0.0.0 makes it reachable on your VPN IP.
--foreground keeps the CLI process alive so systemd can track and restart it.
Why set PATH and SSH_AUTH_SOCK?
systemd user services start with a minimal environment — no shell profile is sourced.
Without an explicit PATH, OpenCode won't find tools installed via Homebrew, npm, or ~/.local/bin.
Without SSH_AUTH_SOCK, git operations over SSH (push, pull, clone) will fail because the agent socket isn't inherited.
Adjust the PATH to match your own tool installation paths.
%t expands to $XDG_RUNTIME_DIR (e.g. /run/user/1000), where most SSH agents write their socket.
OpenChamber will be reachable at http://<your-vpn-hostname>:3000 from any device on your VPN.
Note:--host 0.0.0.0 is required to listen on all interfaces. The default
bind address is 127.0.0.1 (localhost only). Use --host <ip> or
OPENCHAMBER_HOST=<ip> to bind to a specific interface instead.
Managed-local path note: OPENCHAMBER_TUNNEL_CONFIG must point to a path inside the container user home (/home/openchamber/...). If your Cloudflare config references a credentials JSON file, that file path must also be accessible inside the container (mount with volumes).
Tunnel behavior notes
OpenChamber supports one active tunnel per running instance (port).
Starting a tunnel with a different mode/provider on the same instance replaces the current tunnel.
Replacing or stopping a tunnel revokes existing connect links and invalidates remote tunnel sessions for that instance.
Connect links are one-time tokens; generating a new link revokes the previous unused link.
Data Directory Permission Note: The data/ directory is mounted into the container for persistent storage (config, sessions, SSH keys, workspaces). Before running, ensure the directory exists and has proper permissions:
My wife, who - with zero AI background - sat down with the app for the first time and built the firework celebration that plays on every successful push.
Every contributor who shaped this project with their PRs, ideas, and attention to detail.