---
Assists with Zellij terminal multiplexer configuration, layouts, sessions, and troubleshooting workflows.
/plugin marketplace add shepherdjerred/monorepo/plugin install jerred@shepherdjerredZellij is a modern terminal multiplexer with a focus on user experience, WebAssembly plugins, and KDL-based configuration. It provides sessions, tabs, and panes for organizing terminal workflows, with layouts for reproducible workspace setups.
# Start new session
zellij
# Start named session
zellij -s my-session
# Start with layout
zellij --layout dev
# List sessions
zellij list-sessions
zellij ls
# Attach to session
zellij attach my-session
zellij a my-session
# Attach or create if doesn't exist
zellij attach -c my-session
# Kill session
zellij kill-session my-session
zellij k my-session
# Kill all sessions
zellij kill-all-sessions
zellij ka
# Delete session (remove from resurrection)
zellij delete-session my-session
zellij d my-session
# Delete all sessions
zellij delete-all-sessions
zellij da
# Validate configuration
zellij setup --check
# Dump default config
zellij setup --dump-config > config.kdl
# Dump specific layout
zellij setup --dump-layout default
# Generate shell completions
zellij setup --generate-completion bash
zellij setup --generate-completion zsh
zellij setup --generate-completion fish
# Generate autostart script
zellij setup --generate-auto-start bash
Run commands in new panes from the shell:
# Run command in new pane
zellij run -- htop
# Run in floating pane
zellij run -f -- npm run dev
# Run in specific direction
zellij run -d right -- tail -f /var/log/syslog
# Close pane on command exit
zellij run -c -- make build
# Run in-place (replace current pane)
zellij run -i -- vim file.txt
# Start suspended (press Enter to run)
zellij run -s -- dangerous-command
# Custom pane name
zellij run -n "Build Output" -- cargo build
# Set working directory
zellij run --cwd /path/to/project -- ls -la
# Floating pane with size and position
zellij run -f --width 50% --height 30 -x 10% -y 5 -- htop
Open files in editor panes:
# Open file in $EDITOR
zellij edit file.txt
# Open at specific line
zellij edit --line-number 42 src/main.rs
# Open in floating pane
zellij edit -f config.yaml
# Open in-place
zellij edit -i notes.md
# With direction
zellij edit -d down Makefile
Control Zellij programmatically:
# Execute action
zellij action <action-name>
# Pane actions
zellij action new-pane
zellij action new-pane -d right
zellij action new-pane -f # floating
zellij action close-pane
zellij action toggle-fullscreen
zellij action toggle-floating-panes
zellij action toggle-pane-frames
zellij action toggle-pane-embed-or-floating
zellij action move-pane
zellij action move-pane -d left
# Tab actions
zellij action new-tab
zellij action new-tab -n "Dev"
zellij action new-tab -l dev-layout
zellij action close-tab
zellij action go-to-tab 3
zellij action go-to-tab-name "Dev"
zellij action go-to-next-tab
zellij action go-to-previous-tab
zellij action rename-tab "New Name"
# Navigation
zellij action focus-next-pane
zellij action focus-previous-pane
zellij action move-focus left
zellij action move-focus right
zellij action move-focus up
zellij action move-focus down
# Scrolling
zellij action scroll-up
zellij action scroll-down
zellij action page-scroll-up
zellij action page-scroll-down
zellij action half-page-scroll-up
zellij action half-page-scroll-down
zellij action scroll-to-bottom
# Resize
zellij action resize increase left
zellij action resize decrease right
zellij action resize increase up 5
zellij action resize decrease down 10
# Utility actions
zellij action dump-screen /tmp/screen.txt
zellij action dump-layout > current-layout.kdl
zellij action edit-scrollback
zellij action toggle-active-sync-tab
zellij action write "echo hello"
zellij action write-chars "hello world"
# Plugin actions
zellij action launch-or-focus-plugin file:~/.config/zellij/plugins/my-plugin.wasm
zellij action start-or-reload-plugin file:~/.config/zellij/plugins/my-plugin.wasm
| Action | Description |
|---|---|
new-pane | Create new pane |
close-pane | Close current pane |
move-pane | Move pane in direction |
resize | Resize pane |
toggle-fullscreen | Fullscreen current pane |
toggle-floating-panes | Show/hide floating panes |
toggle-pane-embed-or-floating | Convert between embedded/floating |
toggle-pane-frames | Show/hide pane borders |
toggle-pane-pinned | Pin floating pane on top |
stack-panes | Stack panes in direction |
| Action | Description |
|---|---|
new-tab | Create new tab |
close-tab | Close current tab |
go-to-tab | Go to tab by index |
go-to-tab-name | Go to tab by name |
go-to-next-tab | Next tab |
go-to-previous-tab | Previous tab |
rename-tab | Rename current tab |
toggle-tab | Toggle to previous tab |
break-pane | Move pane to new tab |
break-pane-left | Move pane to new tab on left |
break-pane-right | Move pane to new tab on right |
| Action | Description |
|---|---|
focus-next-pane | Focus next pane |
focus-previous-pane | Focus previous pane |
move-focus | Focus pane in direction |
move-focus-or-tab | Focus pane or switch tab |
clear | Clear terminal screen |
| Action | Description |
|---|---|
detach | Detach from session |
quit | Exit Zellij |
switch-mode | Change input mode |
previous-swap-layout | Previous layout |
next-swap-layout | Next layout |
# Start with layout
zellij --layout my-layout
# Create new tab with layout
zellij action new-tab -l my-layout
# Dump current layout
zellij action dump-layout > layout.kdl
// ~/.config/zellij/layouts/dev.kdl
layout {
// Default tab template
default_tab_template {
pane size=1 borderless=true {
plugin location="zellij:tab-bar"
}
children
pane size=2 borderless=true {
plugin location="zellij:status-bar"
}
}
// First tab - code editing
tab name="Code" focus=true {
pane split_direction="vertical" {
pane command="nvim" {
args "."
}
pane split_direction="horizontal" size="30%" {
pane command="lazygit"
pane name="Terminal"
}
}
}
// Second tab - services
tab name="Services" {
pane split_direction="horizontal" {
pane command="npm" {
args "run" "dev"
cwd "/path/to/frontend"
}
pane command="npm" {
args "run" "dev"
cwd "/path/to/backend"
}
}
}
}
layout {
tab {
pane
floating_panes {
pane command="htop" {
x 10%
y 10%
width "60%"
height "60%"
}
}
}
}
layout {
tab {
pane stacked=true {
pane command="tail" {
args "-f" "/var/log/app.log"
name "App Logs"
}
pane command="tail" {
args "-f" "/var/log/system.log"
name "System Logs"
}
pane command="tail" {
args "-f" "/var/log/error.log"
name "Error Logs"
}
}
pane // Main working pane
}
}
layout {
// Attach to existing session or create new one
session name="dev-session"
tab name="Editor" {
pane command="nvim"
}
}
~/.config/zellij/config.kdl
// config.kdl
// Behavior options
on_force_close "quit" // or "detach"
simplified_ui false
pane_frames true
auto_layout true
session_serialization true
pane_viewport_serialization true
scrollback_lines_to_serialize 10000
// Shell and editor
default_shell "zsh"
default_layout "default"
default_mode "normal" // or "locked"
// Mouse and copy
mouse_mode true
scroll_buffer_size 10000
copy_command "pbcopy" // macOS
copy_clipboard "system" // or "primary"
copy_on_select true
// Theme
theme "nord"
// Scrollback editor (for edit-scrollback action)
scrollback_editor "/usr/bin/nvim"
// Mirror sessions (sync input across panes)
mirror_session false
// Web client (v0.43+)
// web_server true
// web_server_port 8080
// Layout and theme directories
layout_dir "/path/to/layouts"
theme_dir "/path/to/themes"
// UI styling
styled_underlines true
hide_session_name false
// config.kdl
keybinds clear-defaults=true {
// Normal mode
normal {
bind "Ctrl g" { SwitchToMode "locked"; }
bind "Ctrl p" { SwitchToMode "pane"; }
bind "Ctrl t" { SwitchToMode "tab"; }
bind "Ctrl n" { SwitchToMode "resize"; }
bind "Ctrl s" { SwitchToMode "scroll"; }
bind "Ctrl o" { SwitchToMode "session"; }
bind "Ctrl q" { Quit; }
}
// Locked mode (only unlock binding works)
locked {
bind "Ctrl g" { SwitchToMode "normal"; }
}
// Pane mode
pane {
bind "h" "Left" { MoveFocus "Left"; }
bind "l" "Right" { MoveFocus "Right"; }
bind "j" "Down" { MoveFocus "Down"; }
bind "k" "Up" { MoveFocus "Up"; }
bind "n" { NewPane; SwitchToMode "normal"; }
bind "d" { NewPane "Down"; SwitchToMode "normal"; }
bind "r" { NewPane "Right"; SwitchToMode "normal"; }
bind "x" { CloseFocus; SwitchToMode "normal"; }
bind "f" { ToggleFocusFullscreen; SwitchToMode "normal"; }
bind "w" { ToggleFloatingPanes; SwitchToMode "normal"; }
bind "e" { TogglePaneEmbedOrFloating; SwitchToMode "normal"; }
bind "Esc" { SwitchToMode "normal"; }
}
// Tab mode
tab {
bind "h" "Left" { GoToPreviousTab; }
bind "l" "Right" { GoToNextTab; }
bind "n" { NewTab; SwitchToMode "normal"; }
bind "x" { CloseTab; SwitchToMode "normal"; }
bind "r" { SwitchToMode "RenameTab"; TabNameInput 0; }
bind "1" { GoToTab 1; SwitchToMode "normal"; }
bind "2" { GoToTab 2; SwitchToMode "normal"; }
bind "3" { GoToTab 3; SwitchToMode "normal"; }
bind "Esc" { SwitchToMode "normal"; }
}
// Resize mode
resize {
bind "h" "Left" { Resize "Increase Left"; }
bind "j" "Down" { Resize "Increase Down"; }
bind "k" "Up" { Resize "Increase Up"; }
bind "l" "Right" { Resize "Increase Right"; }
bind "H" { Resize "Decrease Left"; }
bind "J" { Resize "Decrease Down"; }
bind "K" { Resize "Decrease Up"; }
bind "L" { Resize "Decrease Right"; }
bind "=" "+" { Resize "Increase"; }
bind "-" { Resize "Decrease"; }
bind "Esc" { SwitchToMode "normal"; }
}
// Scroll mode
scroll {
bind "j" "Down" { ScrollDown; }
bind "k" "Up" { ScrollUp; }
bind "Ctrl f" "PageDown" { PageScrollDown; }
bind "Ctrl b" "PageUp" { PageScrollUp; }
bind "d" { HalfPageScrollDown; }
bind "u" { HalfPageScrollUp; }
bind "e" { EditScrollback; SwitchToMode "normal"; }
bind "/" { SwitchToMode "EnterSearch"; SearchInput 0; }
bind "Esc" { SwitchToMode "normal"; }
}
// Search mode
search {
bind "n" { Search "down"; }
bind "N" { Search "up"; }
bind "c" { SearchToggleOption "CaseSensitivity"; }
bind "w" { SearchToggleOption "Wrap"; }
bind "o" { SearchToggleOption "WholeWord"; }
bind "Esc" { SwitchToMode "normal"; }
}
// Session mode
session {
bind "d" { Detach; }
bind "w" {
LaunchOrFocusPlugin "session-manager" {
floating true
move_to_focused_tab true
}
SwitchToMode "normal"
}
bind "Esc" { SwitchToMode "normal"; }
}
// Shared bindings across modes
shared_except "locked" {
bind "Alt h" { MoveFocusOrTab "Left"; }
bind "Alt l" { MoveFocusOrTab "Right"; }
bind "Alt j" { MoveFocus "Down"; }
bind "Alt k" { MoveFocus "Up"; }
bind "Alt n" { NewPane; }
bind "Alt [" { PreviousSwapLayout; }
bind "Alt ]" { NextSwapLayout; }
}
}
Zellij has 13 input modes:
| Mode | Description |
|---|---|
normal | Default mode, typing goes to terminal |
locked | Disable all Zellij keybindings |
pane | Pane operations (create, close, move, focus) |
tab | Tab operations (create, close, switch) |
resize | Resize focused pane |
move | Move focused pane |
scroll | Scroll through pane output |
search | Search within pane scrollback |
entersearch | Enter search query |
renametab | Rename current tab |
renamepane | Rename current pane |
session | Session operations (detach, manager) |
tmux | tmux-compatible keybindings |
// Tab bar at top
plugin location="zellij:tab-bar"
// Status bar at bottom
plugin location="zellij:status-bar"
// Compact status bar
plugin location="zellij:compact-bar"
// File browser
plugin location="zellij:strider"
// Session manager (v0.40+)
plugin location="zellij:session-manager"
layout {
pane size=1 borderless=true {
plugin location="zellij:tab-bar"
}
pane split_direction="vertical" {
pane size="20%" {
plugin location="zellij:strider" {
// Plugin configuration
cwd "/path/to/project"
}
}
pane
}
pane size=2 borderless=true {
plugin location="zellij:status-bar"
}
}
// From file path
plugin location="file:~/.config/zellij/plugins/my-plugin.wasm"
// With configuration
plugin location="file:/path/to/plugin.wasm" {
option1 "value1"
option2 true
}
#!/bin/bash
# Start development session with layout
SESSION="dev"
PROJECT_DIR="/path/to/project"
# Check if session exists
if zellij list-sessions | grep -q "^$SESSION$"; then
zellij attach "$SESSION"
else
cd "$PROJECT_DIR"
zellij -s "$SESSION" --layout dev
fi
#!/bin/bash
# Interactive session selector using fzf
SESSION=$(zellij list-sessions | fzf --header="Select session (or type new name)")
if [ -z "$SESSION" ]; then
exit 0
fi
if zellij list-sessions | grep -q "^$SESSION$"; then
zellij attach "$SESSION"
else
zellij -s "$SESSION"
fi
# Select multiple panes with Alt+click, then:
# - Close all selected: x
# - Float all selected: w
# - Stack all selected: s
# Or from CLI (create multi-pane setup)
zellij action new-pane -d right
zellij action new-pane -d down
zellij action move-focus left
zellij action new-pane -d down
// microservices.kdl
layout {
tab name="Services" {
pane split_direction="vertical" {
pane command="npm" {
args "run" "dev"
cwd "/path/to/api-gateway"
name "API Gateway"
}
pane split_direction="horizontal" {
pane command="npm" {
args "run" "dev"
cwd "/path/to/user-service"
name "User Service"
}
pane command="npm" {
args "run" "dev"
cwd "/path/to/order-service"
name "Order Service"
}
}
}
}
tab name="Logs" {
pane stacked=true {
pane command="docker" {
args "logs" "-f" "api-gateway"
name "Gateway Logs"
}
pane command="docker" {
args "logs" "-f" "user-service"
name "User Logs"
}
pane command="docker" {
args "logs" "-f" "order-service"
name "Order Logs"
}
}
}
tab name="Terminal"
}
# Inside Zellij session
echo $ZELLIJ # "0" if inside session
echo $ZELLIJ_SESSION_NAME # Session name
# For scripting
if [ -n "$ZELLIJ" ]; then
echo "Inside Zellij session: $ZELLIJ_SESSION_NAME"
fi
# .bashrc or .zshrc
if [ -z "$ZELLIJ" ]; then
export ZELLIJ_AUTO_ATTACH=true # Auto-attach to existing
export ZELLIJ_AUTO_EXIT=true # Exit shell when detaching
eval "$(zellij setup --generate-auto-start bash)"
fi
# .bashrc or .zshrc
if [ -z "$ZELLIJ" ]; then
zellij attach -c default
fi
// ide.kdl
layout {
default_tab_template {
pane size=1 borderless=true {
plugin location="zellij:tab-bar"
}
children
pane size=2 borderless=true {
plugin location="zellij:status-bar"
}
}
tab name="Editor" focus=true {
pane split_direction="vertical" {
pane size="20%" {
plugin location="zellij:strider"
}
pane split_direction="horizontal" {
pane command="nvim" focus=true {
args "."
name "Editor"
}
pane size="30%" {
name "Terminal"
}
}
}
}
tab name="Git" {
pane command="lazygit"
}
tab name="Logs" {
pane stacked=true {
pane command="tail" {
args "-f" "logs/app.log"
}
pane command="tail" {
args "-f" "logs/error.log"
}
}
}
}
# Start with layout
zellij --layout ide
#!/bin/bash
# setup-dev.sh - Create development environment
PROJECT="my-project"
# Start new session
zellij -s "$PROJECT" &
sleep 1
# Create tabs and panes
zellij action rename-tab "Code"
zellij action new-pane -d right
zellij action new-tab -n "Server"
zellij run -i -- npm run dev
zellij action new-tab -n "Database"
zellij run -i -- docker compose up db
zellij action go-to-tab 1
zellij action move-focus left
zellij run -i -- nvim .
echo "Development environment ready!"
// config.kdl
web_server true
web_server_port 8080
// For secure access over network
// web_server_ip "0.0.0.0"
// Note: Use SSH tunnel or reverse proxy with HTTPS in production
# Start session with web access
zellij -s web-session
# Access from browser:
# http://localhost:8080
# Use authentication token shown in terminal
# Validate config
zellij setup --check
# Show current config
zellij setup --dump-config
# List all sessions
zellij ls
# Force kill stuck session
zellij kill-session stuck-session
# Clean up dead sessions
zellij delete-all-sessions
# Check if plugin file exists
ls -la ~/.config/zellij/plugins/
# View plugin errors in scrollback
# Press Ctrl+s, then scroll up to see errors
# Reload plugin
zellij action start-or-reload-plugin file:/path/to/plugin.wasm
# Validate layout syntax
zellij --layout my-layout --dry-run
# Dump current state for debugging
zellij action dump-layout > debug-layout.kdl
// Reduce scrollback for memory
scroll_buffer_size 5000
scrollback_lines_to_serialize 5000
// Disable features if slow
pane_viewport_serialization false
session_serialization false
Ask the user for clarification when:
Use this agent to verify that a Python Agent SDK application is properly configured, follows SDK best practices and documentation recommendations, and is ready for deployment or testing. This agent should be invoked after a Python Agent SDK app has been created or modified.
Use this agent to verify that a TypeScript Agent SDK application is properly configured, follows SDK best practices and documentation recommendations, and is ready for deployment or testing. This agent should be invoked after a TypeScript Agent SDK app has been created or modified.