import type { CronTask } from '../../types'; import { formatAbsoluteTime, formatRelativeTime } from '../../util/time'; import { useCron } from '../../hooks/useTasks'; import { CopyButton } from '../shared/CopyButton'; import { Pill } from '../shared/Pill'; interface CronTabProps { sessionId: string; } /** Cron tab — scheduled prompts persisted under the session's `cron/` * directory. Like background tasks, none of this is in the wire, so it is * the only place to see what a session has scheduled. */ export function CronTab({ sessionId }: CronTabProps) { const { data, isLoading, error } = useCron(sessionId); if (isLoading) { return
loading cron…
; } if (error) { return (
{error.message}
); } const cron = data?.cron ?? []; return (
cron jobs{cron.length > 0 ? ` · ${cron.length}` : ''}
{cron.length === 0 ? (
no cron jobs were scheduled in this session
) : (
{cron.map((job) => ( ))}
)}
); } function CronCard({ job }: { job: CronTask }) { // `recurring` is undefined/true → recurring by convention; false → one-shot. const oneShot = job.recurring === false; return (
{oneShot ? 'one-shot' : 'recurring'} {job.cron} {job.id} created {formatRelativeTime(job.createdAt)}
prompt
{job.prompt}
{job.lastFiredAt === undefined ? ( (never fired) ) : ( {formatAbsoluteTime(job.lastFiredAt)} ({formatRelativeTime(job.lastFiredAt)}) )} {formatAbsoluteTime(job.createdAt)}
); } function Field({ label, children }: { label: string; children: import('react').ReactNode }) { return (
{label} {children}
); }