blume@1.5.2
Patch Changes
- 7650327: Add
ai.ask.retrieval—maxResults,excerptChars, andcontextBudget— so a site can size how much documentation each Ask AI question injects into the model’s prompt. Injected characters are the dominant term in time-to-first-token, and on a self-hosted backend the fixed 10,000-character grounding could push a single question past 40 seconds. The three knobs stay separate because they aren’t interchangeable:contextBudgetcaps the total,excerptCharsdecides how deep into one long page an excerpt reaches, andmaxResultscaps how many pages retrieval adds (the page the reader is viewing is injected on top of them). Defaults are unchanged (6 / 2000 / 10000), so existing sites behave exactly as before. - 0c2c985: Try It message composer on native AsyncAPI operation pages. Each
send/receiveoperation ships an interactive Try it panel: a payload editor prefilled from the message’sexamples(or a value sampled from the payload schema when the message declares none) and validated against the payload schema as you type, an input per channel parameter, and a server picker fed by the channel’sserverswith a free-text URL override. The protocol-aware code samples (wscat, browserWebSocket,kcat,mosquitto_pub/mosquitto_sub) stay in lockstep with the form, filling the channel address template with the parameter values you type. Onws/wssbindings the panel also connects live to the resolved channel URL, shows connection state, sends composed messages, and logs received frames with timestamps — there’s no reconnect logic; other protocols get the composer and copyable CLI samples, since Blume doesn’t fake broker connectivity from a browser tab. The panel is server-rendered collapsed and loads its JavaScript only when a reader first opens it;asyncapi.playgroundmirrorsopenapi.playground, so it’s on by default with the native renderer andfalseturns it off.playground.proxystays OpenAPI-only, and no broker credentials are collected or persisted for event operations. - e2dbf74: Adopt Astro’s client router (
<ClientRouter />) for page navigation. Same-origin link clicks now swap the new page into the live document instead of tearing it down for a full load, so navigation is flicker-free in every browser — including Firefox, which has no cross-document paint holding and briefly flashed a blank frame between pages. Navigations animate with native view transitions where supported and Astro’s fade fallback elsewhere, both honoringprefers-reduced-motion; the sidebar keeps its scroll position across pages; search results navigate through the router too; and PostHog analytics captures a pageview per client-side navigation. The Scalar API reference intentionally keeps full-page loads (it is a SPA that mounts once per document), and the cross-document@view-transitionrule from the previous release is gone — the router supersedes it. - 97a9b30: Support a dark-mode favicon. A dark mark is invisible against dark browser chrome, so Blume now auto-detects a
-darksibling of your icon file — the same name and directory with-darkbefore the extension, likeicon.svg→icon-dark.svg— and emits both icons behindmedia="(prefers-color-scheme: …)", preceded by a plain light link so crawlers and browsers that ignore media queries on icons still get a sensible mark. Only the sibling of the icon Blume resolved is picked up, so an unrelated-darkfile can’t pair with your mark by accident. Ship one icon and nothing changes: a single<link rel="icon">, as before. The bundled Blume fallback now ships a light variant too, so a site with no icon of its own keeps a visible favicon in dark mode in browsers that honor media queries on icon links. - 2597b38: Ignore repo-locating
GIT_*environment variables (GIT_DIR,GIT_WORK_TREE,GIT_INDEX_FILEand friends) when resolving git last-modified dates and shallow-clone status. A parent git process exports an absoluteGIT_DIRto its hooks, so a build run from inside one — a husky hook, a post-merge script, a CI wrapper — silently read the wrong repository and dropped every page’s date. - 0c2c985: Try It playground on native OpenAPI operation pages. Each operation ships an interactive Try it panel: a form generated from the operation’s parameters and request-body schema, prefilled from the spec’s examples, with a server picker fed by the spec’s
serversand auth inputs matching the operation’s security schemes (bearer, API key, basic, and a token paste field for OAuth2). Values typed into the form update the generated code samples live, and Send fires the request directly from the browser — with an optional proxy for APIs that don’t allow cross-origin requests from the docs site (openapi.playground.proxy: a URL of your own, ortruefor the built-in/_api-proxyserver route). The panel is server-rendered collapsed and loads its JavaScript only when a reader first opens it; it’s on by default with the native renderer, andplayground: falseturns it off. - e31ff0a: Add
ai.openInChatto configure the “Open in chat” page action:falsehides it, and an array of provider keys ("v0","chatgpt","claude","t3","scira","cursor") shows just that subset, in order. - 5f41cbb: Keep the Ask AI panel alive across page navigations. The island now rides the client router with
transition:persist, so the conversation, a draft question, and the open panel all survive moving between pages instead of resetting on every click. The island re-anchors its portaled panel and the desktop content-push attribute after each swap, and the mobile overlay’s focus containment re-applies to the new page’s content. - 6eceaea: Segment search text for every non-Latin default locale, not just Japanese, Chinese, Korean, and Thai. Orama’s default tokenizer keeps only basic Latin letters and digits, so when
i18n.defaultLocalewas a Cyrillic, Greek, Hebrew, or Devanagari language the index collapsed to zero tokens and every query silently returned no hits. The script now comes fromIntl.Locale.maximize()—sr-Latnkeeps Orama’s tokenizer whileaz-Cyrlis segmented — with legacy tags (ja_JP.UTF-8,zh-cmn-Hans) resolved by their language subtag, and Latin terms on a segmented index fold diacritics so café still matches cafe. The tokenizer follows the default locale for the whole index, so non-Latin translations on a Latin-default site are unchanged. - 0c2c985: Harden the Try It playground: empty auth inputs no longer send their redaction placeholder as a real credential (the live request goes out anonymous instead), pre-network URL/header errors are reported as themselves rather than as a CORS failure, spec-derived names are escaped before selector interpolation, external proxy URLs that already carry a query string join with
&, blank required parameters stay visible in samples and sends, and mid-edit invalid JSON renders as a string literal in the JS/Python samples instead of broken syntax. The AsyncAPI composer now connects with an empty payload editor, prefills channel parameters from declared defaults/examples/enums instead of the sampler literalstring, and degrades a no-example, no-schema payload to{}rather thannull. The built-in CORS proxy allowlist skips templated server URLs, and a proxy with no allowable origin warns at build time. - c289eff: Stop
blume validatereporting colocated images as broken assets. A relative image embed () — the form the docs recommend for local images, since those are optimized at build time — was resolved into a site route and then looked for underpublic/, where it never lands: the image pipeline emits it to_astro/from beside the content. Every such reference came back asBLUME_BROKEN_ASSET, so--strictfailed on a site whose pages render the image correctly. Validation now accepts an image embed whose file exists next to its page source, passing the raw target through the same resolver that decides which colocated images the/blume-assets/contentendpoint serves, so the two can’t disagree about what one is. Everything that resolver would skip is still reported: a plain link to a relative path (only image nodes go through the pipeline), a?query/#fragmentsuffix, a case-mismatched or directory-shaped name (which breaks on the case-sensitive production build), and a reference that resolves nowhere — the last with a diagnostic that points at the page’s folder rather thanpublic/, and even when nopublic/directory exists. - 1517f9c: Fix the sidebar rendering empty on archived version pages when header tabs are configured. A version tree’s navigation root is versionized while tab paths stay in current-docs space, so the root tab was misread as a section tab that owns no group in the snapshot; it is now recognized as the root tab — via a single shared containment check used by sidebar scoping, tab-section pruning, and hoisting alike — and the archived sidebar renders its full tree. Header tabs also no longer claim
aria-currenton archived pages: they link back to the current docs, so none of them is the current page there.