@gradial/aci 0.1.20-preview.2 → 0.1.20

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 (249) hide show
  1. package/README.md +48 -110
  2. package/bin/{aci → aci-darwin-arm64} +0 -0
  3. package/bin/aci.js +99 -6
  4. package/dist/assets/index.d.ts +3 -3
  5. package/dist/assets/index.js +3 -3
  6. package/dist/astro/index.d.ts +14 -3
  7. package/dist/astro/index.js +24 -5
  8. package/dist/content/assets.d.ts +17 -0
  9. package/dist/content/assets.js +65 -0
  10. package/dist/content/index.d.ts +2 -0
  11. package/dist/content/index.js +2 -0
  12. package/dist/content/provider.d.ts +19 -0
  13. package/dist/content/provider.js +7 -0
  14. package/dist/content/resolve-slots.d.ts +9 -0
  15. package/dist/content/resolve-slots.js +24 -0
  16. package/dist/content/types.d.ts +1 -1
  17. package/dist/define-component.d.ts +1 -2
  18. package/dist/define-component.js +73 -11
  19. package/dist/define-layout.d.ts +2 -0
  20. package/dist/define-layout.js +3 -0
  21. package/dist/dev/content-watch.d.ts +37 -0
  22. package/dist/dev/content-watch.js +154 -0
  23. package/dist/dev/index.d.ts +24 -43
  24. package/dist/dev/index.js +4 -169
  25. package/dist/index.d.ts +14 -5
  26. package/dist/index.js +8 -8
  27. package/dist/next/asset-route.d.ts +2 -0
  28. package/dist/next/asset-route.js +12 -4
  29. package/dist/next/config.d.ts +2 -2
  30. package/dist/next/config.js +6 -6
  31. package/dist/next/content-watch.js +6 -1
  32. package/dist/next/index.d.ts +2 -2
  33. package/dist/next/index.js +2 -2
  34. package/dist/next/middleware.d.ts +7 -3
  35. package/dist/next/middleware.js +12 -7
  36. package/dist/next/page.d.ts +16 -15
  37. package/dist/next/page.js +30 -10
  38. package/dist/next/render.d.ts +5 -0
  39. package/dist/next/render.js +17 -0
  40. package/dist/next/root-layout.d.ts +4 -0
  41. package/dist/next/root-layout.js +5 -0
  42. package/dist/next/server.d.ts +14 -13
  43. package/dist/next/server.js +13 -3
  44. package/dist/providers/file.d.ts +2 -0
  45. package/dist/providers/file.js +61 -1
  46. package/dist/providers/s3.d.ts +1 -0
  47. package/dist/providers/s3.js +14 -1
  48. package/dist/react/Media.d.ts +24 -0
  49. package/dist/react/Media.js +30 -0
  50. package/dist/react/Picture.d.ts +12 -0
  51. package/dist/react/Picture.js +11 -0
  52. package/dist/react/VideoPlayer.d.ts +13 -0
  53. package/dist/react/{GradialVideoPlayer.js → VideoPlayer.js} +6 -5
  54. package/dist/react/index.d.ts +333 -3
  55. package/dist/react/index.js +89 -3
  56. package/dist/registry.d.ts +15 -0
  57. package/dist/registry.js +10 -0
  58. package/dist/testing/index.d.ts +3 -0
  59. package/dist/testing/index.js +15 -2
  60. package/dist/types/block-ref.d.ts +26 -0
  61. package/dist/types/block-ref.js +28 -0
  62. package/dist/types/component.d.ts +36 -41
  63. package/dist/types/config.d.ts +1 -2
  64. package/dist/types/image.d.ts +33 -20
  65. package/dist/types/image.js +42 -50
  66. package/dist/types/index.d.ts +1 -0
  67. package/dist/types/index.js +1 -0
  68. package/dist/types/link.d.ts +38 -0
  69. package/dist/types/link.js +58 -0
  70. package/dist/types/media.d.ts +16 -35
  71. package/dist/types/media.js +15 -84
  72. package/dist/types/page.d.ts +1 -2
  73. package/dist/types/render-mode.d.ts +0 -1
  74. package/dist/types/renderer.d.ts +1 -1
  75. package/dist/types/rich-text.d.ts +40 -0
  76. package/dist/types/rich-text.js +39 -0
  77. package/dist/types/video.d.ts +7 -13
  78. package/dist/types/video.js +3 -3
  79. package/package.json +32 -74
  80. package/src/cli/compile-registry.mjs +236 -59
  81. package/src/cli/validate-content.mjs +38 -75
  82. package/src/types/image.ts +79 -60
  83. package/templates/astro/template/.aci.yaml +27 -0
  84. package/templates/astro/template/.storybook/main.ts +79 -0
  85. package/templates/astro/template/.storybook/manager.ts +6 -0
  86. package/templates/astro/template/.storybook/preview.ts +33 -0
  87. package/templates/astro/template/astro.config.mjs +37 -0
  88. package/templates/astro/template/package.json.tmpl +41 -0
  89. package/templates/astro/template/src/cms/contracts/layouts/index.ts +18 -0
  90. package/templates/astro/template/src/cms/registry.ts +28 -0
  91. package/templates/astro/template/src/components/chrome/Footer.astro +107 -0
  92. package/templates/astro/template/src/components/chrome/Header.astro +94 -0
  93. package/templates/astro/template/src/components/elements/AtomicBlock.astro +15 -0
  94. package/templates/astro/template/src/components/elements/AtomicBlocks.astro +16 -0
  95. package/templates/astro/template/src/components/elements/Button.astro +51 -0
  96. package/templates/astro/template/src/components/elements/ButtonBlock.astro +25 -0
  97. package/templates/astro/template/src/components/elements/Container.astro +11 -0
  98. package/templates/astro/template/src/components/elements/Icon.astro +31 -0
  99. package/templates/astro/template/src/components/elements/Logo.astro +29 -0
  100. package/templates/astro/template/src/components/elements/RemoteImage.astro +41 -0
  101. package/templates/astro/template/src/components/sections/ContainerSection.astro +32 -0
  102. package/templates/astro/template/src/components/sections/FeatureCard.astro +23 -0
  103. package/templates/astro/template/src/components/sections/FeatureGrid.astro +35 -0
  104. package/templates/astro/template/src/components/sections/HomeHero.astro +51 -0
  105. package/templates/astro/template/src/components/sections/StatsBar.astro +33 -0
  106. package/templates/astro/template/src/design-system/styles.css +399 -0
  107. package/templates/astro/template/src/design-system/tokens/colors.css +60 -0
  108. package/templates/astro/template/src/design-system/tokens/components.css +69 -0
  109. package/templates/astro/template/src/design-system/tokens/index.css +6 -0
  110. package/templates/astro/template/src/design-system/tokens/radii.css +5 -0
  111. package/templates/astro/template/src/design-system/tokens/shadows.css +5 -0
  112. package/templates/astro/template/src/design-system/tokens/spacing.css +13 -0
  113. package/templates/astro/template/src/design-system/tokens/typography.css +24 -0
  114. package/templates/astro/template/src/env.d.ts +1 -0
  115. package/templates/astro/template/src/fixtures/atomicBlocks.ts +33 -0
  116. package/templates/astro/template/src/fixtures/composition.ts +31 -0
  117. package/templates/astro/template/src/fixtures/index.ts +17 -0
  118. package/templates/astro/template/src/fixtures/sections.ts +39 -0
  119. package/templates/astro/template/src/layouts/SiteLayout.astro +30 -0
  120. package/templates/astro/template/src/pages/[...slug].astro +61 -0
  121. package/templates/astro/template/src/render/RenderPage.astro +66 -0
  122. package/templates/astro/template/src/stories/CompositionStoryFrame.astro +15 -0
  123. package/templates/astro/template/src/stories/HomeHero.stories.ts +24 -0
  124. package/templates/astro/template/src/stories/SectionStoryFrame.astro +16 -0
  125. package/templates/astro/template/src/stories/StoryDocFrame.astro +31 -0
  126. package/templates/astro/template/tsconfig.json +11 -0
  127. package/templates/common/.agents/AGENTS.md +37 -0
  128. package/templates/common/.agents/skills/aci/SKILL.md +162 -0
  129. package/templates/common/.agents/skills/authoring/SKILL.md +590 -0
  130. package/templates/common/.agents/skills/authoring/references/block-registry.md +151 -0
  131. package/templates/common/.agents/skills/authoring/references/contracts.md +153 -0
  132. package/templates/common/.agents/skills/authoring/references/design-system.md +171 -0
  133. package/templates/common/.agents/skills/authoring/references/image-assets.md +73 -0
  134. package/templates/common/.agents/skills/authoring/references/repo-structure.md +157 -0
  135. package/templates/common/.agents/skills/migration/SKILL.md +160 -0
  136. package/templates/common/.agents/skills/migration/references/analyzing-source.md +215 -0
  137. package/templates/common/.agents/skills/migration/references/component-migration.md +200 -0
  138. package/templates/common/.agents/skills/migration/references/selector-map.md +31 -0
  139. package/templates/common/.content/.gradial-dam/blobs/sha256/7f/bf/7fbfc7fe230ff12688c496f660119e41d9725c4504d82e310c15665c73c09292 +0 -0
  140. package/templates/common/.content/.gradial-dam/blobs/sha256/a0/f5/a0f506689de9b15a7055f70103a3f02cd3ba105771ae2de6754df2ede1210d3a +0 -0
  141. package/templates/common/.content/.gradial-dam/blobs/sha256/dd/b7/ddb7e9642be08317bcd4b2bd26b58ba8d0d34dd7239e03e684a4f3634fa3845b +0 -0
  142. package/templates/common/.content/.gradial-dam/blobs/sha256/fb/32/fb3260e8286ea8231ea1c77b9c0be92d6edd9026565731eb14cfdcfd6b1b75b3 +0 -0
  143. package/templates/common/.content/config/site.json +192 -0
  144. package/templates/common/.content/dam/folders/seed/ast_site_about_hero/asset.json +9 -0
  145. package/templates/common/.content/dam/folders/seed/ast_site_about_hero/editorial.json +14 -0
  146. package/templates/common/.content/dam/folders/seed/ast_site_about_hero/governance.json +23 -0
  147. package/templates/common/.content/dam/folders/seed/ast_site_about_hero/versions/v0001.json +37 -0
  148. package/templates/common/.content/dam/folders/seed/ast_site_home_hero/asset.json +9 -0
  149. package/templates/common/.content/dam/folders/seed/ast_site_home_hero/editorial.json +14 -0
  150. package/templates/common/.content/dam/folders/seed/ast_site_home_hero/governance.json +23 -0
  151. package/templates/common/.content/dam/folders/seed/ast_site_home_hero/versions/v0001.json +37 -0
  152. package/templates/common/.content/fragments/navbar/_index.json +25 -0
  153. package/templates/common/.content/fragments/site-footer/_index.json +62 -0
  154. package/templates/common/.content/pages/about/_index.json +51 -0
  155. package/templates/common/.content/pages/home/_index.json +112 -0
  156. package/templates/common/.content/schemas/site.schema.json +123 -0
  157. package/templates/common/README.md.tmpl +45 -0
  158. package/templates/common/contracts/components/button.contract.ts +19 -0
  159. package/templates/common/contracts/components/container.contract.ts +19 -0
  160. package/templates/common/contracts/components/featureCard.contract.ts +15 -0
  161. package/templates/common/contracts/components/featureGrid.contract.ts +16 -0
  162. package/templates/common/contracts/components/homeHero.contract.ts +36 -0
  163. package/templates/common/contracts/components/index.ts +21 -0
  164. package/templates/common/contracts/components/siteFooter.contract.ts +45 -0
  165. package/templates/common/contracts/components/siteNavigation.contract.ts +30 -0
  166. package/templates/common/contracts/components/statsBar.contract.ts +19 -0
  167. package/templates/common/design-system/styles.css +346 -0
  168. package/templates/common/design-system/tokens/colors.css +110 -0
  169. package/templates/common/design-system/tokens/components.css +86 -0
  170. package/templates/common/design-system/tokens/index.css +6 -0
  171. package/templates/common/design-system/tokens/radii.css +5 -0
  172. package/templates/common/design-system/tokens/shadows.css +9 -0
  173. package/templates/common/design-system/tokens/spacing.css +26 -0
  174. package/templates/common/design-system/tokens/typography.css +32 -0
  175. package/templates/common/eslint-rules/no-raw-tailwind-values.js +127 -0
  176. package/templates/common/public/assets/Dwire-model.png +0 -0
  177. package/templates/common/public/assets/bare-metal-logo.png +0 -0
  178. package/templates/common/public/assets/meridian-logo.svg +8 -0
  179. package/templates/common/public/assets/seattle.avif +0 -0
  180. package/templates/nextjs/template/.aci.yaml +25 -0
  181. package/templates/nextjs/template/.storybook/main.ts +13 -0
  182. package/templates/nextjs/template/.storybook/preview.ts +34 -0
  183. package/templates/nextjs/template/eslint.config.mjs +36 -0
  184. package/templates/nextjs/template/next-env.d.ts +6 -0
  185. package/templates/nextjs/template/next.config.ts +8 -0
  186. package/templates/nextjs/template/package.json.tmpl +46 -0
  187. package/templates/nextjs/template/postcss.config.mjs +7 -0
  188. package/templates/nextjs/template/src/app/[[...slug]]/page.tsx +8 -0
  189. package/templates/nextjs/template/src/app/gradial/assets/[releaseId]/[...path]/route.ts +31 -0
  190. package/templates/nextjs/template/src/app/layout.tsx +29 -0
  191. package/templates/nextjs/template/src/cms/contracts/components/button.contract.ts +19 -0
  192. package/templates/nextjs/template/src/cms/contracts/components/container.contract.ts +20 -0
  193. package/templates/nextjs/template/src/cms/contracts/components/homeHero.contract.ts +36 -0
  194. package/templates/nextjs/template/src/cms/contracts/components/index.ts +15 -0
  195. package/templates/nextjs/template/src/cms/contracts/components/siteFooter.contract.ts +45 -0
  196. package/templates/nextjs/template/src/cms/contracts/components/siteNavigation.contract.ts +30 -0
  197. package/templates/nextjs/template/src/cms/contracts/layouts/index.ts +16 -0
  198. package/templates/nextjs/template/src/cms/registry.ts +28 -0
  199. package/templates/nextjs/template/src/components/chrome/Footer.tsx +86 -0
  200. package/templates/nextjs/template/src/components/chrome/Header.tsx +74 -0
  201. package/templates/nextjs/template/src/components/elements/AtomicBlock.tsx +13 -0
  202. package/templates/nextjs/template/src/components/elements/Button.tsx +40 -0
  203. package/templates/nextjs/template/src/components/elements/ButtonBlock.tsx +18 -0
  204. package/templates/nextjs/template/src/components/elements/Container.tsx +14 -0
  205. package/templates/nextjs/template/src/components/elements/Icon.tsx +29 -0
  206. package/templates/nextjs/template/src/components/elements/Logo.tsx +38 -0
  207. package/templates/nextjs/template/src/components/sections/ContainerSection.tsx +28 -0
  208. package/templates/nextjs/template/src/components/sections/FeatureCard.tsx +25 -0
  209. package/templates/nextjs/template/src/components/sections/FeatureGrid.tsx +36 -0
  210. package/templates/nextjs/template/src/components/sections/HomeHero.tsx +62 -0
  211. package/templates/nextjs/template/src/components/sections/StatsBar.tsx +30 -0
  212. package/templates/nextjs/template/src/middleware.ts +4 -0
  213. package/templates/nextjs/template/src/stories/Button.stories.tsx +38 -0
  214. package/templates/nextjs/template/src/stories/Header.stories.tsx +30 -0
  215. package/templates/nextjs/template/src/stories/HomeHero.stories.tsx +33 -0
  216. package/templates/nextjs/template/tsconfig.json +23 -0
  217. package/templates/nextjs/template/vercel.json +6 -0
  218. package/dist/content/cache.test.d.ts +0 -1
  219. package/dist/content/cache.test.js +0 -86
  220. package/dist/content/contract.d.ts +0 -83
  221. package/dist/content/contract.js +0 -104
  222. package/dist/content/tailwind-validator.d.ts +0 -6
  223. package/dist/content/tailwind-validator.js +0 -31
  224. package/dist/content/validation.d.ts +0 -108
  225. package/dist/content/validation.js +0 -184
  226. package/dist/next/preview-banner.d.ts +0 -4
  227. package/dist/next/preview-banner.js +0 -51
  228. package/dist/next/preview.d.ts +0 -7
  229. package/dist/next/preview.js +0 -37
  230. package/dist/react/GradialMedia.d.ts +0 -24
  231. package/dist/react/GradialMedia.js +0 -31
  232. package/dist/react/GradialPicture.d.ts +0 -14
  233. package/dist/react/GradialPicture.js +0 -30
  234. package/dist/react/GradialVideoPlayer.d.ts +0 -13
  235. package/dist/sveltekit/index.d.ts +0 -23
  236. package/dist/sveltekit/index.js +0 -62
  237. package/dist/sveltekit/preview.d.ts +0 -5
  238. package/dist/sveltekit/preview.js +0 -33
  239. package/src/cli/verify-renderer.mjs +0 -73
  240. package/src/types/component.ts +0 -59
  241. package/src/types/config.ts +0 -38
  242. package/src/types/data.ts +0 -47
  243. package/src/types/index.ts +0 -10
  244. package/src/types/layout.ts +0 -29
  245. package/src/types/media.ts +0 -125
  246. package/src/types/page.ts +0 -48
  247. package/src/types/render-mode.ts +0 -18
  248. package/src/types/renderer.ts +0 -83
  249. package/src/types/video.ts +0 -66
