Skip to content

fix(mobile): PR sheet chrome + session UX defect batch; sandbox CLI 7.3.63 for routed-model stamps - #4763

Merged
iscekic merged 9 commits into
mainfrom
mobile/review-session-ux
Jul 25, 2026
Merged

fix(mobile): PR sheet chrome + session UX defect batch; sandbox CLI 7.3.63 for routed-model stamps#4763
iscekic merged 9 commits into
mainfrom
mobile/review-session-ux

Conversation

@iscekic

@iscekic iscekic commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Mobile UX defect batch (7 reproduced defects) + GitHub rate-limit investigation (report-only).

  • R1/R2 — PR formSheets: the comment-composer, review-submit, and merge sheets did not paint their (already-existing) headers; a stray leading-edge floated over content; with the keyboard open the CTA footer rendered fully behind the keyboard. Root cause (device-backed): react-native-screens formSheet only honors a pinned header when the screen content's direct children are [header, ScrollView] — the old View → ScrollView + sticky footer tree made the ScrollView full-bleed over the header; the stray was the parent PR screen's "Go back" showing through a transparent top band. Fix: shared pinned PrFormSheetHeader outside the ScrollView, footer CTAs as trailing scroll content with automaticallyAdjustKeyboardInsets + AppAwareKeyboardPaddingView, plus density passes so all CTAs sit above the keyboard at both detents without scrolling.
  • R4 — file navigator: long paths overlapped the viewed toggle. Fix: min-w-0 chain, truncating shrinkable directory segment, non-shrinking basename, non-shrinking toggle with a guaranteed gap.
  • "Paste a link" hint: removed the redundant helper state (the input placeholder already shows the example URL); dead slot state pruned.
  • R5 — new-session composer: paperclip + mic rendered mid-height flanking the input. Fix: full-width input on top, one bottom action row (paperclip leading, voice trailing; voice-unavailable shows paperclip only).
  • R6 — cloud-agent preparation: the fixed Importing session… footer row duplicated the in-transcript PreparationGroup. Fix: shouldShowSessionFooterRow gate — while preparing, suppress the footer only when the merged transcript carries a visible (non-no-op) preparation item; otherwise the footer keeps rendering (never a blank progress window).
  • R7 — per-message model label: removed entirely; message info is now on long-tap via a new message-details sheet (Copy with immediate clipboard write, role, sent time, model row, cost/tokens block; VoiceOver/TalkBack rotor copy action unchanged).
  • R8 — auto model in Models section: display layer — the context sheet's Models section never renders kilo/kilo-auto/* rows (render-only filter; totals/residual untouched; count derives from filtered rows). Data path — root cause was the sandbox-pinned CLI 7.3.54 predating the routed-model stamp feature (first released in 7.3.63); bumped the pin in lockstep (Dockerfiles, wrangler image_vars, KILO_CLI_VERSION) and re-proved live: fresh kilo-auto/efficient sessions now stamp step-finish.model with the concrete routed id (e.g. qwen/qwen3.7-plus) at the ingest boundary and in the app-facing payload.

R3 (file-navigator missing header) was dropped: could not be reproduced — already fixed on baseline.

GitHub rate-limit investigation (report only — no code changes)

Claim Evidence
All PR-review GitHub calls use per-user GitHub App user access tokens: the token response schema requires expires_in + refresh_token and refresh uses grant_type: 'refresh_token' — the GitHub App user-to-server pattern; each call builds an Octokit with the fetched per-user token; all 16 procedures wrap withGitHubUserTokenRetry, so the rate-limit bucket is per user and scales with user count; no installation-token/shared-bucket path exists in this feature token schema + exchange apps/web/src/lib/integrations/platforms/github/user-authorization.ts:13-18,72-93; refresh grant services/git-token-service/src/github-user-authorization-service.ts:502-511; per-call fetch+Octokit apps/web/src/lib/github-pr-review/retry.ts:63-70 + client.ts:14-19; 16 call sites github-pr-review-router.ts:509-956
GitHub-documented primary limits for user-to-server tokens: 5,000 REST req/h + 5,000 GraphQL points/h per user (EXTERNAL doc figure, not in-repo) https://docs.github.com/en/rest/rate-limit + https://docs.github.com/en/graphql/overview/rate-limits-and-node-limits-for-the-graphql-api
Unbounded concurrent GraphQL burst: thread-comment follow-ups for up to 50 threads fire in one Promise.all github-pr-review-router.ts:653-673 + loop 399-429
Tight pagination with no pacing apps/mobile/src/lib/pr-review/diff/pr-review-file-list-state.ts:197-204; octokit.paginate in listChecks (apps/web/src/routers/github-pr-review-router.ts:570-581); onEndReached auto-pagination (apps/mobile/src/components/pr-review/diff/pr-diff-file-list.tsx:343-347)
Mergeability poller: each 3s tick = 1 tRPC overview refetch = 3 GitHub API requests server-side (pulls.get + repos.get + GraphQL), up to 10 ticks apps/mobile/src/components/pr-review/merge/pr-merge-section.tsx:49-50,131-142; fan-out apps/web/src/routers/github-pr-review-router.ts:515-537
Invalidation multiplier per mutation family: comment/submit → overview + ALL loaded thread pages; merge/update/auto-merge → overview + checks + ALL loaded file pages; reply/resolve/reactions → thread pages only apps/mobile/src/lib/pr-review/use-pr-review-mutations.ts:34-41; apps/mobile/src/lib/pr-review/merge/use-pr-merge-mutations.ts:31-40; apps/mobile/src/lib/pr-review/discussion/use-review-discussion-mutations.ts:55-60
Mobile auto-retries TOO_MANY_REQUESTS 2× against an exhausted bucket apps/mobile/src/lib/query-client.ts:7-26 (permanent-code set omits it)
Headerless 403 secondary limit misclassified as terminal FORBIDDEN apps/web/src/lib/github-pr-review/errors.ts:49-53,163-171
retryAfterEpochMs dropped at the tRPC boundary apps/web/src/lib/github-pr-review/retry.ts:22-27
No conditional requests/ETag; rate-limit headers read only after failure apps/web/src/lib/github-pr-review/errors.ts:146; repo-wide grep confirms no If-None-Match in GitHub paths
getFileLines downloads whole raw file per 500-line window, no cache apps/web/src/routers/github-pr-review-router.ts:611-637; apps/mobile/src/lib/pr-review/diff/use-pr-diff-context-loader.ts:61-68

Recommendations (no code in this PR): bound GraphQL follow-up concurrency + pace pagination; plumb retryAfter to the client and suppress auto-retry on 429; classify headerless 403 secondary limits as retryable TOO_MANY_REQUESTS; consider ETag caching for overview/files.

