Repository navigation
fix(ui): retain loaded dashboards across navigation - #141130
Conversation
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: blocked before merge. Reviewed September 7, 2026, 11:57 AM ET / 15:57 UTC. ClawSweeper reviewWhat this changesKeeps recently visited dashboards and chats loaded across navigation, preserves widget state and drafts, and suspends hidden-page activity and stale composer callbacks. Merge readiness⛔ Blocked before merge - 1 item remains This remains useful: inspected main and the latest release still replace the outer session page during navigation. No actionable introduced defect was found. The previous screenshot-fetch failure is a reviewer limitation, not an outstanding contributor requirement. Priority: P2 Review scores
Verification
How this fits togetherThe Control UI router turns navigation and Gateway data into session pages containing chat panes and dashboard widgets. Retaining those pages preserves local interactions while presentation controls determine which page can receive input and foreground activity. flowchart TD
A[Navigation] --> B[Session route loader]
C[Gateway and signed-in user] --> D[Shared ownership scope]
D --> B
B --> E[Retained session pages]
D --> E
E --> F[Presented page and active controls]
E --> G[Hidden widgets and preserved drafts]
Before merge
Agent review detailsSecurityNone. PR surfaceSource +296, Tests +763, Docs +15. Total +1074 across 34 files. View PR surface stats
Review metrics
Merge-risk optionsMaintainer options:
Technical reviewBest possible solution: Preserve the existing bounded cache and ownership fences, with the documented update-based composer lifecycle as the explicit plugin compatibility contract. Do we have a high-confidence way to reproduce the issue? Yes: main's outer route gate replaces the session subtree when navigating to Settings, and the supplied real-Gateway scenario directly checks the resulting iframe and local-state loss. This review verified the source path without executing it. Is this the best way to solve the issue? Yes: extending the existing bounded session owner avoids a competing cache, while shared Gateway/user scope and presentation retirement preserve the relevant lifecycle boundaries. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 0e1e605121bf. LabelsLabel justifications:
EvidenceWhat I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (1 earlier review cycle)
|
Keep the existing three-session pane cache mounted while visiting other pages, and restore dashboard/chat presentations without waiting for a background route refresh. Preserve widget state, reading position, and drafts while hidden pages relinquish foreground activity, presence, focus, and commands. Share Gateway/user ownership between mounted views and session loader caches, and keep returning presentations inactive until MCP teardown completes. Verified with 90 focused tests, 15 browser tests including a real isolated Gateway, the changed-file gate, and inspected before/after widget-state proof.
Keep ordinary route DOM stable through loader transitions, suspend hidden transcript observers, retire stale plugin composer callbacks, and reconcile active runs on return. Preserve the loaded page and its local state throughout. Cover the lifecycle boundaries with focused units and browser flows; isolated real Gateway proof and all 49 residual browser cases pass.
9fc37f9 to
97952c8
Compare
|
The screenshot retrieval failure was a reviewer-network limitation. I inspected both original full captures locally before uploading them to the PR: they contain only the isolated synthetic Gateway scenario. The browser assertions also verify iframe identity, note and reading position, chat draft continuity, and a subsequent live widget revision; the follow-up real-Gateway run passes. No production Gateway or private desktop data was used. The CI follow-up keeps retention confined to session routes and repairs hidden transcript observers, active-turn reconciliation, and stale plugin composer callbacks. Fresh independent P0–P2 review of that delta found no actionable defects. Required hosted checks will be green before landing. |
|
Maintainer decision on the composer compatibility note: retain the presentation lifetime boundary. A callback captured before a view is hidden must stay retired so delayed work cannot regain permission to change or submit a draft after navigation. The mounted host and view signal remain alive; current operations arrive through I checked the maintained generated composer in A third-party composer that permanently captures its initial props must adopt the documented update path; arbitrary third-party implementations have not been exercised. That is an accepted compatibility tradeoff, not a reason to revive retired operations. Exact-head CI run 34140306399 is green, and the post-rebase full build plus all 15 final navigation/live-Gateway tests passed. |
|
Merged via squash.
|
* fix(ui): retain loaded dashboards across navigation Keep the existing three-session pane cache mounted while visiting other pages, and restore dashboard/chat presentations without waiting for a background route refresh. Preserve widget state, reading position, and drafts while hidden pages relinquish foreground activity, presence, focus, and commands. Share Gateway/user ownership between mounted views and session loader caches, and keep returning presentations inactive until MCP teardown completes. Verified with 90 focused tests, 15 browser tests including a real isolated Gateway, the changed-file gate, and inspected before/after widget-state proof. * fix(ui): preserve route and plugin lifecycles with retained pages Keep ordinary route DOM stable through loader transitions, suspend hidden transcript observers, retire stale plugin composer callbacks, and reconcile active runs on return. Preserve the loaded page and its local state throughout. Cover the lifecycle boundaries with focused units and browser flows; isolated real Gateway proof and all 49 residual browser cases pass.
What Problem This Solves
Fixes an issue where users switching between a loaded dashboard and chat would wait for routing, and visiting Settings would discard the dashboard's iframe, reading position, and local widget state.
Why This Change Was Made
Keep the existing three-session-per-pane cache connected across navigation, preserve each session's chat/dashboard presentation, and display usable cached routes during background refresh. Hidden pages relinquish foreground activity, viewer presence, focus, commands, and transcript observers. Composer callbacks captured before a page is hidden cannot revive when it returns; mounted plugin views keep their local state. Ordinary routes retain their existing loader and DOM lifecycle. Mounted views and session loaders share a Gateway/user scope, and returning pages stay inactive until any pending MCP teardown finishes.
User Impact
Recently visited tasks and dashboards reopen with their widget state, reading position, and chat drafts intact, including after a Settings visit. The existing cache limit remains unchanged; older views can be evicted, and changing Gateway or signed-in user clears retained views.
Evidence
node scripts/check-changed.mjspassed.97952c84f5777fe55935a234f651a7e647ec92f4, including the requiredopenclaw/ci-gate.Synthetic live proof after returning from Settings: before, the reading note and article position reset; after, both are retained.