Commit Graph

439 Commits

Author SHA1 Message Date
Pavan Kumar Gondhi 5eb18c1387 fix(ios): keep authenticated Control UI pages bound to the trusted Gateway [AI] (#119906)
* fix(ios): enforce gateway TLS pins in control pages

* test(ios): run control UI trust regressions in CI

* test(ios): avoid nested Testing macros

* fix(ios): preserve control page navigation

* fix(ios): keep authenticated control pages on origin

* fix(ios): canonicalize control page IPv6 hosts

* chore(ios): refresh native i18n inventory

* fix(ios): normalize default TLS challenge ports

* fix(apps): share gateway TLS authority matching

* test(apps): fix authority CI validation

* chore(ci): drop control UI test routing
2026-08-12 15:18:19 +05:30
Peter Steinberger 526ae6d944 fix(macos): honor While Using location permission (#122435) 2026-08-11 22:12:56 -07:00
Peter Steinberger 4401ff2a92 refactor(macos): remove final private test seams (#122202)
* test(macos): remove final private test seams

* chore(macos): refresh native i18n inventory
2026-08-11 20:42:45 -07:00
Peter Steinberger 5179e12352 fix(macos): deliver provisional notifications (#122179)
* fix(macos): accept provisional notifications

* fix(macos): return notification permission labels

* fix(macos): preserve notification inventory
2026-08-11 11:42:06 -07:00
Peter Steinberger 1383144b02 test(macos): remove private helper mirrors (#122081)
* test(macos): remove private helper mirrors

* test(macos): cover voice transcript finality directly
2026-08-11 09:14:38 -07:00
Peter Steinberger df72781ed4 fix(macos): make the whole AI candidate row clickable and clear stale exhausted verdicts (#121928)
* fix(macos): make the whole AI candidate row clickable and clear stale exhausted verdicts

Live-testing pick-during-testing on 2026-08-11 showed clicks on a candidate
row's blank stretch (between the title/subtitle texts or over the spacer)
silently doing nothing: plain-style buttons only hit-test opaque label
pixels. A user trying to pick Claude Code while Codex auto-tests can click
the visually highlighted row and get no outcome. .contentShape(Rectangle())
makes the full row hit-test.

Also, after auto-candidates exhaust, a user-picked retest left the stale
"None of the found options worked" card up while the new test visibly ran;
userSelect now clears exhaustedAutoCandidates when a fresh attempt begins.

* test(tooling): drop stateless poll tests from stateful-helper fixtures

Main went red when #121923 rewrote the outbound poll tests to be
order-independent and removed their stateful helper import/file; this
lane-config test hardcoded both as stateful-helper classification
fixtures. Folded into this PR per red-main landing policy.
2026-08-11 01:10:12 -07:00
Peter Steinberger 7d647f6810 fix(macos): stop profile onboarding from promising refused attachment (#121614)
* fix(macos): align profile gateway onboarding ownership

Stop onboarding from advertising foreign profile listeners as attachable. Reuse the GatewayProcessManager PID ownership rule and preserve existing non-profile listener wording.

* chore(macos): refresh onboarding i18n inventory
2026-08-11 00:26:46 -07:00
Peter Steinberger 79dcf48434 test(macos): remove stale Canvas helper probes (#121866) 2026-08-10 22:12:49 -07:00
Peter Steinberger 69220fc0d4 test(macos): remove body-only view probes (#121820)
* test(macos): remove body-only view probes

* test(macos): drop retired i18n wrapper contract
2026-08-10 20:26:56 -07:00
Peter Steinberger 87bb2e5af0 fix(mac): profile onboarding updates the operator's host-global managed CLI (#121651)
* fix(mac): scope managed CLI install and detection to the active app profile

Under an active OPENCLAW_PROFILE the onboarding ready page detected the
host-global managed CLI (~/.openclaw/bin/openclaw) and its update/install
flow rewrote the operator's real managed copy. The managed install prefix
now follows the profile state directory (~/.openclaw-<name>), preferred
paths exclude other profiles' managed trees (including stale validated
executables and inherited shell PATH entries), and external CLIs stay
detectable read-only. Default-profile behavior is unchanged.

* chore(mac): refresh native i18n inventory for shifted source lines
2026-08-10 16:50:05 -07:00
Peter Steinberger 033d32447d test(macos): remove Tailscale session exerciser (#121748) 2026-08-10 16:39:45 -07:00
Peter Steinberger 4849106b3b fix(mac): allow superseding AI candidate tests (#121613) 2026-08-10 07:55:31 -07:00
Peter Steinberger 2ed1a62d06 refactor(macos): consolidate gateway readiness ownership (#121510)
* refactor(macos): unify gateway readiness ownership

* chore: re-fire CI after startup_failure race

* chore(i18n): refresh native inventory after readiness consolidation
2026-08-10 02:52:22 -07:00
Peter Steinberger 6f917dfabb test(macos): remove remaining coverage exercisers (#121413)
* test(macos): remove remaining coverage exercisers

* test(macos): remove dead skills typealias

* test(macos): remove unused skill config constructor
2026-08-10 02:08:34 -07:00
Peter Steinberger e4b617300d refactor(macos): remove obsolete Gateway startup probe (#121439)
* refactor(macos): remove dead gateway command builder

* chore(i18n): refresh native inventory after gateway-env cleanup
2026-08-10 00:19:23 -07:00
Peter Steinberger f37507cac2 test(macos): keep mocked gateway probe routes off the operator identity store (#121398) 2026-08-09 23:36:22 -07:00
Peter Steinberger 3a114678f9 refactor(mac): delete dead onboarding surfaces after dashboard handoff (#121352) 2026-08-09 22:17:27 -07:00
Peter Steinberger 374007083a fix(mac): adopt CLI identity during state migration (#121313)
* fix(identity): one canonical device-identity contract across app and CLI

* fix(ci): satisfy native identity checks

* chore: drop changelog edit (release-generation owns CHANGELOG.md)
2026-08-09 20:47:21 -07:00
Peter Steinberger 0dbdf994b3 feat(macos): isolate named app profiles (#121136)
* feat(macos): isolate named app profiles

* refactor(macos): isolate profile launch ownership

* fix(macos): avoid overlapping approvals socket access

* fix(macos): declare profile defaults concurrency ownership

* fix(macos): return profiled node launch arguments

* chore(i18n): refresh macOS profile source inventory

* fix(macos): gate profile startup before services

* test(macos): evaluate profile state before assertions

* fix(daemon): skip absent launchd deactivation

* fix(macos): fail closed on profile port conflicts

* chore(i18n): refresh profile conflict inventory

* fix(macos): ignore non-gateway launch agent claims

* test(macos): stabilize profile lifecycle timing

* fix(macos): remove stale dashboard URL

* chore(macos): refresh native source baseline
2026-08-09 14:50:15 -07:00
Peter Steinberger dd5b4d0d30 test(macos): remove assertion-free coverage exercisers (#121139) 2026-08-09 11:17:57 -07:00
Peter Steinberger 0303af17f3 test: remove low-value implementation assertions (#121085)
* test: remove low-value implementation assertions

* test: refresh native i18n inventory
2026-08-09 08:48:48 -07:00
Peter Steinberger ab5e10fd17 fix(macos): first-run gateway startup survives state migrations (#121012)
* fix(macos): tolerate first-run state migrations during gateway start

* fix(macos): tolerate loaded-host version probes
2026-08-09 03:11:38 -07:00
Peter Steinberger 00854a7002 fix(macos): proper provider brand icons + softer contrast in onboarding AI setup (#120907)
* fix(macos): let AI setup proceed when the login keychain is unavailable

A missing/locked login keychain made GatewayActivationBindingKeyStore
unable to mint the activation binding key, and onboarding refused every
candidate and manual-key activation with 'Secure storage is unavailable'.
The fingerprint only protects the crash/relaunch resume receipt, so
degrade instead of refusing: write an ownerless pending record (still
matched exactly, never as a wildcard), keep the full activation-ambiguity
window, and skip only restart reconciliation, which needs fingerprint
proof by design. A relaunch then repeats activation rather than trusting
the receipt.

Reported by Peter Steinberger.

* fix(macos): render proper provider brand icons in onboarding AI setup

Nearly every provider icon URL the gateway sends is a simpleicons.org
SVG, which AsyncImage cannot decode, so the Connect your AI page fell
back to generic symbols for every tool and provider; the two GitHub
avatar PNGs that did render clashed as full-color rasters.

Bundle nine monochrome template marks (Simple Icons CC0; xAI from
LobeHub icons, MIT) and resolve them local-first by brand id/kind,
including composed choice ids like xai-oauth. Remote icons now load via
NSImage(data:), which decodes SVG, with vector payloads tinted as
templates so plugin-supplied icons blend too. Every glyph sits in a
uniform rounded well; install cards show host-only links, hover states,
and a softer translucent surface shared by all setup sections instead
of controlBackgroundColor.

Requested by Peter Steinberger.

* fix(macos): use failable UTF-8 decode in icon vector sniffing (swiftlint)

* fix(macos): address ClawSweeper review of onboarding icon/keychain changes

- Refuse relaunch handoff from ownerless (keychain-unavailable) completed
  receipts at the reconciliation trust boundary; such receipts can belong
  to replaced credentials, so setup repeats a fresh activation instead.
- Decode and pass the canonical brandId the gateway sends for candidates,
  auth options, and manual providers so bundled marks resolve for opaque
  choice ids.
- Scan the bounded XML prolog (comments, declarations, doctype) when
  sniffing remote SVG payloads; comment-prefixed vectors now tint as
  templates.

* refactor(macos): move setup error enum to support file (swiftlint file length)

* chore(i18n): refresh native source inventory

* fix(macos): give keychain-unavailable activations attempt-specific unbound leases

A nil owner made concurrent unbound attempts indistinguishable: a stale
attempt's delayed response could complete or clear a newer attempt's
record. Unbound attempts now mint a random per-attempt lease id with a
sentinel fingerprint — live matching stays attempt-exact, restart
reconciliation's fingerprint guard rejects them, and relaunch
verification refuses unbound receipts before any handoff.

* chore(macos): ship third-party artwork notices with provider icons

Simple Icons (CC0) attribution and the LobeHub Icons MIT license text
for the xAI mark now travel inside the bundled ProviderIcons directory.

* fix(ci): refresh plugin-sdk API manifest for private-type hashing

#120975 changed the baseline generator to hash private types but landed
without regenerating the manifest; the check-plugin-sdk-api-baseline
lane was gated off on that PR and first failed here. Regenerated via
pnpm plugin-sdk:api:gen with no SDK surface change in this branch.
2026-08-09 01:49:50 -07:00
Dallin Romney dcdbd7aab6 fix(update): prevent stable upgrade notices on extended-stable (#118518)
* fix(update): keep extended-stable update notices on channel

* fix(update): repair extended-stable CI checks

* fix(update): retain verified extended-stable channel

* fix(update): normalize gateway install surface

* test(update): split effective channel coverage

* fix(update): resolve verified extended-stable status paths

* fix(update): preserve Sparkle fallback on missing channel

* fix(update): restore effective channel after rebase

* fix(update): repair rebased CI coverage
2026-08-09 16:01:14 +08:00
Peter Steinberger 5bd623c4b6 feat(macos): open dashboard as soon as onboarding inference connects (#120950)
* feat(macos): open dashboard as soon as onboarding inference connects

* chore(i18n): remove retired setup helper strings

* fix(i18n): keep generated locales isolated
2026-08-09 00:47:43 -07:00
Peter Steinberger a8f8fd3256 fix(macos): prevent shared state in parallel test suites (#120912)
* fix(macos): isolate parallel test state

* chore(i18n): refresh native source inventory
2026-08-08 23:03:20 -07:00
Peter Steinberger ee30bb46c2 fix(macos): keep onboarding alive during Local Network permission (#120859)
* fix(macos): wait for Gateway startup owner

* chore(i18n): refresh macOS source inventory

* fix(macos): bound first-install readiness grace
2026-08-08 21:22:14 -07:00
Peter Steinberger 642b486986 fix(macos): prevent parallel Swift test hangs after coordinator timeouts (#120869)
Make timeout paths cancel or release every pending test continuation before cleanup, so failures cannot poison the remaining Swift suite. Inject the retry sleeper to preserve invalidation-before-backoff ordering without real-time polling.
2026-08-08 21:17:39 -07:00
Peter Steinberger 915c25d713 fix(macos): complete ChatGPT subscription setup (#120782)
Fresh Dev installs now preflight disk space and stream honest stages, while Codex activation probes the refreshed request-scoped registry.

Closes #120779
Closes #120780
2026-08-08 17:16:00 -07:00
Peter Steinberger e6353d85ef fix(daemon): drop stale service version metadata (#120702) 2026-08-08 14:14:22 -07:00
Peter Steinberger d9ff862823 fix(macos): recover node startup after legacy identity recreation (#120610) 2026-08-08 08:54:16 -07:00
Peter Steinberger 6176c0a79d feat(macos): control motorized camera pan, tilt, and zoom (#120511)
* feat(macos): add native camera PTZ controls

Add physical UVC pan, tilt, and zoom through the signed Mac app, with camera.ptz.control kept behind dangerous-command approval. Verified against real Insta360 Link 2 Pro hardware.

* refactor(agents): split message tool display config

* fix(mac): harden camera PTZ contracts
2026-08-08 08:04:29 -07:00
joshavant 28e2ea8e62 test(mac): isolate dashboard frame autosave smoke 2026-08-07 18:40:17 -05:00
joshavant 026f4045b7 Revert "fix(protocol): preserve gateway session attribution across node runs"
This reverts commit 735f176b01.
2026-08-07 18:40:17 -05:00
Vincent Koc 735f176b01 fix(protocol): preserve gateway session attribution across node runs 2026-08-07 08:06:01 +08:00
Patrick Erichsen 355c107c09 fix(macos): unblock first-launch gateway setup (#119831)
* fix(macos): stop writing retired config metadata

* fix(macos): guard packaged CLI bootstrap versions

* chore(macos): refresh native i18n inventory

* fix(macos): repair retired metadata before gateway start
2026-08-05 22:25:17 -07:00
Vincent Koc c489a2ddab fix(setup): complete prepared model activation 2026-08-04 11:08:21 +08:00
Patrick Erichsen 00b459a172 fix(macos): restore dashboard frame double-click zoom (#118976) 2026-08-03 15:14:46 -07:00
Peter Steinberger 7ae6a950f6 fix(macos): preserve native command ownership and consent (#118914) 2026-08-03 12:50:11 -07:00
Peter Steinberger 94410b00d0 fix(macos): show gateway auth failures in app status (#118841)
* fix(macos): surface live gateway connection state

* chore(i18n): defer generated locale refresh

* fix(macos): preserve sleeping gateway badge state
2026-08-03 11:52:24 -07:00
Peter Steinberger 21b3904e91 test(macos): deduplicate Claude session catalog fixtures (#118571) 2026-08-03 01:45:12 -07:00
Peter Steinberger fd2fb643b8 test(macos): consolidate node runtime fixtures (#118521) 2026-08-02 23:15:55 -07:00
Peter Steinberger 0c9cc40c02 refactor(macos): consolidate endpoint publication (#118463) 2026-08-02 22:20:40 -07:00
Peter Steinberger c33e9ba05b refactor(macos): consolidate gateway lifecycle state (#118412) 2026-08-02 20:47:50 -07:00
Peter Steinberger d803843cfd test(macos): consolidate Codex catalog fixtures (#118233) 2026-08-02 16:35:01 -07:00
Peter Steinberger 840ed45b86 test(macos): consolidate onboarding probe fixtures (#118218) 2026-08-02 16:02:16 -07:00
Peter Steinberger 7214577cf1 test(macos): fix three races in the bounded process suites (#118196)
BoundedCommandTests and BoundedProcessTests failed nondeterministically:
4/20 runs idle, 7/8 under CPU saturation. Three separate causes.

1. #require inside a retry loop. waitForPID polled through readPID with
   `try?`, but #require records an issue even when its error is swallowed,
   so the first read of a created-but-not-yet-written pid file failed the
   test outright. Added a non-recording pollPID for the polling path and
   kept the recording read as the authoritative final attempt. The two
   single-read call sites now poll too - echo $$ > file creates and writes
   in two steps, so any single read can see a missing or empty file.

2. A 0.1s deadline racing process spawn. BoundedCommand starts its timeout
   concurrently with the spawn, so the deadline also bounded /bin/sh
   starting and publishing its pid; under load the child was killed before
   it ever wrote the file. Wait for the pid while the run is in flight and
   give the child a deadline well clear of spawn cost.

3. A 1s per-process budget on the concurrent fan-outs. Instrumenting the
   deadline showed a stalled run observed all 64 exits at ~3.1s, clustered
   within 100ms of each other - a global stall, not a straggler. Those
   tests assert that no exit is lost during monitor registration, not
   latency, so the timeout should not double as a performance assertion.
   A missed exit still fails: the 50ms pollUntilExit fallback would never
   complete.

Also widened waitUntilGone, since reaping is asynchronous.

No production code changed. Proof: 30/30 idle and 20/20 under full 32-core
saturation, against 16/20 and 1/8 before.
2026-08-02 14:03:57 -07:00
Peter Steinberger b8a6ea12cc refactor(macos): remove the custom menu bar hover card (#118116)
* refactor(macos): remove the custom menu bar hover card

The status item showed two hover affordances at once: the native AppKit
tooltip and a custom SwiftUI panel rendering an "Idle / No recent activity"
card. Keep the native tooltip and drop the custom HUD.

The HUD was the only consumer of the status item's hover tracking, so the
NSTrackingArea and onHoverChanged plumbing in StatusItemMouseRouter goes
with it; click routing is unchanged. WorkActivityStore.lastToolLabel had no
other reader either.

* chore(i18n): refresh native i18n inventory after hover card removal

Deleting HoverHUD.swift shifted the MenuBar.swift line numbers that
apps/.i18n/native-source.json records. Regenerated with
`pnpm native:i18n:baseline`; only line numbers change, no strings added
or removed.

* refactor(macos): drop the orphaned anchored chat panel

Removing the hover card left WebChatManager.togglePanel() without a caller,
and it was the only thing that created the menu-bar-anchored chat popover.
Delete that presentation path: togglePanel/panelHidden, the panel controller
state, WebChatPresentation, WebChatPanel, presentAnchored and its dismiss
monitor, and WindowPlacement.anchoredBelowFrame.

Chat is unaffected as a window - WebChatManager.show() still backs the Dock
menu, --chat and deep links. The status item highlight that tracked chat
window visibility is preserved, renamed to onChatWindowVisibilityChanged
now that no panel exists to confuse it with.

Periphery reports no unused code.

* chore: drop CHANGELOG edit from this PR

AGENTS.md: CHANGELOG.md is release-only and release generation derives it
from merged PRs. Release-note context lives in the PR body instead.

* chore: restore CHANGELOG to the branch base

Correct the previous commit, which restored CHANGELOG.md from current
origin/main and so pulled in an unrelated entry added after this branch
forked. Reset to the merge-base content: this PR now touches no changelog.
2026-08-02 13:10:27 -07:00
Peter Steinberger 5c2559e2d9 test(macos): deduplicate onboarding AI setup fixtures (#118092)
* test(macos): deduplicate onboarding AI setup fixtures

* test(macos): fix fixture handler binding
2026-08-02 11:52:04 -07:00
Peter Steinberger 0335317679 fix(macos): preserve external remote gateway config edits (#118046)
* fix(macos): reconcile external gateway config edits

* refactor(macos): split gateway reconciliation helpers

* chore(macos): refresh native i18n inventory

* refactor(macos): remove obsolete gateway config helper

* test(macos): seed watcher fixtures as canonical

* fix(macos): add gateway config conflict recovery
2026-08-02 11:21:07 -07:00