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:

StepBeforeAfter
Binary~/.terminid/bin/terminid or %LOCALAPPDATA%\terminid\bin\terminid.exe~/.nid/bin/nid or %LOCALAPPDATA%\nid\bin\nid.exe
PATHthe # terminid 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 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 commandterminid (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:

WhatFromTo
Data directory~/.terminid~/.nid
Databaseterminid.dbcopied to nid.db
User settings~/.terminid/config.yamlcopied to ~/.nid/config.yaml
Stored secretskeychain / DPAPI service terminidcopied to service nid (the old entries stay)
Agent worktrees~/.terminid/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
Release verify stamps.git/terminid-verify/read from .git/nid-verify/ from now on; existing stamps stay valid
Start at loginterminid-daemon task, dev.terminid.daemon agent or terminid.servicethe nid equivalents, only if autostart was on
Notificationsapp id terminidapp 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/<group> and terminid/<group>--<agent> branches (and pawmux groups their pawmux/... ones); nid land, diff, sync and rm use the stored names. New groups get nid/<group>.
  • Environment variables. TERMINID_* variables, then PAWMUX_* ones, are still read when the matching NID_* one is unset, with one deprecation line each. See configuration.
  • terminid.yaml. Still read when no nid.yaml exists (and pawmux.yaml after it), with a one-line notice.
  • Running agents. Agents that were mid-conversation keep working: their MCP server entry still says terminid until their next spawn, when it becomes nid (tools unchanged), and they still receive TERMINID_SESSION for one release.

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.db.bak-<time>.

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:

  1. Install nid with the usual installer (it does not touch ~/.terminid):

    curl -fsSL https://nid.dev/install.sh | sh
    irm https://nid.dev/install.ps1 | iex

    If nid.dev is unreachable, use the copies on GitHub: https://github.com/CatsWithKeyboards/nid/releases/latest/download/install.sh (and install.ps1), or download nid-<os>-<arch>[.exe] from the releases page and check it against SHA256SUMS.

  2. Run nid doctor. It reports the terminid state it found and the running terminid daemon, without changing anything.
  3. Run nid migrate in one of your repositories. It stops the terminid daemon, migrates ~/.terminid, renames that repository's terminid.yaml and starts the nid daemon; the sessions that were running resume.
  4. Run nid migrate in every other repository that has a terminid.yaml.

Installed with a package manager? The winget package is now CatsWithKeyboards.nid 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.

  1. Run nid migrate in each repository that has a terminid.yaml or pawmux.yaml.
  2. Rename TERMINID_* (and PAWMUX_*) variables in your shell profile, CI and scripts to NID_*.
  3. Replace terminid (and pawmux) with nid in your own scripts and aliases. The shims will go away in a later release, and they print 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. The terminid.dev URLs redirect there, and so does terminid.com; the GitHub repository is now CatsWithKeyboards/nid (old links redirect).

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 ~/.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 ~/.terminid/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%\.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 ~/.terminid/worktrees, so their files are where you left them; groups nid created after the upgrade exist only in ~/.nid/worktrees.

  1. Stop nid and its login item:

    nid daemon stop
    nid daemon autostart off
  2. Remove the daemon.json that 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.json
    Remove-Item -Force "$HOME\.terminid\daemon.json", "$HOME\.pawmux\daemon.json" -ErrorAction SilentlyContinue
  3. Put terminid alpha.12 back where it was. The terminid there 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%\terminid\bin\terminid.exe.old-<number>-<id>. Move the shim aside and that file back (terminid.exe.old-* files are never deleted by nid):

      $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%\terminid\bin\terminid.exe) and checks it against that release's 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.

  4. PATH: nid's directory (~/.nid/bin, %LOCALAPPDATA%\nid\bin) sits ahead of terminid's but only holds nid, so terminid runs the restored binary either way. Remove the # nid line from your shell profile (or the entry from your Windows user Path) if you want nid gone from PATH. Do not run nid uninstall for this: it removes the terminid and pawmux binaries in their old install directories too.

  5. Start terminid: terminid daemon start (and terminid daemon autostart on if 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 (~/.nid/migrated-to-nid.json 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.db.bak-<time>).

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_ALLOW_LEGACY_DAEMON=1, 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 ~/.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.