Skip to main content

ftui_runtime/
lib.rs

1#![forbid(unsafe_code)]
2
3//! FrankenTUI Runtime
4//!
5//! This crate provides the runtime components that tie together the core,
6//! render, and layout crates into a complete terminal application framework.
7//!
8//! # Key Components
9//!
10//! - [`TerminalWriter`] - Unified terminal output coordinator with inline mode support
11//! - [`LogSink`] - Line-buffered writer for sanitized log output
12//! - [`Program`] - Bubbletea/Elm-style runtime for terminal applications
13//! - [`Model`] - Trait for application state and behavior
14//! - [`Cmd`] - Commands for side effects
15//! - [`Subscription`] - Trait for continuous event sources
16//! - [`Every`] - Built-in tick subscription
17//!
18//! # Role in FrankenTUI
19//! `ftui-runtime` is the orchestrator. It consumes input events from
20//! `ftui-core`, drives your `Model::update`, calls `Model::view` to render
21//! frames, and delegates rendering to `ftui-render` via `TerminalWriter`.
22//!
23//! # How it fits in the system
24//! The runtime is the center of the architecture: it is the bridge between
25//! input (`ftui-core`) and output (`ftui-render`). Widgets and layout are
26//! optional layers used by your `view()` to construct UI output.
27
28pub mod allocation_budget;
29pub mod alpha_investing;
30pub mod asciicast;
31pub mod bocpd;
32pub mod cancellation;
33
34pub mod conformal_alert;
35pub mod conformal_frame_guard;
36pub mod conformal_predictor;
37pub mod conformal_stages;
38pub mod cost_model;
39pub mod debug_trace;
40pub mod decision_core;
41pub mod degradation_cascade;
42pub mod demo;
43pub mod diff_evidence;
44pub mod effect_system;
45pub mod eprocess_throttle;
46#[cfg(feature = "event-trace")]
47pub mod event_trace;
48pub mod evidence_bridges;
49pub mod evidence_sink;
50pub mod evidence_telemetry;
51pub mod flake_detector;
52pub mod flat_combine;
53pub mod input_fairness;
54pub mod input_macro;
55pub mod ivm;
56pub mod lens;
57pub mod locale;
58pub mod log_sink;
59pub mod metrics_registry;
60pub mod pane_keymap;
61pub mod policy_config;
62pub mod policy_registry;
63pub mod process_subscription;
64pub mod program;
65pub mod queueing_scheduler;
66#[cfg(feature = "render-thread")]
67pub mod render_thread;
68pub mod render_trace;
69pub mod resize_coalescer;
70pub mod resize_sla;
71pub mod retry;
72pub mod reversible;
73pub mod rough_path;
74pub mod schema_compat;
75pub mod simulator;
76pub mod slo;
77pub mod sos_barrier;
78pub mod state_persistence;
79#[cfg(feature = "stdio-capture")]
80pub mod stdio_capture;
81pub mod string_model;
82pub mod subscription;
83pub mod telemetry_schema;
84pub mod terminal_writer;
85pub mod tick_strategy;
86pub mod transparency;
87pub mod undo;
88pub mod unified_evidence;
89pub mod validation_pipeline;
90pub mod voi_sampling;
91pub mod wasm_runner;
92
93pub mod reactive;
94pub mod schedule_trace;
95#[cfg(feature = "telemetry")]
96pub mod telemetry;
97pub mod voi_telemetry;
98
99pub use asciicast::{AsciicastRecorder, AsciicastWriter};
100pub use cancellation::{CancellationSource, CancellationToken};
101pub use diff_evidence::{
102    DiffEvidenceLedger, DiffRegime, DiffStrategyRecord, Observation, RegimeTransition,
103};
104pub use evidence_sink::{EvidenceSink, EvidenceSinkConfig, EvidenceSinkDestination};
105pub use evidence_telemetry::{
106    BudgetDecisionSnapshot, ConformalSnapshot, DiffDecisionSnapshot, ResizeDecisionSnapshot,
107    budget_snapshot, clear_budget_snapshot, clear_diff_snapshot, clear_resize_snapshot,
108    diff_snapshot, resize_snapshot, set_budget_snapshot, set_diff_snapshot, set_resize_snapshot,
109};
110pub use ftui_backend::{BackendEventSource, BackendFeatures};
111#[cfg(feature = "native-backend")]
112pub use ftui_tty::TtyBackend;
113pub use input_macro::{
114    EventRecorder, FilteredEventRecorder, InputMacro, MacroPlayback, MacroPlayer, MacroRecorder,
115    RecordingFilter, RecordingState, TimedEvent,
116};
117pub use locale::{
118    Locale, LocaleContext, LocaleOverride, current_locale, detect_system_locale, set_locale,
119};
120pub use log_sink::LogSink;
121pub use process_subscription::{ProcessEvent, ProcessSubscription};
122#[cfg(feature = "crossterm-compat")]
123pub use program::CrosstermEventSource;
124pub use program::{
125    App, AppBuilder, BatchController, Cmd, EffectQueueConfig, FrameTiming, FrameTimingConfig,
126    FrameTimingSink, HeadlessEventSource, InlineAutoRemeasureConfig, LoadGovernorConfig, Model,
127    MouseCapturePolicy, PaneTerminalAdapter, PaneTerminalAdapterConfig, PaneTerminalDispatch,
128    PaneTerminalIgnoredReason, PaneTerminalLifecyclePhase, PaneTerminalLogEntry,
129    PaneTerminalLogOutcome, PaneTerminalSplitterHandle, PersistenceConfig, Program, ProgramConfig,
130    ResizeBehavior, RolloutPolicy, RuntimeLane, TaskExecutorBackend, TaskSpec, WidgetRefreshConfig,
131    pane_terminal_resolve_splitter_target, pane_terminal_splitter_handles,
132    pane_terminal_target_from_hit, register_pane_terminal_splitter_hits,
133};
134pub use render_trace::{
135    RENDER_TRACE_SCHEMA_VERSION, RenderTraceConfig, RenderTraceContext, RenderTraceFrame,
136    RenderTraceRecorder,
137};
138pub use retry::{BackoffStrategy, RetryPolicy, task_with_retry, task_with_timeout};
139pub use simulator::{ProgramSimulator, SimulatorError};
140pub use string_model::{StringModel, StringModelAdapter};
141pub use subscription::{Every, StopSignal, SubId, Subscription};
142pub use terminal_writer::{ScreenMode, TerminalWriter, UiAnchor, inline_active_widgets};
143pub use tick_strategy::{
144    ActiveOnly, ActivePlusAdjacent, AllocationCurve, Custom, DecayConfig, MarkovPredictor,
145    Predictive, PredictiveConfig, PredictiveStrategyConfig, ScreenPrediction, ScreenTickDispatch,
146    TickAllocation, TickDecision, TickStrategy, TickStrategyKind, TransitionCounter,
147    TransitionEntry, TransitionHistory, Uniform,
148};
149#[cfg(feature = "state-persistence")]
150pub use tick_strategy::{load_transitions, save_transitions};
151pub use voi_telemetry::{
152    clear_inline_auto_voi_snapshot, inline_auto_voi_snapshot, set_inline_auto_voi_snapshot,
153};
154
155#[cfg(feature = "render-thread")]
156pub use render_thread::{OutMsg, RenderThread};
157
158#[cfg(feature = "stdio-capture")]
159pub use stdio_capture::{CapturedWriter, StdioCapture, StdioCaptureError};
160
161pub use allocation_budget::{
162    AllocationBudget, BudgetAlert, BudgetConfig, BudgetEvidence, BudgetSummary,
163};
164pub use conformal_alert::{
165    AlertConfig, AlertDecision, AlertEvidence, AlertReason, AlertStats, ConformalAlert,
166};
167pub use conformal_frame_guard::{
168    ConformalFrameGuard, ConformalFrameGuardConfig, ConformalFrameGuardTelemetry, GuardState,
169    NonconformitySummary, P99Prediction,
170};
171pub use conformal_predictor::{
172    BucketKey, ConformalConfig, ConformalPrediction, ConformalPredictor, ConformalUpdate,
173    DiffBucket, ModeBucket,
174};
175pub use cost_model::{
176    BatchCostParams, BatchCostResult, CacheCostParams, CacheCostResult, PipelineCostParams,
177    PipelineCostResult, StageStats,
178};
179pub use decision_core::{
180    Action as DecisionAction, Decision, DecisionCore, Outcome as DecisionOutcome, Posterior,
181    State as DecisionState, argmin_expected_loss, second_best_loss,
182};
183pub use degradation_cascade::{
184    CascadeConfig, CascadeDecision, CascadeEvidence, CascadeTelemetry, DegradationCascade,
185    PreRenderResult,
186};
187pub use demo::{DemoDefinition, DemoParseError, DemoStep, parse_demo_yaml, validate_demos};
188pub use effect_system::{
189    QueueTelemetry, effects_command_total, effects_executed_total, effects_queue_dropped,
190    effects_queue_enqueued, effects_queue_high_water, effects_queue_processed,
191    effects_subscription_total, queue_telemetry, record_command_effect, record_subscription_start,
192    record_subscription_stop, trace_command_effect,
193};
194pub use eprocess_throttle::{
195    EProcessThrottle, ThrottleConfig, ThrottleDecision, ThrottleLog, ThrottleStats,
196    eprocess_rejections_total,
197};
198#[cfg(feature = "event-trace")]
199pub use event_trace::{
200    EventReplayer, EventTraceReader, EventTraceWriter, EvidenceMismatch, EvidenceVerifier,
201    SerDecisionDomain, SerEvidenceEntry, SerEvidenceTerm, TraceFile, TraceRecord,
202};
203pub use flake_detector::{EvidenceLog, FlakeConfig, FlakeDecision, FlakeDetector, FlakeSummary};
204pub use flat_combine::{CombinerStats, FlatCombiner};
205pub use lens::{AtIndex, Composed, Fst, Identity, Lens, Prism, Snd, SomePrism, at_index, compose};
206pub use metrics_registry::{
207    BuiltinCounter, BuiltinGauge, BuiltinHistogram, Counter as MetricsCounter,
208    Gauge as MetricsGauge, Histogram as MetricsHistogram, METRICS, MetricsRegistry,
209};
210pub use policy_config::{
211    BocpdPolicyConfig, CascadePolicyConfig, ConformalPolicyConfig, EProcessBudgetPolicyConfig,
212    EProcessThrottlePolicyConfig, EvidencePolicyConfig, FrameGuardPolicyConfig, PidPolicyConfig,
213    PolicyConfig, PolicyConfigError, VoiPolicyConfig,
214};
215pub use policy_registry::{PolicyRegistry, PolicyRegistryError, PolicySwitchEvent};
216pub use reactive::{BatchScope, Binding, BindingScope, Computed, Observable, TwoWayBinding};
217pub use resize_coalescer::{
218    CoalesceAction, CoalescerConfig, CoalescerStats, CycleTimePercentiles, DecisionLog,
219    DecisionSummary, Regime, ResizeCoalescer,
220};
221pub use resize_sla::{
222    ResizeEvidence, ResizeSlaMonitor, SlaConfig, SlaLogEntry, SlaSummary, make_sla_hooks,
223};
224pub use reversible::{
225    AddOp, InsertOp, Journal, MulOp, PushOp, RemoveOp, Reversible, Sequence, SetOp, SwapOp, XorOp,
226};
227pub use schema_compat::{
228    CompatCheckResult, Compatibility, MatrixEntry, SchemaKind, check_event_trace_compat,
229    check_evidence_compat, check_golden_trace_compat, check_render_trace_compat,
230    check_schema_compat, default_compatibility_matrix, run_compatibility_matrix,
231};
232pub use slo::{
233    BreachResult, BreachSeverity, MetricSlo, MetricType, SafeModeDecision, SloSchema,
234    SloSchemaError, check_breach, check_safe_mode, emit_slo_check, parse_slo_yaml, run_slo_check,
235};
236pub use undo::{
237    CommandBatch, CommandError, CommandMetadata, CommandResult, CommandSource, HistoryConfig,
238    HistoryManager, MergeConfig, TextDeleteCmd, TextInsertCmd, TextReplaceCmd, Transaction,
239    TransactionScope, UndoableCmd, WidgetId,
240};
241pub use unified_evidence::{
242    DecisionDomain, DomainSummary, EmitsEvidence, EvidenceEntry, EvidenceEntryBuilder,
243    EvidenceTerm, LedgerSummary, UnifiedEvidenceLedger,
244};
245pub use validation_pipeline::{
246    LedgerEntry, PipelineConfig, PipelineResult, PipelineSummary, ValidationOutcome,
247    ValidationPipeline, ValidatorStats,
248};
249pub use voi_sampling::{
250    DeferredRefinementConfig, DeferredRefinementPlan, DeferredRefinementScheduler,
251    RefinementCandidate, RefinementSelection, VoiConfig, VoiDecision, VoiLogEntry, VoiObservation,
252    VoiSampler, VoiSamplerSnapshot, VoiSummary, voi_samples_skipped_total, voi_samples_taken_total,
253};
254
255// State persistence
256#[cfg(feature = "state-persistence")]
257pub use state_persistence::FileStorage;
258pub use state_persistence::{
259    MemoryStorage, RegistryStats, StateRegistry, StorageBackend, StorageError, StorageResult,
260    StoredEntry,
261};
262
263pub use schedule_trace::{
264    CancelReason, GoldenCompareResult, IsomorphismProof, ScheduleTrace, SchedulerPolicy, TaskEvent,
265    TraceConfig, TraceEntry, TraceSummary, WakeupReason, compare_golden,
266};
267
268// Diff strategy (re-exports from ftui-render)
269pub use ftui_render::diff_strategy::{
270    DiffStrategy, DiffStrategyConfig, DiffStrategySelector, StrategyEvidence,
271};
272pub use terminal_writer::RuntimeDiffConfig;
273pub use wasm_runner::{RenderedFrame, StepResult, WasmRunner};
274
275#[cfg(feature = "telemetry")]
276pub use telemetry::{
277    DecisionEvidence, EnabledReason, EndpointSource, EvidenceLedger, Protocol, SCHEMA_VERSION,
278    SpanId, TelemetryConfig, TelemetryError, TelemetryGuard, TraceContextSource, TraceId,
279    is_safe_env_var, redact,
280};