Documentation menu
Upgrading from terminid
terminid is now nid. Same program, same team, shorter name: nid is French for nest, the
thing the colony builds (see the brand story). If you run a terminid alpha,
you do not have to do anything: run terminid update (or wait for the update notice) and you
land on nid with your groups, sessions, worktrees and settings intact.
Still on a pawmux alpha? pawmux update lands you on nid in the same single step, straight
from ~/.pawmux; Upgrading from pawmux has the details that are
specific to it.
Before you update#
Run terminid update from a plain terminal: not an agent's shell and not a dashboard
terminal (the update stops the daemon that runs those, so they would end halfway; terminid and nid
refuse there and tell you so). Put its working directory outside the agents' worktrees, and close
editors that have files open in them, so the worktrees can be moved. When it is done, open a new
terminal to run nid: the one you updated from still has the old PATH.
What happens on update#
terminid update downloads the newest release. The first nid releases also ship their
binaries under the old asset names (terminid-<os>-<arch>[.exe], and pawmux-* for older
alphas), 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:
| Step | Before | After |
|---|---|---|
| Binary | ~/ or %LOCALAPPDATA%\ | ~/.nid/bin/nid or %LOCALAPPDATA%\ |
| PATH | the # terminid profile lines or Windows user Path entry | a # nid line or entry ahead of the old one, which stays while the shim lives there; nid uninstall removes both |
| Daemon | the running terminid daemon (alpha.10, alpha.11 or alpha.12) | stopped cleanly, then started as nid; sessions resume. The two never run side by side on the same state |
| Old command | terminid (and pawmux, if you still had that shim) | the 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:
| What | From | To |
|---|---|---|
| Data directory | ~/.terminid | ~/.nid |
| Database | terminid.db | copied to nid.db |
| User settings | ~/ | copied to ~/ |
| Stored secrets | keychain / DPAPI service terminid | copied to service nid (the old entries stay) |
| Agent worktrees | ~/ | moved to ~/ 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 |
| Release verify stamps | .git/ | read from .git/ from now on; existing stamps stay valid |
| Start at login | terminid-daemon task, dev agent or terminid | the nid equivalents, only if autostart was on |
| Notifications | app id terminid | app id nid |
Everything except the worktrees is copied, so ~/.terminid 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
terminid 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 terminid daemon that is still running is stopped
first, and the sessions it was running resume under nid.
If you chose a data directory yourself (TERMINID_HOME, PAWMUX_HOME or NID_HOME), nid
keeps using it and upgrades it in place: terminid.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 ~/.terminid. An old
terminid 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 terminid daemon on the
old state. nid --version, --help, help and doctor never migrate anything; doctor
tells you when terminid or pawmux state is waiting to come over.
Things that keep their old names on purpose:
- Git branches. Groups created under terminid keep their
terminid/and<group> terminid/branches (and pawmux groups their<group>--<agent> pawmux/...ones);nid land,diff,syncandrmuse the stored names. New groups getnid/.<group> - Environment variables.
TERMINID_*variables, thenPAWMUX_*ones, are still read when the matchingNID_*one is unset, with one deprecation line each. See configuration. terminid.yaml. Still read when nonid.yamlexists (andpawmux.yamlafter it), with a one-line notice.- Running agents. Agents that were mid-conversation keep working: their MCP server entry
still says
terminiduntil their next spawn, when it becomesnid(tools unchanged), and they still receiveTERMINIDfor one release._SESSION
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 terminid 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 ~/.terminid), then renames terminid.yaml (or
terminid.yml, pawmux.yaml, 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 terminid one, after renaming
the old one to nid.
Upgrading by hand#
You never need to, but if you would rather not let the old updater do it, or terminid update
cannot reach GitHub:
Install nid with the usual installer (it does not touch
~/.terminid):curl -fsSL https://nid.dev/install.sh | shirm https://nid.dev/install.ps1 | iexIf nid.dev is unreachable, use the copies on GitHub:
https:/(and/ github .com/ CatsWithKeyboards/ nid/ releases/ latest/ download/ install .sh install.ps1), or downloadnid-<os>-<arch>[.exe]from the releases page and check it againstSHA256SUMS.- Run
nid doctor. It reports the terminid state it found and the running terminid daemon, without changing anything. - Run
nid migratein one of your repositories. It stops the terminid daemon, migrates~/.terminid, renames that repository'sterminid.yamland starts the nid daemon; the sessions that were running resume. - Run
nid migratein every other repository that has aterminid.yaml.
Installed with a package manager? The winget package is now CatsWithKeyboards and the
Homebrew formula is nid; install those and remove the terminid ones.
Rename at your own pace#
None of this is urgent; the compatibility paths stay for several releases.
- Run
nid migratein each repository that has aterminid.yamlorpawmux.yaml. - Rename
TERMINID_*(andPAWMUX_*) variables in your shell profile, CI and scripts toNID_*. - Replace
terminid(andpawmux) withnidin your own scripts and aliases. The shims will go away in a later release, and they print a reminder until then. - Point bookmarks and scripts at the new install URLs:
https:/and/ nid .dev/ install .sh https:/. The terminid.dev URLs redirect there, and so does terminid.com; the GitHub repository is now/ nid .dev/ install .ps1 CatsWithKeyboards/(old links redirect).nid
When something gets stuck#
- The old daemon will not stop. The migration then stops before changing anything and
says so.
nid daemon stopstops 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.txtlists it until then. Or set it again withnid auth set <agent> --api-key. - The migration stopped halfway (a crash, a closed terminal). The next nid command
finishes it. Existing nid state that
--forcereplaced is backed up once, before anything changes, and never again on the resumed run.
Deleting ~/.terminid#
Keep it while you might go back to a terminid release. When you delete it, remove the
worktree links first: the moved groups' old folders under ~/ are links
into ~/, 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%\.terminid\worktrees\*") do rmdir "%G"
rmdir /s /q "%USERPROFILE%\.terminid"
find ~/.terminid/worktrees -mindepth 1 -maxdepth 1 -type l -exec rm {} +
rm -rf ~/.terminid
If MIGRATED.txt says some worktrees were not moved yet, keep the directory: they still live
there. The same applies to ~/.pawmux if you came from pawmux; see
Deleting undefined.
Rolling back#
Upgrades are one-way: what nid keeps reading, and for how long, is in Compatibility and upgrades.
There is no undo command, and nid update refuses to install a release from before nid (the
first nid release is 0.1.0-alpha.13): an old release would run on ~/.terminid while your state
is in ~/.nid. Going back is a few manual steps.
What you get back: ~/.terminid exactly as it was when nid migrated it (its terminid.db is
untouched; that is the database terminid uses again). Anything you did under nid (new groups,
tasks, notes, sessions) is only in ~/.nid and stays there. Worktree groups that moved are still
reachable through their links in ~/, so their files are where you left them;
groups nid created after the upgrade exist only in ~/.
Stop nid and its login item:
nid daemon stop nid daemon autostart offRemove the
daemon.jsonthat nid left in~/.terminid(and in~/.pawmux, if you came from pawmux). It points old binaries at the nid daemon. nid removes it when it stops cleanly, but a crash can leave it behind; delete it if it is still there:rm -f ~/.terminid/daemon.json ~/.pawmux/daemon.jsonRemove-Item -Force "$HOME\.terminid\daemon.json", "$HOME\.pawmux\daemon.json" -ErrorAction SilentlyContinuePut terminid alpha.12 back where it was. The
terminidthere now is a copy of nid (the shim), and the install scripts of today install nid, so take the old binary from one of these:Windows: the alpha.12 updater kept the previous binary next to the shim, as
%LOCALAPPDATA%\. Move the shim aside and that file back (terminid\ bin\ terminid .exe .old-<number>-<id> terminidfiles are never deleted by nid):.exe .old-* $bin = "$env:LOCALAPPDATA\terminid\bin" Rename-Item "$bin\terminid.exe" "terminid.exe.nid-shim" Get-ChildItem "$bin\terminid.exe.old-*" | Sort-Object LastWriteTime | Select-Object -Last 1 | Copy-Item -Destination "$bin\terminid.exe"Any platform (macOS and Linux keep no previous binary): run the v0.1.0-alpha.12 install script with that version pinned. It installs the real alpha.12 to
~/(.terminid/ bin/ terminid %LOCALAPPDATA%\) and checks it against that release'sterminid\ bin\ terminid .exe SHA256SUMS:curl -fsSL https://raw.githubusercontent.com/CatsWithKeyboards/nid/v0.1.0-alpha.12/install.sh | TERMINID_VERSION=0.1.0-alpha.12 sh& ([scriptblock]::Create((irm https://raw.githubusercontent.com/CatsWithKeyboards/nid/v0.1.0-alpha.12/install.ps1))) -Version 0.1.0-alpha.12
Before you upgrade in the first place, copying
terminid(.exe)somewhere safe makes this step a plain copy back.PATH: nid's directory (
~/.nid/bin,%LOCALAPPDATA%\) sits ahead of terminid's but only holdsnid\ bin nid, soterminidruns the restored binary either way. Remove the# nidline from your shell profile (or the entry from your Windows userPath) if you want nid gone from PATH. Do not runnid uninstallfor this: it removes theterminidandpawmuxbinaries in their old install directories too.Start terminid:
terminid daemon start(andterminid daemon autostart onif you used it).
To come back to nid later, install it again (or run the nid binary in ~/.nid/bin). It does not
migrate a second time on its own (~/ says it already did), so bring
the terminid state you worked on in the meantime over explicitly: delete that file, then run
nid migrate --force, which replaces ~/.nid's database with terminid's after keeping a backup
(nid).
A nid daemon that starts while a terminid daemon runs on ~/.terminid stops that terminid
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, and don't point both at the same groups. nid daemon stop (and
terminid daemon stop through the shim) stops a terminid daemon on ~/.terminid 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 terminid's (its singleton pipe or socket, or for
alpha.10 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
~/ usually say why, and a bug report with that output is the quickest
way to fix it for the next person.