feat(desktop): shell overhaul, agent daemon rework, and forensics expansion#77
feat(desktop): shell overhaul, agent daemon rework, and forensics expansion#77
Conversation
…ansion Cherry-picked desktop/agent changes from feat/policy-editor (PR #76) that were not yet on main. Excludes all adapter package refactors. Includes: - Shell: NavRail refactor, ProfileMenu, SessionRail overhaul, DockSystem shelf, hotCommands, plugin registry updates - Forensics: ForensicsRiverView expansion, AgentGlyphOverlay, AgentOrbHud, useAgentCognitionState, ChronicleWorkbenchShelf, PolicyWorkbenchPanel fixes - Agent: daemon.rs rework, notifications, events, crimson/gold icon retheme - Operations: new OperationsHubView - Tests: NavRail, SessionRail, DockSystem, hotCommands, ProfileMenu, ShellApp routing, NexusControlStrip, sessionStore, registry, policyDraftGuard Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: baf05288be
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
apps/agent/src-tauri/src/events.rs
Outdated
| let mut request = self | ||
| .http_client | ||
| .get(&url) | ||
| .query(&[("limit", "50"), ("offset", "0")]); |
There was a problem hiding this comment.
Track audit cursor in polling fallback
The fallback poll now always requests only limit=50, offset=0, so when SSE is down and more than 50 new audit events arrive between polls, older unseen events are never fetched and are permanently dropped from the UI stream; this is a data-loss regression under moderate/high event throughput and should keep a cursor (or paginate) to guarantee continuity.
Useful? React with 👍 / 👎.
| if !external_mode.load(Ordering::SeqCst) { | ||
| if let Some(reason) = check_process_exit(&child).await { |
There was a problem hiding this comment.
Recover from external hushd loss by respawning managed daemon
All restart logic is guarded by !external_mode, so after attaching to an already-running external hushd, if that external process later exits, the monitor only marks the state unhealthy and never attempts to spawn a managed child; this leaves the agent offline until manual intervention instead of self-healing.
Useful? React with 👍 / 👎.
| function asAppId(value: unknown): AppId | null { | ||
| if (typeof value !== "string") return null; | ||
| return KNOWN_APP_IDS.has(value as AppId) ? (value as AppId) : null; |
There was a problem hiding this comment.
Preserve legacy session app IDs when loading localStorage
Session deserialization now rejects any appId not in the new KNOWN_APP_IDS set, so existing persisted sessions from prior versions (for example cyber-nexus, settings, or forensics-river) are dropped during upgrade, causing avoidable user data loss unless those legacy IDs are mapped to current equivalents.
Useful? React with 👍 / 👎.
- events.rs: restore cursor-based pagination in poll fallback so events beyond the latest 50 are not silently dropped when SSE is unavailable - daemon.rs: remove redundant --port/--bind CLI args that duplicate the runtime config file; add recovery path from external_mode when the external hushd becomes unhealthy (fall back to spawning a managed child) - sessionStore.ts: map legacy persisted app IDs (cyber-nexus, settings, forensics, forensics-river, policy-workbench, strikecell) to current equivalents so existing sessions survive upgrades - OpenClawAgentProvider.tsx: guard auto-connect effect with in-flight ref to prevent rapid-fire reconnection loops when connectGateway fails fast Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| history: sortedActions.slice(0, 200), | ||
| } satisfies AgentGlyphState; | ||
| }); | ||
| }, [actions, focusedAgentId, sessionRows]); |
There was a problem hiding this comment.
Side effects inside useMemo corrupt controller state
Medium Severity
The useMemo callback mutates external refs (controllersRef, lastProcessedRunRef) and calls stateful methods like controller.handleEvent() and controller.tick(). React requires useMemo computations to be pure. In React strict mode (development), the component body is double-invoked, causing controllers to receive duplicate events and lastProcessedRunRef to be mutated twice per render cycle. The second invocation sees already-set ref values and takes different code branches, leaving controllers in an inconsistent emotional state. This logic belongs in useEffect or useRef-based manual memoization, not useMemo.
| .await | ||
| .with_context(|| "Failed to parse health response")?; | ||
|
|
||
| Ok(health) |
There was a problem hiding this comment.
health_check method duplicates standalone health_check_with_client function
Low Severity
DaemonManager::health_check was changed from delegating to health_check_with_client to inlining identical logic. The free function health_check_with_client still exists and is used extensively in the health monitor, start, and spawn_and_wait_ready. This duplication means a future bug fix in one copy won't be reflected in the other. The previous one-liner delegation was cleaner and safer.
Additional Locations (1)
| const selectedRows = selectedKeys | ||
| .map((key) => rowByKey.get(key)) | ||
| .filter((row): row is ProbeSessionRow => Boolean(row)); | ||
| const sourceRows = selectedRows.length > 0 ? selectedRows : args.rows.slice(0, 8); |
There was a problem hiding this comment.
Probe fallback uses top-8 but label says top-3
Low Severity
The session dropdown labels the "all" option as "ALL (top 3)", and the live polling path correctly uses sessionRows.slice(0, 3). However, deriveActionsFromProbeRows (the probe fallback path) uses args.rows.slice(0, 8) for "__all__", showing data from up to 8 sessions. Users see more sessions than the label promises when the probe fallback is active.


Summary
Cherry-picked desktop/agent changes from
feat/policy-editor(PR #76) that were not yet on main. Excludes all adapter package refactors to avoid clobbering the currentclawdstrike-claude/clawdstrike-openaipackages.Stats
62 files changed, 6055 insertions, 877 deletions
Test plan
cargo tauri buildinapps/desktop)cargo tauri buildinapps/agent)🤖 Generated with Claude Code
Note
High Risk
Touches core agent daemon lifecycle management (spawn/attach/restart) and substantially rewires the desktop’s primary navigation and forensics telemetry flow, so regressions could affect connectivity, daemon availability, and key UI entrypoints.
Overview
Agent (Tauri/Rust): Reworks
DaemonManagerto attach to an already-runninghushdon the configured port ("external mode"), automatically fall back to spawning a managed child if the external daemon disappears, and write a generatedhushd.runtime.tomlconfig (with legacy policy guard detection that falls back to a default ruleset). Also expandsfind_hushd_binarysearch paths and updates restart/ready logic accordingly.Agent notifications & packaging: Adds
toml+ macOS-onlymac-notification-sys, switches notifications to a branded title + resolved app icon, and uses a macOS-specific notification sender to avoid OS dialogs/attribution issues. Updates tray/menu behavior and Tauri bundle resources/icons configuration.Desktop (React/Tauri): Adds an
OperationsHubViewwith query-param tabs that scopesSettingsViewto connection vs preferences, improves Tauri detection, and adds OpenClaw command fallbacks (env token overrides + CLI probe fallback when agent is unavailable). Major UX rebrand/routing updates fromCyber Nexusto/nexus, enhancesNexusControlStripandNexusAppRail, and heavily expandsForensicsRiverViewinto a Nexus-style station scene with probe/runtime-derived telemetry, agent glyph overlays, and method-unavailable fallbacks.Tests: Adds targeted Vitest coverage for routing (
ShellApp),NexusControlStrip, andOperationsHubView.Written by Cursor Bugbot for commit aaaa541. This will update automatically on new commits. Configure here.