Liking cljdoc? Tell your friends :D

com.blockether.vis.ext.channel-tui.dialogs


adaptive-content-heightclj

(adaptive-content-height rows requested)

Clamp a dialog's REQUESTED content height so the box sizes to its own content instead of the shared footprint.

  • nil requested -> the shared full-height footprint (default-content-height). Spacious logo / welcome screens and long browsers opt in this way.
  • a number -> clamped between min-adaptive-content-h and the terminal-bounded dialog-max-height, so short dialogs are compact and long ones still scroll.
Clamp a dialog's REQUESTED content height so the box sizes to its own
content instead of the shared footprint.

- `nil` requested -> the shared full-height footprint (`default-content-height`).
  Spacious logo / welcome screens and long browsers opt in this way.
- a number -> clamped between `min-adaptive-content-h` and the terminal-bounded
  `dialog-max-height`, so short dialogs are compact and long ones still scroll.
sourceraw docstring

clear-screen!clj

(clear-screen! screen)

Fill the entire screen with terminal background. Call before sub-dialogs to cleanly replace the current dialog (wizard step pattern).

Fill the entire screen with terminal background. Call before sub-dialogs
to cleanly replace the current dialog (wizard step pattern).
sourceraw docstring

command-palette!clj

(command-palette! screen)
(command-palette! screen extra-commands)
(command-palette! screen extra-commands ctx)

Show the searchable command palette. Returns the FULL chosen command map (so the caller's run-command! can read :id and any slash keys), or nil on Esc. extra-commands are the engine slash roots appended after the built-ins. Opened with C-x C-p (Emacs C-x prefix + Ctrl+P).

ctx ({:has-turns? bool}) gates context-only verbs via palette-commands-for — without turns the Fork Session entries are not listed at all.

Show the searchable command palette. Returns the FULL chosen command map
(so the caller's `run-command!` can read `:id` and any slash keys), or nil
on Esc. `extra-commands` are the engine slash roots appended after the
built-ins. Opened with C-x C-p (Emacs C-x prefix + Ctrl+P).

`ctx` (`{:has-turns? bool}`) gates context-only verbs via
[[palette-commands-for]] — without turns the Fork Session entries are not
listed at all.
sourceraw docstring

confirm-dialog!clj

(confirm-dialog! screen title message)

Show Y/N confirmation with side-by-side buttons. Returns true/false, nil on Esc.

Show Y/N confirmation with side-by-side buttons. Returns true/false, nil on Esc.
sourceraw docstring

copy-dialog!clj

(copy-dialog! screen messages)

Show copy dialog for chat messages. Space toggles, A toggles all, Enter copies selected, Esc cancels.

Show copy dialog for chat messages.
Space toggles, A toggles all, Enter copies selected, Esc cancels.
sourceraw docstring

default-content-heightclj

(default-content-height rows)

Shared content height every dialog uses, derived from rows. Clamped to a common modal footprint so dialogs keep equal height.

Shared content height every dialog uses, derived from `rows`.
Clamped to a common modal footprint so dialogs keep equal height.
sourceraw docstring

default-content-widthclj

(default-content-width cols)

Shared content width every dialog uses, derived from cols. Clamped between the theme's dialog min/max widths and bounded by the terminal so the box never paints off-screen.

Shared content width every dialog uses, derived from `cols`. Clamped
between the theme's dialog min/max widths and bounded by the terminal so
the box never paints off-screen.
sourceraw docstring

dialog-boundsclj

(dialog-bounds cols rows content-w content-h)

Pure geometry twin of draw-dialog-chrome! (explicit width+height arity): the box rectangle a content-w×content-h dialog occupies, computed WITHOUT painting. Lets a component measure its full layout — and reconcile a scroll window — before any drawing happens. Returns the SAME shape the chrome does ({:left :top :right :bottom :inner-w :inner-h}), from the same golden math.

Pure geometry twin of `draw-dialog-chrome!` (explicit width+height arity):
the box rectangle a `content-w`×`content-h` dialog occupies, computed WITHOUT
painting. Lets a component measure its full layout — and reconcile a scroll
window — before any drawing happens. Returns the SAME shape the chrome does
({:left :top :right :bottom :inner-w :inner-h}), from the same golden math.
sourceraw docstring

dialog-layoutclj

(dialog-layout bounds)
(dialog-layout {:keys [top bottom]} content-count)

Compute content area layout. When content-count is provided and smaller than the available height, content is vertically centered within the frame. Layout: border -> title bar -> top separator -> CONTENT -> bottom separator -> hint -> border.

Compute content area layout. When `content-count` is provided and smaller than
the available height, content is vertically centered within the frame.
Layout: border -> title bar -> top separator -> CONTENT -> bottom separator -> hint -> border.
sourceraw docstring

draft-picker!clj

(draft-picker! screen drafts)

Open the large draft manager. Returns a switch target, {:action :new}, or {:action :abandon ...}; the screen layer owns prompts, confirmation, and canonical gateway mutations.

Open the large draft manager. Returns a switch target, `{:action :new}`, or
`{:action :abandon ...}`; the screen layer owns prompts, confirmation, and
canonical gateway mutations.
sourceraw docstring

draft-picker-componentclj

(draft-picker-component drafts)

Large, sectioned draft manager component. Trunk stays visually separate from the draft collection, descriptions occupy a smaller italic second line, and filtering uses the same query field, matching rules, navigation, and modified action chords as the other searchable pickers. Pure measure/reconcile/key handling remains testable without a terminal.

Large, sectioned draft manager component. Trunk stays visually separate from
the draft collection, descriptions occupy a smaller italic second line, and
filtering uses the same query field, matching rules, navigation, and modified
action chords as the other searchable pickers. Pure measure/reconcile/key
handling remains testable without a terminal.
sourceraw docstring

draft-picker-itemsclj

(draft-picker-items drafts)

Turn canonical gateway draft rows into the dedicated manager's selectable items. Trunk is deliberately pinned in its own first section; current and parked drafts follow underneath.

Turn canonical gateway draft rows into the dedicated manager's selectable
items. Trunk is deliberately pinned in its own first section; current and
parked drafts follow underneath.
sourceraw docstring

drain-modal-paste!clj

(drain-modal-paste! screen)

After a bracketed-paste START keystroke is seen, drain screen until PASTE_END and return the pasted text (PUA markers stripped). Lets any modal text input accept clipboard paste without re-implementing the paste state machine. Returns "" on a clipboard that yields no chars.

After a bracketed-paste START keystroke is seen, drain `screen` until
PASTE_END and return the pasted text (PUA markers stripped). Lets any
modal text input accept clipboard paste without re-implementing the
paste state machine. Returns "" on a clipboard that yields no chars.
sourceraw docstring

draw-dialog-chrome!clj

(draw-dialog-chrome! g cols rows title content-h)
(draw-dialog-chrome! g cols rows title content-w content-h)

Draw dialog background, shadow, border, and title.

Three arities:

  • (g cols rows title content-h) - shared default width; the box HEIGHT is sized to content-h via adaptive-content-height. Pass nil as content-h for the shared full-height footprint.
  • (g cols rows title content-w content-h) - fully explicit. Use only when a dialog genuinely needs a non-default width.

Returns {:left :top :right :bottom :inner-w :inner-h}.

Draw dialog background, shadow, border, and title.

Three arities:
- `(g cols rows title content-h)` - shared default width; the box HEIGHT is
  sized to `content-h` via `adaptive-content-height`. Pass `nil` as
  `content-h` for the shared full-height footprint.
- `(g cols rows title content-w content-h)` - fully explicit. Use
  only when a dialog genuinely needs a non-default width.

Returns {:left :top :right :bottom :inner-w :inner-h}.
sourceraw docstring

draw-dialog-close-button!clj

(draw-dialog-close-button! g box-right title-row)

Paint a clickable X close button at a dialog's top-right title row and record its click bounds (thread-local) so read-modal-input! can turn a click into Escape. Every dialog inherits it via draw-dialog-chrome!. Lights up to the red pill (close-button-hover-fg + bold) when the thread-local close-hover flag is set - the same affordance the header and help/tasks overlay close buttons use - so modal X buttons are no longer static.

Paint a clickable X close button at a dialog's top-right title row and
record its click bounds (thread-local) so `read-modal-input!` can turn a
click into Escape. Every dialog inherits it via `draw-dialog-chrome!`.
Lights up to the red pill (`close-button-hover-fg` + bold) when the
thread-local close-hover flag is set - the same affordance the header and
help/tasks overlay close buttons use - so modal X buttons are no longer
static.
sourceraw docstring

draw-flat-dialog-chrome!clj

(draw-flat-dialog-chrome! g cols rows title)

Flat variant of draw-dialog-chrome!: no drop shadow, no accent title stripe, no separators - one thin-bordered rect on the dialog background with the title inline on the top border. Same default footprint and the same bounds map as the boxed chrome, so dialog-layout works unchanged.

Flat variant of `draw-dialog-chrome!`: no drop shadow, no accent title
stripe, no separators - one thin-bordered rect on the dialog background
with the title inline on the top border. Same default footprint and the
same bounds map as the boxed chrome, so `dialog-layout` works unchanged.
sourceraw docstring

draw-hint-bar!clj

(draw-hint-bar! g left row inner-w hint)

Draw hint bar. hint can be:

  • a string: rendered as-is, left-aligned
  • a vec of strings: centered, dim italic, joined with ' · '
  • a vec of [key action] pairs: key bold, action dim italic, the whole run centered with thin ' · ' separators between pairs

Hints are CENTERED (not full-width justified) so short hint sets read as one tidy line instead of being stretched ragged across the dialog. Examples: "simple hint" ["move" "select" "cancel"] [["Up/Dn" "move"] ["Enter" "select"] ["Esc" "cancel"]]

Draw hint bar. `hint` can be:
- a string: rendered as-is, left-aligned
- a vec of strings: centered, dim italic, joined with ' · '
- a vec of [key action] pairs: key bold, action dim italic, the whole
  run centered with thin ' · ' separators between pairs

Hints are CENTERED (not full-width justified) so short hint sets read as
one tidy line instead of being stretched ragged across the dialog.
Examples:
  "simple hint"
  ["move" "select" "cancel"]
  [["Up/Dn" "move"] ["Enter" "select"] ["Esc" "cancel"]]
sourceraw docstring

ellipsizeclj

(ellipsize s max-w)

Right-truncate s to max-w columns with a trailing . Thin delegate over the canonical p/ellipsize (lanterna-backed).

Right-truncate `s` to `max-w` columns with a trailing `…`.
Thin delegate over the canonical `p/ellipsize` (lanterna-backed).
sourceraw docstring

filter-select-itemsclj

(filter-select-items items query)

Apply the shared picker filter: case-insensitive substring matching, preserving source order. Items may provide :search-text to include metadata beyond the visible label; otherwise :label is the haystack. A blank query shows all.

Apply the shared picker filter: case-insensitive substring matching, preserving
source order. Items may provide `:search-text` to include metadata beyond the
visible label; otherwise `:label` is the haystack. A blank query shows all.
sourceraw docstring

fit-hint-pairsclj

(fit-hint-pairs hint text-w)

Longest prefix of [key action] hint pairs whose rendered width (with ' · ' separators) fits in text-w columns. put-str! clips to the SCREEN, not the dialog box, so a footer wider than the content area must drop whole trailing chords instead of painting across the border.

Longest prefix of `[key action]` hint pairs whose rendered width (with
'  ·  ' separators) fits in `text-w` columns. `put-str!` clips to the
SCREEN, not the dialog box, so a footer wider than the content area must
drop whole trailing chords instead of painting across the border.
sourceraw docstring

(footer-content-width cols hint)
(footer-content-width cols hint min-content)

Content width for an action-footer dialog: sized so the box is EXACTLY the footer's natural width plus two columns of padding on each side, never narrower than min-content (the widest content line) nor wider than the terminal. The +2 supplies the extra pad beyond the single-column gutter draw-dialog-chrome! already reserves inside the border, so a footer of width W yields 2 blank columns between the frame and the hints on each side.

Content width for an action-footer dialog: sized so the box is EXACTLY the
footer's natural width plus two columns of padding on each side, never
narrower than `min-content` (the widest content line) nor wider than the
terminal. The `+2` supplies the extra pad beyond the single-column gutter
`draw-dialog-chrome!` already reserves inside the border, so a footer of
width W yields 2 blank columns between the frame and the hints on each side.
sourceraw docstring

fork-turn-itemsclj

(fork-turn-items turns)

Rows for the fork-at-turn palette (searchable-select!), one per turn of the current session (from db-list-session-turns), top-to-bottom. Each row's :label is the turn's user message (whitespace-collapsed, truncated) and :hint its ordinal tN; :turn-id carries the session_turn_soul id the fork copies THROUGH — selecting a row forks the session keeping every turn up to and INCLUDING it. Type to filter by message text.

Rows for the fork-at-turn palette (`searchable-select!`), one per turn of the
current session (from `db-list-session-turns`), top-to-bottom. Each row's
`:label` is the turn's user message (whitespace-collapsed, truncated) and
`:hint` its ordinal `tN`; `:turn-id` carries the `session_turn_soul` id the
fork copies THROUGH — selecting a row forks the session keeping every turn up
to and INCLUDING it. Type to filter by message text.
sourceraw docstring

hint-bar-widthclj

(hint-bar-width hint)

Natural rendered width (chars) of a draw-hint-bar! hint — a plain string, a vec of strings, or a vec of [key action] pairs — using the SAME segment and separator math the hint bar paints with. Lets a dialog size its box to the footer instead of a fixed terminal ratio.

Natural rendered width (chars) of a `draw-hint-bar!` hint — a plain string,
a vec of strings, or a vec of `[key action]` pairs — using the SAME segment
and separator math the hint bar paints with. Lets a dialog size its box to
the footer instead of a fixed terminal ratio.
sourceraw docstring

list-dialog!clj

(list-dialog! screen title items opts)

Reusable scrollable, selectable list dialog — the SINGLE implementation behind select-dialog! (plain) and searchable-select! (type-to-filter). Now a THIN driver: select-modal-component supplies the pure geometry / scroll / key logic and run-modal! owns the loop. Returns the chosen item map (the full map, so callers recover :id/slash keys), or nil on Esc.

items is a vec of maps with at least :label. opts: :filter? type-to-filter on :label, case-insensitive (default false) :placeholder query placeholder shown while the filter is empty :enter-label hint-bar verb for Enter (default "select") :height :content sizes the box to the item count (+ the query field), capped; nil uses the shared (tall) footprint.

Reusable scrollable, selectable list dialog — the SINGLE implementation
behind `select-dialog!` (plain) and `searchable-select!` (type-to-filter).
Now a THIN driver: `select-modal-component` supplies the pure geometry /
scroll / key logic and `run-modal!` owns the loop. Returns the chosen item
map (the full map, so callers recover `:id`/slash keys), or nil on Esc.

`items` is a vec of maps with at least `:label`. opts:
  :filter?      type-to-filter on `:label`, case-insensitive (default false)
  :placeholder  query placeholder shown while the filter is empty
  :enter-label  hint-bar verb for Enter (default "select")
  :height       `:content` sizes the box to the item count (+ the query
                field), capped; nil uses the shared (tall) footprint.
sourceraw docstring

log-view-dialog!clj

(log-view-dialog! screen
                  title
                  lines
                  &
                  {:keys [refresh-fn tail? grammar] :or {grammar "bash"}})

FULLSCREEN, syntax-highlighted log viewer — the whole terminal, edge to edge.

Unlike text-view-dialog! (a centered modal box) this owns the entire screen: a title strip on the top row, the log body filling every row beneath it, and a hint strip on the bottom row. Each line is colorized by parsing the WHOLE buffer with tree-sitter (highlight/highlight, default the bash grammar) and painting the resulting ANSI runs through render/paint-ansi-line! — the same path that carries syntax color on the transcript's code fences. Fails open to plain text when the native grammar pack isn't loadable.

Keys: ↑/↓ line, PgUp/PgDn page, Home/End jump, mouse-wheel scroll, r refresh (when :refresh-fn), Enter/Esc close. Options:

  • :refresh-fn thunk returning fresh lines — enables r refresh so a live buffer (e.g. background-shell logs) can be re-pulled in place.
  • :tail? start pinned to the newest line and re-follow the bottom on refresh (log-tail behaviour); scrolling up releases the pin.
  • :grammar tree-sitter grammar for coloring (default "bash"); nil = plain. Returns nil after close.
FULLSCREEN, syntax-highlighted log viewer — the whole terminal, edge to edge.

Unlike `text-view-dialog!` (a centered modal box) this owns the entire screen:
a title strip on the top row, the log body filling every row beneath it, and a
hint strip on the bottom row. Each line is colorized by parsing the WHOLE
buffer with tree-sitter (`highlight/highlight`, default the `bash` grammar) and
painting the resulting ANSI runs through `render/paint-ansi-line!` — the same
path that carries syntax color on the transcript's code fences. Fails open to
plain text when the native grammar pack isn't loadable.

Keys: ↑/↓ line, PgUp/PgDn page, Home/End jump, mouse-wheel scroll, `r` refresh
(when `:refresh-fn`), Enter/Esc close. Options:
- :refresh-fn  thunk returning fresh lines — enables `r` refresh so a live
               buffer (e.g. background-shell logs) can be re-pulled in place.
- :tail?       start pinned to the newest line and re-follow the bottom on
               refresh (log-tail behaviour); scrolling up releases the pin.
- :grammar     tree-sitter grammar for coloring (default "bash"); nil = plain.
Returns nil after close.
sourceraw docstring

magit-dialog!clj

(magit-dialog! screen root-or-repos)

Magit-style status buffer over the git CLI — the C-x g / footer-git modal.

root-or-repos is either ONE root (string/File — the classic single-repo buffer) or a vector of repo entries {:root :label :draft?} from magit/workspace-roots — the session's primary workspace root plus every extra filesystem root (/fs, the dir picker). With several roots each repo gets a Repository <label> — <path> header and its own full section stack; for a DRAFT session the entries already point at the CLONES the session edits, so the buffer shows the draft's git state, not the trunk's.

Sections: head/upstream facts, untracked, unmerged, unstaged, staged, stashes and recent commits. TAB folds a file's diff peek open under its row; RET visits it FULLSCREEN (a file's syntax-highlighted body, a commit's or stash's full patch). Verbs mirror magit and route to the repo UNDER THE CURSOR: s/u stage/unstage the file or the whole section, S/U all, k discard with a confirm, c commit/amend (message prompt), P push (plain / -u / --force-with-lease), F pull, f fetch, b branch (checkout / create / delete), z stash (push / pop / apply / drop), g refresh, C-w copy the sha/path/ref under point, q/Esc close. Every verb shells to the real git binary via internal.git, and the buffer re-reads every repo after each action, so what you see is always git status truth. Returns nil.

Magit-style status buffer over the git CLI — the C-x g / footer-git modal.

`root-or-repos` is either ONE root (string/File — the classic single-repo
buffer) or a vector of repo entries `{:root :label :draft?}` from
`magit/workspace-roots` — the session's primary workspace root plus every
extra filesystem root (`/fs`, the dir picker). With several roots each repo
gets a `Repository <label> — <path>` header and its own full section stack;
for a DRAFT session the entries already point at the CLONES the session
edits, so the buffer shows the draft's git state, not the trunk's.

Sections: head/upstream facts, untracked, unmerged, unstaged, staged,
stashes and recent commits. TAB folds a file's diff peek open under
its row; RET visits it FULLSCREEN (a file's syntax-highlighted body, a
commit's or stash's full patch). Verbs mirror magit and route to the repo
UNDER THE CURSOR:
`s`/`u` stage/unstage the file or the whole section, `S`/`U` all, `k`
discard with a confirm, `c` commit/amend (message prompt), `P` push
(plain / -u / --force-with-lease), `F` pull, `f` fetch, `b` branch
(checkout / create / delete), `z` stash (push / pop / apply / drop), `g`
refresh, `C-w` copy the sha/path/ref under point, `q`/Esc close. Every verb
shells to the real `git` binary via
`internal.git`, and the buffer re-reads every repo after each action, so
what you see is always `git status` truth. Returns nil.
sourceraw docstring

magit-transient!clj

(magit-transient! screen g left inner-w hint-row text-w title spec read-option)

Magit-style transient rendered IN the status buffer's ECHO AREA — a bottom- anchored popup painted over the buffer's own lower rows (title + grouped SWITCHES / value OPTIONS / fire-once ACTIONS + a hint row on hint-row), NOT a centered modal dialog box. The status buffer stays fully visible above it, exactly like Emacs magit's transient popup / minibuffer. There is NO moving cursor — you press an item's :key directly. Switches highlight while active; options display their value inline. spec is {:groups [{:title str :items [{:key :type :id :label}]}]} where :type is :switch | :option | :action. read-option (impure) fetches an option's value: (read-option item current) -> str|nil — nil (Esc) leaves it unchanged; it too should read INLINE (via the buffer's :read! minibuffer), never a box. Returns {:action id :switches #{…} :options {id val}} when an action fires, or nil on Esc.

g left inner-w hint-row text-w are the SAME buffer-geometry values the other inline minibuffer primitives receive, so the popup shares the status buffer's canvas instead of allocating its own screen.

Magit-style transient rendered IN the status buffer's ECHO AREA — a bottom-
anchored popup painted over the buffer's own lower rows (title + grouped
SWITCHES / value OPTIONS / fire-once ACTIONS + a hint row on `hint-row`), NOT
a centered modal dialog box. The status buffer stays fully visible above it,
exactly like Emacs magit's transient popup / minibuffer. There is NO moving
cursor — you press an item's `:key` directly. Switches highlight while active;
options display their value inline. `spec` is
`{:groups [{:title str :items [{:key :type :id :label}]}]}` where `:type` is
`:switch` | `:option` | `:action`. `read-option` (impure) fetches an option's
value: `(read-option item current) -> str|nil` — nil (Esc) leaves it unchanged;
it too should read INLINE (via the buffer's `:read!` minibuffer), never a box.
Returns `{:action id :switches #{…} :options {id val}}` when an action fires,
or nil on Esc.

`g left inner-w hint-row text-w` are the SAME buffer-geometry values the other
inline minibuffer primitives receive, so the popup shares the status buffer's
canvas instead of allocating its own screen.
sourceraw docstring

markdown-viewer-dialog!clj

(markdown-viewer-dialog! screen title md)

Scrollable read-only MARKDOWN viewer: md is lifted to canonical IR (vis/markdown->ast) and painted with styled headings, bold, and code accents, tables — through the SAME IR walker the chat uses (layout/ast->lines). The rich twin of text-viewer-dialog!. Returns nil on Esc. Supports keyboard scrolling.

Scrollable read-only MARKDOWN viewer: `md` is lifted to canonical IR
(`vis/markdown->ast`) and painted with styled headings, bold, and code
accents, tables — through the SAME IR walker the chat uses
(`layout/ast->lines`). The rich twin of `text-viewer-dialog!`.
Returns nil on Esc. Supports keyboard scrolling.
sourceraw docstring

(modal-close-click? key)

True when key is a mouse click on the dialog close (✕) button.

True when `key` is a mouse click on the dialog close (✕) button.
sourceraw docstring

(modal-enter-key? key)
source

(modal-escape-key? key)
source

(modal-input-pending? screen)

True when another keystroke is ALREADY queued for this modal loop. The peeked event is stashed in the same thread-local slot read-modal-input! drains, so nothing is lost.

This is the TUI's DEBOUNCE primitive: an expensive per-keystroke effect (the gateway transcript search) can skip itself while the user is still typing and run once on the keystroke that lands in a pause — no threads, no timers, and no repaint problem from an async result arriving while the loop blocks in readInput.

True when another keystroke is ALREADY queued for this modal loop. The peeked
event is stashed in the same thread-local slot `read-modal-input!` drains, so
nothing is lost.

This is the TUI's DEBOUNCE primitive: an expensive per-keystroke effect (the
gateway transcript search) can skip itself while the user is still typing and
run once on the keystroke that lands in a pause — no threads, no timers, and
no repaint problem from an async result arriving while the loop blocks in
`readInput`.
sourceraw docstring

