create-ailk 0.5.0 → 0.6.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 +55 -8
- package/component-catalog.json +336 -27
- package/component-catalog.md +25 -12
- package/dist/lib/api-boot-assertion.d.ts +46 -0
- package/dist/lib/api-boot-assertion.js +70 -0
- package/dist/lib/import-graph.d.ts +29 -0
- package/dist/lib/import-graph.js +140 -0
- package/dist/module-architecture.d.ts +1 -0
- package/dist/module-architecture.js +253 -127
- package/dist/surfaces.js +105 -7
- package/dist/template-manifest.d.ts +33 -0
- package/dist/template-manifest.js +99 -16
- package/dist/template-names.d.ts +1 -1
- package/dist/template-names.js +1 -0
- package/package.json +3 -2
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +22 -2
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +9 -2
- package/site-templates/marketing-site/ailk-template.json +1 -1
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +2 -2
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +1 -0
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +10 -2
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +47 -35
- package/site-templates/minimalism-site/ailk-template.json +2 -1
- package/site-templates/minimalism-site/assets/wordmark-placeholder.svg +28 -0
- package/site-templates/minimalism-site/content/en/HomePage/home.mdx +49 -19
- package/site-templates/simple-service/TEMPLATE-MANIFEST.json +240 -0
- package/site-templates/simple-service/TEMPLATE-MANIFEST.md +278 -0
- package/site-templates/simple-service/ailk-template.json +10 -0
- package/site-templates/simple-service/content/en/AboutPage/about.mdx +38 -0
- package/site-templates/simple-service/content/en/ContactPage/contact.mdx +67 -0
- package/site-templates/simple-service/content/en/FAQPage/faq.mdx +56 -0
- package/site-templates/simple-service/content/en/HomePage/home.mdx +85 -0
- package/site-templates/simple-service/content/en/Service/landscape-design.mdx +40 -0
- package/site-templates/simple-service/content/en/Service/lawn-maintenance.mdx +40 -0
- package/site-templates/simple-service/content/en/Service/seasonal-cleanup.mdx +40 -0
- package/site-templates/simple-service/content/en/ServicesList/services.mdx +72 -0
- package/site-templates/simple-service/provenance.json +4 -0
- package/templates/.env.example +72 -7
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-31.552Z-fallback-1789916251590-037e9005.json +8 -0
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.840Z-fallback-1789916253842-b52659e9.json +12 -0
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.844Z-fallback-1789916253845-6b266f8c.json +12 -0
- package/templates/apps/api/.env.example +13 -0
- package/templates/apps/api/CLAUDE.md +26 -2
- package/templates/apps/api/jest.config.cjs +3 -0
- package/templates/apps/api/package.json +1 -0
- package/templates/apps/api/src/__tests__/commerce-claim-registration.test.ts +407 -0
- package/templates/apps/api/src/__tests__/module-exclusion.test.ts +83 -7
- package/templates/apps/api/src/__tests__/server.test.ts +471 -0
- package/templates/apps/api/src/__tests__/vercel-handler.test.ts +45 -0
- package/templates/apps/api/src/__tests__/workspace-module-registration.test.ts +2 -0
- package/templates/apps/api/src/config/index.ts +62 -0
- package/templates/apps/api/src/config/modules.ts +7 -3
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +238 -2
- package/templates/apps/api/src/lib/__tests__/auth-email-budget.test.ts +143 -0
- package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +23 -0
- package/templates/apps/api/src/lib/__tests__/deliverable-asset-store.test.ts +125 -0
- package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +20 -0
- package/templates/apps/api/src/lib/__tests__/require-commerce-claim.test.ts +317 -0
- package/templates/apps/api/src/lib/__tests__/site.test.ts +238 -0
- package/templates/apps/api/src/lib/__tests__/stripe.test.ts +75 -0
- package/templates/apps/api/src/lib/auth-email-budget.ts +160 -0
- package/templates/apps/api/src/lib/content-adapter.ts +57 -31
- package/templates/apps/api/src/lib/deliverable-asset-store.ts +76 -0
- package/templates/apps/api/src/lib/error-serializer.ts +23 -3
- package/templates/apps/api/src/lib/outbound-http.ts +7 -2
- package/templates/apps/api/src/lib/require-commerce-claim.ts +250 -0
- package/templates/apps/api/src/lib/site.ts +208 -9
- package/templates/apps/api/src/lib/stripe.ts +66 -0
- package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +182 -0
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +42 -0
- package/templates/apps/api/src/middleware/rate-limit.ts +7 -1
- package/templates/apps/api/src/openapi/spec.ts +543 -2
- package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +48 -0
- package/templates/apps/api/src/routes/auth/__tests__/transactional-email.test.ts +309 -0
- package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +123 -0
- package/templates/apps/api/src/routes/auth/transactional-email.ts +273 -0
- package/templates/apps/api/src/routes/auth/user.ts +61 -0
- package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +434 -0
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +888 -0
- package/templates/apps/api/src/routes/checkout/index.ts +34 -0
- package/templates/apps/api/src/routes/checkout/session.ts +139 -0
- package/templates/apps/api/src/routes/checkout/sessions.ts +197 -0
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +554 -0
- package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +108 -0
- package/templates/apps/api/src/routes/content/__tests__/search.test.ts +450 -0
- package/templates/apps/api/src/routes/content/get-page.ts +94 -12
- package/templates/apps/api/src/routes/content/index.ts +13 -73
- package/templates/apps/api/src/routes/content/list-pages.ts +15 -3
- package/templates/apps/api/src/routes/content/rate-limit.ts +15 -6
- package/templates/apps/api/src/routes/content/search.ts +129 -0
- package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +447 -31
- package/templates/apps/api/src/routes/leads/index.ts +100 -13
- package/templates/apps/api/src/routes/project-listings/__tests__/configured-application.test.ts +51 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +351 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/founder-identity.test.ts +51 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +5 -2
- package/templates/apps/api/src/routes/project-listings/__tests__/public.test.ts +4 -1
- package/templates/apps/api/src/routes/project-listings/__tests__/resume-email.test.ts +58 -0
- package/templates/apps/api/src/routes/project-listings/__tests__/site-answers.test.ts +107 -6
- package/templates/apps/api/src/routes/project-listings/__tests__/site-key.test.ts +87 -2
- package/templates/apps/api/src/routes/project-listings/__tests__/structured-address.test.ts +51 -0
- package/templates/apps/api/src/routes/project-listings/start.ts +5 -1
- package/templates/apps/api/src/routes/requests/__tests__/confirm.test.ts +686 -0
- package/templates/apps/api/src/routes/requests/confirm.ts +601 -0
- package/templates/apps/api/src/routes/requests/index.ts +54 -0
- package/templates/apps/api/src/routes/webhooks/README.md +265 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-dunning.test.ts +749 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-flow-checkout.test.ts +330 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +262 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +285 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +213 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-request-paid.test.ts +301 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +648 -0
- package/templates/apps/api/src/routes/webhooks/index.ts +89 -0
- package/templates/apps/api/src/routes/webhooks/stripe.ts +1399 -0
- package/templates/apps/api/src/server.ts +439 -49
- package/templates/apps/api/src/services/__tests__/abandon-email.test.ts +39 -0
- package/templates/apps/api/src/services/__tests__/aeo-score.test.ts +217 -40
- package/templates/apps/api/src/services/__tests__/audit-log.test.ts +620 -0
- package/templates/apps/api/src/services/__tests__/consent.test.ts +2 -0
- package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +300 -5
- package/templates/apps/api/src/services/__tests__/deliverable-resend.test.ts +20 -0
- package/templates/apps/api/src/services/__tests__/dunning-policy.test.ts +368 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +160 -0
- package/templates/apps/api/src/services/__tests__/listing-config.test.ts +166 -0
- package/templates/apps/api/src/services/__tests__/project-listings.fence.test.ts +154 -0
- package/templates/apps/api/src/services/__tests__/public-site-resolver.test.ts +137 -0
- package/templates/apps/api/src/services/__tests__/request-confirm.test.ts +444 -0
- package/templates/apps/api/src/services/__tests__/revalidation.test.ts +238 -0
- package/templates/apps/api/src/services/__tests__/verified-email.test.ts +78 -0
- package/templates/apps/api/src/services/abandon-email.ts +8 -2
- package/templates/apps/api/src/services/aeo-score.ts +49 -12
- package/templates/apps/api/src/services/audit-log.ts +668 -0
- package/templates/apps/api/src/services/consent.ts +18 -0
- package/templates/apps/api/src/services/default-tenant.ts +70 -31
- package/templates/apps/api/src/services/deliverable-fulfillment.ts +141 -13
- package/templates/apps/api/src/services/dunning-policy.ts +294 -0
- package/templates/apps/api/src/services/entitlements.ts +80 -0
- package/templates/apps/api/src/services/lead-promotion.ts +13 -14
- package/templates/apps/api/src/services/lead-routing.ts +161 -2
- package/templates/apps/api/src/services/leads-inbox.ts +23 -2
- package/templates/apps/api/src/services/listing-config.ts +27 -9
- package/templates/apps/api/src/services/project-listings.ts +201 -6
- package/templates/apps/api/src/services/public-site-resolver.ts +106 -0
- package/templates/apps/api/src/services/request-confirm.ts +646 -0
- package/templates/apps/api/src/services/revalidation.ts +173 -0
- package/templates/apps/api/src/services/verified-email.ts +71 -0
- package/templates/apps/api/src/vercel-handler.ts +75 -35
- package/templates/apps/mcp/.env.example +17 -0
- package/templates/apps/mcp/CLAUDE.md +57 -24
- package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +6 -0
- package/templates/apps/mcp/__tests__/audit.test.ts +137 -8
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +79 -36
- package/templates/apps/mcp/__tests__/get_offerings.test.ts +111 -2
- package/templates/apps/mcp/__tests__/get_pricing.test.ts +82 -2
- package/templates/apps/mcp/__tests__/http-transport.test.ts +541 -2
- package/templates/apps/mcp/__tests__/index.test.ts +39 -0
- package/templates/apps/mcp/__tests__/lib/audit-single-page-readiness-scan.test.ts +143 -0
- package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +111 -0
- package/templates/apps/mcp/__tests__/lib/content-adapter-parity.test.ts +65 -0
- package/templates/apps/mcp/__tests__/lib/content-adapter.test.ts +188 -0
- package/templates/apps/mcp/__tests__/lib/fail-closed-tools.test.ts +165 -0
- package/templates/apps/mcp/__tests__/lib/public-workspace.test.ts +124 -0
- package/templates/apps/mcp/__tests__/list_pages.test.ts +116 -0
- package/templates/apps/mcp/__tests__/module-exclusion.test.ts +7 -1
- package/templates/apps/mcp/__tests__/parity.test.ts +10 -7
- package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +89 -22
- package/templates/apps/mcp/__tests__/read_content.test.ts +322 -1
- package/templates/apps/mcp/__tests__/search_content.test.ts +105 -2
- package/templates/apps/mcp/__tests__/server.test.ts +67 -14
- package/templates/apps/mcp/__tests__/start_purchase.test.ts +252 -0
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +300 -123
- package/templates/apps/mcp/jest.config.cjs +13 -0
- package/templates/apps/mcp/package.json +2 -0
- package/templates/apps/mcp/src/abuse/index.ts +159 -24
- package/templates/apps/mcp/src/config/modules.ts +10 -5
- package/templates/apps/mcp/src/http-transport.ts +102 -29
- package/templates/apps/mcp/src/index.ts +73 -11
- package/templates/apps/mcp/src/lib/audit-single-page.ts +90 -3
- package/templates/apps/mcp/src/lib/commerce-claim.ts +94 -0
- package/templates/apps/mcp/src/lib/content-adapter.ts +113 -0
- package/templates/apps/mcp/src/lib/empty-content-adapter.ts +139 -0
- package/templates/apps/mcp/src/lib/prisma.ts +39 -0
- package/templates/apps/mcp/src/lib/public-workspace.ts +133 -0
- package/templates/apps/mcp/src/lib/stripe-tax-signal.ts +59 -0
- package/templates/apps/mcp/src/server.ts +59 -35
- package/templates/apps/mcp/src/tools/audit.ts +26 -2
- package/templates/apps/mcp/src/tools/get_business_hours.ts +4 -3
- package/templates/apps/mcp/src/tools/get_faq.ts +4 -3
- package/templates/apps/mcp/src/tools/get_locations.ts +5 -3
- package/templates/apps/mcp/src/tools/get_offerings.ts +16 -4
- package/templates/apps/mcp/src/tools/get_pricing.ts +25 -6
- package/templates/apps/mcp/src/tools/get_site_info.ts +4 -3
- package/templates/apps/mcp/src/tools/index.ts +6 -4
- package/templates/apps/mcp/src/tools/list_pages.ts +4 -3
- package/templates/apps/mcp/src/tools/purchase.ts +128 -45
- package/templates/apps/mcp/src/tools/read_content.ts +20 -6
- package/templates/apps/mcp/src/tools/search_content.ts +11 -4
- package/templates/apps/web/.env.example +71 -5
- package/templates/apps/web/CLAUDE.md +44 -0
- package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +18 -2
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +11 -3
- package/templates/apps/web/app/[locale]/(auth)/__tests__/auth-pages.test.tsx +282 -0
- package/templates/apps/web/app/[locale]/(auth)/__tests__/password-reset.test.tsx +515 -0
- package/templates/apps/web/app/[locale]/(auth)/forgot-password/forgot-password-card.tsx +89 -0
- package/templates/apps/web/app/[locale]/(auth)/forgot-password/page.tsx +109 -0
- package/templates/apps/web/app/[locale]/(auth)/layout.tsx +92 -0
- package/templates/apps/web/app/[locale]/(auth)/reset-password/page.tsx +135 -0
- package/templates/apps/web/app/[locale]/(auth)/reset-password/reset-password-card.tsx +109 -0
- package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/__tests__/page.test.tsx +48 -2
- package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/page.tsx +20 -6
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +125 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +96 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +101 -0
- package/templates/apps/web/app/[locale]/(auth)/use-auth-card-flow.ts +102 -0
- package/templates/apps/web/app/[locale]/(auth)/verify-email/page.tsx +87 -0
- package/templates/apps/web/app/[locale]/(authed)/__tests__/gate.test.tsx +20 -10
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/page.test.tsx +84 -0
- package/templates/apps/web/app/[locale]/(authed)/account/actions.ts +58 -0
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +63 -8
- package/templates/apps/web/app/[locale]/(authed)/layout.tsx +18 -1
- package/templates/apps/web/app/[locale]/cancellation/page.tsx +44 -0
- package/templates/apps/web/app/[locale]/layout.tsx +133 -87
- package/templates/apps/web/app/[locale]/purchase/__tests__/cancel.test.tsx +162 -0
- package/templates/apps/web/app/[locale]/purchase/__tests__/module-scope.test.ts +68 -0
- package/templates/apps/web/app/[locale]/purchase/__tests__/success.test.tsx +361 -0
- package/templates/apps/web/app/[locale]/purchase/cancel/page.tsx +115 -0
- package/templates/apps/web/app/[locale]/purchase/success/page.tsx +307 -0
- package/templates/apps/web/app/[locale]/returns/page.tsx +44 -0
- package/templates/apps/web/app/[locale]/shipping/page.tsx +44 -0
- package/templates/apps/web/app/api/revalidate/__tests__/route.test.ts +670 -0
- package/templates/apps/web/app/api/revalidate/route.ts +194 -0
- package/templates/apps/web/auth.ts +407 -8
- package/templates/apps/web/jest.config.cjs +8 -4
- package/templates/apps/web/lib/__tests__/auth-email.test.ts +214 -0
- package/templates/apps/web/lib/__tests__/auth-routes.test.ts +74 -0
- package/templates/apps/web/lib/__tests__/meeting-slugs.test.ts +72 -0
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +18 -1
- package/templates/apps/web/lib/auth-email.ts +318 -0
- package/templates/apps/web/lib/auth-env.ts +85 -0
- package/templates/apps/web/lib/auth-routes.ts +55 -0
- package/templates/apps/web/lib/meeting-slugs.ts +53 -0
- package/templates/apps/web/lib/telemetry-scrub.ts +5 -1
- package/templates/apps/web/messages/en.json +187 -0
- package/templates/apps/web/package.json +2 -1
- package/templates/apps/web/src/lib/commerce-claim.ts +33 -0
- package/templates/apps/web/src/lib/commerce-sections.ts +61 -0
- package/templates/content/en/CancellationPolicyPage/cancellation.mdx +108 -0
- package/templates/content/en/ReturnsPolicyPage/returns.mdx +108 -0
- package/templates/content/en/ShippingPolicyPage/shipping.mdx +108 -0
- package/templates/database/CHANGELOG.md +142 -0
- package/templates/database/README.md +10 -3
- package/templates/database/__tests__/appointment.db.test.ts +106 -0
- package/templates/database/__tests__/artifact-content-store.db.test.ts +316 -0
- package/templates/database/__tests__/composite-fence.db.test.ts +206 -0
- package/templates/database/__tests__/fence-fan-out.db.test.ts +711 -0
- package/templates/database/__tests__/fixtures/appointment-create-probe.ts +79 -0
- package/templates/database/__tests__/fixtures/project-listing-consent-probe.ts +100 -0
- package/templates/database/__tests__/flow-workspace-key.db.test.ts +263 -0
- package/templates/database/__tests__/prefixed-ids.db.test.ts +85 -9
- package/templates/database/__tests__/project-listing-consent-at.db.test.ts +111 -0
- package/templates/database/__tests__/tenancy.test.ts +141 -0
- package/templates/database/config/schema.prisma +79 -2
- package/templates/database/content/schema.prisma +87 -11
- package/templates/database/inbox/schema.prisma +452 -9
- package/templates/database/jest.config.cjs +5 -3
- package/templates/database/migrations/20260915120000_project_listing_solution/migration.sql +15 -0
- package/templates/database/migrations/20260916120000_artifact_content_store/migration.sql +158 -0
- package/templates/database/migrations/20260917120000_callback_request_confirm/migration.sql +40 -0
- package/templates/database/migrations/20260918120000_add_appointment/migration.sql +67 -0
- package/templates/database/migrations/20260918120000_asset_metadata_columns/migration.sql +70 -0
- package/templates/database/migrations/20260919120000_flow_workspace_key/migration.sql +181 -0
- package/templates/database/migrations/20260919130000_flow_definition_admin_columns/migration.sql +172 -0
- package/templates/database/migrations/20260919130000_workspace_meetings/migration.sql +41 -0
- package/templates/database/migrations/20260919140000_inbox_workspace_key/migration.sql +185 -0
- package/templates/database/migrations/20260920120000_lead_handled_at/migration.sql +70 -0
- package/templates/database/migrations/20260920130000_lead_workspace_source_index/migration.sql +57 -0
- package/templates/database/migrations/20260921120000_deliverable_grant_workspace_key/migration.sql +68 -0
- package/templates/database/migrations/20260922120000_tenancy_fence/migration.sql +1067 -0
- package/templates/database/migrations/20260923120000_listing_capturing_magnet/migration.sql +210 -0
- package/templates/database/package.json +1 -1
- package/templates/database/tenancy.ts +86 -1
- package/templates/database/tsconfig.json +1 -0
- package/versions.json +34 -34
- package/templates/apps/api/src/routes/content/__tests__/create.test.ts +0 -253
- package/templates/apps/api/src/routes/content/__tests__/delete.test.ts +0 -215
- package/templates/apps/api/src/routes/content/__tests__/update.test.ts +0 -266
- package/templates/apps/api/src/routes/content/create.ts +0 -115
- package/templates/apps/api/src/routes/content/delete.ts +0 -82
- package/templates/apps/api/src/routes/content/update.ts +0 -112
- package/templates/apps/mcp/__tests__/create_page.test.ts +0 -202
- package/templates/apps/mcp/__tests__/delete_page.test.ts +0 -177
- package/templates/apps/mcp/__tests__/update_page.test.ts +0 -196
- package/templates/apps/mcp/src/tools/create_page.ts +0 -96
- package/templates/apps/mcp/src/tools/delete_page.ts +0 -74
- package/templates/apps/mcp/src/tools/update_page.ts +0 -92
- package/templates/apps/web/app/[locale]/sign-in/sign-in-card.tsx +0 -123
- /package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/__tests__/next-path.test.ts +0 -0
- /package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/next-path.ts +0 -0
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
// oss: false
|
|
2
|
-
/**
|
|
3
|
-
* create_page — Paid-tier MCP tool for authoring a new content page.
|
|
4
|
-
*
|
|
5
|
-
* D14a Stage 1 Unit C — wires the McpServer create_page handler to the
|
|
6
|
-
* ContentAdapter.createPage method (Stage 1 Unit A implements the MDX
|
|
7
|
-
* adapter; tests inject a fake adapter).
|
|
8
|
-
*
|
|
9
|
-
* Surface contract: validates input via FrontmatterSchema.extend({ body }),
|
|
10
|
-
* runs the Paid-tier license guard, calls adapter.createPage, and maps adapter
|
|
11
|
-
* errors to canonical MCP error bodies (see apps/mcp/src/lib/errors.ts).
|
|
12
|
-
*
|
|
13
|
-
* Input shape mirrors the Stage 0 catalog entry in
|
|
14
|
-
* packages/metadata/src/mcp-tool-catalog.ts. Catalog parses a permissive
|
|
15
|
-
* outer shape (`page: record`); this handler parses strictly via
|
|
16
|
-
* FrontmatterSchema so bad frontmatter surfaces as a validation_failed body.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import { join } from "node:path";
|
|
20
|
-
|
|
21
|
-
import {
|
|
22
|
-
FrontmatterSchema,
|
|
23
|
-
createMdxAdapter,
|
|
24
|
-
mapAdapterError,
|
|
25
|
-
type ContentAdapter,
|
|
26
|
-
} from "@working-theory/content-adapters";
|
|
27
|
-
import { z } from "zod";
|
|
28
|
-
|
|
29
|
-
import { validationError, type ErrorBody } from "../lib/errors.js";
|
|
30
|
-
import { requirePaidTier } from "../lib/require-paid-tier.js";
|
|
31
|
-
|
|
32
|
-
const CreatePageInputSchema = FrontmatterSchema.extend({
|
|
33
|
-
body: z.string().min(1),
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
interface CreatePageSuccess {
|
|
37
|
-
page: Record<string, unknown>;
|
|
38
|
-
version: string;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export type CreatePageResult = CreatePageSuccess | ErrorBody;
|
|
42
|
-
|
|
43
|
-
export interface CreatePageInput {
|
|
44
|
-
type: string;
|
|
45
|
-
slug: string;
|
|
46
|
-
page: Record<string, unknown>;
|
|
47
|
-
body: string;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* ailkCreatePage handler.
|
|
52
|
-
*
|
|
53
|
-
* Optional `adapter` injection mirrors the Q3 resolution in the resource plan
|
|
54
|
-
* (tests construct adapters directly with isolated content roots). When
|
|
55
|
-
* omitted, falls back to the default MDX adapter rooted at process.cwd()/content.
|
|
56
|
-
*/
|
|
57
|
-
export async function ailkCreatePage(
|
|
58
|
-
input: CreatePageInput,
|
|
59
|
-
adapter?: ContentAdapter,
|
|
60
|
-
): Promise<CreatePageResult> {
|
|
61
|
-
const guard = await requirePaidTier();
|
|
62
|
-
if (guard) return guard;
|
|
63
|
-
|
|
64
|
-
const parsed = CreatePageInputSchema.safeParse({
|
|
65
|
-
...input.page,
|
|
66
|
-
type: input.type,
|
|
67
|
-
slug: input.slug,
|
|
68
|
-
body: input.body,
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
if (!parsed.success) {
|
|
72
|
-
return validationError("Invalid frontmatter or body for create_page.", {
|
|
73
|
-
issues: parsed.error.issues,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const resolved =
|
|
78
|
-
adapter ??
|
|
79
|
-
createMdxAdapter({ contentRoot: join(process.cwd(), "content") });
|
|
80
|
-
|
|
81
|
-
try {
|
|
82
|
-
const result = await resolved.createPage(
|
|
83
|
-
parsed.data.type,
|
|
84
|
-
parsed.data.slug,
|
|
85
|
-
parsed.data,
|
|
86
|
-
);
|
|
87
|
-
return { page: result.page, version: result.version };
|
|
88
|
-
} catch (err) {
|
|
89
|
-
const mapped = mapAdapterError(err, {
|
|
90
|
-
type: parsed.data.type,
|
|
91
|
-
slug: parsed.data.slug,
|
|
92
|
-
});
|
|
93
|
-
if (mapped) return mapped;
|
|
94
|
-
throw err;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
// oss: false
|
|
2
|
-
/**
|
|
3
|
-
* delete_page — Paid-tier MCP tool for removing a content page.
|
|
4
|
-
*
|
|
5
|
-
* D14a Stage 1 Unit C — wires McpServer delete_page to ContentAdapter.deletePage.
|
|
6
|
-
* Mandatory optimistic locking: caller supplies `ifMatch`; stale or missing
|
|
7
|
-
* tokens yield canonical conflict bodies.
|
|
8
|
-
*
|
|
9
|
-
* Success body is `{ ok: true }` per the Stage 0 catalog `deletePageOutputSchema`.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { join } from "node:path";
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
SCHEMA_ORG_TYPES,
|
|
16
|
-
SLUG_PATTERN,
|
|
17
|
-
createMdxAdapter,
|
|
18
|
-
mapAdapterError,
|
|
19
|
-
type ContentAdapter,
|
|
20
|
-
} from "@working-theory/content-adapters";
|
|
21
|
-
import { z } from "zod";
|
|
22
|
-
|
|
23
|
-
import { validationError, type ErrorBody } from "../lib/errors.js";
|
|
24
|
-
import { requirePaidTier } from "../lib/require-paid-tier.js";
|
|
25
|
-
|
|
26
|
-
const DeletePageInputSchema = z.object({
|
|
27
|
-
type: z.enum(SCHEMA_ORG_TYPES),
|
|
28
|
-
// Defence-in-depth slug allowlist matches create_page / update_page;
|
|
29
|
-
// the adapter also enforces the pattern, but a fail-fast validation_failed
|
|
30
|
-
// here keeps the tool's surface contract consistent (issue #398).
|
|
31
|
-
slug: z.string().regex(SLUG_PATTERN),
|
|
32
|
-
ifMatch: z.string().min(1),
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
interface DeletePageSuccess {
|
|
36
|
-
ok: true;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export type DeletePageResult = DeletePageSuccess | ErrorBody;
|
|
40
|
-
|
|
41
|
-
export interface DeletePageInput {
|
|
42
|
-
type: string;
|
|
43
|
-
slug: string;
|
|
44
|
-
ifMatch: string;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export async function ailkDeletePage(
|
|
48
|
-
input: DeletePageInput,
|
|
49
|
-
adapter?: ContentAdapter,
|
|
50
|
-
): Promise<DeletePageResult> {
|
|
51
|
-
const guard = await requirePaidTier();
|
|
52
|
-
if (guard) return guard;
|
|
53
|
-
|
|
54
|
-
const parsed = DeletePageInputSchema.safeParse(input);
|
|
55
|
-
if (!parsed.success) {
|
|
56
|
-
return validationError("Invalid input for delete_page.", {
|
|
57
|
-
issues: parsed.error.issues,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const { type, slug, ifMatch } = parsed.data;
|
|
62
|
-
const resolved =
|
|
63
|
-
adapter ??
|
|
64
|
-
createMdxAdapter({ contentRoot: join(process.cwd(), "content") });
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
await resolved.deletePage(type, slug, { ifMatch });
|
|
68
|
-
return { ok: true };
|
|
69
|
-
} catch (err) {
|
|
70
|
-
const mapped = mapAdapterError(err, { type, slug });
|
|
71
|
-
if (mapped) return mapped;
|
|
72
|
-
throw err;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
// oss: false
|
|
2
|
-
/**
|
|
3
|
-
* update_page — Paid-tier MCP tool for revising an existing content page.
|
|
4
|
-
*
|
|
5
|
-
* D14a Stage 1 Unit C — wires McpServer update_page to ContentAdapter.updatePage.
|
|
6
|
-
* Mandatory optimistic locking: caller supplies `ifMatch` (version token from a
|
|
7
|
-
* prior read or write); stale or missing tokens yield canonical conflict bodies.
|
|
8
|
-
*
|
|
9
|
-
* Validation strategy mirrors create_page — strict parse via
|
|
10
|
-
* FrontmatterSchema.extend({ body, ifMatch }) inside the handler so bad
|
|
11
|
-
* frontmatter surfaces as validation_failed (the Stage 0 catalog uses a
|
|
12
|
-
* permissive outer shape because @working-theory/metadata cannot import
|
|
13
|
-
* @working-theory/content-adapters).
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { join } from "node:path";
|
|
17
|
-
|
|
18
|
-
import {
|
|
19
|
-
FrontmatterSchema,
|
|
20
|
-
createMdxAdapter,
|
|
21
|
-
mapAdapterError,
|
|
22
|
-
type ContentAdapter,
|
|
23
|
-
} from "@working-theory/content-adapters";
|
|
24
|
-
import { z } from "zod";
|
|
25
|
-
|
|
26
|
-
import { validationError, type ErrorBody } from "../lib/errors.js";
|
|
27
|
-
import { requirePaidTier } from "../lib/require-paid-tier.js";
|
|
28
|
-
|
|
29
|
-
const UpdatePageInputSchema = FrontmatterSchema.extend({
|
|
30
|
-
body: z.string().min(1),
|
|
31
|
-
ifMatch: z.string().min(1),
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
interface UpdatePageSuccess {
|
|
35
|
-
page: Record<string, unknown>;
|
|
36
|
-
version: string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export type UpdatePageResult = UpdatePageSuccess | ErrorBody;
|
|
40
|
-
|
|
41
|
-
export interface UpdatePageInput {
|
|
42
|
-
type: string;
|
|
43
|
-
slug: string;
|
|
44
|
-
page: Record<string, unknown>;
|
|
45
|
-
body: string;
|
|
46
|
-
ifMatch: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export async function ailkUpdatePage(
|
|
50
|
-
input: UpdatePageInput,
|
|
51
|
-
adapter?: ContentAdapter,
|
|
52
|
-
): Promise<UpdatePageResult> {
|
|
53
|
-
const guard = await requirePaidTier();
|
|
54
|
-
if (guard) return guard;
|
|
55
|
-
|
|
56
|
-
const parsed = UpdatePageInputSchema.safeParse({
|
|
57
|
-
...input.page,
|
|
58
|
-
type: input.type,
|
|
59
|
-
slug: input.slug,
|
|
60
|
-
body: input.body,
|
|
61
|
-
ifMatch: input.ifMatch,
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
if (!parsed.success) {
|
|
65
|
-
return validationError(
|
|
66
|
-
"Invalid frontmatter, body, or ifMatch for update_page.",
|
|
67
|
-
{ issues: parsed.error.issues },
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const { ifMatch, ...pageWithBody } = parsed.data;
|
|
72
|
-
const resolved =
|
|
73
|
-
adapter ??
|
|
74
|
-
createMdxAdapter({ contentRoot: join(process.cwd(), "content") });
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
const result = await resolved.updatePage(
|
|
78
|
-
pageWithBody.type,
|
|
79
|
-
pageWithBody.slug,
|
|
80
|
-
pageWithBody,
|
|
81
|
-
{ ifMatch },
|
|
82
|
-
);
|
|
83
|
-
return { page: result.page, version: result.version };
|
|
84
|
-
} catch (err) {
|
|
85
|
-
const mapped = mapAdapterError(err, {
|
|
86
|
-
type: pageWithBody.type,
|
|
87
|
-
slug: pageWithBody.slug,
|
|
88
|
-
});
|
|
89
|
-
if (mapped) return mapped;
|
|
90
|
-
throw err;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
"use client"; // Better Auth's client calls (signIn.social / signIn.email) + error state
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* SignInCard — the /sign-in page's client island (#4984).
|
|
5
|
-
*
|
|
6
|
-
* Composes the shipped `AuthCard` block (`intent="sign-in"`, `footer="none"`)
|
|
7
|
-
* and wires its provider buttons / password form to the Better Auth client,
|
|
8
|
-
* using the SAME `createAuthClient()` idiom the `(authed)` group's
|
|
9
|
-
* `SignInGate` uses. The page (RSC) decides providers + method from auth-env
|
|
10
|
-
* and hands them in; this component never reads env itself.
|
|
11
|
-
*
|
|
12
|
-
* No sign-up affordance anywhere: `footer="none"` drops the "Not a member?
|
|
13
|
-
* Create an account" cross-link (Better Auth `emailAndPassword.disableSignUp`
|
|
14
|
-
* posture).
|
|
15
|
-
*
|
|
16
|
-
* Password path: `apps/web/auth.ts` does not enable `emailAndPassword` today,
|
|
17
|
-
* so `signIn.email` is wired but inert (Better Auth answers with an error)
|
|
18
|
-
* until an operator enables it server-side — the page only selects
|
|
19
|
-
* `method="password"` when auth-env reports the "email" provider.
|
|
20
|
-
*
|
|
21
|
-
* Zero providers (method sso, providers []): the card renders in its inert
|
|
22
|
-
* state — heading + `notConfiguredSubhead`, no buttons, no form. Never a
|
|
23
|
-
* fabricated session.
|
|
24
|
-
*
|
|
25
|
-
* Error surface: AuthCard's `errors` prop is per-field. A failed provider
|
|
26
|
-
* launch lands on `errors.email` — the social row sits inside the password
|
|
27
|
-
* form beside the email field, so it renders there. The SSO body has no
|
|
28
|
-
* fields at all, so for `method="sso"` the same message is rendered as an
|
|
29
|
-
* `Alert` above the card instead.
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
import { AuthCard, type AuthCardLabels } from "@working-theory/ui/blocks";
|
|
33
|
-
import { Alert, AlertDescription } from "@working-theory/ui/primitives";
|
|
34
|
-
import { createAuthClient } from "better-auth/react";
|
|
35
|
-
import type { ReactElement, ReactNode } from "react";
|
|
36
|
-
import { useState } from "react";
|
|
37
|
-
|
|
38
|
-
const authClient = createAuthClient();
|
|
39
|
-
|
|
40
|
-
/** The OAuth providers this page can launch — a subset of AuthCard's. */
|
|
41
|
-
export type SignInProvider = "google" | "github";
|
|
42
|
-
|
|
43
|
-
export interface SignInCardProps {
|
|
44
|
-
/** Active OAuth providers, exactly as auth-env reports them. */
|
|
45
|
-
providers: SignInProvider[];
|
|
46
|
-
/** "password" when the email provider is active; otherwise "sso". */
|
|
47
|
-
method: "sso" | "password";
|
|
48
|
-
/** Sanitised post-sign-in path (see `next-path.ts`). */
|
|
49
|
-
next: string;
|
|
50
|
-
/** Brand mark rendered top-center inside the card. */
|
|
51
|
-
logo?: ReactNode;
|
|
52
|
-
/** Translated AuthCard labels (resolved server-side by the page). */
|
|
53
|
-
labels: AuthCardLabels;
|
|
54
|
-
/** Subhead shown when no provider is configured. */
|
|
55
|
-
notConfiguredSubhead: string;
|
|
56
|
-
/** Translated error copy. */
|
|
57
|
-
errorLabels: { signInFailed: string; providerFailed: string };
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
type FieldErrors = { email?: string; password?: string };
|
|
61
|
-
|
|
62
|
-
export function SignInCard({
|
|
63
|
-
providers,
|
|
64
|
-
method,
|
|
65
|
-
next,
|
|
66
|
-
logo,
|
|
67
|
-
labels,
|
|
68
|
-
notConfiguredSubhead,
|
|
69
|
-
errorLabels,
|
|
70
|
-
}: SignInCardProps): ReactElement {
|
|
71
|
-
const [errors, setErrors] = useState<FieldErrors>({});
|
|
72
|
-
const [providerError, setProviderError] = useState<string | null>(null);
|
|
73
|
-
|
|
74
|
-
const notConfigured = method === "sso" && providers.length === 0;
|
|
75
|
-
|
|
76
|
-
const launchProvider = async (provider: SignInProvider): Promise<void> => {
|
|
77
|
-
setProviderError(null);
|
|
78
|
-
// Better Auth reports a failed launch as `{ error }`; a network/runtime
|
|
79
|
-
// failure rejects. Both land on the same providerFailed message.
|
|
80
|
-
const failed = await authClient.signIn
|
|
81
|
-
.social({ provider, callbackURL: next })
|
|
82
|
-
.then((res) => Boolean(res?.error), () => true);
|
|
83
|
-
if (failed) {
|
|
84
|
-
setProviderError(errorLabels.providerFailed);
|
|
85
|
-
setErrors((prev) => ({ ...prev, email: errorLabels.providerFailed }));
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const submitPassword = async (email: string, password: string): Promise<void> => {
|
|
90
|
-
setErrors({});
|
|
91
|
-
const res = await authClient.signIn.email({ email, password, callbackURL: next });
|
|
92
|
-
if (res?.error) setErrors({ password: errorLabels.signInFailed });
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
return (
|
|
96
|
-
<div
|
|
97
|
-
className="flex min-h-screen items-center justify-center py-section"
|
|
98
|
-
data-testid="sign-in-page"
|
|
99
|
-
>
|
|
100
|
-
<div className="flex w-full max-w-md flex-col gap-4">
|
|
101
|
-
{method === "sso" && providerError ? (
|
|
102
|
-
<Alert variant="error" data-testid="sign-in-provider-error">
|
|
103
|
-
<AlertDescription>{providerError}</AlertDescription>
|
|
104
|
-
</Alert>
|
|
105
|
-
) : null}
|
|
106
|
-
<AuthCard
|
|
107
|
-
intent="sign-in"
|
|
108
|
-
method={method}
|
|
109
|
-
footer="none"
|
|
110
|
-
{...(logo !== undefined ? { logo } : {})}
|
|
111
|
-
{...(notConfigured ? { subhead: notConfiguredSubhead } : {})}
|
|
112
|
-
providers={providers.map((provider) => ({
|
|
113
|
-
provider,
|
|
114
|
-
onClick: () => void launchProvider(provider),
|
|
115
|
-
}))}
|
|
116
|
-
onSubmit={(data) => void submitPassword(data.email, data.password ?? "")}
|
|
117
|
-
errors={errors}
|
|
118
|
-
labels={labels}
|
|
119
|
-
/>
|
|
120
|
-
</div>
|
|
121
|
-
</div>
|
|
122
|
-
);
|
|
123
|
-
}
|
/package/templates/apps/web/app/[locale]/{sign-in → (auth)/sign-in}/__tests__/next-path.test.ts
RENAMED
|
File without changes
|
|
File without changes
|