@minhduydev/mdpi 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/template/.pi/VERSION +1 -1
  3. package/dist/template/.pi/extensions/templates-injector.ts +35 -7
  4. package/dist/template/.pi/prompts/INDEX.md +3 -9
  5. package/dist/template/.pi/skills/INDEX.md +39 -8
  6. package/dist/template/.pi/skills/dcp-hygiene/SKILL.md +1 -1
  7. package/dist/template/.pi/skills/frontend-design/SKILL.md +1 -1
  8. package/dist/template/.pi/skills/frontend-design/references/animation/motion-advanced.md +88 -15
  9. package/dist/template/.pi/skills/frontend-design/references/animation/motion-core.md +148 -13
  10. package/dist/template/.pi/skills/frontend-design/references/shadcn/setup.md +127 -20
  11. package/dist/template/.pi/skills/nextjs-app-router/SKILL.md +334 -0
  12. package/dist/template/.pi/skills/nextjs-cache/SKILL.md +262 -0
  13. package/dist/template/.pi/skills/react-best-practices/SKILL.md +79 -1
  14. package/dist/template/.pi/skills/react-compiler/SKILL.md +237 -0
  15. package/dist/template/.pi/skills/react-hook-form/SKILL.md +374 -0
  16. package/dist/template/.pi/skills/react-server-actions/SKILL.md +299 -0
  17. package/dist/template/.pi/skills/shadcn-ui/SKILL.md +404 -0
  18. package/dist/template/.pi/skills/tanstack-query/SKILL.md +330 -0
  19. package/dist/template/.pi/skills/v0/SKILL.md +264 -0
  20. package/dist/template/.pi/skills/zustand/SKILL.md +333 -0
  21. package/package.json +1 -1
  22. package/dist/template/.pi/prompts/loop-check.md +0 -87
  23. package/dist/template/.pi/prompts/loop-init.md +0 -157
  24. package/dist/template/.pi/prompts/loop-review.md +0 -90
  25. package/dist/template/.pi/skills/loop-audit/SKILL.md +0 -141
  26. package/dist/template/.pi/skills/loop-cost/SKILL.md +0 -130
  27. package/dist/template/.pi/skills/loop-engineering/SKILL.md +0 -175
  28. package/dist/template/.pi/templates/loop-github-action.yml +0 -162
  29. package/dist/template/.pi/templates/loop-orchestrator.sh +0 -514
  30. package/dist/template/.pi/templates/loop-orchestrator.test.ts +0 -332
  31. package/dist/template/.pi/templates/loop-orchestrator.ts +0 -936
  32. package/dist/template/.pi/templates/loop-state.json +0 -24
  33. package/dist/template/.pi/templates/loop-state.md +0 -98
  34. package/dist/template/.pi/templates/loop-vision.md +0 -110
@@ -1,56 +1,161 @@
1
1
  # shadcn/ui Setup
2
2
 
3
- CLI v3.6.x (current: v3.6.3) - Copy-paste components, Radix UI + Tailwind v4.
3
+ CLI v4.x (current: shadcn@4.11.0) Copy-paste components, Radix UI / Base UI + Tailwind v4.
4
4
 
5
- ## New Project
5
+ ## Create a New Project
6
6
 
7
7
  ```bash
8
8
  npx shadcn create
9
9
  ```
10
10
 
11
11
  Interactive setup:
12
- - Visual style: Vega, Nova, Maia, Lyra, Mira
13
- - Component library: Radix UI or Base UI
14
- - Icon library (including Phosphor)
15
- - Next.js 16 support
12
+ - **Visual style**: Vega, Nova, Maia, Lyra, Mira
13
+ - **Component library**: Radix UI or Base UI
14
+ - **Icon library** (Lucide, Phosphor, etc.)
15
+ - **Next.js 16**, Vite, Laravel, React Router, Astro, TanStack Start support
16
+ - **Template scaffolding** via `npx shadcn init --template`
16
17
 
17
18
  ## Existing Project
18
19
 
19
20
  ```bash
20
- npx shadcn@latest init
21
+ npx shadcn@latest init --preset <code>
21
22
  npx shadcn@latest add button card dialog
22
23
  npx shadcn@latest add --all
24
+ npx shadcn@latest add <username>/<repo>/<item> # GitHub Registry
23
25
  ```
24
26
 
25
27
  Components install to `components/ui/`.
26
28
 
