openclaw/apps/web/app/components/chat-panel.tsx

2147 lines
60 KiB
TypeScript
Raw Normal View History

Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
"use client";
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport, type UIMessage } from "ai";
import {
forwardRef,
useCallback,
useEffect,
useImperativeHandle,
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
useMemo,
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
useRef,
useState,
} from "react";
import { ChatMessage } from "./chat-message";
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
import {
FilePickerModal,
type SelectedFile,
} from "./file-picker-modal";
import { ChatEditor, type ChatEditorHandle } from "./tiptap/chat-editor";
2026-02-19 17:46:54 -08:00
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "./ui/dropdown-menu";
import { UnicodeSpinner } from "./unicode-spinner";
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
2026-02-13 15:52:13 -08:00
// ── Attachment types & helpers ──
type AttachedFile = {
id: string;
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
name: string;
2026-02-13 15:52:13 -08:00
path: string;
/** True while the file is still uploading to the server. */
uploading?: boolean;
/** Local blob URL for instant preview before upload completes. */
localUrl?: string;
2026-02-13 15:52:13 -08:00
};
function getFileCategory(
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
name: string,
2026-02-13 15:52:13 -08:00
): "image" | "video" | "audio" | "pdf" | "code" | "document" | "other" {
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
const ext = name.split(".").pop()?.toLowerCase() ?? "";
if (
[
"jpg", "jpeg", "png", "gif", "webp", "svg", "bmp",
"ico", "tiff", "heic",
].includes(ext)
)
{return "image";}
if (["mp4", "webm", "mov", "avi", "mkv", "flv"].includes(ext))
{return "video";}
if (["mp3", "wav", "ogg", "aac", "flac", "m4a"].includes(ext))
{return "audio";}
if (ext === "pdf") {return "pdf";}
2026-02-13 15:52:13 -08:00
if (
[
"js", "ts", "tsx", "jsx", "py", "rb", "go", "rs", "java",
"cpp", "c", "h", "css", "html", "json", "yaml", "yml",
"toml", "md", "sh", "bash", "sql", "swift", "kt",
].includes(ext)
)
{return "code";}
if (
[
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt",
"rtf", "csv", "pages", "numbers", "key",
].includes(ext)
)
{return "document";}
return "other";
}
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
function shortenPath(path: string): string {
return path
.replace(/^\/Users\/[^/]+/, "~")
.replace(/^\/home\/[^/]+/, "~")
.replace(/^[A-Z]:\\Users\\[^\\]+/, "~");
2026-02-13 15:52:13 -08:00
}
const categoryMeta: Record<string, { bg: string; fg: string }> = {
image: { bg: "rgba(16, 185, 129, 0.12)", fg: "#10b981" },
video: { bg: "rgba(139, 92, 246, 0.12)", fg: "#8b5cf6" },
audio: { bg: "rgba(245, 158, 11, 0.12)", fg: "#f59e0b" },
pdf: { bg: "rgba(239, 68, 68, 0.12)", fg: "#ef4444" },
code: { bg: "rgba(59, 130, 246, 0.12)", fg: "#3b82f6" },
document: { bg: "rgba(107, 114, 128, 0.12)", fg: "#6b7280" },
other: { bg: "rgba(107, 114, 128, 0.08)", fg: "#9ca3af" },
};
function FileTypeIcon({ category }: { category: string }) {
const props = {
width: 16,
height: 16,
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: 2,
strokeLinecap: "round" as const,
strokeLinejoin: "round" as const,
};
switch (category) {
case "image":
return (
<svg {...props}>
<rect width="18" height="18" x="3" y="3" rx="2" ry="2" />
<circle cx="9" cy="9" r="2" />
<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" />
</svg>
);
case "video":
return (
<svg {...props}>
<path d="m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5" />
<rect x="2" y="6" width="14" height="12" rx="2" />
</svg>
);
case "audio":
return (
<svg {...props}>
<path d="M9 18V5l12-2v13" />
<circle cx="6" cy="18" r="3" />
<circle cx="18" cy="16" r="3" />
</svg>
);
case "pdf":
return (
<svg {...props}>
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
<path d="M14 2v6h6" />
<path d="M10 13h4" />
<path d="M10 17h4" />
</svg>
);
case "code":
return (
<svg {...props}>
<polyline points="16 18 22 12 16 6" />
<polyline points="8 6 2 12 8 18" />
</svg>
);
case "document":
return (
<svg {...props}>
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
<path d="M14 2v6h6" />
<path d="M16 13H8" />
<path d="M16 17H8" />
<path d="M10 9H8" />
</svg>
);
default:
return (
<svg {...props}>
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
<path d="M14 2v6h6" />
</svg>
);
}
}
2026-02-19 21:58:10 -08:00
function QueueItem({
msg,
idx,
onEdit,
onSendNow,
onRemove,
}: {
msg: QueuedMessage;
idx: number;
onEdit: (id: string, text: string) => void;
onSendNow: (id: string) => void;
onRemove: (id: string) => void;
}) {
const [editing, setEditing] = useState(false);
const [draft, setDraft] = useState(msg.text);
const inputRef = useRef<HTMLTextAreaElement>(null);
const autoResize = () => {
const el = inputRef.current;
if (!el) {return;}
el.style.height = "auto";
el.style.height = `${el.scrollHeight}px`;
};
useEffect(() => {
if (editing) {
inputRef.current?.focus();
const len = inputRef.current?.value.length ?? 0;
inputRef.current?.setSelectionRange(len, len);
autoResize();
}
}, [editing]);
const commitEdit = () => {
const trimmed = draft.trim();
if (trimmed && trimmed !== msg.text) {
onEdit(msg.id, trimmed);
} else {
setDraft(msg.text);
}
setEditing(false);
};
return (
<div
className={`flex items-start gap-2.5 group py-2 ${idx > 0 ? "border-t" : ""}`}
style={idx > 0 ? { borderColor: "var(--color-border)" } : undefined}
>
<span
className="shrink-0 mt-px text-[11px] font-medium tabular-nums w-4"
style={{ color: "var(--color-text-muted)" }}
>
{idx + 1}
</span>
{editing ? (
<textarea
ref={inputRef}
className="flex-1 text-[13px] leading-[1.45] min-w-0 resize-none rounded-md px-2 py-1 outline-none"
style={{
color: "var(--color-text-secondary)",
background: "var(--color-bg)",
border: "1px solid var(--color-border)",
}}
rows={1}
value={draft}
onChange={(e) => { setDraft(e.target.value); autoResize(); }}
onBlur={commitEdit}
onKeyDown={(e) => {
if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); commitEdit(); }
if (e.key === "Escape") { setDraft(msg.text); setEditing(false); }
}}
/>
) : (
<div className="flex-1 min-w-0 flex items-center gap-2">
{msg.attachedFiles.length > 0 && (
<div className="flex gap-1 shrink-0">
{msg.attachedFiles.map((af) => {
const cat = getFileCategory(af.name);
const src = cat === "image"
? (af.localUrl || `/api/workspace/raw-file?path=${encodeURIComponent(af.path)}`)
: af.path ? `/api/workspace/thumbnail?path=${encodeURIComponent(af.path)}&size=100` : undefined;
return (
<img
key={af.id}
src={src}
alt={af.name}
className="rounded object-cover"
style={{ height: 28, width: 28, background: "var(--color-surface-hover)" }}
onError={(e) => { (e.currentTarget as HTMLImageElement).style.display = "none"; }}
/>
);
})}
</div>
)}
<p
className="text-[13px] leading-[1.45] line-clamp-1 min-w-0"
style={{ color: "var(--color-text-secondary)" }}
>
{msg.text || `${msg.attachedFiles.length} ${msg.attachedFiles.length === 1 ? "file" : "files"}`}
</p>
</div>
2026-02-19 21:58:10 -08:00
)}
{!editing && (
<div className="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity">
{/* Edit */}
<button
type="button"
className="rounded-md p-1 transition-colors hover:bg-stone-100 dark:hover:bg-stone-800"
title="Edit message"
onClick={() => { setDraft(msg.text); setEditing(true); }}
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="text-stone-400">
<path d="M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
<path d="M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z" />
</svg>
</button>
{/* Send now */}
<button
type="button"
className="rounded-md p-1 transition-colors hover:bg-stone-100 dark:hover:bg-stone-800"
title="Send now"
onClick={() => onSendNow(msg.id)}
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="text-stone-400">
<path d="M12 19V5" />
<path d="m5 12 7-7 7 7" />
</svg>
</button>
{/* Delete */}
<button
type="button"
className="rounded-md p-1 transition-colors hover:bg-stone-100 dark:hover:bg-stone-800"
title="Remove from queue"
onClick={() => onRemove(msg.id)}
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="text-stone-400">
<path d="M3 6h18" />
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" />
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" />
</svg>
</button>
</div>
)}
</div>
);
}
2026-02-13 15:52:13 -08:00
function AttachmentStrip({
files,
compact,
onRemove,
onClearAll: _onClearAll,
2026-02-13 15:52:13 -08:00
}: {
files: AttachedFile[];
compact?: boolean;
onRemove: (id: string) => void;
onClearAll: () => void;
}) {
if (files.length === 0) {return null;}
return (
<div className={`${compact ? "px-2" : "px-3"} pt-2`}>
2026-02-13 15:52:13 -08:00
<div
className="flex gap-2 overflow-x-auto pb-1"
style={{ scrollbarWidth: "thin" }}
>
{files.map((af) => {
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
const category = getFileCategory(
af.name,
);
2026-02-13 15:52:13 -08:00
const meta =
categoryMeta[category] ??
categoryMeta.other;
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
const short = shortenPath(af.path);
2026-02-13 15:52:13 -08:00
return (
<div
key={af.id}
className="relative group flex-shrink-0 rounded-xl overflow-hidden"
style={{
background:
"var(--color-surface-hover)",
border: "1px solid var(--color-border)",
}}
>
{/* Remove button */}
<button
type="button"
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
onClick={() =>
onRemove(af.id)
}
2026-02-13 15:52:13 -08:00
className="absolute top-1 right-1 z-10 w-[18px] h-[18px] rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity"
style={{
background:
"rgba(0,0,0,0.55)",
color: "white",
backdropFilter:
"blur(4px)",
}}
>
<svg
width="8"
height="8"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="3"
strokeLinecap="round"
>
<path d="M18 6 6 18" />
<path d="m6 6 12 12" />
</svg>
</button>
{category === "image" ? (
/* Image thumbnail — no filename */
<img
src={af.localUrl || `/api/workspace/raw-file?path=${encodeURIComponent(af.path)}`}
alt={af.name}
className="block rounded-xl object-cover"
style={{
height: 80,
width: "auto",
minWidth: 60,
maxWidth: 140,
opacity: af.uploading ? 0.6 : 1,
background: "var(--color-bg-secondary)",
}}
onError={(e) => {
(e.currentTarget as HTMLImageElement).style.display = "none";
}}
/>
) : category === "pdf" && af.path ? (
/* PDF thumbnail via Quick Look */
<img
src={`/api/workspace/thumbnail?path=${encodeURIComponent(af.path)}&size=200`}
alt={af.name}
className="block rounded-xl object-cover"
style={{
height: 80,
width: "auto",
minWidth: 60,
maxWidth: 140,
opacity: af.uploading ? 0.6 : 1,
background: "var(--color-bg-secondary)",
}}
onError={(e) => {
(e.currentTarget as HTMLImageElement).style.display = "none";
}}
/>
) : (
<div className="flex items-center gap-2.5 px-3 py-2.5" style={{ opacity: af.uploading ? 0.6 : 1 }}>
<div
className="w-8 h-8 rounded-lg flex items-center justify-center shrink-0"
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
style={{
background: meta.bg,
color: meta.fg,
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
}}
>
<FileTypeIcon category={category} />
</div>
<div className="min-w-0 max-w-[140px]">
<p
className="text-[11px] font-medium truncate"
style={{ color: "var(--color-text)" }}
title={af.path || af.name}
>
{af.name}
</p>
<p
className="text-[9px] truncate"
style={{ color: "var(--color-text-muted)" }}
title={af.path || af.name}
>
{af.uploading ? "Uploading..." : short}
</p>
</div>
2026-02-13 15:52:13 -08:00
</div>
)}
2026-02-13 15:52:13 -08:00
</div>
);
})}
</div>
</div>
);
}
// ── SSE stream parser for reconnection ──
// Converts raw SSE events (AI SDK v6 wire format) into UIMessage parts.
type ParsedPart =
| { type: "text"; text: string }
| { type: "user-message"; id?: string; text: string }
| { type: "reasoning"; text: string; state?: string }
| {
type: "dynamic-tool";
toolName: string;
toolCallId: string;
state: string;
input?: Record<string, unknown>;
output?: Record<string, unknown>;
};
export function createStreamParser() {
const parts: ParsedPart[] = [];
let currentTextIdx = -1;
let currentReasoningIdx = -1;
function processEvent(event: Record<string, unknown>) {
const t = event.type as string;
switch (t) {
case "user-message":
currentTextIdx = -1;
currentReasoningIdx = -1;
parts.push({
type: "user-message",
id: event.id as string | undefined,
text: (event.text as string) ?? "",
});
break;
case "reasoning-start":
parts.push({
type: "reasoning",
text: "",
state: "streaming",
});
currentReasoningIdx = parts.length - 1;
break;
case "reasoning-delta": {
if (currentReasoningIdx >= 0) {
const p = parts[currentReasoningIdx] as {
type: "reasoning";
text: string;
};
p.text += event.delta as string;
}
break;
}
case "reasoning-end":
if (currentReasoningIdx >= 0) {
const p = parts[currentReasoningIdx] as {
type: "reasoning";
state?: string;
};
delete p.state;
}
currentReasoningIdx = -1;
break;
case "text-start":
parts.push({ type: "text", text: "" });
currentTextIdx = parts.length - 1;
break;
case "text-delta": {
if (currentTextIdx >= 0) {
const p = parts[currentTextIdx] as {
type: "text";
text: string;
};
p.text += event.delta as string;
}
break;
}
case "text-end":
currentTextIdx = -1;
break;
case "tool-input-start":
parts.push({
type: "dynamic-tool",
toolCallId: event.toolCallId as string,
toolName: event.toolName as string,
state: "input-available",
input: {},
});
break;
case "tool-input-available":
for (let i = parts.length - 1; i >= 0; i--) {
const p = parts[i];
if (
p.type === "dynamic-tool" &&
p.toolCallId === event.toolCallId
) {
p.input =
(event.input as Record<string, unknown>) ??
{};
break;
}
}
break;
case "tool-output-available":
for (let i = parts.length - 1; i >= 0; i--) {
const p = parts[i];
if (
p.type === "dynamic-tool" &&
p.toolCallId === event.toolCallId
) {
p.state = "output-available";
p.output =
(event.output as Record<
string,
unknown
>) ?? {};
break;
}
}
break;
case "tool-output-error":
for (let i = parts.length - 1; i >= 0; i--) {
const p = parts[i];
if (
p.type === "dynamic-tool" &&
p.toolCallId === event.toolCallId
) {
p.state = "error";
p.output = {
error: event.errorText as string,
};
break;
}
}
break;
}
}
return {
processEvent,
getParts: (): ParsedPart[] => parts.map((p) => ({ ...p })),
};
}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
/** Imperative handle for parent-driven session control (main page). */
export type ChatPanelHandle = {
loadSession: (sessionId: string) => Promise<void>;
newSession: () => Promise<void>;
/** Create a new session and immediately send a message. */
sendNewMessage: (text: string) => Promise<void>;
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
/** Insert a file mention into the chat editor (e.g. from sidebar drag). */
insertFileMention?: (name: string, path: string) => void;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
};
export type FileContext = {
path: string;
filename: string;
2026-02-13 18:57:15 -08:00
/** When true the path refers to a directory rather than a file. */
isDirectory?: boolean;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
};
type FileScopedSession = {
id: string;
title: string;
createdAt: number;
updatedAt: number;
messageCount: number;
};
/** A message waiting to be sent after the current agent run finishes. */
type QueuedMessage = {
id: string;
text: string;
mentionedFiles: Array<{ name: string; path: string }>;
attachedFiles: AttachedFile[];
createdAt: number;
};
2026-02-19 14:59:34 -08:00
export type SubagentSpawnInfo = {
childSessionKey: string;
runId: string;
task: string;
label?: string;
parentSessionId: string;
status?: "running" | "completed" | "error";
};
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
type ChatPanelProps = {
/** When set, scopes sessions to this file and prepends content as context. */
fileContext?: FileContext;
/** Compact mode for workspace sidebar (smaller UI, built-in session tabs). */
compact?: boolean;
2026-02-13 19:24:24 -08:00
/** Override the header title when a session is active (e.g. show the session's actual title). */
sessionTitle?: string;
2026-02-15 23:42:13 -08:00
/** Session ID to auto-load on mount (for non-file panels that remount after navigation). */
initialSessionId?: string;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
/** Called when file content may have changed after agent edits. */
onFileChanged?: (newContent: string) => void;
/** Called when active session changes (for external sidebar highlighting). */
onActiveSessionChange?: (sessionId: string | null) => void;
/** Called when session list needs refresh (for external sidebar). */
onSessionsChange?: () => void;
2026-02-19 14:59:34 -08:00
/** Called when the agent spawns a subagent. */
onSubagentSpawned?: (info: SubagentSpawnInfo) => void;
/** Called when user clicks a subagent card in the chat to view its output. */
onSubagentClick?: (task: string) => void;
2026-02-19 17:46:54 -08:00
/** Called when user clicks an inline file path in chat output. */
onFilePathClick?: (path: string) => Promise<boolean | void> | boolean | void;
/** Called when user deletes the current session (e.g. from header menu). */
onDeleteSession?: (sessionId: string) => void;
/** Called when user renames the current session. */
onRenameSession?: (sessionId: string, newTitle: string) => void;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
};
export const ChatPanel = forwardRef<ChatPanelHandle, ChatPanelProps>(
function ChatPanelInner(
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
{
fileContext,
compact,
2026-02-13 19:24:24 -08:00
sessionTitle,
2026-02-15 23:42:13 -08:00
initialSessionId,
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
onFileChanged,
onActiveSessionChange,
onSessionsChange,
2026-02-19 14:59:34 -08:00
onSubagentSpawned,
onSubagentClick,
2026-02-19 17:46:54 -08:00
onFilePathClick,
onDeleteSession,
onRenameSession: _onRenameSession,
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
},
ref,
) {
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
const editorRef = useRef<ChatEditorHandle>(null);
const [editorEmpty, setEditorEmpty] = useState(true);
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
const [currentSessionId, setCurrentSessionId] = useState<
string | null
>(null);
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
const [loadingSession, setLoadingSession] = useState(false);
const messagesEndRef = useRef<HTMLDivElement>(null);
2026-02-13 15:52:13 -08:00
// ── Attachment state ──
const [attachedFiles, setAttachedFiles] = useState<
AttachedFile[]
>([]);
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
const [showFilePicker, setShowFilePicker] =
useState(false);
2026-02-13 15:52:13 -08:00
// ── Reconnection state ──
const [isReconnecting, setIsReconnecting] = useState(false);
const reconnectAbortRef = useRef<AbortController | null>(null);
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
// Track persisted messages to avoid double-saves
const savedMessageIdsRef = useRef<Set<string>>(new Set());
// Set when /new or + triggers a new session
const newSessionPendingRef = useRef(false);
// Whether the next message should include file context
const isFirstFileMessageRef = useRef(true);
// File-scoped session list (compact mode only)
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
const [fileSessions, setFileSessions] = useState<
FileScopedSession[]
>([]);
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
// ── Message queue (messages to send after current run completes) ──
const [queuedMessages, setQueuedMessages] = useState<QueuedMessage[]>([]);
const [rawView, _setRawView] = useState(false);
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
const filePath = fileContext?.path ?? null;
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
// ── Ref-based session ID for transport ──
const sessionIdRef = useRef<string | null>(null);
useEffect(() => {
sessionIdRef.current = currentSessionId;
}, [currentSessionId]);
// ── Transport (per-instance) ──
const transport = useMemo(
() =>
new DefaultChatTransport({
api: "/api/chat",
body: () => {
const sid = sessionIdRef.current;
return sid ? { sessionId: sid } : {};
},
}),
[],
);
const { messages, sendMessage, status, stop, error, setMessages } =
useChat({ transport });
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
const isStreaming =
status === "streaming" ||
status === "submitted" ||
isReconnecting;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
2026-02-14 14:07:53 -08:00
// Auto-scroll to bottom on new messages, but only when the user
// is already near the bottom. If the user scrolls up during
// streaming, we stop auto-scrolling until they return to the
// bottom (or a new user message is sent).
const scrollContainerRef = useRef<HTMLDivElement>(null);
const userScrolledAwayRef = useRef(false);
const scrollRafRef = useRef(0);
// Detect when the user scrolls away from the bottom.
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
useEffect(() => {
2026-02-14 14:07:53 -08:00
const el = scrollContainerRef.current;
if (!el) {return;}
const onScroll = () => {
const distanceFromBottom =
el.scrollHeight - el.scrollTop - el.clientHeight;
// Threshold: if within 80px of the bottom, consider "at bottom"
userScrolledAwayRef.current = distanceFromBottom > 80;
};
el.addEventListener("scroll", onScroll, { passive: true });
return () => el.removeEventListener("scroll", onScroll);
}, []);
// Auto-scroll effect — skips when user has scrolled away.
useEffect(() => {
if (userScrolledAwayRef.current) {return;}
if (scrollRafRef.current) {return;}
scrollRafRef.current = requestAnimationFrame(() => {
scrollRafRef.current = 0;
messagesEndRef.current?.scrollIntoView({
behavior: "smooth",
});
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
});
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
}, [messages]);
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
// ── Session persistence helpers ──
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
const createSession = useCallback(
async (title: string): Promise<string> => {
const body: Record<string, string> = { title };
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
if (filePath) {
body.filePath = filePath;
}
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
const res = await fetch("/api/web-sessions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
const data = await res.json();
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
return data.session.id;
},
[filePath],
);
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
// ── Stream reconnection ──
// Attempts to reconnect to an active agent run for the given session.
// Replays buffered SSE events and streams live updates.
const attemptReconnect = useCallback(
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
async (
sessionId: string,
baseMessages: Array<{
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
id: string;
role: "user" | "assistant" | "system";
parts: UIMessage["parts"];
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
}>,
): Promise<boolean> => {
const abort = new AbortController();
reconnectAbortRef.current = abort;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
try {
const res = await fetch(
`/api/chat/stream?sessionId=${encodeURIComponent(sessionId)}`,
{ signal: abort.signal },
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
);
if (!res.ok || !res.body) {
return false; // No active run
}
2026-02-15 23:42:13 -08:00
// If the run already completed (still in the grace
// period), skip the expensive SSE replay -- the
// persisted messages we already loaded are final.
if (res.headers.get("X-Run-Active") === "false") {
void res.body.cancel();
2026-02-15 23:42:13 -08:00
return false;
}
setIsReconnecting(true);
const parser = createStreamParser();
const reader = res.body.getReader();
const decoder = new TextDecoder();
const reconnectMsgId = `reconnect-${sessionId}`;
let buffer = "";
let frameRequested = false;
const updateUI = () => {
2026-02-15 23:42:13 -08:00
// Guard: if the session was switched while a
// rAF was pending, don't overwrite the new
// session's messages with stale data.
if (abort.signal.aborted) {return;}
const assistantMsg = {
id: reconnectMsgId,
role: "assistant" as const,
parts: parser.getParts() as UIMessage["parts"],
};
setMessages([
...baseMessages,
assistantMsg,
]);
};
// Read the SSE stream
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- loop reads until done
while (true) {
const { done, value } =
await reader.read();
if (done) {break;}
buffer += decoder.decode(value, {
stream: true,
});
// Parse SSE events (data: <json>\n\n)
let idx;
while (
(idx = buffer.indexOf("\n\n")) !== -1
) {
const chunk = buffer.slice(0, idx);
buffer = buffer.slice(idx + 2);
if (chunk.startsWith("data: ")) {
try {
const event = JSON.parse(
chunk.slice(6),
);
parser.processEvent(event);
} catch {
/* skip malformed events */
}
}
}
// Batch UI updates to animation frames
if (!frameRequested) {
frameRequested = true;
requestAnimationFrame(() => {
frameRequested = false;
updateUI();
});
}
}
// Final update after stream ends
updateUI();
// Mark all messages as saved (server persisted them)
2026-02-15 23:42:13 -08:00
if (!abort.signal.aborted) {
for (const m of baseMessages) {
savedMessageIdsRef.current.add(m.id);
}
savedMessageIdsRef.current.add(reconnectMsgId);
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
}
setIsReconnecting(false);
reconnectAbortRef.current = null;
return true;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
} catch (err) {
if (
(err as Error).name !== "AbortError"
) {
console.error(
"Reconnection error:",
err,
);
}
setIsReconnecting(false);
reconnectAbortRef.current = null;
return false;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
}
},
[setMessages],
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
);
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
// ── File-scoped session initialization ──
const fetchFileSessionsRef = useRef<
(() => Promise<FileScopedSession[]>) | null
>(null);
fetchFileSessionsRef.current = async () => {
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
if (!filePath) {
return [];
}
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
try {
const res = await fetch(
`/api/web-sessions?filePath=${encodeURIComponent(filePath)}`,
);
const data = await res.json();
return (data.sessions || []) as FileScopedSession[];
} catch {
return [];
}
};
useEffect(() => {
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
if (!filePath) {
return;
}
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
let cancelled = false;
sessionIdRef.current = null;
setCurrentSessionId(null);
onActiveSessionChange?.(null);
setMessages([]);
savedMessageIdsRef.current.clear();
isFirstFileMessageRef.current = true;
void (async () => {
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
const sessions =
(await fetchFileSessionsRef.current?.()) ?? [];
if (cancelled) {
return;
}
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
setFileSessions(sessions);
if (sessions.length > 0) {
const latest = sessions[0];
setCurrentSessionId(latest.id);
sessionIdRef.current = latest.id;
onActiveSessionChange?.(latest.id);
isFirstFileMessageRef.current = false;
try {
const msgRes = await fetch(
`/api/web-sessions/${latest.id}`,
);
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
if (cancelled) {
return;
}
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
const msgData = await msgRes.json();
const sessionMessages: Array<{
id: string;
role: "user" | "assistant";
content: string;
parts?: Array<Record<string, unknown>>;
_streaming?: boolean;
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
}> = msgData.messages || [];
// Filter out in-progress streaming messages
// (will be rebuilt from the live SSE stream)
const hasStreaming = sessionMessages.some(
(m) => m._streaming,
);
const completedMessages = hasStreaming
? sessionMessages.filter(
(m) => !m._streaming,
)
: sessionMessages;
const uiMessages = completedMessages.map(
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
(msg) => {
savedMessageIdsRef.current.add(msg.id);
return {
id: msg.id,
role: msg.role,
parts: (msg.parts ?? [
{
type: "text" as const,
text: msg.content,
},
]) as UIMessage["parts"],
};
},
);
2026-02-15 23:42:13 -08:00
if (!cancelled) {
setMessages(uiMessages);
}
2026-02-15 23:42:13 -08:00
// Always try to reconnect to a potentially
// active agent run. The stream endpoint returns
// 404 gracefully if no run exists, avoiding the
// 2-second persistence timing gap for _streaming.
if (!cancelled) {
await attemptReconnect(
latest.id,
uiMessages,
);
}
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
} catch {
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
// ignore
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
}
}
})();
return () => {
cancelled = true;
};
// eslint-disable-next-line react-hooks/exhaustive-deps -- stable setters
}, [filePath, attemptReconnect]);
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
2026-02-15 23:42:13 -08:00
// ── Non-file panel: auto-restore session on mount ──
// When the main ChatPanel remounts after navigation (e.g. user viewed
// a file then returned to chat), re-load the previously active session
// and reconnect to any active stream.
const initialSessionHandled = useRef(false);
useEffect(() => {
if (filePath || !initialSessionId || initialSessionHandled.current) {
return;
}
initialSessionHandled.current = true;
void handleSessionSelect(initialSessionId);
// eslint-disable-next-line react-hooks/exhaustive-deps -- run once on mount
}, []);
2026-02-19 14:59:34 -08:00
// ── Poll for subagent spawns during active streaming ──
const [hasRunningSubagents, setHasRunningSubagents] = useState(false);
2026-02-19 14:59:34 -08:00
useEffect(() => {
if (!currentSessionId || !onSubagentSpawned) {return;}
let cancelled = false;
const poll = async () => {
try {
const res = await fetch(
`/api/chat/subagents?sessionId=${encodeURIComponent(currentSessionId)}`,
);
if (cancelled || !res.ok) {return;}
const data = await res.json();
const subagents: Array<{
sessionKey: string;
runId: string;
task: string;
label?: string;
status: "running" | "completed" | "error";
}> = data.subagents ?? [];
let anyRunning = false;
2026-02-19 14:59:34 -08:00
for (const sa of subagents) {
if (sa.status === "running") {anyRunning = true;}
2026-02-19 14:59:34 -08:00
onSubagentSpawned({
childSessionKey: sa.sessionKey,
runId: sa.runId,
task: sa.task,
label: sa.label,
parentSessionId: currentSessionId,
status: sa.status,
});
}
if (!cancelled) {setHasRunningSubagents(anyRunning);}
2026-02-19 14:59:34 -08:00
} catch { /* ignore */ }
};
void poll();
const id = setInterval(poll, 3_000);
return () => { cancelled = true; clearInterval(id); };
}, [currentSessionId, onSubagentSpawned]);
// ── Post-stream side-effects (file-reload, session refresh) ──
// Message persistence is handled server-side by ActiveRunManager,
// so we only refresh the file sessions list and notify the parent
// when the file content may have changed.
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
const prevStatusRef = useRef(status);
useEffect(() => {
const wasStreaming =
prevStatusRef.current === "streaming" ||
prevStatusRef.current === "submitted";
const isNowReady = status === "ready";
if (wasStreaming && isNowReady && currentSessionId) {
// Mark all current messages as saved — the server
// already persisted them via ActiveRunManager.
for (const m of messages) {
savedMessageIdsRef.current.add(m.id);
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
}
if (filePath) {
void fetchFileSessionsRef.current?.().then(
(sessions) => {
setFileSessions(sessions);
},
);
}
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
if (filePath && onFileChanged) {
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
fetch(
`/api/workspace/file?path=${encodeURIComponent(filePath)}`,
)
.then((r) => r.json())
.then((data) => {
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
if (data.content) {
onFileChanged(data.content);
}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
})
.catch(() => {});
}
onSessionsChange?.();
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
}
prevStatusRef.current = status;
}, [
status,
messages,
currentSessionId,
filePath,
onFileChanged,
onSessionsChange,
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
]);
// ── Actions ──
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
// Ref for handleNewSession so handleEditorSubmit doesn't depend on the hook order
const handleNewSessionRef = useRef<() => void>(() => {});
/** Submit from the Tiptap editor (called on Enter or send button).
* `overrideAttachments` is used by the queue system to pass saved attachments directly. */
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
const handleEditorSubmit = useCallback(
async (
text: string,
mentionedFiles: Array<{ name: string; path: string }>,
overrideAttachments?: AttachedFile[],
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
) => {
const hasText = text.trim().length > 0;
const hasMentions = mentionedFiles.length > 0;
// Use override attachments (from queue) or current state
const readyFiles = overrideAttachments
? overrideAttachments.filter((f) => !f.uploading && f.path)
: attachedFiles.filter((f) => !f.uploading && f.path);
const hasFiles = readyFiles.length > 0;
if (!hasText && !hasMentions && !hasFiles) {
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
return;
}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
const userText = text.trim();
const currentAttachments = [...readyFiles];
2026-02-13 15:52:13 -08:00
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
if (userText.toLowerCase() === "/new") {
// Revoke blob URLs before clearing
for (const f of attachedFiles) {
if (f.localUrl) {URL.revokeObjectURL(f.localUrl);}
}
setAttachedFiles([]);
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
handleNewSessionRef.current();
return;
}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
// Queue the message if the agent is still running.
if (isStreaming) {
// Clear attachment strip but keep blob URLs alive for queue thumbnails
if (!overrideAttachments) {
setAttachedFiles([]);
}
setQueuedMessages((prev) => [
...prev,
{
id: crypto.randomUUID(),
text: userText,
mentionedFiles,
attachedFiles: currentAttachments,
createdAt: Date.now(),
},
]);
return;
}
// Clear attachments (revoke blob URLs to free memory)
if (!overrideAttachments && currentAttachments.length > 0) {
for (const f of attachedFiles) {
if (f.localUrl) {URL.revokeObjectURL(f.localUrl);}
}
setAttachedFiles([]);
}
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
let sessionId = currentSessionId;
if (!sessionId) {
const titleSource =
userText || "File attachment";
const title =
titleSource.length > 60
? titleSource.slice(0, 60) + "..."
: titleSource;
sessionId = await createSession(title);
setCurrentSessionId(sessionId);
sessionIdRef.current = sessionId;
onActiveSessionChange?.(sessionId);
onSessionsChange?.();
if (filePath) {
void fetchFileSessionsRef.current?.().then(
(sessions) => {
setFileSessions(sessions);
},
);
}
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
// Build message with optional attachment prefix
let messageText = userText;
// Merge mention paths and attachment paths
const allFilePaths = [
...mentionedFiles.map((f) => f.path),
...currentAttachments.map((f) => f.path),
];
if (allFilePaths.length > 0) {
const prefix = `[Attached files: ${allFilePaths.join(", ")}]`;
messageText = messageText
? `${prefix}\n\n${messageText}`
: prefix;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
}
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
if (fileContext && isFirstFileMessageRef.current) {
2026-02-13 18:57:15 -08:00
const label = fileContext.isDirectory ? "directory" : "file";
messageText = `[Context: workspace ${label} '${fileContext.path}']\n\n${messageText}`;
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
isFirstFileMessageRef.current = false;
}
2026-02-13 15:52:13 -08:00
2026-02-14 14:07:53 -08:00
// Reset scroll lock so we auto-scroll to the new user message
userScrolledAwayRef.current = false;
void sendMessage({ text: messageText });
},
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
[
attachedFiles,
isStreaming,
currentSessionId,
createSession,
onActiveSessionChange,
onSessionsChange,
filePath,
fileContext,
sendMessage,
],
);
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
// ── Queue flush: send the next queued message once the stream finishes ──
const prevFlushStatusRef = useRef(status);
useEffect(() => {
const wasStreaming =
prevFlushStatusRef.current === "streaming" ||
prevFlushStatusRef.current === "submitted";
const isNowReady = status === "ready";
prevFlushStatusRef.current = status;
if (wasStreaming && isNowReady && queuedMessages.length > 0) {
const [next, ...rest] = queuedMessages;
setQueuedMessages(rest);
// Revoke blob URLs from queued attachments (no longer needed for thumbnails)
for (const f of next.attachedFiles) {
if (f.localUrl) {URL.revokeObjectURL(f.localUrl);}
}
// Use a microtask so React can settle the status update first.
queueMicrotask(() => {
void handleEditorSubmit(next.text, next.mentionedFiles, next.attachedFiles);
});
}
}, [status, queuedMessages, handleEditorSubmit]);
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
const handleSessionSelect = useCallback(
async (sessionId: string) => {
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
if (sessionId === currentSessionId) {
return;
}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
// Stop any active stream/reconnection for the old session.
reconnectAbortRef.current?.abort();
void stop();
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
setLoadingSession(true);
setCurrentSessionId(sessionId);
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
sessionIdRef.current = sessionId;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
onActiveSessionChange?.(sessionId);
savedMessageIdsRef.current.clear();
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
isFirstFileMessageRef.current = false;
setQueuedMessages([]);
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
try {
const response = await fetch(
`/api/web-sessions/${sessionId}`,
);
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
if (!response.ok) {
throw new Error("Failed to load session");
}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
const data = await response.json();
const sessionMessages: Array<{
id: string;
role: "user" | "assistant";
content: string;
parts?: Array<Record<string, unknown>>;
_streaming?: boolean;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
}> = data.messages || [];
const hasStreaming = sessionMessages.some(
(m) => m._streaming,
);
const completedMessages = hasStreaming
? sessionMessages.filter(
(m) => !m._streaming,
)
: sessionMessages;
const uiMessages = completedMessages.map(
(msg) => {
savedMessageIdsRef.current.add(msg.id);
return {
id: msg.id,
role: msg.role,
parts: (msg.parts ?? [
{
type: "text" as const,
text: msg.content,
},
]) as UIMessage["parts"],
};
},
);
setMessages(uiMessages);
// Clear loading state *before* reconnecting — the
// persisted messages are now visible. attemptReconnect
// manages its own `isReconnecting` state which shows
// "Resuming stream..." instead of "Loading session...".
setLoadingSession(false);
// Always try to reconnect -- the stream endpoint
// returns 404 gracefully if no active run exists,
// and this avoids missing runs whose _streaming
// flag hasn't been persisted yet.
await attemptReconnect(sessionId, uiMessages);
} catch (err) {
console.error("Error loading session:", err);
setLoadingSession(false);
}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
},
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
[
currentSessionId,
setMessages,
onActiveSessionChange,
stop,
attemptReconnect,
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
],
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
);
2026-02-15 23:54:05 -08:00
const handleNewSession = useCallback(() => {
reconnectAbortRef.current?.abort();
void stop();
setIsReconnecting(false);
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
setCurrentSessionId(null);
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
sessionIdRef.current = null;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
onActiveSessionChange?.(null);
setMessages([]);
savedMessageIdsRef.current.clear();
isFirstFileMessageRef.current = true;
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
newSessionPendingRef.current = false;
setQueuedMessages([]);
// Focus the chat input after state updates so "New Chat" is ready to type.
requestAnimationFrame(() => {
editorRef.current?.focus();
});
2026-02-15 23:54:05 -08:00
}, [setMessages, onActiveSessionChange, stop]);
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
// Keep the ref in sync so handleEditorSubmit can call it
handleNewSessionRef.current = handleNewSession;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
useImperativeHandle(
ref,
() => ({
loadSession: handleSessionSelect,
newSession: async () => { handleNewSession(); },
sendNewMessage: async (text: string) => {
handleNewSession();
const title =
text.length > 60 ? text.slice(0, 60) + "..." : text;
const sessionId = await createSession(title);
setCurrentSessionId(sessionId);
sessionIdRef.current = sessionId;
onActiveSessionChange?.(sessionId);
onSessionsChange?.();
userScrolledAwayRef.current = false;
void sendMessage({ text });
},
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
insertFileMention: (name: string, path: string) => {
editorRef.current?.insertFileMention(name, path);
},
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
}),
[handleSessionSelect, handleNewSession, createSession, onActiveSessionChange, onSessionsChange, sendMessage],
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
);
// ── Stop handler (aborts server-side run + client-side stream) ──
const handleStop = useCallback(async () => {
2026-02-17 00:36:01 -08:00
// Abort reconnection stream if active (immediate visual feedback).
reconnectAbortRef.current?.abort();
setIsReconnecting(false);
2026-02-17 00:36:01 -08:00
// Stop the server-side agent run and wait for confirmation so the
// session is no longer in "running" state before we stop the
// client-side stream (which may trigger queued message flush).
if (currentSessionId) {
try {
await fetch("/api/chat/stop", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
sessionId: currentSessionId,
}),
});
} catch { /* ignore */ }
}
// Stop the useChat transport stream (transitions status → "ready").
void stop();
}, [currentSessionId, stop]);
// ── Queue handlers ──
const removeQueuedMessage = useCallback((id: string) => {
setQueuedMessages((prev) => prev.filter((m) => m.id !== id));
}, []);
2026-02-19 21:58:10 -08:00
const updateQueuedMessageText = useCallback((id: string, text: string) => {
setQueuedMessages((prev) => prev.map((m) => m.id === id ? { ...m, text } : m));
}, []);
/** Force-send: stop the agent, then immediately submit this queued message. */
const forceSendQueuedMessage = useCallback(
async (id: string) => {
const msg = queuedMessages.find((m) => m.id === id);
if (!msg) {return;}
// Remove it from the queue first.
setQueuedMessages((prev) => prev.filter((m) => m.id !== id));
// Stop the current agent run.
await handleStop();
// Submit the message after a short delay to let status settle.
setTimeout(() => {
void handleEditorSubmit(msg.text, msg.mentionedFiles, msg.attachedFiles);
}, 100);
},
[queuedMessages, handleStop, handleEditorSubmit],
);
2026-02-13 15:52:13 -08:00
// ── Attachment handlers ──
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
const handleFilesSelected = useCallback(
(files: SelectedFile[]) => {
const newFiles: AttachedFile[] = files.map(
(f) => ({
id: `${f.path}-${Date.now()}-${Math.random().toString(36).slice(2)}`,
name: f.name,
path: f.path,
}),
);
setAttachedFiles((prev) => [
...prev,
...newFiles,
]);
2026-02-13 15:52:13 -08:00
},
[],
);
const removeAttachment = useCallback((id: string) => {
setAttachedFiles((prev) => {
const removed = prev.find((f) => f.id === id);
if (removed?.localUrl) {URL.revokeObjectURL(removed.localUrl);}
return prev.filter((f) => f.id !== id);
});
2026-02-13 15:52:13 -08:00
}, []);
const clearAllAttachments = useCallback(() => {
setAttachedFiles((prev) => {
for (const f of prev) {
if (f.localUrl) {URL.revokeObjectURL(f.localUrl);}
}
return [];
});
2026-02-13 15:52:13 -08:00
}, []);
/** Upload native files (e.g. dropped from Finder/Desktop) and attach them.
* Shows files instantly with a local preview, then uploads in the background. */
const uploadAndAttachNativeFiles = useCallback(
(files: FileList) => {
const fileArray = Array.from(files);
// Immediately add placeholder entries with local blob URLs
const placeholders: AttachedFile[] = fileArray.map((file) => ({
id: `pending-${Date.now()}-${Math.random().toString(36).slice(2)}`,
name: file.name,
path: "",
uploading: true,
localUrl: URL.createObjectURL(file),
}));
setAttachedFiles((prev) => [...prev, ...placeholders]);
// Upload each file in the background and update the entry
for (let i = 0; i < fileArray.length; i++) {
const file = fileArray[i];
const placeholderId = placeholders[i].id;
const localUrl = placeholders[i].localUrl;
const form = new FormData();
form.append("file", file);
fetch("/api/workspace/upload", {
method: "POST",
body: form,
})
.then((res) => res.ok ? res.json() : null)
.then((json: { ok?: boolean; path?: string } | null) => {
if (json?.ok && json.path) {
// Replace placeholder with the real uploaded file
setAttachedFiles((prev) =>
prev.map((f) =>
f.id === placeholderId
? { ...f, path: json.path!, uploading: false }
: f,
),
);
} else {
// Upload failed — remove the placeholder
setAttachedFiles((prev) => prev.filter((f) => f.id !== placeholderId));
if (localUrl) {URL.revokeObjectURL(localUrl);}
}
})
.catch(() => {
setAttachedFiles((prev) => prev.filter((f) => f.id !== placeholderId));
if (localUrl) {URL.revokeObjectURL(localUrl);}
});
}
},
[],
);
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
// ── Status label ──
const _statusLabel = loadingSession
2026-02-15 23:54:05 -08:00
? "Loading session..."
: isReconnecting
? "Resuming stream..."
: status === "ready"
? "Ready"
: status === "submitted"
? "Thinking..."
: status === "streaming"
? (hasRunningSubagents ? "Waiting for subagents..." : "Streaming...")
: status === "error"
? "Error"
: status;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
// Show an inline Unicode spinner in the message flow when the AI
// is thinking/streaming but hasn't produced visible text yet.
const lastMsg = messages.length > 0 ? messages[messages.length - 1] : null;
const lastAssistantHasText =
lastMsg?.role === "assistant" &&
lastMsg.parts.some((p) => p.type === "text" && (p as { text: string }).text.length > 0);
const showInlineSpinner = isStreaming && !lastAssistantHasText;
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
// ── Render ──
return (
2026-02-14 14:07:53 -08:00
<div
2026-02-19 21:58:10 -08:00
className="h-full flex flex-col"
style={{ background: "var(--color-main-bg)" }}
2026-02-14 14:07:53 -08:00
>
{/* Header — sticky glass bar */}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
<header
2026-02-19 21:58:10 -08:00
className={`${compact ? "px-3 py-2" : "px-3 py-2 md:px-6 md:py-3"} flex items-center justify-between z-20`}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
style={{
2026-02-14 14:07:53 -08:00
background: "var(--color-bg-glass)",
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
}}
>
<div className="min-w-0 flex-1">
{compact && fileContext ? (
<h2
className="text-xs font-semibold truncate"
style={{
color: "var(--color-text)",
}}
>
Chat: {fileContext.filename}
</h2>
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
) : (
<h2
className="text-sm font-semibold"
style={{
color: "var(--color-text)",
}}
>
{currentSessionId
? (sessionTitle || "Chat Session")
: "New Chat"}
</h2>
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
)}
</div>
2026-02-19 17:46:54 -08:00
<div className="flex items-center gap-1 shrink-0">
{currentSessionId && onDeleteSession && (
2026-02-19 17:46:54 -08:00
<DropdownMenu>
<DropdownMenuTrigger
className="p-1.5 rounded-lg"
style={{ color: "var(--color-text-muted)" }}
title="More options"
aria-label="More options"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<circle cx="12" cy="12" r="1" />
<circle cx="5" cy="12" r="1" />
<circle cx="19" cy="12" r="1" />
</svg>
2026-02-19 17:46:54 -08:00
</DropdownMenuTrigger>
<DropdownMenuContent align="end" side="bottom">
<DropdownMenuItem
variant="destructive"
onSelect={() => onDeleteSession(currentSessionId)}
>
2026-02-19 21:58:10 -08:00
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18" /><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" /><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" /></svg>
2026-02-19 17:46:54 -08:00
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
{compact && (
<button
type="button"
onClick={() => handleNewSession()}
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
className="p-1.5 rounded-lg"
style={{
color: "var(--color-text-muted)",
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
}}
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
title="New chat"
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
>
<svg
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M12 5v14" />
<path d="M5 12h14" />
</svg>
</button>
)}
</div>
</header>
{/* File-scoped session tabs (compact mode) */}
{compact && fileContext && fileSessions.length > 0 && (
<div
2026-02-19 21:58:10 -08:00
className="px-2 py-1.5 border-b flex gap-1 overflow-x-auto z-20"
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
style={{
borderColor: "var(--color-border)",
2026-02-14 14:07:53 -08:00
background: "var(--color-bg-glass)",
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
}}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
>
{fileSessions.slice(0, 10).map((s) => (
<button
key={s.id}
type="button"
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
onClick={() =>
handleSessionSelect(s.id)
}
2026-02-14 14:07:53 -08:00
className="px-2.5 py-1 text-[10px] rounded-full whitespace-nowrap shrink-0 font-medium"
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
style={{
background:
s.id === currentSessionId
? "var(--color-accent)"
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
: "var(--color-surface-hover)",
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
color:
s.id === currentSessionId
? "white"
: "var(--color-text-muted)",
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
border:
s.id === currentSessionId
? "none"
: "1px solid var(--color-border)",
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
}}
>
{s.title.length > 25
? s.title.slice(0, 25) + "..."
: s.title}
</button>
))}
</div>
)}
2026-02-19 21:58:10 -08:00
<div
ref={scrollContainerRef}
className="flex-1 overflow-y-auto min-h-0"
>
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
{/* Messages */}
<div
className={compact ? "px-3" : "px-6"}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
>
{loadingSession ? (
2026-02-14 14:07:53 -08:00
<div className="flex items-center justify-center h-full min-h-[60vh]">
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
<div className="text-center">
<UnicodeSpinner
name="braille"
className="block text-2xl mx-auto mb-3"
style={{ color: "var(--color-text-muted)" }}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
/>
<p
className="text-xs"
style={{
color: "var(--color-text-muted)",
}}
>
Loading session...
</p>
</div>
</div>
) : messages.length === 0 ? (
2026-02-14 14:07:53 -08:00
<div className="flex items-center justify-center h-full min-h-[60vh]">
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
<div className="text-center max-w-md px-4">
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
{compact ? (
<p
className="text-sm"
style={{
color: "var(--color-text-muted)",
}}
>
Ask about this file
</p>
) : (
<>
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
<h3
className="font-instrument text-3xl tracking-tight mb-2"
style={{
color: "var(--color-text)",
}}
>
What can I help with?
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
</h3>
<p
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
className="text-sm leading-relaxed"
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
style={{
color: "var(--color-text-muted)",
}}
>
Send a message to start a
conversation with your
agent.
</p>
</>
)}
</div>
</div>
) : (
<div
2026-02-14 14:07:53 -08:00
className={`${compact ? "" : "max-w-2xl mx-auto"} py-3`}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
>
{rawView ? (
<pre
className="text-xs whitespace-pre-wrap break-all font-mono p-4 rounded-xl"
style={{ color: "var(--color-text)", background: "var(--color-surface-hover)" }}
>
{JSON.stringify(messages, null, 2)}
</pre>
) : messages.map((message, i) => (
2026-02-19 14:59:34 -08:00
<ChatMessage
key={message.id}
message={message}
isStreaming={isStreaming && i === messages.length - 1}
onSubagentClick={onSubagentClick}
2026-02-19 17:46:54 -08:00
onFilePathClick={onFilePathClick}
2026-02-19 14:59:34 -08:00
/>
))}
{showInlineSpinner && (
<div className="py-3 min-w-0">
<UnicodeSpinner
name="pulse"
className="text-base"
style={{ color: "var(--color-text-muted)" }}
/>
</div>
)}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
<div ref={messagesEndRef} />
</div>
)}
</div>
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
{/* Transport-level error display */}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
{error && (
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
<div
2026-02-14 14:07:53 -08:00
className="px-3 py-2 flex items-center gap-2 sticky bottom-[72px] z-10"
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
style={{
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
background: `color-mix(in srgb, var(--color-error) 6%, var(--color-surface))`,
borderColor: `color-mix(in srgb, var(--color-error) 18%, transparent)`,
color: "var(--color-error)",
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
}}
>
<svg
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
2026-02-14 14:07:53 -08:00
className="shrink-0"
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
>
<circle cx="12" cy="12" r="10" />
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
<line
x1="12"
y1="8"
x2="12"
y2="12"
/>
<line
x1="12"
y1="16"
x2="12.01"
y2="16"
/>
Dench workspace: Tiptap markdown editor, subagent sessions, and error surfacing ── Tiptap Markdown Editor ── - Add full Tiptap-based WYSIWYG markdown editor (markdown-editor.tsx, 709 LOC) with bubble menu, auto-save (debounced), image drag-and-drop/paste upload, table editing, task list checkboxes, and frontmatter preservation on save. - Add slash command system (slash-command.tsx, 607 LOC) with "/" trigger for block insertion (headings, lists, tables, code blocks, images, reports) and "@" trigger for file/document mention with fuzzy search across the workspace tree. - Add ReportBlockNode (report-block-node.tsx) — custom Tiptap node that renders embedded report-json blocks as interactive ReportCard widgets inline in the editor, with expand/collapse and edit-JSON support. - Add workspace asset serving API (api/workspace/assets/[...path]/route.ts) to serve images from the workspace with proper MIME types. - Add workspace file upload orkspace/upload/route.ts) for multipart image uploads (10 MB limit, image types only), saving to assets/ directory. - Add ~500 lines of Tiptap editor CSS to globals.css (editor layout, task lists, images, tables, slash command dropdown, bubble menu toolbar, code blocks, etc.). - Add 14 @tiptap/* dependencies to apps/web/package.json (react, starter-kit, markdown, image, link, table, task-list, suggestion, placeholder, etc.). ── Document View: Edit/Read Mode Toggle ── - document-view.tsx: Add edit/read mode toggle; defaults to edit mode when a filePath is available. Lazy-loads MarkdownEditor to keep initial bundle light. - workspace/page.tsx: Pass activePath, tree, onSave, onNavigate, and onRefreshTree through to DocumentView for full editor integration with workspace navigation and tree refresh after saves. ── Subagent Session Isolation ── - agent-runner.ts: Add RunAgentOptions with optional sessionId; when set, spawns the agent with --session-key agent:main:subagent:<id> ant so file-scoped sidebar chats run in isolated sessions independent of the main agent. - route.ts (chat API): Accept sessionId from request body and forward it to runAgent. Resolve workspace file path prefixes (resolveAgentWorkspacePrefix) so tree-relative paths become agent-cwd-relative. - chat-panel.tsx: Create per-instance DefaultChatTransport that injects sessionId via body function and a ref (avoids stale closures). On file change, auto-load the most recent session and its messages. Refresh session tab list after streaming ends. Stop ongoing stream when switching sessions. - register.agent.ts: Add --session-key <key> and --lane <lane> CLI flags. - agent-via-gateway.ts: Wire sessionKey into session resolution and validation for both interactive and --stream-json code paths. - workspace.ts: Add resolveAgentWorkspacePrefix() to map workspace-root-relative paths to repo-root-relative paths for the agent process. ── Error Surfacing ── - agent-runner.ts: Add onAgentError callback extraction helpers (parseAgentErrorMessage, parseErrorBody, parseErrorFromStderr) to surface API-level errors (402 payment, rate limits, etc.) to the UI. Captures stderr for fallback error detection on non-zero exit. - route.ts: Wire onAgentError into the SSE stream as [error]-prefixed text parts. Improve onError and onClose handlers with clearer error messages and exit code reporting. - chat-message.tsx: Detect [error]-prefixed text segments and render them as styled error banners with alert icon instead of plain text. - chat-panel.tsx: Restyle the transport-level error bar with themed colors and an alert icon consistent with in-message error styling.
2026-02-11 20:54:30 -08:00
</svg>
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
<p className="text-xs">{error.message}</p>
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
</div>
)}
2026-02-19 21:58:10 -08:00
</div>
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
2026-02-19 21:58:10 -08:00
{/* Input bar at bottom */}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
<div
2026-02-19 21:58:10 -08:00
className={`${compact ? "px-3 py-2" : "px-3 pb-3 pt-0 md:px-6 md:pb-5"} z-20`}
2026-02-14 14:07:53 -08:00
style={{ background: "var(--color-bg-glass)" }}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
>
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
<div
2026-02-14 14:07:53 -08:00
className={compact ? "" : "max-w-[720px] mx-auto"}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
>
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
<div
2026-02-15 23:42:13 -08:00
data-chat-drop-target=""
2026-02-19 17:46:54 -08:00
className="rounded-3xl overflow-hidden border shadow-[0_0_32px_rgba(0,0,0,0.07)] transition-[outline,box-shadow] duration-150 ease-out data-drag-hover:outline-2 data-drag-hover:outline-dashed data-drag-hover:outline-(--color-accent) data-drag-hover:-outline-offset-2 data-drag-hover:shadow-[0_0_0_4px_color-mix(in_srgb,var(--color-accent)_15%,transparent),0_0_32px_rgba(0,0,0,0.07)]!"
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
style={{
background: "var(--color-surface)",
2026-02-19 17:46:54 -08:00
borderColor: "var(--color-border)",
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
}}
onDragOver={(e) => {
if (
e.dataTransfer?.types.includes("application/x-file-mention") ||
e.dataTransfer?.types.includes("Files")
) {
e.preventDefault();
e.dataTransfer.dropEffect = "copy";
// visual feedback
(e.currentTarget as HTMLElement).setAttribute("data-drag-hover", "");
}
}}
onDragLeave={(e) => {
// Only remove when leaving the container itself (not entering a child)
if (!e.currentTarget.contains(e.relatedTarget as Node)) {
(e.currentTarget as HTMLElement).removeAttribute("data-drag-hover");
}
}}
onDrop={(e) => {
(e.currentTarget as HTMLElement).removeAttribute("data-drag-hover");
// Sidebar file mention drop
const data = e.dataTransfer?.getData("application/x-file-mention");
if (data) {
2026-02-13 19:24:24 -08:00
e.preventDefault();
e.stopPropagation();
try {
const { name, path } = JSON.parse(data) as { name: string; path: string };
if (name && path) {
editorRef.current?.insertFileMention(name, path);
}
} catch {
// ignore malformed data
}
return;
}
// Native file drop (from OS file manager / Desktop)
const files = e.dataTransfer?.files;
if (files && files.length > 0) {
e.preventDefault();
e.stopPropagation();
uploadAndAttachNativeFiles(files);
}
}}
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
>
{/* Queued messages indicator */}
{queuedMessages.length > 0 && (
<div className={compact ? "px-2 pt-2" : "px-3 pt-3"}>
<div
className="rounded-xl border overflow-hidden"
style={{
background: "var(--color-surface)",
borderColor: "var(--color-border)",
boxShadow: "var(--shadow-sm)",
}}
>
<div
className="px-3 py-1.5 text-[10px] font-semibold uppercase tracking-wider"
style={{ color: "var(--color-text-muted)", background: "var(--color-surface-hover)" }}
>
Queue ({queuedMessages.length})
</div>
<div className="flex flex-col p-2">
{queuedMessages.map((msg, idx) => (
2026-02-19 21:58:10 -08:00
<QueueItem
key={msg.id}
2026-02-19 21:58:10 -08:00
msg={msg}
idx={idx}
onEdit={updateQueuedMessageText}
onSendNow={forceSendQueuedMessage}
onRemove={removeQueuedMessage}
/>
))}
</div>
</div>
</div>
)}
{/* Attachment preview strip */}
<AttachmentStrip
files={attachedFiles}
compact={compact}
onRemove={removeAttachment}
onClearAll={
clearAllAttachments
}
/>
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
<ChatEditor
ref={editorRef}
onSubmit={handleEditorSubmit}
onChange={(isEmpty) =>
setEditorEmpty(isEmpty)
}
onNativeFileDrop={uploadAndAttachNativeFiles}
2026-02-13 18:57:15 -08:00
placeholder={
compact && fileContext
? `Ask about ${fileContext.isDirectory ? "this folder" : fileContext.filename}...`
: isStreaming
? "Type to queue a message..."
2026-02-13 18:57:15 -08:00
: attachedFiles.length >
2026-02-13 15:52:13 -08:00
0
? "Add a message or send files..."
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
: "Type @ to mention files..."
2026-02-13 15:52:13 -08:00
}
2026-02-15 23:54:05 -08:00
disabled={loadingSession}
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
compact={compact}
/>
2026-02-13 15:52:13 -08:00
{/* Toolbar row */}
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
<div
className={`flex items-center justify-between ${compact ? "px-2 pb-1.5" : "px-3 pb-2.5"}`}
>
2026-02-13 15:52:13 -08:00
<div className="flex items-center gap-0.5">
<button
type="button"
onClick={() =>
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
setShowFilePicker(
true,
)
2026-02-13 15:52:13 -08:00
}
className="p-1.5 rounded-lg hover:opacity-80 transition-opacity"
style={{
color:
attachedFiles.length >
0
? "var(--color-accent)"
: "var(--color-text-muted)",
}}
title="Attach files"
>
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48" />
</svg>
</button>
</div>
{/* Send / Stop / Queue buttons */}
<div className="flex items-center gap-1.5">
2026-02-19 21:58:10 -08:00
{isStreaming && (
<button
type="button"
onClick={() => handleStop()}
className={`${compact ? "w-6 h-6" : "w-7 h-7"} rounded-full flex items-center justify-center`}
style={{
background: "var(--color-text)",
color: "var(--color-bg)",
}}
title="Stop generating"
>
<svg
width="8"
height="8"
viewBox="0 0 10 10"
fill="currentColor"
>
<rect width="10" height="10" rx="1.5" />
</svg>
</button>
2026-02-19 21:58:10 -08:00
)}
{isStreaming ? (
<button
type="button"
onClick={() => {
editorRef.current?.submit();
}}
disabled={
(editorEmpty &&
attachedFiles.length === 0) ||
loadingSession
}
className="h-7 px-3 rounded-full flex items-center gap-1.5 text-[12px] font-medium disabled:opacity-40 disabled:cursor-not-allowed"
style={{
background:
!editorEmpty || attachedFiles.length > 0
? "var(--color-accent)"
: "var(--color-surface-hover)",
color:
!editorEmpty || attachedFiles.length > 0
? "white"
: "var(--color-text-muted)",
}}
title="Add to queue"
>
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<polyline points="9 10 4 15 9 20" />
<path d="M20 4v7a4 4 0 0 1-4 4H4" />
</svg>
Queue
</button>
) : (
<button
type="button"
onClick={() => {
editorRef.current?.submit();
}}
disabled={
(editorEmpty &&
attachedFiles.length === 0) ||
loadingSession
}
className={`${compact ? "w-6 h-6" : "w-7 h-7"} rounded-full flex items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed`}
style={{
background:
!editorEmpty ||
attachedFiles.length > 0
? "var(--color-accent)"
: "var(--color-text-muted)",
color:
!editorEmpty || attachedFiles.length > 0
? "white"
: "var(--color-bg)",
}}
title="Send message"
2026-02-14 14:07:53 -08:00
>
<svg
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2.5"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M12 19V5" />
<path d="m5 12 7-7 7 7" />
</svg>
</button>
)}
</div>
feat(web): full UI redesign with light/dark theme, TanStack data tables, media rendering, and gateway-routed agent execution 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>
2026-02-12 11:17:23 -08:00
</div>
</div>
</div>
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
</div>
Web app: add syntax highlighting, diff viewer, rich chat editor, and file search Syntax highlighting & code viewer: - Add shiki for syntax-highlighted fenced code blocks in chat messages - New SyntaxBlock component (lazy shiki, dual light/dark theme) - New CodeViewer for workspace file panel (routes code files via isCodeFile()) - API routes (browse-file, virtual-file) now return "code" type for known extensions Diff rendering: - New DiffCard component for rendering unified diffs with add/remove colors - diff-blocks.ts parser to extract fenced blocks from markdown - Chain-of-thought tool steps show inline diffs for edit/write tools (synthetic from old_string/new_string or direct from tool output) - Agent runner passes through diff/firstChangedLine from edit tool results - Document view handles diff blocks alongside report blocks Rich chat editor (Tiptap): - Replace plain textarea with Tiptap-based ChatEditor - File mention extension (@-mention files with autocomplete dropdown) - File mention list with keyboard navigation and search via suggest-files API - New suggest-files API endpoint for fuzzy file search File search & navigation: - FileSearch component in workspace sidebar (debounced search, keyboard nav) - Search results navigate sidebar to file location and open in panel - File picker modal for browsing/selecting workspace files Drag & drop: - File tree nodes support native HTML5 drag (application/x-file-mention) for cross-component drops (e.g. dragging files into chat editor) Chat attachments reworked: - Switch from browser File objects to path-based references (name + path) - Simplified attachment strip (no media previews, shows shortened paths) Also adds software-engineering skill and related CSS for code blocks/shiki.
2026-02-13 18:06:59 -08:00
{/* File picker modal */}
<FilePickerModal
open={showFilePicker}
onClose={() =>
setShowFilePicker(false)
}
onSelect={handleFilesSelected}
/>
2026-02-15 23:42:13 -08:00
Dench workspace: file manager, relation resolution, and chat refactor File Manager & Filesystem Operations: - Add FileManagerTree component with drag-and-drop (dnd-kit), inline rename, right-click context menu, and compact sidebar mode - Add context-menu component (open, new file/folder, rename, duplicate, copy, paste, move, delete) rendered via portal - Add InlineRename component with validation and shake-on-error animation - Add useWorkspaceWatcher hook with SSE live-reload and polling fallback - Add API routes: mkdir, rename, copy, move, watch (SSE file-change events), and DELETE on /api/workspace/file with system-file protection - Add safeResolveNewPath and isSystemFile helpers to workspace lib - Replace inline WorkspaceTreeNode in sidebar with shared FileManagerTree (compact mode), add workspace refresh callback Object Relation Resolution: - Resolve relation fields to human-readable display labels server-side (resolveRelationLabels, resolveDisplayField helpers) - Add reverse relation discovery (findReverseRelations) — surfaces incoming links from other objects - Add display_field column migration (idempotent ALTER TABLE) and PATCH /api/workspace/objects/[name]/display-field endpoint - Enrich object API response with relationLabels, reverseRelations, effectiveDisplayField, and related_object_name per field - Add RelationCell, RelationChip, ReverseRelationCell, LinkIcon components to object-table with clickable cross-object navigation - Add relation label rendering to kanban cards - Extract ObjectView component in workspace page with display-field selector dropdown and relation/reverse-relation badge counts Chat Panel Extraction: - Extract chat logic from page.tsx into standalone ChatPanel component with forwardRef/useImperativeHandle for session control - ChatPanel supports file-scoped sessions (filePath param) and context-aware file chat sidebar - Simplify page.tsx to thin orchestrator delegating to ChatPanel - Add filePath filter to GET /api/web-sessions for scoped session lists Dependencies: - Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities - Add duckdbExec and parseRelationValue to workspace lib Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:22:53 -08:00
</div>
);
},
);