Skip to content

Bump minimatch and eslint#2

Closed
dependabot[bot] wants to merge 2 commits intomainfrom
dependabot/npm_and_yarn/multi-7b798eeb36
Closed

Bump minimatch and eslint#2
dependabot[bot] wants to merge 2 commits intomainfrom
dependabot/npm_and_yarn/multi-7b798eeb36

Conversation

@dependabot
Copy link
Copy Markdown
Contributor

@dependabot dependabot Bot commented on behalf of github Feb 21, 2026

Bumps minimatch to 10.2.2 and updates ancestor dependency eslint. These dependencies need to be updated together.

Updates minimatch from 3.1.2 to 10.2.2

Changelog

Sourced from minimatch's changelog.

change log

10.2

  • Add braceExpandMax option

10.1

  • Add magicalBraces option for escape
  • Fix makeRe when partial: true is set.
  • Fix makeRe when pattern ends in a final ** path part.

10.0

  • Require node 20 or 22 and higher

9.0

  • No default export, only named exports.

8.0

  • Recursive descent parser for extglob, allowing correct support for arbitrarily nested extglob expressions
  • Bump required Node.js version

7.4

  • Add escape() method
  • Add unescape() method
  • Add Minimatch.hasMagic() method

7.3

  • Add support for posix character classes in a unicode-aware way.

7.2

  • Add windowsNoMagicRoot option

7.1

  • Add optimizationLevel configuration option, and revert the default back to the 6.2 style minimal optimizations, making the advanced transforms introduced in 7.0 opt-in. Also, process provided file paths in the same way in optimizationLevel:2 mode, so most things that matched with optimizationLevel 1 or 0 should match with level 2 as well. However, level 1 is the default, out of an abundance of caution.

... (truncated)

Commits
Install script changes

This version adds prepare script that runs during installation. Review the package contents before updating.


Updates eslint from 9.39.1 to 10.0.1

Release notes

Sourced from eslint's releases.

v10.0.1

Bug Fixes

  • c87d5bd fix: update eslint (#20531) (renovate[bot])
  • d841001 fix: update minimatch to 10.2.1 to address security vulnerabilities (#20519) (루밀LuMir)
  • 04c2147 fix: update error message for unused suppressions (#20496) (fnx)
  • 38b089c fix: update dependency @​eslint/config-array to ^0.23.1 (#20484) (renovate[bot])

Documentation

  • 5b3dbce docs: add AI acknowledgement section to templates (#20431) (루밀LuMir)
  • 6f23076 docs: toggle nav in no-JS mode (#20476) (Tanuj Kanti)
  • b69cfb3 docs: Update README (GitHub Actions Bot)

Chores

  • e5c281f chore: updates for v9.39.3 release (Jenkins)
  • 8c3832a chore: update @​typescript-eslint/parser to ^8.56.0 (#20514) (Milos Djermanovic)
  • 8330d23 test: add tests for config-api (#20493) (Milos Djermanovic)
  • 37d6e91 chore: remove eslint v10 prereleases from eslint-config-eslint deps (#20494) (Milos Djermanovic)
  • da7cd0e refactor: cleanup error message templates (#20479) (Francesco Trotta)
  • 84fb885 chore: package.json update for @​eslint/js release (Jenkins)
  • 1f66734 chore: add eslint to peerDependencies of @eslint/js (#20467) (Milos Djermanovic)

v10.0.0

Breaking Changes

  • f9e54f4 feat!: estimate rule-tester failure location (#20420) (ST-DDT)
  • a176319 feat!: replace chalk with styleText and add color to ResultsMeta (#20227) (루밀LuMir)
  • c7046e6 feat!: enable JSX reference tracking (#20152) (Pixel998)
  • fa31a60 feat!: add name to configs (#20015) (Kirk Waiblinger)
  • 3383e7e fix!: remove deprecated SourceCode methods (#20137) (Pixel998)
  • 501abd0 feat!: update dependency minimatch to v10 (#20246) (renovate[bot])
  • ca4d3b4 fix!: stricter rule tester assertions for valid test cases (#20125) (唯然)
  • 96512a6 fix!: Remove deprecated rule context methods (#20086) (Nicholas C. Zakas)
  • c69fdac feat!: remove eslintrc support (#20037) (Francesco Trotta)
  • 208b5cc feat!: Use ScopeManager#addGlobals() (#20132) (Milos Djermanovic)
  • a2ee188 fix!: add uniqueItems: true in no-invalid-regexp option (#20155) (Tanuj Kanti)
  • a89059d feat!: Program range span entire source text (#20133) (Pixel998)
  • 39a6424 fix!: assert 'text' is a string across all RuleFixer methods (#20082) (Pixel998)
  • f28fbf8 fix!: Deprecate "always" and "as-needed" options of the radix rule (#20223) (Milos Djermanovic)
  • aa3fb2b fix!: tighten func-names schema (#20119) (Pixel998)
  • f6c0ed0 feat!: report eslint-env comments as errors (#20128) (Francesco Trotta)
  • 4bf739f fix!: remove deprecated LintMessage#nodeType and TestCaseError#type (#20096) (Pixel998)
  • 523c076 feat!: drop support for jiti < 2.2.0 (#20016) (michael faith)
  • 454a292 feat!: update eslint:recommended configuration (#20210) (Pixel998)
  • 4f880ee feat!: remove v10_* and inactive unstable_* flags (#20225) (sethamus)
  • f18115c feat!: no-shadow-restricted-names report globalThis by default (#20027) (sethamus)
  • c6358c3 feat!: Require Node.js ^20.19.0 || ^22.13.0 || >=24 (#20160) (Milos Djermanovic)

Features

  • bff9091 feat: handle Array.fromAsync in array-callback-return (#20457) (Francesco Trotta)
  • 290c594 feat: add self to no-implied-eval rule (#20468) (sethamus)
  • 43677de feat: fix handling of function and class expression names in no-shadow (#20432) (Milos Djermanovic)

... (truncated)

Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    You can disable automated security fix PRs for this repo from the Security Alerts page.

butlersrepos and others added 2 commits December 5, 2025 11:29
Bumps [minimatch](https://github.com/isaacs/minimatch) to 10.2.2 and updates ancestor dependency [eslint](https://github.com/eslint/eslint). These dependencies need to be updated together.


Updates `minimatch` from 3.1.2 to 10.2.2
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](isaacs/minimatch@v3.1.2...v10.2.2)

Updates `eslint` from 9.39.1 to 10.0.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](eslint/eslint@v9.39.1...v10.0.1)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 10.2.2
  dependency-type: indirect
- dependency-name: eslint
  dependency-version: 10.0.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Feb 21, 2026
@dependabot @github
Copy link
Copy Markdown
Contributor Author

dependabot Bot commented on behalf of github Mar 9, 2026

OK, I won't notify you again about this release, but will get in touch when a new version is available.

If you change your mind, just re-open this PR and I'll resolve any conflicts on it.

@dependabot dependabot Bot deleted the dependabot/npm_and_yarn/multi-7b798eeb36 branch March 9, 2026 23:36
bird-m added a commit that referenced this pull request Apr 15, 2026
Review-panel #1 (Severe): Remove competing browser tab in requires_auth
path. The requires_auth branch opened the backend's redirect URL via
opn() then fell through to performAmplitudeAuth which opened a second
browser tab with mismatched PKCE. Now we skip the backend URL and let
performAmplitudeAuth handle the entire flow. Added TODO to evaluate
using the backend URL in a follow-up.

Review-panel #2 (Critical): Init feature flags in agent/CI paths so
_headlessSignupEnabled can be true. Previously the flag was only set in
the TUI interactive path, making the entire agent/CI headless signup
block unreachable dead code.

Review-panel #3 (Important): Pre-populate HeadlessSignupScreen from CLI
--email/--full-name flags. Auto-submit if both are present.

Review-panel #4 (Important): Redact email in agent NDJSON log output
to match the redaction pattern in headless-signup.ts.

Review-panel #7 (Important): Split fullName into first_name/last_name
on first space before sending to provisioning endpoint.

Review-panel #9 (Nit): Replace non-null assertions on
headlessSignupEmail/headlessSignupFullName with an explicit guard.

Review-panel #10 (Nit): Extract completeSignupTokenExchange into
headless-signup.ts as a shared helper used by both the agent/CI and
TUI code paths, reducing duplication and drift risk.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bird-m bird-m mentioned this pull request Apr 15, 2026
3 tasks
bird-m added a commit that referenced this pull request Apr 16, 2026
Table.tsx was introduced with no consumers. Remove it to avoid dead
code on merge — can be re-added in the PR that actually needs it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bird-m added a commit that referenced this pull request Apr 16, 2026
Use z.string().trim().toLowerCase().email() for consistent validation
and automatic normalization (trim + lowercase) instead of a hand-rolled
regex.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bird-m added a commit that referenced this pull request Apr 16, 2026
…ilure

Thread allowBrowserRecovery: false through completeAuth for the non-interactive
signup path and interactive headless signup path. If fetchAmplitudeUser fails
after a brand-new token exchange, surface the error and exit AUTH_REQUIRED
instead of contradicting the browserless contract by launching a browser.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
kelsonpw added a commit that referenced this pull request Apr 17, 2026
… picker)

Batch of bird-m and Bugbot findings from PR #112:

#1 claudeCodeMode default mismatch (medium, flagged 3×):
  addMCPServerToClientsStep silently defaulted to 'plugin' while
  mcp-installer.ts defaulted to 'mcp'. Non-TUI fallback via bin.ts
  could install the plugin with no user prompt. Aligned both to 'mcp'
  as the safer default — plugin is interactive-only now.

#3 remove flow can't uninstall plugin (medium, flagged 2×):
  getInstalledClients only ever instantiated ClaudeCodeMCPClient.
  After plugin install removes the bare `amplitude` MCP entry,
  isServerInstalled returned false and `wizard mcp remove` silently
  skipped Claude Code. Added an explicit ClaudeCodePluginClient probe
  before falling through to the MCP check.

#4 non-TUI `local` flag ignored for plugin path (low, Bugbot):
  addMCPServerToClientsStep now forces 'mcp' mode whenever
  local=true, matching the TUI's behavior. The plugin hardcodes the
  prod URL and can't serve localhost.

#5 `as unknown as RawMCPClient[]` cast (nit, bird-m):
  resolveClientsForMode returns MCPClient[] directly; the local
  RawMCPClient interface was a holdover. Dropped the cast and removed
  the unused interface — install loop now type-checks against
  MCPClient directly.

#6 older Claude CLIs fail opaquely (nit, bird-m):
  ClaudeCodePluginClient.isClientSupported now probes `claude plugin
  --help` in addition to `--version`. resolveClientsForMode is async
  and checks plugin support before swapping — older CLIs quietly keep
  ClaudeCodeMCPClient instead of failing during `marketplace add`.

#7 single-Claude-Code hid plugin/MCP choice (medium, Bugbot):
  detected.length === 1 routed to Phase.Ask, which doesn't show the
  split picker. Now: if the lone detected tool is Claude Code and no
  escape hatch is set, route to Phase.Pick so the user sees plugin vs
  MCP rows.

#8 resolveSelection misleading default (low, Bugbot):
  wantsPlugin || !wantsMcp ? 'plugin' : 'mcp' returned 'plugin' when
  the user unchecked both Claude Code rows. Simplified to
  wantsPlugin ? 'plugin' : 'mcp' — explicit semantics, still correct
  since downstream guards the Claude-Code-absent case.

#9 Codex Windows detection (low, Bugbot):
  `command -v` is POSIX-only; Windows never matched. Use `where codex`
  on win32, `command -v codex` on POSIX. Take the first line since
  `where` may return multiple paths. Narrowed the bundled-app
  exclusion to macOS only (Conductor-specific).

#10 multi-picker uncheck-all dead code (medium, Bugbot):
  MultiPickerMenu's Enter handler fell back to the focused row when
  selected was empty, so a user who unchecked every pre-selected row
  got one install instead of a skip. Now: if defaultSelected was
  provided, an empty set means deliberate — pass [] through to the
  caller. Also fixed lexicographic index sort → numeric.

#? dev script env var at build-time (low, Bugbot):
  `AMPLITUDE_WIZARD_DEV=1 pnpm build` only scoped the var to the
  build subprocess, not the globally-linked binary. Removed from the
  `dev` script since it was ineffective there — `try` still sets it
  at runtime where it actually works.

Addressed in comment, no code change: #2 non-atomic settings.json
write — already replaced with `claude plugin marketplace add` CLI in
commit 4679fc4. No direct file write remains.

974 tests pass, lint clean, smoke test passes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@kelsonpw kelsonpw mentioned this pull request Apr 20, 2026
30 tasks
kelsonpw added a commit that referenced this pull request Apr 26, 2026
Bugbot caught: the try/finally wrapping runAgentWizardBody won't
execute cleanupWizardArtifacts on the error paths
(AUTH_ERROR / MCP_MISSING / RESOURCE_MISSING / GATEWAY_DOWN /
RATE_LIMIT / API_ERROR) because those paths call wizardAbort,
which calls process.exit(). process.exit terminates the process
immediately and skips pending async finally blocks — so the
exact paths this PR's change #2 was trying to cover would have
silently still leaked artifacts.

Fix: register cleanupWizardArtifacts via registerCleanup() so
wizardAbort runs it synchronously before exiting, AND keep the
try/finally so success / uncaught-exception paths still cover
themselves. cleanupWizardArtifacts is idempotent (each component
existsSync-checks before unlinking; cleanupIntegrationSkills uses
fs.rmSync with force: true) so double-firing is safe.

Co-Authored-By: Cursor Bugbot <bugbot@cursor.com>
kelsonpw added a commit that referenced this pull request Apr 26, 2026
…261)

* feat(wizard): gitignore + always-clean wizard artifacts after a run

Today, after a wizard run, the user's project ends up with this in
git status:

  new file:   .amplitude-events.json
  new file:   .claude/skills/integration-javascript_web/...
  new file:   .claude/skills/add-analytics-instrumentation/...
  new file:   .claude/skills/amplitude-chart-dashboard-plan/...
  new file:   .claude/skills/amplitude-quickstart-taxonomy-agent/...
  modified:   .gitignore  (only adds .env.local)

A `git add .` after the wizard sweeps all of that into the user's commits.
Three real bugs:

1. .gitignore doesn't cover wizard artifacts. Highest leverage —
   regardless of whether files stay on disk for re-invocation, they
   should never be tracked.

2. cleanupIntegrationSkills only ran on the success path. If the agent
   errored, was killed, or hit a wizard error after skills were installed
   but before outro, integration skills leaked.

3. .amplitude-events.json sticks around. The commandments tell the inner
   Claude agent to delete it during the conclude phase, but model
   variance means it's not always honored.

Fixes:

  ensureWizardArtifactsIgnored(installDir)
    Idempotent — appends a marked block of patterns to .gitignore. If
    the marker already exists from an older wizard version, replaces
    the block in place. Creates .gitignore if missing.

  cleanupAmplitudeEventsFile(installDir)
    Removes .amplitude-events.json. Backstops the agent's conclude-phase
    deletion.

  cleanupWizardArtifacts(installDir)
    Composes the two cleanups. Safe to call from any exit path.

Wiring:
  - runAgentWizard now calls ensureWizardArtifactsIgnored on entry
    (before any skill installs)
  - The cleanup is moved into a try/finally so it runs on success,
    error, AND cancel paths
  - Removed the duplicate success-path call

Instrumentation and taxonomy skills are STILL kept on disk for later
invocation — that design is unchanged. They're just gitignored so
"kept on disk" doesn't mean "committed to git" anymore.

Tests: +31 in wizard-tools.test.ts (47 total). Suite green (1248 pass).

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

* fix: stop ensureWizardArtifactsIgnored from eating user content below the wizard block

Bug: the regex `# Amplitude wizard(?:\n[^\n]*)*` was greedy and used
`[^\n]*` (zero or more), so it matched blank lines (empty content
between two newlines) and kept consuming. On a wizard upgrade that
added a new pattern, replacing the marked block would silently delete
EVERYTHING below it in the user's .gitignore — `dist/`, `.env`, etc.

Fix: change the inner repetition to `[^\n]+` (one or more) so the
regex stops at the first blank line. Pinned with a regression test
that asserts user content below the block survives an in-place
replacement.

Without this, shipping #261 would have silently destroyed user
gitignore content on the next wizard run after a pattern change.

* fix: cleanup runs on wizardAbort error paths via registerCleanup

Bugbot caught: the try/finally wrapping runAgentWizardBody won't
execute cleanupWizardArtifacts on the error paths
(AUTH_ERROR / MCP_MISSING / RESOURCE_MISSING / GATEWAY_DOWN /
RATE_LIMIT / API_ERROR) because those paths call wizardAbort,
which calls process.exit(). process.exit terminates the process
immediately and skips pending async finally blocks — so the
exact paths this PR's change #2 was trying to cover would have
silently still leaked artifacts.

Fix: register cleanupWizardArtifacts via registerCleanup() so
wizardAbort runs it synchronously before exiting, AND keep the
try/finally so success / uncaught-exception paths still cover
themselves. cleanupWizardArtifacts is idempotent (each component
existsSync-checks before unlinking; cleanupIntegrationSkills uses
fs.rmSync with force: true) so double-firing is safe.

Co-Authored-By: Cursor Bugbot <bugbot@cursor.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor Bugbot <bugbot@cursor.com>
kelsonpw added a commit that referenced this pull request Apr 26, 2026
Closes #297.

Real user log (run_id 66d9fa51, Sentry #7442894144) showed the wizard
crashing ~40s into the new attempt with:

    CLI stderr: Error in hook callback hook_0: Error: Stream closed
        at m98.sendRequest …
    Tool permission request failed: Error: Stream closed

Root cause: the outer retry loop in `runAgent` calls `signalDone()` and
then `continue`s to the next attempt without telling the SDK its prior
Query iterator is done. The SDK's underlying subprocess remains alive
just long enough for an in-flight tool-use message to fire our
PreToolUse hook callback through a stdio bridge that is mid-teardown.
The bridge fails on `m98.sendRequest`, the SDK converts the failure
into a tool_result with `is_error: true`, and the run dies because the
agent can't recover from a tool-permission failure.

Fix: hoist the SDK `Query` (an `AsyncIterable<unknown>` here, but its
concrete `Query` type extends `AsyncGenerator`) so the catch and
post-stream retry paths can call `.return()` on it before the next
attempt. `.return()` propagates an EOF down the AsyncGenerator
protocol; the SDK closes its stdio cleanly. Errors from `.return()`
itself are expected during teardown and are swallowed via a tiny
`drainPriorResponse` helper.

Defense in depth: also add `'Stream closed'` to the transient error
pattern list. If a Stream closed somehow does still bubble out (e.g.
late SDK cleanup), the catch path treats it as transient and retries
cleanly instead of throwing API_ERROR.

Tests:
- New: drains the prior response iterator before retrying after a
  transient API error — spies on .return() and asserts it fires
  during attempt #1, before query() is invoked for attempt #2.
- New: classifies Stream closed errors as transient and retries — locks
  down the defense-in-depth pattern.
- Existing 119 runAgent tests still green (stall retry, GATEWAY_DOWN
  classification, race-condition handling, legacy text markers, etc.).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
kelsonpw added a commit that referenced this pull request Apr 28, 2026
…331)

* fix: gracefully handle late-stage API errors so users see the Outro

Two related fixes for a UX gap surfaced when an agent run hits an API
error AFTER all the meaningful work (events instrumented, dashboard
created, setup report written) has completed.

Symptom: the wizard would call wizardAbort -> getUI().cancel() ->
process.exit(NETWORK_ERROR) before Ink had time to render the next
frame, so the user saw a half-rendered "API error occurred" status
banner and a sudden process death — no MCP install offer, no Slack
prompt, no Outro screen with bug-report hotkeys, and a misleading
network error code in CI even though the project was fully set up.

## Fix #1 — wizardAbort awaits OutroScreen dismissal in TUI mode

- WizardUI.cancel() returns Promise<void> instead of void.
  - InkUI: returns a promise that resolves when the OutroScreen is
    dismissed (keypress / picker action) OR after a 5-minute safety
    timeout. The TUI now actually gets to render the failure state.
  - AgentUI / LoggingUI: resolve immediately. No TUI to render, no
    human to interact.
- WizardStore exposes outroDismissed() / signalOutroDismissed() — a
  one-shot promise that bridges the OutroScreen render loop to
  wizardAbort. Idempotent and pre-resolves correctly when dismissal
  arrives before any awaiter (race-safe).
- OutroScreen non-success keypress handler now calls
  store.signalOutroDismissed() instead of process.exit(0). Lets
  wizardAbort drive the actual exit with the right exit code, run
  analytics shutdown, and flush Sentry — none of which were happening
  before because process.exit(0) jumped the queue.
- wizardAbort awaits getUI().cancel() before process.exit. UI errors
  in the await are caught + ignored so a busted UI can't trap the
  user in a hung process.

## Fix #2 — soft-error path: agent finished, just continue

- New `agentArtifactsLookComplete(session)` predicate checks for the
  dashboard URL on the session. The dashboard MCP create is the last
  thing the agent does in its conclude phase, after events are
  instrumented and the setup report is written; if it succeeded, the
  user's project is in a working state.
- API_ERROR / RATE_LIMIT branch in runAgentWizardBody now splits:
  - artifacts complete -> log a soft-error analytics event, surface
    a non-fatal status banner, fall through to the post-agent steps
    (env upload, MCP, Slack, DataIngestion, Outro). User gets the
    full success experience minus a "late API call failed but your
    setup is complete" warning.
  - artifacts missing -> existing hard-abort path, now extracted into
    `abortOnApiError()` for clarity.

## Tests

- src/ui/tui/__tests__/store.test.ts: outroDismissed resolves on
  signalOutroDismissed, returns the same promise for concurrent
  awaiters, pre-resolves on early dismissal, and is idempotent.
- src/lib/__tests__/agent-runner.test.ts: agentArtifactsLookComplete
  returns true with a real dashboard URL, false with null, false
  with empty string.

Verified: pnpm lint clean (1 pre-existing warning in untouched code),
pnpm test 1660 passing (+7 new tests).

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

* fix: address bugbot findings on wizardAbort sequencing

Two related bugbot findings on PR 331:

1. **Medium: outro-hotkey analytics events were silently dropped.**
   `analytics.shutdown()` ran before `getUI().cancel(...)`, but cancel
   now blocks until the user dismisses the OutroScreen. Any
   `wizardCapture` calls fired during that interaction — `'error outro
   log opened'` (press L), `'error outro bug report written'` (press
   C) — got queued *after* the final flush and dropped on
   `process.exit`. Fix: flip the order to cancel-then-shutdown so
   those events are flushed in the post-outro batch.

2. **High: process hangs on the version-check cancel path.**
   `agent-runner.ts` `runAgentWizard` called `getUI().cancel(...)`
   then `return false` for unsupported framework versions. With
   cancel now async + awaiting outro dismissal, the user dismisses
   the outro but nothing exits — Ink keeps the event loop alive
   indefinitely. The old `process.exit(0)` in OutroScreen used to be
   the de-facto exit for this path; replacing it with
   `signalOutroDismissed()` exposed the hang. Fix: route this path
   through `wizardAbort` (which always exits), and extend
   `wizardAbort` to forward `cancelOptions.docsUrl` so the manual
   setup link still surfaces in the Outro.

Tests:
- New: cancel-before-shutdown ordering, cancelOptions.docsUrl
  forwarding.
- Updated: existing ordering tests flipped to match new sequence;
  cancel-call-arity expectations include the new options arg.

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

---------

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

dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants