Skip to content

feat(mobile): show persistent context controls - #5715

Merged
iscekic merged 6 commits into
mainfrom
mobile-context-unlock-a61f
Sep 1, 2026
Merged

iscekic merged 6 commits into
mainfrom
mobile-context-unlock-a61f

Conversation

@iscekic

@iscekic iscekic commented Aug 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Switch between Personal and your organizations directly below the title on Home, Agents, or Quick Chat.
  • On launch, account labels show loading until your saved choice is available, instead of briefly showing Personal.
  • Retry failed account loads or saves without leaving the screen. A failed save does not undo your selection.
  • An unavailable organization now shows a warning and stays selected until you choose another account.
  • Personal stays in the account picker when your organization list is empty, including on Profile.
  • Session headers identify the session's own Personal account or organization without changing the account selected on other screens.
  • Screen readers receive account labels, selection hints, and loading, error, and Retry states.

Maintainer changes

OrganizationContextValue adds isSaving, error (restore or save), and retry; failed restoration keeps isLoaded false.
Save failures retain the chosen account; Retry saves the latest choice, while OrganizationState.token, generations, and authentication epochs prevent stale publication.
setOrganizationId keeps its signature, and ORGANIZATION_STORAGE_KEY still stores an organization string or no value for Personal.

Files
  • apps/mobile/src/lib/organization-context.tsx — Source; M; 145 changed lines; retains save warnings through retries and rejects outdated results after selection, authentication changes, or unmount.
  • apps/mobile/src/lib/organization-context.mounted.test.tsx — Test; A; 317 changed lines; adds a mounted provider suite.

ContextControl introduces global account selection and read-only ContextDisplayScope labels; organizationId: null explicitly means Personal, and isResolved prevents premature labels.
useContextPicker uses supplied memberships and the native action sheet, including Personal for an empty result; cancellation changes nothing.
Loading placeholders, accessible states, and Retry separate restoration, save, and membership failures; missing organizations stay selected and show an unavailable warning.

Files
  • apps/mobile/src/components/context-control.tsx — Source; A; 164 changed lines; adds scoped labels, membership loading, accessible selection and recovery, and safe-area spacing for the shared picker.
  • apps/mobile/src/components/context-control.mounted.test.tsx — Test; A; 323 changed lines; adds a mounted context-control suite.

SessionDetailContentProps.displayScope becomes required so every session label describes that session, not the active global account.
SessionDetailScreen resolves it from the route's organizationId or fetched organization_id; loading and error headers retain the same read-only control.
Unresolved session metadata keeps a placeholder, while the existing AgentSessionProvider continues to own the session independently.

Files
  • apps/mobile/src/app/(app)/agent-chat/[session-id].tsx — Source; M; 13 changed lines; supplies the resolved session scope to the pending, failed, and loaded presentations.
  • apps/mobile/src/components/agents/session-detail-content.tsx — Source; M; 4 changed lines; requires the display scope and renders its account label beneath the session title.
  • apps/mobile/src/app/(app)/agent-chat/[session-id].mounted.test.tsx — Test; M; 149 changed lines; revises mounted session-route coverage.
  • apps/mobile/src/components/agents/session-detail-content.test.ts — Test; M; 71 changed lines; revises the session-detail suite.

ScreenHeaderProps.context adds optional content below the title, keeping account controls fixed on Home, Agents, and Quick Chat.
Existing title actions, Back, history, filters, and right-side controls remain separate from the selector.
Callers that omit the slot keep the title-only layout.

Files
  • apps/mobile/src/components/screen-header.tsx — Source; M; 5 changed lines; accepts and renders the optional account-control slot beneath the title.
  • apps/mobile/src/components/home/home-screen.tsx — Source; M; 9 changed lines; adds the shared selector outside the scrolling Home body.
  • apps/mobile/src/components/agents/session-list-screen.tsx — Source; M; 2 changed lines; mounts the selector in the header independently of list loading, errors, and results.
  • apps/mobile/src/components/quick-chat/quick-chat-screen.tsx — Source; M; 7 changed lines; mounts the selector before the keyboard-adjusted transcript and composer.
  • apps/mobile/src/components/home/home-screen.mounted.test.tsx — Test; M; 57 changed lines; revises the mounted Home suite.
  • apps/mobile/src/components/home/home-screen.test.ts — Test; M; 1 changed line; updates the Home test setup.
  • apps/mobile/src/components/agents/session-list-screen.mounted.test.tsx — Test; M; 63 changed lines; revises the mounted Agents suite.
  • apps/mobile/src/components/quick-chat/quick-chat-screen.mounted.test.tsx — Test; M; 58 changed lines; revises the mounted Quick Chat suite.

CreditsCard reuses useContextPicker and no longer hides account selection when the membership query returns an empty list.
A save failure adds an accessible Retry with busy and disabled states; balance queries and billing permissions retain their existing rules.

Files
  • apps/mobile/src/components/profile-credits-card.tsx — Source; M; 66 changed lines; replaces the local picker implementation, labels its account button, and renders save recovery.
  • apps/mobile/src/components/profile-credits-card.mounted.test.tsx — Test; M; 244 changed lines; revises the mounted credits-card suite.

The mobile continuous integration (CI) workflow kilo-app CI accepts pull requests against any target branch, so stacked changes receive checks.
It removes only pull_request.branches; pull_request.paths, the push.branches restriction to main, jobs, permissions, and concurrency remain intact.

Files
  • .github/workflows/kilo-app-ci.yml — Source; M; 1 changed line; removes the pull request target restriction without changing the push trigger.

