Tips & Tricks
Operational wisdom for running tmux-ide missions, teams, and the dashboard day-to-day
This page is the stuff you only learn by running tmux-ide on real work for a week. The reference docs tell you what every flag does; this one tells you which flags actually matter, and what breaks when you don't think about them.
Mission design
Missions are how tmux-ide turns "I want to ship feature X" into a sequence the orchestrator can actually drive. The most common mistake is treating them like a project management system. They aren't. They're a dispatch contract for agents that have no memory between turns. Write them accordingly.
Pick the right scope. A good mission has 1-3 milestones, each with 2-5 goals, each with 3-8 tasks. Anything bigger and you'll spend more time grooming the queue than shipping; anything smaller and you might as well just send the lead a prompt. If you find yourself writing milestone M7, that's a signal you're describing the engineering process instead of the deliverable — break it into a second mission instead.
Write the mission as an outcome, not a checklist. "Add JWT auth with refresh tokens, mounted into the existing Hono app, plus migration of the three existing endpoints" is a mission. "Step 1: install jose. Step 2: write middleware" is a Jira ticket — and worse, it locks the agent into an approach you haven't validated. Put the why and the acceptance criteria in the description so the orchestrator can build a rich prompt:
tmux-ide mission set "JWT migration" -d "Replace session cookies with JWT + refresh. \
Acceptance: /api/me works with bearer tokens, refresh endpoint rotates tokens, \
all 3 legacy endpoints migrated, tests stay green, no behavioural regressions."Always include acceptance criteria. The orchestrator injects the mission description verbatim into every dispatched task prompt. If the description has no acceptance bar, every teammate has to guess — and they'll guess differently. A one-line "Acceptance: …" clause at the end of -d is the single highest-leverage thing you can add to a mission.
Layout choices
The number of Claude panes you spin up has a real cost: each one consumes context-window budget on every poll, and the orchestrator has to coordinate them. Don't pick the layout based on "more is better" — pick it based on the shape of the work.
Single Claude + dev/shell is right when you're exploring, refactoring something tangled, or pairing on a tricky bug. One agent, fully in your head, no orchestrator overhead. This is the default tmux-ide init layout for a reason.
Lead + 2 teammates (the agent-team default) is the sweet spot for missions with parallelizable goals. The lead drives planning and reviews, the teammates pick up dispatched tasks. Use this when your mission has independent goals (e.g. "frontend changes" and "backend migrations" that don't block each other). Pin the lead with role: lead and focus: true so it doesn't get auto-dispatched a task while it's planning.
Triple Claude (no orchestrator) pays off when you have three genuinely independent threads of work and you want to drive each manually. It does not pay off if you're just going to ask the same question in all three. The overhead of switching context between panes will eat any speedup. If you find one of the three panes idle most of the time, fold it back into the dev row.
Add a dedicated role: validator pane when you have a validation contract with more than a handful of assertions, or when your CI is slow enough that you want a local validator running in parallel. The validator pane gets skill: reviewer injected and won't be auto-dispatched feature tasks — it only picks up validation work. For projects with a strict acceptance bar, this is the difference between "mission done" and "mission done, but actually broken."
Skills
Skills live in .tmux-ide/skills/*.md and are injected into the dispatch prompt for any pane that declares skill: <name>. The templates ship frontend, backend, general-worker, reviewer, and researcher. Reach for a custom skill when you have project-specific conventions an agent keeps getting wrong — not as a general-purpose memory store.
Reuse before you customize. If your project is "yet another Next.js app," the bundled frontend.md covers 90% of what you'd write by hand. Only write a custom skill when you can name three specific patterns you'd put in it. "I want a skill" is not a reason; "Every agent forgets we use effect/Schema for IO" is.
Keep skill files under 200 lines. The bundled skills are 42-78 lines each, and that's not by accident. The skill content is prepended to every dispatched prompt for every matching pane — every token in a skill file is a token you pay for on every task. If your skill is over 200 lines, you're paying agent context for something that probably belongs in .tmux-ide/library/architecture.md (loaded once per mission, not per task).
Compose with the library, don't duplicate. The pattern that works: skill files contain role-specific guidance ("you are a reviewer, your job is X"), and the library contains project-wide facts ("we use Prisma with these conventions"). When a role: validator pane dispatches, it gets reviewer.md + architecture.md + AGENTS.md — three small files composing into a rich prompt, instead of one 500-line skill file repeating context everyone needs.
tmux-ide skill list --json # see what's already loaded
tmux-ide skill validate --json # catch broken skill refs before launch
tmux-ide skill create reviewer # scaffold from a built-inValidation
The validation contract at .tasks/validation-contract.md is the only thing standing between "the orchestrator says done" and "the feature actually works." Treat it as load-bearing.
Don't ship a contract with 1 assertion. A single VAL-001 reading "the feature works" is worse than no contract at all — it gives you a false sense of coverage. The bar to clear: every milestone has at least 2-3 assertions, and at least one of them is testable without human judgement (a passing test, an HTTP 200, a build artifact). If you can't name 2-3 distinct ways a milestone could fail, the milestone is too small and should fold into its neighbour.
Pair every task with an assertion claim. Use --fulfills VAL-003 when creating tasks. The coverage invariant (tmux-ide validate coverage --json) catches "task with no validation claim" before the orchestrator dispatches it — but only if you actually set up the contract first. Run tmux-ide validate coverage after creating tasks for a new milestone; orphan tasks are a red flag that you skipped writing the assertion they were supposed to satisfy.
Update assertions as you ship. The validator pane updates state automatically when it runs, but if you're driving validation manually, tmux-ide validate assert VAL-001 --status passing --evidence "..." keeps the milestone-gating logic honest. In dispatch_mode: missions, M2 tasks don't dispatch until M1 is done and its assertions pass — a stale pending assertion will silently block the entire next milestone.
Working alongside the agents
The biggest mental shift coming from a single-Claude workflow: the agent panes are not where you have conversations. They're where the orchestrator dispatches tasks. Talking to a teammate pane interrupts whatever the orchestrator just sent it.
Open the dashboard while they work. Run tmux-ide dashboard once and leave the browser tab open. The chat view is project-scoped (one thread list per project), so you can ask "what does this error mean?" in a fresh chat thread while the lead pane is mid-mission. The chat thread runs against the same Claude Code provider but in a separate session — it doesn't pollute the lead's context, and the lead doesn't see your side conversation.
Use multichat for one-off questions. Hit + New chat in the dashboard chat view for anything that isn't "the mission." Code review questions, "explain this stack trace," "draft a commit message for these changes" — all of these go in throwaway threads. Rename important ones in place (click the title); delete the rest with the thread context menu. The provider switcher lets you flip a thread between Claude Code and Codex without losing context — handy when you want a second opinion on a tricky diff.
Let the orchestrator handle the agent panes. If you want to direct the lead, use tmux-ide send Lead "your message" from a separate shell — it routes through tmux send-keys cleanly. If you find yourself typing into agent panes constantly, that's a signal the mission is under-specified and the orchestrator isn't dispatching enough on its own.
Restart hygiene
The lifecycle isn't always intuitive because three things are running: tmux, the daemon, and the dashboard. They restart on different cadences.
ide.yml changes require tmux-ide restart. Layout edits (new panes, changed sizes, new commands), team: toggles, and theme changes only take effect on a full session restart. The daemon hot-reloads orchestrator config (poll_interval, stall_timeout, webhook URLs), but the tmux session itself was built from the file at launch time and doesn't reshape mid-flight.
The daemon survives a stop; the tmux session doesn't. tmux-ide stop kills the tmux session but leaves the daemon running so the dashboard stays responsive. A subsequent tmux-ide launches a fresh session and reattaches the daemon to it. If you genuinely want to restart the daemon (e.g. you upgraded the npm package), kill it explicitly — tmux-ide will boot a new one on next launch.
tmux-ide doctor for the smoke test. Before opening an issue or wondering "why is nothing dispatching," run tmux-ide doctor --json. It checks tmux version, Node version, daemon health, port availability, and ide.yml validity in one shot. 80% of "the orchestrator isn't working" reports come back as "your daemon crashed three days ago" or "port 6060 is held by a stale process."
Performance
The orchestrator's defaults (poll_interval: 5000, stall_timeout: 300000, max_concurrent_agents: 10) are tuned for a 5-10 task mission with 2-3 agents. They are not the right defaults for everything.
Small projects (under 20 tasks, 2-3 agents): lower poll_interval to 2000 for snappier dispatch feel, and lower stall_timeout to 120000 (2 minutes) so a stuck agent gets nudged before you notice. The orchestrator's overhead is negligible at this scale.
Big missions (50+ tasks, 5+ agents): raise poll_interval to 10000 to cut the dispatch churn, and raise stall_timeout to 600000 (10 minutes) — long-running tasks like "run the full test suite" will trip the default and get nudged unnecessarily. Cap max_concurrent_agents to your actual pane count + 1; the schema allows up to 50 but you're not going to spin up 50 Claude instances.
Retry tuning is per-task, not global. The orchestrator retries failed tasks up to 5 times with exponential backoff (10s, 20s, 40s, 80s, 160s, capped at 5 min). For known-flaky tasks (network-dependent integration tests), bump maxRetries on the individual task. For tasks where retry is pointless (a genuinely impossible task), set maxRetries: 1 so they fall to review fast instead of burning 5 dispatch cycles.
orchestrator:
enabled: true
auto_dispatch: true
dispatch_mode: missions
poll_interval: 5000 # 2000 small, 10000 big
stall_timeout: 300000 # 120000 small, 600000 big
max_concurrent_agents: 4 # match your pane countGit hygiene with multi-agent work
Multiple agents in the same repo share one git index. If Pane A runs git add src/auth.ts while Pane B is mid-git commit, Pane B's commit will include Pane A's staged files. This bites everyone who runs an agent team for the first time.
Reset the index before staging. The pattern that survives concurrent work:
git reset # clear the index
git add path/to/your-file.ts # stage your files explicitly, no globs
git status --short # verify exactly your files are staged
git commit -m "..." # commit immediately, no delayThe window between git add and git commit is the danger zone. Keep it as short as possible — don't read code, don't run tests, don't wander off to check Slack. Stage, verify, commit, in one breath.
Never use git add . or git add -A in an agent pane. A wide add will sweep in whatever your sibling agents have just touched. Always name the files. If you need to stage a directory, name the directory (git add src/auth/), not the whole tree.
Don't git reset --hard to "fix" a co-committed mess. A hard reset throws away the sibling's work, not just your bad commit. If a commit captured files you didn't intend, the safe fix is git reset --soft HEAD~1, re-stage only your files, and recommit — the sibling's changes stay in the working tree where they belong. The pattern in the user's memory ("Multi-agent git index is shared") exists because someone learned this the hard way.
Navigation
| Shortcut | Action |
|---|---|
Ctrl-b ←/→/↑/↓ | Move between panes |
Ctrl-b z | Zoom current pane (fullscreen toggle) |
Ctrl-b q | Flash pane numbers, press number to jump |
Ctrl-b d | Detach session (keeps everything running) |
Scrolling
Enter scroll mode with Ctrl-b [, then use arrow keys or Page Up/Down. Press q to exit.
Or enable mouse support in ~/.tmux.conf:
set -g mouse onThis lets you scroll with your trackpad and click to switch panes.
Faster Pane Switching
Add to ~/.tmux.conf for prefix-free navigation with Option+arrow:
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -DReload with tmux source-file ~/.tmux.conf.
macOS: Fix Arrow Key Conflicts
macOS uses Ctrl+←/→ for switching desktops, which conflicts with tmux.
Go to System Settings > Desktop & Dock > Mission Control and disable:
- Move left a space (
^←) - Move right a space (
^→)
Or use the Option+arrow bindings above to avoid the conflict entirely.
Reconnecting
If you close your terminal or detach, your session is still running:
# List all sessions
tmux ls
# Reattach
tmux attach -t my-projectResizing Panes
Drag pane borders with the mouse (if set -g mouse on is enabled), or:
# From inside tmux:
Ctrl-b : resize-pane -D 10 # down
Ctrl-b : resize-pane -U 10 # up
Ctrl-b : resize-pane -L 10 # left
Ctrl-b : resize-pane -R 10 # rightRecommended ~/.tmux.conf
A minimal config that works well with tmux-ide:
# Mouse support
set -g mouse on
# Option+arrow pane switching (no prefix needed)
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D
# Start window numbering at 1
set -g base-index 1
setw -g pane-base-index 1
# Increase scrollback
set -g history-limit 10000