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
|
@@ -14,7 +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";
|
|
23
|
+
/** The npm scope a site consumes and never forks (#9191). */
|
|
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
|
+
};
|
|
18
30
|
/** A spoke's composition tiers (#7426 D8): its data and API are the hub's. */
|
|
19
31
|
const SPOKE_TIERS = {
|
|
20
32
|
data: "none — the hub's database",
|
|
@@ -207,18 +219,6 @@ function appToYaml(app) {
|
|
|
207
219
|
}
|
|
208
220
|
return m;
|
|
209
221
|
}
|
|
210
|
-
function namespacesToYaml(ns) {
|
|
211
|
-
const members = {};
|
|
212
|
-
const sortedMembers = Object.entries(ns.members).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
213
|
-
for (const [key, mem] of sortedMembers) {
|
|
214
|
-
members[key] = { path: mem.path, description: mem.description };
|
|
215
|
-
}
|
|
216
|
-
return {
|
|
217
|
-
description: ns.description,
|
|
218
|
-
members,
|
|
219
|
-
rules: [...ns.rules],
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
222
|
/**
|
|
223
223
|
* Derive the `architecture.yaml` document for a module set.
|
|
224
224
|
*
|
|
@@ -229,9 +229,8 @@ function namespacesToYaml(ns) {
|
|
|
229
229
|
* modules gets exactly what the modules imply.
|
|
230
230
|
* @param options the topology (#7426 D8). Absent or `"hub"` ⟹ the output is
|
|
231
231
|
* byte-identical to the two-argument form. `"spoke"` ⟹ only the spoke's own
|
|
232
|
-
* apps (`web`, and `mcp` unless `mcp: false`), no `
|
|
233
|
-
*
|
|
234
|
-
* 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.
|
|
235
234
|
* @returns the complete `architecture.yaml` file content (a deterministic
|
|
236
235
|
* function of the module SET, the surface SET and the topology).
|
|
237
236
|
* @throws Error on an unrecognized module (defensive; parse-args rejects first).
|
|
@@ -304,16 +303,69 @@ export function deriveArchitecture(modules = ["marketing"], surfaces, options =
|
|
|
304
303
|
forbidden_patterns: mergeForbidden([...ARCHITECTURE_BASE.appForbiddenPatterns], [...(a.forbidden_patterns ?? []), ...extra]).map(scoped),
|
|
305
304
|
});
|
|
306
305
|
}
|
|
307
|
-
// namespaces
|
|
308
|
-
//
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
: 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.
|
|
312
310
|
// forbidden_patterns — base floor first, then the selected modules' patterns.
|
|
313
311
|
const extraForbidden = [];
|
|
314
312
|
for (const s of slices)
|
|
315
313
|
extraForbidden.push(...(s.forbiddenPatterns ?? []));
|
|
316
314
|
const forbidden = mergeForbidden([...ARCHITECTURE_BASE.forbiddenPatterns], extraForbidden).map(scoped);
|
|
315
|
+
// The upgradeable-consumer rules (#9191): the workspaces this scaffold
|
|
316
|
+
// creates and the in-scope package names it gives them. The site lint
|
|
317
|
+
// reads this block to refuse a forked, patched or pinned-off package.
|
|
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.
|
|
320
|
+
const upgradeableConsumer = {
|
|
321
|
+
package_scope: PACKAGE_SCOPE,
|
|
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}`)
|
|
330
|
+
.sort(),
|
|
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
|
+
};
|
|
317
369
|
const doc = {
|
|
318
370
|
version: ARCHITECTURE_BASE.version,
|
|
319
371
|
...(spoke ? { topology: "spoke" } : {}),
|
|
@@ -328,8 +380,9 @@ export function deriveArchitecture(modules = ["marketing"], surfaces, options =
|
|
|
328
380
|
available: [...RECOGNIZED_SURFACES],
|
|
329
381
|
},
|
|
330
382
|
apps,
|
|
331
|
-
...(nsSlice ? { namespaces: namespacesToYaml(nsSlice) } : {}),
|
|
332
383
|
forbidden_patterns: forbidden.map(forbiddenToYaml),
|
|
384
|
+
upgradeable_consumer: upgradeableConsumer,
|
|
385
|
+
customizations,
|
|
333
386
|
};
|
|
334
387
|
const header = [
|
|
335
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");
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
* `extractBundle` extracts into an EMPTY staging dir that then swap-renames
|
|
24
24
|
* over the (possibly pre-existing) install target — appropriate for a single
|
|
25
25
|
* self-contained skill directory. A fetched module's files are scattered
|
|
26
|
-
* across an ALREADY-SCAFFOLDED tree (`apps/
|
|
27
|
-
* `apps/web/
|
|
26
|
+
* across an ALREADY-SCAFFOLDED tree (`apps/web/app/...`,
|
|
27
|
+
* `apps/web/lib/...`), so there is no single directory to rename over.
|
|
28
28
|
* `extractModuleBundle` therefore extracts into a throwaway temp dir first
|
|
29
29
|
* (same validation, same guards), and ONLY on full success copies each
|
|
30
30
|
* validated file into its place under `targetDir` — so a rejected or
|
|
@@ -386,6 +386,26 @@ function validateLayerOwnership(destinations, ownership, subject, isTemplate, pa
|
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
388
|
/** Every regular file under `srcRoot`, as a `/`-separated relative path. */
|
|
389
|
+
const API_SOURCE_ROOT = "apps/api/";
|
|
390
|
+
/**
|
|
391
|
+
* #9565 D6 — refuse a tree that would write under `apps/api/`, naming the
|
|
392
|
+
* path. Checked BEFORE any write, beside `validateInstallMap` and
|
|
393
|
+
* `validatePatches`.
|
|
394
|
+
*/
|
|
395
|
+
function refuseApiSource(sourceRoot, installMap, patches, subject) {
|
|
396
|
+
const toPosixRel = (p) => normalize(p).split(sep).join("/").replace(/^\.\//, "");
|
|
397
|
+
// Compared lower-cased: on a case-insensitive filesystem `Apps/API/...` lands
|
|
398
|
+
// in the same tree.
|
|
399
|
+
const underApi = (rel) => rel.toLowerCase().startsWith(API_SOURCE_ROOT);
|
|
400
|
+
const offenders = [
|
|
401
|
+
...stagedFiles(sourceRoot).filter(underApi),
|
|
402
|
+
...Object.values(installMap).map(toPosixRel).filter(underApi),
|
|
403
|
+
...patches.map((patch) => toPosixRel(patch.target)).filter(underApi),
|
|
404
|
+
];
|
|
405
|
+
if (offenders.length > 0) {
|
|
406
|
+
throw new Error(`${subject}: refuses to write ${offenders[0]} — API source ships in its @working-theory/api-<module> package, never in a bundle (#9565)`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
389
409
|
function stagedFiles(srcRoot) {
|
|
390
410
|
const out = [];
|
|
391
411
|
const stack = [srcRoot];
|
|
@@ -545,6 +565,13 @@ export function installBundleTree(options) {
|
|
|
545
565
|
// Every declared patch is validated, skipped or not (#7426 D4), exactly as
|
|
546
566
|
// the installMap is above; only then are the skipped ones dropped.
|
|
547
567
|
validatePatches(declaredPatches, targetAbs, subject);
|
|
568
|
+
// #9565 D6 — no bundle writes under apps/api/: a module's API source is its
|
|
569
|
+
// `@working-theory/api-<module>` package, installed from npm, never a copy
|
|
570
|
+
// in the site's tree. A staged file, a (remapped) installMap destination or
|
|
571
|
+
// a patch target under apps/api/ refuses the whole tree at this same
|
|
572
|
+
// fail-closed point, for module and template trees alike — which is what
|
|
573
|
+
// holds for a bundle built before this change and still at the store.
|
|
574
|
+
refuseApiSource(sourceRoot, remappedInstallMap, declaredPatches, subject);
|
|
548
575
|
const patches = declaredPatches.filter((patch) => !isSkipped(patch.target));
|
|
549
576
|
options.checkPatches?.(patches);
|
|
550
577
|
// The exclusion set copyTree/the content-only guard both use — built from
|
|
@@ -12,7 +12,7 @@ export interface FetchTemplateSnapshotOptions {
|
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Fetch and re-materialise create-ailk `version`'s `templates/apps/{web,api,mcp}/`
|
|
15
|
-
* tree from its published npm tarball.
|
|
15
|
+
* tree, plus its `templates/database/` boot files, from its published npm tarball.
|
|
16
16
|
*
|
|
17
17
|
* @throws FetchTemplateSnapshotError on an invalid version, an unreachable
|
|
18
18
|
* or malformed registry response, an integrity mismatch, or a symlink /
|
|
@@ -21,6 +21,7 @@ import { createHash } from "node:crypto";
|
|
|
21
21
|
import { gunzipSync } from "node:zlib";
|
|
22
22
|
import * as tar from "tar";
|
|
23
23
|
import { templateDestination } from "../copy.js";
|
|
24
|
+
import { DATABASE_BOOT_FILES } from "../template-record.js";
|
|
24
25
|
import { MAX_TOTAL_SIZE_BYTES } from "./extract-module-bundle.js";
|
|
25
26
|
import { assertContentLengthWithinLimit, assertHttpsRegistryUrl, fetchTimeoutSignal, } from "./fetch-guard.js";
|
|
26
27
|
export const DEFAULT_AILK_NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
@@ -29,6 +30,8 @@ const VERSION_PATTERN = /^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/;
|
|
|
29
30
|
/** The one tar path prefix a snapshot is read from, and the three app roots inside it. */
|
|
30
31
|
const TAR_ROOT = "package/templates/";
|
|
31
32
|
const APP_PREFIXES = ["apps/web/", "apps/api/", "apps/mcp/"];
|
|
33
|
+
/** The paths outside the app roots a snapshot keeps: a hub's three database boot files (#9569 DD8). */
|
|
34
|
+
const BOOT_FILES = new Set(DATABASE_BOOT_FILES);
|
|
32
35
|
export class FetchTemplateSnapshotError extends Error {
|
|
33
36
|
constructor(message) {
|
|
34
37
|
super(message);
|
|
@@ -110,13 +113,14 @@ async function fetchTarball(tarballUrl, integrity, version, fetchImpl) {
|
|
|
110
113
|
}
|
|
111
114
|
return buf;
|
|
112
115
|
}
|
|
113
|
-
/** The
|
|
116
|
+
/** The template-relative path (no `package/templates/` prefix) for a tar entry path, or undefined outside the three app trees and the database boot files. */
|
|
114
117
|
function appRelativePath(tarPath) {
|
|
115
118
|
if (!tarPath.startsWith(TAR_ROOT))
|
|
116
119
|
return undefined;
|
|
117
120
|
const rel = tarPath.slice(TAR_ROOT.length);
|
|
118
|
-
if (!APP_PREFIXES.some((prefix) => rel.startsWith(prefix)))
|
|
121
|
+
if (!APP_PREFIXES.some((prefix) => rel.startsWith(prefix)) && !BOOT_FILES.has(rel)) {
|
|
119
122
|
return undefined;
|
|
123
|
+
}
|
|
120
124
|
if (rel.length === 0)
|
|
121
125
|
return undefined;
|
|
122
126
|
const segments = rel.split("/");
|
|
@@ -176,7 +180,7 @@ function parseSnapshot(gunzipped, version) {
|
|
|
176
180
|
}
|
|
177
181
|
/**
|
|
178
182
|
* Fetch and re-materialise create-ailk `version`'s `templates/apps/{web,api,mcp}/`
|
|
179
|
-
* tree from its published npm tarball.
|
|
183
|
+
* tree, plus its `templates/database/` boot files, from its published npm tarball.
|
|
180
184
|
*
|
|
181
185
|
* @throws FetchTemplateSnapshotError on an invalid version, an unreachable
|
|
182
186
|
* or malformed registry response, an integrity mismatch, or a symlink /
|
|
@@ -16,7 +16,7 @@ export declare function resolveRelativeImport(fromFile: string, spec: string, ca
|
|
|
16
16
|
* This is the shape both consumers need, and the reason the walk is shared
|
|
17
17
|
* rather than copied. `paidModuleTemplateExclusions()` seeds it with every
|
|
18
18
|
* paid module's `ownedFiles` to get the files a keyless starter must not
|
|
19
|
-
* carry;
|
|
19
|
+
* carry; the retired slice-registration lint seeded it with the same set to
|
|
20
20
|
* derive, by subtraction, the files a scaffold ships UNCONDITIONALLY.
|
|
21
21
|
*
|
|
22
22
|
* Never a filename-stem rule (#5182 D7), which misses eleven files and
|
package/dist/lib/import-graph.js
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* - `paidModuleTemplateExclusions()` (module-architecture.ts) walks it to take
|
|
9
9
|
* the companion closure of every paid module's `ownedFiles` — the files that
|
|
10
10
|
* would ship dangling into a keyless starter.
|
|
11
|
-
* -
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* - the slice-registration lint walked it (#5701, retired by #9565 D8 once
|
|
12
|
+
* no bundle delivered an API file) to close over the specifiers a module
|
|
13
|
+
* gate loaded and check each against what the slice delivered.
|
|
14
14
|
*
|
|
15
15
|
* Both questions are "which files does this one reach through relative
|
|
16
16
|
* imports", and the answer must be the same function in both mouths: a lint
|
|
@@ -105,7 +105,7 @@ function posixJoin(dir, spec) {
|
|
|
105
105
|
* This is the shape both consumers need, and the reason the walk is shared
|
|
106
106
|
* rather than copied. `paidModuleTemplateExclusions()` seeds it with every
|
|
107
107
|
* paid module's `ownedFiles` to get the files a keyless starter must not
|
|
108
|
-
* carry;
|
|
108
|
+
* carry; the retired slice-registration lint seeded it with the same set to
|
|
109
109
|
* derive, by subtraction, the files a scaffold ships UNCONDITIONALLY.
|
|
110
110
|
*
|
|
111
111
|
* Never a filename-stem rule (#5182 D7), which misses eleven files and
|
|
@@ -17,7 +17,7 @@ export declare class LicenseRequiredError extends Error {
|
|
|
17
17
|
}
|
|
18
18
|
/** The five axes `release-scope.json` declares (spec 6977 D3). */
|
|
19
19
|
export type ReleaseAxis = "templates" | "shapes" | "designs" | "modules" | "levels";
|
|
20
|
-
/** `gated` and `deferred` are both refused; only a `gated` one gets negative checks. */
|
|
20
|
+
/** `gated` and `deferred` are both refused; only a `gated` one gets negative checks (the Free level excepted, #6484). */
|
|
21
21
|
export type ReleaseStatus = "released" | "gated" | "deferred";
|
|
22
22
|
export type ReleaseScope = Readonly<Record<ReleaseAxis, Readonly<Record<string, ReleaseStatus>>>>;
|
|
23
23
|
/**
|
|
@@ -44,6 +44,17 @@ export declare class ReleaseScopeError extends Error {
|
|
|
44
44
|
* gated module.
|
|
45
45
|
*/
|
|
46
46
|
export declare function assertReleased(axis: ReleaseAxis, names: readonly (string | undefined)[], scope?: ReleaseScope): void;
|
|
47
|
+
/**
|
|
48
|
+
* A run with no key is a Free run, and `release-scope.json` says whether Free
|
|
49
|
+
* is available (#6484, REL-034.1: deferred — held). Refused before any prompt,
|
|
50
|
+
* fetch or write, with the level gate's message naming the pricing page; zero
|
|
51
|
+
* network. A keyed run passes through untouched — its level is the registry's
|
|
52
|
+
* answer (`deriveLevel`), never decided here. Called by `cli.ts` ahead of the
|
|
53
|
+
* shape prompt, and by `resolvePaidModules` for an all-Free request — the
|
|
54
|
+
* seam every `scaffold()` branch crosses (alias, keep and default alike),
|
|
55
|
+
* after the scope-name refusals and before the first write.
|
|
56
|
+
*/
|
|
57
|
+
export declare function assertKeyedOrFreeReleased(licenseKey?: string | undefined): void;
|
|
47
58
|
/**
|
|
48
59
|
* Design names every level renders (#6760 D1). Anything else in
|
|
49
60
|
* `STARTER_DESIGNS` is Pro and up. A path design's Free-ness is decided by
|
|
@@ -12,10 +12,11 @@
|
|
|
12
12
|
* (c) a valid key → every requested paid module's bundle bytes, ready for
|
|
13
13
|
* `extract-module-bundle.ts` to merge into the scaffold.
|
|
14
14
|
*
|
|
15
|
-
* A Free-only request (no paid modules) never reaches the
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* A Free-only request (no paid modules) never reaches the network — but since
|
|
16
|
+
* #6484 (REL-034.1) it does read the key: no key is the Free level, which
|
|
17
|
+
* `release-scope.json` defers, so `resolvePaidModules` refuses it through
|
|
18
|
+
* `assertKeyedOrFreeReleased` before returning its empty map. A keyed
|
|
19
|
+
* all-Free scaffold is unaffected (K1's regression floor, keyed).
|
|
19
20
|
*
|
|
20
21
|
* Also carries the design gate (#6760): `assertDesignAllowed` refuses a
|
|
21
22
|
* non-`standard` design at the `free` level, naming the design and the
|
|
@@ -107,14 +108,32 @@ export function assertReleased(axis, names, scope = RELEASE_SCOPE) {
|
|
|
107
108
|
continue;
|
|
108
109
|
const released = Object.keys(statuses).filter((n) => statuses[n] === "released");
|
|
109
110
|
// A level comes from the key, never a flag — so it points at what the run CAN choose.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
// `free` is the keyless level (#6484): it points at the pricing page.
|
|
112
|
+
const choose = axis === "levels" && name === "free"
|
|
113
|
+
? `No licence key, so this would be a Free scaffold — pass --license <key> or set AILK_LICENSE_KEY with a Pro key → ${CONVERSION_HINT_URL}`
|
|
114
|
+
: axis === "levels"
|
|
115
|
+
? `Your licence key's level is ${name}; name the modules you want with --modules (one of: ${Object.keys(scope.modules)
|
|
116
|
+
.filter((m) => scope.modules[m] === "released")
|
|
117
|
+
.join(", ")}).`
|
|
118
|
+
: `Choose one of: ${released.join(", ")}.`;
|
|
115
119
|
throw new ReleaseScopeError(`${AXIS_NOUN[axis]} "${name}" is not available yet. ${choose}`);
|
|
116
120
|
}
|
|
117
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* A run with no key is a Free run, and `release-scope.json` says whether Free
|
|
124
|
+
* is available (#6484, REL-034.1: deferred — held). Refused before any prompt,
|
|
125
|
+
* fetch or write, with the level gate's message naming the pricing page; zero
|
|
126
|
+
* network. A keyed run passes through untouched — its level is the registry's
|
|
127
|
+
* answer (`deriveLevel`), never decided here. Called by `cli.ts` ahead of the
|
|
128
|
+
* shape prompt, and by `resolvePaidModules` for an all-Free request — the
|
|
129
|
+
* seam every `scaffold()` branch crosses (alias, keep and default alike),
|
|
130
|
+
* after the scope-name refusals and before the first write.
|
|
131
|
+
*/
|
|
132
|
+
export function assertKeyedOrFreeReleased(licenseKey = process.env["AILK_LICENSE_KEY"]) {
|
|
133
|
+
if (licenseKey === undefined || licenseKey.length === 0) {
|
|
134
|
+
assertReleased("levels", ["free"]);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
118
137
|
/**
|
|
119
138
|
* Design names every level renders (#6760 D1). Anything else in
|
|
120
139
|
* `STARTER_DESIGNS` is Pro and up. A path design's Free-ness is decided by
|
|
@@ -182,12 +201,15 @@ function licenseErrorMessage(err, moduleName, templateName, level) {
|
|
|
182
201
|
*/
|
|
183
202
|
export async function resolvePaidModules(options) {
|
|
184
203
|
const { paidModules } = options;
|
|
204
|
+
const token = options.licenseKey ?? process.env["AILK_LICENSE_KEY"];
|
|
185
205
|
if (paidModules.length === 0) {
|
|
186
|
-
//
|
|
187
|
-
//
|
|
206
|
+
// Zero network for any request that names no paid module — but no
|
|
207
|
+
// longer zero key reads (#6484): a keyless all-Free request is the Free
|
|
208
|
+
// level, which `release-scope.json` holds, and is refused here, after
|
|
209
|
+
// `scaffold()`'s scope-name refusals and before its first write.
|
|
210
|
+
assertKeyedOrFreeReleased(token);
|
|
188
211
|
return new Map();
|
|
189
212
|
}
|
|
190
|
-
const token = options.licenseKey ?? process.env["AILK_LICENSE_KEY"];
|
|
191
213
|
if (token === undefined || token.length === 0) {
|
|
192
214
|
throw new LicenseRequiredError(noKeyMessage(paidModules, options.templateName));
|
|
193
215
|
}
|
|
@@ -21,6 +21,39 @@ export declare const MAX_REDIRECTS = 5;
|
|
|
21
21
|
* so each entry must answer exactly 404. A 200 means the gate stopped gating.
|
|
22
22
|
*/
|
|
23
23
|
export declare const CLAIM_GATED_ROUTES: Readonly<Record<string, string>>;
|
|
24
|
+
/**
|
|
25
|
+
* Routes whose answer depends on whether the site has a hub to ask (#9423),
|
|
26
|
+
* and the flow each one sells. With no API origin configured the flow read
|
|
27
|
+
* is `not-configured` and the route must answer exactly 404 — the no-hub
|
|
28
|
+
* 404 where the module that owns it is installed, Next's own 404 where it
|
|
29
|
+
* is not. With one configured it must render its own content.
|
|
30
|
+
*/
|
|
31
|
+
export declare const HUB_GATED_ROUTES: Readonly<Record<string, string>>;
|
|
32
|
+
/**
|
|
33
|
+
* The API origin names `apps/web` reads, in step with `apiOriginConfigured()`
|
|
34
|
+
* in `apps/web/app/[locale]/flows/[slug]/magnet-page.tsx`.
|
|
35
|
+
*/
|
|
36
|
+
export declare const HUB_ORIGIN_ENV_NAMES: readonly ["AILK_API_URL", "NEXT_PUBLIC_AILK_API_URL", "NEXT_PUBLIC_API_URL"];
|
|
37
|
+
/**
|
|
38
|
+
* Whether a served `apps/web` has an API origin: a non-empty value for one
|
|
39
|
+
* of `HUB_ORIGIN_ENV_NAMES` in the serve environment or assigned in one of
|
|
40
|
+
* the env files Next loads (`envFileTexts`).
|
|
41
|
+
*/
|
|
42
|
+
export declare function hubOriginConfigured(env: Readonly<Record<string, string | undefined>>, envFileTexts: string[]): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* A `HUB_GATED_ROUTES` entry. Hub configured: the page must render its own
|
|
45
|
+
* content (`assessPageRender`). No hub: exactly 404 with no redirect — a 200
|
|
46
|
+
* means the no-hub branch stopped running.
|
|
47
|
+
*/
|
|
48
|
+
export declare function assessHubGatedRoute(input: {
|
|
49
|
+
route: string;
|
|
50
|
+
hubConfigured: boolean;
|
|
51
|
+
hops: RedirectHop[];
|
|
52
|
+
status: number | null;
|
|
53
|
+
contentType: string | null;
|
|
54
|
+
html: string;
|
|
55
|
+
locale: string;
|
|
56
|
+
}): SweepVerdict;
|
|
24
57
|
/**
|
|
25
58
|
* A route whose live page needs an env var the driver never sets (#6146).
|
|
26
59
|
* While it is unset the route serves its Free placeholder seed instead
|
|
@@ -37,6 +37,51 @@ export const CLAIM_GATED_ROUTES = {
|
|
|
37
37
|
"/purchase/success": "commerce",
|
|
38
38
|
"/purchase/cancel": "commerce",
|
|
39
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Routes whose answer depends on whether the site has a hub to ask (#9423),
|
|
42
|
+
* and the flow each one sells. With no API origin configured the flow read
|
|
43
|
+
* is `not-configured` and the route must answer exactly 404 — the no-hub
|
|
44
|
+
* 404 where the module that owns it is installed, Next's own 404 where it
|
|
45
|
+
* is not. With one configured it must render its own content.
|
|
46
|
+
*/
|
|
47
|
+
export const HUB_GATED_ROUTES = {
|
|
48
|
+
"/trial": "trial",
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* The API origin names `apps/web` reads, in step with `apiOriginConfigured()`
|
|
52
|
+
* in `apps/web/app/[locale]/flows/[slug]/magnet-page.tsx`.
|
|
53
|
+
*/
|
|
54
|
+
export const HUB_ORIGIN_ENV_NAMES = ["AILK_API_URL", "NEXT_PUBLIC_AILK_API_URL", "NEXT_PUBLIC_API_URL"];
|
|
55
|
+
/**
|
|
56
|
+
* Whether a served `apps/web` has an API origin: a non-empty value for one
|
|
57
|
+
* of `HUB_ORIGIN_ENV_NAMES` in the serve environment or assigned in one of
|
|
58
|
+
* the env files Next loads (`envFileTexts`).
|
|
59
|
+
*/
|
|
60
|
+
export function hubOriginConfigured(env, envFileTexts) {
|
|
61
|
+
if (HUB_ORIGIN_ENV_NAMES.some((name) => Boolean(env[name])))
|
|
62
|
+
return true;
|
|
63
|
+
return envFileTexts.some((text) => HUB_ORIGIN_ENV_NAMES.some((name) => new RegExp(`^\\s*(?:export\\s+)?${name}\\s*=\\s*["']?[^\\s"'#]`, "m").test(text)));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A `HUB_GATED_ROUTES` entry. Hub configured: the page must render its own
|
|
67
|
+
* content (`assessPageRender`). No hub: exactly 404 with no redirect — a 200
|
|
68
|
+
* means the no-hub branch stopped running.
|
|
69
|
+
*/
|
|
70
|
+
export function assessHubGatedRoute(input) {
|
|
71
|
+
const { route, hubConfigured, hops, status, contentType, html, locale } = input;
|
|
72
|
+
const flow = HUB_GATED_ROUTES[route];
|
|
73
|
+
if (hubConfigured) {
|
|
74
|
+
const rendered = assessPageRender({ route, hops, status, contentType, html, locale });
|
|
75
|
+
return { ok: rendered.ok, reason: `${rendered.reason} (hub-gated: ${flow}, hub configured)` };
|
|
76
|
+
}
|
|
77
|
+
if (hops.length > 0 || status !== 404) {
|
|
78
|
+
const first = hops[0];
|
|
79
|
+
const seen = first ? `${first.status} redirect` : `status ${status}`;
|
|
80
|
+
const why = status === 200 ? "rendered with no hub to ask" : `expected 404, got ${seen}`;
|
|
81
|
+
return { ok: false, reason: `${route} -> ${why} (hub-gated: ${flow}, no hub)` };
|
|
82
|
+
}
|
|
83
|
+
return { ok: true, reason: `404 (hub-gated: ${flow}, no hub)` };
|
|
84
|
+
}
|
|
40
85
|
/**
|
|
41
86
|
* A route whose live page needs an env var the driver never sets (#6146).
|
|
42
87
|
* While it is unset the route serves its Free placeholder seed instead
|
|
@@ -100,6 +100,15 @@ export interface ModuleSlice {
|
|
|
100
100
|
* otherwise. Only a module with a BASE-tree consumer sets it.
|
|
101
101
|
*/
|
|
102
102
|
paidSectionsPackage?: string;
|
|
103
|
+
/**
|
|
104
|
+
* The paid MCP tool packages base code loads through
|
|
105
|
+
* `apps/mcp/src/lib/paid-tools.generated.ts` (#9460 DD6). Each is one row
|
|
106
|
+
* in the generated registry: a bundled `import()` when the scaffold's
|
|
107
|
+
* `apps/mcp/package.json` declares the package, absent otherwise. A
|
|
108
|
+
* package two modules deliver (`mcp-workspace`) is listed by each and
|
|
109
|
+
* rendered once.
|
|
110
|
+
*/
|
|
111
|
+
paidMcpToolPackages?: string[];
|
|
103
112
|
/** Packages this module adds to apps/web.may_import_from (its presentation surface). */
|
|
104
113
|
webImports?: string[];
|
|
105
114
|
/** Apps this module declares (api, mcp replace the base block; admin is new). web is BASE, never here. */
|
|
@@ -124,7 +133,7 @@ export interface ModuleSlice {
|
|
|
124
133
|
* *scaffolded customer site's* `architecture.yaml` — "apps/web MAY import
|
|
125
134
|
* packages/fumadocs-schema." `ownedFiles` instead names, one literal path at
|
|
126
135
|
* a time, which files in *this* monorepo physically belong to the module —
|
|
127
|
-
* "
|
|
136
|
+
* "packages-paid/api-scheduling/src/routes/schedule/index.ts IS the scheduling module." A
|
|
128
137
|
* package can appear in one view and not the other: `packages/fumadocs-schema`
|
|
129
138
|
* is a `webImports` entry (a permission — a docs scaffold installs it) but
|
|
130
139
|
* NOT an `ownedFiles` entry (it is `oss`-tiered; the strip keeps it).
|
|
@@ -154,7 +163,7 @@ export interface ModuleSlice {
|
|
|
154
163
|
* `RECOGNIZED_MODULES`, so adding a `content-write` key would make
|
|
155
164
|
* `create-ailk --modules content-write` a valid scaffold selection. It is
|
|
156
165
|
* not one — content-write is a licence-tier line drawn inside a single
|
|
157
|
-
* app, never a customer opt-in (see `
|
|
166
|
+
* app, never a customer opt-in (see `packages/api/src/config/modules.ts`).
|
|
158
167
|
* - Two are this-list-only and the manifest simply never recorded them:
|
|
159
168
|
* `apps/web/app/[locale]/docs/[[...slug]]/page.tsx` and
|
|
160
169
|
* `apps/web/app/[locale]/meet/confirmed/page.tsx`.
|
|
@@ -164,6 +173,14 @@ export interface ModuleSlice {
|
|
|
164
173
|
* are derived from the import graph — a test or story file carries
|
|
165
174
|
* `oss: false` iff it imports a slice file — never from filename stems,
|
|
166
175
|
* which miss eleven and over-mark three.
|
|
176
|
+
*
|
|
177
|
+
* Since REL-034.4 (#9565 D6) no entry names an `apps/api/` path: a module's
|
|
178
|
+
* API source is its `@working-theory/api-<module>` package under
|
|
179
|
+
* `packages-paid/`, dropped from the public tree wholesale and reached by a
|
|
180
|
+
* keyed scaffold through npm, never through a bundle. The producer
|
|
181
|
+
* (`scripts/build-module-bundles.mjs` `stageModule`) refuses to stage, and
|
|
182
|
+
* the extractor (`lib/extract-module-bundle.ts` `installBundleTree`) refuses
|
|
183
|
+
* to install, any path under `apps/api/`.
|
|
167
184
|
*/
|
|
168
185
|
ownedFiles?: string[];
|
|
169
186
|
/**
|
|
@@ -349,7 +366,7 @@ export declare const ARCHITECTURE_BASE: {
|
|
|
349
366
|
readonly version: 1;
|
|
350
367
|
readonly composition_model: {
|
|
351
368
|
readonly tiers: {
|
|
352
|
-
readonly data: "database/ — Prisma
|
|
369
|
+
readonly data: "database/ — Prisma config + seed; schema and migrations ship in @working-theory/database";
|
|
353
370
|
readonly api: "apps/api (public HTTP API) + apps/mcp (agent tools)";
|
|
354
371
|
readonly presentation: "apps/web — frontend surfaces";
|
|
355
372
|
};
|