Skip to content

Warp Terminal Setup

Warp terminal is the recommended launcher for Catalyst. This page covers the catalyst quartet pattern — a set of 5 Warp tab configurations per project that give you one-click access to the project root, the PM worktree, new ticket worktrees, existing worktrees, and orchestration runs.

Everything on this page can be auto-generated by running /catalyst-dev:setup-warp.

Warp has a feature called tab configurations (~/.warp/tab_configs/*.toml) — declarative templates that appear in the + (new tab) menu. Each tab config can:

  • Set a colored indicator (visible in the vertical tab bar)
  • Run a sequence of shell commands when the tab opens
  • Prompt the user for parameters (branch names, ticket IDs) before launching
  • Change working directory
  • Display a custom name/emoji in the tab bar

Catalyst takes advantage of all five to create a unified per-project workflow.

For each project you work on, Catalyst generates 5 tab configurations:

#VariantEmojiPurpose
1Main📦Opens project root, runs direnv + thoughts sync + optional setup command
2PM📋Opens pm worktree (long-lived branch for ticket management)
3New Worktree🆕Prompts for branch + description; creates the worktree and launches Claude
4Worktree🔀Branch picker; reopens an existing worktree
5Orchestrator🚀Prompts for tickets/cycle/project/auto; spawns an orchestration run

Each project gets a distinct color so the vertical tab sidebar is scannable. PM tabs are always blue (cross-project convention for PM/backlog work); the other variants inherit the project’s color.

ProjectSuggested color
Catalystmagenta
Advagreen
Personal toolsblue
Client workcyan

Warp accepts 8 color variants total: black, red, green, yellow, blue, magenta, cyan, white. Any other value (e.g. purple, orange, teal, pink) fails to load with a TOML parse error. black is valid but invisible on dark themes.

Every launcher (for PM/worktree/orchestrator variants) exports two environment variables:

Terminal window
export CATALYST_WARP_NAME="<project>_<context>"
export CATALYST_WARP_REMOTE="<project>_<context>"

The catalyst-claude.sh wrapper reads these and passes them to Claude as --name and --remote-control-session-name-prefix, so the name shows up in:

  • Claude Code’s prompt box (bottom of the conversation)
  • The /resume session picker
  • The terminal tab title (via OSC escape from Claude)
  • The Claude Code Remote Control app (match the name you see on screen)

Examples:

ContextSession name
Main Catalyst tabcatalyst
Catalyst PM worktreecatalyst_pm
Ticket worktree with descriptioncatalyst_CTL-64_fix-auth
Orchestrator with 2 ticketscatalyst_CTL-50_CTL-51
Orchestrator with --auto 5catalyst_auto5
Orchestrator with --project ADRcatalyst_ADR
Adva ticket worktreeadva_ADV-230

The fastest path to a working setup:

Terminal window
/catalyst-dev:setup-warp

The skill:

  1. Checks that Warp is installed (offers brew install --cask warp if not)
  2. Scans ~/code-repos, ~/Developer, ~/Projects, ~/src for git repositories
  3. Asks which projects to configure
  4. For each project, interviews you for display name, emoji, color, variants, and optional setup command
  5. Generates ~/.warp/tab_configs/NN_<project>[_variant].toml files
  6. Backs up any existing configs first
  7. Points you at this guide for ongoing reference

Re-run the skill anytime to add a new project or update an existing one. It’s idempotent and always backs up before regenerating.

If you prefer not to use the skill, here are the tab config templates.

name = "Catalyst 📦"
title = "Catalyst"
color = "magenta"
[[panes]]
id = "main"
type = "terminal"
directory = "~/code-repos/github/coalesce-labs/catalyst"
commands = [
"export CATALYST_WARP_NAME=catalyst CATALYST_WARP_REMOTE=catalyst",
"~/code-repos/github/coalesce-labs/catalyst/plugins/dev/scripts/open-project-tab.sh",
]

The helper open-project-tab.sh (shipped in the catalyst plugin) runs direnv, humanlayer thoughts sync, trust-workspace, and git fetch && git status. You can pass a project-specific init command as its first argument:

commands = [
"export CATALYST_WARP_NAME=adva CATALYST_WARP_REMOTE=adva",
"~/code-repos/github/coalesce-labs/catalyst/plugins/dev/scripts/open-project-tab.sh 'bun install && scripts/setup-env.sh'",
]
name = "Catalyst 📋 PM"
title = "Catalyst: PM"
color = "blue"
[[panes]]
id = "main"
type = "terminal"
directory = "~/code-repos/github/coalesce-labs/catalyst"
commands = [
"~/code-repos/github/coalesce-labs/catalyst/plugins/dev/scripts/launch-worktree-tab.sh --project catalyst pm main",
]

The launcher handles: worktree reuse (idempotent — creates if missing, opens if exists), direnv activation, session-name export, and launching catalyst-claude.sh.

name = "Catalyst 🆕 New Worktree"
title = "Catalyst: {{branch}}"
color = "magenta"
[[panes]]
id = "main"
type = "terminal"
directory = "~/code-repos/github/coalesce-labs/catalyst"
commands = [
"~/code-repos/github/coalesce-labs/catalyst/plugins/dev/scripts/launch-worktree-tab.sh --project catalyst '{{branch}}' main '{{description}}'",
]
[params.branch]
type = "text"
description = "Branch/worktree name (e.g. CTL-72, fix-auth)"
[params.description]
type = "text"
description = "Optional short description. Leave blank for none."

The description is sanitized (non-alnum/dash → dash) and appended to the session name. Example input branch=CTL-64, description=fix auth flow → session name catalyst_CTL-64_fix-auth-flow.

name = "Catalyst 🔀 Worktree"
title = "Catalyst: {{worktree}}"
color = "magenta"
[[panes]]
id = "main"
type = "terminal"
directory = "~/catalyst/wt/catalyst-workspace/{{worktree}}"
commands = [
"export CATALYST_WARP_NAME=catalyst_{{worktree}} CATALYST_WARP_REMOTE=catalyst_{{worktree}}",
"direnv allow . && eval \"$(direnv export zsh)\"",
"yes | humanlayer thoughts init --profile $HUMANLAYER_PROFILE --directory $HUMANLAYER_DIRECTORY 2>/dev/null; humanlayer thoughts sync",
"~/code-repos/github/coalesce-labs/catalyst/plugins/dev/scripts/trust-workspace.sh \"$(pwd)\"",
"git status",
]
[params.worktree]
type = "branch"
description = "Pick the branch whose worktree you want to open"

The type = "branch" makes Warp show a git branch picker populated from the worktree directory. Unlike the New Worktree tab, this does not auto-launch Claude — it drops you in a shell so you can inspect state first. Run catalyst-claude.sh manually when ready.

name = "Catalyst 🚀 Orchestrator"
title = "Catalyst: orchestrate"
color = "magenta"
[[panes]]
id = "main"
type = "terminal"
directory = "~/code-repos/github/coalesce-labs/catalyst"
commands = [
"~/code-repos/github/coalesce-labs/catalyst/plugins/dev/scripts/launch-orchestrator-tab.sh --project catalyst '{{tickets}}'",
]
[params.tickets]
type = "text"
description = "Use + for spaces: CTL-50+CTL-51, --cycle+current, --project+Architecture+Decision+Records, --auto+5"

The {{tickets}} param accepts all four orchestration input modes. The launcher parses the + delimited string, dispatches to setup-orchestrator.sh --tickets|--cycle|--project|--auto, and invokes /catalyst-dev:orchestrate with the appropriate flags.

launch-worktree-tab.sh [--project NAME] <worktree-name> [base-branch] [description]

Reuses an existing worktree via create-worktree.sh --reuse-existing, then execs catalyst-claude.sh. Used for both PM and new-worktree variants.

launch-orchestrator-tab.sh [--project NAME] <args-string>

Parses a +-delimited args string (one of TICKET+TICKET, --cycle+VAL, --project+NAME, --auto+N), bootstraps the orchestrator worktree via setup-orchestrator.sh, and execs catalyst-claude.sh with the appropriate /catalyst-dev:orchestrate invocation.

The wrapper around claude. Reads CATALYST_WARP_NAME and CATALYST_WARP_REMOTE from the environment and forwards them to Claude as --name and --remote-control-session-name-prefix, unless the user has explicitly passed those flags.

Shared init for Main tabs: direnv, humanlayer thoughts sync, optional project-specific setup command, trust-workspace, git fetch+status. Ships in plugins/dev/scripts/ so the generated tab configs work on any checkout of the catalyst repo.

Pre-trusts a directory in Claude Code’s ~/.claude.json so the first claude invocation in a fresh worktree skips the trust dialog. Called by open-project-tab.sh and by the existing- worktree tab template. Also ships in plugins/dev/scripts/.

Warp reads ~/.warp/tab_configs/ in raw readdir() order. On APFS, readdir() returns filename-hash order — not insertion, not alphabetical, not sortable. Numeric filename prefixes (01_, 02_, …) don’t help: they give ls a sensible order for shell-side discovery, but the visual + menu is scrambled.

There is no Warp setting, env var, or hidden preference to force sorting. This is an open limitation we’d welcome Warp addressing.

Workaround: Use visual scanning and color coding. The vertical tab sidebar (Warp → Settings → Appearance → Tab Bar → Vertical) makes this bearable — each project’s color becomes its fingerprint.

⌘P (Command Palette) searches open tabs, directories, workflows, and launch configurations — but not tab configs. We considered migrating to launch configurations (which ARE palette- searchable), but they open in a new window by default (requires ⌘⏎ to open in current window) and Warp marks them as legacy in favor of tab configs. Not worth the UX regression.

Warp supports renaming individual panes via right-click, but there is no TOML schema, escape sequence, or CLI to set pane titles programmatically. Tab titles (what shows in the tab bar) work — they’re set by Claude via the --name flag which emits an OSC terminal-title escape.