feat(web): custom display labels for worktrees - #3070

Closed
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels
Closed

feat(web): custom display labels for worktrees#3070
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels

Conversation

@TheIcarusWings

@TheIcarusWingsTheIcarusWings commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What

Lets a worktree carry a readable display name instead of the auto-generated hash folder name (e.g. t3code-f07cb2c5). The label is cosmetic only — no git worktree move, no disk changes.

Screenshots

Bottom-bar workspace label — before vs. after renaming the worktree:

Default (hash-derived)Custom label

Rename dialog (opened from the bottom-bar label or the sidebar):

Entry point — sidebar thread context menu ("Rename worktree"; note the renamed label already showing in the bottom bar):

Design

  • Keyed by worktree PATH, not per-thread, so threads sharing a worktree always show the same name.
  • Stored in a persisted worktreeLabelByPath map in useUiStateStore (local UI state).
  • A single resolver — worktreeDisplayName(path, labelMap) = labelMap[path] ?? formatWorktreePathForDisplay(path) — is used everywhere a worktree name renders, so the UI stays consistent.
  • The rename UI is a single, globally-mounted dialog (WorktreeRenameDialog) driven by a small worktreeRenameStore, so every entry point opens the same dialog and writes the same path-keyed label.

Rename entry points

  • Sidebar thread context menu → "Rename worktree" (only for worktree-backed threads).
  • Bottom-bar workspace label: double-click, or right-click → "Rename worktree" (desktop + mobile).

Leaving the field blank resets to the default hash-derived name. The label persists across reloads.

Where labels surface

  • Bottom-bar workspace label (desktop BranchToolbarEnvModeSelector + mobile MobileRunContextSelector).
  • Orphan-worktree delete confirmation dialog.

Tests

  • worktreeDisplayName (label / fallback / blank / trim).
  • setWorktreeLabel reducer (set / trim / clear / sibling independence) + persistence round-trip.
  • Custom-label cases for resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

pnpm typecheck and vp lint clean; full web unit suite passes (1057 tests). Verified manually in the running app: rename from all entry points, shared label across two threads on the same worktree, blank-resets-to-default, and persistence across reload.

🤖 Generated with Claude Code


Note

Low Risk
Client-only persisted UI labels and rename flows; worktree deletion still uses existing VCS APIs, with label cleanup on successful remove.

Overview
Adds cosmetic worktree display names keyed by environment and worktree path, persisted in local UI state and shared by every thread on that worktree (no disk/git changes).

A global WorktreeRenameDialog plus worktreeRenameStore lets users set or clear labels from the sidebar thread menu (Rename worktree), or from the bottom-bar workspace label via double-click or right-click (useWorktreeRenameTrigger). BranchToolbar / BranchToolbarEnvModeSelector read labels through useWorktreeLabel and pass them into resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

worktreeDisplayName and formatWorktreeDeleteConfirmation use custom labels in orphan-worktree delete prompts; successful worktree removal clears the stored label. Unit tests cover label persistence, resolver behavior, rename trigger context-menu fallback, and display helpers.

Reviewed by Cursor Bugbot for commit 64f86a9. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add custom display labels for worktrees in the branch toolbar and sidebar

  • Introduces a global WorktreeRenameDialog (via useWorktreeRenameStore) that lets users set or clear a cosmetic label for any active worktree, accessible via double-click, right-click context menu, or the sidebar thread context menu.
  • Adds worktreeLabelByEnvironment to uiStateStore, persisted to localStorage and keyed by environment ID and worktree path.
  • Updates BranchToolbarEnvModeSelector and BranchToolbar.MobileRunContextSelector to display the custom label when set, falling back to existing defaults ('Current worktree' / 'Worktree').
  • Extends worktree delete flow in useThreadActions to show the custom label in confirmation text and clear the stored label on successful deletion.

Macroscope summarized 64f86a9.

@coderabbitai

coderabbitaiBot commented Jun 13, 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

Run ID: 9ce56739-357c-4b92-9003-5c4b1b0fc4c5

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 and usage tips.

@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Jun 13, 2026
@macroscopeapp

macroscopeappBot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new user-facing feature (custom worktree labels) with new UI components, state management, and persistence logic. New features warrant human review, and there's an unresolved comment about potential data migration issues.

You can customize Macroscope's approvability policy. Learn more.

TheIcarusWingsand others added 3 commits June 18, 2026 23:00
Let a worktree carry a readable display name instead of the auto-generated
hash folder name (e.g. "t3code-f07cb2c5"). The label is cosmetic only — no
`git worktree move`, no disk changes.
Keyed by worktree PATH (not per-thread) so threads sharing a worktree always
show the same name. Stored in a persisted `worktreeLabelByPath` map in
useUiStateStore. A single `worktreeDisplayName(path, labelMap)` resolver is
used everywhere a worktree name renders.
Rename entry points (all open one shared, globally-mounted dialog):
- Sidebar thread context menu → "Rename worktree" (worktree-backed threads).
- Bottom-bar workspace label: double-click, or right-click → "Rename worktree".
Labels surface in the bottom-bar workspace label and the orphan-worktree
delete confirmation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Address self-review findings on the worktree display-label feature:
- Clear a worktree's custom label when the worktree is deleted
(orphan-delete in useThreadActions), so it can't linger in persisted
state or be inherited by a future worktree reusing the same path.
- Key labels by the verbatim worktree path everywhere. Previously writers
trimmed the path key while useWorktreeLabel read it raw, so a path with
surrounding whitespace would store and read under different keys.
- Remove unused useWorktreeDisplayName hook (dead code).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/worktree-display-labels branch from fcda8a9 to 29febaeCompareJune 19, 2026 06:21
Prevent label collisions across environments that reuse the same worktree path, and fall back to the rename dialog when the native context-menu bridge fails.
Co-authored-by: codex <codex@users.noreply.github.com>

@cursorcursorBot 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 reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

parsed.defaultAdvertisedEndpointKey.length > 0
? parsed.defaultAdvertisedEndpointKey
: null,
worktreeLabelByEnvironment: sanitizePersistedWorktreeLabels(parsed.worktreeLabelByEnvironment),

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.

Path-only label persistence dropped

Medium Severity

The parsePersistedState function was updated to expect the new worktreeLabelByEnvironment structure, but it no longer reads the prior worktreeLabelByPath format from the t3code:ui-state:v1 localStorage key. This causes existing custom worktree names to be lost on load and overwritten on the next state persistence.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as part of backlog cleanup: this PR is stale, currently conflicting with main, has no approval, and has not had active remediation for 30+ days. If the change is still relevant, please rebase onto current main and request reopening or submit a focused current diff. Thank you for the contribution.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheIcarusWings@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(web): custom display labels for worktrees - #3070

