Skip to content

Commands reference

All commands respect the walk-up workspace discovery — run any of them from anywhere under your workspace file and pa will find it. The -w/--workspace flag overrides the walk-up with an explicit path.

Opens the TUI. With no arguments, walks up from $PWD for a *.portagenty.toml or (if none) shows the workspace picker. Pass an optional positional path to jump straight to a workspace without needing to cd there first. The path can be a *.portagenty.toml file or a directory (walks up from it).

Terminal window
pa # walk up / show picker
pa ~/code/myproject # open workspace at this dir
pa ~/code/my.portagenty.toml # open this workspace file directly

Shown when pa runs outside any walkable workspace, or after pressing Esc from the session list.

KeyAction
j / Next workspace
k / Previous workspace
g / HomeFirst workspace
G / EndLast workspace
Enter / l / Open the highlighted workspace
Ctrl+D / Ctrl+UHalf-page down / up
PgDn / PgUp10-row jumps
nFind a folder + scaffold a new workspace
RRename workspace (edits TOML name field)
rReveal workspace path (auto-copies; press o inside to open shell there)
dUnregister workspace from global index (file stays on disk)
DDelete workspace file and unregister (with confirm)
?Help overlay
q / EscExit pa
KeyAction
j / / Alt+JNext session
k / / Alt+KPrevious session
g / HomeFirst session
G / EndLast session
Enter / l / Attach-or-create the highlighted session (takeover)
Ctrl+D / Ctrl+UHalf-page down / up
PgDn / PgUp10-row jumps
aAdd a new session (2-stage name → command modal)
eEdit session (name / cwd / command / kind / env)
dDelete session from workspace TOML (with confirm)
xKill a live mpx session (with confirm)
mSwitch workspace multiplexer (tmux ↔ zellij)
tOpen the file tree rooted at the workspace’s directory
oOpen a plain shell at the workspace’s directory (exits pa)
?Help overlay
Esc / q / Ctrl+QBack to workspace picker
Ctrl+CExit pa directly

Find overlay (triggered by n in picker or e → c in session list)

Section titled “Find overlay (triggered by n in picker or e → c in session list)”
KeyAction
Type charactersFuzzy-search folders by leaf name (nucleo ranking)
/ Move highlight through results
> / Drill into highlighted folder
< / Go up to parent folder
EnterSelect folder (scaffold or open existing workspace)
Ctrl+RToggle global search (all mount points / filesystem root)
Ctrl+TSwitch to tree-browse mode
Ctrl+FFullscreen path display
EscClose the find overlay

Tree browser (triggered by Ctrl+T inside find overlay, or t in session list)

Section titled “Tree browser (triggered by Ctrl+T inside find overlay, or t in session list)”
KeyAction
j / Next row
k / Previous row
g / GFirst / last row
EnterSelect (file or leaf)
l / / SpaceExpand directory (inline)
h / Collapse directory
.Drill — re-root the tree at the highlighted folder
BackspacePop root — re-root at the current root’s parent
nCreate a new folder under the current root
oOpen a plain shell at the highlighted folder (exits pa)
/Search from here — back to search mode with this folder as root
Ctrl+T / EscBack to search mode
q / Ctrl+CClose the overlay

Attach to (or create-and-attach) a specific session by name, without entering the TUI.

FlagDefaultWhat
-w, --workspace <path>walk-upExplicit workspace file
--dry-runoffPrint what would happen, don’t run it
--sharedoffDon’t detach other clients (see attach modes)
--resumeoffKind-aware resume. For kind = "claude-code" sessions, appends --continue before launch so Claude picks up its prior conversation. Other kinds print a one-line hint to stderr and launch unchanged. The workspace TOML command string is never mutated on disk.
--freshoffKill any existing mpx session with this name before launching. On zellij this is the only way to guarantee other clients are disconnected (zellij doesn’t support per-client takeover). On tmux the default takeover already handles it — use --fresh only when you specifically want to wipe running state and restart from the workspace’s declared command.

Examples:

Terminal window
pa launch claude
pa launch claude --dry-run
pa launch claude -w ~/code/my.portagenty.toml
pa launch claude --shared # leave other devices attached
pa launch claude --resume # claude-code → appends --continue

“Make this device the main session.” Short-form alias for takeover-attach. Session name defaults to the first one declared in the workspace.

FlagDefaultWhat
-w, --workspace <path>walk-upExplicit workspace file
--dry-runoffPrint what would happen
--resumeoffSame semantics as pa launch --resume: appends --continue for kind = "claude-code" sessions, one-line hint for other kinds.
--freshoffSame semantics as pa launch --fresh: kill any existing mpx session first. The zellij takeover workaround (loses running state).

Examples:

Terminal window
pa claim # first session in workspace
pa claim tests # specific session
pa claim --dry-run # peek without touching
pa claim claude --resume # takeover + resume the Claude conversation

Print the resolved workspace (name, multiplexer, projects, sessions) to stdout. Handy for scripts + sanity checks.

Terminal window
pa list
pa list -w ~/code/my.portagenty.toml

Example output:

workspace: My stuff
file: /home/u/code/my.portagenty.toml
mpx: Tmux
projects: 2
- /home/u/code/one
- /home/u/code/two
sessions: 2
- claude (cwd: /home/u/code/one) claude
- dev (cwd: /home/u/code/two) bun run dev

Scaffold a new <name>.portagenty.toml in the current directory with one starter session (shellbash). Designed for phone-over- SSH: you don’t have to hand-edit TOML before pa works.

FlagDefaultWhat
name (positional)current-directory nameWorkspace display name; filename stem is a sanitized version
--mpx tmux|zellijglobal default, else tmuxWhich multiplexer to pin
--forceoffOverwrite an existing <name>.portagenty.toml
--with-agent-hooksoffAlso scaffold .mcp.json + .claude/commands/ + .claude/skills/ so a Claude Code agent in this workspace self-discovers portaconv (conversation extractor) and the portagenty workspace shape
Terminal window
pa init # name taken from current dir
pa init my-space # explicit name
pa init my-space --mpx zellij
pa init my-space --force # overwrite existing
pa init --with-agent-hooks # also drop .mcp.json + .claude/ hooks

Writes four files (skipped if already present — opt-in, not authoritative):

  • .mcp.json — registers the portaconv MCP server so Claude Code’s MCP client can call list_conversations / get_conversation against this workspace’s history.
  • .claude/commands/convos.md — a slash command that lists / dumps conversations via pa convos.
  • .claude/skills/portaconv.md — a skill describing what portaconv is and when to reach for it.
  • .claude/skills/portagenty-workspace.md — a skill describing the workspace’s TOML contract (sessions, id, previous_paths).

If pconv (portaconv) isn’t on PATH yet, the hooks are still written — they’re harmless without it, and the MCP handshake starts succeeding the moment you run cargo install portaconv. A hint is printed either way.

Safe on existing workspaces. pa init --with-agent-hooks in a directory that already has a *.portagenty.toml does NOT replace the TOML; it leaves the workspace file alone and just retrofits the agent hooks. Re-running is idempotent (skipped files stay untouched). Pair with --force only when you actually want to rewrite the TOML itself.

Append a new session to the current workspace file. Faster than editing TOML manually, especially from a phone keyboard.

FlagDefaultWhat
name (positional)— (required)New session’s name
-c, --command <cmd>— (required)Command to run
--cwd <path>.Working directory
--kind <...>noneclaude-code, opencode, editor, dev-server, shell, or other
-w, --workspace <path>walk-upExplicit workspace file
Terminal window
pa add claude -c "claude --resume" --kind claude-code
pa add dev -c "bun run dev" --cwd ./app --kind dev-server
pa add tests -c "cargo nextest run"

The append preserves any comments / formatting in the existing workspace file — we just tack on a new [[session]] block at the end. Duplicate names error cleanly.

Delete a session from the current workspace file. Comments and formatting elsewhere in the file are preserved — only the matching [[session]] block is excised.

