mirror of
https://github.com/stablyai/orca.git
synced 2026-11-01 01:27:35 +00:00
* fix(mobile): don't unsubscribe a terminal stream that already ended * fix(mobile): keep the stream registry under the line cap and expect no error after a streamed end The streamed `end` now closes a direct stream, so a later reply for that id is unrouted instead of reaching the listener as an error; the subscription recording test expected the old error. Inline the error wrapper so the registry fits the 300-line cap, and shorten the comments. * fix(mobile): reopen a native chat stream the host ended while the screen still shows it * fix(mobile): only the focused screen takes back a host-ended chat feed, and a reopen keeps loaded history * fix(mobile): give each native chat subscription its own token, and reopen with the first page * test(mobile): pin the reopened chat subscribe params without a cast * fix(mobile): show a host-ended chat feed as an error instead of reopening it With a token per subscription, the desktop ends a phone chat feed only when the phone closes it or the socket drops: no client sends the connection-wide chat unsubscribe, a socket close delivers no end, and every desktop with mobile chat keys feeds by the client's token. The reopen-with-backoff layer and the history-keeping reopen merge guarded a trigger that no longer exists, so they are removed. An end that still reaches the screen settles the feed as an error, so a dead feed is never shown as live; leaving and re-entering the chat subscribes again with a fresh token. * test(mobile): re-record the RPC goldens for the per-subscription chat token Each nativeChat.subscribe now sends its own token, so the native chat scenarios expect `claude:session-1:<id>` in the subscribe params, and the four native chat recordings (native-chat-page-earlier and the session.native-chat-page matrix) record that token in their subscribe and unsubscribe payloads. Every other golden moved only its `baseline` header, repinned to the commit recorded from. * test(mobile): repin RPC recordings to the merge with main and re-record Merging main moved the product tree the recordings are pinned to, so the baseline is repinned to the merge commit and the whole corpus re-recorded. Only the four native chat recordings change content, because each nativeChat.subscribe now carries a per-subscription token; every other recording moves only its baseline header. * test(mobile): repin RPC recordings to the merge with main and re-record Merging main brought #22762's recordings, #23757's repin and #23720's recorder change, so the corpus is repinned to the merge commit, the last commit to touch a recorded path, and re-recorded whole. Against main, 786 recordings move only their baseline header and 4 native chat recordings change content: their nativeChat.subscribe and nativeChat.unsubscribe carry the per-subscription token instead of claude:session-1, which also moves their scenarioSha256.
33 lines
1.3 KiB
TypeScript
33 lines
1.3 KiB
TypeScript
// Why: the runtime keys a native-chat transcript fs-watcher by the client's cleanup token
|
|
// (`agent:sessionId` when none is sent). A subscribing client must echo that exact token on
|
|
// `nativeChat.unsubscribe` so the watcher is closed when the chat view toggles off (not just on
|
|
// socket close) — otherwise watchers leak per session-switch. Centralizing the key shape keeps the
|
|
// token from drifting between the web runtime client and mobile.
|
|
|
|
export type NativeChatUnsubscribeRpc = {
|
|
method: 'nativeChat.unsubscribe'
|
|
params: { subscriptionId: string }
|
|
}
|
|
|
|
/** The cleanup token the server keys the transcript watcher under. An `instance` makes it one
|
|
* subscription's own, so two views of the same chat on one connection never evict each other. */
|
|
export function buildNativeChatSubscriptionId(
|
|
agent: string,
|
|
sessionId: string,
|
|
instance?: string
|
|
): string {
|
|
return instance ? `${agent}:${sessionId}:${instance}` : `${agent}:${sessionId}`
|
|
}
|
|
|
|
/** The unsubscribe RPC frame a client sends on teardown to close the watcher. */
|
|
export function buildNativeChatUnsubscribe(
|
|
agent: string,
|
|
sessionId: string,
|
|
subscriptionId?: string
|
|
): NativeChatUnsubscribeRpc {
|
|
return {
|
|
method: 'nativeChat.unsubscribe',
|
|
params: { subscriptionId: subscriptionId ?? buildNativeChatSubscriptionId(agent, sessionId) }
|
|
}
|
|
}
|