* feat(gateway): live desktop observer for cloud workers
Adds live observation for cloud worker desktops through the gateway and Crabbox plugin, including desktop provisioning, persisted desktop metadata, tunneled WebSocket proxying, and the worker.desktop.observe protocol method.
The gateway, Crabbox plugin, and gateway protocol surfaces remain off by default behind the cloudWorkers.desktop Labs flag.
* feat(ui): Desktop panel for cloud worker observation
* docs(gateway): document cloud worker desktop lab
* fix(ci): regenerate contract baselines after rebase
* fix(protocol): regenerate Android gateway methods
* fix(ci): align rebased SDK and lint baselines
* fix(gateway): enforce view-only RFB boundary and fence desktop teardown
* fix(gateway): tighten RFB filter surface
* fix(state): keep pre-desktop databases readable and harden view-only RFB
* fix(gateway): fence desktop observer upgrades behind work admission
* fix(gateway): bind desktop observer tokens to their owner epoch
* fix(ci): regenerate config and SDK baselines after rebase
* fix(ci): regenerate native protocol and SDK baselines
* fix(ci): regenerate contracts after main rebase
* fix(state): register desktop metadata as lazy additive
* fix(ci): regenerate SDK baseline after final direct-merge rebase
* fix(ui): report dev checkout update status
Show tracked-upstream commit lag and verified install/commit timestamps in Settings > Updates. Verify the post-restart Git revision before reporting success, and surface same-revision updates as an explicit no-op unless plugin convergence changed the install.
* test(ui): expect authoritative update reconciliation
* fix(ui): retain dashboards across view switches
Keep visited dashboard runtimes alive across Chat, Split, and Dashboard transitions, suspend hidden work, and avoid same-face persistence requests.
Refs #120639
* fix(ui): preserve session owner during route loads
Carry the last successful route match through pending loads so face-only navigation retains dashboard runtimes without stranding session or catalog switches.
Refs #120639
* fix(ui): preserve sandbox bridge while hidden
Suspend hidden board frame work without disposing the one-shot sandbox handshake, loaded document, or MessagePort.
Refs #120639
* fix(ui): forward sandbox readiness while hidden
Keep the constrained sandbox message channel alive during dashboard suspension so one-shot proxy readiness reaches the retained host without resuming widget work.
Refs #120639
* fix(ui): pause hidden plugin widgets
Propagate board activity through trusted plugin renderers so Workboard widgets suppress hidden refresh and mutation work, then refresh once without remounting.
Refs #120639
* feat(update): scheduled update campaigns with countdown, dev-channel auto-update, and Updates settings page
* fix(ui): satisfy update campaign deadcode checks
* feat(update): extend scheduled update campaigns
* test(ui): include Updates page in settings sidebar search expectations
* fix(update): end campaigns when apply fails
* fix(update): pin dev campaign applies to the announced commit
* test(ui): align update e2e fixtures
* fix(update): pin adopted dev updates to the announced commit
* docs(update): document automatic dev update campaigns
* fix(ui): gate automatic dev updates on git installs
* fix(gateway): scope detailed update metadata to read-capable clients
* fix(gateway): break post-attach madge cycle with a leaf client-lookup type
* chore(protocol): regenerate clients after rebase
* test(gateway): update method tail after rebase
* fix(update): preserve campaign target and hold state
* test(update): align adoption mocks and split handoff suite
* test(update): route split handoff suites on Windows
* fix(ui): move stale-client refresh notice into the sidebar update card
The 'Server updated — refresh for full capabilities' notice rendered as a
full-width callout at the top of <main>, where the fixed shell-chrome
controls (nav toggle / search, layout.css z-index 45) overlap its text.
Move the notice into the existing sidebar-update-card slot above the
identity/connectivity footer: refreshRequired takes precedence over
updateAvailable (a stale client cannot trust its own update metadata),
renders non-dismissible with a refresh icon and two-line text, and is
wired through the sidebar, settings sidebar, and collapsed-nav floating
card. The old top-of-main banner branch, its resolver helper, and the
orphaned i18n key are deleted.
* fix(ui): keep stale-client refresh visible during onboarding and clear collapsed chrome cluster
Address both accepted ClawSweeper P2 findings:
- restore the stale-client refresh action during onboarding
- keep the floating update card clear of the three-button collapsed chrome cluster
* fix(ui): hide connection form during initial auth
Use the authoritative gateway connecting/error state so trusted-proxy, Tailscale, bootstrap, device, and token auth all keep the centered loading screen until the first handshake resolves. Real failures still reveal the login gate, manual retries stay pinned, and established reconnects retain the shell.
* fix(ui): preserve approval document login gate
Scope the neutral unresolved first-connect splash to the normal Control UI document. Standalone approval links continue to expose their authentication gate without losing the deep link, while embedded terminal behavior remains unchanged.
* fix(ui): preserve active session status layout
* fix(ui): preserve avatar paths and fork lineage
* fix(ui): preserve avatars under control UI base paths
* fix(macos): let onboarding replace an auto-connected AI
The AI page auto-tests the best detected candidate and connects without
asking, then hides every alternative route. Add 'Choose a different AI'
to the connected banner: a re-detect pass with auto-activation
suppressed that ends at the picker (candidates, provider sign-in, API
keys). Also disable the manual key Connect button while another test
runs (submitManualKey silently dropped the tap), and isolate a test
that read the machine's real resume store.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(macos): surface real daemon errors past the Node banner
Gateway daemon failures summarized as 'Node.js v26.5.1' because the
summary takes the last non-empty line and Node fatal errors end with a
version banner. Drop trailing banner lines and prefer the last
error-shaped line above them; all other output keeps its last line.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(macos): hand onboarding off to the dashboard custodian
Native onboarding now ends once inference verifies: welcome, connection,
install (when needed), AI setup. Finish opens the dashboard at
/custodian?onboarding=1, where the custodian onboarding owns memory
import, channels, app recommendations, and the hatch (browser-first per
the onboarding redesign). The native memory-import and permissions
pages leave the first-run flow; 'Set up later' keeps the native ready
page. The native navigation bridge gains a validated optional search
field so the handoff can request onboarding chrome; the URL fallback
carries the query alongside the token fragment.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* refactor(macos): delete the unreachable native memory-import module
The dashboard handoff removed the memory-import page from every flow,
leaving the module reachable only from tests. CI's dead-code scan
rightly flagged the first orphans; remove the whole path (model, page,
mascot wiring, tests) instead of trimming symbol by symbol. The
dashboard's own memory-import surface owns the feature.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>