- Convert sync filesystem and DuckDB operations to async across API routes,
workspace lib, and active-runs to prevent event loop blocking during tree
discovery, object lookups, and database queries
- Add "tags" field type for free-form string arrays with parse-tags utility,
TagsBadges/TagsInput UI components, filter operators, and CRM skill docs
- Preserve rich text formatting (bold, italic, code, @mentions) in user chat
messages by sending HTML alongside plain text through the transport layer
- Detect empty-stream errors, improve agent error emission, and add file
mutation queues for concurrent write safety in active-runs
- Add pre-publish standalone node_modules verification in deploy script
checking serverExternalPackages are present
- Extract syncManagedSkills and discoverWorkspaceDirs for multi-workspace
skill syncing, add ensureSeedAssets for runtime app dir
- Bump version 2.1.1 → 2.1.4
sessions.patch for verboseLevel=full was called before the agent RPC
created the session, so it silently failed on new chats. Tool events
were never emitted and the frontend only showed brief text responses.
Now patches both before (for existing sessions) and after the agent RPC
(for newly created sessions). Also adds SSE keepalive to the POST /api/chat
stream to prevent connection drops during long tool executions, and removes
the unused legacy CLI spawn codepath.
Subagent sessions were missing tool call displays because the gateway's
passive subscribe mode (agent.subscribe unsupported) only broadcasts
assistant + lifecycle events, not tool events.
Three fixes:
- Use start-mode GatewayProcessHandle for subagent follow-up messages
so the agent RPC streams all events (including tools) on the same
WebSocket connection
- Enrich persisted subagent JSONL at load time from the gateway's
on-disk session transcript when tool-invocation parts are missing
- Best-effort enrichment at finalization time from gateway transcript
for subscribe-only runs that didn't receive tool events
BREAKING CHANGE: Convert repository to IronClaw-only package with strict
external dependency on globally installed `openclaw` runtime.
### Changes
- Remove entire OpenClaw core source from repository (src/agents/*, src/acp/*,
src/commands/*, and related modules)
- Implement CLI delegation: non-bootstrap commands now delegate to global
`openclaw` binary via external contract
- Remove local OpenClaw path resolution from web app; always spawn global
`openclaw` binary instead of local scripts
- Rename package.json scripts: `pnpm openclaw` → `pnpm ironclaw`,
`openclaw:rpc` → `ironclaw:rpc`
- Update bootstrap flow to verify and install global OpenClaw when missing
- Migrate web workspace/profile logic to align with OpenClaw state paths
- Add migration contract tests for stream-json, session subscribe, and profile
resolution behaviors
- Update build/release pipeline for IronClaw-only artifacts
- Update documentation for new peer + global installation model
### Architecture
IronClaw is now strictly a frontend/UI/bootstrap layer:
- `npx ironclaw` bootstraps OpenClaw (if missing), runs guided onboarding
- IronClaw UI serves on localhost:3100
- OpenClaw Gateway runs on standard port 18789
- Communication via stable CLI contracts and Gateway WebSocket protocol only
### Migration
Users must have `openclaw` installed globally:
npm install -g openclaw
Existing IronClaw profiles and sessions remain compatible through gateway
protocol stability.
Refs: bootstrap_dev_testing, ironclaw_frontend_split, strict-external-openclaw
Bump version and publish ironclaw@2026.2.10-1.14. Includes chain-of-thought,
chat-message, active-runs, and agent-runner improvements.
Co-authored-by: Cursor <cursoragent@cursor.com>
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.
- Fix spawnAgentProcess path resolution: walk up to find package root
instead of assuming 2 levels up from apps/web (breaks in standalone
where cwd is deep inside .next/standalone/); use openclaw.mjs in
production since scripts/run-node.mjs isn't shipped in the package
- Add missing readline error handlers in active-runs.ts and
agent-runner.ts to prevent "Unhandled 'error' event" crashes when
the child process fails to start
- Pass OPENCLAW_ROOT env var from gateway to standalone server so the
web app can reliably find the CLI entry point
- Add 32 tests covering path resolution, SSE streaming, error handling,
run lifecycle, replay, and abort
Co-authored-by: Cursor <cursoragent@cursor.com>
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>
Rebrand from OpenClaw to Ironclaw across 16 files:
Web app (apps/web):
- layout.tsx: update metadata title to "Ironclaw" and description to
"AI CRM with an agent that connects to your apps and does the work for you"
- page.tsx: change landing page heading from "OpenClaw Dench" to "Ironclaw"
- agent-runner.ts: rename stderr log prefix to [ironclaw stderr]
- package.json: rename package from "openclaw-web" to "ironclaw-web"
Package identity (root):
- package.json: rename package from "openclaw-ai-sdk" to "ironclaw",
update description to reflect CRM/workspace focus, change bin entry
from "openclaw-ai-sdk" to "ironclaw"
- openclaw.mjs: update error message to reference "ironclaw"
- src/version.ts: change CORE_PACKAGE_NAME to "ironclaw"
CLI and TUI:
- command-format.ts: extend CLI prefix regex to accept both "ironclaw"
and "openclaw" for backward compatibility
- register.agent.ts: update example identity name to "Ironclaw" with
🔩 emoji (replacing 🦞)
- tui.ts: rename TUI header from "openclaw tui" to "ironclaw tui"
Onboarding and configuration wizards:
- configure.wizard.ts: rename engine selection prompts and wizard intro
headers to "Ironclaw"
- onboarding.ts: rename onboarding intro and security warning text
- onboarding.finalize.ts: rename all dashboard/control-UI messages and
Brave Search setup instructions to reference "Ironclaw"
Security audit:
- audit.ts: rename state-dir permission warning details to "Ironclaw"
- audit-extra.ts: rename plugin remediation text to "Ironclaw"
Telegram:
- bot-message-context.ts: rename access-denied message to "Ironclaw"
── 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.