* 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>
* feat(mac): hand off gateway-owned settings panes to the dashboard
Gateway-config Settings tabs (Channels, Skills, Cron Jobs, Threads,
Instances) now default to a native handoff page with an Open in Dashboard
deep link; a Debug toggle re-enables the legacy native panes. Adds an
openclaw:native-navigate host->shell event with generation-guarded URL
fallback, and lifts the dashboard route map + same-app path validation
into OpenClawKit for future iOS reuse. Exec Approvals stays native: the
Dashboard's host-native policy editor is read-only by contract.
* fix(mac): satisfy native-i18n inventory and type budget
* fix(mac): refresh native i18n source locations
* fix(chat): close disclosures in coalesced HTML
Keep model-authored details closers visible to the shared disclosure contract when CommonMark absorbs them into type-6 HTML blocks across the Control UI and native apps.
* refactor(apps): isolate disclosure unfolding
Keep the native disclosure segmenter below its lint complexity and type-size limits, and refresh the source-owned native i18n inventory after the move.
* fix(apps): align disclosure helper visibility
Keep the extracted same-file helper compatible with Swift access control while leaving its implementation types hidden outside the source file.
* fix(apps): align source replacement visibility
Keep the source replacement helper at the same file-private boundary as the extracted disclosure unfolding types.
* feat(gateway): manage audio and video attachments
* feat(gateway): preserve generated media metadata
* fix(gateway): align seeded managed media
* fix(gateway): scope pending media trust by URL
* fix(gateway): split managed media by trust
* fix(gateway): require terminal media trust unanimity
* fix(gateway): align managed media metadata types
* fix(gateway): refresh managed media contracts
* chore(ci): model managed media test seams
* test(sessions): expect canonical media kinds
* fix(protocol): make Swift drift checks non-mutating
* test(protocol): cover core Swift gateway frames
* docs(protocol): clarify Swift model update flow
* fix(mac): move device auth tokens to shared SQLite state
* fix(mac): fail identity migration when source auth vanishes mid-read
Missing-file tolerance now applies only to the first observation; a disappearance after the auth file was observed fails the migration so the claimed identity survives for retry instead of committing without its credentials.
* fix(ios): validate auth scope UTF-8 encoding
* fix(ios): isolate SQLite auth profiles
* chore(ios): refresh native source inventory
* fix(mac): keep device auth in the shared token table
* test(mac): pin shared-key token cache semantics
* feat(chat): show live run telemetry across clients
* fix(chat): satisfy native validation gates
* fix(chat): settle advertised terminal runs
* fix(android): clear stale run usage on gaps
* chore(i18n): align native source inventory
* fix(chat): reconcile telemetry with current projections
* refactor(chat): keep run state in owner extensions
* chore(i18n): refresh native source inventory
* test(ui): expect persistent working telemetry through streaming
* fix(mac): drop stale native identity claim when key material matches
* fix(mac): acquire stale identity claim before deletion
* fix(mac): park stale identity claim instead of deleting it
Rescue path now contains no destructive unlink: the acquired claim is parked as .stale-<uuid> and validated before any continue path, closing both replacement races review found.
* fix(mac): restore parked claim when the rescue source vanishes
Review round 4: accepted the vanished-source regression (restore before continue so claim-without-source stays importable); rejected serializing the source acquisition - rescue imports nothing and post-rescue source writes follow the standard atomic claim-then-import path (invariant documented inline).
* style(apple): satisfy device identity SwiftFormat
* fix(thinking): fall back instead of erroring on unsupported adaptive level (#109351)
The adaptive level is the auto sentinel (normalizeThinkLevel maps auto ->
adaptive) meaning 'pick an appropriate level', not 'force this exact level'.
Some clients (e.g. the Apple Watch client) send it as a transport default
while the iOS app sends none, so hard-erroring on an unsupported adaptive
override rejected otherwise-valid turns from those clients. Now the auto
sentinel always falls back to a supported level; explicit concrete levels
(e.g. an explicit /think xhigh) still hard-error as before.
Closes#109351
* docs(proof): add real-behavior-proof screenshot + run log for #111301
Captured run of the real get-reply-run.media-only test (101 passed)
showing the adaptive-thinking fallback fix verified.
Co-Authored-By: yuvrajlaptop2008-byte <284412773+yuvrajlaptop2008-byte@users.noreply.github.com>
* fix(ios): inherit Watch chat thinking defaults
Co-authored-by: yuvraj thakur <284412773+yuvrajlaptop2008-byte@users.noreply.github.com>
* chore(ios): sync native i18n inventory
---------
Co-authored-by: yuvrajlaptop2008-byte <284412773+yuvrajlaptop2008-byte@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>