feat: make worktree branch prefix configurable - #3954
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Skipped Macroscope did not run approvability analysis for this PR. Macroscope could not determine whether this PR modifies its approvability configuration, so the PR was not approved automatically. A PR that may change the rules that govern approval is never approved automatically. Not approved because:
|
|
please merge this, the name t3code forced everywhere is annoying |
|
Was just looking into this myself, I also hope this gets merged. @jssblck please fix conflicts to get this ready to merge |
|
Nice, someone has already done it, hopefully this gets merged soon |
|
I'm hoping we get this merged or something similar soon. I really want to use t3code for some work stuff but the repos we work in use very specific branch prefixes, so the t3code branches don't work for me right now. |
|
I am also upping this |
beabf35 to
1d17f67
Compare
There was a problem hiding this comment.
One convention issue found: an aliased service-module import in CheckpointReactor.test.ts. Everything else in the changed Effect code (new ServerSettingsService acquisition via yield*, added ServerSettingsError in the layer's error channel, prefix helpers in packages/shared/src/git.ts) follows the conventions.
Posted via Macroscope — Effect Service Conventions
| // A temporary placeholder checkout means the first-turn auto-rename is | ||
| // still in flight — don't race it. | ||
| const { worktreeBranchPrefix } = yield* serverSettingsService.getSettings; | ||
| if (isTemporaryWorktreeBranch(checkedOutBranch, worktreeBranchPrefix)) { |
There was a problem hiding this comment.
🟡 Medium Layers/CheckpointReactor.ts:584
When a worktree created with team-a is still on its temporary branch team-a/1234abcd and worktreeBranchPrefix changes to team-b, this check no longer recognizes the branch as temporary, so the rename-race path adopts it into thread.branch and can orphan the thread’s PR association. Preserve or derive the prefix used by the active worktree instead of validating only against the current global setting.
Also found in 1 other location(s)
apps/web/src/components/GitActionsControl.tsx:1138
Reconciliation uses only the current
serverConfig.settings.worktreeBranchPrefix. If a worktree was created asteam/1234abcdand the user changes the setting toorgbefore its temporary branch is renamed, this dependency reruns the effect and the old custom-prefix branch is no longer recognized as temporary.persistThreadBranchSyncthen replaces the draft's semantic branch metadata withteam/1234abcd. The prefix used to create the active worktree must remain recognizable across settings changes.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/orchestration/Layers/CheckpointReactor.ts around line 584:
When a worktree created with `team-a` is still on its temporary branch `team-a/1234abcd` and `worktreeBranchPrefix` changes to `team-b`, this check no longer recognizes the branch as temporary, so the rename-race path adopts it into `thread.branch` and can orphan the thread’s PR association. Preserve or derive the prefix used by the active worktree instead of validating only against the current global setting.
Also found in 1 other location(s):
- apps/web/src/components/GitActionsControl.tsx:1138 -- Reconciliation uses only the *current* `serverConfig.settings.worktreeBranchPrefix`. If a worktree was created as `team/1234abcd` and the user changes the setting to `org` before its temporary branch is renamed, this dependency reruns the effect and the old custom-prefix branch is no longer recognized as temporary. `persistThreadBranchSync` then replaces the draft's semantic branch metadata with `team/1234abcd`. The prefix used to create the active worktree must remain recognizable across settings changes.
There was a problem hiding this comment.
Acknowledged, but leaving this as is. The window requires the prefix setting to change between worktree creation and the first-turn rename, which is seconds on an active thread. If it does happen, the drift dispatch is a compare-and-swap on expectedBranch, so a concurrent rename drops the stale update rather than corrupting the recorded branch. Detecting temporary branches under arbitrary former prefixes would reintroduce the broad eight-hex matching that misclassified branches like release/20260714, which an earlier round of review asked us to remove. The configured-plus-legacy check covers every case that survives a restart.
There was a problem hiding this comment.
Sorry, I'm unable to act on this request because you do not have permissions within this repository.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1d17f67. Configure here.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The first-turn rename previously preserved whatever namespace the temporary branch was created under, so a branch created before the client loaded the prefix setting stayed under t3code/ forever. The rename now targets the configured prefix, and the web branch reconciliation waits for the server config instead of classifying against the default prefix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Reviewed the Effect service changes in this PR (ServerSettingsService acquisition in CheckpointReactor, the branch-prefix helpers moved into @t3tools/shared/git, and the contracts schema). Dependency acquisition, error-channel widening, and helper placement all look consistent with the conventions. One touched test line still reaches the settings layer through the deprecated static.
Posted via Macroscope — Effect Service Conventions
…r test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
One UI consistency finding on the new "Branch prefix" row: the trailing / affix is hand-rolled next to the input instead of using the shared InputGroup contract. Everything else in the web scope (reset wiring, search catalog entry, GitActionsControl prefix guard, ChatView call site) is consistent with the surrounding patterns.
Posted via Macroscope — UI Consistency
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

What Changed
worktreeBranchPrefixsetting witht3codeas the default.Why
New worktrees currently force every generated branch into the
t3code/namespace. That leaks the tool name into repository state and conflicts with teams that require their own branch naming conventions.This implements the smallest useful scope requested in #3651: one persisted prefix setting that covers both temporary branch creation and the generated branch rename. It also addresses the configurable-prefix path discussed in #272.
Closes #3651
Related to #272
UI Changes
Before:
Note: taken from the app.
After:
Note: taken from the dev server launched in the Codex browser, so minor other differences from the app screenshot above.
Testing
vp test run packages/contracts/src/settings.test.ts packages/shared/src/git.test.ts apps/web/src/components/GitActionsControl.logic.test.ts apps/web/src/components/settings/settingsSearch.test.ts apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts apps/server/src/orchestration/Layers/CheckpointReactor.test.ts(195 tests)vp fmtandvp linton the touched files.Checklist
Co-authored-by: Codex noreply@openai.com
Note
Make worktree branch prefix configurable across shared git utilities and callers
worktreeBranchPrefixtoServerSettingswith defaultt3code, a validation schema (WorktreeBranchPrefix), andDEFAULT_WORKTREE_BRANCH_PREFIXin settings.tsbuildTemporaryWorktreeBranchName,isTemporaryWorktreeBranch,extractTemporaryWorktreeBranchPrefix, andbuildGeneratedWorktreeBranchNameall accept and respect a configurable prefix instead of the old hardcodedWORKTREE_BRANCH_PREFIXresolveLiveThreadBranchUpdatein GitActionsControl.logic.ts and gitActions.ts now requiresworktreeBranchPrefix; reconciliation early-returns inGitActionsControluntil the prefix is loaded.CheckpointReactordrift-following andProviderCommandReactorbranch rename now classify temporary branches using the configured prefix. The old constantWORKTREE_BRANCH_PREFIXis removed frompackages/shared/src/git.ts.Macroscope summarized 2091ae0.
Note
Medium Risk
Touches git branch naming, first-turn rename, and live branch reconciliation across web, mobile, and server. Misclassification of temporary vs semantic branches could persist the wrong ref, but the change is well-tested and defaults to the existing
t3codeprefix.Overview
Lets teams choose the Git namespace for new worktrees instead of always using
t3code/. A persistedworktreeBranchPrefixsetting (defaultt3code, validated as a lowercase Git namespace) drives both placeholder branches and the first-turn generated rename.Shared git helpers now take the prefix: temporary detection still matches the configured namespace or the legacy default, so stale
t3code/<hex>checkouts still rename into the new prefix. Web, mobile (including outbox drain), and the checkpoint/provider reactors all pass the setting through.General settings adds a Branch prefix field under new-worktree mode. Live branch reconciliation waits for server config so it does not treat a custom-prefix placeholder as a semantic branch.
Reviewed by Cursor Bugbot for commit 2091ae0. Bugbot is set up for automated code reviews on this repo. Configure here.