Documentation menu

Upgrading from pawmux

pawmux became terminid in 0.1.0-alpha.10, and terminid is now nid. Same program, same team, new name. If you still run a pawmux alpha, you do not have to do anything: run pawmux update (or wait for the update notice) and you land on nid directly, in one step, with your groups, sessions, worktrees and settings intact. You never pass through terminid.

Already on terminid? Read Upgrading from terminid instead; it works the same way.

What happens on update#

pawmux update downloads the newest release. nid releases still ship their binaries under the old pawmux asset names (pawmux-<os>-<arch>[.exe]), so an old updater finds them. When the new binary first starts under the old name or from the old install directory, it moves itself over:

StepBeforeAfter
Binary~/.pawmux/bin/pawmux or %LOCALAPPDATA%\pawmux\bin\pawmux.exe~/.nid/bin/nid or %LOCALAPPDATA%\nid\bin\nid.exe
PATHthe # pawmux profile lines or Windows user Path entrya # nid line or entry ahead of the old one, which stays while the shim lives there; nid uninstall removes both
Daemonthe running pawmux daemonstopped cleanly, then started as nid; sessions resume
Old commandpawmuxthe old file becomes a shim: it prints a one-line deprecation note and runs nid with the same arguments (it stays a full binary, so running agents that call it by path keep working)

Then it migrates your state, once, before anything else touches it:

WhatFromTo
Data directory~/.pawmux~/.nid
Databasepawmux.dbcopied to nid.db
User settings~/.pawmux/config.yamlcopied to ~/.nid/config.yaml
Stored secretskeychain / DPAPI service pawmuxcopied to service nid (the old entries stay)
Agent worktrees~/.pawmux/worktrees/...moved to ~/.nid/worktrees/... one group at a time; Git worktree links and the paths in the database are repaired, and each group's old folder becomes a link to its new place. Claude Code's conversation folders are copied along, so --resume finds them
Start at loginpawmux-daemon task, dev.pawmux.daemon agent or pawmux.servicethe nid equivalents, only if autostart was on

Everything except the worktrees is copied, so ~/.pawmux stays as it was. It gains a MIGRATED.txt that says what actually happened: the date, the new home, the nid version, which worktree groups moved and which did not. The migration runs once, when there is pawmux state and no nid migration marker yet; it is safe to start nid more than once, or from several terminals at the same time. A pawmux daemon that is still running is stopped first, and the sessions it was running resume under nid.

If you already moved from pawmux to terminid, ~/.pawmux has been migrated before (its MIGRATED.txt says so) and nid brings ~/.terminid over instead; see Upgrading from terminid.

If you chose a data directory yourself (PAWMUX_HOME, TERMINID_HOME or NID_HOME), nid keeps using it and upgrades it in place: pawmux.db is copied to nid.db next to it and keyring entries are copied to the new service name. Nothing is moved.

If a worktree group cannot be moved (on Windows, an editor or shell with a folder open inside it is enough), that group stays where it is and keeps working from there; the others move. MIGRATED.txt and nid doctor list what is still waiting, and nid tries again every time its daemon starts, before any session resumes. Close whatever holds the folder and run nid daemon restart to move it now.

While nid runs, it also leaves a copy of its daemon.json in ~/.pawmux. An old pawmux binary that is still around (a copy elsewhere on PATH, a script, an agent's config) finds the running nid daemon there and uses it, rather than starting a pawmux daemon on the old state. nid --version, --help, help and doctor never migrate anything; doctor tells you when pawmux state is waiting to come over.

Things that keep their old names on purpose:

  • Git branches. Groups created under pawmux keep their pawmux/<group> and pawmux/<group>--<agent> branches; nid land, diff and sync use the stored names. New groups get nid/<group>.
  • Environment variables. PAWMUX_* variables are still read when the matching NID_* one is unset, with one deprecation line each. See configuration.
  • pawmux.yaml. Still read when no nid.yaml exists, with a one-line notice.
  • Running agents. Agents that were mid-conversation keep working: their MCP server is now called nid from their next spawn (tools unchanged).

nid migrate#

nid migrate             # finish the job in this repository and report what changed
nid migrate --dry-run   # only show what it would do
nid migrate --force     # bring pawmux state over even though nid already has some

migrate runs the state migration above if it has not happened yet (useful when you installed nid fresh next to an old ~/.pawmux), then renames pawmux.yaml (or pawmux.yml) in the current project to nid.yaml, with git mv when the file is tracked. Commit the rename like any other change. Running it twice does nothing the second time.

If you used nid before migrating, it already has its own database, and migrate leaves both alone and says so. --force replaces the nid database with the pawmux one, after renaming the old one to nid.db.bak-<time>.

Rename at your own pace#

None of this is urgent; the compatibility paths stay for several releases.

  1. Run nid migrate in each repository that has a pawmux.yaml.
  2. Rename PAWMUX_* variables in your shell profile, CI and scripts to NID_*.
  3. Replace pawmux with nid in your own scripts and aliases. The shim will go away in a later release, and it prints a reminder until then.
  4. Point bookmarks and scripts at the new install URLs: https://nid.dev/install.sh and https://nid.dev/install.ps1.

When something gets stuck#

  • The old daemon will not stop. The migration then stops before changing anything and says so. nid daemon stop stops it (by force if it does not answer) without trying to migrate; the next nid command then migrates as usual.
  • A stored API key could not be read (a locked keyring). Everything else migrates; the key is retried each time the nid daemon starts, and MIGRATED.txt lists it until then. Or set it again with nid auth set <agent> --api-key.
  • The migration stopped halfway (a crash, a closed terminal). The next nid command finishes it. Existing nid state that --force replaced is backed up once, before anything changes, and never again on the resumed run.

Deleting ~/.pawmux#

Keep it while you might go back to a pawmux release. When you delete it, remove the worktree links first: the moved groups' old folders under ~/.pawmux/worktrees are links into ~/.nid/worktrees, and a recursive delete that follows links (Windows PowerShell 5.1's Remove-Item -Recurse does) deletes your worktrees in the new home too. MIGRATED.txt has the exact commands for your machine; in short:

:: cmd.exe: rmdir removes a link, never its target, and refuses a real folder that is not empty
for /d %G in ("%USERPROFILE%\.pawmux\worktrees\*") do rmdir "%G"
rmdir /s /q "%USERPROFILE%\.pawmux"
find ~/.pawmux/worktrees -mindepth 1 -maxdepth 1 -type l -exec rm {} +
rm -rf ~/.pawmux

If MIGRATED.txt says some worktrees were not moved yet, keep the directory: they still live there.

Rolling back#

Upgrades are one-way: what nid keeps reading, and for how long, is in Compatibility and upgrades.

There is no undo command, because there is little to undo: the database, settings and secrets were copied, and ~/.pawmux is still readable. To go back to a pawmux alpha:

nid daemon stop
nid daemon autostart off

Then reinstall the pawmux release you want from the GitHub releases page (its install script still works) and start it. It reads ~/.pawmux as it was at the moment of the upgrade; anything you did under nid (new groups, tasks, notes) is only in ~/.nid. Moved worktree groups are reachable through their links in ~/.pawmux/worktrees, so files in them are where you left them either way. Stop nid first: while it runs, ~/.pawmux/daemon.json points old binaries at the nid daemon.

A nid daemon that starts while a pawmux daemon runs on ~/.pawmux stops that pawmux daemon, because two daemons would drive the same worktrees. If you want both running on purpose, for example to try the rollback while keeping nid up, start nid with NID_ALLOW_LEGACY_DAEMON=1, and don't point both at the same groups. nid daemon stop (and pawmux daemon stop through the shim) stops a pawmux daemon on ~/.pawmux as well, before or after the migration. It only forces a daemon that answered with its own token and then did not exit, or one that is provably pawmux's (its command line and its port). A stale daemon.json left by a crash or reboot is reported and its pid left alone.

If something in the upgrade went wrong, please do not roll back silently: nid doctor and ~/.nid/logs/daemon.log usually say why, and a bug report with that output is the quickest way to fix it for the next person.