(modal-wheel-delta key)

Return list-selection delta for a wheel mouse event, else nil. Negative moves up; positive moves down.

Return list-selection delta for a wheel mouse event, else nil.
Negative moves up; positive moves down.
sourceraw docstring

(modal-wheel-step key)

Return wheel delta multiplied by any coalesced event count.

Return wheel delta multiplied by any coalesced event count.
sourceraw docstring

model-picker!clj

(model-picker! screen current)

Searchable per-session model picker — TUI parity with the web footer chooser. Lists every configured model as a row (<provider> / <model>, the active one marked ● current) plus a top ★ router default row that CLEARS the per-session override. current is the session's stored model preference ({:provider <str|kw> :model <str>}) or nil; it marks the active row exactly like the web picker. Returns the chosen item map — {:reset? true} for the router-default row, else {:provider <str> :model <str>} — or nil on Esc.

Searchable per-session model picker — TUI parity with the web footer
chooser. Lists every configured model as a row (`<provider> / <model>`,
the active one marked `● current`) plus a top `★ router default` row
that CLEARS the per-session override. `current` is the session's stored
model preference (`{:provider <str|kw> :model <str>}`) or nil; it marks
the active row exactly like the web picker. Returns the chosen item map
— `{:reset? true}` for the router-default row, else `{:provider <str>
:model <str>}` — or nil on Esc.
sourceraw docstring

multi-select-dialog!clj

(multi-select-dialog! screen title items)

Checkbox multi-select over items (vec of strings). Space toggles the cursor row, a toggles all, Enter confirms, Esc cancels. Returns the vec of selected strings (possibly empty) on confirm, nil on Esc. Mirrors the web modal's alias chips — same proposed options, multi-pick semantics.

Checkbox multi-select over `items` (vec of strings). Space toggles the
cursor row, `a` toggles all, Enter confirms, Esc cancels. Returns the vec
of selected strings (possibly empty) on confirm, nil on Esc. Mirrors the
web modal's alias chips — same proposed options, multi-pick semantics.
sourceraw docstring

(navigator-dialog! screen opts)

Global C-g session picker. Full-width project/session hierarchy; transcript lookup is debounced and asynchronous so typing never waits on the gateway.

Global C-g session picker. Full-width project/session hierarchy; transcript
lookup is debounced and asynchronous so typing never waits on the gateway.
sourceraw docstring

normalize-modal-keyclj

(normalize-modal-key key)

Normalize raw terminal CR/LF/ESC character keystrokes to Lanterna Enter/Escape key types. Some terminals surface modal Enter/Escape as KeyType/Character; modal code should not need to special-case that.

Normalize raw terminal CR/LF/ESC character keystrokes to Lanterna
Enter/Escape key types. Some terminals surface modal Enter/Escape as
`KeyType/Character`; modal code should not need to special-case that.
sourceraw docstring

palette-commandsclj

Command palette entries. Each is {:id keyword :label str}. The :id is the action the screen's run-command! executes. Quit is intentionally NOT here — use Ctrl+C to quit.

The palette is THE discoverable entry point for every app verb: opened with C-x p (reliable on every terminal, unlike Alt/Option chords on macOS) and filtered by typing. Mirrors the web command palette so both channels expose the same command set.

Command palette entries. Each is {:id keyword :label str}. The `:id` is the
action the screen's `run-command!` executes. Quit is intentionally NOT here
— use Ctrl+C to quit.

The palette is THE discoverable entry point for every app verb: opened with
C-x p (reliable on every terminal, unlike Alt/Option chords on macOS) and
filtered by typing. Mirrors the web command palette so both channels expose
the same command set.
sourceraw docstring

palette-commands-forclj

(palette-commands-for {:keys [has-turns?]})

palette-commands filtered to the entries that can ACT in ctx. Mirrors the which-key strip's :show-when gating: an entry tagged :has-turns (both Fork Session verbs) is DROPPED in a session with no turns — forking a turnless session is prohibited, so it must not even be discoverable.

ctx is {:has-turns? bool}; a missing/nil ctx is the conservative turnless case. Untagged entries always survive.

`palette-commands` filtered to the entries that can ACT in `ctx`. Mirrors the
which-key strip's `:show-when` gating: an entry tagged `:has-turns` (both
Fork Session verbs) is DROPPED in a session with no turns — forking a
turnless session is prohibited, so it must not even be discoverable.

