> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bluejutzu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Publishing

> Cut a release, and set up trusted publishing to npm.

Every release goes to GitHub Releases first. Publishing to npm is layered on top, authenticated
over OIDC against a **trusted publisher** rather than a stored token — nothing to rotate or leak.

## Cutting a release

```bash theme={"system"}
pnpm run release minor      # or patch, major, or an explicit 0.2.0
git push origin master --follow-tags
```

`release` bumps both `packages/cli/package.json` and `packages/core/package.json` in lockstep, so
the version number always tells you which `core` a given CLI release was built against — `core`
itself is never published, just bundled in (see below). It also rolls `CHANGELOG.md`'s `Unreleased`
section into the new version.

Pushing the tag runs the release workflow: typecheck, test, build, GitHub release, then npm.

<Note>
  The workflow refuses to build when the tag and the manifest versions disagree. That mismatch
  would publish a version number that says nothing about what's in it, and you'd only find out
  after the tag is public. Use `pnpm run release` rather than tagging by hand.
</Note>

## Only the CLI is published

`@bmux/core` is `private: true` and never touches the registry. `packages/cli`'s `prepack` script
bundles it straight into `dist/index.js` with [esbuild](https://esbuild.github.io/) — `chalk`,
`commander`, `fast-glob` and `sharp` stay external and install normally (`sharp` ships prebuilt
native binaries per platform, which can't be bundled anyway). `prepack` runs for both `pnpm pack`
(what CI uses for the per-commit artifact below) and `pnpm publish`.

That also sidesteps needing an npm org: the CLI publishes under `@bluejutzu`, an existing personal
scope, rather than a new `@bmux` org. Plain `bmux` was tried first and rejected — npm's anti-squat
check blocks unscoped names too close to existing ones (`bun`, `bluu`, `flux` in this case).

## npm trusted publishing

Trusted publishing needs the package to already exist before npm will let you attach a publisher to
it, so there's a one-time bootstrap: publish the first version by hand, then hand off to OIDC for
every release after.

<Steps>
  <Step title="Publish the first version by hand">
    From a clean checkout, logged in to the `@bluejutzu` account:

    ```bash theme={"system"}
    pnpm install
    pnpm build
    npm login
    pnpm --filter @bluejutzu/bmux publish --access public --no-git-checks
    ```

    <Note>
      No `--provenance` here — provenance attestations need a supported CI environment's OIDC
      token, which a local machine doesn't have. The workflow adds it automatically once releases
      run through GitHub Actions.
    </Note>
  </Step>

  <Step title="Configure the trusted publisher">
    On npmjs.com: the `@bluejutzu/bmux` package page → **Settings** → **Trusted Publisher** →
    **GitHub Actions**, and fill in:

    | Field                | Value           |
    | -------------------- | --------------- |
    | Organization or user | `Bluejutzu`     |
    | Repository           | `bmux`          |
    | Workflow filename    | `release.yml`   |
    | Environment          | *(leave blank)* |
  </Step>

  <Step title="Drop the old token, if there was one">
    If a `NPM_TOKEN` repository secret exists from before trusted publishing, it's no longer read
    by the workflow — delete it under **Settings → Secrets and variables → Actions**.
  </Step>
</Steps>

From here, `pnpm run release` and a push is the whole flow — the workflow's `id-token: write`
permission is enough for npm to trust it.

## If publishing fails

Publishing is non-fatal: the GitHub release is already created by the time npm runs, so a broken
trust relationship (a renamed repo, a renamed workflow file) leaves you with a release to publish
by hand rather than a red workflow and a half-done tag. The workflow summary says whether it
published.

Fix the trusted publisher config to match the workflow, then publish the missing version by hand
with the same commands as the bootstrap step above.
