Tech Guides

Hyprland AI Workstation

A comprehensive guide to optimizing Arch Linux + Hyprland as an AI coding workstation for Claude Code and Codex power users

Compositor Hyprland
Protocol Wayland
Distro Arch Linux
AI CLI Claude + Codex
01

Quick Reference

The essential keybinds and commands you need every day. Print this, tape it to your monitor, and burn it into muscle memory.

Hyprland Essentials

Open terminal SUPER + Enter
Close window SUPER + Q
Switch workspace 1-9 SUPER + 1-9
Move window to workspace SUPER + SHIFT + 1-9
Move focus SUPER + Arrow Keys
Move window SUPER + SHIFT + Arrow Keys
Fullscreen toggle SUPER + F
Float toggle SUPER + V
App launcher SUPER + D

tmux Quick Keys

All tmux commands use the Ctrl + b prefix, then press the action key.

New window Ctrl+b then c
Next window Ctrl+b then n
Previous window Ctrl+b then p
Vertical split Ctrl+b then %
Horizontal split Ctrl+b then "
Detach session Ctrl+b then d
Zoom pane (toggle) Ctrl+b then z

Claude Code

Start interactive
claude

Launch Claude Code in interactive mode in the current directory

One-shot prompt
claude -p "prompt"

Run a single prompt and exit; great for scripting and pipelines

Initialize project
/init

Create a CLAUDE.md with project context for better results

Accept all changes
Shift+Tab

Accept all pending file changes at once

Interrupt
Esc

Stop the current generation mid-stream

Add context
# (in prompt)

Reference files, URLs, or other context in your message

Codex CLI

Start interactive
codex

Launch Codex in interactive mode in the current directory

One-shot prompt
codex "prompt"

Run a single prompt directly from the command line

Autonomous mode
codex --full-auto

Let Codex run without manual approval for each step

Select model
codex --model MODEL

Choose a specific model for the session

System Monitoring

System monitor
btop

Beautiful resource monitor: CPU, memory, disks, network, processes

GPU monitor
nvtop

GPU usage, temperature, VRAM, and running processes (NVIDIA/AMD/Intel)

Live system logs
journalctl -f

Stream system journal logs in real time; invaluable for debugging

User services
systemctl --user status

Check status of user-level systemd services

02

Base Arch Setup

A minimal, reproducible package selection for a Hyprland-powered AI development workstation. Install only what you need, keep it lean.

Core Compositor & Desktop

These are the essential packages for a functional Hyprland desktop. Install them first.

# Core Hyprland stack
sudo pacman -S --needed hyprland hyprpaper hyprlock hypridle \
    waybar wofi dunst xdg-desktop-portal-hyprland
Package Role
hyprland Dynamic tiling Wayland compositor -- the core of the setup
hyprpaper Wallpaper daemon with per-monitor support
hyprlock GPU-accelerated screen locker with custom widgets
hypridle Idle daemon -- triggers lock/suspend on inactivity
waybar Highly customizable status bar (workspaces, clock, tray, etc.)
wofi Wayland-native application launcher (or use rofi-wayland from AUR for more theming)
dunst Lightweight notification daemon (or swaync for a richer notification center)
xdg-desktop-portal-hyprland Screen sharing, file dialogs, and app integration portal

Terminal Emulator

Your terminal is where you'll spend 90% of your time. Choose one.

# Recommended: Kitty (GPU-accelerated, splits, images, ligatures)
sudo pacman -S --needed kitty

# Alternative: Foot (lighter, simpler, still fast)
sudo pacman -S --needed foot
Recommendation

Kitty is the preferred choice for AI coding workflows. Its native split support means you can have Claude Code running in one pane and your editor in another without needing tmux for simple layouts. It also renders inline images, which is useful for reviewing generated charts and diagrams.

37.0C

AUR Helper

Many useful tools live in the AUR. You need a helper to build and install them.

# Install paru (recommended, Rust-based, fast)
sudo pacman -S --needed base-devel git
git clone https://aur.archlinux.org/paru.git
cd paru && makepkg -si

# Alternative: yay (Go-based, also popular)
git clone https://aur.archlinux.org/yay.git
cd yay && makepkg -si

Developer Toolchain

Essential compilers, runtimes, and version managers for daily development work.

# Core development tools
sudo pacman -S --needed git base-devel

# Languages & runtimes
sudo pacman -S --needed nodejs npm python python-pip rustup go

# Initialize Rust toolchain
rustup default stable
About --needed

The --needed flag tells pacman to skip packages that are already installed and up-to-date. This makes your install commands idempotent -- safe to re-run without reinstalling everything. Always use it in scripts and dotfiles.

-40.0C

AI Coding Tools

Install the AI CLI tools that make this workstation special.

# Claude Code (Anthropic's CLI)
npm install -g @anthropic-ai/claude-code

# Codex CLI (OpenAI's CLI) -- via npm
npm install -g @openai/codex

# Codex CLI -- alternatively via pip
pip install openai-codex
# Verify installations
claude --version
codex --version
API Keys Required

Both tools require API keys. Set ANTHROPIC_API_KEY for Claude Code and OPENAI_API_KEY for Codex in your shell profile (~/.zshrc or ~/.bashrc). Never commit these to git -- use a secrets manager or encrypted .env file.

72.5C

System Utilities

Clipboard, screenshots, screen recording, and hardware control utilities for a complete Wayland desktop.

# System utilities for a complete Wayland workstation
sudo pacman -S --needed btop nvtop wl-clipboard cliphist \
    grim slurp wf-recorder brightnessctl playerctl \
    tailscale openssh
Package Role
btop Resource monitor with CPU, RAM, disk, network graphs
nvtop GPU monitor for NVIDIA, AMD, and Intel GPUs
wl-clipboard Command-line clipboard access (wl-copy / wl-paste)
cliphist Clipboard history manager -- search and reuse past copies
grim Screenshot tool for Wayland compositors
slurp Region selector for screenshots (pairs with grim)
wf-recorder Screen recorder for Wayland (h264/h265 output)
brightnessctl Backlight and LED brightness control
playerctl MPRIS media player control from the command line

Modern Shell Toolchain

Replace legacy Unix tools with modern alternatives that offer better defaults, color output, and AI-friendly features.

# Modern replacements for classic Unix tools
sudo pacman -S --needed eza bat ripgrep fd zoxide fzf \
    git-delta starship atuin direnv dust procs tokei lazygit
Modern Tool Replaces Why It's Better
eza ls Icons, git status, tree view, color-coded file types
bat cat Syntax highlighting, line numbers, git integration
ripgrep grep 10-50x faster, respects .gitignore, regex by default
fd find Simpler syntax, respects .gitignore, parallel execution
zoxide cd Frecency-based directory jumping (z project instead of cd ~/long/path/to/project)
git-delta diff Side-by-side diffs, syntax highlighting, line numbers
starship bash/zsh prompt Cross-shell prompt with git, language, and context info
atuin history Encrypted, searchable shell history synced across machines
lazygit git (interactive) Full TUI git client with staging, branching, rebasing
dust du Visual disk usage with tree chart
# Shell aliases for muscle memory (add to ~/.zshrc)
alias ls='eza --icons'
alias ll='eza -la --icons --git'
alias tree='eza --tree --icons'
alias cat='bat --style=plain'
alias grep='rg'
alias find='fd'
alias top='btop'
alias du='dust'
alias ps='procs'
alias lg='lazygit'

# Initialize tools (add to ~/.zshrc)
eval "$(starship init zsh)"
eval "$(zoxide init zsh)"
eval "$(atuin init zsh)"
Delta for Git Diffs

Add [core] pager = delta to your ~/.gitconfig and every git diff, git log -p, and git show gets syntax-highlighted side-by-side diffs automatically. Pair with [delta] side-by-side = true and line-numbers = true for maximum readability.

36.6C

Fonts

Good fonts are non-negotiable for a coding workstation. Nerd Fonts include programming ligatures and icon glyphs used by status bars and terminal prompts.

# Essential coding fonts + emoji support
sudo pacman -S --needed ttf-jetbrains-mono-nerd ttf-fira-code \
    noto-fonts noto-fonts-emoji
Pro Tip

JetBrains Mono Nerd is the best all-round terminal font. It has programming ligatures, excellent readability at small sizes, and the full Nerd Font icon set that waybar and starship use. Set it as your terminal font at 11-13px for optimal density.

36.6C

Full Install One-Liner

For the impatient, here's everything from this section in a single copy-pasteable block.

