Overhaul the Dench web app with a comprehensive visual redesign and several
major feature additions across the chat interface, workspace, and agent
runtime layer.
Theme & Design System
- Replace the dark-only palette with a full light/dark theme system that
respects system preference via localStorage + inline script (no FOUC).
- Introduce new design tokens: glassmorphism surfaces, semantic colors
(success/warning/error/info), object-type chip palettes, and a tiered
shadow scale (sm/md/lg/xl).
- Add Instrument Serif + Inter via Google Fonts for a refined typographic
hierarchy; headings use the serif face, body uses Inter.
- Rebrand UI from "Ironclaw" to "Dench" across the landing page and
metadata.
Chat & Chain-of-Thought
- Rewrite the chain-of-thought component with inline media detection and
rendering — images, video, audio, and PDFs referenced in agent output
are now displayed directly in the conversation thread.
- Add status indicator parts (e.g. "Preparing response...",
"Optimizing session context...") that render as subtle activity badges
instead of verbose reasoning blocks.
- Integrate react-markdown with remark-gfm for proper markdown rendering
in assistant messages (tables, strikethrough, autolinks, etc.).
- Improve report-block splitting and lazy-loaded ReportCard rendering.
Workspace
- Introduce @tanstack/react-table for the object table, replacing the
hand-rolled table with full column sorting, fuzzy filtering via
match-sorter-utils, row selection, and bulk actions.
- Add a new media viewer component for in-workspace image/video/PDF
preview.
- New API routes: bulk-delete entries, field management (CRUD + reorder),
raw-file serving endpoint for media assets.
- Redesign workspace sidebar, empty state, and entry detail modal with
the new theme tokens and improved layout.
Agent Runtime
- Switch web agent execution from --local to gateway-routed mode so
concurrent chat threads share the gateway's lane-based concurrency
system, eliminating cross-process file-lock contention.
- Advertise "tool-events" capability during WebSocket handshake so the
gateway streams tool start/update/result events to the UI.
- Add new agent callback hooks: onLifecycleStart, onCompactionStart/End,
and onToolUpdate for richer real-time feedback.
- Forward media URLs emitted by agent events into the chat stream.
Dependencies
- Add @tanstack/match-sorter-utils and @tanstack/react-table to the web
app.
Published as ironclaw@2026.2.10-1.
Co-authored-by: Cursor <cursoragent@cursor.com>
New libraries:
- workspace-links.ts: builders, parsers, and type guards for workspace URLs
(/workspace?path=... for files/objects, /workspace?entry=objName:id for entries).
Replaces ad-hoc relative-path links with real navigable URLs.
- search-index.ts: useSearchIndex hook that fetches a unified search index from
the API and provides Fuse.js-powered fuzzy search across files, objects, and
database entries. Exposes a stable ref-based search function safe for capture
in tiptap extensions.
New API routes:
- GET /api/workspace/search-index: builds a flat search index from the filesystem
tree (knowledge/, reports/, top-level files) and all DuckDB object entries with
display-field labels and preview fields.
- GET /api/workspace/objects/[name]/entries/[id]: fetches a single entry with
all field values, resolved relation labels, reverse relations (incoming links
from other objects), and the effective display field.
New component:
- EntryDetailModal: slide-over modal for viewing an individual entry's fields,
enum badges, user avatars, clickable relation chips (navigate to related
entries), reverse relation sections, and timestamps. Supports Escape to close
and backdrop click dismiss.
Slash command refactor (slash-command.tsx):
- New createWorkspaceMention(searchFn) replaces the old file-only @ mention with
unified search across files, objects, and entries.
- searchItemToSlashItem() converts search index items into tiptap suggestion
items with proper icons, badges (object name pill for entries), and link
insertion commands using real workspace URLs.
- Legacy createFileMention(tree) now delegates to createWorkspaceMention with a
simple substring-match fallback for when no search index is available.
Editor integration (markdown-editor.tsx, document-view.tsx):
- MarkdownEditor accepts optional searchFn prop; when provided, uses
createWorkspaceMention instead of the legacy createFileMention.
- Link click interception now uses the shared isWorkspaceLink() helper and
registers handlers in capture phase for reliable interception.
- DocumentView forwards searchFn to editor and adds a delegated click handler
in read mode to intercept workspace links and navigate via onNavigate.
Object table (object-table.tsx):
- Added onEntryClick prop; table rows are now clickable with cursor-pointer
styling, firing the callback with the entry ID.
Workspace page (page.tsx):
- Integrates useSearchIndex hook and passes search function down to editor.
- Entry detail modal state with URL synchronization (?entry=objName:id param).
- New resolveNode() with fallback strategies: exact match, knowledge/ prefix
toggle, and last-segment object name matching.
- Unified handleEditorNavigate() dispatches /workspace?entry=... to the modal
and /workspace?path=... to file/object navigation.
- URL bar syncs with activePath via router.replace (no full page reloads).
- Top-level container click safety net catches any workspace link clicks that
bubble up unhandled.
Styles (globals.css):
- Added .slash-cmd-item-badge for object-name pills in the @ mention popup.