Files
PiAgentUI/README.md
T
evandro 8ce05620e0
Deploy to GitHub Pages / build (push) Failing after 6m12s
Deploy to GitHub Pages / deploy (push) Skipped
Build Validation / validate (push) Successful in 13m29s
docs(readme): padroniza README (hero, badges, quickstart, arquitetura)
2026-10-24 04:12:59 +00:00

199 lines
12 KiB
Markdown

<div align="center">
<img src="./assets/app-icons/app-icon.svg" width="96" alt="PiAgentUI logo" />
<h1>PiAgentUI</h1>
<p><strong>Desktop and web workspace for AI coding agents: streams real Pi Agent sessions with chat, tool cards, MCP and skills panels.</strong></p>
<a href="#-quickstart">Quickstart</a> ·
<a href="#-architecture">Architecture</a> ·
<a href="#-documentation">Docs</a> ·
<a href="https://git.evandro.dev.br/evandro/PiAgentUI/issues">Issues</a>
![Stack](https://img.shields.io/badge/Stack-Tauri%20%2B%20TypeScript-24C8DB?logo=tauri&logoColor=white)
![Status](https://img.shields.io/badge/status-beta%200.6.10-yellow)
![License](https://img.shields.io/badge/license-GPL--3.0--only-green)
**English (US)** | [Português (BR)](./README.pt-BR.md) | [Español](./README.es.md) | [日本語](./README.ja.md)
</div>
<hr />
## 📌 The problem
Pi Agent runs in a terminal. A bare terminal gives you no overview of sessions, no readable tool calls, and no place to inspect MCP servers, skills or context usage. PiAgentUI puts those in one window, as a web app or a Tauri desktop app, without inventing agent state: sessions, models, tools, skills and commands come from the Pi runtime whenever possible.
## ✨ What it does
- Streams real Pi Agent sessions into a chat view over SSE (`/global/event`), with Markdown, code highlighting (Shiki) and math (KaTeX).
- Renders tool calls as cards and shows context usage for the active session.
- Switches models, using the normalized capabilities returned by the runtime.
- Lists configured MCP servers (transport, command, URL, source) and effective skills grouped by source.
- Exposes built-in and dynamic slash commands, plus Git controls in the composer.
- Embeds a terminal (xterm.js) and a file explorer next to the chat.
- Accepts voice input through an OpenAI-compatible STT endpoint configured in settings.
- Ships as a web build or a Tauri 2 app, with UI locales `en`, `pt-BR`, `es`, `ja`, `zh-CN`, `hi`, `bn` and `ar`.
## 🚀 Quickstart
| Tool | Minimum version | Needed for |
|---|---|---|
| Node.js | `>=22` (`.tool-versions`: 22.22.0) | everything |
| npm | `>=10` | everything (`package-lock.json` is authoritative) |
| Rust | `1.85.0` (`src-tauri/Cargo.toml`) | desktop app and gateway router only |
| Docker | Docker Compose | container stack only |
| Pi Agent | installed locally | real sessions and models |
Without Pi Agent the UI starts in standalone mode and only shows the server connection dialog.
```bash
git clone https://git.evandro.dev.br/evandro/PiAgentUI.git
cd PiAgentUI
npm ci # postinstall runs scripts/copy-material-icons.mjs
npm run build # tsc -b && vite build -> dist/
npm run dev # Vite dev server on http://localhost:5173
```
`npm run dev` is front-end only: it proxies `/api` to `127.0.0.1:4096` with the prefix stripped. For the Pi flow, build first and let the extension serve `dist/`:
```bash
npm run build
cat ~/.pi/agent/piagentui-port.json # {"port": 58785, "token": "..."}
# open http://127.0.0.1:58785 (Pi Agent running this repo as a Pi package, see package.json "pi")
```
Desktop and Android:
```bash
npm run tauri dev # desktop window on the Vite dev server
npm run tauri build # bundles: nsis, dmg, deb (src-tauri/tauri.conf.json)
npm run tauri android dev # see scripts/dev-android.sh
```
### Container stack
Copy `.env.example` to `.env` first. Four compose files exist:
| File | Command | What it does |
|---|---|---|
| `docker-compose.yml` | `docker compose up -d` | Full stack: `gateway` (Caddy + Rust router, `127.0.0.1:6658` and `6659`), `frontend` (Caddy, 3000) and `backend` (`opencode serve`, 4096, 4G memory limit). |
| `docker-compose.standalone.yml` | `docker compose -f docker-compose.standalone.yml up -d` | Front end only, for an existing `opencode serve`. Uses `BACKEND_URL` (default `host.docker.internal:4096`) and `PORT` (default `3000`). |
| `docker-compose.host.yml` | `docker compose -f docker-compose.yml -f docker-compose.host.yml up -d` | Optional override: `backend` runs privileged with the Docker socket and the host `/` mounted at `/host`. Use only when really needed. |
| `docker-compose.build.yml` | `docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build` | Optional override: builds gateway, frontend and backend locally from `docker/`. |
The `backend` and `gateway` images come from `ghcr.io/evandrodevbr/opencodeui-{backend,gateway}`. The `frontend` image still points at upstream `ghcr.io/lehhair/opencodeui-frontend`, because `docker-frontend.yml` has failed since 2026-06-01 and no `ghcr.io/evandrodevbr/opencodeui-frontend` was published.
### Environment variables
All variables come from `.env.example` and apply to the container stack only (the Pi extension flow needs none).
| Variable | Required | Description |
|---|---|---|
| `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, `DEEPSEEK_API_KEY`, `GROQ_API_KEY`, `MISTRAL_API_KEY`, `XAI_API_KEY` | At least one | LLM provider keys passed to the backend container. |
| `GATEWAY_PORT` | No (`6658`) | Host port of the unified entry point. |
| `PREVIEW_PORT` | No (`6659`) | Host port of the dedicated preview entry point. |
| `PREVIEW_DOMAIN` | No | Separate domain for previews, to avoid front-end asset path problems; the reverse proxy forwards it to `PREVIEW_PORT`. |
| `WORKSPACE` | No (`./workspace`) | Host directory mounted at `/workspace` in the backend. |
| `OPENCODE_SERVER_PASSWORD` | Public deployments | Password for the backend and the router. Set it when exposing the stack. |
| `OPENCODE_SERVER_USERNAME` | No (`opencode`) | Username paired with the password above. |
| `PUBLIC_BASE_URL` | No | Public base URL used by the router built into the gateway. |
| `ROUTER_SCAN_INTERVAL` | No (`5`) | Router scan interval. |
| `ROUTER_TOKEN_LENGTH` | No (`12`) | Length of the generated route tokens. |
| `ROUTER_PORT_RANGE` | No (`3000-9999`) | Port range the router handles. |
| `ROUTER_EXCLUDE_PORTS` | No (`4096`) | Ports the router skips. |
| `USE_CHINA_MIRROR` | No (`1`) | Backend image build option: use the mirror sources below. |
| `APT_MIRROR`, `APT_SECURITY_MIRROR` | No | Debian mirrors for the backend image build. |
| `NPM_CONFIG_REGISTRY`, `NODEJS_ORG_MIRROR`, `PIP_INDEX_URL`, `PIP_TRUSTED_HOST` | No | npm, Node.js and pip sources for the backend toolchain. |
| `MISE_INSTALL_URL`, `OPENCODE_INSTALL_URL` | No | Installer URLs used when building the backend image. |
## 🧱 Architecture
```mermaid
flowchart LR
UI["React UI in browser or Tauri webview"] -->|"HTTP api, SSE, WebSocket"| SRV["Pi extension server"]
PI["Pi Agent runtime"] -->|"loads extension"| SRV
SRV -->|"writes port and token"| DISC["~/.pi/agent/piagentui-port.json"]
TAURI["Tauri shell"] -->|"get_pi_agent_connection"| DISC
TAURI --> UI
```
- The extension (`extensions/piagentui-server.ts`, Node `http` + `ws`) serves the built UI from `dist/` and injects `window.PI_BOOT_DATA {baseUrl, token}`.
- On session start it listens on port `58785` (or the next free one) and publishes the port and a random token in the discovery file.
- `GET /global/health` is open; other `/api/*` routes require `Authorization: Bearer <token>`. Access is loopback-only by default, with a LAN toggle at `/api/network/access`.
- The extension bridges sessions, models, tools, MCP, skills and commands; the full route table lives in the server file.
- The Tauri app reads the same discovery file, so the desktop build connects to the local runtime without manual setup.
- In containers, the Rust router (`src-router`, axum) sits behind Caddy as the gateway in front of the frontend and backend services.
## 🗂️ Structure
```text
extensions/ Pi extension: HTTP/WebSocket server, settings, git and extension managers (Vitest)
src/ React 19 front end: api, components, features, hooks, locales, store
src-router/ Rust gateway router (axum) behind Caddy
src-tauri/ Tauri 2 desktop and mobile shell, Android project in gen/
docker/ Dockerfiles, Caddyfiles, entrypoints
scripts/ icon copy, version bump, release preparation, Android dev helper
docs/ design specs and plans (docs/superpowers/)
assets/ app icon sources
.github/ 6 workflows: build, deploy, release, docker-backend/frontend/gateway
```
## 🧪 Scripts
| Command | What it does |
|---|---|
| `npm run dev` | Vite dev server (front end only). |
| `npm run build` | `tsc -b && vite build`, output in `dist/`. |
| `npm run preview` | Serves `dist/` locally for a final check. |
| `npm run typecheck` | `tsc -b` (app and extension projects). |
| `npm run type-check` | Alias of `typecheck`. |
| `npm run typecheck:extensions` | `tsc -p tsconfig.extension.json --noEmit`. |
| `npm run lint` | `eslint .` |
| `npm run format` | `prettier . --write` |
| `npm run format:check` | `prettier . --check` |
| `npm run test` | `vitest` in watch mode. |
| `npm run test:run` | `vitest run` (needs `dist/`, so build first). |
| `npm run validate` | typecheck, extension typecheck, lint, build, tests. The gate CI runs in `build.yml`. |
| `npm run check` | format check, lint, build, tests. |
| `npm run tauri` | Tauri CLI (`dev`, `build`, `android dev`). |
| `npm run icons:tauri` | Regenerates `src-tauri/icons` from `src-tauri/app-icon.manifest.json`. |
| `npm run release:prepare` | Runs `scripts/prepare-release.mjs`. |
| `npm run postinstall` | Runs `scripts/copy-material-icons.mjs` (automatic after `npm ci`). |
Deploy notes: `dist/` is a plain SPA; under a subpath build with `VITE_BASE_PATH=/subpath/ npm run build`. `deploy.yml` publishes to GitHub Pages with `VITE_BASE_PATH=/PiAgentUI/` on pushes to `main`, and `release.yml` attaches Windows, macOS, Linux and Android artifacts on `v*` tags.
## 📚 Documentation
| Document | Content |
|---|---|
| [`docs/superpowers/specs/`](docs/superpowers/specs/) | Design specs: Pi extension migration, sessions, STT and Git controls. |
| [`docs/superpowers/plans/`](docs/superpowers/plans/) | Implementation plans and the context, skills and MCP roadmap. |
| [`CHANGELOG.md`](CHANGELOG.md) | Release history used by the release workflow. |
| [`docker/`](docker/) | Dockerfiles, Caddy configs and entrypoints. |
## 🛣️ Limitations and next steps
- Active single-developer project, pre-1.0 (`0.6.10`); some areas are still moving.
- OpenCodeUI naming is only partly cleaned: the Rust crate is `opencodeui-router`, images are `opencodeui-*`, `.env.example` comments are in Chinese, and the Docker backend runs `opencode serve`, which belongs to the inherited deployment, not the Pi extension flow.
- `docker-frontend.yml` must be fixed before `ghcr.io/evandrodevbr/opencodeui-frontend` exists; compose files pull that image from upstream until then.
- No tests for the Tauri shell or the Rust gateway beyond compilation; desktop and Android bundles are only built by the release workflow.
- Tests are component- and server-level: no end-to-end browser test and no coverage threshold. `npm run format:check` reported unformatted files at the last audit, so `npm run check` can fail on that step while `npm run validate` passes.
- `@mariozechner/pi-coding-agent` is a devDependency for types only, and npm marks that package line as deprecated in favour of `@earendil-works/pi-coding-agent`.
- One runtime per window (discovery file or manually configured server); no multi-runtime aggregation.
- Voice input needs an OpenAI-compatible STT endpoint and has no automated browser test.
- No published npm package and no hosted web demo.
## 🤝 Contributing
Open an issue or a PR on the [issue tracker](https://git.evandro.dev.br/evandro/PiAgentUI/issues). Before a PR, this must pass:
```bash
npm run validate
```
## 📄 License
GPL-3.0-only, see [`LICENSE`](LICENSE). PiAgentUI is a fork and rework of OpenCodeUI; the original authors are credited in `src-tauri/Cargo.toml`.