Changeset 0.11.0 (#62)

This commit is contained in:
2026-02-25 13:29:15 +00:00
parent d2ec55b16d
commit c9d8e9457e
56 changed files with 5664 additions and 91 deletions

View File

@@ -2,6 +2,92 @@
All notable changes to Chat Switchboard.
## [0.11.0] — 2026-02-25
### Added
- **Browser extension system.** Full lifecycle: manifest registration, script
injection, scoped context (`ctx.renderers`, `ctx.tools`, `ctx.events`,
`ctx.storage`, `ctx.ui`), permission-aware API proxying. Extensions self-
register via `Extensions.register()` and receive isolated contexts during
`initAll()`. Admin CRUD endpoints, asset serving (public, no auth needed
for `<script>` tag loading), auto-seeder for builtin extensions.
- **Custom renderer pipeline.** Block renderers intercept code fences by
language tag, post renderers process the DOM after insertion. Case-
insensitive language matching handles LLM capitalization (`Mermaid`,
`Diff`, `CSV`). Nested ` ```markdown ``` ` fence unwrapping prevents the
common LLM pattern of wrapping responses in markdown fences from breaking
inner code blocks.
- **Browser tool bridge.** Extensions register tool handlers via
`ctx.tools.handle()`. Server collects browser tool schemas alongside
server tools, includes them in LLM completions. Tool calls route through
WebSocket EventBus (`tool.call.*` → browser → `tool.result.*` → server).
30-second timeout with error recovery.
- **Server tools: calculator and datetime.** Auto-register via `init()`,
zero wiring changes. Calculator: recursive-descent evaluator with
arithmetic, 17 math functions, constants. Datetime: current date/time/
timezone/unix/ISO-week in any IANA timezone.
- **6 built-in browser extensions** (self-contained, own CSS via
`_injectStyles()`/`destroy()` lifecycle):
- **Mermaid**: block + post renderer, SVG diagrams, dark mode detection,
local vendor with CDN fallback, max-height constraint with scroll
- **KaTeX**: block renderer (` ```latex/math/tex ```) + post renderer
(inline `$...$` and `$$...$$` in text nodes)
- **CSV Table**: block renderer, RFC 4180 parser with quoted fields,
sortable columns (click headers), numeric-aware sorting
- **Diff Viewer**: block renderer, red/green syntax highlighting for
unified diffs, stats badge (+N/-N), hunk/file headers
- **JS Sandbox**: browser tool (`js_eval`), sandboxed iframe
(`allow-scripts` only), console capture, 10s timeout
- **Regex Tester**: browser tool (`regex_test`), multi-input matching,
full match details with named groups and indices
- **Admin extension editor.** Edit button on each extension in Admin →
Extensions. Inline editor shows name, description, manifest JSON, and
script source with tab-key support. System extensions show overwrite
warning.
- **Enhanced diagnostics.** Test 5: browser extensions (loaded, active,
renderers, tool handlers). Test 6: Service Worker cache (registration,
scope, state, cache names, entry counts). Purge Cache button in Debug
Log modal footer.
- **Extension-owned styles.** All 4 rendering extensions (mermaid, katex,
csv, diff) inject their own `<style>` tags during `init()` and remove
them during `destroy()`. Global stylesheet only keeps `.ext-rendered`
wrapper. User-created extensions can bring their own CSS without
touching the global stylesheet.
- **Notes extension rendering.** `runExtensionPostRender()` called in both
note read mode and preview mode. Mermaid diagrams and KaTeX math now
render correctly in notes.
- **Database migration 006_extensions.sql.** `extensions` and
`extension_user_settings` tables.
### Fixed
- **WebSocket token field mismatch.** API saved `{ accessToken: '...' }`
but EventBus read `tokens.access`. Tool bridge was dead on arrival.
- **Extension asset 401.** Asset route was behind auth middleware, but
`<script>` tags don't send Authorization headers. Moved to public group.
- **`runExtensionPostRender is not defined`.** Stale Service Worker cache
served old `ui-format.js` without the function. Added `typeof` guard.
- **Extension init order.** Extensions loaded after `loadChats()` — block
renderers not registered when messages first rendered. Moved extension
loading before chat loading.
- **K8s Ingress WebSocket routing.** Traefik `pathType: Exact` doesn't
reliably win over `Prefix` rules in the same Ingress resource. Changed
`/ws` and `/health` to `Prefix` for longest-prefix-wins routing.
- **Mermaid SVG oversized.** Added `max-height: 600px` on diagram
container with overflow scroll, removed mermaid.js hardcoded `height`
attribute from SVGs so CSS constraints apply.
### Changed
- Extension CSS removed from global `styles.css`. Each extension owns its
styles via `_injectStyles()` in `init()` with `destroy()` cleanup.
Idempotent injection guards prevent duplicates.
- Markdown fence language extraction lowercased at the point of extraction
in `ui-format.js`, making all block renderer pattern matches
case-insensitive without per-extension workarounds.
- `_unwrapMarkdownFence()` pre-processor strips outer ` ```markdown ``` `
wrappers when they contain nested fences. Handles think-block
placeholders and trailing explanation text. Only triggers when nested
fences are present — plain markdown code blocks still render normally.
## [0.10.5] — 2026-02-24
### Added