Skip to content

Releases: dgesteves/ondocs

starlight-ondocs@0.9.0

Choose a tag to compare

@github-actions github-actions released this 12 Oct 20:45
41990b8

Patch Changes

starlight-ondocs@0.10.0

Choose a tag to compare

@github-actions github-actions released this 12 Oct 23:51
bc5b649

Patch Changes

ondocs@0.9.0

Choose a tag to compare

@github-actions github-actions released this 12 Oct 20:45
41990b8

Minor Changes

  • #84 9276df9 Thanks @dgesteves! - One name per option across the endpoint, the dialog, the script tag, the plugins and the CLI. The old names still work, and say once what they are called now, until 0.10 removes them. Upgrading has the table, old name to new.

    • launcher replaces buttonLabel in mountAskDialog, window.Ondocs.mount() and the plugins' dialog options, each locale's included, as AskDialog already called it. It takes true, a label, or false. On the script tag, data-launcher replaces data-button-label.
    • theme: 'auto' replaces theme: 'system' on AskDialog, the name the plugins and the script tag use.
    • retrieval.maxContextChars replaces maxContextChars on createAskHandler, next to topK. The answer cache keeps its keys.
    • ondocs init --site-name replaces --name, as siteName names it in the handlers.

    Two defaults of AskDialog change to match the plugins and the script tag. It opens with ⌘I or Ctrl+I, so ⌘K stays with the site's search; shortcut="k" keeps ⌘K. Its default theme, auto, follows data-theme="light" or "dark" on <html> when the page sets one, and the system's setting otherwise, as before.

Patch Changes

  • #96 9b882ee Thanks @dgesteves! - Fixes from following the docs on a fresh install:

    • ondocs index --llms-txt resolves the relative links and images in Markdown files from each file's folder, so they work from the page's .md copy and from llms-full.txt. Before, content/index.md, copied to /docs.md, kept ./setup.md as written, which pointed at /setup.md there instead of /docs/setup.md. A link to another page's file goes to that page's copy. An HTML index.html page's links are now resolved from its folder too.
    • ondocs init no longer takes a docusaurus deploy script for GitHub Pages: every new Docusaurus site has one, wherever it is hosted. With no host config, init asks, as the docs say. The gh-pages package, a script that runs it, and a Pages workflow still count.
    • For GitHub Pages, init asks for the site's URL when the config has a template's placeholder, such as https://your-docusaurus-site.example.com, and warns when it keeps one: the Worker reads the index from that URL.
    • When the site's config already adds the ondocs plugin, init's next steps no longer say to add it. On GitHub Pages they say which options to give it.
    • On a site with no config to detect, the error now says how to name a plain HTML site's folder, as in npx ondocs init --out public, and names the folder when it finds one with HTML files.
    • For a site indexed with ondocs index (Next.js and static sites), init says that a keyword-only index needs -e none when there is no key. The plugins build one without a key, but the CLI stops.
  • #87 5409b87 Thanks @dgesteves! - ondocs index, and loadDirectory with framework: 'next' or 'auto', now cite Fumadocs and Nextra pages at the URLs those frameworks serve. On any Next.js site, page.mdx and Index.mdx in a content folder are pages of their own, and an app folder is read as Next.js routes it: only page.mdx files, without _private folders. Nextra keeps (group) folders in the URL, and a ## Title [#id] heading is cited at #id. frameworkUrl is unchanged.

  • #76 153760b Thanks @dgesteves! - ondocs init on a static site (Hugo, Jekyll, MkDocs, Eleventy or plain HTML) on Vercel, Netlify or Cloudflare now lists the packages its functions import, ondocs ai @ai-sdk/openai, in its next steps. A site with no package.json gets npm init -y && npm i ondocs ai @ai-sdk/openai, since the host installs the functions' packages from one. Before, the steps left out ai and @ai-sdk/openai, or said nothing without a package.json, and the functions failed to build.

  • #81 7858807 Thanks @dgesteves! - docusaurus-plugin-ondocs and starlight-ondocs now publish to npm, at the same version as ondocs. They re-export ondocs/docusaurus and ondocs/starlight under the names Docusaurus and Starlight users search for, as the 0.7.0 release notes and the migration guide said, but until now they were left out of the publish, so npm i docusaurus-plugin-ondocs or npm i starlight-ondocs found nothing.