# Complete base setup -- run after a fresh Arch install with base packages
sudo pacman -S --needed \
    hyprland hyprpaper hyprlock hypridle \
    waybar wofi dunst xdg-desktop-portal-hyprland \
    kitty \
    git base-devel nodejs npm python python-pip rustup go \
    btop nvtop wl-clipboard cliphist \
    grim slurp wf-recorder brightnessctl playerctl \
    ttf-jetbrains-mono-nerd ttf-fira-code \
    noto-fonts noto-fonts-emoji

# Initialize Rust
rustup default stable

# Install AI coding tools
npm install -g @anthropic-ai/claude-code
npm install -g @openai/codex
03

Hyprland Configuration

The heart of your workstation. Every line of this config is tuned for fast, distraction-free AI-assisted development.

Config File Location

# Hyprland reads its config from:
~/.config/hypr/hyprland.conf

# Create the directory if it doesn't exist
mkdir -p ~/.config/hypr
Live Reload

Hyprland watches its config file and reloads automatically when you save changes. No need to restart the compositor -- just save and see the results instantly. You can also force a reload with hyprctl reload.

-20.0C

Monitor Setup

Configure your displays. Hyprland supports per-monitor resolution, refresh rate, position, and scaling.

# === MONITORS ===

# Auto-detect single monitor (preferred resolution & refresh rate)
monitor=,preferred,auto,1

# Explicit single monitor (4K at 144Hz, no scaling)
monitor=DP-1,3840x2160@144,0x0,1

# Multi-monitor: laptop display + external monitor
monitor=eDP-1,1920x1080@60,0x0,1
monitor=DP-2,3440x1440@165,1920x0,1

# Multi-monitor: triple setup (center primary, flanking secondaries)
monitor=DP-1,2560x1440@165,0x0,1
monitor=DP-2,3840x2160@144,2560x0,1
monitor=DP-3,2560x1440@165,6400x0,1
Find Your Monitor Names

Run hyprctl monitors to see connected displays with their names (DP-1, HDMI-A-1, eDP-1, etc.), supported resolutions, and current configuration.

36.6C

Environment Variables

These ensure Wayland compatibility across the entire desktop stack -- browsers, Qt apps, Electron apps, and screen sharing all need them.

# === ENVIRONMENT VARIABLES ===

# Core Wayland session
env = WAYLAND_DISPLAY,wayland-1
env = XDG_CURRENT_DESKTOP,Hyprland
env = XDG_SESSION_TYPE,wayland
env = XDG_SESSION_DESKTOP,Hyprland

# Application compatibility
env = MOZ_ENABLE_WAYLAND,1
env = QT_QPA_PLATFORM,wayland
env = QT_WAYLAND_DISABLE_WINDOWDECORATION,1
env = GDK_BACKEND,wayland,x11
env = SDL_VIDEODRIVER,wayland
env = CLUTTER_BACKEND,wayland

# Cursor theme (set your preferred cursor here)
env = XCURSOR_SIZE,24
env = XCURSOR_THEME,Adwaita

# Electron apps (VS Code, Discord, etc.) -- Wayland on v28+
env = ELECTRON_OZONE_PLATFORM_HINT,auto
NVIDIA GPU Users

NVIDIA requires additional environment variables or you'll get flashing windows, login failures, and high CPU usage. Add these to your config:

88.0C
# === NVIDIA-SPECIFIC (remove if AMD/Intel) ===
env = LIBVA_DRIVER_NAME,nvidia
env = __GLX_VENDOR_LIBRARY_NAME,nvidia
env = GBM_BACKEND,nvidia-drm
env = NVD_BACKEND,direct
env = WLR_NO_HARDWARE_CURSORS,1

# Force Vulkan backend for wgpu-based apps
env = WGPU_BACKEND,vulkan

Input Configuration

Optimized for fast terminal typing. Higher repeat rate and lower delay mean less waiting when holding keys to navigate code.

# === INPUT ===

input {
    # Keyboard layout (change to your locale)
    kb_layout = us

    # Remap Caps Lock to Escape -- essential for vim/neovim users
    kb_options = caps:escape

    # Fast key repeat for terminal navigation
    # repeat_rate = keys per second after delay
    # repeat_delay = ms before repeat kicks in
    repeat_rate = 50
    repeat_delay = 300

    # Mouse / touchpad
    follow_mouse = 1
    sensitivity = 0

    touchpad {
        natural_scroll = true
        tap-to-click = true
        drag_lock = true
    }
}
Caps Lock Remap

kb_options = caps:escape is the single most impactful keybind change you can make. Escape is used constantly in vim, tmux, and Claude Code (to interrupt). Moving it to Caps Lock saves your pinky finger thousands of reaches per day.

65.0C

General Settings

Gaps, borders, and layout behavior. Minimal gaps keep more code on screen while still providing visual separation between windows.

# === GENERAL ===

general {
    # Gaps between windows and screen edges
    gaps_in = 4
    gaps_out = 8

    # Border width and colors (thermal palette)
    border_size = 2

    # Active border: blue to teal gradient
    col.active_border = rgba(6366f1ee) rgba(14b8a6ee) 45deg

    # Inactive border: dark purple
    col.inactive_border = rgba(2d1b6944)

    # Layout algorithm
    layout = dwindle
}

Decoration

Visual effects for windows. Keep rounding minimal and shadows subtle -- this is a workstation, not a rice contest (well, mostly).

# === DECORATION ===

decoration {
    # Rounded corners (subtle)
    rounding = 6

    # Shadow
    shadow {
        enabled = true
        range = 12
        render_power = 3
        color = rgba(0a001088)
    }

    # Blur (for transparent terminals)
    blur {
        enabled = true
        size = 6
        passes = 2
        new_optimizations = true
        xray = false
    }
}

Animations

Fast, snappy transitions optimized for productivity. Slow animations feel like lag when you're context-switching between AI sessions and editor panes.

# === ANIMATIONS ===
# Tuned for speed -- all transitions under 200ms

animations {
    enabled = true

    # Custom bezier curves
    bezier = snappy, 0.25, 1, 0.5, 1
    bezier = quick, 0.15, 0, 0.1, 1

    # Window open/close
    animation = windows, 1, 3, snappy, slide
    animation = windowsOut, 1, 3, snappy, slide

    # Fade for transparency changes
    animation = fade, 1, 3, quick

    # Workspace switching
    animation = workspaces, 1, 3, snappy, slide
}

Window Rules

Per-application overrides for opacity, floating behavior, and workspace assignment. These rules keep your workspace organized automatically.

# === WINDOW RULES ===

# Terminal transparency (active 95%, inactive 85%)
windowrulev2 = opacity 0.95 0.85, class:^(kitty)$
windowrulev2 = opacity 0.95 0.85, class:^(foot)$

# Browser -- no transparency, slightly rounded
windowrulev2 = opacity 1.0 1.0, class:^(firefox)$
windowrulev2 = opacity 1.0 1.0, class:^(chromium)$

# File picker dialogs -- always float
windowrulev2 = float, title:^(Open File)$
windowrulev2 = float, title:^(Save As)$
windowrulev2 = float, title:^(Choose Files)$

# Pavucontrol (audio mixer) -- float, centered
windowrulev2 = float, class:^(pavucontrol)$
windowrulev2 = size 600 400, class:^(pavucontrol)$
windowrulev2 = center, class:^(pavucontrol)$

# Picture-in-picture -- small, always on top
windowrulev2 = float, title:^(Picture-in-Picture)$
windowrulev2 = pin, title:^(Picture-in-Picture)$
windowrulev2 = size 400 225, title:^(Picture-in-Picture)$
windowrulev2 = move 100%-410 100%-235, title:^(Picture-in-Picture)$

# Notification daemon -- suppress workspace change
windowrulev2 = float, class:^(dunst)$

Key Bindings

The complete keybinding configuration. $mod is your Super/Windows/Meta key.

# === KEY BINDINGS ===

$mod = SUPER

# --- Core ---
bind = $mod, Return, exec, kitty
bind = $mod, Q, killactive
bind = $mod, M, exit
bind = $mod, D, exec, wofi --show drun
bind = $mod, F, fullscreen, 0
bind = $mod, V, togglefloating

# --- Focus ---
bind = $mod, left, movefocus, l
bind = $mod, right, movefocus, r
bind = $mod, up, movefocus, u
bind = $mod, down, movefocus, d

# --- Move windows ---
bind = $mod SHIFT, left, movewindow, l
bind = $mod SHIFT, right, movewindow, r
bind = $mod SHIFT, up, movewindow, u
bind = $mod SHIFT, down, movewindow, d

