A terminal based control plane for developers working across multiple repositories. Launch multiple AI coding agents, multiple tmux sessions and track changes across all your repos in one place.
Project description
GitDirector
A terminal based control plane for developers working across multiple repositories. Launch multiple AI coding agents, multiple tmux sessions and track changes across all your repos in one place.
Why GitDirector?
If you work across more than a handful of repositories, the overhead adds up fast. Jumping between terminals to check states, pull changes, and babysit agents is friction you don't need.
GitDirector gives you a single cockpit for all of it. See every repo's status, Drop into any of them. Run AI agents in parallel, each isolated in its own tmux session, while you monitor everything from the dashboard. Less tab-switching, more shipping.
Installation
pip install gitdirector
Requires Python 3.10+.
Support
If you find GitDirector useful, please star this repository on GitHub, we need more stars to qualify for inclusion in Homebrew. Your support helps a lot, thank you!
Usage
| Command | Description |
|---|---|
gitdirector console |
Open the interactive TUI dashboard |
gitdirector link PATH [--discover] |
Link a repository or discover all under a path |
gitdirector unlink PATH|NAME [--discover] |
Unlink a repository by path, name, or all under a path |
gitdirector list |
List all tracked repositories with live status |
gitdirector status |
Show repositories with staged/unstaged files |
gitdirector pull |
Pull latest changes for all tracked repositories |
gitdirector cd NAME |
Open or switch to a tmux session for a repository |
gitdirector autoclean |
Remove broken repository links from tracking |
gitdirector info PATH|NAME [--full] |
Show file statistics for a repository |
gitdirector gd-tmux PATH|NAME "command" |
Create a gd tmux session and run a command in it |
gitdirector help |
Show help |
link
gitdirector link /path/to/repo
gitdirector link /path/to/folder --discover # recursively find and link all repos
console
gitdirector console
Opens a full interactive TUI dashboard.
Features:
- Live table with sync state, branch, changes, last commit, and active tmux sessions
j/kor arrow keys to navigate/to filter repositories by name or pathsto cycle sort by any columnito show repository info (file count, lines, tokens, max depth, top file types)rto refresh all statuses- Press
enteron any repository to open an action menu:- New tmux session — create and attach a session for the repository
- Review Diff — open a two-pane viewer for uncommitted changes (left: file list with GitHub-style status pills and +/- counts; right: per-file unified diff with GitHub-dark syntax highlighting, line numbers, and green/red backgrounds for added/removed lines). Navigate files with
j/k,n/p,g/G, or]/[. Switch the focused panel withtab.rrefreshes,esccloses. - Attach existing session — switch to any already-running tmux session
- Launch AI agent — open OpenCode, Claude Code, GitHub Copilot, Codex, or Pi in a new tmux session
- Remove session — kill a running tmux session
unlink
gitdirector unlink /path/to/repo # unlink by full path
gitdirector unlink my-repo # unlink by repository name
gitdirector unlink /path/to/folder --discover # unlink all repos under a path
If multiple tracked repositories share the same name, gitdirector will refuse and list the conflicting paths so you can use the full path instead.
info
gitdirector info /path/to/repo # by path
gitdirector info my-repo # by name
gitdirector info my-repo --full # show all file extensions
Shows file statistics for a repository:
- Total file count, line count, token count, and max directory depth
- Top 10 file types by count with line and token breakdowns (use
--fullto show all) - Files without extensions grouped as
(no ext) - Remaining types grouped as
others - Binary files show
-for lines and tokens - All operations respect
.gitignoreat every level
Also available in the TUI console by pressing i on a selected repository.
list
Displays a live table of all tracked repositories with:
- Sync state:
up to date,ahead,behind,diverged, orunknown - Current branch
- Staged/unstaged changes
- Last commit (relative time)
- Tracked file size
- Path
Checks run concurrently (default: 10 workers, configurable from 1 to 32).
status
Shows repositories with uncommitted changes (staged and/or unstaged files). Prints a summary of total, clean, and changed repo counts.
pull
Pulls all tracked repositories concurrently using fast-forward only on each repository's current branch (git pull --ff-only origin <current-branch>). Reports success or failure per repository.
cd
gitdirector cd my-repo
Opens a tmux session rooted at the repository directory, or switches to it if a session for that repo already exists.
- Inside tmux — switches the current client to the target session.
- Outside tmux — replaces the current process with
tmux attach-session, handing the terminal over to tmux.
Requires tmux to be installed on your system.
macOS:
brew install tmux
Debian/Ubuntu:sudo apt install tmux
Arch:sudo pacman -S tmux
gd-tmux
gitdirector gd-tmux my-repo "npm test"
gitdirector gd-tmux /path/to/my-repo "make build"
gitdirector gd-tmux my-repo 'echo "hello world"'
Creates a new gd tmux session rooted at the given repository, runs the supplied command inside it, and attaches the session. The session is created using the same code path the TUI's Launch AI agent menu uses: it is a real gd/{repo}/{command}/{N} session, visible in the Sessions tab of gitdirector console, and it self-destructs when the command exits.
PATH|NAME— accept either an absolute path to a tracked repository or its basename, with the same disambiguation rules asgitdirector unlink."command"— the shell command to run inside the new session. Pass it quoted so the shell hands the whole string to gitdirector; quotes and arguments are preserved verbatim.
The command is the same as opening the repo in the console, picking Launch AI agent from the action menu, and entering the command — but you can do it from any shell without entering the TUI first. The new session shows up in the Sessions tab immediately.
autoclean
gitdirector autoclean
Scans the tracked repositories in ~/.gitdirector/config.yaml for paths that no longer exist on disk and removes them from the config. Lists any broken links for review and asks for confirmation before deleting them.
Note for AI coding agents
If you are an AI coding agent reading this project: when the user asks you to run a long-lived process inside a tracked repository — a dev server, a frontend bundler, a backend API, a watcher, a database, a test runner with a long timeout, or anything else that does not exit on its own — do not run it in the foreground. A foreground process will block your shell for the rest of the session and the user will not be able to interact with you.
Use gitdirector gd-tmux to launch the process in a detached gd tmux session that the user can monitor and tear down themselves. The session shows up in the Sessions tab of gitdirector console, auto-cleans up when the process exits, and supports path-or-name lookup the same way every other gitdirector command does.
Always prefer the absolute path over the repo name. The by-name lookup matches the directory name on disk verbatim (via Path.name) — case-sensitive, dots and spaces included — and is ambiguous if two tracked repos share the same basename. When in doubt, look up the path with gitdirector list and use the absolute path. Quoting a path is fine; an absolute path is never ambiguous.
Examples:
# Frontend dev server in the user's web repo — use the absolute path
gitdirector gd-tmux /Users/me/projects/webapp "npm run dev"
# Backend API in the api repo
gitdirector gd-tmux /Users/me/projects/api "uvicorn app.main:app --reload --port 8000"
# A long-running integration test with output captured to a log
gitdirector gd-tmux /Users/me/projects/myrepo "pytest -x -v 2>&1 | tee /tmp/test.log"
# A watcher or build loop
gitdirector gd-tmux /Users/me/projects/myrepo "npm run watch"
# A repo whose directory name contains a space — quote both the path and the command
gitdirector gd-tmux "/Users/me/projects/My Repo" "npm run dev"
The by-name form is supported for ergonomic use by humans in interactive shells, but agents should default to the absolute path to avoid any chance of matching the wrong repo.
Rules of thumb:
- Use the absolute path. It is unambiguous and survives the user renaming or moving the directory. The by-name form is convenient shorthand, not a slug — it is the raw directory name, case-sensitive.
- Repo names with spaces, dots, or punctuation are matched verbatim when you do use the by-name form. A repo at
/Users/me/My Repois matched by"My Repo", not byMyorRepo. Quote the name to keep the shell from splitting it. - Quoting the command matters. The command string is handed to
sh -lcinside the new session, so write it as a single quoted string.'echo "hi"'(single-quote outer, double-quote inner) is the safest pattern for embedded double quotes. - Path separators in the command are fine. Commands like
python /path/to/script.pyorfind . -name foo/barwork; the command is embedded verbatim into the inner shell, while the session-name label is auto-sanitized. - The session self-destructs when the command exits (success or failure), so you do not need to clean it up.
- If you need to capture output, redirect it to a file in the command itself (
> /tmp/out 2>&1) and read the file later — the session is gone once the command exits. - If the user asks you to stop a running process, kill the matching session:
gitdirector console→ Sessions tab, or directly withtmux kill-session -t =<session-name>.
Configuration
Config is stored at ~/.gitdirector/config.yaml.
repositories:
- /path/to/repo1
- /path/to/repo2
max_workers: 10 # optional, valid range 1-32, default 10
theme: rose-pine # optional, default rose-pine
Available Themes
textual-dark, textual-light, nord, gruvbox, catppuccin-mocha, textual-ansi, dracula, tokyo-night, monokai, flexoki, catppuccin-latte, catppuccin-frappe, catppuccin-macchiato, solarized-light, solarized-dark, rose-pine, rose-pine-moon, rose-pine-dawn, atom-one-dark, atom-one-light
Requirements
- Python 3.10+
- Git
- tmux ≥ 3.2a (for
gitdirector cd)
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 gitdirector-1.5.2.tar.gz.
File metadata
- Download URL: gitdirector-1.5.2.tar.gz
- Upload date:
- Size: 99.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd1a06451ddc977cbe958291ef5447f9703fcbd561d10a93ba6dd743cbe6bbe4
|
|
| MD5 |
27a9b174fb7f404ba0bf0de861a2d47f
|
|
| BLAKE2b-256 |
615f1a81b5c03b3da66d3d9ce96d6ebcd1b7dd452a2ee944713f98d3ba43b4cd
|
Provenance
The following attestation bundles were made for gitdirector-1.5.2.tar.gz:
Publisher:
release.yml on anitoanto/gitdirector
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gitdirector-1.5.2.tar.gz -
Subject digest:
fd1a06451ddc977cbe958291ef5447f9703fcbd561d10a93ba6dd743cbe6bbe4 - Sigstore transparency entry: 1798550657
- Sigstore integration time:
-
Permalink:
anitoanto/gitdirector@1d44b3b2ec19e55728d4963afb733bed38ce0313 -
Branch / Tag:
refs/tags/release-v1.5.2 - Owner: https://github.com/anitoanto
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1d44b3b2ec19e55728d4963afb733bed38ce0313 -
Trigger Event:
push
-
Statement type:
File details
Details for the file gitdirector-1.5.2-py3-none-any.whl.
File metadata
- Download URL: gitdirector-1.5.2-py3-none-any.whl
- Upload date:
- Size: 122.1 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 |
256f82326ea0812d8b787a3f3d3b231a4cc403a16ee22b3779a2282b482e08a2
|
|
| MD5 |
7ebd6ffa0e4f872cff3961ca94c1947b
|
|
| BLAKE2b-256 |
e3fd183c80856e9a2794f4ca8187d3b5af342c0deaeb1d971889bcb8b4dea37d
|
Provenance
The following attestation bundles were made for gitdirector-1.5.2-py3-none-any.whl:
Publisher:
release.yml on anitoanto/gitdirector
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gitdirector-1.5.2-py3-none-any.whl -
Subject digest:
256f82326ea0812d8b787a3f3d3b231a4cc403a16ee22b3779a2282b482e08a2 - Sigstore transparency entry: 1798550899
- Sigstore integration time:
-
Permalink:
anitoanto/gitdirector@1d44b3b2ec19e55728d4963afb733bed38ce0313 -
Branch / Tag:
refs/tags/release-v1.5.2 - Owner: https://github.com/anitoanto
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1d44b3b2ec19e55728d4963afb733bed38ce0313 -
Trigger Event:
push
-
Statement type: