3.9 KiB
Publishing to npm
Low-level reference for how Paperclip packages are prepared and published to npm.
For the maintainer workflow, use doc/RELEASING.md. This document focuses on packaging internals.
Current Release Entry Points
Use these scripts:
scripts/release.shfor canary and stable publish flowsscripts/create-github-release.shafter pushing a stable tagscripts/rollback-latest.shto repointlatestscripts/build-npm.shfor the CLI packaging build
Paperclip no longer uses release branches or Changesets for publishing.
Why the CLI needs special packaging
The CLI package, paperclipai, imports code from workspace packages such as:
@paperclipai/server@paperclipai/db@paperclipai/shared- adapter packages under
packages/adapters/
Those workspace references are valid in development but not in a publishable npm package. The release flow rewrites versions temporarily, then builds a publishable CLI bundle.
build-npm.sh
Run:
./scripts/build-npm.sh
This script:
- runs the forbidden token check unless
--skip-checksis supplied - runs
pnpm -r typecheck - bundles the CLI entrypoint with esbuild into
cli/dist/index.js - verifies the bundled entrypoint with
node --check - rewrites
cli/package.jsoninto a publishable npm manifest and stores the dev copy ascli/package.dev.json - copies the repo
README.mdintocli/README.mdfor npm metadata
After the release script exits, the dev manifest and temporary files are restored automatically.
Package discovery and versioning
Public packages are discovered from:
packages/server/cli/
ui/ is ignored because it is private.
The version rewrite step now uses scripts/release-package-map.mjs, which:
- finds all public packages
- sorts them topologically by internal dependencies
- rewrites each package version to the target release version
- rewrites internal
workspace:*dependency references to the exact target version - updates the CLI's displayed version string
Those rewrites are temporary. The working tree is restored after publish or dry-run.
Version formats
Paperclip uses calendar versions:
- stable:
YYYY.M.D - canary:
YYYY.M.D-canary.N
Examples:
- stable:
2026.3.17 - canary:
2026.3.17-canary.2
Publish model
Canary
Canaries publish under the npm dist-tag canary.
Example:
paperclipai@2026.3.17-canary.2
This keeps the default install path unchanged while allowing explicit installs with:
npx paperclipai@canary onboard
Stable
Stable publishes use the npm dist-tag latest.
Example:
paperclipai@2026.3.17
Stable publishes do not create a release commit. Instead:
- package versions are rewritten temporarily
- packages are published from the chosen source commit
- git tag
vYYYY.M.Dpoints at that original commit
Trusted publishing
The intended CI model is npm trusted publishing through GitHub OIDC.
That means:
- no long-lived
NPM_TOKENin repository secrets - GitHub Actions obtains short-lived publish credentials
- trusted publisher rules are configured per workflow file
See doc/RELEASE-AUTOMATION-SETUP.md for the GitHub/npm setup steps.
Rollback model
Rollback does not unpublish anything.
It repoints the latest dist-tag to a prior stable version:
./scripts/rollback-latest.sh 2026.3.16
This is the fastest way to restore the default install path if a stable release is bad.