Using Fut
TL;DR: Run
futin a project. Most interactive actions start withCtrl-b; pause after the prefix to see every binding, or pressCtrl-b :to search the command palette. Detach withCtrl-b dand return withfut.
Start and return
cd ~/code/my-project
fut
Bare fut starts the daemon when needed, opens the current directory, and
attaches a client. The daemon keeps sessions and terminal processes alive after
you detach. Detached terminals keep consuming and parsing their output, but Fut
defers screen rendering until a client observes them again. Runtime state is not
restored after the daemon exits or the machine restarts.
fut daemon shutdown gracefully closes every session. If an upgrade leaves an
older, protocol-incompatible daemon running, Fut first asks that daemon’s own
executable to shut it down. As a final recovery path,
fut daemon shutdown --force verifies the Unix socket belongs to your user and
terminates its owning process without speaking the incompatible protocol.
Run fut from another directory to open it in the existing daemon. Fut groups
resources like this:
session a project-level container
└─ workspace a user-defined context, often a checkout or worktree
└─ tab a named or process-titled terminal layout
└─ pane a placement of one running terminal
Use fut attach to open the global navigator before attaching, or target an
unambiguous resource directly with fut session attach, fut workspace
attach, fut tab attach, fut pane attach, or fut terminal attach.
Fut refuses to start a nested interactive client inside one of its terminals.
If nesting is intentional, run FUT_ALLOW_NESTED=1 fut.
For Git repositories, Fut groups linked worktrees from the same repository as peer workspaces in one session. Ordinary directories get their own session. Opening the same location again reuses it; bare Git repositories are not valid workspaces.
Everyday controls
These default bindings follow the Ctrl-b prefix, configurable as ui.prefix.
The configuration name is the key to override under [ui.bindings].
| Key | Action | Configuration name |
|---|---|---|
: |
Search every command and configured extension action | open_command_bar |
Shift-S |
Open a configured project or path | open_project |
R |
Reload global and focused-project configuration | reload_config |
[ |
Enter copy mode | enter_copy_mode |
s |
Search sessions, workspaces, tabs, and panes | open_navigator |
a |
Search agents and see their live status | open_agents |
w |
Open the left sidebar | open_left_sidebar |
] |
Open the right sidebar | open_right_sidebar |
t |
Focus the tab bar | open_tab_bar |
u |
List agent notifications and terminal alerts | open_notifications |
Prefix |
Jump to the next notification or terminal alert | focus_next_notification |
C |
Create a workspace | create_workspace |
c |
Create a tab | create_tab |
n |
Switch to the next tab | focus_next_tab |
p |
Switch to the previous tab | focus_previous_tab |
Down |
Switch to the next workspace | focus_next_workspace |
Up |
Switch to the previous workspace | focus_previous_workspace |
| |
Split the pane right | split_pane_right |
_ |
Split the pane down | split_pane_down |
o |
Focus the next pane | focus_next_pane |
; |
Focus the previous pane | focus_previous_pane |
h / j / k / l |
Focus the pane left / down / up / right | focus_pane_left / focus_pane_down / focus_pane_up / focus_pane_right |
P |
Switch to the last active pane | focus_last_pane |
Ctrl-t |
Switch to the last active tab | focus_last_tab |
Ctrl-w |
Switch to the last active workspace | focus_last_workspace |
Ctrl-s |
Switch to the last active session | focus_last_session |
1–9, 0 |
Select tab 1–10 | focus_tab_1 through focus_tab_10 |
z |
Toggle pane zoom | toggle_pane_zoom |
x |
Close the focused pane | close_pane |
d |
Detach | detach |
Pause for 700 ms after Ctrl-b to see the complete, current binding list.
Bindings can be changed in Configuration.
The command palette also provides unbound rename-session, rename-workspace,
rename-tab, kill-session, kill-workspace, and kill-tab actions for the
focused resource. Session actions target the session to which the client is
attached; closing it ends that attachment along with its terminals.
Press Ctrl-b Shift-S to open a project without leaving the client. Fut fuzzy
filters only the explicit [projects] catalog and never scans for repositories.
Typing also adds an Open path row for the exact value, resolved relative to
the focused workspace; obvious paths and queries without a project match select
that row automatically. Opening a live project navigates to its existing
terminal. A new project applies its recipe and focuses the terminal selected by
that recipe.
If a repository recipe is not yet trusted, Fut shows its exact contents for
review and accepts or declines machine-local approval in the same dialog.
The tab bar and workspace rows also support the mouse: left-click to switch or activate a clickable extension token, and right-click for create, rename, close, and sidebar display actions. Token clicks include their visible affixes and pills and take precedence over switching the surrounding tab or expanded workspace row. Drag pane or sidebar dividers to resize them. Fut preserves application mouse reporting; when an application does not claim the mouse, the wheel scrolls client-local history and dragging selects text. Hold Shift to force Fut selection.
Copy and scrollback
Press Ctrl-b [ for copy mode. Move with arrows, hjkl, Home/End, or page
keys. Space starts or clears a selection; y or Enter copies it; Escape or q
cancels. / searches literal text and n/N repeats the search.
Clipboard writes use pbcopy on macOS. On Linux, Fut automatically uses
wl-copy in Wayland sessions or xclip/xsel in X11 sessions. Install
wl-clipboard, xclip, or xsel if your desktop does not provide one. In an
SSH or headless session without access to a graphical clipboard, Fut reports
that the clipboard is unavailable. A failed copy keeps the selection active
for another attempt.
Workspaces, tabs, and panes
Workspaces are organizational contexts, not Git objects. Fut uses their root as a working-directory fallback but does not create or manage worktrees. Unnamed workspaces show their live directory or Git work tree; unnamed tabs follow the oldest surviving pane’s foreground process. Focusing a pane does not change the shared tab label. Rename either to keep a fixed label, or submit an empty name to restore the automatic label.
Pane splits and divider sizes are shared daemon state. Client focus, zoom,
scrollback, dialogs, and configuration are local. Multiple clients may attach
to the same session. Concurrent divider drags use the last ratio accepted by
the daemon, and every client reconciles to that shared ratio. If another client
changes the pane topology during a drag, Fut cancels the stale drag and shows
Layout changed in another client. Attached clients also share terminal input
and output, and shared PTYs use the smallest attached client’s dimensions.
Terminal alerts
Fut reports real BEL characters as terminal-native attention without interpreting ordinary output as agent completion or blocking. An OSC string terminator is not a bell, and repeated bells are represented by a bounded counter rather than an event log.
Bells roll up to tabs, workspace rows, sessions, and navigator results. Press
Ctrl-b u to inspect them, Enter to switch to the pane, or c to acknowledge
the selected bell or agent notification without changing agent lifecycle state.
Ctrl-b Ctrl-b moves to the next alert using typed pane navigation, considering
the current terminal last; when it is the only waiting terminal, Fut reveals and
acknowledges it or confirms that its already-visible attention was cleared.
Rendering the focused pane acknowledges its current bell for this client only;
another attached client keeps its own seen state. A new outer terminal starts at
the current bell baseline. Agent lifecycle state remains separate.
See Configuration for the opt-in outer-terminal BEL.
Fut renders standard terminal mouse modes, indexed and RGB color, OSC 8
hyperlinks, cursor shapes, bracketed paste, alternate screens, application
cursor keys, mode-aware modified keys, and Kitty graphics used by terminals
such as Ghostty, Kitty, and WezTerm. When attached directly from Ghostty,
Kitty, WezTerm, foot, or Alacritty, Fut negotiates the Kitty keyboard protocol
with the outer terminal. This keeps keys such as Ctrl-I distinct from Tab,
preserves modified navigation keys, and lets inner applications request
modifyOtherKeys or Kitty press/repeat/release reporting. Plain text stays on the
traditional UTF-8 path so input generated by accessibility tools and input
methods retains its associated text. Other outer terminals, including terminal
chains that do not advertise this capability, stay on the traditional input
path: text, Unicode, Ctrl/Alt chords, navigation keys, and F1–F12 remain
compatible, but ambiguities already present in legacy terminal input cannot be
recovered.
CLI and automation
The CLI is noun-first. Ask the installed version for exact arguments:
fut --help
fut pane --help
fut pane split --help
Common control commands include:
fut open ../api --name api -- zsh
fut open -b ../api
fut tab new --name tests -- mise run test
fut pane split right --cwd ../api -- zsh
fut pane move PANE_ID DESTINATION_TAB_ID
fut list
fut list --verbose
fut events
fut extension list
fut extension show EXTENSION_ID
fut extension validate PATH
fut extension install PATH
fut extension install-git URL --rev COMMIT [--sha256 DIGEST]
fut extension update EXTENSION_ID --rev COMMIT [--sha256 DIGEST]
fut extension enable EXTENSION_ID
fut extension disable EXTENSION_ID
fut extension remove EXTENSION_ID
fut extension reload
Commands after -- are passed directly, without shell evaluation. Creation
and mutation commands do not change another client’s visual focus. Inside Fut,
many resource IDs may be omitted and are resolved from the caller’s live
terminal ancestry. Human-facing output and shell completion use 23-character
compact Fut IDs. They encode the complete 128-bit identity, so they are stable
and do not depend on the current set of resources. Every ID argument also
accepts the canonical UUID form. Automation should use --json, retain the
returned canonical UUIDs, and pass explicit IDs to later commands.
For terminal I/O, lifecycle-aware agent control, and event streaming, see
Agent activity. Fut also bundles machine-readable operating
instructions through fut agent skill.
Enable dynamic shell completion in your startup file:
# zsh
source <(COMPLETE=zsh fut)
# bash
source <(COMPLETE=bash fut)
# fish
COMPLETE=fish fut | source
Re-source completion after upgrading. Resource completion is bounded and read-only; it never starts a daemon. Active extension-ID completion uses the same bounded, read-only daemon catalog lookup. Package validation itself is daemonless and never executes extension code.
Next steps
- Agent activity — integrations, notifications, and automation
- Configuration — bindings, layout, sidebars, and styles
- Extensions — trusted local commands, hooks, and tokens
- Diagnostics — check configuration and terminal compatibility