From 92e679f5872016af58b3fe809b952bceeb23311e Mon Sep 17 00:00:00 2001 From: Jinwoo-H Date: Mon, 14 Sep 2026 21:18:14 -0400 Subject: [PATCH] refactor(mobile): reach the narrow port type without naming the port module The previous commit named `UnvalidatedRpcRequestPort` by importing the port module, and that fails the boundary ratchet: it counts an import of `unvalidated-rpc-request-port` as reach, so all six unlisted files became offenders and the history panel went from 1 reference to 2. Main's `Pick` fails it for the same reason, by a different rule: a bare `'sendRequest'` string literal is counted too. That is why the migration widened these signatures in the first place, so the review finding's premise that it was done for no cause is wrong. Only the full `RpcClient` scored zero. Re-export the port type from `rpc-client` instead. An export declaration with no module specifier is not counted, the seven signatures still say they need one sender rather than a whole client, and the inventory does not move. Holding a client already carries the same reach, so nothing new is opened. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb --- mobile/src/agent-history/MobileAgentSessionHistoryPanel.tsx | 2 +- mobile/src/dictation/mobile-dictation-setup.ts | 2 +- mobile/src/notifications/push-registration.ts | 2 +- mobile/src/settings/native-voice-settings-operations.ts | 2 +- mobile/src/terminal/mobile-terminal-query-reply.ts | 2 +- mobile/src/terminal/terminal-live-accessory-raw-send.ts | 2 +- mobile/src/terminal/worker-terminal-takeover-report.ts | 2 +- mobile/src/transport/rpc-client.ts | 3 +++ 8 files changed, 10 insertions(+), 7 deletions(-) diff --git a/mobile/src/agent-history/MobileAgentSessionHistoryPanel.tsx b/mobile/src/agent-history/MobileAgentSessionHistoryPanel.tsx index fbe1648fc90..42110d824f0 100644 --- a/mobile/src/agent-history/MobileAgentSessionHistoryPanel.tsx +++ b/mobile/src/agent-history/MobileAgentSessionHistoryPanel.tsx @@ -16,7 +16,7 @@ import { ChevronLeft, RefreshCw } from 'lucide-react-native' import { colors } from '../theme/mobile-theme' import { useHostClient } from '../transport/client-context' import type { RpcSuccess } from '../transport/types' -import type { UnvalidatedRpcRequestPort } from '../transport/unvalidated-rpc-request-port' +import type { UnvalidatedRpcRequestPort } from '../transport/rpc-client' import { readMobileRuntimeHostPlatform } from '../transport/mobile-runtime-host-platform' import { getWorktreeLabel } from '../session/worktree-label' import { diff --git a/mobile/src/dictation/mobile-dictation-setup.ts b/mobile/src/dictation/mobile-dictation-setup.ts index c9104f82bd7..3658526b65e 100644 --- a/mobile/src/dictation/mobile-dictation-setup.ts +++ b/mobile/src/dictation/mobile-dictation-setup.ts @@ -1,5 +1,5 @@ import type { RuntimeSpeechSetupState } from '../../../src/shared/runtime-types' -import type { UnvalidatedRpcRequestPort } from '../transport/unvalidated-rpc-request-port' +import type { UnvalidatedRpcRequestPort } from '../transport/rpc-client' import type { RpcResponse } from '../transport/types' import { interpretOrThrowRefusalMessage } from '../transport/rpc-refusal-message' import { LogicalClientCutoverError } from '../transport/stable-logical-rpc-client' diff --git a/mobile/src/notifications/push-registration.ts b/mobile/src/notifications/push-registration.ts index 8aac71108b9..aa6a0d9d8ca 100644 --- a/mobile/src/notifications/push-registration.ts +++ b/mobile/src/notifications/push-registration.ts @@ -13,7 +13,7 @@ import type { MobilePushRegisterResult } from '../../../src/shared/mobile-push-contract' import { NOTIFICATIONS_REMOTE_PUSH_RUNTIME_CAPABILITY } from '../../../src/shared/protocol-version' -import type { UnvalidatedRpcRequestPort } from '../transport/unvalidated-rpc-request-port' +import type { UnvalidatedRpcRequestPort } from '../transport/rpc-client' import { startRuntimeCapabilityProbe } from '../transport/runtime-capability-probe' import { pushRouteRegister, pushRouteUnregister } from './mobile-push-registration-operations' import { diff --git a/mobile/src/settings/native-voice-settings-operations.ts b/mobile/src/settings/native-voice-settings-operations.ts index 002203f2916..534340f0440 100644 --- a/mobile/src/settings/native-voice-settings-operations.ts +++ b/mobile/src/settings/native-voice-settings-operations.ts @@ -1,4 +1,4 @@ -import type { UnvalidatedRpcRequestPort } from '../transport/unvalidated-rpc-request-port' +import type { UnvalidatedRpcRequestPort } from '../transport/rpc-client' import { fetchDictationSetup, setDictationConfig, diff --git a/mobile/src/terminal/mobile-terminal-query-reply.ts b/mobile/src/terminal/mobile-terminal-query-reply.ts index 2282082c2da..59dc3e47e04 100644 --- a/mobile/src/terminal/mobile-terminal-query-reply.ts +++ b/mobile/src/terminal/mobile-terminal-query-reply.ts @@ -1,5 +1,5 @@ import { isTerminalQueryReply } from '../../../src/shared/terminal-query-reply' -import type { UnvalidatedRpcRequestPort } from '../transport/unvalidated-rpc-request-port' +import type { UnvalidatedRpcRequestPort } from '../transport/rpc-client' import { terminalInputSend } from './mobile-terminal-operations' type TerminalSubscriptionRegistry = { diff --git a/mobile/src/terminal/terminal-live-accessory-raw-send.ts b/mobile/src/terminal/terminal-live-accessory-raw-send.ts index aed0074e10b..cd24a3443f1 100644 --- a/mobile/src/terminal/terminal-live-accessory-raw-send.ts +++ b/mobile/src/terminal/terminal-live-accessory-raw-send.ts @@ -2,7 +2,7 @@ import { reportWorkerTerminalUserInput } from './worker-terminal-takeover-report import { getTerminalLiveAccessoryRawSendTarget } from './terminal-live-accessory-raw-send-target' import { buildTerminalSendParams, TERMINAL_INPUT_SEND_OPTIONS } from './terminal-send-request' import { terminalInputSend } from './mobile-terminal-operations' -import type { UnvalidatedRpcRequestPort } from '../transport/unvalidated-rpc-request-port' +import type { UnvalidatedRpcRequestPort } from '../transport/rpc-client' import type { ConnectionState } from '../transport/types' type TerminalLiveAccessoryRawSendArgs = { diff --git a/mobile/src/terminal/worker-terminal-takeover-report.ts b/mobile/src/terminal/worker-terminal-takeover-report.ts index cc6579ae48a..e60a19f6415 100644 --- a/mobile/src/terminal/worker-terminal-takeover-report.ts +++ b/mobile/src/terminal/worker-terminal-takeover-report.ts @@ -1,4 +1,4 @@ -import type { UnvalidatedRpcRequestPort } from '../transport/unvalidated-rpc-request-port' +import type { UnvalidatedRpcRequestPort } from '../transport/rpc-client' import { workerTerminalTakeoverReport } from './mobile-terminal-operations' type ReportClient = UnvalidatedRpcRequestPort diff --git a/mobile/src/transport/rpc-client.ts b/mobile/src/transport/rpc-client.ts index 05fdbbac8fa..bb2a2c3169e 100644 --- a/mobile/src/transport/rpc-client.ts +++ b/mobile/src/transport/rpc-client.ts @@ -6,6 +6,9 @@ import type { UnvalidatedRpcRequestPort } from './unvalidated-rpc-request-port' // Re-export shim: the options type moved to the port module with the sender it belongs to, // and re-exporting is what keeps that move from touching every importer. export type { SendRequestOptions } from './unvalidated-rpc-request-port' +// Re-exported so a caller that only sends can say so without naming the port module, which the +// boundary ratchet counts as reach. Holding a client already carries the same ability. +export type { UnvalidatedRpcRequestPort } type SubscribeOptions = { onBinaryFrame?: (frame: BrowserScreencastFrame) => void