diff --git a/README.md b/README.md index d3a7d6f..bfdf72c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ **A desktop workbench for the Pi coding agent.** **Workspace-first, not chat-first.** -[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) +[Quick Start](#quick-start) · [Architecture](docs/openpi-architecture.md) · [Design tokens](#design-tokens) · [Docs](docs/openpi-project-brief.md) [![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/) @@ -16,80 +16,26 @@ ## 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. pidex 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 | pidex'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 | - -pidex 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; pidex focuses entirely on the daily coding workflow. - -> A developer's kitchen bench, not a chat pane. - -
- -pidex dashboard preview - -
+Daily coding-agent work means juggling repos, branches, and sessions, and the current tools are chat-first. pidex is the kitchen bench: every active repo, its branch, its sessions, and what's stale, visible in one glance. ## 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. +You need [mise](https://mise.jdx.dev/) and the [Pi CLI](https://pi.dev/). The dashboard reads existing sessions from `~/.pi/agent/sessions`. ```bash $ git clone git@github.com:echohello-dev/pidex.git && cd pidex $ mise install $ bun install -154 packages installed [2.61s] - -$ mise run dev +$ mise run dev # starts Vite + Electron ``` -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 - -$ mise run start -``` - -## Features - -### 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` | +For a production build: `mise run build` then `mise run start`. ## Architecture ``` ┌────────────────────────────────────────┐ -│ Renderer (React 19 + Pretext) │ ← dashboard, session tabs, timeline +│ Renderer (React 19) │ ← dashboard, session tabs, timeline └───────────────────┬────────────────────┘ │ typed IPC (window.openpi) ┌───────────────────▼────────────────────┐ @@ -101,58 +47,37 @@ $ mise run start └────────────────────────────────────────┘ ``` -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 so the UI survives a runtime crash. Pretext handles text measurement so virtualized lists stay smooth in long sessions. Full detail in [docs/openpi-architecture.md](docs/openpi-architecture.md). -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). +## Built on -## 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 +| Layer | Choice | +|---|---| +| Shell | Electron 41, context-isolated, typed `window.openpi` preload bridge | +| UI | React 19.2, Vite 8 with HMR | +| Text | [`@chenglou/pretext`](https://github.com/chenglou/pretext), DOM-free | +| Language | TypeScript 6 | +| Package manager | Bun | +| Toolchain | mise, all commands via `mise run` | ## Design tokens -The workbench inherits its palette from the [Pi coding agent](https://pi.dev) so the desktop harness feels like part of the same family as the runtime it drives. Source of truth: [`scripts/_design.py`](scripts/_design.py), hexes pulled from `pi.dev/style.css`. +The workbench inherits its palette from the [Pi coding agent](https://pi.dev) so it feels like part of the same family as the runtime. Source of truth: [`scripts/_design.py`](scripts/_design.py), hexes pulled from `pi.dev/style.css`. | Token | Hex | Role | |---|---|---| -| warm-black | `#13110f` | Primary window background | -| bg-deep | `#0d1116` | Deepest surface | +| bg-deep | `#0d1116` | Window background | | bg-canvas | `#161d27` | Canvas surface | -| panel | `#212730` | Sidebar / panel surface | +| panel | `#212730` | Sidebar / panel | | panel-soft | `#252f3d` | Card surface | | parchment | `#dacbc2` | Named cream, primary mark and text | -| moonstone | `#ebe7e4` | Lighter cream, lit facet | -| driftwood | `#5c5752` | Warm mid-gray, shadow facet | +| moonstone | `#ebe7e4` | Lighter cream | +| driftwood | `#5c5752` | Warm mid-gray | | terracotta | `#844f3b` | Warm bronze accent | -| terracotta-light | `#b86b52` | Accent highlight, status dots | -| sunkissed | `#e1b06e` | Warm gold accent | +| terracotta-light | `#b86b52` | Status dots | +| sunkissed | `#e1b06e` | Warm gold | | sage | `#a3a473` | Sage accent | -| accent-blue | `#6a9fcc` | Links, focus rings | +| accent-blue | `#6a9fcc` | Links, focus | Regenerate assets after a token edit: @@ -161,26 +86,20 @@ uv run --with fonttools python scripts/build-icon.py # assets/icon, mark uv run --with fonttools python scripts/build-screenshot.py # docs/assets/screenshot ``` +## What's next + +- [ ] Diff viewer with virtualised summaries +- [ ] Session fork, branch sessions visually +- [ ] Worktree switching from the UI + ## 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. +| [docs/openpi-project-brief.md](docs/openpi-project-brief.md) | Thesis, pain points, positioning, MVP slice | +| [docs/openpi-architecture.md](docs/openpi-architecture.md) | Process boundaries, IPC schema, SDK vs RPC | +| [docs/openpi-pretext-deep-dive.md](docs/openpi-pretext-deep-dive.md) | Why DOM-free text measurement | ## License -No license chosen yet. Personal project, shared in the open. - ---- - -
- -Made with Electron, Pi, and an unreasonable attachment to fast text layout. - -
+No license chosen yet. Personal project, shared in the open. \ No newline at end of file diff --git a/docs/assets/banner.png b/docs/assets/banner.png index 4328c9a..c0a3fe6 100644 Binary files a/docs/assets/banner.png and b/docs/assets/banner.png differ diff --git a/docs/assets/screenshot.png b/docs/assets/screenshot.png index c23b4cf..7dbb4a4 100644 Binary files a/docs/assets/screenshot.png and b/docs/assets/screenshot.png differ diff --git a/docs/assets/screenshot.svg b/docs/assets/screenshot.svg index 7ec5d0f..e84180d 100644 --- a/docs/assets/screenshot.svg +++ b/docs/assets/screenshot.svg @@ -11,12 +11,23 @@ + + + + + + + + + + + - + - + @@ -32,11 +43,17 @@ - pidex + pidex - + + + + + + + - + diff --git a/scripts/build-screenshot.py b/scripts/build-screenshot.py index 04de711..b651480 100644 --- a/scripts/build-screenshot.py +++ b/scripts/build-screenshot.py @@ -1,12 +1,16 @@ -"""Build a faithful pidex dashboard mockup SVG (and PNG) using the Pi -(pi.dev) design tokens. Layout mirrors what the renderer ships: warm-black -window with a panel-toned workspace sidebar on the left, session pane on -the right, input pill at the bottom. Apple-style soft drop shadow under -the window. +"""Build a faithful pidex dashboard mockup SVG (and PNG) using the actual +app design tokens (src/renderer/design-system/tokens.css), which mirrors +pi.dev. Layout mirrors what the renderer ships: dark window with the +blueprint grid, panel-toned workspace sidebar on the left, session pane +on the right, input pill at the bottom. Apple-style soft drop shadow. Output: docs/assets/screenshot.svg docs/assets/screenshot.png (1440x900) + +This is a structural render rather than a live capture: it uses the real +tokens (--bg-deep, --panel, --parchment, --terracotta-light) and the real +blueprint grid pattern so the visual language matches the running app. """ from __future__ import annotations @@ -21,11 +25,11 @@ sys.path.insert(0, str(Path(__file__).resolve().parent)) from _design import ( # noqa: E402 - WARM_BLACK, + BG_DEEP, + BG_CANVAS, PANEL, PANEL_SOFT, PARCHMENT, - MOONSTONE, TERRACOTTA_LIGHT, pi_path, ) @@ -44,8 +48,14 @@ SIDE_BG = PANEL SIDE_PAD = 22 -# Warm neutral ground that complements the warm-black window -BG = "#E2D8CC" +# Warm neutral ground that complements the dark window. +# Set to None to render on a transparent canvas (useful when the PNG will be +# composited over a backdrop, e.g. the README banner). +BG = None + +# Blueprint grid colors (from tokens.css --grid-minor / --grid-major) +GRID_MINOR = "rgba(255,255,255,0.025)" +GRID_MAJOR = "rgba(255,255,255,0.06)" def svg() -> str: @@ -53,10 +63,9 @@ def svg() -> str: gx = (bbox[0] + bbox[2]) / 2 gy = (bbox[1] + bbox[3]) / 2 - # Sidebar π mark + pidex wordmark mark_cx = WX + 36 mark_cy = WY + 44 - mark_scale = 0.036 # ~37px tall + mark_scale = 0.036 mark_transform = ( f"translate({mark_cx} {mark_cy}) " f"scale({mark_scale} -{mark_scale}) " @@ -106,12 +115,29 @@ def svg() -> str: pill_y = WY + WH - 64 pill = ( - f'' - f'' - f'' - f'' + f'' + f'' + f'' + f'' + f'' ) + # Blueprint grid pattern (matches tokens.css body background) + # Clipped to the main pane area (not sidebar), so the grid is the + # distinctive app-chrome look in the session view. + grid_id = "blueprint" + grid_def = f""" + + + + + + + + + + """ + return f""" @@ -125,12 +151,13 @@ def svg() -> str: + {grid_def} - + {f'' if BG else ''} - + @@ -146,10 +173,16 @@ def svg() -> str: - pidex + pidex - {''.join(cards)} + + + + + + + {''.join(cards)} {header} {''.join(main_cards)} {pill}