@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.
- package/README.md +48 -110
- 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 +14 -3
- package/dist/astro/index.js +24 -5
- package/dist/content/assets.d.ts +17 -0
- package/dist/content/assets.js +65 -0
- package/dist/content/index.d.ts +2 -0
- package/dist/content/index.js +2 -0
- package/dist/content/provider.d.ts +19 -0
- package/dist/content/provider.js +7 -0
- package/dist/content/resolve-slots.d.ts +9 -0
- package/dist/content/resolve-slots.js +24 -0
- package/dist/content/types.d.ts +1 -1
- package/dist/define-component.d.ts +1 -2
- package/dist/define-component.js +73 -11
- package/dist/define-layout.d.ts +2 -0
- package/dist/define-layout.js +3 -0
- 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 -5
- package/dist/index.js +8 -8
- package/dist/next/asset-route.d.ts +2 -0
- package/dist/next/asset-route.js +12 -4
- package/dist/next/config.d.ts +2 -2
- package/dist/next/config.js +6 -6
- 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 +7 -3
- package/dist/next/middleware.js +12 -7
- package/dist/next/page.d.ts +16 -15
- package/dist/next/page.js +30 -10
- package/dist/next/render.d.ts +5 -0
- package/dist/next/render.js +17 -0
- package/dist/next/root-layout.d.ts +4 -0
- package/dist/next/root-layout.js +5 -0
- package/dist/next/server.d.ts +14 -13
- package/dist/next/server.js +13 -3
- package/dist/providers/file.d.ts +2 -0
- package/dist/providers/file.js +61 -1
- package/dist/providers/s3.d.ts +1 -0
- package/dist/providers/s3.js +14 -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 +15 -0
- package/dist/registry.js +10 -0
- package/dist/testing/index.d.ts +3 -0
- package/dist/testing/index.js +15 -2
- package/dist/types/block-ref.d.ts +26 -0
- package/dist/types/block-ref.js +28 -0
- package/dist/types/component.d.ts +36 -41
- package/dist/types/config.d.ts +1 -2
- 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/page.d.ts +1 -2
- package/dist/types/render-mode.d.ts +0 -1
- 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 +32 -74
- package/src/cli/compile-registry.mjs +236 -59
- package/src/cli/validate-content.mjs +38 -75
- package/src/types/image.ts +79 -60
- package/templates/astro/template/.aci.yaml +27 -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 +25 -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/cache.test.d.ts +0 -1
- package/dist/content/cache.test.js +0 -86
- 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 -184
- package/dist/next/preview-banner.d.ts +0 -4
- package/dist/next/preview-banner.js +0 -51
- package/dist/next/preview.d.ts +0 -7
- package/dist/next/preview.js +0 -37
- 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 -23
- package/dist/sveltekit/index.js +0 -62
- package/dist/sveltekit/preview.d.ts +0 -5
- package/dist/sveltekit/preview.js +0 -33
- package/src/cli/verify-renderer.mjs +0 -73
- package/src/types/component.ts +0 -59
- package/src/types/config.ts +0 -38
- 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 -48
- package/src/types/render-mode.ts +0 -18
- package/src/types/renderer.ts +0 -83
- 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,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.
|