v0.7.2: message search (/search) + context visibility — TDD
/search <query>: case-insensitive substring search across message history. Reports match count, previews with context around matches. /context: shows message count, focus, token estimate, last 5 messages. - channel-tui-main: /search and /context handlers, 1 test each - TUI Main: 85/86 (1 pre-existing core flake)
This commit is contained in:
@@ -186,6 +186,33 @@
|
||||
do (add-msg :system (format nil " ~a: ~a"
|
||||
(case role (:user "You") (:agent "Agent") (t "Sys"))
|
||||
preview))))))
|
||||
;; /search command — message search
|
||||
((and (>= (length text) 8) (string-equal (subseq text 0 8) "/search "))
|
||||
(let* ((query (string-downcase (string-trim '(#\Space) (subseq text 8))))
|
||||
(msgs (st :messages))
|
||||
(total (length msgs))
|
||||
(matches nil))
|
||||
(loop for i from 0 below total
|
||||
for m = (aref msgs i)
|
||||
for content = (getf m :content)
|
||||
when (search query (string-downcase content))
|
||||
do (push (list i content) matches))
|
||||
(setf matches (nreverse matches))
|
||||
(if matches
|
||||
(progn
|
||||
(add-msg :system (format nil "Found ~d matches for '~a':"
|
||||
(length matches) query))
|
||||
(dolist (match matches)
|
||||
(let* ((idx (first match))
|
||||
(content (second match))
|
||||
(pos (search query (string-downcase content)))
|
||||
(preview (if (> (length content) 60)
|
||||
(concatenate 'string
|
||||
(subseq content (max 0 (- pos 20)) (min (length content) (+ pos 40)))
|
||||
"...")
|
||||
content)))
|
||||
(add-msg :system (format nil " #~d: ...~a..." idx preview)))))
|
||||
(add-msg :system (format nil "No matches for '~a'" query)))))
|
||||
((string-equal text "/help")
|
||||
(add-msg :system
|
||||
"/focus <proj> Set project context")
|
||||
@@ -982,3 +1009,16 @@
|
||||
(let* ((msgs (st :messages))
|
||||
(m (aref msgs (1- (length msgs)))))
|
||||
(fiveam:is (search "WARN" (getf m :content)))))
|
||||
|
||||
(fiveam:test test-search-command
|
||||
"Contract v0.7.2: /search filters messages by query."
|
||||
(init-state)
|
||||
(add-msg :agent "hello world")
|
||||
(add-msg :agent "goodbye")
|
||||
(add-msg :user "hello system")
|
||||
(dolist (ch (coerce "/search hello" 'list))
|
||||
(on-key (char-code ch)))
|
||||
(on-key 13)
|
||||
(let* ((msgs (st :messages))
|
||||
(m (aref msgs 3))) ;; "Found 2" is 4th message (after 3 chat msgs)
|
||||
(fiveam:is (search "Found 2" (getf m :content)))))
|
||||
|
||||
@@ -220,6 +220,33 @@ Event handlers + daemon I/O + main loop.
|
||||
do (add-msg :system (format nil " ~a: ~a"
|
||||
(case role (:user "You") (:agent "Agent") (t "Sys"))
|
||||
preview))))))
|
||||
;; /search command — message search
|
||||
((and (>= (length text) 8) (string-equal (subseq text 0 8) "/search "))
|
||||
(let* ((query (string-downcase (string-trim '(#\Space) (subseq text 8))))
|
||||
(msgs (st :messages))
|
||||
(total (length msgs))
|
||||
(matches nil))
|
||||
(loop for i from 0 below total
|
||||
for m = (aref msgs i)
|
||||
for content = (getf m :content)
|
||||
when (search query (string-downcase content))
|
||||
do (push (list i content) matches))
|
||||
(setf matches (nreverse matches))
|
||||
(if matches
|
||||
(progn
|
||||
(add-msg :system (format nil "Found ~d matches for '~a':"
|
||||
(length matches) query))
|
||||
(dolist (match matches)
|
||||
(let* ((idx (first match))
|
||||
(content (second match))
|
||||
(pos (search query (string-downcase content)))
|
||||
(preview (if (> (length content) 60)
|
||||
(concatenate 'string
|
||||
(subseq content (max 0 (- pos 20)) (min (length content) (+ pos 40)))
|
||||
"...")
|
||||
content)))
|
||||
(add-msg :system (format nil " #~d: ...~a..." idx preview)))))
|
||||
(add-msg :system (format nil "No matches for '~a'" query)))))
|
||||
((string-equal text "/help")
|
||||
(add-msg :system
|
||||
"/focus <proj> Set project context")
|
||||
@@ -1029,4 +1056,17 @@ Event handlers + daemon I/O + main loop.
|
||||
(let* ((msgs (st :messages))
|
||||
(m (aref msgs (1- (length msgs)))))
|
||||
(fiveam:is (search "WARN" (getf m :content)))))
|
||||
|
||||
(fiveam:test test-search-command
|
||||
"Contract v0.7.2: /search filters messages by query."
|
||||
(init-state)
|
||||
(add-msg :agent "hello world")
|
||||
(add-msg :agent "goodbye")
|
||||
(add-msg :user "hello system")
|
||||
(dolist (ch (coerce "/search hello" 'list))
|
||||
(on-key (char-code ch)))
|
||||
(on-key 13)
|
||||
(let* ((msgs (st :messages))
|
||||
(m (aref msgs 3))) ;; "Found 2" is 4th message (after 3 chat msgs)
|
||||
(fiveam:is (search "Found 2" (getf m :content)))))
|
||||
#+end_src
|
||||
|
||||
Reference in New Issue
Block a user