Commit Graph

831 Commits

Author SHA1 Message Date
Peter Steinberger ac71743ca4 fix(apple): load chat media behind reverse-proxy paths (#130755)
Share ticketed media URL resolution between iOS and macOS, retaining the connected gateway encoded context path and transport-owned TLS and credential policy. Remove the duplicate native URL and playback resolvers.

Fixes #130746. Related to Android #129957.
2026-08-27 00:21:17 -07:00
openclaw-mantis[bot] 5e193d50ad chore(i18n): refresh native locales (#130667)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-27 04:21:50 +00:00
Peter Steinberger b581ff0be7 feat(apps): resolve the per-profile accent live on iOS, macOS, and Android (#130598)
* feat(apps): resolve the per-profile accent live on iOS, macOS, and Android

Named follow-up from #130340: native apps now fetch the caller's own
profile accent (users.prefs.get, strict #rrggbb normalization) and prefer
it over the gateway accent, refetching on users.prefs.changed — the
gateway targets that event at the caller's own profile, so clients need no
identity logic. macOS stores it separately from the seam color so
settings-pane config refreshes cannot clobber it, and fetches bypass
ControlChannel.request to avoid degrading the channel on older gateways.
Profile-less and token connections are unchanged. Removes the ios/android
users.prefs.changed allowlist entries now that handlers exist.

* chore(macos): satisfy swiftformat explicit-self on profileAccentHex
2026-08-26 20:01:40 -07:00
Peter Steinberger 789a346fa3 fix(macos): detect screen recording permission after granting access (#130530)
Reuse the existing Peekaboo live permission service so Quick Chat, Settings, screenshot gating, and computer-control diagnostics retain confirmed grants instead of re-reading stale CoreGraphics denials. Passive checks remain consent-gated. Document same-build grant recovery.
2026-08-26 18:20:26 -07:00
Peter Steinberger 64f30c70d7 refactor(macos): automation summaries as hosted cards with clickable job rows (#130502)
* test(macos): add debug menu fixtures and submenu-open capture hooks

* feat(macos): render automation summaries as hosted cards

The Automations/Usage/Devices rows were native items cramming count and
next-run into a fitted title that middle-ellipsized into garbage
('5 …s'). They are now hosted summary cards - title left, compact detail
right, own chevron - which escape the native title budget and pick up
the selection highlight. Automation submenu jobs become hosted rows
(name left, next run right, full name on the accessibility label) that
open the Automations page on click instead of dead disabled text.

* style(macos): swiftformat pass on menu fixture hooks

* test(macos): capture hooks accept CLI arguments

launchctl setenv races open(1), which made screenshot launches flaky;
--debug-open-menu / --debug-menu-fixtures / --debug-probe-rightclick now
work as arguments. The arrow-key submenu navigation never fired inside
the tracking loop and is removed.
2026-08-26 17:11:35 -07:00
Peter Steinberger 99a2434f7b refactor(macos): status menu polish — owned width, quiet header, structured diagnostics, native highlight (#130388)
* fix(macos): stabilize status menu width across hosted and native rows

* fix(macos): format node worker termination status without optionals

* refactor(macos): give status menu width one owner

fittedTitle's hasImage/hasSubmenu/keyEquivalent parameters never changed
the computation - the budget always included image, submenu, and shortcut
chrome - because AppKit aligns those columns across the whole menu, so a
per-item budget is the wrong model. Collapse to one menu-wide budget and
drop the misleading knobs from all 13 call sites.

* refactor(macos): keep the status menu header quiet when healthy

A working system now says nothing: the header renders only operator-
actionable trouble lines (colored text, no status bubbles), the healthy
state is title + toggle + capability strip, and the churn sources that
made the open menu jump are gone - relative check ages, 'health check
running', and the per-tool activity label (the critter icon already
animates work). Session-row kind icons go monochrome; green conveyed
nothing actionable. Healthy title is 'OpenClaw' (or the primary gateway
name with multiple gateways) since the toggle already communicates
active. DashboardGatewayMenuModel.connectionLabel lost its last caller
and is deleted with its test.

* fix(macos): preserve structured node worker diagnostics in status menu

* feat(macos): highlight hosted menu rows from AppKit's selection signal

AppKit paints no selection behind NSMenuItem.view, so hosted session and
device rows had no hover or keyboard highlight. HostedMenuRowView now
draws the native selection material (rounded, emphasized) and flips the
SwiftUI content through the existing menuItemHighlighted environment,
driven by NSMenuDelegate.menu(_:willHighlight:) so pointer and arrow-key
navigation both light up. Submenus get a shared highlight-only delegate;
the controller's root-menu guards keep open/refresh paths unaffected.

* refactor(macos): drop the manual Open Canvas action

Canvas panels are agent-opened; a manual open action was noise. The
Allow Canvas capability tile stays - that is the permission. Removes the
menu action, the dock-menu item, and the now-orphaned
AppNavigationActions.toggleCanvas.

* fix(macos): clear hosted submenu selection when the submenu closes

AppKit sends no willHighlight(nil) on submenu close, so a hosted device
row selected there reopened still lit. The shared highlight delegate now
resets its menu's hosted rows in menuDidClose; regression covers the
close cycle.

* style(macos): apply swiftformat to highlight delegate
2026-08-26 14:49:57 -07:00
Peter Steinberger f0ab89ed54 fix(macos): drain SSH tunnels before app quit (#130421) 2026-08-26 14:48:35 -07:00
Peter Steinberger 71a7283792 fix(macos): own process startup and tunnel retirement (#130332)
Replace the cancellable one-shot startup stream with a replayable result. Join process cleanup and durable SSH receipt retirement before admitting a replacement tunnel, and keep stale callers fenced across actor suspension.
2026-08-26 13:25:46 -07:00
Dallin Romney 972b0c4b84 chore(i18n): refresh native locales (#130270) 2026-08-26 12:25:53 -07:00
Peter Steinberger 4cfadd6fa2 fix(macos): onboarding setup rows ignore clicks across their blank areas (#130273) 2026-08-26 11:20:47 -07:00
Peter Steinberger 2b0da0e193 refactor(macos): single-owner hybrid status menu with live session cards and exec approvals (#130041)
* test(macos): add OPENCLAW_DEBUG_OPEN_MENU screenshot hook

* feat(macos): add live execution approval queue

* refactor(macos): replace menu injectors with owned status menu

* fix(macos): keep unconfigured menu header calm

* fix(macos): route status-item right-clicks through a local event monitor

NSControl's send-action mask ignores right mouse buttons, so the previous
sendAction(on: [.rightMouseUp]) wiring never fired and the menu was
unreachable by pointer. A local monitor now owns pointer routing (left =
dashboard, right = menu) — the same mechanism the shipped
StatusItemMouseRouter used — and menuWillOpen gained the re-entrancy
guard the old injector carried, since reconciling tracked rows can
re-enter the callback without a close.

* chore(i18n): refresh native inventory for status menu strings

* chore(macos): remove menu-refactor dead code

Periphery flagged the orphans the status-menu refactor left behind: the
ExecApprovalQuickMode enum and AppState's entire quick-mode read/retry
surface (its only consumer was the deleted menu picker; the Settings
pane owns exec-approval policy UI), SessionMenuLabelView,
TrackingAreaSupport, NodeMenuMultilineView, UpdateStatus.disabled, and
two fixture-only initializers. StatusMenuController.stop() is now wired
into applicationWillTerminate. The menu-highlight environment key moved
from the deleted view file into MenuItemHighlightColors.

* chore(macos): fix status-menu lint style and refresh i18n inventory

* fix(macos): converge approval cards after losing a resolution race

The status-menu queue and the modal prompter intentionally share the
gateway approval event stream: the gateway resolves each approval
exactly once, the resolved broadcast removes the card, and the modal
stays the active presentation owner while the menu is the passive,
ambient one. What was missing: when the menu's resolve loses the race
(modal or another client answered first), the gateway rejection left a
zombie card if the resolved event was dropped. Resolve failures now
re-list from the authoritative queue. Regression test simulates the
race at the socket boundary and fails pre-fix.
2026-08-26 06:16:16 -07:00
RoboClaw 44d60a29e6 fix: preserve unread reminder for open sessions (#129386)
* fix: preserve manual unread markers in open sessions

* fix: distinguish explicit session reads

* fix(ui): gate unread contract on gateway capability

* perf(ui): keep server capabilities out of startup bundle

* test(gateway): keep agent fixtures roster-consistent

* fix(sessions): preserve legacy read compatibility

* test(gateway): type agent fixture configs

* fix(ui): remove unread gateway fallback

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>

* test(infra): avoid fixed SSH tunnel port

* fix(ui): acknowledge unread after history commit

* docs: clarify unread upgrade boundary

* test(ui): drive mobile session menu by tap

* fix(ios): remove stale read reconciliation call

---------

Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-26 05:04:39 -07:00
Peter Steinberger f26c053605 fix(macos): recover denied speech recognition permissions (#129950) 2026-08-26 01:02:54 -07:00
Peter Steinberger d2360e4a1c fix(macos): surface unsaved gateway settings during onboarding (#129959) 2026-08-26 00:41:12 -07:00
Peter Steinberger f991a984e2 fix(macos): preserve Gateway service recovery hints (#129943) 2026-08-26 00:35:25 -07:00
Peter Steinberger af9b0c7616 fix(macos): keep the node channel alive and visible when the node-host worker cannot start (#129925)
* fix(macos): keep the node channel alive and visible when the node-host worker cannot start

A node-host worker that exited before its ready manifest never notified the
retry policy, so the coordinator respawned the broken CLI forever and the
whole node channel silently never dialed the gateway. Startup exits now
consume the crash retry budget and carry the worker's stderr into the start
error; every non-transient worker failure degrades the connect to native
capabilities instead of aborting it; and the menu bar surfaces the recorded
node-channel state with the concrete reason.

* fix(macos): render node-channel status as a top-level menu view

The native-menu extra style flattens multi-view Toggle labels to their first
Text, so status sublines inside the label never rendered — the original
'zero indication' report. Top-level menu views render (exec-approval error
pattern).
2026-08-26 00:02:52 -07:00
Peter Steinberger f61ae1193d fix(macos): surface node service recovery commands (#129874) 2026-08-25 22:32:01 -07:00
Peter Steinberger 58bb40c99b fix(macos): show progress when retrying an existing AI connection (#129863) 2026-08-25 22:29:33 -07:00
Peter Steinberger 51ee692698 fix(macos): confirm close while verifying an existing AI connection (#129790) 2026-08-25 20:17:08 -07:00
Peter Steinberger e4a9407693 fix(macos): reject unsuccessful service process exits (#129615) 2026-08-25 19:39:22 -07:00
Peter Steinberger 8f2253497e fix(macos): cancelled Talk sessions can spin at full CPU (#129682)
* fix(macos): stop cancelled Talk silence monitors

* fix(macos): reuse cancellable periodic task owner
2026-08-25 18:26:43 -07:00
Josh Avant 1c37c8cdc7 fix(exec): scope reusable approvals to their working directory (#129636)
* fix(exec): bind durable approvals to working directory

* chore(apps): refresh native string inventory

* test(node-host): preserve prepared working directory

* fix(exec): use shared path safety facade

* fix(exec): revalidate approved directory identity
2026-08-25 18:24:14 -07:00
openclaw-mantis[bot] fe4554ade4 chore(i18n): refresh native locales (#129631)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-25 23:13:58 +00:00
Peter Steinberger f4d067ec07 fix(macos): paused Gateway setup loses recovery after CLI installation (#129566)
* fix(macos): keep paused gateway onboarding recovery visible

* fix(macos): preserve native onboarding translation inventory
2026-08-25 13:20:43 -07:00
Sasan e9620fba9d fix(gateway): usage.status no longer waits on provider HTTP (#121799)
* fix(gateway): refresh provider usage asynchronously

* fix(ui): report a stalled provider-usage refresh on Model Providers

The page observed the incomplete-usage marker but discarded the exhausted
outcome, so once the retry budget was spent it rendered ordinary provider
cards with no usage and no explanation — indistinguishable from providers
that report no usage at all. Keep the outcome and render the warning the
Usage page already owns, reusing usage.providerUsage.stalled rather than
minting a Model Providers key so no locale baseline churns.

A user-initiated refresh now restarts the retry budget. The notice tells the
operator to refresh, so the button has to hand back attempts to spend; only
the forced path resets it, or the budget could never exhaust.

Also fixes tsgo:core:test on the current head: createStore's inferred literal
had no usageStats, so the run-bookkeeping case could not stamp it, and
view.test.ts needed the new prop.

Closes the ClawSweeper P2 at model-providers-page.ts:169-175.

* fix(ui): keep the stalled usage notice when usage.status starts rejecting

loadModelProvidersData turned a rejected usage.status into providerUsage:
null, which the page read as a completed load. observe(false) then reset the
retry budget and cleared the stalled callout, so a permanently broken usage
endpoint rendered as ordinary cards with no usage and no explanation — the
same silent failure the callout was added to prevent. The reset also fired
mid-cycle: one incomplete response followed by one rejection restarted the
budget, so the notice could be deferred indefinitely.

Record the failure at its producer instead of inferring it downstream. A null
providerUsage also means "not loaded yet", and no caller can tell the two
apart, so load.ts now reports providerUsageFailed explicitly and the page
treats a failed read as unresolved rather than resolved-empty.

Found by a Codex review of 417d43b65d.

* revert(gateway): drop the opportunistic model-catalog fast path

It broke two chat.history tests on main — both assert the cold catalog loader
runs exactly once, and reading the prepared snapshot first means it never does.
checks-node-compact-small-10 was red for that reason.

The change was a separate-surface latency fix that this PR picked up in passing,
and the body already offered to split it. Dropping it is the honest resolution:
rewriting main's assertions to accommodate a drive-by optimization would trade
one concern's proof for another's convenience. optional-model-catalog.ts,
server-model-catalog-auth.ts and their test return to the merge-base.

This PR is now only the usage.status non-blocking contract and its clients.

* fix(usage): preserve incomplete retry state

* perf(ui): keep usage capability startup-neutral

* fix(ui): restore provider usage retry convergence

* fix(usage): restore retry and cache invariants

* fix(usage): stabilize provider convergence

* test(ui): exercise provider recovery path

* test(ui): remove stale usage route fixture field

* fix(macos): show provider usage errors

* fix(macos): bound usage retries per menu open

* fix(macos): end usage retries on menu close

---------

Co-authored-by: Josh Lehman <550978+jalehman@users.noreply.github.com>
2026-08-25 13:20:10 -07:00
Peter Steinberger 55aa0480eb fix(macos): honor remote gateway choice during onboarding (#129572) 2026-08-25 13:16:38 -07:00
Peter Steinberger 482fbdc161 fix(macos): prefer supported version-manager Node runtimes (#129564) 2026-08-25 12:39:44 -07:00
Peter Steinberger d050cf956b fix(macos): confirm closing onboarding during API key verification (#129447) 2026-08-25 10:09:21 -07:00
Peter Steinberger 830700d04b fix(macos): reject failing Gateway runtime probes (#129453) 2026-08-25 09:45:39 -07:00
Peter Steinberger 2a33d749e5 fix(macos): keep onboarding progress aligned with recommended setup (#129435) 2026-08-25 09:31:07 -07:00
Peter Steinberger 6ad7915c05 fix(macos): expose channel account failures in settings (#129400) 2026-08-25 08:55:22 -07:00
Vitor Cepeda Lopes de969db2c3 fix(macos): make OpenClaw settings pane responsive (#128177) 2026-08-25 01:27:34 -07:00
Vitor Cepeda Lopes b71a09fd8a fix(macos): return paired-node Codex catalogs without native supervision (#126811)
* fix(macos): route Codex catalog to plugin worker

* fix(macos): freeze Codex catalog ownership per invoke

---------

Co-authored-by: Josh Lehman <550978+jalehman@users.noreply.github.com>
2026-08-24 16:24:27 -07:00
openclaw-mantis[bot] 61bc753da3 chore(i18n): refresh native locales (#128759)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-24 08:21:09 -07:00
Peter Steinberger 33b10fe4aa fix(macos): user accent from Control UI is clobbered by config snapshots and never live-updates the chat window (#128703)
* fix(macos): honor user accent precedence in config snapshot and live-update chat window

The Control UI user accent (ui.prefs.accent) landed in #128432/#128577 with
precedence user accent -> operator ui.seamColor -> theme default, and the
gateway's talk.config payload already applies it. The macOS app had two gaps:

- ChannelsStore.applyUIConfig read raw ui.seamColor from the config.get
  snapshot and clobbered the user accent set from talk.config depending on
  arrival order. It now resolves ui.prefs.accent ?? ui.seamColor via a
  testable helper mirroring the gateway precedence.
- The native chat window read AppStateStore.seamColorHex once at window
  construction, so accent changes never live-updated. MacChatSurface now
  reads the @Observable store in body, deleting the one-shot userAccent
  plumbing.

Docs: configuration-reference.md documents the precedence for native-app
chrome. Regression test fails pre-fix (snapshot returned the operator seam
color instead of the user accent).

* fix(macos): refresh config from gateway config.changed events

Addresses the review finding that no macOS consumer turned the gateway's
hash-only config.changed broadcast into refreshed shared state, so a
Control UI accent change never reached an open native chat window while
the app ran. ChannelsStore now subscribes to gateway pushes and re-fetches
config.get on config.changed, reconnect snapshots, and sequence gaps.

The refresh applies non-force so an in-progress local settings draft wins
(the gateway rejects stale-hash writes anyway). The in-flight reload queue
gains a closed pending level (none/refresh/force) so a refresh arriving
during a load is coalesced instead of dropped, and a requeued refresh
cannot clobber a dirty draft the way the old boolean force-pending did.
2026-08-24 05:37:59 -07:00
Peter Steinberger 234df15a6d chore: refresh dependencies after seven-day cooldown (#128414)
* build(deps): refresh dependencies after cooldown

Apply dependency, toolchain, action, image, and exact tool updates released by the inclusive 2026-08-16 seven-day cutoff. Adapt owner boundaries for the resulting CUA, logging, Teams, Markdown, native, and test-harness contract changes while retaining versions blocked by upstream compatibility constraints.

* fix(ui): align markdown renderer env typing

* fix(deps): align postcss and mistral peer contracts

* fix(deps): repair refreshed dependency contracts

* fix(deps): retain tslog startup budget

* fix(ci): verify Android tools with SHA-256

* fix(ci): fence Android SDK cache version
2026-08-24 03:01:54 -07:00
Peter Steinberger 554fb212c9 fix(nodes): report camera positions the hardware actually reached (#128595)
* fix(nodes): report camera positions the hardware actually reached

`camera.ptz.control` returned a position it never verified, and
`camera.snap`/`camera.clip` could capture from a camera the caller did
not ask for. Both told the agent an action succeeded when it had not.

PTZ read its post-write status from the same UVC connection that issued
the write. Gimbal cameras echo a pending setpoint back on the writing
connection, so the check confirmed its own write. Those cameras also
service camera-terminal controls only while a video stream is active, and
no capture session was held, so writes could be discarded entirely while
reads returned phantom values.

Hold a frame-discarding capture session across every PTZ operation, close
the writing controller, and verify through a fresh connection against each
axis's advertised resolution. An axis that misses now reports through the
existing CAMERA_PTZ_PARTIAL outcome with observed versus requested values
and what to check next.

Apple camera selection accepted an explicit deviceId and silently fell
back to the default camera when nothing matched. Linux already rejected
this, and CameraPTZService already rejected it in the same app. Centralize
exact selection in OpenClawKit so macOS and iOS both fail with a
device-not-found error; the facing/default fallback stays only for
requests that supply no deviceId.

camera.ptz.status now activates the camera and its privacy indicator for
the duration of the read. That is the cost of returning real positions.

* fix(nodes): tell callers how to recover from an unknown camera ID

Device IDs change when cameras are reconnected, so a bare
device-not-found error dead-ends the caller. Both Apple errors and the
docs now point at camera.list for current IDs.

Addresses the ClawSweeper P2 finding on #128595.
2026-08-24 01:56:12 -07:00
Peter Steinberger 1299ced0c2 fix(macos): escape all login LaunchAgent plist paths (#128378) 2026-08-23 14:42:19 -07:00
Peter Steinberger a85db8cea7 fix(macos): resolve the onboarding install prompt when the gateway is already running (#128273)
Fixes #128194.

Local-mode onboarding has two rightful actors on the CLI page: the page's
own install flow, which may open an install-target prompt on unreleased
builds, and the connection-mode commit, which starts the gateway through
ConnectionModeCoordinator the moment the user picks This Mac. When the
gateway comes up on its own (dev-root builds, or an externally attached
gateway), AI setup auto-connects and finish() runs — but close() was
silently ineffective because AppKit ignores NSWindow.close() while a sheet
is attached. The result, reproduced live with os_log instrumentation: a
completed onboarding (dashboard open, onboardingSeen set) with a zombie
onboarding window showing a dead CLI page and a stale channel-choice sheet.

Two coupled fixes. OnboardingController.close() now ends any attached sheet
before closing, so completion always tears the window down. And a running
local gateway now resolves a pending install prompt directly: a new tested
static (shouldResolveInstallPromptForRunningGateway) extends the existing
gateway-status revise path to the choosingTarget phase, marking the step
installed and dismissing the moot sheet; runCLIInstall returns quietly in
that case instead of writing a cancellation over a resolved step. Genuine
declines keep the cancelled status.
2026-08-23 09:46:16 -07:00
Peter Steinberger bf91e00d36 fix(macos): reject invalid gateway ports before tunnel setup (#128260) 2026-08-23 09:21:05 -07:00
zhilong1115 df7e6f1c44 macOS: surface realtime Talk settings (#118505)
* feat(talk): link realtime settings surfaces

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* fix(talk): clear forced routing for GPT-Live relay

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-23 08:34:23 -07:00
Vincent Koc 000db97c82 feat(talk): add macOS realtime Gateway relay (#128204)
* feat(talk): add macOS realtime relay transport

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* feat(talk): integrate realtime relay with macOS Talk

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* fix(talk): keep realtime bootstrap config redacted

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* fix(talk): surface failed native fallback

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

* test(talk): inject deterministic relay capture

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>

---------

Co-authored-by: Zhilong Zheng <zhengzhilong1115@gmail.com>
2026-08-23 07:30:30 -07:00
Chris Allbritton 3a50b7a448 fix(macos): restore Settings pane scrolling (#118831)
* fix(macos): restore Settings pane scrolling

* test(macos): stabilize Settings dashboard handoff check

* test(macos): scope Settings layout regression

---------

Co-authored-by: Vitor Cepeda Lopes <vitor@vitorcepedalopes.com>
2026-08-23 04:48:51 -07:00
Peter Steinberger 47436e447e fix(macos): attach the onboarding CLI install prompt to the window (#128183)
* fix(macos): attach the onboarding CLI install prompt to the window

On an unreleased build, the onboarding CLI page resolved its install target
through NSAlert.runModal() — a detached app-modal panel that is absent from
the app's AX window list and freely covered by system permission dialogs.
Live repro: with two TCC prompts stacked over it, the main thread sat parked
in runModal for 30+ minutes while the page showed an active "Install
OpenClaw" spinner, the close button was disabled, and busyReason claimed an
install was in flight — before the user had chosen anything. A spinner that
means "answer a dialog you cannot see" is a silent-failure trap.

The prompt (both the confirm-stable alert and the channel chooser) is now a
sheet attached to the onboarding window via beginSheetModal, so it stays
z-ordered with the window and AX-visible. The busy state is honest: a new
.choosingTarget phase renders the install row as pending instead of running,
and installingCLI/close-disabled/busyReason only engage after a target is
actually chosen. Non-onboarding callers (checkAndPromptIfNeeded) keep
runModal by passing no window. All alert text and button order unchanged.

* style(macos): wrap sheetPresentationWindow property body
2026-08-23 04:09:08 -07:00
Peter Steinberger 3cb52f4bb8 fix(macos): preserve externally owned attach-only gateway (#128134) 2026-08-23 02:00:39 -07:00
ClawSweeper 7d95cff39d fix: macOS onboarding waits for Gateway restart (#127713)
* fix(onboarding): wait for inference gateway restart

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* fix(onboarding): preserve custodian handoff after restart

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* refactor(macos): share activation restart finalization

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* style(macos): format restart reconciliation

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* fix(macos): compile restart finalization

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* test(macos): sequence onboarding restart proof

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* test(macos): finish onboarding after activation

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>

Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>

* test(macos): reuse managed restart proof

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>

Co-authored-by: Hannes Rudolph <49103247+hannesrudolph@users.noreply.github.com>

* test(macos): assert receipt before handoff cleanup

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>

Co-authored-by: Hannes Rudolph <49103247+hannesrudolph@users.noreply.github.com>

* fix(onboarding): keep restart verification bounded

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>

Co-authored-by: Hannes Rudolph <49103247+hannesrudolph@users.noreply.github.com>

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: hannesrudolph <49103247+hannesrudolph@users.noreply.github.com>
2026-08-22 15:51:04 -07:00
Peter Steinberger 8b5a02cbf6 fix(mac): serialize persistent node service lifecycle operations (#127732) 2026-08-21 18:17:30 -07:00
Peter Steinberger 51649aa1fa fix(mac): keep local gateway failures on their active route (#127723) 2026-08-21 17:59:35 -07:00
Peter Steinberger ee468b8038 fix(macos): prevent stale port sweeps from killing remote tunnels (#127665) 2026-08-21 15:42:39 -07:00
Peter Steinberger 1257279de6 fix(macos): suppress SIGPIPE on process pipe write ends (#127666)
Writing to a pipe whose reader has already exited raises SIGPIPE, which
kills the whole process instead of throwing. MacNodeHostWorker already
guarded its stdin pipe with F_SETNOSIGPIPE; the codex App Server client
and the MLX TTS helper transport did not, so a child exiting mid-write
could take down the app. Suppressing the signal exposed that an
undelivered App Server request write was reported as appServerUnavailable
even though the frame was provably never sent, so it now requeues once
onto a fresh child instead of failing the caller.

Test-side pipe write ends whose readers are spawned children (or a
readability handler that can close the pipe mid-test) get the same
suppression so a racing reader exit fails the assertion instead of
killing swiftpm-testing-helper with signal 13, which is what caused the
macos-swift CI lane's intermittent unrelated-test crashes (e.g. PR
#126559, run 32341197738 job 96340683947).
2026-08-21 15:40:50 -07:00