This commit introduces several enhancements across the EntryDetailModal and ObjectTable components. Key changes include the addition of a FormattedFieldValue component for consistent display of various field types, improved handling of entry metadata, and the introduction of input type resolution for fields. Additionally, navigation callbacks for entries have been refined to support better interaction within the object table. These updates aim to streamline data presentation and enhance user experience.
This commit refactors the handling of subagent sessions by removing the enrichSubagentMessages function and integrating its functionality into the GET request handler. It also introduces the enrichSubagentSessionFromTranscript function to enhance session data retrieval. Additionally, the persistSubscribeUserMessage function is updated to ensure user messages are saved to the session JSONL file, improving message persistence across page reloads. These changes enhance the clarity and efficiency of subagent session management.
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
Add ensureAgentInConfig, setDefaultAgentInConfig, and resolveActiveAgentId to manage per-workspace agent entries in openclaw.json so the gateway routes to the correct workspace.
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
YAML-parsed date_between/between filters store range values as a
two-element array under `value`, but the filter system expected
separate value/valueTo fields. Add normalizeFilterGroup at the YAML
read boundary and defensive array handling in the evaluator and SQL
builder so both formats work correctly.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Skip updateIndex for session IDs containing :subagent: so they don't
appear as top-level "New Chat" entries in the sidebar
- Filter subagent IDs in the sidebar component as a safety net
- Clean up existing leaked entries from index.json
Co-authored-by: Cursor <cursoragent@cursor.com>
Subagents now use the same ActiveRun infrastructure as parent sessions:
- startSubscribeRun() creates a subscribe-only ActiveRun when sessions_spawn
tool results are detected, using the same event buffering, persistence,
and SSE reconnection as parent runs
- Stream/stop/chat routes no longer branch on subagent vs parent; both
use getActiveRun/subscribeToRun with the session key as map key
- hasRunningSubagentsForParent moved into active-runs.ts to check the
unified activeRuns map (+ disk registry fallback)
- Deferred finalization on lifecycle/end with 5s safety timeout
- ev.data.text fallback for assistant events without delta field
- 24h cleanup grace for subscribe-only runs (vs 30s for parent)
Reverts the broken childSessionKey registration from 32cfcf14f.
Co-authored-by: Cursor <cursoragent@cursor.com>
The spawn tool result uses `childSessionKey` (not `sessionKey`), and
task/label come from the tool input args, not the result details.
Without this fix registerSubagent was never called because the
extracted sessionKey was always undefined.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Handle ev.data.text fallback when delta is absent in assistant events
(both active-runs and subagent-runs)
- Defer subagent finalizeRun until subscribe process closes so buffered
events in readline are still delivered to SSE subscribers
- Register subagents from sessions_spawn tool results in active-runs so
hasRunningSubagentsForParent works without opening SubagentPanel first
- Add disk registry fallback in hasRunningSubagentsForParent for cases
where in-memory parentIndex has no entries
- Fix pre-commit hook: tolerate oxfmt exit 2 when all files are ignored
Co-authored-by: Cursor <cursoragent@cursor.com>
Bug 1: Subagent events from gateway broadcasts were processed as parent
events because the sessionKey filter was accidentally removed during the
subagent decoupling refactor. Re-add the filter in wireChildProcess.
Bug 2: Creating workspaces at custom paths failed because:
- mkdir API rejected absolute paths outside workspace root
- Directory picker started at workspace root, not home
- Error responses from mkdir were silently swallowed
Add absolute path support to mkdir, handle errors in picker UI,
start picker at home dir, and normalize init route paths.
Restore backend/logic features that were incorrectly auto-merged from the
design branch:
- Spreadsheet viewer (xlsx, csv, ods, etc.) and xlsx dependency
- HTML iframe viewer with source toggle
- Directory picker modal for workspace creation
- Workspace registry for custom-path workspaces
- Session auto-discovery for orphaned sessions
- Workspace init seeding (CRM objects, DuckDB, templates, bootstrap files)
- Symlink resolution and showHidden in tree/browse routes
- Upload to workspace assets/ instead of hidden ~/.ironclaw/uploads/
- Webpack dev watcher config (next.config.ts)
- router.push for back-button navigation history
Subagent event JSONL files and rehydration metadata were stored in the
shared ~/.openclaw/web-chat/ directory regardless of the active workspace
profile, while parent chat sessions were correctly profile-scoped.
Move subagent event persistence into the profile-scoped web-chat dir
(web-chat-<profile>/subagent-events/) and add a profile-local
subagent-index.json for fast rehydration after page refresh. The shared
gateway registry (~/.openclaw/subagents/runs.json) remains the fallback
source. Existing events in the legacy shared path are still readable as
a migration fallback.