prompts

package module
v1.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

README

prompts

CI Documentation Go Reference Release Go License

prompts is an explicit, typed foundation for interactive terminal prompts and deterministic non-interactive fallbacks. Callers own the context, streams, terminal capabilities, interaction authority, and lifecycle.

The v1.1.2 patch preserves the stable v1 API. Its automated prompt, rendering, terminal, headless, security, test, and release contracts are implemented and remain subject to compatibility review. The recorded manual terminal and assistive-technology matrix is available in Accessibility review evidence.

Adoption entry points

The root module is github.com/faustbrian/go-prompts (stable). It requires Go 1.27.0. Pin the published v1.1.3 root tag with go get github.com/faustbrian/go-prompts@v1.1.3. Install only the modules your application imports; nested module status and migration boundaries remain documented separately.

Start with the documentation map for package selection, examples, operational constraints, and contributor references.

Installation

go get github.com/faustbrian/go-prompts@v1.1.2

The target-oriented terminal adapter described below is available in v1.1.0. Existing consumers can continue to import the compatibility path at github.com/faustbrian/go-prompts/terminal.

Explicit non-interactive input uses the same typed parser and validation pipeline without authorizing a terminal read:

count, err := prompts.NewInteger(prompts.IntegerConfig{
    ID: "count", Label: "Count",
})
if err != nil { /* invalid definition */ }

value, err := prompts.Parse(ctx, count, configuredCount, dependencies)

Parse supports text, multiline text, confirmation, signed integers, exact decimals, Go durations, ISO dates, wall-clock times, and paths. Path parsing does not inspect or mutate the filesystem.

Secret definitions require an explicit classification. Their values redact formatting, serialization, and structured logging by default; access requires an explicit Reveal call. See Secret handling for the limits of string and byte cleanup.

Interactive execution requires caller authority plus explicit EventSource, TerminalController, and output resources. The core never decodes a process stream or acquires global terminal state on its own. See Interactive input.

The optional real-terminal implementation is github.com/faustbrian/go-prompts/adapters/terminal. The original github.com/faustbrian/go-prompts/terminal path remains as a deprecated, behavior-identical compatibility facade.

Ordered heterogeneous prompts compose through NewForm, AsField, and When; typed answers are recovered with FormValue. See Forms.

Progress, spinners, bounded status streams, messages, tables, and summaries are caller-driven presentation values. See Progress and presentation.

Documentation

Executable examples in example_test.go cover explicit input, headless fallback, virtual-terminal interaction, forms, progress, and tables.

Package map

Use prompts when an application needs typed, bounded interaction or the same validation pipeline for explicit non-interactive input. Do not use it as a command framework, configuration loader, application lifecycle, or source of ambient terminal authority.

Development

Go 1.27.2 is the verification producer; the module minimum remains Go 1.27.0. Direct root tests run with GOWORK=off so the module is verified independently of sibling checkouts.

make check
make ci
make check-full

Ordinary checks use the published tool pinned in .golib.yaml, including deterministic secret/terminal cleanup and a targeted progress/task race. Base-free checks run fuzz seeds; changed-source CI selects active smoke. check-full retains packaging reproducibility, accessibility-tool checks, all full fuzz budgets and benchmarks. See contributor verification for isolated tests, tool installation, disposable-cache sessions and explicit release rehearsal.

Ecosystem

For ecosystem-wide selection and ownership guidance, see the versioned Golib ecosystem index and its Tooling family.

Licensed under Apache-2.0.

Documentation

Overview

Package prompts provides explicit, typed terminal interactions without consulting process-wide streams, environment variables, or terminal state. Start with NewText or a typed constructor, Parse for explicit input, and Run for caller-authorized interaction. Definitions copy callback/option slices, not arbitrary generic values or callback state; callers own their concurrent reuse and dependencies. Interactive limits do not cap explicit Parse input or arbitrary presentation text. Callbacks, writers and terminal cleanup are synchronous and cooperative; no worker, timeout or physical terminal is owned. Secret redaction is not access control or complete memory erasure. The optional adapters/terminal package owns platform operations on borrowed files; benchmark comparison and manual review scripts are separate operational surfaces.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrInteractionNotPermitted is the errors.Is sentinel for refused interaction or
	// default authority.
	ErrInteractionNotPermitted error = sentinelError(ErrorInteractionNotPermitted)
	// ErrTerminalUnavailable is the errors.Is sentinel for absent terminal
	// resources/capabilities.
	ErrTerminalUnavailable error = sentinelError(ErrorTerminalUnavailable)
	// ErrCanceled is the errors.Is sentinel for canceled execution.
	ErrCanceled error = sentinelError(ErrorCanceled)
	// ErrDeadlineExceeded is the errors.Is sentinel for an expired caller deadline.
	ErrDeadlineExceeded error = sentinelError(ErrorDeadlineExceeded)
	// ErrEndOfInput is the errors.Is sentinel for unresolved EOF.
	ErrEndOfInput error = sentinelError(ErrorEndOfInput)
	// ErrTerminalDetached is the errors.Is sentinel for lost terminal attachment.
	ErrTerminalDetached error = sentinelError(ErrorTerminalDetached)
	// ErrInvalidDefinition is the errors.Is sentinel for invalid
	// definitions/configuration.
	ErrInvalidDefinition error = sentinelError(ErrorInvalidDefinition)
	// ErrUnsupported is the errors.Is sentinel for unsupported operations/configuration.
	ErrUnsupported error = sentinelError(ErrorUnsupported)
	// ErrValidationExhausted is the errors.Is sentinel for rejected validation or
	// exhausted retries.
	ErrValidationExhausted error = sentinelError(ErrorValidationExhausted)
	// ErrRenderer is the errors.Is sentinel for renderer failures.
	ErrRenderer error = sentinelError(ErrorRenderer)
	// ErrReader is the errors.Is sentinel for input/event read failures.
	ErrReader error = sentinelError(ErrorReader)
	// ErrWriter is the errors.Is sentinel for output write failures.
	ErrWriter error = sentinelError(ErrorWriter)
	// ErrTerminalControl is the errors.Is sentinel for terminal
	// configuration/restoration failures.
	ErrTerminalControl error = sentinelError(ErrorTerminalControl)
	// ErrAdapter is the errors.Is sentinel for adapter or contained callback failures.
	ErrAdapter error = sentinelError(ErrorAdapter)
)

Functions

func FormValue

func FormValue[T any](result FormResult, identity string) (T, bool)

FormValue returns the answer using the prompt's clone policy: owned slice and SecretBytes policies copy containers, but arbitrary generic references remain shallow. Wrong identity/type returns zero,false. Reveal/byte copies need caller cleanup.

func Parse

func Parse[T any](
	ctx context.Context,
	prompt Prompt[T],
	input string,
	dependencies any,
) (T, error)

Parse converts explicit caller-supplied input and applies the prompt's typed validation pipeline without acquiring terminal input.

Example
package main

import (
	"context"
	"fmt"

	prompts "github.com/faustbrian/go-prompts"
)

func main() {
	prompt, err := prompts.NewInteger(prompts.IntegerConfig{ID: "workers", Label: "Workers"})
	if err != nil {
		panic(err)
	}
	workers, err := prompts.Parse(context.Background(), prompt, "4", nil)
	fmt.Println(workers, err)
}
Output:
4 <nil>

func Run

func Run[T any](ctx context.Context, prompt Prompt[T], execution Execution) (T, error)

Run executes a typed prompt without consulting process-wide streams or environment state. Nil/canceled contexts fail before execution. Headless defaults need PermitDefaults, but fallback and explicit cancel/EOF resolutions have their own configured authority. Validation failures can return a partial typed value with an error; errors govern success. Arbitrary callbacks/writers are synchronous and cannot be forcibly canceled; their retained values and resource concurrency remain caller-owned. Ordinary acquired-session cleanup attempts echo restoration and release; cleanup errors discard a successful value. External event/renderer/terminal panics are not globally isolated.

Example (HeadlessFallback)
package main

import (
	"context"
	"fmt"

	prompts "github.com/faustbrian/go-prompts"
)

func main() {
	prompt, err := prompts.NewText(
		prompts.TextConfig{
			ID:       "region",
			Label:    "Region",
			Headless: prompts.HeadlessUseFallback,
			Fallback: prompts.Some("eu-west-1"),
		},
	)
	if err != nil {
		panic(err)
	}
	region, err := prompts.Run(
		context.Background(),
		prompt,
		prompts.Execution{
			Policy: prompts.InteractionPolicy{Mode: prompts.NonInteractiveOnly},
		},
	)
	fmt.Println(region, err)
}
Output:
eu-west-1 <nil>
Example (VirtualTerminal)
package main

import (
	"context"
	"fmt"

	prompts "github.com/faustbrian/go-prompts"
)

func main() {
	prompt, err := prompts.NewConfirm(prompts.ConfirmConfig{ID: "continue", Label: "Continue"})
	if err != nil {
		panic(err)
	}
	terminal := prompts.NewVirtualTerminal(80, 24)
	if err := terminal.Push(prompts.PasteEvent("yes"), prompts.KeyEvent(prompts.KeyEnter)); err != nil {
		panic(err)
	}
	answer, err := prompts.Run(
		context.Background(),
		prompt,
		prompts.Execution{
			Events:   terminal,
			Terminal: terminal,
			Output:   terminal,
			Capabilities: prompts.Capabilities{
				InputTerminal:  true,
				OutputTerminal: true,
				Width:          80,
				Height:         24,
			},
			Policy: prompts.InteractionPolicy{
				Mode:              prompts.InteractiveRequired,
				PermitInteraction: true,
			},
		},
	)
	fmt.Println(answer, err, terminal.Released())
}
Output:
true <nil> true

func Sanitize

func Sanitize(content string) string

Sanitize neutralizes terminal controls, carriage returns, bidi controls, and invalid UTF-8 while preserving line feeds for semantic layout.

func WriteMessage

func WriteMessage(ctx context.Context, message Message, execution Execution) error

WriteMessage writes a deterministic semantic note without terminal state.

func WriteSummary

func WriteSummary(ctx context.Context, values []KeyValue, execution Execution) error

WriteSummary renders declaration-order key/value lines.

func WriteTable

func WriteTable(ctx context.Context, table Table, execution Execution) error

WriteTable renders a deterministic Unicode-width-aligned linear table.

Example
package main

import (
	"context"
	"os"

	prompts "github.com/faustbrian/go-prompts"
)

func main() {
	err := prompts.WriteTable(
		context.Background(),
		prompts.Table{
			Headers: []string{"Name", "State"},
			Rows:    [][]string{{"api", "ready"}},
		},
		prompts.Execution{Output: os.Stdout},
	)
	if err != nil {
		panic(err)
	}
}
Output:
| Name | State |
| api  | ready |

Types

type ANSIRenderer

type ANSIRenderer struct {
	// Theme is immutable style/marker configuration; zero resolves to DefaultTheme.
	Theme Theme
}

ANSIRenderer emits capability-limited ANSI styling and safe OSC 8 hyperlinks. ColorNone disables styling; explicitly permitted hyperlinks can still emit OSC.

func (ANSIRenderer) Render

func (renderer ANSIRenderer) Render(frame Frame, options RenderOptions) (string, error)

Render emits sanitized linear text with capability-selected ANSI/OSC controls. ColorNone disables styling but Hyperlinks can still permit safe OSC 8 links.

type Accessibility

type Accessibility struct {
	// Label is caller-localized raw display text, sanitized by owned rendering.
	Label string
	// Description is optional raw explanatory text with no universal byte ceiling.
	Description string
	// TextualHint adds localized linear navigation guidance independent of color.
	TextualHint string
}

Accessibility provides caller-localized linear rendering metadata.

type AutoRules

type AutoRules struct {
	// RequireInputTerminal requires input-terminal evidence only in AutoDetect mode.
	RequireInputTerminal bool
	// RequireOutputTerminal requires output-terminal evidence only in AutoDetect mode.
	RequireOutputTerminal bool
}

AutoRules are caller-selected conditions for AutoDetect. Terminal detection is never sufficient without PermitInteraction.

type CancelBehavior

type CancelBehavior uint8

CancelBehavior defines the result of an explicit cancel event.

const (
	// CancelReturnError returns ErrCanceled for explicit cancellation.
	CancelReturnError CancelBehavior = iota
	// CancelUseDefault runs the present typed default through validation on explicit
	// cancel.
	CancelUseDefault
	// CancelUseFallback runs the present fallback through validation on explicit cancel.
	CancelUseFallback
)

type Capabilities

type Capabilities struct {
	// InputTerminal reports explicit input-terminal evidence, independent of authority.
	InputTerminal bool
	// OutputTerminal reports explicit output-terminal evidence, independent of
	// authority.
	OutputTerminal bool
	// Width is initial output width; zero disables owned-renderer wrapping.
	Width int
	// Height controls selection pagination, not rendered-output bytes.
	Height int
	// Color selects output profile; zero is plain.
	Color ColorProfile
	// CursorMovement is metadata; owned rendering is linear, not cursor-updating.
	CursorMovement bool
	// Hyperlinks permits owned OSC 8 output with ANSIRenderer.
	Hyperlinks bool
	// Animation permits caller-selected spinner frames, not a timer or scheduler.
	Animation bool
	// Unicode permits native Unicode; false uses visible ASCII escapes.
	Unicode bool
}

Capabilities are supplied by the caller or an explicit application adapter.

type Clock

type Clock interface {
	// Now returns implementation time; callers choose its authority and concurrency.
	Now() time.Time
	// NewTimer creates an owned timer for caller stop/cleanup.
	NewTimer(time.Duration) Timer
	// NewTicker creates an owned ticker for caller stop/cleanup.
	NewTicker(time.Duration) Ticker
}

Clock is an explicit caller-owned timing seam for sessions and presentation.

type Color

type Color struct {
	// contains filtered or unexported fields
}

Color is a semantic terminal color value.

func ANSI

func ANSI(index uint8) Color

ANSI creates an indexed ANSI color.

func RGB

func RGB(red, green, blue uint8) Color

RGB creates a true-color value that renderers downsample when required.

type ColorProfile

type ColorProfile uint8

ColorProfile describes the color output explicitly supported by a terminal.

const (
	// ColorNone disables ANSI styling.
	ColorNone ColorProfile = iota
	// ColorANSI16 selects sixteen-color output and downsampling.
	ColorANSI16
	// ColorANSI256 selects indexed 256-color output.
	ColorANSI256
	// ColorTrueColor permits explicit RGB ANSI colors.
	ColorTrueColor
)

type ConfirmConfig

type ConfirmConfig struct {
	// ID, Label, Description, Placeholder, Hint, Help identify and describe the prompt;
	// ID/Label are required, other text is optional and sanitized at owned presentation
	// boundaries.
	ID, Label, Description, Placeholder, Hint, Help string
	// Default, Fallback distinguish present typed values from omission; execution
	// follows the selected behavior and caller authority.
	Default, Fallback Optional[bool]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate, PostValidate are ordered callbacks before/after transformations;
	// slices are copied, callback state and context cooperation are not owned.
	PreValidate, PostValidate []Validator[bool]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[bool]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
	// Accept, Reject are copied true/false spellings; empty slices use defaults, values
	// trim/lowercase and must not overlap.
	Accept, Reject []string
}

ConfirmConfig defines a localized yes/no prompt.

type Date

type Date struct {
	// contains filtered or unexported fields
}

Date is a calendar date without a time zone or time of day.

func (Date) Day

func (date Date) Day() int

Day returns the one-based day of the month.

func (Date) Month

func (date Date) Month() time.Month

Month returns the Gregorian calendar month.

func (Date) String

func (date Date) String() string

String formats stored calendar fields; the zero value is not a validated date.

func (Date) Year

func (date Date) Year() int

Year returns the proleptic Gregorian calendar year.

type DateConfig

type DateConfig struct {
	// ID, Label, Description, Placeholder, Hint, Help identify and describe the prompt;
	// ID/Label are required, other text is optional and sanitized at owned presentation
	// boundaries.
	ID, Label, Description, Placeholder, Hint, Help string
	// Default, Fallback distinguish present typed values from omission; execution
	// follows the selected behavior and caller authority.
	Default, Fallback Optional[Date]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate, PostValidate are ordered callbacks before/after transformations;
	// slices are copied, callback state and context cooperation are not owned.
	PreValidate, PostValidate []Validator[Date]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[Date]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
}

DateConfig defines an ISO calendar-date prompt.

type Decimal

type Decimal struct {
	// contains filtered or unexported fields
}

Decimal is a canonical exact base-10 value.

func (Decimal) Scale

func (decimal Decimal) Scale() uint

Scale returns the number of fractional decimal digits.

func (Decimal) String

func (decimal Decimal) String() string

String returns normalized exact base-10 text; the zero value formats as zero.

type DecimalConfig

type DecimalConfig struct {
	// ID, Label, Description, Placeholder, Hint, Help identify and describe the prompt;
	// ID/Label are required, other text is optional and sanitized at owned presentation
	// boundaries.
	ID, Label, Description, Placeholder, Hint, Help string
	// Default, Fallback distinguish present typed values from omission; execution
	// follows the selected behavior and caller authority.
	Default, Fallback Optional[Decimal]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate, PostValidate are ordered callbacks before/after transformations;
	// slices are copied, callback state and context cooperation are not owned.
	PreValidate, PostValidate []Validator[Decimal]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[Decimal]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
}

DecimalConfig defines an exact base-10 prompt.

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

Decoder incrementally translates common terminal byte sequences into semantic events. It reads no stream and owns no goroutine or terminal state.

func NewDecoder

func NewDecoder(config DecoderConfig) (*Decoder, error)

NewDecoder creates a bounded, concurrent-safe incremental decoder.

func (*Decoder) Feed

func (decoder *Decoder) Feed(chunk []byte) ([]InputEvent, error)

Feed copies and decodes one byte chunk. Incomplete UTF-8 and escape sequences remain buffered until a later Feed or Flush call. Returned events transfer byte-wrapper ownership to the caller; failures reset internal state but do not return partial events. Buffer/paste limits do not cap total stream volume or source IO. Use NewDecoder; do not copy this mutex-bearing value.

func (*Decoder) Flush

func (decoder *Decoder) Flush() ([]InputEvent, error)

Flush resolves a lone Escape key and rejects every other incomplete sequence. It does not synthesize an EOF event.

func (*Decoder) Reset

func (decoder *Decoder) Reset()

Reset discards incomplete non-secret decoder state.

type DecoderConfig

type DecoderConfig struct {
	// MaxPasteBytes caps one retained bracketed paste; zero selects 1 MiB and must not
	// exceed MaxBufferBytes.
	MaxPasteBytes int
	// MaxBufferBytes caps buffered bytes plus each incoming chunk before copying; zero
	// selects 4 MiB.
	MaxBufferBytes int
	// ByteInput makes bracketed paste own SecretBytes rather than Text; callers must
	// destroy unused events.
	ByteInput bool
}

DecoderConfig bounds undecoded terminal bytes and bracketed paste content.

type Descriptor

type Descriptor struct {
	// Kind identifies the semantic parser/editor family.
	Kind PromptKind
	// ID is the stable nonempty identity, not a display label or authentication proof.
	ID string
	// Label is caller-localized display text; owned rendering sanitizes terminal
	// controls.
	Label string
	// Description is optional caller-localized explanatory text, with no universal byte
	// cap.
	Description string
	// Placeholder is display-only empty-input guidance, not a submitted default.
	Placeholder string
	// Hint is optional display guidance, not validation or execution authority.
	Hint string
	// Help is optional caller-localized help rendered as semantic text.
	Help string
	// Retry bounds invalid submissions; zero normalizes to three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns a cancellation error.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns an end-of-input error.
	EndOfInput EOFBehavior
	// Secret selects display/error redaction; classification does not erase string
	// memory.
	Secret SecretClass
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
}

Descriptor is an immutable value snapshot used by renderers and tests.

type DurationConfig

type DurationConfig struct {
	// ID, Label, Description, Placeholder, Hint, Help identify and describe the prompt;
	// ID/Label are required, other text is optional and sanitized at owned presentation
	// boundaries.
	ID, Label, Description, Placeholder, Hint, Help string
	// Default, Fallback distinguish present typed values from omission; execution
	// follows the selected behavior and caller authority.
	Default, Fallback Optional[time.Duration]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate, PostValidate are ordered callbacks before/after transformations;
	// slices are copied, callback state and context cooperation are not owned.
	PreValidate, PostValidate []Validator[time.Duration]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[time.Duration]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
}

DurationConfig defines a Go duration prompt.

type DynamicOptions

type DynamicOptions[T any] struct {
	// contains filtered or unexported fields
}

DynamicOptions owns scheduling and generation-safe option replacement. The caller schedules a query and calls Resolve after the debounce deadline. Use NewDynamicOptions; the zero value is unusable. Scheduling does not cancel previous caller contexts, nor coalesce concurrent same-generation Resolve calls. Clock.Now runs under session locks; providers run outside them and must cooperate with cancellation. Snapshots copy slices but not referenced T.