`ctx` is `{:has-turns? bool}`; a missing/nil ctx is the conservative
turnless case. Untagged entries always survive.
sourceraw docstring

read-modal-input!clj

(read-modal-input! screen)

Read one modal input event. Consecutive pending wheel events are drained and returned as one :scroll-delta, so a wheel flood costs one redraw. The first non-wheel event encountered while draining is held for the next modal read on this thread. MOVE/DRAG events also refresh the close (X) hover flag so the button can light up under the cursor.

Read one modal input event. Consecutive pending wheel events are drained
and returned as one `:scroll-delta`, so a wheel flood costs one redraw.
The first non-wheel event encountered while draining is held for the next
modal read on this thread. MOVE/DRAG events also refresh the close (X)
hover flag so the button can light up under the cursor.
sourceraw docstring

read-modal-key!clj

(read-modal-key! screen)

Like Screen/readInput, but drains wheel floods into one synthetic wheel event. Existing modal loops can use it without bespoke scroll-delta code.

Like `Screen/readInput`, but drains wheel floods into one synthetic wheel
event. Existing modal loops can use it without bespoke scroll-delta code.
sourceraw docstring

run-modal!clj

(run-modal! screen {:keys [init measure reconcile paint on-key]})

Shared modal driver — the ONE event loop every ported dialog reuses instead of hand-rolling its own loop/recur. component is a map of PURE fns (they never touch the screen) plus one impure paint fn:

:init immutable start state (a map), or a 0-arg fn returning it :measure (fn [state cols rows] -> geom) — geometry, screen-free, TESTABLE :reconcile (fn [state geom] -> state) — optional clamp (e.g. scroll window) :paint (fn [g state geom] -> cursor|nil) — the only impure piece; draws to g :on-key (fn [state key geom] -> state | {::done result}) — screen-free, TESTABLE

run-modal! owns everything the old dialogs copy-pasted: terminal sizing, the TextGraphics, wheel/close/Esc normalization (via read-modal-key!), the cursor + DELTA refresh, and the recur loop. A key handler returns the next state to continue, or {::done v} to close the modal with value v (nil on Esc/close). Because :measure/:reconcile/:on-key are pure functions of data, a dialog's geometry and key logic can be unit-tested with no live terminal at all — the React-like win.

Shared modal driver — the ONE event loop every ported dialog reuses instead
of hand-rolling its own `loop/recur`. `component` is a map of PURE fns (they
never touch the screen) plus one impure paint fn:

  :init      immutable start state (a map), or a 0-arg fn returning it
  :measure   (fn [state cols rows] -> geom)     — geometry, screen-free, TESTABLE
  :reconcile (fn [state geom] -> state)         — optional clamp (e.g. scroll window)
  :paint     (fn [g state geom] -> cursor|nil)  — the only impure piece; draws to `g`
  :on-key    (fn [state key geom] -> state | {::done result})  — screen-free, TESTABLE

run-modal! owns everything the old dialogs copy-pasted: terminal sizing, the
`TextGraphics`, wheel/close/Esc normalization (via `read-modal-key!`), the
cursor + DELTA refresh, and the recur loop. A key handler returns the next
state to continue, or `{::done v}` to close the modal with value `v` (nil on
Esc/close). Because `:measure`/`:reconcile`/`:on-key` are pure functions of
data, a dialog's geometry and key logic can be unit-tested with no live
terminal at all — the React-like win.
sourceraw docstring

searchable-select!clj

(searchable-select! screen title items)
(searchable-select! screen title items {:keys [placeholder enter-label]})

Type-to-filter selection list — the searchable spine of the command palette. Thin wrapper over list-dialog! (filter on, content-sized, palette placeholder). Returns the FULL chosen item map (so callers recover :id / slash keys), or nil on Esc.

The optional opts map overrides the filter field's :placeholder and the :enter-label — so callers other than the command palette (e.g. the project switcher) show a fitting prompt instead of "Type a command…".

Type-to-filter selection list — the searchable spine of the command palette.
Thin wrapper over `list-dialog!` (filter on, content-sized, palette
placeholder). Returns the FULL chosen item map (so callers recover
`:id` / slash keys), or nil on Esc.

The optional `opts` map overrides the filter field's `:placeholder` and the
`:enter-label` — so callers other than the command palette (e.g. the project
switcher) show a fitting prompt instead of "Type a command…".
sourceraw docstring

select-dialog!clj

(select-dialog! screen title items)

Show a selection list dialog. Returns the selected item map or nil on Esc. items is a vec of {:label str, …} maps. Thin wrapper over list-dialog!.

Show a selection list dialog. Returns the selected item map or nil on Esc.
`items` is a vec of `{:label str, …}` maps. Thin wrapper over `list-dialog!`.
sourceraw docstring

select-modal-componentclj

(select-modal-component title
                        items
                        {:keys [filter? placeholder enter-label height]})

Build the run-modal! component behind list-dialog! — a scrollable, selectable, optionally type-to-filter list. This is the pure-fn heart of the dialog: its :measure (geometry), :reconcile (scroll window) and :on-key (navigation / filtering / select) are plain functions of immutable state, so they can be exercised in tests WITHOUT a terminal. Only :paint touches the screen. items/opts match list-dialog!.

Build the `run-modal!` component behind `list-dialog!` — a scrollable,
selectable, optionally type-to-filter list. This is the pure-fn heart of the
dialog: its `:measure` (geometry), `:reconcile` (scroll window) and `:on-key`
(navigation / filtering / select) are plain functions of immutable state, so
they can be exercised in tests WITHOUT a terminal. Only `:paint` touches the
screen. `items`/opts match `list-dialog!`.
sourceraw docstring

session-dialog-headerclj

(session-dialog-header body-w)
source

session-dialog-itemsclj

(session-dialog-items sessions active-id)
(session-dialog-items sessions active-id body-w)

Build table rows for existing sessions only. New/fork stay dialog options via the N/F shortcuts and command palette; they are not fake table data rows. Rows are sorted by Modified at desc, then Created at desc.

Build table rows for existing sessions only. New/fork stay dialog
options via the N/F shortcuts and command palette; they are not fake table
data rows. Rows are sorted by Modified at desc, then Created at desc.
sourceraw docstring

session-dialog-labelclj

(session-dialog-label session active-id body-w)

Format one fixed-width session table row. Columns are intentionally stable so the picker reads as a table inside the shared dialog chrome.

Format one fixed-width session table row. Columns are intentionally
stable so the picker reads as a table inside the shared dialog chrome.
sourceraw docstring

session-picker-dialog!clj

(session-picker-dialog! screen sessions active-id)

Show recent TUI sessions in a fixed-size table. Returns {:action :new}, {:action :fork}, {:action :switch :id <session-id>}, or nil on Esc.

Show recent TUI sessions in a fixed-size table. Returns
`{:action :new}`, `{:action :fork}`, `{:action :switch :id <session-id>}`,
or nil on Esc.
sourceraw docstring

settings-dialog!clj

(settings-dialog! screen settings)
(settings-dialog! screen settings callbacks)

Show the settings dialog.

ONE flat, grouped, scrollable list (mirrors the web settings modal), laid out VS Code-style: a left Table-of-Contents sidebar rail lists the sections with per-section counts and highlights the one owning the selection, while the right pane shows the settings themselves. Toggle rows render a leading status glyph; choice rows cycle their value with Enter; action rows invoke a callback. The rail is a passive locator — arrow keys still move through the right pane and the rail tracks where you are.

settings is the persisted TUI settings map (see state/default-settings). Esc clears an active search first, then closes and returns the current settings map.

Show the settings dialog.

ONE flat, grouped, scrollable list (mirrors the web settings modal), laid
out VS Code-style: a left Table-of-Contents sidebar rail lists the sections
with per-section counts and highlights the one owning the selection, while
the right pane shows the settings themselves. Toggle rows render a leading
status glyph; choice rows cycle their value with Enter; action rows invoke
a callback. The rail is a passive locator — arrow keys still move through
the right pane and the rail tracks where you are.

