Set gateway mode and port before onboarding so the first daemon start succeeds, then reapply them after onboarding so wizard defaults cannot drift DenchClaw off its expected local gateway.
Backend support for multi-session chat: /api/chat/runs endpoint for parent/subagent run status, subagent registry for reading run state, and cascade stop to abort child sessions when stopping a parent.
Darken --color-sidebar-bg to create more visual hierarchy between
the sidebar and main content area, inspired by animclaw's approach.
Light: #f5f5f4 → #ebebea (delta 15 from main-bg, was 5)
Dark: #141413 → #0c0c0b (delta 10 from main-bg, was 2)
- Remove framer-motion animations from hero greeting, input bar, and
suggestion buttons so they render instantly
- Fix SSR hydration mismatch by deferring hero render until client mount
- Always create a "New Chat" tab on fresh load and when closing last tab
Made-with: Cursor
- Add 'sidebar-animate' class to sidebar elements for improved transition effects.
- Change accent color scheme to a green palette for better visual consistency.
- Ensure sidebar animations are disabled during resizing for smoother user experience.
- Replace custom RowActionsMenu and Columns menu with shared DropdownMenu component
- Restyle ViewTypeSwitcher from bordered button group to subtle rounded tabs
- Simplify DataTable toolbar: remove button borders, tighten spacing
- Use rounded-2xl for compact sidebar chat input, keep rounded-3xl for main
Made-with: Cursor
- Simplify sidebar visibility logic by removing unnecessary variables.
- Enhance sidebar width handling with smooth transitions for collapsed states.
- Update chat sidebar to adjust width dynamically based on its open state.
- Refactor component structure for better readability and maintainability.
- Fix session load error by handling 404 gracefully
- Unify sidebar backgrounds to stone-100, make main-bg fully opaque
- Add divider + gap before new tab button, hide when last tab active
- Make tab hover cursor default, new tab button fully rounded
- Remove glass background from chat header
- Replace show/hide output button with clickable step labels
- Fix chat sidebar header to use solid background
- Set min-height on tab bar wrapper for loading state
Made-with: Cursor
- Tab bar uses distinct strip background with curved connectors on active tab
- "+" button creates new chat tabs (like Chrome new tab)
- Markdown links intercepted for in-app navigation and anchor scrolling
- Fix borderColor shorthand conflict in database-viewer spinner
- Align sidebar header height with tab bar
Made-with: Cursor
- Move chat history from left sidebar to floating popover on tab bar
- Add dench-ui components (Button, Card, Input, Label, Switch) with deps
- Glassmorphism styling for all dropdowns/context menus with dark mode
- Chrome-style active tab that merges with content area
- Align sidebar header with tab bar (34px)
- Condense sidebar header to single line
- Move sidebar expand button into tab bar
- Add next-themes for proper dark mode with system preference support
- Add Tailwind v4 class-based dark mode via @custom-variant
- Add dench-ui CSS tokens (light + dark)
- Restore pointer cursor for all interactive elements
- New chat button always visible in tab bar
- "Delete this chat" label in dropdown menu
Made-with: Cursor
During bootstrap, `onboard --install-daemon` starts the gateway daemon
immediately. The gateway's startup guard requires `gateway.mode=local`
but this was only set *after* onboard completed, causing the daemon to
block with "Gateway start blocked: set gateway.mode=local" and enter a
crash loop. The web UI then fails with "Gateway WebSocket connection
failed".
Move `ensureGatewayModeLocal()` and `ensureGatewayPort()` to run before
the onboard command so the config is in place when the daemon first
starts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When denchclaw is launched via `npx`, npm injects environment variables
(most critically `npm_config_prefix`) that redirect `npm install -g` and
`npm ls -g` to a temporary npx-managed prefix instead of the user's real
global npm directory. This causes openclaw to be installed to a location
that doesn't persist on PATH, so subsequent commands like `denchclaw
restart` fail with "openclaw CLI not found".
Strip `npm_config_*`, `npm_package_*`, and npm lifecycle variables from
the environment passed to npm global commands (`npm ls -g`, `npm install
-g`, `npm prefix -g`) so they use the user's actual npm configuration.
parseSimpleYaml only matched `key: value` lines (regex required `.+`
after the colon), so `permissions:` followed by indented `- database`
list items was never parsed. This caused app bridge methods like
db.query to always fail with "Unknown method or insufficient
permissions" even when the app manifest granted the database permission.
Change the regex to `.*` to also match keys with no inline value, then
collect subsequent indented `- item` lines into an array.
Closes#87
- Refactor WebSocket connection logic to dynamically fetch the port from the server, improving flexibility.
- Introduce global variables to manage WebSocket server state and port, allowing for better control and error handling.
- Update terminal drawer component to use the new port fetching mechanism, ensuring consistent connection behavior.
The terminal drawer was flickering closed immediately after opening because
the spawned shell process exited with code 1, triggering handleExited →
closeTerminal → onClose which unmounted the entire drawer within ~500ms.
- Stop auto-closing the drawer on process exit so users can see error output
- Extract URL param building into testable buildWorkspaceSyncParams function
that correctly includes terminal state, preventing param stripping on navigation
- Add 21 tests covering terminal param preservation across navigation scenarios
Without error handling, if node-pty require or pty.spawn throws (bad
permissions, missing cwd, stale server), the client gets no response and
the terminal hangs with a blinking cursor. Now sends an exit event back.
fitAddon.fit() was called synchronously on mount before the browser laid
out the container, sending 0-dimension cols/rows to the PTY. The shell
would hang without displaying a prompt. Now defers WS connection by 50ms,
re-fits after the shell reports ready, and shows an error if WS fails.
xterm.js frontend + node-pty WebSocket server spawning the user's real shell,
with drag-to-resize drawer, multi-terminal tabs, live theme sync, and URL state.
- 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