diff --git a/lisp/channel-tui-state.lisp b/lisp/channel-tui-state.lisp index e1d9d49..19ca8a2 100644 --- a/lisp/channel-tui-state.lisp +++ b/lisp/channel-tui-state.lisp @@ -114,7 +114,8 @@ See *tui-theme-presets* for named presets (dark, light, solarized, gruvbox).") :scroll-offset 0 :busy nil :cursor-pos 0 :pending-ctrl-x nil :scroll-at-bottom t :scroll-notify nil - :streaming-text nil :url-buffer nil ; v0.7.1 + :streaming-text nil :url-buffer nil ; v0.7.1 + :collapsed-gates nil ; v0.7.2 :dirty (list nil nil nil)))) (defun now () diff --git a/lisp/channel-tui-view.lisp b/lisp/channel-tui-view.lisp index 1796340..f9dc19b 100644 --- a/lisp/channel-tui-view.lisp +++ b/lisp/channel-tui-view.lisp @@ -86,14 +86,21 @@ Returns list of trimmed strings. Single words wider than width are split." (prefix (case role (:user "⬆") (:agent "⬇") (t " "))) (line-text (format nil "~a [~a] ~a" prefix time content)) (wrapped (word-wrap line-text (- w 2)))) - (dolist (line wrapped) - (when (< y (1- h)) - (if (eq role :agent) - (let ((segments (parse-markdown-spans line))) - (setf y (render-styled win segments y 1 w))) - (progn - (add-string win line :y y :x 1 :n (1- w) :fgcolor color) - (incf y)))))))))) + (dolist (line wrapped) + (when (< y (1- h)) + (if (eq role :agent) + (let ((segments (parse-markdown-spans line))) + (setf y (render-styled win segments y 1 w))) + (progn + (add-string win line :y y :x 1 :n (1- w) :fgcolor color) + (incf y))))) + ;; v0.7.2: gate trace below agent messages + (let ((gate-trace (getf msg :gate-trace))) + (when (and gate-trace (not (member i (st :collapsed-gates)))) + (dolist (entry (passepartout::gate-trace-lines gate-trace)) + (when (< y (1- h)) + (add-string win (car entry) :y y :x 3 :n (- w 4) :fgcolor (or (getf (cdr entry) :fgcolor) :dim)) + (incf y)))))))))) (refresh win)) (defun view-input (win) @@ -386,3 +393,9 @@ ASCII < 128 = 1. CJK, fullwidth, emoji = 2. Combining marks = 0. Tab = 8." '((:gate "network" :result :approval))))) (is (= 1 (length lines))) (is (search "HITL" (caar lines))))) + +(test test-init-state-has-collapsed-gates + "Contract v0.7.2: init-state includes :collapsed-gates field." + (passepartout.channel-tui::init-state) + (let ((cg (passepartout.channel-tui::st :collapsed-gates))) + (is (null cg)))) diff --git a/org/channel-tui-state.org b/org/channel-tui-state.org index 061807a..ae9b983 100644 --- a/org/channel-tui-state.org +++ b/org/channel-tui-state.org @@ -134,7 +134,8 @@ See *tui-theme-presets* for named presets (dark, light, solarized, gruvbox).") :scroll-offset 0 :busy nil :cursor-pos 0 :pending-ctrl-x nil :scroll-at-bottom t :scroll-notify nil - :streaming-text nil :url-buffer nil ; v0.7.1 + :streaming-text nil :url-buffer nil ; v0.7.1 + :collapsed-gates nil ; v0.7.2 :dirty (list nil nil nil)))) #+end_src diff --git a/org/channel-tui-view.org b/org/channel-tui-view.org index 7cde77b..5254c4d 100644 --- a/org/channel-tui-view.org +++ b/org/channel-tui-view.org @@ -134,14 +134,21 @@ Returns list of trimmed strings. Single words wider than width are split." (prefix (case role (:user "⬆") (:agent "⬇") (t " "))) (line-text (format nil "~a [~a] ~a" prefix time content)) (wrapped (word-wrap line-text (- w 2)))) - (dolist (line wrapped) - (when (< y (1- h)) - (if (eq role :agent) - (let ((segments (parse-markdown-spans line))) - (setf y (render-styled win segments y 1 w))) - (progn - (add-string win line :y y :x 1 :n (1- w) :fgcolor color) - (incf y)))))))))) + (dolist (line wrapped) + (when (< y (1- h)) + (if (eq role :agent) + (let ((segments (parse-markdown-spans line))) + (setf y (render-styled win segments y 1 w))) + (progn + (add-string win line :y y :x 1 :n (1- w) :fgcolor color) + (incf y))))) + ;; v0.7.2: gate trace below agent messages + (let ((gate-trace (getf msg :gate-trace))) + (when (and gate-trace (not (member i (st :collapsed-gates)))) + (dolist (entry (passepartout::gate-trace-lines gate-trace)) + (when (< y (1- h)) + (add-string win (car entry) :y y :x 3 :n (- w 4) :fgcolor (or (getf (cdr entry) :fgcolor) :dim)) + (incf y)))))))))) (refresh win)) #+end_src @@ -452,4 +459,10 @@ ASCII < 128 = 1. CJK, fullwidth, emoji = 2. Combining marks = 0. Tab = 8." '((:gate "network" :result :approval))))) (is (= 1 (length lines))) (is (search "HITL" (caar lines))))) + +(test test-init-state-has-collapsed-gates + "Contract v0.7.2: init-state includes :collapsed-gates field." + (passepartout.channel-tui::init-state) + (let ((cg (passepartout.channel-tui::st :collapsed-gates))) + (is (null cg)))) #+end_src