create-ailk 0.27.0 → 0.28.1
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 +84 -7
- package/dist/add-module-core.js +2 -1
- package/dist/add-module.d.ts +2 -1
- package/dist/add-module.js +9 -4
- package/dist/add-route.js +46 -19
- package/dist/body-heading.d.ts +56 -0
- package/dist/body-heading.js +394 -0
- package/dist/cli.js +28 -1
- package/dist/content-payloads.js +2 -2
- package/dist/derive-architecture.js +8 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -1
- package/dist/lib/auth-secret-file.d.ts +6 -2
- package/dist/lib/auth-secret-file.js +46 -20
- package/dist/lib/chrome-readers.d.ts +21 -5
- package/dist/lib/chrome-readers.js +128 -20
- package/dist/lib/declared-env.d.ts +6 -0
- package/dist/lib/declared-env.js +2 -0
- package/dist/lib/env-catalog.js +20 -0
- package/dist/lib/import-graph.d.ts +16 -0
- package/dist/lib/import-graph.js +53 -0
- package/dist/lib/site-modules.d.ts +8 -0
- package/dist/lib/site-modules.js +34 -0
- package/dist/module-architecture.js +23 -14
- package/dist/paid-sections.d.ts +17 -0
- package/dist/paid-sections.js +39 -0
- package/dist/programmatic.d.ts +16 -0
- package/dist/programmatic.js +73 -4
- package/dist/remove-module.d.ts +98 -0
- package/dist/remove-module.js +620 -0
- package/dist/seed-flows.d.ts +2 -2
- package/dist/seed-flows.js +16 -9
- package/dist/site-roster.js +4 -1
- package/dist/starter-grid.d.ts +26 -0
- package/dist/starter-grid.js +34 -0
- package/dist/surfaces.d.ts +26 -0
- package/dist/surfaces.js +105 -9
- package/dist/sync-routes.d.ts +7 -0
- package/dist/sync-routes.js +53 -6
- package/dist/template-pages.d.ts +36 -0
- package/dist/template-pages.js +129 -0
- package/dist/template-record.d.ts +13 -4
- package/dist/template-record.js +8 -4
- package/dist/topology.d.ts +2 -1
- package/dist/topology.js +4 -2
- package/dist/update.d.ts +34 -2
- package/dist/update.js +395 -48
- package/package.json +3 -3
- package/release-scope.json +2 -1
- package/site-templates/aliases/hub.TEMPLATE-MANIFEST.json +115 -0
- package/templates/.env.example +5 -2
- package/templates/apps/api/.env.example +9 -5
- package/templates/apps/api/CLAUDE.md +14 -9
- package/templates/apps/api/src/__tests__/vercel-handler.test.ts +37 -0
- package/templates/apps/api/src/vercel-handler.ts +8 -1
- package/templates/apps/mcp/CLAUDE.md +18 -10
- package/templates/apps/web/.env.example +25 -11
- package/templates/apps/web/CLAUDE.md +45 -4
- package/templates/apps/web/__tests__/setup.ts +7 -0
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +7 -7
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/[pieceId]/versions/[version]/file/route.ts +61 -2
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/__tests__/file-route.test.ts +81 -0
- package/templates/apps/web/app/[locale]/(authed)/account/connect/__tests__/page.test.tsx +197 -0
- package/templates/apps/web/app/[locale]/(authed)/account/connect/page.tsx +152 -0
- package/templates/apps/web/app/[locale]/about/__tests__/about-routes.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/careers/[slug]/[action]/page.tsx +76 -21
- package/templates/apps/web/app/[locale]/careers/[slug]/apply.actions.ts +46 -16
- package/templates/apps/web/app/[locale]/careers/[slug]/page.tsx +20 -3
- package/templates/apps/web/app/[locale]/careers/__tests__/apply.actions.test.ts +180 -2
- package/templates/apps/web/app/[locale]/careers/__tests__/careers-set.test.tsx +6 -2
- package/templates/apps/web/app/[locale]/careers/__tests__/job-apply-page.test.tsx +122 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/case-studies/[slug]/page.tsx +20 -3
- package/templates/apps/web/app/[locale]/case-studies/__tests__/hub-children.test.tsx +65 -0
- package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +6 -2
- package/templates/apps/web/app/[locale]/case-studies/page.tsx +23 -11
- package/templates/apps/web/app/[locale]/checkout/__tests__/thank-you-account.test.tsx +11 -1
- package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/consent.actions.ts +44 -6
- package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +4 -4
- package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +269 -42
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +88 -30
- package/templates/apps/web/app/[locale]/courses/[slug]/page.tsx +20 -3
- package/templates/apps/web/app/[locale]/courses/__tests__/hub-children.test.tsx +32 -0
- package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +6 -2
- package/templates/apps/web/app/[locale]/courses/page.tsx +22 -6
- package/templates/apps/web/app/[locale]/events/[slug]/page.tsx +15 -2
- package/templates/apps/web/app/[locale]/events/__tests__/hub-children.test.tsx +32 -0
- package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +8 -2
- package/templates/apps/web/app/[locale]/events/page.tsx +23 -7
- package/templates/apps/web/app/[locale]/features/__tests__/hub-children.test.tsx +32 -0
- package/templates/apps/web/app/[locale]/features/page.tsx +23 -25
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/flow.actions.test.ts +95 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/save.actions.test.ts +193 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/email-moment.ts +92 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/flow.actions.ts +10 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsClient.tsx +513 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsEmailStep.tsx +122 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/ResultsClient.no-commerce.test.tsx +195 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/landing.test.tsx +293 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/__tests__/page.test.tsx +397 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/checkout-seam.ts +74 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/results/[payload]/page.tsx +264 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/save.actions.ts +75 -0
- package/templates/apps/web/app/[locale]/for/__tests__/hub-children.test.tsx +32 -0
- package/templates/apps/web/app/[locale]/for/__tests__/page-renderer-migration.test.tsx +5 -1
- package/templates/apps/web/app/[locale]/for/page.tsx +23 -25
- package/templates/apps/web/app/[locale]/how-to/[slug]/page.tsx +20 -3
- package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/integrations/[slug]/page.tsx +25 -4
- package/templates/apps/web/app/[locale]/integrations/__tests__/hub-children.test.tsx +38 -0
- package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +8 -2
- package/templates/apps/web/app/[locale]/integrations/page.tsx +23 -11
- package/templates/apps/web/app/[locale]/layout.tsx +157 -139
- package/templates/apps/web/app/[locale]/page.tsx +51 -3
- package/templates/apps/web/app/[locale]/partners/[slug]/page.tsx +16 -3
- package/templates/apps/web/app/[locale]/partners/__tests__/hub-children.test.tsx +32 -0
- package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +6 -2
- package/templates/apps/web/app/[locale]/partners/page.tsx +22 -6
- package/templates/apps/web/app/[locale]/portfolio/__tests__/hub-children.test.tsx +38 -0
- package/templates/apps/web/app/[locale]/portfolio/page.tsx +25 -24
- package/templates/apps/web/app/[locale]/pricing/[slug]/__tests__/page.test.tsx +321 -0
- package/templates/apps/web/app/[locale]/pricing/[slug]/page.tsx +87 -0
- package/templates/apps/web/app/[locale]/pricing/__tests__/offerings.test.tsx +3 -0
- package/templates/apps/web/app/[locale]/pricing/__tests__/pricing-pages.test.tsx +215 -0
- package/templates/apps/web/app/[locale]/pricing/page.tsx +56 -341
- package/templates/apps/web/app/[locale]/products/[slug]/page.tsx +21 -4
- package/templates/apps/web/app/[locale]/products/__tests__/hub-children.test.tsx +32 -0
- package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +8 -2
- package/templates/apps/web/app/[locale]/products/page.tsx +22 -6
- package/templates/apps/web/app/[locale]/projects/__tests__/hub-children.test.tsx +32 -0
- package/templates/apps/web/app/[locale]/projects/__tests__/page-renderer-migration.test.tsx +4 -0
- package/templates/apps/web/app/[locale]/projects/page.tsx +18 -11
- package/templates/apps/web/app/[locale]/resources/[slug]/page.tsx +25 -4
- package/templates/apps/web/app/[locale]/resources/__tests__/hub-children.test.tsx +38 -0
- package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +6 -2
- package/templates/apps/web/app/[locale]/resources/page.tsx +20 -10
- package/templates/apps/web/app/[locale]/services/[slug]/[child]/page.tsx +68 -0
- package/templates/apps/web/app/[locale]/services/[slug]/page.tsx +64 -9
- package/templates/apps/web/app/[locale]/services/__tests__/hub-children.test.tsx +158 -0
- package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +12 -2
- package/templates/apps/web/app/[locale]/services/__tests__/service-detail-sections.test.tsx +224 -0
- package/templates/apps/web/app/[locale]/services/__tests__/service-families.test.tsx +368 -0
- package/templates/apps/web/app/[locale]/services/page.tsx +45 -19
- package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/team/__tests__/hub-children.test.tsx +32 -0
- package/templates/apps/web/app/[locale]/team/page.tsx +25 -24
- package/templates/apps/web/app/[locale]/tech-articles/[slug]/page.tsx +24 -3
- package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/templates/[slug]/__tests__/page.test.tsx +203 -0
- package/templates/apps/web/app/[locale]/templates/[slug]/page.tsx +81 -0
- package/templates/apps/web/app/[locale]/templates/__tests__/page.test.tsx +237 -0
- package/templates/apps/web/app/[locale]/templates/page.tsx +108 -0
- package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/whitepapers/[slug]/page.tsx +24 -3
- package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/api/auth/hub/authorize/__tests__/route.test.ts +204 -2
- package/templates/apps/web/app/api/auth/hub/authorize/route.ts +151 -33
- package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/__tests__/route.test.ts +233 -7
- package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/route.ts +92 -41
- package/templates/apps/web/app/api/offerings/checkout/__tests__/route.test.ts +77 -39
- package/templates/apps/web/app/llms.txt/route.ts +41 -3
- package/templates/apps/web/app/robots.txt/route.ts +5 -1
- package/templates/apps/web/app/sitemap.xml/route.ts +45 -3
- package/templates/apps/web/auth.ts +102 -50
- package/templates/apps/web/components/signed-in-nav.tsx +8 -1
- package/templates/apps/web/lib/__tests__/bot-check.test.ts +254 -0
- package/templates/apps/web/lib/__tests__/consent-visitor.test.ts +212 -13
- package/templates/apps/web/lib/__tests__/deck-page.test.ts +13 -1
- package/templates/apps/web/lib/__tests__/docs-index.test.ts +93 -0
- package/templates/apps/web/lib/__tests__/docs-path.test.ts +168 -0
- package/templates/apps/web/lib/__tests__/hub-children.fixtures.ts +279 -0
- package/templates/apps/web/lib/__tests__/nav-label-keys.test.ts +138 -0
- package/templates/apps/web/lib/__tests__/newsletter.actions.test.ts +178 -2
- package/templates/apps/web/lib/__tests__/offerings-pricing.test.ts +183 -0
- package/templates/apps/web/lib/__tests__/page-chrome.test.ts +412 -0
- package/templates/apps/web/lib/__tests__/pricing-page.test.ts +142 -0
- package/templates/apps/web/lib/__tests__/relay.test.ts +202 -10
- package/templates/apps/web/lib/__tests__/route-family.test.ts +57 -0
- package/templates/apps/web/lib/__tests__/service-listing.test.ts +111 -0
- package/templates/apps/web/lib/__tests__/services-path.test.ts +96 -0
- package/templates/apps/web/lib/__tests__/site-header.test.ts +151 -0
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +148 -6
- package/templates/apps/web/lib/__tests__/telemetry-scrub.test.ts +84 -0
- package/templates/apps/web/lib/__tests__/template-listing.test.ts +158 -0
- package/templates/apps/web/lib/auth-secret.ts +57 -0
- package/templates/apps/web/lib/bot-check.ts +138 -0
- package/templates/apps/web/lib/consent-visitor.ts +81 -7
- package/templates/apps/web/lib/deck-page.ts +6 -3
- package/templates/apps/web/lib/docs-index.ts +100 -0
- package/templates/apps/web/lib/docs-path.ts +94 -0
- package/templates/apps/web/lib/hub-children.tsx +318 -0
- package/templates/apps/web/lib/modules.generated.ts +9 -0
- package/templates/apps/web/lib/nav-label-check.ts +61 -0
- package/templates/apps/web/lib/nav-label-keys.ts +78 -0
- package/templates/apps/web/lib/newsletter.actions.ts +31 -6
- package/templates/apps/web/lib/offerings-pricing.ts +135 -6
- package/templates/apps/web/lib/page-chrome.ts +367 -0
- package/templates/apps/web/lib/posting-title.ts +26 -4
- package/templates/apps/web/lib/pricing-page.ts +430 -0
- package/templates/apps/web/lib/relay.ts +31 -106
- package/templates/apps/web/lib/route-family.ts +69 -0
- package/templates/apps/web/lib/service-listing.ts +89 -0
- package/templates/apps/web/lib/services-path.ts +97 -0
- package/templates/apps/web/lib/site-header.ts +94 -0
- package/templates/apps/web/lib/telemetry-scrub.ts +68 -3
- package/templates/apps/web/lib/template-listing.ts +169 -0
- package/templates/apps/web/messages/en.json +86 -30
- package/templates/apps/web/middleware.ts +171 -11
- package/templates/apps/web/next.config.mjs +211 -2
- package/templates/apps/web/package.json +1 -1
- package/templates/apps/web/scripts/assert-content-bundled.ts +28 -6
- package/templates/apps/web/scripts/check-nav-labels.ts +39 -0
- package/templates/apps/web/sentry.server.config.ts +30 -2
- package/templates/apps/web/src/lib/__tests__/rate-limit.test.ts +67 -9
- package/templates/apps/web/src/lib/rate-limit.ts +68 -27
- package/templates/apps/web/src/lib/routes.ts +15 -1
- package/templates/tools/declared-env.ts +7 -0
- package/versions.json +48 -48
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The templates route family's generated seeds (#10051 D10) — the /templates
|
|
3
|
+
* hub seed plus one placeholder TemplatePage per AILK template, derived from
|
|
4
|
+
* `TEMPLATE_MANIFESTS` so a new template never needs a hand-written seed.
|
|
5
|
+
* `add-route templates` writes them (`GENERATED_SEEDS` in `add-route.ts`);
|
|
6
|
+
* the site then edits or deletes them like any content.
|
|
7
|
+
*
|
|
8
|
+
* A seed never invents a fact: its copy is placeholder (`placeholder: true`,
|
|
9
|
+
* renderPage's replace-before-launch label), it has no thumbnail, and its Get
|
|
10
|
+
* it action is `/contact`. Only a template whose `templateDelivery` is
|
|
11
|
+
* `"free"` gets `price: 0` — a paid template's price is the site's to set.
|
|
12
|
+
*
|
|
13
|
+
* Pure (no fs). create-ailk has no YAML dependency by design, so every
|
|
14
|
+
* frontmatter value is written as `JSON.stringify(value)` — a JSON scalar,
|
|
15
|
+
* array or object is valid YAML flow syntax (the `derive-architecture.ts`
|
|
16
|
+
* precedent).
|
|
17
|
+
*/
|
|
18
|
+
import { RECOGNIZED_MODULES } from "./parse-args.js";
|
|
19
|
+
import { TEMPLATE_MANIFESTS, templateDelivery, } from "./template-manifest.js";
|
|
20
|
+
/** What every template carries whatever its modules: the base site. */
|
|
21
|
+
export const BASE_INCLUDE = {
|
|
22
|
+
title: "The base site",
|
|
23
|
+
description: "Your pages with structured data on every one, plus an API and an MCP server agents can read.",
|
|
24
|
+
};
|
|
25
|
+
/** One row per module, typed exhaustively so a new module fails type-check. */
|
|
26
|
+
export const MODULE_INCLUDES = {
|
|
27
|
+
marketing: {
|
|
28
|
+
title: "Marketing pages",
|
|
29
|
+
description: "The pages a marketing site needs, with lead capture.",
|
|
30
|
+
},
|
|
31
|
+
"docs-blog": {
|
|
32
|
+
title: "Docs and blog",
|
|
33
|
+
description: "A documentation section and a blog, written as content files.",
|
|
34
|
+
},
|
|
35
|
+
"multi-tenant": {
|
|
36
|
+
title: "Organizations and workspaces",
|
|
37
|
+
description: "Many customers on one deployment, each with their own members.",
|
|
38
|
+
},
|
|
39
|
+
workspace: {
|
|
40
|
+
title: "Admin",
|
|
41
|
+
description: "Your own signed-in area to edit pages, manage assets and review submissions.",
|
|
42
|
+
},
|
|
43
|
+
scheduling: {
|
|
44
|
+
title: "Scheduling",
|
|
45
|
+
description: "Booking pages visitors use to schedule time with you.",
|
|
46
|
+
},
|
|
47
|
+
"signal-collectors": {
|
|
48
|
+
title: "Quizzes and reports",
|
|
49
|
+
description: "Assessments and downloadable reports that capture interested visitors.",
|
|
50
|
+
},
|
|
51
|
+
commerce: {
|
|
52
|
+
title: "Checkout",
|
|
53
|
+
description: "Take payment through your own Stripe account.",
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
const HUB_SEED_PATH = "content/en/TemplatesList/templates.mdx";
|
|
57
|
+
/** Words a naive capitalisation would mis-case in a template name. */
|
|
58
|
+
const WORD_CASING = { saas: "SaaS" };
|
|
59
|
+
/** `marketing-site-free` → `Marketing Site Free`; `saas-product` → `SaaS Product`. */
|
|
60
|
+
function titleCase(name) {
|
|
61
|
+
return name
|
|
62
|
+
.split("-")
|
|
63
|
+
.map((word) => WORD_CASING[word] ?? word.charAt(0).toUpperCase() + word.slice(1))
|
|
64
|
+
.join(" ");
|
|
65
|
+
}
|
|
66
|
+
/** A seed file: a JSON-valued YAML frontmatter block and a placeholder body. */
|
|
67
|
+
function mdx(frontmatter, body) {
|
|
68
|
+
const lines = Object.entries(frontmatter).map(([key, value]) => `${key}: ${JSON.stringify(value)}`);
|
|
69
|
+
return `---\n${lines.join("\n")}\n---\n\n${body}\n`;
|
|
70
|
+
}
|
|
71
|
+
function templateSeed(name, manifest) {
|
|
72
|
+
const title = titleCase(name);
|
|
73
|
+
const includes = [
|
|
74
|
+
BASE_INCLUDE,
|
|
75
|
+
...RECOGNIZED_MODULES.filter((module) => manifest.requires.includes(module)).map((module) => MODULE_INCLUDES[module]),
|
|
76
|
+
];
|
|
77
|
+
const free = templateDelivery(manifest) === "free";
|
|
78
|
+
return {
|
|
79
|
+
path: `content/en/TemplatePage/${name}.mdx`,
|
|
80
|
+
text: mdx({
|
|
81
|
+
type: "TemplatePage",
|
|
82
|
+
slug: name,
|
|
83
|
+
title,
|
|
84
|
+
description: `Replace with a one-sentence description of the ${title} template.`,
|
|
85
|
+
summary: `Replace with what a site built on ${title} gives a customer.`,
|
|
86
|
+
placeholder: true,
|
|
87
|
+
template: name,
|
|
88
|
+
categories: [...manifest.categories],
|
|
89
|
+
includes,
|
|
90
|
+
demoUrl: `https://${name}.salessmyth.com`,
|
|
91
|
+
getItUrl: "/contact",
|
|
92
|
+
...(free && { price: 0, priceCurrency: "USD" }),
|
|
93
|
+
}, `{/* Placeholder: /templates/${name} renders its hero and "What's included" from the frontmatter above. Replace the copy, add a thumbnail and set getItUrl to your buy link before launch. */}`),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The hub seed, then one TemplatePage seed per manifest, sorted by name.
|
|
98
|
+
* `manifests` defaults to the frozen registry; a test may pass its own.
|
|
99
|
+
*/
|
|
100
|
+
export function templatePageSeeds(manifests = TEMPLATE_MANIFESTS) {
|
|
101
|
+
const description = "Replace with a one-sentence description of the templates you sell.";
|
|
102
|
+
const hub = {
|
|
103
|
+
path: HUB_SEED_PATH,
|
|
104
|
+
text: mdx({
|
|
105
|
+
type: "TemplatesList",
|
|
106
|
+
slug: "templates",
|
|
107
|
+
title: "Templates",
|
|
108
|
+
description,
|
|
109
|
+
placeholder: true,
|
|
110
|
+
// A tight hero keeps the first cards — the hub's actions — inside
|
|
111
|
+
// the first screen (design review round 1, B1).
|
|
112
|
+
sections: [
|
|
113
|
+
{
|
|
114
|
+
id: "templates-hero",
|
|
115
|
+
type: "hero",
|
|
116
|
+
data: {
|
|
117
|
+
headline: "Templates",
|
|
118
|
+
subheadline: description,
|
|
119
|
+
gapBelow: "tight",
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
}, "{/* Placeholder: /templates lists every TemplatePage automatically. Replace the description before launch. */}"),
|
|
124
|
+
};
|
|
125
|
+
const pages = Object.keys(manifests)
|
|
126
|
+
.sort()
|
|
127
|
+
.map((name) => templateSeed(name, manifests[name]));
|
|
128
|
+
return [hub, ...pages];
|
|
129
|
+
}
|
|
@@ -49,14 +49,23 @@ export interface TemplateRecord {
|
|
|
49
49
|
export declare class TemplateRecordError extends Error {
|
|
50
50
|
constructor(message: string);
|
|
51
51
|
}
|
|
52
|
+
export interface ParseTemplateRecordOptions {
|
|
53
|
+
/**
|
|
54
|
+
* Called with each traversal-safe `files` key that is not a recordable path
|
|
55
|
+
* — a path a later create-ailk stopped recording, such as a generated file
|
|
56
|
+
* (#10173) — instead of refusing the record. The row is left out of the
|
|
57
|
+
* result. An unsafe key still refuses.
|
|
58
|
+
*/
|
|
59
|
+
onUnrecordable?: (key: string) => void;
|
|
60
|
+
}
|
|
52
61
|
/**
|
|
53
62
|
* Parse `.ailk-template-files.json` text, refusing — naming the field — on:
|
|
54
63
|
* JSON that does not parse; `schema !== 1`; an unknown top-level key; an
|
|
55
|
-
* empty `projectName`; a `files` key that is not a recordable path
|
|
56
|
-
* `sha256` that is not 64 lowercase hex; a
|
|
57
|
-
* string (#8522 D1).
|
|
64
|
+
* empty `projectName`; a `files` key that is not a recordable path (unless
|
|
65
|
+
* `onUnrecordable` takes it); a `sha256` that is not 64 lowercase hex; a
|
|
66
|
+
* `version` that is not a semver string (#8522 D1).
|
|
58
67
|
*/
|
|
59
|
-
export declare function parseTemplateRecord(text: string): TemplateRecord;
|
|
68
|
+
export declare function parseTemplateRecord(text: string, opts?: ParseTemplateRecordOptions): TemplateRecord;
|
|
60
69
|
/** `record` as `scaffold()` and `update` write it: sorted keys, trailing newline. */
|
|
61
70
|
export declare function serializeTemplateRecord(record: TemplateRecord): string;
|
|
62
71
|
export interface PlanTemplateRecordOptions {
|
package/dist/template-record.js
CHANGED
|
@@ -128,11 +128,11 @@ function isSafeRecordKey(key) {
|
|
|
128
128
|
/**
|
|
129
129
|
* Parse `.ailk-template-files.json` text, refusing — naming the field — on:
|
|
130
130
|
* JSON that does not parse; `schema !== 1`; an unknown top-level key; an
|
|
131
|
-
* empty `projectName`; a `files` key that is not a recordable path
|
|
132
|
-
* `sha256` that is not 64 lowercase hex; a
|
|
133
|
-
* string (#8522 D1).
|
|
131
|
+
* empty `projectName`; a `files` key that is not a recordable path (unless
|
|
132
|
+
* `onUnrecordable` takes it); a `sha256` that is not 64 lowercase hex; a
|
|
133
|
+
* `version` that is not a semver string (#8522 D1).
|
|
134
134
|
*/
|
|
135
|
-
export function parseTemplateRecord(text) {
|
|
135
|
+
export function parseTemplateRecord(text, opts = {}) {
|
|
136
136
|
let doc;
|
|
137
137
|
try {
|
|
138
138
|
doc = JSON.parse(text);
|
|
@@ -167,6 +167,10 @@ export function parseTemplateRecord(text) {
|
|
|
167
167
|
throw new TemplateRecordError(`${TEMPLATE_RECORD_PATH} "files" has an unsafe key "${key}"`);
|
|
168
168
|
}
|
|
169
169
|
if (!isRecordable(key)) {
|
|
170
|
+
if (opts.onUnrecordable !== undefined) {
|
|
171
|
+
opts.onUnrecordable(key);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
170
174
|
throw new TemplateRecordError(`${TEMPLATE_RECORD_PATH} "files" has a key "${key}" that is not a recordable path`);
|
|
171
175
|
}
|
|
172
176
|
if (typeof value !== "object" || value === null) {
|
package/dist/topology.d.ts
CHANGED
|
@@ -32,7 +32,8 @@ export declare const SPOKE_EXCLUDED_MODULE_PATHS: readonly string[];
|
|
|
32
32
|
* The `(authed)` seeds of the sign-in-through-the-hub mode (#7894 D9): the
|
|
33
33
|
* whole `(authed)` group goes in the default mode; in the hub mode its account
|
|
34
34
|
* area, layout and gate seam stay, and only these go — the operator surfaces,
|
|
35
|
-
* the Better Auth gate
|
|
35
|
+
* the Better Auth gate, the hub's own consent page (#9966 D2, a 404 on a
|
|
36
|
+
* spoke) and the suites that mock `auth.ts` by path.
|
|
36
37
|
*/
|
|
37
38
|
export declare const HUB_MODE_AUTHED_SEEDS: readonly string[];
|
|
38
39
|
/** The generated seam files (D5; #7874 D12). A seam is rewritten, never removed. */
|
package/dist/topology.js
CHANGED
|
@@ -86,11 +86,13 @@ export const SPOKE_EXCLUDED_MODULE_PATHS = [
|
|
|
86
86
|
* The `(authed)` seeds of the sign-in-through-the-hub mode (#7894 D9): the
|
|
87
87
|
* whole `(authed)` group goes in the default mode; in the hub mode its account
|
|
88
88
|
* area, layout and gate seam stay, and only these go — the operator surfaces,
|
|
89
|
-
* the Better Auth gate
|
|
89
|
+
* the Better Auth gate, the hub's own consent page (#9966 D2, a 404 on a
|
|
90
|
+
* spoke) and the suites that mock `auth.ts` by path.
|
|
90
91
|
*/
|
|
91
92
|
export const HUB_MODE_AUTHED_SEEDS = [
|
|
92
93
|
"apps/web/app/[locale]/(authed)/__tests__",
|
|
93
94
|
"apps/web/app/[locale]/(authed)/account/__tests__",
|
|
95
|
+
"apps/web/app/[locale]/(authed)/account/connect",
|
|
94
96
|
"apps/web/app/[locale]/(authed)/admin",
|
|
95
97
|
"apps/web/app/[locale]/(authed)/appointments",
|
|
96
98
|
"apps/web/app/[locale]/(authed)/edit",
|
|
@@ -154,7 +156,7 @@ export function spokeRemovedRoots(opts) {
|
|
|
154
156
|
}
|
|
155
157
|
/**
|
|
156
158
|
* The seeds that apply — an mcp seed is moot when `apps/mcp` itself goes; in
|
|
157
|
-
* the hub sign-in mode the `(authed)` seed is replaced by
|
|
159
|
+
* the hub sign-in mode the `(authed)` seed is replaced by nine (#7894 D9).
|
|
158
160
|
*/
|
|
159
161
|
function spokeSeeds(opts) {
|
|
160
162
|
return modeSeeds(opts.signIn).filter((seed) => opts.mcp || !underPrefix(seed, SPOKE_MCP_ROOT));
|
package/dist/update.d.ts
CHANGED
|
@@ -40,16 +40,48 @@ export interface UpdateResult {
|
|
|
40
40
|
path: string;
|
|
41
41
|
reason: string;
|
|
42
42
|
}>;
|
|
43
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Per file left under review or skipped — or a relative import the written
|
|
45
|
+
* code names that the site will not have (`missing`) — the template tests
|
|
46
|
+
* (#8704) and the other template files (`importers`, #10173) held with it
|
|
47
|
+
* — the files that import it, or, when it is a file staying at the site's
|
|
48
|
+
* version, the written files it imports — which keep the site's version so
|
|
49
|
+
* the tree never imports what it lacks.
|
|
50
|
+
*/
|
|
44
51
|
heldBack: Array<{
|
|
45
52
|
file: string;
|
|
46
53
|
tests: string[];
|
|
54
|
+
importers?: string[];
|
|
55
|
+
missing?: true;
|
|
47
56
|
}>;
|
|
57
|
+
/** The `project.yaml` `env_contract` rows added for env vars the written files read (#10172). */
|
|
58
|
+
envRowsAdded?: string[];
|
|
59
|
+
/** Record rows dropped because the path is no longer recordable (#10173). */
|
|
60
|
+
droppedRows?: string[];
|
|
61
|
+
/** The mdx-body pages under `content/` given a `# ` heading this run (#7495). */
|
|
62
|
+
headingsAdded: string[];
|
|
48
63
|
backfilled?: {
|
|
49
64
|
version: string;
|
|
50
65
|
files: number;
|
|
51
66
|
};
|
|
52
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* The site's messages catalog with every key the template's copy has and it
|
|
70
|
+
* lacks (#10173): the site's values always win, nothing is removed, and the
|
|
71
|
+
* keys it gains follow its own. A key that is an object on one side and a
|
|
72
|
+
* value on the other is a conflict, and nothing is merged.
|
|
73
|
+
*/
|
|
74
|
+
export declare function mergeMessagesAdditively(ours: string, theirs: string): {
|
|
75
|
+
status: "merged";
|
|
76
|
+
text: string;
|
|
77
|
+
added: number;
|
|
78
|
+
} | {
|
|
79
|
+
status: "conflict";
|
|
80
|
+
keys: string[];
|
|
81
|
+
} | {
|
|
82
|
+
status: "invalid";
|
|
83
|
+
reason: string;
|
|
84
|
+
};
|
|
53
85
|
export declare function updateSite(opts: UpdateSiteOptions): Promise<UpdateResult>;
|
|
54
86
|
/** The printed report (D9): one section per non-empty list, in order. */
|
|
55
87
|
export declare function formatUpdateReport(result: UpdateResult): string;
|
|
@@ -57,6 +89,6 @@ export interface UpdateArgs {
|
|
|
57
89
|
target: string | undefined;
|
|
58
90
|
help: boolean;
|
|
59
91
|
}
|
|
60
|
-
export declare const UPDATE_HELP = "create-ailk update \u2014 bring template fixes into a site's copied app code.\n\nUsage:\n create-ailk update [<target-dir>]\n\nArguments:\n <target-dir> The existing site. Defaults to the current dir.\n\nOptions:\n --help, -h Print this message.\n\nReads .ailk-template-files.json (written beside .ailk-site-manifest.json by\nevery template scaffold) to tell an untouched copy from an edit. An\nuntouched apps/web, apps/api or apps/mcp file, or a root tools/jest file the\napp jest configs require, whose template copy changed is overwritten. An\nedited file whose template copy also changed is three-way merged with\n`git` (git must be on PATH); a conflict leaves the file alone and is\nlisted under \"Needs review\". Every template
|
|
92
|
+
export declare const UPDATE_HELP = "create-ailk update \u2014 bring template fixes into a site's copied app code.\n\nUsage:\n create-ailk update [<target-dir>]\n\nArguments:\n <target-dir> The existing site. Defaults to the current dir.\n\nOptions:\n --help, -h Print this message.\n\nReads .ailk-template-files.json (written beside .ailk-site-manifest.json by\nevery template scaffold) to tell an untouched copy from an edit. An\nuntouched apps/web, apps/api or apps/mcp file, or a root tools/jest file the\napp jest configs require, whose template copy changed is overwritten. An\nedited file whose template copy also changed is three-way merged with\n`git` (git must be on PATH); a conflict leaves the file alone and is\nlisted under \"Needs review\"; an apps/web/messages catalog instead gains the\ntemplate's new keys and keeps every value it has, and is reviewed only when a\nkey is an object on one side and a value on the other. Every template file,\ntest or not, that imports a file left under \"Needs review\" or \"Skipped\" (by a\nrelative or @/ import, transitively) is held at the site's version with it,\nits record entry is not advanced, and it is listed under \"Held back with\n<file>\" \u2014 reconcile the file, then run update again to bring it forward. A\nwritten file whose import names a file the site will not have is held the\nsame way, under \"Held back with <file> (not in this site)\". Every other file\nin the run still updates. When project.yaml has an env_contract block, each\nenv var the written files read that has no row gains one; no row is edited.\nA record row at a path create-ailk no longer records is dropped and listed.\nA site with no record gets one on its first run, from the version its\n.ailk-site-manifest.json already records. A site scaffolded before\n@working-theory/mcp-server has its copied apps/mcp moved to the boot set:\nthe server and each module's paid MCP pack join apps/mcp/package.json, the\ncopied server files go, and apps/mcp/src/lib/paid-tools.generated.ts is\nrewritten on every run. A site scaffolded before @working-theory/api has its\ncopied apps/api moved to the boot file: the app becomes @working-theory/app-api,\nthe package and the six @working-theory/api-<module> packages join\napps/api/package.json, its bins and build:vercel delegate to the package, and\nthe copied server files go. Run `pnpm install` after either move, since the\napp's package.json gained dependencies. Each mdx-body page in content/ with no\n'# ' heading gets its title and description written into its body as its\nheading and intro, listed under \"Page heading added\"; a page with one heading\nis left as it is, and one with several, or one whose frontmatter it cannot\nread, is listed under \"Needs review\". Commit before running, and review the\ndiff after.\n";
|
|
61
93
|
/** Parse the argv AFTER the `update` word. Strict `node:util` parseArgs, like `parseAdoptArgs`. */
|
|
62
94
|
export declare function parseUpdateArgs(argv: string[]): UpdateArgs;
|