* feat(cli): add --foreground flag for systemd and process manager deployments Adds --foreground / --no-daemon to `openchamber serve` which runs the server inline in the CLI process instead of spawning a detached daemon child. Required for systemd Type=simple (and other process managers) that track the direct child — the always-daemon behavior introduced in #640 broke this use case. Also documents OPENCHAMBER_HOST (bind address) in --help, which was implemented but never exposed to users. * docs: add systemd service guide for VPN/LAN deployments Documents how to run OpenCode and OpenChamber as separate systemd user services for persistent access over Tailscale or LAN, using the new --foreground flag and OPENCODE_HOST to wire them together. * fix(cli): address foreground mode parity issues from PR review - Fix Ctrl+C handling: CLI SIGINT handler now defers to server in foreground mode; dedicated signal handlers perform graceful shutdown and clean exit - Restore lifecycle parity: foreground instances write PID/instance files so status, stop, and restart can discover them - Add deterministic --foreground --json output: emits stable startup JSON with port, pid, url, and foreground flag before blocking * fix(cli): tighten inline foreground behavior for restart UX and JSON-only output * fix(cli): pass --host to foreground server, reject --json, add --quiet output - Pass options.host through to startWebUiServer() in foreground mode so the bind address is respected (fixes localhost-only regression from #750) - Reject --foreground --json with a clear usage error; --json is only supported in background (daemon) mode - Emit resolved port on stdout in --quiet foreground mode, matching daemon parity - Update systemd docs to include --host 0.0.0.0 for LAN/VPN access now that the default bind is 127.0.0.1 * fix(cli): remove duplicate OPENCHAMBER_HOST entry from help text * fix(cli): emit restart summary before foreground serve() blocks restart --json (and --quiet / human) with a foreground instance would hang forever without output because serve() blocks and the post-loop summary was unreachable. Emit the final output after stop succeeds but before the blocking serve call — foreground is always sorted last so all daemon results are already collected. * fix(cli): restart stops foreground instances without re-attaching Foreground instances are managed by a process manager (systemd, Docker, etc.) that will restart them automatically. The restart command now just stops the foreground instance, records the result, and exits — no serve() call, no blocking. This makes restart --json and all other output modes work correctly for foreground instances.
399 lines
19 KiB
Markdown
399 lines
19 KiB
Markdown
# <picture><source media="(prefers-color-scheme: dark)" srcset="docs/references/badges/openchamber-logo-dark.svg"><img src="docs/references/badges/openchamber-logo-light.svg" width="32" height="32" align="absmiddle" /></picture> OpenChamber
|
|
|
|
[](https://github.com/btriapitsyn/openchamber/stargazers)
|
|
[](https://github.com/btriapitsyn/openchamber/releases/latest)
|
|
[](https://opencode.ai)
|
|
[](https://discord.gg/ZYRSdnwwKA)
|
|
[](https://ko-fi.com/G2G41SAWNS)
|
|
|
|
## **OpenCode, everywhere.** Desktop. Browser. Phone.
|
|
|
|
### A rich interface for [OpenCode](https://opencode.ai). Review diffs, manage agents, run dev servers, and keep the big picture while your AI codes.
|
|
|
|

|
|
|
|
<details>
|
|
<summary>More screenshots</summary>
|
|
|
|

|
|

|
|

|
|

|
|

|
|
|
|
<p>
|
|
<img src="docs/references/pwa_chat_example.png" width="45%" alt="PWA Chat">
|
|
<img src="docs/references/pwa_diff_example.png" width="45%" alt="PWA Diff">
|
|
</p>
|
|
|
|
</details>
|
|
|
|
## Why use OpenChamber?
|
|
|
|
- **Cross-device continuity**: Start in TUI, continue on tablet/phone, return to terminal - same session
|
|
- **Remote access**: Use OpenCode from anywhere via browser
|
|
- **Familiarity**: A visual alternative for developers who prefer GUI workflows
|
|
|
|
## Features
|
|
|
|
### Core (all app versions)
|
|
|
|
- Branchable chat timeline with `/undo`, `/redo`, and one-click forks from earlier turns
|
|
- Smart tool UIs for diffs, file operations, permissions, and long-running task progress
|
|
- Voice mode with speech input and read-aloud responses for hands-free workflows
|
|
- Multi-agent runs from one prompt with isolated worktrees for safe side-by-side comparisons
|
|
- Git workflows in-app: identities, commits, PR creation, checks, and merge actions
|
|
- GitHub-native workflows: start sessions from issues and pull requests with context already attached
|
|
- Plan/Build mode with a dedicated plan view for drafting and iterating implementation steps
|
|
- Inline comment drafts on diffs, files, and plans that can be sent back to the agent
|
|
- Context visibility tools (token/cost breakdowns, raw message inspection, and activity summaries)
|
|
- Integrated terminal with per-directory sessions and stable performance on heavy output
|
|
- Built-in skills catalog and local skill management for reusable automation workflows
|
|
|
|
### Web / PWA
|
|
|
|
- Provider-aware tunnel access model with Cloudflare `quick`, `managed-remote`, and `managed-local` modes
|
|
- One-scan onboarding with tunnel QR + password URL helpers
|
|
- Mobile-first experience: optimized chat controls, keyboard-safe layouts, and attachment-friendly UI
|
|
- Background notifications plus reliable cross-tab session activity tracking
|
|
- Built-in self-update + restart flow that keeps your server settings intact
|
|
|
|
### Desktop (macOS)
|
|
|
|
- Native macOS menu integration with polished app actions and deep-link handling
|
|
- Multi-window support for parallel project/session workflows
|
|
- "Open In" shortcuts for Finder, Terminal, and your preferred editor
|
|
- Fast switching between local and remote instances
|
|
- Workspace-first startup flow with directory picker and steadier window restore behavior
|
|
|
|
### VS Code Extension
|
|
|
|
- Editor-native workflow: open files directly from tool output and keep sessions beside your code
|
|
- Agent Manager for parallel multi-model runs from a single prompt
|
|
- Right-click actions to add context, explain selections, and improve code in-place
|
|
- In-extension settings, responsive layout, and theme mapping that matches your editor
|
|
- Hardened runtime lifecycle and health checks for faster startup and fewer stuck reconnect states
|
|
|
|
### Custom Themes
|
|
|
|
- **Use it from anywhere** - Cloudflare tunnel with QR code onboarding. Scan, connect, code from your couch.
|
|
- **Branchable chat timeline** - Undo, redo, fork from any turn. Explore different approaches without losing your place.
|
|
- **GitHub-native workflows** - Start sessions from issues and PRs with context already attached. Review checks, merge - all in-app.
|
|
- **Project Actions** - Run dev servers, configure SSH port forwarding, open remote URLs locally. Your project commands, one click away.
|
|
- **Connect to remote machines** - Desktop app connects to remote OpenChamber instances over SSH, with dedicated lifecycle and UX flows.
|
|
|
|
## Quick Start
|
|
|
|
> **Prerequisite:** [OpenCode CLI](https://opencode.ai) installed.
|
|
|
|
### **Desktop (macOS)**
|
|
Download from [Releases](https://github.com/btriapitsyn/openchamber/releases).
|
|
|
|
### **VS Code**
|
|
Install from [Marketplace](https://marketplace.visualstudio.com/items?itemName=fedaykindev.openchamber) or search "OpenChamber" in Extensions.
|
|
|
|
### **CLI (Web + PWA)**
|
|
_requires Node.js 20+_
|
|
|
|
```bash
|
|
curl -fsSL https://raw.githubusercontent.com/btriapitsyn/openchamber/main/scripts/install.sh | bash
|
|
openchamber --ui-password be-creative-here
|
|
```
|
|
|
|
<details>
|
|
<summary>Advanced CLI options</summary>
|
|
|
|
```bash
|
|
openchamber --port 8080 # Custom port
|
|
openchamber --ui-password secret # Password-protect UI
|
|
openchamber tunnel help # Tunnel lifecycle commands
|
|
openchamber tunnel providers # Show provider capabilities
|
|
openchamber tunnel profile add --provider cloudflare --mode managed-remote --name prod-main --hostname app.example.com --token <token>
|
|
openchamber tunnel start --profile prod-main
|
|
openchamber tunnel start --provider cloudflare --mode quick --qr
|
|
openchamber tunnel start --provider cloudflare --mode managed-local --config ~/.cloudflared/config.yml
|
|
openchamber tunnel status --all # Show tunnel state across instances
|
|
openchamber tunnel stop --port 3000 # Stop tunnel only (server stays running)
|
|
openchamber logs # Follow latest instance logs
|
|
OPENCODE_PORT=4096 OPENCODE_SKIP_START=true openchamber # Connect to external OpenCode server
|
|
OPENCODE_HOST=https://myhost:4096 OPENCODE_SKIP_START=true openchamber # Connect via custom host/HTTPS
|
|
openchamber stop # Stop server
|
|
openchamber update # Update to latest
|
|
```
|
|
|
|
Connect to an existing OpenCode server:
|
|
```bash
|
|
OPENCODE_PORT=4096 OPENCODE_SKIP_START=true openchamber
|
|
OPENCODE_HOST=https://myhost:4096 OPENCODE_SKIP_START=true openchamber
|
|
```
|
|
|
|
Bind managed OpenCode server to all interfaces (use only on trusted networks):
|
|
```bash
|
|
OPENCHAMBER_OPENCODE_HOSTNAME=0.0.0.0 openchamber --port 3000
|
|
```
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary>systemd service (VPN / LAN access)</summary>
|
|
|
|
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.
|
|
|
|
**`~/.config/systemd/user/opencode.service`**
|
|
```ini
|
|
[Unit]
|
|
Description=OpenCode Server
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=opencode serve --port 4095
|
|
Environment="PATH=/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/home/YOU/.local/bin:/home/YOU/.npm-global/bin:/usr/local/bin:/usr/bin:/bin"
|
|
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
```
|
|
|
|
> **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.
|
|
|
|
**`~/.config/systemd/user/openchamber.service`**
|
|
```ini
|
|
[Unit]
|
|
Description=OpenChamber Web Server
|
|
After=opencode.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=openchamber serve --port 3000 --host 0.0.0.0 --ui-password your-password --foreground
|
|
Environment="OPENCODE_HOST=http://localhost:4095"
|
|
Environment="OPENCODE_SKIP_START=true"
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
```
|
|
|
|
```bash
|
|
systemctl --user daemon-reload
|
|
systemctl --user enable --now opencode openchamber
|
|
```
|
|
|
|
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.
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary>Docker</summary>
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
Available at `http://localhost:3000`.
|
|
|
|
**UI Password:**
|
|
```yaml
|
|
environment:
|
|
UI_PASSWORD: your_secure_password
|
|
```
|
|
|
|
**Cloudflare Tunnel (optional):**
|
|
```yaml
|
|
environment:
|
|
OPENCHAMBER_TUNNEL_MODE: quick # quick | managed-remote | managed-local
|
|
OPENCHAMBER_TUNNEL_PROVIDER: cloudflare
|
|
```
|
|
|
|
For `managed-remote` mode, provide:
|
|
|
|
```yaml
|
|
environment:
|
|
OPENCHAMBER_TUNNEL_MODE: managed-remote
|
|
OPENCHAMBER_TUNNEL_HOSTNAME: app.example.com
|
|
OPENCHAMBER_TUNNEL_TOKEN: <token>
|
|
```
|
|
|
|
For `managed-local` mode, optionally provide:
|
|
|
|
```yaml
|
|
environment:
|
|
OPENCHAMBER_TUNNEL_MODE: managed-local
|
|
OPENCHAMBER_TUNNEL_CONFIG: /home/openchamber/.cloudflared/config.yml
|
|
```
|
|
|
|
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:
|
|
|
|
```bash
|
|
mkdir -p data/openchamber data/opencode/share data/opencode/config data/ssh
|
|
chown -R 1000:1000 data/
|
|
```
|
|
|
|
**SSH/Git:** If git push/pull fails, run `ssh -T git@github.com` in terminal.
|
|
|
|
</details>
|
|
|
|
|
|
## Features
|
|
|
|
<details>
|
|
<summary><strong>Chat & Interaction</strong></summary>
|
|
|
|
- Branchable chat timeline with `/undo`, `/redo`, and one-click forks from any turn
|
|
- Multi-agent runs from one prompt with isolated worktrees for safe side-by-side comparisons
|
|
- Voice mode with speech input and read-aloud responses for hands-free workflows
|
|
- Plan/Build mode with a dedicated plan view for drafting and iterating steps
|
|
- Inline comment drafts on diffs, files, and plans - send feedback back to the agent
|
|
- Shell mode via leading `!` with inline output
|
|
- Share messages as images
|
|
- Mermaid diagrams render inline with copy/download actions
|
|
- Smart tool UIs for diffs, file operations, permissions, and task progress
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary><strong>Git & GitHub</strong></summary>
|
|
|
|
- Full Git sidebar with staging, commits, push/pull, branch management, and rebase/merge flows
|
|
- PR creation with AI-generated descriptions, status checks, and merge actions
|
|
- Start sessions from GitHub issues and pull requests with context baked in
|
|
- Multi-remote push and fork-aware PR creation
|
|
- Worktree integration: isolated sessions per branch, merge back with conflict handling
|
|
- Git identities, gitmoji support, and multi-account GitHub auth
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary><strong>Files, Diff & Terminal</strong></summary>
|
|
|
|
- Workspace file browser with inline editing, syntax highlighting, and markdown preview
|
|
- Beautiful diff viewer with stacked/inline modes, lazy loading for large changesets
|
|
- Integrated terminal with per-directory sessions, tabbed interface, and stable heavy-output performance
|
|
- Clickable file paths in messages - jump to exact line locations
|
|
- File-type icons across all views for faster visual scanning
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary><strong>Web / PWA</strong></summary>
|
|
|
|
- Cloudflare tunnel with quick, managed-remote, and managed-local modes, secure one-time connect links, and QR onboarding
|
|
- Mobile-first: optimized chat controls, keyboard-safe layouts, drag-to-reorder projects
|
|
- Background notifications and cross-tab session tracking
|
|
- Self-update + restart flow that keeps your server settings intact
|
|
- Installable as PWA with project-aware naming
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary><strong>Desktop (macOS)</strong></summary>
|
|
|
|
- Connect to remote OpenChamber instances over SSH with dedicated lifecycle flows
|
|
- Project Actions: run dev servers, SSH port forwarding, open remote URLs locally
|
|
- Multi-window support for parallel project workflows
|
|
- "Open In" shortcuts for Finder, Terminal, and your preferred editor
|
|
- Fast switching between local and remote instances
|
|
- Native macOS menu, deep-link handling, and polished startup
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary><strong>VS Code Extension</strong></summary>
|
|
|
|
- Editor-native: open files from tool output, keep sessions beside your code
|
|
- Agent Manager for parallel multi-model runs from a single prompt
|
|
- Right-click actions: add context, explain selections, improve code in-place
|
|
- Session editor panel, responsive layout, and theme mapping to your editor
|
|
- Edit-style tool results open directly in focused diff views
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary><strong>Customization</strong></summary>
|
|
|
|
- 18+ built-in themes with light/dark variants
|
|
- Custom themes via JSON files in `~/.config/openchamber/themes/` - hot reload, no restart
|
|
- Configurable keyboard shortcuts for chat, panels, and services
|
|
- Font size, spacing, corner radius, and layout controls
|
|
- Customizable project icons with upload and automatic favicon discovery
|
|
- Skills catalog and local skill management for reusable automation
|
|
|
|
[Read the Guide: Custom Themes](docs/CUSTOM_THEMES.md)
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary><strong>Context & Productivity</strong></summary>
|
|
|
|
- Token usage, cost breakdowns, and raw message inspection panel
|
|
- Usage quota tracking across multiple providers with pace/prediction indicators
|
|
- Favorite model cycling via keyboard shortcuts
|
|
- Session folders and subfolders with drag-to-reorder
|
|
- Persistent project notes and todos per project
|
|
- Draft persistence per session with expanded focus mode for longer prompts
|
|
|
|
</details>
|
|
|
|
## Roadmap
|
|
|
|
Active development. Here's what's being worked on or planned:
|
|
|
|
- Windows and Linux desktop apps
|
|
- Mobile app with remote instance and laptop connectivity
|
|
- More built-in tunneling options
|
|
- Kanban board for multi-agent management - keeping the human in the loop and in control
|
|
- Custom OpenCode plugins/tools built-in catalog
|
|
- Linear integration
|
|
- Built-in browser for running dev apps with agent integration
|
|
|
|
## Acknowledgments
|
|
|
|
Independent project, not affiliated with the OpenCode team.
|
|
|
|
**Special thanks to:**
|
|
|
|
- [OpenCode](https://opencode.ai) - For the excellent API and extensible architecture.
|
|
- [Flexoki](https://github.com/kepano/flexoki) - Beautiful color scheme by [Steph Ango](https://stephango.com/flexoki).
|
|
- [Pierre](https://pierrejs-docs.vercel.app/) - Fast, beautiful diff viewer with syntax highlighting.
|
|
- [Tauri](https://github.com/tauri-apps/tauri) - Desktop application framework.
|
|
- [Ghostty-web](https://github.com/coder/ghostty-web) - Great implementation of a Ghostty web renderer.
|
|
- [David Hill](https://x.com/iamdavidhill) - Who inspired me to release this without [overthinking](https://x.com/iamdavidhill/status/1993648326450020746).
|
|
- [My wife](https://github.com/yulia-ivashko), 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.
|
|
|
|
## Contributing
|
|
|
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup and guidelines.
|
|
|
|
Docs source lives in [`packages/docs`](packages/docs/README.md).
|
|
|
|
## License
|
|
|
|
MIT
|