Skip to content

Desktop app experience: zero-friction startup with configurable sandboxing #348

@xingyaoww

Description

@xingyaoww

Summary

Design and implement a frictionless startup experience for agent-canvas where npm run dev works immediately without Docker, and users choose their backend configuration through the onboarding UI. A mini setup server bridges the gap between the browser frontend and Docker lifecycle management.

Core Idea

Today: A script detects Docker behind the scenes and picks a mode. npm run dev may fail if Docker isn't installed. Users have no visibility or control over backend selection.

Proposed: npm run dev always starts successfully (local backend, no Docker). The onboarding UI presents backend options — users can multi-select Local + Docker. A lightweight setup server (~100 lines) handles Docker lifecycle on behalf of the browser.

npm run dev
  → Frontend + Local Backend start immediately (always works)
  → Onboarding UI: user picks backend(s)
  → Mini Setup Server manages Docker on demand

Architecture

npm run dev
  ├── Vite dev server          :3001   (frontend)
  ├── Local agent-server       :18000  (via uvx, always started)
  ├── Automation backend       :18001  (via uvx)
  ├── Ingress proxy            :8000   (routes all traffic)
  ├── Mini Setup Server        :18099  ← NEW
  │    ├── GET  /setup/status     → Docker availability check
  │    ├── POST /setup/docker     → Start Docker backend
  │    └── DELETE /setup/docker   → Stop Docker backend
  │
  └── [spawned on demand by setup server]
       Docker agent-server     :18002  (containerized, sandboxed)

Why a setup server?

  • The frontend is a pure browser app — it cannot execute shell commands or start Docker
  • But the npm run dev Node.js process can — it already spawns uvx and Docker via child_process
  • The setup server is a tiny HTTP endpoint (~100 lines) that bridges the gap
  • It only listens on 127.0.0.1 — not exposed to the network
  • In a future Electron app, this role moves to the main process via IPC — same API surface

Onboarding Flow Change

The onboarding keeps its existing structure. The key change is that "Check Backend" becomes "Choose Backend" with multi-select support:

Step Current Proposed
0 Choose Agent Choose Agent (unchanged)
1 Check Backend Choose Backend (multi-select: Local + Docker)
2 Setup LLM Setup LLM (unchanged)
3 Say Hello Say Hello (unchanged)

Choose Backend — Multi-Select

Users can select one or both backends simultaneously:

  • Local Backend (default, always selected): Runs directly on the host. Zero-config, full filesystem access, confirmation mode on by default.
  • Docker Backend (optional): Runs in a container. Sandboxed, requires Docker, user provides workspace directory.

When Docker is selected, the frontend calls the setup server to spawn the container. Both backends appear in the backend dropdown.

Backend Comparison

Local Docker
Sandbox ✗ None ✓ Docker container
Confirmation Mode ✓ On by default Optional
File Access Entire filesystem Mounted directory only
Prerequisites None (uvx only) Docker Desktop
Setup Zero-config Provide workspace dir

Setup Server API

Endpoint Description
GET /setup/status Returns { dockerInstalled, dockerRunning, dockerBackendRunning, projectPath }
POST /setup/docker Body: { projectPath }. Starts Docker agent-server, returns { host, port }
DELETE /setup/docker Stops the Docker agent-server container

Implementation Plan

Phase 1 — Mini setup server + multi-select backend (this PR)

  1. Add scripts/setup-server.mjs — mini HTTP server for Docker lifecycle
  2. Wire setup server into dev-with-automation.mjs startup
  3. Update ChooseBackendStep to support multi-select (Local + Docker)
  4. Frontend calls setup server to start/stop Docker on demand
  5. npm run dev defaults to local mode (always works)

Phase 2 — Agent auto-discovery (upstream SDK + follow-up)

Phase 3 — Electron desktop app

  • Electron main process replaces setup server (IPC instead of HTTP)
  • OS-native sandboxing (Seatbelt on macOS)

Related


This issue was written by an AI agent (OpenHands) on behalf of the user.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions