Commit Graph

34 Commits

Author SHA1 Message Date
Vincent Koc
20e68e01df fix(gateway): sign device proofs with challenge time (#116679) 2026-07-31 16:45:53 +08:00
Peter Steinberger
4232126bba chore: update dependencies across workspace (#115677)
* chore(deps): update dependencies

* fix(deps): restore CI compatibility
2026-07-29 05:16:42 -04:00
Peter Steinberger
117e44cb80 fix(linux): package media codecs for deb and AppImage (#115616)
* fix(linux): package media codecs

* fix(linux): bundle AppImage media codecs

* docs: refresh Linux page map
2026-07-29 02:03:55 -04:00
Peter Steinberger
ab3e9645e7 fix(linux): recover corrupt gateway identity (#114359) 2026-07-27 02:17:08 -04:00
Peter Steinberger
b65dae1511 fix(linux): surface manual update results (#114312) 2026-07-27 01:26:28 -04:00
Peter Steinberger
de92c557f1 fix(linux): serialize tray gateway operations (#114291) 2026-07-27 01:06:03 -04:00
Peter Steinberger
730b341f3f fix(linux): keep Quick Chat on screen across DPI and widget resizes (#114271)
Two geometry defects found while stress-testing the companion.

Positioning mixed coordinate spaces. `work_area()` is physical pixels of the
monitor Quick Chat is moving to, but `inner_size()` is physical pixels at the
scale of the monitor it is on now. A 640pt window on a 2x display reports
1280px, so invoking it on a 1x 1920px display centred using 1280 and landed it
320px left of centre. Re-express the window size in the target monitor's scale
first; equal scales give a ratio of 1, so single-monitor setups are untouched
to the pixel.

Widget growth resized without re-anchoring. `quickchat_set_expanded` resizes
and then repositions, but the widget path only resized, keeping the old top
edge. Growing from 360pt to 440pt in a 440pt work area left the bottom 80pt
off-screen and unreachable. `resize_window_if_needed` now reports whether it
actually changed the height so the caller re-anchors only on a real resize,
rather than moving the window when nothing changed.
2026-07-27 00:05:52 -04:00
Peter Steinberger
992a86a28f fix(linux): make the companion's Rust test suite runnable and run it (#114260)
Three defects that compounded into a test suite nobody could run and nobody
was running.

The suite has been red on main since 2026-07-20. `connect_frame_matches_gateway_schema`
asserts a TLS-pinned connection advertises no capabilities, but #111933 wrote
that assertion while caps held only inline-widgets, and #111920 made
`agent-kind` unconditional the same day. No textual conflict, so both landed
and the assertion has been wrong ever since. Pinning only withdraws inline
widgets, so assert exactly that.

`cargo test` could not run on macOS at all: tauri-plugin-notifications links a
Swift static library, nothing adds an rpath for the Swift runtime, and every
test binary aborted at load with `Library not loaded:
@rpath/libswift_Concurrency.dylib`. Emit the rpath from build.rs.

Neither surfaced because linux-app.yml never ran `cargo test` - it only checked
formatting and built bundles. Run the suite on Linux, and upgrade the macOS job
from `check` to `test` so link-time breakage like the rpath is caught at all;
`check` never links, so it cannot see this class of failure.
2026-07-26 23:43:32 -04:00
Peter Steinberger
e94796e447 fix(linux): restore the macOS build of the Tauri companion (#114243)
* fix(linux): restore the macOS build of the Tauri companion

Tauri gates `WebviewWindowBuilder::transparent` behind its `macos-private-api`
feature on macOS, so the companion stopped compiling for macOS when Quick Chat
landed in #109947: `no method named 'transparent' found for struct
'WebviewWindowBuilder'`. Enable that feature together with the matching
`app.macOSPrivateApi` config flag, which Tauri requires to agree with it or
tauri-build fails the allowlist check.

Quick Chat is built for a transparent window - quickchat.css makes html and
body transparent behind a 16px-radius translucent card with a drop shadow - so
compiling macOS by dropping `.transparent(true)` would ship an opaque rectangle
instead of the floating composer.

Also add a per-PR macOS `cargo check`. The only job that compiled the macOS
target sits behind a manual dispatch input in linux-app-release.yml, which is
why a broken macOS build survived for nine days.

* ci(linux): build the macOS companion on macos-15

tauri-plugin-notifications' Swift sources use typed throws
(`throws(FFIResult)`), which requires Swift 6. The macos-14 runner image still
ships Swift 5.x and cannot parse them, so the plugin's build script panics with
"Swift build failed for target: arm64-apple-macosx13.0".

This hit the new per-PR check immediately, and it means the release workflow's
`build_macos` job could not have produced a macOS bundle either - it compiles
the same crate on the same image, but only runs behind a manual dispatch input
so nothing surfaced it. Move both to macos-15.
2026-07-26 22:57:36 -04:00
Peter Steinberger
e6a6d478f2 fix(linux): draw the macOS tray icon from a template silhouette (#114223)
* fix(linux): draw the macOS tray icon from a template silhouette

AppKit renders menu bar template images from the alpha channel alone, so the
opaque rounded-tile 32x32.png painted a solid white square instead of the
mascot. Add a dedicated tray-template.svg and its 36px render, a silhouette
with the eyes knocked back out, and select it only on macOS. Its geometry
mirrors the native macOS app's CritterIconRenderer at rest so both clients
wear the same face; other platforms keep the full-color 32x32.png.

* chore(linux): drop the root changelog entry from the tray icon fix

CHANGELOG.md is release-owned in this repo (AGENTS.md) and `scripts/pr
prepare-run` rejects normal PRs that touch it; release generation derives
entries from merged PRs. The release-note context lives in the PR body and
the preceding commit message instead.
2026-07-26 21:53:18 -04:00
Peter Steinberger
acd92f6a3d chore(deps): refresh repository dependencies (#112453)
* build(deps): update QA broker dependency

* build(deps): refresh repository dependencies

* build(deps): reconcile rebased shrinkwraps

* test(plugins): remove stale loader test state

* test(deps): stabilize updated dependency coverage

* fix(swift): use caller-isolated TaskLocal overload

* build(deps): regenerate rebased shrinkwraps

* test(msteams): preserve DNS validation in fetch helper

* fix(deps): avoid vulnerable optional image stack

* test(deps): validate generated LRU override

* refactor(ui): extract chat resizable divider

* test(ui): update divider ownership path

* fix(matrix): retain restart-compatible SDK

* style(cron): format update test
2026-07-23 16:17:13 +00:00
Peter Steinberger
c23ca5fda2 fix(linux): hide Quick Chat before widget cleanup (#112308) 2026-07-21 20:07:56 -07:00
Peter Steinberger
e5610976cf fix(linux): harden Quick Chat widget lifecycle (#112261)
* fix(linux): harden Quick Chat widget lifecycle

* fix(linux): retry stale widget cleanup before reveal
2026-07-21 05:35:06 -07:00
Peter Steinberger
49ff6a4497 fix(protocol): classify system agents in rosters (#111920)
* fix(protocol): classify system agents in rosters

* fix(ci): align agent kind client gates

* fix(ci): keep roster filtering in startup bundle

* chore(ui): remove superseded roster module

* style(android): satisfy agent kind test formatting

* style(linux): format merged agent capability assertion

* fix(config): reject reserved system agent ids

* chore(i18n): refresh native source inventory

* style(android): format agent kind surfaces

* fix(gateway): preserve configured agent ownership
2026-07-20 16:57:04 -07:00
Peter Steinberger
a52eb2134b feat(apps): connect multiple gateways simultaneously (#111932)
* feat(apps): support simultaneous gateways

* fix(apps): satisfy multi-gateway checks

* chore(apps): refresh multi-gateway baselines

* style(android): format gateway fleet code
2026-07-20 13:06:29 -07:00
Peter Steinberger
ba3711bb82 feat(linux): render widgets in Quick Chat (#111933) 2026-07-20 11:56:03 -07:00
Peter Steinberger
bc8d0da092 feat(linux): Quick Chat streamed replies and precise pairing states (#110632)
* feat(linux): stream Quick Chat gateway events

* feat(linux): render streamed Quick Chat replies

* fix(linux): correlate Quick Chat streams by run

* style(linux): rustfmt

* test(linux): move Quick Chat stream helper tests into the tooling vitest project

* test: type the Linux quickchat stream harness for strict checks

* test: explicit harness shape for the root test typecheck
2026-07-18 13:22:48 +01:00
Peter Steinberger
222dc58011 feat(linux): native gateway transport for Quick Chat — device identity, TLS pinning, ack-driven sends (#110491)
* feat(gateway): add Linux native auth surface

* feat(linux): persist Gateway device identity

* feat(linux): add native Gateway WebSocket client

* feat(linux): route Quick Chat through Gateway

* feat(cli): expose dashboard transport handoff

* docs(linux): document native Quick Chat transport

* test(linux): placeholder-shaped fixture token in device-auth payload test

* test: placeholder-shaped credential fixtures; reshape device-token rebind

* test: keep auth-method enums verbatim; rename only credential fixtures

* test(gateway): move Linux native admission coverage to a dedicated test file

* style: replace scanner-evasion literals with honest shapes; shared trim helper for auth material

* style(cli): join-built computed keys instead of literal concatenation

* chore: drop release-owned CHANGELOG edit from feature branch
2026-07-18 09:59:10 +01:00
Peter Steinberger
90b4a12ee9 feat(linux): Quick Chat agent switcher, avatars, per-agent routing, and configurable shortcut (#110285)
* feat(linux): expand Quick Chat agent controls

* docs(linux): document Quick Chat controls

* fix(agents): keep avatar summary additive

* refactor(linux): trim Quick Chat dead Default impl and speculative focus-failure recovery

* fix(linux): destroy the Quick Chat window when hide fails after a rejected focus grab

* fix(linux): fail Quick Chat sends when the pinned agent vanishes; classify avatar-only identities as config-derived

* docs(linux): note the accepted cache-fresh send-validation tradeoff

* style: satisfy no-map-spread and rustfmt in Quick Chat parity surfaces
2026-07-18 03:44:49 +01:00
Peter Steinberger
277f009cc9 feat(linux): Quick Chat floating composer for the Tauri companion (#109947)
* feat(linux): add Quick Chat floating composer to the Tauri companion

- frameless transparent always-on-top quickchat window (on-demand, canvas
  pattern), positioned top-third on the cursor monitor, CSS fade+zoom in/out
- global shortcut Ctrl+Shift+Space on X11 (GNOME reserves Alt+Space); tray
  'Quick Chat' item is the Wayland entry point; blur/Esc/close-request hide
- sends via the CLI agent turn with --message-file staged 0600 (argv is
  world-readable procfs) and cleaned up after the turn; failures surface as
  desktop notifications; Ctrl+Enter also opens the dashboard
- default-agent identity chip (emoji/monogram) from agents list --json, 60s cache
- window-scoped capability + permission set; window-state denylist; docs

* chore(linux): register quickchat.js as a knip native-asset entry
2026-07-17 18:25:27 +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
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
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
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
Peter Steinberger
ff4ce42eab fix(linux): use the Clawd mascot for the desktop app icon (#108181)
The bundle/tray icon (icon.svg, icon-tile.svg and the generated
32/128/256/512 PNGs + icon.ico) still used the abstract two-pill
claw-mark. The product logo is the Clawd lobster mascot (already used in
the app header and ui/public/favicon.svg), so the app icon shown in the
Dock, taskbar, window, and tray now matches it: a static mascot on the
dark brand tile (transparent mascot for the tray). Regenerated from the
mascot SVG via rsvg-convert; build accepts the icon set.
2026-07-15 02:11:36 -07:00
Peter Steinberger
b65a2d836a feat(linux): discover gateways via Bonjour and open their dashboard (#108115)
New discovery.rs browses _openclaw-gw._tcp with a lifetime mdns-sd
browser, keeps a fullname-keyed snapshot (resolved updates replace,
goodbye/TTL removes), and mirrors the native clients' TXT contract and
direct-selection gate (resolved SRV endpoint routing; tailnetDns is a
hint only). The bootstrap page lists discovered gateways and connecting
navigates the dashboard WebView to the resolved endpoint, validated
against the live snapshot; remote selection cancels the local watchdog
so an in-flight local bootstrap cannot steal the WebView back.
2026-07-15 01:22:36 -07:00
Peter Steinberger
9384a40393 build(linux): allow macOS and Windows test builds of the desktop app (#108004)
The desktop companion crate was Linux-only. All platform-specific code
lives in canvas.rs (WebKitGTK, cairo, unix sockets, SO_PEERCRED), so:
move webkit2gtk/cairo-rs/libc under linux target dependencies, gate the
canvas module, its protocol registration, invoke handler, and exit
shutdown to Linux, add a USERPROFILE home fallback and an explicit
no-op installer error for Windows, and add the multi-size icon.ico
Windows resource. Linux behavior is unchanged; macOS/Windows builds are
for testing (macOS cargo build+test green locally; Windows aarch64-msvc
built and launched in a Windows 11 ARM VM).
2026-07-14 22:17:05 -07:00
Peter Steinberger
b363d5a293 feat(linux): canvas UI via CLI-node + Tauri app IPC bridge (#107633)
* feat(linux): canvas via CLI-node + Tauri app IPC bridge

* refactor: extract gateway helper modules

* build(linux-canvas): register plugin package in lockfile

* fix(linux-canvas): move canvas advertise test out of core, regen docs/protocol/deadcode

* fix(gateway): break node-catalog/registry import cycle via leaf normalize module; add canvas glossary term

* style: oxfmt invoke.ts and runtime.ts after buildNodeEventParams extraction

* fix(linux): load Canvas WebView via dedicated data_directory context

Wry's Linux/WebKitGTK incognito mode discards Tauri's registered
WebContext (wry webkitgtk/mod.rs), so the Canvas window got a fresh
ephemeral context without the openclaw-canvas:// scheme handler — the
bundled A2UI page never committed (stayed about:blank) and every A2UI
command timed out. Use an isolated cache-backed data_directory instead,
which keeps the protocol handler while still isolating Canvas storage
from the dashboard window.

* fix(linux): keep Canvas WebView ephemeral via incognito + data_directory

Autoreview flagged that a dedicated data_directory alone persists Canvas
browser state (cookies, localStorage, IndexedDB, service workers) across
restarts, so an agent that navigates Canvas to a site could leak an
authenticated session into a later session. iOS uses a non-persistent
store; Linux should match.

Add .incognito(true) alongside .data_directory(): the distinct directory
gives Tauri a fresh WebContext key so it still attaches the
openclaw-canvas:// protocol closure, and incognito makes Wry swap in a
fresh *ephemeral* context carrying those protocols. Live-verified on a
Wayland/WebKitGTK box: the bundled page still loads
(location.href=openclaw-canvas://localhost/index.html, openclawA2UI
present, A2UI renders) and the canvas-webview dir holds no persistent
cookie/storage files.
2026-07-14 16:05:14 -07:00
Peter Steinberger
ad8107e136 feat(linux): ship deb/AppImage bundles on stable main-based releases (#106891)
* feat(linux): attach deb/AppImage bundles to main-based releases

* fix(linux): stamp release version into bundles and verify deb metadata

* fix(linux): stable-only release tags and ubuntu-22.04 glibc build floor

* docs(linux): document AppImage FUSE prerequisite

* fix(linux): allow numeric stable revision tags in release workflow
2026-07-13 16:31:09 -07:00
Peter Steinberger
80bcfa1796 feat(linux): deb/AppImage packaging, claw-mark brand icons, gateway auth guidance (#106533)
* feat(linux): package deb/AppImage bundles, claw-mark icons, foreign-gateway guidance

* fix(linux): pin pnpm dlx release-age for tauri-cli in packaging paths

* fix(linux): pin exact tauri-cli version under the release-age gate

* fix(linux): conditional wording for gateway auth-rejection guidance

* docs(linux): executable square-pad step in tray icon recipe
2026-07-13 09:22:12 -07:00
Peter Steinberger
0bab08510e feat: Linux desktop companion app with auto-install, Gateway lifecycle, and Control UI window (#106352)
* feat(linux): add Tauri desktop companion app and openclaw dashboard --json

* test(dashboard): assemble fake token fixture to satisfy secret scanners

* test(dashboard): avoid secret-scanner-shaped mock factory line

* fix(linux): actionable error when installed CLI predates dashboard --json

* docs: regenerate docs map for linux platform heading change
2026-07-13 05:17:27 -07:00