blume 0.7.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/CHANGELOG.md +666 -0
  2. package/LICENSE +21 -0
  3. package/README.md +107 -0
  4. package/dist/cli/index.js +1852 -380
  5. package/dist/cli/index.js.map +98 -91
  6. package/dist/types/ai/component-markdown.d.ts +34 -0
  7. package/dist/types/components/content/youtube.d.ts +18 -0
  8. package/dist/types/core/base-path.d.ts +9 -0
  9. package/dist/types/core/config-input.d.ts +47 -2
  10. package/dist/types/core/config.d.ts +3 -2
  11. package/dist/types/core/data.d.ts +7 -0
  12. package/dist/types/core/i18n-ui.d.ts +526 -132
  13. package/dist/types/core/schema.d.ts +293 -146
  14. package/dist/types/index.d.ts +1 -0
  15. package/dist/types/openapi/references.d.ts +60 -0
  16. package/dist/types/seo/x-handle.d.ts +12 -0
  17. package/docs/01-quickstart.mdx +5 -2
  18. package/docs/02-deployment.mdx +8 -8
  19. package/docs/03-faq.mdx +46 -16
  20. package/docs/advanced/api-reference.mdx +1 -1
  21. package/docs/advanced/changelog.mdx +1 -1
  22. package/docs/advanced/custom-pages.mdx +1 -1
  23. package/docs/advanced/skills.mdx +1 -1
  24. package/docs/configuration/ai.mdx +49 -10
  25. package/docs/configuration/customization.mdx +11 -0
  26. package/docs/configuration/export.mdx +1 -1
  27. package/docs/configuration/index.mdx +27 -3
  28. package/docs/configuration/seo.mdx +35 -5
  29. package/docs/content/components.mdx +2 -2
  30. package/docs/content/i18n.mdx +1 -1
  31. package/docs/content/navigation.mdx +3 -3
  32. package/docs/content/sources.mdx +1 -1
  33. package/docs/content/syntax.mdx +6 -4
  34. package/docs/index.mdx +2 -2
  35. package/docs/reference/cli.mdx +9 -7
  36. package/docs/reference/frontmatter.mdx +1 -1
  37. package/package.json +22 -4
  38. package/skills/blume/SKILL.md +5 -3
  39. package/skills/blume-update-docs/SKILL.md +3 -2
  40. package/src/ai/agent-readability.ts +9 -8
  41. package/src/ai/ask-context.ts +7 -2
  42. package/src/ai/ask-data.ts +3 -0
  43. package/src/ai/component-markdown.ts +461 -0
  44. package/src/ai/llms.ts +135 -26
  45. package/src/ai/markdown.ts +35 -6
  46. package/src/ai/mcp/data.ts +25 -4
  47. package/src/ai/mcp/discovery.ts +10 -3
  48. package/src/ai/mcp/server.ts +21 -7
  49. package/src/ai/mcp/tools.ts +1 -1
  50. package/src/ai/visibility.ts +74 -0
  51. package/src/astro/component-slots.ts +11 -1
  52. package/src/astro/generate.ts +77 -45
  53. package/src/astro/integration.ts +1 -1
  54. package/src/astro/markdown-negotiation.ts +1 -1
  55. package/src/astro/pages.ts +81 -19
  56. package/src/astro/templates.ts +150 -19
  57. package/src/blume-modules.d.ts +8 -0
  58. package/src/cli/commands/build.ts +120 -23
  59. package/src/cli/commands/check.ts +1 -1
  60. package/src/cli/commands/dev.ts +26 -5
  61. package/src/cli/commands/eject.ts +47 -19
  62. package/src/cli/commands/init.ts +120 -180
  63. package/src/cli/commands/preview.ts +4 -1
  64. package/src/cli/commands/validate.ts +43 -2
  65. package/src/cli/dev-lock.ts +8 -4
  66. package/src/cli/eject-scripts.ts +72 -0
  67. package/src/cli/env.ts +15 -5
  68. package/src/cli/init/questions.ts +158 -0
  69. package/src/cli/init/scaffold.ts +380 -0
  70. package/src/cli/internal-error.ts +9 -4
  71. package/src/cli/prepare.ts +3 -2
  72. package/src/components/Icon.astro +2 -1
  73. package/src/components/content/AccordionItem.astro +23 -4
  74. package/src/components/content/Badge.astro +3 -1
  75. package/src/components/content/Card.astro +4 -2
  76. package/src/components/content/Step.astro +10 -1
  77. package/src/components/content/Tabs.astro +15 -3
  78. package/src/components/content/Tile.astro +2 -1
  79. package/src/components/content/Tooltip.astro +3 -1
  80. package/src/components/content/Update.astro +9 -2
  81. package/src/components/content/auto-type-table.ts +7 -1
  82. package/src/components/content/base-href.ts +33 -0
  83. package/src/components/content/changelog-element.ts +9 -2
  84. package/src/components/content/mermaid-element.ts +7 -2
  85. package/src/components/islands/AskAI.astro +5 -2
  86. package/src/components/islands/ask-ai.tsx +86 -11
  87. package/src/components/islands/hooks.ts +28 -8
  88. package/src/components/layout/Banner.astro +10 -2
  89. package/src/components/layout/Breadcrumbs.astro +11 -2
  90. package/src/components/layout/Header.astro +13 -4
  91. package/src/components/layout/Logo.astro +11 -3
  92. package/src/components/layout/NavTree.astro +19 -5
  93. package/src/components/layout/PageActions.astro +25 -10
  94. package/src/components/layout/PageLayout.astro +85 -9
  95. package/src/components/layout/Pagination.astro +10 -4
  96. package/src/components/layout/ReferenceLayout.astro +20 -2
  97. package/src/components/layout/RootLayout.astro +142 -12
  98. package/src/components/layout/Search.astro +117 -27
  99. package/src/components/layout/search/algolia.ts +11 -2
  100. package/src/components/layout/search/endpoint.ts +11 -5
  101. package/src/components/layout/search/orama-cloud.ts +8 -2
  102. package/src/components/layout/search/types.ts +5 -1
  103. package/src/components/layout/search/typesense.ts +4 -1
  104. package/src/components/layout/toc-element.ts +1 -1
  105. package/src/components/openapi/ApiTagOperations.astro +2 -1
  106. package/src/components/openapi/Operation.astro +47 -40
  107. package/src/components/openapi/RequestPanel.astro +1 -1
  108. package/src/components/openapi/helpers.ts +71 -3
  109. package/src/components/openapi/panel.ts +1 -1
  110. package/src/core/base-path.ts +24 -0
  111. package/src/core/builtin-tags.ts +2 -0
  112. package/src/core/config-input.ts +48 -2
  113. package/src/core/config.ts +3 -2
  114. package/src/core/data.ts +4 -0
  115. package/src/core/frontmatter.ts +7 -0
  116. package/src/core/graph.ts +15 -5
  117. package/src/core/i18n-ui.ts +54 -0
  118. package/src/core/i18n.ts +16 -8
  119. package/src/core/last-modified.ts +13 -6
  120. package/src/core/links.ts +32 -8
  121. package/src/core/navigation.ts +29 -4
  122. package/src/core/package-json.ts +17 -2
  123. package/src/core/project-graph.ts +15 -6
  124. package/src/core/schema.ts +71 -2
  125. package/src/core/sources/assets.ts +6 -1
  126. package/src/core/sources/filesystem.ts +4 -0
  127. package/src/core/sources/mdx-remote.ts +23 -14
  128. package/src/core/sources/normalize.ts +152 -50
  129. package/src/core/sources/notion.ts +8 -8
  130. package/src/core/ui-packs/ar.ts +8 -0
  131. package/src/core/ui-packs/bg.ts +8 -0
  132. package/src/core/ui-packs/bn.ts +8 -0
  133. package/src/core/ui-packs/ca.ts +8 -0
  134. package/src/core/ui-packs/cs.ts +8 -0
  135. package/src/core/ui-packs/da.ts +8 -0
  136. package/src/core/ui-packs/de.ts +8 -0
  137. package/src/core/ui-packs/el.ts +8 -0
  138. package/src/core/ui-packs/es.ts +8 -0
  139. package/src/core/ui-packs/fa.ts +8 -0
  140. package/src/core/ui-packs/fi.ts +8 -0
  141. package/src/core/ui-packs/fr.ts +9 -1
  142. package/src/core/ui-packs/he.ts +8 -0
  143. package/src/core/ui-packs/hi.ts +8 -0
  144. package/src/core/ui-packs/hr.ts +8 -0
  145. package/src/core/ui-packs/hu.ts +8 -0
  146. package/src/core/ui-packs/id.ts +8 -0
  147. package/src/core/ui-packs/it.ts +8 -0
  148. package/src/core/ui-packs/ja.ts +8 -0
  149. package/src/core/ui-packs/ko.ts +8 -0
  150. package/src/core/ui-packs/nl.ts +8 -0
  151. package/src/core/ui-packs/no.ts +8 -0
  152. package/src/core/ui-packs/pl.ts +8 -0
  153. package/src/core/ui-packs/pt-br.ts +8 -0
  154. package/src/core/ui-packs/pt.ts +8 -0
  155. package/src/core/ui-packs/ro.ts +8 -0
  156. package/src/core/ui-packs/ru.ts +8 -0
  157. package/src/core/ui-packs/sk.ts +8 -0
  158. package/src/core/ui-packs/sr.ts +8 -0
  159. package/src/core/ui-packs/sv.ts +8 -0
  160. package/src/core/ui-packs/th.ts +8 -0
  161. package/src/core/ui-packs/tr.ts +8 -0
  162. package/src/core/ui-packs/uk.ts +8 -0
  163. package/src/core/ui-packs/vi.ts +8 -0
  164. package/src/core/ui-packs/zh-tw.ts +8 -0
  165. package/src/core/ui-packs/zh.ts +8 -0
  166. package/src/deploy/adapter-output.ts +18 -8
  167. package/src/deploy/redirects.ts +7 -2
  168. package/src/deploy/sitemap.ts +53 -11
  169. package/src/index.ts +5 -0
  170. package/src/markdown/base-links.ts +10 -8
  171. package/src/markdown/index.ts +15 -3
  172. package/src/markdown/inline-code.ts +7 -2
  173. package/src/markdown/package-commands.ts +10 -4
  174. package/src/og/card.ts +4 -2
  175. package/src/og/dimensions.ts +12 -0
  176. package/src/openapi/model.ts +12 -4
  177. package/src/openapi/parse.ts +21 -0
  178. package/src/openapi/references.ts +38 -8
  179. package/src/openapi/render-mdx.ts +62 -1
  180. package/src/openapi/source.ts +59 -10
  181. package/src/registry/eject.ts +184 -12
  182. package/src/registry/registry.ts +0 -3
  183. package/src/search/documents.ts +34 -2
  184. package/src/seo/jsonld.ts +20 -13
  185. package/src/seo/x-handle.ts +18 -0
