Liking cljdoc? Tell your friends :D

com.blockether.vis.internal.extension

Extension subsystem: spec, builders, hook execution, the global registry, parse-error rescue, and manifest namespace catalog.

An extension is the SINGLE entry point for everything a third-party bundle contributes to vis. Whatever surfaces it populates - Python sandbox symbols, CLI commands, channels, providers, persistence backends - it does so by listing them in the matching :ext/<surface> slot, and register-extension! dispatches each slot to its concrete sub-registry. The same data feeds:

  • the active-extensions list every iteration consults
  • the system-prompt block rendered from :ext.engine/symbols
  • the per-iteration :ext/hooks checks
  • the parse-error rescue chain
  • the manifest id/namespace catalog used for extension metadata

Channel and provider registries live in internal.registry (the sub-registry that lights up when this module dispatches their contributions). Backend dispatch lives in internal.persistance. Classpath manifest scanning lives in internal.manifest. This module is the only consumer of all four.

Extension subsystem: spec, builders, hook execution, the global
registry, parse-error rescue, and manifest namespace catalog.

An extension is the SINGLE entry point for everything a third-party
bundle contributes to vis. Whatever surfaces it populates - Python
sandbox symbols, CLI commands, channels, providers, persistence
backends - it does so by listing them in the matching `:ext/<surface>`
slot, and `register-extension!` dispatches each slot to its concrete
sub-registry. The same data feeds:

  - the active-extensions list every iteration consults
  - the system-prompt block rendered from `:ext.engine/symbols`
  - the per-iteration `:ext/hooks` checks
  - the parse-error rescue chain
  - the manifest id/namespace catalog used for extension metadata

Channel and provider registries live in `internal.registry` (the
sub-registry that lights up when this module dispatches their
contributions). Backend dispatch lives in `internal.persistance`.
Classpath manifest scanning lives in `internal.manifest`. This
module is the only consumer of all four.
raw docstring

*current-extension*clj

Extension map currently executing on an extension callback thread. Bound by symbol wrappers so extension-owned helper APIs can fill the caller's stable extension identity without accepting user-supplied ids.

Extension map currently executing on an extension callback thread.
Bound by symbol wrappers so extension-owned helper APIs can fill the
caller's stable extension identity without accepting user-supplied ids.
sourceraw docstring

*current-form-idx*clj

Zero-based index of the top-level form currently evaluating, bound per-form by run-python-code so the render sink writer can stamp :form-idx on every entry.

The render sink atom itself is iteration-scoped (one channel-sink per run-python-code invocation, fed by every tool call in the block, which runs as one whole-block coroutine).

Zero-based index of the top-level form currently evaluating, bound
per-form by `run-python-code` so the render sink writer can stamp
`:form-idx` on every entry.

The render sink atom itself is iteration-scoped (one channel-sink
per `run-python-code` invocation, fed by every tool call in the
block, which runs as one whole-block coroutine).
sourceraw docstring

*current-symbol*clj

Sandbox symbol currently executing, when a symbol callback is active.

Sandbox symbol currently executing, when a symbol callback is active.
sourceraw docstring

*tool-event-sink*clj

Optional per-eval sink for observable tool lifecycle events. Bound by tests and UI/progress adapters that need to know a tool started before its fn returns. The sink receives plain event maps.

Optional per-eval sink for observable tool lifecycle events. Bound by
tests and UI/progress adapters that need to know a tool started before
its fn returns. The sink receives plain event maps.
sourceraw docstring

active-protected-globsclj

(active-protected-globs environment)

Aggregate protected path rules from active extensions in extension order.

Each active extension may declare :ext/protected-paths as (fn [env] -> [{:glob string :access :read-only|:read-write|:none :hint string} ...]). Rule order is preserved within each extension; the foundation editing core resolves first-match-wins per extension and most-restrictive-wins globally. Returned rows are enriched with :extension/name for diagnostics.

Aggregate protected path rules from active extensions in extension order.

Each active extension may declare `:ext/protected-paths` as
`(fn [env] -> [{:glob string :access :read-only|:read-write|:none
                :hint string} ...])`. Rule order is preserved within
each extension; the foundation editing core resolves first-match-wins
per extension and most-restrictive-wins globally. Returned rows are
enriched with `:extension/name` for diagnostics.
sourceraw docstring

assert-tool-result!clj

(assert-tool-result! x)
source

builtin-sandbox-bindingsclj

(builtin-sandbox-bindings env-thunk)

{sym -> fn} bindings for EVERY registered built-in extension (ext-builtin?), merged into the Python sandbox globals alongside the engine verbs at sandbox-context creation. env-thunk (0-arg) resolves the live environment at call time, so these can be wired before the env map exists. Loads built-ins first (idempotent) so registration is guaranteed before we read the registry. Later extensions win on key collisions, but built-ins are disjoint by construction (kernel tools vs engine verbs).

Each value is the plain wrapped tool fn; env_python/create-python-context installs it as a Python callable (ProxyExecutable). Per-tool docstrings are surfaced through the sandbox's own doc/apropos introspection.

`{sym -> fn}` bindings for EVERY registered built-in extension
(`ext-builtin?`), merged into the Python sandbox globals alongside the engine
verbs at sandbox-context creation. `env-thunk` (0-arg) resolves the live
environment at call time, so these can be wired before the env map exists.
Loads built-ins first (idempotent) so registration is guaranteed before we
read the registry. Later extensions win on key collisions, but built-ins are
disjoint by construction (kernel tools vs engine verbs).

Each value is the plain wrapped tool fn; `env_python/create-python-context`
installs it as a Python callable (ProxyExecutable). Per-tool docstrings are
surfaced through the sandbox's own `doc`/`apropos` introspection.
sourceraw docstring

canonical-hook-lifetimesclj

Hook-task lifetime policies. Controls how long an emitted hook-task lingers in :session/tasks after the hint stops firing.

:session Default. Task survives across turns and is GC'd by the standard TTL machinery (TTL-TASK-DONE/ TTL-TASK-CANCELLED turns after terminal status). Right for cross-turn concerns like :vis.foundation/session-title whose work product (the session title) is itself session-scoped.

:turn Ephemeral. Task is dropped from :session/tasks at advance-turn regardless of status. If the originating hint condition still holds, the next iter recreates the task; if not, it stays gone. Right for transient signals like :vis.foundation/context-pressure whose advisory value evaporates the moment the next request's input size drops below threshold. Prevents the cargo-cult pattern where a stale :done :validated? false task keeps showing up in the CTX render for 6 turns and the model keeps re-emitting (task-set! … :done) to silence it.

:iteration Hyper-transient. Task is dropped at advance-iter (every iter boundary), not just turn boundary. Right for hints whose firing condition is recomputed from per-iter state (e.g. a one-iter retry-shape warning, an in-flight tool-call status banner). The next iter's hook fire is the single source of truth; if the condition still holds the task re-materialises immediately.

Hook-task lifetime policies. Controls how long an emitted hook-task
lingers in `:session/tasks` after the hint stops firing.

  :session    Default. Task survives across turns and is GC'd by the
              standard TTL machinery (`TTL-TASK-DONE`/
              `TTL-TASK-CANCELLED` turns after terminal status). Right
              for cross-turn concerns like
              `:vis.foundation/session-title` whose work product (the
              session title) is itself session-scoped.

  :turn       Ephemeral. Task is dropped from `:session/tasks` at
              `advance-turn` regardless of status. If the originating
              hint condition still holds, the next iter recreates the
              task; if not, it stays gone. Right for transient signals
              like `:vis.foundation/context-pressure` whose advisory
              value evaporates the moment the next request's input
              size drops below threshold. Prevents the cargo-cult
              pattern where a stale `:done :validated? false` task
              keeps showing up in the CTX render for 6 turns and the
              model keeps re-emitting `(task-set! … :done)` to silence
              it.

  :iteration  Hyper-transient. Task is dropped at `advance-iter`
              (every iter boundary), not just turn boundary. Right
              for hints whose firing condition is recomputed from
              per-iter state (e.g. a one-iter retry-shape warning,
              an in-flight tool-call status banner). The next iter's
              hook fire is the single source of truth; if the
              condition still holds the task re-materialises
              immediately.
sourceraw docstring

canonical-hook-phasesclj

Canonical namespaced lifecycle phases accepted by :ext/hooks.

Canonical namespaced lifecycle phases accepted by `:ext/hooks`.
sourceraw docstring

channel-contributions-forclj

(channel-contributions-for channel-id)
(channel-contributions-for channel-id slot)

Return registered extension channel contributions for channel-id in extension registration order. With slot, return only contributions for that channel slot. Contributions are passive data; the channel owns each slot's fn arity + return contract.

Return registered extension channel contributions for `channel-id` in
extension registration order. With `slot`, return only contributions for
that channel slot. Contributions are passive data; the channel owns each
slot's fn arity + return contract.
sourceraw docstring

ctx-contributionsclj

(ctx-contributions environment active-extensions)

Return merged structured ctx contributions for active extensions.

Each active extension may declare :ext/ctx-fn as (fn [env] -> map). The contribution CONTRACT is STRING-KEYED: top-level keys are the folded session_* strings ("session_env", "session_workspace", ...) and values are string-keyed all the way down — the merged map crosses the Python boundary as the model's session dict, which throws on any keyword key/value. This fn only aggregates (deep-merge); producers own the keys. Exceptions and non-map returns are logged and ignored so bad optional context never blocks a turn.

Return merged structured `ctx` contributions for active extensions.

Each active extension may declare `:ext/ctx-fn` as `(fn [env] -> map)`.
The contribution CONTRACT is STRING-KEYED: top-level keys are the
folded `session_*` strings (`"session_env"`, `"session_workspace"`, ...)
and values are string-keyed all the way down — the merged map crosses the
Python boundary as the model's `session` dict, which throws on any keyword
key/value. This fn only aggregates (deep-merge); producers own the keys.
Exceptions and non-map returns are logged and ignored so bad optional
context never blocks a turn.
sourceraw docstring

current-extensionclj

(current-extension)
source

current-extension-idclj

(current-extension-id)
source

deregister-extension!clj

(deregister-extension! ns-sym)

Drop an extension from the global registry AND reverse every side effect register-extension! dispatched: deregister each CLI subcommand, channel, provider, and persistence backend. Returns nil.

Plan caveat: side-effect cleanup on :removed extensions. Used by Stays available for diagnostic surfaces.

Drop an extension from the global registry AND reverse every side
effect `register-extension!` dispatched: deregister each CLI
subcommand, channel, provider, and persistence backend. Returns nil.

Plan caveat: side-effect cleanup on `:removed` extensions. Used by
Stays available for diagnostic surfaces.
sourceraw docstring

discover-extensions!clj

(discover-extensions!)

Public entry point for vis's extension wiring.

