A powerful CLI tool for managing Git worktrees with intelligent environment variable synchronization, automatic backup management, and comprehensive audit logging. Create, sync, and close worktrees with confidence.
- 🔄 Environment Variable Synchronization: Intelligent .env syncing between worktrees and main repo
- 📊 Side-by-Side Diff Display: Visual comparison of environment variables with color-coded changes
- 🎯 Interactive Variable Selection: Line-by-line selection of which variables to sync
- 💾 Automatic Backup Management: Auto-backup before sync with configurable retention (keep last 10)
- 📝 Complete Audit Trail: Dual-format logging (human-readable + JSON) with full history
- 🛡️ Safety Checks Before Closure: Detects uncommitted changes, unpushed commits, merge status
- 🔀 Bidirectional Sync: Sync from worktree to main, main to worktree, or choose direction interactively
- 🧹 Cleanup Utilities: Age-based backup cleanup with dry-run preview
- 📋 Worktree Listing: View all worktrees in table, JSON, or simple format
- ⚙️ Centralized Configuration: Global settings at
~/.workforge/config.json
- ✨ Automatic Organization: Creates
../type/namefolder structure - 🔍 Smart Repository Detection: Works from any directory in a Git repo or worktree
- 🏢 Internal Repository Support: Special handling for internal Bitbucket repositories
- 🎫 Jira Integration: Optional Jira ticket ID support with smart branch naming
- 📦 Package Manager Detection: Automatically detects and uses pnpm, npm, or yarn
- 🚀 Auto Dependency Installation: Runs package manager install after worktree creation
- 🛡️ Pre-flight Checks: Validates branches, paths, and prevents conflicts
- 🌿 Smart Branch Detection: Auto-detects default branch (main, master, beta, etc.)
- 🎯 Branch Management: Creates properly named branches with flexible patterns
- 💬 Interactive Confirmation: Optional confirmation before creation
- 🌈 Colored Output: Beautiful terminal output with status indicators
# Install globally via pnpm
pnpm install -g workforge
# Use anywhere
workforge --type feat --name user-auth
# or
wf --type fix --name memory-leak# Install in your project
pnpm install --save-dev workforge
# Add to package.json scripts
{
"scripts": {
"worktree": "workforge"
}
}
# Use via script
pnpm worktree --type feat --name user-auth# Create a new worktree
workforge create -t feat -n user-auth
# List all worktrees
workforge list
# Sync environment variables
workforge sync-env
# Close a worktree (with automatic env sync)
workforge close
# Clean up old backups
workforge cleanup --older-than 30WorkForge v3.0 provides five powerful commands:
# Create a feature branch worktree
workforge create -t feat -n user-authentication
# Create a fix branch from develop
workforge create -t fix -n memory-leak -b develop
# Create with Jira ticket (internal repos)
workforge create -t feat -n api-integration -j BZ-12345
# Non-interactive creation
workforge create -t doc -n api-guide -yOptions:
-t, --type: Branch type (feat, fix, doc, etc.) - Required-n, --name: Feature/branch name (kebab-case) - Required-b, --base: Base branch to fork from (default: auto-detected primary branch). Accepts a branch that exists only on the remote, a tag, or a commit SHA.-j, --ticket: Jira ticket ID (format: BZ-12345)-y, --yes: Skip confirmations
# Close current worktree (auto-detects)
workforge close
# Close specific worktree by path
workforge close /path/to/worktree
# Close by branch name
workforge close -n feat-auth
# Close and delete branch
workforge close --delete-branch
# Skip environment sync
workforge close --skip-sync
# Force close (ignore safety checks)
workforge close --forceOptions:
path: Path to worktree (optional, auto-detects)-n, --name: Worktree name to close-d, --delete-branch: Delete the branch after closing-s, --skip-sync: Skip environment variable sync-f, --force: Force close even with uncommitted changes-y, --yes: Skip confirmations--dry-run: Preview changes without executing
Features:
- Automatic environment variable diff and sync
- Safety checks (uncommitted changes, unpushed commits, merge status)
- Interactive variable selection
- Automatic backup before sync
- Complete audit logging
# Auto-detect: sync main to current worktree
workforge sync-env
# Sync from main to specific worktree
workforge sync-env --to feat-auth
# Sync from worktree to main
workforge sync-env --from feat-auth
# Sync between two worktrees
workforge sync-env --from feat-auth --to feat-users
# Bidirectional sync (choose direction interactively)
workforge sync-env --between feat-auth
# Auto-accept all changes
workforge sync-env --from feat-auth --yes
# Preview changes without executing
workforge sync-env --from feat-auth --dry-runOptions:
--from: Source worktree path or name--to: Target worktree path or name--between: Bidirectional sync (choose direction interactively)-y, --yes: Auto-accept all changes--dry-run: Preview changes without executing
Features:
- Side-by-side diff visualization
- Line-by-line variable selection
- Automatic backup before sync
- Support for multi-line values and complex .env formats
- Complete audit trail
# List all worktrees (table format)
workforge list
# List in JSON format
workforge list --json
# Simple one-line format
workforge list --simple
# Sort by branch name
workforge list --sort name
# Sort by path
workforge list --sort path
# Sort by age (most recent first)
workforge list --sort ageOptions:
--json: Output in JSON format--simple: Simple one-line format--sort: Sort by name, path, or age
Output includes:
- Branch name
- Worktree path
- Commit hash
- Status (MAIN, ACTIVE, LOCKED, PRUNABLE)
# Clean up all backups (with confirmation)
workforge cleanup
# Delete backups older than 30 days
workforge cleanup --older-than 30
# Preview what would be deleted
workforge cleanup --dry-run
# Skip confirmation
workforge cleanup --yesOptions:
--older-than: Delete backups older than N days-y, --yes: Skip confirmation--dry-run: Preview what would be deleted
# 1. Create worktree for new feature
workforge create -t feat -n user-dashboard
# 2. Work on feature, modify .env as needed
cd ../feat/user-dashboard
# ... make changes ...
# 3. List all worktrees to see status
workforge list
# 4. Sync .env changes back to main
workforge sync-env --from feat-user-dashboard
# 5. Close worktree when done
workforge close --delete-branch# Quick fix workflow
workforge create -t fix -n critical-bug -y
cd ../fix/critical-bug
# Make fix, commit
git add .
git commit -m "fix: resolve critical bug"
git push
# Sync .env changes (if any) and close
workforge close --delete-branch --yes# Create multiple worktrees
workforge create -t feat -n auth
workforge create -t feat -n users
workforge create -t fix -n memory-leak
# List all worktrees
workforge list
# Update .env in main repo
cd /path/to/main/repo
vim .env
# Sync to all worktrees
workforge sync-env --to feat-auth
workforge sync-env --to feat-users
workforge sync-env --to fix-memory-leak
# Close old worktrees
workforge cleanup --older-than 30# .github/workflows/worktree-build.yml
name: Worktree Build
on:
push:
branches: [ main, develop ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install WorkForge
run: pnpm install -g workforge
- name: Configure WorkForge
run: |
mkdir -p ~/.workforge
cat > ~/.workforge/config.json << EOF
{
"preferences": { "skipConfirmations": true },
"backup": { "enabled": false },
"display": {
"colorEnabled": false,
"showProgressIndicators": false
}
}
EOF
- name: Create worktree for build
run: workforge create -t build -n ci-${{ github.run_number }} --yes
- name: Build in worktree
working-directory: ./build-ci-${{ github.run_number }}
run: |
pnpm install
pnpm run build
- name: Cleanup
if: always()
run: workforge close -n build-ci-${{ github.run_number }} --yes --skip-syncWorkForge stores global configuration at ~/.workforge/config.json.
~/.workforge/config.json
{
"version": "3.0.0",
"preferences": {
"defaultBaseBranch": "main",
"autoDeleteBranch": false,
"skipConfirmations": false,
"packageManager": "auto",
"showExistingWorktrees": true
},
"backup": {
"enabled": true,
"maxBackupsPerProject": 10,
"autoCleanup": true
},
"sync": {
"createBackupBeforeSync": true,
"defaultSyncDirection": "ask"
},
"audit": {
"enabled": true,
"includeVariableValues": true,
"retentionDays": 90
},
"display": {
"colorEnabled": true,
"verboseOutput": false,
"showProgressIndicators": true
}
}Preferences:
defaultBaseBranch: Default base branch for new worktrees (default:"main")autoDeleteBranch: Auto-delete branch when closing worktree (default:false)skipConfirmations: Skip all confirmation prompts (default:false)packageManager: Package manager to use:auto,pnpm,npm, oryarn(default:"auto")
Backup:
enabled: Enable automatic backups (default:true)maxBackupsPerProject: Maximum backups per project (default:10)autoCleanup: Auto-delete old backups (default:true)
Sync:
createBackupBeforeSync: Create backup before syncing (default:true)defaultSyncDirection: Direction for bidirectional sync:ask,to-main, orto-worktree(default:"ask")
Audit:
enabled: Enable audit logging (default:true)includeVariableValues: Include values in audit logs (default:true)retentionDays: Days to retain audit logs (default:90)
Display:
colorEnabled: Enable colored output (default:true)verboseOutput: Show detailed debug information (default:false)showProgressIndicators: Show animated progress spinners (default:true)
For more details, see Configuration Guide.
~/.workforge/
├── config.json # Global configuration
├── projects/
│ └── <project-id>/
│ ├── .meta.json # Project metadata
│ ├── audit.log # Human-readable audit log
│ └── sync-history.json # Machine-readable history
└── backups/
└── <project-id>/
└── .env.backup.YYYY-MM-DD_* # Timestamped backups
- Branch Pattern:
type/name - Examples:
feat/user-authentication,fix/memory-leak
- With Ticket:
TICKET-type-name(e.g.,BZ-12345-feat-user-auth) - Without Ticket:
type/name(fallback to standard pattern) - Interactive Prompt: Asks for optional Jira ticket ID
- Validation: Enforces ticket format (e.g., BZ-12345, ABC-123)
The tool automatically detects your project's package manager and runs the appropriate install command:
- pnpm-lock.yaml found → Uses
pnpm install - yarn.lock found → Uses
yarn install - package-lock.json found → Uses
npm install - No lock file → Defaults to
pnpm install
- Runs after worktree creation and environment file copying
- Executes in the new worktree directory (not original repo)
- Shows installation progress with package manager output
- Handles errors gracefully with helpful messages
The tool creates an organized folder structure while maintaining consistent naming:
your-repo/
├── .git/
├── src/
├── pnpm-lock.yaml # Detected: uses pnpm
└── ...
../
├── feat/
│ ├── user-authentication/ # ← New worktree (BZ-12345-feat-user-authentication branch)
│ └── payment-integration/ # ← Another worktree
├── fix/
│ ├── memory-leak/
│ └── database-connection/
└── doc/
└── api-guide/
Note: Folder structure remains ../type/name regardless of ticket ID. Only branch names include ticket IDs.
create fetches before it does anything else, then branches from
<remote>/<base> whenever the base exists on the remote. git fetch only
advances refs/remotes/* — it never moves your local branches — so branching
from a local branch name forks from whatever commit that branch was left at,
which in a worktree workflow is usually well behind the remote.
If the base has no remote counterpart, WorkForge falls back to the local branch and says so. If the remote is unreachable, it warns and continues with the refs already on disk.
Probed in order, falling through on any failure:
- Cached remote HEAD:
refs/remotes/<remote>/HEAD(refreshed after each successful fetch, so a renamed default branch is picked up) - Live query:
git ls-remote --symref <remote> HEAD, then cached locally - Remote candidates:
main,master,release,develop,trunk,beta,dev,stableagainstrefs/remotes/<remote>/* - Local candidates: the same names against
refs/heads/* - Current branch: whatever the main repository has checked out
-b/--base, when passed — never overridden by detection- The auto-detected primary branch
preferences.defaultBaseBranch(used directly whenpreferences.autoDetectBaseBranchisfalse, otherwise only as a last resort)
The new branch is created with --no-track, so it does not inherit the base
branch as its upstream.
# Standard feature development
workforge --type feat --name user-dashboard
# Output:
# ✓ Detected public repository
# ✓ Detected default branch: main
# ✓ Detected package manager: npm
# ✓ Worktree created: ../feat/user-dashboard
# ✓ Branch created: feat/user-dashboard
# ✓ Environment files copied
# ✓ Dependencies installed successfully using npm# Internal repository with Jira ticket
workforge --type feat --name bedrock-migration --ticket BZ-43210
# Output:
# ✓ Detected internal Bitbucket repository
# ✓ Using ticket ID: BZ-43210
# ✓ Detected default branch: beta
# ✓ Detected package manager: pnpm
# ✓ Worktree created: ../feat/bedrock-migration
# ✓ Branch created: BZ-43210-feat-bedrock-migration
# ✓ Environment files copied
# ✓ Dependencies installed successfully using pnpm
cd ../feat/bedrock-migration
# Start working on BZ-43210!# Quick fix from main
workforge -t hotfix -n security-patch -b main -y
# Fix from develop branch
workforge --type fix --name login-error --base develop
# Fix with Jira ticket from release branch
workforge -t fix -n critical-bug -j BZ-99999 -b release/v2.1# Documentation branch
workforge --type doc --name api-guide
# Testing branch
workforge -t test -n integration-tests
# Refactoring with ticket
workforge -t refactor -n code-cleanup -j BZ-11111The tool automatically copies common environment files from your repository root to the new worktree:
.env.env.example.env.local.env.development
This ensures your new worktree has the same configuration as your main repository without manual copying.
- Must contain only letters
- Automatically converted to lowercase
- Examples:
feat,fix,doc,hotfix,refactor
- Must be kebab-case
- Lowercase letters, numbers, and hyphens only
- Examples:
user-auth,api-v2,bug-123,payment-flow
- Format:
LETTERS-NUMBERS(e.g.,BZ-12345,PROJ-456) - Case-sensitive prefix
- Optional for internal repositories
- Validates format before proceeding
- ✅ Git repository detection
- ✅ Git binary availability
- ✅ Repository type detection (public vs internal)
- ✅ Default branch detection
- ✅ Package manager detection
- ✅ Branch name uniqueness (local and remote)
- ✅ Worktree path availability
- ✅ Base branch existence
# .github/workflows/feature-branch.yml
name: Create Feature Branch
on:
workflow_dispatch:
inputs:
feature_name:
description: 'Feature name (kebab-case)'
required: true
ticket_id:
description: 'Jira ticket ID (optional)'
required: false
jobs:
create-branch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Create worktree
run: |
TICKET_FLAG=""
if [ -n "${{ github.event.inputs.ticket_id }}" ]; then
TICKET_FLAG="--ticket ${{ github.event.inputs.ticket_id }}"
fi
npx workforge -t feat -n ${{ github.event.inputs.feature_name }} $TICKET_FLAG -y# Standard team branch types
workforge -t feat -n new-feature # New features
workforge -t fix -n bug-name # Bug fixes
workforge -t hotfix -n urgent-fix # Critical fixes
workforge -t doc -n documentation # Documentation
workforge -t test -n test-suite # Testing
workforge -t refactor -n cleanup # Refactoring
# With Jira tickets (internal repos)
workforge -t feat -n user-onboarding -j BZ-12345
workforge -t fix -n performance-issue -j BZ-67890The tool automatically adapts to your project setup:
# pnpm project (pnpm-lock.yaml exists)
workforge -t feat -n pnpm-feature
# → Runs: pnpm install
# yarn project (yarn.lock exists)
workforge -t feat -n yarn-feature
# → Runs: yarn install
# pnpm project (pnpm-lock.yaml exists)
workforge -t feat -n pnpm-feature
# → Runs: pnpm install"Not inside a Git repository"
# Make sure you're in a Git repository
git status
# or navigate to your repository
cd /path/to/your/repo"Branch already exists"
# Check existing branches
git branch -a
# Use a different name or clean up old branches
git branch -d BZ-12345-feat-old-branch
git branch -d feat/old-branch"Worktree path already exists"
# Check existing worktrees
git worktree list
# Remove old worktree if no longer needed
git worktree remove ../feat/feature-name"Invalid ticket format"
# Ensure ticket follows correct format
workforge -t feat -n my-feature -j BZ-12345 # ✅ Correct
workforge -t feat -n my-feature -j bz-12345 # ❌ Wrong case
workforge -t feat -n my-feature -j BZ12345 # ❌ Missing hyphen"Failed to install dependencies"
# Check package manager is installed
pnpm --version
npm --version
yarn --version
# Install missing package manager (requires npm or other package manager)
npm install -g pnpm
# or
npm install -g yarn
# Manual installation
cd ../feat/your-feature
pnpm install # or npm install, yarn installPackage manager detection issues
# Force specific package manager by creating lock file
touch pnpm-lock.yaml # Forces pnpm
touch yarn.lock # Forces yarn
touch pnpm-lock.yaml # Forces pnpm
# Or run manually after worktree creation
cd ../feat/your-feature
pnpm install # Use your preferred package managerFor troubleshooting, you can manually check each step:
# 1. Verify you're in a Git repo
git rev-parse --show-toplevel
# 2. Check remote URL (for repository type detection)
git remote get-url origin
# 3. Check default branch
git symbolic-ref refs/remotes/origin/HEAD
# 4. Check current worktrees
git worktree list
# 5. Check existing branches
git branch -a | grep "feat/feature-name"
git branch -a | grep "BZ-12345"
# 6. Verify base branch exists (remote first — that is what create uses)
git show-ref --verify refs/remotes/origin/main
git show-ref --verify refs/heads/main
# 7. Check package manager files
ls -la | grep -E "(pnpm-lock|yarn.lock|package-lock)"# Test repository type detection
git remote get-url origin | grep bitbucket.juspay.net
# Test package manager detection manually
if [ -f "pnpm-lock.yaml" ]; then echo "pnpm";
elif [ -f "yarn.lock" ]; then echo "yarn";
elif [ -f "package-lock.json" ]; then echo "npm";
else echo "pnpm (default)"; fi
# Test branch existence
git rev-parse --verify BZ-12345-feat-branch-name 2>/dev/null || echo "Branch doesn't exist"If you're upgrading from the basic version, here's what's new:
- Jira Integration: Add
-j TICKET-IDfor internal repositories - Package Manager Detection: Automatic detection and installation
- Smart Branch Detection: No more hardcoded "main" branch
- Repository Type Detection: Different behavior for internal vs public repos
- None! All existing commands work exactly the same
- New features are opt-in and backward compatible
# Old command (still works)
workforge -t feat -n my-feature
# New enhanced command (internal repos)
workforge -t feat -n my-feature -j BZ-12345
# Let the tool auto-detect everything
workforge -t feat -n my-feature # Will prompt for ticket if internal repo- Fork the repository
- Create a feature branch:
workforge -t feat -n awesome-feature -j CONTRIB-123 - Make your changes
- Add tests
- Update documentation
- Submit a pull request
MIT License - see LICENSE file for details.
- Configuration Guide - Complete configuration options and examples
- Sync Operations - Environment variable synchronization workflows
- Advanced Usage - Power user workflows, CI/CD, scripting
- Troubleshooting - Common issues and solutions
- Environment Sync: See Sync Operations Guide
- Safety Checks: See Troubleshooting - Safety Check Failures
- Backup Recovery: See Troubleshooting - Backup and Recovery
- CI/CD Setup: See Advanced Usage - CI/CD Integration
Major Features:
- 🔄 Intelligent Environment Sync: Close command with automatic .env diff and sync
- 📊 Side-by-Side Diff Display: Visual comparison of environment variables
- 🎯 Interactive Variable Selection: Line-by-line selection of which variables to sync
- 💾 Automatic Backup Management: Auto-backup before sync with configurable retention
- 📝 Complete Audit Trail: Dual-format logging (human-readable + JSON)
- 🛡️ Safety Checks: Pre-close validation (uncommitted changes, unpushed commits, merge status)
- 🔀 Bidirectional Sync: Sync in any direction with interactive prompts
- 🧹 Cleanup Utilities: Age-based backup cleanup with dry-run preview
- 📋 Worktree Listing: View all worktrees in multiple formats
- ⚙️ Centralized Configuration: Global settings at
~/.workforge/config.json
New Commands:
workforge close- Close worktrees with intelligent environment syncworkforge sync-env- Standalone environment variable synchronizationworkforge list- List all worktrees with status indicatorsworkforge cleanup- Clean up old backups and logs
Core Components:
- ConfigManager - Global configuration with deep merge
- ProjectIdentifier - SHA-256 project IDs from Git remote URL
- EnvFileParser - Comprehensive .env parsing (multi-line, comments, escape sequences)
- WorktreeResolver - Three-pattern resolution (path, name, auto-detect)
- EnvDiffer - Intelligent environment variable comparison
- EnvSyncer - Apply sync decisions with backup
- BackupManager - Auto-backup with rotation (keep last 10)
- SafetyChecker - Pre-close validation checks
- WorktreeRemover - Safe worktree removal
- BranchCleaner - Branch deletion with safety checks
- AuditLogger - Dual-format audit logging
- SyncTargetResolver - Four sync patterns (from/to/between/auto)
Implementation Stats:
- 23 major implementation files
- ~5,700 lines of production TypeScript
- 4 comprehensive documentation guides
- Complete type safety with TypeScript 5.0+
- 🎫 Jira Integration: Support for internal Bitbucket repositories with ticket IDs
- 📦 Package Manager Detection: Automatic pnpm/npm/yarn detection and installation
- 🌿 Smart Branch Detection: Auto-detects default branch (main, master, beta, etc.)
- 🏢 Repository Type Detection: Different handling for internal vs public repositories
- 🚀 Auto Dependency Installation: Runs package manager install after worktree creation
- ✨ Enhanced Branch Naming: Supports both
type/nameandTICKET-type-namepatterns - 🛡️ Improved Validation: Better error handling and pre-flight checks
- 💬 Interactive Improvements: Smart prompts based on repository type
- 🌈 Better Logging: More detailed status messages and progress indicators
- Initial release
- Basic workspace creation
- Environment file copying
- Pre-flight validation
- Interactive confirmation
- Colored terminal output