@@ -0,0 +1,39 @@
1
+ import type { KernelPageBlock } from '@gradial/aci/content';
2
+
3
+ export interface SectionStoryFixture {
4
+ id: string;
5
+ storybookId: string;
6
+ title: string;
7
+ direction?: 'ltr' | 'rtl';
8
+ block: KernelPageBlock;
9
+ }
10
+
11
+ export const sectionStoryFixtures: SectionStoryFixture[] = [
12
+ {
13
+ id: 'home-hero',
14
+ storybookId: 'sections-home-hero--default',
15
+ title: 'Home Hero',
16
+ block: {
17
+ id: 'fixture-home-hero',
18
+ component: 'home_hero',
19
+ props: {
20
+ eyebrow: 'Bare Metal Learn',
21
+ headline: 'Ship the same site on every framework.',
22
+ description: 'One content model, three renderers. Build once in Next.js, Astro, and SvelteKit—then prove parity with shared fixtures.',
23
+ ctaLabel: 'Get started',
24
+ ctaHref: '/docs',
25
+ image: {
26
+ $type: 'gradial.image',
27
+ assetId: 'fixture_seattle',
28
+ versionId: 'v0001',
29
+ alt: 'Seattle skyline at dusk',
30
+ sources: [
31
+ { src: '/assets/seattle.avif', width: 1920, height: 1280, type: 'image/avif' }
32
+ ]
33
+ }
34
+ }
35
+ }
36
+ }
37
+ ];
38
+
39
+ export const sectionVisualStoryIds = sectionStoryFixtures.map((fixture) => fixture.storybookId);
@@ -0,0 +1,30 @@
1
+ ---
2
+ import '../design-system/styles.css';
3
+
4
+ interface Props {
5
+ title: string;
6
+ description: string;
7
+ canonical?: string;
8
+ siteName?: string;
9
+ }
10
+
11
+ const { title, description, canonical, siteName = 'Gradial' } = Astro.props;
12
+ ---
13
+
14
+ <!doctype html>
15
+ <html lang="en">
16
+ <head>
17
+ <meta charset="utf-8" />
18
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
19
+ <title>{title}</title>
20
+ <link rel="icon" type="image/png" href="/assets/bare-metal-logo.png" />
21
+ <meta name="description" content={description} />
22
+ {canonical ? <link rel="canonical" href={canonical} /> : null}
23
+ <meta property="og:title" content={title} />
24
+ <meta property="og:description" content={description} />
25
+ <meta property="og:site_name" content={siteName} />
26
+ </head>
27
+ <body>
28
+ <slot />
29
+ </body>
30
+ </html>
@@ -0,0 +1,61 @@
1
+ ---
2
+ import { getGradialStaticPaths, getPageRuntimeRenderInput, createRenderChildren } from '@gradial/aci/astro';
3
+ import { normalizeRoute, routeMetadataForContent, resolveSlots } from '@gradial/aci/content';
4
+ import { FileContentProvider } from '@gradial/aci/providers/file';
5
+ import type { KernelPage, KernelSiteConfig, LayoutEntry, FragmentData } from '@gradial/aci/content';
6
+ import { registry } from '../cms/registry';
7
+ import SiteLayout from '../layouts/SiteLayout.astro';
8
+
9
+ export const getStaticPaths = getGradialStaticPaths;
10
+
11
+ const route = normalizeRoute(Astro.params.slug ? `/${Astro.params.slug}` : '/');
12
+ const runtimeInput = getPageRuntimeRenderInput(Astro.request);
13
+ let siteConfig: KernelSiteConfig;
14
+ let page: KernelPage;
15
+ let provider: FileContentProvider;
16
+ if (runtimeInput) {
17
+ siteConfig = runtimeInput.siteConfig as KernelSiteConfig;
18
+ page = runtimeInput.page as KernelPage;
19
+ } else {
20
+ provider = new FileContentProvider();
21
+ [siteConfig, page] = await Promise.all([
22
+ provider.getSiteConfig<KernelSiteConfig>(),
23
+ provider.getPage<KernelPage>(route),
24
+ ]);
25
+ }
26
+
27
+ const meta = routeMetadataForContent(siteConfig, page);
28
+ const layout = (runtimeInput?.layouts?.[page.layout] ?? await (provider ?? new FileContentProvider()).getLayout<LayoutEntry>(page.layout)) as LayoutEntry;
29
+ const resolvedSlots = await resolveSlots(
30
+ layout,
31
+ page?.regions || {},
32
+ async (id) => {
33
+ if (runtimeInput?.fragments?.[id]) return runtimeInput.fragments[id] as FragmentData;
34
+ return await (provider ?? new FileContentProvider()).getFragment<FragmentData>(id);
35
+ }
36
+ );
37
+
38
+ const renderChildren = createRenderChildren(registry);
39
+ ---
40
+
41
+ <SiteLayout title={meta.title} description={meta.description} canonical={meta.canonical} siteName={meta.siteName}>
42
+ {layout.slots.map((slot) => {
43
+ const blocks = resolvedSlots[slot.name];
44
+ if (!blocks?.length) return null;
45
+ const rendered = renderChildren(blocks);
46
+ if (slot.name === 'main') {
47
+ return (
48
+ <main id="content-main">
49
+ {rendered.map((child) => {
50
+ const Comp = child.Component as any;
51
+ return Comp ? <Comp {...child.props} /> : null;
52
+ })}
53
+ </main>
54
+ );
55
+ }
56
+ return rendered.map((child) => {
57
+ const Comp = child.Component as any;
58
+ return Comp ? <Comp {...child.props} /> : null;
59
+ });
60
+ })}
61
+ </SiteLayout>
@@ -0,0 +1,66 @@
1
+ ---
2
+ import SiteLayout from '../layouts/SiteLayout.astro';
3
+ import type { KernelPage, KernelSiteConfig } from '@gradial/aci/content';
4
+ import { registryLookup } from '@gradial/aci/astro';
5
+ import { registry } from '../cms/registry';
6
+ import Header from '../components/chrome/Header.astro';
7
+ import Footer from '../components/chrome/Footer.astro';
8
+
9
+ interface RenderInput {
10
+ route: string;
11
+ domain: string;
12
+ locale: string;
13
+ siteConfig: KernelSiteConfig;
14
+ page: KernelPage;
15
+ }
16
+
17
+ interface Props {
18
+ input: RenderInput;
19
+ }
20
+
21
+ const { input } = Astro.props;
22
+ const { siteConfig, page } = input;
23
+ const title = page.metadata?.title || siteConfig.seo?.title || siteConfig.title;
24
+ const description = page.metadata?.description || siteConfig.seo?.description || '';
25
+ const canonical = page.metadata?.canonical;
26
+ const siteName = siteConfig.seo?.siteName || siteConfig.title;
27
+
28
+ const footer = siteConfig.footer || {};
29
+ const blocks = page?.regions?.main || [];
30
+ ---
31
+
32
+ <SiteLayout {title} {description} {canonical} {siteName}>
33
+ <Header
34
+ brandHref={siteConfig.brandHref || '/'}
35
+ brandLabel={siteConfig.title || 'Gradial'}
36
+ brandLogo={siteConfig.brandLogo || null}
37
+ navigation={(siteConfig.navigation || []) as any}
38
+ utilities={(siteConfig.utilities || []) as any}
39
+ />
40
+
41
+ <main id="content-main">
42
+ {page && page.status === 'published' ? (
43
+ blocks.map((block) => {
44
+ // Astro's type checker can't validate dynamically resolved components,
45
+ // so we cast to any. The registry is type-safe at registration time.
46
+ const Component = registryLookup(registry, block.component) as any;
47
+ return Component ? <Component {...block.props} /> : null;
48
+ })
49
+ ) : (
50
+ <section class="mx-auto max-w-container-narrow px-[var(--spacing-container)] py-[var(--spacing-section-y)] text-center">
51
+ <h1 class="[font-family:var(--font-family-heading)] text-[length:var(--text-size-h2-mobile)] font-[var(--font-weight-semibold)] leading-heading md:text-[length:var(--text-size-h2)]">Page not found</h1>
52
+ <p class="mt-5 text-[length:var(--text-size-body)] text-[color:var(--color-fg-secondary)]">The requested content route is not available in the local content kernel.</p>
53
+ </section>
54
+ )}
55
+ </main>
56
+
57
+ <Footer
58
+ brandHref={siteConfig.brandHref || '/'}
59
+ brandLabel={siteConfig.title || 'Gradial'}
60
+ brandLogo={siteConfig.brandLogo || null}
61
+ social={(footer.social || []) as any}
62
+ columns={(footer.columns || []) as any}
63
+ legalLinks={(footer.legalLinks || []) as any}
64
+ copyright={String(footer.copyright || '')}
65
+ />
66
+ </SiteLayout>
@@ -0,0 +1,15 @@
1
+ ---
2
+ import type { KernelPageBlock } from '@gradial/aci/content';
3
+ import ContainerSection from '../components/sections/ContainerSection.astro';
4
+
5
+ interface Props {
6
+ block: KernelPageBlock;
7
+ direction?: 'ltr' | 'rtl';
8
+ }
9
+
10
+ const { block, direction = 'ltr' } = Astro.props;
11
+ ---
12
+
13
+ <div dir={direction}>
14
+ {block.component === 'container' ? <ContainerSection {...block.props} /> : null}
15
+ </div>
@@ -0,0 +1,24 @@
1
+ import { sectionStoryFixtures } from '../fixtures/sections';
2
+ import SectionStoryFrame from './SectionStoryFrame.astro';
3
+
4
+ const fixtureById = Object.fromEntries(
5
+ sectionStoryFixtures.map((fixture) => [fixture.id, fixture])
6
+ );
7
+
8
+ export default {
9
+ title: 'Sections/Home Hero',
10
+ component: SectionStoryFrame,
11
+ parameters: {
12
+ docs: {
13
+ description: {
14
+ component: 'Image-backed homepage hero with headline, body copy, and primary CTA.'
15
+ }
16
+ }
17
+ }
18
+ };
19
+
20
+ export const Default = {
21
+ args: {
22
+ block: fixtureById['home-hero'].block
23
+ }
24
+ };
@@ -0,0 +1,16 @@
1
+ ---
2
+ import type { KernelPageBlock } from '@gradial/aci/content';
3
+ import HomeHero from '../components/sections/HomeHero.astro';
4
+
5
+ interface Props {
6
+ block: KernelPageBlock;
7
+ direction?: 'ltr' | 'rtl';
8
+ }
9
+
10
+ const { block, direction = 'ltr' } = Astro.props;
11
+ const props = block.props as any;
12
+ ---
13
+
14
+ <div dir={direction}>
15
+ {block.component === 'home_hero' ? <HomeHero {...props} /> : null}
16
+ </div>
@@ -0,0 +1,31 @@
1
+ ---
2
+ import type { KernelPageBlock } from '@gradial/aci/content';
3
+ import CompositionStoryFrame from './CompositionStoryFrame.astro';
4
+
5
+ interface Props {
6
+ heading?: string;
7
+ description?: string;
8
+ block: KernelPageBlock;
9
+ direction?: 'ltr' | 'rtl';
10
+ }
11
+
12
+ const { heading, description, block, direction = 'ltr' } = Astro.props;
13
+ ---
14
+
15
+ <div>
16
+ {(heading || description) && (
17
+ <div class="theme-auto bg-surface-default px-8 pt-8 pb-4">
18
+ {heading && (
19
+ <h2 class="[font-family:var(--font-family-heading)] text-[length:var(--text-size-h3)] font-[var(--font-weight-semibold)] leading-heading text-fg">
20
+ {heading}
21
+ </h2>
22
+ )}
23
+ {description && (
24
+ <p class="mt-2 max-w-3xl text-[length:var(--text-size-body)] leading-body text-fg-muted">
25
+ {description}
26
+ </p>
27
+ )}
28
+ </div>
29
+ )}
30
+ <CompositionStoryFrame block={block} direction={direction} />
31
+ </div>
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "astro/tsconfigs/base",
3
+ "include": [
4
+ ".astro/types.d.ts",
5
+ "src/**/*"
6
+ ],
7
+ "exclude": [
8
+ "node_modules",
9
+ "dist"
10
+ ]
11
+ }
@@ -0,0 +1,37 @@
1
+ # ACI Site Agent Guide
2
+
3
+ This is an ACI (Agentic Content Infrastructure) frontend project. Agents
4
+ working in this repo should load skills before making changes.
5
+
6
+ ## Skills
7
+
8
+ | Skill | Load when |
9
+ |-------|-----------|
10
+ | `aci` | Onboarding, running builds, validating, troubleshooting |
11
+ | `authoring` | Creating or editing content, adding components, design tokens |
12
+ | `migration` | Reverse-engineering a live site or design into ACI |
13
+
14
+ Skills live in `.agents/skills/`. Each has a `SKILL.md` entry point and
15
+ `references/` for deeper topics.
16
+
17
+ ## Quick Reference
18
+
19
+ - Content lives in `.content/` as JSON.
20
+ - Contracts live in `src/cms/contracts/` (Zod schemas, no framework imports).
21
+ - Runtime components live in `src/components/` (framework code).
22
+ - Registry lives in `src/cms/registry.ts` (`createRegistry` with `[contract, component]` tuples).
23
+ - Compiled output goes to `.aci/compiled/` (generated, not checked in).
24
+ - Framework integration via `withAci()` in the framework config.
25
+ - Supported frameworks: Astro and Next.js (SvelteKit removed).
26
+
27
+ ## Commands
28
+
29
+ ```bash
30
+ npm install
31
+ npm run dev # Start dev server
32
+ npm run aci:validate # Validate content
33
+ npm run aci:compile # Compile contracts
34
+ npm run content:compile # Compile content
35
+ npm run build # Framework build
36
+ npm run aci:doctor # Health check
37
+ ```
@@ -0,0 +1,162 @@
1
+ ---
2
+ name: aci
3
+ description: Onboarding, running builds, validating, and troubleshooting ACI sites. Use when understanding ACI architecture, running CLI commands, diagnosing build errors, or checking project health.
4
+ ---
5
+
6
+ # ACI — Onboarding and Troubleshooting
7
+
8
+ ## How ACI Works
9
+
10
+ ```
11
+ .content/ ──aci build──▶ .aci/compiled/ ──framework build──▶ dist/
12
+ JSON compiled JSON static HTML
13
+ ```
14
+
15
+ 1. You author content as JSON files under `.content/`.
16
+ 2. The `aci` CLI compiles contracts (component schemas) and content into
17
+ `.aci/compiled/`.
18
+ 3. Your framework (Astro or Next.js) reads the compiled content at build
19
+ or render time and produces HTML.
20
+
21
+ ## Contracts vs Runtime
22
+
23
+ The most important architectural rule: **contracts are separate from
24
+ runtime components**.
25
+
26
+ | Layer | Location | Imports | Purpose |
27
+ |-------|----------|---------|---------|
28
+ | Contracts | `src/cms/contracts/` | `@gradial/aci`, `zod` only | Component IDs, Zod schemas, image slots, block refs |
29
+ | Runtime | `src/components/` | Framework code, CSS, contract types | Actual UI components (Astro, React) |
30
+
31
+ The ACI compiler imports only `src/cms/contracts/**`. Contract files must
32
+ never import framework components, CSS, browser globals, or runtime
33
+ modules. Runtime components may import contract types to keep props
34
+ connected to schemas.
35
+
36
+ ## Framework Integration
37
+
38
+ Each framework uses a packaged SDK adapter for ACI dev/build behavior:
39
+
40
+ - **Astro**: `withAci()` in `astro.config.mjs`
41
+ - **Next.js**: `withAci()` in `next.config.ts`
42
+
43
+ These adapters own canonical ACI behavior: content watch/reload, local DAM
44
+ derivative serving at `/.gradial-dam/*`, and asset path rewrites. Do not
45
+ copy site-local middleware for these concerns.
46
+
47
+ Only Next.js and Astro are supported. SvelteKit support has been removed.
48
+
49
+ ## CLI Commands
50
+
51
+ All commands run from the site directory (where `.aci.yaml` lives).
52
+
53
+ | Command | Purpose |
54
+ |---------|---------|
55
+ | `npm run aci:compile` | Compile contract registry. Run after changing contracts. |
56
+ | `npm run content:compile` | Compile content from `.content/` into `.aci/compiled/`. |
57
+ | `npm run aci:validate` | Validate content against schemas without building. |
58
+ | `npm run aci:doctor` | Check project health: config, content, schemas, routes. |
59
+ | `npm run aci:build` | Full build: contracts + content + framework. |
60
+ | `npm run typecheck` | TypeScript type checking. |
61
+ | `npm run build` | Framework build. |
62
+ | `npm run dev` | Start dev server with content hot-reload. |
63
+
64
+ ## Development Workflow
65
+
66
+ ### Start dev server
67
+
68
+ ```bash
69
+ npm install
70
+ npm run aci:compile
71
+ npm run dev
72
+ ```
73
+
74
+ The dev server watches for content changes and re-compiles automatically
75
+ via the framework's ACI adapter. Edit `.content/` files and see changes
76
+ in the browser.
77
+
78
+ ### Full local build
79
+
80
+ ```bash
81
+ npm run aci:compile
82
+ npm run content:compile
83
+ npm run typecheck
84
+ npm run build
85
+ ```
86
+
87
+ ### Content editing loop
88
+
89
+ 1. Edit `.content/pages/{slug}/_index.json` or `.content/config/site.json`.
90
+ 2. Run `npm run aci:validate` to check content is valid.
91
+ 3. Run `npm run content:compile` to compile content.
92
+ 4. Run `npm run build` to build the site.
93
+ 5. Check the output for your changes.
94
+
95
+ ## Test Order (Fastest to Slowest)
96
+
97
+ 1. `npm run aci:validate` — content validation
98
+ 2. `npm run aci:compile` — contract compile
99
+ 3. `npm run typecheck` — TypeScript
100
+ 4. `npm run content:compile` — content compile
101
+ 5. `npm run build` — framework build
102
+ 6. `npm run build:storybook` — Storybook (if configured)
103
+
104
+ ## Troubleshooting
105
+
106
+ ### "Unknown component" error during content compile
107
+
108
+ The content JSON references a `component` name that is not in the contract
109
+ barrel (`src/cms/contracts/components/index.ts`). Add the contract or fix
110
+ the content.
111
+
112
+ ### Contract compile fails with CSS/framework import error
113
+
114
+ A contract file is importing runtime code. Contract files may only import
115
+ `@gradial/aci`, `zod`, and shared schema helpers. Move the import to a
116
+ runtime component file.
117
+
118
+ ### Images not loading in dev
119
+
120
+ Check that `ACI_CONTENT_ROOT` is set and the framework adapter is wired.
121
+ Compiled DAM derivatives should be served at `/.gradial-dam/*`. Verify:
122
+
123
+ ```bash
124
+ curl -I http://localhost:4321/.gradial-dam/derivatives/sha256/.../image.webp
125
+ ```
126
+
127
+ Expected: `200` with `Content-Type: image/webp` (or similar image type).
128
+
129
+ ### `aci` command not found
130
+
131
+ The CLI is provided by `@gradial/aci`. Run `npm install` first. The npm
132
+ scripts use `node ./node_modules/@gradial/aci/bin/aci.js` to find it
133
+ locally.
134
+
135
+ ### Content value not surviving compile/build
136
+
137
+ If a value doesn't survive the round-trip, check:
138
+ - The field is in the contract schema (or it will be stripped).
139
+ - The field name matches between content JSON and contract schema.
140
+ - The field type matches (string vs number vs object).
141
+
142
+ ## Key Files
143
+
144
+ | File | Purpose |
145
+ |------|---------|
146
+ | `.aci.yaml` | ACI config: contract paths, framework, routes, capabilities |
147
+ | `src/cms/contracts/components/index.ts` | Component contract barrel |
148
+ | `src/cms/contracts/layouts/index.ts` | Layout contract barrel |
149
+ | `src/cms/registry.ts` | Component registry (`createRegistry` with `[contract, component]` tuples) |
150
+ | `src/components/` | Runtime component implementations |
151
+ | `src/design-system/` | Design tokens and global styles |
152
+ | `.content/` | Local content for development |
153
+
154
+ ## Deep Dive: Authoring
155
+
156
+ Read `.agents/skills/authoring/SKILL.md` for content authoring, component
157
+ development, design tokens, and the full contract/runtime split.
158
+
159
+ ## Deep Dive: Migration
160
+
161
+ Read `.agents/skills/migration/SKILL.md` for reverse-engineering a live
162
+ site or design into ACI.