prompt
js/tty/prompt.ts
fino:tty/prompt — interactive command-line prompts with non-interactive defaults.
PromptSession wraps the low-level fino:tty helpers and centralizes the
policy for CI or redirected input: prompts either return explicit defaults
or throw instead of blocking forever. The prompt surface intentionally covers
simple text, yes/no, and select questions only. Hidden input, multiline
editing, cancellation, fuzzy search, and full-screen terminal UI behavior are
outside this module's current contract.
import { PromptSession } from 'fino:tty/prompt';
const prompt = new PromptSession();
const project = await prompt.text({ label: 'Project name', defaultValue: 'app' });
const install = await prompt.confirm({ label: 'Install dependencies', defaultValue: true });
const template = await prompt.select({
label: 'Template',
options: [{ label: 'HTTP server', value: 'server' }, 'empty'],
defaultValue: 'server',
});
Interfaces
interface TextPromptOptions {
Options for a text prompt.
defaultValue is returned when the user submits an empty line and is also
used automatically in non-interactive sessions. validate may return an
error message to retry the prompt, or null/undefined to accept the value.
import { PromptSession } from 'fino:tty/prompt';
const prompt = new PromptSession();
const options = {
label: 'Project name',
defaultValue: 'app',
validate: (value) => value ? null : 'Name is required',
};
await prompt.text(options);
Properties
label: string
Label shown before the input field.
const options = { label: 'Project name' };
defaultValue?: string
Value used for empty input and non-interactive mode.
const options = { label: 'Project name', defaultValue: 'app' };
validate?: (value: string) => string | null | undefined
Optional validator that returns an error message when input is invalid.
const options = {
label: 'Port',
validate: (value: string) => Number(value) > 0 ? null : 'Enter a port',
};
interface ConfirmPromptOptions {
Options for a yes/no prompt.
defaultValue controls the hint (Y/n or y/N) and is returned when the
user submits an empty line. In non-interactive mode it is required.
import { PromptSession } from 'fino:tty/prompt';
const prompt = new PromptSession();
const options = {
label: 'Install dependencies',
defaultValue: true,
};
await prompt.confirm(options);
Properties
label: string
Question shown before the yes/no hint.
const options = { label: 'Continue' };
defaultValue?: boolean
Boolean returned for empty input and non-interactive mode.
const options = { label: 'Overwrite', defaultValue: false };
interface SelectPromptOptions {
Options for a select prompt.
Options may be strings, where label and value are the same, or objects with
separate display labels and returned values. In non-interactive mode,
defaultValue is returned without checking that it appears in options.
import { PromptSession } from 'fino:tty/prompt';
const prompt = new PromptSession();
const options = {
label: 'Template',
options: [{ label: 'HTTP server', value: 'server' }, 'empty'],
defaultValue: 'server',
};
await prompt.select(options);
Properties
label: string
Heading printed above the numbered choices.
const options = { label: 'Template', options: ['empty'] };
options: Array<{
label: string;
value: string;
} | string>
Choices accepted by number, exact label, or exact value.
const options = {
label: 'Template',
options: [{ label: 'HTTP server', value: 'server' }, 'empty'],
};
defaultValue?: string
Value returned for empty input and non-interactive mode.
const options = {
label: 'Template',
options: ['empty'],
defaultValue: 'empty',
};
interface PromptSessionOptions {
Constructor options for PromptSession.
Tests and CLI tools can inject custom read/write functions to avoid touching
process stdio. When isInteractive is false, prompts return defaults or
throw instead of reading from stdin.
import { PromptSession } from 'fino:tty/prompt';
const options = {
isInteractive: false,
readLine: async () => null,
write: async () => {},
writeError: async () => {},
};
const prompt = new PromptSession(options);
Properties
isInteractive?: boolean
Override automatic TTY detection.
const options = { isInteractive: false };
readLine?: (prompt: string) => Promise<string | null>
Function used to read one prompted line.
const options = { readLine: async (prompt: string) => 'answer' };
write?: (text: string) => Promise<void>
Function used for normal prompt output.
const options = { write: async (text: string) => {} };
writeError?: (text: string) => Promise<void>
Function used for validation and choice errors.
const options = { writeError: async (text: string) => {} };
Classes
class PromptSession {
Stateful prompt runner for text, confirm, and select questions.
import { PromptSession } from 'fino:tty/prompt';
const prompt = new PromptSession();
const name = await prompt.text({ label: 'Project name', defaultValue: 'app' });
const install = await prompt.confirm({ label: 'Install dependencies', defaultValue: true });
Properties
isInteractive: boolean
Whether this session may ask questions on stdin/stdout.
import { PromptSession } from 'fino:tty/prompt';
const prompt = new PromptSession({ isInteractive: false });
prompt.isInteractive; // false
Constructors
constructor(options: PromptSessionOptions = {})
Create a prompt session.
By default the session is interactive only when both stdin and stdout are
TTYs. Inject readLine, write, and writeError in tests or command
flows that need deterministic prompt behavior.
import { PromptSession } from 'fino:tty/prompt';
const prompt = new PromptSession({
isInteractive: true,
readLine: async () => 'yes',
write: async () => {},
writeError: async () => {},
});
Methods
async text(options: TextPromptOptions): Promise<string>
Ask for a text value, repeating until optional validation passes.
Empty input resolves to defaultValue when provided. In non-interactive
mode, this method returns defaultValue or throws if no default exists.
import { PromptSession } from 'fino:tty/prompt';
const prompt = new PromptSession();
const name = await prompt.text({ label: 'Name', defaultValue: 'app' });
async confirm(options: ConfirmPromptOptions): Promise<boolean>
Ask a yes/no question and return the selected boolean value.
Accepts y, yes, n, and no case-insensitively. Empty input uses
defaultValue when available.
import { PromptSession } from 'fino:tty/prompt';
const prompt = new PromptSession();
const proceed = await prompt.confirm({ label: 'Continue', defaultValue: true });
async select(options: SelectPromptOptions): Promise<string>
Ask the user to choose one labeled option and return its value.
The user may enter a one-based number, an exact label, or an exact value.
In non-interactive mode, this method returns defaultValue or throws if no
default exists.
import { PromptSession } from 'fino:tty/prompt';
const prompt = new PromptSession();
const template = await prompt.select({
label: 'Template',
options: [{ label: 'HTTP server', value: 'server' }, 'empty'],
defaultValue: 'server',
});
Functions
function createDefaultPrompt(): PromptSession
Create a PromptSession using the process standard input and output.
This is a convenience wrapper for new PromptSession(). The returned session
follows the same automatic TTY detection and non-interactive default policy.
import { createDefaultPrompt } from 'fino:tty/prompt';
const prompt = createDefaultPrompt();
const name = await prompt.text({ label: 'Name', defaultValue: 'app' });