Repository navigation
fix(app-shell): one app opens under one address — name-alias routes move onto the package id - #26262
Merged
Merged
Conversation
A route that reached its app through the name alias kept the alias in every link it built while the sidebar built on the package id, so one app answered under two address families. AppContent now replaces the alias segment with the app's one address (path, search, hash and state kept), and both landing producers name the package id directly. Claude-Session: https://claude.ai/code/session_01WMwiEU2YGp3QigAjKszWFq Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WMwiEU2YGp3QigAjKszWFq Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WMwiEU2YGp3QigAjKszWFq Co-authored-by: Claude <noreply@anthropic.com>
A name-alias route moves after its first render, so a first-render probe on the alias read either address depending on timing. Claude-Session: https://claude.ai/code/session_01WMwiEU2YGp3QigAjKszWFq Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WMwiEU2YGp3QigAjKszWFq Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Oct 26, 2026
Contributor
Author
席位核对 · ACCEPT · seat
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Steve · project thread
Fixes #26183
Clause-②: no
Metadata-protocol: none
What was wrong
ADR-0048 §3.6 makes the package id the canonical
/apps/SEGMENTkey ("Canonical = package id"), and objectui#11818 / #11887 moved the app-independent links onto it. The sidebar was already right:UnifiedSidebarbuildsbasePathfromappRouteSegment(activeApp), andresolveHrefin@object-ui/layoutbuilds object (with or withoutviewName), component, page, dashboard, report and doc entries on thatbasePath. So the obligations entry and the approvals inbox in the card are on the canonical address.The second family came from the app NAME alias.
matchAppBySegmentresolves a name,AppContentthen keyed every path it builds on the URL's own segment (appSegment = appName ?? …), and two landing producers emitted the name:resolveDeclaredHomePath(top-bar logo, Home) and the console'sresolveLandingPath(the post-login/). Landing on/apps/clmkept list rows, record pages and related lists onclm, while every sidebar click went toapp.objectstack.hotclm.What changed
utils/appRoute.ts:appAddressSegment(apps, app), the one address of an app: its package id when that resolves back to the same app, else its name (a package that ships several apps shares one package id, which opens the first).canonicalAppPathname(apps, segment, pathname), the alias route rewritten onto that address, ornullwhen it already carries it. It cannot loop: its answer resolves back to the same app.console/AppContent.tsx: a name-alias route is moved onto the address withreplace, keeping the path, query string, hash and history state. This runs in an effect, so a layout already on screen is not unmounted.appSegmentnow keys on the matched app's address, so the recent-items tracker never records the alias.utils/homePath.tsand the console'sRootLandingRedirect.tsx: both landings name the address directly, so no redirect hop follows. They still agree, andlandingHomeParity-7256.test.tsgains two cases for that.Old addresses still open. A name-based bookmark or shared link resolves through the alias as before and then lands on the package id.
Tests
AppContent.nameAliasRedirect-26183.test.tsx(new, a realAppContentmount): the alias moves onto the package id with search, hash and state kept, as aREPLACE. Controls that do not move: the package-id route, an app whose name is its package id (no loop), and the second app of a shared package.appRoute.test.ts:appAddressSegmentandcanonicalAppPathname, covering no loop, name equal to package id, package-less apps, a shared package, and segments outside/apps.homePath.test.ts,RootLandingRedirect.test.ts,landingHomeParity-7256.test.ts: the landing names the package id. Two existing pins changed address because of this: declared Setup now lands on/apps/com.objectstack.setup, and Studio alone on/apps/com.objectstack.studio. What each pin checks (which app is the landing) is unchanged.AppContent.recentOnPackageRoute-11818.test.tsx: its alias CONTROL now records the visit once, on the package-id address.Local run results are in the
os-dev-reportcomment on the card.Acceptance notes
/apps/setup/…links in the console still work, now with one replace-hop onto/apps/com.objectstack.setup/…for a session whose app list carries Setup. Moving those producers ontoresolveHostAppSegmentis not part of this PR (carrier: none).Generated by Claude Code