@hegemonart/get-design-done 1.52.0 → 1.54.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 (60) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +90 -0
  4. package/README.md +4 -0
  5. package/SKILL.md +2 -1
  6. package/agents/component-taxonomy-mapper.md +3 -0
  7. package/agents/design-context-reviewer-gate.md +102 -0
  8. package/agents/design-context-reviewer.md +186 -0
  9. package/agents/motion-mapper.md +1 -0
  10. package/agents/token-mapper.md +3 -0
  11. package/dist/claude-code/.claude/skills/discover/SKILL.md +7 -1
  12. package/dist/claude-code/.claude/skills/explore/SKILL.md +3 -1
  13. package/dist/claude-code/.claude/skills/new-addendum/SKILL.md +81 -0
  14. package/package.json +1 -1
  15. package/reference/frameworks/astro.md +43 -0
  16. package/reference/frameworks/nextjs.md +44 -0
  17. package/reference/frameworks/remix.md +44 -0
  18. package/reference/frameworks/storybook.md +44 -0
  19. package/reference/frameworks/sveltekit.md +43 -0
  20. package/reference/frameworks/vite-react.md +43 -0
  21. package/reference/interaction.md +1 -0
  22. package/reference/motion/framer-motion.md +45 -0
  23. package/reference/motion/gsap.md +45 -0
  24. package/reference/motion/motion-one.md +44 -0
  25. package/reference/motion/react-spring.md +44 -0
  26. package/reference/motion.md +1 -0
  27. package/reference/registry.json +163 -1
  28. package/reference/registry.schema.json +18 -1
  29. package/reference/skill-graph.md +2 -1
  30. package/reference/systems/chakra.md +44 -0
  31. package/reference/systems/css-modules.md +44 -0
  32. package/reference/systems/mui.md +44 -0
  33. package/reference/systems/radix-themes.md +43 -0
  34. package/reference/systems/shadcn.md +45 -0
  35. package/reference/systems/styled-components.md +44 -0
  36. package/reference/systems/tailwind.md +44 -0
  37. package/reference/systems/vanilla-extract.md +44 -0
  38. package/scripts/lib/detect/stack.cjs +455 -0
  39. package/scripts/lib/detect/stack.d.cts +44 -0
  40. package/scripts/lib/explore-parallel-runner/index.ts +196 -1
  41. package/scripts/lib/explore-parallel-runner/types.ts +85 -0
  42. package/scripts/lib/health-mirror/index.cjs +73 -1
  43. package/scripts/lib/manifest/skills.json +10 -2
  44. package/scripts/lib/mapper-spawn.cjs +257 -0
  45. package/scripts/lib/mapper-spawn.d.cts +60 -0
  46. package/scripts/lib/mappers/compute-batches.mjs +625 -0
  47. package/scripts/lib/mappers/graph-adjacency.mjs +129 -0
  48. package/scripts/lib/mappers/incremental-discover.cjs +617 -0
  49. package/scripts/lib/mappers/incremental-discover.d.cts +133 -0
  50. package/scripts/lib/mappers/neighbor-map.mjs +0 -0
  51. package/scripts/lib/new-addendum.cjs +204 -0
  52. package/sdk/cli/index.js +1504 -3
  53. package/sdk/fingerprint/classify.cjs +406 -0
  54. package/sdk/fingerprint/index.ts +405 -0
  55. package/sdk/fingerprint/store.cjs +523 -0
  56. package/sdk/index.ts +1 -0
  57. package/sdk/mcp/gdd-mcp/server.js +1047 -0
  58. package/skills/discover/SKILL.md +7 -1
  59. package/skills/explore/SKILL.md +3 -1
  60. package/skills/new-addendum/SKILL.md +81 -0
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: astro
3
+ kind: framework
4
+ composes_into: [component-taxonomy-mapper, visual-hierarchy-mapper]
5
+ phase: 54
6
+ ---
7
+ <!-- Vendor docs: https://docs.astro.build. -->
8
+
9
+ # Astro
10
+
11
+ ## Conventions
12
+
13
+ - An `.astro` file is a script fence (the `---` code fence runs at build or on the server) plus an HTML template; props arrive via `Astro.props`.
14
+ - File routing lives in `src/pages/` (`.astro` and `.md`). Framework components are static by default; `client:load`, `client:idle`, `client:visible`, and `client:only` directives mark hydration, which is the interactivity signal.
15
+ - `<style>` is scoped by default; `is:global` or `:global()` escapes the scope. Content collections are typed Markdown or MDX in `src/content/`, configured by `content.config.ts` with Zod.
16
+
17
+ ## File patterns
18
+
19
+ - `src/pages/**/*.astro`, `src/layouts/*.astro`, `src/components/*.astro`, `content.config.ts`, `astro.config.mjs`.
20
+ - Identify via: astro in deps plus a `src/pages/` directory.
21
+
22
+ ## Gotchas
23
+
24
+ - Most `.astro` files ship zero js; only `client:*`-directed islands are interactive, so motion attaches only to hydrated islands.
25
+ - Scoped `<style>` rewrites class names locally; treat those names as component-local, not global tokens.
26
+ - `src/pages/*.astro` files are screens; layouts wrap them via a `<slot/>` (emit a composes edge).
27
+ - Global tokens enter via an `is:global` block or a stylesheet imported in a layout.
28
+
29
+ ## Example output
30
+
31
+ ```json
32
+ {
33
+ "schema_version": "52.0",
34
+ "nodes": [
35
+ { "id": "scr.index", "type": "screen", "name": "/", "summary": "Home page from src/pages/index.astro.", "complexity": "simple", "tags": ["navigation"] },
36
+ { "id": "lay.base", "type": "layer", "subtype": "Template", "name": "BaseLayout", "summary": "Layout wrapping pages via slot, holds global styles.", "complexity": "moderate", "tags": ["template", "layout"] },
37
+ { "id": "cmp.counter", "type": "component", "name": "Counter", "summary": "Hydrated island marked client:visible, interactive.", "complexity": "moderate", "tags": ["interactive"] }
38
+ ],
39
+ "edges": [
40
+ { "source": "lay.base", "target": "scr.index", "type": "composes", "direction": "forward", "weight": 0.9 }
41
+ ]
42
+ }
43
+ ```
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: nextjs
3
+ kind: framework
4
+ composes_into: [component-taxonomy-mapper, visual-hierarchy-mapper]
5
+ phase: 54
6
+ ---
7
+ <!-- Vendor docs: https://nextjs.org/docs/app. -->
8
+
9
+ # Next.js
10
+
11
+ ## Conventions
12
+
13
+ - Two routers. App Router (`app/`): folder names are URL segments; `page.tsx` is the routable surface (a screen node). `layout.tsx` wraps and nests its segment; the root layout owns `<html>`/`<body>` and imports `globals.css`.
14
+ - Special files: `loading`, `error`, `template`, `route`. Server Components are the default; `'use client'` marks the client boundary, and only client components are interactive.
15
+ - Pages Router (legacy `pages/`): one file is one route; `_app`/`_document` are shells; data via `getServerSideProps`/`getStaticProps`.
16
+
17
+ ## File patterns
18
+
19
+ - App Router: `app/**/page.tsx`, `app/**/layout.tsx`, `app/globals.css`.
20
+ - Pages Router: `pages/**`, `pages/_app.tsx`, `pages/_document.tsx`.
21
+ - Identify via: next in deps plus an `app/` or `pages/` directory.
22
+
23
+ ## Gotchas
24
+
25
+ - Screen nodes are `page.tsx` files; set the node path to the route, not the file path.
26
+ - A `layout.tsx` plus `page.tsx` in one folder is one screen and its layout; emit a composes edge layout to page.
27
+ - Without `'use client'`, a component is not a motion or hover candidate; the boundary gates interactivity.
28
+ - Global tokens enter at the root-layout `globals.css`.
29
+
30
+ ## Example output
31
+
32
+ ```json
33
+ {
34
+ "schema_version": "52.0",
35
+ "nodes": [
36
+ { "id": "scr.dashboard", "type": "screen", "name": "/dashboard", "summary": "Routable dashboard page from app/dashboard/page.tsx.", "complexity": "moderate", "tags": ["navigation", "layout"] },
37
+ { "id": "lay.root", "type": "layer", "subtype": "Template", "name": "RootLayout", "summary": "Root layout owning html and body, imports global tokens.", "complexity": "moderate", "tags": ["template", "layout"] },
38
+ { "id": "cmp.chart", "type": "component", "name": "Chart", "summary": "Client component marked use client, interactive.", "complexity": "complex", "tags": ["interactive", "data-display"] }
39
+ ],
40
+ "edges": [
41
+ { "source": "lay.root", "target": "scr.dashboard", "type": "composes", "direction": "forward", "weight": 0.9 }
42
+ ]
43
+ }
44
+ ```
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: remix
3
+ kind: framework
4
+ composes_into: [component-taxonomy-mapper, visual-hierarchy-mapper]
5
+ phase: 54
6
+ ---
7
+ <!-- Vendor docs: https://remix.run/docs/en/main/file-conventions/routes (Remix v2 / React Router v7 framework mode). -->
8
+
9
+ # Remix
10
+
11
+ ## Conventions
12
+
13
+ - `app/routes/` uses file conventions; `app/root.tsx` is the root layout and renders an `Outlet`.
14
+ - Flat-routes v2: dot-delimited filenames nest, so `concerts.$city.tsx` is a child of `concerts.tsx` and renders inside its `Outlet`. A trailing `_` opts a segment out of layout nesting; a leading `_` marks a pathless layout.
15
+ - Each route module co-locates a `loader` (server read), an `action` (server mutation), and a default-export component (the screen).
16
+ - Global styles ship via an exported `links` array or a CSS import in `root.tsx`.
17
+
18
+ ## File patterns
19
+
20
+ - `app/root.tsx`, `app/routes/*.tsx` (dot-segment names).
21
+ - Identify via: @remix-run/* or react-router in deps plus an `app/routes/` directory.
22
+
23
+ ## Gotchas
24
+
25
+ - A route file is a screen; parse the dot-naming to recover the layout tree and emit composes edges parent to child.
26
+ - `loader` and `action` are server data functions, not components; do not map them as nodes.
27
+ - A trailing `_` breaks visual nesting even when the dot path looks nested; respect it when building edges.
28
+ - Tokens enter via the `root.tsx` global stylesheet.
29
+
30
+ ## Example output
31
+
32
+ ```json
33
+ {
34
+ "schema_version": "52.0",
35
+ "nodes": [
36
+ { "id": "lay.root", "type": "layer", "subtype": "Template", "name": "Root", "summary": "Root layout with Outlet and global links.", "complexity": "moderate", "tags": ["template", "layout"] },
37
+ { "id": "scr.concerts", "type": "screen", "name": "concerts", "summary": "Parent route screen rendering nested city Outlet.", "complexity": "moderate", "tags": ["navigation"] },
38
+ { "id": "scr.concerts.city", "type": "screen", "name": "concerts.$city", "summary": "Child route screen nested in concerts via dot naming.", "complexity": "simple", "tags": ["navigation"] }
39
+ ],
40
+ "edges": [
41
+ { "source": "scr.concerts", "target": "scr.concerts.city", "type": "composes", "direction": "forward", "weight": 0.8 }
42
+ ]
43
+ }
44
+ ```
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: storybook
3
+ kind: framework
4
+ composes_into: [component-taxonomy-mapper, visual-hierarchy-mapper]
5
+ phase: 54
6
+ ---
7
+ <!-- Vendor docs: https://storybook.js.org/docs/writing-stories. -->
8
+
9
+ # Storybook
10
+
11
+ ## Conventions
12
+
13
+ - The richest source of variant and state nodes. A `*.stories.tsx` file in CSF3 has a default export (the meta, typed `Meta<typeof X>`, with `component`, `title`, `args`, `argTypes`) and named exports (the stories, typed `StoryObj`, mostly `args`).
14
+ - Each named story is a concrete variant or state of one component (Primary, Disabled, Loading, Small).
15
+ - `argTypes` declares the controllable prop space; its enumerated `options` describe the full variant axis. `decorators` wrap a story; `play` scripts an interaction.
16
+
17
+ ## File patterns
18
+
19
+ - `*.stories.@(tsx|jsx|ts|mdx)`, `.storybook/main.ts`, `.storybook/preview.ts` or `preview.tsx`.
20
+ - Identify via: @storybook/* in deps plus any `*.stories.*` file.
21
+
22
+ ## Gotchas
23
+
24
+ - Map each named story to a variant node, or a state node when the name or args set hover, focus, disabled, active, or loading; link it back to `meta.component` via composes or extends.
25
+ - `argTypes.options` enumerates the full variant space and is richer than a source scan; prefer it.
26
+ - The meta default export is metadata, not a component; decorators are wrappers, not nodes.
27
+ - Handle CSF2 (a `template.bind({})` story) the same as CSF3.
28
+
29
+ ## Example output
30
+
31
+ ```json
32
+ {
33
+ "schema_version": "52.0",
34
+ "nodes": [
35
+ { "id": "cmp.button", "type": "component", "name": "Button", "summary": "Component referenced by the stories meta.", "complexity": "moderate", "tags": ["interactive", "atom"] },
36
+ { "id": "var.button.primary", "type": "variant", "name": "Primary", "summary": "Primary variant story of Button.", "complexity": "simple", "tags": ["interactive"] },
37
+ { "id": "st.button.disabled", "type": "state", "name": "Disabled", "summary": "Disabled state story of Button.", "complexity": "simple", "tags": ["disabled", "state"] }
38
+ ],
39
+ "edges": [
40
+ { "source": "var.button.primary", "target": "cmp.button", "type": "extends", "direction": "forward", "weight": 0.9 },
41
+ { "source": "st.button.disabled", "target": "cmp.button", "type": "extends", "direction": "forward", "weight": 0.9 }
42
+ ]
43
+ }
44
+ ```
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: sveltekit
3
+ kind: framework
4
+ composes_into: [component-taxonomy-mapper, visual-hierarchy-mapper]
5
+ phase: 54
6
+ ---
7
+ <!-- Vendor docs: https://svelte.dev/docs/kit/routing. -->
8
+
9
+ # SvelteKit
10
+
11
+ ## Conventions
12
+
13
+ - `src/routes/` uses file routing: `+page.svelte` is a screen, `+layout.svelte` is a wrapper (hierarchical, via `<slot/>` or `{@render children()}`), `+page.ts`/`+page.server.ts` hold `load`, and `+server.ts` is an endpoint.
14
+ - `<style>` in a `.svelte` file is auto-scoped; `:global()` escapes the scope.
15
+ - Shared code lives in `src/lib/` behind the `$lib` alias. Global CSS (`app.css`) is imported once in the root `+layout.svelte`. `src/app.html` is the document shell.
16
+
17
+ ## File patterns
18
+
19
+ - `src/routes/**/+page.svelte`, `+layout.svelte`, `src/lib/`, `src/app.css`, `svelte.config.js`.
20
+ - Identify via: @sveltejs/kit in deps plus a `src/routes/` directory.
21
+
22
+ ## Gotchas
23
+
24
+ - Only `+page`-prefixed and `+layout`-prefixed files are routes; a sibling `+page.server.ts` is data, not a screen.
25
+ - Layout nesting follows directory depth; emit one composes edge per level from layout to page.
26
+ - Scoped styles are component-local; do not promote those class names to global tokens.
27
+ - Tokens live in `app.css` under `:root` or a `$lib` theme module; a `$lib` import is a depends-on edge.
28
+
29
+ ## Example output
30
+
31
+ ```json
32
+ {
33
+ "schema_version": "52.0",
34
+ "nodes": [
35
+ { "id": "scr.home", "type": "screen", "name": "/", "summary": "Home screen from src/routes/+page.svelte.", "complexity": "simple", "tags": ["navigation"] },
36
+ { "id": "lay.root", "type": "layer", "subtype": "Template", "name": "RootLayout", "summary": "Root +layout.svelte wrapping pages, imports app.css.", "complexity": "moderate", "tags": ["template", "layout"] },
37
+ { "id": "tok.color.bg", "type": "token", "subtype": "color", "name": "--bg", "summary": "Surface color token declared in app.css :root.", "complexity": "simple", "tags": ["color", "surface"] }
38
+ ],
39
+ "edges": [
40
+ { "source": "lay.root", "target": "scr.home", "type": "composes", "direction": "forward", "weight": 0.9 }
41
+ ]
42
+ }
43
+ ```
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: vite-react
3
+ kind: framework
4
+ composes_into: [component-taxonomy-mapper, visual-hierarchy-mapper]
5
+ phase: 54
6
+ ---
7
+ <!-- Vendor docs: https://vite.dev/guide and https://reactrouter.com. -->
8
+
9
+ # Vite + React
10
+
11
+ ## Conventions
12
+
13
+ - No built-in routing. `index.html` is the entry and loads `src/main.tsx`, which mounts `<App/>` into the `#root` element.
14
+ - Routing is opt-in via react-router-dom: either `createBrowserRouter([{ path, element }])` with `<RouterProvider>`, or JSX `<Routes>`/`<Route>`. Screens are config objects, not files.
15
+ - Layout is convention only (`src/components`, `src/pages`). Global CSS imports live in `main.tsx` or `App.tsx`. Path aliases come from `vite.config` `resolve.alias` (such as `@/`).
16
+
17
+ ## File patterns
18
+
19
+ - `index.html`, `src/main.tsx` (`createRoot().render`), `vite.config.ts`.
20
+ - Identify via: vite plus react in deps and a `src/main.tsx` entry.
21
+
22
+ ## Gotchas
23
+
24
+ - Screens come from the router config, not the filesystem; parse `createBrowserRouter` or `<Route path>` to recover them.
25
+ - `src/pages/*` is a convention, not a route source; do not infer screens from that folder alone.
26
+ - The entry is `main.tsx`; treat its mounted `<App/>` as the tree root.
27
+ - There is no server or client split; everything is client, so any component can be a motion or hover candidate.
28
+
29
+ ## Example output
30
+
31
+ ```json
32
+ {
33
+ "schema_version": "52.0",
34
+ "nodes": [
35
+ { "id": "scr.home", "type": "screen", "name": "/", "summary": "Home screen from a createBrowserRouter route element.", "complexity": "simple", "tags": ["navigation"] },
36
+ { "id": "lay.app", "type": "layer", "subtype": "Template", "name": "App", "summary": "Root App mounted into #root by main.tsx.", "complexity": "moderate", "tags": ["template", "layout"] },
37
+ { "id": "scr.settings", "type": "screen", "name": "/settings", "summary": "Settings screen declared in the router config.", "complexity": "moderate", "tags": ["navigation", "form"] }
38
+ ],
39
+ "edges": [
40
+ { "source": "lay.app", "target": "scr.home", "type": "composes", "direction": "forward", "weight": 0.8 }
41
+ ]
42
+ }
43
+ ```
@@ -46,3 +46,4 @@ Interaction is the broadest design domain. It governs every point where a user a
46
46
  - Civic one-thing-per-page forms: `reference/domains/civic-patterns.md`
47
47
  - Typography: `reference/typography.md`
48
48
  - Color: `reference/color.md`
49
+ - Stack-specific component and token conventions (Phase 54 composable addendums): `reference/systems/` (design systems) and `reference/frameworks/` (frameworks). These are composed into the explore mappers at spawn time by `scripts/lib/mapper-spawn.cjs` when `detectStack` matches the project, and are registered as `type:"stack-addendum"` entries in `reference/registry.json`.
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: framer-motion
3
+ kind: motion
4
+ composes_into: [motion-mapper]
5
+ phase: 54
6
+ ---
7
+ <!-- Vendor docs: https://motion.dev/docs/react-animation. -->
8
+
9
+ # Framer Motion
10
+
11
+ ## Conventions
12
+
13
+ - Declarative: `motion.*` elements take `initial` / `animate` / `exit` plus gesture props `whileHover` / `whileTap` / `whileDrag` / `whileInView` / `drag`.
14
+ - Named `variants` propagate parent to child; `staggerChildren` sequences them.
15
+ - `transition.type` is the model: `spring` (stiffness/damping/mass, or duration+bounce, default bounce ~0.25, keep <0.1 for UI) vs `tween` (duration plus named ease).
16
+ - `AnimatePresence` (stable `key`) enables `exit`; `layout` / `layoutId` drive FLIP and shared-element morphs.
17
+
18
+ ## File patterns
19
+
20
+ - `import { motion, AnimatePresence } from "motion/react"` (or legacy `"framer-motion"`).
21
+ - Markers: `motion.div`, `whileHover`, `variants`, `layoutId`, `useScroll`.
22
+ - Identify via: the `motion/react` import plus `motion.*` JSX.
23
+
24
+ ## Gotchas
25
+
26
+ - Unit trap: tween `duration` is SECONDS, so multiply by 1000 BEFORE bucketing; the `spring()` value-fn duration is milliseconds.
27
+ - Extract a duration bucket via the taxonomy: instant <100ms, quick 100-200, standard 200-300, slow 300-500, narrative 500+.
28
+ - Easing class: read `transition.type` (spring is physics; tween is named or cubic-bezier).
29
+ - Gesture vs tween: `whileHover` / `whileTap` / `whileDrag` / `whileInView` are gesture fragments; `initial`->`animate`/`exit` are transitions.
30
+ - A matched `layoutId` pair is a shared-element link, emitted as `transitions-to`.
31
+
32
+ ## Example output
33
+
34
+ ```json
35
+ {
36
+ "schema_version": "52.0",
37
+ "nodes": [
38
+ { "id": "mf.button.hover", "type": "motion-fragment", "name": "Button whileHover", "summary": "Pointer-reactive spring lift on hover.", "complexity": "simple", "tags": ["motion", "gesture", "hover"] },
39
+ { "id": "mf.card.enter", "type": "motion-fragment", "name": "Card entrance", "summary": "Quick tween fade-and-rise on mount.", "complexity": "simple", "tags": ["motion", "transition", "enter", "duration"] }
40
+ ],
41
+ "edges": [
42
+ { "source": "mf.card.enter", "target": "mf.button.hover", "type": "composes", "direction": "forward", "weight": 0.5 }
43
+ ]
44
+ }
45
+ ```
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: gsap
3
+ kind: motion
4
+ composes_into: [motion-mapper]
5
+ phase: 54
6
+ ---
7
+ <!-- Vendor docs: https://gsap.com/docs/v3/GSAP/Tween. -->
8
+
9
+ # GSAP
10
+
11
+ ## Conventions
12
+
13
+ - Imperative, no component model: `gsap.to(target, { duration, ease, ... })` plus `.from` / `.fromTo` / `.set`.
14
+ - `gsap.timeline({ defaults })` sequences tweens; children inherit the timeline defaults.
15
+ - Eases are strings `"<name>.<inOut>"`: power0 through power4, none (linear), sine / expo / circ / back / elastic / bounce / steps(); default is `power1.out`.
16
+ - `ScrollTrigger` (registered via `gsap.registerPlugin`) binds a tween to scroll. The core has no spring.
17
+
18
+ ## File patterns
19
+
20
+ - `import gsap from "gsap"`; `import { ScrollTrigger } from "gsap/ScrollTrigger"`.
21
+ - Markers: `gsap.to(`, `gsap.timeline(`, `registerPlugin`, often inside `useGSAP` or `useEffect`.
22
+ - Identify via: the `gsap` import plus a `gsap.to` / `gsap.timeline` call.
23
+
24
+ ## Gotchas
25
+
26
+ - Unit trap: `duration` is SECONDS, so multiply by 1000 BEFORE bucketing.
27
+ - Extract a duration bucket via the taxonomy: instant <100ms, quick 100-200, standard 200-300, slow 300-500, narrative 500+.
28
+ - Easing class: every ease string is a tween (named or eased); GSAP core has no native spring.
29
+ - Gesture vs tween: a `ScrollTrigger`-bound tween is a scroll-linked fragment; a bare `timeline` is an orchestrated transition.
30
+ - Targets are selectors or refs, so link each fragment to the component that owns the ref.
31
+
32
+ ## Example output
33
+
34
+ ```json
35
+ {
36
+ "schema_version": "52.0",
37
+ "nodes": [
38
+ { "id": "mf.hero.reveal", "type": "motion-fragment", "name": "Hero scroll reveal", "summary": "Slow eased tween bound to ScrollTrigger.", "complexity": "moderate", "tags": ["motion", "transition", "duration", "easing"] },
39
+ { "id": "mf.list.stagger", "type": "motion-fragment", "name": "List stagger", "summary": "Timeline staggering item entrances.", "complexity": "moderate", "tags": ["motion", "transition", "enter"] }
40
+ ],
41
+ "edges": [
42
+ { "source": "mf.list.stagger", "target": "mf.hero.reveal", "type": "transitions-to", "direction": "forward", "weight": 0.4 }
43
+ ]
44
+ }
45
+ ```
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: motion-one
3
+ kind: motion
4
+ composes_into: [motion-mapper]
5
+ phase: 54
6
+ ---
7
+ <!-- Vendor docs: https://motion.dev/docs/animate. -->
8
+
9
+ # Motion One
10
+
11
+ ## Conventions
12
+
13
+ - Tiny WAAPI core: `animate(element, keyframes, options)` where options carry `duration`, `ease` (named, cubic-bezier, or fn) OR `type: "spring"`.
14
+ - A spring is compiled to a `linear()` easing from stiffness/damping/mass/bounce; `spring()` and `glide()` generators exist (glide carries velocity).
15
+ - `inView()` runs on viewport entry, `scroll()` is scroll-linked, `stagger()` sequences a set.
16
+ - Imperative with no JSX; the React wrapper IS Framer Motion, so JSX absence is the tell.
17
+
18
+ ## File patterns
19
+
20
+ - `import { animate, inView, scroll, stagger, spring } from "motion"` (or `"motion/mini"`).
21
+ - Markers: `animate(`, `inView(`, `scroll(`, plus a small-footprint import list.
22
+ - Identify via: those imports with NO `motion.*` JSX (which would mean Framer Motion).
23
+
24
+ ## Gotchas
25
+
26
+ - Unit trap: `duration` is SECONDS, so multiply by 1000 BEFORE bucketing.
27
+ - Extract a duration bucket via the taxonomy: instant <100ms, quick 100-200, standard 200-300, slow 300-500, narrative 500+.
28
+ - Easing class: `type: "spring"` or a `spring()` / `glide()` generator is physics; a named or cubic-bezier `ease` is a tween.
29
+ - Gesture vs tween: `inView()` is an entrance, `scroll()` is scroll-linked, a direct `animate` from an event handler is a gesture fragment.
30
+
31
+ ## Example output
32
+
33
+ ```json
34
+ {
35
+ "schema_version": "52.0",
36
+ "nodes": [
37
+ { "id": "mf.section.inview", "type": "motion-fragment", "name": "Section inView", "summary": "Standard tween fade on viewport entry.", "complexity": "simple", "tags": ["motion", "transition", "enter", "duration"] },
38
+ { "id": "mf.banner.scroll", "type": "motion-fragment", "name": "Banner scroll-link", "summary": "Scroll-linked parallax via scroll().", "complexity": "moderate", "tags": ["motion", "animation", "gesture"] }
39
+ ],
40
+ "edges": [
41
+ { "source": "mf.section.inview", "target": "mf.banner.scroll", "type": "composes", "direction": "forward", "weight": 0.4 }
42
+ ]
43
+ }
44
+ ```
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: react-spring
3
+ kind: motion
4
+ composes_into: [motion-mapper]
5
+ phase: 54
6
+ ---
7
+ <!-- Vendor docs: https://react-spring.dev/docs/components/use-spring. -->
8
+
9
+ # React Spring
10
+
11
+ ## Conventions
12
+
13
+ - Physics-first hooks: `useSpring` (one style), `useTransition` (mount/unmount or list, via from/enter/leave), plus `useTrail` / `useChain` / `useSprings`.
14
+ - Config presets tune the spring: default {tension:170,friction:26}, gentle {120,14}, wobbly {180,12}, stiff {210,20}, slow {280,60}, molasses {280,120}.
15
+ - Hooks return `animated.*` styles applied to `animated.div` (and friends).
16
+ - Gestures come from the companion `@use-gesture/react`, which drives the spring from pointer input.
17
+
18
+ ## File patterns
19
+
20
+ - `import { useSpring, useTransition, animated, config } from "@react-spring/web"` (or `react-spring`).
21
+ - Markers: `useSpring({ from, to, config })`, `animated.div`, `config.gentle`.
22
+ - Identify via: a `useSpring` / `useTransition` call plus an `animated.*` element.
23
+
24
+ ## Gotchas
25
+
26
+ - Unit trap: there is NO fixed duration; record the config preset name plus its tension/friction, since the mapper must normalize before bucketing.
27
+ - Map preset to perceived speed (taxonomy): stiff and default read as quick, gentle as standard, slow and molasses as narrative.
28
+ - Easing class: this is almost always a spring (physics), so capture the preset, not an ease curve.
29
+ - Gesture vs tween: `useTransition` enter/leave are transition fragments; a `useSpring` driven by hover or `@use-gesture` is a gesture fragment.
30
+
31
+ ## Example output
32
+
33
+ ```json
34
+ {
35
+ "schema_version": "52.0",
36
+ "nodes": [
37
+ { "id": "mf.modal.transition", "type": "motion-fragment", "name": "Modal useTransition", "summary": "Gentle spring enter and leave, standard speed.", "complexity": "moderate", "tags": ["motion", "transition", "enter", "exit"] },
38
+ { "id": "mf.tile.drag", "type": "motion-fragment", "name": "Tile drag spring", "summary": "Stiff spring driven by pointer drag.", "complexity": "moderate", "tags": ["motion", "gesture", "dragging"] }
39
+ ],
40
+ "edges": [
41
+ { "source": "mf.modal.transition", "target": "mf.tile.drag", "type": "composes", "direction": "forward", "weight": 0.4 }
42
+ ]
43
+ }
44
+ ```
@@ -164,3 +164,4 @@ Always respect this. It is not optional.
164
164
  - CSS layout transitions: `reference/spatial.md`
165
165
  - Typography: `reference/typography.md`
166
166
  - UX writing: `reference/ux-writing.md`
167
+ - Per-library motion conventions (Phase 54 composable addendums): `reference/motion/` (framer-motion, gsap, motion-one, react-spring). These reuse the duration classes above and are composed into the motion mapper at spawn time by `scripts/lib/mapper-spawn.cjs` when `detectStack` matches the project; each is a `type:"stack-addendum"` entry in `reference/registry.json`.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "./schemas/registry.schema.json",
3
3
  "version": 1,
4
- "generated_at": "2026-05-20T09:53:00.000Z",
4
+ "generated_at": "2026-06-03T00:00:00.000Z",
5
5
  "entries": [
6
6
  {
7
7
  "name": "codex-tools",
@@ -1170,6 +1170,168 @@
1170
1170
  "type": "meta-rules",
1171
1171
  "phase": 52,
1172
1172
  "description": "Phase 52 controlled tag vocabulary for DesignContext nodes; validate-design-context.cjs soft-warns on unknown tags."
1173
+ },
1174
+ {
1175
+ "name": "addendum-system-tailwind",
1176
+ "path": "reference/systems/tailwind.md",
1177
+ "type": "stack-addendum",
1178
+ "phase": 54,
1179
+ "kind": "system",
1180
+ "composes_into": ["token-mapper", "component-taxonomy-mapper"],
1181
+ "description": "Phase 54 stack addendum (design-system) — Tailwind CSS. v4 @theme CSS-custom-property token model vs v3 tailwind.config theme, utility-cluster-as-variant reading, arbitrary-value anti-patterns. Composed into the token + component-taxonomy mappers when detectStack reports ds=tailwind."
1182
+ },
1183
+ {
1184
+ "name": "addendum-system-shadcn",
1185
+ "path": "reference/systems/shadcn.md",
1186
+ "type": "stack-addendum",
1187
+ "phase": 54,
1188
+ "kind": "system",
1189
+ "composes_into": ["token-mapper", "component-taxonomy-mapper"],
1190
+ "description": "Phase 54 stack addendum (design-system) — shadcn/ui. components.json + cn() helper signature, copy-in (not dependency) component ownership, CSS-variable theming over the Radix primitive layer. Composed into the token + component-taxonomy mappers when detectStack reports ds=shadcn."
1191
+ },
1192
+ {
1193
+ "name": "addendum-system-radix-themes",
1194
+ "path": "reference/systems/radix-themes.md",
1195
+ "type": "stack-addendum",
1196
+ "phase": 54,
1197
+ "kind": "system",
1198
+ "composes_into": ["token-mapper", "component-taxonomy-mapper"],
1199
+ "description": "Phase 54 stack addendum (design-system) — Radix Themes. The accent/gray scale token system, the 12-step color scales, Theme-prop driven appearance, radius/scaling config. Composed into the token + component-taxonomy mappers when detectStack reports ds=radix-themes."
1200
+ },
1201
+ {
1202
+ "name": "addendum-system-mui",
1203
+ "path": "reference/systems/mui.md",
1204
+ "type": "stack-addendum",
1205
+ "phase": 54,
1206
+ "kind": "system",
1207
+ "composes_into": ["token-mapper", "component-taxonomy-mapper"],
1208
+ "description": "Phase 54 stack addendum (design-system) — MUI (Material UI). createTheme palette/typography/spacing tokens, the sx prop vs styled() usage, theme.vars CSS-variable mode, slot-based component anatomy. Composed into the token + component-taxonomy mappers when detectStack reports ds=mui."
1209
+ },
1210
+ {
1211
+ "name": "addendum-system-chakra",
1212
+ "path": "reference/systems/chakra.md",
1213
+ "type": "stack-addendum",
1214
+ "phase": 54,
1215
+ "kind": "system",
1216
+ "composes_into": ["token-mapper", "component-taxonomy-mapper"],
1217
+ "description": "Phase 54 stack addendum (design-system) — Chakra UI. The theme token scales (colors/space/fontSizes/radii), style-prop usage as token references, semantic tokens, recipe/variant anatomy. Composed into the token + component-taxonomy mappers when detectStack reports ds=chakra."
1218
+ },
1219
+ {
1220
+ "name": "addendum-system-vanilla-extract",
1221
+ "path": "reference/systems/vanilla-extract.md",
1222
+ "type": "stack-addendum",
1223
+ "phase": 54,
1224
+ "kind": "system",
1225
+ "composes_into": ["token-mapper", "component-taxonomy-mapper"],
1226
+ "description": "Phase 54 stack addendum (design-system) — vanilla-extract. The *.css.ts compile-time stylesheet model, createTheme / themeContract token contracts, vars as the token source, recipe() variants. Composed into the token + component-taxonomy mappers when detectStack reports ds=vanilla-extract."
1227
+ },
1228
+ {
1229
+ "name": "addendum-system-styled-components",
1230
+ "path": "reference/systems/styled-components.md",
1231
+ "type": "stack-addendum",
1232
+ "phase": 54,
1233
+ "kind": "system",
1234
+ "composes_into": ["token-mapper", "component-taxonomy-mapper"],
1235
+ "description": "Phase 54 stack addendum (design-system) — styled-components. The ThemeProvider theme object as the token tree, props-driven dynamic styling, the styled() component boundary, css helper composition. Composed into the token + component-taxonomy mappers when detectStack reports ds=styled-components."
1236
+ },
1237
+ {
1238
+ "name": "addendum-system-css-modules",
1239
+ "path": "reference/systems/css-modules.md",
1240
+ "type": "stack-addendum",
1241
+ "phase": 54,
1242
+ "kind": "system",
1243
+ "composes_into": ["token-mapper", "component-taxonomy-mapper"],
1244
+ "description": "Phase 54 stack addendum (design-system) — CSS Modules. The *.module.css locally-scoped class model, :root / var() custom-property tokens, composes for variant reuse, no runtime theme object. Composed into the token + component-taxonomy mappers when detectStack reports ds=css-modules."
1245
+ },
1246
+ {
1247
+ "name": "addendum-framework-nextjs",
1248
+ "path": "reference/frameworks/nextjs.md",
1249
+ "type": "stack-addendum",
1250
+ "phase": 54,
1251
+ "kind": "framework",
1252
+ "composes_into": ["component-taxonomy-mapper", "visual-hierarchy-mapper"],
1253
+ "description": "Phase 54 stack addendum (framework) — Next.js. App Router vs Pages Router layout/route structure, server vs client component split, layout.tsx hierarchy as a screen graph, metadata/loading/error conventions. Composed into the component-taxonomy + visual-hierarchy mappers when detectStack reports framework=nextjs."
1254
+ },
1255
+ {
1256
+ "name": "addendum-framework-remix",
1257
+ "path": "reference/frameworks/remix.md",
1258
+ "type": "stack-addendum",
1259
+ "phase": 54,
1260
+ "kind": "framework",
1261
+ "composes_into": ["component-taxonomy-mapper", "visual-hierarchy-mapper"],
1262
+ "description": "Phase 54 stack addendum (framework) — Remix (v2 / React Router v7 framework mode). Nested-route file conventions as a layout tree, loader/action data boundaries, Outlet composition, the route-as-screen mapping. Composed into the component-taxonomy + visual-hierarchy mappers when detectStack reports framework=remix."
1263
+ },
1264
+ {
1265
+ "name": "addendum-framework-vite-react",
1266
+ "path": "reference/frameworks/vite-react.md",
1267
+ "type": "stack-addendum",
1268
+ "phase": 54,
1269
+ "kind": "framework",
1270
+ "composes_into": ["component-taxonomy-mapper", "visual-hierarchy-mapper"],
1271
+ "description": "Phase 54 stack addendum (framework) — Vite + React SPA. The client-only render tree, react-router route config as the screen graph, entry-point main.tsx, no server-component split. Composed into the component-taxonomy + visual-hierarchy mappers when detectStack reports framework=vite-react."
1272
+ },
1273
+ {
1274
+ "name": "addendum-framework-astro",
1275
+ "path": "reference/frameworks/astro.md",
1276
+ "type": "stack-addendum",
1277
+ "phase": 54,
1278
+ "kind": "framework",
1279
+ "composes_into": ["component-taxonomy-mapper", "visual-hierarchy-mapper"],
1280
+ "description": "Phase 54 stack addendum (framework) — Astro. The .astro component model, island architecture (client:* directives) as the interactivity boundary, file-based pages routing, content collections. Composed into the component-taxonomy + visual-hierarchy mappers when detectStack reports framework=astro."
1281
+ },
1282
+ {
1283
+ "name": "addendum-framework-sveltekit",
1284
+ "path": "reference/frameworks/sveltekit.md",
1285
+ "type": "stack-addendum",
1286
+ "phase": 54,
1287
+ "kind": "framework",
1288
+ "composes_into": ["component-taxonomy-mapper", "visual-hierarchy-mapper"],
1289
+ "description": "Phase 54 stack addendum (framework) — SvelteKit. The +page / +layout route file conventions as a layout tree, load functions, slot composition, the .svelte component anatomy. Composed into the component-taxonomy + visual-hierarchy mappers when detectStack reports framework=sveltekit."
1290
+ },
1291
+ {
1292
+ "name": "addendum-framework-storybook",
1293
+ "path": "reference/frameworks/storybook.md",
1294
+ "type": "stack-addendum",
1295
+ "phase": 54,
1296
+ "kind": "framework",
1297
+ "composes_into": ["component-taxonomy-mapper", "visual-hierarchy-mapper"],
1298
+ "description": "Phase 54 stack addendum (framework) — Storybook. The *.stories.* files as the canonical component + variant catalogue, args/argTypes as the variant matrix, CSF story structure, the component-in-isolation taxonomy signal. Composed into the component-taxonomy + visual-hierarchy mappers when detectStack reports framework=storybook."
1299
+ },
1300
+ {
1301
+ "name": "addendum-motion-framer-motion",
1302
+ "path": "reference/motion/framer-motion.md",
1303
+ "type": "stack-addendum",
1304
+ "phase": 54,
1305
+ "kind": "motion",
1306
+ "composes_into": ["motion-mapper"],
1307
+ "description": "Phase 54 stack addendum (motion) — Framer Motion / motion. Seconds-unit duration trap, the spring-vs-tween default, variants/AnimatePresence/gesture props, mapping onto the instant/quick/standard/slow/narrative duration classes. Composed into the motion mapper when detectStack reports motion_libs includes framer-motion."
1308
+ },
1309
+ {
1310
+ "name": "addendum-motion-gsap",
1311
+ "path": "reference/motion/gsap.md",
1312
+ "type": "stack-addendum",
1313
+ "phase": 54,
1314
+ "kind": "motion",
1315
+ "composes_into": ["motion-mapper"],
1316
+ "description": "Phase 54 stack addendum (motion) — GSAP. Seconds-unit duration, the timeline orchestration model, ease string vocabulary, ScrollTrigger gestures, mapping tweens onto the instant/quick/standard/slow/narrative duration classes. Composed into the motion mapper when detectStack reports motion_libs includes gsap."
1317
+ },
1318
+ {
1319
+ "name": "addendum-motion-motion-one",
1320
+ "path": "reference/motion/motion-one.md",
1321
+ "type": "stack-addendum",
1322
+ "phase": 54,
1323
+ "kind": "motion",
1324
+ "composes_into": ["motion-mapper"],
1325
+ "description": "Phase 54 stack addendum (motion) — Motion One. The Web Animations API foundation, seconds-unit duration, the animate() signature, spring/glide generators, mapping onto the instant/quick/standard/slow/narrative duration classes. Composed into the motion mapper when detectStack reports motion_libs includes motion-one."
1326
+ },
1327
+ {
1328
+ "name": "addendum-motion-react-spring",
1329
+ "path": "reference/motion/react-spring.md",
1330
+ "type": "stack-addendum",
1331
+ "phase": 54,
1332
+ "kind": "motion",
1333
+ "composes_into": ["motion-mapper"],
1334
+ "description": "Phase 54 stack addendum (motion) — react-spring. The physics-first (no-duration) model: tension/friction/mass instead of a duration, useSpring/useTransition hooks, the gesture-driven imperative api, reconciling physics springs with the instant/quick/standard/slow/narrative duration classes. Composed into the motion mapper when detectStack reports motion_libs includes react-spring."
1173
1335
  }
1174
1336
  ]
1175
1337
  }