`settings` is the persisted TUI settings map (see
`state/default-settings`). Esc clears an active search first, then closes
and returns the current settings map.
sourceraw docstring

text-input-dialog!clj

(text-input-dialog! screen
                    title
                    label
                    &
                    {:keys [mask initial body logo flat?] :or {initial ""}})

Show a text input dialog. Returns string or nil on Esc. Options: :mask char (e.g. * for passwords), :initial string, :body string-or-lines rendered above the input label, :logo lines drawn centered in the accent color above the body, :flat? true selects the minimal inline-border chrome.

Show a text input dialog. Returns string or nil on Esc.
Options: :mask char (e.g. \* for passwords), :initial string,
:body string-or-lines rendered above the input label,
:logo lines drawn centered in the accent color above the body,
:flat? true selects the minimal inline-border chrome.
sourceraw docstring

text-view-dialog!clj

(text-view-dialog! screen title lines & {:keys [refresh-fn tail?]})

Show read-only lines in a scrollable modal. Returns nil after close.

Keys: ↑/↓ line, PgUp/PgDn page, Home/End jump, mouse-wheel scroll, Enter/Esc close. Options:

  • :refresh-fn thunk returning fresh lines — enables [r] refresh so a live buffer (e.g. background logs) can be re-pulled in place.
  • :tail? start pinned to the newest line and re-follow the bottom on refresh (log-tail behaviour); scrolling up releases the pin.
Show read-only lines in a scrollable modal. Returns nil after close.

Keys: ↑/↓ line, PgUp/PgDn page, Home/End jump, mouse-wheel scroll,
Enter/Esc close. Options:
- :refresh-fn  thunk returning fresh lines — enables [r] refresh so a live
               buffer (e.g. background logs) can be re-pulled in place.
- :tail?       start pinned to the newest line and re-follow the bottom on
               refresh (log-tail behaviour); scrolling up releases the pin.
sourceraw docstring

text-viewer-dialog!clj

(text-viewer-dialog! screen title text)

Show a scrollable read-only text viewer dialog. title is the dialog header. text is a string (may contain newlines) that is rendered VERBATIM - same content the LLM receives, only soft- wrapped to fit the dialog width. No markdown, no truncation, no reformatting. Returns nil on Esc. Supports keyboard scrolling.

Show a scrollable read-only text viewer dialog.
`title` is the dialog header. `text` is a string (may contain newlines)
that is rendered VERBATIM - same content the LLM receives, only soft-
wrapped to fit the dialog width. No markdown, no truncation, no
reformatting.
Returns nil on Esc. Supports keyboard scrolling.
sourceraw docstring

transient-item-by-keyclj

(transient-item-by-key spec ch)

PURE: the transient spec item bound to single character ch (a Character or string), scanning every group in order. nil when nothing is bound.

PURE: the transient spec item bound to single character `ch` (a Character or
string), scanning every group in order. nil when nothing is bound.
sourceraw docstring

transient-toggleclj

(transient-toggle spec state ch)

PURE reducer for ONE keystroke against a magit transient state ({:switches #{ids} :options {id val}}). Returns a map whose :kind tells the impure caller what to do next: {:kind :continue :state s'} a SWITCH flipped (or an unbound key — no-op) {:kind :option :item it} an OPTION was hit; caller reads a value then re-enters with it stored under [:options id] {:kind :action :item it} an ACTION fires; caller runs it and closes. Switches are the only kind this fn mutates; options/actions leave state untouched (the impure loop finishes their job).

PURE reducer for ONE keystroke against a magit transient `state`
(`{:switches #{ids} :options {id val}}`). Returns a map whose `:kind` tells
the impure caller what to do next:
  {:kind :continue :state s'}  a SWITCH flipped (or an unbound key — no-op)
  {:kind :option   :item it}   an OPTION was hit; caller reads a value then
                                re-enters with it stored under [:options id]
  {:kind :action   :item it}   an ACTION fires; caller runs it and closes.
Switches are the only kind this fn mutates; options/actions leave `state`
untouched (the impure loop finishes their job).
sourceraw docstring

update-modal-close-hover!clj

(update-modal-close-hover! key)

On a MOVE/DRAG event, set the thread-local close-hover flag when the cursor is within the recorded close-button bounds, clear it otherwise. Lets the modal close (X) button light up on hover like the header/overlay buttons.

On a MOVE/DRAG event, set the thread-local close-hover flag when the cursor
is within the recorded close-button bounds, clear it otherwise. Lets the
modal close (X) button light up on hover like the header/overlay buttons.
sourceraw docstring

vis-logo-linesclj

ASCII rendition of the real vis emblem (logo.png) followed by the wordmark. Drawn at the top of branded dialogs (the provider auth gate). Centered + accent-colored by the caller; auto-dropped when the terminal is too short.

ASCII rendition of the real vis emblem (logo.png) followed by the
wordmark. Drawn at the top of branded dialogs (the provider auth
gate). Centered + accent-colored by the caller; auto-dropped when
the terminal is too short.
sourceraw docstring

visible-window-startclj

(visible-window-start idx current-start visible-count total-count)
source

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