Sync Shadcn

SkillDev tools

Lets your agent plan, track, review, and apply syncing of upstream shadcn docs into Plate docs.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Sync Shadcn skill

About this capability

Autogoal-backed planning, status, review, dashboard, apply, and tracking for upstream shadcn docs syncs into Plate docs. Use when the user asks for `sync-shadcn`, `sync-shadcn status`, `sync-shadcn review`, `sync-shadcn dashboard`, `sync-shadcn apply`, a scoped `sync-shadcn <feature>` lane, to sync

What this skill tells your AI

The instructions your AI receives, as published by udecode/plate in .agents/skills/sync-shadcn/SKILL.md and read by ahel’s review.

Handle $ARGUMENTS.

Goal: compare the tracked upstream shadcn docs baseline with the current ../shadcn/apps/v4 target, inventory every added/modified/deleted upstream change, map each change to Plate's docs app, classify the merge decision, write a reviewable plan under docs/sync/shadcn, directly merge any qualifying tiny overlap fixes, then stop for user review of the remaining slices. A later explicit user acceptance starts implementation mode for a named plan and slice.

If $ARGUMENTS starts with a command name, dispatch to that command before the default planning/implementation flow. If $ARGUMENTS names a feature, product surface, or slice, run a scoped planning lane for that scope. The default full-range planning lane applies only when no command or scope is mentioned.

This skill exists because Plate's docs app is a forked product surface, not a generic shadcn mirror. Upstream owns the Fumadocs/shadcn docs architecture. Plate owns Plate docs content, editor demos, registry content, API MDX, CN docs, MCP, Plate Plus hooks, GA, and a small set of intentional forks.

Autogoal Dependency

This skill depends on $autogoal. Load autogoal before mutable sync state, upstream pull/fetch, run artifact writes, status JSON edits, or implementation delegation.

sync-shadcn is a derived autogoal workflow and a two-phase lane:

  • Planning mode is the default. It writes the range plan, updates lastPlannedCommit, directly applies qualifying micro-overlap merges, asks the user to review the remaining plan, and stops.
  • Implementation mode starts only after the user explicitly accepts a plan and slice in a later instruction, except for the micro-overlap direct merge exception below.
  • Default flow mode: one-shot execution for planning mode and one-shot execution for accepted implementation mode. They are separate activations.
  • Use collaborative planning only when the user is explicitly deciding policy before a range plan is written.
  • Primary template: docs/plans/templates/sync-shadcn.md.
  • Default packs: none. Add docs if docs/content pages are edited during an accepted implementation, browser if visible docs UI is edited, and agent-native if .agents/**, .claude/**, .codex/**, skills, commands, prompts, or user-action tooling are edited.
  • Required evidence types: command, source-audit, artifact, and N/A rows. Add browser evidence when a planning scope or accepted implementation touches visible docs UI.
  • Visual sync scopes must capture comparable screenshots of the upstream shadcn page and the Plate page before making or closing a visual parity call. Save only screenshots and notes, not broad upstream patch files.
  • autogoal owns goal lifecycle, blocked/completion semantics, active-goal conflict handling, plan instantiation, output-budget discipline, and check-complete.mjs.
  • sync-shadcn owns shadcn range policy, commit accounting, upstream inventory classification, Plate fork/exclusion decisions, status JSON semantics, and merge-slice handoff.

Micro-Overlap Direct Merge Exception

The default review boundary is still real. Do not use it as an excuse to miss obvious tiny upstream fixes on components Plate already mirrors.

During planning, directly merge a change when all of these are true:

  • The upstream row maps to a retained Plate component, primitive, hook, or utility with a clear local owner path, not to upstream product content.
  • The parent surface is already synced, an accepted partial sync, or an obvious overlapping primitive such as Button, Badge, Input, Command, Tooltip, PageHeader, or the copied docs-shell components.
  • The diff is tiny: one local file, one behavior/class/token/prop/import fix, no new files, no deleted files, no new dependency, no route, no data model, no generated output, and no package or lockfile edit.
  • The local Plate file still has the old value or an equivalent local variant that should receive the same fix.
  • The change does not touch settled exclusions: v0, create, charts, colors, Rhea/theme/customizer/style-registry product surfaces, upstream docs prose, external registry directory content, or generated public/r/** output.
  • No product judgment is needed. If the change changes layout, UX, copy, route shape, docs concepts, registry semantics, or multi-file architecture, it is not a micro-merge.

Examples of direct merges:

  • Replace one stale utility class on Plate's copied Button because upstream fixed the same class on every style variant.
  • Apply one bugfix conditional to a copied Command or CopyButton primitive when Plate has the same bug and no Plate product requirement changes.
  • Remove one dead prop/import from a synced component when upstream removed it and Plate has no local dependency on it.

Examples that still require review:

  • Package bumps, lockfile changes, registry schema/route changes, docs concept additions, new components, deleted components, multi-file UI chunks, visual layout rewrites, sidebar/search behavior changes, generated registry output, and anything touching a deferred or rejected product surface.

When a micro-overlap merge is found:

  1. Record it in the run plan under ## Micro Auto-Merges with upstream path, Plate path, focused diff summary, why it qualifies, and verification.
  2. Patch the Plate owner file directly in the same activation.
  3. Run the smallest meaningful verification: focused eslint/typecheck/source audit; add browser proof when the changed component is browser-visible and a stable route exists.
  4. Add a partialSyncs entry if the full baseline does not advance. Keep lastSyncedCommit unchanged unless the whole range is complete.
  5. Continue to stop for review on every non-micro slice.

Commands

Supported commands:

  • status: summarize current shadcn sync state, partial syncs, deferred decisions, and recommended next step without writing sync artifacts.
  • dashboard: regenerate the structured feature-delta dashboard under docs/sync/shadcn for visual review of synced, deferred, rejected, forked, and pending shadcn sync decisions.
  • apply: apply a copied dashboard review payload to docs/sync/shadcn/deltas.json, answer question-only rows without mutation, implement rows targeting synced, then regenerate the dashboard when rows changed.
  • review: re-audit the current tracked shadcn range against ../shadcn and the current Plate checkout before trusting an existing plan.

Feature-scoped planning:

  • Any non-command $ARGUMENTS value is a user-named scope. Treat the full argument string as the scope label instead of hardcoding allowed feature names.
  • Scope labels can describe UI surfaces, routes, product areas, registry groups, content families, or implementation slices.
  • If the scope is too vague to map to upstream and Plate files, ask one focused question before writing artifacts.

Command parsing:

  • The first $ARGUMENTS token is the command when it matches a supported command.
  • The full $ARGUMENTS string is the scope when the first token is not a supported command.
  • If no command or scope is present, use the default full-range planning/implementation flow.
  • Reserved commands are status, dashboard, apply, and review; do not treat them as scope labels.
  • Scopes are planning lanes, not broad implementation permission. A scoped plan still stops for user review before non-micro apps/www work.

Scoped Planning

Use sync-shadcn <scope> when the user wants to sync only one named surface before reviewing broader docs sync work.

Purpose:

  • compare the tracked upstream range, but inventory and classify only changes that affect the named scope
  • write a reviewable scope-specific plan under docs/sync/shadcn
  • avoid the default full-range lane unless the user invokes sync-shadcn without a command or scope

Scope discovery:

  • Translate the user-named scope into likely upstream files under ../shadcn/apps/v4 and likely Plate files under apps/www.
  • Search names, route paths, component names, config keys, registry names, and docs paths that match the scope.
  • Include all matching hunks that directly affect the scope.
  • Exclude adjacent changes that only share a file but belong to another surface; classify those as out-of-scope.

Scoped planning rules:

  • Save artifacts in a scope-named run directory or plan name, for example docs/sync/shadcn/runs/<date>-<base>-to-<target>-<scope-slug>/.
  • Use upstream diffs/logs for the same baseline and target as the default lane, but filter inventory rows to scope-matching files and patch hunks.
  • Also record an out-of-scope count for upstream rows in the range so it is clear the scoped plan cannot advance lastSyncedCommit alone.
  • If the scope is visual or route-owned, capture upstream and Plate screenshots for the matching route(s) at the same viewport before finalizing the plan. Use docs/sync/shadcn/runs/<range>/screenshots/ for committed evidence, and include screenshot paths plus the visible deltas in the plan.
  • Do not update lastSyncedCommit from a scoped plan. Scoped sync can add a partialSyncs entry after accepted implementation, but the baseline advances only when the full range is accounted for.
  • The plan's recommended slices must stay inside the named scope. If a file also contains unrelated changes, classify the scope hunk as smart-merge and the unrelated hunks as out-of-scope for this lane.
  • Final planning output must say that the default full sync lane remains pending for the out-of-scope rows.

status

Use sync-shadcn status when the user wants a quick checkpoint before choosing the next sync step.

Purpose:

  • show the current baseline, latest planned target, current upstream target, and whether the tracked plan looks fresh enough for decision-making
  • list accepted partial syncs already landed
  • list deferred decisions so the user can choose what to do next
  • list reviewable Plate-vs-shadcn differences that are still intentionally undecided or deferred, especially visual parity gaps from scoped sync plans
  • recommend the next command or decision

Status mode may:

  • read docs/sync/shadcn/status.json
  • read lastPlan, the linked inventory.md, and the latest run directory when present
  • resolve ../shadcn refs and fetch origin main --tags when the user asks for current upstream freshness; if fetch fails, report freshness as unverified
  • count upstream commits and file-status rows for lastPlannedCommit..origin/main
  • summarize partialSyncs[*].slices, partialSyncs[*].deferred, and plan Questions
  • when the user supplies words after status, treat the remaining argument as a status scope filter, for example status our /editors vs shadcn /blocks; prefer the matching partialSyncs[*].plan, lastPlan, or run directory before falling back to global status
  • summarize remaining reviewable differences from the matched plan's Recommended Merge Slices, Visual Evidence, Implementation Result, and partialSyncs[*].deferred

Status mode must not:

  • patch apps/www
  • write docs/sync/shadcn/runs/**
  • write review artifacts
  • change lastSyncedCommit, lastPlannedCommit, lastPlan, or partialSyncs
  • delegate implementation to task
  • treat listed deferred items as accepted decisions
  • list settled exclusions or preserved Plate forks as if they still need action; those belong in review evidence or the plan, not routine status output

Status must distinguish three things:

  • Landed: accepted partial sync slices already applied.
  • Reviewable differences: Plate still differs from upstream and the difference is not settled policy. These are the items the user can re-decide. Include the upstream behavior, current Plate behavior, likely owner files, and the smallest next command or decision.
  • Settled differences: explicit exclusions and preserved Plate forks. Do not list these by default unless the user asks to re-open them.

Deferred item sources, in order:

  1. docs/sync/shadcn/status.json partialSyncs[*].deferred
  2. the selected plan's Questions section
  3. recommended merge slices marked defer, needs-question, or not yet implemented
  4. visual evidence rows where the plan says a Plate-vs-upstream difference still needs work
  5. implementation-result notes that explicitly leave a follow-up slice open
  6. status update notes that say lastSyncedCommit cannot advance

For visual scoped status, do not stop at "fresh" when visible deltas remain. Report them as reviewable differences even when the scoped implementation was verified. Example:

Reviewable differences:
- BlockViewer toolbar: upstream `/blocks` has compact device controls,
  refresh, separated command pill, and v0 action; Plate `/editors` still keeps
  its current toolbar density and excludes v0. Decision: sync toolbar spacing
  only, keep Plate install/source behavior and no v0; or leave as Plate fork.

Collapse upstream product/theme/style noise into its owning deferred decision. For example, Rhea/style/theme/generated style registry rows are part of the upstream create/theming product surface; do not list them as separate status items unless the user explicitly asks to review that product surface.

Status checks:

node -e '
const fs = require("fs");
const status = JSON.parse(fs.readFileSync("docs/sync/shadcn/status.json", "utf8"));
console.log(JSON.stringify({
  lastSyncedCommit: status.lastSyncedCommit,
  lastPlannedCommit: status.lastPlannedCommit,
  lastPlan: status.lastPlan,
  partialSyncs: status.partialSyncs ?? []
}, null, 2));
'

git -C ../shadcn fetch origin main --tags
TARGET=$(git -C ../shadcn rev-parse origin/main)
PLANNED=$(node -e 'console.log(JSON.parse(require("fs").readFileSync("docs/sync/shadcn/status.json", "utf8")).lastPlannedCommit || "")')
git -C ../shadcn log --oneline --decorate "$PLANNED..$TARGET" -- apps/v4
git -C ../shadcn diff --name-status --find-renames "$PLANNED..$TARGET" -- apps/v4

Status output shape:

Status: <fresh | upstream-ahead | no-plan | blocked-ref | unverified>
Baseline: <lastSynced-short>
Planned: <lastPlanned-short>
Current upstream: <target-short>
Plan: <path or none>

Partial syncs:
- <date/range>: <landed slices>

Reviewable differences:
- <surface>: upstream <behavior>; Plate <behavior>; decision needed <adopt |
  smart-merge | keep fork>; files <paths>

Deferred decisions:
- <item>

Next: <run review | rerun planning | decide deferred item | implement accepted slice | advance baseline>

Keep status concise, but do not hide reviewable differences behind a generic "deferred" label. If the user wants full evidence, tell them to run sync-shadcn review.

apply

Use sync-shadcn apply when the user pastes a dashboard review payload.

Purpose:

  • apply rows listed directly under $sync-shadcn apply or under an optional Rows heading
  • answer rows listed under Questions in chat without mutating deltas.json
  • keep the copied dashboard prompt short by storing the mutation contract in this command

Apply mode may:

  • read and update docs/sync/shadcn/deltas.json
  • patch apps/www, content/docs, and related source files when a listed row targets synced or fork
  • delegate a coherent implementation slice to task when a synced or fork row needs more than a tiny local edit
  • remove screenshot refs for rows applied to synced or rejected
  • delete unreferenced local screenshot files under docs/sync/shadcn/runs/**
  • run pnpm sync-shadcn dashboard after any JSON mutation

Apply mode must not:

  • write docs/sync/shadcn/runs/** except deleting unreferenced screenshots
  • change lastSyncedCommit, lastPlannedCommit, lastPlan, or partialSyncs
  • infer decisions for rows not listed in the pasted payload
  • mutate deltas.json for question-only rows
  • mark a row synced or fork before implementation is present and verified
  • ask for review when the row has clear files, suggestion, and acceptance criteria; ask one focused question only when the target behavior is unclear

Payload shape:

$sync-shadcn apply

- command-menu/command-footer-shortcuts (Command Menu / Footer shortcuts and copy payloads): defer -> pending note: Add copy only for components and editor kits.

Questions:
- registry/registry-review (Registry / Full registry review): Which registry rows should include copy shortcuts?

Apply rules:

  • A direct bullet row under $sync-shadcn apply, or under an optional Rows heading, is the only mutation unit.
  • Set each listed item state to the requested target state.
  • Target states pending, defer, and rejected are metadata decisions.
  • Target state synced is implementation mode: inspect the row files and suggestion, implement the requested change, run focused verification, then update deltas.json to synced.
  • Target state fork is also implementation mode when the row's note, suggestion, or files imply work in Plate. Inspect the row files and suggestion, implement or verify the intentional Plate-owned fork, run focused verification, then update deltas.json to fork.
  • A fork update may be metadata-only only when the Plate fork already exists, the row note does not ask for code/content work, and the source evidence is checked before updating deltas.json.
  • Use notes to update decision, suggestion, or summary text when appropriate.
  • If a note is only a question, keep it under Questions, answer it in chat, and do not mutate JSON.
  • When applying synced or rejected, remove that row's screenshots object and delete unreferenced local screenshot files.
  • Keep screenshots for fork rows.
  • If any row is applied, run pnpm sync-shadcn dashboard.

dashboard

Use sync-shadcn dashboard when the user wants a visual decision board for the shadcn sync delta instead of prose status output.

Purpose:

  • render feature-owned sync deltas grouped by product surface, such as header, home, editors, releases, command menu, registry, create, preview routes, and sidebar
  • show review states that can be re-decided later: pending, defer, fork, rejected, and synced
  • keep settled exclusions visible in the dashboard without polluting routine status output
  • make user review possible through a local static HTML artifact
  • include browser-only state controls, note textareas, and a copy button that builds a concise $sync-shadcn apply payload
  • include quick row actions in two rows: Ask, Defer, then Sync, Reject, Fork; pending is a state/filter, not a row action
  • keep note textareas locked until the user chooses an explicit row intent: Ask, a quick apply action, or a changed state value
  • render review actions as selected controls; Sync copies an $sync-shadcn apply row targeting synced, which means implementation mode for that row
  • render Fork as an implementation-capable action too: copied payloads targeting fork mean "make or verify the Plate-owned fork", not "metadata only"
  • use suggestion as the durable item field for Plate-owned recommendation text, rendered as Suggestion in the dashboard with an explicit Apply action that copies that suggestion into Note
  • treat Ask as question-only: it keeps the current row state, writes the row under Questions, and must not mutate deltas.json
  • treat question-only notes as questions to answer in chat, not as decisions to apply to deltas.json; only rows under Rows in a $sync-shadcn apply payload should mutate structured state
  • open on the actionable filter by default: pending and defer; keep synced, rejected, and fork available behind explicit filters
  • split state filters into an Action row and a Done row so active review work is visually separate from settled policy/history
  • render Suggestion and shadcn screenshot columns for non-synced review rows when row screenshot paths exist, with click-to-zoom and close behavior in the static HTML page
  • remove screenshot refs for synced and rejected rows during dashboard generation, and delete unreferenced local screenshot files; keep screenshot evidence for fork rows because forked differences stay useful
  • render one card per delta item instead of a wide table, with Suggestion vs shadcn text in two responsive columns and empty screenshot areas hidden
  • do not use an item-level next field in deltas.json; status and workflow guidance should come from item state, decision, suggestion, and group summary

Dashboard mode may:

  • read docs/sync/shadcn/status.json
  • read and update docs/sync/shadcn/deltas.json
  • write docs/sync/shadcn/dashboard.json
  • write docs/sync/shadcn/dashboard.html

Dashboard mode must not:

  • patch apps/www
  • write docs/sync/shadcn/runs/**
  • change lastSyncedCommit, lastPlannedCommit, lastPlan, or partialSyncs
  • delegate implementation to task
  • treat a dashboard item as user acceptance to implement

State meanings:

  • synced: the slice was accepted, implemented, and verified.
  • defer: the item is acknowledged but intentionally postponed.
  • pending: the item has no final decision yet, including rows waiting on a user decision.
  • fork: Plate intentionally keeps a different implementation, and that implementation is present or has been verified before the row is marked fork.
  • rejected: upstream behavior is explicitly excluded.

Dashboard source:

  • docs/sync/shadcn/deltas.json is the editable structured decision source.
  • docs/sync/shadcn/dashboard.json and docs/sync/shadcn/dashboard.html are generated views.
  • When adding a landed implementation slice, update status.json first, then add or update the matching deltas.json feature row, then regenerate the dashboard.
  • When rejecting, deferring, or forking a feature, record the upstream behavior, suggestion, owner files, and state rationale in deltas.json.
  • For non-synced visual rows, add screenshot paths under screenshots.suggestion and screenshots.shadcn when available. Leave source-only rows blank.
  • The HTML review controls are intentionally not persistent. The user can mark many rows, copy the generated prompt, and send it back; Codex applies the JSON edits and regenerates the dashboard.

Dashboard command:

pnpm sync-shadcn dashboard

This regenerates dashboard.html and opens it in the local browser. Use --no-open or SYNC_SHADCN_NO_OPEN=1 when running in a non-GUI check.

Dashboard output shape:

Dashboard: docs/sync/shadcn/dashboard.html
Data: docs/sync/shadcn/dashboard.json
Opened: file:///.../docs/sync/shadcn/dashboard.html

| Feature | State | Items |
| --- | --- | ---: |
| Registry | defer | 2 |

review

Use sync-shadcn review when the user asks whether the latest sync plan is still fresh, whether a previously written plan can still be implemented, or whether current apps/www drift changed the merge posture.

Purpose:

  • prove whether docs/sync/shadcn/status.json, the latest plan artifacts, the current ../shadcn/apps/v4 target, and the current Plate docs checkout still describe the same sync problem
  • find new upstream commits since lastPlannedCommit
  • find stale inventory artifacts for the lastSyncedCommit..target range
  • re-run local Plate owner/source evidence for actionable rows before implementation

Inputs:

  • optional plan path or run directory; default to lastPlan from docs/sync/shadcn/status.json
  • optional target ref; default to origin/main in ../shadcn
  • baseline from lastSyncedCommit
  • planned target from lastPlannedCommit

Review mode may:

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
17k
Forks
996
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
sync-shadcn
Source
github.com/udecode/plate