* fix(shadcn): create nested output directories in build
Registry item names can contain path segments (e.g. "extension/foo").
Both build commands wrote <outputDir>/<name>.json without creating the
implied nested directories, so builds failed with ENOENT on clean
checkouts where the output directory does not already exist. Create the
parent directory before writing each item.
Fixes#11321
* chore: format
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xq2q7jaDcyxyA6YjutStLn
---------
Co-authored-by: shadcn <m@shadcn.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Adds the @retab namespace (Retab document-processing UI components) to
the registry directory. Registry is open source, publicly hosted, and
flat at https://ui.retab.com/r/{name}.json.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Adds @atelier to the registry directory.
Atelier UI is an open-source registry of WebGL and motion components for React, built on a single shared canvas so many effects can run on one page.
Homepage: https://www.atelier-ui.com
Registry: https://www.atelier-ui.com/r/registry.json
Evaluating 16.3's dev memory eviction: footprint after browsing 14 docs routes drops 32GB -> 15GB and page nav 3.6-16s -> sub-2s vs 16.2.7. Canary, not for merge until stable.
The generated __components__ maps put every style's dynamic-import edges
(~3,800) into any route that resolves a component, making docs pages
uncompilable in dev. Emit one shard per style plus a lazy getComponent
dispatcher, and fail fast in next.config when generated styles are stale.
* feat(registry): add @dkproductcard to registry directory
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Update directory.json
Co-authored-by: shadcn <m@shadcn.com>
* registry: consolidate under the @diklein namespace
Collection-level description and homepage for the @diklein entry, and the earlier single-component @dkmediaviewer entry removed: it pointed at the same registry and its item now installs via @diklein/dk-media-viewer. Recreated as one API commit so it carries a verified signature.
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: shadcn <m@shadcn.com>
* feat(registry): add @hexui to registry directory
* fix(registry): update logo SVG fill color in directory.json
* fix(registry): remove unintended changes
* Added Shadcn Space UI Kit to figma docs
docs: Added Shadcn Space UI Kit to Figma paid section
* Added Shadcn Space UI Kit to figma docs
docs: Added Shadcn Space UI Kit to Figma paid section
* feat(registry): added new registry (@shadcndashboard)
* feat(shadcn): scope component availability by base
* feat(base-toast): add Base UI toast component
* docs(base-toast): document toast and retire base sonner
* test(shadcn): add MCP formatter unit tests
Covers all five formatters in src/mcp/utils.ts (formatSearchResultsWithPagination,
findUnknownTypesMessage, formatSkippedRegistries, formatRegistryItems,
formatItemExamples). Pins the known npxShadcn-not-awaited bug with an
it.fails marker plus a companion test asserting today's broken
"[object Promise]" output, per plans/005 (fix deferred by operator).
* chore(shadcn): add shared test helpers for temp dirs and fixtures
Adds getFixturesDir and withTempDir under src/test-helpers so future
tests don't re-implement mkdtemp cleanup boilerplate or hand-build
fixture paths with __dirname.
* test(shadcn): delete dead vendored-starter test in remix fixture
test/fixtures/frameworks/remix-indie-stack/app/utils.test.ts tested the
vendored Remix Indie Stack starter's own validateEmail helper, not shadcn
code. It's excluded from discovery via the **/fixtures/** vitest exclude,
so this has zero effect on the suite total.
* test(shadcn): move addComponents workspace-routing tests into src/utils
Relocate test/utils/add-components.test.ts's "addComponents workspace
routing" describe block (real addComponents against mock workspace
configs) to a new sibling file, src/utils/add-components.workspace.test.ts,
instead of merging into the existing src/utils/add-components.test.ts.
The existing test file's vi.mock factories replace get-config and
update-files wholesale (no real getWorkspaceConfig/findPackageRoot/
updateFiles passthrough), which conflicts with what the workspace-routing
suite needs. vi.mock is per-file, so a sibling file keeps both real and
mocked variants working side by side.
Also drops the now-untyped `name` field from resolveRegistryTree mock
payloads (not part of registryResolvedItemsTreeSchema, and unused by
addComponents) now that these tests are typechecked as part of src/ for
the first time.
* test(shadcn): move registry and registries/add-registry tests into src/
- test/utils/registry.test.ts -> merged into src/registry/api.test.ts as
a new "resolveTree" describe (sole coverage of resolveTree).
- test/utils/get-item-target-path.test.ts -> merged into
src/registry/api.test.ts as a new "getItemTargetPath" describe;
fixture paths switched to getFixturesDir() from @/src/test-helpers.
- test/utils/registries.test.ts -> src/utils/registries.test.ts.
- test/utils/add-registries.test.ts -> src/commands/registry/add.test.ts
(tests parseRegistryArg, which lives in src/commands/registry/add.ts).
All four now typecheck as part of src/** for the first time. Only type
fix needed: getConfig() returns Config | null, so the moved
getItemTargetPath assertions non-null-assert its result.
* fix(shadcn): complete the registry test-move commit from the prior step
The previous commit's staging step used `git add -A -- <paths>` with a
stale pathspec that failed outright (exit 128), which meant the commit
silently went through with only the git-mv'd renames/deletions and
none of the follow-up import-path fixes and new describe blocks made
via Edit afterward. src/commands/registry/add.test.ts and
src/utils/registries.test.ts were committed still pointing at
../../src/... paths (broken from their new location), and
src/registry/api.test.ts was committed without the merged resolveTree
/getItemTargetPath describes at all. This commit captures those
already-verified changes so HEAD matches what was actually tested.
* test(shadcn): move get-config and get-project-info cluster into src/
- test/utils/get-config.test.ts -> src/utils/get-config.test.ts,
restructured into describe("getRawConfig"/"getProjectConfig"/
"getConfig"/"getWorkspaceConfig") blocks (test -> it), fixture paths
switched to getFixturesDir().
- test/utils/get-project-info.test.ts -> src/utils/get-project-info.test.ts,
test/test.each -> it/it.each; merged in as new describes:
- test/utils/get-tailwind-css-file.test.ts ("get tailwindcss file")
- test/utils/get-ts-config-alias-prefix.test.ts ("get ts config alias prefix")
- test/utils/is-typescript-project.test.ts ("is TypeScript project")
(all four test getters exported from src/utils/get-project-info.ts).
- test/utils/get-package-manager.test.ts -> src/utils/get-package-manager.test.ts,
split into describe blocks per exported function, test -> it.
All now typecheck as part of src/** for the first time; no type errors
surfaced.
* test(shadcn): move resolve-import and dry-run tests into src/utils
- test/utils/resolve-import.test.ts -> src/utils/resolve-import.test.ts,
restructured into describe("resolveImport") + the two pre-existing
describes, test -> it, fixture paths via getFixturesDir().
- test/utils/dry-run.test.ts -> src/utils/dry-run.test.ts, test -> it
throughout (already describe-organized), fixture/temp-dir paths via
getFixturesDir().
Dropped the unused `name` field from 10 resolveRegistryTree mock
payloads (not part of registryResolvedItemsTreeSchema) now that this
file typechecks as part of src/** for the first time.
* test(shadcn): move transformer tests into src/utils/transformers
- test/utils/apply-color-mapping.test.ts + test/utils/transform-css-vars.test.ts
-> merged into src/utils/transformers/transform-css-vars.test.ts.
- test/utils/apply-prefix.test.ts + test/utils/transform-tw-prefix.test.ts
-> merged into src/utils/transformers/transform-tw-prefix.test.ts.
- test/utils/transform-import.test.ts -> src/utils/transformers/transform-import.test.ts.
- test/utils/transform-rsc.test.ts -> src/utils/transformers/transform-rsc.test.ts.
- test/utils/transform-rtl.test.ts -> src/utils/transformers/transform-rtl.test.ts;
deleted 8 commented-out test() blocks that asserted nothing.
test -> it throughout; snapshot-bearing tests kept their exact top-level
title (no new describe wrapping) so vitest regenerates snapshots under
the identical key — diffed byte-identical against the originals before
deleting the orphaned test/utils/__snapshots__ files.
Per reviewer authorization: cast partial Config literals passed to
transform() with `as Config` (60 call sites across
transform-import/rsc/rtl/tw-prefix/css-vars.test.ts), and one
`baseColor: "stone" as any` where a bare string was passed where the
type expects a base-color object (preserves the original, intentional
runtime input unchanged). Also cast the ts-morph/TS-internal
`sourceFile.parseDiagnostics` access in transform-rtl.test.ts as `any`
rather than substituting a different (public) API. All casts only;
no assertions or literal values changed. Verified: every regenerated
snapshot is byte-identical to its pre-move original, and
`pnpm test src/utils/transformers/` passes 196/196 both before and
after the casts were added.
* test(shadcn): move updater tests into src/utils/updaters
- test/utils/updaters/update-tailwind-content.test.ts -> src/utils/updaters/update-tailwind-content.test.ts
- test/utils/updaters/update-dependencies.test.ts -> src/utils/updaters/update-dependencies.test.ts
- test/utils/updaters/update-css.test.ts -> src/utils/updaters/update-css.test.ts
- test/utils/updaters/update-css-vars.test.ts -> src/utils/updaters/update-css-vars.test.ts
- test/utils/updaters/update-tailwind-config.test.ts -> src/utils/updaters/update-tailwind-config.test.ts
- test/utils/updaters/update-files.test.ts (2604 lines, largest) -> src/utils/updaters/update-files.test.ts
test -> it / test.each -> it.each throughout; fixture and scratch-temp-dir
paths switched to getFixturesDir() from @/src/test-helpers. Snapshot-
bearing files (update-tailwind-content, update-tailwind-config) diffed
byte-identical against their pre-move originals before the old
test/utils/updaters/__snapshots__ files were deleted.
Also deleted test/utils/updaters/__snapshots__/initialize-tailwind-config.test.ts.snap,
an orphan with no corresponding test file anywhere in the repo (grep
confirmed) — out of the plan's 27-row map but required to satisfy the
"no orphaned snapshot dirs" done-criterion and let Step 8 rmdir the now-
empty test/utils/updaters directory.
Per reviewer authorization (round 1), fixed the resulting typecheck
errors with casts only, no restructuring or assertion changes:
- `as Config` on partial Config/resolvedPaths object literals passed to
transformTailwindContent/transformTailwindConfig/updateDependencies/
transformCssVars/resolveFilePath (update-files.test.ts alone needed
~59 such casts, plus a `(await getConfig(...))!` non-null assertion
on the 11 getConfig() calls that had no existing `if (!config) throw`
guard).
- `as any` on wrapper objects that don't fit any named type at all: the
`{ config: SHARED_CONFIG }` argument in update-tailwind-content/
update-tailwind-config tests (the production functions take `config`
directly, not a wrapped options object — this mismatch predates this
move and is left as-is per "casts only, do not restructure"), the
flat color-map literals passed to buildTailwindThemeColorsFromCssVars,
the `file` param in two resolveFilePath test.each callbacks (whose
`type` field widens to `string` across the array), and the partial
`ProjectInfo` literals passed to toAliasedImport tests.
Verified every regenerated snapshot is byte-identical to its pre-move
original, and `pnpm test src/utils/updaters/` passes 278/278 both
before and after the casts were added.
* test(shadcn): characterize registry source include resolution
Adds source.test.ts covering the previously-untested include resolver
in src/registry/source.ts: happy-path flattening (flat, single include,
two-level nested include), root validation, and every containment
guard (absolute/traversal/URL paths, non-registry.json includes, include
cycles, duplicate includes, max include depth, duplicate item names).
* test(shadcn): cover workspace adaptation in template scaffolding
Export getInstallArgs, adaptWorkspaceConfig, and rewriteWorkspaceProtocol
from create-template.ts (no logic changes) and add unit tests covering
the destructive package-manager adaptation that runs when scaffolding a
non-pnpm project: lockfile/workspace-config removal, packageManager and
workspaces rewriting, and workspace: protocol rewriting for npm.
Also removes the vestigial "**/templates/**" vitest exclude, which dates
to migration commit e51648139 and today only matches this CLI's own
source files under src/templates/ (no scaffold-template project
directories live there). Verified via `npx vitest list` before/after:
the collected test set changed by exactly one file,
src/templates/create-template.test.ts - nothing else was newly picked up.
Full suite: 83 files / 1584 tests passing (was 82/1571 baseline + this
file's 13 tests). typecheck and build both exit 0.
* test(shadcn): cover add command orchestration branches
Integration-style tests for the `add` command action handler, pinning the
routing between dry-run, the missing-config init flow, the empty-project
create-project flow, the registry:style/theme overwrite confirm, the
universal registry item short-circuit, the app-index update guard, and the
Tailwind v4 deprecated-components guard. Collaborators (runInit,
createProject, addComponents, updateAppIndex, dryRunComponents, prompts) are
mocked at their seams; preFlightAdd, getConfig, and the registry fetch path
run for real against temp-dir fixtures and an MSW-served registry.
* chore(shadcn): format test files with prettier
* feat(v4): generate cross-library icon mapping from registry placeholders
* feat(shadcn): migrate icons between any icon libraries
* fix(shadcn): harden icon template regexes flagged by CodeQL
* fix(shadcn): replace usage-template regexes with a linear scanner