diff --git a/README.md b/README.md index 117e8fd..ff4873b 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,153 @@ -# OpenPi +
-OpenPi is an Electron desktop workbench for the Pi coding agent runtime. +OpenPi, a desktop workbench for the Pi coding agent -## Getting Started +**A desktop workbench for the Pi coding agent.** +**Workspace-first, not chat-first.** -### Prerequisites +[Quick Start](#quick-start) · [Architecture](docs/openpi-architecture.md) · [Project Brief](docs/openpi-project-brief.md) · [Pretext Deep-Dive](docs/openpi-pretext-deep-dive.md) -- [mise](https://mise.jdx.dev/) — tool version manager and task runner +[![CI](https://github.com/echohello-dev/pidex/actions/workflows/ci.yml/badge.svg)](https://github.com/echohello-dev/pidex/actions/workflows/ci.yml) +[![Electron 41](https://img.shields.io/badge/electron-41-blue)](https://www.electronjs.org/) +[![React 19](https://img.shields.io/badge/react-19-blue)](https://react.dev/) +[![TypeScript 6](https://img.shields.io/badge/typescript-6-blue)](https://www.typescriptlang.org/) -### Install +
-```sh -mise install # installs Node 22 and Bun -bun install # installs project dependencies -``` +## Why this exists + +Daily coding-agent work means juggling repos, branches, and sessions, and the current tools are chat-first: the primary screen is a conversation, not your work. OpenPi flips that. It is a kitchen bench where every active repo, its branch, its sessions, and what has gone stale are visible at a glance. + +| The pain, observed daily | OpenPi's answer | +|---|---| +| Workspace switching takes too many clicks | One dashboard of every repo with Pi sessions, sorted by last activity | +| Losing the thread when resuming | Repo, branch, and session state as first-class UI, not buried chat history | +| Long sessions get sluggish | [Pretext](https://github.com/chenglou/pretext) measures multiline text off the DOM hot path, ~600x faster than browser measurement | +| Worktrees feel unreliable | Git and worktree state surfaced directly, no chatting with the agent to switch branches | + +OpenPi is a personal project: learn by building, sharpen day-to-day DX, and share a cleaner local-first harness pattern for coding agents. Not a commercial product, not an OpenCode clone. Install, BYOK, and provider wiring belong to its sibling, Weldable; OpenPi focuses entirely on the daily coding workflow. -### Development +> A developer's kitchen bench, not a chat pane. -```sh -mise run dev # starts Vite dev server + Electron +## Quick Start + +You need [mise](https://mise.jdx.dev/) and the [Pi CLI](https://pi.dev/). The dashboard reads existing sessions from `~/.pi/agent/sessions`, so run `pi` in a repo or two first if you want it to light up. + +```bash +$ git clone git@github.com:echohello-dev/pidex.git && cd pidex +$ mise install +$ bun install +154 packages installed [2.61s] + +$ mise run dev ``` -### Build +That starts Vite on :5173 and launches Electron against it. For a production build: + +```bash +$ mise run build +[build] $ bunx tsc -p tsconfig.main.json +[build] $ bunx tsc -p tsconfig.preload.json +[build] $ bunx vite build +vite v8.0.11 building client environment for production... +✓ 29 modules transformed. +✓ built in 760ms -```sh -mise run build # compiles main/preload + bundles renderer +$ mise run start ``` -### Run production build +## Features -```sh -mise run start # runs the built app +### Shipped today + +| Feature | What you get | +|---|---| +| Workspace dashboard | Every repo with Pi sessions: branch, session count, last activity | +| Session resume | Reopen any past session from its `.jsonl` transcript | +| Streaming transcript | Token-by-token text with tool-call cards, one tab per session | +| Pi over RPC | Each session is a supervised `pi --mode rpc` subprocess | +| Pretext measurement | Row heights and line counts computed without touching the DOM | + +### Built on + +| Layer | Choice | Why | +|---|---|---| +| Shell | Electron 41 | Native window, context-isolated, typed `window.openpi` preload bridge | +| UI | React 19.2 + Vite 8 | HMR in dev, fast renderer bundles | +| Text measurement | `@chenglou/pretext` | ~15KB, DOM-free, built for virtualised text-heavy lists | +| Language | TypeScript 6 | Strict types across main, preload, and renderer | +| Package manager | Bun | Fast installs, frozen lockfile in CI | +| Toolchain | mise | Node and Bun versions pinned, every command via `mise run` | + +## Architecture + +``` +┌────────────────────────────────────────┐ +│ Renderer (React 19 + Pretext) │ ← dashboard, session tabs, timeline +└───────────────────┬────────────────────┘ + │ typed IPC (window.openpi) +┌───────────────────▼────────────────────┐ +│ Main process (Electron) │ ← workspace registry, event normalization +└───────────────────┬────────────────────┘ + │ NDJSON over stdio +┌───────────────────▼────────────────────┐ +│ Pi runtime (`pi --mode rpc`) │ ← one supervised subprocess per session +└────────────────────────────────────────┘ ``` -## Project Structure +The renderer draws. The main process owns the workspace registry and every Pi subprocess, and normalizes agent events before they cross the bridge. Preload exposes a narrow typed API, so renderer code never touches Node. + +Pi runs out-of-process over RPC instead of being embedded via SDK. That keeps the UI alive when a session crashes, makes restart supervision simple, and leaves the door open to non-Node clients later. The full decision matrix is in [docs/openpi-architecture.md](docs/openpi-architecture.md). + +## Philosophy + +1. **Workspace-first, not chat-first.** The primary screen is work state, not the latest conversation thread. +2. **Fast by default.** Compounded multi-second delays are real cognitive drag. +3. **Repo-aware.** Branch, dirty state, last commit, and worktree are first-class concepts. +4. **Work-aware.** Task context belongs next to the session, not in another app. +5. **Local and extensible.** Pi's minimal runtime stays intact; the richness lives in the UI layer. + +## Roadmap + +Shipped: + +- [x] Workspace dashboard over `~/.pi/agent/sessions` +- [x] Session resume and streaming transcript with tool cards +- [x] RPC session supervision +- [x] Pretext-backed text measurement + +Next up: + +- [ ] **Diff viewer**, virtualised summaries with file-level change previews +- [ ] **Session fork**, branch sessions visually +- [ ] **Worktree switching** from the UI + +Long term: + +- [ ] Richer git and PR context in the dashboard +- [ ] Task tracker awareness alongside sessions +- [ ] Optional adapters for other agent runtimes + +## Documentation + +| Doc | What it covers | +|---|---| +| [docs/openpi-project-brief.md](docs/openpi-project-brief.md) | The thesis, pain points, positioning, MVP slice | +| [docs/openpi-architecture.md](docs/openpi-architecture.md) | Process boundaries, IPC schema, SDK vs RPC matrix | +| [docs/openpi-pretext-deep-dive.md](docs/openpi-pretext-deep-dive.md) | Why DOM-free text measurement, and where it applies | + +## Project Status + +Alpha. A personal workbench, not a product that ships. Expect sharp edges and breaking changes. Pushes to `main` tag calendar-versioned releases (`YYYY.MM.DD`) with notes generated from merged PRs. + +## License -- `src/main/` — Electron main process (lifecycle, workspace registry, Pi runtime) -- `src/preload/` — Typed IPC bridge (`window.openpi`) -- `src/renderer/` — React UI (workspace dashboard, session timeline, diffs) -- `docs/` — Project planning docs (brief, architecture, Pretext deep-dive) +No license chosen yet. Personal project, shared in the open. -## Stack +--- -- Electron 41, React 19.2, Vite 8, TypeScript 6 -- Bun as package manager -- `@chenglou/pretext` for DOM-free text measurement -- mise for tool management and task running +
-## Releasing +Made with Electron, Pi, and an unreasonable attachment to fast text layout. -Pushes to `main` tag a calendar-versioned GitHub release (`YYYY.0M.0D`, with a `-N` suffix for same-day re-releases). Release notes are generated from merged PRs. +
diff --git a/docs/assets/banner.png b/docs/assets/banner.png new file mode 100644 index 0000000..0a9c32f Binary files /dev/null and b/docs/assets/banner.png differ