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

@@ -9,8 +9,12 @@
(defun cost-track-call (provider prompt-text &optional response-text)
"Compute and accumulate the cost of a single LLM call.
Returns the cost of this call in USD."
(let* ((input-tokens (funcall (symbol-function 'count-tokens) (or prompt-text "")))
(output-tokens (if response-text (funcall (symbol-function 'count-tokens) response-text) 0))
(let* ((input-tokens (if (fboundp 'count-tokens)
(funcall (symbol-function 'count-tokens) (or prompt-text ""))
(ceiling (length (or prompt-text "")) 4)))
(output-tokens (if (and response-text (fboundp 'count-tokens))
(funcall (symbol-function 'count-tokens) response-text)
0))
(total-tokens (+ input-tokens output-tokens))
(cost (provider-token-cost provider total-tokens)))
(bordeaux-threads:with-lock-held (*session-cost-lock*)
@@ -41,13 +45,19 @@ Returns the cost of this call in USD."
(bordeaux-threads:with-lock-held (*session-cost-lock*)
(getf *session-cost* :by-provider)))
(defun cost-session-summary ()
"Returns plist (:total <float> :calls <int> :by-provider <alist>)."
(bordeaux-threads:with-lock-held (*session-cost-lock*)
(list :total (getf *session-cost* :total)
:calls (getf *session-cost* :calls)
:by-provider (getf *session-cost* :by-provider))))
(defun cost-session-reset ()
"Zeroes the session cost accumulator."
(bordeaux-threads:with-lock-held (*session-cost-lock*)
(setf (getf *session-cost* :total) 0.0)
(setf (getf *session-cost* :calls) 0)
(setf (getf *session-cost* :by-provider) nil)
(log-message "COST TRACKER: Session cost reset.")))
(setf (getf *session-cost* :by-provider) nil)))
(defun cost-format-budget-status (&optional (daily-budget nil))
"Returns a string for the TUI status bar showing session cost.
@@ -132,3 +142,15 @@ If DAILY-BUDGET is provided, includes percentage of budget used."
(cost-session-reset)
(let ((cost (cost-track-call :deepseek "test")))
(is (> cost 0.0))))
(test test-cost-session-summary
"Contract 5: cost-session-summary returns plist with total, calls, by-provider."
(cost-session-reset)
(cost-track-call :deepseek "hello")
(cost-track-call :groq "world")
(let ((s (cost-session-summary)))
(is (> (getf s :total) 0.0))
(is (= 2 (getf s :calls)))
(let ((by (getf s :by-provider)))
(is (assoc :deepseek by))
(is (assoc :groq by)))))