create-ailk 0.3.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.
- package/component-catalog.json +11939 -0
- package/component-catalog.md +176 -64
- package/dist/cli.js +48 -10
- package/dist/derive-architecture.js +5 -2
- package/dist/lib/extract-module-bundle.d.ts +88 -1
- package/dist/lib/extract-module-bundle.js +375 -80
- package/dist/lib/fetch-guard.d.ts +28 -0
- package/dist/lib/fetch-guard.js +101 -0
- package/dist/lib/fetch-module.js +4 -0
- package/dist/lib/fetch-template.d.ts +20 -0
- package/dist/lib/fetch-template.js +133 -0
- package/dist/lib/module-license-gate.d.ts +8 -0
- package/dist/lib/module-license-gate.js +12 -4
- package/dist/module-architecture.d.ts +116 -7
- package/dist/module-architecture.js +465 -94
- package/dist/parse-args.d.ts +8 -1
- package/dist/parse-args.js +49 -2
- package/dist/programmatic.d.ts +36 -1
- package/dist/programmatic.js +216 -5
- package/dist/site-chrome.d.ts +80 -0
- package/dist/site-chrome.js +135 -0
- package/dist/surfaces.d.ts +21 -6
- package/dist/surfaces.js +140 -23
- package/dist/template-manifest.d.ts +144 -0
- package/dist/template-manifest.js +337 -0
- package/dist/template-names.d.ts +41 -0
- package/dist/template-names.js +45 -0
- package/package.json +10 -2
- package/site-templates/_base/ailk-template.json +6 -0
- package/site-templates/_base/content/en/Pricing/pricing.mdx +169 -0
- package/site-templates/_base/content/en/PrivacyPage/privacy.mdx +79 -0
- package/site-templates/_base/content/en/TermsPage/terms.mdx +80 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +331 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +393 -0
- package/site-templates/marketing-site/ailk-template.json +11 -0
- package/site-templates/marketing-site/content/en/blog/05-this-vc-morning-routine-will-make-you-super-annoying.mdx +36 -0
- package/site-templates/marketing-site/provenance.json +4 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +288 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +285 -0
- package/site-templates/marketing-site-free/ailk-template.json +9 -0
- package/site-templates/marketing-site-free/provenance.json +4 -0
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +271 -0
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +324 -0
- package/site-templates/minimalism-site/ailk-template.json +21 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-1.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-2.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-3.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-4.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-5.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-6.svg +7 -0
- package/site-templates/minimalism-site/assets/hero-backdrop.svg +17 -0
- package/site-templates/minimalism-site/assets/logo-placeholder-1.svg +6 -0
- package/site-templates/minimalism-site/assets/logo-placeholder-2.svg +6 -0
- package/site-templates/minimalism-site/assets/logo-placeholder-3.svg +6 -0
- package/site-templates/minimalism-site/content/en/AboutPage/about.mdx +110 -0
- package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +68 -0
- package/site-templates/minimalism-site/content/en/FAQPage/faq.mdx +57 -0
- package/site-templates/minimalism-site/content/en/HomePage/home.mdx +214 -0
- package/site-templates/minimalism-site/content/en/LandingPage/referral.mdx +77 -0
- package/site-templates/minimalism-site/content/en/LandingPage/reports.mdx +73 -0
- package/site-templates/minimalism-site/content/en/ReportPage/annual-letter-2024.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ReportPage/field-notes-2023.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ReportPage/platform-shift-2025.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ReportPage/state-of-the-market-2026.mdx +52 -0
- package/site-templates/minimalism-site/content/en/Service/first-engagement.mdx +38 -0
- package/site-templates/minimalism-site/content/en/Service/second-engagement.mdx +38 -0
- package/site-templates/minimalism-site/content/en/Service/third-engagement.mdx +38 -0
- package/site-templates/minimalism-site/content/en/ServicesList/services.mdx +73 -0
- package/site-templates/minimalism-site/flows/referral.flow.json +71 -0
- package/site-templates/minimalism-site/provenance.json +4 -0
- package/site-templates/saas-product/TEMPLATE-MANIFEST.md +61 -0
- package/site-templates/saas-product/ailk-template.json +16 -0
- package/site-templates/saas-product/provenance.json +10 -0
- package/templates/.claude/skills/README.md +16 -25
- package/templates/.env.example +32 -7
- package/templates/.github/workflows/ci.yml +48 -0
- package/templates/README.md +3 -1
- package/templates/apps/api/CLAUDE.md +4 -1
- package/templates/apps/api/eslint.config.mjs +69 -0
- package/templates/apps/api/package.json +6 -2
- package/templates/apps/api/src/__tests__/module-exclusion.test.ts +6 -2
- package/templates/apps/api/src/__tests__/review-surface-registration.test.ts +167 -0
- package/templates/apps/api/src/__tests__/workspace-module-registration.test.ts +173 -0
- package/templates/apps/api/src/config/modules.ts +1 -1
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +3 -0
- package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +339 -0
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +108 -0
- package/templates/apps/api/src/middleware/default-tenant.ts +136 -0
- package/templates/apps/api/src/routes/leads/__tests__/list.test.ts +171 -0
- package/templates/apps/api/src/routes/leads/list.ts +104 -0
- package/templates/apps/api/src/server.ts +122 -3
- package/templates/apps/api/src/services/__tests__/lead-promotion.test.ts +408 -0
- package/templates/apps/api/src/services/__tests__/leads-inbox.test.ts +329 -0
- package/templates/apps/api/src/services/default-tenant.ts +261 -0
- package/templates/apps/api/src/services/lead-promotion.ts +161 -0
- package/templates/apps/api/src/services/leads-inbox.ts +263 -0
- package/templates/apps/api/src/services/owner-workspaces.ts +132 -0
- package/templates/apps/mcp/CLAUDE.md +1 -1
- package/templates/apps/mcp/__tests__/parity.test.ts +2 -2
- package/templates/apps/mcp/__tests__/tools/{scaffold.test.ts → create_project.test.ts} +23 -23
- package/templates/apps/mcp/eslint.config.mjs +69 -0
- package/templates/apps/mcp/package.json +6 -2
- package/templates/apps/mcp/src/server.ts +2 -2
- package/templates/apps/mcp/src/tools/{scaffold.ts → create_project.ts} +3 -3
- package/templates/apps/mcp/src/tools/index.ts +2 -2
- package/templates/apps/web/.env.example +3 -3
- package/templates/apps/web/CLAUDE.md +2 -0
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +4 -6
- package/templates/apps/web/app/[locale]/(authed)/layout.tsx +1 -1
- package/templates/apps/web/app/[locale]/(authed)/leads/__tests__/page.test.tsx +181 -0
- package/templates/apps/web/app/[locale]/(authed)/leads/components/LeadsTable.tsx +137 -0
- package/templates/apps/web/app/[locale]/(authed)/leads/page.tsx +111 -0
- package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +1 -1
- package/templates/apps/web/app/[locale]/[slug]/__tests__/page.test.tsx +111 -0
- package/templates/apps/web/app/[locale]/[slug]/page.tsx +65 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/FlowStepperClient.tsx +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.permalink.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.test.tsx +6 -5
- package/templates/apps/web/app/[locale]/flows/[slug]/flow.actions.ts +1 -1
- package/templates/apps/web/app/[locale]/layout.tsx +214 -17
- package/templates/apps/web/app/[locale]/pricing/page.tsx +40 -0
- package/templates/apps/web/app/[locale]/privacy/page.tsx +40 -0
- package/templates/apps/web/app/[locale]/terms/page.tsx +40 -0
- package/templates/apps/web/components/google-analytics.tsx +18 -1
- package/templates/apps/web/eslint.config.mjs +69 -0
- package/templates/apps/web/jest.config.cjs +12 -15
- package/templates/apps/web/lib/__tests__/server-api.test.ts +61 -0
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +32 -5
- package/templates/apps/web/lib/nav-config.ts +27 -7
- package/templates/apps/web/lib/server-api.ts +29 -13
- package/templates/apps/web/lib/site-chrome.ts +29 -0
- package/templates/apps/web/lib/telemetry-scrub.ts +46 -0
- package/templates/apps/web/messages/en.json +86 -1
- package/templates/apps/web/next.config.mjs +20 -0
- package/templates/apps/web/package.json +6 -2
- package/templates/apps/web/sentry.client.config.ts +131 -0
- package/templates/apps/web/sentry.edge.config.ts +72 -0
- package/templates/apps/web/sentry.server.config.ts +72 -0
- package/templates/apps/web/src/lib/routes.ts +13 -18
- package/templates/brand_assets/README.md +24 -0
- package/templates/content/en/AboutPage/about.mdx +160 -15
- package/templates/content/en/ContactPage/contact.mdx +90 -13
- package/templates/content/en/FAQPage/faq.mdx +62 -22
- package/templates/content/en/HomePage/home.mdx +244 -20
- package/templates/content/en/LandingPage/blog.mdx +83 -0
- package/templates/content/en/LandingPage/features.mdx +103 -0
- package/templates/content/en/LandingPage/how-it-works.mdx +143 -0
- package/templates/database/CHANGELOG.md +21 -0
- package/templates/database/__tests__/seed.test.ts +1 -1
- package/templates/database/eslint.config.mjs +69 -0
- package/templates/database/package.json +7 -3
- package/templates/database/seed.ts +1 -1
- package/templates/package.json +1 -14
- package/versions.json +52 -0
- /package/templates/apps/web/{src/components → components}/SiteNav.tsx +0 -0
|
@@ -253,18 +253,47 @@ export const MODULE_SLICES = {
|
|
|
253
253
|
// The module's own /llms.txt variant; the bundle installs it onto
|
|
254
254
|
// app/llms.txt/route.ts (#5365 D9, install-path mapping owned by #5373).
|
|
255
255
|
"apps/web/lib/slices/docs-blog/llms-route.ts",
|
|
256
|
-
// The two shells and the six components
|
|
257
|
-
//
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
256
|
+
// The two shells and the six components moved to packages-paid/ui-docs-blog
|
|
257
|
+
// (#5581) — that package is a physical part of the tree, not a listed
|
|
258
|
+
// ownedFiles entry, and is installed via this slice's `patches` block below.
|
|
259
|
+
],
|
|
260
|
+
// pageContributions (spec 5478; parent § D6 shape 1) — the two route
|
|
261
|
+
// surfaces this module mounts, each with the seed MDX it renders. The
|
|
262
|
+
// nine MDX files are exactly the nine on the tree and cannot come from
|
|
263
|
+
// the `templates/` snapshot: `apps/web/content` is in build-templates.mjs's
|
|
264
|
+
// EXCLUDE_TEMPLATE_DIRS and `template-overlay/` carries no blog or docs
|
|
265
|
+
// stub. They ride this module's own bundle, consistent with the route
|
|
266
|
+
// files above: `collectModuleFiles` in build-module-bundles.mjs stages
|
|
267
|
+
// every `pageContributions[].content` entry alongside `ownedFiles` and
|
|
268
|
+
// the `installMap` keys, and `copyTree` lands each at this same path.
|
|
269
|
+
//
|
|
270
|
+
// #5618 D6.2 — the module OWNS its sample content (Rule B): the blog
|
|
271
|
+
// listing, four sample posts and the three docs pages moved here out of
|
|
272
|
+
// `site-templates/marketing-site/`, so any template requiring docs-blog
|
|
273
|
+
// gets the samples and a keyed `--modules docs-blog` scaffold with no
|
|
274
|
+
// template lands them too. `launching-ailk.mdx` stays the module's fifth
|
|
275
|
+
// seed post; the Pro template maps its own post 05 ONTO that path as a
|
|
276
|
+
// copy override (D6.2a — spec § 7 finding 9 carries the seed's fate).
|
|
277
|
+
pageContributions: [
|
|
278
|
+
{
|
|
279
|
+
route: "/blog",
|
|
280
|
+
content: [
|
|
281
|
+
"apps/web/content/en/blog/index.mdx",
|
|
282
|
+
"apps/web/content/en/blog/01-8-things-that-prove-coding-skills-are-directly-linked-to-successfully-assembling-ikea-furniture.mdx",
|
|
283
|
+
"apps/web/content/en/blog/02-5-ways-to-guarantee-your-startup-goes-nowhere-fast.mdx",
|
|
284
|
+
"apps/web/content/en/blog/03-10-ideas-that-will-guarantee-1000x-growth.mdx",
|
|
285
|
+
"apps/web/content/en/blog/04-7-keys-to-saas-success-the-elite-doesnt-want-you-to-know.mdx",
|
|
286
|
+
"apps/web/content/en/blog/launching-ailk.mdx",
|
|
287
|
+
],
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
route: "/docs",
|
|
291
|
+
content: [
|
|
292
|
+
"apps/web/content/en/docs/getting-started.mdx",
|
|
293
|
+
"apps/web/content/en/docs/configure.mdx",
|
|
294
|
+
"apps/web/content/en/docs/deploy.mdx",
|
|
295
|
+
],
|
|
296
|
+
},
|
|
268
297
|
],
|
|
269
298
|
// patches (spec 5418 § 3 D1, Group G) — every Group G row that edits a
|
|
270
299
|
// file the buyer's scaffold already has. Values transcribed verbatim
|
|
@@ -308,6 +337,8 @@ export const MODULE_SLICES = {
|
|
|
308
337
|
"fumadocs-core": "^16.10.4",
|
|
309
338
|
"fumadocs-mdx": "^15.0.12",
|
|
310
339
|
"@working-theory/fumadocs-schema": "workspace:*",
|
|
340
|
+
// #5581 — the docs-blog module's paid component package (D5).
|
|
341
|
+
"@working-theory/ui-docs-blog": "workspace:*",
|
|
311
342
|
},
|
|
312
343
|
},
|
|
313
344
|
{
|
|
@@ -374,19 +405,25 @@ export const MODULE_SLICES = {
|
|
|
374
405
|
//
|
|
375
406
|
// The FEAT-042 Organization → Workspace → Membership tenancy layer:
|
|
376
407
|
// schema (auth/content namespaces) + workspace-scoped API (apps/api) +
|
|
377
|
-
// the authed
|
|
408
|
+
// the authed Admin app surface (apps/admin). Single-tenant sites
|
|
378
409
|
// (module absent) ship none of this — same base apps/web, fixed scope.
|
|
379
410
|
"multi-tenant": {
|
|
380
411
|
apps: {
|
|
381
|
-
|
|
382
|
-
path: "apps/
|
|
383
|
-
description: "Next.js — authed
|
|
412
|
+
admin: {
|
|
413
|
+
path: "apps/admin",
|
|
414
|
+
description: "Next.js — authed Admin app (Organization → Workspace → Membership). Hosts the organization-plugin Better Auth handlers; imports the database only via lib/prisma-for-auth.ts (auth-adapter exception); all domain data via apps/api's workspace-scoped routes over HTTP.",
|
|
384
415
|
may_import_from: [
|
|
385
416
|
"database",
|
|
386
417
|
"packages/templates",
|
|
387
418
|
"packages/theme",
|
|
388
419
|
"packages/ui",
|
|
389
420
|
"packages/validation",
|
|
421
|
+
// The `workspace` module's shared settings components (#5371 req. 6)
|
|
422
|
+
// — the scaffolded-site twin of the root architecture.yaml grant on
|
|
423
|
+
// `apps_paid.admin`. Pro Plus inherits Pro's module set, so a
|
|
424
|
+
// saas-product scaffold carries both modules and this app composes
|
|
425
|
+
// the identical panels apps/web does, with no forked copy.
|
|
426
|
+
"packages/admin-ui",
|
|
390
427
|
],
|
|
391
428
|
may_not_import_from: [
|
|
392
429
|
"apps/api",
|
|
@@ -458,12 +495,12 @@ export const MODULE_SLICES = {
|
|
|
458
495
|
description: "Stripe SDK wrapper + webhook signature verification",
|
|
459
496
|
may_import_from: ["packages/validation"],
|
|
460
497
|
},
|
|
461
|
-
// apps/
|
|
498
|
+
// apps/admin presentation deps. templates is net-new here; theme/ui/
|
|
462
499
|
// validation duplicate the marketing slice's definitions VERBATIM so the
|
|
463
500
|
// Object.assign merge in deriveArchitecture is order-independent (a
|
|
464
501
|
// multi-tenant-only selection stays self-consistent).
|
|
465
502
|
templates: {
|
|
466
|
-
description: "Shell/Chrome composition — AppShell (tier-5 shell);
|
|
503
|
+
description: "Shell/Chrome composition — AppShell (tier-5 shell); AdminShell + ArtifactEditorShell ship inside this module itself, not the public package (D-45)",
|
|
467
504
|
may_import_from: ["packages/theme", "packages/ui", "packages/validation"],
|
|
468
505
|
},
|
|
469
506
|
theme: {
|
|
@@ -525,11 +562,12 @@ export const MODULE_SLICES = {
|
|
|
525
562
|
// ownedFiles (S1, #5088). Verified against the current filesystem and
|
|
526
563
|
// server.ts's module-conditional registration (isModuleEnabled('multi-tenant')).
|
|
527
564
|
//
|
|
528
|
-
// apps-paid/
|
|
565
|
+
// apps-paid/admin/** is a single glob — the whole app (43 files as of
|
|
529
566
|
// this pass, excluding __tests__/node_modules), just moved here from
|
|
530
|
-
// apps/workspace by a parallel workstream on this same branch.
|
|
531
|
-
//
|
|
532
|
-
//
|
|
567
|
+
// apps/workspace by a parallel workstream on this same branch. Later
|
|
568
|
+
// renamed in place from its former Workspace-prefixed directory name by
|
|
569
|
+
// #5637, the Admin-vocabulary rename. Unlike every other entry below,
|
|
570
|
+
// this one is intentionally a glob, not an enumeration.
|
|
533
571
|
//
|
|
534
572
|
// apps/api/src/routes/project-listings/ is MIXED (free anonymous surface
|
|
535
573
|
// + tenant dashboard sharing one directory) — only the tenant-guarded
|
|
@@ -646,7 +684,112 @@ export const MODULE_SLICES = {
|
|
|
646
684
|
"apps/web/app/[locale]/(authed)/waitlist/components/SignupsTable.tsx",
|
|
647
685
|
"apps/web/app/[locale]/(authed)/waitlist/components/WaitlistComparisonTabs.tsx",
|
|
648
686
|
"apps/web/app/[locale]/(authed)/waitlist/components/status-badges.tsx",
|
|
649
|
-
"apps-paid/
|
|
687
|
+
"apps-paid/admin/**",
|
|
688
|
+
],
|
|
689
|
+
// The whole-app glob above lands its files at their REPO-relative path
|
|
690
|
+
// unless something re-roots them (`installBundleTree`'s `copyTree`
|
|
691
|
+
// excludes only `installMap` KEYS from its verbatim copy), so without a
|
|
692
|
+
// rename rule a keyed install left a stray source-tree-relative
|
|
693
|
+
// directory in the scaffold instead of the working `apps/admin` app
|
|
694
|
+
// this slice's own `apps.admin.path` (and `paid-paths.ts`'s
|
|
695
|
+
// `introducedAppPaths()`) already declares (#5626 D3/D4). The fix lives
|
|
696
|
+
// here, on the module, so `--modules multi-tenant` alone is fixed too —
|
|
697
|
+
// never as a per-template workaround.
|
|
698
|
+
//
|
|
699
|
+
// `installRoot`, not a literal `installMap` (#5644 D1): a committed
|
|
700
|
+
// 58-entry literal map — one line per staged file's proprietary source
|
|
701
|
+
// path — put every one of those paths into this OSS-shipped file's
|
|
702
|
+
// SOURCE TEXT, the exact leak class `scripts/check-oss-strip.sh` exists
|
|
703
|
+
// to catch. `build-module-bundles.mjs`'s `deriveGlobInstallMap` derives
|
|
704
|
+
// the equivalent per-file `installMap` at bundle-build time instead —
|
|
705
|
+
// one entry per file `expandEntry` yields for the glob entry above,
|
|
706
|
+
// byte-identical to the literal map it replaces — and the mock registry
|
|
707
|
+
// fixture calls the same derivation so it cannot drift from the
|
|
708
|
+
// producer's. See `installRoot`'s own doc on `ModuleSlice` above.
|
|
709
|
+
installRoot: "apps/admin/",
|
|
710
|
+
},
|
|
711
|
+
// ── workspace — Pro module: the single-workspace settings shell (D-27/D-49)
|
|
712
|
+
//
|
|
713
|
+
// `/admin` in apps/web's `(authed)` segment — General (rename), Site
|
|
714
|
+
// (identity / SEO / theme, over the already-shipped apps/api config routes)
|
|
715
|
+
// and Team (a read-only roster). The three panels live in the shared
|
|
716
|
+
// `packages/admin-ui` package so the multi-tenant Admin app (the
|
|
717
|
+
// Pro Plus app) composes the identical components rather than a fork.
|
|
718
|
+
//
|
|
719
|
+
// No `apps` / `namespaces` / `forbiddenPatterns` block: this module
|
|
720
|
+
// contributes to already-declared apps only (apps/web is BASE; apps/api is
|
|
721
|
+
// declared by multi-tenant / scheduling / commerce and is snapshotted whole).
|
|
722
|
+
workspace: {
|
|
723
|
+
// A PERMISSION, not a physical slice (#5371 D1a) — the identical shape
|
|
724
|
+
// docs-blog uses for `packages/fumadocs-schema`. `packages/` is never in
|
|
725
|
+
// SNAPSHOT_DIRS, so the package reaches a buyer as an npm/bundle
|
|
726
|
+
// dependency under `node_modules/`, never as a `packages/admin-ui`
|
|
727
|
+
// source sibling; the `patches` entry below is what puts it in the
|
|
728
|
+
// buyer's apps/web/package.json.
|
|
729
|
+
webImports: ["packages/admin-ui"],
|
|
730
|
+
packages: {
|
|
731
|
+
"admin-ui": {
|
|
732
|
+
description: "Shared Admin-settings components — the settings shell plus the General / Site / Team panels, presentational only (data + save callbacks as props)",
|
|
733
|
+
// packages/templates is required because AdminSettingsShell
|
|
734
|
+
// composes AppShell from @working-theory/templates/shells — the same
|
|
735
|
+
// composition apps/web's own account page uses.
|
|
736
|
+
may_import_from: [
|
|
737
|
+
"packages/templates",
|
|
738
|
+
"packages/theme",
|
|
739
|
+
"packages/ui",
|
|
740
|
+
"packages/validation",
|
|
741
|
+
],
|
|
742
|
+
},
|
|
743
|
+
},
|
|
744
|
+
// SOURCE files only, and only the ones this module physically owns: the
|
|
745
|
+
// three apps/web route files and the two apps/api route files.
|
|
746
|
+
//
|
|
747
|
+
// `packages/admin-ui/**` is deliberately NOT listed (D1a). It is a
|
|
748
|
+
// whole package that is paid end to end, whose strip disposition is
|
|
749
|
+
// carried by architecture.yaml's `commercial_tier_moves_to` field (its
|
|
750
|
+
// future paid-tree home) rather than by a per-file inventory —
|
|
751
|
+
// exactly the disposition `packages/fumadocs-schema` carries for
|
|
752
|
+
// docs-blog. `multi-tenant`'s whole-app glob (above) works because
|
|
753
|
+
// SNAPSHOT_DIRS physically copies apps wholesale; a package is never in a
|
|
754
|
+
// snapshot root, so an ownedFiles enumeration would add nothing.
|
|
755
|
+
//
|
|
756
|
+
// `packages/api-client/src/workspace.ts` is NOT listed either (D1b):
|
|
757
|
+
// api-client is a base package every scaffold receives regardless of
|
|
758
|
+
// `--modules`, and the field doc above names it by name as a shared
|
|
759
|
+
// package deliberately left out even when genuinely single-purpose. The
|
|
760
|
+
// wrapper is harmless on a scaffold without this module — its calls 404,
|
|
761
|
+
// the same non-event any client wrapper produces against an unregistered
|
|
762
|
+
// route.
|
|
763
|
+
//
|
|
764
|
+
// Test companions (`__tests__/`) are never listed — the SOURCE-files-only
|
|
765
|
+
// rule above.
|
|
766
|
+
ownedFiles: [
|
|
767
|
+
"apps/web/app/[locale]/(authed)/admin/page.tsx",
|
|
768
|
+
"apps/web/app/[locale]/(authed)/admin/site/page.tsx",
|
|
769
|
+
"apps/web/app/[locale]/(authed)/admin/team/page.tsx",
|
|
770
|
+
"apps/api/src/routes/workspaces/general.ts",
|
|
771
|
+
"apps/api/src/routes/workspaces/members.ts",
|
|
772
|
+
],
|
|
773
|
+
// patches — the dependency add that delivers the shared package to the
|
|
774
|
+
// buyer's apps/web, mirroring docs-blog's own fumadocs-schema merge-keys
|
|
775
|
+
// op. No next.config.mjs `add-transpile-package` op: the package ships
|
|
776
|
+
// compiled ESM in dist/ the same way every other @working-theory/*
|
|
777
|
+
// dependency apps/web already consumes does, and docs-blog's transpile op
|
|
778
|
+
// exists for the fumadocs SDK boundary, not for the dependency add itself.
|
|
779
|
+
patches: [
|
|
780
|
+
{
|
|
781
|
+
target: "apps/web/package.json",
|
|
782
|
+
kind: "json",
|
|
783
|
+
ops: [
|
|
784
|
+
{
|
|
785
|
+
op: "merge-keys",
|
|
786
|
+
path: ["dependencies"],
|
|
787
|
+
entries: {
|
|
788
|
+
"@working-theory/admin-ui": "workspace:*",
|
|
789
|
+
},
|
|
790
|
+
},
|
|
791
|
+
],
|
|
792
|
+
},
|
|
650
793
|
],
|
|
651
794
|
},
|
|
652
795
|
// ── scheduling — full-stack module (provider + routes + booker pages) ────
|
|
@@ -658,8 +801,10 @@ export const MODULE_SLICES = {
|
|
|
658
801
|
// the ONLY holder of the scheduling credential.
|
|
659
802
|
// api apps/api's own /v1/schedule/availability + /v1/schedule/book.
|
|
660
803
|
// presentation the `booker` section (packages/ui, no iframe) rendered by
|
|
661
|
-
// the `
|
|
662
|
-
// confirmation page at /
|
|
804
|
+
// the `meet` route surface, plus the per-booking-type page
|
|
805
|
+
// and the module-owned confirmation page at /meet/:slug and
|
|
806
|
+
// /meet/confirmed (renamed from the schedule/ directory by
|
|
807
|
+
// #5563).
|
|
663
808
|
//
|
|
664
809
|
// The four forbidden patterns below are the module's whole security
|
|
665
810
|
// argument, restated as boundary rules rather than left in a comment: the
|
|
@@ -752,16 +897,19 @@ export const MODULE_SLICES = {
|
|
|
752
897
|
// consumer — unlike packages/validation below, a strip tool CAN delete
|
|
753
898
|
// exactly these files without touching anything another module needs.
|
|
754
899
|
//
|
|
755
|
-
//
|
|
756
|
-
// 2026-09-11
|
|
757
|
-
//
|
|
758
|
-
//
|
|
759
|
-
//
|
|
760
|
-
//
|
|
761
|
-
//
|
|
762
|
-
//
|
|
763
|
-
//
|
|
764
|
-
//
|
|
900
|
+
// ALL THREE apps/web/app/[locale]/meet pages are listed (#5182 Q9, disposed
|
|
901
|
+
// 2026-09-11; directory renamed from schedule/ to meet/ by #5563).
|
|
902
|
+
// confirmed/page.tsx says outright in its own doc comment that "The module
|
|
903
|
+
// OWNS this page... a scaffold without the module has no such route", and
|
|
904
|
+
// its sibling page.tsx is the SOLE production constructor of a `booker`
|
|
905
|
+
// section: it builds the section literally in TypeScript (page.tsx:60,
|
|
906
|
+
// `type: "booker"`) rather than reading it from content, and its own
|
|
907
|
+
// header calls the route API-backed with "no content file that could
|
|
908
|
+
// disagree with the calendar". [slug]/page.tsx is the third — the
|
|
909
|
+
// per-booking-type page #5563 added, composing its calLink from the same
|
|
910
|
+
// configured owner rather than reading one of its own. The create-ailk
|
|
911
|
+
// scaffolder already gates the whole `meet` route surface (src/surfaces.ts),
|
|
912
|
+
// so all three pages arrive and depart together.
|
|
765
913
|
//
|
|
766
914
|
// packages/sections-registry/src/registry.ts (the `booker:` entry) and
|
|
767
915
|
// packages/validation/src/schemas/page-sections.ts (BookerSectionDataSchema,
|
|
@@ -790,13 +938,14 @@ export const MODULE_SLICES = {
|
|
|
790
938
|
// scheduling-specific. This is a judgment call, not covered by this
|
|
791
939
|
// card's explicit checklist: flagged for reviewer confirmation.
|
|
792
940
|
//
|
|
793
|
-
//
|
|
794
|
-
//
|
|
795
|
-
//
|
|
796
|
-
//
|
|
797
|
-
// files
|
|
798
|
-
// `slice-renderers.ts` and `ModuleAbsent.tsx` — are
|
|
799
|
-
// here: they ship, and listing one would take the
|
|
941
|
+
// The Booker components and the slice's registration entry point (#5214)
|
|
942
|
+
// moved to packages-paid/ui-scheduling (#5581 U3); that package is a
|
|
943
|
+
// physical part of the tree, not a listed ownedFiles entry, and reaches a
|
|
944
|
+
// keyed scaffold through this slice's `patches` block below (D5). The
|
|
945
|
+
// three files the old in-packages/ui path added on the OSS side —
|
|
946
|
+
// `SectionRenderer.tsx`, `slice-renderers.ts` and `ModuleAbsent.tsx` — are
|
|
947
|
+
// deliberately NOT listed here: they ship, and listing one would take the
|
|
948
|
+
// whole dispatch table with it.
|
|
800
949
|
ownedFiles: [
|
|
801
950
|
"apps/api/src/routes/schedule/index.ts",
|
|
802
951
|
"apps/api/src/services/scheduling/index.ts",
|
|
@@ -805,16 +954,36 @@ export const MODULE_SLICES = {
|
|
|
805
954
|
"apps/mcp/src/tools/list_availability.ts",
|
|
806
955
|
"apps/mcp/src/tools/get_event_meta.ts",
|
|
807
956
|
"apps/mcp/src/tools/create_booking.ts",
|
|
808
|
-
"
|
|
809
|
-
"
|
|
810
|
-
"
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
"
|
|
957
|
+
"apps/web/app/[locale]/meet/page.tsx",
|
|
958
|
+
"apps/web/app/[locale]/meet/[slug]/page.tsx",
|
|
959
|
+
"apps/web/app/[locale]/meet/confirmed/page.tsx",
|
|
960
|
+
],
|
|
961
|
+
// pageContributions (spec 5478; parent § D6 shape 1) — the booker, the
|
|
962
|
+
// per-booking-type page and the confirmation page, whose route files
|
|
963
|
+
// `ownedFiles` above already carries. No row names seed content: all
|
|
964
|
+
// three render from the /v1/schedule/* routes, not from an MDX file.
|
|
965
|
+
pageContributions: [
|
|
966
|
+
{ route: "/meet" },
|
|
967
|
+
{ route: "/meet/[slug]" },
|
|
968
|
+
{ route: "/meet/confirmed" },
|
|
969
|
+
],
|
|
970
|
+
// patches (#5581 U3, D5) — delivers the extracted component package to a
|
|
971
|
+
// keyed scaffold's apps/web, mirroring the signal-collectors slice's
|
|
972
|
+
// identical merge-keys op below.
|
|
973
|
+
patches: [
|
|
974
|
+
{
|
|
975
|
+
target: "apps/web/package.json",
|
|
976
|
+
kind: "json",
|
|
977
|
+
ops: [
|
|
978
|
+
{
|
|
979
|
+
op: "merge-keys",
|
|
980
|
+
path: ["dependencies"],
|
|
981
|
+
entries: {
|
|
982
|
+
"@working-theory/ui-scheduling": "workspace:*",
|
|
983
|
+
},
|
|
984
|
+
},
|
|
985
|
+
],
|
|
986
|
+
},
|
|
818
987
|
],
|
|
819
988
|
},
|
|
820
989
|
// ── signal-collectors — flows, deliverables, project listings, waitlist
|
|
@@ -898,10 +1067,23 @@ export const MODULE_SLICES = {
|
|
|
898
1067
|
// packages/ui: eleven components (D8) plus the NEW slice registration
|
|
899
1068
|
// entry point (D8a, mirroring sections/slices/scheduling.ts). Four of the
|
|
900
1069
|
// eleven (ProjectListingShelves, ListingPrivacyNotice, ProjectListingCard,
|
|
901
|
-
// ResultsReveal)
|
|
902
|
-
//
|
|
903
|
-
//
|
|
904
|
-
//
|
|
1070
|
+
// ResultsReveal) had no consumer anywhere IN THIS REPO at D8 authoring
|
|
1071
|
+
// time — grep-confirmed, a module-boundary fact only in-repo. Three of the
|
|
1072
|
+
// four (ProjectListingShelves, ProjectListingCard, ListingPrivacyNotice —
|
|
1073
|
+
// plus the ListingWindowBand type ProjectListingCard exports) are, in
|
|
1074
|
+
// fact, consumed CROSS-ORG: the samhenry site (salessmyth org) imports all
|
|
1075
|
+
// four from the signal-collectors slice's re-export entry point
|
|
1076
|
+
// (packages/ui/src/sections/slices/signal-collectors.ts, rules/cross-org-
|
|
1077
|
+
// sharing.md), which #5488 additionally re-exports them from so that
|
|
1078
|
+
// consumer can reach them by subpath. "No consumer anywhere in the repo"
|
|
1079
|
+
// was therefore true in-repo and false across the org boundary — not a
|
|
1080
|
+
// reachability fact a repo-scoped grep can see. ResultsReveal remains the
|
|
1081
|
+
// one component of the four with no known consumer anywhere (in-repo or
|
|
1082
|
+
// out) and is NOT re-exported by #5488 — it is not this card's claim to
|
|
1083
|
+
// make it non-orphaned. D8's placement rule (by subject — project-listing
|
|
1084
|
+
// / results-reveal UI — rather than by reachability, since reachability
|
|
1085
|
+
// cannot place an unreached file either) is unchanged and still governs
|
|
1086
|
+
// where all eleven live.
|
|
905
1087
|
"signal-collectors": {
|
|
906
1088
|
ownedFiles: [
|
|
907
1089
|
"apps/api/src/routes/flows/index.ts",
|
|
@@ -956,6 +1138,72 @@ export const MODULE_SLICES = {
|
|
|
956
1138
|
"apps/api/src/bin/seed-waitlist-experiments.ts",
|
|
957
1139
|
"apps/mcp/src/tools/get_flow.ts",
|
|
958
1140
|
"apps/mcp/src/tools/submit_flow_step.ts",
|
|
1141
|
+
// ── The review surface (#5677) — CO-OWNED with multi-tenant ──────────
|
|
1142
|
+
//
|
|
1143
|
+
// Every path below is ALSO a multi-tenant `ownedFiles` entry and stays
|
|
1144
|
+
// one. Listing a file under two modules is additive, not a transfer:
|
|
1145
|
+
// `paidModuleTemplateExclusions()` unions every paid module's entries,
|
|
1146
|
+
// so the `templates/` snapshot is unchanged, and a multi-tenant scaffold
|
|
1147
|
+
// keeps receiving these from the multi-tenant bundle exactly as before.
|
|
1148
|
+
// What changes is that a signal-collectors bundle now carries them too.
|
|
1149
|
+
//
|
|
1150
|
+
// WHY THEY MUST BE HERE. #5677 widened `server.ts`'s review-surface
|
|
1151
|
+
// registration from `multi-tenant` to `multi-tenant || signal-collectors`,
|
|
1152
|
+
// because signal-collectors is the module that SELLS the instruments
|
|
1153
|
+
// these routes read back. Registration and DELIVERY are separate layers:
|
|
1154
|
+
// the widened gate calls `sliceRoutePlugin("waitlistExperimentRoutes")`
|
|
1155
|
+
// and imports `projectListingTenantRoutes`, so on a scaffold whose
|
|
1156
|
+
// `AILK_ENABLED_MODULES` names signal-collectors but whose tree lacks
|
|
1157
|
+
// these files, `loadSlice` throws ERR_MODULE_NOT_FOUND during `build()`
|
|
1158
|
+
// — construction, so EVERY route 500s rather than one. That is not a
|
|
1159
|
+
// feature gap; it is the outage shape `lib/slice-load.ts` exists to
|
|
1160
|
+
// diagnose.
|
|
1161
|
+
//
|
|
1162
|
+
// It is not hypothetical: `marketing-site` — the Pro flagship in
|
|
1163
|
+
// `template-manifest.ts` — declares
|
|
1164
|
+
// `requires: ["marketing", "docs-blog", "scheduling", "signal-collectors"]`,
|
|
1165
|
+
// i.e. signal-collectors WITHOUT multi-tenant. That is exactly the
|
|
1166
|
+
// configuration that would crash, which is why the gate and the delivery
|
|
1167
|
+
// land together rather than the delivery being deferred.
|
|
1168
|
+
//
|
|
1169
|
+
// The closure is tight, verified by grep rather than assumed: none of
|
|
1170
|
+
// these files imports `lib/tenant-db.ts` or `services/tenant-context.ts`
|
|
1171
|
+
// (both multi-tenant-only). #5677 retargeted `waitlist-dashboard.ts`'s
|
|
1172
|
+
// type import of `tenant-context.js` to the base `services/default-tenant.ts`,
|
|
1173
|
+
// which severed the one cross-slice edge that existed.
|
|
1174
|
+
//
|
|
1175
|
+
// `routes/project-listings/{start,patch-draft,submit,public,me,respond,
|
|
1176
|
+
// resume-token,patch-copy}.ts` are NOT listed — they are the free
|
|
1177
|
+
// anonymous surface and the mixed barrel, covered by the note above this
|
|
1178
|
+
// array, and they already ship unconditionally.
|
|
1179
|
+
"apps/api/src/routes/waitlist-experiments/index.ts",
|
|
1180
|
+
"apps/api/src/routes/waitlist-experiments/list.ts",
|
|
1181
|
+
"apps/api/src/routes/waitlist-experiments/comparison.ts",
|
|
1182
|
+
"apps/api/src/routes/waitlist-experiments/signup.ts",
|
|
1183
|
+
"apps/api/src/routes/waitlist-experiments/signups.ts",
|
|
1184
|
+
"apps/api/src/routes/waitlist-experiments/respond.ts",
|
|
1185
|
+
"apps/api/src/services/waitlist-dashboard.ts",
|
|
1186
|
+
"apps/api/src/routes/project-listings/get.ts",
|
|
1187
|
+
"apps/api/src/routes/project-listings/list.ts",
|
|
1188
|
+
"apps/api/src/routes/project-listings/patch.ts",
|
|
1189
|
+
// The dashboard itself. Without these the Pro scaffold would boot with
|
|
1190
|
+
// reachable review routes and no UI to read them through, and the two
|
|
1191
|
+
// files that DO already ship into every scaffold
|
|
1192
|
+
// (`waitlist/format.ts`, `waitlist/components/ForbiddenState.tsx` — never
|
|
1193
|
+
// owned by any module) would stay orphaned. They import only
|
|
1194
|
+
// `@working-theory/api-client`, `@working-theory/ui` and
|
|
1195
|
+
// `@working-theory/validation`, all base packages, so this pulls in no
|
|
1196
|
+
// multi-tenant dependency.
|
|
1197
|
+
"apps/web/app/[locale]/(authed)/waitlist/page.tsx",
|
|
1198
|
+
"apps/web/app/[locale]/(authed)/waitlist/[experimentId]/page.tsx",
|
|
1199
|
+
"apps/web/app/[locale]/(authed)/waitlist/[experimentId]/signups/[leadId]/page.tsx",
|
|
1200
|
+
"apps/web/app/[locale]/(authed)/waitlist/components/ExperimentsTable.tsx",
|
|
1201
|
+
"apps/web/app/[locale]/(authed)/waitlist/components/OfferFunnelTable.tsx",
|
|
1202
|
+
"apps/web/app/[locale]/(authed)/waitlist/components/RollupTicker.tsx",
|
|
1203
|
+
"apps/web/app/[locale]/(authed)/waitlist/components/ScoreTrace.tsx",
|
|
1204
|
+
"apps/web/app/[locale]/(authed)/waitlist/components/SignupsTable.tsx",
|
|
1205
|
+
"apps/web/app/[locale]/(authed)/waitlist/components/WaitlistComparisonTabs.tsx",
|
|
1206
|
+
"apps/web/app/[locale]/(authed)/waitlist/components/status-badges.tsx",
|
|
959
1207
|
// apps/web/app/[locale]/flows/** deliberately NOT listed here (unlike
|
|
960
1208
|
// the docs-blog precedent's own `blog`/`docs` page.tsx entries above),
|
|
961
1209
|
// even though every file under it is signal-collectors territory and
|
|
@@ -982,18 +1230,103 @@ export const MODULE_SLICES = {
|
|
|
982
1230
|
// `NESTED_FOREIGN_MODULE_ENTRIES` for the companion fix that keeps its
|
|
983
1231
|
// presence from falsely reading as "projects carried".
|
|
984
1232
|
"apps/web/app/[locale]/projects/apply/ListingApplicationClient.tsx",
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
"
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
"
|
|
1233
|
+
// #5581 U4 — the eleven signal-collectors components + the slice's own
|
|
1234
|
+
// re-export entry point moved to packages-paid/ui-signal-collectors;
|
|
1235
|
+
// the package is delivered to a keyed scaffold via `patches` below,
|
|
1236
|
+
// not via `ownedFiles`/`installMap` (D5).
|
|
1237
|
+
// #5562 — the report reader at `/reports/<slug>`. UNLIKE the flow routes
|
|
1238
|
+
// above, this one DOES belong in `ownedFiles`, and for the same reason
|
|
1239
|
+
// `projects/apply/ListingApplicationClient.tsx` does: `/reports` is a URL
|
|
1240
|
+
// segment `MODULE_SURFACES["signal-collectors"] = ["flows"]` does not gate,
|
|
1241
|
+
// so `excludedRoutePaths()` would leave it in a keyless scaffold. It has no
|
|
1242
|
+
// upgrade-path fixture to protect either — it is net-new here, so nothing
|
|
1243
|
+
// in `templates/` can regress by its absence.
|
|
1244
|
+
"apps/web/app/[locale]/reports/[slug]/page.tsx",
|
|
1245
|
+
//
|
|
1246
|
+
// The two sections that route composes — `report-header` and
|
|
1247
|
+
// `reports-list` — are deliberately NOT owned here. They are
|
|
1248
|
+
// `SectionRenderer` DISPATCH entries with static imports, so stripping
|
|
1249
|
+
// them would leave the renderer with dangling imports in a keyless
|
|
1250
|
+
// scaffold; the escape hatch for a slice-owned dispatch entry is the
|
|
1251
|
+
// `ModuleAbsent` placeholder (`booker`, `payment-receipt`), which is
|
|
1252
|
+
// machinery neither of these needs. `document-viewer` (#5270) — the
|
|
1253
|
+
// reader this route is built around, and the section with the strongest
|
|
1254
|
+
// claim to being deliverables-only — is likewise unowned base
|
|
1255
|
+
// `packages/ui`. A section is vocabulary; the ROUTE is the module.
|
|
1256
|
+
],
|
|
1257
|
+
// pageContributions (spec 5478; parent § D6 shape 2) — the three flow
|
|
1258
|
+
// routes, named exactly as `surfaces.ts`'s ROUTE_SINCE keys name them.
|
|
1259
|
+
// ROWS AND SEED ONLY: unlike docs-blog and scheduling above, this module's
|
|
1260
|
+
// route code is deliberately NOT in `ownedFiles` (see the comment inside
|
|
1261
|
+
// that array). The first two rows' code reaches a scaffold from the
|
|
1262
|
+
// `templates/` snapshot, retained because the `flows` surface is enabled;
|
|
1263
|
+
// the results row's code is `commerce`'s (`commerce.ownedFiles` carries
|
|
1264
|
+
// `results/[payload]/page.tsx` + its two client files below, and
|
|
1265
|
+
// `paidModuleTemplateExclusions` strips every paid module's owned files
|
|
1266
|
+
// from the snapshot unconditionally), so that one row rides a DIFFERENT
|
|
1267
|
+
// module's bundle — recorded in spec 5478 § 8 item 1, whose delivery
|
|
1268
|
+
// consequence is #5481's and #5464's. Declaring the rows here changes none
|
|
1269
|
+
// of it: a contribution is data, and which delivery shape carries the code
|
|
1270
|
+
// is a property of the module, not of the contribution.
|
|
1271
|
+
pageContributions: [
|
|
1272
|
+
{ route: "/flows/[slug]" },
|
|
1273
|
+
{ route: "/flows/[slug]/start" },
|
|
1274
|
+
{ route: "/flows/[slug]/results/[payload]" },
|
|
1275
|
+
// #5562 — the report reader. Unlike the three rows above, this row's
|
|
1276
|
+
// code IS this module's own `ownedFiles` (see the note beside it), so
|
|
1277
|
+
// the contribution and the delivery shape carrying it agree here.
|
|
1278
|
+
{ route: "/reports/[slug]" },
|
|
1279
|
+
],
|
|
1280
|
+
// installMap (#5618 D6.3) — the module's ten sample files, moved here out
|
|
1281
|
+
// of `site-templates/marketing-site/` so the module OWNS its samples
|
|
1282
|
+
// (Rule B) and a keyed `--modules signal-collectors` scaffold with no
|
|
1283
|
+
// template lands them. Their in-repo home is
|
|
1284
|
+
// `packages/create-ailk/module-templates/signal-collectors/**`, mirroring
|
|
1285
|
+
// `commerce.installMap` below — the only other slice-level map — because
|
|
1286
|
+
// an `installMap` KEY is a repo-relative source the producer copies
|
|
1287
|
+
// literally, and `content/en/ProjectsList/projects.mdx` is ALSO this
|
|
1288
|
+
// repo's own live marketing copy (a different file), which
|
|
1289
|
+
// build-templates.mjs keeps out of every scaffold: under
|
|
1290
|
+
// `module-templates/` the two never meet.
|
|
1291
|
+
//
|
|
1292
|
+
// Four entries are real renames (the flow and waitlist seeds the API
|
|
1293
|
+
// reads, and the report PDF under apps/web/public/); the six MDX entries
|
|
1294
|
+
// are self-addressed because no `pageContributions` row declares
|
|
1295
|
+
// `/projects`, `/projects/[slug]` or `/thanks/[slug]` yet (spec § 7
|
|
1296
|
+
// finding 7 — declaring them changes the enabled-surface set and so the
|
|
1297
|
+
// Pro scaffold's file set, a separate decision). Once those rows exist
|
|
1298
|
+
// the six move to `pageContributions[].content` with no further
|
|
1299
|
+
// migration. `generate-sample-report.py` keeps its root-level
|
|
1300
|
+
// destination (finding 1 — AC7 forbids changing the Pro file set).
|
|
1301
|
+
installMap: {
|
|
1302
|
+
"packages/create-ailk/module-templates/signal-collectors/content/en/ProjectsList/projects.mdx": "content/en/ProjectsList/projects.mdx",
|
|
1303
|
+
"packages/create-ailk/module-templates/signal-collectors/content/en/Project/fit-check-funnel.mdx": "content/en/Project/fit-check-funnel.mdx",
|
|
1304
|
+
"packages/create-ailk/module-templates/signal-collectors/content/en/Project/launch-site-in-fourteen-days.mdx": "content/en/Project/launch-site-in-fourteen-days.mdx",
|
|
1305
|
+
"packages/create-ailk/module-templates/signal-collectors/content/en/ThankYouPage/contact.mdx": "content/en/ThankYouPage/contact.mdx",
|
|
1306
|
+
"packages/create-ailk/module-templates/signal-collectors/content/en/ThankYouPage/newsletter.mdx": "content/en/ThankYouPage/newsletter.mdx",
|
|
1307
|
+
"packages/create-ailk/module-templates/signal-collectors/content/en/ThankYouPage/apply.mdx": "content/en/ThankYouPage/apply.mdx",
|
|
1308
|
+
"packages/create-ailk/module-templates/signal-collectors/flows/fit-check.flow.json": "database/flows/fit-check.flow.json",
|
|
1309
|
+
"packages/create-ailk/module-templates/signal-collectors/waitlist/launch-waitlist.experiment.json": "database/waitlist/launch-waitlist.experiment.json",
|
|
1310
|
+
"packages/create-ailk/module-templates/signal-collectors/reports/sample-report.pdf": "apps/web/public/reports/sample-report.pdf",
|
|
1311
|
+
"packages/create-ailk/module-templates/signal-collectors/reports/generate-sample-report.py": "reports/generate-sample-report.py",
|
|
1312
|
+
},
|
|
1313
|
+
// patches (#5581 U4, D5) — delivers the extracted component package to a
|
|
1314
|
+
// keyed scaffold's apps/web, mirroring the workspace slice's identical
|
|
1315
|
+
// merge-keys op above.
|
|
1316
|
+
patches: [
|
|
1317
|
+
{
|
|
1318
|
+
target: "apps/web/package.json",
|
|
1319
|
+
kind: "json",
|
|
1320
|
+
ops: [
|
|
1321
|
+
{
|
|
1322
|
+
op: "merge-keys",
|
|
1323
|
+
path: ["dependencies"],
|
|
1324
|
+
entries: {
|
|
1325
|
+
"@working-theory/ui-signal-collectors": "workspace:*",
|
|
1326
|
+
},
|
|
1327
|
+
},
|
|
1328
|
+
],
|
|
1329
|
+
},
|
|
997
1330
|
],
|
|
998
1331
|
},
|
|
999
1332
|
// ── commerce — per-site paid add-on (D-47, amending D-26) ─────────────────
|
|
@@ -1091,32 +1424,10 @@ export const MODULE_SLICES = {
|
|
|
1091
1424
|
"apps/api/src/routes/flows/recommender.ts",
|
|
1092
1425
|
"apps/api/src/services/recommender-capture.ts",
|
|
1093
1426
|
"apps/api/src/services/flow-checkouts.ts",
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
"packages/ui/src/blocks/PaymentLinkCard.text.ts",
|
|
1099
|
-
"packages/ui/src/blocks/PaymentLinkForm.tsx",
|
|
1100
|
-
"packages/ui/src/blocks/PaymentLinkForm.text.ts",
|
|
1101
|
-
"packages/ui/src/blocks/PaymentLinkList.tsx",
|
|
1102
|
-
"packages/ui/src/blocks/InvoiceForm.tsx",
|
|
1103
|
-
"packages/ui/src/blocks/InvoiceForm.text.ts",
|
|
1104
|
-
"packages/ui/src/blocks/InvoiceList.tsx",
|
|
1105
|
-
"packages/ui/src/blocks/InvoiceList.text.ts",
|
|
1106
|
-
"packages/ui/src/blocks/SubscriptionStatus.tsx",
|
|
1107
|
-
"packages/ui/src/blocks/SubscriptionStatus.text.ts",
|
|
1108
|
-
"packages/ui/src/blocks/StripeActionButton.tsx",
|
|
1109
|
-
"packages/ui/src/blocks/PaymentStatusBadge.tsx",
|
|
1110
|
-
"packages/ui/src/blocks/PaymentStatusBadge.text.ts",
|
|
1111
|
-
"packages/ui/src/blocks/PaymentResult.tsx",
|
|
1112
|
-
"packages/ui/src/blocks/PaymentResult.text.ts",
|
|
1113
|
-
"packages/ui/src/blocks/PortalEntry.tsx",
|
|
1114
|
-
"packages/ui/src/panels/InvoiceDetail.tsx",
|
|
1115
|
-
"packages/ui/src/panels/InvoiceDetail.text.ts",
|
|
1116
|
-
"packages/ui/src/sections/PaymentReceipt.tsx",
|
|
1117
|
-
"packages/ui/src/sections/PricingTable.tsx",
|
|
1118
|
-
"packages/ui/src/sections/PricingTable.text.ts",
|
|
1119
|
-
"packages/ui/src/sections/slices/commerce.ts",
|
|
1427
|
+
// #5581 U5 — the fifteen commerce components (+ ten .text.ts extractors
|
|
1428
|
+
// + the slice's own re-export entry point) moved to
|
|
1429
|
+
// packages-paid/ui-commerce; the package is delivered to a keyed
|
|
1430
|
+
// scaffold via `patches` below, not via `ownedFiles`/`installMap` (D5).
|
|
1120
1431
|
"apps/web/app/[locale]/flows/[slug]/checkout.actions.ts",
|
|
1121
1432
|
"apps/web/app/[locale]/flows/[slug]/results/[payload]/page.tsx",
|
|
1122
1433
|
"apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsClient.tsx",
|
|
@@ -1147,6 +1458,24 @@ export const MODULE_SLICES = {
|
|
|
1147
1458
|
"packages/create-ailk/module-templates/commerce/.claude/skills/scaffold-commerce/templates/stripe-config.template.ts": ".claude/skills/scaffold-commerce/templates/stripe-config.template.ts",
|
|
1148
1459
|
"packages/create-ailk/module-templates/commerce/.claude/skills/scaffold-commerce/templates/subscription-route.template.ts": ".claude/skills/scaffold-commerce/templates/subscription-route.template.ts",
|
|
1149
1460
|
},
|
|
1461
|
+
// patches (#5581 U5, D5) — delivers the extracted component package to a
|
|
1462
|
+
// keyed scaffold's apps/web, mirroring the workspace slice's identical
|
|
1463
|
+
// merge-keys op above.
|
|
1464
|
+
patches: [
|
|
1465
|
+
{
|
|
1466
|
+
target: "apps/web/package.json",
|
|
1467
|
+
kind: "json",
|
|
1468
|
+
ops: [
|
|
1469
|
+
{
|
|
1470
|
+
op: "merge-keys",
|
|
1471
|
+
path: ["dependencies"],
|
|
1472
|
+
entries: {
|
|
1473
|
+
"@working-theory/ui-commerce": "workspace:*",
|
|
1474
|
+
},
|
|
1475
|
+
},
|
|
1476
|
+
],
|
|
1477
|
+
},
|
|
1478
|
+
],
|
|
1150
1479
|
},
|
|
1151
1480
|
};
|
|
1152
1481
|
/**
|
|
@@ -1194,6 +1523,48 @@ export function normalizeModules(modules) {
|
|
|
1194
1523
|
* Passed in rather than derived from `import.meta.url`, which ts-jest cannot
|
|
1195
1524
|
* load — the same reason `sync-routes.ts` documents for staying pure.
|
|
1196
1525
|
*/
|
|
1526
|
+
/**
|
|
1527
|
+
* Scaffold destinations that MORE THAN ONE module's `ownedFiles` declares —
|
|
1528
|
+
* the co-ownership the `#5618 D4` install-time ownership registry must treat
|
|
1529
|
+
* as intentional rather than as an overwrite (#5702 follow-up).
|
|
1530
|
+
*
|
|
1531
|
+
* Co-ownership is how a file reaches a scaffold under either of two modules
|
|
1532
|
+
* without being transferred away from the other. #5677 needed it for the
|
|
1533
|
+
* submissions review surface: the routes register under
|
|
1534
|
+
* `multi-tenant || signal-collectors`, so BOTH bundles must be able to
|
|
1535
|
+
* deliver them, or the module that lacks them throws
|
|
1536
|
+
* `ERR_MODULE_NOT_FOUND` during `build()`.
|
|
1537
|
+
*
|
|
1538
|
+
* `validateLayerOwnership` (`lib/extract-module-bundle.ts`) refuses a
|
|
1539
|
+
* destination an earlier layer already wrote, because a silent
|
|
1540
|
+
* last-writer-wins between two modules that disagree is the bug `#5618 D4`
|
|
1541
|
+
* exists to catch. Two modules that both DECLARE the same repo file are not
|
|
1542
|
+
* that case: they stage the same bytes from the same source, so whichever
|
|
1543
|
+
* lands second writes what is already there. Without this allowance a
|
|
1544
|
+
* scaffold selecting both modules — `saas-product`, whose `requires` names
|
|
1545
|
+
* `signal-collectors` AND `multi-tenant` — aborts mid-install, after the
|
|
1546
|
+
* first module's files are on disk.
|
|
1547
|
+
*
|
|
1548
|
+
* Only a DECLARED overlap is allowed. A destination two layers collide on
|
|
1549
|
+
* without both naming it in `ownedFiles` is still refused, which is the
|
|
1550
|
+
* whole invariant.
|
|
1551
|
+
*/
|
|
1552
|
+
export function coOwnedModuleDestinations() {
|
|
1553
|
+
const seen = new Map();
|
|
1554
|
+
for (const slice of Object.values(MODULE_SLICES)) {
|
|
1555
|
+
// A module's own list is deduplicated first: repetition within one slice
|
|
1556
|
+
// is not co-ownership and must not license an overlap on its own.
|
|
1557
|
+
for (const file of new Set(slice.ownedFiles ?? [])) {
|
|
1558
|
+
seen.set(file, (seen.get(file) ?? 0) + 1);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
const coOwned = new Set();
|
|
1562
|
+
for (const [file, count] of seen) {
|
|
1563
|
+
if (count > 1)
|
|
1564
|
+
coOwned.add(file);
|
|
1565
|
+
}
|
|
1566
|
+
return coOwned;
|
|
1567
|
+
}
|
|
1197
1568
|
export function paidModuleTemplateExclusions(snapshotRoots, repoRoot) {
|
|
1198
1569
|
const roots = new Set(snapshotRoots);
|
|
1199
1570
|
const excluded = new Set();
|