Skip to content

Feature tui-prompts: Phase 2 — Wire walkthrough.js to the new TUI prompts (hy-9aan8)#29

Merged
philcunliffe merged 1 commit into
integration/tui-promptsfrom
polecat/hy-9aan8
May 23, 2026
Merged

Feature tui-prompts: Phase 2 — Wire walkthrough.js to the new TUI prompts (hy-9aan8)#29
philcunliffe merged 1 commit into
integration/tui-promptsfrom
polecat/hy-9aan8

Conversation

@philcunliffe
Copy link
Copy Markdown
Contributor

Summary

Feature tui-prompts: Phase 2 — Wire walkthrough.js to the new TUI prompts

Implemented: wired hyp init walkthrough to the TUI multiselect/text prompts. New tui-router.js exports shouldUseTui (TTY-on-both-ends + HYP_NO_TUI=1 escape) and isTty. defaultPromptFactory/defaultRetentionPromptFactory are now thin routers between renamed legacy factories and new tuiPromptFactory/tuiRetentionPromptFactory. Tests: 9 router cases + 2 runPickerWalkthrough flows (TUI happy via raw keypresses, HYP_NO_TUI=1 fallback). npm test 341/341 green; lint clean. Existing walkthrough-prompt.test.js unchanged. Manual TTY smoke for 'hyp init' deferred per bead allowance (no hermetic harness).

Delivery

  • Issue: hy-9aan8
  • Branch: polecat/hy-9aan8
  • Integration target: integration/tui-prompts
  • Eventual target: master

This PR is auto-merged into the integration branch once CI is green. Human review for the full feature happens on the downstream PR (integration/tui-prompts -> master), which is opened separately when the feature is ready to ship.

`hyp init` now drives the new TUI multiselect/text prompts when running
against a real TTY on both stdin and stdout. Existing non-TTY callers
(CI, piped stdin, tests injecting PassThrough streams) keep getting the
legacy numbered prompt unchanged, and `HYP_NO_TUI=1` forces the legacy
path even on a TTY for shells that mangle ANSI sequences.

- Rename `defaultPromptFactory` → `legacyNumberedPromptFactory` and
  `defaultRetentionPromptFactory` → `legacyRetentionPromptFactory`
  with their bodies untouched. Add `tuiPromptFactory` (multiselect)
  and `tuiRetentionPromptFactory` (text with non-negative-int validate).
- Re-introduce `defaultPromptFactory` / `defaultRetentionPromptFactory`
  as thin routers that delegate to the right factory. Public
  `AsyncPickPrompt` / `AsyncRetentionPrompt` contracts are unchanged.
- New `src/core/cli/tui-router.js` houses `shouldUseTui` + `isTty` so
  the routing decision is unit-testable in isolation.
- Tests: 9 router cases (TTY combos, HYP_NO_TUI literal "1" only,
  duck-typed `{ write }` sink, omitted `opts.stdin`) plus 2 picker
  walkthrough flows — one TUI happy path driven by raw keypresses,
  one HYP_NO_TUI=1 fallback proving the env override beats the TTY
  probe.

Manual `hyp init` against a real TTY remains a manual verification
step; the bead allowed deferring that smoke when a hermetic harness
isn't available.
@philcunliffe philcunliffe merged commit e036f35 into integration/tui-prompts May 23, 2026
6 checks passed
@philcunliffe philcunliffe deleted the polecat/hy-9aan8 branch May 23, 2026 00:09
philcunliffe added a commit that referenced this pull request May 26, 2026
* chore: seed integration/tui-prompts for feature flow

* feat: TUI primitives module + package export + tests (hy-f4zzf) (#27)

Adds a zero-dependency TUI primitives module that future callers (the
`hyp init` walkthrough in phase 2, and plugin setup commands) can use
to render real interactive prompts. Phase 1 ships the widgets only —
walkthrough.js is untouched and `hyp init` keeps its numbered prompt.

Module layout (src/core/cli/tui/):
- keypress.js — pure reducer (state, key) → state for all four
  primitives; cursor/wrap, toggle/toggle-all, 1-9 jump, bounds
  validation, validate-aware text confirm, ctrl+c/escape cancel.
- render.js — pure frame builder; honors NO_COLOR; emits cursor-move
  escapes separately from SGR color escapes.
- runtime.js — raw-mode keypress loop. Hides cursor, dispatches into
  the reducer, restores raw mode and shows the cursor in `finally` on
  every exit path (resolve, cancel, throw). Throws the documented
  TTY error for non-TTY streams or HYP_NO_TUI=1.
- index.js — entrypoint exporting `multiselect`, `select`, `text`,
  `confirm`, and `PromptCancelledError`.

Package export `./tui` lets sibling packages
`import { multiselect } from 'hypaware/tui'`.

Tests under test/core/cli/tui/ cover the reducer exhaustively, the
frame builder, runtime I/O via fake-TTY PassThrough streams, the
non-TTY guard (with and without HYP_NO_TUI), and the package export
resolution.

The npm test script switched to `find … | xargs node --test` so
deeper directories under test/ are picked up — the old shell glob
only matched two levels on the default macOS /bin/sh.

* feat: wire walkthrough to TUI prompts with HYP_NO_TUI escape (hy-9aan8) (#29)

`hyp init` now drives the new TUI multiselect/text prompts when running
against a real TTY on both stdin and stdout. Existing non-TTY callers
(CI, piped stdin, tests injecting PassThrough streams) keep getting the
legacy numbered prompt unchanged, and `HYP_NO_TUI=1` forces the legacy
path even on a TTY for shells that mangle ANSI sequences.

- Rename `defaultPromptFactory` → `legacyNumberedPromptFactory` and
  `defaultRetentionPromptFactory` → `legacyRetentionPromptFactory`
  with their bodies untouched. Add `tuiPromptFactory` (multiselect)
  and `tuiRetentionPromptFactory` (text with non-negative-int validate).
- Re-introduce `defaultPromptFactory` / `defaultRetentionPromptFactory`
  as thin routers that delegate to the right factory. Public
  `AsyncPickPrompt` / `AsyncRetentionPrompt` contracts are unchanged.
- New `src/core/cli/tui-router.js` houses `shouldUseTui` + `isTty` so
  the routing decision is unit-testable in isolation.
- Tests: 9 router cases (TTY combos, HYP_NO_TUI literal "1" only,
  duck-typed `{ write }` sink, omitted `opts.stdin`) plus 2 picker
  walkthrough flows — one TUI happy path driven by raw keypresses,
  one HYP_NO_TUI=1 fallback proving the env override beats the TTY
  probe.

Manual `hyp init` against a real TTY remains a manual verification
step; the bead allowed deferring that smoke when a hermetic harness
isn't available.

* fix(tui): thread env + handle cancel + portable test runner (hy-3a7ri) (PR #26) (#32)

Address the three findings on integration/tui-prompts dual-review:

- Contract & Interface Fidelity (major): shouldUseTui and TUI runtime
  now read HYP_NO_TUI/NO_COLOR through opts.env when supplied, falling
  back to process.env only when nothing is injected. The walkthrough
  threads env through multiselect/text so env-injected runs flip the
  TUI path consistently.

- Error Handling & Resilience (major): runPickerWalkthrough catches
  PromptCancelledError and returns exit code 130 (SIGINT convention)
  with a "hyp init: cancelled" stderr line, instead of letting cancels
  fall into the dispatcher's generic unhandled-exception path.

- Release Safety (minor): replace shell find/xargs in `npm test` with
  scripts/run-tests.js (Node-driven, mirrors check-syntax.js). The
  script discovers *.test.js under test/ and execs `node --test` with
  the resolved paths so the suite runs on Windows shells too.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(tui): address PR 26 review cleanup

* fix(tui): repair merge-ref typecheck

---------

Co-authored-by: feature-launch <feature-launch@gas.city>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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