/** * @license * Copyright 2025 Steven Roussey * SPDX-License-Identifier: Apache-2.0 */ import type { IRunConfig, ITask, IWorkflow, TaskGraphRunConfig, WorkflowRunConfig } from "@workglow/task-graph"; import { TaskGraph } from "@workglow/task-graph"; /** Values that can be executed with CLI progress UI (TTY) or plain run when not a TTY. */ export type Tasklike = ITask | IWorkflow | TaskGraph; export interface WithCliOptions { /** When true, do not print JSON to stdout on success (default for library-style callers). */ readonly suppressResultOutput?: boolean; /** * Pass false when this run must not draw a terminal UI even on a TTY — * a command emitting JSON on stdout, say, which Ink's rows would interleave * with. Reporting to a watching parent is unaffected: that is a separate * question from whether a human is looking at this terminal, and answering * both with one flag is what made a piped run invisible to the console. */ readonly interactive?: boolean; } /** * Operator opt-out from the terminal UI: `WORKGLOW_NO_TUI=1` runs plainly even * on a TTY, exactly as a piped run does. * * It exists because a run whose length is set by the size of the data can * accumulate memory in proportion to how many times it re-renders. Measured on * one `sync` sweep, same machine and database: 249 MB -> 1,148 MB across 3,000 * filings with the UI on, flat at 297 MB with it off, and ~3x faster. * * The cause is NOT Ink, and this flag is the blunter of the two remedies. * React's DEVELOPMENT build instruments commits for the profiler, emitting * `performance.measure()` per component per commit; Node's user-timing buffer * is unbounded and nothing in a headless process drains it, so every entry is * retained for the process lifetime. A progress UI re-rendering continuously * for hours is simply the workload that makes an unbounded buffer visible. * * So prefer `NODE_ENV=production`, which drops the instrumentation entirely * and is also markedly faster; measured over 8,000 re-renders the heap stays * flat at ~15 MB and yoga node count never moves. Reach for this flag when the * production build is not an option, or when the terminal output itself is * unwanted — it works by removing the renders, which removes the accumulation * as a side effect rather than by fixing it. */ export declare function tuiDisabledByEnv(): boolean; export interface WithCliTaskHandle { readonly kind: "task"; /** * `runConfig` reaches `task.run` and the Ink renderer alike — the * implementation has always threaded it, and the caller that needs it is one * running a task inside something longer than a command, where the registry * and the abort signal are the session's rather than the process's. */ run(overrides?: Record, runConfig?: Partial): Promise; abort(): void; } export interface WithCliWorkflowHandle { readonly kind: "workflow"; run(input?: Record, config?: WorkflowRunConfig): Promise; abort(): void; } export interface WithCliGraphHandle { readonly kind: "graph"; run(input?: Record, config?: TaskGraphRunConfig): Promise; abort(): void; } export type WithCliHandle = WithCliTaskHandle | WithCliWorkflowHandle | WithCliGraphHandle; export declare function withCli(task: ITask, options?: WithCliOptions): WithCliTaskHandle; export declare function withCli(workflow: IWorkflow, options?: WithCliOptions): WithCliWorkflowHandle; export declare function withCli(graph: TaskGraph, options?: WithCliOptions): WithCliGraphHandle;