phux docs

Projects

A project is a repository checkout with its own phux session. A .phux/project.toml recipe in the repository describes the tabs, panes, and commands that session starts with, so phux project open gives you the same workspace every time, on any machine.

phux project init     # write a starter .phux/project.toml
phux project open     # build the session from it, or attach if it's running

phux runs a recipe only after you approve its exact contents on this machine.

Writing a recipe

phux project init writes this starter into the current checkout:

[[windows]]
name = "code"
panes = [
  { id = "editor", command = ["sh", "-c", "exec ${EDITOR:-vi} ."] },
  { split = { target = "editor", direction = "right", ratio = 0.6 } },
]

[[windows]]
name = "shell"

Each [[windows]] entry is a tab, in order. Each pane in panes is one of:

  • The window’s first pane, which needs no split.
  • A later pane, whose split places it beside an earlier pane in the same window: target is that pane’s id, direction is right or down, and ratio (between 0 and 1) is how much the target keeps.
KeyWhereMeans
namewindowThe tab’s name
idwindow, paneA name for focus and split to refer to: letters, digits, -, _
commandpaneAn argument list to run; leave it out for a plain shell
execpanetrue closes the pane when command exits; by default you drop to a shell
cwdwindow, paneThe working directory, relative to the checkout
envtop level, window, paneEnvironment variables; inner tables add to outer ones
focustop level"WINDOW.PANE" ids of the pane to focus; default is the first

A recipe with no windows opens one shell at the checkout root. Commands are argument lists and never pass through a shell, unless you run one, as the editor pane above does. A recipe can’t set PHUX_* variables.

phux checks the whole recipe before it starts anything: an unknown key, a split target that doesn’t exist, a missing directory, or more than 64 panes refuses the recipe with a message naming the window and pane.

Opening a project

phux project open             # the checkout you're in
phux project open ~/code/site # another checkout
phux project open phux        # a named project from your config

Inside a git repository, phux opens the checkout’s root. If the project’s session is already running, open attaches to it as it is and never reruns the recipe. Otherwise it builds the session from the recipe, then attaches.

--json builds the session without attaching and prints its name and the first pane, for scripts.

Trust

A recipe can run any program, and it arrives with the repository, so phux won’t run one you haven’t approved:

$ phux project trust
Trusted /Users/you/code/site/.phux/project.toml (sha256 4a0a322c9cd97a4bf30265435d47ab9979098c780cf08003d88ce46501b715ef).

An approval covers the recipe’s exact bytes in that repository, on this machine, in every worktree of the repository. Changing one byte of the recipe withdraws the approval. After you edit it, or pull someone else’s edit, read it and run phux project trust again.

If you open a recipe that isn’t approved, phux prints it and asks before running it. Without a terminal to ask on, or with --json, it refuses and tells you to run phux project trust.

CommandDoes
phux project trust [TARGET]Validates the recipe and approves its current bytes
phux project untrust [TARGET]Withdraws the approval
phux project status [TARGET]Prints trusted, untrusted, or absent; exits 0 when trusted, 1 when not, 2 when it can’t tell

phux project init approves the starter it writes, so a fresh recipe opens straight away until you edit it.

Named projects

Name your checkouts in the configuration file to open them from anywhere:

[[projects]]
name = "phux"
path = "~/code/phux"

[[projects]]
name = "site"
path = "~/code/site"
recipe = "~/.config/phux/recipes/site.toml"

path is absolute or starts with ~/; phux never scans for repositories. recipe points at a recipe kept outside the repository, used instead of the checkout’s own. It needs no approval, because you wrote it into your own config.

$ phux project list
phux                 open     ~/code/phux
site                 -        ~/code/site

The second column is open when the project’s session is running, missing when the path doesn’t exist, and ? when no server answered.

Grouping sessions

The sidebar, the session picker, and phux ls group sessions by project. A session created inside a git checkout joins its repository’s group, across machines. Click a group’s header in the sidebar to collapse it.

To put any other session in a project, link it by name. The link is stored on the server that owns the session, so every client sees it:

phux project link notes phux    # put session "notes" in the phux group
phux project unlink notes       # back to its repository, or ungrouped

A link outranks the repository, and a link named like a repository joins that repository’s group. --remote me@mini links a session on another machine.

Debugging

  • phux project status says whether the recipe is approved.
  • phux project trust validates the recipe and reports the first problem without starting anything.
  • phux project list shows your named projects and which are open.
  • phux project inspect maps a repository’s worktrees to their checkouts.

If open attaches to a session that doesn’t match your edited recipe, the session was already running: recipes only build new sessions. Close the session and open it again to rebuild it.