prompt

package
v0.25.0 Latest Latest
Warning

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

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

Documentation

Overview

Package prompt provides interactive CLI prompts for solo-provisioner commands.

When a command is invoked without required flags, the prompt layer presents user-friendly forms (powered by charmbracelet/huh) to collect the missing values before the workflow starts. Prompts are skipped when:

  • --non-interactive is set (CI/pipelines)
  • --force / -y is set (auto-accept defaults)
  • stdout is not a TTY (pipes, redirected output)
  • the flag was already provided on the command line

Each prompt shows the effective value (from config.yaml, env, or defaults) as the pre-selected/suggested value. The user can accept it with Enter or override it by typing/selecting a different value.

Index

Constants

View Source
const (
	ComponentConsensusNode = "consensus-node"
	ComponentBlockNode     = "block-node"
)

Component name constants are the canonical identifiers used in --components, daemon.yaml, and all component-branching logic. Always reference these constants — never use raw string literals for component names.

Variables

View Source
var ErrAborted = errorx.RejectedOperation.New("aborted by user")

ErrAborted is returned when the user cancels out of an interactive prompt. It is an errorx-typed sentinel so callers can `errors.Is(err, ErrAborted)` and the doctor layer can branch on the RejectedOperation namespace.

Functions

func AddInputPrompts added in v0.22.0

func AddInputPrompts(w *Wizard, cmd *cobra.Command, prompts []InputPrompt, cv *ChosenValues)

AddInputPrompts appends a wizard page (one group) containing a text-input field for each prompt whose flag was not already supplied on the command line and is registered on the command. Nothing is added when every prompt is skipped. Each prompt's Target pointer is pre-filled with its effective value; chosen values are recorded into cv by an afterRun callback once the wizard form completes.

func AddPluginPresetPrompts added in v0.22.0

func AddPluginPresetPrompts(
	w *Wizard,
	cmd *cobra.Command,
	defaults state.PromptDefaults,
	flagPluginPreset *string,
	flagPlugins *string,
	chartVersion *string,
	valuesFile string,
	cv *ChosenValues,
)

AddPluginPresetPrompts appends the plugin wizard pages: a preset-select page and a conditional custom-plugin multi-select page shown via huh.Group.WithHideFunc only when the Custom preset is selected. Because both pages live in the same wizard form, the operator can navigate back to the preset page and switch away from Custom — the multi-select page hides again and --plugins is left empty (normalised in afterRun).

The preset-select page pre-selects the last used preset read from the on-disk state file. When the operator's --values file defines plugins.names, the "no override" preset (PresetNone) is pre-selected instead so the values file wins unless the operator actively picks a preset.

The custom multi-select page lists all known block-node plugins for the live chartVersion; the operator's selection is joined as a comma-separated string and written to *flagPlugins.

The function is a no-op when either flag was already supplied on the command line — the caller's values are respected as-is.

Parameters:

  • w: the wizard accumulating pages
  • cmd: the Cobra command (used for flag-changed detection)
  • defaults: prompt defaults read from the on-disk state file
  • flagPluginPreset: pointer to the --plugin-preset flag variable
  • flagPlugins: pointer to the --plugins flag variable
  • chartVersion: pointer to the target chart version (used to filter available plugins)
  • valuesFile: path to the operator's --values file (empty when not supplied); used to smart-default the preset to "no override" when it defines plugins.names
  • cv: chosen-values collector for summary printing

The custom multi-select's option list and warning are rebuilt via OptionsFunc / DescriptionFunc bound to *chartVersion, so editing the chart-version input earlier in the same wizard re-shapes the available plugins; huh reconciles the current selection against the new option set (dropping plugins that no longer apply). chartVersion is taken by pointer so those bindings observe later edits.

func AddSelectPrompts added in v0.22.0

func AddSelectPrompts(w *Wizard, cmd *cobra.Command, prompts []SelectPrompt, cv *ChosenValues)

AddSelectPrompts appends a wizard page (one group) containing a select field for each prompt whose flag was not already supplied on the command line. Nothing is added when every prompt is skipped. Each prompt's Target pointer is pre-seeded with its effective value so pressing Enter accepts it; chosen values are recorded into cv by an afterRun callback once the wizard form completes.

func AddStoragePathPrompts added in v0.22.0

func AddStoragePathPrompts(
	w *Wizard,
	cmd *cobra.Command,
	defaults state.PromptDefaults,
	chartVersion *string,
	targets StoragePathTargets,
	cv *ChosenValues,
)

AddStoragePathPrompts appends the storage-path wizard pages: a mode-select page (single base path vs individual paths) followed by two mutually-exclusive path pages, each shown via huh.Group.WithHideFunc based on the selected mode. Because the mode select and the path groups live in the same wizard form, the operator can navigate back to the mode page and switch modes — the path page re-renders to match, including when navigating backward.

The function is a no-op when any storage-related flag was already provided on the command line — the caller's flag values are respected as-is.

Parameters:

  • w: the wizard accumulating pages
  • cmd: the Cobra command (used for flag-changed detection)
  • defaults: prompt defaults read from the on-disk state file
  • chartVersion: the target chart version, used to filter optional-storage prompts
  • targets: pointers to the seven storage path flag variables
  • cv: chosen-values collector for summary printing

All individual paths — the always-present core paths (archive, live, log) plus the optional paths (verification, plugins, application-state) — live on a single wizard page (one huh group). Every input is wrapped in a spacedField, and the optional ones are gated on the registry's RequiredByVersion for the *live* chart version: an optional field whose hidden func (re-reading *chartVersion) reports not-applicable is skipped and rendered empty. Because huh can hide only whole groups (not individual fields) yet recomputes field positions on every keypress, this keeps every applicable path on one page while still re-shaping which optional paths are shown — and the individual-paths label — as the operator edits the chart-version input earlier in the same wizard. chartVersion is taken by pointer so huh's dynamic-func bindings observe those later edits.

The group runs with huh's built-in field separator zeroed (soloThemeNoFieldSeparator, applied via the wizard's per-group theme override); each spacedField instead prepends its own leading gap when an earlier field is visible, so a hidden field in the middle leaves no doubled blank line and spacing stays even no matter which optional paths are hidden.

func ParsePortList added in v0.22.0

func ParsePortList(s string) ([]int, error)

ParsePortList parses a comma-separated port list into ints, skipping blanks. It assumes the input already passed validateInClusterPorts.

func RunConfirm

func RunConfirm(title string, description string, defaultValue bool) (bool, error)

RunConfirm presents a styled confirmation prompt and returns the user's choice. The defaultValue determines which option is pre-selected.

func RunDaemonInstallPrompts added in v0.20.0

func RunDaemonInstallPrompts(
	cmd *cobra.Command,
	cfg *daemon.DaemonConfig,
	targets DaemonInstallInputTargets,
	paths models.WeaverPaths,
	cv *ChosenValues,
) error

RunDaemonInstallPrompts presents interactive prompts for the daemon service install command. It first resolves which components to enable (from --components or via interactive confirm prompts), then presents the relevant per-component input fields.

cfg is updated in-place to reflect newly-enabled components and entered values. Chosen values are collected into cv for summary printing.

func RunInputPrompts

func RunInputPrompts(cmd *cobra.Command, prompts []InputPrompt, cv *ChosenValues) error

RunInputPrompts presents interactive text-input prompts for any flags that were not explicitly set on the command line.

It runs the inputs as a single-page wizard; multi-stage callers should use AddInputPrompts to combine this page with others into one navigable form.

func RunPluginPresetPrompts added in v0.17.0

func RunPluginPresetPrompts(
	cmd *cobra.Command,
	defaults state.PromptDefaults,
	flagPluginPreset *string,
	flagPlugins *string,
	chartVersion string,
	valuesFile string,
	cv *ChosenValues,
) error

RunPluginPresetPrompts presents the plugin preset prompts as a standalone wizard. It is retained for callers that run plugin prompts in isolation; the block-node install flow uses AddPluginPresetPrompts to combine these pages with the rest of the installation wizard. It is a no-op when either --plugins or --plugin-preset was already provided on the command line.

func RunSelectPrompts

func RunSelectPrompts(cmd *cobra.Command, prompts []SelectPrompt, cv *ChosenValues) error

RunSelectPrompts presents interactive select prompts for any flags that were not explicitly set on the command line. Returns nil if all flags are already set or prompts are not applicable.

It runs the selects as a single-page wizard; multi-stage callers should use AddSelectPrompts to combine this page with others into one navigable form.

func RunStoragePathPrompts added in v0.17.0

func RunStoragePathPrompts(
	cmd *cobra.Command,
	defaults state.PromptDefaults,
	chartVersion string,
	targets StoragePathTargets,
	cv *ChosenValues,
) error

RunStoragePathPrompts presents the storage-path prompts as a standalone wizard. It is retained for callers that run storage prompts in isolation; the block-node install flow uses AddStoragePathPrompts to combine these pages with the rest of the installation wizard into one navigable form. It is a no-op when any storage-related flag was already provided on the command line.

func ShouldPrompt

func ShouldPrompt(force bool) bool

ShouldPrompt returns true when interactive prompts should be presented. It returns false when the TUI is suppressed (non-interactive, not a TTY).

func SoloTheme

func SoloTheme() *huh.Theme

