Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,15 @@ runs:
if: inputs.electron-cache == 'true'
uses: actions/cache@v6
with:
# One list works for every runner OS: actions/cache silently skips
# whichever paths don't exist on the current platform.
path: |
~/AppData/Local/electron/Cache
~/AppData/Local/electron-builder/Cache
~/Library/Caches/electron
~/Library/Caches/electron-builder
~/.cache/electron
~/.cache/electron-builder
key: ${{ runner.os }}-electron-${{ hashFiles('bun.lock') }}
restore-keys: ${{ runner.os }}-electron-

Expand Down
139 changes: 139 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ jobs:
"title=NativePi $version ($shortSha)" >> $env:GITHUB_OUTPUT

- name: Publish GitHub Release
if: false
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ needs.release.outputs.tag }}
Expand All @@ -139,6 +140,144 @@ jobs:
draft: false
prerelease: ${{ contains(needs.release.outputs.tag, '-') }}

macos-installer:
name: Build macOS Installer & Publish
needs: release
if: needs.release.outputs.publish == 'true'
runs-on: macos-latest
timeout-minutes: 30
env:
# No Apple Developer ID configured; skip signing and notarization.
CSC_IDENTITY_AUTO_DISCOVERY: "false"
steps:
- name: Checkout
uses: actions/checkout@v7
with:
ref: ${{ needs.release.outputs.sha }}

- name: Setup
uses: ./.github/actions/setup
with:
electron-cache: "true"

- name: Build macOS installer
run: bun run dist:mac --publish never
working-directory: apps/desktop

- name: Upload installer artifact
uses: actions/upload-artifact@v7
with:
name: nativepi-macos-installer
path: |
apps/desktop/release/*.dmg
apps/desktop/release/*.zip
apps/desktop/release/*.blockmap
apps/desktop/release/latest-mac.yml
if-no-files-found: error

- name: Prepare release title
id: release
run: |
version="${{ needs.release.outputs.tag }}"
version="${version#v}"
short_sha="${{ needs.release.outputs.sha }}"
short_sha="${short_sha:0:12}"
echo "title=NativePi $version ($short_sha)" >> "$GITHUB_OUTPUT"

- name: Publish GitHub Release
if: false
uses: softprops/action-gh-release@v3
Comment thread
nonlooped marked this conversation as resolved.
with:
tag_name: ${{ needs.release.outputs.tag }}
target_commitish: ${{ needs.release.outputs.sha }}
name: ${{ steps.release.outputs.title }}
files: |
apps/desktop/release/*.dmg
apps/desktop/release/*.zip
apps/desktop/release/*.blockmap
apps/desktop/release/latest-mac.yml
generate_release_notes: true
previous_tag: ${{ needs.release.outputs.previous_tag }}
draft: false
prerelease: ${{ contains(needs.release.outputs.tag, '-') }}

linux-installer:
name: Build Linux Installer & Publish
needs: release
if: needs.release.outputs.publish == 'true'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v7
with:
ref: ${{ needs.release.outputs.sha }}

- name: Setup
uses: ./.github/actions/setup
with:
electron-cache: "true"

- name: Build Linux installer
run: bun run dist:linux --publish never
working-directory: apps/desktop

- name: Upload installer artifact
uses: actions/upload-artifact@v7
with:
name: nativepi-linux-installer
path: |
apps/desktop/release/*.AppImage
apps/desktop/release/*.blockmap
apps/desktop/release/latest-linux.yml
if-no-files-found: error

- name: Prepare release title
id: release
run: |
version="${{ needs.release.outputs.tag }}"
version="${version#v}"
short_sha="${{ needs.release.outputs.sha }}"
short_sha="${short_sha:0:12}"
echo "title=NativePi $version ($short_sha)" >> "$GITHUB_OUTPUT"

- name: Publish GitHub Release
if: false
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ needs.release.outputs.tag }}
target_commitish: ${{ needs.release.outputs.sha }}
name: ${{ steps.release.outputs.title }}
files: |
apps/desktop/release/*.AppImage
apps/desktop/release/*.blockmap
apps/desktop/release/latest-linux.yml
generate_release_notes: true
previous_tag: ${{ needs.release.outputs.previous_tag }}
draft: false
prerelease: ${{ contains(needs.release.outputs.tag, '-') }}

publish-release:
name: Publish GitHub Release
needs: [release, windows-installer, macos-installer, linux-installer]
if: needs.release.outputs.publish == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v7
with:
path: release
merge-multiple: true
- uses: softprops/action-gh-release@v3
with:
tag_name: ${{ needs.release.outputs.tag }}
target_commitish: ${{ needs.release.outputs.sha }}
name: NativePi ${{ needs.release.outputs.tag }}
files: release/*
generate_release_notes: true
previous_tag: ${{ needs.release.outputs.previous_tag }}
draft: false
prerelease: ${{ contains(needs.release.outputs.tag, '-') }}

repair-release-notes:
name: Regenerate release notes
if: github.event_name == 'workflow_dispatch'
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ and pull request mechanics.

## Project

NativePi is a small, local, Windows-first desktop interface for the Pi coding
agent. It is a wrapper, not an agent harness.
NativePi is a small, local desktop interface for the Pi coding agent, for
Windows, macOS, and Linux. It is a wrapper, not an agent harness.

Read `apps/desktop/PRODUCT.md` before making product-scope decisions and
`apps/desktop/DESIGN.md` before changing the interface's visual language.
Expand Down
16 changes: 8 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Contributing to NativePi

Thanks for your interest in the project. NativePi is a small Windows-first
desktop interface for the Pi coding agent, and it is deliberately narrow in
scope. Reading this page before you start will save you a rewrite.
Thanks for your interest in the project. NativePi is a small desktop interface
for the Pi coding agent, for Windows, macOS, and Linux, and it is deliberately
narrow in scope. Reading this page before you start will save you a rewrite.

## Scope

Expand All @@ -28,8 +28,8 @@ people.

## Getting set up

You need [Bun](https://bun.sh/) and Git. Windows is the supported platform; the
app builds elsewhere but is neither tested nor released for other systems.
You need [Bun](https://bun.sh/) and Git. Windows, macOS, and Linux are all
supported and released platforms.

```sh
git clone https://github.com/nonlooped/nativepi.git
Expand Down Expand Up @@ -70,9 +70,9 @@ They are not expected for static rendering, getters, or coverage counts.

## Reporting bugs

Open an issue with the NativePi version, your Windows version, and the steps
that reproduce the problem. Logs and screenshots help. If the problem involves
a specific model or provider, say which one.
Open an issue with the NativePi version, your operating system and its
version, and the steps that reproduce the problem. Logs and screenshots help.
If the problem involves a specific model or provider, say which one.

## Reporting vulnerabilities

Expand Down
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

<p align="center">
<strong>Pi, at home on your desktop.</strong><br>
A free, open-source Windows desktop interface for the <a href="https://pi.dev/">Pi coding agent</a>.
A free, open-source desktop interface for the <a href="https://pi.dev/">Pi coding agent</a>, for Windows, macOS, and Linux.
</p>

<p align="center">
<a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
<img alt="Platform: Windows" src="https://img.shields.io/badge/platform-Windows-0078D4.svg">
<img alt="Platform: Windows, macOS, Linux" src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-0078D4.svg">
<img alt="Built with Electron + React" src="https://img.shields.io/badge/built%20with-Electron%20%2B%20React%2019-47848F.svg">
</p>

Expand Down Expand Up @@ -63,9 +63,11 @@ storage, their own login. NativePi takes the opposite approach.

## Install

Download the latest Windows installer from
[GitHub Releases](https://github.com/nonlooped/nativepi/releases). Releases are
currently unsigned, so Windows SmartScreen will warn on first launch.
Download the latest installer for your platform from
[GitHub Releases](https://github.com/nonlooped/nativepi/releases): an `.exe`
for Windows, a `.dmg` for macOS, or an `.AppImage` for Linux. Releases are
currently unsigned (and, on macOS, not notarized), so Windows SmartScreen and
macOS Gatekeeper will warn on first launch.

NativePi bundles Pi. A separate Pi installation is not required, and existing
Pi credentials, configuration, and sessions in `~/.pi/agent` are reused.
Expand Down Expand Up @@ -97,6 +99,8 @@ cd apps/desktop && bun test # run the test suite
cd ../.. && bun run build # build the app
bun run pack # package without installer
bun run dist:win # build the Windows installer
bun run dist:mac # build the macOS installer
bun run dist:linux # build the Linux installer
```

## Architecture
Expand Down
10 changes: 5 additions & 5 deletions apps/desktop/PRODUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## Platform

Windows desktop (Electron)
Windows, macOS, and Linux desktop (Electron)

## Users

Expand All @@ -27,7 +27,7 @@ NativePi is a Pi-only desktop wrapper, not a separate agent harness. Pi remains

## Operating Context

- NativePi is a Windows desktop application used alongside local code projects, Git repositories, and the existing Pi CLI ecosystem. Its workspace can be shared temporarily to browsers on the same local network.
- NativePi is a Windows, macOS, or Linux desktop application used alongside local code projects, Git repositories, and the existing Pi CLI ecosystem. Its workspace can be shared temporarily to browsers on the same local network.
- Users pin project folders; create, discover, import, and manage Pi sessions; inspect streamed messages and tool activity; and review Git state and diffs.
- Existing Pi credentials, configuration, sessions, packages, skills, prompts, and extensions remain in Pi's normal storage and remain usable by the Pi CLI.
- NativePi keeps at most one Pi process per project. Different projects may run concurrently.
Expand All @@ -36,7 +36,7 @@ NativePi is a Pi-only desktop wrapper, not a separate agent harness. Pi remains

## Current Capabilities

- Project and chat pinning, date-grouped chat discovery, filtering, title and transcript search, and direct opening in installed editors or Explorer.
- Project and chat pinning, date-grouped chat discovery, filtering, title and transcript search, and direct opening in installed editors or the system file manager.
- New, resume, rename, clone, fork, delete, import, HTML export, session-tree, statistics, and compaction workflows backed by Pi.
- Streaming text, thinking, tool activity, file-change summaries, rich diffs, retries, steering, follow-ups, queues, and abort controls.
- Images attached to a message by paste, drag and drop, or the file picker, resized by Pi before they are sent and shown in the transcript alongside the message they went with.
Expand All @@ -57,7 +57,7 @@ NativePi is a Pi-only desktop wrapper, not a separate agent harness. Pi remains

## Boundaries and Constraints

- NativePi's host is currently Windows-only, single-window, and dark-only. Browser access requires an explicitly started server, the access token in the link, and the running desktop app. Remote Access is a throwaway Cloudflare quick tunnel created for one session and closed after twelve hours; NativePi does not operate a hosting service, register a permanent address, or hold an account of any kind.
- NativePi's host is currently single-window and dark-only. Browser access requires an explicitly started server, the access token in the link, and the running desktop app. Remote Access is a throwaway Cloudflare quick tunnel created for one session and closed after twelve hours; NativePi does not operate a hosting service, register a permanent address, or hold an account of any kind.
- NativePi does not own an agent loop, make its own LLM requests, add agent tools, or support other harnesses.
- Pi session files are the durable conversation source of truth. NativePi persists only pinned projects and chats, the last project and chat, text drafts, favorite models, pane state, and its own interface preferences.
- Agent configuration is Pi's. NativePi reads and writes it through Pi's own settings manager at user scope, so a change made here is a change the Pi command line sees; NativePi never writes Pi's configuration format itself, and exposes only the settings that have meaning in a desktop window. Project-scope overrides remain the Pi command line's business.
Expand All @@ -66,7 +66,7 @@ NativePi is a Pi-only desktop wrapper, not a separate agent harness. Pi remains
- Normal Pi extensions run unchanged. Optional graphical extensions contribute only through controlled NativePi UI slots and are trusted code, not sandboxed code.
- Terminal extension components are drawn by Pi and displayed, not reimplemented: NativePi runs the component in the Pi process and shows what it draws, so it looks as its author wrote it rather than as NativePi would have styled it. Two parts of Pi's terminal UI have no equivalent here and keep Pi's documented no-op: raw terminal input, and replacing the input editor, which in this window is the composer.
- NativePi has no cloud sync, collaboration, remote projects, SSH launching, configurable keybindings, product accounts, paid features, or telemetry.
- NativePi is MIT licensed. GitHub publishes Windows installers, currently without code signing, so SmartScreen warnings are expected.
- NativePi is MIT licensed. GitHub publishes Windows, macOS, and Linux installers, currently without code signing or notarization, so SmartScreen warnings on Windows and Gatekeeper warnings on macOS are expected.

## Brand Commitments

Expand Down
24 changes: 22 additions & 2 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@nativepi/desktop",
"private": true,
"version": "0.11.0",
"description": "A Windows-first desktop interface for the Pi coding agent.",
"description": "A desktop interface for the Pi coding agent.",
"author": "nonlooped",
"type": "module",
"main": "./out/main/index.js",
Expand All @@ -13,7 +13,9 @@
"typecheck": "tsc --noEmit",
"pack": "electron-vite build && electron-builder --dir",
"dist": "electron-vite build && electron-builder",
"dist:win": "electron-vite build && electron-builder --win"
"dist:win": "electron-vite build && electron-builder --win",
"dist:mac": "electron-vite build && electron-builder --mac",
"dist:linux": "electron-vite build && electron-builder --linux"
},
"dependencies": {
"@earendil-works/pi-coding-agent": "0.82.1",
Expand Down Expand Up @@ -103,6 +105,24 @@
"oneClick": false,
"allowToChangeInstallationDirectory": true,
"installerSidebar": "resources/installer-sidebar.bmp"
},
"mac": {
Comment thread
nonlooped marked this conversation as resolved.
"icon": "resources/icon.png",
"identity": null,
"target": [
"dmg",
"zip"
]
},
"dmg": {
"artifactName": "${productName}-${version}.${ext}"
},
"linux": {
Comment thread
nonlooped marked this conversation as resolved.
"icon": "resources/icon.png",
"category": "Development",
"target": [
"AppImage"
]
}
}
}
Loading
Loading