Files
passepartout/org/gateway-tui-model.org
Amr Gharbeia cd86509e3a
Some checks failed
Deploy (Gitea) / deploy (push) Failing after 2s
v0.3.0 finish: TUI tests, embedding wiring, gateway :configured, focus commands, export cleanup
- TUI: Fix stale contract (remove handle-return/*incoming-msgs*), rewrite
  10->13 tests (38 checks, 100% pass). Export missing symbols from TUI
  package. Fix view-chat contract arity.
- Gateway messaging: Add :configured key to registry (boolean, nil default).
  Fix contract to match (vault-based, not env-var-based).
- Async Embedding Gateway: Add *embedding-backend* var, embeddings-compute
  function. Modify ingest-ast to populate vectors on new objects.
  Add EMBEDDING_PROVIDER env var support. Add Contract + 4 tests (8 checks).
- Context Manager: Add /focus, /scope, /unfocus commands to TUI on-key
  handler. Commands degrade gracefully when context-manager not loaded.
- Export hygiene: Remove 30+ ghost exports (undefined symbols). Remove
  duplicate/mismatched names. Exports now match actual definitions.
2026-05-05 17:42:03 -04:00

2.1 KiB

Passepartout TUI — Model

Model

The TUI state is a single plist accessed via st / (setf st). All state mutation flows through event handlers in the controller.

Contract

  1. (init-state): returns a fresh state plist with :msgs list, :input buffer, :dirty flag, and :connection status.
  2. (add-msg type text): appends a message to the :msgs list in *state*, tagged with a timestamp and type. Truncates at the message buffer limit.
  3. (queue-event ev): thread-safely enqueues an event for the reader loop. (drain-queue) returns and clears the queue.

Package + State

(defpackage :passepartout.gateway-tui
  (:use :cl :croatoan :passepartout :usocket :bordeaux-threads)
  (:export :tui-main :st :add-msg :now :input-string
           :queue-event :drain-queue :init-state
           :view-status :view-chat :view-input :redraw
           :on-key :on-daemon-msg :send-daemon
           :connect-daemon :disconnect-daemon))
(in-package :passepartout.gateway-tui)

(defvar *state* nil)
(defvar *event-queue* nil)
(defvar *event-lock* (bt:make-lock "tui-event-lock"))

(defun st (key) (getf *state* key))
(defun (setf st) (val key) (setf (getf *state* key) val))

(defun init-state ()
  (setf *state*
        (list :running t :mode :chat :connected nil :stream nil
              :input-buffer nil :input-history nil :input-hpos 0
              :messages nil :scroll-offset 0 :dirty (list nil nil nil))))

Helpers

(defun now ()
  (multiple-value-bind (h m) (get-decoded-time)
    (format nil "~2,'0d:~2,'0d" h m)))

(defun input-string ()
  (coerce (reverse (st :input-buffer)) 'string))

(defun add-msg (role content)
  (push (list :role role :content content :time (now)) (st :messages))
  (setf (st :dirty) (list t t nil)))

Event Queue

(defun queue-event (ev)
  (bt:with-lock-held (*event-lock*) (push ev *event-queue*)))

(defun drain-queue ()
  (bt:with-lock-held (*event-lock*)
    (let ((evs (nreverse *event-queue*)))
      (setf *event-queue* nil) evs)))