Skip to content

refactor(tray): extract CommandCenterStateBuilder from App.xaml.cs#297

Merged
shanselman merged 1 commit into
openclaw:masterfrom
AlexAlves87:refactor/extract-state-builder
May 12, 2026
Merged

refactor(tray): extract CommandCenterStateBuilder from App.xaml.cs#297
shanselman merged 1 commit into
openclaw:masterfrom
AlexAlves87:refactor/extract-state-builder

Conversation

@AlexAlves87
Copy link
Copy Markdown
Contributor

@AlexAlves87 AlexAlves87 commented May 8, 2026

Context

App.xaml.cs currently handles a range of distinct responsibilities: gateway event
routing, tray menu construction, window lifecycle, diagnostics state assembly, update
management, and SSH tunnel orchestration, alongside its role as the WinUI 3 Application
entry point.

This PR is the first in a series of small, incremental extractions that move cohesive
groups of logic into dedicated classes, one at a time. Each extraction leaves a thin
delegation call in App and does not alter observable behavior: same events, same order,
same threading, same side effects.

If this direction fits the repository criteria, it would allow App.xaml.cs to
progressively move toward its natural role in WinUI: serving primarily as an entry point
and composition root, rather than directly embedding additional responsibilities. The
extraction is designed incrementally with a criterion of observable behavioral equivalence.

App will continue to exist as a WinUI 3 Application subclass throughout this series.
Each PR can be evaluated independently as a structural equivalence proof: the question to
ask is not whether this changes what the app does, but whether this code does the same
thing it did before, from a different location.

Changes

Extracts the BuildCommandCenterState cluster (11 methods, ~400 lines) from App.xaml.cs
into two new classes in Services/:

  • AppStateSnapshot: sealed record capturing the 15 App fields the cluster reads, as
    init-only properties. Captured at call time via CaptureSnapshot() before being passed
    to the builder.
  • CommandCenterStateBuilder: receives the snapshot in the constructor, exposes a single
    Build() method returning GatewayCommandCenterState.

App.BuildCommandCenterState() becomes a 2-line delegation call. All 11 existing callers
are unchanged.

Equivalence

The 11 methods in the cluster are near-pure: they read App state, do not mutate shared
fields, do not call UI, and do not marshal threads. Equivalence is verifiable by comparing
the DTO output field by field.

The one non-trivial ordering constraint (ApplyDetectedSshForwardTopology mutates
topology at a fixed position in the sequence) is preserved exactly.

Validation

  • ./build.ps1 green
  • dotnet test OpenClaw.Shared.Tests — 1442 passed, 22 skipped, 1464 total
  • dotnet test OpenClaw.Tray.Tests — 702 passed, 0 skipped, 702 total

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Moves the BuildCommandCenterState cluster (11 methods, ~400 lines) into
two new classes in Services/:

- AppStateSnapshot: sealed record capturing the 15 App fields the cluster
  reads at call time (init-only, no mutation).
- CommandCenterStateBuilder: receives the snapshot, exposes Build() returning
  GatewayCommandCenterState.

App.BuildCommandCenterState() becomes a 2-line delegation call. All 11
existing callers are unchanged.

The cluster is near-pure: reads App state, no shared mutations, no UI
calls, no DispatcherQueue marshal. Equivalence is verifiable by comparing
the DTO output field by field. Execution order including the
ApplyDetectedSshForwardTopology mutation of topology in its fixed position
is preserved exactly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@AlexAlves87 AlexAlves87 force-pushed the refactor/extract-state-builder branch from cafd118 to 4224c5e Compare May 11, 2026 14:05
@shanselman shanselman merged commit 3d871f9 into openclaw:master May 12, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants