2026-03-03 09:32:55 -06:00
# Publishing to npm
2026-03-17 14:08:55 -05:00
Low-level reference for how Paperclip packages are prepared and published to npm.
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
For the maintainer workflow, use [doc/RELEASING.md ](RELEASING.md ). This document focuses on packaging internals.
2026-03-03 09:32:55 -06:00
2026-03-09 08:49:42 -05:00
## Current Release Entry Points
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
Use these scripts:
2026-03-03 13:46:06 -06:00
2026-03-17 14:08:55 -05:00
- [`scripts/release.sh` ](../scripts/release.sh ) for canary and stable publish flows
- [`scripts/create-github-release.sh` ](../scripts/create-github-release.sh ) after pushing a stable tag
- [`scripts/rollback-latest.sh` ](../scripts/rollback-latest.sh ) to repoint `latest`
- [`scripts/build-npm.sh` ](../scripts/build-npm.sh ) for the CLI packaging build
Paperclip no longer uses release branches or Changesets for publishing.
2026-03-03 13:46:06 -06:00
2026-03-09 08:49:42 -05:00
## Why the CLI needs special packaging
2026-03-03 13:46:06 -06:00
2026-03-09 08:49:42 -05:00
The CLI package, `paperclipai` , imports code from workspace packages such as:
2026-03-03 13:46:06 -06:00
2026-03-09 08:49:42 -05:00
- `@paperclipai/server`
- `@paperclipai/db`
- `@paperclipai/shared`
- adapter packages under `packages/adapters/`
2026-03-03 13:46:06 -06:00
2026-03-17 14:08:55 -05:00
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.
2026-03-03 13:46:06 -06:00
2026-03-09 08:49:42 -05:00
## `build-npm.sh`
2026-03-03 13:46:06 -06:00
2026-03-09 08:49:42 -05:00
Run:
2026-03-03 09:32:55 -06:00
```bash
./scripts/build-npm.sh
```
2026-03-17 14:08:55 -05:00
This script:
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
1. runs the forbidden token check unless `--skip-checks` is supplied
2. runs `pnpm -r typecheck`
3. bundles the CLI entrypoint with esbuild into `cli/dist/index.js`
4. verifies the bundled entrypoint with `node --check`
5. rewrites `cli/package.json` into a publishable npm manifest and stores the dev copy as `cli/package.dev.json`
6. copies the repo `README.md` into `cli/README.md` for npm metadata
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
After the release script exits, the dev manifest and temporary files are restored automatically.
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
## Package discovery and versioning
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
Public packages are discovered from:
2026-03-03 09:32:55 -06:00
2026-03-09 08:49:42 -05:00
- `packages/`
- `server/`
- `cli/`
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
`ui/` is ignored because it is private.
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
The version rewrite step now uses [`scripts/release-package-map.mjs` ](../scripts/release-package-map.mjs ), which:
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
- 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
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
Those rewrites are temporary. The working tree is restored after publish or dry-run.
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
## Version formats
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
Paperclip uses calendar versions:
2026-03-03 09:32:55 -06:00
2026-03-18 07:50:33 -05:00
- stable: `YYYY.MDD.P`
- canary: `YYYY.MDD.P-canary.N`
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
Examples:
2026-03-03 09:32:55 -06:00
2026-03-18 07:50:33 -05:00
- stable: `2026.318.0`
- canary: `2026.318.1-canary.2`
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
## Publish model
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
### Canary
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
Canaries publish under the npm dist-tag `canary` .
Example:
2026-03-03 09:32:55 -06:00
2026-03-18 07:50:33 -05:00
- `paperclipai@2026.318.1-canary.2`
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
This keeps the default install path unchanged while allowing explicit installs with:
2026-03-03 09:32:55 -06:00
2026-03-09 08:49:42 -05:00
```bash
2026-03-17 14:08:55 -05:00
npx paperclipai@canary onboard
2026-03-03 09:32:55 -06:00
```
2026-03-17 14:08:55 -05:00
### Stable
Stable publishes use the npm dist-tag `latest` .
Example:
2026-03-18 07:50:33 -05:00
- `paperclipai@2026.318.0`
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
Stable publishes do not create a release commit. Instead:
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
- package versions are rewritten temporarily
- packages are published from the chosen source commit
2026-03-18 07:50:33 -05:00
- git tag `vYYYY.MDD.P` points at that original commit
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
## Trusted publishing
The intended CI model is npm trusted publishing through GitHub OIDC.
That means:
- no long-lived `NPM_TOKEN` in repository secrets
- GitHub Actions obtains short-lived publish credentials
- trusted publisher rules are configured per workflow file
See [doc/RELEASE-AUTOMATION-SETUP.md ](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:
```bash
2026-03-18 07:50:33 -05:00
./scripts/rollback-latest.sh 2026.318.0
2026-03-17 14:08:55 -05:00
```
2026-03-03 09:32:55 -06:00
2026-03-17 14:08:55 -05:00
This is the fastest way to restore the default install path if a stable release is bad.
2026-03-03 09:32:55 -06:00
2026-03-09 08:49:42 -05:00
## Related Files
2026-03-03 09:32:55 -06:00
2026-03-09 08:49:42 -05:00
- [`scripts/build-npm.sh` ](../scripts/build-npm.sh )
- [`scripts/generate-npm-package-json.mjs` ](../scripts/generate-npm-package-json.mjs )
2026-03-17 14:08:55 -05:00
- [`scripts/release-package-map.mjs` ](../scripts/release-package-map.mjs )
2026-03-09 08:49:42 -05:00
- [`cli/esbuild.config.mjs` ](../cli/esbuild.config.mjs )
- [`doc/RELEASING.md` ](RELEASING.md )