Skip to content

fix(ui): show project names in session hover cards - #4743

Merged
Astro-Han merged 1 commit into
apache:mainfrom
liuxiaocs7:fix/session-hover-project-name
Sep 4, 2026
Merged

fix(ui): show project names in session hover cards#4743
Astro-Han merged 1 commit into
apache:mainfrom
liuxiaocs7:fix/session-hover-project-name

Conversation

@liuxiaocs7

Copy link
Copy Markdown
Member

Summary

  • show the registered project name in session hover cards instead of the full absolute working-directory path
  • fall back to the working directory folder name for sessions outside the project catalog
  • retain the full path as secondary tooltip context

Fixes #4742

Verification

  • npm run lint
  • npm run format:check
  • npm run build
  • npm --workspace @maka/ui run test:dist (364 passed)
  • npm --workspace @maka/desktop run typecheck
  • npx knip --workspace packages/ui
  • npx knip --workspace apps/desktop
  • npm run check:renderer-architecture (71 passed)
  • npx playwright test --config e2e/playwright.config.ts e2e/sidebar-project-row.spec.ts (4 passed)

Visual verification used the deterministic Electron sidebar fixture: the task card now renders 示例项目; the absolute fixture path remains available only through the element title.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Codex diagnosed the display path, implemented the project-name projection and fallback, and added regression coverage.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

Resolve each session's registered project name for sidebar hover details, falling back to the working directory basename while retaining the full path as secondary tooltip context.

Fixes apache#4742

Generated-by: Codex
@github-actions github-actions Bot added the effort/S Under 100 readable lines label Sep 4, 2026
@liuxiaocs7

Copy link
Copy Markdown
Member Author

Visual verification

Before After
Before: absolute working-directory path After: registered project name

Both screenshots use the deterministic Electron sidebar fixture. The full path remains available through the project-name element’s tooltip.

Generated-by: Codex

@Astro-Han Astro-Han 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.

Right fix. Reusing deriveTitlebarProjectName rather than adding a second name derivation is what makes it reviewable, keeping the absolute path on title means nothing is lost for mouse users, and moving the aria description to the same value keeps the spoken and visible text in agreement.

I checked the cases where the new value can be worse than the path it replaces. Most are not: a project that is archived or missing from the local snapshot falls back to the cwd basename rather than blanking, sessions outside the catalog fall back the same way, and the only input where the old code rendered something and the new one renders nothing is cwd === '/', which named nothing anyway. Three notes below, none blocking.

[P3] projectNameByIdentity is a fourth copy of one rule, and it resolves differently

@maka/core/project owns "resolve a project by id or alias":

export function findProjectByIdentity<T extends { readonly id: string; readonly aliases?: readonly string[] }>(
  projects: readonly T[], identity: string,
): T | undefined {
  return projects.find((project) => project.id === identity || project.aliases?.includes(identity));
}

session-project-grouping.ts already builds two more index structures from the same input.projects in this same hook — canonicalProjectIds in deriveSessionNavigationGroups, and projectsById in deriveWorktreeSessionIds, which is already a Map<identity, ProjectRecord> and therefore already carries name. The new map is the fourth.

A map is a real improvement over an O(n) find per row, so this is not "just call the existing function". But the rule now diverges rather than merely repeating: names.set(alias, …) in a loop is last-write-wins, while find is first-match-wins. Two projects sharing an alias resolve to different names depending on which path asks. Relink is supposed to prevent shared aliases, so that specific input is a constructed one and I am not raising it as a defect — it is evidence that these are no longer the same rule.

Reusing the projectsById map that deriveWorktreeSessionIds already builds would give the O(1) lookup and one authority at the same time.

[P3] The change costs the ability to tell worktree sessions apart

A project's main checkout and each of its worktree sessions all carry the same projectId, and workspace-resolver.ts sets cwd from project.preferredPath. Their hover cards now show identical project-name lines, separated only by the boolean worktree badge, which does not name the worktree. The cwd used to separate them.

#4742 explicitly allows the path to become secondary tooltip detail, and the native tooltip does carry it — I confirmed Astryx's useHoverCard keeps the card open when the pointer moves into it and does not set pointer-events: none, so the path is reachable on hover. So this is a real reduction that the issue authorised, not a regression against it. worktreeSessionIds is already computed one line away if you want 项目名 · <basename> for those rows.

Related: for keyboard and screen-reader users the title is not reachable, and the aria description now carries the project name instead of the path, so the absolute path has no path at all in the sidebar for them. Given the issue's framing that is a trade rather than a loss, and the surrounding comments show the AT surface was considered — flagging it so it is a decision.

[P3] The new selector has a unit seam right next to it and the coverage went to E2E instead

session-navigation-controller.test.ts already asserts this exact selector shape:

assert.equal(controller().selectors.sessionMeta(linkedCatalog[2]!), 'Remote Mac');

Two more lines there would cover sessionProjectName. As it stands the only new assertion is the E2E happy path, so alias resolution, the outside-catalog fallback, and projectId: null have no coverage in any tier. The checklist claim holds — the E2E does fail on main, because the class name does not exist — but the covered surface is one of four branches.

That also matters for placement: e2e/sidebar-project-row.spec.ts is on #4761's P2 list, so this grows a file scheduled to move, while the seam that would survive the move is already open.

Approving.

@Astro-Han
Astro-Han merged commit 4f72332 into apache:main Sep 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/S Under 100 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(ui): show project names in session hover cards

2 participants