plugins/dev/skills/setup-warp/SKILL.md
Interactively configure Warp terminal as a Catalyst launcher. Checks Warp install, detects projects, interviews the user for display details (name/emoji/color/variants) and generates ~/.warp/tab_configs/*.toml files with session-naming and remote-control wiring. Idempotent — re-run to add or update projects.
npx skillsauth add coalesce-labs/catalyst setup-warpInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Configure Warp terminal to work as a Catalyst launcher. Scan the user's machine for projects,
interview them, and generate ~/.warp/tab_configs/*.toml files following the "catalyst quartet"
pattern (main + PM + new-worktree + worktree + orchestrator), with colors, emoji, and session-name
wiring so Claude's in-UI session name, terminal title, and remote-control name all match the Warp
tab.
+ menu order is not controllable. Warp reads ~/.warp/tab_configs/ in raw
readdir() order; on APFS this is filename-hash order (not insertion, not alphabetical, not
sortable). We still use NN_ numeric prefixes so ls gives coherent shell-side order. The visual
+ menu is scrambled — that's a Warp limitation, not ours. We'll offer to file a feature request
at the end.⌘P searches open tabs, directories, and launch
configurations — not tab configs. Migrating to launch_configurations was considered and rejected
because they open in a new window by default and are marked legacy by Warp.CATALYST_WARP_NAME +
CATALYST_WARP_REMOTE so catalyst-claude.sh forwards them to claude --name +
--remote-control-session-name-prefix. If the user doesn't use catalyst-claude.sh wrapper, the
naming won't propagate.if [[ ! -d "/Applications/Warp.app" ]]; then
echo "MISSING"
fi
If missing, use AskUserQuestion to ask:
Warp is not installed. Install via Homebrew (
brew install --cask warp)?
brew install --cask warp, wait for success/catalyst-dev:setup-warp." Exit cleanly.Generated TOMLs need absolute paths to launch-worktree-tab.sh and launch-orchestrator-tab.sh.
CATALYST_ROOT=""
if [[ -n "${CLAUDE_PLUGIN_ROOT:-}" ]]; then
# When skill runs from the installed plugin, CLAUDE_PLUGIN_ROOT points to plugins/dev/.
# Walk up to the repo root.
CANDIDATE="$(cd "${CLAUDE_PLUGIN_ROOT}/../.." 2>/dev/null && pwd || true)"
[[ -f "${CANDIDATE}/plugins/dev/scripts/launch-worktree-tab.sh" ]] && CATALYST_ROOT="$CANDIDATE"
fi
# Common paths fallback
for p in "$HOME/code-repos/github/coalesce-labs/catalyst" "$HOME/catalyst"; do
[[ -z "$CATALYST_ROOT" && -f "$p/plugins/dev/scripts/launch-worktree-tab.sh" ]] && CATALYST_ROOT="$p"
done
If still empty, ask the user for the path.
~/.warp/tab_configs/mkdir -p ~/.warp/tab_configs
If any *.toml files are present:
TS="$(date +%Y-%m-%d_%H%M%S)"
BACKUP="$HOME/.warp/tab_configs_backup_$TS"
mkdir -p "$BACKUP"
cp ~/.warp/tab_configs/*.toml "$BACKUP/" 2>/dev/null || true
echo "Backed up to: $BACKUP"
Tell the user the backup path so they can restore if needed.
Do NOT auto-write plist keys (the exact key name varies by Warp version). Instead, run:
defaults read dev.warp.Warp-Stable 2>/dev/null | grep -iE 'tab|sidebar' | head -10 || true
Show output and tell the user:
To enable vertical tabs (recommended when you have many tab configs): Warp → Settings → Appearance → Tab Bar → "Vertical" or "Left".
for base in "$HOME/code-repos" "$HOME/Developer" "$HOME/Projects" "$HOME/src"; do
[[ -d "$base" ]] || continue
find "$base" -mindepth 2 -maxdepth 3 -type d -name ".git" 2>/dev/null
done | xargs -I{} dirname {} 2>/dev/null | sort -u
Exclude worktree dirs (anything under $HOME/catalyst/wt/, $HOME/.warp/worktrees/).
Use AskUserQuestion with one question containing the detected project list as multi-select options (plus an "Add a path manually" option).
For each selected project, collect (in one AskUserQuestion call with multiple questions when
possible, or sequential questions):
Display name — shown in Warp menu (e.g., "Catalyst", "Adva")
Short identifier (slug) — alnum/dash only, lowercase (e.g., catalyst, bob-rozich). Default:
lowercase display name with spaces → dashes, non-alnum stripped.
Emoji — for main tab (default: 📦)
Color — Warp only accepts these 8 values: black, red, green, yellow, blue,
magenta, cyan, white. Do not offer any others — Warp rejects unknown variants with a
TOML parse error at load. Recommend against black (invisible on dark themes).
Assign by GitHub org, not per-project. Derive the org from the project path
(e.g., /Users/ryan/code-repos/github/coalesce-labs/catalyst → coalesce-labs). All repos from
the same org share one color so the vertical sidebar visually groups them. Ask the user once per
org, not once per project.
blue is reserved for PM tabs. Recommend it strongly but let the user pick something else if
they want — just warn that picking blue for an org will conflict with the PM convention (blue PM
tabs become indistinguishable from that org's rows in the sidebar). Do not offer blue in the
per-org color picker.
Variants — multi-select from:
/catalyst-dev:oneshot {{ticket}} already queued)/catalyst-dev:orchestrate)Setup command — optional init for the main tab (e.g., bun install && scripts/setup-env.sh).
Leave blank if none.
Worktree base dir — where this project's worktrees live, if worktree variants selected.
Default: $HOME/catalyst/wt/<repo-name>/<branch> following the Catalyst convention.
The + menu is scrambled regardless, but ls ~/.warp/tab_configs/ follows numeric prefix order —
so pick an order that's meaningful for shell-side discovery.
Default order: the project that owns this skill installation first (typically catalyst), then
alphabetical. Ask the user to confirm or reorder.
If tab_configs contains existing files (backed up in Phase 0.4), confirm with user:
Delete current ~/.warp/tab_configs/*.toml and regenerate? (Backup exists at $BACKUP)
On yes:
rm -f ~/.warp/tab_configs/*.toml
Compute prefix counter starting at 01. For each project in the Phase 3 order, emit each enabled variant in this order: Main, PM, New Worktree, New Worktree One-Shot, Worktree, Orchestrator.
Naming conventions:
📦, PM 📋, New Worktree 🆕, New Worktree One-Shot 🎯,
Worktree 🔀, Orchestrator 🚀blue
(cross-project convention for PM/backlog work).<slug> (main), <slug>_pm, <slug>_<branch>[_<desc>],
<slug>_<ticket> (one-shot), <slug>_<worktree>, <slug>_<tickets>.Substitute {DISPLAY}, {EMOJI}, {COLOR}, {SLUG}, {PROJECT_PATH}, {WORKTREE_BASE},
{CATALYST_ROOT}, {SETUP_CMD_SUFFIX} (either empty or 'cmd').
01_catalyst.toml)name = "{DISPLAY} {EMOJI}"
title = "{DISPLAY}"
color = "{COLOR}"
[[panes]]
id = "main"
type = "terminal"
directory = "{PROJECT_PATH}"
commands = [
"export CATALYST_WARP_NAME={SLUG} CATALYST_WARP_REMOTE={SLUG}",
"{CATALYST_ROOT}/plugins/dev/scripts/open-project-tab.sh{SETUP_CMD_SUFFIX}",
]
name = "{DISPLAY} 📋 PM"
title = "{DISPLAY}: PM"
color = "blue"
[[panes]]
id = "main"
type = "terminal"
directory = "{PROJECT_PATH}"
commands = [
"{CATALYST_ROOT}/plugins/dev/scripts/launch-worktree-tab.sh --project {SLUG} pm main",
]
name = "{DISPLAY} 🆕 New Worktree"
title = "{DISPLAY}: {{branch}}"
color = "{COLOR}"
[[panes]]
id = "main"
type = "terminal"
directory = "{PROJECT_PATH}"
commands = [
"{CATALYST_ROOT}/plugins/dev/scripts/launch-worktree-tab.sh --project {SLUG} '{{branch}}' main '{{description}}'",
]
[params.branch]
type = "text"
description = "Branch/worktree name (e.g. {TICKET_EXAMPLE}, fix-auth)"
[params.description]
type = "text"
description = "Optional short description. Leave blank for none."
{TICKET_EXAMPLE} — use a sensible example like CTL-72 for catalyst, ADV-230 for Adva, or
NEW-1 as fallback.
/catalyst-dev:oneshot)Creates the worktree AND launches Claude with the oneshot invocation pre-filled. Intended for the walk-away workflow: user types a ticket, hits enter, Claude runs the full research → plan → implement → ship pipeline autonomously.
The --prompt flag passes a literal string that Warp has already substituted ({{ticket}}).
The worktree name equals the ticket, so create-worktree.sh makes a branch matching the
ticket ID.
name = "{DISPLAY} 🎯 New Worktree One-Shot"
title = "{DISPLAY}: oneshot {{ticket}}"
color = "{COLOR}"
[[panes]]
id = "main"
type = "terminal"
directory = "{PROJECT_PATH}"
commands = [
"{CATALYST_ROOT}/plugins/dev/scripts/launch-worktree-tab.sh --project {SLUG} --prompt '/catalyst-dev:oneshot {{ticket}}' '{{ticket}}' main",
]
[params.ticket]
type = "text"
description = "Ticket ID (e.g. {TICKET_EXAMPLE}). Worktree/branch = this value; Claude auto-runs /catalyst-dev:oneshot with it."
name = "{DISPLAY} 🔀 Worktree"
title = "{DISPLAY}: {{worktree}}"
color = "{COLOR}"
[[panes]]
id = "main"
type = "terminal"
directory = "{PROJECT_PATH}"
commands = [
"{CATALYST_ROOT}/plugins/dev/scripts/launch-worktree-tab.sh --project {SLUG} '{{worktree}}' main",
]
[params.worktree]
type = "branch"
description = "Pick the branch whose worktree you want to open"
name = "{DISPLAY} 🚀 Orchestrator"
title = "{DISPLAY}: orchestrate"
color = "{COLOR}"
[[panes]]
id = "main"
type = "terminal"
directory = "{PROJECT_PATH}"
commands = [
"{CATALYST_ROOT}/plugins/dev/scripts/launch-orchestrator-tab.sh --project {SLUG} '{{tickets}}'",
]
[params.tickets]
type = "text"
description = "Use + for spaces: {TICKET_EXAMPLE}+{TICKET_EXAMPLE_2}, --cycle+current, --project+Project+Name, --auto+5"
After all files are written:
Run ls ~/.warp/tab_configs/ to show the final prefix-ordered list.
Tell the user to fully quit and relaunch Warp (not just close the window) to pick up the new configs.
Summarize what was generated (count per project, variants, session-name examples).
Offer to open a Warp feature-request URL for menu sort support:
Want to file a feature request with Warp for tab-config menu sort order? https://github.com/warpdotdev/Warp/issues/new?title=Sort%20tab%20configs%20in%20%2B%20menu
Point to the website guide at https://<docs-host>/guides/warp-terminal (or the local path if
offline) for the full reference.
~ in directory but absolute paths are safer.
Launcher script paths MUST be absolute (Warp's shell doesn't expand $HOME reliably before exec).catalyst-claude.sh: The env-var-to---name forwarding happens in
that wrapper. If a project doesn't use catalyst-claude.sh (rare), the session naming won't flow
through.testing
Phase-agent that fixes a failing verify verdict so the pipeline self-heals instead of stalling to needs-human (CTL-653). Reads `${ORCH_DIR}/workers/<ticket>/verify.json`, fixes the `findings[]` (every severity:"high" plus the regression_risk drivers) directly via Edit/Write, commits the remediation, and emits `phase.remediate.complete.<ticket>`. The scheduler's router then re-dispatches `verify` to re-check (the verify⇄remediate cycle, cap 3). Dispatched as a `claude --bg` job by `phase-agent-dispatch`, which invokes it via slash command — hence `user-invocable: true`.
development
Phase agent for the verify step of the 9-phase orchestrator pipeline (CTL-450). NEW skill — has no canonical wrapper. Runs read-only adversarial verification against the implement-phase diff: tsc, tests, lint, security scan, reward-hacking scan, code review, test coverage, silent-failure hunt. Writes ${ORCH_DIR}/workers/<TICKET>/verify.json then emits phase.verify.complete.<ticket>. Reads phase-implement.json as its prior-phase artifact. NEVER writes application code — only test files allowed. Spawned via phase-agent-dispatch via slash command — hence `user-invocable: true`.
tools
--- name: phase-triage description: Phase agent that triages a Linear ticket — expands acronyms, classifies (feature/bug/docs/refactor/chore), identifies dependencies, estimates scope, writes triage.json, and posts a triage analysis comment to Linear. Triage completion is signaled by that comment plus the local triage.json — there is no `triaged` label. Emits phase.triage.complete.<TICKET> on success and phase.triage.failed.<TICKET> on error. Dispatched by the phase-agent orchestrator (CTL-452)
testing
Phase agent for the review step of the 9-phase orchestrator pipeline (CTL-450). Wraps the /review skill (gstack) — explicitly skips /ultrareview per user decision. Reads verify.json from the prior phase, runs /review against the diff, writes ${ORCH_DIR}/workers/<TICKET>/review.json, and creates a remediation commit for any HIGH-severity finding that has a deterministic fix. Emits phase.review.complete.<ticket>. Spawned via phase-agent-dispatch via slash command — hence `user-invocable: true`.