blume 0.5.3 → 0.5.4

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 (113) hide show
  1. package/dist/cli/index.js +2985 -6883
  2. package/dist/cli/index.js.map +27 -58
  3. package/dist/types/core/config.d.ts +0 -8
  4. package/dist/types/core/data.d.ts +2 -2
  5. package/dist/types/core/schema.d.ts +58 -453
  6. package/dist/types/core/types.d.ts +1 -7
  7. package/docs/advanced/meta.ts +1 -8
  8. package/docs/advanced/skills.mdx +28 -0
  9. package/docs/configuration/ai.mdx +2 -0
  10. package/docs/configuration/index.mdx +13 -17
  11. package/docs/configuration/theming.mdx +2 -10
  12. package/docs/content/components.mdx +2 -53
  13. package/docs/content/i18n.mdx +0 -4
  14. package/docs/content/syntax.mdx +1 -1
  15. package/docs/index.mdx +0 -1
  16. package/docs/reference/cli.mdx +12 -13
  17. package/package.json +4 -6
  18. package/skills/blume/SKILL.md +71 -0
  19. package/skills/blume-update-docs/SKILL.md +52 -0
  20. package/skills/blume-update-docs/references/audit-checklist.md +46 -0
  21. package/src/astro/generate.ts +15 -12
  22. package/src/astro/integration.ts +0 -21
  23. package/src/astro/templates.ts +9 -16
  24. package/src/cli/commands/dev.ts +0 -6
  25. package/src/cli/commands/validate.ts +0 -2
  26. package/src/cli/index.ts +0 -2
  27. package/src/components/BlumePage.astro +0 -6
  28. package/src/components/Icon.astro +1 -12
  29. package/src/components/content/AccordionItem.astro +3 -6
  30. package/src/components/content/Badge.astro +1 -3
  31. package/src/components/content/Callout.astro +3 -9
  32. package/src/components/content/Card.astro +2 -3
  33. package/src/components/content/ColorItem.astro +2 -2
  34. package/src/components/content/Column.astro +1 -1
  35. package/src/components/content/Prompt.astro +1 -1
  36. package/src/components/content/Step.astro +3 -4
  37. package/src/components/content/Tab.astro +2 -3
  38. package/src/components/content/TypeTable.astro +5 -5
  39. package/src/components/content/Update.astro +1 -1
  40. package/src/components/layout/Header.astro +26 -3
  41. package/src/components/layout/Logo.astro +5 -1
  42. package/src/components/layout/NavSelector.astro +1 -1
  43. package/src/components/layout/NavTree.astro +14 -14
  44. package/src/components/layout/PageLayout.astro +42 -0
  45. package/src/components/layout/ReferenceLayout.astro +1 -0
  46. package/src/components/layout/RootLayout.astro +31 -2
  47. package/src/components/layout/Search.astro +5 -5
  48. package/src/components/layout/nav-utils.ts +9 -4
  49. package/src/components/openapi/ApiOverview.astro +4 -50
  50. package/src/components/openapi/ApiTagOperations.astro +42 -0
  51. package/src/core/builtin-tags.ts +1 -3
  52. package/src/core/config.ts +5 -28
  53. package/src/core/data.ts +2 -2
  54. package/src/core/graph.ts +1 -4
  55. package/src/core/links.ts +5 -19
  56. package/src/core/meta.ts +1 -1
  57. package/src/core/navigation.ts +0 -5
  58. package/src/core/project-graph.ts +0 -5
  59. package/src/core/schema.ts +13 -90
  60. package/src/core/sources/resolve.ts +0 -13
  61. package/src/core/sources/watch.ts +3 -2
  62. package/src/core/types.ts +1 -8
  63. package/src/openapi/parse.ts +197 -14
  64. package/src/openapi/render-mdx.ts +44 -10
  65. package/src/openapi/source.ts +19 -2
  66. package/src/theme/entry.ts +45 -17
  67. package/src/theme/icons.ts +18 -109
  68. package/src/theme/palette.ts +4 -37
  69. package/src/theme/twoslash.ts +6 -1
  70. package/dist/types/core/bridge.d.ts +0 -24
  71. package/dist/types/core/package-json.d.ts +0 -12
  72. package/dist/types/migrate/mintlify/assets.d.ts +0 -8
  73. package/dist/types/migrate/mintlify/config.d.ts +0 -16
  74. package/dist/types/migrate/mintlify/i18n.d.ts +0 -7
  75. package/dist/types/migrate/shared.d.ts +0 -153
  76. package/docs/advanced/bridge.mdx +0 -76
  77. package/docs/advanced/migrate.mdx +0 -124
  78. package/src/astro/static-assets.ts +0 -124
  79. package/src/cli/commands/migrate.ts +0 -39
  80. package/src/components/content/ApiField.astro +0 -75
  81. package/src/components/content/ParamField.astro +0 -39
  82. package/src/components/content/RequestField.astro +0 -23
  83. package/src/components/content/ResponseField.astro +0 -23
  84. package/src/components/content/Warning.astro +0 -9
  85. package/src/core/assets.ts +0 -31
  86. package/src/core/bridge.ts +0 -102
  87. package/src/core/sources/mintlify.ts +0 -190
  88. package/src/migrate/fumadocs/config.ts +0 -155
  89. package/src/migrate/fumadocs/content.ts +0 -376
  90. package/src/migrate/fumadocs/frontmatter.ts +0 -18
  91. package/src/migrate/fumadocs/groups.ts +0 -237
  92. package/src/migrate/fumadocs/index.ts +0 -355
  93. package/src/migrate/fumadocs/meta.ts +0 -244
  94. package/src/migrate/migrate.ts +0 -53
  95. package/src/migrate/mintlify/assets.ts +0 -46
  96. package/src/migrate/mintlify/config.ts +0 -954
  97. package/src/migrate/mintlify/content.ts +0 -120
  98. package/src/migrate/mintlify/frontmatter.ts +0 -126
  99. package/src/migrate/mintlify/i18n.ts +0 -51
  100. package/src/migrate/mintlify/icons.ts +0 -128
  101. package/src/migrate/mintlify/index.ts +0 -459
  102. package/src/migrate/mintlify/snippets.ts +0 -315
  103. package/src/migrate/mintlify/transform.ts +0 -82
  104. package/src/migrate/nextra/content.ts +0 -46
  105. package/src/migrate/nextra/frontmatter.ts +0 -40
  106. package/src/migrate/nextra/index.ts +0 -389
  107. package/src/migrate/nextra/meta.ts +0 -266
  108. package/src/migrate/shared.ts +0 -801
  109. package/src/migrate/starlight/config.ts +0 -455
  110. package/src/migrate/starlight/content.ts +0 -75
  111. package/src/migrate/starlight/frontmatter.ts +0 -111
  112. package/src/migrate/starlight/i18n.ts +0 -54
  113. package/src/migrate/starlight/index.ts +0 -131
@@ -162,22 +162,16 @@ export interface NavSelectorItem {
162
162
  icon?: string;
163
163
  tag?: string;
164
164
  }
165
- /** Top-level Mintlify-style partition selectors. */
165
+ /** Top-level partition selectors (products, versions, languages). */
166
166
  export interface NavSelector {
167
167
  label: string;
168
168
  kind: "dropdown" | "language" | "product" | "version";
169
169
  items: NavSelectorItem[];
170
170
  }
171
- /** Chrome overrides used when the current route belongs to a nav partition. */
172
- export interface NavChromeVariant {
173
- path: string;
174
- banner?: ResolvedConfig["banner"];
175
- }
176
171
  /** The complete navigation model derived from the content graph. */
177
172
  export interface Navigation {
178
173
  tabs: NavTab[];
179
174
  selectors: NavSelector[];
180
- chromeVariants: NavChromeVariant[];
181
175
  sidebar: NavNode[];
182
176
  /** Repo URL for the header link, or null when hidden (`navigation.repo`). */
183
177
  repoUrl?: string | null;
@@ -2,13 +2,6 @@ import { defineMeta } from "blume";
2
2
 
3
3
  export default defineMeta({
4
4
  order: 5,
5
- pages: [
6
- "migrate",
7
- "bridge",
8
- "custom-pages",
9
- "changelog",
10
- "blog",
11
- "api-reference",
12
- ],
5
+ pages: ["skills", "custom-pages", "changelog", "blog", "api-reference"],
13
6
  title: "Advanced",
14
7
  });
@@ -0,0 +1,28 @@
1
+ ---
2
+ title: Skills
3
+ description: The agent skills Blume ships — playbooks that teach a coding agent to build and maintain a Blume docs site.
4
+ ---
5
+
6
+ Blume ships [agent skills](https://docs.claude.com/en/docs/claude-code/skills) — playbooks that teach a coding agent (Claude Code, Codex, Cursor) how to do a Blume-shaped job without you explaining it. They live on GitHub in the repo's `skills/` folder and are bundled in the package at `node_modules/blume/skills/` once Blume is installed, so any agent can be pointed at a `SKILL.md` directly.
7
+
8
+ ## Blume
9
+
10
+ The core skill. It teaches the agent what Blume is and how to scaffold, write, and configure a site — filesystem-derived navigation, the config schema, content components — and points it at the full docs bundled in the installed package (`node_modules/blume/docs`). Install it in any project where an agent helps you build your docs:
11
+
12
+ ```bash
13
+ npx skills add haydenbleasel/blume
14
+ ```
15
+
16
+ ## Self-updating docs
17
+
18
+ `blume-update-docs` keeps your docs in sync with the product they document. On each run — typically from a schedule you configure in your agent runner — it audits recently merged PRs, changelogs, config schemas, and CLI help against the docs content, updates only pages that are factually stale (feature-flagged work is ignored), verifies with `blume build`, and opens or updates a `blume/*` pull request. If nothing drifted, it reports a clean no-op instead of opening a noisy PR.
19
+
20
+ ```bash
21
+ npx skills use haydenbleasel/blume@blume-update-docs
22
+ ```
23
+
24
+ Blume doesn't host the automation — wire the skill into a scheduled task in Claude Code, a Codex or Cursor automation, or plain cron, with permission to read repo history and open PRs. A typical weekly prompt:
25
+
26
+ ```text
27
+ Use the blume-update-docs skill. Review the PRs merged within the last 7 days and compare them to the docs content. Ignore work behind feature flags. If docs need updates, make them, verify the docs build, and open a blume/* PR. If not, report what you checked and do not open a PR.
28
+ ```
@@ -184,3 +184,5 @@ npx skills add haydenbleasel/blume
184
184
  ```
185
185
 
186
186
  The skill teaches the agent what Blume is and how to scaffold, write, and configure a site, and points it at the full docs bundled in the installed package (`node_modules/blume/docs`).
187
+
188
+ It's one of the [agent skills Blume ships](/docs/advanced/skills), alongside skills for migrating an existing docs site to Blume and keeping docs in sync with your product from a scheduled agent run.
@@ -91,7 +91,7 @@ export default defineConfig({
91
91
  | --- | --- | --- |
92
92
  | `title` | `"Documentation"` | Site name — shown in the header, page titles, OG cards. |
93
93
  | `description` | — | Default meta description, used for SEO and OG. |
94
- | `logo` | — | Brand logo shown beside the title in the header. |
94
+ | `logo` | — | Brand mark and/or wordmark shown in the header. |
95
95
  | `banner` | — | Site-wide announcement bar above the header. |
96
96
 
97
97
  ### Logo
@@ -102,18 +102,23 @@ Point `logo` at an SVG and Blume inlines it, so a `currentColor` logo follows th
102
102
  logo: "/logo.svg",
103
103
  ```
104
104
 
105
- The SVG can live at your project root or in `public/`. For raster images or separate light and dark artwork — use the object form (these must live in `public/`):
105
+ The SVG can live at your project root or in `public/`. The brand is a mark (`image`) plus a wordmark (`text`); the object form lets you set them independently:
106
106
 
107
107
  ```ts blume.config.ts lineNumbers
108
108
  logo: {
109
- light: "/logo-light.png",
110
- dark: "/logo-dark.png",
111
- alt: "Acme",
112
- href: "/",
109
+ image: "/logo.svg", // string, or { light, dark, alt } for themed raster art
110
+ text: "Acme", // wordmark beside the mark
111
+ href: "/", // overrides the brand link (defaults to "/")
113
112
  },
114
113
  ```
115
114
 
116
- `href` overrides the logo's link (it defaults to `/`).
115
+ `image` takes the same value as the shorthand — a single path, or `{ light, dark, alt }` for separate light/dark artwork (raster images must live in `public/`).
116
+
117
+ `text` controls the wordmark independently of the mark:
118
+
119
+ - **Omit `text`** and the brand uses your site `title` (the default).
120
+ - **Set `text: ""`** to show the mark alone — handy when the logo image already includes the wordmark.
121
+ - **Set `text` with no `image`** for a text-only logo.
117
122
 
118
123
  ### Favicon
119
124
 
@@ -177,17 +182,8 @@ content: {
177
182
  | `exclude` | `["**/_*", "**/.*"]` | Globs to ignore (underscore- and dot-files). |
178
183
  | `pages` | `"pages"` | Folder for custom `.astro` pages. |
179
184
  | `defaultType` | `"doc"` | Page `type` used when frontmatter omits it. |
180
- | `assets` | `[]` | Extra top-level directories served at the site root, alongside `public/`. |
181
-
182
- Assets normally live in `public/` — a file at `public/logo.png` is served at `/logo.png`. Use `assets` to serve additional root-level folders in place instead of moving them under `public/`. Each entry is a directory relative to your project root, served at the matching URL and copied into `dist/` on build:
183
-
184
- ```ts blume.config.ts
185
- content: {
186
- assets: ["images"], // /images/create.png → images/create.png
187
- }
188
- ```
189
185
 
190
- This is mainly useful after [migrating](/docs/advanced/migrate) from a tool that serves assets from the project root (like Mintlify), so references such as `![](/images/create.png)` keep resolving without relocating every file. [Bridge mode](/docs/advanced/bridge) uses the same mechanism to serve a Mintlify project's assets in place, untouched.
186
+ Static assets live in `public/` a file at `public/logo.png` is served at `/logo.png`, so a reference like `![](/images/create.png)` resolves against `public/images/create.png`.
191
187
 
192
188
  ## Last modified
193
189
 
@@ -112,17 +112,9 @@ theme: {
112
112
  }
113
113
  ```
114
114
 
115
- ### Background decoration
115
+ ### Background image
116
116
 
117
- Add a subtle, theme-aware pattern behind your content with `backgroundDecoration` `gradient`, `grid`, or `windows`:
118
-
119
- ```ts blume.config.ts
120
- theme: {
121
- backgroundDecoration: "grid",
122
- }
123
- ```
124
-
125
- For a full background image, set `backgroundImage` (and `backgroundImageDark` for a dark variant) to a URL or a path under `public/`:
117
+ Set a background image behind your content with `backgroundImage` (and `backgroundImageDark` for a dark variant) — a URL or a path under `public/`:
126
118
 
127
119
  ```ts blume.config.ts lineNumbers
128
120
  theme: {
@@ -125,7 +125,7 @@ A negative or breaking state, such as a deprecation.
125
125
 
126
126
  ## Icon
127
127
 
128
- Render an icon by name — the same `icon` props power cards, steps, tiles, tabs, and sidebar entries. Names come from three bundled libraries: [Lucide](https://lucide.dev) (the default), [Font Awesome](https://fontawesome.com/icons) (its free set), and [Tabler](https://tabler.io/icons). Names are lowercase and kebab-cased (`rocket`, `gauge-high`, `book-open`).
128
+ Render an icon by name — the same `icon` prop powers cards, steps, tabs, and sidebar entries. Names come from [Lucide](https://lucide.dev/icons), lowercase and kebab-cased (`rocket`, `gauge`, `book-open`).
129
129
 
130
130
  <Icon icon="rocket" size={20} />
131
131
 
@@ -133,27 +133,10 @@ Render an icon by name — the same `icon` props power cards, steps, tiles, tabs
133
133
  <Icon icon="rocket" size={20} />
134
134
  ```
135
135
 
136
- A bare name resolves against your project's [`icons.library`](#default-library) (Lucide unless you change it). Two ways to reach another library for a single icon:
137
-
138
- - **`iconType`** selects a Font Awesome style — `solid` (default), `regular`, or `brands`: `<Icon icon="github" iconType="brands" />`. Font Awesome Pro styles (`light`, `thin`, `duotone`, `sharp-solid`) aren't in the bundled free data and fall back to solid.
139
- - **A `library:name` prefix** overrides the default per icon: `fa6-solid:gauge-high`, `fa6-brands:github`, `lucide:rocket`, `tabler:heart`.
140
-
141
- `size` sets the pixel size (default `16`) and `color` tints it (any CSS color; defaults to `currentColor`). Pass a raw `<svg>` string, an image URL, or a local image path in place of a name to render your own art, and add a `label` to expose it to assistive tech — without one, the icon is decorative.
136
+ Blume is Lucide-only — a bare name resolves against Lucide, and you can prefix a name with `lucide:` (`lucide:rocket`) for symmetry with other icon inputs. `size` sets the pixel size (default `16`) and `color` tints it (any CSS color; defaults to `currentColor`). Pass a raw `<svg>` string, an image URL, or a local image path in place of a name to render your own art, and add a `label` to expose it to assistive tech — without one, the icon is decorative.
142
137
 
143
138
  Icons resolve at build time and inline as zero-JS SVG — nothing is fetched at runtime.
144
139
 
145
- ### Default library
146
-
147
- Set which library bare icon names resolve against:
148
-
149
- ```ts title="blume.config.ts"
150
- export default defineConfig({
151
- icons: { library: "fontawesome" }, // "lucide" (default) | "fontawesome" | "tabler"
152
- });
153
- ```
154
-
155
- A `library:name` prefix always wins over this, so you can mix libraries on any default. Migrating from Mintlify sets this to `fontawesome` for you (Mintlify's default), so your existing icon names keep working.
156
-
157
140
  ## File tree
158
141
 
159
142
  Illustrate a project or folder layout. Wrap a normal Markdown list and Blume styles it as a tree — handy for explaining structure in setup and config guides.
@@ -457,40 +440,6 @@ Show or hide content by audience. `for="web"` renders only on the site; `for="ag
457
440
  <Visibility for="agents">Shown only in the generated Markdown.</Visibility>
458
441
  ```
459
442
 
460
- ## API fields
461
-
462
- Document a single request/response field — a CLI flag, an SDK argument, an endpoint parameter — with its name, type, and description. `ParamField`, `ResponseField`, and `RequestField` are Mintlify-compatible, so a migrated site's field markup renders unchanged. Each takes a `type`, plus `required`, `deprecated`, and `default`; the description is the element's body and may hold rich MDX, including a nested [Expandable](#expandable) for sub-properties.
463
-
464
- `ParamField` names the field through the attribute that marks its location — `path`, `query`, `header`, or `body` (or a plain `name`); the location shows as a small label.
465
-
466
- <ParamField path="userId" type="string" required>
467
- The unique identifier of the user.
468
- </ParamField>
469
-
470
- <ParamField query="limit" type="integer" default="20">
471
- Maximum number of results to return per page.
472
- </ParamField>
473
-
474
- <ResponseField name="createdAt" type="string">
475
- ISO 8601 timestamp for when the record was created.
476
- </ResponseField>
477
-
478
- ```mdx
479
- <ParamField path="userId" type="string" required>
480
- The unique identifier of the user.
481
- </ParamField>
482
-
483
- <ParamField query="limit" type="integer" default="20">
484
- Maximum number of results to return per page.
485
- </ParamField>
486
-
487
- <ResponseField name="createdAt" type="string">
488
- ISO 8601 timestamp for when the record was created.
489
- </ResponseField>
490
- ```
491
-
492
- For a full spec-driven API reference — one page per operation with generated schemas — use the [OpenAPI reference](/docs/advanced/api-reference) instead.
493
-
494
443
  ## Type tables
495
444
 
496
445
  Tables for documenting an object's properties — its props, types, and defaults. Write the rows by hand with `TypeTable`, or generate them straight from a TypeScript interface or type alias with `AutoTypeTable`.
@@ -22,10 +22,6 @@ i18n: {
22
22
 
23
23
  Each locale has a `code` (used in URLs), a `label` (shown in the language switcher), and an optional `dir` for right-to-left scripts (`"ltr"` by default).
24
24
 
25
- :::tip
26
- Migrating from Mintlify? [`blume migrate mintlify`](/docs/advanced/migrate) reads `navigation.languages[]` and writes the `i18n` block for you — the `default: true` language becomes `defaultLocale`, and translated folders already match Blume's layout.
27
- :::
28
-
29
25
  ## Organize translated content
30
26
 
31
27
  The default locale lives at your content root. Every other locale is a top-level folder named by its `code`, mirroring the default structure:
@@ -95,7 +95,7 @@ Tabulate structured data — config options, comparison matrices, parameter list
95
95
 
96
96
  ## Links and images
97
97
 
98
- Link to other pages or external sites. Images accept any path under `public/` (or another directory listed in [`content.assets`](/docs/configuration#content)) or a remote URL.
98
+ Link to other pages or external sites. Images accept any path under `public/` (served at the site root) or a remote URL.
99
99
 
100
100
  Read the [quickstart](/docs/quickstart) to get started.
101
101
 
package/docs/index.mdx CHANGED
@@ -49,7 +49,6 @@ Your [`blume.config.ts`](/docs/configuration) and every [`meta.ts`](/docs/conten
49
49
  - **Navigation** — inferred from files, refined with `meta.ts` or config.
50
50
  - **SEO** — metadata, Open Graph images, RSS feeds, and JSON-LD, [built in](/docs/configuration/seo).
51
51
  - **Customization** — component overrides, React islands, custom pages, theme tokens, and a source-component registry via `blume add`.
52
- - **Migration** — [`blume migrate mintlify | starlight | nextra | fumadocs`](/docs/advanced/migrate), or run `blume dev` on a Mintlify project as-is with [bridge mode](/docs/advanced/bridge).
53
52
  - **Eject** — `blume eject` produces a standalone Astro project that still uses the `blume` package.
54
53
 
55
54
  ## How it works
@@ -9,19 +9,18 @@ blume <command> [options]
9
9
 
10
10
  ## Commands
11
11
 
12
- | Command | Description |
13
- | --- | --- |
14
- | `blume init` | Scaffold a minimal project. |
15
- | `blume dev` | Start the dev server with hot reload. |
16
- | `blume build` | Build the static (or server) site. |
17
- | `blume preview` | Preview the last build. |
18
- | `blume add <item>` | Install a source component from the registry. |
19
- | [`blume migrate <tool>`](/docs/advanced/migrate) | Migrate from Mintlify, Starlight, Nextra, or Fumadocs. |
20
- | `blume sync` | Re-fetch remote content sources and regenerate. |
21
- | `blume eject` | Promote the runtime into a standalone Astro app. |
22
- | `blume check` | Type-check the site with `astro check`. |
23
- | `blume doctor` | Diagnose config and content problems. |
24
- | `blume validate` | Validate links across your content. |
12
+ | Command | Description |
13
+ | ------------------ | ------------------------------------------------ |
14
+ | `blume init` | Scaffold a minimal project. |
15
+ | `blume dev` | Start the dev server with hot reload. |
16
+ | `blume build` | Build the static (or server) site. |
17
+ | `blume preview` | Preview the last build. |
18
+ | `blume add <item>` | Install a source component from the registry. |
19
+ | `blume sync` | Re-fetch remote content sources and regenerate. |
20
+ | `blume eject` | Promote the runtime into a standalone Astro app. |
21
+ | `blume check` | Type-check the site with `astro check`. |
22
+ | `blume doctor` | Diagnose config and content problems. |
23
+ | `blume validate` | Validate links across your content. |
25
24
 
26
25
  ## Common flags
27
26
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blume",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "Documentation that's fast, AI-ready, and zero-config.",
5
5
  "keywords": [
6
6
  "astro",
@@ -28,7 +28,8 @@
28
28
  "dist",
29
29
  "src",
30
30
  "bin",
31
- "docs"
31
+ "docs",
32
+ "skills"
32
33
  ],
33
34
  "type": "module",
34
35
  "types": "./dist/types/index.d.ts",
@@ -70,11 +71,7 @@
70
71
  "@astrojs/node": "^11.0.0",
71
72
  "@astrojs/react": "^6.0.0",
72
73
  "@astrojs/vercel": "^11.0.0",
73
- "@iconify-json/fa6-brands": "^1.2.6",
74
- "@iconify-json/fa6-regular": "^1.2.4",
75
- "@iconify-json/fa6-solid": "^1.2.4",
76
74
  "@iconify-json/lucide": "^1.2.115",
77
- "@iconify-json/tabler": "^1.2.35",
78
75
  "@iconify/types": "^2.0.0",
79
76
  "@iconify/utils": "^3.1.3",
80
77
  "@modelcontextprotocol/sdk": "^1.29.0",
@@ -111,6 +108,7 @@
111
108
  "tailwindcss": "^4",
112
109
  "tinyglobby": "^0.2.10",
113
110
  "typescript": "^5.7.0",
111
+ "undici": "^8.6.0",
114
112
  "zod": "^3.24.0"
115
113
  },
116
114
  "devDependencies": {
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: blume
3
+ description: Build and maintain documentation sites with Blume, the markdown-first docs framework on Astro and Vite. Use when working in a project that depends on `blume`, when scaffolding or configuring a docs site, writing Markdown/MDX content, tuning navigation/search/theming/SEO/AI features, running the `blume` CLI (init, dev, build, eject), or editing `blume.config.ts` and `meta.ts` files.
4
+ ---
5
+
6
+ # Blume
7
+
8
+ Blume is an open-source, **markdown-first** documentation framework built on Astro and Vite. Drop Markdown or MDX into a folder, run `blume dev`, and get a production-grade docs site — navigation, search, theming, Open Graph images, and a rich component library — with no app boilerplate to write or maintain.
9
+
10
+ The core idea: **the framework _is_ the template.** There's no starter to clone and no project to own before you've written a word. The only thing you touch is your content. When you outgrow the defaults, you add configuration one file at a time — and you can `blume eject` to a plain Astro project the day you want full control.
11
+
12
+ ## What makes it different
13
+
14
+ - **Fast by default** — Static HTML on Astro/Vite. The core theme ships no client framework JS so pages score well on Core Web Vitals out of the box. You opt into server features only when you need them.
15
+ - **AI-ready out of the box** — Emits `llms.txt`/`llms-full.txt`, serves any page's raw Markdown by appending `.md` to its URL, offers **Copy as Markdown** and **Open in chat** on every page, and can host an optional **Ask AI** assistant or an **MCP server** so coding agents read your docs directly.
16
+ - **Zero configuration — even the template** — A folder of docs is a complete project. Navigation is inferred from files, search works in dev and production with no hosted service, and theming is a handful of tokens.
17
+ - **Type-safe to the core** — `blume.config.ts` and every `meta.ts` are real TypeScript, validated by a schema and authored with `defineConfig` and `defineMeta`. Your editor autocompletes options and catches mistakes before a build.
18
+
19
+ ## Quickstart
20
+
21
+ Blume needs **Node.js 22 or newer**. From an empty or existing project:
22
+
23
+ ```bash
24
+ npm i blume # install the package
25
+ blume init # scaffold: docs/index.mdx + blume.config.ts
26
+ blume dev # dev server with hot reload
27
+ blume build # static HTML to dist/, with a local search index
28
+ ```
29
+
30
+ Blume works with any package manager and never requires you to set up Astro or Tailwind yourself.
31
+
32
+ ### Writing a page
33
+
34
+ Every page is Markdown or MDX with a little frontmatter. The `title` and `description` render as the page heading and intro automatically; built-in components (callouts, cards, tabs, steps, and more) need **no imports**.
35
+
36
+ ```mdx
37
+ ---
38
+ title: Introduction
39
+ description: Welcome to my docs.
40
+ ---
41
+
42
+ Welcome! Use **Markdown** and built-in components — no imports required:
43
+
44
+ :::note Blume ships callouts, cards, tabs, steps, and more. :::
45
+ ```
46
+
47
+ Navigation, search, and page metadata are inferred from your files as you add them.
48
+
49
+ ## What's included
50
+
51
+ - **Components** — callouts, cards, steps, tabs, accordions, badges, file trees, and parameter tables, usable in MDX with no imports.
52
+ - **Local search** — Orama in dev and production; Pagefind is one flag away for large sites. No hosted index.
53
+ - **AI** — `llms.txt`, raw Markdown URLs, Copy as Markdown, Open in chat, an Ask AI assistant, and a hosted MCP server.
54
+ - **Navigation** — inferred from files, refined with `meta.ts` or config.
55
+ - **SEO** — metadata, Open Graph images, RSS feeds, and JSON-LD.
56
+ - **Customization** — component overrides, React islands, custom pages, theme tokens, and a source-component registry via `blume add`.
57
+ - **Eject** — `blume eject` produces a standalone Astro project that still uses the `blume` package.
58
+
59
+ ## How it works
60
+
61
+ The Blume CLI discovers your content, builds a content graph, and generates a hidden Astro project under `.blume/` that it drives for dev and build. The generated runtime is an implementation detail — you write Markdown, Blume handles the rest — until you choose to eject and own it.
62
+
63
+ ## Full documentation
64
+
65
+ This is a high-level overview. For complete, authoritative docs — configuration reference, every CLI command and flag, component APIs, content authoring, navigation, search, SEO, AI features, theming, and deployment — read the bundled docs in the installed package:
66
+
67
+ ```
68
+ node_modules/blume/docs
69
+ ```
70
+
71
+ Start with `node_modules/blume/docs/index.mdx` (Introduction) and `node_modules/blume/docs/01-quickstart.mdx`, then browse the `configuration/`, `content/`, `reference/`, and `advanced/` sections for specifics.
@@ -0,0 +1,52 @@
1
+ ---
2
+ name: blume-update-docs
3
+ description: Keep a Blume docs site in sync with the product it documents. Audit recently merged pull requests, changelogs, config schemas, CLI help, and public APIs against the docs content, update only pages that are factually stale, verify the docs build, and open (or update) a maintenance pull request — or report a clean no-op. Use when asked to check docs for drift, refresh stale documentation, run a scheduled docs audit, or keep docs current after a release.
4
+ ---
5
+
6
+ # Update Blume Docs
7
+
8
+ Blume is a **markdown-first** documentation framework on Astro/Vite: content lives as Markdown/MDX under a content root (default `docs/`), navigation derives from the file tree plus optional `meta.ts` files, and `blume build` validates links, anchors, frontmatter, and routes.
9
+
10
+ Your job is **docs maintenance, not docs authorship**: find where shipped, user-facing behavior has drifted from what the docs claim, fix exactly that, prove the site still builds, and deliver the result as a pull request. A run that finds nothing actionable ends with a short report and **no branch, no commit, no PR** — prefer a no-op over a noisy PR.
11
+
12
+ ## Ground rules
13
+
14
+ - **Only document what shipped.** Never invent features, timelines, pricing, APIs, or compatibility claims. Work behind a feature flag is not ready for docs unless the flag is enabled for the documented audience or the repo explicitly documents unreleased behavior.
15
+ - **Facts over polish.** Edit when a command, option, default, route, prop, or workflow is wrong or missing. Skip subjective rewording, marketing polish, restructuring, and formatting-only churn.
16
+ - **Smallest correct diff.** Touch the fewest pages that remove the drift. Preserve the site's voice, frontmatter style, component usage, and `meta.ts` navigation patterns.
17
+ - **Exact source-of-truth wording** for commands, flags, config keys, environment variables, routes, and version numbers — copy them from code, don't paraphrase from memory.
18
+ - **Respect the repo.** Follow `AGENTS.md`/`CLAUDE.md` conventions, don't touch generated output (`.blume/`, `dist/`), and never overwrite unrelated local changes.
19
+
20
+ ## Workflow
21
+
22
+ 1. **Establish context.**
23
+ - Read the repo's agent/contributor instructions (`AGENTS.md`, `CLAUDE.md`, contribution docs) and honor them.
24
+ - Locate the docs app and content root: `blume.config.ts` (`content.root`), the directory of `.md`/`.mdx` pages, `meta.ts` files, and the package manager + docs build command.
25
+ - If this run was configured with a trigger, lookback window, docs path, target branch, or PR policy, honor those. Use the defaults below only where the prompt is silent.
26
+
27
+ 2. **Reuse or create a maintenance branch.**
28
+ - If an open docs-maintenance PR from a previous run exists (head branch starting with `blume/`), check out and update that branch instead of opening a duplicate.
29
+ - Otherwise branch from the default branch as `blume/docs-refresh-YYYY-MM-DD`. Create the branch only once you know an edit is needed.
30
+
31
+ 3. **Find drift.** Read `references/audit-checklist.md` for the full source list and change criteria, then:
32
+ - Review PRs merged into the default branch within the lookback window (default: the last 7 days) and extract the user-facing changes.
33
+ - Compare those changes — plus changelogs, release notes, config schemas, exported APIs, CLI help, and examples — against the docs content.
34
+ - Check external links only when a checked page depends on them; prefer official docs and release notes over secondary sources.
35
+ - Keep notes: what you checked, what changed upstream, and why each edit is (or isn't) needed.
36
+
37
+ 4. **Update the docs.**
38
+ - Fix the stale pages. Add, rename, or remove `meta.ts` entries when pages are added, renamed, or deleted.
39
+ - Match the surrounding pages: frontmatter shape, Blume components already in use, code-fence style, root-relative internal links.
40
+
41
+ 5. **Verify.**
42
+ - Run the docs build (`blume build` or the repo's documented docs QA) — it validates links, anchors, frontmatter, and duplicate routes.
43
+ - Run lint/format/typecheck when the repo's conventions call for them on docs changes.
44
+ - Fix failures your edits caused; report pre-existing failures separately instead of fixing them in this PR.
45
+
46
+ 6. **Deliver.**
47
+ - **Changes made:** commit only the maintenance edits, push the `blume/*` branch, and open or update a PR against the default branch titled like `blume: refresh docs for YYYY-MM-DD`. In the body list sources checked, docs changed, verification commands and results, skipped checks, and residual risk.
48
+ - **No changes needed:** report the PRs and docs areas checked and the no-op result. Do not create a branch, commit, or PR.
49
+
50
+ ## Resources
51
+
52
+ - `references/audit-checklist.md` — the source checklist, edit/skip criteria, and Blume-specific editing guidance. Read it before making docs changes.
@@ -0,0 +1,46 @@
1
+ # Audit checklist
2
+
3
+ Use this checklist to decide whether a docs-maintenance run should make changes.
4
+
5
+ ## Sources to check
6
+
7
+ - **Repo instructions:** `AGENTS.md`, `CLAUDE.md`, contribution docs, release docs, PR templates, and package scripts.
8
+ - **Blume config:** `blume.config.ts` — `content.root`, navigation (`meta.ts` files, tabs, selectors), site settings, AI/MCP settings, search, OpenAPI/AsyncAPI sources, theme, and export settings.
9
+ - **Public surface area:** exported package entrypoints, config schemas, component props, CLI commands and help text, route handlers, environment variables, and registry items.
10
+ - **User workflows:** quickstarts, examples, migration guides, deployment guides, screenshots, sample projects, and README snippets.
11
+ - **Recent merge signals:** PRs merged within the lookback window (default 7 days), changelogs, release notes, changesets, tags, and package version bumps.
12
+ - **Docs content:** every `.md`/`.mdx` page under the configured content root, plus custom pages and blog/changelog entries.
13
+ - **External dependencies:** official provider docs and release notes for linked integrations — only when the docs mention them or the dependency changed.
14
+ - **Generated docs surfaces:** `llms.txt`, raw Markdown URLs, MCP tools, OpenAPI pages, search, sitemap, robots, RSS, and OG behavior when relevant.
15
+
16
+ ## Change criteria
17
+
18
+ Make a docs edit when at least one condition is true:
19
+
20
+ - A command, config option, environment variable, route, CLI flag, component prop, or default value changed.
21
+ - A documented workflow no longer works or misses a required step.
22
+ - A page promises a feature, provider, adapter, or integration the code no longer supports.
23
+ - A new user-facing capability shipped but is absent from the appropriate docs page.
24
+ - A link points at moved, removed, or outdated primary documentation.
25
+ - A changelog or release page needs an entry for shipped user-facing behavior.
26
+
27
+ Skip the edit when the only available change is subjective polish, wording preference, duplicated information, speculative future work, or behavior still hidden behind a feature flag.
28
+
29
+ ## Blume editing guidance
30
+
31
+ - Keep frontmatter short and factual; use `title` and `description` consistently with nearby pages. Blume's frontmatter schema is **strict** — unknown keys are build errors.
32
+ - Preserve existing page order and `defineMeta` style; update `pages` arrays when adding, renaming, or removing pages.
33
+ - Use the Blume components already present in the docs (callout directives, steps, cards) instead of inventing new markup patterns.
34
+ - Match nearby code fences: filenames, language tags, and line numbers where the surrounding docs use them.
35
+ - Keep internal links root-relative (`/docs/...`).
36
+ - Do not edit generated `.blume/` or `dist/` output.
37
+
38
+ ## PR notes
39
+
40
+ Include these sections in the PR body or no-op summary:
41
+
42
+ - Sources checked
43
+ - Docs changed
44
+ - Verification run (commands and results)
45
+ - Skipped checks, with reasons
46
+ - Remaining risk or follow-up
@@ -432,11 +432,16 @@ const resolveLogo = (project: BlumeProject): BlumeLogo | null => {
432
432
  if (!logo) {
433
433
  return null;
434
434
  }
435
- const config = typeof logo === "string" ? { light: logo } : logo;
436
- const light = config.light ?? config.dark;
437
- const dark = config.dark ?? config.light;
438
- const alt = config.alt ?? "";
439
- const href = config.href ?? "/";
435
+ const config = typeof logo === "string" ? { image: logo } : logo;
436
+ // `text` is passed through verbatim: `undefined` lets the brand fall back to
437
+ // the site title, `""` renders the mark alone (a logo with the wordmark baked
438
+ // in).
439
+ const { href, image: source, text } = config;
440
+ const image = typeof source === "string" ? { light: source } : source;
441
+ const light = image?.light ?? image?.dark;
442
+ const dark = image?.dark ?? image?.light;
443
+ const alt = image?.alt ?? "";
444
+ const brandHref = href ?? "/";
440
445
 
441
446
  if (light && light === dark && light.toLowerCase().endsWith(".svg")) {
442
447
  const rel = light.replace(/^\//u, "");
@@ -445,10 +450,10 @@ const resolveLogo = (project: BlumeProject): BlumeLogo | null => {
445
450
  join(project.context.root, rel),
446
451
  ].find((path) => existsSync(path));
447
452
  if (file) {
448
- return { alt, href, svg: readFileSync(file, "utf-8") };
453
+ return { alt, href: brandHref, svg: readFileSync(file, "utf-8"), text };
449
454
  }
450
455
  }
451
- return { alt, dark, href, light };
456
+ return { alt, dark, href: brandHref, light, text };
452
457
  };
453
458
 
454
459
  /**
@@ -615,7 +620,6 @@ export const buildRuntimeData = (project: BlumeProject): string => {
615
620
  code,
616
621
  withReferenceTabs(
617
622
  graph.navigationByLocale[code] ?? {
618
- chromeVariants: [],
619
623
  selectors: [],
620
624
  sidebar: [],
621
625
  tabs: [],
@@ -648,7 +652,6 @@ export const buildRuntimeData = (project: BlumeProject): string => {
648
652
  })),
649
653
  }
650
654
  : null,
651
- icons: config.icons,
652
655
  imageZoom: config.markdown.imageZoom,
653
656
  logo: resolveLogo(project),
654
657
  mcp: config.mcp.enabled
@@ -974,9 +977,9 @@ export const generateRuntime = async (
974
977
  const staged = collectStaged(project);
975
978
  const hasStaged = staged.size > 0;
976
979
  // Only emit a project-scanning `docs` collection when a filesystem source
977
- // actually feeds it. Bridge mode has just the staged Mintlify source, so the
978
- // `docs` glob would otherwise scan (and watch) the whole project root for
979
- // nothing — see contentConfigTemplate.
980
+ // actually feeds it. An all-staged project (openapi/notion/…) has only staged
981
+ // sources, so the `docs` glob would otherwise scan (and watch) the whole
982
+ // project root for nothing — see contentConfigTemplate.
980
983
  const hasFilesystemSource = project.sources.some((source) => !source.staged);
981
984
 
982
985
  const structural = await Promise.all([
@@ -1,13 +1,10 @@
1
1
  import type { IncomingMessage, ServerResponse } from "node:http";
2
- import { fileURLToPath } from "node:url";
3
2
 
4
3
  import type { AstroIntegration } from "astro";
5
4
 
6
- import type { AssetMount } from "../core/assets.ts";
7
5
  import { enrichDiagnostic } from "../core/diagnostics.ts";
8
6
  import type { Diagnostic } from "../core/types.ts";
9
7
  import { markdownVariantUrl, prefersMarkdown } from "./markdown-negotiation.ts";
10
- import { copyAssetMounts, serveAssetMounts } from "./static-assets.ts";
11
8
 
12
9
  /** The dev server's HMR channel — either `.ws` (Vite ≤5) or `.hot` (Vite 6+). */
13
10
  interface OverlayChannel {
@@ -77,11 +74,6 @@ export interface BlumeIntegrationOptions {
77
74
  contentRoutes: string[];
78
75
  /** Configured `deployment.base`, stripped from dev URLs before matching. */
79
76
  base?: string;
80
- /**
81
- * `content.assets` mounts: top-level dirs served at the site root in dev and
82
- * copied into the build output, so root-served assets need no relocation.
83
- */
84
- assets?: AssetMount[];
85
77
  }
86
78
 
87
79
  /**
@@ -118,12 +110,6 @@ export const blumeIntegration = (
118
110
  options: BlumeIntegrationOptions
119
111
  ): AstroIntegration => ({
120
112
  hooks: {
121
- "astro:build:done": async ({ dir }) => {
122
- // Copy in-place asset mounts into the build output, mirroring publicDir.
123
- if (options.assets?.length) {
124
- await copyAssetMounts(options.assets, fileURLToPath(dir));
125
- }
126
- },
127
113
  "astro:config:setup": ({ injectRoute }) => {
128
114
  for (const page of options.pages) {
129
115
  injectRoute({
@@ -143,13 +129,6 @@ export const blumeIntegration = (
143
129
  handle: negotiateMarkdown(new Set(options.contentRoutes), options.base),
144
130
  route: "",
145
131
  });
146
- // Serve `content.assets` mounts (Astro only serves publicDir in dev).
147
- if (options.assets?.length) {
148
- server.middlewares.stack.unshift({
149
- handle: serveAssetMounts(options.assets),
150
- route: "",
151
- });
152
- }
153
132
  },
154
133
  },
155
134
  name: "blume",