Repository navigation
fix(mobile): open profile management on the stack that owns the caller - #8708
Conversation
The new-session form and agent session screens live on the root `(app)` Stack, but the profile-management destinations they open (repository defaults, Manage profiles) resolved inside the Profile tab stack. A push that crosses into the tabs navigator leaves the caller behind it, so Back landed on the tab root and the next Back reached the composer only through the discard guard. Profile-management routes now take the Stack they belong to. The Profile tab keeps its own routes and screens; a second route tree at `(app)/profile-management` serves the root Stack, so Back returns to the form, the session, or the tab row that opened the screen, with the draft or the session state intact. - `profile-agent-navigation` builds every profile path for either stack, defaulting to the Profile tab. - Repository defaults, Manage profiles and the session profile chip pass the root stack. - The profile list, create screen and overview stay in the stack they were mounted in for their own pushes.
|
bot: Android emulator, local dev stack, local test account. On the fixed build: repository defaults opens from the new-session form without the bottom tab bar, and both the header Back and the system Back return to the form with the typed draft still in the field; the same holds after Environment → profile picker → Manage profiles → New profile → Back → Back. The draft text in the captures is test data typed for this run. |
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryThe incremental change folds the branch onto current Assumptions: Files Reviewed (26 files)
Previous Review Summaries (2 snapshots, latest commit eae63cf)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit eae63cf)Status: No Issues Found | Recommendation: Merge Executive SummaryThe follow-up makes the bottom clearance stack-aware through Assumptions: Files Reviewed (14 files)
Previous review (commit 49ff505)Status: 1 Issues Found | Recommendation: Address before merge Executive SummaryThe stack-owned profile navigation is implemented consistently across the composer, session and Profile tab entry points; the only finding is a layout remnant where the new root-stack profile screens still reserve the tab bar's bottom clearance. Assumptions: Overview
Issue Details (click to expand)SUGGESTION
Files Reviewed (26 files)
Reviewed by deepseek-flash-latest · Input: 79.6K · Output: 21.4K · Cached: 1.4M Review guidance: REVIEW.md from base branch |
The shared profile screens render TabScreenScrollView, which reserves the tab bar's band in the viewport. A screen reused on the root (app) Stack has no bar below it, so that band was empty space at the bottom of every root-stack profile screen. TabBarBandContext now carries whether a bar is rendered below the screen. The tabs navigator keeps the default, and the root-stack profile routes provide false, so their viewport ends at the safe-area edge. Measured on the emulator with the same screen component: viewport bottom at y=2337 from the new-session form versus y=2195 from the Profile tab.
|
bot: Android emulator, same screen component, one build. The profiles list opened from the new-session form ends its scroll viewport at y=2337 (the safe-area edge); the same list opened from the Profile tab ends at y=2195, where the tab-bar band sits. The root-stack copy no longer reserves an empty band at the bottom, and the tab copy is unchanged. |
…ent-stack # Conflicts: # apps/mobile/src/components/tab-screen.mounted.test.tsx # apps/mobile/src/components/tab-screen.tsx # apps/mobile/src/lib/tab-bar-clearance.ts
|
bot: Correction after merging main: the earlier note about a local band context no longer applies to this branch. #8509 gives the root stack its own |
The two route trees render the same screens; the comment states the rule a caller must follow, at the constant that encodes it.
|
bot: Re-ran the flow on the current head (56b5072): new-session form → prompt → Advanced configuration → repository defaults → header Back returns to the form with the draft, and system Back from repository defaults does the same. The draft text in the captures is test data typed for this run. |








Evidence
Evidence: demonstrated — on the Android emulator against the local dev stack, with a local test account (re-run on the final head). Before the change, opening repository defaults from the new-session form and tapping the header Back landed on the Home tab (the repository-defaults screen it opened also kept the bottom tab bar). After the change, the same screen opens on the new-session form's own stack: header Back and system Back both return to the form with the draft text still in the field, and Manage profiles → New profile → Back → Back also returns to the form. The Profile tab's own Profiles row still keeps the tab bar, and Back from there returns to the Profile tab.
What changed
The new-session form (
(app)/agent-chat/new) and the agent session screens live on the root(app)Stack, but the profile-management screens they opened resolved inside the Profile tab stack. A push that crosses into the tabs navigator leaves the caller behind it, so Back landed on the tab root instead of the screen that opened the profile screen.Profile management now takes the Stack it belongs to:
src/lib/profile-agent-navigation.tsbuilds every profile path for either stack (apporprofileTab) and defaults to the Profile tab, so existing callers and the Profile tab keep their current routes.src/app/(app)/profile-management/**is a thin route tree on the root stack that renders the existing screens (list, create, repository defaults, profile editor tabs). The Profile tab's own routes are unchanged.The root-stack copies also inherit the root stack's content clearance (
TabBarLabelContextisnullthere since the stack itself owns the tab-bar boundary), so their scroll viewport ends at the safe-area edge rather than reserving a bar band that is not rendered.Verification
pnpm --filter kilo-app exec vitest run src/lib/profile-agent-navigation.test.ts src/components/profiles src/components/tab-screen.mounted.test.tsx src/app/\(app\)/agent-chat/profile-picker.mounted.test.tsx src/components/agents/session-detail-content.test.ts— passes.pnpm --filter kilo-app test— 18785 tests pass (2 skipped).pnpm exec tsgo --noEmitandpnpm --filter kilo-app run lintare clean.Not exercised on the emulator: the agent-session profile chip, because producing a session with an active profile needs fixtures this run does not have. Its route target is covered by the updated mounted test in
session-detail-content.test.ts, which now asserts the root-stack path.Proxy answers
The owner's proxy gave these answers in the owner's place.
Answer: Composer + agent session
Confidence: 0.65 · Precedent: Fix the root cause and the class of the issue on every affected surface: session 7f3470e0ba6f, "fix class of issue preventing progress"; session 75f8833fe8c1, "fix this for all ... on all surfaces"
Answer: Parallel app-stack route tree
Confidence: 0.70 · Precedent: The brief requires that Profile tab entry points keep their current behavior. UX rule (no surprising layout change, best-in-class standard): session 00eb2a1d3e4b, "design and UX MUST BE BEST-IN-CLASS". Keep the wrappers thin and reuse the existing screen components.
Answer: Push a genuine small commit
Confidence: 0.68 · Precedent: Autonomy: "blocked is not an acceptable end state" (55c9c80332a7) and "if you saw a gap, fix it" (89824a222897). The missing PROFILE_ROOTS rationale comment is a real gap, and adding it gets the bot to review the new head.