@@ -0,0 +1,34 @@
1
+ /** Evaluated props plus whether any attribute resisted static evaluation. */
2
+ interface EvaluatedProps {
3
+ lossy: boolean;
4
+ props: Record<string, unknown>;
5
+ }
6
+ /** A child component extracted by name (e.g. each `<Step>` under `<Steps>`). */
7
+ export interface ComponentMarkdownChild extends EvaluatedProps {
8
+ /** The child's body, downleveled and dedented. */
9
+ children: string;
10
+ }
11
+ /** What a serializer receives for one component usage. */
12
+ export interface ComponentMarkdownContext extends EvaluatedProps {
13
+ /** Direct child components of `name`, each with evaluated props and body. */
14
+ childComponents: (name: string) => ComponentMarkdownChild[];
15
+ /** The element's body, downleveled and dedented (empty if self-closing). */
16
+ children: string;
17
+ }
18
+ /**
19
+ * A component's Markdown serializer. Return the replacement Markdown, or
20
+ * `null` to leave the component's JSX in the output verbatim (the safe
21
+ * fallback when the props can't be recovered statically).
22
+ */
23
+ export type ComponentMarkdown = (context: ComponentMarkdownContext) => string | null;
24
+ /**
25
+ * Downlevel supported components in an MDX source to plain Markdown. Sources
26
+ * with no supported components — and sources Satteri can't parse as MDX, e.g.
27
+ * plain `.md` with literal `<`/`{` — are returned byte-identical.
28
+ *
29
+ * `components` adds user serializers from `ai.markdownComponents`, layered
30
+ * over the built-ins: a same-name entry replaces the built-in serializer, and
31
+ * one that always returns `null` effectively opts that component out.
32
+ */
33
+ export declare const downlevelComponents: (source: string, components?: Record<string, ComponentMarkdown>) => string;
34
+ export {};
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Helpers for the `<YouTube>` content component. Kept in a sibling `.ts` (like
3
+ * `diff.ts`/`github-info.ts`) so the id parsing and embed-URL building are pure,
4
+ * unit-testable functions — the `.astro` file stays a thin presentational shell.
5
+ */
6
+ /**
7
+ * Resolve a YouTube video id from either a bare id or a full URL. Returns `null`
8
+ * when nothing that looks like an id can be found, so the component can render
9
+ * nothing rather than a broken embed.
10
+ */
11
+ export declare const parseYouTubeId: (input: string) => string | null;
12
+ /**
13
+ * Build a privacy-enhanced (`youtube-nocookie.com`) embed URL, optionally
14
+ * starting at `start` seconds.
15
+ */
16
+ export declare const youtubeEmbedUrl: (id: string, options?: {
17
+ start?: number;
18
+ }) => string;
@@ -29,6 +29,15 @@ export declare const isInternalPath: (target: string) => boolean;
29
29
  * the base by hand (`/docs/x`) aren't double-prefixed to `/docs/docs/x`.
30
30
  */
31
31
  export declare const withBasePath: (basePath: string, route: string) => string;
32
+ /**
33
+ * {@link withBasePath} for the composed `deployment.base` + `basePath` stack
34
+ * (`/base` + `/docs` serves pages at `/base/docs/x`). The hand-written-base
35
+ * promise applies per layer: authors write `basePath` by hand (see
36
+ * `markdown/base-links.ts`), so a `/docs/x` link gains only the deployment base
37
+ * (`/base/docs/x`) rather than being double-prefixed to `/base/docs/docs/x`,
38
+ * and a route already under the full composite is returned unchanged.
39
+ */
40
+ export declare const withComposedBasePath: (deployBase: string, basePath: string, route: string) => string;
32
41
  /**
33
42
  * Remove `basePath` from the front of a route (`/docs/guide` -> `/guide`,
34
43
  * `/docs` -> `/`). A route not under the base is returned unchanged. Inverse of
@@ -1,3 +1,4 @@
1
+ import type { ComponentMarkdown } from "../ai/component-markdown.ts";
1
2
  import type { FontSlug } from "../theme/fonts.ts";
2
3
  import type { OpenApiSource, SearchProvider, SidebarDisplay, SidebarItemConfig } from "./schema.ts";
3
4
  import type { ContentSource } from "./sources/types.ts";
@@ -434,12 +435,45 @@ export interface AskConfig {
434
435
  /** Starter prompts shown before the first question. */
435
436
  suggestions?: AskSuggestion[];
436
437
  }
438
+ /** What the `llms.txt`/`llms-full.txt` files include. */
439
+ export interface LlmsTxtConfig {
440
+ /** Emit `llms.txt` and `llms-full.txt`. Defaults to `true`. */
441
+ enabled?: boolean;
442
+ /**
443
+ * Include the generated API reference pages (OpenAPI/AsyncAPI). Defaults to
444
+ * `true`; set `false` to keep a placeholder or example spec's pages out of
445
+ * the LLM-facing files.
446
+ */
447
+ openapi?: boolean;
448
+ }
437
449
  /** AI-facing features: the Ask AI assistant and an `llms.txt` manifest. */
438
450
  export interface AiConfig {
439
451
  /** The Ask AI chat assistant. */
440
452
  ask?: AskConfig;
441
- /** Emit `llms.txt` (an index of the docs for LLMs). Defaults to `true`. */
442
- llmsTxt?: boolean;
453
+ /**
454
+ * Emit `llms.txt` (an index of the docs for LLMs). Defaults to `true`.
455
+ * The object form adds knobs for what the files include.
456
+ */
457
+ llmsTxt?: boolean | LlmsTxtConfig;
458
+ /**
459
+ * Markdown serializers for custom components in agent-facing output (the
460
+ * `.md` mirror, `llms-full.txt`, MCP `get_page`), keyed by JSX name. Each
461
+ * receives the component's statically-evaluated `props` and downleveled
462
+ * `children` and returns replacement Markdown — or `null` to leave the JSX
463
+ * verbatim. A same-name entry replaces a built-in serializer.
464
+ *
465
+ * These live in `blume.config.ts` (which is executed at build time), not in
466
+ * `components.tsx` (which is only statically analyzed, never run).
467
+ *
468
+ * ```ts
469
+ * ai: {
470
+ * markdownComponents: {
471
+ * Chart: ({ props }) => `![${props.title}](/charts/${props.slug}.png)`,
472
+ * },
473
+ * }
474
+ * ```
475
+ */
476
+ markdownComponents?: Record<string, ComponentMarkdown>;
443
477
  }
