create-ailk 0.23.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 +68 -33
- package/component-catalog.json +3 -3
- package/component-catalog.md +3 -3
- package/dist/add-module.js +10 -3
- package/dist/add-route.d.ts +12 -1
- package/dist/add-route.js +38 -4
- package/dist/cli.js +12 -7
- package/dist/derive-architecture.d.ts +3 -4
- package/dist/derive-architecture.js +75 -22
- 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/lib/scaffold-render-sweep.d.ts +33 -0
- package/dist/lib/scaffold-render-sweep.js +45 -0
- package/dist/module-architecture.d.ts +20 -3
- package/dist/module-architecture.js +122 -538
- package/dist/paid-sections.d.ts +25 -1
- package/dist/paid-sections.js +88 -3
- package/dist/surfaces.js +10 -2
- package/dist/sync-routes.d.ts +30 -4
- package/dist/sync-routes.js +271 -18
- 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 +9 -5
- package/templates/.github/workflows/ci.yml +7 -4
- package/templates/CLAUDE.md +15 -3
- package/templates/CONVENTIONS.md +8 -10
- package/templates/README.md +14 -13
- package/templates/apps/api/.env.example +9 -2
- package/templates/apps/api/CLAUDE.md +122 -82
- 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 +7 -4
- 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 -1857
- package/templates/apps/api/vercel.json +2 -2
- package/templates/apps/mcp/CLAUDE.md +77 -24
- 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 -12
- 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 +21 -5
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +9 -3
- package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +14 -4
- package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +1 -1
- package/templates/apps/web/app/[locale]/contact/intake-script.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 +28 -7
- 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/__tests__/magnet-routes.test.ts +7 -0
- package/templates/apps/web/lib/auth-email.ts +1 -1
- package/templates/apps/web/lib/magnet-routes.ts +3 -1
- package/templates/apps/web/lib/newsletter.actions.ts +9 -6
- 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 +32 -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 +757 -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 -292
- 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 -254
- 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 -318
- 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 -264
- 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 -1815
- 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 -325
- 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 -1300
- 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 -268
- package/templates/apps/api/src/routes/content/index.ts +0 -49
- package/templates/apps/api/src/routes/content/list-pages.ts +0 -95
- 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 -129
- package/templates/apps/api/src/routes/content/shown-offerings.ts +0 -229
- package/templates/apps/api/src/routes/content/slug.ts +0 -9
- 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 -573
- 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 -480
- package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +0 -465
- 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 -448
- 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 -808
- 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 -2026
- package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +0 -528
- 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 -867
- 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 -1176
- package/templates/apps/api/src/services/__tests__/plan-offerings.test.ts +0 -444
- package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +0 -154
- 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 -313
- 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 -755
- 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 -295
- 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 -868
- 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 -396
- package/templates/apps/api/src/services/offerings/__tests__/readers.test.ts +0 -681
- package/templates/apps/api/src/services/offerings/__tests__/source.test.ts +0 -231
- package/templates/apps/api/src/services/offerings/catalog.ts +0 -308
- package/templates/apps/api/src/services/offerings/checkout-authorization.ts +0 -385
- package/templates/apps/api/src/services/offerings/checkout-session-record.ts +0 -192
- package/templates/apps/api/src/services/offerings/connection.ts +0 -1003
- 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 -1188
- 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 -2073
- 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 -1151
- 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 -65
- package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +0 -187
- 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 -165
- package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +0 -124
- package/templates/apps/mcp/__tests__/list_pages.test.ts +0 -228
- package/templates/apps/mcp/__tests__/locale.test.ts +0 -135
- 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__/read_content.test.ts +0 -474
- package/templates/apps/mcp/__tests__/request_callback.test.ts +0 -225
- package/templates/apps/mcp/__tests__/search_content.test.ts +0 -256
- 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 -307
- package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +0 -223
- 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 -342
- 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 -526
- 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 -142
- package/templates/apps/mcp/src/lib/empty-content-adapter.ts +0 -139
- 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/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 -64
- 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 -137
- package/templates/apps/mcp/src/tools/list_pages.ts +0 -74
- 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 -75
- package/templates/apps/mcp/src/tools/request_callback.ts +0 -59
- package/templates/apps/mcp/src/tools/search_content.ts +0 -67
- package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +0 -57
- package/templates/apps/mcp/src/workspace-server.ts +0 -224
- package/templates/database/CHANGELOG.md +0 -961
- 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 -240
- package/templates/database/__tests__/spoke-registry.db.test.ts +0 -191
- package/templates/database/__tests__/tenancy.test.ts +0 -141
- 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/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
|
|
@@ -214,9 +221,9 @@ as-is, they never fail the check, and `--apply` never overwrites them.
|
|
|
214
221
|
|
|
215
222
|
`--apply` only creates route directories that are absent, through the same
|
|
216
223
|
copier a fresh scaffold uses (so the copied files are byte-identical to a fresh
|
|
217
|
-
scaffold's). It never rewrites or deletes an existing file,
|
|
218
|
-
outside `apps/web/app/[locale]
|
|
219
|
-
no-op. `--apply` exits 0 on success.
|
|
224
|
+
scaffold's). It never rewrites or deletes an existing file, writes nothing
|
|
225
|
+
outside `apps/web/app/[locale]/` except the local modules those routes import
|
|
226
|
+
(below), runs no install, and a second run is a no-op. `--apply` exits 0 on success.
|
|
220
227
|
|
|
221
228
|
**Scope.** Every core route (`about`, `contact`, `faq`, `thanks/[slug]`,
|
|
222
229
|
`sign-in`) is always checked, and so is the `(authed)` route GROUP —
|
|
@@ -232,17 +239,30 @@ gated off at scaffold time is listed as skipped, not missing — its absence is
|
|
|
232
239
|
deliberate, not drift. Add a surface with `--sync-architecture` and the
|
|
233
240
|
`add-page` skill, not with `sync-routes`.
|
|
234
241
|
|
|
235
|
-
**The
|
|
236
|
-
files OUTSIDE their own route directory — `
|
|
237
|
-
`apps/web/lib/
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
242
|
+
**The local-module dependency contract (#5014, #9406).** Some routes import
|
|
243
|
+
files OUTSIDE their own route directory — `purchase/success/page.tsx` imports
|
|
244
|
+
`apps/web/src/lib/commerce-claim.ts`; the `(authed)` group's `layout.tsx`
|
|
245
|
+
imports `apps/web/auth.ts`. Copying a route's directory alone would leave those
|
|
246
|
+
imports dangling in an older consumer that never had them. So `sync-routes`
|
|
247
|
+
resolves every relative import (`./`, `../`) of every file the route would
|
|
248
|
+
copy, and of every helper that brings in turn, against the site first and then
|
|
249
|
+
the template. `ROUTE_DEPENDENCIES` in `src/surfaces.ts` is a declared
|
|
250
|
+
supplement, unioned with what the resolver finds. Each imported module has one
|
|
251
|
+
of three outcomes:
|
|
252
|
+
|
|
253
|
+
- **Copied** — the site lacks it and the template has it: `--apply` copies it
|
|
254
|
+
(never overwriting) and check mode lists it under `copies:` and `Also
|
|
255
|
+
required`.
|
|
256
|
+
- **Left as-is** — the site has it and its copy differs from the template's:
|
|
257
|
+
it is named under `left as-is (differs from the template)` and never
|
|
258
|
+
written. The route is still copied; run your type-check afterwards.
|
|
259
|
+
- **Refused** — the import resolves to no file in the site or the template,
|
|
260
|
+
only to a spoke-excluded file, or to a surface the site does not carry: the
|
|
261
|
+
route is listed under `cannot resolve:` and `--apply` does not write it, nor
|
|
262
|
+
its sub-routes, nor a route that imports from it. Its ancestor route is still
|
|
263
|
+
copied without the refused sub-tree.
|
|
264
|
+
|
|
265
|
+
`ROUTE_MESSAGE_NAMESPACES`
|
|
246
266
|
does the same for the i18n namespaces a route's copy needs
|
|
247
267
|
(`signIn`, `account`, `waitlistDashboard.gate`) — but CHECK-ONLY: a
|
|
248
268
|
consumer's `apps/web/messages/<locale>.json` already exists and may carry
|
|
@@ -483,6 +503,17 @@ from the module distribution's own 401/403 (`src/lib/fetch-module.ts`). The
|
|
|
483
503
|
gate runs before anything is copied (`scaffold()` in `src/programmatic.ts`), so
|
|
484
504
|
a refused run leaves no partial scaffold behind.
|
|
485
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
|
+
|
|
486
517
|
`AILK_MODULE_REGISTRY_URL` is optional: `fetchModule` uses an explicitly passed
|
|
487
518
|
`registryUrl`, then that variable, then `https://api.ailaunchkit.ai/v1/modules`
|
|
488
519
|
(`DEFAULT_AILK_MODULE_REGISTRY_URL`, `src/lib/fetch-module.ts`).
|
|
@@ -493,7 +524,10 @@ explicitly passed `registryUrl`, then that variable, then
|
|
|
493
524
|
either registry fails the fetch before any second request is sent.
|
|
494
525
|
|
|
495
526
|
```bash
|
|
496
|
-
#
|
|
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)
|
|
497
531
|
pnpm create ailk@latest my-site --shape organization-product --modules marketing
|
|
498
532
|
|
|
499
533
|
# paid — the key is read from the environment
|
|
@@ -502,9 +536,10 @@ AILK_LICENSE_KEY=... pnpm create ailk@latest my-site --shape organization-produc
|
|
|
502
536
|
|
|
503
537
|
The network invariant (#6759 D6), in full:
|
|
504
538
|
|
|
505
|
-
- **No key** → no request at all. A request that names no paid module
|
|
506
|
-
|
|
507
|
-
|
|
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.
|
|
508
543
|
- **A key with no `--modules`** → the level probe (`deriveLevel`): 3-4
|
|
509
544
|
requests, to find out what the key unlocks.
|
|
510
545
|
- **An explicit `--modules` list** → requests only for the paid modules it
|
|
@@ -513,7 +548,7 @@ The network invariant (#6759 D6), in full:
|
|
|
513
548
|
## What it does
|
|
514
549
|
|
|
515
550
|
1. Validates the target directory does not exist OR is empty.
|
|
516
|
-
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.
|
|
517
552
|
3. Substitutes `workspace:*` references in every `package.json` with the matching `@working-theory/*` semver from npm — versions are pinned at npm-publish time.
|
|
518
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).
|
|
519
554
|
5. Derives and writes `architecture.yaml` (the site's code-boundary config) from the selected module set — see below.
|
|
@@ -544,10 +579,10 @@ declares a slice for every recognized module.
|
|
|
544
579
|
## Templates are snapshotted at build time
|
|
545
580
|
|
|
546
581
|
The `prepublishOnly` script (`scripts/build-templates.mjs`) reads the canonical
|
|
547
|
-
sources from this monorepo (`apps/`, `database
|
|
548
|
-
populates `templates/`. The npm tarball ships the populated templates via the
|
|
549
|
-
`files` field.
|
|
550
|
-
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
|
|
551
586
|
registry. A run naming a paid module fetches that module's bundle — see
|
|
552
587
|
[Paid modules require `AILK_LICENSE_KEY`](#paid-modules-require-ailk_license_key).
|
|
553
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
|
});
|
|
@@ -351,7 +353,9 @@ export function formatAddModuleReport(result, moduleName) {
|
|
|
351
353
|
const lines = [
|
|
352
354
|
`[create-ailk] add-module ${moduleName} → ${result.targetDir}`,
|
|
353
355
|
];
|
|
354
|
-
if (result.report.length === 0 &&
|
|
356
|
+
if (result.report.length === 0 &&
|
|
357
|
+
result.routes.applied.length === 0 &&
|
|
358
|
+
result.routes.refused.length === 0) {
|
|
355
359
|
lines.push(`Nothing to add — the site already carries everything ${moduleName} brings.`);
|
|
356
360
|
}
|
|
357
361
|
if (written.length > 0) {
|
|
@@ -387,6 +391,9 @@ export function formatAddModuleReport(result, moduleName) {
|
|
|
387
391
|
lines.push(`Also copied ${routes.appliedDependencies.length} file(s) those routes import:`);
|
|
388
392
|
lines.push(...routes.appliedDependencies.map((dep) => ` ${dep}`));
|
|
389
393
|
}
|
|
394
|
+
if (routes.refused.length > 0) {
|
|
395
|
+
lines.push(`Routes not copied (${routes.refused.length}) — an import does not resolve (run create-ailk sync-routes for the paths): ${routes.refused.join(", ")}`);
|
|
396
|
+
}
|
|
390
397
|
if (routes.missingMessageNamespaces.length > 0) {
|
|
391
398
|
lines.push("Also required — message namespace(s) not found in apps/web/messages/en.json (add manually, not auto-merged):");
|
|
392
399
|
lines.push(...routes.missingMessageNamespaces.map((ns) => ` ${ns}`));
|
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
|
@@ -226,13 +226,16 @@ export function formatAddRouteReport(result) {
|
|
|
226
226
|
const skipped = result.report.filter((row) => row.action === "skipped");
|
|
227
227
|
const routes = result.routes ?? {
|
|
228
228
|
applied: [],
|
|
229
|
+
refused: [],
|
|
229
230
|
appliedDependencies: [],
|
|
230
231
|
missingMessageNamespaces: [],
|
|
231
232
|
};
|
|
232
233
|
const lines = [
|
|
233
234
|
`[create-ailk] add-route ${result.route} → ${result.targetDir}`,
|
|
234
235
|
];
|
|
235
|
-
if (result.report.length === 0 &&
|
|
236
|
+
if (result.report.length === 0 &&
|
|
237
|
+
routes.applied.length === 0 &&
|
|
238
|
+
routes.refused.length === 0) {
|
|
236
239
|
lines.push(`Nothing to add — the site already carries the ${result.route} route.`);
|
|
237
240
|
}
|
|
238
241
|
if (routes.applied.length > 0) {
|
|
@@ -243,6 +246,9 @@ export function formatAddRouteReport(result) {
|
|
|
243
246
|
lines.push(`Also copied ${routes.appliedDependencies.length} file(s) those routes import:`);
|
|
244
247
|
lines.push(...routes.appliedDependencies.map((dep) => ` ${dep}`));
|
|
245
248
|
}
|
|
249
|
+
if (routes.refused.length > 0) {
|
|
250
|
+
lines.push(`Routes not copied (${routes.refused.length}) — an import does not resolve (run create-ailk sync-routes for the paths): ${routes.refused.join(", ")}`);
|
|
251
|
+
}
|
|
246
252
|
if (written.length > 0) {
|
|
247
253
|
lines.push(`Written (${written.length}):`);
|
|
248
254
|
lines.push(...written.map((row) => ` ${row.path}`));
|
|
@@ -308,6 +314,11 @@ const RESERVED_FIRST_SEGMENTS = new Set([
|
|
|
308
314
|
const LOCALE_SHAPED_RE = /^[a-z]{2}(-[a-z]{2})?$/;
|
|
309
315
|
/** Template-relative root every page directory sits under. */
|
|
310
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";
|
|
311
322
|
/** Whether `slug` passes `flowSlugSchema`'s rule. */
|
|
312
323
|
export function isMagnetFlowSlug(slug) {
|
|
313
324
|
return slug.length <= FLOW_SLUG_MAX && FLOW_SLUG_RE.test(slug);
|
|
@@ -322,6 +333,12 @@ export function isMagnetFlowSlug(slug) {
|
|
|
322
333
|
* that already exists is never overwritten: a second run reports both
|
|
323
334
|
* `skipped`. No `architecture.yaml`, nav or seed changes — the pair is the
|
|
324
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).
|
|
325
342
|
*/
|
|
326
343
|
export function addMagnetToScaffold(opts) {
|
|
327
344
|
const targetAbs = resolve(opts.targetDir);
|
|
@@ -376,7 +393,23 @@ export function addMagnetToScaffold(opts) {
|
|
|
376
393
|
writeFileSync(dest, text);
|
|
377
394
|
report.push({ path, action: "written" });
|
|
378
395
|
}
|
|
379
|
-
|
|
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
|
+
};
|
|
380
413
|
}
|
|
381
414
|
/** `--path`'s segments, refusing a path a pair may not take (SEC-8840-J). */
|
|
382
415
|
function magnetPathSegments(path) {
|
|
@@ -501,7 +534,7 @@ export function formatAddMagnetReport(result) {
|
|
|
501
534
|
lines.push(...skipped.map((row) => ` ${row.path}`));
|
|
502
535
|
}
|
|
503
536
|
if (written.length > 0) {
|
|
504
|
-
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);
|
|
505
538
|
}
|
|
506
539
|
return lines.join("\n") + "\n";
|
|
507
540
|
}
|
|
@@ -542,7 +575,8 @@ serves, a one-segment path a LandingPage seed of the same slug owns, a path
|
|
|
542
575
|
ending in start or apply, a reserved first segment (api, v1, flows, account,
|
|
543
576
|
admin, the sign-in routes, a locale) and a slug the flow API would refuse. A
|
|
544
577
|
page that exists is never overwritten: running it again skips both. It changes
|
|
545
|
-
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.
|
|
546
580
|
`;
|
|
547
581
|
/**
|
|
548
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).
|