Liking cljdoc? Tell your friends :D

com.blockether.vis.internal.config

Configuration: paths, JVM lifecycle, provider presets, svar-native coercion, config file I/O, and the active-provider state every channel reads through.

Two halves:

  • On-disk config under ~/.vis/: state.yml (machine-written), vis.mdb/, vis.log. init! / init-cli! / shutdown! redirect stdout/stderr into the log file and bring up Telemere's file handler.
  • Live process state: the active-config atom holds the currently-selected provider config; current-config, active-provider, active-model, provider-ids, has-provider? are the read API. reload-config! re-reads from disk.

The ->svar-provider helper resolves :api-key lazily by calling the registered provider's :provider/get-token-fn, so the token-refresh policy stays inside each provider implementation instead of leaking up here.

Configuration: paths, JVM lifecycle, provider presets, svar-native
coercion, config file I/O, and the active-provider state every
channel reads through.

Two halves:

  - On-disk config under `~/.vis/`: `state.yml` (machine-written), `vis.mdb/`, `vis.log`.
    `init!` / `init-cli!` / `shutdown!` redirect stdout/stderr into
    the log file and bring up Telemere's file handler.
  - Live process state: the `active-config` atom holds the
    currently-selected provider config; `current-config`,
    `active-provider`, `active-model`, `provider-ids`,
    `has-provider?` are the read API. `reload-config!` re-reads
    from disk.

The `->svar-provider` helper resolves `:api-key` lazily by calling
the registered provider's `:provider/get-token-fn`, so the
token-refresh policy stays inside each provider implementation
instead of leaking up here.
raw docstring

*extension-dotenv-local-path*clj

Project .env.local consulted after .env and before an unset result. Bind in tests; production defaults to the process working directory.

Project `.env.local` consulted after `.env` and before an unset result.
Bind in tests; production defaults to the process working directory.
sourceraw docstring

*extension-dotenv-path*clj

Project .env consulted for extension-declared variables after the process environment. It takes precedence over .env.local. Bind in tests; production defaults to the process working directory.

Project `.env` consulted for extension-declared variables after the process environment.
It takes precedence over `.env.local`. Bind in tests; production defaults to the
process working directory.
sourceraw docstring

*extension-getenv*clj

Function used to read process environment variables. Bind in tests.

Function used to read process environment variables. Bind in tests.
sourceraw docstring

->svar-modelclj

(->svar-model model)
(->svar-model _provider-id model)

Coerce a model representation to svar-native {:name str}.

Coerce a model representation to svar-native `{:name str}`.
sourceraw docstring

->svar-providerclj

(->svar-provider provider)

Coerce a provider map to svar-native shape (:id, :api-key, :base-url, :api-style, :models, optional :responses-path, optional :llm-headers).

svar's make-router calls normalize-provider which auto-resolves :base-url from svar's KNOWN_PROVIDERS table for built-in providers, so we forward :base-url ONLY when the provider map has one explicitly (vis-only providers like :github-models, user overrides, or OAuth-supplied URLs). For known providers svar fills in the URL itself - stop fighting it.

When :api-key is nil, look the provider up in the global provider registry (registry.clj) and call its :provider/get-token-fn to resolve a usable token. Each provider implementation handles its own auth lifecycle (OAuth refresh, env-var fallback, provider-specific headers, ...) so this fn stays provider-agnostic and never references a concrete provider ns by name.

Coerce a provider map to svar-native shape (`:id`, `:api-key`,
`:base-url`, `:api-style`, `:models`, optional `:responses-path`,
optional `:llm-headers`).

svar's `make-router` calls `normalize-provider` which auto-resolves
`:base-url` from svar's `KNOWN_PROVIDERS` table for built-in
providers, so we forward `:base-url` ONLY when the provider map
has one explicitly (vis-only providers like `:github-models`,
user overrides, or OAuth-supplied URLs). For known providers
svar fills in the URL itself - stop fighting it.

When `:api-key` is nil, look the provider up in the global
provider registry (registry.clj) and call its
`:provider/get-token-fn` to resolve a usable token. Each provider
implementation handles its own auth lifecycle (OAuth refresh,
env-var fallback, provider-specific headers, ...) so this fn stays
provider-agnostic and never references a concrete provider ns by
name.
sourceraw docstring

active-configclj

source

active-modelclj

(active-model)

Return the primary model name string, or nil.

Return the primary model name string, or nil.
sourceraw docstring

active-providerclj

(active-provider)

Return the first (primary) provider from config, or nil.

Return the first (primary) provider from config, or nil.
sourceraw docstring

baked-tokenclj

(baked-token pid)

The access token ->svar-provider last baked into a router for provider pid (nil if none). This is the token the live router's requests actually send, so it's the correct REJECTED token on a 401 — unlike the current on-file token, which a peer tab/process may already have rotated to something fresh.

The access token `->svar-provider` last baked into a router for provider `pid`
(nil if none). This is the token the live router's requests actually send, so
it's the correct REJECTED token on a 401 — unlike the current on-file token,
which a peer tab/process may already have rotated to something fresh.
sourceraw docstring

compatibility->api-styleclj

The user-facing compatibility: knob -> svar's low-level :api-style.

A provider speaks exactly one wire dialect, and that is all a user should have to state: Anthropic Messages, or OpenAI-compatible (chat completions by default, the Responses API when the endpoint serves only that). api_style stays as the raw svar escape hatch and wins when both are set.

The user-facing `compatibility:` knob -> svar's low-level `:api-style`.

A provider speaks exactly one wire dialect, and that is all a user should
have to state: Anthropic Messages, or OpenAI-compatible (chat completions by
default, the Responses API when the endpoint serves only that). `api_style`
stays as the raw svar escape hatch and wins when both are set.
sourceraw docstring

compatibility-api-styleclj

(compatibility-api-style compatibility)

:api-style implied by a provider's compatibility value. nil when absent or unknown - config validation rejects unknown values long before this.

`:api-style` implied by a provider's `compatibility` value. nil when absent or
unknown - config validation rejects unknown values long before this.
sourceraw docstring

config-dirclj

source

config-problemsclj

(config-problems)

Model-readable, per-top-level-key reasons the currently merged live config fails the contract (config-spec/explain-problems over load-config-raw), or [] when it is valid. Loads leniently so this never throws even while the config on disk is broken — it is the diagnostic surfaced as config_error.

Model-readable, per-top-level-key reasons the currently merged live config
fails the contract (`config-spec/explain-problems` over `load-config-raw`),
or [] when it is valid. Loads leniently so this never throws even while the
config on disk is broken — it is the diagnostic surfaced as `config_error`.
sourceraw docstring

current-configclj

(current-config)

Return the current provider config. Loads from disk on first call.

Return the current provider config. Loads from disk on first call.
sourceraw docstring

db-pathclj

source

default-db-specclj

source

default-search-always-excludeclj

Default :grep :always-exclude patterns (.gitignore syntax) guarding the subtrees an :include-gitignored-paths overlay re-includes: machine-generated dirs nobody wants surfaced even inside a rescued vendored repo. Setting :always-exclude in config REPLACES this list (vectors replace on merge, like everywhere else in config).

Default `:grep :always-exclude` patterns (`.gitignore` syntax) guarding
the subtrees an `:include-gitignored-paths` overlay re-includes:
machine-generated dirs nobody wants surfaced even inside a rescued vendored
repo. Setting `:always-exclude` in config REPLACES this list (vectors
replace on merge, like everywhere else in config).
sourceraw docstring

display-labelclj

(display-label pid)

Human-readable label for a provider id. Never persisted.

A REGISTERED provider extension owns its own branding (Anthropic (API Key), LM Studio, OpenAI) and wins. For every other id — anything a caller wrote as providers: - id: … in vis.yml — that id IS the author's chosen spelling, so it is echoed VERBATIM.

Never str/capitalize here: it force-uppercases the first letter AND lowercases the rest, so an authored openAI rendered as Openai, ACME as Acme, and GPT4All as Gpt4all. A provider entry has no label key (see config-spec/provider-keys), so the id is the only casing signal the author has — mangling it means the TUI, the gateway /v1/providers label, and the companion all disagree with the file on disk.

Human-readable label for a provider id. Never persisted.

A REGISTERED provider extension owns its own branding (`Anthropic (API Key)`,
`LM Studio`, `OpenAI`) and wins. For every other id — anything a caller wrote
as `providers: - id: …` in `vis.yml` — that id IS the author's chosen
spelling, so it is echoed VERBATIM.

Never `str/capitalize` here: it force-uppercases the first letter AND
lowercases the rest, so an authored `openAI` rendered as `Openai`, `ACME` as
`Acme`, and `GPT4All` as `Gpt4all`. A provider entry has no `label` key
(see `config-spec/provider-keys`), so the id is the only casing signal the
author has — mangling it means the TUI, the gateway `/v1/providers` label,
and the companion all disagree with the file on disk.
sourceraw docstring

env-refsclj

(env-refs s)

Distinct env var names referenced as ${NAME} inside string s, in order. nil for a non-string.

Distinct env var names referenced as `${NAME}` inside string `s`, in order.
nil for a non-string.
sourceraw docstring

extension-env-statusclj

(extension-env-status name)

Return source and value metadata for an extension-declared variable. The process environment wins over the working directory's .env, then .env.local; Vis config is deliberately never consulted. :source is :env, :dotenv, or :unset.

Return source and value metadata for an extension-declared variable.
The process environment wins over the working directory's `.env`, then `.env.local`;
Vis config is deliberately never consulted. `:source` is `:env`, `:dotenv`, or `:unset`.
sourceraw docstring

extension-env-valueclj

(extension-env-value name)

Resolve an extension-declared variable from the process environment or .env. Blank/missing values return nil.

Resolve an extension-declared variable from the process environment or `.env`.
Blank/missing values return nil.
sourceraw docstring

first-run?clj

(first-run?)

True on a genuine FIRST run: no provider configured AND no global machine store (~/.vis/state.yml) has ever been written. Distinguishes the full welcome (brand-new user) from a returning user who merely has no provider right now (e.g. removed their only one).

True on a genuine FIRST run: no provider configured AND no global machine store
(`~/.vis/state.yml`) has ever been written. Distinguishes the full welcome
(brand-new user) from a returning user who merely has no provider right now
(e.g. removed their only one).
sourceraw docstring

frame-buffered-tty-outclj

(frame-buffered-tty-out raw)

Wrap the raw tty stream so a whole repaint reaches the terminal as ONE atomic write instead of one write(2) syscall PER CELL.

Lanterna's refreshByDelta calls putString/setCursorPosition per changed cell and only flushes once at the end of refresh. On a raw FileOutputStream every one of those calls is its own syscall straight to the tty, so the terminal renders PARTIAL frames mid-repaint: a fold toggle that shifts the transcript reads as a whole-screen flicker and a transient content jump. Buffering until flush collapses the frame to one write, and the DEC 2026 bracket makes the terminal hold rendering until the frame is complete even when the kernel chunks the write.

Everything vis writes to the tty outside Lanterna (SGR-mouse / bracketed-paste toggles, OSC 11 background, the :bell fx, the panic PrintStream) already flushes explicitly, so nothing can sit in the buffer across frames.

Wrap the raw tty stream so a whole repaint reaches the terminal as ONE
atomic write instead of one write(2) syscall PER CELL.

Lanterna's `refreshByDelta` calls `putString`/`setCursorPosition` per
changed cell and only `flush`es once at the end of `refresh`. On a raw
`FileOutputStream` every one of those calls is its own syscall straight
to the tty, so the terminal renders PARTIAL frames mid-repaint: a fold
toggle that shifts the transcript reads as a whole-screen flicker and a
transient content jump. Buffering until `flush` collapses the frame to
one write, and the DEC 2026 bracket makes the terminal hold rendering
until the frame is complete even when the kernel chunks the write.

Everything vis writes to the tty outside Lanterna (SGR-mouse /
bracketed-paste toggles, OSC 11 background, the `:bell` fx, the panic
PrintStream) already flushes explicitly, so nothing can sit in the
buffer across frames.
sourceraw docstring

has-provider?clj

(has-provider? provider-id)
source

init!clj

(init!)

Redirect System/out and System/err to the log file. Lanterna uses tty-in / tty-out for terminal I/O. Call from the TUI entry point.

Redirect System/out and System/err to the log file. Lanterna uses
tty-in / tty-out for terminal I/O. Call from the TUI entry point.
sourceraw docstring

init-cli!clj

(init-cli!)

Logging init for non-TUI processes. Same redirects as init! but without the shutdown hook (CLI commands run to completion and exit).

Logging init for non-TUI processes. Same redirects as init! but
without the shutdown hook (CLI commands run to completion and exit).
sourceraw docstring

interpolate-envclj

(interpolate-env v)

Replace every ${NAME} inside every STRING of v with (System/getenv NAME). Map KEYS are left alone — the contract's key set is finite and snake_case, so a ${} key is a typo, not a feature. An unset var is left verbatim.

Replace every `${NAME}` inside every STRING of `v` with `(System/getenv NAME)`.
Map KEYS are left alone — the contract's key set is finite and snake_case, so
a `${}` key is a typo, not a feature. An unset var is left verbatim.
sourceraw docstring

invalidate-config-cache!clj

(invalidate-config-cache!)

Drop the load-config-raw memo. Called on every config WRITE, because two writes inside one filesystem mtime tick could otherwise stamp identically.

Drop the `load-config-raw` memo. Called on every config WRITE, because two
writes inside one filesystem mtime tick could otherwise stamp identically.
sourceraw docstring

invalidate-credential-command!clj

(invalidate-credential-command! pid)

Forget the memoized api_key_command token for provider pid, so the next router build re-execs the helper.

The 401 recovery path lives in loop.clj and must not reach past this ns into the credential executor, so the one-line hook belongs here beside the rest of the credential seam.

Forget the memoized `api_key_command` token for provider `pid`, so the next
router build re-execs the helper.

The 401 recovery path lives in `loop.clj` and must not reach past this ns into
the credential executor, so the one-line hook belongs here beside the rest of
the credential seam.
sourceraw docstring

load-configclj

(load-config)

Load the validated YAML config and adapt its finite schema keys to internal keyword-keyed domain maps. load-config-raw retains the original string keys.

This is also the ${NAME} interpolation boundary. It is done HERE and not in load-config-raw on purpose: the raw loaders are the read half of every read-modify-write into ~/.vis/state.yml, so resolving there would write the plaintext secret straight back to disk. save-config! runs restore-env-refs as the matching guard for values that still reach a write through this keywordized view.

Load the validated YAML config and adapt its finite schema keys to internal
keyword-keyed domain maps. `load-config-raw` retains the original string keys.

This is also the `${NAME}` interpolation boundary. It is done HERE and not in
`load-config-raw` on purpose: the raw loaders are the read half of every
read-modify-write into `~/.vis/state.yml`, so resolving there would write the
plaintext secret straight back to disk. `save-config!` runs
`restore-env-refs` as the matching guard for values that still reach a write
through this keywordized view.
sourceraw docstring

load-config-rawclj

(load-config-raw)

Load raw config as the deep-merge of four YAML sources — later sources win, nested maps merge, scalar/vector values replace:

  1. ~/.vis/config.yml (or .yaml / vis.yml / vis.yaml) — hand-written global base
  2. ~/.vis/state.yml — machine-written global store (OAuth tokens, TUI-added providers); wins over the hand-written base
  3. <cwd>/vis.yml (or vis.yaml) — visible project root, the committed team config
  4. <cwd>/.vis/config.yml (or .yaml) — hidden project overlay; the NESTED overlay wins over the root file (personal beats committed)

Memoized against the sources' mtime+size (see config-raw-cache).

Load raw config as the deep-merge of four YAML sources — later sources win,
nested maps merge, scalar/vector values replace:

1. `~/.vis/config.yml` (or `.yaml` / `vis.yml` / `vis.yaml`) — hand-written
   global base
2. `~/.vis/state.yml` — machine-written global store (OAuth tokens, TUI-added
   providers); wins over the hand-written base
3. `<cwd>/vis.yml` (or `vis.yaml`) — visible project root, the committed team
   config
4. `<cwd>/.vis/config.yml` (or `.yaml`) — hidden project overlay; the NESTED
   overlay wins over the root file (personal beats committed)

Memoized against the sources' mtime+size (see `config-raw-cache`).
sourceraw docstring

load-global-config-rawclj

(load-global-config-raw)

Load the machine-written global store as a config map (or nil): ~/.vis/state.yml, the YAML file Vis read-modify-writes. Machine-owned on purpose — kept out of the hand-written YAML merge so the RMW cycle never clobbers user files.

Load the machine-written global store as a config map (or nil): `~/.vis/state.yml`,
the YAML file Vis read-modify-writes. Machine-owned on purpose — kept out of the
hand-written YAML merge so the RMW cycle never clobbers user files.
sourceraw docstring

load-global-yaml-config-rawclj

(load-global-yaml-config-raw)

Load only the hand-written global YAML tier: the first existing of ~/.vis/config.yml / config.yaml / vis.yml / vis.yaml, or nil. This hand-written base is deep-merged UNDER the machine-written ~/.vis/state.yml store (state.yml wins per key), keeping user-authored config separate from the RMW machine file.

Load only the hand-written global YAML tier: the first existing of
`~/.vis/config.yml` / `config.yaml` / `vis.yml` / `vis.yaml`, or nil. This
hand-written base is deep-merged UNDER the machine-written `~/.vis/state.yml`
store (`state.yml` wins per key), keeping user-authored config separate from
the RMW machine file.
sourceraw docstring

load-project-config-rawclj

(load-project-config-raw)

Load the hidden project overlay tier: the first existing of <invocation-cwd>/.vis/config.yml / .vis/config.yaml, or nil. Skipped when the overlay dir resolves to the global ~/.vis store, so running Vis from $HOME never aliases a global file as a project overlay.

Load the hidden project overlay tier: the first existing of
`<invocation-cwd>/.vis/config.yml` / `.vis/config.yaml`, or nil. Skipped when
the overlay dir resolves to the global `~/.vis` store, so running Vis from
$HOME never aliases a global file as a project overlay.
sourceraw docstring

load-project-root-config-rawclj

(load-project-root-config-raw)

Load the visible project-root tier: the first existing of <invocation-cwd>/vis.yml / vis.yaml, or nil.

Load the visible project-root tier: the first existing of
`<invocation-cwd>/vis.yml` / `vis.yaml`, or nil.
sourceraw docstring

model-nameclj

(model-name model)

Extract the model name string from a model (string or {:name str}).

Extract the model name string from a model (string or `{:name str}`).
sourceraw docstring

original-stdoutclj

source

provider-api-styleclj

(provider-api-style provider)
(provider-api-style provider template)

Effective :api-style for a provider map: explicit api_style first (raw svar value), then the compatibility alias, then catalog/preset metadata.

Effective `:api-style` for a provider map: explicit `api_style` first (raw
svar value), then the `compatibility` alias, then catalog/preset metadata.
sourceraw docstring

provider-base-urlclj

(provider-base-url provider)

Resolve base-url for a provider: explicit field on the provider map first (so user-supplied URLs win), then the merged catalog.

Resolve base-url for a provider: explicit field on the provider
map first (so user-supplied URLs win), then the merged catalog.
sourceraw docstring

provider-configured?clj

(provider-configured?)

True when at least one provider is configured (global or project config). The single predicate entry points use to branch onboarding vs normal start — never trips the resolve-config throw.

True when at least one provider is configured (global or project config).
The single predicate entry points use to branch onboarding vs normal start —
never trips the `resolve-config` throw.
sourceraw docstring

provider-credential-errorclj

(provider-credential-error provider)

provider-credential-gap's message, or nil. Convenience for call sites that only render the reason.

`provider-credential-gap`'s message, or nil. Convenience for call sites that
only render the reason.
sourceraw docstring

provider-credential-gapclj

(provider-credential-gap provider)

The ONE non-secret reason provider cannot currently produce a credential, or nil when it can.

