From 7873c58f4aab1f262816ff2c060801fe87fde95a Mon Sep 17 00:00:00 2001 From: Jinwoo-H Date: Sun, 11 Oct 2026 01:52:32 -0400 Subject: [PATCH] refactor(mobile): read only the rows of a server's workspace list The desktop no longer sends a freshness flag, so the phone's schema drops it. The relay capability list names the delegated-devices constant instead of repeating its literal, which also retires a now-circular type check. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb --- mobile/src/files/MobileFilePreviewScreen.tsx | 1 + .../src/host-screen/host-server-workspaces-wiring.test.ts | 6 +++--- mobile/src/worktree/server-workspace-operations.ts | 5 +---- src/shared/delegated-mobile-device-contract.ts | 5 ++--- src/shared/mobile-desktop-relay-contract.ts | 4 +++- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/mobile/src/files/MobileFilePreviewScreen.tsx b/mobile/src/files/MobileFilePreviewScreen.tsx index 05221697aad..e71da8e2833 100644 --- a/mobile/src/files/MobileFilePreviewScreen.tsx +++ b/mobile/src/files/MobileFilePreviewScreen.tsx @@ -36,6 +36,7 @@ type Props = { } export function MobileFilePreviewScreen({ route }: Props) { + // Why: every workspace screen uses the handoff so it shares the route chunk; else the bundle overruns its asset budget. const router = useWorkspaceRouteHandoff() const previewParams = route.ok ? route.params : null const { client, state: connState } = useWorkspaceClient(previewParams?.hostId) diff --git a/mobile/src/host-screen/host-server-workspaces-wiring.test.ts b/mobile/src/host-screen/host-server-workspaces-wiring.test.ts index 791d19e1859..2111f70d70c 100644 --- a/mobile/src/host-screen/host-server-workspaces-wiring.test.ts +++ b/mobile/src/host-screen/host-server-workspaces-wiring.test.ts @@ -76,7 +76,7 @@ function desktop({ hostWorktrees, carriesExecutionHost }: Desktop = {}): FakeSes const { hostId } = z.object({ hostId: z.string() }).parse(params) const result = hostWorktrees ? hostWorktrees(hostId) - : { worktrees: [row(`${hostId}-wt`, hostId)], stale: false, fetchedAt: 1 } + : { worktrees: [row(`${hostId}-wt`, hostId)] } if (result instanceof Error) { throw result } @@ -244,7 +244,7 @@ describe("a desktop's server workspaces on the phone", () => { hostWorktrees: (hostId) => failing && hostId === 'runtime:vm' ? new Error('timed out') - : { worktrees: [row(`${hostId}-wt`, hostId)], stale: false, fetchedAt: 1 } + : { worktrees: [row(`${hostId}-wt`, hostId)] } }) const screen = await mountScreen(client, RELAYS) failing = true @@ -255,7 +255,7 @@ describe("a desktop's server workspaces on the phone", () => { method === 'mobileRelay.hosts.list' ? reply({ hosts: [HOSTS[1]] }) : method === 'mobileRelay.hosts.worktrees' - ? reply({ worktrees: [row('stray', 'runtime:vm')], stale: true, fetchedAt: 1 }) + ? reply({ worktrees: [row('stray', 'runtime:vm')] }) : reply({ worktrees: [row('mac-wt', 'local')], snapshotId: 's1' }) ) await screen.poll() diff --git a/mobile/src/worktree/server-workspace-operations.ts b/mobile/src/worktree/server-workspace-operations.ts index 71f76fa84c6..cbb0efa5c9f 100644 --- a/mobile/src/worktree/server-workspace-operations.ts +++ b/mobile/src/worktree/server-workspace-operations.ts @@ -64,10 +64,7 @@ export const relayHostWorktreesRead = bindDeferredRpcOperation( barrier: 'after-caller-barrier', read: rpcResultVariant( 'relay-host-worktrees', - z.looseObject({ - worktrees: z.array(z.unknown()).nullable(), - stale: z.boolean().optional() - }) + z.looseObject({ worktrees: z.array(z.unknown()).nullable() }) ) }) ) diff --git a/src/shared/delegated-mobile-device-contract.ts b/src/shared/delegated-mobile-device-contract.ts index ec248eda586..b33e426512e 100644 --- a/src/shared/delegated-mobile-device-contract.ts +++ b/src/shared/delegated-mobile-device-contract.ts @@ -1,11 +1,10 @@ import { z } from 'zod' -import type { RUNTIME_CAPABILITIES } from './protocol-version' // Why: a paired desktop relays each of its phones to this host as an ordinary phone device it owns. export const DELEGATED_MOBILE_DEVICE_SYNC_METHOD = 'pairing.delegatedMobileDevice.sync' -// Why: a desktop relays phones only to a host advertising this; `satisfies` ties it to RUNTIME_CAPABILITIES. +// Why: a desktop relays phones only to a host advertising this (via MOBILE_RELAY_RUNTIME_CAPABILITIES). export const DELEGATED_MOBILE_DEVICES_RUNTIME_CAPABILITY = - 'pairing.delegated-mobile-devices.v1' satisfies (typeof RUNTIME_CAPABILITIES)[number] + 'pairing.delegated-mobile-devices.v1' as const export const DELEGATED_MOBILE_DEVICE_SYNC_MAX_PHONES = 32 export const DELEGATED_PHONE_NAME_MAX_CHARS = 128 diff --git a/src/shared/mobile-desktop-relay-contract.ts b/src/shared/mobile-desktop-relay-contract.ts index b3b692224f2..7a028becc64 100644 --- a/src/shared/mobile-desktop-relay-contract.ts +++ b/src/shared/mobile-desktop-relay-contract.ts @@ -1,9 +1,11 @@ +import { DELEGATED_MOBILE_DEVICES_RUNTIME_CAPABILITY } from './delegated-mobile-device-contract' + // Why: a phone may put `executionHost` on a request only after its desktop advertises this; an older // desktop ignores the field and would run the call on itself. export const MOBILE_DESKTOP_RELAY_RUNTIME_CAPABILITY = 'mobile.desktop-relay.v1' as const /** A desktop relays a phone to a server that mints delegated phone devices; each side advertises. */ export const MOBILE_RELAY_RUNTIME_CAPABILITIES = [ - 'pairing.delegated-mobile-devices.v1', + DELEGATED_MOBILE_DEVICES_RUNTIME_CAPABILITY, MOBILE_DESKTOP_RELAY_RUNTIME_CAPABILITY ] as const