design-protocol 1.0.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 (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +225 -0
  3. package/agents/dp-researcher.md +239 -0
  4. package/agents/dp-verifier.md +207 -0
  5. package/bin/install.js +464 -0
  6. package/commands/dp-back.md +221 -0
  7. package/commands/dp-discuss.md +257 -0
  8. package/commands/dp-execute.md +513 -0
  9. package/commands/dp-journey.md +85 -0
  10. package/commands/dp-progress.md +178 -0
  11. package/commands/dp-roadmap.md +83 -0
  12. package/commands/dp-skip.md +186 -0
  13. package/commands/dp-start.md +510 -0
  14. package/commands/dp-storytell.md +94 -0
  15. package/commands/dp-verify.md +207 -0
  16. package/package.json +59 -0
  17. package/skills/dp-color/SKILL.md +214 -0
  18. package/skills/dp-color/export_tokens.py +297 -0
  19. package/skills/dp-color/references/apca-contrast.md +87 -0
  20. package/skills/dp-color/references/hue-emotions.md +109 -0
  21. package/skills/dp-color/references/oklch-gamut.md +79 -0
  22. package/skills/dp-color/references/pitfalls.md +171 -0
  23. package/skills/dp-color/references/scale-patterns.md +206 -0
  24. package/skills/dp-color/references/tool-workflows.md +200 -0
  25. package/skills/dp-discovery/SKILL.md +480 -0
  26. package/skills/dp-eng_review/SKILL.md +471 -0
  27. package/skills/dp-eng_review/references/code-review-checklist.md +385 -0
  28. package/skills/dp-eng_review/references/react-patterns.md +512 -0
  29. package/skills/dp-eng_review/references/shadcn-patterns.md +510 -0
  30. package/skills/dp-eng_review/references/tailwind-conventions.md +351 -0
  31. package/skills/dp-journey/SKILL.md +682 -0
  32. package/skills/dp-journey/references/journey-types.md +97 -0
  33. package/skills/dp-journey/references/map-structures.md +177 -0
  34. package/skills/dp-journey/references/omnichannel-patterns.md +208 -0
  35. package/skills/dp-journey/references/research-methods.md +125 -0
  36. package/skills/dp-prd/SKILL.md +201 -0
  37. package/skills/dp-prd/references/claude-code-spec.md +107 -0
  38. package/skills/dp-prd/references/interview-questions.md +158 -0
  39. package/skills/dp-prd/references/section-templates.md +231 -0
  40. package/skills/dp-research/SKILL.md +540 -0
  41. package/skills/dp-research/references/facilitation-guide.md +291 -0
  42. package/skills/dp-research/references/interview-guide-template.md +190 -0
  43. package/skills/dp-research/references/method-selection.md +195 -0
  44. package/skills/dp-research/references/question-writing.md +244 -0
  45. package/skills/dp-research/references/research-report-template.md +363 -0
  46. package/skills/dp-research/references/synthesis-methods.md +289 -0
  47. package/skills/dp-research/references/usability-test-template.md +260 -0
  48. package/skills/dp-roadmap/SKILL.md +648 -0
  49. package/skills/dp-roadmap/references/prioritization-frameworks.md +312 -0
  50. package/skills/dp-roadmap/references/roadmap-structures.md +179 -0
  51. package/skills/dp-roadmap/references/roadmap-workshops.md +264 -0
  52. package/skills/dp-roadmap/references/theme-development.md +168 -0
  53. package/skills/dp-storytell/SKILL.md +645 -0
  54. package/skills/dp-storytell/references/audience-playbooks.md +260 -0
  55. package/skills/dp-storytell/references/content-type-templates.md +310 -0
  56. package/skills/dp-storytell/references/delivery-tactics.md +228 -0
  57. package/skills/dp-storytell/references/narrative-frameworks.md +259 -0
  58. package/skills/dp-ui/SKILL.md +503 -0
  59. package/skills/dp-ui/references/b2b-enterprise-patterns.md +319 -0
  60. package/skills/dp-ui/references/data-visualization.md +304 -0
  61. package/skills/dp-ui/references/visual-design-principles.md +237 -0
  62. package/skills/dp-ux/SKILL.md +414 -0
  63. package/skills/dp-ux/references/accessibility-checklist.md +128 -0
  64. package/skills/dp-ux/references/product-excellence.md +149 -0
  65. package/skills/dp-ux/references/usability-principles.md +140 -0
  66. package/skills/dp-ux/references/ux-patterns.md +221 -0
  67. package/templates/config.json +55 -0
  68. package/templates/context.md +96 -0
  69. package/templates/project.md +83 -0
  70. package/templates/requirements.md +137 -0
  71. package/templates/roadmap.md +168 -0
  72. package/templates/state.md +107 -0
@@ -0,0 +1,510 @@
1
+ # shadcn/ui Patterns
2
+
3
+ Correct usage patterns for shadcn/ui components in this project. Reference this when reviewing component implementations.
4
+
5
+ ---
6
+
7
+ ## Component Usage Philosophy
8
+
9
+ 1. **Use shadcn components over primitives** — Don't write `<button>` when `<Button>` exists
10
+ 2. **Leverage composition** — Most components are built to be composed
11
+ 3. **Don't override internals** — Style via className, don't recreate
12
+ 4. **Check the docs** — Each component has specific patterns
13
+
14
+ ---
15
+
16
+ ## Button Patterns
17
+
18
+ ### Basic Usage
19
+
20
+ ```tsx
21
+ import { Button } from "@/components/dp:ui/button"
22
+
23
+ // Variants
24
+ <Button>Default</Button>
25
+ <Button variant="secondary">Secondary</Button>
26
+ <Button variant="destructive">Delete</Button>
27
+ <Button variant="outline">Outline</Button>
28
+ <Button variant="ghost">Ghost</Button>
29
+ <Button variant="link">Link</Button>
30
+
31
+ // Sizes
32
+ <Button size="sm">Small</Button>
33
+ <Button size="default">Default</Button>
34
+ <Button size="lg">Large</Button>
35
+ <Button size="icon">
36
+ <Plus className="h-4 w-4" />
37
+ </Button>
38
+ ```
39
+
40
+ ### Button Loading State {#button-loading}
41
+
42
+ ```tsx
43
+ // REQUIRED PATTERN for async buttons
44
+ interface SubmitButtonProps {
45
+ isLoading: boolean
46
+ children: React.ReactNode
47
+ }
48
+
49
+ function SubmitButton({ isLoading, children }: SubmitButtonProps) {
50
+ return (
51
+ <Button disabled={isLoading}>
52
+ {isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
53
+ {children}
54
+ </Button>
55
+ )
56
+ }
57
+
58
+ // Usage
59
+ <Button disabled={isSubmitting} onClick={handleSubmit}>
60
+ {isSubmitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
61
+ {isSubmitting ? 'Saving...' : 'Save'}
62
+ </Button>
63
+ ```
64
+
65
+ ### Icon Buttons (Accessibility Required)
66
+
67
+ ```tsx
68
+ // ALWAYS add aria-label for icon-only buttons
69
+ <Button size="icon" aria-label="Close dialog">
70
+ <X className="h-4 w-4" />
71
+ </Button>
72
+
73
+ // Or use sr-only text
74
+ <Button size="icon">
75
+ <X className="h-4 w-4" />
76
+ <span className="sr-only">Close dialog</span>
77
+ </Button>
78
+
79
+ // With tooltip (preferred for discoverability)
80
+ <TooltipProvider>
81
+ <Tooltip>
82
+ <TooltipTrigger asChild>
83
+ <Button size="icon" aria-label="Delete item">
84
+ <Trash2 className="h-4 w-4" />
85
+ </Button>
86
+ </TooltipTrigger>
87
+ <TooltipContent>Delete item</TooltipContent>
88
+ </Tooltip>
89
+ </TooltipProvider>
90
+ ```
91
+
92
+ ### Button as Link
93
+
94
+ ```tsx
95
+ // Use asChild to render as different element
96
+ import Link from "next/link"
97
+
98
+ <Button asChild>
99
+ <Link href="/dashboard">Go to Dashboard</Link>
100
+ </Button>
101
+
102
+ // NOT this (wrong semantics)
103
+ <Button onClick={() => router.push('/dashboard')}>Go to Dashboard</Button>
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Form Patterns
109
+
110
+ ### Input with Label (Required)
111
+
112
+ ```tsx
113
+ import { Input } from "@/components/dp:ui/input"
114
+ import { Label } from "@/components/dp:ui/label"
115
+
116
+ // ALWAYS pair inputs with labels
117
+ <div className="space-y-2">
118
+ <Label htmlFor="email">Email</Label>
119
+ <Input id="email" type="email" placeholder="name@example.com" />
120
+ </div>
121
+ ```
122
+
123
+ ### Input with Error State
124
+
125
+ ```tsx
126
+ <div className="space-y-2">
127
+ <Label htmlFor="email" className={error ? 'text-destructive' : ''}>
128
+ Email
129
+ </Label>
130
+ <Input
131
+ id="email"
132
+ type="email"
133
+ aria-invalid={!!error}
134
+ aria-describedby={error ? 'email-error' : undefined}
135
+ className={error ? 'border-destructive' : ''}
136
+ />
137
+ {error && (
138
+ <p id="email-error" className="text-sm text-destructive">
139
+ {error}
140
+ </p>
141
+ )}
142
+ </div>
143
+ ```
144
+
145
+ ### Complete Form Field Pattern
146
+
147
+ ```tsx
148
+ interface FormFieldProps {
149
+ id: string
150
+ label: string
151
+ error?: string
152
+ hint?: string
153
+ required?: boolean
154
+ children: React.ReactNode
155
+ }
156
+
157
+ function FormField({ id, label, error, hint, required, children }: FormFieldProps) {
158
+ return (
159
+ <div className="space-y-2">
160
+ <Label htmlFor={id} className={error ? 'text-destructive' : ''}>
161
+ {label}
162
+ {required && <span className="text-destructive ml-1">*</span>}
163
+ </Label>
164
+ {children}
165
+ {error ? (
166
+ <p id={`${id}-error`} className="text-sm text-destructive">
167
+ {error}
168
+ </p>
169
+ ) : hint ? (
170
+ <p id={`${id}-hint`} className="text-sm text-muted-foreground">
171
+ {hint}
172
+ </p>
173
+ ) : null}
174
+ </div>
175
+ )
176
+ }
177
+ ```
178
+
179
+ ### Select Component
180
+
181
+ ```tsx
182
+ import {
183
+ Select,
184
+ SelectContent,
185
+ SelectItem,
186
+ SelectTrigger,
187
+ SelectValue,
188
+ } from "@/components/dp:ui/select"
189
+
190
+ <div className="space-y-2">
191
+ <Label htmlFor="status">Status</Label>
192
+ <Select value={status} onValueChange={setStatus}>
193
+ <SelectTrigger id="status">
194
+ <SelectValue placeholder="Select status" />
195
+ </SelectTrigger>
196
+ <SelectContent>
197
+ <SelectItem value="active">Active</SelectItem>
198
+ <SelectItem value="inactive">Inactive</SelectItem>
199
+ <SelectItem value="pending">Pending</SelectItem>
200
+ </SelectContent>
201
+ </Select>
202
+ </div>
203
+ ```
204
+
205
+ ---
206
+
207
+ ## Dialog Patterns
208
+
209
+ ### Basic Dialog
210
+
211
+ ```tsx
212
+ import {
213
+ Dialog,
214
+ DialogContent,
215
+ DialogDescription,
216
+ DialogFooter,
217
+ DialogHeader,
218
+ DialogTitle,
219
+ DialogTrigger,
220
+ } from "@/components/dp:ui/dialog"
221
+
222
+ <Dialog>
223
+ <DialogTrigger asChild>
224
+ <Button>Open Dialog</Button>
225
+ </DialogTrigger>
226
+ <DialogContent>
227
+ <DialogHeader>
228
+ {/* DialogTitle is REQUIRED for accessibility */}
229
+ <DialogTitle>Edit Profile</DialogTitle>
230
+ {/* DialogDescription is REQUIRED for accessibility */}
231
+ <DialogDescription>
232
+ Make changes to your profile here. Click save when done.
233
+ </DialogDescription>
234
+ </DialogHeader>
235
+ <div className="py-4">
236
+ {/* Content */}
237
+ </div>
238
+ <DialogFooter>
239
+ <Button type="submit">Save changes</Button>
240
+ </DialogFooter>
241
+ </DialogContent>
242
+ </Dialog>
243
+ ```
244
+
245
+ ### Controlled Dialog
246
+
247
+ ```tsx
248
+ function EditDialog({ open, onOpenChange }: DialogProps) {
249
+ return (
250
+ <Dialog open={open} onOpenChange={onOpenChange}>
251
+ <DialogContent>
252
+ <DialogHeader>
253
+ <DialogTitle>Edit Item</DialogTitle>
254
+ <DialogDescription>Make changes to the item.</DialogDescription>
255
+ </DialogHeader>
256
+ {/* Content */}
257
+ </DialogContent>
258
+ </Dialog>
259
+ )
260
+ }
261
+ ```
262
+
263
+ ### Alert Dialog (Destructive Actions)
264
+
265
+ ```tsx
266
+ import {
267
+ AlertDialog,
268
+ AlertDialogAction,
269
+ AlertDialogCancel,
270
+ AlertDialogContent,
271
+ AlertDialogDescription,
272
+ AlertDialogFooter,
273
+ AlertDialogHeader,
274
+ AlertDialogTitle,
275
+ AlertDialogTrigger,
276
+ } from "@/components/dp:ui/alert-dialog"
277
+
278
+ <AlertDialog>
279
+ <AlertDialogTrigger asChild>
280
+ <Button variant="destructive">Delete</Button>
281
+ </AlertDialogTrigger>
282
+ <AlertDialogContent>
283
+ <AlertDialogHeader>
284
+ <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
285
+ <AlertDialogDescription>
286
+ This action cannot be undone. This will permanently delete the item.
287
+ </AlertDialogDescription>
288
+ </AlertDialogHeader>
289
+ <AlertDialogFooter>
290
+ <AlertDialogCancel>Cancel</AlertDialogCancel>
291
+ <AlertDialogAction className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
292
+ Delete
293
+ </AlertDialogAction>
294
+ </AlertDialogFooter>
295
+ </AlertDialogContent>
296
+ </AlertDialog>
297
+ ```
298
+
299
+ ---
300
+
301
+ ## Table Patterns
302
+
303
+ ### Basic Table
304
+
305
+ ```tsx
306
+ import {
307
+ Table,
308
+ TableBody,
309
+ TableCell,
310
+ TableHead,
311
+ TableHeader,
312
+ TableRow,
313
+ } from "@/components/dp:ui/table"
314
+
315
+ <Table>
316
+ <TableHeader>
317
+ <TableRow>
318
+ <TableHead>Name</TableHead>
319
+ <TableHead>Status</TableHead>
320
+ <TableHead className="text-right">Actions</TableHead>
321
+ </TableRow>
322
+ </TableHeader>
323
+ <TableBody>
324
+ {items.map((item) => (
325
+ <TableRow key={item.id}>
326
+ <TableCell className="font-medium">{item.name}</TableCell>
327
+ <TableCell>
328
+ <Badge variant={item.active ? 'default' : 'secondary'}>
329
+ {item.active ? 'Active' : 'Inactive'}
330
+ </Badge>
331
+ </TableCell>
332
+ <TableCell className="text-right">
333
+ <Button variant="ghost" size="icon" aria-label={`Edit ${item.name}`}>
334
+ <Pencil className="h-4 w-4" />
335
+ </Button>
336
+ </TableCell>
337
+ </TableRow>
338
+ ))}
339
+ </TableBody>
340
+ </Table>
341
+ ```
342
+
343
+ ### Empty Table State
344
+
345
+ ```tsx
346
+ <Table>
347
+ <TableHeader>
348
+ <TableRow>
349
+ <TableHead>Name</TableHead>
350
+ <TableHead>Status</TableHead>
351
+ </TableRow>
352
+ </TableHeader>
353
+ <TableBody>
354
+ {items.length === 0 ? (
355
+ <TableRow>
356
+ <TableCell colSpan={2} className="h-24 text-center">
357
+ <div className="flex flex-col items-center justify-center">
358
+ <Package className="h-8 w-8 text-muted-foreground mb-2" />
359
+ <p className="text-muted-foreground">No items found</p>
360
+ </div>
361
+ </TableCell>
362
+ </TableRow>
363
+ ) : (
364
+ items.map((item) => (
365
+ <TableRow key={item.id}>
366
+ {/* ... */}
367
+ </TableRow>
368
+ ))
369
+ )}
370
+ </TableBody>
371
+ </Table>
372
+ ```
373
+
374
+ ---
375
+
376
+ ## Card Patterns
377
+
378
+ ### Basic Card
379
+
380
+ ```tsx
381
+ import {
382
+ Card,
383
+ CardContent,
384
+ CardDescription,
385
+ CardFooter,
386
+ CardHeader,
387
+ CardTitle,
388
+ } from "@/components/dp:ui/card"
389
+
390
+ <Card>
391
+ <CardHeader>
392
+ <CardTitle>Card Title</CardTitle>
393
+ <CardDescription>Card description goes here.</CardDescription>
394
+ </CardHeader>
395
+ <CardContent>
396
+ <p>Card content</p>
397
+ </CardContent>
398
+ <CardFooter>
399
+ <Button>Action</Button>
400
+ </CardFooter>
401
+ </Card>
402
+ ```
403
+
404
+ ### Clickable Card
405
+
406
+ ```tsx
407
+ // Use proper semantic when card is clickable
408
+ <Card
409
+ className="cursor-pointer hover:bg-accent transition-colors"
410
+ role="button"
411
+ tabIndex={0}
412
+ onClick={handleClick}
413
+ onKeyDown={(e) => e.key === 'Enter' && handleClick()}
414
+ >
415
+ {/* Content */}
416
+ </Card>
417
+
418
+ // Better: Use Link for navigation
419
+ <Link href={`/items/${item.id}`} className="block">
420
+ <Card className="hover:bg-accent transition-colors">
421
+ {/* Content */}
422
+ </Card>
423
+ </Link>
424
+ ```
425
+
426
+ ---
427
+
428
+ ## Toast Patterns
429
+
430
+ ```tsx
431
+ import { toast } from "sonner"
432
+
433
+ // Success
434
+ toast.success("Item created successfully")
435
+
436
+ // Error
437
+ toast.error("Failed to create item")
438
+
439
+ // With description
440
+ toast.success("Item created", {
441
+ description: "Your item has been added to the list."
442
+ })
443
+
444
+ // With action
445
+ toast.error("Failed to save", {
446
+ action: {
447
+ label: "Retry",
448
+ onClick: () => handleRetry(),
449
+ },
450
+ })
451
+
452
+ // Promise-based
453
+ toast.promise(saveItem(), {
454
+ loading: 'Saving...',
455
+ success: 'Item saved!',
456
+ error: 'Failed to save item',
457
+ })
458
+ ```
459
+
460
+ ---
461
+
462
+ ## Common Anti-Patterns
463
+
464
+ ### Don't Recreate Components
465
+
466
+ ```tsx
467
+ // BAD: Custom button
468
+ <button className="bg-primary text-primary-foreground hover:bg-primary/90 rounded-md px-4 py-2">
469
+ Click me
470
+ </button>
471
+
472
+ // GOOD: Use the component
473
+ <Button>Click me</Button>
474
+ ```
475
+
476
+ ### Don't Skip Accessibility
477
+
478
+ ```tsx
479
+ // BAD: Missing required parts
480
+ <Dialog>
481
+ <DialogContent>
482
+ <h2>Title</h2> {/* Wrong! Use DialogTitle */}
483
+ Content here
484
+ </DialogContent>
485
+ </Dialog>
486
+
487
+ // GOOD: Proper structure
488
+ <Dialog>
489
+ <DialogContent>
490
+ <DialogHeader>
491
+ <DialogTitle>Title</DialogTitle>
492
+ <DialogDescription>Description</DialogDescription>
493
+ </DialogHeader>
494
+ Content here
495
+ </DialogContent>
496
+ </Dialog>
497
+ ```
498
+
499
+ ### Don't Fight the Styling System
500
+
501
+ ```tsx
502
+ // BAD: Inline styles overriding design system
503
+ <Button style={{ backgroundColor: '#ff0000' }}>Delete</Button>
504
+
505
+ // GOOD: Use variants
506
+ <Button variant="destructive">Delete</Button>
507
+
508
+ // GOOD: If custom color needed, use className
509
+ <Button className="bg-orange-500 hover:bg-orange-600">Custom</Button>
510
+ ```