Git worktree workflow manager for feature development
Project description
fwts
Git worktree workflow manager for feature development. Automates creating worktrees, tmux sessions, docker services, and more.
Why fwts? When working on multiple features simultaneously, git worktrees let you have separate working directories for each branch. fwts automates the tedious parts: creating worktrees, spinning up tmux sessions, managing docker services, and switching shared resources between features.
Features
- Worktree Management - Create and manage git worktrees for parallel feature development
- Multi-Project Support - Manage multiple repos with named projects in global config
- Tmux Integration - Automatic session creation with editor and side command (e.g., Claude)
- Docker Compose - Start/stop isolated docker services per feature
- Linear Integration - Resolve ticket IDs to branch names
- GitHub Integration - Resolve PR numbers to branches
- Interactive TUI - Rich terminal UI for viewing and managing worktrees
- Programmable Columns - Custom hooks for CI status, review status, etc.
- Shell Completions - bash, zsh, and fish support
Installation
From Homebrew (macOS) - Recommended
brew tap laudiacay/tap
brew install fwts
Auto-updates: Since we ship changes frequently, enable auto-update:
# Auto-update daily (add to your shell rc file)
export HOMEBREW_AUTO_UPDATE_SECS=86400
# Or manually update anytime
brew upgrade fwts
Check for new releases: https://github.com/laudiacay/fwts/releases
From PyPI
pip install fwts
# or with uv (recommended for CLI tools)
uv tool install fwts
# Update with:
pip install --upgrade fwts
# or
uv tool upgrade fwts
Quick Start
1. Run Interactive Setup
fwts includes an interactive setup wizard that guides you through configuration:
For multi-project setup (recommended):
fwts init --global
This will prompt you for:
- Project names and repo paths
- GitHub repositories
- Linear integration (if you use it)
- Tmux layout preferences (editor, side command)
- Docker compose integration
- Custom hooks and columns for the TUI
For single-project setup:
cd ~/code/myproject
fwts init
The wizard will auto-detect:
- Git repository information
- Default branch (main/dev/master)
- GitHub remote URL
And prompt you to configure:
- Worktree base directory
- Integrations (Linear, Docker)
- Tmux layout (editor, side pane)
- Claude Code context
- Lifecycle hooks
- Custom TUI columns
2. Start working on a feature:
# From a Linear ticket
fwts start SUP-123
# From a GitHub PR
fwts start #456
# From a branch name
fwts start feature/my-feature
# Interactive mode - pick from existing worktrees or tickets
fwts start
3. View all worktrees:
# Interactive TUI with status columns
fwts status
# Simple list
fwts list
4. Clean up when done:
# Cleanup specific worktree
fwts cleanup feature/my-feature
# Interactive cleanup with uncommitted changes detection
fwts cleanup
Configuration
Global Config (Multi-Project)
Create ~/.config/fwts/config.toml for managing multiple projects:
# Default project when not in a project directory
default_project = "myproject"
[projects.myproject]
name = "myproject"
main_repo = "~/code/myproject"
worktree_base = "~/code/myproject-worktrees"
base_branch = "main"
github_repo = "username/myproject"
[projects.another]
name = "another"
main_repo = "~/code/another"
worktree_base = "~/code/another-worktrees"
base_branch = "dev"
Per-Repo Config
Create .fwts.toml in your repo root:
[project]
name = "myproject"
main_repo = "~/code/myproject"
worktree_base = "~/code/myproject-worktrees"
base_branch = "main"
github_repo = "username/myproject"
[linear]
enabled = true
# LINEAR_API_KEY from environment
[tmux]
editor = "nvim ."
side_command = "claude"
layout = "vertical"
[lifecycle]
on_start = ["just up"]
on_cleanup = ["just down"]
[symlinks]
paths = [".env.local"]
[docker]
enabled = true
compose_file = "docker-compose.dev.yml"
# Custom TUI columns
[[tui.columns]]
name = "CI"
hook = "gh run list --branch $BRANCH_NAME --limit 1 --json conclusion -q '.[0].conclusion'"
color_map = { success = "green", failure = "red", pending = "yellow" }
Per-Worktree Config
Create .fwts.local.toml in a worktree to override settings for that specific worktree. This file should be gitignored.
Config Hierarchy
Configuration is loaded and merged in this order (later overrides earlier):
~/.config/fwts/config.toml(global)<main_repo>/.fwts.toml(per-repo)<worktree>/.fwts.local.toml(per-worktree)
Commands
| Command | Description |
|---|---|
fwts start [input] |
Start or resume a feature worktree |
fwts cleanup [input] |
Clean up worktree, tmux, docker |
fwts status |
Interactive TUI dashboard |
fwts list |
Simple worktree list |
fwts projects |
List configured projects |
fwts init |
Initialize config file |
fwts init --global |
Initialize global config |
fwts completions <shell> |
Generate shell completions |
Global Options
All commands support:
--project, -p- Use a specific named project from global config--config, -c- Use a specific config file
Aliases
fb is an alias for fwts:
fb start SUP-123
fb status
TUI Keyboard Shortcuts
| Key | Action |
|---|---|
j / ↓ |
Move down |
k / ↑ |
Move up |
space |
Toggle selection |
a |
Select all |
enter |
Launch selected |
d |
Cleanup selected |
r |
Refresh |
q |
Quit |
Advanced Features
Custom TUI Columns and Hooks
Add custom status columns to the TUI dashboard by defining hooks in your config:
[[tui.columns]]
name = "CI"
hook = "gh run list --branch $BRANCH_NAME --limit 1 --json conclusion -q '.[0].conclusion'"
color_map = { success = "green", failure = "red", pending = "yellow", null = "dim" }
[[tui.columns]]
name = "Review"
hook = "gh pr view $BRANCH_NAME --json reviewDecision -q '.reviewDecision' 2>/dev/null || echo 'none'"
color_map = { APPROVED = "green", CHANGES_REQUESTED = "red", REVIEW_REQUIRED = "yellow" }
[[tui.columns]]
name = "Checks"
hook = "gh pr checks $BRANCH_NAME 2>/dev/null | grep -c '✓' || echo '0'"
Hooks have access to these environment variables:
$BRANCH_NAME- The worktree's branch name$WORKTREE_PATH- Path to the worktree$MAIN_REPO- Path to the main repository
Lifecycle Commands
Run commands automatically during worktree lifecycle:
[lifecycle]
# Run after worktree creation
post_create = ["npm install", "cp .env.example .env"]
# Run when starting a worktree
on_start = ["just up", "just migrate"]
# Run when cleaning up
on_cleanup = ["just down", "just clean-cache"]
Per-Worktree Overrides
Create .fwts.local.toml in any worktree to override settings just for that worktree:
[tmux]
editor = "code ." # Use VS Code instead of neovim for this worktree
[docker]
enabled = false # Don't start docker for this worktree
Shell Completions
# Bash
eval "$(fwts completions bash)"
# Zsh
eval "$(fwts completions zsh)"
# Fish
fwts completions fish > ~/.config/fish/completions/fwts.fish
Environment Variables
| Variable | Description |
|---|---|
LINEAR_API_KEY |
Linear API key for ticket integration |
Requirements
- Python 3.10+
- git
- tmux
- gh (GitHub CLI) - optional, for PR integration
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fwts-0.1.57.tar.gz.
File metadata
- Download URL: fwts-0.1.57.tar.gz
- Upload date:
- Size: 142.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
949b28fbcd9fe62680a241dffea1b7da01768f4dbc5350ec3e39f66e63bdec7c
|
|
| MD5 |
81840bf5bc13e962c0a0e34bc5f6d4d8
|
|
| BLAKE2b-256 |
f8b0d2772a2ce2baf3ad59a4ae74183d485a4cf0a10b1504f40733a8be7242a8
|
Provenance
The following attestation bundles were made for fwts-0.1.57.tar.gz:
Publisher:
release.yml on laudiacay/fwts
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fwts-0.1.57.tar.gz -
Subject digest:
949b28fbcd9fe62680a241dffea1b7da01768f4dbc5350ec3e39f66e63bdec7c - Sigstore transparency entry: 1328422497
- Sigstore integration time:
-
Permalink:
laudiacay/fwts@35162c17fa19c8602d8cce8125f67699d93e72c4 -
Branch / Tag:
refs/tags/v0.1.57 - Owner: https://github.com/laudiacay
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@35162c17fa19c8602d8cce8125f67699d93e72c4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fwts-0.1.57-py3-none-any.whl.
File metadata
- Download URL: fwts-0.1.57-py3-none-any.whl
- Upload date:
- Size: 68.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34ca844dd4399f63b8a8f47d5729740cdd87d1a4c383320a1b311e67e146c85d
|
|
| MD5 |
1b62460d5eaeb4010095bff92858ee0e
|
|
| BLAKE2b-256 |
47fb9bf5023ae746ae68e2fdecb312d815bb76651f767854d83a43df6b71a55f
|
Provenance
The following attestation bundles were made for fwts-0.1.57-py3-none-any.whl:
Publisher:
release.yml on laudiacay/fwts
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fwts-0.1.57-py3-none-any.whl -
Subject digest:
34ca844dd4399f63b8a8f47d5729740cdd87d1a4c383320a1b311e67e146c85d - Sigstore transparency entry: 1328422564
- Sigstore integration time:
-
Permalink:
laudiacay/fwts@35162c17fa19c8602d8cce8125f67699d93e72c4 -
Branch / Tag:
refs/tags/v0.1.57 - Owner: https://github.com/laudiacay
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@35162c17fa19c8602d8cce8125f67699d93e72c4 -
Trigger Event:
push
-
Statement type: