What is the problem this feature would solve?
Every CLI branches on whether it is talking to a person: prompt or fail on a missing value, spinner or plain lines, color or none. Nothing in the platform answers that.
Stdio exposes args, stdin, stdout(), stderr(). Terminal exposes columns, rows, readInput, readLine, display. Neither says whether those streams are attached to a terminal, and no platform implementation surfaces it.
The only route is process.stdin.isTTY, which reaches past the platform package entirely — the same code reads Node globals when running on the Deno or Bun layer — and cannot be substituted in a test, so the branch that most needs covering is the one that can't be exercised.
What is the feature you are proposing to solve the problem?
Add it to Stdio, beside the streams it already describes, in the same shape as args:
export interface Stdio {
// ...
readonly stdinIsTerminal: Effect.Effect<boolean>
readonly stdoutIsTerminal: Effect.Effect<boolean>
}
### What alternatives have you considered?
- **Reading `process.stdin.isTTY` directly** — what we do now, confined to a single
`Context.Reference` so the rest of the CLI branches on a value a test can substitute.
It works, but it defeats the platform abstraction: nothing in the layer is doing the
work, and the Deno and Bun layers inherit Node's globals by accident.
- **Inferring it from `Terminal.columns`** — on Node it happens to work, since
`stdout.columns ?? 0` yields `0` for a pipe. That is an undocumented sentinel, it
conflates "not a terminal" with "zero-width terminal", and it only ever answers for
stdout — while stdin is what decides whether prompting is possible at all.
- **Putting it on `Terminal`** — TTY-ness is a property of the streams, which is what
`Stdio` describes, and it has to be answerable when no `Terminal` is wired.
What is the problem this feature would solve?
Every CLI branches on whether it is talking to a person: prompt or fail on a missing value, spinner or plain lines, color or none. Nothing in the platform answers that.
Stdioexposesargs,stdin,stdout(),stderr().Terminalexposescolumns,rows,readInput,readLine,display. Neither says whether those streams are attached to a terminal, and no platform implementation surfaces it.The only route is
process.stdin.isTTY, which reaches past the platform package entirely — the same code reads Node globals when running on the Deno or Bun layer — and cannot be substituted in a test, so the branch that most needs covering is the one that can't be exercised.What is the feature you are proposing to solve the problem?
Add it to
Stdio, beside the streams it already describes, in the same shape asargs: