A desktop GUI for the Pi and oh-my-pi coding agents. Chat, manage projects, browse files, run commands, and install packages in one window.
Pi Desktop is in alpha, so expect rough edges.
- Streaming chat with thinking blocks and tool calls. Consecutive tool calls fold into groups, file reads show as line-numbered code, and edits show as diffs. SVG blocks render inline, and file names in replies open a preview pane
- Composer with
@file mentions, prompt recall withUp/Down, a model picker you can drive from the keyboard, and file or image attachments (pick, paste, or drop them) - Find in the conversation (
Ctrl/Cmd+F) and a quick switcher (Ctrl/Cmd+K) for commands, skills, prompt templates, workspaces, sessions, and files - Multiple workspaces with project tabs you can drag to reorder. Each live session runs its own agent process, so a turn keeps running after you switch away. Mission Control and sidebar activity dots show background work, and desktop notifications tell you when a session finishes, fails, or waits for approval
- New Task starts a fresh session in a project and sends the task right away, optionally in an isolated Git worktree
- Linked tasks: one task across several Git repositories, shipped as linked pull requests
- Right-edge tool rail that opens the Review panel, file tree, diff viewer, and terminal
- Subagents panel with a live, read-only transcript for each subagent the chat starts (OMP, or Pi with pi-subagents)
- Diff viewer with a filter for the files the session touched, per-file discard, and a Git bar with Commit, Commit + Push, Push, and PR (it becomes Open PR #N when the branch has an open pull request). In the Commit dialog, Suggest message asks the session's model for a commit message, and new files are committed only if you check them. The status bar has a branch menu to switch branches or create a new one
- Code, image, PDF, and HTML previews, a CodeMirror 6 editor with Git change markers, and workspace file search
- Resizable terminal, one per workspace
- Permission modes and custom allow/deny rules, global or per workspace
- Workflow runs viewer for the pi-dynamic-workflows extension, with Abort and Resume
- Skills browser, session fork/branch tree, session tags, inline session rename, and one-click context compaction
- Home dashboard with usage stats: messages, tokens, active-day streaks, peak hour, and a per-model breakdown
- Diagnostics view: Pi/OMP install and PATH resolution, provider configuration, permissions, and recent errors
- Package browser for pi.dev/packages, with local search and update checks for installed packages
- Custom models and providers editor, which edits your engine's models file (
~/.pi/agent/models.jsonfor Pi,~/.omp/agent/models.ymlfor OMP) - Keyboard shortcuts you can change in Settings, themes (7 built-ins, System, and your own), and a UI font setting
- Multi-Agent Council Planning: Pi, Claude, and Codex plan together before Pi builds (opt-in)
- TypeSafe Jev: save your TypeSafe API key once and install the Jev skill for Pi and OMP (opt-in)
- Voice dictation that runs on your machine with a model you pick (opt-in)
- Translatable interface (English and Simplified Chinese ship today)
The Review panel shows the permission mode, pending approvals, changed files, and session status while you chat with Pi. It is hidden by default. Open it from the right-edge tool rail or with Ctrl/Cmd+Shift+U.
Changed files use these status badges:
| Badge | Meaning |
|---|---|
NEW |
Untracked new file |
MOD |
Existing tracked file was modified |
DEL |
Tracked file was deleted |
ADD |
New file staged in git |
STG |
Modified file staged in git |
REN |
File was renamed |
Pi Desktop speaks Pi's RPC protocol, so it can run either the standard pi CLI or the compatible omp binary from oh-my-pi. Settings > Agent Configuration > Agent Installation finds installed engines and lets you pick one, or point it at a custom executable or install directory.
Each engine keeps its own sessions: Pi writes to ~/.pi/agent/sessions, OMP to ~/.omp/agent/sessions. The app reads both, so switching engines never hides your history. When sessions from both appear in one list, each row is tagged Pi or OMP, and opening one starts the engine that wrote it. Under OMP, package actions use OMP's plugin commands.
If ~/.pi/.env exists, its variables (provider API keys, for example) are passed to every Pi or OMP process and to the terminal. A variable already set in the environment wins.
A linked task lets the agent change several Git repositories together, for example a library and the app that uses it. Start one from Linked task on the Home screen, the tab bar, or /linked-task.
- A repo set is a saved group of repositories with one main repository. The agent starts in the main one and follows its project rules. Make sets in the same dialog or with
/new-repo-set. - Isolated (default) gives each repository a new worktree, all on one new branch, so your own checkouts do not change. In place edits your checkouts on their current branches.
- The repo bar under the tabs lists the repositories. Select one to show it in the file tree, diff viewer, and Git bar. Add repo (or
/add-repo) adds a repository while the task runs; the agent sees it on its next turn. - Ship all commits, pushes, and opens a pull request in each changed repository, then lists the other pull requests in each description. Retry runs only the repositories that failed. It never ships from
main,master, or the remote's default branch. - Works with Pi and OMP.
A file edit outside the task's repositories always asks first, even in Trusted mode. Shell commands are not checked for paths: they follow your permission mode and rules like any other command.
Four base modes control what Pi may do. Pick one in the composer, the Review panel, or Settings > Behavior:
| Mode | Behavior |
|---|---|
| Plan / Read-only | Only read/search/list tools are enabled; edits and shell commands are blocked |
| Ask before edits | Pi asks before file edits and shell commands |
| Ask before commands | Pi asks before shell commands |
| Trusted | All tools enabled |
The default is Ask before edits.
Custom permission rules refine the modes with allow/deny rules per Pi tool, edited in Settings > Behavior > Permission Rules:
- A rule has an action (
allowordeny), a tool name (bash,edit,write,read, and so on, or*for any tool), and an optional glob pattern matched against the tool's input: the shell command forbash, the file path for file tools.*is the only wildcard. - Deny beats allow, and allow beats the mode default. Deny rules apply in every mode, so a
deny * *.env*rule holds even in Trusted. Allow rules skip the confirmation prompt in the ask modes. - Rule edits apply to the next tool call without restarting Pi.
- The Global and This workspace tabs edit your global rules or the active workspace's
.pi-desktop/permission-rules.json. A workspace file depends on workspace trust. After you trust the workspace, its file replaces the global list while you work there. Until then (the default for a repo you just opened), only its deny rules apply, on top of your global rules, and its allow rules are ignored. A cloned repo can tighten your permissions but never loosen them. Opening a workspace whose file has allow rules asks you to trust it, and the This workspace tab has Trust and Revoke controls. Import and Export move rule lists as JSON files. You can also edit the workspace file by hand or commit it with the repo; the app picks up changes live. - Rules match raw strings, with no path canonicalization or command parsing. Treat them as a guard against accidents, not a security sandbox, and keep even a trusted workspace's allow rules narrow.
Example rules:
{ "action": "allow", "tool": "bash", "match": "npm test*" }
{ "action": "deny", "tool": "bash", "match": "rm -rf *" }
{ "action": "deny", "tool": "*", "match": "*.env*" }Pi Desktop ships 7 built-in themes (Dark, Light, Nord, Gruvbox, Breeze Dark, Breeze Light, Breeze Claudius) plus System, the default. You can also create your own in Settings > Appearance. With System selected, Light Theme and Dark Theme choose which installed theme each OS mode uses.
Click Create theme to fork the active theme, or Edit theme to keep editing one you created. Pick 7 seed colors (app background, surface, text, accent, success, warning, error) and a dark or light kind. The app derives every other color from those seeds, and the whole window previews your changes as you edit. Two sections give finer control:
- Advanced overrides individual derived tokens (borders, hovers, scrollbars, and so on).
- Syntax colors overrides the code-highlighting colors (keywords, strings, comments, and so on) in the code editor and diff viewer.
Your themes appear next to the built-ins in the Theme dropdown. To rename a theme, edit its name in the editor. To duplicate one, select it and click Create theme. To delete one, select it and click Delete under Theme Actions.
To share a theme, use Import and Export to move it as a .json file, or paste an https:// URL into the field under Theme Actions and click Install. Plain HTTP URLs are refused, and downloads have a size limit.
A theme file uses the pi-theme/v1 format: JSON with a $schema, a name, a kind ("dark" or "light"), and 7 seeds. That is enough for a complete theme; the app derives the rest with CSS color-mix():
{
"$schema": "pi-theme/v1",
"name": "My Theme",
"kind": "dark",
"seeds": {
"app": "#0a0a0a",
"surface": "#171717",
"text": "#f5f5f5",
"accent": "#2563eb",
"success": "#34d399",
"warning": "#facc15",
"error": "#f87171"
}
}Two optional top-level objects pin exact values instead of derived ones: overrides (any derived token, such as border, scrollbar, or accent-hover) and syntax (code-highlighting colors, such as keyword, string, or comment). Without them, the theme renders from the 7 seeds alone.
User theme files live in the app's data directory under themes/ (on Linux, ~/.config/pi-desktop/themes/).
Browse gallery under Theme Actions opens the community gallery, pi-desktop-themes, where you can preview and install themes. To add your own theme to it, open a pull request there.
Pick the interface language in Settings > Appearance > Language. System default follows your operating system's language list and falls back to English. The change applies when you click Save Settings, with no restart.
English and Simplified Chinese are bundled today. Each language is one JSON file in resources/locales/<code>/translation.json; see Translations to add one.
Only the app's own text is translated. Chat replies, file contents, and names of models, packages, and sessions stay as they are. Logs and the copied Diagnostics report stay in English, so bug reports stay readable.
Pi, Claude, and Codex each write a plan, and Pi merges them into one consensus plan before anything is built. Pi is the only agent that edits files.
The feature is off by default. Turn it on in Settings > Multi-Agent Council Planning. A confirmation dialog warns that each request runs several agents, which costs more tokens and credits.
The app detects each member's CLI, and you can enable only the agents it finds. A run needs at least two members. Pi always merges the plans, even when it is not checked as a planner.
Every member plans read-only: Claude runs with --permission-mode plan, Codex with --sandbox read-only, and Pi without its write tools. Each member streams its plan into its own card with an elapsed timer.
There are two consensus modes:
- One debate round (default): each member reads the others' plans and revises once, then Pi merges them.
- Arbiter merge: faster and cheaper. Pi merges the first plans directly.
A per-member timeout (10 to 600 seconds, default 240) limits each member. A member that times out or fails is dropped, and the run continues if at least one plan came back.
To use it, type your request and click Plan with Council in the composer. Read each member's plan and the merged plan. To change it, type feedback in Request changes to the plan… and Pi revises the plan. When it looks right, click Implement this and Pi builds it.
Jev is TypeSafe's judgment model. It does not write text. It answers typed questions with yes/no probabilities, scores, and choices that code can use directly.
Nothing happens until you set it up in Settings > TypeSafe Jev:
- API key: paste a key from the TypeSafe console. The app saves it in its own file in the app's data folder, readable only by your user account, and never in
settings.json. Every new Pi or OMP session gets it asTYPESAFE_API_KEY. If that variable is already set in the environment Pi Desktop started with, that value wins. Restart an open session to give it the key. - Jev skill: installs TypeSafe's official agent skill into
~/.agents/skills, where both Pi and OMP find it. The files come from a pinned release and are checked before install.
Then ask the agent to use TypeSafe. Pi Desktop never calls TypeSafe itself.
To learn more, see the TypeSafe quickstart, models and pricing, and API reference.
Click the microphone in the composer and start talking. Your words show up in the prompt box while you speak, and recording stops after a short pause (or click the mic to stop). The text stays in the box for you to read and edit; the app never sends it for you.
Speech-to-text runs on your own computer. No model ships with the app and none is selected by default, so nothing downloads until you choose one in Settings > Voice dictation. The model you pick downloads once, with a progress bar, into the app's data folder.
The right model depends on your machine and language. Moonshine is small and fast and handles English well, so it is a good first choice. Whisper covers many languages. Parakeet V3 is the most accurate and also covers many languages, but it is a much larger download. Bigger models are more accurate but run slower and use more disk. Models use your graphics card when there is one and fall back to the processor otherwise.
You need Pi installed first:
npm install -g @earendil-works/pi-coding-agentOn Linux, grab the AppImage from Releases:
chmod +x Pi-Desktop-*.AppImage
./Pi-Desktop-*.AppImageDownload the .dmg (Apple Silicon / arm64) from Releases, open it, and drag Pi Desktop to Applications.
Builds are ad-hoc signed, without an Apple-issued certificate, and not notarized. macOS can quarantine the download, and on first launch Gatekeeper shows this dialog (this is macOS's wording, not our advice):
Pi Desktop is damaged and can't be opened. You should move it to the Trash.
Do not move it to the Trash. The app is not damaged; Gatekeeper uses this wording to block any unsigned app. This dialog has no "Open Anyway" button, so clear the quarantine flag in Terminal instead:
xattr -dr com.apple.quarantine "/Applications/Pi Desktop.app"Then open the app normally. You only need to do this once.
If macOS instead says the app "cannot be opened because Apple cannot check it for malicious software," you can allow it without Terminal: open System Settings > Privacy & Security, scroll to the Security section, click Open Anyway next to the Pi Desktop notice, and confirm with Touch ID or your password.
To skip the unsigned-app warnings, build from source. Gatekeeper does not block a build you compile yourself, so there is no quarantine flag to clear. See Build it yourself: Linux / macOS below.
Local-network model providers also depend on macOS Local Network permission. The app declares why it needs that access and the release build signs it with Pi Desktop's own bundle identifier. Allow access when prompted, or check System Settings > Privacy & Security > Local Network. Apple's TN3179 explains how permission applies to agent and terminal child processes; it recommends an Apple-issued signing identity for reliable permission tracking across builds. Ad-hoc signing does not provide that publisher identity or notarization.
Download the installer (…-win-x64-setup.exe, recommended) or the portable …-win-x64.exe from Releases. Builds are unsigned, so SmartScreen may warn; choose More info > Run anyway. If file edits or saves fail, see the Controlled Folder Access note below. Windows is community-tested, so please open a bug report if you hit a problem.
You can change the app shortcuts in Settings > Keyboard shortcuts, or turn any of them off. Mod is Cmd on macOS and Ctrl elsewhere. The defaults:
| Shortcut | What it does |
|---|---|
Mod+K |
Command palette |
Mod+N |
New session |
Mod+Shift+M |
Model selector |
Mod+B |
Sidebar |
Mod+Shift+E |
File tree |
Mod+G |
Diff viewer |
Ctrl+` |
Terminal |
Mod+Shift+U |
Review panel |
Mod+Shift+H |
Show this session's changes in the diff; press again to Commit + Push |
Mod+, |
Settings |
Ctrl+Shift+P |
Insert a saved note |
Mod+[ / Mod+] |
Previous / next open session in the project |
Mod+Shift+[ / Mod+Shift+] |
Previous / next project |
Mod+Shift+T (hold) |
Voice dictation while held |
A system-wide voice dictation key, off by default, starts and stops dictation from any app.
These shortcuts are fixed:
| Shortcut | What it does |
|---|---|
Enter |
Send message |
Shift+Enter |
New line |
Up / Down |
Recall prompts sent in this session |
@ |
Mention a workspace file |
/ (start of message) |
Show commands |
Esc |
Stop the running turn |
Ctrl+P (composer focused) |
Cycle model |
Ctrl/Cmd+F |
Find in conversation |
Ctrl/Cmd+Shift+F |
Search workspace files |
Ctrl/Cmd+Shift+N |
New workspace |
Ctrl/Cmd+O |
Open project |
git clone https://github.com/FaqFirebase/pi-desktop.git
cd pi-desktop
npm install --ignore-scripts=false
npm run dev--ignore-scripts=false runs the install scripts that prepare Electron and the native modules, even if your npm configuration turns scripts off.
Windows needs extra steps because node-pty (the terminal backend) compiles a native module against Electron's ABI.
Install these before cloning:
- Git for Windows
- Node.js LTS, via the official Windows installer (adds
nodeandnpmto PATH) - Visual Studio Build Tools 2022, downloaded from Visual Studio downloads
- Select the Desktop development with C++ workload
- Open Individual components, search
Spectre, and install Spectre-mitigated libs for v143 toolset
Use VS Build Tools 2022, not 2026. node-pty needs Spectre-mitigated runtime libraries. VS 2022 stable (v143 toolset) ships them. VS 2026 preview (v180 toolset) does not, and
npm installthen fails withMSB8040: Spectre-mitigated libraries are required for this project.
Defender can block or slow npm install on projects with many small files. Before cloning, add an exclusion:
Settings > Privacy & Security > Windows Security > Virus & threat protection > Manage settings > Exclusions > Add a folder > (pick where you'll clone the repo)
git clone https://github.com/FaqFirebase/pi-desktop.git
cd pi-desktop
npm install --ignore-scripts=false--ignore-scripts=false runs the install scripts even if your npm configuration turns them off. The postinstall script rebuilds node-pty against Electron's ABI and downloads the Electron binary if it is missing. The first install can take a few minutes.
If the Electron binary is still missing after install, follow the manual Electron binary download steps below. They fix the case where Electron's postinstall extraction leaves a partial dist folder.
powershell -c "irm https://pi.dev/install.ps1 | iex"Open a new terminal afterwards so the updated PATH takes effect.
npm run dev| Error | Cause | Fix |
|---|---|---|
MSB8040: Spectre libs missing |
VS Build Tools 2026 (v180 toolset) installed instead of 2022 (v143) | Uninstall 2026, install VS Build Tools 2022 with Spectre libs for v143 |
electron-vite is not recognized |
npm install didn't complete |
Run npm install again |
| Electron binary missing after install | Electron's postinstall extraction left a partial or missing dist folder |
Add the repo folder to Defender exclusions, then npm install again. If it still fails, use the manual download steps below |
EPERM / EACCES writing a project file |
Controlled Folder Access (Ransomware protection) is blocking writes under Documents/Desktop | Keep the repo and your projects out of protected folders, or allow Pi Desktop through Controlled folder access (see below) |
| Pi shows "error" in status popover | Pi not installed or PATH not updated | Run the install script above in a new terminal window |
Windows Controlled Folder Access protects Documents, Desktop, Pictures, and similar folders by silently blocking untrusted apps from writing to them. If your repo or projects live in a protected folder, you get intermittent EPERM/EACCES failures during npm install, when the agent edits code, or when you save a file.
The reliable fix is to keep code out of protected folders. Clone the repo and keep your projects somewhere unprotected, for example:
# Not C:\Users\<you>\Documents\...; use an unprotected path:
git clone https://github.com/FaqFirebase/pi-desktop.git C:\dev\pi-desktopIf your code must stay under Documents or Desktop, allow the app instead:
Windows Security > Virus & threat protection > Ransomware protection > Manage ransomware protection > Allow an app through Controlled folder access > Add an allowed app, then add the installed Pi Desktop.exe (and, for development, node.exe, git.exe, and electron.exe).
The portable
.exeextracts to a new temporary folder on each launch, so an allow-list entry for it does not last. Use the installer (Pi-Desktop-<version>-win-x64-setup.exe) if you rely on the allow list.
If npm install completes but the app won't launch because Electron is missing or damaged, download Electron from GitHub and unpack it into place. Use this when node_modules\electron\dist holds only part of its files, such as locales, and no electron.exe.
Replace 43.7.7 with the version in node_modules/electron/package.json if it differs.
$ver = "43.7.7"
$url = "https://github.com/electron/electron/releases/download/v$ver/electron-v$ver-win32-x64.zip"
$zip = "$env:TEMP\electron-v$ver-win32-x64.zip"
Invoke-WebRequest -Uri $url -OutFile $zip
if (Test-Path node_modules\electron\dist) { Remove-Item -Recurse -Force node_modules\electron\dist }
Expand-Archive -Path $zip -DestinationPath node_modules\electron\dist -Force
"electron.exe" | Out-File -Encoding ASCII -NoNewline node_modules\electron\path.txt
"v$ver" | Out-File -Encoding ASCII -NoNewline node_modules\electron\dist\versionAfter this, npm run dev should work.
Note: Windows builds are community-tested. If you hit a problem not listed above, please open a bug report.
Apache 2.0