Tests: 9 files, 1,283 changed lines; added organization-context.mounted.test.tsx, context-control.mounted.test.tsx; modified [session-id].mounted.test.tsx, session-detail-content.test.ts, session-list-screen.mounted.test.tsx, home-screen.mounted.test.tsx, home-screen.test.ts, quick-chat-screen.mounted.test.tsx, profile-credits-card.mounted.test.tsx.
Generated: 0 changed files.


Verification

Local end-to-end verification on an iOS simulator, 2026-09-01. Seven of eleven checks passed. Four have partial coverage.

This section covers the stack's three PRs together: #5715, #5719, and #5721.

No product bug was found. No product source changed. The worktree stayed clean.

Check Result Note
4. Removed membership shows "Organization unavailable" and survives a cold launch PASS Only an explicit Personal selection clears it.
5. Picker keeps Personal available with no memberships PASS Cancel stays available.
6. A transcript shows its own context as static text PASS A label tap opens no picker; the global context survives.
7. Preferences documents launch, background, setup, and passcode fallback PASS Help text covers all four.
9. A cold launch gates content behind authentication PASS The gate hides the draft, the open sheet, and the tab bar.
10. Five background minutes require authentication again PASS Real background time was 305 seconds.
11. A successful match restores the draft and the open sheet PASS Code stayed selected; the draft text survived.
1. Context switches on Home and Agents PARTIAL Quick Chat is owner-descoped and was unreachable.
2. A saved organization restores before Personal at startup PARTIAL Local restore finished before the first visible frame, so the loading state never appeared.
3. An organization-list failure shows an error and recovers on Retry PARTIAL Backend failure verified. A local SecureStore failure has no fault seam.
8. The unlock switch guards against taps during authentication PARTIAL Verified during native authentication. The local write phase completed too fast to test.

Test-harness limits, not defects

  • Account restoration and selection saving use SecureStore. A backend lock cannot delay or fail a local keychain operation, so failed-save retention has no runtime verdict.
  • No simulator passcode was set, so the passcode fallback path was not exercised. Check 7 covers its help text only.
  • This Xcode rejects simctl biometric. Native simulator enrollment, match, and failure notifications were used instead.
  • Accessibility checks read the simulator accessibility tree. VoiceOver speech itself was not tested.

Setup

  • Real worktree stack and Metro, branch mobile-context-unlock-a61f-s3, simulator iOS 26.5.
  • Normal browser sign-in. Faults came from bounded PostgreSQL transactions on named tables.
  • Screenshots captured with xcrun simctl io <udid> screenshot. Full report and images: /Users/igor/Projects/.scratch/local-e2e-context/.

@kilo-code-bot

kilo-code-bot Bot commented Aug 29, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed the follow-up react-test-renderer type-cast corrections in mounted context-control tests with high confidence and no blocking defects.

Files Reviewed (7 files)
  • apps/mobile/src/app/(app)/agent-chat/[session-id].mounted.test.tsx
  • apps/mobile/src/components/agents/session-detail-content.test.ts
  • apps/mobile/src/components/agents/session-list-screen.mounted.test.tsx
  • apps/mobile/src/components/context-control.mounted.test.tsx
  • apps/mobile/src/components/home/home-screen.mounted.test.tsx
  • apps/mobile/src/components/profile-credits-card.mounted.test.tsx
  • apps/mobile/src/components/quick-chat/quick-chat-screen.mounted.test.tsx
Previous Review Summaries (2 snapshots, latest commit 4d3ec77)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 4d3ec77)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed the follow-up save/restore busy-state wiring (isSaving, picker and Retry progress) with high confidence and no blocking defects.

Files Reviewed (8 files)
  • apps/mobile/src/components/agents/session-list-screen.mounted.test.tsx
  • apps/mobile/src/components/context-control.mounted.test.tsx
  • apps/mobile/src/components/context-control.tsx
  • apps/mobile/src/components/home/home-screen.mounted.test.tsx
  • apps/mobile/src/components/profile-credits-card.mounted.test.tsx
  • apps/mobile/src/components/profile-credits-card.tsx
  • apps/mobile/src/lib/organization-context.mounted.test.tsx
  • apps/mobile/src/lib/organization-context.tsx

Previous review (commit 48c4842)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed persistent mobile account-context controls, organization restore/save guards, and session display-scope wiring with high confidence and no blocking defects.

Files Reviewed (19 files)
  • .github/workflows/kilo-app-ci.yml
  • apps/mobile/src/app/(app)/agent-chat/[session-id].mounted.test.tsx
  • apps/mobile/src/app/(app)/agent-chat/[session-id].tsx
  • apps/mobile/src/components/agents/session-detail-content.test.ts
  • apps/mobile/src/components/agents/session-detail-content.tsx
  • apps/mobile/src/components/agents/session-list-screen.mounted.test.tsx
  • apps/mobile/src/components/agents/session-list-screen.tsx
  • apps/mobile/src/components/context-control.mounted.test.tsx
  • apps/mobile/src/components/context-control.tsx
  • apps/mobile/src/components/home/home-screen.mounted.test.tsx
  • apps/mobile/src/components/home/home-screen.test.ts
  • apps/mobile/src/components/home/home-screen.tsx
  • apps/mobile/src/components/profile-credits-card.mounted.test.tsx
  • apps/mobile/src/components/profile-credits-card.tsx
  • apps/mobile/src/components/quick-chat/quick-chat-screen.mounted.test.tsx
  • apps/mobile/src/components/quick-chat/quick-chat-screen.tsx
  • apps/mobile/src/components/screen-header.tsx
  • apps/mobile/src/lib/organization-context.mounted.test.tsx
  • apps/mobile/src/lib/organization-context.tsx

Reviewed by grok-4.6 · Input: 77.5K · Output: 3.5K · Cached: 78.5K

Review guidance: REVIEW.md from base branch main

@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready The PR is ready for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants