blume 1.1.4 → 1.2.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.
- package/CHANGELOG.md +19 -0
- package/README.md +1 -1
- package/dist/cli/index.js +1286 -63
- package/dist/cli/index.js.map +32 -21
- package/dist/types/core/config-input.d.ts +18 -0
- package/dist/types/core/config.d.ts +4 -0
- package/dist/types/core/data.d.ts +1 -0
- package/dist/types/core/schema.d.ts +132 -17
- package/dist/types/core/types.d.ts +5 -3
- package/dist/types/openapi/references.d.ts +6 -0
- package/docs/advanced/api-reference.mdx +27 -0
- package/docs/advanced/changelog.mdx +10 -0
- package/docs/configuration/ai.mdx +38 -2
- package/docs/configuration/customization.mdx +27 -0
- package/docs/configuration/index.mdx +5 -0
- package/docs/content/navigation.mdx +12 -0
- package/docs/reference/cli.mdx +17 -13
- package/docs/reference/eval.mdx +106 -0
- package/docs/reference/meta.ts +1 -1
- package/package.json +1 -1
- package/src/ai/agent-readability.ts +19 -1
- package/src/ai/llms.ts +9 -4
- package/src/ai/mcp/server.ts +19 -8
- package/src/ai/mcp/stdio.ts +35 -0
- package/src/astro/generate.ts +25 -2
- package/src/astro/templates.ts +114 -22
- package/src/cli/commands/eval.ts +291 -0
- package/src/cli/commands/init.ts +9 -4
- package/src/cli/commands/mcp-stdio.ts +36 -0
- package/src/cli/index.ts +4 -0
- package/src/cli/required-secrets.ts +1 -1
- package/src/components/content/AccordionItem.astro +2 -2
- package/src/components/content/TreeFolder.astro +1 -2
- package/src/components/islands/AskAI.astro +9 -2
- package/src/components/islands/ask-ai.tsx +4 -2
- package/src/components/islands/hooks.ts +10 -4
- package/src/components/layout/NavTree.astro +37 -19
- package/src/components/layout/ReferenceLayout.astro +4 -0
- package/src/components/layout/RootLayout.astro +1 -1
- package/src/components/openapi/SchemaProperty.astro +3 -3
- package/src/core/config-input.ts +18 -0
- package/src/core/config.ts +4 -0
- package/src/core/data.ts +1 -0
- package/src/core/graph.ts +1 -0
- package/src/core/navigation.ts +9 -2
- package/src/core/schema.ts +51 -4
- package/src/core/server-features.ts +1 -1
- package/src/core/types.ts +5 -3
- package/src/eval/agents.ts +340 -0
- package/src/eval/findings.ts +103 -0
- package/src/eval/prompts.ts +78 -0
- package/src/eval/report.ts +214 -0
- package/src/eval/run.ts +290 -0
- package/src/eval/schema.ts +124 -0
- package/src/openapi/references.ts +23 -2
- package/src/openapi/render-mdx.ts +27 -4
- package/src/openapi/scalar.ts +1 -0
- package/src/openapi/source.ts +11 -4
- package/src/registry/eject.ts +23 -1
- package/src/search/build.ts +4 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ApiOperationRef, ApiSpecData } from "./model.ts";
|
|
2
|
+
import type { ReferenceSource } from "./references.ts";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Lower a parsed spec into MDX for the staged content source. Each operation and
|
|
@@ -126,7 +127,11 @@ const withDescription = (description: string, component: string): string =>
|
|
|
126
127
|
|
|
127
128
|
export const operationMdx = (
|
|
128
129
|
spec: ApiSpecData,
|
|
129
|
-
operation: ApiOperationRef
|
|
130
|
+
operation: ApiOperationRef,
|
|
131
|
+
reference?: Pick<
|
|
132
|
+
ReferenceSource,
|
|
133
|
+
"includeInLlms" | "includeInSearch" | "noindex"
|
|
134
|
+
>
|
|
130
135
|
): RenderedPage => {
|
|
131
136
|
const method = operation.method.toUpperCase();
|
|
132
137
|
const title = operation.summary || `${method} ${operation.path}`;
|
|
@@ -142,9 +147,16 @@ export const operationMdx = (
|
|
|
142
147
|
`<Operation source="${spec.slug}" id="${operation.key}" />`
|
|
143
148
|
),
|
|
144
149
|
data: {
|
|
150
|
+
...(reference?.includeInLlms === false ? { ai: { exclude: true } } : {}),
|
|
145
151
|
...(operation.deprecated ? { deprecated: true } : {}),
|
|
146
|
-
search: {
|
|
147
|
-
|
|
152
|
+
search: {
|
|
153
|
+
...(reference?.includeInSearch === false ? { exclude: true } : {}),
|
|
154
|
+
tags: [operation.tag, method],
|
|
155
|
+
},
|
|
156
|
+
seo: {
|
|
157
|
+
description: operationDescription(spec, operation),
|
|
158
|
+
...(reference?.noindex ? { noindex: true } : {}),
|
|
159
|
+
},
|
|
148
160
|
sidebar: { badge: method, label: operation.summary || operation.path },
|
|
149
161
|
title,
|
|
150
162
|
// Signals the two-column API layout (request panel instead of the TOC).
|
|
@@ -153,7 +165,13 @@ export const operationMdx = (
|
|
|
153
165
|
};
|
|
154
166
|
};
|
|
155
167
|
|
|
156
|
-
export const overviewMdx = (
|
|
168
|
+
export const overviewMdx = (
|
|
169
|
+
spec: ApiSpecData,
|
|
170
|
+
reference?: Pick<
|
|
171
|
+
ReferenceSource,
|
|
172
|
+
"includeInLlms" | "includeInSearch" | "noindex"
|
|
173
|
+
>
|
|
174
|
+
): RenderedPage => {
|
|
157
175
|
// Tag sections: declared tags in spec order, then any tag an operation
|
|
158
176
|
// references that isn't declared under `tags`. The section headings are
|
|
159
177
|
// emitted as real markdown `##` (not markup inside a component) so the
|
|
@@ -205,10 +223,15 @@ export const overviewMdx = (spec: ApiSpecData): RenderedPage => {
|
|
|
205
223
|
...tagSections,
|
|
206
224
|
].join("\n\n"),
|
|
207
225
|
data: {
|
|
226
|
+
...(reference?.includeInLlms === false ? { ai: { exclude: true } } : {}),
|
|
227
|
+
...(reference?.includeInSearch === false
|
|
228
|
+
? { search: { exclude: true } }
|
|
229
|
+
: {}),
|
|
208
230
|
seo: {
|
|
209
231
|
description:
|
|
210
232
|
clip(plainProse(spec.description), META_DESCRIPTION_MAX) ||
|
|
211
233
|
`${apiName(spec)} API reference.`,
|
|
234
|
+
...(reference?.noindex ? { noindex: true } : {}),
|
|
212
235
|
},
|
|
213
236
|
sidebar: { label: "Overview" },
|
|
214
237
|
title: apiName(spec),
|
package/src/openapi/scalar.ts
CHANGED
package/src/openapi/source.ts
CHANGED
|
@@ -53,17 +53,24 @@ const toEntry = (rendered: RenderedPage, ref: string): SourceEntry => {
|
|
|
53
53
|
/** All staged entries for one spec: operations first, overview last. */
|
|
54
54
|
const specEntries = (
|
|
55
55
|
spec: ApiSpecData,
|
|
56
|
-
operations: ApiOperationRef[]
|
|
56
|
+
operations: ApiOperationRef[],
|
|
57
|
+
reference: ReferenceSource
|
|
57
58
|
): SourceEntry[] => {
|
|
58
59
|
const entries = operations.map((operation) =>
|
|
59
|
-
toEntry(
|
|
60
|
+
toEntry(
|
|
61
|
+
operationMdx(spec, operation, reference),
|
|
62
|
+
`${routeToRef(operation.route)}.mdx`
|
|
63
|
+
)
|
|
60
64
|
);
|
|
61
65
|
// Overview last so an operation sets the section's routePath before the index
|
|
62
66
|
// page is inserted (the group's routePath is derived from its first child).
|
|
63
67
|
// A root-mounted reference refs `index.mdx`, not `/index.mdx`.
|
|
64
68
|
const base = routeToRef(spec.route);
|
|
65
69
|
entries.push(
|
|
66
|
-
toEntry(
|
|
70
|
+
toEntry(
|
|
71
|
+
overviewMdx(spec, reference),
|
|
72
|
+
base ? `${base}/index.mdx` : "index.mdx"
|
|
73
|
+
)
|
|
67
74
|
);
|
|
68
75
|
return entries;
|
|
69
76
|
};
|
|
@@ -149,7 +156,7 @@ export const openApiSource = (
|
|
|
149
156
|
]
|
|
150
157
|
: []),
|
|
151
158
|
],
|
|
152
|
-
entries: specEntries(spec, operations),
|
|
159
|
+
entries: specEntries(spec, operations, reference),
|
|
153
160
|
slug: reference.slug,
|
|
154
161
|
spec,
|
|
155
162
|
};
|
package/src/registry/eject.ts
CHANGED
|
@@ -112,7 +112,15 @@ const askFiles = async (
|
|
|
112
112
|
genDir: string
|
|
113
113
|
): Promise<{ content: string; path: string }[]> => {
|
|
114
114
|
const { ask } = project.config.ai;
|
|
115
|
-
if (!ask?.enabled) {
|
|
115
|
+
if (!(ask?.enabled && !ask.endpoint)) {
|
|
116
|
+
const endpointPath = join(srcDir, "pages", "api", "ask.ts");
|
|
117
|
+
if (existsSync(endpointPath)) {
|
|
118
|
+
const content = await readFile(endpointPath, "utf-8");
|
|
119
|
+
if (content.startsWith("// Generated by Blume. Do not edit.")) {
|
|
120
|
+
await rm(endpointPath, { force: true });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
await rm(join(genDir, "ask-data.json"), { force: true });
|
|
116
124
|
return [];
|
|
117
125
|
}
|
|
118
126
|
const grounded = ask.provider !== "inkeep";
|
|
@@ -271,6 +279,15 @@ const examplesPreviewFiles = (
|
|
|
271
279
|
]
|
|
272
280
|
: [];
|
|
273
281
|
|
|
282
|
+
const ejectIntegrationBridge = (
|
|
283
|
+
config: BlumeProject["config"],
|
|
284
|
+
root: string,
|
|
285
|
+
configFile: string | null
|
|
286
|
+
): Parameters<typeof astroConfigTemplate>[0]["integrationBridge"] =>
|
|
287
|
+
config.integrations.length > 0 && configFile
|
|
288
|
+
? { configFile: toPosix(relative(root, configFile)) }
|
|
289
|
+
: undefined;
|
|
290
|
+
|
|
274
291
|
/**
|
|
275
292
|
* Promote the generated runtime into the project as an owned Astro app. After
|
|
276
293
|
* eject the project has a normal `astro.config.mjs` and `src/`, the `blume` CLI
|
|
@@ -367,6 +384,11 @@ export const eject = async (
|
|
|
367
384
|
dataPath: "./src/generated/data.json",
|
|
368
385
|
examplesPath: "./src/generated/examples.ts",
|
|
369
386
|
examplesThemePath: "./src/generated/examples.css",
|
|
387
|
+
integrationBridge: ejectIntegrationBridge(
|
|
388
|
+
config,
|
|
389
|
+
root,
|
|
390
|
+
context.configFile
|
|
391
|
+
),
|
|
370
392
|
needsReact,
|
|
371
393
|
needsSvelte,
|
|
372
394
|
needsVue,
|
package/src/search/build.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { join } from "pathe";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Build a local Pagefind search index over the built site. Pagefind
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Build a local Pagefind search index over the built site. Pagefind indexes
|
|
5
|
+
* every rendered page except those whose `<html>` carries
|
|
6
|
+
* `data-pagefind-ignore`, which Blume stamps on non-indexable pages
|
|
7
|
+
* (search-excluded, or hidden without the opt-in), so those stay out.
|
|
7
8
|
*
|
|
8
9
|
* Returns the number of pages indexed.
|
|
9
10
|
*/
|