ondocs@0.10.0

Choose a tag to compare

@github-actions github-actions released this 12 Oct 23:51
bc5b649

Minor Changes

  • #107 c675e01 Thanks @dgesteves! - ondocs index now cites Nextra and Fumadocs headings at the ids those sites render (a mixed-case [#id] in a Nextra app page is lowercased, and footnote references such as [^1] are left out of the anchor and the heading's text, as on Docusaurus), resolves relative links in the .md copy of a page in a Nextra (group) folder from that folder, and frameworkUrl takes an optional routing, so it gives the URL loadDirectory gives for a content folder's page.mdx.

Patch Changes

  • #106 900f368 Thanks @dgesteves! - The Ask dialog no longer lists sources under an answer that cites none of them, shows a model reply of only "I don't know" as a refusal (the endpoint now marks it as one at the end of its stream), shows the question over an error, and shows a long question from its start in the input once it is asked.

docusaurus-plugin-ondocs@0.9.0

Choose a tag to compare

@github-actions github-actions released this 12 Oct 20:45
41990b8

Patch Changes

docusaurus-plugin-ondocs@0.10.0

Choose a tag to compare

@github-actions github-actions released this 12 Oct 23:51
bc5b649

Patch Changes

ondocs@0.8.0

Choose a tag to compare

@github-actions github-actions released this 11 Oct 09:09
50d31ea

Minor Changes

  • #69 bbe0f87 Thanks @dgesteves! - New entry, ondocs/integration: the build helpers the Docusaurus, Astro and Starlight plugins are made of, for a plugin for another framework. It reads the pages a build wrote (readBuiltHtml, loadBuiltPage), builds the embedding model (buildEmbedding), writes the index with the previous build's vectors (writeSiteIndex, indexCache) and the llms files (writeLlmsFiles), and adds the launcher to every page (launcherScript, LAUNCHER_STYLESHEETS). The plugins now build with it alone. See "Writing an integration" in the docs.

  • #73 4daccdf Thanks @dgesteves! - The Docusaurus, Astro, Starlight and VitePress plugins link each page to its Markdown copy. After the build, every page that has a .md copy gets <link rel="alternate" type="text/markdown" href="…"> in its <head>, with the site's base path and the page's locale, so an agent that fetches the page finds the copy. A page whose head already links a Markdown copy keeps its own, and no page is linked when llmsTxt turns the copies off or another plugin writes them. Each page's HTML is replaced in one step, so a Docusaurus plugin reading it in its own postBuild at the same time reads all of it. In ondocs/integration, writeLlmsFiles takes linkPages to do the same for another framework.

  • #71 d8a3e65 Thanks @dgesteves! - createAskHandler takes two retrieval hooks. retrieval.rerank(question, hits, { signal, index }) puts the candidates in a new order before topK is applied, with the AI SDK's rerank() and a reranking model, or to boost sections. retrieval.retrieve(query, search, context) finds the candidates instead of the built-in retrieval, with search to call it. The relevance gate decides after both: each hit's chunk is measured again against the question, so a hook cannot make an off-topic page count. A hook that throws is reported to onError and skipped. Without hooks, retrieval is unchanged. gateHits, the gate on hits from anywhere, is exported from ondocs.

  • #74 55772ba Thanks @dgesteves! - An optional bot check for the ask endpoint, with Cloudflare Turnstile, off by default. createAskHandler takes challenge: turnstile({ secretKey }), with turnstile from ondocs/server. Each question must then carry a Turnstile token as challenge in its body, which the endpoint checks with Turnstile's siteverify after the rate limit and before the answer cache, the embedding and the model. A question without a token gets a 403 with code challenge_required, and one with a bad or used token a 403 with challenge_failed. When Turnstile cannot be reached, the endpoint answers 503, or answers anyway with rateLimitFailure: 'open'. Feedback posts and the MCP endpoint are not checked.

    The dialog solves the check with challenge: { turnstile: '<site key>' }: on AskDialog, mountAskDialog, and the dialog options of the Docusaurus, Astro, Starlight and VitePress plugins, or with data-turnstile-site-key on the script tag. When the dialog opens, it loads Turnstile's script from challenges.cloudflare.com and solves a token, invisibly unless Turnstile asks the visitor to click, and it sends a fresh token with each question. Pages load nothing of Turnstile until then. Two new labels, challengeRequired and challengeFailed, say when the check did not load or failed. useAsk takes challengeToken, for a widget of your own.

    The Astro integration's own ask route checks tokens when dialog.challenge.turnstile is set, with the secret in TURNSTILE_SECRET_KEY. The endpoints ondocs init writes, and the Cloudflare Worker template, turn the check on once TURNSTILE_SECRET_KEY is set.

  • #70 4773192 Thanks @dgesteves! - New VitePress plugin, ondocs/vitepress: wrap the config in withOndocs(defineConfig({ ... })) and, after vitepress build, it indexes the pages at the URLs VitePress serves (with base, cleanUrls, rewrites, srcExclude, dynamic routes and an index per locale, leaving out pages with search: false), writes llms.txt, llms-full.txt and a Markdown copy of each page, and adds the "Ask AI" button and ⌘I to every page: about 2 KB of JavaScript, in VitePress's colors and dark mode, with the dialog loaded the first time it is wanted. No theme file is needed. npx ondocs init now recognizes VitePress sites and writes their endpoint for the index the plugin builds, and ondocs dev finds .vitepress/dist/ask-index.json.

    ondocs/integration adds quietUseClient, and launcherScript takes spa: true for a site that moves between pages without loading them.

