From 0b1d0584173e11753811468508633d9d6d4c1050 Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Fri, 24 Apr 2026 15:08:19 -0700 Subject: [PATCH] Add zellij alongside tmux --- dotfiles/agents/AGENTS.md | 13 +++++++----- dotfiles/agents/hooks/tmux-title.sh | 32 +++++++++++++++++++++-------- dotfiles/cider/bootstrap.json | 1 + dotfiles/config/taffybar/AGENTS.md | 11 +++++----- nix-darwin/home/common.nix | 1 + nixos/environment.nix | 1 + nixos/essential.nix | 1 + 7 files changed, 41 insertions(+), 19 deletions(-) diff --git a/dotfiles/agents/AGENTS.md b/dotfiles/agents/AGENTS.md index e83788c6..680fe1ca 100644 --- a/dotfiles/agents/AGENTS.md +++ b/dotfiles/agents/AGENTS.md @@ -1,8 +1,9 @@ # Agentic Session Preferences -## Tmux session titling -- Treat this chat as the controller for the current tmux session. -- Run the tmux rename one-liner eagerly without checking whether TMUX is set first. +## Multiplexer session titling +- Treat this chat as the controller for the current tmux or zellij session. +- If the current session is in tmux, run the tmux rename one-liner eagerly without checking whether TMUX is set first. +- If the current session is in zellij, run the zellij rename commands eagerly without checking whether ZELLIJ is set first. - Maintain a session/window/pane title that updates when the task focus changes substantially. - Prefer automatic titling: infer a concise from the current user request and context without asking. - Title format: " - ". @@ -11,11 +12,13 @@ - is a short, user-friendly description of what we are doing. - Ask for a short descriptive only when the task is ambiguous or you are not confident in an inferred title. - When the task changes substantially, update the automatically if clear; otherwise ask for an updated . -- When a title is provided or updated, immediately run this one-liner: +- When a title is provided or updated, immediately run the matching command for the active multiplexer: tmux rename-session ' - ' \; rename-window ' - ' \; select-pane -T ' - ' -- Assume you are inside tmux, so do not use -t unless the user asks to target a specific session. + zellij action rename-session ' - ' && zellij action rename-tab ' - ' && zellij action rename-pane ' - ' + +- Assume you are inside the active multiplexer, so do not use tmux `-t` or zellij targeting flags unless the user asks to target a specific session/tab/pane. - For Claude Code sessions, a UserPromptSubmit hook will also update titles automatically based on the latest prompt. ## Pane usage diff --git a/dotfiles/agents/hooks/tmux-title.sh b/dotfiles/agents/hooks/tmux-title.sh index 707b0e17..3c7c5147 100755 --- a/dotfiles/agents/hooks/tmux-title.sh +++ b/dotfiles/agents/hooks/tmux-title.sh @@ -1,25 +1,33 @@ #!/usr/bin/env bash set -euo pipefail -if [[ -z "${TMUX:-}" ]]; then +if [[ -n "${ZELLIJ:-}" ]]; then + multiplexer="zellij" +elif [[ -n "${TMUX:-}" ]]; then + multiplexer="tmux" +else exit 0 fi input=$(cat) -read -r cwd prompt <<'PY' < <(python3 - <<'PY' +mapfile -d '' -t parsed < <(PAYLOAD="$input" python3 - <<'PY' import json, os, sys try: - data = json.load(sys.stdin) + data = json.loads(os.environ.get("PAYLOAD", "")) except Exception: data = {} cwd = data.get("cwd") or os.getcwd() prompt = (data.get("prompt") or "").strip() -print(cwd) -print(prompt) +sys.stdout.write(cwd) +sys.stdout.write("\0") +sys.stdout.write(prompt) +sys.stdout.write("\0") PY ) +cwd="${parsed[0]:-}" +prompt="${parsed[1]:-}" if [[ -z "${cwd}" ]]; then cwd="$PWD" @@ -46,7 +54,7 @@ if [[ -z "$task" ]]; then task="work" fi -# Trim to a reasonable length for tmux status bars. +# Trim to a reasonable length for multiplexer UI labels. if [[ ${#task} -gt 60 ]]; then task="${task:0:57}..." fi @@ -54,7 +62,7 @@ fi title="$project - $task" state_dir="${HOME}/.agents/state" -state_file="$state_dir/tmux-title" +state_file="$state_dir/${multiplexer}-title" mkdir -p "$state_dir" if [[ -f "$state_file" ]]; then @@ -66,5 +74,11 @@ fi printf '%s' "$title" > "$state_file" -# Update session, window, and pane titles. -tmux rename-session "$title" \; rename-window "$title" \; select-pane -T "$title" +# Update session, window/tab, and pane titles. +if [[ "$multiplexer" == "tmux" ]]; then + tmux rename-session "$title" \; rename-window "$title" \; select-pane -T "$title" +else + zellij action rename-session "$title" + zellij action rename-tab "$title" + zellij action rename-pane "$title" +fi diff --git a/dotfiles/cider/bootstrap.json b/dotfiles/cider/bootstrap.json index 26998e71..029d39d8 100644 --- a/dotfiles/cider/bootstrap.json +++ b/dotfiles/cider/bootstrap.json @@ -170,6 +170,7 @@ "tig", "tmate", "tmux", + "zellij", "unoconv", "vim", "w3m", diff --git a/dotfiles/config/taffybar/AGENTS.md b/dotfiles/config/taffybar/AGENTS.md index b3b4e3b6..4e201005 100644 --- a/dotfiles/config/taffybar/AGENTS.md +++ b/dotfiles/config/taffybar/AGENTS.md @@ -4,8 +4,8 @@ - Prefer `just run` (foreground) and `just restart` (background) when running taffybar during iterative work. - If running manually, prefer `direnv exec . cabal run` (or `nix develop -c cabal run` if direnv is not active) so you get the right build inputs and environment. -## Tmux session titling -- If the TMUX environment variable is set, treat this chat as the controller for the current tmux session. +## Multiplexer session titling +- If the `TMUX` or `ZELLIJ` environment variable is set, treat this chat as the controller for the current tmux or zellij session. - Maintain a session/window/pane title that updates when the task focus changes substantially. - Prefer automatic titling: infer a concise from the current user request and context without asking. - Title format: " - ". @@ -14,11 +14,13 @@ - is a short, user-friendly description of what we are doing. - Ask for a short descriptive only when the task is ambiguous or you are not confident in an inferred title. - When the task changes substantially, update the automatically if clear; otherwise ask for an updated . -- When a title is provided or updated, immediately run this one-liner: +- When a title is provided or updated, immediately run the matching command for the active multiplexer: tmux rename-session ' - ' \; rename-window ' - ' \; select-pane -T ' - ' -- Assume you are inside tmux, so do not use -t unless the user asks to target a specific session. + zellij action rename-session ' - ' && zellij action rename-tab ' - ' && zellij action rename-pane ' - ' + +- Assume you are inside the active multiplexer, so do not use tmux `-t` or zellij targeting flags unless the user asks to target a specific session/tab/pane. ## Pane usage - Do not create extra panes or windows unless the user asks. @@ -30,4 +32,3 @@ ## Skills A skill is a set of local instructions to follow that is stored in a `SKILL.md` file. - diff --git a/nix-darwin/home/common.nix b/nix-darwin/home/common.nix index 84cab9da..a337e7f1 100644 --- a/nix-darwin/home/common.nix +++ b/nix-darwin/home/common.nix @@ -110,6 +110,7 @@ in { shellAliases = { df_ssh = "TERM='xterm-256color' ssh -o StrictHostKeyChecking=no"; ta = "tmux attach"; + za = "zellij attach"; }; initContent = lib.mkMerge [ (lib.mkOrder 550 '' diff --git a/nixos/environment.nix b/nixos/environment.nix index 3c66ccc0..66635d83 100644 --- a/nixos/environment.nix +++ b/nixos/environment.nix @@ -82,6 +82,7 @@ with lib; df_ssh = "TERM=xterm-256color ssh -o StrictHostKeyChecking=no"; fix_nix = "LD_LIBRARY_PATH='' nix"; ta = "tmux attach"; + za = "zellij attach"; }; variables = { ROFI_SYSTEMD_TERM = "ghostty -e"; diff --git a/nixos/essential.nix b/nixos/essential.nix index cfb84cb5..ac5b99d3 100644 --- a/nixos/essential.nix +++ b/nixos/essential.nix @@ -56,6 +56,7 @@ silver-searcher skim tmux + zellij unzip wget xkcdpass