// what the agent sees

Ask digest

When you press ⌘K and ask a question, the agent doesn't read these pages — it reads this. It's committed as a .hev-ask/ tree — one markdown file per section — rendered here the way the ladder discloses it: titles you skim, details you open on demand.

version
2
sections
107
glossary
10
generated
2026-06-19
content hash
0d50d5f620f9
  1. level 1 · tree

    The cheap rung: every section title, plus the glossary terms that widen a query. Titles only — bounded, safe to skim. This is the group/row map below.

  2. level 2 · cat <section>

    On demand, open a section to read its verbatim facts — and, for reference sections, the source text. That's what expanding a row reveals.

Expand a row to cat a section, the way an agent would.

Orientation

The compact product overview the build distills — context for the keyword/expansion path.

hev ask (@hevmind/ask) is a ⌘K search overlay and agent-readable docs distillation, documented at hevask.com, a site that searches itself with the package. The central artifact is the ask digest: a committed, offline-built markdown tree (.hev-ask/, one small file per section) holding section summaries, verbatim facts, source anchors, a glossary, and a site overview. The same tree serves three readers: the ⌘K overlay for humans, the ask CLI read verbs — tree to map it (a couple levels deep, --depth to go further), cat to read a section/_glossary entry/_meta, facts for grounded literals, grep to search — one verb per operation, since the tree is a real directory you can also ls/head — for agents, and the ask mcp server, which hydrates the tree to local disk so an agent reads it with its own file tools. The digest is host-neutral (built from markdown, not a renderer); Astro gets the turnkey hevAsk() integration, while Docusaurus, VitePress, MkDocs, and plain static sites use the drop-in static overlay plus an optional hostable endpoint. Two retrieval paths: instant keyless keyword search (token overlap widened by the digest glossary, deep-linking to /docs/page#anchor with anchors from github-slugger, gated in CI by ask digest verify) and an agentic answer on Enter (needs a server-side provider API key — ANTHROPIC_API_KEY by default; OpenAI and OpenRouter are supported via the provider option, with providerBaseUrl for any OpenAI-compatible endpoint — and streams SSE with inline citations to opened sections). The digest is hash-gated and incremental: rebuilds skip model work for unchanged sections, and it's buildable via the Claude Code skill (subscription, sharded), the one-shot CLI ask digest build, or the sharded flow for big sites. Everything degrades instead of hard-failing: no key means keyword mode, no tree means plain excerpts. The corpus is only the configured content collection(s) or globs, with no crawler. The POST /api/ask endpoint renders on demand, so the agentic path needs a server or hybrid adapter. The digest was formerly called the knowledge graph (kg) and was a digest.json; both are legacy names. Users compare hev ask against Pagefind, Algolia DocSearch, and Orama; the Tradeoffs and Limits pages answer that directly.

Glossary 10 terms

Aliases that widen a reader's query before retrieval — so k8s finds kubernetes. List the terms; open one for its aliases and definition.

Sections 107 sections

One file per section — the tree the agent navigates. Collapsed shows the title and summary it skims; open a section to cat its facts.

API

  • CLI reference
    The ask CLI treats the committed digest as a directory: read verbs map, read, pull grounded literals from, and search it, plus a synthesized cited reply and a server for agents. A separate producer command group builds, verifies, and serves the digest.
    facts · quoted verbatim
    @hevmind/askasktreecatfactsgrepanswermcpask digestbuildcorpusassembleverifystatusmigrateCallout.astroCodeTabs.astro

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Building the digest reference
    Producer commands run from the site root to build, emit a keyless corpus, assemble the tree, verify, report shard coverage, and migrate a legacy JSON digest. Only the build calls a model and is the only one needing a key; it is incremental and hash-gated, so a clean tree calls the model zero times, and a one-shot build is bounded by section-text size before it requires the sharded flow. The model authors only context, glossary, summaries, and suggestions; everything else is computed deterministically.
    facts · quoted verbatim
    export ANTHROPIC_API_KEY=sk-ant-... ask digest build # claude-opus-4-8 by defaultexport OPENAI_API_KEY=sk-... ask digest build --provider openai # gpt-5.1 by defaultexport OPENROUTER_API_KEY=sk-or-... ask digest build --provider openrouter # anthropic/claude-opus-4.8 by defaultask digest build--providerask digest corpusask digest assemble.hev-ask/contextsummariessuggestions.hev-ask/digest.jsonask digest migratedigest.json

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Claude Code skill reference
    The bundled build-digest skill builds the tree inside a Claude Code subscription without an API key by running the deterministic producer seam sharded: emit a corpus, distill each shard in a fresh context, synthesize over the shard notes, then assemble. Because each shard is its own context, corpus size never hits a context limit, and the result matches a normal build with the same incremental hash gate.
    facts · quoted verbatim
    ask digest corpus --shards-dir .hev-ask/shards -> input-<id>.json + manifest.json ...one fresh-context distillation per shard -> distill-<id>.json... ...one synthesis pass over the shard notes -> global.json... ask digest assemble --input-dir .hev-ask/shards -> the .hev-ask/ treebuild-digestANTHROPIC_API_KEYask digest build

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Distribution reference
    The npm package exposes a single bin whose launcher resolves an environment-variable override first, then a platform-specific optional binary package, then the checked-out Go source as a development fallback. Published installs use the packaged binary.
    facts · quoted verbatim
    askHEV_ASK_BINARY

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Flags reference
    A reference table of every CLI flag with its default and purpose, covering digest paths, remote endpoint reads, JSON output, tree depth, result caps, collection and chunking controls, the digest model and provider selection, sharding inputs, and verify options. Global flags come before the subcommand.
    facts · quoted verbatim
    ask --digest-dir .hev-ask --json grep "openapi" ask --endpoint https://hevask.com/api/ask cat api/endpoint ask digest build --collection docs --collection guides --chunk-heading-depth 2 ask digest verify --skip-build--digest-dir <dir>.hev-ask--endpoint <url>/api/askanswer--json--depth <n\|all>tree(+N)all--max-results <n>grep--collection <name>docs--base-path <path>/docs/--content-glob <glob>--chunk-heading-depth <n>--digest-model <model>ask digest buildclaude-opus-4-8--provider <name>anthropic

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Go library reference
    A reusable Go API exposes pure helpers and a dependency-free command group you can mount in your own CLI, including loaders, section listing and retrieval, search, an endpoint client, and an MCP server. It supports reading the tree from disk or an embedded filesystem.
    facts · quoted verbatim
    group := ask.NewCommandGroup(ask.CommandOptions{ DigestDir: ".hev-ask", }) err := group.Run(ctx, []string{"cat", "overview/quick-start"}, os.Stdin, os.Stdout, os.Stderr)pkg/askLoadDigestembed.FSListSectionSummariesGetSectionSearchDigestNewEndpointClientServeMCP

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • MCP reference
    The CLI's MCP command runs a stdio server with one tool that downloads the whole digest tree to local disk and returns the title-tree inline, after which the agent reads the files with its own tools. It can point at a checked-out repo or a deployed endpoint via configuration.
    facts · quoted verbatim
    { "mcpServers": { "hevask": { "command": "ask", "args": ["--endpoint", "https://hevask.com/api/ask", "mcp"] } } }ask mcptreecatgrep

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Reading the digest as a directory reference
    By default the CLI reads the local tree; a remote endpoint flag reads a deployed site's HTTP API instead, with path-addressed reads that mirror doc URLs. Mapping the tree is the cheap first step, returning titles only and defaulting to two levels deep, scoped and deepened by a path and depth flag, with truncated directories reporting a hidden count; the glossary table is collapsed until you scope into it. Because the tree is real markdown, plain shell tools work on it, while the verbs add frontmatter, fuzzy path resolution, glossary aliases, and remote reads; the synthesized reply requires a remote endpoint, so keyless local retrieval uses search and read.
    facts · quoted verbatim
    ask.hev-ask/--endpoint <url>lshead--endpointask tree--depth N--depth all(+N)_glossary/ask tree _glossarycatfactsask answerask grepask cat

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Sharded builds for large sites reference
    The sharded flow removes the single-context bound by splitting the corpus along slug-prefix boundaries, distilling each shard independently, and merging on assembly. Sharding is stable and incremental: editing one doc re-pends only the shard that owns it, stale distillations are detected and skipped with a warning while affected sections fall back to plain excerpts, and the tree stays usable throughout. Verify builds the site and checks rendered anchors, coverage, literal fidelity, and tree integrity, with anchor drift always fatal and the rest warnings unless strict mode is set.
    facts · quoted verbatim
    ask digest corpus --shards-dir .hev-ask/shards # input-<id>.json per shard + manifest.json ask digest status --shards-dir .hev-ask/shards # distilled / pending / stale, per shard # ...one distillation per shard writes distill-<id>.json; a final pass writes global.json... ask digest assemble --input-dir .hev-ask/shards # merge + write the .hev-ask/ treeworkers/...pages/...corpusask digest verify--skip-build_meta.md--strict

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Where it runs reference
    Producer commands run locally or in CI with filesystem access, and the Astro integration also runs the build during the site build when a key is present, falling back to the committed tree otherwise. The deployed site reads the committed tree through a virtual module and needs no filesystem access; running verify on every build is the mechanical check that generated slugs still match what the renderer produces.
    facts · quoted verbatim
    ask digest buildastro buildANTHROPIC_API_KEYvirtual:hev-ask/digestask digest verify

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Configuration reference
    The hevAsk() Astro integration is the package's default export and takes a single options object. Only the content collections list is effectively required; every other option has a default.
    facts · quoted verbatim
    // astro.config.mjs import hevAsk from "@hevmind/ask"; export default defineConfig({ integrations: [ hevAsk({ collections: ["docs"], basePath: "/docs/", model: "claude-haiku-4-5", maxResults: 6, }), ], });hevAsk()@hevmind/askcollectionsCallout.astroCodeTabs.astro

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Choosing a provider reference
    The provider option selects who serves both the runtime answer loop and the offline digest build, with identical search behavior, digest format, and endpoint contract across providers; only the model and key environment variable change. OpenRouter reaches every model it routes through one key, and a base-URL override points the OpenAI-compatible client at any Chat Completions endpoint. Loop models must support tool calling and the digest builder needs forced tool choice, which current major-provider models satisfy; a changed endpoint route must be mirrored on the overlay component.
    facts · quoted verbatim
    // astro.config.mjs — the default; reads ANTHROPIC_API_KEY hevAsk({ collections: ["docs"], // model defaults to claude-haiku-4-5 });// astro.config.mjs — reads OPENAI_API_KEY hevAsk({ collections: ["docs"], provider: "openai", // model defaults to gpt-4.1-mini });// astro.config.mjs — reads OPENROUTER_API_KEY hevAsk({ collections: ["docs"], provider: "openrouter", model: "anthropic/claude-haiku-4.5", // or any OpenRouter model slug });hevAsk({ collections: ["docs"], provider: "openai", providerBaseUrl: "https://my-gateway.example.com/v1", model: "my-model", });providerOPENROUTER_API_KEYproviderBaseUrlprovider: "openai"endpoint/api/askSearchOverlay

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Options reference
    A reference table of every hevAsk() option with its type, default, and description, spanning collections, base path, endpoint route, provider and base-URL override, the loop and digest models, source and result caps, the answer token budget, search iteration limit, chunk heading depth, per-search and per-document candidate caps, and the digest directory and content globs.
    facts · quoted verbatim
    collectionsstring[]basePathstring'/docs/'basePath + slug#anchorendpoint'/api/ask'provider'anthropic''openai''openrouter'ANTHROPIC_API_KEYOPENAI_API_KEYOPENROUTER_API_KEYproviderBaseUrlmodelclaude-haiku-4-5gpt-4.1-minianthropic/claude-haiku-4.5digestModelclaude-opus-4-8gpt-5.1

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Tuning notes reference
    Guidance on tuning the knobs: chunk heading depth trades finer section anchors against sections too small to stand alone, the iteration cap trades latency against multi-part recall, the per-document cap controls result spread, and the candidates-per-search count trades recall against token cost.
    facts · quoted verbatim
    chunkHeadingDepth###maxIterationsperDocCapcandidatePerSearch

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • TypeScript reference
    The options type is exported so editors can offer help and config files can be typed.
    facts · quoted verbatim
    import type { HevAskOptions } from "@hevmind/ask";

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • What the integration does reference
    At config setup the integration injects the on-demand endpoint route, registers virtual modules for the resolved config and the committed tree, watches the digest directory for dev reloads, and warns on empty collections. At build start it runs the hash-gated digest build when the provider key is present and otherwise warns and proceeds with the committed artifact; the build never fails for lack of a key.
    facts · quoted verbatim
    astro:config:setupendpoint@hevmind/ask/endpointprerender: falsevirtual:hev-ask/configvirtual:hev-ask/digestdigestDircollectionsastro:build:startANTHROPIC_API_KEY

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Digest format reference
    The ask digest is a committed directory built offline and globbed into the build through a virtual module, so the running site reads it without filesystem access. It is the agent's distilled, source-grounded mirror of the docs, read progressively, with every section carrying a deep link back to its real source page; humans read rendered pages while agents read the tree.
    facts · quoted verbatim
    .hev-ask/ask digest builddigest.jsonkgvirtual:hev-ask/digesturlanchorCallout.astro0.1

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • _meta.md and _glossary/ reference
    The meta entry carries digest-level fields used as the freshness gate and ordering, plus orientation context, the deterministic overview map, and the suggestions the overlay shows on open. The glossary is one file per term holding its aliases and definition, and it widens keyword search by expanding each query term to its aliases before retrieval.
    facts · quoted verbatim
    _meta.md_glossary/versiongeneratedAtcontentHashcontextoverviewsuggestions_glossary/<term>.mdtermaliasesdefinitionk8skubernetes

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • A section file reference
    A single section file is shown with its frontmatter and body: the first paragraph is the summary, the body below the frontmatter is the full read payload, and the frontmatter arrays are the grounded facts. One file thus serves the three rungs of progressive disclosure.
    facts · quoted verbatim
    headcatfacts

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Degradation reference
    The tree is read defensively: a missing or malformed digest degrades to keyword-style fallback search, raw token-overlap ranking, and no suggested questions, and nothing hard-fails. Being a committed markdown tree, each section's distilled prose and grounded facts change together in one reviewable diff, which is why it is a directory rather than a runtime computation and why the model step can move into a skill.
    facts · quoted verbatim
    .hev-ask/

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Frontmatter fields reference
    A reference table of every section frontmatter field with its type and role, covering the listing title and literal heading text, group and order, the citation URL and anchor, ranking terms, the incremental-build hash, the agent-primary versus source-primary mode, the deterministically extracted verbatim facts, and the source provenance references.
    facts · quoted verbatim
    titlestringtreelsheadinggroupordernumberurlanchorgithub-sluggerverifyidtermsstring[]hashmode'agent-primary' \| 'source-primary'source-primaryfactsFact[]sourcesSourceRef[]

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • How each field is used reference
    The title-tree and summaries are injected into the loop's prompt-cached system prompt; the model opens needed sections and answers from their summaries, quoting facts for exact strings. The glossary drives query expansion, and terms, summary, and facts all rank keyword results so central sections outrank incidental mentions; the anchor is what verify checks and what citations link to, and the hash is the incremental gate.
    facts · quoted verbatim
    facts_glossary/termssummaryanchorask digest verifyhashbuild

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Layout reference
    Describes the on-disk layout: a meta file, a glossary directory of per-term files, and per-section markdown files under directories that mirror the doc paths. Underscore-prefixed non-section entries sort first and never collide with a real slug, and there is no committed JSON; the whole artifact is markdown.
    facts · quoted verbatim
    .hev-ask/ _meta.md overview · context · suggestions · version · contentHash _glossary/ digest.md one file per term: aliases + definition overview/ quick-start.md one file per section, mirroring your doc paths limits.md api/ cli.md_meta_glossary

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Regenerating reference
    Rebuild after content changes and commit the result; the build is incremental, spending model work only on sections whose hash changed. You can build with the keyless skill, the one-call CLI build, or the integration during the site build when a key is present; large sites use the sharded flow, verify gates anchors and coverage, and a legacy single-file digest can be exploded into the tree with no model call.
    facts · quoted verbatim
    hashask digest buildastro buildask digest verifydigest.jsonask digest migrate

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Search endpoint reference
    The integration injects one on-demand route serving the overlay: keyword mode returns JSON and agentic mode streams a grounded answer as Server-Sent Events. Keyless sub-routes expose the committed digest for CLIs, MCP servers, and generated clients, and the full machine-readable contract is published as OpenAPI.
    facts · quoted verbatim
    /api/asktext/event-stream/openapi.yamlCallout.astro3.1openapi.yaml

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Agentic response (SSE) reference
    When a key is present and agentic mode is requested, the endpoint streams the answer as named SSE frames whose example payloads and meaning are documented in a table: search context the model gathered, the one-time grounding source set, streamed answer-text deltas, completion, and a post-stream error. A source carries title, optional heading, URL, and group but no snippet, since the prose carries the substance and links point at the URL.
    facts · quoted verbatim
    modeagenticcontent-type: text/event-streamsearch{ query }sources{ sources: Source[], model, mode }token{ text }done{}error{ error }200Source{ title, heading?, url, group? }snippeturl

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Digest reads (GET) reference
    A table of keyless GET routes that read the committed digest, never call a model, and never need a key, covering the glossary and a single term, section summaries optionally filtered by group, a single full section, the overview, and a compressed archive of the whole tree. Section IDs with slashes or hashes are URL-encoded in the path, the archive is the bulk transport used by the MCP command, a HEAD request returns cache headers including the content hash so clients can skip a download, and unknown reads return a JSON not-found error.
    facts · quoted verbatim
    { "error": "Not found." }virtual:hev-ask/digestGET /api/ask/glossary{ "terms": GlossaryEntry[] }GET /api/ask/glossary/{term}GlossaryEntryGET /api/ask/sections{ "sections": SectionSummary[] }GET /api/ask/sections?group=APIGET /api/ask/sections/{id}DigestNodeGET /api/ask/overview{ "overview": string, "context": string }GET /api/ask/archive.hev-ask/SectionSummary{ id, title, heading, group, url }/api/ask/sections/api%2Fcli%23flagsask mcp --endpointHEAD /api/ask/archivex-hev-ask-content-hash404

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Errors reference
    A table of error responses: a bad request for invalid JSON, not-found for an unknown read route or missing term or section, and a server error when the chunk index fails to build. A failure during the agentic stream arrives as a final SSE error event because the HTTP status is already successful.
    facts · quoted verbatim
    400{ "error": "Invalid JSON body." }404{ "error": "…" }500event: error200errore.g

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Index lifecycle reference
    The chunk index is built once per server instance on the first request and cached for the process lifetime. On that first request the endpoint compares the live content hash against the digest's and logs a one-time warning on mismatch, signaling a rebuild.
    facts · quoted verbatim
    ask digest build

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Keyword response (JSON) reference
    Keyword mode returns a successful JSON envelope whose fields are documented in a table: ranked results with title, optional heading, URL, group, and snippet; the echoed query; the configured loop model; the mode that ran; and an optional warning when agentic was requested with no key. The result URL carries the deep link with anchor appended except for a document's intro chunk.
    facts · quoted verbatim
    { "results": [ { "title": "Concepts", "heading": "The agentic search loop", "url": "/docs/concepts#the-agentic-search-loop", "group": "Overview", "snippet": "When the reader presses Enter, the query goes to a bounded loop…" } ], "query": "how does agentic search work", "model": "claude-haiku-4-5", "mode": "keyword" }200resultsResult[]titleheading?urlgroup?snippetquerystringmodelmode'keyword'warningstring?#anchor

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • LLM tracing reference
    Setting a PostHog key in the environment makes every agentic answer emit a trace with model, tokens, latency, and the loop's tool calls, with additional variables to override the ingestion host and control how much prompt and answer text ships. Without a key tracing is a no-op and the answer path never depends on it.
    facts · quoted verbatim
    POSTHOG_KEYPOSTHOG_API_KEY$ai_generationPOSTHOG_HOSTPOSTHOG_CAPTURE_CONTENToffredactedfull

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Mode selection reference
    The endpoint decides what to run: an empty query returns empty keyword JSON, an explicit keyword request or no key returns keyword JSON, an agentic request without a key returns keyword JSON plus a warning, and otherwise it streams the agentic answer. There is no AI-unavailable error path; a missing key simply downgrades to keyword results, and the overlay branches on the response content type to handle both shapes.
    facts · quoted verbatim
    { results: [], query: "", model, mode: "keyword" }mode: "keyword"mode: "agentic"warningcontent-type

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Request reference
    The endpoint takes a POST with a JSON body documented in a table: a query string where empty or whitespace returns no results, and an optional mode that forces the instant path or requests the loop, defaulting to agentic behavior when a key is present.
    facts · quoted verbatim
    { "query": "how does autoscaling work", "mode": "agentic" }POSTquerystringmode'keyword' \| 'agentic'keywordagentic

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Suggested questions (GET) reference
    A GET to the base route returns the digest's baked-in suggested questions and the loop model with no query and no model call. The overlay fetches this once on first open when AI is enabled to populate its suggestions; an empty array, including no digest at all, simply shows none.
    facts · quoted verbatim
    { "suggestions": ["How does the digest stay fresh?"], "model": "claude-haiku-4-5" }GET /api/asksuggestions

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • The API key reference
    The endpoint reads the key named by the configured provider from the adapter runtime environment, then the process environment, then the build-time environment, in that order. Set it wherever the host injects server secrets; it is never sent to the browser.
    facts · quoted verbatim
    ANTHROPIC_API_KEYOPENAI_API_KEYOPENROUTER_API_KEYproviderlocals.runtime.envprocess.envimport.meta.enve.g

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • MCP server reference
    The MCP command runs a stdio server that is one tool plus instructions: the tool downloads the whole digest tree to local disk and the instructions tell the agent to navigate it with its own file tools and cite every claim with the section's deep link. Since an MCP consumer is already an agent it needs the corpus rather than synthesis, so there is no answer tool here.
    facts · quoted verbatim
    ask mcptreecatgrepurlanchorlsanswerCallout.astro

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Co-location reference
    Hydrate-to-disk assumes the MCP server and the agent's file tools share a host, which is true for the default stdio transport, and the server intentionally exposes only that path. A remote transport where the agent cannot read the server's cache would need a separate resource or tool fallback, since returning a local path would not help.
    facts · quoted verbatim
    ask mcp

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Configure reference
    Shows MCP client configuration for two cases: a keyless setup pointing at a local checked-out tree, and one pointing at a deployed site's endpoint, which lets any site running hev ask be pulled into the agent's workspace from anywhere.
    facts · quoted verbatim
    { "mcpServers": { "docs": { "command": "ask", "args": ["--digest-dir", ".hev-ask", "mcp"] } } }{ "mcpServers": { "hevask": { "command": "ask", "args": ["--endpoint", "https://hevask.com/api/ask", "mcp"] } } }

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Data sources reference
    The MCP server uses the same source resolution as the CLI: a remote endpoint downloads the deployed tree as a compressed archive, otherwise it reads the local digest directory. A just-rebuilt tree becomes visible on the next fetch without restarting the server.
    facts · quoted verbatim
    ask mcp--endpoint <url>/api/ask/archive--digest-dir.hev-askfetch_docs

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Protocol surface reference
    The server speaks newline-delimited JSON-RPC over stdio and handles initialization (returning the instructions), tool listing, and tool calls, plus the initialized notification. Unknown methods return a protocol error and tool failures return an error result, keeping the server thin because all substantive behavior lives in the shared core that the CLI, command group, and MCP server reuse.
    facts · quoted verbatim
    initializeinstructionstools/listtools/callisError: truepkg/ask

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • The instructions reference
    The server's instructions string teaches the agent two things: navigation, to read the inline title-tree first and open sections only when relevant rather than reading everything; and citation, to answer from the files and cite every claim with the section's deep link. Citation is the easy-to-lose part that carries the entire grounded-deep-link value, so the instructions make it non-negotiable.
    facts · quoted verbatim
    instructionscatgrep_glossary/urlanchor/docs/page#anchor

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • The tool reference
    The single tool materializes the digest tree at a host-keyed local cache path and returns the title-tree inline plus on-disk bodies and facts, so one call bootstraps the whole disclosure ladder with no second round-trip and the agent then uses its native tools. A force argument re-pulls unconditionally, otherwise it compares the remote content hash and re-downloads only on mismatch; because the corpus is bounded the whole tree ships compressed in one shot with no per-file delta protocol.
    facts · quoted verbatim
    tree ~/.cache/hev-ask/hevask.com # already returned inline by fetch_docs cat ~/.cache/hev-ask/hevask.com/overview/quick-start.md grep -r "prerender" ~/.cache/hev-ask/hevask.comfetch_docs{ force?: boolean }{ path, contentHash, sections, tree, upToDate }~/.cache/hev-ask/hevask.com/force: truecontentHashupToDate: truee.g

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • SearchOverlay component reference
    The SearchOverlay component renders the ⌘K command palette, added once in a global layout. It opens over the page and does not affect layout until opened.
    facts · quoted verbatim
    --- import SearchOverlay from "@hevmind/ask/components/SearchOverlay.astro"; --- <SearchOverlay />SearchOverlay.astro⌘K<dialog>Callout.astro

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Any static site reference
    For any static site there is no framework to satisfy: run the bundle command in your build, deploy its output alongside your HTML, and drop the script tag into your template, adding the endpoint attribute when you want answers.
    facts · quoted verbatim
    ask digest bundle<script>

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Bundling the static assets reference
    The bundle command emits the browser payload (keyword index, glossary, suggestions, and title-tree) into a served directory, run as part of your build like the HTML render step. The output is served rather than committed, so gitignore it while keeping the committed tree as the reviewable source of truth; regenerating every build keeps the assets from drifting from what you deploy.
    facts · quoted verbatim
    ask digest bundle.hev-ask/

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Docusaurus reference
    Shows the Docusaurus wiring: emit the bundle into the static directory from the build script and add the overlay script through the site config. Docusaurus headings carry explicit custom-id anchors, which its slug mode honors and verify checks against the built HTML.
    facts · quoted verbatim
    // docusaurus.config.js export default { scripts: [ { src: "https://cdn.jsdelivr.net/npm/@hevmind/ask/overlay.js", type: "module", "data-hev-ask-digest": "/hev-ask/", "data-hev-ask-endpoint": "https://docs-ask.example.workers.dev/api/ask", }, ], };// package.json — bundle into the static dir before docusaurus build "scripts": { "build": "ask digest bundle --out static/hev-ask && docusaurus build" }static/builddocusaurus.config.js{#custom-id}ask digest verifybuild/

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Keyboard model reference
    The overlay is ask-first and the number of words typed decides the path: opening with AI on shows suggested questions, one word runs debounced keyless keyword search with the first result auto-active, and typing a space switches to ask mode where Enter sends the question to the agentic loop. Arrow keys move the keyword selection, Escape closes, and the footer hint reflects the mode; with no server key, asking returns keyword results plus a shown warning rather than escalating.
    facts · quoted verbatim
    TabANTHROPIC_API_KEY

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Keyword results and deep links reference
    Each keyword result row shows the document title, an optional heading breadcrumb, and a one-line snippet, and the row's link is the chunk's URL with its anchor already appended so clicking lands on the exact heading.
    facts · quoted verbatim
    Concepts › The agentic loopurl#anchor

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • MkDocs reference
    Shows the MkDocs wiring: bundle the assets into a docs subdirectory and reference the overlay script through the site config's extra-JavaScript list.
    facts · quoted verbatim
    # mkdocs.yml extra_javascript: - hev-ask/overlay.jsdocs/hev-ask/extra_javascript

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Opening the overlay reference
    Two built-in ways to open the overlay: the ⌘K / Ctrl-K shortcut is bound automatically once the component is on the page, and any element carrying the opener attribute opens it on click, so you can wire up as many triggers as you like.
    facts · quoted verbatim
    <button type="button" data-hev-ask-open> Search <kbd>⌘K</kbd> </button> <a href="#" data-hev-ask-open>Search the docs</a>⌘KCtrl-Kdata-hev-ask-open

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Props reference
    A table of the overlay component's props with defaults: the endpoint it posts to, which must match the integration's endpoint option; the input placeholder text; and the debounce delay before a keyword query is sent.
    facts · quoted verbatim
    <SearchOverlay endpoint="/api/ask" placeholder="Search hev ask…" debounce={400} />endpointstring'/api/ask'placeholder'Search the docs…'debouncenumber500

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Suggested questions reference
    When AI is on, the overlay fetches a short list of suggested questions from the endpoint the first time it opens and shows them in the empty state. They come from the digest's baked-in suggestions, so there is no model call to render them, and an empty list simply shows nothing; clicking a suggestion fills the input and asks it immediately.
    facts · quoted verbatim
    GET /api/asksuggestions

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Support at a glance reference
    A matrix of framework support across digest build, keyword overlay, and agentic answers: Astro is turnkey through the integration and mounted route, while Docusaurus, VitePress, MkDocs, and plain static sites run the digest build in their own pipeline, drop in the overlay, and use a hostable endpoint for answers. The CLI and MCP surfaces are host-neutral on every row, giving a coding agent the same reads regardless of renderer.
    facts · quoted verbatim
    hevAsk()SearchOverlay.astro/api/askask digest<script>mountHevAskextra_javascript

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • The hostable endpoint reference
    For agentic answers without Astro, deploy the bounded answer loop as a standalone service (a Cloudflare Worker, a Node server, or a Vercel function) that serves the same endpoint contract, holds the key server-side, and reads the committed tree. Deploy it once and point any number of sites' overlays at it; keyword search stays in the browser, so only the answer loop needs anything deployed, and a scaffold command bootstraps the Worker flavor.
    facts · quoted verbatim
    # scaffold and deploy the Worker flavor ask endpoint init --target cloudflare wrangler deploy # set ANTHROPIC_API_KEY as a secretPOST /api/askANTHROPIC_API_KEY

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • The mode toggle reference
    The overlay persists an AI-on-Enter preference in localStorage. Readers who flip it to keyword-only never trigger a model call (a space just searches a phrase and no suggestions show), and the choice survives reloads.
    facts · quoted verbatim
    localStoragehev-ask:modeagentickeyword

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • The overlay on other frameworks reference
    Beyond the Astro component, the same palette ships as a prebuilt web component that any site loads with one script tag from npm or a CDN. It reads a bundled copy of the digest in the browser so keyword search runs fully static, and a digest attribute points at the bundled assets while an optional endpoint attribute enables the agentic loop with the key staying on the server. It reads the same CSS variables, opener attribute, and keyboard model as the Astro component.
    facts · quoted verbatim
    <script type="module" src="https://cdn.jsdelivr.net/npm/@hevmind/ask/overlay.js" data-hev-ask-digest="/hev-ask/" data-hev-ask-endpoint="https://docs-ask.example.workers.dev/api/ask" ></script> <button data-hev-ask-open>Search <kbd>⌘K</kbd></button>SearchOverlay.astro@hevmind/ask/overlaydata-hev-ask-digestask digest bundledata-hev-ask-endpoint

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • The streamed answer reference
    Pressing Enter with a key configured replaces the keyword rows with an answer panel: the model's sub-queries appear live, then the grounded answer streams in token-by-token, with inline accent-colored deep links to exact headings and a Sources row listing every section it drew from. Links are validated against the streamed source set, so any link to a URL outside that set renders as plain text and a hallucinated anchor can never become a clickable dead link.
    facts · quoted verbatim
    searched: …/docs/page#anchor

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • Theming reference
    The overlay reads your page's CSS custom properties for background, text, muted text, and accent, so defining those tokens on the root makes the overlay inherit your palette. Because its scoped styles are keyed to those variables, matching your site's look is usually just defining the tokens with no overlay CSS to override.
    facts · quoted verbatim
    :root { --paper: #111111; /* overlay background */ --ink: #fafaf5; /* primary text */ --muted: #6b6b66; /* secondary text */ --signal: #e25822; /* accent / active state */ }as-:root

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗
  • VitePress reference
    Shows the VitePress wiring: bundle the assets into the public directory and register the overlay in the theme's enhance step, passing the digest path and an endpoint from an environment variable.
    facts · quoted verbatim
    // .vitepress/theme/index.ts import DefaultTheme from "vitepress/theme"; import { mountHevAsk } from "@hevmind/ask/overlay"; export default { extends: DefaultTheme, enhanceApp() { if (typeof window !== "undefined") { mountHevAsk({ digest: "/hev-ask/", endpoint: import.meta.env.VITE_ASK_ENDPOINT }); } }, };.vitepress/public/

    Reference section — on open, the agent also receives this section's source text verbatim.

    open section ↗

Overview

  • Concepts summary
    hev ask rests on one idea: the digest is just a directory of distilled markdown, one file per section, read two ways that both climb it progressively — a coding agent navigates it with its own file tools, and a ⌘K overlay reads it server-side to synthesize a grounded answer for a human. The tree is built offline with a strong model and committed to git while the readers run on demand, so no durable state lives in the running site.
    facts · quoted verbatim
    ⌘KDiagram.astroCallout.astro
    open section ↗
  • Asking is the default summary
    The overlay is ask-first: a single word is answered instantly from the keyword index, and the moment the query grows past one word it switches to ask mode where Enter sends the question to the agentic loop. Suggested questions baked into the digest make asking the obvious move, but a reader can flip the overlay to keyword-only, after which a space just searches a phrase and the model is never called.
    facts · quoted verbatim
    _meta.mdlocalStorage
    open section ↗
  • Chunks and anchors summary
    hev ask indexes sections rather than pages: each document is split on its headings up to a configurable depth, content before the first heading becomes an intro chunk, and each chunk carries a URL built from the base path, slug, and anchor. Anchors are generated with the same slugger the renderer uses so links land on headings that actually exist, each framework adapter declares its slug scheme, and both the offline build and the runtime index chunk through one shared function so anchors agree and the same digest comes out regardless of renderer.
    facts · quoted verbatim
    #####basePath + slug + #anchorgithub-slugger{#custom-id}getCollectiongithub.com
    open section ↗
  • Degradation, by design summary
    hev ask keeps working as pieces drop away: no key at runtime leaves keyword mode, no key at build keeps the committed tree with a warning, no digest tree falls back to keyword-style retrieval and raw token-overlap ranking with no suggestions, and a stale tree logs a one-line warning but still serves. Everything still works, and the page points to Limits and Tradeoffs for boundaries and choices.
    facts · quoted verbatim
    .hev-ask/_meta.md
    open section ↗
  • Host-neutral: one digest, any framework summary
    The build reads markdown off disk, chunks on headings, derives anchors in code, and writes the tree without importing any framework, so the digest is the same artifact whether Astro, Docusaurus, VitePress, or MkDocs renders the pages; only the adapter differs. Astro is the batteries-included flagship, while every other framework uses two host-neutral primitives — the fully static drop-in overlay for the keyword path and the standalone hostable endpoint for the agentic path — and the CLI and MCP surfaces are already host-neutral because they read the committed tree directly.
    facts · quoted verbatim
    .hev-ask/hevAsk()astro build/api/askSearchOverlay.astro<script>treecatgrep
    open section ↗
  • Keyword search and the glossary summary
    The instant keyword path runs a dependency-free prefilter over the chunks: it expands each query term with its glossary aliases and matched-term tokens, scores by token overlap widened by the digest so matches against a section's summary, terms, and facts lift it above incidental body mentions, caps results per document so one long page can't dominate, then excerpts around the first match for the snippet. It needs no key and no embeddings, and with no tree it degrades to plain token overlap so keyword search always works.
    facts · quoted verbatim
    grepk8skubernetessummarytermsfacts
    open section ↗
  • Progressive disclosure as a directory summary
    Because the digest is a real directory, progressive disclosure is just the directory's own cost model, and the reads form a disclosure ladder where each rung is a strictly larger slice of one section file. A listing reads frontmatter only so it can never leak a body and is bounded by the number of sections rather than the size of the docs, making it safe to call speculatively, and every deeper rung is an explicit verb so nothing larger than a title is ever returned by surprise; an agent climbs it with its own file tools while the CLI offers one verb per operation for keyless and remote cases.
    facts · quoted verbatim
    cattreefactsgreplsheadask
    open section ↗
  • The agentic search loop summary
    The overlay answers humans by doing the synthesis an agent would do itself, sending a multi-word query to a bounded tool-use loop in two phases. In the gather phase the model is given the title-tree of every section plus one tool to open a section's summary, facts, and (for reference sections) source text, opening only what it needs up to the iteration cap and citing only what it opened; in the answer phase the accumulated sources are sent to the overlay for link validation and the model is called once more with no tools so it can only write prose, streamed token-by-token. Dropping the tools on the final turn guarantees it answers rather than searching again, and it can only ground in and link to the sections retrieval returned.
    facts · quoted verbatim
    open_section({ id })factsmaxIterationsurl
    open section ↗
  • The ask digest directory summary
    The build distills each section into a small markdown-plus-frontmatter file and writes the whole tree mirroring the doc paths, where the body is the distilled prose and the frontmatter carries the citation link, verbatim facts, sources, ranking terms, and the content hash, alongside the per-term glossary and the meta entry. There is no committed JSON, and because a listing returns only titles, page-level titles come from the collection while sub-section titles are synthesized into descriptive one-liners, since the title is the only thing a reader sees before opening a file.
    facts · quoted verbatim
    .hev-ask/overview/api/titleurlanchorfactssourcestermshash_glossary/_meta.mdcontextheading
    open section ↗
  • The system prompt is cached summary
    The title-tree and section summaries are injected into the system prompt with a cache marker, so across the search rounds it is a prompt-cache hit rather than re-sent tokens; the final answer turn changes the tool set and so cannot reuse that cache, but it is the last call anyway. The loop model defaults to a small model and is configurable, and the page warns not to confuse the reader's server-side synthesis loop with a consumer's own coding agent that navigates the files itself, though both climb the same ladder.
    facts · quoted verbatim
    cache_control4.5
    open section ↗
  • Two ways to build the tree summary
    Only the section summary, glossary, orientation context, and suggestions are model-authored; the tree structure, verbatim facts, overview, per-section hashes, and anchors are derived deterministically in code, so the model only supplies the distillation. That distillation can run in a Claude Code skill inside an existing subscription with no key and no per-build token spend (the recommended path), or unattended through the one-call CLI build for CI; either way the build is incremental and hash-gated and the tree is reviewed in pull requests.
    facts · quoted verbatim
    summarycontextsuggestionsfacts.hev-ask/ANTHROPIC_API_KEYask digest build4.8
    open section ↗
  • Digest creation summary
    The ask digest is created offline and committed to the repo like any other source file: a build reads markdown off the filesystem, distills each section into a small markdown file, and writes the tree. The running site, CLI, and MCP server all read that committed artifact and never call a model to serve it.
    facts · quoted verbatim
    .hev-ask/Callout.astroCodeTabs.astro
    open section ↗
  • Built from markdown, not from a renderer summary
    The build never imports your framework; it reads files, chunks on headings, derives anchors in code, and writes the tree, so the same artifact comes out whether Astro, Docusaurus, VitePress, MkDocs, or nothing renders the pages. What differs per host is only when the build runs — during the Astro build when a key is present, and a build or CI step everywhere else — while wiring the overlay into a non-Astro site is a separate, smaller job.
    facts · quoted verbatim
    astro build
    open section ↗
  • Incremental by hash summary
    Every section file records the hash of the content it was distilled from, so a rebuild re-distills only the sections whose hash changed and a clean tree does no model work at all. That makes rebuilding on every content change cheap enough to be the intended workflow rather than a chore.
    no verbatim facts in this section open section ↗
  • Two ways to run the build summary
    The build runs two ways that write the same tree under the same hash gate: the recommended bundled Claude Code skill builds inside your subscription with no key and no token spend, sharding the corpus and distilling each shard in a fresh context so size never hits a context limit; and the CLI build does the same distillation unattended in one API call for CI or outside Claude Code, on the default provider or any provider via a flag. The full command set, flags, and sharded flow are in the CLI reference.
    facts · quoted verbatim
    You: build the hev ask digest Claude runs: ask digest corpus # emits the sections to distil …writes context/glossary/summaries/suggestions… ask digest assemble # writes the .hev-ask/ treeexport ANTHROPIC_API_KEY=sk-ant-... pnpm exec ask digest buildexport OPENAI_API_KEY=sk-... pnpm exec ask digest build --provider openaiexport OPENROUTER_API_KEY=sk-or-... pnpm exec ask digest build --provider openrouterbuild-digestANTHROPIC_API_KEY--provider4.8
    open section ↗
  • Verify, review, commit summary
    The verify command is the CI gate: it builds the site, fails when any section's anchor is missing from the rendered HTML, and warns on coverage or fidelity drift, after which you commit the tree. Because the tree is markdown, a section's distilled prose and grounded facts change together in one reviewable diff and are reviewed in pull requests; the digest regenerates only when content changes and a build runs, with the runtime logging a warning on hash mismatch as a rebuild cue while a stale digest degrades rather than breaks.
    facts · quoted verbatim
    pnpm exec ask digest verify # builds the site, checks every anchor resolves git add .hev-askask digest verify
    open section ↗
  • What the model writes summary
    Only the distillation is model-authored — each section's summary, the glossary, the orientation context, and the suggested questions — while the structure, verbatim facts, overview, anchors, and per-section hashes are derived deterministically in code. That seam is what lets the model step run anywhere a model is available, including inside your editor.
    no verbatim facts in this section open section ↗
  • Introduction summary
    hev ask distills a docs site into an ask digest, a compact directory with one small markdown file per section that an agent navigates like any directory and a ⌘K overlay answers readers from. The digest is host-neutral because it is built from your markdown rather than your renderer, works with Astro, Docusaurus, VitePress, MkDocs, or any folder of markdown, ships a turnkey Astro integration with a one-script add for other frameworks, and is built offline and committed so the docs become readable three ways from one artifact; it suits technical documentation, internal wikis, and other medium-sized corpora.
    facts · quoted verbatim
    ⌘KDiagram.astroCallout.astroastro.build
    open section ↗
  • Next steps summary
    A pointer list to the next pages: Quick start, Digest creation, Concepts, Tradeoffs and Limits, the CLI, and the API reference.
    facts · quoted verbatim
    asktreecatgrep
    open section ↗
  • One artifact, three readers summary
    The digest is built inside your coding agent with the bundled skill using an existing subscription, with no key and no per-build token spend, and once committed the same files serve three readers: the ⌘K overlay for humans with instant keyword results plus a grounded answer on Enter and deep links; the CLI for agents to map, read, pull facts, and search over path keys keylessly from any shell; and the MCP server for agents, whose one tool hydrates the whole tree to disk for the agent's own file tools. hev ask only reads the content you point it at, with no crawler, no external index, and nothing to keep in sync, and the committed tree is reviewable per section in every pull request.
    facts · quoted verbatim
    .hev-ask/ANTHROPIC_API_KEY⌘Kasktreecatfactsgrepask mcpdocs/
    open section ↗
  • Who this is for summary
    hev ask suits anyone building a docs site whose content is Markdown or MDX on Astro, Docusaurus, VitePress, MkDocs, or any folder of markdown, who wants search that works without standing up a service or crawler, deep-links to the right section, answers questions in the reader's own words, and is queryable by a coding agent. On Astro one integration covers all of that; other frameworks drop in the static overlay and optionally point it at a hosted endpoint for answers. If you only need keyword search over a static site and never want a key in the loop, Pagefind is simpler and a good fit.
    facts · quoted verbatim
    pagefind.app
    open section ↗
  • Limits summary
    These are the hard boundaries to know before adopting hev ask — corpus scope, recall ceiling, build limits, frontmatter parsing, latency, and adapter requirements. None are bugs; they are the edges of what the current design covers.
    facts · quoted verbatim
    Callout.astro
    open section ↗
  • Agentic search adds latency summary
    The agentic path is bounded by the configured number of model round-trips, so worst case is a few seconds and it is not instant by nature. The keyword path is the always-available instant lane while agentic search is the considered one, and the iteration cap can be tuned down for a tighter ceiling.
    facts · quoted verbatim
    maxIterations
    open section ↗
  • Anchors depend on the renderer's slugger summary
    Deep links are only correct while the heading slugs hev ask generates match the renderer's id attributes; it uses the GitHub-aligned slugger by default and each framework adapter declares its own scheme where that differs. Either way the verify command fails if any chunk anchor is missing from the built HTML, so wiring verify into CI is what catches a slugging change before a broken link ships.
    facts · quoted verbatim
    idgithub-sluggerask digest verifyverify
    open section ↗
  • Frontmatter parsing is a flat-YAML subset summary
    The offline build parses frontmatter with a small flat-YAML splitter rather than a full YAML parser, handling the common docs schema of string and number fields but not nested structures. This affects only the offline build reading files from disk; on Astro the runtime index uses the collection API and honors your real schema.
    facts · quoted verbatim
    getCollection
    open section ↗
  • Recall has a keyword ceiling summary
    Retrieval is keyword token-overlap widened by the glossary rather than embeddings, and the agentic loop can only ground in what retrieval finds. The glossary recovers most synonym cases, but a reader searching in language that shares no tokens with the docs and isn't in the glossary may never surface the right section; embeddings are the known fix for paraphrase recall and are deliberately not built yet, so until analytics show consistent misses, a richer glossary is the cheaper lever.
    facts · quoted verbatim
    k8skubernetes
    open section ↗
  • Secrets live server-side summary
    The agentic path needs the configured provider's API key in the server environment that runs the endpoint, and the key is never exposed to the browser. If the key isn't present at runtime the endpoint serves keyword results, so search degrades rather than breaking.
    facts · quoted verbatim
    ANTHROPIC_API_KEYOPENAI_API_KEYOPENROUTER_API_KEYprovider/api/ask
    open section ↗
  • The agentic path needs a server somewhere summary
    Keyword search runs fully static from the committed digest in the browser with no server on any host, but the agentic path needs a runtime: on Astro it is the on-demand endpoint route requiring a server or hybrid adapter, and on other frameworks it is the standalone hostable endpoint you deploy and point the overlay at. A purely static site can ship keyword search with nothing hosted but can't answer questions until an endpoint exists somewhere.
    facts · quoted verbatim
    /api/ask
    open section ↗
  • The corpus is the content you configure summary
    hev ask searches only the markdown you point it at — a content collection, a docs tree, or a set of globs — with no crawler, no sitemap ingestion, and no way to index pages outside the configured corpus such as a hand-written page or a bare route. A doc not in the corpus won't appear in search, so put what you want searchable where the adapter looks.
    facts · quoted verbatim
    docs/.astro
    open section ↗
  • The one-shot digest build is bounded; sharded builds are not summary
    The one-shot build sends the full cleaned corpus to the model in a single call, which fits a typical docs site but fails loudly past a section-text size threshold; beyond that the sharded build splits the corpus into prefix-stable shards each distilled in its own context and merged deterministically, so corpus size stops being a context-window problem and a content edit re-distills only the touched shard. The remaining scale consideration is the runtime prompt, since the agentic path inlines section summaries, so trees with tens of thousands of sections aren't yet a fit for the answer loop, though a coding agent reading the tree over MCP has no such ceiling.
    facts · quoted verbatim
    ask digest build
    open section ↗
  • Quick start summary
    Add hev ask to an existing Astro 5 docs site whose content lives in a collection in about five minutes: install the integration and drop in the overlay for keyword search with no key and nothing to host, then add a provider key on the server to enable the agentic answer loop on Enter, or skip the key if you only want the search UI. On any other framework you drop in the same overlay as a script tag and point it at a hosted endpoint for answers.
    facts · quoted verbatim
    src/content/docsANTHROPIC_API_KEY<script>Callout.astroCodeTabs.astro
    open section ↗
  • 1. Install summary
    Install the package from npm once published, or until then consume it straight from the package subdirectory on GitHub.
    facts · quoted verbatim
    pnpm add @hevmind/askpnpm add "git+ssh://[email protected]/hev/ask.git#main&path:/packages/ui"
    open section ↗
  • 2. Register the integration summary
    Register the integration in the Astro config by adding the hevAsk() call with your content collection names and a base path; the collections list is the one option you must set and everything else has a default.
    facts · quoted verbatim
    // astro.config.mjs import { defineConfig } from "astro/config"; import hevAsk from "@hevmind/ask"; export default defineConfig({ integrations: [ hevAsk({ collections: ["docs"], // your content collection name(s) basePath: "/docs/", // slug → URL prefix: basePath + slug }), ], });collections
    open section ↗
  • 3. Add a server adapter summary
    Because the endpoint route renders on demand, add whichever server or hybrid adapter matches your host while existing pages stay prerendered; the example uses the Cloudflare adapter.
    facts · quoted verbatim
    // astro.config.mjs import cloudflare from "@astrojs/cloudflare"; export default defineConfig({ adapter: cloudflare({ platformProxy: { enabled: true } }), // ...integrations as above });/api/ask
    open section ↗
  • 4. Render the overlay summary
    Add the overlay component once somewhere global like the base layout; any element with the opener attribute opens the palette and the keyboard shortcut is bound automatically. Keyword search works at this point — run the dev server and try it.
    facts · quoted verbatim
    --- // src/layouts/Base.astro import SearchOverlay from "@hevmind/ask/components/SearchOverlay.astro"; --- <button type="button" data-hev-ask-open> Search <kbd>⌘K</kbd> </button> <slot /> <SearchOverlay />data-hev-ask-open⌘Kastro dev
    open section ↗
  • 5. Build the digest summary
    The digest is an offline-built markdown tree you commit that gives the loop context, ranks keyword results, supplies the glossary, and holds suggested questions. Build it the recommended way with the bundled Claude Code skill inside your subscription (no key, no token spend), or with the one-call CLI build for CI choosing a provider, then verify anchors and commit; both paths are incremental and hash-gated, and the integration runs the build automatically during the site build when a key is present.
    facts · quoted verbatim
    You: build the hev ask digest Claude runs: ask digest corpus # emits the sections to distil …writes context/glossary/summaries/suggestions… ask digest assemble # writes the .hev-ask/ treeexport ANTHROPIC_API_KEY=sk-ant-... pnpm exec ask digest build # writes the .hev-ask/ treeexport OPENAI_API_KEY=sk-... pnpm exec ask digest build --provider openaiexport OPENROUTER_API_KEY=sk-or-... pnpm exec ask digest build --provider openrouterpnpm exec ask digest verify # builds the site, checks every anchor resolves git add .hev-askk8skubernetes--providerastro buildclaude.com
    open section ↗
  • Enable agentic search summary
    Set the provider's API key in the server environment where the endpoint runs, after which pressing Enter runs the agentic loop with self-issued sub-queries, a grounded answer, and inline deep links; without a key Enter returns keyword results. The Anthropic default needs only the key, while OpenAI and OpenRouter also need the matching provider set in the integration options.
    facts · quoted verbatim
    # the default provider — nothing else to configure export ANTHROPIC_API_KEY=sk-ant-...# with provider: "openai" in the hevAsk() options export OPENAI_API_KEY=sk-...# with provider: "openrouter" in the hevAsk() options export OPENROUTER_API_KEY=sk-or-.../api/ask.envprovider
    open section ↗
  • Prerequisites summary
    Prerequisites are Astro 5 with at least one content collection, a server or hybrid adapter because the endpoint route renders on demand and a fully static build can't serve it, and a provider API key to enable agentic search; keyword search needs no key, and OpenAI and OpenRouter work via the provider option though the guide uses the Anthropic default.
    facts · quoted verbatim
    /api/askANTHROPIC_API_KEYproviderdocs.astro.build
    open section ↗
  • Set up keyword search summary
    Section header introducing the keyless keyword-search setup steps that follow.
    no verbatim facts in this section open section ↗
  • Verify it works summary
    Verify the install three ways: a single heading word should deep-link to that section, a multi-word question on Enter should show the model's sub-queries and stream a grounded answer with inline deep links, and the verify command exits non-zero if any chunk anchor is missing from the built HTML, so wire it into CI. From here, read the configuration options or Concepts.
    facts · quoted verbatim
    /docs/page#headingask digest verify
    open section ↗
  • Tradeoffs summary
    Every search tool makes choices, and this page is the honest version of what hev ask trades away to get what it gives, so you can decide whether the trade fits your docs.
    facts · quoted verbatim
    Callout.astro
    open section ↗
  • A committed digest summary
    The digest is generated offline and committed to git as a markdown tree rather than computed at runtime or hidden in a service. The upside is that it is reviewable per section in pull requests, deterministic and free to read at runtime, bundled into the edge worker without filesystem access, and directly navigable by an agent; the cost is that it can go stale, regenerating only on a content change and build, though the runtime warns on hash mismatch and the per-section hash gate makes rebuilding on every content change in CI the intended workflow.
    facts · quoted verbatim
    treecatgrep
    open section ↗
  • A flagship adapter, primitives for the rest summary
    hev ask is host-neutral at the core but opinionated about Astro: the Astro integration is batteries-included from one config block, while every other framework wires two primitives itself — the static overlay and, for answers, the standalone endpoint. The upside is that the digest, overlay, CLI, and MCP are the same everywhere so a new framework is an adapter rather than a fork and the keyword path needs nothing hosted; the cost is that off Astro you do the wiring the integration would have done, and a turnkey plugin per framework is a goal rather than a guarantee.
    facts · quoted verbatim
    <script>/api/ask
    open section ↗
  • Cost and latency of agentic search summary
    The agentic path calls the model, meaning real if small cost and latency: worst-case latency is roughly the iteration count of small-model round-trips (a few seconds) with the keyword path staying instant and the iteration cap as the knob, and cost is one bounded loop per submitted query on the default small model with domain context prompt-cached across rounds. The offline build uses a stronger model but the hash gate means you pay for it only when content changes, and keyword-only is a first-class mode if you want no key in the loop.
    facts · quoted verbatim
    maxIterations
    open section ↗
  • How it compares summary
    A comparison table across retrieval method, AI ranking, deep links, and hosting for hev ask, Pagefind, Algolia DocSearch, and Orama. The summary: choose Pagefind for simple zero-service keyword search with no key, Algolia for a managed crawler-based keyword service, Orama for client-side vector search you manage, and hev ask if your docs are a folder of markdown on any framework, you want deep links to sections, and you want a reader's question rather than just their keywords to find the right section.
    no verbatim facts in this section open section ↗
  • Keyword retrieval, not embeddings summary
    Retrieval is dependency-free token overlap widened by the glossary, with no embeddings or vector store. The upside is nothing to host or keep in sync, edge-safe and instant, with the glossary recovering much synonym recall; the cost is a paraphrase-recall ceiling, since the agent can only ground in what keyword retrieval found, so readers who routinely search in words sharing no tokens with the docs and absent from the glossary would be better served by embeddings — an upgrade deferred rather than designed out.
    no verbatim facts in this section open section ↗
  • One dependency, deliberately summary
    hev ask aims to be near zero-dependency with one deliberate exception: the heading slugger, a tiny pure-JS edge-safe library. Generating anchors by hand risks drifting from the renderer and shipping a link that 404s to the top of the page, so using the same slugger the renderer uses guarantees byte-identical anchors, with per-framework adapters extending that guarantee to their slug rules; the dependency was taken on purpose.
    facts · quoted verbatim
    github-sluggergithub.com
    open section ↗
  • Two paths instead of one summary
    hev ask runs an instant keyword path and an agentic path and asks the reader to choose between them by pressing Enter. The upside is that the common case of a word or two stays instant and keyless while hard questions get a smarter ranker; the cost is a slightly more complex interaction model than a single search box, since readers must learn that Enter means asking AI, which the page argues is the right trade for docs where queries split between jumping to a known thing and finding an unnameable one.
    no verbatim facts in this section open section ↗
Normalized digest data
{
  "version": 2,
  "generatedAt": "2026-06-19T02:40:57.073Z",
  "contentHash": "0d50d5f620f95e4b3d44c731ec546540a5acf9b4e30d01d448c9c8d270e28348",
  "context": "**hev ask** (`@hevmind/ask`) is a `⌘K` search overlay and agent-readable docs distillation, documented at hevask.com, a site that searches itself with the package. The central artifact is the **ask digest**: a committed, offline-built markdown tree (`.hev-ask/`, one small file per section) holding section summaries, verbatim facts, source anchors, a glossary, and a site overview. The same tree serves three readers: the `⌘K` overlay for humans, the `ask` CLI read verbs — `tree` to map it (a couple levels deep, `--depth` to go further), `cat` to read a section/`_glossary` entry/`_meta`, `facts` for grounded literals, `grep` to search — one verb per operation, since the tree is a real directory you can also `ls`/`head` — for agents, and the `ask mcp` server, which hydrates the tree to local disk so an agent reads it with its own file tools. The digest is host-neutral (built from markdown, not a renderer); Astro gets the turnkey `hevAsk()` integration, while Docusaurus, VitePress, MkDocs, and plain static sites use the drop-in static overlay plus an optional hostable endpoint. Two retrieval paths: instant keyless **keyword** search (token overlap widened by the digest glossary, deep-linking to `/docs/page#anchor` with anchors from github-slugger, gated in CI by `ask digest verify`) and an **agentic** answer on Enter (needs a server-side provider API key — `ANTHROPIC_API_KEY` by default; OpenAI and OpenRouter are supported via the `provider` option, with `providerBaseUrl` for any OpenAI-compatible endpoint — and streams SSE with inline citations to opened sections). The digest is hash-gated and incremental: rebuilds skip model work for unchanged sections, and it's buildable via the Claude Code skill (subscription, sharded), the one-shot CLI `ask digest build`, or the sharded flow for big sites. Everything degrades instead of hard-failing: no key means keyword mode, no tree means plain excerpts. The corpus is only the configured content collection(s) or globs, with no crawler. The `POST /api/ask` endpoint renders on demand, so the agentic path needs a server or hybrid adapter. The digest was formerly called the knowledge graph (kg) and was a digest.json; both are legacy names. Users compare hev ask against Pagefind, Algolia DocSearch, and Orama; the Tradeoffs and Limits pages answer that directly.",
  "glossary": [
    {
      "term": "adapter",
      "aliases": [
        "integration",
        "framework adapter",
        "hevAsk"
      ],
      "definition": "The per-framework glue that builds the digest and wires the overlay; Astro's is turnkey."
    },
    {
      "term": "agentic search",
      "aliases": [
        "ai search",
        "agentic loop",
        "ask ai",
        "answer loop"
      ],
      "definition": "The bounded tool-use loop that gathers sections and streams a grounded, cited answer on Enter."
    },
    {
      "term": "anchor",
      "aliases": [
        "deep link",
        "heading anchor",
        "slug"
      ],
      "definition": "The per-heading id used to deep-link a result to the exact section it answers."
    },
    {
      "term": "digest",
      "aliases": [
        "ask digest",
        "kg",
        "knowledge graph",
        ".hev-ask"
      ],
      "definition": "The committed offline-built markdown tree, one file per doc section, that all readers navigate."
    },
    {
      "term": "facts",
      "aliases": [
        "grounded literals",
        "verbatim facts"
      ],
      "definition": "Verbatim flags, code, and identifiers extracted deterministically so an agent quotes exact strings."
    },
    {
      "term": "keyword search",
      "aliases": [
        "instant search",
        "keyword mode",
        "type-ahead"
      ],
      "definition": "The keyless, instant token-overlap search widened by the glossary that runs as you type."
    },
    {
      "term": "MCP",
      "aliases": [
        "mcp server",
        "model context protocol",
        "ask mcp"
      ],
      "definition": "The stdio server whose one tool hydrates the digest tree to disk for a coding agent."
    },
    {
      "term": "overlay",
      "aliases": [
        "search overlay",
        "command palette",
        "cmdk",
        "command-k"
      ],
      "definition": "The ⌘K UI that searches the digest and synthesizes answers for human readers."
    },
    {
      "term": "provider",
      "aliases": [
        "llm provider",
        "anthropic",
        "openai",
        "openrouter"
      ],
      "definition": "The pluggable inference backend for the loop and digest build, each with its own key env var."
    },
    {
      "term": "shard",
      "aliases": [
        "sharded build",
        "sharding"
      ],
      "definition": "A slug-prefix slice of the corpus distilled in its own fresh context so build size never hits a context limit."
    }
  ],
  "overview": "## API\n- CLI — `api/cli`\n- Building the digest — `api/cli#building-the-digest`\n- Claude Code skill — `api/cli#claude-code-skill`\n- Distribution — `api/cli#distribution`\n- Flags — `api/cli#flags`\n- Go library — `api/cli#go-library`\n- MCP — `api/cli#mcp`\n- Reading the digest as a directory — `api/cli#reading-the-digest-as-a-directory`\n- Sharded builds for large sites — `api/cli#sharded-builds-for-large-sites`\n- Where it runs — `api/cli#where-it-runs`\n- Configuration — `api/configuration`\n- Choosing a provider — `api/configuration#choosing-a-provider`\n- Options — `api/configuration#options`\n- Tuning notes — `api/configuration#tuning-notes`\n- TypeScript — `api/configuration#typescript`\n- What the integration does — `api/configuration#what-the-integration-does`\n- Digest format — `api/digest`\n- _meta.md and _glossary/ — `api/digest#_metamd-and-_glossary`\n- A section file — `api/digest#a-section-file`\n- Degradation — `api/digest#degradation`\n- Frontmatter fields — `api/digest#frontmatter-fields`\n- How each field is used — `api/digest#how-each-field-is-used`\n- Layout — `api/digest#layout`\n- Regenerating — `api/digest#regenerating`\n- Search endpoint — `api/endpoint`\n- Agentic response (SSE) — `api/endpoint#agentic-response-sse`\n- Digest reads (GET) — `api/endpoint#digest-reads-get`\n- Errors — `api/endpoint#errors`\n- Index lifecycle — `api/endpoint#index-lifecycle`\n- Keyword response (JSON) — `api/endpoint#keyword-response-json`\n- LLM tracing — `api/endpoint#llm-tracing`\n- Mode selection — `api/endpoint#mode-selection`\n- Request — `api/endpoint#request`\n- Suggested questions (GET) — `api/endpoint#suggested-questions-get`\n- The API key — `api/endpoint#the-api-key`\n- MCP server — `api/mcp`\n- Co-location — `api/mcp#co-location`\n- Configure — `api/mcp#configure`\n- Data sources — `api/mcp#data-sources`\n- Protocol surface — `api/mcp#protocol-surface`\n- The instructions — `api/mcp#the-instructions`\n- The tool — `api/mcp#the-tool`\n- SearchOverlay component — `api/search-overlay`\n- Any static site — `api/search-overlay#any-static-site`\n- Bundling the static assets — `api/search-overlay#bundling-the-static-assets`\n- Docusaurus — `api/search-overlay#docusaurus`\n- Keyboard model — `api/search-overlay#keyboard-model`\n- Keyword results and deep links — `api/search-overlay#keyword-results-and-deep-links`\n- MkDocs — `api/search-overlay#mkdocs`\n- Opening the overlay — `api/search-overlay#opening-the-overlay`\n- Props — `api/search-overlay#props`\n- Suggested questions — `api/search-overlay#suggested-questions`\n- Support at a glance — `api/search-overlay#support-at-a-glance`\n- The hostable endpoint — `api/search-overlay#the-hostable-endpoint`\n- The mode toggle — `api/search-overlay#the-mode-toggle`\n- The overlay on other frameworks — `api/search-overlay#the-overlay-on-other-frameworks`\n- The streamed answer — `api/search-overlay#the-streamed-answer`\n- Theming — `api/search-overlay#theming`\n- VitePress — `api/search-overlay#vitepress`\n## Overview\n- Concepts — `concepts`\n- Asking is the default — `concepts#asking-is-the-default`\n- Chunks and anchors — `concepts#chunks-and-anchors`\n- Degradation, by design — `concepts#degradation-by-design`\n- Host-neutral: one digest, any framework — `concepts#host-neutral-one-digest-any-framework`\n- Keyword search and the glossary — `concepts#keyword-search-and-the-glossary`\n- Progressive disclosure as a directory — `concepts#progressive-disclosure-as-a-directory`\n- The agentic search loop — `concepts#the-agentic-search-loop`\n- The ask digest directory — `concepts#the-ask-digest-directory`\n- The system prompt is cached — `concepts#the-system-prompt-is-cached`\n- Two ways to build the tree — `concepts#two-ways-to-build-the-tree`\n- Digest creation — `digest-creation`\n- Built from markdown, not from a renderer — `digest-creation#built-from-markdown-not-from-a-renderer`\n- Incremental by hash — `digest-creation#incremental-by-hash`\n- Two ways to run the build — `digest-creation#two-ways-to-run-the-build`\n- Verify, review, commit — `digest-creation#verify-review-commit`\n- What the model writes — `digest-creation#what-the-model-writes`\n- Introduction — `index`\n- Next steps — `index#next-steps`\n- One artifact, three readers — `index#one-artifact-three-readers`\n- Who this is for — `index#who-this-is-for`\n- Limits — `limits`\n- Agentic search adds latency — `limits#agentic-search-adds-latency`\n- Anchors depend on the renderer's slugger — `limits#anchors-depend-on-the-renderers-slugger`\n- Frontmatter parsing is a flat-YAML subset — `limits#frontmatter-parsing-is-a-flat-yaml-subset`\n- Recall has a keyword ceiling — `limits#recall-has-a-keyword-ceiling`\n- Secrets live server-side — `limits#secrets-live-server-side`\n- The agentic path needs a server somewhere — `limits#the-agentic-path-needs-a-server-somewhere`\n- The corpus is the content you configure — `limits#the-corpus-is-the-content-you-configure`\n- The one-shot digest build is bounded; sharded builds are not — `limits#the-one-shot-digest-build-is-bounded-sharded-builds-are-not`\n- Quick start — `quickstart`\n- 1. Install — `quickstart#1-install`\n- 2. Register the integration — `quickstart#2-register-the-integration`\n- 3. Add a server adapter — `quickstart#3-add-a-server-adapter`\n- 4. Render the overlay — `quickstart#4-render-the-overlay`\n- 5. Build the digest — `quickstart#5-build-the-digest`\n- Enable agentic search — `quickstart#enable-agentic-search`\n- Prerequisites — `quickstart#prerequisites`\n- Set up keyword search — `quickstart#set-up-keyword-search`\n- Verify it works — `quickstart#verify-it-works`\n- Tradeoffs — `tradeoffs`\n- A committed digest — `tradeoffs#a-committed-digest`\n- A flagship adapter, primitives for the rest — `tradeoffs#a-flagship-adapter-primitives-for-the-rest`\n- Cost and latency of agentic search — `tradeoffs#cost-and-latency-of-agentic-search`\n- How it compares — `tradeoffs#how-it-compares`\n- Keyword retrieval, not embeddings — `tradeoffs#keyword-retrieval-not-embeddings`\n- One dependency, deliberately — `tradeoffs#one-dependency-deliberately`\n- Two paths instead of one — `tradeoffs#two-paths-instead-of-one`",
  "suggestions": [
    "How do I add hev ask to my Astro site?",
    "Can I use hev ask on Docusaurus or MkDocs?",
    "How does the agentic answer loop work?",
    "How do I build and refresh the ask digest?",
    "What can't hev ask do?"
  ],
  "nodes": [
    {
      "id": "api/cli",
      "kind": "section",
      "title": "CLI",
      "heading": null,
      "group": "API",
      "url": "/docs/api/cli",
      "summary": "The ask CLI treats the committed digest as a directory: read verbs map, read, pull grounded literals from, and search it, plus a synthesized cited reply and a server for agents. A separate producer command group builds, verifies, and serves the digest.",
      "hash": "f9dd2f3be3ca7de2dd148ca07176d2a5bd6c9ffc1aa4f12e4d923c6c1b2716c8",
      "facts": [
        {
          "kind": "code",
          "literal": "@hevmind/ask",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "ask",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "tree",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "cat",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "facts",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "grep",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "answer",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "mcp",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "ask digest",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "build",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "corpus",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "assemble",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "verify",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "status",
          "chunkId": "api/cli"
        },
        {
          "kind": "code",
          "literal": "migrate",
          "chunkId": "api/cli"
        },
        {
          "kind": "value",
          "literal": "Callout.astro",
          "chunkId": "api/cli"
        },
        {
          "kind": "value",
          "literal": "CodeTabs.astro",
          "chunkId": "api/cli"
        }
      ],
      "sources": [
        {
          "chunkId": "api/cli",
          "url": "/docs/api/cli",
          "anchor": null
        }
      ],
      "mode": "source-primary",
      "terms": [
        "treats",
        "committed",
        "digest",
        "directory",
        "read",
        "verbs",
        "pull",
        "grounded",
        "literals",
        "search",
        "plus",
        "synthesized",
        "cited",
        "reply",
        "server",
        "agents",
        "separate",
        "producer",
        "command",
        "group",
        "builds",
        "verifies",
        "serves",
        "hevmind",
        "tree",
        "facts",
        "grep",
        "answer",
        "build",
        "corpus",
        "assemble",
        "verify",
        "status",
        "migrate",
        "callout",
        "astro",
        "codetabs",
        "reads",
        "path",
        "keys"
      ]
    },
    {
      "id": "api/cli#building-the-digest",
      "kind": "section",
      "title": "CLI",
      "heading": "Building the digest",
      "group": "API",
      "url": "/docs/api/cli#building-the-digest",
      "summary": "Producer commands run from the site root to build, emit a keyless corpus, assemble the tree, verify, report shard coverage, and migrate a legacy JSON digest. Only the build calls a model and is the only one needing a key; it is incremental and hash-gated, so a clean tree calls the model zero times, and a one-shot build is bounded by section-text size before it requires the sharded flow. The model authors only context, glossary, summaries, and suggestions; everything else is computed deterministically.",
      "hash": "c8c9b3c2808376bf87bc7128a3a9a84bdde6aa70ac2011e1ccb1debae2976f33",
      "facts": [
        {
          "kind": "code",
          "literal": "export ANTHROPIC_API_KEY=sk-ant-...\nask digest build                    # claude-opus-4-8 by default",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "code",
          "literal": "export OPENAI_API_KEY=sk-...\nask digest build --provider openai  # gpt-5.1 by default",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "code",
          "literal": "export OPENROUTER_API_KEY=sk-or-...\nask digest build --provider openrouter   # anthropic/claude-opus-4.8 by default",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "code",
          "literal": "ask digest build",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "code",
          "literal": "--provider",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "code",
          "literal": "ask digest corpus",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "code",
          "literal": "ask digest assemble",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "code",
          "literal": ".hev-ask/",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "code",
          "literal": "context",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "code",
          "literal": "summaries",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "code",
          "literal": "suggestions",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "code",
          "literal": ".hev-ask/digest.json",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "code",
          "literal": "ask digest migrate",
          "chunkId": "api/cli#building-the-digest"
        },
        {
          "kind": "value",
          "literal": "digest.json",
          "chunkId": "api/cli#building-the-digest"
        }
      ],
      "sources": [
        {
          "chunkId": "api/cli#building-the-digest",
          "url": "/docs/api/cli#building-the-digest",
          "anchor": "building-the-digest"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "building",
        "digest",
        "producer",
        "commands",
        "site",
        "root",
        "build",
        "emit",
        "keyless",
        "corpus",
        "assemble",
        "tree",
        "verify",
        "report",
        "shard",
        "coverage",
        "migrate",
        "legacy",
        "json",
        "only",
        "calls",
        "model",
        "needing",
        "incremental",
        "hash",
        "gated",
        "clean",
        "zero",
        "times",
        "shot",
        "bounded",
        "section",
        "text",
        "size",
        "before",
        "requires",
        "sharded",
        "flow",
        "authors",
        "context"
      ]
    },
    {
      "id": "api/cli#claude-code-skill",
      "kind": "section",
      "title": "CLI",
      "heading": "Claude Code skill",
      "group": "API",
      "url": "/docs/api/cli#claude-code-skill",
      "summary": "The bundled build-digest skill builds the tree inside a Claude Code subscription without an API key by running the deterministic producer seam sharded: emit a corpus, distill each shard in a fresh context, synthesize over the shard notes, then assemble. Because each shard is its own context, corpus size never hits a context limit, and the result matches a normal build with the same incremental hash gate.",
      "hash": "443db6e48ac36d708dfd7e6b19f5e65b8f34ee4eb0675c8da98bd86cacfecc96",
      "facts": [
        {
          "kind": "code",
          "literal": "ask digest corpus --shards-dir .hev-ask/shards    -> input-<id>.json + manifest.json\n...one fresh-context distillation per shard       -> distill-<id>.json...\n...one synthesis pass over the shard notes        -> global.json...\nask digest assemble --input-dir .hev-ask/shards   -> the .hev-ask/ tree",
          "chunkId": "api/cli#claude-code-skill"
        },
        {
          "kind": "code",
          "literal": "build-digest",
          "chunkId": "api/cli#claude-code-skill"
        },
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "api/cli#claude-code-skill"
        },
        {
          "kind": "code",
          "literal": "ask digest build",
          "chunkId": "api/cli#claude-code-skill"
        }
      ],
      "sources": [
        {
          "chunkId": "api/cli#claude-code-skill",
          "url": "/docs/api/cli#claude-code-skill",
          "anchor": "claude-code-skill"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "claude",
        "code",
        "skill",
        "bundled",
        "build",
        "digest",
        "builds",
        "tree",
        "inside",
        "subscription",
        "without",
        "running",
        "deterministic",
        "producer",
        "seam",
        "sharded",
        "emit",
        "corpus",
        "distill",
        "shard",
        "fresh",
        "context",
        "synthesize",
        "notes",
        "assemble",
        "because",
        "size",
        "never",
        "hits",
        "limit",
        "result",
        "matches",
        "normal",
        "same",
        "incremental",
        "hash",
        "gate",
        "shards",
        "input",
        "json"
      ]
    },
    {
      "id": "api/cli#distribution",
      "kind": "section",
      "title": "CLI",
      "heading": "Distribution",
      "group": "API",
      "url": "/docs/api/cli#distribution",
      "summary": "The npm package exposes a single bin whose launcher resolves an environment-variable override first, then a platform-specific optional binary package, then the checked-out Go source as a development fallback. Published installs use the packaged binary.",
      "hash": "6ca69ef59f845bf9734dc9ec208f3fa63fdd9272703d454891bdbebb56fcda55",
      "facts": [
        {
          "kind": "code",
          "literal": "ask",
          "chunkId": "api/cli#distribution"
        },
        {
          "kind": "code",
          "literal": "HEV_ASK_BINARY",
          "chunkId": "api/cli#distribution"
        }
      ],
      "sources": [
        {
          "chunkId": "api/cli#distribution",
          "url": "/docs/api/cli#distribution",
          "anchor": "distribution"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "distribution",
        "package",
        "exposes",
        "single",
        "whose",
        "launcher",
        "resolves",
        "environment",
        "variable",
        "override",
        "first",
        "platform",
        "specific",
        "optional",
        "binary",
        "checked",
        "source",
        "development",
        "fallback",
        "published",
        "installs",
        "packaged",
        "hevaskbinary",
        "installed",
        "monorepo",
        "path"
      ]
    },
    {
      "id": "api/cli#flags",
      "kind": "section",
      "title": "CLI",
      "heading": "Flags",
      "group": "API",
      "url": "/docs/api/cli#flags",
      "summary": "A reference table of every CLI flag with its default and purpose, covering digest paths, remote endpoint reads, JSON output, tree depth, result caps, collection and chunking controls, the digest model and provider selection, sharding inputs, and verify options. Global flags come before the subcommand.",
      "hash": "5d1a8038354ca7c57c1f2e3fbe3b99e9d22881cbbfd064e764ef233dc3e098d3",
      "facts": [
        {
          "kind": "code",
          "literal": "ask --digest-dir .hev-ask --json grep \"openapi\"\nask --endpoint https://hevask.com/api/ask cat api/endpoint\nask digest build --collection docs --collection guides --chunk-heading-depth 2\nask digest verify --skip-build",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "--digest-dir <dir>",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": ".hev-ask",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "--endpoint <url>",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "/api/ask",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "answer",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "--json",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "--depth <n\\|all>",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "tree",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "(+N)",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "all",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "--max-results <n>",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "grep",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "--collection <name>",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "docs",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "--base-path <path>",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "/docs/",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "--content-glob <glob>",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "--chunk-heading-depth <n>",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "--digest-model <model>",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "ask digest build",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "claude-opus-4-8",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "--provider <name>",
          "chunkId": "api/cli#flags"
        },
        {
          "kind": "code",
          "literal": "anthropic",
          "chunkId": "api/cli#flags"
        }
      ],
      "sources": [
        {
          "chunkId": "api/cli#flags",
          "url": "/docs/api/cli#flags",
          "anchor": "flags"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "flags",
        "reference",
        "table",
        "every",
        "flag",
        "default",
        "purpose",
        "covering",
        "digest",
        "paths",
        "remote",
        "endpoint",
        "reads",
        "json",
        "output",
        "tree",
        "depth",
        "result",
        "caps",
        "collection",
        "chunking",
        "controls",
        "model",
        "provider",
        "selection",
        "sharding",
        "inputs",
        "verify",
        "options",
        "global",
        "come",
        "before",
        "subcommand",
        "grep",
        "openapi",
        "https",
        "hevask",
        "build",
        "docs",
        "guides"
      ]
    },
    {
      "id": "api/cli#go-library",
      "kind": "section",
      "title": "CLI",
      "heading": "Go library",
      "group": "API",
      "url": "/docs/api/cli#go-library",
      "summary": "A reusable Go API exposes pure helpers and a dependency-free command group you can mount in your own CLI, including loaders, section listing and retrieval, search, an endpoint client, and an MCP server. It supports reading the tree from disk or an embedded filesystem.",
      "hash": "fdda297bbdabdbd250da161cec7574e09209c99f50b254923354681e1bef245c",
      "facts": [
        {
          "kind": "code",
          "literal": "group := ask.NewCommandGroup(ask.CommandOptions{\n\tDigestDir: \".hev-ask\",\n})\nerr := group.Run(ctx, []string{\"cat\", \"overview/quick-start\"}, os.Stdin, os.Stdout, os.Stderr)",
          "chunkId": "api/cli#go-library"
        },
        {
          "kind": "code",
          "literal": "pkg/ask",
          "chunkId": "api/cli#go-library"
        },
        {
          "kind": "code",
          "literal": "LoadDigest",
          "chunkId": "api/cli#go-library"
        },
        {
          "kind": "code",
          "literal": "embed.FS",
          "chunkId": "api/cli#go-library"
        },
        {
          "kind": "code",
          "literal": "ListSectionSummaries",
          "chunkId": "api/cli#go-library"
        },
        {
          "kind": "code",
          "literal": "GetSection",
          "chunkId": "api/cli#go-library"
        },
        {
          "kind": "code",
          "literal": "SearchDigest",
          "chunkId": "api/cli#go-library"
        },
        {
          "kind": "code",
          "literal": "NewEndpointClient",
          "chunkId": "api/cli#go-library"
        },
        {
          "kind": "code",
          "literal": "ServeMCP",
          "chunkId": "api/cli#go-library"
        }
      ],
      "sources": [
        {
          "chunkId": "api/cli#go-library",
          "url": "/docs/api/cli#go-library",
          "anchor": "go-library"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "library",
        "reusable",
        "exposes",
        "pure",
        "helpers",
        "dependency",
        "free",
        "command",
        "group",
        "mount",
        "including",
        "loaders",
        "section",
        "listing",
        "retrieval",
        "search",
        "endpoint",
        "client",
        "server",
        "supports",
        "reading",
        "tree",
        "disk",
        "embedded",
        "filesystem",
        "newcommandgroup",
        "commandoptions",
        "digestdir",
        "string",
        "overview",
        "quick",
        "start",
        "stdin",
        "stdout",
        "stderr",
        "loaddigest",
        "embed",
        "listsectionsummaries",
        "getsection",
        "searchdigest"
      ]
    },
    {
      "id": "api/cli#mcp",
      "kind": "section",
      "title": "CLI",
      "heading": "MCP",
      "group": "API",
      "url": "/docs/api/cli#mcp",
      "summary": "The CLI's MCP command runs a stdio server with one tool that downloads the whole digest tree to local disk and returns the title-tree inline, after which the agent reads the files with its own tools. It can point at a checked-out repo or a deployed endpoint via configuration.",
      "hash": "e9ba5f690d5158797f3f370cbc8f7a816946b64c3da22ea8ece21bc4d9afba91",
      "facts": [
        {
          "kind": "code",
          "literal": "{\n  \"mcpServers\": {\n    \"hevask\": {\n      \"command\": \"ask\",\n      \"args\": [\"--endpoint\", \"https://hevask.com/api/ask\", \"mcp\"]\n    }\n  }\n}",
          "chunkId": "api/cli#mcp"
        },
        {
          "kind": "code",
          "literal": "ask mcp",
          "chunkId": "api/cli#mcp"
        },
        {
          "kind": "code",
          "literal": "tree",
          "chunkId": "api/cli#mcp"
        },
        {
          "kind": "code",
          "literal": "cat",
          "chunkId": "api/cli#mcp"
        },
        {
          "kind": "code",
          "literal": "grep",
          "chunkId": "api/cli#mcp"
        }
      ],
      "sources": [
        {
          "chunkId": "api/cli#mcp",
          "url": "/docs/api/cli#mcp",
          "anchor": "mcp"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "command",
        "runs",
        "stdio",
        "server",
        "tool",
        "downloads",
        "whole",
        "digest",
        "tree",
        "local",
        "disk",
        "returns",
        "title",
        "inline",
        "after",
        "agent",
        "reads",
        "files",
        "tools",
        "point",
        "checked",
        "repo",
        "deployed",
        "endpoint",
        "configuration",
        "mcpservers",
        "hevask",
        "args",
        "https",
        "grep",
        "page",
        "instructions",
        "ships",
        "archive",
        "cache"
      ]
    },
    {
      "id": "api/cli#reading-the-digest-as-a-directory",
      "kind": "section",
      "title": "CLI",
      "heading": "Reading the digest as a directory",
      "group": "API",
      "url": "/docs/api/cli#reading-the-digest-as-a-directory",
      "summary": "By default the CLI reads the local tree; a remote endpoint flag reads a deployed site's HTTP API instead, with path-addressed reads that mirror doc URLs. Mapping the tree is the cheap first step, returning titles only and defaulting to two levels deep, scoped and deepened by a path and depth flag, with truncated directories reporting a hidden count; the glossary table is collapsed until you scope into it. Because the tree is real markdown, plain shell tools work on it, while the verbs add frontmatter, fuzzy path resolution, glossary aliases, and remote reads; the synthesized reply requires a remote endpoint, so keyless local retrieval uses search and read.",
      "hash": "90c1c568baea1522a00a439ee7e9874bb7988865a71bdd8af7759e1b4660f504",
      "facts": [
        {
          "kind": "code",
          "literal": "ask",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": ".hev-ask/",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "--endpoint <url>",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "ls",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "head",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "--endpoint",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "ask tree",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "--depth N",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "--depth all",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "(+N)",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "_glossary/",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "ask tree _glossary",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "cat",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "facts",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "ask answer",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "ask grep",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "ask cat",
          "chunkId": "api/cli#reading-the-digest-as-a-directory"
        }
      ],
      "sources": [
        {
          "chunkId": "api/cli#reading-the-digest-as-a-directory",
          "url": "/docs/api/cli#reading-the-digest-as-a-directory",
          "anchor": "reading-the-digest-as-a-directory"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "reading",
        "digest",
        "directory",
        "default",
        "reads",
        "local",
        "tree",
        "remote",
        "endpoint",
        "flag",
        "deployed",
        "site",
        "http",
        "instead",
        "path",
        "addressed",
        "mirror",
        "urls",
        "mapping",
        "cheap",
        "first",
        "step",
        "returning",
        "titles",
        "only",
        "defaulting",
        "levels",
        "deep",
        "scoped",
        "deepened",
        "depth",
        "truncated",
        "directories",
        "reporting",
        "hidden",
        "count",
        "glossary",
        "table",
        "collapsed",
        "until"
      ]
    },
    {
      "id": "api/cli#sharded-builds-for-large-sites",
      "kind": "section",
      "title": "CLI",
      "heading": "Sharded builds for large sites",
      "group": "API",
      "url": "/docs/api/cli#sharded-builds-for-large-sites",
      "summary": "The sharded flow removes the single-context bound by splitting the corpus along slug-prefix boundaries, distilling each shard independently, and merging on assembly. Sharding is stable and incremental: editing one doc re-pends only the shard that owns it, stale distillations are detected and skipped with a warning while affected sections fall back to plain excerpts, and the tree stays usable throughout. Verify builds the site and checks rendered anchors, coverage, literal fidelity, and tree integrity, with anchor drift always fatal and the rest warnings unless strict mode is set.",
      "hash": "edb0ce1e92994c33baa1814a21cdfb79ae95bdf7c3ffc385218dcd0f79c2d35e",
      "facts": [
        {
          "kind": "code",
          "literal": "ask digest corpus --shards-dir .hev-ask/shards   # input-<id>.json per shard + manifest.json\nask digest status --shards-dir .hev-ask/shards   # distilled / pending / stale, per shard\n# ...one distillation per shard writes distill-<id>.json; a final pass writes global.json...\nask digest assemble --input-dir .hev-ask/shards  # merge + write the .hev-ask/ tree",
          "chunkId": "api/cli#sharded-builds-for-large-sites"
        },
        {
          "kind": "code",
          "literal": "workers/...",
          "chunkId": "api/cli#sharded-builds-for-large-sites"
        },
        {
          "kind": "code",
          "literal": "pages/...",
          "chunkId": "api/cli#sharded-builds-for-large-sites"
        },
        {
          "kind": "code",
          "literal": "corpus",
          "chunkId": "api/cli#sharded-builds-for-large-sites"
        },
        {
          "kind": "code",
          "literal": "ask digest verify",
          "chunkId": "api/cli#sharded-builds-for-large-sites"
        },
        {
          "kind": "code",
          "literal": "--skip-build",
          "chunkId": "api/cli#sharded-builds-for-large-sites"
        },
        {
          "kind": "code",
          "literal": "_meta.md",
          "chunkId": "api/cli#sharded-builds-for-large-sites"
        },
        {
          "kind": "code",
          "literal": "--strict",
          "chunkId": "api/cli#sharded-builds-for-large-sites"
        }
      ],
      "sources": [
        {
          "chunkId": "api/cli#sharded-builds-for-large-sites",
          "url": "/docs/api/cli#sharded-builds-for-large-sites",
          "anchor": "sharded-builds-for-large-sites"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "sharded",
        "builds",
        "large",
        "sites",
        "flow",
        "removes",
        "single",
        "context",
        "bound",
        "splitting",
        "corpus",
        "along",
        "slug",
        "prefix",
        "boundaries",
        "distilling",
        "shard",
        "independently",
        "merging",
        "assembly",
        "sharding",
        "stable",
        "incremental",
        "editing",
        "pends",
        "only",
        "owns",
        "stale",
        "distillations",
        "detected",
        "skipped",
        "warning",
        "while",
        "affected",
        "sections",
        "fall",
        "back",
        "plain",
        "excerpts",
        "tree"
      ]
    },
    {
      "id": "api/cli#where-it-runs",
      "kind": "section",
      "title": "CLI",
      "heading": "Where it runs",
      "group": "API",
      "url": "/docs/api/cli#where-it-runs",
      "summary": "Producer commands run locally or in CI with filesystem access, and the Astro integration also runs the build during the site build when a key is present, falling back to the committed tree otherwise. The deployed site reads the committed tree through a virtual module and needs no filesystem access; running verify on every build is the mechanical check that generated slugs still match what the renderer produces.",
      "hash": "3160b534adda5d403ca544d7fa24738f6edc01c050b30b719a2cc04be4a6eede",
      "facts": [
        {
          "kind": "code",
          "literal": "ask digest build",
          "chunkId": "api/cli#where-it-runs"
        },
        {
          "kind": "code",
          "literal": "astro build",
          "chunkId": "api/cli#where-it-runs"
        },
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "api/cli#where-it-runs"
        },
        {
          "kind": "code",
          "literal": "virtual:hev-ask/digest",
          "chunkId": "api/cli#where-it-runs"
        },
        {
          "kind": "code",
          "literal": "ask digest verify",
          "chunkId": "api/cli#where-it-runs"
        }
      ],
      "sources": [
        {
          "chunkId": "api/cli#where-it-runs",
          "url": "/docs/api/cli#where-it-runs",
          "anchor": "where-it-runs"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "runs",
        "producer",
        "commands",
        "locally",
        "filesystem",
        "access",
        "astro",
        "integration",
        "also",
        "build",
        "during",
        "site",
        "present",
        "falling",
        "back",
        "committed",
        "tree",
        "otherwise",
        "deployed",
        "reads",
        "through",
        "virtual",
        "module",
        "needs",
        "running",
        "verify",
        "every",
        "mechanical",
        "check",
        "generated",
        "slugs",
        "still",
        "match",
        "renderer",
        "produces",
        "digest",
        "anthropic",
        "invokes",
        "anthropicapikey",
        "falls"
      ]
    },
    {
      "id": "api/configuration",
      "kind": "section",
      "title": "Configuration",
      "heading": null,
      "group": "API",
      "url": "/docs/api/configuration",
      "summary": "The hevAsk() Astro integration is the package's default export and takes a single options object. Only the content collections list is effectively required; every other option has a default.",
      "hash": "e7c504dd58a7e10c8e9f034b0d0ce1286da961ec8f56fbe2ad5ad932f90fcbf6",
      "facts": [
        {
          "kind": "code",
          "literal": "// astro.config.mjs\nimport hevAsk from \"@hevmind/ask\";\n\nexport default defineConfig({\n  integrations: [\n    hevAsk({\n      collections: [\"docs\"],\n      basePath: \"/docs/\",\n      model: \"claude-haiku-4-5\",\n      maxResults: 6,\n    }),\n  ],\n});",
          "chunkId": "api/configuration"
        },
        {
          "kind": "code",
          "literal": "hevAsk()",
          "chunkId": "api/configuration"
        },
        {
          "kind": "code",
          "literal": "@hevmind/ask",
          "chunkId": "api/configuration"
        },
        {
          "kind": "code",
          "literal": "collections",
          "chunkId": "api/configuration"
        },
        {
          "kind": "value",
          "literal": "Callout.astro",
          "chunkId": "api/configuration"
        },
        {
          "kind": "value",
          "literal": "CodeTabs.astro",
          "chunkId": "api/configuration"
        }
      ],
      "sources": [
        {
          "chunkId": "api/configuration",
          "url": "/docs/api/configuration",
          "anchor": null
        }
      ],
      "mode": "source-primary",
      "terms": [
        "hevask",
        "astro",
        "integration",
        "package",
        "default",
        "export",
        "takes",
        "single",
        "options",
        "object",
        "only",
        "content",
        "collections",
        "list",
        "effectively",
        "required",
        "every",
        "other",
        "option",
        "config",
        "import",
        "hevmind",
        "defineconfig",
        "integrations",
        "docs",
        "basepath",
        "model",
        "claude",
        "haiku",
        "maxresults",
        "callout",
        "codetabs",
        "models",
        "endpoint",
        "chunking",
        "depth",
        "retrieval",
        "caps",
        "digest",
        "paths"
      ]
    },
    {
      "id": "api/configuration#choosing-a-provider",
      "kind": "section",
      "title": "Configuration",
      "heading": "Choosing a provider",
      "group": "API",
      "url": "/docs/api/configuration#choosing-a-provider",
      "summary": "The provider option selects who serves both the runtime answer loop and the offline digest build, with identical search behavior, digest format, and endpoint contract across providers; only the model and key environment variable change. OpenRouter reaches every model it routes through one key, and a base-URL override points the OpenAI-compatible client at any Chat Completions endpoint. Loop models must support tool calling and the digest builder needs forced tool choice, which current major-provider models satisfy; a changed endpoint route must be mirrored on the overlay component.",
      "hash": "64020ee9bbb713bf179bf7c6d3f2673b780e483e4c6b7f584c829f690db6acd3",
      "facts": [
        {
          "kind": "code",
          "literal": "// astro.config.mjs — the default; reads ANTHROPIC_API_KEY\nhevAsk({\n  collections: [\"docs\"],\n  // model defaults to claude-haiku-4-5\n});",
          "chunkId": "api/configuration#choosing-a-provider"
        },
        {
          "kind": "code",
          "literal": "// astro.config.mjs — reads OPENAI_API_KEY\nhevAsk({\n  collections: [\"docs\"],\n  provider: \"openai\",\n  // model defaults to gpt-4.1-mini\n});",
          "chunkId": "api/configuration#choosing-a-provider"
        },
        {
          "kind": "code",
          "literal": "// astro.config.mjs — reads OPENROUTER_API_KEY\nhevAsk({\n  collections: [\"docs\"],\n  provider: \"openrouter\",\n  model: \"anthropic/claude-haiku-4.5\", // or any OpenRouter model slug\n});",
          "chunkId": "api/configuration#choosing-a-provider"
        },
        {
          "kind": "code",
          "literal": "hevAsk({\n  collections: [\"docs\"],\n  provider: \"openai\",\n  providerBaseUrl: \"https://my-gateway.example.com/v1\",\n  model: \"my-model\",\n});",
          "chunkId": "api/configuration#choosing-a-provider"
        },
        {
          "kind": "code",
          "literal": "provider",
          "chunkId": "api/configuration#choosing-a-provider"
        },
        {
          "kind": "code",
          "literal": "OPENROUTER_API_KEY",
          "chunkId": "api/configuration#choosing-a-provider"
        },
        {
          "kind": "code",
          "literal": "providerBaseUrl",
          "chunkId": "api/configuration#choosing-a-provider"
        },
        {
          "kind": "code",
          "literal": "provider: \"openai\"",
          "chunkId": "api/configuration#choosing-a-provider"
        },
        {
          "kind": "code",
          "literal": "endpoint",
          "chunkId": "api/configuration#choosing-a-provider"
        },
        {
          "kind": "code",
          "literal": "/api/ask",
          "chunkId": "api/configuration#choosing-a-provider"
        },
        {
          "kind": "code",
          "literal": "SearchOverlay",
          "chunkId": "api/configuration#choosing-a-provider"
        }
      ],
      "sources": [
        {
          "chunkId": "api/configuration#choosing-a-provider",
          "url": "/docs/api/configuration#choosing-a-provider",
          "anchor": "choosing-a-provider"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "choosing",
        "provider",
        "option",
        "selects",
        "serves",
        "both",
        "runtime",
        "answer",
        "loop",
        "offline",
        "digest",
        "build",
        "identical",
        "search",
        "behavior",
        "format",
        "endpoint",
        "contract",
        "across",
        "providers",
        "only",
        "model",
        "environment",
        "variable",
        "change",
        "openrouter",
        "reaches",
        "every",
        "routes",
        "through",
        "base",
        "override",
        "points",
        "openai",
        "compatible",
        "client",
        "chat",
        "completions",
        "models",
        "must"
      ]
    },
    {
      "id": "api/configuration#options",
      "kind": "section",
      "title": "Configuration",
      "heading": "Options",
      "group": "API",
      "url": "/docs/api/configuration#options",
      "summary": "A reference table of every hevAsk() option with its type, default, and description, spanning collections, base path, endpoint route, provider and base-URL override, the loop and digest models, source and result caps, the answer token budget, search iteration limit, chunk heading depth, per-search and per-document candidate caps, and the digest directory and content globs.",
      "hash": "3d7084435ad219aa81a8c7a65fc84859b1ef0613d128fa21ec4a2178b4fa7eb9",
      "facts": [
        {
          "kind": "code",
          "literal": "collections",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "string[]",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "basePath",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "string",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "'/docs/'",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "basePath + slug",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "#anchor",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "endpoint",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "'/api/ask'",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "provider",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "'anthropic'",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "'openai'",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "'openrouter'",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "OPENAI_API_KEY",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "OPENROUTER_API_KEY",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "providerBaseUrl",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "model",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "claude-haiku-4-5",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "gpt-4.1-mini",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "anthropic/claude-haiku-4.5",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "digestModel",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "claude-opus-4-8",
          "chunkId": "api/configuration#options"
        },
        {
          "kind": "code",
          "literal": "gpt-5.1",
          "chunkId": "api/configuration#options"
        }
      ],
      "sources": [
        {
          "chunkId": "api/configuration#options",
          "url": "/docs/api/configuration#options",
          "anchor": "options"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "options",
        "reference",
        "table",
        "every",
        "hevask",
        "option",
        "type",
        "default",
        "description",
        "spanning",
        "collections",
        "base",
        "path",
        "endpoint",
        "route",
        "provider",
        "override",
        "loop",
        "digest",
        "models",
        "source",
        "result",
        "caps",
        "answer",
        "token",
        "budget",
        "search",
        "iteration",
        "limit",
        "chunk",
        "heading",
        "depth",
        "document",
        "candidate",
        "directory",
        "content",
        "globs",
        "string",
        "basepath",
        "docs"
      ]
    },
    {
      "id": "api/configuration#tuning-notes",
      "kind": "section",
      "title": "Configuration",
      "heading": "Tuning notes",
      "group": "API",
      "url": "/docs/api/configuration#tuning-notes",
      "summary": "Guidance on tuning the knobs: chunk heading depth trades finer section anchors against sections too small to stand alone, the iteration cap trades latency against multi-part recall, the per-document cap controls result spread, and the candidates-per-search count trades recall against token cost.",
      "hash": "357904627c549ccc59120393a2316912522af1027d5a3d35be21390520aadac2",
      "facts": [
        {
          "kind": "code",
          "literal": "chunkHeadingDepth",
          "chunkId": "api/configuration#tuning-notes"
        },
        {
          "kind": "code",
          "literal": "###",
          "chunkId": "api/configuration#tuning-notes"
        },
        {
          "kind": "code",
          "literal": "maxIterations",
          "chunkId": "api/configuration#tuning-notes"
        },
        {
          "kind": "code",
          "literal": "perDocCap",
          "chunkId": "api/configuration#tuning-notes"
        },
        {
          "kind": "code",
          "literal": "candidatePerSearch",
          "chunkId": "api/configuration#tuning-notes"
        }
      ],
      "sources": [
        {
          "chunkId": "api/configuration#tuning-notes",
          "url": "/docs/api/configuration#tuning-notes",
          "anchor": "tuning-notes"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "tuning",
        "notes",
        "guidance",
        "knobs",
        "chunk",
        "heading",
        "depth",
        "trades",
        "finer",
        "section",
        "anchors",
        "against",
        "sections",
        "small",
        "stand",
        "alone",
        "iteration",
        "latency",
        "multi",
        "part",
        "recall",
        "document",
        "controls",
        "result",
        "spread",
        "candidates",
        "search",
        "count",
        "token",
        "cost",
        "chunkheadingdepth",
        "maxiterations",
        "perdoccap",
        "candidatepersearch",
        "granularity",
        "raise",
        "default",
        "long",
        "pages",
        "drop"
      ]
    },
    {
      "id": "api/configuration#typescript",
      "kind": "section",
      "title": "Configuration",
      "heading": "TypeScript",
      "group": "API",
      "url": "/docs/api/configuration#typescript",
      "summary": "The options type is exported so editors can offer help and config files can be typed.",
      "hash": "9bf5a2870c8b34a8276f2eea78e055b318b7af5e01ed708d3c91be079700f844",
      "facts": [
        {
          "kind": "code",
          "literal": "import type { HevAskOptions } from \"@hevmind/ask\";",
          "chunkId": "api/configuration#typescript"
        }
      ],
      "sources": [
        {
          "chunkId": "api/configuration#typescript",
          "url": "/docs/api/configuration#typescript",
          "anchor": "typescript"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "typescript",
        "options",
        "type",
        "exported",
        "editors",
        "offer",
        "help",
        "config",
        "files",
        "typed",
        "import",
        "hevaskoptions",
        "hevmind",
        "editor",
        "typing"
      ]
    },
    {
      "id": "api/configuration#what-the-integration-does",
      "kind": "section",
      "title": "Configuration",
      "heading": "What the integration does",
      "group": "API",
      "url": "/docs/api/configuration#what-the-integration-does",
      "summary": "At config setup the integration injects the on-demand endpoint route, registers virtual modules for the resolved config and the committed tree, watches the digest directory for dev reloads, and warns on empty collections. At build start it runs the hash-gated digest build when the provider key is present and otherwise warns and proceeds with the committed artifact; the build never fails for lack of a key.",
      "hash": "0b9a79f3448bfbbfaff7b1b2d3b80844d670db91fb5228cd58d14f8a8f57220a",
      "facts": [
        {
          "kind": "code",
          "literal": "astro:config:setup",
          "chunkId": "api/configuration#what-the-integration-does"
        },
        {
          "kind": "code",
          "literal": "endpoint",
          "chunkId": "api/configuration#what-the-integration-does"
        },
        {
          "kind": "code",
          "literal": "@hevmind/ask/endpoint",
          "chunkId": "api/configuration#what-the-integration-does"
        },
        {
          "kind": "code",
          "literal": "prerender: false",
          "chunkId": "api/configuration#what-the-integration-does"
        },
        {
          "kind": "code",
          "literal": "virtual:hev-ask/config",
          "chunkId": "api/configuration#what-the-integration-does"
        },
        {
          "kind": "code",
          "literal": "virtual:hev-ask/digest",
          "chunkId": "api/configuration#what-the-integration-does"
        },
        {
          "kind": "code",
          "literal": "digestDir",
          "chunkId": "api/configuration#what-the-integration-does"
        },
        {
          "kind": "code",
          "literal": "collections",
          "chunkId": "api/configuration#what-the-integration-does"
        },
        {
          "kind": "code",
          "literal": "astro:build:start",
          "chunkId": "api/configuration#what-the-integration-does"
        },
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "api/configuration#what-the-integration-does"
        }
      ],
      "sources": [
        {
          "chunkId": "api/configuration#what-the-integration-does",
          "url": "/docs/api/configuration#what-the-integration-does",
          "anchor": "what-the-integration-does"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "integration",
        "does",
        "config",
        "setup",
        "injects",
        "demand",
        "endpoint",
        "route",
        "registers",
        "virtual",
        "modules",
        "resolved",
        "committed",
        "tree",
        "watches",
        "digest",
        "directory",
        "reloads",
        "warns",
        "empty",
        "collections",
        "build",
        "start",
        "runs",
        "hash",
        "gated",
        "provider",
        "present",
        "otherwise",
        "proceeds",
        "artifact",
        "never",
        "fails",
        "lack",
        "astro",
        "hevmind",
        "prerender",
        "false",
        "digestdir",
        "anthropic"
      ]
    },
    {
      "id": "api/digest",
      "kind": "section",
      "title": "Digest format",
      "heading": null,
      "group": "API",
      "url": "/docs/api/digest",
      "summary": "The ask digest is a committed directory built offline and globbed into the build through a virtual module, so the running site reads it without filesystem access. It is the agent's distilled, source-grounded mirror of the docs, read progressively, with every section carrying a deep link back to its real source page; humans read rendered pages while agents read the tree.",
      "hash": "b6293e0ab65f8b5986d57524cc424f78c9c857f9f546fc9998fbb7c7ac72221b",
      "facts": [
        {
          "kind": "code",
          "literal": ".hev-ask/",
          "chunkId": "api/digest"
        },
        {
          "kind": "code",
          "literal": "ask digest build",
          "chunkId": "api/digest"
        },
        {
          "kind": "code",
          "literal": "digest.json",
          "chunkId": "api/digest"
        },
        {
          "kind": "code",
          "literal": "kg",
          "chunkId": "api/digest"
        },
        {
          "kind": "code",
          "literal": "virtual:hev-ask/digest",
          "chunkId": "api/digest"
        },
        {
          "kind": "code",
          "literal": "url",
          "chunkId": "api/digest"
        },
        {
          "kind": "code",
          "literal": "anchor",
          "chunkId": "api/digest"
        },
        {
          "kind": "value",
          "literal": "Callout.astro",
          "chunkId": "api/digest"
        },
        {
          "kind": "value",
          "literal": "0.1",
          "chunkId": "api/digest"
        }
      ],
      "sources": [
        {
          "chunkId": "api/digest",
          "url": "/docs/api/digest",
          "anchor": null
        }
      ],
      "mode": "source-primary",
      "terms": [
        "digest",
        "committed",
        "directory",
        "built",
        "offline",
        "globbed",
        "build",
        "through",
        "virtual",
        "module",
        "running",
        "site",
        "reads",
        "without",
        "filesystem",
        "access",
        "agent",
        "distilled",
        "source",
        "grounded",
        "mirror",
        "docs",
        "read",
        "progressively",
        "every",
        "section",
        "carrying",
        "deep",
        "link",
        "back",
        "real",
        "page",
        "humans",
        "rendered",
        "pages",
        "while",
        "agents",
        "tree",
        "json",
        "anchor"
      ]
    },
    {
      "id": "api/digest#_metamd-and-_glossary",
      "kind": "section",
      "title": "Digest format",
      "heading": "_meta.md and _glossary/",
      "group": "API",
      "url": "/docs/api/digest#_metamd-and-_glossary",
      "summary": "The meta entry carries digest-level fields used as the freshness gate and ordering, plus orientation context, the deterministic overview map, and the suggestions the overlay shows on open. The glossary is one file per term holding its aliases and definition, and it widens keyword search by expanding each query term to its aliases before retrieval.",
      "hash": "942dcfb8559c766f29833404f3162b513322dc3ebc5e47d56806d1b513206465",
      "facts": [
        {
          "kind": "code",
          "literal": "_meta.md",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "_glossary/",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "version",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "generatedAt",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "contentHash",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "context",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "overview",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "suggestions",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "_glossary/<term>.md",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "term",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "aliases",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "definition",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "k8s",
          "chunkId": "api/digest#_metamd-and-_glossary"
        },
        {
          "kind": "code",
          "literal": "kubernetes",
          "chunkId": "api/digest#_metamd-and-_glossary"
        }
      ],
      "sources": [
        {
          "chunkId": "api/digest#_metamd-and-_glossary",
          "url": "/docs/api/digest#_metamd-and-_glossary",
          "anchor": "_metamd-and-_glossary"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "meta",
        "glossary",
        "entry",
        "carries",
        "digest",
        "level",
        "fields",
        "freshness",
        "gate",
        "ordering",
        "plus",
        "orientation",
        "context",
        "deterministic",
        "overview",
        "suggestions",
        "overlay",
        "shows",
        "open",
        "file",
        "term",
        "holding",
        "aliases",
        "definition",
        "widens",
        "keyword",
        "search",
        "expanding",
        "query",
        "before",
        "retrieval",
        "version",
        "generatedat",
        "contenthash",
        "kubernetes",
        "frontmatter",
        "group",
        "section",
        "body",
        "picks"
      ]
    },
    {
      "id": "api/digest#a-section-file",
      "kind": "section",
      "title": "Digest format",
      "heading": "A section file",
      "group": "API",
      "url": "/docs/api/digest#a-section-file",
      "summary": "A single section file is shown with its frontmatter and body: the first paragraph is the summary, the body below the frontmatter is the full read payload, and the frontmatter arrays are the grounded facts. One file thus serves the three rungs of progressive disclosure.",
      "hash": "09b10b67fd7759b696a8d7228b5a49dcac296da426f707c2a64076a2cad56437",
      "facts": [
        {
          "kind": "code",
          "literal": "head",
          "chunkId": "api/digest#a-section-file"
        },
        {
          "kind": "code",
          "literal": "cat",
          "chunkId": "api/digest#a-section-file"
        },
        {
          "kind": "code",
          "literal": "facts",
          "chunkId": "api/digest#a-section-file"
        }
      ],
      "sources": [
        {
          "chunkId": "api/digest#a-section-file",
          "url": "/docs/api/digest#a-section-file",
          "anchor": "a-section-file"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "section",
        "file",
        "single",
        "shown",
        "frontmatter",
        "body",
        "first",
        "paragraph",
        "summary",
        "below",
        "full",
        "read",
        "payload",
        "arrays",
        "grounded",
        "facts",
        "thus",
        "serves",
        "three",
        "rungs",
        "progressive",
        "disclosure",
        "head",
        "title",
        "quick",
        "start",
        "astro",
        "site",
        "five",
        "minutes",
        "heading",
        "group",
        "overview",
        "order",
        "docs",
        "quickstart",
        "anchor",
        "terms",
        "digest",
        "integration"
      ]
    },
    {
      "id": "api/digest#degradation",
      "kind": "section",
      "title": "Digest format",
      "heading": "Degradation",
      "group": "API",
      "url": "/docs/api/digest#degradation",
      "summary": "The tree is read defensively: a missing or malformed digest degrades to keyword-style fallback search, raw token-overlap ranking, and no suggested questions, and nothing hard-fails. Being a committed markdown tree, each section's distilled prose and grounded facts change together in one reviewable diff, which is why it is a directory rather than a runtime computation and why the model step can move into a skill.",
      "hash": "8c7b92cf65264a8dd443821aed31b529e5da7fb17f7ee72414d61378fb7757e2",
      "facts": [
        {
          "kind": "code",
          "literal": ".hev-ask/",
          "chunkId": "api/digest#degradation"
        }
      ],
      "sources": [
        {
          "chunkId": "api/digest#degradation",
          "url": "/docs/api/digest#degradation",
          "anchor": "degradation"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "degradation",
        "tree",
        "read",
        "defensively",
        "missing",
        "malformed",
        "digest",
        "degrades",
        "keyword",
        "style",
        "fallback",
        "search",
        "token",
        "overlap",
        "ranking",
        "suggested",
        "questions",
        "nothing",
        "hard",
        "fails",
        "being",
        "committed",
        "markdown",
        "section",
        "distilled",
        "prose",
        "grounded",
        "facts",
        "change",
        "together",
        "reviewable",
        "diff",
        "directory",
        "rather",
        "runtime",
        "computation",
        "model",
        "step",
        "move",
        "skill"
      ]
    },
    {
      "id": "api/digest#frontmatter-fields",
      "kind": "section",
      "title": "Digest format",
      "heading": "Frontmatter fields",
      "group": "API",
      "url": "/docs/api/digest#frontmatter-fields",
      "summary": "A reference table of every section frontmatter field with its type and role, covering the listing title and literal heading text, group and order, the citation URL and anchor, ranking terms, the incremental-build hash, the agent-primary versus source-primary mode, the deterministically extracted verbatim facts, and the source provenance references.",
      "hash": "ac0ff9a835edcc72c30d1502c26241ac65e2dd9e634502949e1cc09fda26e06b",
      "facts": [
        {
          "kind": "code",
          "literal": "title",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "string",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "tree",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "ls",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "heading",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "group",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "order",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "number",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "url",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "anchor",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "github-slugger",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "verify",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "id",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "terms",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "string[]",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "hash",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "mode",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "'agent-primary' \\| 'source-primary'",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "source-primary",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "facts",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "Fact[]",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "sources",
          "chunkId": "api/digest#frontmatter-fields"
        },
        {
          "kind": "code",
          "literal": "SourceRef[]",
          "chunkId": "api/digest#frontmatter-fields"
        }
      ],
      "sources": [
        {
          "chunkId": "api/digest#frontmatter-fields",
          "url": "/docs/api/digest#frontmatter-fields",
          "anchor": "frontmatter-fields"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "frontmatter",
        "fields",
        "reference",
        "table",
        "every",
        "section",
        "field",
        "type",
        "role",
        "covering",
        "listing",
        "title",
        "literal",
        "heading",
        "text",
        "group",
        "order",
        "citation",
        "anchor",
        "ranking",
        "terms",
        "incremental",
        "build",
        "hash",
        "agent",
        "primary",
        "versus",
        "source",
        "mode",
        "deterministically",
        "extracted",
        "verbatim",
        "facts",
        "provenance",
        "references",
        "string",
        "tree",
        "number",
        "github",
        "slugger"
      ]
    },
    {
      "id": "api/digest#how-each-field-is-used",
      "kind": "section",
      "title": "Digest format",
      "heading": "How each field is used",
      "group": "API",
      "url": "/docs/api/digest#how-each-field-is-used",
      "summary": "The title-tree and summaries are injected into the loop's prompt-cached system prompt; the model opens needed sections and answers from their summaries, quoting facts for exact strings. The glossary drives query expansion, and terms, summary, and facts all rank keyword results so central sections outrank incidental mentions; the anchor is what verify checks and what citations link to, and the hash is the incremental gate.",
      "hash": "17f47e86d1eba6bfe1ba189937eeefcf9e88ee2b8e80ce1cf3edca8b9c7949e1",
      "facts": [
        {
          "kind": "code",
          "literal": "facts",
          "chunkId": "api/digest#how-each-field-is-used"
        },
        {
          "kind": "code",
          "literal": "_glossary/",
          "chunkId": "api/digest#how-each-field-is-used"
        },
        {
          "kind": "code",
          "literal": "terms",
          "chunkId": "api/digest#how-each-field-is-used"
        },
        {
          "kind": "code",
          "literal": "summary",
          "chunkId": "api/digest#how-each-field-is-used"
        },
        {
          "kind": "code",
          "literal": "anchor",
          "chunkId": "api/digest#how-each-field-is-used"
        },
        {
          "kind": "code",
          "literal": "ask digest verify",
          "chunkId": "api/digest#how-each-field-is-used"
        },
        {
          "kind": "code",
          "literal": "hash",
          "chunkId": "api/digest#how-each-field-is-used"
        },
        {
          "kind": "code",
          "literal": "build",
          "chunkId": "api/digest#how-each-field-is-used"
        }
      ],
      "sources": [
        {
          "chunkId": "api/digest#how-each-field-is-used",
          "url": "/docs/api/digest#how-each-field-is-used",
          "anchor": "how-each-field-is-used"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "field",
        "title",
        "tree",
        "summaries",
        "injected",
        "loop",
        "prompt",
        "cached",
        "system",
        "model",
        "opens",
        "needed",
        "sections",
        "answers",
        "their",
        "quoting",
        "facts",
        "exact",
        "strings",
        "glossary",
        "drives",
        "query",
        "expansion",
        "terms",
        "summary",
        "rank",
        "keyword",
        "results",
        "central",
        "outrank",
        "incidental",
        "mentions",
        "anchor",
        "verify",
        "checks",
        "citations",
        "link",
        "hash",
        "incremental",
        "gate"
      ]
    },
    {
      "id": "api/digest#layout",
      "kind": "section",
      "title": "Digest format",
      "heading": "Layout",
      "group": "API",
      "url": "/docs/api/digest#layout",
      "summary": "Describes the on-disk layout: a meta file, a glossary directory of per-term files, and per-section markdown files under directories that mirror the doc paths. Underscore-prefixed non-section entries sort first and never collide with a real slug, and there is no committed JSON; the whole artifact is markdown.",
      "hash": "6ebf2bffe75c0ce6e0e4ebce97214673a69cdc69161cbfe9d7e1a584adb512bc",
      "facts": [
        {
          "kind": "code",
          "literal": ".hev-ask/\n  _meta.md                     overview · context · suggestions · version · contentHash\n  _glossary/\n    digest.md                  one file per term: aliases + definition\n  overview/\n    quick-start.md             one file per section, mirroring your doc paths\n    limits.md\n  api/\n    cli.md",
          "chunkId": "api/digest#layout"
        },
        {
          "kind": "code",
          "literal": "_meta",
          "chunkId": "api/digest#layout"
        },
        {
          "kind": "code",
          "literal": "_glossary",
          "chunkId": "api/digest#layout"
        }
      ],
      "sources": [
        {
          "chunkId": "api/digest#layout",
          "url": "/docs/api/digest#layout",
          "anchor": "layout"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "layout",
        "describes",
        "disk",
        "meta",
        "file",
        "glossary",
        "directory",
        "term",
        "files",
        "section",
        "markdown",
        "under",
        "directories",
        "mirror",
        "paths",
        "underscore",
        "prefixed",
        "entries",
        "sort",
        "first",
        "never",
        "collide",
        "real",
        "slug",
        "there",
        "committed",
        "json",
        "whole",
        "artifact",
        "overview",
        "context",
        "suggestions",
        "version",
        "contenthash",
        "digest",
        "aliases",
        "definition",
        "quick",
        "start",
        "mirroring"
      ]
    },
    {
      "id": "api/digest#regenerating",
      "kind": "section",
      "title": "Digest format",
      "heading": "Regenerating",
      "group": "API",
      "url": "/docs/api/digest#regenerating",
      "summary": "Rebuild after content changes and commit the result; the build is incremental, spending model work only on sections whose hash changed. You can build with the keyless skill, the one-call CLI build, or the integration during the site build when a key is present; large sites use the sharded flow, verify gates anchors and coverage, and a legacy single-file digest can be exploded into the tree with no model call.",
      "hash": "18c55bbc27ee8afb9bdda4d22407ee10967f514cfa90fb49fb6506dc60a2a138",
      "facts": [
        {
          "kind": "code",
          "literal": "hash",
          "chunkId": "api/digest#regenerating"
        },
        {
          "kind": "code",
          "literal": "ask digest build",
          "chunkId": "api/digest#regenerating"
        },
        {
          "kind": "code",
          "literal": "astro build",
          "chunkId": "api/digest#regenerating"
        },
        {
          "kind": "code",
          "literal": "ask digest verify",
          "chunkId": "api/digest#regenerating"
        },
        {
          "kind": "code",
          "literal": "digest.json",
          "chunkId": "api/digest#regenerating"
        },
        {
          "kind": "code",
          "literal": "ask digest migrate",
          "chunkId": "api/digest#regenerating"
        }
      ],
      "sources": [
        {
          "chunkId": "api/digest#regenerating",
          "url": "/docs/api/digest#regenerating",
          "anchor": "regenerating"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "regenerating",
        "rebuild",
        "after",
        "content",
        "changes",
        "commit",
        "result",
        "build",
        "incremental",
        "spending",
        "model",
        "work",
        "only",
        "sections",
        "whose",
        "hash",
        "changed",
        "keyless",
        "skill",
        "call",
        "integration",
        "during",
        "site",
        "present",
        "large",
        "sites",
        "sharded",
        "flow",
        "verify",
        "gates",
        "anchors",
        "coverage",
        "legacy",
        "single",
        "file",
        "digest",
        "exploded",
        "tree",
        "astro",
        "json"
      ]
    },
    {
      "id": "api/endpoint",
      "kind": "section",
      "title": "Search endpoint",
      "heading": null,
      "group": "API",
      "url": "/docs/api/endpoint",
      "summary": "The integration injects one on-demand route serving the overlay: keyword mode returns JSON and agentic mode streams a grounded answer as Server-Sent Events. Keyless sub-routes expose the committed digest for CLIs, MCP servers, and generated clients, and the full machine-readable contract is published as OpenAPI.",
      "hash": "6326b7a8d7fb952de486ebf8d8df5438e6d86ae7aafd2ce10fc15ea6549a8046",
      "facts": [
        {
          "kind": "code",
          "literal": "/api/ask",
          "chunkId": "api/endpoint"
        },
        {
          "kind": "code",
          "literal": "text/event-stream",
          "chunkId": "api/endpoint"
        },
        {
          "kind": "code",
          "literal": "/openapi.yaml",
          "chunkId": "api/endpoint"
        },
        {
          "kind": "value",
          "literal": "Callout.astro",
          "chunkId": "api/endpoint"
        },
        {
          "kind": "value",
          "literal": "3.1",
          "chunkId": "api/endpoint"
        },
        {
          "kind": "value",
          "literal": "openapi.yaml",
          "chunkId": "api/endpoint"
        }
      ],
      "sources": [
        {
          "chunkId": "api/endpoint",
          "url": "/docs/api/endpoint",
          "anchor": null
        }
      ],
      "mode": "source-primary",
      "terms": [
        "integration",
        "injects",
        "demand",
        "route",
        "serving",
        "overlay",
        "keyword",
        "mode",
        "returns",
        "json",
        "agentic",
        "streams",
        "grounded",
        "answer",
        "server",
        "sent",
        "events",
        "keyless",
        "routes",
        "expose",
        "committed",
        "digest",
        "clis",
        "servers",
        "generated",
        "clients",
        "full",
        "machine",
        "readable",
        "contract",
        "published",
        "openapi",
        "text",
        "event",
        "stream",
        "yaml",
        "callout",
        "astro",
        "suggestions",
        "reads"
      ]
    },
    {
      "id": "api/endpoint#agentic-response-sse",
      "kind": "section",
      "title": "Search endpoint",
      "heading": "Agentic response (SSE)",
      "group": "API",
      "url": "/docs/api/endpoint#agentic-response-sse",
      "summary": "When a key is present and agentic mode is requested, the endpoint streams the answer as named SSE frames whose example payloads and meaning are documented in a table: search context the model gathered, the one-time grounding source set, streamed answer-text deltas, completion, and a post-stream error. A source carries title, optional heading, URL, and group but no snippet, since the prose carries the substance and links point at the URL.",
      "hash": "366017faa11220e7fdd7545cd885b58cdf2133c5f21be853f4339fe775ebc51a",
      "facts": [
        {
          "kind": "code",
          "literal": "mode",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "agentic",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "content-type: text/event-stream",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "search",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "{ query }",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "sources",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "{ sources: Source[], model, mode }",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "token",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "{ text }",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "done",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "{}",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "error",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "{ error }",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "200",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "Source",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "{ title, heading?, url, group? }",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "snippet",
          "chunkId": "api/endpoint#agentic-response-sse"
        },
        {
          "kind": "code",
          "literal": "url",
          "chunkId": "api/endpoint#agentic-response-sse"
        }
      ],
      "sources": [
        {
          "chunkId": "api/endpoint#agentic-response-sse",
          "url": "/docs/api/endpoint#agentic-response-sse",
          "anchor": "agentic-response-sse"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "agentic",
        "response",
        "present",
        "mode",
        "requested",
        "endpoint",
        "streams",
        "answer",
        "named",
        "frames",
        "whose",
        "example",
        "payloads",
        "meaning",
        "documented",
        "table",
        "search",
        "context",
        "model",
        "gathered",
        "time",
        "grounding",
        "source",
        "streamed",
        "text",
        "deltas",
        "completion",
        "post",
        "stream",
        "error",
        "carries",
        "title",
        "optional",
        "heading",
        "group",
        "snippet",
        "since",
        "prose",
        "substance",
        "links"
      ]
    },
    {
      "id": "api/endpoint#digest-reads-get",
      "kind": "section",
      "title": "Search endpoint",
      "heading": "Digest reads (GET)",
      "group": "API",
      "url": "/docs/api/endpoint#digest-reads-get",
      "summary": "A table of keyless GET routes that read the committed digest, never call a model, and never need a key, covering the glossary and a single term, section summaries optionally filtered by group, a single full section, the overview, and a compressed archive of the whole tree. Section IDs with slashes or hashes are URL-encoded in the path, the archive is the bulk transport used by the MCP command, a HEAD request returns cache headers including the content hash so clients can skip a download, and unknown reads return a JSON not-found error.",
      "hash": "e462a9453db8dbf2c1ce2211b0989c34a851fefa9e2dc075bb461f12817eff77",
      "facts": [
        {
          "kind": "code",
          "literal": "{ \"error\": \"Not found.\" }",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "virtual:hev-ask/digest",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "GET /api/ask/glossary",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "{ \"terms\": GlossaryEntry[] }",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "GET /api/ask/glossary/{term}",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "GlossaryEntry",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "GET /api/ask/sections",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "{ \"sections\": SectionSummary[] }",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "GET /api/ask/sections?group=API",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "GET /api/ask/sections/{id}",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "DigestNode",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "GET /api/ask/overview",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "{ \"overview\": string, \"context\": string }",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "GET /api/ask/archive",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": ".hev-ask/",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "SectionSummary",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "{ id, title, heading, group, url }",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "/api/ask/sections/api%2Fcli%23flags",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "ask mcp --endpoint",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "HEAD /api/ask/archive",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "x-hev-ask-content-hash",
          "chunkId": "api/endpoint#digest-reads-get"
        },
        {
          "kind": "code",
          "literal": "404",
          "chunkId": "api/endpoint#digest-reads-get"
        }
      ],
      "sources": [
        {
          "chunkId": "api/endpoint#digest-reads-get",
          "url": "/docs/api/endpoint#digest-reads-get",
          "anchor": "digest-reads-get"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "digest",
        "reads",
        "table",
        "keyless",
        "routes",
        "read",
        "committed",
        "never",
        "call",
        "model",
        "need",
        "covering",
        "glossary",
        "single",
        "term",
        "section",
        "summaries",
        "optionally",
        "filtered",
        "group",
        "full",
        "overview",
        "compressed",
        "archive",
        "whole",
        "tree",
        "slashes",
        "hashes",
        "encoded",
        "path",
        "bulk",
        "transport",
        "command",
        "head",
        "request",
        "returns",
        "cache",
        "headers",
        "including",
        "content"
      ]
    },
    {
      "id": "api/endpoint#errors",
      "kind": "section",
      "title": "Search endpoint",
      "heading": "Errors",
      "group": "API",
      "url": "/docs/api/endpoint#errors",
      "summary": "A table of error responses: a bad request for invalid JSON, not-found for an unknown read route or missing term or section, and a server error when the chunk index fails to build. A failure during the agentic stream arrives as a final SSE error event because the HTTP status is already successful.",
      "hash": "c67a8ab9b70204c62cb0ae5f63d37f2d21863e6f4fdc6e684b85e3a81e37ff3d",
      "facts": [
        {
          "kind": "code",
          "literal": "400",
          "chunkId": "api/endpoint#errors"
        },
        {
          "kind": "code",
          "literal": "{ \"error\": \"Invalid JSON body.\" }",
          "chunkId": "api/endpoint#errors"
        },
        {
          "kind": "code",
          "literal": "404",
          "chunkId": "api/endpoint#errors"
        },
        {
          "kind": "code",
          "literal": "{ \"error\": \"…\" }",
          "chunkId": "api/endpoint#errors"
        },
        {
          "kind": "code",
          "literal": "500",
          "chunkId": "api/endpoint#errors"
        },
        {
          "kind": "code",
          "literal": "event: error",
          "chunkId": "api/endpoint#errors"
        },
        {
          "kind": "code",
          "literal": "200",
          "chunkId": "api/endpoint#errors"
        },
        {
          "kind": "code",
          "literal": "error",
          "chunkId": "api/endpoint#errors"
        },
        {
          "kind": "value",
          "literal": "e.g",
          "chunkId": "api/endpoint#errors"
        }
      ],
      "sources": [
        {
          "chunkId": "api/endpoint#errors",
          "url": "/docs/api/endpoint#errors",
          "anchor": "errors"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "errors",
        "table",
        "error",
        "responses",
        "request",
        "invalid",
        "json",
        "found",
        "unknown",
        "read",
        "route",
        "missing",
        "term",
        "section",
        "server",
        "chunk",
        "index",
        "fails",
        "build",
        "failure",
        "during",
        "agentic",
        "stream",
        "arrives",
        "final",
        "event",
        "because",
        "http",
        "status",
        "already",
        "successful",
        "body",
        "cause",
        "wasn",
        "valid",
        "digest",
        "glossary",
        "failed",
        "misconfigured",
        "collection"
      ]
    },
    {
      "id": "api/endpoint#index-lifecycle",
      "kind": "section",
      "title": "Search endpoint",
      "heading": "Index lifecycle",
      "group": "API",
      "url": "/docs/api/endpoint#index-lifecycle",
      "summary": "The chunk index is built once per server instance on the first request and cached for the process lifetime. On that first request the endpoint compares the live content hash against the digest's and logs a one-time warning on mismatch, signaling a rebuild.",
      "hash": "8ae12673a130ca300e56e9955e6f0835a89f68ad5a0152b23de3665127f7dee8",
      "facts": [
        {
          "kind": "code",
          "literal": "ask digest build",
          "chunkId": "api/endpoint#index-lifecycle"
        }
      ],
      "sources": [
        {
          "chunkId": "api/endpoint#index-lifecycle",
          "url": "/docs/api/endpoint#index-lifecycle",
          "anchor": "index-lifecycle"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "index",
        "lifecycle",
        "chunk",
        "built",
        "once",
        "server",
        "instance",
        "first",
        "request",
        "cached",
        "process",
        "lifetime",
        "endpoint",
        "compares",
        "live",
        "content",
        "hash",
        "against",
        "digest",
        "logs",
        "time",
        "warning",
        "mismatch",
        "signaling",
        "rebuild",
        "build",
        "also",
        "differ"
      ]
    },
    {
      "id": "api/endpoint#keyword-response-json",
      "kind": "section",
      "title": "Search endpoint",
      "heading": "Keyword response (JSON)",
      "group": "API",
      "url": "/docs/api/endpoint#keyword-response-json",
      "summary": "Keyword mode returns a successful JSON envelope whose fields are documented in a table: ranked results with title, optional heading, URL, group, and snippet; the echoed query; the configured loop model; the mode that ran; and an optional warning when agentic was requested with no key. The result URL carries the deep link with anchor appended except for a document's intro chunk.",
      "hash": "bbc5f7240f935311df97464c2bf6780dc597f246cfa94d8bfd9176bfe72cdd40",
      "facts": [
        {
          "kind": "code",
          "literal": "{\n  \"results\": [\n    {\n      \"title\": \"Concepts\",\n      \"heading\": \"The agentic search loop\",\n      \"url\": \"/docs/concepts#the-agentic-search-loop\",\n      \"group\": \"Overview\",\n      \"snippet\": \"When the reader presses Enter, the query goes to a bounded loop…\"\n    }\n  ],\n  \"query\": \"how does agentic search work\",\n  \"model\": \"claude-haiku-4-5\",\n  \"mode\": \"keyword\"\n}",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "200",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "results",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "Result[]",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "title",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "heading?",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "url",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "group?",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "snippet",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "query",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "string",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "model",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "mode",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "'keyword'",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "warning",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "string?",
          "chunkId": "api/endpoint#keyword-response-json"
        },
        {
          "kind": "code",
          "literal": "#anchor",
          "chunkId": "api/endpoint#keyword-response-json"
        }
      ],
      "sources": [
        {
          "chunkId": "api/endpoint#keyword-response-json",
          "url": "/docs/api/endpoint#keyword-response-json",
          "anchor": "keyword-response-json"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "keyword",
        "response",
        "json",
        "mode",
        "returns",
        "successful",
        "envelope",
        "whose",
        "fields",
        "documented",
        "table",
        "ranked",
        "results",
        "title",
        "optional",
        "heading",
        "group",
        "snippet",
        "echoed",
        "query",
        "configured",
        "loop",
        "model",
        "warning",
        "agentic",
        "requested",
        "result",
        "carries",
        "deep",
        "link",
        "anchor",
        "appended",
        "except",
        "document",
        "intro",
        "chunk",
        "concepts",
        "search",
        "docs",
        "overview"
      ]
    },
    {
      "id": "api/endpoint#llm-tracing",
      "kind": "section",
      "title": "Search endpoint",
      "heading": "LLM tracing",
      "group": "API",
      "url": "/docs/api/endpoint#llm-tracing",
      "summary": "Setting a PostHog key in the environment makes every agentic answer emit a trace with model, tokens, latency, and the loop's tool calls, with additional variables to override the ingestion host and control how much prompt and answer text ships. Without a key tracing is a no-op and the answer path never depends on it.",
      "hash": "e583d09f55427f22b7d112b649fb4111c7081e86ca0197320fc01a19b6e0c354",
      "facts": [
        {
          "kind": "code",
          "literal": "POSTHOG_KEY",
          "chunkId": "api/endpoint#llm-tracing"
        },
        {
          "kind": "code",
          "literal": "POSTHOG_API_KEY",
          "chunkId": "api/endpoint#llm-tracing"
        },
        {
          "kind": "code",
          "literal": "$ai_generation",
          "chunkId": "api/endpoint#llm-tracing"
        },
        {
          "kind": "code",
          "literal": "POSTHOG_HOST",
          "chunkId": "api/endpoint#llm-tracing"
        },
        {
          "kind": "code",
          "literal": "POSTHOG_CAPTURE_CONTENT",
          "chunkId": "api/endpoint#llm-tracing"
        },
        {
          "kind": "code",
          "literal": "off",
          "chunkId": "api/endpoint#llm-tracing"
        },
        {
          "kind": "code",
          "literal": "redacted",
          "chunkId": "api/endpoint#llm-tracing"
        },
        {
          "kind": "code",
          "literal": "full",
          "chunkId": "api/endpoint#llm-tracing"
        }
      ],
      "sources": [
        {
          "chunkId": "api/endpoint#llm-tracing",
          "url": "/docs/api/endpoint#llm-tracing",
          "anchor": "llm-tracing"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "tracing",
        "setting",
        "posthog",
        "environment",
        "makes",
        "every",
        "agentic",
        "answer",
        "emit",
        "trace",
        "model",
        "tokens",
        "latency",
        "loop",
        "tool",
        "calls",
        "additional",
        "variables",
        "override",
        "ingestion",
        "host",
        "control",
        "much",
        "prompt",
        "text",
        "ships",
        "without",
        "path",
        "never",
        "depends",
        "generation",
        "capture",
        "content",
        "redacted",
        "full",
        "posthogkey",
        "posthogapikey",
        "same",
        "emits",
        "aigeneration"
      ]
    },
    {
      "id": "api/endpoint#mode-selection",
      "kind": "section",
      "title": "Search endpoint",
      "heading": "Mode selection",
      "group": "API",
      "url": "/docs/api/endpoint#mode-selection",
      "summary": "The endpoint decides what to run: an empty query returns empty keyword JSON, an explicit keyword request or no key returns keyword JSON, an agentic request without a key returns keyword JSON plus a warning, and otherwise it streams the agentic answer. There is no AI-unavailable error path; a missing key simply downgrades to keyword results, and the overlay branches on the response content type to handle both shapes.",
      "hash": "268456691571b15ea83b4fb47d86fa28225dcc41a170a2483ba5d5e97a419665",
      "facts": [
        {
          "kind": "code",
          "literal": "{ results: [], query: \"\", model, mode: \"keyword\" }",
          "chunkId": "api/endpoint#mode-selection"
        },
        {
          "kind": "code",
          "literal": "mode: \"keyword\"",
          "chunkId": "api/endpoint#mode-selection"
        },
        {
          "kind": "code",
          "literal": "mode: \"agentic\"",
          "chunkId": "api/endpoint#mode-selection"
        },
        {
          "kind": "code",
          "literal": "warning",
          "chunkId": "api/endpoint#mode-selection"
        },
        {
          "kind": "code",
          "literal": "content-type",
          "chunkId": "api/endpoint#mode-selection"
        }
      ],
      "sources": [
        {
          "chunkId": "api/endpoint#mode-selection",
          "url": "/docs/api/endpoint#mode-selection",
          "anchor": "mode-selection"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "mode",
        "selection",
        "endpoint",
        "decides",
        "empty",
        "query",
        "returns",
        "keyword",
        "json",
        "explicit",
        "request",
        "agentic",
        "without",
        "plus",
        "warning",
        "otherwise",
        "streams",
        "answer",
        "there",
        "unavailable",
        "error",
        "path",
        "missing",
        "simply",
        "downgrades",
        "results",
        "overlay",
        "branches",
        "response",
        "content",
        "type",
        "handle",
        "both",
        "shapes",
        "model",
        "stream",
        "says",
        "reader",
        "still",
        "gets"
      ]
    },
    {
      "id": "api/endpoint#request",
      "kind": "section",
      "title": "Search endpoint",
      "heading": "Request",
      "group": "API",
      "url": "/docs/api/endpoint#request",
      "summary": "The endpoint takes a POST with a JSON body documented in a table: a query string where empty or whitespace returns no results, and an optional mode that forces the instant path or requests the loop, defaulting to agentic behavior when a key is present.",
      "hash": "f2a05f3dd644d4d9abb081702bbbc0fe721849ccf0e70f59742aea2ae18980a0",
      "facts": [
        {
          "kind": "code",
          "literal": "{\n  \"query\": \"how does autoscaling work\",\n  \"mode\": \"agentic\"\n}",
          "chunkId": "api/endpoint#request"
        },
        {
          "kind": "code",
          "literal": "POST",
          "chunkId": "api/endpoint#request"
        },
        {
          "kind": "code",
          "literal": "query",
          "chunkId": "api/endpoint#request"
        },
        {
          "kind": "code",
          "literal": "string",
          "chunkId": "api/endpoint#request"
        },
        {
          "kind": "code",
          "literal": "mode",
          "chunkId": "api/endpoint#request"
        },
        {
          "kind": "code",
          "literal": "'keyword' \\| 'agentic'",
          "chunkId": "api/endpoint#request"
        },
        {
          "kind": "code",
          "literal": "keyword",
          "chunkId": "api/endpoint#request"
        },
        {
          "kind": "code",
          "literal": "agentic",
          "chunkId": "api/endpoint#request"
        }
      ],
      "sources": [
        {
          "chunkId": "api/endpoint#request",
          "url": "/docs/api/endpoint#request",
          "anchor": "request"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "request",
        "endpoint",
        "takes",
        "post",
        "json",
        "body",
        "documented",
        "table",
        "query",
        "string",
        "empty",
        "whitespace",
        "returns",
        "results",
        "optional",
        "mode",
        "forces",
        "instant",
        "path",
        "requests",
        "loop",
        "defaulting",
        "agentic",
        "behavior",
        "present",
        "does",
        "autoscaling",
        "work",
        "keyword",
        "field",
        "type",
        "description",
        "search",
        "result",
        "omitted",
        "behaves",
        "like"
      ]
    },
    {
      "id": "api/endpoint#suggested-questions-get",
      "kind": "section",
      "title": "Search endpoint",
      "heading": "Suggested questions (GET)",
      "group": "API",
      "url": "/docs/api/endpoint#suggested-questions-get",
      "summary": "A GET to the base route returns the digest's baked-in suggested questions and the loop model with no query and no model call. The overlay fetches this once on first open when AI is enabled to populate its suggestions; an empty array, including no digest at all, simply shows none.",
      "hash": "09b11b93e36f83adbf3806b64893ae0d6e67036b50132a6ffb096ad9e279489b",
      "facts": [
        {
          "kind": "code",
          "literal": "{\n  \"suggestions\": [\"How does the digest stay fresh?\"],\n  \"model\": \"claude-haiku-4-5\"\n}",
          "chunkId": "api/endpoint#suggested-questions-get"
        },
        {
          "kind": "code",
          "literal": "GET /api/ask",
          "chunkId": "api/endpoint#suggested-questions-get"
        },
        {
          "kind": "code",
          "literal": "suggestions",
          "chunkId": "api/endpoint#suggested-questions-get"
        }
      ],
      "sources": [
        {
          "chunkId": "api/endpoint#suggested-questions-get",
          "url": "/docs/api/endpoint#suggested-questions-get",
          "anchor": "suggested-questions-get"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "suggested",
        "questions",
        "base",
        "route",
        "returns",
        "digest",
        "baked",
        "loop",
        "model",
        "query",
        "call",
        "overlay",
        "fetches",
        "once",
        "first",
        "open",
        "enabled",
        "populate",
        "suggestions",
        "empty",
        "array",
        "including",
        "simply",
        "shows",
        "none",
        "does",
        "stay",
        "fresh",
        "claude",
        "haiku",
        "without",
        "just",
        "means"
      ]
    },
    {
      "id": "api/endpoint#the-api-key",
      "kind": "section",
      "title": "Search endpoint",
      "heading": "The API key",
      "group": "API",
      "url": "/docs/api/endpoint#the-api-key",
      "summary": "The endpoint reads the key named by the configured provider from the adapter runtime environment, then the process environment, then the build-time environment, in that order. Set it wherever the host injects server secrets; it is never sent to the browser.",
      "hash": "6b9f401de0da470a422dab86c8b67ba6461101611461a5f6ad508bcf0c854ece",
      "facts": [
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "api/endpoint#the-api-key"
        },
        {
          "kind": "code",
          "literal": "OPENAI_API_KEY",
          "chunkId": "api/endpoint#the-api-key"
        },
        {
          "kind": "code",
          "literal": "OPENROUTER_API_KEY",
          "chunkId": "api/endpoint#the-api-key"
        },
        {
          "kind": "code",
          "literal": "provider",
          "chunkId": "api/endpoint#the-api-key"
        },
        {
          "kind": "code",
          "literal": "locals.runtime.env",
          "chunkId": "api/endpoint#the-api-key"
        },
        {
          "kind": "code",
          "literal": "process.env",
          "chunkId": "api/endpoint#the-api-key"
        },
        {
          "kind": "code",
          "literal": "import.meta.env",
          "chunkId": "api/endpoint#the-api-key"
        },
        {
          "kind": "value",
          "literal": "e.g",
          "chunkId": "api/endpoint#the-api-key"
        }
      ],
      "sources": [
        {
          "chunkId": "api/endpoint#the-api-key",
          "url": "/docs/api/endpoint#the-api-key",
          "anchor": "the-api-key"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "endpoint",
        "reads",
        "named",
        "configured",
        "provider",
        "adapter",
        "runtime",
        "environment",
        "process",
        "build",
        "time",
        "order",
        "wherever",
        "host",
        "injects",
        "server",
        "secrets",
        "never",
        "sent",
        "browser",
        "anthropic",
        "openai",
        "openrouter",
        "locals",
        "import",
        "meta",
        "anthropicapikey",
        "default",
        "openaiapikey",
        "openrouterapikey",
        "option",
        "cloudflare"
      ]
    },
    {
      "id": "api/mcp",
      "kind": "section",
      "title": "MCP server",
      "heading": null,
      "group": "API",
      "url": "/docs/api/mcp",
      "summary": "The MCP command runs a stdio server that is one tool plus instructions: the tool downloads the whole digest tree to local disk and the instructions tell the agent to navigate it with its own file tools and cite every claim with the section's deep link. Since an MCP consumer is already an agent it needs the corpus rather than synthesis, so there is no answer tool here.",
      "hash": "ff242827eef613609690f7b116ad40577a561e412599b78d9afd465f7436aaac",
      "facts": [
        {
          "kind": "code",
          "literal": "ask mcp",
          "chunkId": "api/mcp"
        },
        {
          "kind": "code",
          "literal": "tree",
          "chunkId": "api/mcp"
        },
        {
          "kind": "code",
          "literal": "cat",
          "chunkId": "api/mcp"
        },
        {
          "kind": "code",
          "literal": "grep",
          "chunkId": "api/mcp"
        },
        {
          "kind": "code",
          "literal": "url",
          "chunkId": "api/mcp"
        },
        {
          "kind": "code",
          "literal": "anchor",
          "chunkId": "api/mcp"
        },
        {
          "kind": "code",
          "literal": "ls",
          "chunkId": "api/mcp"
        },
        {
          "kind": "code",
          "literal": "answer",
          "chunkId": "api/mcp"
        },
        {
          "kind": "value",
          "literal": "Callout.astro",
          "chunkId": "api/mcp"
        }
      ],
      "sources": [
        {
          "chunkId": "api/mcp",
          "url": "/docs/api/mcp",
          "anchor": null
        }
      ],
      "mode": "source-primary",
      "terms": [
        "command",
        "runs",
        "stdio",
        "server",
        "tool",
        "plus",
        "instructions",
        "downloads",
        "whole",
        "digest",
        "tree",
        "local",
        "disk",
        "tell",
        "agent",
        "navigate",
        "file",
        "tools",
        "cite",
        "every",
        "claim",
        "section",
        "deep",
        "link",
        "since",
        "consumer",
        "already",
        "needs",
        "corpus",
        "rather",
        "synthesis",
        "there",
        "answer",
        "here",
        "grep",
        "anchor",
        "callout",
        "astro",
        "hand",
        "coding"
      ]
    },
    {
      "id": "api/mcp#co-location",
      "kind": "section",
      "title": "MCP server",
      "heading": "Co-location",
      "group": "API",
      "url": "/docs/api/mcp#co-location",
      "summary": "Hydrate-to-disk assumes the MCP server and the agent's file tools share a host, which is true for the default stdio transport, and the server intentionally exposes only that path. A remote transport where the agent cannot read the server's cache would need a separate resource or tool fallback, since returning a local path would not help.",
      "hash": "0dd5d436dbfe12945ae2a67bf0100156e9645f9c1e9a8afe293b1b83a7348757",
      "facts": [
        {
          "kind": "code",
          "literal": "ask mcp",
          "chunkId": "api/mcp#co-location"
        }
      ],
      "sources": [
        {
          "chunkId": "api/mcp#co-location",
          "url": "/docs/api/mcp#co-location",
          "anchor": "co-location"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "location",
        "hydrate",
        "disk",
        "assumes",
        "server",
        "agent",
        "file",
        "tools",
        "share",
        "host",
        "true",
        "default",
        "stdio",
        "transport",
        "intentionally",
        "exposes",
        "only",
        "path",
        "remote",
        "cannot",
        "read",
        "cache",
        "would",
        "need",
        "separate",
        "resource",
        "tool",
        "fallback",
        "since",
        "returning",
        "local",
        "help",
        "stdin",
        "stdout",
        "because",
        "useful"
      ]
    },
    {
      "id": "api/mcp#configure",
      "kind": "section",
      "title": "MCP server",
      "heading": "Configure",
      "group": "API",
      "url": "/docs/api/mcp#configure",
      "summary": "Shows MCP client configuration for two cases: a keyless setup pointing at a local checked-out tree, and one pointing at a deployed site's endpoint, which lets any site running hev ask be pulled into the agent's workspace from anywhere.",
      "hash": "bd48710aaa8e6b45422ed8cee00e44b2004fdbd68d1178fac60bae41e706b728",
      "facts": [
        {
          "kind": "code",
          "literal": "{\n  \"mcpServers\": {\n    \"docs\": {\n      \"command\": \"ask\",\n      \"args\": [\"--digest-dir\", \".hev-ask\", \"mcp\"]\n    }\n  }\n}",
          "chunkId": "api/mcp#configure"
        },
        {
          "kind": "code",
          "literal": "{\n  \"mcpServers\": {\n    \"hevask\": {\n      \"command\": \"ask\",\n      \"args\": [\"--endpoint\", \"https://hevask.com/api/ask\", \"mcp\"]\n    }\n  }\n}",
          "chunkId": "api/mcp#configure"
        }
      ],
      "sources": [
        {
          "chunkId": "api/mcp#configure",
          "url": "/docs/api/mcp#configure",
          "anchor": "configure"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "configure",
        "shows",
        "client",
        "configuration",
        "cases",
        "keyless",
        "setup",
        "pointing",
        "local",
        "checked",
        "tree",
        "deployed",
        "site",
        "endpoint",
        "lets",
        "running",
        "pulled",
        "agent",
        "workspace",
        "anywhere",
        "mcpservers",
        "docs",
        "command",
        "args",
        "digest",
        "hevask",
        "https",
        "repo",
        "reads",
        "including",
        "other",
        "runs"
      ]
    },
    {
      "id": "api/mcp#data-sources",
      "kind": "section",
      "title": "MCP server",
      "heading": "Data sources",
      "group": "API",
      "url": "/docs/api/mcp#data-sources",
      "summary": "The MCP server uses the same source resolution as the CLI: a remote endpoint downloads the deployed tree as a compressed archive, otherwise it reads the local digest directory. A just-rebuilt tree becomes visible on the next fetch without restarting the server.",
      "hash": "863a2df687abe731858ab1157d344474fb96e257b5e52ec7266642179186a4dc",
      "facts": [
        {
          "kind": "code",
          "literal": "ask mcp",
          "chunkId": "api/mcp#data-sources"
        },
        {
          "kind": "code",
          "literal": "--endpoint <url>",
          "chunkId": "api/mcp#data-sources"
        },
        {
          "kind": "code",
          "literal": "/api/ask/archive",
          "chunkId": "api/mcp#data-sources"
        },
        {
          "kind": "code",
          "literal": "--digest-dir",
          "chunkId": "api/mcp#data-sources"
        },
        {
          "kind": "code",
          "literal": ".hev-ask",
          "chunkId": "api/mcp#data-sources"
        },
        {
          "kind": "code",
          "literal": "fetch_docs",
          "chunkId": "api/mcp#data-sources"
        }
      ],
      "sources": [
        {
          "chunkId": "api/mcp#data-sources",
          "url": "/docs/api/mcp#data-sources",
          "anchor": "data-sources"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "data",
        "sources",
        "server",
        "uses",
        "same",
        "source",
        "resolution",
        "remote",
        "endpoint",
        "downloads",
        "deployed",
        "tree",
        "compressed",
        "archive",
        "otherwise",
        "reads",
        "local",
        "digest",
        "directory",
        "just",
        "rebuilt",
        "becomes",
        "visible",
        "next",
        "fetch",
        "without",
        "restarting",
        "docs",
        "disk",
        "defaulting",
        "fetchdocs"
      ]
    },
    {
      "id": "api/mcp#protocol-surface",
      "kind": "section",
      "title": "MCP server",
      "heading": "Protocol surface",
      "group": "API",
      "url": "/docs/api/mcp#protocol-surface",
      "summary": "The server speaks newline-delimited JSON-RPC over stdio and handles initialization (returning the instructions), tool listing, and tool calls, plus the initialized notification. Unknown methods return a protocol error and tool failures return an error result, keeping the server thin because all substantive behavior lives in the shared core that the CLI, command group, and MCP server reuse.",
      "hash": "e99d0aabc9e51f725c1d5a66babc38fafa6631b456ce3eeb9647327596ca44ce",
      "facts": [
        {
          "kind": "code",
          "literal": "initialize",
          "chunkId": "api/mcp#protocol-surface"
        },
        {
          "kind": "code",
          "literal": "instructions",
          "chunkId": "api/mcp#protocol-surface"
        },
        {
          "kind": "code",
          "literal": "tools/list",
          "chunkId": "api/mcp#protocol-surface"
        },
        {
          "kind": "code",
          "literal": "tools/call",
          "chunkId": "api/mcp#protocol-surface"
        },
        {
          "kind": "code",
          "literal": "isError: true",
          "chunkId": "api/mcp#protocol-surface"
        },
        {
          "kind": "code",
          "literal": "pkg/ask",
          "chunkId": "api/mcp#protocol-surface"
        }
      ],
      "sources": [
        {
          "chunkId": "api/mcp#protocol-surface",
          "url": "/docs/api/mcp#protocol-surface",
          "anchor": "protocol-surface"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "protocol",
        "surface",
        "server",
        "speaks",
        "newline",
        "delimited",
        "json",
        "stdio",
        "handles",
        "initialization",
        "returning",
        "instructions",
        "tool",
        "listing",
        "calls",
        "plus",
        "initialized",
        "notification",
        "unknown",
        "methods",
        "return",
        "error",
        "failures",
        "result",
        "keeping",
        "thin",
        "because",
        "substantive",
        "behavior",
        "lives",
        "shared",
        "core",
        "command",
        "group",
        "reuse",
        "initialize",
        "tools",
        "list",
        "call",
        "iserror"
      ]
    },
    {
      "id": "api/mcp#the-instructions",
      "kind": "section",
      "title": "MCP server",
      "heading": "The instructions",
      "group": "API",
      "url": "/docs/api/mcp#the-instructions",
      "summary": "The server's instructions string teaches the agent two things: navigation, to read the inline title-tree first and open sections only when relevant rather than reading everything; and citation, to answer from the files and cite every claim with the section's deep link. Citation is the easy-to-lose part that carries the entire grounded-deep-link value, so the instructions make it non-negotiable.",
      "hash": "14bcb7471103193eb94df0723bcfe733355523b8b1442cae8c864428d6418c5b",
      "facts": [
        {
          "kind": "code",
          "literal": "instructions",
          "chunkId": "api/mcp#the-instructions"
        },
        {
          "kind": "code",
          "literal": "cat",
          "chunkId": "api/mcp#the-instructions"
        },
        {
          "kind": "code",
          "literal": "grep",
          "chunkId": "api/mcp#the-instructions"
        },
        {
          "kind": "code",
          "literal": "_glossary/",
          "chunkId": "api/mcp#the-instructions"
        },
        {
          "kind": "code",
          "literal": "url",
          "chunkId": "api/mcp#the-instructions"
        },
        {
          "kind": "code",
          "literal": "anchor",
          "chunkId": "api/mcp#the-instructions"
        },
        {
          "kind": "code",
          "literal": "/docs/page#anchor",
          "chunkId": "api/mcp#the-instructions"
        }
      ],
      "sources": [
        {
          "chunkId": "api/mcp#the-instructions",
          "url": "/docs/api/mcp#the-instructions",
          "anchor": "the-instructions"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "instructions",
        "server",
        "string",
        "teaches",
        "agent",
        "things",
        "navigation",
        "read",
        "inline",
        "title",
        "tree",
        "first",
        "open",
        "sections",
        "only",
        "relevant",
        "rather",
        "reading",
        "everything",
        "citation",
        "answer",
        "files",
        "cite",
        "every",
        "claim",
        "section",
        "deep",
        "link",
        "easy",
        "lose",
        "part",
        "carries",
        "entire",
        "grounded",
        "value",
        "make",
        "negotiable",
        "grep",
        "glossary",
        "anchor"
      ]
    },
    {
      "id": "api/mcp#the-tool",
      "kind": "section",
      "title": "MCP server",
      "heading": "The tool",
      "group": "API",
      "url": "/docs/api/mcp#the-tool",
      "summary": "The single tool materializes the digest tree at a host-keyed local cache path and returns the title-tree inline plus on-disk bodies and facts, so one call bootstraps the whole disclosure ladder with no second round-trip and the agent then uses its native tools. A force argument re-pulls unconditionally, otherwise it compares the remote content hash and re-downloads only on mismatch; because the corpus is bounded the whole tree ships compressed in one shot with no per-file delta protocol.",
      "hash": "54bc7be8d62d5112772761d161b203c851308fffd7751b1c920e8c99e1975b96",
      "facts": [
        {
          "kind": "code",
          "literal": "tree ~/.cache/hev-ask/hevask.com        # already returned inline by fetch_docs\ncat  ~/.cache/hev-ask/hevask.com/overview/quick-start.md\ngrep -r \"prerender\" ~/.cache/hev-ask/hevask.com",
          "chunkId": "api/mcp#the-tool"
        },
        {
          "kind": "code",
          "literal": "fetch_docs",
          "chunkId": "api/mcp#the-tool"
        },
        {
          "kind": "code",
          "literal": "{ force?: boolean }",
          "chunkId": "api/mcp#the-tool"
        },
        {
          "kind": "code",
          "literal": "{ path, contentHash, sections, tree, upToDate }",
          "chunkId": "api/mcp#the-tool"
        },
        {
          "kind": "code",
          "literal": "~/.cache/hev-ask/hevask.com/",
          "chunkId": "api/mcp#the-tool"
        },
        {
          "kind": "code",
          "literal": "force: true",
          "chunkId": "api/mcp#the-tool"
        },
        {
          "kind": "code",
          "literal": "contentHash",
          "chunkId": "api/mcp#the-tool"
        },
        {
          "kind": "code",
          "literal": "upToDate: true",
          "chunkId": "api/mcp#the-tool"
        },
        {
          "kind": "value",
          "literal": "e.g",
          "chunkId": "api/mcp#the-tool"
        }
      ],
      "sources": [
        {
          "chunkId": "api/mcp#the-tool",
          "url": "/docs/api/mcp#the-tool",
          "anchor": "the-tool"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "tool",
        "single",
        "materializes",
        "digest",
        "tree",
        "host",
        "keyed",
        "local",
        "cache",
        "path",
        "returns",
        "title",
        "inline",
        "plus",
        "disk",
        "bodies",
        "facts",
        "call",
        "bootstraps",
        "whole",
        "disclosure",
        "ladder",
        "second",
        "round",
        "trip",
        "agent",
        "uses",
        "native",
        "tools",
        "force",
        "argument",
        "pulls",
        "unconditionally",
        "otherwise",
        "compares",
        "remote",
        "content",
        "hash",
        "downloads",
        "only"
      ]
    },
    {
      "id": "api/search-overlay",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": null,
      "group": "API",
      "url": "/docs/api/search-overlay",
      "summary": "The SearchOverlay component renders the ⌘K command palette, added once in a global layout. It opens over the page and does not affect layout until opened.",
      "hash": "d5156262703aa7e6cb35195e090b1c23f46c9afc441cd1132e051a171936da45",
      "facts": [
        {
          "kind": "code",
          "literal": "---\nimport SearchOverlay from \"@hevmind/ask/components/SearchOverlay.astro\";\n---\n<SearchOverlay />",
          "chunkId": "api/search-overlay"
        },
        {
          "kind": "code",
          "literal": "SearchOverlay.astro",
          "chunkId": "api/search-overlay"
        },
        {
          "kind": "code",
          "literal": "⌘K",
          "chunkId": "api/search-overlay"
        },
        {
          "kind": "code",
          "literal": "<dialog>",
          "chunkId": "api/search-overlay"
        },
        {
          "kind": "value",
          "literal": "Callout.astro",
          "chunkId": "api/search-overlay"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay",
          "url": "/docs/api/search-overlay",
          "anchor": null
        }
      ],
      "mode": "source-primary",
      "terms": [
        "searchoverlay",
        "component",
        "renders",
        "command",
        "palette",
        "added",
        "once",
        "global",
        "layout",
        "opens",
        "page",
        "does",
        "affect",
        "until",
        "opened",
        "import",
        "hevmind",
        "components",
        "astro",
        "dialog",
        "callout",
        "props",
        "data",
        "open",
        "opener",
        "attribute",
        "keyboard",
        "model",
        "mode",
        "toggle",
        "theming",
        "through",
        "variables",
        "drop",
        "script",
        "overlay",
        "docusaurus",
        "vitepress",
        "mkdocs",
        "static"
      ]
    },
    {
      "id": "api/search-overlay#any-static-site",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "Any static site",
      "group": "API",
      "url": "/docs/api/search-overlay#any-static-site",
      "summary": "For any static site there is no framework to satisfy: run the bundle command in your build, deploy its output alongside your HTML, and drop the script tag into your template, adding the endpoint attribute when you want answers.",
      "hash": "5bc9f3e49238a7029f2917dba220035cdbde4b3141ca78013be0cb6e04d31301",
      "facts": [
        {
          "kind": "code",
          "literal": "ask digest bundle",
          "chunkId": "api/search-overlay#any-static-site"
        },
        {
          "kind": "code",
          "literal": "<script>",
          "chunkId": "api/search-overlay#any-static-site"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#any-static-site",
          "url": "/docs/api/search-overlay#any-static-site",
          "anchor": "any-static-site"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "static",
        "site",
        "there",
        "framework",
        "satisfy",
        "bundle",
        "command",
        "build",
        "deploy",
        "output",
        "alongside",
        "html",
        "drop",
        "script",
        "template",
        "adding",
        "endpoint",
        "attribute",
        "want",
        "answers",
        "digest",
        "release",
        "step"
      ]
    },
    {
      "id": "api/search-overlay#bundling-the-static-assets",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "Bundling the static assets",
      "group": "API",
      "url": "/docs/api/search-overlay#bundling-the-static-assets",
      "summary": "The bundle command emits the browser payload (keyword index, glossary, suggestions, and title-tree) into a served directory, run as part of your build like the HTML render step. The output is served rather than committed, so gitignore it while keeping the committed tree as the reviewable source of truth; regenerating every build keeps the assets from drifting from what you deploy.",
      "hash": "77f8c50f2486577e256ed8eda9ca5648330bd15f01f56ec275d154b6dfa0019d",
      "facts": [
        {
          "kind": "code",
          "literal": "ask digest bundle",
          "chunkId": "api/search-overlay#bundling-the-static-assets"
        },
        {
          "kind": "code",
          "literal": ".hev-ask/",
          "chunkId": "api/search-overlay#bundling-the-static-assets"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#bundling-the-static-assets",
          "url": "/docs/api/search-overlay#bundling-the-static-assets",
          "anchor": "bundling-the-static-assets"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "bundling",
        "static",
        "assets",
        "bundle",
        "command",
        "emits",
        "browser",
        "payload",
        "keyword",
        "index",
        "glossary",
        "suggestions",
        "title",
        "tree",
        "served",
        "directory",
        "part",
        "build",
        "like",
        "html",
        "render",
        "step",
        "output",
        "rather",
        "committed",
        "gitignore",
        "while",
        "keeping",
        "reviewable",
        "source",
        "truth",
        "regenerating",
        "every",
        "keeps",
        "drifting",
        "deploy",
        "digest",
        "site",
        "serves",
        "renders"
      ]
    },
    {
      "id": "api/search-overlay#docusaurus",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "Docusaurus",
      "group": "API",
      "url": "/docs/api/search-overlay#docusaurus",
      "summary": "Shows the Docusaurus wiring: emit the bundle into the static directory from the build script and add the overlay script through the site config. Docusaurus headings carry explicit custom-id anchors, which its slug mode honors and verify checks against the built HTML.",
      "hash": "6eceffab590110ca1344359049f1a1892f1f4d5c2871542003b2a624ada9a945",
      "facts": [
        {
          "kind": "code",
          "literal": "// docusaurus.config.js\nexport default {\n  scripts: [\n    {\n      src: \"https://cdn.jsdelivr.net/npm/@hevmind/ask/overlay.js\",\n      type: \"module\",\n      \"data-hev-ask-digest\": \"/hev-ask/\",\n      \"data-hev-ask-endpoint\": \"https://docs-ask.example.workers.dev/api/ask\",\n    },\n  ],\n};",
          "chunkId": "api/search-overlay#docusaurus"
        },
        {
          "kind": "code",
          "literal": "// package.json — bundle into the static dir before docusaurus build\n\"scripts\": {\n  \"build\": \"ask digest bundle --out static/hev-ask && docusaurus build\"\n}",
          "chunkId": "api/search-overlay#docusaurus"
        },
        {
          "kind": "code",
          "literal": "static/",
          "chunkId": "api/search-overlay#docusaurus"
        },
        {
          "kind": "code",
          "literal": "build",
          "chunkId": "api/search-overlay#docusaurus"
        },
        {
          "kind": "code",
          "literal": "docusaurus.config.js",
          "chunkId": "api/search-overlay#docusaurus"
        },
        {
          "kind": "code",
          "literal": "{#custom-id}",
          "chunkId": "api/search-overlay#docusaurus"
        },
        {
          "kind": "code",
          "literal": "ask digest verify",
          "chunkId": "api/search-overlay#docusaurus"
        },
        {
          "kind": "code",
          "literal": "build/",
          "chunkId": "api/search-overlay#docusaurus"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#docusaurus",
          "url": "/docs/api/search-overlay#docusaurus",
          "anchor": "docusaurus"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "docusaurus",
        "shows",
        "wiring",
        "emit",
        "bundle",
        "static",
        "directory",
        "build",
        "script",
        "overlay",
        "through",
        "site",
        "config",
        "headings",
        "carry",
        "explicit",
        "custom",
        "anchors",
        "slug",
        "mode",
        "honors",
        "verify",
        "checks",
        "against",
        "built",
        "html",
        "export",
        "default",
        "scripts",
        "https",
        "jsdelivr",
        "hevmind",
        "type",
        "module",
        "data",
        "digest",
        "endpoint",
        "docs",
        "example",
        "workers"
      ]
    },
    {
      "id": "api/search-overlay#keyboard-model",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "Keyboard model",
      "group": "API",
      "url": "/docs/api/search-overlay#keyboard-model",
      "summary": "The overlay is ask-first and the number of words typed decides the path: opening with AI on shows suggested questions, one word runs debounced keyless keyword search with the first result auto-active, and typing a space switches to ask mode where Enter sends the question to the agentic loop. Arrow keys move the keyword selection, Escape closes, and the footer hint reflects the mode; with no server key, asking returns keyword results plus a shown warning rather than escalating.",
      "hash": "ee1d21380babc93166dcbdb53a1180c1fd71608113d3f633a28f81b7c40dd1b6",
      "facts": [
        {
          "kind": "code",
          "literal": "Tab",
          "chunkId": "api/search-overlay#keyboard-model"
        },
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "api/search-overlay#keyboard-model"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#keyboard-model",
          "url": "/docs/api/search-overlay#keyboard-model",
          "anchor": "keyboard-model"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "keyboard",
        "model",
        "overlay",
        "first",
        "number",
        "words",
        "typed",
        "decides",
        "path",
        "opening",
        "shows",
        "suggested",
        "questions",
        "word",
        "runs",
        "debounced",
        "keyless",
        "keyword",
        "search",
        "result",
        "auto",
        "active",
        "typing",
        "space",
        "switches",
        "mode",
        "enter",
        "sends",
        "question",
        "agentic",
        "loop",
        "arrow",
        "keys",
        "move",
        "selection",
        "escape",
        "closes",
        "footer",
        "hint",
        "reflects"
      ]
    },
    {
      "id": "api/search-overlay#keyword-results-and-deep-links",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "Keyword results and deep links",
      "group": "API",
      "url": "/docs/api/search-overlay#keyword-results-and-deep-links",
      "summary": "Each keyword result row shows the document title, an optional heading breadcrumb, and a one-line snippet, and the row's link is the chunk's URL with its anchor already appended so clicking lands on the exact heading.",
      "hash": "330287eee67f4021f8ba2a74434848977080dfdc106b39f73bac9c0326d60a78",
      "facts": [
        {
          "kind": "code",
          "literal": "Concepts › The agentic loop",
          "chunkId": "api/search-overlay#keyword-results-and-deep-links"
        },
        {
          "kind": "code",
          "literal": "url",
          "chunkId": "api/search-overlay#keyword-results-and-deep-links"
        },
        {
          "kind": "code",
          "literal": "#anchor",
          "chunkId": "api/search-overlay#keyword-results-and-deep-links"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#keyword-results-and-deep-links",
          "url": "/docs/api/search-overlay#keyword-results-and-deep-links",
          "anchor": "keyword-results-and-deep-links"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "keyword",
        "results",
        "deep",
        "links",
        "result",
        "shows",
        "document",
        "title",
        "optional",
        "heading",
        "breadcrumb",
        "line",
        "snippet",
        "link",
        "chunk",
        "anchor",
        "already",
        "appended",
        "clicking",
        "lands",
        "exact",
        "concepts",
        "agentic",
        "loop",
        "renders",
        "carries"
      ]
    },
    {
      "id": "api/search-overlay#mkdocs",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "MkDocs",
      "group": "API",
      "url": "/docs/api/search-overlay#mkdocs",
      "summary": "Shows the MkDocs wiring: bundle the assets into a docs subdirectory and reference the overlay script through the site config's extra-JavaScript list.",
      "hash": "5ff9bd89fc3f721d871f2e212ce8636856466218e115dacabc4e9bad5a20aca6",
      "facts": [
        {
          "kind": "code",
          "literal": "# mkdocs.yml\nextra_javascript:\n  - hev-ask/overlay.js",
          "chunkId": "api/search-overlay#mkdocs"
        },
        {
          "kind": "code",
          "literal": "docs/hev-ask/",
          "chunkId": "api/search-overlay#mkdocs"
        },
        {
          "kind": "code",
          "literal": "extra_javascript",
          "chunkId": "api/search-overlay#mkdocs"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#mkdocs",
          "url": "/docs/api/search-overlay#mkdocs",
          "anchor": "mkdocs"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "mkdocs",
        "shows",
        "wiring",
        "bundle",
        "assets",
        "docs",
        "subdirectory",
        "reference",
        "overlay",
        "script",
        "through",
        "site",
        "config",
        "extra",
        "javascript",
        "list",
        "extrajavascript"
      ]
    },
    {
      "id": "api/search-overlay#opening-the-overlay",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "Opening the overlay",
      "group": "API",
      "url": "/docs/api/search-overlay#opening-the-overlay",
      "summary": "Two built-in ways to open the overlay: the ⌘K / Ctrl-K shortcut is bound automatically once the component is on the page, and any element carrying the opener attribute opens it on click, so you can wire up as many triggers as you like.",
      "hash": "3e4c8449e1af4f6a284fdcd274b32d88321a897b8133c10c6c232e10ec4d6a3f",
      "facts": [
        {
          "kind": "code",
          "literal": "<button type=\"button\" data-hev-ask-open>\n  Search <kbd>⌘K</kbd>\n</button>\n\n<a href=\"#\" data-hev-ask-open>Search the docs</a>",
          "chunkId": "api/search-overlay#opening-the-overlay"
        },
        {
          "kind": "code",
          "literal": "⌘K",
          "chunkId": "api/search-overlay#opening-the-overlay"
        },
        {
          "kind": "code",
          "literal": "Ctrl-K",
          "chunkId": "api/search-overlay#opening-the-overlay"
        },
        {
          "kind": "code",
          "literal": "data-hev-ask-open",
          "chunkId": "api/search-overlay#opening-the-overlay"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#opening-the-overlay",
          "url": "/docs/api/search-overlay#opening-the-overlay",
          "anchor": "opening-the-overlay"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "opening",
        "overlay",
        "built",
        "ways",
        "open",
        "ctrl",
        "shortcut",
        "bound",
        "automatically",
        "once",
        "component",
        "page",
        "element",
        "carrying",
        "opener",
        "attribute",
        "opens",
        "click",
        "wire",
        "many",
        "triggers",
        "like",
        "button",
        "type",
        "data",
        "search",
        "href",
        "docs",
        "both",
        "header",
        "sidebar",
        "inline",
        "links"
      ]
    },
    {
      "id": "api/search-overlay#props",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "Props",
      "group": "API",
      "url": "/docs/api/search-overlay#props",
      "summary": "A table of the overlay component's props with defaults: the endpoint it posts to, which must match the integration's endpoint option; the input placeholder text; and the debounce delay before a keyword query is sent.",
      "hash": "ae4f683359160725bca5d58e0e1aac3897a94d552fab66a948c2682add9e2524",
      "facts": [
        {
          "kind": "code",
          "literal": "<SearchOverlay\n  endpoint=\"/api/ask\"\n  placeholder=\"Search hev ask…\"\n  debounce={400}\n/>",
          "chunkId": "api/search-overlay#props"
        },
        {
          "kind": "code",
          "literal": "endpoint",
          "chunkId": "api/search-overlay#props"
        },
        {
          "kind": "code",
          "literal": "string",
          "chunkId": "api/search-overlay#props"
        },
        {
          "kind": "code",
          "literal": "'/api/ask'",
          "chunkId": "api/search-overlay#props"
        },
        {
          "kind": "code",
          "literal": "placeholder",
          "chunkId": "api/search-overlay#props"
        },
        {
          "kind": "code",
          "literal": "'Search the docs…'",
          "chunkId": "api/search-overlay#props"
        },
        {
          "kind": "code",
          "literal": "debounce",
          "chunkId": "api/search-overlay#props"
        },
        {
          "kind": "code",
          "literal": "number",
          "chunkId": "api/search-overlay#props"
        },
        {
          "kind": "code",
          "literal": "500",
          "chunkId": "api/search-overlay#props"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#props",
          "url": "/docs/api/search-overlay#props",
          "anchor": "props"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "props",
        "table",
        "overlay",
        "component",
        "defaults",
        "endpoint",
        "posts",
        "must",
        "match",
        "integration",
        "option",
        "input",
        "placeholder",
        "text",
        "debounce",
        "delay",
        "before",
        "keyword",
        "query",
        "sent",
        "searchoverlay",
        "search",
        "string",
        "docs",
        "number",
        "prop",
        "type",
        "default",
        "description",
        "queries",
        "milliseconds",
        "after",
        "typing",
        "stops"
      ]
    },
    {
      "id": "api/search-overlay#suggested-questions",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "Suggested questions",
      "group": "API",
      "url": "/docs/api/search-overlay#suggested-questions",
      "summary": "When AI is on, the overlay fetches a short list of suggested questions from the endpoint the first time it opens and shows them in the empty state. They come from the digest's baked-in suggestions, so there is no model call to render them, and an empty list simply shows nothing; clicking a suggestion fills the input and asks it immediately.",
      "hash": "7b69c77e3577551acb6b854069a902fa75a2f4e203eaa0343c33db7656710c47",
      "facts": [
        {
          "kind": "code",
          "literal": "GET /api/ask",
          "chunkId": "api/search-overlay#suggested-questions"
        },
        {
          "kind": "code",
          "literal": "suggestions",
          "chunkId": "api/search-overlay#suggested-questions"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#suggested-questions",
          "url": "/docs/api/search-overlay#suggested-questions",
          "anchor": "suggested-questions"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "suggested",
        "questions",
        "overlay",
        "fetches",
        "short",
        "list",
        "endpoint",
        "first",
        "time",
        "opens",
        "shows",
        "empty",
        "state",
        "come",
        "digest",
        "baked",
        "suggestions",
        "there",
        "model",
        "call",
        "render",
        "simply",
        "nothing",
        "clicking",
        "suggestion",
        "fills",
        "input",
        "asks",
        "immediately",
        "build",
        "none",
        "extra"
      ]
    },
    {
      "id": "api/search-overlay#support-at-a-glance",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "Support at a glance",
      "group": "API",
      "url": "/docs/api/search-overlay#support-at-a-glance",
      "summary": "A matrix of framework support across digest build, keyword overlay, and agentic answers: Astro is turnkey through the integration and mounted route, while Docusaurus, VitePress, MkDocs, and plain static sites run the digest build in their own pipeline, drop in the overlay, and use a hostable endpoint for answers. The CLI and MCP surfaces are host-neutral on every row, giving a coding agent the same reads regardless of renderer.",
      "hash": "459a17a643d2212b27a127a6fab51e535bcc32e9fdc9cd83250b058d472224ce",
      "facts": [
        {
          "kind": "code",
          "literal": "hevAsk()",
          "chunkId": "api/search-overlay#support-at-a-glance"
        },
        {
          "kind": "code",
          "literal": "SearchOverlay.astro",
          "chunkId": "api/search-overlay#support-at-a-glance"
        },
        {
          "kind": "code",
          "literal": "/api/ask",
          "chunkId": "api/search-overlay#support-at-a-glance"
        },
        {
          "kind": "code",
          "literal": "ask digest",
          "chunkId": "api/search-overlay#support-at-a-glance"
        },
        {
          "kind": "code",
          "literal": "<script>",
          "chunkId": "api/search-overlay#support-at-a-glance"
        },
        {
          "kind": "code",
          "literal": "mountHevAsk",
          "chunkId": "api/search-overlay#support-at-a-glance"
        },
        {
          "kind": "code",
          "literal": "extra_javascript",
          "chunkId": "api/search-overlay#support-at-a-glance"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#support-at-a-glance",
          "url": "/docs/api/search-overlay#support-at-a-glance",
          "anchor": "support-at-a-glance"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "support",
        "glance",
        "matrix",
        "framework",
        "across",
        "digest",
        "build",
        "keyword",
        "overlay",
        "agentic",
        "answers",
        "astro",
        "turnkey",
        "through",
        "integration",
        "mounted",
        "route",
        "while",
        "docusaurus",
        "vitepress",
        "mkdocs",
        "plain",
        "static",
        "sites",
        "their",
        "pipeline",
        "drop",
        "hostable",
        "endpoint",
        "surfaces",
        "host",
        "neutral",
        "every",
        "giving",
        "coding",
        "agent",
        "same",
        "reads",
        "regardless",
        "renderer"
      ]
    },
    {
      "id": "api/search-overlay#the-hostable-endpoint",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "The hostable endpoint",
      "group": "API",
      "url": "/docs/api/search-overlay#the-hostable-endpoint",
      "summary": "For agentic answers without Astro, deploy the bounded answer loop as a standalone service (a Cloudflare Worker, a Node server, or a Vercel function) that serves the same endpoint contract, holds the key server-side, and reads the committed tree. Deploy it once and point any number of sites' overlays at it; keyword search stays in the browser, so only the answer loop needs anything deployed, and a scaffold command bootstraps the Worker flavor.",
      "hash": "de2a87abed98b0710faec2697d9c06ee50122f8ab3852fc8e2133a2af0333886",
      "facts": [
        {
          "kind": "code",
          "literal": "# scaffold and deploy the Worker flavor\nask endpoint init --target cloudflare\nwrangler deploy            # set ANTHROPIC_API_KEY as a secret",
          "chunkId": "api/search-overlay#the-hostable-endpoint"
        },
        {
          "kind": "code",
          "literal": "POST /api/ask",
          "chunkId": "api/search-overlay#the-hostable-endpoint"
        },
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "api/search-overlay#the-hostable-endpoint"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#the-hostable-endpoint",
          "url": "/docs/api/search-overlay#the-hostable-endpoint",
          "anchor": "the-hostable-endpoint"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "hostable",
        "endpoint",
        "agentic",
        "answers",
        "without",
        "astro",
        "deploy",
        "bounded",
        "answer",
        "loop",
        "standalone",
        "service",
        "cloudflare",
        "worker",
        "node",
        "server",
        "vercel",
        "function",
        "serves",
        "same",
        "contract",
        "holds",
        "side",
        "reads",
        "committed",
        "tree",
        "once",
        "point",
        "number",
        "sites",
        "overlays",
        "keyword",
        "search",
        "stays",
        "browser",
        "only",
        "needs",
        "anything",
        "deployed",
        "scaffold"
      ]
    },
    {
      "id": "api/search-overlay#the-mode-toggle",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "The mode toggle",
      "group": "API",
      "url": "/docs/api/search-overlay#the-mode-toggle",
      "summary": "The overlay persists an AI-on-Enter preference in localStorage. Readers who flip it to keyword-only never trigger a model call (a space just searches a phrase and no suggestions show), and the choice survives reloads.",
      "hash": "f5b67968083cdfbfa00b247a46ae07a527001d5feb7c83f6ef6b3cd40deac99e",
      "facts": [
        {
          "kind": "code",
          "literal": "localStorage",
          "chunkId": "api/search-overlay#the-mode-toggle"
        },
        {
          "kind": "code",
          "literal": "hev-ask:mode",
          "chunkId": "api/search-overlay#the-mode-toggle"
        },
        {
          "kind": "code",
          "literal": "agentic",
          "chunkId": "api/search-overlay#the-mode-toggle"
        },
        {
          "kind": "code",
          "literal": "keyword",
          "chunkId": "api/search-overlay#the-mode-toggle"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#the-mode-toggle",
          "url": "/docs/api/search-overlay#the-mode-toggle",
          "anchor": "the-mode-toggle"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "mode",
        "toggle",
        "overlay",
        "persists",
        "enter",
        "preference",
        "localstorage",
        "readers",
        "flip",
        "keyword",
        "only",
        "never",
        "trigger",
        "model",
        "call",
        "space",
        "just",
        "searches",
        "phrase",
        "suggestions",
        "show",
        "choice",
        "survives",
        "reloads",
        "agentic",
        "under",
        "suggested",
        "questions",
        "shown"
      ]
    },
    {
      "id": "api/search-overlay#the-overlay-on-other-frameworks",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "The overlay on other frameworks",
      "group": "API",
      "url": "/docs/api/search-overlay#the-overlay-on-other-frameworks",
      "summary": "Beyond the Astro component, the same palette ships as a prebuilt web component that any site loads with one script tag from npm or a CDN. It reads a bundled copy of the digest in the browser so keyword search runs fully static, and a digest attribute points at the bundled assets while an optional endpoint attribute enables the agentic loop with the key staying on the server. It reads the same CSS variables, opener attribute, and keyboard model as the Astro component.",
      "hash": "294cf6be8257ee487de6d9399df7bb94a4a88fbf3c1865008b451588f489d85e",
      "facts": [
        {
          "kind": "code",
          "literal": "<script\n  type=\"module\"\n  src=\"https://cdn.jsdelivr.net/npm/@hevmind/ask/overlay.js\"\n  data-hev-ask-digest=\"/hev-ask/\"\n  data-hev-ask-endpoint=\"https://docs-ask.example.workers.dev/api/ask\"\n></script>\n\n<button data-hev-ask-open>Search <kbd>⌘K</kbd></button>",
          "chunkId": "api/search-overlay#the-overlay-on-other-frameworks"
        },
        {
          "kind": "code",
          "literal": "SearchOverlay.astro",
          "chunkId": "api/search-overlay#the-overlay-on-other-frameworks"
        },
        {
          "kind": "code",
          "literal": "@hevmind/ask/overlay",
          "chunkId": "api/search-overlay#the-overlay-on-other-frameworks"
        },
        {
          "kind": "code",
          "literal": "data-hev-ask-digest",
          "chunkId": "api/search-overlay#the-overlay-on-other-frameworks"
        },
        {
          "kind": "code",
          "literal": "ask digest bundle",
          "chunkId": "api/search-overlay#the-overlay-on-other-frameworks"
        },
        {
          "kind": "code",
          "literal": "data-hev-ask-endpoint",
          "chunkId": "api/search-overlay#the-overlay-on-other-frameworks"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#the-overlay-on-other-frameworks",
          "url": "/docs/api/search-overlay#the-overlay-on-other-frameworks",
          "anchor": "the-overlay-on-other-frameworks"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "overlay",
        "other",
        "frameworks",
        "beyond",
        "astro",
        "component",
        "same",
        "palette",
        "ships",
        "prebuilt",
        "site",
        "loads",
        "script",
        "reads",
        "bundled",
        "copy",
        "digest",
        "browser",
        "keyword",
        "search",
        "runs",
        "fully",
        "static",
        "attribute",
        "points",
        "assets",
        "while",
        "optional",
        "endpoint",
        "enables",
        "agentic",
        "loop",
        "staying",
        "server",
        "variables",
        "opener",
        "keyboard",
        "model",
        "type",
        "module"
      ]
    },
    {
      "id": "api/search-overlay#the-streamed-answer",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "The streamed answer",
      "group": "API",
      "url": "/docs/api/search-overlay#the-streamed-answer",
      "summary": "Pressing Enter with a key configured replaces the keyword rows with an answer panel: the model's sub-queries appear live, then the grounded answer streams in token-by-token, with inline accent-colored deep links to exact headings and a Sources row listing every section it drew from. Links are validated against the streamed source set, so any link to a URL outside that set renders as plain text and a hallucinated anchor can never become a clickable dead link.",
      "hash": "e3cc1c7af28492ceee2772cc484fcc0a30279232d034fc13fcbb6a74e0f7c152",
      "facts": [
        {
          "kind": "code",
          "literal": "searched: …",
          "chunkId": "api/search-overlay#the-streamed-answer"
        },
        {
          "kind": "code",
          "literal": "/docs/page#anchor",
          "chunkId": "api/search-overlay#the-streamed-answer"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#the-streamed-answer",
          "url": "/docs/api/search-overlay#the-streamed-answer",
          "anchor": "the-streamed-answer"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "streamed",
        "answer",
        "pressing",
        "enter",
        "configured",
        "replaces",
        "keyword",
        "rows",
        "panel",
        "model",
        "queries",
        "appear",
        "live",
        "grounded",
        "streams",
        "token",
        "inline",
        "accent",
        "colored",
        "deep",
        "links",
        "exact",
        "headings",
        "sources",
        "listing",
        "every",
        "section",
        "drew",
        "validated",
        "against",
        "source",
        "link",
        "outside",
        "renders",
        "plain",
        "text",
        "hallucinated",
        "anchor",
        "never",
        "become"
      ]
    },
    {
      "id": "api/search-overlay#theming",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "Theming",
      "group": "API",
      "url": "/docs/api/search-overlay#theming",
      "summary": "The overlay reads your page's CSS custom properties for background, text, muted text, and accent, so defining those tokens on the root makes the overlay inherit your palette. Because its scoped styles are keyed to those variables, matching your site's look is usually just defining the tokens with no overlay CSS to override.",
      "hash": "37bbca09a73293fc3a1fe639cabd35a98647bf221c502cc18b4e1a02585df7cf",
      "facts": [
        {
          "kind": "code",
          "literal": ":root {\n  --paper: #111111;       /* overlay background */\n  --ink: #fafaf5;         /* primary text */\n  --muted: #6b6b66;       /* secondary text */\n  --signal: #e25822;      /* accent / active state */\n}",
          "chunkId": "api/search-overlay#theming"
        },
        {
          "kind": "code",
          "literal": "as-",
          "chunkId": "api/search-overlay#theming"
        },
        {
          "kind": "code",
          "literal": ":root",
          "chunkId": "api/search-overlay#theming"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#theming",
          "url": "/docs/api/search-overlay#theming",
          "anchor": "theming"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "theming",
        "overlay",
        "reads",
        "page",
        "custom",
        "properties",
        "background",
        "text",
        "muted",
        "accent",
        "defining",
        "those",
        "tokens",
        "root",
        "makes",
        "inherit",
        "palette",
        "because",
        "scoped",
        "styles",
        "keyed",
        "variables",
        "matching",
        "site",
        "look",
        "usually",
        "just",
        "override",
        "paper",
        "111111",
        "fafaf5",
        "primary",
        "6b6b66",
        "secondary",
        "signal",
        "e25822",
        "active",
        "state",
        "markup",
        "uses"
      ]
    },
    {
      "id": "api/search-overlay#vitepress",
      "kind": "section",
      "title": "SearchOverlay component",
      "heading": "VitePress",
      "group": "API",
      "url": "/docs/api/search-overlay#vitepress",
      "summary": "Shows the VitePress wiring: bundle the assets into the public directory and register the overlay in the theme's enhance step, passing the digest path and an endpoint from an environment variable.",
      "hash": "c5725004205e727e67ddb65cabf811a187df397a10d72e5bb48afc6e9e7712ba",
      "facts": [
        {
          "kind": "code",
          "literal": "// .vitepress/theme/index.ts\nimport DefaultTheme from \"vitepress/theme\";\nimport { mountHevAsk } from \"@hevmind/ask/overlay\";\n\nexport default {\n  extends: DefaultTheme,\n  enhanceApp() {\n    if (typeof window !== \"undefined\") {\n      mountHevAsk({ digest: \"/hev-ask/\", endpoint: import.meta.env.VITE_ASK_ENDPOINT });\n    }\n  },\n};",
          "chunkId": "api/search-overlay#vitepress"
        },
        {
          "kind": "code",
          "literal": ".vitepress/public/",
          "chunkId": "api/search-overlay#vitepress"
        }
      ],
      "sources": [
        {
          "chunkId": "api/search-overlay#vitepress",
          "url": "/docs/api/search-overlay#vitepress",
          "anchor": "vitepress"
        }
      ],
      "mode": "source-primary",
      "terms": [
        "vitepress",
        "shows",
        "wiring",
        "bundle",
        "assets",
        "public",
        "directory",
        "register",
        "overlay",
        "theme",
        "enhance",
        "step",
        "passing",
        "digest",
        "path",
        "endpoint",
        "environment",
        "variable",
        "index",
        "import",
        "defaulttheme",
        "mounthevask",
        "hevmind",
        "export",
        "default",
        "extends",
        "enhanceapp",
        "typeof",
        "window",
        "undefined",
        "meta",
        "vite",
        "viteaskendpoint"
      ]
    },
    {
      "id": "concepts",
      "kind": "section",
      "title": "Concepts",
      "heading": null,
      "group": "Overview",
      "url": "/docs/concepts",
      "summary": "hev ask rests on one idea: the digest is just a directory of distilled markdown, one file per section, read two ways that both climb it progressively — a coding agent navigates it with its own file tools, and a ⌘K overlay reads it server-side to synthesize a grounded answer for a human. The tree is built offline with a strong model and committed to git while the readers run on demand, so no durable state lives in the running site.",
      "hash": "f0a685967c67732cf07a30f2bd53d177317ecfad71a2882f464985695010891d",
      "facts": [
        {
          "kind": "code",
          "literal": "⌘K",
          "chunkId": "concepts"
        },
        {
          "kind": "value",
          "literal": "Diagram.astro",
          "chunkId": "concepts"
        },
        {
          "kind": "value",
          "literal": "Callout.astro",
          "chunkId": "concepts"
        }
      ],
      "sources": [
        {
          "chunkId": "concepts",
          "url": "/docs/concepts",
          "anchor": null
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "rests",
        "idea",
        "digest",
        "just",
        "directory",
        "distilled",
        "markdown",
        "file",
        "section",
        "read",
        "ways",
        "both",
        "climb",
        "progressively",
        "coding",
        "agent",
        "navigates",
        "tools",
        "overlay",
        "reads",
        "server",
        "side",
        "synthesize",
        "grounded",
        "answer",
        "human",
        "tree",
        "built",
        "offline",
        "strong",
        "model",
        "committed",
        "while",
        "readers",
        "demand",
        "durable",
        "state",
        "lives",
        "running",
        "site"
      ]
    },
    {
      "id": "concepts#asking-is-the-default",
      "kind": "section",
      "title": "Concepts",
      "heading": "Asking is the default",
      "group": "Overview",
      "url": "/docs/concepts#asking-is-the-default",
      "summary": "The overlay is ask-first: a single word is answered instantly from the keyword index, and the moment the query grows past one word it switches to ask mode where Enter sends the question to the agentic loop. Suggested questions baked into the digest make asking the obvious move, but a reader can flip the overlay to keyword-only, after which a space just searches a phrase and the model is never called.",
      "hash": "a3f146a134e17963029d99e4fc3bf803f5a03a7159cd15893680d25badbfd52c",
      "facts": [
        {
          "kind": "code",
          "literal": "_meta.md",
          "chunkId": "concepts#asking-is-the-default"
        },
        {
          "kind": "code",
          "literal": "localStorage",
          "chunkId": "concepts#asking-is-the-default"
        }
      ],
      "sources": [
        {
          "chunkId": "concepts#asking-is-the-default",
          "url": "/docs/concepts#asking-is-the-default",
          "anchor": "asking-is-the-default"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "asking",
        "default",
        "overlay",
        "first",
        "single",
        "word",
        "answered",
        "instantly",
        "keyword",
        "index",
        "moment",
        "query",
        "grows",
        "past",
        "switches",
        "mode",
        "enter",
        "sends",
        "question",
        "agentic",
        "loop",
        "suggested",
        "questions",
        "baked",
        "digest",
        "make",
        "obvious",
        "move",
        "reader",
        "flip",
        "only",
        "after",
        "space",
        "just",
        "searches",
        "phrase",
        "model",
        "never",
        "called",
        "meta"
      ]
    },
    {
      "id": "concepts#chunks-and-anchors",
      "kind": "section",
      "title": "Concepts",
      "heading": "Chunks and anchors",
      "group": "Overview",
      "url": "/docs/concepts#chunks-and-anchors",
      "summary": "hev ask indexes sections rather than pages: each document is split on its headings up to a configurable depth, content before the first heading becomes an intro chunk, and each chunk carries a URL built from the base path, slug, and anchor. Anchors are generated with the same slugger the renderer uses so links land on headings that actually exist, each framework adapter declares its slug scheme, and both the offline build and the runtime index chunk through one shared function so anchors agree and the same digest comes out regardless of renderer.",
      "hash": "7114c39ed148b671179972b86fbdceaa60d0146af253d0bf66722359e2522155",
      "facts": [
        {
          "kind": "code",
          "literal": "##",
          "chunkId": "concepts#chunks-and-anchors"
        },
        {
          "kind": "code",
          "literal": "###",
          "chunkId": "concepts#chunks-and-anchors"
        },
        {
          "kind": "code",
          "literal": "basePath + slug + #anchor",
          "chunkId": "concepts#chunks-and-anchors"
        },
        {
          "kind": "code",
          "literal": "github-slugger",
          "chunkId": "concepts#chunks-and-anchors"
        },
        {
          "kind": "code",
          "literal": "{#custom-id}",
          "chunkId": "concepts#chunks-and-anchors"
        },
        {
          "kind": "code",
          "literal": "getCollection",
          "chunkId": "concepts#chunks-and-anchors"
        },
        {
          "kind": "value",
          "literal": "github.com",
          "chunkId": "concepts#chunks-and-anchors"
        }
      ],
      "sources": [
        {
          "chunkId": "concepts#chunks-and-anchors",
          "url": "/docs/concepts#chunks-and-anchors",
          "anchor": "chunks-and-anchors"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "chunks",
        "anchors",
        "indexes",
        "sections",
        "rather",
        "pages",
        "document",
        "split",
        "headings",
        "configurable",
        "depth",
        "content",
        "before",
        "first",
        "heading",
        "becomes",
        "intro",
        "chunk",
        "carries",
        "built",
        "base",
        "path",
        "slug",
        "anchor",
        "generated",
        "same",
        "slugger",
        "renderer",
        "uses",
        "links",
        "land",
        "actually",
        "exist",
        "framework",
        "adapter",
        "declares",
        "scheme",
        "both",
        "offline",
        "build"
      ]
    },
    {
      "id": "concepts#degradation-by-design",
      "kind": "section",
      "title": "Concepts",
      "heading": "Degradation, by design",
      "group": "Overview",
      "url": "/docs/concepts#degradation-by-design",
      "summary": "hev ask keeps working as pieces drop away: no key at runtime leaves keyword mode, no key at build keeps the committed tree with a warning, no digest tree falls back to keyword-style retrieval and raw token-overlap ranking with no suggestions, and a stale tree logs a one-line warning but still serves. Everything still works, and the page points to Limits and Tradeoffs for boundaries and choices.",
      "hash": "94c92585e092fcc000511ebc5e7640ac04f1bfd70029f77bd3aea3959affb6e0",
      "facts": [
        {
          "kind": "code",
          "literal": ".hev-ask/",
          "chunkId": "concepts#degradation-by-design"
        },
        {
          "kind": "code",
          "literal": "_meta.md",
          "chunkId": "concepts#degradation-by-design"
        }
      ],
      "sources": [
        {
          "chunkId": "concepts#degradation-by-design",
          "url": "/docs/concepts#degradation-by-design",
          "anchor": "degradation-by-design"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "degradation",
        "design",
        "keeps",
        "working",
        "pieces",
        "drop",
        "away",
        "runtime",
        "leaves",
        "keyword",
        "mode",
        "build",
        "committed",
        "tree",
        "warning",
        "digest",
        "falls",
        "back",
        "style",
        "retrieval",
        "token",
        "overlap",
        "ranking",
        "suggestions",
        "stale",
        "logs",
        "line",
        "still",
        "serves",
        "everything",
        "works",
        "page",
        "points",
        "limits",
        "tradeoffs",
        "boundaries",
        "choices",
        "meta",
        "built",
        "keep"
      ]
    },
    {
      "id": "concepts#host-neutral-one-digest-any-framework",
      "kind": "section",
      "title": "Concepts",
      "heading": "Host-neutral: one digest, any framework",
      "group": "Overview",
      "url": "/docs/concepts#host-neutral-one-digest-any-framework",
      "summary": "The build reads markdown off disk, chunks on headings, derives anchors in code, and writes the tree without importing any framework, so the digest is the same artifact whether Astro, Docusaurus, VitePress, or MkDocs renders the pages; only the adapter differs. Astro is the batteries-included flagship, while every other framework uses two host-neutral primitives — the fully static drop-in overlay for the keyword path and the standalone hostable endpoint for the agentic path — and the CLI and MCP surfaces are already host-neutral because they read the committed tree directly.",
      "hash": "b670f196f7770314128233d4a8ce13b0b168f901639a3697bcaf9c119bc1a17a",
      "facts": [
        {
          "kind": "code",
          "literal": ".hev-ask/",
          "chunkId": "concepts#host-neutral-one-digest-any-framework"
        },
        {
          "kind": "code",
          "literal": "hevAsk()",
          "chunkId": "concepts#host-neutral-one-digest-any-framework"
        },
        {
          "kind": "code",
          "literal": "astro build",
          "chunkId": "concepts#host-neutral-one-digest-any-framework"
        },
        {
          "kind": "code",
          "literal": "/api/ask",
          "chunkId": "concepts#host-neutral-one-digest-any-framework"
        },
        {
          "kind": "code",
          "literal": "SearchOverlay.astro",
          "chunkId": "concepts#host-neutral-one-digest-any-framework"
        },
        {
          "kind": "code",
          "literal": "<script>",
          "chunkId": "concepts#host-neutral-one-digest-any-framework"
        },
        {
          "kind": "code",
          "literal": "tree",
          "chunkId": "concepts#host-neutral-one-digest-any-framework"
        },
        {
          "kind": "code",
          "literal": "cat",
          "chunkId": "concepts#host-neutral-one-digest-any-framework"
        },
        {
          "kind": "code",
          "literal": "grep",
          "chunkId": "concepts#host-neutral-one-digest-any-framework"
        }
      ],
      "sources": [
        {
          "chunkId": "concepts#host-neutral-one-digest-any-framework",
          "url": "/docs/concepts#host-neutral-one-digest-any-framework",
          "anchor": "host-neutral-one-digest-any-framework"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "host",
        "neutral",
        "digest",
        "framework",
        "build",
        "reads",
        "markdown",
        "disk",
        "chunks",
        "headings",
        "derives",
        "anchors",
        "code",
        "writes",
        "tree",
        "without",
        "importing",
        "same",
        "artifact",
        "whether",
        "astro",
        "docusaurus",
        "vitepress",
        "mkdocs",
        "renders",
        "pages",
        "only",
        "adapter",
        "differs",
        "batteries",
        "included",
        "flagship",
        "while",
        "every",
        "other",
        "uses",
        "primitives",
        "fully",
        "static",
        "drop"
      ]
    },
    {
      "id": "concepts#keyword-search-and-the-glossary",
      "kind": "section",
      "title": "Concepts",
      "heading": "Keyword search and the glossary",
      "group": "Overview",
      "url": "/docs/concepts#keyword-search-and-the-glossary",
      "summary": "The instant keyword path runs a dependency-free prefilter over the chunks: it expands each query term with its glossary aliases and matched-term tokens, scores by token overlap widened by the digest so matches against a section's summary, terms, and facts lift it above incidental body mentions, caps results per document so one long page can't dominate, then excerpts around the first match for the snippet. It needs no key and no embeddings, and with no tree it degrades to plain token overlap so keyword search always works.",
      "hash": "6496e6a2896ae22bcdf61b3dbba97df885d89427d2f4b266e7553f09e094cb91",
      "facts": [
        {
          "kind": "code",
          "literal": "grep",
          "chunkId": "concepts#keyword-search-and-the-glossary"
        },
        {
          "kind": "code",
          "literal": "k8s",
          "chunkId": "concepts#keyword-search-and-the-glossary"
        },
        {
          "kind": "code",
          "literal": "kubernetes",
          "chunkId": "concepts#keyword-search-and-the-glossary"
        },
        {
          "kind": "code",
          "literal": "summary",
          "chunkId": "concepts#keyword-search-and-the-glossary"
        },
        {
          "kind": "code",
          "literal": "terms",
          "chunkId": "concepts#keyword-search-and-the-glossary"
        },
        {
          "kind": "code",
          "literal": "facts",
          "chunkId": "concepts#keyword-search-and-the-glossary"
        }
      ],
      "sources": [
        {
          "chunkId": "concepts#keyword-search-and-the-glossary",
          "url": "/docs/concepts#keyword-search-and-the-glossary",
          "anchor": "keyword-search-and-the-glossary"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "keyword",
        "search",
        "glossary",
        "instant",
        "path",
        "runs",
        "dependency",
        "free",
        "prefilter",
        "chunks",
        "expands",
        "query",
        "term",
        "aliases",
        "matched",
        "tokens",
        "scores",
        "token",
        "overlap",
        "widened",
        "digest",
        "matches",
        "against",
        "section",
        "summary",
        "terms",
        "facts",
        "lift",
        "above",
        "incidental",
        "body",
        "mentions",
        "caps",
        "results",
        "document",
        "long",
        "page",
        "dominate",
        "excerpts",
        "around"
      ]
    },
    {
      "id": "concepts#progressive-disclosure-as-a-directory",
      "kind": "section",
      "title": "Concepts",
      "heading": "Progressive disclosure as a directory",
      "group": "Overview",
      "url": "/docs/concepts#progressive-disclosure-as-a-directory",
      "summary": "Because the digest is a real directory, progressive disclosure is just the directory's own cost model, and the reads form a disclosure ladder where each rung is a strictly larger slice of one section file. A listing reads frontmatter only so it can never leak a body and is bounded by the number of sections rather than the size of the docs, making it safe to call speculatively, and every deeper rung is an explicit verb so nothing larger than a title is ever returned by surprise; an agent climbs it with its own file tools while the CLI offers one verb per operation for keyless and remote cases.",
      "hash": "232cb8862518efe7f81d2a8c80e7c97bd5bee0bfd5609ce4d59d381d5ad148f8",
      "facts": [
        {
          "kind": "code",
          "literal": "cat",
          "chunkId": "concepts#progressive-disclosure-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "tree",
          "chunkId": "concepts#progressive-disclosure-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "facts",
          "chunkId": "concepts#progressive-disclosure-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "grep",
          "chunkId": "concepts#progressive-disclosure-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "ls",
          "chunkId": "concepts#progressive-disclosure-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "head",
          "chunkId": "concepts#progressive-disclosure-as-a-directory"
        },
        {
          "kind": "code",
          "literal": "ask",
          "chunkId": "concepts#progressive-disclosure-as-a-directory"
        }
      ],
      "sources": [
        {
          "chunkId": "concepts#progressive-disclosure-as-a-directory",
          "url": "/docs/concepts#progressive-disclosure-as-a-directory",
          "anchor": "progressive-disclosure-as-a-directory"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "progressive",
        "disclosure",
        "directory",
        "because",
        "digest",
        "real",
        "just",
        "cost",
        "model",
        "reads",
        "form",
        "ladder",
        "rung",
        "strictly",
        "larger",
        "slice",
        "section",
        "file",
        "listing",
        "frontmatter",
        "only",
        "never",
        "leak",
        "body",
        "bounded",
        "number",
        "sections",
        "rather",
        "size",
        "docs",
        "making",
        "safe",
        "call",
        "speculatively",
        "every",
        "deeper",
        "explicit",
        "verb",
        "nothing",
        "title"
      ]
    },
    {
      "id": "concepts#the-agentic-search-loop",
      "kind": "section",
      "title": "Concepts",
      "heading": "The agentic search loop",
      "group": "Overview",
      "url": "/docs/concepts#the-agentic-search-loop",
      "summary": "The overlay answers humans by doing the synthesis an agent would do itself, sending a multi-word query to a bounded tool-use loop in two phases. In the gather phase the model is given the title-tree of every section plus one tool to open a section's summary, facts, and (for reference sections) source text, opening only what it needs up to the iteration cap and citing only what it opened; in the answer phase the accumulated sources are sent to the overlay for link validation and the model is called once more with no tools so it can only write prose, streamed token-by-token. Dropping the tools on the final turn guarantees it answers rather than searching again, and it can only ground in and link to the sections retrieval returned.",
      "hash": "2f6dfa7319e162069240585c70a19b0d2727aa413c0bddd5dd0644f360619892",
      "facts": [
        {
          "kind": "code",
          "literal": "open_section({ id })",
          "chunkId": "concepts#the-agentic-search-loop"
        },
        {
          "kind": "code",
          "literal": "facts",
          "chunkId": "concepts#the-agentic-search-loop"
        },
        {
          "kind": "code",
          "literal": "maxIterations",
          "chunkId": "concepts#the-agentic-search-loop"
        },
        {
          "kind": "code",
          "literal": "url",
          "chunkId": "concepts#the-agentic-search-loop"
        }
      ],
      "sources": [
        {
          "chunkId": "concepts#the-agentic-search-loop",
          "url": "/docs/concepts#the-agentic-search-loop",
          "anchor": "the-agentic-search-loop"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "agentic",
        "search",
        "loop",
        "overlay",
        "answers",
        "humans",
        "doing",
        "synthesis",
        "agent",
        "would",
        "itself",
        "sending",
        "multi",
        "word",
        "query",
        "bounded",
        "tool",
        "phases",
        "gather",
        "phase",
        "model",
        "given",
        "title",
        "tree",
        "every",
        "section",
        "plus",
        "open",
        "summary",
        "facts",
        "reference",
        "sections",
        "source",
        "text",
        "opening",
        "only",
        "needs",
        "iteration",
        "citing",
        "opened"
      ]
    },
    {
      "id": "concepts#the-ask-digest-directory",
      "kind": "section",
      "title": "Concepts",
      "heading": "The ask digest directory",
      "group": "Overview",
      "url": "/docs/concepts#the-ask-digest-directory",
      "summary": "The build distills each section into a small markdown-plus-frontmatter file and writes the whole tree mirroring the doc paths, where the body is the distilled prose and the frontmatter carries the citation link, verbatim facts, sources, ranking terms, and the content hash, alongside the per-term glossary and the meta entry. There is no committed JSON, and because a listing returns only titles, page-level titles come from the collection while sub-section titles are synthesized into descriptive one-liners, since the title is the only thing a reader sees before opening a file.",
      "hash": "d9602cd4160894a54ec544b98098991a34a8f6349b3394b4b5eb3b7299eed10d",
      "facts": [
        {
          "kind": "code",
          "literal": ".hev-ask/",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "overview/",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "api/",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "title",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "url",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "anchor",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "facts",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "sources",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "terms",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "hash",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "_glossary/",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "_meta.md",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "context",
          "chunkId": "concepts#the-ask-digest-directory"
        },
        {
          "kind": "code",
          "literal": "heading",
          "chunkId": "concepts#the-ask-digest-directory"
        }
      ],
      "sources": [
        {
          "chunkId": "concepts#the-ask-digest-directory",
          "url": "/docs/concepts#the-ask-digest-directory",
          "anchor": "the-ask-digest-directory"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "digest",
        "directory",
        "build",
        "distills",
        "section",
        "small",
        "markdown",
        "plus",
        "frontmatter",
        "file",
        "writes",
        "whole",
        "tree",
        "mirroring",
        "paths",
        "body",
        "distilled",
        "prose",
        "carries",
        "citation",
        "link",
        "verbatim",
        "facts",
        "sources",
        "ranking",
        "terms",
        "content",
        "hash",
        "alongside",
        "term",
        "glossary",
        "meta",
        "entry",
        "there",
        "committed",
        "json",
        "because",
        "listing",
        "returns",
        "only"
      ]
    },
    {
      "id": "concepts#the-system-prompt-is-cached",
      "kind": "section",
      "title": "Concepts",
      "heading": "The system prompt is cached",
      "group": "Overview",
      "url": "/docs/concepts#the-system-prompt-is-cached",
      "summary": "The title-tree and section summaries are injected into the system prompt with a cache marker, so across the search rounds it is a prompt-cache hit rather than re-sent tokens; the final answer turn changes the tool set and so cannot reuse that cache, but it is the last call anyway. The loop model defaults to a small model and is configurable, and the page warns not to confuse the reader's server-side synthesis loop with a consumer's own coding agent that navigates the files itself, though both climb the same ladder.",
      "hash": "740d6a77b01eeb8a97450a731c865c453c8e7aac42a1971856ecacdf05622c39",
      "facts": [
        {
          "kind": "code",
          "literal": "cache_control",
          "chunkId": "concepts#the-system-prompt-is-cached"
        },
        {
          "kind": "value",
          "literal": "4.5",
          "chunkId": "concepts#the-system-prompt-is-cached"
        }
      ],
      "sources": [
        {
          "chunkId": "concepts#the-system-prompt-is-cached",
          "url": "/docs/concepts#the-system-prompt-is-cached",
          "anchor": "the-system-prompt-is-cached"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "system",
        "prompt",
        "cached",
        "title",
        "tree",
        "section",
        "summaries",
        "injected",
        "cache",
        "marker",
        "across",
        "search",
        "rounds",
        "rather",
        "sent",
        "tokens",
        "final",
        "answer",
        "turn",
        "changes",
        "tool",
        "cannot",
        "reuse",
        "last",
        "call",
        "anyway",
        "loop",
        "model",
        "defaults",
        "small",
        "configurable",
        "page",
        "warns",
        "confuse",
        "reader",
        "server",
        "side",
        "synthesis",
        "consumer",
        "coding"
      ]
    },
    {
      "id": "concepts#two-ways-to-build-the-tree",
      "kind": "section",
      "title": "Concepts",
      "heading": "Two ways to build the tree",
      "group": "Overview",
      "url": "/docs/concepts#two-ways-to-build-the-tree",
      "summary": "Only the section summary, glossary, orientation context, and suggestions are model-authored; the tree structure, verbatim facts, overview, per-section hashes, and anchors are derived deterministically in code, so the model only supplies the distillation. That distillation can run in a Claude Code skill inside an existing subscription with no key and no per-build token spend (the recommended path), or unattended through the one-call CLI build for CI; either way the build is incremental and hash-gated and the tree is reviewed in pull requests.",
      "hash": "ea8c9b547ad83de8bac44812d869f94180b8ff660c5fb30cba7a6662d1e77a14",
      "facts": [
        {
          "kind": "code",
          "literal": "summary",
          "chunkId": "concepts#two-ways-to-build-the-tree"
        },
        {
          "kind": "code",
          "literal": "context",
          "chunkId": "concepts#two-ways-to-build-the-tree"
        },
        {
          "kind": "code",
          "literal": "suggestions",
          "chunkId": "concepts#two-ways-to-build-the-tree"
        },
        {
          "kind": "code",
          "literal": "facts",
          "chunkId": "concepts#two-ways-to-build-the-tree"
        },
        {
          "kind": "code",
          "literal": ".hev-ask/",
          "chunkId": "concepts#two-ways-to-build-the-tree"
        },
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "concepts#two-ways-to-build-the-tree"
        },
        {
          "kind": "code",
          "literal": "ask digest build",
          "chunkId": "concepts#two-ways-to-build-the-tree"
        },
        {
          "kind": "value",
          "literal": "4.8",
          "chunkId": "concepts#two-ways-to-build-the-tree"
        }
      ],
      "sources": [
        {
          "chunkId": "concepts#two-ways-to-build-the-tree",
          "url": "/docs/concepts#two-ways-to-build-the-tree",
          "anchor": "two-ways-to-build-the-tree"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "ways",
        "build",
        "tree",
        "only",
        "section",
        "summary",
        "glossary",
        "orientation",
        "context",
        "suggestions",
        "model",
        "authored",
        "structure",
        "verbatim",
        "facts",
        "overview",
        "hashes",
        "anchors",
        "derived",
        "deterministically",
        "code",
        "supplies",
        "distillation",
        "claude",
        "skill",
        "inside",
        "existing",
        "subscription",
        "token",
        "spend",
        "recommended",
        "path",
        "unattended",
        "through",
        "call",
        "either",
        "incremental",
        "hash",
        "gated",
        "reviewed"
      ]
    },
    {
      "id": "digest-creation",
      "kind": "section",
      "title": "Digest creation",
      "heading": null,
      "group": "Overview",
      "url": "/docs/digest-creation",
      "summary": "The ask digest is created offline and committed to the repo like any other source file: a build reads markdown off the filesystem, distills each section into a small markdown file, and writes the tree. The running site, CLI, and MCP server all read that committed artifact and never call a model to serve it.",
      "hash": "ab2a11a79292291f51f62b5d2f5ec903af81ac9609ecb10ec4d71d9ad66f3f71",
      "facts": [
        {
          "kind": "code",
          "literal": ".hev-ask/",
          "chunkId": "digest-creation"
        },
        {
          "kind": "value",
          "literal": "Callout.astro",
          "chunkId": "digest-creation"
        },
        {
          "kind": "value",
          "literal": "CodeTabs.astro",
          "chunkId": "digest-creation"
        }
      ],
      "sources": [
        {
          "chunkId": "digest-creation",
          "url": "/docs/digest-creation",
          "anchor": null
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "digest",
        "created",
        "offline",
        "committed",
        "repo",
        "like",
        "other",
        "source",
        "file",
        "build",
        "reads",
        "markdown",
        "filesystem",
        "distills",
        "section",
        "small",
        "writes",
        "tree",
        "running",
        "site",
        "server",
        "read",
        "artifact",
        "never",
        "call",
        "model",
        "serve",
        "callout",
        "astro",
        "codetabs",
        "built",
        "distillation",
        "through",
        "claude",
        "code",
        "skill",
        "gated",
        "hashes",
        "verified",
        "distils"
      ]
    },
    {
      "id": "digest-creation#built-from-markdown-not-from-a-renderer",
      "kind": "section",
      "title": "Digest creation",
      "heading": "Built from markdown, not from a renderer",
      "group": "Overview",
      "url": "/docs/digest-creation#built-from-markdown-not-from-a-renderer",
      "summary": "The build never imports your framework; it reads files, chunks on headings, derives anchors in code, and writes the tree, so the same artifact comes out whether Astro, Docusaurus, VitePress, MkDocs, or nothing renders the pages. What differs per host is only when the build runs — during the Astro build when a key is present, and a build or CI step everywhere else — while wiring the overlay into a non-Astro site is a separate, smaller job.",
      "hash": "473b58f15073f724b5961c7a62a2f9f09cabd49ec8b8e42e7d692e7ae6ec4461",
      "facts": [
        {
          "kind": "code",
          "literal": "astro build",
          "chunkId": "digest-creation#built-from-markdown-not-from-a-renderer"
        }
      ],
      "sources": [
        {
          "chunkId": "digest-creation#built-from-markdown-not-from-a-renderer",
          "url": "/docs/digest-creation#built-from-markdown-not-from-a-renderer",
          "anchor": "built-from-markdown-not-from-a-renderer"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "built",
        "markdown",
        "renderer",
        "build",
        "never",
        "imports",
        "framework",
        "reads",
        "files",
        "chunks",
        "headings",
        "derives",
        "anchors",
        "code",
        "writes",
        "tree",
        "same",
        "artifact",
        "comes",
        "whether",
        "astro",
        "docusaurus",
        "vitepress",
        "mkdocs",
        "nothing",
        "renders",
        "pages",
        "differs",
        "host",
        "only",
        "runs",
        "during",
        "present",
        "step",
        "everywhere",
        "else",
        "while",
        "wiring",
        "overlay",
        "site"
      ]
    },
    {
      "id": "digest-creation#incremental-by-hash",
      "kind": "section",
      "title": "Digest creation",
      "heading": "Incremental by hash",
      "group": "Overview",
      "url": "/docs/digest-creation#incremental-by-hash",
      "summary": "Every section file records the hash of the content it was distilled from, so a rebuild re-distills only the sections whose hash changed and a clean tree does no model work at all. That makes rebuilding on every content change cheap enough to be the intended workflow rather than a chore.",
      "hash": "55d38a351a62131967527fca13fca8ad624324075d63337614941148ce9174f1",
      "facts": [],
      "sources": [
        {
          "chunkId": "digest-creation#incremental-by-hash",
          "url": "/docs/digest-creation#incremental-by-hash",
          "anchor": "incremental-by-hash"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "incremental",
        "hash",
        "every",
        "section",
        "file",
        "records",
        "content",
        "distilled",
        "rebuild",
        "distills",
        "only",
        "sections",
        "whose",
        "changed",
        "clean",
        "tree",
        "does",
        "model",
        "work",
        "makes",
        "rebuilding",
        "change",
        "cheap",
        "enough",
        "intended",
        "workflow",
        "rather",
        "chore",
        "distils"
      ]
    },
    {
      "id": "digest-creation#two-ways-to-run-the-build",
      "kind": "section",
      "title": "Digest creation",
      "heading": "Two ways to run the build",
      "group": "Overview",
      "url": "/docs/digest-creation#two-ways-to-run-the-build",
      "summary": "The build runs two ways that write the same tree under the same hash gate: the recommended bundled Claude Code skill builds inside your subscription with no key and no token spend, sharding the corpus and distilling each shard in a fresh context so size never hits a context limit; and the CLI build does the same distillation unattended in one API call for CI or outside Claude Code, on the default provider or any provider via a flag. The full command set, flags, and sharded flow are in the CLI reference.",
      "hash": "cc8ff5c21b0b7eeda4b14b44b4f1df1a979bf029b005e2bf8c24d334fe803413",
      "facts": [
        {
          "kind": "code",
          "literal": "You: build the hev ask digest\n\nClaude runs:\n  ask digest corpus       # emits the sections to distil\n  …writes context/glossary/summaries/suggestions…\n  ask digest assemble     # writes the .hev-ask/ tree",
          "chunkId": "digest-creation#two-ways-to-run-the-build"
        },
        {
          "kind": "code",
          "literal": "export ANTHROPIC_API_KEY=sk-ant-...\npnpm exec ask digest build",
          "chunkId": "digest-creation#two-ways-to-run-the-build"
        },
        {
          "kind": "code",
          "literal": "export OPENAI_API_KEY=sk-...\npnpm exec ask digest build --provider openai",
          "chunkId": "digest-creation#two-ways-to-run-the-build"
        },
        {
          "kind": "code",
          "literal": "export OPENROUTER_API_KEY=sk-or-...\npnpm exec ask digest build --provider openrouter",
          "chunkId": "digest-creation#two-ways-to-run-the-build"
        },
        {
          "kind": "code",
          "literal": "build-digest",
          "chunkId": "digest-creation#two-ways-to-run-the-build"
        },
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "digest-creation#two-ways-to-run-the-build"
        },
        {
          "kind": "code",
          "literal": "--provider",
          "chunkId": "digest-creation#two-ways-to-run-the-build"
        },
        {
          "kind": "value",
          "literal": "4.8",
          "chunkId": "digest-creation#two-ways-to-run-the-build"
        }
      ],
      "sources": [
        {
          "chunkId": "digest-creation#two-ways-to-run-the-build",
          "url": "/docs/digest-creation#two-ways-to-run-the-build",
          "anchor": "two-ways-to-run-the-build"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "ways",
        "build",
        "runs",
        "write",
        "same",
        "tree",
        "under",
        "hash",
        "gate",
        "recommended",
        "bundled",
        "claude",
        "code",
        "skill",
        "builds",
        "inside",
        "subscription",
        "token",
        "spend",
        "sharding",
        "corpus",
        "distilling",
        "shard",
        "fresh",
        "context",
        "size",
        "never",
        "hits",
        "limit",
        "does",
        "distillation",
        "unattended",
        "call",
        "outside",
        "default",
        "provider",
        "flag",
        "full",
        "command",
        "flags"
      ]
    },
    {
      "id": "digest-creation#verify-review-commit",
      "kind": "section",
      "title": "Digest creation",
      "heading": "Verify, review, commit",
      "group": "Overview",
      "url": "/docs/digest-creation#verify-review-commit",
      "summary": "The verify command is the CI gate: it builds the site, fails when any section's anchor is missing from the rendered HTML, and warns on coverage or fidelity drift, after which you commit the tree. Because the tree is markdown, a section's distilled prose and grounded facts change together in one reviewable diff and are reviewed in pull requests; the digest regenerates only when content changes and a build runs, with the runtime logging a warning on hash mismatch as a rebuild cue while a stale digest degrades rather than breaks.",
      "hash": "3e04fbcdb9c42dcd79f213c0ffc5ff67e8eba56d67c1e18de255ae88432e8c8a",
      "facts": [
        {
          "kind": "code",
          "literal": "pnpm exec ask digest verify     # builds the site, checks every anchor resolves\ngit add .hev-ask",
          "chunkId": "digest-creation#verify-review-commit"
        },
        {
          "kind": "code",
          "literal": "ask digest verify",
          "chunkId": "digest-creation#verify-review-commit"
        }
      ],
      "sources": [
        {
          "chunkId": "digest-creation#verify-review-commit",
          "url": "/docs/digest-creation#verify-review-commit",
          "anchor": "verify-review-commit"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "verify",
        "review",
        "commit",
        "command",
        "gate",
        "builds",
        "site",
        "fails",
        "section",
        "anchor",
        "missing",
        "rendered",
        "html",
        "warns",
        "coverage",
        "fidelity",
        "drift",
        "after",
        "tree",
        "because",
        "markdown",
        "distilled",
        "prose",
        "grounded",
        "facts",
        "change",
        "together",
        "reviewable",
        "diff",
        "reviewed",
        "pull",
        "requests",
        "digest",
        "regenerates",
        "only",
        "content",
        "changes",
        "build",
        "runs",
        "runtime"
      ]
    },
    {
      "id": "digest-creation#what-the-model-writes",
      "kind": "section",
      "title": "Digest creation",
      "heading": "What the model writes",
      "group": "Overview",
      "url": "/docs/digest-creation#what-the-model-writes",
      "summary": "Only the distillation is model-authored — each section's summary, the glossary, the orientation context, and the suggested questions — while the structure, verbatim facts, overview, anchors, and per-section hashes are derived deterministically in code. That seam is what lets the model step run anywhere a model is available, including inside your editor.",
      "hash": "bc56e588e06df49a56847fc7db807331fdb4e9d43d51ed574f7bbb540d36c1da",
      "facts": [],
      "sources": [
        {
          "chunkId": "digest-creation#what-the-model-writes",
          "url": "/docs/digest-creation#what-the-model-writes",
          "anchor": "what-the-model-writes"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "model",
        "writes",
        "only",
        "distillation",
        "authored",
        "section",
        "summary",
        "glossary",
        "orientation",
        "context",
        "suggested",
        "questions",
        "while",
        "structure",
        "verbatim",
        "facts",
        "overview",
        "anchors",
        "hashes",
        "derived",
        "deterministically",
        "code",
        "seam",
        "lets",
        "step",
        "anywhere",
        "available",
        "including",
        "inside",
        "editor",
        "everything",
        "else",
        "tree"
      ]
    },
    {
      "id": "index",
      "kind": "section",
      "title": "Introduction",
      "heading": null,
      "group": "Overview",
      "url": "/docs",
      "summary": "hev ask distills a docs site into an ask digest, a compact directory with one small markdown file per section that an agent navigates like any directory and a ⌘K overlay answers readers from. The digest is host-neutral because it is built from your markdown rather than your renderer, works with Astro, Docusaurus, VitePress, MkDocs, or any folder of markdown, ships a turnkey Astro integration with a one-script add for other frameworks, and is built offline and committed so the docs become readable three ways from one artifact; it suits technical documentation, internal wikis, and other medium-sized corpora.",
      "hash": "5a94ae0b351ff3ceebfccf626431a5b0d5420c9f81c900ff454f69e5b3646c92",
      "facts": [
        {
          "kind": "code",
          "literal": "⌘K",
          "chunkId": "index"
        },
        {
          "kind": "value",
          "literal": "Diagram.astro",
          "chunkId": "index"
        },
        {
          "kind": "value",
          "literal": "Callout.astro",
          "chunkId": "index"
        },
        {
          "kind": "value",
          "literal": "astro.build",
          "chunkId": "index"
        }
      ],
      "sources": [
        {
          "chunkId": "index",
          "url": "/docs",
          "anchor": null
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "distills",
        "docs",
        "site",
        "digest",
        "compact",
        "directory",
        "small",
        "markdown",
        "file",
        "section",
        "agent",
        "navigates",
        "like",
        "overlay",
        "answers",
        "readers",
        "host",
        "neutral",
        "because",
        "built",
        "rather",
        "renderer",
        "works",
        "astro",
        "docusaurus",
        "vitepress",
        "mkdocs",
        "folder",
        "ships",
        "turnkey",
        "integration",
        "script",
        "other",
        "frameworks",
        "offline",
        "committed",
        "become",
        "readable",
        "three",
        "ways"
      ]
    },
    {
      "id": "index#next-steps",
      "kind": "section",
      "title": "Introduction",
      "heading": "Next steps",
      "group": "Overview",
      "url": "/docs#next-steps",
      "summary": "A pointer list to the next pages: Quick start, Digest creation, Concepts, Tradeoffs and Limits, the CLI, and the API reference.",
      "hash": "292d13fd4cc150850f930dbe0b306b79ccebb4ecad52afd02797d107a94aaf57",
      "facts": [
        {
          "kind": "code",
          "literal": "ask",
          "chunkId": "index#next-steps"
        },
        {
          "kind": "code",
          "literal": "tree",
          "chunkId": "index#next-steps"
        },
        {
          "kind": "code",
          "literal": "cat",
          "chunkId": "index#next-steps"
        },
        {
          "kind": "code",
          "literal": "grep",
          "chunkId": "index#next-steps"
        }
      ],
      "sources": [
        {
          "chunkId": "index#next-steps",
          "url": "/docs#next-steps",
          "anchor": "next-steps"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "next",
        "steps",
        "pointer",
        "list",
        "pages",
        "quick",
        "start",
        "digest",
        "creation",
        "concepts",
        "tradeoffs",
        "limits",
        "reference",
        "tree",
        "grep",
        "search",
        "astro",
        "site",
        "five",
        "minutes",
        "built",
        "kept",
        "fresh",
        "verified",
        "chunks",
        "anchors",
        "disclosure",
        "ladder",
        "agentic",
        "loop",
        "directory",
        "choosing",
        "deliberately",
        "doesn",
        "browse",
        "every",
        "option",
        "component",
        "props",
        "endpoint"
      ]
    },
    {
      "id": "index#one-artifact-three-readers",
      "kind": "section",
      "title": "Introduction",
      "heading": "One artifact, three readers",
      "group": "Overview",
      "url": "/docs#one-artifact-three-readers",
      "summary": "The digest is built inside your coding agent with the bundled skill using an existing subscription, with no key and no per-build token spend, and once committed the same files serve three readers: the ⌘K overlay for humans with instant keyword results plus a grounded answer on Enter and deep links; the CLI for agents to map, read, pull facts, and search over path keys keylessly from any shell; and the MCP server for agents, whose one tool hydrates the whole tree to disk for the agent's own file tools. hev ask only reads the content you point it at, with no crawler, no external index, and nothing to keep in sync, and the committed tree is reviewable per section in every pull request.",
      "hash": "39a7eba44c79ba2276e1c001e1707b90708d914ab8d2d455fff33286c94b8e02",
      "facts": [
        {
          "kind": "code",
          "literal": ".hev-ask/",
          "chunkId": "index#one-artifact-three-readers"
        },
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "index#one-artifact-three-readers"
        },
        {
          "kind": "code",
          "literal": "⌘K",
          "chunkId": "index#one-artifact-three-readers"
        },
        {
          "kind": "code",
          "literal": "ask",
          "chunkId": "index#one-artifact-three-readers"
        },
        {
          "kind": "code",
          "literal": "tree",
          "chunkId": "index#one-artifact-three-readers"
        },
        {
          "kind": "code",
          "literal": "cat",
          "chunkId": "index#one-artifact-three-readers"
        },
        {
          "kind": "code",
          "literal": "facts",
          "chunkId": "index#one-artifact-three-readers"
        },
        {
          "kind": "code",
          "literal": "grep",
          "chunkId": "index#one-artifact-three-readers"
        },
        {
          "kind": "code",
          "literal": "ask mcp",
          "chunkId": "index#one-artifact-three-readers"
        },
        {
          "kind": "code",
          "literal": "docs/",
          "chunkId": "index#one-artifact-three-readers"
        }
      ],
      "sources": [
        {
          "chunkId": "index#one-artifact-three-readers",
          "url": "/docs#one-artifact-three-readers",
          "anchor": "one-artifact-three-readers"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "artifact",
        "three",
        "readers",
        "digest",
        "built",
        "inside",
        "coding",
        "agent",
        "bundled",
        "skill",
        "existing",
        "subscription",
        "build",
        "token",
        "spend",
        "once",
        "committed",
        "same",
        "files",
        "serve",
        "overlay",
        "humans",
        "instant",
        "keyword",
        "results",
        "plus",
        "grounded",
        "answer",
        "enter",
        "deep",
        "links",
        "agents",
        "read",
        "pull",
        "facts",
        "search",
        "path",
        "keys",
        "keylessly",
        "shell"
      ]
    },
    {
      "id": "index#who-this-is-for",
      "kind": "section",
      "title": "Introduction",
      "heading": "Who this is for",
      "group": "Overview",
      "url": "/docs#who-this-is-for",
      "summary": "hev ask suits anyone building a docs site whose content is Markdown or MDX on Astro, Docusaurus, VitePress, MkDocs, or any folder of markdown, who wants search that works without standing up a service or crawler, deep-links to the right section, answers questions in the reader's own words, and is queryable by a coding agent. On Astro one integration covers all of that; other frameworks drop in the static overlay and optionally point it at a hosted endpoint for answers. If you only need keyword search over a static site and never want a key in the loop, Pagefind is simpler and a good fit.",
      "hash": "0b40a609d61a8ab6344a8eb64cec888f892ce876364bddd93286bee49ac715b5",
      "facts": [
        {
          "kind": "value",
          "literal": "pagefind.app",
          "chunkId": "index#who-this-is-for"
        }
      ],
      "sources": [
        {
          "chunkId": "index#who-this-is-for",
          "url": "/docs#who-this-is-for",
          "anchor": "who-this-is-for"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "suits",
        "anyone",
        "building",
        "docs",
        "site",
        "whose",
        "content",
        "markdown",
        "astro",
        "docusaurus",
        "vitepress",
        "mkdocs",
        "folder",
        "wants",
        "search",
        "works",
        "without",
        "standing",
        "service",
        "crawler",
        "deep",
        "links",
        "right",
        "section",
        "answers",
        "questions",
        "reader",
        "words",
        "queryable",
        "coding",
        "agent",
        "integration",
        "covers",
        "other",
        "frameworks",
        "drop",
        "static",
        "overlay",
        "optionally",
        "point"
      ]
    },
    {
      "id": "limits",
      "kind": "section",
      "title": "Limits",
      "heading": null,
      "group": "Overview",
      "url": "/docs/limits",
      "summary": "These are the hard boundaries to know before adopting hev ask — corpus scope, recall ceiling, build limits, frontmatter parsing, latency, and adapter requirements. None are bugs; they are the edges of what the current design covers.",
      "hash": "d7dca49533d95fbdc798e6cfdf74017abfc0cf190ff1530d7050351890b64fdb",
      "facts": [
        {
          "kind": "value",
          "literal": "Callout.astro",
          "chunkId": "limits"
        }
      ],
      "sources": [
        {
          "chunkId": "limits",
          "url": "/docs/limits",
          "anchor": null
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "these",
        "hard",
        "boundaries",
        "know",
        "before",
        "adopting",
        "corpus",
        "scope",
        "recall",
        "ceiling",
        "build",
        "limits",
        "frontmatter",
        "parsing",
        "latency",
        "adapter",
        "requirements",
        "none",
        "bugs",
        "edges",
        "current",
        "design",
        "covers",
        "callout",
        "astro",
        "digest",
        "deliberately",
        "does",
        "should"
      ]
    },
    {
      "id": "limits#agentic-search-adds-latency",
      "kind": "section",
      "title": "Limits",
      "heading": "Agentic search adds latency",
      "group": "Overview",
      "url": "/docs/limits#agentic-search-adds-latency",
      "summary": "The agentic path is bounded by the configured number of model round-trips, so worst case is a few seconds and it is not instant by nature. The keyword path is the always-available instant lane while agentic search is the considered one, and the iteration cap can be tuned down for a tighter ceiling.",
      "hash": "39f47a0577b861e2dbe61b168c9018a6b5514c62ce98b8c23fb620d1d0a7e717",
      "facts": [
        {
          "kind": "code",
          "literal": "maxIterations",
          "chunkId": "limits#agentic-search-adds-latency"
        }
      ],
      "sources": [
        {
          "chunkId": "limits#agentic-search-adds-latency",
          "url": "/docs/limits#agentic-search-adds-latency",
          "anchor": "agentic-search-adds-latency"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "agentic",
        "search",
        "adds",
        "latency",
        "path",
        "bounded",
        "configured",
        "number",
        "model",
        "round",
        "trips",
        "worst",
        "case",
        "seconds",
        "instant",
        "nature",
        "keyword",
        "always",
        "available",
        "lane",
        "while",
        "considered",
        "iteration",
        "tuned",
        "down",
        "tighter",
        "ceiling",
        "maxiterations",
        "default",
        "claude",
        "tune",
        "need"
      ]
    },
    {
      "id": "limits#anchors-depend-on-the-renderers-slugger",
      "kind": "section",
      "title": "Limits",
      "heading": "Anchors depend on the renderer's slugger",
      "group": "Overview",
      "url": "/docs/limits#anchors-depend-on-the-renderers-slugger",
      "summary": "Deep links are only correct while the heading slugs hev ask generates match the renderer's id attributes; it uses the GitHub-aligned slugger by default and each framework adapter declares its own scheme where that differs. Either way the verify command fails if any chunk anchor is missing from the built HTML, so wiring verify into CI is what catches a slugging change before a broken link ships.",
      "hash": "3be9d1ca0662266a81ed851e1d0f0874f32e2082cb2ff3336eafaa8eb6ac175e",
      "facts": [
        {
          "kind": "code",
          "literal": "id",
          "chunkId": "limits#anchors-depend-on-the-renderers-slugger"
        },
        {
          "kind": "code",
          "literal": "github-slugger",
          "chunkId": "limits#anchors-depend-on-the-renderers-slugger"
        },
        {
          "kind": "code",
          "literal": "ask digest verify",
          "chunkId": "limits#anchors-depend-on-the-renderers-slugger"
        },
        {
          "kind": "code",
          "literal": "verify",
          "chunkId": "limits#anchors-depend-on-the-renderers-slugger"
        }
      ],
      "sources": [
        {
          "chunkId": "limits#anchors-depend-on-the-renderers-slugger",
          "url": "/docs/limits#anchors-depend-on-the-renderers-slugger",
          "anchor": "anchors-depend-on-the-renderers-slugger"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "anchors",
        "depend",
        "renderer",
        "slugger",
        "deep",
        "links",
        "only",
        "correct",
        "while",
        "heading",
        "slugs",
        "generates",
        "match",
        "attributes",
        "uses",
        "github",
        "aligned",
        "default",
        "framework",
        "adapter",
        "declares",
        "scheme",
        "differs",
        "either",
        "verify",
        "command",
        "fails",
        "chunk",
        "anchor",
        "missing",
        "built",
        "html",
        "wiring",
        "catches",
        "slugging",
        "change",
        "before",
        "broken",
        "link",
        "ships"
      ]
    },
    {
      "id": "limits#frontmatter-parsing-is-a-flat-yaml-subset",
      "kind": "section",
      "title": "Limits",
      "heading": "Frontmatter parsing is a flat-YAML subset",
      "group": "Overview",
      "url": "/docs/limits#frontmatter-parsing-is-a-flat-yaml-subset",
      "summary": "The offline build parses frontmatter with a small flat-YAML splitter rather than a full YAML parser, handling the common docs schema of string and number fields but not nested structures. This affects only the offline build reading files from disk; on Astro the runtime index uses the collection API and honors your real schema.",
      "hash": "da3ebf7a72c862c9bb94804726792203ebd2dad95887c4c094bf492223e719b8",
      "facts": [
        {
          "kind": "code",
          "literal": "getCollection",
          "chunkId": "limits#frontmatter-parsing-is-a-flat-yaml-subset"
        }
      ],
      "sources": [
        {
          "chunkId": "limits#frontmatter-parsing-is-a-flat-yaml-subset",
          "url": "/docs/limits#frontmatter-parsing-is-a-flat-yaml-subset",
          "anchor": "frontmatter-parsing-is-a-flat-yaml-subset"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "frontmatter",
        "parsing",
        "flat",
        "yaml",
        "subset",
        "offline",
        "build",
        "parses",
        "small",
        "splitter",
        "rather",
        "full",
        "parser",
        "handling",
        "common",
        "docs",
        "schema",
        "string",
        "number",
        "fields",
        "nested",
        "structures",
        "affects",
        "only",
        "reading",
        "files",
        "disk",
        "astro",
        "runtime",
        "index",
        "uses",
        "collection",
        "honors",
        "real",
        "getcollection",
        "handles",
        "aren",
        "supported",
        "time"
      ]
    },
    {
      "id": "limits#recall-has-a-keyword-ceiling",
      "kind": "section",
      "title": "Limits",
      "heading": "Recall has a keyword ceiling",
      "group": "Overview",
      "url": "/docs/limits#recall-has-a-keyword-ceiling",
      "summary": "Retrieval is keyword token-overlap widened by the glossary rather than embeddings, and the agentic loop can only ground in what retrieval finds. The glossary recovers most synonym cases, but a reader searching in language that shares no tokens with the docs and isn't in the glossary may never surface the right section; embeddings are the known fix for paraphrase recall and are deliberately not built yet, so until analytics show consistent misses, a richer glossary is the cheaper lever.",
      "hash": "df75d2232fca5a321ba6501fe42757e069ef11d194231d4a0af212994581279a",
      "facts": [
        {
          "kind": "code",
          "literal": "k8s",
          "chunkId": "limits#recall-has-a-keyword-ceiling"
        },
        {
          "kind": "code",
          "literal": "kubernetes",
          "chunkId": "limits#recall-has-a-keyword-ceiling"
        }
      ],
      "sources": [
        {
          "chunkId": "limits#recall-has-a-keyword-ceiling",
          "url": "/docs/limits#recall-has-a-keyword-ceiling",
          "anchor": "recall-has-a-keyword-ceiling"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "recall",
        "keyword",
        "ceiling",
        "retrieval",
        "token",
        "overlap",
        "widened",
        "glossary",
        "rather",
        "embeddings",
        "agentic",
        "loop",
        "only",
        "ground",
        "finds",
        "recovers",
        "most",
        "synonym",
        "cases",
        "reader",
        "searching",
        "language",
        "shares",
        "tokens",
        "docs",
        "never",
        "surface",
        "right",
        "section",
        "known",
        "paraphrase",
        "deliberately",
        "built",
        "until",
        "analytics",
        "show",
        "consistent",
        "misses",
        "richer",
        "cheaper"
      ]
    },
    {
      "id": "limits#secrets-live-server-side",
      "kind": "section",
      "title": "Limits",
      "heading": "Secrets live server-side",
      "group": "Overview",
      "url": "/docs/limits#secrets-live-server-side",
      "summary": "The agentic path needs the configured provider's API key in the server environment that runs the endpoint, and the key is never exposed to the browser. If the key isn't present at runtime the endpoint serves keyword results, so search degrades rather than breaking.",
      "hash": "2adf59c2589370b5a968f7e95da1bd1c86a15fdc4f3dce2c0f994addb33152bc",
      "facts": [
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "limits#secrets-live-server-side"
        },
        {
          "kind": "code",
          "literal": "OPENAI_API_KEY",
          "chunkId": "limits#secrets-live-server-side"
        },
        {
          "kind": "code",
          "literal": "OPENROUTER_API_KEY",
          "chunkId": "limits#secrets-live-server-side"
        },
        {
          "kind": "code",
          "literal": "provider",
          "chunkId": "limits#secrets-live-server-side"
        },
        {
          "kind": "code",
          "literal": "/api/ask",
          "chunkId": "limits#secrets-live-server-side"
        }
      ],
      "sources": [
        {
          "chunkId": "limits#secrets-live-server-side",
          "url": "/docs/limits#secrets-live-server-side",
          "anchor": "secrets-live-server-side"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "secrets",
        "live",
        "server",
        "side",
        "agentic",
        "path",
        "needs",
        "configured",
        "provider",
        "environment",
        "runs",
        "endpoint",
        "never",
        "exposed",
        "browser",
        "present",
        "runtime",
        "serves",
        "keyword",
        "results",
        "search",
        "degrades",
        "rather",
        "breaking",
        "anthropic",
        "openai",
        "openrouter",
        "anthropicapikey",
        "default",
        "openaiapikey",
        "openrouterapikey",
        "option",
        "doesn",
        "break"
      ]
    },
    {
      "id": "limits#the-agentic-path-needs-a-server-somewhere",
      "kind": "section",
      "title": "Limits",
      "heading": "The agentic path needs a server somewhere",
      "group": "Overview",
      "url": "/docs/limits#the-agentic-path-needs-a-server-somewhere",
      "summary": "Keyword search runs fully static from the committed digest in the browser with no server on any host, but the agentic path needs a runtime: on Astro it is the on-demand endpoint route requiring a server or hybrid adapter, and on other frameworks it is the standalone hostable endpoint you deploy and point the overlay at. A purely static site can ship keyword search with nothing hosted but can't answer questions until an endpoint exists somewhere.",
      "hash": "f6ba9d8e2cd2303d69ee82861d85d062cfb484e3cb111cb2187049e8b7116231",
      "facts": [
        {
          "kind": "code",
          "literal": "/api/ask",
          "chunkId": "limits#the-agentic-path-needs-a-server-somewhere"
        }
      ],
      "sources": [
        {
          "chunkId": "limits#the-agentic-path-needs-a-server-somewhere",
          "url": "/docs/limits#the-agentic-path-needs-a-server-somewhere",
          "anchor": "the-agentic-path-needs-a-server-somewhere"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "agentic",
        "path",
        "needs",
        "server",
        "somewhere",
        "keyword",
        "search",
        "runs",
        "fully",
        "static",
        "committed",
        "digest",
        "browser",
        "host",
        "runtime",
        "astro",
        "demand",
        "endpoint",
        "route",
        "requiring",
        "hybrid",
        "adapter",
        "other",
        "frameworks",
        "standalone",
        "hostable",
        "deploy",
        "point",
        "overlay",
        "purely",
        "site",
        "ship",
        "nothing",
        "hosted",
        "answer",
        "questions",
        "until",
        "exists",
        "drop",
        "reads"
      ]
    },
    {
      "id": "limits#the-corpus-is-the-content-you-configure",
      "kind": "section",
      "title": "Limits",
      "heading": "The corpus is the content you configure",
      "group": "Overview",
      "url": "/docs/limits#the-corpus-is-the-content-you-configure",
      "summary": "hev ask searches only the markdown you point it at — a content collection, a docs tree, or a set of globs — with no crawler, no sitemap ingestion, and no way to index pages outside the configured corpus such as a hand-written page or a bare route. A doc not in the corpus won't appear in search, so put what you want searchable where the adapter looks.",
      "hash": "f3508affa059adf48c4ae3f6ee96dccd8792a0ee66479077d9e8d9be1be41521",
      "facts": [
        {
          "kind": "code",
          "literal": "docs/",
          "chunkId": "limits#the-corpus-is-the-content-you-configure"
        },
        {
          "kind": "code",
          "literal": ".astro",
          "chunkId": "limits#the-corpus-is-the-content-you-configure"
        }
      ],
      "sources": [
        {
          "chunkId": "limits#the-corpus-is-the-content-you-configure",
          "url": "/docs/limits#the-corpus-is-the-content-you-configure",
          "anchor": "the-corpus-is-the-content-you-configure"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "corpus",
        "content",
        "configure",
        "searches",
        "only",
        "markdown",
        "point",
        "collection",
        "docs",
        "tree",
        "globs",
        "crawler",
        "sitemap",
        "ingestion",
        "index",
        "pages",
        "outside",
        "configured",
        "such",
        "hand",
        "written",
        "page",
        "bare",
        "route",
        "appear",
        "search",
        "want",
        "searchable",
        "adapter",
        "looks",
        "astro",
        "docusaurus",
        "nothing",
        "else",
        "there",
        "external",
        "aren",
        "part",
        "react",
        "example"
      ]
    },
    {
      "id": "limits#the-one-shot-digest-build-is-bounded-sharded-builds-are-not",
      "kind": "section",
      "title": "Limits",
      "heading": "The one-shot digest build is bounded; sharded builds are not",
      "group": "Overview",
      "url": "/docs/limits#the-one-shot-digest-build-is-bounded-sharded-builds-are-not",
      "summary": "The one-shot build sends the full cleaned corpus to the model in a single call, which fits a typical docs site but fails loudly past a section-text size threshold; beyond that the sharded build splits the corpus into prefix-stable shards each distilled in its own context and merged deterministically, so corpus size stops being a context-window problem and a content edit re-distills only the touched shard. The remaining scale consideration is the runtime prompt, since the agentic path inlines section summaries, so trees with tens of thousands of sections aren't yet a fit for the answer loop, though a coding agent reading the tree over MCP has no such ceiling.",
      "hash": "b92a502b0c0bf50078803a9d6b07d38be0501c79206b0246bd30626eb1f8f08f",
      "facts": [
        {
          "kind": "code",
          "literal": "ask digest build",
          "chunkId": "limits#the-one-shot-digest-build-is-bounded-sharded-builds-are-not"
        }
      ],
      "sources": [
        {
          "chunkId": "limits#the-one-shot-digest-build-is-bounded-sharded-builds-are-not",
          "url": "/docs/limits#the-one-shot-digest-build-is-bounded-sharded-builds-are-not",
          "anchor": "the-one-shot-digest-build-is-bounded-sharded-builds-are-not"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "shot",
        "digest",
        "build",
        "bounded",
        "sharded",
        "builds",
        "sends",
        "full",
        "cleaned",
        "corpus",
        "model",
        "single",
        "call",
        "fits",
        "typical",
        "docs",
        "site",
        "fails",
        "loudly",
        "past",
        "section",
        "text",
        "size",
        "threshold",
        "beyond",
        "splits",
        "prefix",
        "stable",
        "shards",
        "distilled",
        "context",
        "merged",
        "deterministically",
        "stops",
        "being",
        "window",
        "problem",
        "content",
        "edit",
        "distills"
      ]
    },
    {
      "id": "quickstart",
      "kind": "section",
      "title": "Quick start",
      "heading": null,
      "group": "Overview",
      "url": "/docs/quickstart",
      "summary": "Add hev ask to an existing Astro 5 docs site whose content lives in a collection in about five minutes: install the integration and drop in the overlay for keyword search with no key and nothing to host, then add a provider key on the server to enable the agentic answer loop on Enter, or skip the key if you only want the search UI. On any other framework you drop in the same overlay as a script tag and point it at a hosted endpoint for answers.",
      "hash": "54831061153def336afcc7a27a41a77ca77fa55d4ade8329bf0326e8fc6c19de",
      "facts": [
        {
          "kind": "code",
          "literal": "src/content/docs",
          "chunkId": "quickstart"
        },
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "quickstart"
        },
        {
          "kind": "code",
          "literal": "<script>",
          "chunkId": "quickstart"
        },
        {
          "kind": "value",
          "literal": "Callout.astro",
          "chunkId": "quickstart"
        },
        {
          "kind": "value",
          "literal": "CodeTabs.astro",
          "chunkId": "quickstart"
        }
      ],
      "sources": [
        {
          "chunkId": "quickstart",
          "url": "/docs/quickstart",
          "anchor": null
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "existing",
        "astro",
        "docs",
        "site",
        "whose",
        "content",
        "lives",
        "collection",
        "about",
        "five",
        "minutes",
        "install",
        "integration",
        "drop",
        "overlay",
        "keyword",
        "search",
        "nothing",
        "host",
        "provider",
        "server",
        "enable",
        "agentic",
        "answer",
        "loop",
        "enter",
        "skip",
        "only",
        "want",
        "other",
        "framework",
        "same",
        "script",
        "point",
        "hosted",
        "endpoint",
        "answers",
        "anthropic",
        "callout",
        "codetabs"
      ]
    },
    {
      "id": "quickstart#1-install",
      "kind": "section",
      "title": "Quick start",
      "heading": "1. Install",
      "group": "Overview",
      "url": "/docs/quickstart#1-install",
      "summary": "Install the package from npm once published, or until then consume it straight from the package subdirectory on GitHub.",
      "hash": "b0e3103a35b35c38f295163b3d2055792feacebcaf6e70c6d224e89d3f8f23e1",
      "facts": [
        {
          "kind": "code",
          "literal": "pnpm add @hevmind/ask",
          "chunkId": "quickstart#1-install"
        },
        {
          "kind": "code",
          "literal": "pnpm add \"git+ssh://[email protected]/hev/ask.git#main&path:/packages/ui\"",
          "chunkId": "quickstart#1-install"
        }
      ],
      "sources": [
        {
          "chunkId": "quickstart#1-install",
          "url": "/docs/quickstart#1-install",
          "anchor": "1-install"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "install",
        "package",
        "once",
        "published",
        "until",
        "consume",
        "straight",
        "subdirectory",
        "github",
        "pnpm",
        "hevmind",
        "main",
        "path",
        "packages"
      ]
    },
    {
      "id": "quickstart#2-register-the-integration",
      "kind": "section",
      "title": "Quick start",
      "heading": "2. Register the integration",
      "group": "Overview",
      "url": "/docs/quickstart#2-register-the-integration",
      "summary": "Register the integration in the Astro config by adding the hevAsk() call with your content collection names and a base path; the collections list is the one option you must set and everything else has a default.",
      "hash": "02f816dd61687ca1704bca5caeb6868ea8d531804bd9dc7ca569c05522811b6d",
      "facts": [
        {
          "kind": "code",
          "literal": "// astro.config.mjs\nimport { defineConfig } from \"astro/config\";\nimport hevAsk from \"@hevmind/ask\";\n\nexport default defineConfig({\n  integrations: [\n    hevAsk({\n      collections: [\"docs\"],   // your content collection name(s)\n      basePath: \"/docs/\",      // slug → URL prefix: basePath + slug\n    }),\n  ],\n});",
          "chunkId": "quickstart#2-register-the-integration"
        },
        {
          "kind": "code",
          "literal": "collections",
          "chunkId": "quickstart#2-register-the-integration"
        }
      ],
      "sources": [
        {
          "chunkId": "quickstart#2-register-the-integration",
          "url": "/docs/quickstart#2-register-the-integration",
          "anchor": "2-register-the-integration"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "register",
        "integration",
        "astro",
        "config",
        "adding",
        "hevask",
        "call",
        "content",
        "collection",
        "names",
        "base",
        "path",
        "collections",
        "list",
        "option",
        "must",
        "everything",
        "else",
        "default",
        "import",
        "defineconfig",
        "hevmind",
        "export",
        "integrations",
        "docs",
        "name",
        "basepath",
        "slug",
        "prefix",
        "configuration",
        "reference"
      ]
    },
    {
      "id": "quickstart#3-add-a-server-adapter",
      "kind": "section",
      "title": "Quick start",
      "heading": "3. Add a server adapter",
      "group": "Overview",
      "url": "/docs/quickstart#3-add-a-server-adapter",
      "summary": "Because the endpoint route renders on demand, add whichever server or hybrid adapter matches your host while existing pages stay prerendered; the example uses the Cloudflare adapter.",
      "hash": "795eff804c3ce56e4f62c96e59090a4c4845680aef5ab40735d8a57b33976dcf",
      "facts": [
        {
          "kind": "code",
          "literal": "// astro.config.mjs\nimport cloudflare from \"@astrojs/cloudflare\";\n\nexport default defineConfig({\n  adapter: cloudflare({ platformProxy: { enabled: true } }),\n  // ...integrations as above\n});",
          "chunkId": "quickstart#3-add-a-server-adapter"
        },
        {
          "kind": "code",
          "literal": "/api/ask",
          "chunkId": "quickstart#3-add-a-server-adapter"
        }
      ],
      "sources": [
        {
          "chunkId": "quickstart#3-add-a-server-adapter",
          "url": "/docs/quickstart#3-add-a-server-adapter",
          "anchor": "3-add-a-server-adapter"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "server",
        "adapter",
        "because",
        "endpoint",
        "route",
        "renders",
        "demand",
        "whichever",
        "hybrid",
        "matches",
        "host",
        "while",
        "existing",
        "pages",
        "stay",
        "prerendered",
        "example",
        "uses",
        "cloudflare",
        "astro",
        "config",
        "import",
        "astrojs",
        "export",
        "default",
        "defineconfig",
        "platformproxy",
        "enabled",
        "true",
        "integrations",
        "above",
        "only",
        "runs",
        "function",
        "site"
      ]
    },
    {
      "id": "quickstart#4-render-the-overlay",
      "kind": "section",
      "title": "Quick start",
      "heading": "4. Render the overlay",
      "group": "Overview",
      "url": "/docs/quickstart#4-render-the-overlay",
      "summary": "Add the overlay component once somewhere global like the base layout; any element with the opener attribute opens the palette and the keyboard shortcut is bound automatically. Keyword search works at this point — run the dev server and try it.",
      "hash": "5c984aa14647046abf4d3804523a339a029e8187d8562f22a9b55f4a3b7e7b33",
      "facts": [
        {
          "kind": "code",
          "literal": "---\n// src/layouts/Base.astro\nimport SearchOverlay from \"@hevmind/ask/components/SearchOverlay.astro\";\n---\n<button type=\"button\" data-hev-ask-open>\n  Search <kbd>⌘K</kbd>\n</button>\n\n<slot />\n\n<SearchOverlay />",
          "chunkId": "quickstart#4-render-the-overlay"
        },
        {
          "kind": "code",
          "literal": "data-hev-ask-open",
          "chunkId": "quickstart#4-render-the-overlay"
        },
        {
          "kind": "code",
          "literal": "⌘K",
          "chunkId": "quickstart#4-render-the-overlay"
        },
        {
          "kind": "code",
          "literal": "astro dev",
          "chunkId": "quickstart#4-render-the-overlay"
        }
      ],
      "sources": [
        {
          "chunkId": "quickstart#4-render-the-overlay",
          "url": "/docs/quickstart#4-render-the-overlay",
          "anchor": "4-render-the-overlay"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "render",
        "overlay",
        "component",
        "once",
        "somewhere",
        "global",
        "like",
        "base",
        "layout",
        "element",
        "opener",
        "attribute",
        "opens",
        "palette",
        "keyboard",
        "shortcut",
        "bound",
        "automatically",
        "keyword",
        "search",
        "works",
        "point",
        "server",
        "layouts",
        "astro",
        "import",
        "searchoverlay",
        "hevmind",
        "components",
        "button",
        "type",
        "data",
        "open",
        "slot",
        "press"
      ]
    },
    {
      "id": "quickstart#5-build-the-digest",
      "kind": "section",
      "title": "Quick start",
      "heading": "5. Build the digest",
      "group": "Overview",
      "url": "/docs/quickstart#5-build-the-digest",
      "summary": "The digest is an offline-built markdown tree you commit that gives the loop context, ranks keyword results, supplies the glossary, and holds suggested questions. Build it the recommended way with the bundled Claude Code skill inside your subscription (no key, no token spend), or with the one-call CLI build for CI choosing a provider, then verify anchors and commit; both paths are incremental and hash-gated, and the integration runs the build automatically during the site build when a key is present.",
      "hash": "c3e971ffc29cc5333a5448cb5e2846615f72af766d664a071dd8b904dd6b09d4",
      "facts": [
        {
          "kind": "code",
          "literal": "You: build the hev ask digest\n\nClaude runs:\n  ask digest corpus       # emits the sections to distil\n  …writes context/glossary/summaries/suggestions…\n  ask digest assemble     # writes the .hev-ask/ tree",
          "chunkId": "quickstart#5-build-the-digest"
        },
        {
          "kind": "code",
          "literal": "export ANTHROPIC_API_KEY=sk-ant-...\npnpm exec ask digest build      # writes the .hev-ask/ tree",
          "chunkId": "quickstart#5-build-the-digest"
        },
        {
          "kind": "code",
          "literal": "export OPENAI_API_KEY=sk-...\npnpm exec ask digest build --provider openai",
          "chunkId": "quickstart#5-build-the-digest"
        },
        {
          "kind": "code",
          "literal": "export OPENROUTER_API_KEY=sk-or-...\npnpm exec ask digest build --provider openrouter",
          "chunkId": "quickstart#5-build-the-digest"
        },
        {
          "kind": "code",
          "literal": "pnpm exec ask digest verify     # builds the site, checks every anchor resolves\ngit add .hev-ask",
          "chunkId": "quickstart#5-build-the-digest"
        },
        {
          "kind": "code",
          "literal": "k8s",
          "chunkId": "quickstart#5-build-the-digest"
        },
        {
          "kind": "code",
          "literal": "kubernetes",
          "chunkId": "quickstart#5-build-the-digest"
        },
        {
          "kind": "code",
          "literal": "--provider",
          "chunkId": "quickstart#5-build-the-digest"
        },
        {
          "kind": "code",
          "literal": "astro build",
          "chunkId": "quickstart#5-build-the-digest"
        },
        {
          "kind": "value",
          "literal": "claude.com",
          "chunkId": "quickstart#5-build-the-digest"
        }
      ],
      "sources": [
        {
          "chunkId": "quickstart#5-build-the-digest",
          "url": "/docs/quickstart#5-build-the-digest",
          "anchor": "5-build-the-digest"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "build",
        "digest",
        "offline",
        "built",
        "markdown",
        "tree",
        "commit",
        "gives",
        "loop",
        "context",
        "ranks",
        "keyword",
        "results",
        "supplies",
        "glossary",
        "holds",
        "suggested",
        "questions",
        "recommended",
        "bundled",
        "claude",
        "code",
        "skill",
        "inside",
        "subscription",
        "token",
        "spend",
        "call",
        "choosing",
        "provider",
        "verify",
        "anchors",
        "both",
        "paths",
        "incremental",
        "hash",
        "gated",
        "integration",
        "runs",
        "automatically"
      ]
    },
    {
      "id": "quickstart#enable-agentic-search",
      "kind": "section",
      "title": "Quick start",
      "heading": "Enable agentic search",
      "group": "Overview",
      "url": "/docs/quickstart#enable-agentic-search",
      "summary": "Set the provider's API key in the server environment where the endpoint runs, after which pressing Enter runs the agentic loop with self-issued sub-queries, a grounded answer, and inline deep links; without a key Enter returns keyword results. The Anthropic default needs only the key, while OpenAI and OpenRouter also need the matching provider set in the integration options.",
      "hash": "ef1e17ef641cdc4792581c2c5f7d313aa573f6ccc6cb923f2288488784deac0e",
      "facts": [
        {
          "kind": "code",
          "literal": "# the default provider — nothing else to configure\nexport ANTHROPIC_API_KEY=sk-ant-...",
          "chunkId": "quickstart#enable-agentic-search"
        },
        {
          "kind": "code",
          "literal": "# with provider: \"openai\" in the hevAsk() options\nexport OPENAI_API_KEY=sk-...",
          "chunkId": "quickstart#enable-agentic-search"
        },
        {
          "kind": "code",
          "literal": "# with provider: \"openrouter\" in the hevAsk() options\nexport OPENROUTER_API_KEY=sk-or-...",
          "chunkId": "quickstart#enable-agentic-search"
        },
        {
          "kind": "code",
          "literal": "/api/ask",
          "chunkId": "quickstart#enable-agentic-search"
        },
        {
          "kind": "code",
          "literal": ".env",
          "chunkId": "quickstart#enable-agentic-search"
        },
        {
          "kind": "code",
          "literal": "provider",
          "chunkId": "quickstart#enable-agentic-search"
        }
      ],
      "sources": [
        {
          "chunkId": "quickstart#enable-agentic-search",
          "url": "/docs/quickstart#enable-agentic-search",
          "anchor": "enable-agentic-search"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "enable",
        "agentic",
        "search",
        "provider",
        "server",
        "environment",
        "endpoint",
        "runs",
        "after",
        "pressing",
        "enter",
        "loop",
        "self",
        "issued",
        "queries",
        "grounded",
        "answer",
        "inline",
        "deep",
        "links",
        "without",
        "returns",
        "keyword",
        "results",
        "anthropic",
        "default",
        "needs",
        "only",
        "while",
        "openai",
        "openrouter",
        "also",
        "need",
        "matching",
        "integration",
        "options",
        "nothing",
        "else",
        "configure",
        "export"
      ]
    },
    {
      "id": "quickstart#prerequisites",
      "kind": "section",
      "title": "Quick start",
      "heading": "Prerequisites",
      "group": "Overview",
      "url": "/docs/quickstart#prerequisites",
      "summary": "Prerequisites are Astro 5 with at least one content collection, a server or hybrid adapter because the endpoint route renders on demand and a fully static build can't serve it, and a provider API key to enable agentic search; keyword search needs no key, and OpenAI and OpenRouter work via the provider option though the guide uses the Anthropic default.",
      "hash": "5eef6bcbb64bfe13a8f2d64c6597ac69ef41ab1136dece4916e64326dd033c7d",
      "facts": [
        {
          "kind": "code",
          "literal": "/api/ask",
          "chunkId": "quickstart#prerequisites"
        },
        {
          "kind": "code",
          "literal": "ANTHROPIC_API_KEY",
          "chunkId": "quickstart#prerequisites"
        },
        {
          "kind": "code",
          "literal": "provider",
          "chunkId": "quickstart#prerequisites"
        },
        {
          "kind": "value",
          "literal": "docs.astro.build",
          "chunkId": "quickstart#prerequisites"
        }
      ],
      "sources": [
        {
          "chunkId": "quickstart#prerequisites",
          "url": "/docs/quickstart#prerequisites",
          "anchor": "prerequisites"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "prerequisites",
        "astro",
        "least",
        "content",
        "collection",
        "server",
        "hybrid",
        "adapter",
        "because",
        "endpoint",
        "route",
        "renders",
        "demand",
        "fully",
        "static",
        "build",
        "serve",
        "provider",
        "enable",
        "agentic",
        "search",
        "keyword",
        "needs",
        "openai",
        "openrouter",
        "work",
        "option",
        "though",
        "guide",
        "uses",
        "anthropic",
        "default",
        "docs",
        "node",
        "cloudflare",
        "vercel",
        "anthropicapikey"
      ]
    },
    {
      "id": "quickstart#set-up-keyword-search",
      "kind": "section",
      "title": "Quick start",
      "heading": "Set up keyword search",
      "group": "Overview",
      "url": "/docs/quickstart#set-up-keyword-search",
      "summary": "Section header introducing the keyless keyword-search setup steps that follow.",
      "hash": "20c32e1a769e434abfef0906b5f05128b3bc42af63060ad5c866de714eea0d47",
      "facts": [],
      "sources": [
        {
          "chunkId": "quickstart#set-up-keyword-search",
          "url": "/docs/quickstart#set-up-keyword-search",
          "anchor": "set-up-keyword-search"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "keyword",
        "search",
        "section",
        "header",
        "introducing",
        "keyless",
        "setup",
        "steps",
        "follow"
      ]
    },
    {
      "id": "quickstart#verify-it-works",
      "kind": "section",
      "title": "Quick start",
      "heading": "Verify it works",
      "group": "Overview",
      "url": "/docs/quickstart#verify-it-works",
      "summary": "Verify the install three ways: a single heading word should deep-link to that section, a multi-word question on Enter should show the model's sub-queries and stream a grounded answer with inline deep links, and the verify command exits non-zero if any chunk anchor is missing from the built HTML, so wire it into CI. From here, read the configuration options or Concepts.",
      "hash": "ef40c511b8d94f0d7c0c8e3fdf7db8156b68ace57ccc8d3f7559c9cad10897e6",
      "facts": [
        {
          "kind": "code",
          "literal": "/docs/page#heading",
          "chunkId": "quickstart#verify-it-works"
        },
        {
          "kind": "code",
          "literal": "ask digest verify",
          "chunkId": "quickstart#verify-it-works"
        }
      ],
      "sources": [
        {
          "chunkId": "quickstart#verify-it-works",
          "url": "/docs/quickstart#verify-it-works",
          "anchor": "verify-it-works"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "verify",
        "works",
        "install",
        "three",
        "ways",
        "single",
        "heading",
        "word",
        "should",
        "deep",
        "link",
        "section",
        "multi",
        "question",
        "enter",
        "show",
        "model",
        "queries",
        "stream",
        "grounded",
        "answer",
        "inline",
        "links",
        "command",
        "exits",
        "zero",
        "chunk",
        "anchor",
        "missing",
        "built",
        "html",
        "wire",
        "here",
        "read",
        "configuration",
        "options",
        "concepts",
        "docs",
        "page",
        "digest"
      ]
    },
    {
      "id": "tradeoffs",
      "kind": "section",
      "title": "Tradeoffs",
      "heading": null,
      "group": "Overview",
      "url": "/docs/tradeoffs",
      "summary": "Every search tool makes choices, and this page is the honest version of what hev ask trades away to get what it gives, so you can decide whether the trade fits your docs.",
      "hash": "1b4bca991a9374eeb54f7ce6a92452afc7b47d4c36d02ef744c6036823919c78",
      "facts": [
        {
          "kind": "value",
          "literal": "Callout.astro",
          "chunkId": "tradeoffs"
        }
      ],
      "sources": [
        {
          "chunkId": "tradeoffs",
          "url": "/docs/tradeoffs",
          "anchor": null
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "every",
        "search",
        "tool",
        "makes",
        "choices",
        "page",
        "honest",
        "version",
        "trades",
        "away",
        "gives",
        "decide",
        "whether",
        "trade",
        "fits",
        "docs",
        "callout",
        "astro",
        "choosing",
        "adopting",
        "dependency",
        "posture",
        "committed",
        "digest",
        "cost",
        "latency",
        "agentic",
        "compares",
        "pagefind",
        "algolia",
        "orama"
      ]
    },
    {
      "id": "tradeoffs#a-committed-digest",
      "kind": "section",
      "title": "Tradeoffs",
      "heading": "A committed digest",
      "group": "Overview",
      "url": "/docs/tradeoffs#a-committed-digest",
      "summary": "The digest is generated offline and committed to git as a markdown tree rather than computed at runtime or hidden in a service. The upside is that it is reviewable per section in pull requests, deterministic and free to read at runtime, bundled into the edge worker without filesystem access, and directly navigable by an agent; the cost is that it can go stale, regenerating only on a content change and build, though the runtime warns on hash mismatch and the per-section hash gate makes rebuilding on every content change in CI the intended workflow.",
      "hash": "110adfc68831d0e1a9dcd3844ea876fb7fbd211e79537b3c2e854618aaecdc8d",
      "facts": [
        {
          "kind": "code",
          "literal": "tree",
          "chunkId": "tradeoffs#a-committed-digest"
        },
        {
          "kind": "code",
          "literal": "cat",
          "chunkId": "tradeoffs#a-committed-digest"
        },
        {
          "kind": "code",
          "literal": "grep",
          "chunkId": "tradeoffs#a-committed-digest"
        }
      ],
      "sources": [
        {
          "chunkId": "tradeoffs#a-committed-digest",
          "url": "/docs/tradeoffs#a-committed-digest",
          "anchor": "a-committed-digest"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "committed",
        "digest",
        "generated",
        "offline",
        "markdown",
        "tree",
        "rather",
        "computed",
        "runtime",
        "hidden",
        "service",
        "upside",
        "reviewable",
        "section",
        "pull",
        "requests",
        "deterministic",
        "free",
        "read",
        "bundled",
        "edge",
        "worker",
        "without",
        "filesystem",
        "access",
        "directly",
        "navigable",
        "agent",
        "cost",
        "stale",
        "regenerating",
        "only",
        "content",
        "change",
        "build",
        "though",
        "warns",
        "hash",
        "mismatch",
        "gate"
      ]
    },
    {
      "id": "tradeoffs#a-flagship-adapter-primitives-for-the-rest",
      "kind": "section",
      "title": "Tradeoffs",
      "heading": "A flagship adapter, primitives for the rest",
      "group": "Overview",
      "url": "/docs/tradeoffs#a-flagship-adapter-primitives-for-the-rest",
      "summary": "hev ask is host-neutral at the core but opinionated about Astro: the Astro integration is batteries-included from one config block, while every other framework wires two primitives itself — the static overlay and, for answers, the standalone endpoint. The upside is that the digest, overlay, CLI, and MCP are the same everywhere so a new framework is an adapter rather than a fork and the keyword path needs nothing hosted; the cost is that off Astro you do the wiring the integration would have done, and a turnkey plugin per framework is a goal rather than a guarantee.",
      "hash": "ace3b69886bb992230df003c64bc5e89ff7954e8f07de9202a71d5d00d362d40",
      "facts": [
        {
          "kind": "code",
          "literal": "<script>",
          "chunkId": "tradeoffs#a-flagship-adapter-primitives-for-the-rest"
        },
        {
          "kind": "code",
          "literal": "/api/ask",
          "chunkId": "tradeoffs#a-flagship-adapter-primitives-for-the-rest"
        }
      ],
      "sources": [
        {
          "chunkId": "tradeoffs#a-flagship-adapter-primitives-for-the-rest",
          "url": "/docs/tradeoffs#a-flagship-adapter-primitives-for-the-rest",
          "anchor": "a-flagship-adapter-primitives-for-the-rest"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "flagship",
        "adapter",
        "primitives",
        "rest",
        "host",
        "neutral",
        "core",
        "opinionated",
        "about",
        "astro",
        "integration",
        "batteries",
        "included",
        "config",
        "block",
        "while",
        "every",
        "other",
        "framework",
        "wires",
        "itself",
        "static",
        "overlay",
        "answers",
        "standalone",
        "endpoint",
        "upside",
        "digest",
        "same",
        "everywhere",
        "rather",
        "fork",
        "keyword",
        "path",
        "needs",
        "nothing",
        "hosted",
        "cost",
        "wiring",
        "would"
      ]
    },
    {
      "id": "tradeoffs#cost-and-latency-of-agentic-search",
      "kind": "section",
      "title": "Tradeoffs",
      "heading": "Cost and latency of agentic search",
      "group": "Overview",
      "url": "/docs/tradeoffs#cost-and-latency-of-agentic-search",
      "summary": "The agentic path calls the model, meaning real if small cost and latency: worst-case latency is roughly the iteration count of small-model round-trips (a few seconds) with the keyword path staying instant and the iteration cap as the knob, and cost is one bounded loop per submitted query on the default small model with domain context prompt-cached across rounds. The offline build uses a stronger model but the hash gate means you pay for it only when content changes, and keyword-only is a first-class mode if you want no key in the loop.",
      "hash": "64c96faf9220cd1746ff5fe83b61b585b03f23674074ae444bfec6a16b4411de",
      "facts": [
        {
          "kind": "code",
          "literal": "maxIterations",
          "chunkId": "tradeoffs#cost-and-latency-of-agentic-search"
        }
      ],
      "sources": [
        {
          "chunkId": "tradeoffs#cost-and-latency-of-agentic-search",
          "url": "/docs/tradeoffs#cost-and-latency-of-agentic-search",
          "anchor": "cost-and-latency-of-agentic-search"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "cost",
        "latency",
        "agentic",
        "search",
        "path",
        "calls",
        "model",
        "meaning",
        "real",
        "small",
        "worst",
        "case",
        "roughly",
        "iteration",
        "count",
        "round",
        "trips",
        "seconds",
        "keyword",
        "staying",
        "instant",
        "knob",
        "bounded",
        "loop",
        "submitted",
        "query",
        "default",
        "domain",
        "context",
        "prompt",
        "cached",
        "across",
        "rounds",
        "offline",
        "build",
        "uses",
        "stronger",
        "hash",
        "gate",
        "means"
      ]
    },
    {
      "id": "tradeoffs#how-it-compares",
      "kind": "section",
      "title": "Tradeoffs",
      "heading": "How it compares",
      "group": "Overview",
      "url": "/docs/tradeoffs#how-it-compares",
      "summary": "A comparison table across retrieval method, AI ranking, deep links, and hosting for hev ask, Pagefind, Algolia DocSearch, and Orama. The summary: choose Pagefind for simple zero-service keyword search with no key, Algolia for a managed crawler-based keyword service, Orama for client-side vector search you manage, and hev ask if your docs are a folder of markdown on any framework, you want deep links to sections, and you want a reader's question rather than just their keywords to find the right section.",
      "hash": "f7153362862908034c56b96908a7bca0f733e311dfba14d3d4681b1c72e1fe12",
      "facts": [],
      "sources": [
        {
          "chunkId": "tradeoffs#how-it-compares",
          "url": "/docs/tradeoffs#how-it-compares",
          "anchor": "how-it-compares"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "compares",
        "comparison",
        "table",
        "across",
        "retrieval",
        "method",
        "ranking",
        "deep",
        "links",
        "hosting",
        "pagefind",
        "algolia",
        "docsearch",
        "orama",
        "summary",
        "choose",
        "simple",
        "zero",
        "service",
        "keyword",
        "search",
        "managed",
        "crawler",
        "based",
        "client",
        "side",
        "vector",
        "manage",
        "docs",
        "folder",
        "markdown",
        "framework",
        "want",
        "sections",
        "reader",
        "question",
        "rather",
        "just",
        "their",
        "keywords"
      ]
    },
    {
      "id": "tradeoffs#keyword-retrieval-not-embeddings",
      "kind": "section",
      "title": "Tradeoffs",
      "heading": "Keyword retrieval, not embeddings",
      "group": "Overview",
      "url": "/docs/tradeoffs#keyword-retrieval-not-embeddings",
      "summary": "Retrieval is dependency-free token overlap widened by the glossary, with no embeddings or vector store. The upside is nothing to host or keep in sync, edge-safe and instant, with the glossary recovering much synonym recall; the cost is a paraphrase-recall ceiling, since the agent can only ground in what keyword retrieval found, so readers who routinely search in words sharing no tokens with the docs and absent from the glossary would be better served by embeddings — an upgrade deferred rather than designed out.",
      "hash": "816629bc3f9d42150a53cdbf54324d130714f295a4f5db66f417ac4b8965fa94",
      "facts": [],
      "sources": [
        {
          "chunkId": "tradeoffs#keyword-retrieval-not-embeddings",
          "url": "/docs/tradeoffs#keyword-retrieval-not-embeddings",
          "anchor": "keyword-retrieval-not-embeddings"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "keyword",
        "retrieval",
        "embeddings",
        "dependency",
        "free",
        "token",
        "overlap",
        "widened",
        "glossary",
        "vector",
        "store",
        "upside",
        "nothing",
        "host",
        "keep",
        "sync",
        "edge",
        "safe",
        "instant",
        "recovering",
        "much",
        "synonym",
        "recall",
        "cost",
        "paraphrase",
        "ceiling",
        "since",
        "agent",
        "only",
        "ground",
        "found",
        "readers",
        "routinely",
        "search",
        "words",
        "sharing",
        "tokens",
        "docs",
        "absent",
        "would"
      ]
    },
    {
      "id": "tradeoffs#one-dependency-deliberately",
      "kind": "section",
      "title": "Tradeoffs",
      "heading": "One dependency, deliberately",
      "group": "Overview",
      "url": "/docs/tradeoffs#one-dependency-deliberately",
      "summary": "hev ask aims to be near zero-dependency with one deliberate exception: the heading slugger, a tiny pure-JS edge-safe library. Generating anchors by hand risks drifting from the renderer and shipping a link that 404s to the top of the page, so using the same slugger the renderer uses guarantees byte-identical anchors, with per-framework adapters extending that guarantee to their slug rules; the dependency was taken on purpose.",
      "hash": "ab20e6d42c28963543737ab48f6363737ae3acca033cbf40114668f79b31f2c6",
      "facts": [
        {
          "kind": "code",
          "literal": "github-slugger",
          "chunkId": "tradeoffs#one-dependency-deliberately"
        },
        {
          "kind": "value",
          "literal": "github.com",
          "chunkId": "tradeoffs#one-dependency-deliberately"
        }
      ],
      "sources": [
        {
          "chunkId": "tradeoffs#one-dependency-deliberately",
          "url": "/docs/tradeoffs#one-dependency-deliberately",
          "anchor": "one-dependency-deliberately"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "dependency",
        "deliberately",
        "aims",
        "near",
        "zero",
        "deliberate",
        "exception",
        "heading",
        "slugger",
        "tiny",
        "pure",
        "edge",
        "safe",
        "library",
        "generating",
        "anchors",
        "hand",
        "risks",
        "drifting",
        "renderer",
        "shipping",
        "link",
        "404s",
        "page",
        "same",
        "uses",
        "guarantees",
        "byte",
        "identical",
        "framework",
        "adapters",
        "extending",
        "guarantee",
        "their",
        "slug",
        "rules",
        "taken",
        "purpose",
        "github",
        "close"
      ]
    },
    {
      "id": "tradeoffs#two-paths-instead-of-one",
      "kind": "section",
      "title": "Tradeoffs",
      "heading": "Two paths instead of one",
      "group": "Overview",
      "url": "/docs/tradeoffs#two-paths-instead-of-one",
      "summary": "hev ask runs an instant keyword path and an agentic path and asks the reader to choose between them by pressing Enter. The upside is that the common case of a word or two stays instant and keyless while hard questions get a smarter ranker; the cost is a slightly more complex interaction model than a single search box, since readers must learn that Enter means asking AI, which the page argues is the right trade for docs where queries split between jumping to a known thing and finding an unnameable one.",
      "hash": "e48be674eb6b12550ce9b63172698290c2dfd2eff74eec7bf157321de76f4d67",
      "facts": [],
      "sources": [
        {
          "chunkId": "tradeoffs#two-paths-instead-of-one",
          "url": "/docs/tradeoffs#two-paths-instead-of-one",
          "anchor": "two-paths-instead-of-one"
        }
      ],
      "mode": "agent-primary",
      "terms": [
        "paths",
        "instead",
        "runs",
        "instant",
        "keyword",
        "path",
        "agentic",
        "asks",
        "reader",
        "choose",
        "between",
        "pressing",
        "enter",
        "upside",
        "common",
        "case",
        "word",
        "stays",
        "keyless",
        "while",
        "hard",
        "questions",
        "smarter",
        "ranker",
        "cost",
        "slightly",
        "more",
        "complex",
        "interaction",
        "model",
        "single",
        "search",
        "since",
        "readers",
        "must",
        "learn",
        "means",
        "asking",
        "page",
        "argues"
      ]
    }
  ],
  "edges": []
}
esc