This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/docs/ROADMAP.md
2026-03-01 14:44:55 +00:00

50 KiB
Raw Blame History

Roadmap — Chat Switchboard

See also:

  • ARCHITECTURE.md — Core services design, store layer, scope model
  • EXTENSIONS.md — Extension system spec (Browser/Starlark/Sidecar tiers, manifests, browser tool bridge, surfaces/modes, model roles)
  • CHANGELOG.md — Detailed release notes for all completed versions

Versioning (pre-1.0): 0.<major>.<minor> — hotfixes use quad: 0.x.y.z No compatibility guarantees before 1.0.


Dependency Graph

Features have real dependencies. This ordering respects them.

v0.9.x  Stability + Quick UX Wins              ✅
          │
v0.9.3  Content Visibility & Block Controls     ✅
          │
v0.9.4  API Key Encryption + Vault              ✅
          │
v0.10.0 Model Roles (utility + embedding)       ✅
        + Usage Tracking
          │
v0.10.2 Summarize & Continue                    ✅
          │
v0.10.3 Frontend Refactor                       ✅
          │
v0.10.4 Model Type Pipeline + Role Fixes        ✅
          │
v0.10.5 UI Primitives + Extension Surfaces      ✅
          │
v0.11.0 Extension Foundation (browser tier)     ✅
          │
  ┌───────┴──────────────┐
  │                      │
v0.12.0 File Handling  v0.13.0 Admin Panel
  + Vision ✅            Refactor (fullscreen) ✅
  │                      │
  │                    v0.13.1 Web Search
  │                      + url_fetch ✅
  │                      │
  └───────┬──────────────┘
          │
v0.14.0 Knowledge Bases ✅ (embedding role + file storage + pgvector)
          │
v0.15.0 Compaction ✅ (utility role + background job)
          │
v0.15.1 Context Recall Tools ✅ (attachment_recall, conversation_search)
          │
  ┌───────┴──────────────┐
  │                      │
v0.16.0 User Groups    v0.17.0 Persona-KB Binding
  + Resource Grants ✅   + Enterprise KB Mode
  │                      + QOL / UX Wins
  └───────┬──────────────┘
          │
  ┌───────┴──────────────┐
  │                      │
v0.17.1 SQLite Backend ✅ v0.17.2 CodeMirror 6 ✅
v0.17.3 Notes Graph + Wikilinks ✅
  (dual DB)              (editor bundle, chat
  │                       input, ext editor)
  └───────┬──────────────┘
          │
v0.18.0 Memory ✅ (user + persona scopes, review pipeline)
          │
v0.18.1 Side Panel Architecture ✅ (single-slot, ctx.ui primitives, mermaid refactor)
          │
v0.19.0 Projects / Workspaces ✅ (project groups, KB resolution, drag-drop sidebar)
          │
v0.19.1 Active Project + System Prompt + Detail Panel ✅
          │
v0.19.2 Project Persona Default + Archive + Reorder ✅
          │
v0.20.0 Notifications + @mention Routing + Multi-model   ✅
          │
v0.21.0 Workspace Storage Primitive                      ✅
          │
  ┌───────┴──────────────┐
  │                      │
v0.21.1 Workspace      v0.21.3 Surface Infra
  Tools + Bindings       + REPL (parallel)
  │                      │
v0.21.2 Workspace      v0.21.5 Editor Surface
  Indexing + Search      (Development Mode)
  │                      │
v0.21.4 Git            v0.21.6 Article Surface
  Integration            + Document Output
  └───────┬──────────────┘
          │
v0.22.0 Smart Routing + Provider Extensions
          │
v0.23.0 Multi-Participant Channels + Presence
          │
v0.24.0 Auth Strategy (mTLS/OIDC) + Full RBAC + Group permissions
          │
  ┌───────┴──────────────┐
  │                      │
v0.25.0 Workflow       v0.26.0 Tasks /
  Engine                 Autonomous Agents
  (team-owned,           (service channels,
   staged processes,      scheduler, unattended
   human + AI collab)     execution)

Completed Releases

Full details for all completed versions are in CHANGELOG.md.

v0.9.0 — Schema Consolidation + BYOK

21 migrations → single schema, store layer abstraction, persona-as-trust-boundary, BYOK with auto-fetch, composite model IDs, journey integration tests.

v0.9.1 — Capability Architecture + Docs

Removed static known model table. Resolution chain: catalog → heuristic only. Frontend relies solely on backend for capabilities. Docs rewrite.

v0.9.2 — Quick UX Wins + Hardening

Collapsible code blocks, HTML preview, token counter, context warning, proxy interception detection, environment injection, team admin audit scoping.

v0.9.3 — Content Visibility & Block Controls

Button-driven code collapse, always-rendered thinking blocks, tool call persistence in history, Notes panel → unified side panel, streaming refactor (streamWithToolLoop), regenerate fix.

v0.9.4 — API Key Encryption + Vault

Two-tier AES-256-GCM: env-var key for global/team, per-user UEK (Argon2id) for personal BYOK. server/crypto/ package. Migration 003. Startup backfill. DOMPurify strict allowlist (XSS fix).

v0.10.0 — Model Roles + Usage Tracking + Vault Debt

Named role slots (utility, embedding) with fallback. Provider.Embed() interface. usage_log + model_pricing tables. Streaming token capture. Vault debt: UEK re-wrap on password change, destruction on admin reset.

v0.10.1 — Polish + UX

Admin system prompt injection, Personas tab, Team Management modal extraction, preview pane enhancements, code download, personal usage scoped to BYOK.

v0.10.2 — Summarize & Continue + Role Cleanup

User-triggered conversation compaction via utility role. Summary as tree node with boundary metadata. BYOK role overrides (personal → team → global). Utility rate limiting. Generation role removed.

v0.10.3 — Frontend Refactor

2 monolith files → 13 domain-scoped files (~544 lines avg). Zero features, no function renames. Vanilla JS, no build step. See REFACTOR-0.10.3.md.

v0.10.4 — Model Type Pipeline + Role Fixes

model_type (chat/embedding/image) captured end-to-end from provider API through catalog to frontend. Role dropdowns filter by type.

v0.10.5 — UI Primitives + Extension Surfaces

Shared Providers/Roles registries, 6 consolidated render primitives, showConfirm() replacing native dialogs, .popup-menu CSS primitive. Removed ~400 lines of duplication.

v0.11.0 — Extension Foundation (Browser Tier)

Full extension lifecycle: manifest, loader, scoped ctx.* API, browser tool bridge via WebSocket. Custom renderer pipeline. 2 server tools (calculator, datetime), 6 built-in browser extensions (Mermaid, KaTeX, CSV, Diff, JS Sandbox, Regex). See EXTENSIONS.md.

v0.12.0 — File Handling + Vision

S3/PVC storage backend, image/file upload (📎, drag-drop, paste), multimodal message assembly, text extraction pipeline (PDF/DOCX/XLSX/PPTX/ODT/RTF), vault CLI (rekey/status), per-chat model persistence.

v0.13.0 — Admin Panel Refactor

12-tab modal → fullscreen admin panel. 4 categories (People, AI, System, Monitoring) × section sidebar. URL-based routing, responsive, banner-aware. CSS design token cleanup.

v0.13.1 — Web Search + URL Fetch

web_search + url_fetch tools. Search provider abstraction (DuckDuckGo, SearXNG). Tool categories with per-tool toggle UI in chat bar.

v0.14.0 — Knowledge Bases

RAG: upload → chunk → embed (pgvector) → kb_search tool. Channel KB toggle. Team/personal KB scopes. Notes semantic search. Admin panel KB management. See DESIGN-0.14.0.md.

v0.15.0 — Compaction

Background scanner with configurable thresholds. Automatic summarization via utility role. Per-channel opt-in/out. Context budget guard rail (80% ceiling).

v0.15.1 — Context Recall Tools

attachment_recall (list + read, channel-scoped), conversation_search (full-text via plainto_tsquery). Token estimator attachment awareness.

v0.16.0 — User Groups + Resource Grants

Groups (global/team-scoped ACLs) decoupled from team membership. Three-way resource grants (team_only/global/groups) for Personas and KBs. Grant picker UI. Schema consolidation: 9 migrations → single 001_v016_schema.sql.


v0.17.0 — Persona-KB Binding + Enterprise KB Mode + QOL

Personas become gateways to knowledge. In enterprise deployments, users don't interact with KBs directly — they talk to Personas that have KBs attached. Plus quality-of-life improvements: chat rename, token display, state persistence, utility model auto-naming.

Depends on: knowledge bases (v0.14.0), user groups (v0.16.0).

Persona-KB Binding

  • persona_knowledge_bases table: persona_id, kb_id, auto_search (bool — always search vs tool-only)
  • When a channel uses a Persona with bound KBs, kb_search is auto-scoped to those KBs
  • No user toggle needed — Persona carries its own KB context
  • Channel KB toggle becomes "additional KBs" on top of Persona-provided ones
  • Persona system prompt auto-includes KB listing hint (reuses BuildKBHint pattern)
  • Admin/team admin UI: KB picker on Persona create/edit form

Enterprise KB Mode

  • discoverable flag on knowledge_bases: true (default — appears in user's KB popup) or false (hidden, only accessible through Persona binding)
  • Hidden KBs don't appear in GET /api/v1/knowledge-bases-discoverable for non-admins
  • Hidden KBs still searchable by kb_search tool when accessed through a Persona
  • Admin panel: toggle discoverability per KB
  • Platform policy: kb_direct_access — when false, disables channel KB popup entirely (strict enterprise mode)

Access Control Integration

  • Persona grants (v0.16.0 groups) control who can use a Persona
  • KB grants control who can manage a KB (upload/delete docs)
  • Persona-KB binding grants implicit search access through the Persona
  • Users who can use a Persona can search its KBs, even if they can't see those KBs directly

Team Admin Workflow

  • Team admin creates KB → uploads documents → marks non-discoverable
  • Team admin creates Persona → binds KBs → sets access to Team Only or specific Groups
  • Team members see the Persona in their preset list, use it, get KB-powered answers
  • Team members never see or manage the underlying KBs

Technical Debt (carried forward)

  • Security: KB create handler authorization — team/global scope verified
  • Test hygiene: stripped DIAG diagnostics from TestGroupBasedPersonaAccess
  • Architecture: KnowledgeBaseStore.UpdateDocumentStorageKey() — moved to store layer
  • UX: Embedding dropdown fix — tolerant type filter, manual model ID fallback, auto-switch on empty (already implemented in ui-primitives.js)
  • Minor: Paste-to-file character threshold — synced from backend PublicSettings (storage.paste_to_file_chars), admin-configurable, default 2000

Role Fallback Alerts (#69)

  • Audit log entry on fallback fire: action = "role.fallback" with primary/fallback model IDs and error string
  • role.fallback WebSocket event via EventBus (PublishAsync, zero latency impact on completion path)
  • In-memory cooldown on Resolver (per-role, 5-minute TTL) to deduplicate repeated fallback alerts
  • Admin UI: persistent alert banner on role.fallback event (persists until dismissed)
  • Wire *events.Bus into roles.NewResolver via .WithBus() builder

QOL / UX Wins

  • Chat rename: inline edit on sidebar item — dblclick title → input → blur/Enter saves via API.updateChannel(id, { title })
  • Chat token count: display Tokens.estimateConversation() in model bar, update on selectChat and after each message
  • State restore on refresh: persist App.currentChatId to sessionStorage on select, restore on load
  • Utility model auto-naming: after first assistant response, background utility role request → POST /channels/:id/generate-title → re-render sidebar. Fallback to truncation when no utility model configured. Debounced via _autoNamePending set
  • SW extension cache fix: exclude /extensions/ from service worker fetch handler
  • Mermaid renderer: promoted enhanced version (v2.0 — pan/zoom, SVG/PNG export, source copy) to extensions/builtin/mermaid-renderer/

v0.17.1 — SQLite Backend

Dual-database support. Every subsequent schema change is developed against both Postgres and SQLite from day one — no retrofit. SQLite enables single-binary deployment for dev, demo, edge, and single-user.

Depends on: v0.17.0 DB debt cleanup (store layer is sole DB interface).

Store Layer

  • 19 SQLite store implementations covering all domain interfaces
  • DB_DRIVER env var: postgres (default) | sqlite
  • Separate migration files per driver (migrations/sqlite/)
  • WAL mode + single-writer connection pooling for SQLite concurrency
  • CI matrix: full handler integration tests against both Postgres and SQLite

Vector Search

  • App-level cosine similarity in Go (pure Go, no CGO/sqlite-vec required)
  • Embeddings stored as JSON text in kb_chunks.embedding column
  • Full feature parity with pgvector: SimilaritySearch, InsertChunks
  • Graceful: adequate performance for SQLite-scale deployments (single-user, not millions of chunks)

Schema Compatibility

  • UUID generation: application-side store.NewID() (Go uuid.New())
  • JSONB → JSON text columns with ToJSON()/ScanJSON() helpers
  • UUID[] arrays → JSON arrays with ToJSONArray()/ScanJSONArray()
  • TIMESTAMPTZ → SQLite TEXT with datetime('now')
  • ON CONFLICT excluded.* pattern (works in both dialects)
  • INSERT RETURNING id → separate query pattern for SQLite

Test Infrastructure

  • dialectSQL() converts $N? and strips ::jsonb at runtime
  • database.PH(n) returns dialect-appropriate placeholder
  • database.TruncateAll() dialect-aware (DELETE + PRAGMA vs TRUNCATE CASCADE)
  • Generic provider config: PROVIDER/PROVIDER_KEY/PROVIDER_URL (replaces VENICE_API_KEY)
  • Model selection prefers non-reasoning models in live tests

What SQLite mode skips (feature-gated, not broken):

  • LISTEN/NOTIFY — WebSocket event fan-out uses in-process EventBus (already works)
  • Full-text search tsvector — conversation_search uses LIKE fallback

v0.17.2 — CodeMirror 6 Integration

Rich editor infrastructure for the frontend. CM6 is ESM-native; the build step runs in Docker (esbuild → single IIFE bundle). No change to dev experience for non-editor code — the rest of src/js/ stays vanilla.

Depends on: nothing (frontend-only). Prerequisite for: extension surfaces (v0.21.5 editor surface). See DESIGN-CM6.md for full spec.

Build Pipeline

  • src/editor/ directory: package.json, build.mjs, index.mjs, language/theme modules
  • scripts/build-editor.sh: shared build script for both Dockerfiles and local dev
  • New Docker stage (cm6-build): npm ci + node build.mjsvendor/codemirror/
  • Both Dockerfile.frontend and Dockerfile (unified) use the shared build script
  • Bundle output: codemirror.bundle.js (~295KB min, ~90KB gzip)
  • Graceful degradation: all integration points check window.CM — falls back to <textarea> if bundle unavailable

Languages (bundled)

  • Markdown, JavaScript, JSON, SQL, HTML, CSS, YAML, Go, Python, Rust
  • Additional modes: one-line import + rebuild

Phase 1: Extension Editor (admin panel)

  • CM.codeEditor() factory: line numbers, bracket matching, auto-indent, search/replace
  • Replace manifest <textarea> → CM6 JSON mode
  • Replace script <textarea> → CM6 JavaScript mode
  • Remove manual Tab-key handler in admin-handlers.js (CM6 handles it)
  • Update saveAdminExtension() to use .getValue()

Phase 2: Chat Input (markdown mode)

  • CM.chatInput() factory: markdown highlighting, minimal chrome (no line numbers, no gutter)
  • Enter=send, Shift+Enter=newline keybindings
  • Auto-growing height, placeholder text
  • Wire onChangeupdateInputTokens()
  • Update chat.js, attachments.js, tokens.js to use CM API
  • WYSIWYG fenced code block decorations (visual container matching claude.ai UX)
  • Inline code shortcut (Ctrl/Cmd+E)

Phase 3: Polish

  • Theme integration: CSS variable overrides (--bg, --border, --accent, etc.)
  • Dark/light/system mode toggle in appearance settings
  • Vim/Emacs keybinding preference in appearance settings (@replit/codemirror-vim, @replit/codemirror-emacs)
  • Vim/Emacs applies to code editor + extension editor only (never chat input)
  • SW cache: exclude vendor/codemirror/ with version bust
  • Update debug.js snapshot to include CM6 version
  • Documentation in ARCHITECTURE.md

CI/CD

  • Path-based change detection gating (FE-only → skip BE tests, docs-only → skip all)

Knowledge graph and bi-directional linking for the notes system. Transforms notes from flat documents into an interconnected knowledge base with Obsidian-style [[wikilinks]], backlinks, graph visualization, and transclusion.

Depends on: CodeMirror 6 (v0.17.2), Notes CRUD (v0.13.x). See DESIGN-0.17.3.md for full spec.

Backend: Note Links

  • note_links table (Postgres + SQLite migrations)
  • NoteLinkStore interface + both implementations
  • ExtractWikilinks() regex parser + tests
  • Link extraction on note create/update
  • Dangling link resolution on note create
  • notes.source_message_id column for chat-to-note provenance

API Endpoints

  • GET /notes/:id/backlinks — notes linking to this note
  • GET /notes/search-titles?q= — lightweight fuzzy search for autocomplete
  • GET /notes/graph — full graph topology (nodes + edges + unresolved)

CM6 Note Editor

  • note-editor.mjs factory: markdown live preview (heading sizes, blockquotes, code blocks)
  • wikilink.mjs CM6 extension: parse, decorate as clickable chips, autocomplete on [[
  • Textarea → CM6 swap in notes.js with graceful fallback
  • noteEditorTheme in theme.mjs

Graph Visualization

  • Canvas-based force-directed graph (~200 lines, no d3 dependency)
  • O(n²) Coulomb repulsion + Hooke spring + center gravity
  • Pan, zoom (0.154.0x), drag nodes, hover highlight, click to open
  • Node sizing by link_count, folder-based coloring
  • Ghost nodes for unresolved [[links]] with toggle
  • Energy-based pause (stop rAF below KE threshold)
  • ResizeObserver for responsive canvas

Note-from-Selection + Daily Notes

  • "Note" button in message action bar
  • Selection-aware capture (window.getSelection() within message)
  • Provenance tracking (source_channel_id + source_message_id)
  • "Today" button → find-or-create daily note in /daily/

Read Mode

  • [[link]] rendered as clickable wikilink chips
  • ![[embed]] transclusion with async content fetch, recursion guard
  • Backlinks panel (collapsible, with count badge)

v0.18.0 — Memory (User + Persona Scopes)

Long-term memory across conversations, with scope-aware isolation. Unlike KB (static documents) or compaction (within-conversation), this captures facts and preferences that persist across channels.

Key differentiator: Persona-scoped memory. Each Persona can build its own memory independently of user memory, preventing cross-context contamination and enabling specialized knowledge accumulation.

Depends on: compaction (v0.15.0), knowledge bases (v0.14.0), persona-KB binding (v0.17.0), SQLite backend (v0.17.1).

See DESIGN-0.18.0.md for full spec.

Memory Scopes

  • user — personal facts/preferences, persists across all conversations (current industry standard)
  • persona — shared across all users of that Persona, accumulated from conversations (differentiator)
  • persona+user — per-user within a Persona context (e.g. tutoring progress per student)
  • Configurable per Persona: which scopes are active, whether user memory is passed through

Data Model

  • memories table: id, scope (user, persona, persona_user), owner_id (user_id or persona_id), user_id (nullable — for persona+user scope), key, value, source_channel_id, confidence (float), status (active, pending_review, archived), created_at, updated_at
  • Index on (scope, owner_id, user_id) for fast lookup
  • Embedding column (vector(3072)) for semantic memory search

Tools

  • memory_save tool: LLM explicitly stores a fact
    • Scope-aware: saves to the active memory scope for the current Persona context
    • Structured: key (short label) + value (detail) + confidence
  • memory_recall tool: LLM queries stored facts relevant to current context
    • Merges results from applicable scopes (user + persona + persona+user)
    • Semantic search via embeddings + keyword fallback

Automatic Extraction

  • Background job: post-conversation analysis identifies memorable facts (opt-in)
  • Configurable extraction prompt per Persona (e.g. "extract FAQ-worthy Q&A pairs")
  • Extracted memories start in pending_review status

Review Pipeline

  • Admin/team admin review queue: pending memories with approve/reject/edit
  • Persona memory review: team admins see what Personas are "learning"
  • User memory review: users see their own memories in Settings

Memory Injection

  • At completion time: inject relevant memories into system prompt
  • Context budget aware: limit injected memory tokens
  • Scope priority: persona+user > persona > user (most specific wins on conflicts)

Use Cases

  • Helpdesk Persona: builds FAQ from repeated questions, human-reviewable
  • Roleplay Persona: isolated memory prevents tone/context bleeding from user's other conversations
  • Tutoring Persona: tracks per-student progress, common misconceptions
  • Sales Persona: accumulates objection responses from real conversations
  • Onboarding Persona: learns what new hires commonly struggle with

User Controls

  • Settings → Memory: view, edit, delete personal memories
  • Per-Persona memory toggle: "Allow this persona to remember things about me"
  • Admin: enable/disable, retention policies, per-team scoping
  • Privacy: user memories never cross team boundaries; persona memories respect group access

v0.18.1 — Side Panel Architecture

Refactored the side panel from a shared-tab layout to independent single-slot panels. Any action fills the slot, replacing whatever was there — no tabs, no association between panel types. Extension UI primitives give browser extensions safe access to host app features.

Depends on: Notes graph + wikilinks (v0.17.3). Prerequisite for: live collaboration (v0.23.0) where multiple panels need simultaneous visibility.

Panel System

  • Panel registry: named panels with independent open/close state
  • Single-slot model: action-driven, each open replaces the previous
  • Dual-view mode: two panels side-by-side (configurable split ratio via drag divider)
  • Panel-persistent state: each panel remembers scroll position, open note, etc.
  • Header label shows active panel name (replaces tab bar)
  • Keyboard shortcut: Ctrl/Cmd+\ cycles panels, Ctrl/Cmd+Shift+\ toggles dual

Preview Panel

  • Dedicated preview panel (independent of Notes)
  • HTML/document preview with iframe sandbox
  • Code output preview (extension-rendered blocks via pop-out)
  • Live-updating during streaming responses (500ms debounce)

Extension UI Primitives

  • ctx.ui.toast() — toast notifications
  • ctx.ui.openPreview() — load HTML into side panel preview
  • ctx.ui.isDark() — theme detection
  • ctx.ui.isMobile() — viewport width check
  • ctx.ui.isPanelOpen() — side panel visibility
  • ctx.ui.confirm() — modal confirm dialog
  • Mermaid extension refactored to use primitives exclusively (zero direct globals)
  • Context-aware expand: single button, fullscreen or side panel pop-out

Mobile

  • Swipe navigation between panels
  • Tap-to-close overlay
  • Graceful collapse to single-panel on narrow viewports
  • Enlarged touch targets, fullscreen close button (40px desktop, 48px mobile)

v0.19.0 — Projects / Workspaces

Organizational containers that group related conversations, KBs, and notes into a single workspace with shared access controls.

Depends on: user groups (v0.16.0), knowledge bases (v0.14.0).

Data Model

  • projects table: id, name, description, color, icon, scope (personal/team/global), owner_id, team_id, is_archived, settings (JSONB)
  • project_channels junction: ordered membership with UNIQUE channel_id, denormalized FK on channels.project_id
  • project_knowledge_bases junction: with auto_search flag
  • project_notes junction
  • resource_grants CHECK extended to include 'project'

Features

  • Channels can belong to a project (optional project_id FK)
  • KBs can belong to a project → auto-linked to all channels in the project (BuildKBHint + kbsearch)
  • Notes can belong to a project → auto-associated when created from project channel
  • KB resolution chain: Persona → Project → Channel → Personal
  • Project sidebar section: collapsible groups above time-based Recent section

UI

  • Sidebar: projects as collapsible groups with color dots, counts, options menu
  • Right-click context menu: move chat to project / remove / create-and-assign
  • Drag-and-drop channels between project groups and Recent
  • New Project button in split dropdown
  • Channel list project_id filter (?project_id=uuid or ?project_id=none)
  • Collapse state persisted in localStorage

Deferred to later versions:

  • Project creation dialog (name, description, default Persona, default KBs) — using prompt() for now
  • Project detail panel (KB + note management within a project) → v0.19.1
  • Project-level Persona default → v0.19.2
  • Folders within projects
  • Project templates
  • Admin-level team/global project management
  • Project-specific files (full project-level upload — deferred for proper architecture)
  • Notifications (moved to v0.20.0)

v0.19.1 — Active Project + Project System Prompt + Detail Panel

Quality-of-life improvements making projects usable for daily workflow. No migrations.

Depends on: v0.19.0 Projects/Workspaces.

Active Project

  • Pin a project as active — new chats auto-assign via addChannelToProject after channel creation
  • App.activeProjectId persisted in localStorage('cs-active-project')
  • Visual indicator: .project-group.active accent border + 📌 icon
  • Toggle from project ⋯ menu ("Pin as active" / "Unpin project")
  • Cleared on project delete

Project System Prompt

  • Per-project instructions in projects.settings JSONB (system_prompt key)
  • Injected in loadConversation between persona/channel prompt and KB hint
  • Merge semantics on update: reads existing JSONB, overlays patch keys, writes back
  • Both Postgres and SQLite stores updated

Project Detail Panel

  • Registered with PanelRegistry (same pattern as Notes, Preview)
  • System prompt textarea with Save button
  • KB management: list with names (LEFT JOIN), [+ Add] picker dropdown, [✕] remove
  • Notes list with titles (LEFT JOIN), [✕] unbind
  • Accessible from project ⋯ menu → "Project settings"

Bug Fixes

  • renderChatList early return prevented project groups from rendering when zero chats
  • Recent section drop target: "Drop chats here to unassign" hint with min-height: 40px

v0.19.2 — Project Persona Default + Archive + Channel Reorder

Completes the project management feature set. No migrations.

Depends on: v0.19.1.

Project Persona Default

  • Bind a persona to a project via detail panel dropdown
  • Stored in projects.settings.persona_id
  • Resolution chain: explicit req.PresetID → project persona → none
  • Inherits model, provider config, temperature, max tokens, system prompt as defaults

Project Archive Toggle

  • Checkbox in project detail panel
  • Archived projects hidden from sidebar by default
  • "▸ Show archived (N)" toggle button below project list
  • Chats in hidden-archived projects spill into Recent section (never vanish)
  • Dimmed + italic visual treatment for archived groups

Channel Reorder

  • loadProjectChannelPositions() fetches server-persisted positions on startup
  • _getReorderedProjectChats() sorts project chats by stored position
  • Right-click context menu: ↑ Move up / ↓ Move down (optimistic swap + API call)
  • Order maintained across add/remove/move operations

v0.20.0 — Notifications + @mention Routing + Multi-model

Notification infrastructure that makes collaboration real-time, plus multi-model routing for channels. Three-phase delivery: notifications core (in-app), @mention parsing + fan-out completions, email transport

  • per-user notification preferences.

(Notifications shifted from v0.19.0; @mention routing shifted from v0.17.0)

Depends on: v0.19.2 (Projects complete), EventBus + WebSocket hub (v0.9.x), channel_models table (v0.16.0 schema). See DESIGN-0.20.0.md for full spec.

Phase 1 — Notifications Core (in-app)

  • notifications table: id, user_id, type, title, body, resource_type, resource_id, is_read, created_at (Postgres + SQLite migrations)
  • NotificationStore interface + both implementations: Create, ListByUser (paginated), MarkRead, MarkAllRead, Delete, UnreadCount
  • notifications.Service with Notify() / NotifyMany() — centralized creation + WebSocket dispatch
  • EventBus routes: notification.new, notification.read (badge sync across tabs)
  • API endpoints: list, unread-count, mark-read, mark-all-read, delete (5 endpoints, all user-scoped)
  • Initial sources: role.fallback (EventBus subscription), kb.ready/kb.error, grant.changed
  • Frontend: bell icon + unread badge (capped 9+), notification dropdown (latest 10, click-to-navigate), full panel via PanelRegistry
  • WebSocket handler: real-time push + toast for high-priority types
  • Background cleanup goroutine (configurable retention, default 90 days)

Phase 2 — @mention Parsing + Multi-model Routing

  • mentions.Parse(): extract @mentions, resolve against channel model roster (case-insensitive, longest-match-first, trailing punctuation tolerant)
  • Parser tests: no mentions, unresolved, multiple, overlapping names, punctuation edge cases
  • Channel model CRUD handlers (4 endpoints: list, add, remove, update)
  • Completion handler: mention extraction → target resolution → sequential fan-out → N assistant messages
  • SSE streaming: model attribution in delta events (model_display field)
  • Frontend: model pills in chat header with add/remove UI
  • Frontend: @mention autocomplete via CM6 mentionCompletion extension (roster-backed)
  • Frontend: model attribution labels on multi-model assistant messages
  • Backward compat: channels with no extra channel_models rows work exactly as before

Phase 3 — Email Transport + Notification Preferences

  • notification_preferences table (Postgres + SQLite): per-user, per-type in_app/email toggles
  • Preference resolution chain: specific type → user wildcard * → system default (in_app=true, email=false)
  • EmailTransport: SMTP with implicit TLS (port 465) and STARTTLS (port 587), multipart MIME (HTML + plaintext)
  • Email templates: branded HTML + plaintext, domain-prefixed subjects, Go html/template
  • Preference CRUD endpoints (3: list, set with partial patch, delete)
  • Admin SMTP configuration: enable toggle, host/port/user/password/from/TLS fields, test email button
  • User notification preferences UI (Settings → Notifications tab, per-type checkboxes)
  • Notification service: preference check before dispatch, async email delivery (goroutine, 30s timeout)
  • Tests: preference resolution chain (7 tests), email templates (4 tests)
  • Deferred: digest mode (batched email), SMTP password vault encryption

Hotfix (carried forward from v0.19.2 investigation)

  • user_model_settings NULL scan fix: COALESCE on hidden/sort_order in SELECT + INSERT for both dialects
  • Gin release mode: auto-set gin.ReleaseMode when ENVIRONMENT=production, suppress health check log spam

v0.21.x — Workspace Platform + Extension Surfaces

Seven-release series decomposing workspace storage, tools, indexing, git, surface infrastructure, and editor/article modes. Full specification in DESIGN-0.21.0.md.

Depends on: file storage (v0.12.0), extension foundation (v0.11.0), CodeMirror 6 (v0.17.2), knowledge base embedding pipeline (v0.14.0).

v0.21.0 — Workspace Storage Primitive

Pure backend foundation. Workspaces as a polymorphic platform primitive owned by users, projects, channels, or teams. Dual-layer storage: PVC filesystem (source of truth) + DB metadata index (queryable cache).

  • workspaces table: polymorphic owner (user/project/channel/team), root_path, max_bytes quota, status
  • workspace_files table: metadata index (path, MIME type, size, sha256, is_directory)
  • WorkspaceStore interface: CRUD, file index (upsert/delete/list/prefix), ownership lookup, stats
  • Postgres + SQLite store implementations with upsert-on-conflict for file index
  • workspace.FS package: read, write (atomic via temp+rename), delete, mkdir, stat, list, reconcile (FS→DB sync)
  • workspace.Archive: zip/tar.gz extract + create with archive bomb protection (10K file limit, 100MB single file, quota enforcement), common-prefix stripping
  • Content type detection: extension-based (40+ source code types) with http.DetectContentType fallback
  • SHA256 computed during write via tee reader (enables content-addressed skip in v0.21.2)
  • Path traversal guards: cleanPath + absPath validation, symlink rejection
  • 15 API endpoints: workspace CRUD, file CRUD, archive upload/download, reconcile, stats
  • Owner-based authorization: user=self, channel=owner, project=member, team=member
  • Unit tests: path cleaning, traversal detection, MIME detection, unsafe path filtering, write/read round-trip, delete, mkdir

v0.21.1 — Workspace Tools + Channel/Project Binding

Make workspaces useful in chat mode via tool calls.

  • Workspace tools (category: workspace): workspace_ls, workspace_read (50KB soft limit), workspace_write (auto-mkdir), workspace_rm (recursive guard), workspace_mv, workspace_patch (find/replace)
  • channels.workspace_id FK, projects.workspace_id FK
  • Workspace resolution: channel workspace → project workspace (override pattern)
  • Archive upload flow: detect archive MIME + workspace binding → extract to workspace
  • Frontend: channel settings workspace toggle, project Files tab with tree view, chat bar workspace indicator

Embed text files for semantic search. Reuses knowledge.SplitText + knowledge.Embedder.

  • workspace_chunks table: workspace_id, file_id, chunk_index, content, embedding, metadata
  • workspace_files additions: index_status, chunk_count
  • Indexable types: text MIME types + 30+ code extensions
  • Code-aware chunking: larger chunks (1500 chars), function/class boundary separators
  • Content-addressed skip: sha256 check before re-chunking/re-embedding
  • Background indexing: async goroutine with shared semaphore
  • workspace_search tool: semantic search with optional glob filtering

v0.21.3 — Surface Infrastructure + REPL

Pure UI architecture. No workspace dependency (parallel development).

  • Surface registration: ctx.surfaces.register() with label, icon, regions, activate/deactivate
  • Region management: ctx.ui.replace() / ctx.ui.restore() for CM6 state preservation
  • Mode selector in sidebar when ≥1 extension surface registered
  • surface.activated / surface.deactivated events
  • REPL console (#70): fourth debug modal tab, AsyncFunction wrapper, injected globals, command history, tab-completion, admin-gated

v0.21.4 — Git Integration

Layer git operations onto workspaces.

  • workspaces additions: git_remote_url, git_branch, git_credential_id, git_last_sync
  • git_credentials table: auth_type (https_pat/https_basic/ssh_key), encrypted_data (AES-256-GCM)
  • Git operations via exec: clone, pull, push, status, diff, commit, log, branch, checkout
  • Workspace tools (git-aware): git_status, git_diff, git_commit, git_log, git_branch
  • Post-operation hooks: clone/pull/checkout trigger reconcile + re-index changed files

v0.21.5 — Editor Surface (Development Mode)

IDE-like experience. Browser-tier extension consuming workspace primitives.

  • Layout: file tree (sidebar), code editor (CM6, main), AI chat panel (resizable split), status bar
  • File tree: workspace_ls backed, git status indicators, context menu, drag-drop
  • Code editor: CM6 codeEditor() factory, language auto-detection, tab bar, Ctrl+S save
  • AI chat panel: same channel context, workspace tools auto-injected, live update via EventBus
  • Keyboard shortcuts: Ctrl+P quick open, Ctrl+Shift+F workspace search

v0.21.6 — Article Surface + Document Output Pipeline

Writing-focused surface. Document is artifact, conversation is secondary.

  • Document output pipeline: write → workspace → export (markdown → HTML/PDF/DOCX via pandoc)
  • Layout: outline (sidebar top), AI assistant (sidebar bottom), rich text editor (CM6 markdown, main)
  • Outline: auto-generated from headings, click-to-scroll, drag to reorder
  • AI assistant: lightweight chat with article-specific tools (suggest_outline, expand_section, check_citations)
  • Rich text editor: CM6 noteEditor() with enhanced live preview, focus mode
  • Export: download as markdown/HTML/PDF, copy to clipboard

v0.22.0 — Smart Routing + Provider Extensions

Depends on: model roles (v0.10.0), usage tracking (v0.10.0). Rules-based routing engine — policy, not ML. Plus declarative provider configuration to replace hardcoded provider-specific behavior.

(Shifted from v0.19.0 — routing content unchanged, provider extensions added)

Routing

  • Admin routing policies: "cheapest model with required capabilities", "prefer private providers, fallback to cloud", "for team X, use Y"
  • Fallback chains: primary provider down → next with same model
  • Cost-aware: factor pricing into routing decisions
  • Latency-aware: track response times per provider, prefer faster

Provider Extensions (declarative provider config)

  • provider_profiles table (or JSONB on api_configs): per-provider configuration schema
  • System prompt injection: provider-specific preambles (e.g. Venice character system prompt)
  • Thinking mode toggle: per-provider think parameter support (Venice venice_parameters.include_venice_system_prompt, Anthropic thinking, etc.)
  • Request transform hooks: provider-specific parameter mapping before API call
  • Response transform hooks: normalize provider-specific response fields
  • Admin UI: provider profile editor (key-value config per provider type)
  • Preset-level overrides: Persona can override provider-specific settings (e.g. "always enable thinking for this Persona")
  • Provider health: track error rates, latency percentiles, auto-disable unhealthy providers
  • Search/URL fetch rate limiting per provider
  • Capability admin/user override: manual correction for model capabilities (intrinsic.go admin override layer)

v0.23.0 — Multi-Participant Channels + Presence

The channel foundation for workflows and real-time collaboration. Today channels are single-user direct chats. This release makes channels a shared space that multiple actors can inhabit.

Depends on: extension surfaces (v0.21.3), WebSocket infrastructure (already exists).

(Shifted from v0.20.0 — no content changes)

Channel Participants

  • channel_participants table: channel_id, participant_type (user, session, persona), participant_id, role (owner, member, observer), joined_at
  • Channel access queries rewritten: WHERE user_id = $1 → participant-based lookup
  • Backward compatible: existing single-user channels auto-have one participant (owner)
  • Channel type column: direct (current), group (multi-user), workflow (staged)

Presence + Real-time

  • Typing indicators and presence (who's online, who's in this channel)
  • Participant join/leave events via WebSocket
  • Co-editing for extension surfaces (editor mode, article mode)
  • Cursor sharing, selection highlighting

Channel-Scoped Notes

  • Optional channel_id FK on notes (NULL = personal notebook, set = channel-attached)
  • Notes created by tool calls within a channel auto-attach to that channel
  • Channel notes visible to all participants (not just creator)

v0.24.0 — Auth Strategy (mTLS/OIDC) + Full RBAC

Enterprise auth modes on top of the teams + groups foundation. Depends on: vault passphrase support from v0.9.3 (conditional unlock for personal providers under external auth), user groups (v0.16.0).

(Shifted from v0.21.0 — enhanced with group-based permissions)

  • AUTH_MODE env var: builtin | mtls | oidc
  • All three resolve to the same internal user model
  • auth_source + external_id columns on users table
  • mTLS: header trust, auto-provision from cert DN
  • OIDC: Keycloak/Okta token validation, claim extraction, role mapping
  • Per-source auto-activate policy: auto_activate, default_team, default_role
  • Vault passphrase prompt for mTLS/OIDC users (v0.9.3 conditional unlock)
  • Fine-grained permissions: model access, KB write, task create, token budgets
  • Group-based permission sets: assign permissions to groups, users inherit from membership
  • OIDC claim → group mapping: external IdP groups auto-sync to internal groups

Anonymous / Session Participants

  • Session-based identity for unauthenticated visitors (workflow intake)
  • mTLS: cert CN/fingerprint as stable session identity (no users row required)
  • Non-mTLS: ephemeral session token (cookie or URL token)
  • Session participants can send messages and trigger tool calls within workflow channels
  • Session identity visible to assigned team members (cert DN, display name, or "Anonymous #N")

v0.25.0 — Workflow Engine

Team-owned, stage-based process execution. The channel is the runtime, personas drive each stage, and the existing tool/notes infrastructure handles structured data collection. See ARCHITECTURE.md — Workflow Architecture for the conceptual model.

Depends on: multi-participant channels (v0.23.0), anonymous identity (v0.24.0).

(Shifted from v0.22.0 — no content changes, dependency refs updated)

Workflow Definitions

  • workflows table: team_id (owner), name, description, is_active, entry_mode (public_link, team_internal, api)
  • workflow_stages table: workflow_id, ordinal, persona_id, assignment_team_id, form_template (JSONB, structured note schema), transition_rules (JSONB)
  • Team-admin CRUD: create/edit/delete workflows and stages
  • Workflow versioning: edits create new version, active instances continue on their version

Workflow Instances (Channels)

  • Workflow-typed channels: type='workflow', workflow_id, current_stage, stage_version
  • Entry point: public link generates workflow channel, adds anonymous participant, binds stage 1 persona
  • Stage transitions: triggered by AI (tool call), team member (button), or rule (form complete)
  • On transition: swap active persona, notify assignment team, update channel metadata

AI Intake

  • Stage persona drives structured collection via system prompt
  • Form template → persona system prompt injection ("collect these fields: ...")
  • Tool calls create channel-scoped notes as form responses
  • AI determines readiness: "I have everything needed" → trigger transition

Assignment + Queue

  • Assignment queue: unassigned workflow channels visible to team members
  • Claim model: team member claims channel (becomes participant with member role)
  • Round-robin / rule-based auto-assignment (optional, per-stage config)
  • Assignment notifications via WebSocket + optional webhook

Team Member Collaboration

  • Assigned member sees full history (AI intake + artifacts + notes)
  • Persona remains active — assists both visitor and team member
  • Member can trigger stage transitions, add notes, invoke tools
  • Member can reassign to different team member or escalate to different team

Frontend

  • Workflow builder UI in team admin panel (stage list, persona picker, form template editor)
  • Queue view: sidebar section showing unassigned workflow channels for user's teams
  • Channel header: workflow stage indicator, transition controls
  • Anonymous visitor view: minimal UI, persona-driven conversation (public link entry)

v0.26.0 — Tasks / Autonomous Agents

Unattended execution — workflows without a human in the loop. Depends on: workflow engine (v0.25.0).

(Shifted from v0.23.0 — no content changes, dependency refs updated)

  • Scheduler + task runner (cron-like triggers for workflow instantiation)
  • task_create tool (AI can spawn sub-workflows)
  • type: 'service' channels: workflow instances with no human participants
  • Execution budgets: max tokens, max tool calls, max wall-clock per stage
  • Admin controls for resource limits and kill switches
  • Completion webhooks (notify external systems when workflow completes)

TBD (unscheduled — real features, no immediate need)

Items that are real but don't yet have a version assignment. Pull left based on need.

Extension System — Additional Extensions

  • Image generation tool (browser or sidecar, provider-agnostic)
  • STT/TTS (browser extension, Web Speech API — personal use case)
  • Code execution sandbox (server-side, container isolation)

Extension System — Server Tiers

  • Starlark runtime integration (Tier 1 — server sandbox)
  • Sidecar HTTP tool protocol (Tier 2 — container isolation)
  • Server-side tool execution in completion handler

Desktop + Mobile

  • Desktop app (Tauri)
  • Full PWA with offline capability
  • Mobile-optimized layouts (beyond current responsive)

Data + Portability

  • Bulk export/import (account data, conversations, settings)
  • ChatGPT/other tool import
  • GDPR-style "download my data"
  • Backup/restore CronJob manifests

UX / Multi-Seat

  • "Group" scope badge on model selector / KB list: show access-source annotation so users see why they have access (global, team, group grant). Requires backend to include access_source in list responses.
  • Per-provider model preferences: user_model_settings unique key is (user_id, model_id) — same model from different providers shares one visibility toggle. Needs provider_config_id dimension in DB constraint, store, API, and frontend hiddenModels keying. Frontend composite key (configId:modelId) already exists in App.models[].id.

Projects — Future

  • Project-specific files: full project-level upload (own endpoint, storage path, UI surface — not just channel attachment re-linking)
  • Project templates: create new projects from predefined configurations (persona, KBs, system prompt)
  • Project creation dialog: replace prompt() with proper modal (name, description, persona, KB picker)
  • Admin-level project management: cross-instance visibility, reassign ownership, enforce team policies (scope: enterprise only, BYOK personal projects stay private)
  • Sub-projects / nested hierarchy: child inherits parent KBs, system prompt, persona (deferred until usage patterns clarify need vs tags/labels)

Knowledge Bases — Future

  • KB auto-injection: top-K chunk prepend to system prompt, context budget aware, per-channel toggle (latency budgeting required)
  • Hybrid search: combine vector similarity with full-text tsvector, re-rank
  • Semantic chunking: embedding-based boundary detection for smarter splits
  • HNSW index: better query performance than IVFFlat for large datasets
  • Web scraping source: ingest URLs as KB documents (extends url_fetch)
  • Scheduled re-indexing: periodic rebuild when source documents update
  • Store cleanup: add UpdateDocumentStorageKey() to KnowledgeBaseStore interface (done in v0.17.0) (currently uses direct database.DB.ExecContext in handler — works but bypasses store layer)

Memory — Future

  • Memory compaction: summarize old memories to save context tokens
  • Memory confidence decay: reduce confidence over time, prune low-confidence entries
  • Memory export/import: portable memory format across instances
  • Cross-persona memory sharing (opt-in): e.g. "coding assistant" can read facts from "project manager"
  • Memory analytics: dashboard showing what Personas are learning, memory growth trends

Platform

  • Rate limiting per user/team/tier (token budgets)
  • Provider health monitoring → v0.22.0 + key rotation
  • Multi-tenant SaaS mode
  • Plugin/extension marketplace
  • Virtual scroll for long conversations
  • SQLite backend option (single-user / dev) → v0.17.1