create-ailk 0.24.0 → 0.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -20
- package/component-catalog.json +3 -3
- package/component-catalog.md +3 -3
- package/dist/add-module.js +4 -2
- package/dist/add-route.d.ts +12 -1
- package/dist/add-route.js +31 -3
- package/dist/cli.js +12 -7
- package/dist/derive-architecture.d.ts +3 -4
- package/dist/derive-architecture.js +65 -29
- package/dist/lib/design-checks.d.ts +9 -4
- package/dist/lib/design-checks.js +13 -7
- package/dist/lib/extract-module-bundle.js +29 -2
- package/dist/lib/fetch-template-snapshot.d.ts +1 -1
- package/dist/lib/fetch-template-snapshot.js +7 -3
- package/dist/lib/import-graph.d.ts +1 -1
- package/dist/lib/import-graph.js +4 -4
- package/dist/lib/module-license-gate.d.ts +12 -1
- package/dist/lib/module-license-gate.js +34 -12
- package/dist/module-architecture.d.ts +20 -3
- package/dist/module-architecture.js +117 -550
- package/dist/paid-sections.d.ts +25 -1
- package/dist/paid-sections.js +88 -3
- package/dist/surfaces.js +10 -2
- package/dist/template-record.d.ts +14 -4
- package/dist/template-record.js +23 -5
- package/dist/topology.d.ts +16 -3
- package/dist/topology.js +31 -19
- package/dist/update.d.ts +10 -1
- package/dist/update.js +540 -16
- package/package.json +3 -3
- package/release-scope.json +1 -1
- package/templates/.claude/cloudparity-repo-hooks.json +5 -0
- package/templates/.claude/hooks/template-guard.sh +137 -0
- package/templates/.claude/rules/extending.md +106 -0
- package/templates/.claude/rules/loop-contract.md +2 -2
- package/templates/.claude/settings.json +11 -0
- package/templates/.env.example +5 -5
- package/templates/.github/workflows/ci.yml +7 -4
- package/templates/CLAUDE.md +11 -1
- package/templates/CONVENTIONS.md +8 -10
- package/templates/README.md +14 -13
- package/templates/apps/api/.env.example +2 -2
- package/templates/apps/api/CLAUDE.md +102 -76
- package/templates/apps/api/jest.config.cjs +15 -5
- package/templates/apps/api/package.json +16 -20
- package/templates/apps/api/src/__tests__/trusted-origins.server.test.ts +2 -2
- package/templates/apps/api/src/__tests__/vercel-handler.test.ts +4 -4
- package/templates/apps/api/src/index.ts +1 -1
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +3 -3
- package/templates/apps/api/src/modules/commerce.ts +10 -0
- package/templates/apps/api/src/modules/content-write.ts +10 -0
- package/templates/apps/api/src/modules/multi-tenant.ts +10 -0
- package/templates/apps/api/src/modules/scheduling.ts +10 -0
- package/templates/apps/api/src/modules/signal-collectors.ts +10 -0
- package/templates/apps/api/src/modules/workspace.ts +10 -0
- package/templates/apps/api/src/server.ts +117 -1882
- package/templates/apps/api/vercel.json +2 -2
- package/templates/apps/mcp/CLAUDE.md +67 -20
- package/templates/apps/mcp/__tests__/app-entry.test.ts +4 -254
- package/templates/apps/mcp/__tests__/boot-file.test.ts +92 -0
- package/templates/apps/mcp/jest.config.cjs +6 -1
- package/templates/apps/mcp/package.json +5 -13
- package/templates/apps/mcp/src/app.ts +8 -7
- package/templates/apps/mcp/src/index.ts +6 -34
- package/templates/apps/mcp/src/lib/paid-tools.generated.ts +10 -0
- package/templates/apps/mcp/src/lib/topology.generated.ts +2 -2
- package/templates/apps/mcp/src/site.ts +12 -0
- package/templates/apps/web/.env.example +1 -1
- package/templates/apps/web/CLAUDE.md +10 -3
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +9 -3
- package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/magnet-page.test.tsx +22 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/magnet-page.tsx +7 -3
- package/templates/apps/web/app/[locale]/pricing/__tests__/unconnected.test.tsx +43 -0
- package/templates/apps/web/app/[locale]/pricing/page.tsx +7 -3
- package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/__tests__/route.test.ts +222 -0
- package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/route.ts +10 -3
- package/templates/apps/web/app/api/revalidate/route.ts +3 -3
- package/templates/apps/web/auth.ts +2 -2
- package/templates/apps/web/jest.config.cjs +1 -0
- package/templates/apps/web/lib/auth-email.ts +1 -1
- package/templates/apps/web/lib/relay.ts +2 -2
- package/templates/apps/web/lib/release-scope.ts +47 -0
- package/templates/apps/web/lib/server-api.ts +1 -1
- package/templates/apps/web/src/lib/commerce-claim.ts +1 -1
- package/templates/customizations.yaml +37 -0
- package/templates/database/prisma.config.ts +10 -14
- package/templates/database/seed-test.ts +2 -2
- package/templates/database/seed.ts +5 -5
- package/templates/package.json +12 -6
- package/templates/pnpm-workspace.yaml +0 -1
- package/templates/project.yaml +16 -8
- package/templates/tools/jest/reporters.cjs +65 -0
- package/templates/tools/lint-architecture.ts +553 -7
- package/templates/tsconfig.json +1 -2
- package/versions.json +48 -35
- package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +0 -409
- package/templates/apps/api/src/__tests__/factories/agent-caller.ts +0 -102
- package/templates/apps/api/src/__tests__/factories/content-fixture.ts +0 -138
- package/templates/apps/api/src/__tests__/factories/in-memory-prisma.ts +0 -441
- package/templates/apps/api/src/__tests__/factories/index.ts +0 -70
- package/templates/apps/api/src/__tests__/factories/lead-fixture.ts +0 -82
- package/templates/apps/api/src/__tests__/leads-forwarded-rate-limit.test.ts +0 -135
- package/templates/apps/api/src/__tests__/services/enrichment-shim.test.ts +0 -126
- package/templates/apps/api/src/__tests__/stripe-boot.test.ts +0 -132
- package/templates/apps/api/src/__tests__/support/hub-sign-in-fake-db.ts +0 -362
- package/templates/apps/api/src/bin/__tests__/rate-limit-probe.test.ts +0 -184
- package/templates/apps/api/src/bin/abandon-sweep.ts +0 -42
- package/templates/apps/api/src/bin/rate-limit-probe.ts +0 -53
- package/templates/apps/api/src/bin/spokes.ts +0 -198
- package/templates/apps/api/src/bin/stripe-connections-rekey.ts +0 -45
- package/templates/apps/api/src/config/__tests__/hub-require-spoke-key.test.ts +0 -196
- package/templates/apps/api/src/config/__tests__/index.test.ts +0 -233
- package/templates/apps/api/src/config/__tests__/modules.test.ts +0 -76
- package/templates/apps/api/src/config/__tests__/stripe-connection-key.test.ts +0 -185
- package/templates/apps/api/src/config/__tests__/trusted-origins.test.ts +0 -238
- package/templates/apps/api/src/config/index.ts +0 -596
- package/templates/apps/api/src/config/modules.ts +0 -83
- package/templates/apps/api/src/lib/__tests__/agent-store.test.ts +0 -581
- package/templates/apps/api/src/lib/__tests__/auth-email-budget.test.ts +0 -143
- package/templates/apps/api/src/lib/__tests__/consent-ledger-double.ts +0 -237
- package/templates/apps/api/src/lib/__tests__/consent-store.test.ts +0 -353
- package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +0 -201
- package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +0 -224
- package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +0 -120
- package/templates/apps/api/src/lib/__tests__/errors.test.ts +0 -94
- package/templates/apps/api/src/lib/__tests__/file-fallback.test.ts +0 -144
- package/templates/apps/api/src/lib/__tests__/fixtures/HomePage/home.mdx +0 -8
- package/templates/apps/api/src/lib/__tests__/flow-completion-store.test.ts +0 -149
- package/templates/apps/api/src/lib/__tests__/flow-rename-race.db.test.ts +0 -116
- package/templates/apps/api/src/lib/__tests__/hub-sign-in-store.test.ts +0 -209
- package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +0 -257
- package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +0 -96
- package/templates/apps/api/src/lib/__tests__/outbound-http.test.ts +0 -125
- package/templates/apps/api/src/lib/__tests__/prisma.test.ts +0 -165
- package/templates/apps/api/src/lib/__tests__/require-commerce-claim.test.ts +0 -317
- package/templates/apps/api/src/lib/__tests__/require-paid-tier.test.ts +0 -129
- package/templates/apps/api/src/lib/__tests__/site.test.ts +0 -308
- package/templates/apps/api/src/lib/__tests__/slice-load.test.ts +0 -89
- package/templates/apps/api/src/lib/__tests__/spoke-store.test.ts +0 -202
- package/templates/apps/api/src/lib/__tests__/stripe-admission.test.ts +0 -217
- package/templates/apps/api/src/lib/__tests__/stripe.test.ts +0 -82
- package/templates/apps/api/src/lib/agent-store.ts +0 -613
- package/templates/apps/api/src/lib/auth-email-budget.ts +0 -161
- package/templates/apps/api/src/lib/consent-store.ts +0 -363
- package/templates/apps/api/src/lib/content-adapter.ts +0 -112
- package/templates/apps/api/src/lib/deliverable-asset-store.ts +0 -96
- package/templates/apps/api/src/lib/error-serializer.ts +0 -164
- package/templates/apps/api/src/lib/errors.ts +0 -95
- package/templates/apps/api/src/lib/file-fallback.ts +0 -87
- package/templates/apps/api/src/lib/flow-completion-store.ts +0 -136
- package/templates/apps/api/src/lib/hub-sign-in-store.ts +0 -455
- package/templates/apps/api/src/lib/lead-capture-store.ts +0 -122
- package/templates/apps/api/src/lib/lead-delivery.ts +0 -52
- package/templates/apps/api/src/lib/license-key-store.ts +0 -45
- package/templates/apps/api/src/lib/locales.ts +0 -201
- package/templates/apps/api/src/lib/outbound-http.ts +0 -127
- package/templates/apps/api/src/lib/prisma.ts +0 -21
- package/templates/apps/api/src/lib/proposal-paid-store.ts +0 -66
- package/templates/apps/api/src/lib/rate-limit-probe.ts +0 -165
- package/templates/apps/api/src/lib/rate-limit-store.ts +0 -142
- package/templates/apps/api/src/lib/require-commerce-claim.ts +0 -250
- package/templates/apps/api/src/lib/require-paid-tier.ts +0 -53
- package/templates/apps/api/src/lib/site.ts +0 -257
- package/templates/apps/api/src/lib/slice-load.ts +0 -90
- package/templates/apps/api/src/lib/spoke-store.ts +0 -180
- package/templates/apps/api/src/lib/stripe.ts +0 -321
- package/templates/apps/api/src/lib/webhook-idempotency.ts +0 -156
- package/templates/apps/api/src/middleware/__tests__/adversarial/bearer-token-format.test.ts +0 -111
- package/templates/apps/api/src/middleware/__tests__/adversarial/cookie-or-bearer-precedence.test.ts +0 -172
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-bearer-skip.test.ts +0 -119
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-cookie-path.test.ts +0 -138
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-trusted-origins.test.ts +0 -142
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +0 -155
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-timeout.test.ts +0 -139
- package/templates/apps/api/src/middleware/__tests__/auth.bearer-path.test.ts +0 -562
- package/templates/apps/api/src/middleware/__tests__/auth.both-present-precedence.test.ts +0 -76
- package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +0 -220
- package/templates/apps/api/src/middleware/__tests__/auth.database-not-configured.test.ts +0 -97
- package/templates/apps/api/src/middleware/__tests__/auth.hub-session-path.test.ts +0 -557
- package/templates/apps/api/src/middleware/__tests__/auth.neither-present.test.ts +0 -72
- package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +0 -140
- package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +0 -721
- package/templates/apps/api/src/middleware/__tests__/rate-limit-cross-isolate.db.test.ts +0 -220
- package/templates/apps/api/src/middleware/__tests__/rate-limit-store.test.ts +0 -430
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +0 -1409
- package/templates/apps/api/src/middleware/__tests__/write-budget.test.ts +0 -174
- package/templates/apps/api/src/middleware/auth.ts +0 -864
- package/templates/apps/api/src/middleware/default-tenant.ts +0 -166
- package/templates/apps/api/src/middleware/rate-limit.ts +0 -983
- package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +0 -391
- package/templates/apps/api/src/openapi/__tests__/spec-identity.test.ts +0 -182
- package/templates/apps/api/src/openapi/index.ts +0 -18
- package/templates/apps/api/src/openapi/spec.ts +0 -2148
- package/templates/apps/api/src/openapi/surface-drift.ts +0 -195
- package/templates/apps/api/src/routes/aeo/__tests__/index.test.ts +0 -175
- package/templates/apps/api/src/routes/aeo/index.ts +0 -107
- package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +0 -196
- package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +0 -249
- package/templates/apps/api/src/routes/auth/__tests__/hub-sign-in.test.ts +0 -532
- package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +0 -313
- package/templates/apps/api/src/routes/auth/__tests__/transactional-email.test.ts +0 -413
- package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +0 -609
- package/templates/apps/api/src/routes/auth/hub-sign-in.ts +0 -242
- package/templates/apps/api/src/routes/auth/tokens.ts +0 -211
- package/templates/apps/api/src/routes/auth/transactional-email.ts +0 -301
- package/templates/apps/api/src/routes/auth/user.ts +0 -305
- package/templates/apps/api/src/routes/billing/plan-checkout.ts +0 -332
- package/templates/apps/api/src/routes/checkout/__tests__/live-key.test.ts +0 -178
- package/templates/apps/api/src/routes/checkout/__tests__/offerings-authorization.test.ts +0 -1426
- package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +0 -448
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +0 -1742
- package/templates/apps/api/src/routes/checkout/index.ts +0 -34
- package/templates/apps/api/src/routes/checkout/session.ts +0 -171
- package/templates/apps/api/src/routes/checkout/sessions.ts +0 -540
- package/templates/apps/api/src/routes/consent/__tests__/account.test.ts +0 -386
- package/templates/apps/api/src/routes/consent/__tests__/sign-up-rate-limit.test.ts +0 -160
- package/templates/apps/api/src/routes/consent/account.ts +0 -268
- package/templates/apps/api/src/routes/consent/cookie.ts +0 -90
- package/templates/apps/api/src/routes/consent/index.ts +0 -26
- package/templates/apps/api/src/routes/consent/unsubscribe.ts +0 -127
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +0 -853
- package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +0 -230
- package/templates/apps/api/src/routes/content/__tests__/list-types.test.ts +0 -44
- package/templates/apps/api/src/routes/content/__tests__/locale.test.ts +0 -118
- package/templates/apps/api/src/routes/content/__tests__/offerings.test.ts +0 -731
- package/templates/apps/api/src/routes/content/__tests__/pricing.test.ts +0 -753
- package/templates/apps/api/src/routes/content/__tests__/rate-limit.test.ts +0 -51
- package/templates/apps/api/src/routes/content/__tests__/search.test.ts +0 -450
- package/templates/apps/api/src/routes/content/__tests__/shown-offerings.test.ts +0 -762
- package/templates/apps/api/src/routes/content/get-page.ts +0 -183
- package/templates/apps/api/src/routes/content/index.ts +0 -49
- package/templates/apps/api/src/routes/content/list-pages.ts +0 -74
- package/templates/apps/api/src/routes/content/list-types.ts +0 -19
- package/templates/apps/api/src/routes/content/offerings.ts +0 -184
- package/templates/apps/api/src/routes/content/pricing.ts +0 -176
- package/templates/apps/api/src/routes/content/rate-limit.ts +0 -22
- package/templates/apps/api/src/routes/content/search.ts +0 -100
- package/templates/apps/api/src/routes/content/shown-offerings.ts +0 -229
- package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +0 -88
- package/templates/apps/api/src/routes/leads/__tests__/list.test.ts +0 -171
- package/templates/apps/api/src/routes/leads/__tests__/magnet-completion.test.ts +0 -515
- package/templates/apps/api/src/routes/leads/__tests__/spoke.test.ts +0 -392
- package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +0 -165
- package/templates/apps/api/src/routes/leads/index.ts +0 -639
- package/templates/apps/api/src/routes/leads/list.ts +0 -104
- package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +0 -626
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +0 -1268
- package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +0 -847
- package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +0 -491
- package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +0 -476
- package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +0 -872
- package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +0 -1022
- package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +0 -484
- package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +0 -535
- package/templates/apps/api/src/routes/project-listings/index.ts +0 -164
- package/templates/apps/api/src/routes/project-listings/me.ts +0 -87
- package/templates/apps/api/src/routes/project-listings/patch-copy.ts +0 -224
- package/templates/apps/api/src/routes/project-listings/patch-draft.ts +0 -102
- package/templates/apps/api/src/routes/project-listings/public.ts +0 -98
- package/templates/apps/api/src/routes/project-listings/respond.ts +0 -48
- package/templates/apps/api/src/routes/project-listings/resume-token.ts +0 -27
- package/templates/apps/api/src/routes/project-listings/start.ts +0 -140
- package/templates/apps/api/src/routes/project-listings/submit.ts +0 -130
- package/templates/apps/api/src/routes/project-listings/verify-email.ts +0 -150
- package/templates/apps/api/src/routes/requests/__tests__/confirm.test.ts +0 -686
- package/templates/apps/api/src/routes/requests/confirm.ts +0 -601
- package/templates/apps/api/src/routes/requests/index.ts +0 -54
- package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +0 -306
- package/templates/apps/api/src/routes/test/auth/session.ts +0 -143
- package/templates/apps/api/src/routes/webhooks/README.md +0 -398
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-checkout-consent.test.ts +0 -649
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-dunning.test.ts +0 -749
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +0 -449
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +0 -264
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode-live.test.ts +0 -159
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode.test.ts +0 -158
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-offerings.test.ts +0 -814
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +0 -301
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-proposal-paid.test.ts +0 -369
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +0 -215
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-request-paid.test.ts +0 -301
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-site-filter.test.ts +0 -809
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +0 -1155
- package/templates/apps/api/src/routes/webhooks/index.ts +0 -141
- package/templates/apps/api/src/routes/webhooks/stripe-offerings.ts +0 -384
- package/templates/apps/api/src/routes/webhooks/stripe.ts +0 -2028
- package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +0 -645
- package/templates/apps/api/src/services/__tests__/answer-distributions.test.ts +0 -132
- package/templates/apps/api/src/services/__tests__/audit-log.test.ts +0 -1028
- package/templates/apps/api/src/services/__tests__/checkout-plan.test.ts +0 -313
- package/templates/apps/api/src/services/__tests__/consent-ledger.test.ts +0 -503
- package/templates/apps/api/src/services/__tests__/consent-migration.test.ts +0 -65
- package/templates/apps/api/src/services/__tests__/consent.test.ts +0 -299
- package/templates/apps/api/src/services/__tests__/default-tenant.test.ts +0 -147
- package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +0 -877
- package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +0 -379
- package/templates/apps/api/src/services/__tests__/dunning-policy.test.ts +0 -368
- package/templates/apps/api/src/services/__tests__/entitlements.test.ts +0 -142
- package/templates/apps/api/src/services/__tests__/hub-sign-in.test.ts +0 -854
- package/templates/apps/api/src/services/__tests__/keyless-workspace-predicate.test.ts +0 -234
- package/templates/apps/api/src/services/__tests__/lead-accept-user.test.ts +0 -251
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +0 -2660
- package/templates/apps/api/src/services/__tests__/listing-config.test.ts +0 -166
- package/templates/apps/api/src/services/__tests__/magnet-completion.test.ts +0 -389
- package/templates/apps/api/src/services/__tests__/person.test.ts +0 -1204
- package/templates/apps/api/src/services/__tests__/plan-offerings.test.ts +0 -450
- package/templates/apps/api/src/services/__tests__/project-listings.counts.test.ts +0 -202
- package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +0 -151
- package/templates/apps/api/src/services/__tests__/public-site-resolver.test.ts +0 -137
- package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +0 -531
- package/templates/apps/api/src/services/__tests__/revalidation.test.ts +0 -372
- package/templates/apps/api/src/services/__tests__/slack-notify.test.ts +0 -348
- package/templates/apps/api/src/services/__tests__/spoke-resolution.test.ts +0 -660
- package/templates/apps/api/src/services/__tests__/usage-aggregation.test.ts +0 -941
- package/templates/apps/api/src/services/__tests__/usage-credits.test.ts +0 -588
- package/templates/apps/api/src/services/__tests__/verified-email.test.ts +0 -78
- package/templates/apps/api/src/services/abandon-email.ts +0 -336
- package/templates/apps/api/src/services/aeo-score.ts +0 -325
- package/templates/apps/api/src/services/answer-distributions.ts +0 -138
- package/templates/apps/api/src/services/audit-log.ts +0 -961
- package/templates/apps/api/src/services/checkout-buyer.ts +0 -168
- package/templates/apps/api/src/services/consent.ts +0 -834
- package/templates/apps/api/src/services/default-tenant.ts +0 -416
- package/templates/apps/api/src/services/deliverable-fulfillment.ts +0 -750
- package/templates/apps/api/src/services/dunning-policy.ts +0 -294
- package/templates/apps/api/src/services/enrichment-shim.ts +0 -53
- package/templates/apps/api/src/services/entitlements.ts +0 -338
- package/templates/apps/api/src/services/hub-sign-in.ts +0 -472
- package/templates/apps/api/src/services/lead-accept-user.ts +0 -126
- package/templates/apps/api/src/services/lead-promotion.ts +0 -160
- package/templates/apps/api/src/services/lead-routing.ts +0 -1372
- package/templates/apps/api/src/services/leads-inbox.ts +0 -312
- package/templates/apps/api/src/services/listing-config.ts +0 -178
- package/templates/apps/api/src/services/magnet-completion.ts +0 -242
- package/templates/apps/api/src/services/offerings/__tests__/catalog.test.ts +0 -348
- package/templates/apps/api/src/services/offerings/__tests__/checkout-session-record.test.ts +0 -268
- package/templates/apps/api/src/services/offerings/__tests__/connection.test.ts +0 -975
- package/templates/apps/api/src/services/offerings/__tests__/fixtures.ts +0 -416
- package/templates/apps/api/src/services/offerings/__tests__/org-products.test.ts +0 -400
- package/templates/apps/api/src/services/offerings/__tests__/readers.test.ts +0 -685
- package/templates/apps/api/src/services/offerings/__tests__/source.test.ts +0 -231
- package/templates/apps/api/src/services/offerings/catalog.ts +0 -318
- package/templates/apps/api/src/services/offerings/checkout-authorization.ts +0 -403
- package/templates/apps/api/src/services/offerings/checkout-session-record.ts +0 -192
- package/templates/apps/api/src/services/offerings/connection.ts +0 -1083
- package/templates/apps/api/src/services/offerings/index.ts +0 -614
- package/templates/apps/api/src/services/offerings/source.ts +0 -140
- package/templates/apps/api/src/services/offerings/store.ts +0 -150
- package/templates/apps/api/src/services/owner-workspaces.ts +0 -132
- package/templates/apps/api/src/services/person.ts +0 -1211
- package/templates/apps/api/src/services/plan-offerings.ts +0 -125
- package/templates/apps/api/src/services/project-listing-resume-email.ts +0 -326
- package/templates/apps/api/src/services/project-listings.ts +0 -2085
- package/templates/apps/api/src/services/public-site-resolver.ts +0 -396
- package/templates/apps/api/src/services/request-confirm.ts +0 -698
- package/templates/apps/api/src/services/revalidation.ts +0 -235
- package/templates/apps/api/src/services/slack-notify.ts +0 -291
- package/templates/apps/api/src/services/usage-aggregation.ts +0 -516
- package/templates/apps/api/src/services/usage-credits.ts +0 -340
- package/templates/apps/api/src/services/verified-email.ts +0 -71
- package/templates/apps/mcp/__tests__/abuse/daily-cap.test.ts +0 -52
- package/templates/apps/mcp/__tests__/abuse/email-validator.test.ts +0 -46
- package/templates/apps/mcp/__tests__/abuse/guard.test.ts +0 -198
- package/templates/apps/mcp/__tests__/abuse/honeypot.test.ts +0 -36
- package/templates/apps/mcp/__tests__/abuse/user-agent-deny.test.ts +0 -54
- package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +0 -116
- package/templates/apps/mcp/__tests__/audit-single-page.test.ts +0 -299
- package/templates/apps/mcp/__tests__/boot.test.ts +0 -280
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +0 -359
- package/templates/apps/mcp/__tests__/config/modules.test.ts +0 -78
- package/templates/apps/mcp/__tests__/get_business_hours.test.ts +0 -82
- package/templates/apps/mcp/__tests__/get_faq.test.ts +0 -80
- package/templates/apps/mcp/__tests__/get_locations.test.ts +0 -65
- package/templates/apps/mcp/__tests__/get_offerings.test.ts +0 -557
- package/templates/apps/mcp/__tests__/get_pricing.test.ts +0 -524
- package/templates/apps/mcp/__tests__/get_site_info.test.ts +0 -81
- package/templates/apps/mcp/__tests__/http-transport.test.ts +0 -1232
- package/templates/apps/mcp/__tests__/index.test.ts +0 -195
- package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +0 -191
- package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +0 -531
- package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +0 -70
- package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +0 -162
- package/templates/apps/mcp/__tests__/lib/content-root.test.ts +0 -93
- package/templates/apps/mcp/__tests__/lib/errors.test.ts +0 -75
- package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +0 -180
- package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +0 -124
- package/templates/apps/mcp/__tests__/list_pages.test.ts +0 -268
- package/templates/apps/mcp/__tests__/locale.test.ts +0 -120
- package/templates/apps/mcp/__tests__/module-exclusion.test.ts +0 -175
- package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +0 -101
- package/templates/apps/mcp/__tests__/rate-limit-write.test.ts +0 -189
- package/templates/apps/mcp/__tests__/read_content.test.ts +0 -511
- package/templates/apps/mcp/__tests__/request_callback.test.ts +0 -160
- package/templates/apps/mcp/__tests__/search_content.test.ts +0 -271
- package/templates/apps/mcp/__tests__/server.test.ts +0 -388
- package/templates/apps/mcp/__tests__/start_purchase.test.ts +0 -448
- package/templates/apps/mcp/__tests__/submit_lead.test.ts +0 -222
- package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +0 -152
- package/templates/apps/mcp/__tests__/tools/create_project.test.ts +0 -243
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +0 -451
- package/templates/apps/mcp/src/abuse/daily-cap.ts +0 -47
- package/templates/apps/mcp/src/abuse/email-validator.ts +0 -25
- package/templates/apps/mcp/src/abuse/honeypot.ts +0 -21
- package/templates/apps/mcp/src/abuse/index.ts +0 -349
- package/templates/apps/mcp/src/abuse/user-agent-deny.ts +0 -58
- package/templates/apps/mcp/src/boot.ts +0 -167
- package/templates/apps/mcp/src/config/modules.ts +0 -43
- package/templates/apps/mcp/src/http-transport.ts +0 -564
- package/templates/apps/mcp/src/lib/audit-single-page.ts +0 -308
- package/templates/apps/mcp/src/lib/commerce-claim.ts +0 -263
- package/templates/apps/mcp/src/lib/content-adapter.ts +0 -116
- package/templates/apps/mcp/src/lib/empty-content-adapter.ts +0 -140
- package/templates/apps/mcp/src/lib/errors.ts +0 -61
- package/templates/apps/mcp/src/lib/license-key-store.ts +0 -45
- package/templates/apps/mcp/src/lib/locales.ts +0 -171
- package/templates/apps/mcp/src/lib/prisma.ts +0 -39
- package/templates/apps/mcp/src/lib/public-workspace.ts +0 -133
- package/templates/apps/mcp/src/lib/resolve-locale.ts +0 -30
- package/templates/apps/mcp/src/lib/shown-offerings.ts +0 -105
- package/templates/apps/mcp/src/lib/site-config.ts +0 -53
- package/templates/apps/mcp/src/lib/stripe-tax-signal.ts +0 -59
- package/templates/apps/mcp/src/request-context.ts +0 -52
- package/templates/apps/mcp/src/server.ts +0 -343
- package/templates/apps/mcp/src/serverless-app.ts +0 -88
- package/templates/apps/mcp/src/tools/audit.ts +0 -127
- package/templates/apps/mcp/src/tools/capture_lead.ts +0 -66
- package/templates/apps/mcp/src/tools/create_project.ts +0 -134
- package/templates/apps/mcp/src/tools/get_business_hours.ts +0 -68
- package/templates/apps/mcp/src/tools/get_faq.ts +0 -71
- package/templates/apps/mcp/src/tools/get_locations.ts +0 -88
- package/templates/apps/mcp/src/tools/get_offerings.ts +0 -96
- package/templates/apps/mcp/src/tools/get_pricing.ts +0 -94
- package/templates/apps/mcp/src/tools/get_site_info.ts +0 -86
- package/templates/apps/mcp/src/tools/index.ts +0 -138
- package/templates/apps/mcp/src/tools/list_pages.ts +0 -68
- package/templates/apps/mcp/src/tools/person_notes.ts +0 -25
- package/templates/apps/mcp/src/tools/proposals.ts +0 -27
- package/templates/apps/mcp/src/tools/purchase.ts +0 -205
- package/templates/apps/mcp/src/tools/read_content.ts +0 -81
- package/templates/apps/mcp/src/tools/request_callback.ts +0 -52
- package/templates/apps/mcp/src/tools/search_content.ts +0 -63
- package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +0 -54
- package/templates/apps/mcp/src/workspace-server.ts +0 -224
- package/templates/database/CHANGELOG.md +0 -981
- package/templates/database/LICENSE +0 -202
- package/templates/database/NOTICE +0 -2
- package/templates/database/README.md +0 -243
- package/templates/database/__tests__/agents.db.test.ts +0 -320
- package/templates/database/__tests__/appointment.db.test.ts +0 -106
- package/templates/database/__tests__/artifact-content-store.db.test.ts +0 -316
- package/templates/database/__tests__/composite-fence.db.test.ts +0 -206
- package/templates/database/__tests__/consent-ledger.db.test.ts +0 -345
- package/templates/database/__tests__/consent-source-checkout-migration.test.ts +0 -79
- package/templates/database/__tests__/fence-fan-out.db.test.ts +0 -715
- package/templates/database/__tests__/fixtures/appointment-create-probe.ts +0 -79
- package/templates/database/__tests__/fixtures/person-backfill.json +0 -264
- package/templates/database/__tests__/fixtures/person-contact-backfill.json +0 -182
- package/templates/database/__tests__/fixtures/project-listing-consent-probe.ts +0 -100
- package/templates/database/__tests__/flow-completion-migration.test.ts +0 -115
- package/templates/database/__tests__/flow-completion.db.test.ts +0 -136
- package/templates/database/__tests__/flow-workspace-key.db.test.ts +0 -263
- package/templates/database/__tests__/flows-listing-diagnostic.test.ts +0 -392
- package/templates/database/__tests__/flows-presets.test.ts +0 -173
- package/templates/database/__tests__/in-page-magnets-migration.test.ts +0 -161
- package/templates/database/__tests__/lead-idempotency-key.db.test.ts +0 -92
- package/templates/database/__tests__/member-area.db.test.ts +0 -257
- package/templates/database/__tests__/member-contract-migration.test.ts +0 -85
- package/templates/database/__tests__/member-contract.db.test.ts +0 -413
- package/templates/database/__tests__/offerings-checkout-session.db.test.ts +0 -270
- package/templates/database/__tests__/offerings-migration.test.ts +0 -197
- package/templates/database/__tests__/offerings-shown-price-ids-migration.test.ts +0 -86
- package/templates/database/__tests__/offerings.db.test.ts +0 -303
- package/templates/database/__tests__/outbound-message-action.db.test.ts +0 -80
- package/templates/database/__tests__/person-contact.db.test.ts +0 -563
- package/templates/database/__tests__/person-notes.db.test.ts +0 -249
- package/templates/database/__tests__/person.db.test.ts +0 -586
- package/templates/database/__tests__/piece-kind-migration.test.ts +0 -67
- package/templates/database/__tests__/piece-kind.db.test.ts +0 -208
- package/templates/database/__tests__/prefixed-ids.db.test.ts +0 -222
- package/templates/database/__tests__/project-listing-consent-at.db.test.ts +0 -111
- package/templates/database/__tests__/seed.test.ts +0 -272
- package/templates/database/__tests__/spoke-registry.db.test.ts +0 -191
- package/templates/database/__tests__/tenancy.test.ts +0 -141
- package/templates/database/__tests__/trial-magnet-migration.test.ts +0 -186
- package/templates/database/__tests__/user-cascade.test.ts +0 -140
- package/templates/database/_gitignore +0 -8
- package/templates/database/auth/.gitkeep +0 -0
- package/templates/database/auth/schema.prisma +0 -641
- package/templates/database/config/.gitkeep +0 -0
- package/templates/database/config/schema.prisma +0 -441
- package/templates/database/content/.gitkeep +0 -0
- package/templates/database/content/schema.prisma +0 -339
- package/templates/database/eslint.config.mjs +0 -69
- package/templates/database/flows/listing-diagnostic.ts +0 -182
- package/templates/database/flows/presets.ts +0 -315
- package/templates/database/inbox/.gitkeep +0 -0
- package/templates/database/inbox/README.md +0 -3
- package/templates/database/inbox/__tests__/schema.test.ts +0 -44
- package/templates/database/inbox/schema.prisma +0 -1447
- package/templates/database/jest.config.cjs +0 -36
- package/templates/database/migrations/20260508000000_add_inbox_namespace/migration.sql +0 -328
- package/templates/database/migrations/20260513000000_better_auth_migration/migration.sql +0 -100
- package/templates/database/migrations/20260515000000_add_user_billing_fields/migration.sql +0 -28
- package/templates/database/migrations/20260516000000_add_user_tier_care_plan_seat/migration.sql +0 -25
- package/templates/database/migrations/20260518000000_add_telemetry_records/migration.sql +0 -42
- package/templates/database/migrations/20260525000000_theme_wiring/migration.sql +0 -67
- package/templates/database/migrations/20260710000000_retire_commercial_tier/migration.sql +0 -21
- package/templates/database/migrations/20260712215647_add_multi_tenant_tenancy/migration.sql +0 -201
- package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql +0 -67
- package/templates/database/migrations/20260713174000_add_audit_logs/migration.sql +0 -46
- package/templates/database/migrations/20260713190000_drop_telemetry_records/migration.sql +0 -25
- package/templates/database/migrations/20260713192000_add_uuidv7_function/migration.sql +0 -49
- package/templates/database/migrations/20260713192429_prefixed_uuid_entity_ids/migration.sql +0 -197
- package/templates/database/migrations/20260713200000_add_org_billing/migration.sql +0 -32
- package/templates/database/migrations/20260714000000_add_lead_promotion_fields/migration.sql +0 -22
- package/templates/database/migrations/20260714010000_add_usage_billing_content_models/migration.sql +0 -151
- package/templates/database/migrations/20260714020000_add_usage_billing_auth_config_models/migration.sql +0 -223
- package/templates/database/migrations/20260714030000_credit_balance_non_negative/migration.sql +0 -22
- package/templates/database/migrations/20260714030000_widen_usage_billing_report_aggregates/migration.sql +0 -32
- package/templates/database/migrations/20260810233516_add_flow_engine_models/migration.sql +0 -40
- package/templates/database/migrations/20260811020000_add_flow_session_abandon_email_columns/migration.sql +0 -4
- package/templates/database/migrations/20260811030000_add_flow_session_abandon_email_index/migration.sql +0 -2
- package/templates/database/migrations/20260811040000_add_flow_session_segment/migration.sql +0 -2
- package/templates/database/migrations/20260811050000_add_deliverable_models/migration.sql +0 -29
- package/templates/database/migrations/20260812000000_add_deliverable_grant_send_columns/migration.sql +0 -6
- package/templates/database/migrations/20260902222948_add_waitlist_experiment_models/migration.sql +0 -39
- package/templates/database/migrations/20260902224500_add_waitlist_id_format_checks/migration.sql +0 -24
- package/templates/database/migrations/20260903004112_add_flow_session_flags_aeo_score/migration.sql +0 -3
- package/templates/database/migrations/20260903010000_add_playbook_instance/migration.sql +0 -33
- package/templates/database/migrations/20260904000000_add_waitlist_followup_send/migration.sql +0 -30
- package/templates/database/migrations/20260905230000_add_flow_checkout/migration.sql +0 -47
- package/templates/database/migrations/20260906000000_add_flow_checkout_idempotency/migration.sql +0 -16
- package/templates/database/migrations/20260907120000_add_project_listing/migration.sql +0 -47
- package/templates/database/migrations/20260907130000_add_project_listing_slack_columns/migration.sql +0 -10
- package/templates/database/migrations/20260907180000_add_listing_csv_send/migration.sql +0 -26
- package/templates/database/migrations/20260909120000_project_listings_platform/migration.sql +0 -90
- package/templates/database/migrations/20260909180000_listing_draft_and_fields/migration.sql +0 -174
- package/templates/database/migrations/20260910120000_listing_public_site_key/migration.sql +0 -14
- package/templates/database/migrations/20260911120000_listing_copy_edit_audit/migration.sql +0 -25
- package/templates/database/migrations/20260911140000_listing_structured_address/migration.sql +0 -32
- package/templates/database/migrations/20260911180000_consent_grants/migration.sql +0 -71
- package/templates/database/migrations/20260911200000_listing_site_answers/migration.sql +0 -30
- package/templates/database/migrations/20260912120000_listing_owner_link/migration.sql +0 -49
- package/templates/database/migrations/20260914120000_listing_founder_identity/migration.sql +0 -123
- package/templates/database/migrations/20260915120000_project_listing_solution/migration.sql +0 -15
- package/templates/database/migrations/20260916120000_artifact_content_store/migration.sql +0 -158
- package/templates/database/migrations/20260917120000_callback_request_confirm/migration.sql +0 -40
- package/templates/database/migrations/20260918120000_add_appointment/migration.sql +0 -67
- package/templates/database/migrations/20260918120000_asset_metadata_columns/migration.sql +0 -70
- package/templates/database/migrations/20260919120000_flow_workspace_key/migration.sql +0 -181
- package/templates/database/migrations/20260919130000_flow_definition_admin_columns/migration.sql +0 -172
- package/templates/database/migrations/20260919130000_workspace_meetings/migration.sql +0 -41
- package/templates/database/migrations/20260919140000_inbox_workspace_key/migration.sql +0 -185
- package/templates/database/migrations/20260920120000_lead_handled_at/migration.sql +0 -70
- package/templates/database/migrations/20260920130000_lead_workspace_source_index/migration.sql +0 -57
- package/templates/database/migrations/20260921120000_deliverable_grant_workspace_key/migration.sql +0 -68
- package/templates/database/migrations/20260922120000_tenancy_fence/migration.sql +0 -1067
- package/templates/database/migrations/20260923120000_listing_capturing_magnet/migration.sql +0 -210
- package/templates/database/migrations/20261003120000_spoke_registry/migration.sql +0 -80
- package/templates/database/migrations/20261003130000_scheduling_connection/migration.sql +0 -49
- package/templates/database/migrations/20261005120000_agents/migration.sql +0 -84
- package/templates/database/migrations/20261008120000_user_last_workspace/migration.sql +0 -35
- package/templates/database/migrations/20261008130000_lead_idempotency_key/migration.sql +0 -20
- package/templates/database/migrations/20261009120000_agent_grants/migration.sql +0 -33
- package/templates/database/migrations/20261010120000_person/migration.sql +0 -106
- package/templates/database/migrations/20261010121000_person_backfill/migration.sql +0 -132
- package/templates/database/migrations/20261010130000_agent_grants_people_read/migration.sql +0 -20
- package/templates/database/migrations/20261011120000_member_area/migration.sql +0 -158
- package/templates/database/migrations/20261011130000_agent_grants_member_pieces_manage/migration.sql +0 -21
- package/templates/database/migrations/20261012120000_member_contract/migration.sql +0 -192
- package/templates/database/migrations/20261013120000_lead_spoke_checkout/migration.sql +0 -20
- package/templates/database/migrations/20261014120000_consent_ledger/migration.sql +0 -122
- package/templates/database/migrations/20261014120000_person_contact/migration.sql +0 -231
- package/templates/database/migrations/20261015120000_person_notes/migration.sql +0 -77
- package/templates/database/migrations/20261015120000_rate_limit_counters/migration.sql +0 -43
- package/templates/database/migrations/20261016120000_piece_kind/migration.sql +0 -95
- package/templates/database/migrations/20261017120000_outbound_message_action/migration.sql +0 -30
- package/templates/database/migrations/20261018120000_flow_completion/migration.sql +0 -52
- package/templates/database/migrations/20261019120000_consent_source_checkout/migration.sql +0 -27
- package/templates/database/migrations/20261020120000_offerings_data_model/migration.sql +0 -146
- package/templates/database/migrations/20261021120000_offerings_checkout_session/migration.sql +0 -77
- package/templates/database/migrations/20261022120000_in_page_magnets/migration.sql +0 -45
- package/templates/database/migrations/20261023120000_offerings_shown_price_ids/migration.sql +0 -47
- package/templates/database/migrations/20261024120000_organization_plan_checkout_session/migration.sql +0 -16
- package/templates/database/migrations/20261025120000_trial_magnet/migration.sql +0 -28
- package/templates/database/migrations/20261026120000_trial_magnet_proof_line/migration.sql +0 -23
- package/templates/database/migrations/migration_lock.toml +0 -3
- package/templates/database/ops/.gitkeep +0 -0
- package/templates/database/ops/schema.prisma +0 -43
- package/templates/database/package.json +0 -89
- package/templates/database/schema.prisma +0 -71
- package/templates/database/scripts/db-generate-locked.sh +0 -80
- package/templates/database/scripts/person-backfill.sql +0 -132
- package/templates/database/tenancy.ts +0 -183
- package/templates/database/tsconfig.build.json +0 -16
- package/templates/database/tsconfig.flows.json +0 -15
- package/templates/database/tsconfig.json +0 -16
- package/templates/database/tsconfig.tenancy.json +0 -14
package/README.md
CHANGED
|
@@ -17,9 +17,13 @@ Compose the site from modules with `--modules`. The recognized vocabulary is
|
|
|
17
17
|
`RECOGNIZED_MODULES` in `src/parse-args.ts` — `marketing`, `docs-blog`,
|
|
18
18
|
`multi-tenant`, `workspace`, `scheduling`, `signal-collectors`, `commerce` —
|
|
19
19
|
and `--modules` TRIMS or ADDS relative to the level your licence key unlocks
|
|
20
|
-
(#6759), never replaces it:
|
|
21
|
-
|
|
22
|
-
`
|
|
20
|
+
(#6759), never replaces it: Free is `marketing` alone; a Pro key switches
|
|
21
|
+
on `docs-blog`, `scheduling` and `signal-collectors` too; Pro Plus adds
|
|
22
|
+
`multi-tenant`. A run with no key is a Free run, and Free is held for now
|
|
23
|
+
(`release-scope.json` marks `levels.free` `deferred`, #6484): the CLI refuses
|
|
24
|
+
it before its first write, naming `https://ailaunchkit.ai/pricing` and the
|
|
25
|
+
two ways to pass a key (`--license <key>` or `AILK_LICENSE_KEY`). The Free
|
|
26
|
+
template and level stay defined; only the keyless path is held. Naming modules here
|
|
23
27
|
keeps exactly those, trimming the level's default; naming only `commerce`
|
|
24
28
|
(a per-site add-on) or `workspace` (included at Pro, opt-in) adds it on top
|
|
25
29
|
of the level's default without trimming. The level is always DERIVED from
|
|
@@ -42,24 +46,27 @@ vocabulary is `RECOGNIZED_SHAPES` in `src/parse-args.ts` — `organization-produ
|
|
|
42
46
|
`organization-service`, `local-business-service`, `person-service` (the README
|
|
43
47
|
already lists `RECOGNIZED_MODULES` the same way); `local-business-product` is
|
|
44
48
|
refused as not available yet. A terminal run with no `--shape` asks; a
|
|
45
|
-
non-interactive one stops. The level comes only from your license key:
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
non-interactive one stops. The level comes only from your license key: a key
|
|
50
|
+
switches on its level's modules (`LEVEL_MODULES`) — `--modules` trims or adds
|
|
51
|
+
relative to that set, as above — and no key is the Free level, which is held
|
|
52
|
+
(above), so the run is refused before the shape prompt. A keyed example:
|
|
48
53
|
|
|
49
54
|
```bash
|
|
50
55
|
pnpm create ailk@latest my-site --shape organization-service --license <key>
|
|
51
56
|
```
|
|
52
57
|
|
|
53
58
|
`--design minimalism` picks the other look and needs a Pro or Pro Plus key;
|
|
54
|
-
`standard` (the default) needs none
|
|
59
|
+
`standard` (the default) needs none of its own (the run itself still needs a
|
|
60
|
+
key while Free is held, above). `--template <alias>` scaffolds one of the
|
|
55
61
|
three named aliases (`marketing-site-free`, `marketing-site`, `saas-product`) —
|
|
56
62
|
each fixes a shape, a design and its own module list — and cannot be combined
|
|
57
|
-
with `--shape` or `--design
|
|
63
|
+
with `--shape` or `--design`; `marketing-site-free` with no key is refused the
|
|
64
|
+
same way while Free is held.
|
|
58
65
|
|
|
59
66
|
### Add a purchased module to an existing site
|
|
60
67
|
|
|
61
|
-
A site scaffolded without a paid module (a
|
|
62
|
-
|
|
68
|
+
A site scaffolded without a paid module (a site scaffolded with `--modules
|
|
69
|
+
marketing` whose owner then adds `docs-blog`, say) gets it with `add-module` — alias `upgrade` — run against the site
|
|
63
70
|
itself, with `AILK_LICENSE_KEY` covering the module:
|
|
64
71
|
|
|
65
72
|
```bash
|
|
@@ -245,7 +252,7 @@ of three outcomes:
|
|
|
245
252
|
|
|
246
253
|
- **Copied** — the site lacks it and the template has it: `--apply` copies it
|
|
247
254
|
(never overwriting) and check mode lists it under `copies:` and `Also
|
|
248
|
-
|
|
255
|
+
required`.
|
|
249
256
|
- **Left as-is** — the site has it and its copy differs from the template's:
|
|
250
257
|
it is named under `left as-is (differs from the template)` and never
|
|
251
258
|
written. The route is still copied; run your type-check afterwards.
|
|
@@ -496,6 +503,17 @@ from the module distribution's own 401/403 (`src/lib/fetch-module.ts`). The
|
|
|
496
503
|
gate runs before anything is copied (`scaffold()` in `src/programmatic.ts`), so
|
|
497
504
|
a refused run leaves no partial scaffold behind.
|
|
498
505
|
|
|
506
|
+
While the Free level is held (`release-scope.json` `levels.free: "deferred"`,
|
|
507
|
+
#6484), a request that names no paid module needs a key as well: with none,
|
|
508
|
+
`resolvePaidModules` and `cli.ts` call `assertKeyedOrFreeReleased`, which
|
|
509
|
+
refuses the run with `level "free" is not available yet. No licence key, so
|
|
510
|
+
this would be a Free scaffold — pass --license <key> or set AILK_LICENSE_KEY
|
|
511
|
+
with a Pro key → https://ailaunchkit.ai/pricing`, before any prompt, fetch or
|
|
512
|
+
write. The key is read on that path but never validated or sent — an all-Free
|
|
513
|
+
request still makes no request — and a keyed run proceeds exactly as before.
|
|
514
|
+
`AILK_RELEASE_SCOPE=ignore` is the test-only bypass (this package's jest
|
|
515
|
+
setup); a published CLI never sets it.
|
|
516
|
+
|
|
499
517
|
`AILK_MODULE_REGISTRY_URL` is optional: `fetchModule` uses an explicitly passed
|
|
500
518
|
`registryUrl`, then that variable, then `https://api.ailaunchkit.ai/v1/modules`
|
|
501
519
|
(`DEFAULT_AILK_MODULE_REGISTRY_URL`, `src/lib/fetch-module.ts`).
|
|
@@ -506,7 +524,10 @@ explicitly passed `registryUrl`, then that variable, then
|
|
|
506
524
|
either registry fails the fetch before any second request is sent.
|
|
507
525
|
|
|
508
526
|
```bash
|
|
509
|
-
#
|
|
527
|
+
# all-Free — the key is read (Free is held), never validated or sent; no network call
|
|
528
|
+
AILK_LICENSE_KEY=... pnpm create ailk@latest my-site --shape organization-product --modules marketing
|
|
529
|
+
|
|
530
|
+
# the same run with no key is refused before its first write (exit 1)
|
|
510
531
|
pnpm create ailk@latest my-site --shape organization-product --modules marketing
|
|
511
532
|
|
|
512
533
|
# paid — the key is read from the environment
|
|
@@ -515,9 +536,10 @@ AILK_LICENSE_KEY=... pnpm create ailk@latest my-site --shape organization-produc
|
|
|
515
536
|
|
|
516
537
|
The network invariant (#6759 D6), in full:
|
|
517
538
|
|
|
518
|
-
- **No key** → no request at all. A request that names no paid module
|
|
519
|
-
|
|
520
|
-
|
|
539
|
+
- **No key** → no request at all. A request that names no paid module reads
|
|
540
|
+
the key (#6484) but never validates or sends it: `resolvePaidModules` runs
|
|
541
|
+
`assertKeyedOrFreeReleased` — refusing a keyless run while Free is held —
|
|
542
|
+
and returns an empty map on its first branch, before the network.
|
|
521
543
|
- **A key with no `--modules`** → the level probe (`deriveLevel`): 3-4
|
|
522
544
|
requests, to find out what the key unlocks.
|
|
523
545
|
- **An explicit `--modules` list** → requests only for the paid modules it
|
|
@@ -526,7 +548,7 @@ The network invariant (#6759 D6), in full:
|
|
|
526
548
|
## What it does
|
|
527
549
|
|
|
528
550
|
1. Validates the target directory does not exist OR is empty.
|
|
529
|
-
2. Copies the curated template tree (`apps/{web,api,mcp}` + `database/` + `content/` + root config files) from the package's `templates/` directory.
|
|
551
|
+
2. Copies the curated template tree (`apps/{web,api,mcp}` + the thin `database/` — `prisma.config.ts` over the installed `@working-theory/database`, plus the two seeds — + `content/` + root config files) from the package's `templates/` directory.
|
|
530
552
|
3. Substitutes `workspace:*` references in every `package.json` with the matching `@working-theory/*` semver from npm — versions are pinned at npm-publish time.
|
|
531
553
|
4. Substitutes `{{PROJECT_NAME}}`, `{{COMPANY_NAME}}`, `{{COMPANY_DOMAIN}}` markers in `templates/README.md` from the target directory name (and CLI flags / interactive prompts in future versions).
|
|
532
554
|
5. Derives and writes `architecture.yaml` (the site's code-boundary config) from the selected module set — see below.
|
|
@@ -557,10 +579,10 @@ declares a slice for every recognized module.
|
|
|
557
579
|
## Templates are snapshotted at build time
|
|
558
580
|
|
|
559
581
|
The `prepublishOnly` script (`scripts/build-templates.mjs`) reads the canonical
|
|
560
|
-
sources from this monorepo (`apps/`, `database
|
|
561
|
-
populates `templates/`. The npm tarball ships the populated templates via the
|
|
562
|
-
`files` field.
|
|
563
|
-
time; only `pnpm install` (run by the user after scaffolding) hits the npm
|
|
582
|
+
sources from this monorepo (`apps/`, the two `database/` seeds, `content/`, root
|
|
583
|
+
config) and populates `templates/`. The npm tarball ships the populated templates via the
|
|
584
|
+
`files` field. An all-Free scaffold (a key plus `--modules marketing`)
|
|
585
|
+
performs no network access at scaffold time; only `pnpm install` (run by the user after scaffolding) hits the npm
|
|
564
586
|
registry. A run naming a paid module fetches that module's bundle — see
|
|
565
587
|
[Paid modules require `AILK_LICENSE_KEY`](#paid-modules-require-ailk_license_key).
|
|
566
588
|
|
package/component-catalog.json
CHANGED
|
@@ -1283,7 +1283,7 @@
|
|
|
1283
1283
|
"sourcePath": "packages/ui/src/blocks/ListRow.tsx",
|
|
1284
1284
|
"importPath": "@working-theory/ui/blocks",
|
|
1285
1285
|
"exported": true,
|
|
1286
|
-
"description": "The PHONE form of one admin list item. The reference is `
|
|
1286
|
+
"description": "The PHONE form of one admin list item. The reference is `packages-paid/admin/design/demos/first-steps/demo.html:475` (`rowDoc`), which lays the row out as: a leading type glyph, a two-line text column with the MUTED META LINE FIRST and the item's name second (every phone screen in the demo agrees), an optional trailing control, and a chevron.",
|
|
1287
1287
|
"descriptionSource": "doc-comment",
|
|
1288
1288
|
"descriptionGrade": "strong",
|
|
1289
1289
|
"sectionType": null
|
|
@@ -1294,7 +1294,7 @@
|
|
|
1294
1294
|
"sourcePath": "packages/ui/src/blocks/ListTable.tsx",
|
|
1295
1295
|
"importPath": "@working-theory/ui/blocks",
|
|
1296
1296
|
"exported": true,
|
|
1297
|
-
"description": "The desktop form: a fixed-layout list table that never wraps, with the shared Tags and Live cells. The reference is `
|
|
1297
|
+
"description": "The desktop form: a fixed-layout list table that never wraps, with the shared Tags and Live cells. The reference is `packages-paid/admin/design/demos/first-steps/demo.html`'s `.tbl`: `table-layout:fixed` on the table and `white-space:nowrap;overflow:hidden;text-overflow:ellipsis` on every cell. BOTH are load-bearing — `table-fixed` alone lets the cell wrap, `truncate` alone lets the browser widen the column to fit.",
|
|
1298
1298
|
"descriptionSource": "barrel",
|
|
1299
1299
|
"descriptionGrade": "strong",
|
|
1300
1300
|
"sectionType": null
|
|
@@ -1646,7 +1646,7 @@
|
|
|
1646
1646
|
"sourcePath": "packages/ui/src/blocks/RowGroup.tsx",
|
|
1647
1647
|
"importPath": "@working-theory/ui/blocks",
|
|
1648
1648
|
"exported": true,
|
|
1649
|
-
"description": "The bordered box that groups ListRows with hairline dividers. The reference is `
|
|
1649
|
+
"description": "The bordered box that groups ListRows with hairline dividers. The reference is `packages-paid/admin/design/demos/first-steps/demo.html`'s `.box` (`background:var(--bg);border:1px solid var(--border); border-radius:6px;overflow:hidden`) with `.row{border-top:…}` and `.row:first-child{border-top:0}` — i.e. hairlines BETWEEN rows, none above the first.",
|
|
1650
1650
|
"descriptionSource": "barrel",
|
|
1651
1651
|
"descriptionGrade": "strong",
|
|
1652
1652
|
"sectionType": null
|
package/component-catalog.md
CHANGED
|
@@ -177,8 +177,8 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
|
|
|
177
177
|
| `LeadCaptureForm` | The one contact form every template renders. Submits ONLY through the `action` prop — a Server Action the page binds — so there is no fetch, no URL and no browser-side JSON here. | `import { LeadCaptureForm } from "@working-theory/ui/blocks"` |
|
|
178
178
|
| `LinkCard` | A whole-tile link card: the entire tile IS the anchor (Claude-docs link-card anatomy). Optional leading icon, a title heading, and an optional description paragraph. Hover fill + chrome are intrinsic to the block — never props. | `import { LinkCard } from "@working-theory/ui/blocks"` |
|
|
179
179
|
| `LinkListItem` | Hub-page spoke list row: prose Link + optional description, enlarged to the 44px touch-target floor. Fix: the enlarged-hit-area pattern (same idiom as ShortcutTrigger, SegmentedControl's touchTargetFloor) — `min-h-(control-height-big)` clamps the anchor's clickable box to 44px while `inline-flex items-center` keeps the visible text at its normal prose size. | `import { LinkListItem } from "@working-theory/ui/blocks"` |
|
|
180
|
-
| `ListRow` | The PHONE form of one admin list item. The reference is `
|
|
181
|
-
| `ListTable` | The desktop form: a fixed-layout list table that never wraps, with the shared Tags and Live cells. The reference is `
|
|
180
|
+
| `ListRow` | The PHONE form of one admin list item. The reference is `packages-paid/admin/design/demos/first-steps/demo.html:475` (`rowDoc`), which lays the row out as: a leading type glyph, a two-line text column with the MUTED META LINE FIRST and the item's name second (every phone screen in the demo agrees), an optional trailing control, and a chevron. | `import { ListRow } from "@working-theory/ui/blocks"` |
|
|
181
|
+
| `ListTable` | The desktop form: a fixed-layout list table that never wraps, with the shared Tags and Live cells. The reference is `packages-paid/admin/design/demos/first-steps/demo.html`'s `.tbl`: `table-layout:fixed` on the table and `white-space:nowrap;overflow:hidden;text-overflow:ellipsis` on every cell. BOTH are load-bearing — `table-fixed` alone lets the cell wrap, `truncate` alone lets the browser widen the column to fit. | `import { ListTable } from "@working-theory/ui/blocks"` |
|
|
182
182
|
| `LocaleSwitcher` | Compact globe + locale dropdown. Extracts the "🌐 English ▾" affordance that lived as an inline node in the chrome Footer story into a reusable block. Composes the `Select` primitive (NOT a raw <select>): a leading globe icon, the current locale label (via SelectValue), and the trigger's built-in chevron. | `import { LocaleSwitcher } from "@working-theory/ui/blocks"` |
|
|
183
183
|
| `LocaleSwitcherNav` | Composes the controlled `LocaleSwitcher` block and owns the navigation side-effect that block deliberately leaves to its consumer: on a locale change it writes the `NEXT_LOCALE` cookie and navigates to the as-needed prefixed path (default locale unprefixed, every other locale `/<code>` + path — mirroring `apps/web/middleware.ts`'s `localePrefix: "as-needed"`). | `import { LocaleSwitcherNav } from "@working-theory/ui/blocks"` |
|
|
184
184
|
| `LogoRow` | The ONE logo-strip implementation; bounded layout/treatment/logoSize plus an opt-in motion-safe marquee; composed by the LogoCloud section and the Hero logoStrip opt-in. | `import { LogoRow } from "@working-theory/ui/blocks"` |
|
|
@@ -210,7 +210,7 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
|
|
|
210
210
|
| `Prose` | The single typography wrapper both the docs route and blog render their compiled-MDX body inside. It styles every RAW markdown element a compiled document emits — h2–h6, p, ul/ol/li, blockquote, table parts, hr, a, inline code, pre, img, kbd, strong/em — via `@working-theory/theme` semantic tokens and type roles. No raw color or spacing literals; dark mode rides the semantic tokens (no `dark:` variants needed). | `import { Prose } from "@working-theory/ui/blocks"` |
|
|
211
211
|
| `RecommendationCard` | "For you" proactive-recommendation tile: status + title + description + "Why this?" disclosure + context chip + action + dismiss (ploy-capture recomposition). The "For you" proactive-recommendation card captured off ploy.ai's Overview page (behavior spec: -2, — `overview-page` "For you" feed / rebuild-triage row "For you" recommendation card"). | `import { RecommendationCard } from "@working-theory/ui/blocks"` |
|
|
212
212
|
| `ResponsiveSheet` | ONE component, TWO forms, ONE open pair. Renders its `children` as a Radix Dialog at `md` (768px, --breakpoint-md) and up, and as a full-screen Radix Sheet below it — never both at once. | `import { ResponsiveSheet } from "@working-theory/ui/blocks"` |
|
|
213
|
-
| `RowGroup` | The bordered box that groups ListRows with hairline dividers. The reference is `
|
|
213
|
+
| `RowGroup` | The bordered box that groups ListRows with hairline dividers. The reference is `packages-paid/admin/design/demos/first-steps/demo.html`'s `.box` (`background:var(--bg);border:1px solid var(--border); border-radius:6px;overflow:hidden`) with `.row{border-top:…}` and `.row:first-child{border-top:0}` — i.e. hairlines BETWEEN rows, none above the first. | `import { RowGroup } from "@working-theory/ui/blocks"` |
|
|
214
214
|
| `SchedulerEmbed` | A declarative third-party booking iframe. Renders a full-width, border-0, lazy-loaded <iframe> at `src` with a graceful loading skeleton (shown until the iframe's own `load` event fires) and a timeout-gated plain-link fallback beneath it — for environments that block third-party frames (ad blockers, a strict CSP `frame-src`) where the iframe may load blank or never load at all. | `import { SchedulerEmbed } from "@working-theory/ui/blocks"` · `packages/ui/src/blocks/SchedulerEmbed.tsx` |
|
|
215
215
|
| `SectionActionRow` | The bottom-anchored, centered action row a section places BENEATH its own content, at the 44×44px target-size floor. It is the block form of the placement established for `stair-steps`: a bounded 1-2 action list rendered after the section body rather than inside the section header. | `import { SectionActionRow } from "@working-theory/ui/blocks"` |
|
|
216
216
|
| `SectionHeader` | Alignment-parameterized section header (eyebrow/subtitle/description/supportLink). The same component serves two ranks (headingLevel="section" \| "subsection") and three alignments (align="start" \| "center" \| "end"). It knows nothing about columns/splits/carousels — it is width-flexible and fills whatever container the section places it in. | `import { SectionHeader } from "@working-theory/ui/blocks"` |
|
package/dist/add-module.js
CHANGED
|
@@ -35,7 +35,7 @@ import { writeAuthSecretFile } from "./lib/auth-secret-file.js";
|
|
|
35
35
|
import { appendEnvRows } from "./lib/declared-env.js";
|
|
36
36
|
import { diffTwoStrings, extractModuleBundle, } from "./lib/extract-module-bundle.js";
|
|
37
37
|
import { normalizeModules } from "./module-architecture.js";
|
|
38
|
-
import { MODULE_FLAGS_PATH, PAID_SECTIONS_PATH, writePaidSections } from "./paid-sections.js";
|
|
38
|
+
import { MODULE_FLAGS_PATH, PAID_MCP_TOOLS_PATH, PAID_SECTIONS_PATH, writePaidSections, } from "./paid-sections.js";
|
|
39
39
|
import { ParseError, parseModules } from "./parse-args.js";
|
|
40
40
|
import { writeSpokeFlowsReadme } from "./seed-flows.js";
|
|
41
41
|
import { SITE_ROSTER_PATH, moduleRosterRows, planRosterAppend, readSiteRoster, siteRosterProblems, } from "./site-roster.js";
|
|
@@ -211,7 +211,9 @@ export async function applyModuleToScaffold(opts) {
|
|
|
211
211
|
// overwritten, like `architecture.yaml` above.
|
|
212
212
|
// #8843 D10 — its module-presence flags follow the same file, and are
|
|
213
213
|
// reported the same way when a module turns one on.
|
|
214
|
-
|
|
214
|
+
// #9460 DD6 — the paid MCP tool registry follows `apps/mcp/package.json`
|
|
215
|
+
// the same way.
|
|
216
|
+
const generated = [PAID_SECTIONS_PATH, MODULE_FLAGS_PATH, PAID_MCP_TOOLS_PATH].map((path) => {
|
|
215
217
|
const abs = join(targetAbs, path);
|
|
216
218
|
return { path, abs, before: existsSync(abs) ? readFileSync(abs, "utf8") : undefined };
|
|
217
219
|
});
|
package/dist/add-route.d.ts
CHANGED
|
@@ -72,6 +72,11 @@ export interface AddMagnetResult {
|
|
|
72
72
|
flow: string;
|
|
73
73
|
/** The landing's row, then the walk's. */
|
|
74
74
|
report: MagnetReportRow[];
|
|
75
|
+
/**
|
|
76
|
+
* The `customizations.yaml` entry mapping both pages, indented to append
|
|
77
|
+
* under `customizations:` as `--seed-customizations` prints entries.
|
|
78
|
+
*/
|
|
79
|
+
entry: string;
|
|
75
80
|
}
|
|
76
81
|
/**
|
|
77
82
|
* Write a magnet page pair — `apps/web/app/[locale]/<path>/page.tsx` (the
|
|
@@ -83,6 +88,12 @@ export interface AddMagnetResult {
|
|
|
83
88
|
* that already exists is never overwritten: a second run reports both
|
|
84
89
|
* `skipped`. No `architecture.yaml`, nav or seed changes — the pair is the
|
|
85
90
|
* site's own, with no `ROUTE_SINCE` key or routes-map row (D13).
|
|
91
|
+
*
|
|
92
|
+
* Being the site's own, the pair is no template-record row either: `update`
|
|
93
|
+
* deletes an untouched recorded file the template does not carry. So the
|
|
94
|
+
* site lint's R5a reads both pages as site-authored, and the result carries
|
|
95
|
+
* the `customizations.yaml` entry that maps them, a site-kept decision the
|
|
96
|
+
* report prints ready to paste (#9553).
|
|
86
97
|
*/
|
|
87
98
|
export declare function addMagnetToScaffold(opts: AddMagnetOptions): AddMagnetResult;
|
|
88
99
|
/** The report `add-route magnet` prints. */
|
|
@@ -98,7 +109,7 @@ export interface AddRouteArgs {
|
|
|
98
109
|
/** `--flow`, the magnet mode's flow slug — set only with `magnet`. */
|
|
99
110
|
flow?: string;
|
|
100
111
|
}
|
|
101
|
-
export declare const ADD_ROUTE_HELP = "create-ailk add-route \u2014 add a route family to an existing site.\n\nUsage:\n create-ailk add-route <route> [<target-dir>]\n create-ailk add-route magnet --path <path> --flow <slug> [<target-dir>]\n\nArguments:\n <route> One route family, named as --surfaces names it,\n e.g. pricing.\n <target-dir> An already-scaffolded repo (contains\n architecture.yaml). Defaults to the current dir.\n\nOptions:\n --path <path> magnet only: the site path the landing serves,\n one to three kebab-case segments, e.g. /diagnostic.\n --flow <slug> magnet only: the flow slug the pages are bound to.\n --help, -h Print this message.\n\nCopies the route's pages, writes its seed content, declares it in\narchitecture.yaml and adds its link to the generated nav \u2014 the site a fresh\nscaffold with --surfaces <route> would have been. A file the site already has\nis never overwritten: one whose content differs, a hand-edited nav included,\nis left as-is and listed for manual review with the change the route wanted.\nLike add-module, it also restores any other page route the site carries but\nlacks. A route a module delivers (blog and docs come with docs-blog) is\nrefused; add that module with create-ailk add-module. Running it again changes\nnothing.\n\nadd-route magnet writes a magnet page pair bound to one flow: a landing at\napps/web/app/[locale]/<path>/page.tsx and a full-screen walk at\n<path>/start/page.tsx, each a few lines over the standard magnet pages, so the\ncopy, consent and ending come from the flow's record. It needs the\nsignal-collectors module, and refuses (nothing written) a path the site already\nserves, a one-segment path a LandingPage seed of the same slug owns, a path\nending in start or apply, a reserved first segment (api, v1, flows, account,\nadmin, the sign-in routes, a locale) and a slug the flow API would refuse. A\npage that exists is never overwritten: running it again skips both. It changes\nno architecture.yaml, nav or seed.\n";
|
|
112
|
+
export declare const ADD_ROUTE_HELP = "create-ailk add-route \u2014 add a route family to an existing site.\n\nUsage:\n create-ailk add-route <route> [<target-dir>]\n create-ailk add-route magnet --path <path> --flow <slug> [<target-dir>]\n\nArguments:\n <route> One route family, named as --surfaces names it,\n e.g. pricing.\n <target-dir> An already-scaffolded repo (contains\n architecture.yaml). Defaults to the current dir.\n\nOptions:\n --path <path> magnet only: the site path the landing serves,\n one to three kebab-case segments, e.g. /diagnostic.\n --flow <slug> magnet only: the flow slug the pages are bound to.\n --help, -h Print this message.\n\nCopies the route's pages, writes its seed content, declares it in\narchitecture.yaml and adds its link to the generated nav \u2014 the site a fresh\nscaffold with --surfaces <route> would have been. A file the site already has\nis never overwritten: one whose content differs, a hand-edited nav included,\nis left as-is and listed for manual review with the change the route wanted.\nLike add-module, it also restores any other page route the site carries but\nlacks. A route a module delivers (blog and docs come with docs-blog) is\nrefused; add that module with create-ailk add-module. Running it again changes\nnothing.\n\nadd-route magnet writes a magnet page pair bound to one flow: a landing at\napps/web/app/[locale]/<path>/page.tsx and a full-screen walk at\n<path>/start/page.tsx, each a few lines over the standard magnet pages, so the\ncopy, consent and ending come from the flow's record. It needs the\nsignal-collectors module, and refuses (nothing written) a path the site already\nserves, a one-segment path a LandingPage seed of the same slug owns, a path\nending in start or apply, a reserved first segment (api, v1, flows, account,\nadmin, the sign-in routes, a locale) and a slug the flow API would refuse. A\npage that exists is never overwritten: running it again skips both. It changes\nno architecture.yaml, nav or seed; it prints the customizations.yaml entry\nthat maps the two pages, for pnpm architecture.\n";
|
|
102
113
|
/**
|
|
103
114
|
* Parse the argv AFTER the `add-route` word. Strict `node:util` parseArgs,
|
|
104
115
|
* like `parseAddModuleArgs`; the route itself is validated by
|
package/dist/add-route.js
CHANGED
|
@@ -314,6 +314,11 @@ const RESERVED_FIRST_SEGMENTS = new Set([
|
|
|
314
314
|
const LOCALE_SHAPED_RE = /^[a-z]{2}(-[a-z]{2})?$/;
|
|
315
315
|
/** Template-relative root every page directory sits under. */
|
|
316
316
|
const WEB_ROUTE_ROOT = "apps/web/app/[locale]";
|
|
317
|
+
/**
|
|
318
|
+
* The `request` a pair's `customizations.yaml` entry names (#9553): the AILK
|
|
319
|
+
* issue that made the pair the site's own page (#8840 C1).
|
|
320
|
+
*/
|
|
321
|
+
const MAGNET_REQUEST = "working-theory-labs/ai-launch-kit-internal#8840";
|
|
317
322
|
/** Whether `slug` passes `flowSlugSchema`'s rule. */
|
|
318
323
|
export function isMagnetFlowSlug(slug) {
|
|
319
324
|
return slug.length <= FLOW_SLUG_MAX && FLOW_SLUG_RE.test(slug);
|
|
@@ -328,6 +333,12 @@ export function isMagnetFlowSlug(slug) {
|
|
|
328
333
|
* that already exists is never overwritten: a second run reports both
|
|
329
334
|
* `skipped`. No `architecture.yaml`, nav or seed changes — the pair is the
|
|
330
335
|
* site's own, with no `ROUTE_SINCE` key or routes-map row (D13).
|
|
336
|
+
*
|
|
337
|
+
* Being the site's own, the pair is no template-record row either: `update`
|
|
338
|
+
* deletes an untouched recorded file the template does not carry. So the
|
|
339
|
+
* site lint's R5a reads both pages as site-authored, and the result carries
|
|
340
|
+
* the `customizations.yaml` entry that maps them, a site-kept decision the
|
|
341
|
+
* report prints ready to paste (#9553).
|
|
331
342
|
*/
|
|
332
343
|
export function addMagnetToScaffold(opts) {
|
|
333
344
|
const targetAbs = resolve(opts.targetDir);
|
|
@@ -382,7 +393,23 @@ export function addMagnetToScaffold(opts) {
|
|
|
382
393
|
writeFileSync(dest, text);
|
|
383
394
|
report.push({ path, action: "written" });
|
|
384
395
|
}
|
|
385
|
-
|
|
396
|
+
// Segments join on `--`, which no kebab segment carries, so `/a-b` and
|
|
397
|
+
// `/a/b` never share an id.
|
|
398
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
399
|
+
const entry = [
|
|
400
|
+
` - id: ${JSON.stringify(`magnet-${segments.join("--")}`)}`,
|
|
401
|
+
" paths:",
|
|
402
|
+
...pages.map(([path]) => ` - ${JSON.stringify(path)}`),
|
|
403
|
+
` request: ${JSON.stringify(MAGNET_REQUEST)}`,
|
|
404
|
+
` decision: ${JSON.stringify(`build-in: site — ailk#8840, ${today}, a magnet pair is the site's own page over AILK's standard renderers`)}`,
|
|
405
|
+
].join("\n");
|
|
406
|
+
return {
|
|
407
|
+
targetDir: targetAbs,
|
|
408
|
+
path: opts.path,
|
|
409
|
+
flow: opts.flow,
|
|
410
|
+
report,
|
|
411
|
+
entry,
|
|
412
|
+
};
|
|
386
413
|
}
|
|
387
414
|
/** `--path`'s segments, refusing a path a pair may not take (SEC-8840-J). */
|
|
388
415
|
function magnetPathSegments(path) {
|
|
@@ -507,7 +534,7 @@ export function formatAddMagnetReport(result) {
|
|
|
507
534
|
lines.push(...skipped.map((row) => ` ${row.path}`));
|
|
508
535
|
}
|
|
509
536
|
if (written.length > 0) {
|
|
510
|
-
lines.push(`Next:
|
|
537
|
+
lines.push(`Next: append this entry to customizations.yaml unless it is there already (an empty \`customizations: []\` becomes \`customizations:\` first), then pnpm build and open ${result.path}. The page's copy comes from the ${result.flow} flow's record.`, result.entry);
|
|
511
538
|
}
|
|
512
539
|
return lines.join("\n") + "\n";
|
|
513
540
|
}
|
|
@@ -548,7 +575,8 @@ serves, a one-segment path a LandingPage seed of the same slug owns, a path
|
|
|
548
575
|
ending in start or apply, a reserved first segment (api, v1, flows, account,
|
|
549
576
|
admin, the sign-in routes, a locale) and a slug the flow API would refuse. A
|
|
550
577
|
page that exists is never overwritten: running it again skips both. It changes
|
|
551
|
-
no architecture.yaml, nav or seed.
|
|
578
|
+
no architecture.yaml, nav or seed; it prints the customizations.yaml entry
|
|
579
|
+
that maps the two pages, for pnpm architecture.
|
|
552
580
|
`;
|
|
553
581
|
/**
|
|
554
582
|
* Parse the argv AFTER the `add-route` word. Strict `node:util` parseArgs,
|
package/dist/cli.js
CHANGED
|
@@ -55,7 +55,7 @@ import { ADOPT_HELP, AdoptRefusedError, adoptSite, formatAdoptReport, parseAdopt
|
|
|
55
55
|
import { APPLY_DESIGN_HELP, applyDesign, formatApplyDesignReport, parseApplyDesignArgs, } from "./apply-design.js";
|
|
56
56
|
import { CLAUDE_MD_CHECK_PATH } from "./claude-md.js";
|
|
57
57
|
import { buildScaffoldMarkers } from "./copy.js";
|
|
58
|
-
import { assertReleased } from "./lib/module-license-gate.js";
|
|
58
|
+
import { assertKeyedOrFreeReleased, assertReleased } from "./lib/module-license-gate.js";
|
|
59
59
|
import { withNpmTokenUserConfig } from "./lib/npm-auth.js";
|
|
60
60
|
import { FREE_PREREQUISITES_NOTE, LICENSED_PREREQUISITES_NOTE, isLicensedInstall, proCallout, } from "./lib/pro-callout.js";
|
|
61
61
|
import { LICENSE_SET_HELP, runLicenseSet } from "./license-set.js";
|
|
@@ -309,6 +309,7 @@ async function main() {
|
|
|
309
309
|
targetDir: args.target ?? process.cwd(),
|
|
310
310
|
templatesDir: resolve(PKG_ROOT, "templates"),
|
|
311
311
|
version: readPackageVersion(),
|
|
312
|
+
versions: readVersionMap(),
|
|
312
313
|
});
|
|
313
314
|
process.stdout.write(formatUpdateReport(result));
|
|
314
315
|
}
|
|
@@ -328,6 +329,8 @@ async function main() {
|
|
|
328
329
|
if (parsed.needsShapePrompt && !parsed.help && !parsed.version) {
|
|
329
330
|
assertReleased("designs", [parsed.design]);
|
|
330
331
|
assertReleased("modules", parsed.modules ?? []);
|
|
332
|
+
// #6484 — and a keyless run, which is the Free level the scope defers.
|
|
333
|
+
assertKeyedOrFreeReleased(parsed.license);
|
|
331
334
|
}
|
|
332
335
|
const opts = await resolveCliShape(parsed, {
|
|
333
336
|
input: process.stdin,
|
|
@@ -433,10 +436,12 @@ async function main() {
|
|
|
433
436
|
// rejection (caught at top level below). The network invariant (#6759 D6):
|
|
434
437
|
// no key → no request at all; a key with no --modules → the D4 level probe
|
|
435
438
|
// (3-4 requests); an explicit --modules list → requests only for the paid
|
|
436
|
-
// modules it names, exactly as before this card. `--template
|
|
437
|
-
// marketing-site-free`
|
|
438
|
-
//
|
|
439
|
-
//
|
|
439
|
+
// modules it names, exactly as before this card. A keyless run — `--template
|
|
440
|
+
// marketing-site-free` included, whose all-free `requires` once rode the
|
|
441
|
+
// no-key case (record D11) — is refused by the licence gate inside
|
|
442
|
+
// scaffold() (#6484, REL-034.1: Free is a deferred level,
|
|
443
|
+
// `release-scope.json`), after its scope-name refusals and before its first
|
|
444
|
+
// write, naming the pricing page. With a key, every branch is as before.
|
|
440
445
|
const { targetDir: targetAbs, surfaces, starter, modules: effectiveModules, droppedModules, hubOrigin, hubSignInOrigin, } = await scaffold(toScaffoldOptions(opts));
|
|
441
446
|
const isSpoke = opts.topology === "spoke";
|
|
442
447
|
// The starter scaffold() resolved — from --template, or from --shape (#6754 D4).
|
|
@@ -491,7 +496,7 @@ async function main() {
|
|
|
491
496
|
" AILK_HUB_CLIENT_SECRET # issued by the hub; never written here",
|
|
492
497
|
"",
|
|
493
498
|
"On the hub, issue the client id and secret with:",
|
|
494
|
-
" pnpm --filter @working-theory/api spokes sign-in-client --id <spoke_id> --redirect-uri <this site's origin>/api/hub-session/callback",
|
|
499
|
+
" pnpm --filter @working-theory/app-api spokes sign-in-client --id <spoke_id> --redirect-uri <this site's origin>/api/hub-session/callback",
|
|
495
500
|
]
|
|
496
501
|
: []),
|
|
497
502
|
]
|
|
@@ -500,7 +505,7 @@ async function main() {
|
|
|
500
505
|
];
|
|
501
506
|
// Prerequisites (#6440 AC4) — every one the scaffold enforces, and nothing
|
|
502
507
|
// it does not. A starter reaches `pnpm dev` AND `pnpm build` on a toolchain
|
|
503
|
-
// alone: the Prisma client
|
|
508
|
+
// alone: the Prisma client ships prebuilt in `@working-theory/database`,
|
|
504
509
|
// so there is no generator step to remember, and no database or vendor API
|
|
505
510
|
// key gates either command (a free install also says no licence key does;
|
|
506
511
|
// a licensed one, #6480, does not). Saying so is the point — the previous
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* fixed document shape this module produces — no `yaml`/`js-yaml` dependency.
|
|
15
15
|
*/
|
|
16
16
|
import { type ForbiddenPattern } from "./module-architecture.js";
|
|
17
|
-
import type
|
|
17
|
+
import { type Topology } from "./topology.js";
|
|
18
18
|
/** The topology a document is derived for (#7426 D8). */
|
|
19
19
|
export interface DeriveArchitectureOptions {
|
|
20
20
|
/** `"hub"` (the default) or `"spoke"`. */
|
|
@@ -51,9 +51,8 @@ export declare const SPOKE_MCP_FORBIDDEN_PATTERNS: readonly ForbiddenPattern[];
|
|
|
51
51
|
* modules gets exactly what the modules imply.
|
|
52
52
|
* @param options the topology (#7426 D8). Absent or `"hub"` ⟹ the output is
|
|
53
53
|
* byte-identical to the two-argument form. `"spoke"` ⟹ only the spoke's own
|
|
54
|
-
* apps (`web`, and `mcp` unless `mcp: false`), no `
|
|
55
|
-
*
|
|
56
|
-
* composition tiers.
|
|
54
|
+
* apps (`web`, and `mcp` unless `mcp: false`), no `database` root, a
|
|
55
|
+
* top-level `topology: spoke` and the hub-facing composition tiers.
|
|
57
56
|
* @returns the complete `architecture.yaml` file content (a deterministic
|
|
58
57
|
* function of the module SET, the surface SET and the topology).
|
|
59
58
|
* @throws Error on an unrecognized module (defensive; parse-args rejects first).
|
|
@@ -14,9 +14,19 @@
|
|
|
14
14
|
* fixed document shape this module produces — no `yaml`/`js-yaml` dependency.
|
|
15
15
|
*/
|
|
16
16
|
import { ARCHITECTURE_BASE, MODULE_SLICES, normalizeModules, } from "./module-architecture.js";
|
|
17
|
-
import {
|
|
17
|
+
import { MODULE_FLAGS_PATH, PAID_MCP_TOOLS_PATH, PAID_SECTIONS_PATH } from "./paid-sections.js";
|
|
18
|
+
import { SITE_CHROME_PATH } from "./site-chrome.js";
|
|
19
|
+
import { SITE_FONTS_PATH } from "./site-fonts.js";
|
|
20
|
+
import { SPOKE_CHECKOUT_CONFIG_PATH, SPOKE_CHECKOUT_TEMPLATE_PATHS, } from "./spoke-checkout.js";
|
|
21
|
+
import { CORE_SURFACE_PATHS, NAV_CONFIG_PATH, RECOGNIZED_SURFACES, resolveSurfaces, } from "./surfaces.js";
|
|
22
|
+
import { SPOKE_SEAM_FILES } from "./topology.js";
|
|
18
23
|
/** The npm scope a site consumes and never forks (#9191). */
|
|
19
24
|
const PACKAGE_SCOPE = "@working-theory/";
|
|
25
|
+
/** Apps whose `package.json` name is not `@working-theory/<dir>`, because the published package took it (#9564, #9570). */
|
|
26
|
+
const SHELL_PACKAGE_NAME = {
|
|
27
|
+
api: "app-api",
|
|
28
|
+
admin: "admin-shell",
|
|
29
|
+
};
|
|
20
30
|
/** A spoke's composition tiers (#7426 D8): its data and API are the hub's. */
|
|
21
31
|
const SPOKE_TIERS = {
|
|
22
32
|
data: "none — the hub's database",
|
|
@@ -209,18 +219,6 @@ function appToYaml(app) {
|
|
|
209
219
|
}
|
|
210
220
|
return m;
|
|
211
221
|
}
|
|
212
|
-
function namespacesToYaml(ns) {
|
|
213
|
-
const members = {};
|
|
214
|
-
const sortedMembers = Object.entries(ns.members).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
215
|
-
for (const [key, mem] of sortedMembers) {
|
|
216
|
-
members[key] = { path: mem.path, description: mem.description };
|
|
217
|
-
}
|
|
218
|
-
return {
|
|
219
|
-
description: ns.description,
|
|
220
|
-
members,
|
|
221
|
-
rules: [...ns.rules],
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
222
|
/**
|
|
225
223
|
* Derive the `architecture.yaml` document for a module set.
|
|
226
224
|
*
|
|
@@ -231,9 +229,8 @@ function namespacesToYaml(ns) {
|
|
|
231
229
|
* modules gets exactly what the modules imply.
|
|
232
230
|
* @param options the topology (#7426 D8). Absent or `"hub"` ⟹ the output is
|
|
233
231
|
* byte-identical to the two-argument form. `"spoke"` ⟹ only the spoke's own
|
|
234
|
-
* apps (`web`, and `mcp` unless `mcp: false`), no `
|
|
235
|
-
*
|
|
236
|
-
* composition tiers.
|
|
232
|
+
* apps (`web`, and `mcp` unless `mcp: false`), no `database` root, a
|
|
233
|
+
* top-level `topology: spoke` and the hub-facing composition tiers.
|
|
237
234
|
* @returns the complete `architecture.yaml` file content (a deterministic
|
|
238
235
|
* function of the module SET, the surface SET and the topology).
|
|
239
236
|
* @throws Error on an unrecognized module (defensive; parse-args rejects first).
|
|
@@ -306,11 +303,10 @@ export function deriveArchitecture(modules = ["marketing"], surfaces, options =
|
|
|
306
303
|
forbidden_patterns: mergeForbidden([...ARCHITECTURE_BASE.appForbiddenPatterns], [...(a.forbidden_patterns ?? []), ...extra]).map(scoped),
|
|
307
304
|
});
|
|
308
305
|
}
|
|
309
|
-
// namespaces
|
|
310
|
-
//
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
: slices.find((s) => s.namespaces)?.namespaces;
|
|
306
|
+
// No `namespaces` block (#9569): a site's `database/` holds no schema — the
|
|
307
|
+
// namespace boundaries belong to `@working-theory/database`'s own source and
|
|
308
|
+
// this monorepo's lint, and a rule naming `database/<ns>` paths a scaffold
|
|
309
|
+
// lacks is what #6940 refuses.
|
|
314
310
|
// forbidden_patterns — base floor first, then the selected modules' patterns.
|
|
315
311
|
const extraForbidden = [];
|
|
316
312
|
for (const s of slices)
|
|
@@ -319,17 +315,57 @@ export function deriveArchitecture(modules = ["marketing"], surfaces, options =
|
|
|
319
315
|
// The upgradeable-consumer rules (#9191): the workspaces this scaffold
|
|
320
316
|
// creates and the in-scope package names it gives them. The site lint
|
|
321
317
|
// reads this block to refuse a forked, patched or pinned-off package.
|
|
322
|
-
//
|
|
318
|
+
// A hub's `database/` is a plain folder, not a workspace (#9569): the
|
|
319
|
+
// package is an npm dependency the same-caret rule covers like any other.
|
|
323
320
|
const upgradeableConsumer = {
|
|
324
321
|
package_scope: PACKAGE_SCOPE,
|
|
325
|
-
workspaces:
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
322
|
+
workspaces: ["apps/*"],
|
|
323
|
+
// Every app the scaffold ships is named `@working-theory/<dir>`, except
|
|
324
|
+
// the two whose published package took the name: `@working-theory/api` is
|
|
325
|
+
// what the API app boots from (#9564), so the app is
|
|
326
|
+
// `@working-theory/app-api`; `@working-theory/admin` is what the Admin
|
|
327
|
+
// shell boots from (#9570), so the app is `@working-theory/admin-shell`.
|
|
328
|
+
scaffold_packages: Object.keys(apps)
|
|
329
|
+
.map((dir) => `${PACKAGE_SCOPE}${SHELL_PACKAGE_NAME[dir] ?? dir}`)
|
|
331
330
|
.sort(),
|
|
332
331
|
};
|
|
332
|
+
// The customizations manifest (#9223): the files under `apps/` the template
|
|
333
|
+
// record (`.ailk-template-files.json`) cannot see, so the site lint can tell
|
|
334
|
+
// a site-authored file from a scaffolded one by membership alone. (a) The
|
|
335
|
+
// generator outputs, on a hub and a spoke alike — an exempted path that is
|
|
336
|
+
// absent exempts nothing, and only a create-ailk generator writes each. The
|
|
337
|
+
// constants are composed here, never at module top level: `spoke-checkout`
|
|
338
|
+
// imports this module back, and `template-record`'s own list is deliberately
|
|
339
|
+
// not imported (it reads `spoke-checkout` at top level). (b) Each selected
|
|
340
|
+
// module's bundle-delivered and patched app files, scoped to the apps this
|
|
341
|
+
// derivation declares. (c) A commerce spoke's checkout slice, which
|
|
342
|
+
// `add-module` writes with no record row.
|
|
343
|
+
const generatorPaths = [
|
|
344
|
+
NAV_CONFIG_PATH,
|
|
345
|
+
SITE_CHROME_PATH,
|
|
346
|
+
SITE_FONTS_PATH,
|
|
347
|
+
PAID_SECTIONS_PATH,
|
|
348
|
+
MODULE_FLAGS_PATH,
|
|
349
|
+
PAID_MCP_TOOLS_PATH,
|
|
350
|
+
...SPOKE_SEAM_FILES,
|
|
351
|
+
SPOKE_CHECKOUT_CONFIG_PATH,
|
|
352
|
+
SPOKE_BILLING_ACTION_PATH,
|
|
353
|
+
];
|
|
354
|
+
const modulePaths = [];
|
|
355
|
+
for (const s of slices) {
|
|
356
|
+
modulePaths.push(...(s.ownedFiles ?? []));
|
|
357
|
+
modulePaths.push(...Object.values(s.installMap ?? {}));
|
|
358
|
+
if (s.installRoot)
|
|
359
|
+
modulePaths.push(`${s.installRoot.replace(/\/$/, "")}/**`);
|
|
360
|
+
modulePaths.push(...(s.patches ?? []).map((p) => p.target));
|
|
361
|
+
}
|
|
362
|
+
const checkoutPaths = spoke && selected.includes("commerce")
|
|
363
|
+
? SPOKE_CHECKOUT_TEMPLATE_PATHS.map((p) => (/\.[^/]+$/.test(p) ? p : `${p}/**`))
|
|
364
|
+
: [];
|
|
365
|
+
const customizations = {
|
|
366
|
+
manifest: "customizations.yaml",
|
|
367
|
+
scaffold_paths: sortedUnion(generatorPaths, [...modulePaths, ...checkoutPaths].filter((p) => p.startsWith("apps/") && inScaffold(p))),
|
|
368
|
+
};
|
|
333
369
|
const doc = {
|
|
334
370
|
version: ARCHITECTURE_BASE.version,
|
|
335
371
|
...(spoke ? { topology: "spoke" } : {}),
|
|
@@ -344,9 +380,9 @@ export function deriveArchitecture(modules = ["marketing"], surfaces, options =
|
|
|
344
380
|
available: [...RECOGNIZED_SURFACES],
|
|
345
381
|
},
|
|
346
382
|
apps,
|
|
347
|
-
...(nsSlice ? { namespaces: namespacesToYaml(nsSlice) } : {}),
|
|
348
383
|
forbidden_patterns: forbidden.map(forbiddenToYaml),
|
|
349
384
|
upgradeable_consumer: upgradeableConsumer,
|
|
385
|
+
customizations,
|
|
350
386
|
};
|
|
351
387
|
const header = [
|
|
352
388
|
"# Architecture Boundaries — AI Launch Kit site",
|
|
@@ -79,13 +79,18 @@ export interface MeasureApplyDesignDriftOptions {
|
|
|
79
79
|
workDir: string;
|
|
80
80
|
/** The loopback registry the CLI resolves modules and templates from. */
|
|
81
81
|
registryUrl?: string;
|
|
82
|
-
/**
|
|
82
|
+
/**
|
|
83
|
+
* Scaffolds with `--license <key>` (#9650: a keyless run refuses while Free
|
|
84
|
+
* is held), which writes the site's own `ailk.key` — what `apply-design`
|
|
85
|
+
* gates a non-Free design on.
|
|
86
|
+
*/
|
|
83
87
|
licenseKey?: string;
|
|
84
88
|
}
|
|
85
89
|
/**
|
|
86
|
-
* Scaffold
|
|
87
|
-
* JSON-LD, run `apply-design <design>` on
|
|
88
|
-
* exit at any step throws naming the step
|
|
90
|
+
* Scaffold an `organization-product` site on `standard` — keyed when
|
|
91
|
+
* `licenseKey` is given — compose its JSON-LD, run `apply-design <design>` on
|
|
92
|
+
* it, and compose again. A non-zero exit at any step throws naming the step
|
|
93
|
+
* and the child's stderr.
|
|
89
94
|
*/
|
|
90
95
|
export declare function measureApplyDesignDrift(opts: MeasureApplyDesignDriftOptions): {
|
|
91
96
|
before: ComposedPages;
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
* (#8661 D11); `admitSeededContactPage` admits only those two fields.
|
|
26
26
|
*/
|
|
27
27
|
import { execFileSync } from "node:child_process";
|
|
28
|
-
import { writeFileSync } from "node:fs";
|
|
29
28
|
import { join } from "node:path";
|
|
30
29
|
import { isDeepStrictEqual } from "node:util";
|
|
31
30
|
import { CONTACT_PAGE_PATH } from "../design-home.js";
|
|
@@ -189,9 +188,10 @@ export function assessJsonLdDrift(design, before, after) {
|
|
|
189
188
|
};
|
|
190
189
|
}
|
|
191
190
|
/**
|
|
192
|
-
* Scaffold
|
|
193
|
-
* JSON-LD, run `apply-design <design>` on
|
|
194
|
-
* exit at any step throws naming the step
|
|
191
|
+
* Scaffold an `organization-product` site on `standard` — keyed when
|
|
192
|
+
* `licenseKey` is given — compose its JSON-LD, run `apply-design <design>` on
|
|
193
|
+
* it, and compose again. A non-zero exit at any step throws naming the step
|
|
194
|
+
* and the child's stderr.
|
|
195
195
|
*/
|
|
196
196
|
export function measureApplyDesignDrift(opts) {
|
|
197
197
|
const baseEnv = { ...process.env };
|
|
@@ -223,9 +223,15 @@ export function measureApplyDesignDrift(opts) {
|
|
|
223
223
|
throw new Error(`drift: ${label} printed no JSON: ${err.message}`, { cause: err });
|
|
224
224
|
}
|
|
225
225
|
};
|
|
226
|
-
exec("scaffold organization-product on standard", process.execPath, [
|
|
227
|
-
|
|
228
|
-
|
|
226
|
+
exec("scaffold organization-product on standard", process.execPath, [
|
|
227
|
+
opts.cliPath,
|
|
228
|
+
site,
|
|
229
|
+
"--shape",
|
|
230
|
+
"organization-product",
|
|
231
|
+
"--design",
|
|
232
|
+
"standard",
|
|
233
|
+
...(opts.licenseKey === undefined ? [] : ["--license", opts.licenseKey]),
|
|
234
|
+
], registryEnv);
|
|
229
235
|
const before = compose("compose JSON-LD before apply-design");
|
|
230
236
|
const applyStdout = exec(`apply-design ${opts.design}`, process.execPath, [opts.cliPath, "apply-design", opts.design, "--target", site], opts.registryUrl === undefined ? {} : { AILK_MODULE_REGISTRY_URL: opts.registryUrl });
|
|
231
237
|
const after = compose("compose JSON-LD after apply-design");
|