Skip to content

OpenPets Publishing Guide

This guide covers how to publish and install OpenPets through various package managers and distribution channels.

Table of Contents

  1. NPM/Bun Publishing
  2. Curl Installation
  3. Homebrew (brew)
  4. AUR/Paru (Arch Linux)
  5. Version Management

NPM/Bun Publishing

Current Setup

OpenPets is published to npm under two scopes:

  • Core package: openpets
  • Individual pets: @openpets/<pet-name>

npm Authentication Setup

Before publishing, you need to authenticate with npm.

The simplest way to authenticate:

bash
npm login

This opens a browser for authentication and automatically updates your ~/.npmrc with a valid token.

Option 2: Using an Access Token

For automation or if interactive login isn't available:

  1. Go to https://www.npmjs.com/settings/~/tokens

  2. Click "Generate New Token" > "Granular Access Token"

  3. Configure the token:

    • Name: openpets-publish (or any descriptive name)
    • Expiration: Up to 90 days
    • Packages: "Read and write" access
    • Scopes: Select @openpets if publishing to the official scope
  4. Create or update ~/.npmrc:

ini
//registry.npmjs.org/:_authToken=npm_YOUR_TOKEN_HERE

Option 3: Environment Variable (CI/CD)

For CI/CD pipelines, use an environment variable:

  1. Create ~/.npmrc or project .npmrc:
ini
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
  1. Set the environment variable:
bash
export NPM_TOKEN=npm_YOUR_TOKEN_HERE

Verify Authentication

bash
npm whoami

This should display your npm username.


Publishing with pets publish

The pets publish command is the recommended way to publish pets. It handles security checks, version management, and npm configuration automatically.

Basic Usage

bash
# Publish to @openpets scope (requires org membership)
pets publish my-pet

# Preview what would be published (dry-run)
pets publish my-pet --preview

# Auto-detect pet from current directory
cd pets/my-pet
pets publish

Command Options

bash
pets publish [pet-name] [options]

Options:
  --preview           Dry-run mode (don't actually publish)
  --channel <name>    npm tag (default: latest)
  --scope <scope>     npm scope (default: @openpets, use "" for unscoped)
  --otp <code>        One-time password for 2FA-enabled accounts

Publishing to Custom Scopes

You can publish to your own npm scope instead of @openpets:

bash
# Publish to @yourscope/my-pet
pets publish my-pet --scope yourscope

# Or with @ prefix
pets publish my-pet --scope @yourscope

# Publish without any scope (unscoped)
pets publish my-pet --scope ""

Two-Factor Authentication (2FA)

If your npm account has 2FA enabled:

bash
pets publish my-pet --otp 123456

Release Channels

Publish to different npm tags:

bash
# Publish to beta channel
pets publish my-pet --channel beta

# Publish to next channel
pets publish my-pet --channel next

What pets publish Does

The command automatically:

  1. Ensures .npmignore exists with secure defaults
  2. Runs security scans for sensitive files (.env, credentials, API keys)
  3. Auto-bumps version if already published
  4. Resolves workspace dependencies to published versions
  5. Sets publishConfig.access: "public"
  6. Verifies tarball contents before publishing

Security Checks

Files blocked from publishing:

  • .env files
  • .pem and .key files
  • credentials*.json
  • Files containing private_key or private-key
  • reference/ and reports/ directories

If secrets are detected, the publish will fail with a detailed error.


Scopes and Permissions

@openpets Scope

The @openpets scope is the official namespace. To publish here:

  1. You must be a member of the @openpets npm organization
  2. Contact the maintainers to request access

Check organization members:

bash
npm org ls openpets

Custom Scopes

Publish to your own scope without special permissions:

  1. Create a scope at https://www.npmjs.com/org/create (or use your username as @username)
  2. Use --scope yourscope when publishing

Unscoped Packages

Unscoped packages are published to the global npm namespace. The package name must be unique across all of npm.


Publishing Workflow

1. Validate Your Pet

bash
pets validate ./pets/my-pet

2. Preview the Publish

Always preview first:

bash
pets publish my-pet --preview

3. Publish

bash
pets publish my-pet

4. Verify Publication

bash
npm view @openpets/my-pet

Troubleshooting

"Access token expired or revoked"

Re-authenticate:

bash
npm login

"This operation requires a one-time password"

Use the --otp flag:

bash
pets publish my-pet --otp 123456

"You do not have permission to publish"

For @openpets scope: You need organization membership.
For custom scopes: Ensure you own the scope or have write access.

"Package name already exists"

The CLI auto-bumps versions, but if the name is taken:

  • Use a different package name
  • Publish to a different scope with --scope

"Forbidden file would be published"

Remove the file or add it to .npmignore.


Legacy Publishing Methods

Publishing the Core Package

bash
cd src/core
npm run publish:core

Or with Bun:

bash
cd src/core
bun script/publish.ts

Publishing Options

Preview mode (test without publishing):

bash
OPENPETS_PREVIEW=true bun script/publish.ts

Custom channel (for beta/alpha releases):

bash
OPENPETS_CHANNEL=beta bun script/publish.ts

Publishing Individual Pets (Legacy)

Publish a single pet:

bash
npm run publish:pet <pet-name>

Example:

bash
npm run publish:pet maps

Publish all pets:

bash
npm run publish:pets

Preview all pets:

bash
npm run publish:pets:preview

Publishing Workflow

The publishing scripts automatically:

  1. ✅ Compile TypeScript (tsc)
  2. ✅ Update package.json with correct paths
  3. ✅ Set proper publishConfig for public access
  4. ✅ Include only necessary files
  5. ✅ Restore original package.json after publish

Installation via NPM

Users can install in multiple ways:

Global installation:

bash
npm install -g openpets

With pnpm:

bash
pnpm add -g openpets

With bun:

bash
bun add -g openpets

Installing specific pets:

bash
npm install @openpets/maps
npm install @openpets/jira

Curl Installation

Current Implementation

OpenPets provides a shell script installer accessible via curl:

bash
curl -fsSL https://pets.raggle.co/install | bash

Or using GitHub directly:

bash
curl -fsSL https://raw.githubusercontent.com/raggle-ai/raggle-repo/main/core/openpets/install.sh | bash

How It Works

The install.sh script (already implemented):

  1. Checks dependencies: Node.js 18+, npm
  2. Downloads from npm: Uses npm to download openpets
  3. Installs locally: To ~/.openpets directory
  4. Creates CLI wrappers: pets and pets-mcp commands
  5. Updates PATH: Automatically adds to shell config
  6. Supports multiple shells: bash, zsh, fish

Installation Options

Install specific version:

bash
VERSION=1.0.1 curl -fsSL https://pets.raggle.co/install | bash

Download and inspect first:

bash
curl -fsSL https://pets.raggle.co/install -o install.sh
chmod +x install.sh
./install.sh

Setting Up the Domain

To enable https://pets.raggle.co/install, configure your web server:

Netlify/Cloudflare Pages _redirects:

/install https://raw.githubusercontent.com/raggle-ai/raggle-repo/main/core/openpets/install.sh 200

Nginx:

nginx
location /install {
    return 302 https://raw.githubusercontent.com/raggle-ai/raggle-repo/main/core/openpets/install.sh;
}

Apache .htaccess:

apache
RewriteRule ^install$ https://raw.githubusercontent.com/raggle-ai/raggle-repo/main/core/openpets/install.sh [R=302,L]

Homebrew (brew)

Status: Not Yet Implemented

To make OpenPets installable via Homebrew, you need to create a Homebrew formula.

Creating a Homebrew Formula

Create a file openpets.rb in your Homebrew tap repository:

ruby
class Openpets < Formula
  desc "AI plugin infrastructure and shared utilities"
  homepage "https://pets.raggle.co"
  url "https://registry.npmjs.org/openpets/-/openpets-1.0.1.tgz"
  sha256 "CHECKSUM_HERE"
  license "MIT"

  depends_on "node"

  def install
    system "npm", "install", "-g", "--prefix=#{libexec}", "openpets"
    bin.install_symlink Dir["#{libexec}/bin/*"]
  end

  test do
    system "#{bin}/pets", "--version"
  end
end

Setting Up a Homebrew Tap

Option 1: Official Homebrew (recommended for stable releases)

Submit to homebrew-core via pull request:

bash
brew create --set-name openpets https://registry.npmjs.org/openpets/-/openpets-1.0.1.tgz

Option 2: Custom Tap (faster iteration)

Create your own tap repository:

bash
# Create tap repo at: https://github.com/raggle-ai/homebrew-openpets
mkdir homebrew-openpets
cd homebrew-openpets
git init

# Create formula
cat > openpets.rb << 'EOF'
class Openpets < Formula
  desc "AI plugin infrastructure and shared utilities"
  homepage "https://pets.raggle.co"
  url "https://registry.npmjs.org/openpets/-/openpets-1.0.1.tgz"
  sha256 "SHA256_CHECKSUM"
  license "MIT"

  depends_on "node@20"

  def install
    libexec.install Dir["*"]
    system "npm", "install", "--production", "--prefix=#{libexec}"

    (bin/"pets").write_env_script "#{Formula["node@20"].opt_bin}/node",
      "#{libexec}/cli.js", {}
    (bin/"pets-mcp").write_env_script "#{Formula["node@20"].opt_bin}/node",
      "#{libexec}/mcp-server.js", {}
  end

  test do
    assert_match version.to_s, shell_output("#{bin}/pets --version")
  end
end
EOF

git add openpets.rb
git commit -m "Add openpets formula"
git push origin main

Users Installing via Homebrew

From custom tap:

bash
brew tap raggle-ai/openpets
brew install openpets

From official Homebrew (after acceptance):

bash
brew install openpets

Updating the Formula

When releasing a new version:

  1. Update the version and URL
  2. Recalculate the SHA256:
bash
curl -L https://registry.npmjs.org/openpets/-/openpets-1.0.2.tgz | shasum -a 256
  1. Update formula and push

Automated Formula Updates

Create a GitHub Action to auto-update on npm publish:

yaml
# .github/workflows/update-homebrew.yml
name: Update Homebrew Formula

on:
  release:
    types: [published]

jobs:
  update:
    runs-on: ubuntu-latest
    steps:
      - name: Update Homebrew Formula
        uses: mislav/bump-homebrew-formula-action@v3
        with:
          formula-name: openpets
          homebrew-tap: raggle-ai/homebrew-openpets
        env:
          COMMITTER_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}

AUR/Paru (Arch Linux)

Status: Not Yet Implemented

To make OpenPets available on Arch Linux via AUR (installable with paru or yay).

Creating a PKGBUILD

Create a PKGBUILD file:

bash
# Maintainer: Raggle <support@raggle.co>
pkgname=openpets
pkgver=1.0.1
pkgrel=1
pkgdesc="AI plugin infrastructure and shared utilities"
arch=('any')
url="https://pets.raggle.co"
license=('MIT')
depends=('nodejs>=18' 'npm')
optdepends=('tsx: TypeScript execution support')
source=("https://registry.npmjs.org/openpets/-/openpets-$pkgver.tgz")
sha256sums=('CHECKSUM_HERE')
noextract=("openpets-$pkgver.tgz")

package() {
    npm install -g --prefix="$pkgdir/usr" --cache "$srcdir/npm-cache" \
        "openpets@$pkgver"

    # Remove unnecessary files
    find "$pkgdir/usr" -type d -name '.cache' -exec rm -r {} +

    # Fix permissions
    find "$pkgdir/usr" -type d -exec chmod 755 {} +
    find "$pkgdir/usr" -type f -exec chmod 644 {} +
    chmod 755 "$pkgdir/usr/bin/pets"
    chmod 755 "$pkgdir/usr/bin/pets-mcp"

    install -Dm644 "$pkgdir/usr/lib/node_modules/openpets/README.md" \
        "$pkgdir/usr/share/doc/$pkgname/README.md"
}

Publishing to AUR

Initial Setup:

  1. Create AUR account at https://aur.archlinux.org
  2. Set up SSH keys
  3. Create AUR repository:
bash
git clone ssh://aur@aur.archlinux.org/openpets.git
cd openpets
  1. Add PKGBUILD and .SRCINFO:
bash
# Create PKGBUILD (as shown above)
makepkg --printsrcinfo > .SRCINFO

git add PKGBUILD .SRCINFO
git commit -m "Initial commit: openpets 1.0.1"
git push

Users Installing via Paru/Yay

With paru:

bash
paru -S openpets

With yay:

bash
yay -S openpets

Manual installation:

bash
git clone https://aur.archlinux.org/openpets.git
cd openpets
makepkg -si

Updating AUR Package

When releasing a new version:

bash
cd openpets-aur
# Update pkgver in PKGBUILD
# Update sha256sums
makepkg --printsrcinfo > .SRCINFO
git commit -am "Update to version 1.0.2"
git push

Automated AUR Updates

Create a script to automate updates:

bash
#!/bin/bash
# scripts/update-aur.sh

set -e

VERSION=$1
if [ -z "$VERSION" ]; then
    echo "Usage: $0 <version>"
    exit 1
fi

# Calculate SHA256
TARBALL_URL="https://registry.npmjs.org/openpets/-/openpets-$VERSION.tgz"
SHA256=$(curl -sL "$TARBALL_URL" | sha256sum | cut -d' ' -f1)

