@mkusaka/wtm
v0.0.8
Published
Git worktree manager CLI tool
Readme
wtm - Git Worktree Manager
A high-performance Git worktree management CLI tool written in TypeScript, designed to simplify the creation, organization, and maintenance of Git worktrees.
Features
- Interactive TUI Mode: Default interactive terminal UI with real-time filtering and preview
- Organized Worktree Structure: Creates worktrees with timestamp prefixes in
.git/tmp_worktrees/for better organization - Real-time Filtering: Type to filter worktrees by branch name or path instantly
- Preview Pane: See worktree details (path, branch, commit) while navigating
- Hook System: Automate worktree initialization with customizable hooks
- TypeScript Support: Fully typed with TypeScript and ES modules for better developer experience
- Fast Linting: Uses oxc-lint for blazing-fast code quality checks
- Rich CLI Output: Colorful and informative terminal output with progress indicators
- Status Tracking: Shows working tree status, modified files, and recent commits
- JSON Export: Machine-readable output format for scripting and automation
- Zero Config: Works out of the box with sensible defaults
- Branch Normalization: Automatically handles
refs/heads/prefixes
Installation
Prerequisites
- Node.js 18.0.0 or higher
- Git 2.0.0 or higher
Install from npm
# Using npm
npm install -g @mkusaka/wtm
# Using pnpm
pnpm add -g @mkusaka/wtm
# Using yarn
yarn global add @mkusaka/wtmInstall from source
# Clone the repository
git clone https://github.com/mkusaka/wtm.git
cd wtm
# Install dependencies
pnpm install
# Build the project
pnpm build
# Link globally (optional)
pnpm link --globalUsage
Interactive Mode (Default)
wtm # Opens interactive TUI for worktree selection (default)
wtm list # Same as above - interactive mode is default for list commandIn interactive mode:
- Type to filter: Start typing to filter worktrees by branch name or path
- ↑/↓: Navigate through worktrees
- Enter: Open selected worktree in a new shell
- Ctrl-D: Delete the selected worktree (with confirmation)
- Ctrl-C or Esc: Exit interactive mode
Non-interactive Mode
wtm list --no-interactive # Simple list output
wtm list --json # JSON format (automatically disables interactive mode)Create a new worktree
wtm add # Interactive branch selection
wtm add -b feature-branch # Create worktree for specific branch
wtm add -b # Interactive branch selection (same as wtm add)
wtm add --from develop -b feature # Create 'feature' branch from 'develop'
wtm add -b feature --path-only # Output only the worktree path (for shell integration)
wtm add -b feature --shell # Create worktree and launch new shell in itThe worktree will be created at .git/tmp_worktrees/YYYYMMDD_HHMMSS_feature-branch/
Shell Integration Examples
# Navigate to new worktree immediately
cd "$(wtm add -b feature --path-only)"
# Create alias for quick worktree creation and navigation
alias wta='cd "$(wtm add --path-only -b"'
# Usage: wta feature-branchRemove a worktree
wtm remove feature-branch # Interactive confirmation
wtm remove feature-branch -f # Force removal without confirmationNavigate to main repository
wtm root # Output main repository path
wtm root --verbose # Show detailed worktree information
wtm root --json # Output in JSON format for programmatic use
# Shell integration - navigate to main repo from any worktree
cd "$(wtm root)"
# Create an alias for quick navigation
alias wh='cd "$(wtm root)"' # "worktree home"The root command helps you quickly navigate back to the main repository from any worktree. It automatically detects the main repository path using .wt_env files created in worktrees for faster resolution.
Initialize hook file
wtm init # Creates .wt_hook.js in repository rootHook System
The hook system allows you to automate worktree setup tasks. After running wtm init, a .wt_hook.js file is created in your repository root.
Default Hook Behavior
The default hook copies the following files/directories from the main repository to new worktrees:
.env.env.local.claude
These files are commonly used for local configuration and are not typically committed to version control.
Customizing Hooks
Edit .wt_hook.js to customize the initialization process:
// Available environment variables:
// - WT_WORKTREE_PATH: Path to the new worktree
// - WT_BRANCH_NAME: Name of the new branch
// - WT_PROJECT_ROOT: Path to the main project root
// Example: Install dependencies after creating worktree
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
async function main() {
console.log('Installing dependencies...');
await execAsync('pnpm install', { cwd: process.env.WT_WORKTREE_PATH });
}Using External Libraries in Hooks
Hooks can use any npm packages installed in your parent project without requiring separate installations:
// The parent project's node_modules is automatically available
import { $ } from 'zx'; // If zx is installed in parent project
import { glob } from 'glob'; // If glob is installed in parent project
// Example: Advanced hook using external libraries
console.log(`Setting up worktree at: ${process.env.WT_WORKTREE_PATH}`);
console.log(`Branch name: ${process.env.WT_BRANCH_NAME}`);
// Use zx for shell commands
await $`cd ${process.env.WT_WORKTREE_PATH} && pnpm install`;
// Use glob to find and copy configuration files
const configFiles = await glob('config/*.json', {
cwd: process.env.WT_PROJECT_ROOT
});
for (const file of configFiles) {
await $`cp ${process.env.WT_PROJECT_ROOT}/${file} ${process.env.WT_WORKTREE_PATH}/${file}`;
}This feature enables powerful automation workflows by leveraging the full npm ecosystem without bloating individual worktrees with dependencies.
Development
Setup
# Install dependencies
pnpm install
# Run tests
pnpm test # Run all tests in CI mode
pnpm test:coverage # Run tests with coverage reports
# Type checking
pnpm typecheck
# Linting and formatting
pnpm lint # Linting with oxc-lint
pnpm format # Format code with Prettier
# Build and run
pnpm build # Build TypeScript to JavaScript
pnpm start # Run the built CLI
# Development workflow
pnpm build && node dist/src/bin/wtm.js <command> # Test CLI locally
tsx src/bin/wtm.ts <command> # Run directly with tsxProject Structure
wtm/
├── src/
│ ├── bin/ # CLI entry point
│ ├── commands/ # Command implementations
│ ├── components/ # React components for interactive UI
│ ├── utils/ # Utility functions
│ └── types/ # TypeScript type definitions
├── test/ # Test files
├── dist/ # Compiled output
└── .github/ # GitHub Actions workflowsTechnology Stack
- TypeScript: Type-safe development with ES modules
- Commander.js: CLI argument parsing (v14)
- simple-git: Git operations wrapper
- chalk: Terminal styling (v5)
- ora: Progress indicators (v8)
- ink: React for CLIs - powers the interactive TUI (v6)
- @inkjs/ui: Pre-built UI components for ink (v2)
- ink-select-input: Enhanced select component with highlight tracking (v6)
- oxc-lint: Fast linting (primary linter)
- vitest: Testing framework with coverage support
- tsx: TypeScript execution for development
Configuration
Git Worktree Structure
Worktrees are created in .git/tmp_worktrees/ with the naming convention:
YYYYMMDD_HHMMSS_<branch-name>This ensures:
- Chronological ordering
- Easy identification
- No naming conflicts
Ignoring Hook Files
Add .wt_hook.js to your .gitignore to keep hook configurations local:
.wt_hook.jsAPI Reference
Commands
wtm or wtm list
Lists all worktrees with their status. Opens interactive TUI by default.
Options:
-j, --json: Output in JSON format (automatically disables interactive mode)--no-interactive: Disable interactive mode and show simple list
wtm add
Creates a new worktree with interactive branch selection or specified branch.
Options:
-b, --branch [branch]: Branch name for the new worktree (interactive if not specified)--from <branch>: Base branch to create from (default: HEAD)--path-only: Output only the worktree path (useful for shell functions)-s, --shell: Launch a new shell in the worktree directory
wtm remove <branch>
Removes the worktree and deletes the associated branch.
Options:
-f, --force: Skip confirmation prompt
wtm init
Creates a .wt_hook.js template in the repository root.
wtm root
Shows the main repository path, useful for navigation from worktrees.
Options:
-j, --json: Output in JSON format-v, --verbose: Show detailed information about worktree status
Troubleshooting
Common Issues
"Not in a git repository" error
- Ensure you're running wtm from within a Git repository
- Check that
.gitdirectory exists
"No worktree found for branch" error
- Verify the branch name is correct
- Use
wtm listto see all available worktrees - Branch names are normalized (e.g.,
refs/heads/mainbecomesmain)
Hook execution fails
- Check
.wt_hook.jssyntax - Ensure the hook file has execute permissions
- Review error messages for specific issues
- Hook files run with inherited stdio for real-time output
- Check
ES Module import errors
- Ensure all imports use
.jsextensions (even for TypeScript files) - Node.js version must be 18.0.0 or higher for ES modules support
- Ensure all imports use
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Setup
All pull requests must pass CI checks:
- Tests must pass on Node.js 18.x, 20.x, and 22.x
- Type checking must pass (
pnpm typecheck) - Linting must pass (
pnpm lint) - Build must succeed (
pnpm build)
Publishing (Maintainers Only)
The package is published to npm as @mkusaka/wtm. To publish a new version:
- Ensure you have
NPM_TOKENsecret configured in GitHub repository settings - Run
npm version patch/minor/majorto bump version and create git tag - Push with tags:
git push origin main --follow-tags - GitHub Actions will automatically:
- Run tests across Node.js 18.x, 20.x, and 22.x
- Execute linting and type checking
- Publish to npm registry
- Create a GitHub release with build artifacts
The prepublishOnly script ensures the package is always built and tested before publishing.
License
MIT License - see the LICENSE file for details
Acknowledgments
- Inspired by the need for better Git worktree management
- Built with modern TypeScript tooling
- Leverages the power of Git's worktree feature
