@polymorphism-tech/morph-spec 4.10.7 → 4.10.9

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 (123) hide show
  1. package/CLAUDE.md +3 -3
  2. package/LICENSE +71 -71
  3. package/README.md +379 -379
  4. package/bin/morph-spec.js +1 -1
  5. package/claude-plugin.json +14 -14
  6. package/docs/CHEATSHEET.md +1 -1
  7. package/docs/QUICKSTART.md +206 -206
  8. package/framework/agents/README.md +14 -14
  9. package/framework/agents/architecture/standards-architect.md +159 -159
  10. package/framework/agents/frontend/blazor-builder.md +13 -0
  11. package/framework/agents/frontend/css-specialist.md +87 -0
  12. package/framework/agents/frontend/nextjs-expert.md +13 -0
  13. package/framework/agents/frontend/nextjs-ui-specialist.md +218 -0
  14. package/framework/agents/frontend/ui-ux-designer.md +80 -10
  15. package/framework/agents/infrastructure/azure-architect.md +149 -149
  16. package/framework/agents/infrastructure/infra-architect.md +48 -48
  17. package/framework/agents.json +2268 -2204
  18. package/framework/hooks/README.md +204 -204
  19. package/framework/hooks/claude-code/session-start/inject-morph-context.js +10 -24
  20. package/framework/hooks/shared/phase-utils.js +139 -139
  21. package/framework/hooks/shared/worktree-helpers.js +30 -8
  22. package/framework/rules/csharp-standards.md +13 -13
  23. package/framework/rules/frontend-standards.md +13 -13
  24. package/framework/rules/infrastructure-standards.md +16 -16
  25. package/framework/rules/testing-standards.md +14 -14
  26. package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +12 -0
  27. package/framework/skills/level-0-meta/morph-code-review-nextjs/references/review-example-nextjs.md +254 -254
  28. package/framework/skills/level-0-meta/morph-init/SKILL.md +136 -3
  29. package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +247 -247
  30. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +270 -270
  31. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +515 -499
  32. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +508 -500
  33. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +12 -1
  34. package/framework/skills/level-1-workflows/morph-phase-setup/SKILL.md +272 -262
  35. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +317 -311
  36. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +457 -323
  37. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +1 -1
  38. package/framework/standards/STANDARDS.json +2040 -2040
  39. package/framework/standards/frontend/nextjs/motion-patterns.md +321 -0
  40. package/framework/standards/frontend/nextjs/nextjs-patterns.md +17 -17
  41. package/framework/templates/README.md +814 -814
  42. package/framework/templates/code/dotnet/contracts/Commands.cs +74 -74
  43. package/framework/templates/code/dotnet/contracts/Entities.cs +25 -25
  44. package/framework/templates/code/dotnet/contracts/Queries.cs +74 -74
  45. package/framework/templates/code/dotnet/contracts/README.md +74 -74
  46. package/framework/templates/code/dotnet/contracts/api-contracts.cs +173 -173
  47. package/framework/templates/code/dotnet/frontend/component.razor +239 -239
  48. package/framework/templates/code/dotnet/jobs/agent.cs +163 -163
  49. package/framework/templates/code/dotnet/jobs/job.cs +171 -171
  50. package/framework/templates/code/dotnet/test.cs +239 -239
  51. package/framework/templates/code/sql/rls-policy.sql +57 -57
  52. package/framework/templates/code/sql/supabase-migration.sql +100 -100
  53. package/framework/templates/code/sql/supabase-migration.template.sql +113 -113
  54. package/framework/templates/code/typescript/contracts.ts +168 -168
  55. package/framework/templates/context/CONTEXT.md +181 -181
  56. package/framework/templates/context/design-system.md +211 -0
  57. package/framework/templates/docs/proposal.md +182 -182
  58. package/framework/templates/docs/user-stories.md +34 -34
  59. package/framework/templates/examples/design-system-examples.md +357 -357
  60. package/framework/templates/examples/spec-examples.md +90 -90
  61. package/framework/templates/feature/decisions.md +187 -187
  62. package/framework/templates/feature/recap.md +146 -146
  63. package/framework/templates/feature/tasks.md +199 -199
  64. package/framework/templates/infrastructure/azure/README.md +286 -286
  65. package/framework/templates/infrastructure/azure/deploy-checklist.md +426 -426
  66. package/framework/templates/infrastructure/azure/parameters.dev.json +29 -29
  67. package/framework/templates/infrastructure/azure/parameters.prod.json +29 -29
  68. package/framework/templates/infrastructure/azure/parameters.staging.json +29 -29
  69. package/framework/templates/infrastructure/docker/docker-compose.template.yml +67 -67
  70. package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
  71. package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
  72. package/framework/templates/infrastructure/docker/easypanel.template.json +54 -54
  73. package/package.json +82 -82
  74. package/src/commands/agents/index.js +13 -13
  75. package/src/commands/project/install-plugin-cmd.js +28 -28
  76. package/src/commands/project/setup-infra-cmd.js +12 -12
  77. package/src/commands/project/worktree.js +58 -2
  78. package/src/commands/tasks/index.js +4 -4
  79. package/src/commands/templates/index.js +5 -5
  80. package/src/commands/utils/index.js +3 -3
  81. package/src/commands/validation/index.js +4 -4
  82. package/src/core/state/phase-state-machine.js +217 -217
  83. package/src/lib/detectors/design-system-detector.js +73 -31
  84. package/src/lib/generators/design-system-generator.js +298 -298
  85. package/src/lib/generators/index.js +10 -10
  86. package/src/lib/generators/metadata-extractor.js +387 -387
  87. package/src/lib/stack-filter.js +65 -65
  88. package/src/lib/standards/index.js +7 -7
  89. package/src/lib/standards/standards-context-injector.js +302 -302
  90. package/src/lib/validators/architecture/architecture-validator.js +387 -387
  91. package/src/lib/validators/architecture/index.js +7 -7
  92. package/src/lib/validators/blazor/blazor-concurrency-analyzer.js +316 -316
  93. package/src/lib/validators/blazor/blazor-state-validator.js +279 -279
  94. package/src/lib/validators/blazor/blazor-validator.js +369 -369
  95. package/src/lib/validators/blazor/index.js +9 -9
  96. package/src/lib/validators/content/content-validator.js +287 -287
  97. package/src/lib/validators/content/index.js +7 -7
  98. package/src/lib/validators/contracts/index.js +7 -7
  99. package/src/lib/validators/css/css-validator.js +352 -352
  100. package/src/lib/validators/css/index.js +7 -7
  101. package/src/lib/validators/design-system/design-system-validator.js +231 -231
  102. package/src/lib/validators/design-system/index.js +7 -7
  103. package/src/lib/validators/nextjs/index.js +6 -6
  104. package/src/lib/validators/nextjs/next-component-validator.js +183 -183
  105. package/src/lib/validators/packages/index.js +7 -7
  106. package/src/lib/validators/packages/package-validator.js +360 -360
  107. package/src/lib/validators/shared/index.js +12 -12
  108. package/src/lib/validators/shared/issue-counter.js +18 -18
  109. package/src/lib/validators/shared/result-formatter.js +124 -124
  110. package/src/lib/validators/ui/index.js +7 -7
  111. package/src/lib/validators/ui/ui-contrast-validator.js +422 -422
  112. package/src/scripts/global-install.js +58 -58
  113. package/src/scripts/install-plugin.js +126 -126
  114. package/src/utils/claude-md-injector.js +90 -90
  115. package/src/utils/file-copier.js +200 -196
  116. package/src/utils/hooks-installer.js +556 -494
  117. package/src/utils/logger.js +32 -32
  118. package/src/utils/skills-installer.js +178 -178
  119. package/src/utils/version-checker.js +175 -175
  120. package/framework/skills/level-1-workflows/morph-phase-implement/.morph/logs/activity.json +0 -38
  121. package/framework/skills/level-1-workflows/morph-phase-tasks/.morph/logs/activity.json +0 -14
  122. package/framework/templates/.idea/morph-templates.xml +0 -92
  123. package/framework/templates/.vscode/morph-templates.code-snippets +0 -186
@@ -0,0 +1,321 @@
1
+ ---
2
+ scope: frontend-nextjs-ui
3
+ layer: 3
4
+ keywords: framer-motion, animation, motion, transition, variants, gesture, scroll
5
+ load_when: nextjs-ui-specialist active
6
+ ---
7
+
8
+ # Motion Patterns — Framer Motion
9
+
10
+ Reference guide for implementing animations and transitions in Next.js projects using Framer Motion. Covers the canonical variants library, design token bridge, scroll and gesture patterns, loading states, and mandatory WCAG accessibility compliance.
11
+
12
+ ---
13
+
14
+ ## Section 1: Core Variants Library
15
+
16
+ Place this file at `motion/variants.ts` in your Next.js project root.
17
+
18
+ ```typescript
19
+ import { Variants } from 'framer-motion';
20
+ import { durations, easings } from '@/lib/design-tokens'; // maps to design-system.md motion tokens
21
+
22
+ // Fade
23
+ export const fadeIn: Variants = {
24
+ hidden: { opacity: 0 },
25
+ visible: { opacity: 1, transition: { duration: durations.base, ease: easings.standard } },
26
+ };
27
+
28
+ // Slide variations
29
+ export const slideInUp: Variants = {
30
+ hidden: { opacity: 0, y: 24 },
31
+ visible: { opacity: 1, y: 0, transition: { duration: durations.base, ease: easings.decelerate } },
32
+ };
33
+ export const slideInDown: Variants = {
34
+ hidden: { opacity: 0, y: -24 },
35
+ visible: { opacity: 1, y: 0, transition: { duration: durations.base, ease: easings.decelerate } },
36
+ };
37
+ export const slideInLeft: Variants = {
38
+ hidden: { opacity: 0, x: -24 },
39
+ visible: { opacity: 1, x: 0, transition: { duration: durations.base, ease: easings.decelerate } },
40
+ };
41
+ export const slideInRight: Variants = {
42
+ hidden: { opacity: 0, x: 24 },
43
+ visible: { opacity: 1, x: 0, transition: { duration: durations.base, ease: easings.decelerate } },
44
+ };
45
+
46
+ // Scale
47
+ export const scaleIn: Variants = {
48
+ hidden: { opacity: 0, scale: 0.92 },
49
+ visible: { opacity: 1, scale: 1, transition: { duration: durations.fast, ease: easings.bounce } },
50
+ };
51
+
52
+ // Stagger container + child
53
+ export const staggerContainer: Variants = {
54
+ hidden: {},
55
+ visible: {
56
+ transition: {
57
+ staggerChildren: 0.08,
58
+ delayChildren: 0.1,
59
+ },
60
+ },
61
+ };
62
+ export const staggerItem: Variants = {
63
+ hidden: { opacity: 0, y: 16 },
64
+ visible: { opacity: 1, y: 0, transition: { duration: durations.base, ease: easings.decelerate } },
65
+ };
66
+
67
+ // Page transition (for AnimatePresence in layout.tsx)
68
+ export const pageTransition: Variants = {
69
+ hidden: { opacity: 0, y: 8 },
70
+ visible: { opacity: 1, y: 0, transition: { duration: durations.base, ease: easings.decelerate } },
71
+ exit: { opacity: 0, y: -8, transition: { duration: durations.fast, ease: easings.accelerate } },
72
+ };
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Section 2: Design Token Bridge
78
+
79
+ This file bridges the CSS variables defined in `.morph/context/design-system.md` to JavaScript values consumed by Framer Motion. Place at `lib/design-tokens.ts`.
80
+
81
+ ```typescript
82
+ // lib/design-tokens.ts
83
+ // Maps CSS variables from .morph/context/design-system.md to JS values for Framer Motion
84
+ export const durations = {
85
+ instant: 0.05,
86
+ fast: 0.15,
87
+ base: 0.3,
88
+ slow: 0.5,
89
+ slower: 0.8,
90
+ } as const;
91
+
92
+ export const easings = {
93
+ standard: [0.4, 0, 0.2, 1] as [number, number, number, number],
94
+ decelerate: [0, 0, 0.2, 1] as [number, number, number, number],
95
+ accelerate: [0.4, 0, 1, 1] as [number, number, number, number],
96
+ bounce: [0.34, 1.56, 0.64, 1] as [number, number, number, number],
97
+ spring: [0.68, -0.55, 0.265, 1.55] as [number, number, number, number],
98
+ };
99
+ ```
100
+
101
+ > **Rule**: Never hardcode duration numbers or easing arrays in component files. Always import from `@/lib/design-tokens`.
102
+
103
+ ---
104
+
105
+ ## Section 3: Scroll Animations
106
+
107
+ Two approaches for triggering animations when elements enter the viewport:
108
+
109
+ ```tsx
110
+ 'use client';
111
+ import { motion, useInView } from 'framer-motion';
112
+ import { useRef } from 'react';
113
+ import { fadeIn, slideInUp } from '@/motion/variants';
114
+
115
+ // Option A: whileInView (simpler, one-shot)
116
+ <motion.div
117
+ variants={slideInUp}
118
+ initial="hidden"
119
+ whileInView="visible"
120
+ viewport={{ once: true, margin: '-50px' }}
121
+ >
122
+
123
+ // Option B: useInView hook (more control)
124
+ function AnimatedSection({ children }: { children: React.ReactNode }) {
125
+ const ref = useRef(null);
126
+ const isInView = useInView(ref, { once: true, margin: '-100px' });
127
+ return (
128
+ <motion.div ref={ref} variants={fadeIn} initial="hidden" animate={isInView ? 'visible' : 'hidden'}>
129
+ {children}
130
+ </motion.div>
131
+ );
132
+ }
133
+ ```
134
+
135
+ - Use `once: true` for content sections — animations should not replay on scroll up.
136
+ - Adjust `margin` to fire slightly before the element fully enters the viewport.
137
+ - Prefer `whileInView` for simple cases; use `useInView` when you need imperative control or conditional logic.
138
+
139
+ ---
140
+
141
+ ## Section 4: Gesture Interactions
142
+
143
+ ```tsx
144
+ import { durations, easings } from '@/lib/design-tokens';
145
+
146
+ // Hover + tap on cards
147
+ <motion.div
148
+ whileHover={{ y: -4, boxShadow: 'var(--shadow-lift)' }}
149
+ whileTap={{ scale: 0.98 }}
150
+ transition={{ duration: durations.fast, ease: easings.standard }}
151
+ >
152
+
153
+ // Drag interaction
154
+ <motion.div
155
+ drag
156
+ dragConstraints={{ left: 0, right: 0, top: 0, bottom: 0 }}
157
+ dragElastic={0.1}
158
+ whileDrag={{ scale: 1.05, cursor: 'grabbing' }}
159
+ >
160
+ ```
161
+
162
+ - `whileHover` and `whileTap` are inline — they do not need variant definitions for simple state changes.
163
+ - Use `var(--shadow-lift)` from the design system rather than hardcoded box-shadow values.
164
+ - `dragElastic={0.1}` gives a subtle rubber-band feel without being distracting.
165
+
166
+ ---
167
+
168
+ ## Section 5: AnimatePresence (Page Transitions)
169
+
170
+ Integrate `AnimatePresence` at the layout level to animate between routes:
171
+
172
+ ```tsx
173
+ // app/layout.tsx
174
+ 'use client';
175
+ import { AnimatePresence, motion } from 'framer-motion';
176
+ import { usePathname } from 'next/navigation';
177
+ import { pageTransition } from '@/motion/variants';
178
+
179
+ export default function Layout({ children }: { children: React.ReactNode }) {
180
+ const pathname = usePathname();
181
+
182
+ return (
183
+ <html>
184
+ <body>
185
+ <AnimatePresence mode="wait">
186
+ <motion.main
187
+ key={pathname}
188
+ variants={pageTransition}
189
+ initial="hidden"
190
+ animate="visible"
191
+ exit="exit"
192
+ >
193
+ {children}
194
+ </motion.main>
195
+ </AnimatePresence>
196
+ </body>
197
+ </html>
198
+ );
199
+ }
200
+ ```
201
+
202
+ - `mode="wait"` ensures the exit animation completes before the entering page renders.
203
+ - The `key` prop must change on navigation — use `usePathname()` from `next/navigation`.
204
+ - Keep page transitions subtle (`y: 8`, fast duration) — aggressive transitions hurt perceived performance.
205
+
206
+ ---
207
+
208
+ ## Section 6: Loading Patterns
209
+
210
+ Prefer CSS `animate-pulse` for skeleton loaders over Framer Motion — CSS animations run off the main thread and have lower performance overhead.
211
+
212
+ ```tsx
213
+ // components/skeleton.tsx
214
+ import { cn } from '@/lib/utils';
215
+
216
+ function Skeleton({ className }: { className?: string }) {
217
+ return (
218
+ <div
219
+ className={cn(
220
+ 'animate-pulse rounded-[var(--radius-md)] bg-[var(--color-neutral-200)]',
221
+ className
222
+ )}
223
+ />
224
+ );
225
+ }
226
+
227
+ // Skeleton card example
228
+ function SkeletonCard() {
229
+ return (
230
+ <div className="p-[var(--space-6)] space-y-[var(--space-4)]">
231
+ <Skeleton className="h-4 w-3/4" />
232
+ <Skeleton className="h-4 w-1/2" />
233
+ <Skeleton className="h-20 w-full" />
234
+ </div>
235
+ );
236
+ }
237
+ ```
238
+
239
+ - Use design token CSS variables (`--radius-md`, `--color-neutral-200`, `--space-*`) — never hardcode dimensions or colors.
240
+ - Skeleton shapes should mirror the actual content layout to minimize layout shift on load.
241
+ - For spinner/progress indicators that need JS control, use a simple Framer Motion `animate={{ rotate: 360 }}` with `repeat: Infinity`.
242
+
243
+ ---
244
+
245
+ ## Section 7: WCAG Accessibility (MANDATORY)
246
+
247
+ > **This section is non-negotiable.** All animated components must respect `prefers-reduced-motion`.
248
+
249
+ ### Hook pattern — wrap all animated components
250
+
251
+ ```tsx
252
+ 'use client';
253
+ import { motion, useReducedMotion } from 'framer-motion';
254
+ import { slideInUp } from '@/motion/variants';
255
+
256
+ function AnimatedCard({ children }: { children: React.ReactNode }) {
257
+ const shouldReduceMotion = useReducedMotion();
258
+
259
+ const variants = shouldReduceMotion
260
+ ? { hidden: { opacity: 0 }, visible: { opacity: 1 } } // instant, no movement
261
+ : slideInUp;
262
+
263
+ return (
264
+ <motion.div variants={variants} initial="hidden" animate="visible">
265
+ {children}
266
+ </motion.div>
267
+ );
268
+ }
269
+ ```
270
+
271
+ When `shouldReduceMotion` is `true`:
272
+ - Remove all `x`, `y`, `scale` transforms.
273
+ - Keep opacity transitions (they do not cause vestibular issues).
274
+ - Do not set `transition: { duration: 0 }` — a very short fade is acceptable and less jarring than an instant pop-in.
275
+
276
+ ### CSS fallback (add to global stylesheet)
277
+
278
+ ```css
279
+ @media (prefers-reduced-motion: reduce) {
280
+ *, *::before, *::after {
281
+ animation-duration: 0.01ms !important;
282
+ transition-duration: 0.01ms !important;
283
+ }
284
+ }
285
+ ```
286
+
287
+ This CSS fallback catches animations outside Framer Motion (Tailwind `animate-*`, third-party components, CSS keyframes).
288
+
289
+ ---
290
+
291
+ ## Section 8: Anti-patterns
292
+
293
+ | Anti-pattern | Correct approach |
294
+ |---|---|
295
+ | `duration: 0.8` for UI interactions | `duration: durations.fast` (0.15) for micro-interactions |
296
+ | Hardcoded easing `[0.4, 0, 0.2, 1]` | `ease: easings.standard` (from design-tokens) |
297
+ | No `useReducedMotion()` check | Always check or use CSS media query |
298
+ | Animating everything on the page | Reserve motion for 3-5 meaningful moments per page |
299
+ | Forgetting `animation-fill-mode: backwards` in stagger | Will cause a flash before the animation starts |
300
+ | `AnimatePresence` without `key` changes | Exit animations will never fire |
301
+ | Using `framer-motion` for skeleton loaders | Use CSS `animate-pulse` — lower performance cost |
302
+
303
+ ---
304
+
305
+ ## Section 9: Installation
306
+
307
+ ```bash
308
+ npm install framer-motion
309
+ ```
310
+
311
+ > If using **shadcn/ui**, framer-motion is already included as a dependency — no additional install needed.
312
+
313
+ Verify the installed version supports the features used here (requires framer-motion >= 10):
314
+
315
+ ```bash
316
+ npm list framer-motion
317
+ ```
318
+
319
+ ---
320
+
321
+ *MORPH-SPEC by Polymorphism Tech*
@@ -196,20 +196,20 @@ Components are copied to `components/ui/` -- NOT an npm dependency, your code to
196
196
  | `useEffect` for data fetching | React Query `useQuery` | No caching, race conditions |
197
197
  | Form validation on submit only | Zod resolver + react-hook-form | Delayed error feedback |
198
198
  | shadcn as npm package | `npx shadcn@latest add` | Copy-paste system, not a dependency |
199
-
200
- ## TypeScript Strict Mode (Required)
201
-
202
- Always enable `"strict": true` in `tsconfig.json`. This is non-negotiable for
203
- agent-assisted development because agents rely on compiler errors to self-correct.
204
- Without strict mode, type/null errors only surface at runtime where agents cannot observe them.
205
-
206
- ```json
207
- {
208
- "compilerOptions": {
209
- "strict": true,
210
- "noUncheckedIndexedAccess": true
211
- }
212
- }
213
- ```
214
-
215
- Strict mode enables: `strictNullChecks`, `noImplicitAny`, `strictFunctionTypes`, `strictPropertyInitialization`.
199
+
200
+ ## TypeScript Strict Mode (Required)
201
+
202
+ Always enable `"strict": true` in `tsconfig.json`. This is non-negotiable for
203
+ agent-assisted development because agents rely on compiler errors to self-correct.
204
+ Without strict mode, type/null errors only surface at runtime where agents cannot observe them.
205
+
206
+ ```json
207
+ {
208
+ "compilerOptions": {
209
+ "strict": true,
210
+ "noUncheckedIndexedAccess": true
211
+ }
212
+ }
213
+ ```
214
+
215
+ Strict mode enables: `strictNullChecks`, `noImplicitAny`, `strictFunctionTypes`, `strictPropertyInitialization`.