authorgravatar for jakeleventhal@me.comJake Leventhal <jakeleventhal@me.com> 2026-10-03 10:54:10-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-03 09:54:10-05:00
loga0bf1eee48d1537ec38e0f1fa5243f10ffd4e870
tree90a2b645f7bdaa4d310f12555354ead7890ef6d7
parent44b49650170a76e6171642d6f8de946cf1d1c821
signature Signed by PGP key B5690EEEBB952194

fix(mobile): a dev server left running no longer shows the waiting bolt (#15194)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

3 files changed, 15 insertions(+), 6 deletions(-)

apps/mobile/src/features/threads/ThreadDetailScreen.tsx+2-1
...@@ -474,11 +474,12 @@ export const ThreadDetailScreen = memo(function ThreadDetailScreen(props: Thread...@@ -474,11 +474,12 @@ export const ThreadDetailScreen = memo(function ThreadDetailScreen(props: Thread
474 }474 }
475 if (pendingBackgroundWork !== null && contentPresentationKind === "ready") {475 if (pendingBackgroundWork !== null && contentPresentationKind === "ready") {
476 return {476 return {
477 kind: "waiting",477 kind: "background",
478 label: pendingBackgroundWork.title,478 label: pendingBackgroundWork.title,
479 accessibilityLabel: `${pendingBackgroundWork.title}: ${pendingBackgroundWork.items479 accessibilityLabel: `${pendingBackgroundWork.title}: ${pendingBackgroundWork.items
480 .map((item) => item.label)480 .map((item) => item.label)
481 .join(", ")}`,481 .join(", ")}`,
482 waiting: pendingBackgroundWork.waiting,
482 };483 };
483 }484 }
484 return null;485 return null;
apps/mobile/src/features/threads/floating-working-control.tsx+5-3
...@@ -385,16 +385,18 @@ function FloatingStatusLabel(props: {...@@ -385,16 +385,18 @@ function FloatingStatusLabel(props: {
385 </StatusLabelRow>385 </StatusLabelRow>
386 );386 );
387 }387 }
388 if (props.status.kind === "waiting") {388 if (props.status.kind === "background") {
389 return (389 return (
390 <StatusLabelRow390 <StatusLabelRow
391 key="waiting"391 key="background"
392 accessibilityLabel={props.status.accessibilityLabel}392 accessibilityLabel={props.status.accessibilityLabel}
393 className="gap-2"393 className="gap-2"
394 onLayout={props.onLayout}394 onLayout={props.onLayout}
395 >395 >
396 {/* A dev server can run for hours after the agent is done, so only work
397 that will wake the agent gets the bolt. */}
396 <SymbolView398 <SymbolView
397 name={{ ios: "bolt", android: "bolt" }}399 name={props.status.waiting ? { ios: "bolt", android: "bolt" } : "terminal"}
398 size={13}400 size={13}
399 tintColorClassName="foreground"401 tintColorClassName="foreground"
400 type="monochrome"402 type="monochrome"
apps/mobile/src/features/threads/floating-working-status.ts+8-2
...@@ -9,8 +9,14 @@ export type FloatingWorkingStatus =...@@ -9,8 +9,14 @@ export type FloatingWorkingStatus =
9 | { readonly kind: "working"; readonly startedAt: string }9 | { readonly kind: "working"; readonly startedAt: string }
10 | { readonly kind: "syncing"; readonly label: string }10 | { readonly kind: "syncing"; readonly label: string }
11 | { readonly kind: "compacting" }11 | { readonly kind: "compacting" }
12 // The turn settled while background work it started still runs.12 // The turn settled while background work it started still runs. `waiting`
13 | { readonly kind: "waiting"; readonly label: string; readonly accessibilityLabel: string }13 // is false when only commands remain, such as a dev server: the agent is done.
14 | {
15 readonly kind: "background";
16 readonly label: string;
17 readonly accessibilityLabel: string;
18 readonly waiting: boolean;
19 }
14 // A task whose thread the server has not created yet: the worktree may20 // A task whose thread the server has not created yet: the worktree may
15 // still be checking out, so there is no turn to time.21 // still be checking out, so there is no turn to time.
16 | { readonly kind: "preparing"; readonly label: string }22 | { readonly kind: "preparing"; readonly label: string }