import { z } from "zod" import { clineMessageSchema, tokenUsageSchema } from "./message" import { toolNamesSchema, toolUsageSchema } from "./tool" import { rooCodeSettingsSchema } from "./global-settings" /** * isSubtaskSchema */ export const isSubtaskSchema = z.object({ isSubtask: z.boolean(), }) export type IsSubtask = z.infer /** * RooCodeEvent */ export enum RooCodeEventName { Message = "message", TaskCreated = "taskCreated", TaskStarted = "taskStarted", TaskModeSwitched = "taskModeSwitched", TaskPaused = "taskPaused", TaskUnpaused = "taskUnpaused", TaskAskResponded = "taskAskResponded", TaskAborted = "taskAborted", TaskSpawned = "taskSpawned", TaskCompleted = "taskCompleted", TaskTokenUsageUpdated = "taskTokenUsageUpdated", TaskToolFailed = "taskToolFailed", EvalPass = "evalPass", EvalFail = "evalFail", } export const rooCodeEventsSchema = z.object({ [RooCodeEventName.Message]: z.tuple([ z.object({ taskId: z.string(), action: z.union([z.literal("created"), z.literal("updated")]), message: clineMessageSchema, }), ]), [RooCodeEventName.TaskCreated]: z.tuple([z.string()]), [RooCodeEventName.TaskStarted]: z.tuple([z.string()]), [RooCodeEventName.TaskModeSwitched]: z.tuple([z.string(), z.string()]), [RooCodeEventName.TaskPaused]: z.tuple([z.string()]), [RooCodeEventName.TaskUnpaused]: z.tuple([z.string()]), [RooCodeEventName.TaskAskResponded]: z.tuple([z.string()]), [RooCodeEventName.TaskAborted]: z.tuple([z.string()]), [RooCodeEventName.TaskSpawned]: z.tuple([z.string(), z.string()]), [RooCodeEventName.TaskCompleted]: z.tuple([z.string(), tokenUsageSchema, toolUsageSchema, isSubtaskSchema]), [RooCodeEventName.TaskTokenUsageUpdated]: z.tuple([z.string(), tokenUsageSchema]), [RooCodeEventName.TaskToolFailed]: z.tuple([z.string(), toolNamesSchema, z.string()]), }) export type RooCodeEvents = z.infer /** * Ack */ export const ackSchema = z.object({ clientId: z.string(), pid: z.number(), ppid: z.number(), }) export type Ack = z.infer /** * TaskCommand */ export enum TaskCommandName { StartNewTask = "StartNewTask", CancelTask = "CancelTask", CloseTask = "CloseTask", } export const taskCommandSchema = z.discriminatedUnion("commandName", [ z.object({ commandName: z.literal(TaskCommandName.StartNewTask), data: z.object({ configuration: rooCodeSettingsSchema, text: z.string(), images: z.array(z.string()).optional(), newTab: z.boolean().optional(), }), }), z.object({ commandName: z.literal(TaskCommandName.CancelTask), data: z.string(), }), z.object({ commandName: z.literal(TaskCommandName.CloseTask), data: z.string(), }), ]) export type TaskCommand = z.infer /** * TaskEvent */ export const taskEventSchema = z.discriminatedUnion("eventName", [ z.object({ eventName: z.literal(RooCodeEventName.Message), payload: rooCodeEventsSchema.shape[RooCodeEventName.Message], taskId: z.number().optional(), }), z.object({ eventName: z.literal(RooCodeEventName.TaskCreated), payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskCreated], taskId: z.number().optional(), }), z.object({ eventName: z.literal(RooCodeEventName.TaskStarted), payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskStarted], taskId: z.number().optional(), }), z.object({ eventName: z.literal(RooCodeEventName.TaskModeSwitched), payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskModeSwitched], taskId: z.number().optional(), }), z.object({ eventName: z.literal(RooCodeEventName.TaskPaused), payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskPaused], taskId: z.number().optional(), }), z.object({ eventName: z.literal(RooCodeEventName.TaskUnpaused), payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskUnpaused], taskId: z.number().optional(), }), z.object({ eventName: z.literal(RooCodeEventName.TaskAskResponded), payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskAskResponded], taskId: z.number().optional(), }), z.object({ eventName: z.literal(RooCodeEventName.TaskAborted), payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskAborted], taskId: z.number().optional(), }), z.object({ eventName: z.literal(RooCodeEventName.TaskSpawned), payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskSpawned], taskId: z.number().optional(), }), z.object({ eventName: z.literal(RooCodeEventName.TaskCompleted), payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskCompleted], taskId: z.number().optional(), }), z.object({ eventName: z.literal(RooCodeEventName.TaskTokenUsageUpdated), payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskTokenUsageUpdated], taskId: z.number().optional(), }), z.object({ eventName: z.literal(RooCodeEventName.TaskToolFailed), payload: rooCodeEventsSchema.shape[RooCodeEventName.TaskToolFailed], taskId: z.number().optional(), }), z.object({ eventName: z.literal(RooCodeEventName.EvalPass), payload: z.undefined(), taskId: z.number(), }), z.object({ eventName: z.literal(RooCodeEventName.EvalFail), payload: z.undefined(), taskId: z.number(), }), ]) export type TaskEvent = z.infer /** * IpcMessage */ export enum IpcMessageType { Connect = "Connect", Disconnect = "Disconnect", Ack = "Ack", TaskCommand = "TaskCommand", TaskEvent = "TaskEvent", } export enum IpcOrigin { Client = "client", Server = "server", } export const ipcMessageSchema = z.discriminatedUnion("type", [ z.object({ type: z.literal(IpcMessageType.Ack), origin: z.literal(IpcOrigin.Server), data: ackSchema, }), z.object({ type: z.literal(IpcMessageType.TaskCommand), origin: z.literal(IpcOrigin.Client), clientId: z.string(), data: taskCommandSchema, }), z.object({ type: z.literal(IpcMessageType.TaskEvent), origin: z.literal(IpcOrigin.Server), relayClientId: z.string().optional(), data: taskEventSchema, }), ]) export type IpcMessage = z.infer /** * Client */ export type IpcClientEvents = { [IpcMessageType.Connect]: [] [IpcMessageType.Disconnect]: [] [IpcMessageType.Ack]: [data: Ack] [IpcMessageType.TaskCommand]: [data: TaskCommand] [IpcMessageType.TaskEvent]: [data: TaskEvent] } /** * Server */ export type IpcServerEvents = { [IpcMessageType.Connect]: [clientId: string] [IpcMessageType.Disconnect]: [clientId: string] [IpcMessageType.TaskCommand]: [clientId: string, data: TaskCommand] [IpcMessageType.TaskEvent]: [relayClientId: string | undefined, data: TaskEvent] }