--- summary: 'Release flow: changesets local mode, three-way version sync, pre-publish gates, manual passkey publish' read_when: - preparing an npm release - a version-mismatch guard test fails - wondering why there is a .changeset directory --- # Releasing Versioning uses [changesets](https://github.com/changesets/changesets) in local mode — no CI is involved today (the CI rebuild is a recorded future item, and publishing uses an interactive npm passkey that automation cannot hold). The version's single source of truth is `package.json`. `src/version.ts` mirrors it, pinned by `src/version-sync.test.ts`, so a missed sync fails `pnpm check`. ## During development Any wave that ships user-visible change should leave a changeset behind: ```bash npx changeset # pick the bump level, write a human-readable summary ``` This creates a markdown file under `.changeset/` that travels with the branch. Multiple changesets accumulate — `changeset version` later collapses them into one correct bump (two minors do not become two bumps). ## Cutting a release On a release branch off `main`: ```bash pnpm release:version # changeset version + sync src/version.ts + stamp the docs pnpm check # guard tests confirm every copy of the version agrees ``` `release:version` also runs `scripts/stamp.mts`, which rewrites two kinds of pinned version to the new one: - **The skill launchers.** `PINNED` in `skills/pptfast/scripts/run.sh` and `$Pinned` in `run.ps1`. This is the one that matters most: on a machine with no `pptfast` on `PATH`, that constant decides which release actually runs when a harness invokes the skill. - **Every pinned install command in the repo's markdown** (the dsh `plugin add` lines in the READMEs and `INSTALL.md`, the no-script fallback commands in both SKILL files). The drift test (`scripts/stamp.test.mts`, part of `pnpm check`) reads each one back, so a forgotten stamp fails the release before it ships stale numbers. Review `CHANGELOG.md`, commit, merge to `main`, then tag the merge: ```bash git tag v$(node -p "require('./package.json').version") git push origin main --follow-tags ``` ## Publishing (maintainer, manual) 1. `pnpm e2e` — full chain on the built CLI. 2. PowerPoint repair-dialog probe (`docs/testing.md`) — mandatory whenever the export XML changed since the last release. 3. `npm publish` — `prepublishOnly` reruns `pnpm check && pnpm e2e` as the final gate. On a machine running concurrent heavy sessions the vitest leg can hit spurious 30s timeouts — bound the workers for the publish run (`VITEST_MAX_THREADS=2 VITEST_MAX_FORKS=2 npm publish`) rather than skipping the gate, and isolate-rerun any failing file first to confirm it is contention, not a regression. When CI is rebuilt, migrate publishing to npm trusted publishing (OIDC) and let the changesets action open version PRs — that is the current ecosystem best practice this local flow deliberately scales down from.