Repository navigation
Conversation
…page Replace the flat notification list with the web Control UI Inbox model: only items that still need the user, action-first order, All/Approvals/ Mentions/Automations/System tabs, expandable rows, Dismiss shown, a notification settings shortcut and a 9+ capped badge that turns caution while an approval waits. - InboxProjection (WinUI-free) owns classification, order, tabs and badge - InboxView is shared by the bell flyout and the full Inbox page - Banner 'Show more' only appears when the Inbox has another entry - Strings localized in all six locales; ledger rows updated 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: needs real behavior proof before merge. What this changesThis PR adds a persisted Do not disturb toggle and Windows device-access alerts on top of the stacked Inbox changes. Example: Do not disturb is enabled while one approval for
Review scores
ProductKind: Feature · Worth it: Yes · Fix scope: Complete Merge readiness⛔ Blocked before merge - 8 items remain Keep open: this collaborator-authored feature is absent from main, but its included approval layer still has blocking disclosure defects. Priority: P2 Before merge
Findings
Tests
Agent review detailsHow this fits togetherGateway events and Windows privacy status feed the native Inbox; settings control interruptions, and approval decisions return through the authenticated operator client. flowchart LR
Gateway[Gateway] --> Sources[Inbox sources]
Windows[Windows device access] --> Sources
Sources --> Feed[Inbox feed]
Settings[Settings store] --> Feed
Feed --> UI[Inbox page and bell]
Feed --> Alerts[Toasts and banners]
UI --> Decisions[Approval decision owner]
Decisions --> Gateway
Technical reviewBest possible solution: Keep the existing settings, notification and approval owners, expose complete approval details, and distinguish uncertain completion from a confirmed failure to send. Do we have a high-confidence way to reproduce the issue? Source inspection establishes the approval-disclosure and timeout-feedback paths; supplied screenshots demonstrate the new visible states, but this review executed no target code. Is this the best way to solve the issue? The final layer appropriately extends existing owners: preserve approvals and Inbox collection while suppressing ordinary interruptions, and publish device blocks through the existing notification service without another connection or permission prompt. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against b6f158ab257a. Merge-risk optionsMaintainer options:
Provenance checked
TestingProof path: shipped entry point. SecurityNeeds attention: The included approval surfaces can authorize operations without displaying their complete details. EvidenceSecurity concerns:
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:
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 Reviewed November 7, 2026, 12:04 AM ET / 05:04 UTC. |
InboxView unbound itself on Unloaded, and a late Unloaded from the previous close could disconnect the freshly opened flyout. Hosts now own the binding: the flyout unbinds on Closed and the page on its own Unloaded. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ount alerts Wire Gateway-sourced items into the web-aligned Inbox through the existing operator client: - Typed pending approvals (exec, plugin, system agent) from approval events, hydrated with *.approval.list on connect and removed on resolve, expiry or disconnect. Expanded rows show the expiry countdown, scope/effect text, warning, command preview and Open chat (decisions follow in layer 3). - Failed and overdue automations from cron.list/cron.status, matching the web Control UI rules, with Ask OpenClaw and Open Automations. - Expired or missing model-provider accounts from models.authStatus, with Ask OpenClaw and the matching sign-in or API key action. - InboxFeed combines app notifications and Gateway facts so rows, tab counts and the badge share one projection. Gateway text is never logged. - New strings localized in all six locales; ledger rows updated. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…sts and long commands Review fixes for the Gateway-sourced Inbox items: - Out-of-range epoch-ms times (e.g. 9007199254740991) are rejected or clamped through one GatewayUnixTime helper instead of throwing and freezing every Gateway Inbox item until disconnect. - Approvals expire on a local-clock deadline fixed at arrival (arrival plus the Gateway's own lifetime), so a skewed Gateway clock cannot end them early or keep them forever. Repeats keep the original deadline. - host "gateway" is labelled "Gateway" (localized), not "This computer"; the Gateway may be remote. - The approval command preview shows the complete command in a scrollable, selectable block; hidden control, bidi and format characters are shown as visible escapes instead of being trimmed or rendered invisibly. - WorkspaceWindow no longer creates a fallback InboxFeed that never unsubscribed from the notification service. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Add Allow once / Always allow / Deny to Inbox approval rows and actionable Windows toasts for approvals that arrive while OpenClaw is in the background, with one authoritative decision path shared with the chat approval banner. - OperatorApprovalDecisions owns every operator decision: it revalidates the live pending approval (id, kind, unexpired, offered decision, explicit operator.approvals/admin grant, observed connection epoch) right before sending through the kind-aware OpenClawGatewayClient.ResolveApprovalAsync (exec.approval.resolve, plugin.approval.resolve, approval.resolve kind system-agent). Stale replies remove the row; other failures keep it for retry. - The chat banner routes through the same owner; the RPC-not-slash-command rule is unchanged. - Commands that cannot be reviewed in full are deny-only, matching the chat banner. A request that states unknown or malformed allowedDecisions offers nothing rather than the defaults. - Toasts carry only the approval id, decision and a one-shot token bound to the client and connection epoch; Allow once only for a fully shown exec command, never Always allow. Stale, forged or replayed activations open the Inbox. Toasts honor Show notifications and are withdrawn once decided or expired. - Local node exec approvals keep their separate in-process dialog. - New strings localized in all six locales; ledger rows updated. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Inbox Allow once / Always allow are offered and accepted only when the row shows the whole command; otherwise only Deny. - Chat banner decisions resolve against tracked approvals only (banner id or its correlated canonical id); untracked, expired or resolved ids are refused. Expiry uses the local per-approval deadline for rows, chat and toasts. - The chat banner offers only the decisions the owner accepts and shows the approval-access reason without an explicit grant. - Toasts offer Allow once only without a Gateway warning on a host confirmed to be this computer, and show that host; tokens are bound to the shown decisions. - Approval rejections log only the method and allowlisted codes. - Approval access is recomputed as soon as a reconnect's handshake arrives. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…rough Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
00f4c9f to
247abef
Compare
Depends on #2063 (feat: decide approvals from the Inbox and background toasts), which depends on #2060 (feat: show live Gateway approvals, automation failures and account alerts in the Inbox) and #2057 (feat: web-aligned Inbox for the footer bell and notifications page). This is layer 4 of 4; it includes the lower layers' commits, so review only the top two commits (
feat(inbox): Do not disturb and This PC alerts in the Inboxandfix(inbox): Do not disturb lets pairing and scope-upgrade requests through).What Problem This Solves
There was no way to silence OpenClaw alerts without also missing approvals, and nothing told you when Windows privacy settings blocked a device that an enabled node capability (camera, microphone, location) needs.
User Impact
User impact: the Inbox (bell flyout and full Inbox page) has a Do not disturb toggle. While it is on, Windows toasts, their sounds and in-app banners stay silent for everything except approvals and device pairing or scope-upgrade requests ("Approvals always come through"); the Inbox still collects items and the bell still counts them, and the bell switches to a slashed bell with help text "Do not disturb is on. N waiting". The System tab now shows This PC alerts (for example "This PC: camera access is off") with Open Windows privacy settings, which disappear when the block clears or the capability is turned off. This PC alerts work in the packaged (MSIX/Store) app; unpackaged development builds never show them (see Evidence).
Why This Change Was Made
DoNotDisturbPolicydecides;ToastService.ShowToastapplies it using the alert kindAppNotificationPublisherderives from the existing Inbox classification (so exec-approval Gateway notifications still toast), andAppNotificationInfoBarPresenterapplies it to banner eligibility without forgetting banners the user closed. Background approval toasts fromApprovalToastPresenterare never silenced. The Settings Send test notification button stays an explicit user test.SettingsData.DoNotDisturbis a field-scopedISettingsStoresave; hosts read and toggle it only throughInboxFeed, which ignores stale change events.AppCapability.CheckAccess(no prompt) only for devices an enabled capability needs while node or MCP mode is on: camera forcamera.*, microphone for speech-to-text and camera clips (they record sound by default), location forlocation.get. They re-read on settings saves and Windows access-change events; a dismissed row stays dismissed until its block clears or changes. The action opens only the matchingms-settings:privacy-*page.OPENCLAW_FIXTURE_DEVICE_ACCESSsupplies synthetic access for manual fixture proof.docs/ARCHITECTURE.mdgains the Do not disturb and This PC rows.Evidence
Fixture Gateway (
chat-interactive,approval). The first two screenshots come from an earlier build of this branch, before the fix that attaches settings after the service provider exists (the bell badge path did not change); the rest come from the final code. Plain bell, nothing waiting:Amber count while an approval waits; the flyout shows the new Do not disturb row:
Do not disturb on: slashed bell, the amber count still shows, and the approval is still listed. The bell's help text reads "Do not disturb is on. 1 waiting" and
settings.jsonholds"DoNotDisturb": true:Do not disturb on the full Inbox page:
This PC row in the System tab with an accent (non-approval) count, from a fixture app launched with camera enabled and
OPENCLAW_FIXTURE_DEVICE_ACCESS=camera=denied-by-user:Change Type
Scope
winnodeRequired proof pools
windows-winui-interactive: new Inbox Do not disturb states, the slashed bell and This PC rows need current-head visual, accessibility and notification proof in the WinUI app, including on-screen toast suppression and a real privacy block in the packaged app.Validation
Run on head
247abef2after rebasing onto #2063's review fixes (3e904ada) (Windows 11 ARM64, .NET SDK 10.0.403,OPENCLAW_REPO_ROOTset to the worktree):./build.ps1: passed (Shared, Cli, WinNodeCli, SetupEngine, WinUI; documentation and proof-pool validation passed).dotnet test ./tests/OpenClaw.Shared.Tests/OpenClaw.Shared.Tests.csproj --no-restore: passed 4922, failed 0, skipped 25 (existing opt-in integration/MXC/GPU skips).dotnet test ./tests/OpenClaw.Tray.Tests/OpenClaw.Tray.Tests.csproj --no-restore: passed 5407, failed 0, skipped 0.git diff --check: clean.DoNotDisturbTests(policy matrix, pairing and scope-upgrade requests come through while a standard alert stays silent, pairing results stay standard, both App pairing-request toasts tagged as approvals, approval tagging inAppNotificationPublisher, banner suppression/restore including closing an approval banner while on, persistence, settings attached later, stale change events, toast-service source guard),ThisPcAlertsTests(only enabled capabilities are read, unknown/allowed is not a block, camera needs the microphone, system-managed copy, route allowlist, fixture override parsing, publish/withdraw/dismiss/re-episode/replace throughThisPcAlertSource),GatewayFixtureIsolationContractTests(no host privacy reads or Settings launch in fixture mode),LocalizationValidationTests.Review fixes
DoNotDisturbPolicynow treats Inbox access requests as approvals, and App's node-pairing-pending and pairing-request toasts passAlertKind.Approval; paired/rejected results stay standard.Real Behavior Proof
scripts/run-gateway-fixture.ps1 -Scenario chat-interactive -Interaction approval), plus a second fixture-isolated app on a copy of that profile withNodeCameraEnabledtrue andOPENCLAW_FIXTURE_DEVICE_ACCESS=camera=denied-by-user.00f4c9f2(the pre-rebase layer-4 commit). The review fix and the rebase onto feat: decide approvals from the Inbox and background toasts #2063 do not change the bell, toggle or This PC rendering; head247abef2was revalidated with the full test run above but not re-screenshotted.run approvalto trigger a real fixtureexec.approval.requested; opened the bell; switched Do not disturb on; opened Open Inbox; read the bell and toggle through UI Automation; read the profilesettings.json.Name: Do not disturb,HelpText: Approvals always come through, value on/off;settings.jsonDoNotDisturb: true.Yes/No/N/A) YesAppCapabilitybehavior in the packaged MSIX app. A native probe from an unpackaged process returnedUserPromptRequiredfor webcam, microphone and location even though all are allowed, so unpackaged builds map to Unknown and show no This PC alerts (fail-safe, documented in the ledger). Clicking Open Windows privacy settings outside fixture mode was not exercised.Security Impact
Yes/No) NoYes/No) NoYes/No) NoYes/No) NoYes/No) YesYes, explain the risk and mitigation: the app now reads Windows privacy access status for camera, microphone and location withAppCapability.CheckAccess, which never prompts, only for capabilities the user enabled and only while node or MCP mode is on. Only the status enum is logged; no notification or user content is logged or exported. The Inbox action launches only three allowlistedms-settings:privacy-*URIs, and never in fixture mode.Compatibility and Migration
Yes/No) YesYes/No) YesYes/No) Nosettings.jsongainsDoNotDisturb(defaultfalsewhen absent).OPENCLAW_FIXTURE_DEVICE_ACCESSis read only in Gateway fixture mode.Review Conversations