Closed
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels
Closed

feat(web): custom display labels for worktrees#3070
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels

Conversation

@TheIcarusWings

@TheIcarusWingsTheIcarusWings commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What

Lets a worktree carry a readable display name instead of the auto-generated hash folder name (e.g. t3code-f07cb2c5). The label is cosmetic only — no git worktree move, no disk changes.

Screenshots

Bottom-bar workspace label — before vs. after renaming the worktree:

Default (hash-derived)Custom label

Rename dialog (opened from the bottom-bar label or the sidebar):

Entry point — sidebar thread context menu ("Rename worktree"; note the renamed label already showing in the bottom bar):

Design

  • Keyed by worktree PATH, not per-thread, so threads sharing a worktree always show the same name.
  • Stored in a persisted worktreeLabelByPath map in useUiStateStore (local UI state).
  • A single resolver — worktreeDisplayName(path, labelMap) = labelMap[path] ?? formatWorktreePathForDisplay(path) — is used everywhere a worktree name renders, so the UI stays consistent.
  • The rename UI is a single, globally-mounted dialog (WorktreeRenameDialog) driven by a small worktreeRenameStore, so every entry point opens the same dialog and writes the same path-keyed label.

Rename entry points

  • Sidebar thread context menu → "Rename worktree" (only for worktree-backed threads).
  • Bottom-bar workspace label: double-click, or right-click → "Rename worktree" (desktop + mobile).

Leaving the field blank resets to the default hash-derived name. The label persists across reloads.

Where labels surface

  • Bottom-bar workspace label (desktop BranchToolbarEnvModeSelector + mobile MobileRunContextSelector).
  • Orphan-worktree delete confirmation dialog.

Tests

  • worktreeDisplayName (label / fallback / blank / trim).
  • setWorktreeLabel reducer (set / trim / clear / sibling independence) + persistence round-trip.
  • Custom-label cases for resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

pnpm typecheck and vp lint clean; full web unit suite passes (1057 tests). Verified manually in the running app: rename from all entry points, shared label across two threads on the same worktree, blank-resets-to-default, and persistence across reload.

🤖 Generated with Claude Code


Note

Low Risk
Client-only persisted UI labels and rename flows; worktree deletion still uses existing VCS APIs, with label cleanup on successful remove.

Overview
Adds cosmetic worktree display names keyed by environment and worktree path, persisted in local UI state and shared by every thread on that worktree (no disk/git changes).

A global WorktreeRenameDialog plus worktreeRenameStore lets users set or clear labels from the sidebar thread menu (Rename worktree), or from the bottom-bar workspace label via double-click or right-click (useWorktreeRenameTrigger). BranchToolbar / BranchToolbarEnvModeSelector read labels through useWorktreeLabel and pass them into resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

worktreeDisplayName and formatWorktreeDeleteConfirmation use custom labels in orphan-worktree delete prompts; successful worktree removal clears the stored label. Unit tests cover label persistence, resolver behavior, rename trigger context-menu fallback, and display helpers.

Reviewed by Cursor Bugbot for commit 64f86a9. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add custom display labels for worktrees in the branch toolbar and sidebar

  • Introduces a global WorktreeRenameDialog (via useWorktreeRenameStore) that lets users set or clear a cosmetic label for any active worktree, accessible via double-click, right-click context menu, or the sidebar thread context menu.
  • Adds worktreeLabelByEnvironment to uiStateStore, persisted to localStorage and keyed by environment ID and worktree path.
  • Updates BranchToolbarEnvModeSelector and BranchToolbar.MobileRunContextSelector to display the custom label when set, falling back to existing defaults ('Current worktree' / 'Worktree').
  • Extends worktree delete flow in useThreadActions to show the custom label in confirmation text and clear the stored label on successful deletion.

Macroscope summarized 64f86a9.

@coderabbitai

coderabbitaiBot commented Jun 13, 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

Run ID: 9ce56739-357c-4b92-9003-5c4b1b0fc4c5

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 and usage tips.

@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Jun 13, 2026
@macroscopeapp

macroscopeappBot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new user-facing feature (custom worktree labels) with new UI components, state management, and persistence logic. New features warrant human review, and there's an unresolved comment about potential data migration issues.

You can customize Macroscope's approvability policy. Learn more.

TheIcarusWingsand others added 3 commits June 18, 2026 23:00
Let a worktree carry a readable display name instead of the auto-generated
hash folder name (e.g. "t3code-f07cb2c5"). The label is cosmetic only — no
`git worktree move`, no disk changes.
Keyed by worktree PATH (not per-thread) so threads sharing a worktree always
show the same name. Stored in a persisted `worktreeLabelByPath` map in
useUiStateStore. A single `worktreeDisplayName(path, labelMap)` resolver is
used everywhere a worktree name renders.
Rename entry points (all open one shared, globally-mounted dialog):
- Sidebar thread context menu → "Rename worktree" (worktree-backed threads).
- Bottom-bar workspace label: double-click, or right-click → "Rename worktree".
Labels surface in the bottom-bar workspace label and the orphan-worktree
delete confirmation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Address self-review findings on the worktree display-label feature:
- Clear a worktree's custom label when the worktree is deleted
(orphan-delete in useThreadActions), so it can't linger in persisted
state or be inherited by a future worktree reusing the same path.
- Key labels by the verbatim worktree path everywhere. Previously writers
trimmed the path key while useWorktreeLabel read it raw, so a path with
surrounding whitespace would store and read under different keys.
- Remove unused useWorktreeDisplayName hook (dead code).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/worktree-display-labels branch from fcda8a9 to 29febaeCompareJune 19, 2026 06:21
Prevent label collisions across environments that reuse the same worktree path, and fall back to the rename dialog when the native context-menu bridge fails.
Co-authored-by: codex <codex@users.noreply.github.com>

@cursorcursorBot 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 reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

parsed.defaultAdvertisedEndpointKey.length > 0
? parsed.defaultAdvertisedEndpointKey
: null,
worktreeLabelByEnvironment: sanitizePersistedWorktreeLabels(parsed.worktreeLabelByEnvironment),

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.

Path-only label persistence dropped

Medium Severity

The parsePersistedState function was updated to expect the new worktreeLabelByEnvironment structure, but it no longer reads the prior worktreeLabelByPath format from the t3code:ui-state:v1 localStorage key. This causes existing custom worktree names to be lost on load and overwritten on the next state persistence.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as part of backlog cleanup: this PR is stale, currently conflicting with main, has no approval, and has not had active remediation for 30+ days. If the change is still relevant, please rebase onto current main and request reopening or submit a focused current diff. Thank you for the contribution.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheIcarusWings@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(web): custom display labels for worktrees - #3070

