create-ailk 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -22
- package/component-catalog.json +3 -3
- package/component-catalog.md +3 -3
- package/dist/add-module.js +4 -2
- package/dist/add-route.d.ts +12 -1
- package/dist/add-route.js +31 -3
- package/dist/cli.js +12 -7
- package/dist/derive-architecture.d.ts +3 -4
- package/dist/derive-architecture.js +65 -29
- package/dist/lib/design-checks.d.ts +9 -4
- package/dist/lib/design-checks.js +13 -7
- package/dist/lib/extract-module-bundle.js +29 -2
- package/dist/lib/fetch-template-snapshot.d.ts +2 -1
- package/dist/lib/fetch-template-snapshot.js +8 -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 +36 -15
- package/dist/lib/module-tier.d.ts +2 -8
- package/dist/lib/module-tier.js +13 -12
- package/dist/module-architecture.d.ts +20 -3
- package/dist/module-architecture.js +129 -552
- package/dist/paid-sections.d.ts +25 -1
- package/dist/paid-sections.js +88 -3
- package/dist/starter-grid.d.ts +6 -6
- package/dist/starter-grid.js +12 -5
- package/dist/surfaces.js +39 -2
- package/dist/template-record.d.ts +21 -3
- package/dist/template-record.js +38 -7
- package/dist/topology.d.ts +16 -3
- package/dist/topology.js +54 -23
- package/dist/update.d.ts +10 -1
- package/dist/update.js +715 -21
- package/package.json +3 -3
- package/release-scope.json +2 -2
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +8 -2
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +2 -2
- package/site-templates/marketing-site/ailk-template.json +7 -1
- package/site-templates/marketing-site/provenance.json +7 -1
- package/site-templates/saas-product/ailk-template.json +2 -1
- package/site-templates/saas-product/provenance.json +1 -0
- 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 +20 -5
- package/templates/.github/workflows/ci.yml +7 -4
- package/templates/CLAUDE.md +11 -1
- package/templates/CONVENTIONS.md +8 -10
- package/templates/README.md +14 -13
- package/templates/apps/api/.env.example +23 -2
- package/templates/apps/api/CLAUDE.md +119 -83
- 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-client.js +16 -0
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +3 -3
- package/templates/apps/api/src/modules/commerce.ts +10 -0
- package/templates/apps/api/src/modules/content-write.ts +10 -0
- package/templates/apps/api/src/modules/multi-tenant.ts +10 -0
- package/templates/apps/api/src/modules/scheduling.ts +10 -0
- package/templates/apps/api/src/modules/signal-collectors.ts +10 -0
- package/templates/apps/api/src/modules/workspace.ts +10 -0
- package/templates/apps/api/src/server.ts +117 -1882
- package/templates/apps/api/vercel.json +2 -2
- package/templates/apps/mcp/CLAUDE.md +90 -26
- package/templates/apps/mcp/__tests__/app-entry.test.ts +4 -254
- package/templates/apps/mcp/__tests__/boot-file.test.ts +92 -0
- package/templates/apps/mcp/jest.config.cjs +6 -1
- package/templates/apps/mcp/package.json +5 -13
- package/templates/apps/mcp/src/app.ts +8 -7
- package/templates/apps/mcp/src/index.ts +6 -34
- package/templates/apps/mcp/src/lib/paid-tools.generated.ts +10 -0
- package/templates/apps/mcp/src/lib/topology.generated.ts +2 -2
- package/templates/apps/mcp/src/site.ts +12 -0
- package/templates/apps/web/.env.example +1 -1
- package/templates/apps/web/CLAUDE.md +31 -3
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +9 -3
- package/templates/apps/web/app/[locale]/(auth)/__tests__/auth-pages.test.tsx +43 -4
- package/templates/apps/web/app/[locale]/(auth)/legal-footnote.tsx +35 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/page.test.tsx +117 -8
- package/templates/apps/web/app/[locale]/(auth)/sign-in/page.tsx +14 -37
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +6 -6
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-text.ts +20 -35
- package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/page.test.tsx +108 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/sign-up-card.test.tsx +111 -5
- package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +78 -16
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +132 -12
- package/templates/apps/web/app/[locale]/(authed)/__tests__/gate.test.tsx +53 -1
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/billing.test.tsx +38 -0
- package/templates/apps/web/app/[locale]/(authed)/account/billing/page.tsx +4 -2
- package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +47 -24
- package/templates/apps/web/app/[locale]/(authed)/signed-out-gate.generated.tsx +23 -4
- package/templates/apps/web/app/[locale]/contact/intake-analytics.ts +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/magnet-page.test.tsx +22 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/magnet-page.tsx +7 -3
- package/templates/apps/web/app/[locale]/layout.tsx +33 -13
- package/templates/apps/web/app/[locale]/meet/confirmed/BookingHandOff.tsx +128 -0
- package/templates/apps/web/app/[locale]/meet/confirmed/__tests__/BookingHandOff.test.tsx +126 -0
- 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 +10 -6
- package/templates/apps/web/i18n/request.ts +49 -1
- package/templates/apps/web/jest.config.cjs +1 -0
- package/templates/apps/web/lib/__tests__/account-config.test.ts +7 -0
- package/templates/apps/web/lib/__tests__/auth-email.test.ts +276 -0
- package/templates/apps/web/lib/auth-email.ts +103 -21
- package/templates/apps/web/lib/hub-session/__tests__/sign-in-gate.test.tsx +72 -23
- package/templates/apps/web/lib/hub-session/sign-in-gate.tsx +94 -70
- package/templates/apps/web/lib/prisma-for-auth.ts +5 -2
- 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/lib/sign-up-agreements.ts +291 -28
- package/templates/apps/web/lib/site-contributions.ts +18 -0
- package/templates/apps/web/messages/en.json +186 -20
- package/templates/apps/web/messages/site/en.json +1 -0
- package/templates/apps/web/src/lib/commerce-claim.ts +1 -1
- package/templates/customizations.yaml +37 -0
- package/templates/database/prisma.config.ts +10 -14
- package/templates/database/seed-test.ts +2 -2
- package/templates/database/seed.ts +5 -5
- package/templates/package.json +12 -6
- package/templates/pnpm-workspace.yaml +0 -1
- package/templates/project.yaml +16 -8
- package/templates/tools/jest/reporters.cjs +65 -0
- package/templates/tools/lint-architecture.ts +553 -7
- package/templates/tsconfig.json +1 -2
- package/versions.json +49 -36
- package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +0 -409
- package/templates/apps/api/src/__tests__/factories/agent-caller.ts +0 -102
- package/templates/apps/api/src/__tests__/factories/content-fixture.ts +0 -138
- package/templates/apps/api/src/__tests__/factories/in-memory-prisma.ts +0 -441
- package/templates/apps/api/src/__tests__/factories/index.ts +0 -70
- package/templates/apps/api/src/__tests__/factories/lead-fixture.ts +0 -82
- package/templates/apps/api/src/__tests__/leads-forwarded-rate-limit.test.ts +0 -135
- package/templates/apps/api/src/__tests__/services/enrichment-shim.test.ts +0 -126
- package/templates/apps/api/src/__tests__/stripe-boot.test.ts +0 -132
- package/templates/apps/api/src/__tests__/support/hub-sign-in-fake-db.ts +0 -362
- package/templates/apps/api/src/bin/__tests__/rate-limit-probe.test.ts +0 -184
- package/templates/apps/api/src/bin/abandon-sweep.ts +0 -42
- package/templates/apps/api/src/bin/rate-limit-probe.ts +0 -53
- package/templates/apps/api/src/bin/spokes.ts +0 -198
- package/templates/apps/api/src/bin/stripe-connections-rekey.ts +0 -45
- package/templates/apps/api/src/config/__tests__/hub-require-spoke-key.test.ts +0 -196
- package/templates/apps/api/src/config/__tests__/index.test.ts +0 -233
- package/templates/apps/api/src/config/__tests__/modules.test.ts +0 -76
- package/templates/apps/api/src/config/__tests__/stripe-connection-key.test.ts +0 -185
- package/templates/apps/api/src/config/__tests__/trusted-origins.test.ts +0 -238
- package/templates/apps/api/src/config/index.ts +0 -596
- package/templates/apps/api/src/config/modules.ts +0 -83
- package/templates/apps/api/src/lib/__tests__/agent-store.test.ts +0 -581
- package/templates/apps/api/src/lib/__tests__/auth-email-budget.test.ts +0 -143
- package/templates/apps/api/src/lib/__tests__/consent-ledger-double.ts +0 -237
- package/templates/apps/api/src/lib/__tests__/consent-store.test.ts +0 -353
- package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +0 -201
- package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +0 -224
- package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +0 -120
- package/templates/apps/api/src/lib/__tests__/errors.test.ts +0 -94
- package/templates/apps/api/src/lib/__tests__/file-fallback.test.ts +0 -144
- package/templates/apps/api/src/lib/__tests__/fixtures/HomePage/home.mdx +0 -8
- package/templates/apps/api/src/lib/__tests__/flow-completion-store.test.ts +0 -149
- package/templates/apps/api/src/lib/__tests__/flow-rename-race.db.test.ts +0 -116
- package/templates/apps/api/src/lib/__tests__/hub-sign-in-store.test.ts +0 -209
- package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +0 -257
- package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +0 -96
- package/templates/apps/api/src/lib/__tests__/outbound-http.test.ts +0 -125
- package/templates/apps/api/src/lib/__tests__/prisma.test.ts +0 -165
- package/templates/apps/api/src/lib/__tests__/require-commerce-claim.test.ts +0 -317
- package/templates/apps/api/src/lib/__tests__/require-paid-tier.test.ts +0 -129
- package/templates/apps/api/src/lib/__tests__/site.test.ts +0 -308
- package/templates/apps/api/src/lib/__tests__/slice-load.test.ts +0 -89
- package/templates/apps/api/src/lib/__tests__/spoke-store.test.ts +0 -202
- package/templates/apps/api/src/lib/__tests__/stripe-admission.test.ts +0 -217
- package/templates/apps/api/src/lib/__tests__/stripe.test.ts +0 -82
- package/templates/apps/api/src/lib/agent-store.ts +0 -613
- package/templates/apps/api/src/lib/auth-email-budget.ts +0 -161
- package/templates/apps/api/src/lib/consent-store.ts +0 -363
- package/templates/apps/api/src/lib/content-adapter.ts +0 -112
- package/templates/apps/api/src/lib/deliverable-asset-store.ts +0 -96
- package/templates/apps/api/src/lib/error-serializer.ts +0 -164
- package/templates/apps/api/src/lib/errors.ts +0 -95
- package/templates/apps/api/src/lib/file-fallback.ts +0 -87
- package/templates/apps/api/src/lib/flow-completion-store.ts +0 -136
- package/templates/apps/api/src/lib/hub-sign-in-store.ts +0 -455
- package/templates/apps/api/src/lib/lead-capture-store.ts +0 -122
- package/templates/apps/api/src/lib/lead-delivery.ts +0 -52
- package/templates/apps/api/src/lib/license-key-store.ts +0 -45
- package/templates/apps/api/src/lib/locales.ts +0 -201
- package/templates/apps/api/src/lib/outbound-http.ts +0 -127
- package/templates/apps/api/src/lib/prisma.ts +0 -21
- package/templates/apps/api/src/lib/proposal-paid-store.ts +0 -66
- package/templates/apps/api/src/lib/rate-limit-probe.ts +0 -165
- package/templates/apps/api/src/lib/rate-limit-store.ts +0 -142
- package/templates/apps/api/src/lib/require-commerce-claim.ts +0 -250
- package/templates/apps/api/src/lib/require-paid-tier.ts +0 -53
- package/templates/apps/api/src/lib/site.ts +0 -257
- package/templates/apps/api/src/lib/slice-load.ts +0 -90
- package/templates/apps/api/src/lib/spoke-store.ts +0 -180
- package/templates/apps/api/src/lib/stripe.ts +0 -321
- package/templates/apps/api/src/lib/webhook-idempotency.ts +0 -156
- package/templates/apps/api/src/middleware/__tests__/adversarial/bearer-token-format.test.ts +0 -111
- package/templates/apps/api/src/middleware/__tests__/adversarial/cookie-or-bearer-precedence.test.ts +0 -172
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-bearer-skip.test.ts +0 -119
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-cookie-path.test.ts +0 -138
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-trusted-origins.test.ts +0 -142
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +0 -155
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-timeout.test.ts +0 -139
- package/templates/apps/api/src/middleware/__tests__/auth.bearer-path.test.ts +0 -562
- package/templates/apps/api/src/middleware/__tests__/auth.both-present-precedence.test.ts +0 -76
- package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +0 -220
- package/templates/apps/api/src/middleware/__tests__/auth.database-not-configured.test.ts +0 -97
- package/templates/apps/api/src/middleware/__tests__/auth.hub-session-path.test.ts +0 -557
- package/templates/apps/api/src/middleware/__tests__/auth.neither-present.test.ts +0 -72
- package/templates/apps/api/src/middleware/__tests__/auth.optional-cookie.test.ts +0 -140
- package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +0 -721
- package/templates/apps/api/src/middleware/__tests__/rate-limit-cross-isolate.db.test.ts +0 -220
- package/templates/apps/api/src/middleware/__tests__/rate-limit-store.test.ts +0 -430
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +0 -1409
- package/templates/apps/api/src/middleware/__tests__/write-budget.test.ts +0 -174
- package/templates/apps/api/src/middleware/auth.ts +0 -864
- package/templates/apps/api/src/middleware/default-tenant.ts +0 -166
- package/templates/apps/api/src/middleware/rate-limit.ts +0 -983
- package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +0 -391
- package/templates/apps/api/src/openapi/__tests__/spec-identity.test.ts +0 -182
- package/templates/apps/api/src/openapi/index.ts +0 -18
- package/templates/apps/api/src/openapi/spec.ts +0 -2148
- package/templates/apps/api/src/openapi/surface-drift.ts +0 -195
- package/templates/apps/api/src/routes/aeo/__tests__/index.test.ts +0 -175
- package/templates/apps/api/src/routes/aeo/index.ts +0 -107
- package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +0 -196
- package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +0 -249
- package/templates/apps/api/src/routes/auth/__tests__/hub-sign-in.test.ts +0 -532
- package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +0 -313
- package/templates/apps/api/src/routes/auth/__tests__/transactional-email.test.ts +0 -413
- package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +0 -609
- package/templates/apps/api/src/routes/auth/hub-sign-in.ts +0 -242
- package/templates/apps/api/src/routes/auth/tokens.ts +0 -211
- package/templates/apps/api/src/routes/auth/transactional-email.ts +0 -301
- package/templates/apps/api/src/routes/auth/user.ts +0 -305
- package/templates/apps/api/src/routes/billing/plan-checkout.ts +0 -332
- package/templates/apps/api/src/routes/checkout/__tests__/live-key.test.ts +0 -178
- package/templates/apps/api/src/routes/checkout/__tests__/offerings-authorization.test.ts +0 -1426
- package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +0 -448
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +0 -1742
- package/templates/apps/api/src/routes/checkout/index.ts +0 -34
- package/templates/apps/api/src/routes/checkout/session.ts +0 -171
- package/templates/apps/api/src/routes/checkout/sessions.ts +0 -540
- package/templates/apps/api/src/routes/consent/__tests__/account.test.ts +0 -386
- package/templates/apps/api/src/routes/consent/__tests__/sign-up-rate-limit.test.ts +0 -160
- package/templates/apps/api/src/routes/consent/account.ts +0 -268
- package/templates/apps/api/src/routes/consent/cookie.ts +0 -90
- package/templates/apps/api/src/routes/consent/index.ts +0 -26
- package/templates/apps/api/src/routes/consent/unsubscribe.ts +0 -127
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +0 -853
- package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +0 -230
- package/templates/apps/api/src/routes/content/__tests__/list-types.test.ts +0 -44
- package/templates/apps/api/src/routes/content/__tests__/locale.test.ts +0 -118
- package/templates/apps/api/src/routes/content/__tests__/offerings.test.ts +0 -731
- package/templates/apps/api/src/routes/content/__tests__/pricing.test.ts +0 -753
- package/templates/apps/api/src/routes/content/__tests__/rate-limit.test.ts +0 -51
- package/templates/apps/api/src/routes/content/__tests__/search.test.ts +0 -450
- package/templates/apps/api/src/routes/content/__tests__/shown-offerings.test.ts +0 -762
- package/templates/apps/api/src/routes/content/get-page.ts +0 -183
- package/templates/apps/api/src/routes/content/index.ts +0 -49
- package/templates/apps/api/src/routes/content/list-pages.ts +0 -74
- package/templates/apps/api/src/routes/content/list-types.ts +0 -19
- package/templates/apps/api/src/routes/content/offerings.ts +0 -184
- package/templates/apps/api/src/routes/content/pricing.ts +0 -176
- package/templates/apps/api/src/routes/content/rate-limit.ts +0 -22
- package/templates/apps/api/src/routes/content/search.ts +0 -100
- package/templates/apps/api/src/routes/content/shown-offerings.ts +0 -229
- package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +0 -88
- package/templates/apps/api/src/routes/leads/__tests__/list.test.ts +0 -171
- package/templates/apps/api/src/routes/leads/__tests__/magnet-completion.test.ts +0 -515
- package/templates/apps/api/src/routes/leads/__tests__/spoke.test.ts +0 -392
- package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +0 -165
- package/templates/apps/api/src/routes/leads/index.ts +0 -639
- package/templates/apps/api/src/routes/leads/list.ts +0 -104
- package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +0 -626
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +0 -1268
- package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +0 -847
- package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +0 -491
- package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +0 -476
- package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +0 -872
- package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +0 -1022
- package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +0 -484
- package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +0 -535
- package/templates/apps/api/src/routes/project-listings/index.ts +0 -164
- package/templates/apps/api/src/routes/project-listings/me.ts +0 -87
- package/templates/apps/api/src/routes/project-listings/patch-copy.ts +0 -224
- package/templates/apps/api/src/routes/project-listings/patch-draft.ts +0 -102
- package/templates/apps/api/src/routes/project-listings/public.ts +0 -98
- package/templates/apps/api/src/routes/project-listings/respond.ts +0 -48
- package/templates/apps/api/src/routes/project-listings/resume-token.ts +0 -27
- package/templates/apps/api/src/routes/project-listings/start.ts +0 -140
- package/templates/apps/api/src/routes/project-listings/submit.ts +0 -130
- package/templates/apps/api/src/routes/project-listings/verify-email.ts +0 -150
- package/templates/apps/api/src/routes/requests/__tests__/confirm.test.ts +0 -686
- package/templates/apps/api/src/routes/requests/confirm.ts +0 -601
- package/templates/apps/api/src/routes/requests/index.ts +0 -54
- package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +0 -306
- package/templates/apps/api/src/routes/test/auth/session.ts +0 -143
- package/templates/apps/api/src/routes/webhooks/README.md +0 -398
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-checkout-consent.test.ts +0 -649
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-dunning.test.ts +0 -749
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +0 -449
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +0 -264
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode-live.test.ts +0 -159
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-livemode.test.ts +0 -158
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-offerings.test.ts +0 -814
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +0 -301
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-proposal-paid.test.ts +0 -369
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +0 -215
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-request-paid.test.ts +0 -301
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-site-filter.test.ts +0 -809
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +0 -1155
- package/templates/apps/api/src/routes/webhooks/index.ts +0 -141
- package/templates/apps/api/src/routes/webhooks/stripe-offerings.ts +0 -384
- package/templates/apps/api/src/routes/webhooks/stripe.ts +0 -2028
- package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +0 -645
- package/templates/apps/api/src/services/__tests__/answer-distributions.test.ts +0 -132
- package/templates/apps/api/src/services/__tests__/audit-log.test.ts +0 -1028
- package/templates/apps/api/src/services/__tests__/checkout-plan.test.ts +0 -313
- package/templates/apps/api/src/services/__tests__/consent-ledger.test.ts +0 -503
- package/templates/apps/api/src/services/__tests__/consent-migration.test.ts +0 -65
- package/templates/apps/api/src/services/__tests__/consent.test.ts +0 -299
- package/templates/apps/api/src/services/__tests__/default-tenant.test.ts +0 -147
- package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +0 -877
- package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +0 -379
- package/templates/apps/api/src/services/__tests__/dunning-policy.test.ts +0 -368
- package/templates/apps/api/src/services/__tests__/entitlements.test.ts +0 -142
- package/templates/apps/api/src/services/__tests__/hub-sign-in.test.ts +0 -854
- package/templates/apps/api/src/services/__tests__/keyless-workspace-predicate.test.ts +0 -234
- package/templates/apps/api/src/services/__tests__/lead-accept-user.test.ts +0 -251
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +0 -2660
- package/templates/apps/api/src/services/__tests__/listing-config.test.ts +0 -166
- package/templates/apps/api/src/services/__tests__/magnet-completion.test.ts +0 -389
- package/templates/apps/api/src/services/__tests__/person.test.ts +0 -1204
- package/templates/apps/api/src/services/__tests__/plan-offerings.test.ts +0 -450
- package/templates/apps/api/src/services/__tests__/project-listings.counts.test.ts +0 -202
- package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +0 -151
- package/templates/apps/api/src/services/__tests__/public-site-resolver.test.ts +0 -137
- package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +0 -531
- package/templates/apps/api/src/services/__tests__/revalidation.test.ts +0 -372
- package/templates/apps/api/src/services/__tests__/slack-notify.test.ts +0 -348
- package/templates/apps/api/src/services/__tests__/spoke-resolution.test.ts +0 -660
- package/templates/apps/api/src/services/__tests__/usage-aggregation.test.ts +0 -941
- package/templates/apps/api/src/services/__tests__/usage-credits.test.ts +0 -588
- package/templates/apps/api/src/services/__tests__/verified-email.test.ts +0 -78
- package/templates/apps/api/src/services/abandon-email.ts +0 -336
- package/templates/apps/api/src/services/aeo-score.ts +0 -325
- package/templates/apps/api/src/services/answer-distributions.ts +0 -138
- package/templates/apps/api/src/services/audit-log.ts +0 -961
- package/templates/apps/api/src/services/checkout-buyer.ts +0 -168
- package/templates/apps/api/src/services/consent.ts +0 -834
- package/templates/apps/api/src/services/default-tenant.ts +0 -416
- package/templates/apps/api/src/services/deliverable-fulfillment.ts +0 -750
- package/templates/apps/api/src/services/dunning-policy.ts +0 -294
- package/templates/apps/api/src/services/enrichment-shim.ts +0 -53
- package/templates/apps/api/src/services/entitlements.ts +0 -338
- package/templates/apps/api/src/services/hub-sign-in.ts +0 -472
- package/templates/apps/api/src/services/lead-accept-user.ts +0 -126
- package/templates/apps/api/src/services/lead-promotion.ts +0 -160
- package/templates/apps/api/src/services/lead-routing.ts +0 -1372
- package/templates/apps/api/src/services/leads-inbox.ts +0 -312
- package/templates/apps/api/src/services/listing-config.ts +0 -178
- package/templates/apps/api/src/services/magnet-completion.ts +0 -242
- package/templates/apps/api/src/services/offerings/__tests__/catalog.test.ts +0 -348
- package/templates/apps/api/src/services/offerings/__tests__/checkout-session-record.test.ts +0 -268
- package/templates/apps/api/src/services/offerings/__tests__/connection.test.ts +0 -975
- package/templates/apps/api/src/services/offerings/__tests__/fixtures.ts +0 -416
- package/templates/apps/api/src/services/offerings/__tests__/org-products.test.ts +0 -400
- package/templates/apps/api/src/services/offerings/__tests__/readers.test.ts +0 -685
- package/templates/apps/api/src/services/offerings/__tests__/source.test.ts +0 -231
- package/templates/apps/api/src/services/offerings/catalog.ts +0 -318
- package/templates/apps/api/src/services/offerings/checkout-authorization.ts +0 -403
- package/templates/apps/api/src/services/offerings/checkout-session-record.ts +0 -192
- package/templates/apps/api/src/services/offerings/connection.ts +0 -1083
- package/templates/apps/api/src/services/offerings/index.ts +0 -614
- package/templates/apps/api/src/services/offerings/source.ts +0 -140
- package/templates/apps/api/src/services/offerings/store.ts +0 -150
- package/templates/apps/api/src/services/owner-workspaces.ts +0 -132
- package/templates/apps/api/src/services/person.ts +0 -1211
- package/templates/apps/api/src/services/plan-offerings.ts +0 -125
- package/templates/apps/api/src/services/project-listing-resume-email.ts +0 -326
- package/templates/apps/api/src/services/project-listings.ts +0 -2085
- package/templates/apps/api/src/services/public-site-resolver.ts +0 -396
- package/templates/apps/api/src/services/request-confirm.ts +0 -698
- package/templates/apps/api/src/services/revalidation.ts +0 -235
- package/templates/apps/api/src/services/slack-notify.ts +0 -291
- package/templates/apps/api/src/services/usage-aggregation.ts +0 -516
- package/templates/apps/api/src/services/usage-credits.ts +0 -340
- package/templates/apps/api/src/services/verified-email.ts +0 -71
- package/templates/apps/mcp/__tests__/abuse/daily-cap.test.ts +0 -52
- package/templates/apps/mcp/__tests__/abuse/email-validator.test.ts +0 -46
- package/templates/apps/mcp/__tests__/abuse/guard.test.ts +0 -198
- package/templates/apps/mcp/__tests__/abuse/honeypot.test.ts +0 -36
- package/templates/apps/mcp/__tests__/abuse/user-agent-deny.test.ts +0 -54
- package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +0 -116
- package/templates/apps/mcp/__tests__/audit-single-page.test.ts +0 -299
- package/templates/apps/mcp/__tests__/boot.test.ts +0 -280
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +0 -359
- package/templates/apps/mcp/__tests__/config/modules.test.ts +0 -78
- package/templates/apps/mcp/__tests__/get_business_hours.test.ts +0 -82
- package/templates/apps/mcp/__tests__/get_faq.test.ts +0 -80
- package/templates/apps/mcp/__tests__/get_locations.test.ts +0 -65
- package/templates/apps/mcp/__tests__/get_offerings.test.ts +0 -557
- package/templates/apps/mcp/__tests__/get_pricing.test.ts +0 -524
- package/templates/apps/mcp/__tests__/get_site_info.test.ts +0 -81
- package/templates/apps/mcp/__tests__/http-transport.test.ts +0 -1232
- package/templates/apps/mcp/__tests__/index.test.ts +0 -195
- package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +0 -191
- package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +0 -531
- package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +0 -70
- package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +0 -162
- package/templates/apps/mcp/__tests__/lib/content-root.test.ts +0 -93
- package/templates/apps/mcp/__tests__/lib/errors.test.ts +0 -75
- package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +0 -180
- package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +0 -124
- package/templates/apps/mcp/__tests__/list_pages.test.ts +0 -268
- package/templates/apps/mcp/__tests__/locale.test.ts +0 -120
- package/templates/apps/mcp/__tests__/module-exclusion.test.ts +0 -175
- package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +0 -101
- package/templates/apps/mcp/__tests__/rate-limit-write.test.ts +0 -189
- package/templates/apps/mcp/__tests__/read_content.test.ts +0 -511
- package/templates/apps/mcp/__tests__/request_callback.test.ts +0 -160
- package/templates/apps/mcp/__tests__/search_content.test.ts +0 -271
- package/templates/apps/mcp/__tests__/server.test.ts +0 -388
- package/templates/apps/mcp/__tests__/start_purchase.test.ts +0 -448
- package/templates/apps/mcp/__tests__/submit_lead.test.ts +0 -222
- package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +0 -152
- package/templates/apps/mcp/__tests__/tools/create_project.test.ts +0 -243
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +0 -451
- package/templates/apps/mcp/src/abuse/daily-cap.ts +0 -47
- package/templates/apps/mcp/src/abuse/email-validator.ts +0 -25
- package/templates/apps/mcp/src/abuse/honeypot.ts +0 -21
- package/templates/apps/mcp/src/abuse/index.ts +0 -349
- package/templates/apps/mcp/src/abuse/user-agent-deny.ts +0 -58
- package/templates/apps/mcp/src/boot.ts +0 -167
- package/templates/apps/mcp/src/config/modules.ts +0 -43
- package/templates/apps/mcp/src/http-transport.ts +0 -564
- package/templates/apps/mcp/src/lib/audit-single-page.ts +0 -308
- package/templates/apps/mcp/src/lib/commerce-claim.ts +0 -263
- package/templates/apps/mcp/src/lib/content-adapter.ts +0 -116
- package/templates/apps/mcp/src/lib/empty-content-adapter.ts +0 -140
- package/templates/apps/mcp/src/lib/errors.ts +0 -61
- package/templates/apps/mcp/src/lib/license-key-store.ts +0 -45
- package/templates/apps/mcp/src/lib/locales.ts +0 -171
- package/templates/apps/mcp/src/lib/prisma.ts +0 -39
- package/templates/apps/mcp/src/lib/public-workspace.ts +0 -133
- package/templates/apps/mcp/src/lib/resolve-locale.ts +0 -30
- package/templates/apps/mcp/src/lib/shown-offerings.ts +0 -105
- package/templates/apps/mcp/src/lib/site-config.ts +0 -53
- package/templates/apps/mcp/src/lib/stripe-tax-signal.ts +0 -59
- package/templates/apps/mcp/src/request-context.ts +0 -52
- package/templates/apps/mcp/src/server.ts +0 -343
- package/templates/apps/mcp/src/serverless-app.ts +0 -88
- package/templates/apps/mcp/src/tools/audit.ts +0 -127
- package/templates/apps/mcp/src/tools/capture_lead.ts +0 -66
- package/templates/apps/mcp/src/tools/create_project.ts +0 -134
- package/templates/apps/mcp/src/tools/get_business_hours.ts +0 -68
- package/templates/apps/mcp/src/tools/get_faq.ts +0 -71
- package/templates/apps/mcp/src/tools/get_locations.ts +0 -88
- package/templates/apps/mcp/src/tools/get_offerings.ts +0 -96
- package/templates/apps/mcp/src/tools/get_pricing.ts +0 -94
- package/templates/apps/mcp/src/tools/get_site_info.ts +0 -86
- package/templates/apps/mcp/src/tools/index.ts +0 -138
- package/templates/apps/mcp/src/tools/list_pages.ts +0 -68
- package/templates/apps/mcp/src/tools/person_notes.ts +0 -25
- package/templates/apps/mcp/src/tools/proposals.ts +0 -27
- package/templates/apps/mcp/src/tools/purchase.ts +0 -205
- package/templates/apps/mcp/src/tools/read_content.ts +0 -81
- package/templates/apps/mcp/src/tools/request_callback.ts +0 -52
- package/templates/apps/mcp/src/tools/search_content.ts +0 -63
- package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +0 -54
- package/templates/apps/mcp/src/workspace-server.ts +0 -224
- package/templates/database/CHANGELOG.md +0 -981
- package/templates/database/LICENSE +0 -202
- package/templates/database/NOTICE +0 -2
- package/templates/database/README.md +0 -243
- package/templates/database/__tests__/agents.db.test.ts +0 -320
- package/templates/database/__tests__/appointment.db.test.ts +0 -106
- package/templates/database/__tests__/artifact-content-store.db.test.ts +0 -316
- package/templates/database/__tests__/composite-fence.db.test.ts +0 -206
- package/templates/database/__tests__/consent-ledger.db.test.ts +0 -345
- package/templates/database/__tests__/consent-source-checkout-migration.test.ts +0 -79
- package/templates/database/__tests__/fence-fan-out.db.test.ts +0 -715
- package/templates/database/__tests__/fixtures/appointment-create-probe.ts +0 -79
- package/templates/database/__tests__/fixtures/person-backfill.json +0 -264
- package/templates/database/__tests__/fixtures/person-contact-backfill.json +0 -182
- package/templates/database/__tests__/fixtures/project-listing-consent-probe.ts +0 -100
- package/templates/database/__tests__/flow-completion-migration.test.ts +0 -115
- package/templates/database/__tests__/flow-completion.db.test.ts +0 -136
- package/templates/database/__tests__/flow-workspace-key.db.test.ts +0 -263
- package/templates/database/__tests__/flows-listing-diagnostic.test.ts +0 -392
- package/templates/database/__tests__/flows-presets.test.ts +0 -173
- package/templates/database/__tests__/in-page-magnets-migration.test.ts +0 -161
- package/templates/database/__tests__/lead-idempotency-key.db.test.ts +0 -92
- package/templates/database/__tests__/member-area.db.test.ts +0 -257
- package/templates/database/__tests__/member-contract-migration.test.ts +0 -85
- package/templates/database/__tests__/member-contract.db.test.ts +0 -413
- package/templates/database/__tests__/offerings-checkout-session.db.test.ts +0 -270
- package/templates/database/__tests__/offerings-migration.test.ts +0 -197
- package/templates/database/__tests__/offerings-shown-price-ids-migration.test.ts +0 -86
- package/templates/database/__tests__/offerings.db.test.ts +0 -303
- package/templates/database/__tests__/outbound-message-action.db.test.ts +0 -80
- package/templates/database/__tests__/person-contact.db.test.ts +0 -563
- package/templates/database/__tests__/person-notes.db.test.ts +0 -249
- package/templates/database/__tests__/person.db.test.ts +0 -586
- package/templates/database/__tests__/piece-kind-migration.test.ts +0 -67
- package/templates/database/__tests__/piece-kind.db.test.ts +0 -208
- package/templates/database/__tests__/prefixed-ids.db.test.ts +0 -222
- package/templates/database/__tests__/project-listing-consent-at.db.test.ts +0 -111
- package/templates/database/__tests__/seed.test.ts +0 -272
- package/templates/database/__tests__/spoke-registry.db.test.ts +0 -191
- package/templates/database/__tests__/tenancy.test.ts +0 -141
- package/templates/database/__tests__/trial-magnet-migration.test.ts +0 -186
- package/templates/database/__tests__/user-cascade.test.ts +0 -140
- package/templates/database/_gitignore +0 -8
- package/templates/database/auth/.gitkeep +0 -0
- package/templates/database/auth/schema.prisma +0 -641
- package/templates/database/config/.gitkeep +0 -0
- package/templates/database/config/schema.prisma +0 -441
- package/templates/database/content/.gitkeep +0 -0
- package/templates/database/content/schema.prisma +0 -339
- package/templates/database/eslint.config.mjs +0 -69
- package/templates/database/flows/listing-diagnostic.ts +0 -182
- package/templates/database/flows/presets.ts +0 -315
- package/templates/database/inbox/.gitkeep +0 -0
- package/templates/database/inbox/README.md +0 -3
- package/templates/database/inbox/__tests__/schema.test.ts +0 -44
- package/templates/database/inbox/schema.prisma +0 -1447
- package/templates/database/jest.config.cjs +0 -36
- package/templates/database/migrations/20260508000000_add_inbox_namespace/migration.sql +0 -328
- package/templates/database/migrations/20260513000000_better_auth_migration/migration.sql +0 -100
- package/templates/database/migrations/20260515000000_add_user_billing_fields/migration.sql +0 -28
- package/templates/database/migrations/20260516000000_add_user_tier_care_plan_seat/migration.sql +0 -25
- package/templates/database/migrations/20260518000000_add_telemetry_records/migration.sql +0 -42
- package/templates/database/migrations/20260525000000_theme_wiring/migration.sql +0 -67
- package/templates/database/migrations/20260710000000_retire_commercial_tier/migration.sql +0 -21
- package/templates/database/migrations/20260712215647_add_multi_tenant_tenancy/migration.sql +0 -201
- package/templates/database/migrations/20260713143320_reanchor_site_config_to_workspace/migration.sql +0 -67
- package/templates/database/migrations/20260713174000_add_audit_logs/migration.sql +0 -46
- package/templates/database/migrations/20260713190000_drop_telemetry_records/migration.sql +0 -25
- package/templates/database/migrations/20260713192000_add_uuidv7_function/migration.sql +0 -49
- package/templates/database/migrations/20260713192429_prefixed_uuid_entity_ids/migration.sql +0 -197
- package/templates/database/migrations/20260713200000_add_org_billing/migration.sql +0 -32
- package/templates/database/migrations/20260714000000_add_lead_promotion_fields/migration.sql +0 -22
- package/templates/database/migrations/20260714010000_add_usage_billing_content_models/migration.sql +0 -151
- package/templates/database/migrations/20260714020000_add_usage_billing_auth_config_models/migration.sql +0 -223
- package/templates/database/migrations/20260714030000_credit_balance_non_negative/migration.sql +0 -22
- package/templates/database/migrations/20260714030000_widen_usage_billing_report_aggregates/migration.sql +0 -32
- package/templates/database/migrations/20260810233516_add_flow_engine_models/migration.sql +0 -40
- package/templates/database/migrations/20260811020000_add_flow_session_abandon_email_columns/migration.sql +0 -4
- package/templates/database/migrations/20260811030000_add_flow_session_abandon_email_index/migration.sql +0 -2
- package/templates/database/migrations/20260811040000_add_flow_session_segment/migration.sql +0 -2
- package/templates/database/migrations/20260811050000_add_deliverable_models/migration.sql +0 -29
- package/templates/database/migrations/20260812000000_add_deliverable_grant_send_columns/migration.sql +0 -6
- package/templates/database/migrations/20260902222948_add_waitlist_experiment_models/migration.sql +0 -39
- package/templates/database/migrations/20260902224500_add_waitlist_id_format_checks/migration.sql +0 -24
- package/templates/database/migrations/20260903004112_add_flow_session_flags_aeo_score/migration.sql +0 -3
- package/templates/database/migrations/20260903010000_add_playbook_instance/migration.sql +0 -33
- package/templates/database/migrations/20260904000000_add_waitlist_followup_send/migration.sql +0 -30
- package/templates/database/migrations/20260905230000_add_flow_checkout/migration.sql +0 -47
- package/templates/database/migrations/20260906000000_add_flow_checkout_idempotency/migration.sql +0 -16
- package/templates/database/migrations/20260907120000_add_project_listing/migration.sql +0 -47
- package/templates/database/migrations/20260907130000_add_project_listing_slack_columns/migration.sql +0 -10
- package/templates/database/migrations/20260907180000_add_listing_csv_send/migration.sql +0 -26
- package/templates/database/migrations/20260909120000_project_listings_platform/migration.sql +0 -90
- package/templates/database/migrations/20260909180000_listing_draft_and_fields/migration.sql +0 -174
- package/templates/database/migrations/20260910120000_listing_public_site_key/migration.sql +0 -14
- package/templates/database/migrations/20260911120000_listing_copy_edit_audit/migration.sql +0 -25
- package/templates/database/migrations/20260911140000_listing_structured_address/migration.sql +0 -32
- package/templates/database/migrations/20260911180000_consent_grants/migration.sql +0 -71
- package/templates/database/migrations/20260911200000_listing_site_answers/migration.sql +0 -30
- package/templates/database/migrations/20260912120000_listing_owner_link/migration.sql +0 -49
- package/templates/database/migrations/20260914120000_listing_founder_identity/migration.sql +0 -123
- package/templates/database/migrations/20260915120000_project_listing_solution/migration.sql +0 -15
- package/templates/database/migrations/20260916120000_artifact_content_store/migration.sql +0 -158
- package/templates/database/migrations/20260917120000_callback_request_confirm/migration.sql +0 -40
- package/templates/database/migrations/20260918120000_add_appointment/migration.sql +0 -67
- package/templates/database/migrations/20260918120000_asset_metadata_columns/migration.sql +0 -70
- package/templates/database/migrations/20260919120000_flow_workspace_key/migration.sql +0 -181
- package/templates/database/migrations/20260919130000_flow_definition_admin_columns/migration.sql +0 -172
- package/templates/database/migrations/20260919130000_workspace_meetings/migration.sql +0 -41
- package/templates/database/migrations/20260919140000_inbox_workspace_key/migration.sql +0 -185
- package/templates/database/migrations/20260920120000_lead_handled_at/migration.sql +0 -70
- package/templates/database/migrations/20260920130000_lead_workspace_source_index/migration.sql +0 -57
- package/templates/database/migrations/20260921120000_deliverable_grant_workspace_key/migration.sql +0 -68
- package/templates/database/migrations/20260922120000_tenancy_fence/migration.sql +0 -1067
- package/templates/database/migrations/20260923120000_listing_capturing_magnet/migration.sql +0 -210
- package/templates/database/migrations/20261003120000_spoke_registry/migration.sql +0 -80
- package/templates/database/migrations/20261003130000_scheduling_connection/migration.sql +0 -49
- package/templates/database/migrations/20261005120000_agents/migration.sql +0 -84
- package/templates/database/migrations/20261008120000_user_last_workspace/migration.sql +0 -35
- package/templates/database/migrations/20261008130000_lead_idempotency_key/migration.sql +0 -20
- package/templates/database/migrations/20261009120000_agent_grants/migration.sql +0 -33
- package/templates/database/migrations/20261010120000_person/migration.sql +0 -106
- package/templates/database/migrations/20261010121000_person_backfill/migration.sql +0 -132
- package/templates/database/migrations/20261010130000_agent_grants_people_read/migration.sql +0 -20
- package/templates/database/migrations/20261011120000_member_area/migration.sql +0 -158
- package/templates/database/migrations/20261011130000_agent_grants_member_pieces_manage/migration.sql +0 -21
- package/templates/database/migrations/20261012120000_member_contract/migration.sql +0 -192
- package/templates/database/migrations/20261013120000_lead_spoke_checkout/migration.sql +0 -20
- package/templates/database/migrations/20261014120000_consent_ledger/migration.sql +0 -122
- package/templates/database/migrations/20261014120000_person_contact/migration.sql +0 -231
- package/templates/database/migrations/20261015120000_person_notes/migration.sql +0 -77
- package/templates/database/migrations/20261015120000_rate_limit_counters/migration.sql +0 -43
- package/templates/database/migrations/20261016120000_piece_kind/migration.sql +0 -95
- package/templates/database/migrations/20261017120000_outbound_message_action/migration.sql +0 -30
- package/templates/database/migrations/20261018120000_flow_completion/migration.sql +0 -52
- package/templates/database/migrations/20261019120000_consent_source_checkout/migration.sql +0 -27
- package/templates/database/migrations/20261020120000_offerings_data_model/migration.sql +0 -146
- package/templates/database/migrations/20261021120000_offerings_checkout_session/migration.sql +0 -77
- package/templates/database/migrations/20261022120000_in_page_magnets/migration.sql +0 -45
- package/templates/database/migrations/20261023120000_offerings_shown_price_ids/migration.sql +0 -47
- package/templates/database/migrations/20261024120000_organization_plan_checkout_session/migration.sql +0 -16
- package/templates/database/migrations/20261025120000_trial_magnet/migration.sql +0 -28
- package/templates/database/migrations/20261026120000_trial_magnet_proof_line/migration.sql +0 -23
- package/templates/database/migrations/migration_lock.toml +0 -3
- package/templates/database/ops/.gitkeep +0 -0
- package/templates/database/ops/schema.prisma +0 -43
- package/templates/database/package.json +0 -89
- package/templates/database/schema.prisma +0 -71
- package/templates/database/scripts/db-generate-locked.sh +0 -80
- package/templates/database/scripts/person-backfill.sql +0 -132
- package/templates/database/tenancy.ts +0 -183
- package/templates/database/tsconfig.build.json +0 -16
- package/templates/database/tsconfig.flows.json +0 -15
- package/templates/database/tsconfig.json +0 -16
- package/templates/database/tsconfig.tenancy.json +0 -14
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The MCP read of the site's Offerings shown set (#8933, spec D6).
|
|
3
|
-
*
|
|
4
|
-
* `get_pricing` and `get_offerings` answer a connected site's shown set —
|
|
5
|
-
* the persisted Stripe snapshot `GET /v1/content/shown-offerings` serves
|
|
6
|
-
* (#8924) — rather than its page content. apps/mcp reaches Offerings data
|
|
7
|
-
* only over HTTP (#8876 D9), so this file reads that route through
|
|
8
|
-
* `@working-theory/api-client` and hands the tools the current set, or
|
|
9
|
-
* `null` for the content path:
|
|
10
|
-
*
|
|
11
|
-
* 1. The deployment's own claim first: unless `mcpCommerceClaim()` reads
|
|
12
|
-
* `claimed`, no HTTP call is made at all. The API's claim, read inside
|
|
13
|
-
* the route, still decides; this one only spares an unlicensed host the
|
|
14
|
-
* call.
|
|
15
|
-
* 2. One `apiClient.offerings.shown()`, raced against
|
|
16
|
-
* `MCP_SHOWN_SET_BUDGET_MS`, so a hung API never holds a tool call.
|
|
17
|
-
* 3. A refusal, a body `shownOfferingsAnswerSchema` refuses, the budget
|
|
18
|
-
* passing or a rejection is `null` and one `console.error` line.
|
|
19
|
-
* 4. Otherwise `currentShownSet` — a `current` set with offerings, or `null`.
|
|
20
|
-
*
|
|
21
|
-
* The workspace is the API's: api-client sends the deployment's own spoke
|
|
22
|
-
* key, and no tool argument names one (identity-blind). No Stripe package is
|
|
23
|
-
* imported here or anywhere in apps/mcp (T7).
|
|
24
|
-
*
|
|
25
|
-
* T6 — every log line is `{ event, outcome }` plus an HTTP `status` or an
|
|
26
|
-
* error's class name as `errName`: never a body, a message, the shown set, a
|
|
27
|
-
* lookup key, an id, a name or a description. The log calls live here
|
|
28
|
-
* because the tool files may not call `console.*`.
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
import { apiClient } from "@working-theory/api-client";
|
|
32
|
-
import { currentShownSet } from "@working-theory/content-adapters";
|
|
33
|
-
import {
|
|
34
|
-
shownOfferingsAnswerSchema,
|
|
35
|
-
type WorkspaceShownSetWire,
|
|
36
|
-
} from "@working-theory/validation";
|
|
37
|
-
|
|
38
|
-
import { mcpCommerceClaim } from "./commerce-claim.js";
|
|
39
|
-
|
|
40
|
-
/** The longest one tool call waits on the shown set before answering content. */
|
|
41
|
-
export const MCP_SHOWN_SET_BUDGET_MS = 5000;
|
|
42
|
-
|
|
43
|
-
const OVER_BUDGET = Symbol("over-budget");
|
|
44
|
-
|
|
45
|
-
/** An error's class name only — never its message, which may carry Stripe text. */
|
|
46
|
-
function errName(err: unknown): string {
|
|
47
|
-
return err instanceof Error ? err.constructor.name : typeof err;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** The site's current shown set, or `null` for the content path. */
|
|
51
|
-
export async function mcpCurrentShownSet(): Promise<WorkspaceShownSetWire | null> {
|
|
52
|
-
if (mcpCommerceClaim() !== "claimed") return null;
|
|
53
|
-
|
|
54
|
-
// Caught before the race, so a rejection after the budget is never unhandled.
|
|
55
|
-
const read = apiClient.offerings.shown().catch((err: unknown) => {
|
|
56
|
-
console.error({
|
|
57
|
-
event: "shown-offerings",
|
|
58
|
-
outcome: "unreachable",
|
|
59
|
-
errName: errName(err),
|
|
60
|
-
});
|
|
61
|
-
return null;
|
|
62
|
-
});
|
|
63
|
-
let timer: NodeJS.Timeout | undefined;
|
|
64
|
-
const budget = new Promise<typeof OVER_BUDGET>((resolve) => {
|
|
65
|
-
timer = setTimeout(() => resolve(OVER_BUDGET), MCP_SHOWN_SET_BUDGET_MS);
|
|
66
|
-
});
|
|
67
|
-
let res: Awaited<typeof read> | typeof OVER_BUDGET;
|
|
68
|
-
try {
|
|
69
|
-
res = await Promise.race([read, budget]);
|
|
70
|
-
} finally {
|
|
71
|
-
clearTimeout(timer);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (res === OVER_BUDGET) {
|
|
75
|
-
console.error({ event: "shown-offerings", outcome: "over_budget" });
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
if (res === null) return null;
|
|
79
|
-
if (!res.ok) {
|
|
80
|
-
console.error({
|
|
81
|
-
event: "shown-offerings",
|
|
82
|
-
outcome: "refused",
|
|
83
|
-
status: res.status,
|
|
84
|
-
});
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
const parsed = shownOfferingsAnswerSchema.safeParse(res.body);
|
|
88
|
-
if (!parsed.success) {
|
|
89
|
-
console.error({ event: "shown-offerings", outcome: "unreadable" });
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
return currentShownSet(parsed.data);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Logs a shown-set mapping that threw (D12): the tool then answers its
|
|
97
|
-
* content path, so no `ZodError` message ever reaches the agent.
|
|
98
|
-
*/
|
|
99
|
-
export function reportMappingFailure(err: unknown): void {
|
|
100
|
-
console.error({
|
|
101
|
-
event: "shown-offerings",
|
|
102
|
-
outcome: "mapping_failed",
|
|
103
|
-
errName: errName(err),
|
|
104
|
-
});
|
|
105
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The deployment's `_site.mdx`, read once per content root (#7169).
|
|
3
|
-
*
|
|
4
|
-
* `read_content` answers through `readContentDocument` in
|
|
5
|
-
* `@working-theory/content-adapters`, which takes the parsed site config for
|
|
6
|
-
* the `HomePage` graph and the `origin` read. That package may not import
|
|
7
|
-
* `@working-theory/site-config` (`architecture.yaml`), so the read stays with
|
|
8
|
-
* each app: this is the same reader `apps/api/src/routes/content/get-page.ts`
|
|
9
|
-
* carries — the one duplication the import rule leaves, kept identical so a
|
|
10
|
-
* `HomePage` read through the tool is the route's to the byte. The rejected
|
|
11
|
-
* alternative, `@working-theory/aeo`'s `loadSitewideIdentity`, applies its own
|
|
12
|
-
* acceptance rules and a parent-directory fallback, which could make the two
|
|
13
|
-
* differ on an edge site.
|
|
14
|
-
*
|
|
15
|
-
* A local read with the client-safe `/schema` entry:
|
|
16
|
-
* `@working-theory/site-config/server` imports `server-only`, which throws
|
|
17
|
-
* outside a React Server Components runtime.
|
|
18
|
-
*/
|
|
19
|
-
import { readFileSync } from "node:fs";
|
|
20
|
-
import { join } from "node:path";
|
|
21
|
-
|
|
22
|
-
import {
|
|
23
|
-
SiteConfigSchema,
|
|
24
|
-
type SiteConfig,
|
|
25
|
-
} from "@working-theory/site-config/schema";
|
|
26
|
-
import { parse as parseYaml } from "yaml";
|
|
27
|
-
|
|
28
|
-
const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
29
|
-
|
|
30
|
-
/** `_site.mdx` per content root, read once; `null` when it does not load. */
|
|
31
|
-
const siteConfigByRoot = new Map<string, SiteConfig | null>();
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The deployment's `_site.mdx`, validated against `SiteConfigSchema`, or
|
|
35
|
-
* `undefined` on any failure (absent, unreadable, invalid).
|
|
36
|
-
*/
|
|
37
|
-
export function readSiteConfig(contentRoot: string): SiteConfig | undefined {
|
|
38
|
-
if (!siteConfigByRoot.has(contentRoot)) {
|
|
39
|
-
let config: SiteConfig | null = null;
|
|
40
|
-
try {
|
|
41
|
-
const raw = readFileSync(join(contentRoot, "_site.mdx"), "utf8");
|
|
42
|
-
const match = FRONTMATTER_RE.exec(raw);
|
|
43
|
-
if (match) {
|
|
44
|
-
const parsed = SiteConfigSchema.safeParse(parseYaml(match[1] ?? ""));
|
|
45
|
-
if (parsed.success) config = parsed.data;
|
|
46
|
-
}
|
|
47
|
-
} catch {
|
|
48
|
-
// Absent or unreadable — no site.
|
|
49
|
-
}
|
|
50
|
-
siteConfigByRoot.set(contentRoot, config);
|
|
51
|
-
}
|
|
52
|
-
return siteConfigByRoot.get(contentRoot) ?? undefined;
|
|
53
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* stripe-tax-signal — reads `commerce.stripe_tax` from project.yaml (#5949 D4).
|
|
3
|
-
*
|
|
4
|
-
* The declaration the audit's `tax-code-when-stripe-tax` rule grades against:
|
|
5
|
-
* "this site's Stripe account has Stripe Tax enabled, so every priced page owes
|
|
6
|
-
* a `stripe.taxCode`". Declarative only — nothing here calls Stripe, and no
|
|
7
|
-
* license claim is read.
|
|
8
|
-
*
|
|
9
|
-
* The actual YAML read + field extraction delegates to `loadCommerceConfig`
|
|
10
|
-
* (`@working-theory/aeo`, exported from the package root since #6012) — this
|
|
11
|
-
* file's own job is the directory PROBE: apps run from their own dirs in
|
|
12
|
-
* dev/build (`apps/mcp/`) but from repo root in some test setups, mirroring
|
|
13
|
-
* `apps/mcp/src/lib/locales.ts`'s own project.yaml probe (the same three
|
|
14
|
-
* candidates it walks; `apps/*` may not import `apps/*`, so a shared probe
|
|
15
|
-
* helper isn't an option either — only the parse/extract logic was the
|
|
16
|
-
* duplicate #6012 removes).
|
|
17
|
-
*
|
|
18
|
-
* NEVER throws. An unreadable, absent, malformed or non-boolean value all
|
|
19
|
-
* resolve to `undefined` — the site declares no Stripe Tax posture, and the
|
|
20
|
-
* rule passes saying so.
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
import { readFileSync } from "node:fs";
|
|
24
|
-
import { dirname, join } from "node:path";
|
|
25
|
-
|
|
26
|
-
import { loadCommerceConfig } from "@working-theory/aeo";
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Probe likely locations for project.yaml. Apps run from their own dirs in
|
|
30
|
-
* dev/build (`apps/mcp/`) but from repo root in some test setups — the same
|
|
31
|
-
* three candidates `locales.ts` walks.
|
|
32
|
-
*/
|
|
33
|
-
function resolveProjectYamlPath(cwd: string): string {
|
|
34
|
-
const candidates = [
|
|
35
|
-
join(cwd, "project.yaml"),
|
|
36
|
-
join(cwd, "..", "project.yaml"),
|
|
37
|
-
join(cwd, "..", "..", "project.yaml"),
|
|
38
|
-
];
|
|
39
|
-
for (const candidate of candidates) {
|
|
40
|
-
try {
|
|
41
|
-
readFileSync(candidate, "utf8");
|
|
42
|
-
return candidate;
|
|
43
|
-
} catch {
|
|
44
|
-
// continue
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return candidates[0] ?? join(cwd, "project.yaml");
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* `commerce.stripe_tax` at `projectRoot` (default: the process cwd), or
|
|
52
|
-
* `undefined` when the site declares none.
|
|
53
|
-
*/
|
|
54
|
-
export function readStripeTaxSignal(
|
|
55
|
-
projectRoot: string = process.cwd(),
|
|
56
|
-
): boolean | undefined {
|
|
57
|
-
const resolvedPath = resolveProjectYamlPath(projectRoot);
|
|
58
|
-
return loadCommerceConfig(dirname(resolvedPath)).stripeTaxEnabled;
|
|
59
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-request context for @working-theory/mcp, shared by the HTTP transport
|
|
3
|
-
* and the MCP lead-write tools (#8073).
|
|
4
|
-
*
|
|
5
|
-
* Deliberately dependency-free beyond `@working-theory/api-client` (already
|
|
6
|
-
* loaded by every tool): `http-transport.ts` imports Fastify and the full
|
|
7
|
-
* HTTP stack, and `src/index.ts`'s stdio branch dynamic-imports `server.js`
|
|
8
|
-
* specifically to avoid loading that stack for a local stdio caller. A tool
|
|
9
|
-
* importing `trustedCallerAddress` straight from `http-transport.ts` would
|
|
10
|
-
* pull Fastify into every stdio boot and, worse, close an import cycle
|
|
11
|
-
* (`http-transport.ts` → `server.ts` → `tools/*.ts` → `http-transport.ts`).
|
|
12
|
-
* This module sits below both: `http-transport.ts` populates the store,
|
|
13
|
-
* the tools read it, neither imports the other.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
17
|
-
|
|
18
|
-
import { visitorForwardHeaders } from "@working-theory/api-client";
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* The caller address the transport trusted for the POST request currently
|
|
22
|
-
* being handled — `request.ip`, Fastify's own `trustProxy`-resolved value
|
|
23
|
-
* (the Vercel entry trusts exactly one hop, #8070 D5), never the raw,
|
|
24
|
-
* caller-forgeable leftmost `X-Forwarded-For` entry. Populated by
|
|
25
|
-
* `http-transport.ts` for the duration of one `transport.handleRequest()`
|
|
26
|
-
* call and read by the three MCP lead-write tools (#8073) so they can
|
|
27
|
-
* forward it to the hub without the tool gaining an identity argument.
|
|
28
|
-
* `undefined` outside an HTTP request — stdio has no client address to
|
|
29
|
-
* forward.
|
|
30
|
-
*/
|
|
31
|
-
export const trustedCallerAddress = new AsyncLocalStorage<string>();
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The two visitor-forwarding headers (`x-ailk-visitor-ip`,
|
|
35
|
-
* `x-ailk-visitor-forward-key`) for the request this call is running inside,
|
|
36
|
-
* or `undefined` when there is no trusted address for this call (not an HTTP
|
|
37
|
-
* request), no `AILK_VISITOR_FORWARD_KEY`, or `visitorForwardHeaders` itself
|
|
38
|
-
* declines (an unsafe transport, an unsafe key value). Read by the lead-write
|
|
39
|
-
* tools right before they call the hub (#8073).
|
|
40
|
-
*/
|
|
41
|
-
export function visitorForwardHeadersForThisCall():
|
|
42
|
-
| Record<string, string>
|
|
43
|
-
| undefined {
|
|
44
|
-
const address = trustedCallerAddress.getStore();
|
|
45
|
-
if (!address) return undefined;
|
|
46
|
-
return visitorForwardHeaders(
|
|
47
|
-
{
|
|
48
|
-
get: (name: string) => (name === "x-forwarded-for" ? address : null),
|
|
49
|
-
},
|
|
50
|
-
process.env.AILK_VISITOR_FORWARD_KEY,
|
|
51
|
-
);
|
|
52
|
-
}
|
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP server factory.
|
|
3
|
-
*
|
|
4
|
-
* Creates and configures the McpServer instance with all registered tools.
|
|
5
|
-
* The server is returned unconnected — callers attach a transport (stdio in
|
|
6
|
-
* production, in-memory in tests).
|
|
7
|
-
*
|
|
8
|
-
* Tool names + descriptions + input shapes come from the canonical catalog
|
|
9
|
-
* exported by `@working-theory/metadata` (issue #209). The catalog is the single source
|
|
10
|
-
* of truth shared with `apps/web /.well-known/mcp` for agent discovery.
|
|
11
|
-
* Handlers continue to live in `apps/mcp/src/tools/*` — this module wires
|
|
12
|
-
* each catalog entry to its handler.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
16
|
-
import {
|
|
17
|
-
getMcpToolRegistrations,
|
|
18
|
-
OSS_DISABLED_TOOLS,
|
|
19
|
-
type McpCatalogOptions,
|
|
20
|
-
type McpToolRegistration,
|
|
21
|
-
} from "@working-theory/metadata";
|
|
22
|
-
|
|
23
|
-
import { isModuleEnabled } from "./config/modules.js";
|
|
24
|
-
import {
|
|
25
|
-
mcpCommerceClaim,
|
|
26
|
-
mcpFeatureGateOverride,
|
|
27
|
-
mcpHeldFeatures,
|
|
28
|
-
} from "./lib/commerce-claim.js";
|
|
29
|
-
import { notFoundError } from "./lib/errors.js";
|
|
30
|
-
import { UNSERVED_MCP_TOOLS } from "./lib/topology.generated.js";
|
|
31
|
-
import { ailkAudit } from "./tools/audit.js";
|
|
32
|
-
import { ailkCaptureLead } from "./tools/capture_lead.js";
|
|
33
|
-
import { ailkCreateProject } from "./tools/create_project.js";
|
|
34
|
-
import { ailkGetBusinessHours } from "./tools/get_business_hours.js";
|
|
35
|
-
import { ailkGetFaq } from "./tools/get_faq.js";
|
|
36
|
-
import { ailkGetLocations } from "./tools/get_locations.js";
|
|
37
|
-
import { ailkGetOfferings } from "./tools/get_offerings.js";
|
|
38
|
-
import { ailkGetPricing } from "./tools/get_pricing.js";
|
|
39
|
-
import { ailkGetSiteInfo } from "./tools/get_site_info.js";
|
|
40
|
-
import { ailkListPages } from "./tools/list_pages.js";
|
|
41
|
-
import { ailkPurchase } from "./tools/purchase.js";
|
|
42
|
-
import { ailkReadContent } from "./tools/read_content.js";
|
|
43
|
-
import { ailkRequestCallback } from "./tools/request_callback.js";
|
|
44
|
-
import { ailkSearchContent } from "./tools/search_content.js";
|
|
45
|
-
import { ailkSubscribeNewsletter } from "./tools/subscribe_newsletter.js";
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Tool-name → handler map. Each handler accepts the parsed input the SDK
|
|
49
|
-
* passes through after Zod validation against the catalog input shape.
|
|
50
|
-
*
|
|
51
|
-
* Cast via `never` is safe: each handler validates its input via its own
|
|
52
|
-
* Zod parse before doing real work (see apps/mcp/src/tools/*.ts).
|
|
53
|
-
*/
|
|
54
|
-
const HANDLERS: Record<string, (input: unknown) => Promise<unknown>> = {
|
|
55
|
-
start_purchase: (input) => ailkPurchase(input as never),
|
|
56
|
-
list_pages: (input) => ailkListPages(input as never),
|
|
57
|
-
read_content: (input) => ailkReadContent(input as never),
|
|
58
|
-
search_content: (input) => ailkSearchContent(input as never),
|
|
59
|
-
get_site_info: (input) => ailkGetSiteInfo(input as never),
|
|
60
|
-
get_business_hours: (input) => ailkGetBusinessHours(input as never),
|
|
61
|
-
get_locations: (input) => ailkGetLocations(input as never),
|
|
62
|
-
get_offerings: (input) => ailkGetOfferings(input as never),
|
|
63
|
-
get_pricing: (input) => ailkGetPricing(input as never),
|
|
64
|
-
get_faq: (input) => ailkGetFaq(input as never),
|
|
65
|
-
audit: (input) => {
|
|
66
|
-
const { slug, type, url } = input as {
|
|
67
|
-
slug?: string;
|
|
68
|
-
type?: string;
|
|
69
|
-
url?: string;
|
|
70
|
-
};
|
|
71
|
-
const handlerInput = url !== undefined ? { url } : { slug: slug!, type };
|
|
72
|
-
return ailkAudit(handlerInput as never);
|
|
73
|
-
},
|
|
74
|
-
capture_lead: (input) => ailkCaptureLead(input as never),
|
|
75
|
-
subscribe_newsletter: (input) => ailkSubscribeNewsletter(input as never),
|
|
76
|
-
request_callback: (input) => ailkRequestCallback(input as never),
|
|
77
|
-
create_project: (input) => ailkCreateProject(input as never),
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
type ToolHandler = (input: unknown) => Promise<unknown>;
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Module-conditional tool handlers — the FILE-grain half of S1's registration
|
|
84
|
-
* gate (#5182).
|
|
85
|
-
*
|
|
86
|
-
* `shouldRegister` already keeps a paid module's tools out of the registered
|
|
87
|
-
* catalog when the module is absent, but that is a RUNTIME filter: a static
|
|
88
|
-
* `import` of the handler still pins the file into the TYPE graph, so an OSS
|
|
89
|
-
* strip that deletes it reds `tsc`. A literal `await import()` does not help —
|
|
90
|
-
* `import()` defers evaluation, not resolution, so `tsc` resolves the specifier
|
|
91
|
-
* either way and reports TS2307 once the file is gone.
|
|
92
|
-
*
|
|
93
|
-
* The specifier therefore comes from this table rather than being written
|
|
94
|
-
* inline, which is what makes it non-literal at the call site and so
|
|
95
|
-
* unresolvable by `tsc`. The cast in {@link resolveHandler} is the load-bearing
|
|
96
|
-
* line: `import(nonLiteral)` yields `any`, and the cast is the only thing
|
|
97
|
-
* restoring a type at the module boundary.
|
|
98
|
-
*
|
|
99
|
-
* Every entry here is a slice file the strip deletes; every entry's catalog
|
|
100
|
-
* row carries the matching `module` tag, so `shouldRegister` and this table
|
|
101
|
-
* appear or vanish together.
|
|
102
|
-
*/
|
|
103
|
-
const MODULE_TOOL_ENTRIES: Record<
|
|
104
|
-
string,
|
|
105
|
-
{ readonly specifier: string; readonly exportName: string }
|
|
106
|
-
> = {
|
|
107
|
-
// #4416 — the scheduling twins of GET /v1/schedule/availability and
|
|
108
|
-
// POST /v1/schedule/book. Anonymous, identity-blind, credential-free: the
|
|
109
|
-
// scheduling credential lives in apps/api, which these reach via api-client.
|
|
110
|
-
list_availability: {
|
|
111
|
-
specifier: "./tools/list_availability.js",
|
|
112
|
-
exportName: "ailkListAvailability",
|
|
113
|
-
},
|
|
114
|
-
get_event_meta: {
|
|
115
|
-
specifier: "./tools/get_event_meta.js",
|
|
116
|
-
exportName: "ailkGetEventMeta",
|
|
117
|
-
},
|
|
118
|
-
create_booking: {
|
|
119
|
-
specifier: "./tools/create_booking.js",
|
|
120
|
-
exportName: "ailkCreateBooking",
|
|
121
|
-
},
|
|
122
|
-
// #8843 D5 — the twin of GET /v1/schedule/meetings.
|
|
123
|
-
list_meetings: {
|
|
124
|
-
specifier: "./tools/list_meetings.js",
|
|
125
|
-
exportName: "ailkListMeetings",
|
|
126
|
-
},
|
|
127
|
-
// D-48 signal-collectors — the flow engine's MCP twins of GET
|
|
128
|
-
// /v1/flows/:slug and POST /v1/flows/:slug/steps. Anonymous, identity-blind;
|
|
129
|
-
// free-anonymous status is now module-gated rather than unconditional.
|
|
130
|
-
get_flow: { specifier: "./tools/get_flow.js", exportName: "ailkGetFlow" },
|
|
131
|
-
submit_flow_step: {
|
|
132
|
-
specifier: "./tools/submit_flow_step.js",
|
|
133
|
-
exportName: "ailkSubmitFlowStep",
|
|
134
|
-
},
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Resolves a tool name to its handler: the statically-imported map first, then
|
|
139
|
-
* the module-conditional table. Called from inside the already-`async`
|
|
140
|
-
* `server.tool` callback so {@link createMcpServer} stays synchronous — seven
|
|
141
|
-
* files call it that way, one of them production (`src/index.ts`), and making
|
|
142
|
-
* it async would rewrite all seven for no gain.
|
|
143
|
-
*/
|
|
144
|
-
async function resolveHandler(name: string): Promise<ToolHandler> {
|
|
145
|
-
const direct = HANDLERS[name];
|
|
146
|
-
if (direct) return direct;
|
|
147
|
-
|
|
148
|
-
const entry = MODULE_TOOL_ENTRIES[name];
|
|
149
|
-
if (!entry) {
|
|
150
|
-
throw new Error(`MCP catalog drift: no handler for tool '${name}'`);
|
|
151
|
-
}
|
|
152
|
-
const mod = (await import(entry.specifier)) as Record<
|
|
153
|
-
string,
|
|
154
|
-
ToolHandler | undefined
|
|
155
|
-
>;
|
|
156
|
-
const fn = mod[entry.exportName];
|
|
157
|
-
if (!fn) {
|
|
158
|
-
throw new Error(
|
|
159
|
-
`MCP slice drift: '${entry.specifier}' does not export '${entry.exportName}'`,
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
return fn;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Tool descriptor returned by {@link listRegisteredTools}. A minimal shape
|
|
167
|
-
* sufficient for callers that need to assert which tools are registered
|
|
168
|
-
* (e.g., the S15a regression test) without depending on the SDK's internal
|
|
169
|
-
* `_registeredTools` field.
|
|
170
|
-
*/
|
|
171
|
-
export interface RegisteredToolDescriptor {
|
|
172
|
-
name: string;
|
|
173
|
-
description: string;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Whether a catalog registration entry should register on this build/boot —
|
|
178
|
-
* four filters:
|
|
179
|
-
*
|
|
180
|
-
* 0. the topology filter (#8070 D7): a name in the generated seam's
|
|
181
|
-
* `UNSERVED_MCP_TOOLS` is never served — `create_project` on a spoke,
|
|
182
|
-
* which carries no create-ailk CLI for it to spawn. `[]` on a hub. The
|
|
183
|
-
* web manifest drops the same list, so the two surfaces agree;
|
|
184
|
-
* 1. the OSS-disabled filter (static per-name set; empty since #5971);
|
|
185
|
-
* 2. the module-presence filter (S1, #5088): a tool tagged with `module`
|
|
186
|
-
* (e.g. `create_booking` carrying `module: "scheduling"`) registers only
|
|
187
|
-
* when {@link isModuleEnabled} says its module is present, the same way
|
|
188
|
-
* its `apps/api` HTTP route is module-conditional in `server.ts` there —
|
|
189
|
-
* so a tool and its route appear or vanish together, holding API↔MCP
|
|
190
|
-
* parity;
|
|
191
|
-
* 3. the ADD-ON CLAIM filter (#5971): a tool tagged `addon: "commerce"`
|
|
192
|
-
* registers only on a deployment that positively holds the `commerce`
|
|
193
|
-
* licence claim. Deliberately NOT the module filter — D-64/#5796 moved
|
|
194
|
-
* the commerce primitives off module gating precisely so that adding
|
|
195
|
-
* commerce to a live site is a licence change that lands no files on its
|
|
196
|
-
* repo, and "keyless site" / "keyed site" name the LICENCE, not an env
|
|
197
|
-
* allowlist.
|
|
198
|
-
*
|
|
199
|
-
* The claim is the memoised claim, re-read every `MCP_CLAIM_REFRESH_MS`; this
|
|
200
|
-
* stays synchronous — see `lib/commerce-claim.ts`. {@link isServedNow}
|
|
201
|
-
* re-applies this filter at call time.
|
|
202
|
-
*
|
|
203
|
-
* The LICENCE-FEATURE gate (#7136) is not repeated here: it applies upstream,
|
|
204
|
-
* in `getMcpToolRegistrations()`, through {@link catalogOptionsForThisBoot} —
|
|
205
|
-
* only the catalog knows `MCP_FEATURE_GATE_MODE`. `catalog-drift.test.ts`
|
|
206
|
-
* pins that upstream filter from this side in every claim state.
|
|
207
|
-
*/
|
|
208
|
-
function shouldRegister(reg: {
|
|
209
|
-
name: string;
|
|
210
|
-
module?: string;
|
|
211
|
-
addon?: "commerce";
|
|
212
|
-
}): boolean {
|
|
213
|
-
if (UNSERVED_MCP_TOOLS.includes(reg.name)) return false;
|
|
214
|
-
if (OSS_DISABLED_TOOLS.has(reg.name)) return false;
|
|
215
|
-
if (reg.module && !isModuleEnabled(reg.module)) return false;
|
|
216
|
-
if (reg.addon === "commerce" && mcpCommerceClaim() !== "claimed")
|
|
217
|
-
return false;
|
|
218
|
-
return true;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Call-time gate (#7315). True when a server built NOW would register this
|
|
223
|
-
* tool — the exact same predicate {@link listRegisteredTools} computes, so
|
|
224
|
-
* the call-time answer and a fresh session's `tools/list` cannot disagree by
|
|
225
|
-
* construction. A session keeps the tool list it registered at `initialize`;
|
|
226
|
-
* this makes each listed entry refuse within `MCP_CLAIM_REFRESH_MS` of a
|
|
227
|
-
* re-read that drops its claim.
|
|
228
|
-
*/
|
|
229
|
-
function isServedNow(reg: McpToolRegistration): boolean {
|
|
230
|
-
return listRegisteredTools().some((current) => current.name === reg.name);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* The {@link McpCatalogOptions} this boot's claims imply — passed to
|
|
235
|
-
* `getMcpToolRegistrations()` so the upstream catalog filter and
|
|
236
|
-
* {@link shouldRegister} agree by construction rather than by coincidence.
|
|
237
|
-
* Carries the held licence features (#7136); the gate mode is the catalog's
|
|
238
|
-
* `MCP_FEATURE_GATE_MODE` unless a test has overridden it.
|
|
239
|
-
*/
|
|
240
|
-
function catalogOptionsForThisBoot(): McpCatalogOptions {
|
|
241
|
-
const featureGate = mcpFeatureGateOverride();
|
|
242
|
-
return {
|
|
243
|
-
addons: { commerce: mcpCommerceClaim() === "claimed" },
|
|
244
|
-
features: [...mcpHeldFeatures()],
|
|
245
|
-
...(featureGate ? { featureGate } : {}),
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* The one-release warning cycle's boot report (#7136): for every tool this
|
|
251
|
-
* boot serves whose licence `feature` the deployment does not hold, calls
|
|
252
|
-
* `warn` once, naming the tool and the feature, and returns their names.
|
|
253
|
-
*
|
|
254
|
-
* Called ONCE per process from `bootMcp()` (`boot.ts`, which both `index.ts`
|
|
255
|
-
* and the Vercel entry `app.ts` await), after the claim resolves — never
|
|
256
|
-
* from {@link createMcpServer}, which runs once per HTTP session. In refuse
|
|
257
|
-
* mode it finds nothing: the upstream catalog filter has already dropped
|
|
258
|
-
* every such tool, so it needs no mode check of its own. Defaults to
|
|
259
|
-
* `console.warn` — stderr, never stdout, which is the stdio transport's
|
|
260
|
-
* JSON-RPC channel. The message carries two catalog literals and nothing
|
|
261
|
-
* read from the licence.
|
|
262
|
-
*/
|
|
263
|
-
export function reportUnlicensedProTools(
|
|
264
|
-
warn: (message: string) => void = console.warn,
|
|
265
|
-
): string[] {
|
|
266
|
-
const held = mcpHeldFeatures();
|
|
267
|
-
const unlicensed = getMcpToolRegistrations(catalogOptionsForThisBoot())
|
|
268
|
-
.filter(shouldRegister)
|
|
269
|
-
.filter((reg) => reg.feature !== undefined && !held.has(reg.feature));
|
|
270
|
-
for (const reg of unlicensed) {
|
|
271
|
-
warn(
|
|
272
|
-
`[mcp] licence feature "${reg.feature}" is not held by this deployment — ` +
|
|
273
|
-
`tool "${reg.name}" is served in this release only; the next release ` +
|
|
274
|
-
`stops serving it unless the licence includes "${reg.feature}".`,
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
return unlicensed.map((reg) => reg.name);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Returns the list of tools that {@link createMcpServer} will register, after
|
|
282
|
-
* the OSS catalog filter ({@link OSS_DISABLED_TOOLS}), the module-presence
|
|
283
|
-
* filter and the add-on claim filter are applied. Pure — no server instance
|
|
284
|
-
* is constructed.
|
|
285
|
-
*
|
|
286
|
-
* Consumed by `apps/mcp/__tests__/purchase-disabled.test.ts`, which drives
|
|
287
|
-
* both halves of the claim matrix: `start_purchase` absent on a keyless boot,
|
|
288
|
-
* present on a claimed one.
|
|
289
|
-
*/
|
|
290
|
-
export function listRegisteredTools(): RegisteredToolDescriptor[] {
|
|
291
|
-
return getMcpToolRegistrations(catalogOptionsForThisBoot())
|
|
292
|
-
.filter(shouldRegister)
|
|
293
|
-
.map((reg) => ({ name: reg.name, description: reg.description }));
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Creates a configured McpServer with all AILK tools registered, less any
|
|
298
|
-
* tool this topology does not serve (`UNSERVED_MCP_TOOLS`, #8070 D7), less any
|
|
299
|
-
* tool name in {@link OSS_DISABLED_TOOLS}, less any tool whose `module` is
|
|
300
|
-
* not enabled on this build (S1, #5088), and less any `addon`-tagged tool
|
|
301
|
-
* whose claim this deployment does not hold (#5971) — see
|
|
302
|
-
* {@link shouldRegister}. Every filter is applied defensively here even
|
|
303
|
-
* though the upstream `getMcpToolRegistrations()` already excludes the same
|
|
304
|
-
* entries: a belt-and-braces guard so a regression in the metadata package
|
|
305
|
-
* can't accidentally register something this boot should not serve.
|
|
306
|
-
*/
|
|
307
|
-
export function createMcpServer(): McpServer {
|
|
308
|
-
const server = new McpServer({
|
|
309
|
-
name: "ailk",
|
|
310
|
-
version: "0.1.0",
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
for (const reg of getMcpToolRegistrations(catalogOptionsForThisBoot())) {
|
|
314
|
-
if (!shouldRegister(reg)) {
|
|
315
|
-
continue;
|
|
316
|
-
}
|
|
317
|
-
// Boot-time drift detection is preserved: a registered name must be
|
|
318
|
-
// resolvable from ONE of the two tables, checked here rather than at first
|
|
319
|
-
// invocation, so a catalog/handler mismatch still fails at startup.
|
|
320
|
-
if (!HANDLERS[reg.name] && !MODULE_TOOL_ENTRIES[reg.name]) {
|
|
321
|
-
throw new Error(`MCP catalog drift: no handler for tool '${reg.name}'`);
|
|
322
|
-
}
|
|
323
|
-
server.tool(reg.name, reg.description, reg.inputShape, async (input) => {
|
|
324
|
-
if (
|
|
325
|
-
(reg.feature !== undefined || reg.addon !== undefined) &&
|
|
326
|
-
!isServedNow(reg)
|
|
327
|
-
) {
|
|
328
|
-
return {
|
|
329
|
-
content: [
|
|
330
|
-
{ type: "text", text: JSON.stringify(notFoundError("Not found")) },
|
|
331
|
-
],
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
const handler = await resolveHandler(reg.name);
|
|
335
|
-
const result = await handler(input);
|
|
336
|
-
return {
|
|
337
|
-
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
338
|
-
};
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
return server;
|
|
343
|
-
}
|