444
478
  /** An arbitrary analytics `<script>`; set exactly one of `src` or `content`. */
445
479
  export interface AnalyticsScript {
@@ -589,6 +623,17 @@ export interface SeoConfig {
589
623
  sitemap?: boolean;
590
624
  /** Emit schema.org JSON-LD in each page's `<head>`. Defaults to `true`. */
591
625
  structuredData?: boolean;
626
+ /**
627
+ * X (Twitter) attribution for share cards. Handles may omit the `@`. The rest
628
+ * of the X card is read from the `og:*` tags, so these accounts are the only
629
+ * values X cannot infer.
630
+ */
631
+ x?: {
632
+ /** Author account (`twitter:creator`); a page can override it via `seo.x.creator` frontmatter. */
633
+ creator?: string;
634
+ /** The site's own account (`twitter:site`), e.g. `@blume`. */
635
+ handle?: string;
636
+ };
592
637
  }
593
638
  /** Source repository, powering "Edit this page" links and the header repo link. */
594
639
  export interface GithubConfig {
@@ -65,8 +65,9 @@ import type { Diagnostic } from "./types.ts";
65
65
  * - `search` — search backend `provider` (`orama` by default; `pagefind`,
66
66
  * `algolia`, `typesense`, `orama-cloud`, `mixedbread`, or `none`) plus its
67
67
  * credential block.
68
- * - `ai` — `ask` (the Ask AI chat endpoint and its provider/model) and `llmsTxt`
69
- * (emit `llms.txt`).
68
+ * - `ai` — `ask` (the Ask AI chat endpoint and its provider/model), `llmsTxt`
69
+ * (emit `llms.txt`), and `markdownComponents` (Markdown serializers for
70
+ * custom components in agent-facing output).
70
71
  * - `mcp` — expose the docs as an MCP server for connecting agents.
71
72
  *
72
73
  * **SEO, feeds & analytics**
@@ -87,6 +87,8 @@ export interface BlumeDataConfig {
87
87
  suggestions: NonNullable<ResolvedConfig["ai"]["ask"]>["suggestions"];
88
88
  } | null;
89
89
  banner: BlumeBanner | null;
90
+ /** Site-wide route mount point, normalized to `""` or `/seg` (see config). */
91
+ basePath: string;
90
92
  /** `markdown.codeBlocks.theme`: light/dark Shiki themes for code surfaces. */
91
93
  codeThemes: ResolvedConfig["markdown"]["codeBlocks"]["theme"];
92
94
  /** `markdown.code.wrap`: wrap long code lines instead of scrolling. */
@@ -120,6 +122,11 @@ export interface BlumeDataConfig {
120
122
  title: string;
121
123
  /** Table-of-contents settings: whether to show it and the heading range. */
122
124
  toc: ResolvedConfig["toc"];
125
+ /** X (Twitter) attribution: the site's account, and a default creator. */
126
+ x: {
127
+ creator?: string;
128
+ handle?: string;
129
+ };
123
130
  }
124
131
  /**
125
132
  * The compact snapshot the layout serializes into the page for React island