OpenPets Publishing Guide
This guide covers how to publish and install OpenPets through various package managers and distribution channels.
Table of Contents
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.
Option 1: Interactive Login (Recommended)
The simplest way to authenticate:
npm loginThis 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:
Click "Generate New Token" > "Granular Access Token"
Configure the token:
- Name:
openpets-publish(or any descriptive name) - Expiration: Up to 90 days
- Packages: "Read and write" access
- Scopes: Select
@openpetsif publishing to the official scope
- Name:
Create or update
~/.npmrc:
//registry.npmjs.org/:_authToken=npm_YOUR_TOKEN_HEREOption 3: Environment Variable (CI/CD)
For CI/CD pipelines, use an environment variable:
- Create
~/.npmrcor project.npmrc:
//registry.npmjs.org/:_authToken=${NPM_TOKEN}- Set the environment variable:
export NPM_TOKEN=npm_YOUR_TOKEN_HEREVerify Authentication
npm whoamiThis 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
# 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 publishCommand Options
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 accountsPublishing to Custom Scopes
You can publish to your own npm scope instead of @openpets:
# 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:
pets publish my-pet --otp 123456Release Channels
Publish to different npm tags:
# Publish to beta channel
pets publish my-pet --channel beta
# Publish to next channel
pets publish my-pet --channel nextWhat pets publish Does
The command automatically:
- Ensures
.npmignoreexists with secure defaults - Runs security scans for sensitive files (
.env, credentials, API keys) - Auto-bumps version if already published
- Resolves workspace dependencies to published versions
- Sets
publishConfig.access: "public" - Verifies tarball contents before publishing
Security Checks
Files blocked from publishing:
.envfiles.pemand.keyfilescredentials*.json- Files containing
private_keyorprivate-key reference/andreports/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:
- You must be a member of the
@openpetsnpm organization - Contact the maintainers to request access
Check organization members:
npm org ls openpetsCustom Scopes
Publish to your own scope without special permissions:
- Create a scope at https://www.npmjs.com/org/create (or use your username as
@username) - Use
--scope yourscopewhen 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
pets validate ./pets/my-pet2. Preview the Publish
Always preview first:
pets publish my-pet --preview3. Publish
pets publish my-pet4. Verify Publication
npm view @openpets/my-petTroubleshooting
"Access token expired or revoked"
Re-authenticate:
npm login"This operation requires a one-time password"
Use the --otp flag:
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
cd src/core
npm run publish:coreOr with Bun:
cd src/core
bun script/publish.tsPublishing Options
Preview mode (test without publishing):
OPENPETS_PREVIEW=true bun script/publish.tsCustom channel (for beta/alpha releases):
OPENPETS_CHANNEL=beta bun script/publish.tsPublishing Individual Pets (Legacy)
Publish a single pet:
npm run publish:pet <pet-name>Example:
npm run publish:pet mapsPublish all pets:
npm run publish:petsPreview all pets:
npm run publish:pets:previewPublishing Workflow
The publishing scripts automatically:
- ✅ Compile TypeScript (
tsc) - ✅ Update package.json with correct paths
- ✅ Set proper
publishConfigfor public access - ✅ Include only necessary files
- ✅ Restore original package.json after publish
Installation via NPM
Users can install in multiple ways:
Global installation:
npm install -g openpetsWith pnpm:
pnpm add -g openpetsWith bun:
bun add -g openpetsInstalling specific pets:
npm install @openpets/maps
npm install @openpets/jiraCurl Installation
Current Implementation
OpenPets provides a shell script installer accessible via curl:
curl -fsSL https://pets.raggle.co/install | bashOr using GitHub directly:
curl -fsSL https://raw.githubusercontent.com/raggle-ai/raggle-repo/main/core/openpets/install.sh | bashHow It Works
The install.sh script (already implemented):
- Checks dependencies: Node.js 18+, npm
- Downloads from npm: Uses npm to download
openpets - Installs locally: To
~/.openpetsdirectory - Creates CLI wrappers:
petsandpets-mcpcommands - Updates PATH: Automatically adds to shell config
- Supports multiple shells: bash, zsh, fish
Installation Options
Install specific version:
VERSION=1.0.1 curl -fsSL https://pets.raggle.co/install | bashDownload and inspect first:
curl -fsSL https://pets.raggle.co/install -o install.sh
chmod +x install.sh
./install.shSetting 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 200Nginx:
location /install {
return 302 https://raw.githubusercontent.com/raggle-ai/raggle-repo/main/core/openpets/install.sh;
}Apache .htaccess:
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:
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
endSetting Up a Homebrew Tap
Option 1: Official Homebrew (recommended for stable releases)
Submit to homebrew-core via pull request:
brew create --set-name openpets https://registry.npmjs.org/openpets/-/openpets-1.0.1.tgzOption 2: Custom Tap (faster iteration)
Create your own tap repository:
# 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 mainUsers Installing via Homebrew
From custom tap:
brew tap raggle-ai/openpets
brew install openpetsFrom official Homebrew (after acceptance):
brew install openpetsUpdating the Formula
When releasing a new version:
- Update the version and URL
- Recalculate the SHA256:
curl -L https://registry.npmjs.org/openpets/-/openpets-1.0.2.tgz | shasum -a 256- Update formula and push
Automated Formula Updates
Create a GitHub Action to auto-update on npm publish:
# .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:
# 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:
- Create AUR account at https://aur.archlinux.org
- Set up SSH keys
- Create AUR repository:
git clone ssh://aur@aur.archlinux.org/openpets.git
cd openpets- Add PKGBUILD and .SRCINFO:
# Create PKGBUILD (as shown above)
makepkg --printsrcinfo > .SRCINFO
git add PKGBUILD .SRCINFO
git commit -m "Initial commit: openpets 1.0.1"
git pushUsers Installing via Paru/Yay
With paru:
paru -S openpetsWith yay:
yay -S openpetsManual installation:
git clone https://aur.archlinux.org/openpets.git
cd openpets
makepkg -siUpdating AUR Package
When releasing a new version:
cd openpets-aur
# Update pkgver in PKGBUILD
# Update sha256sums
makepkg --printsrcinfo > .SRCINFO
git commit -am "Update to version 1.0.2"
git pushAutomated AUR Updates
Create a script to automate updates:
#!/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:
# 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:
npm run bumpManual version bump:
# 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 --tagsPublishing 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):
npm install openpetsBeta:
npm install openpets@betaAlpha:
npm install openpets@alphaSpecific version:
npm install openpets@1.0.1Automation
GitHub Actions for Publishing
The repository uses several publish workflows:
publish-single-pet.yml— Manual single-pet publishing viaworkflow_dispatchauto-publish.yml— Auto-publishes changed pets on merge to mainpublish.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:
- 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: ${{ secrets.NPM_TOKEN }}
run: bun scripts/publish-pet.ts my-petVercel/Netlify Redirects
For the curl install method, configure redirects:
vercel.json:
{
"redirects": [
{
"source": "/install",
"destination": "https://raw.githubusercontent.com/raggle-ai/raggle-repo/main/core/openpets/install.sh",
"permanent": false
}
]
}netlify.toml:
[[redirects]]
from = "/install"
to = "https://raw.githubusercontent.com/raggle-ai/raggle-repo/main/core/openpets/install.sh"
status = 200
force = trueSummary
| Method | Status | Command |
|---|---|---|
| NPM | ✅ Implemented | npm install -g openpets |
| Bun | ✅ Implemented | bun add -g openpets |
| Curl | ✅ Implemented | curl -fsSL https://pets.raggle.co/install | bash |
| Homebrew | ⏳ To Implement | brew install openpets |
| Paru/AUR | ⏳ To Implement | paru -S openpets |
Next Steps
- Immediate: Use npm/bun/curl methods
- Short-term: Create Homebrew tap and formula
- Medium-term: Publish to AUR for Arch Linux users
- Long-term: Add to official Homebrew core