Notes

  • The sandbox CLI pin bump (7.3.63) takes effect for new sandboxes; production images pick it up on the next image build/publish. Existing sandboxes stay on 7.3.54 until recycled.
  • default-slash-commands.generated.ts: source marker bumped for the lockstep test; the catalog body was not regenerated (the generator's kilo serve step hung locally with 7.3.63) — content drift vs 7.3.63 is possible and tracked as follow-up.
  • providerMetadata.kilocode.routedModelID is not emitted by the 7.3.63 stamp path; consumers read part.model ({providerID, modelID}), which cloud-agent-sdk/part-utils#getStepFinishRoutedModel already does.

iscekic added 7 commits July 24, 2026 22:46
…board-safe footer

react-native-screens formSheet only honors a pinned header when the screen
content's direct children are [header, ScrollView]; the old
View → ScrollView + sticky-footer tree let the ScrollView go full-bleed and
overpaint the header. The stray leading-edge ‹ was the parent PR screen's
Go back showing through a transparent top band (opaque sheet chrome +
close affordance fixes it). Footer CTAs move inside the ScrollView as
trailing content with automaticallyAdjustKeyboardInsets +
AppAwareKeyboardPaddingView, plus density passes so Merge/Submit/comment
CTAs stay above the keyboard at both detents without scrolling.
The input placeholder already shows the example URL, so the Paste a link
hint state is dead weight; invalid and clipboard-empty helper states are
unchanged. Navigator rows get a min-w-0 chain with a truncating shrinkable
directory segment, non-shrinking basename, and a non-shrinking viewed
toggle with a guaranteed gap, so long paths no longer overlap the toggle.
Paperclip and voice button no longer flank the multiline input at
mid-height. The input sits full-width at the top of the card and one
bottom action row holds the paperclip (leading) and voice toggle
(trailing); when voice input is unavailable the row shows the paperclip
only. Attachment strip, voice status line, and ChatToolbar unchanged.
Render-only filter: a Models row is hidden iff providerID is kilo and
modelID starts with kilo-auto/. Totals and the Subagents residual are
still computed over all steps, and section visibility plus the Models (N)
count derive from the filtered rows plus the residual, so an auto-only
session with no residual hides the section entirely.
…amps

The 7.3.54 pin predates the routed-model stamp feature (first released in
v7.3.63), so step-finish parts for kilo-auto/* sessions arrived without a
model stamp and the mobile Models list had nothing concrete to show.
Bumped in lockstep across Dockerfiles, wrangler image_vars, and
KILO_CLI_VERSION (devcontainer.test.ts asserts the lockstep). Re-proved
live: a fresh kilo-auto/efficient session now stamps step-finish.model
with the concrete routed id at the ingest boundary and in the app-facing
payload. @kilocode/sdk stays at 7.3.54 (verified faithful in the ingest
path). The slash-command SOURCE marker follows the pin; the catalog body
regeneration is a follow-up (generator's kilo serve step hung locally).
…model label

While the cloud agent is preparing, the fixed footer row above the composer
duplicated the in-transcript PreparationGroup. The new
shouldShowSessionFooterRow gate suppresses the footer only while the
transcript carries a running (non-no-op) preparation item; a stale
completed or failed group never suppresses it, and with no live group the
footer keeps rendering so there is never a blank progress window.

Also removes the per-message model label from the transcript (label,
wiring, and computeMessageModelLabels); message info moves to a long-tap
details sheet. resolveMessageDisplayModel is kept for that sheet.
Long-press on a user or assistant message now opens a details sheet
(Modal pageSheet with SheetHeader chrome) instead of the copy ActionSheet.
The sheet shows a Copy message action (immediate clipboard write through
the shared performCopy extracted from use-message-copy, hidden when the
message has no copyable text), title-cased Role, Sent time formatted from
the epoch created timestamp, a Model row for assistant messages
(routed-first via resolveMessageDisplayModel, friendly catalog name,
hidden only when unresolvable), and a Cost & tokens block for assistant
messages (hidden when cost and all five token values are zero). The
VoiceOver/TalkBack rotor copy action keeps the existing useMessageCopy
behavior, and compaction-only rows stay non-interactive.
@iscekic iscekic self-assigned this Jul 24, 2026
@kilo-code-bot

kilo-code-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Re-verified against current HEAD (d7e2668c); the branch update since the last review is a clean merge of main only — none of this PR's 38 changed files have any new content diff, so no new Code Review Findings.

Files Reviewed (38 files)
  • apps/mobile/src/components/agents/message-bubble.test.ts
  • apps/mobile/src/components/agents/message-bubble.tsx
  • apps/mobile/src/components/agents/message-details-content.ts
  • apps/mobile/src/components/agents/message-details-copy.ts
  • apps/mobile/src/components/agents/message-details-sheet.test.ts
  • apps/mobile/src/components/agents/message-details-sheet.tsx
  • apps/mobile/src/components/agents/message-model-label.test.ts
  • apps/mobile/src/components/agents/message-model-label.ts
  • apps/mobile/src/components/agents/new-session-prompt.tsx
  • apps/mobile/src/components/agents/session-context-sheet.tsx
  • apps/mobile/src/components/agents/session-cost-breakdown-models-filter.test.ts
  • apps/mobile/src/components/agents/session-cost-breakdown.ts
  • apps/mobile/src/components/agents/session-detail-content.tsx
  • apps/mobile/src/components/agents/session-working-state.test.ts
  • apps/mobile/src/components/agents/session-working-state.ts
  • apps/mobile/src/components/agents/use-message-copy.test.ts
  • apps/mobile/src/components/agents/use-message-copy.ts
  • apps/mobile/src/components/pr-review/diff/pr-diff-navigator-file-row.tsx
  • apps/mobile/src/components/pr-review/merge/pr-merge-sheet-parts.tsx
  • apps/mobile/src/components/pr-review/merge/pr-merge-sheet.tsx
  • apps/mobile/src/components/pr-review/pr-form-sheet-chrome.tsx
  • apps/mobile/src/components/pr-review/pr-review-comment-composer-parts.tsx
  • apps/mobile/src/components/pr-review/pr-review-comment-composer-screen.tsx
  • apps/mobile/src/components/pr-review/pr-review-comment-composer.tsx
  • apps/mobile/src/components/pr-review/pr-review-entry-screen.tsx
  • apps/mobile/src/components/pr-review/pr-review-merge-screen.tsx
  • apps/mobile/src/components/pr-review/pr-review-pending-comment-row.tsx
  • apps/mobile/src/components/pr-review/pr-review-review-submit-screen.tsx
  • apps/mobile/src/components/pr-review/pr-review-submit.tsx
  • apps/mobile/src/lib/pr-review/pr-link-helper-slot.test.ts
  • apps/mobile/src/lib/pr-review/pr-link-helper-slot.ts
  • services/cloud-agent-next/Dockerfile
  • services/cloud-agent-next/Dockerfile.dev
  • services/cloud-agent-next/Dockerfile.dind
  • services/cloud-agent-next/src/kilo/devcontainer.ts
  • services/cloud-agent-next/src/shared/default-slash-commands.generated.ts
  • services/cloud-agent-next/wrangler.jsonc
Previous Review Summary (commit e62f835)

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

Previous review (commit e62f835)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed the mobile PR-sheet chrome/UX defect batch and cloud-agent-next CLI version bump across 39 changed files; no high-confidence security, runtime, logic, or breaking-API issues were found in changed lines.

Files Reviewed (39 files)
  • apps/mobile/src/components/agents/message-bubble.test.ts
  • apps/mobile/src/components/agents/message-bubble.tsx
  • apps/mobile/src/components/agents/message-details-content.ts
  • apps/mobile/src/components/agents/message-details-copy.ts
  • apps/mobile/src/components/agents/message-details-sheet.test.ts
  • apps/mobile/src/components/agents/message-details-sheet.tsx
  • apps/mobile/src/components/agents/message-model-label.test.ts
  • apps/mobile/src/components/agents/message-model-label.ts
  • apps/mobile/src/components/agents/new-session-prompt.tsx
  • apps/mobile/src/components/agents/session-context-sheet.tsx
  • apps/mobile/src/components/agents/session-cost-breakdown-models-filter.test.ts
  • apps/mobile/src/components/agents/session-cost-breakdown.ts
  • apps/mobile/src/components/agents/session-detail-content.tsx
  • apps/mobile/src/components/agents/session-working-state.test.ts
  • apps/mobile/src/components/agents/session-working-state.ts
  • apps/mobile/src/components/agents/use-message-copy.test.ts
  • apps/mobile/src/components/agents/use-message-copy.ts
  • apps/mobile/src/components/pr-review/diff/pr-diff-navigator-file-row.tsx
  • apps/mobile/src/components/pr-review/merge/pr-merge-sheet-parts.tsx
  • apps/mobile/src/components/pr-review/merge/pr-merge-sheet.tsx
  • apps/mobile/src/components/pr-review/pr-form-sheet-chrome.tsx
  • apps/mobile/src/components/pr-review/pr-review-comment-composer-parts.tsx
  • apps/mobile/src/components/pr-review/pr-review-comment-composer-screen.tsx
  • apps/mobile/src/components/pr-review/pr-review-comment-composer.tsx
  • apps/mobile/src/components/pr-review/pr-review-entry-screen.tsx
  • apps/mobile/src/components/pr-review/pr-review-merge-screen.tsx
  • apps/mobile/src/components/pr-review/pr-review-pending-comment-row.tsx
  • apps/mobile/src/components/pr-review/pr-review-review-submit-screen.tsx
  • apps/mobile/src/components/pr-review/pr-review-submit.tsx
  • apps/mobile/src/lib/pr-review/pr-link-helper-slot.test.ts
  • apps/mobile/src/lib/pr-review/pr-link-helper-slot.ts
  • services/cloud-agent-next/Dockerfile
  • services/cloud-agent-next/Dockerfile.dev
  • services/cloud-agent-next/Dockerfile.dind
  • services/cloud-agent-next/src/kilo/devcontainer.ts
  • services/cloud-agent-next/src/shared/default-slash-commands.generated.ts
  • services/cloud-agent-next/wrangler.jsonc

Reviewed by claude-sonnet-5 · Input: 18 · Output: 4.5K · Cached: 346.1K

Review guidance: REVIEW.md from base branch main

@iscekic

iscekic commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

(bot) @kilo-code-bot please review the latest head (57e0e8d) — the branch was updated with a clean merge of main.

@pandemicsyn pandemicsyn 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.

lgtm, one nit inline from the robot.

isDisabled,
/** Half-detent / keyboard-open: keep a single-line-ish field so footer CTAs fit. */
compact = false,
}: Readonly<{

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.

useFormSheetKeyboardVisible() is now called independently in both PrMergeSheet (for isHalfDetent) and CommitMessageField (for tight), each registering its own pair of Keyboard listeners. Functionally harmless (both derive the same boolean) but it duplicates listener setup/teardown on every mount and is easy to lose sync with if the two call sites ever diverge in show/hide event names.

Suggested fix: Thread the keyboard-visible boolean down from PrMergeSheet as a prop instead of re-subscribing inside CommitMessageField, matching the single-source pattern already used for isHalfDetent.

@iscekic
iscekic merged commit 62d15ad into main Jul 25, 2026
19 checks passed
@iscekic
iscekic deleted the mobile/review-session-ux branch July 25, 2026 06:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants