fix scroll

ober

ffafa19201f072e1ede32741c6d41e714753d538

diff --git a/signal/main.ss b/signal/main.ss
index 5957444..c8bb7e8 100644
--- a/signal/main.ss
+++ b/signal/main.ss
@@ -143,7 +143,8 @@ linking once before using this tool:
 
 (def (main argv)
   (cond
-    [(null? argv) (usage) (exit 2)]
+    [(null? argv) (let-values ([(account args) (parse-account-flag '())])
+                     (cmd-tui account))]
     [else
      (let ([sub (car argv)]
            [rest (cdr argv)])
diff --git a/signal/tui/main.ss b/signal/tui/main.ss
index 616a3c0..8ab8a86 100644
--- a/signal/tui/main.ss
+++ b/signal/tui/main.ss
@@ -12,14 +12,14 @@
           terminal-display)
 
   (import (except (scheme)
-                  make-hash-table hash-table?
-                  sort sort!
-                  printf fprintf
-                  path-extension path-absolute?
-                  with-input-from-string with-output-to-string
-                  iota 1+ 1-
-                  partition
-                  make-date make-time)
+                   make-hash-table hash-table?
+                   sort sort!
+                   printf fprintf
+                   path-extension path-absolute?
+                   with-input-from-string with-output-to-string
+                   iota 1+ 1-
+                   partition
+                   make-date make-time)
           (except (jerboa prelude) meta atom?)
           (std csp)
           (std text json)
@@ -50,7 +50,7 @@
      conversations selected-index mode picker-query picker-index removed aliases
      logdb live-capture? resend challenge rate-limits send-events
      capture-events capture-stop-box capture-worker
-     thread-scroll mention-active? mention-index mention-candidates))
+      thread-scroll conv-scroll mention-active? mention-index mention-candidates))
 
   ;; Open the encrypted message log. Passphrase comes from JERBOA_SIGNAL_DB_KEY
   ;; if set (enables headless use), otherwise we prompt. A blank passphrase or a
@@ -207,10 +207,11 @@
                     (make-channel/buf 256)
                      (box #f)
                      #f
-                     0
-                     #f
-                     0
-                     '()))
+                      0
+                      0
+                      #f
+                      0
+                      '()))
 
   ;; Pull recent rows out of the encrypted log so search and scrollback cover
   ;; previous sessions, not just this one. Runs after contact/group seeding so
@@ -1033,6 +1034,16 @@
           (tui-state-selected-index-set! state next-index)
           (conversation-unread-set! conv 0)
           (tui-state-thread-scroll-set! state 0)
+          ;; Auto-scroll conversations list so selection is visible.
+          ;; The visible area shows `height` rows starting at conv-scroll.
+          (let* ([body-h (max 4 (- (tui-state-height state) 4))]
+                 [left-w (if (< (tui-state-width state) 80) 18 24)]
+                 [height (- body-h 3)]
+                 [scroll (tui-state-conv-scroll state)])
+            (when (>= next-index (+ scroll height))
+              (tui-state-conv-scroll-set! state (- next-index (- height 1))))
+            (when (< next-index scroll)
+              (tui-state-conv-scroll-set! state next-index)))
           (cancel-mention! state)
           (tui-state-status-set!
             state
@@ -2633,26 +2644,36 @@
 
   (def (draw-conversations! state x y width height)
     (let* ([conversations (tui-state-conversations state)]
-           [selected-index (clamp-index (tui-state-selected-index state)
-                                        (length conversations))])
-      (let loop ([conversations conversations]
-                 [idx 0]
-                 [row y])
-        (when (and (pair? conversations) (< row (+ y height)))
-        (let* ([conv (car conversations)]
-               [selected? (= idx selected-index)]
-               [marker (if selected? "> " "  ")]
-               [unread (conversation-unread conv)]
-               [suffix (if (> unread 0)
-                         (string-append " (" (number->string unread) ")")
-                         "")]
-               [fgc (if selected? (fg-accent) (fg))]
-               [bgc (if selected? (selected-bg) (panel-bg))])
-          (draw-text! x row width fgc bgc
-                      (string-append marker
-                                     (conversation-title conv)
-                                     suffix))
-          (loop (cdr conversations) (+ idx 1) (+ row 1)))))))
+           [total (length conversations)]
+           [selected-index (clamp-index (tui-state-selected-index state) total)]
+           [scroll (tui-state-conv-scroll state)]
+           [max-scroll (max 0 (- total height))])
+      ;; Scroll indicator (up arrow if scroll > 0)
+      (when (> scroll 0)
+        (draw-text! x y width (fg-dim) (panel-bg) "^"))
+      ;; Draw visible slice
+      (let loop ([idx scroll]
+                 [row (+ y (if (> scroll 0) 1 0))])
+        (when (and (< idx total) (< row (+ y height)))
+          (let* ([conv (list-ref conversations idx)]
+                 [selected? (= idx selected-index)]
+                 [marker (if selected? "> " "  ")]
+                 [unread (conversation-unread conv)]
+                 [suffix (if (> unread 0)
+                            (string-append " (" (number->string unread) ")")
+                            "")]
+                 [fgc (if selected? (fg-accent) (fg))]
+                 [bgc (if selected? (selected-bg) (panel-bg))])
+            (draw-text! x row width fgc bgc
+                        (string-append marker
+                                       (conversation-title conv)
+                                       suffix))
+            (loop (+ idx 1) (+ row 1)))))
+      ;; Scroll indicator (down arrow if more items below)
+      (when (< (+ scroll height) total)
+        (let* ([ind-row (+ y height -1)]
+               [ind-row (if (> scroll 0) ind-row (- ind-row 1))])
+          (draw-text! x ind-row width (fg-dim) (panel-bg) "v")))))
 
   (def (draw-new-message-page! state x y width height)
     (draw-panel! x y width height "New Message")
@@ -2834,7 +2855,10 @@
                                                 width
                                                 rows
                                                 scroll)])
-            (let loop ([rs rendered] [row (+ y 3)])
+            ;; Scroll indicator (up arrow if scroll > 0)
+            (when (> scroll 0)
+              (draw-text! x (+ y 3) width (fg-dim) (bg) "^"))
+            (let loop ([rs rendered] [row (+ y 3 (if (> scroll 0) 1 0))])
               (if (and (pair? rs) (< row (+ y 3 rows)))
                 (begin
                   (draw-text! x row width (chat-message-fg (caar rs)) (bg)
@@ -2842,7 +2866,11 @@
                   (loop (cdr rs) (+ row 1)))
                 (when (and typing (< row (+ y height)))
                   (draw-text! x row width (fg-dim) (bg)
-                              (string-append typing " is typing...")))))))
+                              (string-append typing " is typing...")))))
+            ;; Scroll indicator (down arrow if more rows below)
+            (let* ([max-scroll (max-thread-scroll conv width rows)])
+              (when (< scroll max-scroll)
+                (draw-text! x (+ y height -1) width (fg-dim) (bg) "v")))))
         (begin
           (draw-text! x y width (fg-strong) (bg) "jerboa-signal")
           (draw-text! x (+ y 1) width (fg-dim) (bg)
@@ -2899,6 +2927,17 @@
             (clamp-index (+ (tui-state-thread-scroll state) delta)
                          (+ max-scroll 1)))))))
 
+  ;; Scroll the conversations list. Positive delta scrolls down.
+  (def (scroll-conversations! state delta)
+    (let* ([total (length (tui-state-conversations state))]
+           [body-h (max 4 (- (tui-state-height state) 4))]
+           [left-w (if (< (tui-state-width state) 80) 18 24)]
+           [height (- body-h 3)]
+           [max-scroll (max 0 (- total height))]
+           [scroll (tui-state-conv-scroll state)]
+           [new-scroll (clamp-index (+ scroll delta) (+ max-scroll 1))])
+      (tui-state-conv-scroll-set! state new-scroll)))
+
   ;; --- @mention support ---
 
   ;; All direct conversation titles (contact names) as mention candidates.