# --- Workspaces ---
bind = $mod, 1, workspace, 1
bind = $mod, 2, workspace, 2
bind = $mod, 3, workspace, 3
bind = $mod, 4, workspace, 4
bind = $mod, 5, workspace, 5
bind = $mod, 6, workspace, 6
bind = $mod, 7, workspace, 7
bind = $mod, 8, workspace, 8
bind = $mod, 9, workspace, 9

# --- Move to workspace ---
bind = $mod SHIFT, 1, movetoworkspace, 1
bind = $mod SHIFT, 2, movetoworkspace, 2
bind = $mod SHIFT, 3, movetoworkspace, 3
bind = $mod SHIFT, 4, movetoworkspace, 4
bind = $mod SHIFT, 5, movetoworkspace, 5
bind = $mod SHIFT, 6, movetoworkspace, 6
bind = $mod SHIFT, 7, movetoworkspace, 7
bind = $mod SHIFT, 8, movetoworkspace, 8
bind = $mod SHIFT, 9, movetoworkspace, 9

# --- Resize with mod + right-click drag ---
bindm = $mod, mouse:272, movewindow
bindm = $mod, mouse:273, resizewindow

# --- Screenshots ---
bind = , Print, exec, grim -g "$(slurp)" - | wl-copy
bind = SHIFT, Print, exec, grim - | wl-copy

# --- Clipboard history ---
bind = $mod, C, exec, cliphist list | wofi --dmenu | cliphist decode | wl-copy

# --- Volume control ---
binde = , XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
binde = , XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
bind = , XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle

# --- Brightness control ---
binde = , XF86MonBrightnessUp, exec, brightnessctl set +5%
binde = , XF86MonBrightnessDown, exec, brightnessctl set 5%-

Workspace Rules

Assign workspaces to specific monitors in multi-monitor setups. This keeps your mental model stable -- code is always on the center screen, browser always on the right, etc.

# === WORKSPACE RULES ===
# Assign workspaces to monitors (multi-monitor)

# Primary monitor: coding workspaces
workspace = 1, monitor:DP-2, default:true
workspace = 2, monitor:DP-2
workspace = 3, monitor:DP-2

# Left monitor: reference / docs
workspace = 4, monitor:DP-1, default:true
workspace = 5, monitor:DP-1

# Right monitor: browser / communication
workspace = 6, monitor:DP-3, default:true
workspace = 7, monitor:DP-3

# Scroll through workspaces on current monitor
bind = $mod, mouse_down, workspace, e+1
bind = $mod, mouse_up, workspace, e-1

Autostart (exec-once)

Services and daemons that launch once when Hyprland starts. These are the background processes that make the desktop functional.

# === AUTOSTART ===

# Status bar
exec-once = waybar

# Notification daemon (pick one)
exec-once = dunst
# exec-once = swaync    # alternative: richer notification center with panel

# Wallpaper (pick one)
exec-once = hyprpaper
# exec-once = swww-daemon  # alternative: animated transitions + crossfade

# Clipboard listener (stores clipboard history)
exec-once = wl-paste --type text --watch cliphist store
exec-once = wl-paste --type image --watch cliphist store

# Idle daemon (lock after 5 min, suspend after 10 min)
exec-once = hypridle

# Authentication agent (for GUI sudo prompts)
exec-once = /usr/lib/polkit-kde-authentication-agent-1

# Optional: start tmux session on boot
# exec-once = kitty --class startup-term -e tmux new -s main
exec vs exec-once

Use exec-once for daemons and background services -- they should only start one instance. Use exec (without -once) only for commands you want to re-run on every config reload, which is almost never what you want for services.

220.0C
Session Management with uwsm

For a cleaner launch, use uwsm (Universal Wayland Session Manager) instead of raw exec Hyprland in your shell profile. uwsm ensures environment variables propagate correctly to systemd user units, which fixes issues where exec-once services can't see your WAYLAND_DISPLAY. Install with pacman -S uwsm, then start with uwsm start hyprland from your ~/.zprofile.

-15.0C

Complete Config File

Everything above combined into a single ready-to-use hyprland.conf. Copy this to ~/.config/hypr/hyprland.conf and customize to taste.

# ~/.config/hypr/hyprland.conf
# Hyprland AI Workstation Configuration
# Optimized for Claude Code + Codex power users

# --- Monitors ---
monitor=,preferred,auto,1

# --- Environment ---
env = XDG_CURRENT_DESKTOP,Hyprland
env = XDG_SESSION_TYPE,wayland
env = XDG_SESSION_DESKTOP,Hyprland
env = MOZ_ENABLE_WAYLAND,1
env = QT_QPA_PLATFORM,wayland
env = QT_WAYLAND_DISABLE_WINDOWDECORATION,1
env = GDK_BACKEND,wayland,x11
env = XCURSOR_SIZE,24

# --- Input ---
input {
    kb_layout = us
    kb_options = caps:escape
    repeat_rate = 50
    repeat_delay = 300
    follow_mouse = 1
    sensitivity = 0
    touchpad {
        natural_scroll = true
        tap-to-click = true
    }
}

# --- General ---
general {
    gaps_in = 4
    gaps_out = 8
    border_size = 2
    col.active_border = rgba(6366f1ee) rgba(14b8a6ee) 45deg
    col.inactive_border = rgba(2d1b6944)
    layout = dwindle
}

# --- Decoration ---
decoration {
    rounding = 6
    shadow {
        enabled = true
        range = 12
        render_power = 3
        color = rgba(0a001088)
    }
    blur {
        enabled = true
        size = 6
        passes = 2
        new_optimizations = true
    }
}

# --- Animations ---
animations {
    enabled = true
    bezier = snappy, 0.25, 1, 0.5, 1
    bezier = quick, 0.15, 0, 0.1, 1
    animation = windows, 1, 3, snappy, slide
    animation = windowsOut, 1, 3, snappy, slide
    animation = fade, 1, 3, quick
    animation = workspaces, 1, 3, snappy, slide
}

# --- Window Rules ---
windowrulev2 = opacity 0.95 0.85, class:^(kitty)$
windowrulev2 = opacity 1.0 1.0, class:^(firefox)$
windowrulev2 = float, title:^(Open File)$
windowrulev2 = float, title:^(Save As)$
windowrulev2 = float, class:^(pavucontrol)$
windowrulev2 = size 600 400, class:^(pavucontrol)$
windowrulev2 = center, class:^(pavucontrol)$

# --- Key Bindings ---
$mod = SUPER
bind = $mod, Return, exec, kitty
bind = $mod, Q, killactive
bind = $mod, M, exit
bind = $mod, D, exec, wofi --show drun
bind = $mod, F, fullscreen, 0
bind = $mod, V, togglefloating
bind = $mod, left, movefocus, l
bind = $mod, right, movefocus, r
bind = $mod, up, movefocus, u
bind = $mod, down, movefocus, d
bind = $mod SHIFT, left, movewindow, l
bind = $mod SHIFT, right, movewindow, r
bind = $mod SHIFT, up, movewindow, u
bind = $mod SHIFT, down, movewindow, d
bind = $mod, 1, workspace, 1
bind = $mod, 2, workspace, 2
bind = $mod, 3, workspace, 3
bind = $mod, 4, workspace, 4
bind = $mod, 5, workspace, 5
bind = $mod, 6, workspace, 6
bind = $mod, 7, workspace, 7
bind = $mod, 8, workspace, 8
bind = $mod, 9, workspace, 9
bind = $mod SHIFT, 1, movetoworkspace, 1
bind = $mod SHIFT, 2, movetoworkspace, 2
bind = $mod SHIFT, 3, movetoworkspace, 3
bind = $mod SHIFT, 4, movetoworkspace, 4
bind = $mod SHIFT, 5, movetoworkspace, 5
bind = $mod SHIFT, 6, movetoworkspace, 6
bind = $mod SHIFT, 7, movetoworkspace, 7
bind = $mod SHIFT, 8, movetoworkspace, 8
bind = $mod SHIFT, 9, movetoworkspace, 9
bindm = $mod, mouse:272, movewindow
bindm = $mod, mouse:273, resizewindow
bind = , Print, exec, grim -g "$(slurp)" - | wl-copy
bind = SHIFT, Print, exec, grim - | wl-copy
bind = $mod, C, exec, cliphist list | wofi --dmenu | cliphist decode | wl-copy
binde = , XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
binde = , XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
bind = , XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
binde = , XF86MonBrightnessUp, exec, brightnessctl set +5%
binde = , XF86MonBrightnessDown, exec, brightnessctl set 5%-

# --- Autostart ---
exec-once = waybar
exec-once = dunst
exec-once = hyprpaper
exec-once = wl-paste --type text --watch cliphist store
exec-once = wl-paste --type image --watch cliphist store
exec-once = hypridle
04

Terminal & Multiplexing

Your terminal is the cockpit of the AI workstation. Choose the right emulator, configure it for maximum output density, and set up multiplexing for multi-agent workflows.

Choosing a Terminal Emulator

Three terminals dominate the Wayland AI coding landscape. Each has a distinct philosophy and sweet spot.

Terminal Rendering Multiplexing Config Format Best For
kitty GPU (OpenGL) fastest Built-in splits, tabs, kitty @ IPC Custom (kitty.conf) Power users who want everything in one app
foot CPU (Wayland-native) None (pair with tmux) INI (foot.ini) Minimalists, tmux-centric workflows
alacritty GPU (OpenGL/Vulkan) None (pair with tmux) TOML (alacritty.toml) Cross-platform users, simple setups
Recommendation

kitty is the optimal choice for AI coding on Hyprland. Its built-in multiplexing means you can split panes without tmux for simple layouts, the kitty @ IPC lets you script pane creation from the shell, and its image protocol renders inline graphics from AI tools. For multi-agent orchestration, pair any terminal with tmux.

37.0C

Kitty Configuration for AI Coding

A battle-tested ~/.config/kitty/kitty.conf tuned for long AI output sessions, fast rendering, and Wayland integration.

~/.config/kitty/kitty.conf
# --- Typography ---
font_family      JetBrainsMono Nerd Font
font_size        13.0
bold_font        auto
italic_font      auto

# --- Thermal-Inspired Colors ---
background       #0a0010
foreground       #c4b5fd
selection_background #22143d
selection_foreground #e9e0ff
cursor           #22c55e
cursor_shape     beam

# --- Performance ---
repaint_delay    6
input_delay      1
sync_to_monitor  yes

# --- Scrollback for Long AI Outputs ---
scrollback_lines 50000
scrollback_pager_history_size 100

# --- Window Management ---
enabled_layouts  splits,stack
window_padding_width 8
hide_window_decorations yes

# --- Wayland-Specific ---
wayland_titlebar_color background
linux_display_server wayland

# --- Quick Splits (use instead of tmux for simpler setups) ---
map ctrl+shift+enter new_window_with_cwd
map ctrl+shift+] next_window
map ctrl+shift+[ previous_window
map ctrl+shift+f toggle_layout stack
New split pane Ctrl+Shift+Enter
Next pane Ctrl+Shift+]
Previous pane Ctrl+Shift+[
Toggle fullscreen pane Ctrl+Shift+F

tmux for Multi-Agent Workflows

When running multiple AI agents simultaneously, tmux provides the session persistence and scriptable pane management you need. This config is tuned for Wayland clipboard integration and thermal-colored UI.

~/.tmux.conf
# --- Core Settings ---
set -g default-terminal "tmux-256color"
set -ag terminal-overrides ",*:RGB"
set -g mouse on
set -g history-limit 100000
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on

# --- Fast Escape for Vim/Neovim ---
set -sg escape-time 0

# --- Wayland Clipboard Integration ---
set -g copy-command 'wl-copy'
bind -T copy-mode-vi y send -X copy-pipe-and-cancel 'wl-copy'
bind -T copy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel 'wl-copy'

# --- Paste from Wayland Clipboard ---
bind p run 'wl-paste | tmux load-buffer - && tmux paste-buffer'

# --- Status Bar (Thermal Theme) ---
set -g status-style 'bg=#120822 fg=#7c6faa'
set -g status-left '#[fg=#22c55e,bold][ #S ] '
set -g status-right '#[fg=#6366f1]#(date +"%H:%M") #[fg=#14b8a6]| #H'
set -g status-left-length 30

# --- Pane Borders (Thermal Colors) ---
set -g pane-border-style 'fg=#2d1b69'
set -g pane-active-border-style 'fg=#14b8a6'

# --- AI Coding Layout Shortcut ---
# Ctrl+b then A = create AI coding layout
bind A split-window -h -p 40 \; \
  split-window -v -p 50 \; \
  select-pane -t 0 \; \
  send-keys 'claude' Enter \; \
  select-pane -t 1 \; \
  send-keys 'nvim .' Enter \; \
  select-pane -t 2 \; \
  send-keys 'btop' Enter
Why 100k Scrollback?

AI agents produce massive output -- a single Claude Code session can easily generate thousands of lines of code, diffs, and explanations. Setting history-limit to 100000 ensures you can scroll back through an entire coding session without losing context. The memory cost is negligible on a modern workstation.

-30.0C

Session Layout Patterns

Pre-built tmux session recipes for common AI coding scenarios. Copy these into shell scripts or aliases for instant workspace setup.

Dual Agent Layout

Run Claude Code and Codex side-by-side to compare approaches on the same task.

dual-agents.sh
#!/bin/bash
# Dual Agent Session -- Claude Code (left) + Codex (right)
tmux new-session -d -s agents -n compare
tmux send-keys -t agents:compare 'cd ~/project && claude' Enter
tmux split-window -h -t agents:compare
tmux send-keys -t agents:compare.1 'cd ~/project && codex' Enter
tmux attach -t agents

Monitor Layout

Main pane for the AI agent, bottom panes for git log and system monitoring.

monitor-layout.sh
#!/bin/bash
# Monitor Session -- Agent (top) + Git log (bottom-left) + Watcher (bottom-right)
tmux new-session -d -s monitor -n dev
tmux send-keys -t monitor:dev 'cd ~/project && claude' Enter
tmux split-window -v -p 30 -t monitor:dev
tmux send-keys -t monitor:dev.1 'watch -n2 git log --oneline -20' Enter
tmux split-window -h -t monitor:dev.1
tmux send-keys -t monitor:dev.2 'cd ~/project && npm run test:watch' Enter
tmux select-pane -t monitor:dev.0
tmux attach -t monitor

Full Stack Layout

Four-pane layout covering agent, editor, server, and tests.

fullstack-layout.sh
#!/bin/bash
# Full Stack -- Agent | Editor / Server | Tests
tmux new-session -d -s fullstack -n work
tmux send-keys -t fullstack:work 'cd ~/project && claude' Enter
tmux split-window -h -p 50 -t fullstack:work
tmux send-keys -t fullstack:work.1 'cd ~/project && nvim .' Enter
tmux split-window -v -p 40 -t fullstack:work.0
tmux send-keys -t fullstack:work.2 'cd ~/project && npm run dev' Enter
tmux split-window -v -p 50 -t fullstack:work.1
tmux send-keys -t fullstack:work.3 'cd ~/project && npm test -- --watch' Enter
tmux select-pane -t fullstack:work.0
tmux attach -t fullstack

Scrollback & Output Management

AI agents produce orders of magnitude more terminal output than manual coding. These techniques keep that output accessible and searchable.

Search scrollback
prefix + [ then /

Enter tmux copy mode and search backward through output with regex

Pipe pane to file
tmux pipe-pane -o 'cat >> ~/logs/agent-$(date +%Y%m%d).log'

Record all output from the current pane to a timestamped log file

kitty scrollback pager
ctrl+shift+h

Open scrollback in less or nvim for comfortable searching through long output

Clear & reset
tmux clear-history

Flush scrollback buffer when it gets too large and slows down search

Log Everything

When running autonomous agents, always pipe output to a log file. If an agent makes a wrong turn at 3 AM, you need the full transcript to understand what happened. Use tmux pipe-pane or script -a ~/logs/session.log as a safety net.

68.5C
05

Claude Code Optimization

Claude Code is the heart of this workstation. These configuration patterns and workflows will dramatically improve your output quality, speed, and autonomy.

CLAUDE.md — Your Project Brain

CLAUDE.md is a special Markdown file that Claude Code reads at the start of every session. It gives the agent persistent context about your project -- architecture, conventions, build commands, and domain knowledge that would otherwise be lost between conversations.

Location Scope Use Case
./CLAUDE.md Project-level (committed to git) Shared conventions, build commands, architecture overview
~/.claude/CLAUDE.md User-level (all projects) Personal preferences, global tool configs, coding style
./src/CLAUDE.md Directory-level (monorepo sections) Subsystem-specific patterns, local conventions

Example CLAUDE.md Skeleton

CLAUDE.md
# Project Name

## Architecture
- Frontend: React + TypeScript in /src/client
- Backend: Express API in /src/server
- Database: PostgreSQL via Prisma ORM

## Build & Test
- Build: `npm run build`
- Test: `npm test` (Jest, run from root)
- Lint: `npm run lint` (ESLint + Prettier)
- Dev server: `npm run dev` (port 3000)

## Conventions
- Use named exports, not default exports
- All API routes return { data, error } shape
- Use Zod for runtime validation
- Database migrations in /prisma/migrations

## Common Patterns
- Error handling: wrap async handlers with catchAsync()
- Auth: JWT in httpOnly cookies, middleware in /src/server/auth
- Tests: colocate test files as *.test.ts next to source
Pro Tip

Run /init inside Claude Code to auto-generate a starter CLAUDE.md from your project structure. Then refine it manually -- the more specific your context, the fewer mistakes the agent makes.

36.6C

Context Management

Claude Code has a finite context window. Every file, every conversation turn, every tool output consumes tokens. Managing context is the single most impactful skill for productive AI coding.

Compact conversation
/compact

Compress the conversation history when context gets large, preserving key decisions and losing verbose output

Add file context
# filename.ts

Reference a file in your prompt to pull it into context without reading it manually

Add URL context
# https://docs.example.com/api

Pull documentation or web content directly into context for reference

Clear and restart
/clear

Reset the conversation entirely when context is polluted or you are changing tasks

Excluding Irrelevant Files

Create a .claudeignore file (same syntax as .gitignore) to prevent large or irrelevant files from being pulled into context.

.claudeignore
# Dependencies
node_modules/
vendor/
.venv/

# Build artifacts
dist/
build/
*.min.js
*.min.css

# Large data files
*.sql
*.csv
*.sqlite

# Media
*.mp4
*.png
*.jpg

Permission Modes & Allowlists

Claude Code asks permission before running commands or modifying files. For trusted workflows, allowlists let you pre-approve specific tools so the agent can work autonomously.

Mode Flag Behavior
Default (none) Ask permission for every tool use -- safest, most interactive
Allowlist --allowedTools Pre-approve specific tools, ask for the rest -- best balance
Full Auto --dangerously-skip-permissions Skip all permission checks -- use only in disposable sandboxes

Recommended Allowlists

Safe automation (read/write, git, tests)
claude --allowedTools "Read,Write,Edit,Glob,Grep,Bash(git *),Bash(npm test),Bash(npm run *)"
Full dev workflow
claude --allowedTools "Read,Write,Edit,Glob,Grep,Bash(git *),Bash(npm *),Bash(cargo *),Bash(python *),Agent"
Never Use Full Auto on Your Main System

--dangerously-skip-permissions means Claude can run any shell command without asking. Only use this inside Docker containers, disposable VMs, or CI pipelines where the worst case is a rebuild. On your workstation, use allowlists instead.

240.0C

Hooks System

Hooks let you run custom commands before or after Claude Code uses a tool. Use them for auto-formatting, linting, notifications, and custom integrations.

Desktop Notification on Task Completion

Get a dunst notification when a long-running agent task finishes.

~/.claude/settings.json (hooks section)
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Stop",
        "command": "notify-send 'Claude Code' 'Agent finished working' --icon=terminal --urgency=normal"
      }
    ]
  }
}

Auto-Format on File Write

Format TypeScript files after every write
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "command": "prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
      }
    ]
  }
}
Hook Execution

Hooks run synchronously -- they block Claude from proceeding until the command finishes. Keep hook commands fast (under 2 seconds). For slow operations like full test suites, trigger them asynchronously with & at the end of the command.

-15.0C

MCP Servers

The Model Context Protocol (MCP) extends Claude Code with external tool servers. MCP servers give the agent access to databases, APIs, file systems, and custom tools beyond its built-in capabilities.

Configuration

~/.claude/settings.json (mcpServers section)
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here"
      }
    },
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "postgresql://user:pass@localhost:5432/mydb"
      }
    },
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/docs"]
    }
  }
}
GitHub MCP
@modelcontextprotocol/server-github

Create PRs, read issues, search repos, manage branches directly from Claude

PostgreSQL MCP
@modelcontextprotocol/server-postgres

Query databases, inspect schemas, run migrations with natural language

Filesystem MCP
@modelcontextprotocol/server-filesystem

Give Claude access to directories outside the project root (docs, configs)

Model Selection Strategy

Claude Code supports multiple models with different cost/capability tradeoffs. Switch models mid-conversation with /model to match the complexity of each sub-task.

Model Thermal Rating Best For Context
Opus searing Complex architecture, large refactors, multi-file changes, subtle bugs 200K tokens
Sonnet warm Routine coding, quick edits, test writing, documentation 200K tokens
Haiku cool Simple lookups, explanations, formatting, boilerplate generation 200K tokens
Switch model mid-conversation /model
Check current model /config
Cost Strategy

Start complex tasks with Opus for the architecture and design phase, then switch to Sonnet for implementation. Use /compact before switching models to avoid wasting the expensive model's tokens on stale context. This hybrid approach can cut API costs by 50%+ while maintaining quality where it matters.

72.0C
06

Codex & Multi-Agent Workflows

Run multiple AI agents in parallel on the same codebase. Git worktrees isolate each agent's changes, tmux manages the sessions, and disciplined branching keeps everything mergeable.

Codex CLI Setup

OpenAI's Codex CLI is a terminal-native coding agent. It complements Claude Code by offering a different model family and a sandbox-first approach to file modifications.

Install and configure
# Install globally via npm
npm install -g @openai/codex

# Verify installation
codex --version

# Set your API key (add to ~/.zshrc)
export OPENAI_API_KEY="sk-your-key-here"
Mode Flag Behavior
Suggest (default) Shows proposed changes, asks for approval before applying
Auto-Edit --auto-edit Applies file edits automatically, asks before shell commands
Full Auto --full-auto Runs everything in a sandbox without asking -- network disabled
Model selection
# Use GPT-4.1 for complex tasks
codex --model gpt-4.1 "refactor the auth module to use JWT"

# Use o4-mini for quick edits (faster, cheaper)
codex --model o4-mini "add error handling to the API routes"
Project instructions
# Codex reads these files for project context (similar to CLAUDE.md)
# Create one of these in your project root:
~/.codex/instructions.md      # Global instructions
./codex.md                     # Project-level instructions
./.codex/instructions.md       # Project-level (alternative)

Running Agents in Parallel

The key insight: each agent needs its own working directory to avoid file conflicts. If two agents edit the same file simultaneously, you get corruption. Git worktrees solve this elegantly.

Create isolated worktrees for each agent
# From your main project directory
cd ~/project

# Create worktrees for parallel agents
git worktree add ../project-claude -b feature/claude-refactor
git worktree add ../project-codex -b feature/codex-tests

# Launch agents in separate tmux panes
tmux new-session -d -s parallel -n agents
tmux send-keys -t parallel:agents 'cd ~/project-claude && claude' Enter
tmux split-window -h -t parallel:agents
tmux send-keys -t parallel:agents.1 'cd ~/project-codex && codex --full-auto' Enter
tmux attach -t parallel
Never Share a Working Directory

Two agents in the same directory will overwrite each other's changes. Always use separate worktrees or separate clones. This is the number one mistake in multi-agent setups -- it looks like it works until you lose an hour of agent output to a silent conflict.

210.0C

Git Worktree Mastery

Git worktrees let you check out multiple branches simultaneously in different directories, all sharing the same .git history. This is the foundation of parallel agent workflows.

Create worktree
git worktree add <path> -b <branch>

Create a new worktree at the given path with a new branch

List worktrees
git worktree list

Show all worktrees with their paths, branches, and HEAD commits

Remove worktree
git worktree remove <path>

Clean up a worktree after merging the agent's branch

Prune stale
git worktree prune

Remove worktree references for directories that no longer exist

Complete Workflow

worktree-workflow.sh
#!/bin/bash
# 1. Create worktrees for two parallel features
git worktree add ../project-auth -b feature/auth-refactor
git worktree add ../project-tests -b feature/test-coverage

# 2. Run agents (in separate tmux panes or terminals)
# Pane 1:
cd ../project-auth && claude "refactor auth to use JWT with refresh tokens"
# Pane 2:
cd ../project-tests && codex --full-auto "add unit tests for all API routes, aim for 80% coverage"

# 3. When agents finish, review and merge
cd ~/project
git merge feature/auth-refactor
git merge feature/test-coverage

# 4. Clean up worktrees
git worktree remove ../project-auth
git worktree remove ../project-tests
git branch -d feature/auth-refactor feature/test-coverage
Branch Lock Rule

Git prevents the same branch from being checked out in multiple worktrees simultaneously. This is a feature, not a bug -- it prevents the exact kind of conflicts that would corrupt your work. Each agent gets its own branch, always.

65.0C

Task Orchestration Patterns

Strategic patterns for dividing work across agents. The right pattern depends on task decomposability and how much the subtasks overlap in files.

Pattern Agents When to Use Merge Risk
Divide & Conquer 2-4 agents on independent modules Features touch different files/directories low
Review Chain Agent 1 writes → Agent 2 reviews High-stakes code that needs a second opinion low
Research + Implement Sonnet researches → Opus implements Unfamiliar domains where you need to explore first low
Parallel Features Each agent on a separate feature branch Sprint-style work with multiple independent stories medium
Competitive 2 agents solve the same problem differently Architecture decisions where you want to compare approaches none (pick one)
Built-in Subagents

Claude Code's Agent tool spawns subagents within a single session for parallel work. Use it for tasks like "search the codebase for all uses of X while I continue editing Y." Add Agent to your allowlist to enable it: --allowedTools "...,Agent".

-25.0C

Resolving Merge Conflicts from Parallel Agents

When two agents touch overlapping files, merge conflicts are inevitable. The key is minimizing their frequency and having a clean resolution strategy.

Prevention

  • Separate by module: Assign agents to different directories or files. Frontend agent vs. backend agent, not two agents on the same component.
  • Shared interfaces first: Define interfaces/types in a shared file before agents start. Both agents code to the interface, not to each other's implementation.
  • Lock files: For critical shared files (e.g., database schema), only let one agent modify them.

Resolution

Use Claude itself to resolve conflicts
# After a failed merge, let Claude resolve it
git merge feature/agent-2
# CONFLICT in src/api/routes.ts

# Open Claude in the conflicted repo
claude "resolve the merge conflicts in all files. Read both versions \
carefully and combine the best from each approach. Run tests after resolving."
Manual resolution workflow
# See all conflicted files
git diff --name-only --diff-filter=U

# For each file, review both sides
git diff --merge HEAD...feature/agent-2 -- src/api/routes.ts

# After resolving
git add -A
git commit -m "merge: combine auth refactor and test improvements"

Claude Code vs Codex CLI

A side-by-side comparison to help you decide which agent to deploy for each task.

Feature Claude Code Codex CLI
Provider Anthropic OpenAI
Models Opus, Sonnet, Haiku GPT-4.1, o4-mini, o3
Install npm i -g @anthropic-ai/claude-code npm i -g @openai/codex
Project Context CLAUDE.md codex.md or instructions.md
Sandbox Permission allowlists Full sandbox (network disabled in full-auto)
Tool Use Read, Write, Edit, Bash, Glob, Grep, Agent, MCP Shell commands, file I/O (sandboxed)
MCP Support Yes (extensible via MCP servers) No
Subagents Yes (Agent tool) No
Mid-Session Model Switch Yes (/model) No (set at launch)
Hooks Yes (pre/post tool use) No
Best Strength Complex multi-file refactors, architecture Fast sandboxed edits, autonomous batch jobs
Use Both

These tools are complementary, not competing. Use Claude Code as your primary agent for architecture, complex reasoning, and interactive development. Deploy Codex for batch tasks, quick autonomous fixes, and as a second opinion. The dual-agent tmux layout from Section 04 makes this workflow seamless.

37.0C
07

Workspace Strategies

Organize your Hyprland workspaces into dedicated zones for coding, browsing, communication, and monitoring. A disciplined workspace model eliminates context-switching friction and keeps your agents front and center.

The Six-Workspace Model

Dedicate each Hyprland workspace to a single concern. This keeps your primary coding environment distraction-free while giving every tool a predictable home.

Workspace Name Purpose
SUPER+1 code Primary editor / agent workspace — this is where Claude Code lives
SUPER+2 agent Second agent or Codex CLI on a worktree
SUPER+3 web Firefox / Chromium for docs, PRs, API references
SUPER+4 comm Slack, Discord, email
SUPER+5 mon btop, nvtop, journalctl, waybar dashboard
SUPER+6 scratch Throwaway terminals, quick tests, file managers
~/.config/hypr/hyprland.conf — workspace rules
# Workspace assignments
windowrulev2 = workspace 3 silent, class:^(firefox)$
windowrulev2 = workspace 3 silent, class:^(chromium)$
windowrulev2 = workspace 4 silent, class:^(Slack)$
windowrulev2 = workspace 4 silent, class:^(discord)$

# Workspace names (for waybar)
workspace = 1, name:code
workspace = 2, name:agent
workspace = 3, name:web
workspace = 4, name:comm
workspace = 5, name:mon
workspace = 6, name:scratch

Waybar Configuration

Waybar is the de-facto status bar for Hyprland. Configure it to show workspace names, system metrics, and thermal readings at a glance.

~/.config/waybar/config.jsonc
{
    "layer": "top",
    "position": "top",
    "height": 32,
    "modules-left": ["hyprland/workspaces", "hyprland/window"],
    "modules-center": ["clock"],
    "modules-right": ["cpu", "memory", "temperature", "network", "pulseaudio", "tray"],
    "hyprland/workspaces": {
        "format": "{icon}",
        "format-icons": {
            "1": "code",
            "2": "agent",
            "3": "web",
            "4": "comm",
            "5": "mon",
            "6": "misc"
        }
    },
    "cpu": { "format": "CPU {usage}%" },
    "memory": { "format": "RAM {percentage}%" },
    "temperature": { "format": "{temperatureC}°C" }
}
~/.config/waybar/style.css — thermal palette
/* Waybar styling matched to thermal design system */
* {
    font-family: 'JetBrainsMono Nerd Font', monospace;
    font-size: 13px;
}
window#waybar {
    background: #0a0010;
    border-bottom: 2px solid #2d1b69;
}
#workspaces button {
    color: #7c6faa;
    padding: 0 8px;
}
#workspaces button.active {
    color: #22c55e;
    border-bottom: 2px solid #14b8a6;
}
#cpu, #memory { color: #14b8a6; }
#temperature { color: #f59e0b; }
#temperature.critical { color: #ef4444; }

Notification Daemon

You have two good choices: dunst (lightweight, config-file driven) or swaync (richer notification center with a slide-out panel and Do Not Disturb). Both work well for agent completion alerts.

# Option A: dunst (lightweight, simple)
sudo pacman -S --needed dunst

# Option B: swaync (notification center with panel)
sudo pacman -S --needed swaync
# Bind notification center toggle in hyprland.conf:
# bind = SUPER, N, exec, swaync-client -t -sw
~/.config/dunst/dunstrc
[global]
    monitor = 0
    follow = keyboard
    width = 350
    offset = 20x20
    origin = top-right
    font = Rajdhani 12
    frame_color = "#14b8a6"
    separator_color = frame
    background = "#120822"
    foreground = "#c4b5fd"

[urgency_low]
    background = "#120822"
    foreground = "#7c6faa"
    frame_color = "#2d1b69"

[urgency_normal]
    background = "#120822"
    foreground = "#c4b5fd"
    frame_color = "#14b8a6"

[urgency_critical]
    background = "#120822"
    foreground = "#ef4444"
    frame_color = "#ef4444"
Agent Completion Alerts

Pair dunst with a simple wrapper script: when Claude Code exits, fire notify-send "Claude Code" "Task complete on $(pwd)". This way you can context-switch to workspace 4 (comms) without losing track of agent progress.

36.6C

Quick Workspace Switching Patterns

Go beyond basic SUPER+N workspace switching with scratchpads and quick-toggle binds.

~/.config/hypr/hyprland.conf — scratchpad & switching
# Special workspace (scratchpad) for quick terminal
bind = SUPER, grave, togglespecialworkspace, scratchpad
bind = SUPER SHIFT, grave, movetoworkspace, special:scratchpad

# Move focused window to another workspace
bind = SUPER SHIFT, 1, movetoworkspace, 1
bind = SUPER SHIFT, 2, movetoworkspace, 2
bind = SUPER SHIFT, 3, movetoworkspace, 3

# Named special workspaces for persistent tools
bind = SUPER, F1, togglespecialworkspace, btop
bind = SUPER, F2, togglespecialworkspace, notes

# Workspace overview (requires hyprland plugins or hyprexpo)
bind = SUPER, Tab, hyprexpo:expo, toggle
Toggle scratchpad terminal SUPER + `
Move window to scratchpad SUPER + SHIFT + `
Toggle btop overlay SUPER + F1
Workspace overview SUPER + Tab
08

Clipboard & Wayland Integration

Wayland replaces X11's clipboard model entirely. Master wl-clipboard, cliphist, and screenshot tooling to keep data flowing smoothly between your agents, browser, and terminal.

wl-clipboard Essentials

wl-copy and wl-paste are the core Wayland clipboard tools. They replace xclip and xsel from the X11 era.

Copy file to clipboard
cat file.txt | wl-copy

Pipe file contents to clipboard

Paste to file
wl-paste > output.txt

Paste clipboard to file

Copy command output
ls -la | wl-copy

Copy command output

Copy file directly
wl-copy < ~/.ssh/id_ed25519.pub

Copy file contents directly

Primary selection copy
wl-copy --primary

Copy to primary selection (middle-click)

Primary selection paste
wl-paste --primary

Paste from primary selection

Clipboard History with cliphist

cliphist watches your clipboard and stores a searchable history. Paired with wofi, it gives you a visual clipboard manager accessible via a single keybind.

~/.config/hypr/hyprland.conf — cliphist setup
# Start clipboard watcher on login
exec-once = wl-paste --watch cliphist store

# Bind clipboard history to SUPER+C
bind = SUPER, C, exec, cliphist list | wofi --dmenu | cliphist decode | wl-copy
List history
cliphist list

Show all clipboard history entries

Wipe history
cliphist wipe

Clear entire clipboard history

Recent entries
cliphist list | head -5

Show 5 most recent entries

Image Support

cliphist supports images in addition to text. Screenshots copied via grim are stored in history and can be re-pasted later. The default max history is 750 entries — adjust with cliphist store --max-items 1500 if you need more.

-20.0C

Screenshot Workflows

grim captures screenshots and slurp provides interactive region selection. Together they replace the full-featured screenshot tools from desktop environments.

Screenshot commands
# Full screen → clipboard
grim - | wl-copy

# Region select → clipboard
grim -g "$(slurp)" - | wl-copy

# Region select → file
grim -g "$(slurp)" ~/screenshots/$(date +%Y%m%d-%H%M%S).png

# Active window only
grim -g "$(hyprctl activewindow -j | jq -r '"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"')" - | wl-copy
~/.config/hypr/hyprland.conf — screenshot keybinds
bind = , Print, exec, grim - | wl-copy
bind = SHIFT, Print, exec, grim -g "$(slurp)" - | wl-copy
bind = SUPER, Print, exec, grim -g "$(slurp)" ~/screenshots/$(date +%Y%m%d-%H%M%S).png
Full screen to clipboard Print
Region select to clipboard SHIFT + Print
Region select to file SUPER + Print

Screen Recording with wf-recorder

wf-recorder captures Wayland screen output to video files. Essential for recording agent sessions, creating demos, and debugging visual issues.

Record full screen
wf-recorder -f recording.mp4

Record full screen

Record region
wf-recorder -g "$(slurp)" -f recording.mp4

Record a selected region

Record with audio
wf-recorder --audio -f recording.mp4

Record with audio capture

Stop recording
pkill -INT wf-recorder

Stop recording gracefully

AI Agent ↔ Clipboard Workflows

Practical patterns for moving data between agents, browsers, and terminals using the Wayland clipboard as glue.

Clipboard to Claude
wl-paste | claude -p "explain this code"

Pipe clipboard contents into Claude for quick analysis

Round-trip pipeline
wl-paste | claude -p "fix this error" | wl-copy

Round-trip: clipboard → agent → clipboard

Dump to file
wl-paste > /tmp/debug.txt

Dump clipboard to file for agent context

Browser Error Pipeline

Copy an error from your browser console, switch to workspace 1, and run wl-paste | claude -p "explain this error and suggest a fix". The Wayland clipboard persists across workspaces, making cross-app data flow seamless without touching a mouse.

36.6C
09

Performance Tuning

AI agents are resource-intensive processes. Tune memory, CPU scheduling, GPU compositing, and storage I/O to keep your workstation responsive even when multiple agents are hammering the API and processing large codebases.

Memory Management

AI agents are memory-hungry — each Claude Code session runs Node.js processes that can consume 1-4 GB of RAM. Running two agents with a browser and monitoring tools easily exceeds 16 GB.

/etc/systemd/zram-generator.conf
# Install zram for compressed swap
sudo pacman -S zram-generator

# Configure compressed swap
[zram0]
zram-size = ram / 2
compression-algorithm = zstd
swap-priority = 100

zram compresses swap in RAM using zstd, which is dramatically faster than paging to disk. For AI workloads that allocate and release large buffers frequently, zram keeps the system responsive without SSD wear.

Swappiness tuning
# Keep agent processes in RAM -- prefer compressing over swapping
sudo sysctl vm.swappiness=10

# Make persistent
echo "vm.swappiness=10" | sudo tee /etc/sysctl.d/99-swappiness.conf
Never Run AI Agents Without Swap

A system with no swap and 16 GB RAM will hit the OOM killer when running two agents, a browser with 20 tabs, and btop simultaneously. The kernel will kill your agent mid-task with no warning. Always configure at least zram — it costs nothing and prevents catastrophic process termination.

240.0C

GPU Monitoring & Acceleration

Hyprland uses the GPU for compositing. Monitor GPU utilization to ensure smooth rendering alongside any local model inference.

GPU monitor (all vendors)
nvtop

Interactive GPU monitor (NVIDIA, AMD, Intel)

Intel GPU monitor
intel_gpu_top

Intel integrated graphics monitor

AMD GPU monitor
radeontop

AMD GPU utilization monitor

List monitors
hyprctl monitors -j | jq '.[].name'

List connected monitors

Multi-GPU configuration
# Check GPU usage
nvtop

# Hyprland GPU info
hyprctl monitors -j | jq '.[].name'

# Force specific GPU (multi-GPU setups)
env WLR_DRM_DEVICES=/dev/dri/card1 hyprland

Process Priority & CPU Scheduling

Give AI agents priority CPU access so they respond instantly to API results, and pin them to specific cores to avoid contention with the compositor.

Priority and affinity commands
# Run Claude Code with higher priority
nice -n -5 claude

# Real-time scheduling for responsive UI
sudo renice -n -10 -p $(pgrep hyprland)

# CPU affinity -- pin agents to specific cores
taskset -c 0-3 claude
taskset -c 4-7 codex
Root Required for Negative Nice

Setting negative nice values (higher priority) requires root or CAP_SYS_NICE. For a persistent setup, add your_user hard nice -10 to /etc/security/limits.conf so you can prioritize agents without sudo. Be careful not to starve system processes.

72.0C

systemd Resource Limits

Use systemd cgroups v2 to set hard resource limits on agent processes, preventing any single runaway agent from consuming all system resources.

~/.config/systemd/user/claude-agent.service
[Service]
MemoryMax=8G
CPUQuota=400%
IOWeight=200
One-off resource-limited execution
# Run Claude with a 4 GB memory ceiling
systemd-run --user --scope -p MemoryMax=4G claude

# Run Codex with CPU and memory limits
systemd-run --user --scope -p MemoryMax=4G -p CPUQuota=200% codex
Property Example Effect
MemoryMax 8G Hard memory limit — OOM kills the process if exceeded
CPUQuota 400% Max 4 CPU cores worth of time (percentage of one core)
IOWeight 200 I/O priority relative to default (100). Higher = more bandwidth
MemoryHigh 6G Soft limit — throttles I/O before hitting MemoryMax

Network Optimization

Both Claude Code and Codex are API-heavy — every keystroke can trigger network requests. Optimize DNS resolution, connection reuse, and bandwidth monitoring to minimize latency.

DNS caching with systemd-resolved
# Enable and start systemd-resolved
sudo systemctl enable --now systemd-resolved

# Verify DNS caching is active
resolvectl statistics
Bandwidth monitoring
# Monitor network per-process
sudo bandwhich

# Check API latency
curl -w "%{time_total}s\n" -o /dev/null -s https://api.anthropic.com/v1/messages
curl -w "%{time_total}s\n" -o /dev/null -s https://api.openai.com/v1/chat/completions
Bandwidth monitor
bandwhich

Per-process bandwidth monitor with TUI

Network usage
nethogs

Lightweight per-process network usage

DNS statistics
resolvectl statistics

DNS cache hit rate and stats

Storage Performance

Git operations on large repos, agent file I/O, and build artifacts all benefit from fast storage. An NVMe SSD is essential — spinning disks will bottleneck every agent interaction.

tmpfs for fast builds
# Mount tmpfs for fast builds
sudo mount -t tmpfs -o size=4G tmpfs /tmp/build

# Or add to /etc/fstab for persistence
tmpfs /tmp/build tmpfs size=4G,mode=1777 0 0
/etc/fstab — noatime optimization
# Add noatime to your root partition to reduce write overhead
# Before:
UUID=xxxx / ext4 defaults 0 1

# After:
UUID=xxxx / ext4 defaults,noatime 0 1
Optimization Impact Risk
noatime mount option Eliminates access-time writes on every file read None
tmpfs for /tmp/build RAM-speed builds, zero SSD wear Data lost on reboot
NVMe over SATA SSD 3-7x sequential, 10x random I/O improvement None
btrfs compression Smaller on-disk size, slight CPU overhead Marginal CPU cost
SSD Health Monitoring

AI workloads generate significant disk I/O — constant git operations, file writes, and log output. Monitor your NVMe health with sudo smartctl -a /dev/nvme0n1 and check the Percentage Used field monthly. Most NVMe drives handle 600 TBW+ but heavy agent use can accelerate wear.

68.0C
10

Dotfiles & Reproducibility

Your workstation is only as good as your ability to recreate it. Dotfile management turns a fragile snowflake into a reproducible, version-controlled machine definition.

Dotfile Management Approaches

Three dominant strategies exist for tracking and syncing your configuration files. Each trades off simplicity against power.

Approach Pros Cons Best For
chezmoi Templates, secrets management, multi-machine support Learning curve, Go dependency Multi-device power users
GNU Stow Simple symlinks, no dependencies, composable No templating, manual sync Single-machine, Unix purists
Bare Git Repo No extra tools, pure git Awkward commands, easy to make mistakes Minimalists

chezmoi Setup (Recommended)

chezmoi is the most capable dotfile manager — it supports templates for machine-specific values, encrypted secrets, and one-command apply across multiple machines.

Install & initialize
# Install chezmoi
sudo pacman -S chezmoi

# Initialize (creates ~/.local/share/chezmoi/)
chezmoi init
Add config files to chezmoi
# Add your Hyprland workstation configs
chezmoi add ~/.config/hypr/hyprland.conf
chezmoi add ~/.config/kitty/kitty.conf
chezmoi add ~/.config/waybar/config.jsonc
chezmoi add ~/.config/waybar/style.css
chezmoi add ~/.config/dunst/dunstrc
chezmoi add ~/.tmux.conf
chezmoi add ~/.claude/settings.json
Edit, apply, and push
# Edit a managed file (opens in $EDITOR)
chezmoi edit ~/.config/hypr/hyprland.conf

# Apply changes to home directory
chezmoi apply

# Push to your dotfiles repo
chezmoi cd && git add -A && git commit -m "update configs" && git push
~/.local/share/chezmoi/.chezmoidata.yaml — template variables
# Machine-specific values used in templates
monitor_primary: "DP-1"
monitor_scale: "1.5"
gpu_driver: "nvidia"

In your Hyprland config template, reference these with {{ .monitor_primary }} and chezmoi will substitute the correct value per machine.

GNU Stow Alternative

If you prefer zero-magic simplicity, GNU Stow manages dotfiles via symlinks. Each package is a directory tree that mirrors your home directory structure.

Directory structure
# Create package directories mirroring home structure
mkdir -p ~/dotfiles/{hypr,kitty,waybar,tmux,claude}/.config
Symlink management
# Stow each package (creates symlinks into ~)
cd ~/dotfiles
stow hypr    # Creates ~/.config/hypr → ~/dotfiles/hypr/.config/hypr
stow kitty
stow waybar
stow tmux
stow claude

# Remove symlinks for a package
stow -D kitty

# Re-stow (remove + re-create, useful after restructuring)
stow -R kitty

Bootstrap Script

A single script that takes a bare Arch install to a fully configured Hyprland AI workstation. Run it once on a fresh machine, or use it as a reference for what to install.

bootstrap.sh — Hyprland AI Workstation Setup
#!/usr/bin/env bash
# bootstrap.sh — Hyprland AI Workstation Setup
set -euo pipefail

echo "[*] Installing core packages..."
sudo pacman -S --needed --noconfirm \
    hyprland hyprpaper hyprlock hypridle \
    waybar wofi dunst \
    xdg-desktop-portal-hyprland \
    kitty tmux \
    git base-devel \
    nodejs npm python python-pip \
    btop wl-clipboard cliphist grim slurp \
    ttf-jetbrains-mono-nerd noto-fonts \
    zram-generator brightnessctl

echo "[*] Installing paru (AUR helper)..."
if ! command -v paru &>/dev/null; then
    git clone https://aur.archlinux.org/paru-bin.git /tmp/paru
    cd /tmp/paru && makepkg -si --noconfirm
fi

echo "[*] Installing AUR packages..."
paru -S --needed --noconfirm \
    nvtop wf-recorder bandwhich

echo "[*] Installing AI tools..."
npm install -g @anthropic-ai/claude-code
npm install -g @openai/codex

echo "[*] Applying dotfiles..."
chezmoi init --apply https://github.com/YOUR_USER/dotfiles.git

echo "[*] Enabling services..."
sudo systemctl enable --now systemd-resolved
systemctl --user enable --now pipewire pipewire-pulse wireplumber

echo "[*] Setup complete! Reboot and launch Hyprland."

Essential Dotfile Checklist

Every config file covered in this guide, mapped to its purpose and the section where it was introduced. Track all of these in your dotfile repo.

File Purpose Section
~/.config/hypr/hyprland.conf Window manager config §03
~/.config/kitty/kitty.conf Terminal emulator §04
~/.tmux.conf Terminal multiplexer §04
~/.config/waybar/config.jsonc Status bar §07
~/.config/waybar/style.css Status bar styling §07
~/.config/dunst/dunstrc Notifications §07
~/.claude/settings.json Claude Code settings §05
~/.claude/CLAUDE.md Global Claude context §05
project/CLAUDE.md Project Claude context §05
.claudeignore Claude file exclusions §05
/etc/systemd/zram-generator.conf Swap config §09

Remote Bootstrap with Tailscale

The fastest path from bare Arch install to full AI workstation: enable SSH immediately, then let Claude Code on another device do the heavy lifting over the network.

# Phase 1: On the fresh Arch box (TTY only)
sudo pacman -S --needed openssh tailscale
sudo systemctl enable --now sshd
sudo systemctl enable --now tailscaled
sudo tailscale up

# Phase 2: From your other device (laptop, phone, etc.)
ssh builder@arch-box    # or use Tailscale IP/hostname

# Phase 3: Clone dotfiles and bootstrap
git clone https://github.com/YOUR_USER/dotfiles.git ~/dotfiles
cd ~/dotfiles && ./bootstrap.sh

# Phase 4: Build any custom components
cargo build --release    # if you have Rust desktop tools

# Phase 5: Reboot into Hyprland
sudo reboot
Phone as Bootstrap Device

You can bootstrap an entire Hyprland desktop from your phone using Termux or PocketForge over Tailscale + SSH. Install Arch to a TTY, enable SSH + Tailscale, then run Claude Code from your phone to install packages, write configs, and build everything remotely. The phone becomes a remote control for AI-driven system building.

36.8C
Why Tailscale?

Tailscale creates a WireGuard mesh network between your devices with zero configuration. No port forwarding, no dynamic DNS, no firewall rules. Your phone and desktop are always one hop away on any network. Install it on every device in your toolkit.

-20.0C

Version Control Strategy

Dotfiles without version control are just text files waiting to be lost. Treat your configs with the same discipline as production code.

# Keep dotfiles in a dedicated repo
chezmoi cd
git init
git remote add origin git@github.com:YOUR_USER/dotfiles.git

# Use branches for different machines
git checkout -b laptop
git checkout -b desktop
git checkout -b server

# Tag stable configs before major changes
git tag -a v1.0-hyprland "stable hyprland + claude setup"
git tag -a v1.1-waybar "waybar GPU module added"

# Include a README documenting each config's purpose
# Sensitive data: use chezmoi's encryption with age/gpg
chezmoi age encrypt ~/.config/secrets/api-keys.env
Test Before You Deploy

Always test config changes in a VM or container before applying to your production machine. A broken Hyprland config can leave you at a TTY with no graphical environment. Keep a known-good config tagged in git so you can roll back quickly.

36.5C
Never Commit API Keys

Your ANTHROPIC_API_KEY, OPENAI_API_KEY, and any other secrets must never appear in your dotfiles repo. Use chezmoi’s built-in encryption (age or gpg), environment variables loaded from an untracked .env file, or a dedicated secrets manager like pass or 1password-cli. A single leaked key can result in thousands of dollars of unauthorized API usage within hours.

92.0C