blume 2.0.0 → 2.0.2
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/AGENTS.md +1 -1
- package/CHANGELOG.md +110 -0
- package/README.md +2 -2
- package/dist/cli/{chunk-f2972sbt.js → chunk-00gs3wqs.js} +1 -1
- package/dist/cli/{chunk-fa25z98p.js → chunk-273ygyr4.js} +4 -3
- package/dist/cli/chunk-273ygyr4.js.map +11 -0
- package/dist/cli/{chunk-pat2zzwc.js → chunk-3yce002v.js} +21 -8
- package/dist/cli/{chunk-pat2zzwc.js.map → chunk-3yce002v.js.map} +4 -4
- package/dist/cli/{chunk-d1tadaw7.js → chunk-4e9b9ra6.js} +17 -7
- package/dist/cli/chunk-4e9b9ra6.js.map +10 -0
- package/dist/cli/{chunk-zg2gtj10.js → chunk-5r8g91qn.js} +352 -676
- package/dist/cli/chunk-5r8g91qn.js.map +34 -0
- package/dist/cli/{chunk-11j0384y.js → chunk-6dtt0zfn.js} +14 -14
- package/dist/cli/{chunk-11j0384y.js.map → chunk-6dtt0zfn.js.map} +3 -3
- package/dist/cli/{chunk-bw22s759.js → chunk-6k4ftwze.js} +38 -19
- package/dist/cli/{chunk-bw22s759.js.map → chunk-6k4ftwze.js.map} +4 -4
- package/dist/cli/{chunk-sqn5t4q0.js → chunk-7mbqtmgb.js} +16 -7
- package/dist/cli/chunk-7mbqtmgb.js.map +10 -0
- package/dist/cli/{chunk-79njf86q.js → chunk-7vtckvaw.js} +21 -19
- package/dist/cli/chunk-7vtckvaw.js.map +11 -0
- package/dist/cli/{chunk-fh5hj5jt.js → chunk-8g8ytmgx.js} +17 -18
- package/dist/cli/{chunk-fh5hj5jt.js.map → chunk-8g8ytmgx.js.map} +2 -2
- package/dist/cli/{chunk-1w8dp3qb.js → chunk-91ws1n6j.js} +18 -15
- package/dist/cli/chunk-91ws1n6j.js.map +10 -0
- package/dist/cli/{chunk-7ez8ny0t.js → chunk-bbnwccaz.js} +2 -2
- package/dist/cli/{chunk-5a2z0198.js → chunk-bfwp9vp6.js} +18 -10
- package/dist/cli/chunk-bfwp9vp6.js.map +10 -0
- package/dist/cli/{chunk-ernrthtr.js → chunk-d1v5rhy0.js} +14 -15
- package/dist/cli/{chunk-ernrthtr.js.map → chunk-d1v5rhy0.js.map} +2 -2
- package/dist/cli/{chunk-a9kptbw5.js → chunk-ddndchfr.js} +21 -6
- package/dist/cli/chunk-ddndchfr.js.map +14 -0
- package/dist/cli/{chunk-zxccj738.js → chunk-esh98wmb.js} +1 -1
- package/dist/cli/{chunk-88cpgt6h.js → chunk-fsmrqk8a.js} +1 -1
- package/dist/cli/{chunk-b5aj94ah.js → chunk-g698a744.js} +5 -5
- package/dist/cli/{chunk-jts8mvcz.js → chunk-gs7r695n.js} +9 -3
- package/dist/cli/{chunk-jts8mvcz.js.map → chunk-gs7r695n.js.map} +3 -3
- package/dist/cli/{chunk-41za066z.js → chunk-h2ez8dzb.js} +4 -4
- package/dist/cli/{chunk-by2290sx.js → chunk-h7k3nq3v.js} +2 -2
- package/dist/cli/{chunk-j8mw0za6.js → chunk-hqp2ajnh.js} +252 -123
- package/dist/cli/chunk-hqp2ajnh.js.map +35 -0
- package/dist/cli/{chunk-mnqj32sj.js → chunk-hr8ne106.js} +119 -50
- package/dist/cli/chunk-hr8ne106.js.map +13 -0
- package/dist/cli/{chunk-mwt1k8n7.js → chunk-j85scx15.js} +74 -30
- package/dist/cli/chunk-j85scx15.js.map +10 -0
- package/dist/cli/{chunk-z01ze5c1.js → chunk-k7pj68a8.js} +63 -22
- package/dist/cli/chunk-k7pj68a8.js.map +11 -0
- package/dist/cli/{chunk-2q1dwty4.js → chunk-mqc662a6.js} +8 -8
- package/dist/cli/{chunk-2q1dwty4.js.map → chunk-mqc662a6.js.map} +4 -4
- package/dist/cli/{chunk-y3e45rc8.js → chunk-n1yg3tj3.js} +4 -4
- package/dist/cli/{chunk-bctazmbk.js → chunk-nfcyttvj.js} +17 -6
- package/dist/cli/chunk-nfcyttvj.js.map +10 -0
- package/dist/cli/{chunk-6k8vp3ta.js → chunk-pbg5a4s3.js} +60 -28
- package/dist/cli/chunk-pbg5a4s3.js.map +19 -0
- package/dist/cli/{chunk-d80hr03s.js → chunk-ppzjqwx2.js} +24 -17
- package/dist/cli/{chunk-d80hr03s.js.map → chunk-ppzjqwx2.js.map} +4 -4
- package/dist/cli/{chunk-beat36xx.js → chunk-qkb5a8sa.js} +25 -10
- package/dist/cli/chunk-qkb5a8sa.js.map +10 -0
- package/dist/cli/{chunk-bnbmcwfb.js → chunk-sqw4ekg1.js} +5 -5
- package/dist/cli/{chunk-bnbmcwfb.js.map → chunk-sqw4ekg1.js.map} +3 -3
- package/dist/cli/{chunk-xaz13gwg.js → chunk-v6ya5kcb.js} +3268 -1150
- package/dist/cli/chunk-v6ya5kcb.js.map +189 -0
- package/dist/cli/{chunk-tzne8qfq.js → chunk-w4bxdvsa.js} +18 -15
- package/dist/cli/chunk-w4bxdvsa.js.map +10 -0
- package/dist/cli/{chunk-f7t03s3g.js → chunk-wdrt2k2v.js} +2 -2
- package/dist/cli/{chunk-z1f5arsg.js → chunk-xh43dwgw.js} +170 -55
- package/dist/cli/chunk-xh43dwgw.js.map +36 -0
- package/dist/cli/{chunk-pnnvybbk.js → chunk-zp79m0ts.js} +5 -5
- package/dist/cli/{chunk-pnnvybbk.js.map → chunk-zp79m0ts.js.map} +2 -2
- package/dist/cli/index.js +160 -35
- package/dist/cli/index.js.map +4 -4
- package/dist/types/ai/agent-readability.d.ts +1 -1
- package/dist/types/ai/agent-surface.d.ts +32 -0
- package/dist/types/ai/api/paths.d.ts +1 -1
- package/dist/types/ai/api-catalog.d.ts +7 -1
- package/dist/types/ai/ask-context.d.ts +14 -7
- package/dist/types/ai/ask.d.ts +43 -43
- package/dist/types/ai/component-markdown.d.ts +4 -4
- package/dist/types/ai/index.d.ts +3 -3
- package/dist/types/ai/openapi-components.d.ts +1 -1
- package/dist/types/ai/relative-links.d.ts +9 -4
- package/dist/types/ai/serializers.d.ts +1 -1
- package/dist/types/ai/static-expression.d.ts +28 -0
- package/dist/types/ai/visibility.d.ts +1 -1
- package/dist/types/analytics/databuddy.d.ts +43 -0
- package/dist/types/analytics/index.d.ts +2 -0
- package/dist/types/analytics/schema.d.ts +14 -0
- package/dist/types/cli/env.d.ts +5 -0
- package/dist/types/cli/init/scaffold.d.ts +19 -3
- package/dist/types/cli/init/starter-spec.d.ts +11 -0
- package/dist/types/core/base-path.d.ts +9 -0
- package/dist/types/core/config-input.d.ts +21 -21
- package/dist/types/core/config.d.ts +5 -5
- package/dist/types/core/data.d.ts +3 -3
- package/dist/types/core/graph.d.ts +2 -0
- package/dist/types/core/i18n-ui.d.ts +37 -8
- package/dist/types/core/i18n.d.ts +7 -1
- package/dist/types/core/links.d.ts +3 -1
- package/dist/types/core/load-module.d.ts +10 -0
- package/dist/types/core/locale-links.d.ts +12 -2
- package/dist/types/core/meta.d.ts +5 -1
- package/dist/types/core/nav-diagnostics.d.ts +10 -0
- package/dist/types/core/navigation.d.ts +38 -0
- package/dist/types/core/ordering-prefix.d.ts +4 -0
- package/dist/types/core/safe-links.d.ts +3 -1
- package/dist/types/core/schema.d.ts +57 -18
- package/dist/types/core/sources/github-releases.d.ts +5 -0
- package/dist/types/core/sources/lower.d.ts +14 -2
- package/dist/types/core/sources/normalize.d.ts +10 -1
- package/dist/types/core/sources/remote.d.ts +11 -1
- package/dist/types/core/sources/resolve.d.ts +12 -0
- package/dist/types/core/sources/types.d.ts +31 -0
- package/dist/types/core/types.d.ts +9 -0
- package/dist/types/core/unrecognized-keys.d.ts +1 -1
- package/dist/types/deploy/adapters/node.d.ts +5 -2
- package/dist/types/deploy/adapters/types.d.ts +7 -0
- package/dist/types/deploy/cloudflare-negotiation.d.ts +3 -2
- package/dist/types/deploy/headers.d.ts +31 -7
- package/dist/types/deploy/node-headers.d.ts +43 -8
- package/dist/types/deploy/platforms/netlify.d.ts +27 -2
- package/dist/types/deploy/platforms/node.d.ts +6 -5
- package/dist/types/deploy/platforms/types.d.ts +7 -0
- package/dist/types/deploy/platforms/vercel.d.ts +3 -2
- package/dist/types/deploy/redirects.d.ts +7 -2
- package/dist/types/deploy/vercel-negotiation.d.ts +3 -2
- package/dist/types/openapi/model.d.ts +20 -6
- package/dist/types/search/documents.d.ts +1 -1
- package/dist/types/search/orama-index.d.ts +1 -1
- package/dist/types/search/sync/algolia.d.ts +3 -1
- package/docs/01-quickstart.mdx +3 -2
- package/docs/02-deployment.mdx +21 -12
- package/docs/03-upgrading.mdx +22 -9
- package/docs/04-migrating.mdx +4 -4
- package/docs/08-faq.mdx +12 -5
- package/docs/advanced/changelog.mdx +1 -1
- package/docs/advanced/custom-pages.mdx +5 -3
- package/docs/advanced/skills.mdx +1 -1
- package/docs/cli/audit.mdx +5 -5
- package/docs/cli/doctor.mdx +4 -4
- package/docs/cli/evals.mdx +9 -9
- package/docs/cli/index.mdx +6 -3
- package/docs/cli/translate.mdx +8 -8
- package/docs/configuration/analytics.mdx +23 -2
- package/docs/configuration/{ask-ai.mdx → assistant.mdx} +20 -20
- package/docs/configuration/customization.mdx +5 -4
- package/docs/configuration/index.mdx +7 -5
- package/docs/configuration/meta.ts +1 -1
- package/docs/configuration/search.mdx +2 -2
- package/docs/content/components.mdx +1 -1
- package/docs/content/frontmatter.mdx +5 -1
- package/docs/content/i18n.mdx +3 -3
- package/docs/content/index.mdx +4 -2
- package/docs/content/islands.mdx +1 -1
- package/docs/content/meta.mdx +5 -3
- package/docs/content/navigation.mdx +29 -4
- package/docs/content/sources.mdx +18 -12
- package/docs/content/versioning.mdx +1 -0
- package/docs/discoverability/agent-discovery.mdx +22 -8
- package/docs/discoverability/index.mdx +3 -3
- package/docs/discoverability/llms-txt.mdx +2 -5
- package/docs/discoverability/markdown.mdx +5 -3
- package/docs/discoverability/mcp.mdx +4 -0
- package/docs/discoverability/metadata.mdx +3 -2
- package/docs/discoverability/open-graph.mdx +6 -4
- package/docs/discoverability/rss.mdx +3 -1
- package/docs/index.mdx +2 -2
- package/docs/references/asyncapi.mdx +1 -1
- package/docs/references/graphql.mdx +2 -2
- package/docs/references/openapi.mdx +3 -3
- package/package.json +1 -1
- package/skills/blume/SKILL.md +5 -5
- package/skills/blume-migrate/SKILL.md +6 -6
- package/skills/blume-migrate/references/docusaurus.md +6 -6
- package/skills/blume-migrate/references/mintlify.md +3 -3
- package/skills/blume-migrate/references/monorepo.md +1 -1
- package/skills/blume-migrate/references/nextra.md +1 -1
- package/skills/blume-migrate/references/starlight.md +5 -5
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +2 -2
- package/skills/blume-update-docs/references/audit-checklist.md +1 -1
- package/src/ai/agent-readability.ts +4 -4
- package/src/ai/agent-surface.ts +56 -0
- package/src/ai/api/paths.ts +1 -1
- package/src/ai/api/spec.ts +15 -2
- package/src/ai/api-catalog.ts +7 -1
- package/src/ai/ask-context.ts +21 -9
- package/src/ai/ask-data.ts +28 -14
- package/src/ai/ask.ts +84 -71
- package/src/ai/component-markdown.ts +43 -37
- package/src/ai/cors.ts +3 -3
- package/src/ai/index.ts +16 -16
- package/src/ai/link-headers.ts +8 -3
- package/src/ai/llms.ts +4 -3
- package/src/ai/markdown.ts +23 -11
- package/src/ai/mcp/server.ts +78 -7
- package/src/ai/openapi-components.ts +1 -1
- package/src/ai/relative-links.ts +78 -10
- package/src/ai/serializers.ts +1 -1
- package/src/ai/static-expression.ts +416 -0
- package/src/ai/visibility.ts +46 -15
- package/src/analytics/databuddy.ts +67 -0
- package/src/analytics/head.ts +4 -0
- package/src/analytics/index.ts +2 -0
- package/src/analytics/posthog.ts +21 -3
- package/src/analytics/schema.ts +2 -0
- package/src/astro/generate.ts +90 -45
- package/src/astro/module-types.ts +1 -1
- package/src/astro/runtime-deps.ts +6 -6
- package/src/astro/templates.ts +87 -49
- package/src/audit/catalog.ts +2 -2
- package/src/audit/checks/assets.ts +25 -5
- package/src/audit/checks/content.ts +20 -2
- package/src/audit/checks/i18n.ts +46 -8
- package/src/audit/checks/indexability.ts +39 -19
- package/src/audit/checks/links.ts +14 -0
- package/src/audit/checks/llms.ts +6 -3
- package/src/audit/checks/network.ts +3 -1
- package/src/audit/checks/og-image.ts +10 -0
- package/src/audit/checks/robots.ts +6 -1
- package/src/audit/checks/sitemap.ts +56 -31
- package/src/audit/checks/social.ts +21 -2
- package/src/audit/crawl.ts +88 -15
- package/src/audit/report.ts +54 -17
- package/src/audit/run.ts +1 -0
- package/src/audit/types.ts +18 -0
- package/src/audit/url.ts +37 -6
- package/src/blume-modules.d.ts +2 -2
- package/src/cli/build-failure.ts +50 -0
- package/src/cli/commands/audit.ts +8 -1
- package/src/cli/commands/build.ts +19 -5
- package/src/cli/commands/check.ts +2 -0
- package/src/cli/commands/doctor.ts +7 -5
- package/src/cli/commands/eval.ts +4 -10
- package/src/cli/commands/init.ts +15 -5
- package/src/cli/commands/migrate.ts +2 -2
- package/src/cli/commands/preview.ts +15 -0
- package/src/cli/commands/sync.ts +2 -0
- package/src/cli/commands/translate.ts +12 -9
- package/src/cli/commands/upgrade.ts +13 -2
- package/src/cli/eject-scripts.ts +32 -7
- package/src/cli/env.ts +12 -1
- package/src/cli/init/scaffold.ts +117 -11
- package/src/cli/init/starter-spec.ts +235 -0
- package/src/cli/required-secrets.ts +3 -3
- package/src/components/content/AccordionItem.astro +26 -22
- package/src/components/content/Badge.astro +2 -9
- package/src/components/content/Card.astro +2 -2
- package/src/components/content/Component.astro +9 -3
- package/src/components/content/Expandable.astro +5 -1
- package/src/components/content/Frame.astro +2 -7
- package/src/components/content/GithubInfo.astro +12 -2
- package/src/components/content/Prompt.astro +2 -7
- package/src/components/content/Tabs.astro +54 -5
- package/src/components/content/Tile.astro +1 -1
- package/src/components/content/Tooltip.astro +69 -7
- package/src/components/content/Tree.astro +7 -2
- package/src/components/content/TypeTable.astro +10 -5
- package/src/components/content/Update.astro +8 -2
- package/src/components/content/auto-type-table.ts +4 -1
- package/src/components/content/badge-color.ts +17 -0
- package/src/components/content/base-href.ts +18 -3
- package/src/components/content/inline-markdown.ts +27 -7
- package/src/components/copy-feedback.ts +36 -9
- package/src/components/islands/{AskAI.astro → Assistant.astro} +10 -10
- package/src/components/islands/{ask-ai.tsx → assistant.tsx} +39 -25
- package/src/components/islands/hooks.ts +21 -14
- package/src/components/islands/webmcp.ts +12 -8
- package/src/components/layout/Banner.astro +23 -4
- package/src/components/layout/Header.astro +32 -19
- package/src/components/layout/Logo.astro +5 -0
- package/src/components/layout/NavSelector.astro +6 -1
- package/src/components/layout/NavTabMenu.astro +133 -0
- package/src/components/layout/NavTree.astro +15 -6
- package/src/components/layout/NavTreeCache.astro +5 -2
- package/src/components/layout/NavTreeScript.astro +45 -5
- package/src/components/layout/PageLayout.astro +28 -14
- package/src/components/layout/Pagination.astro +7 -7
- package/src/components/layout/ReferenceLayout.astro +5 -2
- package/src/components/layout/RootLayout.astro +27 -14
- package/src/components/layout/Search.astro +18 -14
- package/src/components/layout/analytics-client.ts +3 -1
- package/src/components/layout/drawer-inert.ts +1 -1
- package/src/components/openapi/GraphqlType.astro +11 -3
- package/src/components/openapi/MessageComposer.astro +1 -1
- package/src/components/openapi/Operation.astro +21 -5
- package/src/components/openapi/PanelTabs.astro +4 -1
- package/src/components/openapi/Playground.astro +8 -2
- package/src/components/openapi/RequestPanel.astro +9 -5
- package/src/components/openapi/SchemaProperty.astro +11 -33
- package/src/components/openapi/SchemaTable.astro +27 -52
- package/src/components/openapi/description.ts +2 -2
- package/src/components/openapi/helpers.ts +90 -12
- package/src/components/openapi/message-composer.ts +8 -0
- package/src/components/openapi/message-model.ts +12 -2
- package/src/components/openapi/message.ts +4 -1
- package/src/components/openapi/operation-model.ts +40 -8
- package/src/components/openapi/panel.ts +29 -5
- package/src/components/openapi/playground-client.ts +37 -7
- package/src/components/openapi/playground-schema.ts +25 -6
- package/src/components/openapi/request.ts +2 -0
- package/src/components/openapi/schema-tree.ts +203 -0
- package/src/components/openapi/snippets.ts +30 -15
- package/src/components/openapi/validate-json.ts +1 -1
- package/src/core/base-path.ts +15 -0
- package/src/core/code-fences.ts +1 -1
- package/src/core/config-input.ts +23 -23
- package/src/core/config.ts +21 -7
- package/src/core/data.ts +3 -3
- package/src/core/diagnostics.ts +217 -30
- package/src/core/graph.ts +120 -11
- package/src/core/i18n-ui.ts +74 -11
- package/src/core/i18n.ts +13 -2
- package/src/core/links.ts +7 -4
- package/src/core/load-module.ts +20 -0
- package/src/core/locale-links.ts +17 -17
- package/src/core/manifest.ts +3 -2
- package/src/core/meta.ts +69 -6
- package/src/core/nav-diagnostics.ts +56 -1
- package/src/core/navigation.ts +245 -76
- package/src/core/ordering-prefix.ts +27 -0
- package/src/core/project-graph.ts +23 -1
- package/src/core/request-body.ts +1 -1
- package/src/core/safe-href.ts +53 -1
- package/src/core/safe-links.ts +11 -2
- package/src/core/schema.ts +95 -34
- package/src/core/server-features.ts +2 -2
- package/src/core/sources/assets.ts +83 -41
- package/src/core/sources/contentful-rich-text.ts +3 -2
- package/src/core/sources/contentful.ts +25 -12
- package/src/core/sources/filesystem.ts +5 -1
- package/src/core/sources/github-releases.ts +106 -5
- package/src/core/sources/lexical.ts +9 -4
- package/src/core/sources/lower.ts +79 -26
- package/src/core/sources/mdx-remote.ts +1 -0
- package/src/core/sources/normalize.ts +132 -30
- package/src/core/sources/notion.ts +26 -10
- package/src/core/sources/obsidian.ts +17 -3
- package/src/core/sources/payload.ts +1 -0
- package/src/core/sources/portable-text.ts +63 -44
- package/src/core/sources/remote.ts +18 -2
- package/src/core/sources/resolve.ts +52 -33
- package/src/core/sources/sanity.ts +1 -0
- package/src/core/sources/strapi-blocks.ts +9 -4
- package/src/core/sources/strapi.ts +1 -0
- package/src/core/sources/types.ts +31 -0
- package/src/core/types.ts +9 -0
- package/src/core/ui-packs/ar.ts +17 -5
- package/src/core/ui-packs/bg.ts +17 -5
- package/src/core/ui-packs/bn.ts +17 -5
- package/src/core/ui-packs/ca.ts +17 -5
- package/src/core/ui-packs/cs.ts +17 -5
- package/src/core/ui-packs/da.ts +17 -5
- package/src/core/ui-packs/de.ts +17 -5
- package/src/core/ui-packs/el.ts +17 -5
- package/src/core/ui-packs/es.ts +17 -5
- package/src/core/ui-packs/fa.ts +17 -5
- package/src/core/ui-packs/fi.ts +17 -5
- package/src/core/ui-packs/fr.ts +17 -5
- package/src/core/ui-packs/he.ts +17 -5
- package/src/core/ui-packs/hi.ts +17 -5
- package/src/core/ui-packs/hr.ts +17 -5
- package/src/core/ui-packs/hu.ts +17 -5
- package/src/core/ui-packs/id.ts +17 -5
- package/src/core/ui-packs/it.ts +17 -5
- package/src/core/ui-packs/ja.ts +17 -5
- package/src/core/ui-packs/ko.ts +17 -5
- package/src/core/ui-packs/nl.ts +17 -5
- package/src/core/ui-packs/no.ts +17 -5
- package/src/core/ui-packs/pl.ts +17 -5
- package/src/core/ui-packs/pt-br.ts +17 -5
- package/src/core/ui-packs/pt.ts +17 -5
- package/src/core/ui-packs/ro.ts +17 -5
- package/src/core/ui-packs/ru.ts +17 -5
- package/src/core/ui-packs/sk.ts +17 -5
- package/src/core/ui-packs/sr.ts +17 -5
- package/src/core/ui-packs/sv.ts +17 -5
- package/src/core/ui-packs/th.ts +17 -5
- package/src/core/ui-packs/tr.ts +17 -5
- package/src/core/ui-packs/uk.ts +17 -5
- package/src/core/ui-packs/vi.ts +17 -5
- package/src/core/ui-packs/zh-tw.ts +17 -5
- package/src/core/ui-packs/zh.ts +17 -5
- package/src/core/unrecognized-keys.ts +1 -1
- package/src/core/version-cut.ts +17 -2
- package/src/core/versions.ts +4 -1
- package/src/deploy/adapters/node.ts +5 -2
- package/src/deploy/adapters/registry.ts +2 -1
- package/src/deploy/adapters/types.ts +13 -1
- package/src/deploy/artifacts.ts +25 -5
- package/src/deploy/cloudflare-negotiation.ts +23 -4
- package/src/deploy/headers.ts +67 -51
- package/src/deploy/node-headers.ts +148 -27
- package/src/deploy/platforms/cloudflare.ts +1 -0
- package/src/deploy/platforms/netlify.ts +82 -5
- package/src/deploy/platforms/node.ts +7 -5
- package/src/deploy/platforms/static.ts +1 -0
- package/src/deploy/platforms/types.ts +7 -0
- package/src/deploy/platforms/vercel.ts +9 -3
- package/src/deploy/redirects.ts +14 -3
- package/src/deploy/vercel-negotiation.ts +35 -3
- package/src/eval/agents.ts +10 -2
- package/src/eval/run.ts +25 -0
- package/src/markdown/base-links.ts +55 -8
- package/src/markdown/index.ts +6 -3
- package/src/markdown/relative-links.ts +3 -23
- package/src/markdown/route-snapshot.ts +37 -0
- package/src/og/card.ts +20 -4
- package/src/og/derive.ts +145 -4
- package/src/openapi/graphql-build.ts +28 -2
- package/src/openapi/model.ts +77 -13
- package/src/openapi/render-mdx.ts +10 -1
- package/src/registry/eject.ts +135 -37
- package/src/search/documents.ts +24 -3
- package/src/search/orama-index.ts +1 -1
- package/src/search/sync/algolia.ts +36 -2
- package/src/sources/registry.ts +5 -0
- package/src/theme/entry.ts +11 -4
- package/src/translate/agents.ts +6 -1
- package/src/translate/ledger.ts +26 -3
- package/src/translate/meta.ts +11 -3
- package/src/translate/report.ts +1 -1
- package/src/translate/run.ts +11 -5
- package/src/translate/validate.ts +10 -1
- package/src/translate/work-list.ts +36 -3
- package/src/upgrade/upgrade.ts +37 -5
- package/dist/cli/chunk-1w8dp3qb.js.map +0 -10
- package/dist/cli/chunk-5a2z0198.js.map +0 -10
- package/dist/cli/chunk-6k8vp3ta.js.map +0 -19
- package/dist/cli/chunk-79njf86q.js.map +0 -11
- package/dist/cli/chunk-a9kptbw5.js.map +0 -14
- package/dist/cli/chunk-abh8yjkn.js +0 -31
- package/dist/cli/chunk-abh8yjkn.js.map +0 -10
- package/dist/cli/chunk-bctazmbk.js.map +0 -10
- package/dist/cli/chunk-beat36xx.js.map +0 -10
- package/dist/cli/chunk-d1tadaw7.js.map +0 -10
- package/dist/cli/chunk-fa25z98p.js.map +0 -11
- package/dist/cli/chunk-j8mw0za6.js.map +0 -35
- package/dist/cli/chunk-mnqj32sj.js.map +0 -12
- package/dist/cli/chunk-mwt1k8n7.js.map +0 -10
- package/dist/cli/chunk-nk3ts2xk.js +0 -51
- package/dist/cli/chunk-nk3ts2xk.js.map +0 -10
- package/dist/cli/chunk-sqn5t4q0.js.map +0 -10
- package/dist/cli/chunk-tzne8qfq.js.map +0 -10
- package/dist/cli/chunk-xaz13gwg.js.map +0 -182
- package/dist/cli/chunk-z01ze5c1.js.map +0 -10
- package/dist/cli/chunk-z1f5arsg.js.map +0 -36
- package/dist/cli/chunk-zg2gtj10.js.map +0 -35
- /package/dist/cli/{chunk-f2972sbt.js.map → chunk-00gs3wqs.js.map} +0 -0
- /package/dist/cli/{chunk-7ez8ny0t.js.map → chunk-bbnwccaz.js.map} +0 -0
- /package/dist/cli/{chunk-zxccj738.js.map → chunk-esh98wmb.js.map} +0 -0
- /package/dist/cli/{chunk-88cpgt6h.js.map → chunk-fsmrqk8a.js.map} +0 -0
- /package/dist/cli/{chunk-b5aj94ah.js.map → chunk-g698a744.js.map} +0 -0
- /package/dist/cli/{chunk-41za066z.js.map → chunk-h2ez8dzb.js.map} +0 -0
- /package/dist/cli/{chunk-by2290sx.js.map → chunk-h7k3nq3v.js.map} +0 -0
- /package/dist/cli/{chunk-y3e45rc8.js.map → chunk-n1yg3tj3.js.map} +0 -0
- /package/dist/cli/{chunk-f7t03s3g.js.map → chunk-wdrt2k2v.js.map} +0 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import {
|
|
2
|
+
objectProperties,
|
|
3
|
+
refName,
|
|
4
|
+
resolveSchema,
|
|
5
|
+
typeLabel,
|
|
6
|
+
} from "./helpers.ts";
|
|
7
|
+
import type { SchemaLike, SpecValue } from "./helpers.ts";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The expansion plan behind the schema tables (`SchemaTable.astro` and
|
|
11
|
+
* `SchemaProperty.astro`). Every nested object is server-rendered in full
|
|
12
|
+
* inside a collapsed `<details>`, so the plan is the page's weight: expanding
|
|
13
|
+
* each named schema wherever it appears — stopping only at a model nested in
|
|
14
|
+
* itself — grows exponentially with cross-references (twelve schemas that
|
|
15
|
+
* each reference four others render tens of thousands of nested tables for
|
|
16
|
+
* one request body).
|
|
17
|
+
*
|
|
18
|
+
* So a named schema expands wherever it appears in the first
|
|
19
|
+
* {@link REPEAT_DEPTH} named levels, and deeper than that only where it
|
|
20
|
+
* appears first in the tree, breadth-first; a later mention shows its name
|
|
21
|
+
* alone. Beyond the first levels each named schema expands at most once, so
|
|
22
|
+
* the tree stays proportional to the spec instead of to the number of paths
|
|
23
|
+
* through it, while the shallow nesting typical specs use — `billing` and
|
|
24
|
+
* `shipping` both an `Address` — renders exactly as before.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Named-schema nesting depth (the root being 0) up to which a named schema
|
|
29
|
+
* expands at every mention, even one already expanded elsewhere in the tree.
|
|
30
|
+
*/
|
|
31
|
+
export const REPEAT_DEPTH = 2;
|
|
32
|
+
|
|
33
|
+
/** A place in the tree a node is planned into; filled in breadth-first. */
|
|
34
|
+
export interface SchemaSlot {
|
|
35
|
+
node: SchemaNode;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** One property row of an object table. */
|
|
39
|
+
export interface SchemaRow {
|
|
40
|
+
name: string;
|
|
41
|
+
required: boolean;
|
|
42
|
+
schema: SchemaLike;
|
|
43
|
+
/** The row's disclosure contents; absent when the row has nothing to show. */
|
|
44
|
+
children?: SchemaSlot;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** What one schema table renders. */
|
|
48
|
+
export type SchemaNode =
|
|
49
|
+
/** A named schema nested inside itself. */
|
|
50
|
+
| { kind: "circular"; name: string }
|
|
51
|
+
/** A named schema expanded elsewhere in this tree: its name only. */
|
|
52
|
+
| { kind: "named"; name: string }
|
|
53
|
+
| { kind: "array"; itemsLabel: string; items?: SchemaSlot }
|
|
54
|
+
| {
|
|
55
|
+
kind: "branches";
|
|
56
|
+
label: "One of" | "Any of";
|
|
57
|
+
branches: { label: string; slot: SchemaSlot }[];
|
|
58
|
+
}
|
|
59
|
+
| { kind: "properties"; rows: SchemaRow[] }
|
|
60
|
+
| { kind: "type"; label: string };
|
|
61
|
+
|
|
62
|
+
const isString = (value: SpecValue): value is string =>
|
|
63
|
+
typeof value === "string";
|
|
64
|
+
|
|
65
|
+
const typesOf = (schema: SchemaLike): (string | undefined)[] =>
|
|
66
|
+
Array.isArray(schema.type) ? schema.type : [schema.type];
|
|
67
|
+
|
|
68
|
+
/** Whether a schema has nested fields a row can disclose. */
|
|
69
|
+
const hasNestedFields = (candidate: SchemaLike): boolean =>
|
|
70
|
+
Boolean(
|
|
71
|
+
candidate.properties ||
|
|
72
|
+
candidate.allOf ||
|
|
73
|
+
candidate.oneOf ||
|
|
74
|
+
candidate.anyOf ||
|
|
75
|
+
isString(candidate.$ref)
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
/** A named schema waiting for its breadth-first turn. */
|
|
79
|
+
interface PendingRef {
|
|
80
|
+
ancestors: string[];
|
|
81
|
+
name: string;
|
|
82
|
+
schema: SchemaLike;
|
|
83
|
+
slot: SchemaSlot;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Plan the table tree for one schema (a request body, a response, a payload). */
|
|
87
|
+
export const schemaTree = (
|
|
88
|
+
root: SchemaLike,
|
|
89
|
+
schemas: Record<string, SchemaLike>
|
|
90
|
+
): SchemaNode => {
|
|
91
|
+
const queue: PendingRef[] = [];
|
|
92
|
+
const expanded = new Set<string>();
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* A table for `schema`, where `ancestors` are the named schemas already
|
|
96
|
+
* open above it. A `$ref` waits in the queue, so every mention at one depth
|
|
97
|
+
* is planned before any deeper one; `resolved` plans a dequeued schema's
|
|
98
|
+
* own body instead.
|
|
99
|
+
*/
|
|
100
|
+
const table = (
|
|
101
|
+
schema: SchemaLike,
|
|
102
|
+
ancestors: string[],
|
|
103
|
+
resolved = false
|
|
104
|
+
): SchemaSlot => {
|
|
105
|
+
if (!resolved && isString(schema.$ref)) {
|
|
106
|
+
const name = refName(schema.$ref);
|
|
107
|
+
if (ancestors.includes(name)) {
|
|
108
|
+
return { node: { kind: "circular", name } };
|
|
109
|
+
}
|
|
110
|
+
const slot: SchemaSlot = { node: { kind: "named", name } };
|
|
111
|
+
queue.push({ ancestors, name, schema, slot });
|
|
112
|
+
return slot;
|
|
113
|
+
}
|
|
114
|
+
if (typesOf(schema).includes("array")) {
|
|
115
|
+
// Items stay unresolved, so a self-referential item `$ref` is still
|
|
116
|
+
// recognized as the circle it is.
|
|
117
|
+
const { items } = schema;
|
|
118
|
+
return {
|
|
119
|
+
node: items
|
|
120
|
+
? {
|
|
121
|
+
items: table(items, ancestors),
|
|
122
|
+
itemsLabel: typeLabel(items),
|
|
123
|
+
kind: "array",
|
|
124
|
+
}
|
|
125
|
+
: { itemsLabel: typeLabel({}), kind: "array" },
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const branches = schema.oneOf ?? schema.anyOf;
|
|
129
|
+
if (branches) {
|
|
130
|
+
return {
|
|
131
|
+
node: {
|
|
132
|
+
branches: branches.map((branch, index) => ({
|
|
133
|
+
label: typeLabel(branch) || `Option ${index + 1}`,
|
|
134
|
+
slot: table(branch, ancestors),
|
|
135
|
+
})),
|
|
136
|
+
kind: "branches",
|
|
137
|
+
label: schema.oneOf ? "One of" : "Any of",
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// A row discloses nested structure — never a model inside itself.
|
|
142
|
+
const rowChildren = (property: SchemaLike): SchemaSlot | undefined => {
|
|
143
|
+
if (
|
|
144
|
+
isString(property.$ref) &&
|
|
145
|
+
ancestors.includes(refName(property.$ref))
|
|
146
|
+
) {
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
const target = resolveSchema(schemas, property);
|
|
150
|
+
const items = typesOf(target).includes("array")
|
|
151
|
+
? resolveSchema(schemas, target.items)
|
|
152
|
+
: null;
|
|
153
|
+
return hasNestedFields(target) || (items && hasNestedFields(items))
|
|
154
|
+
? table(property, ancestors)
|
|
155
|
+
: undefined;
|
|
156
|
+
};
|
|
157
|
+
const { properties, required } = objectProperties(schema, schemas);
|
|
158
|
+
if (properties.length > 0) {
|
|
159
|
+
return {
|
|
160
|
+
node: {
|
|
161
|
+
kind: "properties",
|
|
162
|
+
rows: properties.map(([name, property]) => ({
|
|
163
|
+
children: rowChildren(property),
|
|
164
|
+
name,
|
|
165
|
+
required: required.has(name),
|
|
166
|
+
schema: property,
|
|
167
|
+
})),
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return { node: { kind: "type", label: typeLabel(schema) } };
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const tree = table(root, []);
|
|
175
|
+
// The queue grows while it drains, in depth order: every mention at one
|
|
176
|
+
// named depth is queued before the first one at the next.
|
|
177
|
+
for (const pending of queue) {
|
|
178
|
+
const depth = pending.ancestors.length;
|
|
179
|
+
if (depth > REPEAT_DEPTH && expanded.has(pending.name)) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
expanded.add(pending.name);
|
|
183
|
+
pending.slot.node = table(
|
|
184
|
+
resolveSchema(schemas, pending.schema),
|
|
185
|
+
[...pending.ancestors, pending.name],
|
|
186
|
+
true
|
|
187
|
+
).node;
|
|
188
|
+
}
|
|
189
|
+
return tree.node;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Whether a row gets a disclosure: it has nested structure, and that structure
|
|
194
|
+
* isn't just the name of a schema expanded elsewhere (directly, or as the
|
|
195
|
+
* items of an array).
|
|
196
|
+
*/
|
|
197
|
+
export const rowExpands = (row: SchemaRow): boolean => {
|
|
198
|
+
const node = row.children?.node;
|
|
199
|
+
if (!node || node.kind === "named") {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
return !(node.kind === "array" && node.items?.node.kind === "named");
|
|
203
|
+
};
|
|
@@ -22,26 +22,42 @@ const headerLines = (
|
|
|
22
22
|
): string[] =>
|
|
23
23
|
Object.entries(headers).map(([key, value]) => format(key, value));
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* A single-quoted POSIX shell word. Nothing expands inside single quotes — no
|
|
27
|
+
* `$`, backtick, `!`, or `\` — so a value reaches curl byte for byte; a
|
|
28
|
+
* literal `'` closes the quote, adds an escaped one, and reopens it.
|
|
29
|
+
*/
|
|
30
|
+
const shellQuote = (value: string): string =>
|
|
31
|
+
`'${value.replaceAll("'", String.raw`'\''`)}'`;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A double-quoted string literal for the JavaScript and Python samples. JSON's
|
|
35
|
+
* string escapes are a subset of both languages' — a quote in a header value
|
|
36
|
+
* (`If-Match: "33a64df5"`) or a backslash becomes an escape rather than
|
|
37
|
+
* ending the literal early.
|
|
38
|
+
*/
|
|
39
|
+
const stringLiteral = (value: string): string => JSON.stringify(value);
|
|
40
|
+
|
|
25
41
|
const curlSnippet = (sample: RequestSample): string => {
|
|
26
42
|
const lines = [
|
|
27
|
-
`curl -X ${sample.method}
|
|
28
|
-
...headerLines(
|
|
43
|
+
`curl -X ${sample.method} ${shellQuote(sample.url)}`,
|
|
44
|
+
...headerLines(
|
|
45
|
+
sample.headers,
|
|
46
|
+
(key, value) => ` -H ${shellQuote(`${key}: ${value}`)}`
|
|
47
|
+
),
|
|
29
48
|
];
|
|
30
49
|
if (sample.body) {
|
|
31
|
-
|
|
32
|
-
// single-quoted string, so an example like "it's" doesn't break the shell.
|
|
33
|
-
const escapedBody = sample.body.replaceAll("'", String.raw`'\''`);
|
|
34
|
-
lines.push(` -d '${escapedBody}'`);
|
|
50
|
+
lines.push(` -d ${shellQuote(sample.body)}`);
|
|
35
51
|
}
|
|
36
52
|
return lines.join(" \\\n");
|
|
37
53
|
};
|
|
38
54
|
|
|
39
55
|
const fetchSnippet = (sample: RequestSample): string => {
|
|
40
|
-
const options = [` method:
|
|
56
|
+
const options = [` method: ${stringLiteral(sample.method)}`];
|
|
41
57
|
if (Object.keys(sample.headers).length > 0) {
|
|
42
58
|
const headers = headerLines(
|
|
43
59
|
sample.headers,
|
|
44
|
-
(key, value) => `
|
|
60
|
+
(key, value) => ` ${stringLiteral(key)}: ${stringLiteral(value)}`
|
|
45
61
|
).join(",\n");
|
|
46
62
|
options.push(` headers: {\n${headers}\n }`);
|
|
47
63
|
}
|
|
@@ -53,28 +69,27 @@ const fetchSnippet = (sample: RequestSample): string => {
|
|
|
53
69
|
// and an id past 2^53 loses digits through a JS number. The string
|
|
54
70
|
// literal also stays syntactically valid while the editor holds mid-edit
|
|
55
71
|
// text that isn't JSON yet.
|
|
56
|
-
options.push(` body: ${
|
|
72
|
+
options.push(` body: ${stringLiteral(sample.body)}`);
|
|
57
73
|
}
|
|
58
|
-
return `const response = await fetch(
|
|
74
|
+
return `const response = await fetch(${stringLiteral(sample.url)}, {\n${options.join(
|
|
59
75
|
",\n"
|
|
60
76
|
)}\n});`;
|
|
61
77
|
};
|
|
62
78
|
|
|
63
79
|
const pythonSnippet = (sample: RequestSample): string => {
|
|
64
|
-
const args = [`
|
|
80
|
+
const args = [` ${stringLiteral(sample.url)}`];
|
|
65
81
|
if (Object.keys(sample.headers).length > 0) {
|
|
66
82
|
const headers = headerLines(
|
|
67
83
|
sample.headers,
|
|
68
|
-
(key, value) => `
|
|
84
|
+
(key, value) => ` ${stringLiteral(key)}: ${stringLiteral(value)}`
|
|
69
85
|
).join(",\n");
|
|
70
86
|
args.push(` headers={\n${headers}\n }`);
|
|
71
87
|
}
|
|
72
88
|
if (sample.body) {
|
|
73
89
|
// Same rule as the fetch snippet: the raw text travels as a string via
|
|
74
|
-
// `data=`
|
|
75
|
-
// valid) rather than a `json=` dict — a Python literal re-serializes
|
|
90
|
+
// `data=` rather than a `json=` dict — a Python literal re-serializes
|
|
76
91
|
// `1e400` as `Infinity` and would otherwise diverge from the live send.
|
|
77
|
-
args.push(` data=${
|
|
92
|
+
args.push(` data=${stringLiteral(sample.body)}`);
|
|
78
93
|
}
|
|
79
94
|
return `import requests\n\nresponse = requests.${sample.method.toLowerCase()}(\n${args.join(
|
|
80
95
|
",\n"
|
package/src/core/base-path.ts
CHANGED
|
@@ -88,6 +88,21 @@ export const withBasePath = (basePath: string, route: string): string => {
|
|
|
88
88
|
return route === "/" ? basePath : `${basePath}${route}`;
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Mount a route Blume generates from content under `basePath`,
|
|
93
|
+
* unconditionally. {@link withBasePath} leaves a route that already starts
|
|
94
|
+
* with the base alone, which is right for a link an author based by hand but
|
|
95
|
+
* wrong for a content route: with `basePath: "/docs"`, `docs/guide.md` routes
|
|
96
|
+
* to `/docs/guide` before the base and publishes at `/docs/docs/guide`, not on
|
|
97
|
+
* top of the root `guide.md`.
|
|
98
|
+
*/
|
|
99
|
+
export const mountBasePath = (basePath: string, route: string): string => {
|
|
100
|
+
if (!basePath) {
|
|
101
|
+
return route;
|
|
102
|
+
}
|
|
103
|
+
return route === "/" ? basePath : `${basePath}${route}`;
|
|
104
|
+
};
|
|
105
|
+
|
|
91
106
|
/**
|
|
92
107
|
* {@link withBasePath} for the composed `deployment.base` + `basePath` stack
|
|
93
108
|
* (`/base` + `/docs` serves pages at `/base/docs/x`). The hand-written-base
|
package/src/core/code-fences.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Fenced-code state for line scanners. Kept free of imports so request-time
|
|
3
|
-
* code (the
|
|
3
|
+
* code (the assistant's grounding excerpts) can share it with the build-time source
|
|
4
4
|
* scanners without pulling the filesystem and schema modules along.
|
|
5
5
|
*
|
|
6
6
|
* CommonMark allows backtick *and* tilde fences, three or more characters
|
package/src/core/config-input.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { AstroIntegration } from "astro";
|
|
|
2
2
|
import type { z } from "zod";
|
|
3
3
|
|
|
4
4
|
import type { AskRetrievalOptions } from "../ai/ask-context.ts";
|
|
5
|
-
import type {
|
|
5
|
+
import type { AssistantAdapter } from "../ai/ask.ts";
|
|
6
6
|
import type { ComponentMarkdown } from "../ai/component-markdown.ts";
|
|
7
7
|
import type { AnalyticsAdapter } from "../analytics/schema.ts";
|
|
8
8
|
import type { DeploymentInput } from "../deploy/adapters/registry.ts";
|
|
@@ -488,16 +488,16 @@ export type SearchConfig = SearchProviderConfig | SearchOptions;
|
|
|
488
488
|
// AI
|
|
489
489
|
// ---------------------------------------------------------------------------
|
|
490
490
|
|
|
491
|
-
/** An empty-state prompt shown before the first
|
|
492
|
-
export interface
|
|
491
|
+
/** An empty-state prompt shown before the first question to the assistant. */
|
|
492
|
+
export interface AssistantSuggestion {
|
|
493
493
|
/** Lucide icon name shown beside the suggestion. */
|
|
494
494
|
icon?: string;
|
|
495
495
|
/** The clickable suggestion text. */
|
|
496
496
|
label: string;
|
|
497
497
|
}
|
|
498
498
|
|
|
499
|
-
/** How much retrieved documentation each
|
|
500
|
-
export interface
|
|
499
|
+
/** How much retrieved documentation each question to the assistant carries. */
|
|
500
|
+
export interface AssistantRetrievalConfig {
|
|
501
501
|
/**
|
|
502
502
|
* Total injected documentation characters, across all excerpts. Defaults to
|
|
503
503
|
* `10000`. The single biggest lever on time-to-first-token — the model reads
|
|
@@ -518,8 +518,8 @@ export interface AskRetrievalConfig {
|
|
|
518
518
|
maxResults?: number;
|
|
519
519
|
}
|
|
520
520
|
|
|
521
|
-
/** The
|
|
522
|
-
export interface
|
|
521
|
+
/** The chat assistant. */
|
|
522
|
+
export interface AssistantConfig {
|
|
523
523
|
/**
|
|
524
524
|
* Origins allowed to call the generated endpoint from another site — a
|
|
525
525
|
* marketing page that embeds an ask box, for example — or `"*"` to allow
|
|
@@ -532,10 +532,10 @@ export interface AskConfig {
|
|
|
532
532
|
* combined with it.
|
|
533
533
|
*/
|
|
534
534
|
cors?: string[];
|
|
535
|
-
/** Turn
|
|
535
|
+
/** Turn the assistant on. Defaults to `false`. */
|
|
536
536
|
enabled?: boolean;
|
|
537
537
|
/**
|
|
538
|
-
* Existing
|
|
538
|
+
* Existing assistant endpoint to call instead of generating one. This keeps a
|
|
539
539
|
* Blume site static while an API backend owns retrieval, model access, rate
|
|
540
540
|
* limiting, and streaming. Accepts an absolute URL or root-relative path.
|
|
541
541
|
*/
|
|
@@ -555,15 +555,15 @@ export interface AskConfig {
|
|
|
555
555
|
* mapping, and `providerOptions` passthrough. Defaults to
|
|
556
556
|
* `gateway({ model: "openai/gpt-5.5" })`.
|
|
557
557
|
*/
|
|
558
|
-
provider?:
|
|
558
|
+
provider?: AssistantAdapter;
|
|
559
559
|
/**
|
|
560
560
|
* How much documentation each question carries into the model's prompt.
|
|
561
561
|
* Lower values cut time-to-first-token — which dominates on a self-hosted
|
|
562
562
|
* backend — at the cost of recall. Defaults keep the built-in behavior.
|
|
563
563
|
*/
|
|
564
|
-
retrieval?:
|
|
564
|
+
retrieval?: AssistantRetrievalConfig;
|
|
565
565
|
/** Starter prompts shown before the first question. */
|
|
566
|
-
suggestions?:
|
|
566
|
+
suggestions?: AssistantSuggestion[];
|
|
567
567
|
}
|
|
568
568
|
|
|
569
569
|
/** What the AI Catalog (ARD) manifest carries. */
|
|
@@ -596,14 +596,14 @@ export interface LlmsTxtConfig {
|
|
|
596
596
|
/**
|
|
597
597
|
* Markdown placed after the title and summary in `llms.txt`, before the
|
|
598
598
|
* page sections — the llms.txt spec's "details" block. Use it to tell
|
|
599
|
-
* agents when to reach for the product and how to call it (
|
|
600
|
-
*
|
|
601
|
-
* dropped.
|
|
599
|
+
* agents when to reach for the product and how to call it (the install
|
|
600
|
+
* command, the package name). The spec allows any Markdown there but
|
|
601
|
+
* headings. Blank values are dropped.
|
|
602
602
|
*
|
|
603
603
|
* ```ts
|
|
604
604
|
* agents: {
|
|
605
605
|
* llmsTxt: {
|
|
606
|
-
* details: "
|
|
606
|
+
* details: "Use Acme when…",
|
|
607
607
|
* },
|
|
608
608
|
* }
|
|
609
609
|
* ```
|
|
@@ -631,10 +631,10 @@ export interface McpConfig {
|
|
|
631
631
|
route?: string;
|
|
632
632
|
}
|
|
633
633
|
|
|
634
|
-
/** Model-facing features: the
|
|
634
|
+
/** Model-facing features: the assistant and the "Open in chat" action. */
|
|
635
635
|
export interface AiConfig {
|
|
636
|
-
/** The
|
|
637
|
-
|
|
636
|
+
/** The chat assistant. */
|
|
637
|
+
assistant?: AssistantConfig;
|
|
638
638
|
/**
|
|
639
639
|
* The "Open in chat" page action, which opens the current page in an AI
|
|
640
640
|
* assistant pre-filled with a prompt pointing at its raw Markdown.
|
|
@@ -833,7 +833,7 @@ export type ContentSignalsConfig =
|
|
|
833
833
|
/**
|
|
834
834
|
* The machine-readable surface agents consume: the JSON API, `llms.txt`, the
|
|
835
835
|
* MCP server, published skills, discovery manifests, and the robots.txt usage
|
|
836
|
-
* policy. The reader-facing model features (
|
|
836
|
+
* policy. The reader-facing model features (the assistant, Open in chat) live under
|
|
837
837
|
* `ai`.
|
|
838
838
|
*/
|
|
839
839
|
export interface AgentsConfig {
|
|
@@ -1331,7 +1331,7 @@ export type TocConfig =
|
|
|
1331
1331
|
export interface BlumeConfig {
|
|
1332
1332
|
/** The machine-readable surface for agents: JSON API, `llms.txt`, MCP, skills, discovery. */
|
|
1333
1333
|
agents?: AgentsConfig;
|
|
1334
|
-
/** Model-facing features: the
|
|
1334
|
+
/** Model-facing features: the assistant and the "Open in chat" action. */
|
|
1335
1335
|
ai?: AiConfig;
|
|
1336
1336
|
/**
|
|
1337
1337
|
* Analytics adapters from `blume/analytics`, emitted into `<head>` of every
|
|
@@ -1452,10 +1452,10 @@ type _NoExtraOrMissingKeys = AssertExtends<
|
|
|
1452
1452
|
// endpoint and silently ignored at request time). `Required` makes a rename in
|
|
1453
1453
|
// either copy a missing property, which stops compiling.
|
|
1454
1454
|
type _AskRetrievalMatchesRuntime = AssertExtends<
|
|
1455
|
-
Required<
|
|
1455
|
+
Required<AssistantRetrievalConfig>,
|
|
1456
1456
|
Required<AskRetrievalOptions>
|
|
1457
1457
|
>;
|
|
1458
1458
|
type _AskRuntimeMatchesRetrieval = AssertExtends<
|
|
1459
1459
|
Required<AskRetrievalOptions>,
|
|
1460
|
-
Required<
|
|
1460
|
+
Required<AssistantRetrievalConfig>
|
|
1461
1461
|
>;
|
package/src/core/config.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
|
|
3
|
+
import { basename } from "pathe";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
|
|
5
6
|
import type { BlumeConfig } from "./config-input.ts";
|
|
@@ -9,7 +10,7 @@ import {
|
|
|
9
10
|
diagnosticsFromIssues,
|
|
10
11
|
diagnosticsFromZod,
|
|
11
12
|
} from "./diagnostics.ts";
|
|
12
|
-
import {
|
|
13
|
+
import { createDefaultExportLoader } from "./load-module.ts";
|
|
13
14
|
import { findConfigFile } from "./project.ts";
|
|
14
15
|
import { blumeConfigSchema } from "./schema.ts";
|
|
15
16
|
import type { ResolvedConfig } from "./schema.ts";
|
|
@@ -68,8 +69,8 @@ import type { Diagnostic } from "./types.ts";
|
|
|
68
69
|
* - `theme` — `accent` color, `fonts` (curated slugs, any provider family, or
|
|
69
70
|
* local font files), `radius`,
|
|
70
71
|
* `mode` (`system`/`light`/`dark`), and `background`.
|
|
71
|
-
* - `markdown` — `code` (language icons,
|
|
72
|
-
* `
|
|
72
|
+
* - `markdown` — `code` (language icons, light/dark Shiki `theme`, line
|
|
73
|
+
* `wrap`), `externalLinks`, `headingAnchors`, and `imageZoom`.
|
|
73
74
|
* - `toc` — on-page table of contents; `true`/`false` or a heading-level range.
|
|
74
75
|
* - `lastModified` — "Last updated" stamps from `git` history or frontmatter.
|
|
75
76
|
* - `feedback` — the per-page "Was this helpful?" widget (on by default).
|
|
@@ -87,7 +88,7 @@ import type { Diagnostic } from "./types.ts";
|
|
|
87
88
|
* `flexsearch()`, `pagefind()`, `algolia({…})`, `oramaCloud({…})`,
|
|
88
89
|
* `typesense({…})`, `mixedbread({…})`, or `false`), or `{ provider,
|
|
89
90
|
* popular, indexing }` to add curated links and indexing settings.
|
|
90
|
-
* - `ai` — what faces a model at read time: `
|
|
91
|
+
* - `ai` — what faces a model at read time: `assistant` (the chat assistant, with
|
|
91
92
|
* a provider adapter from `blume/ai` such as `gateway()` or `openrouter()`)
|
|
92
93
|
* and `openInChat` (the "Open in chat" page action).
|
|
93
94
|
* - `agents` — the machine-readable surface: `llmsTxt`, the JSON `api`, the
|
|
@@ -146,7 +147,7 @@ import type { Diagnostic } from "./types.ts";
|
|
|
146
147
|
* });
|
|
147
148
|
* ```
|
|
148
149
|
*
|
|
149
|
-
* @example An OpenAPI reference with the
|
|
150
|
+
* @example An OpenAPI reference with the assistant enabled.
|
|
150
151
|
* ```ts
|
|
151
152
|
* import { openapi } from "blume/reference";
|
|
152
153
|
*
|
|
@@ -159,7 +160,7 @@ import type { Diagnostic } from "./types.ts";
|
|
|
159
160
|
* }),
|
|
160
161
|
* ],
|
|
161
162
|
* agents: { llmsTxt: true },
|
|
162
|
-
* ai: {
|
|
163
|
+
* ai: { assistant: { enabled: true } },
|
|
163
164
|
* });
|
|
164
165
|
* ```
|
|
165
166
|
*
|
|
@@ -199,7 +200,7 @@ export interface ConfigLoadResult {
|
|
|
199
200
|
themeFontsConfigured: boolean;
|
|
200
201
|
}
|
|
201
202
|
|
|
202
|
-
const importConfigModule =
|
|
203
|
+
const importConfigModule = createDefaultExportLoader();
|
|
203
204
|
|
|
204
205
|
/**
|
|
205
206
|
* The slice of a user config module probed before schema defaults apply:
|
|
@@ -290,6 +291,19 @@ export const loadConfig = async (
|
|
|
290
291
|
severity: "error",
|
|
291
292
|
});
|
|
292
293
|
}
|
|
294
|
+
// Validating whatever else the module holds would build a silent default
|
|
295
|
+
// site (a bare `defineConfig({…})` call) or reject a named `config` export
|
|
296
|
+
// as an unknown key, neither of which names the actual mistake.
|
|
297
|
+
if (raw === undefined) {
|
|
298
|
+
throw new BlumeError({
|
|
299
|
+
code: "BLUME_CONFIG_INVALID",
|
|
300
|
+
file: configFile,
|
|
301
|
+
message: `${basename(configFile)} has no default export, so Blume can't read its config.`,
|
|
302
|
+
severity: "error",
|
|
303
|
+
suggestion:
|
|
304
|
+
"Export the config as the file's default: `export default defineConfig({ … })`.",
|
|
305
|
+
});
|
|
306
|
+
}
|
|
293
307
|
}
|
|
294
308
|
|
|
295
309
|
// Read before parsing: schema defaults erase the set-vs-defaulted distinction.
|
package/src/core/data.ts
CHANGED
|
@@ -122,10 +122,10 @@ export interface BlumeDataConfig {
|
|
|
122
122
|
analytics: ResolvedConfig["analytics"];
|
|
123
123
|
/** Apple touch icon, or `null` when none is configured/detected. */
|
|
124
124
|
appleIcon: BlumeFavicon | null;
|
|
125
|
-
/**
|
|
126
|
-
|
|
125
|
+
/** The assistant's empty-state suggestions, or `null` when the assistant is off. */
|
|
126
|
+
assistant: {
|
|
127
127
|
endpoint: string | null;
|
|
128
|
-
suggestions: NonNullable<ResolvedConfig["ai"]["
|
|
128
|
+
suggestions: NonNullable<ResolvedConfig["ai"]["assistant"]>["suggestions"];
|
|
129
129
|
} | null;
|
|
130
130
|
banner: BlumeBanner | null;
|
|
131
131
|
/** Site-wide route mount point, normalized to `""` or `/seg` (see config). */
|