| name | create-manifest |
| description | Create a Trellis migration manifest and matching docs-site changelogs for a target release by analyzing commits since the previous release. Use when preparing a patch, beta, rc, or minor release manifest. |
Create Migration Manifest
Create a migration manifest for a new patch, beta, rc, or minor release based on commits since the previous release.
Arguments
$ARGUMENTS - Target version, for example 0.5.15 or 0.6.0-beta.14. If omitted, ask the user.
Package release model
Trellis currently publishes two npm packages from the same git tag:
@mindfoldhq/trellis
@mindfoldhq/trellis-core
Both packages must always share the exact same version and npm dist-tag. Source uses workspace:*; the packed CLI must depend on the exact published core version.
Official npm publishing is CI-only. Never use local npm publish or pnpm publish to compensate for a failed or partial release. Local verification may use pnpm pack, release-preflight, tests, lint, typecheck, and npm view.
Step 1: Identify Last Release
git tag --sort=-v:refname | head -5
Pick the most recent release tag on the current release line, for example v0.5.14 or v0.6.0-beta.13.
Step 2: Gather Changes
git log <last-release-tag>..HEAD --oneline
git log <last-release-tag>..HEAD --oneline -- packages/cli/src/ packages/core/src/
git log <last-release-tag>..HEAD --oneline -- packages/cli/scripts/ .github/workflows/ package.json packages/*/package.json pnpm-lock.yaml
User-facing changelog coverage should focus on source behavior under packages/cli/src/ and packages/core/src/. Release wiring, workflow, or package dependency changes belong in Internal only when users can observe the behavior, for example install/update reliability or multi-package availability.
Step 3: Analyze Each Relevant Commit
For each commit that touches relevant source or release behavior:
- Read the diff:
git diff <parent>...<commit> -- packages/cli/src/ packages/core/src/ --stat
git diff <parent>...<commit> -- packages/cli/scripts/ .github/workflows/ package.json packages/*/package.json pnpm-lock.yaml --stat
- Classify as
feat, fix, refactor, or chore.
- Write a one-line changelog entry in conventional commit style.
Drop pure spec edits, mechanical refactors, and internal-only cleanup unless they materially change what users observe.
Step 4: Draft Changelog
Voice: technical reference doc. Short, clear, plain. Not a story, not a sales pitch. Follow .trellis/spec/docs-site/docs/style-guide.md -> "Changelog / Release Notes Voice".
Do:
- Lead each
### section with one sentence stating what changed. Then table, code, or bullets. Done.
- Use feature names as headings, for example
### Joiner onboarding task.
- Include grep-able identifiers: file paths, function names, flag names, migration entries.
- Mirror English and Chinese 1:1 in docs-site changelogs: same sections, same tables, same code blocks; only prose translated.
Do not:
- Add "Why", "Background", or "Rationale" paragraphs.
- Add a Tests section or test counts.
- Add Internal entries unless users can observe the behavior.
- Use rhetorical questions, emotional framing, filler adverbs, or marketing voice.
- Use outcome-phrased headings that age badly or are not grep-able.
Length cap: each ### section should stay under about 120 words.
Allowed top-level sections, ordered:
Enhancements
Bug Fixes
Internal only if user-observable
Upgrade
Skip empty sections.
Manifest changelog field:
- Use one string with real
\n separators.
- Group with bold prefixes:
**Enhancements:**, **Bug Fixes:**, **Internal:**.
- Keep it shorter than the MDX changelog because it prints in terminal during
trellis update.
Step 5: Determine Manifest Fields
| Field | How to decide |
|---|
breaking | Any breaking API or behavior change. Default false for patch/prerelease fixes. |
recommendMigrate | Any rename/delete migration the user should run. Default false for patch fixes. When breaking=true and recommendMigrate=true, trellis update exits 1 without --migrate. |
migrations | List of rename, rename-dir, delete, or safe-file-delete actions. Usually [] for patch fixes. |
migrationGuide | Mandatory when breaking=true and recommendMigrate=true. Human migration guide inserted into the generated migration task PRD. |
aiInstructions | Strongly recommended with migrationGuide. Instructions for AI migration assistance. |
notes | Brief terminal guidance shown during update. |
Breaking releases without migrationGuide produce a broken upgrade experience. packages/cli/scripts/create-manifest.js validates this.
Step 5a: Per-Migration Entry Fields
| Field | Purpose | Required |
|---|
type | rename, rename-dir, delete, or safe-file-delete | yes |
from | Source path relative to project root | yes |
to | Target path | yes for renames |
description | What the migration does, shown in the confirm prompt | recommended |
reason | Version-specific context for modified-file prompts | optional |
allowed_hashes | Known-pristine SHA256 hashes for safe deletion | required for safe-file-delete |
rename uses the project-local .trellis/.template-hashes.json; it does not use manifest allowed_hashes.
Use:
rename when a file moved and has a replacement path.
safe-file-delete when a file was removed and has no replacement.
safe-file-delete plus notes when a removed file was folded into another command.
Step 6: Create Manifest
Pipe JSON through stdin:
cat <<'EOF' | node packages/cli/scripts/create-manifest.js
{
"version": "<version>",
"description": "<short description>",
"breaking": false,
"recommendMigrate": false,
"changelog": "<changelog text with real newlines>",
"notes": "<notes>",
"migrations": []
}
EOF
For breaking releases with many rename entries, generate the entries with a small temporary Node script and pipe the final JSON into create-manifest.js.
Step 7: Create Docs-Site Changelogs
This step is mandatory for every release.
Create both files:
docs-site/changelog/v<version>.mdx
docs-site/zh/changelog/v<version>.mdx
Use the format from recent changelog files. English and Chinese structure must match 1:1.
Update docs-site/docs.json:
- Add
"changelog/v<version>" to the English changelog pages list at the top.
- Add
"zh/changelog/v<version>" to the Chinese changelog pages list at the top.
- Update navbar changelog links to the new version.
When a <Note> or <Warning> block contains a markdown list, the closing tag must start at column 0:
<Note>
- bullet
</Note>
Step 8: Docs Lifecycle
The docs-site root path is stable. Development cycles live under beta/ or rc/.
| Transition | Script | When |
|---|
| Start a new beta | docs-site/scripts/docs-beta-start.sh | Before the first beta of a new minor/major, for example 0.6.0-beta.0. |
| Beta to RC | docs-site/scripts/docs-beta-to-rc.sh | Before the first rc, for example 0.6.0-rc.0. |
| RC to GA | docs-site/scripts/docs-promote.sh | Before pnpm release:promote. |
Per-patch releases (-beta.1, -rc.1, 0.5.1) do not run lifecycle scripts. Write changelog MDX, update docs.json, commit/push docs-site, then bump the main repo submodule pointer.
Full reference: .trellis/spec/docs-site/docs/release-lifecycle.md.
Step 9: Preflight Before Release
Run local verification only; do not publish locally.
node packages/cli/scripts/check-docs-changelog.js --type <beta|rc|promote>
node packages/cli/scripts/release-preflight.js check-versions
node packages/cli/scripts/release-preflight.js verify-packed-cli
node packages/cli/scripts/release-preflight.js publish-plan
pnpm lint
pnpm typecheck
pnpm test
Skip check-docs-changelog only for stable patch releases where that command is not required by the release type.
Step 10: Review and Confirm
Verify:
packages/cli/src/migrations/manifests/<version>.json exists and has valid JSON.
- Manifest
changelog renders as real newlines.
- Both docs-site changelog MDX files exist and match 1:1.
- All submodule commits are pushed before the main repo pointer commit (currently
docs-site/ + marketplace/). Verify with: git submodule foreach 'sha=$(git rev-parse HEAD); git ls-remote origin $sha | grep -q $sha && echo "ok $name" || echo "FAIL $name $sha"'. Tag-triggered CI does git submodule update --init --recursive and fails on the first unpushed pointer with fatal: remote error: upload-pack: not our ref <SHA>.
@mindfoldhq/trellis and @mindfoldhq/trellis-core versions still match.
Step 11: Publish Through CI
Use the project release script so the tag starts CI:
pnpm release
pnpm release:beta
pnpm release:rc
pnpm release:promote
After CI succeeds, verify public npm:
npm view @mindfoldhq/trellis@<version> version dist-tags --json --registry=https://registry.npmjs.org/
npm view @mindfoldhq/trellis-core@<version> version dist-tags --json --registry=https://registry.npmjs.org/
If CI fails or npm visibility is wrong, fix the workflow/scripts and re-run the CI path. Do not use local publish to fill the gap.
Dogfooding
Breaking releases must run end-to-end migration in a throwaway directory:
mkdir /tmp/migrate-test && cd /tmp/migrate-test && git init -q .
npx -y @mindfoldhq/trellis@<last-ga> init -y -u test --claude --cursor --<platforms>
node <repo>/packages/cli/dist/cli/index.js update --migrate --dry-run
yes | node <repo>/packages/cli/dist/cli/index.js update --migrate --force
yes | node <repo>/packages/cli/dist/cli/index.js update
Watch for orphan files, idempotency churn, and backup bloat.