Skip to content
Development
Command

/worktree

Worktree lifecycle management - create, list, remove, info on interactive worktrees

From plugin
lets-workflow
1622 skills15 agents22 commands
Install
$ npx -y skills add restarter/lets-workflow --agent claude-code

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/worktree

Context preview

What this command does when you run it.

Worktree lifecycle management - create, list, remove, info on interactive worktrees

Command definition

worktree.md
description: Worktree lifecycle management - create, list, remove, info on interactive worktrees

Worktree Management

Thin dispatcher for interactive parallel worktrees. All filesystem/git work lives in the Go subcommand `lets worktree` (`cli/internal/worktreecmd/`); this skill captures user intent via `AskUserQuestion`, shells out with `--json`, and renders the result.

**Interactive worktrees only.** Agent worktrees (`isolation: worktree`) use native Claude Code behavior — not this command.

> **IMPORTANT:** If the spec below invokes any deferred tool (e.g. `AskUserQuestion`), you MUST load and call it as specified. Never skip the call, never substitute a default answer of your own — the tool invocation is part of the contract. This is critical.

Step 1: Determine Subcommand

**If argument provided** (e.g., `/lets:worktree create auth-feature`), parse it:

  • `create <name>` -> go to Create. **First strip any `--cmux` / `--no-cmux` / `--tmux` / `--no-tmux` / `--auto` / `--flow <value>` / `--branch <ref>` token** out of the argument and carry them as overrides (`--cmux`/`--no-cmux`/`--tmux`/`--no-tmux` = launcher; `--auto` = autonomous permission mode; `--flow plan|plan-workflow` = which command the launch lands in — all for Step C3.5; `--branch <ref>` decouples the attached/created branch from the dir name — Step C2). Bind the remainder as `<name>` (so `create auth --flow plan-workflow --auto` => name `auth`, not the flags; `create pwa-46696 --branch feature/pwa-46696` => name `pwa-46696`, branch `feature/pwa-46696`).
  • `list` -> go to List
  • `remove <name>` -> go to Remove
  • `info` -> go to Info

**If no argument**, use **AskUserQuestion**:

AskUserQuestion(
  questions=[{
    question: "What do you want to do with worktrees?",
    header: "Action",
    options: [
      { label: "Create", description: "Create a new worktree for parallel work" },
      { label: "List", description: "Show all active worktrees" },
      { label: "Remove", description: "Remove a worktree and clean up" },
      { label: "Info", description: "Show current worktree status" }
    ],
    multiSelect: false
  }]
)

---

Create

Create an interactive worktree. The Go subcommand owns the guard, name validation, `.gitignore` ensure, `git worktree add`, symlinks (`.lets/`, `.beads/.env`), verify, and rollback. The skill drives the user choices.

Optional launcher override on the argument: `--cmux` / `--no-cmux` / `--tmux` / `--no-tmux` force the launcher for this run (otherwise `$LETS_LAUNCHER` decides — see Step C3.5).

Optional `--auto`: launch the session in `claude --permission-mode auto` (autonomous — auto-approves low-risk work, still gates push / PR / close / external per LETS AUTO MODE rules). Maps ONLY to `--permission-mode auto`, **never** `bypassPermissions`. Applies to the launcher paths in Step C3.5 / C4 (see Step C3.5).

Optional `--flow plan|plan-workflow`: which `/lets:*` command the spawned session lands in. `--flow` ONLY swaps the launch `--command` string — all other steering stays in the tracker task (the launch stays uniform/reproducible). Default (no `--flow`) → `/lets:start <id>` (today's behavior). `--flow plan` → `/lets:plan <id>` (interactive planning in the worktree; the human drives). `--flow plan-workflow` → `/lets:plan-workflow <id>` (autonomous planning). Because only the command string changes, `--flow` is **launcher-agnostic** — the cmux (C3.5) and terminal (C4) paths both inherit it (so does the future tmux launcher). Composes orthogonally with `--auto`. Requires a known task id; on a **taskless** worktree, ignore `--flow` with a one-line note (and `taskless + --flow + --auto` collapses to the existing taskless `--auto` path, `claude --permission-mode auto`). **plan-workflow is PREVIEW** (needs Claude Code ≥ 2.1.154 / paid / Dynamic Workflows) — the launch string can't probe that, so the launched `/lets:plan-workflow` is responsible: if the Workflow tool is unavailable it prints the standard PREVIEW-unavailable message and the operator re-runs `--flow plan`.

Step C1: Get Name

If name not provided via argument, use **AskUserQuestion**:

AskUserQuestion(
  questions=[{
    question: "Name for the worktree? (lowercase, no spaces - used for directory and branch)",
    header: "NameMode",
    options: [
      { label: "From task", description: "Auto-generate from the current or a selected tracker task" },
      { label: "Custom", description: "Enter a custom name" }
    ],
    multiSelect: false
  }]
)

**From task:** Show the tracker's `ready` view (top 5) and let user pick a task or use the current in-progress task. Generate name as `<task-id>-<slugified-title>` (e.g., `lets-hpi.3-worktree-start`).

**Custom:** Use provided text. Slugify: lowercase, spaces to hyphens, remove special chars, max 50 chars (the Go validator allows up to 64; the skill pre-truncates to 50 to leave headroom for `worktree-` prefixes and tmux pane labels). `lets worktree create` will reject invalid names with exit 2.

**Slash branch (git-flow / Bitbucket refs).** The dir NAME must not contain `/` (it's a directory + the validator forbids it). If the user names a branch ref that contains `/` (e.g. `feature/pwa-46696`, `bugfix/x`) — or passed `--branch <ref>` on the argument — **decouple the two**: derive a slash-free dir name (replace `/` with `-`, e.g. `feature/pwa-46696` -> `feature-pwa-46696`, or just the trailing segment `pwa-46696`) and pass the original ref via `--branch` in Step C2. The Go subcommand attaches to (or creates) that ref verbatim while the worktree dir keeps the sanitized name (lets-x5ucf).

Step C2: Create

LETS_PROJECT_ROOT=$(git rev-parse --show-toplevel)
cd "$LETS_PROJECT_ROOT"
lets worktree create "$NAME" --json
# Slash branch ref decoupled from dir name (see Step C1 "Slash branch"):
#   lets worktree create "$DIR_NAME" --branch "$BRANCH_REF" --json

The Go subcommand auto-detects attach vs new-branch: if `refs/heads/<NAME>` exists, a

Read more
Ships withlets-workflow

A development workflow plugin for Claude Code Stop babysitting your AI. Start shipping with it.

Get the whole plugin, auto-invoked
Stats
16
Stars
1
Views
3
Forks
Active
Maintenance
Go
Language
MIT
License
3d ago
Last commit
5mo ago
Created

Repo: restarter/lets-workflow