import React from "react"; import { type PlanStatusSession, CLI } from "./service.ts"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; import type { IPlan } from "../plan.ts"; import { render } from "ink"; import { ApprovePlan } from "./components/ApprovePlan.tsx"; import { Plan } from "./components/Plan.tsx"; import { PlanProgress } from "./components/PlanProgress.tsx"; import type { ApplyEvent } from "../event.ts"; 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; });