Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
403 commits
Select commit Hold shift + click to select a range
3b59187
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
b62a6f6
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
4bdb66e
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
d3b2e0e
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
53ec2f2
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
9ea0b8b
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
481fa68
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
ec981ed
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
b3348af
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
37305ab
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
f2176c3
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
3bb25e9
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
3704405
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
14ff6ef
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
a7ef887
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
6744d54
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
e630678
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
28261e5
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
5959fcb
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
b2b536b
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
2e34395
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
7c87584
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
1330506
Merge upstream main into resume completion deadline fix
JustYannicc Oct 25, 2026
a4e25c3
Merge upstream main into resume completion deadline fix
JustYannicc Oct 26, 2026
3f813e6
Merge upstream main into resume completion deadline fix
JustYannicc Oct 26, 2026
385ef66
Merge upstream main into resume completion deadline fix
JustYannicc Oct 26, 2026
9303ee6
Merge upstream main into resume completion deadline fix
JustYannicc Oct 26, 2026
4853553
Merge upstream main into resume completion deadline fix
JustYannicc Oct 26, 2026
b739900
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
fe89620
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
d48bedd
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
b948b8e
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
874a119
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
4c76218
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
05ef8f7
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
4406677
chore: merge upstream main and resolve sync test conflict
JustYannicc Oct 26, 2026
4de72ca
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
fb12ddf
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
a82e809
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
2762749
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
c7ec0c7
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
66d7b5b
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
59018e1
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
722ebc8
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
582b017
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
9b3f115
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
0f07217
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
4da6718
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
f2a0466
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
4d8d7d1
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
47ad3b5
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
ae574f9
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
cc4742a
chore: merge upstream main into resume recovery branch
JustYannicc Oct 26, 2026
475a0eb
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
704a5f1
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
46ccb18
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
a4e1966
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
98d9f45
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
1b708ac
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
56bc794
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
5669c88
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
143b43d
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
6d5799c
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
fe6f1fc
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
0f48504
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
7e7c4e7
chore: merge upstream main into resume completion fix
JustYannicc Oct 26, 2026
c956339
chore: merge upstream main into resume completion fix
JustYannicc Oct 27, 2026
cc78f15
chore: merge upstream main into resume completion fix
JustYannicc Oct 27, 2026
26269fe
chore: merge upstream main into resume completion fix
JustYannicc Oct 27, 2026
911cb56
chore: merge upstream main into resume completion fix
JustYannicc Oct 27, 2026
33ef1a2
chore: merge upstream main into resume completion fix
JustYannicc Oct 27, 2026
8e2e744
chore: merge upstream main into resume completion fix
JustYannicc Oct 27, 2026
60d43f2
chore: merge upstream main into resume completion fix
JustYannicc Oct 27, 2026
e6fb1cf
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
d861eab
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
8dd63c0
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
5cae5f1
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
19685cf
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
1b76935
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
ea26c48
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
792d322
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
94cb565
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
7c73072
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
af0e6d3
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
51e416a
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
3b9f5b3
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
868fabc
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
2490309
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
3b2f704
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
26dbb80
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
5554f2c
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
37b5247
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
988acd6
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
02f09ed
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
28cbc3b
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
0a5e4e2
Merge upstream main into fix/resume-completion-deadline-upstream
JustYannicc Oct 27, 2026
6a45820
chore: merge upstream main into resume recovery
JustYannicc Oct 27, 2026
c9ace7f
chore: merge upstream main into resume recovery
JustYannicc Oct 27, 2026
66fcaef
chore: merge upstream main into resume recovery
JustYannicc Oct 27, 2026
c63ee38
chore: merge upstream main into resume recovery
JustYannicc Oct 27, 2026
77619cc
chore: merge upstream main into resume recovery
JustYannicc Oct 27, 2026
f45e319
chore: merge upstream main into resume recovery
JustYannicc Oct 27, 2026
544fa37
chore: merge upstream main into resume recovery
JustYannicc Oct 27, 2026
f840a53
chore: merge upstream main into resume recovery
JustYannicc Oct 27, 2026
8c0808f
chore: merge upstream main into resume recovery
JustYannicc Oct 27, 2026
6ba3289
chore: merge upstream main into resume recovery
JustYannicc Oct 27, 2026
3bfe20f
chore: merge upstream main into resume recovery
JustYannicc Oct 27, 2026
3ac8e38
chore: merge upstream main into resume recovery
JustYannicc Oct 28, 2026
8e58a06
chore: merge upstream main into resume recovery
JustYannicc Oct 28, 2026
b1bffff
chore: merge upstream main into resume recovery
JustYannicc Oct 28, 2026
cd8aea2
chore: merge upstream main into resume recovery
JustYannicc Oct 28, 2026
63824b9
chore: merge upstream main into resume recovery
JustYannicc Oct 28, 2026
b2bd636
chore: merge upstream main
JustYannicc Oct 28, 2026
9168c94
chore: merge upstream main
JustYannicc Oct 28, 2026
3ae3d9a
chore: merge upstream main
JustYannicc Oct 28, 2026
b089ca3
chore: merge upstream main
JustYannicc Oct 28, 2026
a9eef61
chore: merge upstream main
JustYannicc Oct 28, 2026
8d31dc6
chore: merge upstream main
JustYannicc Oct 28, 2026
9a88d03
chore: merge upstream main
JustYannicc Oct 28, 2026
5502e61
chore: merge upstream main
JustYannicc Oct 28, 2026
bf1c932
chore: merge upstream main
JustYannicc Oct 28, 2026
a3c392c
chore: merge upstream main
JustYannicc Oct 28, 2026
98c3410
chore: merge upstream main
JustYannicc Oct 28, 2026
c234844
chore: merge upstream main
JustYannicc Oct 28, 2026
cb1e597
chore: merge upstream main
JustYannicc Oct 28, 2026
e709bb0
chore: merge upstream main
JustYannicc Oct 28, 2026
098a7f6
chore: merge upstream main
JustYannicc Oct 28, 2026
58b472b
chore: merge upstream main
JustYannicc Oct 28, 2026
712af3a
chore: merge upstream main
JustYannicc Oct 28, 2026
ea0c143
chore: merge upstream main
JustYannicc Oct 28, 2026
061ef9d
chore: merge upstream main
JustYannicc Oct 28, 2026
85c2973
chore: merge upstream main
JustYannicc Oct 28, 2026
59e3b55
chore: merge upstream main
JustYannicc Oct 28, 2026
451c673
chore: merge upstream main
JustYannicc Oct 28, 2026
4a0b4b5
chore: merge upstream main into resume recovery branch
JustYannicc Oct 28, 2026
c90ed2b
chore: merge upstream main into resume recovery branch
JustYannicc Oct 28, 2026
a18a8ae
chore: merge upstream main into resume recovery branch
JustYannicc Oct 28, 2026
fa17ffe
chore: merge upstream main into resume recovery branch
JustYannicc Oct 28, 2026
8d4924b
chore: merge upstream main into resume recovery branch
JustYannicc Oct 28, 2026
5030a0d
chore: merge upstream main into resume recovery branch
JustYannicc Oct 28, 2026
205adef
chore: merge upstream main into resume recovery branch
JustYannicc Oct 28, 2026
8781492
chore: merge upstream main into resume recovery branch
JustYannicc Oct 28, 2026
85653d5
chore: merge upstream main into resume recovery branch
JustYannicc Oct 28, 2026
5a6744d
chore: merge upstream main into resume recovery branch
JustYannicc Oct 29, 2026
0197305
chore: merge upstream main into resume recovery branch
JustYannicc Oct 29, 2026
0a1fbd1
chore: merge upstream main into resume recovery branch
JustYannicc Oct 29, 2026
29c4c04
chore: merge upstream main into resume recovery branch
JustYannicc Oct 29, 2026
9020a33
chore: merge upstream main into resume recovery branch
JustYannicc Oct 29, 2026
c3e71de
chore: merge upstream main into resume recovery branch
JustYannicc Oct 29, 2026
ba626c8
chore: merge upstream main into resume recovery branch
JustYannicc Oct 29, 2026
4c76dce
chore: merge upstream main into resume recovery branch
JustYannicc Oct 29, 2026
7070100
chore: merge upstream main into resume recovery branch
JustYannicc Oct 29, 2026
05de668
chore: merge upstream main into resume recovery branch
JustYannicc Oct 29, 2026
c868de5
chore: merge upstream main into resume recovery branch
JustYannicc Oct 29, 2026
f04df51
chore: merge upstream main into resume recovery branch
JustYannicc Oct 29, 2026
83afc72
chore: merge upstream main
JustYannicc Oct 29, 2026
d6ec015
chore: merge upstream main
JustYannicc Oct 29, 2026
f3744eb
chore: merge upstream main
JustYannicc Oct 29, 2026
b1c0a2d
chore: merge upstream main
JustYannicc Oct 29, 2026
8487871
chore: merge upstream main
JustYannicc Oct 29, 2026
7911b37
chore: merge upstream main
JustYannicc Oct 29, 2026
085575b
chore: merge upstream main
JustYannicc Oct 29, 2026
bb041d0
chore: merge upstream main
JustYannicc Oct 29, 2026
4e25612
chore: merge upstream main
JustYannicc Oct 29, 2026
8b31571
chore: merge upstream main
JustYannicc Oct 29, 2026
b9f0e69
chore: merge upstream main
JustYannicc Oct 29, 2026
f7f96b7
chore: merge upstream main
JustYannicc Oct 29, 2026
3b50fdf
chore: merge upstream main
JustYannicc Oct 29, 2026
f5ba1b6
chore: merge upstream main
JustYannicc Oct 30, 2026
0fdf4b5
chore: merge upstream main
JustYannicc Oct 30, 2026
6695cbc
chore: merge upstream main
JustYannicc Oct 30, 2026
368d5c7
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
ea86df7
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
7ad3394
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
16aa7d6
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
ea80a4d
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
4f3cc95
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
5ee93d2
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
9d5e668
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
6910205
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
8ace807
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
25da121
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
2bf04a1
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
7872537
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
848a0d0
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
0c6f5a7
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
6781d9d
chore: merge upstream main into resume completion deadline
JustYannicc Oct 30, 2026
0cab545
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
d3a83fe
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
e57b722
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
0e8339e
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
0522bc5
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
8c22ed5
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
c962d4f
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
c2cf5dd
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
112c21c
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
3f36248
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
513302f
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
55b2205
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
9b9c428
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
5c4269c
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
7f30226
chore: merge upstream main into resume deadline fix
JustYannicc Oct 30, 2026
9e36fc2
chore: merge main into resume completion fix
JustYannicc Oct 30, 2026
bfdd758
chore: merge main into resume completion fix
JustYannicc Oct 30, 2026
1f7a021
chore: merge main into resume completion fix
JustYannicc Oct 31, 2026
94be677
chore: merge main into resume completion fix
JustYannicc Oct 31, 2026
d901225
chore: merge main into resume completion fix
JustYannicc Oct 31, 2026
70e06ec
chore: merge main into resume completion fix
JustYannicc Oct 31, 2026
58969a2
chore: merge main into resume completion fix
JustYannicc Oct 31, 2026
60ee64e
chore: merge main into resume completion fix
JustYannicc Oct 31, 2026
c2c06a7
chore: merge main into resume completion fix
JustYannicc Oct 31, 2026
6f027bb
chore: merge upstream main
JustYannicc Oct 31, 2026
c2f2984
chore: merge upstream main
JustYannicc Oct 31, 2026
86b6180
chore: merge upstream main
JustYannicc Oct 31, 2026
e7c6eb1
chore: merge upstream main
JustYannicc Oct 31, 2026
2471046
chore: merge upstream main
JustYannicc Oct 31, 2026
5f33d3b
chore: merge upstream main
JustYannicc Oct 31, 2026
c3c216e
chore: merge upstream main
JustYannicc Oct 31, 2026
8510de4
chore: merge upstream main
JustYannicc Oct 31, 2026
6aefa9e
chore: merge upstream main
JustYannicc Oct 31, 2026
da986c5
chore: merge upstream main
JustYannicc Oct 31, 2026
a0e7c25
chore: merge upstream main
JustYannicc Oct 31, 2026
98d6546
chore: merge upstream main
JustYannicc Oct 31, 2026
e62b7ed
chore: merge upstream main
JustYannicc Oct 31, 2026
1fdc26f
chore: merge upstream main
JustYannicc Oct 31, 2026
5b9aa9d
chore: merge upstream main
JustYannicc Oct 31, 2026
a303b6b
chore: merge upstream main
JustYannicc Nov 1, 2026
0007920
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
c820b6a
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
7b1a7e7
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
e4430dd
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
275fc01
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
b26cdcf
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
888b731
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
c222bfe
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
267d2b6
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
b1fc307
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
be85235
chore: merge main and preserve thread sync error notice
JustYannicc Nov 1, 2026
505f970
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
193eb0c
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
08c3f77
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
e16fe01
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
da88a99
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
830a705
chore: merge upstream main into resume completion fix
JustYannicc Nov 1, 2026
2da411f
chore: merge upstream main into resume recovery
JustYannicc Nov 1, 2026
96811ed
chore: merge upstream main into resume recovery
JustYannicc Nov 1, 2026
a590641
chore: merge upstream main into resume recovery
JustYannicc Nov 1, 2026
24b4f81
chore: merge upstream main into resume recovery
JustYannicc Nov 1, 2026
7f7dc60
chore: merge upstream main into resume recovery
JustYannicc Nov 1, 2026
41ed877
chore: merge upstream main into resume recovery
JustYannicc Nov 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions apps/mobile/src/features/threads/ThreadDetailScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ import type {
} from "../../lib/threadActivity";
import { PendingApprovalCard } from "./PendingApprovalCard";
import { ComposerErrorNotice } from "./ComposerErrorNotice";
import { Notice } from "../../components/ui/Notice";
import { ManagedRuntimeModeNotice } from "./ManagedRuntimeModeNotice";
import { ComposerFeedback } from "./ComposerFeedback";
import { ComposerUsageLimits } from "./ComposerUsageLimits";
Expand Down Expand Up @@ -256,6 +257,7 @@ export interface ThreadDetailScreenProps {
readonly respondingUserInputId: RuntimeRequestId | null;
readonly connectionStateLabel: EnvironmentConnectionPhase;
readonly threadSyncStatus?: EnvironmentThreadStatus;
readonly threadSyncError?: string | null;
readonly historyControls?: ThreadFeedHistoryControls;
readonly activeThreadBusy: boolean;
readonly canStopThread: boolean;
Expand Down Expand Up @@ -538,6 +540,7 @@ function ThreadDetailBody(
const composerKeyboardOffset = composerBottomInset;
const contentPresentationKind = props.contentPresentation.kind;
const realThreadSyncLabel = (() => {
if (props.threadSyncError != null) return null;
switch (props.threadSyncStatus) {
case "empty":
case "cached":
Expand Down Expand Up @@ -1600,6 +1603,17 @@ function ThreadDetailBody(
onDismiss={() => props.onDismissFeedback(submission.id)}
/>
))}
{props.threadSyncError != null && contentPresentationKind === "ready" ? (
<View className="shrink-0 px-4 pb-3">
<Notice
message={props.threadSyncError}
icon="exclamationmark.circle"
tone="danger"
iconTone="danger"
floating
/>
</View>
) : null}
{props.canOperateThread ? (
<ManagedRuntimeModeNotice
threadKey={selectedThreadKey}
Expand Down
19 changes: 9 additions & 10 deletions apps/mobile/src/features/threads/ThreadRouteScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -986,16 +986,14 @@ function ThreadRouteContent(
return <OpeningThreadLoadingScreen />;
}

// Queued creation displays its prompt before server creation; temporary not-found is expected.
const contentPresentation =
creationState !== null
? { kind: "ready" as const }
: projectThreadContentPresentation({
hasDetail: selectedThreadDetail !== null,
detailError: Option.getOrNull(selectedThreadDetailState.error),
detailDeleted: selectedThreadDetailState.status === "deleted",
connectionState: routeConnectionState,
});
const threadDetailError = Option.getOrNull(selectedThreadDetailState.error);
const contentPresentation = projectThreadContentPresentation({
hasDetail: selectedThreadDetail !== null,
detailError: threadDetailError,
detailDeleted: selectedThreadDetailState.status === "deleted",
connectionState: routeConnectionState,
hasPendingCreation: creationState !== null,
});
const serverConfig = routeEnvironmentRuntime?.serverConfig ?? null;
const renderThreadRouteBody = () => (
<>
Expand Down Expand Up @@ -1078,6 +1076,7 @@ function ThreadRouteContent(
respondingUserInputId={requests.respondingUserInputId}
connectionStateLabel={routeConnectionState}
threadSyncStatus={selectedThreadDetailState.status}
threadSyncError={threadDetailError}
historyControls={historyControls}
activeThreadBusy={composer.activeThreadBusy}
canStopThread={awaitingBootstrapTurn || composer.interruptibleRunId !== null}
Expand Down
40 changes: 40 additions & 0 deletions apps/mobile/src/features/threads/threadContentPresentation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,44 @@ describe("thread content presentation", () => {
detail: "Reconnect this environment to load the conversation.",
});
});

it("keeps a pending creation's prompt visible before its thread exists", () => {
expect(
projectThreadContentPresentation({
hasDetail: false,
detailError: null,
detailDeleted: true,
connectionState: "connected",
hasPendingCreation: true,
}),
).toEqual({ kind: "ready" });
});

it("surfaces a synchronization failure while creation is still pending", () => {
expect(
projectThreadContentPresentation({
hasDetail: false,
detailError: "Message synchronization timed out.",
detailDeleted: false,
connectionState: "connected",
hasPendingCreation: true,
}),
).toEqual({
kind: "unavailable",
title: "Could not load conversation",
detail: "Message synchronization timed out.",
});
});

it("keeps cached messages visible after a synchronization failure during creation", () => {
expect(
projectThreadContentPresentation({
hasDetail: true,
detailError: "Message synchronization timed out.",
detailDeleted: false,
connectionState: "connected",
hasPendingCreation: true,
}),
).toEqual({ kind: "ready" });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ export function projectThreadContentPresentation(input: {
readonly detailError: string | null;
readonly detailDeleted: boolean;
readonly connectionState: EnvironmentConnectionPhase;
readonly hasPendingCreation?: boolean;
}): ThreadContentPresentation {
if (input.hasDetail) {
// The local prompt remains usable before creation reaches the server. A real
// synchronization failure still needs the unavailable state or a cached-detail notice.
if (input.hasDetail || (input.hasPendingCreation && input.detailError === null)) {
return { kind: "ready" };
}
if (input.detailDeleted) {
Expand Down
5 changes: 4 additions & 1 deletion apps/web/src/components/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ import {
resolveThreadDetailRef,
useEnvironmentSupportsServerBrowser,
useProject,
useThreadError,
useQuietThreadProjection,
useThreadUpdatedAt,
useThreadLastVisitedAt,
Expand Down Expand Up @@ -509,8 +510,10 @@ export default function ChatView(props: ChatViewProps) {
? deriveReportedModelSelection(serverProjection)
: null;
const threadStatus = useThreadStatus(routeThreadDetailRef);
const threadDetailError = useThreadError(routeThreadDetailRef);
const threadSyncPhase = resolveThreadSyncPhase({
detailExists: serverProjection !== null,
detailError: threadDetailError,
shellExists: serverThread !== null,
status: threadStatus,
});
Expand Down Expand Up @@ -920,7 +923,7 @@ export default function ChatView(props: ChatViewProps) {
title: parentSubagentThread?.title ?? "Parent thread",
};
const threadError = isServerThread
? (localServerError ?? serverRuntime?.lastError ?? null)
? (threadDetailError ?? localServerError ?? serverRuntime?.lastError ?? null)
: localDraftError;
const threadErrorBannerKey = getThreadErrorBannerKey(routeThreadKey, threadError);
const visibleThreadError = shouldShowThreadErrorBanner(
Expand Down
9 changes: 9 additions & 0 deletions apps/web/src/state/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ const EMPTY_THREAD_SHELL_ATOM = Atom.make<EnvironmentThreadShell | null>(null).p
const EMPTY_THREAD_PROJECTION_ATOM = Atom.make<EnvironmentThread | null>(null).pipe(
Atom.withLabel("web-thread-projection:empty"),
);
const EMPTY_THREAD_ERROR_ATOM = Atom.make<string | null>(null).pipe(
Atom.withLabel("web-thread-error:empty"),
);
const EMPTY_THREAD_STATUS_ATOM = Atom.make<EnvironmentThreadStatus>("empty").pipe(
Atom.withLabel("web-thread-status:empty"),
);
Expand Down Expand Up @@ -189,6 +192,12 @@ export function useThreadStatus(ref: ScopedThreadRef | null): EnvironmentThreadS
);
}

export function useThreadError(ref: ScopedThreadRef | null): string | null {
return useAtomValue(
ref === null ? EMPTY_THREAD_ERROR_ATOM : environmentThreadDetails.errorAtom(ref),
);
}

export function useThreadHistory(ref: ScopedThreadRef | null): ThreadHistoryMeta {
return useAtomValue(
ref === null ? EMPTY_THREAD_HISTORY_ATOM : environmentThreadDetails.historyAtom(ref),
Expand Down
29 changes: 29 additions & 0 deletions apps/web/src/threadSync.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { describe, expect, it } from "vite-plus/test";

import { resolveThreadSyncPhase } from "./threadSync";

describe("resolveThreadSyncPhase", () => {
it("stops syncing cached detail on terminal error and resumes when recovery clears it", () => {
const cachedDetail = {
detailExists: true,
shellExists: true,
status: "cached" as const,
detailError: null,
};
expect(resolveThreadSyncPhase(cachedDetail)).toBe("syncing");

const failedDetail = {
...cachedDetail,
detailError:
"Message synchronization timed out. Reconnect or return to the app to try again.",
};
expect.soft(resolveThreadSyncPhase(failedDetail)).toBeNull();

const recoveringDetail = {
...failedDetail,
status: "synchronizing" as const,
detailError: null,
};
expect(resolveThreadSyncPhase(recoveringDetail)).toBe("syncing");
});
});
3 changes: 2 additions & 1 deletion apps/web/src/threadSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ export type ThreadSyncPhase = "loading" | "syncing";

export function resolveThreadSyncPhase(input: {
readonly detailExists: boolean;
readonly detailError?: string | null;
readonly shellExists: boolean;
readonly status: EnvironmentThreadStatus;
}): ThreadSyncPhase | null {
if (!input.shellExists) {
if (!input.shellExists || input.detailError != null) {
return null;
}

Expand Down
10 changes: 9 additions & 1 deletion packages/client-runtime/src/rpc/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,10 @@ export function runStreamGuarded<TTag extends EnvironmentStreamCommandRpcTag>(
}

interface SubscriptionOptions<TTag extends EnvironmentSubscriptionRpcTag> {
readonly transform?: (
stream: Stream.Stream<EnvironmentRpcStreamValue<TTag>, EnvironmentRpcStreamFailure<TTag>>,
input: EnvironmentRpcInput<TTag>,
) => Stream.Stream<EnvironmentRpcStreamValue<TTag>, EnvironmentRpcStreamFailure<TTag>>;
readonly onDefect?: (
cause: Cause.Cause<EnvironmentRpcStreamFailure<TTag>>,
) => Effect.Effect<void, never, never>;
Expand Down Expand Up @@ -299,7 +303,11 @@ function subscribeDynamicMapped<TTag extends EnvironmentSubscriptionRpcTag, A>(
method: tag,
input,
});
const stream = mapStream(session, method(input)).pipe(
const source = method(input);
const stream = mapStream(
session,
options?.transform?.(source, input) ?? source,
).pipe(
Stream.onFirst(() =>
Effect.sync(() => {
expectedFailureRetries = 0;
Expand Down
Loading
Loading