Files
ajet-chat/cli
2026-02-17 17:30:45 -05:00
..
2026-02-17 17:30:45 -05:00
2026-02-17 17:30:45 -05:00
2026-02-17 00:23:25 -05:00
2026-02-17 17:30:45 -05:00

CLI & TUI Client

Terminal client for ajet-chat. Provides two modes:

  • CLI Mode — stateless one-shot commands for scripting and quick interactions
  • TUI Mode — full interactive terminal application with split panes, markdown rendering, and real-time updates

Usage

# CLI commands
ajet login                          # OAuth login
ajet communities                    # List communities
ajet channels                       # List channels
ajet read general                   # Read messages
ajet send general "hello"           # Send a message
ajet tui                            # Launch interactive TUI

# TUI with options
ajet tui --community my-team        # Open to specific community
ajet tui --channel general          # Open to specific channel

Dependencies

  • clojure-tui — local dep at ../../clojure-tui (Elm architecture TUI framework)
  • babashka.http-client — HTTP client for API calls
  • clojure.data.json — JSON parsing
  • clojure.tools.cli — CLI argument parsing
  • Shared modules: api-client, markdown, mentions

TODO: clojure-tui Gaps

The TUI (tui.clj) uses clojure-tui's Elm architecture (init/update/view) for state management and rendering. However, several PRD features require capabilities that clojure-tui does not yet provide. SSE integration is worked around via a shared LinkedBlockingQueue polled every 100ms with delayed-event. Below is the complete list of gaps between the PRD requirements and clojure-tui's current capabilities.

1. Mouse Support (PRD 4.4)

PRD requires: Mouse click to select channel/message/button, mouse scroll in message list.

Gap: clojure-tui has no mouse tracking escape sequences in terminal.clj and no mouse event parsing in input.clj. The library only handles keyboard input.

Workaround: Keyboard-only navigation (Ctrl+N/P for channels, Tab for focus, arrow keys for scrolling).

To resolve: Add SGR mouse tracking (\033[?1000h\033[?1006h) to terminal.clj and mouse event parsing (button, position, scroll) to input.clj.

2. Inline Image Rendering (PRD 4.5)

PRD requires: Render images inline in message list via timg, sixel, or kitty graphics protocol.

Gap: clojure-tui has no image rendering support. Its render pipeline outputs ANSI text only.

Workaround: Images display as [image: filename.png] text placeholder.

To resolve: Add a :image render primitive that shells out to timg or emits sixel/kitty escape sequences. Requires terminal capability detection.

3. Multiline Text Input (PRD 4.4)

PRD requires: Shift+Enter or Alt+Enter inserts a newline in the input field.

Gap: clojure-tui's :input widget is single-line only. It handles backspace and character insertion but has no concept of line breaks within the input buffer.

Workaround: Messages are single-line only. No multiline composition.

To resolve: Extend :input widget to support a multi-line buffer with cursor movement across lines, or create a new :textarea widget.

4. Autocomplete Dropdowns (PRD 4.4)

PRD requires: Typing @ shows user mention dropdown, # shows channel dropdown, / shows slash command list. Tab to select.

Gap: clojure-tui has no autocomplete or dropdown widget. It has :modal and :scroll primitives but no composition for filtered-list-as-you-type behavior.

Workaround: @mentions, #channels, and /commands are typed manually without autocomplete.

To resolve: Build an autocomplete widget by composing :modal + :scroll + filtered list, with keyboard navigation. This is application-level code that could be contributed back to clojure-tui.

5. SSE Client Integration (PRD 4.7)

PRD requires: Real-time event stream from TUI session manager via Server-Sent Events.

Gap: clojure-tui's event loop (core.clj) only processes keyboard input events. It has no mechanism to inject external events (HTTP responses, SSE data) into the Elm update cycle.

Workaround: A background thread reads SSE via HttpURLConnection and writes parsed events to a shared LinkedBlockingQueue. The Elm loop polls this queue every 100ms via delayed-event, draining events and processing them in the :update function. This works but adds up to 100ms latency.

To resolve: Add an external event channel to clojure-tui's run function (e.g., accept a core.async channel that the event loop merges with stdin input via alt!). This would eliminate polling and allow SSE events to flow through :update with zero latency.

6. Terminal Bell (PRD 4.8)

PRD requires: Terminal bell (\a) on new @mention or DM.

Gap: clojure-tui's render pipeline doesn't include bell output. Trivial to implement but not part of the library's event/render model.

Workaround: Not yet implemented. Can be added as (print "\u0007") (flush) in the message event handler.

To resolve: Either add a :bell event type to clojure-tui, or just emit the bell character directly in application code (outside the render cycle).

PRD requires: URLs in messages render as clickable hyperlinks using OSC 8 escape sequences (\033]8;;URL\033\\text\033]8;;\033\\).

Gap: clojure-tui's ansi.clj has ANSI color/style codes but no OSC 8 hyperlink support.

Workaround: URLs render as plain underlined text without click behavior.

To resolve: Add OSC 8 hyperlink escape sequences to ansi.clj and integrate into the :text render primitive when a :href attribute is present.

8. Spoiler Text Reveal (PRD 4.6)

PRD requires: ||spoiler|| text renders hidden (e.g., as block characters) until user presses Enter on the selected message to reveal.

Gap: This is an application-level feature requiring per-message hidden/revealed state and keypress handling. clojure-tui doesn't prevent this but provides no specific support.

Workaround: Spoiler text renders as plain text (not hidden).

To resolve: Track revealed-spoiler state per message ID in app state. Render spoiler spans as \u2588 block characters when hidden, original text when revealed. Toggle on Enter keypress when message is selected.

Summary Table

Feature PRD Section Status Blocked By
Mouse support 4.4 Not implemented clojure-tui: no mouse input
Inline images 4.5 Placeholder only clojure-tui: no image rendering
Multiline input 4.4 Single-line only clojure-tui: :input is single-line
Autocomplete 4.4 Not implemented clojure-tui: no dropdown widget
SSE integration 4.7 Queue polling (100ms) clojure-tui: no external event injection
Terminal bell 4.8 Not implemented Trivial — just needs \a output
OSC 8 hyperlinks 4.6 Not implemented clojure-tui: no OSC 8 support
Spoiler reveal 4.6 Plain text Application-level (not blocked)