Skip to content

feat(mobile): add sandbox type selection to new cloud agent sessions - #6202

Merged
iscekic merged 1 commit into
mainfrom
kwf/sandbox-type-on-new-session-9b29
Sep 18, 2026
Merged

iscekic merged 1 commit into
mainfrom
kwf/sandbox-type-on-new-session-9b29

Conversation

@iscekic

@iscekic iscekic commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

Changelog for users

  • The new session page offers a Sandbox field for Cloud Agent sessions, beside the other cloud options.
  • The field starts on the backend's own default destination until a type is picked.
  • Tapping the field opens a sheet listing exactly the sandbox types the backend offers, grouped by provider.
  • Picking a type checks its row, closes the sheet, and shows it in the field, for example "Cloudflare · Shared".
  • While the options load, a field-sized skeleton holds the slot; a failed load shows "Couldn't load sandbox options" with Retry.
  • A pick the backend no longer offers shows an inline reason and a one-tap Use Default, and blocks Start until resolved.
  • Starting a session sends the picked type; nothing picked applies the backend's default.
  • Owners without sandbox selection see no Sandbox field, and the other cloud options are unchanged.

Changelog for maintainers

  • Mobile derives every sandbox type from the cloudAgentNext.getSandboxSelectionOptions tRPC result; no type is hardcoded, so review sandbox-allocation-label.ts first.
  • The backend procedure pre-exists and is unchanged; the client renders exactly the returned options and default.
  • A new sandboxPickerSlot bridge carries the backend snapshot into the agent-chat/sandbox-picker formSheet.
  • The picker re-queries the same capabilities key for its route scope, so its list stays fresh and a failure has Retry; onSelect(undefined) is the backend default row.
  • The screen body owns the pick, which resets with the organization scope; only a settled unavailable verdict blocks Start.
  • The creator adds sandboxAllocation to the create body only when set and folds it into the operation key, so a changed pick forks a new intent.
  • The section hides for remote targets and disabled capabilities; loading reserves the field's box so the resolved field replaces it in place.
  • New agentChat.newSession.* keys were added to the English and translated catalogs, with Cloudflare and Vercel allowlisted as brand names.

E2E proof

[e1] New session page can pick the cloud agent sandbox type on android (emulator-5554) — Android emulator-5554, live: the new-session Sandbox field starts on the backend default (android.widget.Button Sandbox: Default · Cloudflare · Small tappable [37,1882][1043,1998], e1-sheet-live.log line 31), tapping it opens a sheet whose only rows are content-desc="Default · Cloudflare · Small", content-desc="Cloudflare · Small" and content-desc="Cloudflare · Shared" under text="CLOUDFLARE" (e1-sheet-open.xml), and picking Cloudflare · Shared closes the sheet and moves the field to content-desc="Sandbox: Cloudflare · Shared" (e1-field-shared.xml), the scripted flow's final…

[e1] New session page can pick the cloud agent sandbox type on android (emulator-5554) — e2e-mobile-app/e1.png

