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
113 changes: 113 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,116 @@ jobs:

- name: Publish to npm
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

binaries:
strategy:
fail-fast: false
matrix:
include:
- target: bun-linux-x64
name: linux-x64
archive: tar.gz
- target: bun-linux-arm64
name: linux-arm64
archive: tar.gz
- target: bun-darwin-x64
name: darwin-x64
archive: tar.gz
- target: bun-darwin-arm64
name: darwin-arm64
archive: tar.gz
- target: bun-windows-x64
name: windows-x64
archive: zip

runs-on: ubuntu-latest
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')

steps:
- uses: actions/checkout@v4

- name: Set up Bun
uses: oven-sh/setup-bun@v2

- name: Install dependencies
run: |
bun install
cd web && bun install

- name: Set version from tag
id: version
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Build TypeScript and Web UI
run: |
bun run build:ts
bun run build:web

- name: Compile binary
run: |
mkdir -p dist-binaries
BINARY_NAME="perry"
if [[ "${{ matrix.name }}" == windows-* ]]; then
BINARY_NAME="perry.exe"
fi
bun build ./src/index.ts --compile --target=${{ matrix.target }} --minify --outfile=dist-binaries/$BINARY_NAME

- name: Create archive
run: |
VERSION=${{ steps.version.outputs.version }}
ARCHIVE_DIR="perry-${VERSION}-${{ matrix.name }}"
mkdir -p "$ARCHIVE_DIR"

if [[ "${{ matrix.name }}" == windows-* ]]; then
cp dist-binaries/perry.exe "$ARCHIVE_DIR/"
else
cp dist-binaries/perry "$ARCHIVE_DIR/"
fi
cp -r dist/agent/web "$ARCHIVE_DIR/"

if [[ "${{ matrix.archive }}" == "tar.gz" ]]; then
tar -czvf "dist-binaries/perry-${VERSION}-${{ matrix.name }}.tar.gz" "$ARCHIVE_DIR"
else
zip -r "dist-binaries/perry-${VERSION}-${{ matrix.name }}.zip" "$ARCHIVE_DIR"
fi

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.name }}
path: dist-binaries/perry-*.*
retention-days: 1

release:
needs: binaries
runs-on: ubuntu-latest
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
permissions:
contents: write

steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: dist-binaries
pattern: binary-*
merge-multiple: true

- name: Generate checksums
run: |
cd dist-binaries
sha256sum perry-*.tar.gz perry-*.zip > checksums.txt
cat checksums.txt

- name: Upload to GitHub Release
uses: softprops/action-gh-release@v2
with:
files: |
dist-binaries/*.tar.gz
dist-binaries/*.zip
dist-binaries/checksums.txt
fail_on_unmatched_files: true
36 changes: 36 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,42 @@ jobs:
path: dist/
retention-days: 1

binary:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4

- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: dist
path: dist/

- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
run: bun install

- name: Compile binary
run: |
bun build ./src/index.ts --compile --minify --outfile=perry-test

- name: Test binary runs
run: |
./perry-test --version
./perry-test --help

- name: Test binary with web assets
run: |
mkdir -p test-install/bin
cp perry-test test-install/bin/perry
cp -r dist/agent/web test-install/
./test-install/bin/perry --version

test:
runs-on: ubuntu-latest
needs: build
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<p align="center">
<a href="https://github.com/gricha/perry/actions/workflows/test.yml"><img src="https://github.com/gricha/perry/actions/workflows/test.yml/badge.svg" alt="Tests"></a>
<a href="https://www.npmjs.com/package/@gricha/perry"><img src="https://badge.fury.io/js/@gricha%2Fperry.svg" alt="npm version"></a>
<a href="https://github.com/gricha/perry/releases"><img src="https://img.shields.io/github/v/release/gricha/perry" alt="Release"></a>
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
</p>

Expand All @@ -29,7 +29,7 @@ Perry is designed to run on a machine within a **secure private network** such a
### Install

```bash
npm install -g @gricha/perry
curl -fsSL https://raw.githubusercontent.com/gricha/perry/main/install.sh | bash
```

### Start Agent
Expand Down
59 changes: 58 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,64 @@

## Tasks

*No active tasks*
### Binary Distribution via Curl Install Script

Switch from npm-based distribution to standalone binary distribution with curl install script (like OpenCode/Claude Code).

**Benefits:**
- No runtime dependency (currently requires Bun installed globally)
- Single binary, faster cold starts with bytecode compilation
- Simpler: `curl -fsSL https://raw.githubusercontent.com/gricha/perry/main/install.sh | bash`

#### Phase 1: Binary Build System

- [ ] Create binary build script using Bun's `--compile` flag for all platforms:
- `perry-linux-x64` (glibc)
- `perry-linux-arm64` (glibc)
- `perry-darwin-x64` (Intel Mac)
- `perry-darwin-arm64` (Apple Silicon)
- `perry-windows-x64.exe`
- [ ] Use `--minify --bytecode` flags for optimized binaries
- [ ] Handle web UI assets embedding (investigate Bun file embedding)
- [ ] Add `build:binaries` script to package.json
- [ ] Test compiled binary runs basic commands locally

#### Phase 2: Install Script

- [ ] Create `install.sh` at repository root with:
- Platform detection (Darwin/Linux via uname)
- Architecture detection (x64/arm64)
- GitHub releases API to fetch latest version
- Download binary from GitHub releases
- Install to `$HOME/.perry/bin` (or `$PERRY_INSTALL_DIR`)
- PATH modification (.bashrc, .zshrc, config.fish, .profile)
- Post-install verification (`perry --version`)
- [ ] Support `--version` flag for specific version install
- [ ] Support `--no-modify-path` flag
- [ ] GitHub Actions detection (add to `$GITHUB_PATH`)

#### Phase 3: Release Workflow

- [ ] Add `binaries` job to `.github/workflows/release.yml`:
- Cross-compile for all targets using Bun
- Create archives (tar.gz for Linux/macOS, zip for Windows)
- Upload to GitHub Releases
- Generate SHA256 checksums
- [ ] Keep npm publish as alternative install method

#### Phase 4: Update Checker

- [ ] Modify `src/update-checker.ts`:
- Query GitHub releases API instead of npm registry
- Update upgrade message to show curl command
- [ ] (Optional) Add `perry upgrade` self-update command

#### Phase 5: Documentation

- [ ] Update `docs/docs/installation.md` with curl install as primary method
- [ ] Update README.md
- [ ] Document manual download from GitHub Releases
- [ ] Document uninstall process

---

Expand Down
20 changes: 16 additions & 4 deletions docs/docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,28 @@ sidebar_position: 2
## Prerequisites

- Docker
- Node.js 18+ or Bun
- SSH client

## Install
## Quick Install (Recommended)

```bash
npm install -g @gricha/perry
curl -fsSL https://raw.githubusercontent.com/gricha/perry/main/install.sh | bash
```

From source:
This downloads and installs the pre-built binary for your platform to `~/.perry/bin`.

### Options

```bash
# Install specific version
curl -fsSL https://raw.githubusercontent.com/gricha/perry/main/install.sh | bash -s -- --version 0.1.8

# Don't modify PATH
curl -fsSL https://raw.githubusercontent.com/gricha/perry/main/install.sh | bash -s -- --no-modify-path
```

## From Source

```bash
git clone https://github.com/gricha/perry.git
cd perry
Expand Down
Loading