Commit Graph

4369 Commits

Author SHA1 Message Date
Peter Steinberger
8020dd3e08 fix(reef): discover trusted peers as conversations (#109905)
* fix(reef): discover trusted peer conversations

* test(reef): document temporary state cleanup

* test(gateway): include conversation discovery in method order

* chore: leave changelog to release automation

* fix(gateway): preserve configured conversation discovery

* fix(gateway): validate turns before session binding

* fix(gateway): preserve directory conversation identity
2026-07-17 13:55:30 +01:00
WhatsSkiLL
4d3b18811e feat(android): add Wear real-time Talk controls (#109483)
* feat(android): add Wear real-time Talk controls

* fix(android): satisfy Wear Talk CI checks

* fix(talk): remove unused client language parameter

* fix(android): harden Wear realtime Talk routing

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* chore(android): refresh Wear Talk metadata

* chore(android): align native i18n baseline

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 13:46:05 +01:00
Peter Steinberger
bf754b8a34 feat: align native macOS chat with the web chat capability set (#109712)
* feat(macos): wire sessions manager, assistant trace, talk, voice notes, and Listen into native chat

* feat(clients): add input history, reply quoting, and per-session drafts to native chat composer

* fix(clients): capture TTS server lease before gateway check and dedupe restored input-history entries

* docs(clients): document reply-chip consume parity with web accepted-send semantics

* fix(clients): retire sent-text recall stash and keep recall markers stable under prepends

* test(clients): wait for outbox restore before asserting live-send paths

* docs(clients): note cross-session outbox flush scheduling contract

* chore(clients): split oversized chat files to satisfy SwiftLint length caps

* chore(i18n): sync native app i18n inventory for new chat strings

* chore: retrigger ci

* chore(i18n): translate new chat strings and regenerate Apple catalogs

* chore(i18n): regenerate Android localization resources for new chat strings

* test(clients): await lifecycle cleanup before modeling replacement gateway traffic

* chore(clients): split invoke timeout helper to satisfy SwiftLint length cap

* chore(clients): drop unused OpenClawProtocol import from invoke timeout split
2026-07-17 13:44:48 +01:00
Peter Steinberger
8bd78de5da test(macos): fix timestamp-anchoring flakes in chat haptics and stream replay tests (#109954)
Both flakes (CI run 29573675642, macos-swift) were the same mechanism:
fixture timestamps anchored to wall clock at test start, raced against
the optimistic user-echo timestamp captured later at send time. The
pending-run drain (clearPendingRunIfAssistantMessagePresent ->
assistantHapticEvent(after:)) only matches assistant rows timestamped
at or after the user echo, and the fake transports' default
waitForRunCompletion returns .unavailable, so this comparison is the
only drain path in both tests.

ChatHapticsTests "durable assistant failure fires run failed": the
durable failure row was stamped test start + 1000ms. Under CI load a
>1s stall between fixture creation and send() left the row permanently
older than the user echo, so .runFailed never fired for either
parameterized case. Fix: HapticsTestTransport now takes a history
closure and the test stamps the failure row at requestHistory time,
which is always post-send by event order.

ChatStreamReplayTests "reconnect mid-run converges via history
refetch": the completed transcript rows were stamped test start +
100/900ms; the scripted payload has no inFlightRun/sessionInfo, so the
foreground refetch cannot drain and only the pending-run owner's
timestamp comparison can. Bootstrap plus send taking >900ms made the
assistant row older than the echo and the run never drained. Fix:
anchor the reconnect transcript to a timestamp captured after the send
completed.

Proof: injecting a 1.5s/1.2s stall before send reproduced both CI
failures exactly (timeout after ~16.5s/16.2s, both haptics cases
failing); with the fixes the tests pass even with the stalls injected.
Full ChatHapticsTests + ChatStreamReplayTests suites green; both fixed
tests stressed 10x with zero failures.
2026-07-17 13:35:54 +01:00
WhatsSkiLL
6bd9e5f158 fix(android): keep composer media with its chat (#109200)
* fix(android): keep composer media with its chat

* fix(android): retry shared media after chat switch

* fix(android): bind composer media synchronously

* fix(android): bind composer state to chat owners

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* chore(android): keep release notes app-scoped

* refactor(android): reuse localized outbox failure text

* style: format web push state migration

* style: format google meet setup test

* fix(android): restore composer build compatibility

* chore(android): sync native i18n inventory

* fix(android): satisfy composer warning gate

* fix(android): align composer ownership tests

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* test(android): align durable composer assertions

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* test(android): bound outbox scheduler advances

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* fix(ci): recalibrate status startup memory budget (#109887)

* fix(android): admit live composer payload

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* fix(android): refresh native i18n inventory

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* fix(android): bound composer admission receipts

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* fix(android): preserve owner-bound async state

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* fix(android): bind composer drafts to saved state

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-17 13:05:38 +01:00
Peter Steinberger
c3f5526285 fix(desktop): use native system notifications (#109901)
* fix(desktop): use native system notifications

* fix(desktop): declare notification dependency MSRV

* fix(desktop): select notification backends per platform
2026-07-17 12:24:46 +01:00
Peter Steinberger
6ac15970a7 feat(onboarding): unified empty-state with provider icons, websites, and recommended installs (#109681)
* feat(onboarding): unify setup recommendations

* fix(control-ui): proxy model setup icons

* fix(onboarding): refresh landing artifacts

* chore(ui): sync translated i18n catalogs

* chore(ui): keep generated locale artifacts on the refresh workflow
2026-07-17 01:01:06 -07:00
Peter Steinberger
1859cdb231 feat(mac): Quick Chat — global-shortcut floating composer for the main session (#109720)
* feat(mac): add Quick Chat floating composer with global shortcut

- Spotlight-style non-activating key panel on Option+Space (KeyboardShortcuts
  3.0.1 exact-pinned, recorder row in Settings -> General) plus a menu bar item
- shows the main-session agent identity via agent.identity.get with a
  'main session' chip; Return sends via chat.send reusing the idempotency key
  on ambiguous retries; Cmd+Return also opens full chat; Shift+Return newline
- targeted permission strip (notifications/accessibility/screen recording)
  with a scoped 1s status poll while visible; grant flow keeps the bar alive
  and avoids PermissionMonitor's AppleScript probe
- extract shared ChatSendStatus acceptance mapping; TalkModeRuntime adopts it
- rename anchored-panel 'quick chat' wording to 'compact chat panel'; docs

* chore(mac): regenerate docs map and native i18n inventory for Quick Chat

* ci: retrigger checks after stalled push event

* chore(mac): refresh native locale artifacts for Quick Chat strings

* chore(android): regenerate locale strings for refreshed shared translations
2026-07-17 01:00:45 -07:00
Peter Steinberger
765bb37364 feat(setup): stream provider prepare progress to every surface (#109764)
* feat: stream provider preparation progress

* fix(android): refresh gateway method constants
2026-07-17 00:55:04 -07:00
Peter Steinberger
a2ec3f6904 refactor: separate external conversations from local sessions (#109411)
* feat: separate external conversations from sessions

* test: cover conversation tool authorization

* chore: refresh session schema baseline

* fix: persist effective conversation delivery text

* fix: bind conversation identity to delivery target

* fix: preserve pending conversation deliveries

* fix: make conversation delivery outcomes synchronous

* refactor: make conversation delivery durable

* fix: harden durable conversation retries

* fix: close durable conversation pre-send gaps

* fix: terminally reject invalid conversation deliveries

* refactor: route external conversations through gateway

* fix: namespace conversation delivery queue intents

* refactor: remove obsolete transcript replacement path

* test: prove conversation delivery v10 migration

* test: keep conversation action mock typed

* fix: clear conversation refactor CI gates

* test: align Reef delivery coverage

* chore: refresh Android conversation strings

* fix: harden external conversation state

* fix: close conversation race edges

* fix: preserve conversation delivery identity

* fix: replay durable conversation operations

* fix: unify agent schema at version 11

* chore: move release note context to PR

* fix: make required queue persistence force core delivery

* chore: refresh plugin SDK baseline
2026-07-17 00:09:51 -07:00
Peter Steinberger
b42cd82217 test(apple): stabilize OpenClawKit suite (#109688) 2026-07-16 23:52:40 -07:00
Peter Steinberger
399345e1bb feat: report Pi and OpenCode in guided setup (#109624)
* feat(onboarding): detect Pi and OpenCode CLIs

* fix(onboarding): clarify Pi and OpenCode readiness
2026-07-16 22:35:33 -07:00
ooiuuii
7641aa80c2 fix: plugins update rewrites config for install-record-only updates (#98422)
* Avoid config rewrites for plugin index updates

* Preserve config freshness for records-only plugin updates

* Validate records-only plugin update config

* fix(plugins): reload index-only updates

Co-authored-by: luyifan <al3060388206@gmail.com>

* chore(protocol): refresh generated clients

Co-authored-by: luyifan <al3060388206@gmail.com>

* fix(gateway): wire plugin refresh handler

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 21:38:45 -07:00
Peter Steinberger
a0fac37f14 feat: add OpenAI Video Talk (#109579)
* feat(talk): add OpenAI Video Talk

Co-authored-by: wuxuanshu <1064076525@qq.com>

* fix(protocol): refresh native Talk capability model

* chore(i18n): refresh control UI fallback baseline

* chore(i18n): defer locale refresh to workflow

---------

Co-authored-by: wuxuanshu <1064076525@qq.com>
2026-07-16 21:25:09 -07:00
Peter Steinberger
8d5e39afcd feat(android): add Wear OS companion (#109433)
* feat(android): add Wear OS companion

Co-authored-by: Sebastian Schubotz <git@sibbl.net>

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* style(android): format Wear release gate test

* test(android): cover Wear release CI contracts

* test(android): import Wear JSON fixture type

* fix(android): harden Wear proxy event actor

* test(android): stabilize Wear proxy actor tests

* test(android): isolate Wear proxy actor lifecycles

* test(android): own Wear actor dispatchers

* test(android): use real time for Wear actor tests

* test(android): own Wear actors in test scope

* test(android): stop Wear actors explicitly

* test(android): drain Wear actor cancellation

* test(android): isolate Wear actors from test scheduler

* test(android): inject Wear test clock

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-07-16 20:59:29 -07:00
Patrick Erichsen
55bb6cfa2e feat(control-ui): proxy plugin catalog icons (#109510) 2026-07-16 20:31:27 -07:00
Peter Steinberger
00a6ecb906 feat(ui): always-on chat title bar with inline rename and workspace actions (#109422)
* feat(gateway): add sessions.files.reveal to open a session workspace on the gateway host

Resolves the session's workspace root server-side (same resolution as
sessions.files.list), refuses exec-node and cloud-worker placements, and
opens the directory with the platform opener. The opener helpers move out
of config.ts into a shared open-path module that config.openFile now uses.

* feat(ui): always-on chat title bar with inline rename and workspace menu

Every chat pane now renders its header: click the session title to rename
it inline (Enter commits via sessions.patch, Escape cancels), a workspace
chip names the session's checkout with reveal/copy-path/copy-branch
actions, and cloud-worker sessions show a globe. The single-pane floating
toggle cluster and the transcript's reserved titlebar drag band fold into
the header, which keeps native macOS window dragging.

* fix(ui): resolve title-bar session aliases and clear the collapsed-nav overlay

Live verification found two gaps: route aliases like ?session=main showed
the generic key-derived title instead of the session's label (resolve via
hello defaults + key equivalence, matching the pane), and the floating
sidebar-expand pill overlapped the header title on plain web while the nav
was collapsed (52px inset, mirroring the native-shell clearances).

* fix(ui): keep the protocol schema layer out of the Control UI startup bundle

The title-bar change made session-row-badges runtime-import the
gateway-protocol barrel for one classifier, dragging typebox and every
schema into startup JS (395 KiB gzip vs the 370 KiB budget). The placement
vocabulary now lives in a dependency-free session-placement-state module:
the schema union derives from it, the barrel re-exports it, and the UI
deep-imports it (startup back to 361.8 KiB).

* fix(gateway-protocol): keep SessionPlacementStateSchema statically typed

Type.Union over a mapped array loses tuple inference and collapses Static
to never; the literal list stays explicit with a compile-time guard tying
it to the shared SESSION_PLACEMENT_STATES vocabulary.

* chore(protocol): regenerate Swift/Kotlin bindings for sessions.files.reveal

* chore: narrow new exports flagged by the deadcode gate

* chore(i18n): leave generated locale artifacts to the locale-refresh workflow

The generated-artifact isolation gate (067635cb51) landed mid-flight;
source PRs now carry en.ts only.
2026-07-16 20:04:12 -07:00
Peter Steinberger
28a3540f32 feat: add native inline widget support (#109212)
* feat: add native inline widget support

* refactor: simplify plugin surface refresh

* fix: preserve plugin surface refresh API

* fix: reload widgets after WebKit termination

* fix: harden native widget refresh

* fix: bound native widget recovery

* docs: defer native widget release note

* chore: refresh native i18n inventory

* fix: harden native widget delivery

* refactor: simplify native widget API surface

* fix: serialize native widget capability refresh

* fix: harden native widget recovery

* fix: recover native widget capabilities

* style: format widget refresh role selection

* fix: correct widget refresh formatting

* fix: harden cross-platform widget recovery

* fix: bind widget trust and recovery to routes

* chore: refresh native i18n inventory

* chore: regenerate Android gateway protocol

* test: remove unused release workflow read
2026-07-16 19:24:41 -07:00
Peter Steinberger
c6ebd6be34 feat(watch): inbox mascot with Always-On-safe rendering (#109365)
The watch inbox's empty and waiting surface gets a 72pt Clawd: sleepy
(nightcap and all) when nothing is waiting, thinking while the watch
waits for iPhone sync, attentive when an approval needs a decision.
The Always-On display renders a static pose so the animation loop
never runs dimmed, and the active loop is throttled to 15fps for
battery. The shared mascot gains a defaulted minimum frame interval;
mascot sources compile directly into the watch target following the
TalkWaveformView pattern.
2026-07-16 17:47:07 -07:00
Peter Steinberger
167a8ef20a fix(onboarding): harden fresh local startup and activation (#108764)
* fix(macos): preserve gateway during fresh setup

* fix(macos): validate reusable gateway service

* chore(macos): sync native i18n inventory

* fix(macos): preserve latest gateway service request

* test(macos): isolate gateway port concurrency coverage

* fix(macos): recover gateways after failed readiness

* fix(macos): repair wedged gateway listeners

* fix(macos): bound gateway startup probes

* chore(macos): sync native i18n inventory

* fix(onboarding): activate verified inference immediately

* fix(macos): isolate readiness failure generations

* chore(macos): refresh native i18n inventory

* fix(macos): serialize gateway service lifecycle

* fix(macos): sequence gateway startup persistence

* fix(macos): close gateway readiness races

* fix(macos): publish recovered gateway state

* fix(macos): make gateway readiness generation-safe

* chore(macos): refresh native i18n inventory

* fix(macos): preserve gateway endpoint identity

* fix(macos): refresh gateway ownership after attach

* fix(macos): distinguish transient gateway readiness

* refactor(macos): split gateway readiness lifecycle

* chore(macos): refresh native i18n inventory

* chore(release): keep changelog release-owned
2026-07-16 17:24:53 -07:00
Peter Steinberger
87bb99d673 feat(android): add Wear OS phone proxy (#109341)
* feat(android): add Wear proxy protocol

Introduce a bounded, versioned phone/watch RPC contract and wire its test, lint, and build gates before either runtime endpoint lands.

Co-authored-by: Sebastian Schubotz <git@sibbl.de>

* test(android): lock Wear wire names

Cover every supported RPC method and event discriminator so phone and watch cannot silently drift.

Co-authored-by: Sebastian Schubotz <git@sibbl.net>

* fix(android): bound Wear JSON depth

Reject excessively nested Data Layer envelopes before kotlinx.serialization can recurse through them.

* fix(android): enforce Wear depth on encode

Keep outbound messages inside the same JSON nesting contract enforced by the decoder.

* fix(android): preflight Wear payload depth

Traverse arbitrary JSON payloads iteratively before serialization so deeply nested local trees fail safely.

* feat(android): add Wear phone proxy

Co-authored-by: Sebastian Schubotz <git@sibbl.net>

* fix(ci): repair Wear and docs sync checks

---------

Co-authored-by: Sebastian Schubotz <git@sibbl.de>
Co-authored-by: Sebastian Schubotz <git@sibbl.net>
2026-07-16 16:08:16 -07:00
Peter Steinberger
7496f4d988 feat(android): mascot mood engine and onboarding moods (#109311)
Ports the deterministic mascot animator to Android: full pose channels
(face, gaze, droop, hard hat, effects), seeded mood loops including the
hard-hat working hammer cycle, entrance gestures, and static poses when
system animations are off. Onboarding heroes now feel the flow — working
while the gateway connects, celebrating once paired, thinking during
node approval, curious on permissions, sad on visible errors. Tinted
silhouette marks keep their ambient idle loop and stay silent for
TalkBack outside the welcome hero.
2026-07-16 14:04:40 -07:00
Leon-SK668
5dce814ca1 fix(android): preserve emoji in shell initials (#108830)
* fix(android): preserve emoji in shell initials

* chore(android): refresh native i18n inventory

* refactor(android): share Unicode initial extraction

* fix(android): preserve grapheme cluster initials

* chore(android): refresh native i18n inventory

* fix(android): satisfy ICU iterator nullability

* test(android): run shell initials under Robolectric

Co-authored-by: Leon-SK668 <0668001470@xydigit.com>

* style(android): format localized initial helper

Co-authored-by: Leon-SK668 <0668001470@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 13:38:27 -07:00
Peter Steinberger
fbb5af6515 improve(mac): group pairing session providers (#109320)
* feat(mac): group pairing session access

* chore(i18n): sync native source inventory

* chore(mac): defer release note generation
2026-07-16 13:19:15 -07:00
Peter Steinberger
8f74762f4d fix(macos): merge the WebChat window title band into the toolbar row (#109318)
The standalone chat window stacked a visible title bar (traffic lights +
"OpenClaw" title) above the SwiftUI toolbar row, wasting a full band of
vertical space. Apply the Dashboard window's merged chrome: hidden title,
transparent titlebar, no separator, movable-by-background — the unified
toolbar (sidebar toggle, search, pickers, session actions) now shares its row
with the traffic lights. A window subclass pins titleVisibility to hidden
because SwiftUI's toolbar bridge can restore visible title chrome, and scene
bridging is reset to toolbars-only after controller attachment (attaching an
NSHostingController resets it to .all).
2026-07-16 13:12:24 -07:00
Peter Steinberger
a9f82837a1 feat: inspect background tasks across web and mobile (#109150)
* feat: add background task details across clients

* fix: refresh background task clients and translations

* fix: keep background task details fresh

* fix: ignore deleted background task details

* refactor: split background task rendering

* fix: use canonical background task ids

* refactor: extract background task view types

* fix(apps): regenerate task localizations

* fix(ios): remove unused task screen import

* fix(apps): refresh task localization inventory
2026-07-16 13:08:42 -07:00
Peter Steinberger
da8a443a4d feat(linux): pending-approval notifications and a summon shortcut for the companion (#109322)
The companion now rings the doorbell for gateway approvals: it polls pending
node and device pairing requests over the existing CLI seam on the connected
watchdog cadence, fires one native notification per new request when the
window is unfocused, and shows a pending count in the tray status line.
Approval itself stays in the dashboard/CLI (owner boundary).

Adds a CmdOrCtrl+Shift+O summon shortcut with a tray toggle whose opt-out
persists as a marker file (no config schema). The X11-only global-hotkey
backend is gated off on native Wayland sessions — the feature is omitted
rather than half-registered through XWayland; a portal implementation can
follow.
2026-07-16 13:06:18 -07:00
Peter Steinberger
2f3bda1be6 feat(linux): OS integration for the desktop companion (#109236)
Single-instance + openclaw:// deep links (openclaw://dashboard opens and
connects the dashboard; the tiny URL contract is routed entirely in Rust), a
Start at Login tray toggle (tauri-plugin-autostart, default off), native
notifications for update-ready/update-available when the window is unfocused,
and window-state persistence (canvas window excluded). All official Tauri v2
plugins; cross-platform deps so the macOS/Windows test builds keep compiling.
2026-07-16 11:19:10 -07:00
Peter Steinberger
b35fc165ee feat(linux): extend companion self-update to macOS/Windows test builds (#109244)
Platform-aware install kinds: Linux AppImage and macOS self-install in place;
Windows defers — the update downloads and verifies in the background, then the
NSIS installer runs only from the user-confirmed restart (Tauri's installer
launch exits the process, so it must never fire behind a silent auto-check).
Linux system packages stay notify-only.

The release workflow gains dispatch-gated unsigned macOS/Windows test bundles
signed with the same minisign key, and a separate desktop-test update channel:
latest.json stays Linux-only on every release, while an opt-in fixed
'desktop-test' prerelease hosts latest-desktop-test.json (monotonic version
guard) so Linux-only releases can never strand distributed test builds. Build
jobs check out the SHA the validation job resolved, closing the tag-move race.
2026-07-16 10:55:19 -07:00
Peter Steinberger
bf92404b50 feat(linux-app): ask dev builds for the install channel on first run (#109242) 2026-07-16 10:54:26 -07:00
Peter Steinberger
cb84dc76fc feat(control-ui): approval attention chip + approval history page (#108776)
Adds the sidebar approval attention chip and a dedicated approval history
page backed by the new approval.history gateway RPC (30-day retention
window). Extracts buildSidebarAttentionItems into its own module so the Lit
component consumes it as a real cross-module dependency, and wires the strict
i18n catalog for the new strings (fallbacks=0).
2026-07-16 10:32:05 -07:00
Peter Steinberger
b6e90cbed4 test: raise async wait ceilings that flaked under CI load (#109222)
vi.waitFor in the ACP abort test and the shared Swift waitUntil helper
both timed out on contended runners while passing solo; polling waits
return immediately when healthy, so the higher ceilings cost nothing.
2026-07-16 10:30:50 -07:00
Peter Steinberger
0815f6a4f9 feat(android): add Wear proxy protocol (#108835)
* feat(android): add Wear proxy protocol

Introduce a bounded, versioned phone/watch RPC contract and wire its test, lint, and build gates before either runtime endpoint lands.

Co-authored-by: Sebastian Schubotz <git@sibbl.de>

* test(android): lock Wear wire names

Cover every supported RPC method and event discriminator so phone and watch cannot silently drift.

Co-authored-by: Sebastian Schubotz <git@sibbl.net>

* fix(android): bound Wear JSON depth

Reject excessively nested Data Layer envelopes before kotlinx.serialization can recurse through them.

* fix(android): enforce Wear depth on encode

Keep outbound messages inside the same JSON nesting contract enforced by the decoder.

* fix(android): preflight Wear payload depth

Traverse arbitrary JSON payloads iteratively before serialization so deeply nested local trees fail safely.

---------

Co-authored-by: Sebastian Schubotz <git@sibbl.de>
Co-authored-by: Sebastian Schubotz <git@sibbl.net>
2026-07-16 10:21:38 -07:00
Peter Steinberger
e71ef76e8e feat(onboarding): offer detected Claude Code/Codex/Hermes memory imports across CLI, macOS, and Linux onboarding (#108977)
* feat(migrate): add Hermes memory-only import and a shared memory-import core

* feat(onboarding): offer detected memory imports during CLI setup and guided onboarding

* feat(ui): show a first-run memory-import offer in Control UI onboarding mode

* feat(linux-app): open the first-run dashboard in onboarding mode

* feat(macos): add the onboarding memory-import page

* docs: document the onboarding memory-import page across surfaces

* chore(i18n): translate onboarding memory-import strings for control-ui and native locales

* refactor: keep memory-import internals unexported for deadcode gates

* fix(ci): resolve lint findings in onboarding memory import

* chore(i18n): refresh native inventory after lint refactor

* fix(ci): skip updater artifacts in the unsigned Linux companion PR lane

* chore(i18n): reconcile locale artifacts after rebase
2026-07-16 10:10:01 -07:00
Leon-SK668
a8fe7dd834 fix(android): preserve emoji in debug diagnostics (#108823)
* fix(android): preserve unicode in debug diagnostics

* chore(android): refresh native i18n inventory

* test(android): satisfy debug handler ktlint

* refactor(android): centralize UTF-safe diagnostics

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 09:53:14 -07:00
Peter Steinberger
aebea4891e feat(ios): render plugin approvals as native Allow/Deny notifications (#108709)
* feat(ios): render plugin approvals as native Allow/Deny notifications

Extend the iOS approval handling from exec to plugin approvals so the native
push the gateway now sends (#108505) shows a phone notification with Allow/Deny.
Extract a shared ApprovalNotificationBridge with exec/plugin wrappers owning
their own kind constants and category; tag the parsed prompt with its kind;
register the plugin category and route plugin pushes in the app delegate; add a
.plugin case that maps the plugin presentation (title/description/pluginId/
severity) into the existing prompt and widens the exec-only validation, current,
cache-restore, and resolve guards to accept plugin; parameterize the dialog copy
by kind. Watch snapshot publication stays exec-only; the phone notification still
mirrors to the watch via WatchConnectivity. Reuses the unified approval.get/
approval.resolve RPCs (already kind-generic); no server or protocol changes.

* chore(i18n): sync native inventory after rebase

* chore(ios): drop accidentally committed local Version.xcconfig build override

* fix(ios): sync Apple i18n catalog and remove dead approval-bridge methods

Sync apps/ios/Resources/Localizable.xcstrings for the new plugin-approval
strings (native inventory sync alone did not cover the Apple catalog).
Remove the superseded per-bridge registerCategory variants and the redundant
exec parseResolvedPush wrapper flagged by the iOS Periphery dead-code scan;
registration uses ApprovalNotificationBridge.registerCategories and the shared
parse helpers.

* chore(ios): drop generated SwiftSources filelist; reconcile native i18n inventory

* chore(ios): drop generated Xcode project from tracking

Codex generated OpenClaw.xcodeproj for its simulator test run and the initial
apps/ios directory commit force-added it; xcodegen regenerates it in CI, so it
must not be tracked (matches main).

* chore(ios): reconcile native i18n inventory after rebase
2026-07-16 09:50:42 -07:00
Peter Steinberger
b3301e3212 feat(clients): show live plan checklists in web, iOS, and Android chat (#108675)
The gateway already broadcasts stream:"plan" agent events with typed
{step, status} snapshots; all three clients dropped them. Control UI now
renders an expandable checklist bar above the composer (run-scoped,
cleared on run lifecycle); the shared iOS/macOS chat UI mounts a
Liquid Glass pill (iOS 26 glassEffect, material fallback) between the
message list and composer; Android adds an expandable pill above the
composer bridged through ChatController/NodeRuntime/MainViewModel.
All parsers accept typed and legacy string steps, enforce the
single-in_progress invariant, and scope snapshots and clears to the
owning run. Locale artifacts, Android resources, and the iOS string
catalog carry generated translations for the pill strings.
2026-07-16 09:33:52 -07:00
Peter Steinberger
79b1fdfa39 feat(mac): mascot accessory pack — nightcap, grad cap, hat-tip exit (#108882)
* feat(mac): mascot accessory pack — nightcap, grad cap, hat-tip exit

New accessory channel for the shared mascot: sleepy (and auto-dozing)
Clawd wears a floppy blue nightcap; the final onboarding page tops the
celebration with a graduation cap whose tassel swings with the body;
and leaving the working mood plays a hat-tip — claw to the brim, small
bow, hard hat lifts away. Headwear drawing moves to its own canvas
extension file.

* fix(mac): one hat at a time and no phantom hat tips

The working hard hat (including its hat-tip exit) suppresses any mood-
or consumer-requested accessory until it is fully gone, and the hat-tip
plays only when the hat actually seated — a working state cancelled
mid-don exits through the normal entrance instead of synthesizing a
full hat just to lift it.

* chore(i18n): refresh native inventory lines for mascot view
2026-07-16 09:14:21 -07:00
Peter Steinberger
20d748a4f0 feat(agents): agent-owned gateway terminals with operator co-attach 2026-07-16 09:12:50 -07:00
Peter Steinberger
8fe4eeea9e fix(exec): stop isolated state dirs from moving live approvals (#108742)
* fix(exec): isolate approval state directories

* chore: drop release-owned changelog entry

* chore: refresh native i18n inventory

* fix(ci): pin XcodeGen for Periphery scans
2026-07-16 08:57:32 -07:00
Peter Steinberger
6b79db8b7d feat(ios): mascot moods for onboarding and gateway quick setup (#108900)
* feat(ios): mascot moods for onboarding and gateway quick setup

The activation glyph now takes a mood: the onboarding welcome step
shows the hard-hat working mascot while connecting, the success step
celebrates, and the gateway quick-setup header derives working/sad/
curious/idle from its connect state.

* fix(ios): quick-setup mood reflects app-level gateway problems too

The sheet renders two error surfaces — the local connect error and the
app-level gateway problem banner — and the mascot now goes sad for
either instead of only the sheet-local failure.
2026-07-16 08:56:18 -07:00
Peter Steinberger
65bdd1bf08 feat(mac): menu-bar critter celebrates gateway recovery and finished work (#108866)
Two one-shot micro-beats for the 18pt menu-bar critter: a happy-eyes
ear-wiggle when the Gateway comes back from a failure (judged against
the last settled status, so failed -> starting -> running still reads
as a comeback while cold starts and deliberate stop/start cycles stay
quiet), and a brief celebration when sustained work (>= 10s) finishes.
Short blips stay silent so the menu bar never gets noisy.
2026-07-16 08:52:43 -07:00
Peter Steinberger
8bcff3bad9 fix(macos): recover after installed app replacement (#108991)
* fix(macos): relaunch trusted app replacements

* refactor(macos): split relocator extension

* fix(macos): revalidate replacement bundle in child

* chore(macos): refresh native i18n inventory

* style(macos): satisfy Swift formatting and dead-code gates
2026-07-16 06:31:02 -07:00
Peter Steinberger
cf029ea29e feat(agents): screen tool drives Control UI layout 2026-07-16 05:43:02 -07:00
Peter Steinberger
93c9d2a20c fix(ios): stop fresh setup from failing after pairing (#108779)
* fix(ios): make setup keychain handoff atomic

* fix(ios): refresh native i18n inventory
2026-07-16 03:50:54 -07:00
Wynne668
b7e099d36e fix(gateway): agent model overrides cannot be cleared (#108734)
* fix(gateway): allow clearing agent model overrides

* fix(protocol): preserve Swift agent model compatibility

* fix(protocol): preserve null when Swift decodes agent updates

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:46:37 -07:00
Peter Steinberger
e4f4b93b10 feat(mac): playful hard-hat working mascot during setup and updates (#108735)
* feat(mac): playful hard-hat working mascot during setup and updates

The mascot gets a new .working mood: it dons a safety hard hat, hammers
away with impact sparks while setup work is in flight, and pauses every
few seconds to wipe its brow. Used on the onboarding "Getting things
ready" page and the post-update window instead of the generic thinking
mood. Lives in shared OpenClawKit so iOS can adopt it too.

* chore(i18n): refresh native inventory line for mascot view
2026-07-16 02:45:19 -07:00
Leandre Chamberland-Dozois
5c1857fc55 fix(android): stop killing long chat runs with hardcoded timeouts (#106863) (#106864)
* fix(android): stop killing long chat runs with hardcoded timeouts

Two independent timeouts made any agent turn longer than ~2 minutes fail
when started from the Android app, while the same turn worked over
Telegram (#106863):

- chat.send hardcoded timeoutMs=30000, which the gateway turns into the
  server-side run expiry; the maintenance sweep then aborts longer runs
  ("CLI run aborted" / "Embedded agent failed before reply"). Omit the
  override so app runs get the configured default like other channels.

- armPendingRunTimeout declared a timeout after 120s even when the
  refreshed history snapshot confirmed the run was still in flight,
  showing a spurious error and dropping the optimistic bubble mid-run.
  Re-arm the timer in that case; terminal events and the server-side
  expiry remain the liveness backstop.

Fixes #106863

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(i18n): sync native inventory after ChatController line shifts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(android): run ChatController on backgroundScope in reconnect tests

The pending-run watchdog now re-arms while a run is confirmed in flight,
so reconnect scenarios that end with a restored in-flight run keep a
timer coroutine alive. Launch the controller on runTest's
backgroundScope so that timer is cancelled at test end instead of
failing the suite with UncompletedCoroutinesError.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(android): bound pending-run watchdog recovery

Distinguish applied, superseded, and failed history refreshes so recovered runs neither expire during a newer authoritative load nor rearm forever after refresh failure.

Co-authored-by: Léandre Chamberland-Dozois <lchamberland-dozois@hotmail.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 02:12:45 -07:00
Peter Steinberger
f460c2871a feat(linux): add signed auto-updater to the Tauri companion app (#108770)
Sparkle-parity self-update for the apps/linux companion: tauri-plugin-updater +
process, checked silently on launch and from a "Check for Updates" tray item /
manual trigger. AppImage installs download, verify the signed update, and wait
for a user-confirmed restart; package-managed (deb) installs get a release-page
notice instead of replacing files the system package manager owns. The
linux-app release workflow signs the AppImage and publishes a signed latest.json
manifest that the app verifies with the committed minisign public key.
2026-07-16 01:48:08 -07:00
NianJiu
727f9e0a7e fix(ios): preserve active chat across foreground reconnects (#108241)
* fix(ios): preserve chat focus across reconnects

* chore(ios): sync native i18n inventory

* test(ios): strengthen reconnect ownership coverage

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>

---------

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 01:38:45 -07:00