Skip to content

feat: make worktree branch prefix configurable - #3954

Open
jssblck wants to merge 5 commits into
pingdotgg:mainfrom
jssblck:codex/custom-worktree-branch-prefix
Open

feat: make worktree branch prefix configurable#3954
jssblck wants to merge 5 commits into
pingdotgg:mainfrom
jssblck:codex/custom-worktree-branch-prefix

Conversation

@jssblck

@jssblck jssblck commented Jul 14, 2026

Copy link
Copy Markdown

What Changed

  • Added a persisted worktreeBranchPrefix setting with t3code as the default.
  • Added a "Branch prefix" field below "Start from origin" when new threads use worktrees.
  • Applied the configured prefix to temporary worktree branches and preserved it during the first-turn branch rename.
  • Centralized branch construction and detection in shared git utilities, with focused contract, utility, and reactor tests.
  • Rebased onto current main: kept the legacy UUID-shaped temporary branch matcher and the source control writer model selection, and registered the new field in settings search.
  • Applied the prefix to the call sites main added since the original branch: mobile thread creation (draft screen and outbox drain) and the checkpoint reactor's branch drift check.

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.

image

After:

Note: taken from the dev server launched in the Codex browser, so minor other differences from the app screenshot above.

image image

Testing

  • Typecheck for contracts, shared, client-runtime, server, web, and mobile.
  • 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 fmt and vp lint on the touched files.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for the UI change
  • A video is not applicable because the change does not depend on animation or interaction timing

Co-authored-by: Codex noreply@openai.com

Note

Make worktree branch prefix configurable across shared git utilities and callers

  • Adds worktreeBranchPrefix to ServerSettings with default t3code, a validation schema (WorktreeBranchPrefix), and DEFAULT_WORKTREE_BRANCH_PREFIX in settings.ts
  • Updates git.ts so buildTemporaryWorktreeBranchName, isTemporaryWorktreeBranch, extractTemporaryWorktreeBranchPrefix, and buildGeneratedWorktreeBranchName all accept and respect a configurable prefix instead of the old hardcoded WORKTREE_BRANCH_PREFIX
  • Updates all callers (mobile, web, server orchestration, client-runtime) to derive the prefix from server config and pass it through branch creation and reconciliation paths
  • Adds a settings UI input row in SettingsPanels.tsx with normalization and reset-to-default support
  • Behavioral Change: resolveLiveThreadBranchUpdate in GitActionsControl.logic.ts and gitActions.ts now requires worktreeBranchPrefix; reconciliation early-returns in GitActionsControl until the prefix is loaded. CheckpointReactor drift-following and ProviderCommandReactor branch rename now classify temporary branches using the configured prefix. The old constant WORKTREE_BRANCH_PREFIX is removed from packages/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 t3code prefix.

Overview
Lets teams choose the Git namespace for new worktrees instead of always using t3code/. A persisted worktreeBranchPrefix setting (default t3code, 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.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 25ef049b-c7a0-4c32-8328-9729c56461cd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 14, 2026
Comment thread packages/shared/src/git.ts Outdated
@jssblck
jssblck marked this pull request as ready for review July 14, 2026 01:34
Comment thread apps/web/src/components/GitActionsControl.logic.ts
@macroscopeapp

macroscopeapp Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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:

  • 1 blocking correctness issue found at or above your repo's Minimum Blocking Severity

@a3ylf

a3ylf commented Jul 18, 2026

Copy link
Copy Markdown

please merge this, the name t3code forced everywhere is annoying

@jetpham

jetpham commented Jul 22, 2026

Copy link
Copy Markdown

Was just looking into this myself, I also hope this gets merged. @jssblck please fix conflicts to get this ready to merge

@gabeburnett

Copy link
Copy Markdown

Nice, someone has already done it, hopefully this gets merged soon

@kevhardy

kevhardy commented Aug 4, 2026

Copy link
Copy Markdown

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.

@jetpham

jetpham commented Aug 14, 2026

Copy link
Copy Markdown

I am also upping this

@jssblck
jssblck force-pushed the codex/custom-worktree-branch-prefix branch from beabf35 to 1d17f67 Compare August 23, 2026 03:15

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread apps/server/src/orchestration/Layers/CheckpointReactor.test.ts Outdated
Comment thread apps/web/src/components/GitActionsControl.tsx Outdated
// 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)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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 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.

🤖 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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm unable to act on this request because you do not have permissions within this repository.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
jssblck and others added 2 commits August 22, 2026 20:56
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>

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts Outdated
…r test

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread apps/web/src/components/settings/SettingsPanels.tsx Outdated
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Worktree branch naming other than t3code

5 participants