create-ailk 0.4.0 → 0.5.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.
Files changed (146) hide show
  1. package/component-catalog.json +11939 -0
  2. package/component-catalog.md +176 -64
  3. package/dist/cli.js +29 -1
  4. package/dist/derive-architecture.js +5 -2
  5. package/dist/lib/extract-module-bundle.d.ts +50 -2
  6. package/dist/lib/extract-module-bundle.js +223 -15
  7. package/dist/lib/fetch-guard.d.ts +28 -0
  8. package/dist/lib/fetch-guard.js +101 -0
  9. package/dist/lib/fetch-module.js +4 -0
  10. package/dist/lib/fetch-template.js +4 -0
  11. package/dist/module-architecture.d.ts +59 -8
  12. package/dist/module-architecture.js +334 -115
  13. package/dist/parse-args.js +6 -2
  14. package/dist/programmatic.d.ts +10 -0
  15. package/dist/programmatic.js +134 -19
  16. package/dist/site-chrome.d.ts +80 -0
  17. package/dist/site-chrome.js +135 -0
  18. package/dist/surfaces.d.ts +21 -6
  19. package/dist/surfaces.js +107 -32
  20. package/dist/template-manifest.d.ts +55 -3
  21. package/dist/template-manifest.js +181 -12
  22. package/dist/template-names.d.ts +1 -1
  23. package/dist/template-names.js +1 -0
  24. package/package.json +9 -2
  25. package/site-templates/_base/ailk-template.json +6 -0
  26. package/site-templates/_base/content/en/Pricing/pricing.mdx +169 -0
  27. package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +331 -0
  28. package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +393 -0
  29. package/site-templates/marketing-site/ailk-template.json +11 -0
  30. package/site-templates/marketing-site/content/en/blog/05-this-vc-morning-routine-will-make-you-super-annoying.mdx +36 -0
  31. package/site-templates/marketing-site/provenance.json +4 -0
  32. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +288 -0
  33. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +285 -0
  34. package/site-templates/marketing-site-free/ailk-template.json +2 -1
  35. package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +271 -0
  36. package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +324 -0
  37. package/site-templates/minimalism-site/ailk-template.json +21 -0
  38. package/site-templates/minimalism-site/assets/avatar-placeholder-1.svg +7 -0
  39. package/site-templates/minimalism-site/assets/avatar-placeholder-2.svg +7 -0
  40. package/site-templates/minimalism-site/assets/avatar-placeholder-3.svg +7 -0
  41. package/site-templates/minimalism-site/assets/avatar-placeholder-4.svg +7 -0
  42. package/site-templates/minimalism-site/assets/avatar-placeholder-5.svg +7 -0
  43. package/site-templates/minimalism-site/assets/avatar-placeholder-6.svg +7 -0
  44. package/site-templates/minimalism-site/assets/hero-backdrop.svg +17 -0
  45. package/site-templates/minimalism-site/assets/logo-placeholder-1.svg +6 -0
  46. package/site-templates/minimalism-site/assets/logo-placeholder-2.svg +6 -0
  47. package/site-templates/minimalism-site/assets/logo-placeholder-3.svg +6 -0
  48. package/site-templates/minimalism-site/content/en/AboutPage/about.mdx +110 -0
  49. package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +68 -0
  50. package/site-templates/minimalism-site/content/en/FAQPage/faq.mdx +57 -0
  51. package/site-templates/minimalism-site/content/en/HomePage/home.mdx +214 -0
  52. package/site-templates/minimalism-site/content/en/LandingPage/referral.mdx +77 -0
  53. package/site-templates/minimalism-site/content/en/LandingPage/reports.mdx +73 -0
  54. package/site-templates/minimalism-site/content/en/ReportPage/annual-letter-2024.mdx +52 -0
  55. package/site-templates/minimalism-site/content/en/ReportPage/field-notes-2023.mdx +52 -0
  56. package/site-templates/minimalism-site/content/en/ReportPage/platform-shift-2025.mdx +52 -0
  57. package/site-templates/minimalism-site/content/en/ReportPage/state-of-the-market-2026.mdx +52 -0
  58. package/site-templates/minimalism-site/content/en/Service/first-engagement.mdx +38 -0
  59. package/site-templates/minimalism-site/content/en/Service/second-engagement.mdx +38 -0
  60. package/site-templates/minimalism-site/content/en/Service/third-engagement.mdx +38 -0
  61. package/site-templates/minimalism-site/content/en/ServicesList/services.mdx +73 -0
  62. package/site-templates/minimalism-site/flows/referral.flow.json +71 -0
  63. package/site-templates/minimalism-site/provenance.json +4 -0
  64. package/site-templates/saas-product/TEMPLATE-MANIFEST.md +61 -0
  65. package/site-templates/saas-product/ailk-template.json +16 -0
  66. package/site-templates/saas-product/provenance.json +10 -0
  67. package/templates/.claude/skills/README.md +16 -25
  68. package/templates/.env.example +32 -7
  69. package/templates/.github/workflows/ci.yml +48 -0
  70. package/templates/README.md +3 -1
  71. package/templates/apps/api/CLAUDE.md +4 -1
  72. package/templates/apps/api/eslint.config.mjs +69 -0
  73. package/templates/apps/api/package.json +6 -2
  74. package/templates/apps/api/src/__tests__/module-exclusion.test.ts +6 -2
  75. package/templates/apps/api/src/__tests__/review-surface-registration.test.ts +167 -0
  76. package/templates/apps/api/src/__tests__/workspace-module-registration.test.ts +8 -1
  77. package/templates/apps/api/src/lib/__mocks__/prisma.ts +3 -0
  78. package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +339 -0
  79. package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +108 -0
  80. package/templates/apps/api/src/middleware/default-tenant.ts +136 -0
  81. package/templates/apps/api/src/routes/leads/__tests__/list.test.ts +171 -0
  82. package/templates/apps/api/src/routes/leads/list.ts +104 -0
  83. package/templates/apps/api/src/server.ts +82 -6
  84. package/templates/apps/api/src/services/__tests__/lead-promotion.test.ts +408 -0
  85. package/templates/apps/api/src/services/__tests__/leads-inbox.test.ts +329 -0
  86. package/templates/apps/api/src/services/default-tenant.ts +261 -0
  87. package/templates/apps/api/src/services/lead-promotion.ts +161 -0
  88. package/templates/apps/api/src/services/leads-inbox.ts +263 -0
  89. package/templates/apps/api/src/services/owner-workspaces.ts +132 -0
  90. package/templates/apps/mcp/CLAUDE.md +1 -1
  91. package/templates/apps/mcp/__tests__/parity.test.ts +2 -2
  92. package/templates/apps/mcp/__tests__/tools/{scaffold.test.ts → create_project.test.ts} +23 -23
  93. package/templates/apps/mcp/eslint.config.mjs +69 -0
  94. package/templates/apps/mcp/package.json +6 -2
  95. package/templates/apps/mcp/src/server.ts +2 -2
  96. package/templates/apps/mcp/src/tools/{scaffold.ts → create_project.ts} +3 -3
  97. package/templates/apps/mcp/src/tools/index.ts +2 -2
  98. package/templates/apps/web/.env.example +3 -3
  99. package/templates/apps/web/CLAUDE.md +2 -0
  100. package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +4 -6
  101. package/templates/apps/web/app/[locale]/(authed)/layout.tsx +1 -1
  102. package/templates/apps/web/app/[locale]/(authed)/leads/__tests__/page.test.tsx +181 -0
  103. package/templates/apps/web/app/[locale]/(authed)/leads/components/LeadsTable.tsx +137 -0
  104. package/templates/apps/web/app/[locale]/(authed)/leads/page.tsx +111 -0
  105. package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +1 -1
  106. package/templates/apps/web/app/[locale]/[slug]/__tests__/page.test.tsx +111 -0
  107. package/templates/apps/web/app/[locale]/[slug]/page.tsx +65 -0
  108. package/templates/apps/web/app/[locale]/flows/[slug]/FlowStepperClient.tsx +1 -1
  109. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.permalink.test.tsx +1 -1
  110. package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.test.tsx +6 -5
  111. package/templates/apps/web/app/[locale]/flows/[slug]/flow.actions.ts +1 -1
  112. package/templates/apps/web/app/[locale]/layout.tsx +214 -17
  113. package/templates/apps/web/components/google-analytics.tsx +18 -1
  114. package/templates/apps/web/eslint.config.mjs +69 -0
  115. package/templates/apps/web/jest.config.cjs +7 -15
  116. package/templates/apps/web/lib/__tests__/structured-data.test.tsx +32 -5
  117. package/templates/apps/web/lib/nav-config.ts +27 -7
  118. package/templates/apps/web/lib/server-api.ts +1 -1
  119. package/templates/apps/web/lib/site-chrome.ts +29 -0
  120. package/templates/apps/web/lib/telemetry-scrub.ts +46 -0
  121. package/templates/apps/web/messages/en.json +29 -2
  122. package/templates/apps/web/next.config.mjs +20 -0
  123. package/templates/apps/web/package.json +6 -2
  124. package/templates/apps/web/sentry.client.config.ts +131 -0
  125. package/templates/apps/web/sentry.edge.config.ts +72 -0
  126. package/templates/apps/web/sentry.server.config.ts +72 -0
  127. package/templates/apps/web/src/lib/routes.ts +13 -18
  128. package/templates/brand_assets/README.md +24 -0
  129. package/templates/content/en/AboutPage/about.mdx +160 -15
  130. package/templates/content/en/ContactPage/contact.mdx +90 -13
  131. package/templates/content/en/FAQPage/faq.mdx +62 -22
  132. package/templates/content/en/HomePage/home.mdx +244 -20
  133. package/templates/content/en/LandingPage/blog.mdx +83 -0
  134. package/templates/content/en/LandingPage/features.mdx +103 -0
  135. package/templates/content/en/LandingPage/how-it-works.mdx +143 -0
  136. package/templates/database/CHANGELOG.md +7 -0
  137. package/templates/database/__tests__/seed.test.ts +1 -1
  138. package/templates/database/eslint.config.mjs +69 -0
  139. package/templates/database/package.json +7 -3
  140. package/templates/database/seed.ts +1 -1
  141. package/templates/package.json +1 -14
  142. package/versions.json +52 -0
  143. package/site-templates/marketing-site-free/content/en/Pricing/pricing.mdx +0 -103
  144. /package/site-templates/{marketing-site-free → _base}/content/en/PrivacyPage/privacy.mdx +0 -0
  145. /package/site-templates/{marketing-site-free → _base}/content/en/TermsPage/terms.mdx +0 -0
  146. /package/templates/apps/web/{src/components → components}/SiteNav.tsx +0 -0
@@ -26,6 +26,7 @@
26
26
  * gate the paid path. The registry's own 401 IS the licence verdict.
27
27
  */
28
28
  import pkg from "../../package.json" with { type: "json" };
29
+ import { assertContentLengthWithinLimit, assertHttpsRegistryUrl, fetchTimeoutSignal, } from "./fetch-guard.js";
29
30
  export const DEFAULT_AILK_TEMPLATE_REGISTRY_URL = "https://ailaunchkit.ai/api/templates";
30
31
  /**
31
32
  * This package's own `package.json` `"version"` — a static JSON import for
@@ -66,6 +67,7 @@ export async function fetchTemplate(options) {
66
67
  const registryUrl = options.registryUrl ??
67
68
  process.env["AILK_TEMPLATE_REGISTRY_URL"] ??
68
69
  DEFAULT_AILK_TEMPLATE_REGISTRY_URL;
70
+ assertHttpsRegistryUrl(registryUrl, FetchTemplateError);
69
71
  const url = buildUrl(registryUrl, templateName, version);
70
72
  const fetchImpl = options.fetchImpl ?? globalThis.fetch;
71
73
  let response;
@@ -77,6 +79,7 @@ export async function fetchTemplate(options) {
77
79
  Accept: "application/gzip, application/octet-stream",
78
80
  },
79
81
  redirect: "error",
82
+ signal: fetchTimeoutSignal(),
80
83
  });
81
84
  }
82
85
  catch (err) {
@@ -98,6 +101,7 @@ export async function fetchTemplate(options) {
98
101
  const body = await safeReadBody(response);
99
102
  throw new FetchTemplateError(`template registry returned ${response.status} for "${templateName}": ${body}`);
100
103
  }
104
+ assertContentLengthWithinLimit(response, FetchTemplateError);
101
105
  const buf = await response.arrayBuffer();
102
106
  return new Uint8Array(buf);
103
107
  }
@@ -58,7 +58,7 @@ export interface PageRosterRow {
58
58
  route: string;
59
59
  /**
60
60
  * Repo-relative seed content this row renders. Absent for an API-backed row
61
- * (`/schedule` renders from the scheduling API, not from an MDX file).
61
+ * (`/meet` renders from the scheduling API, not from an MDX file).
62
62
  */
63
63
  content?: readonly string[];
64
64
  }
@@ -105,7 +105,7 @@ export interface ModuleSlice {
105
105
  * disappears just because one module's slice of it does).
106
106
  *
107
107
  * One entry in the arrays below is deliberately a GLOB
108
- * (`"apps-paid/workspace/**"`) rather than enumerated file-by-file — a
108
+ * (`"apps-paid/admin/**"`) rather than enumerated file-by-file — a
109
109
  * whole app with dozens of files, owned outright by one module; every other
110
110
  * entry is a literal file
111
111
  * path. A file that a module's own docs mention but that lives inside a
@@ -128,7 +128,7 @@ export interface ModuleSlice {
128
128
  * app, never a customer opt-in (see `apps/api/src/config/modules.ts`).
129
129
  * - Two are this-list-only and the manifest simply never recorded them:
130
130
  * `apps/web/app/[locale]/docs/[[...slug]]/page.tsx` and
131
- * `apps/web/app/[locale]/schedule/confirmed/page.tsx`.
131
+ * `apps/web/app/[locale]/meet/confirmed/page.tsx`.
132
132
  *
133
133
  * A file's TEST and STORY companions are never listed here (the
134
134
  * SOURCE-files-only rule above still holds) but DO carry the marker. They
@@ -167,13 +167,37 @@ export interface ModuleSlice {
167
167
  * Every source must be a file the validated tar extraction produced in the
168
168
  * bundle producer's staging directory — repo-relative, coinciding with the
169
169
  * `ownedFiles`/`installMap`-source paths this module's producer step
170
- * stages at, by construction. `extractModuleBundle` applies this map after
171
- * the tar entries are validated: an absolute path, a `..` segment, or a
172
- * path absent from staging rejects the whole bundle, as does a destination
173
- * that resolves outside the scaffold. A mapped source is copied to its
174
- * destination only, never also to its original path.
170
+ * stages at, by construction. ONE exception: `build-module-bundles.mjs`
171
+ * also stages the proprietary licence-client LICENSE at the archive root
172
+ * as `LICENSE` and adds its own `installMap["LICENSE"]` entry (never a
173
+ * slice field — the producer adds it uniformly, #5552 D1), so a slice's
174
+ * own `installMap` must not declare a `"LICENSE"` key. `extractModuleBundle`
175
+ * applies this map after the tar entries are validated: an absolute path, a
176
+ * `..` segment, or a path absent from staging rejects the whole bundle, as
177
+ * does a destination that resolves outside the scaffold. A mapped source is
178
+ * copied to its destination only, never also to its original path.
175
179
  */
176
180
  installMap?: Record<string, string>;
181
+ /**
182
+ * Rename root for this slice's whole-app glob `ownedFiles` entry(ies)
183
+ * (a `"<dir>/**"` entry — see `ownedFiles`'s own doc above) — the glob
184
+ * sibling of `installMap` (#5644 D1). Every file `expandEntry` yields
185
+ * under `<dir>/` installs at `installRoot + <rel-path-under-dir>` instead
186
+ * of its repo-relative path. `build-module-bundles.mjs`'s
187
+ * `deriveGlobInstallMap` derives one `installMap` entry per file from this
188
+ * rule at bundle-build time, and the mock registry fixture
189
+ * (`__tests__/fixtures/mock-module-registry-server.mjs`) calls the SAME
190
+ * function so its served manifest cannot drift from the producer's.
191
+ * Undefined for a slice with no glob `ownedFiles` entry, or one whose glob
192
+ * files install unchanged at their repo-relative path.
193
+ *
194
+ * `installMap` above stays the mechanism for hand-enumerated, non-glob
195
+ * remaps (see `commerce.installMap`) — a literal map is fine there because
196
+ * enumerating ten skill files costs ten lines; a whole app's worth of
197
+ * files committed one line per file into this OSS-shipped source is the
198
+ * leak class `scripts/check-oss-strip.sh` exists to catch (#5644).
199
+ */
200
+ installRoot?: string;
177
201
  /**
178
202
  * Plain text `extractModuleBundle` prints to stdout after a successful
179
203
  * merge, with C0/C1 control characters (other than newline) stripped
@@ -346,4 +370,31 @@ export declare function normalizeModules(modules: string[]): ModuleName[];
346
370
  * Passed in rather than derived from `import.meta.url`, which ts-jest cannot
347
371
  * load — the same reason `sync-routes.ts` documents for staying pure.
348
372
  */
373
+ /**
374
+ * Scaffold destinations that MORE THAN ONE module's `ownedFiles` declares —
375
+ * the co-ownership the `#5618 D4` install-time ownership registry must treat
376
+ * as intentional rather than as an overwrite (#5702 follow-up).
377
+ *
378
+ * Co-ownership is how a file reaches a scaffold under either of two modules
379
+ * without being transferred away from the other. #5677 needed it for the
380
+ * submissions review surface: the routes register under
381
+ * `multi-tenant || signal-collectors`, so BOTH bundles must be able to
382
+ * deliver them, or the module that lacks them throws
383
+ * `ERR_MODULE_NOT_FOUND` during `build()`.
384
+ *
385
+ * `validateLayerOwnership` (`lib/extract-module-bundle.ts`) refuses a
386
+ * destination an earlier layer already wrote, because a silent
387
+ * last-writer-wins between two modules that disagree is the bug `#5618 D4`
388
+ * exists to catch. Two modules that both DECLARE the same repo file are not
389
+ * that case: they stage the same bytes from the same source, so whichever
390
+ * lands second writes what is already there. Without this allowance a
391
+ * scaffold selecting both modules — `saas-product`, whose `requires` names
392
+ * `signal-collectors` AND `multi-tenant` — aborts mid-install, after the
393
+ * first module's files are on disk.
394
+ *
395
+ * Only a DECLARED overlap is allowed. A destination two layers collide on
396
+ * without both naming it in `ownedFiles` is still refused, which is the
397
+ * whole invariant.
398
+ */
399
+ export declare function coOwnedModuleDestinations(): ReadonlySet<string>;
349
400
  export declare function paidModuleTemplateExclusions(snapshotRoots: readonly string[], repoRoot: string): string[];