v0.8.1: deduplication cleanup — remove duplicate defpackage/defvar blocks from programming-tools, duplicate plist-keywords-normalize from programming-lisp, duplicate *VAULT-MEMORY* from security-vault; TUI defensive fixes — add word-wrap function, wrap on-key in ignore-errors; daemon startup hardening — optional skill loads with handler-case

This commit is contained in:
2026-05-10 07:10:47 -04:00
parent 2ac87b626a
commit 27d203ad67
11 changed files with 78 additions and 271 deletions

View File

@@ -1300,7 +1300,7 @@ if the user reopens it within the same session. State is per-session only
(recreate-windows (or (width scr) 80) (or (height scr) 24))
(redraw sw cw ch iw)
(refresh scr))
(t (on-key ch))))
(t (ignore-errors (on-key ch)))))
(redraw sw cw ch iw)
(when sidebar-w
(view-sidebar sidebar-w)

View File

@@ -218,7 +218,7 @@ that the TUI actuator attaches to the response plist before transmission.
(search-highlight content (st :search-query))
content))
(line-text (format nil "~a [~a] ~a" prefix time content-show))
(wrapped (word-wrap line-text (- w 2)))
(wrapped (passepartout::word-wrap line-text (- w 2)))
(nlines (length wrapped)))
(if (<= nlines lines-remaining)
(progn (decf lines-remaining nlines) (incf msg-count))
@@ -240,7 +240,7 @@ that the TUI actuator attaches to the response plist before transmission.
(search-highlight content (st :search-query))
content))
(line-text (format nil "~a [~a] ~a" prefix time content-show))
(wrapped (word-wrap line-text (- w 2))))
(wrapped (passepartout::word-wrap line-text (- w 2))))
;; HITL panel: render with colored border
(when is-panel
(setf color (if is-resolved
@@ -313,6 +313,34 @@ ASCII < 128 = 1. CJK, fullwidth, emoji = 2. Combining marks = 0. Tab = 8."
((<= #x20D0 code #x20FF) 0)
((<= #xFE00 code #xFE0F) 0)
(t 1))))
(defun word-wrap (text max-width)
"Split TEXT into lines that fit within MAX-WIDTH columns.
Word-breaks at spaces when possible; breaks mid-word if necessary.
Respects CJK/emoji char widths via char-width."
(let ((lines nil)
(start 0)
(end (length text)))
(loop while (< start end) do
(let* ((col 0)
(pos start)
(last-break start))
(loop while (< pos end)
for width = (char-width (char text pos)) do
(when (char= (char text pos) #\Space)
(setf last-break pos))
(when (> (+ col width) max-width)
(return))
(incf col width)
(incf pos)
(when (>= pos end) (return)))
(let ((line-end (if (> pos start) pos (1+ start))))
(when (>= line-end end) (setf line-end end))
(push (subseq text start line-end) lines)
(setf start (if (and (< line-end end) (char= (char text line-end) #\Space))
(1+ line-end)
line-end)))))
(nreverse lines)))
#+end_src
* v0.7.1 — Markdown Rendering

View File

@@ -236,33 +236,6 @@ The skill has four layers:
** Plist Keywords Normalize (relocated from core-reason)
Lisp keywords are case-sensitive. The LLM might produce ~:payload~ or ~:PAYLOAD~ depending on the model. This function normalizes keyword keys to uppercase.
#+begin_src lisp
(defun plist-keywords-normalize (plist)
(when (listp plist)
(loop for (k v) on plist by #'cddr
collect (if (and (symbolp k) (not (keywordp k)))
(intern (string k) :keyword)
k)
collect v)))
#+end_src
** Plist Keywords Normalize (relocated from core-reason)
Lisp keywords are case-sensitive. The LLM might produce :payload or :PAYLOAD depending on the model. This function normalizes keyword keys to uppercase.
#+begin_src lisp

View File

@@ -382,7 +382,7 @@ Surgical text replacement in an Org file — matches exact text and replaces it.
** Package Definition and Export List
The package definition. All public symbols are exported here.
#+begin_src lisp
#+begin_src lisp :tangle no
(defpackage :passepartout
(:use :cl)
(:export
@@ -555,7 +555,7 @@ The package implementation section defines the low-level utilities and global st
*** Robust plist access (plist-get)
Retrieves a value from a plist, checking both upper and lowercase keyword variants. This is needed because different components use different keyword conventions.
#+begin_src lisp
#+begin_src lisp :tangle no
(in-package :passepartout)
(defun plist-get (plist key)
@@ -568,7 +568,7 @@ Retrieves a value from a plist, checking both upper and lowercase keyword varian
*** Logging state
The harness maintains a bounded ring buffer of log messages for inclusion in LLM context. Access is thread-safe via a lock.
#+begin_src lisp
#+begin_src lisp :tangle no
(defvar *log-buffer* nil)
(defvar *log-lock* (bordeaux-threads:make-lock "log-messages-lock"))
(defvar *log-limit* 100)
@@ -576,14 +576,14 @@ The harness maintains a bounded ring buffer of log messages for inclusion in LLM
*** Skill registry
The global registry of all loaded skills. This is the authoritative list that the deterministic engine iterates.
#+begin_src lisp
#+begin_src lisp :tangle no
(defvar *skill-registry* (make-hash-table :test 'equal)
"Global registry of all loaded skills.")
#+end_src
*** Skill telemetry
Tracks execution metrics per skill (count, duration, failures) for diagnostics and performance analysis.
#+begin_src lisp
#+begin_src lisp :tangle no
(defvar *telemetry-table* (make-hash-table :test 'equal))
(defvar *telemetry-lock* (bordeaux-threads:make-lock "harness-telemetry-lock"))
@@ -600,7 +600,7 @@ Tracks execution metrics per skill (count, duration, failures) for diagnostics a
*** Cognitive tool registry
Tools that the LLM can invoke are registered here. Each tool has a name, description, parameters, optional guard, and implementation body. The ~def-cognitive-tool~ macro handles registration. ~cognitive-tool-prompt~ serialises the registry into the LLM's system prompt.
#+begin_src lisp
#+begin_src lisp :tangle no
(defvar *cognitive-tool-registry* (make-hash-table :test 'equal))
#+end_src

View File

@@ -103,13 +103,6 @@ Delegates to the existing =vault-get=/=vault-set= with ~:type :secret~.
:trigger (lambda (ctx) (declare (ignore ctx)) nil))
#+end_src
** Vault Memory (relocated from core-skills)
#+begin_src lisp
(defvar *VAULT-MEMORY* (make-hash-table :test 'equal))
#+end_src
* Test Suite
#+begin_src lisp