/** @jsxImportSource react */ import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; import { render } from "ink"; import type { Plan } from "../Plan.ts"; import { type PlanStatusSession, Cli } from "./Cli.ts"; import type { ApplyEvent } from "./Event.ts"; import { ApprovePlan } from "./components/ApprovePlan.tsx"; import { Plan as PlanComponent } from "./components/Plan.tsx"; import { PlanProgress } from "./components/PlanProgress.tsx"; export const inkCLI = () => Layer.succeed( Cli, Cli.of({ approvePlan, displayPlan, startApplySession, }), ); const approvePlan = Effect.fn(function*

(plan: P) { let approved = false; const { waitUntilExit } = render( (approved = a)} />, ); yield* Effect.promise(waitUntilExit); return approved; }); const displayPlan =

(plan: P): Effect.Effect => Effect.sync(() => { const { unmount } = render(); unmount(); }); const startApplySession = Effect.fn(function*

(plan: P) { const listeners = new Set<(event: ApplyEvent) => void>(); const { unmount } = render( listeners.delete(listener); }, }} />, ); return { done: Effect.fn(function* () { yield* Effect.sleep(10); // give the react event loop time to re-render yield* Effect.sync(() => unmount()); }), emit: (event) => Effect.sync(() => { for (const listener of listeners) listener(event); }), } satisfies PlanStatusSession; });