SoloTheme returns a huh.Theme styled to match the solo-provisioner TUI.

The color palette mirrors the existing view.go/style constants:

"6" = cyan (spinners, accents)
"2" = green (success, cursor)
"1" = red (errors)
"8" = grey (descriptions, durations)
"3" = yellow (warnings, selectors)

Types

type ChosenValues

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

ChosenValues collects prompted values across multiple Run*Prompts calls so they can be printed as a single summary block with a header.

func NewChosenValues

func NewChosenValues() *ChosenValues

NewChosenValues creates a new collector for prompted values.

func (*ChosenValues) Print

func (cv *ChosenValues) Print(header string)

Print prints a styled header followed by indented chosen values. It is a no-op when no values were collected.

type ComponentSet added in v0.20.0

type ComponentSet map[string]struct{}

ComponentSet holds the set of daemon components selected by the operator. Use Has() to test membership; Empty() to detect nothing selected.

func ParseComponentsFlag added in v0.20.0

func ParseComponentsFlag(raw string) ComponentSet

ParseComponentsFlag splits a comma-separated --components value into a ComponentSet. Unknown names are silently ignored so a newer daemon.yaml opened by an older CLI does not error.

func (ComponentSet) Empty added in v0.20.0

func (cs ComponentSet) Empty() bool

Empty returns true when no component was selected.

func (ComponentSet) Has added in v0.20.0

func (cs ComponentSet) Has(name string) bool

Has returns true if name was selected.

func (ComponentSet) String added in v0.20.0

func (cs ComponentSet) String() string

String serialises the set back to a comma-separated list in knownComponents order — suitable for writing back into the --components flag variable.

type DaemonInstallInputTargets added in v0.20.0

type DaemonInstallInputTargets struct {
	// ComponentsRaw is the --components flag variable pointer.
	ComponentsRaw *string

	// Per-component field pointers — nil when the component was not pre-selected
	// (they are wired in after the component-selection step).
	CNNodeID     *string
	CNOrbit      *string
	CNUpgradeDir *string
	BNOrbit      *string
}

DaemonInstallInputTargets carries flag-variable pointers for the daemon install prompts. ComponentsRaw is both read (detect pre-set flag) and written (record interactive choices).

type InputPrompt

type InputPrompt struct {
	// FlagName is the Cobra flag name. Used to detect if already supplied.
	FlagName string

	// Title is displayed as the prompt header.
	Title string

	// Description is displayed below the title.
	Description string

	// Placeholder is the greyed-out hint shown when the input is empty.
	Placeholder string

	// EffectiveValue is the suggested default — pre-filled in the input.
	EffectiveValue string

	// Target is a pointer to the flag variable that will receive the entered value.
	Target *string

	// Validate is an optional validation function applied on submit.
	Validate func(string) error
}

InputPrompt defines an interactive text-input prompt for a flag with free-form text.

func BlockNodeInputPrompts

func BlockNodeInputPrompts(defaults state.PromptDefaults, flagNamespace, flagReleaseName, flagChartVersion, flagHistoricRetention, flagRecentRetention *string) []InputPrompt

BlockNodeInputPrompts returns the text-input-type prompts for install/upgrade commands. Includes namespace, release-name, chart-version and retention thresholds.

Parameters:

  • defaults: prompt defaults read from the on-disk state file
  • flagNamespace: pointer to the flag variable for --namespace
  • flagReleaseName: pointer to the flag variable for --release-name
  • flagChartVersion: pointer to the flag variable for --chart-version
  • flagHistoricRetention: pointer to the flag variable for --historic-retention
  • flagRecentRetention: pointer to the flag variable for --recent-retention

func BlockNodeReconfigureInputPrompts added in v0.17.0

func BlockNodeReconfigureInputPrompts(
	defaults state.PromptDefaults,
	flagHistoricRetention, flagRecentRetention *string,
) []InputPrompt

BlockNodeReconfigureInputPrompts returns the text-input-type prompts for the reconfigure command. It omits fields that are immutable once a block node is installed (namespace, release-name) and chart-version (reconfigure never changes the chart version — use upgrade for that).

Storage path prompts are handled separately by RunStoragePathPrompts, which presents a mode select (single base path vs individual paths) before showing only the relevant path inputs. Cross-field completeness is enforced at workflow time by ValidateStorageCompleteness.

Parameters:

  • defaults: prompt defaults read from the on-disk state file
  • flagHistoricRetention: pointer to the flag variable for --historic-retention
  • flagRecentRetention: pointer to the flag variable for --recent-retention

func BlockedCIDRsInputPrompt added in v0.25.0

func BlockedCIDRsInputPrompt(eff string, target *string) InputPrompt

BlockedCIDRsInputPrompt returns the interactive prompt for the host firewall's operator-curated block list. eff is the effective value (from flag/config) shown as the pre-filled suggestion; target receives the comma-separated result. This is distinct from the BN workload plane's `bn-restricted` set, which the traffic-shaper daemon manages automatically — this list is purely operator-managed.

func EgressInterfaceInputPrompt added in v0.22.0

func EgressInterfaceInputPrompt(eff, speedHint string, target *string) InputPrompt

EgressInterfaceInputPrompt returns the interactive prompt for --egress-interface. eff is the auto-detected NIC name used as the placeholder/effective value; speedHint is a tc-style bandwidth string (e.g. "1gbit") derived from the detected NIC's link speed — pass an empty string when the speed is unavailable.

func InClusterPortsInputPrompt added in v0.22.0

func InClusterPortsInputPrompt(eff string, target *string) InputPrompt

InClusterPortsInputPrompt returns the interactive prompt for the in-cluster host-service ports reachable from the pod CIDR.

func LinkRateInputPrompt added in v0.23.0

func LinkRateInputPrompt(speedHint string, target *string) InputPrompt

LinkRateInputPrompt returns the interactive prompt for --link-rate. speedHint is the auto-detected link speed (e.g. "1gbit") used as the pre-filled default; pass an empty string when detection was unavailable. The operator may leave the field blank to keep runtime auto-detection from sysfs.

func MgmtCIDRsInputPrompt added in v0.22.0

func MgmtCIDRsInputPrompt(eff string, target *string) InputPrompt

MgmtCIDRsInputPrompt returns the interactive prompt for the host firewall's SSH/management allowlist. eff is the effective value (from flag/config) shown as the pre-filled suggestion; target receives the comma-separated result.

func PodCIDRInputPrompt added in v0.22.0

func PodCIDRInputPrompt(eff string, target *string) InputPrompt

PodCIDRInputPrompt returns the interactive prompt for the pod CIDR that is allowed to reach the in-cluster host-service ports.

func SSHPortInputPrompt added in v0.22.0

func SSHPortInputPrompt(eff string, target *string) InputPrompt

SSHPortInputPrompt returns the interactive prompt for the SSH/management port.

type SelectPrompt

type SelectPrompt struct {
	// FlagName is the Cobra flag name (e.g. "profile"). Used to detect whether
	// the user already supplied this flag on the command line.
	FlagName string

	// Title is displayed as the prompt header (e.g. "Deployment Profile").
	Title string

	// Description is displayed below the title (e.g. "Select the target network").
	Description string

	// Options are the allowed values the user can choose from.
	Options []string

	// EffectiveValue is the suggested default — pre-selected in the list.
	// It is resolved from the RSL / config before the prompt runs.
	EffectiveValue string

	// Target is a pointer to the flag variable that will receive the selected value.
	Target *string
}

SelectPrompt defines an interactive select prompt for a flag with a fixed set of choices.

func BlockNodeSelectPrompts

func BlockNodeSelectPrompts(defaults state.PromptDefaults, flagProfile *string) []SelectPrompt

BlockNodeSelectPrompts returns the select-type prompts for block node commands. The defaults parameter provides persisted state values read once by the caller; the effective profile is resolved using the priority: persisted state > config > default.

Parameters:

  • defaults: prompt defaults read from the on-disk state file
  • flagProfile: pointer to the flag variable for --profile

type StoragePathTargets added in v0.17.0

type StoragePathTargets struct {
	BasePath             *string
	ArchivePath          *string
	LivePath             *string
	LogPath              *string
	VerificationPath     *string
	PluginsPath          *string
	ApplicationStatePath *string
}

StoragePathTargets holds pointers to the Cobra flag variables for all storage path flags. It is used by RunStoragePathPrompts to keep the parameter count within linter limits.

type Wizard added in v0.22.0

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

Wizard accumulates huh groups (one per wizard page) plus post-run callbacks, then runs them all in a single huh.Form. Presenting every stage as one form is what makes the pages navigable back and forward (Shift+Tab / Tab) — huh's built-in navigation only crosses group boundaries within a single form.

Each stage's post-processing (recording chosen values into ChosenValues, normalising flag targets, joining multi-selects) is deferred into an afterRun callback because a field's value is only final once the shared form completes.

func NewWizard added in v0.22.0

func NewWizard() *Wizard

NewWizard returns an empty wizard ready to accumulate pages.

func (*Wizard) Run added in v0.22.0

func (w *Wizard) Run() error

Run executes all accumulated groups in a single huh form, then fires the afterRun callbacks (which is where all ChosenValues interaction happens). It is a no-op (returns nil) when no pages were added — the same behaviour the per-stage runners had when every prompt was skipped.

Jump to

Keyboard shortcuts

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