Skip to content

Terminal

The @effect/platform/Terminal module provides an abstraction for interacting with standard input and output, including reading user input and displaying messages on the terminal.

The module provides a single Terminal tag, which serves as the entry point to reading from and writing to standard input and standard output.

1
import {
import Terminal
Terminal
} from "@effect/platform"
2
import {
import Effect
Effect
} from "effect"
3
4
const
const program: Effect.Effect<void, never, Terminal.Terminal>
program
=
import Effect
Effect
.
const gen: <YieldWrap<Tag<Terminal.Terminal, Terminal.Terminal>>, void>(f: (resume: Effect.Adapter) => Generator<YieldWrap<Tag<Terminal.Terminal, Terminal.Terminal>>, void, never>) => Effect.Effect<...> (+1 overload)
gen
(function* () {
5
const
const terminal: Terminal.Terminal
terminal
= yield*
import Terminal
Terminal
.
const Terminal: Tag<Terminal.Terminal, Terminal.Terminal>

A `Terminal` represents a command-line interface which can read input from a user and display messages to a user.

Terminal
6
7
// use `terminal` to interact with standard input and output
8
})
1
import {
import Terminal
Terminal
} from "@effect/platform"
2
import {
import NodeRuntime
NodeRuntime
,
import NodeTerminal
NodeTerminal
} from "@effect/platform-node"
3
import {
import Effect
Effect
} from "effect"
4
5
const
const program: Effect.Effect<void, PlatformError, Terminal.Terminal>
program
=
import Effect
Effect
.
const gen: <YieldWrap<Tag<Terminal.Terminal, Terminal.Terminal>> | YieldWrap<Effect.Effect<void, PlatformError, never>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen
(function* () {
6
const
const terminal: Terminal.Terminal
terminal
= yield*
import Terminal
Terminal
.
const Terminal: Tag<Terminal.Terminal, Terminal.Terminal>

A `Terminal` represents a command-line interface which can read input from a user and display messages to a user.

Terminal
7
yield*
const terminal: Terminal.Terminal
terminal
.
(property) Terminal.display: (text: string) => Effect.Effect<void, PlatformError>

Displays text to the the default standard output.

display
("a message\n")
8
})
9
10
import NodeRuntime
NodeRuntime
.
const runMain: RunMain <PlatformError, void>(effect: Effect.Effect<void, PlatformError, never>, options?: { readonly disableErrorReporting?: boolean | undefined; readonly disablePrettyLogger?: boolean | undefined; readonly teardown?: Teardown | undefined; }) => void (+1 overload)
runMain
(
const program: Effect.Effect<void, PlatformError, Terminal.Terminal>
program
.
(method) Pipeable.pipe<Effect.Effect<void, PlatformError, Terminal.Terminal>, Effect.Effect<void, PlatformError, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<void, PlatformError, Terminal.Terminal>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect
Effect
.
const provide: <Terminal.Terminal, never, never>(layer: Layer<Terminal.Terminal, never, never>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<...> (+9 overloads)

Splits the context into two parts, providing one part using the specified layer/context/runtime and leaving the remainder `R0`

provide
(
import NodeTerminal
NodeTerminal
.
const layer: Layer<Terminal.Terminal, never, never>
layer
)))
11
// Output: "a message"
1
import {
import Terminal
Terminal
} from "@effect/platform"
2
import {
import NodeRuntime
NodeRuntime
,
import NodeTerminal
NodeTerminal
} from "@effect/platform-node"
3
import {
import Effect
Effect
} from "effect"
4
5
const
const program: Effect.Effect<void, Terminal.QuitException, Terminal.Terminal>
program
=
import Effect
Effect
.
const gen: <YieldWrap<Tag<Terminal.Terminal, Terminal.Terminal>> | YieldWrap<Effect.Effect<string, Terminal.QuitException, never>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen
(function* () {
6
const
const terminal: Terminal.Terminal
terminal
= yield*
import Terminal
Terminal
.
const Terminal: Tag<Terminal.Terminal, Terminal.Terminal>

A `Terminal` represents a command-line interface which can read input from a user and display messages to a user.

Terminal
7
const
const input: string
input
= yield*
const terminal: Terminal.Terminal
terminal
.
(property) Terminal.readLine: Effect.Effect<string, Terminal.QuitException, never>

Reads a single line from the default standard input.

readLine
8
namespace console var console: Console

The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```

console
.
(method) Console.log(message?: any, ...optionalParams: any[]): void

Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.

log
(`input: ${
const input: string
input
}`)
9
})
10
11
import NodeRuntime
NodeRuntime
.
const runMain: RunMain <Terminal.QuitException, void>(effect: Effect.Effect<void, Terminal.QuitException, never>, options?: { readonly disableErrorReporting?: boolean | undefined; readonly disablePrettyLogger?: boolean | undefined; readonly teardown?: Teardown | undefined; }) => void (+1 overload)
runMain
(
const program: Effect.Effect<void, Terminal.QuitException, Terminal.Terminal>
program
.
(method) Pipeable.pipe<Effect.Effect<void, Terminal.QuitException, Terminal.Terminal>, Effect.Effect<void, Terminal.QuitException, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect
Effect
.
const provide: <Terminal.Terminal, never, never>(layer: Layer<Terminal.Terminal, never, never>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<...> (+9 overloads)

Splits the context into two parts, providing one part using the specified layer/context/runtime and leaving the remainder `R0`

provide
(
import NodeTerminal
NodeTerminal
.
const layer: Layer<Terminal.Terminal, never, never>
layer
)))
12
// Input: "hello"
13
// Output: "input: hello"

This example demonstrates how to create a complete number-guessing game by reading input from the terminal and providing feedback to the user. The game continues until the user guesses the correct number.

1
import {
import Terminal
Terminal
} from "@effect/platform"
2
import type {
(alias) type PlatformError = BadArgument | SystemError (alias) namespace PlatformError import PlatformError
PlatformError
} from "@effect/platform/Error"
3
import {
import Effect
Effect
,
import Option
Option
,
import Random
Random
} from "effect"
4
import {
import NodeRuntime
NodeRuntime
,
import NodeTerminal
NodeTerminal
} from "@effect/platform-node"
5
6
const
const secret: Effect.Effect<number, never, never>
secret
=
import Random
Random
.
const nextIntBetween: (min: number, max: number) => Effect.Effect<number>

Returns the next integer value in the specified range from the pseudo-random number generator.

nextIntBetween
(1, 100)
7
8
const
const parseGuess: (input: string) => Option.None<number> | Option.Some<number>
parseGuess
= (
(parameter) input: string
input
: string) => {
9
const
const n: number
n
=
function parseInt(string: string, radix?: number): number

Converts a string to an integer.

parseInt
(
(parameter) input: string
input
, 10)
10
return
function isNaN(number: number): boolean

Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number).

isNaN
(
const n: number
n
) ||
const n: number
n
< 1 ||
const n: number
n
> 100 ?
import Option
Option
.
const none: <never>() => Option.Option<never>

Creates a new `Option` that represents the absence of a value.

none
() :
import Option
Option
.
const some: <number>(value: number) => Option.Option<number>

Creates a new `Option` that wraps the given value.

some
(
const n: number
n
)
11
}
12
13
const
const display: (message: string) => Effect.Effect<void, PlatformError, Terminal.Terminal>
display
= (
(parameter) message: string
message
: string) =>
14
import Effect
Effect
.
const gen: <YieldWrap<Tag<Terminal.Terminal, Terminal.Terminal>> | YieldWrap<Effect.Effect<void, PlatformError, never>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen
(function* () {
15
const
const terminal: Terminal.Terminal
terminal
= yield*
import Terminal
Terminal
.
const Terminal: Tag<Terminal.Terminal, Terminal.Terminal>

A `Terminal` represents a command-line interface which can read input from a user and display messages to a user.

Terminal
16
yield*
const terminal: Terminal.Terminal
terminal
.
(property) Terminal.display: (text: string) => Effect.Effect<void, PlatformError>

Displays text to the the default standard output.

display
(`${
(parameter) message: string
message
}\n`)
17
})
18
19
const
const prompt: Effect.Effect<string, PlatformError | Terminal.QuitException, Terminal.Terminal>
prompt
=
import Effect
Effect
.
const gen: <YieldWrap<Tag<Terminal.Terminal, Terminal.Terminal>> | YieldWrap<Effect.Effect<void, PlatformError, never>> | YieldWrap<...>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen
(function* () {
20
const
const terminal: Terminal.Terminal
terminal
= yield*
import Terminal
Terminal
.
const Terminal: Tag<Terminal.Terminal, Terminal.Terminal>

A `Terminal` represents a command-line interface which can read input from a user and display messages to a user.

Terminal
21
yield*
const terminal: Terminal.Terminal
terminal
.
(property) Terminal.display: (text: string) => Effect.Effect<void, PlatformError>

Displays text to the the default standard output.

display
("Enter a guess: ")
22
return yield*
const terminal: Terminal.Terminal
terminal
.
(property) Terminal.readLine: Effect.Effect<string, Terminal.QuitException, never>

Reads a single line from the default standard input.

readLine
23
})
24
25
const
const answer: Effect.Effect<number, PlatformError | Terminal.QuitException, Terminal.Terminal>
answer
:
import Effect
Effect
.
interface Effect<out A, out E = never, out R = never> namespace Effect

The `Effect` interface defines a value that lazily describes a workflow or job. The workflow requires some context `R`, and may fail with an error of type `E`, or succeed with a value of type `A`. `Effect` values model resourceful interaction with the outside world, including synchronous, asynchronous, concurrent, and parallel interaction. They use a fiber-based concurrency model, with built-in support for scheduling, fine-grained interruption, structured concurrency, and high scalability. To run an `Effect` value, you need a `Runtime`, which is a type that is capable of executing `Effect` values.

Effect
<
26
number,
27
import Terminal
Terminal
.
class QuitException

A `QuitException` represents an exception that occurs when a user attempts to quit out of a `Terminal` prompt for input (usually by entering `ctrl`+`c`).

QuitException
|
(alias) type PlatformError = BadArgument | SystemError (alias) namespace PlatformError import PlatformError
PlatformError
,
28
import Terminal
Terminal
.
interface Terminal

A `Terminal` represents a command-line interface which can read input from a user and display messages to a user.

Terminal
29
> =
import Effect
Effect
.
const gen: <YieldWrap<Effect.Effect<number, PlatformError | Terminal.QuitException, Terminal.Terminal>> | YieldWrap<Effect.Effect<string, PlatformError | Terminal.QuitException, Terminal.Terminal>> | YieldWrap<...>, number>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen
(function* () {
30
const
const input: string
input
= yield*
const prompt: Effect.Effect<string, PlatformError | Terminal.QuitException, Terminal.Terminal>
prompt
31
const
const guess: Option.None<number> | Option.Some<number>
guess
=
const parseGuess: (input: string) => Option.None<number> | Option.Some<number>
parseGuess
(
const input: string
input
)
32
if (
import Option
Option
.
const isNone: <number>(self: Option.Option<number>) => self is Option.None<number>

Determine if a `Option` is a `None`.

isNone
(
const guess: Option.None<number> | Option.Some<number>
guess
)) {
33
yield*
const display: (message: string) => Effect.Effect<void, PlatformError, Terminal.Terminal>
display
("You must enter an integer from 1 to 100")
34
return yield*
const answer: Effect.Effect<number, PlatformError | Terminal.QuitException, Terminal.Terminal>
answer
35
}
36
return
const guess: Option.Some<number>
guess
.
(property) Some<number>.value: number
value
37
})
38
39
const
const check: <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>) => Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
check
= <
(type parameter) A in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
A
,
(type parameter) E in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
E
,
(type parameter) R in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
R
>(
40
(parameter) secret: number
secret
: number,
41
(parameter) guess: number
guess
: number,
42
(parameter) ok: Effect.Effect<A, E, R>
ok
:
import Effect
Effect
.
interface Effect<out A, out E = never, out R = never> namespace Effect

The `Effect` interface defines a value that lazily describes a workflow or job. The workflow requires some context `R`, and may fail with an error of type `E`, or succeed with a value of type `A`. `Effect` values model resourceful interaction with the outside world, including synchronous, asynchronous, concurrent, and parallel interaction. They use a fiber-based concurrency model, with built-in support for scheduling, fine-grained interruption, structured concurrency, and high scalability. To run an `Effect` value, you need a `Runtime`, which is a type that is capable of executing `Effect` values.

Effect
<
(type parameter) A in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
A
,
(type parameter) E in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
E
,
(type parameter) R in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
R
>,
43
(parameter) ko: Effect.Effect<A, E, R>
ko
:
import Effect
Effect
.
interface Effect<out A, out E = never, out R = never> namespace Effect

The `Effect` interface defines a value that lazily describes a workflow or job. The workflow requires some context `R`, and may fail with an error of type `E`, or succeed with a value of type `A`. `Effect` values model resourceful interaction with the outside world, including synchronous, asynchronous, concurrent, and parallel interaction. They use a fiber-based concurrency model, with built-in support for scheduling, fine-grained interruption, structured concurrency, and high scalability. To run an `Effect` value, you need a `Runtime`, which is a type that is capable of executing `Effect` values.

Effect
<
(type parameter) A in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
A
,
(type parameter) E in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
E
,
(type parameter) R in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
R
>
44
) =>
45
import Effect
Effect
.
const gen: <YieldWrap<Effect.Effect<void, PlatformError, Terminal.Terminal>> | YieldWrap<Effect.Effect<A, E, R>>, A>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen
(function* () {
46
if (
(parameter) guess: number
guess
>
(parameter) secret: number
secret
) {
47
yield*
const display: (message: string) => Effect.Effect<void, PlatformError, Terminal.Terminal>
display
("Too high")
48
return yield*
(parameter) ko: Effect.Effect<A, E, R>
ko
49
} else if (
(parameter) guess: number
guess
<
(parameter) secret: number
secret
) {
50
yield*
const display: (message: string) => Effect.Effect<void, PlatformError, Terminal.Terminal>
display
("Too low")
51
return yield*
(parameter) ko: Effect.Effect<A, E, R>
ko
52
} else {
53
return yield*
(parameter) ok: Effect.Effect<A, E, R>
ok
54
}
55
})
56
57
const
const end: Effect.Effect<void, PlatformError, Terminal.Terminal>
end
=
const display: (message: string) => Effect.Effect<void, PlatformError, Terminal.Terminal>
display
("You guessed it!")
58
59
const
const loop: (secret: number) => Effect.Effect<void, Terminal.QuitException | PlatformError, Terminal.Terminal>
loop
= (
60
(parameter) secret: number
secret
: number
61
):
import Effect
Effect
.
interface Effect<out A, out E = never, out R = never> namespace Effect

The `Effect` interface defines a value that lazily describes a workflow or job. The workflow requires some context `R`, and may fail with an error of type `E`, or succeed with a value of type `A`. `Effect` values model resourceful interaction with the outside world, including synchronous, asynchronous, concurrent, and parallel interaction. They use a fiber-based concurrency model, with built-in support for scheduling, fine-grained interruption, structured concurrency, and high scalability. To run an `Effect` value, you need a `Runtime`, which is a type that is capable of executing `Effect` values.

Effect
<
62
void,
63
import Terminal
Terminal
.
class QuitException

A `QuitException` represents an exception that occurs when a user attempts to quit out of a `Terminal` prompt for input (usually by entering `ctrl`+`c`).

QuitException
|
(alias) type PlatformError = BadArgument | SystemError (alias) namespace PlatformError import PlatformError
PlatformError
,
64
import Terminal
Terminal
.
interface Terminal

A `Terminal` represents a command-line interface which can read input from a user and display messages to a user.

Terminal
65
> =>
66
import Effect
Effect
.
const gen: <YieldWrap<Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen
(function* () {
67
const
const guess: number
guess
= yield*
const answer: Effect.Effect<number, PlatformError | Terminal.QuitException, Terminal.Terminal>
answer
68
return yield*
const check: <void, PlatformError | Terminal.QuitException, Terminal.Terminal>(secret: number, guess: number, ok: Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>, ko: Effect.Effect<...>) => Effect.Effect<...>
check
(
69
(parameter) secret: number
secret
,
70
const guess: number
guess
,
71
const end: Effect.Effect<void, PlatformError, Terminal.Terminal>
end
,
72
import Effect
Effect
.
const suspend: <void, PlatformError | Terminal.QuitException, Terminal.Terminal>(effect: LazyArg<Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>>) => Effect.Effect<...>
suspend
(() =>
const loop: (secret: number) => Effect.Effect<void, Terminal.QuitException | PlatformError, Terminal.Terminal>
loop
(
(parameter) secret: number
secret
))
73
)
74
})
75
76
const
const game: Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>
game
=
import Effect
Effect
.
const gen: <YieldWrap<Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen
(function* () {
77
yield*
const display: (message: string) => Effect.Effect<void, PlatformError, Terminal.Terminal>
display
(
78
`We have selected a random number between 1 and 100.
79
See if you can guess it in 10 turns or fewer.
80
We'll tell you if your guess was too high or too low.`
81
)
82
yield*
const loop: (secret: number) => Effect.Effect<void, Terminal.QuitException | PlatformError, Terminal.Terminal>
loop
(yield*
const secret: Effect.Effect<number, never, never>
secret
)
83
})
84
85
import NodeRuntime
NodeRuntime
.
const runMain: RunMain <PlatformError | Terminal.QuitException, void>(effect: Effect.Effect<void, PlatformError | Terminal.QuitException, never>, options?: { readonly disableErrorReporting?: boolean | undefined; readonly disablePrettyLogger?: boolean | undefined; readonly teardown?: Teardown | undefined; }) => void (+1 overload)
runMain
(
const game: Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>
game
.
(method) Pipeable.pipe<Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>, Effect.Effect<void, PlatformError | Terminal.QuitException, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe
(
import Effect
Effect
.
const provide: <Terminal.Terminal, never, never>(layer: Layer<Terminal.Terminal, never, never>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<...> (+9 overloads)

Splits the context into two parts, providing one part using the specified layer/context/runtime and leaving the remainder `R0`

provide
(
import NodeTerminal
NodeTerminal
.
const layer: Layer<Terminal.Terminal, never, never>
layer
)))