My Daily Moshi Workflow: How I Organize tmux for Claude Code
A practical guide to organizing tmux windows for AI agents, web servers, and Expo — with push notifications to stay in the loop
TL;DR: I run five tmux windows: 1-3 for Claude Code agents, 4 for web servers or Expo, 5 for misc tasks. Same layout across all projects — muscle memory means I can navigate without thinking. Claude Code sets window titles automatically, Moshi propagates them. Push notifications ping me when agents need input.
The Problem
Running AI coding agents alongside web or mobile development means juggling multiple processes. On desktop, you'd use multiple terminal tabs. On mobile, context-switching kills productivity.
My solution: a consistent tmux layout I can navigate blind.
┌─────────────────────────────────────────────────────────────────┐
│ dev ─ 1:frontend 2:api-refactor 3:tests 4:servers 5:bash │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Window 1: Claude working on frontend │
│ Window 2: Claude refactoring API │
│ Window 3: Claude running tests │
│ │
│ Window 4: Web servers or Expo │
│ Window 5: Misc (deploy, app store submit, etc.) │
│ │
└─────────────────────────────────────────────────────────────────┘
Note: Windows 1-3 don't need manual names. Claude Code automatically sets the terminal title based on current task, and Moshi propagates it to the tmux window name.
My tmux Configuration
Here's my ~/.tmux.conf:
# Large scrollback for long agent sessions
set -g history-limit 100000
# Mouse support (essential for mobile scrolling)
set -g mouse on
# Start numbering at 1 (matches keyboard shortcuts)
set -g base-index 1
# Show window index and title in terminal title
set -g set-titles on
set -g set-titles-string "#I: #W"
# Renumber windows when one closes
set -g renumber-windows on
Window Layout
I always use the same window numbers. Muscle memory matters.
| Window | Purpose |
|---|---|
| 1 | Primary Claude Code session |
| 2 | Secondary agent (reviews, parallel tasks) |
| 3 | Tertiary agent (tests, research) |
| 4 | Web servers or Expo (if app) |
| 5 | Misc (deploy, app store submit, etc.) |
Windows 1-3 don't need manual names — Claude Code sets the terminal title automatically based on the current task (e.g., "frontend", "api-refactor", "tests"), and Moshi propagates it to the tmux status bar.
Creating the Layout
I have a script that sets this up:
#!/bin/bash
# ~/bin/dev-session
SESSION="dev"
tmux new-session -d -s $SESSION
tmux new-window -t $SESSION:2
tmux new-window -t $SESSION:3
tmux new-window -t $SESSION:4 -n servers
tmux new-window -t $SESSION:5 -n misc
# Start in window 1
tmux select-window -t $SESSION:1
tmux attach -t $SESSION
Or create manually:
tmux new -s dev
# Ctrl+B, c to create new windows
Navigating from Moshi
In Moshi, I use the tmux shortcuts panel constantly.
Long-press Ctrl → Tmux tab → Tap window number
| Tap | Jumps to |
|---|---|
1 | Claude (primary) |
2 | Claude (secondary) |
3 | Claude (tests) |
4 | Servers / Expo |
5 | Misc |
The status bar shows where I am. Claude Code sets the terminal title automatically, and Moshi displays it in the header.
For a deeper dive into Moshi's shortcuts and modifier keys, see Mastering Moshi's Terminal Keyboard.
Push Notifications
This is the key to "endless agent" workflows. Each Claude session has this in the project's CLAUDE.md:
## Notifications
When you complete a task or need input, notify me:
curl -s -X POST https://api.getmoshi.app/api/webhook \
-H "Content-Type: application/json" \
-d '{"token": "YOUR_TOKEN", "title": "Task complete", "message": "Need approval for npm install"}'
Workflow
- Start Claude in windows 1-3 with different tasks
- Put phone in pocket
- Get notification: "Tests passing, ready for review"
- Open Moshi → check window titles in status bar → jump to the right one
- Approve and walk away
For the full push notification setup including webhook tokens and mosh/tmux configuration, see The Best Remote Coding Setup for AI Agents.
Window 4: Web Servers or Expo
Window 4 is for dev servers. For web projects, use Bun's parallel mode:
cd ~/projects/my-app && bun dev --filter '*'
This starts all workspace packages with dev scripts in parallel. For a monorepo:
// package.json
{
"workspaces": ["apps/*", "packages/*"],
"scripts": {
"dev": "bun --filter '*' dev"
}
}
Example output:
$ bun dev --filter '*'
[web] Server running at http://100.64.0.1:3000
[api] Server running at http://100.64.0.1:4000
[admin] Server running at http://100.64.0.1:3001
All servers in one window, one command. No panes needed.
For mobile apps, run Expo instead:
cd ~/projects/my-app && npx expo start
The Expo CLI has its own keyboard shortcuts (r to reload, i to open iOS Simulator) that work through Moshi.
Window 5: Misc
Window 5 is my scratch space for one-off tasks:
eas submit— submit to App Storebun run deploy— deploy to productiongh pr create— create pull requests- Quick git operations
- Anything that doesn't fit windows 1-4
I keep it named misc or bash so it's always there when I need it.
Previewing on Your Phone
When running dev servers, you want to tap a link and preview directly on your phone. Two things need to happen:
1. Bind to Network Interface
By default, Vite/Expo/Next.js bind to localhost — unreachable from your phone. Add --host:
| Framework | Command |
|---|---|
| Vite | vite --host or vite --host 0.0.0.0 |
| Next.js | next dev -H 0.0.0.0 |
| Expo | Already binds to network by default |
| Create React App | HOST=0.0.0.0 react-scripts start |
| Bun | bun run --host 0.0.0.0 dev |
Or configure permanently in vite.config.ts:
export default defineConfig({
server: {
host: true, // or '0.0.0.0'
},
})
2. Tell Claude to Show the Address
Add this to your project's CLAUDE.md:
## Dev Server
When starting dev servers, always use --host flag to bind to network interface.
After the server starts, show me the network URL (not localhost) so I can tap to preview:
Example output:
> Server running at http://192.168.1.100:5173
Now when Claude starts your server, you'll see a tappable link in the terminal output. Tap it → opens in Safari → instant preview.
Using Tailscale IP
If you're connected via Tailscale (see Using Your Mac as a Remote Agent for setup), use your Mac's Tailscale IP:
# Get your Tailscale IP
tailscale ip -4
# Example: 100.64.0.1
# Server will be at http://100.64.0.1:5173
Add this to CLAUDE.md too:
My Tailscale IP is 100.64.0.1. When showing server URLs, use this IP instead of 192.168.x.x for reliable access.
Quick Preview Workflow
- Claude starts server with
--host - Terminal shows:
http://100.64.0.1:5173 - Tap the link
- Safari opens with your app
- Make changes → Claude rebuilds → pull to refresh
Tips
Name Your Sessions Too
Not just windows — sessions. I use different sessions for different projects:
tmux new -s moshi # Moshi development
tmux new -s client-app # Client project
tmux new -s experiments # Throwaway experiments
Moshi shows available sessions when you connect, so naming helps.
Quick Status Check
From any window, Ctrl+B, w shows a list of all windows. But tapping through 1-5 is usually faster.
Aggressive Scrollback
AI agents produce a lot of output. My history-limit 100000 means I can scroll back through an entire debugging session. Default 2000 lines isn't enough.
Quick Setup
# 1. Add to ~/.tmux.conf
cat >> ~/.tmux.conf << 'EOF'
set -g history-limit 100000
set -g mouse on
set -g base-index 1
set -g set-titles on
set -g set-titles-string "#I: #W"
set -g renumber-windows on
EOF
# 2. Create session script
cat > ~/bin/dev-session << 'EOF'
#!/bin/bash
SESSION="dev"
tmux new-session -d -s $SESSION
tmux new-window -t $SESSION:2
tmux new-window -t $SESSION:3
tmux new-window -t $SESSION:4 -n servers
tmux new-window -t $SESSION:5 -n misc
tmux select-window -t $SESSION:1
tmux attach -t $SESSION
EOF
chmod +x ~/bin/dev-session
# 3. Start working
dev-session
Resources
- Moshi — Mobile Terminal for Developers
- The Complete Remote Coding Setup — mosh, tmux, Tailscale, and push notifications
- Mastering Moshi's Terminal Keyboard — shortcuts, modifiers, and voice input
- Using Your Mac as a Remote Agent — always-on server setup
- Best iOS Terminal App for AI Coding — comparing terminal apps
- tmux man page
