Skip to main content
Glama
README.md
# wtx

**Git worktree manager with a built-in MCP server.** Create, inspect, and clean isolated workspaces from your terminal — or let your AI coding agents do it themselves.

[![CI](https://github.com/willkhinz/wtx/actions/workflows/ci.yml/badge.svg)](https://github.com/willkhinz/wtx/actions/workflows/ci.yml)
[![npm](https://img.shields.io/npm/v/wtx)](https://www.npmjs.com/package/wtx)
[![license](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)

---

Parallel AI coding agents made `git stash`-juggling obsolete — but raw `git worktree add ../foo -b foo && cd ../foo && cp ../.env .` is a chore nobody wants to repeat five times a day. `wtx` turns worktrees into a one-word workflow **for humans and for agents**:

```console
$ wtx new fix-login
✔ created worktree fix-login
  path:   ~/code/myapp/.worktrees/fix-login
  branch: wt/fix-login (new)
  copied: .env, .env.local
```

Your agent gets the same power through [MCP](https://modelcontextprotocol.io):

```json
{ "name": "create_worktree", "arguments": { "name": "fix-login", "setup": "npm install" } }
```

## Why wtx

- **One tool, two interfaces.** A fast CLI for you, an MCP server (`wtx mcp`) for Claude Code, Cursor, Codex, or any MCP-capable agent.
- **Zero dependencies.** Single Node.js binary that only shells out to `git`. Nothing to audit, nothing to break.
- **Hygiene-aware.** Every worktree shows its disk footprint and last activity. Reclaim gigabytes of stale `node_modules` clones with `wtx clean --dry-run`.
- **Safe by default.** Refuses to delete dirty worktrees, never touches the main checkout, deletes branches only when fully merged, and hides `.worktrees/` via `.git/info/exclude` (no `.gitignore` pollution).
- **Batteries included.** Copies env files into new worktrees and runs your project's setup hook automatically.

## Install

```bash
npm install -g wtx        # or: brew install wtx (planned)
```

Requires Node.js ≥ 18 and any modern `git`.

## Quickstart

```console
$ cd myapp
$ wtx new feat-search          # isolated workspace at .worktrees/feat-search on branch wt/feat-search
$ cd $(wtx path feat-search)   # jump in
$ wtx ls                       # see every workspace, its state and size
NAME       BRANCH         STATUS       AGE      SIZE     PATH
myapp*     main           ✓ clean      2d ago   412 MB   ~/code/myapp
feat-api   wt/feat-api    ● dirty (1)  3h ago   38 MB    ~/code/myapp/.worktrees/feat-api
$ wtx clean --dry-run          # preview reclaimable space
· feat-api (branch merged, 38 MB)
would free: 38 MB · kept 0 worktree(s)
```

## Commands

| Command | Description |
| --- | --- |
| `wtx new <name>` | Create `.worktrees/<name>` on branch `wt/<name>`, copy env files, run setup hook |
| `wtx ls` | Table of worktrees: branch, ahead/behind, dirty state, last-commit age, disk usage |
| `wtx rm <name> [--force]` | Remove a worktree; refuses if dirty; deletes merged branches |
| `wtx clean [--dry-run] [--stale-days <n>]` | Remove worktrees whose branches are fully merged and/or inactive |
| `wtx open [name]` | Spawn `$SHELL` inside a worktree (`--print` to just echo the path) |
| `wtx path [name]` | Print a worktree's absolute path (shell-script friendly) |
| `wtx mcp` | Run as an MCP server over stdio |

Global flags: `--json` (machine-readable output), `--base <ref>`, `--setup <cmd>`, `--no-copy`, `--no-setup`.

## Use it from AI agents (MCP)

Add to your MCP client config:

```jsonc
// e.g. claude_desktop_config.json / opencode.json / .mcp.json
{
  "mcpServers": {
    "wtx": { "command": "npx", "args": ["-y", "wtx", "mcp"] }
  }
}
```

The server exposes four tools: `list_worktrees`, `create_worktree`, `remove_worktree`, `clean_worktrees`. All accept an optional `repo_path`; otherwise the server's working directory is used. Responses are JSON, so agents can chain them: *create → work → remove* without ever switching branches in your main checkout.

Example agent prompt: *"Set up a workspace called oauth-fix based on develop, run pnpm install in it, then tell me the path."*

## Configuration

Drop a `wtx.config.json` (or `.wtxrc`) in your repo root:

```json
{
  "dir": ".worktrees",
  "copyFiles": [".env", ".env.local"],
  "setup": "pnpm install",
  "branchPrefix": "wt/"
}
```

| Key | Default | Meaning |
| --- | --- | --- |
| `dir` | `.worktrees` | Where worktrees live, relative to repo root (auto-added to `.git/info/exclude`) |
| `copyFiles` | `[".env", ".env.local"]` | Files copied from the main checkout into each new worktree |
| `setup` | *(none)* | Shell command run inside a new worktree after creation |
| `branchPrefix` | `wt/` | Prefix for branches created by `wtx new` |

## Safety model

- The **main worktree is never removed** by `rm` or `clean`.
- Dirty worktrees are **always preserved** by `clean`, and `rm` requires `--force`.
- Branches are deleted **only when fully merged** into the default branch (`origin/HEAD` → `main` → `master` fallback).
- Worktree directories live under `.worktrees/`, excluded via `.git/info/exclude` so your `.gitignore` stays untouched.
- Names are sanitized; traversal like `../evil` is rejected.

## How it compares

| | raw `git worktree` | TUI managers | **wtx** |
| --- | --- | --- | --- |
| One-command create + env copy + setup hook | ✗ | partial | ✓ |
| Disk usage & staleness per worktree | ✗ | rare | ✓ |
| Machine-readable `--json` everywhere | ✗ | ✗ | ✓ |
| MCP server for coding agents | ✗ | ✗ | ✓ |
| Zero runtime dependencies | n/a | ✗ (usually heavy) | ✓ |

## Development

```bash
git clone https://github.com/willkhinz/wtx && cd wtx
npm install
npm test        # build + 32 integration/unit tests
node dist/src/cli.js help
```

Architecture: [`src/core.ts`](src/core.ts) (engine), [`src/cli.ts`](src/cli.ts) (human UI), [`src/mcp.ts`](src/mcp.ts) (agent UI). The MCP implementation is dependency-free newline-delimited JSON-RPC 2.0.

## Roadmap

- [ ] `wtx exec <name> -- <cmd>` run commands across all worktrees
- [ ] tmux/iTerm session spawning per worktree
- [ ] Homebrew formula
- [ ] GitHub Action: comment PRs with per-worktree previews

## License

[MIT](./LICENSE)