feat(tpagectl): add interactive mode #606
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
thwap/thwap-pagesd!606
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/tpagectl-interactive"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Implements Phase 7 interactive mode (roadmap #276).
internal/tpagectl/interactive— active only when both stdin and stdout are terminals (a clean gate that keeps all tests and piped output on the existing non-interactive paths). Provides:Prompt/ResolveValue— free-text prompts for omitted required values (#274).ResolveSite— lists registered sites and lets the user pick via a fuzzy finder (#275): live case-insensitive subsequence filter (position-ranked), arrow-key navigation, Enter confirms, Esc/Ctrl-C cancels, raw-mode stdin viax/term, rendered with konsorucursor/screen/style, keys parsed withkonsoru/input.site createfills in missing--name/--owner/--visibilityinteractively (the urfaveRequiredflags are relaxed; non-interactive missing values now fall through to the existingbuildCreateRequestvalidation).deployment getprompts for--version/--latest;preview get/deploy/deleteprompt for--branch.site get/delete/update,deployment list/get/promote/rollback,preview list/get/deploy/delete. Omitted values without a terminal still return the exact same validation errors.Why
Roadmap task #276, the last item in Phase 7.
Testing
interactiveunit tests: subsequence filter (case-insensitive, position-ranked, empty query),subsequenceAt,selectInteractivefed synthetic key bytes ("bl\r"confirms "blog","\x1b[B\r"arrow-down selects index 1,"\x1b"cancels),Enabledfalse for buffered writer,ResolveValueprovided-wins and non-interactive validation,Promptsite createrequired-flag test updated to the new validation messagego test -race ./...passes (28 packages)golangci-lint runcleanBreaking Changes
None for scripting: without a terminal the behavior and messages are identical.
site createno longer relies on urfave'sRequired: truefor the three flags (same validation, now with interactive prompting).Notes
konsoru/inputadded to the vendor tree. True TTY end-to-end interaction is not unit-tested (no pty dependency); theio.Reader-based core plus the both-terminals gate give deterministic coverage.Closes #274
Closes #275
Closes #276
Well-constructed interactive layer. The both-terminals gate cleanly preserves all non-interactive paths, raw mode is set and restored correctly around the picker, escape/Ctrl-C cancel semantics work with the vendored
konsoru/input(verifiedKeyEvent.CtrlandParseSequencebehavior), and the fuzzy filter (case-insensitive subsequence, position-ranked) is sound.ResolveSite/ResolveValue/prompt wiring across site/deployment/preview is consistent and non-terminal behavior is unchanged. Approving; one robustness gap filed.Suggestions
internal/tpagectl/interactive/interactive.go:35– No escape hatch for interactive mode. Pty-based automation (script,expect, CI with a pty, tmux,ssh -t) satisfies "stdin and stdout are terminals", so a missing required value now blocks on a prompt where it previously failed fast with exit 5 — scripts can hang. Add an override (TPAGECTL_INTERACTIVE=0,--no-interactive, or disable underCI/TERM=dumb). Filed as #607.Notes
selectInteractiveplaces the cursor at the fixed start-of-query position on every redraw (cursor.MoveTo(1, len(prompt)+3)); it never tracks the typed query. Input remains correct (append/backspace at the string level), purely a cosmetic cursor placement issue.deployment getinteractive version prompt can't select--latest(the label hints at it, but there's no picker entry for it) — a minor UX dead-end.promptCreateFlags(empty prompt → skip tobuildCreateRequest) andResolveValue(empty → direct validation error) handle empty input slightly differently, converging on the same validation messages.Praise
MakeRawfailure (proceeds cooked) and always restores the terminal via defer.