[e1] New session page can pick the cloud agent sandbox type on android (emulator -> pass :: Android emulator-5554, live: the new-session Sandbox field starts on the backend default (`android.widget.Button Sandbox: Default · Cloudflare · Small tappable [37,1882][1043,1998]`, e1-sheet-live.log line 31), tapping it opens a sheet whose only rows are `content-desc="Default · Cloudflare · Small"`, `content-desc="Cloudflare · Small"` and `content-desc="Cloudflare · Shared"` under `text="CLOUDFLARE"` (e1-sheet-open.xml), and picking Cloudflare · Shared closes the sheet and moves the field to `content-desc="Sandbox: Cloudflare · Shared"` (e1-field-shared.xml), the scripted flow's final digest being `android.widget.Button Sandbox: Cloudflare · Shared tappable [37,1882][1043,1998]` (e1-scene-

Follow-ups (not changed here)

Open findings (not fixed here)

  • the next round (.kwf-keep-device)
    mobile-device: verifier passed
    mobile-device: spot skips 22 still(s) of missed scripted scene(s)
    mobile-device: spot check clean
    mobile-device: signed-in app data restored on emulator-5554
    mobile-device: signed-in app data frozen on emulator-5554 (66008064 bytes)
  • the '## E2E proof' section carries no log excerpt, so nothing shows the change was driven end to end

e1

@iscekic
iscekic marked this pull request as draft September 16, 2026 07:06
@kilo-code-bot

kilo-code-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • apps/mobile/src/lib/hooks/use-sandbox-selection.ts
  • apps/mobile/src/lib/hooks/use-sandbox-selection.test.ts
Previous Review Summaries (6 snapshots, latest commit a99b21e)

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

Previous review (commit a99b21e)

Status: 1 Issues Found | Recommendation: Address before merge

Executive Summary

A failed background refetch of the sandbox capabilities is classified as a hard error even while cached options exist, which blanks the already-resolved Sandbox field and its recovery and clears the Start gate that blocks a known-invalid pick.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/lib/hooks/use-sandbox-selection.ts 55 status: 'error' is set on any isError without checking cached data, so a failed background refetch hides loaded sandbox options and their recovery.
Files Reviewed (109 files)
  • apps/mobile/src/app/(app)/_layout.tsx
  • apps/mobile/src/app/(app)/agent-chat/sandbox-picker.mounted.test.tsx
  • apps/mobile/src/app/(app)/agent-chat/sandbox-picker.tsx
  • apps/mobile/src/components/agents/new-session-configure-form.test.ts
  • apps/mobile/src/components/agents/new-session-configure-form.tsx
  • apps/mobile/src/components/agents/new-session-sandbox-section.tsx
  • apps/mobile/src/components/agents/new-session-screen-body.tsx
  • apps/mobile/src/components/agents/sandbox-selector.mounted.test.tsx
  • apps/mobile/src/components/agents/sandbox-selector.tsx
  • apps/mobile/src/components/agents/use-new-session-creator.test.ts
  • apps/mobile/src/components/agents/use-new-session-creator.ts
  • apps/mobile/src/lib/app-actions/prepare-agent-session.ts
  • apps/mobile/src/lib/hooks/use-sandbox-selection.test.ts
  • apps/mobile/src/lib/hooks/use-sandbox-selection.ts - 1 issue
  • apps/mobile/src/lib/new-session-submit.test.ts
  • apps/mobile/src/lib/new-session-submit.ts
  • apps/mobile/src/lib/picker-bridge.ts
  • apps/mobile/src/lib/route-registry.test.ts
  • apps/mobile/src/lib/route-registry.ts
  • apps/mobile/src/lib/sandbox-allocation-label.test.ts
  • apps/mobile/src/lib/sandbox-allocation-label.ts
  • apps/mobile/src/i18n/locales/*.json (87 catalogs)
  • tools/i18n/check-catalogs.mjs

Fix these issues in Kilo Cloud

Previous review (commit cd19a8e)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • apps/mobile/src/components/agents/use-new-session-creator.ts
  • apps/mobile/src/components/agents/use-new-session-creator.test.ts

Previous review (commit 1e70dc9)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/components/agents/use-new-session-creator.ts 185 Adding sandboxAllocation to the scoped intent fingerprint changes the pick-less fingerprint bytes, so exact-match safe-retry rows written by the previous app version are not found; the bare-name fallback does not cover the object-repo shape, so a pick-less relaunch retry mints a new key and can duplicate an already-admitted session.
Files Reviewed (3 files)
  • apps/mobile/src/components/agents/use-new-session-creator.ts - 1 issue
  • apps/mobile/src/components/agents/use-new-session-creator.test.ts
  • apps/mobile/src/lib/hooks/use-sandbox-selection.test.ts

Fix these issues in Kilo Cloud

Previous review (commit 61616a6)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/components/agents/use-new-session-creator.ts 174 The sandbox pick is added to the scoped retry fingerprint but omitted from legacyIntentFingerprint; the GitHub legacy fallback can reuse a pre-sandbox operation key while submitting a pick, which the server rejects as a terminal BAD_REQUEST (and the dropped key can duplicate an already-admitted session).

SUGGESTION

File Line Issue
apps/mobile/src/lib/hooks/use-sandbox-selection.test.ts 109 expect(allocationEffect).not.toBeNull() can never fail (undefined, not null); assert toBeDefined().
Files Reviewed (108 files)
  • apps/mobile/src/app/(app)/_layout.tsx
  • apps/mobile/src/app/(app)/agent-chat/sandbox-picker.tsx - new
  • apps/mobile/src/app/(app)/agent-chat/sandbox-picker.mounted.test.tsx - new
  • apps/mobile/src/components/agents/new-session-configure-form.tsx
  • apps/mobile/src/components/agents/new-session-configure-form.test.ts - new
  • apps/mobile/src/components/agents/new-session-sandbox-section.tsx - new
  • apps/mobile/src/components/agents/new-session-screen-body.tsx
  • apps/mobile/src/components/agents/sandbox-selector.tsx - new
  • apps/mobile/src/components/agents/sandbox-selector.mounted.test.tsx - new
  • apps/mobile/src/components/agents/use-new-session-creator.ts - 1 issue
  • apps/mobile/src/components/agents/use-new-session-creator.test.ts - new
  • apps/mobile/src/lib/hooks/use-sandbox-selection.ts - new
  • apps/mobile/src/lib/hooks/use-sandbox-selection.test.ts - 1 issue
  • apps/mobile/src/lib/new-session-submit.ts
  • apps/mobile/src/lib/new-session-submit.test.ts
  • apps/mobile/src/lib/picker-bridge.ts
  • apps/mobile/src/lib/route-registry.ts
  • apps/mobile/src/lib/route-registry.test.ts
  • apps/mobile/src/lib/sandbox-allocation-label.ts - new
  • apps/mobile/src/lib/sandbox-allocation-label.test.ts - new
  • tools/i18n/check-catalogs.mjs
  • apps/mobile/src/i18n/locales/*.json (87 catalogs)

Fix these issues in Kilo Cloud

Previous review (commit 83fe92b)

Status: No Issues Found | Recommendation: Merge

Reviewed the incremental change since ab12677 (two files): the explanatory comment in the picker route and the new iOS/Android parity test. Both are non-functional additions; the haptics call path, row rendering, bridge clear, and dismissal are unchanged and still covered by the existing tests. No new high-confidence bugs, security issues, or leaks were found.

Files Reviewed (2 files)
  • apps/mobile/src/app/(app)/agent-chat/sandbox-picker.tsx
  • apps/mobile/src/app/(app)/agent-chat/sandbox-picker.mounted.test.tsx

Previous review (commit ab12677)

Status: No Issues Found | Recommendation: Merge

Executive Summary

I reviewed the full sandbox-type selection feature in apps/mobile (labelled state module, hook, selector, picker sheet, form section, screen wiring, create-request plumbing, route registration, and the i18n additions) and found no high-confidence bugs, security issues, or leaks.

Notes (verified, not defects)

  • sandboxPickerSlot is cleared on select and again by useRouteRegistry(UNFENCED_ROUTE_KEY) on picker unmount, matching the existing branch-picker/repo-picker pattern, so the bridge does not leak across visits.
  • User types are derived from the cloudAgentNext.getSandboxSelectionOptions tRPC result (inferRouterOutputs), and the structured SandboxAllocation sent in prepareSession matches selectableSandboxAllocationInputSchema; nothing is hardcoded.
  • New agentChat.newSession.* keys are referenced from non-test source, have matching {{destination}}/{{label}} placeholders in all 87 catalogs, and the new English copy has no duplicate-copy or wording-group collisions. Cloudflare/Vercel are correctly allowlisted.
  • Start gating only blocks on a settled ready verdict; loading/error keeps Start enabled, matching the stated server-arbitration intent, and the remote run-target path short-circuits before the sandbox gate.
Files Reviewed (108 files)
  • apps/mobile/src/app/(app)/_layout.tsx
  • apps/mobile/src/app/(app)/agent-chat/sandbox-picker.tsx
  • apps/mobile/src/app/(app)/agent-chat/sandbox-picker.mounted.test.tsx
  • apps/mobile/src/components/agents/new-session-configure-form.tsx
  • apps/mobile/src/components/agents/new-session-configure-form.test.ts
  • apps/mobile/src/components/agents/new-session-sandbox-section.tsx
  • apps/mobile/src/components/agents/new-session-screen-body.tsx
  • apps/mobile/src/components/agents/sandbox-selector.tsx
  • apps/mobile/src/components/agents/sandbox-selector.mounted.test.tsx
  • apps/mobile/src/components/agents/use-new-session-creator.ts
  • apps/mobile/src/components/agents/use-new-session-creator.test.ts
  • apps/mobile/src/lib/hooks/use-sandbox-selection.ts
  • apps/mobile/src/lib/hooks/use-sandbox-selection.test.ts
  • apps/mobile/src/lib/new-session-submit.ts
  • apps/mobile/src/lib/new-session-submit.test.ts
  • apps/mobile/src/lib/picker-bridge.ts
  • apps/mobile/src/lib/route-registry.ts
  • apps/mobile/src/lib/route-registry.test.ts
  • apps/mobile/src/lib/sandbox-allocation-label.ts
  • apps/mobile/src/lib/sandbox-allocation-label.test.ts
  • tools/i18n/check-catalogs.mjs
  • apps/mobile/src/i18n/locales/*.json (87 catalogs)

Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

@iscekic

iscekic commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Cross-platform fix. Pushed e07d92a (kwf kwf-fix-platform-c937).

What changed:

  • apps/mobile/src/lib/sandbox-allocation-label.ts derives every type from the cloudAgentNext.getSandboxSelectionOptions tRPC result, so no sandbox type is hardcoded; review this first.
  • The closed field (sandbox-selector.tsx) opens the agent-chat/sandbox-picker formSheet through a new sandboxPickerSlot bridge registered beside the other formSheets; the picker re-queries the same capabilities key, offers Retry, and treats onSelect(undefined) as the backend default row.
  • The pick is owned by new-session-screen-body.tsx and resets when the organization scope changes; a settled verdict that the pick is unavailable blocks Start, while loading or errored capabilities lets the server arbitrate.
  • The create request omits sandboxAllocation when nothing is picked, and the pick is part of the create operation key, so changing it forks a new intent while an unchanged retry reuses the key.
  • The section hides for remote run targets and disabled capabilities; risk to check is the bridge slot's expired state and the reserved loading-slot height.
  • New agentChat.newSession.* keys are added to English and every translated catalog, with Cloudflare and Vercel allowlisted as brand names in the catalog check.
  • apps/mobile/src/app/(app)/agent-chat/sandbox-picker.tsx:2 — rejected as a platform fork: the expo-haptics import is the app's cross-platform haptics library and this route has no Platform branch.
  • The pick route names the shared haptics capability in a code comment, and a mounted parity test compares both platforms' rows, checked row, haptic, and dismissal so a re-added branch fails.

@iscekic
iscekic force-pushed the kwf/sandbox-type-on-new-session-9b29 branch from e07d92a to 83fe92b Compare September 16, 2026 08:07
@iscekic
iscekic marked this pull request as ready for review September 16, 2026 08:17
@iscekic
iscekic marked this pull request as draft September 16, 2026 18:35
@iscekic
iscekic force-pushed the kwf/sandbox-type-on-new-session-9b29 branch 6 times, most recently from e05cfdb to 61616a6 Compare September 17, 2026 01:16
@iscekic
iscekic marked this pull request as ready for review September 17, 2026 01:26
@iscekic
iscekic marked this pull request as draft September 17, 2026 01:28
Comment thread apps/mobile/src/components/agents/use-new-session-creator.ts Outdated
Comment thread apps/mobile/src/lib/hooks/use-sandbox-selection.test.ts Outdated
@iscekic
iscekic force-pushed the kwf/sandbox-type-on-new-session-9b29 branch 13 times, most recently from 1f1525b to f93cad5 Compare September 17, 2026 03:46
@iscekic
iscekic force-pushed the kwf/sandbox-type-on-new-session-9b29 branch 2 times, most recently from f86b9b4 to aaf1f22 Compare September 17, 2026 08:55
@iscekic
iscekic force-pushed the kwf/sandbox-type-on-new-session-9b29 branch from aaf1f22 to 1e70dc9 Compare September 17, 2026 09:33
@iscekic
iscekic marked this pull request as ready for review September 17, 2026 09:43
Comment thread apps/mobile/src/components/agents/use-new-session-creator.ts Outdated
@iscekic
iscekic marked this pull request as draft September 17, 2026 09:52
@iscekic
iscekic force-pushed the kwf/sandbox-type-on-new-session-9b29 branch from 1e70dc9 to cd19a8e Compare September 17, 2026 10:13
@iscekic
iscekic marked this pull request as ready for review September 17, 2026 10:23
@iscekic
iscekic marked this pull request as draft September 17, 2026 14:49
@iscekic
iscekic force-pushed the kwf/sandbox-type-on-new-session-9b29 branch from ba679e7 to a99b21e Compare September 17, 2026 17:01
@iscekic
iscekic marked this pull request as ready for review September 17, 2026 17:21
Comment thread apps/mobile/src/lib/hooks/use-sandbox-selection.ts Outdated
@iscekic
iscekic marked this pull request as draft September 17, 2026 17:52
@iscekic
iscekic force-pushed the kwf/sandbox-type-on-new-session-9b29 branch from 01080a6 to a159425 Compare September 17, 2026 18:33
@iscekic
iscekic marked this pull request as ready for review September 17, 2026 18:49
@iscekic
iscekic requested a review from eshurakov September 17, 2026 19:19
@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 17, 2026
@iscekic
iscekic requested a review from pandemicsyn September 17, 2026 19:19
@iscekic iscekic self-assigned this Sep 17, 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