Skip to content

Configuration

workmux uses a two-level configuration system:

  • Global (~/.config/workmux/config.yaml): Personal defaults for all projects. Run workmux config edit to open it in your editor.
  • Project (.workmux.yaml): Project-specific overrides

Project settings override global settings. When you run workmux from a subdirectory, it walks upward to find the nearest .workmux.yaml, allowing nested configs for monorepos. See Monorepos for details. For post_create and file operation lists (files.copy, files.symlink), you can use "<global>" to include global values alongside project-specific ones. Other settings like panes are replaced entirely when defined in the project config.

XDG Base Directory support

workmux respects the XDG Base Directory Specification:

PurposeEnvironment variableDefault
ConfigurationXDG_CONFIG_HOME~/.config
CacheXDG_CACHE_HOME~/.cache
StateXDG_STATE_HOME~/.local/state

All workmux files live under a workmux/ subdirectory within these base directories. If you have an existing config at the default location and later set a custom XDG_CONFIG_HOME, workmux will fall back to reading from ~/.config/workmux/ if no config exists at the new location.

Global configuration example

~/.config/workmux/config.yaml:

yaml
nerdfont: true # Enable nerdfont icons (prompted on first run)
merge_strategy: rebase # Make workmux merge do rebase by default
agent: claude

panes:
  - command: <agent> # Start the configured agent (e.g., claude)
    focus: true
  - split: horizontal # Second pane with default shell

Project configuration example

.workmux.yaml:

yaml
post_create:
  - "<global>"
  - mise use

files:
  symlink:
    - "<global>" # Include global symlinks (node_modules)
    - .pnpm-store # Add project-specific symlink

panes:
  - command: pnpm install
    focus: true
  - command: <agent>
    split: horizontal
  - command: pnpm run dev
    split: vertical

For a real-world example, see workmux's own .workmux.yaml.

Configuration options

Most options have sensible defaults. You only need to configure what you want to customize.

Basic options

OptionDescriptionDefault
main_branchBranch to merge intoAuto-detected
base_branchDefault base branch for new worktrees (overridden by --base)Current branch
worktree_dirDirectory for worktrees (absolute or relative)<project>__worktrees/
nerdfontEnable nerdfont icons (prompted on first run)Prompted
window_prefixOverride tmux window/session prefixIcon or wm-
agentDefault agent for <agent> placeholderclaude
agentsNamed agent commands (global-only). See named agents.{}
prompt_file_onlyWrite prompt files without injecting into agent commandsfalse
merge_strategyDefault merge strategy (merge, rebase, squash)merge
themeDashboard color scheme (see themes)default (auto dark/light)
modeTmux mode (window or session). See session mode.window

Themes

The dashboard supports 12 color schemes, each with dark and light variants. Dark/light mode is auto-detected from your terminal background.

Press T (shift+t) in the dashboard to cycle through schemes. The selection persists to your global config (~/.config/workmux/config.yaml).

Available schemes: default, emberforge, glacier-signal, obsidian-pop, slate-garden, phosphor-arcade, lasergrid, mossfire, night-sorbet, graphite-code, festival-circuit, teal-drift.

yaml
# Just a scheme name (auto-detect dark/light)
theme: emberforge

# Force a specific mode
theme:
  scheme: emberforge
  mode: light

Custom colors

You can override individual palette colors using the custom block. Custom colors are applied on top of the base scheme, so you can start from any built-in theme and tweak specific colors. Values can be hex colors ("#51afef"), named colors (red, cyan), or terminal color indices (42):

yaml
theme:
  custom:
    bg: "#282c34"
    fg: "#bbc2cf"
    accent: "#51afef"
    success: "#98be65"
    warning: "#ECBE7B"
    error: "#ff6c6b"

You can also combine custom colors with a specific scheme and mode:

yaml
theme:
  scheme: emberforge
  mode: dark
  custom:
    accent: "#51afef"
    danger: "#ff6c6b"

Shorthand aliases: bg for current_row_bg, fg for text, error for danger.

All palette fields: current_row_bg, highlight_row_bg, current_worktree_fg, dimmed, text, border, help_border, help_muted, header, keycap, info, success, warning, danger, accent.

Custom colors persist when cycling themes with T.

Naming options

OptionDescriptionDefault
worktree_namingHow to derive names from branchesfull
worktree_prefixPrefix for worktree directories and windowsnone

worktree_naming strategies:

  • full: Use the full branch name (slashes become dashes)
  • basename: Use only the part after the last / (e.g., prj-123/featurefeature)

Panes

Define your tmux pane layout with the panes array. For multiple windows in session mode, use windows instead (they are mutually exclusive).

yaml
panes:
  - command: <agent>
    focus: true
  - command: npm run dev
    split: horizontal
    size: 15

Each pane supports:

OptionDescriptionDefault
commandCommand to run (see agent placeholders below)Shell
focusWhether this pane receives focusfalse
zoomZoom pane to fullscreen (implies focus: true)false
splitSplit direction (horizontal or vertical)---
sizeAbsolute size in lines/cells50%
percentageSize as percentage (1-100)50%

Agent placeholders

  • <agent>: resolves to the configured agent (from agent config or --agent flag)

Built-in agents (claude, gemini, codex, opencode, kiro-cli, vibe, pi) are auto-detected when used as literal commands and receive prompt injection automatically, without needing the <agent> placeholder or a matching agent config:

yaml
panes:
  - command: "claude --dangerously-skip-permissions"
    focus: true
  - command: "codex --yolo"
    split: vertical

Each agent receives the prompt (via -p/-P/-e) using the correct format for that agent. Auto-detection matches the executable name regardless of flags or path.

Named layouts

Define reusable pane arrangements in the layouts map and select one at add-time with -l/--layout:

yaml
layouts:
  design:
    panes:
      - command: <agent>
        focus: true
      - command: <agent:codex>
        split: vertical
  review:
    panes:
      - command: <agent>
bash
workmux add my-feature -l design

When -l is used, the layout's panes replace the top-level panes for that worktree. All other config (hooks, files, agent, etc.) comes from the top-level as usual. The -l flag cannot be combined with --agent.

Windows

When using session mode, you can configure multiple windows per session using the windows array. This is mutually exclusive with the top-level panes config. See multiple windows per session for full details.

yaml
mode: session
windows:
  - name: editor
    panes:
      - command: <agent>
        focus: true
      - split: horizontal
        size: 20
  - name: tests
    panes:
      - command: just test --watch

File operations

New worktrees are clean checkouts with no gitignored files (.env, node_modules, etc.). Use files to automatically copy or symlink what each worktree needs:

yaml
files:
  copy:
    - .env
  symlink:
    - .next/cache # Share build cache across worktrees

Both copy and symlink accept glob patterns.

To re-apply file operations to existing worktrees (e.g., after updating the config), use workmux sync-files.

Lifecycle hooks

Run commands at specific points in the worktree lifecycle, such as installing dependencies or running database migrations. All hooks run with the worktree directory as the working directory (or the nested config directory for nested configs) and receive environment variables: WM_HANDLE, WM_WORKTREE_PATH, WM_PROJECT_ROOT, WM_CONFIG_DIR.

HookWhen it runsAdditional env vars
post_createAfter worktree creation, before tmux window opens
pre_mergeBefore merging (aborts on failure)WM_BRANCH_NAME, WM_TARGET_BRANCH
pre_removeBefore worktree removal (aborts on failure)

WM_CONFIG_DIR points to the directory containing the .workmux.yaml that was used, which may differ from WM_WORKTREE_PATH when using nested configs.

Example:

yaml
post_create:
  - direnv allow

pre_merge:
  - just check

Agent status icons

Customize the icons shown in tmux window names:

yaml
status_icons:
  working: "🤖" # Agent is processing
  waiting: "💬" # Agent needs input (auto-clears on focus)
  done: "✅" # Agent finished (auto-clears on focus)

You can use tmux style codes for colored icons in both the tmux status bar and the dashboard:

yaml
status_icons:
  done: "#[fg=#a6e3a1]󰄴#[fg=default]"

Supported tmux style attributes: fg=, bg=, default. Colors can be hex (#a6e3a1), named (red, green, etc.), or indexed (colour196).

Set status_format: false to disable automatic tmux format modification.

Auto-name configuration

Configure LLM-based branch name generation for the --auto-name (-A) flag:

yaml
auto_name:
  command: "claude -p" # Use a custom command instead of the inferred default
  model: "gemini-2.5-flash-lite"
  background: true
  system_prompt: "Generate a kebab-case git branch name."

The command used for branch name generation is resolved in this order:

  1. auto_name.command is set: uses that command as-is
  2. agent is a known agent (claude, gemini, codex, opencode, kiro-cli, vibe, pi): uses the agent's CLI with a fast/cheap model automatically
  3. Neither: falls back to the llm CLI (requires installation)

To override back to llm when an agent is configured, set auto_name.command: "llm".

OptionDescriptionDefault
commandCommand for branch name generation (overrides agent profile)Agent profile or llm CLI
modelLLM model to use with the llm CLI (ignored when command set)llm's default
backgroundAlways run in background when using --auto-namefalse
system_promptCustom system prompt for branch name generationBuilt-in prompt

See workmux add --auto-name for usage details.

Default behavior

  • Worktrees are created in <project>__worktrees as a sibling directory to your project by default
  • If no panes configuration is defined, workmux provides opinionated defaults:
    • For projects with a CLAUDE.md file: Opens the configured agent (see agent option) in the first pane, defaulting to claude if none is set.
    • For all other projects: Opens your default shell.
    • Both configurations include a second pane split horizontally
  • post_create commands are optional and only run if you configure them

Automatic setup with panes

Use the panes configuration to automate environment setup. Unlike post_create hooks which must finish before the tmux window opens, pane commands execute immediately within the new window.

This can be used for:

  • Installing dependencies: Run npm install or cargo build in a focused pane to monitor progress.
  • Starting services: Launch dev servers, database containers, or file watchers automatically.
  • Running agents: Initialize AI agents with specific context.

Since these run in standard tmux panes, you can interact with them (check logs, restart servers) just like a normal terminal session.

TIP

Running dependency installation (like pnpm install) in a pane command rather than post_create has a key advantage: you get immediate access to the tmux window while installation runs in the background. With post_create, you'd have to wait for the install to complete before the window even opens. This also means AI agents can start working immediately in their pane while dependencies install in parallel.

yaml
panes:
  # Pane 1: Install dependencies, then start dev server
  - command: pnpm install && pnpm run dev

  # Pane 2: AI agent
  - command: <agent>
    split: horizontal
    focus: true

Released under the MIT License.