Skip to content

fix(console): an app-root deep link keeps its query when it redirects to the landing page - #27641

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-7wdma9
Oct 29, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-7wdma9

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Bill · project thread
Fixes #27450

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:打开 /apps/APP?palette=1 这类应用根深链时,应用根重定向到默认页会保留查询串和 hash,命令面板照常打开;?recordId=、?form= 等其它 URL 浮层参数同样保留。控制台根 /?palette=1 也一样。
  • 为什么改:应用根的重定向只用默认页地址拼目标,把查询串丢了,浮层参数在被读取之前就没了。分诊结论是「重定向要把查询带过去」。
  • 风险与回滚:只改两处前端重定向的目标拼接;不带查询的应用根行为字节不变。默认页自身带查询(页面 params、对象 filters/runAction)时两者合并,同名键以链接为准、不重复。回滚即 revert 本 PR。
  • 先看:ui/packages/app-shell/src/console/AppContent.tsx 的 carryQueryOntoLanding 与 AppRootLanding 里那行 Navigate;然后 ui/apps/console/src/components/RootLandingRedirect.tsx 末尾的重定向;最后新测试 AppContent.rootLandingCarriesQuery-27450.test.tsx。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/console/__tests__/AppContent.rootLandingCarriesQuery-27450.test.tsx apps/console/src/components/RootLandingRedirect.route.test.tsx,预期 2 个文件 22 个用例全绿。
  • 需要你做的:无,席位落地。

What changes

Two redirects that land a user on a page rebuilt their target without the URL's query, so the URL overlays (?palette=1, ?recordId=, ?form=, the constants in urlParams.ts) were dropped before useUrlOverlay read them.

  • App root (/apps/APP, AppRootLanding in AppContent.tsx): the Navigate to the app's landing now goes through a new local helper, carryQueryOntoLanding(landing, location.search, location.hash). With nothing arriving the target is unchanged. With no query on the landing the arriving search is appended as written. A landing can carry a query of its own (a page entry's params, an object entry's filters or runAction, built by resolveHref): then the two merge through URLSearchParams, and a key the arriving URL names replaces the landing's values for that key instead of doubling it (the link is the more specific ask). The arriving hash wins over a landing hash; resolveHref emits none today.
  • Console root (/, RootLandingRedirect in ui/apps/console): the RedirectWithSplash target now appends location.search and location.hash. Its landing is a bare /apps/SEGMENT or /home, so there is nothing to merge; the app root it lands on carries the query on in turn.

The fix is generic query carriage, not a palette special case. The other redirects on these paths were measured and left as they are:

Changeset: @object-ui/app-shell patch, @object-ui/console patch.

Tests

  • New ui/packages/app-shell/src/console/__tests__/AppContent.rootLandingCarriesQuery-27450.test.tsx, on the AppContent.nameAliasRedirect-26183 harness (a real AppContent mount; the router's location is the observation point). Its ConsoleLayout stand-in keeps the real CommandPaletteProvider the shipped layout mounts, so "the palette is open" is that provider's own answer from the landed URL. Cases: the card's URL (/apps/showcase_app?palette=1, through the name-alias move too) lands on the default page with ?palette=1 kept, REPLACE, palette open; a record-drawer param and a hash are carried; a landing with its own ?runAction= merges with ?palette=1; a key both name is the link's value once; CONTROL: a bare app root lands bare with the palette closed.
  • ui/apps/console/src/components/RootLandingRedirect.route.test.tsx: three cases added (default app with query and hash, the launcher with query, CONTROL bare /), and its location probe now also renders the hash.

Ablation, each via scripts/ablation-replace.mjs (anchor hit 1 to 0, restored to the HEAD blob with git diff HEAD empty):

  • AppContent.tsx target reverted to to={landing}: 4 of 5 new cases red, the CONTROL green.
  • RootLandingRedirect.tsx target reverted to to={landing}: the 2 new carrying cases red, the other 15 in the file green.

Acceptance notes

  • /home?palette=1 from the console root keeps the query, but the home frame mounts no CommandPaletteProvider (useCommandPalette documents the home and orgs frames as palette-less), so the palette does not open there. The card names the app root; this is noted, not changed.
  • An unauthenticated /?palette=1 goes to login first; whether LoginRedirect captures a bare / with a query is outside this card and unchanged.
  • Browser reproduction of the card's steps on a running showcase was not done in this container; the acceptance is pinned by the mounted AppContent test above.

Verification

Targeted tests, ablation and typecheck (head 27534cf)
  • New and edited files: pnpm --dir ui exec vitest run --maxWorkers=2 --reporter=verbose packages/app-shell/src/console/__tests__/AppContent.rootLandingCarriesQuery-27450.test.tsx apps/console/src/components/RootLandingRedirect.route.test.tsx: Test Files 2 passed (2), Tests 22 passed (22).
  • Neighbouring landing and redirect suites (every AppContent.* file on landing, alias, boot redirects, pseudo-routes, the Setup and System redirect targets, and the console's RootLandingRedirect, landingHomeParity-7256 and SetupRoute tests): Test Files 20 passed (20), Tests 193 passed (193).
  • Ablation 1, AppContent.tsx anchor to={carryQueryOntoLanding(landing, location.search, location.hash)} to to={landing}: Tests 4 failed, 1 passed (5); restored, blob == HEAD.
  • Ablation 2, RootLandingRedirect.tsx anchor on the template-literal target to to={landing}: Tests 2 failed, 15 passed (17); restored, blob == HEAD.
  • pnpm --filter @object-ui/app-shell run type-check: exit 0; the new test file is in tsconfig.test.json's program (--listFilesOnly count 1).
  • pnpm --filter @object-ui/console run type-check: exit 0 (after building the five plugin dists the console imports); the route test is in its program (--listFilesOnly count 1).
  • eslint on the four touched files: 0 errors; no warning on a touched line.
  • check:new-line-citations (ui): 0 new citations.
Derived gates

At head 27534cfd, node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 34 derived; each run and recorded as COMMAND :: exit CODE, all 34 exit 0, reconciled with --ran: "34 derived famil(ies) accounted for — 34 run, 0 NOT-MEASURED". node scripts/check-sdui-manifest.mjs and pnpm check:nul-bytes are among them. main moved 4 commits since the base 77e993ea, none touching these files; no merge taken. Every other family is CI's, on this PR's check-runs.


Generated by Claude Code

…t and console-root landing redirects

The app root (`/apps/:appName`) redirected to the app's landing with a
target built from the landing alone, so `?palette=1` and every other URL
overlay param was dropped before anything read it. `AppRootLanding` now
carries search and hash onto the landing, merging with a landing that has
a query of its own (a key the link names replaces the landing's value).
`RootLandingRedirect` at the console root carries them as well.

Claude-Session: https://claude.ai/code/session_01Utp6CbjUouY1fgaJXGSQMk
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tooling labels Oct 29, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#4 · os-bill · session_01Utp6CbDAucNyQ4UtzCJKyh

席位核对

ACCEPT · head 27534cfdbef8cd43f2e4eb4925019cb366510f09 · 2026-10-29T16:08Z

  • Shape: draft → main, with Fixes #27450 on its own line and no other card number beside a closing keyword. Clause-②: no and Metadata-protocol: none hold. carryQueryOntoLanding is module-local in AppContent.tsx. @object-ui/app-shell and @object-ui/console are private: true, so there is no published surface. The PR body and the changeset agree.
  • Change, read:
    • AppRootLanding sends its Navigate target through carryQueryOntoLanding(landing, search, hash). It returns the landing untouched when no query arrives. It appends the arriving query verbatim when the landing has none. When both have a query, it merges them with URLSearchParams, so a key the link names replaces the landing's value instead of doubling it.
    • RootLandingRedirect appends search and hash to its bare /apps/SEGMENT or /home target.
    • This is generic carriage, not a palette special case.
  • Surface: within claim 6500141247, as amended by 6500172717 to add RootLandingRedirect.tsx. AppContent.tsx was serialised behind seat 2's PR fix(app-shell): a member Setup refuses gets the app's no-access page on Setup's settings and marketplace routes #27590, and mergeable_state reads clean.
  • Left alone, named in the body: the no-active-app bounce to homePath (a refusal, not a landing). LegacyMetadataRedirect resource mode (consumes ?type= by design). metadata/package/* (fixed target).
  • Observations accepted, not filed: the /home frame mounts no palette provider, so /home?palette=1 keeps the query but opens nothing. Unauthenticated /?palette=1 capture through login was not measured.
  • Evidence: the new AppContent.rootLandingCarriesQuery-27450.test.tsx uses the real CommandPaletteProvider, which reads the landed URL. Three cases were added to RootLandingRedirect.route.test.tsx. 22/22 pass. Both ablations go red (4/5 and 2/17) and were restored to the HEAD blob.
  • Gates (check-runs on the head): 44 success, 11 skipped, 0 failure. Lint & Repo Gates, TypeScript Type Check and Check Changeset are each success. check-governed-merges --pr 27641 reads NOT governed, 311 changed lines.
  • Landing: the PR is non-governed, all checks are green and mergeable_state is clean, so the seat lands it (pr_ready + automerge_enable).

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 29, 2026 16:09
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit b761968 Oct 29, 2026
56 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-7wdma9 branch October 29, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

console: the ?palette=1 deep-link is dropped when an app root redirects to its default page

1 participant