Web companion channel - the gateway's /ui chat instrument.
Chat-first anatomy (the ChatGPT/Claude shape): the conversation is a centered document column - user messages as compact right-aligned pills, vis answers as flat typeset prose behind a small accent avatar, the execution trace folded into a 'Work' disclosure, a floating pill composer pinned to the bottom (Enter sends, Shift+Enter breaks, auto-grows), a thin blurred sticky header, and CONTEXT - the same ctx mirror the model reads - as a quiet right rail.
Pure Clojure SSR: hiccup renders HTML, HTMX does declarative swaps,
the live feed is the htmx SSE extension consuming
/ui/session/:sid/stream - a gateway SSE stream of named HTML
fragments (activity/thinking/context) rendered server-side. Every
script is VENDORED on the classpath and served from memory
(htmx 2.0.10 + its SSE extension + ui.js) - a page
never loads anything from outside vis.
This namespace is the THIRD canonical-IR walker: the TUI walks IR
into ANSI cells, Telegram walks it into its HTML subset, and
ir->hiccup walks the same IR into DOM (GATEWAY.md §4.1 ALWAYS IR).
AUTO-MOUNT: the extension declares a :gateway.slot/http-routes
contribution; the gateway pulls it whenever it builds its handler
(whiteboard pattern - no ordering requirement, see GATEWAY.md §10.1).
Auth: none on the loopback default (gateway-auth-required? false);
when the gate is on, POST /ui/auth exchanges the bearer token for an
HttpOnly vis_token cookie that EventSource carries on SSE connect.
Theme: vis-light - white surfaces, slate neutrals, one indigo accent -
CSS variables lifted 1:1 from internal/theme.clj light-palette.
Web companion channel - the gateway's `/ui` chat instrument. Chat-first anatomy (the ChatGPT/Claude shape): the conversation is a centered document column - user messages as compact right-aligned pills, vis answers as flat typeset prose behind a small accent avatar, the execution trace folded into a 'Work' disclosure, a floating pill composer pinned to the bottom (Enter sends, Shift+Enter breaks, auto-grows), a thin blurred sticky header, and CONTEXT - the same ctx mirror the model reads - as a quiet right rail. Pure Clojure SSR: hiccup renders HTML, HTMX does declarative swaps, the live feed is the htmx SSE extension consuming `/ui/session/:sid/stream` - a gateway SSE stream of named HTML fragments (activity/thinking/context) rendered server-side. Every script is VENDORED on the classpath and served from memory (htmx 2.0.10 + its SSE extension + ui.js) - a page never loads anything from outside vis. This namespace is the THIRD canonical-IR walker: the TUI walks IR into ANSI cells, Telegram walks it into its HTML subset, and `ir->hiccup` walks the same IR into DOM (GATEWAY.md §4.1 ALWAYS IR). AUTO-MOUNT: the extension declares a `:gateway.slot/http-routes` contribution; the gateway pulls it whenever it builds its handler (whiteboard pattern - no ordering requirement, see GATEWAY.md §10.1). Auth: none on the loopback default (`gateway-auth-required?` false); when the gate is on, POST /ui/auth exchanges the bearer token for an HttpOnly `vis_token` cookie that EventSource carries on SSE connect. Theme: vis-light - white surfaces, slate neutrals, one indigo accent - CSS variables lifted 1:1 from `internal/theme.clj` light-palette.
(channel-main args)vis channels web - start the gateway (UI auto-mounted because this
namespace is loaded), print the /ui address, park until SIGTERM.
--cloudflared additionally exposes the UI through a Cloudflare quick
tunnel (requires the cloudflared binary on PATH) and FORCES
--require-token - a public tunnel never runs without auth.
`vis channels web` - start the gateway (UI auto-mounted because this namespace is loaded), print the /ui address, park until SIGTERM. `--cloudflared` additionally exposes the UI through a Cloudflare quick tunnel (requires the `cloudflared` binary on PATH) and FORCES `--require-token` - a public tunnel never runs without auth.
(export-session-html sid)Standalone, self-contained HTML export of sid — the SAME chat view the web
/ui renders (user/vis bubbles + inline op-card trace), styled with the inlined
app.css + theme + the vendored marked/DOMPurify/Prism scripts, with a session-
summary card on top. Returns the HTML string; a 'Session not found' note (no
throw) on a bad id so pipelines stay clean.
Standalone, self-contained HTML export of `sid` — the SAME chat view the web /ui renders (user/vis bubbles + inline op-card trace), styled with the inlined app.css + theme + the vendored marked/DOMPurify/Prism scripts, with a session- summary card on top. Returns the HTML string; a 'Session not found' note (no throw) on a bad id so pipelines stay clean.
(ir->hiccup node)Walk a canonical IR node ([:tag {attrs}? & children], strings,
seqs) into hiccup. Total: unknown tags degrade to classed divs,
non-IR leaves degrade to strings. Never throws on model output.
Walk a canonical IR node (`[:tag {attrs}? & children]`, strings,
seqs) into hiccup. Total: unknown tags degrade to classed divs,
non-IR leaves degrade to strings. Never throws on model output.(stream-handler request)Live-only SSE stream of HTML fragments for the session page. Same
replay-then-live monitor discipline as the JSON stream, but the
cursor pins to gateway-current-seq so the page (which rendered
current state) receives only what happens next.
Live-only SSE stream of HTML fragments for the session page. Same replay-then-live monitor discipline as the JSON stream, but the cursor pins to `gateway-current-seq` so the page (which rendered current state) receives only what happens next.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |