Skip to content

chore: version @sanring/cli 0.23.3 -> 0.24.0 - #27

Merged
jack755051 merged 9 commits into
mainfrom
chore/cli-0.24.0
Aug 22, 2026
Merged

jack755051 merged 9 commits into
mainfrom
chore/cli-0.24.0

Conversation

@jack755051

Copy link
Copy Markdown
Contributor

Summary

  • Bumps @sanring/cli 0.23.3 → 0.24.0 (minor, since build/list --json + shared registry-integrity checks is a feat) via pnpm changeset version
  • Consumes changesets covering: build/list --outdated --json, shared registry-integrity module (doctor/build/MCP), typed RegistryFetchError, remove exit-code consistency, info alias:component crash fix
  • Syncs the docs site: new 0.24.0 entry in component-changelog.ts (CLI changes + otp-input + P30 headless-a11y-sweep component changes), and updates the two hardcoded v0.23.3 display strings (home hero, roadmap page)

Test plan

  • npx tsc --noEmit on docs app passes
  • npx eslint on changed docs files passes
  • pnpm build / visual check of changelog page and home hero version chip

🤖 Generated with Claude Code

jack755051 and others added 9 commits August 22, 2026 00:02
…erage

`remove` now distinguishes unknown targets (hard exit 1, matching
diff/update) from known-but-not-installed ones (soft skip), instead of
silently exiting 0 whenever any target succeeded. Also adds the missing
test files for `info`/`migrate`/`search`, which surfaced a real crash
in `info`'s alias:component lookup, and pins vitest to the `forks` pool
to stop chdir-based command tests from racing on process.cwd().

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Slots now shrink to fit their container instead of triggering a
horizontal scrollbar, and the hidden native input covers the full
control (type="text", inset-0) so password managers/autofill see a
properly sized target instead of a 1px hit area. Active-slot focus
styling switches from an offset ring + transform to an inset ring to
match the new non-scrolling layout. packages/ui and registry stay in
sync; docs previews and locale strings updated to match.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…yped fetch errors

Completes the remaining P27 items: build/list --outdated gain --json
output; a new registry-integrity module (dangling componentDeps/
sharedDeps/group references, unparseable peer versions, optional
file-fetchability) is shared across doctor, build, and the MCP
doctor_project tool; and fetchRegistry/fetchFile now throw a typed
RegistryFetchError instead of calling process.exit directly.

The typed-error change fixes two real bugs found along the way: doctor's
"Unreachable" catch block was dead code (die() exited before it could
run), and 6 of 7 MCP tool handlers had no try/catch around getRegistry(),
so a single failed fetch could kill the whole long-running MCP server
instead of returning a normal tool error. Also fixes a flaky-test root
cause: sync-registry.mjs's rm-then-async-copy raced with mcp.e2e.test.ts's
`npm run build`, intermittently deleting packages/cli/registry mid-test;
now copies into a temp dir and swaps in atomically.

index.ts's --help, the npm README, and the docs CLI page are reorganized
around the same five command groups (install/explore/maintain/publish/
agent), the docs page gets a full migrate section, and five stale
flag-doc gaps are backfilled (add --check, remove --dry-run, list
--outdated/--json, doctor --fix/--json, diff --summary/--json).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Applies the P14 CVA base refactor (previously registry-only) to
packages/ui: checkbox, switch, radio-group, slider, otp-input,
calendar, and file-upload now extend SanringCvaBase, removing each
file's duplicated ControlValueAccessor callbacks, disabled-state
handling, deferred NgControl resolution, control.events bridging, and
Field described-by id plumbing. (combobox and date-picker get the same
treatment in the next commit, alongside their P30 accessibility fixes.)

Also adds an explicit no-selector @directive() to SanringCvaBase in
both packages/ui and registry — needed once the base was actually
compiled by the Angular library build (it uses inject()/OnInit without
carrying Angular DI metadata otherwise), a gap the prior static parity
check couldn't see since registry source wasn't compiled directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…nents

Closes out the last 15 "suggested fix" items from the full-library
headless audit (P30), touching avatar, breadcrumb, combobox,
context-menu, date-picker, dialog/alert-dialog, field, hover-card,
select, sheet, sidebar, transfer, and tree, with matching registry/
sources, component specs, and bilingual docs updates.

Highlights:
- avatar-group-count: disabled boolean coercion + click/keyboard guard.
- breadcrumb: localizable ariaLabel.
- field/select: consumer-settable id with fallback generation preserved.
- dialog/alert-dialog/sheet: explicit-input -> config -> projected-title
  -> fallback relationship resolution, so a title-less alertdialog still
  gets an accessible name; signal contentChild + effect handles title
  being added/removed dynamically without leaving stale attributes.
- hover-card: trigger/content linked via aria-controls/aria-expanded.
- sidebar: default complementary role + overridable label; menu button/
  action get role="button", tab stop, Enter/Space activation, disabled
  guard, and ignore key-repeat without narrowing their selectors.
- combobox: overridable inputId/listId; focus returns to trigger/input
  after Escape or single-select completion, but not after an outside
  pointerdown close (so it doesn't steal focus from what the user just
  clicked).
- date-picker: ariaLabel/ariaLabelledBy; disabled now also accepts a
  plain boolean (including a bare `disabled` attribute) alongside the
  existing day-matcher API, with selection guards and ARIA state kept
  consistent either way.
- context-menu: single roving tab stop per menu level instead of every
  item being tabbable; Tab/Shift+Tab closes the whole menu tree and
  moves focus to the logical next/previous control in document order
  regardless of the CDK overlay being portaled to the end of <body>.
- transfer: each row now owns role="checkbox"/aria-checked/aria-disabled/
  roving tabindex/click+Space directly instead of a row-click and a
  nested checkbox both trying to toggle state; panel supports
  ArrowUp/Down/Home/End, skipping disabled items.
- tree: ariaLabel/ariaLabelledBy on the root, per-node disabled; child
  lookup now builds one parent map instead of rescanning all
  descendants per node (was O(n^2) on deep/large trees).
- dropdown-menu is deliberately left alone: it already hand-rolls CDK
  overlay lifecycle because @angular/aria/menu's permanent DomPortal
  attach-once model conflicts with MenuOverlayController's own
  create/attach/detach — a documented, intentional divergence, not a
  correctness gap.

Also fixes issues found during cross-review: a protected/public
visibility drift on four hover-card-content template handlers between
packages/ui and registry, a fully-duplicated onFocus/onBlur left over
in registry's combobox after the CVA base migration, and a wrong
--sanring-primary-foreground token in transfer (reverted to the
existing --sanring-primary-fg).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Added changesets covering the last session's CLI work (build/list --json,
shared registry-integrity checks, typed fetch errors; remove exit-code
consistency + info/migrate/search test coverage), then ran
`pnpm changeset version` to consume them — this produced 0.24.0 (a minor
bump, since the --json/registry-integrity work is a feat).

Synced the docs site to match: added the 0.24.0 entry to
component-changelog.ts's cliVersionChangelog (covering the CLI changes
plus the otp-input and P30 headless-a11y-sweep component changes shipped
in the same window), and updated the two hardcoded "v0.23.3" display
strings (home hero, roadmap page).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…t gaps

Reworked the previous commit on this branch: it manually ran
`pnpm changeset version` and pushed the resulting 0.24.0 bump directly,
but this repo's actual release flow (used for every prior release except
one) is that changeset files land on `main` unconsumed, and the
`changesets/action` bot opens its own `chore: version packages` PR from
`changeset-release/main` to do the bump. Manually pre-bumping broke
`require-changeset.yml`, which expects a pending changeset, not an
already-consumed one. Reverted `packages/cli/package.json` and
`packages/cli/CHANGELOG.md` back to 0.23.3 and restored the two pending
changesets so the bot can do its job normally after this merges.

Also fixed two CI bugs surfaced while chasing down the "Test (@sanring/cli)"
failure on this PR, both pre-existing (reproduced on main / an older PR
run too, unrelated to the above):

- `ci.yml`'s `test-cli` job never ran `sync-registry` before `pnpm --filter
  @sanring/cli test`, so `packages/cli/registry/` (gitignored, normally
  populated by `build`) didn't exist on a clean checkout — 9 tests that
  read the bundled registry directly failed with ENOENT. Added a
  "Sync registry fixtures" step before the test step.
- Once that was fixed, one real drift remained: the golden-fixture test
  (`build.test.ts`) caught that `registry/registry.json`'s hand-written
  `transfer` entry was missing the `@lucide/angular` peerDependency that
  `transfer-item.component.ts` actually imports (added when transfer's
  checked-indicator was rewritten to use a Lucide icon in the P30 sweep,
  but registry.json was never regenerated to match). Added the missing
  peerDependency entry.

`pnpm --filter @sanring/cli test` now passes 240/240 locally with a
sync'd registry.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Root-caused the remaining "Test (@sanring/cli)" CI failures (4 tests,
reproduced reliably via Docker with node:24-bookworm + CI=true to match
the GitHub Actions runner exactly): picocolors treats any truthy `CI`
env var as color support ("it can't tell GitHub Actions' log viewer from
a dumb pipe"), so command output carries ANSI codes under CI but not in
a normal local run. Assertions like
`output.includes('Already installed: @lucide/angular')` and
`/Installed \(1\).*widget/` are literal/near-literal string checks that
silently break once an ANSI escape lands between the words they're
matching — which only happens in CI, hence 100% reproducible there and
0% locally regardless of retries.

Set `NO_COLOR: '1'` in vitest.config.ts's `test.env` so command output —
and these assertions — behave identically in CI and locally, rather than
patching each assertion to tolerate ANSI codes.

Verified via Docker (node:24-bookworm, CI=true, GITHUB_ACTIONS=true,
frozen-lockfile install, sync-registry, vitest run): 240/240 passing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jack755051
jack755051 merged commit 49c6c2e into main Aug 22, 2026
6 checks passed
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