Skip to content

Releases: mostafasudo/worktree-compose

worktree-compose 1.0.0

Choose a tag to compare

@mostafasudo mostafasudo released this 24 Oct 07:55

The first stable release: worktree stacks keep a stable identity, cleanup no longer touches what it doesn't own, every command runs without a shell, and Podman is supported.

Thanks to @DarellYuhu for monorepo env targeting (#10), to @KennyCandra for the original COMPOSE_PROJECT_NAME proposal (#3), to @kevmtt for reporting #7, and to @geniuskamo for reporting #9.

Upgrading from 0.2

  • Node.js 20 or newer is required (was 18).
  • Install globally and type wtc. An unrelated npm package is named wtc, so npx wtc without a global install runs that package. Use npm install -g worktree-compose, or npx worktree-compose <command> for a one-off. Update MCP configs to {"command": "wtc", "args": ["mcp"]} (or {"command": "npx", "args": ["-y", "worktree-compose", "mcp"]}).
  • Indices are stable. On the first run, existing worktrees get the same positional indices 0.2 used, and a worktree whose 0.2 stack is running adopts that stack's index and project, so running stacks are picked up, not duplicated. After that an index never changes: removing a worktree no longer renumbers the ones after it, and a new worktree takes the lowest free index. Identities are stored in .git/wtc/state.json.
  • Deleted worktrees become orphans. A worktree removed with git worktree remove or rm -rf shows in wtc list as (removed), and its index stays reserved until wtc prune (or wtc clean) tears its stack down.
  • wtc stop keeps containers. It runs compose stop instead of compose down: containers and all volumes are kept, wtc start resumes them, and wtc list shows them as exited. restart is now compose stop followed by start with --remove-orphans.
  • wtc clean keeps worktrees that hold work. Worktrees with uncommitted changes (other than files wtc wrote), commits on a detached HEAD that nothing else reaches, unpushed submodule commits, or a lock are kept unless you pass --force; the main checkout and the current worktree are never removed. Kept worktrees' stacks are still torn down with down -v (their volumes are deleted).
  • wtc clean only removes stacks it owns. It no longer removes every container named *-wt-*; leftovers are swept only for stacks this checkout owns, one at a time. Same-named stacks of other checkouts are listed, never removed. Stale 0.2 leftovers whose worktree directory is gone: wtc clean --sweep (stacks that still have containers; leftover volumes with no container — e.g. after 0.2's wtc stop, which kept named volumes — are listed for you to remove with docker volume rm).
  • Env keys are rewritten in place. A key that already exists in the env file (e.g. POSTGRES_PORT) is rewritten where it is instead of being repeated in the wtc block, and the root env file now gets COMPOSE_PROJECT_NAME. ${VAR} placeholders in overrides are replaced everywhere in a value, not just the first time.
  • wtc promote is stricter. It aborts when the target branch committed changes to the same files since the worktree branched (promoting would revert them; --force overrides), and untracked files in the target now count as conflicts.
  • MCP wtc_list output. content[0] is still a pure JSON array (the same as wtc list --json); rows gain running, total, url, orphan, and unavailable, status can be up, partial, exited, down, or ?, orphan rows are included, and warnings come as separate content items.
  • MCP selectors. indices and wtc_promote's index accept strings (branch, directory name, path, .) as well as numbers.
  • Exit codes. stop, clean, and prune exit 1 when a stack or removal fails; MCP tools return isError: true.
  • Agent skill. Install it with wtc skill --install instead of symlinking SKILL.md.

Added

  • Stable worktree identity: each worktree's index and compose project are recorded at first sight in .git/wtc/state.json (locked, atomic writes) and survive branch renames and git worktree move (an id is kept in the worktree's git admin dir). 0.2 stacks are adopted by position or by the directory compose ran in (#9).
  • Orphan tracking: (removed) rows in wtc list, reserved indices, and wtc prune [--dry-run] / MCP wtc_prune to tear orphaned stacks down. A worktree git still lists is never an orphan: a locked worktree whose directory is missing (an unmounted drive) keeps its index, record, and stack, shown as (locked, missing on disk).
  • Worktree selectors for start, stop, restart, promote, and the MCP tools: index, branch, directory name, path, or . (the worktree you are in), with ambiguity errors.
  • COMPOSE_PROJECT_NAME written into each worktree's root env file, so plain docker compose in the worktree (with the default .env) reaches the same stack; ${COMPOSE_PROJECT_NAME} interpolation in envOverrides and workspaceEnvOverrides (#2; original proposal by @KennyCandra in #3).
  • Podman support and compose engine detection: docker compose → podman compose → docker-compose → podman-compose, preferring an engine whose daemon answers. Override with the WTC_COMPOSE_COMMAND environment variable or the composeCommand config key. OrbStack and Colima work through the docker CLI; global flags such as --context are honored by status checks and cleanup too (#1).
  • Monorepo env targeting: envFile / --env, workspaces / --workspace, and workspaceEnvOverrides; allocated ports exported into the compose process environment; existing env keys rewritten in place. By @DarellYuhu in #10.
  • wtc doctor [--json] and MCP wtc_doctor: git, repository layout, compose file, config, engine and daemon, port isolation, isolation-breaking settings, collisions, missing worktrees, orphans, and allocated ports already in use.
  • Isolation warnings for container_name, and for volumes and networks with a fixed name: or external: true.
  • wtc list --json, with running/total counts and partial and exited states.
  • wtc start / wtc restart --no-build (MCP build: false).
  • wtc clean --dry-run, --force, --keep-worktrees, and --sweep (MCP dryRun, force, keepWorktrees, sweep).
  • wtc promote --force (MCP force).
  • wtc skill [--install] [--dir <path>]; SKILL.md now ships in the package.
  • wtc.schema.json for .wtcrc.json editor completion: "$schema": "https://unpkg.com/worktree-compose/wtc.schema.json".
  • MCP: tool annotations (read-only/destructive; wtc_list and wtc_doctor never write anything), progress notifications, cancellation that stops the running compose command (a request cancelled while it waits its turn never runs), serialized stack-changing tools, and isError results with compose's error output.
  • Support for bare repositories with worktrees, submodules, and --separate-git-dir checkouts. The main checkout is remembered where git can't always name it (a bare repo's default-branch worktree mid-rebase, a --separate-git-dir repo seen from a linked worktree); when it is unknown, start, restart, and clean refuse instead of guessing.
  • CI on Node.js 20, 22, and 24; releases are published from GitHub Actions with npm trusted publishing.

Changed

  • Every command resolves the main checkout, even when run from a linked worktree (where agents and MCP servers usually run): the repo name, and therefore every project name, stays the same, and compose, config, and env files are always read from main.
  • wtc stop runs compose stop (containers and volumes are kept); wtc restart runs compose stop, then start with up -d --remove-orphans, and checks env options and selectors before stopping anything.
  • wtc clean tears stacks down with down -v --remove-orphans (anonymous volumes included), removes only worktrees without work of their own unless --force, sweeps only resources of stacks it owns, one at a time, and keeps the records (and indices) of worktrees that remain.
  • wtc promote takes a selector, reads changes with -z and --no-renames (a rename deletes the old path in the target), and checks every path before writing anything.
  • MCP tools use registerTool; wtc_list returns full rows; tool handlers never throw.
  • Port collision warnings consider the indices actually in use (live worktrees and orphans).
  • Errors name the failing command and include the tail of its error output.
  • stop, clean, and prune exit 1 when something failed; MCP tools return isError: true.
  • Node.js 20 or newer is required (commander 14 needs it).
  • Docs use wtc (global install) instead of npx wtc; the homepage is now https://www.worktree-compose.com.

Fixed

  • Removing a worktree renumbered every worktree after it: their stacks were orphaned and start created new stacks on new ports (#9).
  • wtc clean's unanchored -wt- filter matched other repositories' containers, and one failed removal discarded a whole batch (#9).
  • wtc clean force-removed worktrees with uncommitted work.
  • Running wtc from a linked worktree used that worktree's directory name as the repo name and synced files from it.
  • wtc mcp could write log lines to stdout, corrupting the...
Read more