Patch Changes

  • #67 98d1021 Thanks @dgesteves! - The Cloudflare Worker that ondocs init writes, and templates/cloudflare-worker, now allow the install scripts of esbuild and workerd in package.json (allowScripts) and decline fsevents. npm 12 runs no install scripts unless they are allowed, so a fresh install no longer warns that Wrangler's binaries were blocked.

  • #72 5dbe809 Thanks @dgesteves! - The website moved to ondocs.vercel.app, and the README links point there. The old address redirects, so links in earlier versions keep working.

ondocs@0.7.0

Choose a tag to compare

@github-actions github-actions released this 10 Oct 16:46
403e67a

Minor Changes

  • #61 a7fc5d3 Thanks @dgesteves! - Follow-up questions. The dialog keeps the thread and sends it with each question as { messages }; the handler rewrites a follow-up that leans on the conversation ("and on Netlify?") into a question that stands on its own, with one short model call, before retrieval, the relevance gate, the answer cache and the answer. A question that already stands on its own is not rewritten. The rewrite counts against budget, can use a model of its own (followUps.model), and followUps: false keeps the single-question behavior; onFinish gets the rewritten question as followUp. In the dialog, earlier questions and answers stay above the current one with their own citations, typing offers "Follow up", and "New question" starts over. useAsk returns the thread as turns.

  • #59 2321172 Thanks @dgesteves! - npx ondocs init writes the ask endpoint and the MCP endpoint for your site and its host: Vercel Functions, Netlify Functions, Cloudflare Pages Functions, or a Cloudflare Worker with static assets. Each has a rate limit on the host's client IP header, a daily budget, the answer cache, the CORS preflight answered, and the index bundled the way the host needs. For GitHub Pages and other hosts that only serve files, it writes a Cloudflare Worker of its own that reads the index from the live site, with CORS for the site's origin only. It detects Docusaurus, Starlight, Astro, Next.js, VitePress, Hugo, MkDocs, Jekyll and Eleventy, prints what it wrote and the environment variables to set, asks before it overwrites a file that differs, has --dry-run, and never deploys anything or reads secrets.

    On an Astro or Starlight site with an SSR adapter, the integration now serves POST /api/ask and /api/mcp itself with injectRoute, from the index it builds, so there is no route file to write. It answers with openai:gpt-5.4-mini by default, under a rate limit and a daily budget. A route file the site already has at either path answers instead; route sets the model and the limits, and route: false turns the routes off and keeps the previous behavior.

    remoteIndex(url) from ondocs/server fetches an index over HTTP, keeps it in memory and checks it again every five minutes with its ETag, for an endpoint deployed apart from its site.

  • #63 1950ef2 Thanks @dgesteves! - Labels and locales. Every string the dialog and its button show or announce is a label: labels on AskDialog, dialog.labels in the plugins, and data-labels (a JSON object) or data-label-<name> on the script tag, over English defaults; DEFAULT_LABELS lists them. The endpoint's own messages show as it sends them unless a label for them is given. The plugins take options per locale (dialog.locales), from Docusaurus's i18n and from the page's path in Starlight and Astro, and the dialog sends the page's locale with each question; createAskHandler answers it from indexes[locale], the index the plugins already build per locale. The routes the Astro integration serves, and the endpoints ondocs init writes, wire each locale's index. useAsk takes locale, and an AskError has a reason.

  • #62 eefb00c Thanks @dgesteves! - The quality loop. ondocs eval <questions.yaml> scores retrieval against questions whose answers you know, hit@1 and hit@3, and refusal precision and recall for questions marked unanswerable, question by question, embedding each question as the index was and calling no language model; it exits 1 under its thresholds, for CI. With onFeedback, the dialog asks "Was this helpful?" under each answer, with thumbs up and down and a comment, posted to the endpoint with the answer's id, which onFinish now gets too. onFinish also gets lowConfidence, true when the model answered without citing its sources, so refused || lowConfidence is the log of the questions the docs do not answer. Nothing leaves the site unless you wire it. useAsk has rate(), and ondocs dev prints ratings.

  • #66 e3c5e30 Thanks @dgesteves! - ask-my-site is now ondocs, and this is its first release under that name. The options, the endpoints and their paths, ask-index.json and its format are unchanged, and so is what the dialog and the endpoint send each other. What had the old name moves, and the old names in your code keep working until you rename them (migration guide):

    • Package and command: npm install ondocs, imports from ondocs/server, ondocs/react, ondocs/docusaurus, ondocs/astro, ondocs/starlight, ondocs/embed and the stylesheets under the same paths, and npx ondocs index, init, dev and eval. The ask-my-site package gets no new releases.
    • Script tag: https://cdn.jsdelivr.net/npm/ondocs@0.7/dist/embed.global.js. Its global is window.Ondocs; window.AskMySite still works, and says once in the console to use the new name.
    • Docusaurus: the theme components are @theme/Ondocs and @theme/OndocsMcp. @theme/AskMySite and @theme/AskMySiteMcp still work, and say once, while the site builds or in docusaurus start, to import the new names. The plugin warns about a swizzled src/theme/AskMySite, which its Root no longer renders. The plugin's name, for useAllPluginInstancesData, is ondocs.
    • Types: OndocsOptions, OndocsDialogOptions, OndocsStarlightOptions, OndocsGlobalData and OndocsTheme. The AskMySite… names are deprecated aliases.
    • Plugins under their own names: docusaurus-plugin-ondocs and starlight-ondocs. They were prepared in the repository as docusaurus-plugin-ask-my-site and starlight-ask-my-site, and never published under those names.
    • Smaller things: the button's class is .ondocs-launcher and the script tag's container .ondocs; log lines start with [ondocs] and errors with ondocs:; the Astro integration and the Starlight plugin are named ondocs, and so is the MCP server in initialize unless you pass name. The plugins keep the previous build's index in node_modules/.cache/ondocs, and the first build after the upgrade reuses the vectors in node_modules/.cache/ask-my-site, so it embeds only what changed.
    • Unchanged on purpose: the index's format id (ask-my-site/index@1), the key under which the endpoint sends each source's title, and the store keys of budget and answerCache (ask-my-site:budget:, ask-my-site:answer:, ask-my-site:mcp-budget:), so indexes, dialogs and shared stores carry over.
  • #60 0510866 Thanks @dgesteves! - A Cloudflare Worker that answers any static docs site with Workers AI, with no API key: npx ondocs init --host github-pages now writes it by default (--provider openai keeps OpenAI), and templates/cloudflare-worker is the same Worker as a template for npm create cloudflare. It reads the index from the live site, embeds questions with the Workers AI model the index records (or searches by keywords), answers with CHAT_MODEL, caps itself near the free daily allowance, and runs its tests in workerd with stand-ins, offline.

    -e workers-ai:@cf/<model> (and embedding: 'workers-ai:…' in the plugins) builds an index with a Workers AI embedding model over Cloudflare's REST API, with CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN; ondocs dev embeds questions for such an index the same way.

    An index embedded with @cf/baai/bge-small-en-v1.5 gets a relevance gate of 0.65 by default, measured on docusaurus.io's docs, instead of the 0.25 set for OpenAI's models, which would let every question through.

Patch Changes

  • #64 1d742bb Thanks @dgesteves! - The repository gains two packages under the names people search for, docusaurus-plugin-ondocs and starlight-ondocs. Each re-exports ondocs/docusaurus or ondocs/starlight, is versioned with ondocs, and asks for the peer dependencies that entry needs. The main package gains the chatbot and ui keywords.

ask-my-site@0.6.0

Choose a tag to compare

@github-actions github-actions released this 10 Oct 11:34
aaab9b2

Minor Changes

  • #41 1e6ceb5 Thanks @dgesteves! - Add links: 'sources' to the dialog (<AskDialog links="sources">, <AskAnswer links="sources">, dialog: { links: 'sources' } in the plugins, data-links="sources" on the script tag): a Markdown link in an answer then stays a link only when it points at one of the answer's source pages, and any other shows as its text, so text injected into indexed content cannot get the model to show visitors another site's link. Citations link to their sources either way; the default, 'all', is unchanged. The Docusaurus launcher's shortcut hint now reaches 4.5:1 contrast in light and dark mode (it was 3.97:1 in light mode), using Infima's emphasis colors instead of opacity.

  • #40 2e8d08b Thanks @dgesteves! - The Docusaurus, Astro and Starlight plugins now build their default model, OpenAI's text-embedding-3-small, at 512 dimensions instead of its full 1,536: a third of the index size, as the README's figures assume. Pass dimensions (or embeddingProviderOptions) for another size; a model you name with embedding keeps its own size unless you give one. createAskHandler reads the vector size from the index for OpenAI's text-embedding-3 models, directly or through AI Gateway, so the endpoint no longer repeats embeddingProviderOptions: { openai: { dimensions } }, and indexes built at 1,536 keep working. If your endpoint runs on an older ask-my-site than your site's build, either upgrade it or pin dimensions: 1536 in the plugin. ask-my-site dev also finds dist/client/ask-index.json, where Astro writes the index for a site with an adapter, and the Astro integration's build log names the file it wrote from the project root.

  • #36 12b4be8 Thanks @dgesteves! - createAskHandler now rate-limits by default: without a rateLimit, each client IP gets 10 questions a minute through memoryRateLimit(), keyed by the last X-Forwarded-For entry as on Vercel. Pass your own limiter to change it (for example memoryRateLimit({ trustedHeader: 'cf-connecting-ip' }) on Cloudflare), or rateLimit: false to turn it off when something in front of the endpoint already limits it. Requests without an X-Forwarded-For header share one bucket, so on a platform that does not set it the default is a single limit for all visitors, and the handler reports the first such request to onError with the setting to change. ask-my-site dev answers up to 30 questions a minute. The Vercel and Cloudflare recipes in the README now show their rate limit, as the Netlify one did.

  • #38 1493ad3 Thanks @dgesteves! - ask-my-site dev now answers only pages on your machine. Before, it allowed any origin, so with OPENAI_API_KEY set any site you visited could spend your key through it. Requests from an origin other than localhost, 127.0.0.1 or [::1] (any port) get a 403 unless --allow-origin names it (repeatable, or * for any; --origin still works). Requests whose Host is not one of those names get a 403, which stops DNS rebinding. Request bodies over 64 KiB get a 413 as soon as they pass the limit, instead of being read into memory first.

  • #46 8c47324 Thanks @dgesteves! - Load the dialog on first use. A page now carries only the dialog's button and shortcut, and the dialog itself (Radix Dialog, cmdk and the answer) loads the first time it is wanted: a pointer over or focus on its button or trigger, the shortcut, or opening it. A shortcut pressed while it loads still opens it, with focus in its input, and focus goes back where it was when it closes. Measured on the example sites, ask-my-site's JavaScript per page goes from about 22 KB to 3 KB gzipped with Docusaurus, from 88 KB to under 2 KB with Starlight, and from 91 KB to 2.4 KB with the script tag. AskDialog keeps its props; loadAskDialog() loads it sooner. mountAskDialog from ask-my-site/embed no longer loads React until the dialog is wanted. The script tag's embed.global.js now loads embed-dialog.global.js from next to it: copy both when you host the script yourself, or set data-dialog-src.

  • #45 d6d93d6 Thanks @dgesteves! - Write llms.txt, llms-full.txt and a Markdown copy of each page at build time, from the pages the index is built from. The Docusaurus, Astro and Starlight plugins write them into the build output by default: llms.txt as llmstxt.org describes it, linking each page's copy at its URL plus .md (/docs/intro.md), and naming the MCP endpoint when the mcp option is set. The copies, read from the built HTML, keep links, emphasis, code languages, numbered and nested lists, tables and quotes; the index is unchanged. The plugins never replace a file the build already has, and leave what docusaurus-plugin-llms, docusaurus-plugin-llms-txt, docusaurus-plugin-copy-page-button, starlight-llms-txt, starlight-page-actions and starlight-llm-actions write to them. llmsTxt: false turns all three off, or { index, full, markdown } one at a time. The CLI writes them with ask-my-site index --llms-txt <dir>, and buildLlmsFiles from ask-my-site builds them anywhere. Pages read from Markdown or HTML now carry their description.

  • #44 31ef143 Thanks @dgesteves! - Serve the index to agents as an MCP server. createMcpHandler from ask-my-site/server is a Web-standard (Request) => Promise<Response>, mounted like the ask endpoint, with three read-only tools: search (ranked sections with a snippet and a URL to the anchor), fetch (a page or section as Markdown) and list_pages. It never calls a language model, and without an embeddingModel it calls no model at all. It speaks MCP 2026-07-28 (server/discover, no session) and, for clients that start with initialize, 2025-11-25 back to 2024-11-05, statelessly. Tool calls are rate-limited (60 a minute per client IP by default) and can take a daily budget.

    The Docusaurus, Astro and Starlight plugins take an mcp option with the endpoint's URL, for an "Add to Cursor / VS Code / Claude" block on a docs page: <AskMySiteMcp /> from @theme/AskMySiteMcp, or ask-my-site/astro/McpInstall.astro. McpInstall from ask-my-site/react and mcpInstallLinks from ask-my-site do the same anywhere. ask-my-site dev serves the index at /api/mcp too.

  • #35 213d8da Thanks @dgesteves! - Add spend controls to createAskHandler. budget: { requestsPerDay, tokensPerDay } caps the whole endpoint per UTC day, counting model tokens from each answer's usage and reserving an answer's worst case before the model is called, so concurrent answers cannot overshoot it; once it is spent, questions get a 429 with code budget_exceeded. answerCache: true answers a repeated question (compared after normalizing case, spacing and trailing punctuation) without embedding it or calling the model, keyed by the index's content hash so a rebuilt index starts fresh. Both keep their counts and answers in memory by default, and take a shared store: upstashBudgetStore and upstashAnswerCache adapt @upstash/redis without a dependency on it. Rate-limit keys now bucket an IPv6 client by its /64, so rotating addresses within one subscriber's network no longer gets a fresh limit each time, and useAsk errors carry the server's code.

Patch Changes

  • #37 a8b97c5 Thanks @dgesteves! - The Docusaurus, Astro and Starlight plugins now post to ASK_ENDPOINT whenever it is set as the site builds or starts, even when the config sets endpoint. Before, an endpoint in the config won, so following the README (a config with endpoint: '/api/ask', then ASK_ENDPOINT=http://localhost:8787/api/ask npm start) left the dialog posting to a path the dev server does not serve. The README's plugin snippets no longer set endpoint, since /api/ask is the default.

  • #39 6ff0ccb Thanks @dgesteves! - Read heading ids written as MDX comments, ## Title {/* #custom-id */}, which is how Docusaurus spells {#custom-id} in MDX. The MDX loader used to drop the comment and slug the heading text instead, so the CLI's citations missed the page's anchor for every such heading whose id is not its slug: 141 of the 702 indexed sections in docusaurus.io's own docs. And refuse to index a page whose URL is not a path o...

Read more

ask-my-site@0.5.3

Choose a tag to compare

@github-actions github-actions released this 09 Oct 19:48
4760f0e

Patch Changes

  • #33 054c7ca Thanks @dgesteves! - The README on npm opens with the demo animated, the same one GitHub plays as a video, instead of a still image.