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.
- package/component-catalog.json +11939 -0
- package/component-catalog.md +176 -64
- package/dist/cli.js +29 -1
- package/dist/derive-architecture.js +5 -2
- package/dist/lib/extract-module-bundle.d.ts +50 -2
- package/dist/lib/extract-module-bundle.js +223 -15
- 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.js +4 -0
- package/dist/module-architecture.d.ts +59 -8
- package/dist/module-architecture.js +334 -115
- package/dist/parse-args.js +6 -2
- package/dist/programmatic.d.ts +10 -0
- package/dist/programmatic.js +134 -19
- 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 +107 -32
- package/dist/template-manifest.d.ts +55 -3
- package/dist/template-manifest.js +181 -12
- package/dist/template-names.d.ts +1 -1
- package/dist/template-names.js +1 -0
- package/package.json +9 -2
- package/site-templates/_base/ailk-template.json +6 -0
- package/site-templates/_base/content/en/Pricing/pricing.mdx +169 -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 +2 -1
- 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 +8 -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 +82 -6
- 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/components/google-analytics.tsx +18 -1
- package/templates/apps/web/eslint.config.mjs +69 -0
- package/templates/apps/web/jest.config.cjs +7 -15
- 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 +1 -1
- 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 +29 -2
- 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 +7 -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/site-templates/marketing-site-free/content/en/Pricing/pricing.mdx +0 -103
- /package/site-templates/{marketing-site-free → _base}/content/en/PrivacyPage/privacy.mdx +0 -0
- /package/site-templates/{marketing-site-free → _base}/content/en/TermsPage/terms.mdx +0 -0
- /package/templates/apps/web/{src/components → components}/SiteNav.tsx +0 -0
|
@@ -253,39 +253,46 @@ 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
|
-
"packages/templates/src/shells/DocsShell.tsx",
|
|
260
|
-
"packages/templates/src/shells/slices/docs-blog.ts",
|
|
261
|
-
"packages/ui/src/blocks/DocsActionBar.tsx",
|
|
262
|
-
"packages/ui/src/blocks/DocsArticleHeader.tsx",
|
|
263
|
-
"packages/ui/src/blocks/DocsFeedback.tsx",
|
|
264
|
-
"packages/ui/src/blocks/DocsSearch.tsx",
|
|
265
|
-
"packages/ui/src/blocks/DocsTocButton.tsx",
|
|
266
|
-
"packages/ui/src/chrome/DocsSidebar.tsx",
|
|
267
|
-
"packages/ui/src/chrome/slices/docs-blog.ts",
|
|
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.
|
|
268
259
|
],
|
|
269
260
|
// pageContributions (spec 5478; parent § D6 shape 1) — the two route
|
|
270
261
|
// surfaces this module mounts, each with the seed MDX it renders. The
|
|
271
|
-
//
|
|
262
|
+
// nine MDX files are exactly the nine on the tree and cannot come from
|
|
272
263
|
// the `templates/` snapshot: `apps/web/content` is in build-templates.mjs's
|
|
273
264
|
// EXCLUDE_TEMPLATE_DIRS and `template-overlay/` carries no blog or docs
|
|
274
265
|
// stub. They ride this module's own bundle, consistent with the route
|
|
275
|
-
// files above
|
|
276
|
-
//
|
|
277
|
-
//
|
|
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).
|
|
278
277
|
pageContributions: [
|
|
279
278
|
{
|
|
280
279
|
route: "/blog",
|
|
281
280
|
content: [
|
|
282
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",
|
|
283
286
|
"apps/web/content/en/blog/launching-ailk.mdx",
|
|
284
287
|
],
|
|
285
288
|
},
|
|
286
289
|
{
|
|
287
290
|
route: "/docs",
|
|
288
|
-
content: [
|
|
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
|
+
],
|
|
289
296
|
},
|
|
290
297
|
],
|
|
291
298
|
// patches (spec 5418 § 3 D1, Group G) — every Group G row that edits a
|
|
@@ -330,6 +337,8 @@ export const MODULE_SLICES = {
|
|
|
330
337
|
"fumadocs-core": "^16.10.4",
|
|
331
338
|
"fumadocs-mdx": "^15.0.12",
|
|
332
339
|
"@working-theory/fumadocs-schema": "workspace:*",
|
|
340
|
+
// #5581 — the docs-blog module's paid component package (D5).
|
|
341
|
+
"@working-theory/ui-docs-blog": "workspace:*",
|
|
333
342
|
},
|
|
334
343
|
},
|
|
335
344
|
{
|
|
@@ -396,13 +405,13 @@ export const MODULE_SLICES = {
|
|
|
396
405
|
//
|
|
397
406
|
// The FEAT-042 Organization → Workspace → Membership tenancy layer:
|
|
398
407
|
// schema (auth/content namespaces) + workspace-scoped API (apps/api) +
|
|
399
|
-
// the authed
|
|
408
|
+
// the authed Admin app surface (apps/admin). Single-tenant sites
|
|
400
409
|
// (module absent) ship none of this — same base apps/web, fixed scope.
|
|
401
410
|
"multi-tenant": {
|
|
402
411
|
apps: {
|
|
403
|
-
|
|
404
|
-
path: "apps/
|
|
405
|
-
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.",
|
|
406
415
|
may_import_from: [
|
|
407
416
|
"database",
|
|
408
417
|
"packages/templates",
|
|
@@ -411,10 +420,10 @@ export const MODULE_SLICES = {
|
|
|
411
420
|
"packages/validation",
|
|
412
421
|
// The `workspace` module's shared settings components (#5371 req. 6)
|
|
413
422
|
// — the scaffolded-site twin of the root architecture.yaml grant on
|
|
414
|
-
// `apps_paid.
|
|
423
|
+
// `apps_paid.admin`. Pro Plus inherits Pro's module set, so a
|
|
415
424
|
// saas-product scaffold carries both modules and this app composes
|
|
416
425
|
// the identical panels apps/web does, with no forked copy.
|
|
417
|
-
"packages/
|
|
426
|
+
"packages/admin-ui",
|
|
418
427
|
],
|
|
419
428
|
may_not_import_from: [
|
|
420
429
|
"apps/api",
|
|
@@ -486,12 +495,12 @@ export const MODULE_SLICES = {
|
|
|
486
495
|
description: "Stripe SDK wrapper + webhook signature verification",
|
|
487
496
|
may_import_from: ["packages/validation"],
|
|
488
497
|
},
|
|
489
|
-
// apps/
|
|
498
|
+
// apps/admin presentation deps. templates is net-new here; theme/ui/
|
|
490
499
|
// validation duplicate the marketing slice's definitions VERBATIM so the
|
|
491
500
|
// Object.assign merge in deriveArchitecture is order-independent (a
|
|
492
501
|
// multi-tenant-only selection stays self-consistent).
|
|
493
502
|
templates: {
|
|
494
|
-
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)",
|
|
495
504
|
may_import_from: ["packages/theme", "packages/ui", "packages/validation"],
|
|
496
505
|
},
|
|
497
506
|
theme: {
|
|
@@ -553,11 +562,12 @@ export const MODULE_SLICES = {
|
|
|
553
562
|
// ownedFiles (S1, #5088). Verified against the current filesystem and
|
|
554
563
|
// server.ts's module-conditional registration (isModuleEnabled('multi-tenant')).
|
|
555
564
|
//
|
|
556
|
-
// apps-paid/
|
|
565
|
+
// apps-paid/admin/** is a single glob — the whole app (43 files as of
|
|
557
566
|
// this pass, excluding __tests__/node_modules), just moved here from
|
|
558
|
-
// apps/workspace by a parallel workstream on this same branch.
|
|
559
|
-
//
|
|
560
|
-
//
|
|
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.
|
|
561
571
|
//
|
|
562
572
|
// apps/api/src/routes/project-listings/ is MIXED (free anonymous surface
|
|
563
573
|
// + tenant dashboard sharing one directory) — only the tenant-guarded
|
|
@@ -674,15 +684,36 @@ export const MODULE_SLICES = {
|
|
|
674
684
|
"apps/web/app/[locale]/(authed)/waitlist/components/SignupsTable.tsx",
|
|
675
685
|
"apps/web/app/[locale]/(authed)/waitlist/components/WaitlistComparisonTabs.tsx",
|
|
676
686
|
"apps/web/app/[locale]/(authed)/waitlist/components/status-badges.tsx",
|
|
677
|
-
"apps-paid/
|
|
687
|
+
"apps-paid/admin/**",
|
|
678
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/",
|
|
679
710
|
},
|
|
680
711
|
// ── workspace — Pro module: the single-workspace settings shell (D-27/D-49)
|
|
681
712
|
//
|
|
682
|
-
// `/
|
|
713
|
+
// `/admin` in apps/web's `(authed)` segment — General (rename), Site
|
|
683
714
|
// (identity / SEO / theme, over the already-shipped apps/api config routes)
|
|
684
715
|
// and Team (a read-only roster). The three panels live in the shared
|
|
685
|
-
// `packages/
|
|
716
|
+
// `packages/admin-ui` package so the multi-tenant Admin app (the
|
|
686
717
|
// Pro Plus app) composes the identical components rather than a fork.
|
|
687
718
|
//
|
|
688
719
|
// No `apps` / `namespaces` / `forbiddenPatterns` block: this module
|
|
@@ -692,14 +723,14 @@ export const MODULE_SLICES = {
|
|
|
692
723
|
// A PERMISSION, not a physical slice (#5371 D1a) — the identical shape
|
|
693
724
|
// docs-blog uses for `packages/fumadocs-schema`. `packages/` is never in
|
|
694
725
|
// SNAPSHOT_DIRS, so the package reaches a buyer as an npm/bundle
|
|
695
|
-
// dependency under `node_modules/`, never as a `packages/
|
|
726
|
+
// dependency under `node_modules/`, never as a `packages/admin-ui`
|
|
696
727
|
// source sibling; the `patches` entry below is what puts it in the
|
|
697
728
|
// buyer's apps/web/package.json.
|
|
698
|
-
webImports: ["packages/
|
|
729
|
+
webImports: ["packages/admin-ui"],
|
|
699
730
|
packages: {
|
|
700
|
-
"
|
|
701
|
-
description: "Shared
|
|
702
|
-
// packages/templates is required because
|
|
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
|
|
703
734
|
// composes AppShell from @working-theory/templates/shells — the same
|
|
704
735
|
// composition apps/web's own account page uses.
|
|
705
736
|
may_import_from: [
|
|
@@ -713,7 +744,7 @@ export const MODULE_SLICES = {
|
|
|
713
744
|
// SOURCE files only, and only the ones this module physically owns: the
|
|
714
745
|
// three apps/web route files and the two apps/api route files.
|
|
715
746
|
//
|
|
716
|
-
// `packages/
|
|
747
|
+
// `packages/admin-ui/**` is deliberately NOT listed (D1a). It is a
|
|
717
748
|
// whole package that is paid end to end, whose strip disposition is
|
|
718
749
|
// carried by architecture.yaml's `commercial_tier_moves_to` field (its
|
|
719
750
|
// future paid-tree home) rather than by a per-file inventory —
|
|
@@ -733,9 +764,9 @@ export const MODULE_SLICES = {
|
|
|
733
764
|
// Test companions (`__tests__/`) are never listed — the SOURCE-files-only
|
|
734
765
|
// rule above.
|
|
735
766
|
ownedFiles: [
|
|
736
|
-
"apps/web/app/[locale]/(authed)/
|
|
737
|
-
"apps/web/app/[locale]/(authed)/
|
|
738
|
-
"apps/web/app/[locale]/(authed)/
|
|
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",
|
|
739
770
|
"apps/api/src/routes/workspaces/general.ts",
|
|
740
771
|
"apps/api/src/routes/workspaces/members.ts",
|
|
741
772
|
],
|
|
@@ -754,7 +785,7 @@ export const MODULE_SLICES = {
|
|
|
754
785
|
op: "merge-keys",
|
|
755
786
|
path: ["dependencies"],
|
|
756
787
|
entries: {
|
|
757
|
-
"@working-theory/
|
|
788
|
+
"@working-theory/admin-ui": "workspace:*",
|
|
758
789
|
},
|
|
759
790
|
},
|
|
760
791
|
],
|
|
@@ -770,8 +801,10 @@ export const MODULE_SLICES = {
|
|
|
770
801
|
// the ONLY holder of the scheduling credential.
|
|
771
802
|
// api apps/api's own /v1/schedule/availability + /v1/schedule/book.
|
|
772
803
|
// presentation the `booker` section (packages/ui, no iframe) rendered by
|
|
773
|
-
// the `
|
|
774
|
-
// 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).
|
|
775
808
|
//
|
|
776
809
|
// The four forbidden patterns below are the module's whole security
|
|
777
810
|
// argument, restated as boundary rules rather than left in a comment: the
|
|
@@ -864,16 +897,19 @@ export const MODULE_SLICES = {
|
|
|
864
897
|
// consumer — unlike packages/validation below, a strip tool CAN delete
|
|
865
898
|
// exactly these files without touching anything another module needs.
|
|
866
899
|
//
|
|
867
|
-
//
|
|
868
|
-
// 2026-09-11
|
|
869
|
-
//
|
|
870
|
-
//
|
|
871
|
-
//
|
|
872
|
-
//
|
|
873
|
-
//
|
|
874
|
-
//
|
|
875
|
-
//
|
|
876
|
-
//
|
|
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.
|
|
877
913
|
//
|
|
878
914
|
// packages/sections-registry/src/registry.ts (the `booker:` entry) and
|
|
879
915
|
// packages/validation/src/schemas/page-sections.ts (BookerSectionDataSchema,
|
|
@@ -902,13 +938,14 @@ export const MODULE_SLICES = {
|
|
|
902
938
|
// scheduling-specific. This is a judgment call, not covered by this
|
|
903
939
|
// card's explicit checklist: flagged for reviewer confirmation.
|
|
904
940
|
//
|
|
905
|
-
//
|
|
906
|
-
//
|
|
907
|
-
//
|
|
908
|
-
//
|
|
909
|
-
// files
|
|
910
|
-
// `slice-renderers.ts` and `ModuleAbsent.tsx` — are
|
|
911
|
-
// 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.
|
|
912
949
|
ownedFiles: [
|
|
913
950
|
"apps/api/src/routes/schedule/index.ts",
|
|
914
951
|
"apps/api/src/services/scheduling/index.ts",
|
|
@@ -917,24 +954,36 @@ export const MODULE_SLICES = {
|
|
|
917
954
|
"apps/mcp/src/tools/list_availability.ts",
|
|
918
955
|
"apps/mcp/src/tools/get_event_meta.ts",
|
|
919
956
|
"apps/mcp/src/tools/create_booking.ts",
|
|
920
|
-
"
|
|
921
|
-
"
|
|
922
|
-
"
|
|
923
|
-
"packages/ui/src/blocks/BookerSlotGrid.tsx",
|
|
924
|
-
"packages/ui/src/blocks/BookerAttendeeFields.tsx",
|
|
925
|
-
"packages/ui/src/blocks/BookerEventHeader.tsx",
|
|
926
|
-
"packages/ui/src/blocks/BookerDateStrip.tsx",
|
|
927
|
-
"packages/ui/src/sections/slices/scheduling.ts",
|
|
928
|
-
"apps/web/app/[locale]/schedule/page.tsx",
|
|
929
|
-
"apps/web/app/[locale]/schedule/confirmed/page.tsx",
|
|
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",
|
|
930
960
|
],
|
|
931
|
-
// pageContributions (spec 5478; parent § D6 shape 1) — the booker
|
|
932
|
-
// confirmation page, whose route files
|
|
933
|
-
//
|
|
934
|
-
// routes, not from an MDX file.
|
|
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.
|
|
935
965
|
pageContributions: [
|
|
936
|
-
{ route: "/
|
|
937
|
-
{ route: "/
|
|
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
|
+
},
|
|
938
987
|
],
|
|
939
988
|
},
|
|
940
989
|
// ── signal-collectors — flows, deliverables, project listings, waitlist
|
|
@@ -1089,6 +1138,72 @@ export const MODULE_SLICES = {
|
|
|
1089
1138
|
"apps/api/src/bin/seed-waitlist-experiments.ts",
|
|
1090
1139
|
"apps/mcp/src/tools/get_flow.ts",
|
|
1091
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",
|
|
1092
1207
|
// apps/web/app/[locale]/flows/** deliberately NOT listed here (unlike
|
|
1093
1208
|
// the docs-blog precedent's own `blog`/`docs` page.tsx entries above),
|
|
1094
1209
|
// even though every file under it is signal-collectors territory and
|
|
@@ -1115,18 +1230,29 @@ export const MODULE_SLICES = {
|
|
|
1115
1230
|
// `NESTED_FOREIGN_MODULE_ENTRIES` for the companion fix that keeps its
|
|
1116
1231
|
// presence from falsely reading as "projects carried".
|
|
1117
1232
|
"apps/web/app/[locale]/projects/apply/ListingApplicationClient.tsx",
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
"
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
"
|
|
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.
|
|
1130
1256
|
],
|
|
1131
1257
|
// pageContributions (spec 5478; parent § D6 shape 2) — the three flow
|
|
1132
1258
|
// routes, named exactly as `surfaces.ts`'s ROUTE_SINCE keys name them.
|
|
@@ -1146,6 +1272,61 @@ export const MODULE_SLICES = {
|
|
|
1146
1272
|
{ route: "/flows/[slug]" },
|
|
1147
1273
|
{ route: "/flows/[slug]/start" },
|
|
1148
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
|
+
},
|
|
1149
1330
|
],
|
|
1150
1331
|
},
|
|
1151
1332
|
// ── commerce — per-site paid add-on (D-47, amending D-26) ─────────────────
|
|
@@ -1243,32 +1424,10 @@ export const MODULE_SLICES = {
|
|
|
1243
1424
|
"apps/api/src/routes/flows/recommender.ts",
|
|
1244
1425
|
"apps/api/src/services/recommender-capture.ts",
|
|
1245
1426
|
"apps/api/src/services/flow-checkouts.ts",
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
"packages/ui/src/blocks/PaymentLinkCard.text.ts",
|
|
1251
|
-
"packages/ui/src/blocks/PaymentLinkForm.tsx",
|
|
1252
|
-
"packages/ui/src/blocks/PaymentLinkForm.text.ts",
|
|
1253
|
-
"packages/ui/src/blocks/PaymentLinkList.tsx",
|
|
1254
|
-
"packages/ui/src/blocks/InvoiceForm.tsx",
|
|
1255
|
-
"packages/ui/src/blocks/InvoiceForm.text.ts",
|
|
1256
|
-
"packages/ui/src/blocks/InvoiceList.tsx",
|
|
1257
|
-
"packages/ui/src/blocks/InvoiceList.text.ts",
|
|
1258
|
-
"packages/ui/src/blocks/SubscriptionStatus.tsx",
|
|
1259
|
-
"packages/ui/src/blocks/SubscriptionStatus.text.ts",
|
|
1260
|
-
"packages/ui/src/blocks/StripeActionButton.tsx",
|
|
1261
|
-
"packages/ui/src/blocks/PaymentStatusBadge.tsx",
|
|
1262
|
-
"packages/ui/src/blocks/PaymentStatusBadge.text.ts",
|
|
1263
|
-
"packages/ui/src/blocks/PaymentResult.tsx",
|
|
1264
|
-
"packages/ui/src/blocks/PaymentResult.text.ts",
|
|
1265
|
-
"packages/ui/src/blocks/PortalEntry.tsx",
|
|
1266
|
-
"packages/ui/src/panels/InvoiceDetail.tsx",
|
|
1267
|
-
"packages/ui/src/panels/InvoiceDetail.text.ts",
|
|
1268
|
-
"packages/ui/src/sections/PaymentReceipt.tsx",
|
|
1269
|
-
"packages/ui/src/sections/PricingTable.tsx",
|
|
1270
|
-
"packages/ui/src/sections/PricingTable.text.ts",
|
|
1271
|
-
"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).
|
|
1272
1431
|
"apps/web/app/[locale]/flows/[slug]/checkout.actions.ts",
|
|
1273
1432
|
"apps/web/app/[locale]/flows/[slug]/results/[payload]/page.tsx",
|
|
1274
1433
|
"apps/web/app/[locale]/flows/[slug]/results/[payload]/ResultsClient.tsx",
|
|
@@ -1299,6 +1458,24 @@ export const MODULE_SLICES = {
|
|
|
1299
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",
|
|
1300
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",
|
|
1301
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
|
+
],
|
|
1302
1479
|
},
|
|
1303
1480
|
};
|
|
1304
1481
|
/**
|
|
@@ -1346,6 +1523,48 @@ export function normalizeModules(modules) {
|
|
|
1346
1523
|
* Passed in rather than derived from `import.meta.url`, which ts-jest cannot
|
|
1347
1524
|
* load — the same reason `sync-routes.ts` documents for staying pure.
|
|
1348
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
|
+
}
|
|
1349
1568
|
export function paidModuleTemplateExclusions(snapshotRoots, repoRoot) {
|
|
1350
1569
|
const roots = new Set(snapshotRoots);
|
|
1351
1570
|
const excluded = new Set();
|