pando help prints every command, as below. Flags can go before or after a command’s other arguments. Commands that read the API take --json and print the API’s own JSON; see For scripts and agents. pando api reaches every route of the API.
Every command
usage: pando <command> [args]
pando login [--server <url>] [--bootstrap | --with-credential] sign this machine in (in the browser)
pando logout [--server <url>] sign this machine out
pando auth status who this machine is signed in as
pando init [folder] [--name <name>] [--owner <org>] [--yes] [--dry-run] make a Pando repo or monorepo from a folder
pando clone <owner/name | name> [folder] [--text-only] set up a Pando repo or monorepo on this machine
pando worktree add <repo> <branch> [--issue n] | list | remove <path> | follow | mount one branch, one folder
pando branch list [--repo <path>] [--all] branches with ahead, behind and checks
pando branch view [<branch>] [--commits] one branch: checks, merge, reviews, head commit
pando diff [<branch>] [--json | --patch] [paths...] the branch diff against main
pando review [<branch>] [-m <comment>] review in Plannotator, or comment
pando merge [<branch>] [--force] land a branch on main with a merge commit
pando reference update <path> | sync move a reference to its newest commit
pando status this folder, its worktrees and references
pando status <pending|success|failure|error> [--context ci] [--target-url u] [--description d]
in a CI build: a check on its commit (PANDO_STATUS_TOKEN)
pando issue list [--state s] [--label l] [--assignee a] [--search w] a monorepo's issues, newest first
pando issue view <n> [--comments] one issue: its body, branches and timeline
pando issue create --title t [--body b] [--label l] [--key k] open an issue
pando issue comment <n> --body b [--key k] comment on one
pando issue close <n> [--reason not-planned] | reopen <n> close or reopen one
pando issue edit <n> [--title t] [--body b] [--base-version v] edit, label, assign one
pando issue link | unlink <n> [<branch>] merging the branch closes the issue
pando issue react <n> <reaction> [--comment id] [--remove] +1, -1, laugh, hooray, confused, heart, rocket, eyes
pando monorepo list | view [<owner/name>] your monorepos; one with its repos and members
pando monorepo rename <new-name> rename one (owners); the old name keeps working
pando monorepo edit --description <text> its one line under the name on the web (owners)
pando monorepo transfer <owner/name> <new-owner> [--yes] move one to an org, or back to a person (owners)
pando monorepo delete <owner/name> [--yes] delete one (owners)
pando members list | invite <email> [--owner] | remove <who> who belongs to a monorepo
pando members invites | revoke <email> invites still waiting; withdraw one
pando org create <login> [--name n] | list | view <org> organizations: a namespace many people share
pando org members [<org>] | add <org> <email | login> [--owner] who is in one; add someone (owners)
pando org remove <org> <login | email> | leave <org> take someone out (owners), or leave
pando mac broker [--dry-run] load Pando.app's broker (before FSKit mounts)
pando ci connect --org <slug> | status | disconnect --org <slug> a monorepo's Buildkite connection [--monorepo <owner/name>]
pando ci pipeline add <repo> <pipeline> | list | remove <repo> <pipeline> the pipeline pushes and merges start
pando ci build list [--pipeline p] [--branch b] [--state s] builds, newest first
pando ci build view | log | rebuild | cancel <build> one build: its jobs, a job's log [--job j] [--follow]
pando ci job retry <build> <job> run a job again
pando ci run <pipeline> [--branch b] start a build of a branch (default: main)
pando mirror status [--json] mirroring to GitHub: on or paused, one row per project [--monorepo <owner/name>]
pando mirror on | off [<project>] turn mirroring on or pause it, or one project's (owners)
pando mirror retry [<project>...] try again now, with the wait reset (owners)
pando mirror connect set it up: opens the repository's Settings (GitHub needs a browser)
pando release list | view [<tag>] a project's releases, newest first; one with its notes [--repo <path>]
pando release create <tag> [--generate] [--title t] [--notes n] [--draft] tag main and publish it (checks green, or --force)
pando release create <tag> <file>... with files: a draft, its files, then published
pando release upload <tag> <file>... | download [<tag>] a release's files (checked by SHA-256) [--pattern p] [--dir d]
pando release publish <tag> [--force] | delete <tag> publish a draft; delete one (its tag stays)
pando artifact add [<branch>] <file> [<image>...] a document (and its images) on a branch's page; the same name again is v2
pando artifact list [<branch>] the branch's artifacts, their versions and open comments
pando artifact get [<branch>] <name> [--version n] [-o dir] download a version's files (checked by SHA-256)
pando artifact open [<branch>] <name> its page in the browser
pando artifact comments [<branch>] [<name>] [--all] open threads: the quote, the comment, replies, ids
pando artifact comment [<branch>] <name> [--quote words] -m c comment on words, or on the whole file
pando artifact reply <id> -m c | resolve <id> [--reopen] answer a thread; resolve or reopen it
pando credential create --name <sandbox> | list | revoke <id> credentials that act as you
pando hook list | create <url> | delete <id> a repo's web hooks [--repo <path>] (owners write)
pando hook deliveries <id> | redeliver <delivery-id> what a hook sent; send one again
pando machine list machines that acted in the monorepo, and which are connected
pando profile [<login>] [--json] a person's profile: their graph for the last year, by month
pando activity [--monorepo <owner/name> | --all] [--limit n] what happened, newest first
pando session enable | disable record coding sessions on this machine, or stop
pando session status what this machine records, from where, and what it skips
pando session paths [add <folder> --program <name> | remove <folder>] where Claude Code, Codex, Pi or OpenCode keep sessions
pando session exclude | include [<owner/name>] [--project <path>] a repository or project you do not record, on every machine
pando session delete <id> [--monorepo <owner/name>] delete a session at once and for good
pando api <path> [-X method] [-f k=v] [-F k=v] [--paginate] any API call, signed as this machine (like gh api)
pando sync [--once] keep the monorepo's files outside projects/ live (the daemon)
pando history <path> [--limit n] [--json] every saved version of a file outside projects/
pando restore <path> --to <version | HH:MM> write an old version back, as a new save
pando resolve [<path>...] unfreeze a file after a conflict
pando fetch <path>... download large files outside projects/ kept as pointersThe CLI names a repository a monorepo in its own words: the pando monorepo command, the --monorepo flag and its help text. They mean the repository.
Sign in
pando login
pando login [--server <url>] [--bootstrap | --with-credential]Signs this machine in. It shows a code and a link, opens your browser when it can, and waits for you to confirm. git and pando on this machine then act as you.
| Flag | What it does |
|---|---|
--server <url> |
The Pando server. Default: the one in ~/.pando/config.toml, or PANDO_SERVER, else https://app.gitpando.com. |
--with-credential |
Sign in with a credential made by pando credential create, typed with no echo or piped in. No browser. |
--bootstrap |
Self-hosted servers only: make your user with the server’s bootstrap secret, typed with no echo. |
--login <login> |
With --bootstrap: the login to make. Default: your user name on this machine. |
--kind <kind> |
With the browser sign-in: machine (the default) or sandbox. |
--name <name> |
Your name on commits. Default: the account’s, else git config user.name. |
--email <email> |
Your email on commits. Default: the account’s, else git config user.email. |
The credential is kept in ~/.pando/credentials/, readable only by you.
pando logout
pando logout [--server <url>]Deletes this machine’s credential. The credential keeps working on the server until you revoke it with pando credential revoke.
pando auth status
pando auth statusShows the server, where the credential comes from, this machine’s name, and who the server says you are. It takes --server <url> too.
Set up a repository
pando init
pando init [folder] [--name <name>] [--owner <org>] [--yes] [--dry-run]Makes a Pando repository from a folder (default: the current folder), and you become its owner. A git repo becomes a plain repository. Any other folder becomes a repository with projects: each git repo under projects/ becomes one of its projects, other git repos inside it become references, and the rest of the folder becomes its shared files. Run it again after a failure: it skips what is done.
| Flag | What it does |
|---|---|
--name <name> |
The name on the server. Default: the folder’s name, in lower case. |
--owner <org> |
Make it in an organization you are in, as org/name. Default: your own account. |
--yes |
Take the default answer to every question. |
--dry-run |
Show what would happen and change nothing. |
--server <url> |
The Pando server. Default: the configured one. |
A name is lower-case letters, digits, ., _ and -, at most 39 characters, with no --.
pando clone
pando clone <owner/name | name> [folder] [--text-only]Sets up a repository on this machine: the shared files outside projects/ and a read-only main for every project, each a git clone. References are cloned when you ask, with pando reference sync. The folder defaults to the name. A bare name means the one in your own account, else the only one so named that you belong to.
| Flag | What it does |
|---|---|
--text-only |
Keep large shared files and binaries as pointers until pando fetch. For sandboxes. |
--kind <kind> |
How to check out each read-only main: sparse (a git clone, the default), or a mount, fuse (Linux with ArtifactFS) or fskit (a Mac with Pando.app on). |
--server <url> |
The Pando server. Default: the configured one. |
pando status
pando statusRun inside a repository: shows the server and your role, then each project with this machine’s worktrees (branch, kind, commit, changed files, unpushed commits) and each reference. With a state it posts a check instead; see pando status in a CI build.
Worktrees and branches
One branch, one folder. See Worktrees.
pando worktree
pando worktree add <repo> <branch> [--issue n] | list | remove <path> | follow | mount| Subcommand | What it does |
|---|---|
add <repo> <branch> [folders...] |
Makes the branch off main if it is new, and checks it out at <repo>/worktrees/<branch> (a / in the branch name becomes -). Branch main gives a read-only main. Folders, with the sparse kind, check out only those folders and the top-level files. |
list |
Every worktree of the repository on every machine: path, branch, machine, kind, ahead, behind, and when it was last seen. |
remove <path> |
Takes a worktree off this machine. It refuses when there is uncommitted or unpushed work. The branch stays on the server until it merges. |
follow |
Keeps this machine’s read-only mains at the server’s main until stopped. pando sync runs the same follower. |
mount |
Mounts again the worktrees whose mount stopped, after a restart for example. Sparse worktrees need nothing. |
| Flag | What it does |
|---|---|
--kind <kind> |
With add: sparse (a git clone with every file of the branch, the default on every machine), or a mount: fuse (Linux with ArtifactFS) or fskit (a Mac with Pando.app on). Pando’s cloud agents get fuse. |
--issue <n> |
With add: link the branch to issue n, so merging it closes the issue. A wrong number stops before anything is made. |
--json |
With list: print JSON. |
--force |
With remove: remove even with uncommitted or unpushed work, which is lost. |
--once |
With follow: move the mains once and stop. |
--poll <duration> |
With follow: how often to read the branch lists besides the live updates. Default 5m. |
pando branch list
pando branch list [--repo <path>] [--all]Lists open branches with ahead, behind, author, checks, whether they merge cleanly, state and head.
| Flag | What it does |
|---|---|
--repo <path> |
One repo. Default: the repo you are in, or every repo. |
--all |
Include merged branches. |
--json |
Print JSON: for each repo, its branches as the API lists them. |
pando branch view
pando branch view [<branch>] [--commits]Shows one branch as its page does: its state and title, its head commit, who made it and the machine that last pushed it, how far it is ahead of and behind main, whether it merges cleanly (and, when not, the paths changed on both sides), each check, and its reviews. With no branch, the branch of the worktree you are in.
| Flag | What it does |
|---|---|
--commits |
Also list the commits the branch adds (those not on main), newest first, at most 250. |
--repo <path> |
The repo. Default: the one you are in. |
--json |
Print {"branch", "reviews", "commits"}: the API’s answers for the branch, its reviews and its commits (the newest only, without --commits). |
Review and merge
diff, review and merge take the branch of the worktree you are in when you name none.
pando diff
pando diff [<branch>] [--json | --patch] [paths...]Shows the branch diff against main: the changes since the branch left main, as GitHub shows a pull request. Name paths to see only those.
| Flag | What it does |
|---|---|
--patch |
Print a unified diff, for git apply or a review tool. |
--json |
Print the API’s JSON. |
--repo <path> |
The repo. Default: the one you are in. |
pando review
pando review [<branch>] [-m <comment>]With no -m, opens the branch diff in Plannotator (it must be installed). Approving there posts an approval; annotations post a request for changes. With -m, posts the comment with no Plannotator. Reviews are comments and approvals, not a gate on merging.
| Flag | What it does |
|---|---|
-m <comment> |
Post this comment. |
--approve |
With -m: post it as an approval (people only). |
--request-changes |
With -m: post it as a request for changes. |
--repo <path> |
The repo. Default: the one you are in. |
pando artifact
pando artifact add [<branch>] <file> [<image>...]
pando artifact list [<branch>]
pando artifact get [<branch>] <name> [--version n] [-o dir]
pando artifact open [<branch>] <name>
pando artifact comments [<branch>] [<name>] [--all]
pando artifact comment [<branch>] <name> [--quote "<words>"] -m "<comment>"
pando artifact reply <id> -m "<reply>"
pando artifact resolve <id> [--reopen]Documents on a branch’s page, never in git: a plan, a diagram, a design, an exported guided review. add uploads the first file and the images it uses, kept by their paths from the document’s folder; the same name again is its next version. An agent reads the comments people leave with comments, uploads the next version with add, and answers with reply and resolve. With no branch, the branch of the worktree you are in. See Artifacts.
| Flag | What it does |
|---|---|
-m <text> |
comment, reply: the comment, Markdown. |
--quote <words> |
comment: the words it is on, plain, from one line. Default: the whole file. |
--version <n> |
get: the version. Default: the newest. |
-o <dir> |
get: the folder to write its files in. Default: this folder. |
--all |
comments: resolved threads too. |
--reopen |
resolve: open the thread again. |
--json |
Print the API’s answer. |
--repo <path> |
The repo. Default: the one you are in, or the only one. |
--monorepo <owner/name> |
The monorepo. Default: the one you are in. |
pando merge
pando merge [<branch>] [--force]Lands the branch on main with a merge commit, and names the issues the merge closes (each closes about a second later). It stops when checks are not green, when the branch and main both changed a file in different ways (Pando merges whole files, with no line-by-line merge), or, run in the branch’s worktree, when the branch on the server is not what you pushed. This machine’s read-only main then follows within a moment.
| Flag | What it does |
|---|---|
--force |
Merge past red or missing checks. The merge is recorded as forced. |
--wait |
Return only once this machine’s read-only main has the merge. For scripts. |
--repo <path> |
The repo. Default: the one you are in. |
Issues
A repository has one list of issues, numbered #1, #2, … An issue can be about one of its projects. A branch is linked to an issue by “Fixes #12” in its title, its description or one of its commits, or by pando issue link; merging the branch into main closes the issue.
pando issue
pando issue list [--state s] [--label l] [--assignee a] [--search w]
pando issue view <n> [--comments]
pando issue create --title t [--body b] [--label l] [--key k]
pando issue comment <n> --body b [--key k]
pando issue close <n> [--reason not-planned] | reopen <n>
pando issue edit <n> [--title t] [--body b] [--base-version v]
pando issue link | unlink <n> [<branch>]
pando issue react <n> <reaction> [--comment id] [--remove]A number can be written 12 or #12.
| Subcommand | What it does |
|---|---|
list |
The issues, newest first, and how many are open and closed for the same filters. |
view <n> |
One issue: its state, who opened it and from which machine, labels, assignees, project, tasks, the branches linked to it, its reactions, then its body as written (Markdown). With --comments, then its timeline: comments and events, oldest first. |
create --title <title> |
Opens an issue. |
comment <n> |
Comments on an issue. |
close <n> |
Closes it, as completed or as not planned. |
reopen <n> |
Opens it again. A later merge that names it closes it again. |
edit <n> |
Changes its title, body or project, and adds or removes labels and assignees, in one call. |
link <n> [<branch>] |
Links a branch (default: the branch of the worktree you are in), so merging it closes the issue. |
unlink <n> [<branch>] |
Takes that link away. A closing keyword in the branch’s title or commits still links it. |
react <n> <reaction> |
One of GitHub’s eight reactions: +1, -1, laugh, hooray, confused, heart, rocket, eyes (or the emoji). |
| Flag | What it does |
|---|---|
--state <state> |
With list: open (the default), closed or all. |
--label <label> |
With list: issues with this label; repeat it, and every one must match. With create: a label to put on it; repeat it. |
--assignee <login> |
With list: issues assigned to this person, @me, or none. With create: assign this member, or @me; repeat it. |
--author <login> |
With list: issues opened by this person, or @me. |
--project <path> |
With list: issues about this project, or none. With create and edit: the project it is about (none with edit takes it away). |
--search <words> |
With list: these words in the title or body. |
--sort <order> |
With list: created (the default), updated or comments. |
--limit <n> |
With list: how many issues. Default 30. |
--comments |
With view: also print the timeline. |
--title <title> |
With create and edit: the title, 1 to 256 characters. |
--body <text>, --body-file <file> |
With create, comment and edit: the text, Markdown, at most 65,536 characters. --body-file - reads standard input. |
--key <key> |
With create and comment: an idempotency key, up to 64 characters. Run again with the same key, the command makes nothing new and answers the first issue or comment. |
--reason <reason> |
With close: completed (the default) or not-planned. |
--comment <text> |
With close and reopen: comment first. |
--base-version <v> |
With edit and a body: the body_version your text was written from. If someone changed the body since, the edit is refused (edited) and nothing is overwritten. |
--add-label, --remove-label <label> |
With edit: repeat them. |
--add-assignee, --remove-assignee <login> |
With edit: members, or @me; repeat them. |
--repo <path> |
With link and unlink: the branch’s project. Default: the one you are in. |
--comment <id> |
With react: react to that comment (ic_..., from view --comments) instead of the issue. |
--remove |
With react: take your reaction back. |
--json |
Print the API’s answer: list, view (with --comments, the issue with its timeline under timeline), create, comment, close, reopen, edit, link and unlink (the issue now), react (its reactions now). A refusal prints the API’s error object on stderr. |
--monorepo <owner/name> |
The repository. Default: the one you are in. |
Labels are made and changed by owners in the web’s Settings, or with pando api on /monorepos/{owner}/{monorepo}/labels.
A task, start to end:
n=$(pando issue create --title "Merge refuses when pando.toml has a trailing comma" \
--body-file report.md --label bug --project projects/pando --key task-41 --json | jq .number)
pando worktree add projects/pando toml-error-line --issue "$n"
# work, commit, git push
pando merge # This merge closes #41 (each within about a second).References
pando reference
pando reference update <path> | syncA reference is someone else’s repo inside the repository, kept as a pointer to one commit. See References.
| Subcommand | What it does |
|---|---|
update <path> |
Moves the reference to the newest commit of its branch. The pointer is a shared file, so every machine running pando sync follows. |
sync |
Clones each reference that is not on this machine, read-only at its pointer’s commit, and moves the others to it. |
--kind <kind> (sparse, the default, fuse or fskit) sets how a new reference folder is checked out.
Members, credentials and repositories
pando members
pando members list | invite <email> [--owner] | remove <who>
pando members invites | revoke <email>Each subcommand takes the repository as owner/name before its other arguments, or uses the repository you are in.
| Subcommand | What it does |
|---|---|
list |
Members and their roles, then invites still waiting. |
invite <email> |
Adds the person now if they have an account, else they join when they first run pando login. |
remove <who> |
A login removes that member; unless they have the repository through its organization, their open pages and pando sync stop at once. An email withdraws that invite. |
invites |
Invites still waiting, with who sent them. |
revoke <email> |
Withdraws the invite for that email. |
| Flag | What it does |
|---|---|
--owner |
With invite: invite as an owner. Default: member. |
--json |
With list or invites: print the API’s answer (members, invites). |
--server <url> |
The Pando server. Default: the configured one. |
pando credential
pando credential create --name <sandbox> | list | revoke <id>Credentials that act as you, for another machine or a cloud sandbox.
| Subcommand | What it does |
|---|---|
create --name <name> --out <file> |
Makes a credential and writes its secret to the file, readable only by you. --out - writes it to a pipe instead (never to a terminal). In the sandbox, set PANDO_TOKEN from it. |
list |
Your credentials: ID, name, kind, created, last used. |
revoke <id> |
Stops a credential working. |
| Flag | What it does |
|---|---|
--kind <kind> |
With create: sandbox (the default) or machine. |
--server <url> |
The Pando server. Default: the configured one. |
git also runs pando credential as its credential helper for Pando URLs. You never run that part yourself.
pando monorepo
pando monorepo list | view [<owner/name>]
pando monorepo rename <new-name>
pando monorepo transfer <owner/name> <new-owner> [--yes]
pando monorepo delete <owner/name> [--yes]| Subcommand | What it does |
|---|---|
list |
Your repositories, with your role in each. |
view [<owner/name>] |
The repository you name, or the one you are in: its id, your role, how many members, and each project with main’s head and its clone URL. |
rename <new-name> |
Owners only. Renames the repository within its owner. The old owner/name keeps leading to it, for the API and for git, until it is given to another repository. Run in the repository’s folder, the folder takes the new name and its git remotes the new clone URLs. A pando sync already running keeps the old name until it restarts. |
transfer <owner/name> <new-owner> |
Owners only. Moves the repository to an organization you are in, or back to a person who is already its owner directly. Its own members stay; the organization’s people gain it, and the old owner’s lose it. The old owner/name keeps leading to it, for the API and for git. You type its full name to confirm. Run in the repository’s folder, the folder and its git remotes follow, as with rename. Run again, it changes nothing. |
delete <owner/name> |
Owners only. Deletes every project in it, their history, and its shared files. There is no undo. You type the full name to confirm. Folders on this machine stay. |
| Flag | What it does |
|---|---|
--monorepo <owner/name> |
With rename: the repository. Default: the one you are in. |
--json |
With view: print {"monorepo", "repos", "members"}, the API’s answers for the repository, its projects and members. With rename and transfer: the API’s answer. |
--yes |
Delete or transfer without typing the name. For scripts. |
--server <url> |
The Pando server. Default: the configured one. |
Organizations
An organization is a namespace many people share, like a person’s login: its repositories are org/name. Everyone in it can open and push to every repository it owns; its owners own them all. People are added at once, or by email at their first sign-in.
pando org
pando org create <login> [--name n] | list | view <org>
pando org members [<org>] | add <org> <email | login> [--owner]
pando org remove <org> <login | email> | leave <org>| Subcommand | What it does |
|---|---|
create <login> |
Makes an organization; you are its first owner. The login follows the rule for people’s logins (lower-case letters, digits and single dashes, at most 39) and shares their namespace, so a person’s login can’t be taken. Run again, it changes nothing. |
list |
The organizations you are in, with your role and how many people each has. |
view <org> |
Its login, name, description and website, your role, and its repositories you can open. |
members [<org>] |
Its people and their roles, then invites still waiting. Default: the organization that owns the repository you are in. |
add <org> <email | login> |
Owners only. A login is added at once. An email adds the person now if they have signed in with it, else at their first pando login. Run again, it changes nothing. |
remove <org> <login | email> |
Owners only. A login takes that person out: their access to its repositories ends within about 15 seconds, except where they are a member of one directly, and their open pages and pando sync there stop at once. An email withdraws that invite. |
leave <org> |
Takes you out. An organization keeps at least one owner. |
| Flag | What it does |
|---|---|
--name <name> |
With create: its display name, up to 100 characters. |
--owner |
With add: as an owner. Default: member. |
--json |
Print the API’s answer: create, list, view, members, and add (by login or by email). |
--server <url> |
The Pando server. Default: the configured one. |
An organization’s display name (up to 100 characters), description (up to 160) and website (an https address, up to 2,048) are changed by its owners in the web, or with pando api: pando api -X PATCH /orgs/<org> -f description="...". Make a repository in one with pando init --owner <org>, or move one in with pando monorepo transfer.
CI
Pando starts builds on Buildkite and shows their checks. See CI with Buildkite.
pando ci
pando ci connect --org <slug> | status | disconnect --org <slug>
pando ci pipeline add <repo> <pipeline> | list | remove <repo> <pipeline>| Subcommand | What it does |
|---|---|
connect --org <slug> |
Connects a Buildkite organization to the repository. It prints the webhook URL and token to put in Buildkite, and the steps. The token is shown once, only on a terminal. |
status |
The connections, the last event Pando received, and each pipeline with its last build. |
disconnect --org <slug> |
Removes the connection. Its builds leave Pando; its checks stay. |
pipeline add <repo> <pipeline> |
Owners only. Each push to a branch of the repo, and each merge into its main, then starts a build of that Buildkite pipeline. A merge builds main’s new merge commit, on main. |
pipeline list |
Which pipeline each repo starts. |
pipeline remove <repo> <pipeline> |
Owners only. Pushes and merges stop starting that pipeline. |
| Flag | What it does |
|---|---|
--monorepo <owner/name> |
The repository. Default: the one you are in. |
--org <slug> |
The Buildkite organization, as in buildkite.com/<slug>. With pipeline, the default is the repository’s one connected organization. |
--out <file> |
With connect: write the webhook token to this file, readable only by you, instead of the terminal. |
--paste-token |
With connect: use the token Buildkite made, typed with no echo, instead of a new one. |
--server <url> |
The Pando server. Default: the configured one. |
pando ci build
pando ci build list [--pipeline p] [--branch b] [--state s]
pando ci build view | log | rebuild | cancel <build>Builds as Pando has them from Buildkite’s webhooks, newest first. Name a build by its number (12 or #12, with --pipeline unless the repository has one pipeline), by its pipeline and number (pando-ci/12, as in its page’s address), or by its id (cib_...).
| Subcommand | What it does |
|---|---|
list |
Builds: number, pipeline, state, repo, branch, commit, who pushed it, when, how long it took, and its id. |
view <build> |
One build and its jobs: each job’s state, check, exit status and time. |
log <build> |
Each job’s log, its last 1 MiB, from Buildkite. Buildkite’s timestamps are taken out, and colours too when the output is not a terminal. |
rebuild <build> |
Starts a new build of the same commit, with fresh tokens. |
cancel <build> |
Cancels a build that is running. |
| Flag | What it does |
|---|---|
--pipeline <slug> |
With list: that pipeline’s builds. With a build number: the build’s pipeline. |
--branch <name> |
With list: builds of that branch. |
--state <state> |
With list: builds in that state: queued, running, blocked, passed, failed, canceled or skipped. |
--repo <path> |
With list: builds of that repo. |
--limit <n> |
With list: how many builds. Default 30. |
--job <job> |
With log: one job, by its key, name or id. |
--follow |
With log: keep printing the job’s log as it grows, until the job finishes. It follows one job. |
--json |
Print the API’s answer: list, view, log (an array, one answer per job), rebuild, cancel. |
--monorepo <owner/name> |
The repository. Default: the one you are in. |
pando ci job retry
pando ci job retry <build> <job>Runs a job again in Buildkite, with the build’s first environment, so it can still clone for 24 hours after the build started. Name the job by its key, name or id. Its check goes back to pending. It takes --pipeline, --monorepo and --json (the API’s answer).
pando ci run
pando ci run <pipeline> [--branch b]Starts a build of the pipeline for the head of a branch as Pando has it (default: its project’s main), with fresh tokens, the way a push starts one. It takes --monorepo and --json (the API’s answer).
pando status in a CI build
pando status <pending|success|failure|error> [--context ci] [--target-url u] [--description d]Only in a build Pando started. Posts a check on the build’s commit, using PANDO_STATUS_URL and PANDO_STATUS_TOKEN from the build’s environment. Pando shows the CI service’s mark on the check.
| Flag | What it does |
|---|---|
--context <name> |
The check’s name. Default ci. |
--target-url <url> |
A link for the check. Default: BUILDKITE_BUILD_URL. |
--description <text> |
A short line for the check. |
Releases
A release is a tag on a project’s main, with notes and files. See Releases.
pando release
pando release list | view [<tag>]
pando release create <tag> [<file>...] [--generate] [--title t] [--notes n | --notes-file f] [--target <sha>] [--draft] [--force]
pando release publish <tag> [--force]
pando release upload <tag> <file>...
pando release download [<tag>] [--pattern p] [--dir d]
pando release delete <tag> [--yes]| Subcommand | What it does |
|---|---|
list |
Releases, newest first: tag, title, draft or published (and forced), commit, when. |
view [<tag>] |
One release (default: the latest published): its state, commit, who published it, its commit’s checks, its files and its notes. |
create <tag> [<file>...] |
Tags main (or --target, a commit on main) and publishes it. With files, it makes a draft, uploads them, then publishes. Refused while the commit’s required checks are red or missing, unless --force. |
publish <tag> |
Publishes a draft, by the same rule. From then on git can’t move or delete its tag. |
upload <tag> <file>... |
Adds files to a release, each at most 100 MB, 20 a release. A name sent again replaces the file. |
download [<tag>] |
Writes a release’s files (default: the latest’s) into the current folder, each checked against its SHA-256. |
delete <tag> |
Deletes the release and its files. Its tag stays, and git can move or delete it again. Asks first; --yes for scripts. |
| Flag | What it does |
|---|---|
--generate |
With create: write the notes from the branches merged since the last release, after --notes, if any. |
--title <text> |
With create: its title. Default: the tag. |
--notes <text>, --notes-file <file> |
With create: its notes, in Markdown (- reads standard input). |
--target <sha> |
With create: the commit on main to release. Default: main, or the tag’s commit when the tag exists. |
--draft |
With create: keep it a draft. |
--force |
With create and publish: publish past red or missing required checks. The release says it was forced. |
--pattern <pattern> |
With download: only files whose names match, such as pando-darwin-*. |
--dir <folder> |
With download: where to write the files. Default: the current folder. |
--repo <path> |
The project. Default: the one you are in, or the only one. |
--json |
Print the API’s answer: list, view, create, publish. |
--monorepo <owner/name> |
The repository. Default: the one you are in. |
Hooks
pando hook
pando hook list | create <url> | delete <id>
pando hook deliveries <id> | redeliver <delivery-id>A repo’s web hooks: on a push, a new branch or a merge, Pando POSTs JSON to a URL, signed with a secret you choose (X-Pando-Signature-256). Buildkite hooks are added with pando ci pipeline add and show in the list too. Adding, deleting and sending again need an owner.
| Subcommand | What it does |
|---|---|
list |
The repo’s hooks: id, type, where it sends, events, app, and who added it when. |
create <url> |
Adds a web hook. It asks for the signing secret with no echo, or reads it with --secret-file; the secret is never an argument. With a URL that has a hook already, it adds nothing. |
delete <id> |
Removes a hook. |
deliveries <id> |
What the hook sent, newest first (the last 100): event, seq, status, tries and the answer. |
redeliver <delivery-id> |
Sends one delivery again, with the same id and seq. |
redeliver <hook-id> --since <seq> |
After an outage: sends again every delivery of the hook after that seq, oldest first, at most 1,000. |
| Flag | What it does |
|---|---|
--event <event> |
With create: push, branch.opened, merged or tag. Repeat it. Default: all four. |
--app <slug> |
With create: the CI service behind the URL (github-actions, circleci, …), shown on the checks its builds post. |
--secret-file <file> |
With create: read the secret from the file, or from standard input with -. |
--since <seq> |
With redeliver: send again every delivery after this seq. |
--repo <path> |
The repo. Default: the one you are in, or the only one. |
--json |
Print the API’s answer: list, create, deliveries, redeliver or, with --since, replay. |
--monorepo <owner/name> |
The repository. Default: the one you are in. |
Machines and activity
pando worktree list shows every worktree on every machine.
pando machine list
pando machine listEach machine (a credential: a laptop, a cloud sandbox) that acted in the repository or is connected to it, latest activity first: whose it is, its kind, whether it is connected now and since when, how many worktrees it has open, and its last action. It takes --monorepo and --json (the API’s answer).
pando activity
pando activity [--monorepo <owner/name> | --all] [--limit n]What happened, newest first, one line each, as the home page shows it: pushes, new and deleted branches, merges, reviews, checks that changed, worktrees added and removed, and shared files saved. Inside a repository’s folder, that repository’s lines; elsewhere, or with --all, those of every repository you belong to.
| Flag | What it does |
|---|---|
--monorepo <owner/name> |
One repository’s lines. |
--all |
Every repository’s lines, even inside a repository’s folder. |
--limit <n> |
How many lines. Default 30. |
--json |
Print the API’s answer, its pages joined. |
pando profile
pando profile [<login>] [--json]A person’s profile, yours by default: their name, bio and links, their contribution graph for the last year drawn in the terminal (a column a week, Sunday on top, · for a day with nothing and ░▒▓█ for busier days), then each month in a line. You see only their work in repositories you can open. --json prints the API’s answer.
The API
pando api
pando api <path> [-X method] [-f k=v] [-F k=v] [--paginate]Calls any route of the API with this machine’s credential, like gh api, and prints the answer: indented on a terminal, on one line in a pipe. The path may leave out /v1. In the path, {owner} and {monorepo} stand for the repository you are in (or --monorepo), {repo} for the project you are in (or --repo), and {branch} for the branch of the worktree you are in.
pando api /monorepos/{owner}/{monorepo}/repos/{repo}/branches --paginate
pando api /monorepos/{owner}/{monorepo}/repos/{repo}/branches -f name=fix-login -f title="Fix the login page"
pando api -X PATCH /monorepos/{owner}/{monorepo}/repos/{repo}/branches/{branch} --input body.json| Flag | What it does |
|---|---|
-X <method> |
The method. Default GET, or POST when there are fields or --input. |
-f key=value |
A string field. Repeat it. With POST, PUT and PATCH the fields make a JSON body; with GET and DELETE they go in the query. a[b]=x makes {"a": {"b": "x"}}, and a[]=x adds x to the array a. |
-F key=value |
A field with a type: true, false, null, a whole number, or @file (the file’s text; @- for standard input). Anything else is a string. |
--input <file> |
Send the file as the body (- for standard input). Fields then go in the query. |
-H 'Name: value' |
A request header. Repeat it. |
--paginate |
Follow a list’s cursor (next_cursor, or next in the activity log) and print every page as one answer: the lists end to end, the cursor null. GET only. |
-i |
Print the status line and the headers first. |
--monorepo <owner/name> |
The repository for {owner} and {monorepo}. |
--repo <path> |
The repo for {repo}: its path, or its name in URLs. |
It exits 0 on a 2xx or 3xx answer; a 3xx with no body (an artifact’s download) prints where it leads. Any other answer puts the API’s error body on stderr and exits 1. A full URL is refused: the credential goes only to the server you signed in to. There is no --jq; pipe the output to jq.
For scripts and agents
--jsonis the API’s JSON. Each command above links the answer it prints, and the API reference holds every field. A few commands put several answers together under fixed keys:branch view(branch,reviews,commits),monorepo view(monorepo,repos,members),issue view --comments(the issue, with its timeline undertimeline), andci build log(an array, one answer per job). A list read in several pages comes out as one answer, the lists end to end. On a terminal the JSON is indented; in a pipe it is one line.- Exit codes. 0 when the command worked. 1 when it did not, with one line on stderr that says why and ends with the API’s code and HTTP status, as in
pando: no pipeline nope here (not_found, HTTP 404);pando issuewith--jsonprints the API’s error object there instead. 2 when the command was used wrongly, with its usage. - Running a write again. Only issues and comments take an idempotency key:
pando issue createandpando issue commentalways send one (--key, else one made for the run), and try again with it after a network error or a 502, 503 or 504, so a lost answer never makes a second issue. An agent that may run the command again after a crash passes its own stable--key, such as its task id. The rest of the API takes none, so another write retried after a lost answer may happen twice. These are safe to run again; a second run changes nothing (a delete or revoke already done answersnot_found): every otherpando issuesubcommand (states, labels, assignees, links and reactions are set, not added twice; a body edit with--base-versionis refused, not repeated),pando hook createandpando ci pipeline add(they look first, and add nothing when it is there),pando monorepo renameandtransfer,pando org create,add,removeandleave,pando members invite,revokeandremove,pando hook delete,pando ci build cancelandpando merge. These are not:pando ci runandpando ci build rebuildstart another build (look withpando ci build list --branch <b>first);pando review -mposts another review;pando credential createmakes another credential;pando hook redeliversends again (the receiver sees the sameX-Pando-Deliveryid and can drop it).pando ci job retrywith a job’s key retries that job’s newest run, so once a first retry has finished, a second runs it again; name the job by its id to retry it once.
Shared files
A repository’s shared files are every file outside projects/ and outside references: notes, decisions, plans. They are plain files on every machine. While pando sync runs, a save on one machine goes to the others as soon as it is made, and becomes a git commit after 10 seconds without changes.
Each of these commands takes --root <folder> for a repository in another folder than the one you are in.
pando sync
pando sync [--once]Keeps the shared files live until stopped: it sends this machine’s saves and writes everyone else’s. It also keeps this machine’s read-only mains at the server’s main. --once sends and receives what is waiting, then exits.
If you lose access to the repository (an owner removes you, you leave the organization that owns it, or it moves out of that organization), pando sync stops at once and says so. The folder keeps its files.
pando history
pando history <path> [--limit n] [--json]Every saved version of a shared file, newest first: version, when, who, machine, what, and the commit.
| Flag | What it does |
|---|---|
--limit <n> |
How many versions. Default 50. |
--json |
Print JSON. |
pando restore
pando restore <path> --to <version | HH:MM>Writes an old version back as a new save, which every machine gets. --to takes a version number, a time today (10:42), or a date and time (2026-10-03 10:42). A time means the latest version at or before it.
pando resolve
pando resolve [<path>...]When two machines change a file at once, one keeps a conflict copy beside it and the file stops syncing there. pando resolve <path> makes it sync again: if you edited the file, your version goes out. With no path, it lists the files that are stopped.
pando fetch
pando fetch <path>...Downloads the bytes of large shared files that a --text-only clone keeps as pointers. See Limits for file sizes.
The Mac
pando mac broker
pando mac broker [--dry-run]macOS only. Loads Pando.app’s background helper, which a worktree mounted through Pando.app (--kind fskit) needs. The first mount runs this step on its own.
| Flag | What it does |
|---|---|
--dry-run |
Print what it would load and the commands, and load nothing. |
--app <path> |
The installed Pando.app. Default: found on its own. |
Environment
| Variable | What it does |
|---|---|
PANDO_SERVER |
The Pando server URL, over the one in ~/.pando/config.toml. |
PANDO_HOME |
Where pando keeps this machine’s config and credentials. Default ~/.pando. |
PANDO_TOKEN |
A credential to use instead of the stored one, for sandboxes. Make one with pando credential create. |
PANDO_MACHINE |
This machine’s name in Pando. Default: the host name up to its first dot. |
PANDO_NO_BROWSER |
Any value: pando login prints the link and opens no browser. |
PANDO_WORKTREE_KIND |
The default for --kind: sparse, fuse or fskit. |
Pando sets these in a build it starts:
| Variable | What it does |
|---|---|
PANDO_CLONE_URL |
The repo’s clone URL. |
PANDO_READ_TOKEN |
A read-only token for that one repo. Clone with it as a bearer token. It lasts at least 24 hours, so a retried job can still clone. |
PANDO_STATUS_URL |
Where pando status <state> posts. It names the build’s commit. |
PANDO_STATUS_TOKEN |
Lets pando status <state> post checks on that one commit, for 24 hours. |