export type JsonPrimitive = string | number | boolean | null; export type JsonValue = | JsonPrimitive | JsonValue[] | { [key: string]: JsonValue }; export type ApiProblemDetails = { type?: string; title: string; status: number; detail?: string; message?: string; /** Stable machine-readable identifier, unlike title or detail. */ code: string; requestId?: string; operationId?: string; errors?: Record; }; export type Page = { items: T[]; nextCursor?: string; }; export const KUBER_API_VERSION = "kuber.astrxl.dev/v2" as const; export type ObjectMeta = { name: string; uid: string; resourceVersion: string; creationTimestamp: string; labels?: Record; annotations?: Record; }; export type WorkspaceSourceReference = { uri: string; digest: string; revision?: string; }; export type WorkspaceSpec = { source: WorkspaceSourceReference; config?: unknown; }; export type Workspace = { apiVersion: typeof KUBER_API_VERSION; kind: "Workspace"; metadata: ObjectMeta; spec: WorkspaceSpec; status: { latestRevision: number }; }; export type CreateWorkspaceRequest = { id: string; source: WorkspaceSourceReference; config?: unknown; labels?: Record; annotations?: Record; }; export type UpdateWorkspaceRequest = Omit; export type CreateWorkspaceResponse = Workspace; export type ListWorkspacesResponse = Page; export type GetWorkspaceResponse = Workspace; export type WorkspaceTrustResponse = { fingerprints: string[]; }; export type DeleteWorkspaceResponse = OperationAcceptedResponse; export type AdoptWorkspaceResponse = { workspaceId: string; workspaceUid: string; resourcesAdopted: number; }; export type AdoptPlatformRequest = { workspaceUid: string }; export type AdoptPlatformResponse = AdoptWorkspaceResponse; export type WorkspaceState = | "pending" | "ready" | "degraded" | "stopped" | "deleting" | "failed"; export type ServiceStatus = { name: string; state: "pending" | "running" | "stopped" | "failed" | "unknown"; readyReplicas: number; desiredReplicas: number; image?: string; message?: string; }; export type WorkspaceStatusResponse = { workspaceId: string; state: WorkspaceState; services: ServiceStatus[]; observedAt: string; }; export type LifecycleAction = "start" | "stop" | "restart" | "delete"; export type LifecycleRequest = { action: LifecycleAction; services?: string[]; }; export type LifecycleResponse = OperationAcceptedResponse; export type ResourceObject = { apiVersion: string; kind: string; metadata: { name: string; namespace?: string; labels?: Record; annotations?: Record; }; } & Record; export type ResourceChange = { apiVersion: string; kind: string; name: string; action: "create" | "update" | "delete" | "unchanged"; }; export type ReconcileResourcesRequest = { resources: ResourceObject[]; prune?: boolean; dryRun?: boolean; }; export type ReconcileResourcesResponse = { operationId?: string; changes: ResourceChange[]; }; export type DatabaseEngine = "postgres"; export type DatabaseClaim = { name: string; engine: DatabaseEngine; database?: string; username?: string; }; export type ReconcileDatabasesRequest = { claims: DatabaseClaim[] }; export type DatabaseBinding = { claim: string; service: string; environment: Record; }; export type ReconcileDatabasesResponse = { bindings: DatabaseBinding[]; operationId?: string; }; export type StorageKind = "s3"; export type StorageClaim = { name: string; kind: StorageKind; bucket?: string; region?: string; }; export type ReconcileStorageRequest = { claims: StorageClaim[] }; export type StorageBinding = { claim: string; service: string; environment: Record; }; export type ReconcileStorageResponse = { bindings: StorageBinding[]; operationId?: string; }; export type OperationState = | "pending" | "running" | "succeeded" | "failed" | "cancelled"; export type OperationError = { code: string; message: string }; export type Operation = { apiVersion: typeof KUBER_API_VERSION; kind: "Operation"; metadata: ObjectMeta & { workspaceUid?: string }; spec: { workspaceId: string; action: string }; status: { state: OperationState; startedAt?: string; finishedAt?: string; result?: unknown; error?: OperationError; }; }; export type OperationAcceptedResponse = { operationId: string; operation?: Operation; }; export type GetOperationResponse = Operation; export type CancelOperationResponse = Operation; export type OperationEvent = { operationId: string; sequence: number; timestamp: string; type: "status" | "progress" | "log" | "result" | "error"; data: JsonValue; }; export type ListOperationEventsResponse = { items: OperationEvent[]; nextCursor?: number; /** The oldest event sequence still retained for this operation. */ retainedFirstSequence: number; /** True when `after` predates the retained event history. */ cursorGap: boolean; }; export type UserRole = "admin" | "operator" | "viewer" | (string & {}); export type User = { username: string; roles: UserRole[]; disabled: boolean; createdAt?: string; updatedAt?: string; }; export type CreateUserRequest = { username: string; password: string; roles: UserRole[]; }; export type UpdateUserRequest = { password?: string; roles?: UserRole[]; disabled?: boolean; }; export type UserResponse = User; export type ListUsersResponse = Page; export type Capability = | "kubernetes:read" | "kubernetes:write" | "kubernetes:exec" | "users:read" | "users:write" | "sessions:revoke" | "platform:adopt"; export type ApiKey = { id: string; username: string; capabilities: Capability[]; workspace?: string; /** Absent for a key that never expires. */ expiresAt?: string; disabled: boolean; }; export type CreateApiKeyRequest = { capabilities: Capability[]; workspace?: string; expiresAt?: string; }; export type CreateApiKeyResponse = ApiKey & { token: string }; export type ListApiKeysResponse = Page; export type AuditEvent = { id: string; timestamp: string; actor: string; action: string; resourceType: string; resourceId?: string; workspaceId?: string; requestId?: string; operationId?: string; outcome: "success" | "failure"; metadata?: Record; }; export type ListAuditEventsRequest = { cursor?: string; limit?: number; actor?: string; workspaceId?: string; since?: string; until?: string; }; export type ListAuditEventsResponse = Page; export type MaintenanceStatus = { host: string; enabled: boolean; hosts: string[]; };