Documentation
¶
Overview ¶
Package cage draws the CELL-655 bar: a one-line tmux status line pinned to the bottom of the terminal while devcell boots a cell and runs the agent. tmux runs on the host; devcell re-executes itself inside the tmux window, so the boot panel and the agent both render under the bar.
Left: the workspace name, then the cell name (<project>-<cellID>), each its own coloured element. Right: the status panel with clocks, joined with the theme separator. The prefix key is None, so every keystroke reaches the agent; the bar is display-only. The mouse is not captured (mouse off): selection and the wheel stay with the outer terminal or tmux.
Opt in with --experimental=ui-cage, DEVCELL_EXPERIMENTAL=ui-cage or cell experimental = ["ui-cage"] (see internal/experiments).
Index ¶
- Constants
- func Active() bool
- func Command(confPath string, spec Spec, windowName, self string, args []string) (string, []string)
- func ConfPath(spec Spec) string
- func Enabled(stdinTTY, stdoutTTY bool) bool
- func PopupCommand(spec PopupSpec, pid int) (string, []string)
- func PopupHeight(groups, clientRows int) int
- func Run(spec Spec, agent string, args []string) error
- func RunBootUI(ctx context.Context, o BootUIOptions) int
- func SocketPath(cellName string) string
- func StatePath(workspaceHome, name string) string
- func ThemeNames() []string
- func TmuxConf(workspaceName, cellName string, theme Theme) string
- func TmuxRunner(tmux string) func(args ...string) (string, error)
- func WriteConf(spec Spec) (string, error)
- type BootUIOptions
- type Geometry
- type Popup
- type PopupSpec
- type Spec
- type Theme
Constants ¶
const ( BootUIOK = 0 // boot finished, popup may close BootUIFailed = 1 // boot failed or the writer died; user acknowledged BootUIUnreachable = 2 // could not connect to the event socket BootUIInterrupted = 130 // second Ctrl+C )
Exit codes of RunBootUI.
const EnvActive = "DEVCELL_CAGE"
EnvActive marks the devcell process that already runs inside the cage.
Variables ¶
This section is empty.
Functions ¶
func Command ¶
Command builds the tmux argv that runs `self args...` inside the cage. The session gets its own socket per cell so it never collides with the user's tmux server. The inner process is pinned to the same identity (workspace, cell ID) because inside tmux TMUX_PANE would say otherwise. The command is shell-joined, the form every tmux version accepts.
func Enabled ¶
Enabled reports whether the cage can wrap this run: tmux draws the bar on the tty, so both ends must be terminals.
func PopupCommand ¶
PopupCommand builds the tmux argv that opens the popup running boot-ui. The popup command is shell-joined; DEVCELL_BOOT_PID tells boot-ui where to forward Ctrl+C.
func PopupHeight ¶
PopupHeight is the popup height for a boot panel of groups rows: the group rows, the border and rule, and the two rows a failed boot's hold line takes, never taller than the client minus a margin. Step and warning text is drawn on the group rows, so nothing else grows below the rule.
func Run ¶
Run writes the config, starts tmux on the host with this terminal attached and re-runs devcell (os.Args[1:] as args) inside it. It returns when the agent exits and tmux closes with it.
func RunBootUI ¶
func RunBootUI(ctx context.Context, o BootUIOptions) int
RunBootUI connects to the boot event socket, replays the events into a BootPanel on this process's terminal and exits by the rules below:
- finish: wait Dwell, close the socket (the ack), return BootUIOK
- finish_error: hold the panel until a key is pressed, return BootUIFailed
- socket EOF before finish: the writer died; show "boot aborted", hold for a key, return BootUIFailed
- Ctrl+C: forwarded to ForwardPID, never acted on here; a second one within 2s returns BootUIInterrupted
func SocketPath ¶
SocketPath is the boot event socket for a cell. Unix socket paths are capped at about 104 bytes, so it lives in the temp dir and falls back to a hashed name when the cell name is long.
func TmuxRunner ¶
TmuxRunner runs the tmux binary for PopupPreflight.
Types ¶
type BootUIOptions ¶
type BootUIOptions struct {
Socket string // unix socket the window process serves events on
ForwardPID int // process to receive the first Ctrl+C (the booting devcell)
Stdin *os.File // keyboard, for "press any key"; nil means no wait
ConnectTimeout time.Duration // give up connecting after this; default 3s
Dwell time.Duration // keep the finished panel visible before closing; default 400ms
}
BootUIOptions configures RunBootUI, the renderer that runs inside the tmux popup (`devcell boot-ui <socket>`).
type Geometry ¶
type Geometry struct{ Width, Height int }
Geometry is the popup size, from PopupPreflight.
func PopupPreflight ¶
PopupPreflight decides whether a popup can be shown: tmux 3.3 or newer (title, border and style flags) and a client large enough. run executes tmux with the given arguments and returns its stdout. groups is how many group rows the boot panel will draw (see PopupHeight).
type Popup ¶
type Popup struct {
// contains filtered or unexported fields
}
Popup is one boot popup session owned by the window process.
func StartPopup ¶
StartPopup listens for boot-ui, redirects this process's stdio away from the tty and opens the popup. On error nothing is left redirected and the caller runs with the inline panel.
func (*Popup) BeforeAttach ¶
BeforeAttach is the engine.RunOpts.BeforeAttach hook: the agent gate. It returns once the popup is gone and the tty is ours again.
func (*Popup) Finish ¶
Finish closes the session after the engine returned. On a boot error the popup stays up until the user acknowledges it; on success everything was already torn down by BeforeAttach.
func (*Popup) NewBootView ¶
func (p *Popup) NewBootView(groups []ux.PanelGroup) ux.BootView
NewBootView is the engine.RunOpts.NewBootView hook. Events buffer from the first call; boot-ui gets them when it connects. If no client connects within the window, the popup is abandoned and the buffered events replay into an inline panel on the restored tty.
type PopupSpec ¶
type PopupSpec struct {
SocketPath string // unix socket for boot events
LogPath string // where the window process's stdout/stderr go during boot
Title string // popup title
Accent string // tmux colour for the border
Geometry Geometry // from PopupPreflight
Tmux string // tmux binary; default "tmux"
Self string // devcell binary that runs boot-ui; default os.Executable()
SelfArgs []string // arguments placed before "boot-ui" (tests inject a helper)
Env []string // KEY=VALUE pairs for boot-ui; the popup runs from the tmux server's environment, not ours
}
PopupSpec is what StartPopup needs.
type Spec ¶
type Spec struct {
WorkspaceName string
CellID string
CellName string
WorkspaceHome string // ~/.devcell/<workspace>; the config is written below it
Theme Theme // from ResolveTheme; zero value means the default preset
}
Spec is what the cage needs to render its bar and find its config.
type Theme ¶
type Theme struct {
BarBG, BarFG string
WorkspaceBG, WorkspaceFG string
CellBG, CellFG string
StatusBG, StatusFG string
Accent string
Separator string
}
Theme is the resolved colour set the cage template renders. The bar has three elements, each coloured on its own: the workspace name, the cell name and the status panel (clocks). Bar* colours fill the gap between.
func ResolveTheme ¶
func ResolveTheme(t cfg.ThemeSection) (Theme, error)
ResolveTheme turns [theme] into a Theme: the named preset (or the default) with every non-empty override applied. Colours are checked here because tmux stops reading the config at the first bad one.