Git worktree manager for parallel coding agent development
Project description
Timberline
Git worktree manager for parallel coding agent development.
Features
- Agent session linking — symlinks worktree's agent session data to the main repo, so coding agents inherit full conversation history and memory across worktrees
- Auto-launch coding agents — spawn Claude, Codex, OpenCode, or Aider directly into a worktree (
tl new --agent) - Agent context injection — auto-injects worktree metadata (branch, base, sibling worktrees) into agent config files (CLAUDE.md, AGENTS.md)
- Auto-init dependencies — detects & installs via bun/npm/pnpm/yarn/uv/pip/cargo/go/composer/bundle on worktree creation
- Auto-copy .env files — glob-based discovery with include/exclude patterns, sync & diff commands
- Auto-init submodules — recursive submodule setup on worktree creation
- Archive & restore —
tl donesoft-removes a worktree (keeps directory, marks archived), warns about uncommitted/unpushed work;tl unarchiverestores it - Shell integration —
tlcd,tln,tldone,tlunarchiveshell aliases,tl-promptfor PS1, auto-install for bash/zsh/fish - Creative naming schemes — minerals, cities, or compound names for auto-named worktrees
- Branch templates — configurable
{user}/{type}/{name}patterns for consistent naming - Land workflow — pre-land checks → push → PR creation in one command
- Multi-worktree status — git status, ahead/behind tracking across all worktrees
- Sync all worktrees — rebase or merge all worktrees on latest base branch
Install
# global CLI (recommended)
uv tool install timberline
# or with pip
pip install timberline
Upgrade
uv tool upgrade timberline
Setup
Setup shell aliases
tl setup
Quick Start
cd your-repo
tl init # create .timberline.toml
tl new auth-refactor # create worktree + branch
tl new --type fix # auto-named fix worktree
tl ls # list all worktrees
tlcd auth-refactor # jump into worktree
tl land # run checks, push, and create PR
tldone # archive worktree + cd back to main repo
tl rm auth-refactor # full removal (or skip if archived)
Getting Started
Run tl init inside any git repo to create .timberline.toml. The wizard auto-detects:
- Project name — defaults to the repo directory name, used for global worktree storage at
~/.timberline/projects/<name>/ - Branch prefix from your git user
- Base branch (main/master/develop)
- Package manager (bun, npm, pnpm, yarn, uv, pip, cargo, go, composer, bundle) for dependency install
- Pre-land checks (Makefile targets, npm scripts like
lint,test,check) - Default agent (claude, codex, opencode, aider) if installed
Worktrees are stored globally at ~/.timberline/projects/<project>/worktrees/ — fully outside the repo tree. This prevents agents from accidentally writing files into the parent repo.
Use --defaults to skip prompts and accept detected values.
Create & Enter a Worktree
tl new auth-refactor # named worktree
tl new --type fix # auto-named (minerals, cities, or compound)
tl new --agent # create + launch coding agent
Enter a worktree:
cd $(tl cd auth-refactor) # subshell-friendly
Or with shell integration (tl setup):
tlcd auth-refactor # cd directly
Each worktree gets its own branch (from branch_template), dependencies installed via auto_init, and .env files copied from the main repo.
Agent Session Linking
When using Claude Code, each worktree normally gets a fresh session with no history. Enable session linking to share conversation history, memory, and project context across all worktrees:
tl config set agent.link_project_session true
This symlinks each worktree's Claude project data directory (~/.claude/projects/<encoded-worktree-path>) to the main repo's project directory. Your agent sees the same session history, CLAUDE.md memory, and project context regardless of which worktree you're in.
- Created automatically on
tl new - Cleaned up on
tl rm - Skip for a single worktree with
tl new --no-link
Sync with Base Branch
tl sync # rebase current worktree onto base
tl sync auth-refactor # rebase specific worktree
tl sync --all # rebase all worktrees
tl sync --merge # merge instead of rebase
Fetches all remotes, then rebases (default) or merges onto origin/{base_branch}. Each worktree tracks its own base branch from creation — no hardcoded "main".
Land a PR
tl land auth-refactor # checks → push → PR
tl land --draft # create as draft PR
tl land --skip-checks # bypass pre-land checks
tl land runs your configured pre_land command (e.g. make check), pushes the branch, then creates a PR via gh. Configure it in .timberline.toml:
[timberline]
pre_land = "make check" # or "bun run lint && bun run test", etc.
Archive a Worktree
When you're done with a worktree but want to keep it around (e.g. waiting for PR review), use tl done to archive it:
tldone # archive current worktree + cd back to repo root
tl done --name auth-refactor # archive by name
tl done --force # skip uncommitted/unpushed warnings
tl done warns if you have uncommitted changes or unpushed commits before archiving. Archived worktrees are hidden from tl ls but the directory stays on disk. To see them:
tl ls --archived # list only archived worktrees
Restore an archived worktree:
tl unarchive auth-refactor # restore to active
tlunarchive auth-refactor # restore + cd into it
tl rm still works on archived worktrees for full removal.
Commands
| Command | Description |
|---|---|
tl init |
Interactive setup, write .timberline.toml |
tl new [name] |
Create worktree (aliases: create) |
tl ls |
List worktrees (aliases: list). --json, --paths, --archived |
tl done [--name] |
Archive worktree, print repo root. --force |
tl unarchive <name> |
Restore archived worktree |
tl rm <name> |
Remove worktree (aliases: remove). --force, --keep-branch, --all |
tl cd <name> |
Print worktree path. --shell for subshell |
tl status |
Git status across all worktrees |
tl sync [name] |
Rebase/merge on base branch. --all, --merge |
tl land [name] |
Run checks, push, and create PR. --draft, --skip-checks |
tl rename <branch> |
Rename worktree's git branch. -n <name> |
tl agent [name] |
Launch coding agent in worktree. --new |
tl run-init [name] |
Re-run dependency install |
tl pr [name] |
Create PR via gh CLI. --draft |
tl env sync [name] |
Re-copy .env files from main repo |
tl env ls |
List discovered .env files |
tl env diff [name] |
Show .env differences |
tl clean |
Prune stale worktrees. --dry-run |
tl setup |
Install shell integration into rc file. --uninstall |
tl shell-init |
Output shell integration script |
tl config show |
Print resolved config |
tl config set <k> <v> |
Set config value |
tl config edit |
Open config in $EDITOR |
Config
.timberline.toml in repo root:
[timberline]
project_name = "my-project" # global storage name (~/.timberline/projects/<name>/)
branch_template = "{user}/{type}/{name}"
user = "nc9"
default_type = "feature"
base_branch = "main"
naming_scheme = "minerals" # minerals | cities | compound
default_agent = "claude" # claude | codex | opencode | aider
pre_land = "make check" # command to run before pushing
[timberline.init]
auto_init = true
# init_command = "bun run init"
# post_init = ["echo done"]
[timberline.env]
auto_copy = true
patterns = [".env", ".env.*", "!.env.example", "!.env.template"]
scan_depth = 3
[timberline.submodules]
auto_init = true
recursive = true
[timberline.agent]
auto_launch = false
inject_context = true
link_project_session = false # symlink worktree agent session to main repo
Shell Integration
# Automatic install:
tl setup
# Or manually add to .zshrc / .bashrc:
eval "$(tl shell-init)"
Shell Aliases
Installed by tl setup (bash/zsh/fish):
| Alias | Description |
|---|---|
tln [args] |
Create worktree + cd into it (tl new wrapper) |
tlcd <name> |
cd into a worktree |
tldone [args] |
Archive current worktree + cd back to repo root |
tlunarchive <name> |
Restore archived worktree + cd into it |
tl-prompt |
Print worktree name for PS1 prompt integration |
Development
uv sync
make test # pytest
make lint # ruff + basedpyright
make fmt # ruff format
make check # all of the above
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 timberline-0.1.6.tar.gz.
File metadata
- Download URL: timberline-0.1.6.tar.gz
- Upload date:
- Size: 56.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.10 {"installer":{"name":"uv","version":"0.9.10"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e68659dc050c1f1f54e2ca4132a761f0cb83031022163b50891f693977f7d80c
|
|
| MD5 |
2679a4b065cefad9d2b44ad550877402
|
|
| BLAKE2b-256 |
533b695f9a60ff40661698a4dbfd23a503d23ed1482e486ffb118f59beb53e09
|
File details
Details for the file timberline-0.1.6-py3-none-any.whl.
File metadata
- Download URL: timberline-0.1.6-py3-none-any.whl
- Upload date:
- Size: 32.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.10 {"installer":{"name":"uv","version":"0.9.10"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5c78a272c1620fb63993dbd2c1119fc43e23a9c68d643eb34968141aa68f9cd
|
|
| MD5 |
b3e41c73b77da3aba6bf2ecf58a14a8f
|
|
| BLAKE2b-256 |
75f75774367b267e8548dde6a5df9ef93234884a5f743e4aa1dbe4104b885381
|