blume 1.5.3 → 1.6.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/CHANGELOG.md +94 -0
- package/dist/cli/index.js +3949 -1403
- package/dist/cli/index.js.map +111 -96
- package/dist/types/ai/component-markdown.d.ts +79 -0
- package/dist/types/components/layout/nav-utils.d.ts +60 -0
- package/dist/types/core/base-path.d.ts +9 -0
- package/dist/types/core/config-input.d.ts +206 -4
- package/dist/types/core/config.d.ts +6 -4
- package/dist/types/core/data.d.ts +33 -2
- package/dist/types/core/github.d.ts +35 -0
- package/dist/types/core/i18n-ui.d.ts +10 -0
- package/dist/types/core/navigation.d.ts +69 -0
- package/dist/types/core/schema.d.ts +122 -1
- package/dist/types/core/sources/types.d.ts +31 -6
- package/dist/types/core/types.d.ts +29 -2
- package/dist/types/markdown/features.d.ts +21 -0
- package/dist/types/openapi/references.d.ts +26 -1
- package/dist/types/seo/jsonld.d.ts +105 -0
- package/dist/types/theme/fonts.d.ts +34 -4
- package/docs/07-faq.mdx +9 -9
- package/docs/_snippets/include-demo.mdx +7 -0
- package/docs/advanced/api-reference.mdx +13 -4
- package/docs/advanced/custom-pages.mdx +4 -2
- package/docs/advanced/graphql.mdx +84 -0
- package/docs/advanced/meta.ts +8 -1
- package/docs/configuration/ai.mdx +25 -3
- package/docs/configuration/index.mdx +24 -0
- package/docs/configuration/search.mdx +13 -1
- package/docs/configuration/seo.mdx +30 -3
- package/docs/configuration/theming.mdx +23 -0
- package/docs/content/components.mdx +15 -1
- package/docs/content/includes.mdx +68 -0
- package/docs/content/meta.ts +1 -0
- package/docs/content/navigation.mdx +25 -0
- package/docs/content/sources.mdx +42 -1
- package/docs/content/syntax.mdx +69 -1
- package/docs/content/versioning.mdx +15 -9
- package/docs/reference/cli.mdx +2 -1
- package/package.json +66 -57
- package/skills/blume-migrate/SKILL.md +16 -7
- package/skills/blume-migrate/references/docusaurus.md +5 -3
- package/skills/blume-migrate/references/fumadocs.md +10 -2
- package/skills/blume-migrate/references/mintlify.md +3 -2
- package/skills/blume-migrate/references/nextra.md +2 -2
- package/skills/blume-migrate/references/starlight.md +1 -1
- package/src/ai/agent-readability.ts +2 -1
- package/src/ai/ask-data.ts +2 -1
- package/src/ai/component-markdown.ts +199 -36
- package/src/ai/llms.ts +93 -6
- package/src/ai/markdown.ts +2 -2
- package/src/ai/mcp/discovery.ts +10 -2
- package/src/ai/mcp/server.ts +74 -2
- package/src/astro/examples.ts +29 -2
- package/src/astro/generate.ts +282 -177
- package/src/astro/include-hmr.ts +81 -0
- package/src/astro/include-refresh.ts +0 -0
- package/src/astro/index.ts +10 -5
- package/src/astro/markdown-negotiation.ts +1 -1
- package/src/astro/runtime-modules.ts +196 -0
- package/src/astro/templates.ts +365 -113
- package/src/cli/commands/build.ts +91 -16
- package/src/cli/commands/dev.ts +6 -3
- package/src/cli/host-args.ts +18 -0
- package/src/cli/index.ts +2 -1
- package/src/cli/init/questions.ts +1 -0
- package/src/cli/init/scaffold.ts +27 -4
- package/src/components/colors.ts +142 -0
- package/src/components/content/Badge.astro +5 -12
- package/src/components/content/Callout.astro +19 -36
- package/src/components/content/Card.astro +15 -21
- package/src/components/content/Component.astro +10 -1
- package/src/components/content/GithubInfo.astro +28 -9
- package/src/components/content/Tabs.astro +27 -5
- package/src/components/content/github-info.ts +20 -5
- package/src/components/copy-feedback.ts +93 -9
- package/src/components/dropdown-dismiss.ts +122 -0
- package/src/components/islands/ask-ai.tsx +4 -1
- package/src/components/islands/hooks.ts +3 -1
- package/src/components/layout/Fonts.astro +15 -8
- package/src/components/layout/Header.astro +44 -0
- package/src/components/layout/LanguageSwitcher.astro +9 -1
- package/src/components/layout/NavSelector.astro +12 -3
- package/src/components/layout/NavTree.astro +6 -18
- package/src/components/layout/PageActions.astro +54 -22
- package/src/components/layout/PageLayout.astro +2 -0
- package/src/components/layout/ReferenceLayout.astro +6 -1
- package/src/components/layout/RootLayout.astro +42 -15
- package/src/components/layout/Search.astro +36 -4
- package/src/components/layout/TableOfContents.astro +8 -2
- package/src/components/layout/head-scripts.ts +30 -1
- package/src/components/openapi/ApiOverview.astro +13 -3
- package/src/components/openapi/AsyncApiOperation.astro +7 -14
- package/src/components/openapi/GraphqlChip.astro +33 -0
- package/src/components/openapi/GraphqlFieldsTable.astro +111 -0
- package/src/components/openapi/GraphqlOperation.astro +186 -0
- package/src/components/openapi/GraphqlType.astro +154 -0
- package/src/components/openapi/MethodBadge.astro +3 -14
- package/src/components/openapi/Operation.astro +12 -5
- package/src/components/openapi/OperationPanel.astro +43 -0
- package/src/components/openapi/RequestPanel.astro +5 -10
- package/src/components/openapi/Responses.astro +1 -16
- package/src/components/openapi/graphql-helpers.ts +466 -0
- package/src/components/openapi/playground-client.ts +15 -0
- package/src/components/openapi/sample-panels.ts +45 -0
- package/src/components/openapi/snippets.ts +13 -35
- package/src/core/base-path.ts +11 -0
- package/src/core/config-input.ts +209 -2
- package/src/core/config.ts +6 -4
- package/src/core/content-assets.ts +15 -4
- package/src/core/data.ts +28 -3
- package/src/core/define-components.ts +2 -0
- package/src/core/diagnostics.ts +8 -0
- package/src/core/frontmatter.ts +20 -8
- package/src/core/github.ts +71 -0
- package/src/core/graph.ts +22 -8
- package/src/core/heading-markers.ts +96 -0
- package/src/core/i18n-ui.ts +12 -0
- package/src/core/includes.ts +633 -0
- package/src/core/last-modified.ts +36 -11
- package/src/core/links.ts +79 -13
- package/src/core/manifest.ts +10 -0
- package/src/core/meta.ts +2 -1
- package/src/core/nav-diagnostics.ts +11 -2
- package/src/core/navigation.ts +27 -6
- package/src/core/project-graph.ts +61 -9
- package/src/core/schema.ts +235 -36
- package/src/core/server-features.ts +5 -9
- package/src/core/sources/github-releases.ts +2 -2
- package/src/core/sources/normalize.ts +502 -115
- package/src/core/sources/notion.ts +43 -8
- package/src/core/sources/obsidian.ts +1038 -0
- package/src/core/sources/read.ts +36 -1
- package/src/core/sources/resolve.ts +34 -1
- package/src/core/sources/types.ts +28 -6
- package/src/core/sources/watch.ts +12 -8
- package/src/core/tsconfig-aliases.ts +48 -35
- package/src/core/types.ts +31 -2
- package/src/core/ui-packs/ar.ts +2 -0
- package/src/core/ui-packs/bg.ts +3 -0
- package/src/core/ui-packs/bn.ts +2 -0
- package/src/core/ui-packs/ca.ts +3 -0
- package/src/core/ui-packs/cs.ts +2 -0
- package/src/core/ui-packs/da.ts +2 -0
- package/src/core/ui-packs/de.ts +3 -0
- package/src/core/ui-packs/el.ts +3 -0
- package/src/core/ui-packs/es.ts +3 -0
- package/src/core/ui-packs/fa.ts +2 -0
- package/src/core/ui-packs/fi.ts +2 -0
- package/src/core/ui-packs/fr.ts +3 -0
- package/src/core/ui-packs/he.ts +2 -0
- package/src/core/ui-packs/hi.ts +2 -0
- package/src/core/ui-packs/hr.ts +3 -0
- package/src/core/ui-packs/hu.ts +3 -0
- package/src/core/ui-packs/id.ts +3 -0
- package/src/core/ui-packs/it.ts +2 -0
- package/src/core/ui-packs/ja.ts +3 -0
- package/src/core/ui-packs/ko.ts +3 -0
- package/src/core/ui-packs/nl.ts +3 -0
- package/src/core/ui-packs/no.ts +3 -0
- package/src/core/ui-packs/pl.ts +3 -0
- package/src/core/ui-packs/pt-br.ts +3 -0
- package/src/core/ui-packs/pt.ts +3 -0
- package/src/core/ui-packs/ro.ts +3 -0
- package/src/core/ui-packs/ru.ts +3 -0
- package/src/core/ui-packs/sk.ts +2 -0
- package/src/core/ui-packs/sr.ts +2 -0
- package/src/core/ui-packs/sv.ts +3 -0
- package/src/core/ui-packs/th.ts +2 -0
- package/src/core/ui-packs/tr.ts +3 -0
- package/src/core/ui-packs/uk.ts +3 -0
- package/src/core/ui-packs/vi.ts +2 -0
- package/src/core/ui-packs/zh-tw.ts +2 -0
- package/src/core/ui-packs/zh.ts +2 -0
- package/src/core/version-cut.ts +26 -6
- package/src/core/yaml.ts +26 -0
- package/src/deploy/function-bundle.ts +251 -0
- package/src/deploy/vercel-negotiation.ts +49 -6
- package/src/eval/schema.ts +3 -1
- package/src/markdown/code-title.ts +22 -16
- package/src/markdown/features.ts +21 -0
- package/src/markdown/fence-meta.ts +50 -0
- package/src/markdown/heading-anchors.ts +198 -37
- package/src/markdown/include.ts +247 -0
- package/src/markdown/index.ts +43 -34
- package/src/markdown/language-icon.ts +2 -2
- package/src/markdown/mdast.ts +7 -3
- package/src/markdown/ts2js.ts +264 -0
- package/src/og/card.ts +1 -1
- package/src/openapi/asyncapi.ts +4 -1
- package/src/openapi/graphql-build.ts +293 -0
- package/src/openapi/graphql.ts +212 -0
- package/src/openapi/model.ts +38 -5
- package/src/openapi/parse.ts +34 -0
- package/src/openapi/proxy.ts +30 -5
- package/src/openapi/references.ts +97 -13
- package/src/openapi/render-mdx.ts +66 -12
- package/src/openapi/scalar.ts +5 -16
- package/src/openapi/source.ts +91 -23
- package/src/registry/eject.ts +47 -17
- package/src/search/documents.ts +229 -37
- package/src/search/orama-index.ts +9 -5
- package/src/seo/jsonld.ts +293 -51
- package/src/theme/code-block-padding.ts +16 -0
- package/src/theme/entry.ts +67 -13
- package/src/theme/fonts.ts +189 -16
- package/src/theme/sources.ts +49 -0
- package/src/translate/prompts.ts +2 -0
- package/src/translate/run.ts +7 -0
- package/src/translate/work-list.ts +0 -0
package/src/ai/markdown.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { readFile } from "node:fs/promises";
|
|
|
3
3
|
import { rewriteRelativeImages } from "../core/content-assets.ts";
|
|
4
4
|
import matter from "../core/frontmatter.ts";
|
|
5
5
|
import type { BlumeProject } from "../core/project-graph.ts";
|
|
6
|
-
import {
|
|
6
|
+
import { readExpandedEntryText } from "../core/sources/read.ts";
|
|
7
7
|
import type { RouteManifestEntry } from "../core/types.ts";
|
|
8
8
|
import {
|
|
9
9
|
downlevelComponents,
|
|
@@ -65,7 +65,7 @@ export const buildRawMarkdown = async (
|
|
|
65
65
|
const readRoute = async (route: RouteManifestEntry): Promise<string> => {
|
|
66
66
|
const page = pageById.get(route.id);
|
|
67
67
|
if (page) {
|
|
68
|
-
return await
|
|
68
|
+
return await readExpandedEntryText(project, page);
|
|
69
69
|
}
|
|
70
70
|
return route.sourcePath ? await readFile(route.sourcePath, "utf-8") : "";
|
|
71
71
|
};
|
package/src/ai/mcp/discovery.ts
CHANGED
|
@@ -103,7 +103,10 @@ const HTTP_URL = /^https?:\/\//u;
|
|
|
103
103
|
*/
|
|
104
104
|
export interface McpServerCard {
|
|
105
105
|
$schema: string;
|
|
106
|
-
capabilities: {
|
|
106
|
+
capabilities: {
|
|
107
|
+
resources: { listChanged: boolean; subscribe: boolean };
|
|
108
|
+
tools: { listChanged: boolean };
|
|
109
|
+
};
|
|
107
110
|
description: string;
|
|
108
111
|
name: string;
|
|
109
112
|
/** Absolute endpoints only — present when a `site` is configured. */
|
|
@@ -122,7 +125,12 @@ export const buildMcpServerCard = (input: McpDiscoveryInput): McpServerCard => {
|
|
|
122
125
|
const url = serverUrl(input);
|
|
123
126
|
const card: McpServerCard = {
|
|
124
127
|
$schema: SERVER_CARD_SCHEMA,
|
|
125
|
-
|
|
128
|
+
// Resources mirror the page list (one `text/markdown` resource per page);
|
|
129
|
+
// a rebuilt site replaces the server wholesale, so nothing changes live.
|
|
130
|
+
capabilities: {
|
|
131
|
+
resources: { listChanged: false, subscribe: false },
|
|
132
|
+
tools: { listChanged: false },
|
|
133
|
+
},
|
|
126
134
|
description: truncate(
|
|
127
135
|
`Model Context Protocol server for the ${input.name} documentation.`
|
|
128
136
|
),
|
package/src/ai/mcp/server.ts
CHANGED
|
@@ -3,7 +3,10 @@ import type { ServerOptions } from "@modelcontextprotocol/sdk/server/index.js";
|
|
|
3
3
|
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
4
4
|
import {
|
|
5
5
|
CallToolRequestSchema,
|
|
6
|
+
ListResourcesRequestSchema,
|
|
6
7
|
ListToolsRequestSchema,
|
|
8
|
+
McpError,
|
|
9
|
+
ReadResourceRequestSchema,
|
|
7
10
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
8
11
|
import { z } from "zod";
|
|
9
12
|
|
|
@@ -33,6 +36,12 @@ const DEFAULT_SEARCH_LIMIT = 8;
|
|
|
33
36
|
const MAX_SEARCH_LIMIT = 20;
|
|
34
37
|
/** Excerpt length when a page has no description. */
|
|
35
38
|
const EXCERPT_LENGTH = 200;
|
|
39
|
+
/** Every page resource is the page's agent Markdown. */
|
|
40
|
+
const RESOURCE_MIME_TYPE = "text/markdown";
|
|
41
|
+
/** The MCP spec's JSON-RPC code for an unknown resource URI. */
|
|
42
|
+
const RESOURCE_NOT_FOUND = -32_002;
|
|
43
|
+
/** URI scheme for page resources when no `deployment.site` is configured. */
|
|
44
|
+
const LOCAL_RESOURCE_SCHEME = "blume:";
|
|
36
45
|
|
|
37
46
|
const CORS_HEADERS = {
|
|
38
47
|
"Access-Control-Allow-Headers":
|
|
@@ -191,6 +200,15 @@ interface SearchHitPayload {
|
|
|
191
200
|
version?: string;
|
|
192
201
|
}
|
|
193
202
|
|
|
203
|
+
/** One `resources/list` entry: a page served as `text/markdown`. */
|
|
204
|
+
interface PageResource {
|
|
205
|
+
description?: string;
|
|
206
|
+
mimeType: string;
|
|
207
|
+
name: string;
|
|
208
|
+
title: string;
|
|
209
|
+
uri: string;
|
|
210
|
+
}
|
|
211
|
+
|
|
194
212
|
/** One `list_pages` entry; `version` only appears on versioned sites. */
|
|
195
213
|
interface PageListingPayload {
|
|
196
214
|
contentType: string;
|
|
@@ -288,6 +306,26 @@ const urlFor = (route: string, data: McpData): string => {
|
|
|
288
306
|
return data.site ? absoluteUrl(data.site, path) : path;
|
|
289
307
|
};
|
|
290
308
|
|
|
309
|
+
/**
|
|
310
|
+
* A page's resource URI. Resource URIs must be absolute, so this is the page's
|
|
311
|
+
* served URL when a site is configured (the same URL `search_docs` and
|
|
312
|
+
* `list_pages` emit, so an agent can hand either back to `resources/read`),
|
|
313
|
+
* and a `blume:` URI carrying the based route otherwise.
|
|
314
|
+
*/
|
|
315
|
+
const resourceUri = (route: string, data: McpData): string =>
|
|
316
|
+
data.site
|
|
317
|
+
? urlFor(route, data)
|
|
318
|
+
: `${LOCAL_RESOURCE_SCHEME}${withBasePath(data.base, route)}`;
|
|
319
|
+
|
|
320
|
+
/** The `pages` key a resource URI (either form, or a bare route) names. */
|
|
321
|
+
const resourceRoute = (uri: string, data: McpData): string =>
|
|
322
|
+
normalizeRoute(
|
|
323
|
+
uri.startsWith(LOCAL_RESOURCE_SCHEME)
|
|
324
|
+
? uri.slice(LOCAL_RESOURCE_SCHEME.length)
|
|
325
|
+
: uri,
|
|
326
|
+
data
|
|
327
|
+
);
|
|
328
|
+
|
|
291
329
|
/** A hit's excerpt: its description, else the head of its content with an
|
|
292
330
|
* ellipsis only when something was actually cut off. */
|
|
293
331
|
const excerptFor = (doc: OramaDoc): string => {
|
|
@@ -331,9 +369,10 @@ export const buildServer = (
|
|
|
331
369
|
data: McpData,
|
|
332
370
|
index: OramaIndexProvider
|
|
333
371
|
): Server => {
|
|
372
|
+
const capabilities = { resources: {}, tools: {} };
|
|
334
373
|
const serverOptions: ServerOptions = data.instructions
|
|
335
|
-
? { capabilities
|
|
336
|
-
: { capabilities
|
|
374
|
+
? { capabilities, instructions: data.instructions }
|
|
375
|
+
: { capabilities };
|
|
337
376
|
const server = new Server(
|
|
338
377
|
{ name: data.name, version: data.version },
|
|
339
378
|
serverOptions
|
|
@@ -343,6 +382,39 @@ export const buildServer = (
|
|
|
343
382
|
tools: TOOL_DEFINITIONS,
|
|
344
383
|
}));
|
|
345
384
|
|
|
385
|
+
// Every page doubles as a resource, so a client that attaches context by
|
|
386
|
+
// URI (rather than calling tools) can browse and read the docs too. The
|
|
387
|
+
// list is the same route set `list_pages` returns; reading one serves the
|
|
388
|
+
// same agent Markdown `get_page` does.
|
|
389
|
+
server.setRequestHandler(ListResourcesRequestSchema, () => ({
|
|
390
|
+
resources: data.routes.map((route) => {
|
|
391
|
+
const resource: PageResource = {
|
|
392
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
393
|
+
name: route.title,
|
|
394
|
+
title: route.title,
|
|
395
|
+
uri: resourceUri(route.route, data),
|
|
396
|
+
};
|
|
397
|
+
if (route.description) {
|
|
398
|
+
resource.description = route.description;
|
|
399
|
+
}
|
|
400
|
+
return resource;
|
|
401
|
+
}),
|
|
402
|
+
}));
|
|
403
|
+
|
|
404
|
+
server.setRequestHandler(ReadResourceRequestSchema, (request) => {
|
|
405
|
+
const { uri } = request.params;
|
|
406
|
+
const markdown = data.pages[resourceRoute(uri, data)];
|
|
407
|
+
if (markdown === undefined) {
|
|
408
|
+
throw new McpError(
|
|
409
|
+
RESOURCE_NOT_FOUND,
|
|
410
|
+
`No page found at "${uri}". Use resources/list or list_pages to find valid URIs.`
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
return {
|
|
414
|
+
contents: [{ mimeType: RESOURCE_MIME_TYPE, text: markdown, uri }],
|
|
415
|
+
};
|
|
416
|
+
});
|
|
417
|
+
|
|
346
418
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
347
419
|
const { arguments: args = {}, name } = request.params;
|
|
348
420
|
|
package/src/astro/examples.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
|
|
3
3
|
import pMap from "p-map";
|
|
4
|
-
import { join, relative } from "pathe";
|
|
4
|
+
import { isAbsolute, join, relative } from "pathe";
|
|
5
5
|
import { glob } from "tinyglobby";
|
|
6
6
|
|
|
7
7
|
import type { ExampleLookup } from "../core/types.ts";
|
|
@@ -28,6 +28,11 @@ export interface ExampleSpec {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
export interface ExampleDiscovery {
|
|
31
|
+
/**
|
|
32
|
+
* Absolute directory the examples were discovered under: the configured
|
|
33
|
+
* `examples.source` (or a glob's static prefix) resolved against the root.
|
|
34
|
+
*/
|
|
35
|
+
dir: string;
|
|
31
36
|
examples: ExampleSpec[];
|
|
32
37
|
warnings: string[];
|
|
33
38
|
}
|
|
@@ -56,6 +61,28 @@ const DEFAULT_EXAMPLE_GLOB = "**/*.{astro,jsx,svelte,tsx,vue}";
|
|
|
56
61
|
/** Ceiling on concurrent example-file reads; unbounded fan-out risks EMFILE. */
|
|
57
62
|
const READ_CONCURRENCY = 16;
|
|
58
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Files the preview-frame Tailwind entry scans for utility classes, appended
|
|
66
|
+
* to each directory from `exampleScanRoots`.
|
|
67
|
+
*/
|
|
68
|
+
export const EXAMPLE_SCAN_GLOB = "**/*.{astro,jsx,svelte,ts,tsx,vue}";
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Directories the `<Component />` preview sheet scans for utility classes:
|
|
72
|
+
* the project root, plus the examples directory when it lives outside the
|
|
73
|
+
* root (a sibling workspace package, say). Tailwind's `@source` is a file
|
|
74
|
+
* glob, not an import graph, so an out-of-root examples directory would
|
|
75
|
+
* otherwise contribute no utilities and previews would render half-styled.
|
|
76
|
+
*/
|
|
77
|
+
export const exampleScanRoots = (
|
|
78
|
+
root: string,
|
|
79
|
+
examplesDir: string
|
|
80
|
+
): string[] => {
|
|
81
|
+
const path = relative(root, examplesDir);
|
|
82
|
+
const outside = path.startsWith("..") || isAbsolute(path);
|
|
83
|
+
return outside ? [root, examplesDir] : [root];
|
|
84
|
+
};
|
|
85
|
+
|
|
59
86
|
// Glob magic that turns `examples` from a plain directory into a pattern. `()`,
|
|
60
87
|
// `@`, and `+` are excluded so literal path segments (npm scopes, parens) keep
|
|
61
88
|
// resolving as directories; the extglob leads `*?!` still trigger here.
|
|
@@ -153,7 +180,7 @@ export const discoverExamples = async (
|
|
|
153
180
|
collectExample(file, sources[index] ?? "");
|
|
154
181
|
}
|
|
155
182
|
|
|
156
|
-
return { examples, warnings };
|
|
183
|
+
return { dir, examples, warnings };
|
|
157
184
|
};
|
|
158
185
|
|
|
159
186
|
/**
|