Skip to content

Instantly share code, notes, and snippets.

@markwallsgrove
Last active May 21, 2026 19:02
Show Gist options
  • Select an option

  • Save markwallsgrove/3558c21a93568604562e57db3ec44a29 to your computer and use it in GitHub Desktop.

Select an option

Save markwallsgrove/3558c21a93568604562e57db3ec44a29 to your computer and use it in GitHub Desktop.
Tmux + Claude Code + Jira worktree workflow — per-ticket sessions, attention tracking, broadcast, and full issue-to-merge lifecycle

My Dev Workflow: Tmux + Claude Code + Jira + Git Worktrees

I run multiple Claude Code instances in parallel — one per Jira ticket — each in its own tmux session with a dedicated git worktree. A custom attention system tracks which Claude needs me. Here's how it fits together.

The Loop

  1. Ctrl-i — pick a Jira issue, pick a repo, name a branch. A git worktree and tmux session are created. Claude Code launches in a split pane with the Jira ticket context, and we discuss the ticket first (no implementation). When done, Claude writes a YAML outcome file, updates Jira, then restarts in implementation mode.

  2. Work — Claude writes tests first, implements, runs checks, creates a PR. Meanwhile I'm already on another ticket in another session.

  3. Ctrl-e — jump to whichever Claude has been waiting longest for input. A 🤖 in the status bar tells me someone needs me.

  4. Ctrl-m — pick a session to close out. Squash-merges the PR, walks the Jira issue through transitions to "Done", removes the worktree, deletes the branch, kills the session.

Key Bindings

All root-table (no prefix needed), all open fzf in a tmux popup:

Key What
Ctrl-i Start Jira issue → discuss → worktree → Claude
Ctrl-m Merge PR → transition Jira → cleanup
Ctrl-f Find/create tmux session
Ctrl-n New branch + worktree
Ctrl-g Switch git worktree
Ctrl-j Find Claude instances (! = needs attention)
Ctrl-e Jump to next Claude needing help
Ctrl-b Broadcast message to multiple Claude instances
Ctrl-x Kill sessions
Ctrl-p Find processes across all panes
Ctrl-h Searchable keybindings help
Ctrl-_ Snippet picker (paste/add/edit/delete)

The Jira Start Flow (tmux-jira-start)

Source

The popup walks through fzf dialogs:

  1. Issue picker — your assigned issues with full preview
  2. Repo picker — all git repos under ~/projects
  3. Base branch — fetch + branch picker
  4. Branch name — defaults to feat/<key>-, or attach to existing session

Then it creates the worktree, launches a tmux session, and splits the window. The right pane runs Claude with a discussion-only prompt:

"This is a DISCUSSION ONLY. Do NOT implement anything. Discuss the ticket: ask clarifying questions, suggest an approach, refine requirements. Keep everything HIGH LEVEL and CONCEPTUAL. You SHOULD read the codebase to understand what exists, but keep responses conceptual."

When you say you're done discussing, Claude writes a YAML outcome:

proceed: true
refined_description: |
  ...
acceptance_criteria: |
  ...
implementation_notes: |
  ...

The script pushes the refined description back to Jira, then execs a fresh Claude with the implementation prompt (write tests first → implement → run checks → create PR).

Hydration

tmux-sessionizer sources a .tmux-sessionizer file in the project root. tmux-jira-start writes one to auto-setup the split layout:

tmux rename-window "repo-name"
tmux split-window -h -p 50 "tmux-jira-start --continue SUP-1234 /path/to/worktree /path/to/repo"

The Merge Flow (tmux-jira-merge)

Source

  1. Session picker — sessions enriched with Jira key + summary
  2. PR check — verifies CI, option to override failures
  3. Squash merge — editable commit message (defaults to PR title)
  4. Jira transition — walks the issue through states until "Done"
  5. Cleanup — removes worktree, deletes branch, kills session

One popup, entire ticket lifecycle closed.

Claude Attention System

The problem: you have 5 Claude instances running. Which ones are waiting for you?

Hooks (~/.claude/settings.json)

{
  "hooks": {
    "Notification": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "mkdir -p /tmp/claude-attention && printf '%s' \"$(date +%s)\" > \"/tmp/claude-attention/${TMUX_PANE}\" && tmux set-option -t \"${TMUX_PANE}\" -p @claude_attention 1 2>/dev/null; tmux run-shell 'printf \"\\a\"' 2>/dev/null; true"
      }]
    }],
    "PreToolUse": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "rm -f \"/tmp/claude-attention/${TMUX_PANE}\" && tmux set-option -t \"${TMUX_PANE}\" -p -u @claude_attention 2>/dev/null; true"
      }]
    }]
  }
}

When Claude sends a notification (waiting for input), a timestamp is written to /tmp/claude-attention/<pane_id>. When Claude resumes work (any tool use), it's cleared.

Scripts that consume this

  • tmux-claude-finder (Ctrl-j) — fzf picker of all Claude instances. Attention ones show ! with age (e.g. ! session > window (3m ago)). Preview shows last 100 lines.
  • tmux-claude-next (Ctrl-e) — jumps to the longest-waiting instance. No fzf, instant switch.
  • tmux-claude-broadcast (Ctrl-b) — multi-select Claude instances, type one message sent to all. Remembers deselection state between invocations.
  • tmux-claude-status — status bar script, shows 🤖 when any instance needs you.

Claude Code Status Line

Shows in Claude's footer bar:

 feat/sup-4530 │ ctx:45% │ $1.23 │ 5h:12% 7d:3% │ +150/-30 │ 14:30

Git branch, context window usage (color-coded red/yellow/green), session cost, rate limits, lines changed, time. Configured via ~/.claude/settings.json:

{ "statusLine": { "type": "command", "command": "~/.claude/statusline.sh" } }

Tool Audit

Every Claude tool call is logged:

{ "command": "jq -c '{ts: (now | todate), tool: .tool_name, input: .tool_input}' >> ~/.claude/permission-audit.jsonl; true" }

Other Scripts

  • tmux-new-branch — repo picker → base branch → branch name → worktree → session. Like tmux-jira-start without the Jira/Claude parts.
  • gwts — quick worktree switcher. Repo picker → branch picker → open existing or create worktree → session.
  • tmux-session-kill — multi-select fzf to kill sessions (current excluded).
  • tmux-fzf-processes — lists all processes across all tmux panes with descendant tree. Preview shows pane content. Select to switch.
  • tmux-help — parses ~/.tmux.conf inline comments + all active bindings into searchable fzf.
  • tmux-snippets — snippet manager. 4 modes cycled with Tab: paste, add, edit, delete. Stores in ~/.config/snippets/, loads into tmux paste buffer.

Prerequisites

brew install tmux fzf jq yq zoxide
brew install go-jira   # https://github.com/ankitpokhrel/jira-cli
brew install gh
npm install -g @anthropic-ai/claude-code

All dotfiles

github.com/markwallsgrove/dotfiles — scripts in .local/bin/, tmux config in .tmux.conf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment