caique
API reference

caique/decide

Every export of caique/decide, with its signature and doc comment: decide, plus 4 types.

import { decide } from 'caique/decide';

Functions

decide

The rule, in order, and the order is the argument:

  1. A value from any source wins. Prompting for something already answered is how a script that sets an env var still ends up waiting for input.
  2. --json never prompts. It means "a machine is reading this", and there is no answer a machine can type.
  3. --yes answers a confirm, and only a confirm — it is not a licence to invent a path or a password.
  4. Nobody there — no terminal on stdin, CI set, or an agent driving the process — means refuse, naming the flag. That is roundel's interactive(), so CLAUDECODE=1 on a terminal refuses here exactly as burgee's own agent detection does; asking isTTY.stdin && !CI alone prompted an agent that has a terminal and no person, and hung it. FORCE_TTY=1 is the one override, as it is everywhere in the family.
  5. --interactive reaches past 4 only when there is a terminal; it is an override for "you would not have asked", never for "there is no one to ask".
  6. Otherwise, if it is required or --interactive was asked for, prompt.
function decide({ value, spec, option, runtime, flags, required }: DecideInput): Decision;
ParameterType
{ value, spec, option, runtime, flags, required }DecideInput

Returns Decision

Interfaces

DecideInput

interface DecideInput {
    /** Whatever the option resolved to before prompting, from any source. */
    value: unknown;
    spec: PromptSpec;
    /** The option's long name, for the flag a refusal names. */
    option: string;
    runtime: Runtime;
    flags?: Flags;
    /** Whether the option must have a value for the command to run. */
    required?: boolean;
}

Decision

interface Decision {
    action: 'skip' | 'prompt' | 'answer' | 'error';
    /** For `answer`: what to use without asking. Today only `--yes` produces one. */
    value?: boolean;
    /** For `error`: an E1 code the caller maps to its own error type. */
    code?: 'USAGE';
    message?: string;
    /** For `error`: the one sentence that turns a refusal into a next step. */
    fix?: string;
}

Flags

What the run was asked for, as the engine knows it — never sniffed from the process.

interface Flags {
    /** `--json`: a machine is reading stdout, so no one is here to type (R6). */
    json?: boolean;
    /** `--yes`: every `confirm` is already answered true (R3). */
    yes?: boolean;
    /** `--interactive`: prompt for what is missing even where we would not have (R3). */
    interactive?: boolean;
    /** `--interactive=all`: prompt for every promptable option, not only the required ones. */
    interactiveAll?: boolean;
}

Runtime

The slice of a runtime this needs. burgee's satisfies it; so does a literal in a test.

interface Runtime {
    env: Record<string, string | undefined>;
    isTTY: {
        stdin: boolean;
    };
}

On this page