v0.8.0: Information Radiator, Command Palette, TrueColor Themes, Setup Wizard

- Sidebar: permanent 42-col panel with 7 data panels (Gate Trace, Focus,
  Rules, Context gauge, Files, Cost, Protection); 4-window Croatoan layout
  at >=120 cols, toggle via Ctrl+X+B
- Command palette: Ctrl+P overlay with fuzzy-filtered categorized items,
  keyboard navigation, Enter to execute; view-palette rendering
- TrueColor themes: 4 new presets (nord, tokyonight, catppuccin, monokai)
  with 27 hex keys via theme-hex-to-rgb
- Setup wizard: Ctrl+\ /setup 4-step overlay (provider, key, memory, save)
  writing .env with in-TUI rendering
- Daemon enrichment: dispatcher block counts, cost session summary,
  modified files tracking, context usage percentage
- Daemon fixes: fboundp guards for count-tokens/provider-token-cost,
  tool registry save/restore in safety tests, SELF_BUILD_MODE cleanup
- 139 tests pass across all suites (0 failures)
This commit is contained in:
2026-05-09 15:00:14 -04:00
parent d77d41f3a8
commit 2ac87b626a
17 changed files with 2916 additions and 528 deletions

View File

@@ -27,6 +27,19 @@ core-reason thin while enabling token economics as a hot-loadable skill.
Depends on: tokenizer.lisp, cost-tracker.lisp
** v0.8.0 — Context Usage for Sidebar
The sidebar's Context gauge needs a single integer: 0-100 representing
how much of the token budget is consumed. ~context-usage-percentage~
computes this from ~*context-cache*~'s stored token counts and
~CONTEXT_MAX_TOKENS~ (or the model's context limit from ~tokenizer~).
The function is a thin wrapper (~8 lines): read the most recent context
assembly's token count from ~*context-cache*~, divide by the budget,
multiply by 100, clamp to [0, 100]. Called from ~core-act.org~'s ~:tui~
actuator via ~fboundp~ guard. Degrades gracefully to nil when
token-economics is not loaded.
** Contract
1. (prompt-prefix-cached assistant-name identity-content feedback mandates-text tool-belt):
@@ -44,6 +57,10 @@ Depends on: tokenizer.lisp, cost-tracker.lisp
L3: downgrade context to single-line summary
Returns (values trimmed-prefix trimmed-ctxt trimmed-logs trimmed-user trimmed-mandates).
4. (token-economics-initialize): zeroes the cache state at daemon boot.
5. (context-usage-percentage): returns integer 0-100 representing
current token budget consumption from ~*context-cache*~. Clamped.
Returns nil when no context cache data is available. Consumed by
the TUI actuator for the sidebar Context gauge (v0.8.0).
* Implementation
@@ -57,7 +74,9 @@ Depends on: tokenizer.lisp, cost-tracker.lisp
(defvar *prompt-prefix-cache* (cons nil "")
"Prompt prefix cache: (sxhash . cached-string). Rebuilt when IDENTITY or TOOLS change.")
(defvar *context-cache* (list :foveal-id nil :scope nil :memory-timestamp 0 :rendered "")
(defvar *context-cache* (list :foveal-id nil :scope nil :memory-timestamp 0 :rendered ""
:identity-tokens 0 :tool-tokens 0 :context-tokens 0
:log-tokens 0 :config-tokens 0 :time-tokens 0)
"Context assembly cache: metadata + last rendered context string.")
#+end_src
@@ -127,7 +146,9 @@ with trimmed sections."
(ignore-errors
(parse-integer (uiop:getenv "CONTEXT_MAX_TOKENS")))
16384)))
(labels ((ct (s) (funcall (symbol-function 'count-tokens) s))
(labels ((ct (s) (if (fboundp 'count-tokens)
(funcall (symbol-function 'count-tokens) s)
(ceiling (length s) 4)))
(total-tokens (p c l u m)
(+ (ct p)
(if c (ct c) 0)
@@ -169,6 +190,25 @@ with trimmed sections."
(getf *context-cache* :rendered) ""))
#+end_src
** Contract 5: context usage percentage (v0.8.0)
#+begin_src lisp
(defun context-usage-percentage ()
"Returns integer 0-100: current token budget consumption.
Returns nil when no context cache data is available."
(let* ((limit (or (ignore-errors
(parse-integer (uiop:getenv "CONTEXT_MAX_TOKENS")))
16384))
(tokens (+ (or (getf *context-cache* :identity-tokens) 0)
(or (getf *context-cache* :tool-tokens) 0)
(or (getf *context-cache* :context-tokens) 0)
(or (getf *context-cache* :log-tokens) 0)
(or (getf *context-cache* :config-tokens) 0)
(or (getf *context-cache* :time-tokens) 0))))
(if (> tokens 0)
(min 100 (floor (* 100 tokens) limit))
nil)))
#+end_src
* Test Suite
#+begin_src lisp
(eval-when (:compile-toplevel :load-toplevel :execute)
@@ -270,3 +310,38 @@ with trimmed sections."
(is (string= "" (cdr passepartout::*prompt-prefix-cache*)))
(is (string= "" (getf passepartout::*context-cache* :rendered))))
#+end_src
* v0.8.0 Tests — Context Usage
#+begin_src lisp
(in-package :passepartout-token-economics-tests)
(test test-context-usage-percentage
"Contract 5: context-usage-percentage returns integer 0-100."
;; Set up a cache with known token counts
(let* ((ctx passepartout::*context-cache*)
(limit (or (ignore-errors (parse-integer (uiop:getenv "CONTEXT_MAX_TOKENS")))
16384)))
(setf (getf ctx :identity-tokens) 1000
(getf ctx :tool-tokens) 500
(getf ctx :context-tokens) 2000
(getf ctx :log-tokens) 800
(getf ctx :config-tokens) 200
(getf ctx :time-tokens) 100)
(let ((pct (passepartout::context-usage-percentage)))
(is (integerp pct))
(is (<= 0 pct 100)))))
(test test-context-usage-percentage-empty-cache
"Contract 5: context-usage-percentage returns nil with no cache data."
(let ((saved-ctx (copy-list passepartout::*context-cache*)))
(unwind-protect
(progn
(setf (getf passepartout::*context-cache* :identity-tokens) nil
(getf passepartout::*context-cache* :tool-tokens) nil
(getf passepartout::*context-cache* :context-tokens) nil
(getf passepartout::*context-cache* :log-tokens) nil
(getf passepartout::*context-cache* :config-tokens) nil
(getf passepartout::*context-cache* :time-tokens) nil)
(is (null (passepartout::context-usage-percentage))))
(setf passepartout::*context-cache* saved-ctx))))
#+end_src