WezTerm Configuration for AI Agents Workflow

I use four different AI agents for coding: Claude for planning, Opencode for quick edits, Aider for git operations, Gemini for automation. Every morning I'd open Windows Terminal, create tabs manually, type "claude" in one, "opencode" in another, navigate to project folders. Repeat for each project.

Ten minutes wasted before writing a single line of code.

I needed a terminal that could automate this. WezTerm solved it.

The problem with default terminals

Windows Terminal, the default on Windows 11, is fine for basic use. But when you work with multiple AI CLI tools simultaneously, it falls short:

No automation: Can't script the startup. Every session requires manual tab creation and command typing.

Slow tab switching: Mouse clicks to change tabs. No keyboard shortcuts that feel natural.

Limited customization: Want to spawn two tabs with specific commands in specific directories? Not possible.

No Lua scripting: Can't write custom behaviors. You get what Microsoft built, nothing more.

If you use one terminal for simple tasks, Windows Terminal works. If you juggle multiple AI agents across projects, you need more control.

What WezTerm does differently

WezTerm is a terminal emulator written in Rust. Cross-platform, fast, and fully scriptable with Lua.

The key feature: you can write Lua scripts to automate anything. Create custom keybindings, spawn tabs with pre-loaded commands, switch between panes, detect when windows open and run startup scripts.

I wrote a config that turns one keyboard shortcut into a full AI workspace.

The one-key workspace: Ctrl+Shift+P

Press Ctrl+Shift+P. A prompt appears: "Enter project path."

Type the path or just hit Enter for default. WezTerm immediately:

  1. Creates tab 1, navigates to your project, runs claude
  2. Creates tab 2, same directory, runs opencode

Two AI agents ready to work, in two seconds.

Here's the config:

{
  key = 'p',
  mods = 'CTRL|SHIFT',
  action = act.PromptInputLine{
    description = 'Enter project path (Enter = D:):',
    action = wezterm.action_callback(function(window, pane, line)
      local project_path = (line and line ~= '') and line or 'D:'

      -- Tab 1: Claude
      local tab1 = window:mux_window():spawn_tab{ cwd = project_path }
      tab1:active_pane():send_text("claude\r")

      -- Tab 2: Opencode
      local tab2 = window:mux_window():spawn_tab{ cwd = project_path }
      tab2:active_pane():send_text("opencode\r")
    end),
  },
}

You can extend this. Add more tabs, different commands, conditional logic based on the path. It's just Lua code.

Fast navigation between agents

When you have multiple agents running, switching between them needs to be instant.

Ctrl+Tab: Next tab Ctrl+Shift+Tab: Previous tab Alt+Arrow keys: Navigate between split panes

No mouse required. Jump from Claude to Opencode to Aider without lifting your hands from the keyboard.

Windows Terminal technically has shortcuts, but they're inconsistent. Ctrl+Tab sometimes works, sometimes doesn't. WezTerm lets you define exactly what each key does:

keys = {
  { key = 't', mods = 'CTRL', action = act.SpawnTab 'CurrentPaneDomain' },
  { key = 'w', mods = 'CTRL', action = act.CloseCurrentTab{confirm = false} },
  { key = 'Tab', mods = 'CTRL', action = act.ActivateTabRelative(1) },
  { key = 'Tab', mods = 'CTRL|SHIFT', action = act.ActivateTabRelative(-1) },
}

Close a tab with Ctrl+W. No confirmation dialog, instant close. When I'm done with Claude, I close it and move on. No friction.

Split screen for parallel work

Sometimes I need two agents visible at once. Claude on the left for planning, Opencode on the right for implementation.

Ctrl+Shift+D: Split horizontally Ctrl+Shift+Shift+D: Split vertically

Each pane is independent. Run different commands, different directories, different agents. Navigate with Alt+Arrow keys.

I use this when debugging. Claude analyzes error logs on one side, Opencode fixes code on the other. See both outputs simultaneously without switching tabs.

-- Splits
{ key = 'd', mods = 'CTRL|SHIFT', action = act.SplitHorizontal{domain = 'CurrentPaneDomain'} },
{ key = 'D', mods = 'CTRL|SHIFT', action = act.SplitVertical{domain = 'CurrentPaneDomain'} },

-- Navigate panes
{ key = 'LeftArrow', mods = 'ALT', action = act.ActivatePaneDirection 'Left' },
{ key = 'RightArrow', mods = 'ALT', action = act.ActivatePaneDirection 'Right' },

Clean, fast interface

I configured WezTerm to look minimal. Black text on white background, Cascadia Code font, no scroll bar, no fancy tab styling.

Why? Performance. Every visual feature costs CPU cycles. Disable everything unnecessary and the terminal runs faster.

-- Performance optimizations
enable_scroll_bar = false,
use_fancy_tab_bar = false,
hide_tab_bar_if_only_one_tab = true,

The tab bar only appears when I have multiple tabs. One tab? Hidden automatically.

Colors are custom-tuned. ANSI colors are darker than default, easier to read on white background:

colors = {
  background = "#FFFFFF",
  foreground = "#000000",
  ansi = {
    "#1a1a1a",  -- black (darker)
    "#cc0000",  -- red (darker)
    "#008800",  -- green (darker)
    "#cc6600",  -- yellow-orange (darker)
    "#0066cc",  -- blue (darker)
    "#cc00cc",  -- magenta (darker)
    "#0088aa",  -- cyan (darker)
    "#666666",  -- white (gray)
  },
}

Code syntax highlighting is readable. Error messages stand out. No eye strain after hours of terminal work.

Auto-maximize on startup

Every time I open WezTerm, it maximizes the window automatically. Small detail, but it saves one click every session.

wezterm.on('gui-startup', function(cmd)
  local tab, pane, window = wezterm.mux.spawn_window(cmd or {})
  window:gui_window():maximize()
end)

The window opens full-screen, ready to work. No resizing, no dragging corners.

Real workflow examples

Morning routine:

  1. Open WezTerm (auto-maximizes)
  2. Ctrl+Shift+P
  3. Hit Enter (uses default path D:)
  4. Claude and Opencode load in separate tabs
  5. Start coding

Total time: 5 seconds.

Working on a specific project:

  1. Ctrl+Shift+P
  2. Type "D:\projects\myapp"
  3. Both agents open in that directory
  4. Ready to work

Debugging with multiple agents:

  1. Tab 1: Claude analyzing logs
  2. Ctrl+Shift+D to split
  3. Right pane: Opencode editing fix
  4. Alt+Left/Right to switch focus
  5. See both outputs, no tab switching

Quick command execution:

  1. Ctrl+L clears screen instantly
  2. Ctrl+W closes tab without confirmation
  3. Ctrl+Tab cycles between agents

The pattern: minimize repetitive actions. Automate everything that happens more than once.

Why WezTerm over alternatives

Windows Terminal:

  • Pro: Built-in, no installation
  • Con: No scripting, limited customization, slow tab management

WezTerm wins on automation. I can't script Windows Terminal to spawn agents automatically.

ConEmu:

  • Pro: Lots of features, been around forever
  • Con: Complex config, outdated interface, slower than WezTerm

I tried ConEmu. Spent two hours configuring, still couldn't get auto-spawn working cleanly.

Alacritty:

  • Pro: Very fast, minimal, GPU-accelerated
  • Con: No tabs, no splits, config in TOML only

Alacritty is for people who want one terminal, one process. I need tabs and splits.

iTerm2 (Mac only):

  • Pro: Excellent features, solid automation
  • Con: Mac only, not cross-platform

WezTerm gives me iTerm2-level features on Windows. Same config works on Linux and Mac if I switch platforms.

Setting this up yourself

1. Install WezTerm

Download from https://wezfurlong.org/wezterm/installation.html

Windows: Use the installer. Takes 30 seconds.

2. Create config file

Location: C:\Users\{your-username}\.wezterm.lua

Paste this basic config:

local wezterm = require 'wezterm'
local act = wezterm.action

return {
  font = wezterm.font 'Cascadia Code',
  font_size = 13,
  default_cwd = "D:\\",  -- Change to your preferred directory
  default_prog = {"powershell.exe"},

  -- Auto-maximize on startup
  wezterm.on('gui-startup', function(cmd)
    local tab, pane, window = wezterm.mux.spawn_window(cmd or {})
    window:gui_window():maximize()
  end),

  keys = {
    -- Close tab without confirmation
    { key = 'w', mods = 'CTRL', action = act.CloseCurrentTab{confirm = false} },

    -- Tab navigation
    { key = 'Tab', mods = 'CTRL', action = act.ActivateTabRelative(1) },
    { key = 'Tab', mods = 'CTRL|SHIFT', action = act.ActivateTabRelative(-1) },
  },
}

3. Add the magic shortcut

Add this to the keys array:

{
  key = 'p',
  mods = 'CTRL|SHIFT',
  action = act.PromptInputLine{
    description = 'Enter project path (Enter = D:):',
    action = wezterm.action_callback(function(window, pane, line)
      local project_path = (line and line ~= '') and line or 'D:'

      -- Replace "claude" and "opencode" with your own commands
      local tab1 = window:mux_window():spawn_tab{ cwd = project_path }
      tab1:active_pane():send_text("claude\r")

      local tab2 = window:mux_window():spawn_tab{ cwd = project_path }
      tab2:active_pane():send_text("opencode\r")
    end),
  },
},

Change "claude" and "opencode" to whatever CLI tools you use.

4. Reload config

WezTerm auto-reloads config when you save the file. Just save .wezterm.lua and it applies instantly.

Who should use this

This setup makes sense if you:

  • Use multiple CLI tools daily (AI agents, git clients, build tools)
  • Switch between projects frequently
  • Want keyboard-driven workflow
  • Value automation over manual setup

It doesn't make sense if you:

  • Use terminal occasionally
  • Prefer GUIs over CLI
  • Only use one terminal tab at a time
  • Don't want to learn Lua (though the config above works copy-paste)

Bottom line

I used to waste 10 minutes every morning setting up terminals. Now it's one keyboard shortcut.

WezTerm isn't magic. It's a terminal with Lua scripting. But that scripting capability means I can automate the boring parts and focus on actual work.

If you work with multiple CLI tools and hate repetitive setup, try this config. Copy it, adjust the commands to your tools, and see if it saves you time.

One shortcut. Two seconds. Full workspace ready.