Move docs/ package mirror into document-navigator plugin

Relocate the ~6k-file docs tree from the repo root into
plugins/document-navigator/docs/ so the plugin is self-contained and
portable. docs/superpowers/ (specs and plans) stays at the repo root.

Moved via cp+rm rather than git mv because directory rename() fails with
EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the
identical-content files at commit time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 01:10:00 +01:00
parent fe3fedf42e
commit 9bf56a806b
6022 changed files with 12437 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
# `check-registry-eject`
## Purpose
Shadcn-eject smoke gate for `@suaveplan/react-ui`. Verifies the `registry/r/*.json` tree against the package source so a downstream consumer running `shadcn add @suaveplan/<name>` always finds the files the registry promised. Catches the realistic drift modes today: a registry entry whose listed file vanished (rename / restructure), a component directory shipped without a registry entry (forgot to regenerate), an orphaned registry entry whose component was deleted (forgot to clean up), and entries that fail JSON or shape validation. Runs as part of `bunx turbo lint` on every commit.
## Features
- Per-entry validation: shape (`name`, `type`, `files`), JSON parse, non-empty `files[]`.
- Per-file existence: every `files[].path` resolves to a real file under `src/components/<name>/`.
- Bidirectional drift detection: registry entries without matching component directories AND component directories without registry entries both fail.
- Sorted, stable diagnostic output for diff-friendly CI logs.
- Pure helper exports (`audit`, `loadEntry`) reusable from tests.
## Usage: Basic Example
```bash
bun run check:registry-eject
# check-registry-eject: clean — 51 registry entries match 51 component directories.
```
When a registry entry lists a missing file:
```bash
bun run check:registry-eject
# MISSING_SOURCE_FILE registry/r/toast.json: file 'toast.tsx' does not exist at src/components/toast/toast.tsx
# check-registry-eject: 1 diagnostic(s) — see above.
# (exit 1)
```
## Usage: Advanced Example
The exported helpers can be reused — for example, a CI report generator that walks both registries (`react-ui` + a future `react-ui-social`) and emits a unified report:
```ts
import { audit } from "@suaveplan/react-ui/scripts/check-registry-eject";
const diagnostics = await audit({
registryEntries: await listEntries(packageA),
componentDirs: await listDirs(packageA),
componentsDir: join(packageA, "src/components"),
});
```
## API Reference
### CLI
`bun scripts/check-registry-eject.ts`
Exits 0 on a clean tree; exits 1 on any diagnostic; exits 2 when the registry directory or components directory is missing entirely (configuration error).
### Exported helpers
- `loadEntry(entryPath): Promise<RegistryEntry | { error }>` — reads + validates a single `registry/r/<name>.json` entry. Returns `{ error: string }` on any structural failure (missing field, wrong type, malformed JSON).
- `audit({ registryEntries, componentDirs, componentsDir }): Promise<Diagnostic[]>` — pure function returning sorted diagnostics. The four diagnostic kinds are: `MISSING_REGISTRY_ENTRY`, `MISSING_SOURCE_FILE`, `EMPTY_FILES_LIST`, `MALFORMED_ENTRY`, `ORPHAN_REGISTRY_ENTRY`.
## Implementation Notes
- The gate is intentionally narrower than the proposal's full vision — it verifies file presence + entry shape, NOT that the ejected source compiles against a synthesized consumer `tsconfig.json`. The synthesized-tsconfig roundtrip depends on the registry transform itself (rewriting `@suaveplan/react-ui` imports to consumer-local paths) which today is a passthrough — `build-registry.ts` ships source verbatim, so a consumer's `shadcn add` already gets compilable source. When the transform lands as a callable helper (per the comment block in `build-registry.ts`), this gate's `audit()` will be extended to invoke it and then run `tsc --noEmit` against the transformed tree.
- `index.json` is excluded from the per-entry walk — it is the manifest of manifests, not an individual component.
- Component directories whose only files are barrels (`index.ts` only, no `<name>.tsx`/`<name>.ts`) are NOT detected as component directories. The list-detection mirrors `build-registry.ts`'s heuristic.
- Both `.tsx` and `.ts` extensions are valid for the file listed in `files[]`. Components like `<Toast>` that ship as JSX-free TypeScript ship as `.ts`; the registry entry for them lists `<name>.ts` and the gate accepts it.