func NewDynamicOptions

func NewDynamicOptions[T any](config DynamicOptionsConfig[T]) (*DynamicOptions[T], error)

NewDynamicOptions creates an explicit dynamic-option session.

func (*DynamicOptions[T]) Resolve

func (dynamic *DynamicOptions[T]) Resolve(
	ctx context.Context,
	generation QueryGeneration,
) ([]Option[T], bool, error)

Resolve calls the provider only after the scheduled debounce deadline. Its applied result is false for an early or superseded generation.

func (*DynamicOptions[T]) Schedule

func (dynamic *DynamicOptions[T]) Schedule(query string) (QueryGeneration, error)

Schedule supersedes every prior query and returns its new generation.

func (*DynamicOptions[T]) Snapshot

func (dynamic *DynamicOptions[T]) Snapshot() ([]Option[T], QueryGeneration)

Snapshot returns a defensive option slice and the latest scheduled generation. It is safe to call concurrently with Schedule and Resolve.

type DynamicOptionsConfig

type DynamicOptionsConfig[T any] struct {
	// Clock is borrowed; Now runs under session locks and must be prompt and
	// non-reentrant.
	Clock Clock
	// Provider is called synchronously outside session locks; cancellation and shallow
	// value ownership remain caller-owned.
	Provider OptionProvider[T]
	// Debounce is a nonnegative minimum delay checked against Clock; zero is immediate.
	Debounce time.Duration
	// MaxOptions caps admitted provider results after the call; zero selects 10000, not
	// a provider allocation budget.
	MaxOptions int
	// MaxQueryRunes caps validated query rune count; zero selects 256.
	MaxQueryRunes int
}

DynamicOptionsConfig defines a caller-driven, deterministic dynamic-option session. Debouncing is checked against Clock without timers or goroutines.

type EOFBehavior

type EOFBehavior uint8

EOFBehavior defines the result of end-of-input or Ctrl-D.

const (
	// EOFReturnError returns ErrEndOfInput for EOF/Ctrl-D.
	EOFReturnError EOFBehavior = iota
	// EOFUseDefault runs the present typed default through validation on EOF.
	EOFUseDefault
	// EOFUseFallback runs the present fallback through validation on EOF.
	EOFUseFallback
)

type Error

type Error struct {
	// Kind is stable classification; manually supplied kinds must not carry secrets or
	// terminal controls.
	Kind ErrorKind
	// Operation is context sanitized during Error formatting, not a secret-redaction
	// boundary.
	Operation string
	// PromptID is stable prompt context sanitized by Error formatting.
	PromptID string
	// Cause is omitted from default Error text but remains accessible through Unwrap.
	Cause error
}

Error describes a prompt failure without incorporating unsafe cause text.

func (*Error) Error

func (err *Error) Error() string

Error formats kind and sanitized operation/identity, omitting Cause text.

func (*Error) Is

func (err *Error) Is(target error) bool

Is matches stable error kind rather than cause text; nil receivers do not match.

func (*Error) Unwrap

func (err *Error) Unwrap() error

Unwrap returns the original cause, which may carry sensitive caller/backend diagnostics.

type ErrorKind

type ErrorKind string

ErrorKind identifies a stable class of prompt failure.

const (
	// ErrorInteractionNotPermitted classifies when caller authority refuses interaction
	// or the default path.
	ErrorInteractionNotPermitted ErrorKind = "interaction_not_permitted"
	// ErrorTerminalUnavailable classifies when required terminal resources or
	// capabilities are absent.
	ErrorTerminalUnavailable ErrorKind = "terminal_unavailable"
	// ErrorCanceled classifies when execution was canceled.
	ErrorCanceled ErrorKind = "canceled"
	// ErrorDeadlineExceeded classifies when the caller deadline ended.
	ErrorDeadlineExceeded ErrorKind = "deadline_exceeded"
	// ErrorEndOfInput classifies when input ended without configured resolution.
	ErrorEndOfInput ErrorKind = "end_of_input"
	// ErrorTerminalDetached classifies when terminal attachment was lost.
	ErrorTerminalDetached ErrorKind = "terminal_detached"
	// ErrorInvalidDefinition classifies when definition or configuration is invalid.
	ErrorInvalidDefinition ErrorKind = "invalid_definition"
	// ErrorUnsupported classifies when configuration or operation is unsupported.
	ErrorUnsupported ErrorKind = "unsupported_configuration"
	// ErrorValidationExhausted classifies when validation failed or retries ended.
	ErrorValidationExhausted ErrorKind = "validation_exhausted"
	// ErrorRenderer classifies when semantic rendering failed.
	ErrorRenderer ErrorKind = "renderer_failure"
	// ErrorReader classifies when input reading or decoding failed.
	ErrorReader ErrorKind = "reader_failure"
	// ErrorWriter classifies when output writing failed.
	ErrorWriter ErrorKind = "writer_failure"
	// ErrorTerminalControl classifies when configuration or restoration failed.
	ErrorTerminalControl ErrorKind = "terminal_control_failure"
	// ErrorAdapter classifies when an adapter or contained callback failed.
	ErrorAdapter ErrorKind = "adapter_failure"
)

type EventKind

type EventKind uint8

EventKind identifies one bounded terminal input or capability event.

const (
	// EventKey carries Key and optional insertion Rune.
	EventKey EventKind = iota
	// EventPaste carries Text or an owned byte wrapper.
	EventPaste
	// EventResize replaces interactive dimensions.
	EventResize
	// EventEOF resolves configured end-of-input behavior.
	EventEOF
	// EventDetached terminates with terminal-detachment classification.
	EventDetached
	// EventCapabilities replaces the entire active capability snapshot.
	EventCapabilities
)

type EventSource

type EventSource interface {
	// Next returns one semantic event or context/read error; implementations must honor
	// cancellation and transfer byte-payload ownership.
	Next(context.Context) (InputEvent, error)
}

EventSource supplies decoded, cancellable semantic terminal events. It must honor context cancellation; the core never starts a goroutine around it.

type Execution

type Execution struct {
	// Input is for explicit adapter composition; core Run consumes Events, not this
	// reader.
	Input io.Reader
	// Output is a borrowed synchronous writer; context checks cannot interrupt a
	// blocking Write.
	Output io.Writer
	// Error is supplied diagnostic output for caller composition; core Run does not
	// write it.
	Error io.Writer
	// Capabilities supplies initial terminal evidence, not interaction permission.
	Capabilities Capabilities
	// Policy supplies caller authority for interaction, defaults and unlimited retries.
	Policy InteractionPolicy
	// Clock is an explicit timing seam for caller composition; core prompts add no
	// timers.
	Clock Clock
	// Dependencies is passed through to callbacks without copying or container
	// ownership.
	Dependencies any
	// Events is borrowed; implementations must honor cancellation without a hidden core
	// worker.
	Events EventSource
	// Terminal is acquired per interactive prompt; ordinary exits attempt restore/release.
	// Cleanup must return promptly rather than block or panic.
	Terminal TerminalController
	// Renderer is synchronous and borrowed; nil selects the capability-driven owned
	// renderer.
	Renderer Renderer
	// Theme is immutable default-renderer configuration; zero resolves to DefaultTheme.
	Theme Theme
	// Limits bounds interactive text/paste; nonpositive values select defaults, not
	// explicit Parse budgets.
	Limits InputLimits
	// Keys is the immutable local remap; zero uses default semantic bindings.
	Keys KeyMap
}

Execution contains every ambient resource a prompt is allowed to use.

type Form

type Form struct {
	// contains filtered or unexported fields
}

Form is an immutable grouped prompt definition.

func NewForm

func NewForm(config FormConfig) (Form, error)

NewForm creates an ordered, reusable form definition.

type FormConfig

type FormConfig struct {
	// ID is the stable nonempty identity, independent of display text.
	ID string
	// Fields is copied in declaration order; fields need unique nonempty identities and
	// come from AsField/When.
	Fields []FormField
	// Validate is copied ordered cross-field validation after enabled fields; callbacks
	// are panic-contained.
	Validate []FormValidator
	// Dependencies is fallback for cross-field validators only, overridden by non-nil
	// Execution.Dependencies.
	Dependencies any
}

FormConfig defines an ordered grouped interaction.

type FormField

type FormField interface {
	// contains filtered or unexported methods
}

FormField is an immutable type-erased field wrapper created with AsField.

func AsField

func AsField[T any](prompt Prompt[T]) FormField

AsField retains a prompt's typed execution and cloning behavior in a form.

func When

func When(field FormField, predicate func(FormResult) bool) FormField

When returns a conditional copy of a field. The predicate observes only answers from prior fields in this execution; nil predicate keeps it hidden. Predicates run synchronously under RunForm panic containment, not a deadline.

type FormResult

type FormResult struct {
	// contains filtered or unexported fields
}

FormResult is an immutable typed answer collection.

func RunForm

func RunForm(
	ctx context.Context,
	form Form,
	execution Execution,
) (result FormResult, resultErr error)

RunForm executes fields in declaration order without retaining answers in the reusable definition. Separate concurrent runs need safe callback state and execution resources. Definition Dependencies apply to cross-field validation only; per-field callbacks receive Execution.Dependencies. On failure accumulated result-owned byte secrets are destroyed and no answer collection is returned.

Example
package main

import (
	"context"
	"fmt"

	prompts "github.com/faustbrian/go-prompts"
)

func main() {
	name, err := prompts.NewText(
		prompts.TextConfig{
			ID:       "name",
			Label:    "Name",
			Headless: prompts.HeadlessUseFallback,
			Fallback: prompts.Some("Brian"),
		},
	)
	if err != nil {
		panic(err)
	}
	form, err := prompts.NewForm(
		prompts.FormConfig{
			ID:     "profile",
			Fields: []prompts.FormField{prompts.AsField(name)},
		},
	)
	if err != nil {
		panic(err)
	}
	result, err := prompts.RunForm(
		context.Background(),
		form,
		prompts.Execution{
			Policy: prompts.InteractionPolicy{Mode: prompts.NonInteractiveOnly},
		},
	)
	value, ok := prompts.FormValue[string](result, "name")
	fmt.Println(value, ok, err)
}
Output:
Brian true <nil>

func (FormResult) DestroySecrets

func (result FormResult) DestroySecrets()

DestroySecrets best-effort destroys byte-oriented secrets owned by this result. Copies of FormResult share the same owned secret wrappers.

func (FormResult) Has

func (result FormResult) Has(identity string) bool

Has reports whether a field ran and produced an answer.

func (FormResult) IDs

func (result FormResult) IDs() []string

IDs returns answered field identities in execution order.

type FormValidator

type FormValidator func(context.Context, FormResult, ValidationContext) error

FormValidator performs explicit cross-field validation after field prompts.

type Frame

type Frame struct {
	// contains filtered or unexported fields
}

Frame is the authoritative semantic screen representation.

func NewFrame

func NewFrame(lines ...SemanticLine) Frame

NewFrame creates a semantic frame with deeply copied lines.

func (Frame) Lines

func (frame Frame) Lines() []SemanticLine

Lines returns a deep copy of the semantic lines.

type HeadlessBehavior

type HeadlessBehavior uint8

HeadlessBehavior defines how a prompt behaves without interactive input.

const (
	// HeadlessForbidden refuses noninteractive execution.
	HeadlessForbidden HeadlessBehavior = iota
	// HeadlessUseDefault uses a present default only when PermitDefaults is true.
	HeadlessUseDefault
	// HeadlessUseFallback uses a present fallback without PermitDefaults.
	HeadlessUseFallback
)

type InputEvent

type InputEvent struct {
	// Kind selects which event payload fields execution interprets.
	Kind EventKind
	// Key is the semantic key interpreted for EventKey, subject to execution remapping.
	Key Key
	// Rune carries KeyRune input; direct field access bypasses formatting redaction.
	Rune rune
	// Text is borrowed immutable paste text; clearing references cannot erase it.
	Text string
	// Bytes is a shared paste wrapper; transfer or explicit Destroy determines its
	// lifetime.
	Bytes *SecretBytes
	// Width, Height are caller resize dimensions; negative interactive dimensions are
	// rejected.
	Width, Height int
	// Capabilities is the full replacement snapshot for EventCapabilities.
	Capabilities Capabilities
}

InputEvent is a secret-redacting semantic input event.

func CapabilityEvent

func CapabilityEvent(capabilities Capabilities) InputEvent

CapabilityEvent reports a complete replacement capability snapshot.

func KeyEvent

func KeyEvent(key Key) InputEvent

KeyEvent creates a non-text key event.

func PasteBytesEvent

func PasteBytesEvent(value []byte) InputEvent

PasteBytesEvent creates an owned byte-oriented paste event. Call Destroy when the event is not transferred to prompt execution.

func PasteEvent

func PasteEvent(value string) InputEvent

PasteEvent creates a bracketed or ordinary paste event.

func ResizeEvent

func ResizeEvent(width, height int) InputEvent

ResizeEvent creates a terminal dimension event.

func RuneEvent

func RuneEvent(value rune) InputEvent

RuneEvent creates a text insertion event.

func (*InputEvent) Destroy

func (event *InputEvent) Destroy()

Destroy overwrites an owned byte payload and releases text references.

func (InputEvent) Format

func (InputEvent) Format(state fmt.State, _ rune)

Format prevents pasted or typed input from appearing through fmt.

func (InputEvent) GoString

func (InputEvent) GoString() string

GoString returns a redacted Go-syntax representation without exposing payloads.

func (InputEvent) LogValue

func (InputEvent) LogValue() slog.Value

LogValue redacts event payloads in structured logging.

func (InputEvent) MarshalJSON

func (InputEvent) MarshalJSON() ([]byte, error)

MarshalJSON redacts event payloads.

func (InputEvent) MarshalText

func (InputEvent) MarshalText() ([]byte, error)

MarshalText redacts event payloads.

func (InputEvent) String

func (InputEvent) String() string

String returns a redacted representation without revealing payloads.

type InputLimits

type InputLimits struct {
	// MaxPasteBytes caps an interactive paste; nonpositive values select 1 MiB.
	MaxPasteBytes int
	// MaxInputBytes caps retained interactive editor bytes; nonpositive values select 4
	// MiB.
	MaxInputBytes int
}

InputLimits bound retained input and individual paste events.

type IntegerConfig

type IntegerConfig struct {
	// ID, Label, Description, Placeholder, Hint, Help identify and describe the prompt;
	// ID/Label are required, other text is optional and sanitized at owned presentation
	// boundaries.
	ID, Label, Description, Placeholder, Hint, Help string
	// Default, Fallback distinguish present typed values from omission; execution
	// follows the selected behavior and caller authority.
	Default, Fallback Optional[int64]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate, PostValidate are ordered callbacks before/after transformations;
	// slices are copied, callback state and context cooperation are not owned.
	PreValidate, PostValidate []Validator[int64]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[int64]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
}

IntegerConfig defines a signed 64-bit integer prompt.

type InteractionMode

type InteractionMode uint8

InteractionMode defines whether execution may acquire interactive input.

const (
	// InteractiveRequired requires permission and both input/output terminal
	// capabilities.
	InteractiveRequired InteractionMode = iota
	// InteractivePreferred interacts only with permission and both terminal
	// capabilities.
	InteractivePreferred
	// NonInteractiveOnly never acquires terminal input.
	NonInteractiveOnly
	// AutoDetect checks explicit AutoRules while still requiring interaction permission.
	AutoDetect
)

type InteractionPolicy

type InteractionPolicy struct {
	// Mode selects interaction policy; zero requires both terminal capabilities and
	// permission.
	Mode InteractionMode
	// PermitInteraction is explicit caller authorization; detection alone never grants
	// it.
	PermitInteraction bool
	// PermitDefaults permits HeadlessUseDefault; explicit cancel/EOF defaults use their
	// own configured behavior.
	PermitDefaults bool
	// PermitUnlimitedRetries permits explicitly unlimited interactive retry definitions.
	PermitUnlimitedRetries bool
	// Auto selects capability prerequisites only for AutoDetect.
	Auto AutoRules
}

InteractionPolicy records the caller's explicit authority to interact.

type Key

type Key uint8

Key identifies a semantic key independently of terminal byte encoding.

const (
	// KeyRune inserts Rune and cannot be remapped.
	KeyRune Key = iota
	// KeyEnter submits input unless rebound.
	KeyEnter
	// KeyEscape resolves cancellation by default.
	KeyEscape
	// KeyCtrlC maps to Escape in the default key map.
	KeyCtrlC
	// KeyCtrlD resolves EOF by default.
	KeyCtrlD
	// KeyTab advances selection focus or submits the current form field.
	KeyTab
	// KeyShiftTab moves focus backward or revisits the prior enabled form field.
	KeyShiftTab
	// KeyBackspace removes the preceding editor grapheme.
	KeyBackspace
	// KeyDelete removes the editor grapheme at the cursor.
	KeyDelete
	// KeyLeft moves the cursor one grapheme left.
	KeyLeft
	// KeyRight moves the cursor one grapheme right.
	KeyRight
	// KeyUp moves selection focus up; plain editors ignore it.
	KeyUp
	// KeyDown moves selection focus down; plain editors ignore it.
	KeyDown
	// KeyHome moves to the first editor position or enabled selection.
	KeyHome
	// KeyEnd moves to the last editor position or enabled selection.
	KeyEnd
	// KeyWordLeft moves across whitespace-delimited editor words.
	KeyWordLeft
	// KeyWordRight moves across whitespace-delimited editor words.
	KeyWordRight
	// KeyPageUp moves selection focus by a height-derived page.
	KeyPageUp
	// KeyPageDown moves selection focus by a height-derived page.
	KeyPageDown
	// KeyIgnored is an inert unbound shortcut.
	KeyIgnored
	// KeyNewline inserts LF only in multiline input unless rebound.
	KeyNewline
)

type KeyBinding

type KeyBinding struct {
	// Input is a non-rune physical semantic key; duplicate bindings are rejected.
	Input Key
	// Meaning is an existing non-rune meaning whose prior shortcuts become inert.
	Meaning Key
}

KeyBinding assigns one physical semantic key to an existing prompt meaning. KeyRune is not configurable because text runes carry their own value.

type KeyMap

type KeyMap struct {
	// contains filtered or unexported fields
}

KeyMap is an immutable execution-local key translation table.

func NewKeyMap

func NewKeyMap(bindings ...KeyBinding) (KeyMap, error)

NewKeyMap starts with the default bindings and applies each rebind. Rebinding a meaning removes its prior keys so the old shortcut does not remain active.

type KeyValue

type KeyValue struct {
	// Key, Value are ordered summary label/value text; Key is required and owned
	// rendering sanitizes both.
	Key, Value string
}

KeyValue is one declaration-ordered summary entry.

type Message

type Message struct {
	// Kind selects a fixed role; values beyond MessageSuccess are rejected.
	Kind MessageKind
	// Title, Body are localized message text; Title is required and Body may contain
	// line-separated text.
	Title, Body string
}

Message is a caller-localized note or status message.

type MessageKind

type MessageKind uint8

MessageKind selects a textual semantic role.

const (
	// MessageInfo selects informational presentation without changing operation
	// execution.
	MessageInfo MessageKind = iota
	// MessageWarning selects warning presentation without changing operation execution.
	MessageWarning
	// MessageError selects error presentation without changing operation execution.
	MessageError
	// MessageSuccess selects successful presentation without changing operation
	// execution.
	MessageSuccess
)

type MultiSelectConfig

type MultiSelectConfig[T any] struct {
	// ID, Label, Description, Placeholder, Hint, Help identify and describe the prompt;
	// ID/Label are required, other text is optional and sanitized at owned presentation
	// boundaries.
	ID, Label, Description, Placeholder, Hint, Help string
	// DefaultIDs, FallbackIDs select unique enabled identities resolved in declaration
	// order; generic option values remain shallow.
	DefaultIDs, FallbackIDs Optional[[]string]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate, PostValidate are ordered callbacks before/after transformations;
	// slices are copied, callback state and context cooperation are not owned.
	PreValidate, PostValidate []Validator[[]T]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[[]T]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
	// Options is copied as a slice; unique nonempty identities are required, generic
	// values stay shallow.
	Options []Option[T]
	// InitialIDs are copied initial selections checked against enabled identities and
	// bounds.
	InitialIDs []string
	// Min, Max bound selected cardinality; zero Max means all options and Min must be
	// nonnegative.
	Min, Max int
	// MaxOptions caps static option count; zero selects 10000.
	MaxOptions int
}

MultiSelectConfig defines a bounded multiple-selection prompt. Results are always returned in option declaration order.

type MultilineConfig

type MultilineConfig struct {
	// ID, Label, Description, Placeholder, Hint, Help identify and describe the prompt;
	// ID/Label are required, other text is optional and sanitized at owned presentation
	// boundaries.
	ID, Label, Description, Placeholder, Hint, Help string
	// Default, Fallback distinguish present typed values from omission; execution
	// follows the selected behavior and caller authority.
	Default, Fallback Optional[string]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate, PostValidate are ordered callbacks before/after transformations;
	// slices are copied, callback state and context cooperation are not owned.
	PreValidate, PostValidate []Validator[string]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[string]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
	// Secret selects display/error redaction, not string-memory erasure.
	Secret SecretClass
}

MultilineConfig defines a multiline text prompt.

type Option

type Option[T any] struct {
	// contains filtered or unexported fields
}

Option keeps stable identity separate from its display label and value.

func NewOption

func NewOption[T any](config OptionConfig[T]) (Option[T], error)

NewOption validates identity/label and stores Value shallowly, not deep-copying T.

func Search[T any](options []Option[T], query string, policy SearchPolicy) ([]Option[T], error)

Search returns shallow option copies using NFKC/case folding, with exact, prefix, token-prefix and token-substring ranking and declaration-order ties. Disabled options remain in results. Count/query bounds do not cap label bytes or all intermediate matches; callers own referenced generic values.

func (Option[T]) Description

func (option Option[T]) Description() string

Description returns raw optional display description.

func (Option[T]) Disabled

func (option Option[T]) Disabled() bool

Disabled reports selection unavailability.

func (Option[T]) Group

func (option Option[T]) Group() string

Group returns display grouping, not a sorting key.

func (Option[T]) ID

func (option Option[T]) ID() string

ID returns stable option identity without display normalization.

func (Option[T]) Label

func (option Option[T]) Label() string

Label returns raw display text sanitized only by owned rendering.

func (Option[T]) Value

func (option Option[T]) Value() T

Value returns stored generic data by assignment, preserving reference aliases.

type OptionConfig

type OptionConfig[T any] struct {
	// ID is the stable nonempty identity, independent of display text.
	ID string
	// Label is caller-localized raw display text, sanitized by owned rendering.
	Label string
	// Description is optional raw explanatory text with no universal byte ceiling.
	Description string
	// Group is raw display grouping, not a sorting or identity key.
	Group string
	// Value is stored by ordinary assignment; referenced maps/slices/pointers are not
	// deeply copied.
	Value T
	// Disabled keeps an option visible but unavailable for selection/default/fallback.
	Disabled bool
}

OptionConfig defines one stable selection identity and display value.

type OptionProvider

type OptionProvider[T any] func(context.Context, string) ([]Option[T], error)

OptionProvider resolves options for a complete caller-visible query. It must honor context cancellation and must not retain or mutate returned option slices after returning.

type Optional

type Optional[T any] struct {
	// contains filtered or unexported fields
}

Optional distinguishes an explicit zero value from an omitted value.

func Some

func Some[T any](value T) Optional[T]

Some marks a present value by ordinary assignment, not deep copying references.

func (Optional[T]) Get

func (optional Optional[T]) Get() (T, bool)

Get returns the stored value by assignment and presence; referenced data can alias.

type Path

type Path struct {
	// contains filtered or unexported fields
}

Path is an unverified filesystem path with explicit caller intent.

func (Path) Kind

func (path Path) Kind() PathKind

Kind returns caller intent without asserting anything about the filesystem.

func (Path) String

func (path Path) String() string

String returns unverified path text without filesystem access.

type PathConfig

type PathConfig struct {
	// ID, Label, Description, Placeholder, Hint, Help identify and describe the prompt;
	// ID/Label are required, other text is optional and sanitized at owned presentation
	// boundaries.
	ID, Label, Description, Placeholder, Hint, Help string
	// Default, Fallback distinguish present typed values from omission; execution
	// follows the selected behavior and caller authority.
	Default, Fallback Optional[Path]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate, PostValidate are ordered callbacks before/after transformations;
	// slices are copied, callback state and context cooperation are not owned.
	PreValidate, PostValidate []Validator[Path]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[Path]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
	// Kind is filesystem intent only; parsing does not access the filesystem.
	Kind PathKind
}

PathConfig defines a path prompt without filesystem access.

type PathKind

type PathKind uint8

PathKind is caller intent only; parsing never consults or mutates the file system.

const (
	// PathAny retains path intent without inspecting its filesystem kind.
	PathAny PathKind = iota
	// PathFile retains file intent without checking existence or permissions.
	PathFile
	// PathDirectory retains directory intent without checking existence or permissions.
	PathDirectory
)

type PlainRenderer

type PlainRenderer struct {
	// Theme is immutable style/marker configuration; zero resolves to DefaultTheme.
	Theme Theme
}

PlainRenderer emits deterministic linear output without terminal controls.

func (PlainRenderer) Render

func (renderer PlainRenderer) Render(frame Frame, options RenderOptions) (string, error)

Render validates capabilities and emits sanitized linear text without ANSI or OSC controls; safe link targets appear textually. Width zero disables wrapping.

type Progress

type Progress struct {
	// contains filtered or unexported fields
}

Progress stores only the latest update and never creates a goroutine or queue. Update does no output IO; Render is explicit. Use NewProgress and do not copy this mutex-bearing value. Concurrent state operations are serialized, but an optional Clock.Now runs under the mutex and must not block/reenter. Rendering uses borrowed callbacks/output after snapshotting, without forced cancellation.

Example
package main

import (
	"context"
	"os"

	prompts "github.com/faustbrian/go-prompts"
)

func main() {
	progress, err := prompts.NewProgress(
		prompts.ProgressConfig{ID: "upload", Label: "Upload", Total: 2},
	)
	if err != nil {
		panic(err)
	}
	if err := progress.Update(2, "sent"); err != nil {
		panic(err)
	}
	progress.Complete("done")
	if err := progress.Render(context.Background(), prompts.Execution{Output: os.Stdout}); err != nil {
		panic(err)
	}
}
Output:
success: Upload: 2/2 (100%) - done

func NewProgress

func NewProgress(config ProgressConfig) (*Progress, error)

NewProgress creates a caller-driven progress value.

func (*Progress) Cancel

func (progress *Progress) Cancel(message string)

Cancel records a stable canceled terminal state.

func (*Progress) Complete

func (progress *Progress) Complete(message string)

Complete records a stable successful terminal state.

func (*Progress) Fail

func (progress *Progress) Fail(message string)

Fail records a stable failed terminal state.

func (*Progress) Increment

func (progress *Progress) Increment(delta int64, message string) error

Increment atomically advances progress without integer overflow.

func (*Progress) IncrementContext

func (progress *Progress) IncrementContext(ctx context.Context, delta int64, message string) error

IncrementContext atomically advances progress unless the context has ended.

func (*Progress) Render

func (progress *Progress) Render(ctx context.Context, execution Execution) error

Render explicitly writes the latest stable semantic line.

func (*Progress) Snapshot

func (progress *Progress) Snapshot() ProgressSnapshot

Snapshot returns the latest coalesced state.

func (*Progress) Update

func (progress *Progress) Update(current int64, message string) error

Update replaces the latest progress value and message.

func (*Progress) UpdateContext

func (progress *Progress) UpdateContext(ctx context.Context, current int64, message string) error

UpdateContext replaces the latest progress value unless the context has ended. Prefer it when updates are emitted from caller-owned operations.

type ProgressConfig

type ProgressConfig struct {
	// ID, Label are required stable identity and caller-localized display text.
	ID, Label string
	// Total is nonnegative; zero is indeterminate, positive totals bound current
	// updates.
	Total int64
	// AllowRegression permits lower Update values and resets timing baselines; Increment
	// still rejects negative deltas.
	AllowRegression bool
	// Clock is optional; Now runs under the progress mutex and must be prompt and
	// non-reentrant.
	Clock Clock
}

ProgressConfig defines determinate or indeterminate caller-owned progress. A zero total is indeterminate.

type ProgressSnapshot

type ProgressSnapshot struct {
	// ID, Label, Message are copied identity, label and latest raw progress message.
	ID, Label, Message string
	// Current, Total are latest progress and configured total; zero Total means
	// indeterminate.
	Current, Total int64
	// State is latest lifecycle state; first terminal transition wins.
	State ProgressState
	// Elapsed is time since the current measurement baseline, not constructor wall time.
	Elapsed time.Duration
	// RatePerSecond is present only for positive elapsed time and progress delta.
	RatePerSecond Optional[float64]
	// EstimatedRemaining is optional bounded ETA when a determinate total has a usable
	// rate.
	EstimatedRemaining Optional[time.Duration]
}

ProgressSnapshot is an immutable state copy.

type ProgressState

type ProgressState uint8

ProgressState identifies a stable lifecycle state.

const (
	// ProgressPending is the initial state before any update or finish.
	ProgressPending ProgressState = iota
	// ProgressRunning identifies the latest nonterminal update.
	ProgressRunning
	// ProgressSucceeded identifies successful finish; later terminal finishes are
	// ignored.
	ProgressSucceeded
	// ProgressFailed identifies failed finish; later terminal finishes are ignored.
	ProgressFailed
	// ProgressCanceled identifies canceled finish; later terminal finishes are ignored.
	ProgressCanceled
)

type Prompt

type Prompt[T any] struct {
	// contains filtered or unexported fields
}

Prompt is a reusable definition created by a constructor; its zero value is not executable. Callback slices are copied, but callback state and generic referenced values are borrowed. Concurrent use requires safe dependencies and separate execution resources. Typed defaults/fallbacks bypass string parsing and still run the validation pipeline; constructors do not validate their business meaning. Secret-byte definitions retain copied defaults until unreachable.

func NewConfirm

func NewConfirm(config ConfirmConfig) (Prompt[bool], error)

NewConfirm creates a localized yes/no prompt.

func NewDate

func NewDate(config DateConfig) (Prompt[Date], error)

NewDate creates an ISO calendar-date prompt.

func NewDecimal

func NewDecimal(config DecimalConfig) (Prompt[Decimal], error)

NewDecimal creates an exact base-10 decimal prompt.

func NewDuration

func NewDuration(config DurationConfig) (Prompt[time.Duration], error)

NewDuration creates a Go duration prompt.

func NewInteger

func NewInteger(config IntegerConfig) (Prompt[int64], error)

NewInteger creates a signed 64-bit integer prompt.

func NewMultiSelect

func NewMultiSelect[T any](config MultiSelectConfig[T]) (Prompt[[]T], error)

NewMultiSelect creates a bounded multiple-selection prompt.

func NewMultiline

func NewMultiline(config MultilineConfig) (Prompt[string], error)

NewMultiline creates a multiline text prompt.

func NewPath

func NewPath(config PathConfig) (Prompt[Path], error)

NewPath creates a path prompt that performs no filesystem access.

func NewSearchSelect

func NewSearchSelect[T any](config SearchSelectConfig[T]) (Prompt[T], error)

NewSearchSelect creates a searchable single selection prompt.

func NewSecret

func NewSecret(config SecretConfig) (Prompt[SecretValue], error)

NewSecret creates a classified redacting string secret prompt.

func NewSecretBytesPrompt

func NewSecretBytesPrompt(config SecretBytesConfig) (Prompt[*SecretBytes], error)

NewSecretBytesPrompt creates a classified cleanup-capable secret prompt.

func NewSelect

func NewSelect[T any](config SelectConfig[T]) (Prompt[T], error)

NewSelect creates a stable-identity single selection prompt.

func NewText

func NewText(config TextConfig) (Prompt[string], error)

NewText creates a single-line text prompt.

func NewTime

func NewTime(config TimeConfig) (Prompt[TimeOfDay], error)

NewTime creates a wall-clock time prompt.

func (Prompt[T]) Describe

func (prompt Prompt[T]) Describe() Descriptor

Describe returns a value snapshot of the prompt's execution contract.

func (Prompt[T]) ID

func (prompt Prompt[T]) ID() string

ID returns the stable prompt identity.

type PromptKind

type PromptKind string

PromptKind identifies the semantic prompt type independently of rendering.

const (
	// KindText selects single-line string parsing; CR/LF input is rejected.
	KindText PromptKind = "text"
	// KindMultiline selects string input with interactive newline insertion.
	KindMultiline PromptKind = "multiline"
	// KindInteger selects signed base-10 int64 parsing.
	KindInteger PromptKind = "integer"
	// KindDecimal selects exact base-10 decimal parsing without binary floating point.
	KindDecimal PromptKind = "decimal"
	// KindDuration selects Go time.Duration parsing.
	KindDuration PromptKind = "duration"
	// KindDate selects calendar-date parsing without a timezone.
	KindDate PromptKind = "date"
	// KindTime selects wall-clock parsing without a date or timezone.
	KindTime PromptKind = "time"
	// KindPath selects nonempty NUL-free path text without filesystem access.
	KindPath PromptKind = "path"
	// KindConfirm selects localized normalized true/false spellings.
	KindConfirm PromptKind = "confirm"
	// KindSelect selects enabled stable option identity.
	KindSelect PromptKind = "select"
	// KindMultiSelect selects unique enabled identities returned in declaration order.
	KindMultiSelect PromptKind = "multi_select"
	// KindSearchSelect adds bounded normalized option ranking to single selection.
	KindSearchSelect PromptKind = "search_select"
	// KindSecret selects classified redacting string storage.
	KindSecret PromptKind = "secret"
	// KindSecretBytes selects classified owned byte storage with explicit cleanup.
	KindSecretBytes PromptKind = "secret_bytes"
)

type QueryGeneration

type QueryGeneration uint64

QueryGeneration identifies one scheduled dynamic-option query. Results may be applied only while their generation remains current.

type RenderOptions

type RenderOptions struct {
	// Width is a nonnegative grapheme-cell wrapping target; zero disables wrapping.
	Width int
	// Color must be a valid profile even when rendering plain text.
	Color ColorProfile
	// ASCIIOnly renders non-ASCII runes as visible escapes after sanitization.
	ASCIIOnly bool
	// Hyperlinks permits owned OSC 8 in ANSI mode; plain mode prints targets.
	Hyperlinks bool
}

RenderOptions are explicit output capabilities.

type Renderer

type Renderer interface {
	// Render converts a frame synchronously under explicit capabilities; implementations
	// own blocking and sanitization.
	Render(Frame, RenderOptions) (string, error)
}

Renderer converts an owned semantic frame into terminal output.

type RetryPolicy

type RetryPolicy struct {
	// MaxAttempts counts invalid interactive submissions; zero selects three unless
	// Unlimited is true.
	MaxAttempts uint
	// Unlimited requires zero MaxAttempts and explicit interactive
	// PermitUnlimitedRetries authority.
	Unlimited bool
}

RetryPolicy bounds invalid submissions. Unlimited retry requires separate authority in the interactive execution policy.

type Role

type Role string

Role identifies semantic meaning independently of terminal styling.

const (
	// RoleLabel selects label styling and textual markers independently of color.
	RoleLabel Role = "label"
	// RoleValue selects ordinary value styling and textual markers independently of
	// color.
	RoleValue Role = "value"
	// RoleHint selects guidance styling and textual markers independently of color.
	RoleHint Role = "hint"
	// RoleHelp selects help styling and textual markers independently of color.
	RoleHelp Role = "help"
	// RoleError selects failure styling and textual markers independently of color.
	RoleError Role = "error"
	// RoleSuccess selects success styling and textual markers independently of color.
	RoleSuccess Role = "success"
	// RoleWarning selects warning styling and textual markers independently of color.
	RoleWarning Role = "warning"
	// RoleFocus selects focused option styling and textual markers independently of
	// color.
	RoleFocus Role = "focus"
	// RoleSelected selects selected option styling and textual markers independently of
	// color.
	RoleSelected Role = "selected"
	// RoleDisabled selects visible unavailable option styling and textual markers
	// independently of color.
	RoleDisabled Role = "disabled"
	// RoleProgress selects caller-driven progress styling and textual markers
	// independently of color.
	RoleProgress Role = "progress"
)

type SearchPolicy

type SearchPolicy struct {
	// MaxOptions caps admitted options; all-zero SearchPolicy selects 10000.
	MaxOptions int
	// MaxResults caps returned ranked matches; all-zero SearchPolicy selects 50.
	MaxResults int
	// MaxQueryRunes caps query runes before normalization; all-zero SearchPolicy selects
	// 256.
	MaxQueryRunes int
}

SearchPolicy bounds deterministic static option search.

type SearchSelectConfig

type SearchSelectConfig[T any] struct {
	// Select supplies copied static options and single-selection behavior.
	Select SelectConfig[T]
	// Search supplies ranking bounds; partially zero policies are rejected.
	Search SearchPolicy
}

SearchSelectConfig defines a searchable single selection prompt.

type SecretBytes

type SecretBytes struct {
	// contains filtered or unexported fields
}

SecretBytes synchronizes owned mutable bytes and is safe for concurrent Reveal/Destroy/Len calls; a zero wrapper is empty but not yet destroyed, and nil receivers are safe. Do not copy this mutex-bearing value. Destroy erases only its current owned slice, not prior Reveal/callback/runtime copies.

func NewSecretBytes

func NewSecretBytes(value []byte) *SecretBytes

NewSecretBytes creates an owned copy of secret bytes.

func ParseBytes

func ParseBytes(
	ctx context.Context,
	prompt Prompt[*SecretBytes],
	input []byte,
	dependencies any,
) (*SecretBytes, error)

ParseBytes copies explicit caller-owned bytes and validates them without converting the input into an immutable Go string. It does not apply interactive InputLimits; callers bound explicit bytes. Failure can return a destroyed wrapper alongside an error; transformer-retained or replaced copies remain callback-owned, not a complete erasure guarantee.

func (*SecretBytes) Destroy

func (secret *SecretBytes) Destroy()

Destroy overwrites and releases the wrapper's owned byte slice.

func (*SecretBytes) Destroyed

func (secret *SecretBytes) Destroyed() bool

Destroyed reports whether Destroy has been called.

func (*SecretBytes) Format

func (*SecretBytes) Format(state fmt.State, _ rune)

Format redacts every fmt formatting verb.

func (*SecretBytes) GoString

func (*SecretBytes) GoString() string

GoString returns a redacted Go-syntax representation without exposing payloads.

func (*SecretBytes) Len

func (secret *SecretBytes) Len() int

Len returns the current owned byte count.

func (*SecretBytes) LogValue

func (*SecretBytes) LogValue() slog.Value

LogValue returns a redacted structured logging value.

func (*SecretBytes) MarshalJSON

func (*SecretBytes) MarshalJSON() ([]byte, error)

MarshalJSON returns a redacted JSON string.

func (*SecretBytes) MarshalText

func (*SecretBytes) MarshalText() ([]byte, error)

MarshalText returns a redacted representation.

func (*SecretBytes) Reveal

func (secret *SecretBytes) Reveal() []byte

Reveal returns an owned copy of the current secret bytes.

func (*SecretBytes) String

func (*SecretBytes) String() string

String returns a redacted representation without revealing payloads.

type SecretBytesConfig

type SecretBytesConfig struct {
	// ID, Label, Description, Placeholder, Hint, Help identify and describe the prompt;
	// ID/Label are required, other text is optional and sanitized at owned presentation
	// boundaries.
	ID, Label, Description, Placeholder, Hint, Help string
	// Default, Fallback distinguish present typed values from omission; execution
	// follows the selected behavior and caller authority.
	Default, Fallback Optional[*SecretBytes]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate, PostValidate are ordered callbacks before/after transformations;
	// slices are copied, callback state and context cooperation are not owned.
	PreValidate, PostValidate []Validator[*SecretBytes]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[*SecretBytes]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
	// Class must classify Password, Token or Other; secret constructors reject zero.
	Class SecretClass
}

SecretBytesConfig defines a cleanup-capable byte secret prompt.

type SecretClass

type SecretClass uint8

SecretClass controls redaction and terminal echo policy.

const (
	// SecretNone is public input; dedicated secret constructors reject it.
	SecretNone SecretClass = iota
	// SecretPassword classifies password input for owned display/error suppression.
	SecretPassword
	// SecretToken classifies token input for owned display/error suppression.
	SecretToken
	// SecretOther classifies other sensitive input without an erasure guarantee.
	SecretOther
)

type SecretConfig

type SecretConfig struct {
	// ID, Label, Description, Placeholder, Hint, Help identify and describe the prompt;
	// ID/Label are required, other text is optional and sanitized at owned presentation
	// boundaries.
	ID, Label, Description, Placeholder, Hint, Help string
	// Default, Fallback distinguish present typed values from omission; execution
	// follows the selected behavior and caller authority.
	Default, Fallback Optional[SecretValue]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate, PostValidate are ordered callbacks before/after transformations;
	// slices are copied, callback state and context cooperation are not owned.
	PreValidate, PostValidate []Validator[SecretValue]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[SecretValue]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
	// Class must classify Password, Token or Other; secret constructors reject zero.
	Class SecretClass
}

SecretConfig defines a string-backed secret prompt.

type SecretValue

type SecretValue struct {
	// contains filtered or unexported fields
}

SecretValue is a string-backed secret with redacted formatting. Reveal is explicit; Go strings cannot be reliably erased from memory.

func NewSecretValue

func NewSecretValue(value string) SecretValue

NewSecretValue copies a string reference into a redacting value wrapper.

func (SecretValue) Format

func (SecretValue) Format(state fmt.State, _ rune)

Format redacts every fmt formatting verb.

func (SecretValue) GoString

func (SecretValue) GoString() string

GoString returns a redacted Go-syntax representation without exposing payloads.

func (SecretValue) LogValue

func (SecretValue) LogValue() slog.Value

LogValue returns a redacted structured logging value.

func (SecretValue) MarshalJSON

func (SecretValue) MarshalJSON() ([]byte, error)

MarshalJSON returns a redacted JSON string.

func (SecretValue) MarshalText

func (SecretValue) MarshalText() ([]byte, error)

MarshalText returns a redacted representation.

func (SecretValue) Reveal

func (secret SecretValue) Reveal() string

Reveal returns the underlying immutable Go string explicitly.

func (SecretValue) String

func (SecretValue) String() string

String returns a redacted representation without revealing payloads.

type Segment

type Segment struct {
	// Role selects semantic style/marker; unknown roles remain unstyled.
	Role Role
	// Content is raw caller text sanitized during owned rendering, without a universal
	// size cap.
	Content string
	// contains filtered or unexported fields
}

Segment is a semantic unit of untrusted caller-facing text.

func Hyperlink(role Role, content, target string) (Segment, error)

Hyperlink creates a semantic link with a safe absolute HTTP, HTTPS, or mailto target. Unsupported or control-bearing targets are rejected.

func Text

func Text(role Role, content string) Segment

Text creates a semantic text segment.

func (Segment) Target

func (segment Segment) Target() string

Target returns the link target, or an empty string for ordinary text.

type SelectConfig

type SelectConfig[T any] struct {
	// ID, Label, Description, Placeholder, Hint, Help identify and describe the prompt;
	// ID/Label are required, other text is optional and sanitized at owned presentation
	// boundaries.
	ID, Label, Description, Placeholder, Hint, Help string
	// DefaultID, FallbackID select enabled option identities; omission does not
	// implicitly choose an option.
	DefaultID, FallbackID Optional[string]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate, PostValidate are ordered callbacks before/after transformations;
	// slices are copied, callback state and context cooperation are not owned.
	PreValidate, PostValidate []Validator[T]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[T]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
	// Options is copied as a slice; unique nonempty identities are required, generic
	// values stay shallow.
	Options []Option[T]
	// InitialID is optional enabled initial focus/selection, not headless fallback.
	InitialID string
	// MaxOptions caps static option count; zero selects 10000.
	MaxOptions int
}

SelectConfig defines a single selection prompt.

type SemanticLine

type SemanticLine struct {
	// contains filtered or unexported fields
}

SemanticLine is a defensively owned sequence of segments.

func Line

func Line(segments ...Segment) SemanticLine

Line creates a semantic line and copies the supplied segments.

func (SemanticLine) Segments

func (line SemanticLine) Segments() []Segment

Segments returns a defensive copy of the line's segments.

type Spinner

type Spinner struct {
	// contains filtered or unexported fields
}

Spinner is caller-advanced without timers. Use NewSpinner; do not copy its mutex-bearing state. Snapshot/mutations are synchronized, while rendering remains synchronous caller-owned IO.

func NewSpinner

func NewSpinner(config SpinnerConfig) (*Spinner, error)

NewSpinner creates a caller-driven spinner.

func (*Spinner) Advance

func (spinner *Spinner) Advance(message string)

Advance selects the next frame and coalesces the latest message.

func (*Spinner) AdvanceContext

func (spinner *Spinner) AdvanceContext(ctx context.Context, message string) error

AdvanceContext selects the next frame unless the context has ended.

func (*Spinner) Cancel

func (spinner *Spinner) Cancel(message string)

Cancel records first canceled spinner finish; later terminal calls do nothing.

func (*Spinner) Fail

func (spinner *Spinner) Fail(message string)

Fail records first failed spinner finish; later terminal calls do nothing.

func (*Spinner) Render

func (spinner *Spinner) Render(ctx context.Context, execution Execution) error

Render writes a frame only when animation is explicitly supported.

func (*Spinner) Snapshot

func (spinner *Spinner) Snapshot() SpinnerSnapshot

Snapshot returns the latest state and caller-selected frame.

func (*Spinner) Succeed

func (spinner *Spinner) Succeed(message string)

Succeed records first successful spinner finish; later terminal calls do nothing.

type SpinnerConfig

type SpinnerConfig struct {
	// ID, Label are required stable identity and caller-localized display text.
	ID, Label string
	// Frames are copied; empty selects four ASCII frames, advances remain caller-driven.
	Frames []string
}

SpinnerConfig defines caller-advanced indeterminate status frames.

type SpinnerSnapshot

type SpinnerSnapshot struct {
	ProgressSnapshot
	// Frame is the current spinner glyph; rendering can omit it without animation
	// capability.
	Frame string
}

SpinnerSnapshot is an immutable spinner state copy.

type StatusEntry

type StatusEntry struct {
	// Kind selects fixed status role; values beyond StatusSuccess are rejected.
	Kind StatusKind
	// Text is raw caller message text; capacity bounds entries, not their bytes.
	Text string
}

StatusEntry is a deterministic status-stream value.

type StatusKind

type StatusKind uint8

StatusKind identifies one bounded line-oriented status role.

const (
	// StatusInfo selects informational presentation without changing operation
	// execution.
	StatusInfo StatusKind = iota
	// StatusWarning selects warning presentation without changing operation execution.
	StatusWarning
	// StatusError selects error presentation without changing operation execution.
	StatusError
	// StatusSuccess selects successful presentation without changing operation
	// execution.
	StatusSuccess
)

type StatusStream

type StatusStream struct {
	// contains filtered or unexported fields
}

StatusStream retains a configured count of latest entries, not bounded text bytes. Use NewStatusStream; do not copy its mutex. State operations are safe concurrently, while rendering borrows caller-owned renderer/writer behavior. Entries and dropped count are read separately, not one atomic render snapshot.

func NewStatusStream

func NewStatusStream(capacity int) (*StatusStream, error)

NewStatusStream creates a bounded concurrent stream.

func (*StatusStream) Append

func (stream *StatusStream) Append(kind StatusKind, text string) error

Append adds one entry and drops the oldest entry at capacity.

func (*StatusStream) AppendContext

func (stream *StatusStream) AppendContext(ctx context.Context, kind StatusKind, text string) error

AppendContext adds one entry unless the context has ended.

func (*StatusStream) Dropped

func (stream *StatusStream) Dropped() uint64

Dropped returns the number of omitted oldest entries.

func (*StatusStream) Render

func (stream *StatusStream) Render(ctx context.Context, execution Execution) error

Render writes a deterministic linear stream snapshot.

func (*StatusStream) Snapshot

func (stream *StatusStream) Snapshot() []StatusEntry

Snapshot returns entries in append order.

type Style

type Style struct {
	// Foreground is semantic color; zero leaves the terminal default.
	Foreground Color
	// Bold requests bold only under ANSI styling capability.
	Bold bool
	// Underline requests underline only under ANSI styling capability.
	Underline bool
	// Dim requests dim only under ANSI styling capability.
	Dim bool
}

Style assigns visual attributes to one semantic role.

type Table

type Table struct {
	// Headers are borrowed required table labels; callers must not mutate during
	// rendering.
	Headers []string
	// Rows are borrowed rectangular cells; callers bound text bytes.
	Rows [][]string
	// MaxRows, MaxColumns bound table counts; zero selects 1000 rows and 50 columns, not
	// per-cell bytes.
	MaxRows, MaxColumns int
}

Table is a bounded rectangular display model.

type Task

type Task struct {
	// Progress is the group-owned state handle; callers must not replace it or copy its mutex.
	*Progress
	// contains filtered or unexported fields
}

Task presents caller-owned work; it never schedules or retries that work.

func (*Task) Snapshot

func (task *Task) Snapshot() TaskSnapshot

Snapshot returns a stable task state copy.

type TaskConfig

type TaskConfig struct {
	// ID, Label are required stable identity and caller-localized display text.
	ID, Label string
	// ParentID is optional parent identity; Add requires the parent to already exist.
	ParentID string
	// Total is nonnegative; zero is indeterminate progress.
	Total int64
	// AllowRegression permits lower progress updates, not negative Increment values.
	AllowRegression bool
}

TaskConfig defines one caller-owned task state.

type TaskGroup

type TaskGroup struct {
	// contains filtered or unexported fields
}

TaskGroup preserves Add order and explicit nesting without running work. Use NewTaskGroup; do not copy its mutex. Membership is synchronized but each task is snapshotted independently, not as one atomic group-wide progress view.

func NewTaskGroup

func NewTaskGroup(config TaskGroupConfig) (*TaskGroup, error)

NewTaskGroup creates an ordered bounded presentation group.

func (*TaskGroup) Add

func (group *TaskGroup) Add(config TaskConfig) (*Task, error)

Add declares a task after its optional parent and returns its state handle.

func (*TaskGroup) Len

func (group *TaskGroup) Len() int

Len returns the declared task count.

func (*TaskGroup) Render

func (group *TaskGroup) Render(ctx context.Context, execution Execution) error

Render writes a deterministic nested task summary in Add order.

func (*TaskGroup) Snapshot

func (group *TaskGroup) Snapshot() []TaskSnapshot

Snapshot returns task states in Add order.

type TaskGroupConfig

type TaskGroupConfig struct {
	// ID, Label are required stable identity and caller-localized display text.
	ID, Label string
	// MaxTasks caps group membership; zero selects 100, not worker count or text bytes.
	MaxTasks int
}

TaskGroupConfig defines explicit ordered task presentation ownership.

type TaskSnapshot

type TaskSnapshot struct {
	ProgressSnapshot
	// ParentID is optional parent identity; Add requires the parent to already exist.
	ParentID string
}

TaskSnapshot is a progress snapshot with explicit parent ownership.

type TerminalController

type TerminalController interface {
	// Acquire acquires explicit state; success requires a later Release.
	Acquire(context.Context) error
	// SetEcho configures owned terminal echo; implementations must not disclose secret
	// input.
	SetEcho(bool) error
	// Release attempts restoration; failures must remain visible.
	Release() error
}

TerminalController owns acquisition and restoration of explicit terminal state. Methods must return errors for failure rather than panic; the core does not isolate arbitrary terminal-control panics or bound blocking cleanup calls.

type TextConfig

type TextConfig struct {
	// ID is the stable nonempty identity, independent of display text.
	ID string
	// Label is caller-localized raw display text, sanitized by owned rendering.
	Label string
	// Description is optional raw explanatory text with no universal byte ceiling.
	Description string
	// Placeholder is empty-input display guidance, not a submitted default.
	Placeholder string
	// Hint is optional semantic guidance, not validation authority.
	Hint string
	// Help is optional localized extended guidance.
	Help string
	// Default distinguishes a present typed default from omission; Some preserves zero
	// values.
	Default Optional[string]
	// Fallback distinguishes a present typed fallback from omission.
	Fallback Optional[string]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate contains ordered validators for the parsed value; constructors copy
	// callback slices but not callback state.
	PreValidate []Validator[string]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[string]
	// PostValidate contains ordered validators for the transformed value; constructors
	// copy callback slices but not callback state.
	PostValidate []Validator[string]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
	// Secret selects display/error redaction, not string-memory erasure.
	Secret SecretClass
}

TextConfig defines an immutable single-line text prompt.

type Theme

type Theme struct {
	// contains filtered or unexported fields
}

Theme is an immutable role-to-style and role-to-text-marker mapping.

func DefaultTheme

func DefaultTheme() Theme

DefaultTheme returns the sober color-independent default theme.

func (Theme) Marker

func (theme Theme) Marker(role Role) string

Marker returns the role's color-independent textual marker.

func (Theme) Style

func (theme Theme) Style(role Role) Style

Style returns the role's style or the zero style for an unknown role.

func (Theme) With

func (theme Theme) With(role Role, style Style) Theme

With returns a copy with one role's style replaced.

func (Theme) WithMarker

func (theme Theme) WithMarker(role Role, marker string) Theme

WithMarker returns a copy with one role's textual marker replaced.

type Ticker

type Ticker interface {
	// C returns the owned event channel; Stop need not close it.
	C() <-chan time.Time
	// Stop prevents future tick generation; already buffered values can remain
	// and the channel need not close.
	Stop()
}

Ticker is an owned, stoppable sequence of clock events.

type TimeConfig

type TimeConfig struct {
	// ID, Label, Description, Placeholder, Hint, Help identify and describe the prompt;
	// ID/Label are required, other text is optional and sanitized at owned presentation
	// boundaries.
	ID, Label, Description, Placeholder, Hint, Help string
	// Default, Fallback distinguish present typed values from omission; execution
	// follows the selected behavior and caller authority.
	Default, Fallback Optional[TimeOfDay]
	// Headless selects the noninteractive path; zero forbids headless execution.
	Headless HeadlessBehavior
	// Accessibility overrides localized label/description and adds textual navigation
	// guidance.
	Accessibility Accessibility
	// PreValidate, PostValidate are ordered callbacks before/after transformations;
	// slices are copied, callback state and context cooperation are not owned.
	PreValidate, PostValidate []Validator[TimeOfDay]
	// Transform contains ordered synchronous transformations; context cooperation and
	// retained values remain caller-owned.
	Transform []Transformer[TimeOfDay]
	// Retry bounds invalid interactive submissions; zero selects three attempts.
	Retry RetryPolicy
	// Cancel selects explicit cancel resolution; zero returns ErrCanceled.
	Cancel CancelBehavior
	// EndOfInput selects EOF/Ctrl-D resolution; zero returns ErrEndOfInput.
	EndOfInput EOFBehavior
}

TimeConfig defines a wall-clock time prompt.

type TimeOfDay

type TimeOfDay struct {
	// contains filtered or unexported fields
}

TimeOfDay is a wall-clock time without a date or time zone.

func (TimeOfDay) Hour

func (value TimeOfDay) Hour() int

Hour returns the hour in the range 0 through 23.

func (TimeOfDay) Minute

func (value TimeOfDay) Minute() int

Minute returns the minute in the range 0 through 59.

func (TimeOfDay) Nanosecond

func (value TimeOfDay) Nanosecond() int

Nanosecond returns the fractional second in nanoseconds.

func (TimeOfDay) Second

func (value TimeOfDay) Second() int

Second returns the second in the range 0 through 59.

func (TimeOfDay) String

func (value TimeOfDay) String() string

String formats wall-clock fields with trailing fractional zeroes removed.

type Timer

type Timer interface {
	// C returns the owned event channel; Stop need not close it.
	C() <-chan time.Time
	// Stop reports whether an active event was stopped; an already buffered value
	// can remain and the channel need not close.
	Stop() bool
}

Timer is an owned, stoppable clock event.

type Transformer

type Transformer[T any] func(context.Context, T, ValidationContext) (T, error)

Transformer returns the next pipeline value synchronously. Returned aliases, replaced mutable secret wrappers and callback-owned copies remain its cleanup responsibility; pipeline context checks cannot stop arbitrary blocked code.

type ValidationContext

type ValidationContext struct {
	// Dependencies is the exact borrowed callback dependency value; callers own
	// synchronization.
	Dependencies any
}

ValidationContext supplies caller-owned dependencies to validation and transformation callbacks.

type ValidationIssue

type ValidationIssue struct {
	// contains filtered or unexported fields
}

ValidationIssue is a terminal-safe field-addressable validation failure. It neither bounds message bytes nor identifies/redacts arbitrary secrets; callers supply non-sensitive localized text. Dedicated secret prompts apply their own generic failure replacement during execution.

func NewValidationIssue

func NewValidationIssue(code string, message string, fields ...string) *ValidationIssue

NewValidationIssue creates a validation failure with defensively copied, terminal-safe content.

func (*ValidationIssue) Code

func (issue *ValidationIssue) Code() string

Code returns the stable machine-readable issue code.

func (*ValidationIssue) Error

func (issue *ValidationIssue) Error() string

Error returns message, then code, then generic text; nil is safe.

func (*ValidationIssue) Fields

func (issue *ValidationIssue) Fields() []string

Fields returns a defensive copy of relevant prompt identities.

func (*ValidationIssue) Message

func (issue *ValidationIssue) Message() string

Message returns safe caller-facing text.

type Validator

type Validator[T any] func(context.Context, T, ValidationContext) error

Validator checks a typed value synchronously. Callbacks must cooperate with context and avoid mutating retained caller data; pipeline panics become ErrAdapter. Secret callbacks must not independently log or retain revealed input.

type VirtualClock

type VirtualClock struct {
	// contains filtered or unexported fields
}

VirtualClock is a deterministic parallel-safe clock with no goroutines or real sleeps. Advance is the only way positive-duration events fire. Use NewVirtualClock; its zero value cannot register positive-duration events. Do not copy its mutex. Stopping leaves buffered ticks and channels intact.

func NewVirtualClock

func NewVirtualClock(start time.Time) *VirtualClock

NewVirtualClock creates a fixed starting instant.

func (*VirtualClock) Advance

func (clock *VirtualClock) Advance(duration time.Duration) error

Advance moves time forward, fires timers, and coalesces ticker events to one buffered tick while preserving the first due instant.

func (*VirtualClock) NewTicker

func (clock *VirtualClock) NewTicker(interval time.Duration) Ticker

NewTicker creates an owned coalescing virtual ticker. A non-positive interval creates a stopped ticker because the interface cannot return an ordinary configuration error.

func (*VirtualClock) NewTimer

func (clock *VirtualClock) NewTimer(duration time.Duration) Timer

NewTimer creates an owned virtual timer. Non-positive durations fire immediately without requiring Advance.

func (*VirtualClock) Now

func (clock *VirtualClock) Now() time.Time

Now returns the current virtual instant.

type VirtualTerminal

type VirtualTerminal struct {
	// contains filtered or unexported fields
}

VirtualTerminal is a parallel-safe deterministic event source, terminal controller, and output capture for tests. It never touches a real terminal.

func NewVirtualTerminal

func NewVirtualTerminal(width, height int) *VirtualTerminal

NewVirtualTerminal creates a fixed-capability terminal with a bounded event queue of 4096 events. Use the constructor; its zero value is not usable. Closing input does not drain/destroy queued byte wrappers, which retain their transferred lifetime until consumed or explicitly released by the owner.

func (*VirtualTerminal) Acquire

func (terminal *VirtualTerminal) Acquire(context.Context) error

Acquire marks the virtual terminal acquired.

func (*VirtualTerminal) Acquired

func (terminal *VirtualTerminal) Acquired() bool

Acquired reports latest successful virtual acquisition state.

func (*VirtualTerminal) CloseInput

func (terminal *VirtualTerminal) CloseInput()

CloseInput makes an exhausted event sequence return EOF.

func (*VirtualTerminal) EchoEnabled

func (terminal *VirtualTerminal) EchoEnabled() bool

EchoEnabled reports latest virtual echo state.

func (*VirtualTerminal) FailAcquire

func (terminal *VirtualTerminal) FailAcquire(err error)

FailAcquire injects an acquisition failure; nil clears it.

func (*VirtualTerminal) FailEcho

func (terminal *VirtualTerminal) FailEcho(err error)

FailEcho injects an echo failure; nil clears it.

func (*VirtualTerminal) FailRelease

func (terminal *VirtualTerminal) FailRelease(err error)

FailRelease injects a release failure; nil clears it.

func (*VirtualTerminal) Height

func (terminal *VirtualTerminal) Height() int

Height returns latest virtual output height under the fixture lock.

func (*VirtualTerminal) Next

func (terminal *VirtualTerminal) Next(ctx context.Context) (InputEvent, error)

Next returns the next event, EOF, or the context cause.

func (*VirtualTerminal) Output

func (terminal *VirtualTerminal) Output() string

Output returns a copy of captured output as a string.

func (*VirtualTerminal) Push

func (terminal *VirtualTerminal) Push(events ...InputEvent) error

Push queues events without copying byte wrappers. Capacity failure can follow a successfully queued prefix; ownership of enqueued events has transferred. Caller destroys unqueued byte payloads. Concurrent Push calls can interleave.

func (*VirtualTerminal) Release

func (terminal *VirtualTerminal) Release() error

Release marks the virtual terminal released.

func (*VirtualTerminal) Released

func (terminal *VirtualTerminal) Released() bool

Released reports latest successful virtual release state.

func (*VirtualTerminal) SetEcho

func (terminal *VirtualTerminal) SetEcho(enabled bool) error

SetEcho records virtual echo state.

func (*VirtualTerminal) Width

func (terminal *VirtualTerminal) Width() int

Width returns latest virtual output width under the fixture lock.

func (*VirtualTerminal) Write

func (terminal *VirtualTerminal) Write(value []byte) (int, error)

Write captures output.

Directories

Path Synopsis
adapters
terminal
Package promptsterminal provides an explicit application adapter for caller-owned terminal files.
Package promptsterminal provides an explicit application adapter for caller-owned terminal files.
Package terminal preserves the original terminal-adapter import path.
Package terminal preserves the original terminal-adapter import path.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址