Files
openclaw/apps/macos
Peter Steinberger 4bc37cd597 fix(state): copy-safe agent database registry via state-relative paths (schema v9) (#124728)
* fix(state): store in-root agent database registry paths relative to the state dir (schema v9)

Copied state directories retained stale absolute agent database registry rows. The combined gateway store then merged old and new copies, causing every sessions.list request to fail with SessionCanonicalKeyMigrationRequiredError.

Schema v9 stores in-root registry paths relative to the state directory; migration rewrites eligible rows, deletes stale duplicates, and preserves external paths.

* fix(voice-call): describe state-relative registry migration

* fix(state): preserve registry locator traversal

* test(macos): move PortGuardian schema-version boundary to v9

The store opens any state database up to maximumSupportedSchemaVersion,
which the schema v9 bump moved from 8 to 9. Shift the supported/newer
partition in the boundary test accordingly.

* fix(state): re-anchor copied default-layout registry rows instead of deleting them

Resolve the ClawSweeper P1 by preserving genuine external default-layout registrations, re-anchoring copied rows when an in-root counterpart exists, and deleting only dual default-layout conflicts.
2026-08-16 13:31:32 -07:00
..

OpenClaw macOS app (dev + signing)

Quick dev run

# from repo root
scripts/restart-mac.sh

Options:

scripts/restart-mac.sh --no-sign   # fastest dev; ad-hoc signing (TCC permissions do not stick)
scripts/restart-mac.sh --sign      # force code signing (requires cert)
scripts/restart-mac.sh --background-only # keep services running without automatic windows

--background-only suppresses first-run onboarding, update and CLI prompts, and the --chat/--dashboard auto-open helpers. Pairing, control-channel, and Mac node services still start. It also keeps GUI-owned onboarding and saved Gateway profile Keychain state cold, so a signer or ACL transition cannot raise a SecurityAgent prompt during unattended work. The primary Gateway route still comes from the normal environment/config endpoint. Combine it with --attach-only when an external process owns the local Gateway.

App profiles

Launch a fully isolated app instance with the same profile name used by the CLI:

OPENCLAW_PROFILE=work /Applications/OpenClaw.app/Contents/MacOS/OpenClaw

Profile names use 164 lowercase letters, numbers, underscores, or hyphens and must start with a letter or number. default selects the normal app; gateway, mac, and node are reserved LaunchAgent identities.

scripts/restart-mac.sh intentionally rejects named profiles because its packaging cleanup is host-global. Build/package normally, then launch the named profile directly with the command above.

A named profile keeps state in ~/.openclaw-<name>, uses its own app defaults, Keychain services, duplicate-instance lock, and the CLI-managed Gateway service ai.openclaw.<name>. Unless config or environment selects a port, each profile derives a stable port in the profile 20000...59999 range. The app does not install or modify the host-global Mac node service or OpenClaw login item while a profile is active. The runtime child node still runs in process as usual. App relocation, Sparkle updates, and post-update service repair are disabled in profile mode; update the installed app through the normal default-profile workflow.

Packaging flows

Development bundle (signed but not notarized):

scripts/package-mac-app.sh

This creates dist/OpenClaw.app and signs it via scripts/codesign-mac-app.sh. It is not a distribution artifact. For a notarized app ZIP and DMG, use:

scripts/package-mac-dist.sh

For an unattended Peekaboo elevation host, use the closed Foundation signing profile and source-addressed ZIP workflow. package is an internal release operator command: it requires the OpenClaw Foundation signing identity and notarization credentials, and its archive is not a general-download artifact.

scripts/mac-elevation-host.sh package
cd dist/elevation-host
shasum -a 256 -c "OpenClaw-<full-source-sha>-stable.zip.sha256"
shasum -a 256 -c "OpenClaw-<full-source-sha>-stable-installer.sh.sha256"
./OpenClaw-<full-source-sha>-stable-installer.sh install \
  --archive "OpenClaw-<full-source-sha>-stable.zip"
./OpenClaw-<full-source-sha>-stable-installer.sh status

The elevation package is ZIP-only, notarized and stapled, contains exactly OpenClaw.app, omits Apple Events entitlements, records an immutable receipt, and verifies a freshly extracted copy. The same source-addressed artifact set includes an executable installer copied from that exact Git commit plus separate archive and installer checksum files, so a target Mac does not need a source checkout. Transfer the complete set and verify both checksums before running the installer. Installation owns the separate ai.openclaw.mac.elevation-host launchd job with RunAtLoad and KeepAlive. It refuses to replace or race the ordinary ai.openclaw.mac Launch at login job. recover restores the recorded prior bundle after a failed cutover; uninstall removes only the elevation job and preserves the app, state, Keychain, TCC, and recovery receipt. Installation exits successfully once the launchd-owned process is Bridge-ready; missing TCC remains a degraded status result until the required grants are present.

Signing behavior

Auto-selects identity (first match):

  1. Developer ID Application
  2. Apple Distribution
  3. Apple Development
  4. first available identity

If none found:

  • errors by default
  • set ALLOW_ADHOC_SIGNING=1 or SIGN_IDENTITY="-" to ad-hoc sign

Team ID audit (Sparkle mismatch guard)

After signing, we read the app bundle Team ID and compare every Mach-O inside the app. If any embedded binary has a different Team ID, signing fails.

Skip the audit:

SKIP_TEAM_ID_CHECK=1 scripts/package-mac-app.sh

Library validation workaround (dev only)

If Sparkle Team ID mismatch blocks loading (common with Apple Development certs), opt in:

DISABLE_LIBRARY_VALIDATION=1 scripts/package-mac-app.sh

This adds com.apple.security.cs.disable-library-validation to app entitlements. Use for local dev only; keep off for release builds.

Useful env flags

  • SIGN_IDENTITY="Apple Development: Your Name (TEAMID)"
  • ALLOW_ADHOC_SIGNING=1 (ad-hoc, TCC permissions do not persist)
  • CODESIGN_TIMESTAMP=off (offline debug)
  • DISABLE_LIBRARY_VALIDATION=1 (dev-only Sparkle workaround)
  • SKIP_TEAM_ID_CHECK=1 (bypass audit)