Repository navigation
feat(automations): native Automations page with web parity - #1893
Conversation
Rebuild the Windows Automations page with Reactor on a UI-agnostic OpenClaw.Shared.Cron layer so operators can see and manage an agent's automations with the same information and actions as the web page. Fix agent scoping: every cron.list now sends agentId. Upgrade Microsoft.UI.Reactor to 0.1.0-preview.16 and retire the preview.12 pin and Markdown ListItem workaround. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
🦞👀 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. What this changesThis PR replaces the Cron page with agent-scoped native Automations management and upgrades Reactor. Example: Browse the ops agent’s daily automations.
Review scores
ProductKind: Feature · Worth it: Yes · Fix scope: Complete Merge readiness⛔ Blocked before merge - 5 items remain Keep this maintainer-authored draft open: it delivers distinct native scheduling work, but two behavior defects and unreachable production UI remain. Priority: P2 Before merge
Findings
Provenance
Tests
Agent review detailsHow this fits togetherThe WinUI page sends authenticated scheduling requests through the shared Automations store and Gateway client, then renders jobs, recent results, and mutation feedback. flowchart LR
User[Operator] --> Page[Native Automations page]
Page --> Store[Automations store]
Store --> Client[Operator Gateway client]
Client --> Gateway[Gateway scheduler]
Gateway --> Overview[Overview and Inbox facts]
Overview --> Page
Technical reviewBest possible solution: Land the daily-workflow replacement with valid session payloads, invocation-bound run tracking, and only reachable UI. Do we have a high-confidence way to reproduce the issue? Source establishes the Main-session failure against the released Gateway validator and the stale-history completion path; neither was executed during this read-only review. Is this the best way to solve the issue? The shared store and retained daily editor are appropriate, but session normalization and run identity need correction, and the superseded full-history component should be removed. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 1c223f14f6b6. Provenance checked
TestingProof path: none. SecurityNone. EvidenceAcceptance criteria:
What I checked:
Likely related people:
Preflight sourceSource unknown. Source comparison at the observed PR snapshot only. Completion is self-reported; body, policy, tests, execution, and report bytes are not verified. Review metrics
LabelsLabel changes: No label changes. Label justifications:
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment HistoryReview history (1 earlier review cycle)
Reviewed November 9, 2026, 6:13 PM ET / 23:13 UTC (Revision 2). |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep Automations mounted during reconnect attempts so its recovery UI remains available. Exercise the populated page in Light and Dark with per-process Axe scans. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Retain all populated theme scans and offline UI assertions. Disconnected CronPage Axe coverage stays in the existing stable accessibility lane, avoiding live element invalidation during reconnect. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Pin Light and Dark for the disconnected Axe path without Gateway reconnect events. Keep populated fixture scans and offline screenshots independent. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Native Automations proofWindows 11 ARM64, isolated synthetic Gateway. No production jobs or provider calls. The app source is unchanged since Debug proof: Light and Dark populated states, independent Light/Dark disconnected Axe scans, and the actual final message in 240-message chat histories at both window widths: 5 passed, 0 failed, 0 skipped. Details in LightDetails in Dark |
Wait for the independent recent-run summary and completed fixture reads, rather than scan controls while asynchronous replies replace their native elements. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Real Windows High Contrast (Night sky), production-shaped Release ARM64, fixture Gateway only. The test recorded Windows high contrast: True and passed all main states plus populated Axe checks (1 passed, 0 failed, 0 skipped). Both stable disconnected Axe cases also passed in the preceding High Contrast run. The original None contrast setting was restored and verified. An earlier duplicate Light case completed its UI checks but failed on temporary-profile cleanup; that failed attempt remains recorded locally. |
Automations parity checklist (web → native)Reference: openclaw/openclaw@5089aa71
Screenshots: Light/Dark main-state gallery and actual Windows High Contrast. This is the implementation inventory, not a claim that every control has separate live-provider proof. Runtime proof uses the isolated fixture Gateway. |
Keep editor form, revision and save feedback in the page-owned session. Fence delayed updates and close callbacks by editor nonce. Scope conversation directory results and selections to the active delivery route. Add fixture response gates and three native regressions. Build passed; Shared: 4701 passed, 25 ordinary skips; Tray: 4583 passed, four known ARM64 prerequisite failures. All five selected native UI cases passed against an isolated app compiled with the local Reactor fix. The directory regression still needs the unpublished Reactor empty-Suggestions binding fix. The NuGet dependency is unchanged, and no consumer workaround is added. Document that dependency explicitly. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…on requests Reduce the native Automations page to the workflows people use every day, keep advanced jobs readable and safe, and make the cron client work against released Gateways. Automations page - Show the full inventory on the connected Gateway, including paused and auto-disabled jobs, with All agents discovery and explicit agent filtering. Keep search, All/Active/Paused, paging and counts, refresh and scoped scheduler health and failures. - Keep Run now, pause and resume, safe ordinary edits and confirmed removal. Keep one-time, interval, daily, weekday and weekly presets with timezone clarity, and a simple delivery destination with visible existing destinations and delivery errors. - Keep recent run history with result and error text, Open chat, and Open in web handoffs that only use routes the web app supports. - Advanced jobs stay visible and readable. Basic edits preserve hidden settings, and unsupported edits route to web management instead of rewriting the job. - Remove client-authored suggestions, event and cron-step authoring, scratch editing and the inline transcript explorer. - Match the shared eyebrow row, anchor the page gradient to the viewport behind the scroll viewer, and separate stacked cards with the shared 8 DIP inner gap. Gateway cron requests - cron.runs no longer sends the beta-only view parameter, which stable Gateways reject with "unexpected property 'view'". - cron.remove sends only the job id after confirming the loaded revision with cron.get, matching the stable closed schema. - The Gateway fixture now enforces the stable closed cron schemas so this cannot be hidden again. Build and CI - Move Microsoft.UI.Reactor and Microsoft.UI.Reactor.Advanced to 0.1.0-preview.17 through a digest-pinned bootstrap of the official release assets into an ignored repository-local feed, and adapt the chat link builder to the new API. - Run the steady-resource Automations UI tests in CI. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Merge origin/main (4ea07e8) into the Automations page. The only textual conflict was CronPage.xaml.cs, where main still edited the retired XAML page; the Reactor host is kept. Main's shared navigation search (#2016) opens a found automation through CronPage.RevealSearchJob, which the Reactor page did not have. Port it: - AutomationsStore.RevealAsync looks the job up on the Gateway, selects it and reports Revealed, NotFound, Failed or Superseded. A missing job selects nothing instead of leaving a phantom selection, and a reveal that loses to a newer load changes nothing. - A reveal can widen a specific-agent filter to All agents so a job owned by another agent is shown. Search and the post-save reveal widen; agenda and attention reveals stay in the current scope. New automations still belong to the route agent. - A job that no longer exists shows the Hub search "unavailable" wording as a neutral, auto-dismissing in-page notice. It is not a global notification and adds no new localized strings. - AutomationsRevealChannel carries the page request to the mounted root, holds one pending request until the root attaches, and supersedes it on dispose, so a search that lands before the first render is not lost. - SettingsShellView and the search catalog from main are unchanged. Docs: update the architecture ledger rows for the Automations page and add the search reveal owner with its behavioral guard. Tests: store reveal tests (found, missing, filtered, widened, saved for another agent, disconnected, superseded), channel tests and source contract tests. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve complete inventory and advanced job settings, integrate shared adaptive Settings and inset ownership, and add focused pinned native proof definitions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reconcile Settings navigation persistence and adaptive page allocation, retire removed Event Stream state, and preserve the native foreground activation gate after replacing the legacy Cron editor tests. Co-authored-by: bkudiess <7658216+bkudiess@users.noreply.github.com>
Co-authored-by: bkudiess <7658216+bkudiess@users.noreply.github.com>
Keep the viewport-layer ordering and single brush-owner assertions while matching the header height plus retained shell inset. Co-authored-by: bkudiess <7658216+bkudiess@users.noreply.github.com>
Read the nonce-bound owner session when Save runs, rather than the render-captured form. Keep UIA proof on exposed controls and explicitly positioned viewports; preserve exact inert-link and destructive-copy checks and route keyboard-only proof through its existing opt-in lane. Co-authored-by: bkudiess <7658216+bkudiess@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve daily workflows and distinct native regressions while removing unrelated baseline repairs, duplicate shared guards, unused history copy and reflection diagnostics. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Retain cached chat theme resources alongside the Automations production-profile guard and shared resource loader. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep text subscriptions bound to Reactor lifetime and isolate result rendering from chat navigation. Exercise modal input and native allocation contracts, and distinguish fixed pixel sampling apertures from aggregate UIA bounds. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Verify automatic automation reveal before scrolling to inspect details, retain the observed Settings search peer, and give the ordinary hosted fixture invocation 1200 seconds within its existing outer limit. Keep the 900-second default and strict owned-process and result admission guards. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Retain the independently measured same-window sampling aperture for post-reveal detail inspection instead of resetting and traversing the entire expanded inventory. Keep automatic focus, capture, containment and deadline assertions unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use the existing dedicated-worker pattern without changing the identity lock deadline or security assertions. Add the approved bounded public reader-event observations only to failure diagnostics, preserving all actions, predicates and timeouts. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Expanding the agenda can scroll the header out of view. Return to the top and invoke the observed enabled New button once, retaining the expansion and draft-preservation assertions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve both host-owned Usage and Automations sources, protocol interfaces, fixtures and locale catalogs. Reconcile native fixture input type names without changing input behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Place pagination rows on one local reported date and expand the rendered date group rather than recomputing its key from a later clock sample. Preserve the collapsed budget, automatic reveal, detail capture and separate multi-group/calendar coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Integrate e59374c while preserving both page owners. Size the ordinary fixture aggregate budget from measured combined inventory and wait for committed history publication in the transient-retry fixture. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
PR cleanup reviewReviewed head: Thanks for the work on this. I would keep #1893 (feat(automations): native Automations page with web parity) open as a draft, rather than close it as superseded: pinned main still has the legacy Cron page, and this branch has a distinct native daily-workflow implementation. At d11898a, the latest CI run has completed, not remained pending: the production-resource lane passed 31/31, while the UI and Mock Gateway jobs failed on reader scrolling, a Usage title-bar peer and composer readiness. Those failures need attribution before rerunning; this read-only pass did not establish baseline flakes. The next useful pass is focused lifecycle and proof work: bind the page store to its originating connection, cover omitted-owner cloning and multiple expanded rows across reconnect, and preserve visible results when persistent error toasts fill the queue. Please also keep capture observational and restore the native timezone-transition matrix. These are source-backed concerns, not an executed Windows reproduction. Please refresh the body to the actual head and current daily-workflow scope, reconcile the older review against the repairs already present, and attach current-head native/compatibility evidence before moving out of draft. Historical screenshots and the old parity checklist are useful provenance, but not proof of this UI. Action in this cleanup pass: leaving this PR open. No branch changes or runtime-proof waiver. The findings above come from source, discussion and recorded-CI review; Windows validation was not rerun in this pass. |
Preserve run-correlated transcript ordering and queued follow-ups across delayed acknowledgements. Keep fixture geometry readiness bounded, retain critical reader failure observations, and add exact-two-case unsigned non-Dev Release fixture proof without changing production signing defaults. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Observe the existing failed reader request under one restored anchoring counterfactual and always rethrow its original failure. Capture content-free single-write reconnect diagnostics only on failure; preserve all original actions, predicates and deadlines. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep the existing rendered readiness deadlines and all strict geometry, focus and consequence assertions; a popup entry alone does not establish that its dialog template is loaded. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use bounded overlapping viewport steps for the exact session header, preserve strict expansion assertions, and record content-free reopened-Inbox evidence only if its existing wait fails. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep automatic expansion evidence separate from explicit inspection. Freeze the client-clipped sampling aperture and require stable visible detail anchors through the final Errors row, with obstruction checks around capture. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Integrate exact a6ff6a1. Yield edge anchoring for an admitted keyboard reader bring while preserving initial, disclosure and tail navigation ownership. Guard editor reveal against nonfinite geometry and require the exact reader pair in Release proof. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Retire reader event buffering, reconnect peer sampling and reopened-Inbox failure dumps. Preserve all test cases, native actions, readiness predicates, assertions and Debug/Release proof selections; production behavior is unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>













What Problem This Solves
Users need a complete automation inventory and reliable everyday controls without reproducing the entire Gateway web editor.
User Impact
User impact: browse all accessible agents and paused or advanced jobs, run or pause jobs, edit ordinary schedules, inspect recent results, and open chat or web management for deeper work. Owner delivery and unsupported timing writes/copies remain web-managed; basic edits omit unchanged unsupported fields and preserve hidden saved settings.
Removal is not atomic: the client checks the loaded revision with
cron.get, then sends the released Gateway's id-onlycron.remove. A concurrent edit between those calls is not detected. Reported conflicts are surfaced without an unguarded removal retry.Why This Change Was Made
The native page prioritizes discovery, status, timezone-aware presets, delivery visibility and daily actions. Permission checks, confirmations, draft lifetime and stale-response fencing remain explicit instead of silently converting advanced jobs. Landed Usage and Dashboard owners are preserved.
A reproduced queued-chat ordering defect is also repaired: delayed acceptance no longer reopens a completed turn or places its prompt after the response. Unrelated/newer runs and queued follow-ups remain isolated. The combined fixture inventory uses a measured 1500-second aggregate allowance within the unchanged 30-minute outer step; individual deadlines, assertions and cleanup gates are unchanged.
The final reader repair relinquishes bottom anchoring for an actual keyboard-directed destination outside the follow range. Matching native completion and existing tail-navigation owners retain follow/restoration responsibilities; no extra scrolling or forced layout is introduced.
Evidence
Current-head CI passed on attempt 1, including the required CI Gate. Head
35715c5900e0368f3d43d13bd0dd20e367f70a67was tested as mergeb6288e913dec3aa111c36b205961b9852f73569d(maina6ff6a16plus this head), whose tree9582ba29a84a747f2c6b369e60c2a7c3d8420005exactly matches the local candidate.The requested simplification removed 373 net lines of temporary diagnostics across three test files, with no production, test-case, assertion, action, wait-budget or CI-selection changes. The reduced candidate passed all 122 Debug fixture cases, both Debug/Release reader widths, two Release queued-chat cases, native UI 1243 cases with nine policy skips, and full unfiltered hosted Tray 6276/6276.
Previous intermittent failures are preserved. The reader counterfactual demonstrated that changing anchoring released the already-pending requests; it did not identify the source of the nine-DIP measurement oscillation. The original reader assertions passed through the production repair in Debug and Release. Temporary reader, reconnect and notification diagnostics are now retired without removing their regression tests; their removal is not a reconnect or notification root-cause fix. Fixture evidence does not establish live Gateway timing or installer/Store upgrade behavior.
Review scope and resolved findings
Independent Opus 5.5 and GPT-6 Astra code-review contexts covered implementation/proof-plan scope at
03f45691against045d13ac, 128 paths per reviewer. The rubber-duck role was unavailable. Ten retained findings were repaired incab3b592and subsequent lifetime, rendering and proof corrections. Supplemental coverage followed narrative exposure, so this was not wholly blind; reviewers did not execute runtime proof.Separate bounded P0-P3 reviews covered integration conflicts, CI capacity, queued-turn repair, diagnostic safety, reader-anchor ownership, editor geometry and the Systems/Usage proof-readiness corrections. Accepted agent-delta correlation and Release-build prerequisite findings were repaired and rechecked. The simplification mapped 206 authored repair hunks to 193 retained and 13 removed; its independent review found no significant issues, and AST checks preserved cases, assertions, actions and waits. This is not a fresh whole-head dual-model review; subsequent reviewer model identities are unverified.
The older durable review was reconciled against source and executed regressions: Main normalizes to
systemEvent/text; accepted invocation/run IDs govern completion, with conservative ID-less handling; unreachable full-history UI was removed while recent full results remain; hidden-field preservation and strict protocol tests protect existing jobs. Released portable-profile preservation is not installer/Store or live Gateway cron-storage migration proof.Change Type
Scope
winnodeRequired proof pools
windows-winui-interactive: native editing, navigation, focus, accessibility, responsive layout and visible result/hero rendering. Declaration is not complete-pool acceptance.Validation
Current local source: head
35715c5900e0368f3d43d13bd0dd20e367f70a67, tree9582ba29a84a747f2c6b369e60c2a7c3d8420005. Validation ran on the frozen source manifest whose exact tree became this commit. Its parent integrates pinned maina6ff6a16.$ownedResultsdenotes each invocation's separate task-owned output directory, with its private path redacted..\build.ps1 -NoTrustRepositorydotnet build .\tests\OpenClaw.Tray.UITests\OpenClaw.Tray.UITests.csproj -c Debug -r win-arm64 -p:DevBuild=false --disable-build-servers -nodeReuse:falsedotnet build .\tests\OpenClaw.Tray.UITests\OpenClaw.Tray.UITests.csproj -c Release -r win-arm64 -p:DevBuild=false --disable-build-servers -nodeReuse:false -p:RequireSignedCleanupHost=falsedotnet test .\tests\OpenClaw.Shared.Tests\OpenClaw.Shared.Tests.csproj --disable-build-servers --logger "trx;LogFileName=shared.trx" --results-directory $ownedResultsdotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --disable-build-servers --logger "trx;LogFileName=tray.trx" --results-directory $ownedResults --filter "FullyQualifiedName!=OpenClaw.Tray.Tests.SettingsManagerIsolationTests.OpenClawTrayDataDirRedirectsSettingsAwayFromRealAppData"dotnet test .\tests\OpenClaw.Tray.Tests\OpenClaw.Tray.Tests.csproj --disable-build-servers --filter "FullyQualifiedName~ChatTimelinePresentationTests" --logger "trx;LogFileName=chat-focused.trx" --results-directory $ownedResultsgit diff --checkThe one locally excluded Tray case reads OS-roaming settings outside isolation overrides. No repository/CI filter was changed. The exact case passed in both current hosted Tray variants; this does not retroactively make the local filtered run unfiltered.
Earlier evidence stays attributed: the 621/621 provider-owner and 12/12 ordering/isolation runs belong to
575bd3d8; unchanged managed cases re-executed in current full Tray closeout. Documentation, skill, skill-validator and workflow-contract scripts passed at3dec70a9; those inputs are unchanged by this three-test-file reduction. Actual-source reader characterization reproduced the missing handoff on the prior owner and passed on the repair; this does not substitute for native event/layout execution.Real Behavior Proof
35715c59; hosted mergeb6288e91, identical tree9582ba29, as recorded above.906225BD5D23C040F4388F6EC105D13B95E1CB0573E41A5D58F9223E14A936C0matches both running-app receipts.Yes/No/N/A) Yes: current job artifacts were downloaded, raw TRX inspected and the Light/Dark expanded-detail images visually checked.CI explicitly selects the Release app, enables isolated fixtures/screenshots, and retains its DLL for configuration, identity and runtime-hash verification. Unsigned fixture builds do not change production signing defaults.
Security Impact
Yes/No) No.Yes/No) No.Yes/No) Yes.Yes/No) No.Yes/No) Yes.Yes, explain the risk and mitigation: native discovery reads all jobs accessible to the connected operator. Existing authenticated Gateway authorization governs reads and mutations. Explicit filters, capability checks and generation fencing reject stale results and unsupported writes. Web handoff retains existing credential policy; run-result rendering stays inert.Compatibility and Migration
Yes/No) Yes, with explicit web-management fallback for unsupported edits or Gateway revisions.Yes/No) Yes: ordinary hosted fixture allowance is 1500 seconds; runner default remains 900 and accepted range remains 1 through 1800.Yes/No) No.Review Conversations
The final review-thread check found zero inline threads. No formal approval or bot reply is implied; the old-head durable findings are reconciled above and final required CI is green.