create-ailk 0.8.0 → 0.10.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 +71 -3
- 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 +104 -5
- 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 +48 -32
- package/dist/lib/module-license-gate.js +117 -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 +67 -23
- 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 +216 -19
- 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 +16 -63
- package/dist/starter-grid.js +102 -84
- 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 +53 -28
- package/package.json +6 -3
- package/release-scope.json +25 -0
- 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/designs/minimalism/DESIGN.md +98 -6
- package/site-templates/designs/minimalism/sample/README.md +48 -0
- package/site-templates/{minimalism-site → designs/minimalism/sample}/content/en/HomePage/home.mdx +1 -1
- 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/agents/web.md +10 -8
- package/templates/.claude/rules/architecture.md +17 -7
- package/templates/.claude/skills/README.md +3 -2
- package/templates/.claude/skills/add-auth/SKILL.md +142 -90
- package/templates/.claude/skills/add-auth/references/env-vars.md +32 -17
- package/templates/.claude/skills/add-auth/references/oauth-app-setup.md +17 -8
- package/templates/.claude/skills/add-page/SKILL.md +241 -238
- package/templates/.claude/skills/add-page/references/page-types.md +94 -86
- 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 +51 -18
- package/templates/.claude/skills/check-site/references/common-errors.md +12 -9
- package/templates/.claude/skills/check-site/references/findings-glossary.md +4 -4
- package/templates/.claude/skills/check-site/references/severity-levels.md +3 -3
- 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/SKILL.md +75 -38
- 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/.env.example +23 -2
- 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 +4 -1
- package/templates/tools/check-claude-md.ts +128 -0
- package/versions.json +33 -33
- package/dist/modules/commerce/0.6.0.tar.gz +0 -0
- package/dist/modules/commerce/0.6.1.tar.gz +0 -0
- package/dist/modules/docs-blog/0.6.0.tar.gz +0 -0
- package/dist/modules/docs-blog/0.6.1.tar.gz +0 -0
- package/dist/modules/marketing-site/0.6.1.tar.gz +0 -0
- package/dist/modules/minimalism-site/0.6.1.tar.gz +0 -0
- package/dist/modules/multi-tenant/0.6.0.tar.gz +0 -0
- package/dist/modules/multi-tenant/0.6.1.tar.gz +0 -0
- package/dist/modules/saas-product/0.6.1.tar.gz +0 -0
- package/dist/modules/scheduling/0.6.0.tar.gz +0 -0
- package/dist/modules/scheduling/0.6.1.tar.gz +0 -0
- package/dist/modules/signal-collectors/0.6.0.tar.gz +0 -0
- package/dist/modules/signal-collectors/0.6.1.tar.gz +0 -0
- package/dist/modules/simple-service/0.6.1.tar.gz +0 -0
- package/dist/modules/workspace/0.6.0.tar.gz +0 -0
- package/dist/modules/workspace/0.6.1.tar.gz +0 -0
- 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.json +0 -506
- 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/.claude/skills/setup-deploy/references/env-vars-template.md +0 -175
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-31.552Z-fallback-1789916251590-037e9005.json +0 -8
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.840Z-fallback-1789916253842-b52659e9.json +0 -12
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.844Z-fallback-1789916253845-6b266f8c.json +0 -12
- 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/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
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "BookCall"
|
|
3
|
+
slug: "book-a-call"
|
|
4
|
+
title: "Book a Call"
|
|
5
|
+
description: "{One sentence on who this call is for and what they leave with}"
|
|
6
|
+
schema:
|
|
7
|
+
mainEntity:
|
|
8
|
+
"@type": "Offer"
|
|
9
|
+
name: "Book a Call"
|
|
10
|
+
sections:
|
|
11
|
+
[
|
|
12
|
+
{
|
|
13
|
+
"id": "hero",
|
|
14
|
+
"type": "hero",
|
|
15
|
+
"data":
|
|
16
|
+
{
|
|
17
|
+
"eyebrow": "Book a Call",
|
|
18
|
+
"headline": "Book a Call",
|
|
19
|
+
"subheadline": "{One sentence on who this call is for and what they leave with}",
|
|
20
|
+
"primaryCta": { "label": "{Get in touch}", "href": "/contact" },
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "add-scheduling",
|
|
25
|
+
"type": "cta",
|
|
26
|
+
"data":
|
|
27
|
+
{
|
|
28
|
+
"variant": "box",
|
|
29
|
+
"headline": "{What booking a call would do for your visitors}",
|
|
30
|
+
"description": "{One or two sentences on what live scheduling adds once it's on}",
|
|
31
|
+
"primaryCta":
|
|
32
|
+
{
|
|
33
|
+
"label": "Add scheduling with Pro",
|
|
34
|
+
"href": "https://ailaunchkit.ai/pricing",
|
|
35
|
+
"external": true,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "what-happens-on-the-call",
|
|
41
|
+
"type": "items",
|
|
42
|
+
"data":
|
|
43
|
+
{
|
|
44
|
+
"headline": "What happens on the call?",
|
|
45
|
+
"columns": 3,
|
|
46
|
+
"items":
|
|
47
|
+
[
|
|
48
|
+
{
|
|
49
|
+
"title": "{The first thing you cover}",
|
|
50
|
+
"description": "{One or two sentences on what the visitor learns or decides here}",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"title": "{The second thing you cover}",
|
|
54
|
+
"description": "{One or two sentences on what the visitor learns or decides here}",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"title": "{The next step you agree}",
|
|
58
|
+
"description": "{One or two sentences on what happens after the call}",
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"id": "back-to-meet",
|
|
65
|
+
"type": "content-block",
|
|
66
|
+
"data":
|
|
67
|
+
{
|
|
68
|
+
"body": "{Looking for a different kind of meeting?}",
|
|
69
|
+
"cta":
|
|
70
|
+
{
|
|
71
|
+
"label": "← All meeting types",
|
|
72
|
+
"href": "/meet",
|
|
73
|
+
"variant": "link",
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
]
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
{/* Rendered from frontmatter `sections[]` by the /meet/[slug] placeholder route. A template that carries the scheduling module overrides this file with the live booker. The "What happens on the call?" section moved here verbatim from the retired /book-a-call page (#6897 D10). Placeholder copy — replace every {brace} with your own words before you launch. */}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "BookCall"
|
|
3
|
+
slug: "onsite-estimate"
|
|
4
|
+
title: "Onsite Estimate"
|
|
5
|
+
description: "{One sentence on who this visit is for and what they leave with}"
|
|
6
|
+
schema:
|
|
7
|
+
mainEntity:
|
|
8
|
+
"@type": "Offer"
|
|
9
|
+
name: "Onsite Estimate"
|
|
10
|
+
sections:
|
|
11
|
+
[
|
|
12
|
+
{
|
|
13
|
+
"id": "hero",
|
|
14
|
+
"type": "hero",
|
|
15
|
+
"data":
|
|
16
|
+
{
|
|
17
|
+
"eyebrow": "Onsite Estimate",
|
|
18
|
+
"headline": "Onsite Estimate",
|
|
19
|
+
"subheadline": "{One sentence on who this visit is for and what they leave with}",
|
|
20
|
+
"primaryCta": { "label": "{Get in touch}", "href": "/contact" },
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "add-scheduling",
|
|
25
|
+
"type": "cta",
|
|
26
|
+
"data":
|
|
27
|
+
{
|
|
28
|
+
"variant": "box",
|
|
29
|
+
"headline": "{What booking an onsite estimate would do for your visitors}",
|
|
30
|
+
"description": "{One or two sentences on what live scheduling adds once it's on}",
|
|
31
|
+
"primaryCta":
|
|
32
|
+
{
|
|
33
|
+
"label": "Add scheduling with Pro",
|
|
34
|
+
"href": "https://ailaunchkit.ai/pricing",
|
|
35
|
+
"external": true,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "back-to-meet",
|
|
41
|
+
"type": "content-block",
|
|
42
|
+
"data":
|
|
43
|
+
{
|
|
44
|
+
"body": "{Looking for a different kind of meeting?}",
|
|
45
|
+
"cta":
|
|
46
|
+
{
|
|
47
|
+
"label": "← All meeting types",
|
|
48
|
+
"href": "/meet",
|
|
49
|
+
"variant": "link",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
]
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
{/* Rendered from frontmatter `sections[]` by the /meet/[slug] placeholder route. A template that carries the scheduling module overrides this file with the live booker. Placeholder copy — replace every {brace} with your own words before you launch. */}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "BookCall"
|
|
3
|
+
slug: "onsite-service"
|
|
4
|
+
title: "Onsite Service"
|
|
5
|
+
description: "{One sentence on who this visit is for and what they leave with}"
|
|
6
|
+
schema:
|
|
7
|
+
mainEntity:
|
|
8
|
+
"@type": "Offer"
|
|
9
|
+
name: "Onsite Service"
|
|
10
|
+
sections:
|
|
11
|
+
[
|
|
12
|
+
{
|
|
13
|
+
"id": "hero",
|
|
14
|
+
"type": "hero",
|
|
15
|
+
"data":
|
|
16
|
+
{
|
|
17
|
+
"eyebrow": "Onsite Service",
|
|
18
|
+
"headline": "Onsite Service",
|
|
19
|
+
"subheadline": "{One sentence on who this visit is for and what they leave with}",
|
|
20
|
+
"primaryCta": { "label": "{Get in touch}", "href": "/contact" },
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "add-scheduling",
|
|
25
|
+
"type": "cta",
|
|
26
|
+
"data":
|
|
27
|
+
{
|
|
28
|
+
"variant": "box",
|
|
29
|
+
"headline": "{What booking an onsite service call would do for your visitors}",
|
|
30
|
+
"description": "{One or two sentences on what live scheduling adds once it's on}",
|
|
31
|
+
"primaryCta":
|
|
32
|
+
{
|
|
33
|
+
"label": "Add scheduling with Pro",
|
|
34
|
+
"href": "https://ailaunchkit.ai/pricing",
|
|
35
|
+
"external": true,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "back-to-meet",
|
|
41
|
+
"type": "content-block",
|
|
42
|
+
"data":
|
|
43
|
+
{
|
|
44
|
+
"body": "{Looking for a different kind of meeting?}",
|
|
45
|
+
"cta":
|
|
46
|
+
{
|
|
47
|
+
"label": "← All meeting types",
|
|
48
|
+
"href": "/meet",
|
|
49
|
+
"variant": "link",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
]
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
{/* Rendered from frontmatter `sections[]` by the /meet/[slug] placeholder route. A template that carries the scheduling module overrides this file with the live booker. Placeholder copy — replace every {brace} with your own words before you launch. */}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "BookCall"
|
|
3
|
+
slug: "start-project"
|
|
4
|
+
title: "Start Project"
|
|
5
|
+
description: "{One sentence on who this kickoff is for and what they leave with}"
|
|
6
|
+
schema:
|
|
7
|
+
mainEntity:
|
|
8
|
+
"@type": "Offer"
|
|
9
|
+
name: "Start Project"
|
|
10
|
+
sections:
|
|
11
|
+
[
|
|
12
|
+
{
|
|
13
|
+
"id": "hero",
|
|
14
|
+
"type": "hero",
|
|
15
|
+
"data":
|
|
16
|
+
{
|
|
17
|
+
"eyebrow": "Start Project",
|
|
18
|
+
"headline": "Start Project",
|
|
19
|
+
"subheadline": "{One sentence on who this kickoff is for and what they leave with}",
|
|
20
|
+
"primaryCta": { "label": "{Get in touch}", "href": "/contact" },
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "add-scheduling",
|
|
25
|
+
"type": "cta",
|
|
26
|
+
"data":
|
|
27
|
+
{
|
|
28
|
+
"variant": "box",
|
|
29
|
+
"headline": "{What booking a project kickoff would do for your visitors}",
|
|
30
|
+
"description": "{One or two sentences on what live scheduling adds once it's on}",
|
|
31
|
+
"primaryCta":
|
|
32
|
+
{
|
|
33
|
+
"label": "Add scheduling with Pro",
|
|
34
|
+
"href": "https://ailaunchkit.ai/pricing",
|
|
35
|
+
"external": true,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "back-to-meet",
|
|
41
|
+
"type": "content-block",
|
|
42
|
+
"data":
|
|
43
|
+
{
|
|
44
|
+
"body": "{Looking for a different kind of meeting?}",
|
|
45
|
+
"cta":
|
|
46
|
+
{
|
|
47
|
+
"label": "← All meeting types",
|
|
48
|
+
"href": "/meet",
|
|
49
|
+
"variant": "link",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
]
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
{/* Rendered from frontmatter `sections[]` by the /meet/[slug] placeholder route. A template that carries the scheduling module overrides this file with the live booker. Placeholder copy — replace every {brace} with your own words before you launch. */}
|
|
@@ -22,12 +22,51 @@ sections:
|
|
|
22
22
|
],
|
|
23
23
|
"secondaryCta":
|
|
24
24
|
{
|
|
25
|
-
"label": "
|
|
25
|
+
"label": "Save my leads",
|
|
26
26
|
"href": "https://ailaunchkit.ai/pricing",
|
|
27
27
|
"variant": "outline",
|
|
28
28
|
},
|
|
29
29
|
},
|
|
30
30
|
},
|
|
31
|
+
{
|
|
32
|
+
"id": "meeting-types",
|
|
33
|
+
"type": "items",
|
|
34
|
+
"data":
|
|
35
|
+
{
|
|
36
|
+
"headline": "{Add appointment scheduling to your site}",
|
|
37
|
+
"variant": "tiles",
|
|
38
|
+
"columns": 2,
|
|
39
|
+
"items":
|
|
40
|
+
[
|
|
41
|
+
{
|
|
42
|
+
"title": "Book a Call",
|
|
43
|
+
"description": "{A quick intro call.}",
|
|
44
|
+
"link": { "label": "Book a Call", "href": "/meet/book-a-call" },
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"title": "Onsite Estimate",
|
|
48
|
+
"description": "{We come to you and quote the work.}",
|
|
49
|
+
"link":
|
|
50
|
+
{
|
|
51
|
+
"label": "Onsite Estimate",
|
|
52
|
+
"href": "/meet/onsite-estimate",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"title": "Start Project",
|
|
57
|
+
"description": "{Kick off a project you're ready to start.}",
|
|
58
|
+
"link":
|
|
59
|
+
{ "label": "Start Project", "href": "/meet/start-project" },
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"title": "Onsite Service",
|
|
63
|
+
"description": "{Book a service visit at your location.}",
|
|
64
|
+
"link":
|
|
65
|
+
{ "label": "Onsite Service", "href": "/meet/onsite-service" },
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
31
70
|
]
|
|
32
71
|
---
|
|
33
72
|
|
|
@@ -23,7 +23,7 @@ sections:
|
|
|
23
23
|
"secondaryCta":
|
|
24
24
|
{
|
|
25
25
|
"label": "{Secondary CTA}",
|
|
26
|
-
"href": "/
|
|
26
|
+
"href": "/for",
|
|
27
27
|
"variant": "outline",
|
|
28
28
|
},
|
|
29
29
|
"closingLine": "{Risk Reversal goes here}",
|
|
@@ -303,11 +303,7 @@ sections:
|
|
|
303
303
|
"variant": "outline",
|
|
304
304
|
},
|
|
305
305
|
"secondaryCta":
|
|
306
|
-
{
|
|
307
|
-
"label": "Watch the demo",
|
|
308
|
-
"href": "/use-cases",
|
|
309
|
-
"variant": "link",
|
|
310
|
-
},
|
|
306
|
+
{ "label": "Watch the demo", "href": "/for", "variant": "link" },
|
|
311
307
|
},
|
|
312
308
|
},
|
|
313
309
|
]
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "LandingPage"
|
|
3
|
+
slug: "meet"
|
|
4
|
+
title: "Book a time with us"
|
|
5
|
+
description: "{One sentence on how visitors pick the right meeting type}"
|
|
6
|
+
sections:
|
|
7
|
+
[
|
|
8
|
+
{
|
|
9
|
+
"id": "hero",
|
|
10
|
+
"type": "hero",
|
|
11
|
+
"data":
|
|
12
|
+
{
|
|
13
|
+
"eyebrow": "Meet",
|
|
14
|
+
"headline": "{Book a time with us}",
|
|
15
|
+
"subheadline": "{One sentence on how visitors pick the right meeting type}",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "meeting-types",
|
|
20
|
+
"type": "items",
|
|
21
|
+
"data":
|
|
22
|
+
{
|
|
23
|
+
"variant": "tiles",
|
|
24
|
+
"columns": 2,
|
|
25
|
+
"items":
|
|
26
|
+
[
|
|
27
|
+
{
|
|
28
|
+
"title": "Book a Call",
|
|
29
|
+
"description": "{A quick intro call.}",
|
|
30
|
+
"link": { "label": "Book a Call", "href": "/meet/book-a-call" },
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"title": "Onsite Estimate",
|
|
34
|
+
"description": "{We come to you and quote the work.}",
|
|
35
|
+
"link":
|
|
36
|
+
{
|
|
37
|
+
"label": "Onsite Estimate",
|
|
38
|
+
"href": "/meet/onsite-estimate",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"title": "Start Project",
|
|
43
|
+
"description": "{Kick off a project you're ready to start.}",
|
|
44
|
+
"link":
|
|
45
|
+
{ "label": "Start Project", "href": "/meet/start-project" },
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"title": "Onsite Service",
|
|
49
|
+
"description": "{Book a service visit at your location.}",
|
|
50
|
+
"link":
|
|
51
|
+
{ "label": "Onsite Service", "href": "/meet/onsite-service" },
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
]
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
{/* The Free /meet hub (one static page, rendered by the generic `[slug]` route). With the scheduling module installed its own `meet/` route directory takes precedence and this file is inert. Placeholder copy — replace every {brace} with your own words before you launch. */}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
type: "UseCasesList"
|
|
3
|
-
slug: "
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
slug: "for"
|
|
4
|
+
placeholder: true
|
|
5
|
+
title: "{Customers: who your product or service is for}"
|
|
6
|
+
description: "{One sentence on the customers your product or service serves and the results they get}"
|
|
6
7
|
sections:
|
|
7
8
|
[
|
|
8
9
|
{
|
|
@@ -10,14 +11,14 @@ sections:
|
|
|
10
11
|
"type": "hero",
|
|
11
12
|
"data":
|
|
12
13
|
{
|
|
13
|
-
"eyebrow": "
|
|
14
|
-
"headline": "{
|
|
15
|
-
"subheadline": "{One sentence on the customers your product serves and the results they get}",
|
|
14
|
+
"eyebrow": "Customers",
|
|
15
|
+
"headline": "{Customers: who your product or service is for}",
|
|
16
|
+
"subheadline": "{One sentence on the customers your product or service serves and the results they get}",
|
|
16
17
|
"primaryCta": { "label": "{Primary CTA}", "href": "/contact" },
|
|
17
18
|
"secondaryCta":
|
|
18
19
|
{
|
|
19
20
|
"label": "{Secondary CTA}",
|
|
20
|
-
"href": "/
|
|
21
|
+
"href": "/about",
|
|
21
22
|
"variant": "outline",
|
|
22
23
|
},
|
|
23
24
|
},
|
|
@@ -27,38 +28,38 @@ sections:
|
|
|
27
28
|
"type": "items",
|
|
28
29
|
"data":
|
|
29
30
|
{
|
|
30
|
-
"headline": "{The jobs customers hire your product to do}",
|
|
31
|
+
"headline": "{The jobs customers hire your product or service to do}",
|
|
31
32
|
"description": "{One sentence that helps a visitor find the use case that sounds like them}",
|
|
32
33
|
"columns": 3,
|
|
33
34
|
"items":
|
|
34
35
|
[
|
|
35
36
|
{
|
|
36
|
-
"title": "{Use case 1: the job this customer hires your product to do}",
|
|
37
|
+
"title": "{Use case 1: the job this customer hires your product or service to do}",
|
|
37
38
|
"description": "{Two sentences on who this customer is and the result they get}",
|
|
38
39
|
"link":
|
|
39
40
|
{
|
|
40
41
|
"label": "Read the use case",
|
|
41
|
-
"href": "/
|
|
42
|
+
"href": "/for/persona-1",
|
|
42
43
|
"variant": "link",
|
|
43
44
|
},
|
|
44
45
|
},
|
|
45
46
|
{
|
|
46
|
-
"title": "{Use case 2: the job this customer hires your product to do}",
|
|
47
|
+
"title": "{Use case 2: the job this customer hires your product or service to do}",
|
|
47
48
|
"description": "{Two sentences on who this customer is and the result they get}",
|
|
48
49
|
"link":
|
|
49
50
|
{
|
|
50
51
|
"label": "Read the use case",
|
|
51
|
-
"href": "/
|
|
52
|
+
"href": "/for/persona-2",
|
|
52
53
|
"variant": "link",
|
|
53
54
|
},
|
|
54
55
|
},
|
|
55
56
|
{
|
|
56
|
-
"title": "{Use case 3: the job this customer hires your product to do}",
|
|
57
|
+
"title": "{Use case 3: the job this customer hires your product or service to do}",
|
|
57
58
|
"description": "{Two sentences on who this customer is and the result they get}",
|
|
58
59
|
"link":
|
|
59
60
|
{
|
|
60
61
|
"label": "Read the use case",
|
|
61
|
-
"href": "/
|
|
62
|
+
"href": "/for/persona-3",
|
|
62
63
|
"variant": "link",
|
|
63
64
|
},
|
|
64
65
|
},
|
|
@@ -107,15 +108,15 @@ sections:
|
|
|
107
108
|
"data":
|
|
108
109
|
{
|
|
109
110
|
"variant": "box",
|
|
110
|
-
"headline": "{Switch to your product in time amount or less}",
|
|
111
|
-
"description": "{You shouldn't have to experience a painful problem. With
|
|
111
|
+
"headline": "{Switch to your product or service in time amount or less}",
|
|
112
|
+
"description": "{You shouldn't have to experience a painful problem. With it, you can finally achieve a value outcome or get a big improvement.}",
|
|
112
113
|
"checklist":
|
|
113
114
|
["No credit card required", "Cancel any time", "Live chat support"],
|
|
114
115
|
"primaryCta": { "label": "{Primary CTA}", "href": "/contact" },
|
|
115
116
|
"secondaryCta":
|
|
116
117
|
{
|
|
117
118
|
"label": "{Secondary CTA}",
|
|
118
|
-
"href": "/
|
|
119
|
+
"href": "/about",
|
|
119
120
|
"variant": "outline",
|
|
120
121
|
},
|
|
121
122
|
"closingLine": "{Social Proof goes here}",
|
|
@@ -167,4 +168,4 @@ sections:
|
|
|
167
168
|
]
|
|
168
169
|
---
|
|
169
170
|
|
|
170
|
-
{/* Rendered from frontmatter `sections[]` by the /
|
|
171
|
+
{/* Rendered from frontmatter `sections[]` by the /for route. The three cards link the UseCase pages at /for/<slug>, and their titles become the page's JSON-LD ItemList, so keep each card's title equal to its page's title. Placeholder copy — replace every {brace} with your own words before you launch. */}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @working-theory/database
|
|
2
2
|
|
|
3
|
+
## 0.29.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`dc86291`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/dc862915d1700d8566e3ca82591128e31a7570a9), [`346c3c1`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/346c3c1e8c405ead3080a2f7f6a828fee6d132a9), [`1dfc83e`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/1dfc83ec63e5dc6e862b131b14af2735f4914eb6), [`6ccd87d`](https://github.com/Working-Theory-Labs/ai-launch-kit-internal/commit/6ccd87dbd56df3b886584b215f101af7e2fd68c4)]:
|
|
8
|
+
- @working-theory/validation@0.29.0
|
|
9
|
+
|
|
3
10
|
## 0.28.0
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
package/templates/package.json
CHANGED
|
@@ -19,9 +19,11 @@
|
|
|
19
19
|
"db:seed": "pnpm --filter @working-theory/database run db:seed",
|
|
20
20
|
"db:studio": "pnpm --filter @working-theory/database run db:studio",
|
|
21
21
|
"architecture": "tsx tools/lint-architecture.ts",
|
|
22
|
-
"
|
|
22
|
+
"claude-md:check": "tsx tools/check-claude-md.ts",
|
|
23
|
+
"preflight": "pnpm architecture && pnpm claude-md:check && pnpm type-check && pnpm lint && pnpm build"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
26
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
25
27
|
"@changesets/changelog-github": "^0.7.0",
|
|
26
28
|
"@changesets/cli": "^2.27.0",
|
|
27
29
|
"@eslint/js": "^10.0.1",
|
|
@@ -50,6 +52,7 @@
|
|
|
50
52
|
"jest": "^30.4.2",
|
|
51
53
|
"jiti": "^2.4.2",
|
|
52
54
|
"prettier": "^3.9.4",
|
|
55
|
+
"publint": "^0.3.24",
|
|
53
56
|
"ts-declaration-location": "^1.0.7",
|
|
54
57
|
"ts-jest": "^29.4.11",
|
|
55
58
|
"tsx": "^4.22.4",
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* CLAUDE.md drift check — fails when a template-owned section was edited.
|
|
4
|
+
*
|
|
5
|
+
* This repo's root `CLAUDE.md` comes from AI Launch Kit. Each section between
|
|
6
|
+
* `<!-- ailk:template id="…" sha256="…" -->` and
|
|
7
|
+
* `<!-- /ailk:template id="…" -->` is template-owned, and its begin marker
|
|
8
|
+
* records the SHA-256 of the section's own text. This check re-hashes every
|
|
9
|
+
* section, so it needs no network and no create-ailk. Everything from the
|
|
10
|
+
* `<!-- ailk:site -->` line to the end of the file is yours and is never read.
|
|
11
|
+
*
|
|
12
|
+
* To change a template-owned section, put your change under Site notes
|
|
13
|
+
* instead; `pnpm create ailk@latest --sync-claude-md` restores the sections to
|
|
14
|
+
* the current template.
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* pnpm claude-md:check # or: tsx tools/check-claude-md.ts
|
|
18
|
+
*
|
|
19
|
+
* Exit codes:
|
|
20
|
+
* 0 — every template section matches its recorded hash
|
|
21
|
+
* 1 — a section was edited, a marker is malformed, or the file is missing
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { createHash } from "node:crypto";
|
|
25
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
26
|
+
import { dirname, join, resolve } from "node:path";
|
|
27
|
+
|
|
28
|
+
const ROOT = resolve(dirname(process.argv[1] ?? "."), "..");
|
|
29
|
+
const SYNC = "run pnpm create ailk@latest --sync-claude-md";
|
|
30
|
+
|
|
31
|
+
const BEGIN_RE = /^<!-- ailk:template id="([^"]*)"(?: sha256="([^"]*)")? -->$/;
|
|
32
|
+
const END_RE = /^<!-- \/ailk:template id="([^"]*)" -->$/;
|
|
33
|
+
const ID_RE = /^[a-z][a-z0-9-]*$/;
|
|
34
|
+
const SHA_RE = /^[0-9a-f]{64}$/;
|
|
35
|
+
|
|
36
|
+
function hashBody(body: string): string {
|
|
37
|
+
return createHash("sha256").update(body.replace(/\r\n/g, "\n"), "utf8").digest("hex");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Every finding for `text`, one line each; empty means the file passes. */
|
|
41
|
+
function check(text: string): { findings: string[]; sections: number } {
|
|
42
|
+
const faults: string[] = [];
|
|
43
|
+
const unhashed: string[] = [];
|
|
44
|
+
const edited: string[] = [];
|
|
45
|
+
const seen = new Set<string>();
|
|
46
|
+
let open: { id: string; sha256: string | undefined; bodyStart: number } | undefined;
|
|
47
|
+
let marked = false;
|
|
48
|
+
let site = false;
|
|
49
|
+
let sections = 0;
|
|
50
|
+
|
|
51
|
+
let pos = 0;
|
|
52
|
+
while (pos < text.length) {
|
|
53
|
+
const nl = text.indexOf("\n", pos);
|
|
54
|
+
const next = nl === -1 ? text.length : nl + 1;
|
|
55
|
+
const line = text.slice(pos, nl === -1 ? text.length : nl).replace(/\r$/, "");
|
|
56
|
+
|
|
57
|
+
if (line === "<!-- ailk:site -->") {
|
|
58
|
+
marked = true;
|
|
59
|
+
site = true;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
const begin = BEGIN_RE.exec(line);
|
|
63
|
+
const end = END_RE.exec(line);
|
|
64
|
+
if (begin) {
|
|
65
|
+
marked = true;
|
|
66
|
+
const id = begin[1] ?? "";
|
|
67
|
+
const sha = begin[2];
|
|
68
|
+
if (!ID_RE.test(id)) faults.push(`invalid section id "${id}"`);
|
|
69
|
+
if (sha !== undefined && !SHA_RE.test(sha)) faults.push(`section "${id}" has a malformed sha256`);
|
|
70
|
+
if (open) {
|
|
71
|
+
faults.push(`nested region: section "${id}" opens inside section "${open.id}"`);
|
|
72
|
+
} else {
|
|
73
|
+
if (seen.has(id)) faults.push(`duplicate section id "${id}"`);
|
|
74
|
+
seen.add(id);
|
|
75
|
+
open = { id, sha256: sha, bodyStart: next };
|
|
76
|
+
}
|
|
77
|
+
} else if (end) {
|
|
78
|
+
marked = true;
|
|
79
|
+
const id = end[1] ?? "";
|
|
80
|
+
if (!open) {
|
|
81
|
+
faults.push(`unbalanced marker: end of section "${id}" has no begin marker`);
|
|
82
|
+
} else if (open.id !== id) {
|
|
83
|
+
faults.push(`unbalanced marker: section "${open.id}" is closed by an end marker for "${id}"`);
|
|
84
|
+
open = undefined;
|
|
85
|
+
} else {
|
|
86
|
+
sections += 1;
|
|
87
|
+
const body = text.slice(open.bodyStart, pos);
|
|
88
|
+
if (open.sha256 === undefined) {
|
|
89
|
+
unhashed.push(`begin marker of section "${id}" has no sha256`);
|
|
90
|
+
} else if (SHA_RE.test(open.sha256) && open.sha256 !== hashBody(body)) {
|
|
91
|
+
edited.push(id);
|
|
92
|
+
}
|
|
93
|
+
open = undefined;
|
|
94
|
+
}
|
|
95
|
+
} else if (/^<!-- \/?ailk:template\b/.test(line)) {
|
|
96
|
+
marked = true;
|
|
97
|
+
faults.push(`malformed marker line: ${line}`);
|
|
98
|
+
}
|
|
99
|
+
pos = next;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (!marked) return { findings: [`CLAUDE.md: no ailk:template markers — ${SYNC}`], sections };
|
|
103
|
+
if (open) faults.push(`unbalanced marker: section "${open.id}" has no end marker`);
|
|
104
|
+
if (!site) faults.push("no ailk:site marker");
|
|
105
|
+
// Unhashed markers follow the structural faults, the order create-ailk's
|
|
106
|
+
// own findDrift reports them in.
|
|
107
|
+
return {
|
|
108
|
+
findings: [
|
|
109
|
+
...[...faults, ...unhashed].map((f) => `CLAUDE.md: ${f}`),
|
|
110
|
+
...edited.map(
|
|
111
|
+
(id) =>
|
|
112
|
+
`CLAUDE.md: template section "${id}" was edited by hand — move your change to Site notes, then ${SYNC}`,
|
|
113
|
+
),
|
|
114
|
+
],
|
|
115
|
+
sections,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const path = join(ROOT, "CLAUDE.md");
|
|
120
|
+
const { findings, sections } = existsSync(path)
|
|
121
|
+
? check(readFileSync(path, "utf8"))
|
|
122
|
+
: { findings: ["CLAUDE.md: missing"], sections: 0 };
|
|
123
|
+
|
|
124
|
+
if (findings.length > 0) {
|
|
125
|
+
for (const finding of findings) console.error(finding);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
console.log(`claude-md: OK (${sections} template sections)`);
|