First loads the BUILT-IN extensions (load-builtin-extensions! — core modules like the foundation v/ kernel that register via the same API but ship in the main jar). Then runs manifest/scan-extensions! (which scans every META-INF/vis-extension/vis.edn, requires every namespace listed under each manifest's :nses key, and returns the merged parsed manifests) and merges those manifests into this namespace's manifest registry. Returns the count of namespaces declared under :nses across the merged manifests.

Idempotent on every layer.

Public entry point for vis's extension wiring.

First loads the BUILT-IN extensions (`load-builtin-extensions!` — core
modules like the foundation `v/` kernel that register via the same API but
ship in the main jar). Then runs `manifest/scan-extensions!` (which scans
every `META-INF/vis-extension/vis.edn`, `require`s every namespace listed
under each manifest's `:nses` key, and returns the merged parsed manifests)
and merges those manifests into this namespace's manifest registry. Returns
the count of namespaces declared under `:nses` across the merged manifests.

Idempotent on every layer.
sourceraw docstring

envelope-failure?clj

(envelope-failure? envelope)

True when envelope is an :envelope and :success? is false (i.e. failure path with a structured :error). Returns false for non-envelopes.

True when `envelope` is an `:envelope` and `:success?` is
false (i.e. failure path with a structured `:error`). Returns
false for non-envelopes.
sourceraw docstring

envelope-success?clj

(envelope-success? envelope)

True when envelope is an :envelope and :success? is true. Use this instead of raw (:success? e) in renderers and guards — it (a) reads as English and (b) returns false for non- envelopes (defensive against shape drift).

True when `envelope` is an `:envelope` and `:success?` is
true. Use this instead of raw `(:success? e)` in renderers and
guards — it (a) reads as English and (b) returns false for non-
envelopes (defensive against shape drift).
sourceraw docstring

ex->op-errorclj

(ex->op-error t & [{:keys [form-source hint]}])

Convert an arbitrary Throwable to a structured :error map.

Output shape: {:message <one-line headline, required> :trace <preformatted multi-line string, optional> :hint <recovery suggestion, optional> :block {:source :phase :row :col :opened-loc?, optional}}

Throwables reaching here are transport / spec / wrapping failures — Python eval errors are mapped to op-error shape inside the engine via env-python/map-polyglot-error, so the block :phase is :preflight.

Optional opts: :form-source the verbatim source the form was built from; embedded in :block.source so the model sees its own input echoed back. :hint override / pre-supply a recovery hint string.

Convert an arbitrary `Throwable` to a structured `:error` map.

Output shape:
  {:message <one-line headline, required>
   :trace   <preformatted multi-line string, optional>
   :hint    <recovery suggestion, optional>
   :block   {:source :phase :row :col :opened-loc?, optional}}

Throwables reaching here are transport / spec / wrapping failures —
Python eval errors are mapped to op-error shape inside the engine via
`env-python/map-polyglot-error`, so the block `:phase` is `:preflight`.

Optional opts:
  :form-source  the verbatim source the form was built from;
                 embedded in `:block.source` so the model sees its
                 own input echoed back.
  :hint          override / pre-supply a recovery hint string.
sourceraw docstring

ext-aliasclj

(ext-alias ext)
source

ext-alias-symbolclj

(ext-alias-symbol ext)
source

ext-builtin?clj

(ext-builtin? ext)

True when this extension is a BUILT-IN: its symbols bind BARE into the sandbox ns (no alias), alongside the engine verbs. See builtin-sandbox-bindings.

True when this extension is a BUILT-IN: its symbols bind BARE into the
sandbox ns (no alias), alongside the engine verbs. See
`builtin-sandbox-bindings`.
sourceraw docstring

ext-classesclj

(ext-classes ext)
source

ext-display-nameclj

(ext-display-name ext)
source

ext-engineclj

(ext-engine ext)
source

ext-engine-nsclj

(ext-engine-ns ext)
source

ext-importsclj

(ext-imports ext)
source

ext-sandbox-shimsclj

(ext-sandbox-shims ext)
source

ext-source-nsesclj

(ext-source-nses ext)
source

ext-symbolsclj

(ext-symbols ext)
source

extensionclj

(extension spec)

Build and validate an extension. The canonical constructor.

See docs/src/extensions/extension-spec.md for the full key list.

Build and validate an extension. The canonical constructor.

See docs/src/extensions/extension-spec.md for the full key list.
sourceraw docstring

extension-id-of-nsclj

(extension-id-of-ns ns-sym)

Reverse lookup: given a namespace symbol, return the extension id that registered it under :nses, or nil.

Reverse lookup: given a namespace symbol, return the extension id
that registered it under `:nses`, or `nil`.
sourceraw docstring

extension-infoclj

(extension-info ext)

Canonical extension info map.

Merges author-declared extension metadata with source markers: {:namespace :alias? :doc? :kind? :version? :author? :owner? :license? :registry-id? :source-paths :source-mtime-max :source-hash-sha256}

This is the single info shape used by ctx :extensions and tool-result enrichment.

Canonical extension info map.

Merges author-declared extension metadata with source markers:
  {:namespace :alias? :doc? :kind? :version? :author? :owner?
   :license? :registry-id? :source-paths :source-mtime-max
   :source-hash-sha256}

This is the single info shape used by ctx :extensions and tool-result enrichment.
sourceraw docstring

extension-namespacesclj

(extension-namespaces id)

Vector of namespaces declared under :nses for an id. Empty when the id is unknown.

Vector of namespaces declared under `:nses` for an id. Empty when
the id is unknown.
sourceraw docstring

extension-source-markers-ofclj

(extension-source-markers-of ns-sym)

Lookup the source markers stored for ns-sym. Returns the marker map ({:source-paths :source-mtime-max :source-hash-sha256}) or nil when the extension was never registered (or its markers computation failed at register time).

Lookup the source markers stored for `ns-sym`. Returns the marker
map (`{:source-paths :source-mtime-max :source-hash-sha256}`) or
nil when the extension was never registered (or its markers
computation failed at register time).
sourceraw docstring

failureclj

(failure {:keys [error throwable] :as args})

Construct a failing tool-result envelope. :throwable auto-builds an :error map via normalize-error. Explicit :error (already structured) wins.

Construct a failing tool-result envelope. `:throwable` auto-builds
an `:error` map via `normalize-error`. Explicit `:error`
(already structured) wins.
sourceraw docstring

helperclj

(helper v)
(helper v opts)

Build a raw callable helper entry FROM A CLOJURE VAR.

Helpers are bound as plain values in Python, not observed tools: no envelope validation, no channel renderer. Use for composable host helper functions such as snapshot, not for user-observable tool calls.

Build a raw callable helper entry FROM A CLOJURE VAR.

Helpers are bound as plain values in Python, not observed tools: no envelope
validation, no channel renderer. Use for composable host helper functions
such as `snapshot`, not for user-observable tool calls.
sourceraw docstring

hook-lifetime?clj

(hook-lifetime? lifetime)

True when lifetime is one of the canonical hook-task lifetimes.

True when `lifetime` is one of the canonical hook-task lifetimes.
sourceraw docstring

hook-phase?clj

(hook-phase? phase)

True when phase is a canonical namespaced hook phase.

True when `phase` is a canonical namespaced hook phase.
sourceraw docstring

invoke-symbol-wrapperclj

(invoke-symbol-wrapper ext sym-entry args env)

Full invocation pipeline for an observed tool symbol entry: before-fn -> fn -> after-fn, with on-error-fn catching :fn errors.

Every hook can override :fn, :args, :env via its return map. :before-fn can return {:result val} to short-circuit. :on-error-fn can return {:result val}, {:error err}, or {:fn :args :env} to retry.

The implementation's final value must be a canonical internal envelope. The wrapper records channel/provenance from that envelope, then returns only the payload :result to Python. Failure envelopes are converted into thrown ex-info so ordinary Python error reporting handles them.

Raw helper symbols (:ext.symbol/raw? true) bypass this function entirely.

Full invocation pipeline for an observed tool symbol entry:
before-fn -> fn -> after-fn, with on-error-fn catching :fn errors.

Every hook can override :fn, :args, :env via its return map.
:before-fn can return {:result val} to short-circuit.
:on-error-fn can return {:result val}, {:error err}, or {:fn :args :env} to retry.

The implementation's final value must be a canonical internal envelope.
The wrapper records channel/provenance from that envelope, then
returns only the payload `:result` to Python. Failure envelopes are converted
into thrown ex-info so ordinary Python error reporting handles them.

Raw helper symbols (`:ext.symbol/raw? true`) bypass this function entirely.
sourceraw docstring

load-extension!clj

(load-extension! ns-sym)

Dynamically load extension namespace and return extensions it registered.

Dynamically load extension namespace and return extensions it registered.
sourceraw docstring

merge-into-metadataclj

(merge-into-metadata envelope extra)

Merge extra into the :metadata slot of an already-valid envelope, re-check the contract, and preserve metadata. Used by the extension wrapper to stamp extension/source info onto tool-like returns.

Merge `extra` into the `:metadata` slot of an already-valid
envelope, re-check the contract, and preserve metadata. Used by the
extension wrapper to stamp extension/source info onto tool-like
returns.
sourceraw docstring

native-tool-call-shapesclj

(native-tool-call-shapes active-extensions)
(native-tool-call-shapes active-extensions env)

Map wire-name → the symbol's :call synthesis shape (a shape map or a (fn [input] -> source)) for every ACTIVE native tool that declares one. tool-call->python-source consults this to build the Python a tool call runs; a tool with no :call is ABSENT here and falls back to the generic name({input}) form. Single source — the shape lives WITH its symbol, so a new module's tool needs NO engine edit.

Map wire-name → the symbol's `:call` synthesis shape (a shape map or a
`(fn [input] -> source)`) for every ACTIVE native tool that declares one.
`tool-call->python-source` consults this to build the Python a tool call runs;
a tool with no `:call` is ABSENT here and falls back to the generic
`name({input})` form. Single source — the shape lives WITH its symbol, so a new
module's tool needs NO engine edit.
sourceraw docstring

native-tool-color-rolesclj

(native-tool-color-roles active-extensions)

Map wire-name → :color-role keyword (read / search / edit / …) for every declared native tool — the per-tool result-badge colour. NOT active-filtered (mirrors renderers).

Map wire-name → `:color-role` keyword (read / search / edit / …) for every
declared native tool — the per-tool result-badge colour. NOT active-filtered
(mirrors renderers).
sourceraw docstring

native-tool-handlersclj

(native-tool-handlers active-extensions)
(native-tool-handlers active-extensions env)

Map wire-name → :handler (fn [env input] -> result) for every ACTIVE native tool that declares one. A handler tool is dispatched DIRECTLY in Clojure by the loop (no synthesized Python); one without runs the legacy synthesized-Python path. Inactive (:active-fn false) tools are excluded — unadvertised ⇒ undispatchable.

Map wire-name → `:handler` `(fn [env input] -> result)` for every ACTIVE native
tool that declares one. A handler tool is dispatched DIRECTLY in Clojure by the
loop (no synthesized Python); one without runs the legacy synthesized-Python
path. Inactive (`:active-fn` false) tools are excluded — unadvertised ⇒
undispatchable.
sourceraw docstring

native-tool-renderersclj

(native-tool-renderers active-extensions)

Map wire-name → :render fn for every declared native tool. A :render takes the tool's RESULT and returns a {:summary :body} op-card both the TUI and web paint — a clean card, never a raw args+result dump. NOT active-filtered: a result that already ran must still render even if its toggle flipped after.

Map wire-name → `:render` fn for every declared native tool. A `:render` takes
the tool's RESULT and returns a `{:summary :body}` op-card both the TUI and web
paint — a clean card, never a raw args+result dump. NOT active-filtered: a
result that already ran must still render even if its toggle flipped after.
sourceraw docstring

native-tool-renderers-by-opclj

(native-tool-renderers-by-op active-extensions)

Map op-STRING (the value stamp-public-result-op writes into a result's :op, e.g. "cat") -> {:render :color-role}. Resolves the op-card of a TOOL RESULT the model print()ed in Python, where the only origin handle is :op. Mirrors native-tool-renderers (NOT active-filtered: a printed result must still render even if its toggle flipped).

Map op-STRING (the value `stamp-public-result-op` writes into a result's `:op`,
e.g. "cat") -> `{:render :color-role}`. Resolves the op-card of a TOOL RESULT
the model print()ed in Python, where the only origin handle is `:op`. Mirrors
`native-tool-renderers` (NOT active-filtered: a printed result must still render
even if its toggle flipped).
sourceraw docstring

native-tool-schemasclj

(native-tool-schemas active-extensions)
(native-tool-schemas active-extensions env)

The model-facing :tools surface: {:name :description :schema} for every ACTIVE native tool, in extension/symbol order. Single source — schema lives WITH its symbol.

The model-facing `:tools` surface: `{:name :description :schema}` for every
ACTIVE native tool, in extension/symbol order. Single source — schema lives
WITH its symbol.
sourceraw docstring

native-tool-tagsclj

(native-tool-tags active-extensions)

Map wire-name → :tag (:observation | :mutation) for every declared native tool that carries a :tag. The tag is the AUTHORITATIVE observation/mutation classification declared INLINE on each (vis/symbol …) opts map (never a hardcoded name list). Used by the loop to decide whether an all-observation iteration may run its calls concurrently. NOT active-filtered (mirrors native-tool-color-roles): the classification of a tool never depends on whether its toggle is currently on.

Map wire-name → `:tag` (`:observation | :mutation`) for every declared native
tool that carries a `:tag`. The tag is the AUTHORITATIVE observation/mutation
classification declared INLINE on each `(vis/symbol …)` opts map (never a
hardcoded name list). Used by the loop to decide whether an all-observation
iteration may run its calls concurrently. NOT active-filtered (mirrors
`native-tool-color-roles`): the classification of a tool never depends on
whether its toggle is currently on.
sourceraw docstring

native-tools-forclj

(native-tools-for active-extensions)
(native-tools-for active-extensions env)

Every native tool on active-extensions' symbols — ONE walk, the single source the schemas / handlers / renderers / colours all project from, NORMALIZED to {:name :description :schema :handler :render :color-role :active?}.

A symbol IS a native tool IFF it declares :native-tool? true (which REQUIRES :schema). Every field is FLAT on the symbol — no legacy :native-tool map. :description defaults to the symbol's :doc so the schema description and the docstring are ONE source. :name is the :name wire-name override else the symbol name (so exists? advertises file_exists). :active? is the :active-fn against env (default true). env may be nil.

Every native tool on `active-extensions`' symbols — ONE walk, the single source
the schemas / handlers / renderers / colours all project from, NORMALIZED to
`{:name :description :schema :handler :render :color-role :active?}`.

A symbol IS a native tool IFF it declares `:native-tool? true` (which REQUIRES
`:schema`). Every field is FLAT on the symbol — no legacy `:native-tool` map.
`:description` defaults to the symbol's `:doc` so the schema description and the
docstring are ONE source. `:name` is the `:name` wire-name override else the
symbol name (so `exists?` advertises `file_exists`). `:active?` is the
`:active-fn` against `env` (default true). `env` may be nil.
sourceraw docstring

normalize-errorclj

(normalize-error t)

Build a structured :error map from a Throwable. Required :message; optional :trace (preformatted string including header + frames). :hint and :block are tool/engine- supplied via merge-into-metadata style updates after construction.

Build a structured `:error` map from a Throwable.
Required `:message`; optional `:trace` (preformatted string
including header + frames). `:hint` and `:block` are tool/engine-
supplied via `merge-into-metadata` style updates after
construction.
sourceraw docstring

normalize-metadataclj

(normalize-metadata metadata)

Fill timing keys on the :metadata map when absent. Returns a metadata map (NOT an envelope). The envelope wraps the result of this fn under :metadata.

Timing keys (always populated): :started-at-ms :finished-at-ms :duration-ms

Callers may pass richer maps (tool / extension / source metadata, tool-specific :paths / :hit-count / :command); this helper only normalizes the shared timing surface.

Fill timing keys on the `:metadata` map when absent. Returns a
metadata map (NOT an envelope). The envelope wraps the result of
this fn under `:metadata`.

Timing keys (always populated):
  :started-at-ms  :finished-at-ms  :duration-ms

Callers may pass richer maps (tool / extension / source metadata,
tool-specific :paths / :hit-count / :command); this helper only
normalizes the shared timing surface.
sourceraw docstring

normalize-prompt-textclj

(normalize-prompt-text text)

Normalize model-facing prompt text.

Removes source indentation from multiline literals, trims leading/trailing blank lines, trims trailing horizontal whitespace, and collapses runs of blank lines to a single blank line.

Normalize model-facing prompt text.

Removes source indentation from multiline literals, trims leading/trailing
blank lines, trims trailing horizontal whitespace, and collapses runs of
blank lines to a single blank line.
sourceraw docstring

normalize-traceclj

(normalize-trace t)

Convert a Throwable's stack into the preformatted, babashka-style single-string ::op.error/trace. First line is <ClassName>: <message> (matches babashka error-handler header); subsequent lines are filtered frames (one per line, `class/method

  • file:line`).

Frames in noisy-frame? (clojure.lang reflection, java.lang.reflect, jdk.internal.reflect) are dropped to keep the trace LLM-friendly. Capped at max-trace-frames lines after the header.

Convert a Throwable's stack into the preformatted, babashka-style
single-string `::op.error/trace`. First line is
`<ClassName>: <message>` (matches babashka error-handler header);
subsequent lines are filtered frames (one per line, `class/method
- file:line`).

Frames in `noisy-frame?` (clojure.lang reflection,
java.lang.reflect, jdk.internal.reflect) are dropped to keep the
trace LLM-friendly. Capped at `max-trace-frames` lines after the
header.
sourceraw docstring

op-batch-hint-thresholdclj

(op-batch-hint-threshold op-keyword)

The per-tool high-fan-out batch-hint threshold for op-keyword, or nil when the tool declared no override (callers fall back to the default). Never throws on unknown ops — the hint is advisory, not load-bearing.

The per-tool high-fan-out batch-hint threshold for `op-keyword`, or nil
when the tool declared no override (callers fall back to the default).
Never throws on unknown ops — the hint is advisory, not load-bearing.
sourceraw docstring

op-presentationclj

(op-presentation op)

Engine-owned presentation metadata for a tool's :op keyword: {:tag ...}. Tool wrappers merge this into their :info/:metadata so channels read canonical keys.

Badge LABEL is derived from :tag by the channel, not stored here. Color / glyph / layout remain pure channel concerns.

Engine-owned presentation metadata for a tool's `:op` keyword:
`{:tag ...}`. Tool wrappers merge this into their `:info`/`:metadata`
so channels read canonical keys.

Badge LABEL is derived from `:tag` by the channel, not stored here.
Color / glyph / layout remain pure channel concerns.
sourceraw docstring

op-tagclj

(op-tag op-keyword)

Return the :observation | :mutation tag for op-keyword. Unknown ops fail closed; every symbol must declare :tag inline on its vis/symbol entry.

Return the `:observation | :mutation` tag for `op-keyword`. Unknown
ops fail closed; every symbol must declare `:tag` inline on its
`vis/symbol` entry.
sourceraw docstring

op-tag-indexclj

(op-tag-index)

Read-only snapshot of the canonical op-keyword -> tag map. Lets call-sites that only hold a Python-snake call HEAD (the classify-form-tag resolver in loop.clj, which reads the head off the model's source) fold each registered op to its Python name and recover the tag — there is no vis/symbol handle at that point. Never throws; an unknown head simply misses the folded view.

Read-only snapshot of the canonical op-keyword -> tag map. Lets
call-sites that only hold a Python-snake call HEAD (the
`classify-form-tag` resolver in `loop.clj`, which reads the head off
the model's source) fold each registered op to its Python name and
recover the tag — there is no `vis/symbol` handle at that point.
Never throws; an unknown head simply misses the folded view.
sourceraw docstring

op-tagsclj

Closed set of operation tags a tool can declare. The two values map to the observation/mutation half of the OODA loop. The prior granular enum collapses into these two:

:observation reads state without changing it — cat, ls, exists?, locators, rg, env queries, registry lookups

:mutation mutates state — patch, write, append, mkdir, touch, delete, move, copy.

Channels that want to color tools by tag look it up themselves; the engine never carries presentation in the tool envelope.

Closed set of operation tags a tool can declare. The two values
map to the observation/mutation half of the OODA loop. The prior
granular enum collapses into these two:

  :observation   reads state without changing it — cat,
                        ls, exists?, locators, rg, env
                        queries, registry lookups

  :mutation      mutates state — patch, write, append,
                        mkdir, touch, delete, move, copy.

Channels that want to color tools by tag look it up themselves;
the engine never carries presentation in the tool envelope.
sourceraw docstring

register-extension!clj

(register-extension! ext)

Register an extension in the global process-level registry.

This is THE single entry point for everything an extension contributes to vis. Whatever the extension declares -- Python sandbox symbols (:ext.engine/symbols), CLI commands (:ext/cli), channels (:ext/channels), LLM providers (:ext/providers), persistence backends (:ext/persistance) -- gets routed here and dispatched into the matching sub-registry as a side effect.

Also computes source-file markers (paths, max-mtime, sha256) and stores them in a sidecar atom read by the tool-envelope emitter (UI extension provenance label).

Idempotent on :ext/name. Returns the validated extension.

Register an extension in the global process-level registry.

This is THE single entry point for everything an extension
contributes to vis. Whatever the extension declares -- Python sandbox
symbols (`:ext.engine/symbols`), CLI commands (`:ext/cli`), channels
(`:ext/channels`), LLM providers (`:ext/providers`), persistence
backends (`:ext/persistance`) -- gets routed here and dispatched into
the matching sub-registry as a side effect.

Also computes source-file markers (paths, max-mtime, sha256) and
stores them in a sidecar atom read by the tool-envelope emitter
(UI extension provenance label).

Idempotent on `:ext/name`. Returns the validated extension.
sourceraw docstring

register-extensions!clj

(register-extensions! environment register-fn!)

Install all globally registered extensions into an environment.

Topologically sorts by :ext/requires so dependencies are registered before dependents. Throws on missing dependencies or cycles.

Called by create-environment automatically. Returns environment.

Install all globally registered extensions into an environment.

Topologically sorts by :ext/requires so dependencies are registered
before dependents. Throws on missing dependencies or cycles.

Called by `create-environment` automatically. Returns environment.
sourceraw docstring

register-op-hook!clj

(register-op-hook! {:keys [op phase owner] hook-fn :fn :or {phase :after}})

Register a cross-cutting hook on operation :op (its op-keyword, e.g. :struct_patch). :phase is :after (default — sees & may rewrite the result envelope), :before (sees & may rewrite the args vector), or :around (MIDDLEWARE — wraps the call). :fn is, for :after, (fn [env op-kw args result] -> result-envelope); for :before, (fn [env op-kw args] -> args-vector); for :around, (fn [env op-kw args next] -> result) where next runs the inner call and may be invoked zero+ times (skip / retry) or wrapped in try/catch (recover — this is how an op is made NOT to fail). :owner (an ext keyword) makes the registration idempotent across :reloads — re-registering the same owner+phase for an op REPLACES the prior one. Returns the op-keyword.

Register a cross-cutting hook on operation `:op` (its op-keyword, e.g.
:struct_patch). `:phase` is :after (default — sees & may rewrite the result
envelope), :before (sees & may rewrite the args vector), or :around (MIDDLEWARE
— wraps the call). `:fn` is, for :after, (fn [env op-kw args result] ->
result-envelope); for :before, (fn [env op-kw args] -> args-vector); for
:around, (fn [env op-kw args next] -> result) where `next` runs the inner call
and may be invoked zero+ times (skip / retry) or wrapped in try/catch (recover
— this is how an op is made NOT to fail). `:owner` (an ext keyword) makes the
registration idempotent across `:reload`s — re-registering the same
owner+phase for an op REPLACES the prior one. Returns the op-keyword.
sourceraw docstring

register-reload-hook!clj

(register-reload-hook! id f)

Register a zero-arg f to run on /reload. Idempotent per id — re-registering replaces. Hooks must be cheap and safe to call at any time; a throwing hook is reported, never fatal.

Register a zero-arg `f` to run on `/reload`. Idempotent per `id` —
re-registering replaces. Hooks must be cheap and safe to call at any
time; a throwing hook is reported, never fatal.
sourceraw docstring

registered-extension-idsclj

(registered-extension-ids)

Sorted vector of every extension id known to the manifest registry.

Sorted vector of every extension id known to the manifest registry.
sourceraw docstring

registered-extensionsclj

(registered-extensions)
source

registered-extensions-summaryclj

(registered-extensions-summary)

Pure data view of the manifest registry: returns {<id> {:nses [...]}} for every loaded extension.

Pure data view of the manifest registry: returns `{<id> {:nses [...]}}`
for every loaded extension.
sourceraw docstring

registered-startable-resourcesclj

(registered-startable-resources)

Union of every registered extension's :ext/startable-resources — the declarative resources any channel's Resources UI can start (each with its own label + proposed options + start-fn).

A startable may declare a :visible-fn (() -> bool) to gate its appearance, e.g. behind a feature toggle; non-visible ones are dropped here so EVERY channel's Resources UI (web modal + TUI dialog) hides them uniformly.

Union of every registered extension's `:ext/startable-resources` — the
declarative resources any channel's Resources UI can start (each with its own
label + proposed options + start-fn).

A startable may declare a `:visible-fn` (() -> bool) to gate its appearance,
e.g. behind a feature toggle; non-visible ones are dropped here so EVERY
channel's Resources UI (web modal + TUI dialog) hides them uniformly.
sourceraw docstring

render-promptclj

(render-prompt {:keys [heading usage-note notes] :as opts})

Render canonical :ext/prompt-fn text from symbol docstrings + arglists.

Accepts an extension map or any map with:

  • :ext/description or :heading
  • :ext.engine/alias optional {:alias 'v}
  • :ext.engine/symbols vector of symbol + value entries
  • :usage-note optional extra note added to the heading
  • :notes optional string or seq of extra lines appended verbatim

Returns a prompt string suitable for :ext/prompt-fn.

Render canonical :ext/prompt-fn text from symbol docstrings + arglists.

Accepts an extension map or any map with:
- :ext/description      or :heading
- :ext.engine/alias optional {:alias 'v}
- :ext.engine/symbols  vector of symbol + value entries
- :usage-note   optional extra note added to the heading
- :notes        optional string or seq of extra lines appended verbatim

Returns a prompt string suitable for :ext/prompt-fn.
sourceraw docstring

resolve-markersclj

(resolve-markers ns-syms)

Resolve every namespace in ns-syms to its source on the classpath and compute aggregate markers.

Returns {:source-paths ["..."] ;; sorted entry locators :source-mtime-max long ;; -1 if nothing resolved :source-hash-sha256 "hex"} ;; nil if nothing resolved

Always returns a map (never throws). Per-namespace failures are logged at :warn and skipped; an extension whose nses partially resolve still gets markers from the parts that did.

Resolve every namespace in `ns-syms` to its source on the classpath
and compute aggregate markers.

Returns
  {:source-paths      ["..."]               ;; sorted entry locators
   :source-mtime-max  long                    ;; -1 if nothing resolved
   :source-hash-sha256 "hex"}                ;; nil if nothing resolved

Always returns a map (never throws). Per-namespace failures are
logged at :warn and skipped; an extension whose nses partially
resolve still gets markers from the parts that did.
sourceraw docstring

resolve-markers-for-extensionclj

(resolve-markers-for-extension ext-or-manifest)

Resolve source markers from manifest :nses or extension :ext/source-nses.

Resolve source markers from manifest `:nses` or extension `:ext/source-nses`.
sourceraw docstring

run-reload-hooks!clj

(run-reload-hooks!)

Run every registered reload hook. Returns {id {:ok? bool :error msg}}.

Run every registered reload hook. Returns `{id {:ok? bool :error msg}}`.
sourceraw docstring

sandbox-shimsclj

(sandbox-shims)

Every Python sandbox SHIM contributed across all registered extensions, in registration order (built-ins first). env-python/build-agent-context installs each into the model sandbox Context at creation time — wiring the shim's host :shim/bindings onto the globals, then eval'ing its :shim/preamble — turning a host / JVM capability into an importable Python module. Loads built-ins first (idempotent) so the registry is populated before we read it.

Every Python sandbox SHIM contributed across all registered extensions, in
registration order (built-ins first). `env-python/build-agent-context`
installs each into the model sandbox Context at creation time — wiring the
shim's host `:shim/bindings` onto the globals, then eval'ing its
`:shim/preamble` — turning a host / JVM capability into an importable Python
module. Loads built-ins first (idempotent) so the registry is populated
before we read it.
sourceraw docstring

sandbox-symbol-docsclj

(sandbox-symbol-docs)

Map {sandbox-symbol -> doc-text} for every engine-bound symbol across the registered extensions, keyed by the :ext.symbol/symbol as it is bound in the Python sandbox. doc-text prefers the curated :ext.symbol/description (the model-facing prose the prompt catalog renders) and falls back to the tool var's :ext.symbol/doc docstring.

env_python/build-agent-context seeds the sandbox __vis_docs__ table from this so in-sandbox doc(name) returns the tool's real description instead of a bare name (callable). Loads built-ins first (idempotent) so the registry is populated before we read it. Symbols absent here simply have no doc entry.

Map `{sandbox-symbol -> doc-text}` for every engine-bound symbol across the
registered extensions, keyed by the `:ext.symbol/symbol` as it is bound in
the Python sandbox. `doc-text` prefers the curated `:ext.symbol/description`
(the model-facing prose the prompt catalog renders) and falls back to the
tool var's `:ext.symbol/doc` docstring.

`env_python/build-agent-context` seeds the sandbox `__vis_docs__` table from
this so in-sandbox `doc(name)` returns the tool's real description instead of
a bare `name (callable)`. Loads built-ins first (idempotent) so the registry
is populated before we read it. Symbols absent here simply have no doc entry.
sourceraw docstring

sha256-hexclj

(sha256-hex s)

Hex SHA-256 of a string (UTF-8). The ONE string-digest helper — loop's replay-dedup key and the source-marker hashing share it instead of re-rolling MessageDigest + hex folds.

Hex SHA-256 of a string (UTF-8). The ONE string-digest helper —
loop's replay-dedup key and the source-marker hashing share it
instead of re-rolling MessageDigest + hex folds.
sourceraw docstring

slash-pathclj

(slash-path slash-spec)

Canonical full path vec of a slash spec: parent ++ [name]. Used as the lookup key in internal/slash.clj.

Canonical full path vec of a slash spec: parent ++ [name]. Used as the
lookup key in `internal/slash.clj`.
sourceraw docstring

successclj

(success args)

Construct a successful tool-result envelope. See envelope-of for the call shape. Returns a :envelope map (flat, all metadata under op/*).

Construct a successful tool-result envelope. See `envelope-of` for
the call shape. Returns a `:envelope` map (flat, all metadata
under `op/*`).
sourceraw docstring

symbolclj

(symbol v)
(symbol v opts)

Build a function symbol entry FROM A CLOJURE VAR.

The 3-arg form (symbol sym-name f opts) is a test-friendly direct constructor: pass the sandbox-visible symbol, the implementation fn, and an opts map whose :doc / :arglists are read directly from opts instead of var meta. Production code uses the var form.

The var supplies :symbol (var name), :fn (the var's value), :doc and :arglists (read from var metadata - i.e. the underlying defn's docstring + arglists). Pass it as #'my-tool.

Observed tools return canonical internal envelope maps and must provide a symbol-specific channel renderer. The model-facing surface is the per-iteration trailer (real Python form values); no per-tool model-side render exists.

Raw helpers pass :raw? true and return plain values directly, with no envelope enforcement, channel sink, or tool metadata.

Optional opts: :symbol - override the Python sandbox name (default: var name). :doc-fn - compute doc lazily from (sym v) when the var lacks a docstring (third-party vars only). :raw? - true for plain composable helpers. :tag - REQUIRED :observation | :mutation for observed tools (unless :raw? true). :before-fn :after-fn :on-error-fn

Observed tool functions return canonical internal envelope maps. The wrapper records the envelope, then returns only its payload to Python; failure envelopes are converted into thrown ex-info so Python reports normal errors.

:doc and :arglists ALWAYS come from var metadata — the previous test-only (symbol sym-name f opts) 3-arg form is RETIRED. Tests that want to register an inline fn must defn it first and pass #'the-fn.

See docs/src/extensions/hooks.md for hook semantics.

Build a function symbol entry FROM A CLOJURE VAR.

The 3-arg form `(symbol sym-name f opts)` is a test-friendly direct
constructor: pass the sandbox-visible symbol, the implementation fn, and
an opts map whose `:doc` / `:arglists` are read directly from opts
instead of var meta. Production code uses the var form.

The var supplies `:symbol` (var name), `:fn` (the var's value), `:doc` and
`:arglists` (read from var metadata - i.e. the underlying defn's
docstring + arglists). Pass it as `#'my-tool`.

Observed tools return canonical internal envelope maps and must provide
a symbol-specific channel renderer. The model-facing surface is the
per-iteration trailer (real Python form values); no per-tool model-side
render exists.

Raw helpers pass `:raw? true` and return plain values directly, with no
envelope enforcement, channel sink, or tool metadata.

Optional opts:
  :symbol      - override the Python sandbox name (default: var name).
  :doc-fn      - compute doc lazily from `(sym v)` when the var
                 lacks a docstring (third-party vars only).
  :raw?        - true for plain composable helpers.
  :tag         - REQUIRED `:observation | :mutation` for observed
                 tools (unless `:raw? true`).
  :before-fn :after-fn :on-error-fn

Observed tool functions return canonical internal envelope maps. The
wrapper records the envelope, then returns only its payload to Python; failure
envelopes are converted into thrown ex-info so Python reports normal errors.

`:doc` and `:arglists` ALWAYS come from var metadata — the previous
test-only `(symbol sym-name f opts)` 3-arg form is RETIRED. Tests
that want to register an inline fn must `defn` it first and pass
`#'the-fn`.

See `docs/src/extensions/hooks.md` for hook semantics.
sourceraw docstring

symbol-active?clj

(symbol-active? e env)

Whether a symbol ENTRY is LIVE for env this iteration. Default true; an :active-fn (fn [env] -> bool) makes it dynamic (e.g. a sub-toggle). env may be nil — toggle-style predicates ignore it.

Whether a symbol ENTRY is LIVE for `env` this iteration. Default true; an
`:active-fn (fn [env] -> bool)` makes it dynamic (e.g. a sub-toggle). `env` may
be nil — toggle-style predicates ignore it.
sourceraw docstring

symbol-bound?clj

(symbol-bound? e)

Whether a symbol ENTRY is ENGINE-BOUND (bound into the GraalPy env as a Python verb). Default true; :engine-bound? false (native-tool-only verbs, e.g. skill) opts out — they never become a Python name; their :handler executes directly.

Whether a symbol ENTRY is ENGINE-BOUND (bound into the GraalPy env as a Python
verb). Default true; `:engine-bound? false` (native-tool-only verbs, e.g. skill)
opts out — they never become a Python name; their `:handler` executes directly.
sourceraw docstring

tool-result?clj

(tool-result? x)

True when x is a valid :envelope map. Renamed conceptually; name kept for caller compatibility.

True when `x` is a valid `:envelope` map. Renamed conceptually;
name kept for caller compatibility.
sourceraw docstring

unregister-op-hooks-for-owner!clj

(unregister-op-hooks-for-owner! owner)

Remove EVERY op-hook registered by owner (all ops + phases). Driven by deregister-extension! so an extension's hooks die with it; also callable directly to dynamically tear an extension's hooks down.

Remove EVERY op-hook registered by `owner` (all ops + phases). Driven by
`deregister-extension!` so an extension's hooks die with it; also callable
directly to dynamically tear an extension's hooks down.
sourceraw docstring

validate!clj

(validate! ext)

Normalize and assert that an extension map conforms to ::extension. Normalizes :ext/prompt-fn (string -> fn) before checking the spec when the key is present. Throws with spec explain-data on violation.

Normalize and assert that an extension map conforms to ::extension.
Normalizes `:ext/prompt-fn` (string -> fn) before checking the spec
when the key is present. Throws with spec explain-data on violation.
sourceraw docstring

valueclj

(value v)
(value v opts-or-val)
(value sym-name val opts)

Build a value symbol entry FROM A CLOJURE VAR - a plain constant/data binding.

The var supplies :symbol (var name), :val (the var's value, unless :val is provided in opts to override - used by macro-shim entries), and :doc (from var metadata, i.e. the defn's docstring).

(def ^{:doc "Maximum retry attempts."} max-retries 3) (vis/value #'max-retries)

Opts: :symbol - override the Python sandbox name (default: var name). :val - explicit value override (rare; for macro shims that bind a marker map instead of the var's own value).

Build a value symbol entry FROM A CLOJURE VAR - a plain constant/data binding.

The var supplies `:symbol` (var name), `:val` (the var's value, unless `:val`
is provided in opts to override - used by macro-shim entries), and `:doc`
(from var metadata, i.e. the defn's docstring).

(def ^{:doc "Maximum retry attempts."} max-retries 3)
(vis/value #'max-retries)

Opts:
  :symbol - override the Python sandbox name (default: var name).
  :val - explicit value override (rare; for macro shims that bind a
         marker map instead of the var's own value).
sourceraw docstring

wrap-extensionclj

(wrap-extension ext env)

Wrap all function symbols in an extension into invocation fns.

Returns a map of {sym -> (fn [& args] result)} where each fn closes over the extension, symbol entry, and environment, then routes through invoke-symbol-wrapper.

All stdout/stderr from extension calls is redirected to the log file so nothing bleeds into the TUI.

Value symbols are returned as {sym -> value}.

Returns every extension symbol.

Wrap all function symbols in an extension into invocation fns.

Returns a map of {sym -> (fn [& args] result)} where each fn
closes over the extension, symbol entry, and environment, then
routes through `invoke-symbol-wrapper`.

All stdout/stderr from extension calls is redirected to the log
file so nothing bleeds into the TUI.

Value symbols are returned as {sym -> value}.

Returns every extension symbol.
sourceraw docstring

wrap-extension-thunkedclj

(wrap-extension-thunked ext env-thunk)

Like wrap-extension but resolves the environment LAZILY via env-thunk (a 0-arg fn) at CALL time instead of closing over a concrete env. Interns BUILT-IN extension symbols into the sandbox at Python-context creation — BEFORE the environment map exists — mirroring how doc/apropos defer through environment-atom. Same wrapping/IO-redirect as wrap-extension.

Like `wrap-extension` but resolves the environment LAZILY via `env-thunk`
(a 0-arg fn) at CALL time instead of closing over a concrete `env`. Interns
BUILT-IN extension symbols into the sandbox at Python-context creation —
BEFORE the environment map exists — mirroring how `doc`/`apropos` defer
through `environment-atom`. Same wrapping/IO-redirect as `wrap-extension`.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close