<!-- Generated by scripts/gen-docs.ts from the TSDoc in src/. Do not edit by hand. -->

# `ask`

Source: [`src/ask.ts`](https://github.com/AI-for-dev/combo/blob/main/src/ask.ts)

Asking the *user* a question - the one place a workflow may block on a human.

This is a port, not an implementation: no pi, no terminal, no readline. The
extension supplies a pi dialog, an example supplies readline, a test supplies
a scripted array. That is the same rule as everywhere else here (a feature
must work from a script before it is exposed in the TUI), applied to input
rather than to display.

The shape is deliberately Claude Code's: **one question at a time**, a handful
of concrete options, free text always available, and a way to say "enough,
get on with it".

## `Answer`

*type*

```typescript
export type Answer = {
	/** The question as it was asked, so a transcript reads on its own. */
	question: string;
	/** A choice's `label`, or free text when `custom`. */
	answer: string;
	/** True when the user typed their own answer instead of picking one. */
	custom: boolean;
};
```

What came back: the question, the answer, and whether it was typed or picked.

## `Asking`

*type*

```typescript
export type Asking = {
	/**
	 * What the card takes. `open`, the default: one of the options, or a typed
	 * answer (`custom`). `closed`: one of the options only. `confirm`: yes or
	 * no, answered `"yes"` or `"no"`. `text`: a typed answer, `""` when left
	 * empty.
	 */
	readonly form?: "open" | "closed" | "confirm" | "text";
	/** Shown above the question, in order. */
	readonly context?: readonly Shown[];
	/** The visit path of whoever asks, when more than one may. */
	readonly visit?: string;
	/**
	 * The label of "that's enough". Absent: offered, in the card's own words.
	 * `false`: not offered, and declining is the run's stop.
	 */
	readonly enough?: string | false;
	/** Aborted when the question no longer stands, a timeout or a stop: the card closes, and its answer is not read. */
	readonly signal?: AbortSignal;
};
```

How a question is put, beyond the question itself: what a flow's `ask`
node says of its card. Nothing said is the interview's card.

## `AskUser`

*type*

```typescript
export type AskUser = (question: Question, asking?: Asking) => Promise<Answer | undefined>;
```

Puts one question to the user.

Returning `undefined` is the person declining. Where "that's enough" is
offered, it is **the submit**: the user has decided there is enough to go
on. It is not an error and not a cancellation of what came before - every
answer already given still counts. Where it is not, it is the stop.

## `Choice`

*type*

```typescript
export type Choice = {
	/** What the user reads and picks. A few words, not a sentence. */
	label: string;
	/** What choosing it commits to, when the label alone leaves that open. */
	description?: string;
};
```

One proposed answer. `description` says what picking it implies.

## `Question`

*type*

```typescript
export type Question = {
	/** Very short label for the question - a chip, not a sentence. */
	header?: string;
	/** The question itself, asked whole - it is also what a transcript keeps. */
	question: string;
	/** Two to four concrete, mutually exclusive options. */
	options: Choice[];
};
```

One question, in the shape a card can draw and a script can answer.

## `Shown`

*type*

```typescript
export type Shown = {
	/** The address it was read from, as the section's title. */
	readonly name: string;
	/** What it holds: a text as it is, a typed value as JSON, `""` when there is nothing. */
	readonly body: string;
};
```

A value shown above a question, under its name, so the person answers knowing what it is about.
