Migration Guide

Agent Quick Context

  • Run pm normalize after every upgrade โ€” rewrites items to the current format safely
  • Run pm validate after normalizing to surface any remaining issues
  • Breaking changes in 2026.5.x: --blocked-by none removed, priority is integer 0โ€“4 (named aliases critical|high|medium|low|minimal are 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 with pm 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

  1. Identify the failing item from the error output (e.g. pm-3042).

  2. Find the raw file on disk:

    find .agents/pm -name "pm-3042*" -not -path "*/history/*"
    
  3. Open the file. The frontmatter is the block between the opening --- delimiters (TOON) or the opening { ... } block (JSON-markdown).

  4. Determine which format your tracker uses:

    cat .agents/pm/settings.json | grep format
    
  5. Manually convert the frontmatter to the expected format. The required fields are id, type, title, status, and created. 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
    ---
    
  6. Validate the repaired item:

    pm validate pm-3042
    
  7. Repeat 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 update accept the named priority aliases critical|high|medium|low|minimal in addition to numeric 0..4.
  • pm delete --dry-run previews 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 init prints a concise summary by default; the full settings tree is now behind --verbose (--json output unchanged).
  • pm gc help clarifies that cache artefacts are deleted by default; use --dry-run to 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 search no longer emit item_list_item_read_failed warnings 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:

  1. Stop any running pm-cli processes.
  2. Replace the active store with your backup:
    rm -rf .agents/pm
    cp -r .agents/pm-backup-<date> .agents/pm
    
  3. Reinstall the previous pm-cli version (see Rollback).
  4. Run pm health to confirm the restored state.

Migration Guide local
Report an issue