import { Box, Text, render, useApp, useInput } from "ink"; import React, { useEffect } from "react"; import { ExecutionEvent, type Flow, type Task } from "../../src/flows"; import { back } from "./inc/back"; import { fanout } from "./inc/fanout-condition"; import { parallel } from "./inc/parallel"; import { simpleFetch } from "./inc/simple-fetch"; const flows = { back, fanout, parallel, simpleFetch }; const arg = process.argv[2]; if (!arg) { console.log("Please provide a flow name:", Object.keys(flows).join(", ")); process.exit(1); } if (!flows[arg]) { console.log("Flow not found:", arg, Object.keys(flows).join(", ")); process.exit(1); } console.log(JSON.stringify(flows[arg].toJSON(), null, 2)); process.exit(); const colors = [ "#B5E61D", // Lime Green "#4A90E2", // Bright Blue "#F78F1E", // Saffron "#BD10E0", // Vivid Purple "#50E3C2", // Turquoise "#9013FE" // Grape ]; const colorsCache: Record = {}; type Sequence = { source: string; target: string }[]; type Layout = Task[][]; type State = { layout: Layout; connections: Sequence }; type TaskWithStatus = { task: Task; status: string }; function TerminalFlow({ flow }: { flow: Flow }) { const [tasks, setTasks] = React.useState([]); const sequence = flow.getSequence(); const connections = flow.connections; const { exit } = useApp(); useInput((input, key) => { if (input === "q") { exit(); return; } if (key.return) { // Left arrow key pressed console.log("Enter pressed"); } else { console.log(input); } }); useEffect(() => { setTasks(flow.tasks.map((t) => ({ task: t, status: "pending" }))); const execution = flow.createExecution(); execution.subscribe((event) => { if (event instanceof ExecutionEvent) { setTasks((prev) => prev.map((t) => { if (t.task.name === event.task().name) { let newStatus = "pending"; if (event.isStart()) { newStatus = "running"; } else { newStatus = event.succeeded() ? "success" : "failure"; } return { task: t.task, status: newStatus }; } return t; }) ); } }); execution.start().then(() => { const response = execution.getResponse(); console.log("done", response ? response : "(no response)"); console.log( "Executed tasks:", execution.logs.map((l) => l.task.name) ); console.log("Executed count:", execution.logs.length); }); }, []); function getColor(key: string) { if (!colorsCache[key]) { colorsCache[key] = colors[Object.keys(colorsCache).length]; } return colorsCache[key]; } if (tasks.length === 0) { return Loading...; } return ( {sequence.map((step, stepIndex) => { return ( {step.map((_task, index) => { const find = tasks.find((t) => t.task.name === _task.name)!; if (!find) { //console.log("couldnt find", _task.name); return null; } const { task, status } = find; const inTasks = flow.task(task).getInTasks(); return ( {inTasks.length > 0 && ( In: {inTasks.map((inTask, i) => ( {i > 0 ? ", " : ""} {inTask.name} ))} )} {task.name} ); })} ); })} ); } const Status = ({ status }: { status: string }) => { let color: string | undefined; switch (status) { case "running": color = "orange"; break; case "success": color = "green"; break; case "failure": color = "red"; break; } return ( {status} ); }; render();