Make any project agent-ready. Detect its shape once, then spin up isolated parallel environments — ports, DBs, env files, hooks — on demand, so you and your AI agents can work side-by-side without colliding.
You can't run your agent on feat-a while you're on feat-b if both fight
for port 3000, the same Postgres volume, and the same .env. git worktree add gives you a folder — 5% of the work. The painful 95% (docker port
collisions, COMPOSE_PROJECT_NAME, DB volumes shared with main, copied env
files, install hooks, cleanup, multi-repo coordination) is what cograft
handles for you.
cd ~/my-project
# 1. One-time. AI scaffolder detects shape + writes the config.
# Point your agent (Claude Code, Codex, Cursor, …) at the skill markdown
# at ~/.local/share/cograft/SKILL.md and let it run against the project.
# .worktrees/ is gitignored by default — solo mode. Zero impact on teammates.
# (Share with the team later: swap the ignore for the team-mode negation —
# shares config only, keeps checkouts/dumps local. See Step 4.5 in the skill.)
# 2. Daily.
cograft new feat-x # isolated environment ready
cograft ls
cograft rm feat-x # full teardown feat-a feat-b feat-c ← parallel worktrees
┌──────────┐ ┌──────────┐ ┌──────────┐
│ web:3001 │ │ web:3002 │ │ web:3003 │ isolated
│ api:8001 │ │ api:8002 │ │ api:8003 │ ports + DBs
│ db_a │ │ db_b │ │ db_c │ per worktree
└─────┬────┘ └─────┬────┘ └─────┬────┘
│ │ │
└────────────────────┼────────────────────┘
│
┌────────────┴────────────┐
│ project (one or │ ← cograft auto-detects
│ several .git roots) │ the project shape
└─────────────────────────┘
The AI scaffolder reads your project once and figures out the shape:
| Shape | Signal | Config it writes |
|---|---|---|
| Single repo | one .git/, no workspace manager |
<repo>/.worktrees/config.sh |
| Monorepo workspace | pnpm-workspace.yaml / turbo.json / nx.json / lerna.json / Cargo workspace / go.work |
One config with per-workspace port ranges |
| Multi-repo umbrella | parent dir with ≥2 git repos inside | .worktrees/umbrella.sh + one .worktrees/config.sh per repo, coordinated by shared slug + offset |
The scaffolder writes the files locally and gitignores them by default.
Solo mode — your machine only, no impact on teammates. Everything (config,
checkouts, dumps) lives in one .worktrees/; switch to team mode later by
swapping the whole-dir ignore for a negation that shares only the config
(config.sh + hooks/) and keeps checkouts and dumps local.
After scaffolding, every cograft new <slug> is deterministic — no LLM on
the hot path.
| Problem | What cograft does |
|---|---|
| Docker port collisions | Deterministic per-worktree offset → host ports remapped via auto-generated docker-compose.override.yml |
| Two worktrees sharing the main DB | COMPOSE_PROJECT_NAME=cograft-<slug> + external volumes overridden → fresh isolated volume per worktree |
| A fresh worktree's DB starts empty & useless | Scaffolder asks once how to fill it — migrate-only, run your seed command, or clone a canonical base dump ("branch the DB") — and writes the matching hook |
.env / .env.local / app-level envs |
Detected by the scaffolder, copied into the worktree at create time |
| Install deps (pnpm, poetry, uv, cargo…) | Lockfile detected → hook runs the right install command |
| Multi-repo coordination | Umbrella manifest creates one worktree per repo with the same slug + shared offset namespace |
| Cleanup leaving orphan containers/volumes | cograft rm brings down compose with the right project name, removes external-volume overrides, branches, worktree dirs — atomically across the whole umbrella |
Drift when docker-compose.yml or lockfile changes |
cograft doctor flags it, re-run the scaffolder to update |
- You have a multi-repo project (frontend + backend + shared in separate repos) and want one coordinated environment per task.
- You have a monorepo with many apps that need per-app port ranges and env coordination.
- You have a mixed-stack project (Django + Next + Rust) needing hooks written per stack.
- You want to start solo (gitignored) and optionally share with the team later when you've validated cograft fits your workflow.
- You work serially on branches and don't run parallel worktrees yet. Plain branches are fine.
- You're on a cloud dev environment (Coder, Gitpod, Codespaces). Different category — cograft is local.
curl -fsSL https://raw.githubusercontent.com/isromero/cograft/main/install.sh | bashInstalls the cograft runner to /usr/local/bin and the cograft-init
scaffolder (a markdown file) to ~/.local/share/cograft/SKILL.md. Any AI
coding agent — Claude Code, Codex, Cursor, Aider, whatever — or a human can
read it. Re-run to update.
Cograft also prints a one-line hint when a new release exists (passive,
once a day). Force a check with cograft update.
Advanced install options
install.sh honours these env vars (override before running):
| Variable | Default | What it does |
|---|---|---|
COGRAFT_TAG |
main |
Branch or tag to install from. Pin to a specific release. |
COGRAFT_BIN_DIR |
/usr/local/bin |
Where to put the cograft binary. Use $HOME/.local/bin for no-sudo. |
COGRAFT_SKILL_FILE |
~/.local/share/cograft/SKILL.md |
Where the skill markdown lives. If a ~/.claude/skills/ layout exists on the machine, a symlink is also dropped there for auto-discovery. |
COGRAFT_INSTALL_SKILL |
1 |
Set to 0 to install only the runner. |
COGRAFT_NO_UPDATE_CHECK |
unset | Set to 1 to silence the passive update hint. |
The script is ~75 lines of bash — read it at install.sh
before piping to bash if you prefer.
The scaffolder is a markdown file at ~/.local/share/cograft/SKILL.md. Any
AI coding agent (or a human) that can read markdown and write files can
execute it. Open your agent in the project directory and ask it:
Follow the instructions in
~/.local/share/cograft/SKILL.mdagainst this project. Detect the shape and write the config.
This works with Claude Code, Codex, Cursor, Cline, Aider,
Continue, custom agents, or by hand. Agents with a slash-command convention
will auto-discover the skill if their layout was already on the machine at
install time (e.g. claude /cograft-init if ~/.claude/skills/ exists).
Review the draft — the scaffolder leaves # REVIEW: markers where it
wasn't sure. By default .worktrees/ is appended to each repo's
.gitignore (solo mode): the config stays on your machine, no PR forced on
the team.
When you've validated cograft fits your workflow and the team wants in:
# Remove the `.worktrees/` entry from each repo's .gitignore, then:
git add .worktrees/
# Teammates pull → instantly worktree-ready.cograft new my-task # isolated worktree(s) ready
cograft ls
cograft rm my-task
cograft doctor # drift + port health| Command | What it does |
|---|---|
cograft new <slug> |
Create worktree(s) + materialize config + run hooks |
cograft apply <path> |
Materialize config on a worktree created by another tool |
cograft ls |
List active worktrees + offsets |
cograft rm <slug> |
Tear down docker, branches, worktree dirs (atomic across umbrella) |
cograft doctor |
Drift detection + container health |
If another tool already creates git worktrees for you, cograft can run as a post-create step:
git worktree add /path branch-x
command -v cograft >/dev/null 2>&1 && cograft apply /pathIf cograft is installed, the worktree gets isolated config. If not, the user gets a plain worktree (no regression). See INTEGRATION.md.
Grafting joins branches to a shared rootstock so they grow as one tree. Git
already uses the vocabulary (git replace --graft). Cograft is multiple
branches co-grafted onto one git rootstock at once — each growing in its
own isolated working dir. For multi-repo projects, several rootstocks
coordinated by a small umbrella manifest.
MIT.