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 ​