blume 2.0.3 → 2.1.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 -0
- package/CHANGELOG.md +142 -0
- package/README.md +1 -1
- package/dist/cli/{chunk-5f86nr5m.js → chunk-073rdvgb.js} +21 -48
- package/dist/cli/{chunk-5f86nr5m.js.map → chunk-073rdvgb.js.map} +4 -5
- 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-150jk7km.js +52 -0
- package/dist/cli/chunk-150jk7km.js.map +10 -0
- package/dist/cli/{chunk-9t7a85s3.js → chunk-313vnn40.js} +30 -19
- package/dist/cli/chunk-313vnn40.js.map +10 -0
- package/dist/cli/{chunk-tkacnehg.js → chunk-3v3ffbrj.js} +2 -2
- package/dist/cli/{chunk-q58y5e6a.js → chunk-3x6x3pph.js} +46 -24
- package/dist/cli/chunk-3x6x3pph.js.map +10 -0
- package/dist/cli/{chunk-1d7ve1dm.js → chunk-42t4jxdx.js} +37 -5
- package/dist/cli/chunk-42t4jxdx.js.map +12 -0
- package/dist/cli/{chunk-8ktnccpt.js → chunk-54ztw1nj.js} +21 -2
- package/dist/cli/chunk-54ztw1nj.js.map +10 -0
- package/dist/cli/{chunk-hm3vjy5s.js → chunk-5vjtgs6e.js} +28 -10
- package/dist/cli/{chunk-hm3vjy5s.js.map → chunk-5vjtgs6e.js.map} +4 -4
- package/dist/cli/chunk-66w9j7p6.js +322 -0
- package/dist/cli/chunk-66w9j7p6.js.map +14 -0
- package/dist/cli/{chunk-2hsdwb9n.js → chunk-7ppf1rva.js} +34 -18
- package/dist/cli/chunk-7ppf1rva.js.map +10 -0
- package/dist/cli/{chunk-r9rcc4w7.js → chunk-8y2kmjv8.js} +7 -7
- package/dist/cli/{chunk-r20tn01b.js → chunk-c1y538kd.js} +8 -2
- package/dist/cli/{chunk-r20tn01b.js.map → chunk-c1y538kd.js.map} +3 -3
- package/dist/cli/{chunk-2eytanqx.js → chunk-c887fj0s.js} +2 -2
- package/dist/cli/{chunk-p3v96n38.js → chunk-cfyg47zg.js} +16 -6
- package/dist/cli/chunk-cfyg47zg.js.map +10 -0
- package/dist/cli/chunk-cm89scdv.js +443 -0
- package/dist/cli/chunk-cm89scdv.js.map +11 -0
- package/dist/cli/{chunk-akbpwfxc.js → chunk-dzwehpy7.js} +2 -2
- package/dist/cli/{chunk-wrr3j9w9.js → chunk-e6atmn4h.js} +299 -72
- package/dist/cli/chunk-e6atmn4h.js.map +36 -0
- package/dist/cli/{chunk-tzmab476.js → chunk-e8xw9qkh.js} +8 -6
- package/dist/cli/{chunk-tzmab476.js.map → chunk-e8xw9qkh.js.map} +3 -3
- package/dist/cli/{chunk-6dsbexzp.js → chunk-e9q7a2ak.js} +17 -15
- package/dist/cli/{chunk-6dsbexzp.js.map → chunk-e9q7a2ak.js.map} +2 -2
- package/dist/cli/{chunk-pv29h0wf.js → chunk-ehweg4fr.js} +5155 -1249
- package/dist/cli/chunk-ehweg4fr.js.map +218 -0
- package/dist/cli/{chunk-c8chx29p.js → chunk-ep6nd0rn.js} +390 -318
- package/dist/cli/chunk-ep6nd0rn.js.map +36 -0
- package/dist/cli/{chunk-p73c0m7w.js → chunk-fdrkhpjy.js} +18 -15
- package/dist/cli/{chunk-p73c0m7w.js.map → chunk-fdrkhpjy.js.map} +3 -3
- package/dist/cli/{chunk-2z928egk.js → chunk-ft9vfys6.js} +5 -5
- package/dist/cli/{chunk-5m5nmvyq.js → chunk-gb420vvz.js} +316 -79
- package/dist/cli/chunk-gb420vvz.js.map +17 -0
- package/dist/cli/{chunk-vg9r4eb9.js → chunk-hebn0tpx.js} +86 -13
- package/dist/cli/chunk-hebn0tpx.js.map +14 -0
- package/dist/cli/{chunk-35d4wj9f.js → chunk-htrwgabr.js} +41 -23
- package/dist/cli/chunk-htrwgabr.js.map +15 -0
- package/dist/cli/{chunk-g4hq16wv.js → chunk-hx3xqnk9.js} +16 -14
- package/dist/cli/{chunk-g4hq16wv.js.map → chunk-hx3xqnk9.js.map} +2 -2
- package/dist/cli/chunk-j134vrp2.js +65 -0
- package/dist/cli/chunk-j134vrp2.js.map +10 -0
- package/dist/cli/{chunk-a58773jm.js → chunk-kma9f6sf.js} +2 -2
- package/dist/cli/chunk-kwrg63tm.js +31 -0
- package/dist/cli/chunk-kwrg63tm.js.map +10 -0
- package/dist/cli/{chunk-ey84smr6.js → chunk-mrcccgnh.js} +6 -6
- package/dist/cli/{chunk-ey84smr6.js.map → chunk-mrcccgnh.js.map} +1 -1
- package/dist/cli/{chunk-yfyb25rh.js → chunk-n0v7m8ry.js} +24 -8
- package/dist/cli/chunk-n0v7m8ry.js.map +14 -0
- package/dist/cli/{chunk-j85vccga.js → chunk-ncj7w596.js} +576 -367
- package/dist/cli/chunk-ncj7w596.js.map +35 -0
- package/dist/cli/{chunk-5xvm6tfj.js → chunk-nq1d20w2.js} +17 -15
- package/dist/cli/{chunk-5xvm6tfj.js.map → chunk-nq1d20w2.js.map} +2 -2
- package/dist/cli/{chunk-pehfxfta.js → chunk-nrns10mj.js} +6 -98
- package/dist/cli/chunk-nrns10mj.js.map +10 -0
- package/dist/cli/{chunk-crgn1q09.js → chunk-sds923fa.js} +4 -4
- package/dist/cli/chunk-t2m5j4pr.js +104 -0
- package/dist/cli/chunk-t2m5j4pr.js.map +11 -0
- package/dist/cli/{chunk-acanzt5p.js → chunk-tdqhyxfz.js} +6 -6
- package/dist/cli/chunk-tphac74f.js +126 -0
- package/dist/cli/chunk-tphac74f.js.map +11 -0
- package/dist/cli/chunk-w1r4vase.js +18 -0
- package/dist/cli/chunk-w1r4vase.js.map +10 -0
- package/dist/cli/{chunk-3em5wd2y.js → chunk-zccbjcj0.js} +4 -3
- package/dist/cli/{chunk-3em5wd2y.js.map → chunk-zccbjcj0.js.map} +2 -2
- package/dist/cli/index.js +31 -20
- package/dist/cli/index.js.map +5 -5
- package/dist/types/ai/agent-surface.d.ts +8 -7
- package/dist/types/ai/ai-catalog.d.ts +7 -0
- package/dist/types/ai/ask-context.d.ts +26 -0
- package/dist/types/ai/ask.d.ts +271 -58
- package/dist/types/ai/component-markdown.d.ts +2 -0
- package/dist/types/ai/index.d.ts +2 -2
- package/dist/types/ai/openapi-components.d.ts +4 -1
- package/dist/types/ai/site-skill.d.ts +26 -0
- package/dist/types/ai/skills.d.ts +16 -0
- package/dist/types/astro/integration.d.ts +9 -0
- package/dist/types/astro/markdown-negotiation.d.ts +3 -0
- package/dist/types/astro/pages.d.ts +10 -0
- package/dist/types/captcha/hcaptcha.d.ts +27 -0
- package/dist/types/captcha/index.d.ts +28 -0
- package/dist/types/captcha/schema.d.ts +29 -0
- package/dist/types/captcha/turnstile.d.ts +28 -0
- package/dist/types/cli/init/scaffold.d.ts +1 -1
- package/dist/types/components/content/api-field.d.ts +62 -0
- package/dist/types/components/content/api-page.d.ts +100 -0
- package/dist/types/components/layout/nav-utils.d.ts +26 -0
- package/dist/types/components/openapi/code-samples.d.ts +29 -0
- package/dist/types/components/openapi/helpers.d.ts +158 -0
- package/dist/types/components/openapi/security.d.ts +95 -0
- package/dist/types/components/openapi/snippets.d.ts +60 -0
- package/dist/types/consent/ethyca.d.ts +48 -0
- package/dist/types/consent/index.d.ts +37 -0
- package/dist/types/consent/native.d.ts +28 -0
- package/dist/types/consent/osano.d.ts +42 -0
- package/dist/types/consent/schema.d.ts +110 -0
- package/dist/types/core/changelog-index.d.ts +8 -0
- package/dist/types/core/config-input.d.ts +217 -23
- package/dist/types/core/data.d.ts +53 -4
- package/dist/types/core/footer.d.ts +8 -0
- package/dist/types/core/i18n-ui.d.ts +88 -0
- package/dist/types/core/includes.d.ts +8 -2
- package/dist/types/core/links.d.ts +8 -0
- package/dist/types/core/localizable.d.ts +7 -0
- package/dist/types/core/page-modes.d.ts +29 -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 +152 -0
- package/dist/types/core/related.d.ts +40 -0
- package/dist/types/core/schema.d.ts +670 -56
- 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/normalize.d.ts +20 -1
- package/dist/types/core/sources/read.d.ts +5 -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 +18 -1
- package/dist/types/core/variables.d.ts +42 -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/node-headers.d.ts +13 -2
- package/dist/types/deploy/platforms/cloudflare.d.ts +15 -7
- package/dist/types/deploy/platforms/netlify.d.ts +7 -0
- 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 +26 -1
- package/dist/types/deploy/redirects.d.ts +55 -11
- package/dist/types/deploy/sitemap.d.ts +2 -1
- package/dist/types/deploy/vercel-negotiation.d.ts +51 -21
- package/dist/types/markdown/code-title.d.ts +17 -0
- package/dist/types/markdown/features.d.ts +3 -2
- package/dist/types/narration/build.d.ts +70 -0
- package/dist/types/narration/provider.d.ts +26 -0
- package/dist/types/narration/script.d.ts +154 -0
- 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 +27 -10
- package/dist/types/openapi/overlay.d.ts +54 -0
- package/dist/types/openapi/parse.d.ts +16 -0
- package/dist/types/openapi/references.d.ts +30 -4
- package/dist/types/ratelimit/cloudflare.d.ts +39 -0
- package/dist/types/ratelimit/index.d.ts +27 -0
- package/dist/types/ratelimit/memory.d.ts +36 -0
- package/dist/types/ratelimit/schema.d.ts +119 -0
- package/dist/types/ratelimit/upstash.d.ts +46 -0
- package/dist/types/ratelimit/wrangler.d.ts +23 -0
- package/dist/types/reference/asyncapi.d.ts +10 -10
- package/dist/types/reference/graphql.d.ts +89 -11
- package/dist/types/reference/index.d.ts +1 -1
- package/dist/types/reference/openapi.d.ts +33 -12
- package/dist/types/reference/options.d.ts +82 -6
- package/dist/types/reference/scalar.d.ts +13 -0
- package/dist/types/reference/schema.d.ts +144 -36
- 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/documents.d.ts +12 -1
- package/dist/types/search/orama-index.d.ts +13 -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/metatags.d.ts +20 -0
- package/dist/types/sources/contentful.d.ts +16 -0
- package/dist/types/sources/github-releases.d.ts +8 -1
- package/dist/types/sources/payload.d.ts +2 -0
- package/dist/types/sources/registry.d.ts +54 -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 +71 -17
- package/docs/03-upgrading.mdx +4 -4
- package/docs/04-migrating.mdx +1 -1
- package/docs/advanced/changelog.mdx +13 -2
- package/docs/advanced/skills.mdx +15 -1
- package/docs/cli/audit.mdx +51 -8
- package/docs/cli/doctor.mdx +5 -1
- package/docs/cli/evals.mdx +4 -4
- package/docs/cli/index.mdx +1 -0
- package/docs/cli/translate.mdx +1 -0
- package/docs/cli/validate.mdx +4 -3
- package/docs/configuration/analytics.mdx +3 -1
- package/docs/configuration/assistant.mdx +194 -38
- package/docs/configuration/consent.mdx +100 -0
- package/docs/configuration/customization.mdx +8 -6
- package/docs/configuration/export.mdx +5 -3
- package/docs/configuration/index.mdx +64 -5
- package/docs/configuration/meta.ts +3 -0
- package/docs/configuration/narration.mdx +119 -0
- package/docs/configuration/rate-limiting.mdx +90 -0
- package/docs/configuration/search.mdx +63 -12
- package/docs/configuration/theming.mdx +3 -1
- package/docs/content/components.mdx +108 -2
- package/docs/content/frontmatter.mdx +80 -2
- package/docs/content/i18n.mdx +39 -4
- package/docs/content/includes.mdx +16 -0
- package/docs/content/meta.mdx +1 -0
- package/docs/content/meta.ts +1 -0
- package/docs/content/navigation.mdx +32 -10
- package/docs/content/sources/contentful.mdx +35 -0
- package/docs/content/sources/custom.mdx +43 -0
- package/docs/content/sources/github-releases.mdx +39 -0
- package/docs/content/sources/index.mdx +91 -0
- package/docs/content/sources/meta.ts +16 -0
- package/docs/content/sources/notion.mdx +32 -0
- package/docs/content/sources/obsidian.mdx +37 -0
- package/docs/content/sources/payload.mdx +31 -0
- package/docs/content/sources/remote-mdx.mdx +44 -0
- package/docs/content/sources/sanity.mdx +29 -0
- package/docs/content/sources/strapi.mdx +32 -0
- package/docs/content/syntax.mdx +69 -4
- package/docs/content/variables.mdx +41 -0
- package/docs/discoverability/agent-discovery.mdx +29 -2
- package/docs/discoverability/index.mdx +2 -2
- package/docs/discoverability/json-api.mdx +2 -0
- package/docs/discoverability/llms-txt.mdx +2 -2
- package/docs/discoverability/markdown.mdx +3 -1
- package/docs/discoverability/mcp.mdx +4 -0
- package/docs/discoverability/metadata.mdx +17 -0
- package/docs/discoverability/sitemap-and-robots.mdx +1 -1
- package/docs/references/api-pages.mdx +74 -0
- package/docs/references/asyncapi.mdx +4 -2
- package/docs/references/graphql.mdx +14 -2
- package/docs/references/meta.ts +1 -1
- package/docs/references/openapi.mdx +148 -7
- package/docs/references/scalar.mdx +3 -1
- package/package.json +43 -8
- package/skills/blume/SKILL.md +3 -0
- package/skills/blume-migrate/SKILL.md +6 -6
- package/skills/blume-migrate/references/docusaurus.md +7 -7
- package/skills/blume-migrate/references/fumadocs.md +17 -13
- package/skills/blume-migrate/references/mintlify.md +37 -19
- package/skills/blume-migrate/references/nextra.md +10 -7
- package/skills/blume-migrate/references/starlight.md +11 -8
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +60 -14
- package/skills/blume-write-skill/SKILL.md +82 -0
- package/src/ai/agent-readability.ts +2 -1
- package/src/ai/agent-surface.ts +9 -7
- package/src/ai/ai-catalog.ts +6 -3
- package/src/ai/ask-context.ts +103 -20
- package/src/ai/ask-data.ts +6 -0
- package/src/ai/ask-limits.ts +13 -0
- package/src/ai/ask-tools.ts +142 -0
- package/src/ai/ask.ts +354 -76
- package/src/ai/changelog-markdown.ts +11 -6
- package/src/ai/component-markdown.ts +76 -1
- package/src/ai/cors.ts +14 -3
- package/src/ai/index.ts +12 -0
- package/src/ai/llms.ts +6 -2
- package/src/ai/markdown.ts +2 -1
- package/src/ai/mcp/data.ts +6 -0
- package/src/ai/mcp/query.ts +14 -6
- package/src/ai/openapi-components.ts +36 -6
- package/src/ai/relative-links.ts +4 -38
- package/src/ai/site-skill.ts +274 -0
- package/src/ai/skills.ts +35 -2
- package/src/ai/write-skill.ts +97 -0
- package/src/astro/generate.ts +210 -66
- package/src/astro/index.ts +1 -0
- package/src/astro/integration.ts +42 -4
- package/src/astro/markdown-negotiation.ts +3 -0
- package/src/astro/module-types.ts +9 -1
- package/src/astro/pages.ts +23 -0
- package/src/astro/templates.ts +406 -108
- package/src/astro/variables.ts +31 -0
- package/src/audit/catalog.ts +38 -3
- package/src/audit/checks/contrast.ts +183 -0
- package/src/audit/checks/i18n.ts +2 -3
- package/src/audit/checks/indexability.ts +2 -3
- package/src/audit/checks/links.ts +19 -13
- 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/checks/sitemap.ts +2 -3
- package/src/audit/redirects.ts +46 -15
- package/src/audit/run.ts +5 -0
- package/src/audit/types.ts +4 -1
- package/src/audit/url.ts +14 -5
- package/src/blume-modules.d.ts +12 -1
- package/src/captcha/client.ts +152 -0
- package/src/captcha/hcaptcha.ts +36 -0
- package/src/captcha/index.ts +28 -0
- package/src/captcha/schema.ts +32 -0
- package/src/captcha/turnstile.ts +38 -0
- package/src/captcha/verify.ts +71 -0
- package/src/cli/args.ts +51 -0
- package/src/cli/build-failure.ts +23 -0
- package/src/cli/command-meta.ts +5 -0
- package/src/cli/commands/audit.ts +10 -1
- package/src/cli/commands/dev.ts +18 -2
- package/src/cli/commands/doctor.ts +67 -28
- package/src/cli/commands/eval.ts +36 -4
- package/src/cli/commands/init.ts +6 -4
- package/src/cli/commands/skill.ts +96 -0
- package/src/cli/commands/validate.ts +10 -1
- package/src/cli/index.ts +5 -0
- package/src/cli/init/scaffold.ts +3 -3
- package/src/cli/prepare.ts +6 -3
- package/src/cli/required-secrets.ts +72 -30
- package/src/components/BlumePage.astro +2 -0
- package/src/components/content/ApiEndpoint.astro +18 -0
- package/src/components/content/ApiField.astro +79 -0
- package/src/components/content/ApiPlayground.astro +66 -0
- package/src/components/content/ApiRail.astro +19 -0
- package/src/components/content/Color.astro +1 -0
- package/src/components/content/FileTree.astro +1 -0
- package/src/components/content/GithubInfo.astro +1 -0
- package/src/components/content/Panel.astro +1 -0
- package/src/components/content/ParamField.astro +25 -0
- package/src/components/content/RequestExample.astro +17 -0
- package/src/components/content/ResponseExample.astro +17 -0
- package/src/components/content/ResponseField.astro +32 -0
- package/src/components/content/Step.astro +1 -0
- package/src/components/content/Tile.astro +1 -0
- package/src/components/content/Tooltip.astro +1 -0
- package/src/components/content/Tree.astro +1 -0
- package/src/components/content/TypeTable.astro +4 -1
- package/src/components/content/View.astro +21 -0
- package/src/components/content/ViewSwitcher.astro +168 -0
- package/src/components/content/api-field.ts +103 -0
- package/src/components/content/api-page.ts +248 -0
- package/src/components/content/mermaid-element.ts +15 -1
- package/src/components/content/view-switcher.ts +71 -0
- package/src/components/index.ts +2 -0
- package/src/components/islands/Assistant.astro +10 -1
- package/src/components/islands/assistant.tsx +104 -14
- package/src/components/islands/code-question.ts +62 -0
- package/src/components/islands/hooks.ts +136 -21
- package/src/components/islands/support-link.ts +68 -0
- package/src/components/layout/Analytics.astro +11 -2
- package/src/components/layout/Banner.astro +14 -10
- package/src/components/layout/Breadcrumbs.astro +6 -2
- package/src/components/layout/ConsentBanner.astro +62 -0
- package/src/components/layout/ConsentHead.astro +38 -0
- package/src/components/layout/Directory.astro +94 -0
- package/src/components/layout/DrawerSwitchers.astro +51 -0
- package/src/components/layout/Empty.astro +2 -2
- package/src/components/layout/Header.astro +122 -80
- package/src/components/layout/LanguageSwitcher.astro +48 -15
- package/src/components/layout/NarrationPlayer.astro +1085 -0
- package/src/components/layout/NavSelector.astro +33 -7
- package/src/components/layout/PageActions.astro +139 -24
- package/src/components/layout/PageFeedback.astro +54 -49
- package/src/components/layout/PageLayout.astro +71 -3
- package/src/components/layout/ReferenceLayout.astro +17 -6
- package/src/components/layout/RelatedPages.astro +42 -0
- package/src/components/layout/RootLayout.astro +318 -47
- package/src/components/layout/Search.astro +47 -19
- package/src/components/layout/SiteFooter.astro +124 -0
- package/src/components/layout/SiteMetatags.astro +16 -0
- package/src/components/layout/TableOfContents.astro +24 -17
- package/src/components/layout/consent/native.ts +79 -0
- package/src/components/layout/consent/types.ts +37 -0
- package/src/components/layout/footer-links.ts +53 -0
- package/src/components/layout/footer-socials.ts +87 -0
- package/src/components/layout/head-scripts.ts +6 -1
- package/src/components/layout/locale-redirect.ts +107 -0
- package/src/components/layout/nav-utils.ts +83 -0
- package/src/components/layout/page-feedback.ts +96 -0
- package/src/components/layout/search/algolia.ts +10 -1
- package/src/components/layout/search/analytics.ts +126 -0
- package/src/components/layout/search/endpoint.ts +48 -5
- package/src/components/layout/search/flexsearch.ts +17 -5
- package/src/components/layout/search/orama-cloud.ts +26 -14
- package/src/components/layout/search/pagefind.ts +114 -5
- package/src/components/layout/search/types.ts +32 -0
- package/src/components/layout/search/typesense.ts +19 -3
- 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 +184 -13
- package/src/components/openapi/ParametersTable.astro +8 -4
- package/src/components/openapi/Playground.astro +7 -1
- package/src/components/openapi/RequestBody.astro +24 -5
- package/src/components/openapi/RequestPanel.astro +59 -7
- package/src/components/openapi/Responses.astro +7 -4
- package/src/components/openapi/SchemaTable.astro +15 -3
- package/src/components/openapi/async-snippets.ts +65 -9
- package/src/components/openapi/async.ts +123 -29
- package/src/components/openapi/code-samples.ts +97 -0
- 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 +24 -5
- package/src/components/openapi/playground-schema.ts +1 -1
- package/src/components/openapi/schema-tree.ts +44 -14
- package/src/components/openapi/security.ts +16 -3
- package/src/components/openapi/snippets.ts +873 -10
- package/src/components/openapi/validate-json.ts +4 -3
- package/src/components/props.ts +6 -0
- package/src/consent/client.ts +95 -0
- package/src/consent/clients.ts +19 -0
- package/src/consent/ethyca.ts +71 -0
- package/src/consent/head.ts +24 -0
- package/src/consent/index.ts +37 -0
- package/src/consent/init.ts +29 -0
- package/src/consent/native.ts +36 -0
- package/src/consent/osano.ts +59 -0
- package/src/consent/schema.ts +30 -0
- package/src/core/builtin-tags.ts +5 -0
- package/src/core/changelog-index.ts +31 -1
- package/src/core/client-address.ts +19 -0
- package/src/core/component-diagnostics.ts +53 -0
- package/src/core/component-overrides.ts +32 -0
- package/src/core/config-input.ts +225 -23
- package/src/core/data.ts +46 -4
- package/src/core/diagnostics.ts +8 -2
- package/src/core/footer.ts +26 -0
- package/src/core/graph.ts +39 -36
- package/src/core/i18n-ui.ts +84 -2
- package/src/core/includes.ts +21 -4
- package/src/core/links.ts +63 -19
- package/src/core/localizable.ts +26 -0
- package/src/core/navigation.ts +43 -12
- package/src/core/page-modes.ts +56 -0
- package/src/core/probe.ts +26 -6
- package/src/core/project-graph.ts +163 -16
- package/src/core/redirect-patterns.ts +520 -0
- package/src/core/related.ts +131 -0
- package/src/core/schema.ts +339 -66
- 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/mdx-remote.ts +62 -10
- package/src/core/sources/normalize.ts +228 -41
- package/src/core/sources/notion.ts +7 -1
- package/src/core/sources/obsidian.ts +16 -3
- package/src/core/sources/payload.ts +38 -15
- package/src/core/sources/read.ts +8 -3
- 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 +19 -1
- package/src/core/ui-packs/ar.ts +44 -0
- package/src/core/ui-packs/bg.ts +46 -0
- package/src/core/ui-packs/bn.ts +44 -0
- package/src/core/ui-packs/ca.ts +47 -0
- package/src/core/ui-packs/cs.ts +45 -0
- package/src/core/ui-packs/da.ts +46 -0
- package/src/core/ui-packs/de.ts +47 -0
- package/src/core/ui-packs/el.ts +46 -0
- package/src/core/ui-packs/es.ts +47 -0
- package/src/core/ui-packs/fa.ts +46 -0
- package/src/core/ui-packs/fi.ts +46 -0
- package/src/core/ui-packs/fr.ts +47 -0
- package/src/core/ui-packs/he.ts +44 -0
- package/src/core/ui-packs/hi.ts +45 -0
- package/src/core/ui-packs/hr.ts +46 -0
- package/src/core/ui-packs/hu.ts +45 -0
- package/src/core/ui-packs/id.ts +46 -0
- package/src/core/ui-packs/it.ts +46 -0
- package/src/core/ui-packs/ja.ts +46 -0
- package/src/core/ui-packs/ko.ts +45 -0
- package/src/core/ui-packs/nl.ts +47 -0
- package/src/core/ui-packs/no.ts +45 -0
- package/src/core/ui-packs/pl.ts +46 -0
- package/src/core/ui-packs/pt-br.ts +47 -0
- package/src/core/ui-packs/pt.ts +46 -0
- package/src/core/ui-packs/ro.ts +46 -0
- package/src/core/ui-packs/ru.ts +46 -0
- package/src/core/ui-packs/sk.ts +45 -0
- package/src/core/ui-packs/sr.ts +46 -0
- package/src/core/ui-packs/sv.ts +45 -0
- package/src/core/ui-packs/th.ts +44 -0
- package/src/core/ui-packs/tr.ts +46 -0
- package/src/core/ui-packs/uk.ts +46 -0
- package/src/core/ui-packs/vi.ts +46 -0
- package/src/core/ui-packs/zh-tw.ts +44 -0
- package/src/core/ui-packs/zh.ts +44 -0
- package/src/core/variables.ts +103 -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 +79 -9
- package/src/deploy/cloudflare-negotiation.ts +35 -5
- package/src/deploy/headers.ts +2 -1
- package/src/deploy/node-headers.ts +63 -9
- package/src/deploy/platforms/cloudflare.ts +45 -9
- package/src/deploy/platforms/netlify.ts +35 -2
- package/src/deploy/platforms/node.ts +12 -2
- package/src/deploy/platforms/types.ts +21 -7
- package/src/deploy/platforms/vercel.ts +149 -17
- package/src/deploy/redirects.ts +151 -24
- package/src/deploy/rss.ts +3 -1
- package/src/deploy/sitemap.ts +39 -5
- package/src/deploy/vercel-negotiation.ts +326 -102
- 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/api-rail.ts +259 -0
- package/src/markdown/code-title.ts +35 -9
- package/src/markdown/features.ts +3 -2
- package/src/markdown/fence-meta.ts +2 -0
- package/src/markdown/include.ts +11 -1
- package/src/markdown/index.ts +28 -5
- package/src/markdown/math.ts +4 -4
- package/src/markdown/relative-links.ts +3 -2
- package/src/markdown/variables.ts +56 -0
- package/src/markdown/views.ts +82 -0
- package/src/narration/build.ts +412 -0
- package/src/narration/player.ts +249 -0
- package/src/narration/provider.ts +29 -0
- package/src/narration/script.ts +592 -0
- package/src/og/card.ts +7 -6
- 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 +72 -27
- package/src/openapi/overlay.ts +256 -0
- package/src/openapi/parse.ts +182 -4
- package/src/openapi/references.ts +64 -8
- package/src/openapi/render-mdx.ts +5 -1
- package/src/openapi/scalar.ts +40 -6
- package/src/openapi/source.ts +40 -15
- package/src/ratelimit/cloudflare.ts +54 -0
- package/src/ratelimit/index.ts +30 -0
- package/src/ratelimit/memory.ts +45 -0
- package/src/ratelimit/runtime.ts +247 -0
- package/src/ratelimit/schema.ts +28 -0
- package/src/ratelimit/upstash.ts +60 -0
- package/src/ratelimit/wrangler.ts +70 -0
- package/src/reference/asyncapi.ts +2 -2
- package/src/reference/graphql.ts +20 -3
- package/src/reference/index.ts +1 -0
- package/src/reference/openapi.ts +21 -7
- package/src/reference/options.ts +80 -8
- package/src/reference/scalar.ts +33 -8
- package/src/registry/eject.ts +23 -5
- package/src/registry/registry.ts +7 -0
- 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/documents.ts +26 -2
- package/src/search/orama-index.ts +191 -34
- package/src/search/pagefind-ranking.ts +39 -0
- package/src/search/source-pages.ts +29 -0
- package/src/search/sync/algolia.ts +111 -10
- package/src/search/sync/index.ts +52 -13
- package/src/search/sync/orama-cloud.ts +3 -0
- package/src/search/sync/typesense.ts +76 -26
- package/src/seo/metatags.ts +67 -0
- package/src/sources/contentful.ts +12 -0
- package/src/sources/github-releases.ts +7 -1
- package/src/sources/shared.ts +3 -0
- package/src/theme/chrome-icons.ts +1 -0
- package/src/theme/color.ts +500 -0
- package/src/theme/entry.ts +85 -6
- package/src/theme/palette.ts +121 -45
- package/src/translate/prompts.ts +1 -0
- package/src/translate/validate.ts +31 -3
- package/src/upgrade/upgrade.ts +4 -171
- package/dist/cli/chunk-1d7ve1dm.js.map +0 -12
- package/dist/cli/chunk-2hsdwb9n.js.map +0 -10
- package/dist/cli/chunk-35d4wj9f.js.map +0 -15
- package/dist/cli/chunk-364znk6q.js +0 -75
- package/dist/cli/chunk-364znk6q.js.map +0 -11
- package/dist/cli/chunk-5m5nmvyq.js.map +0 -13
- package/dist/cli/chunk-8ktnccpt.js.map +0 -10
- package/dist/cli/chunk-9t7a85s3.js.map +0 -10
- package/dist/cli/chunk-b07cmahc.js +0 -145
- package/dist/cli/chunk-b07cmahc.js.map +0 -11
- package/dist/cli/chunk-c8chx29p.js.map +0 -36
- package/dist/cli/chunk-e04dxsz1.js +0 -39
- package/dist/cli/chunk-e04dxsz1.js.map +0 -10
- package/dist/cli/chunk-j85vccga.js.map +0 -36
- package/dist/cli/chunk-p3v96n38.js.map +0 -10
- package/dist/cli/chunk-pehfxfta.js.map +0 -10
- package/dist/cli/chunk-pv29h0wf.js.map +0 -190
- package/dist/cli/chunk-q58y5e6a.js.map +0 -10
- package/dist/cli/chunk-vg9r4eb9.js.map +0 -14
- package/dist/cli/chunk-wrr3j9w9.js.map +0 -35
- package/dist/cli/chunk-yfyb25rh.js.map +0 -14
- package/docs/content/sources.mdx +0 -334
- /package/dist/cli/{chunk-tkacnehg.js.map → chunk-3v3ffbrj.js.map} +0 -0
- /package/dist/cli/{chunk-r9rcc4w7.js.map → chunk-8y2kmjv8.js.map} +0 -0
- /package/dist/cli/{chunk-2eytanqx.js.map → chunk-c887fj0s.js.map} +0 -0
- /package/dist/cli/{chunk-akbpwfxc.js.map → chunk-dzwehpy7.js.map} +0 -0
- /package/dist/cli/{chunk-2z928egk.js.map → chunk-ft9vfys6.js.map} +0 -0
- /package/dist/cli/{chunk-a58773jm.js.map → chunk-kma9f6sf.js.map} +0 -0
- /package/dist/cli/{chunk-crgn1q09.js.map → chunk-sds923fa.js.map} +0 -0
- /package/dist/cli/{chunk-acanzt5p.js.map → chunk-tdqhyxfz.js.map} +0 -0
package/src/cli/build-failure.ts
CHANGED
|
@@ -20,8 +20,31 @@ const buildErrorSchema = z.looseObject({
|
|
|
20
20
|
.optional(),
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* The diagnostic a `BlumeError` thrown inside the build carries, such as a
|
|
25
|
+
* failed hosted search sync in `astro:build:done`. The hook runs Blume's
|
|
26
|
+
* source rather than the CLI bundle, so its error is another copy of the class
|
|
27
|
+
* that the command's `instanceof BlumeError` doesn't recognize.
|
|
28
|
+
*/
|
|
29
|
+
const blumeErrorSchema = z.looseObject({
|
|
30
|
+
diagnostic: z.object({
|
|
31
|
+
code: z.string(),
|
|
32
|
+
column: z.number().optional(),
|
|
33
|
+
docsUrl: z.string().optional(),
|
|
34
|
+
file: z.string().optional(),
|
|
35
|
+
line: z.number().optional(),
|
|
36
|
+
message: z.string(),
|
|
37
|
+
severity: z.enum(["error", "info", "warning"]),
|
|
38
|
+
suggestion: z.string().optional(),
|
|
39
|
+
}),
|
|
40
|
+
});
|
|
41
|
+
|
|
23
42
|
/** One failure as a diagnostic at the file (and position) it names. */
|
|
24
43
|
const failureDiagnostic = (error: Error): Diagnostic => {
|
|
44
|
+
const raised = blumeErrorSchema.safeParse(error);
|
|
45
|
+
if (raised.success) {
|
|
46
|
+
return raised.data.diagnostic;
|
|
47
|
+
}
|
|
25
48
|
const parsed = buildErrorSchema.safeParse(error);
|
|
26
49
|
const { id, loc } = parsed.success ? parsed.data : {};
|
|
27
50
|
// A named error (`MDXError`, `CompilerError`) says which step failed.
|
package/src/cli/command-meta.ts
CHANGED
|
@@ -62,6 +62,11 @@ export const commandMeta = {
|
|
|
62
62
|
description: "Preview the last production build.",
|
|
63
63
|
name: "preview",
|
|
64
64
|
},
|
|
65
|
+
skill: {
|
|
66
|
+
description:
|
|
67
|
+
"Write the docs site's agent skill with a coding agent, in place of the generated one.",
|
|
68
|
+
name: "skill",
|
|
69
|
+
},
|
|
65
70
|
sync: {
|
|
66
71
|
description: "Re-fetch remote content sources and regenerate the runtime.",
|
|
67
72
|
name: "sync",
|
|
@@ -15,6 +15,7 @@ import { isHttpUrl } from "../../audit/url.ts";
|
|
|
15
15
|
import { BlumeError } from "../../core/diagnostics.ts";
|
|
16
16
|
import { scanProject } from "../../core/project-graph.ts";
|
|
17
17
|
import type { DiagnosticSeverity } from "../../core/types.ts";
|
|
18
|
+
import { parseIgnoreFlag } from "../args.ts";
|
|
18
19
|
import { commandMeta } from "../command-meta.ts";
|
|
19
20
|
import { reportInternalError } from "../internal-error.ts";
|
|
20
21
|
import { flushStdout, logger, reportDiagnostics } from "../log.ts";
|
|
@@ -103,6 +104,12 @@ export const auditCommand = defineCommand({
|
|
|
103
104
|
"Exit non-zero at this severity or above: error | warning | info. Defaults to error.",
|
|
104
105
|
type: "string",
|
|
105
106
|
},
|
|
107
|
+
ignore: {
|
|
108
|
+
description:
|
|
109
|
+
'With --external, skip outbound links whose URL matches this glob (e.g. "https://example.com/**"). Repeat it for more; internal links are always checked.',
|
|
110
|
+
type: "string",
|
|
111
|
+
valueHint: "glob",
|
|
112
|
+
},
|
|
106
113
|
json: {
|
|
107
114
|
description: "Emit the report as JSON on stdout (for CI/editors).",
|
|
108
115
|
type: "boolean",
|
|
@@ -134,7 +141,7 @@ export const auditCommand = defineCommand({
|
|
|
134
141
|
},
|
|
135
142
|
},
|
|
136
143
|
meta: commandMeta.audit,
|
|
137
|
-
async run({ args }) {
|
|
144
|
+
async run({ args, rawArgs }) {
|
|
138
145
|
if (args["list-checks"]) {
|
|
139
146
|
process.stdout.write(formatCatalog());
|
|
140
147
|
return;
|
|
@@ -172,6 +179,7 @@ export const auditCommand = defineCommand({
|
|
|
172
179
|
const only = splitTerms(args.only);
|
|
173
180
|
const skip = splitTerms(args.skip);
|
|
174
181
|
rejectUnknownTerms([...only, ...skip]);
|
|
182
|
+
const ignore = parseIgnoreFlag(rawArgs);
|
|
175
183
|
let result: AuditResult;
|
|
176
184
|
try {
|
|
177
185
|
// `scanProject`, not `prepareProject`: the audit reads the *existing*
|
|
@@ -180,6 +188,7 @@ export const auditCommand = defineCommand({
|
|
|
180
188
|
const project = await scanProject(root, { mode: "build" });
|
|
181
189
|
result = await runAudit({
|
|
182
190
|
external: args.external,
|
|
191
|
+
ignore,
|
|
183
192
|
only,
|
|
184
193
|
origin: args.url,
|
|
185
194
|
project,
|
package/src/cli/commands/dev.ts
CHANGED
|
@@ -11,7 +11,9 @@ import {
|
|
|
11
11
|
import { BlumeError } from "../../core/diagnostics.ts";
|
|
12
12
|
import { scanProject } from "../../core/project-graph.ts";
|
|
13
13
|
import { resolveRuntimeDir } from "../../core/project.ts";
|
|
14
|
+
import { referenceSpecFiles } from "../../openapi/references.ts";
|
|
14
15
|
import { parsePort } from "../args.ts";
|
|
16
|
+
import { astroBuildDiagnostics } from "../build-failure.ts";
|
|
15
17
|
import { commandMeta } from "../command-meta.ts";
|
|
16
18
|
import {
|
|
17
19
|
acquireDevLock,
|
|
@@ -140,7 +142,19 @@ export const devCommand = defineCommand({
|
|
|
140
142
|
server: { host: normalizeHost(args.host), open, port: listenPort },
|
|
141
143
|
});
|
|
142
144
|
|
|
143
|
-
let server
|
|
145
|
+
let server: Awaited<ReturnType<typeof createServer>>;
|
|
146
|
+
try {
|
|
147
|
+
server = await createServer(explicitPort, args.open ?? false);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
// Astro's first content sync rejects on a page it can't load (front
|
|
150
|
+
// matter that isn't valid YAML): report it at the file it names, as
|
|
151
|
+
// `blume build` does, not as an internal error blaming Blume.
|
|
152
|
+
if (error instanceof BlumeError || !(error instanceof Error)) {
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
reportDiagnostics(astroBuildDiagnostics(error), root);
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
144
158
|
|
|
145
159
|
// Vite bumps to the next free port when the default is taken, so record
|
|
146
160
|
// the port the server actually bound — the lock's URL is what a refused
|
|
@@ -229,7 +243,8 @@ export const devCommand = defineCommand({
|
|
|
229
243
|
|
|
230
244
|
// Content is watched per source (filesystem uses fs.watch; remote sources
|
|
231
245
|
// are frozen for the session). The remaining project inputs — user pages,
|
|
232
|
-
// config, theme,
|
|
246
|
+
// config, theme, component overrides, and the local specs and overlays API
|
|
247
|
+
// references read — are watched directly.
|
|
233
248
|
const dirTargets = [project.context.pagesRoot].filter(
|
|
234
249
|
(target) => target !== null
|
|
235
250
|
);
|
|
@@ -237,6 +252,7 @@ export const devCommand = defineCommand({
|
|
|
237
252
|
project.context.configFile,
|
|
238
253
|
project.context.themeFile,
|
|
239
254
|
project.context.componentsFile,
|
|
255
|
+
...referenceSpecFiles(project.config, root),
|
|
240
256
|
].filter((target) => target !== null);
|
|
241
257
|
|
|
242
258
|
// chokidar handles what raw fs.watch made us hand-roll: recursive
|
|
@@ -5,15 +5,20 @@ import { defineCommand } from "citty";
|
|
|
5
5
|
import { join } from "pathe";
|
|
6
6
|
import { satisfies } from "semver";
|
|
7
7
|
|
|
8
|
+
import { discoverExamples } from "../../astro/examples.ts";
|
|
8
9
|
import { discoverIslands } from "../../astro/islands.ts";
|
|
10
|
+
import { discoverPages, navTargetRoutes } from "../../astro/pages.ts";
|
|
9
11
|
import { missingDependencyDiagnostic } from "../../astro/runtime-deps.ts";
|
|
12
|
+
import { missingExampleDiagnostics } from "../../core/component-diagnostics.ts";
|
|
10
13
|
import {
|
|
11
14
|
analyzeComponentOverrides,
|
|
12
15
|
ComponentOverridesError,
|
|
13
16
|
} from "../../core/component-overrides.ts";
|
|
14
17
|
import { BlumeError } from "../../core/diagnostics.ts";
|
|
18
|
+
import { validateNavTargets } from "../../core/nav-diagnostics.ts";
|
|
15
19
|
import { packageRoot } from "../../core/package-root.ts";
|
|
16
20
|
import { scanProject } from "../../core/project-graph.ts";
|
|
21
|
+
import type { ResolvedConfig } from "../../core/schema.ts";
|
|
17
22
|
import { serverFeatures } from "../../core/server-features.ts";
|
|
18
23
|
import type { Diagnostic } from "../../core/types.ts";
|
|
19
24
|
import { unregisteredSnapshotDiagnostics } from "../../core/version-cut.ts";
|
|
@@ -34,23 +39,24 @@ const FALLBACK_NODE_RANGE = ">=22.12.0";
|
|
|
34
39
|
* Plan `components.ts` the way `blume dev`/`build` do, reporting each override
|
|
35
40
|
* that can't be planned — a non-static form, or an import of a file that
|
|
36
41
|
* doesn't exist — with its own line. The scan alone never reads the file, so
|
|
37
|
-
* without this doctor would pass a project whose build fails.
|
|
42
|
+
* without this doctor would pass a project whose build fails. Also returns
|
|
43
|
+
* the MDX tags the file overrides.
|
|
38
44
|
*/
|
|
39
45
|
const componentsDiagnostics = async (
|
|
40
46
|
componentsFile: string | null
|
|
41
|
-
): Promise<Diagnostic[]> => {
|
|
47
|
+
): Promise<{ issues: Diagnostic[]; mdx: string[] }> => {
|
|
42
48
|
if (!componentsFile) {
|
|
43
|
-
return [];
|
|
49
|
+
return { issues: [], mdx: [] };
|
|
44
50
|
}
|
|
45
51
|
try {
|
|
46
|
-
analyzeComponentOverrides(
|
|
52
|
+
const { mdx } = analyzeComponentOverrides(
|
|
47
53
|
await readFile(componentsFile, "utf-8"),
|
|
48
54
|
componentsFile
|
|
49
55
|
);
|
|
50
|
-
return [];
|
|
56
|
+
return { issues: [], mdx: mdx.map((entry) => entry.key) };
|
|
51
57
|
} catch (error) {
|
|
52
58
|
if (error instanceof ComponentOverridesError) {
|
|
53
|
-
return error.issues;
|
|
59
|
+
return { issues: error.issues, mdx: [] };
|
|
54
60
|
}
|
|
55
61
|
throw error;
|
|
56
62
|
}
|
|
@@ -71,6 +77,25 @@ const supportedNodeRange = (): string => {
|
|
|
71
77
|
}
|
|
72
78
|
};
|
|
73
79
|
|
|
80
|
+
/** The adapters a project runs, one line per kind, for the doctor summary. */
|
|
81
|
+
const integrationSummary = (config: ResolvedConfig): string[] => {
|
|
82
|
+
const { assistant } = config.ai;
|
|
83
|
+
let assistantSummary = "off";
|
|
84
|
+
if (assistant?.enabled) {
|
|
85
|
+
assistantSummary = assistant.endpoint
|
|
86
|
+
? "external endpoint"
|
|
87
|
+
: assistant.provider.kind;
|
|
88
|
+
}
|
|
89
|
+
return [
|
|
90
|
+
`References: ${config.reference.map((adapter) => adapter.kind).join(", ") || "none"}`,
|
|
91
|
+
`Analytics: ${config.analytics.map((adapter) => adapter.kind).join(", ") || "none"}`,
|
|
92
|
+
`Consent: ${config.consent?.kind ?? "none"}`,
|
|
93
|
+
`Rate limiting: ${config.rateLimit?.kind ?? "off"}`,
|
|
94
|
+
`Sources: ${config.content.sources.map((source) => source.kind).join(", ")}`,
|
|
95
|
+
`Assistant: ${assistantSummary}`,
|
|
96
|
+
];
|
|
97
|
+
};
|
|
98
|
+
|
|
74
99
|
export const doctorCommand = defineCommand({
|
|
75
100
|
args: {
|
|
76
101
|
json: {
|
|
@@ -97,15 +122,33 @@ export const doctorCommand = defineCommand({
|
|
|
97
122
|
loadEnvFiles(root);
|
|
98
123
|
|
|
99
124
|
try {
|
|
100
|
-
const project = await scanProject(root, {
|
|
125
|
+
const project = await scanProject(root, {
|
|
126
|
+
// A missing secret fails at the first request. Checked before the
|
|
127
|
+
// sources fetch, so it's still reported when one of them fails the
|
|
128
|
+
// scan for want of it.
|
|
129
|
+
beforeSources: (config) => {
|
|
130
|
+
diagnostics.push(...checkRequiredSecrets(config));
|
|
131
|
+
},
|
|
132
|
+
mode: "build",
|
|
133
|
+
});
|
|
134
|
+
// Tabs, selector items, and featured links can point at custom pages
|
|
135
|
+
// and generated routes too, so they're checked against every route
|
|
136
|
+
// the site serves, as `blume dev`/`build` check them.
|
|
137
|
+
const userPages = project.context.pagesRoot
|
|
138
|
+
? await discoverPages(project.context.pagesRoot)
|
|
139
|
+
: [];
|
|
101
140
|
diagnostics.push(
|
|
102
141
|
...project.diagnostics,
|
|
103
|
-
...unregisteredSnapshotDiagnostics(project)
|
|
142
|
+
...unregisteredSnapshotDiagnostics(project),
|
|
143
|
+
...validateNavTargets(
|
|
144
|
+
project.graph.navigation,
|
|
145
|
+
navTargetRoutes(project, userPages)
|
|
146
|
+
)
|
|
104
147
|
);
|
|
105
148
|
|
|
106
149
|
const { config } = project;
|
|
107
|
-
// The packages
|
|
108
|
-
//
|
|
150
|
+
// The packages a build would need: an adapter's missing SDK fails the
|
|
151
|
+
// build.
|
|
109
152
|
const { islands } = await discoverIslands(root);
|
|
110
153
|
const dependencies = await missingDependencyDiagnostic(
|
|
111
154
|
config,
|
|
@@ -116,9 +159,19 @@ export const doctorCommand = defineCommand({
|
|
|
116
159
|
if (dependencies) {
|
|
117
160
|
diagnostics.push(dependencies);
|
|
118
161
|
}
|
|
162
|
+
const overrides = await componentsDiagnostics(
|
|
163
|
+
project.context.componentsFile
|
|
164
|
+
);
|
|
119
165
|
diagnostics.push(
|
|
120
|
-
...
|
|
121
|
-
|
|
166
|
+
...overrides.issues,
|
|
167
|
+
// A `<Component path>` naming no example renders a "No example
|
|
168
|
+
// found" box, which dev and build warn about too.
|
|
169
|
+
...missingExampleDiagnostics(
|
|
170
|
+
project.graph.pages,
|
|
171
|
+
await discoverExamples(root, config.examples.source),
|
|
172
|
+
root,
|
|
173
|
+
new Set([...islands.map((island) => island.name), ...overrides.mdx])
|
|
174
|
+
)
|
|
122
175
|
);
|
|
123
176
|
const features = serverFeatures(config);
|
|
124
177
|
if (
|
|
@@ -144,23 +197,9 @@ export const doctorCommand = defineCommand({
|
|
|
144
197
|
logger.info(`Output: ${config.deployment.options.output}`);
|
|
145
198
|
logger.info(`Adapter: ${config.deployment.kind}`);
|
|
146
199
|
logger.info(`Search: ${config.search.provider.kind}`);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
);
|
|
150
|
-
logger.info(
|
|
151
|
-
`Analytics: ${config.analytics.map((adapter) => adapter.kind).join(", ") || "none"}`
|
|
152
|
-
);
|
|
153
|
-
logger.info(
|
|
154
|
-
`Sources: ${config.content.sources.map((source) => source.kind).join(", ")}`
|
|
155
|
-
);
|
|
156
|
-
const { assistant } = config.ai;
|
|
157
|
-
let assistantSummary = "off";
|
|
158
|
-
if (assistant?.enabled) {
|
|
159
|
-
assistantSummary = assistant.endpoint
|
|
160
|
-
? "external endpoint"
|
|
161
|
-
: assistant.provider.kind;
|
|
200
|
+
for (const line of integrationSummary(config)) {
|
|
201
|
+
logger.info(line);
|
|
162
202
|
}
|
|
163
|
-
logger.info(`Assistant: ${assistantSummary}`);
|
|
164
203
|
}
|
|
165
204
|
} catch (error) {
|
|
166
205
|
if (error instanceof BlumeError) {
|
package/src/cli/commands/eval.ts
CHANGED
|
@@ -104,12 +104,37 @@ const parseFlags = (args: EvalFlags) => {
|
|
|
104
104
|
return { agent: args.agent, threshold, timeoutS };
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
+
/** A shell word for the rerun command, single-quoted only when it has to be. */
|
|
108
|
+
const shellWord = (value: string): string =>
|
|
109
|
+
/^[\w./:@%+=,-]+$/u.test(value)
|
|
110
|
+
? value
|
|
111
|
+
: `'${value.replaceAll("'", String.raw`'\''`)}'`;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* The command a `--fix` agent reruns to verify its edits. It carries the run's
|
|
115
|
+
* own flags: a bare `blume eval` would fall back to Codex and `evals.yaml`,
|
|
116
|
+
* grading a different file with a different agent than the run it's fixing.
|
|
117
|
+
*/
|
|
118
|
+
const rerunCommand = (
|
|
119
|
+
args: EvalFlags,
|
|
120
|
+
{ agent, threshold, timeoutS }: ReturnType<typeof parseFlags>
|
|
121
|
+
): string =>
|
|
122
|
+
[
|
|
123
|
+
`blume eval --agent ${agent}`,
|
|
124
|
+
args.file === DEFAULT_FILE ? "" : `--file ${shellWord(args.file)}`,
|
|
125
|
+
args.threshold === undefined ? "" : `--threshold ${threshold}`,
|
|
126
|
+
args.timeout === undefined ? "" : `--timeout ${timeoutS}`,
|
|
127
|
+
]
|
|
128
|
+
.filter((part) => part !== "")
|
|
129
|
+
.join(" ");
|
|
130
|
+
|
|
107
131
|
/** `blume eval --fix`: hand the failing report to the interactive agent. */
|
|
108
132
|
const runFixHandoff = async (
|
|
109
133
|
agent: AgentKind,
|
|
110
134
|
result: EvalResult,
|
|
111
135
|
root: string,
|
|
112
|
-
threshold: number
|
|
136
|
+
threshold: number,
|
|
137
|
+
command: string
|
|
113
138
|
): Promise<void> => {
|
|
114
139
|
const count = result.counts.fail + result.counts.error;
|
|
115
140
|
if (count === 0) {
|
|
@@ -120,7 +145,7 @@ const runFixHandoff = async (
|
|
|
120
145
|
process.stderr.write(
|
|
121
146
|
` Handing ${count} failed question${count === 1 ? "" : "s"} to ${cli.name}…\n\n`
|
|
122
147
|
);
|
|
123
|
-
const code = await launchAgentCode(agent, evalFixPrompt(report));
|
|
148
|
+
const code = await launchAgentCode(agent, evalFixPrompt(report, command));
|
|
124
149
|
if (code !== 0) {
|
|
125
150
|
process.exit(code);
|
|
126
151
|
}
|
|
@@ -184,7 +209,8 @@ export const evalCommand = defineCommand({
|
|
|
184
209
|
meta: commandMeta.eval,
|
|
185
210
|
async run({ args }) {
|
|
186
211
|
const root = process.cwd();
|
|
187
|
-
const
|
|
212
|
+
const flags = parseFlags(args);
|
|
213
|
+
const { agent, threshold, timeoutS } = flags;
|
|
188
214
|
if (args.action === "init") {
|
|
189
215
|
await runInit(agent, args.file);
|
|
190
216
|
return;
|
|
@@ -259,7 +285,13 @@ export const evalCommand = defineCommand({
|
|
|
259
285
|
if (args.fix) {
|
|
260
286
|
// The gate is a CI concern; a handoff run succeeds when the agent
|
|
261
287
|
// session does, not when the docs already passed.
|
|
262
|
-
await runFixHandoff(
|
|
288
|
+
await runFixHandoff(
|
|
289
|
+
agent,
|
|
290
|
+
result,
|
|
291
|
+
root,
|
|
292
|
+
threshold,
|
|
293
|
+
rerunCommand(args, flags)
|
|
294
|
+
);
|
|
263
295
|
return;
|
|
264
296
|
}
|
|
265
297
|
|
package/src/cli/commands/init.ts
CHANGED
|
@@ -272,14 +272,16 @@ export const initCommand = defineCommand({
|
|
|
272
272
|
// which `init` leaves alone; say what it still needs before installing.
|
|
273
273
|
const note = workspaceNote(root, answers, env);
|
|
274
274
|
|
|
275
|
-
// Keep installed dependencies, Blume's generated runtime (`.blume/`),
|
|
276
|
-
// build output (`dist/`)
|
|
277
|
-
//
|
|
278
|
-
//
|
|
275
|
+
// Keep installed dependencies, Blume's generated runtime (`.blume/`),
|
|
276
|
+
// build output (`dist/`), and local secrets (`.env.local`, where every
|
|
277
|
+
// missing-secret warning says to put them) out of version control.
|
|
278
|
+
// Idempotent: creates `.gitignore` when absent and skips entries already
|
|
279
|
+
// present (trailing-slash agnostic).
|
|
279
280
|
const ignored = await ensureGitignore(root, [
|
|
280
281
|
"node_modules/",
|
|
281
282
|
".blume/",
|
|
282
283
|
"dist/",
|
|
284
|
+
".env.local",
|
|
283
285
|
]);
|
|
284
286
|
if (ignored.length > 0) {
|
|
285
287
|
sink.success(`Added ${ignored.join(", ")} to .gitignore`);
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import { join } from "pathe";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
planSkill,
|
|
6
|
+
WRITE_SKILL_DIR,
|
|
7
|
+
writeSkillPrompt,
|
|
8
|
+
} from "../../ai/write-skill.ts";
|
|
9
|
+
import { AGENTS, launchInstalledAgent } from "../../audit/agent.ts";
|
|
10
|
+
import type { AgentKind } from "../../audit/agent.ts";
|
|
11
|
+
import { BlumeError } from "../../core/diagnostics.ts";
|
|
12
|
+
import { packageRoot } from "../../core/package-root.ts";
|
|
13
|
+
import { scanProject } from "../../core/project-graph.ts";
|
|
14
|
+
import { getBlumeVersion } from "../../core/version.ts";
|
|
15
|
+
import { commandMeta } from "../command-meta.ts";
|
|
16
|
+
import { reportInternalError } from "../internal-error.ts";
|
|
17
|
+
import { logger, reportDiagnostics } from "../log.ts";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* `blume skill` — write the docs site's agent skill with a coding agent. Every
|
|
21
|
+
* build publishes a generated skill at `/skill.md` (a map of the docs); this
|
|
22
|
+
* opens Claude Code or Codex on the `blume-write-skill` skill bundled in this
|
|
23
|
+
* package to write the richer one, grounded in the docs, under the same name
|
|
24
|
+
* so it takes the generated one's place. The judgment stays in the skill; the
|
|
25
|
+
* command is the front door, like `blume migrate`. Status lines go straight to
|
|
26
|
+
* stderr: consola drops info-level lines in test and CI environments.
|
|
27
|
+
*/
|
|
28
|
+
export const skillCommand = defineCommand({
|
|
29
|
+
args: {
|
|
30
|
+
claude: {
|
|
31
|
+
description: "Write the skill with Claude Code.",
|
|
32
|
+
type: "boolean",
|
|
33
|
+
},
|
|
34
|
+
codex: {
|
|
35
|
+
description: "Write the skill with Codex.",
|
|
36
|
+
type: "boolean",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
meta: commandMeta.skill,
|
|
40
|
+
async run({ args }) {
|
|
41
|
+
const root = process.cwd();
|
|
42
|
+
// SAFETY: AGENTS is a closed record keyed by AgentKind, so its keys are
|
|
43
|
+
// exactly the agent kinds.
|
|
44
|
+
const agents = (Object.keys(AGENTS) as AgentKind[]).filter(
|
|
45
|
+
(kind) => args[kind]
|
|
46
|
+
);
|
|
47
|
+
if (agents.length > 1) {
|
|
48
|
+
logger.error("Pass at most one of --codex or --claude.");
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
const [agent] = agents;
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
// A scan, not `prepareProject`: the agent reads the content tree and
|
|
55
|
+
// the runtime isn't touched, so a running dev server is left alone.
|
|
56
|
+
const plan = planSkill(await scanProject(root, { mode: "build" }));
|
|
57
|
+
const skillDir = join(packageRoot(), WRITE_SKILL_DIR);
|
|
58
|
+
process.stderr.write(
|
|
59
|
+
` ${plan.exists ? "Updating" : "Writing"} the "${plan.name}" skill at ${plan.file}.\n`
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// Without an agent flag the command is the pointer for any other agent:
|
|
63
|
+
// the bundled skill's path, and the install line that puts the skill
|
|
64
|
+
// where agents look for it.
|
|
65
|
+
if (!agent) {
|
|
66
|
+
process.stderr.write(
|
|
67
|
+
` blume skill writes it with a coding agent: rerun with --codex or --claude.\n Using another agent? Point it at ${join(skillDir, "SKILL.md")},\n or install the skill where your agent looks for skills: npx skills add haydenbleasel/blume --skill blume-write-skill\n`
|
|
68
|
+
);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const cli = AGENTS[agent];
|
|
73
|
+
process.stderr.write(` Handing it to ${cli.name}…\n\n`);
|
|
74
|
+
const code = await launchInstalledAgent(
|
|
75
|
+
cli.bin,
|
|
76
|
+
writeSkillPrompt(plan, { skillDir, version: getBlumeVersion() })
|
|
77
|
+
);
|
|
78
|
+
if (code === null) {
|
|
79
|
+
logger.error(
|
|
80
|
+
`${cli.name} (\`${cli.bin}\`) was not found on PATH. Install it with \`${cli.install}\`.`
|
|
81
|
+
);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
if (code !== 0) {
|
|
85
|
+
process.exit(code);
|
|
86
|
+
}
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if (error instanceof BlumeError) {
|
|
89
|
+
reportDiagnostics([error.diagnostic], root);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
reportInternalError(error);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
});
|
|
@@ -13,6 +13,7 @@ import { validateLinks } from "../../core/links.ts";
|
|
|
13
13
|
import { buildManifest } from "../../core/manifest.ts";
|
|
14
14
|
import { scanProject } from "../../core/project-graph.ts";
|
|
15
15
|
import type { Diagnostic } from "../../core/types.ts";
|
|
16
|
+
import { parseIgnoreFlag } from "../args.ts";
|
|
16
17
|
import { commandMeta } from "../command-meta.ts";
|
|
17
18
|
import { reportInternalError } from "../internal-error.ts";
|
|
18
19
|
import {
|
|
@@ -28,6 +29,12 @@ export const validateCommand = defineCommand({
|
|
|
28
29
|
description: "Check external (HTTP) links over the network.",
|
|
29
30
|
type: "boolean",
|
|
30
31
|
},
|
|
32
|
+
ignore: {
|
|
33
|
+
description:
|
|
34
|
+
'With --external, skip external links whose URL matches this glob (e.g. "https://example.com/**"). Repeat it for more; internal links are always checked.',
|
|
35
|
+
type: "string",
|
|
36
|
+
valueHint: "glob",
|
|
37
|
+
},
|
|
31
38
|
json: {
|
|
32
39
|
description: "Emit diagnostics as JSON on stdout (for CI/editors).",
|
|
33
40
|
type: "boolean",
|
|
@@ -38,8 +45,9 @@ export const validateCommand = defineCommand({
|
|
|
38
45
|
},
|
|
39
46
|
},
|
|
40
47
|
meta: commandMeta.validate,
|
|
41
|
-
async run({ args }) {
|
|
48
|
+
async run({ args, rawArgs }) {
|
|
42
49
|
const root = process.cwd();
|
|
50
|
+
const ignore = parseIgnoreFlag(rawArgs);
|
|
43
51
|
const diagnostics: Diagnostic[] = [];
|
|
44
52
|
|
|
45
53
|
try {
|
|
@@ -83,6 +91,7 @@ export const validateCommand = defineCommand({
|
|
|
83
91
|
checkExternal: Boolean(args.external),
|
|
84
92
|
extraRoutes,
|
|
85
93
|
i18n: project.config.i18n,
|
|
94
|
+
ignore,
|
|
86
95
|
publicDir: existsSync(publicDir) ? publicDir : null,
|
|
87
96
|
redirects: project.config.redirects,
|
|
88
97
|
}))
|
package/src/cli/index.ts
CHANGED
|
@@ -81,6 +81,11 @@ const main = defineCommand({
|
|
|
81
81
|
() => import("./commands/preview.ts"),
|
|
82
82
|
"previewCommand"
|
|
83
83
|
),
|
|
84
|
+
skill: lazyCommand(
|
|
85
|
+
commandMeta.skill,
|
|
86
|
+
() => import("./commands/skill.ts"),
|
|
87
|
+
"skillCommand"
|
|
88
|
+
),
|
|
84
89
|
sync: lazyCommand(
|
|
85
90
|
commandMeta.sync,
|
|
86
91
|
() => import("./commands/sync.ts"),
|
package/src/cli/init/scaffold.ts
CHANGED
|
@@ -679,7 +679,7 @@ const ESBUILD_APPROVAL = " allowBuilds:\n esbuild: true";
|
|
|
679
679
|
* What the project still needs from a workspace it sits in, when `init` left
|
|
680
680
|
* that workspace's config alone: a place in a pnpm workspace's `packages`
|
|
681
681
|
* (pnpm skips a folder it doesn't list), pnpm's approval for esbuild's build
|
|
682
|
-
* script (pnpm
|
|
682
|
+
* script (pnpm 11 and later fail the install without it), or Yarn Berry's
|
|
683
683
|
* `node_modules` linker. Undefined when the workspace already has it, or the
|
|
684
684
|
* project doesn't sit in one.
|
|
685
685
|
*/
|
|
@@ -699,12 +699,12 @@ export const workspaceNote = (
|
|
|
699
699
|
const entry = ` packages:\n - ${relative(workspace, root)}`;
|
|
700
700
|
return approved
|
|
701
701
|
? `This folder sits inside the pnpm workspace at ${file}, which doesn't list it under packages, so pnpm won't install it. Add it there before installing:\n\n${entry}`
|
|
702
|
-
: `This folder sits inside the pnpm workspace at ${file}, which doesn't list it under packages, so pnpm won't install it. Add it there before installing, and approve esbuild's build script, or pnpm
|
|
702
|
+
: `This folder sits inside the pnpm workspace at ${file}, which doesn't list it under packages, so pnpm won't install it. Add it there before installing, and approve esbuild's build script, or pnpm 11 and later stop the install:\n\n${entry}\n${ESBUILD_APPROVAL}`;
|
|
703
703
|
}
|
|
704
704
|
if (approved) {
|
|
705
705
|
return;
|
|
706
706
|
}
|
|
707
|
-
return `This project joins the pnpm workspace at ${file}. Approve esbuild's build script there before installing, or pnpm
|
|
707
|
+
return `This project joins the pnpm workspace at ${file}. Approve esbuild's build script there before installing, or pnpm 11 and later stop the install:\n\n${ESBUILD_APPROVAL}`;
|
|
708
708
|
}
|
|
709
709
|
if (answers.packageManager !== "yarn" || yarnMajor(env.userAgent) === 1) {
|
|
710
710
|
return;
|
package/src/cli/prepare.ts
CHANGED
|
@@ -59,6 +59,12 @@ export const prepareProject = async (
|
|
|
59
59
|
let project: BlumeProject;
|
|
60
60
|
try {
|
|
61
61
|
project = await scanProject(options.root, {
|
|
62
|
+
// Fail-fast on missing secrets: warn now, not at the first request, and
|
|
63
|
+
// before the sources fetch, so a source that can't authenticate on a
|
|
64
|
+
// fresh build still gets its variable named.
|
|
65
|
+
beforeSources: (config) => {
|
|
66
|
+
reportDiagnostics(checkRequiredSecrets(config), options.root);
|
|
67
|
+
},
|
|
62
68
|
devServerUrl: options.devServerUrl,
|
|
63
69
|
mode: options.mode,
|
|
64
70
|
overrides: options.overrides,
|
|
@@ -138,8 +144,5 @@ export const prepareProject = async (
|
|
|
138
144
|
logger.warn(warning);
|
|
139
145
|
}
|
|
140
146
|
|
|
141
|
-
// Fail-fast on missing runtime secrets: warn now, not at the first request.
|
|
142
|
-
reportDiagnostics(checkRequiredSecrets(project.config), options.root);
|
|
143
|
-
|
|
144
147
|
return project;
|
|
145
148
|
};
|