Closed
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels
Closed

feat(web): custom display labels for worktrees#3070
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels

Conversation

@TheIcarusWings

@TheIcarusWingsTheIcarusWings commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What

Lets a worktree carry a readable display name instead of the auto-generated hash folder name (e.g. t3code-f07cb2c5). The label is cosmetic only — no git worktree move, no disk changes.

Screenshots

Bottom-bar workspace label — before vs. after renaming the worktree:

Default (hash-derived)Custom label

Rename dialog (opened from the bottom-bar label or the sidebar):

Entry point — sidebar thread context menu ("Rename worktree"; note the renamed label already showing in the bottom bar):

Design

  • Keyed by worktree PATH, not per-thread, so threads sharing a worktree always show the same name.
  • Stored in a persisted worktreeLabelByPath map in useUiStateStore (local UI state).
  • A single resolver — worktreeDisplayName(path, labelMap) = labelMap[path] ?? formatWorktreePathForDisplay(path) — is used everywhere a worktree name renders, so the UI stays consistent.
  • The rename UI is a single, globally-mounted dialog (WorktreeRenameDialog) driven by a small worktreeRenameStore, so every entry point opens the same dialog and writes the same path-keyed label.

Rename entry points

  • Sidebar thread context menu → "Rename worktree" (only for worktree-backed threads).
  • Bottom-bar workspace label: double-click, or right-click → "Rename worktree" (desktop + mobile).

Leaving the field blank resets to the default hash-derived name. The label persists across reloads.

Where labels surface

  • Bottom-bar workspace label (desktop BranchToolbarEnvModeSelector + mobile MobileRunContextSelector).
  • Orphan-worktree delete confirmation dialog.

Tests

  • worktreeDisplayName (label / fallback / blank / trim).
  • setWorktreeLabel reducer (set / trim / clear / sibling independence) + persistence round-trip.
  • Custom-label cases for resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

pnpm typecheck and vp lint clean; full web unit suite passes (1057 tests). Verified manually in the running app: rename from all entry points, shared label across two threads on the same worktree, blank-resets-to-default, and persistence across reload.

🤖 Generated with Claude Code


Note

Low Risk
Client-only persisted UI labels and rename flows; worktree deletion still uses existing VCS APIs, with label cleanup on successful remove.

Overview
Adds cosmetic worktree display names keyed by environment and worktree path, persisted in local UI state and shared by every thread on that worktree (no disk/git changes).

A global WorktreeRenameDialog plus worktreeRenameStore lets users set or clear labels from the sidebar thread menu (Rename worktree), or from the bottom-bar workspace label via double-click or right-click (useWorktreeRenameTrigger). BranchToolbar / BranchToolbarEnvModeSelector read labels through useWorktreeLabel and pass them into resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

worktreeDisplayName and formatWorktreeDeleteConfirmation use custom labels in orphan-worktree delete prompts; successful worktree removal clears the stored label. Unit tests cover label persistence, resolver behavior, rename trigger context-menu fallback, and display helpers.

Reviewed by Cursor Bugbot for commit 64f86a9. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add custom display labels for worktrees in the branch toolbar and sidebar

  • Introduces a global WorktreeRenameDialog (via useWorktreeRenameStore) that lets users set or clear a cosmetic label for any active worktree, accessible via double-click, right-click context menu, or the sidebar thread context menu.
  • Adds worktreeLabelByEnvironment to uiStateStore, persisted to localStorage and keyed by environment ID and worktree path.
  • Updates BranchToolbarEnvModeSelector and BranchToolbar.MobileRunContextSelector to display the custom label when set, falling back to existing defaults ('Current worktree' / 'Worktree').
  • Extends worktree delete flow in useThreadActions to show the custom label in confirmation text and clear the stored label on successful deletion.

Macroscope summarized 64f86a9.

@coderabbitai

coderabbitaiBot commented Jun 13, 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

Run ID: 9ce56739-357c-4b92-9003-5c4b1b0fc4c5

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 and usage tips.

@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Jun 13, 2026
@macroscopeapp

macroscopeappBot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new user-facing feature (custom worktree labels) with new UI components, state management, and persistence logic. New features warrant human review, and there's an unresolved comment about potential data migration issues.

You can customize Macroscope's approvability policy. Learn more.

TheIcarusWingsand others added 3 commits June 18, 2026 23:00
Let a worktree carry a readable display name instead of the auto-generated
hash folder name (e.g. "t3code-f07cb2c5"). The label is cosmetic only — no
`git worktree move`, no disk changes.
Keyed by worktree PATH (not per-thread) so threads sharing a worktree always
show the same name. Stored in a persisted `worktreeLabelByPath` map in
useUiStateStore. A single `worktreeDisplayName(path, labelMap)` resolver is
used everywhere a worktree name renders.
Rename entry points (all open one shared, globally-mounted dialog):
- Sidebar thread context menu → "Rename worktree" (worktree-backed threads).
- Bottom-bar workspace label: double-click, or right-click → "Rename worktree".
Labels surface in the bottom-bar workspace label and the orphan-worktree
delete confirmation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Address self-review findings on the worktree display-label feature:
- Clear a worktree's custom label when the worktree is deleted
(orphan-delete in useThreadActions), so it can't linger in persisted
state or be inherited by a future worktree reusing the same path.
- Key labels by the verbatim worktree path everywhere. Previously writers
trimmed the path key while useWorktreeLabel read it raw, so a path with
surrounding whitespace would store and read under different keys.
- Remove unused useWorktreeDisplayName hook (dead code).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/worktree-display-labels branch from fcda8a9 to 29febaeCompareJune 19, 2026 06:21
Prevent label collisions across environments that reuse the same worktree path, and fall back to the rename dialog when the native context-menu bridge fails.
Co-authored-by: codex <codex@users.noreply.github.com>

@cursorcursorBot 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 reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

parsed.defaultAdvertisedEndpointKey.length > 0
? parsed.defaultAdvertisedEndpointKey
: null,
worktreeLabelByEnvironment: sanitizePersistedWorktreeLabels(parsed.worktreeLabelByEnvironment),

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.

Path-only label persistence dropped

Medium Severity

The parsePersistedState function was updated to expect the new worktreeLabelByEnvironment structure, but it no longer reads the prior worktreeLabelByPath format from the t3code:ui-state:v1 localStorage key. This causes existing custom worktree names to be lost on load and overwritten on the next state persistence.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as part of backlog cleanup: this PR is stale, currently conflicting with main, has no approval, and has not had active remediation for 30+ days. If the change is still relevant, please rebase onto current main and request reopening or submit a focused current diff. Thank you for the contribution.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheIcarusWings@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(web): custom display labels for worktrees - #3070

Closed
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels
Closed

feat(web): custom display labels for worktrees#3070
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels

Conversation

@TheIcarusWings

@TheIcarusWingsTheIcarusWings commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What

Lets a worktree carry a readable display name instead of the auto-generated hash folder name (e.g. t3code-f07cb2c5). The label is cosmetic only — no git worktree move, no disk changes.

Screenshots

Bottom-bar workspace label — before vs. after renaming the worktree:

Default (hash-derived)Custom label

Rename dialog (opened from the bottom-bar label or the sidebar):

Entry point — sidebar thread context menu ("Rename worktree"; note the renamed label already showing in the bottom bar):

Design

  • Keyed by worktree PATH, not per-thread, so threads sharing a worktree always show the same name.
  • Stored in a persisted worktreeLabelByPath map in useUiStateStore (local UI state).
  • A single resolver — worktreeDisplayName(path, labelMap) = labelMap[path] ?? formatWorktreePathForDisplay(path) — is used everywhere a worktree name renders, so the UI stays consistent.
  • The rename UI is a single, globally-mounted dialog (WorktreeRenameDialog) driven by a small worktreeRenameStore, so every entry point opens the same dialog and writes the same path-keyed label.

Rename entry points

  • Sidebar thread context menu → "Rename worktree" (only for worktree-backed threads).
  • Bottom-bar workspace label: double-click, or right-click → "Rename worktree" (desktop + mobile).

Leaving the field blank resets to the default hash-derived name. The label persists across reloads.

Where labels surface

  • Bottom-bar workspace label (desktop BranchToolbarEnvModeSelector + mobile MobileRunContextSelector).
  • Orphan-worktree delete confirmation dialog.

Tests

  • worktreeDisplayName (label / fallback / blank / trim).
  • setWorktreeLabel reducer (set / trim / clear / sibling independence) + persistence round-trip.
  • Custom-label cases for resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

pnpm typecheck and vp lint clean; full web unit suite passes (1057 tests). Verified manually in the running app: rename from all entry points, shared label across two threads on the same worktree, blank-resets-to-default, and persistence across reload.

🤖 Generated with Claude Code


Note

Low Risk
Client-only persisted UI labels and rename flows; worktree deletion still uses existing VCS APIs, with label cleanup on successful remove.

Overview
Adds cosmetic worktree display names keyed by environment and worktree path, persisted in local UI state and shared by every thread on that worktree (no disk/git changes).

A global WorktreeRenameDialog plus worktreeRenameStore lets users set or clear labels from the sidebar thread menu (Rename worktree), or from the bottom-bar workspace label via double-click or right-click (useWorktreeRenameTrigger). BranchToolbar / BranchToolbarEnvModeSelector read labels through useWorktreeLabel and pass them into resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

worktreeDisplayName and formatWorktreeDeleteConfirmation use custom labels in orphan-worktree delete prompts; successful worktree removal clears the stored label. Unit tests cover label persistence, resolver behavior, rename trigger context-menu fallback, and display helpers.

Reviewed by Cursor Bugbot for commit 64f86a9. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add custom display labels for worktrees in the branch toolbar and sidebar

  • Introduces a global WorktreeRenameDialog (via useWorktreeRenameStore) that lets users set or clear a cosmetic label for any active worktree, accessible via double-click, right-click context menu, or the sidebar thread context menu.
  • Adds worktreeLabelByEnvironment to uiStateStore, persisted to localStorage and keyed by environment ID and worktree path.
  • Updates BranchToolbarEnvModeSelector and BranchToolbar.MobileRunContextSelector to display the custom label when set, falling back to existing defaults ('Current worktree' / 'Worktree').
  • Extends worktree delete flow in useThreadActions to show the custom label in confirmation text and clear the stored label on successful deletion.

Macroscope summarized 64f86a9.

@coderabbitai

coderabbitaiBot commented Jun 13, 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

Run ID: 9ce56739-357c-4b92-9003-5c4b1b0fc4c5

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 and usage tips.

@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Jun 13, 2026
@macroscopeapp

macroscopeappBot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new user-facing feature (custom worktree labels) with new UI components, state management, and persistence logic. New features warrant human review, and there's an unresolved comment about potential data migration issues.

You can customize Macroscope's approvability policy. Learn more.

TheIcarusWingsand others added 3 commits June 18, 2026 23:00
Let a worktree carry a readable display name instead of the auto-generated
hash folder name (e.g. "t3code-f07cb2c5"). The label is cosmetic only — no
`git worktree move`, no disk changes.
Keyed by worktree PATH (not per-thread) so threads sharing a worktree always
show the same name. Stored in a persisted `worktreeLabelByPath` map in
useUiStateStore. A single `worktreeDisplayName(path, labelMap)` resolver is
used everywhere a worktree name renders.
Rename entry points (all open one shared, globally-mounted dialog):
- Sidebar thread context menu → "Rename worktree" (worktree-backed threads).
- Bottom-bar workspace label: double-click, or right-click → "Rename worktree".
Labels surface in the bottom-bar workspace label and the orphan-worktree
delete confirmation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Address self-review findings on the worktree display-label feature:
- Clear a worktree's custom label when the worktree is deleted
(orphan-delete in useThreadActions), so it can't linger in persisted
state or be inherited by a future worktree reusing the same path.
- Key labels by the verbatim worktree path everywhere. Previously writers
trimmed the path key while useWorktreeLabel read it raw, so a path with
surrounding whitespace would store and read under different keys.
- Remove unused useWorktreeDisplayName hook (dead code).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/worktree-display-labels branch from fcda8a9 to 29febaeCompareJune 19, 2026 06:21
Prevent label collisions across environments that reuse the same worktree path, and fall back to the rename dialog when the native context-menu bridge fails.
Co-authored-by: codex <codex@users.noreply.github.com>

@cursorcursorBot 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 reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

parsed.defaultAdvertisedEndpointKey.length > 0
? parsed.defaultAdvertisedEndpointKey
: null,
worktreeLabelByEnvironment: sanitizePersistedWorktreeLabels(parsed.worktreeLabelByEnvironment),

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.

Path-only label persistence dropped

Medium Severity

The parsePersistedState function was updated to expect the new worktreeLabelByEnvironment structure, but it no longer reads the prior worktreeLabelByPath format from the t3code:ui-state:v1 localStorage key. This causes existing custom worktree names to be lost on load and overwritten on the next state persistence.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as part of backlog cleanup: this PR is stale, currently conflicting with main, has no approval, and has not had active remediation for 30+ days. If the change is still relevant, please rebase onto current main and request reopening or submit a focused current diff. Thank you for the contribution.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheIcarusWings@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(web): custom display labels for worktrees - #3070

Closed
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels
Closed

feat(web): custom display labels for worktrees#3070
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels

Conversation

@TheIcarusWings

@TheIcarusWingsTheIcarusWings commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What

Lets a worktree carry a readable display name instead of the auto-generated hash folder name (e.g. t3code-f07cb2c5). The label is cosmetic only — no git worktree move, no disk changes.

Screenshots

Bottom-bar workspace label — before vs. after renaming the worktree:

Default (hash-derived)Custom label

Rename dialog (opened from the bottom-bar label or the sidebar):

Entry point — sidebar thread context menu ("Rename worktree"; note the renamed label already showing in the bottom bar):

Design

  • Keyed by worktree PATH, not per-thread, so threads sharing a worktree always show the same name.
  • Stored in a persisted worktreeLabelByPath map in useUiStateStore (local UI state).
  • A single resolver — worktreeDisplayName(path, labelMap) = labelMap[path] ?? formatWorktreePathForDisplay(path) — is used everywhere a worktree name renders, so the UI stays consistent.
  • The rename UI is a single, globally-mounted dialog (WorktreeRenameDialog) driven by a small worktreeRenameStore, so every entry point opens the same dialog and writes the same path-keyed label.

Rename entry points

  • Sidebar thread context menu → "Rename worktree" (only for worktree-backed threads).
  • Bottom-bar workspace label: double-click, or right-click → "Rename worktree" (desktop + mobile).

Leaving the field blank resets to the default hash-derived name. The label persists across reloads.

Where labels surface

  • Bottom-bar workspace label (desktop BranchToolbarEnvModeSelector + mobile MobileRunContextSelector).
  • Orphan-worktree delete confirmation dialog.

Tests

  • worktreeDisplayName (label / fallback / blank / trim).
  • setWorktreeLabel reducer (set / trim / clear / sibling independence) + persistence round-trip.
  • Custom-label cases for resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

pnpm typecheck and vp lint clean; full web unit suite passes (1057 tests). Verified manually in the running app: rename from all entry points, shared label across two threads on the same worktree, blank-resets-to-default, and persistence across reload.

🤖 Generated with Claude Code


Note

Low Risk
Client-only persisted UI labels and rename flows; worktree deletion still uses existing VCS APIs, with label cleanup on successful remove.

Overview
Adds cosmetic worktree display names keyed by environment and worktree path, persisted in local UI state and shared by every thread on that worktree (no disk/git changes).

A global WorktreeRenameDialog plus worktreeRenameStore lets users set or clear labels from the sidebar thread menu (Rename worktree), or from the bottom-bar workspace label via double-click or right-click (useWorktreeRenameTrigger). BranchToolbar / BranchToolbarEnvModeSelector read labels through useWorktreeLabel and pass them into resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

worktreeDisplayName and formatWorktreeDeleteConfirmation use custom labels in orphan-worktree delete prompts; successful worktree removal clears the stored label. Unit tests cover label persistence, resolver behavior, rename trigger context-menu fallback, and display helpers.

Reviewed by Cursor Bugbot for commit 64f86a9. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add custom display labels for worktrees in the branch toolbar and sidebar

  • Introduces a global WorktreeRenameDialog (via useWorktreeRenameStore) that lets users set or clear a cosmetic label for any active worktree, accessible via double-click, right-click context menu, or the sidebar thread context menu.
  • Adds worktreeLabelByEnvironment to uiStateStore, persisted to localStorage and keyed by environment ID and worktree path.
  • Updates BranchToolbarEnvModeSelector and BranchToolbar.MobileRunContextSelector to display the custom label when set, falling back to existing defaults ('Current worktree' / 'Worktree').
  • Extends worktree delete flow in useThreadActions to show the custom label in confirmation text and clear the stored label on successful deletion.

Macroscope summarized 64f86a9.

@coderabbitai

coderabbitaiBot commented Jun 13, 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

Run ID: 9ce56739-357c-4b92-9003-5c4b1b0fc4c5

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 and usage tips.

@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Jun 13, 2026
@macroscopeapp

macroscopeappBot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new user-facing feature (custom worktree labels) with new UI components, state management, and persistence logic. New features warrant human review, and there's an unresolved comment about potential data migration issues.

You can customize Macroscope's approvability policy. Learn more.

TheIcarusWingsand others added 3 commits June 18, 2026 23:00
Let a worktree carry a readable display name instead of the auto-generated
hash folder name (e.g. "t3code-f07cb2c5"). The label is cosmetic only — no
`git worktree move`, no disk changes.
Keyed by worktree PATH (not per-thread) so threads sharing a worktree always
show the same name. Stored in a persisted `worktreeLabelByPath` map in
useUiStateStore. A single `worktreeDisplayName(path, labelMap)` resolver is
used everywhere a worktree name renders.
Rename entry points (all open one shared, globally-mounted dialog):
- Sidebar thread context menu → "Rename worktree" (worktree-backed threads).
- Bottom-bar workspace label: double-click, or right-click → "Rename worktree".
Labels surface in the bottom-bar workspace label and the orphan-worktree
delete confirmation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Address self-review findings on the worktree display-label feature:
- Clear a worktree's custom label when the worktree is deleted
(orphan-delete in useThreadActions), so it can't linger in persisted
state or be inherited by a future worktree reusing the same path.
- Key labels by the verbatim worktree path everywhere. Previously writers
trimmed the path key while useWorktreeLabel read it raw, so a path with
surrounding whitespace would store and read under different keys.
- Remove unused useWorktreeDisplayName hook (dead code).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/worktree-display-labels branch from fcda8a9 to 29febaeCompareJune 19, 2026 06:21
Prevent label collisions across environments that reuse the same worktree path, and fall back to the rename dialog when the native context-menu bridge fails.
Co-authored-by: codex <codex@users.noreply.github.com>

@cursorcursorBot 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 reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

parsed.defaultAdvertisedEndpointKey.length > 0
? parsed.defaultAdvertisedEndpointKey
: null,
worktreeLabelByEnvironment: sanitizePersistedWorktreeLabels(parsed.worktreeLabelByEnvironment),

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.

Path-only label persistence dropped

Medium Severity

The parsePersistedState function was updated to expect the new worktreeLabelByEnvironment structure, but it no longer reads the prior worktreeLabelByPath format from the t3code:ui-state:v1 localStorage key. This causes existing custom worktree names to be lost on load and overwritten on the next state persistence.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as part of backlog cleanup: this PR is stale, currently conflicting with main, has no approval, and has not had active remediation for 30+ days. If the change is still relevant, please rebase onto current main and request reopening or submit a focused current diff. Thank you for the contribution.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheIcarusWings@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(web): custom display labels for worktrees - #3070

Closed
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels
Closed

feat(web): custom display labels for worktrees#3070
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels

Conversation

@TheIcarusWings

@TheIcarusWingsTheIcarusWings commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What

Lets a worktree carry a readable display name instead of the auto-generated hash folder name (e.g. t3code-f07cb2c5). The label is cosmetic only — no git worktree move, no disk changes.

Screenshots

Bottom-bar workspace label — before vs. after renaming the worktree:

Default (hash-derived)Custom label

Rename dialog (opened from the bottom-bar label or the sidebar):

Entry point — sidebar thread context menu ("Rename worktree"; note the renamed label already showing in the bottom bar):

Design

  • Keyed by worktree PATH, not per-thread, so threads sharing a worktree always show the same name.
  • Stored in a persisted worktreeLabelByPath map in useUiStateStore (local UI state).
  • A single resolver — worktreeDisplayName(path, labelMap) = labelMap[path] ?? formatWorktreePathForDisplay(path) — is used everywhere a worktree name renders, so the UI stays consistent.
  • The rename UI is a single, globally-mounted dialog (WorktreeRenameDialog) driven by a small worktreeRenameStore, so every entry point opens the same dialog and writes the same path-keyed label.

Rename entry points

  • Sidebar thread context menu → "Rename worktree" (only for worktree-backed threads).
  • Bottom-bar workspace label: double-click, or right-click → "Rename worktree" (desktop + mobile).

Leaving the field blank resets to the default hash-derived name. The label persists across reloads.

Where labels surface

  • Bottom-bar workspace label (desktop BranchToolbarEnvModeSelector + mobile MobileRunContextSelector).
  • Orphan-worktree delete confirmation dialog.

Tests

  • worktreeDisplayName (label / fallback / blank / trim).
  • setWorktreeLabel reducer (set / trim / clear / sibling independence) + persistence round-trip.
  • Custom-label cases for resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

pnpm typecheck and vp lint clean; full web unit suite passes (1057 tests). Verified manually in the running app: rename from all entry points, shared label across two threads on the same worktree, blank-resets-to-default, and persistence across reload.

🤖 Generated with Claude Code


Note

Low Risk
Client-only persisted UI labels and rename flows; worktree deletion still uses existing VCS APIs, with label cleanup on successful remove.

Overview
Adds cosmetic worktree display names keyed by environment and worktree path, persisted in local UI state and shared by every thread on that worktree (no disk/git changes).

A global WorktreeRenameDialog plus worktreeRenameStore lets users set or clear labels from the sidebar thread menu (Rename worktree), or from the bottom-bar workspace label via double-click or right-click (useWorktreeRenameTrigger). BranchToolbar / BranchToolbarEnvModeSelector read labels through useWorktreeLabel and pass them into resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

worktreeDisplayName and formatWorktreeDeleteConfirmation use custom labels in orphan-worktree delete prompts; successful worktree removal clears the stored label. Unit tests cover label persistence, resolver behavior, rename trigger context-menu fallback, and display helpers.

Reviewed by Cursor Bugbot for commit 64f86a9. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add custom display labels for worktrees in the branch toolbar and sidebar

  • Introduces a global WorktreeRenameDialog (via useWorktreeRenameStore) that lets users set or clear a cosmetic label for any active worktree, accessible via double-click, right-click context menu, or the sidebar thread context menu.
  • Adds worktreeLabelByEnvironment to uiStateStore, persisted to localStorage and keyed by environment ID and worktree path.
  • Updates BranchToolbarEnvModeSelector and BranchToolbar.MobileRunContextSelector to display the custom label when set, falling back to existing defaults ('Current worktree' / 'Worktree').
  • Extends worktree delete flow in useThreadActions to show the custom label in confirmation text and clear the stored label on successful deletion.

Macroscope summarized 64f86a9.

@coderabbitai

coderabbitaiBot commented Jun 13, 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

Run ID: 9ce56739-357c-4b92-9003-5c4b1b0fc4c5

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 and usage tips.

@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Jun 13, 2026
@macroscopeapp

macroscopeappBot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new user-facing feature (custom worktree labels) with new UI components, state management, and persistence logic. New features warrant human review, and there's an unresolved comment about potential data migration issues.

You can customize Macroscope's approvability policy. Learn more.

TheIcarusWingsand others added 3 commits June 18, 2026 23:00
Let a worktree carry a readable display name instead of the auto-generated
hash folder name (e.g. "t3code-f07cb2c5"). The label is cosmetic only — no
`git worktree move`, no disk changes.
Keyed by worktree PATH (not per-thread) so threads sharing a worktree always
show the same name. Stored in a persisted `worktreeLabelByPath` map in
useUiStateStore. A single `worktreeDisplayName(path, labelMap)` resolver is
used everywhere a worktree name renders.
Rename entry points (all open one shared, globally-mounted dialog):
- Sidebar thread context menu → "Rename worktree" (worktree-backed threads).
- Bottom-bar workspace label: double-click, or right-click → "Rename worktree".
Labels surface in the bottom-bar workspace label and the orphan-worktree
delete confirmation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Address self-review findings on the worktree display-label feature:
- Clear a worktree's custom label when the worktree is deleted
(orphan-delete in useThreadActions), so it can't linger in persisted
state or be inherited by a future worktree reusing the same path.
- Key labels by the verbatim worktree path everywhere. Previously writers
trimmed the path key while useWorktreeLabel read it raw, so a path with
surrounding whitespace would store and read under different keys.
- Remove unused useWorktreeDisplayName hook (dead code).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/worktree-display-labels branch from fcda8a9 to 29febaeCompareJune 19, 2026 06:21
Prevent label collisions across environments that reuse the same worktree path, and fall back to the rename dialog when the native context-menu bridge fails.
Co-authored-by: codex <codex@users.noreply.github.com>

@cursorcursorBot 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 reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

parsed.defaultAdvertisedEndpointKey.length > 0
? parsed.defaultAdvertisedEndpointKey
: null,
worktreeLabelByEnvironment: sanitizePersistedWorktreeLabels(parsed.worktreeLabelByEnvironment),

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.

Path-only label persistence dropped

Medium Severity

The parsePersistedState function was updated to expect the new worktreeLabelByEnvironment structure, but it no longer reads the prior worktreeLabelByPath format from the t3code:ui-state:v1 localStorage key. This causes existing custom worktree names to be lost on load and overwritten on the next state persistence.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as part of backlog cleanup: this PR is stale, currently conflicting with main, has no approval, and has not had active remediation for 30+ days. If the change is still relevant, please rebase onto current main and request reopening or submit a focused current diff. Thank you for the contribution.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheIcarusWings@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(web): custom display labels for worktrees - #3070

Closed
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels
Closed

feat(web): custom display labels for worktrees#3070
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels

Conversation

@TheIcarusWings

@TheIcarusWingsTheIcarusWings commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What

Lets a worktree carry a readable display name instead of the auto-generated hash folder name (e.g. t3code-f07cb2c5). The label is cosmetic only — no git worktree move, no disk changes.

Screenshots

Bottom-bar workspace label — before vs. after renaming the worktree:

Default (hash-derived)Custom label

Rename dialog (opened from the bottom-bar label or the sidebar):

Entry point — sidebar thread context menu ("Rename worktree"; note the renamed label already showing in the bottom bar):

Design

  • Keyed by worktree PATH, not per-thread, so threads sharing a worktree always show the same name.
  • Stored in a persisted worktreeLabelByPath map in useUiStateStore (local UI state).
  • A single resolver — worktreeDisplayName(path, labelMap) = labelMap[path] ?? formatWorktreePathForDisplay(path) — is used everywhere a worktree name renders, so the UI stays consistent.
  • The rename UI is a single, globally-mounted dialog (WorktreeRenameDialog) driven by a small worktreeRenameStore, so every entry point opens the same dialog and writes the same path-keyed label.

Rename entry points

  • Sidebar thread context menu → "Rename worktree" (only for worktree-backed threads).
  • Bottom-bar workspace label: double-click, or right-click → "Rename worktree" (desktop + mobile).

Leaving the field blank resets to the default hash-derived name. The label persists across reloads.

Where labels surface

  • Bottom-bar workspace label (desktop BranchToolbarEnvModeSelector + mobile MobileRunContextSelector).
  • Orphan-worktree delete confirmation dialog.

Tests

  • worktreeDisplayName (label / fallback / blank / trim).
  • setWorktreeLabel reducer (set / trim / clear / sibling independence) + persistence round-trip.
  • Custom-label cases for resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

pnpm typecheck and vp lint clean; full web unit suite passes (1057 tests). Verified manually in the running app: rename from all entry points, shared label across two threads on the same worktree, blank-resets-to-default, and persistence across reload.

🤖 Generated with Claude Code


Note

Low Risk
Client-only persisted UI labels and rename flows; worktree deletion still uses existing VCS APIs, with label cleanup on successful remove.

Overview
Adds cosmetic worktree display names keyed by environment and worktree path, persisted in local UI state and shared by every thread on that worktree (no disk/git changes).

A global WorktreeRenameDialog plus worktreeRenameStore lets users set or clear labels from the sidebar thread menu (Rename worktree), or from the bottom-bar workspace label via double-click or right-click (useWorktreeRenameTrigger). BranchToolbar / BranchToolbarEnvModeSelector read labels through useWorktreeLabel and pass them into resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

worktreeDisplayName and formatWorktreeDeleteConfirmation use custom labels in orphan-worktree delete prompts; successful worktree removal clears the stored label. Unit tests cover label persistence, resolver behavior, rename trigger context-menu fallback, and display helpers.

Reviewed by Cursor Bugbot for commit 64f86a9. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add custom display labels for worktrees in the branch toolbar and sidebar

  • Introduces a global WorktreeRenameDialog (via useWorktreeRenameStore) that lets users set or clear a cosmetic label for any active worktree, accessible via double-click, right-click context menu, or the sidebar thread context menu.
  • Adds worktreeLabelByEnvironment to uiStateStore, persisted to localStorage and keyed by environment ID and worktree path.
  • Updates BranchToolbarEnvModeSelector and BranchToolbar.MobileRunContextSelector to display the custom label when set, falling back to existing defaults ('Current worktree' / 'Worktree').
  • Extends worktree delete flow in useThreadActions to show the custom label in confirmation text and clear the stored label on successful deletion.

Macroscope summarized 64f86a9.

@coderabbitai

coderabbitaiBot commented Jun 13, 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

Run ID: 9ce56739-357c-4b92-9003-5c4b1b0fc4c5

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 and usage tips.

@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Jun 13, 2026
@macroscopeapp

macroscopeappBot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new user-facing feature (custom worktree labels) with new UI components, state management, and persistence logic. New features warrant human review, and there's an unresolved comment about potential data migration issues.

You can customize Macroscope's approvability policy. Learn more.

TheIcarusWingsand others added 3 commits June 18, 2026 23:00
Let a worktree carry a readable display name instead of the auto-generated
hash folder name (e.g. "t3code-f07cb2c5"). The label is cosmetic only — no
`git worktree move`, no disk changes.
Keyed by worktree PATH (not per-thread) so threads sharing a worktree always
show the same name. Stored in a persisted `worktreeLabelByPath` map in
useUiStateStore. A single `worktreeDisplayName(path, labelMap)` resolver is
used everywhere a worktree name renders.
Rename entry points (all open one shared, globally-mounted dialog):
- Sidebar thread context menu → "Rename worktree" (worktree-backed threads).
- Bottom-bar workspace label: double-click, or right-click → "Rename worktree".
Labels surface in the bottom-bar workspace label and the orphan-worktree
delete confirmation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Address self-review findings on the worktree display-label feature:
- Clear a worktree's custom label when the worktree is deleted
(orphan-delete in useThreadActions), so it can't linger in persisted
state or be inherited by a future worktree reusing the same path.
- Key labels by the verbatim worktree path everywhere. Previously writers
trimmed the path key while useWorktreeLabel read it raw, so a path with
surrounding whitespace would store and read under different keys.
- Remove unused useWorktreeDisplayName hook (dead code).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/worktree-display-labels branch from fcda8a9 to 29febaeCompareJune 19, 2026 06:21
Prevent label collisions across environments that reuse the same worktree path, and fall back to the rename dialog when the native context-menu bridge fails.
Co-authored-by: codex <codex@users.noreply.github.com>

@cursorcursorBot 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 reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

parsed.defaultAdvertisedEndpointKey.length > 0
? parsed.defaultAdvertisedEndpointKey
: null,
worktreeLabelByEnvironment: sanitizePersistedWorktreeLabels(parsed.worktreeLabelByEnvironment),

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.

Path-only label persistence dropped

Medium Severity

The parsePersistedState function was updated to expect the new worktreeLabelByEnvironment structure, but it no longer reads the prior worktreeLabelByPath format from the t3code:ui-state:v1 localStorage key. This causes existing custom worktree names to be lost on load and overwritten on the next state persistence.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as part of backlog cleanup: this PR is stale, currently conflicting with main, has no approval, and has not had active remediation for 30+ days. If the change is still relevant, please rebase onto current main and request reopening or submit a focused current diff. Thank you for the contribution.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheIcarusWings@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(web): custom display labels for worktrees - #3070

Closed
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels
Closed

feat(web): custom display labels for worktrees#3070
TheIcarusWings wants to merge 4 commits into
pingdotgg:mainfrom
TheIcarusWings:t3code/worktree-display-labels

