create-ailk 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -0
- package/component-catalog.json +279 -45
- package/dist/add-module.d.ts +20 -0
- package/dist/add-module.js +43 -7
- package/dist/add-route.d.ts +56 -0
- package/dist/add-route.js +286 -0
- package/dist/apply-design-md.d.ts +7 -0
- package/dist/apply-design-md.js +50 -0
- package/dist/apply-design.d.ts +64 -0
- package/dist/apply-design.js +273 -0
- package/dist/claude-md.d.ts +111 -0
- package/dist/claude-md.js +334 -0
- package/dist/cli.js +92 -4
- package/dist/derive-architecture.js +41 -36
- package/dist/design-compile.d.ts +71 -0
- package/dist/design-compile.js +98 -0
- package/dist/design-package.d.ts +83 -0
- package/dist/design-package.js +468 -0
- package/dist/design-presets.d.ts +86 -0
- package/dist/design-presets.js +642 -0
- package/dist/design-scaffold.d.ts +76 -0
- package/dist/design-scaffold.js +220 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -1
- package/dist/legacy-nav-renderers.d.ts +45 -0
- package/dist/legacy-nav-renderers.js +545 -0
- package/dist/lib/auth-secret-file.d.ts +19 -0
- package/dist/lib/auth-secret-file.js +112 -0
- package/dist/lib/design-checks.d.ts +78 -0
- package/dist/lib/design-checks.js +174 -0
- package/dist/lib/license-key-files.d.ts +9 -0
- package/dist/lib/license-key-files.js +2 -2
- package/dist/lib/module-license-gate.d.ts +19 -9
- package/dist/lib/module-license-gate.js +19 -8
- package/dist/lib/render-verdict.d.ts +52 -0
- package/dist/lib/render-verdict.js +77 -0
- package/dist/lib/scaffold-render-sweep.d.ts +105 -0
- package/dist/lib/scaffold-render-sweep.js +236 -0
- package/dist/module-architecture.d.ts +19 -16
- package/dist/module-architecture.js +64 -21
- package/dist/parse-args.d.ts +12 -2
- package/dist/parse-args.js +74 -13
- package/dist/programmatic.d.ts +30 -6
- package/dist/programmatic.js +206 -17
- package/dist/site-chrome.d.ts +19 -9
- package/dist/site-chrome.js +23 -13
- package/dist/site-manifest.d.ts +25 -0
- package/dist/site-manifest.js +254 -0
- package/dist/site-roster.d.ts +41 -0
- package/dist/site-roster.js +141 -8
- package/dist/starter-grid.d.ts +32 -16
- package/dist/starter-grid.js +129 -33
- package/dist/surfaces.d.ts +41 -9
- package/dist/surfaces.js +200 -83
- package/dist/template-manifest.d.ts +30 -13
- package/dist/template-manifest.js +49 -24
- package/package.json +5 -4
- package/site-templates/_base/content/en/UseCase/persona-1.mdx +7 -6
- package/site-templates/_base/content/en/UseCase/persona-2.mdx +7 -6
- package/site-templates/_base/content/en/UseCase/persona-3.mdx +7 -6
- package/site-templates/{minimalism-site/TEMPLATE-MANIFEST.json → aliases/minimalism-site.TEMPLATE-MANIFEST.json} +72 -40
- package/site-templates/designs/minimalism/DESIGN.md +98 -6
- package/site-templates/designs/minimalism/sample/README.md +48 -0
- package/site-templates/designs/standard/DESIGN.md +98 -6
- package/site-templates/marketing-site/DESIGN.md +98 -6
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +60 -27
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +50 -30
- package/site-templates/marketing-site-free/DESIGN.md +98 -6
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +60 -24
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +44 -27
- package/site-templates/marketing-site-free/ailk-template.json +1 -1
- package/site-templates/saas-product/DESIGN.md +98 -6
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.json +127 -18
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +74 -20
- package/site-templates/shapes/local-business-service/ailk-template.json +1 -1
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +127 -18
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +74 -20
- package/site-templates/shapes/organization-service/ailk-template.json +1 -1
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +127 -18
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +75 -21
- package/site-templates/shapes/person-service/ailk-template.json +1 -1
- package/site-templates/shapes/person-service/content/en/AboutPage/about.mdx +1 -1
- package/site-templates/shapes/person-service/content/en/HomePage/home.mdx +2 -2
- package/site-templates/shapes/person-service/content/en/PortfolioList/portfolio.mdx +4 -2
- package/site-templates/shapes/person-service/content/en/ServicesList/services.mdx +1 -1
- package/templates/.claude/rules/architecture.md +7 -0
- package/templates/.claude/skills/README.md +3 -2
- package/templates/.claude/skills/add-auth/references/env-vars.md +22 -15
- package/templates/.claude/skills/add-auth/references/oauth-app-setup.md +3 -2
- package/templates/.claude/skills/add-page/SKILL.md +241 -238
- package/templates/.claude/skills/add-page/references/page-types.md +85 -76
- package/templates/.claude/skills/add-page/scripts/site-pages.mjs +87 -0
- package/templates/.claude/skills/add-page/templates/comparison-page.mdx.tmpl +99 -0
- package/templates/.claude/skills/add-page/templates/content.mdx.tmpl +8 -18
- package/templates/.claude/skills/add-page/templates/flow-landing-page.mdx.tmpl +43 -0
- package/templates/.claude/skills/add-page/templates/report-page.mdx.tmpl +52 -0
- package/templates/.claude/skills/add-page/templates/reports-list.mdx.tmpl +38 -0
- package/templates/.claude/skills/check-site/SKILL.md +23 -0
- package/templates/.claude/skills/fill-page/SKILL.md +26 -7
- package/templates/.claude/skills/fill-page/profiles/plumbing.yaml +1 -1
- package/templates/.claude/skills/setup-deploy/references/env-vars-template.md +28 -11
- package/templates/.claude/skills/update-page/SKILL.md +117 -0
- package/templates/.claude/skills/update-page/scripts/update-page.ts +640 -0
- package/templates/.claude/skills/update-page/templates/redirects.mjs.tmpl +31 -0
- package/templates/.claude/skills/upgrade-plan/SKILL.md +12 -8
- package/templates/.github/workflows/ci.yml +4 -0
- package/templates/.prettierignore +1 -0
- package/templates/CLAUDE.md +146 -103
- package/templates/DESIGN.md +98 -6
- package/templates/README.md +50 -38
- package/templates/apps/api/.env.example +2 -1
- package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +2 -0
- package/templates/apps/api/src/__tests__/server.test.ts +116 -0
- package/templates/apps/api/src/lib/stripe.ts +9 -0
- package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +140 -0
- package/templates/apps/api/src/middleware/auth.ts +54 -0
- package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +5 -2
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +628 -0
- package/templates/apps/api/src/routes/checkout/sessions.ts +222 -24
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +1 -1
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +5 -1
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +521 -20
- package/templates/apps/api/src/routes/webhooks/stripe.ts +124 -32
- package/templates/apps/api/src/server.ts +28 -0
- package/templates/apps/api/src/services/__tests__/revalidation.test.ts +90 -15
- package/templates/apps/api/src/services/checkout-buyer.ts +72 -0
- package/templates/apps/api/src/services/revalidation.ts +60 -15
- package/templates/apps/mcp/__tests__/tools/create_project.test.ts +30 -24
- package/templates/apps/mcp/src/tools/purchase.ts +4 -2
- package/templates/apps/web/.env.example +13 -0
- package/templates/apps/web/CLAUDE.md +22 -28
- package/templates/apps/web/app/[locale]/(auth)/layout.tsx +1 -1
- package/templates/apps/web/app/[locale]/(authed)/leads/__tests__/page.test.tsx +24 -0
- package/templates/apps/web/app/[locale]/(authed)/leads/page.tsx +17 -6
- package/templates/apps/web/app/[locale]/[slug]/[detail]/__tests__/page.test.tsx +110 -0
- package/templates/apps/web/app/[locale]/[slug]/[detail]/page.tsx +60 -0
- package/templates/apps/web/app/[locale]/[slug]/page.tsx +1 -1
- package/templates/apps/web/app/[locale]/alternatives/__tests__/page.test.tsx +161 -0
- package/templates/apps/web/app/[locale]/alternatives/page.tsx +104 -0
- package/templates/apps/web/app/[locale]/{use-cases → for}/[slug]/page.tsx +4 -3
- package/templates/apps/web/app/[locale]/for/__tests__/page-renderer-migration.test.tsx +73 -0
- package/templates/apps/web/app/[locale]/{use-cases → for}/page.tsx +8 -7
- package/templates/apps/web/app/[locale]/glossary/page.tsx +1 -1
- package/templates/apps/web/app/[locale]/layout.tsx +35 -19
- package/templates/apps/web/app/[locale]/newsletter/page.tsx +1 -1
- package/templates/apps/web/app/[locale]/portfolio/[slug]/page.tsx +1 -1
- package/templates/apps/web/app/[locale]/portfolio/page.tsx +1 -1
- package/templates/apps/web/app/[locale]/vs/[slug]/__tests__/page.test.tsx +112 -0
- package/templates/apps/web/app/[locale]/vs/[slug]/page.tsx +70 -0
- package/templates/apps/web/app/api/revalidate/__tests__/route.test.ts +236 -44
- package/templates/apps/web/app/api/revalidate/route.ts +78 -36
- package/templates/apps/web/lib/__tests__/site-brand.test.ts +79 -0
- package/templates/apps/web/lib/__tests__/site-theme.test.ts +104 -11
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +21 -4
- package/templates/apps/web/lib/locale-guard.ts +18 -0
- package/templates/apps/web/lib/meet-placeholder.ts +5 -0
- package/templates/apps/web/lib/nav-config.ts +14 -13
- package/templates/apps/web/lib/site-brand.tsx +13 -9
- package/templates/apps/web/lib/site-logo.tsx +36 -0
- package/templates/apps/web/lib/site-theme.ts +46 -26
- package/templates/apps/web/messages/en.json +23 -9
- package/templates/apps/web/middleware.ts +28 -4
- package/templates/content/en/BookCall/book-a-call.mdx +80 -0
- package/templates/content/en/BookCall/onsite-estimate.mdx +56 -0
- package/templates/content/en/BookCall/onsite-service.mdx +56 -0
- package/templates/content/en/BookCall/start-project.mdx +56 -0
- package/templates/content/en/ContactPage/contact.mdx +40 -1
- package/templates/content/en/HomePage/home.mdx +2 -6
- package/templates/content/en/LandingPage/meet.mdx +59 -0
- package/templates/content/en/UseCasesList/{use-cases.mdx → for.mdx} +19 -18
- package/templates/database/CHANGELOG.md +7 -0
- package/templates/database/package.json +1 -1
- package/templates/package.json +2 -1
- package/templates/tools/check-claude-md.ts +128 -0
- package/versions.json +33 -33
- package/site-templates/_base/content/en/BookCall/book-call.mdx +0 -52
- package/site-templates/minimalism-site/DESIGN.md +0 -162
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +0 -458
- package/site-templates/minimalism-site/ailk-template.json +0 -23
- package/site-templates/minimalism-site/content/en/AboutPage/about.mdx +0 -110
- package/site-templates/minimalism-site/content/en/BookCall/book-call.mdx +0 -52
- package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +0 -34
- package/site-templates/minimalism-site/content/en/FAQPage/faq.mdx +0 -57
- package/site-templates/minimalism-site/content/en/LandingPage/referral.mdx +0 -77
- package/site-templates/minimalism-site/content/en/LandingPage/reports.mdx +0 -73
- package/site-templates/minimalism-site/content/en/PurchasePolicyPage/purchase-policy.mdx +0 -123
- package/site-templates/minimalism-site/content/en/ReportPage/annual-letter-2024.mdx +0 -52
- package/site-templates/minimalism-site/content/en/ReportPage/field-notes-2023.mdx +0 -52
- package/site-templates/minimalism-site/content/en/ReportPage/platform-shift-2025.mdx +0 -52
- package/site-templates/minimalism-site/content/en/ReportPage/state-of-the-market-2026.mdx +0 -52
- package/site-templates/minimalism-site/content/en/Service/first-engagement.mdx +0 -38
- package/site-templates/minimalism-site/content/en/Service/second-engagement.mdx +0 -38
- package/site-templates/minimalism-site/content/en/Service/third-engagement.mdx +0 -38
- package/site-templates/minimalism-site/content/en/ServicesList/services.mdx +0 -73
- package/site-templates/minimalism-site/flows/referral.flow.json +0 -71
- package/site-templates/minimalism-site/provenance.json +0 -4
- package/templates/.claude/skills/add-page/templates/route.tsx.tmpl +0 -28
- package/templates/apps/web/app/[locale]/book-a-call/page.tsx +0 -50
- package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +0 -72
- /package/site-templates/{minimalism-site → designs/minimalism/sample}/content/en/HomePage/home.mdx +0 -0
- /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-1.svg +0 -0
- /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-2.svg +0 -0
- /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-3.svg +0 -0
- /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-4.svg +0 -0
- /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-5.svg +0 -0
- /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/avatar-placeholder-6.svg +0 -0
- /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/hero-backdrop.svg +0 -0
- /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-1.svg +0 -0
- /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-2.svg +0 -0
- /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/logo-placeholder-3.svg +0 -0
- /package/site-templates/{minimalism-site/assets → designs/minimalism/sample/public}/wordmark-placeholder.svg +0 -0
|
@@ -20,6 +20,13 @@ The skill resolves in this order:
|
|
|
20
20
|
3. **Free-text hint match** — "company story" / "team" → `AboutPage`.
|
|
21
21
|
4. **Ask** — if nothing matches, ask the consumer rather than guessing.
|
|
22
22
|
|
|
23
|
+
**Level** and **Module** name what a page type needs: the module whose
|
|
24
|
+
code renders it, and the level that module comes with. Read the site's
|
|
25
|
+
`.ailk-site-manifest.json` `modules` first — a page type whose Module is
|
|
26
|
+
not in that list is one this site cannot render, so it is never offered;
|
|
27
|
+
name its module and level instead (the `upgrade-plan` skill explains the
|
|
28
|
+
levels). The level is the module's, never a claim about this site's key.
|
|
29
|
+
|
|
23
30
|
`<slug>` in a route below is the page's own slug (e.g. `hello-world`);
|
|
24
31
|
`<Type>` families using two-layer builders route supplementary schema
|
|
25
32
|
through the `schema:` frontmatter override — see this skill's
|
|
@@ -28,88 +35,90 @@ override contract.
|
|
|
28
35
|
|
|
29
36
|
## Core
|
|
30
37
|
|
|
31
|
-
| Key | `@type` | Family | Chassis | Route |
|
|
32
|
-
| --- | --- | --- | --- | --- |
|
|
33
|
-
| `HomePage` | `HomePage` | core | home | / |
|
|
34
|
-
| `AboutPage` | `AboutPage` | core | detail | /about |
|
|
35
|
-
| `ContactPage` | `ContactPage` | core | detail | /contact |
|
|
36
|
-
| `PrivacyPage` | `WebPage` | core | detail | /privacy |
|
|
37
|
-
| `TermsPage` | `WebPage` | core | detail | /terms |
|
|
38
|
-
| `PurchasePolicyPage` | `WebPage` | core | detail | /purchase-policy |
|
|
39
|
-
| `WorkingAgreementPage` | `WebPage` | core | detail | /working-agreement |
|
|
40
|
-
| `LandingPage` | `WebPage` | core | home | /<slug> |
|
|
41
|
-
| `ThankYouPage` | `WebPage` | core | detail | /thanks/<slug> |
|
|
42
|
-
| `BookCall` | `WebPage` | core | home | /
|
|
43
|
-
| `NewsletterSignup` | `WebPage` | core | home | /newsletter |
|
|
44
|
-
| `DemoRequest` | `WebPage` | core | home | /demo-request |
|
|
45
|
-
| `TrialSignup` | `WebPage` | core | home | /trial-signup |
|
|
46
|
-
| `Waitlist` | `WebPage` | core | home | /waitlist |
|
|
47
|
-
| `Assessment` | `WebApplication` | core | home | /assessment |
|
|
48
|
-
| `Calculator` | `WebApplication` | core | home | /calculator |
|
|
49
|
-
| `CampaignLP` | `WebPage` | core | home | /<slug> |
|
|
38
|
+
| Key | `@type` | Family | Chassis | Route | Level | Module |
|
|
39
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
40
|
+
| `HomePage` | `HomePage` | core | home | / | Free | `marketing` |
|
|
41
|
+
| `AboutPage` | `AboutPage` | core | detail | /about | Free | `marketing` |
|
|
42
|
+
| `ContactPage` | `ContactPage` | core | detail | /contact | Free | `marketing` |
|
|
43
|
+
| `PrivacyPage` | `WebPage` | core | detail | /privacy | Free | `marketing` |
|
|
44
|
+
| `TermsPage` | `WebPage` | core | detail | /terms | Free | `marketing` |
|
|
45
|
+
| `PurchasePolicyPage` | `WebPage` | core | detail | /purchase-policy | Free | `marketing` |
|
|
46
|
+
| `WorkingAgreementPage` | `WebPage` | core | detail | /working-agreement | Free | `marketing` |
|
|
47
|
+
| `LandingPage` | `WebPage` | core | home | /<slug> | Free | `marketing` |
|
|
48
|
+
| `ThankYouPage` | `WebPage` | core | detail | /thanks/<slug> | Free | `marketing` |
|
|
49
|
+
| `BookCall` | `WebPage` | core | home | /meet/:slug | Pro | `scheduling` |
|
|
50
|
+
| `NewsletterSignup` | `WebPage` | core | home | /newsletter | Free | `marketing` |
|
|
51
|
+
| `DemoRequest` | `WebPage` | core | home | /demo-request | Free | `marketing` |
|
|
52
|
+
| `TrialSignup` | `WebPage` | core | home | /trial-signup | Free | `marketing` |
|
|
53
|
+
| `Waitlist` | `WebPage` | core | home | /waitlist | Free | `marketing` |
|
|
54
|
+
| `Assessment` | `WebApplication` | core | home | /assessment | Pro | `signal-collectors` |
|
|
55
|
+
| `Calculator` | `WebApplication` | core | home | /calculator | Pro | `signal-collectors` |
|
|
56
|
+
| `CampaignLP` | `WebPage` | core | home | /<slug> | Free | `marketing` |
|
|
50
57
|
|
|
51
58
|
## Identity
|
|
52
59
|
|
|
53
|
-
| Key | `@type` | Family | Chassis | Route |
|
|
54
|
-
| --- | --- | --- | --- | --- |
|
|
55
|
-
| `Organization` | `Organization` | identity | detail | — site-wide identity — emitted on the home page or in a layout |
|
|
56
|
-
| `Person` | `Person` | identity | detail | — site-wide identity — emitted on the home page or in a layout |
|
|
57
|
-
| `BreadcrumbList` | `BreadcrumbList` | identity | detail | — site-wide — attached alongside another page's own schema |
|
|
58
|
-
| `ContactPoint` | `ContactPoint` | identity | detail | — site-wide — embedded in `Organization` or `Person` |
|
|
60
|
+
| Key | `@type` | Family | Chassis | Route | Level | Module |
|
|
61
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
62
|
+
| `Organization` | `Organization` | identity | detail | — site-wide identity — emitted on the home page or in a layout | Free | `marketing` |
|
|
63
|
+
| `Person` | `Person` | identity | detail | — site-wide identity — emitted on the home page or in a layout | Free | `marketing` |
|
|
64
|
+
| `BreadcrumbList` | `BreadcrumbList` | identity | detail | — site-wide — attached alongside another page's own schema | Free | `marketing` |
|
|
65
|
+
| `ContactPoint` | `ContactPoint` | identity | detail | — site-wide — embedded in `Organization` or `Person` | Free | `marketing` |
|
|
59
66
|
|
|
60
67
|
## Canonical
|
|
61
68
|
|
|
62
|
-
| Key | `@type` | Family | Chassis | Route |
|
|
63
|
-
| --- | --- | --- | --- | --- |
|
|
64
|
-
| `ServicesList` | `CollectionPage` | canonical-list | list | /services |
|
|
65
|
-
| `Service` | `Service` | canonical-detail | detail | /services/<slug> |
|
|
66
|
-
| `ProductsList` | `CollectionPage` | canonical-list | list | /products |
|
|
67
|
-
| `Product` | `Product` | canonical-detail | detail | /products/<slug> |
|
|
68
|
-
| `ProjectsList` | `CollectionPage` | canonical-list | list | /projects |
|
|
69
|
-
| `Project` | `CreativeWork` | canonical-detail | detail | /projects/<slug> |
|
|
70
|
-
| `FAQPage` | `FAQPage` | canonical-list | list | /faq |
|
|
71
|
-
| `CareersList` | `CollectionPage` | canonical-list | list | /careers |
|
|
72
|
-
| `JobPosting` | `JobPosting` | canonical-detail | detail | /careers/<slug> |
|
|
73
|
-
| `UseCasesList` | `CollectionPage` | canonical-list | list | /
|
|
74
|
-
| `UseCase` | `WebPage` | canonical-detail | detail | /
|
|
75
|
-
| `PortfolioList` | `CollectionPage` | canonical-list | list | /portfolio |
|
|
76
|
-
| `PortfolioItem` | `WebPage` | canonical-detail | detail | /portfolio/<slug> |
|
|
77
|
-
| `FeaturesList` | `CollectionPage` | canonical-list | list | /features |
|
|
78
|
-
| `Feature` | `WebPage` | canonical-detail | detail | /features/<slug> |
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
69
|
+
| Key | `@type` | Family | Chassis | Route | Level | Module |
|
|
70
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
71
|
+
| `ServicesList` | `CollectionPage` | canonical-list | list | /services | Free | `marketing` |
|
|
72
|
+
| `Service` | `Service` | canonical-detail | detail | /services/<slug> | Free | `marketing` |
|
|
73
|
+
| `ProductsList` | `CollectionPage` | canonical-list | list | /products | Free | `marketing` |
|
|
74
|
+
| `Product` | `Product` | canonical-detail | detail | /products/<slug> | Free | `marketing` |
|
|
75
|
+
| `ProjectsList` | `CollectionPage` | canonical-list | list | /projects | Free | `marketing` |
|
|
76
|
+
| `Project` | `CreativeWork` | canonical-detail | detail | /projects/<slug> | Free | `marketing` |
|
|
77
|
+
| `FAQPage` | `FAQPage` | canonical-list | list | /faq | Free | `marketing` |
|
|
78
|
+
| `CareersList` | `CollectionPage` | canonical-list | list | /careers | Free | `marketing` |
|
|
79
|
+
| `JobPosting` | `JobPosting` | canonical-detail | detail | /careers/<slug> | Free | `marketing` |
|
|
80
|
+
| `UseCasesList` | `CollectionPage` | canonical-list | list | /for | Free | `marketing` |
|
|
81
|
+
| `UseCase` | `WebPage` | canonical-detail | detail | /for/<slug> | Free | `marketing` |
|
|
82
|
+
| `PortfolioList` | `CollectionPage` | canonical-list | list | /portfolio | Free | `marketing` |
|
|
83
|
+
| `PortfolioItem` | `WebPage` | canonical-detail | detail | /portfolio/<slug> | Free | `marketing` |
|
|
84
|
+
| `FeaturesList` | `CollectionPage` | canonical-list | list | /features | Free | `marketing` |
|
|
85
|
+
| `Feature` | `WebPage` | canonical-detail | detail | /features/<slug> | Free | `marketing` |
|
|
86
|
+
| `ComparisonsList` | `CollectionPage` | canonical-list | list | /alternatives | Free | `marketing` |
|
|
87
|
+
| `ComparisonPage` | `WebPage` | canonical-detail | detail | /vs/<slug> | Free | `marketing` |
|
|
88
|
+
| `ReportsList` | `CollectionPage` | canonical-list | list | /reports | Free | `marketing` |
|
|
89
|
+
| `ReportPage` | `Report` | canonical-detail | detail | /reports/<slug> | Pro | `signal-collectors` |
|
|
90
|
+
| `TestimonialsList` | `CollectionPage` | canonical-list | list | /testimonials | Free | `marketing` |
|
|
91
|
+
| `ClientsList` | `CollectionPage` | canonical-list | list | /clients | Free | `marketing` |
|
|
92
|
+
| `DownloadsList` | `CollectionPage` | canonical-list | list | /downloads | Free | `marketing` |
|
|
93
|
+
| `EventsList` | `CollectionPage` | canonical-list | list | /events | Free | `marketing` |
|
|
94
|
+
| `Event` | `Event` | canonical-detail | detail | /events/<slug> | Free | `marketing` |
|
|
95
|
+
| `CoursesList` | `CollectionPage` | canonical-list | list | /courses | Free | `marketing` |
|
|
96
|
+
| `Course` | `Course` | canonical-detail | detail | /courses/<slug> | Free | `marketing` |
|
|
97
|
+
| `TeamList` | `CollectionPage` | canonical-list | list | /team | Free | `marketing` |
|
|
98
|
+
| `TeamMember` | `ProfilePage` | canonical-detail | detail | /team/<slug> | Free | `marketing` |
|
|
99
|
+
| `PartnersList` | `CollectionPage` | canonical-list | list | /partners | Free | `marketing` |
|
|
100
|
+
| `Partner` | `AboutPage` | canonical-detail | detail | /partners/<slug> | Free | `marketing` |
|
|
101
|
+
| `IntegrationsList` | `CollectionPage` | canonical-list | list | /integrations | Free | `marketing` |
|
|
102
|
+
| `Integration` | `WebPage` | canonical-detail | detail | /integrations/<slug> | Free | `marketing` |
|
|
103
|
+
| `GlossaryList` | `CollectionPage` | canonical-list | list | /glossary | Free | `marketing` |
|
|
104
|
+
| `LocationsList` | `CollectionPage` | canonical-list | list | /locations | Free | `marketing` |
|
|
105
|
+
| `Location` | `Place` | canonical-detail | detail | /locations/<slug> | Free | `marketing` |
|
|
106
|
+
| `DocsList` | `CollectionPage` | canonical-list | list | /docs | Pro | `docs-blog` |
|
|
107
|
+
| `SoftwareProduct` | `WebPage` | canonical-detail | detail | /software/<slug> | Free | `marketing` |
|
|
108
|
+
| `ServiceAreaPage` | `WebPage` | canonical-detail | detail | /service-areas/<slug> | Free | `marketing` |
|
|
109
|
+
| `Pricing` | `WebPage` | canonical-detail | detail | /pricing | Free | `marketing` |
|
|
101
110
|
|
|
102
111
|
## Editorial
|
|
103
112
|
|
|
104
|
-
| Key | `@type` | Family | Chassis | Route |
|
|
105
|
-
| --- | --- | --- | --- | --- |
|
|
106
|
-
| `BlogList` | `Blog` | editorial-list | list | /blog |
|
|
107
|
-
| `BlogPosting` | `BlogPosting` | editorial-detail | detail | /blog/<slug> |
|
|
108
|
-
| `ResourcesHub` | `CollectionPage` | editorial-list | list | /resources |
|
|
109
|
-
| `ResourceDetail` | `Article` | editorial-detail | detail | /resources/<slug> |
|
|
110
|
-
| `CaseStudiesList` | `CollectionPage` | editorial-list | list | /case-studies |
|
|
111
|
-
| `CaseStudy` | `Article` | editorial-detail | detail | /case-studies/<slug> |
|
|
112
|
-
| `HowTo` | `HowTo` | editorial-detail | detail | /how-to/<slug> |
|
|
113
|
-
| `Whitepaper` | `Article` | editorial-detail | detail | /whitepapers/<slug> |
|
|
114
|
-
| `TechArticle` | `TechArticle` | editorial-detail | detail | /tech-articles/<slug> |
|
|
115
|
-
| `DocsDetail` | `TechArticle` | editorial-detail | detail | /docs/<slug> |
|
|
113
|
+
| Key | `@type` | Family | Chassis | Route | Level | Module |
|
|
114
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
115
|
+
| `BlogList` | `Blog` | editorial-list | list | /blog | Free | `marketing` |
|
|
116
|
+
| `BlogPosting` | `BlogPosting` | editorial-detail | detail | /blog/<slug> | Pro | `docs-blog` |
|
|
117
|
+
| `ResourcesHub` | `CollectionPage` | editorial-list | list | /resources | Free | `marketing` |
|
|
118
|
+
| `ResourceDetail` | `Article` | editorial-detail | detail | /resources/<slug> | Free | `marketing` |
|
|
119
|
+
| `CaseStudiesList` | `CollectionPage` | editorial-list | list | /case-studies | Free | `marketing` |
|
|
120
|
+
| `CaseStudy` | `Article` | editorial-detail | detail | /case-studies/<slug> | Free | `marketing` |
|
|
121
|
+
| `HowTo` | `HowTo` | editorial-detail | detail | /how-to/<slug> | Free | `marketing` |
|
|
122
|
+
| `Whitepaper` | `Article` | editorial-detail | detail | /whitepapers/<slug> | Free | `marketing` |
|
|
123
|
+
| `TechArticle` | `TechArticle` | editorial-detail | detail | /tech-articles/<slug> | Free | `marketing` |
|
|
124
|
+
| `DocsDetail` | `TechArticle` | editorial-detail | detail | /docs/<slug> | Pro | `docs-blog` |
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// site-pages.mjs — report what THIS site can serve, read from the site itself.
|
|
3
|
+
//
|
|
4
|
+
// Usage: node .claude/skills/add-page/scripts/site-pages.mjs [--json] [<site-root>]
|
|
5
|
+
//
|
|
6
|
+
// It scans apps/web/app/[locale]/**/page.tsx for the page type each route
|
|
7
|
+
// renders (the `type: "X"` literal in renderPage / renderPageMetadata, or a
|
|
8
|
+
// getMdxSource("X", …) call), then pairs each type with its content folder and
|
|
9
|
+
// the pages already written there. It also echoes .ailk-site-manifest.json's
|
|
10
|
+
// shape, design and (when recorded) level. Read-only: it never writes.
|
|
11
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
12
|
+
import { join, relative, sep } from "node:path";
|
|
13
|
+
|
|
14
|
+
const args = process.argv.slice(2);
|
|
15
|
+
const asJson = args.includes("--json");
|
|
16
|
+
const root = args.find((a) => !a.startsWith("--")) ?? process.cwd();
|
|
17
|
+
const appRoot = join(root, "apps/web/app/[locale]");
|
|
18
|
+
if (!existsSync(appRoot)) {
|
|
19
|
+
console.error(`site-pages: ${appRoot} not found — run from the site's root.`);
|
|
20
|
+
process.exit(2);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Types whose content lives outside content/<locale>/<Type>.
|
|
24
|
+
const CONTENT_OVERRIDES = {
|
|
25
|
+
BlogPosting: "apps/web/content/en/blog",
|
|
26
|
+
BlogList: "apps/web/content/en/blog",
|
|
27
|
+
DocsDetail: "apps/web/content/en/docs",
|
|
28
|
+
DocsList: "apps/web/content/en/docs",
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
function walk(dir, out = []) {
|
|
32
|
+
for (const name of readdirSync(dir)) {
|
|
33
|
+
const abs = join(dir, name);
|
|
34
|
+
if (name === "__tests__" || name === "node_modules") continue;
|
|
35
|
+
if (statSync(abs).isDirectory()) walk(abs, out);
|
|
36
|
+
else if (name === "page.tsx") out.push(abs);
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const routes = [];
|
|
42
|
+
for (const file of walk(appRoot)) {
|
|
43
|
+
const src = readFileSync(file, "utf8");
|
|
44
|
+
const types = new Set();
|
|
45
|
+
for (const m of src.matchAll(/type:\s*"([A-Z][A-Za-z]+)"/g)) types.add(m[1]);
|
|
46
|
+
for (const m of src.matchAll(/getMdxSource\(\s*"([A-Z][A-Za-z]+)"/g)) types.add(m[1]);
|
|
47
|
+
const dir = relative(appRoot, file).split(sep).slice(0, -1);
|
|
48
|
+
// Route groups like (auth) do not appear in the URL.
|
|
49
|
+
const path = "/" + dir.filter((s) => !/^\(.*\)$/.test(s)).join("/");
|
|
50
|
+
const dynamic = dir.some((s) => s.startsWith("["));
|
|
51
|
+
routes.push({ route: path === "/" ? "/" : path, file: relative(root, file), types: [...types], dynamic });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const byType = {};
|
|
55
|
+
for (const r of routes) {
|
|
56
|
+
for (const t of r.types) {
|
|
57
|
+
const entry = (byType[t] ??= { type: t, routes: [], contentDir: CONTENT_OVERRIDES[t] ?? `content/en/${t}`, pages: [] });
|
|
58
|
+
entry.routes.push(r.route);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
for (const e of Object.values(byType)) {
|
|
62
|
+
const abs = join(root, e.contentDir);
|
|
63
|
+
if (existsSync(abs)) {
|
|
64
|
+
e.pages = readdirSync(abs).filter((f) => /\.mdx?$/.test(f)).map((f) => f.replace(/\.mdx?$/, ""));
|
|
65
|
+
}
|
|
66
|
+
// A type served by a dynamic route takes new pages; a static-only type is one page.
|
|
67
|
+
e.takesNewPages = routes.some((r) => r.dynamic && r.types.includes(e.type));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let manifest = null;
|
|
71
|
+
const manifestPath = join(root, ".ailk-site-manifest.json");
|
|
72
|
+
if (existsSync(manifestPath)) {
|
|
73
|
+
const m = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
74
|
+
manifest = { shape: m.shape ?? null, design: m.design ?? null, level: m.level ?? null, modules: m.modules ?? m.requires ?? null };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const result = { manifest, types: Object.values(byType).sort((a, b) => a.type.localeCompare(b.type)) };
|
|
78
|
+
if (asJson) {
|
|
79
|
+
console.log(JSON.stringify(result, null, 2));
|
|
80
|
+
} else {
|
|
81
|
+
if (manifest) console.log(`shape: ${manifest.shape} design: ${manifest.design} level: ${manifest.level ?? "(not recorded)"}`);
|
|
82
|
+
console.log("");
|
|
83
|
+
console.log("type".padEnd(22) + "route(s)".padEnd(34) + "new pages?".padEnd(12) + "existing");
|
|
84
|
+
for (const e of result.types) {
|
|
85
|
+
console.log(e.type.padEnd(22) + e.routes.join(" ").padEnd(34) + (e.takesNewPages ? "yes" : "no").padEnd(12) + (e.pages.join(", ") || "—"));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: ComparisonPage
|
|
3
|
+
slug: {{SLUG}}
|
|
4
|
+
placeholder: true
|
|
5
|
+
title: {{TITLE}}
|
|
6
|
+
description: {{DESCRIPTION}}
|
|
7
|
+
sections:
|
|
8
|
+
[
|
|
9
|
+
{
|
|
10
|
+
"id": "hero",
|
|
11
|
+
"type": "hero",
|
|
12
|
+
"data":
|
|
13
|
+
{
|
|
14
|
+
"eyebrow": "Comparisons",
|
|
15
|
+
"headline": "{{TITLE}}",
|
|
16
|
+
"subheadline": "{{DESCRIPTION}}",
|
|
17
|
+
"primaryCta": { "label": "{Primary CTA}", "href": "/contact" },
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "decision-split",
|
|
22
|
+
"type": "decision-split",
|
|
23
|
+
"data":
|
|
24
|
+
{
|
|
25
|
+
"headline": "{Which one fits you}",
|
|
26
|
+
"panels":
|
|
27
|
+
[
|
|
28
|
+
{
|
|
29
|
+
"title": "{{TITLE}}",
|
|
30
|
+
"checklist":
|
|
31
|
+
[
|
|
32
|
+
"{Reason 1 to choose us}",
|
|
33
|
+
"{Reason 2 to choose us}",
|
|
34
|
+
"{Reason 3 to choose us}",
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"title": "{The alternative}",
|
|
39
|
+
"glyph": "cross",
|
|
40
|
+
"checklist":
|
|
41
|
+
[
|
|
42
|
+
"{Reason 1 to choose them instead}",
|
|
43
|
+
"{Reason 2 to choose them instead}",
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"id": "comparison-table",
|
|
51
|
+
"type": "comparison-table",
|
|
52
|
+
"data":
|
|
53
|
+
{
|
|
54
|
+
"headline": "{How they compare}",
|
|
55
|
+
"columns":
|
|
56
|
+
[
|
|
57
|
+
{ "key": "us", "name": "{{TITLE}}", "highlighted": true },
|
|
58
|
+
{ "key": "them", "name": "{The alternative}" },
|
|
59
|
+
],
|
|
60
|
+
"groups":
|
|
61
|
+
[
|
|
62
|
+
{
|
|
63
|
+
"groupName": "{Core features}",
|
|
64
|
+
"rows":
|
|
65
|
+
[
|
|
66
|
+
{
|
|
67
|
+
"featureName": "{Feature 1}",
|
|
68
|
+
"values": { "us": true, "them": false },
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"featureName": "{Feature 2}",
|
|
72
|
+
"values": { "us": true, "them": true },
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"id": "cta",
|
|
81
|
+
"type": "cta",
|
|
82
|
+
"data":
|
|
83
|
+
{
|
|
84
|
+
"variant": "box",
|
|
85
|
+
"headline": "{Ready to switch?}",
|
|
86
|
+
"description": "{One sentence on what happens next}",
|
|
87
|
+
"primaryCta": { "label": "{Primary CTA}", "href": "/contact" },
|
|
88
|
+
"secondaryCta":
|
|
89
|
+
{
|
|
90
|
+
"label": "See all alternatives",
|
|
91
|
+
"href": "/alternatives",
|
|
92
|
+
"variant": "outline",
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
]
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
{/* Rendered from frontmatter `sections[]` by the /vs/<slug> route (D10 — the generic detail chassis: hero, decision-split, comparison-table, cta; no dedicated comparison section). Listed automatically by the /alternatives hub. Placeholder copy — replace every {brace} with your own words before you launch. */}
|
|
@@ -5,24 +5,14 @@ title: {{TITLE}}
|
|
|
5
5
|
description: {{DESCRIPTION}}
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
{/*
|
|
9
|
+
Written by the add-page skill, used only when this site had no other page of
|
|
10
|
+
this type to copy. The frontmatter drives the page's route and its JSON-LD:
|
|
11
|
+
keep `type` as it is, and make `description` a true one-sentence summary.
|
|
12
|
+
Run `fill-page` to write the real copy, then `check-site` to score it.
|
|
13
|
+
Extra structured data goes in a `schema:` block — see the add-page skill.
|
|
14
|
+
*/}
|
|
15
|
+
|
|
8
16
|
# {{TITLE}}
|
|
9
17
|
|
|
10
18
|
{{DESCRIPTION}}
|
|
11
|
-
|
|
12
|
-
<!--
|
|
13
|
-
This is the MDX content stub emitted by `add-page`.
|
|
14
|
-
The frontmatter is the source of truth for JSON-LD — the
|
|
15
|
-
`{{BUILDER}}(page)` call in `app/{{SLUG}}/page.tsx` reads it.
|
|
16
|
-
|
|
17
|
-
Edit this file freely:
|
|
18
|
-
- Add sections, prose, components imported from your project.
|
|
19
|
-
- Update `description` (it's used both as the meta description
|
|
20
|
-
and as input to the JSON-LD builder).
|
|
21
|
-
- Don't change `type` unless you also update the route's import
|
|
22
|
-
to match a different `@working-theory/schema` builder.
|
|
23
|
-
|
|
24
|
-
When you're happy with the page, run `check-site` to see
|
|
25
|
-
how it scores on citation-readiness. Use the `schema:` frontmatter
|
|
26
|
-
override to add supplementary schema (FAQPage, HowTo, etc.) without
|
|
27
|
-
re-scaffolding.
|
|
28
|
-
-->
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: LandingPage
|
|
3
|
+
slug: {{SLUG}}
|
|
4
|
+
placeholder: true
|
|
5
|
+
title: {{TITLE}}
|
|
6
|
+
description: {{DESCRIPTION}}
|
|
7
|
+
sections:
|
|
8
|
+
[
|
|
9
|
+
{
|
|
10
|
+
"id": "hero",
|
|
11
|
+
"type": "hero",
|
|
12
|
+
"data":
|
|
13
|
+
{
|
|
14
|
+
"variant": "centered",
|
|
15
|
+
"eyebrow": "{{TITLE}}",
|
|
16
|
+
"headline": "{{TITLE}}",
|
|
17
|
+
"subheadline": "{{DESCRIPTION}}",
|
|
18
|
+
"primaryCta":
|
|
19
|
+
{ "label": "{Get started →}", "href": "/flows/{{FLOW_SLUG}}/start" },
|
|
20
|
+
"ctaSize": "xl",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "request",
|
|
25
|
+
"type": "cta",
|
|
26
|
+
"data":
|
|
27
|
+
{
|
|
28
|
+
"variant": "minimal",
|
|
29
|
+
"headline": "{Ready?}",
|
|
30
|
+
"primaryCta":
|
|
31
|
+
{ "label": "{Get started →}", "href": "/flows/{{FLOW_SLUG}}/start" },
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
]
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
{/* This page's CTA opens the `{{FLOW_SLUG}}` flow at
|
|
38
|
+
/flows/{{FLOW_SLUG}}/start — a signal-collectors module route, not a page
|
|
39
|
+
this seed owns. The flow definition itself
|
|
40
|
+
(`database/flows/{{FLOW_SLUG}}.flow.json`) is a separate artifact this
|
|
41
|
+
skill does not write; seed it via the flow engine before this page's CTA
|
|
42
|
+
resolves. Placeholder copy — replace every {brace} with your own words
|
|
43
|
+
before you launch. */}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: ReportPage
|
|
3
|
+
slug: {{SLUG}}
|
|
4
|
+
placeholder: true
|
|
5
|
+
title: {{TITLE}}
|
|
6
|
+
description: {{DESCRIPTION}}
|
|
7
|
+
schema:
|
|
8
|
+
datePublished: "{{DATE_PUBLISHED}}"
|
|
9
|
+
author:
|
|
10
|
+
"@type": Organization
|
|
11
|
+
name: "{Your Company}"
|
|
12
|
+
sections:
|
|
13
|
+
[
|
|
14
|
+
{
|
|
15
|
+
"id": "header",
|
|
16
|
+
"type": "report-header",
|
|
17
|
+
"data":
|
|
18
|
+
{
|
|
19
|
+
"title": "{{TITLE}}",
|
|
20
|
+
"eyebrow": "{{DATE_LABEL}}",
|
|
21
|
+
"backHref": "/reports",
|
|
22
|
+
"backLabel": "All reports",
|
|
23
|
+
"tone": "on-dark",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "document",
|
|
28
|
+
"type": "document-viewer",
|
|
29
|
+
"data":
|
|
30
|
+
{
|
|
31
|
+
"src": "/reports/sample-report.pdf",
|
|
32
|
+
"geometry": "16:9",
|
|
33
|
+
"pages": 8,
|
|
34
|
+
"downloadFilename": "{{SLUG}}.pdf",
|
|
35
|
+
"outline":
|
|
36
|
+
[
|
|
37
|
+
{ "id": "opening", "label": "Opening", "startPage": 1 },
|
|
38
|
+
{ "id": "findings", "label": "Findings", "startPage": 3 },
|
|
39
|
+
{ "id": "outlook", "label": "Outlook", "startPage": 6 },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
]
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
{/* A PLACEHOLDER report. Its bytes are the signal-collectors module's own
|
|
47
|
+
sample PDF (apps/web/public/reports/sample-report.pdf), shared by every
|
|
48
|
+
sample report so the site ships no binary of its own. Point `src` at your
|
|
49
|
+
real document and set `pages` to its real page count. Rendered by the
|
|
50
|
+
signal-collectors module's own /reports/<slug> route (`app/[locale]/reports/[slug]/page.tsx`)
|
|
51
|
+
and listed automatically by the /reports hub (ReportsList) — never
|
|
52
|
+
hand-list a report there. */}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: ReportsList
|
|
3
|
+
slug: reports
|
|
4
|
+
placeholder: true
|
|
5
|
+
title: {{TITLE}}
|
|
6
|
+
description: {{DESCRIPTION}}
|
|
7
|
+
sections:
|
|
8
|
+
[
|
|
9
|
+
{
|
|
10
|
+
"id": "hero",
|
|
11
|
+
"type": "hero",
|
|
12
|
+
"data":
|
|
13
|
+
{
|
|
14
|
+
"variant": "centered",
|
|
15
|
+
"eyebrow": "Reports",
|
|
16
|
+
"headline": "{{TITLE}}",
|
|
17
|
+
"subheadline": "{{DESCRIPTION}}",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "closing",
|
|
22
|
+
"type": "cta",
|
|
23
|
+
"data":
|
|
24
|
+
{
|
|
25
|
+
"variant": "minimal",
|
|
26
|
+
"headline": "{Want the next one as it lands?}",
|
|
27
|
+
"primaryCta": { "label": "{Contact me →}", "href": "/contact" },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
]
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
{/* Rendered from frontmatter `sections[]` by the /reports route
|
|
34
|
+
(`app/[locale]/reports/page.tsx`). Its card list is GENERATED, not
|
|
35
|
+
authored here (spec 6892 D2): the route appends one `reports-list`
|
|
36
|
+
section listing every ReportPage seed, so this seed carries only its own
|
|
37
|
+
hero and closing cta. Placeholder copy — replace every {brace} with your
|
|
38
|
+
own words before you launch. */}
|
|
@@ -34,6 +34,23 @@ Skip this skill when:
|
|
|
34
34
|
|
|
35
35
|
## The mechanic
|
|
36
36
|
|
|
37
|
+
### Step 0 — Read what this site can render
|
|
38
|
+
|
|
39
|
+
Read `.ailk-site-manifest.json` at the site root, the site's roster of
|
|
40
|
+
record:
|
|
41
|
+
|
|
42
|
+
- `modules` — the modules this site has. Add any module the
|
|
43
|
+
`# Modules:` line of `architecture.yaml` names that `modules` does not:
|
|
44
|
+
`create-ailk add-module` records a module it adds there. With no
|
|
45
|
+
manifest, or none carrying `modules`, that line is the set.
|
|
46
|
+
- `rows` — every route the site carries and the page type each renders.
|
|
47
|
+
- `level` — present only when the scaffold derived it from the licence
|
|
48
|
+
key. It never decides what to suggest; `modules` does.
|
|
49
|
+
|
|
50
|
+
A page type renders on this site only when its **Module** in
|
|
51
|
+
`.claude/skills/add-page/references/page-types.md` is in that set.
|
|
52
|
+
Step 7 suggests a page only of such a type.
|
|
53
|
+
|
|
37
54
|
### Step 1 — Invoke the CLI
|
|
38
55
|
|
|
39
56
|
Run `ailk-audit --json` from the consumer's project root. Use
|
|
@@ -136,6 +153,12 @@ themselves on a subsequent turn.
|
|
|
136
153
|
| `entity-markup` | Manual edit — ensure `Organization` (or `Person`) JSON-LD is emitted somewhere site-wide |
|
|
137
154
|
| `faq-howto-incentive` | `add-page`'s `schema:` frontmatter override — add an `FAQPage` or `HowTo` block to a relevant page |
|
|
138
155
|
|
|
156
|
+
When a fix means adding a page, name only a page type this site can
|
|
157
|
+
render (Step 0) — for `faq-howto-incentive`, a `FAQPage` or `HowTo`
|
|
158
|
+
page, never one the site's modules do not render. When only a type the
|
|
159
|
+
site cannot render would fix a finding, say which module renders it and
|
|
160
|
+
which level carries it, and point at the `upgrade-plan` skill.
|
|
161
|
+
|
|
139
162
|
Phrase the pointer as a single sentence:
|
|
140
163
|
|
|
141
164
|
> "Missing `Product` schema on `/pricing` — add it via `add-page`'s
|
|
@@ -67,15 +67,30 @@ comes from `_site.mdx` `siteIdentity.name`.
|
|
|
67
67
|
|
|
68
68
|
## Step 0 — Read
|
|
69
69
|
|
|
70
|
-
1. Read the
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
1. Read `.ailk-site-manifest.json` at the site root, the site's roster
|
|
71
|
+
of record: `modules` (the modules this site has) and `rows` (every
|
|
72
|
+
route it carries). Add any module the `# Modules:` line of
|
|
73
|
+
`architecture.yaml` names that `modules` does not — `create-ailk
|
|
74
|
+
add-module` records a module it adds there; with no manifest, or none
|
|
75
|
+
carrying `modules`, that line is the set. `level`, when present, never
|
|
76
|
+
decides anything here.
|
|
77
|
+
|
|
78
|
+
The page's `type` must render on this site: its **Module** in
|
|
79
|
+
`../add-page/references/page-types.md` is in that set, or a row
|
|
80
|
+
already renders it (`rows[].pageType` — a Free starter's `/meet/<slug>`
|
|
81
|
+
`BookCall` placeholders). When it does not,
|
|
82
|
+
say which module renders the type and which level carries it, point at
|
|
83
|
+
the `upgrade-plan` skill, and stop. Never fill a page this site cannot
|
|
84
|
+
render.
|
|
85
|
+
2. Read the profile: `profiles/<slug>.yaml`.
|
|
86
|
+
3. Read `content/_site.mdx` for `siteIdentity.name`.
|
|
87
|
+
4. Read the page file. Note its stack (`sections[].type` in order).
|
|
88
|
+
5. For each section type in the stack, read its data schema: the
|
|
74
89
|
`<Type>SectionDataSchema` (or `<Type>DataSchema`) export in the
|
|
75
90
|
installed `@working-theory/validation`'s `schemas/page-sections`. Fill
|
|
76
91
|
only fields the schema declares. Every field a section renders from
|
|
77
92
|
copy gets content; a field the source page did not use stays unused.
|
|
78
|
-
|
|
93
|
+
6. Find the route that renders this page type under `apps/web/app/[locale]/`
|
|
79
94
|
and read its `bodyMode`. When it is `"mdx-body"`, the MDX body is
|
|
80
95
|
rendered and must be filled too. Otherwise the body is a short note,
|
|
81
96
|
and you rewrite it as one plain sentence that names no braces.
|
|
@@ -88,7 +103,9 @@ fields and intake answers that fill it.
|
|
|
88
103
|
1. **Sections.** For each section, in place, write every copy field from
|
|
89
104
|
the profile using `references/section-sources.md`:
|
|
90
105
|
- offerings → `items` entries (`title` = the offering `name`,
|
|
91
|
-
`description` = its `job`, `link.href` = `/services/<kebab name>`
|
|
106
|
+
`description` = its `job`, `link.href` = `/services/<kebab name>`
|
|
107
|
+
only when the manifest's `rows` carry `/services/[slug]`; otherwise
|
|
108
|
+
no `link`, so no entry points at a page the site does not have);
|
|
92
109
|
- vocabulary → headlines, eyebrows and FAQ questions (the buyer's own
|
|
93
110
|
words: the `problem` list for what went wrong, `outcome` for what
|
|
94
111
|
they get);
|
|
@@ -176,5 +193,7 @@ and run both again. Stop only when both are clean.
|
|
|
176
193
|
- Tier 3 (the Messaging Canvas through the content pipeline).
|
|
177
194
|
- Create a page — use `add-page`.
|
|
178
195
|
- Edit `_site.mdx`, the nav or the page roster. A profile's `roster` and
|
|
179
|
-
`nav` entries are declared for a later step and are not applied here
|
|
196
|
+
`nav` entries are declared for a later step and are not applied here,
|
|
197
|
+
and a profile page type this site cannot render (Step 0) is never
|
|
198
|
+
suggested.
|
|
180
199
|
- Write a price, a name or an address the owner did not give.
|