Migration Guide
Agent Quick Context
- Run
pm normalizeafter every upgrade โ rewrites items to the current format safely - Run
pm validateafter normalizing to surface any remaining issues - Breaking changes in 2026.5.x:
--blocked-by noneremoved, priority is integer 0โ4 (named aliasescritical|high|medium|low|minimalare re-supported as of 2026.5.24), date alias"today"not recognized - New in 2026.5.24: register custom item types with
pm schema add-type <Name>; preview deletions withpm delete --dry-run; install hints when invoking unknown package-owned commands (pm guide,pm templates,pm calendar,pm cal) - Recovery:
pm restore <id> <timestamp>replays any item from its history log - Rollback:
npm install -g @unbrained/pm-cli@<version> - History files (
.agents/pm/history/<id>.jsonl) are never modified by migration tooling โ always safe to restore from
When You Need This Guide
Run through this guide whenever you have just upgraded pm-cli:
npm install -g @unbrained/pm-cli # or pnpm / yarn equivalent
pm --version # confirm the new version
If you skipped one or more releases, read the breaking-changes section for every release between your old version and the new one.
Before Upgrading
1. Check current state
Make sure your tracker has no pre-existing errors before you upgrade:
pm health
pm validate
Fix any reported issues. Upgrading on top of a broken tracker makes it harder to tell whether a problem was pre-existing or caused by the upgrade.
2. Dry-run the cache cleaner
pm gc --dry-run
This shows what pm gc would delete without actually deleting anything.
Review the output so you know the baseline state of your cache.
3. Back up your tracker data
cp -r .agents/pm .agents/pm-backup-$(date +%Y%m%d)
This is especially important before a major version bump. The backup lets you roll back data even if you need to keep the new binary.
General Upgrade Steps
Run these steps in order after every upgrade:
# 1. Install the new version
npm install -g @unbrained/pm-cli
# 2. Confirm the version
pm --version
# 3. Check overall health
pm health
# 4. Normalise item format to the current schema
pm normalize
# 5. Validate all items
pm validate
# 6. Clean cache artefacts
pm gc
If pm normalize or pm validate report errors, see the sections below.
Format Migration
Background
pm-cli stores items as TOON files (default) or JSON-markdown files. The exact
schema of the frontmatter evolves between releases. pm normalize handles
routine schema migrations automatically.
When pm normalize crashes on an item
In some versions, pm normalize crashes when it encounters non-JSON
frontmatter in a file that is expected to have JSON frontmatter (or vice
versa). This can happen if items were created with an older format and were
never migrated.
Symptoms
Error: Failed to parse item pm-3042: Unexpected token < in JSON at position 0
pm normalize aborted. 3 items were not migrated.
Manual recovery steps
Identify the failing item from the error output (e.g.
pm-3042).Find the raw file on disk:
find .agents/pm -name "pm-3042*" -not -path "*/history/*"Open the file. The frontmatter is the block between the opening
---delimiters (TOON) or the opening{...}block (JSON-markdown).Determine which format your tracker uses:
cat .agents/pm/settings.json | grep formatManually convert the frontmatter to the expected format. The required fields are
id,type,title,status, andcreated. All other fields are optional.Example of a valid TOON frontmatter block:
--- id: pm-3042 type: Task title: Fix login redirect status: open priority: 2 created: 2026-04-01T09:00:00.000Z ---Validate the repaired item:
pm validate pm-3042Repeat for each failing item, then re-run:
pm normalize pm validate
After migration
Once pm normalize and pm validate both complete without errors, run:
pm reindex
This rebuilds the search index from the newly normalised files.
Breaking Changes by Version
2026.5.23 โ 2026.5.24
No breaking changes. This release is purely additive plus one data-recoverability fix:
pm schema add-type <Name>is a first-class command for registering custom item types into.agents/pm/schema/types.json(idempotent upsert; alias-safe; built-in types protected).pm create/pm updateaccept the named priority aliasescritical|high|medium|low|minimalin addition to numeric0..4.pm delete --dry-runpreviews the item file that would be removed without mutating disk โ safe for agent workflows.- Unknown package-owned commands (
pm guide,pm templates,pm calendar,pm cal) now print concrete install hints instead of a generic "command not found" error. pm initprints a concise summary by default; the full settings tree is now behind--verbose(--jsonoutput unchanged).pm gchelp clarifies that cache artefacts are deleted by default; use--dry-runto preview.- Recovers item files that were unreadable on 2026.5.23 due to a TOON
2.3.0 strict-decoder bug parsing scalars that contain
[bracket]:tokens (e.g.[Unreleased]:).pm get/pm list/pm searchno longer emititem_list_item_read_failedwarnings for these items.
# Register and use a custom type
pm schema add-type Spike --description "Time-boxed research item"
pm create Spike "Investigate cache options"
# Preview a delete safely
pm delete pm-tsk-abc123 --dry-run
# Concise init summary
pm init # short
pm init --verbose # full settings tree
2026.3.x โ 2026.5.x
--blocked-by none removed
The --blocked-by none shorthand for clearing a blocker has been removed.
# Old (2026.3.x) โ no longer works
pm update pm-3042 --blocked-by none
# New (2026.5.x)
pm update pm-3042 --unset blocked-by
If you have scripts or automation that used --blocked-by none, update them
before upgrading.
Priority values are integers โ named aliases are re-supported in 2026.5.24
Internally priority is stored as an integer 0โ4. In 2026.5.0โ2026.5.23 the CLI
only accepted the raw integer. As of 2026.5.24 the CLI accepts named
aliases at the command line again (on pm create / pm update and in filters),
mapping them to the canonical integer:
| Alias | Integer |
|---|---|
critical |
0 |
high |
1 |
medium |
2 |
low |
3 |
minimal |
4 |
# These are equivalent on 2026.5.24+
pm create Task "Fix login" --priority critical
pm create Task "Fix login" --priority 0
Items stored with the legacy string priority values are automatically
converted to integers by pm normalize. Custom priority strings outside the
five canonical aliases above remain unsupported.
Date aliases changed
The "today" date alias is no longer recognised. Use ISO dates or relative
offsets:
# Old โ no longer works
pm update pm-3042 --due today
# New
pm update pm-3042 --due 2026-05-03 # explicit ISO date
pm update pm-3042 --due +0d # relative: zero days from now
Rollback
If an upgrade causes problems you cannot resolve, pin the previous version:
npm install -g @unbrained/pm-cli@<previous-version>
Example โ rolling back to 2026.3.1:
npm install -g @unbrained/[email protected]
pm --version # should print 2026.3.1
Your data files are not modified by the install or uninstall steps, so
rollback is always safe as long as you have not run pm normalize with a
format that the old binary cannot read. If you have, restore from the backup
you made before upgrading:
rm -rf .agents/pm
cp -r .agents/pm-backup-<date> .agents/pm
Data Recovery
Restore a single item from history
Every write to an item is appended to .agents/pm/history/<id>.jsonl. This
log is never modified by migration tooling, so you can always recover a
previous state.
# List all snapshots for an item
pm history pm-3042
# Restore the item to a specific point in time
pm restore pm-3042 2026-04-15T10:30:00.000Z
# Restore to the most recent snapshot (useful after accidental deletion)
pm restore pm-3042 latest
Restore all items to a pre-migration state
If a migration went badly and you need to roll back all item data:
- Stop any running pm-cli processes.
- Replace the active store with your backup:
rm -rf .agents/pm cp -r .agents/pm-backup-<date> .agents/pm - Reinstall the previous pm-cli version (see Rollback).
- Run
pm healthto confirm the restored state.