Skip to content

Quickstart

Create a *.portagenty.toml anywhere — typically at the root of a directory that holds related projects. The prefix before .portagenty.toml can be anything non-empty (e.g. agentic.portagenty.toml, work.portagenty.toml).

name = "Example workspace"
id = "a1b2c3d4-e5f6-4890-abcd-ef1234567890"
multiplexer = "tmux"
projects = ["~/code/portagenty"]
[[session]]
name = "claude"
cwd = "~/code/portagenty"
command = "claude"
kind = "claude-code"
Terminal window
cd /path/under/your/workspace
pa

pa walks up from $PWD looking for a *.portagenty.toml. It loads the workspace, resolves paths (~, ${VAR}), merges in any per-project portagenty.toml files, and renders the session list. Nothing is launched yet.

KeyAction
j / ↓Next session
k / ↑Previous session
g / HomeFirst session
G / EndLast session
EnterAttach a live session, or require supervision when starting an eligible idle row
SEdit supervision limits or use the advanced upgrade/restart paths
q / Esc / Ctrl-CQuit the TUI

For the UUID-backed Claude-kind row above, Enter requires an experimental Linux supervised launch with 3G MemoryHigh, 5G MemoryMax, 512MiB MemorySwapMax, 800% CPU, and 1200 tasks beneath the pre-provisioned aggregate Claude slice. Every supervised kind receives the same complete resource baseline; kind = "claude-code" alone selects Claude slice placement, resume behavior, oomd integration, and stricter override rules. Naming a session or command claude without that kind remains generic. If ownership, capability, or runtime preflight cannot prove a safe supervised launch, eligible Enter fails closed without creating an ordinary target. Existing live ordinary sessions attach in place and are never retroactively claimed; workspace files with no ID retain ordinary Enter.

The TUI restores the terminal before handing the TTY to tmux. Detach with the multiplexer’s normal binding (Ctrl-b d for tmux). After any client return—normal, nonzero, or by signal—Portagenty prints the human workspace / session identity; a pre-client setup failure instead reopens the same workspace and logical row.

Terminal window
pa list # print the resolved workspace to stdout
pa launch claude # skip the TUI, launch a session by name
pa launch claude --dry-run # print what would happen without running it
pa launch claude -w ./my.portagenty.toml # explicit workspace file
# "Make this device the main session." Defaults the session name to the
# first one in the workspace — the common one-agent-per-project case.
pa claim
pa claim tests # specific session by name
# Render the workspace as a starter script (or zellij layout). Useful
# for committing alongside the TOML so teammates can launch the whole
# stack without installing pa themselves.
pa export # to stdout; format follows the workspace's mpx
pa export --format zellij -o layout.kdl
pa export --format tmux -o starter.sh

5. Cross-device: take over from a different machine

Section titled “5. Cross-device: take over from a different machine”

When you SSH in from a phone (or any other device) and attach to a session that’s already attached on your desktop, tmux (and by extension pa) will shrink the session to the smaller client’s terminal size and keep it that way. That’s the infamous “stuck in a weird size” bug.

pa’s default behavior fixes this for you:

  • pa, pa launch <name>, and pa claim all default to takeover mode. On attach, any other clients get detached so the session reshapes to the current device.

  • The session itself keeps running — the other device’s client is disconnected, not the session. You can re-attach from the other device later; it’ll just reconnect to the still-running session.

  • Pass --shared to opt out:

    Terminal window
    pa launch claude --shared # multiple devices can watch concurrently

pa claim is a shorter verb for the common “I moved devices, make this one the main” flow — it’s the same as pa launch <first-session> but without having to remember the session name.

Multiplexer caveats:

  • tmux: uses tmux attach -d internally — takeover works cleanly.
  • zellij: has no CLI equivalent to force-detach other clients. pa warns when other clients appear to be attached, but you may need to manually detach the other device (Ctrl+Q on the other end) if screen-size weirdness persists.

Each launch writes an entry to $XDG_STATE_HOME/portagenty/state.toml (or ~/.local/state/portagenty/state.toml if unset). It’s machine-local and not committed anywhere. v1 tracks the data; the Recent view that displays it is a v1.x feature.

If you’ve installed portaconv (pconv) alongside pa, you can query Claude Code’s conversation history scoped to this workspace:

Terminal window
pa convos list # sessions in this workspace
pa convos dump <session-id> # paste-ready markdown
pa convos dump <session-id> --rewrite wsl-to-win

pa convos forwards to pconv with --workspace-toml <path> auto-injected, so the lookup only sees Claude sessions whose cwd falls under this workspace’s projects (or its previous_paths, auto-maintained when folders move).

For a Claude Code agent to self-discover this capability, scaffold the MCP + skill hooks when you pa init:

Terminal window
pa init --with-agent-hooks # on a fresh workspace
pa init --with-agent-hooks # safe to re-run on an existing one
# (TOML untouched, only missing hooks written)

See Portaconv integration for the full workflow.

A project can ship its own portagenty.toml at its root:

~/code/portagenty/portagenty.toml
[[session]]
name = "tests"
cwd = "."
command = "cargo nextest run"

When a workspace lists a project via projects = [...], portagenty merges that project’s sessions into the workspace view. Name collisions: the workspace’s version wins. See the three-tier merge for the full rules.