| 1 | # Source control |
| 2 | |
| 3 | T3 Code integrates with GitHub, GitLab, Forgejo, Gitea, Bitbucket, Azure DevOps, and GitCafe to clone |
| 4 | and publish repositories, create pull requests, and review changes. |
| 5 | |
| 6 | ## Review turn changes |
| 7 | |
| 8 | A turn's changed files and diff show only the turn's own work. When a turn pulls, merges, or |
| 9 | rebases, the files Git brought in are left out. A file stays in the list when the turn edited it, |
| 10 | committed it, or fixed a conflict in it. Use the branch comparison to review everything that changed |
| 11 | against your base branch. Restore still returns the complete saved workspace. |
| 12 | |
| 13 | ## Connect an account |
| 14 | |
| 15 | Install Git and configure authentication on the machine running your T3 Code server. For a remote |
| 16 | environment, do this on the remote machine. After signing in, open **Settings → Source Control** |
| 17 | and choose **Rescan**. |
| 18 | |
| 19 | ### GitHub |
| 20 | |
| 21 | T3 Code talks to GitHub's API directly and only needs a token. Any of these works, in this |
| 22 | order of precedence: |
| 23 | |
| 24 | 1. A token saved in **Settings → Source Control → GitHub**. It is kept in the server's secret |
| 25 | store, and works without the GitHub CLI. |
| 26 | 2. `GH_TOKEN` (`GH_ENTERPRISE_TOKEN` with `GH_HOST` for GitHub Enterprise Server) in the |
| 27 | server's environment. |
| 28 | 3. [GitHub CLI](https://cli.github.com/) 2.81.0 or newer, signed in with `gh auth login`. |
| 29 | |
| 30 | If `gh` is signed in to several accounts or hosts, expand **GitHub** in the same place to pick |
| 31 | the account each host uses or turn a host off. A saved token or `GH_TOKEN` takes precedence |
| 32 | over that choice; a host turned off stays off either way. |
| 33 | |
| 34 | For GitHub Enterprise, sign in with `gh auth login --hostname YOUR_HOST`. T3 Code treats a |
| 35 | custom server name as GitHub once it has a credential for that host. |
| 36 | |
| 37 | ### Forgejo and Gitea |
| 38 | |
| 39 | Install [Forgejo CLI (`fj`)](https://codeberg.org/forgejo-contrib/forgejo-cli) or |
| 40 | [Gitea CLI (`tea`)](https://gitea.com/gitea/tea) 0.16 or later on your T3 Code server. |
| 41 | Sign in with `fj --host https://your-server auth add-token` or `tea login add`. |
| 42 | Repeat for each server you use, including Codeberg. |
| 43 | |
| 44 | T3 Code prefers a matching `fj` login and falls back to `tea` when `fj` is unavailable |
| 45 | or has no login for that server. Once an account is selected, failed actions stay on that |
| 46 | account. Settings shows the detected CLI. Forgejo and Gitea share one integration entry. |
| 47 | Servers hosted under a URL subpath, such as `https://example.com/forgejo`, use `tea` because |
| 48 | fj 0.6 does not preserve the subpath when checking its account. |
| 49 | |
| 50 | When cloning or publishing, use a full repository URL to select a specific server. |
| 51 | You can use `owner/repo` when only one fj server is configured, or with your default `tea` |
| 52 | login when fj is unavailable or unconfigured. With multiple fj servers, use the full URL. |
| 53 | If you have multiple `tea` accounts on one server, select one with |
| 54 | `tea login default <login-name>`. Git push and clone also need Git credentials or an SSH key |
| 55 | for that server. |
| 56 | |
| 57 | ### GitLab |
| 58 | |
| 59 | Install [GitLab CLI](https://gitlab.com/gitlab-org/cli), then sign in: |
| 60 | |
| 61 | ```bash |
| 62 | glab auth login |
| 63 | ``` |
| 64 | |
| 65 | ### Bitbucket |
| 66 | |
| 67 | Open **Settings → Source Control**, expand **Bitbucket**, and enter one of: |
| 68 | |
| 69 | - **Access token**: a token created for one repository, project, or workspace. It can only reach |
| 70 | what it was created for. |
| 71 | - **Atlassian account email** and **API token**: an Atlassian API token for your account. It can |
| 72 | reach every repository you can. Give it read/write access to repositories and pull requests, plus |
| 73 | user read access (`read:user:bitbucket`). |
| 74 | |
| 75 | A field saves when you leave it, and applies right away. The access token wins when both are saved. |
| 76 | Credentials are saved on the environment's server, so select a remote environment to configure |
| 77 | it. Saved tokens can't be viewed again; enter a new one to replace it, or choose **Remove** to clear |
| 78 | everything saved for Bitbucket. |
| 79 | |
| 80 | If no credentials are saved, T3 Code falls back to these variables in the server's environment. |
| 81 | Restart the server after changing them: |
| 82 | |
| 83 | ```bash |
| 84 | export T3CODE_BITBUCKET_ACCESS_TOKEN="your-access-token" |
| 85 | # or |
| 86 | export T3CODE_BITBUCKET_EMAIL="you@example.com" |
| 87 | export T3CODE_BITBUCKET_API_TOKEN="your-token" |
| 88 | ``` |
| 89 | |
| 90 | ### Azure DevOps |
| 91 | |
| 92 | Install [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/), add the DevOps extension, and sign in: |
| 93 | |
| 94 | ```bash |
| 95 | az extension add --name azure-devops |
| 96 | az login |
| 97 | ``` |
| 98 | |
| 99 | ### GitCafe |
| 100 | |
| 101 | Install the GitCafe CLI and sign in: |
| 102 | |
| 103 | ```bash |
| 104 | bun install -g @gitcafe/cli |
| 105 | cafe auth login --host https://git.cafe/api |
| 106 | ``` |
| 107 | |
| 108 | Alternatively, open **Settings → Source Control**, expand **GitCafe**, and enter a token. It is |
| 109 | kept in the server's secret store, applies right away, and is used before `CAFE_TOKEN` and the |
| 110 | `cafe` login. Or set `CAFE_TOKEN` in the server's environment and restart it. Both tokens are only |
| 111 | sent to `git.cafe`; `CAFE_TOKEN` follows `CAFE_HOST` if you set it. Repositories on |
| 112 | `staging.git.cafe` need their own login with `--host https://staging.git.cafe/api`. |
| 113 | |
| 114 | Line comments, reviewer requests, and labels are not available for GitCafe pull requests yet. |
| 115 | Merging a stack lands it through GitCafe, and updating a branch restacks the layers above it. |
| 116 | |
| 117 | ## Start, clone, or publish a project |
| 118 | |
| 119 | To start from nothing, choose **New project** in the command palette (`Cmd/Ctrl+K`), or |
| 120 | **New project** under **Add Project** on any client, and type a name. T3 Code makes a Git |
| 121 | repository in `~/.t3/projects` (the `projects` folder of your T3 data directory) with a README, |
| 122 | an icon, and a first commit, then opens a new thread in it. Until the project has a thread, new |
| 123 | threads work in its folder, even when your default is a new worktree. The folder is named after the project, |
| 124 | like `pinball-stats` for "Pinball Stats". Turn on **Create private repository on GitHub** to also |
| 125 | publish it. If Git has no name or email on that machine, the project is created without the |
| 126 | first commit. |
| 127 | |
| 128 | Use **Add Project** in the command palette (`Cmd/Ctrl+K`) to clone a repository. Choose a hosting |
| 129 | provider or paste a Git URL, then choose where to save it. The project opens right away while the |
| 130 | clone runs in the background: you can write your first prompt, and sending waits until the files |
| 131 | are in place. A toast tracks progress and lets you cancel; if the clone fails, retry it from the |
| 132 | toast or from the banner above the composer. |
| 133 | |
| 134 | For a local Git repository without a remote, **Publish Repository** creates a hosted repository, |
| 135 | adds it as `origin`, and pushes your commits. If there are no commits yet, it creates the remote; |
| 136 | make your first commit before pushing. |
| 137 | |
| 138 | ## Create a pull request |
| 139 | |
| 140 | Use a thread's Git actions to commit, push, and create a pull request. T3 Code can generate commit |
| 141 | messages, review titles, and descriptions from your changes. |
| 142 | |
| 143 | An existing fork PR can appear beside the branch even if you pushed without setting an upstream. |
| 144 | If its badge is missing because several remotes hold that branch, set the branch's upstream to |
| 145 | the intended remote with `git branch --set-upstream-to=<remote>/<branch>`. |
| 146 | |
| 147 | Choose the writing style and model in **Settings → Source Control**. **Repository conventions** |
| 148 | uses the project's instructions and recent commit subjects. |
| 149 | |
| 150 | ## Review and merge |
| 151 | |
| 152 | Open **Pull requests** to review changes and comments, request reviewers, check out a branch, |
| 153 | or merge. You can edit review titles and descriptions and your own comments where the host allows it. |
| 154 | GitLab calls these merge requests. |
| 155 | |
| 156 | Configured work repositories use Mergebot for PR status, checks, and live updates. |
| 157 | Their PR links open Mergebot inside T3 Code's Browser, with its queue and review actions. |
| 158 | Open **Mergebot** from the sidebar or Pull requests page to see the queue without a chat. |
| 159 | On mobile, these links use the environment's server Browser and require browser access. |
| 160 | If Mergebot disconnects, PR decisions wait for a verified update after it reconnects. |
| 161 | |
| 162 | On mobile, **Pull requests** lists reviews across your connected environments. Open a review |
| 163 | to read its description, activity, commits, and changed files. Line comments stay as drafts |
| 164 | until you submit the review. **Work on PR** opens a chat with the review attached; sending |
| 165 | the first message prepares a worktree from the review's branch. |
| 166 | |
| 167 | Previously loaded lists, review details, guides, and diff pages remain readable on mobile |
| 168 | without a connection, including after restarting the app. Saved content refreshes when the |
| 169 | environment reconnects; submitting changes requires a connection. |
| 170 | |
| 171 | Enable **Remove agent credits when merging** in Settings → Source Control to remove recognized |
| 172 | agent co-author and generated-by lines from GitHub merge and squash commit messages. Human |
| 173 | co-authors stay credited. The setting is off by default and projects can override it. It also |
| 174 | applies to auto-merge, but not merge queues or native stack merges. Original commits keep their |
| 175 | messages, so merge and rebase can still retain agent credits in those commits. |
| 176 | |
| 177 | On web and desktop, hold **Shift** in the GitHub pull request list for quick actions. |
| 178 | To close several, press **Close**, drag across the rows in the same group, and release. |
| 179 | Press **Escape** before releasing to cancel. Failed closes stay in the list so you can retry them. |
| 180 | |
| 181 | GitHub, GitLab, and Azure DevOps support auto-merge while checks are outstanding. GitHub also |
| 182 | supports approving waiting fork workflows and opening a revert pull request for a merged change. |
| 183 | |
| 184 | GitHub sharing is off by default. In Settings → Connections → GitHub sharing (Environments on mobile), choose |
| 185 | **Read PRs** or **Read and act** for each environment you trust to share GitHub access. |
| 186 | Enable both the original environment and the environment answering its requests on this client. |
| 187 | **Read and act** can use broader GitHub permissions than the original environment's credential; |
| 188 | only enable it for environments you control and trust. Changing a saved endpoint or removing an |
| 189 | environment clears its permission. |
| 190 | |
| 191 | GitHub review details, linked PR status, and permitted review actions can then use another |
| 192 | connected environment signed in to the same GitHub account. Each needs a project on that host. |
| 193 | A connected local environment is preferred for actions and can answer slow or failed reads. |
| 194 | Browsers and mobile clients need a paired environment to use its GitHub credentials. |
| 195 | Credentials stay on their machines. Previously verified credentials remain usable for routing |
| 196 | for ten minutes during a GitHub outage; new credentials must be verified first. An action with |
| 197 | an uncertain result is never automatically retried elsewhere. Listings, diffs, and checkout or |
| 198 | PR creation from Git actions continue to use the project's environment. |
| 199 | |
| 200 | For Azure DevOps, use the host website to change comments. Bitbucket does not support reopening a |
| 201 | declined pull request. |
| 202 | |
| 203 | ### Review guides |
| 204 | |
| 205 | Review guides are in beta. Turn on **Review guides** in Settings → Source Control to add the |
| 206 | **Guide** tab to pull requests on that server. On mobile, move between stops with **Next** |
| 207 | and the back button; a stale guide offers a rewrite and hides excerpts that no longer match |
| 208 | the current change. |
| 209 | |
| 210 | The **Guide** tab gives you a tour of a pull request without reading it line by line: stops |
| 211 | through the change in reading order. Each stop points at the lines worth reading, and a stop marked |
| 212 | **Look closely** has a call only a maintainer can make. Mechanical changes such as renames and |
| 213 | snapshots are grouped at the end, and every changed file appears somewhere on the tour. |
| 214 | Conversations already resolved in review are left out. For a pull request in a stack, the guide |
| 215 | covers that layer only, and may point out what a lower layer introduced or what a higher one uses. |
| 216 | |
| 217 | Choose **Write guide** to have the review guide model from Settings → Source Control read the |
| 218 | change in a temporary checkout; without one set, the source control writer model is used. Nothing |
| 219 | in the checkout is changed, and a large pull request takes a few minutes; you can go elsewhere in |
| 220 | the app. On web, you are told when the guide is ready; on mobile, return to the guide to check |
| 221 | its progress. Claude and Codex can write guides. The guide is |
| 222 | kept for everyone using this server. To write it again, for example after a push or after changing |
| 223 | the model or instructions, choose **Rewrite guide** from the pull request's **⋯** menu. |
| 224 | |
| 225 | On web, while reading a stop, select lines in an excerpt to add a comment to your review or ask an agent |
| 226 | about them; comments wait with the ones from the **Code** tab until you send the review. Choose a |
| 227 | suggested question, or **Ask about this stop**, to open a thread that already knows which stop you |
| 228 | are on. **Finish review** on the last stop opens the review with everything you collected. |
| 229 | |
| 230 | Agents can write guides too: ask one to prepare guides for a set of pull requests, and it starts |
| 231 | them for you. Each is read through the project whose checkout has that repository. |
| 232 | |
| 233 | To shape guides to your taste, write **Review guide instructions** in Settings → Source Control, |
| 234 | such as what to show first or what to skip; projects can override them. They change emphasis and |
| 235 | ordering, not the guide's layout or which files it covers. |
| 236 | |
| 237 | ### Mark files as viewed |
| 238 | |
| 239 | Tick a file off in the **Code** tab once you have read it and it collapses; the toolbar keeps a |
| 240 | running count. A tick belongs to the pull request rather than to a commit, so scoping the tab to a |
| 241 | single commit keeps them. A file pushed to after you cleared it comes back marked **Changed**. |
| 242 | |
| 243 | On GitHub these are GitHub's own viewed marks, so a review carries between T3 Code and github.com |
| 244 | in either direction. Forgejo, GitLab, Bitbucket, and Azure DevOps expose no record T3 Code can read, so the |
| 245 | server you are connected to keeps them instead: they follow you across the apps connected to that |
| 246 | server, but the host's own site will not show them, and the count reads **viewed in T3 Code**. |
| 247 | |
| 248 | On mobile, open a changed file and mark it viewed from its header. Viewed files collapse, |
| 249 | and their marks follow the same rules as on web and desktop. |
| 250 | |
| 251 | ## Troubleshooting |
| 252 | |
| 253 | - **Not authenticated:** run the provider's login command on the server, then rescan. For Bitbucket, |
| 254 | check the credentials saved in Settings → Source Control, or confirm the running server received |
| 255 | the environment variables. |
| 256 | - **GitHub sign-in cannot be verified:** update GitHub CLI to at least 2.81.0, or save a token in Settings → Source Control. |
| 257 | - **Push fails despite a connected account:** check the Git remote's credentials. SSH and HTTPS |
| 258 | remotes can require separate setup from the hosting provider's API access. |
| 259 | - **A review cannot load:** open it on the host website while resolving connectivity, permissions, |
| 260 | or rate limits. |
| 261 | |
| 262 | ## Linked pull requests |
| 263 | |
| 264 | A thread can hold several pull requests, including reviews from another repository on the same host. |
| 265 | Use **Link pull request** in the command palette or **Linked pull requests** panel, or right-click a |
| 266 | pull request link in the conversation. Creating a pull request from Git actions links it automatically. |
| 267 | Agents can link their pull requests with the `link_pull_request` tool. |
| 268 | |
| 269 | Use **Link this PR** in a branch-detected badge's tooltip to keep it with the thread. From a review |
| 270 | on the Pull Requests page, **Link to thread** lets you search for an active thread. The review header |
| 271 | also lists the threads that link to it, including archived threads, so you can return to their context. |
| 272 | |
| 273 | Thread badges show a stack's layer count or the current review number with a count of additional |
| 274 | links. Clicking a badge with more than one review opens the **Linked pull requests** panel. On mobile, the Git overview lists linked reviews and their stacks; tap a review to open it. |
| 275 | Linking and unlinking are available in the web and desktop clients. |
| 276 | |
| 277 | The **Linked pull requests** panel lists every review and groups stacks. Unlink a review from its |
| 278 | row menu. An unlinked stack layer stays out of later syncs. Open linked reviews refresh on the server; |
| 279 | closed reviews refresh periodically so reopening one on the host is detected. Merged reviews refresh |
| 280 | when requested. A settled thread's reviews stop refreshing until you unsettle it. With **Auto-settle merged threads** enabled, a thread can settle after every linked |
| 281 | review is terminal. An open or unsynced link keeps it active. |
| 282 | |
| 283 | Ask the agent to watch, monitor, or babysit a pull request and it calls `watch_pull_request`. While |
| 284 | the thread is active, the server checks the pull request every two minutes and wakes the agent when a |
| 285 | check fails, the required checks pass, someone else comments or reviews, or the branch starts to |
| 286 | conflict. Threads in a project that watch the same pull request share one check. On GitHub, a check |
| 287 | first asks whether anything changed and reads the pull request only when it did, which keeps |
| 288 | watching inside GitHub's rate limit. Comments from your own account do not wake it. A merge wakes |
| 289 | the agent once to finish any follow-up work and ends the watch. Watching also ends |
| 290 | when the pull request closes, after 10 wakes in a row that bring only comments, after 8 |
| 291 | failed reads in a row, or when you press Stop on the thread. A rate limit only pauses watching. |
| 292 | Settling or archiving a thread also ends all its watches. Unsettle the thread before starting a new |
| 293 | watch. Subagents cannot watch pull requests; the thread that delegated to them does. To start or stop |
| 294 | it yourself, use the row menu in the **Linked pull requests** panel. In the thread details card, a |
| 295 | watched pull request shows an eye; click it to stop watching. |
| 296 | |
| 297 | A watched thread counts as working between wakes, so it stays in the **Working** section and does |
| 298 | not auto-settle. Agents stop watching when they hand the work back to you, and the thread then |
| 299 | returns to your inbox. |
| 300 | |
| 301 | Cross-repository links use a project on the same host. Azure DevOps reviews require a project checked |
| 302 | out from the matching organization and repository. |
| 303 | |
| 304 | ## GitHub stacks |
| 305 | |
| 306 | The Pull Requests page shows each PR's position in its GitHub stack. Open the stack badge in a |
| 307 | review to navigate its layers. **Merge stack** submits the selected pull request and every unmerged |
| 308 | layer below it to GitHub together, respecting branch rules and merge queues. The confirmation shows |
| 309 | the scope and merge strategy. GitHub rebases the remaining stack after merging. |
| 310 | |
| 311 | **Rebase stack** updates remote branches from bottom to top without changing your local checkout. |
| 312 | It can rewrite history and restart checks. If a layer fails, earlier updates remain; resolve that |
| 313 | layer before retrying. GitHub may require manual conflict resolution after a lower layer is amended, |
| 314 | even when its changes look independent. Stack actions require an environment that supports them. |