Server-side WebSocket connections should not set Origin (a browser security
concept). The header caused the gateway to treat the web runtime as a browser
client, blocking silent local device pairing after device identity auth was
added.
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.
Add workspace mock to agent-runner tests, skip PostHog pageviews on cron paths to reduce noise, document web-chat storage path in CRM skill, and include cursor plans and build info.
- New src/config/paths.test.ts: 11 tests covering resolveGatewayPort
profile-aware precedence (env > config > profile > global default)
- Extend bootstrap-external.test.ts: 15 new tests for
readExistingGatewayPort (config reading, fallback, edge cases) and
isPersistedPortAcceptable (18789 rejection guard, end-to-end composition)
- Extend web-runtime-command.test.ts: 2 new tests verifying the fallback
returns 19001 when manifest has no lastGatewayPort or is null
- Update test fixtures across all test files to expect port 19001
All 5 critical mutations verified: removing profile check, removing
18789 guard, reverting fallback, changing constant, breaking config
reader -- each caught by at least 2 tests.
- Bump version of denchclaw to 2.0.2 in package.json.
- Add posthog-node and posthog-js dependencies with specified versions.
- Update chokidar dependency in web package.json.
- Modify deploy script to publish an alias package (dench) alongside denchclaw.
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
- 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>