@gradial/aci 0.1.20-preview.3 → 0.1.21
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/README.md +48 -108
- package/bin/{aci → aci-darwin-arm64} +0 -0
- package/bin/aci.js +99 -6
- package/dist/assets/index.d.ts +3 -3
- package/dist/assets/index.js +3 -3
- package/dist/astro/index.d.ts +12 -3
- package/dist/astro/index.js +20 -5
- package/dist/content/assets.d.ts +17 -0
- package/dist/content/assets.js +65 -0
- package/dist/content/index.d.ts +1 -0
- package/dist/content/index.js +1 -0
- package/dist/define-component.d.ts +1 -2
- package/dist/define-component.js +73 -5
- package/dist/dev/content-watch.d.ts +37 -0
- package/dist/dev/content-watch.js +154 -0
- package/dist/dev/index.d.ts +24 -43
- package/dist/dev/index.js +4 -169
- package/dist/index.d.ts +14 -6
- package/dist/index.js +8 -9
- package/dist/next/asset-route.js +2 -2
- package/dist/next/config.d.ts +2 -2
- package/dist/next/config.js +5 -5
- package/dist/next/content-watch.js +6 -1
- package/dist/next/index.d.ts +2 -2
- package/dist/next/index.js +2 -2
- package/dist/next/middleware.d.ts +1 -0
- package/dist/next/middleware.js +49 -8
- package/dist/next/page.d.ts +1 -1
- package/dist/next/page.js +14 -12
- package/dist/next/render.d.ts +3 -3
- package/dist/next/render.js +11 -9
- package/dist/next/server.d.ts +12 -12
- package/dist/next/server.js +1 -1
- package/dist/preview/core.d.ts +5 -0
- package/dist/preview/core.js +1 -1
- package/dist/react/Media.d.ts +24 -0
- package/dist/react/Media.js +30 -0
- package/dist/react/Picture.d.ts +12 -0
- package/dist/react/Picture.js +11 -0
- package/dist/react/VideoPlayer.d.ts +13 -0
- package/dist/react/{GradialVideoPlayer.js → VideoPlayer.js} +6 -5
- package/dist/react/index.d.ts +333 -3
- package/dist/react/index.js +89 -3
- package/dist/registry.d.ts +2 -2
- package/dist/registry.js +3 -3
- package/dist/types/block-ref.d.ts +26 -0
- package/dist/types/block-ref.js +28 -0
- package/dist/types/component.d.ts +36 -32
- package/dist/types/config.d.ts +1 -1
- package/dist/types/image.d.ts +33 -20
- package/dist/types/image.js +42 -50
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/link.d.ts +38 -0
- package/dist/types/link.js +58 -0
- package/dist/types/media.d.ts +16 -35
- package/dist/types/media.js +15 -84
- package/dist/types/renderer.d.ts +1 -1
- package/dist/types/rich-text.d.ts +40 -0
- package/dist/types/rich-text.js +39 -0
- package/dist/types/video.d.ts +7 -13
- package/dist/types/video.js +3 -3
- package/package.json +29 -76
- package/src/cli/compile-registry.mjs +120 -63
- package/src/cli/validate-content.mjs +38 -75
- package/src/types/block-ref.ts +74 -0
- package/src/types/image.ts +79 -60
- package/templates/astro/template/.aci.yaml +28 -0
- package/templates/astro/template/.storybook/main.ts +79 -0
- package/templates/astro/template/.storybook/manager.ts +6 -0
- package/templates/astro/template/.storybook/preview.ts +33 -0
- package/templates/astro/template/astro.config.mjs +37 -0
- package/templates/astro/template/package.json.tmpl +41 -0
- package/templates/astro/template/src/cms/contracts/layouts/index.ts +18 -0
- package/templates/astro/template/src/cms/registry.ts +28 -0
- package/templates/astro/template/src/components/chrome/Footer.astro +107 -0
- package/templates/astro/template/src/components/chrome/Header.astro +94 -0
- package/templates/astro/template/src/components/elements/AtomicBlock.astro +15 -0
- package/templates/astro/template/src/components/elements/AtomicBlocks.astro +16 -0
- package/templates/astro/template/src/components/elements/Button.astro +51 -0
- package/templates/astro/template/src/components/elements/ButtonBlock.astro +25 -0
- package/templates/astro/template/src/components/elements/Container.astro +11 -0
- package/templates/astro/template/src/components/elements/Icon.astro +31 -0
- package/templates/astro/template/src/components/elements/Logo.astro +29 -0
- package/templates/astro/template/src/components/elements/RemoteImage.astro +41 -0
- package/templates/astro/template/src/components/sections/ContainerSection.astro +32 -0
- package/templates/astro/template/src/components/sections/FeatureCard.astro +23 -0
- package/templates/astro/template/src/components/sections/FeatureGrid.astro +35 -0
- package/templates/astro/template/src/components/sections/HomeHero.astro +51 -0
- package/templates/astro/template/src/components/sections/StatsBar.astro +33 -0
- package/templates/astro/template/src/design-system/styles.css +399 -0
- package/templates/astro/template/src/design-system/tokens/colors.css +60 -0
- package/templates/astro/template/src/design-system/tokens/components.css +69 -0
- package/templates/astro/template/src/design-system/tokens/index.css +6 -0
- package/templates/astro/template/src/design-system/tokens/radii.css +5 -0
- package/templates/astro/template/src/design-system/tokens/shadows.css +5 -0
- package/templates/astro/template/src/design-system/tokens/spacing.css +13 -0
- package/templates/astro/template/src/design-system/tokens/typography.css +24 -0
- package/templates/astro/template/src/env.d.ts +1 -0
- package/templates/astro/template/src/fixtures/atomicBlocks.ts +33 -0
- package/templates/astro/template/src/fixtures/composition.ts +31 -0
- package/templates/astro/template/src/fixtures/index.ts +17 -0
- package/templates/astro/template/src/fixtures/sections.ts +39 -0
- package/templates/astro/template/src/layouts/SiteLayout.astro +30 -0
- package/templates/astro/template/src/pages/[...slug].astro +61 -0
- package/templates/astro/template/src/render/RenderPage.astro +66 -0
- package/templates/astro/template/src/stories/CompositionStoryFrame.astro +15 -0
- package/templates/astro/template/src/stories/HomeHero.stories.ts +24 -0
- package/templates/astro/template/src/stories/SectionStoryFrame.astro +16 -0
- package/templates/astro/template/src/stories/StoryDocFrame.astro +31 -0
- package/templates/astro/template/tsconfig.json +11 -0
- package/templates/common/.agents/AGENTS.md +37 -0
- package/templates/common/.agents/skills/aci/SKILL.md +162 -0
- package/templates/common/.agents/skills/authoring/SKILL.md +590 -0
- package/templates/common/.agents/skills/authoring/references/block-registry.md +151 -0
- package/templates/common/.agents/skills/authoring/references/contracts.md +153 -0
- package/templates/common/.agents/skills/authoring/references/design-system.md +171 -0
- package/templates/common/.agents/skills/authoring/references/image-assets.md +73 -0
- package/templates/common/.agents/skills/authoring/references/repo-structure.md +157 -0
- package/templates/common/.agents/skills/migration/SKILL.md +160 -0
- package/templates/common/.agents/skills/migration/references/analyzing-source.md +215 -0
- package/templates/common/.agents/skills/migration/references/component-migration.md +200 -0
- package/templates/common/.agents/skills/migration/references/selector-map.md +31 -0
- package/templates/common/.content/.gradial-dam/blobs/sha256/7f/bf/7fbfc7fe230ff12688c496f660119e41d9725c4504d82e310c15665c73c09292 +0 -0
- package/templates/common/.content/.gradial-dam/blobs/sha256/a0/f5/a0f506689de9b15a7055f70103a3f02cd3ba105771ae2de6754df2ede1210d3a +0 -0
- package/templates/common/.content/.gradial-dam/blobs/sha256/dd/b7/ddb7e9642be08317bcd4b2bd26b58ba8d0d34dd7239e03e684a4f3634fa3845b +0 -0
- package/templates/common/.content/.gradial-dam/blobs/sha256/fb/32/fb3260e8286ea8231ea1c77b9c0be92d6edd9026565731eb14cfdcfd6b1b75b3 +0 -0
- package/templates/common/.content/config/site.json +192 -0
- package/templates/common/.content/dam/folders/seed/ast_site_about_hero/asset.json +9 -0
- package/templates/common/.content/dam/folders/seed/ast_site_about_hero/editorial.json +14 -0
- package/templates/common/.content/dam/folders/seed/ast_site_about_hero/governance.json +23 -0
- package/templates/common/.content/dam/folders/seed/ast_site_about_hero/versions/v0001.json +37 -0
- package/templates/common/.content/dam/folders/seed/ast_site_home_hero/asset.json +9 -0
- package/templates/common/.content/dam/folders/seed/ast_site_home_hero/editorial.json +14 -0
- package/templates/common/.content/dam/folders/seed/ast_site_home_hero/governance.json +23 -0
- package/templates/common/.content/dam/folders/seed/ast_site_home_hero/versions/v0001.json +37 -0
- package/templates/common/.content/fragments/navbar/_index.json +25 -0
- package/templates/common/.content/fragments/site-footer/_index.json +62 -0
- package/templates/common/.content/pages/about/_index.json +51 -0
- package/templates/common/.content/pages/home/_index.json +112 -0
- package/templates/common/.content/schemas/site.schema.json +123 -0
- package/templates/common/README.md.tmpl +45 -0
- package/templates/common/contracts/components/button.contract.ts +19 -0
- package/templates/common/contracts/components/container.contract.ts +19 -0
- package/templates/common/contracts/components/featureCard.contract.ts +15 -0
- package/templates/common/contracts/components/featureGrid.contract.ts +16 -0
- package/templates/common/contracts/components/homeHero.contract.ts +36 -0
- package/templates/common/contracts/components/index.ts +21 -0
- package/templates/common/contracts/components/siteFooter.contract.ts +45 -0
- package/templates/common/contracts/components/siteNavigation.contract.ts +30 -0
- package/templates/common/contracts/components/statsBar.contract.ts +19 -0
- package/templates/common/design-system/styles.css +346 -0
- package/templates/common/design-system/tokens/colors.css +110 -0
- package/templates/common/design-system/tokens/components.css +86 -0
- package/templates/common/design-system/tokens/index.css +6 -0
- package/templates/common/design-system/tokens/radii.css +5 -0
- package/templates/common/design-system/tokens/shadows.css +9 -0
- package/templates/common/design-system/tokens/spacing.css +26 -0
- package/templates/common/design-system/tokens/typography.css +32 -0
- package/templates/common/eslint-rules/no-raw-tailwind-values.js +127 -0
- package/templates/common/public/assets/Dwire-model.png +0 -0
- package/templates/common/public/assets/bare-metal-logo.png +0 -0
- package/templates/common/public/assets/meridian-logo.svg +8 -0
- package/templates/common/public/assets/seattle.avif +0 -0
- package/templates/nextjs/template/.aci.yaml +26 -0
- package/templates/nextjs/template/.storybook/main.ts +13 -0
- package/templates/nextjs/template/.storybook/preview.ts +34 -0
- package/templates/nextjs/template/eslint.config.mjs +36 -0
- package/templates/nextjs/template/next-env.d.ts +6 -0
- package/templates/nextjs/template/next.config.ts +8 -0
- package/templates/nextjs/template/package.json.tmpl +46 -0
- package/templates/nextjs/template/postcss.config.mjs +7 -0
- package/templates/nextjs/template/src/app/[[...slug]]/page.tsx +8 -0
- package/templates/nextjs/template/src/app/gradial/assets/[releaseId]/[...path]/route.ts +31 -0
- package/templates/nextjs/template/src/app/layout.tsx +29 -0
- package/templates/nextjs/template/src/cms/contracts/components/button.contract.ts +19 -0
- package/templates/nextjs/template/src/cms/contracts/components/container.contract.ts +20 -0
- package/templates/nextjs/template/src/cms/contracts/components/homeHero.contract.ts +36 -0
- package/templates/nextjs/template/src/cms/contracts/components/index.ts +15 -0
- package/templates/nextjs/template/src/cms/contracts/components/siteFooter.contract.ts +45 -0
- package/templates/nextjs/template/src/cms/contracts/components/siteNavigation.contract.ts +30 -0
- package/templates/nextjs/template/src/cms/contracts/layouts/index.ts +16 -0
- package/templates/nextjs/template/src/cms/registry.ts +28 -0
- package/templates/nextjs/template/src/components/chrome/Footer.tsx +86 -0
- package/templates/nextjs/template/src/components/chrome/Header.tsx +74 -0
- package/templates/nextjs/template/src/components/elements/AtomicBlock.tsx +13 -0
- package/templates/nextjs/template/src/components/elements/Button.tsx +40 -0
- package/templates/nextjs/template/src/components/elements/ButtonBlock.tsx +18 -0
- package/templates/nextjs/template/src/components/elements/Container.tsx +14 -0
- package/templates/nextjs/template/src/components/elements/Icon.tsx +29 -0
- package/templates/nextjs/template/src/components/elements/Logo.tsx +38 -0
- package/templates/nextjs/template/src/components/sections/ContainerSection.tsx +28 -0
- package/templates/nextjs/template/src/components/sections/FeatureCard.tsx +25 -0
- package/templates/nextjs/template/src/components/sections/FeatureGrid.tsx +36 -0
- package/templates/nextjs/template/src/components/sections/HomeHero.tsx +62 -0
- package/templates/nextjs/template/src/components/sections/StatsBar.tsx +30 -0
- package/templates/nextjs/template/src/middleware.ts +4 -0
- package/templates/nextjs/template/src/stories/Button.stories.tsx +38 -0
- package/templates/nextjs/template/src/stories/Header.stories.tsx +30 -0
- package/templates/nextjs/template/src/stories/HomeHero.stories.tsx +33 -0
- package/templates/nextjs/template/tsconfig.json +23 -0
- package/templates/nextjs/template/vercel.json +6 -0
- package/dist/content/contract.d.ts +0 -83
- package/dist/content/contract.js +0 -104
- package/dist/content/tailwind-validator.d.ts +0 -6
- package/dist/content/tailwind-validator.js +0 -31
- package/dist/content/validation.d.ts +0 -108
- package/dist/content/validation.js +0 -183
- package/dist/react/GradialMedia.d.ts +0 -24
- package/dist/react/GradialMedia.js +0 -31
- package/dist/react/GradialPicture.d.ts +0 -14
- package/dist/react/GradialPicture.js +0 -30
- package/dist/react/GradialVideoPlayer.d.ts +0 -13
- package/dist/sveltekit/index.d.ts +0 -25
- package/dist/sveltekit/index.js +0 -66
- package/dist/sveltekit/preview.d.ts +0 -5
- package/dist/sveltekit/preview.js +0 -33
- package/src/types/component.ts +0 -49
- package/src/types/config.ts +0 -37
- package/src/types/data.ts +0 -47
- package/src/types/index.ts +0 -10
- package/src/types/layout.ts +0 -29
- package/src/types/media.ts +0 -125
- package/src/types/page.ts +0 -47
- package/src/types/render-mode.ts +0 -10
- package/src/types/renderer.ts +0 -83
- package/src/types/video.ts +0 -66
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Repository Structure Reference
|
|
2
|
+
|
|
3
|
+
## Directory Layout
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
.aci.yaml ACI config: contract paths, framework, routes
|
|
7
|
+
package.json Dependencies and scripts
|
|
8
|
+
tsconfig.json TypeScript config
|
|
9
|
+
.content/ Local content for development
|
|
10
|
+
config/
|
|
11
|
+
site.json Site metadata, navigation, footer, branding, SEO
|
|
12
|
+
pages/
|
|
13
|
+
home/_index.json Homepage (route /)
|
|
14
|
+
about/_index.json About page (route /about)
|
|
15
|
+
fragments/
|
|
16
|
+
navbar/_index.json Navbar fragment (layout default)
|
|
17
|
+
site-footer/_index.json Footer fragment (layout default)
|
|
18
|
+
src/
|
|
19
|
+
cms/
|
|
20
|
+
contracts/
|
|
21
|
+
components/ Component contracts (framework-agnostic)
|
|
22
|
+
homeHero.contract.ts Hero section contract
|
|
23
|
+
button.contract.ts Button block contract
|
|
24
|
+
container.contract.ts Container (nested blocks) contract
|
|
25
|
+
featureGrid.contract.ts Feature grid contract
|
|
26
|
+
featureCard.contract.ts Feature card contract
|
|
27
|
+
statsBar.contract.ts Stats bar contract
|
|
28
|
+
siteNavigation.contract.ts Site navigation contract
|
|
29
|
+
siteFooter.contract.ts Site footer contract
|
|
30
|
+
index.ts Component contract barrel
|
|
31
|
+
layouts/
|
|
32
|
+
index.ts Layout contract barrel (plain objects)
|
|
33
|
+
registry.ts Component registry — createRegistry([contract, component] tuples)
|
|
34
|
+
components/
|
|
35
|
+
elements/ Small reusable components + atomic content blocks
|
|
36
|
+
ButtonBlock.astro/.tsx Button block (renders <a> with variant)
|
|
37
|
+
sections/ Page-level section components
|
|
38
|
+
HomeHero.astro/.tsx Hero section
|
|
39
|
+
ContainerSection.astro/.tsx Container section (renders nested blocks)
|
|
40
|
+
FeatureGrid.astro/.tsx Feature grid (renders nested feature cards)
|
|
41
|
+
FeatureCard.astro/.tsx Feature card
|
|
42
|
+
StatsBar.astro/.tsx Stats bar
|
|
43
|
+
chrome/ Site chrome (Header, Footer, Nav)
|
|
44
|
+
Header.astro/.tsx Site header (renders navbar fragment)
|
|
45
|
+
Footer.astro/.tsx Site footer (renders footer fragment)
|
|
46
|
+
design-system/
|
|
47
|
+
styles.css Global stylesheet + Tailwind import
|
|
48
|
+
tokens/
|
|
49
|
+
colors.css Brand and semantic color tokens
|
|
50
|
+
typography.css Font families, sizes, weights, line heights
|
|
51
|
+
spacing.css Spacing scale
|
|
52
|
+
radii.css Border radius values
|
|
53
|
+
shadows.css Shadow definitions
|
|
54
|
+
components.css Component-level tokens
|
|
55
|
+
index.css Barrel import for all token files
|
|
56
|
+
app/ Framework routes (Next.js App Router)
|
|
57
|
+
layout.tsx Root layout (minimal, imports CSS only)
|
|
58
|
+
[[...slug]]/page.tsx Optional catch-all for all CMS pages
|
|
59
|
+
pages/ Framework routes (Astro file-based routing)
|
|
60
|
+
[...slug].astro Catch-all for all CMS pages
|
|
61
|
+
layouts/ Page layout wrappers (framework-specific)
|
|
62
|
+
stories/ Storybook stories (one per component tier)
|
|
63
|
+
fixtures/ Test fixture data (optional)
|
|
64
|
+
public/ Static assets (images, fonts, logos)
|
|
65
|
+
.agents/ Agent skills and guides
|
|
66
|
+
AGENTS.md Site-level agent guide
|
|
67
|
+
skills/
|
|
68
|
+
aci/ ACI onboarding and troubleshooting skill
|
|
69
|
+
authoring/ Content authoring and component development skill
|
|
70
|
+
migration/ Site migration skill
|
|
71
|
+
.aci/
|
|
72
|
+
compiled/ Generated compiled content (not checked in)
|
|
73
|
+
schemas/ Auto-generated content schemas
|
|
74
|
+
.storybook/ Storybook configuration
|
|
75
|
+
main.ts Framework-specific Storybook config
|
|
76
|
+
preview.ts Global decorators, theme switching
|
|
77
|
+
eslint-rules/
|
|
78
|
+
no-raw-tailwind-values.js Custom ESLint rule for design token enforcement
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Framework-Specific Paths
|
|
82
|
+
|
|
83
|
+
Only Next.js and Astro are supported. SvelteKit support has been removed.
|
|
84
|
+
|
|
85
|
+
### Next.js
|
|
86
|
+
|
|
87
|
+
| Concern | Path |
|
|
88
|
+
|---------|------|
|
|
89
|
+
| Routes | `src/app/[[...slug]]/page.tsx` (optional catch-all, `force-dynamic`) |
|
|
90
|
+
| Root layout | `src/app/layout.tsx` (minimal — imports CSS, no chrome) |
|
|
91
|
+
| Config | `next.config.ts` with `withAci()` |
|
|
92
|
+
| Registry | `src/cms/registry.ts` (shared, `createRegistry` with `[contract, component]` tuples) |
|
|
93
|
+
| Middleware | `src/middleware.ts` |
|
|
94
|
+
| Asset routes | `src/app/gradial/assets/[releaseId]/[...path]/route.ts` |
|
|
95
|
+
|
|
96
|
+
### Astro
|
|
97
|
+
|
|
98
|
+
| Concern | Path |
|
|
99
|
+
|---------|------|
|
|
100
|
+
| Routes | `src/pages/[...slug].astro` |
|
|
101
|
+
| Layout | `src/layouts/SiteLayout.astro` |
|
|
102
|
+
| Config | `astro.config.mjs` with `withAci()` |
|
|
103
|
+
| Registry | `src/cms/registry.ts` (shared, `createRegistry` with `[contract, component]` tuples) |
|
|
104
|
+
| Storybook | `.storybook/main.ts`, `.storybook/preview.ts` |
|
|
105
|
+
|
|
106
|
+
## Import Rules
|
|
107
|
+
|
|
108
|
+
1. **Contract files** import only `@gradial/aci`, `zod`, and shared schema
|
|
109
|
+
helpers. No React, Astro, CSS, browser globals, or runtime modules.
|
|
110
|
+
2. **Runtime components** may import contract types and framework code.
|
|
111
|
+
3. **Registry files** (`src/cms/registry.ts`) import both contracts and
|
|
112
|
+
runtime components — they are the wiring point.
|
|
113
|
+
4. Use `@gradial/aci` as the SDK package. Do not use `@baremetal/runtime`.
|
|
114
|
+
|
|
115
|
+
## Naming Conventions
|
|
116
|
+
|
|
117
|
+
| Type | Convention | Example |
|
|
118
|
+
|------|-----------|---------|
|
|
119
|
+
| Directories | lowercase, singular, no underscores | `sections/`, `chrome/` |
|
|
120
|
+
| Component files | PascalCase | `HomeHero.astro`, `FeatureShowcase.tsx` |
|
|
121
|
+
| Contract files | camelCase + `.contract.ts` | `homeHero.contract.ts` |
|
|
122
|
+
| Contract `id` | snake_case | `home_hero`, `feature_grid` |
|
|
123
|
+
| Test files | `*.test.ts` or `*.spec.ts` | `HomeHero.test.ts` |
|
|
124
|
+
| Story files | `*.stories.ts` | `HomeHero.stories.ts` |
|
|
125
|
+
| CSS files | lowercase, hyphen-separated | `colors.css`, `styles.css` |
|
|
126
|
+
| Block `id` in content | kebab-case with section context | `hero-heading`, `feature-cta` |
|
|
127
|
+
| Content `$type` | lowercase | `page`, `site`, `dam.assetRef` |
|
|
128
|
+
|
|
129
|
+
## Generated Files (Not Checked In)
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
.aci/ Compiled content and build artifacts
|
|
133
|
+
node_modules/ Dependencies
|
|
134
|
+
dist/ Astro build output
|
|
135
|
+
.next/ Next.js build output
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Package.json Scripts
|
|
139
|
+
|
|
140
|
+
Standard scripts across all frameworks:
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"scripts": {
|
|
145
|
+
"dev": "...",
|
|
146
|
+
"build": "...",
|
|
147
|
+
"typecheck": "...",
|
|
148
|
+
"aci:compile": "aci build --compile-only",
|
|
149
|
+
"content:compile": "aci build --skip-code --content ./.content --out ./.aci/compiled",
|
|
150
|
+
"aci:build": "aci build --content ./.content",
|
|
151
|
+
"aci:doctor": "aci doctor",
|
|
152
|
+
"aci:validate": "aci build --validate-only"
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Customer repos use `npm` as the package manager. The monorepo uses `pnpm`.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: migration
|
|
3
|
+
description: Migrate existing websites, Figma designs, or screenshots into ACI repos. Use when reverse-engineering a live site, extracting design tokens, modeling content from HTML, building components to match a visual source, or running a pixel-perfect migration workflow.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Migration — Reverse-Engineering into ACI
|
|
7
|
+
|
|
8
|
+
## Goal
|
|
9
|
+
|
|
10
|
+
A pixel-perfect migration. Phase 3 targets <10% visual variance per
|
|
11
|
+
section. Phase 4 targets <1% variance per element.
|
|
12
|
+
|
|
13
|
+
"We reused existing components and called it done" is not a successful
|
|
14
|
+
migration. Build new components and copy CSS 1:1 when needed. Visual
|
|
15
|
+
fidelity wins over design-system purity.
|
|
16
|
+
|
|
17
|
+
## Phases
|
|
18
|
+
|
|
19
|
+
### Phase 1: Style Transfer
|
|
20
|
+
|
|
21
|
+
1. Visually inspect the live source site using browser automation.
|
|
22
|
+
2. Describe the style visually first (color palette, type scale, spacing
|
|
23
|
+
rhythm, accent treatments) before touching code.
|
|
24
|
+
3. Inspect source CSS files to extract exact font families, color hex/rgb
|
|
25
|
+
values, and typography specs.
|
|
26
|
+
4. Scan source CSS for responsive breakpoints. Record the canonical
|
|
27
|
+
breakpoint set (e.g., `[360, 768, 1024, 1280, 1400]`).
|
|
28
|
+
5. Translate findings into design tokens and populate
|
|
29
|
+
`src/design-system/tokens/`.
|
|
30
|
+
6. Update base styling of the target: header, footer, logo, CTAs/buttons,
|
|
31
|
+
typography, accents.
|
|
32
|
+
- The customer logo must be downloaded and wired in Phase 1.
|
|
33
|
+
- Header and footer chrome colors must be extracted from source CSS,
|
|
34
|
+
not eyeballed.
|
|
35
|
+
- Font family must match.
|
|
36
|
+
7. Visually inspect the target site, note discrepancies, then fix base
|
|
37
|
+
styling iteratively.
|
|
38
|
+
|
|
39
|
+
### Phase 2: Content Modeling
|
|
40
|
+
|
|
41
|
+
**CONTENT DRIVES LAYOUT.** The content model in `_index.json` and
|
|
42
|
+
`site.json` describes every element you'll need to render.
|
|
43
|
+
|
|
44
|
+
Rules:
|
|
45
|
+
1. **Never hard-code content inside component code.** All content lives in
|
|
46
|
+
the JSON content model.
|
|
47
|
+
2. **Do not use bare atomic blocks for migration-phase content modeling.**
|
|
48
|
+
Stub out named components with named props — even if the component
|
|
49
|
+
doesn't exist yet. The content model is a contract for what components
|
|
50
|
+
must be built.
|
|
51
|
+
3. **Name components by inspecting the source HTML.** Look at class names
|
|
52
|
+
of root elements (e.g., `ancillary-nav`, `home-hero`) — that's your
|
|
53
|
+
component name.
|
|
54
|
+
4. **Extract copy from HTML markup, not from visual inspection.** Use HTML
|
|
55
|
+
parsing to pull exact strings. Agents drift when reading text off
|
|
56
|
+
screenshots.
|
|
57
|
+
5. **Classify imagery:** `<img>` child vs CSS `background-image` on the
|
|
58
|
+
root vs CSS `background-image` on a wrapper. This drives the component's
|
|
59
|
+
markup.
|
|
60
|
+
6. **Migrate copy verbatim.** Do not paraphrase, summarize, or invent
|
|
61
|
+
marketing claims, policy text, or CTAs.
|
|
62
|
+
7. **Stub every content element you observe.** Missing nav items, social
|
|
63
|
+
links, fine print — if it's on the source page, it's in the content
|
|
64
|
+
model.
|
|
65
|
+
|
|
66
|
+
For global elements (header, footer, nav), put their content under
|
|
67
|
+
`.content/config/site.json`, not in page content.
|
|
68
|
+
|
|
69
|
+
### Phase 3: Component Development
|
|
70
|
+
|
|
71
|
+
The default assumption is that **new components will be built.** If you
|
|
72
|
+
finish a section and built no new components, re-inspect for missed detail.
|
|
73
|
+
|
|
74
|
+
1. Work one page section at a time, starting with global sections (header,
|
|
75
|
+
footer).
|
|
76
|
+
2. Build an atomic component system for reused elements.
|
|
77
|
+
3. For each section: isolate single, reused, atomic elements first, then
|
|
78
|
+
build the broader section.
|
|
79
|
+
4. Use browser tools to visually compare source -> target.
|
|
80
|
+
5. Rely on visual descriptions first — describe layout, don't migrate
|
|
81
|
+
markup 1:1.
|
|
82
|
+
6. Build Storybook stories for every component/block.
|
|
83
|
+
7. For polish: if visual flourishes can't be expressed via existing
|
|
84
|
+
design-system primitives, build a new component or variant.
|
|
85
|
+
|
|
86
|
+
**Variance bar: <10% per section.** If a section is over 10%, you're
|
|
87
|
+
missing a structural element — fix that before moving on.
|
|
88
|
+
|
|
89
|
+
### Phase 4: Polish (Pixel-Level Visual Regression)
|
|
90
|
+
|
|
91
|
+
**<1% visual variance per element is the bar for "done."**
|
|
92
|
+
|
|
93
|
+
1. Go element by element, not section by section.
|
|
94
|
+
2. Inspect applied CSS on the source for each element using DevTools or
|
|
95
|
+
`getComputedStyle`.
|
|
96
|
+
3. Copy CSS verbatim into the target when needed. Fidelity wins over
|
|
97
|
+
abstraction.
|
|
98
|
+
4. Decide per element: extend the design system, or do a 1:1 CSS
|
|
99
|
+
migration?
|
|
100
|
+
5. Diff workflow: scope the visual-diff to a single element. Diff, fix
|
|
101
|
+
one delta, re-diff. Iterate until under 1%.
|
|
102
|
+
6. Compare at the same dimensions at every breakpoint from the source's
|
|
103
|
+
CSS breakpoint set.
|
|
104
|
+
7. Report prose discrepancies, not just percentages.
|
|
105
|
+
|
|
106
|
+
## Decision Principles
|
|
107
|
+
|
|
108
|
+
- **Visual fidelity first, markup parity never.** Match the visual, build
|
|
109
|
+
the structure idiomatically.
|
|
110
|
+
- **Atomic before composite.** Always migrate the smallest reusable unit
|
|
111
|
+
first.
|
|
112
|
+
- **Describe before implementing.** Write a prose description of what you
|
|
113
|
+
see before writing code.
|
|
114
|
+
- **Pixel fidelity beats design-system purity.** If the design system
|
|
115
|
+
can't express the source faithfully, build a new component or variant.
|
|
116
|
+
- **Migrate copy verbatim.** Never paraphrase or invent content.
|
|
117
|
+
- **One section at a time.** Resist the urge to scaffold everything at
|
|
118
|
+
once.
|
|
119
|
+
|
|
120
|
+
## Deep Dive: Analyzing Source Sites
|
|
121
|
+
|
|
122
|
+
Read `references/analyzing-source.md` for Playwright patterns, CSS
|
|
123
|
+
extraction, DOM inspection, interactive state probing, and responsive
|
|
124
|
+
inspection techniques.
|
|
125
|
+
|
|
126
|
+
## Deep Dive: Component Migration
|
|
127
|
+
|
|
128
|
+
Read `references/component-migration.md` for building components to spec,
|
|
129
|
+
header/footer inventory checklists, visual verification workflows, CSS
|
|
130
|
+
discipline rules, and interactivity approach.
|
|
131
|
+
|
|
132
|
+
## Deep Dive: Selector Map
|
|
133
|
+
|
|
134
|
+
Read `references/selector-map.md` for the source-to-target selector
|
|
135
|
+
mapping format that tracks every migrated element.
|
|
136
|
+
|
|
137
|
+
## Validation Gates
|
|
138
|
+
|
|
139
|
+
Before considering any change complete:
|
|
140
|
+
|
|
141
|
+
1. Run `npm run aci:validate` — content validation
|
|
142
|
+
2. Run `npm run typecheck && npm run build` — CI build steps
|
|
143
|
+
3. Run visual regression comparisons
|
|
144
|
+
4. Verify Storybook stories render correctly
|
|
145
|
+
|
|
146
|
+
## Asset Handling
|
|
147
|
+
|
|
148
|
+
Default: treat customer fonts and imagery as proprietary. Substitute the
|
|
149
|
+
closest licensed/open alternative and use neutral placeholders.
|
|
150
|
+
|
|
151
|
+
**Demo override:** If this is a demo/proof-of-concept, download assets and
|
|
152
|
+
serve them locally. Do NOT hot-link the customer's CDN.
|
|
153
|
+
|
|
154
|
+
1. Fonts: extract `@font-face` declarations, download font files, rewrite
|
|
155
|
+
URLs to local paths.
|
|
156
|
+
2. Images: download hero shots and section imagery, preserving `srcset`
|
|
157
|
+
variants.
|
|
158
|
+
3. Logos: download the customer's logo and reference locally.
|
|
159
|
+
4. Organize under a customer-scoped subdirectory
|
|
160
|
+
(e.g., `public/images/<customer>/`).
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# Analyzing Source Sites
|
|
2
|
+
|
|
3
|
+
This guide covers how to probe live sites for migration: Playwright
|
|
4
|
+
patterns, spatial relationships, interactive states, and CSS extraction.
|
|
5
|
+
|
|
6
|
+
## Visual Inspection
|
|
7
|
+
|
|
8
|
+
Before touching code, describe what you see:
|
|
9
|
+
|
|
10
|
+
1. Open the source site in a browser (or via Playwright/headless browser).
|
|
11
|
+
2. Take screenshots at desktop and mobile widths.
|
|
12
|
+
3. Write a prose description:
|
|
13
|
+
- Overall layout (header, hero, sections, footer)
|
|
14
|
+
- Color palette (primary, secondary, accents, surfaces)
|
|
15
|
+
- Type scale (heading sizes, body size, eyebrow/caption sizes)
|
|
16
|
+
- Spacing rhythm (tight vs airy, section padding)
|
|
17
|
+
- Accent treatments (gradients, borders, shadows)
|
|
18
|
+
- Interactive elements (nav dropdowns, carousels, tabs, accordions)
|
|
19
|
+
|
|
20
|
+
This description becomes the reference for Phase 1 style transfer.
|
|
21
|
+
|
|
22
|
+
## CSS Extraction
|
|
23
|
+
|
|
24
|
+
Inspect the source site's CSS to extract exact values:
|
|
25
|
+
|
|
26
|
+
### Colors
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
// Via Playwright evaluate
|
|
30
|
+
const styles = getComputedStyle(document.querySelector('.hero'));
|
|
31
|
+
console.log(styles.color, styles.backgroundColor, styles.borderColor);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or inspect the source CSS files directly:
|
|
35
|
+
- Look for `:root` or `body` custom properties
|
|
36
|
+
- Find the brand color palette
|
|
37
|
+
- Note semantic color usage (text, surface, border, accent)
|
|
38
|
+
|
|
39
|
+
### Typography
|
|
40
|
+
|
|
41
|
+
Extract:
|
|
42
|
+
- Font family declarations (`font-family`)
|
|
43
|
+
- Font weights used (`font-weight`)
|
|
44
|
+
- Font sizes at each heading level
|
|
45
|
+
- Line heights
|
|
46
|
+
- Letter spacing
|
|
47
|
+
- Font loading mechanism (`@font-face`, Google Fonts, etc.)
|
|
48
|
+
|
|
49
|
+
### Spacing
|
|
50
|
+
|
|
51
|
+
Look for:
|
|
52
|
+
- Container max-width
|
|
53
|
+
- Section vertical padding
|
|
54
|
+
- Card padding
|
|
55
|
+
- Gap values in grids/flex
|
|
56
|
+
- Header/footer height
|
|
57
|
+
|
|
58
|
+
### Responsive Breakpoints
|
|
59
|
+
|
|
60
|
+
Scan CSS for `@media` rules across loaded stylesheets:
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
// Via Playwright
|
|
64
|
+
const sheets = Array.from(document.styleSheets);
|
|
65
|
+
const breakpoints = new Set();
|
|
66
|
+
for (const sheet of sheets) {
|
|
67
|
+
try {
|
|
68
|
+
const rules = sheet.cssRules;
|
|
69
|
+
for (const rule of rules) {
|
|
70
|
+
if (rule instanceof CSSMediaRule) {
|
|
71
|
+
const match = rule.conditionText.match(/min-width:\s*(\d+)/);
|
|
72
|
+
if (match) breakpoints.add(parseInt(match[1]));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} catch (e) { /* cross-origin */ }
|
|
76
|
+
}
|
|
77
|
+
console.log([...breakpoints].sort((a, b) => a - b));
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Record the canonical breakpoint set. These are the only viewports for
|
|
81
|
+
visual-diff comparisons.
|
|
82
|
+
|
|
83
|
+
## DOM Inspection
|
|
84
|
+
|
|
85
|
+
### Classify each element
|
|
86
|
+
|
|
87
|
+
For every content element on the source page, classify:
|
|
88
|
+
|
|
89
|
+
1. **Is it text or an image?**
|
|
90
|
+
- Use `textContent` or `innerHTML` to extract copy.
|
|
91
|
+
- Check if eyebrows/badges/logos that look like text are actually
|
|
92
|
+
`<img>` elements.
|
|
93
|
+
|
|
94
|
+
2. **How is imagery rendered?**
|
|
95
|
+
- `<img>` child element
|
|
96
|
+
- CSS `background-image` on the root element
|
|
97
|
+
- CSS `background-image` on a wrapper element
|
|
98
|
+
- Check with: `getComputedStyle(el).backgroundImage`
|
|
99
|
+
|
|
100
|
+
3. **Is it interactive?**
|
|
101
|
+
- Click to check for dropdowns, tabs, carousels
|
|
102
|
+
- Scroll to check for sticky elements
|
|
103
|
+
- Look for `transform`, `overflow-x`, `scroll-snap-type` (carousel
|
|
104
|
+
indicators)
|
|
105
|
+
- Look for `animation`, `transition`, `keyframes` (animated elements)
|
|
106
|
+
|
|
107
|
+
### Extract copy from HTML
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
// Via Playwright
|
|
111
|
+
const hero = document.querySelector('.hero');
|
|
112
|
+
const headline = hero.querySelector('h1')?.textContent;
|
|
113
|
+
const description = hero.querySelector('p')?.textContent;
|
|
114
|
+
const cta = hero.querySelector('a')?.textContent;
|
|
115
|
+
const ctaHref = hero.querySelector('a')?.getAttribute('href');
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Do NOT extract copy from screenshots. Agents drift when reading text off
|
|
119
|
+
images. Always use HTML parsing.
|
|
120
|
+
|
|
121
|
+
### Identify components by class name
|
|
122
|
+
|
|
123
|
+
Look at the class names of root elements to determine component names:
|
|
124
|
+
- `.ancillary-nav` → `ancillaryNav` component
|
|
125
|
+
- `.home-hero` → `homeHero` component
|
|
126
|
+
- `.footer-zip-code` → `footerZipCode` component
|
|
127
|
+
|
|
128
|
+
Don't invent names from visual impressions. Use the source's class names
|
|
129
|
+
as the guide.
|
|
130
|
+
|
|
131
|
+
## Interactive State Inspection
|
|
132
|
+
|
|
133
|
+
### Navigation dropdowns
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
// Hover or click to reveal dropdowns
|
|
137
|
+
const navItem = document.querySelector('.nav-item-has-children');
|
|
138
|
+
navItem.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true }));
|
|
139
|
+
// Wait, then inspect the revealed dropdown
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Carousels
|
|
143
|
+
|
|
144
|
+
Check for:
|
|
145
|
+
- `transform: translateX` on a container
|
|
146
|
+
- `scroll-snap-type` CSS property
|
|
147
|
+
- Prev/next control buttons
|
|
148
|
+
- Carousel library class names (`slick`, `swiper`, `glide`)
|
|
149
|
+
|
|
150
|
+
A carousel migrated as a grid will fail visual-diff. Inspect before
|
|
151
|
+
deciding markup.
|
|
152
|
+
|
|
153
|
+
### Tabs
|
|
154
|
+
|
|
155
|
+
Click each tab to verify other panes exist and contain content. Note the
|
|
156
|
+
tab labels and pane content for the content model.
|
|
157
|
+
|
|
158
|
+
### Accordions
|
|
159
|
+
|
|
160
|
+
Click to expand/collapse. Note which items are expanded by default.
|
|
161
|
+
|
|
162
|
+
## Responsive Inspection
|
|
163
|
+
|
|
164
|
+
View the source at multiple viewport sizes:
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
// Via Playwright
|
|
168
|
+
await page.setViewportSize({ width: 360, height: 800 });
|
|
169
|
+
await page.screenshot({ path: 'source-mobile.png' });
|
|
170
|
+
|
|
171
|
+
await page.setViewportSize({ width: 768, height: 1024 });
|
|
172
|
+
await page.screenshot({ path: 'source-tablet.png' });
|
|
173
|
+
|
|
174
|
+
await page.setViewportSize({ width: 1280, height: 800 });
|
|
175
|
+
await page.screenshot({ path: 'source-desktop.png' });
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Note layout changes at each breakpoint:
|
|
179
|
+
- Does the nav switch to hamburger?
|
|
180
|
+
- Do multi-column grids stack?
|
|
181
|
+
- Does the hero image change aspect ratio?
|
|
182
|
+
- Are there mobile-only or desktop-only elements?
|
|
183
|
+
|
|
184
|
+
## Background Image Detection
|
|
185
|
+
|
|
186
|
+
Easy to miss because they're CSS `background-image` and don't show in a
|
|
187
|
+
child-element inventory:
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
// Check every section root
|
|
191
|
+
const sections = document.querySelectorAll('section, header, footer, .hero');
|
|
192
|
+
for (const section of sections) {
|
|
193
|
+
const bg = getComputedStyle(section).backgroundImage;
|
|
194
|
+
if (bg && bg !== 'none') {
|
|
195
|
+
console.log(section.className, 'has background image:', bg);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
If the source root carries the image, the target root must too — don't
|
|
201
|
+
substitute with a media-then-body card.
|
|
202
|
+
|
|
203
|
+
## Recording Findings
|
|
204
|
+
|
|
205
|
+
As you inspect, record:
|
|
206
|
+
1. Component names (from class names)
|
|
207
|
+
2. Content (from HTML parsing)
|
|
208
|
+
3. Imagery mode (img child vs background-image)
|
|
209
|
+
4. Interactive behavior (carousel, tabs, accordion, sticky)
|
|
210
|
+
5. CSS values for style transfer (colors, fonts, spacing)
|
|
211
|
+
6. Breakpoints for visual-diff
|
|
212
|
+
7. Selector pairs for the selector map
|
|
213
|
+
|
|
214
|
+
Update the selector map (`artifacts/source-vs-target/selector-map.json`)
|
|
215
|
+
every time you inspect an element.
|