Two sources, checked in that order:

  • an unresolved ${NAME} anywhere in the entry (provider-env-gap);
  • an api_key_command that cannot currently produce a token — missing executable, non-zero exit, timeout, or blank stdout.

Returns {:reason <human string> :env-vars [...]|nil}. :reason is safe to log, render and put in an error: it names the provider, the unset vars or the PROGRAM, and never the command's stdout.

This is the single seam every availability decision reads — provider status, vis-agent doctor, router-build exclusion and the hard error raised when a user explicitly selects the provider — so a command-backed credential behaves exactly like an unset ${NAME} everywhere, by construction.

The ONE non-secret reason `provider` cannot currently produce a credential,
or nil when it can.

Two sources, checked in that order:

  - an unresolved `${NAME}` anywhere in the entry (`provider-env-gap`);
  - an `api_key_command` that cannot currently produce a token — missing
    executable, non-zero exit, timeout, or blank stdout.

Returns `{:reason <human string> :env-vars [...]|nil}`. `:reason` is safe to
log, render and put in an error: it names the provider, the unset vars or the
PROGRAM, and never the command's stdout.

This is the single seam every availability decision reads — provider status,
`vis-agent doctor`, router-build exclusion and the hard error raised when a
user explicitly selects the provider — so a command-backed credential behaves
exactly like an unset `${NAME}` everywhere, by construction.
sourceraw docstring

provider-credential-gap-cachedclj

(provider-credential-gap-cached provider)

provider-credential-gap restricted to what is ALREADY known: the env check is pure, and a credential command is only consulted through its cache.

Paint paths (providers/initial-provider-status) must never fork a subprocess to draw a frame, so an unprobed helper yields nil here and the card renders as loading until the real background probe answers.

`provider-credential-gap` restricted to what is ALREADY known: the env check is
pure, and a credential command is only consulted through its cache.

Paint paths (`providers/initial-provider-status`) must never fork a subprocess
to draw a frame, so an unprobed helper yields nil here and the card renders as
loading until the real background probe answers.
sourceraw docstring

provider-credential-messageclj

(provider-credential-message provider-id reason)

The message shown when a provider's api_key_command cannot produce a token.

Mirrors provider-env-message's shape — can't use <provider>: <reason> — so every channel renders both credential gaps identically. reason is the executor's own non-secret verdict (missing program, exit code, timeout, blank output); the helper's STDOUT is the credential and never reaches here.

The message shown when a provider's `api_key_command` cannot produce a token.

Mirrors `provider-env-message`'s shape — `can't use <provider>: <reason>` — so
every channel renders both credential gaps identically. `reason` is the
executor's own non-secret verdict (missing program, exit code, timeout, blank
output); the helper's STDOUT is the credential and never reaches here.
sourceraw docstring

provider-env-gapclj

(provider-env-gap provider)

Sorted vec of env vars ONE provider map still references but that are unset, or nil when the provider resolved completely.

Sorted vec of env vars ONE provider map still references but that are unset,
or nil when the provider resolved completely.
sourceraw docstring

provider-env-gapsclj

(provider-env-gaps config)

provider-id -> reason for every provider in config that cannot currently authenticate; an empty map when the whole fleet resolved. Covers unset ${NAME} references AND failing api_key_command helpers.

`provider-id -> reason` for every provider in `config` that cannot currently
authenticate; an empty map when the whole fleet resolved. Covers unset
`${NAME}` references AND failing `api_key_command` helpers.
sourceraw docstring

provider-env-messageclj

(provider-env-message provider-id env-vars)

The message shown when an env-gapped provider is reached for. Names the provider and every unset var and NOTHING else — it carries no config value, so a half-resolved secret can never leak through it into a log or a dialog.

The message shown when an env-gapped provider is reached for. Names the
provider and every unset var and NOTHING else — it carries no config value, so
a half-resolved secret can never leak through it into a log or a dialog.
sourceraw docstring

provider-idsclj

(provider-ids)

Set of configured provider :id keywords.

Set of configured provider `:id` keywords.
sourceraw docstring

provider-model-visible?clj

(provider-model-visible? provider-id model-id)

True when svar's provider-scoped model filters allow this model id.

True when svar's provider-scoped model filters allow this model id.
sourceraw docstring

provider-presetsclj

(provider-presets)

All known provider presets, sorted for the 'Add Provider' picker.

All known provider presets, sorted for the 'Add Provider' picker.
sourceraw docstring

provider-templateclj

(provider-template pid)

Preset descriptor for a provider id, merged from a provider extension's metadata and svar's catalog. Returns nil for unknown or intentionally removed ids.

Preset descriptor for a provider id, merged from a provider
extension's metadata and svar's catalog. Returns nil for unknown or
intentionally removed ids.
sourceraw docstring

reload-config!clj

(reload-config!)
source

remove-config-provider!clj

(remove-config-provider! provider-id)
(remove-config-provider! provider-id source)

Remove every persisted provider entry for provider-id from the string-keyed machine config, preserving unrelated keys.

A FALLBACK tag naming that provider goes with it. Unlike default_provider, which degrades to the fleet's first provider, the fallback root is never implicit: a tag left behind names nobody, is invisible to every UI, and silently resurrects the moment that provider is authenticated again.

Remove every persisted provider entry for `provider-id` from the string-keyed
machine config, preserving unrelated keys.

A FALLBACK tag naming that provider goes with it. Unlike `default_provider`,
which degrades to the fleet's first provider, the fallback root is never
implicit: a tag left behind names nobody, is invisible to every UI, and
silently resurrects the moment that provider is authenticated again.
sourceraw docstring

resolve-configclj

(resolve-config)
(resolve-config explicit-config)

Resolve provider config: explicit -> merged YAML config. Throws when nothing is available.

Resolve provider config: explicit -> merged YAML config.
Throws when nothing is available.
sourceraw docstring

resolve-db-specclj

(resolve-db-spec)
(resolve-db-spec explicit-db-spec)

Resolve DB spec: explicit -> JVM property -> environment -> validated YAML -> default.

Resolve DB spec: explicit -> JVM property -> environment -> validated YAML -> default.
sourceraw docstring

restore-env-refsclj

(restore-env-refs v)

Inverse of interpolate-env, applied on the WRITE path: any string equal to a value this process resolved from a WHOLE-value ${NAME} reference is written back as ${NAME}.

Without this the feature would silently DE-reference itself. Every read-modify-write into ~/.vis/state.yml — a theme flip, a toggle listener, a provider edit — re-serializes maps that may have travelled through load-config, and would bake the PLAINTEXT secret onto disk. The entire point of ${NAME} is that the secret never lands in a file, so the guard belongs at the single write boundary (save-config!) rather than in every caller.

Inverse of `interpolate-env`, applied on the WRITE path: any string equal to a
value this process resolved from a WHOLE-value `${NAME}` reference is written
back as `${NAME}`.

Without this the feature would silently DE-reference itself. Every
read-modify-write into `~/.vis/state.yml` — a theme flip, a toggle listener, a
provider edit — re-serializes maps that may have travelled through
`load-config`, and would bake the PLAINTEXT secret onto disk. The entire point
of `${NAME}` is that the secret never lands in a file, so the guard belongs at
the single write boundary (`save-config!`) rather than in every caller.
sourceraw docstring

router-baked-tokensclj

Access token last baked into a built router, keyed by provider id. ->svar-provider records the token it resolved via :provider/get-token-fn here at router-build time. On a 401 the runtime reads it back as the REJECTED token — the exact token the failing request sent — so single-flight refresh reuse won't hand that same dead token straight back (see loop.clj OAuth 401 recovery). Correct across multi-tab/multi-process rotation, where the current ON-FILE token may already be a peer's fresh one.

Access token last baked into a built router, keyed by provider id.
`->svar-provider` records the token it resolved via `:provider/get-token-fn`
here at router-build time. On a 401 the runtime reads it back as the REJECTED
token — the exact token the failing request sent — so single-flight refresh
reuse won't hand that same dead token straight back (see loop.clj OAuth 401
recovery). Correct across multi-tab/multi-process rotation, where the current
ON-FILE token may already be a peer's fresh one.
sourceraw docstring

router-optsclj

(router-opts config)

Extracts svar/make-router opts from a Vis config map.

Reads the :router block from the merged YAML config:

{:router
 {:rate-limit {:same-provider-delays-ms [2000 3000 6000]
               :fallback-after-ms 30000
               :respect-retry-after? true
               :fallback-provider? true}
  :network    {:timeout-ms 300000 :idle-timeout-ms 45000}
  :budget     {:max-tokens 1000000 :max-cost 5.0}}}

Returns {} when no :router block is present so svar's built-in defaults win. Unknown keys are dropped — only the keys svar's make-router knows about flow through.

See com.blockether.svar.internal.router/make-router for the authoritative key reference.

Extracts `svar/make-router` opts from a Vis config map.

Reads the `:router` block from the merged YAML config:

```clojure
{:router
 {:rate-limit {:same-provider-delays-ms [2000 3000 6000]
               :fallback-after-ms 30000
               :respect-retry-after? true
               :fallback-provider? true}
  :network    {:timeout-ms 300000 :idle-timeout-ms 45000}
  :budget     {:max-tokens 1000000 :max-cost 5.0}}}
