- Debug panel now probes both legacy (/api/status, /api/health) and current
OpenClaw routes (/healthz, /health, /ready) with automatic fallback.
Returns probedPath in response so admins know which route succeeded.
- POST proxy allowlist updated to include current gateway health routes.
- Path validation relaxed from /api/ prefix to / prefix (health routes
don't use /api/).
- Dockerfile: chmod 755 entrypoint (was +x/711, shell needs read permission)
and chmod -R a+rX on public/ and src/ for nextjs user access.
- make /api/spawn compatible with gateway-managed default models
- add regression coverage for gateway dashboard registration
- publish official multi-arch images to Docker Hub when configured
* fix(docker): move pids to service-level pids_limit and copy public assets
- Move `pids: 256` from `deploy.resources.limits` to service-level
`pids_limit` for Docker Compose v5+ compatibility (#322)
- Add `COPY --from=build /app/public ./public` to Dockerfile runtime
stage so static assets (logos, icons) are available at runtime (#323)
Closes#322, closes#323
* test: add Docker config validation tests
Verifies pids_limit is at service level (Compose v5+), public dir
is copied in Dockerfile, and all required COPY instructions exist.
Eliminate friction for new users by adding a web-based setup wizard,
auto-generating infrastructure secrets, and providing actionable
feedback when no admin account exists.
- Add /setup page with visual progress steps for admin account creation
- Add /api/setup route (GET: check status, POST: create admin + auto-login)
- Auto-generate AUTH_SECRET and API_KEY when not set (persisted to .data/)
- Add docker-entrypoint.sh for zero-config Docker startup
- Login page auto-redirects to /setup when no users exist
- Login API returns NO_USERS error code with setup guidance
- Remove insecure defaults from .env.example
- Update README Quick Start for zero-config Docker and web setup
- Add CLAUDE.md for AI agent discoverability
* fix: preserve gateway token query in websocket URLs
* fix: classify secure-context device identity handshake errors
* fix: normalize trailing dot in host allowlist checks
* fix: support proxied gateway websocket paths and tailnet host normalization
* fix: auto-connect startup to primary configured gateway
* fix: keep gateway tokens server-side only
* fix: allow authenticated viewers to resolve gateway connect credentials
* fix: identify mission control as operator gateway client
* fix: redirect remote http sessions to https for gateway auth
* fix: support URL-style gateway hosts in health probes
* fix: resolve primary gateway credentials from detected openclaw runtime
* fix: hide duplicate gateway connection summary when managed
* refactor: remove super admin and workspaces panels from UI navigation
* fix: treat configured gateways as full-mode capability
* refactor: move promo banner copy into subtle footer note
* fix: stabilize gateway websocket connect protocol detection
* test: cover https forwarded proto for gateway websocket url
* fix: load canonical agent files and memory in detail panel
* fix: resolve agent files from openclaw workspace conventions
* fix: persist websocket client across route remounts
* feat: allow deleting agents with optional workspace removal
* feat: refresh mission control branding and favicon assets
* feat: complete github parity sync implementation
* chore: remove e2e temp artifacts from repo
* feat: add embedded /chat panel with shared chat workspace
* feat: unify sessions navigation into chat panel
* feat: show local Claude/Codex sessions in chat list
* feat: enable local session continuation and chat tagging
* fix: correct local codex session recency detection
* fix: refresh local session age and anchor chat composer
* refactor: make chat provider-session-first by mode
* fix: add local provider and MC health rows in overview
* feat: finalize tenant-scoped workspaces and full e2e coverage
* feat: improve session workbench controls and smoke coverage
* refactor: extract SaaS code to separate pro repo
- Add registerAuthResolver() hook to auth.ts
- Add registerMigrations() hook to migrations.ts
- Remove saas config block, SaaS modules, Pro API routes
- Keep adapters, super-admin routes, migration 032
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add framework adapters and self-update mechanism
- Framework adapter layer for multi-agent registration (autogen, crewai, langgraph, claude-sdk, openclaw, generic)
- Self-update API endpoint (admin-only git pull + install + build)
- Update banner UI component showing available versions with dismiss
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: update README stats, remove stale Super Admin refs, improve self-update
- Panel count 28→32, API routes 66→95, migrations 21→30
- Remove Super Admin from UI-facing docs (APIs remain)
- Document framework adapters and self-update mechanism
- Mark workspace isolation, adapters, projects as completed in roadmap
- Self-update now uses tag-based checkout instead of branch pull
- Plugin hook comments: "Pro" → "extensions"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add skills hub with registry integration, bidirectional sync, and local agent discovery
- Bidirectional disk↔DB skill sync via scheduler (60s interval, SHA-256 change detection, disk-wins conflict resolution)
- ClawdHub + skills.sh registry proxy with search, install, and security scanning (9 rules: prompt injection, credential leaks, data exfiltration, obfuscated content)
- Local agent discovery from ~/.agents/, ~/.codex/agents/, ~/.claude/agents/ with bidirectional sync
- DB-backed skills API with filesystem fallback, admin-only install, rate limiting
- Skills panel: installed/registry tabs, security badges, friendly source labels, OpenClaw gateway support
- Agent panel: local sync button, source badges (local/gateway)
- Migrations 033 (skills table) and 034 (agents source/hash/workspace columns)
- Full test coverage: 24 unit tests, 34 E2E tests (286 total suite green)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add per-agent rate limiting and agent self-registration
- Per-agent rate limiter keyed on x-agent-name header (falls back to IP)
- Agent heartbeat: 30 req/min per agent, task polling: 20 req/min per agent
- Rate limit response headers (Retry-After, X-RateLimit-*) for agent backoff
- POST /api/agents/register: self-service registration with viewer-level auth
- Idempotent registration (re-registering updates last_seen, returns existing)
- Name validation, role whitelist, capabilities/framework in config
- Self-registration rate-limited to 5/min per IP
- 9 E2E tests for self-registration (295 total suite green)
- README: updated API route count (97), test counts, new endpoints
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: enhance agent cost panel, OAuth approval UI, and framework adapter gateway
- Agent Cost Panel: add task cost attribution drill-down, cost share
percentages, bar chart comparison, 5th summary card for task-attributed
costs, 30s auto-refresh, and tabbed expanded view (tasks/models)
- OAuth Approval UI: replace window.prompt() with inline role selector
and note input, add avatar display, show animated pending count badge,
add dedicated "awaiting approval" state on login page
- Framework Adapter Gateway: wire GenericAdapter.getAssignments() to
query task queue, add POST /api/adapters route for framework-agnostic
agent actions (register, heartbeat, report, assignments, disconnect)
- Clean up dead api-keys import and DB-backed key resolution from
auth.ts (moved to Pro repo)
- Resolve README merge conflicts, update route count to 98
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: complete free-tier functionality — adapters, workspace CRUD, agent sync, and UI polish
- Implement all 5 framework adapter stubs (claude-sdk, crewai, langgraph, autogen, openclaw)
with shared queryPendingAssignments() helper to eliminate SQL duplication
- Add recurring gateway_agent_sync scheduler task (was startup-only)
- Add workspace CRUD API: POST/PUT/DELETE /api/workspaces with tenant isolation
- Add local agent discovery for flat .md files (Claude Code agent format with YAML frontmatter)
- Add per-agent cost breakdown API (GET /api/tokens/by-agent)
- Add API key rotation endpoint (GET/POST /api/tokens/rotate)
- Add Google OAuth disconnect endpoint
- Polish login page with inline Google Sign-In button
- Enhance settings panel with Security tab (API key management, OAuth)
- Enhance agent cost panel with per-agent DB view
- Add Awesome OpenClaw as third skill registry source
- Add integration connectivity test fallback
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: include session-message component (required by chat-workspace)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: gateway dot color should reflect live connection state
When WebSocket is connected, show green dot regardless of stored
probe status. Prevents misleading red dot + green CONNECTED badge.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: agent creation progress modal and openclaw CLI flag
- Remove invalid --name flag from openclaw agents add CLI invocation
- Add multi-step progress UI to CreateAgentModal showing DB insert,
gateway write, and workspace provisioning steps with animated status
- Progress view replaces review content during creation with spinner,
checkmark, and error states per step
- Auto-close on success after 1.5s, retry/close buttons on error
- Squad panel: add status-based card edge colors and glow styles
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: task dispatch — scheduler polls assigned tasks and runs agents via openclaw CLI
Adds a task_dispatch scheduler job that picks up tasks in 'assigned' status,
executes them via `openclaw agent --local --json`, and moves them to 'review'
with the agent's response as resolution + comment.
* feat: link dispatched tasks to agent sessions — view session from task detail
- task-dispatch: extract sessionId from openclaw JSON response, store in task metadata
- task detail modal: "View Session" button navigates to /chat with the agent's session transcript
- shows pulsing "Live" indicator when task is in_progress
- agent squad panel: show quality_review and done counts in task stats
* feat: automated Aegis quality review — scheduler polls review tasks and approves/rejects
- aegis_review scheduler job picks up tasks in 'review' status every 60s
- runs openclaw agent to evaluate task resolution quality
- approved → done, rejected → in_progress with feedback as comment
- quality-review API: rejected reviews now push task back to in_progress
- approved reviews work for any reviewer (not just aegis)
* feat: natural language recurring tasks + Claude Code task bridge
Add NL schedule parser (zero deps) for creating recurring tasks via
"every morning at 9am" style input. Template-clone pattern spawns dated
child tasks on cron schedule with Aegis quality gates per instance.
Read-only bridge surfaces Claude Code team tasks and configs from
~/.claude/tasks/ and ~/.claude/teams/ on the MC dashboard.
New files: schedule-parser.ts, recurring-tasks.ts, claude-tasks.ts,
API routes for /claude-tasks and /schedule-parse.
Modified: scheduler.ts (recurring_task_spawn), migrations.ts (036),
task-board-panel.tsx (schedule UI + badges + CC section),
cron-management-panel.tsx (CC teams section).
* docs: update README with recurring tasks and Claude Code task bridge
Add sections for natural language recurring tasks, Claude Code task
bridge, new API endpoints, architecture tree entries, and roadmap items.
* fix: agent card redesign, gateway badge tooltip, and ws:// for localhost gateways
- Compact agent cards: remove 4 colored stat boxes, show inline task stats,
display model name from config, remove session info box, remove Busy button
- Gateway ConnectionBadge: rich hover tooltip with host, latency, WS/SSE status
- Fix gateway connect over Tailscale/HTTPS: use ws:// for localhost gateway
hosts since they have no TLS (browsers allow mixed content for localhost)
- Extract agent-card-helpers.ts with formatModelName, buildTaskStatParts,
extractWsHost for testability
- Add 16 tests for agent card helpers, update 12 gateway-url tests
- Sanitize test fixtures to remove personal Tailscale hostnames
* fix: gateway auto-connect via Tailscale Serve and informative mode badge
- Detect Tailscale Serve mode from OpenClaw config and build
wss://<dashboard-host>/gw URL for remote browser connections
- Replace static mode badge with ModeBadge showing live WS status,
latency, and rich hover tooltip (host, WS/SSE, retries)
- Fall back to host rewrite for non-Tailscale remote access
* feat: discover OS-level gateways and show in Gateway Manager
- Add GET /api/gateways/discover — scans /home/*/.openclaw/openclaw.json
for gateway configs and checks if they're listening (via ss)
- Show discovered gateways in Gateway Manager with user, port, bind mode,
active status, and Tailscale mode badge
- One-click Register button to add discovered gateways to the DB
- Refine Tailscale Serve detection in connect route with config caching
* fix: GitHub sync panel loading hang and gateway discovery via systemd
- GitHub panel: use Promise.allSettled + AbortSignal.timeout(8000) to
prevent indefinite loading spinner when any API call hangs
- Show helpful "not configured" notice when GITHUB_TOKEN is missing
- Always render Sync History and Linked Tasks sections with empty states
- Gateway discover: rewrite to use systemctl + ss for port detection
instead of reading other users' config files (permission-denied)
- Gateway panel: filter discovered gateways that are already registered
* feat: complete audit trail action type coverage with grouped filters
Add labels, colors, and icons for 22 new action types (agents, workspaces,
system, config, auth). Replace flat filter dropdown with optgroup categories.
Extend formatDetail() for settings, backups, heartbeats, cleanup, and export.
* refactor: consolidate spawn into task board and editable sub-agent config
- Move spawn form into collapsible section in task board header
- Make sub-agent config editable in agent detail ConfigTab
- Remove /spawn as standalone page and nav item
- Use violet color for sub-agents to distinguish from agents (blue)
* refactor: remove agent comms panel from agents page
* refactor: redesign agent detail modal — minimal header, compact overview, model selector
- Compact modal header with inline status badge and underline tabs
- Delete actions moved to hover dropdown (trash icon)
- Overview tab: two-column layout with key fields + message panel
- Added model selector to agent overview (editable, saved via PUT /api/agents)
- Status controls as compact pill buttons instead of bulky cards
- Heartbeat shown as inline compact bar instead of full card
- Task stats as horizontal row instead of grid
* feat: add memory knowledge graph visualization for gateway mode
Add interactive ReactFlow-based node graph showing OpenClaw per-agent
memory topology. New /api/memory/graph endpoint reads SQLite memory
databases and returns chunk/file statistics per agent. Graph tab in
Memory Browser (gateway mode only) shows agent hub nodes sized by
chunk count with drill-down to file-level views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: update README for spawn consolidation, modal redesign, test count
* fix: harden agent-comms session threads and runtime tool visibility
* refactor: remove orphaned agent-spawn-panel after spawn/task unification
Spawn functionality now lives inline in task-board-panel and sub-agent
config is in agent-detail-tabs. This file had no imports anywhere.
* fix: exclude /brand/ assets from auth middleware matcher
The login page logo was broken because requests to /brand/mc-logo-128.png
were intercepted by the auth gate and redirected to /login.
* fix: redesign cron calendar — aggregate by job, add detail table
Calendar was broken: each cron occurrence was rendered individually,
causing 135+ jobs * N daily runs = thousands of entries per day cell
(all showing 00:00). Now:
- Week/month cells show unique jobs per day with run counts
- Agent color coding for visual distinction
- Human-readable frequency labels (every 5m, hourly at :00, etc.)
- Selected day panel shows job summaries not raw occurrences
- Agenda view capped at 500 entries (was unlimited)
- Job list replaced with compact sortable table
- Job detail panel redesigned: config, command, timing, logs in 2-col
* fix: clean agent payload in task comments, deduplicate sidebar Agents
Comments:
- Display-side: parse OpenClaw JSON payloads, extract text, strip ANSI
codes, show model/tokens/duration as compact badge
- API-side: normalize agent result JSON on ingestion — store clean text
with optional metadata footer instead of raw payload dump
Sidebar:
- Move Agent Costs and Memory as children under core Agents item
- Remove duplicate "Agents" group from Observe section
* fix: make Agents nav item clickable + split parent/chevron, move Memory standalone
- Clicking "Agents" label navigates to agents page and auto-expands children
- Chevron is a separate toggle button for expand/collapse
- Active indicator shown when on agents page
- Memory moved to standalone item below Skills in core nav
- Agent Costs remains as child under Agents
* refactor: move Office panel to Observe nav category
* feat: Obsidian-style memory graph + browser panel redesign
- Replace React Flow with d3-force canvas renderer for memory graph
- Force-directed physics: node repulsion, link attraction, organic settling
- Canvas rendering for 500+ node performance at 60fps
- Drag/pin nodes, hover highlighting, zoom/pan, search glow
- Redesign memory browser panel with Obsidian-inspired layout:
- Slim 240px collapsible sidebar file tree
- Top bar with Files/Graph view switcher
- Dense mono-font file items with text-char icons
- Graph view as default landing
- Improved markdown renderer with code block support
- Add d3-force dependency
* fix: memory panel sidebar scroll overflow + graph canvas blank on mount
- Add min-h-0 to sidebar flex container so file tree scrolls within bounds
- Guard ResizeObserver callback against 0×0 dimensions to prevent invisible canvas
- Add requestAnimationFrame re-measure to catch post-paint layout
- Set minHeight floor on canvas container to prevent flex collapse
- Propagate flex height through page → panel → graph component chain
* fix: memory panel viewport height — use calc(100vh) instead of h-full
h-full doesn't resolve in a scrollable parent. Use explicit viewport
calc matching the pattern from chat-page-panel.
* fix: memory panel overflow — add overflow-hidden to prevent page scroll
* fix: agent detail crash when model is object instead of string
React error #31 — agent.model can be { primary: "..." } object,
not a string. Handle both shapes in the display fallback.
* fix: agent squad panel crash on unknown agent status
statusCardStyles only covered offline/idle/busy/error but agents can
have other statuses (active, online). Fall back to default style.
* fix: handle double-nested model.primary in agent config
The testdev agent had config.model.primary stored as an object
{ primary: "anthropic/..." } instead of a plain string. Defend
against this at all render and initialization sites.
* test: add E2E tests for onboarding, security-scan, diagnostics, and injection guard endpoints
- onboarding-api.spec.ts: 11 tests covering GET/POST auth, step completion, skip, reset, full lifecycle
- security-scan-api.spec.ts: 5 tests covering auth, response shape, score range, categories
- diagnostics-api.spec.ts: 7 tests covering auth, all response sections and field types
- injection-guard-endpoints.spec.ts: 7 tests verifying 422 blocking on workflows, spawn, agent message, chat forward
- auth-guards.spec.ts: added 3 new endpoints to protected GET list
* feat: phases 1-8 — Docker hardening, diagnostics, installer, skills, security, onboarding, injection guard
- Docker: hardened compose override, non-root user, read-only fs, health checks
- Diagnostics API: system info, security checks, database stats, gateway probe
- Installer: interactive install.sh, generate-env.sh, station-doctor.sh
- Skills: mission-control-installer and mission-control-manage OpenClaw skills
- Security: proxy hardening (HSTS, CSP, host allowlist), cookie improvements,
security-scan API with 5 categories, security-audit.sh script
- Onboarding: wizard UI components, onboarding API with step tracking
- Injection guard: prompt/command injection scanning on workflows, spawn,
agent messages, and chat forwarding endpoints (42 unit tests)
- Status API: enhanced with agent/session/gateway diagnostics
- Settings: onboarding integration in settings panel
- Docs: security hardening guide, landing page handoff, hardening guide
* fix: remove duplicate GW badges and optimize header for smaller screens
- Remove ConnectionBadge and MobileConnectionDot (ModeBadge covers all sizes)
- Lower stats breakpoint from 2xl to xl (visible at ≥1280px)
- Move DigitalClock into stats group
- Remove redundant Chat button (accessible from sidebar)
* feat: agent-optimized onboarding wizard with live capability detection
Rewrite wizard step content for human + agent dual audience:
- Welcome: live status chips (sessions, gateway, agents), mode-adaptive capability cards
- Credentials: explain impact on both dashboard access and agent self-registration
- Agent Setup: comprehensive feature explainer with descriptions per mode
- Security: agent-security framing with category tags before auto-scan
- Get Started: highlighted primary CTA, detailed feature descriptions, self-register tip
Add SystemCapabilities fetch on mount (parallel /api/status + /api/agents).
Show step titles below progress dots. Rename API step titles.
* feat: Google Workspace integration + TUI-style agent comms feed
Add Google Workspace CLI as a productivity integration with gws binary
detection. Rewrite agent-comms-panel to a TUI-style feed with
FeedCategory taxonomy (chat/tools/trace/system/safety) matching the
OpenClaw CLI. Extract inline loading spinners into shared Loader
component. Add autoScan and copy-fix to security scan card. Bump to
v2.0.0.
* fix: cross-codebase audit — SSRF hardening, race conditions, spawn security, memory leaks
- Expand SSRF blocklist with IPv4 CIDR matching for private ranges (10/8, 172.16/12, 192.168/16, 169.254/16, 127/8) while allowlisting user-configured gateway hosts
- Add 1MB file size limit on agent workspace file reads to prevent OOM
- Reorder agent config write-back: DB first (transactional), then gateway file
- Wrap gateway health DB updates in a single transaction
- Add 60s TTL to Tailscale Serve detection cache
- Expand injection guard to scan spawn label field
- Narrow spawn compatibility fallback to only retry on tools/profile schema errors
- Add audit logging for spawn operations
- Cap WebSocket ping timestamp map at 10 entries to prevent memory leak
- Apply rate limiting to GET /api/spawn history endpoint
* fix: cap unbounded store arrays, add fetch cleanup, add missing rate limits
- Cap spawnRequests (500), notifications (500), tokenUsage (2000) in Zustand store to prevent memory leaks in long-running browser sessions
- Add cancellation flag to sidebar fetch to prevent state updates after unmount
- Add error handling to notifications panel markRead/markAllRead operations
- Add missing mutationLimiter to PUT/DELETE /api/workflows endpoints
* fix: multi-tenancy isolation — scope search, export, SSE, webhooks, agent files
- Scope search endpoint: messages and webhooks filtered by workspace_id, audit search restricted to admin role, pipelines filtered by workspace_id
- Scope export endpoint: pipeline_runs export filtered by workspace_id, audit export annotated as intentionally instance-global (admin-only)
- Filter SSE events by workspace_id to prevent cross-workspace data leakage
- Add SSRF blocklist to webhook URL validation (private IPs, localhost, cloud metadata)
- Add 1MB file size limit to agent workspace file writes
* fix: auth timing attack, session revocation, validation bounds, cleanup scoping
- Prevent timing-based username enumeration by always running verifyPassword
against a dummy hash when user not found or ineligible
- Revoke all sessions on password change and issue fresh session cookie
- Add loginLimiter rate limiting to Google OAuth POST endpoint
- Tighten Zod schemas: bound timestamps, cap arrays at 50, limit string
items, constrain numeric fields (hours, timeout, template_id)
- Scope cleanup retention deletes by workspace_id (activities, notifications,
pipeline_runs); audit_log remains instance-global by design
- Clamp config retention values to [0, 3650] days and gateway port to
[1, 65535] with NaN fallback to defaults
* feat: plugin capabilities system + Hyperbrowser integration
- Add plugin registry (src/lib/plugins.ts) with registries for
integrations, categories, nav items, panels, and tool providers
- Add Hyperbrowser as built-in integration with API key test handler
- Wire plugin hooks into integrations route, content router, nav rail,
and agent template tool groups
- Add plugin loader stub and example plugin file
* feat: Ars Contexta-inspired memory knowledge system
Add wiki-link connections, schema enforcement, processing pipeline,
MOC generation, health diagnostics, and context injection to the
memory subsystem. Includes 4 new API routes (/api/memory/links,
/health, /context, /process), a shared utility library, enhanced
memory browser panel with graph/health/pipeline views, 15 unit
tests, and 14 E2E tests.
* feat: composable dashboard widgets, new panels, boot sequence loader
Refactor monolithic dashboard into composable widget grid with 10
extracted widgets (metric cards, task flow, event stream, gateway
health, etc.). Add channels, debug, exec-approval, and nodes panels
with corresponding API routes. Improve boot loader with stepped
init sequence. Enhance token dashboard, websocket reconnect, and
message bubble rendering.
* feat: security audit panel, agent eval framework, optimization endpoint
- Add security event logging (auth failures, rate limits, injection attempts, secret exposures)
- Add secret scanner with regex patterns for AWS keys, GitHub tokens, Stripe keys, JWTs, private keys, DB URIs
- Add MCP call auditing with tool-use frequency and success/failure tracking
- Add agent trust scoring with weighted recalculation
- Add four-layer agent eval stack (output, trace, component, drift detection)
- Add agent optimization engine (token efficiency, tool patterns, fleet benchmarks)
- Add hook profiles (minimal/standard/strict) for security strictness control
- Add security audit panel with posture gauge, timeline, trust scores, MCP audit charts
- Add API endpoints: /api/security-audit, /api/agents/optimize, /api/agents/evals
- Wire security events into auth, rate-limit, injection-guard, agent messages
- Add 3 DB migrations (security_events, agent_trust_scores, mcp_call_log, eval tables, session costs)
- Add unit tests (60 tests) and e2e tests for all new endpoints
* docs: update README and security hardening guide for security audit, evals, optimization
- Update panel count (32), API route count (101), migration count (39), test count (282)
- Add security audit panel, agent eval framework, optimization endpoint to features list
- Add architecture tree entries for new libraries
- Add Security & Evals API reference section
- Add feature descriptions for security audit, eval framework, agent optimization
- Update SECURITY-HARDENING.md with security event system, hook profiles, eval framework docs
- Renumber hardening sections to accommodate new content
* docs: add onboarding wizard to README features and API reference
* feat: OpenClaw auto-update detection with version banner
Add /api/openclaw/version endpoint that checks installed OpenClaw version
against latest GitHub release, with 1-hour ISR cache. Cyan-themed banner
displays when an update is available, with copy-to-clipboard for the
update command and per-version dismiss persistence via localStorage.
* fix: add dark class to SSR html element to prevent white login flash
The html element was rendered without any class in SSR, causing the
:root (white) CSS variables to apply until client-side scripts added
the dark class. Setting className="dark" as the server default ensures
dark theme renders immediately. The FOUC script and next-themes will
adjust for light theme users on hydration.
* fix: login button stays disabled with browser autofill
Browser autofill populates input values without firing React onChange,
so the controlled state stays empty and the disabled check fails.
Remove the username/password emptiness check from disabled — HTML
required attributes already prevent empty submission.
* fix: login fails with browser autofill due to empty React state
When browser autofills credentials, React onChange never fires so state
stays empty. Read actual DOM input values on form submit as fallback.
* fix: login redirect fails due to router.push race with cookie
Replace router.push('/') + router.refresh() with window.location.href
to force a full page reload after login. The soft navigation could
race with the RSC payload cache, causing /api/auth/me to fire before
the session cookie was available.
* fix: CSP nonce blocks inline scripts, breaking theme and login
The CSP had both 'unsafe-inline' and a nonce in script-src. Per the
CSP spec, browsers ignore 'unsafe-inline' when a nonce is present.
Since no scripts actually use the nonce attribute, all inline scripts
(FOUC prevention, next-themes) were blocked — causing white flash
and broken client-side behavior. Remove the unused nonce so
'unsafe-inline' is respected.
* feat: OpenClaw update-now button triggers server-side update
Add POST /api/openclaw/update endpoint that runs `openclaw update
--channel stable` with 5-minute timeout, audit logs the version
change, and returns the new version. Banner now shows Update Now
button with updating/success/error states alongside the existing
Copy Command and View Release actions.
* feat: security scan auto-fix, gateway session chat, boot loader improvements
- Add POST /api/security-scan/fix endpoint with per-issue and fix-all support
- Accepts optional { ids: ["check_id"] } to fix specific issues
- Handles env permissions, host allowlist, HSTS, cookies, API key,
OpenClaw config (auth, bind, elevated, DM, exec), world-writable files
- Audit logs all fixes
- Add "Fix All Issues" button and per-check "Fix" buttons to security scan card
- Auto-re-scans after fixes complete
- Add GET /api/sessions/transcript/gateway for fetching gateway session messages
- Proxies to OpenClaw gateway HTTP API with format normalization
- Enable chat input for gateway sessions (forwards via chat messages API)
- Move boot loader state to Zustand store (bootComplete) so it only shows
after login, not on every panel navigation
- Add sessionKey and agent fields to Conversation session metadata
* feat: add OpenClaw security hardening checks to security scan
New checks aligned with `openclaw security audit`:
- Control UI device auth (dangerouslyDisableDeviceAuth)
- Control UI insecure auth (allowInsecureAuth)
- Filesystem workspace isolation (tools.fs.workspaceOnly)
- Dangerous tool groups deny list
- Log redaction (logging.redactSensitive)
- Agent sandbox mode (agents.defaults.sandbox.mode)
- Safe bins interpreter profiling
Auto-fix support for control_ui_device_auth, control_ui_insecure_auth,
fs_workspace_only, and log_redaction.
* fix: read gateway session transcripts from JSONL files on disk
The gateway doesn't expose an HTTP API for session messages.
OpenClaw stores transcripts as JSONL files at:
{STATE_DIR}/agents/{agent}/sessions/{sessionId}.jsonl
Rewrote the endpoint to:
1. Extract agent name from session key
2. Look up sessionId from agent's sessions.json
3. Read and parse the JSONL transcript file directly
4. Extract type:"message" entries with Claude API content format
* feat: merge agent costs and token dashboard into unified Cost Tracker panel
- New CostTrackerPanel with 4 tabs: Overview, Agents, Sessions, Tasks
- Combines data from both /api/tokens and /api/tokens/by-agent endpoints
- Flat sidebar entry under OBSERVE (replaces Tokens), no dropdown
- Old routes (tokens, agent-costs) still resolve to new panel
- Removed agent-costs child from Agents nav item
* fix: use correct openclaw CLI command for agent deletion
`openclaw agents remove` doesn't exist — the correct command is
`openclaw agents delete <id> --force`.
* fix: click-based delete dropdown and progress loaders for agent CRUD
Replace CSS group-hover dropdown with click toggle + click-outside
listener so the delete menu stays open. Add spinner loaders for
save and delete operations.
* fix: channels auth, chat send, task UX, skills defaults, memory graph
- Channels: add Bearer token auth headers to gateway API calls
- Chat: add missing `from` field in gateway session message send
- Tasks: remove setLoading(true) on refresh to prevent full-page skeleton
- Skills: pre-select openclaw source when in gateway mode
- Memory graph: add delayed resize retries for flex layout settling
- Memory graph API: drop SUM(LENGTH(text)) for faster query (17 DBs)
* fix: memory graph auto-fit to view and faster API query
- Add fitToView() that computes bounding box and auto-zooms to fit
all nodes after 60 simulation ticks
- Drop SUM(LENGTH(text)) from graph API for faster queries across
17 SQLite databases (523 MB total)
- Add delayed resize retries for flex layout settling
* fix: resolve security audit crash and sidebar scroll jump
- Transform authEvents object to array before rendering to prevent
.map() crash on security audit panel
- Remove pathname from boot effect deps to prevent sidebar scroll
reset on panel navigation
* fix: always merge session-derived token data instead of fallback-only
The token data pipeline treated gateway session data as a last-resort
fallback, only used when both DB and JSON file were empty. Stale e2e
test records in the JSON file prevented real session data from ever
appearing. Now all three sources (DB, file, sessions) are always merged
and deduplicated.
* refactor: merge Activity Feed and Agent History into unified Activity panel
Consolidates two panels that shared the same /api/activities data source.
The merged panel shows a flat feed when "All" is selected and switches
to a day-grouped timeline with agent sidebar when a specific agent is
picked. Removes the History nav entry and AgentHistoryPanel import.
* fix: agent comms feed stream, clickable session/agent chips, target selector
- Add agent_% pattern to comms SQL predicate so chat messages appear in feed
- Make SessionChip and agent bar chips clickable to select message target
- Replace hardcoded "Admin -> Coordinator" label with dismissible target chip
- Route messages to selected target with correct conversation_id and sessionKey
* fix: gateway dispatch, inline session feed, and header z-index
- Switch task dispatch and Aegis reviews from `openclaw agent` CLI to
gateway two-step pattern (call agent → agent.wait) matching the
proven chat route invocation path
- Include previous Aegis rejection feedback in re-dispatch prompts
- Add tags to task dispatch prompts
- Replace navigate-away "View Session" button with inline Session tab
in task detail modal, with auto-refresh, live indicator, and
SessionMessage rendering
- Fix header z-index so theme dropdown renders above page content
* fix: normalize all security audit API fields to match frontend types
Transform agentTrust, secretAlerts, toolAudit, rateLimits,
injectionAttempts, and timeline from nested API objects into the flat
arrays the UI components expect, preventing .map() crashes.
* feat: animated OpenClaw + Claude converging logos on loading screen
Replace static PNG logo with inline SVG OpenClaw and Claude marks that
animate inward from opposite sides, converging at center with a glow
burst. Includes prefers-reduced-motion support.
* feat: onboarding wizard shows both modes with mode-themed colors
- Add modeColors() helper returning amber (local) or cyan (gateway) classes
- StepWelcome: two side-by-side mode cards with active/inactive styling
- StepGateway: both feature columns always visible, inactive dimmed + locked
- All steps: progress bar, dots, and buttons themed to detected mode
- Thread isGateway prop to StepCredentials and StepSecurity
- Remove unused CapabilityCard and FeatureItem components
* fix: channels panel gateway status, response transform, and boot improvements
- Transform gateway's rich channel data model into flat ChannelAccount[] the frontend expects
- Fall back to /api/health check when /api/channels/status fails, avoiding false "disconnected"
- Use Zustand WebSocket connection state as fallback for gateway status in channels panel
- Show context-aware empty state messages (connected vs disconnected)
- Preload workspace data (agents, sessions, projects) during boot sequence
- Add anti-self-XSS console warning on boot
- Forward explicit sessionKey in chat message dispatch
* fix: move useMissionControl hook before early returns in channels panel
Hook was called after conditional returns (loading/error), violating
Rules of Hooks and causing React error #310.
* fix: loading screen uses real OpenClaw logo, converge→MC mark animation
- Replace placeholder talon SVG with actual OpenClaw favicon (green gradient claw)
- Add MissionControlMark SVG (network graph matching app icon)
- Animation: OpenClaw + Claude converge → pair fades out → MC mark emerges
- Progress steps fade in after logo animation, completed steps collapse away
- Add reduced-motion fallback for new animations
* fix: use real OpenClaw lobster logo and MC brand mark on loading screen
- Replace SVG approximations with actual brand assets (img tags)
- OpenClaw: lobster character from x.com/openclaw profile
- Mission Control: network graph mark from /brand/mc-logo-128.png
- Animation: OpenClaw + Claude converge → fade out → MC mark emerges
* feat: aggregate all gateway session transcripts into agent-feed
Add /api/sessions/transcript/aggregate endpoint that fans out to all
active session JSONL files on disk and returns a merged chronological
event stream. Agent-comms panel now merges transcript events as a third
data source alongside WS logs and DB comms, with deduplication and
category classification (tools, trace, chat, system).
Extract shared JSONL parsing logic into src/lib/transcript-parser.ts
to avoid duplication between gateway and aggregate routes.
* fix: replace collapsing step list with single active label on loading screen
Eliminates layout shifts by replacing the collapsing step list with a
fixed-height single active step label that crossfades between steps.
Progress section now appears at 2.4s delay to let the brand mark land.
* feat: agent-feed send error details, memory activity events, chat height cap
- Parse injection (422) and auth (403) errors from chat send endpoint
with specific user-facing messages instead of generic "Failed to send"
- Log memory file save/create/delete operations to activities table
- Support comma-separated type filter on activities endpoint (IN query)
- Poll memory activity events at 30s cadence and merge into agent-feed
- Cap feed stream container at max-h-[500px] with existing scroll
* feat: replace memory graph Canvas 2D + d3-force with reagraph WebGL
- Rewrite memory-graph.tsx to use reagraph GraphCanvas with Obsidian-style
dark theme (glow effects, connected-node highlighting, force-directed layout)
- Fix parent layout overflow-auto → overflow-hidden to prevent height collapse
- Add next/dynamic SSR-safe import for WebGL/Three.js compatibility
- Remove d3-force dependency, add reagraph
* fix: use infrastructure scan for security audit posture score
The security audit page scored ~95 based only on event history (no
incidents = high score). Now it runs the full infrastructure scan
(credentials, network, OpenClaw, runtime, OS) and blends it 70/30
with event history, matching what the onboarding security scan shows.
- Extract scan logic to shared src/lib/security-scan.ts
- Simplify /api/security-scan route to use shared lib
- Add scan data + expandable categories to security audit panel
- Blended score: 70% infrastructure config, 30% event history
* fix: add worker-src CSP directive and persist panel data across tab switches
Add worker-src 'self' blob: to CSP so reagraph WebGL force layout workers
are not blocked. Move agents, skills, and memory graph data from component
local state into zustand store so data survives tab switches without refetch.
* fix: add worker-src to proxy middleware CSP (mirrors next.config.js)
The middleware in proxy.ts was overwriting the next.config.js CSP header
without the worker-src directive, blocking reagraph blob: workers.
* fix: add blob: to script-src CSP for worker importScripts
worker-src allows worker creation but importScripts() inside workers
falls back to script-src, which also needs blob: for reagraph's
workerize-transferable chain.
* fix: allow cdn.jsdelivr.net in connect-src for reagraph font loading
troika-three-text (used by reagraph for WebGL text) fetches unicode font
resolver data from cdn.jsdelivr.net at runtime.
* feat: obsidian-style memory graph with hover tooltips and breadcrumb nav
- Full-bleed graph canvas with Catppuccin Mocha color palette
- Floating glass-morphism overlays: breadcrumb nav, stats, legend
- Hover tooltip shows file path, chunk count, and text size
- Click hub to drill in, click breadcrumb or hub again to go back
- Color legend for file categories (sessions, memory, knowledge, etc.)
* fix: auto-fit memory graph into view after layout settles
Calls fitNodesInView at 800ms and 2000ms after nodes change to ensure
the graph is visible without needing a manual zoom.
* feat: prefetch memory graph and skills data on app boot
Add memory graph and skills API fetches to the existing Promise.all
block so data is warm before the user navigates to those panels.
* feat: rewrite onboarding copy with mothership/docking narrative
Reframe all 6 onboarding steps to use consistent station/docking
metaphor: Mission Control is the mothership, agents dock here to
gain capabilities. Replaces generic SaaS copy with agent-centric
language (docking credentials, solo/fleet station, skills hangar).
Copy-only changes — no structural, layout, or API changes.
* feat: add essential/full interface mode toggle
- Add interfaceMode to store (essential | full)
- Filter nav-rail items by essential flag in essential mode
- Persist preference via general.interface_mode setting
- Add toggle button to sidebar footer and settings panel
- Redirect to overview if current panel hidden when switching
- Add changelog toggle to openclaw update banner
* fix: scope comms panel auto-scroll to its own container
scrollIntoView was bubbling up to the page-level <main>, causing the
overview page to scroll to the bottom on load. Use scrollTo on the
feed container ref instead.
* refactor: replace ad-hoc spinners with shared Loader component
Standardize loading states across 12 panel files to use the shared
Loader component (panel variant for full-panel states, inline variant
for section-level states) instead of individual animate-spin spinners.
* refactor: move interface mode toggle into user dropdown menu
Remove standalone toggle button from sidebar footer and integrate it
as a segmented control inside the ContextSwitcher dropdown. Add
Settings and Activity quick-nav links to the dropdown.
* feat: add gateway state backup via `openclaw backup create`
Add ?target=gateway variant to POST /api/backup that runs
`openclaw backup create` (60s timeout) and logs an openclaw.backup
audit event. The existing MC SQLite backup remains the default.
Surface both backup actions in Settings panel under a new Backups
row so admins can trigger either backup type with one click.
* refactor: use shared Loader in log viewer panel
Replace ad-hoc spinner with the shared Loader component,
consistent with the rest of the codebase.
* fix: write gateway backup to MC backup dir to avoid path conflict
openclaw backup create writes archives to CWD by default, which is
the state dir — causing a "must not be written inside a source path"
error. Use --output to write to the MC backup directory instead.
* fix: handle openclaw backup non-zero exit with successful output
openclaw backup create may exit non-zero in some environments even
when the archive is successfully created. Check for "Created" in
the combined output before treating it as a failure.
* feat: add global exec approval overlay modal + refactor panel
- Add fixed overlay modal (ExecApprovalOverlay) that shows pending
exec approvals regardless of active panel, matching OpenClaw
reference UI pattern
- Decisions sent via WebSocket RPC (exec.approval.resolve) with
HTTP fallback
- Handle both exec.approval and exec.approval.requested/resolved
event variants for gateway compatibility
- Refactor ExecApprovalPanel to read from Zustand store (populated
by WebSocket) instead of its own HTTP polling loop
- Add cwd, host, resolvedPath fields to ExecApprovalRequest type
* feat: streamline onboarding wizard to 3 steps + add persistent checklist
- Reduce wizard from 6 steps to 3 (welcome, interface mode, credentials)
- Remove agent setup, security scan, and next steps from blocking modal
- Add "Station Online" completion animation with endowed progress bar
- Add persistent onboarding checklist widget to dashboard (6 items, 3 pre-checked)
- Checklist auto-detects completion from store data and auto-dismisses
- Add "Replay Onboarding" button in settings panel
- Improve empty states in agent, cost tracker, and task board panels
* feat: enhance security scanner with severity scoring, new checks, and agent endpoint
- Add CheckSeverity and FixSafety types with severity-weighted scoring
- Add ~20 new platform-specific checks (Linux, macOS, Windows hardening)
- Add cachedExec and tryExecBatch helpers for batching OS checks
- Consolidate auth_pass_set/auth_pass_strong into single auth_pass ID
- Add POST /api/security-scan/agent endpoint with scan/fix/scan-and-fix
actions, fix scope control, dry-run mode, and structured response
- Add fixSafety field to fix route responses
- Add 10 new secret patterns (Slack/Discord webhooks, OpenAI, Anthropic,
Twilio, SendGrid, Mailgun, GCP, Azure, SSH key content)
- Add 3 new injection guard rules (SSRF, template injection, SQL injection)
- Show severity badges and fix safety warnings in onboarding and audit UI
- Sort failing checks by severity in audit panel
- Add tests for new fields, patterns, injection rules, and agent endpoint
* feat: close OpenClaw UI gap analysis — schema config, channels, chat, devices, sessions, cron, usage, agents, exec approval, websocket, logs
Phase 1 (Critical):
- Config editor: schema-driven form with typed fields, section sidebar, search, hot-apply, hash concurrency
- Channels: per-platform cards (WhatsApp QR, Telegram bot, Discord guilds, Slack workspace, Nostr profile editor)
- Chat: file attachments (picker/drag-drop/paste), abort generation, focus mode, scroll indicator, RTL detection, compaction/fallback toasts
- Devices: approve/reject pending pairing, token rotation/revocation with confirmation
- WebSocket: event sequence tracking with gap detection, caps negotiation, 1.7x backoff (15s cap), protocol error codes
Phase 2 (Important):
- Usage dashboard: filter chips, client-side CSV export, cache tokens, timezone selector, cost-by-provider chart
- Sessions: thinking/verbose/reasoning level controls, editable labels, deletion, time window filtering
- Agents: 5 new tabs (files browser+editor, tools allow/deny, channels, cron, model fallback chain)
- Cron: clone job, force/due run modes, run history browser, schedule/enabled filters, field validation, stagger
- Exec approval: per-agent command allowlist editor with glob pattern matching preview
Phase 3 (Nice-to-have):
- Log viewer: export .log/JSON, buffer truncation indicator, log file path display
* test: add unit + E2E tests for gap analysis features
Unit tests (vitest, 132 new tests):
- websocket-utils: error codes, backoff calculation, sequence gaps (23 tests)
- config-schema-utils: schema normalization, field type inference, tags (29 tests)
- chat-utils: RTL detection, attachment validation, file size formatting (18 tests)
- cron-utils: schedule description, expression validation, clone names (26 tests)
- token-utils: provider detection, CSV generation, timezone offsets (17 tests)
- exec-approval-utils: glob pattern matching, multi-pattern search (19 tests)
E2E tests (playwright, 53 new tests):
- gateway-config: GET/PUT config, schema, hash concurrency, auth (5 tests)
- channels-api: list, probe, action validation, auth (4 tests)
- device-management: nodes, approve/reject/rotate/revoke validation (11 tests)
- session-controls: thinking/verbose/reasoning/label/delete, auth (12 tests)
- cron-operations: list, clone, trigger modes, history, auth (13 tests)
- exec-approval-allowlist: CRUD, round-trip, hash concurrency, auth (8 tests)
Refactor: extracted pure logic into standalone utility modules for testability
* feat: integrate Hermes task/cron system and memory into MC observability
- Add read-only cron job scanner (hermes-tasks.ts) with 30s throttled cache
- Add read-only memory scanner (hermes-memory.ts) for MEMORY.md/USER.md
- Add /api/hermes/tasks and /api/hermes/memory API routes
- Enrich /api/hermes GET with cronJobCount and memoryEntries
- Add HermesCronSection to task board (collapsible, purple accent)
- Add Hermes memory tab to memory browser with capacity bars
- Add cron/memory stat badges to settings panel Hermes section
- Enrich dashboard Hermes card subtitle with cron count
* feat: add Hermes observability, branded loader, and conversation UX improvements
* feat: register MC as default dashboard and add gateway onboarding step
Auto-writes gateway.controlUi.dashboardUrl and allowedOrigins to
openclaw.json on capabilities check. Adds a dynamic "Gateway Link"
step to the onboarding wizard when a gateway is detected.
* fix: disable device auth when registering MC as dashboard
MC authenticates via gateway token — device pairing is unnecessary
and causes "pairing required" WebSocket errors. Auto-set
dangerouslyDisableDeviceAuth when writing dashboardUrl.
* fix: remove invalid dashboardUrl write that crashes gateway
The gateway validates its config strictly — unknown keys like
`dashboardUrl` cause startup failures. registerMcAsDashboard() now
only manages valid keys: allowedOrigins and dangerouslyDisableDeviceAuth.
Updated onboarding wizard text to reflect origin registration
instead of dashboard URL configuration.
* fix: auto-detect Tailscale Serve /gw route instead of relying on gateway config
The previous approach read gateway.tailscale.mode from openclaw.json, but
setting mode to "off" (to stop gateway from auto-managing routes) also broke
MC's WebSocket URL resolution. Now checks `tailscale serve status --json`
directly for a /gw handler, with the config check as a legacy fallback.
* fix: retry gateway websocket without stale device identity
* feat: use real codex and hermes session logos
* feat: update hermes session logo
* fix: make standalone deploys include static assets
* fix: wait for standalone server and bind explicit host
* fix: harden nextjs image and typed client boundaries
* refactor: reduce nextjs image and jsx lint debt
* refactor: fix react compiler and channels typing
* fix(refactor): onboarding/walkthrough hardening (#272)
* docs(plan): add onboarding walkthrough hardening plan
* fix(onboarding): harden wizard step flow and keyboard navigation
feat(loader): use real brand logo assets for Claude/OpenClaw/Codex/Hermes
* fix(onboarding): harden API state transitions and reset semantics
* test(onboarding): align e2e API spec with current step model
* test(e2e): isolate openclaw harness gateway port and fail fast on startup errors (#273)
* fix: restore agent key auth and actor attribution regressions
* fix: replay onboarding once per fresh browser session
* Add support section with donation links to README
Added a section to encourage support for the project, including donation links.
* fix: restore memory panel and onboarding scanner
* fix: accept gateway config hash in validation schema
* fix: refine onboarding overlay and boot loader
* fix: harden gateway config updates and nav latency
* fix: add openclaw doctor warning and fix banner
* fix: fallback to openclaw cli for channel status
* fix: align channels and chat with gateway rpc
* fix: speed memory tree and scroll doctor details
* fix: clarify security scan autofix results
* fix: correct runtime data directory resolution
* fix: isolate deploy builds from runtime sqlite
* fix: migrate sqlite data with backup
* fix: trust dynamic self hostnames in proxy
* fix: preserve active hosts in security autofix
* fix: pin mission control node runtime
* fix: make doctor warnings template-safe
* fix: isolate build database overrides
* fix: scope doctor warnings to active state dir
* fix: auto-resolve doctor session drift
* fix: harden standalone deploy restart
* fix: detect standalone listener on jarv
* fix: preserve e2e env after security autofix
* fix: scope onboarding to users and sessions
* docs: clarify node 22 support
* fix: load hermes local session transcripts
* fix: fully remove deleted agents from openclaw state
* fix: normalize openclaw model config writes
* fix: isolate e2e runtime state
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- package.json: dev and start scripts now use ${PORT:-3000}
- Dockerfile: healthcheck uses ${PORT:-3000}, ENV PORT=3000 as default
- docker-compose.yml: passes PORT env to container, maps MC_PORT to PORT
- .env.example: documents PORT variable
Set PORT=<number> to change the listening port. Defaults to 3000.
Previously dev used Next.js default (3000) and start hardcoded 3005.
- Fix deps stage: copy only package.json + pnpm-lock.yaml* for proper
layer caching instead of COPY . . which invalidates cache on any change
- Copy node_modules from deps into build stage separately from source
- Copy schema.sql into runtime stage (migration 001_init reads it at
runtime via process.cwd(), but standalone output omits source files)
- Remove broken public* glob COPY (no public/ dir exists; Docker COPY
fails silently with incorrect glob syntax)
- docker-compose: add container_name, configurable port via MC_PORT,
mark .env as optional to avoid startup failure if missing
Fixes#129
Bug 1 (#78): Dockerfile HEALTHCHECK curled authenticated /api/status,
always got 401 in production. Changed to /login which is public.
Bug 2 (#78): Login hangs on HTTP deployments because secure=true cookie
is silently rejected. Now auto-detects protocol from x-forwarded-proto
header, only sets secure when request actually came over HTTPS.
Bug 3 (#78): Agent model field from OpenClaw 2026.3.x is {primary: "name"}
object instead of string, causing React error #31. Added normalizeModel()
helper and applied it in all WebSocket/session mapping code paths.
Security hardening:
- Fix timing-safe comparison bugs in webhooks.ts and auth.ts (was comparing buffer with itself)
- Harden rate limiter IP extraction — use rightmost untrusted IP from XFF chain with MC_TRUSTED_PROXIES support
- Add 12-char minimum password validation in Zod schema and runtime check
- Add Zod validation on PUT /api/tasks bulk status update
Webhook retry system (completing in-progress feature):
- Exponential backoff with circuit breaker in webhooks.ts
- POST /api/webhooks/retry endpoint for manual retry
- GET /api/webhooks/verify-docs endpoint for signature verification docs
- Scheduler integration for automatic retry processing
- Unit tests for signature verification and backoff logic
Local Claude Code session tracking:
- New claude-sessions.ts scanner parses JSONL transcripts from ~/.claude/projects/
- Extracts model, tokens, messages, cost estimates, active status per session
- Migration 020 adds claude_sessions table
- GET/POST /api/claude/sessions endpoint with filtering and aggregate stats
- Scheduler runs scan every 60s with MC_CLAUDE_HOME config
Quality improvements:
- Replace all console.error/warn with structured logger across 31 API routes
- Add Docker HEALTHCHECK directive
- Add vitest coverage config with v8 provider (60% threshold)
- Update README with new features, API docs, env vars, and roadmap items
- Fix E2E tests for password length and rate limiter IP changes
Fix WebSocket reconnect storm (issue #53) caused by stale closure
reading connection.reconnectAttempts from Zustand state. Use a ref
to track attempts, avoiding the closure capture problem entirely.
Improve Dockerfile: create .data directory with correct ownership for
SQLite, set PORT/HOSTNAME env vars explicitly.
Add deployment guide documenting Ubuntu prerequisites (python3, make,
g++ for better-sqlite3 native compilation) and platform-specific
build constraints.
- Sanitize session ID in control route to prevent command injection
via unsanitized URL params interpolated into shell commands
- Add mutationLimiter and structured logging to session control endpoint
- Install python3/make/g++ in Dockerfile deps stage for better-sqlite3
native addon compilation
- Handle missing public/ directory in Docker COPY with glob pattern
- Guard pino-pretty transport against missing devDependency at runtime