FlagDefaultWhat
name (positional)— (required)Session to remove
-w, --workspace <path>walk-upExplicit workspace file
Terminal window
pa rm claude
pa rm tests -w ~/code/my.portagenty.toml

Change one field on an existing session without opening an editor. Pass exactly one change flag; passing zero or more than one errors with guidance.

FlagWhat
name (positional)Session to edit
--command <cmd>Replace the command
--cwd <path>Replace the cwd
--kind <...>Replace the kind hint
--rename <new-name>Rename (errors on collision with an existing session)
--env KEY=VALSet an env var (repeatable)
--unset-env KEYRemove an env var (repeatable)
-w, --workspace <path>Explicit workspace file (walk-up otherwise)
Terminal window
pa edit claude --command "claude --resume"
pa edit dev --cwd ./new-app
pa edit my-session --kind claude-code
pa edit old-name --rename new-name
pa edit claude --env ANTHROPIC_MODEL=opus --env DEBUG=1
pa edit claude --unset-env DEBUG

Same comment-preserving behavior as pa rm: only the target field on the target session changes; everything else in the file is left untouched.

Workspace-aware shim over portaconv (pconv). Forwards any subcommand + flags you pass to pconv with --workspace-toml <resolved-path> prepended so the tool only sees this workspace’s conversation history.

FlagDefaultWhat
-w, --workspace <path>walk-upExplicit workspace file (maps to pconv’s --workspace-toml)
everything elsePassed through verbatim to pconv
Terminal window
pa convos list # list conversations in this workspace
pa convos list --since 7d # pconv flags pass through
pa convos dump <session-id> # paste-ready markdown
pa convos dump <session-id> --rewrite wsl-to-win

portagenty doesn’t bundle pconv. Install it separately with cargo install portaconv (or drop a release binary on PATH). When pconv isn’t installed, pa convos exits with a clear install hint — it doesn’t silently become a no-op.

Scripts that care about pconv’s exit code work the same as if you’d invoked pconv directly: pa convos re-exits with pconv’s status on non-zero.

Emit a shell completion script to stdout. See shell completion setup for per-shell install recipes.

Terminal window
pa completions bash > ~/.local/share/bash-completion/completions/pa
pa completions zsh > ~/.zsh/completions/_pa
pa completions fish > ~/.config/fish/completions/pa.fish

Covers subcommand names + flag names + flag values that come from a closed set. Dynamic completion of session names / snippet names / workspace files is roadmapped, not v1.x.

Render the resolved workspace as a multiplexer-native starter artifact. Useful for committing alongside the workspace TOML so teammates can launch the whole stack without installing pa themselves.

FlagDefaultWhat
-w, --workspace <path>walk-upExplicit workspace file
--format tmux|zellijworkspace’s multiplexerOutput format
-o, --output <path>stdoutFile to write to

Examples:

Terminal window
pa export # stdout, format auto-picked
pa export --format zellij # zellij KDL layout
pa export --format tmux -o starter.sh # save to file

Outputs a POSIX shell script for --format tmux (tmux new-session -d per session + tmux attach-session -d to the first) or a KDL layout with one tab per session for --format zellij. Both respect env vars declared on sessions and sanitize session names the same way pa does at runtime.

Re-run the first-run wizard at any time. Interactive; walks you through workspace scaffolding, multiplexer choice (with installed / not-found annotations), optional Claude Code starter session, and offers to set or change the machine-default multiplexer. Writes a <name>.portagenty.toml in the current directory and auto-registers it in the global workspace index so pa from anywhere can find it.

Terminal window
pa onboard

No flags — the wizard is fully interactive. Safe to re-run: an existing workspace file in the current directory is left untouched.

Bundled bash ergonomics shipped inside the pa binary. Idempotent: installing twice replaces the block in-place via a marker comment so your rc file never accumulates duplicates.

The pa-aliases snippet includes a paclaim shell function for claiming a session from inside it (once pa has handed off to tmux/zellij, pa claim is refused due to nested-mpx guard). On tmux, paclaim runs tmux detach-client -a — kicks all other clients but keeps your current terminal attached. On zellij, there’s no built-in equivalent; the function prints the detach + reattach workaround.

Print the bundled snippet catalog with one-line descriptions.

Terminal window
pa snippets list

Print a snippet’s contents to stdout. Review before installing.

Terminal window
pa snippets show pa-aliases

Install (or update) a snippet in your rc file.

FlagDefaultWhat
name (positional)— (required)Snippet name from pa snippets list
--to <path>~/.bashrcTarget rc file
--dry-runoffPreview the result without writing
Terminal window
pa snippets install pa-aliases
pa snippets install termux-friendly --to ~/.zshrc
pa snippets install pa-aliases --dry-run

Remove a previously-installed snippet from your rc file. Surrounding user content is preserved byte-for-byte.

FlagDefaultWhat
name (positional)— (required)Snippet name to remove
--from <path>~/.bashrcTarget rc file
--dry-runoffPreview the result without writing
Terminal window
pa snippets uninstall pa-aliases

Dispatch a pa://... URL to the matching pa action. Called automatically by the OS when the user clicks a pa:// link (see pa protocol below). Supported URL shapes:

URLOpens
pa://open/<path>Workspace TUI for the workspace at path (percent-encoded)
pa://shell/<path>Plain shell at path (no pa state, no mpx)
pa://workspace/<uuid>Workspace whose TOML has id = "<uuid>"
pa://launch/<uuid>/<session>Launch session in the workspace with that id
Terminal window
pa open "pa://open/home/u/code/myproject"
pa open "pa://workspace/a1b2c3d4-e5f6-7890-abcd-ef1234567890"

Unknown actions error cleanly rather than silently opening the picker — clicks are asynchronous and a wrong-scheme URL shouldn’t leave you staring at a generic home screen.

Manage the OS-level pa:// URL scheme so browser / note-app / Slack clicks on pa://... links launch pa in your terminal.

List terminal emulators detected on this machine, highest-priority first. The first entry is what install / show default to. Detection covers: Windows Terminal, ConEmu, Alacritty, WezTerm, cmd.exe (Windows) · GNOME Terminal, Konsole, Alacritty, Kitty, WezTerm, Foot, XFCE Terminal, xterm (Linux) · iTerm2, Terminal.app, Alacritty, WezTerm, Kitty (macOS).

On WSL, Windows terminals (e.g. wt.exe) are preferred — URL clicks originate from Windows, so that’s where the handler lives.

Terminal window
pa protocol terminals

pa protocol show [--terminal <name-or-path>]

Section titled “pa protocol show [--terminal <name-or-path>]”

Print the OS-appropriate registration snippet without writing anything. Safe — always a read-only preview. Output is:

  • Linux → a .desktop file body
  • Windows / WSL → a .reg file body
  • macOS → guidance (install not automated there)
Terminal window
pa protocol show
pa protocol show --terminal alacritty # override the default
pa protocol show --terminal /opt/my-term # absolute path works too

pa protocol install [--terminal <name-or-path>]

Section titled “pa protocol install [--terminal <name-or-path>]”

Write the registration:

  • Linux~/.local/share/applications/portagenty.desktop + runs xdg-mime default portagenty.desktop x-scheme-handler/pa so the desktop environment picks it up immediately.
  • Windows / WSLHKCU\Software\Classes\pa (user-scope, no admin needed; works from WSL via reg.exe).
  • macOS → errors; use pa protocol show and apply the Info.plist guidance manually.

--terminal accepts either a detected terminal name (substring match, case-insensitive) or any absolute path / PATH-resolvable binary. Custom terminals get a generic -e {cmd} template — works for most POSIX emulators.

Terminal window
pa protocol install # auto-pick the best
pa protocol install --terminal alacritty
pa protocol install --terminal /usr/local/bin/my-terminal

Reverse of install. Idempotent — removing an already-absent registration is a no-op.

Terminal window
pa protocol uninstall

Report what’s currently registered. Useful for verifying install or debugging “why doesn’t my pa:// link work?”.

Terminal window
pa protocol status