The ONE corpus behind the two discovery verbs.
The sandbox answers exactly two questions about itself, and this namespace holds the documents both of them read:
apropos(query) SEARCHES — ranked full text over every document the
session can reach.doc(target) RETRIEVES — the one authoritative text for a name.ONE RECORD for every document, whatever seeded it:
{:name "grep" ;; the only handle :text "..." ;; the whole document; its FIRST LINE is the gist :call "grep({"query": …})"} ;; the python that USES it; absent = prose
There is no kind and no group. A taxonomy is not actionable: what a hit
actually needs is the expression that uses it, so call is the field and it
spells the vocabulary out — a function answers grep({"query": …}), an MCP tool
answers mcp__call("server", "tool", {…}), and a skill or a documentation
page answers NOTHING, because a missing call is exactly "this is prose,
read it".
There is no stored gist either. Two texts for one entry are two places to
drift, invisibly, because nothing reads both at once: gist is a RENDERING
of the first line, so the index prints first lines and doc prints the whole
thing from the SAME string.
Sources are REGISTERED, never required in: documentation pages and skills
are seeded here because both are leaves; the MCP catalogue registers itself
from foundation.mcp.core, which sits above this namespace. A fifth source
is a new seeder, not a new verb.
Function contracts (sandbox verbs, shims, language tools) are NOT seeded
here — they come off the live extension registry inside env-python, which
merges them over these entries so a callable name always wins a collision.
The ONE corpus behind the two discovery verbs.
The sandbox answers exactly two questions about itself, and this namespace
holds the documents both of them read:
- `apropos(query)` SEARCHES — ranked full text over every document the
session can reach.
- `doc(target)` RETRIEVES — the one authoritative text for a name.
ONE RECORD for every document, whatever seeded it:
{:name "grep" ;; the only handle
:text "..." ;; the whole document; its FIRST LINE is the gist
:call "grep({"query": …})"} ;; the python that USES it; absent = prose
There is no `kind` and no `group`. A taxonomy is not actionable: what a hit
actually needs is the expression that uses it, so `call` is the field and it
spells the vocabulary out — a function answers `grep({"query": …})`, an MCP tool
answers `mcp__call("server", "tool", {…})`, and a skill or a documentation
page answers NOTHING, because a missing `call` is exactly "this is prose,
read it".
There is no stored `gist` either. Two texts for one entry are two places to
drift, invisibly, because nothing reads both at once: `gist` is a RENDERING
of the first line, so the index prints first lines and `doc` prints the whole
thing from the SAME string.
Sources are REGISTERED, never required in: documentation pages and skills
are seeded here because both are leaves; the MCP catalogue registers itself
from `foundation.mcp.core`, which sits above this namespace. A fifth source
is a new seeder, not a new verb.
Function contracts (sandbox verbs, shims, language tools) are NOT seeded
here — they come off the live extension registry inside `env-python`, which
merges them over these entries so a callable name always wins a collision.What doc() prints: a hand-ordered short list of the verbs a session starts
from, NOT a dump. Sixty functions plus every page plus every skill is just
another prompt; anything off this list stays discoverable through
apropos(text), which is the whole point of dropping the schemas. A name
that is not in the corpus is simply skipped, so this vector never has to
track which extensions are active.
What `doc()` prints: a hand-ordered short list of the verbs a session starts from, NOT a dump. Sixty functions plus every page plus every skill is just another prompt; anything off this list stays discoverable through `apropos(text)`, which is the whole point of dropping the schemas. A name that is not in the corpus is simply skipped, so this vector never has to track which extensions are active.
(entries)The whole corpus, in registration order, deduplicated by name (first wins). A source that throws contributes nothing — discovery must never be the reason an env fails to build.
The whole corpus, in registration order, deduplicated by name (first wins). A source that throws contributes nothing — discovery must never be the reason an env fails to build.
(entry-text entry)(entry-text {:keys [name text call]} note)What doc(target) answers for one entry: the handle, the expression that
uses it when there is one, then the WHOLE document. note is the caller's
one-word remark about the handle (env-python marks a live callable).
What `doc(target)` answers for one entry: the handle, the expression that uses it when there is one, then the WHOLE document. `note` is the caller's one-word remark about the handle (`env-python` marks a live callable).
(gist text)(gist text max-len)The FIRST LINE of text, as a one-liner: leading markdown heading marks are
dropped (a page's first line is its # Title) and the result is capped at
gist-max-len — or at max-len, which the curated index tightens so twenty
rows stay scannable. This is the only place a gist exists — never a stored
field.
The FIRST LINE of `text`, as a one-liner: leading markdown heading marks are dropped (a page's first line is its `# Title`) and the result is capped at `gist-max-len` — or at `max-len`, which the curated index tightens so twenty rows stay scannable. This is the only place a gist exists — never a stored field.
(index-text es)What bare doc() answers: the curated verbs that are actually present, one
name — first line per row, then the sentence that says where the rest is.
Never a dump — everything off curated is one apropos(text) away.
What bare `doc()` answers: the curated verbs that are actually present, one `name — first line` per row, then the sentence that says where the rest is. Never a dump — everything off `curated` is one `apropos(text)` away.
(miss-text es target)What doc(target) answers when nothing carries that handle: the closest hits
for the SAME string, so a near-miss costs one call instead of two.
What `doc(target)` answers when nothing carries that handle: the closest hits for the SAME string, so a near-miss costs one call instead of two.
(normalize-name target)Coerce a caller's target to a comparable handle: unwrap the map/kwargs shape,
trim, drop a trailing .md (pages cross-link by filename), lower-case. This
is why doc("Gateway.md") and doc("gateway") are the same ask.
Coerce a caller's target to a comparable handle: unwrap the map/kwargs shape,
trim, drop a trailing `.md` (pages cross-link by filename), lower-case. This
is why `doc("Gateway.md")` and `doc("gateway")` are the same ask.(register-source! id f)Register f — a 0-arity returning a coll of :vis.doc/entry — under id.
Re-registering an id replaces it IN PLACE, so a reloaded namespace never
duplicates its own entries.
Register `f` — a 0-arity returning a coll of `:vis.doc/entry` — under `id`. Re-registering an `id` replaces it IN PLACE, so a reloaded namespace never duplicates its own entries.
(search es query)Rank es against query: whitespace-separated terms are ANDed, and every
term scores where it hit — an exact name beats a name substring beats the
first line beats the body. Ties break on name, so the order is stable.
A blank query is not a failure, it is "everything": the whole corpus, in name order.
Rank `es` against `query`: whitespace-separated terms are ANDed, and every term scores where it hit — an exact name beats a name substring beats the first line beats the body. Ties break on name, so the order is stable. A blank query is not a failure, it is "everything": the whole corpus, in name order.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |