create-ailk 0.1.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/LICENSE +201 -0
- package/README.md +39 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +80 -0
- package/dist/copy.d.ts +8 -0
- package/dist/copy.js +109 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/lib/pro-callout.d.ts +12 -0
- package/dist/lib/pro-callout.js +20 -0
- package/dist/parse-args.d.ts +13 -0
- package/dist/parse-args.js +81 -0
- package/dist/programmatic.d.ts +49 -0
- package/dist/programmatic.js +89 -0
- package/dist/substitute.d.ts +31 -0
- package/dist/substitute.js +45 -0
- package/dist/validate.d.ts +8 -0
- package/dist/validate.js +70 -0
- package/package.json +47 -0
- package/templates/.claude/.gitkeep +0 -0
- package/templates/.claude/agents/web.md +80 -0
- package/templates/.claude/rules/architecture.md +62 -0
- package/templates/.claude/rules/preserve-existing-style.md +51 -0
- package/templates/.claude/skills/README.md +43 -0
- package/templates/.claude/skills/add-schema/SKILL.md +270 -0
- package/templates/.claude/skills/add-schema/references/conflict-handling.md +200 -0
- package/templates/.claude/skills/add-schema/references/file-finding.md +123 -0
- package/templates/.claude/skills/add-schema/references/schema-types.md +131 -0
- package/templates/.claude/skills/audit-site/SKILL.md +213 -0
- package/templates/.claude/skills/audit-site/references/common-errors.md +113 -0
- package/templates/.claude/skills/audit-site/references/findings-glossary.md +138 -0
- package/templates/.claude/skills/audit-site/references/severity-levels.md +114 -0
- package/templates/.claude/skills/provision-config/SKILL.md +243 -0
- package/templates/.claude/skills/provision-config/references/env-vars-template.md +184 -0
- package/templates/.claude/skills/provision-config/references/runbook-template.md +248 -0
- package/templates/.claude/skills/provision-config/references/vercel-json-template.md +98 -0
- package/templates/.claude/skills/scaffold-auth/SKILL.md +261 -0
- package/templates/.claude/skills/scaffold-auth/references/env-vars.md +91 -0
- package/templates/.claude/skills/scaffold-auth/references/oauth-app-setup.md +171 -0
- package/templates/.claude/skills/scaffold-commerce/SKILL.md +310 -0
- package/templates/.claude/skills/scaffold-commerce/references/lookup-keys-template.md +71 -0
- package/templates/.claude/skills/scaffold-commerce/references/marketplace-brand-pages.md +83 -0
- package/templates/.claude/skills/scaffold-commerce/templates/marketplace-cta-route.tsx.tmpl +72 -0
- package/templates/.claude/skills/scaffold-page/SKILL.md +243 -0
- package/templates/.claude/skills/scaffold-page/references/page-types.md +169 -0
- package/templates/.claude/skills/scaffold-page/templates/content.mdx.tmpl +28 -0
- package/templates/.claude/skills/scaffold-page/templates/route.tsx.tmpl +28 -0
- package/templates/.claude/skills/suggest-site-pages/SKILL.md +242 -0
- package/templates/.claude/skills/suggest-site-pages/references/categories.md +287 -0
- package/templates/.env.example +205 -0
- package/templates/.gitkeep +2 -0
- package/templates/CLAUDE.md +142 -0
- package/templates/CONVENTIONS.md +222 -0
- package/templates/README.md +110 -0
- package/templates/apps/api/.env.example +40 -0
- package/templates/apps/api/CLAUDE.md +63 -0
- package/templates/apps/api/api/index.ts +144 -0
- package/templates/apps/api/jest.config.cjs +74 -0
- package/templates/apps/api/package.json +54 -0
- package/templates/apps/api/src/__tests__/factories/content-fixture.ts +138 -0
- package/templates/apps/api/src/__tests__/factories/index.ts +70 -0
- package/templates/apps/api/src/__tests__/factories/lead-fixture.ts +82 -0
- package/templates/apps/api/src/__tests__/index.test.ts +118 -0
- package/templates/apps/api/src/__tests__/server.test.ts +207 -0
- package/templates/apps/api/src/__tests__/services/enrichment-shim.test.ts +126 -0
- package/templates/apps/api/src/__tests__/setup.ts +24 -0
- package/templates/apps/api/src/cli.ts +30 -0
- package/templates/apps/api/src/config/__tests__/index.test.ts +97 -0
- package/templates/apps/api/src/config/index.ts +56 -0
- package/templates/apps/api/src/index.ts +32 -0
- package/templates/apps/api/src/lib/__mocks__/prisma-client.js +15 -0
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +45 -0
- package/templates/apps/api/src/lib/__tests__/content-adapter.test.ts +178 -0
- package/templates/apps/api/src/lib/__tests__/error-serializer.test.ts +100 -0
- package/templates/apps/api/src/lib/__tests__/errors.test.ts +94 -0
- package/templates/apps/api/src/lib/__tests__/file-fallback.test.ts +144 -0
- package/templates/apps/api/src/lib/__tests__/fixtures/HomePage/home.mdx +8 -0
- package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +227 -0
- package/templates/apps/api/src/lib/__tests__/outbound-http.test.ts +125 -0
- package/templates/apps/api/src/lib/__tests__/prisma.test.ts +165 -0
- package/templates/apps/api/src/lib/__tests__/require-paid-tier.test.ts +129 -0
- package/templates/apps/api/src/lib/__tests__/stripe.test.ts +74 -0
- package/templates/apps/api/src/lib/content-adapter.ts +86 -0
- package/templates/apps/api/src/lib/error-serializer.ts +77 -0
- package/templates/apps/api/src/lib/errors.ts +95 -0
- package/templates/apps/api/src/lib/file-fallback.ts +87 -0
- package/templates/apps/api/src/lib/lead-capture-store.ts +110 -0
- package/templates/apps/api/src/lib/locales.ts +201 -0
- package/templates/apps/api/src/lib/outbound-http.ts +122 -0
- package/templates/apps/api/src/lib/prisma.ts +21 -0
- package/templates/apps/api/src/lib/require-paid-tier.ts +53 -0
- package/templates/apps/api/src/lib/stripe.ts +30 -0
- package/templates/apps/api/src/lib/webhook-idempotency.ts +92 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/bearer-token-format.test.ts +111 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/cookie-or-bearer-precedence.test.ts +172 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-bearer-skip.test.ts +119 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/csrf-cookie-path.test.ts +138 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-fixation.test.ts +149 -0
- package/templates/apps/api/src/middleware/__tests__/adversarial/session-timeout.test.ts +139 -0
- package/templates/apps/api/src/middleware/__tests__/auth.bearer-path.test.ts +175 -0
- package/templates/apps/api/src/middleware/__tests__/auth.both-present-precedence.test.ts +76 -0
- package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +153 -0
- package/templates/apps/api/src/middleware/__tests__/auth.neither-present.test.ts +72 -0
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +292 -0
- package/templates/apps/api/src/middleware/auth.ts +246 -0
- package/templates/apps/api/src/middleware/rate-limit.ts +132 -0
- package/templates/apps/api/src/openapi/__tests__/openapi.test.ts +129 -0
- package/templates/apps/api/src/openapi/index.ts +12 -0
- package/templates/apps/api/src/openapi/spec.ts +408 -0
- package/templates/apps/api/src/routes/auth/__tests__/auth-tokens.functional.test.ts +193 -0
- package/templates/apps/api/src/routes/auth/__tests__/auth-user.functional.test.ts +201 -0
- package/templates/apps/api/src/routes/auth/__tests__/tokens.test.ts +294 -0
- package/templates/apps/api/src/routes/auth/__tests__/user.test.ts +486 -0
- package/templates/apps/api/src/routes/auth/tokens.ts +199 -0
- package/templates/apps/api/src/routes/auth/user.ts +244 -0
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +588 -0
- package/templates/apps/api/src/routes/checkout/index.ts +13 -0
- package/templates/apps/api/src/routes/checkout/sessions.ts +185 -0
- package/templates/apps/api/src/routes/content/__tests__/create.test.ts +239 -0
- package/templates/apps/api/src/routes/content/__tests__/delete.test.ts +201 -0
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +141 -0
- package/templates/apps/api/src/routes/content/__tests__/list-pages.test.ts +122 -0
- package/templates/apps/api/src/routes/content/__tests__/list-types.test.ts +44 -0
- package/templates/apps/api/src/routes/content/__tests__/locale.test.ts +118 -0
- package/templates/apps/api/src/routes/content/__tests__/rate-limit.test.ts +51 -0
- package/templates/apps/api/src/routes/content/__tests__/update.test.ts +252 -0
- package/templates/apps/api/src/routes/content/create.ts +114 -0
- package/templates/apps/api/src/routes/content/delete.ts +81 -0
- package/templates/apps/api/src/routes/content/get-page.ts +98 -0
- package/templates/apps/api/src/routes/content/index.ts +32 -0
- package/templates/apps/api/src/routes/content/list-pages.ts +83 -0
- package/templates/apps/api/src/routes/content/list-types.ts +19 -0
- package/templates/apps/api/src/routes/content/rate-limit.ts +13 -0
- package/templates/apps/api/src/routes/content/slug.ts +9 -0
- package/templates/apps/api/src/routes/content/update.ts +111 -0
- package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +415 -0
- package/templates/apps/api/src/routes/leads/__tests__/track.test.ts +165 -0
- package/templates/apps/api/src/routes/leads/index.ts +130 -0
- package/templates/apps/api/src/routes/test/auth/__tests__/session.test.ts +296 -0
- package/templates/apps/api/src/routes/test/auth/session.ts +141 -0
- package/templates/apps/api/src/routes/webhooks/README.md +57 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-idempotency.test.ts +247 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-rate-limit.test.ts +198 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +633 -0
- package/templates/apps/api/src/routes/webhooks/index.ts +41 -0
- package/templates/apps/api/src/routes/webhooks/stripe.ts +253 -0
- package/templates/apps/api/src/server.ts +157 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +395 -0
- package/templates/apps/api/src/services/enrichment-shim.ts +53 -0
- package/templates/apps/api/src/services/lead-routing.ts +338 -0
- package/templates/apps/api/tsconfig.json +34 -0
- package/templates/apps/api/vercel.json +17 -0
- package/templates/apps/mcp/.env.example +52 -0
- package/templates/apps/mcp/CLAUDE.md +84 -0
- package/templates/apps/mcp/__tests__/abuse/daily-cap.test.ts +52 -0
- package/templates/apps/mcp/__tests__/abuse/email-validator.test.ts +46 -0
- package/templates/apps/mcp/__tests__/abuse/honeypot.test.ts +36 -0
- package/templates/apps/mcp/__tests__/abuse/user-agent-deny.test.ts +54 -0
- package/templates/apps/mcp/__tests__/aeo-cli-parity.test.ts +110 -0
- package/templates/apps/mcp/__tests__/audit-single-page.test.ts +213 -0
- package/templates/apps/mcp/__tests__/audit.test.ts +217 -0
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +52 -0
- package/templates/apps/mcp/__tests__/create_page.test.ts +201 -0
- package/templates/apps/mcp/__tests__/delete_page.test.ts +176 -0
- package/templates/apps/mcp/__tests__/get_business_hours.test.ts +82 -0
- package/templates/apps/mcp/__tests__/get_faq.test.ts +80 -0
- package/templates/apps/mcp/__tests__/get_locations.test.ts +65 -0
- package/templates/apps/mcp/__tests__/get_offerings.test.ts +90 -0
- package/templates/apps/mcp/__tests__/get_pricing.test.ts +80 -0
- package/templates/apps/mcp/__tests__/get_site_info.test.ts +81 -0
- package/templates/apps/mcp/__tests__/http-transport.test.ts +323 -0
- package/templates/apps/mcp/__tests__/lib/errors.test.ts +75 -0
- package/templates/apps/mcp/__tests__/lib/require-paid-tier.test.ts +75 -0
- package/templates/apps/mcp/__tests__/list_pages.test.ts +112 -0
- package/templates/apps/mcp/__tests__/locale.test.ts +135 -0
- package/templates/apps/mcp/__tests__/parity.test.ts +205 -0
- package/templates/apps/mcp/__tests__/purchase-disabled.test.ts +34 -0
- package/templates/apps/mcp/__tests__/read_content.test.ts +153 -0
- package/templates/apps/mcp/__tests__/request_callback.test.ts +163 -0
- package/templates/apps/mcp/__tests__/search_content.test.ts +153 -0
- package/templates/apps/mcp/__tests__/server.test.ts +115 -0
- package/templates/apps/mcp/__tests__/submit_lead.test.ts +165 -0
- package/templates/apps/mcp/__tests__/subscribe_newsletter.test.ts +161 -0
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +227 -0
- package/templates/apps/mcp/__tests__/tools/scaffold.test.ts +237 -0
- package/templates/apps/mcp/__tests__/update_page.test.ts +195 -0
- package/templates/apps/mcp/jest.config.cjs +82 -0
- package/templates/apps/mcp/package.json +37 -0
- package/templates/apps/mcp/src/abuse/daily-cap.ts +47 -0
- package/templates/apps/mcp/src/abuse/email-validator.ts +25 -0
- package/templates/apps/mcp/src/abuse/honeypot.ts +21 -0
- package/templates/apps/mcp/src/abuse/index.ts +111 -0
- package/templates/apps/mcp/src/abuse/user-agent-deny.ts +58 -0
- package/templates/apps/mcp/src/http-transport.ts +303 -0
- package/templates/apps/mcp/src/index.ts +67 -0
- package/templates/apps/mcp/src/lib/audit-single-page.ts +194 -0
- package/templates/apps/mcp/src/lib/errors.ts +61 -0
- package/templates/apps/mcp/src/lib/locales.ts +171 -0
- package/templates/apps/mcp/src/lib/require-paid-tier.ts +44 -0
- package/templates/apps/mcp/src/lib/resolve-locale.ts +30 -0
- package/templates/apps/mcp/src/server.ts +139 -0
- package/templates/apps/mcp/src/tools/audit.ts +103 -0
- package/templates/apps/mcp/src/tools/capture_lead.ts +52 -0
- package/templates/apps/mcp/src/tools/create_page.ts +95 -0
- package/templates/apps/mcp/src/tools/delete_page.ts +73 -0
- package/templates/apps/mcp/src/tools/get_business_hours.ts +66 -0
- package/templates/apps/mcp/src/tools/get_faq.ts +69 -0
- package/templates/apps/mcp/src/tools/get_locations.ts +85 -0
- package/templates/apps/mcp/src/tools/get_offerings.ts +66 -0
- package/templates/apps/mcp/src/tools/get_pricing.ts +74 -0
- package/templates/apps/mcp/src/tools/get_site_info.ts +84 -0
- package/templates/apps/mcp/src/tools/index.ts +125 -0
- package/templates/apps/mcp/src/tools/list_pages.ts +72 -0
- package/templates/apps/mcp/src/tools/purchase.ts +89 -0
- package/templates/apps/mcp/src/tools/read_content.ts +61 -0
- package/templates/apps/mcp/src/tools/request_callback.ts +51 -0
- package/templates/apps/mcp/src/tools/scaffold.ts +119 -0
- package/templates/apps/mcp/src/tools/search_content.ts +59 -0
- package/templates/apps/mcp/src/tools/subscribe_newsletter.ts +47 -0
- package/templates/apps/mcp/src/tools/update_page.ts +91 -0
- package/templates/apps/mcp/tsconfig.json +19 -0
- package/templates/apps/web/.env.example +47 -0
- package/templates/apps/web/CLAUDE.md +81 -0
- package/templates/apps/web/__tests__/auth/adversarial/cookie-attributes.test.ts +94 -0
- package/templates/apps/web/__tests__/auth/adversarial/oauth-state-parameter.test.ts +75 -0
- package/templates/apps/web/__tests__/auth/adversarial/redirect-uri-allowlist.test.ts +82 -0
- package/templates/apps/web/__tests__/auth/env-helpers.test.ts +168 -0
- package/templates/apps/web/__tests__/authority-list-routes.test.tsx +208 -0
- package/templates/apps/web/__tests__/better-stack.test.ts +66 -0
- package/templates/apps/web/__tests__/blog-dir-resolution.test.ts +87 -0
- package/templates/apps/web/__tests__/blog-source-populated.test.ts +130 -0
- package/templates/apps/web/__tests__/data-testid-coverage.test.tsx +60 -0
- package/templates/apps/web/__tests__/google-analytics.test.tsx +104 -0
- package/templates/apps/web/__tests__/i18n/middleware.test.ts +119 -0
- package/templates/apps/web/__tests__/i18n/routing.test.ts +114 -0
- package/templates/apps/web/__tests__/i18n/translations.test.ts +191 -0
- package/templates/apps/web/__tests__/json-ld.test.ts +98 -0
- package/templates/apps/web/__tests__/knowledge-events-routes.test.tsx +580 -0
- package/templates/apps/web/__tests__/layout-stealth.test.ts +39 -0
- package/templates/apps/web/__tests__/lighthouse-fixtures/improvement-image-shrink.tsx +103 -0
- package/templates/apps/web/__tests__/lighthouse-fixtures/override-fixture.md +114 -0
- package/templates/apps/web/__tests__/lighthouse-fixtures/regression-bloat.tsx +94 -0
- package/templates/apps/web/__tests__/page.test.tsx +230 -0
- package/templates/apps/web/__tests__/products-services-phase1.test.tsx +321 -0
- package/templates/apps/web/__tests__/projects-routes.test.tsx +392 -0
- package/templates/apps/web/__tests__/resources-downloads-integrations-phase2.test.tsx +475 -0
- package/templates/apps/web/__tests__/routes/ai-plugin-json.test.ts +53 -0
- package/templates/apps/web/__tests__/routes/blog-route.test.tsx +191 -0
- package/templates/apps/web/__tests__/routes/llms-txt.test.ts +123 -0
- package/templates/apps/web/__tests__/routes/robots-txt.test.ts +52 -0
- package/templates/apps/web/__tests__/routes/sitemap-xml.test.ts +78 -0
- package/templates/apps/web/__tests__/routes/well-known-mcp.test.ts +203 -0
- package/templates/apps/web/__tests__/section-routes.test.tsx +693 -0
- package/templates/apps/web/__tests__/security-headers.test.ts +201 -0
- package/templates/apps/web/__tests__/sentry-config.test.ts +116 -0
- package/templates/apps/web/__tests__/setup.ts +82 -0
- package/templates/apps/web/__tests__/sitemap-locales.test.ts +415 -0
- package/templates/apps/web/__tests__/standalone-informational-routes.test.tsx +844 -0
- package/templates/apps/web/app/.well-known/ai-plugin.json/route.ts +81 -0
- package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +110 -0
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +58 -0
- package/templates/apps/web/app/[locale]/__tests__/layout.test.tsx +120 -0
- package/templates/apps/web/app/[locale]/__tests__/page-renderer-migration.test.tsx +202 -0
- package/templates/apps/web/app/[locale]/about/page.tsx +31 -0
- package/templates/apps/web/app/[locale]/blog/[[...slug]]/page.tsx +173 -0
- package/templates/apps/web/app/[locale]/careers/[slug]/page.tsx +45 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +117 -0
- package/templates/apps/web/app/[locale]/careers/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/case-studies/[slug]/page.tsx +44 -0
- package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +113 -0
- package/templates/apps/web/app/[locale]/case-studies/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +63 -0
- package/templates/apps/web/app/[locale]/clients/page.tsx +27 -0
- package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +130 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +152 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +92 -0
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +79 -0
- package/templates/apps/web/app/[locale]/contact/error.tsx +24 -0
- package/templates/apps/web/app/[locale]/contact/page.tsx +38 -0
- package/templates/apps/web/app/[locale]/courses/[slug]/page.tsx +34 -0
- package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +119 -0
- package/templates/apps/web/app/[locale]/courses/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/dev/purchase/__tests__/actions.test.ts +160 -0
- package/templates/apps/web/app/[locale]/dev/purchase/error.tsx +25 -0
- package/templates/apps/web/app/[locale]/dev/purchase/page.tsx +117 -0
- package/templates/apps/web/app/[locale]/dev/purchase/purchase.actions.ts +58 -0
- package/templates/apps/web/app/[locale]/docs/[[...slug]]/page.tsx +118 -0
- package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +72 -0
- package/templates/apps/web/app/[locale]/downloads/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/events/[slug]/page.tsx +47 -0
- package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +130 -0
- package/templates/apps/web/app/[locale]/events/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/faq/page.tsx +36 -0
- package/templates/apps/web/app/[locale]/how-to/[slug]/page.tsx +34 -0
- package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +78 -0
- package/templates/apps/web/app/[locale]/how-to/page.tsx +40 -0
- package/templates/apps/web/app/[locale]/integrations/[slug]/page.tsx +43 -0
- package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +129 -0
- package/templates/apps/web/app/[locale]/integrations/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/launch-service/page.tsx +31 -0
- package/templates/apps/web/app/[locale]/layout.tsx +241 -0
- package/templates/apps/web/app/[locale]/page.tsx +41 -0
- package/templates/apps/web/app/[locale]/partners/[slug]/page.tsx +44 -0
- package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +113 -0
- package/templates/apps/web/app/[locale]/partners/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/products/[slug]/page.tsx +43 -0
- package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +129 -0
- package/templates/apps/web/app/[locale]/products/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/projects/[slug]/page.tsx +39 -0
- package/templates/apps/web/app/[locale]/projects/__tests__/page-renderer-migration.test.tsx +138 -0
- package/templates/apps/web/app/[locale]/projects/page.tsx +30 -0
- package/templates/apps/web/app/[locale]/resources/[slug]/page.tsx +51 -0
- package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +117 -0
- package/templates/apps/web/app/[locale]/resources/page.tsx +27 -0
- package/templates/apps/web/app/[locale]/services/[slug]/page.tsx +43 -0
- package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +129 -0
- package/templates/apps/web/app/[locale]/services/page.tsx +25 -0
- package/templates/apps/web/app/[locale]/software/[slug]/page.tsx +34 -0
- package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +81 -0
- package/templates/apps/web/app/[locale]/software/page.tsx +39 -0
- package/templates/apps/web/app/[locale]/tech-articles/[slug]/page.tsx +34 -0
- package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +82 -0
- package/templates/apps/web/app/[locale]/tech-articles/page.tsx +39 -0
- package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +63 -0
- package/templates/apps/web/app/[locale]/testimonials/page.tsx +27 -0
- package/templates/apps/web/app/[locale]/use-cases/__tests__/page-renderer-migration.test.tsx +63 -0
- package/templates/apps/web/app/[locale]/use-cases/page.tsx +27 -0
- package/templates/apps/web/app/[locale]/whitepapers/[slug]/page.tsx +34 -0
- package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +82 -0
- package/templates/apps/web/app/[locale]/whitepapers/page.tsx +39 -0
- package/templates/apps/web/app/__tests__/error-boundaries.test.tsx +152 -0
- package/templates/apps/web/app/api/auth/[...all]/route.ts +16 -0
- package/templates/apps/web/app/error-fallback.tsx +75 -0
- package/templates/apps/web/app/error.tsx +23 -0
- package/templates/apps/web/app/layout.tsx +18 -0
- package/templates/apps/web/app/llms.txt/route.ts +101 -0
- package/templates/apps/web/app/not-found.tsx +48 -0
- package/templates/apps/web/app/og/__tests__/route.test.ts +164 -0
- package/templates/apps/web/app/og/route.tsx +135 -0
- package/templates/apps/web/app/robots.txt/route.ts +36 -0
- package/templates/apps/web/app/sitemap.xml/route.ts +146 -0
- package/templates/apps/web/auth.ts +141 -0
- package/templates/apps/web/components/ThemeToggle.tsx +60 -0
- package/templates/apps/web/components/google-analytics.tsx +34 -0
- package/templates/apps/web/content/en/blog/index.mdx +15 -0
- package/templates/apps/web/content/en/blog/launching-ailk.mdx +20 -0
- package/templates/apps/web/content/en/docs/getting-started.mdx +30 -0
- package/templates/apps/web/i18n/request.ts +36 -0
- package/templates/apps/web/jest.config.cjs +100 -0
- package/templates/apps/web/lib/__mocks__/next-mdx-remote-rsc.js +12 -0
- package/templates/apps/web/lib/__mocks__/source-server.js +31 -0
- package/templates/apps/web/lib/__tests__/og.test.ts +65 -0
- package/templates/apps/web/lib/auth-env.ts +66 -0
- package/templates/apps/web/lib/blog-list-data.ts +95 -0
- package/templates/apps/web/lib/blog-post-data.ts +79 -0
- package/templates/apps/web/lib/nav-config.ts +13 -0
- package/templates/apps/web/lib/observability/better-stack.ts +27 -0
- package/templates/apps/web/lib/og.ts +23 -0
- package/templates/apps/web/lib/prisma-for-auth.ts +34 -0
- package/templates/apps/web/lib/source.ts +34 -0
- package/templates/apps/web/messages/en.json +131 -0
- package/templates/apps/web/middleware.ts +80 -0
- package/templates/apps/web/next.config.mjs +167 -0
- package/templates/apps/web/package.json +62 -0
- package/templates/apps/web/public/.well-known/security.txt +17 -0
- package/templates/apps/web/public/android-chrome-192x192.png +0 -0
- package/templates/apps/web/public/android-chrome-512x512.png +0 -0
- package/templates/apps/web/public/apple-touch-icon.png +0 -0
- package/templates/apps/web/public/favicon-16x16.png +0 -0
- package/templates/apps/web/public/favicon-32x32.png +0 -0
- package/templates/apps/web/public/favicon.ico +0 -0
- package/templates/apps/web/public/favicon.svg +4 -0
- package/templates/apps/web/public/logo-dark.svg +21 -0
- package/templates/apps/web/public/logo-light.svg +21 -0
- package/templates/apps/web/public/logomark-dark.svg +4 -0
- package/templates/apps/web/public/logomark-light.svg +4 -0
- package/templates/apps/web/public/og-default.png +0 -0
- package/templates/apps/web/public/site.webmanifest +19 -0
- package/templates/apps/web/scripts/assert-content-bundled.ts +55 -0
- package/templates/apps/web/security-headers.config.ts +132 -0
- package/templates/apps/web/sentry.client.config.ts +27 -0
- package/templates/apps/web/sentry.edge.config.ts +15 -0
- package/templates/apps/web/sentry.server.config.ts +20 -0
- package/templates/apps/web/source.config.ts +78 -0
- package/templates/apps/web/src/components/SiteNav.tsx +21 -0
- package/templates/apps/web/src/lib/routes.ts +37 -0
- package/templates/apps/web/tsconfig.json +35 -0
- package/templates/apps/web/types/messages.d.ts +19 -0
- package/templates/content/.gitkeep +0 -0
- package/templates/content/CLAUDE.md +85 -0
- package/templates/content/_site.mdx +38 -0
- package/templates/content/ar/HomePage/home.mdx +123 -0
- package/templates/content/ar/_site.mdx +35 -0
- package/templates/content/de/_site.mdx +29 -0
- package/templates/content/en/.gitkeep +0 -0
- package/templates/content/en/AboutPage/about.mdx +19 -0
- package/templates/content/en/AboutPage/about.schema.json +82 -0
- package/templates/content/en/BookCall/book-call.mdx +19 -0
- package/templates/content/en/BookCall/book-call.schema.json +121 -0
- package/templates/content/en/BreadcrumbList/site-breadcrumbs.mdx +20 -0
- package/templates/content/en/CareersList/careers.mdx +24 -0
- package/templates/content/en/CaseStudiesList/case-studies.mdx +22 -0
- package/templates/content/en/CaseStudiesList/showcase.mdx +8 -0
- package/templates/content/en/CaseStudy/ailk-aeo-rollout.mdx +32 -0
- package/templates/content/en/CaseStudy/schema-builder-migration.mdx +41 -0
- package/templates/content/en/ClientsList/clients.mdx +38 -0
- package/templates/content/en/ContactPage/contact.mdx +19 -0
- package/templates/content/en/ContactPage/contact.schema.json +100 -0
- package/templates/content/en/ContactPoint/primary.mdx +14 -0
- package/templates/content/en/Course/aeo-fundamentals.mdx +37 -0
- package/templates/content/en/Course/schema-builder-workshop.mdx +62 -0
- package/templates/content/en/CoursesList/courses.mdx +22 -0
- package/templates/content/en/DownloadsList/downloads.mdx +22 -0
- package/templates/content/en/Event/aeo-office-hours-may-2026.mdx +39 -0
- package/templates/content/en/Event/ailk-launch-day-2026.mdx +35 -0
- package/templates/content/en/EventsList/events.mdx +26 -0
- package/templates/content/en/FAQPage/faq.mdx +420 -0
- package/templates/content/en/FAQPage/faq.schema.json +231 -0
- package/templates/content/en/GlossaryList/glossary.mdx +19 -0
- package/templates/content/en/GlossaryList/glossary.schema.json +300 -0
- package/templates/content/en/HomePage/home.mdx +312 -0
- package/templates/content/en/HomePage/home.schema.json +88 -0
- package/templates/content/en/HomePage/launch-service.mdx +475 -0
- package/templates/content/en/HomePage/launch-service.schema.json +138 -0
- package/templates/content/en/HowTo/add-mdx-content.mdx +38 -0
- package/templates/content/en/HowTo/configure-aeo-scoring.mdx +35 -0
- package/templates/content/en/HowTo/set-up-json-ld.mdx +36 -0
- package/templates/content/en/Integration/github-actions.mdx +31 -0
- package/templates/content/en/Integration/openai-api.mdx +26 -0
- package/templates/content/en/Integration/vercel.mdx +32 -0
- package/templates/content/en/IntegrationsList/integrations.mdx +22 -0
- package/templates/content/en/JobPosting/content-strategist.mdx +46 -0
- package/templates/content/en/JobPosting/developer-advocate.mdx +47 -0
- package/templates/content/en/JobPosting/senior-fullstack-engineer.mdx +57 -0
- package/templates/content/en/LandingPage/aeo-audit.mdx +19 -0
- package/templates/content/en/LandingPage/aeo-audit.schema.json +92 -0
- package/templates/content/en/LandingPage/agency-waitlist.mdx +340 -0
- package/templates/content/en/LandingPage/agency-waitlist.schema.json +152 -0
- package/templates/content/en/LandingPage/developers.mdx +19 -0
- package/templates/content/en/LandingPage/developers.schema.json +109 -0
- package/templates/content/en/LandingPage/for-agencies.mdx +390 -0
- package/templates/content/en/LandingPage/for-agencies.schema.json +107 -0
- package/templates/content/en/LandingPage/for-ai-search-agencies.mdx +417 -0
- package/templates/content/en/LandingPage/for-ai-search-agencies.schema.json +105 -0
- package/templates/content/en/LandingPage/for-businesses.mdx +19 -0
- package/templates/content/en/LandingPage/for-businesses.schema.json +96 -0
- package/templates/content/en/LandingPage/platform.mdx +369 -0
- package/templates/content/en/LandingPage/platform.schema.json +166 -0
- package/templates/content/en/LandingPage/vs-ai-website-builders.mdx +19 -0
- package/templates/content/en/LandingPage/vs-ai-website-builders.schema.json +102 -0
- package/templates/content/en/LandingPage/vs-wordpress.mdx +19 -0
- package/templates/content/en/LandingPage/vs-wordpress.schema.json +53 -0
- package/templates/content/en/NewsletterSignup/newsletter.mdx +236 -0
- package/templates/content/en/NewsletterSignup/newsletter.schema.json +91 -0
- package/templates/content/en/Organization/site-owner.mdx +16 -0
- package/templates/content/en/Partner/prisma.mdx +31 -0
- package/templates/content/en/Partner/supabase.mdx +30 -0
- package/templates/content/en/Partner/vercel.mdx +28 -0
- package/templates/content/en/PartnersList/partners.mdx +22 -0
- package/templates/content/en/Person/founder.mdx +18 -0
- package/templates/content/en/Pricing/pricing.mdx +538 -0
- package/templates/content/en/Pricing/pricing.schema.json +209 -0
- package/templates/content/en/PrivacyPage/privacy.mdx +165 -0
- package/templates/content/en/PrivacyPage/privacy.schema.json +64 -0
- package/templates/content/en/Product/ailk.mdx +19 -0
- package/templates/content/en/Product/ailk.schema.json +94 -0
- package/templates/content/en/Product/api-launch-kit.mdx +26 -0
- package/templates/content/en/Product/launch-kit.mdx +28 -0
- package/templates/content/en/ProductsList/products.mdx +26 -0
- package/templates/content/en/Project/ailk-phase-2.mdx +54 -0
- package/templates/content/en/ProjectsList/projects.mdx +25 -0
- package/templates/content/en/ResourceDetail/aeo-scoring-guide.mdx +27 -0
- package/templates/content/en/ResourceDetail/content-model-whitepaper.mdx +28 -0
- package/templates/content/en/ResourceDetail/schema-org-quick-reference.mdx +39 -0
- package/templates/content/en/ResourcesHub/resources.mdx +22 -0
- package/templates/content/en/Service/consulting.mdx +22 -0
- package/templates/content/en/Service/implementation.mdx +30 -0
- package/templates/content/en/Service/launch-service.mdx +232 -0
- package/templates/content/en/Service/launch.mdx +228 -0
- package/templates/content/en/ServicesList/services.mdx +84 -0
- package/templates/content/en/SoftwareProduct/ailk-aeo.mdx +44 -0
- package/templates/content/en/SoftwareProduct/ailk-content-adapters.mdx +47 -0
- package/templates/content/en/SoftwareProduct/ailk-schema.mdx +49 -0
- package/templates/content/en/TeamList/team.mdx +63 -0
- package/templates/content/en/TeamMember/founder.mdx +72 -0
- package/templates/content/en/TermsPage/terms.mdx +19 -0
- package/templates/content/en/TermsPage/terms.schema.json +99 -0
- package/templates/content/en/TestimonialsList/testimonials.mdx +44 -0
- package/templates/content/en/UseCasesList/use-cases.mdx +30 -0
- package/templates/content/en/Whitepaper/ax-first-product-development.mdx +27 -0
- package/templates/content/en/Whitepaper/open-core-commercial-strategy.mdx +27 -0
- package/templates/content/en/Whitepaper/structured-data-for-answer-engines.mdx +31 -0
- package/templates/content/en-XA/AboutPage/about.mdx +8 -0
- package/templates/content/en-XA/FAQPage/faq.mdx +8 -0
- package/templates/content/en-XA/HomePage/home.mdx +8 -0
- package/templates/content/es/_site.mdx +30 -0
- package/templates/content/fr/_site.mdx +30 -0
- package/templates/content/ja/_site.mdx +30 -0
- package/templates/content/pt-BR/AboutPage/about.mdx +8 -0
- package/templates/content/pt-BR/FAQPage/faq.mdx +8 -0
- package/templates/content/pt-BR/HomePage/home.mdx +23 -0
- package/templates/database/CHANGELOG.md +5 -0
- package/templates/database/README.md +234 -0
- package/templates/database/__tests__/user-cascade.test.ts +125 -0
- package/templates/database/auth/.gitkeep +0 -0
- package/templates/database/config/.gitkeep +0 -0
- package/templates/database/content/.gitkeep +0 -0
- package/templates/database/inbox/.gitkeep +0 -0
- package/templates/database/inbox/README.md +3 -0
- package/templates/database/inbox/__tests__/schema.test.ts +40 -0
- package/templates/database/inbox/schema.prisma +52 -0
- package/templates/database/jest.config.cjs +29 -0
- package/templates/database/migrations/20260508000000_add_inbox_namespace/migration.sql +328 -0
- package/templates/database/migrations/20260513000000_better_auth_migration/migration.sql +100 -0
- package/templates/database/migrations/20260515000000_add_user_billing_fields/migration.sql +28 -0
- package/templates/database/migrations/20260516000000_add_user_tier_care_plan_seat/migration.sql +25 -0
- package/templates/database/migrations/20260518000000_add_telemetry_records/migration.sql +42 -0
- package/templates/database/migrations/20260525000000_theme_wiring/migration.sql +67 -0
- package/templates/database/migrations/20260710000000_retire_commercial_tier/migration.sql +21 -0
- package/templates/database/migrations/migration_lock.toml +3 -0
- package/templates/database/ops/.gitkeep +0 -0
- package/templates/database/package.json +45 -0
- package/templates/database/prisma.config.ts +20 -0
- package/templates/database/schema.prisma +487 -0
- package/templates/database/scripts/db-generate-locked.sh +80 -0
- package/templates/database/seed-test.ts +85 -0
- package/templates/database/tsconfig.build.json +16 -0
- package/templates/database/tsconfig.json +9 -0
- package/templates/package.json +125 -0
- package/templates/pnpm-workspace.yaml +6 -0
- package/templates/project.yaml +59 -0
- package/templates/tsconfig.base.json +18 -0
- package/templates/tsconfig.json +45 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: suggest-site-pages
|
|
3
|
+
description: Recommend a starter set of website pages — each tagged with the schema.org type to use — from a free-text business description. Use when the user is opening a new AI Launch Kit project, asks "what pages should this site have?", "help me plan my pages", "what should I build first" for a website, or describes a business in plain language and wants a page plan back. The output is shaped so each line can be passed straight to the `scaffold-page` skill.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# suggest-site-pages
|
|
7
|
+
|
|
8
|
+
Turn a free-text business description into an ordered list of pages, with the
|
|
9
|
+
right schema.org type per page, that the user can build with `scaffold-page`.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
|
|
13
|
+
The user is in a fresh `pnpm create ailk` project (or any AI Launch Kit
|
|
14
|
+
project that has no pages yet) and needs a plan for what to build. They
|
|
15
|
+
describe their business — "I'm building a SaaS for accountants", "I'm
|
|
16
|
+
opening a pizza restaurant", "I'm launching my law firm" — and want a
|
|
17
|
+
page list back, not a generic site-builder questionnaire.
|
|
18
|
+
|
|
19
|
+
Skip this skill when:
|
|
20
|
+
|
|
21
|
+
- The user already has a page list and just wants one more page added
|
|
22
|
+
(use `scaffold-page` directly).
|
|
23
|
+
- The user is asking about page _content_, not page _structure_ (answer
|
|
24
|
+
conversationally; this skill is about which pages exist, not what
|
|
25
|
+
goes inside them).
|
|
26
|
+
- The user wants schema added to an _existing_ page (use `add-schema`).
|
|
27
|
+
|
|
28
|
+
## What you produce
|
|
29
|
+
|
|
30
|
+
An ordered list, one line per page, in this exact format:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
<slug> — <Schema.orgType> — <one-sentence purpose>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Example for a SaaS for accountants:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
home — HomePage — top-of-funnel landing with the headline value prop
|
|
40
|
+
about — AboutPage — company story and team
|
|
41
|
+
pricing — Product — public price tiers and feature comparison
|
|
42
|
+
features — ServicesList — what the product does, broken into capabilities
|
|
43
|
+
contact — ContactPage — sales and support entry point
|
|
44
|
+
privacy — PrivacyPage — privacy policy
|
|
45
|
+
terms — TermsPage — terms of service
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Each line is a copy-paste plan: the user (or you, on their next turn)
|
|
49
|
+
can hand any line to `scaffold-page` and the chain works because the
|
|
50
|
+
schema type is the input contract `scaffold-page` expects.
|
|
51
|
+
|
|
52
|
+
## The mechanic
|
|
53
|
+
|
|
54
|
+
### Step 1 — Identify the category
|
|
55
|
+
|
|
56
|
+
Match the user's description to one of the **10 v1 categories**:
|
|
57
|
+
|
|
58
|
+
1. SaaS
|
|
59
|
+
2. E-commerce
|
|
60
|
+
3. Service business (restaurant / salon / contractor / gym)
|
|
61
|
+
4. Professional services (law / accounting / consulting / agency)
|
|
62
|
+
5. Marketplace
|
|
63
|
+
6. Content / Blog
|
|
64
|
+
7. Course / Education
|
|
65
|
+
8. Real estate
|
|
66
|
+
9. Healthcare / Medical
|
|
67
|
+
10. Nonprofit / Org
|
|
68
|
+
|
|
69
|
+
The full corpus — each category's entity tag, page list, and schemas —
|
|
70
|
+
lives in `references/categories.md`. **Read that file** before producing
|
|
71
|
+
the page list. Don't try to remember it.
|
|
72
|
+
|
|
73
|
+
If the description doesn't match any of the 10, do **not** invent a
|
|
74
|
+
category. Say:
|
|
75
|
+
|
|
76
|
+
> "That's not in the v1 catalog. The closest matches are **\<X\>** and
|
|
77
|
+
> **\<Y\>**. Would you like to use one of those, or describe your business
|
|
78
|
+
> differently?"
|
|
79
|
+
|
|
80
|
+
The two closest matches come from `references/categories.md` — pick
|
|
81
|
+
whichever categories share the most surface area with the user's
|
|
82
|
+
description (e.g., "research consortium" → Professional services and
|
|
83
|
+
Nonprofit / Org).
|
|
84
|
+
|
|
85
|
+
### Step 2 — Disambiguate Person vs Organization (when needed)
|
|
86
|
+
|
|
87
|
+
Each category in `references/categories.md` carries an **entity tag**:
|
|
88
|
+
`organization`, `person`, or `both`. The tag drives the next step.
|
|
89
|
+
|
|
90
|
+
- **`organization`** — skip the question. Marketplaces are always
|
|
91
|
+
organizations, SaaS is always an organization. Proceed to Step 3.
|
|
92
|
+
- **`person`** — skip the question. A "personal poetry blog" is always
|
|
93
|
+
a Person. Proceed to Step 3.
|
|
94
|
+
- **`both`** — the consumer could be either. This is where the
|
|
95
|
+
disambiguation matters: a solo lawyer's home page anchors on `Person`,
|
|
96
|
+
a law firm's anchors on `Organization`, and the page recommendations
|
|
97
|
+
shift accordingly.
|
|
98
|
+
|
|
99
|
+
For `both`-tagged categories, first check whether the user's free-text
|
|
100
|
+
**already settles it**. Phrases like:
|
|
101
|
+
|
|
102
|
+
- "my brokerage", "our firm", "the company", "we're a clinic" → Organization
|
|
103
|
+
- "I'm a solo \<role\>", "as an independent \<role\>", "my personal", "I'm a freelance" → Person
|
|
104
|
+
|
|
105
|
+
If the description settles it, **infer and confirm** rather than ask blind:
|
|
106
|
+
|
|
107
|
+
> "Got it — sounds like you're operating as an individual. I'll plan
|
|
108
|
+
> the pages around a Person identity. Does that match?"
|
|
109
|
+
|
|
110
|
+
If it's genuinely ambiguous, **ask once**:
|
|
111
|
+
|
|
112
|
+
> "Are you operating as an individual practitioner or as a business
|
|
113
|
+
> entity (firm / company / organization)? It changes which schemas
|
|
114
|
+
> anchor your home, about, and contact pages."
|
|
115
|
+
|
|
116
|
+
Then proceed to Step 3 with the answer.
|
|
117
|
+
|
|
118
|
+
### Step 3 — Emit the page list
|
|
119
|
+
|
|
120
|
+
Look up the category in `references/categories.md`. Use:
|
|
121
|
+
|
|
122
|
+
- The **page list** for that category, in the listed order.
|
|
123
|
+
- The **primary schema.org type** for each page, adjusted for the
|
|
124
|
+
Person-vs-Organization choice from Step 2 where the corpus calls it
|
|
125
|
+
out (typically the home, about, and contact pages).
|
|
126
|
+
|
|
127
|
+
Format every line as `<slug> — <Schema.orgType> — <one-sentence purpose>`.
|
|
128
|
+
The slugs come from the corpus; don't invent new ones. The one-sentence
|
|
129
|
+
purpose can be lifted from the corpus or rephrased — keep it short.
|
|
130
|
+
|
|
131
|
+
After the list, add one line:
|
|
132
|
+
|
|
133
|
+
> "Pass any of these to `scaffold-page` to generate the page."
|
|
134
|
+
|
|
135
|
+
## Person vs Organization — how it actually maps
|
|
136
|
+
|
|
137
|
+
The Person/Organization choice cascades into the **identity attached to
|
|
138
|
+
the page**, not into a different per-page type. `HomePage`, `AboutPage`,
|
|
139
|
+
and `ContactPage` are entity-agnostic; only the `Organization` vs
|
|
140
|
+
`Person` identity inside the JSON-LD changes.
|
|
141
|
+
|
|
142
|
+
`@working-theory/schema` does **not** ship narrower types like `Attorney`,
|
|
143
|
+
`Physician`, `RealEstateAgent`, `LegalService`, `MedicalBusiness`, or
|
|
144
|
+
`EducationalOrganization` at v1. If the user mentions a category whose
|
|
145
|
+
"natural" schema is one of those, fall back to the closest type from
|
|
146
|
+
the supported catalog — typically `ServicesList` / `Service` for
|
|
147
|
+
service-shaped categories. The corpus already does this for you.
|
|
148
|
+
|
|
149
|
+
## Invocation contract
|
|
150
|
+
|
|
151
|
+
This skill is **conversational only**. It is not a CLI command, not an
|
|
152
|
+
MCP tool. The user invokes it by talking to Claude in plain language.
|
|
153
|
+
|
|
154
|
+
## The `references/` convention
|
|
155
|
+
|
|
156
|
+
This skill establishes a pattern: **`SKILL.md` holds the mechanic; the
|
|
157
|
+
knowledge corpus lives in `references/<corpus>.md`**.
|
|
158
|
+
|
|
159
|
+
- `SKILL.md` describes how to invoke the skill, the steps to run, the
|
|
160
|
+
output format, and pointers into the corpus. It stays short — under
|
|
161
|
+
500 lines is the budget — so the whole skill is auditable in under
|
|
162
|
+
ten minutes.
|
|
163
|
+
- `references/<corpus>.md` holds the data the skill operates on. For
|
|
164
|
+
this skill, that's `references/categories.md`: 10 categories, each
|
|
165
|
+
with entity tag, page list, and primary schema per page. Editing the
|
|
166
|
+
corpus is a single-file change; the mechanic stays untouched.
|
|
167
|
+
|
|
168
|
+
Other OSS skills that need a knowledge corpus (`add-schema` for
|
|
169
|
+
primary/supplementary tagging, `provision-config` for persistence
|
|
170
|
+
options) should adopt the same shape.
|
|
171
|
+
|
|
172
|
+
## Worked examples
|
|
173
|
+
|
|
174
|
+
**Example 1 — SaaS (unambiguous Organization)**
|
|
175
|
+
|
|
176
|
+
User: "I'm building a SaaS for dental practices to manage appointments."
|
|
177
|
+
|
|
178
|
+
You:
|
|
179
|
+
|
|
180
|
+
1. Category → SaaS
|
|
181
|
+
2. Entity tag → `organization`. No question.
|
|
182
|
+
3. Read `references/categories.md` § SaaS, emit:
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
home — HomePage — top-of-funnel landing with the headline value prop
|
|
186
|
+
about — AboutPage — company story and team
|
|
187
|
+
pricing — Product — public price tiers and feature comparison
|
|
188
|
+
features — ServicesList — what the product does, broken into capabilities
|
|
189
|
+
contact — ContactPage — sales and support entry point
|
|
190
|
+
privacy — PrivacyPage — privacy policy
|
|
191
|
+
terms — TermsPage — terms of service
|
|
192
|
+
|
|
193
|
+
Pass any of these to scaffold-page to generate the page.
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Example 2 — Law firm (ambiguous, asks)**
|
|
197
|
+
|
|
198
|
+
User: "What pages should I have for my law firm?"
|
|
199
|
+
|
|
200
|
+
You: "Are you operating as an individual lawyer or as a law firm
|
|
201
|
+
entity? It changes which schemas anchor your home, about, and contact
|
|
202
|
+
pages."
|
|
203
|
+
|
|
204
|
+
User: "It's a firm with five attorneys."
|
|
205
|
+
|
|
206
|
+
You: read `references/categories.md` § Professional services, render
|
|
207
|
+
the list with `Organization` as the home/about/contact identity.
|
|
208
|
+
|
|
209
|
+
**Example 3 — Real estate (free-text settles it)**
|
|
210
|
+
|
|
211
|
+
User: "What pages should I have for a real estate brokerage?"
|
|
212
|
+
|
|
213
|
+
You: "Got it — 'brokerage' tells me you're operating as an organization,
|
|
214
|
+
not a solo agent. I'll plan around an Organization identity. Does that
|
|
215
|
+
match?" Then proceed.
|
|
216
|
+
|
|
217
|
+
**Example 4 — Personal blog (unambiguous Person)**
|
|
218
|
+
|
|
219
|
+
User: "What pages should I have for my personal poetry blog?"
|
|
220
|
+
|
|
221
|
+
You:
|
|
222
|
+
|
|
223
|
+
1. Category → Content / Blog
|
|
224
|
+
2. Entity tag → `person` (the corpus tags personal blogs as Person). No
|
|
225
|
+
question.
|
|
226
|
+
3. Render the blog page list with `Person` as the home/about identity.
|
|
227
|
+
|
|
228
|
+
**Example 5 — Out of catalog**
|
|
229
|
+
|
|
230
|
+
User: "What pages should I have for a quantum-computing research
|
|
231
|
+
consortium?"
|
|
232
|
+
|
|
233
|
+
You: "That's not in the v1 catalog. The closest matches are
|
|
234
|
+
**Professional services** and **Nonprofit / Org**. Would you like to use
|
|
235
|
+
one of those, or describe your business differently?"
|
|
236
|
+
|
|
237
|
+
## When the user pushes back
|
|
238
|
+
|
|
239
|
+
The corpus is opinionated, not authoritative. If the user disputes a
|
|
240
|
+
schema choice, explain why the corpus tagged it that way, then offer
|
|
241
|
+
to override — `scaffold-page` accepts any type from the supported
|
|
242
|
+
catalog. Don't argue.
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Site-page categories — v1 corpus
|
|
2
|
+
|
|
3
|
+
The 10 business categories `suggest-site-pages` knows about, with the
|
|
4
|
+
ordered page list and primary schema.org type for each page. Schemas
|
|
5
|
+
are drawn from the 45 types `@working-theory/schema` builds; nothing in this
|
|
6
|
+
file should reference a type the package can't generate.
|
|
7
|
+
|
|
8
|
+
## How to read this file
|
|
9
|
+
|
|
10
|
+
Each category section has:
|
|
11
|
+
|
|
12
|
+
1. **Name and description** — what the category covers.
|
|
13
|
+
2. **Entity tag** — `organization`, `person`, or `both`. Drives whether
|
|
14
|
+
`suggest-site-pages` asks the Person-vs-Organization disambiguation
|
|
15
|
+
question.
|
|
16
|
+
3. **Page list** — ordered. The slug is what `scaffold-page` will use.
|
|
17
|
+
4. **Primary schema per page** — the `Schema.orgType` to emit.
|
|
18
|
+
|
|
19
|
+
When the entity tag is `both`, some pages (typically home, about,
|
|
20
|
+
contact) carry an identity that flips between `Organization` and
|
|
21
|
+
`Person` based on the consumer's answer. The page's _own_ schema type
|
|
22
|
+
(`HomePage`, `AboutPage`, `ContactPage`) does not change; only the
|
|
23
|
+
identity attached inside the JSON-LD does.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## SaaS
|
|
28
|
+
|
|
29
|
+
Software-as-a-service products — anything where the value prop is
|
|
30
|
+
"sign up and use the software." Includes vertical SaaS, horizontal
|
|
31
|
+
tools, dev platforms, and self-serve B2B.
|
|
32
|
+
|
|
33
|
+
- **Entity tag:** `organization`
|
|
34
|
+
- **Pages:**
|
|
35
|
+
|
|
36
|
+
| Slug | Schema.orgType | Purpose |
|
|
37
|
+
| ---------- | -------------- | -------------------------------------------------- |
|
|
38
|
+
| `home` | `HomePage` | top-of-funnel landing with the headline value prop |
|
|
39
|
+
| `about` | `AboutPage` | company story and team |
|
|
40
|
+
| `pricing` | `Product` | public price tiers and feature comparison |
|
|
41
|
+
| `features` | `ServicesList` | what the product does, broken into capabilities |
|
|
42
|
+
| `contact` | `ContactPage` | sales and support entry point |
|
|
43
|
+
| `privacy` | `PrivacyPage` | privacy policy |
|
|
44
|
+
| `terms` | `TermsPage` | terms of service |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## E-commerce
|
|
49
|
+
|
|
50
|
+
Direct-to-consumer or B2B storefronts selling physical or digital
|
|
51
|
+
goods. The catalog is the primary surface; everything else supports it.
|
|
52
|
+
|
|
53
|
+
- **Entity tag:** `organization`
|
|
54
|
+
- **Pages:**
|
|
55
|
+
|
|
56
|
+
| Slug | Schema.orgType | Purpose |
|
|
57
|
+
| --------- | -------------- | ------------------------------------------- |
|
|
58
|
+
| `home` | `HomePage` | featured products and category entry points |
|
|
59
|
+
| `shop` | `ProductsList` | the full catalog |
|
|
60
|
+
| `about` | `AboutPage` | brand story and what the company makes |
|
|
61
|
+
| `contact` | `ContactPage` | customer-service entry point |
|
|
62
|
+
| `faq` | `FAQPage` | shipping, returns, sizing, common questions |
|
|
63
|
+
| `privacy` | `PrivacyPage` | privacy policy |
|
|
64
|
+
| `terms` | `TermsPage` | terms of service |
|
|
65
|
+
|
|
66
|
+
Per-product pages use `Product` and live under `shop/<product-slug>`.
|
|
67
|
+
`scaffold-page` handles them one at a time once the user has the
|
|
68
|
+
catalog page.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Service business
|
|
73
|
+
|
|
74
|
+
Restaurant, salon, contractor, gym, plumber, cleaner — anyone whose
|
|
75
|
+
business is "show up and do the work." Owner is usually an entity
|
|
76
|
+
(LLC / corp), occasionally a sole proprietor.
|
|
77
|
+
|
|
78
|
+
- **Entity tag:** `both`
|
|
79
|
+
- **Pages:**
|
|
80
|
+
|
|
81
|
+
| Slug | Schema.orgType | Purpose |
|
|
82
|
+
| -------------- | ------------------ | --------------------------------------------------- |
|
|
83
|
+
| `home` | `HomePage` | what the business does, where, and how to book |
|
|
84
|
+
| `services` | `ServicesList` | menu of services offered |
|
|
85
|
+
| `about` | `AboutPage` | the operator's story and credentials |
|
|
86
|
+
| `contact` | `ContactPage` | hours, address, booking link |
|
|
87
|
+
| `testimonials` | `TestimonialsList` | customer reviews and quotes |
|
|
88
|
+
| `faq` | `FAQPage` | common questions about service, pricing, scheduling |
|
|
89
|
+
| `privacy` | `PrivacyPage` | privacy policy |
|
|
90
|
+
| `terms` | `TermsPage` | terms of service |
|
|
91
|
+
|
|
92
|
+
Individual services go under `services/<service-slug>` with `Service`
|
|
93
|
+
as the type. The home/about/contact pages anchor on `Organization` for
|
|
94
|
+
a business entity, `Person` for a sole proprietor.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Professional services
|
|
99
|
+
|
|
100
|
+
Law firms, accounting firms, consulting shops, marketing agencies — fee-for-engagement
|
|
101
|
+
expertise. Almost always firm-shaped at scale, but plenty of solo practitioners.
|
|
102
|
+
|
|
103
|
+
- **Entity tag:** `both`
|
|
104
|
+
- **Pages:**
|
|
105
|
+
|
|
106
|
+
| Slug | Schema.orgType | Purpose |
|
|
107
|
+
| -------------- | ----------------- | ------------------------------------------------- |
|
|
108
|
+
| `home` | `HomePage` | who the firm serves and what kinds of engagements |
|
|
109
|
+
| `services` | `ServicesList` | practice areas or service lines |
|
|
110
|
+
| `team` | `TeamList` | the people clients will work with |
|
|
111
|
+
| `case-studies` | `CaseStudiesList` | engagement outcomes and references |
|
|
112
|
+
| `about` | `AboutPage` | firm history, philosophy, credentials |
|
|
113
|
+
| `contact` | `ContactPage` | how to reach out about an engagement |
|
|
114
|
+
| `blog` | `BlogList` | thought leadership and updates |
|
|
115
|
+
| `privacy` | `PrivacyPage` | privacy policy |
|
|
116
|
+
| `terms` | `TermsPage` | terms of service |
|
|
117
|
+
|
|
118
|
+
For solo practitioners, drop the `team` page and anchor home/about/contact
|
|
119
|
+
on `Person` instead of `Organization`.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Marketplace
|
|
124
|
+
|
|
125
|
+
Two-sided platforms — buyers on one side, sellers/providers on the
|
|
126
|
+
other. Always organizational; an individual cannot be a marketplace.
|
|
127
|
+
|
|
128
|
+
- **Entity tag:** `organization`
|
|
129
|
+
- **Pages:**
|
|
130
|
+
|
|
131
|
+
| Slug | Schema.orgType | Purpose |
|
|
132
|
+
| ------------- | -------------- | ------------------------------------------------ |
|
|
133
|
+
| `home` | `HomePage` | the value prop for both sides of the marketplace |
|
|
134
|
+
| `for-buyers` | `ServicesList` | what buyers get and how it works |
|
|
135
|
+
| `for-sellers` | `ServicesList` | what sellers get and how to onboard |
|
|
136
|
+
| `browse` | `ProductsList` | the searchable catalog of listings |
|
|
137
|
+
| `about` | `AboutPage` | who runs the platform and why |
|
|
138
|
+
| `contact` | `ContactPage` | support entry point |
|
|
139
|
+
| `faq` | `FAQPage` | trust, payments, dispute resolution |
|
|
140
|
+
| `privacy` | `PrivacyPage` | privacy policy |
|
|
141
|
+
| `terms` | `TermsPage` | terms of service |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Content / Blog
|
|
146
|
+
|
|
147
|
+
Publications, personal blogs, newsletters with a website. The
|
|
148
|
+
defining feature: posts are the primary surface, not products or
|
|
149
|
+
services.
|
|
150
|
+
|
|
151
|
+
- **Entity tag:** `both`
|
|
152
|
+
- **Pages:**
|
|
153
|
+
|
|
154
|
+
| Slug | Schema.orgType | Purpose |
|
|
155
|
+
| --------- | -------------- | ----------------------------------------- |
|
|
156
|
+
| `home` | `HomePage` | recent and featured posts |
|
|
157
|
+
| `blog` | `BlogList` | the full archive |
|
|
158
|
+
| `about` | `AboutPage` | who writes and why |
|
|
159
|
+
| `contact` | `ContactPage` | how to reach the author or editorial team |
|
|
160
|
+
| `privacy` | `PrivacyPage` | privacy policy |
|
|
161
|
+
| `terms` | `TermsPage` | terms of service |
|
|
162
|
+
|
|
163
|
+
Individual posts use `BlogPosting`. A "personal" blog (one writer,
|
|
164
|
+
their name on the site) is `Person`; an editorial publication with a
|
|
165
|
+
masthead is `Organization`. Phrases like "personal" or "my" in the
|
|
166
|
+
description settle it as Person without asking.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Course / Education
|
|
171
|
+
|
|
172
|
+
Course providers, schools, online academies, individual instructors
|
|
173
|
+
selling courses. Core surface is the course catalog.
|
|
174
|
+
|
|
175
|
+
- **Entity tag:** `both`
|
|
176
|
+
- **Pages:**
|
|
177
|
+
|
|
178
|
+
| Slug | Schema.orgType | Purpose |
|
|
179
|
+
| -------------- | ------------------ | ------------------------------------------------ |
|
|
180
|
+
| `home` | `HomePage` | who the courses are for and the headline outcome |
|
|
181
|
+
| `courses` | `CoursesList` | catalog of available courses |
|
|
182
|
+
| `about` | `AboutPage` | instructor or institution story |
|
|
183
|
+
| `testimonials` | `TestimonialsList` | student outcomes and quotes |
|
|
184
|
+
| `contact` | `ContactPage` | enrollment and support |
|
|
185
|
+
| `faq` | `FAQPage` | format, prerequisites, certification |
|
|
186
|
+
| `privacy` | `PrivacyPage` | privacy policy |
|
|
187
|
+
| `terms` | `TermsPage` | terms of service |
|
|
188
|
+
|
|
189
|
+
Individual courses use `Course`. A solo instructor anchors on `Person`;
|
|
190
|
+
a school anchors on `Organization`.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Real estate
|
|
195
|
+
|
|
196
|
+
Brokerages, individual agents, property-management firms. The
|
|
197
|
+
disambiguation matters here: a solo agent's site looks different from
|
|
198
|
+
a brokerage's.
|
|
199
|
+
|
|
200
|
+
- **Entity tag:** `both`
|
|
201
|
+
- **Pages:**
|
|
202
|
+
|
|
203
|
+
| Slug | Schema.orgType | Purpose |
|
|
204
|
+
| -------------- | ------------------ | ------------------------------------------------------- |
|
|
205
|
+
| `home` | `HomePage` | what kinds of properties and which markets |
|
|
206
|
+
| `listings` | `ProductsList` | available properties (treat each property as a Product) |
|
|
207
|
+
| `services` | `ServicesList` | buyer / seller / rental representation |
|
|
208
|
+
| `about` | `AboutPage` | the agent's or brokerage's story and credentials |
|
|
209
|
+
| `team` | `TeamList` | the agents at the brokerage (skip for solo agents) |
|
|
210
|
+
| `testimonials` | `TestimonialsList` | client reviews |
|
|
211
|
+
| `contact` | `ContactPage` | how to reach out about a property |
|
|
212
|
+
| `privacy` | `PrivacyPage` | privacy policy |
|
|
213
|
+
| `terms` | `TermsPage` | terms of service |
|
|
214
|
+
|
|
215
|
+
Words like "brokerage", "team", "our agents" → `Organization`. "Solo
|
|
216
|
+
agent", "I represent" → `Person`. Drop the `team` page for solo
|
|
217
|
+
agents.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Healthcare / Medical
|
|
222
|
+
|
|
223
|
+
Clinics, solo practitioners, group practices, dental offices,
|
|
224
|
+
therapists, specialty practices. Privacy and credibility are
|
|
225
|
+
load-bearing here.
|
|
226
|
+
|
|
227
|
+
- **Entity tag:** `both`
|
|
228
|
+
- **Pages:**
|
|
229
|
+
|
|
230
|
+
| Slug | Schema.orgType | Purpose |
|
|
231
|
+
| ---------- | -------------- | ------------------------------------------------------ |
|
|
232
|
+
| `home` | `HomePage` | what care is offered and for whom |
|
|
233
|
+
| `services` | `ServicesList` | conditions treated and procedures offered |
|
|
234
|
+
| `team` | `TeamList` | the providers (skip for solo practitioners) |
|
|
235
|
+
| `about` | `AboutPage` | practice philosophy, credentials, affiliations |
|
|
236
|
+
| `faq` | `FAQPage` | insurance, scheduling, what to expect |
|
|
237
|
+
| `contact` | `ContactPage` | hours, address, intake form link |
|
|
238
|
+
| `privacy` | `PrivacyPage` | privacy policy (HIPAA-relevant; flag this to the user) |
|
|
239
|
+
| `terms` | `TermsPage` | terms of service |
|
|
240
|
+
|
|
241
|
+
Solo practitioner → `Person`; clinic or group practice → `Organization`.
|
|
242
|
+
Drop `team` for solo practitioners.
|
|
243
|
+
|
|
244
|
+
When emitting the privacy line, mention HIPAA: "Healthcare sites need
|
|
245
|
+
a HIPAA-aware privacy policy. The default `PrivacyPage` is a starting
|
|
246
|
+
point, not a finished policy."
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Nonprofit / Org
|
|
251
|
+
|
|
252
|
+
Nonprofits, advocacy groups, professional associations, foundations.
|
|
253
|
+
Always organizational by nature; even a one-person foundation
|
|
254
|
+
operates as an entity.
|
|
255
|
+
|
|
256
|
+
- **Entity tag:** `organization`
|
|
257
|
+
- **Pages:**
|
|
258
|
+
|
|
259
|
+
| Slug | Schema.orgType | Purpose |
|
|
260
|
+
| ---------- | -------------- | ------------------------------------------------------------- |
|
|
261
|
+
| `home` | `HomePage` | mission and what the org does this year |
|
|
262
|
+
| `programs` | `ServicesList` | programs the org runs |
|
|
263
|
+
| `about` | `AboutPage` | history, mission, governance |
|
|
264
|
+
| `team` | `TeamList` | staff and board |
|
|
265
|
+
| `partners` | `PartnersList` | funders, partners, supporting organizations |
|
|
266
|
+
| `events` | `EventsList` | upcoming events and campaigns |
|
|
267
|
+
| `donate` | `Service` | donation entry point (treat the act of donating as a Service) |
|
|
268
|
+
| `contact` | `ContactPage` | how to reach the org |
|
|
269
|
+
| `privacy` | `PrivacyPage` | privacy policy |
|
|
270
|
+
| `terms` | `TermsPage` | terms of service |
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Schema-builder coverage
|
|
275
|
+
|
|
276
|
+
Every `Schema.orgType` referenced above is a member of the
|
|
277
|
+
`SchemaOrgType` union exported by `@working-theory/schema` and has a builder
|
|
278
|
+
function. The v1 catalog uses 21 of the 45 supported types:
|
|
279
|
+
|
|
280
|
+
`HomePage`, `AboutPage`, `ContactPage`, `PrivacyPage`, `TermsPage`,
|
|
281
|
+
`Organization`, `Person`, `ServicesList`, `Service`, `ProductsList`,
|
|
282
|
+
`Product`, `FAQPage`, `TestimonialsList`, `TeamList`, `PartnersList`,
|
|
283
|
+
`EventsList`, `CoursesList`, `Course`, `BlogList`, `BlogPosting`,
|
|
284
|
+
`CaseStudiesList`.
|
|
285
|
+
|
|
286
|
+
The remaining 24 types are available to `scaffold-page` and `add-schema`
|
|
287
|
+
for per-page use but don't drive category recommendations.
|