# Changelog ## [0.37.9] — 2026-03-21 ### Summary Preact NotesPane kit — Obsidian-grade composable note components replacing the old imperative `note-panel.js`, `note-graph.js`, and `notes.js` (~1,630 lines deleted). Every piece independently importable. `NotesPane` is the default assembly; surfaces import individual pieces for custom layouts. ### New - **NotesPane kit** (`src/js/sw/components/notes-pane/`) — 10 files: - `NotesPane` — default assembly: list + editor + reader + graph + quick switcher - `useNotes(opts)` — state machine (views, CRUD, pagination, search, folders, sort, selection, backlinks, daily notes, wikilink navigation, pinning) - `NoteList` — toolbar, search, folder/sort filters, tag cloud, pinned section, selection bar, load-more pagination - `NoteListItem` — single note row with title, time, preview, folder, tags, pin - `NoteEditor` — title/folder/tags/content with CM6 integration, word/char count, Ctrl+S save, Esc cancel, folder datalist autocomplete - `NoteReader` — rendered markdown with wikilink chips, transclusion embeds, sticky outline sidebar, daily note nav, backlinks panel, unlinked mentions - `NoteGraph` — canvas force-directed graph with focus mode (single-click = focus neighbors, double-click = open note), ghost node click → create, folder colors, pan/zoom/drag, orphan toggle - `renderNoteMarkdown` — marked+DOMPurify with wikilink chip rendering, transclusion blocks, heading extraction for outline - `SaveToNoteDialog` — create-new or append-to-existing, independently importable by ChatPane or any surface - `QuickSwitcher` — Cmd+K/Ctrl+K overlay: fuzzy title search, keyboard nav (↑↓ Enter Esc), recent notes (localStorage), create-on-enter - **`sw.notesPane(container, opts)`** — SDK mount helper, lazy-imports Preact NotesPane, returns imperative handle - **`sw-notes-pane.css`** — component styles with `sw-notes-pane` prefix (~500 lines) - **Obsidian-grade features:** - Wikilinks (`[[Title]]`, `[[Title|Display]]`) → clickable chips - Transclusions (`![[Title]]`) → inline embedded content (1-level) - Quick Switcher (Ctrl+K) with fuzzy search + create-on-enter - Outline sidebar (sticky, right side, scroll-to-heading) - Daily notes with auto-template + prev/next day navigation - Pinned notes (localStorage) at top of list - Tag cloud with clickable filter chips - Unlinked mentions (note titles in content not yet wikilinked) - Graph focus mode (click = focus neighbors, walk the graph) - Ghost node click → create missing note - Word/character count in editor - Keyboard shortcuts (Ctrl+S, Ctrl+N, Ctrl+D, Ctrl+K, Esc) ### Deleted - `src/js/notes.js` (155 lines) — backward-compat shim - `src/js/note-panel.js` (976 lines) — old imperative NotePanel - `src/js/note-graph.js` (501 lines) — old canvas graph - `src/css/panels.css` — all `.note-*`, `.notes-*`, `.wikilink-*`, `.transclusion-*`, `.save-note-*` rules stripped - `server/pages/templates/surfaces/chat.html` — `notes.js` script tag removed - `server/pages/templates/base.html` — `note-panel.js` + `note-graph.js` script tags removed ### Changed - `notes.html` — rewritten: Preact vendor globals + SDK `boot()` + `sw.notesPane()` mount (same pattern as settings/admin surfaces) - `base.html` — added `sw-notes-pane.css` stylesheet link - `switchboard-sdk.js` — `sw.notes()` redirects to `sw.notesPane()` with deprecation warning - `app.js` — removed `_initNotesListeners()` + `_registerNotesPanel()` calls - `ui-format.js` — `_openNoteFromTool()` made no-op (dies in v0.37.10) - `ui-core.js` — note tool-call link handler made no-op - `server/version.go` — version `0.37.8` → `0.37.9` - `VERSION` — `0.37.8` → `0.37.9` - `src/js/sw/sdk/index.js` — `sw.notesPane()` helper, `sw._sdk` → `0.37.9` ### Design Notes - **Kit of Parts** — same composability pattern as ChatPane. Any surface can import `NoteList` alone, or `NoteEditor` + `NoteReader`, or the full assembly. - **handleRef pattern** — same as ChatPane (no `forwardRef`/compat). - **Graph interaction model** — single click = focus (show 1-hop neighbors), double click = open note. Walk the graph by clicking through focused nodes. Ghost nodes (unresolved wikilinks) create on click via `navigateToLink`. - **Outline sidebar** — sticky right pane when note has >2 headings; falls back to stacked layout on mobile (<600px). ### Known Issues (minor, pre-tag) - Light mode: some notes-pane styles still reference dark theme defaults. Needs CSS variable audit for `--bg-surface`, `--input-bg` in light theme. --- ## [0.37.8] — 2026-03-21 ### Summary Preact ChatPane kit — composable chat components replacing the old imperative `chat-pane.js` standalone mode. Every piece (hooks, components, utilities) independently importable. `ChatPane` is the default assembly; surfaces import individual pieces for custom layouts. ### New - **ChatPane kit** (`src/js/sw/components/chat-pane/`) — 9 files: - `ChatPane` — default assembly: header + messages + input - `useChat(opts)` — channel state machine (messages, send/receive, model selection, channel CRUD) - `useStream()` — SSE ReadableStream parser with rAF-batched updates - `MessageList` — scrollable messages with auto-scroll-to-bottom - `MessageBubble` — single message with role styling + markdown - `MessageInput` — auto-resize textarea, Enter-to-send, handleRef - `ModelSelector` — model dropdown from `sw.api.models.enabled()` - `ChatHistory` — channel history select + new-chat button - `renderMarkdown` — `marked` + `DOMPurify` wrapper with fallback - **`sw.chatPane(container, opts)`** — SDK mount helper, lazy-imports Preact ChatPane, returns imperative handle - **`sw-chat-pane.css`** — component styles with `sw-` prefix convention - **Layer 1.5: Components** — `src/js/sw/components/` directory established for reusable compound components (between SDK and surfaces) ### Changed - `switchboard-sdk.js` — `sw.chat()` now prefers `window.sw.chatPane()` when new SDK is loaded, falls back to legacy `ChatPane.mount()` - `chat-pane.js` — stripped standalone mode (446 → 160 lines). Removed `mount()`, `_initStandalone()`, and all streaming/model/history logic. Retained DOM-binding `create()` for legacy chat surface (`app.js`) - `server/version.go` — version `0.37.6` → `0.37.8` - `VERSION` — `0.37.6` → `0.37.8` - `src/js/sw/sdk/index.js` — `sw.chatPane()` helper, `sw._sdk` → `0.37.8` - `server/pages/templates/base.html` — added `sw-chat-pane.css` link ### Design Notes - **Kit of Parts + Default Assembly** — every hook and component is independently importable. Future Chat surface (v0.37.10) will import `useChat`, `useStream`, `MessageList`, `MessageInput` individually with a completely different layout. - **handleRef pattern** — core Preact only exposes `{ h, render }`; `forwardRef` requires `preact/compat`. Components use a `handleRef` prop pattern instead: caller passes `{ current: null }`, component populates with imperative methods via `useEffect`. --- ## [0.37.7] — 2026-03-21 ### Summary Scorched earth: all legacy admin JS removed. Team Admin becomes a standalone surface. Settings bridge sections replaced with native Preact components. Chat surface stripped of all admin/settings script dependencies. 16 legacy JS files deleted (~5,400+ lines). ### New - **Team Admin surface** (`src/js/sw/surfaces/team-admin/`) — standalone at `/team-admin`, 10 native Preact sections: - `TeamAdminSurface` — root with team picker (multi-team admins), tab sidebar nav, lazy `import()` per section - `MembersSection` — list, add, change role, remove via `sw.api.teams.members/addMember/updateMember/removeMember` - `ProvidersSection` — CRUD provider configs, card layout, model sync - `PersonasSection` — CRUD personas with KB bindings - `KnowledgeSection` — read-only team KB list - `GroupsSection` — read-only team groups list - `WorkflowsSection` — full CRUD + publish, stage viewer - `TasksSection` — CRUD + run/kill, schedule display - `SettingsSection` — team name/description form - `UsageSection` — stat cards + usage-by-day table - `ActivitySection` — paginated audit log with filters - **7 native settings sections** (replace all bridge sections): - `WorkflowsSection` — user's visible workflows (read-only) - `TasksSection` — user tasks with run/stop actions - `GitKeysSection` — SSH credential management - `DataSection` — data export + account deletion (danger zone) - `KnowledgeSection` — personal KB CRUD with document upload - `MemorySection` — memory list with inline edit, status badges - `NotificationsSection` — toggle-based notification preferences - **SDK additions** (`api-domains.js`): - `teams.workflows/createWorkflow/getWorkflow/updateWorkflow/ deleteWorkflow/publishWorkflow` — team-scoped workflow CRUD - `teams.tasks/createTask/updateTask/deleteTask/runTask/killTask` — team-scoped task CRUD - `teams.knowledgeBases` — team KB list - `teams.update` — team settings update - `teams.updatePersona` — team persona update - `git.credentials.list/create/del` — git SSH credentials - `dataPortability.exportMe/deleteAccount` — data portability - **Go template** — `server/pages/templates/surfaces/team-admin.html` (Preact mount + vendor boot, no legacy modals) - **Surface registration** — `team-admin` surface registered in `pages.go`, `loaders.go`, `base.html` template dispatch, `nginx.conf` proxy rule ### Changed - `server/version.go` — `0.37.6` → `0.37.7` - `VERSION` — `0.37.6` → `0.37.7` - `settings/index.js` — removed `BridgeSection` import, emptied `bridgeSections` object, added 7 native section modules to `sectionModules`, removed bridge rendering ternary, added Knowledge Bases / Memory / Notifications / Data & Privacy to `NAV_ITEMS` - `chat.js` — menu handlers navigate to `/admin/users`, `/team-admin/members`, `/settings/general` instead of opening modals. Removed `UI.initAppearance()` call (was in deleted settings-handlers). - `app.js` — removed `_initSettingsListeners()` and `_initAdminListeners()` calls - `chat.html` — stripped 5 legacy admin script tags (`ui-settings.js`, `ui-admin.js`, `settings-handlers.js`, `admin-handlers.js`, `workflow-admin.js`) + `memory-ui.js`, `persona-kb.js`, `notification-prefs.js`. Removed team admin modal HTML (~110 lines). - `admin.html` — removed 7 legacy modal overlays (~130 lines of HTML): createUserModal, resetPwModal, approveUserModal, createTeamModal, createGroupModal, providerFormModal, personaFormModal - `settings.html` — removed 9 bridge loader script tags, updated docstring to reflect full Preact (no bridges) - `base.html` — added `team-admin` surface template + scripts dispatch - `nginx.conf` — added `/team-admin` proxy rule to Go backend ### Deleted - `ui-admin.js` (1,690 lines) — old admin panel, team admin modal, ADMIN_LOADERS - `ui-settings.js` (867 lines) — team management functions - `admin-handlers.js` (~900 lines) — admin event listeners - `settings-handlers.js` (908 lines) — settings save/load, bridge loaders - `admin-scaffold.js` (367 lines) — old admin DOM scaffolding - `admin-packages.js` — old package management UI - `broadcast-admin.js` — old broadcast admin UI - `task-admin.js` — old task admin UI - `task-settings.js` — old task settings UI - `workflow-admin.js` — old workflow admin builder - `workflow-team-admin.js` — old team workflow builder - `memory-ui.js` — old memory management UI - `notification-prefs.js` — old notification preferences UI - `persona-kb.js` — old persona KB binding UI - `data-portability.js` — old data export/import UI - `git-credentials-ui.js` — old git credentials UI - `bridge-section.js` — settings bridge wrapper (no longer needed) ### Retained (chat surface still uses) - `knowledge-ui.js` — `KnowledgeUI.onChatChanged()` called by chat.js for channel KB popup. Dies in v0.37.10 (chat surface rebuild). - `channel-models.js` — `ChannelModels.*` used by chat.js for @mention autocomplete. Dies in v0.37.10. - `notifications.js` — `Notifications.init()` called by app.js for notification badge/list. Dies in v0.37.10. ## [0.37.5] — 2026-03-21 ### Summary Login + Settings surface rebuild (Phase 3 begins). First surfaces converted from server-rendered Go templates + imperative DOM JS to Preact component trees consuming the v0.37.3 SDK (`sw.api.*`, `sw.auth.*`, `sw.theme.*`). ### New - **Login surface** (`src/js/sw/surfaces/login/`) — 5 Preact components: - `LoginSurface` — root, auth mode switching (builtin/oidc/mtls), OIDC callback hash handler - `Hero` — left panel with branding, feature pills, version display - `LoginForm` — username/password, calls `sw.api.auth.login()` - `RegisterForm` — registration flow with validation, pending approval - `SSOPanel` — OIDC redirect + mTLS continue button - **Settings surface** (`src/js/sw/surfaces/settings/`) — 12 files: - `SettingsSurface` — left nav + section routing via `__SECTION__` - `GeneralSection` — model select, system prompt, max tokens, temperature slider, thinking toggle. Uses `sw.api.models.enabled()` + `sw.api.profile.settings()` - `AppearanceSection` — theme toggle (light/dark/system) via `sw.theme.set()`, UI scale + message font size sliders - `ProfileSection` — avatar (upload/remove), display name, email, password change. Uses `sw.api.profile.*` - `ModelsSection` — searchable model table with visibility toggles. Uses `sw.api.models.enabled()` + `sw.api.models.setPref()` - `TeamsSection` — read-only team membership list via `sw.api.teams.mine()` - `BridgeSection` — thin Preact wrapper for deferred sections that call old JS loaders (Tasks, Git Keys, Workflows, Data & Privacy) - **`sw.toast()`** — imperative toast API on the SDK. Dynamic import from primitives. `sw.emit('toast', { message, variant })` event listener for surface-agnostic toast firing. - **Nav gating** — Personas tab hidden when `allow_user_personas` policy is false. BYOK section (Providers, Roles, Usage) hidden when `allow_user_byok` is false. Fetched from `sw.api.admin.settings.public()`. - **ToastContainer + DialogStack** mounted in settings surface root (not via shell ``, since surfaces render standalone). - **`sw-login.css`** — login-specific styles extracted from inline `