SPB Git

Repository Public

states.ts 2.3 KB 69 lines typescript

1import { z } from 'zod';23/** Terminal session lifecycle. WAITING_FOR_INPUT is only ever set from a Claude Code hook signal. */4export const SessionState = z.enum([5  'CREATED',6  'STARTING',7  'RUNNING',8  'DETACHED',9  'WAITING_FOR_INPUT',10  'STOPPING',11  'STOPPED',12  'FAILED',13  'RECOVERABLE',14]);15export type SessionState = z.infer<typeof SessionState>;1617/** Allowed transitions (from -> to[]). Enforced server-side; unit-tested. */18export const SESSION_TRANSITIONS: Record<SessionState, readonly SessionState[]> = {19  CREATED: ['STARTING', 'FAILED', 'STOPPED'],20  STARTING: ['RUNNING', 'DETACHED', 'FAILED', 'STOPPED'],21  RUNNING: ['DETACHED', 'WAITING_FOR_INPUT', 'STOPPING', 'STOPPED', 'FAILED', 'RECOVERABLE'],22  DETACHED: ['RUNNING', 'WAITING_FOR_INPUT', 'STOPPING', 'STOPPED', 'FAILED', 'RECOVERABLE'],23  WAITING_FOR_INPUT: ['RUNNING', 'DETACHED', 'STOPPING', 'STOPPED', 'FAILED', 'RECOVERABLE'],24  STOPPING: ['STOPPED', 'FAILED'],25  STOPPED: [],26  FAILED: [],27  // After a host reboot / lost tmux server: metadata survives, process does not.28  RECOVERABLE: ['STARTING', 'STOPPED'],29};30export function canTransition(from: SessionState, to: SessionState): boolean {31  return from === to || SESSION_TRANSITIONS[from].includes(to);32}33export const LIVE_SESSION_STATES: readonly SessionState[] = [34  'STARTING',35  'RUNNING',36  'DETACHED',37  'WAITING_FOR_INPUT',38  'STOPPING',39];4041export const TaskState = z.enum([42  'QUEUED',43  'RUNNING',44  'SUCCEEDED',45  'FAILED',46  'CANCELLING',47  'CANCELLED',48  'TIMED_OUT',49  'LOST', // host rebooted / runner vanished; never auto-retried50]);51export type TaskState = z.infer<typeof TaskState>;52export const TASK_TRANSITIONS: Record<TaskState, readonly TaskState[]> = {53  QUEUED: ['RUNNING', 'CANCELLED', 'FAILED'],54  RUNNING: ['SUCCEEDED', 'FAILED', 'CANCELLING', 'CANCELLED', 'TIMED_OUT', 'LOST'],55  CANCELLING: ['CANCELLED', 'FAILED', 'SUCCEEDED', 'LOST'],56  SUCCEEDED: [],57  FAILED: [],58  CANCELLED: [],59  TIMED_OUT: [],60  LOST: [],61};62export function canTaskTransition(from: TaskState, to: TaskState): boolean {63  return from === to || TASK_TRANSITIONS[from].includes(to);64}6566/** Health vocabulary used by every dashboard. Stale data must be UNKNOWN, never ONLINE. */67export const Health = z.enum(['ONLINE', 'OFFLINE', 'DEGRADED', 'UNKNOWN']);68export type Health = z.infer<typeof Health>;69
Files main
Menu

Theme