A task-first web UI for ACP-compatible agents — Copilot CLI, Claude Code, Gemini CLI, and more.
The web UI is a thin wrapper: the browser client stays small because the substance lives in the server behind it, where work is organized as Tasks — durable units with their own history, attachments, working directory, lifecycle, and parent/child tree. Each Task is bound to an ACP session that executes it, so a Task survives its session being resumed, rotated (/clear), or replaced, and Tasks work with each other by creating children, sending durable messages, and handing work back. One instance can drive several named ACP agents at once: the agent a Task runs on is provenance you pick at creation or rotate later, never a separate scope, so a parent on one agent can dispatch to a child on another and still supervise it through the same tree. The same model is served as a documented REST + SSE API, so anything else you build can drive it too. Nothing leaves your machine.
Status: pre-1.0. WebAgent is under active development, so breaking changes ship whenever the contract needs them: configuration settings, REST/SSE fields and events, MCP tool names, and sometimes the database schema, which is not migrated before 1.0 — back up and reset
./data/when a release says so. Each release's changelog lists its breaking changes first, and the pre-1.0 reset policy covers the data side.
- Task-first, thin client — the browser is a thin wrapper over a server that treats the Task as the durable unit of work:
+api-fixcreates a named child Task,@api-fixopens it or sends it a message, and each Task keeps its history, working directory, and place in the tree while its agent session can be resumed, rotated, or replaced. - One file to configure —
webagent config initwrites a TOML with one[agents.<id>]table and adefault_agent;webagent --config config.tomlthen starts on port 6800, mints an admin token on first start, and persists everything in./data/. - Task-oriented API — everything the UI does is a documented REST + SSE API:
POST /api/v1/taskscreates a Task with a parent, title, cwd, and inherited model/mode, and every Task exposes its own event stream. Script it from CI or a cron job, or build your own client. See Server API. - Direct Task tools for agents (MCP) — when the agent supports MCP, WebAgent injects a scoped
lelouchhe_webagentMCP server into its session, so the agent itself getstask_create,task_send,task_update, bounded history lookup, and child cancellation. It creates and coordinates child Tasks on its own instead of asking you to relay. See Task MCP Control Plane. - Several agents, one workspace — configure any number of ACP CLIs as
[agents.<id>]; create a Task on any of them (/new copilot:~/repo,+copilot:docs) and switch an existing Task with/clear copilot:. A Task's agent is provenance, not a container: its history, attachments, cwd, and tree position survive the switch, and its children may run somewhere else. Dispatched work also runs unattended — the runtime answers a delegated turn's tool-permission requests and records every answer, while your own turns keep prompting exactly as before. See Multiple agents. - Multi-device, real-time — REST + SSE keeps Tasks, permissions, collaboration messages, and bash output synced. Approve a permission on your laptop, see it confirmed on your phone.
- Web Push notifications — Get pinged on
prompt_done,permission_request, orbash_donewhen the tab isn't focused. Smart per-task suppression: if any device is actively viewing Task X, no buzz from Task X. - PWA + mobile-friendly — Installable to iOS / Android home screen. Mobile-first input, attach via paste/upload, dark-mode native.
- Attachments — Drag, paste, or
^Uany file (images, code, PDFs, …). Server sniffs real MIME from content, so agents reliably read it. - Local file viewer —
/viewbrowses arbitrary local paths and renders Markdown, highlighted code/text, and images; mobile opens full-screen while desktop keeps chat in a split pane. - Inline bash —
!ls -laruns directly in your Task's cwd, output streams in real time, cancellable. - Tasks that survive everything — SQLite-persisted history, auto-resume on page open, auto-restore via ACP
loadTaskafter server restart, and context clearing that keeps the Task and its history intact. - Faithful ACP completion status — standard
cancelled,max_tokens,max_turn_requests, andrefusaloutcomes are shown as system notices; prompt errors are displayed and persisted without becoming assistant messages. - Rich slash menu —
/new,/switch,/view,/model,/mode,/think,/notify,/inbox,/share,/token,/log— autocomplete with Tab, submenus for pickable values. - Public share links —
/sharesnapshots a Task into a sanitized read-only viewer at/s/<token>for show-and-tell. - Daemon mode with crash recovery —
webagent startruns as a background service with PID file, log rotation, and exponential-backoff restart on crash. - Built-in security — Bearer token auth, per-device tokens, signed image URLs, strict CSP, single-operator threat model.
See Features for the full tour, and Known issues for the limits and deferred defects we know about.
|
|
+ creates a named child Task: title first, working directory optional.
|
@ addresses the Task family — a child, the parent, or a message to either.
|
More screenshots
Desktop chat: streamed output, tool calls, and diffs. |
Slash command autocomplete menu. |
Inline permission prompts, synced across devices. |
Prerequisites: Node.js 24+, an ACP-compatible agent installed and authenticated (Copilot CLI, Claude Code adapter, Gemini CLI, etc.).
npm install -g @lelouchhe/webagent
webagent config init # writes ./config.toml with one [agents.<id>] table
# edit it: set `cmd` to your ACP CLI, e.g. cmd = "copilot --acp"
webagent --config config.toml # runs on port 6800A config file is required: it names the agent (or agents) to launch and which one is the default. Every other setting has a default.
On first run, the server prints a one-time admin token in the startup
diagnostic. Open http://localhost:6800, paste the token into the
login form, done. The token persists in data/auth.json — subsequent
runs skip the prompt.
Other ways to start:
webagent start --config config.toml # background daemon (same first-run UX in your terminal)
webagent --create-token laptop # mint extra tokens for other devices / CIData (SQLite database, uploaded files) lives in ./data/ by default. See Configuration & Operations for daemon mode, TOML settings, and agent setup.
Browser ←── REST + SSE ──→ Server ←── ACP ──→ Agent CLI
(thin client) (Node.js) (copilot/claude/gemini)
The frontend is a standard browser client that talks to the server over REST + SSE. The API is the boundary — anyone can build their own client.
| Module | Role |
|---|---|
routes.ts |
REST API + static files (full API reference) |
event-handler.ts |
ACP event routing → SSE broadcast |
task-manager.ts |
Task state, buffers, bash processes |
bridge.ts |
ACP bridge — agent subprocess lifecycle |
store.ts |
SQLite persistence (WAL mode) |
daemon.ts |
Background service with crash recovery |
Tech stack: Node.js + TypeScript (--experimental-strip-types), SQLite (better-sqlite3), Zod validation, esbuild bundling.
Frontend source lives in public/js/*.ts, bundled by esbuild into a single content-hashed JS file. See Client Architecture.
| Document | Contents |
|---|---|
| Features | Chat, attachments, bash, tasks, slash commands, keyboard shortcuts, themes |
| Task UX | + creation, @ paths, autocomplete, navigation, and collaboration |
| Task Manual | Principles for using Tasks effectively |
| Task Examples | Short examples of direct work, delegation, handoff, and coordination |
| Task MCP Control Plane | Task tools, compact history, capability scope, and provider-schema compatibility |
| Task Obligations | Directed-dispatch closure: arming, accounts, state machine, budgets, and notices |
| Task Lifecycle | Task states, the transitions between them, and what each one keeps or drops |
| Vocabulary | Task vs ACP session naming, and the storage, API, and UI vocabulary contract |
| Configuration & Operations | TOML config, daemon commands, agent setup, upgrading |
| Security | Bearer auth, token storage, SSE ticket, signed image URLs, CSP, data layout |
| API Reference | REST endpoints, SSE events, implementation details |
| Attachments | Upload pipeline, on-disk layout, lifecycle, permission auto-approve, observability |
| ACP Integration | Client extensions, protocol scope, current limits |
| Client Architecture | Frontend modules, data flow, conventions |
| Streaming Render Performance | rAF coalescing, incremental lex, per-block memo, single-token fast path |
| Slash Menu | Walker pipeline, CmdNode tree, Tab/Enter/Click contract, how to add commands |
| Messages / Inbox | /inbox slash command, POST ingress, bound vs unbound messages |
| Share Links | Public read-only task snapshots via /share + /s/<token> |
| Database Schema | SQLite tables, indexes, FK policy, cascade/lifecycle rules, reset policy |
| Development | Building from source, dev mode, testing, publishing |
| Implementation Invariants | Runtime, security, protocol, frontend, browser, and platform constraints |
| Auto-Start on Boot | launchd, systemd, crontab, Windows Task Scheduler |