# Update PKGBUILD
sed -i "s/pkgver=.*/pkgver=$VERSION/" PKGBUILD
sed -i "s/sha256sums=.*/sha256sums=('$SHA256')/" PKGBUILD

# Generate .SRCINFO
makepkg --printsrcinfo > .SRCINFO

# Commit and push
git commit -am "Update to version $VERSION"
git push

echo "✓ AUR package updated to $VERSION"

Alternative: AUR Binary Package

For faster installation, create a binary package:

bash
# PKGBUILD for openpets-bin
pkgname=openpets-bin
pkgver=1.0.1
pkgrel=1
pkgdesc="AI plugin infrastructure (binary package)"
arch=('x86_64' 'aarch64')
url="https://pets.raggle.co"
license=('MIT')
provides=('openpets')
conflicts=('openpets')

source_x86_64=("https://github.com/raggle-ai/pets/releases/download/v$pkgver/openpets-linux-x64.tar.gz")
source_aarch64=("https://github.com/raggle-ai/pets/releases/download/v$pkgver/openpets-linux-arm64.tar.gz")

sha256sums_x86_64=('CHECKSUM')
sha256sums_aarch64=('CHECKSUM')

package() {
    install -Dm755 pets "$pkgdir/usr/bin/pets"
    install -Dm755 pets-mcp "$pkgdir/usr/bin/pets-mcp"
}

Version Management

Semantic Versioning

OpenPets follows semantic versioning (semver):

MAJOR.MINOR.PATCH
  1  .  0  .  1
  • MAJOR: Breaking changes
  • MINOR: New features (backward compatible)
  • PATCH: Bug fixes

Bumping Versions

Using the built-in script:

bash
npm run bump

Manual version bump:

bash
# Update version in src/core/package.json
# Update version in root package.json

# Commit changes
git add .
git commit -m "chore: bump version to 1.0.2"
git tag v1.0.2
git push && git push --tags

Publishing Checklist

Before publishing a new version:

  • [ ] Run tests: bun run validate:all
  • [ ] Update CHANGELOG.md
  • [ ] Bump version: npm run bump
  • [ ] Commit version changes
  • [ ] Create git tag
  • [ ] Publish core: npm run publish:core
  • [ ] Publish pets: npm run publish:pets
  • [ ] Update Homebrew formula (if applicable)
  • [ ] Update AUR PKGBUILD (if applicable)
  • [ ] Create GitHub release
  • [ ] Update documentation

Release Channels

OpenPets supports multiple release channels:

Latest (stable):

bash
npm install openpets

Beta:

bash
npm install openpets@beta

Alpha:

bash
npm install openpets@alpha

Specific version:

bash
npm install openpets@1.0.1

Automation

GitHub Actions for Publishing

The repository uses several publish workflows:

  • publish-single-pet.yml — Manual single-pet publishing via workflow_dispatch
  • auto-publish.yml — Auto-publishes changed pets on merge to main
  • publish.yml — General publish workflow with version bumping

All workflows use actions/setup-node@v4 with registry-url for npm authentication and NODE_AUTH_TOKEN for the npm secret:

yaml
- name: Setup Node.js
  uses: actions/setup-node@v4
  with:
    node-version: '20.x'
    registry-url: 'https://registry.npmjs.org'

- name: Publish
  env:
    NODE_AUTH_TOKEN: $&#123;&#123; secrets.NPM_TOKEN &#125;&#125;
  run: bun scripts/publish-pet.ts my-pet

Vercel/Netlify Redirects

For the curl install method, configure redirects:

vercel.json:

json
{
  "redirects": [
    {
      "source": "/install",
      "destination": "https://raw.githubusercontent.com/raggle-ai/raggle-repo/main/core/openpets/install.sh",
      "permanent": false
    }
  ]
}

netlify.toml:

toml
[[redirects]]
  from = "/install"
  to = "https://raw.githubusercontent.com/raggle-ai/raggle-repo/main/core/openpets/install.sh"
  status = 200
  force = true

Summary

MethodStatusCommand
NPM✅ Implementednpm install -g openpets
Bun✅ Implementedbun add -g openpets
Curl✅ Implementedcurl -fsSL https://pets.raggle.co/install | bash
Homebrew⏳ To Implementbrew install openpets
Paru/AUR⏳ To Implementparu -S openpets

Next Steps

  1. Immediate: Use npm/bun/curl methods
  2. Short-term: Create Homebrew tap and formula
  3. Medium-term: Publish to AUR for Arch Linux users
  4. Long-term: Add to official Homebrew core

Resources