Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 14 additions & 19 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Changesets

This repository versions its published packages with
This repository versions its distributed packages with
[Changesets](https://github.com/changesets/changesets). A changeset is a small
Markdown file in this directory that names the packages a pull request
changes, the bump each one needs, and a user-facing summary. `changeset
version` folds pending changesets into `CHANGELOG.md` and `package.json`
versions; `changeset publish` (when enabled) publishes the result.
versions. pkg.pr.new publishes commit-addressed previews of the result.

## Which packages get changesets

Expand Down Expand Up @@ -108,10 +108,9 @@ because they change no publishable package.
`rsc-markdown-stream: workspace:^` edge republishes it with the renderer's
new caret. The scaffolder's two optional `workspace:*` peers patch-bump and
republish it whenever either member of its exact release pair moves.
- `access` stays `"restricted"` at the repository level until the release
owner decides the npm package names and access policy
(`docs/preview-packages.md`). `@agent-bundle/runtime` and
`create-agent-bundle` already override it with `publishConfig.access`.
- `access` stays `"restricted"` at the repository level. It is harmless while
Changesets only versions packages and pkg.pr.new is the distribution
channel; no npm publish command consumes it.

## Release flow

Expand All @@ -138,16 +137,12 @@ because they change no publishable package.
directly.

3. Merging Version Packages pushes a `Version Packages` commit to `main`
with no pending changesets. The workflow runs the release gates
(`pnpm check:release`) and then `scripts/verify-registry-versions.sh`,
which fails the job unless every publishable `package.json` version
resolves on npm. With publishing disabled that step is red by design:
green means published, never "versioned but not shipped".
4. Publishing is opt-in: set the repository variable
`AGENT_BUNDLE_NPM_PUBLISH=true` and the `NPM_TOKEN` secret. The action
then runs `pnpm release` (`pnpm check:release && changeset publish`) with
npm provenance (`NPM_CONFIG_PROVENANCE=true`, `id-token: write`) and
creates GitHub releases and tags.

Until publishing is enabled, installable previews come from pkg.pr.new
(`pnpm preview:publish`, `docs/preview-packages.md`).
with no pending changesets. The `Release packages` workflow first calls
the reusable `Package preview` workflow, which runs `pnpm preview:publish`
and verifies that all four package URLs resolve for the merge SHA. The
release job depends on that proof and runs `pnpm check:release`; a green
Version Packages run therefore means both the packed gates and the exact
commit-addressed previews passed.
4. Consumers pin the resulting artifacts as
`https://pkg.pr.new/ScriptedAlchemy/agent-bundle/<package>@<sha>`. No npm
registry credential is needed or expected.
7 changes: 5 additions & 2 deletions .github/workflows/package-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ name: Package preview

on:
pull_request:
push:
branches: [main]
workflow_call:

permissions: {}

Expand All @@ -26,3 +25,7 @@ jobs:
node-version: 22.19.0
- run: pnpm build
- run: pnpm preview:publish
- name: Verify pkg.pr.new preview artifacts
run: >-
bash scripts/verify-preview-artifacts.sh
"${{ github.event.pull_request.head.sha || github.sha }}"
74 changes: 21 additions & 53 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,36 @@ on:
# actions: write lets the built-in token dispatch CI for that generated branch
# when no external Changesets token is configured. workflow_dispatch is one of
# the explicit recursion exceptions for GITHUB_TOKEN-created events.
# id-token: write is required for npm package provenance once publishing is
# enabled; it is inert while PUBLISH_ENABLED below is false. The repository
# setting "Allow GitHub Actions to create and approve pull requests" must
# also be on, or the PR step fails after the branch is pushed.
# The repository setting "Allow GitHub Actions to create and approve pull
# requests" must also be on, or the PR step fails after the branch is pushed.
permissions:
actions: write
contents: write
id-token: write
pull-requests: write

concurrency:
group: package-release

jobs:
preview:
name: Publish and verify pkg.pr.new
permissions: {}
uses: ./.github/workflows/package-preview.yml

release:
name: Version Packages / release
name: Version Packages / verify release
needs: preview

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the failure summary reachable after preview failures

When the preview job fails or is cancelled, GitHub skips this entire dependent job because needs defaults to requiring success, so the step-level if: always() on the summary is never evaluated. This also prevents changesets/action from maintaining the Version Packages PR and means the documented failed outcome is not written; use an independent always-running summary job or a job-level always() condition with the operational steps gated separately.

AGENTS.md reference: AGENTS.md:L96-L99

Useful? React with 👍 / 👎.

runs-on: ubuntu-latest
timeout-minutes: 60
env:
# npm publishing is opt-in and off by default: previews ship through
# pkg.pr.new (docs/preview-packages.md) until the package-name and
# access decisions are made. Set the repository variable
# AGENT_BUNDLE_NPM_PUBLISH=true *and* the NPM_TOKEN secret to let the
# action run `pnpm release` (release gates + `changeset publish`) when
# the Version Packages PR merges. While off, the action still opens and
# updates the Version Packages PR, and merging that PR only runs the
# release gates (`pnpm check:release`) so the tree stays publishable.
PUBLISH_ENABLED: ${{ vars.AGENT_BUNDLE_NPM_PUBLISH == 'true' && secrets.NPM_TOKEN != '' }}
# pkg.pr.new is the distribution channel. The reusable preview job
# publishes and resolves all four commit-addressed package URLs before
# this job maintains or verifies a Version Packages commit.
CHANGESETS_TOKEN_CONFIGURED: ${{ secrets.CHANGESETS_GITHUB_TOKEN != '' }}
AGENT_BUNDLE_PLAYWRIGHT_CHANNEL: chromium
# Packed qualification writes package/digest evidence here when
# `pnpm check:release` / `pnpm release` runs. `github.workspace` is
# valid at job env; `runner.temp` is not (no runner assigned yet).
# `pnpm check:release` runs. `github.workspace` is valid at job env;
# `runner.temp` is not (no runner assigned yet).
AGENT_BUNDLE_RELEASE_EVIDENCE: ${{ github.workspace }}/.release-qualification.json
steps:
# The action pushes and opens the PR through the GitHub API with the
Expand All @@ -58,29 +55,19 @@ jobs:
with:
node-version: 22.19.0
playwright-browser: chromium
# changesets/action v2 no longer writes .npmrc from an NPM_TOKEN env
# variable; expose the token via npm config so `changeset publish`
# (pnpm publish) can authenticate. The ${NPM_TOKEN} placeholder is kept
# literal here and expanded by npm/pnpm from the step environment.
- if: env.PUBLISH_ENABLED == 'true'
run: echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >> "$HOME/.npmrc"
- id: changesets
uses: changesets/action@v2
with:
version-script: pnpm version-packages
# Empty publish-script means "version only": the action opens or
# refreshes the Version Packages PR and never publishes.
publish-script: ${{ env.PUBLISH_ENABLED == 'true' && 'pnpm release' || '' }}
# No publish-script: Changesets only opens or refreshes the Version
# Packages PR. Distribution is the commit-addressed preview above.
commit-message: Version Packages
pr-title: Version Packages
# An external PAT/App token makes the generated PR's native
# pull_request event run CI directly. With only GITHUB_TOKEN, the
# step below dispatches CI explicitly so the candidate still gets
# pre-merge qualification without a manual close/reopen.
github-token: ${{ secrets.CHANGESETS_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: true
# GITHUB_TOKEN-created pushes do not recursively start workflows, but
# workflow_dispatch is an explicit GitHub exception. ci.yml documents
# manual dispatch as the full main-push matrix on any ref, including the
Expand All @@ -103,41 +90,22 @@ jobs:
gh workflow run ci.yml --ref changeset-release/main
gh workflow run release-candidate.yml --ref changeset-release/main

# Publishing disabled: when the Version Packages PR lands (no pending
# changesets, "Version Packages" merge commit), prove the versioned
# tree still passes the pre-publish gates that `pnpm release` would run.
- name: Release gates (publish disabled)
# When the Version Packages PR lands, prove the versioned tree still
# passes the packed release gates. `needs: preview` separately proves
# that every package resolves from pkg.pr.new at this exact commit.
- name: Release gates for Version Packages merge
id: qualify
if: >-
env.PUBLISH_ENABLED != 'true' &&
steps.changesets.outputs.has-changesets == 'false' &&
startsWith(github.event.head_commit.message, 'Version Packages')
run: pnpm check:release
# Green must mean published. Every publishable package.json version on
# main must resolve on npm — whether this run published it or an earlier
# one did — so this runs on every main push while publishing is enabled
# (versions only move through Version Packages merges, which publish),
# and always for a Version Packages merge so a disabled publish cannot
# pass one silently. Not gated on the action's `published` output: a
# publish script that prints no "New tag" lines leaves it false, and
# that silence is exactly what must turn red.
- name: Verify published registry artifacts
id: registry
if: >-
env.PUBLISH_ENABLED == 'true' ||
(steps.changesets.outputs.has-changesets == 'false' &&
startsWith(github.event.head_commit.message, 'Version Packages'))
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: bash scripts/verify-registry-versions.sh
- name: Release outcome summary
if: always()
env:
HAS_CHANGESETS: ${{ steps.changesets.outputs.has-changesets }}
PUBLISHED: ${{ steps.changesets.outputs.published }}
QUALIFY_OUTCOME: ${{ steps.qualify.outcome }}
CHANGESETS_OUTCOME: ${{ steps.changesets.outcome }}
REGISTRY_OUTCOME: ${{ steps.registry.outcome }}
PREVIEW_OUTCOME: ${{ needs.preview.result }}
JOB_STATUS: ${{ job.status }}
CANDIDATE_SHA: ${{ github.sha }}
EVIDENCE_FILE: ${{ env.AGENT_BUNDLE_RELEASE_EVIDENCE }}
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ Requires Node.js 22.19 or later.

## Install

Nothing is published to npm yet (the `agent-bundle` name on npm currently belongs to an unrelated project). Until the first release, install the preview tarballs CI publishes for every commit and pull request:
Packages are distributed through pkg.pr.new, not the npm registry. Install the
preview tarballs CI publishes for every commit and pull request:
Comment on lines +11 to +12

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the stale promise of a future npm channel

This now presents pkg.pr.new rather than npm as the distribution policy, but the same README still says at line 103 that pkg.pr.new is only the release channel until a final npm package name is chosen. Under this commit's owner correction those statements are mutually exclusive, leaving consumers unsure whether npm distribution is still planned; update the Status section to match the new policy.

AGENTS.md reference: AGENTS.md:L96-L99

Useful? React with 👍 / 👎.


```sh
npm i -D https://pkg.pr.new/ScriptedAlchemy/agent-bundle/agent-bundle@<sha-or-pr>
Expand All @@ -26,9 +27,8 @@ project that already passes its own `check`:
npx https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@<sha-or-pr> my-plugin
```

(`npm create agent-bundle` once npm releases exist. See the
[create-agent-bundle README](packages/create-agent-bundle/README.md) for
templates and flags.)
See the [create-agent-bundle README](packages/create-agent-bundle/README.md)
for templates and flags.

Or describe the plugin by hand in `agent-bundle.config.ts` at the project root:

Expand Down
5 changes: 3 additions & 2 deletions docs/local-ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,9 @@ then treat a repeat as a real signal.
- **dependency-review** runs as a GitHub-side action against the GitHub
advisory database on the PR diff; it has no local equivalent and stays a
hosted-only, PR-time check.
- **package-preview** (pkg.pr.new) and the **release publish** workflow are
publish-side effects, not checks; nothing about them gates a merge.
- **package-preview** (pkg.pr.new) and the **Release packages** workflow have
hosted publish-side effects. The latter also verifies the four remote
commit URLs, which a local gate cannot reproduce.
- **host-install-proofs** needs the pinned `claude` and `codex` CLIs on PATH
(see [Real-host install proofs](#real-host-install-proofs)). The local gate
does not install host CLIs into its legs, so run those proofs by hand with
Expand Down
56 changes: 21 additions & 35 deletions docs/preview-packages.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
# Preview packages (pkg.pr.new)

Nothing is published to npm yet, deliberately: the current package names are
placeholders, and npm publishing is deferred until the final name is chosen
(it will then use [npm package provenance](https://docs.npmjs.com/generating-provenance-statements);
the publish step exports `NPM_CONFIG_PROVENANCE=true` and runs the packed
release gates before `changeset publish`, and only runs at all when the
`AGENT_BUNDLE_NPM_PUBLISH` repository variable is `true` — see "How an npm
release will flow" below). Before enabling that path, the
release owner must resolve the repository-wide `"access": "restricted"`
policy for `agent-bundle`, which does not currently override it with
`publishConfig.access`. Until then
pkg.pr.new is the release channel. Every CI package-preview run publishes real,
installable tarballs of all four publishable workspace packages (`agent-bundle`,
pkg.pr.new is the only package distribution channel. Every CI package-preview
run publishes real, installable tarballs of all four publishable workspace
packages (`agent-bundle`,
`@agent-bundle/runtime`, `rsc-markdown-stream`, `create-agent-bundle`) to
[pkg.pr.new](https://pkg.pr.new)
— a free continuous-release registry keyed by commit SHA and pull request.
These are the packages to install until a first npm release is cut.
Consumers pin these previews by commit SHA; no npm registry credential is
needed or expected.

## Install the latest preview

Expand Down Expand Up @@ -87,37 +79,31 @@ URL, so `pnpm add` of a preview `@agent-bundle/runtime` fails with
`blockExoticSubdeps: false` in the consuming project's `pnpm-workspace.yaml`,
or install previews with npm.

## How an npm release will flow
## How a Version Packages merge flows

Versioning is driven by Changesets (`.changeset/README.md`). Every PR that
changes a publishable package carries a `.changeset/*.md`; on each push to
`main`, `.github/workflows/release.yml` runs `changesets/action`, which keeps
a machine-owned **Version Packages** pull request up to date with the pending
bumps and `CHANGELOG.md` entries. Merging that PR versions the packages and
must leave them on npm: the workflow runs the release gates
(`pnpm check:release`) against that exact versioned candidate SHA and then
`scripts/verify-registry-versions.sh`, which fails the job unless every
publishable `package.json` version resolves with `npm view`. Publishing turns
on when the repository variable `AGENT_BUNDLE_NPM_PUBLISH` is `true` *and*
the `NPM_TOKEN` secret exists; the action then runs `pnpm release`
(`pnpm check:release && changeset publish`) with npm provenance, and the
registry check runs on every later `main` push too, so a silently failed
publish is red at the next merge. With publishing disabled, a Version
Packages merge fails the registry check (`outcome: failed`, **NOT
PUBLISHED**) instead of reporting green; a push that only refreshes the
Version Packages PR records `version-maintenance-only`.
bumps and `CHANGELOG.md` entries. Merging that PR versions the packages. The
`Release packages` workflow calls the reusable `Package preview` workflow,
which publishes and resolves all four
`https://pkg.pr.new/ScriptedAlchemy/agent-bundle/<package>@<sha>` URLs. The
release job depends on that proof and runs `pnpm check:release` against the
same Version Packages commit. A green run records `preview-release`; a push
that only refreshes the Version Packages PR records
`version-maintenance-only`.

## Where previews come from

`.github/workflows/package-preview.yml` runs
`pnpm preview:publish` (`pkg-pr-new publish --previewVersion --peerDeps
--no-compact --no-template './packages/agent-bundle' './packages/rsc-runtime'
'./packages/rsc-markdown-stream' './packages/create-agent-bundle'`)
after a full build, on every pull request and on every push to `main`. Runs are
grouped per PR and per branch with `cancel-in-progress`, so a newer push
cancels the superseded build: only the latest preview of a PR or of `main`
matters, and a `main` commit overtaken before its preview published has no
installable snapshot (pin the tip instead). The "Publish pkg.pr.new preview"
check on a PR or commit links to the exact URLs for that build. Previews are
built from the same `pnpm build` output the release gates verify; they are
not npm releases and carry preview version strings.
after a full build. Pull requests invoke the workflow directly and cancel a
superseded run for the same PR. On `main`, the serialized `Release packages`
workflow calls it as a reusable workflow and waits for all four URLs to
resolve before continuing. The "Publish pkg.pr.new preview" check on a PR or
commit links to the exact URLs for that build. Previews are built from the same
`pnpm build` output the release gates verify; they are not npm releases and
carry preview version strings.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
"test:host-install:session:claude": "pnpm build && AGENT_BUNDLE_HOST_INSTALL_CLAUDE_SESSION=1 pnpm test:host-install:session",
"changeset": "changeset",
"version-packages": "changeset version",
"release": "pnpm check:release && changeset publish",
"preview:publish": "pkg-pr-new publish --previewVersion --peerDeps --no-compact --no-template './packages/agent-bundle' './packages/rsc-runtime' './packages/rsc-markdown-stream' './packages/create-agent-bundle'",
"pack:dry-run": "pnpm build && npm pack ./packages/agent-bundle --dry-run --json",
"lint:release": "attw --pack --profile esm-only packages/agent-bundle && attw --pack --profile esm-only packages/rsc-runtime && attw --pack --profile esm-only packages/rsc-markdown-stream && attw --pack --profile esm-only packages/create-agent-bundle && node scripts/check-declaration-imports.mjs --strict packages/agent-bundle packages/rsc-runtime packages/rsc-markdown-stream packages/create-agent-bundle",
Expand Down
8 changes: 3 additions & 5 deletions packages/agent-bundle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1158,8 +1158,6 @@ then Hooks and Scripts, then the interactive MCP App.
Run the complete local delivery gate with `pnpm check && pnpm check:release`.
`pnpm check:release` is release-only: its exact package-script components are
`pnpm pack:dry-run`, `pnpm lint:release`, and `pnpm test:packed:release`, and it does not replace
`pnpm check`. `pnpm release` runs that release gate before `changeset publish`.
Native Claude/Codex smokes stay intentionally opt-in and skipped in ordinary CI.
npm publishing is deferred until the release owner picks the final package name/scope;
pkg.pr.new previews are the interim channel, and the first npm release will use npm
package provenance (`publishConfig.provenance` is already set).
`pnpm check`. A Version Packages merge runs that gate after the reusable Package preview workflow
publishes and resolves every commit-addressed pkg.pr.new artifact. Native Claude/Codex smokes stay
intentionally opt-in and skipped in ordinary CI. pkg.pr.new is the package distribution channel.
Loading
Loading