feat(mobile): adapt agent composers for keyboard, height, and preferences - #5617
Conversation
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryHiding the remaining-character counter until 1000 characters remain, plus compact starter chips with hitSlop, looks correct with high confidence. Files Reviewed (4 files)
Previous Review Summaries (10 snapshots, latest commit 52c3387)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 52c3387)Status: No Issues Found | Recommendation: Merge Executive SummaryDirectional UI Files Reviewed (5 files)
Previous review (commit 81d77d9)Status: No Issues Found | Recommendation: Merge Executive SummaryIncremental composer-control extraction, signed-URL attachment restore, and queue-cancel/optimistic-row fixes look correct with high confidence. Files Reviewed (98 files)
Previous review (commit 25329aa)Status: No Issues Found | Recommendation: Merge Executive SummaryUnused Files Reviewed (1 file)
Previous review (commit 0563cc1)Status: No Issues Found | Recommendation: Merge Executive SummaryCancel-queued restore now inlines the composer-empty check after dropping Files Reviewed (2 files)
Previous review (commit a24f1e1)Status: No Issues Found | Recommendation: Merge Executive Summary
Files Reviewed (2 files)
Previous review (commit c3187ea)Status: No Issues Found | Recommendation: Merge Executive SummaryIncremental a11y labels, metadata-status parity, and new-session-prompt test mocks look correct; the previous missing-mock warning is resolved. Files Reviewed (4 files)
Previous review (commit b88d498)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (3 files)
Fix these issues in Kilo Cloud Previous review (commit 305c0af)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (9 files)
Fix these issues in Kilo Cloud Previous review (commit 802c231)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (3 files)
Fix these issues in Kilo Cloud Previous review (commit 41a6f73)Status: 2 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (20 files)
Reviewed by grok-4.6 · Input: 73K · Output: 7.6K · Cached: 290.2K Review guidance: REVIEW.md from base branch |
# Conflicts: # apps/mobile/src/components/agents/chat-composer.test.ts
# Conflicts: # apps/mobile/src/components/agents/chat-composer-input-row.mounted.test.tsx
- Announce the photoMetadataNotRemoved status on the new-session prompt. - Label both character counters with charactersRemaining. - Mock the new composer dependencies in the new-session prompt suite.
# Conflicts: # apps/mobile/src/components/agents/new-session-configure-form.tsx # apps/mobile/src/components/agents/new-session-prompt.tsx
Starter chips lose the 44pt visual min-height. A hitSlop keeps the 44pt/48dp touch target. The chat composer chip row gains top padding against the transcript hairline. The remaining-character counter appears only when 1000 or fewer characters remain, instead of on the first keystroke.
Summary
Scope: 112 files, 2,296 insertions, and 249 deletions. Each file entry gives its status, class, and size in added-plus-removed lines.
Status: A = added; M = modified. Classes: 18 Source files, 8 Test files, and 86 Generated bundled translation assets.
restoreFilePartsreplaces the current attachment set rather than appending, so restoring a canceled message preserves its own file set and limit. It cancels displaced uploads and invalidates pending work, preventing late results from changing the replacement set.CancelQueuedRestoreOutcomeandresolveCancelQueuedRestoreOutcomeare removed; cancellation still restores into empty composers and keeps Restore available for occupied composers.Files
apps/mobile/src/lib/agent-attachments/use-agent-attachment-upload.ts— replaces restored chips, advances the generation, cancels uploads, and clears live identifiers (M, Source, 16 lines).apps/mobile/src/components/agents/mobile-session-manager.ts— removes the exported restoration outcome type and boolean mapper (M, Source, 8 lines).apps/mobile/src/lib/agent-attachments/use-agent-attachment-upload.test.ts— extends the attachment upload test file (M, Test, 67 lines).apps/mobile/src/components/agents/chat-composer-attachment-send.test.ts— updates the attachment-send test file (M, Test, 23 lines).useReturnSendsMessagePreferenceadds an on-device choice underRETURN_SENDS_MESSAGE_KEY(return-sends-message), defaulting to newline insertion. Only storedtrueenables sending, so absent or other stored values keep multiline behavior without migration. Preferences disables the switch until storage loads and uses the existing secure preference store to save changes.Files
apps/mobile/src/lib/hooks/use-return-sends-message-preference.ts— adds the boolean preference, loaded state, subscription, and setter through the shared store (A, Source, 26 lines).apps/mobile/src/lib/storage-keys.ts— registers the Return preference storage key (M, Source, 2 lines).apps/mobile/src/components/preferences-screen.tsx— adds the labeled Return switch and disables it until the preference loads (M, Source, 12 lines).apps/mobile/src/components/preferences-screen.mounted.test.tsx— extends the mounted preferences test file (M, Test, 37 lines).ChatComposerInputRowPropsnow requiresreturnSendsMessageandonInsertNewline; Return selectssubmitornewlinethroughsubmitBehavior. The newline button preserves line breaks; Send, Stop, and newline targets use 44 iOS points or 48 Android density-independent pixels. The parent retains send admission and caret insertion, whilemaxFontSizeMultiplier={1}prevents a second font scale.Files
apps/mobile/src/components/agents/chat-composer-input-row.tsx— switches Return behavior, adds the newline control, prevents double scaling, and enlarges Send and Stop (M, Source, 42 lines).apps/mobile/src/components/ui/icons.ts— exportsCornerDownLeftthrough the existing direct icon import convention (M, Source, 1 line).apps/mobile/src/components/agents/chat-composer-input-row.mounted.test.tsx— expands the mounted input-row test file (M, Test, 129 lines).resolveComposerMaxHeightreplaces the fixed 124-point and 160-point caps with remaining viewport space, preserving each input's minimum height.SESSION_HEADER_HEIGHT,STARTER_ROW_HEIGHT,COMPOSER_CHROME_HEIGHT, andNEW_SESSION_PROMPT_CHROME_HEIGHTreserve space for surrounding controls, with host budgets scaled for Dynamic Type.UseTextHeightOptions.fontScaleapplies scaling once; callers that omit it keep native scaling, and changed height limits apply without another text measurement.Files
apps/mobile/src/components/agents/chat-composer-input-height.ts— adds the remaining-space calculation and conservative header, starter, attachment, toolbar, and action budgets (M, Source, 69 lines).apps/mobile/src/components/agents/use-text-height.tsx— keeps unclamped content height, recalculates the displayed height, and optionally scales the native measurement text (M, Source, 43 lines).apps/mobile/src/components/agents/chat-composer-input-height.test.ts— extends the input-height test file (M, Test, 49 lines).ChatComposerSessionStateaddsempty,preparing,finalizing, andmessagephases, withmessageas the default for existing callers. Empty drafts offer three localized starters, with an extra choice for empty, preparing, or finalizing sessions; selection fills and focuses without sending. The composer applies adaptive sizing and the Return preference, while aCLOUD_AGENT_PROMPT_MAX_LENGTHcounter follows typing, restoration, insertion, and clearing.Files
apps/mobile/src/components/agents/chat-composer.tsx— wires keyboard-aware sizing, caret-aware newlines, starters, counters, reduced-motion overlays, and shared Text labels with normal font weight (M, Source, 156 lines).apps/mobile/src/components/agents/session-detail-content.tsx— prioritizes preparing and finalizing phases, forwardssessionState, and inlines the cancellation occupancy check (M, Source, 25 lines).apps/mobile/src/components/agents/chat-composer.test.ts— expands the composer test file (M, Test, 196 lines).NewSessionPromptComponentProps.onStartSessionlets Return use the existing Start flow when enabled, including the host's model, repository, profile, and voice-settlement gates. Empty prompts, active creation, failed attachments, and uploads block Return; hosts without the callback keep Return inert, and clone entry keeps no composer.NewSessionPromptControlsProps.childrenplaces the newline control beside voice controls without duplicating their layout.Files
apps/mobile/src/components/agents/new-session-prompt.tsx— adds adaptive sizing with a three-line minimum, starters, counters, gated Return, caret-aware newlines, shared Text labels, and the photo-metadata warning (M, Source, 208 lines).apps/mobile/src/components/agents/new-session-configure-form.tsx— forwardsonStartSessiononly when the Start action is enabled (M, Source, 1 line).apps/mobile/src/components/agents/new-session-prompt-controls.tsx— accepts optional children between the listening status and voice button (M, Source, 4 lines).apps/mobile/src/components/agents/new-session-prompt-initial-prompt.test.ts— expands the initial-prompt test file (M, Test, 157 lines).handleKeyboardShowfollows the newest message through the existing guarded scroll scheduler. Manual scrolling and scrolled-up reading keep their existing guards. iOS useskeyboardWillShowandkeyboardDidShow; Android useskeyboardDidShow, and unmount removes the listeners.Files
apps/mobile/src/components/agents/use-session-list-auto-scroll.ts— exposes the keyboard callback through the follow, user-scroll, and programmatic-scroll guards (M, Source, 9 lines).apps/mobile/src/components/agents/session-message-list.tsx— registers and removes the platform-specific keyboard listeners (M, Source, 31 lines).apps/mobile/src/components/agents/session-message-list.mounted.test.tsx— updates the mounted transcript test file (M, Test, 3 lines).MotionPolicy.reducedMotionexposes the system setting, andselectReducedMotionEntranceremoves optional animation builders when that setting is on. Composer toolbar and slash suggestions then appear and disappear immediately;scrollAnimatedretains its current behavior.Files
apps/mobile/src/lib/a11y/motion.ts— exposes the reduced-motion flag and adds the optional animation selector (M, Source, 15 lines).The new
preferences.returnSendsMessageandpreferences.returnSendsMessageSubtitlelabels explain the default-off Return choice.agentChat.composeraddscharactersRemaining,insertNewline,starterChipBuild,starterChipFix,starterChipWriteTests,starterChipPrepare,starterChipWrapUp, andstarterChipEmpty. The translation landing supplies 860 values across 86 non-English catalogs without changing existing text, key order, or the{{count}}placeholder.Files
apps/mobile/src/i18n/locales/en.json— defines eight composer labels and two Return preference labels (M, Source, 12 lines).apps/mobile/src/i18n/locales/af.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/am.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ar.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/az.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/be.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/bg.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/bn.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/bs.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ca.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ckb.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/cs.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/cy.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/da.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/de.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/el.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/es.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/et.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/eu.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/fa.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/fi.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/fil.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/fr.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ga.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/gl.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/gu.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ha.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/he.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/hi.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/hr.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ht.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/hu.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/hy.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/id.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ig.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/is.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/it.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ja.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ka.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/kk.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/km.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/kn.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ko.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/lo.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/lt.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/lv.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/mg.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/mi.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/mk.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ml.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/mn.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/mr.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ms.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/mt.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/my.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/nb.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ne.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/nl.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/om.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/or.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/pa.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/pl.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ps.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/pt-BR.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/pt.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ro.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ru.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/si.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/sk.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/sl.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/so.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/sq.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/sr.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/sv.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/sw.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ta.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/te.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/th.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/tr.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/uk.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/ur.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/uz.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/vi.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/yo.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/zh-Hans.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/zh-Hant.json— merges ten prepared translations (M, Generated, 14 lines).apps/mobile/src/i18n/locales/zu.json— merges ten prepared translations (M, Generated, 14 lines).Tests: 8 test files updated, totaling 661 changed lines: attachment send, input height, input row, composer, initial prompt, transcript, preferences, and upload.
Generated: 86 non-English locale catalogs updated, totaling 1,204 changed lines; each named catalog contains ten prepared additions for this level.
Visual Changes
Cloud Agent session composer, iOS
The user now sees the empty composer with three starter chips above the message field, and the attach, mic, and send controls beside it. In the picture, that new composer is the bottom band: the chips "Build a feature", "Fix a bug", and "Write tests" sit above the "Message..." field, with the clip at its left and the mic and send at its right.
Cloud Agent session composer, Android
The round-1 report says the user sees the same composer with the message field, starter chips, attach, mic, and send controls. No picture shows it. The three candidate frames for this screen are fully black; they fail to show the composer, the two-line newline draft, and the sent user row.
Verification
Nine cases ran to a result on iOS, Android, and the backend; two voice cases did not run because neither device can start dictation.
includeCloudAgentSessions:trueflag. The corrected query passed in round 2; the defect does not reproduce.Recording: none.
Reviewer Notes
Human steps
No additional setup is required after merge; this level adds no migration, environment value, secret, or deployment flag.
Verification limits
Automated evidence
The handoff records these results; this description refresh runs no product tests.
Description scope
/Users/igor/Projects/.worktrees/agent-composers-c07a—Kilo-Org/cloud, branchagent-composers-c07a-s6.ba3b08b933c5b2079439c199194f9d022f506429to52c33872b87e52d2be13dad849c1da52182bdd42; the changelogs cover only this level./Users/igor/Projects/.worktrees/agent-composers-c07a-kilocode—Kilo-Org/kilocode, branchagent-composers-c07a; it contributes no files to this description.Notes
Current-head CI and Kilobot approve all seven PRs. Existing E2E images precede later extraction, translation, and shared-Text repairs.
Stacked PRs — merge bottom to top. Each level shows only its own diff.
Runtime verification (E2E, user advocacy, simplify) runs on the tip PR over every level.
Every level keeps its own checks, its own bot review, and its own threads; each one is answered on its own PR.
Each level is its own deliverable: it builds and passes its own checks alone.
A finding on a level is repaired on that level, then carried upward with stack.sh forward.
agent-composers-c07a— feat(agent-composer): add message identity and queue cancel APIs #5537agent-composers-c07a-s2— feat(mobile): pre-upload attachments and release abandoned files #5538agent-composers-c07a-s3— feat(mobile): reorder composer attachments with drag and a11y moves #5540agent-composers-c07a-s4— feat(agent-composer): render sent messages immediately and cancel queued ones #5589agent-composers-c07a-s5— feat(mobile): keep agent composers editable during live dictation #5607agent-composers-c07a-s6— feat(mobile): adapt agent composers for keyboard, height, and preferences #5617 ← this PR (tip)