Skip to content

feat(tui): make prompt component messages caller-overridable#27

Merged
hi-lei merged 7 commits into
mainfrom
feat/tui-overridable-messages
Jun 2, 2026
Merged

feat(tui): make prompt component messages caller-overridable#27
hi-lei merged 7 commits into
mainfrom
feat/tui-overridable-messages

Conversation

@hi-lei

@hi-lei hi-lei commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Makes user-facing validation/affordance strings in the TUI prompt components caller-overridable instead of hardcoded, so consumers can customize wording without a library change. All changes ship sane defaults — existing callers are unaffected.

Multiselect

  • WithMinSelectionsError(func(min int) string) / WithMaxSelectionsError(func(max int) string) — override the min/max validation messages. nil keeps the library default.
  • Default min message now reads at least %d selections required — press space to select (more actionable).

Editor (previously had no override hooks at all)

  • WithEditorHint(string) — override the (ctrl+d to submit, esc to cancel) affordance text.
  • WithEditorNoHint() — suppress the affordance line entirely (resolves the Hint/Summary sentinel asymmetry).
  • WithEditorSummary(func(lines int) string) — override the post-submit [N lines] summary.

Wizard

  • Step.MinError func(min int) string — lets MultiSelectPrompt steps customize the min-selection message, plumbed through buildPromptModel. Useful to replace the grammatically awkward default (at least 1 selections required) on Required multi-selects.
  • Max/editor overrides intentionally not plumbed: the wizard never sets a max on multi-selects and has no editor prompt type, so wiring them would be dead code.

Design notes

  • Formatter-func pattern (func(count int) string) chosen over format-strings to avoid the %d footgun and stay type-safe.
  • Audited all six prompt components: textinput was already flexible (errors come from the caller's Validate); select/livelist have no validation strings (labels already relabel-able). Multiselect and editor were the genuine gaps.

Testing

  • New unit tests for every override path, including the multiselect toggleAll/Ctrl+A max path and default-when-unset cases for both min and max.
  • Editor: default/override/no-hint/summary tests.
  • Wizard: TestEngine_MultiSelectMinErrorPlumbed drives a real built model end-to-end.
  • go build ./..., full pkg/tui/... suite, go vet, and pre-commit (gofmt/goimports/lint/tests) all green.

🤖 Generated with Claude Code

hi-lei and others added 7 commits June 2, 2026 22:16
The min-selection guard previously showed "at least %d selections
required" without telling the user how to select. Append "— press
space to select" so the error is actionable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The min/max selection validation strings were hardcoded, forcing a
library change for any caller that wanted different wording. Add
WithMinSelectionsError / WithMaxSelectionsError options taking a
func(count int) string; nil keeps the library default, so existing
callers are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The editor was the only prompt component with no override hooks: its
"(ctrl+d to submit, esc to cancel)" affordance and "[N lines]" summary
were hardcoded in View(). Add WithEditorHint(string) and
WithEditorSummary(func(lines int) string); empty/nil keeps the current
output, so existing callers are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…x default

Adversarial review found the max-error override was only exercised
through the space-toggle path, not the separate toggleAll (ctrl+a)
path, and there was no symmetric "default max message" test to mirror
the min case. Add both.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolves the API asymmetry flagged in review: WithEditorHint("") meant
"use default", so a caller could never render an empty/suppressed hint
(unlike Summary, whose nil sentinel lets a func return ""). Add an
explicit WithEditorNoHint() that drops the parenthetical entirely and
takes precedence over WithEditorHint.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Previously the multiselect min/max error overrides were only reachable
via a direct Prompter.MultiSelect call; wizard steps could not set them.
Add Step.MinError and plumb it through buildPromptModel. This lets flows
replace the grammatically awkward default ("at least 1 selections
required") on Required multi-selects.

Max/editor overrides are intentionally not plumbed: the wizard never
sets a max on multi-selects and has no editor prompt type, so wiring
them would be dead code.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hi-lei hi-lei merged commit 9ba54b9 into main Jun 2, 2026
14 checks passed
@hi-lei hi-lei deleted the feat/tui-overridable-messages branch June 2, 2026 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant