Skip to main content
Obversa is a guest in the host that you selected. cmux is the first host. The glue for cmux is setup, not a product: configuration plus small scripts. There is no host fork and no new UI.

What you get

  • One command in a workspace opens one editor window with the two Order roots: the Project worktree and the Shared worktree, as peers.
  • A local web surface opens in a browser split beside the terminal.
  • The Plannotator review page opens in a split. Every other link keeps your default browser.
  • Callback Gate surfaces use the same door when a router launches them.

The two-root workspace

Each Order binds two worktrees. The Project worktree holds your product source. The Shared worktree holds the Context and Workflow that all projects share. Neither root appears inside the other. The glue generates one editor workspace file with both roots and opens it. The file lives outside both trees, so no worktree carries host state. Your editor stays your editor.

Surfaces in splits

A surface is a small user interface for one decision. In cmux, a surface opens as a browser pane in your workspace, split beside the terminal. Outside cmux, the same command opens your default browser. The fallback keeps every script usable in a plain terminal. The URL a surface hands the glue is a one-time launch URL that opens the session (single use, valid for a minute; the page URL with its token is never placed in a process argument), and it is still the one door to the review, so every command the glue runs (cmux, macOS’s open, the python3 that reads the cmux tree, and the few coreutils the cmux route needs) runs by absolute path from a fixed list of system directories (/usr/bin, /bin, /usr/local/bin, /opt/homebrew/bin), never by a bare name looked up on PATH. A host may name other directories in OBVERSA_SYSTEM_BIN_DIRS (colon-separated). On Linux the glue does not run xdg-open, which runs its own helpers by bare name: the URL is printed on stderr for you to open, as it is on any platform with no opener found, and nothing else receives it.

One route for Plannotator

Plannotator opens its review page through one environment variable, PLANNOTATOR_BROWSER, and the workspace launcher below binds it to the glue script for the workspaces it creates. Only the review page routes into a cmux split; no other tool reads the variable, so no other link changes behavior.

Set up

The glue is a handful of scripts in hosts/cmux/bin/ plus one Command Palette entry. It targets macOS today: the default-browser fallback uses open. Put the scripts on your PATH first, or call them by full path:
  1. Obversa checkouts carry the palette entry in .cmux/cmux.json. Open a cmux workspace on the repository and run Order Workspace from the Command Palette. The first run shows the cmux trust prompt.
  2. For every other workspace, add the same entry to ~/.config/cmux/cmux.json with the script’s absolute path. The project-local entry overrides the global one, so the pair never conflicts.
  3. Set the Shared root once: export OBVERSA_SHARED_ROOT=<shared worktree>.
  4. Create workspaces through the host’s launcher, which binds both placement variables — OBVERSA_SURFACE_BIN for Obversa surfaces and PLANNOTATOR_BROWSER for Plannotator — to this checkout’s scripts for every terminal and agent in the workspace:
    The binding is per launch host, never global: do not put either variable in a shell profile or an agent client’s settings, and remove an old global PLANNOTATOR_BROWSER entry from ~/.claude/settings.json if one is there — a global binding sends every launch to one host, so a review started in another host would land in this one instead of where it started. In a workspace opened without the launcher, export OBVERSA_SURFACE_BIN as the absolute path of obversa-surface in that workspace; outside cmux, surfaces open in the default browser.
  5. Apply with cmux reload-config.

Use

The generator writes the workspace file to ~/.local/state/obversa/workspaces/ and opens it with code (override with $OBVERSA_EDITOR_CMD). It refuses nested or identical roots.

When something fails

Every failure path lands somewhere safe. When cmux is absent, wedged, or returns an unusable topology, the URL opens in the default browser. When the Shared root is missing, the generator stops with the exact flag to pass. A cancel during the lookup opens nothing. Wrong placement is treated as worse than a plain browser, so the scripts never guess a workspace.

Your host stays yours

The glue adds one Command Palette entry, three scripts, and nothing else. cmux supplies the panes, the layout, and the keybindings. Obversa supplies the workspace file and the surface placement. Remove the glue and cmux is exactly as it was.