29
+ ## Key CLI v4 Commands
30
+
31
+ ```bash
32
+ # Inspection
33
+ npx shadcn info # Full project config (for agent context)
34
+ npx shadcn info --json # JSON output for programmatic use
35
+ npx shadcn docs <component> # Docs, code, examples from CLI
36
+
37
+ # Preview changes before writing
38
+ npx shadcn add button --dry-run # Show what will be installed
39
+ npx shadcn add button --diff # Show diff against current
40
+ npx shadcn add button --view # Open component in browser
41
+
42
+ # Project setup flags
43
+ npx shadcn init --preset a1Dg5eFl # Pack entire design system into short code
44
+ npx shadcn init --template # Scaffold project templates
45
+ npx shadcn init --monorepo # Monorepo setup
46
+ npx shadcn init --base radix # Choose primitives (radix | base)
47
+
48
+ # Skills (AI Agent)
49
+ npx skills add shadcn/ui # Install agent prompt file
50
+ npx shadcn skills generate # Regenerate after adding components
51
+ npx shadcn skills update # Update monthly
52
+ ```
53
+
27
54
  ## Visual Styles
28
55
 
29
- | Style | Description |
30
- |-------|-------------|
31
- | **Vega** | Classic shadcn look |
32
- | **Nova** | Reduced padding, compact |
33
- | **Maia** | Soft, rounded, generous |
34
- | **Lyra** | Boxy, sharp, mono fonts |
35
- | **Mira** | Compact, dense interfaces |
56
+ | Style | Characteristics |
57
+ |-------|----------------|
58
+ | **Vega** | Classic shadcn look — balanced, versatile |
59
+ | **Nova** | Reduced padding, compact, space-efficient |
60
+ | **Maia** | Soft, rounded corners, generous spacing |
61
+ | **Lyra** | Boxy, sharp corners, monospace fonts |
62
+ | **Mira** | Compact, dense, data-heavy interfaces |
63
+
64
+ Styles rewrite component code, not just CSS — fonts, spacing, structure, primitives all adapt.
65
+
66
+ ## Presets
67
+
68
+ Presets pack the entire design system into a reproducible short code:
69
+
70
+ ```bash
71
+ # Export your preset
72
+ npx shadcn preset export
73
+
74
+ # Init a project with a preset
75
+ npx shadcn init --preset a1Dg5eFl
76
+ ```
77
+
78
+ A preset includes: colors, theme, icons, fonts, radius, spacing — everything in one code.
36
79
 
37
80
  ## Component Libraries
38
81
 
39
- - **Radix UI** (default): Full accessibility, React-only
40
- - **Base UI**: MUI unstyled components
82
+ - **Radix UI** (default): Full accessibility, React-only, battle-tested
83
+ - **Base UI**: MUI unstyled components, headless
84
+
85
+ Select during `npx shadcn create` or with `--base` flag. CLI auto-detects your library when pulling components.
86
+
87
+ ## GitHub Registries (June 2026)
88
+
89
+ Any public GitHub repo with a `registry.json` can be a component registry:
41
90
 
42
- Select during `npx shadcn create` or in `components.json`.
91
+ ```bash
92
+ npx shadcn@latest add <username>/<repo>/<item>
93
+ ```
94
+
95
+ Distribute: components, hooks, utilities, design tokens, feature kits, project conventions, CI workflows, templates. No build step — CLI reads `registry.json` directly.
96
+
97
+ ```json
98
+ // registry.json (in any GitHub repo)
99
+ {
100
+ "name": "my-components",
101
+ "items": [
102
+ {
103
+ "name": "data-table",
104
+ "type": "registry:component",
105
+ "files": [{ "path": "components/data-table.tsx" }]
106
+ }
107
+ ]
108
+ }
109
+ ```
110
+
111
+ ## shadcn/skills — AI Agent Bridge
112
+
113
+ ```bash
114
+ npx skills add shadcn/ui
115
+ ```
116
+
117
+ Creates `.shadcn/skills.md` — a machine-readable file that gives AI coding agents project-aware context:
118
+
119
+ - **Project context** — framework, aliases, installed components, icon library, base library (via `shadcn info --json`)
120
+ - **CLI command reference** — all flags, smart merge, presets, templates
121
+ - **Theming guidance** — CSS vars, OKLCH, dark mode, Tailwind v3/v4
122
+ - **Registry authoring** — `registry.json` format
123
+ - **Pattern enforcement** — FieldGroup for forms, ToggleGroup for options, semantic colors
124
+
125
+ **Measured impact**: API errors 34% → 3%, correct variants 61% → 98%, first-try success 45% → 89%.
126
+
127
+ **Critical workflows**:
128
+ - Re-generate after adding components: `npx shadcn skills generate`
129
+ - Update monthly: `npx shadcn skills update`
130
+ - Reference file path (don't paste into context — 4K cutoff)
43
131
 
44
132
  ## MCP Server Support
45
133
 
46
- - OpenCode MCP (v3.6.3)
47
- - Codex MCP (v3.4.0)
134
+ Connect AI editors to your registry:
135
+
136
+ ```json
137
+ {
138
+ "mcpServers": {
139
+ "shadcn": {
140
+ "command": "npx",
141
+ "args": ["-y", "shadcn@canary", "registry:mcp"],
142
+ "env": {
143
+ "REGISTRY_URL": "https://your-registry.vercel.app/r/registry.json"
144
+ }
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ Also: OpenCode MCP (v3.6.3), Codex MCP (v3.4.0).
48
151
 
49
152
  ## Registry System
50
153
 
51
154
  - Registry Directory: https://ui.shadcn.com/docs/directory
52
155
  - Custom registries via `components.json`
53
156
  - Namespaced components
157
+ - `registry:base` — distribute entire design systems
158
+ - `registry:font` — distribute font packages
54
159
 
55
160
  ## Component List
56
161
 
@@ -66,4 +171,6 @@ Select during `npx shadcn create` or in `components.json`.
66
171
 
67
172
  **Overlay**: Dropdown Menu, Context Menu, Popover, Collapsible
68
173
 
69
- **Other**: Toggle, Toggle Group, Kbd, Button Group, Item, Empty, Input OTP
174
+ **2026 New**: Spinner, Kbd, KbdGroup, Button Group, Input Group, Field, Item, Empty, Input OTP
175
+
176
+ **Other**: Toggle, Toggle Group
@@ -0,0 +1,334 @@
1
+ ---
2
+ name: nextjs-app-router
3
+ description: Use when building or refactoring Next.js App Router pages. Covers file conventions, layouts vs templates, parallel/intercepting routes, route groups, async params, streaming, RSC boundaries. MUST load before any App Router architecture work.
4
+ ---
5
+
6
+ # Next.js App Router Patterns (Next.js 15+)
7
+
8
+ ## When to Use
9
+
10
+ - Building new pages in Next.js App Router
11
+ - Understanding or refactoring App Router file conventions
12
+ - Designing route architecture (parallel routes, intercepting, groups)
13
+ - Setting up layouts, error boundaries, and loading states
14
+ - Making decisions about Server vs Client Components
15
+
16
+ ## When NOT to Use
17
+
18
+ - Pages Router projects (`pages/` directory — use `react-best-practices`)
19
+ - Non-Next.js React projects (Vite, Remix, React Router)
20
+ - Pure API routes (not page structure)
21
+
22
+ ## File Conventions Reference
23
+
24
+ | File | Purpose | Runs |
25
+ |------|---------|------|
26
+ | `page.tsx` | Route's unique UI | Server (default) |
27
+ | `layout.tsx` | Shared UI that persists across navigations | Server (default) |
28
+ | `template.tsx` | Shared UI that remounts on navigation | Server (default) |
29
+ | `loading.tsx` | Suspense fallback while page loads | Server (default) |
30
+ | `error.tsx` | Error boundary for the segment | Client |
31
+ | `not-found.tsx` | 404 UI for the segment | Server (default) |
32
+ | `default.tsx` | Fallback for parallel routes | Server (default) |
33
+ | `route.tsx` | API endpoint for the segment | Server |
34
+
35
+ ## Layout vs Template
36
+
37
+ **Layout**: persists across navigations, state preserved.
38
+
39
+ ```tsx
40
+ // app/dashboard/layout.tsx
41
+ export default function DashboardLayout({ children }: { children: React.ReactNode }) {
42
+ return (
43
+ <div>
44
+ <nav>Sidebar — stays mounted</nav>
45
+ <main>{children}</main>
46
+ </div>
47
+ )
48
+ }
49
+ ```
50
+
51
+ **Template**: remounts on every navigation. Use when you need:
52
+ - Page transitions (AnimatePresence needs remount)
53
+ - `useEffect` that must re-run on navigation
54
+ - Resetting client state between pages
55
+
56
+ ```tsx
57
+ // app/dashboard/template.tsx
58
+ 'use client'
59
+
60
+ import { AnimatePresence, motion } from 'motion/react'
61
+
62
+ export default function Template({ children }: { children: React.ReactNode }) {
63
+ return (
64
+ <AnimatePresence mode="wait">
65
+ <motion.div
66
+ key={usePathname()}
67
+ initial={{ opacity: 0 }}
68
+ animate={{ opacity: 1 }}
69
+ exit={{ opacity: 0 }}
70
+ >
71
+ {children}
72
+ </motion.div>
73
+ </AnimatePresence>
74
+ )
75
+ }
76
+ ```
77
+
78
+ **Rule**: Layout wraps Template wraps Page: `layout.tsx > template.tsx > page.tsx`
79
+
80
+ ## Route Groups — `(group)/`
81
+
82
+ Use parentheses to group routes without affecting the URL:
83
+
84
+ ```
85
+ app/
86
+ ├── (marketing)/
87
+ │ ├── page.tsx → /
88
+ │ ├── about/page.tsx → /about
89
+ │ └── layout.tsx # Marketing layout
90
+ ├── (dashboard)/
91
+ │ ├── dashboard/page.tsx → /dashboard
92
+ │ └── layout.tsx # Dashboard layout (different from marketing)
93
+ ```
94
+
95
+ ## Parallel Routes — `@folder/`
96
+
97
+ Render multiple pages in the same layout simultaneously:
98
+
99
+ ```
100
+ app/
101
+ ├── dashboard/
102
+ │ ├── layout.tsx # Accepts both props:
103
+ │ ├── @analytics/ # children, analytics, team
104
+ │ │ └── page.tsx
105
+ │ ├── @team/
106
+ │ │ └── page.tsx
107
+ │ └── page.tsx # Default children
108
+ ```
109
+
110
+ ```tsx
111
+ // app/dashboard/layout.tsx
112
+ export default function DashboardLayout(props: {
113
+ children: React.ReactNode
114
+ analytics: React.ReactNode
115
+ team: React.ReactNode
116
+ }) {
117
+ return (
118
+ <div className="grid grid-cols-2">
119
+ <div>{props.children}</div>
120
+ <div>{props.analytics}</div>
121
+ <div>{props.team}</div>
122
+ </div>
123
+ )
124
+ }
125
+ ```
126
+
127
+ Each slot needs a `default.tsx` for initial load and unmatched routes.
128
+
129
+ ## Intercepting Routes — `(.)folder/`
130
+
131
+ Render a route in the context of another without full navigation:
132
+
133
+ | Convention | Meaning |
134
+ |-----------|---------|
135
+ | `(.)folder/` | Same level |
136
+ | `(..)folder/` | One level up |
137
+ | `(..)(..)folder/` | Two levels up |
138
+ | `(...)folder/` | From root |
139
+
140
+ Common pattern: Photo modal:
141
+
142
+ ```
143
+ app/
144
+ ├── photos/
145
+ │ ├── page.tsx # Photos grid: /
146
+ │ └── [id]/
147
+ │ └── page.tsx # Photo detail: /photos/1
148
+ └── @modal/
149
+ ├── default.tsx # null return
150
+ └── (.)photos/
151
+ └── [id]/
152
+ └── page.tsx # Modal overlay when navigating from photos grid
153
+ ```
154
+
155
+ ```tsx
156
+ // app/layout.tsx
157
+ export default function RootLayout({ children, modal }) {
158
+ return (
159
+ <>
160
+ {children}
161
+ {modal}
162
+ </>
163
+ )
164
+ }
165
+ ```
166
+
167
+ ## Async Server Components
168
+
169
+ ```tsx
170
+ // app/posts/[id]/page.tsx — no 'use client'
171
+ export default async function PostPage({
172
+ params,
173
+ }: {
174
+ params: Promise<{ id: string }> // params is a Promise in Next.js 15+
175
+ }) {
176
+ const { id } = await params
177
+ const post = await db.post.findUnique({ where: { id } })
178
+
179
+ return <article>{post.content}</article>
180
+ }
181
+ ```
182
+
183
+ **Next.js 15+**: `params`, `searchParams` are Promises — must `await` them.
184
+
185
+ ## Streaming with Suspense + loading.tsx
186
+
187
+ ```tsx
188
+ // app/posts/page.tsx
189
+ import { Suspense } from 'react'
190
+
191
+ export default function PostsPage() {
192
+ return (
193
+ <div>
194
+ <h1>Posts</h1>
195
+ <Suspense fallback={<PostsSkeleton />}>
196
+ <PostsList /> {/* Streams in when ready */}
197
+ </Suspense>
198
+ <Suspense fallback={<StatsSkeleton />}>
199
+ <PostStats /> {/* Streams independently */}
200
+ </Suspense>
201
+ </div>
202
+ )
203
+ }
204
+ ```
205
+
206
+ - `loading.tsx` wraps the entire page in Suspense automatically
207
+ - Manual `<Suspense>` gives finer control — stream sections independently
208
+ - Wrap data-fetching Server Components in Suspense
209
+
210
+ ## RSC Boundary Rules
211
+
212
+ ```
213
+ Server Component (default)
214
+ └─ can render → Client Components
215
+ └─ can pass → serializable props only (no functions, no JSX as props)
216
+ └─ can use → async/await, direct DB access, filesystem, secrets
217
+
218
+ Client Component ('use client')
219
+ └─ can render → Server Components (passed as children)
220
+ └─ can use → hooks, event handlers, browser APIs, state
221
+ └─ cannot → async/await directly, access DB
222
+ ```
223
+
224
+ **Boundary pattern** — push 'use client' as deep as possible:
225
+
226
+ ```tsx
227
+ // ✅ Server Component (default) — data fetching here
228
+ export default async function UserProfile({ userId }) {
229
+ const user = await db.user.findUnique({ where: { id: userId } })
230
+
231
+ return (
232
+ <div>
233
+ <h1>{user.name}</h1>
234
+ <EditButton /> {/* Only the interactive leaf is client */}
235
+ </div>
236
+ )
237
+ }
238
+
239
+ // ✅ Client leaf — only what needs interactivity
240
+ 'use client'
241
+ function EditButton() {
242
+ const [open, setOpen] = useState(false)
243
+ return <button onClick={() => setOpen(true)}>Edit</button>
244
+ }
245
+ ```
246
+
247
+ ## Error Handling
248
+
249
+ ```tsx
250
+ // app/dashboard/error.tsx
251
+ 'use client'
252
+
253
+ export default function DashboardError({
254
+ error,
255
+ reset,
256
+ }: {
257
+ error: Error & { digest?: string }
258
+ reset: () => void
259
+ }) {
260
+ return (
261
+ <div>
262
+ <h2>Something went wrong!</h2>
263
+ <button onClick={() => reset()}>Try again</button>
264
+ </div>
265
+ )
266
+ }
267
+ ```
268
+
269
+ - `error.tsx` must be a Client Component
270
+ - Errors bubble up to the nearest `error.tsx`
271
+ - `reset()` re-renders the error boundary's children
272
+ - `error.tsx` in a nested segment only catches errors in that segment and below
273
+
274
+ ## Middleware
275
+
276
+ ```tsx
277
+ // middleware.ts (root level)
278
+ import { NextResponse } from 'next/server'
279
+ import type { NextRequest } from 'next/server'
280
+
281
+ export function middleware(request: NextRequest) {
282
+ const token = request.cookies.get('token')
283
+
284
+ // Protect routes
285
+ if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
286
+ return NextResponse.redirect(new URL('/login', request.url))
287
+ }
288
+
289
+ return NextResponse.next()
290
+ }
291
+
292
+ export const config = {
293
+ matcher: ['/dashboard/:path*']
294
+ }
295
+ ```
296
+
297
+ ## Metadata API
298
+
299
+ ```tsx
300
+ // Static metadata
301
+ export const metadata: Metadata = {
302
+ title: 'Dashboard',
303
+ description: 'Manage your account',
304
+ }
305
+
306
+ // Dynamic metadata (Server Components)
307
+ export async function generateMetadata({ params }): Promise<Metadata> {
308
+ const post = await getPost(params.id)
309
+ return { title: post.title, description: post.excerpt }
310
+ }
311
+ ```
312
+
313
+ ## Common Pitfalls
314
+
315
+ | Pitfall | Fix |
316
+ |---------|-----|
317
+ | Adding `'use client'` to a layout | Layouts are Server Components by default; only add `'use client'` when you need hooks |
318
+ | Forgetting `default.tsx` for parallel routes | Every slot needs a `default.tsx` for initial load |
319
+ | Passing functions as props from Server to Client | Functions are not serializable — define them in the client |
320
+ | Using `useSearchParams()` in Server Component | Use `searchParams` prop (Promise in v15+) |
321
+ | `params` treated as plain object (v15+) | `params` is now a Promise — must `await params` |
322
+ | No Suspense boundary for async component | Wrap in `<Suspense>` or ensure `loading.tsx` exists |
323
+ | `layout.tsx` doesn't receive `searchParams` | Only `page.tsx` gets `searchParams` |
324
+
325
+ ## Verification
326
+
327
+ - [ ] Server Components are the default — `'use client'` only where interactive
328
+ - [ ] `params` and `searchParams` are awaited (Next.js 15+)
329
+ - [ ] Error boundaries (`error.tsx`) exist at appropriate levels
330
+ - [ ] Loading states (`loading.tsx` or `<Suspense>`) for async pages
331
+ - [ ] Parallel route slots each have `default.tsx`
332
+ - [ ] Layout and template used correctly (persist vs remount)
333
+ - [ ] Route groups used to share layouts without affecting URL
334
+ - [ ] Functions and non-serializable data stay in Client Components