Skip to content

feat(windows): PS 5.1 ASCII picker, Resolve-FinalToolset, TUI tests [Slice 3] (#495) - #506

Open
primetimetank21 wants to merge 3 commits into
developfrom
squad/495-tui-picker-powershell-slice-3
Open

feat(windows): PS 5.1 ASCII picker, Resolve-FinalToolset, TUI tests [Slice 3] (#495)#506
primetimetank21 wants to merge 3 commits into
developfrom
squad/495-tui-picker-powershell-slice-3

Conversation

@primetimetank21

@primetimetank21 primetimetank21 commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Slice 3: PS 5.1 ASCII Picker + Resolve-FinalToolset Refactor

Part of #495


Scope

This PR implements Slice 3 only of the #495 TUI picker plan.

New file scripts/windows/lib/tui.ps1:

  • Resolve-FinalToolset: canonical ordered tool resolver (pure function, no exit, no I/O). Replaces the inline FinalTools build block in setup.ps1. Handles default/only/skip paths with order preservation and alphabetic opt-in appending.
  • Show-ToolMenu: [Console]::ReadKey($True) loop, pure ASCII display ([x]/[ ], no Write-Host, no Unicode). Keys: Up/Down, Space, A toggle-all, Enter, Esc/Q. Defaults pre-checked; opt-ins unchecked + labeled (opt-in). Cancel returns $null; nothing-selected returns [string[]]@(); confirmed returns [string[]]. ReadKey failure catches to one stderr warning ("Interactive menu failed; installation is being cancelled.") + returns $null (Install cancelled.).

Refactored scripts/windows/setup.ps1:

  • Dot-sources lib/tui.ps1 (after logging.ps1 + path.ps1).
  • Removes old inline /// block; all paths now call Resolve-FinalToolset.
  • Wires Test-ShouldShowMenu result to menu dispatch: interactive path handles SelectionFile seam or Show-ToolMenu; non-interactive path validates and resolves via flags.
  • Adds _PS_TUI_TEST_MENU env seam to Test-ShouldShowMenu (hidden; enables headless integration tests).
  • Cancel/nothing-selected messages use Write-Output (PSSA-clean).

New file tests/test_tui_pwsh.ps1 (9 tests):

  • Unit: T_resolve_toolset_defaults/only/skip_ps
  • Integration: T_menu_selection_file_e2e_ps, T_menu_noop_empty_ps, T_noarg_noninteractive_compat_ps [DRIFT]
  • Static: T_ascii_purity_ps, T_help_no_seam_ps, T_parse_tui_ps51

Updated .github/workflows/validate.yml:

  • lint-powershell: PSSA for scripts/windows/lib/tui.ps1
  • validate-ps51: (restored job key) syntax check + PSSA for tui.ps1; run test_tui_pwsh.ps1 under PowerShell 5.1
  • validate-powershell: run test_tui_pwsh.ps1 under pwsh (modern)

Excluded

  • No Bash changes (Slice 2 is independent draft PR feat(tui): Bash checkbox menu (#495 Slice 2) #505 -- not touched)
  • No Slice 4 docs or broad CI redesign
  • No --help exposure of -SelectionFile (hidden seam)
  • Resolve-ToolSelection removed (dead function -- Show-ToolMenu result feeds Resolve-FinalToolset directly)
  • _PS_TUI_MOCK fake seam removed (tested bypass, not production control flow)

Rejection Findings Fixed (Rex corrective revision, Hardcase locked out)

  1. validate-ps51 job key was missing (YAML merged the job body into validate-powershell, silently dropping the PS 5.1 CI job)
  2. Resolve-ToolSelection was dead production code and its 4 tests removed
  3. _PS_TUI_MOCK fake seam removed; T_menu_cancel_aborts_ps removed; cancel/ReadKey failure remain manual gates
  4. ReadKey catch warning corrected: "Interactive menu failed; installation is being cancelled." -- no longer promises non-interactive proceed; caller receives $null -> "Install cancelled."
  5. $null vs @() return semantics verified under PS 5.1 and pwsh: cancel (return $null) and empty (return ,$selected) are distinguishable at caller

CI Gates

All existing CI checks preserved. New gates added:

  • PSSA 0 findings on tui.ps1 (lint-powershell, validate-ps51)
  • PS 5.1 syntax parse on tui.ps1 (validate-ps51)
  • 9 TUI tests pass under PS 5.1 and pwsh (validate-ps51, validate-powershell)
  • 50 Slice 1 flag tests still pass (validate-ps51)
  • [DRIFT] T_noarg_noninteractive_compat_ps confirms no regression

Manual TTY Verification Required (Kix Protocol)

These cannot be tested headlessly:

  1. Cancel (Esc/Q): exit 0, "Install cancelled." printed, nothing installed
  2. Arrow Up/Down navigation in Windows Terminal (PS 5.1 + pwsh)
  3. Arrow navigation in legacy conhost (cmd.exe host, PS 5.1)
  4. Opt-in tools shown unchecked below defaults, labeled (opt-in)
  5. Space toggles; A toggles all
  6. All defaults checked + Enter == no-arg non-interactive run result
  7. Uncheck a default, confirm => that tool is skipped
  8. [Console]::ReadKey exception path: warning to stderr ("Interactive menu failed; installation is being cancelled."), exit 0, nothing installed

Relationship to Other PRs

primetimetank21 and others added 3 commits August 5, 2026 04:04
…495)

- Add scripts/windows/lib/tui.ps1 with Resolve-FinalToolset (canonical
  ordered resolver), Resolve-ToolSelection (checked-array to CSV), and
  Show-ToolMenu ([Console]::ReadKey loop, ASCII-only, no Write-Host).
- Refactor scripts/windows/setup.ps1: extract inline FinalToolset building
  into Resolve-FinalToolset calls; wire menu/selection-file dispatch under
  Test-ShouldShowMenu; add _PS_TUI_TEST_MENU env seam to Test-ShouldShowMenu
  for headless integration tests.
- Add tests/test_tui_pwsh.ps1: 14 tests covering resolver defaults/only/skip,
  selection resolver defaults/subset/opt-in/empty, selection-file E2E,
  cancel/empty guards (seam-driven), drift gate, ASCII purity, help hiding,
  PS 5.1 parse check.
- Update .github/workflows/validate.yml: PSSA for tui.ps1 in lint-powershell;
  tui.ps1 syntax check + PSSA + test_tui_pwsh.ps1 in validate-ps51;
  test_tui_pwsh.ps1 in validate-powershell (pwsh).

Part of #495

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- validate.yml: restore validate-ps51 job key (was merged into
  validate-powershell body, breaking YAML structure and dropping the
  dedicated PS 5.1 CI job entirely)
- tui.ps1: remove Resolve-ToolSelection (dead function; Show-ToolMenu
  internal result feeds Resolve-FinalToolset directly, no CSV mapping
  needed at that layer)
- tui.ps1: remove _PS_TUI_MOCK seam (fake bypass returning final result,
  not driving state machine); cancel/empty live behavior under manual gate
- tui.ps1: fix ReadKey catch warning to say 'Interactive menu failed;
  installation is being cancelled.' -- no longer misleads caller about
  proceeding non-interactively; return null drives 'Install cancelled.'
- tui.ps1: document null-vs-empty return contract (cancel = return null,
  non-null = return comma-prefixed array; distinguishable at caller,
  verified under PS 5.1 and pwsh)
- test_tui_pwsh.ps1: remove 4 Resolve-ToolSelection unit tests (dead
  function removed), remove T_menu_cancel_aborts_ps (tested _PS_TUI_MOCK
  bypass only, not production flow); 14 -> 9 tests remain
- test_tui_pwsh.ps1: update manual gate list (cancel explicitly named,
  ReadKey failure warning wording updated)

Authored by Rex (CT-7567), independent revision author for rejected PR #506.
Hardcase strictly locked out per reviewer protocol.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Update exports list to match actual exported functions, removing Resolve-ToolSelection.
- Keep Resolve-FinalToolset and Show-ToolMenu exports listed.

Authored by Tech, third independent revision author for rejected PR #506.
Hardcase and Rex strictly locked out per reviewer protocol.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@primetimetank21

Copy link
Copy Markdown
Owner Author

Manual Verification: Group A TUI Behaviors

Date: 2026-08-07
Tester: Earl Tankard, Jr., Ph.D
Environment: Windows Terminal with -ToolsDir tests\fixtures\stub-tools\windows\

All Group A interactive menu behaviors verified passing:

  • ✅ Arrow navigation (up/down cursor movement)
  • ✅ Space bar toggle (selection state)
  • ✅ A key toggle-all (select/deselect all items)
  • ✅ Default and opt-in label rendering
  • ✅ Esc and Q cancel (null return, installation aborted)
  • ✅ Enter confirmation with stub logging

All manual gates cleared. Ready for review.

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