Skip to main content
HAPI supports Git worktrees for spawning sessions in isolated branch environments. This enables parallel development on multiple branches without switching contexts or managing multiple repository clones.

What Are Worktrees?

Git worktrees allow you to check out multiple branches from a single repository simultaneously. Each worktree has its own working directory, enabling parallel work without context switching.

Parallel Development

Work on multiple features or bug fixes simultaneously without switching branches

Clean Isolation

Each session gets a pristine branch with no uncommitted changes from other work

How HAPI Uses Worktrees

When you spawn a session with sessionType: 'worktree', the HAPI runner:
1

Create Branch

Creates a new branch named hapi-<name> (e.g., hapi-0106-a3f2)
2

Create Worktree

Creates a worktree directory at <repo-name>-worktrees/<name>
3

Spawn Session

Starts the AI coding session in the worktree directory
4

Set Environment

Injects worktree metadata as environment variables

Worktree Environment Variables

When a session runs in a worktree, the runner sets these environment variables:

HAPI_WORKTREE_BASE_PATH

The root directory of the base repository:
HAPI_WORKTREE_BASE_PATH=/Users/you/projects/my-repo

HAPI_WORKTREE_BRANCH

The branch name created for this worktree:
HAPI_WORKTREE_BRANCH=hapi-0106-a3f2

HAPI_WORKTREE_NAME

The worktree name (also the directory name):
HAPI_WORKTREE_NAME=0106-a3f2

HAPI_WORKTREE_PATH

The full path to the worktree directory:
HAPI_WORKTREE_PATH=/Users/you/projects/my-repo-worktrees/0106-a3f2

HAPI_WORKTREE_CREATED_AT

Worktree creation timestamp in milliseconds:
HAPI_WORKTREE_CREATED_AT=1703001234567

Worktree Directory Structure

Worktrees are created in a sibling directory to your repository:
projects/
├── my-repo/                      # Base repository
│   ├── .git/
│   ├── src/
│   └── ...
└── my-repo-worktrees/            # Worktrees directory
    ├── 0106-a3f2/                # First worktree
    │   ├── .git -> ../my-repo/.git/worktrees/0106-a3f2
    │   ├── src/
    │   └── ...
    └── feature-auth/             # Named worktree
        ├── .git -> ../my-repo/.git/worktrees/feature-auth
        ├── src/
        └── ...

Creating Worktree Sessions

Via Web/Mobile App

When spawning a session through the web interface or Telegram Mini App:
  1. Select “Git Worktree” as the session type
  2. Choose your repository base directory
  3. Optionally provide a worktree name (e.g., “feature-auth”)
  4. The runner creates the worktree and spawns the session

Via Runner RPC

Programmatically spawn worktree sessions:
const result = await spawnSession({
  directory: '/Users/you/projects/my-repo',
  sessionType: 'worktree',
  worktreeName: 'feature-auth',  // Optional
  agent: 'claude',
  machineId: 'machine-uuid-123'
});

if (result.type === 'success') {
  console.log('Session ID:', result.sessionId);
  console.log('Worktree path:', result.worktreePath);
}

Worktree Naming

Worktree names follow a specific pattern:
If you don’t provide a worktreeName, HAPI generates a name with the format MMDD-XXXX:
  • MM: Month (01-12)
  • DD: Day (01-31)
  • XXXX: Random hex suffix (4 characters)
Example: 0106-a3f2 (January 6th with random suffix)
If you provide a worktreeName, it’s converted to a URL-safe slug:
  • Lowercase conversion
  • Replace non-alphanumeric with hyphens
  • Strip leading/trailing hyphens
Examples:
  • "Feature Auth"feature-auth
  • "fix/bug-123"fix-bug-123
  • "My New Feature"my-new-feature
If a worktree name or branch already exists, HAPI appends a random hex suffix:
  • First attempt: feature-auth
  • Second attempt: feature-auth-7b9e
  • Third attempt: feature-auth-d4c1
Maximum attempts: 5 (then fails with error)

Branch Naming

Worktree branches are prefixed with hapi- to distinguish them from regular branches:
# Worktree name: feature-auth
# Branch name: hapi-feature-auth

# Worktree name: 0106-a3f2
# Branch name: hapi-0106-a3f2
View worktree branches:
git branch | grep hapi-

Worktree Cleanup

The runner automatically cleans up worktrees when sessions end:
1

Session Exit

The session process exits normally or is terminated
2

Runner Detects Exit

Runner’s onChildExited handler is called
3

Process Check

Runner verifies the process is no longer alive
4

Remove Worktree

Runner executes git worktree remove --force <path>
If the session process is still alive when cleanup is triggered, the runner skips worktree removal to prevent data loss. The worktree will remain until manually cleaned.

Manual Cleanup

To manually remove a worktree:
# List all worktrees
git worktree list

# Remove specific worktree
git worktree remove /path/to/repo-worktrees/feature-auth

# Remove worktree and delete branch
git worktree remove /path/to/repo-worktrees/feature-auth
git branch -D hapi-feature-auth

Cleanup on Errors

Worktrees are cleaned up in error scenarios:
  • Spawn fails (no PID returned)
  • Session webhook timeout
  • Directory creation error
  • Exception during spawn
If the session process is still running, cleanup is skipped to preserve data.

Worktree Detection

HAPI can automatically detect if a session is running in a worktree:
// Runner sets these when spawning worktree sessions
const worktreeInfo = {
  basePath: process.env.HAPI_WORKTREE_BASE_PATH,
  branch: process.env.HAPI_WORKTREE_BRANCH,
  name: process.env.HAPI_WORKTREE_NAME,
  worktreePath: process.env.HAPI_WORKTREE_PATH,
  createdAt: parseInt(process.env.HAPI_WORKTREE_CREATED_AT)
};

Use Cases

Feature Development

Work on multiple features in parallel without branch switching

Bug Fixes

Isolate bug fix work while keeping feature development active

Code Review

Check out a PR branch in a worktree for side-by-side comparison

Experimentation

Test risky changes in an isolated worktree without affecting main work

Worktree Metadata in Sessions

HAPI sessions track worktree information in session metadata:
interface SessionMetadata {
  // ... other metadata
  worktreeInfo?: {
    basePath: string;      // Base repo path
    branch: string;        // hapi-<name>
    name: string;          // Worktree name
    worktreePath: string;  // Full worktree path
    createdAt: number;     // Timestamp (ms)
  }
}
This metadata is:
  • Stored in the hub database
  • Visible in the web interface
  • Included in session exports
  • Used for session restoration

Limitations

Repository Requirements:
  • Base directory must be a valid Git repository
  • Repository must not be in a detached HEAD state
  • Must have at least one commit
Worktree Restrictions:
  • Cannot create worktrees from worktrees (must use base repo)
  • Branch names must be unique across all worktrees
  • Worktree paths must not already exist

Error Handling

Common errors and solutions:
Cause: Base directory is not a git repoSolution: Initialize git or provide correct repository path:
git init
git commit --allow-empty -m "Initial commit"
Cause: Branch name collisionSolution: Use a different worktree name or delete the existing branch:
git branch -D hapi-name
Cause: Random name collisions (rare)Solution: Try again or manually specify a unique worktree name
Cause: Base path doesn’t existSolution: Verify the repository path exists and is accessible

Best Practices

Use Descriptive Names

Provide meaningful worktree names for easy identification: feature-auth, bugfix-123, refactor-api

Clean Up Regularly

Remove unused worktrees to save disk space and avoid clutter

Merge Frequently

Merge worktree branches back to main regularly to avoid long-lived branches

Monitor Disk Usage

Each worktree duplicates your working directory. Large repos consume significant space.

Advanced: Worktree Persistence

Worktrees persist after the runner stops or restarts:
  • Runner restart: Sessions continue running in worktrees
  • Machine reboot: Worktrees remain on disk but sessions are lost
  • Orphaned worktrees: Use git worktree list and git worktree prune to clean up
# List all worktrees (including orphaned)
git worktree list

# Remove orphaned worktree metadata
git worktree prune

# Force remove worktree even if not clean
git worktree remove --force /path/to/worktree

Troubleshooting

Session Not Detecting Worktree

  1. Check environment variables:
    echo $HAPI_WORKTREE_PATH
    
  2. Verify git worktree:
    git rev-parse --git-dir
    git rev-parse --git-common-dir
    
  3. Check runner logs:
    tail -f $(hapi runner logs) | grep WORKTREE
    

Worktree Not Cleaned Up

If a worktree remains after session exit:
  1. Check if process is still alive:
    ps aux | grep hapi
    
  2. Manually remove worktree:
    git worktree remove --force /path/to/worktree
    
  3. Check runner logs for cleanup failures:
    tail -f $(hapi runner logs) | grep "Failed to remove worktree"
    

Runner

Background daemon that manages worktree sessions

Configuration

Environment variables and settings

Sessions

Managing AI coding sessions

Build docs developers (and LLMs) love