Th0rgal/ios compat review (#37)
* Add hardcoded Google/Gemini OAuth credentials Use the same client credentials as Gemini CLI for seamless OAuth flow. This removes the need for GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET env vars. * Add iOS Settings view and first-launch setup flow - Add SetupSheet for configuring server URL on first launch - Add SettingsView for managing server URL and appearance - Add isConfigured flag to APIService to detect unconfigured state - Show setup sheet automatically when no server URL is configured * Add iOS global workspace state management - Add WorkspaceState singleton for shared workspace selection - Refactor ControlView to use global workspace state - Refactor FilesView with workspace picker in toolbar - Refactor HistoryView with workspace picker in toolbar - Refactor TerminalView with workspace picker and improved UI - Update Xcode project with new files * Add reusable EnvVarsEditor component and fix page scrolling - Extract EnvVarsEditor as reusable component with password masking - Refactor workspaces page to use EnvVarsEditor component - Refactor workspace-templates page to use EnvVarsEditor component - Fix workspace-templates page to use h-screen with overflow-hidden - Add min-h-0 to flex containers to enable proper internal scrolling - Environment and Init Script tabs now scroll internally * Improve workspace creation UX and build log auto-scroll - Auto-scroll build log to bottom when new content arrives - Fix chroot workspace creation to show correct building status immediately - Prevent status flicker by triggering build before closing dialog * Improve iOS control view empty state and input styling - Show workspace name in empty state subtitle - Distinguish between host and isolated workspaces - Refine input field alignment and padding * Add production security and self-hosting documentation - Add Section 10: TLS + Reverse Proxy setup (Caddy and Nginx examples) - Add Section 11: Authentication modes documentation (disabled, single tenant, multi-user) - Add Section 12: Dashboard configuration (web and iOS) - Add Section 13: OAuth provider setup information - Add Production Deployment Checklist * fix: wip * wip * Improve settings sync UX and fix failed mission display Settings page: - Add out-of-sync warning when Library and System settings differ - Add post-save modal prompting to restart OpenCode - Load both Library and System settings for comparison Control client: - Fix missionHistoryToItems to show "Failed" status for failed missions - Last assistant message now inherits mission's failed status - Show resume button for failed resumable missions * Fix: restore original URL on connection failure in SetupSheet Previously, SetupSheet.connectToServer() persisted the URL before validation. If the health check failed, the invalid URL remained in UserDefaults, causing the app to skip the setup flow on next launch and attempt to connect to an unreachable server. Now the original URL is restored on failure, matching the behavior in SettingsView.testConnection(). * Fix: restore queueLength on failed removal in ControlView The removeFromQueue function now properly saves and restores both queuedItems and queueLength on API error, matching the behavior of clearQueue. Previously only queuedItems was refreshed via loadQueueItems() while queueLength remained incorrectly decremented until the next SSE event. * Add selective encryption for template environment variables - Add lock/unlock icon to each env var row for encryption toggle - When locking, automatically hide value and show eye icon - Auto-enable encryption when key matches sensitive patterns - Backend selectively encrypts only keys in encrypted_keys array - Backwards compatible: detects encrypted values in legacy templates - Refactor workspaces page to use SWR for data fetching Frontend: - env-vars-editor.tsx: Add encrypted field, lock toggle, getEncryptedKeys() - api.ts: Add encrypted_keys to WorkspaceTemplate types - workspaces/page.tsx: Use SWR, pass encrypted_keys on save - workspace-templates/page.tsx: Load/save encrypted_keys Backend: - library/types.rs: Add encrypted_keys field to WorkspaceTemplate - library/mod.rs: Selective encryption logic + legacy detection - api/library.rs: Accept encrypted_keys in save request * Fix: Settings Cancel restores URL and queue ops refresh on error SettingsView: - Store original URL at view init and restore it on Cancel - Ensures Cancel properly discards unsaved changes including tested URLs ControlView: - Queue operations now refresh from server on error instead of restoring captured state, avoiding race conditions with concurrent operations * Fix: preserve undefined for encrypted_keys to enable auto-detection Passing `template.encrypted_keys || []` converted undefined to an empty array, which broke the auto-detection logic in toEnvRows. The nullish coalescing in `encryptedKeys?.includes(key) ?? secret` only falls back to `secret` when encryptedKeys is undefined, not when it's an empty array. * Add Queue button and fix SSE/desktop session handling - Dashboard: Show Queue button when agent is busy to allow message queuing - OpenCode: Fix SSE inactivity timeout to only reset on meaningful events, not heartbeats, preventing false timeout resets - Desktop: Deduplicate sessions by display to prevent showing duplicate entries - Docs: Add dashboard password to installation prerequisites * Fix race conditions in default agent selection and workspace creation - Fix default agent config being ignored: wait for config to finish loading before setting defaults to prevent race between agents and config SWR fetches - Fix workspace list not refreshing after build failure: move mutateWorkspaces call to immediately after createWorkspace, add try/catch around getWorkspace * Fix encryption lock icon and add skill content encryption - Fix lock icon showing unlocked for sensitive keys when encrypted_keys is empty: now falls back to auto-detection based on key name patterns - Add showEncryptionToggle prop to EnvVarsEditor to conditionally show encryption toggle (only for workspace templates) - Add skill content encryption with <encrypted>...</encrypted> tags - Update config pages with consistent styling and encryption support
This commit is contained in:
263
INSTALL.md
263
INSTALL.md
@@ -4,6 +4,15 @@ This is the installation approach currently used on a **dedicated Ubuntu 24.04 s
|
||||
|
||||
Open Agent is the orchestrator/UI backend. **It does not run model inference**; it delegates execution to an **OpenCode server** running locally (default `http://127.0.0.1:4096`).
|
||||
|
||||
> **For AI Agents**: Before starting this installation, ask the user to provide:
|
||||
> 1. **Server IP address** (e.g., `95.216.112.253`)
|
||||
> 2. **Domain name** pointing to that IP (e.g., `agent.example.com`)
|
||||
> 3. **SSH access** credentials or key path for the server
|
||||
> 4. **Library git repo URL** (or confirm using the template)
|
||||
> 5. **Dashboard password** to set for authentication (or offer to generate one)
|
||||
>
|
||||
> Verify you have SSH access before proceeding: `ssh root@<server-ip> "hostname"`
|
||||
|
||||
---
|
||||
|
||||
## 0) Assumptions
|
||||
@@ -15,6 +24,74 @@ Open Agent is the orchestrator/UI backend. **It does not run model inference**;
|
||||
- Open Agent bound to: `0.0.0.0:3000`
|
||||
- You have a Git repo for your **Library** (skills/tools/agents/rules/MCP configs)
|
||||
|
||||
> **Recommendation**: Unless you know exactly what you need, install **all components** in this guide:
|
||||
> - **Bun** (required for OpenCode plugins and Playwright MCP)
|
||||
> - **systemd-container + debootstrap** (for isolated container workspaces)
|
||||
> - **Desktop automation tools** (Xvfb, i3, Chromium, xdotool, etc.)
|
||||
> - **Reverse proxy with SSL** (Caddy or Nginx + Certbot)
|
||||
>
|
||||
> Skipping components may limit functionality. The full installation uses ~2-3 GB of disk space.
|
||||
|
||||
---
|
||||
|
||||
## 0.5) DNS & Domain Setup (before you begin)
|
||||
|
||||
Before starting the installation, ensure your domain is configured:
|
||||
|
||||
### 0.5.1 Point your domain to the server
|
||||
|
||||
Add an A record in your DNS provider:
|
||||
|
||||
```
|
||||
agent.yourdomain.com → A → YOUR_SERVER_IP
|
||||
```
|
||||
|
||||
Example with common providers:
|
||||
- **Cloudflare**: DNS → Add Record → Type: A, Name: `agent`, IPv4: `YOUR_SERVER_IP`
|
||||
- **Namecheap**: Advanced DNS → Add New Record → A Record
|
||||
- **Route53**: Create Record → Simple routing → A record
|
||||
|
||||
### 0.5.2 Verify DNS propagation
|
||||
|
||||
Wait for DNS to propagate (usually 1-15 minutes), then verify:
|
||||
|
||||
```bash
|
||||
# From your local machine
|
||||
dig +short agent.yourdomain.com
|
||||
# Should return your server IP
|
||||
|
||||
# Or use an online checker
|
||||
curl -s "https://dns.google/resolve?name=agent.yourdomain.com&type=A" | jq .
|
||||
```
|
||||
|
||||
### 0.5.3 SSH key for Library repo (if private)
|
||||
|
||||
If your Library repo is private, set up an SSH deploy key on the server:
|
||||
|
||||
```bash
|
||||
# On the server
|
||||
ssh-keygen -t ed25519 -C "openagent-server" -f /root/.ssh/openagent -N ""
|
||||
cat /root/.ssh/openagent.pub
|
||||
# Copy this public key
|
||||
```
|
||||
|
||||
Add the public key as a **deploy key** in your git provider:
|
||||
- **GitHub**: Repository → Settings → Deploy keys → Add deploy key
|
||||
- **GitLab**: Repository → Settings → Repository → Deploy keys
|
||||
|
||||
Configure SSH to use the key:
|
||||
|
||||
```bash
|
||||
cat >> /root/.ssh/config <<'EOF'
|
||||
Host github.com
|
||||
IdentityFile /root/.ssh/openagent
|
||||
IdentitiesOnly yes
|
||||
EOF
|
||||
|
||||
# Test the connection
|
||||
ssh -T git@github.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1) Install base OS dependencies
|
||||
@@ -26,19 +103,19 @@ apt install -y \
|
||||
build-essential pkg-config libssl-dev
|
||||
```
|
||||
|
||||
If you plan to use container workspaces (systemd-nspawn), also install:
|
||||
**Container workspaces** (systemd-nspawn) — recommended for isolated environments:
|
||||
|
||||
```bash
|
||||
apt install -y systemd-container debootstrap
|
||||
```
|
||||
|
||||
If you plan to use **desktop automation** tools (Xvfb/i3/Chromium screenshots/OCR), install:
|
||||
**Desktop automation** (Xvfb/i3/Chromium screenshots/OCR) — recommended for browser control:
|
||||
|
||||
```bash
|
||||
apt install -y xvfb i3 x11-utils xdotool scrot imagemagick chromium chromium-sandbox tesseract-ocr
|
||||
```
|
||||
|
||||
See `docs/DESKTOP_SETUP.md` for a full checklist and i3 config recommendations.
|
||||
See `docs/DESKTOP_SETUP.md` for i3 config and additional setup after installation.
|
||||
|
||||
---
|
||||
|
||||
@@ -510,9 +587,179 @@ systemctl restart opencode.service
|
||||
curl -fsSL http://127.0.0.1:4096/global/health | jq .
|
||||
```
|
||||
|
||||
## Suggested improvements
|
||||
## 10) Production Security (TLS + Reverse Proxy)
|
||||
|
||||
- Put Open Agent behind a reverse proxy (Caddy/Nginx) with TLS and restrict who can reach `:3000`.
|
||||
- Set `DEV_MODE=false` in production and use strong JWT secrets / multi-user auth.
|
||||
- Run OpenCode on localhost only (already recommended) and keep it firewalled.
|
||||
- Pin OpenCode/plugin versions for reproducible deployments.
|
||||
For production deployments, **always** put Open Agent behind a reverse proxy with TLS. The backend serves HTTP only and should never be exposed directly to the internet.
|
||||
|
||||
### 10.1 Caddy (recommended - automatic HTTPS)
|
||||
|
||||
Caddy automatically obtains and renews Let's Encrypt certificates.
|
||||
|
||||
Install Caddy:
|
||||
|
||||
```bash
|
||||
apt install -y debian-keyring debian-archive-keyring apt-transport-https
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
|
||||
apt update && apt install caddy
|
||||
```
|
||||
|
||||
Create `/etc/caddy/Caddyfile`:
|
||||
|
||||
```
|
||||
agent.yourdomain.com {
|
||||
reverse_proxy localhost:3000
|
||||
}
|
||||
```
|
||||
|
||||
Enable and start:
|
||||
|
||||
```bash
|
||||
systemctl enable --now caddy
|
||||
```
|
||||
|
||||
Caddy will automatically obtain TLS certificates for your domain.
|
||||
|
||||
### 10.2 Nginx (manual certificate setup)
|
||||
|
||||
Install Nginx and Certbot:
|
||||
|
||||
```bash
|
||||
apt install -y nginx certbot python3-certbot-nginx
|
||||
```
|
||||
|
||||
Create `/etc/nginx/sites-available/openagent`:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name agent.yourdomain.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# SSE support (for mission streaming)
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_read_timeout 86400s;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Enable the site and obtain certificates:
|
||||
|
||||
```bash
|
||||
ln -s /etc/nginx/sites-available/openagent /etc/nginx/sites-enabled/
|
||||
nginx -t && systemctl reload nginx
|
||||
certbot --nginx -d agent.yourdomain.com
|
||||
```
|
||||
|
||||
### 10.3 Firewall
|
||||
|
||||
Block direct access to port 3000 from the internet:
|
||||
|
||||
```bash
|
||||
# Allow only localhost to reach Open Agent directly
|
||||
iptables -A INPUT -p tcp --dport 3000 -s 127.0.0.1 -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport 3000 -j DROP
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11) Authentication Modes
|
||||
|
||||
Open Agent supports three authentication modes:
|
||||
|
||||
| Mode | Environment Variables | Use Case |
|
||||
|------|----------------------|----------|
|
||||
| **Disabled** | `DEV_MODE=true` | Local development only |
|
||||
| **Single Tenant** | `DASHBOARD_PASSWORD`, `JWT_SECRET` | Personal server, one user |
|
||||
| **Multi-User** | `OPEN_AGENT_USERS`, `JWT_SECRET` | Shared server, multiple users |
|
||||
|
||||
### 11.1 Single Tenant (default for production)
|
||||
|
||||
Set a strong password and JWT secret:
|
||||
|
||||
```bash
|
||||
# Generate a random JWT secret
|
||||
JWT_SECRET=$(openssl rand -base64 32)
|
||||
|
||||
# In /etc/open_agent/open_agent.env:
|
||||
DEV_MODE=false
|
||||
DASHBOARD_PASSWORD=your-strong-password-here
|
||||
JWT_SECRET=$JWT_SECRET
|
||||
JWT_TTL_DAYS=30
|
||||
```
|
||||
|
||||
### 11.2 Multi-User Mode
|
||||
|
||||
For multiple users with separate credentials:
|
||||
|
||||
```bash
|
||||
# In /etc/open_agent/open_agent.env:
|
||||
DEV_MODE=false
|
||||
OPEN_AGENT_USERS='[
|
||||
{"username": "alice", "password": "alice-strong-password"},
|
||||
{"username": "bob", "password": "bob-strong-password"}
|
||||
]'
|
||||
JWT_SECRET=$(openssl rand -base64 32)
|
||||
```
|
||||
|
||||
Note: Multi-user mode provides separate login credentials but does **not** provide workspace or data isolation between users. All users see the same missions and workspaces.
|
||||
|
||||
---
|
||||
|
||||
## 12) Dashboard Configuration
|
||||
|
||||
### 12.1 Web Dashboard
|
||||
|
||||
The web dashboard auto-detects the backend URL. For production, set the environment variable:
|
||||
|
||||
```bash
|
||||
# When building/running the Next.js dashboard
|
||||
NEXT_PUBLIC_API_URL=https://agent.yourdomain.com
|
||||
```
|
||||
|
||||
Or configure it at runtime via the Settings page.
|
||||
|
||||
### 12.2 iOS App
|
||||
|
||||
On first launch, the iOS app prompts for the server URL. Enter your production URL (e.g., `https://agent.yourdomain.com`).
|
||||
|
||||
To change later: **Menu (⋮) → Settings**
|
||||
|
||||
---
|
||||
|
||||
## 13) OAuth Provider Setup
|
||||
|
||||
Open Agent uses OAuth for AI provider authentication. The following providers are pre-configured:
|
||||
|
||||
| Provider | OAuth Client | Setup Required |
|
||||
|----------|-------------|----------------|
|
||||
| **Anthropic** | OpenCode's client | None (works out of the box) |
|
||||
| **OpenAI** | Codex CLI client | None (works out of the box) |
|
||||
| **Google/Gemini** | Gemini CLI client | Install `opencode-gemini-auth` plugin |
|
||||
|
||||
OAuth flows use copy-paste for the authorization code. The user:
|
||||
1. Clicks "Authorize" in the dashboard
|
||||
2. Completes OAuth in their browser
|
||||
3. Copies the redirect URL back to the dashboard
|
||||
|
||||
---
|
||||
|
||||
## Checklist for Production Deployment
|
||||
|
||||
- [ ] Set `DEV_MODE=false`
|
||||
- [ ] Set strong `DASHBOARD_PASSWORD` and `JWT_SECRET`
|
||||
- [ ] Configure reverse proxy (Caddy or Nginx) with TLS
|
||||
- [ ] Firewall port 3000 (only allow localhost)
|
||||
- [ ] Pin OpenCode version for stability
|
||||
- [ ] Set up your Library git repo
|
||||
- [ ] Test OAuth flows for AI providers
|
||||
|
||||
Reference in New Issue
Block a user