Repository navigation
ci: distinguish unusable smoke credentials from CLI regressions - #251
Merged
Merged
Conversation
The `--dashboard` installer mode and hidden `workos dashboard` command were unmaintained. Remove them along with the Ink/React components, the DashboardAdapter, the eval harness's Ink live view, and the ink, react, @types/react, and react-devtools-core dependencies. The installer now uses HeadlessAdapter in JSON mode and CLIAdapter otherwise. Evals always use sequential logging (`--no-dashboard` is gone). BREAKING CHANGE: `workos install --dashboard` / `-d` and `workos dashboard` are removed. Use `workos install`.
Groundwork for the full-screen installer. Nothing imports these yet. react-devtools-core is a build-only devDependency: Ink's reconciler statically imports it behind a DEV gate, and `bun build --compile` must resolve it.
Task labels, walkthrough copy, tips, and announcements live in one bundled, data-only JSON file validated by a zod schema. Walkthrough keys must be real installer events with only the placeholders each event supplies; tips and announcements can target frameworks, and announcements take a date window. Adds a runtime INSTALLER_EVENT_NAMES list that the compiler keeps in sync with InstallerEvents.
setUiHost() routes every ui line (with its log level), spinner status, and confirm/select/text/password prompt to a host such as the full-screen installer. The --json and non-TTY guards and the one-prompt-at-a-time chain still apply in front of the host. With no host registered, output is byte-for-byte unchanged.
A plain subscribe/getSnapshot store over InstallerEventEmitter. It maps machine phases to the task list (settling a task on the next phase's enter, so a failure never flashes "completed"), narrates events with the content copy, and records agent status lines, file changes, and commands. It also holds the pending prompt, spinner status, notices, the outcome, and the tips and announcements for the detected framework. No Ink dependency; tests drive the real installer machine.
In an interactive terminal of at least 80x24, `workos install` now opens a full-screen Ink view: the WorkOS logomark (Arc's raster, precomputed), a task list driven by installer events, a plain-English walkthrough, a rotating tips and news card, and every question asked inline. When it closes, the terminal is restored and the same output a plain run prints is replayed into the scrollback, ending with the completion summary. TuiAdapter wraps CLIAdapter, so every event is still handled and every prompt answered by the same code; it only redirects ui output and prompts through setUiHost() and captures stray console output. ctrl-c goes down the existing SIGINT path, esc/ctrl-c in a prompt cancel it as in the plain CLI, and an exit hook restores the terminal on any process.exit. Adapter selection is a pure, tested function. JSON stays headless; CI/agent modes, piped stdio, TERM=dumb, small terminals, and --no-tui keep the plain CLI adapter. Telemetry reports installer.mode 'tui'. Also drops a leftover `dashboard` arg type and stops the adapter if the environment picker throws.
…and add a top margin
Callers print what a question is about and then ask ("You have uncommitted
or untracked files:" + the list, then "Continue anyway?"). With a UI host,
ui.ts now attaches the lines printed in the same synchronous run to the
prompt as `context`, and the full-screen view shows them right above the
question. The list collapses to "… N more" when the terminal is short, so
the question and its answer line always stay on screen.
The view also leaves a blank row at the top, matching the blank row at the
bottom and the one-column side margins.
The CLI drew two brand marks: the full-screen installer uses the WorkOS logomark, while the plain CLI (and the scrollback replayed after the full screen) used a lock mascot whose face showed the outcome. - The install opener draws the compact logomark in WorkOS indigo beside the wordmark, or one plain line without Unicode. - The install summary and `workos doctor`'s summary box lead with a title line that carries the outcome (✔ green, ! yellow, ✗ red). An error detail under a failed install's title reads "›" instead of repeating the ✗. - After the full-screen view closes, the replay skips the opener: you just saw the logo, so the scrollback starts with what happened. The logomark raster moves to src/utils/logomark.ts so both surfaces share it; lock-art.ts is gone.
The full-screen installer can now tick off the dashboard's AuthKit checklist as the installer works through it, instead of one "Configure WorkOS" row. - `config:step`: the configure step (before the agent) reports "Add environment variables", and for React Router and TanStack Start the redirect URI and CORS origin as each REST write settles; without an API key those two are reported as not set, with the reason. - `app-urls:step`: for Next.js, the redirect, initiate login, and sign-out URIs that #244 sets on the AuthKit application once the agent's routes exist. `reportAppUrlSetup` wraps `configureAuthkitApplication` without changing it: a throw still fails the install; an unverified result flags both URLs with its reason. Plain and JSON output are unchanged.
…ight - "Configure WorkOS" expands into the dashboard's items it sets while it runs, in the dashboard's order and words, and collapses once they land. - New "Connect your app's URLs" step (Next.js) after the agent, where the redirect, initiate login, and sign-out URIs are actually set. Items that weren't set or verified stay open with a `!`, and items sharing a reason share one walkthrough line. - "Complete your first sign-up" ends the list as the next step (→). The run's closing line says so when a setting still needs a look. - The walkthrough is on the left and the checklist on the right. Below 100x30 the walkthrough keeps the room and the checklist becomes one progress line.
…crollback On exit the full-screen view replayed everything the plain CLI would have printed, so the scrollback filled with every command and file the agent touched. It now keeps the answers, the settings rows, warnings and errors (including any from the agent's run), validation, and the summary, and points to the installer log for the step-by-step.
Ink re-subscribes input handlers after each render, so a key arriving before that reached a handler holding the previous state: - a fast ↓ then enter in a select picked the option from before the move (continue on the current branch became "create a branch") - a text or password answer pasted with its trailing newline was inserted as text and never submitted, and typing ahead lost characters The select keeps its focus in a ref, and text/password prompts use a small line input whose value and cursor live in a ref; a newline anywhere in a chunk submits what precedes it, as the plain CLI's prompts do. It edits by character (an emoji is one step), ignores keys Ink delivers as raw escape sequences (Home, End), and shows a validator that throws as the prompt's error instead of crashing the installer.
…screen view From review of the stack: - A terminating signal emits no 'exit' event, so `kill` or a closed terminal left the alternate screen up and the tty raw. The view now restores the terminal on SIGTERM/SIGHUP and then dies of the signal. - Redirected stderr (`2> errors.log`) now keeps the plain CLI, so errors stay on stderr; previously only the interaction mode implied this. - A setting whose write failed while the install carried on no longer ends the run on "All done": it counts as needing a look, like one not set.
The note on where the hidden agent lines went printed just before "Agent completed", so the scrollback read backwards. It now follows the next line.
A finished task with a setting left to check showed a green ✔ above its ! items and counted toward "N of M done", so a run that ends on "setup required" read 8 of 8 done. The task now shares the ! and stays out of the count.
When authenticated command smoke fails, issue a single GET /connections using the same smoke credential and configured API host through curl instead of the compiled CLI. Discard the body, do not follow redirects, and log only HTTP status, curl exit status, and the request ID. Keep the original failed check red.
Preflight live smoke with one direct read-only API request. Missing credentials or direct HTTP401 report live checks NOT RUN with an explicit warning/summary instead of misclassifying a CLI regression. HTTP200 enables the unchanged authenticated CLI checks, whose failures still fail CI. All other HTTP or transport failures remain fatal. Localhost-only tests cover status handling, non-disclosure, no redirects, and propagation of CLI failures.
6 of 7 tasks
|
nicknisi
force-pushed
the
nicknisi/installer-tui
branch
from
September 25, 2026 10:00
d201fd5 to
5737030
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Split the independent CI work out of #250 so installer URL fixes can be reviewed on their own.
Validation
bun install --frozen-lockfilepassed.bun run test scripts/smoke-auth-preflight.spec.ts: 15 passed, using localhost fixtures only.This branch contains only the workflow, preflight script, and its tests.