Liking cljdoc? Tell your friends :D

com.blockether.vis.internal.form

The canonical per-form DISPLAY contract — ONE source of truth for the fields a channel reads to render an executed form, live (via the gateway) and restored (via the DB).

Why this exists: the SAME field set used to be hand-listed in ~7 independent allowlists — the loop chunk, the persisted block, the gateway block.output wire payload, the gateway→chunk client projection, the live progress form, the DB-restored form, and the restored display form. A new field was invisible until every one was edited, and whichever layer forgot it silently dropped the field (the gateway dropping :tool-color-role so the live badge vanished was exactly that). Now every layer projects the WHOLE set through ->display (outbound) / <-wire (inbound, tolerant of the wire's snake_case + stringified keyword values), so a new display field is a ONE-line change to display-keys and form-roundtrip-test fails if a boundary stops carrying it.

Transformed fields (:stdout/:error bounded, :silent/:duration_ms renamed) stay as explicit gateway overrides — they are not carried verbatim, so they are NOT in this set.

The canonical per-form DISPLAY contract — ONE source of truth for the fields a
channel reads to render an executed form, live (via the gateway) and restored
(via the DB).

Why this exists: the SAME field set used to be hand-listed in ~7 independent
allowlists — the loop chunk, the persisted block, the gateway `block.output`
wire payload, the gateway→chunk client projection, the live progress form, the
DB-restored form, and the restored display form. A new field was invisible
until every one was edited, and whichever layer forgot it silently dropped the
field (the gateway dropping `:tool-color-role` so the live badge vanished was
exactly that). Now every layer projects the WHOLE set through `->display`
(outbound) / `<-wire` (inbound, tolerant of the wire's snake_case + stringified
keyword values), so a new display field is a ONE-line change to `display-keys`
and `form-roundtrip-test` fails if a boundary stops carrying it.

Transformed fields (`:stdout`/`:error` bounded, `:silent`/`:duration_ms`
renamed) stay as explicit gateway overrides — they are not carried verbatim, so
they are NOT in this set.
raw docstring

->displayclj

(->display m)

Project the canonical display fields off a source map (loop chunk/block, a restored row) — the ONE projection every form builder + the gateway uses instead of hand-listing keys. Drops nils so a merge never stamps empty keys.

Project the canonical display fields off a source map (loop chunk/block, a
restored row) — the ONE projection every form builder + the gateway uses
instead of hand-listing keys. Drops nils so a merge never stamps empty keys.
sourceraw docstring

<-wireclj

(<-wire event)

Read the canonical display fields back off a gateway WIRE event into a form, using the literal wire spelling declared beside each engine key in display-fields, and re-keywording keyword-valued fields. The single inbound projection channels use — the mirror of ->display.

Read the canonical display fields back off a gateway WIRE event into a form,
using the literal wire spelling declared beside each engine key in
`display-fields`, and re-keywording keyword-valued fields. The single inbound
projection channels use — the mirror of `->display`.
sourceraw docstring

coalesce-formsclj

(coalesce-forms forms)

Merge each maximal run of ADJACENT, successful coalescable native op-cards into a single card. cat/patch coalesce only for the SAME file; format_code coalesces adjacent per-file acks into one roll-up across files. Every other form passes through untouched. The ONE projection both channels apply before rendering an iteration's forms, so repeated tool acks never render as a stack of look-alike sibling bubbles. Always returns a vector.

Merge each maximal run of ADJACENT, successful coalescable native op-cards into
a single card. `cat`/`patch` coalesce only for the SAME file; `format_code`
coalesces adjacent per-file acks into one roll-up across files. Every other
form passes through untouched. The ONE projection both channels apply before
rendering an iteration's forms, so repeated tool acks never render as a stack
of look-alike sibling bubbles. Always returns a vector.
sourceraw docstring

display-keysclj

The canonical engine keys projected by ->display and recovered by <-wire.

The canonical engine keys projected by `->display` and recovered by `<-wire`.
sourceraw docstring

hide-tool-code?clj

(hide-tool-code? {:keys [error success?] :as form})

Should a channel DROP a form's invocation source instead of showing it as a separate code block? Successful native tools already have a result card, so their synthesized invocation is redundant. Failed native tools keep source context. python_execution is different: its program is user-relevant evidence and remains visible on both success and failure. This is the shared TUI/channel policy; web mirrors it at the wire boundary.

Should a channel DROP a form's invocation source instead of showing it as a
separate code block? Successful native tools already have a result card, so
their synthesized invocation is redundant. Failed native tools keep source
context. `python_execution` is different: its program is user-relevant
evidence and remains visible on both success and failure. This is the shared
TUI/channel policy; web mirrors it at the wire boundary.
sourceraw docstring

native-tool-form?clj

(native-tool-form? {tool-name :vis/tool-name})

True when form is a NATIVE tool call (cat/rg/patch/…): it carries a :vis/tool-name and therefore renders as an op-card via result-card.

True when `form` is a NATIVE tool call (cat/rg/patch/…): it carries a
`:vis/tool-name` and therefore renders as an op-card via `result-card`.
sourceraw docstring

result-cardclj

(result-card {:keys [tool-color-role result-summary pending-summary
                     result-render pending-render]
              tool-name :vis/tool-name})

Canonical tool-result CARD descriptor — the ONE place the op-card / collapse decision is made, so the TUI and web AGREE on tool?/label/colour/summary/ collapsible instead of each re-deriving it from the raw form. Given an executed form map, returns the op-card shape for a NATIVE TOOL result:

{:tool? true :label "RG" — op-card badge label (tool-label) :color-role :tool-color/search — badge colour role (keyword-normalized, since a JSON wire hop stringifies it) :summary "5 hits in 1 file" — the HEADLINE (:result-summary), nil when the tool authored none :body "…markdown…" — the detail body (:result-render), nil for a summary-only tool (move/delete) :collapsible? true} — true ⇔ there's a body to fold under the summary (a chevron/<details>)

A call still RUNNING has no result yet, so the headline falls back to the tool-authored :pending-summary (shell's $ npm test (running)): the SAME card, in its awaiting state, rather than a bare unlabeled code band.

nil for a NON-tool form (no :vis/tool-name) — its result rendering stays channel-specific (raw value / stdout). The badge is whatever the tool's :summary already produced; no first-line-of-body heuristic.

Canonical tool-result CARD descriptor — the ONE place the op-card / collapse
decision is made, so the TUI and web AGREE on `tool?`/label/colour/summary/
collapsible instead of each re-deriving it from the raw form. Given an executed
form map, returns the op-card shape for a NATIVE TOOL result:

  {:tool?        true
   :label        "RG"                — op-card badge label (`tool-label`)
   :color-role   :tool-color/search   — badge colour role (keyword-normalized,
                                        since a JSON wire hop stringifies it)
   :summary      "5 hits in 1 file"  — the HEADLINE (`:result-summary`), nil
                                        when the tool authored none
   :body         "…markdown…"        — the detail body (`:result-render`), nil
                                        for a summary-only tool (move/delete)
   :collapsible? true}                — true ⇔ there's a body to fold under
                                        the summary (a chevron/`<details>`)

A call still RUNNING has no result yet, so the headline falls back to the
tool-authored `:pending-summary` (`shell`'s `$ npm test (running)`): the SAME
card, in its awaiting state, rather than a bare unlabeled code band.

`nil` for a NON-tool form (no `:vis/tool-name`) — its result rendering stays
channel-specific (raw value / stdout). The badge is whatever the tool's
`:summary` already produced; no first-line-of-body heuristic.
sourceraw docstring

result-cardsclj

(result-cards form)

The op-card descriptor(s) a form renders — the ONE place a channel asks "what cards does this form show?" so the TUI and web never re-derive it differently.

A python block that print()ed several tool results carries a :cards vector of canonical mini-forms; each becomes its OWN op-card via result-card. Any other form yields its single result-card (or none). Always a vector — channels just iterate. Empty when the form has no tool card at all (plain value / stdout).

The op-card descriptor(s) a form renders — the ONE place a channel asks "what
cards does this form show?" so the TUI and web never re-derive it differently.

A python block that print()ed several tool results carries a `:cards` vector of
canonical mini-forms; each becomes its OWN op-card via `result-card`. Any other
form yields its single `result-card` (or none). Always a vector — channels just
iterate. Empty when the form has no tool card at all (plain value / stdout).
sourceraw docstring

running-code-toolsclj

Native tools whose SUBMITTED invocation stays visible while the call is STILL RUNNING — the command/program itself is the payload a user needs to judge a long-running op. Every other native tool just spins behind its badge: a 200ms cat/grep must not flash a bordered code frame with a copy control for something nobody reads. python_execution additionally keeps its source after completion (see hide-tool-code?); shell only while it runs, because the finished command is already carried by its op-card headline.

Native tools whose SUBMITTED invocation stays visible while the call is STILL
RUNNING — the command/program itself is the payload a user needs to judge a
long-running op. Every other native tool just spins behind its badge: a 200ms
`cat`/`grep` must not flash a bordered code frame with a copy control for
something nobody reads. `python_execution` additionally keeps its source after
completion (see `hide-tool-code?`); `shell` only while it runs, because the
finished command is already carried by its op-card headline.
sourceraw docstring

show-running-tool-code?clj

(show-running-tool-code? form)

Should a channel show a STILL-RUNNING form's invocation source even though hide-tool-code? would drop it once the call completes? Only for running-code-tools (and non-tool forms, which have no op-card to hide behind) — and never when the tool AUTHORED its own pending card body (:pending-render): that body already IS the submitted command, rendered as the card renders it, so the raw invocation beside it would say the same thing twice in JSON. This is the shared TUI/channel policy; web mirrors it.

Should a channel show a STILL-RUNNING form's invocation source even though
`hide-tool-code?` would drop it once the call completes? Only for
`running-code-tools` (and non-tool forms, which have no op-card to hide
behind) — and never when the tool AUTHORED its own pending card body
(`:pending-render`): that body already IS the submitted command, rendered as
the card renders it, so the raw invocation beside it would say the same thing
twice in JSON. This is the shared TUI/channel policy; web mirrors it.
sourceraw docstring

tool-color-rolesclj

The canonical set of native-tool op-card BADGE colour roles — the ONE list both channels colour against (TUI maps each to a lanterna fg, the web to a --tool-* CSS var). Hand-maintained per-channel maps were free to drift; a guard test in each channel asserts its map covers every role here, so a new role can't be added in one channel and silently forgotten in the other.

The canonical set of native-tool op-card BADGE colour roles — the ONE list both
channels colour against (TUI maps each to a lanterna fg, the web to a `--tool-*`
CSS var). Hand-maintained per-channel maps were free to drift; a guard test in
each channel asserts its map covers every role here, so a new role can't be
added in one channel and silently forgotten in the other.
sourceraw docstring

tool-labelclj

(tool-label wire-name)

The op-card badge LABEL for a native tool's wire name: the name uppercased, except the few label-overrides rename. ONE place both channels derive it from so the TUI badge and the web label never drift. nil for a non-tool form.

The op-card badge LABEL for a native tool's wire name: the name uppercased,
except the few `label-overrides` rename. ONE place both channels derive it from
so the TUI badge and the web label never drift. nil for a non-tool form.
sourceraw docstring

with-display-codeclj

(with-display-code form)

Attach the canonical cached ruff rendering of a form's Python source. Channels render :display-code verbatim; local callers without it may use the same formatter. Nested result cards are normalized recursively.

An AUTHORED :display-code is never overwritten: a native tool may render its own PENDING call (:render-callshell ships the bash it is about to run instead of the raw invocation JSON), and that surface, paired with its :display-language, is the one the channels must paint.

Attach the canonical cached ruff rendering of a form's Python source.
Channels render `:display-code` verbatim; local callers without it may use
the same formatter. Nested result cards are normalized recursively.

An AUTHORED `:display-code` is never overwritten: a native tool may render
its own PENDING call (`:render-call` — `shell` ships the bash it is about to
run instead of the raw invocation JSON), and that surface, paired with its
`:display-language`, is the one the channels must paint.
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