tuil
Concepts

Architecture

Runtime ownership, package layers, lifecycle, and end-to-end control flow.

View rawEdit

System layers

Documentation flow diagram. subgraph Authoring and distribution; tuil CLI; component and skill registries; portable story catalog; end; subgraph Application boundary; TuilApp; Lifecycle
Documentation flow diagram. subgraph Authoring and distribution; tuil CLI; component and skill registries; portable story catalog; end; subgraph Application boundary; TuilApp; Lifecycle

The TuilApp instance is the ownership root. It constructs runtime services, registers plugins, exposes typed extension registries, and disposes resources in reverse ownership order.

Application lifecycle

Documentation flow diagram. [*] leads to configured; configured leads to initializing: initialize(); initializing leads to initialized: services + plugins ready; initialized leads to mounting: mount(); mounting leads to mounted: renderer attached; mounted leads to ready: ready(); ready leads to stopping: stop(); stopping leads to disposed: reverse teardown
Documentation flow diagram. [*] leads to configured; configured leads to initializing: initialize(); initializing leads to initialized: services + plugins ready; initialized leads to mounting: mount(); mounting leads to mounted: renderer attached; mounted leads to ready: ready(); ready leads to stopping: stop(); stopping leads to disposed: reverse teardown

Every stage has a matching app:* event. Errors are reported through app:error, then the configured error handler. Teardown is idempotent so error paths and normal exit share the same ownership rules.

Input flow

Documentation flow diagram. terminal bytes leads to Ink useInput; Ink leads to top overlay handler; Overlay leads to scoped input layer; Layer leads to hotkey manager; Hotkey leads to default focus traversal; Focus leads to semantic component callback; Component leads to runtime or application state; State leads to React rerender
Documentation flow diagram. terminal bytes leads to Ink useInput; Ink leads to top overlay handler; Overlay leads to scoped input layer; Layer leads to hotkey manager; Hotkey leads to default focus traversal; Focus leads to semantic component callback; Component leads to runtime or application state; State leads to React rerender

The first consumer that handles input stops the chain. Active overlays suppress application hotkeys, and input errors flow to app.reportError() instead of escaping through an unobserved promise.

Documentation flow diagram. participant UI as Component; participant Router as TerminalRouter; participant Guard as Guards; participant Loader as Loader; participant Focus as FocusManager; UI leads to >Router: navigate(target); Router leads to >Guard: before hooks; Guard leads to >Router: allow, redirect, or cancel
Documentation flow diagram. participant UI as Component; participant Router as TerminalRouter; participant Guard as Guards; participant Loader as Loader; participant Focus as FocusManager; UI leads to >Router: navigate(target); Router leads to >Guard: before hooks; Guard leads to >Router: allow, redirect, or cancel

Ownership rules

  • TuilApp owns core services, plugins, event definitions, and extension registries.
  • Providers own React subscriptions and unregister on unmount.
  • Every runtime registration returns a disposer.
  • Plugins deactivate and dispose in reverse dependency order.
  • Workflow runners and operation executors own abort controllers and observers.
  • Stories and tests always close render sessions, even after a failed action.

See Events, Extensibility, and the package reference for the concrete contracts.

On this page