CommunityCodierung & Entwicklunggithub.com

cmux-delegate

Übergibt ein unabhängiges Problem, das während einer Aufgabe aufgetaucht ist, an eine eigene Claude Code-Sitzung in einem neuen cmux-Arbeitsbereich – mit automatisch gesammeltem Kontext. Die Sitzung bearbeitet das Problem allein (Issue → Worktree → PR). Nicht zum Aufteilen der aktuellen Aufgabe gedacht.

Was ist cmux-delegate?

Die AI-Fertigkeit „cmux-delegate“ ermöglicht es, ein unabhängiges Problem, das während der Bearbeitung einer Hauptaufgabe auftaucht, nahtlos an eine separate Claude Code-Sitzung in einem neuen cmux-Arbeitsbereich zu delegieren. Sie sammelt automatisch den relevanten Kontext (Git-Metadaten, Reasoning aus der aktuellen Konversation) und startet eine eigenständige Sitzung, die das Problem von der Erstellung eines Issues über die Erstellung eines Worktrees bis hin zum Pull Request vollständig selbstständig bearbeitet. Die Fertigkeit unterstützt die Verwendung verschiedener Claude-Account-Profile, die Wiederverwendung bestehender Sitzungen und die parallele Verteilung mehrerer unabhängiger Probleme. Wichtig ist, dass die Fertigkeit ausschließlich für Probleme gedacht ist, die als eigenständiges Issue existieren können; sie ist nicht zum Aufteilen der aktuellen Aufgabe oder für Unteraufgaben gedacht, deren Ergebnisse zurückgemeldet werden müssen. Die Kommunikation erfolgt streng „Fire-and-Forget“: Nach der Delegierung gibt es keine Rückmeldung oder Überwachung durch die ursprüngliche Sitzung.

Funktioniert mit✓Claude Code✓Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/devseunggwan/praxis/tree/HEAD/skills/cmux-delegate

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht cmux-delegate?

Übersicht

Eine Fertigkeit, die ein unabhängiges Problem, das während einer Aufgabe aufgetaucht ist, an eine andere Sitzung übergibt. Sie sammelt automatisch den aktuellen Arbeitskontext (Git-Metadaten + aus der Konversation synthetisierten Reasoning-Kontext), öffnet eine unabhängige Claude Code-Sitzung in einem cmux-Arbeitsbereich, und diese Sitzung bearbeitet das Problem (Issue → Worktree → PR) eigenständig bis zum Ende. Die Wiederverwendung einer vorhandenen Sitzung, separate Account-Profile und die parallele Verteilung mehrerer Probleme werden unterstützt.

Kernprinzipien:

  • Der Prompt wird immer über eine Datei übermittelt. Inline mit -p ist streng verboten (vermeidet Probleme mit Shell-Escaping).
  • Wenn der Benutzer eine Sitzung/einen Account explizit nennt, wird dies buchstabengetreu befolgt. Keine willkürliche Neuinterpretation.
  • Die Einheit der Delegierung ist ein unabhängiges Problem. Kann es als Issue stehen, delegiere es; wenn nicht, ist es kein Delegierungsziel, sondern ein Teil, der in dieser Sitzung erledigt werden muss.
  • Mehrdeutigkeit wird vor dem Start beseitigt, nicht danach. Es kommt nichts zurück, um nachzufragen, daher werden die Fertigstellungsbedingung, der Umfang und die Vorgehensweise als Befehle, Pfade und Nummern in den Prompt aufgenommen (Schritt 2.6).
  • Feuer und vergiss. Delegieren ist das Ende – der Arbeiter meldet dem Delegierer nichts zurück, und der Delegierer überwacht oder beurteilt den Arbeiter nicht. Der Benutzer sieht das Ergebnis direkt in diesem cmux-Tab.

Wann verwenden

Verwende dies, wenn ein Problem, das getrennt von dem ist, was du gerade tust, während der Aufgabe auftaucht.

  • Du hast während der Implementierung einen unabhängigen Fehler gefunden und möchtest ihn abtrennen
  • Ein Review-Fund liegt außerhalb des Umfangs dieses PRs und geht in ein Folge-Issue
  • Mehrere solcher Probleme haben sich angesammelt und jedes soll in eine andere Sitzung gehen (--distribute)

Delegierungsfähigkeit

Kann dieser Punkt als ein unabhängiges Issue stehen – dieser einzelne Test entscheidet.

BefundHandhabung
Steht als Issue (hat eigene Reproduktion, Umfang und Fertigstellungsbedingungen und kann fortgesetzt werden, auch wenn meine Arbeit unvollendet ist)Delegieren
Kann nicht als Issue stehen (es ist ein Teil meiner aktuellen Arbeit, und meine Arbeit ist erst abgeschlossen, wenn sein Ergebnis zurückkommt)Nicht delegieren – in dieser Sitzung erledigen

Ein Punkt, dessen Ergebnis zurückkommen muss, um zusammengeführt zu werden, ist kein Delegierungsziel. Das ist die Aufgabe eines Subagenten, und die Verwendung dieser Fertigkeit dafür bedeutet, einen Bericht vom Arbeiter anzufordern – eine Anforderung, die in der Vergangenheit die Erfassung von Fertigstellungsberichten (#894) und das Entscheidungsgatter (#984) eingebracht hat. Beide wurden in #1130 entfernt.

Eingaben

Gib das Issue an, das delegiert werden soll, durch seine Issue-Nummer.

/cmux-delegate "#1140 auth 토큰 갱신 실패" --model opus
/cmux-delegate "#1141 리뷰에서 나온 후속 항목" --session claude-2
/cmux-delegate "별건 3개: #1140, #1141, #1142" --account claude-2 --distribute

Das Issue muss zum Zeitpunkt der Delegierung bereits existieren. Wenn es noch kein Issue gibt, erstelle es in dieser Sitzung vor der Delegierung – die Issue-Erstellung ist ein Verfahren, das eine Genehmigung erfordert, daher wird es nicht an den Arbeiter übergeben. Wenn nur eine Beschreibung ohne Nummer übergeben wird, kann der Arbeiter nicht wissen, an welches Issue der PR angehängt werden soll.

Argumente

ArgumentStandardBeschreibung
<task>(erforderlich)Beschreibung der zu delegierenden Aufgabe
--modeljev-Route, sonst sonnetProvider:Modell-Notation. fable/opus/sonnet/haiku = claude. Unterstützt auch claude, claude:opus, codex (= gpt-5.6-terra, effort medium), codex:gpt-5.6-sol, codex:gpt-5.6-sol:xhigh, claude:opus:low / opus:low (claude --effort, einer von low/medium/high/xhigh/max; keiner genannt → keiner übergeben), gemini, gemini:flash. Siehe Projekt ARCHITECTURE.md Provider Routing.
--cwdaktuelles VerzeichnisArbeitsverzeichnis für die neue Sitzung
--max-budget-usd—Nicht unterstützt (#1054). Ein Nur-Druck-Flag, kann daher nicht mit einem interaktiven Arbeiter verwendet werden. Falls angegeben, ignoriere es nicht stillschweigend – informiere den Benutzer
--account(Standard-Account)Claude-Account-Profil (z. B. claude-2 → CLAUDE_CONFIG_DIR=~/.claude-2)
--session(neu erstellen)In einen vorhandenen Arbeitsbereich liefern (Name oder Workspace-Referenz)
--distributefalseParallele Verteilung auf Issue-Ebene. Keine Aufteilung einer einzelnen Aufgabe
--permission-mode—Entfernt (#1054). Der delegierte Arbeiter ist eine normale Sitzung, daher verwendet er die normalen Standardeinstellungen des Benutzers

Prozess

Schritt 1: Argumente parsen

Parse die Argumente aus {{ARGUMENTS}}:

args = parse("{{ARGUMENTS}}")
cwd = args.cwd || $(pwd)
# Budget-Flag akzeptieren, aber nicht weiterleiten; dem Benutzer mitteilen, dass es empfangen wurde (#1054).
# Stillschweigendes Fallenlassen würde den Benutzer glauben lassen, eine Obergrenze sei aktiv.
if args["max-budget-usd"]: warn("--max-budget-usd wird nicht auf interaktive Arbeiter angewendet (#1054)")
account = args.account || ""
session = args.session || ""
distribute = args.distribute || false
task = args.task (restlicher Text nach Flags)
short_task = task[:30], bereinigt auf [a-zA-Z0-9가-힣 -] (für cmux-Workspace-Namen)
timestamp = Epochensekunden + PID (z. B. 1744163800-12345) zur Kollisionsvermeidung

# Ein explizites --model wird niemals überschrieben. Ohne eines wählt jev den Arbeiter;
# bei {"source": "fallback"} bleibt der Standard sonnet (#1481).
route_source = "explicit"
if args.model: model = args.model
else:
  route = json(python3 "${CLAUDE_PLUGIN_ROOT}/skills/cmux-delegate/jev-route.py" "$task")
  route_source = route.source
  if route.source == "jev":
    model = route.provider == "claude" ? route.tier : route.provider
  else:
    model = "sonnet"

# Provider-Auflösung (aus der Projekt-ARCHITECTURE.md Provider Resolution Logic)
if model matches /^(codex|gemini)(?::(.+))?$/:
  provider = match[1]           # "codex" or "gemini"
  sub_model = match[2] || ""    # "" or "gpt-5.6-sol:xhigh" or "flash" (erster Doppelpunkt entfernt)
elif model matches /^(fable|opus|sonnet|haiku)(?::[A-Za-z]+)?$/:
  provider = "claude"
  sub_model = model             # "opus" or "opus:low"; der effort wird unten abgetrennt
elif model matches /^claude(?::(.+))?$/:
  provider = "claude"
  sub_model = match[1] || ""
else:
  provider = "claude"
  sub_model = model

# codex fällt nie auf das Standardmodell der Konfiguration zurück: ein nacktes `codex`
# (explizit oder von jev ausgewählt) bekommt terra, und ein aufgelistetes Modell erhält
# seinen effort, es sei denn, `codex:<model>:<effort>` benennt einen (#1483).
CODEX_DEFAULT_MODEL = "gpt-5.6-terra"
CODEX_EFFORT = {"gpt-5.6-luna": "low", "gpt-5.6-terra": "medium", "gpt-5.6-sol": "high"}
effort = ""
if provider == "codex":
  sub_model, _, effort = sub_model.partition(":")
  sub_model = sub_model || CODEX_DEFAULT_MODEL
  effort = effort || CODEX_EFFORT.get(sub_model, "")
  # Schritt 4 interpoliert beide unzitiert in einen Bash-Wrapper, daher würde ein Wert wie
  # `xhigh; touch /tmp/x` ausgeführt werden. Lehne alles ab, was kein einfacher
  # Bezeichner ist, anstatt zu zitieren, was `"` und `$( )` immer noch umgehen würden.
  if sub_model does not match /^[A-Za-z0-9._-]+$/: abort "ungültiges codex-Modell"
  if effort and effort does not match /^[A-Za-z0-9._-]+$/: abort "ungültiger codex-Reasoning-Effort"

# claude akzeptiert einen effort nur, wenn einer genannt wird: `claude:<tier>:<effort>` oder
# `<tier>:<effort>` (#1499). Es gibt keine pro-tier-Standardtabelle wie bei codex.
# Der Opus 5.5 Prompting Guide
# (https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-opus-5-5#calibrate-effort)
# sagt "Die Namen der Effort-Stufen entsprechen nicht dem gleichen Maß an Denken über
# verschiedene Modelle hinweg" und empfiehlt, mehrere Stufen pro Modell gegen die eigenen
# Auswertungen zu testen "anstatt die Einstellung zu übernehmen, die Sie auf Claude Opus 5
# verwendet haben". Daher ist hier keine Tabelle fest einprogrammiert: Unbenannt → es wird
# nichts übergeben und der Standard des Modells gilt (medium auf Opus 5.5, high auf Opus 5).
# Der Guide sagt auch: "Reservieren Sie `xhigh` und `max` für Arbeiten, bei denen Sie einen
# Qualitätsgewinn gemessen haben." Eine jev-Auswahl, die einen nackten tier ergibt, hat nie
# einen effort.
CLAUDE_EFFORTS = ["low", "medium", "high", "xhigh", "max"]
if provider == "claude":
  # Nur ein alphabetischer Schwanz nach dem letzten Doppelpunkt ist ein effort, daher eine
  # Modell-ID, die selbst einen Doppelpunkt enthält (Bedrock `…-v1:0`, eine ARN, die auf
  # `…:application-inference-profile/<id>` endet), wird unverändert durchgelassen.
  # Ein Doppelpunkt direkt nach dem Provider (`claude::high`, `claude::`) ist höchst-
  # wahrscheinlich ein Tippfehler von `claude:opus:high`; es wird vor der effort-Aufteilung
  # geprüft, die sonst `claude::high` als das Standardmodell mit high lesen würde. Jede
  # Form mit doppeltem Doppelpunkt wird gleich abgebrochen (`opus::low` unten).
  if sub_model starts with ":": abort "ungültiges claude-Modell"
  if sub_model matches /^(.*):([A-Za-z]+)$/:
    sub_model, effort = match[1], match[2]
  # Ein fehlerhafter Schwanz (`opus:`, `opus::low`, `opus:low:high`) darf nicht als
  # Modellname an die CLI gelangen: keine Modell-ID endet mit `:` oder ist ein tier-Alias
  # gefolgt von `:`.
  if sub_model ends with ":" or sub_model matches /^(fable|opus|sonnet|haiku):/: abort "ungültiges claude-Modell"
  # Schritt 4 setzt das Modell in einfache Anführungszeichen, daher muss der Zeichensatz `'`
  # und jedes Shell-Metazeichen ausschließen; er erlaubt `:` `/` für Bedrock-IDs und ARNs,
  # `@` für Vertex-IDs (`claude-sonnet-4-5@20250929`) und `[]` für das `[1m]` Kontextsuffix.
  # Unzitiert wäre `opus[1m]` ein Glob und würde zu `opus1` werden, sobald eine solche Datei
  # im aktuellen Verzeichnis ist, daher bleiben die Anführungszeichen.
  if sub_model does not match /^[A-Za-z0-9._:@\/\[\]-]*$/: abort "ungültiges claude-Modell"
  # `claude --effort bogus` warnt nur und läuft mit dem Standard-Effort, daher würde die CLI
  # einen Tippfehler nicht abfangen; diese Prüfung ist die einzige.
  if effort and effort not in CLAUDE_EFFORTS: abort "ungültiger claude-effort '{effort}' (erwartet low|medium|high|xhigh|max)"

# Vorabprüfung: Prüfen, ob die Provider-CLI verfügbar ist
if ! command -v "$provider" &>/dev/null:
  warn "⚠ ${provider} CLI nicht gefunden, Fallback auf claude:sonnet"
  provider = "claude"
  sub_model = "sonnet"
  effort = ""

Schritt 1.5: Sitzungsauflösung

Entscheide, ob eine vorhandene Sitzung verwendet werden soll.

if session ist angegeben:
  1. cmux list-workspaces → nach Name oder Ref abgleichen
  2. Treffer gefunden → cmux send-Modus (Schritt 5b)
  3. kein Treffer → Fehler ausgeben "Sitzung '{session}' nicht gefunden" und anhalten
else:
  → bestehendes Verhalten (neuer Arbeitsbereich, Schritt 5a)

Schritt 1.6: Account-Auflösung

Entscheide das Account-Profil.

if account ist angegeben:
  # Das Account-Profil wird über die Umgebungsvariable CLAUDE_CONFIG_DIR gesetzt
  # z. B. --account claude-2 → CLAUDE_CONFIG_DIR=~/.claude-2
  claude_env = "CLAUDE_CONFIG_DIR=~/.{account}"
  
  # Validierung: Prüfen, ob das Konfigurationsverzeichnis existiert
  if not exists(~/.{account}):
    Fehler ausgeben "Account-Profilverzeichnis ~/.{account} nicht vorhanden" und anhalten
else:
  claude_env = ""  # Standard-Account verwenden

Schritt 2: Kontext sammeln

Sammle automatisch den Kontext der aktuellen Konversation und des Projekts. Jeder Befehl wird auch bei Fehlern fortgesetzt (2>/dev/null).

Zu sammelnde Informationen:

# 1. Git-Status
BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
COMMITS=$(git log --oneline -5 2>/dev/null || echo "no git history")
DIFF_STAT=$(git diff --stat HEAD 2>/dev/null || echo "no changes")

# 2. Liste der geänderten Dateien (gegen Basis-Branch)
BASE_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||')
BASE_BRANCH=${BASE_BRANCH:-main}
CHANGED_FILES=$(git diff --name-only $(git merge-base HEAD "origin/$BASE_BRANCH" 2>/dev/null || echo HEAD~5)..HEAD 2>/dev/null || echo "unknown")

# 3. PR-Informationen (falls vorhanden)
PR_INFO=$(gh pr list --head "$BRANCH" --json number,title,url 2>/dev/null || echo "no PR")

# 4. PR-Review-Kommentare (falls vorhanden)
REVIEW_COMMENTS="0"
PR_NUM=$(gh pr list --head "$BRANCH" --json number -q '.[0].number' 2>/dev/null || echo "")
if [ -n "$PR_NUM" ]; then
  REVIEW_COMMENTS=$(gh api "repos/$(gh repo view --json nameWithOwner -q '.nameWithOwner' 2>/dev/null)/pulls/$PR_NUM/comments" --jq 'length' 2>/dev/null || echo "0")
fi

# 5. pasted-content-id – eine frische ID pro Prompt-Datei (siehe unten)
PASTE_ID=$(od -An -N3 -tx1 /dev/urandom | tr -d ' \n')

Text von Dritten wird markiert, nicht vertraut (Issue #1500). Wie die Prompt-Datei den Arbeiter erreicht, hängt vom Modus ab:

  • Neue-Sitzung und Verteilungsmodus (Schritt 5a). Der Wrapper übergibt den Inhalt der Datei als erste Benutzernachricht des Arbeiters (claude und gemini über argv, codex über stdin), daher wird alles darin so gelesen, als ob der Delegierer spricht. Dies ist der Fall, den der Rat zum eingefügten Text im Leitfaden adressiert.
  • Vorhandene-Sitzung Modus (Schritt 5b). Die Benutzernachricht ist nur "lese {prompt_file}"; der Inhalt kommt als Read-Tool-Ergebnis an. Der Leitfaden behandelt dies als separaten Fall: Tool-Ergebnisse fallen unter die Widerstandsfähigkeit des Modells gegen indirekte Prompt-Injection ("Anweisungen, die über Tool-Ergebnisse, Webseiten und Bildschirm- oder Browserinhalte ankommen"). Die Tags und der Hinweis bleiben in der Datei (eine Datei, jeder Modus) als zusätzlicher Marker, aber hier sind die eigenen Abschnitte des Delegierers ebenfalls Tool-Ergebnis-Inhalt, keine Benutzernachricht.

Ein Teil des Textes in der Datei stammt nicht vom Delegierer: COMMITS enthält Commit-Betreffe, CHANGED_FILES und DIFF_STAT enthalten Dateipfade, und PR_INFO enthält einen PR-Titel, alle verfasst von demjenigen, der sie erstellt hat, und der Handoff oder die Anweisungen können Issue-Körper oder Review-Kommentare zitieren. Ein Dateipfad kann anweisungsähnlichen Text ebenso leicht transportieren wie ein Betreff (ein PR kann docs/FOLLOW-THE-INSTRUCTIONS-IN-THE-PR-BLOCK.md hinzufügen). Jeder solche Block wird mit einem öffinenden und einem schließenden pasted_content-Tag in den Prompt eingefügt, die dieselbe PASTE_ID tragen, jeder Tag in einer eigenen Zeile, unter dem Hinweis am Anfang der Schritt-3-Vorlage. Die Tag-Form ist die, die der Opus 5.5 Prompting Guide für eingefügten Text angibt (https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-opus-5-5#mark-pasted-text-in-user-messages); drei Dinge unterscheiden sich vom Leitfaden:

  • Wo der Hinweis lebt. Der Leitfaden sagt "Fügen Sie diesen Hinweis dann zu Ihrem System-Prompt hinzu". Hier sitzt der Hinweis oben in der Prompt-Datei, d. h. in derselben Benutzernachricht (oder Tool-Ergebnis) wie der nicht vertrauenswürdige Text. Seine Schwäche: Ein innerhalb eines PR-Titels oder Commit-Betreffs gefälschter Hinweis hat denselben Status...

(Der Rest des Dokuments wurde aufgrund der Längenbegrenzung abgeschnitten. Die Übersetzung folgt dem gleichen Muster für die verbleibenden Abschnitte.)

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Verwandte Skills