blume 2.1.3 → 2.2.1
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 +134 -0
- package/README.md +4 -4
- package/dist/cli/{chunk-y4msrwm9.js → chunk-080mfch6.js} +15 -15
- package/dist/cli/{chunk-gfc5fqvf.js → chunk-1ch3ct3r.js} +18 -18
- package/dist/cli/{chunk-gfc5fqvf.js.map → chunk-1ch3ct3r.js.map} +1 -1
- package/dist/cli/{chunk-32khwcb6.js → chunk-2ssh60qh.js} +42 -69
- package/dist/cli/{chunk-32khwcb6.js.map → chunk-2ssh60qh.js.map} +9 -10
- package/dist/cli/{chunk-9qzgg6mj.js → chunk-34wap3ed.js} +3 -3
- package/dist/cli/{chunk-k3gr1nm9.js → chunk-40vk8kgf.js} +13 -16
- package/dist/cli/{chunk-k3gr1nm9.js.map → chunk-40vk8kgf.js.map} +3 -3
- package/dist/cli/chunk-487b95qy.js +329 -0
- package/dist/cli/chunk-487b95qy.js.map +13 -0
- package/dist/cli/chunk-4zxh25hc.js +157 -0
- package/dist/cli/chunk-4zxh25hc.js.map +10 -0
- package/dist/cli/chunk-69rjf786.js +146 -0
- package/dist/cli/chunk-69rjf786.js.map +11 -0
- package/dist/cli/{chunk-dqhg54mr.js → chunk-9h8mh2tk.js} +3 -3
- package/dist/cli/{chunk-dqhg54mr.js.map → chunk-9h8mh2tk.js.map} +2 -2
- package/dist/cli/{chunk-bqxaqn5p.js → chunk-9jqmq5hv.js} +8 -8
- package/dist/cli/{chunk-bqxaqn5p.js.map → chunk-9jqmq5hv.js.map} +1 -1
- package/dist/cli/{chunk-dv2z0rzf.js → chunk-aafhwx74.js} +38 -13
- package/dist/cli/{chunk-dv2z0rzf.js.map → chunk-aafhwx74.js.map} +5 -4
- package/dist/cli/{chunk-desvm72z.js → chunk-b680sv30.js} +22 -26
- package/dist/cli/chunk-b680sv30.js.map +13 -0
- package/dist/cli/{chunk-0w6hs479.js → chunk-beb0z983.js} +30 -18
- package/dist/cli/chunk-beb0z983.js.map +10 -0
- package/dist/cli/{chunk-1f882900.js → chunk-c5bjxq8v.js} +2 -2
- package/dist/cli/chunk-e1n41w9m.js +155 -0
- package/dist/cli/chunk-e1n41w9m.js.map +11 -0
- package/dist/cli/{chunk-sc93apfs.js → chunk-etckvbrh.js} +17 -17
- package/dist/cli/{chunk-sc93apfs.js.map → chunk-etckvbrh.js.map} +2 -2
- package/dist/cli/{chunk-bxwhtvw8.js → chunk-f260jdrn.js} +5 -5
- package/dist/cli/{chunk-74wfhv79.js → chunk-fnxgtjeq.js} +1 -1
- package/dist/cli/{chunk-ms9z66nz.js → chunk-gwy55cx3.js} +2 -2
- package/dist/cli/{chunk-ms9z66nz.js.map → chunk-gwy55cx3.js.map} +2 -2
- package/dist/cli/{chunk-dhwtqnnd.js → chunk-gxhcf2hs.js} +2 -2
- package/dist/cli/{chunk-tfycddbt.js → chunk-h0qwdbem.js} +2 -2
- package/dist/cli/{chunk-nbyvgnnm.js → chunk-hktq4j5r.js} +109 -49
- package/dist/cli/chunk-hktq4j5r.js.map +36 -0
- package/dist/cli/{chunk-twy7psdz.js → chunk-hn3g2b89.js} +14 -10
- package/dist/cli/chunk-hn3g2b89.js.map +10 -0
- package/dist/cli/{chunk-j1x92mx9.js → chunk-j4nfgn2j.js} +1 -1
- package/dist/cli/{chunk-dpy8qdjf.js → chunk-k45sq16q.js} +74 -183
- package/dist/cli/chunk-k45sq16q.js.map +18 -0
- package/dist/cli/{chunk-5cmts6dv.js → chunk-kmswjxj9.js} +7 -7
- package/dist/cli/{chunk-5cmts6dv.js.map → chunk-kmswjxj9.js.map} +1 -1
- package/dist/cli/{chunk-36bxs9c7.js → chunk-nqna8dzp.js} +27 -23
- package/dist/cli/chunk-nqna8dzp.js.map +10 -0
- package/dist/cli/{chunk-a57yh0h9.js → chunk-p834rkcn.js} +7 -7
- package/dist/cli/{chunk-a57yh0h9.js.map → chunk-p834rkcn.js.map} +1 -1
- package/dist/cli/{chunk-60hz265r.js → chunk-ppa6mg4d.js} +24 -11
- package/dist/cli/chunk-ppa6mg4d.js.map +10 -0
- package/dist/cli/{chunk-s0bdnc7v.js → chunk-q1wwrxzw.js} +5 -4
- package/dist/cli/chunk-q1wwrxzw.js.map +10 -0
- package/dist/cli/{chunk-ave1wcbr.js → chunk-qcyxkj44.js} +1 -1
- package/dist/cli/{chunk-124fvmzq.js → chunk-r5nm9w0c.js} +11183 -8806
- package/dist/cli/{chunk-124fvmzq.js.map → chunk-r5nm9w0c.js.map} +82 -66
- package/dist/cli/{chunk-ckrcm08h.js → chunk-rtvgmg2j.js} +48 -62
- package/dist/cli/{chunk-ckrcm08h.js.map → chunk-rtvgmg2j.js.map} +4 -5
- package/dist/cli/{chunk-297ajdcv.js → chunk-t2h8pwy1.js} +6 -6
- package/dist/cli/{chunk-297ajdcv.js.map → chunk-t2h8pwy1.js.map} +3 -3
- package/dist/cli/{chunk-gxtg6ed2.js → chunk-x60e15st.js} +21 -21
- package/dist/cli/{chunk-gxtg6ed2.js.map → chunk-x60e15st.js.map} +3 -3
- package/dist/cli/{chunk-58bt3hag.js → chunk-x7bh6d9j.js} +4 -4
- package/dist/cli/{chunk-hvcxng5f.js → chunk-ydqzkhjn.js} +6 -6
- package/dist/cli/{chunk-kdpzw38a.js → chunk-yg8ckc3g.js} +95 -7
- package/dist/cli/chunk-yg8ckc3g.js.map +11 -0
- package/dist/cli/{chunk-0pmb4tr4.js → chunk-zxd5jrgx.js} +1205 -222
- package/dist/cli/chunk-zxd5jrgx.js.map +44 -0
- package/dist/cli/index.js +78 -42
- package/dist/cli/index.js.map +7 -6
- package/dist/types/ai/changelog-components.d.ts +18 -0
- package/dist/types/ai/changelog-markdown.d.ts +12 -0
- package/dist/types/ai/openapi-components.d.ts +7 -7
- package/dist/types/ai/operation-details.d.ts +39 -0
- package/dist/types/ai/relative-links.d.ts +3 -1
- package/dist/types/ai/serializers.d.ts +6 -4
- package/dist/types/analytics/head.d.ts +4 -2
- package/dist/types/analytics/script.d.ts +8 -2
- package/dist/types/components/content/youtube.d.ts +20 -0
- package/dist/types/components/layout/nav-utils.d.ts +8 -0
- package/dist/types/components/openapi/example-panels.d.ts +33 -0
- package/dist/types/components/openapi/helpers.d.ts +53 -11
- package/dist/types/components/openapi/snippets.d.ts +7 -1
- package/dist/types/core/alert-diagnostics.d.ts +10 -0
- package/dist/types/core/builtin-tags.d.ts +16 -0
- package/dist/types/core/changelog-list.d.ts +48 -0
- package/dist/types/core/closest-match.d.ts +6 -0
- package/dist/types/core/code-fence-diagnostics.d.ts +18 -0
- package/dist/types/core/code-fences.d.ts +8 -1
- package/dist/types/core/config-input.d.ts +38 -6
- package/dist/types/core/content-assets.d.ts +16 -18
- package/dist/types/core/data.d.ts +6 -2
- package/dist/types/core/diagnostics.d.ts +14 -0
- package/dist/types/core/directive-diagnostics.d.ts +22 -8
- package/dist/types/core/former-routes.d.ts +14 -0
- package/dist/types/core/github.d.ts +5 -4
- package/dist/types/core/heading-markers.d.ts +65 -2
- package/dist/types/core/hidden-pages.d.ts +3 -0
- package/dist/types/core/includes.d.ts +23 -0
- package/dist/types/core/last-modified.d.ts +18 -6
- package/dist/types/core/links.d.ts +42 -2
- package/dist/types/core/load-module.d.ts +19 -4
- package/dist/types/core/manifest.d.ts +14 -1
- package/dist/types/core/markdown-mirrors.d.ts +22 -0
- package/dist/types/core/mcp-clients.d.ts +47 -0
- package/dist/types/core/mdx-elements.d.ts +32 -0
- package/dist/types/core/mdx-syntax.d.ts +100 -0
- package/dist/types/core/meta-diagnostics.d.ts +7 -0
- package/dist/types/core/meta.d.ts +32 -5
- package/dist/types/core/nav-diagnostics.d.ts +16 -2
- package/dist/types/core/navigation.d.ts +13 -0
- package/dist/types/core/ordering-prefix.d.ts +6 -0
- package/dist/types/core/pinned-ids.d.ts +23 -0
- package/dist/types/core/project-graph.d.ts +9 -1
- package/dist/types/core/redirect-patterns.d.ts +18 -0
- package/dist/types/core/relative-files.d.ts +31 -0
- package/dist/types/core/schema.d.ts +322 -11
- package/dist/types/core/sources/normalize.d.ts +101 -9
- package/dist/types/core/sources/types.d.ts +16 -0
- package/dist/types/core/static-files.d.ts +10 -0
- package/dist/types/core/static-host.d.ts +42 -0
- package/dist/types/core/svg-images.d.ts +26 -0
- package/dist/types/core/syntax-diagnostics.d.ts +14 -0
- package/dist/types/core/types.d.ts +42 -1
- package/dist/types/deploy/generated-files.d.ts +41 -0
- package/dist/types/deploy/redirects.d.ts +21 -7
- package/dist/types/markdown/code-title.d.ts +9 -5
- package/dist/types/markdown/directives.d.ts +8 -0
- package/dist/types/markdown/fence-language.d.ts +51 -0
- package/dist/types/markdown/fence-meta.d.ts +5 -0
- package/dist/types/markdown/github-alerts.d.ts +35 -0
- package/dist/types/openapi/asyncapi.d.ts +6 -5
- package/dist/types/openapi/checks.d.ts +10 -5
- package/dist/types/openapi/model.d.ts +55 -8
- package/dist/types/openapi/parse.d.ts +4 -1
- package/dist/types/ratelimit/index.d.ts +2 -0
- package/dist/types/ratelimit/memory.d.ts +1 -1
- package/dist/types/ratelimit/schema.d.ts +40 -0
- package/dist/types/ratelimit/unkey.d.ts +48 -0
- package/dist/types/sources/filesystem.d.ts +14 -4
- package/dist/types/sources/mdx-remote.d.ts +6 -3
- package/dist/types/sources/registry.d.ts +3 -3
- package/dist/types/theme/color.d.ts +33 -0
- package/dist/types/theme/palette.d.ts +122 -0
- package/docs/01-quickstart.mdx +1 -1
- package/docs/02-deployment.mdx +24 -8
- package/docs/04-migrating.mdx +16 -4
- package/docs/advanced/changelog.mdx +27 -1
- package/docs/advanced/skills.mdx +1 -1
- package/docs/cli/audit.mdx +1 -1
- package/docs/cli/doctor.mdx +2 -2
- package/docs/cli/evals.mdx +1 -1
- package/docs/cli/index.mdx +4 -2
- package/docs/cli/validate.mdx +10 -7
- package/docs/configuration/analytics.mdx +2 -0
- package/docs/configuration/customization.mdx +3 -1
- package/docs/configuration/index.mdx +7 -6
- package/docs/configuration/rate-limiting.mdx +20 -1
- package/docs/configuration/theming.mdx +5 -1
- package/docs/content/components.mdx +26 -6
- package/docs/content/frontmatter.mdx +1 -1
- package/docs/content/i18n.mdx +1 -1
- package/docs/content/includes.mdx +6 -2
- package/docs/content/index.mdx +11 -1
- package/docs/content/islands.mdx +2 -0
- package/docs/content/meta.mdx +9 -3
- package/docs/content/navigation.mdx +14 -6
- package/docs/content/sources/obsidian.mdx +1 -1
- package/docs/content/sources/remote-mdx.mdx +3 -1
- package/docs/content/syntax.mdx +76 -8
- package/docs/content/variables.mdx +3 -1
- package/docs/discoverability/agent-discovery.mdx +1 -1
- package/docs/discoverability/json-api.mdx +1 -1
- package/docs/discoverability/llms-txt.mdx +1 -1
- package/docs/discoverability/markdown.mdx +2 -2
- package/docs/discoverability/mcp.mdx +40 -8
- package/docs/discoverability/open-graph.mdx +1 -1
- package/docs/discoverability/sitemap-and-robots.mdx +1 -1
- package/docs/references/graphql.mdx +2 -0
- package/docs/references/openapi.mdx +45 -7
- package/package.json +4 -4
- package/skills/blume/SKILL.md +2 -2
- package/skills/blume-migrate/SKILL.md +51 -29
- package/skills/blume-migrate/references/docsify.md +262 -0
- package/skills/blume-migrate/references/docus.md +298 -0
- package/skills/blume-migrate/references/docusaurus.md +5 -5
- package/skills/blume-migrate/references/fern.md +327 -0
- package/skills/blume-migrate/references/fumadocs.md +1 -1
- package/skills/blume-migrate/references/gitbook.md +267 -0
- package/skills/blume-migrate/references/github-wiki.md +259 -0
- package/skills/blume-migrate/references/jekyll.md +253 -0
- package/skills/blume-migrate/references/mdbook.md +256 -0
- package/skills/blume-migrate/references/mintlify.md +5 -5
- package/skills/blume-migrate/references/mkdocs.md +236 -0
- package/skills/blume-migrate/references/monorepo.md +20 -8
- package/skills/blume-migrate/references/nextra.md +5 -5
- package/skills/blume-migrate/references/readme.md +257 -0
- package/skills/blume-migrate/references/redocly.md +198 -0
- package/skills/blume-migrate/references/starlight.md +3 -3
- package/skills/blume-migrate/references/vitepress.md +204 -0
- package/skills/blume-migrate/references/vuepress.md +271 -0
- package/skills/blume-migrate/scripts/docsify-codemod.mjs +2387 -0
- package/skills/blume-migrate/scripts/docus-codemod.mjs +2542 -0
- package/skills/blume-migrate/scripts/fern-codemod.mjs +2633 -0
- package/skills/blume-migrate/scripts/github-wiki-codemod.mjs +2808 -0
- package/skills/blume-migrate/scripts/include-excerpts.mjs +649 -0
- package/skills/blume-migrate/scripts/jekyll-codemod.mjs +3649 -0
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +17 -13
- package/skills/blume-migrate/scripts/mkdocs-codemod.mjs +2526 -0
- package/skills/blume-migrate/scripts/operation-routes.mjs +508 -0
- package/skills/blume-migrate/scripts/pin-heading-ids.mjs +1049 -0
- package/skills/blume-migrate/scripts/readme-codemod.mjs +4139 -0
- package/skills/blume-migrate/scripts/vitepress-codemod.mjs +1511 -0
- package/src/ai/changelog-components.ts +24 -0
- package/src/ai/changelog-markdown.ts +45 -41
- package/src/ai/component-markdown.ts +22 -9
- package/src/ai/llms.ts +36 -5
- package/src/ai/markdown.ts +2 -2
- package/src/ai/openapi-components.ts +25 -9
- package/src/ai/operation-details.ts +208 -0
- package/src/ai/relative-links.ts +48 -8
- package/src/ai/serializers.ts +7 -6
- package/src/ai/site-skill.ts +6 -2
- package/src/analytics/head.ts +11 -5
- package/src/analytics/script.ts +13 -3
- package/src/astro/generate.ts +47 -11
- package/src/astro/index.ts +1 -0
- package/src/astro/integration.ts +27 -1
- package/src/astro/mdx-source-errors.ts +46 -0
- package/src/astro/templates.ts +93 -189
- package/src/audit/checks/redirects.ts +5 -1
- package/src/audit/redirects.ts +36 -19
- package/src/audit/report.ts +22 -9
- package/src/audit/run.ts +12 -28
- package/src/audit/terms.ts +23 -0
- package/src/audit/url.ts +2 -2
- package/src/cli/build-failure.ts +256 -7
- package/src/cli/command-meta.ts +1 -1
- package/src/cli/commands/audit.ts +1 -1
- package/src/cli/commands/build.ts +12 -3
- package/src/cli/commands/check.ts +13 -2
- package/src/cli/commands/dev.ts +1 -1
- package/src/cli/commands/doctor.ts +4 -2
- package/src/cli/commands/init.ts +3 -3
- package/src/cli/commands/preview.ts +17 -1
- package/src/cli/commands/validate.ts +22 -10
- package/src/cli/prepare.ts +1 -1
- package/src/cli/preview-pages.ts +161 -0
- package/src/cli/required-secrets.ts +0 -1
- package/src/cli/unknown-flags.ts +1 -42
- package/src/components/code-copy.ts +51 -0
- package/src/components/code-language.ts +75 -0
- package/src/components/content/AccordionItem.astro +16 -1
- package/src/components/content/Callout.astro +11 -1
- package/src/components/content/Changelog.astro +189 -0
- package/src/components/content/CodeBlock.astro +8 -11
- package/src/components/content/Tabs.astro +16 -2
- package/src/components/content/YouTube.astro +6 -4
- package/src/components/content/code-block.ts +33 -0
- package/src/components/content/content-strings.ts +5 -1
- package/src/components/content/inline-markdown.ts +35 -8
- package/src/components/content/youtube.ts +49 -7
- package/src/components/layout/Analytics.astro +5 -1
- package/src/components/layout/NavTree.astro +8 -3
- package/src/components/layout/PageActions.astro +81 -23
- package/src/components/layout/RootLayout.astro +35 -32
- package/src/components/layout/SiteFooter.astro +31 -8
- package/src/components/layout/nav-utils.ts +14 -0
- package/src/components/layout/search/pagefind.ts +2 -1
- package/src/components/openapi/Operation.astro +4 -0
- package/src/components/openapi/PanelTabs.astro +9 -3
- package/src/components/openapi/RequestBody.astro +42 -8
- package/src/components/openapi/RequestPanel.astro +34 -53
- package/src/components/openapi/example-panels.ts +110 -0
- package/src/components/openapi/helpers.ts +195 -20
- package/src/components/openapi/operation-model.ts +63 -26
- package/src/components/openapi/request.ts +13 -0
- package/src/components/openapi/snippets.ts +14 -2
- package/src/core/alert-diagnostics.ts +89 -0
- package/src/core/builtin-tags.ts +76 -0
- package/src/core/changelog-list.ts +87 -0
- package/src/core/closest-match.ts +41 -0
- package/src/core/code-fence-diagnostics.ts +267 -0
- package/src/core/code-fences.ts +43 -7
- package/src/core/component-diagnostics.ts +65 -12
- package/src/core/config-input.ts +39 -5
- package/src/core/config.ts +46 -1
- package/src/core/content-assets.ts +64 -144
- package/src/core/data.ts +10 -3
- package/src/core/diagnostics.ts +36 -3
- package/src/core/directive-diagnostics.ts +265 -47
- package/src/core/former-routes.ts +46 -0
- package/src/core/git-ignored.ts +53 -0
- package/src/core/github.ts +5 -4
- package/src/core/heading-markers.ts +156 -2
- package/src/core/hidden-pages.ts +64 -0
- package/src/core/includes.ts +181 -41
- package/src/core/last-modified.ts +47 -10
- package/src/core/links.ts +438 -83
- package/src/core/load-module.ts +98 -9
- package/src/core/manifest.ts +12 -9
- package/src/core/markdown-mirrors.ts +52 -0
- package/src/core/mcp-clients.ts +87 -0
- package/src/core/mdx-elements.ts +153 -0
- package/src/core/mdx-syntax.ts +377 -0
- package/src/core/meta-diagnostics.ts +134 -0
- package/src/core/meta.ts +154 -55
- package/src/core/nav-diagnostics.ts +41 -4
- package/src/core/navigation.ts +70 -10
- package/src/core/ordering-prefix.ts +22 -2
- package/src/core/pinned-ids.ts +141 -0
- package/src/core/project-graph.ts +221 -29
- package/src/core/redirect-patterns.ts +41 -0
- package/src/core/relative-files.ts +145 -0
- package/src/core/schema.ts +110 -6
- package/src/core/sources/mdx-remote.ts +75 -14
- package/src/core/sources/normalize.ts +885 -179
- package/src/core/sources/notion.ts +5 -4
- package/src/core/sources/obsidian.ts +2 -5
- package/src/core/sources/types.ts +17 -0
- package/src/core/static-files.ts +40 -0
- package/src/core/static-host.ts +125 -0
- package/src/core/svg-images.ts +98 -0
- package/src/core/syntax-diagnostics.ts +491 -0
- package/src/core/types.ts +43 -1
- package/src/deploy/artifacts.ts +2 -28
- package/src/deploy/generated-files.ts +128 -0
- package/src/deploy/platforms/vercel.ts +25 -1
- package/src/deploy/redirects.ts +43 -16
- package/src/deploy/sitemap.ts +2 -1
- package/src/markdown/base-links.ts +87 -6
- package/src/markdown/code-title.ts +29 -13
- package/src/markdown/content-assets.ts +210 -0
- package/src/markdown/directives.ts +69 -5
- package/src/markdown/fence-language.ts +106 -0
- package/src/markdown/fence-meta.ts +42 -0
- package/src/markdown/github-alerts.ts +172 -0
- package/src/markdown/heading-anchors.ts +265 -56
- package/src/markdown/include.ts +30 -3
- package/src/markdown/index.ts +145 -40
- package/src/markdown/prompt-text.ts +95 -0
- package/src/markdown/relative-links.ts +37 -2
- package/src/markdown/route-snapshot.ts +22 -12
- package/src/markdown/svg-fallback.ts +51 -0
- package/src/markdown/title-heading.ts +134 -0
- package/src/migrate/migrate.ts +127 -2
- package/src/og/card.ts +14 -4
- package/src/openapi/asyncapi.ts +14 -6
- package/src/openapi/checks.ts +160 -15
- package/src/openapi/model.ts +172 -33
- package/src/openapi/parse.ts +13 -4
- package/src/openapi/render-mdx.ts +55 -9
- package/src/openapi/source.ts +87 -6
- package/src/ratelimit/index.ts +2 -0
- package/src/ratelimit/memory.ts +1 -1
- package/src/ratelimit/runtime.ts +81 -0
- package/src/ratelimit/schema.ts +2 -0
- package/src/ratelimit/unkey.ts +61 -0
- package/src/registry/eject.ts +0 -1
- package/src/registry/registry.ts +1 -1
- package/src/search/documents.ts +10 -2
- package/src/sources/filesystem.ts +28 -3
- package/src/sources/mdx-remote.ts +7 -15
- package/src/theme/color.ts +14 -0
- package/src/theme/entry.ts +22 -1
- package/src/theme/palette.ts +74 -1
- package/dist/cli/chunk-0pmb4tr4.js.map +0 -35
- package/dist/cli/chunk-0w6hs479.js.map +0 -10
- package/dist/cli/chunk-150jk7km.js +0 -52
- package/dist/cli/chunk-150jk7km.js.map +0 -10
- package/dist/cli/chunk-36bxs9c7.js.map +0 -10
- package/dist/cli/chunk-53jqw8z0.js +0 -89
- package/dist/cli/chunk-53jqw8z0.js.map +0 -10
- package/dist/cli/chunk-60hz265r.js.map +0 -10
- package/dist/cli/chunk-desvm72z.js.map +0 -14
- package/dist/cli/chunk-dpy8qdjf.js.map +0 -17
- package/dist/cli/chunk-es8h0v3j.js +0 -441
- package/dist/cli/chunk-es8h0v3j.js.map +0 -11
- package/dist/cli/chunk-kdpzw38a.js.map +0 -11
- package/dist/cli/chunk-nbyvgnnm.js.map +0 -36
- package/dist/cli/chunk-s0bdnc7v.js.map +0 -10
- package/dist/cli/chunk-twy7psdz.js.map +0 -10
- package/dist/cli/chunk-ydp3065p.js +0 -64
- package/dist/cli/chunk-ydp3065p.js.map +0 -10
- /package/dist/cli/{chunk-y4msrwm9.js.map → chunk-080mfch6.js.map} +0 -0
- /package/dist/cli/{chunk-9qzgg6mj.js.map → chunk-34wap3ed.js.map} +0 -0
- /package/dist/cli/{chunk-1f882900.js.map → chunk-c5bjxq8v.js.map} +0 -0
- /package/dist/cli/{chunk-bxwhtvw8.js.map → chunk-f260jdrn.js.map} +0 -0
- /package/dist/cli/{chunk-74wfhv79.js.map → chunk-fnxgtjeq.js.map} +0 -0
- /package/dist/cli/{chunk-dhwtqnnd.js.map → chunk-gxhcf2hs.js.map} +0 -0
- /package/dist/cli/{chunk-tfycddbt.js.map → chunk-h0qwdbem.js.map} +0 -0
- /package/dist/cli/{chunk-j1x92mx9.js.map → chunk-j4nfgn2j.js.map} +0 -0
- /package/dist/cli/{chunk-ave1wcbr.js.map → chunk-qcyxkj44.js.map} +0 -0
- /package/dist/cli/{chunk-58bt3hag.js.map → chunk-x7bh6d9j.js.map} +0 -0
- /package/dist/cli/{chunk-hvcxng5f.js.map → chunk-ydqzkhjn.js.map} +0 -0
package/src/core/schema.ts
CHANGED
|
@@ -43,6 +43,7 @@ import { isExternalUrl, normalizeBasePath } from "./base-path.ts";
|
|
|
43
43
|
import { FOOTER_SOCIALS } from "./footer.ts";
|
|
44
44
|
import { PUBLIC_HOST_URL } from "./github.ts";
|
|
45
45
|
import { uiLocaleOverridesSchema } from "./i18n-ui.ts";
|
|
46
|
+
import { isBuiltInMcpClient, mcpClients } from "./mcp-clients.ts";
|
|
46
47
|
import { openInChatProviders } from "./open-in-chat.ts";
|
|
47
48
|
import { PAGE_MODES } from "./page-modes.ts";
|
|
48
49
|
import { redirectPatternError } from "./redirect-patterns.ts";
|
|
@@ -305,11 +306,24 @@ const pageMetaBaseSchema = z.strictObject({
|
|
|
305
306
|
type: z.string().optional(),
|
|
306
307
|
});
|
|
307
308
|
|
|
308
|
-
export const pageMetaSchema = pageMetaBaseSchema;
|
|
309
|
-
|
|
310
309
|
export type PageMeta = z.infer<typeof pageMetaBaseSchema>;
|
|
311
310
|
export type PageMetaInput = z.input<typeof pageMetaBaseSchema>;
|
|
312
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Fold the top-level `hidden`/`noindex` shorthands into the nested fields
|
|
314
|
+
* every consumer reads (`sidebar.hidden`, `seo.noindex`). It runs inside both
|
|
315
|
+
* page schemas, so the scan's `PageMeta` (the sitemap, llms.txt, search) and
|
|
316
|
+
* the content collections' `entry.data` (the page's robots tag) can't
|
|
317
|
+
* disagree about a page that uses the shorthand.
|
|
318
|
+
*/
|
|
319
|
+
const foldShorthands = <Meta extends PageMeta>(meta: Meta): Meta => ({
|
|
320
|
+
...meta,
|
|
321
|
+
seo: { ...meta.seo, noindex: meta.seo.noindex || meta.noindex },
|
|
322
|
+
sidebar: { ...meta.sidebar, hidden: meta.sidebar.hidden || meta.hidden },
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
export const pageMetaSchema = pageMetaBaseSchema.transform(foldShorthands);
|
|
326
|
+
|
|
313
327
|
/** The fully-defaulted front matter of a page that declares nothing. */
|
|
314
328
|
const EMPTY_PAGE_META: PageMeta = pageMetaBaseSchema.parse({});
|
|
315
329
|
|
|
@@ -326,11 +340,12 @@ const EMPTY_PAGE_META: PageMeta = pageMetaBaseSchema.parse({});
|
|
|
326
340
|
*/
|
|
327
341
|
export const pageCollectionSchema = pageMetaBaseSchema
|
|
328
342
|
.loose()
|
|
343
|
+
.transform(foldShorthands)
|
|
329
344
|
// oxlint-disable-next-line promise/prefer-await-to-then -- zod's catch, not a promise
|
|
330
345
|
.catch(() => EMPTY_PAGE_META);
|
|
331
346
|
|
|
332
347
|
/** Built-in page frontmatter keys; custom keys must never redeclare one. */
|
|
333
|
-
const BUILT_IN_PAGE_META_KEYS = new Set<string>(
|
|
348
|
+
export const BUILT_IN_PAGE_META_KEYS: ReadonlySet<string> = new Set<string>(
|
|
334
349
|
pageMetaBaseSchema.keyof().options
|
|
335
350
|
);
|
|
336
351
|
|
|
@@ -473,10 +488,13 @@ const apiConfigSchema = z.strictObject({
|
|
|
473
488
|
});
|
|
474
489
|
|
|
475
490
|
/**
|
|
476
|
-
* The site footer: a row of links, and social profile
|
|
477
|
-
* has no footer (a `components.ts` `Footer` still
|
|
491
|
+
* The site footer: a copyright line, a row of links, and social profile
|
|
492
|
+
* icons. Unset, the site has no footer (a `components.ts` `Footer` still
|
|
493
|
+
* renders).
|
|
478
494
|
*/
|
|
479
495
|
const footerConfigSchema = z.strictObject({
|
|
496
|
+
/** A line of plain text between the links and the icons (`© 2026 Acme, Inc.`). */
|
|
497
|
+
copyright: localizableLabelSchema.optional(),
|
|
480
498
|
/** Links in one row, in the order written. */
|
|
481
499
|
links: z
|
|
482
500
|
.array(z.strictObject({ href: z.string(), label: localizableLabelSchema }))
|
|
@@ -877,7 +895,91 @@ const publicJwkSchema = z
|
|
|
877
895
|
}
|
|
878
896
|
});
|
|
879
897
|
|
|
898
|
+
// The label is the row button's only accessible name (its icon is
|
|
899
|
+
// decorative), so unlike a header link's it can't be blank in any locale.
|
|
900
|
+
const mcpClientLabelSchema = z.union(
|
|
901
|
+
[
|
|
902
|
+
z.string().trim().min(1),
|
|
903
|
+
z
|
|
904
|
+
.record(z.string(), z.string().trim().min(1))
|
|
905
|
+
.refine((value) => Object.keys(value).length > 0, {
|
|
906
|
+
message: "Provide at least one locale's label.",
|
|
907
|
+
}),
|
|
908
|
+
],
|
|
909
|
+
{ error: "Expected a label, or a map of locale code to label" }
|
|
910
|
+
);
|
|
911
|
+
|
|
912
|
+
// A "Connect to MCP" row for a client Blume doesn't ship: its `command` is
|
|
913
|
+
// copied with `{name}` and `{url}` filled in.
|
|
914
|
+
const mcpCustomClientSchema = z.strictObject({
|
|
915
|
+
command: z.string().trim().min(1),
|
|
916
|
+
icon: iconName.optional(),
|
|
917
|
+
label: mcpClientLabelSchema,
|
|
918
|
+
});
|
|
919
|
+
|
|
920
|
+
const ACCEPTED_MCP_CLIENTS = `${mcpClients.map((key) => `"${key}"`).join(", ")}, or a custom client { label, command, icon? }`;
|
|
921
|
+
|
|
922
|
+
/** A union's issue: every member failed, each with issues of its own. */
|
|
923
|
+
const isUnionIssue = (
|
|
924
|
+
issue: z.core.$ZodIssue
|
|
925
|
+
): issue is z.core.$ZodIssueInvalidUnion => issue.code === "invalid_union";
|
|
926
|
+
|
|
927
|
+
// A bad entry fails the list member of `clients`, which zod reports as a bare
|
|
928
|
+
// "Invalid input" on the whole list; that union issue is all this map sees.
|
|
929
|
+
// The entries' issues ride along in `errors`. The culprit is an entry that
|
|
930
|
+
// matches neither a built-in key nor a custom client, which fails as a union
|
|
931
|
+
// at its index (a blank field or an unknown key elsewhere doesn't fail the
|
|
932
|
+
// list on its own). Name that entry, and for a custom client its bad field.
|
|
933
|
+
const mcpClientsError = (issue: z.core.$ZodRawIssue): string => {
|
|
934
|
+
const entryIssue = (issue.code === "invalid_union" ? issue.errors : [])
|
|
935
|
+
.flat()
|
|
936
|
+
.filter(isUnionIssue)
|
|
937
|
+
.find((nested) => Number.isInteger(nested.path[0]));
|
|
938
|
+
if (!entryIssue) {
|
|
939
|
+
return `agents.mcp.clients takes true, false, or a list whose entries are each ${ACCEPTED_MCP_CLIENTS}.`;
|
|
940
|
+
}
|
|
941
|
+
const index = Number(entryIssue.path[0]);
|
|
942
|
+
const at = `agents.mcp.clients.${String(index)}`;
|
|
943
|
+
const entry = Array.isArray(issue.input) ? issue.input[index] : null;
|
|
944
|
+
if (isString(entry)) {
|
|
945
|
+
return `${at} is "${entry}", which isn't a built-in client. Use ${ACCEPTED_MCP_CLIENTS}.`;
|
|
946
|
+
}
|
|
947
|
+
const fieldIssue = entryIssue.errors
|
|
948
|
+
.flat()
|
|
949
|
+
.find((nested) => nested.path.length > 0);
|
|
950
|
+
return fieldIssue
|
|
951
|
+
? `${at}.${fieldIssue.path.map(String).join(".")}: ${fieldIssue.message}. A custom client is { label, command, icon? }.`
|
|
952
|
+
: `${at} isn't ${ACCEPTED_MCP_CLIENTS}.`;
|
|
953
|
+
};
|
|
954
|
+
|
|
880
955
|
const mcpConfigSchema = z.strictObject({
|
|
956
|
+
/**
|
|
957
|
+
* The "Connect to MCP" page action's clients. `true` (the default) lists
|
|
958
|
+
* every built-in client, `false` none (the menu keeps "Copy server URL"),
|
|
959
|
+
* and an array picks built-in clients by key and adds custom ones, in the
|
|
960
|
+
* given order. Normalized to the list so consumers read a plain array.
|
|
961
|
+
*/
|
|
962
|
+
clients: z
|
|
963
|
+
.union(
|
|
964
|
+
[
|
|
965
|
+
z.boolean(),
|
|
966
|
+
z.array(z.union([z.enum(mcpClients), mcpCustomClientSchema])).refine(
|
|
967
|
+
(value) => {
|
|
968
|
+
const keys = value.filter(isBuiltInMcpClient);
|
|
969
|
+
return new Set(keys).size === keys.length;
|
|
970
|
+
},
|
|
971
|
+
{ message: "agents.mcp.clients must not repeat a built-in client." }
|
|
972
|
+
),
|
|
973
|
+
],
|
|
974
|
+
{ error: mcpClientsError }
|
|
975
|
+
)
|
|
976
|
+
.default(true)
|
|
977
|
+
.transform((value) => {
|
|
978
|
+
if (isBoolean(value)) {
|
|
979
|
+
return value ? [...mcpClients] : [];
|
|
980
|
+
}
|
|
981
|
+
return value;
|
|
982
|
+
}),
|
|
881
983
|
enabled: z.boolean().default(false),
|
|
882
984
|
/** Optional system hint passed to connecting agents. */
|
|
883
985
|
instructions: z.string().optional(),
|
|
@@ -1168,6 +1270,8 @@ export type AssistantConfig = NonNullable<
|
|
|
1168
1270
|
>;
|
|
1169
1271
|
export { openInChatProviders } from "./open-in-chat.ts";
|
|
1170
1272
|
export type { OpenInChatProvider } from "./open-in-chat.ts";
|
|
1273
|
+
export { mcpClients } from "./mcp-clients.ts";
|
|
1274
|
+
export type { McpClient, McpCustomClient } from "./mcp-clients.ts";
|
|
1171
1275
|
|
|
1172
1276
|
// Reader-facing "Export" page action (PDF via print, EPUB via client-side
|
|
1173
1277
|
// generation). Off by default. Accepts a shorthand boolean to toggle both
|
|
@@ -2257,7 +2361,7 @@ export const blumeConfigSchema = z
|
|
|
2257
2361
|
ctx.addIssue({
|
|
2258
2362
|
code: z.ZodIssueCode.custom,
|
|
2259
2363
|
message:
|
|
2260
|
-
'rateLimit: cloudflare() counts with a Workers binding, so it needs `deployment: cloudflare()` from "blume/deploy". On another host, use upstash() or memory() from "blume/ratelimit".',
|
|
2364
|
+
'rateLimit: cloudflare() counts with a Workers binding, so it needs `deployment: cloudflare()` from "blume/deploy". On another host, use upstash(), unkey(), or memory() from "blume/ratelimit".',
|
|
2261
2365
|
path: ["rateLimit"],
|
|
2262
2366
|
});
|
|
2263
2367
|
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
pollingWatch,
|
|
10
10
|
snapshotCache,
|
|
11
11
|
} from "./cache.ts";
|
|
12
|
+
import { extractHeadings } from "./normalize.ts";
|
|
12
13
|
import { REMOTE_TIMEOUT_MS } from "./remote.ts";
|
|
13
14
|
import type {
|
|
14
15
|
ContentSource,
|
|
@@ -71,20 +72,29 @@ interface RemoteRef {
|
|
|
71
72
|
// arbitrary third party.
|
|
72
73
|
const GITHUB_HOSTS = new Set(["api.github.com", "raw.githubusercontent.com"]);
|
|
73
74
|
|
|
75
|
+
const isGithubUrl = (url: string): boolean =>
|
|
76
|
+
URL.canParse(url) && GITHUB_HOSTS.has(new URL(url).hostname);
|
|
77
|
+
|
|
74
78
|
const githubHeaders = (url: string): Record<string, string> => {
|
|
75
79
|
const token = process.env.GITHUB_TOKEN;
|
|
76
|
-
|
|
77
|
-
return {};
|
|
78
|
-
}
|
|
79
|
-
let host = "";
|
|
80
|
-
try {
|
|
81
|
-
host = new URL(url).hostname;
|
|
82
|
-
} catch {
|
|
83
|
-
return {};
|
|
84
|
-
}
|
|
85
|
-
return GITHUB_HOSTS.has(host) ? { authorization: `Bearer ${token}` } : {};
|
|
80
|
+
return token && isGithubUrl(url) ? { authorization: `Bearer ${token}` } : {};
|
|
86
81
|
};
|
|
87
82
|
|
|
83
|
+
// What GitHub answers a request for a private repository's file without a
|
|
84
|
+
// token (404, so it never confirms the repository exists), a token it rejects
|
|
85
|
+
// (401), and a client past the unauthenticated rate limit (403).
|
|
86
|
+
const TOKEN_STATUSES = new Set([401, 403, 404]);
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Why a request failed, naming GITHUB_TOKEN when it's unset and a token could
|
|
90
|
+
* fix the status. A public repository needs no token, so a raw `url` source
|
|
91
|
+
* declares none up front and only says so here, once a request fails.
|
|
92
|
+
*/
|
|
93
|
+
const statusReason = (url: string, status: number): string =>
|
|
94
|
+
TOKEN_STATUSES.has(status) && !process.env.GITHUB_TOKEN && isGithubUrl(url)
|
|
95
|
+
? `${url} -> ${status}; GITHUB_TOKEN is not set, which a private repository needs`
|
|
96
|
+
: `${url} -> ${status}`;
|
|
97
|
+
|
|
88
98
|
/**
|
|
89
99
|
* GET `url`'s body, giving up after {@link REMOTE_TIMEOUT_MS}: a server that
|
|
90
100
|
* accepts the connection and never finishes answering would otherwise hold the
|
|
@@ -103,7 +113,7 @@ const fetchText = async (
|
|
|
103
113
|
signal: AbortSignal.timeout(REMOTE_TIMEOUT_MS),
|
|
104
114
|
});
|
|
105
115
|
if (!res.ok) {
|
|
106
|
-
throw new Error(
|
|
116
|
+
throw new Error(statusReason(url, res.status));
|
|
107
117
|
}
|
|
108
118
|
return await res.text();
|
|
109
119
|
} catch (error) {
|
|
@@ -183,6 +193,50 @@ const enumerateGithub = async (
|
|
|
183
193
|
};
|
|
184
194
|
};
|
|
185
195
|
|
|
196
|
+
// A line an ATX heading opens (`# Title`); any other first line can only open
|
|
197
|
+
// a setext heading, underlined on the line after it.
|
|
198
|
+
const ATX_HEADING = /^ {0,3}#/u;
|
|
199
|
+
|
|
200
|
+
/** A remote page's body and front matter, as the source hands them on. */
|
|
201
|
+
interface RemotePage {
|
|
202
|
+
body: string;
|
|
203
|
+
// oxlint-disable-next-line anti-slop/no-unsafe-dictionary-type -- pre-validation front matter, as `SourceEntry.data` holds it
|
|
204
|
+
data: Record<string, unknown>;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Drop a remote page's leading h1 when it is the page's title. A file written
|
|
209
|
+
* to read on GitHub opens with `# Title`, and Blume renders the page's title
|
|
210
|
+
* as its h1, so the heading would show twice. A local page loses the
|
|
211
|
+
* duplicate when its author deletes the heading (the fix the multiple-h1
|
|
212
|
+
* audit names); a remote file can't be edited from the site that reads it.
|
|
213
|
+
* The heading's text becomes `title` when the front matter sets none, the
|
|
214
|
+
* title Blume derives from it anyway, and an h1 that differs from a front
|
|
215
|
+
* matter title stays. The heading's lines are blanked rather than removed, so
|
|
216
|
+
* every other line keeps the number it has in the remote file.
|
|
217
|
+
*/
|
|
218
|
+
const withoutTitleHeading = (page: RemotePage): RemotePage => {
|
|
219
|
+
const lines = page.body.split("\n");
|
|
220
|
+
const start = lines.findIndex((line) => line.trim() !== "");
|
|
221
|
+
const span = ATX_HEADING.test(lines[start] ?? "") ? 1 : 2;
|
|
222
|
+
const [heading] =
|
|
223
|
+
start === -1
|
|
224
|
+
? []
|
|
225
|
+
: extractHeadings(lines.slice(start, start + span).join("\n"));
|
|
226
|
+
if (
|
|
227
|
+
heading?.depth !== 1 ||
|
|
228
|
+
heading.text === "" ||
|
|
229
|
+
(page.data.title !== undefined && page.data.title !== heading.text)
|
|
230
|
+
) {
|
|
231
|
+
return page;
|
|
232
|
+
}
|
|
233
|
+
lines.fill("", start, start + span);
|
|
234
|
+
return {
|
|
235
|
+
body: lines.join("\n"),
|
|
236
|
+
data: { ...page.data, title: heading.text },
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
|
|
186
240
|
/**
|
|
187
241
|
* Remote Markdown/MDX content source. Fetches raw `.md`/`.mdx` over HTTP and
|
|
188
242
|
* passes the text straight through `normalizeEntry`. A snapshot under
|
|
@@ -229,12 +283,19 @@ export const mdxRemoteSource = (
|
|
|
229
283
|
const text = await fetchText(item.fetchUrl, doFetch);
|
|
230
284
|
const parsed = matter(text);
|
|
231
285
|
const format = item.ref.toLowerCase().endsWith(".mdx") ? "mdx" : "md";
|
|
232
|
-
|
|
233
|
-
body:
|
|
286
|
+
const page = withoutTitleHeading({
|
|
287
|
+
body: parsed.content,
|
|
234
288
|
data: parsed.data,
|
|
289
|
+
});
|
|
290
|
+
return {
|
|
291
|
+
body: { format, text: page.body },
|
|
292
|
+
data: page.data,
|
|
235
293
|
editUrl: item.editUrl,
|
|
236
294
|
hash: hashText(text),
|
|
237
|
-
|
|
295
|
+
// The body is the text's tail, after the front matter, which stays as
|
|
296
|
+
// written: a title taken from the dropped heading lives in `data`, as a
|
|
297
|
+
// title derived from a local page's heading does.
|
|
298
|
+
raw: text.slice(0, text.length - parsed.content.length) + page.body,
|
|
238
299
|
ref: item.ref,
|
|
239
300
|
};
|
|
240
301
|
};
|