```

Returns `{}` when no `:router` block is present so svar's built-in
defaults win. Unknown keys are dropped — only the keys svar's
`make-router` knows about flow through.

See `com.blockether.svar.internal.router/make-router` for the
authoritative key reference.
sourceraw docstring

runtime-configclj

(runtime-config v)

Adapt an already-validated string-keyed YAML map to Vis' internal domain maps. Only the finite keys in runtime-keywords become keywords. User-defined map keys remain strings, and parsing/validation never uses this adapter.

Adapt an already-validated string-keyed YAML map to Vis' internal domain maps.
Only the finite keys in `runtime-keywords` become keywords. User-defined map keys
remain strings, and parsing/validation never uses this adapter.
sourceraw docstring

save-config!clj

(save-config! config)
(save-config! config source)

Persist configuration to ~/.vis/state.yml using the string-keyed YAML contract. Callers may supply internal keyword-keyed domain maps; validation always runs on the exact string-keyed map that is written.

Persist configuration to `~/.vis/state.yml` using the string-keyed YAML contract.
Callers may supply internal keyword-keyed domain maps; validation always runs on
the exact string-keyed map that is written.
sourceraw docstring

search-overlayclj

(search-overlay)

Return the grep overlay as an internal keyword-keyed map, or nil when unset. The source configuration remains string-keyed and spec-validated.

Return the grep overlay as an internal keyword-keyed map, or nil when unset.
The source configuration remains string-keyed and spec-validated.
sourceraw docstring

shutdown!clj

(shutdown!)

Flush and stop all telemere handlers. Call after the TUI screen stops.

Flush and stop all telemere handlers. Call after the TUI screen
stops.
sourceraw docstring

state-pathclj

Machine-owned RMW config store ~/.vis/state.yml (YAML). Vis read-modify-writes this exact file — OAuth tokens, TUI-added providers, extension env overrides — so it is kept SEPARATE from the hand-written ~/.vis/config.yml tier: the RMW cycle must never fold (and thus clobber) a user's hand-written YAML.

Machine-owned RMW config store `~/.vis/state.yml` (YAML). Vis read-modify-writes
this exact file — OAuth tokens, TUI-added providers, extension env overrides — so
it is kept SEPARATE from the hand-written `~/.vis/config.yml` tier: the RMW cycle
must never fold (and thus clobber) a user's hand-written YAML.
sourceraw docstring

tty-inclj

source

tty-outclj

source

unresolved-env-refsclj

(unresolved-env-refs v)

Env var names still spelled ${NAME} anywhere in v AFTER interpolation — i.e. exactly the referenced vars this process has no value for. Sorted and distinct. Walks strings, map VALUES, and sequences.

Env var names still spelled `${NAME}` anywhere in `v` AFTER interpolation —
i.e. exactly the referenced vars this process has no value for. Sorted and
distinct. Walks strings, map VALUES, and sequences.
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