Skip to main content
renew and schedule keep parked logins, the logins pitboard holds for accounts not in use, alive. log lists what pitboard changed, uninstall removes pitboard’s files and doctor checks the machine. Each command also takes --json and --help, described in Global options, so the options tables leave them out.

renew

A parked login is due when its access token has expired or expires within 2 minutes. It is also due when its refresh token expires within 3 days. A parked login whose refresh token has expired is never due, because it cannot be renewed. Its account needs a sign-in again: see Sign in to an account again. A parked login of OpenAI’s Codex CLI records no refresh token expiry, so only its access token makes it due. pitboard renew asks the service that issued each due parked login, Anthropic or OpenAI, to renew it. It sends the requests at the same time and parks each renewed login in place of the old one. It does not switch accounts or ask for usage. Without --offline, pitboard status also renews, but only parked logins whose access token has expired or expires within 2 minutes. pitboard never renews the login a tool is using. Renewing a parked login that copies it would use up the refresh token the tool holds, so renew drops that parked login instead. The account needs no sign-in, because the tool holds the same login. A parked login the service refuses is dropped, and its account needs a sign-in again. A parked login the service could not renew, because the service was unreachable or asked for less traffic, is tried again next time. renew prints one of these lines, and exits with status 0 even when nothing could be renewed:
See Keep parked logins alive.

schedule

pitboard schedule install sets up a job that runs pitboard renew every 24 hours. On macOS the job is a LaunchAgent, and on Linux a systemd user timer. For its files, see Files and environment variables. The job runs renew from the full path of the pitboard program that installed it. If nothing is at that path any more, pitboard doctor fails its renewal schedule check. For the fix, see Daily renewal stopped working. The job does not carry PITBOARD_HOME, the variable that moves pitboard’s directory, so it always renews the parked logins of the accounts in ~/.pitboard. pitboard schedule uninstall removes the job whatever PITBOARD_HOME is set to. pitboard schedule status checks only that the job’s file exists. It does not ask launchd or systemd whether the job is loaded. On a Mac:
See Keep parked logins alive.

log

pitboard log prints the last 20 changes, or as many as --lines asks for, oldest first. Each line gives the local time, a verb, the subject (what the change was about) and the outcome. The outcome is ok, a code from the following table, or the code of the error that stopped the change. With no changes logged, it prints pitboard has not changed anything yet. The log includes changes made from the app. Only --json says where each came from, in caller: cli, app, or unknown for older lines that do not say. pitboard keeps the log in ~/.pitboard/audit.log. Past 256 KiB, it moves the file to audit.log.1, replacing the one there, and pitboard log reads both. The log holds labels, codes and times, and no email addresses. It holds an account id only in a reclaim line with the outcome discarded. That line’s subject is a parked login’s name, which contains the account id.
See Troubleshooting.

uninstall

pitboard uninstall works in this order:
  1. It removes the daily renewal schedule. If that fails, it stops before deleting anything.
  2. It deletes every parked login this pitboard wrote.
  3. It deletes ~/.pitboard, but only if every parked login was deleted.
The login each tool is using stays in place. On macOS, uninstall also leaves any parked login that pitboard repair gave back but this pitboard did not write. Every pitboard on the Mac shares the keychain, so one with another PITBOARD_HOME may own it. It removes the schedule only when pitboard’s directory is ~/.pitboard. With PITBOARD_HOME set to another directory, it deletes that directory and leaves the schedule, which pitboard schedule uninstall removes. The question and the output still say ~/.pitboard. uninstall refuses to run while CLAUDE_CODE_CUSTOM_OAUTH_URL is set, in the environment or in Claude Code’s settings, and fails with custom_oauth_endpoint. With that variable set, Claude Code keeps its login under a name pitboard does not read. In a terminal, it asks first:
For when it asks and when it does not, see Output. Any answer but y, Y or yes stops it with nothing deleted. With two parked logins and daily renewal on:
It can also print these lines: See Remove pitboard.

doctor

pitboard doctor prints one line per check: a mark, the check’s name and what it found. When there is something to do, the next line says what. It changes nothing and sends no network request. The last line sums up: doctor exits with status 3 when a check fails, and 0 otherwise. With --json, a failed check also sets ok to false and gives the error code checks_failed. For the fields, see JSON output. pitboard doctor --json replaces email addresses, your user name, account ids, organisation ids and names, login fingerprints and parked login names with digests such as <email 1a2b3c4d>. It writes your home folder as ~. The text report hides nothing. Codex’s checks come last, under the heading Codex. They appear when Codex’s directory (~/.codex, or CODEX_HOME) exists or a Codex account is enrolled. With a Codex account enrolled, codex_backend fails when Codex keeps its login anywhere but auth.json. codex_login warns when Codex is signed in with an API key. With none enrolled, both are ok in those cases. A login in auth.json that pitboard cannot read fails codex_login either way. When Codex’s checks appear and Claude Code is absent, doctor leaves out most of Claude Code’s checks. Claude Code is absent when it has no config file, no claude program and no login, and no Claude Code account is enrolled.
The checks in the order doctor prints them. In a name, <label> is an account’s label.
See Troubleshooting.