Rebuild Nodes page as cross-platform Instances page#407
Conversation
Replaces NodesPage (959 LOC, Windows-paired-only) with a single presence-driven InstancesPage modelled on macOS InstancesSettings: one card per gateway entity (gateway + Mac/iPhone/iPad/Android beacons + paired Windows nodes). All NodesPage management surface (capabilities, commands, PATH, Rename, Forget) is preserved inline on paired Windows rows. Operator/node pairing relocated to ConnectionPage. - Add OpenClaw.Shared.InstanceMerger: pure presence x node-list merge with conservative two-pass matching (strong DeviceId/InstanceId before weak host fallback), dedup, stable sort. 45 unit tests. - Add InstancesPage with Fluent card layout: 4px state stripe, role pills, identity caption, icon-row metadata, hover affordance, refresh ProgressRing. - Add InstanceManagementControls helper for inline node management; reuses existing NodesPage_* resource keys so translations carry over. - Add localized InstancesPage_TimeAgo_* keys across all 5 locales. - Delete NodesPage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
shanselman
left a comment
There was a problem hiding this comment.
Thanks for the big cleanup here. The current-master merge validates locally for me (.\build.ps1, Shared tests, Tray tests), and I agree the GitHub test failure appears to be the existing flaky CanvasEval_ReturnsResultOrWellFormedError timeout rather than something specific to this branch.
I don't think this is safe to merge yet because the new Instances merge can still attach destructive node management actions from a weak identity match.
TryWeakMatch(...) matches a presence row to a node using only unique host ↔ DisplayName. Once that happens, BuildFromPresence(...) stores the GatewayNodeInfo on the row, MergedInstance.IsManaged returns Node != null, and InstancesPage renders InstanceManagementControls.BuildManagementBody(...), including Rename and Forget. That means a presence row matched only by display name/host can expose destructive actions for a paired Windows node. The comment above TryStrongMatch says "Only this kind of match should attach Rename/Forget to a presence row", but the implementation and HostFallback_Matches_When_BothSides_Unique test currently allow weak matches to be managed.
Please track match strength and gate the management surface separately from Node != null. Strong ID matches (DeviceId/InstanceId to NodeId/ClientId) and orphan node rows are okay to manage. Weak host/display-name matches should either be presence-only plus a separate manageable node row, or use node data only for non-destructive enrichment while suppressing Rename/Forget.
One more user-visible regression to fix: legacy ShowHub("nodes")/deep-link paths load InstancesPage, but NavigateTo("nodes") calls FindAndSelectNavItem("nodes") before aliasing, and the nav item is now tagged instances. The page opens through the fallback path with no selected nav item. Normalize nodes to instances before FindAndSelectNavItem(...) runs, and add a small regression test if possible.
The pairing approval move to Connection looks otherwise wired correctly: LastNodePairList/LastDevicePairList are replayed in InitializeCurrentPage, and the old nodes page type references appear cleaned up.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
shanselman
left a comment
There was a problem hiding this comment.
Maintainer-side follow-up e2e1cf0 addresses the requested blockers: weak host/display-name matches now keep node data for enrichment but do not enable management actions, orphan/strong ID-matched rows remain manageable, and legacy
odes\ navigation is normalized before nav selection so the Instances nav item highlights correctly.\n\nValidated locally in \D:\github\moltbot-windows-hub.pr407-review: .\build.ps1; Shared tests 1620/1648 with 28 skipped; Tray tests 1211/1211.
Replaces
NodesPage(959 LOC, Windows-paired-only) with a single presence-drivenInstancesPagemodelled on macOSInstancesSettings. One card per gateway entity: the gateway itself, Mac / iPhone / iPad / Android beacons, and paired Windows nodes. All NodesPage management (capabilities, commands, PATH, Rename, Forget) is preserved inline on paired Windows rows. Operator / node pairing relocates to the Connection page.New
OpenClaw.Shared.InstanceMerger— pure presence × node-list merge. Conservative two-pass matching (strongDeviceId/InstanceIdbefore weak host fallback), dedup, stable sort. 45 unit tests.InstancesPage— Fluent card layout: 4px state stripe (Active / Idle / Inactive / Disconnected / Gateway), role pills, identity caption, icon-row metadata, hover affordance, refreshProgressRing.InstanceManagementControls— inline management body for paired Windows rows; reuses existingNodesPage_*resource keys so translations carry over.InstancesPage_TimeAgo_*keys across all 5 locales.Gone
NodesPage(959 LOC).Validation
./build.ps1clean (Shared / Cli / WinNodeCli / WinUI)OpenClaw.Shared.Tests1620 passed (+45 new)OpenClaw.Tray.Tests1210 passedNotes
NodePairingCard+UpdatePairingRequests) was added knowing another contributor is also editing this file — expect a small merge.95cfcfband may need a rebase onto currentmaster.