@deckio/deck-engine 0.2.1 → 0.2.3
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.
- package/instructions/AGENTS.md +12 -0
- package/instructions/deck-project.instructions.md +6 -0
- package/instructions/shadcn-components.instructions.md +283 -0
- package/instructions/shadcn-setup.instructions.md +117 -0
- package/instructions/slide-css.instructions.md +8 -0
- package/instructions/slide-jsx.instructions.md +20 -0
- package/package.json +2 -1
- package/scripts/sync-version-from-npm.mjs +68 -0
- package/skills/deck-add-slide/SKILL.md +29 -0
- package/skills/deck-validate-project/SKILL.md +38 -0
- package/styles/global.css +7 -1
- package/themes/descriptors/funky-punk.md +231 -0
- package/themes/descriptors/shadcn-design-system.md +467 -0
- package/themes/descriptors/shadcn.md +356 -106
package/instructions/AGENTS.md
CHANGED
|
@@ -24,3 +24,15 @@ Create and maintain slide-based presentations. Each project is a self-contained
|
|
|
24
24
|
- `@deckio/deck-engine` provides: `Slide`, `BottomBar`, `Navigation`, `SlideProvider`, `useSlides`, `GenericThankYouSlide`
|
|
25
25
|
- See `.github/instructions/` for detailed conventions on slide JSX, CSS modules, and deck.config.js
|
|
26
26
|
- See `.github/skills/` for step-by-step workflows (e.g., adding a slide)
|
|
27
|
+
|
|
28
|
+
## Design system
|
|
29
|
+
|
|
30
|
+
Check `designSystem` in `deck.config.js`. When it is `'shadcn'`:
|
|
31
|
+
|
|
32
|
+
- Real shadcn/ui components are preinstalled: `Button`, `Card`, `Badge`, `Separator`, `Alert`
|
|
33
|
+
- ReactBits motion components are preinstalled: `Aurora`, `BlurText`, `ShinyText`, `DecryptedText`, `SpotlightCard`
|
|
34
|
+
- **Prefer real component imports over CSS imitation** — this is the default authoring pattern
|
|
35
|
+
- **Expand via MCP** — the shadcn MCP server is pre-configured in `.vscode/mcp.json`. To add new components, prompt Copilot (e.g., *"Add Dialog from shadcn"*) or use `npx shadcn@latest add <name>`
|
|
36
|
+
- Both shadcn/ui and ReactBits registries are configured in `components.json` and coexist cleanly
|
|
37
|
+
- Read the shadcn supplement instructions (`shadcn-setup.instructions.md`, `shadcn-components.instructions.md`) for the full reference
|
|
38
|
+
- See `MCP-GUIDE.md` for detailed MCP authoring prompts and workflows
|
|
@@ -29,6 +29,12 @@ Then read the active theme descriptor:
|
|
|
29
29
|
|
|
30
30
|
Use the descriptor as the source of truth for slide structure, CSS patterns, decorative language, component ecosystem, and anti-patterns.
|
|
31
31
|
|
|
32
|
+
If `designSystem` is `shadcn`, also read the shadcn supplement instructions:
|
|
33
|
+
- `shadcn-setup.instructions.md` — infrastructure contract
|
|
34
|
+
- `shadcn-components.instructions.md` — component reference, preinstalled set, MCP expansion workflow
|
|
35
|
+
|
|
36
|
+
Real shadcn/ui components (`Button`, `Card`, `Badge`, `Separator`, `Alert`) are preinstalled — prefer them over CSS imitation. To add more components, use MCP (prompt Copilot, e.g., *"Add Dialog from shadcn"*) or CLI (`npx shadcn@latest add dialog`). See `MCP-GUIDE.md` for the full MCP authoring reference.
|
|
37
|
+
|
|
32
38
|
## Out of scope — do NOT modify
|
|
33
39
|
|
|
34
40
|
- `App.jsx`, `main.jsx` — these are generic, engine-driven, identical across projects
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Component reference and migration patterns for shadcn DECKIO decks. Read alongside shadcn-setup.instructions.md when designSystem is shadcn."
|
|
3
|
+
applyTo: "**/*"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# shadcn Component Reference
|
|
7
|
+
|
|
8
|
+
Read this file when `deck.config.js` has `designSystem: 'shadcn'`. It complements the setup contract (`shadcn-setup.instructions.md`) with component-specific authoring guidance.
|
|
9
|
+
|
|
10
|
+
## Component availability matrix
|
|
11
|
+
|
|
12
|
+
| Component | Status | How to get it | Import path |
|
|
13
|
+
|-----------|--------|---------------|-------------|
|
|
14
|
+
| `Button` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/button'` |
|
|
15
|
+
| `Card` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/card'` |
|
|
16
|
+
| `CardHeader` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/card'` |
|
|
17
|
+
| `CardTitle` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/card'` |
|
|
18
|
+
| `CardDescription` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/card'` |
|
|
19
|
+
| `CardAction` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/card'` |
|
|
20
|
+
| `CardContent` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/card'` |
|
|
21
|
+
| `CardFooter` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/card'` |
|
|
22
|
+
| `Badge` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/badge'` |
|
|
23
|
+
| `Separator` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/separator'` |
|
|
24
|
+
| `Alert` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/alert'` |
|
|
25
|
+
| `Aurora` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/aurora'` |
|
|
26
|
+
| `BlurText` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/blur-text'` |
|
|
27
|
+
| `ShinyText` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/shiny-text'` |
|
|
28
|
+
| `DecryptedText` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/decrypted-text'` |
|
|
29
|
+
| `SpotlightCard` | ✅ Preinstalled | Scaffolded automatically | `'@/components/ui/spotlight-card'` |
|
|
30
|
+
| `Dialog` | ➕ Add first | `npx shadcn@latest add dialog` | `'@/components/ui/dialog'` |
|
|
31
|
+
| `Sheet` | ➕ Add first | `npx shadcn@latest add sheet` | `'@/components/ui/sheet'` |
|
|
32
|
+
| `Tooltip` | ➕ Add first | `npx shadcn@latest add tooltip` | `'@/components/ui/tooltip'` |
|
|
33
|
+
| `Accordion` | ➕ Add first | `npx shadcn@latest add accordion` | `'@/components/ui/accordion'` |
|
|
34
|
+
| `Tabs` | ➕ Add first | `npx shadcn@latest add tabs` | `'@/components/ui/tabs'` |
|
|
35
|
+
| `Input` | ➕ Add first | `npx shadcn@latest add input` | `'@/components/ui/input'` |
|
|
36
|
+
| `Table` | ➕ Add first | `npx shadcn@latest add table` | `'@/components/ui/table'` |
|
|
37
|
+
| `Progress` | ➕ Add first | `npx shadcn@latest add progress` | `'@/components/ui/progress'` |
|
|
38
|
+
| Any other shadcn | ➕ Add first | `npx shadcn@latest add <name>` | `'@/components/ui/<name>'` |
|
|
39
|
+
| Any ReactBits | ➕ Add first | `npx shadcn@latest add @react-bits/<name>` | `'@/components/ui/<name>'` |
|
|
40
|
+
|
|
41
|
+
### Preinstalled rule
|
|
42
|
+
|
|
43
|
+
- ✅ components: import directly, no setup needed
|
|
44
|
+
- ➕ components: run the CLI command first, **then** import — never import a file that doesn't exist
|
|
45
|
+
|
|
46
|
+
## Migration patterns: raw markup → real components
|
|
47
|
+
|
|
48
|
+
When updating slides from CSS-imitation patterns to real components, follow these transformations.
|
|
49
|
+
|
|
50
|
+
### Card surface
|
|
51
|
+
|
|
52
|
+
**Before (CSS imitation):**
|
|
53
|
+
```jsx
|
|
54
|
+
<div className={styles.card}>
|
|
55
|
+
<h3 className={styles.cardTitle}>Title</h3>
|
|
56
|
+
<p className={styles.cardText}>Description</p>
|
|
57
|
+
</div>
|
|
58
|
+
```
|
|
59
|
+
```css
|
|
60
|
+
.card {
|
|
61
|
+
background: var(--card);
|
|
62
|
+
border: 1px solid var(--border);
|
|
63
|
+
border-radius: var(--radius);
|
|
64
|
+
padding: 24px;
|
|
65
|
+
}
|
|
66
|
+
.cardTitle { color: var(--card-foreground); font-weight: 600; }
|
|
67
|
+
.cardText { color: var(--muted-foreground); }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**After (real component):**
|
|
71
|
+
```jsx
|
|
72
|
+
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
|
|
73
|
+
|
|
74
|
+
<Card className={styles.metricCard}>
|
|
75
|
+
<CardHeader>
|
|
76
|
+
<CardTitle>Title</CardTitle>
|
|
77
|
+
</CardHeader>
|
|
78
|
+
<CardContent>
|
|
79
|
+
<p>Description</p>
|
|
80
|
+
</CardContent>
|
|
81
|
+
</Card>
|
|
82
|
+
```
|
|
83
|
+
```css
|
|
84
|
+
.metricCard {
|
|
85
|
+
/* Only layout-specific overrides — component handles surface, border, radius */
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Badge / label
|
|
90
|
+
|
|
91
|
+
**Before (CSS imitation):**
|
|
92
|
+
```jsx
|
|
93
|
+
<span className={styles.badge}>Phase 1</span>
|
|
94
|
+
```
|
|
95
|
+
```css
|
|
96
|
+
.badge {
|
|
97
|
+
background: var(--secondary);
|
|
98
|
+
color: var(--secondary-foreground);
|
|
99
|
+
padding: 2px 10px;
|
|
100
|
+
border-radius: 9999px;
|
|
101
|
+
font-size: 12px;
|
|
102
|
+
font-weight: 500;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**After (real component):**
|
|
107
|
+
```jsx
|
|
108
|
+
import { Badge } from '@/components/ui/badge'
|
|
109
|
+
|
|
110
|
+
<Badge variant="secondary">Phase 1</Badge>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Action button
|
|
114
|
+
|
|
115
|
+
**Before (CSS imitation):**
|
|
116
|
+
```jsx
|
|
117
|
+
<button className={styles.actionBtn}>Get started</button>
|
|
118
|
+
```
|
|
119
|
+
```css
|
|
120
|
+
.actionBtn {
|
|
121
|
+
background: var(--primary);
|
|
122
|
+
color: var(--primary-foreground);
|
|
123
|
+
padding: 10px 20px;
|
|
124
|
+
border-radius: var(--radius);
|
|
125
|
+
border: none;
|
|
126
|
+
font-weight: 500;
|
|
127
|
+
cursor: pointer;
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**After (real component):**
|
|
132
|
+
```jsx
|
|
133
|
+
import { Button } from '@/components/ui/button'
|
|
134
|
+
|
|
135
|
+
<Button>Get started</Button>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Alert / callout
|
|
139
|
+
|
|
140
|
+
**Before (CSS imitation):**
|
|
141
|
+
```jsx
|
|
142
|
+
<div className={styles.callout}>
|
|
143
|
+
<strong>Important</strong>
|
|
144
|
+
<p>This is a key message for the audience.</p>
|
|
145
|
+
</div>
|
|
146
|
+
```
|
|
147
|
+
```css
|
|
148
|
+
.callout {
|
|
149
|
+
background: var(--muted);
|
|
150
|
+
border: 1px solid var(--border);
|
|
151
|
+
border-radius: var(--radius);
|
|
152
|
+
padding: 16px;
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**After (real component):**
|
|
157
|
+
```jsx
|
|
158
|
+
import { Alert, AlertTitle, AlertDescription } from '@/components/ui/alert'
|
|
159
|
+
|
|
160
|
+
<Alert>
|
|
161
|
+
<AlertTitle>Important</AlertTitle>
|
|
162
|
+
<AlertDescription>This is a key message for the audience.</AlertDescription>
|
|
163
|
+
</Alert>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Divider
|
|
167
|
+
|
|
168
|
+
**Before (CSS imitation):**
|
|
169
|
+
```jsx
|
|
170
|
+
<hr className={styles.divider} />
|
|
171
|
+
```
|
|
172
|
+
```css
|
|
173
|
+
.divider {
|
|
174
|
+
border: none;
|
|
175
|
+
border-top: 1px solid var(--border);
|
|
176
|
+
margin: 16px 0;
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**After (real component):**
|
|
181
|
+
```jsx
|
|
182
|
+
import { Separator } from '@/components/ui/separator'
|
|
183
|
+
|
|
184
|
+
<Separator />
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Component-first authoring decision tree
|
|
188
|
+
|
|
189
|
+
When building a new slide element in a shadcn deck:
|
|
190
|
+
|
|
191
|
+
1. **Is there a preinstalled component for this?** → Use it. (`Card`, `Badge`, `Button`, `Alert`, `Separator`)
|
|
192
|
+
2. **Is there a preinstalled ReactBits component?** → Use it for motion/effects. (`BlurText`, `SpotlightCard`, etc.)
|
|
193
|
+
3. **Would a non-preinstalled shadcn component fit?** → Add it via MCP or CLI, then import.
|
|
194
|
+
4. **None of the above?** → Write custom JSX + CSS Module using semantic tokens from the descriptor.
|
|
195
|
+
|
|
196
|
+
## Expanding with MCP — the primary workflow
|
|
197
|
+
|
|
198
|
+
**MCP is the recommended way to add components** beyond the preinstalled set. The shadcn MCP server is pre-configured in `.vscode/mcp.json` and gives AI assistants direct access to both the shadcn/ui and ReactBits registries.
|
|
199
|
+
|
|
200
|
+
### How it works
|
|
201
|
+
|
|
202
|
+
When an author (or an AI agent acting on behalf of the author) needs a component that isn't preinstalled:
|
|
203
|
+
|
|
204
|
+
1. **Prompt Copilot** with what you need — e.g., *"Add the Dialog component from shadcn"*
|
|
205
|
+
2. The MCP server resolves the component from the registry
|
|
206
|
+
3. The component source is written to `src/components/ui/`
|
|
207
|
+
4. Import it in your slide: `import { Dialog } from '@/components/ui/dialog'`
|
|
208
|
+
|
|
209
|
+
### Example prompts for agents and authors
|
|
210
|
+
|
|
211
|
+
**shadcn/ui components:**
|
|
212
|
+
- *"Add the Dialog component from shadcn"*
|
|
213
|
+
- *"Add Sheet, Tooltip, and Tabs from shadcn"*
|
|
214
|
+
- *"I need a data table — add Table from shadcn"*
|
|
215
|
+
- *"Add Accordion from shadcn for collapsible sections"*
|
|
216
|
+
- *"What shadcn components would work for a pricing comparison slide?"*
|
|
217
|
+
|
|
218
|
+
**ReactBits components:**
|
|
219
|
+
- *"Add Hyperspeed from React Bits for an animated background"*
|
|
220
|
+
- *"Show me available text animations from React Bits"*
|
|
221
|
+
- *"Add AnimatedContent from React Bits for scroll reveals"*
|
|
222
|
+
|
|
223
|
+
### Registry coexistence
|
|
224
|
+
|
|
225
|
+
Both registries are declared in `components.json` and share the same output directory:
|
|
226
|
+
|
|
227
|
+
| Registry | CLI syntax | MCP prompt pattern |
|
|
228
|
+
|----------|-----------|-------------------|
|
|
229
|
+
| **shadcn/ui** | `npx shadcn@latest add dialog` | *"Add Dialog from shadcn"* |
|
|
230
|
+
| **ReactBits** | `npx shadcn@latest add @react-bits/code-block` | *"Add code-block from React Bits"* |
|
|
231
|
+
|
|
232
|
+
They never conflict — shadcn/ui components use Radix primitives and Tailwind, ReactBits components use their own animation systems. Both consume the same `cn()` utility and `@/` path alias.
|
|
233
|
+
|
|
234
|
+
### CLI fallback
|
|
235
|
+
|
|
236
|
+
If MCP is unavailable, the CLI produces identical results:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
npx shadcn@latest add dialog sheet tooltip
|
|
240
|
+
npx shadcn@latest add @react-bits/animated-content
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### For agents: when to suggest MCP expansion
|
|
244
|
+
|
|
245
|
+
When generating slide code that would benefit from a non-preinstalled component:
|
|
246
|
+
|
|
247
|
+
1. **Don't silently import a component that doesn't exist** — check the preinstalled list above
|
|
248
|
+
2. **Suggest the MCP prompt** — e.g., "This slide would benefit from a Dialog. Run: *Add Dialog from shadcn* or `npx shadcn@latest add dialog`"
|
|
249
|
+
3. **Then generate the slide code** using the component, noting the dependency
|
|
250
|
+
|
|
251
|
+
## Design-system supplement discovery
|
|
252
|
+
|
|
253
|
+
The shadcn design system adds a supplementary authoring layer on top of the theme:
|
|
254
|
+
|
|
255
|
+
- **Theme descriptor** (`shadcn.md`) → visual language, token contract, slide personality, anti-patterns
|
|
256
|
+
- **Setup contract** (`shadcn-setup.instructions.md`) → infrastructure, what's wired, how to verify
|
|
257
|
+
- **Component reference** (this file) → what components exist, how to use them, migration patterns
|
|
258
|
+
|
|
259
|
+
Skills and agents should load all three when `designSystem: 'shadcn'` is detected in `deck.config.js`. The presence of this field is the trigger — there is no separate plugin or runtime discovery mechanism.
|
|
260
|
+
|
|
261
|
+
### How skills detect the design system
|
|
262
|
+
|
|
263
|
+
```js
|
|
264
|
+
// In deck.config.js
|
|
265
|
+
export default {
|
|
266
|
+
// ...
|
|
267
|
+
designSystem: 'shadcn', // ← triggers component-first authoring
|
|
268
|
+
theme: 'shadcn', // ← drives visual token set
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
When a skill reads `designSystem: 'shadcn'`:
|
|
273
|
+
1. Load the theme descriptor for visual rules
|
|
274
|
+
2. Load `shadcn-setup.instructions.md` for infrastructure rules
|
|
275
|
+
3. Load `shadcn-components.instructions.md` for component authoring rules
|
|
276
|
+
4. Prefer real component imports over CSS imitation in all generated code
|
|
277
|
+
|
|
278
|
+
### Extending the supplement pattern
|
|
279
|
+
|
|
280
|
+
If a future design system is added (e.g., `designSystem: 'radix'`), the same pattern applies:
|
|
281
|
+
- Create `<name>-setup.instructions.md` and `<name>-components.instructions.md`
|
|
282
|
+
- Skills check `designSystem` and load the matching supplement files
|
|
283
|
+
- Theme descriptors remain independent of the design system choice
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Canonical Tailwind v4 + shadcn setup contract for DECKIO decks. Read when designSystem is shadcn."
|
|
3
|
+
applyTo: "**/*"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# shadcn Setup Contract
|
|
7
|
+
|
|
8
|
+
Use this file when `deck.config.js` has `designSystem: 'shadcn'`.
|
|
9
|
+
|
|
10
|
+
## What is canonical today
|
|
11
|
+
|
|
12
|
+
1. `src/main.jsx` should import `./index.css`
|
|
13
|
+
2. `src/index.css` is the single CSS entrypoint for the deck
|
|
14
|
+
3. `src/index.css` should import:
|
|
15
|
+
- `@deckio/deck-engine/styles/global.css`
|
|
16
|
+
- `@deckio/deck-engine/themes/<theme>.css`
|
|
17
|
+
4. `global.css` establishes the canonical Tailwind layer order: `@layer theme, base, components, utilities;`
|
|
18
|
+
5. The active theme CSS provides `@import "tailwindcss"` plus the `@theme inline` bridge used by shadcn-style utilities
|
|
19
|
+
|
|
20
|
+
## Preinstalled components
|
|
21
|
+
|
|
22
|
+
Scaffolded shadcn decks ship with **real, working components** out of the box. These are source files copied into the project — not npm dependencies.
|
|
23
|
+
|
|
24
|
+
### shadcn/ui starter set (preinstalled)
|
|
25
|
+
|
|
26
|
+
| Component | Import path | Source |
|
|
27
|
+
|-----------|-------------|--------|
|
|
28
|
+
| `Button` | `'@/components/ui/button'` | Pre-scaffolded from engine templates |
|
|
29
|
+
| `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`, `CardFooter` | `'@/components/ui/card'` | Pre-scaffolded from engine templates |
|
|
30
|
+
| `Badge` | `'@/components/ui/badge'` | Pre-scaffolded from engine templates |
|
|
31
|
+
| `Separator` | `'@/components/ui/separator'` | Pre-scaffolded from engine templates |
|
|
32
|
+
| `Alert`, `AlertTitle`, `AlertDescription` | `'@/components/ui/alert'` | Pre-scaffolded from engine templates |
|
|
33
|
+
|
|
34
|
+
### ReactBits starter set (preinstalled)
|
|
35
|
+
|
|
36
|
+
| Component | Import path | Purpose |
|
|
37
|
+
|-----------|-------------|---------|
|
|
38
|
+
| `Aurora` | `'@/components/ui/aurora'` | Gradient background effect |
|
|
39
|
+
| `BlurText` | `'@/components/ui/blur-text'` | Blur-in text animation |
|
|
40
|
+
| `ShinyText` | `'@/components/ui/shiny-text'` | Shimmer text effect |
|
|
41
|
+
| `DecryptedText` | `'@/components/ui/decrypted-text'` | Glitch text animation |
|
|
42
|
+
| `SpotlightCard` | `'@/components/ui/spotlight-card'` | Spotlight glow card wrapper |
|
|
43
|
+
|
|
44
|
+
### Infrastructure (preinstalled)
|
|
45
|
+
|
|
46
|
+
| Resource | Path | Purpose |
|
|
47
|
+
|----------|------|---------|
|
|
48
|
+
| `cn()` utility | `src/lib/utils.js` | Class name merging (clsx + tailwind-merge) |
|
|
49
|
+
| `ThemeProvider` | `src/components/theme-provider.jsx` | Light/dark mode shell |
|
|
50
|
+
| `components.json` | project root | shadcn CLI + registry config |
|
|
51
|
+
| `jsconfig.json` | project root | `@/*` path alias |
|
|
52
|
+
| `.vscode/mcp.json` | `.vscode/` | shadcn MCP server config |
|
|
53
|
+
|
|
54
|
+
### Add via MCP or CLI (not preinstalled)
|
|
55
|
+
|
|
56
|
+
Everything else in the shadcn/ui and ReactBits registries must be added before importing.
|
|
57
|
+
|
|
58
|
+
**MCP (recommended):** The shadcn MCP server is pre-configured in `.vscode/mcp.json`. Prompt Copilot directly:
|
|
59
|
+
- *"Add the Dialog component from shadcn"*
|
|
60
|
+
- *"Add Sheet and Tooltip from shadcn"*
|
|
61
|
+
- *"Add AnimatedContent from React Bits"*
|
|
62
|
+
|
|
63
|
+
**CLI (fallback):**
|
|
64
|
+
```bash
|
|
65
|
+
# Official shadcn/ui components
|
|
66
|
+
npx shadcn@latest add dialog
|
|
67
|
+
npx shadcn@latest add sheet tooltip input textarea select
|
|
68
|
+
|
|
69
|
+
# ReactBits components via registry
|
|
70
|
+
npx shadcn@latest add @react-bits/code-block
|
|
71
|
+
npx shadcn@latest add @react-bits/animated-content
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Both methods produce the same result — component source files in `src/components/ui/`.
|
|
75
|
+
|
|
76
|
+
### Registry coexistence
|
|
77
|
+
|
|
78
|
+
`components.json` declares two registries that share the same output directory and infrastructure:
|
|
79
|
+
|
|
80
|
+
- **shadcn/ui** (default): UI primitives — no prefix needed
|
|
81
|
+
- **ReactBits** (`@react-bits/`): Animation and effect components
|
|
82
|
+
|
|
83
|
+
They never conflict. shadcn/ui components use Radix + Tailwind, ReactBits components use their own animation systems. Both use the `cn()` utility and `@/` alias.
|
|
84
|
+
|
|
85
|
+
## Default authoring pattern
|
|
86
|
+
|
|
87
|
+
**Real components are the default.** When `designSystem: 'shadcn'`, every new slide should:
|
|
88
|
+
|
|
89
|
+
1. **Import preinstalled components first** — `Button`, `Card`, `Badge`, `Separator`, `Alert` are already there. Use them.
|
|
90
|
+
2. **Use ReactBits for motion** — `BlurText`, `SpotlightCard`, etc. for animation inside content blocks.
|
|
91
|
+
3. **Use CSS Modules only for layout** — grid, spacing, density, positioning. Not for recreating what components already do.
|
|
92
|
+
4. **Never imitate a component with raw markup** — if `<Card>` exists, use it. Don't hand-build a card-like div with border-radius and background.
|
|
93
|
+
5. **Expand via MCP when needed** — if the slide needs a dialog, accordion, or tabs, prompt Copilot (e.g., *"Add Dialog from shadcn"*) or run `npx shadcn@latest add <name>`, then import.
|
|
94
|
+
|
|
95
|
+
## Design-system supplement layer
|
|
96
|
+
|
|
97
|
+
When `designSystem: 'shadcn'` is set in `deck.config.js`, agents should load additional authoring context beyond the theme descriptor:
|
|
98
|
+
|
|
99
|
+
1. Read this file (`shadcn-setup.instructions.md`) for the setup contract
|
|
100
|
+
2. Read `shadcn-components.instructions.md` for the component reference and migration patterns
|
|
101
|
+
3. Check which components exist in `src/components/ui/` before importing — the preinstalled set is guaranteed, but additional ones may have been added by the author
|
|
102
|
+
|
|
103
|
+
This two-layer approach (theme descriptor + design-system supplement) lets the theme control visual language while the design system controls component authoring patterns.
|
|
104
|
+
|
|
105
|
+
## Verification checklist
|
|
106
|
+
|
|
107
|
+
Before claiming a deck is "using shadcn":
|
|
108
|
+
|
|
109
|
+
- `src/index.css` exists and is imported by `src/main.jsx`
|
|
110
|
+
- `components.json` exists with correct aliases (`@/components`, `@/lib/utils`, `@/components/ui`) and registries (`@react-bits`)
|
|
111
|
+
- `@/` resolves to `src`
|
|
112
|
+
- `src/lib/utils.js` exists
|
|
113
|
+
- Preinstalled shadcn/ui components exist: `button.jsx`, `card.jsx`, `badge.jsx`, `separator.jsx`, `alert.jsx` in `src/components/ui/`
|
|
114
|
+
- Preinstalled ReactBits components exist in `src/components/ui/`
|
|
115
|
+
- `.vscode/mcp.json` exists with the shadcn MCP server configured
|
|
116
|
+
- `MCP-GUIDE.md` exists at project root
|
|
117
|
+
- Any additional imported component actually exists under `src/components/ui/`
|
|
@@ -19,6 +19,14 @@ Before writing any slide CSS:
|
|
|
19
19
|
- Custom themes: read `src/themes/<theme>/descriptor.md` or `src/themes/<theme>.descriptor.md`
|
|
20
20
|
- If the custom descriptor is missing, fall back to the built-in descriptor implied by `designSystem`
|
|
21
21
|
|
|
22
|
+
If `designSystem` is `shadcn`, also read the shadcn supplement instructions:
|
|
23
|
+
- `shadcn-setup.instructions.md` — infrastructure contract
|
|
24
|
+
- `shadcn-components.instructions.md` — component reference, preinstalled set, migration patterns
|
|
25
|
+
|
|
26
|
+
### CSS role in shadcn decks
|
|
27
|
+
|
|
28
|
+
When real components are available, **CSS Modules handle layout only** — grid, spacing, density, positioning. The components own their own surface styling (background, border, border-radius, typography). Do not rewrite component styles in CSS Modules. Override only when the descriptor explicitly calls for deck-specific layout adjustments (e.g., a card width constraint or grid gap).
|
|
29
|
+
|
|
22
30
|
## What to read in the descriptor
|
|
23
31
|
|
|
24
32
|
Before generating CSS, read:
|
|
@@ -19,6 +19,10 @@ Before writing any slide JSX:
|
|
|
19
19
|
- Custom themes: read `src/themes/<theme>/descriptor.md` or `src/themes/<theme>.descriptor.md`
|
|
20
20
|
- If the custom descriptor is missing, fall back to the built-in descriptor implied by `designSystem`
|
|
21
21
|
|
|
22
|
+
If `designSystem` is `shadcn`, also read the shadcn supplement instructions:
|
|
23
|
+
- `shadcn-setup.instructions.md` — infrastructure contract
|
|
24
|
+
- `shadcn-components.instructions.md` — component reference, preinstalled set, migration patterns
|
|
25
|
+
|
|
22
26
|
## Common imports
|
|
23
27
|
|
|
24
28
|
```jsx
|
|
@@ -26,6 +30,22 @@ import { BottomBar, Slide } from '@deckio/deck-engine'
|
|
|
26
30
|
import styles from './MySlide.module.css'
|
|
27
31
|
```
|
|
28
32
|
|
|
33
|
+
### shadcn deck imports (when `designSystem === 'shadcn'`)
|
|
34
|
+
|
|
35
|
+
Preinstalled components are ready to import — no CLI setup needed:
|
|
36
|
+
|
|
37
|
+
```jsx
|
|
38
|
+
import { Button } from '@/components/ui/button'
|
|
39
|
+
import { Card, CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter } from '@/components/ui/card'
|
|
40
|
+
import { Badge } from '@/components/ui/badge'
|
|
41
|
+
import { Separator } from '@/components/ui/separator'
|
|
42
|
+
import { Alert, AlertTitle, AlertDescription } from '@/components/ui/alert'
|
|
43
|
+
import SpotlightCard from '@/components/ui/spotlight-card'
|
|
44
|
+
import BlurText from '@/components/ui/blur-text'
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Real components are the default authoring pattern.** Never recreate a Card, Badge, Button, Alert, or Separator with raw `<div>` + CSS when the real component is available.
|
|
48
|
+
|
|
29
49
|
## What to read in the descriptor
|
|
30
50
|
|
|
31
51
|
Before generating JSX, read:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deckio/deck-engine",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"**/*.css"
|
|
41
41
|
],
|
|
42
42
|
"scripts": {
|
|
43
|
+
"version:sync": "node scripts/sync-version-from-npm.mjs",
|
|
43
44
|
"prepublishOnly": "npm test --if-present"
|
|
44
45
|
},
|
|
45
46
|
"dependencies": {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process'
|
|
2
|
+
import { readFileSync, writeFileSync } from 'node:fs'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { dirname, join } from 'node:path'
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
7
|
+
const packageJsonPath = join(__dirname, '..', 'package.json')
|
|
8
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'))
|
|
9
|
+
|
|
10
|
+
function parseVersion(value) {
|
|
11
|
+
const match = String(value || '').trim().match(/^(\d+)\.(\d+)\.(\d+)$/)
|
|
12
|
+
if (!match) {
|
|
13
|
+
throw new Error(`Unsupported semver value: ${value}`)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
major: Number(match[1]),
|
|
18
|
+
minor: Number(match[2]),
|
|
19
|
+
patch: Number(match[3]),
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function compareVersion(left, right) {
|
|
24
|
+
if (left.major !== right.major) return left.major - right.major
|
|
25
|
+
if (left.minor !== right.minor) return left.minor - right.minor
|
|
26
|
+
return left.patch - right.patch
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function formatVersion(value) {
|
|
30
|
+
return `${value.major}.${value.minor}.${value.patch}`
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getPublishedVersion(packageName) {
|
|
34
|
+
const npmCommand = process.platform === 'win32'
|
|
35
|
+
? `npm view ${packageName} version`
|
|
36
|
+
: `npm view ${packageName} version`
|
|
37
|
+
const raw = execSync(npmCommand, {
|
|
38
|
+
encoding: 'utf8',
|
|
39
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
40
|
+
shell: true,
|
|
41
|
+
}).trim()
|
|
42
|
+
|
|
43
|
+
if (!raw) {
|
|
44
|
+
throw new Error(`npm view returned an empty version for ${packageName}`)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return raw
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const localVersion = parseVersion(packageJson.version)
|
|
51
|
+
const publishedVersionRaw = getPublishedVersion(packageJson.name)
|
|
52
|
+
const publishedVersion = parseVersion(publishedVersionRaw)
|
|
53
|
+
|
|
54
|
+
if (compareVersion(localVersion, publishedVersion) > 0) {
|
|
55
|
+
console.log(`Local version ${packageJson.version} is already ahead of npm ${publishedVersionRaw}`)
|
|
56
|
+
process.exit(0)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const nextVersion = {
|
|
60
|
+
major: publishedVersion.major,
|
|
61
|
+
minor: publishedVersion.minor,
|
|
62
|
+
patch: publishedVersion.patch + 1,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
packageJson.version = formatVersion(nextVersion)
|
|
66
|
+
writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`)
|
|
67
|
+
|
|
68
|
+
console.log(`Updated ${packageJson.name} version from ${formatVersion(localVersion)} to ${packageJson.version} using npm latest ${publishedVersionRaw}`)
|
|
@@ -51,6 +51,32 @@ If no custom descriptor exists, fall back to the built-in descriptor that matche
|
|
|
51
51
|
|
|
52
52
|
If the descriptor and `designSystem` disagree, follow `designSystem` for structure and call out the mismatch in your response so the project owner can fix the configuration.
|
|
53
53
|
|
|
54
|
+
### When `designSystem === 'shadcn'`: load the component supplement
|
|
55
|
+
|
|
56
|
+
Also read the shadcn supplement instructions before generating code:
|
|
57
|
+
|
|
58
|
+
1. `shadcn-setup.instructions.md` — infrastructure contract
|
|
59
|
+
2. `shadcn-components.instructions.md` — component reference, migration patterns, MCP expansion workflow
|
|
60
|
+
|
|
61
|
+
These tell you which real components are preinstalled and ready to import:
|
|
62
|
+
|
|
63
|
+
| Preinstalled | Import |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `Button` | `'@/components/ui/button'` |
|
|
66
|
+
| `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`, `CardFooter` | `'@/components/ui/card'` |
|
|
67
|
+
| `Badge` | `'@/components/ui/badge'` |
|
|
68
|
+
| `Separator` | `'@/components/ui/separator'` |
|
|
69
|
+
| `Alert`, `AlertTitle`, `AlertDescription` | `'@/components/ui/alert'` |
|
|
70
|
+
| `Aurora`, `BlurText`, `ShinyText`, `DecryptedText`, `SpotlightCard` | `'@/components/ui/<name>'` |
|
|
71
|
+
|
|
72
|
+
**Always prefer real component imports over CSS imitation.** If a preinstalled component can replace a hand-built div, use the component.
|
|
73
|
+
|
|
74
|
+
**Need a component that isn't preinstalled?** Use MCP (recommended) or CLI to add it first:
|
|
75
|
+
- MCP: Prompt Copilot — *"Add Dialog from shadcn"* or *"Add AnimatedContent from React Bits"*
|
|
76
|
+
- CLI: `npx shadcn@latest add dialog` or `npx shadcn@latest add @react-bits/animated-content`
|
|
77
|
+
|
|
78
|
+
Never import a component file that doesn't exist. Add it first, then import.
|
|
79
|
+
|
|
54
80
|
## Step 3 — Create the slide from the descriptor
|
|
55
81
|
|
|
56
82
|
The descriptor is the source of truth. Read these sections before generating code:
|
|
@@ -109,6 +135,9 @@ After writing the slide:
|
|
|
109
135
|
|
|
110
136
|
- [ ] Read `theme` and `designSystem` from `deck.config.js`
|
|
111
137
|
- [ ] Read the active theme descriptor before writing code
|
|
138
|
+
- [ ] If `designSystem === 'shadcn'`: read the shadcn supplement instructions
|
|
139
|
+
- [ ] If `designSystem === 'shadcn'`: used real component imports (Card, Badge, Button, Alert, Separator) instead of CSS imitation
|
|
140
|
+
- [ ] If `designSystem === 'shadcn'` and a non-preinstalled component is needed: added it via MCP or CLI before importing
|
|
112
141
|
- [ ] Used the descriptor's exact JSX skeleton or direct variant of it
|
|
113
142
|
- [ ] Used the descriptor's exact CSS skeleton or direct variant of it
|
|
114
143
|
- [ ] Stayed inside the descriptor's token set and component ecosystem
|
|
@@ -96,6 +96,40 @@ Check whether the project configuration and descriptor agree:
|
|
|
96
96
|
- If `designSystem` is not `'shadcn'`, the project should follow a default DECKIO descriptor such as dark or light
|
|
97
97
|
- If the descriptor and `designSystem` disagree, report an **architecture mismatch** even if individual slides render
|
|
98
98
|
|
|
99
|
+
### When `designSystem === 'shadcn'`: validate preinstalled components
|
|
100
|
+
|
|
101
|
+
Verify the preinstalled component set is intact:
|
|
102
|
+
|
|
103
|
+
- [ ] `src/components/ui/button.jsx` exists
|
|
104
|
+
- [ ] `src/components/ui/card.jsx` exists
|
|
105
|
+
- [ ] `src/components/ui/badge.jsx` exists
|
|
106
|
+
- [ ] `src/components/ui/separator.jsx` exists
|
|
107
|
+
- [ ] `src/components/ui/alert.jsx` exists
|
|
108
|
+
- [ ] `src/lib/utils.js` exists (provides `cn()`)
|
|
109
|
+
- [ ] `components.json` exists at project root with correct aliases and registries
|
|
110
|
+
- [ ] `.vscode/mcp.json` exists with shadcn MCP server configured
|
|
111
|
+
- [ ] `MCP-GUIDE.md` exists at project root
|
|
112
|
+
- [ ] ReactBits files exist: `aurora.jsx`, `blur-text.jsx`, `shiny-text.jsx`, `decrypted-text.jsx`, `spotlight-card.jsx` in `src/components/ui/`
|
|
113
|
+
|
|
114
|
+
If any preinstalled file is missing, report it as a **scaffold integrity issue** — the file may have been accidentally deleted.
|
|
115
|
+
|
|
116
|
+
### Validate MCP integration
|
|
117
|
+
|
|
118
|
+
- [ ] `.vscode/mcp.json` exists and contains a `shadcn` server entry
|
|
119
|
+
- [ ] `components.json` has `registries` with `@react-bits` configured
|
|
120
|
+
- [ ] `components.json` has correct `aliases` (`@/components`, `@/lib/utils`, `@/components/ui`)
|
|
121
|
+
|
|
122
|
+
If MCP config is missing, the author loses the primary component expansion workflow.
|
|
123
|
+
|
|
124
|
+
### Validate component usage patterns
|
|
125
|
+
|
|
126
|
+
For each slide in a shadcn deck, check:
|
|
127
|
+
|
|
128
|
+
- [ ] Slides use real `<Card>`, `<Badge>`, `<Button>`, `<Alert>`, `<Separator>` imports instead of CSS-imitation divs where applicable
|
|
129
|
+
- [ ] No hand-built card-like patterns when the Card component is available
|
|
130
|
+
- [ ] No raw `<button>` or `<span className={styles.badge}>` when real components exist
|
|
131
|
+
- [ ] CSS Modules focus on layout (grid, spacing, positioning) not component surface styling
|
|
132
|
+
|
|
99
133
|
## Step 6: Report results
|
|
100
134
|
|
|
101
135
|
Summarize:
|
|
@@ -112,6 +146,10 @@ Summarize:
|
|
|
112
146
|
|
|
113
147
|
- [ ] Read `theme` and `designSystem`
|
|
114
148
|
- [ ] Read the active descriptor
|
|
149
|
+
- [ ] If `designSystem === 'shadcn'`: read shadcn supplement instructions
|
|
150
|
+
- [ ] If `designSystem === 'shadcn'`: verified preinstalled component files exist
|
|
151
|
+
- [ ] If `designSystem === 'shadcn'`: verified MCP config (`.vscode/mcp.json`, `components.json` registries)
|
|
152
|
+
- [ ] If `designSystem === 'shadcn'`: verified slides use real components over CSS imitation
|
|
115
153
|
- [ ] All `deck.config.js` imports resolve
|
|
116
154
|
- [ ] `slides` array matches imports
|
|
117
155
|
- [ ] Every `.jsx` slide has a companion `.module.css`
|