Conversation

@TheIcarusWings

@TheIcarusWingsTheIcarusWings commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What

Lets a worktree carry a readable display name instead of the auto-generated hash folder name (e.g. t3code-f07cb2c5). The label is cosmetic only — no git worktree move, no disk changes.

Screenshots

Bottom-bar workspace label — before vs. after renaming the worktree:

Default (hash-derived)Custom label

Rename dialog (opened from the bottom-bar label or the sidebar):

Entry point — sidebar thread context menu ("Rename worktree"; note the renamed label already showing in the bottom bar):

Design

  • Keyed by worktree PATH, not per-thread, so threads sharing a worktree always show the same name.
  • Stored in a persisted worktreeLabelByPath map in useUiStateStore (local UI state).
  • A single resolver — worktreeDisplayName(path, labelMap) = labelMap[path] ?? formatWorktreePathForDisplay(path) — is used everywhere a worktree name renders, so the UI stays consistent.
  • The rename UI is a single, globally-mounted dialog (WorktreeRenameDialog) driven by a small worktreeRenameStore, so every entry point opens the same dialog and writes the same path-keyed label.

Rename entry points

  • Sidebar thread context menu → "Rename worktree" (only for worktree-backed threads).
  • Bottom-bar workspace label: double-click, or right-click → "Rename worktree" (desktop + mobile).

Leaving the field blank resets to the default hash-derived name. The label persists across reloads.

Where labels surface

  • Bottom-bar workspace label (desktop BranchToolbarEnvModeSelector + mobile MobileRunContextSelector).
  • Orphan-worktree delete confirmation dialog.

Tests

  • worktreeDisplayName (label / fallback / blank / trim).
  • setWorktreeLabel reducer (set / trim / clear / sibling independence) + persistence round-trip.
  • Custom-label cases for resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

pnpm typecheck and vp lint clean; full web unit suite passes (1057 tests). Verified manually in the running app: rename from all entry points, shared label across two threads on the same worktree, blank-resets-to-default, and persistence across reload.

🤖 Generated with Claude Code


Note

Low Risk
Client-only persisted UI labels and rename flows; worktree deletion still uses existing VCS APIs, with label cleanup on successful remove.

Overview
Adds cosmetic worktree display names keyed by environment and worktree path, persisted in local UI state and shared by every thread on that worktree (no disk/git changes).

A global WorktreeRenameDialog plus worktreeRenameStore lets users set or clear labels from the sidebar thread menu (Rename worktree), or from the bottom-bar workspace label via double-click or right-click (useWorktreeRenameTrigger). BranchToolbar / BranchToolbarEnvModeSelector read labels through useWorktreeLabel and pass them into resolveCurrentWorkspaceLabel / resolveLockedWorkspaceLabel.

worktreeDisplayName and formatWorktreeDeleteConfirmation use custom labels in orphan-worktree delete prompts; successful worktree removal clears the stored label. Unit tests cover label persistence, resolver behavior, rename trigger context-menu fallback, and display helpers.

Reviewed by Cursor Bugbot for commit 64f86a9. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add custom display labels for worktrees in the branch toolbar and sidebar

  • Introduces a global WorktreeRenameDialog (via useWorktreeRenameStore) that lets users set or clear a cosmetic label for any active worktree, accessible via double-click, right-click context menu, or the sidebar thread context menu.
  • Adds worktreeLabelByEnvironment to uiStateStore, persisted to localStorage and keyed by environment ID and worktree path.
  • Updates BranchToolbarEnvModeSelector and BranchToolbar.MobileRunContextSelector to display the custom label when set, falling back to existing defaults ('Current worktree' / 'Worktree').
  • Extends worktree delete flow in useThreadActions to show the custom label in confirmation text and clear the stored label on successful deletion.

Macroscope summarized 64f86a9.

@coderabbitai

coderabbitaiBot commented Jun 13, 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

Run ID: 9ce56739-357c-4b92-9003-5c4b1b0fc4c5

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 and usage tips.

@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Jun 13, 2026
@macroscopeapp

macroscopeappBot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new user-facing feature (custom worktree labels) with new UI components, state management, and persistence logic. New features warrant human review, and there's an unresolved comment about potential data migration issues.

You can customize Macroscope's approvability policy. Learn more.

TheIcarusWingsand others added 3 commits June 18, 2026 23:00
Let a worktree carry a readable display name instead of the auto-generated
hash folder name (e.g. "t3code-f07cb2c5"). The label is cosmetic only — no
`git worktree move`, no disk changes.
Keyed by worktree PATH (not per-thread) so threads sharing a worktree always
show the same name. Stored in a persisted `worktreeLabelByPath` map in
useUiStateStore. A single `worktreeDisplayName(path, labelMap)` resolver is
used everywhere a worktree name renders.
Rename entry points (all open one shared, globally-mounted dialog):
- Sidebar thread context menu → "Rename worktree" (worktree-backed threads).
- Bottom-bar workspace label: double-click, or right-click → "Rename worktree".
Labels surface in the bottom-bar workspace label and the orphan-worktree
delete confirmation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Address self-review findings on the worktree display-label feature:
- Clear a worktree's custom label when the worktree is deleted
(orphan-delete in useThreadActions), so it can't linger in persisted
state or be inherited by a future worktree reusing the same path.
- Key labels by the verbatim worktree path everywhere. Previously writers
trimmed the path key while useWorktreeLabel read it raw, so a path with
surrounding whitespace would store and read under different keys.
- Remove unused useWorktreeDisplayName hook (dead code).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/worktree-display-labels branch from fcda8a9 to 29febaeCompareJune 19, 2026 06:21
Prevent label collisions across environments that reuse the same worktree path, and fall back to the rename dialog when the native context-menu bridge fails.
Co-authored-by: codex <codex@users.noreply.github.com>

@cursorcursorBot 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 reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

parsed.defaultAdvertisedEndpointKey.length > 0
? parsed.defaultAdvertisedEndpointKey
: null,
worktreeLabelByEnvironment: sanitizePersistedWorktreeLabels(parsed.worktreeLabelByEnvironment),

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.

Path-only label persistence dropped

Medium Severity

The parsePersistedState function was updated to expect the new worktreeLabelByEnvironment structure, but it no longer reads the prior worktreeLabelByPath format from the t3code:ui-state:v1 localStorage key. This causes existing custom worktree names to be lost on load and overwritten on the next state persistence.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 64f86a9. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing as part of backlog cleanup: this PR is stale, currently conflicting with main, has no approval, and has not had active remediation for 30+ days. If the change is still relevant, please rebase onto current main and request reopening or submit a focused current diff. Thank you for the contribution.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheIcarusWings@juliusmarminge