blume 2.1.0 → 2.1.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/CHANGELOG.md +110 -0
- package/dist/cli/{chunk-ga0pf4aj.js → chunk-0n9xkp3d.js} +12 -3
- package/dist/cli/{chunk-ga0pf4aj.js.map → chunk-0n9xkp3d.js.map} +3 -3
- package/dist/cli/{chunk-43zcf4gz.js → chunk-0pmb4tr4.js} +541 -368
- package/dist/cli/chunk-0pmb4tr4.js.map +35 -0
- package/dist/cli/{chunk-9geymqns.js → chunk-0w6hs479.js} +15 -15
- package/dist/cli/{chunk-xkz5xbtv.js → chunk-124fvmzq.js} +2802 -1422
- package/dist/cli/chunk-124fvmzq.js.map +220 -0
- package/dist/cli/chunk-150jk7km.js +52 -0
- package/dist/cli/chunk-150jk7km.js.map +10 -0
- package/dist/cli/{chunk-y4ykbark.js → chunk-1f882900.js} +2 -2
- package/dist/cli/{chunk-5ffywsmb.js → chunk-297ajdcv.js} +8 -6
- package/dist/cli/{chunk-5ffywsmb.js.map → chunk-297ajdcv.js.map} +3 -3
- package/dist/cli/{chunk-h2a48yhd.js → chunk-32khwcb6.js} +120 -16
- package/dist/cli/{chunk-h2a48yhd.js.map → chunk-32khwcb6.js.map} +10 -10
- package/dist/cli/{chunk-5cg2rzgf.js → chunk-36bxs9c7.js} +20 -49
- package/dist/cli/{chunk-5cg2rzgf.js.map → chunk-36bxs9c7.js.map} +4 -5
- package/dist/cli/{chunk-py62fewh.js → chunk-53jqw8z0.js} +3 -3
- package/dist/cli/{chunk-5wj2qwn2.js → chunk-58bt3hag.js} +4 -4
- package/dist/cli/{chunk-e7vvk5ya.js → chunk-5cmts6dv.js} +3 -3
- package/dist/cli/{chunk-y5h4r2y0.js → chunk-60hz265r.js} +15 -5
- package/dist/cli/chunk-60hz265r.js.map +10 -0
- package/dist/cli/chunk-74wfhv79.js +65 -0
- package/dist/cli/chunk-74wfhv79.js.map +10 -0
- package/dist/cli/{chunk-g2z9x01v.js → chunk-9qzgg6mj.js} +3 -3
- package/dist/cli/{chunk-q3wxxq39.js → chunk-a57yh0h9.js} +5 -5
- package/dist/cli/{chunk-713mngdq.js → chunk-ave1wcbr.js} +76 -10
- package/dist/cli/chunk-ave1wcbr.js.map +14 -0
- package/dist/cli/{chunk-2n4ps1b3.js → chunk-bqxaqn5p.js} +40 -22
- package/dist/cli/chunk-bqxaqn5p.js.map +15 -0
- package/dist/cli/{chunk-jnwj5kjj.js → chunk-bxwhtvw8.js} +20 -7
- package/dist/cli/{chunk-jnwj5kjj.js.map → chunk-bxwhtvw8.js.map} +3 -3
- package/dist/cli/chunk-ckrcm08h.js +324 -0
- package/dist/cli/chunk-ckrcm08h.js.map +14 -0
- package/dist/cli/{chunk-2f3ndkpw.js → chunk-desvm72z.js} +3 -3
- package/dist/cli/{chunk-gp84za0h.js → chunk-dhwtqnnd.js} +2 -2
- package/dist/cli/{chunk-4h8z9vv5.js → chunk-dpy8qdjf.js} +93 -47
- package/dist/cli/chunk-dpy8qdjf.js.map +17 -0
- package/dist/cli/{chunk-2f7n4qzt.js → chunk-dqhg54mr.js} +1 -1
- package/dist/cli/{chunk-0gz36akr.js → chunk-dv2z0rzf.js} +21 -5
- package/dist/cli/chunk-dv2z0rzf.js.map +12 -0
- package/dist/cli/{chunk-cm89scdv.js → chunk-es8h0v3j.js} +9 -11
- package/dist/cli/{chunk-cm89scdv.js.map → chunk-es8h0v3j.js.map} +3 -3
- package/dist/cli/{chunk-zhvd6adm.js → chunk-gfc5fqvf.js} +14 -14
- package/dist/cli/{chunk-nd1821sk.js → chunk-gxtg6ed2.js} +33 -19
- package/dist/cli/chunk-gxtg6ed2.js.map +10 -0
- package/dist/cli/{chunk-p804f3pe.js → chunk-hvcxng5f.js} +6 -6
- package/dist/cli/{chunk-ta27feev.js → chunk-j1x92mx9.js} +21 -2
- package/dist/cli/chunk-j1x92mx9.js.map +10 -0
- package/dist/cli/{chunk-rekqz4qg.js → chunk-k3gr1nm9.js} +19 -16
- package/dist/cli/chunk-k3gr1nm9.js.map +10 -0
- package/dist/cli/{chunk-1n228xqb.js → chunk-kdpzw38a.js} +2 -2
- package/dist/cli/{chunk-cy5bm0j0.js → chunk-ms9z66nz.js} +2 -2
- package/dist/cli/{chunk-cy5bm0j0.js.map → chunk-ms9z66nz.js.map} +2 -2
- package/dist/cli/{chunk-zf748avv.js → chunk-nbyvgnnm.js} +193 -286
- package/dist/cli/chunk-nbyvgnnm.js.map +36 -0
- package/dist/cli/{chunk-6bm0xpgd.js → chunk-s0bdnc7v.js} +2 -2
- package/dist/cli/{chunk-yxmk4pec.js → chunk-sc93apfs.js} +17 -16
- package/dist/cli/{chunk-yxmk4pec.js.map → chunk-sc93apfs.js.map} +3 -3
- package/dist/cli/{chunk-cmtcnh9f.js → chunk-tfycddbt.js} +2 -2
- package/dist/cli/{chunk-9xr4dgee.js → chunk-twy7psdz.js} +29 -16
- package/dist/cli/chunk-twy7psdz.js.map +10 -0
- package/dist/cli/{chunk-ntv4qrt7.js → chunk-y4msrwm9.js} +15 -15
- package/dist/cli/{chunk-yj17vs39.js → chunk-ydp3065p.js} +5 -5
- package/dist/cli/index.js +24 -19
- package/dist/cli/index.js.map +3 -3
- package/dist/types/ai/ask-context.d.ts +6 -2
- package/dist/types/ai/ask.d.ts +24 -5
- package/dist/types/ai/component-markdown.d.ts +2 -0
- package/dist/types/ai/openapi-components.d.ts +4 -1
- package/dist/types/analytics/clics.d.ts +37 -0
- package/dist/types/analytics/index.d.ts +2 -0
- package/dist/types/analytics/schema.d.ts +18 -0
- package/dist/types/astro/integration.d.ts +11 -4
- package/dist/types/astro/markdown-negotiation.d.ts +3 -0
- package/dist/types/astro/pages.d.ts +10 -0
- package/dist/types/cli/init/scaffold.d.ts +1 -1
- package/dist/types/components/content/api-field.d.ts +4 -1
- package/dist/types/components/content/api-page.d.ts +6 -1
- package/dist/types/components/openapi/code-samples.d.ts +29 -0
- package/dist/types/components/openapi/helpers.d.ts +22 -1
- package/dist/types/components/openapi/security.d.ts +10 -0
- package/dist/types/components/openapi/snippets.d.ts +60 -0
- package/dist/types/core/changelog-index.d.ts +8 -0
- package/dist/types/core/config-input.d.ts +37 -6
- package/dist/types/core/data.d.ts +4 -0
- package/dist/types/core/i18n-ui.d.ts +2 -0
- package/dist/types/core/links.d.ts +8 -0
- package/dist/types/core/powered-by.d.ts +12 -0
- package/dist/types/core/probe.d.ts +2 -0
- package/dist/types/core/project-graph.d.ts +6 -0
- package/dist/types/core/redirect-patterns.d.ts +11 -3
- package/dist/types/core/schema.d.ts +228 -3
- package/dist/types/core/sources/cache.d.ts +3 -0
- package/dist/types/core/sources/contentful-rich-text.d.ts +11 -2
- package/dist/types/core/sources/contentful.d.ts +17 -1
- package/dist/types/core/sources/lexical.d.ts +5 -0
- package/dist/types/core/sources/lower.d.ts +10 -2
- package/dist/types/core/sources/normalize.d.ts +20 -1
- package/dist/types/core/sources/notion.d.ts +8 -0
- package/dist/types/core/sources/remote.d.ts +37 -10
- package/dist/types/core/sources/sanity.d.ts +1 -1
- package/dist/types/core/types.d.ts +17 -0
- package/dist/types/deploy/adapter-output.d.ts +2 -1
- package/dist/types/deploy/adapters/cloudflare.d.ts +7 -5
- package/dist/types/deploy/adapters/node.d.ts +58 -23
- package/dist/types/deploy/adapters/registry.d.ts +10 -0
- package/dist/types/deploy/adapters/types.d.ts +3 -2
- package/dist/types/deploy/cloudflare-negotiation.d.ts +5 -2
- package/dist/types/deploy/node-headers.d.ts +12 -4
- package/dist/types/deploy/platforms/cloudflare.d.ts +10 -7
- package/dist/types/deploy/platforms/node.d.ts +3 -1
- package/dist/types/deploy/platforms/types.d.ts +18 -7
- package/dist/types/deploy/platforms/vercel.d.ts +21 -2
- package/dist/types/deploy/redirects.d.ts +17 -1
- package/dist/types/deploy/sitemap.d.ts +2 -1
- package/dist/types/deploy/vercel-negotiation.d.ts +44 -21
- package/dist/types/narration/build.d.ts +34 -12
- package/dist/types/narration/provider.d.ts +96 -8
- package/dist/types/openapi/checks.d.ts +27 -0
- package/dist/types/openapi/graphql.d.ts +6 -0
- package/dist/types/openapi/model.d.ts +15 -4
- package/dist/types/openapi/parse.d.ts +3 -0
- package/dist/types/openapi/references.d.ts +16 -0
- package/dist/types/openapi/sentence.d.ts +11 -1
- package/dist/types/ratelimit/index.d.ts +1 -1
- package/dist/types/ratelimit/schema.d.ts +8 -0
- package/dist/types/ratelimit/upstash.d.ts +39 -14
- package/dist/types/reference/graphql.d.ts +76 -1
- package/dist/types/reference/index.d.ts +1 -1
- package/dist/types/reference/openapi.d.ts +2 -2
- package/dist/types/reference/options.d.ts +37 -1
- package/dist/types/reference/schema.d.ts +84 -0
- package/dist/types/search/adapters/registry.d.ts +3 -0
- package/dist/types/search/adapters/typesense.d.ts +14 -4
- package/dist/types/search/build.d.ts +3 -1
- package/dist/types/search/orama-index.d.ts +9 -9
- package/dist/types/search/sync/algolia.d.ts +5 -2
- package/dist/types/search/sync/index.d.ts +3 -1
- package/dist/types/search/sync/typesense.d.ts +11 -7
- package/dist/types/seo/jsonld.d.ts +11 -6
- package/dist/types/sources/contentful.d.ts +16 -0
- package/dist/types/sources/github-releases.d.ts +8 -1
- package/dist/types/sources/notion.d.ts +8 -0
- package/dist/types/sources/payload.d.ts +2 -0
- package/dist/types/sources/registry.d.ts +63 -0
- package/dist/types/sources/shared.d.ts +3 -0
- package/dist/types/sources/strapi.d.ts +2 -0
- package/docs/01-quickstart.mdx +4 -2
- package/docs/02-deployment.mdx +59 -13
- package/docs/03-upgrading.mdx +2 -1
- package/docs/04-migrating.mdx +9 -9
- package/docs/08-faq.mdx +12 -12
- package/docs/advanced/changelog.mdx +30 -2
- package/docs/advanced/custom-pages.mdx +1 -1
- package/docs/advanced/skills.mdx +1 -1
- package/docs/cli/audit.mdx +30 -7
- package/docs/cli/doctor.mdx +6 -2
- package/docs/cli/evals.mdx +4 -4
- package/docs/cli/translate.mdx +1 -0
- package/docs/cli/validate.mdx +4 -3
- package/docs/configuration/analytics.mdx +19 -1
- package/docs/configuration/assistant.mdx +6 -2
- package/docs/configuration/customization.mdx +4 -2
- package/docs/configuration/export.mdx +5 -3
- package/docs/configuration/index.mdx +4 -2
- package/docs/configuration/narration.mdx +43 -6
- package/docs/configuration/rate-limiting.mdx +23 -2
- package/docs/configuration/search.mdx +37 -14
- package/docs/content/components.mdx +2 -2
- package/docs/content/frontmatter.mdx +5 -3
- package/docs/content/i18n.mdx +2 -2
- package/docs/content/includes.mdx +1 -1
- package/docs/content/navigation.mdx +8 -6
- package/docs/content/sources/contentful.mdx +9 -4
- package/docs/content/sources/custom.mdx +7 -3
- package/docs/content/sources/github-releases.mdx +12 -2
- package/docs/content/sources/index.mdx +3 -3
- package/docs/content/sources/notion.mdx +17 -2
- package/docs/content/sources/obsidian.mdx +3 -1
- package/docs/content/sources/payload.mdx +5 -2
- package/docs/content/sources/remote-mdx.mdx +6 -0
- package/docs/content/sources/sanity.mdx +4 -2
- package/docs/content/sources/strapi.mdx +5 -2
- package/docs/content/syntax.mdx +2 -2
- package/docs/discoverability/agent-discovery.mdx +1 -1
- package/docs/discoverability/index.mdx +1 -1
- package/docs/discoverability/json-api.mdx +2 -0
- package/docs/discoverability/llms-txt.mdx +1 -1
- package/docs/discoverability/markdown.mdx +3 -1
- package/docs/discoverability/mcp.mdx +6 -0
- package/docs/discoverability/sitemap-and-robots.mdx +1 -1
- package/docs/discoverability/structured-data.mdx +8 -6
- package/docs/references/api-pages.mdx +1 -1
- package/docs/references/asyncapi.mdx +5 -1
- package/docs/references/graphql.mdx +15 -1
- package/docs/references/openapi.mdx +64 -8
- package/package.json +9 -9
- package/skills/blume/SKILL.md +1 -1
- package/skills/blume-migrate/SKILL.md +2 -2
- package/skills/blume-migrate/assets/{oxfmt@0.67.0.patch → oxfmt@0.71.0.patch} +7 -7
- package/skills/blume-migrate/references/docusaurus.md +4 -4
- package/skills/blume-migrate/references/fumadocs.md +17 -13
- package/skills/blume-migrate/references/monorepo.md +5 -5
- package/skills/blume-migrate/references/nextra.md +8 -5
- package/skills/blume-migrate/references/starlight.md +9 -7
- package/src/ai/ask-context.ts +33 -3
- package/src/ai/ask-limits.ts +13 -0
- package/src/ai/ask.ts +24 -6
- package/src/ai/changelog-markdown.ts +11 -6
- package/src/ai/component-markdown.ts +1 -1
- package/src/ai/cors.ts +12 -3
- package/src/ai/mcp/query.ts +14 -6
- package/src/ai/openapi-components.ts +28 -4
- package/src/ai/relative-links.ts +4 -38
- package/src/analytics/clics.ts +58 -0
- package/src/analytics/head.ts +5 -0
- package/src/analytics/index.ts +2 -0
- package/src/analytics/schema.ts +2 -0
- package/src/astro/generate.ts +91 -56
- package/src/astro/integration.ts +72 -22
- package/src/astro/markdown-negotiation.ts +3 -0
- package/src/astro/module-types.ts +3 -1
- package/src/astro/pages.ts +23 -0
- package/src/astro/render-deps.ts +10 -5
- package/src/astro/runtime-deps.ts +23 -2
- package/src/astro/templates.ts +129 -81
- package/src/audit/catalog.ts +19 -3
- package/src/audit/checks/links.ts +14 -1
- package/src/audit/checks/network.ts +110 -6
- package/src/audit/checks/redirects.ts +6 -4
- package/src/audit/checks/robots.ts +58 -2
- package/src/audit/run.ts +3 -0
- package/src/audit/types.ts +2 -0
- package/src/audit/url.ts +14 -5
- package/src/blume-modules.d.ts +5 -1
- package/src/cli/args.ts +51 -0
- package/src/cli/build-failure.ts +23 -0
- package/src/cli/commands/audit.ts +10 -1
- package/src/cli/commands/dev.ts +18 -2
- package/src/cli/commands/doctor.ts +45 -12
- package/src/cli/commands/eval.ts +36 -4
- package/src/cli/commands/init.ts +6 -4
- package/src/cli/commands/validate.ts +10 -1
- package/src/cli/init/scaffold.ts +9 -6
- package/src/cli/prepare.ts +6 -3
- package/src/cli/required-secrets.ts +3 -2
- package/src/components/content/ApiPlayground.astro +6 -2
- package/src/components/content/api-field.ts +4 -1
- package/src/components/content/api-page.ts +31 -7
- package/src/components/content/mermaid-element.ts +15 -1
- package/src/components/content/view-switcher.ts +7 -4
- package/src/components/islands/hooks.ts +27 -1
- package/src/components/layout/NavTree.astro +49 -5
- package/src/components/layout/NavTreeScript.astro +18 -0
- package/src/components/layout/PageActions.astro +139 -24
- package/src/components/layout/PageLayout.astro +13 -3
- package/src/components/layout/RootLayout.astro +27 -14
- package/src/components/layout/Search.astro +17 -3
- package/src/components/layout/TableOfContents.astro +24 -17
- package/src/components/layout/analytics-client.ts +8 -8
- package/src/components/layout/head-scripts.ts +6 -1
- package/src/components/layout/search/algolia.ts +10 -1
- package/src/components/layout/search/analytics.ts +42 -14
- package/src/components/layout/search/endpoint.ts +48 -5
- package/src/components/layout/search/pagefind.ts +114 -5
- package/src/components/layout/search/types.ts +12 -0
- package/src/components/layout/search/typesense.ts +18 -6
- package/src/components/openapi/AsyncApiOperation.astro +14 -7
- package/src/components/openapi/Authorization.astro +10 -0
- package/src/components/openapi/GraphqlOperation.astro +5 -0
- package/src/components/openapi/Operation.astro +24 -1
- package/src/components/openapi/ParametersTable.astro +8 -4
- package/src/components/openapi/Playground.astro +7 -1
- package/src/components/openapi/RequestBody.astro +19 -2
- package/src/components/openapi/Responses.astro +1 -0
- package/src/components/openapi/SchemaTable.astro +15 -3
- package/src/components/openapi/async-snippets.ts +61 -5
- package/src/components/openapi/async.ts +123 -29
- package/src/components/openapi/graphql-helpers.ts +35 -12
- package/src/components/openapi/helpers.ts +36 -2
- package/src/components/openapi/message-model.ts +54 -11
- package/src/components/openapi/message.ts +14 -4
- package/src/components/openapi/operation-model.ts +16 -7
- package/src/components/openapi/playground-client.ts +77 -58
- package/src/components/openapi/playground-schema.ts +1 -1
- package/src/components/openapi/schema-tree.ts +44 -14
- package/src/components/openapi/security.ts +10 -0
- package/src/components/openapi/snippets.ts +5 -3
- package/src/components/openapi/validate-json.ts +4 -3
- package/src/components/powered-by-middleware.ts +33 -0
- package/src/core/changelog-index.ts +31 -1
- package/src/core/component-diagnostics.ts +53 -0
- package/src/core/component-overrides.ts +32 -0
- package/src/core/config-input.ts +42 -6
- package/src/core/data.ts +2 -0
- package/src/core/diagnostics.ts +5 -0
- package/src/core/i18n-ui.ts +2 -0
- package/src/core/includes.ts +1 -1
- package/src/core/links.ts +47 -17
- package/src/core/powered-by.ts +12 -0
- package/src/core/probe.ts +26 -6
- package/src/core/project-graph.ts +59 -18
- package/src/core/redirect-patterns.ts +36 -7
- package/src/core/schema.ts +26 -6
- package/src/core/sources/cache.ts +6 -0
- package/src/core/sources/contentful-rich-text.ts +29 -6
- package/src/core/sources/contentful.ts +135 -25
- package/src/core/sources/filesystem.ts +26 -4
- package/src/core/sources/github-releases.ts +12 -1
- package/src/core/sources/lexical.ts +15 -10
- package/src/core/sources/lower.ts +19 -3
- package/src/core/sources/mdx-remote.ts +62 -10
- package/src/core/sources/normalize.ts +227 -41
- package/src/core/sources/notion.ts +34 -10
- package/src/core/sources/obsidian.ts +16 -3
- package/src/core/sources/payload.ts +38 -15
- package/src/core/sources/remote.ts +72 -15
- package/src/core/sources/resolve.ts +11 -1
- package/src/core/sources/sanity.ts +43 -25
- package/src/core/sources/strapi.ts +2 -2
- package/src/core/types.ts +18 -0
- package/src/core/ui-packs/ar.ts +1 -0
- package/src/core/ui-packs/bg.ts +1 -0
- package/src/core/ui-packs/bn.ts +1 -0
- package/src/core/ui-packs/ca.ts +1 -0
- package/src/core/ui-packs/cs.ts +1 -0
- package/src/core/ui-packs/da.ts +1 -0
- package/src/core/ui-packs/de.ts +1 -0
- package/src/core/ui-packs/el.ts +1 -0
- package/src/core/ui-packs/es.ts +1 -0
- package/src/core/ui-packs/fa.ts +1 -0
- package/src/core/ui-packs/fi.ts +1 -0
- package/src/core/ui-packs/fr.ts +1 -0
- package/src/core/ui-packs/he.ts +1 -0
- package/src/core/ui-packs/hi.ts +1 -0
- package/src/core/ui-packs/hr.ts +1 -0
- package/src/core/ui-packs/hu.ts +1 -0
- package/src/core/ui-packs/id.ts +1 -0
- package/src/core/ui-packs/it.ts +1 -0
- package/src/core/ui-packs/ja.ts +1 -0
- package/src/core/ui-packs/ko.ts +1 -0
- package/src/core/ui-packs/nl.ts +1 -0
- package/src/core/ui-packs/no.ts +1 -0
- package/src/core/ui-packs/pl.ts +1 -0
- package/src/core/ui-packs/pt-br.ts +1 -0
- package/src/core/ui-packs/pt.ts +1 -0
- package/src/core/ui-packs/ro.ts +1 -0
- package/src/core/ui-packs/ru.ts +1 -0
- package/src/core/ui-packs/sk.ts +1 -0
- package/src/core/ui-packs/sr.ts +1 -0
- package/src/core/ui-packs/sv.ts +1 -0
- package/src/core/ui-packs/th.ts +1 -0
- package/src/core/ui-packs/tr.ts +1 -0
- package/src/core/ui-packs/uk.ts +1 -0
- package/src/core/ui-packs/vi.ts +1 -0
- package/src/core/ui-packs/zh-tw.ts +1 -0
- package/src/core/ui-packs/zh.ts +1 -0
- package/src/deploy/adapter-output.ts +7 -2
- package/src/deploy/adapters/cloudflare.ts +7 -5
- package/src/deploy/adapters/node.ts +47 -9
- package/src/deploy/adapters/types.ts +7 -3
- package/src/deploy/artifacts.ts +2 -1
- package/src/deploy/cloudflare-negotiation.ts +36 -7
- package/src/deploy/headers.ts +15 -1
- package/src/deploy/node-headers.ts +32 -20
- package/src/deploy/platforms/cloudflare.ts +14 -9
- package/src/deploy/platforms/netlify.ts +2 -1
- package/src/deploy/platforms/node.ts +12 -2
- package/src/deploy/platforms/types.ts +21 -7
- package/src/deploy/platforms/vercel.ts +115 -17
- package/src/deploy/redirects.ts +66 -6
- package/src/deploy/rss.ts +3 -1
- package/src/deploy/sitemap.ts +39 -5
- package/src/deploy/vercel-negotiation.ts +325 -103
- package/src/eval/agents.ts +18 -1
- package/src/eval/prompts.ts +6 -3
- package/src/eval/report.ts +34 -13
- package/src/eval/run.ts +5 -0
- package/src/markdown/base-links.ts +15 -14
- package/src/markdown/package-commands.ts +9 -8
- package/src/markdown/relative-links.ts +3 -2
- package/src/narration/build.ts +218 -40
- package/src/narration/provider.ts +89 -9
- package/src/openapi/checks.ts +273 -0
- package/src/openapi/graphql-build.ts +21 -0
- package/src/openapi/graphql.ts +11 -0
- package/src/openapi/model.ts +15 -3
- package/src/openapi/parse.ts +127 -2
- package/src/openapi/references.ts +43 -3
- package/src/openapi/render-mdx.ts +68 -8
- package/src/openapi/sentence.ts +29 -2
- package/src/openapi/source.ts +39 -14
- package/src/ratelimit/index.ts +1 -1
- package/src/ratelimit/runtime.ts +37 -19
- package/src/ratelimit/upstash.ts +40 -10
- package/src/reference/graphql.ts +15 -1
- package/src/reference/index.ts +1 -0
- package/src/reference/openapi.ts +2 -2
- package/src/reference/options.ts +29 -1
- package/src/registry/eject.ts +8 -2
- package/src/search/adapters/locale-scope.ts +30 -0
- package/src/search/adapters/typesense.ts +14 -4
- package/src/search/build.ts +21 -3
- package/src/search/orama-index.ts +163 -31
- package/src/search/source-pages.ts +29 -0
- package/src/search/sync/algolia.ts +99 -9
- package/src/search/sync/index.ts +52 -13
- package/src/search/sync/typesense.ts +72 -27
- package/src/seo/jsonld.ts +38 -20
- package/src/sources/contentful.ts +12 -0
- package/src/sources/github-releases.ts +7 -1
- package/src/sources/notion.ts +7 -0
- package/src/sources/shared.ts +3 -0
- package/src/theme/color.ts +9 -10
- package/src/theme/entry.ts +43 -6
- package/src/translate/validate.ts +23 -1
- package/dist/cli/chunk-0gz36akr.js.map +0 -12
- package/dist/cli/chunk-2n4ps1b3.js.map +0 -15
- package/dist/cli/chunk-43zcf4gz.js.map +0 -36
- package/dist/cli/chunk-4ejxbzee.js +0 -39
- package/dist/cli/chunk-4ejxbzee.js.map +0 -10
- package/dist/cli/chunk-4h8z9vv5.js.map +0 -16
- package/dist/cli/chunk-713mngdq.js.map +0 -14
- package/dist/cli/chunk-9xr4dgee.js.map +0 -10
- package/dist/cli/chunk-amrb6hgh.js +0 -145
- package/dist/cli/chunk-amrb6hgh.js.map +0 -11
- package/dist/cli/chunk-nd1821sk.js.map +0 -10
- package/dist/cli/chunk-rekqz4qg.js.map +0 -10
- package/dist/cli/chunk-ta27feev.js.map +0 -10
- package/dist/cli/chunk-xkz5xbtv.js.map +0 -213
- package/dist/cli/chunk-y5h4r2y0.js.map +0 -10
- package/dist/cli/chunk-zf748avv.js.map +0 -37
- /package/dist/cli/{chunk-9geymqns.js.map → chunk-0w6hs479.js.map} +0 -0
- /package/dist/cli/{chunk-y4ykbark.js.map → chunk-1f882900.js.map} +0 -0
- /package/dist/cli/{chunk-py62fewh.js.map → chunk-53jqw8z0.js.map} +0 -0
- /package/dist/cli/{chunk-5wj2qwn2.js.map → chunk-58bt3hag.js.map} +0 -0
- /package/dist/cli/{chunk-e7vvk5ya.js.map → chunk-5cmts6dv.js.map} +0 -0
- /package/dist/cli/{chunk-g2z9x01v.js.map → chunk-9qzgg6mj.js.map} +0 -0
- /package/dist/cli/{chunk-q3wxxq39.js.map → chunk-a57yh0h9.js.map} +0 -0
- /package/dist/cli/{chunk-2f3ndkpw.js.map → chunk-desvm72z.js.map} +0 -0
- /package/dist/cli/{chunk-gp84za0h.js.map → chunk-dhwtqnnd.js.map} +0 -0
- /package/dist/cli/{chunk-2f7n4qzt.js.map → chunk-dqhg54mr.js.map} +0 -0
- /package/dist/cli/{chunk-zhvd6adm.js.map → chunk-gfc5fqvf.js.map} +0 -0
- /package/dist/cli/{chunk-p804f3pe.js.map → chunk-hvcxng5f.js.map} +0 -0
- /package/dist/cli/{chunk-1n228xqb.js.map → chunk-kdpzw38a.js.map} +0 -0
- /package/dist/cli/{chunk-6bm0xpgd.js.map → chunk-s0bdnc7v.js.map} +0 -0
- /package/dist/cli/{chunk-cmtcnh9f.js.map → chunk-tfycddbt.js.map} +0 -0
- /package/dist/cli/{chunk-ntv4qrt7.js.map → chunk-y4msrwm9.js.map} +0 -0
- /package/dist/cli/{chunk-yj17vs39.js.map → chunk-ydp3065p.js.map} +0 -0
|
@@ -21,17 +21,17 @@ Keep content where it is — set `content.root: "src/content/docs"`.
|
|
|
21
21
|
| `logo` (`{ src }` or `{ light, dark, alt }`) | `logo` — move the referenced file into `public/` |
|
|
22
22
|
| `logo.replacesTitle` | `logo: { text: "" }` (renders the mark alone) |
|
|
23
23
|
| `favicon` | copy the file into `public/` (drop the config field — Blume auto-detects) |
|
|
24
|
-
| `social` (array of `{ label, icon, href }`; pre-0.33 legacy: `{ github: url }` object) | derive **`github: { owner, repo }`** from the GitHub entry; other socials drop (report) |
|
|
24
|
+
| `social` (array of `{ label, icon, href }`; pre-0.33 legacy: `{ github: url }` object) | derive **`github: { owner, repo }`** from the GitHub entry; every other entry whose platform Blume knows → **`footer.socials`** (`{ discord: href, bluesky: href, … }`; the `x.com`/`twitter` icon → `x`; the platform list is under `footer` in `docs/configuration/index.mdx`); the rest (`mastodon`, `gitlab`, `rss`, …) drop (report) |
|
|
25
25
|
| `editLink.baseUrl` (`…/edit/<branch>/<subdir?>`) | `github: { owner, repo, branch }` — **and any repo sub-path after the branch → `github.dir`** (a docs-in-subfolder repo breaks every edit link without it); **an origin other than `https://github.com` → `github.host`** (a GitHub Enterprise repo otherwise links to the public site) |
|
|
26
26
|
| `sidebar` (array) | filesystem nav / `navigation.sidebar` (see below) |
|
|
27
27
|
| `tableOfContents` (`false` or `{ minHeadingLevel, maxHeadingLevel }`) | `toc` — identical shape, 1:1 |
|
|
28
28
|
| `markdown.headingLinks: false` | `markdown.headingAnchors: false` |
|
|
29
29
|
| `expressiveCode.themes` | `markdown.code.theme: { light, dark }` — EC assigns by theme _type_, so match each theme by its darkness, not by array position |
|
|
30
30
|
| `expressiveCode.styleOverrides` | drop → restyle via a root `theme.css` file |
|
|
31
|
-
| `head` |
|
|
31
|
+
| `head` | per entry: a `meta` tag → **`seo.metatags`** (`{ [attrs.name ?? attrs.property]: attrs.content }` — verification tokens, `theme-color`, and the like), minus the tags Blume writes itself (`description`, `robots`, `og:title`/`og:description`/`og:image`/`og:url`/`og:type`/`og:site_name`, `twitter:*` card tags, `article:*` dates — the build refuses them and names the setting that owns each, e.g. `og:image` → `seo.og`, `twitter:site` → `seo.x.handle`); an analytics `<script>` → one `script()` adapter each in the `analytics` list (from `blume/analytics`): `attrs.src` → `src`, an `async`/`defer` attr → `strategy`, every other `attrs` key → `attributes`, and an inline body (`content`) → `content`; anything else (`link`, `style`, other scripts) → drop and report |
|
|
32
32
|
| `lastUpdated: true` | `lastModified: "git"` |
|
|
33
33
|
| `customCss` | drop → move into a root **`theme.css`** file (auto-picked-up; not a config field) |
|
|
34
|
-
| `components` (overrides) | Blume's layout slots via `defineComponents({ layout: { Header
|
|
34
|
+
| `components` (overrides) | Blume's layout slots via `defineComponents({ layout: { … } })` in a root `components.ts`: `Header`, `Search`, `Sidebar`, `TableOfContents`, `Pagination` keep their names; `SiteTitle` → `Logo`; **`Footer` → `PageFooter`**, not Blume's `Footer` (that slot is the site footer; Starlight's `Footer` is the page-end last-updated date, pagination, and edit link, which Blume renders itself, so keep only what the override added). Other overrides (`Banner`, `PageTitle`, `Hero`, `EditLink`, `SocialIcons`, …) have no slot — fold their additions into `PageHeader`/`PageFooter`, or `blume eject`; a Starlight name left under `layout` matches no slot and does nothing. Rewrite reads of `Astro.locals.starlightRoute` against the slot's props |
|
|
35
35
|
| `plugins` | **map, don't blanket-drop** — see Plugins below |
|
|
36
36
|
| `pagination: false`, `pagefind`/Pagefind options, `titleDelimiter`, `credits`, `disable404Route`, `routeMiddleware` | drop (report) |
|
|
37
37
|
| `locales` / `defaultLocale` | `i18n` (see below) |
|
|
@@ -40,7 +40,7 @@ Keep content where it is — set `content.root: "src/content/docs"`.
|
|
|
40
40
|
|
|
41
41
|
Starlight's `sidebar` array → prefer letting Blume generate from the filesystem; use `navigation.sidebar` only for shapes files can't express:
|
|
42
42
|
|
|
43
|
-
- `{ label, autogenerate: { directory: "d" } }` → **structure the folder and rely on filesystem nav** (label → the folder's `meta.ts` `title`). Do **not** map it to a sidebar item with `root:` — in an explicit Blume sidebar that renders a single page link, not the directory's children.
|
|
43
|
+
- `{ label, items: [{ autogenerate: { directory: "d" } }] }` (0.39 and later; before 0.39 the group held it directly, `{ label, autogenerate: { directory: "d" } }`) → **structure the folder and rely on filesystem nav** (label → the folder's `meta.ts` `title`; `autogenerate.collapsed` → `collapsed: true` in each subfolder's `meta.ts`). Do **not** map it to a sidebar item with `root:` — in an explicit Blume sidebar that renders a single page link, not the directory's children. Since 0.39 a group's `items` can mix manual entries with an `autogenerate` entry; move those manual pages into the folder (route change → `redirects`) so the folder holds the whole group.
|
|
44
44
|
- string `"guides/intro"` → `"/guides/intro"`; `{ label?, slug }` → `/<slug>`.
|
|
45
45
|
- `{ label, items: [...] }` → `{ label, items: [...] }` (recursive) — or better, a real folder.
|
|
46
46
|
- `{ label?, link }` → `{ label, href: link }`.
|
|
@@ -59,7 +59,8 @@ Starlight's `sidebar` array → prefer letting Blume generate from the filesyste
|
|
|
59
59
|
| `lastUpdated: false` (boolean) | **remove** (Blume's `lastModified` takes a date; a boolean is a build error) |
|
|
60
60
|
| `prev: false` **and** `next: false` | `pagination: false` (hides both links) |
|
|
61
61
|
| `prev` / `next` otherwise (one side, or a label/link) | **drop** (report — the links can only be hidden together, and their labels come from the linked pages) |
|
|
62
|
-
| `template: splash`
|
|
62
|
+
| `template: splash` | `mode: center` (no sidebar, a wider centered column — the closest layout; report) |
|
|
63
|
+
| `hero` | **no key** — its tagline → a paragraph, its actions → `<Card>`s or links, its image → a Markdown image (report); for a designed landing page, rebuild it as a custom `.astro` page under `content.pages` (`pages/index.astro` on `PageLayout` wins over the content page) |
|
|
63
64
|
| `banner`, `tableOfContents`, `editUrl`, `head` | drop (report) |
|
|
64
65
|
|
|
65
66
|
## Asides → directives (and the `.md` trap)
|
|
@@ -83,7 +84,8 @@ Starlight content is full of Expressive Code fence meta; Blume understands some
|
|
|
83
84
|
- `title="file.js"` → works as-is (or use the space-title shorthand). Line ranges `{2-3}` → work as-is.
|
|
84
85
|
- `ins=`/`del=` line marks → `// [!code ++]` / `// [!code --]` comments; `mark=` → `{ranges}` or `// [!code highlight]`.
|
|
85
86
|
- `showLineNumbers` → `lineNumbers`.
|
|
86
|
-
-
|
|
87
|
+
- `wrap` / `wrap=true` → a bare `wrap` (that block's long lines wrap); a site-wide `expressiveCode.defaultProps.wrap: true` → `markdown.code.wrap: true`.
|
|
88
|
+
- **Drop:** `frame="terminal"`, `collapse=`, `wrap=false`, `preserveIndent`/`hangingIndent`, `"string"` and `/regex/` text markers (report if they carried meaning).
|
|
87
89
|
- ` ```diff lang="js" ` → a normal ` ```js ` fence with `[!code ++]`/`[!code --]` markers.
|
|
88
90
|
|
|
89
91
|
## Plugins — map, don't drop
|
|
@@ -114,4 +116,4 @@ Remove `@astrojs/starlight` (and plugin deps) from deps, delete the Starlight bi
|
|
|
114
116
|
|
|
115
117
|
## Dropped — report these
|
|
116
118
|
|
|
117
|
-
|
|
119
|
+
Socials on a platform `footer.socials` lacks, badge variants, sidebar/item `attrs` + `translations`, `customCss` beyond `theme.css`, `head` entries other than meta tags and analytics scripts, a page's frontmatter `head`, `routeMiddleware`, splash layouts approximated with `mode: center` and hero blocks rebuilt as content, override components with no Blume slot, starlight-blog's tag and author pages, aside custom icons, EC frames/collapse/text markers, prev/next toggles, unmapped plugins, any `<Icon>` name with no Lucide equivalent.
|
package/src/ai/ask-context.ts
CHANGED
|
@@ -622,10 +622,37 @@ export interface ReaderScope {
|
|
|
622
622
|
filters: { locale: string | undefined; version: string | undefined };
|
|
623
623
|
}
|
|
624
624
|
|
|
625
|
+
// The snapshot's locale codes, keyed lowercase, built once per snapshot.
|
|
626
|
+
const localeCodes = new WeakMap<AskData, Map<string, string>>();
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* The locale a path's first segment names (`/ja` or `/ja/pricing` → `ja`),
|
|
630
|
+
* when it's one the snapshot's documents carry: a page outside the docs,
|
|
631
|
+
* like a localized landing page, still says which language it's in.
|
|
632
|
+
*/
|
|
633
|
+
const pathLocale = (data: AskData, path: string): string | undefined => {
|
|
634
|
+
let codes = localeCodes.get(data);
|
|
635
|
+
if (!codes) {
|
|
636
|
+
codes = new Map<string, string>();
|
|
637
|
+
for (const { locale } of data.documents) {
|
|
638
|
+
if (locale) {
|
|
639
|
+
codes.set(locale.toLowerCase(), locale);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
localeCodes.set(data, codes);
|
|
643
|
+
}
|
|
644
|
+
const [, first = ""] = normalizeRoute(path).split("/");
|
|
645
|
+
return first ? codes.get(first.toLowerCase()) : undefined;
|
|
646
|
+
};
|
|
647
|
+
|
|
625
648
|
/**
|
|
626
649
|
* Where the reader is: their page, when it's in the snapshot, and the locale
|
|
627
|
-
* and docs version retrieval keeps to.
|
|
628
|
-
*
|
|
650
|
+
* and docs version retrieval keeps to. A page the snapshot doesn't have (the
|
|
651
|
+
* homepage, a custom page, or none at all from a cross-origin caller) keeps
|
|
652
|
+
* to the locale its path's first segment names, or the default locale, so
|
|
653
|
+
* translations of every page don't crowd each other out. Without a page, a
|
|
654
|
+
* versioned site grounds in the current docs rather than every archived copy
|
|
655
|
+
* of each page.
|
|
629
656
|
*/
|
|
630
657
|
export const readerScope = (
|
|
631
658
|
data: AskData,
|
|
@@ -635,10 +662,13 @@ export const readerScope = (
|
|
|
635
662
|
const current = page?.path
|
|
636
663
|
? byRoute.get(normalizeRoute(page.path))
|
|
637
664
|
: undefined;
|
|
665
|
+
const locale = current
|
|
666
|
+
? current.locale
|
|
667
|
+
: (page?.path && pathLocale(data, page.path)) || data.defaultLocale;
|
|
638
668
|
return {
|
|
639
669
|
current,
|
|
640
670
|
filters: {
|
|
641
|
-
locale:
|
|
671
|
+
locale: locale || undefined,
|
|
642
672
|
version: data.versioned ? (current?.version ?? "") : undefined,
|
|
643
673
|
},
|
|
644
674
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one request to the assistant's generated route (`/api/ask`) may carry.
|
|
3
|
+
* The route answers a longer conversation with a `400` (see
|
|
4
|
+
* `askEndpointTemplate`), so the panel's client (`useAssistant`) sends only
|
|
5
|
+
* the latest turns that fit. The endpoint is unauthenticated, so the limits
|
|
6
|
+
* bound what one request can spend against the model.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** The most messages, questions and answers together, one request sends. */
|
|
10
|
+
export const ASK_MAX_MESSAGES = 40;
|
|
11
|
+
|
|
12
|
+
/** The most characters the messages take as JSON (`JSON.stringify`). */
|
|
13
|
+
export const ASK_MAX_MESSAGES_CHARS = 24_000;
|
package/src/ai/ask.ts
CHANGED
|
@@ -110,7 +110,8 @@ export interface AssistantGatewayOptions extends AssistantAdapterOptions {
|
|
|
110
110
|
* How much the model reasons before answering. Sent as the AI SDK's
|
|
111
111
|
* top-level `reasoning` option, which the gateway maps to the model's own
|
|
112
112
|
* control (OpenAI's `reasoning_effort`, for example); the model has to
|
|
113
|
-
* offer the level you pick. Omitted keeps the model's default.
|
|
113
|
+
* offer the level you pick. Omitted keeps the model's default. Assistant
|
|
114
|
+
* only.
|
|
114
115
|
*/
|
|
115
116
|
reasoning?: AssistantReasoning;
|
|
116
117
|
/** Narration only: the speech model's voice. Defaults to `alloy`. */
|
|
@@ -153,32 +154,47 @@ export const gateway = (
|
|
|
153
154
|
// openai()
|
|
154
155
|
// ---------------------------------------------------------------------------
|
|
155
156
|
|
|
156
|
-
const OPENAI_API_KEY_ENV = "OPENAI_API_KEY";
|
|
157
|
+
export const OPENAI_API_KEY_ENV = "OPENAI_API_KEY";
|
|
157
158
|
|
|
158
159
|
/** Options for {@link openai}. */
|
|
159
160
|
export interface AssistantOpenAIOptions extends AssistantAdapterOptions {
|
|
161
|
+
/**
|
|
162
|
+
* Name of the env var holding the key. Defaults to `OPENAI_API_KEY`, except
|
|
163
|
+
* for narration with a `baseUrl`, which sends only a key named here.
|
|
164
|
+
*/
|
|
165
|
+
apiKeyEnv?: string;
|
|
160
166
|
/**
|
|
161
167
|
* An OpenAI-compatible endpoint to call instead of OpenAI
|
|
162
168
|
* (`https://llm.internal.example.com/v1`): a self-hosted model or an
|
|
163
169
|
* internal gateway. The route then talks Chat Completions through
|
|
164
170
|
* `@ai-sdk/openai-compatible`, and the docs tools are off unless
|
|
165
171
|
* `ai.assistant.tools` turns them on, since the model may not call tools.
|
|
172
|
+
* For narration, a server with OpenAI's speech API (`/audio/speech`),
|
|
173
|
+
* called through `@ai-sdk/openai` and sent only the key `apiKeyEnv` names,
|
|
174
|
+
* if any.
|
|
166
175
|
*/
|
|
167
176
|
baseUrl?: string;
|
|
168
|
-
/**
|
|
177
|
+
/**
|
|
178
|
+
* Narration only: how the voice should sound, for speech models that take
|
|
179
|
+
* instructions ("Read calmly, like a teacher").
|
|
180
|
+
*/
|
|
181
|
+
instructions?: string;
|
|
182
|
+
/** The model id (`gpt-5.5`, or a speech model like `gpt-4o-mini-tts`). */
|
|
169
183
|
model: string;
|
|
170
184
|
/**
|
|
171
185
|
* The provider name the AI SDK reports, which a custom endpoint also reads
|
|
172
186
|
* its `providerOptions` under. Defaults to `openai`, or `openai-compatible`
|
|
173
|
-
* with a `baseUrl`.
|
|
187
|
+
* with a `baseUrl`. Assistant only.
|
|
174
188
|
*/
|
|
175
189
|
name?: string;
|
|
176
190
|
/**
|
|
177
191
|
* How much the model reasons before answering, sent as `reasoning_effort`;
|
|
178
192
|
* with a `baseUrl`, the endpoint has to accept that parameter. Omitted
|
|
179
|
-
* keeps the model's default.
|
|
193
|
+
* keeps the model's default. Assistant only.
|
|
180
194
|
*/
|
|
181
195
|
reasoning?: AssistantReasoning;
|
|
196
|
+
/** Narration only: the speech model's voice. Defaults to `alloy`. */
|
|
197
|
+
voice?: string;
|
|
182
198
|
}
|
|
183
199
|
|
|
184
200
|
const openaiOptionsSchema = z.strictObject({
|
|
@@ -203,7 +219,9 @@ export const openaiAdapterSchema = adapterDescriptorSchema(
|
|
|
203
219
|
* Route the assistant to OpenAI, or to any OpenAI-compatible endpoint with
|
|
204
220
|
* `baseUrl`. Reads `OPENAI_API_KEY` and needs `@ai-sdk/openai` installed; a
|
|
205
221
|
* custom endpoint needs `@ai-sdk/openai-compatible` instead, since most
|
|
206
|
-
* don't serve OpenAI's Responses API.
|
|
222
|
+
* don't serve OpenAI's Responses API. Narration generates audio with it
|
|
223
|
+
* through `@ai-sdk/openai` either way, and with a `baseUrl` sends only the key
|
|
224
|
+
* `apiKeyEnv` names.
|
|
207
225
|
*/
|
|
208
226
|
export const openai = (
|
|
209
227
|
options: AssistantOpenAIOptions
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { mountBasePath, normalizeBasePath } from "../core/base-path.ts";
|
|
2
|
+
import { withChangelogIndexText } from "../core/changelog-index.ts";
|
|
2
3
|
import { EN_UI, resolveUIStrings } from "../core/i18n-ui.ts";
|
|
3
4
|
import type { BlumeProject } from "../core/project-graph.ts";
|
|
4
5
|
import { absoluteUrl } from "../core/site-url.ts";
|
|
@@ -45,12 +46,16 @@ const rowLine = (project: BlumeProject, { date, page }: IndexRow): string => {
|
|
|
45
46
|
|
|
46
47
|
export const buildChangelogIndexMarkdown = (project: BlumeProject): string => {
|
|
47
48
|
const { i18n } = project.config;
|
|
48
|
-
const ui =
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
const ui = withChangelogIndexText(
|
|
50
|
+
project.config,
|
|
51
|
+
i18n
|
|
52
|
+
? resolveUIStrings(i18n.defaultLocale, {
|
|
53
|
+
defaultLocale: i18n.defaultLocale,
|
|
54
|
+
overrides: i18n.ui,
|
|
55
|
+
})
|
|
56
|
+
: EN_UI,
|
|
57
|
+
i18n?.defaultLocale
|
|
58
|
+
);
|
|
54
59
|
const rows: IndexRow[] = project.graph.pages
|
|
55
60
|
.filter(
|
|
56
61
|
(page) =>
|
|
@@ -584,7 +584,7 @@ export const inlineCode = (text: string): string => {
|
|
|
584
584
|
};
|
|
585
585
|
|
|
586
586
|
/** Fence `code` so its opening/closing run outlengths any backticks inside. */
|
|
587
|
-
const fencedBlock = (lang: string, code: string): string => {
|
|
587
|
+
export const fencedBlock = (lang: string, code: string): string => {
|
|
588
588
|
const trimmed = code.replace(/(?<!\n)\n+$/u, "");
|
|
589
589
|
const runs = trimmed.match(/`+/gu);
|
|
590
590
|
const longest = runs ? Math.max(...runs.map((run) => run.length)) : 0;
|
package/src/ai/cors.ts
CHANGED
|
@@ -66,6 +66,13 @@ interface RequestContext {
|
|
|
66
66
|
request: Request;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* The response headers a cross-origin caller may read beyond the safelisted
|
|
71
|
+
* ones: the rate limit's `Retry-After`, so a caller can tell a reader how
|
|
72
|
+
* long to wait after a `429`.
|
|
73
|
+
*/
|
|
74
|
+
const EXPOSED_HEADERS = "retry-after";
|
|
75
|
+
|
|
69
76
|
/** Stamp the CORS headers on every response `handler` returns. */
|
|
70
77
|
export const withCors =
|
|
71
78
|
(
|
|
@@ -74,9 +81,8 @@ export const withCors =
|
|
|
74
81
|
): ((context: RequestContext) => Promise<Response>) =>
|
|
75
82
|
async (context) => {
|
|
76
83
|
const response = await handler(context);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
)) {
|
|
84
|
+
const headers = corsHeaders(context.request, allowed);
|
|
85
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
80
86
|
// `Vary` accumulates (the handler may already vary on something), the
|
|
81
87
|
// rest replace.
|
|
82
88
|
if (key === "vary") {
|
|
@@ -85,5 +91,8 @@ export const withCors =
|
|
|
85
91
|
response.headers.set(key, value);
|
|
86
92
|
}
|
|
87
93
|
}
|
|
94
|
+
if (headers["access-control-allow-origin"]) {
|
|
95
|
+
response.headers.set("access-control-expose-headers", EXPOSED_HEADERS);
|
|
96
|
+
}
|
|
88
97
|
return response;
|
|
89
98
|
};
|
package/src/ai/mcp/query.ts
CHANGED
|
@@ -53,20 +53,28 @@ const contentTypesField = z.preprocess((value) => {
|
|
|
53
53
|
}, z.array(z.string()).optional().describe('Only include pages of these content types (frontmatter `type`, e.g. `["doc", "rfc"]`). `list_pages` shows each page\'s type. Omit to include every type.'));
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
|
-
* The optional facet filter `search_docs` and `list_pages` share.
|
|
57
|
-
*
|
|
56
|
+
* The optional facet filter `search_docs` and `list_pages` share. A value
|
|
57
|
+
* is read the way `pageFacets` stores one: a string as-is, a number or
|
|
58
|
+
* boolean stringified (`{"priority": 1}` matches the facet `"1"`). Entries of
|
|
59
|
+
* any other shape are dropped; an empty `{}` means "no filter".
|
|
58
60
|
*/
|
|
59
|
-
/** Accepts any plain object, so the
|
|
61
|
+
/** Accepts any plain object, so the usable entries can be sifted out. */
|
|
60
62
|
const looseFacetObject = z.record(z.string(), z.unknown());
|
|
61
63
|
|
|
64
|
+
/** A filter value a facet can hold, stringified like `pageFacets` does. */
|
|
65
|
+
const facetFilterValue = z
|
|
66
|
+
.union([z.string(), z.number(), z.boolean()])
|
|
67
|
+
.transform(String);
|
|
68
|
+
|
|
62
69
|
const filtersField = z.preprocess((value) => {
|
|
63
70
|
const candidate = looseFacetObject.safeParse(value);
|
|
64
71
|
if (!candidate.success) {
|
|
65
72
|
return;
|
|
66
73
|
}
|
|
67
|
-
const entries = Object.entries(candidate.data).
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
const entries = Object.entries(candidate.data).flatMap(([key, entry]) => {
|
|
75
|
+
const parsed = facetFilterValue.safeParse(entry);
|
|
76
|
+
return parsed.success ? [[key, parsed.data] as const] : [];
|
|
77
|
+
});
|
|
70
78
|
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
71
79
|
}, z.record(z.string(), z.string()).optional().describe('Only include pages matching every facet, key → required value (e.g. `{"status": "enforced"}`). Facets are metadata the site declares per content type; `list_pages` shows each page\'s facet values. Omit for no facet filtering.'));
|
|
72
80
|
|
|
@@ -1,13 +1,24 @@
|
|
|
1
|
+
import { customCodeSamples } from "../components/openapi/code-samples.ts";
|
|
1
2
|
import { mountBasePath, normalizeBasePath } from "../core/base-path.ts";
|
|
2
3
|
import type { ApiOperationRef, OpenApiData } from "../openapi/model.ts";
|
|
3
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
operationObject,
|
|
6
|
+
operationOf,
|
|
7
|
+
specAddresses,
|
|
8
|
+
specOf,
|
|
9
|
+
} from "../openapi/model.ts";
|
|
4
10
|
import { asSentence } from "../openapi/sentence.ts";
|
|
5
11
|
import { operationSignature } from "../openapi/signature.ts";
|
|
6
12
|
import type {
|
|
7
13
|
ComponentMarkdown,
|
|
8
14
|
EvaluatedValue,
|
|
9
15
|
} from "./component-markdown.ts";
|
|
10
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
fencedBlock,
|
|
18
|
+
inlineCode,
|
|
19
|
+
isString,
|
|
20
|
+
linkDestination,
|
|
21
|
+
} from "./component-markdown.ts";
|
|
11
22
|
|
|
12
23
|
/**
|
|
13
24
|
* Spec-authored prose as one line of inline Markdown. Unlike the props the
|
|
@@ -62,7 +73,10 @@ const listItem = (
|
|
|
62
73
|
* section shows. Parameters, schemas and responses are deliberately left out:
|
|
63
74
|
* those are `operation-model.ts` plus each component's own preparation, and a
|
|
64
75
|
* second implementation here would be free to disagree with the page. The
|
|
65
|
-
* endpoint and what it does is the part that was missing altogether.
|
|
76
|
+
* endpoint and what it does is the part that was missing altogether. The
|
|
77
|
+
* spec's own `x-codeSamples` do come along, as fenced code: they're text the
|
|
78
|
+
* spec wrote out (often an SDK call no agent could derive from the
|
|
79
|
+
* endpoint), read through the same `customCodeSamples` the page renders.
|
|
66
80
|
*
|
|
67
81
|
* `specs` is the parsed `blume:openapi` data — empty when the project has no
|
|
68
82
|
* API reference, in which case every serializer declines. `deployBase` is the
|
|
@@ -142,7 +156,17 @@ export const openapiComponentSerializers = (
|
|
|
142
156
|
: "",
|
|
143
157
|
operation.deprecated ? "**Deprecated.**" : "",
|
|
144
158
|
].filter(Boolean);
|
|
145
|
-
|
|
159
|
+
// The spec's own `x-codeSamples`, labeled as their tabs are.
|
|
160
|
+
const object =
|
|
161
|
+
data.kind === "openapi" ? operationObject(data, operation) : undefined;
|
|
162
|
+
const samples = customCodeSamples({
|
|
163
|
+
"x-code-samples": object?.["x-code-samples"],
|
|
164
|
+
"x-codeSamples": object?.["x-codeSamples"],
|
|
165
|
+
}).map(
|
|
166
|
+
(sample) =>
|
|
167
|
+
`**${inlineText(sample.label)}**\n\n${fencedBlock(sample.lang, sample.source)}`
|
|
168
|
+
);
|
|
169
|
+
return [signature, ...notes, ...samples].join("\n\n");
|
|
146
170
|
},
|
|
147
171
|
} satisfies Record<string, ComponentMarkdown>;
|
|
148
172
|
};
|
package/src/ai/relative-links.ts
CHANGED
|
@@ -7,8 +7,6 @@ import {
|
|
|
7
7
|
withAuthoredBasePath,
|
|
8
8
|
withBasePath,
|
|
9
9
|
} from "../core/base-path.ts";
|
|
10
|
-
import { nextFenceState } from "../core/code-fences.ts";
|
|
11
|
-
import type { FenceState } from "../core/code-fences.ts";
|
|
12
10
|
import { localePrefix } from "../core/i18n.ts";
|
|
13
11
|
import {
|
|
14
12
|
buildFileRouteIndex,
|
|
@@ -49,10 +47,6 @@ export interface LinkedPage {
|
|
|
49
47
|
/** Rewrite a page's relative page links to the routes they mean. */
|
|
50
48
|
export type RelativeLinkRewriter = (text: string, page: LinkedPage) => string;
|
|
51
49
|
|
|
52
|
-
/** A reference definition's target: `[label]: ./install` or `<./install>`. */
|
|
53
|
-
const DEFINITION =
|
|
54
|
-
/^(?<lead> {0,3}\[(?:[^\]\\]|\\.)+\]:[\t ]*)(?:<(?<angled>[^>]*)>|(?<bare>\S+))/u;
|
|
55
|
-
|
|
56
50
|
/**
|
|
57
51
|
* Whether a text could hold a relative page link at all: an inline link, a
|
|
58
52
|
* reference definition, or a component `href` whose target isn't a URL with
|
|
@@ -88,31 +82,13 @@ const spliceLine = (line: string, splices: readonly Splice[]): string => {
|
|
|
88
82
|
return out;
|
|
89
83
|
};
|
|
90
84
|
|
|
91
|
-
/** One line's reference-definition splice, when it defines a routed target. */
|
|
92
|
-
const definitionSplice = (
|
|
93
|
-
line: string,
|
|
94
|
-
routed: (target: string) => string | undefined
|
|
95
|
-
): Splice | undefined => {
|
|
96
|
-
const groups = DEFINITION.exec(line)?.groups;
|
|
97
|
-
const lead = groups?.lead;
|
|
98
|
-
const target = groups?.angled ?? groups?.bare;
|
|
99
|
-
const route = target === undefined ? undefined : routed(target);
|
|
100
|
-
if (lead === undefined || target === undefined || route === undefined) {
|
|
101
|
-
return undefined;
|
|
102
|
-
}
|
|
103
|
-
// An angle-bracketed target starts one past its `<`.
|
|
104
|
-
const angled = groups?.angled === undefined ? 0 : 1;
|
|
105
|
-
return { column: lead.length + angled, length: target.length, text: route };
|
|
106
|
-
};
|
|
107
|
-
|
|
108
85
|
/**
|
|
109
|
-
* Every routed splice in `text`, by 0-based line: links
|
|
110
|
-
* definitions. An image target goes
|
|
111
|
-
* `routed`.
|
|
86
|
+
* Every routed splice in `text`, by 0-based line: links, images, and
|
|
87
|
+
* reference definitions, as `extractLinks` finds them. An image target goes
|
|
88
|
+
* through `imaged`, everything else through `routed`.
|
|
112
89
|
*/
|
|
113
90
|
const collectSplices = (
|
|
114
91
|
text: string,
|
|
115
|
-
lines: readonly string[],
|
|
116
92
|
routed: (target: string) => string | undefined,
|
|
117
93
|
imaged: (target: string) => string | undefined
|
|
118
94
|
): Map<number, Splice[]> => {
|
|
@@ -130,16 +106,6 @@ const collectSplices = (
|
|
|
130
106
|
});
|
|
131
107
|
}
|
|
132
108
|
}
|
|
133
|
-
let fence: FenceState = null;
|
|
134
|
-
for (const [index, line] of lines.entries()) {
|
|
135
|
-
const next = nextFenceState(line, fence);
|
|
136
|
-
const inFence = fence !== null || next !== null;
|
|
137
|
-
fence = next;
|
|
138
|
-
const splice = inFence ? undefined : definitionSplice(line, routed);
|
|
139
|
-
if (splice !== undefined) {
|
|
140
|
-
add(index, splice);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
109
|
return splices;
|
|
144
110
|
};
|
|
145
111
|
|
|
@@ -242,7 +208,7 @@ export const relativeLinkRewriter = (
|
|
|
242
208
|
};
|
|
243
209
|
|
|
244
210
|
const lines = text.split("\n");
|
|
245
|
-
const splices = collectSplices(text,
|
|
211
|
+
const splices = collectSplices(text, routed, imaged);
|
|
246
212
|
|
|
247
213
|
return lines
|
|
248
214
|
.map((line, index) => {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import type { AdapterDescriptor } from "../core/adapter.ts";
|
|
4
|
+
import { adapterDescriptorSchema } from "../core/adapter.ts";
|
|
5
|
+
import type { HeadScript } from "./head.ts";
|
|
6
|
+
|
|
7
|
+
/** The browser tracker in Clics' installation guide. */
|
|
8
|
+
export const CLICS_SCRIPT_SRC = "https://clics.dev/tracker.js";
|
|
9
|
+
|
|
10
|
+
/** Public project ID and optional tracker flags. */
|
|
11
|
+
export interface ClicsOptions {
|
|
12
|
+
/** Project ID from Configure → Tracking in the Clics dashboard. */
|
|
13
|
+
projectId: string;
|
|
14
|
+
/** Include localhost and 127.0.0.1 in a production build's reports. */
|
|
15
|
+
allowLocalhost?: boolean;
|
|
16
|
+
/** Turn off automatic outbound-link events. */
|
|
17
|
+
disableOutboundLinks?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const clicsOptionsSchema = z.strictObject({
|
|
21
|
+
allowLocalhost: z.boolean().optional(),
|
|
22
|
+
disableOutboundLinks: z.boolean().optional(),
|
|
23
|
+
projectId: z.string().min(1),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export type ClicsAdapter = AdapterDescriptor<"clics", ClicsOptions>;
|
|
27
|
+
|
|
28
|
+
export const clicsAdapterSchema = adapterDescriptorSchema(
|
|
29
|
+
"clics",
|
|
30
|
+
clicsOptionsSchema
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
/** Clics website analytics. The project ID is public in the tracker tag. */
|
|
34
|
+
export const clics = (options: ClicsOptions): ClicsAdapter => ({
|
|
35
|
+
kind: "clics",
|
|
36
|
+
options,
|
|
37
|
+
requiredSecrets: [],
|
|
38
|
+
runtimeDeps: [],
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The documented deferred tracker tag. Clics reads these attributes from
|
|
43
|
+
* `document.currentScript` and tracks history changes without a Blume hook.
|
|
44
|
+
*/
|
|
45
|
+
export const clicsHead = (options: ClicsOptions): HeadScript[] => {
|
|
46
|
+
const attributes: HeadScript["attributes"] = {
|
|
47
|
+
"data-project-id": options.projectId,
|
|
48
|
+
defer: true,
|
|
49
|
+
src: CLICS_SCRIPT_SRC,
|
|
50
|
+
};
|
|
51
|
+
if (options.allowLocalhost) {
|
|
52
|
+
attributes["data-allow-localhost"] = true;
|
|
53
|
+
}
|
|
54
|
+
if (options.disableOutboundLinks) {
|
|
55
|
+
attributes["data-disable-outbound-links"] = true;
|
|
56
|
+
}
|
|
57
|
+
return [{ attributes, content: null }];
|
|
58
|
+
};
|
package/src/analytics/head.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { adobeHead } from "./adobe.ts";
|
|
|
2
2
|
import { amplitudeHead } from "./amplitude.ts";
|
|
3
3
|
import { clarityHead } from "./clarity.ts";
|
|
4
4
|
import { clearbitHead } from "./clearbit.ts";
|
|
5
|
+
import { clicsHead } from "./clics.ts";
|
|
5
6
|
import { cloudflareHead } from "./cloudflare.ts";
|
|
6
7
|
import { databuddyHead } from "./databuddy.ts";
|
|
7
8
|
import { fathomHead } from "./fathom.ts";
|
|
@@ -47,6 +48,7 @@ export type HeadNode =
|
|
|
47
48
|
* the one place that branches on `kind`. A provider whose install snippet is
|
|
48
49
|
* two tags (an SDK plus its init call) emits two.
|
|
49
50
|
*/
|
|
51
|
+
// oxlint-disable-next-line complexity -- each adapter has one exhaustive, type-narrowed dispatch case
|
|
50
52
|
const adapterScripts = (
|
|
51
53
|
adapter: Exclude<AnalyticsAdapter, { kind: "vercel" }>
|
|
52
54
|
): HeadScript[] => {
|
|
@@ -63,6 +65,9 @@ const adapterScripts = (
|
|
|
63
65
|
case "clearbit": {
|
|
64
66
|
return clearbitHead(adapter.options);
|
|
65
67
|
}
|
|
68
|
+
case "clics": {
|
|
69
|
+
return clicsHead(adapter.options);
|
|
70
|
+
}
|
|
66
71
|
case "cloudflare": {
|
|
67
72
|
return cloudflareHead(adapter.options);
|
|
68
73
|
}
|
package/src/analytics/index.ts
CHANGED
|
@@ -28,6 +28,8 @@ export { clarity } from "./clarity.ts";
|
|
|
28
28
|
export type { ClarityAdapter, ClarityOptions } from "./clarity.ts";
|
|
29
29
|
export { clearbit } from "./clearbit.ts";
|
|
30
30
|
export type { ClearbitAdapter, ClearbitOptions } from "./clearbit.ts";
|
|
31
|
+
export { clics } from "./clics.ts";
|
|
32
|
+
export type { ClicsAdapter, ClicsOptions } from "./clics.ts";
|
|
31
33
|
export { cloudflare } from "./cloudflare.ts";
|
|
32
34
|
export type { CloudflareAdapter, CloudflareOptions } from "./cloudflare.ts";
|
|
33
35
|
export { databuddy } from "./databuddy.ts";
|
package/src/analytics/schema.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { adobeAdapterSchema } from "./adobe.ts";
|
|
|
4
4
|
import { amplitudeAdapterSchema } from "./amplitude.ts";
|
|
5
5
|
import { clarityAdapterSchema } from "./clarity.ts";
|
|
6
6
|
import { clearbitAdapterSchema } from "./clearbit.ts";
|
|
7
|
+
import { clicsAdapterSchema } from "./clics.ts";
|
|
7
8
|
import { cloudflareAdapterSchema } from "./cloudflare.ts";
|
|
8
9
|
import { databuddyAdapterSchema } from "./databuddy.ts";
|
|
9
10
|
import { fathomAdapterSchema } from "./fathom.ts";
|
|
@@ -28,6 +29,7 @@ export const analyticsAdapterSchema = z.discriminatedUnion("kind", [
|
|
|
28
29
|
amplitudeAdapterSchema,
|
|
29
30
|
clarityAdapterSchema,
|
|
30
31
|
clearbitAdapterSchema,
|
|
32
|
+
clicsAdapterSchema,
|
|
31
33
|
cloudflareAdapterSchema,
|
|
32
34
|
databuddyAdapterSchema,
|
|
33
35
|
fathomAdapterSchema,
|