pi Desktop puts the terminal agent in a worker and adds the panes the CLI has no room for
An elegant GUI implementation of pi-agent
At a glance
- What is it?
- pi-app is an Electron front end for the pi coding agent, not a second agent: it runs the same SDK in a background worker against the same ~/.pi/agent files, so the CLI and the GUI can take turns on one session. What it adds is a timeline, a Git review pane with per-hunk staging, and three panels that show how the context window is being spent.
- Who is it for?
- Adopt pi-app if you already live in terminal pi and want its sessions reviewable and diffable without losing the command line, since it shares ~/.pi/agent rather than creating a parallel history. Do not adopt it to evaluate the agent itself, because everything it shows comes from the SDK it wraps, and do not expect a lighter runtime than an Electron shell with a native SQLite module.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 3, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The GUI owns no agent of its own
The claim the project leads with is that pi Desktop is not another agent. It runs the pi SDK in a background worker and reads the same files the command line reads: sessions, model logins, settings.json and installed extensions. Open a project and the sessions you started in the terminal are already in the sidebar, and you can continue any of them or start a new one.
The process layout enforces that. The renderer never talks to the SDK directly. The main process routes each request to the worker that owns that session, and the worker runs the SDK either on your machine or inside a WSL distribution. Sessions, logins and settings stay in ~/.pi/agent, which is what lets the CLI and the app alternate on the same session instead of forking two histories.
The app bundles its own pi SDK, so the only credential step is signing in to a model provider once, the same way you do for terminal pi. Settings, then Runtime, can switch it to a globally installed pi version instead.
Installers per platform, or five commands with Node 22.19
Binaries come from GitHub Releases and the naming tells you which one you want:
git clone https://github.com/justhil/pi-app.git
cd pi-app
npm install
npm run dev # development
npm run build # production bundle in out/
npm run package # installers via electron-builderFrom source that is the whole sequence, and it needs Node.js 22.19 or newer. From a release you pick a package for your platform: pi.Desktop-Setup-<version>-x64.exe as installer or pi.Desktop-Portable-<version>-x64.exe on Windows x64, .dmg or .zip for macOS on both Apple Silicon and Intel, .AppImage or .deb on Linux x64. Every release lists SHA-256 checksums in SHA256SUMS.txt.
Updates are handled inside the app: it checks GitHub Releases in the background and can download and launch the installer, so you do not have to remember to come back for a new version. v0.6.0 shipped on 2026-10-01, after v0.5.8 in September and v0.5.7 in August.
Timeline folds a working turn into a single line
Tool calls stream in as flat steps: thinking, commands, reads, edits. Once the answer starts, those steps fold into one summary line, so a turn that ran twelve tool calls reads as a paragraph plus a footnote rather than a wall of output. Every edit carries its own added and removed line count, and the turn closes with a Files changed card that opens the file in Files or in Review.
Markdown, code blocks, KaTeX and long output render in place, which matters more for an agent transcript than it would in a chat window, because the transcript is mostly output.
The other half of the timeline is going backwards. Hovering a message lets you copy it, rewind to it, or fork a new session from it, so a wrong turn is a rewind rather than a retype. The session tree panel does the same thing at session level, mirroring the CLI's pi /tree view: filter to user messages, jump back to any node, continue from there as a new branch.
Review stages hunks one at a time and sends comments back to the model
Review is the reason to run this instead of reading diffs in a terminal. You pick a scope first: this turn, this session, or the whole Git working tree. Then you expand a file for its diff, and drag the sidebar wider for a side-by-side view against the conversation.
Staging is per hunk rather than per file. A hunk can be staged or unstaged on its own, which is the granularity you actually want when an agent reformatted a file and only one hunk matters. A line comment goes straight back into the conversation, so reviewing and correcting happen in one place rather than in a review tool and a chat window.
The Files panel sits next to the chat for browsing, with Ctrl or Cmd plus click opening a file in another tab. The gutter button quotes path:line into the composer as a reference, and dragging a file onto the composer attaches it. Expand preview gives a file the whole chat column, and clicking again returns.
Each session owns a worker, and working sessions are never reclaimed
Parallel sessions are the feature that changes how you use the agent. Every session runs in its own worker, so starting a turn in one session, opening another and starting a second turn leaves both running. The sidebar marks the sessions that are working and the status bar counts them.
Memory is bounded by a setting rather than by hope. Settings, then General, sets how many workers stay alive and when idle ones are reclaimed, and one guarantee is stated outright: running sessions are never reclaimed. That is the difference between a worker pool and a tab you have to think about before closing.
While the agent is working, the composer changes meaning. Enter steers the current turn, Alt+Enter queues a follow-up for when it finishes, and Alt with the up arrow pulls the last queued message back. The @ symbol searches project files while respecting .gitignore and using fd, inserting matches as references, and / lists pi's built-in commands plus whatever your extensions register.
Run and Context show where the token budget went
Three panels share the right sidebar with Review and Files, and each answers a question the terminal makes awkward.
Run holds the run state, the model and thinking level, and how the context window is currently split between user, assistant and tool messages. Context lists the messages that make up the current context with a token estimate per entry, so you can see which ten tool outputs are eating the window rather than guessing. Tree holds the session as a tree with branching.
That trio is also how you debug a bad turn. When output goes strange, the Context panel distinguishes a model that stopped following instructions from a context window that filled up with file contents.
The interface itself is bilingual, switchable in Settings, with light and dark themes taking either a preset or your own colors, and following the system when you prefer. Themes import from pi-theme-v1 and codex-theme-v1 strings, and custom CSS, five icon sets and 90 to 110 percent density sit in Settings, then Appearance. Notifications arrive as a system notification and an in-app inbox when a turn finishes or needs input.
Extensions arrive through declarative adapters, 36 of them
Extensions installed for terminal pi load in the app rather than needing a rewrite. Their dialogs, tool cards, panels and slash commands are mapped to native UI by declarative adapters, and 36 of those adapters ship built in, with the list in the adapters guide under doc/guide. Install them exactly as you would in the terminal:
pi install npm:<package> # or: pi install git:github.com/<owner>/<repo>The declarative part is the interesting constraint. An adapter describes how an extension's UI maps onto the app's, so an extension with a dialog either has an adapter that covers it or falls back to something less native. That is a smaller promise than arbitrary extensions rendering themselves, and a more honest one.
On Windows the worker can run inside a chosen WSL distribution, with sessions, Git and previews resolved on the Linux side, which is the answer to having both a Windows desktop and a Linux checkout.
An Electron shell with a native SQLite module and three test layers
The package is pi-desktop at version 0.6.0, an ES module whose main entry is out/main/index.js, with the same Node.js 22.19 floor the README states. The build runs through electron-vite, and electron-builder produces the installers.
The dependency that will cost you time is better-sqlite3, a native module. The package scripts include rebuild:native, which runs npx @electron/rebuild -f -w better-sqlite3, and postinstall already calls electron-builder install-app-deps followed by a build. If you hit a mismatch between the Node ABI and the prebuilt binary, that script is the documented route.
Testing is layered: vitest for unit tests, playwright for end-to-end tests with its own chromium install step, and a separate contract test runner. The repository also ships an sbom.cdx.json, a CycloneDX software bill of materials, alongside e2e/ and packages/, which is a reasonable thing for a desktop app that reads your credentials directory to publish.
Licence is MIT, and CHANGELOG.md sits at the root next to the two READMEs.
Editorial conclusion
Adopt pi-app if you already live in terminal pi and want its sessions reviewable and diffable without losing the command line, since it shares ~/.pi/agent rather than creating a parallel history. Do not adopt it to evaluate the agent itself, because everything it shows comes from the SDK it wraps, and do not expect a lighter runtime than an Electron shell with a native SQLite module. Verify first that your extensions appear in the app through one of the 36 built-in adapters, and confirm your Git working tree scope in Review before you stage from a whole session.
Frequently asked questions
Does pi-app replace the terminal pi agent?
No. It runs the pi SDK in a background worker and reads the same files as the CLI, including sessions, model logins, settings.json and installed extensions. Those stay in ~/.pi/agent, so the terminal and the app can take turns on one session instead of keeping separate histories.
How do I install pi-app?
From GitHub Releases: pi.Desktop-Setup-<version>-x64.exe or pi.Desktop-Portable-<version>-x64.exe on Windows x64, .dmg or .zip for macOS on arm64 and x64, and .AppImage or .deb on Linux x64, with SHA-256 checksums in SHA256SUMS.txt. Building from source needs Node.js 22.19 or newer and npm install followed by npm run dev.
Can pi-app run several agent sessions at once?
Yes, each session runs in its own worker, so a second session keeps going while the first is mid-turn, with the sidebar marking the working ones and the status bar counting them. Settings, then General, sets how many workers stay alive and when idle ones are reclaimed, and running sessions are never reclaimed.
Do my pi extensions work inside pi-app?
Extensions installed for terminal pi load in the app. Their dialogs, tool cards, panels and slash commands are mapped to native UI by declarative adapters, and 36 adapters ship built in. Install them the same way, with pi install npm:<package>.
How do I stage changes one hunk at a time in pi-app?
In Review, choose a scope of this turn, this session or the whole Git working tree, expand a file for its diff, and stage or unstage individual hunks. A line comment goes straight back into the conversation, and the sidebar can be dragged wider for a side-by-side view.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/justhil-pi-app)