import { HStack, Spacer, Text, VStack } from "@expo/ui/swift-ui";import { font, foregroundStyle, lineLimit, padding } from "@expo/ui/swift-ui/modifiers";import { createLiveActivity, type LiveActivityComponent, type LiveActivityLayout,} from "expo-widgets"; type LiveActivityEnvironment = Parameters<LiveActivityComponent<AgentActivityProps>>[1]; export type AgentActivityPhase = | "starting" | "running" | "waiting_for_approval" | "waiting_for_input" | "completed" | "failed" | "stale"; export interface AgentActivityRowProps { readonly environmentId: string; readonly threadId: string; readonly projectTitle: string; readonly threadTitle: string; readonly modelTitle: string; readonly phase: AgentActivityPhase; readonly status: string; readonly updatedAt: string; readonly deepLink: string;} export interface AgentActivityProps { readonly title: string; readonly subtitle: string; readonly activeCount: number; readonly updatedAt: string; readonly activities: ReadonlyArray<AgentActivityRowProps>;} export function AgentActivity( props: AgentActivityProps, environment: LiveActivityEnvironment,): LiveActivityLayout { "widget"; const row0 = props.activities[0]; const row1 = props.activities[1]; const row2 = props.activities[2]; const updatedAtMatch = /^\d{4}-\d{2}-\d{2}T(\d{2}):(\d{2}):/.exec(props.updatedAt); const updatedAtHours24 = Number(updatedAtMatch?.[1]); const updatedAtMinutes = updatedAtMatch?.[2]; const updatedAt = Number.isInteger(updatedAtHours24) && updatedAtHours24 >= 0 && updatedAtHours24 <= 23 && updatedAtMinutes ? `${updatedAtHours24 % 12 || 12}:${updatedAtMinutes}` : "now"; const activeLabel = `${props.activeCount} active`; const isLight = environment.colorScheme === "light"; const primaryForeground = isLight ? "#262626" : "#f5f5f5"; const secondaryForeground = isLight ? "#525252" : "#a3a3a3"; const mutedForeground = isLight ? "#737373" : "#8e8e93"; const tint = environment.isLuminanceReduced ? secondaryForeground : row0?.phase === "waiting_for_approval" || row0?.phase === "waiting_for_input" ? "#f97316" : row0?.phase === "failed" ? "#ef4444" : "#14b8a6"; return { banner: ( <VStack modifiers={[padding({ all: 14 })]}> <HStack> <VStack> <Text modifiers={[font({ weight: "bold", size: 15 }), foregroundStyle(primaryForeground)]} > {props.title} </Text> <Text modifiers={[font({ size: 12 }), foregroundStyle(secondaryForeground), lineLimit(1)]} > {props.subtitle} </Text> </VStack> <Spacer minLength={8} /> <Text modifiers={[font({ weight: "semibold", size: 12 }), foregroundStyle(tint)]}> {activeLabel} </Text> </HStack> {row0 ? ( <HStack modifiers={[padding({ vertical: 4 })]}> <VStack> <Text modifiers={[ font({ weight: "bold", size: 13 }), foregroundStyle(primaryForeground), lineLimit(1), ]} > {row0.threadTitle} </Text> <Text modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]} > {row0.projectTitle} - {row0.modelTitle} </Text> </VStack> <Spacer minLength={8} /> <Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}> {row0.status} </Text> </HStack> ) : null} {row1 ? ( <HStack modifiers={[padding({ vertical: 4 })]}> <VStack> <Text modifiers={[ font({ weight: "bold", size: 13 }), foregroundStyle(primaryForeground), lineLimit(1), ]} > {row1.threadTitle} </Text> <Text modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]} > {row1.projectTitle} - {row1.modelTitle} </Text> </VStack> <Spacer minLength={8} /> <Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}> {row1.status} </Text> </HStack> ) : null} {row2 ? ( <HStack modifiers={[padding({ vertical: 4 })]}> <VStack> <Text modifiers={[ font({ weight: "bold", size: 13 }), foregroundStyle(primaryForeground), lineLimit(1), ]} > {row2.threadTitle} </Text> <Text modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]} > {row2.projectTitle} - {row2.modelTitle} </Text> </VStack> <Spacer minLength={8} /> <Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}> {row2.status} </Text> </HStack> ) : null} <Text modifiers={[font({ size: 11 }), foregroundStyle(mutedForeground)]}> Updated {updatedAt} </Text> </VStack> ), bannerSmall: ( <VStack modifiers={[padding({ all: 12 })]}> <HStack> <Text modifiers={[font({ weight: "bold", size: 13 }), foregroundStyle(primaryForeground)]} > {props.title} </Text> <Spacer minLength={6} /> <Text modifiers={[font({ weight: "semibold", size: 12 }), foregroundStyle(tint)]}> {activeLabel} </Text> </HStack> {row0 ? ( <VStack> <Text modifiers={[ font({ weight: "bold", size: 12 }), foregroundStyle(primaryForeground), lineLimit(1), ]} > {row0.threadTitle} </Text> <Text modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]} > {row0.projectTitle} - {row0.status} </Text> </VStack> ) : null} </VStack> ), compactLeading: ( <Text modifiers={[font({ weight: "bold", size: 11 }), foregroundStyle(tint)]}>T3</Text> ), compactTrailing: ( <Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}> {activeLabel} </Text> ), minimal: ( <Text modifiers={[font({ weight: "bold", size: 11 }), foregroundStyle(tint)]}>T3</Text> ), expandedLeading: ( <VStack modifiers={[padding({ all: 8 })]}> <Text modifiers={[font({ weight: "bold", size: 12 }), foregroundStyle(tint)]}> {activeLabel} </Text> </VStack> ), expandedCenter: row0 ? ( <VStack> <Text modifiers={[ font({ weight: "bold", size: 12 }), foregroundStyle(primaryForeground), lineLimit(1), ]} > {row0.threadTitle} </Text> <Text modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]}> {row0.projectTitle} - {row0.status} </Text> </VStack> ) : null, expandedTrailing: ( <Text modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground)]}> Updated {updatedAt} </Text> ), expandedBottom: ( <VStack modifiers={[padding({ all: 8 })]}> {row0 ? ( <HStack modifiers={[padding({ vertical: 4 })]}> <VStack> <Text modifiers={[ font({ weight: "bold", size: 13 }), foregroundStyle(primaryForeground), lineLimit(1), ]} > {row0.threadTitle} </Text> <Text modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]} > {row0.projectTitle} - {row0.modelTitle} </Text> </VStack> <Spacer minLength={8} /> <Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}> {row0.status} </Text> </HStack> ) : null} {row1 ? ( <HStack modifiers={[padding({ vertical: 4 })]}> <VStack> <Text modifiers={[ font({ weight: "bold", size: 13 }), foregroundStyle(primaryForeground), lineLimit(1), ]} > {row1.threadTitle} </Text> <Text modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]} > {row1.projectTitle} - {row1.modelTitle} </Text> </VStack> <Spacer minLength={8} /> <Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}> {row1.status} </Text> </HStack> ) : null} {row2 ? ( <HStack modifiers={[padding({ vertical: 4 })]}> <VStack> <Text modifiers={[ font({ weight: "bold", size: 13 }), foregroundStyle(primaryForeground), lineLimit(1), ]} > {row2.threadTitle} </Text> <Text modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]} > {row2.projectTitle} - {row2.modelTitle} </Text> </VStack> <Spacer minLength={8} /> <Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}> {row2.status} </Text> </HStack> ) : null} </VStack> ), };} export default createLiveActivity<AgentActivityProps>("AgentActivity", AgentActivity);
import { HStack, Spacer, Text, VStack } from "@expo/ui/swift-ui";
import { font, foregroundStyle, lineLimit, padding } from "@expo/ui/swift-ui/modifiers";
import {
createLiveActivity,
type LiveActivityComponent,
type LiveActivityLayout,
} from "expo-widgets";
type LiveActivityEnvironment = Parameters<LiveActivityComponent<AgentActivityProps>>[1];
export type AgentActivityPhase =
| "starting"
| "running"
| "waiting_for_approval"
| "waiting_for_input"
| "completed"
| "failed"
| "stale";
export interface AgentActivityRowProps {
readonly environmentId: string;
readonly threadId: string;
readonly projectTitle: string;
readonly threadTitle: string;
readonly modelTitle: string;
readonly phase: AgentActivityPhase;
readonly status: string;
readonly updatedAt: string;
readonly deepLink: string;
}
export interface AgentActivityProps {
readonly title: string;
readonly subtitle: string;
readonly activeCount: number;
readonly updatedAt: string;
readonly activities: ReadonlyArray<AgentActivityRowProps>;
}
export function AgentActivity(
props: AgentActivityProps,
environment: LiveActivityEnvironment,
): LiveActivityLayout {
"widget";
const row0 = props.activities[0];
const row1 = props.activities[1];
const row2 = props.activities[2];
const updatedAtMatch = /^\d{4}-\d{2}-\d{2}T(\d{2}):(\d{2}):/.exec(props.updatedAt);
const updatedAtHours24 = Number(updatedAtMatch?.[1]);
const updatedAtMinutes = updatedAtMatch?.[2];
const updatedAt =
Number.isInteger(updatedAtHours24) &&
updatedAtHours24 >= 0 &&
updatedAtHours24 <= 23 &&
updatedAtMinutes
? `${updatedAtHours24 % 12 || 12}:${updatedAtMinutes}`
: "now";
const activeLabel = `${props.activeCount} active`;
const isLight = environment.colorScheme === "light";
const primaryForeground = isLight ? "#262626" : "#f5f5f5";
const secondaryForeground = isLight ? "#525252" : "#a3a3a3";
const mutedForeground = isLight ? "#737373" : "#8e8e93";
const tint = environment.isLuminanceReduced
? secondaryForeground
: row0?.phase === "waiting_for_approval" || row0?.phase === "waiting_for_input"
? "#f97316"
: row0?.phase === "failed"
? "#ef4444"
: "#14b8a6";
return {
banner: (
<VStack modifiers={[padding({ all: 14 })]}>
<HStack>
<VStack>
<Text
modifiers={[font({ weight: "bold", size: 15 }), foregroundStyle(primaryForeground)]}
>
{props.title}
</Text>
<Text
modifiers={[font({ size: 12 }), foregroundStyle(secondaryForeground), lineLimit(1)]}
>
{props.subtitle}
</Text>
</VStack>
<Spacer minLength={8} />
<Text modifiers={[font({ weight: "semibold", size: 12 }), foregroundStyle(tint)]}>
{activeLabel}
</Text>
</HStack>
{row0 ? (
<HStack modifiers={[padding({ vertical: 4 })]}>
<VStack>
<Text
modifiers={[
font({ weight: "bold", size: 13 }),
foregroundStyle(primaryForeground),
lineLimit(1),
]}
>
{row0.threadTitle}
</Text>
<Text
modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]}
>
{row0.projectTitle} - {row0.modelTitle}
</Text>
</VStack>
<Spacer minLength={8} />
<Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}>
{row0.status}
</Text>
</HStack>
) : null}
{row1 ? (
<HStack modifiers={[padding({ vertical: 4 })]}>
<VStack>
<Text
modifiers={[
font({ weight: "bold", size: 13 }),
foregroundStyle(primaryForeground),
lineLimit(1),
]}
>
{row1.threadTitle}
</Text>
<Text
modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]}
>
{row1.projectTitle} - {row1.modelTitle}
</Text>
</VStack>
<Spacer minLength={8} />
<Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}>
{row1.status}
</Text>
</HStack>
) : null}
{row2 ? (
<HStack modifiers={[padding({ vertical: 4 })]}>
<VStack>
<Text
modifiers={[
font({ weight: "bold", size: 13 }),
foregroundStyle(primaryForeground),
lineLimit(1),
]}
>
{row2.threadTitle}
</Text>
<Text
modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]}
>
{row2.projectTitle} - {row2.modelTitle}
</Text>
</VStack>
<Spacer minLength={8} />
<Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}>
{row2.status}
</Text>
</HStack>
) : null}
<Text modifiers={[font({ size: 11 }), foregroundStyle(mutedForeground)]}>
Updated {updatedAt}
</Text>
</VStack>
),
bannerSmall: (
<VStack modifiers={[padding({ all: 12 })]}>
<HStack>
<Text
modifiers={[font({ weight: "bold", size: 13 }), foregroundStyle(primaryForeground)]}
>
{props.title}
</Text>
<Spacer minLength={6} />
<Text modifiers={[font({ weight: "semibold", size: 12 }), foregroundStyle(tint)]}>
{activeLabel}
</Text>
</HStack>
{row0 ? (
<VStack>
<Text
modifiers={[
font({ weight: "bold", size: 12 }),
foregroundStyle(primaryForeground),
lineLimit(1),
]}
>
{row0.threadTitle}
</Text>
<Text
modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]}
>
{row0.projectTitle} - {row0.status}
</Text>
</VStack>
) : null}
</VStack>
),
compactLeading: (
<Text modifiers={[font({ weight: "bold", size: 11 }), foregroundStyle(tint)]}>T3</Text>
),
compactTrailing: (
<Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}>
{activeLabel}
</Text>
),
minimal: (
<Text modifiers={[font({ weight: "bold", size: 11 }), foregroundStyle(tint)]}>T3</Text>
),
expandedLeading: (
<VStack modifiers={[padding({ all: 8 })]}>
<Text modifiers={[font({ weight: "bold", size: 12 }), foregroundStyle(tint)]}>
{activeLabel}
</Text>
</VStack>
),
expandedCenter: row0 ? (
<VStack>
<Text
modifiers={[
font({ weight: "bold", size: 12 }),
foregroundStyle(primaryForeground),
lineLimit(1),
]}
>
{row0.threadTitle}
</Text>
<Text modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]}>
{row0.projectTitle} - {row0.status}
</Text>
</VStack>
) : null,
expandedTrailing: (
<Text modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground)]}>
Updated {updatedAt}
</Text>
),
expandedBottom: (
<VStack modifiers={[padding({ all: 8 })]}>
{row0 ? (
<HStack modifiers={[padding({ vertical: 4 })]}>
<VStack>
<Text
modifiers={[
font({ weight: "bold", size: 13 }),
foregroundStyle(primaryForeground),
lineLimit(1),
]}
>
{row0.threadTitle}
</Text>
<Text
modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]}
>
{row0.projectTitle} - {row0.modelTitle}
</Text>
</VStack>
<Spacer minLength={8} />
<Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}>
{row0.status}
</Text>
</HStack>
) : null}
{row1 ? (
<HStack modifiers={[padding({ vertical: 4 })]}>
<VStack>
<Text
modifiers={[
font({ weight: "bold", size: 13 }),
foregroundStyle(primaryForeground),
lineLimit(1),
]}
>
{row1.threadTitle}
</Text>
<Text
modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]}
>
{row1.projectTitle} - {row1.modelTitle}
</Text>
</VStack>
<Spacer minLength={8} />
<Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}>
{row1.status}
</Text>
</HStack>
) : null}
{row2 ? (
<HStack modifiers={[padding({ vertical: 4 })]}>
<VStack>
<Text
modifiers={[
font({ weight: "bold", size: 13 }),
foregroundStyle(primaryForeground),
lineLimit(1),
]}
>
{row2.threadTitle}
</Text>
<Text
modifiers={[font({ size: 11 }), foregroundStyle(secondaryForeground), lineLimit(1)]}
>
{row2.projectTitle} - {row2.modelTitle}
</Text>
</VStack>
<Spacer minLength={8} />
<Text modifiers={[font({ weight: "semibold", size: 11 }), foregroundStyle(tint)]}>
{row2.status}
</Text>
</HStack>
) : null}
</VStack>
),
};
}
export default createLiveActivity<AgentActivityProps>("AgentActivity", AgentActivity);