mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-10-03 16:01:59 +00:00
* feat(worktree): setup script, .worktreeinclude, fresh base, recoverable removal - Start new worktrees from the remote default branch, fetched first, with --no-track; fall back to the current branch without a remote. - Carry gitignored files listed in .worktreeinclude over from the main checkout, copy-on-write (clonefile on macOS, copy_file_range elsewhere); remote hosts copy through the Host trait under a size budget. - Run .tty7/setup in the first pane before the agent, with TTY7_ROOT_PATH, TTY7_WORKTREE_PATH, TTY7_WORKTREE_NAME and a per-worktree TTY7_PORT block. The script only runs once its exact content is approved for the repo. - The New Worktree dialog picks what the first pane starts (Shell or a recent agent) and takes a task for agents that open on a first message. - Removal snapshots the checkout, uncommitted work included, under refs/tty7/trash/<name> first; the ref also retires the name. A branch git refuses to delete is reported instead of silently kept. - Hide .tty7/worktrees via info/exclude rather than a catch-all .tty7/.gitignore, so .tty7/setup can be committed. * feat(cli): tty7 worktree new/ls/rm - worktree new: the GUI dialog's worktree from the command line — create, carry .worktreeinclude, open a tab named after the branch, and type .tty7/setup && <agent> [task] into it. Prints the path first. - worktree ls: every checkout of the repo, tty7's marked, with the live panes working in each. - worktree rm: refuses while panes are inside unless --close-panes, and a dirty checkout unless --force; reports the snapshot ref and a kept branch. - Move shell_quote and the first-line builders into tty7-core so the GUI and the CLI type the same line. - Docs: CLI reference and the Worktrees page cover .worktreeinclude, .tty7/setup, TTY7_PORT and recoverable removal. * fix(worktree): run setup and the agent inside the worktree; Start is a dropdown - The first line now opens with cd into the worktree: a shell's startup files can move the pane, and setup then ran in (and wrote into) the main checkout. - The Start choice is a dropdown listing Shell and every agent this machine offers, instead of a segmented switch capped at three.
133 lines
4.6 KiB
Plaintext
133 lines
4.6 KiB
Plaintext
---
|
|
title: "Worktrees"
|
|
description: "One checkout per task: fresh branch, set up, and handed to an agent — in one dialog."
|
|
---
|
|
|
|
Running two agents on the same repository at once means they fight over the
|
|
working tree. A git worktree is the fix, and tty7 makes it a single dialog:
|
|
create the checkout, make it runnable, and start the agent in it.
|
|
|
|
## Creating one
|
|
|
|
**New Worktree Tab…** — in Search Everywhere, the tab's right-click menu, and
|
|
the application menu — asks:
|
|
|
|
| Field | Default |
|
|
|---|---|
|
|
| **Worktree Name** | A fresh name that no branch, directory or removed worktree has used |
|
|
| **New Branch** | The same name, editable |
|
|
| **Start From** | The remote's default branch (`origin/main`), fetched first; the current branch when there is no remote |
|
|
| **Start** | A dropdown: Shell, or any agent on this machine — the last one used is picked |
|
|
| **Task** | The agent's first message (Claude Code, Codex and Gemini take one) |
|
|
|
|
Each field opens on a suggestion you can accept or type straight over.
|
|
|
|
<Frame caption="The New Worktree Tab dialog, every field pre-filled">
|
|
<img src="/images/new-worktree.webp" alt="Creating a worktree" />
|
|
</Frame>
|
|
|
|
Confirm and tty7 creates the worktree, copies in what `.worktreeinclude` asks
|
|
for, opens a tab there, and runs `.tty7/setup` followed by the agent. The
|
|
[sidebar](/window/sidebar) files it under the same repository group as its
|
|
parent, on its own branch.
|
|
|
|
The new branch does not track `origin/main`: its first `git push -u` goes to a
|
|
branch of its own name.
|
|
|
|
## Files a checkout needs: `.worktreeinclude`
|
|
|
|
A fresh checkout has none of your gitignored files — no `.env`, no local
|
|
settings. List the ones it needs in `.worktreeinclude` at the repository root,
|
|
in gitignore syntax:
|
|
|
|
```
|
|
.env
|
|
.env.local
|
|
config/local/*.json
|
|
```
|
|
|
|
A path is copied only if it matches **and** git ignores it.
|
|
|
|
Copies are copy-on-write where the filesystem supports it (APFS on macOS,
|
|
btrfs and XFS on Linux): a copied directory costs no disk until one side
|
|
changes it. Nothing is symlinked, because two checkouts sharing one dependency
|
|
tree break each other the moment their lockfiles disagree. On a remote machine
|
|
the files go over the connection, up to 64 MB in total — enough for
|
|
configuration, not for `node_modules`.
|
|
|
|
## Making it runnable: `.tty7/setup`
|
|
|
|
Commit an executable at `.tty7/setup` — any language, with a shebang — and
|
|
every new worktree runs it in its first tab, before the agent. Install
|
|
dependencies there, rather than copying them:
|
|
|
|
```sh
|
|
#!/bin/sh
|
|
set -e
|
|
pnpm install
|
|
echo "PORT=$TTY7_PORT" > .env.local
|
|
```
|
|
|
|
| Variable | Value |
|
|
|---|---|
|
|
| `TTY7_ROOT_PATH` | The main checkout |
|
|
| `TTY7_WORKTREE_PATH` | The new worktree |
|
|
| `TTY7_WORKTREE_NAME` | Its directory name |
|
|
| `TTY7_PORT` | The first of ten ports this worktree has to itself |
|
|
|
|
`TTY7_PORT` comes from the worktree's path, so a dev server started there does
|
|
not collide with its siblings, and the same worktree always gets the same
|
|
ports. The setup and the agent are chained with `&&`: if setup fails, the
|
|
agent does not start and the error stays on screen.
|
|
|
|
The script is code from the repository, so tty7 asks before running it the
|
|
first time, and again whenever its content changes. Without a setup script,
|
|
the dialog suggests one based on your lockfile (`pnpm install`, `uv sync`, …).
|
|
Setup runs on macOS and Linux; Windows worktrees skip it.
|
|
|
|
## Where they go
|
|
|
|
Worktrees land inside the repository, under:
|
|
|
|
```
|
|
<repo>/.tty7/worktrees/<name>
|
|
```
|
|
|
|
The directory is listed in `.git/info/exclude`, so it never shows up in
|
|
`git status`, and `.tty7/setup` next to it stays committable.
|
|
|
|
## Removing one
|
|
|
|
Closing a worktree tab offers to remove the worktree with it:
|
|
|
|
- **Clean tree** — *Remove Worktree* or *Keep*.
|
|
- **Dirty tree** — the dialog says so, and removing requires the explicit
|
|
*Discard Changes & Remove*.
|
|
|
|
Before anything is deleted, the checkout's state — uncommitted and untracked
|
|
files included — is saved under `refs/tty7/trash/<name>`. Even a discarded
|
|
change can come back:
|
|
|
|
```bash
|
|
git checkout refs/tty7/trash/<name> -- .
|
|
```
|
|
|
|
The branch is deleted only if it is merged; otherwise tty7 says it kept it.
|
|
*Keep* leaves the worktree on disk, and `tty7 worktree ls` finds it later.
|
|
|
|
## From the command line
|
|
|
|
```bash
|
|
tty7 worktree new --agent claude --task "fix the flaky login test"
|
|
tty7 worktree ls
|
|
tty7 worktree rm quiet-otter
|
|
```
|
|
|
|
See the [CLI reference](/cli/reference#worktree--one-checkout-per-task).
|
|
|
|
<Tip>
|
|
Pair this with [agent sessions](/agents/sessions): a worktree per agent means
|
|
two Claude Codes can work on the same repository without stepping on each
|
|
other's files.
|
|
</Tip>
|