Skip to content

chore(deps): update dependency ink-stepper to v0.2.3 - #142

Merged
dawsontoth merged 1 commit into
mainfrom
renovate/ink-stepper-0.x-lockfile
Aug 17, 2026
Merged

chore(deps): update dependency ink-stepper to v0.2.3#142
dawsontoth merged 1 commit into
mainfrom
renovate/ink-stepper-0.x-lockfile

Conversation

@renovate

@renovate renovate Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
ink-stepper (source) 0.2.10.2.3 age confidence

Release Notes

archcorsair/ink-stepper (ink-stepper)

v0.2.3

Compare Source

Added
  • pulse prop on Stepper - animates the current-step marker in the default progress bar by
    cycling its brightness (bright → normal → dim → normal), the same frame-swapping technique CLI
    spinners use. Off by default; composes with custom markers; ignored with renderProgress.
Fixed
  • Progress bar labels wider than their marker column (e.g. an 8-character name over a 1-wide
    marker) overflowed flush into the next label with no gap; overflowing labels now keep at least
    one space of separation.
Changed
  • Example wizard polish: default pulsing markers (matching the README demo), a keycap-styled hint
    bar per step showing only the keys active right now, an "m" key cycling marker themes to demo the
    markers prop live, a braille spinner during async validation, and a color-coded lifecycle log.

  • CI runs an ink compatibility matrix covering the full declared peer range - the exact 6.x floor
    (6.6.0) and the latest 7.x - in addition to the lockfile-pinned version, so the dual-major claim
    stays verified. An API-surface audit against ink 7 confirmed every ink API this library uses is
    unchanged or additive across the two majors.

v0.2.2

Compare Source

Added
  • onError prop on Stepper - receives any error thrown by an async canProceed or onExitStep
    callback. Without it, errors are logged via console.error instead of crashing the host process.
  • initialStep prop on Stepper - starting step index for uncontrolled mode (default 0, ignored
    when the controlled step prop is provided).
  • ProgressContext.steps entries now carry a stable id, usable as a React key in custom
    progress renderers.
  • Runnable example wizard at examples/wizard.tsx (bun run example, INITIAL_STEP=<n> to start
    elsewhere) exercising render-function steps, useStepperInput, async validation, onError,
    a conditional step, and goTo.
Fixed
  • Published npm bundle shipped the development JSX runtime (react/jsx-dev-runtime). The build now
    runs with NODE_ENV=production, emitting react/jsx-runtime.
  • Conditional steps mounted after the initial render were ordered last instead of by their position
    in the tree.
  • Errors thrown from an async canProceed or onExitStep escaped as unhandled rejections, which
    terminates the host Node process. Navigation is now blocked and the error is reported.
  • goNext, goBack, and goTo are no-ops while validation is in flight or navigation is disabled -
    previously only the keyboard path honoured those guards.
  • goTo now fires the full lifecycle (onExitStep -> onStepChange -> onEnterStep) and can be
    cancelled by returning false from onExitStep. It still deliberately skips canProceed
    (raw-jump semantics).
  • Default progress bar used step names as React keys, colliding when two steps share a name; it now
    keys off the registered step id.
  • Progress bar label widths were computed from the completed marker for every step, so labels drifted
    out of alignment with mixed-width markers. Widths are now per-step.
Removed
  • Dead internal StepConfig interface.
Changed
  • The ink peer range is widened to ^6.6.0 || ^7.0.0 - the test suite passes against ink 7.1.1.
    The JSR import map pins npm:ink@^7.0.0 (Deno npm specifiers cannot express compound ranges, and
    JSR validates imports against the installed ink 7); a JSR publish dry run now gates the publish
    workflow so an unsatisfiable import range fails before anything ships.
  • Dev dependencies bumped to current versions (@biomejs/biome 2.5.x with a migrated config,
    @types/bun, @types/react, bunup) and react-devtools-core removed (unused; it pulled in a
    shell-quote version with a critical advisory). bun audit is clean for both the root and the
    docs workspace, whose vitepress toolchain was also brought current.
  • onExitStep return type widened to void | boolean | Promise<void | boolean>. Side-effect-only
    handlers no longer have to return a value; only an explicit false cancels navigation.
  • Steps mounted after the initial render keep the user on the same step in uncontrolled mode - the
    active step is now pinned by id rather than by index, and these repairs fire no lifecycle callbacks.
  • CI now runs typecheck and lint alongside tests, and typechecks tests/.
  • Publish workflow gates on a check job, asserts the pushed tag matches both package.json and
    jsr.json, and publishes to npm before JSR.
  • Version bumps sync jsr.json from package.json via the npm-style version lifecycle script
    (scripts/sync-versions.ts + git add), so the release commit that bun pm version tags always
    carries both manifests in agreement.
  • jsr.json now excludes tests/, examples/, docs/, .github/, and scripts/ from the JSR
    package.
  • Publish workflow verifies after publishing that both npm and JSR actually serve the tagged
    version, failing the run otherwise. Each registry's publish step is also guarded by an
    already-published check, so re-running the workflow after a partial failure retries only the
    registry that is still missing the version. The tag ↔ manifest assertion now runs in the check
    job, before the credentialed publish job starts.
  • Package metadata: author, homepage, bugs, and sideEffects (scoped to ./src/**, which marks
    every published file under dist/ as side-effect free for consumer tree-shaking).
  • Populated the previously empty .editorconfig.
  • README and the VitePress docs updated for the new props, goTo lifecycle, step-ordering rules, and
    the input-coordination ordering caveat.

Configuration

📅 Schedule: (in timezone America/New_York)

  • Branch creation
    • "before 9am on Monday"
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
renovate Bot force-pushed the renovate/ink-stepper-0.x-lockfile branch from d5ee4ee to f732c90 Compare August 11, 2026 00:55
@renovate renovate Bot changed the title chore(deps): update dependency ink-stepper to v0.2.2 chore(deps): update dependency ink-stepper to v0.2.3 Aug 11, 2026

@dawsontoth dawsontoth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocked: this is a real regression from ink-stepper 0.2.3, not the old flake

ink/main.test.tsx has a history of flaking, so I checked carefully before attributing it — this one is caused by the bump.

CI evidence:

  • main (unchanged, commit 2ac96543): I dispatched verify-pr.yaml three times — 3/3 green.
  • This PR: Test (Node 24) has now failed twice (original run + my re-run of the failed job).
  • Siblings #143, #144, #145, #146 all carry the byte-identical ink/main.test.tsx and all pass Test. The only thing unique to this PR is ink-stepper 0.2.1 → 0.2.3.

Local isolation — main's tree, COLUMNS=200, changing only ink-stepper:

ink-stepper npx vitest --run ink/main.test.tsx
0.2.1 (main) 1 failed / 5 passed
0.2.3 (this PR) 4 failed / 2 passed

and those 4 are exactly the 4 CI reports:

AssertionError: expected '\n AI Provider   API Key      Model  …' to contain 'Can you provide us with your OpenAI A…'
  ❯ ink/main.test.tsx:44:45   (same for Anthropic, Google, and 'Where are you hosting Ollama?')

The rendered frame shows the progress header but never the step body, i.e. the walkthrough never advances off step 1.

Likely cause

0.2.2/0.2.3 reworked step ordering. 0.2.1 assigned order from a module-global counter:

var globalMountOrder = 0;
...
if (orderRef.current === null) { orderRef.current = globalMountOrder++; }

0.2.3 replaces that with a per-Stepper counter claimed in layout-effect order, plus an orderGeneration that forces every Step to re-claim when a new step id appears:

if (orderRef.current === null || claimedGenerationRef.current !== orderGeneration) {
  orderRef.current = claimOrder();
  claimedGenerationRef.current = orderGeneration;
}

MainConfig's tests derive navigation from the rendered highlight (added in 706ec5f), so a change in when steps register/order shifts what's on screen at the moment the test writes input. Also new in this range: initialStep, onError, pulse, and a stable Step.id.

Note this is a 0.x line, where even a patch-looking bump can carry breaking behavior — worth treating ink-stepper as major-risk in Renovate until it hits 1.0.

Either the component needs a look at the new ordering semantics, or the walkthrough tests need to adapt to them — but it shouldn't merge as-is.

@dawsontoth

Copy link
Copy Markdown
Contributor

Root-caused and fixed — #147 unblocks this

Took this over. The failure is real (as flagged above), but the fault is on our side, not in the bump — and the fix is a small subtraction.

What actually breaks

disableNavigation() changed meaning in a patch release.

Through 0.2.1, it only gated the Stepper's own keyboard handler, leaving programmatic navigation alone:

useInput((_input, key) => {
  if (isValidating || isNavigationDisabled) return;   // keyboard only
  ...
}, { isActive: keyboardNav });

0.2.3 added an isBlocked() guard to the navigation functions themselves:

const isBlocked = useCallback(() => isValidatingRef.current || isNavigationDisabledRef.current, []);

const goNext = useCallback(async () => {
  if (isBlocked()) return;    // <-- now swallows programmatic calls too

Every wizard step mounts with disableNavigation() and unmounts with enableNavigation(). So under 0.2.3 each step was disabling its own goNext(). The wizard can never leave step 1 — which is exactly what the failing frame shows:

 AI Provider     API        Model     Compactor    Settings
 ━━━━ ● ━━━━━━━━━ ○ ━━━━━━━━━ ○ ━━━━━━━━━ ○ ━━━━━━━━━ ○ ━━━━━

 What model provider would you like to use today?
 ❯ Ollama

Note the header already reads "API" rather than "API Key" — setProvider('Ollama') landed fine; only the goNext() beside it was dropped. That's the tell that this is navigation being blocked, not a render-ordering or step-registration problem. My earlier guess in this thread that 0.2.2/0.2.3's orderGeneration rework was the likely cause was wrong — step ordering is fine.

The fix — #147

Those disableNavigation() calls existed to stop the Stepper double-handling <enter>, since every step's widget already consumes it and advances explicitly. But with all five steps disabling it for their whole lifetime, keyboardNav={true} never did anything. #147 states that directly with keyboardNav={false} and deletes the five identical effects — 12 insertions, 113 deletions, no behavior change on main.

Verified (Node 24.18.0, full suite):

tree ink-stepper result
main 0.2.1 6/6 in ink/main.test.tsx, 3 consecutive runs
main 0.2.3 4 failed / 2 passed
#147 0.2.1 344/344
#147 0.2.3 344/344

Correcting one detail from my original review: I reported 0.2.1 giving "1 failed / 5 passed" locally. On a clean install it's a clean 6/6 — that earlier number came from a desynced node_modules. Doesn't change the conclusion, but the baseline is green, so there's no lingering flake hiding here.

So: leaving my CHANGES_REQUESTED for now

Only because, as it stands today, this PR alone still breaks main. Once #147 merges, rebase this and it should go green — no changes needed to the bump itself. Happy to re-approve then.

Two things worth doing separately

1. Treat ink-stepper as major-risk while it's 0.x. A patch release redefined a public API's semantics. A Renovate rule alongside the AI SDK / OpenAI Agents groupings would stop this arriving as a routine patch. I'll file the upstream issue — "suppress the stepper's keybindings but keep explicit programmatic navigation" is a reasonable thing to want, and 0.2.3 removed it with no replacement.

2. ink-stepper@0.2.2+ pulls in ws for nothing. It declares "ws": "^8.21.2" as a runtime dependency, but ws is imported nowhere in the shipped dist/ — the whole bundle only imports react, ink, and react/jsx-runtime. Not a security concern (I read the dist; it's unminified and clean), but this bump adds a WebSocket library to our production tree for no reason. Also worth raising upstream. 🤖

@renovate
renovate Bot force-pushed the renovate/ink-stepper-0.x-lockfile branch from f732c90 to 7871b48 Compare August 14, 2026 18:35
dawsontoth added a commit that referenced this pull request Aug 17, 2026
…ling the stepper's

Every configuration-wizard step mounted with `disableNavigation()` and unmounted
with `enableNavigation()`, so the Stepper's built-in `keyboardNav` bindings were
suppressed for the entire lifetime of every step — they never actually ran. Each
step already owns its keys: its widget (Select / MultiSelect / BlinkingTextInput)
consumes <enter> and advances by calling `goNext()` from `onConfirm`, and each
step binds <esc> itself.

Declare that directly with `keyboardNav={false}` on the Stepper and drop the five
identical disable/enable effects. Net behavior on `main` is unchanged.

This also unblocks the ink-stepper 0.2.3 bump (#142). Through 0.2.1,
`disableNavigation()` only gated the Stepper's own `useInput` handler, so a
programmatic `goNext()` still worked. 0.2.3 added an `isBlocked()` guard to
`goNext`/`goBack`/`goTo`, so the same flag now also swallows the step's explicit
`goNext()` — the wizard could never advance past step 1 and the four walkthrough
tests in `ink/main.test.tsx` failed. Not depending on that flag makes the wizard
behave identically under both versions.

Verified locally on Node 24.18.0, full suite 344/344 under ink-stepper 0.2.1
(main's lockfile) and 0.2.3; lint, format, and `npm run build` clean.
dawsontoth added a commit that referenced this pull request Aug 17, 2026
…ling the stepper's

Every configuration-wizard step mounted with `disableNavigation()` and unmounted
with `enableNavigation()`, so the Stepper's built-in `keyboardNav` bindings were
suppressed for the entire lifetime of every step — they never actually ran. Each
step already owns its keys: its widget (Select / MultiSelect / BlinkingTextInput)
consumes <enter> and advances by calling `goNext()` from `onConfirm`, and each
step binds <esc> itself.

Declare that directly with `keyboardNav={false}` on the Stepper and drop the five
identical disable/enable effects. Net behavior on `main` is unchanged.

This also unblocks the ink-stepper 0.2.3 bump (#142). Through 0.2.1,
`disableNavigation()` only gated the Stepper's own `useInput` handler, so a
programmatic `goNext()` still worked. 0.2.3 added an `isBlocked()` guard to
`goNext`/`goBack`/`goTo`, so the same flag now also swallows the step's explicit
`goNext()` — the wizard could never advance past step 1 and the four walkthrough
tests in `ink/main.test.tsx` failed. Not depending on that flag makes the wizard
behave identically under both versions.

Verified locally on Node 24.18.0, full suite 344/344 under ink-stepper 0.2.1
(main's lockfile) and 0.2.3; lint, format, and `npm run build` clean.
github-actions Bot pushed a commit that referenced this pull request Aug 17, 2026
## [0.16.43](v0.16.42...v0.16.43) (2026-08-17)

### Bug Fixes

* **wizard:** let each step's <esc> own back-navigation ([c1d8435](c1d8435))

### Refactoring

* **wizard:** let the wizard own its keyboard nav instead of toggling the stepper's ([f740b95](f740b95)), closes [#142](#142)
@dawsontoth
dawsontoth force-pushed the renovate/ink-stepper-0.x-lockfile branch from 7871b48 to bd05e13 Compare August 17, 2026 18:44
@dawsontoth
dawsontoth marked this pull request as ready for review August 17, 2026 18:47
@dawsontoth
dawsontoth merged commit a62b5fb into main Aug 17, 2026
6 checks passed
@dawsontoth
dawsontoth deleted the renovate/ink-stepper-0.x-lockfile branch August 17, 2026 18:47
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.16.44 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant