Skip to content

[codex] Group projects in new-thread pickers#4312

Merged
juliusmarminge merged 7 commits into
mainfrom
codex/grouped-project-pickers
Jul 23, 2026
Merged

[codex] Group projects in new-thread pickers#4312
juliusmarminge merged 7 commits into
mainfrom
codex/grouped-project-pickers

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Jul 22, 2026

Copy link
Copy Markdown
Member

Why

After Sidebar V2 groups duplicate repository copies, its new-thread flows can still list every physical environment/project pair. That makes the picker disagree with the sidebar and presents redundant choices.

Root cause

The command palette and global new-thread route consume the raw project collection rather than logical project snapshots.

Fix

  • present one entry per logical project in the command palette
  • prefer the active concrete project as the creation target
  • make the global shortcut use logical project count

Dependency

Stacked on PR #4282 because it reuses the logical grouping helpers introduced there.

Verification

  • targeted formatting and lint
  • vp run --filter @t3tools/web typecheck

Note

Group projects by logical group in new-thread pickers across sidebar, command palette, and draft hero

  • Introduces buildSidebarProjectPickerEntries and sortLogicalProjectsForSidebar to model and sort logical project groups (sets of related physical projects) for use in UI pickers.
  • The sidebar, command palette, and draft hero headline now display one entry per logical group using group.displayName, search across all member project titles/paths, and open the most recently active thread across all group members.
  • Removing a project from the sidebar filter menu now deletes all physical projects in the group.
  • The chat.new shortcut and new-thread button now trigger the project picker based on the number of logical groups rather than raw project count.
  • buildSidebarProjectSnapshots is extended to expose memberProjectRefs for all grouped physical projects, enabling downstream group-aware operations.

Macroscope summarized 7920d02.


Note

Medium Risk
Changes which project/thread is targeted when opening or creating threads from grouped duplicates; behavior is localized to pickers and shortcuts using existing grouping helpers, not server or auth paths.

Overview
Aligns new-thread flows with Sidebar V2 logical project grouping so pickers no longer list every physical environment/project pair for the same repo.

The command palette builds project actions from buildSidebarProjectPickerEntries / snapshots (manual order, grouping settings, sidebar sort). Each row uses the group display name; buildProjectActionItems accepts optional searchTerms so member titles and workspace roots still match search. Open project resolves the latest non-archived thread across all members of the group. New thread in project keeps the contextual concrete project when it belongs to the selected group. The quick “New thread in …” action label prefers the preferred picker entry’s group name.

Draft hero project menu uses the same grouped entries and display names instead of a flat sorted project list.

Global chat.new (Sidebar v2) opens the palette only when projectGroupCount > 1, not raw project count.

Sidebar v2 thread rows show group display names for project titles; settle/unsettle hover buttons drop bordered row-hover styling for transparent buttons.

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

@coderabbitai

coderabbitai Bot commented Jul 22, 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: 2a535d17-fb13-4929-a098-ad75be286ddb

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
  • Commit unit tests in branch codex/grouped-project-pickers

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

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 22, 2026
@juliusmarminge
juliusmarminge marked this pull request as ready for review July 22, 2026 22:35
Comment thread apps/web/src/components/CommandPalette.tsx Outdated
Comment thread apps/web/src/components/CommandPalette.tsx
@macroscopeapp

macroscopeapp Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

2 blocking correctness issues found. This feature PR has multiple unresolved review comments identifying bugs: DraftHeroHeadline ignores manual project ordering, and SidebarV2 may show null project titles for some threads due to lookup issues in the new grouping logic.

No code changes detected at af1853b. Prior analysis still applies.

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

@juliusmarminge
juliusmarminge force-pushed the codex/grouped-project-pickers branch from e7d474e to 7ec6918 Compare July 22, 2026 23:14
Comment thread apps/web/src/components/CommandPalette.tsx
Comment thread apps/web/src/components/CommandPalette.tsx Outdated
@juliusmarminge
juliusmarminge force-pushed the codex/sidebar-v2-grouped-filter branch from c0f0ff2 to 2e484a2 Compare July 23, 2026 12:23
@juliusmarminge
juliusmarminge force-pushed the codex/grouped-project-pickers branch 3 times, most recently from 3914285 to 4078fa6 Compare July 23, 2026 12:55
),
[environments],
);
const projectGroups = useMemo(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Medium chat/DraftHeroHeadline.tsx:52

When projectSortOrder is "manual", the project picker in DraftHeroHeadline displays projects in entity-store order instead of the user's saved sidebar order, so the menu disagrees with the sidebar. sortLogicalProjectsForSidebar preserves its input order for manual sorting, but projectGroups passes the raw projects collection into buildSidebarProjectSnapshots without first applying the saved projectOrder that the sidebar and command palette use. Apply the user's manual ordering to projects before passing them into buildSidebarProjectSnapshots.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/web/src/components/chat/DraftHeroHeadline.tsx around line 52:

When `projectSortOrder` is `"manual"`, the project picker in `DraftHeroHeadline` displays projects in entity-store order instead of the user's saved sidebar order, so the menu disagrees with the sidebar. `sortLogicalProjectsForSidebar` preserves its input order for manual sorting, but `projectGroups` passes the raw `projects` collection into `buildSidebarProjectSnapshots` without first applying the saved `projectOrder` that the sidebar and command palette use. Apply the user's manual ordering to `projects` before passing them into `buildSidebarProjectSnapshots`.

[projects],
);
const projectTitleByKey = useMemo(
const projectDisplayNameByKey = useMemo(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Medium components/SidebarV2.tsx:826

projectDisplayNameByKey is built only from group.memberProjects, which buildSidebarProjectSnapshots deduplicates down to one physical-project winner per group. But threads can belong to a discarded duplicate project ref that is absent from memberProjects yet present in memberProjectRefs. For those rows, the projectDisplayNameByKey.get(...) lookup returns undefined, so the row gets projectTitle={null} instead of the group display name it received before this change. The mapping should be built from group.memberProjectRefs (or the raw projects list) so every concrete ref resolves to the group's display name.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/web/src/components/SidebarV2.tsx around line 826:

`projectDisplayNameByKey` is built only from `group.memberProjects`, which `buildSidebarProjectSnapshots` deduplicates down to one physical-project winner per group. But threads can belong to a discarded duplicate project ref that is absent from `memberProjects` yet present in `memberProjectRefs`. For those rows, the `projectDisplayNameByKey.get(...)` lookup returns `undefined`, so the row gets `projectTitle={null}` instead of the group display name it received before this change. The mapping should be built from `group.memberProjectRefs` (or the raw `projects` list) so every concrete ref resolves to the group's display name.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is ON, but a cloud agent failed to start.

Reviewed by Cursor Bugbot for commit 7920d02. Configure here.

Comment thread apps/web/src/components/SidebarV2.tsx
Comment thread apps/web/src/components/chat/DraftHeroHeadline.tsx
@juliusmarminge
juliusmarminge changed the base branch from codex/sidebar-v2-grouped-filter to main July 23, 2026 16:07
juliusmarminge and others added 7 commits July 23, 2026 18:07
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarminge force-pushed the codex/grouped-project-pickers branch from 7920d02 to af1853b Compare July 23, 2026 16:07
@juliusmarminge
juliusmarminge enabled auto-merge (squash) July 23, 2026 16:07
aria-label="Un-settle thread"
onClick={handleUnsettleClick}
className="absolute inset-y-0 right-0 inline-flex cursor-pointer items-center gap-1 rounded-md border border-sidebar-border bg-sidebar-row-hover px-2 text-xs text-muted-foreground opacity-0 transition-opacity hover:text-foreground focus-visible:opacity-100 group-hover/v2-row:opacity-100 dark:border-transparent dark:inset-ring-1 dark:inset-ring-white/5"
className="absolute inset-y-0 right-0 inline-flex cursor-pointer items-center gap-1 rounded-md bg-transparent px-2 text-xs text-muted-foreground opacity-0 transition-opacity hover:text-foreground focus-visible:opacity-100 group-hover/v2-row:opacity-100"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Medium components/SidebarV2.tsx:576

The settle/unsettle buttons lose their opaque background, so when a keyboard user tabs to one without hovering, focus-visible:opacity-100 reveals the button while the time/status label underneath stays visible (it's only hidden via group-hover/v2-row:opacity-0). Both texts render in the same space and overlap, becoming illegible. Restoring an opaque background or adding group-focus-within/v2-row:opacity-0 to the label would prevent the overlap. The same issue affects the equivalent buttons at lines 585 and 662.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/web/src/components/SidebarV2.tsx around line 576:

The settle/unsettle buttons lose their opaque background, so when a keyboard user tabs to one without hovering, `focus-visible:opacity-100` reveals the button while the time/status label underneath stays visible (it's only hidden via `group-hover/v2-row:opacity-0`). Both texts render in the same space and overlap, becoming illegible. Restoring an opaque background or adding `group-focus-within/v2-row:opacity-0` to the label would prevent the overlap. The same issue affects the equivalent buttons at lines 585 and 662.

@juliusmarminge
juliusmarminge merged commit 9d9208c into main Jul 23, 2026
16 checks passed
@juliusmarminge
juliusmarminge deleted the codex/grouped-project-pickers branch July 23, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant