diff --git a/.detect-secrets.cfg b/.detect-secrets.cfg
index 3ab7ebb69b5..34f4ff85f07 100644
--- a/.detect-secrets.cfg
+++ b/.detect-secrets.cfg
@@ -41,3 +41,5 @@ pattern = grep -q 'N[O]DE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache' ~/.bash
pattern = env: \{ MISTRAL_API_K[E]Y: "sk-\.\.\." \},
pattern = "ap[i]Key": "xxxxx",
pattern = ap[i]Key: "A[I]za\.\.\.",
+# Sparkle appcast signatures are release metadata, not credentials.
+pattern = sparkle:edSignature="[A-Za-z0-9+/=]+"
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 74dc847d487..2f9d299a5b3 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -71,6 +71,8 @@ repos:
- 'ap[i]Key: "A[I]za\.\.\.",'
- --exclude-lines
- '"ap[i]Key": "(resolved|normalized|legacy)-key"(,)?'
+ - --exclude-lines
+ - 'sparkle:edSignature="[A-Za-z0-9+/=]+"'
# Shell script linting
- repo: https://github.com/koalaman/shellcheck-precommit
rev: v0.11.0
diff --git a/.secrets.baseline b/.secrets.baseline
index 871217bc3bc..b1f909e6ca4 100644
--- a/.secrets.baseline
+++ b/.secrets.baseline
@@ -153,7 +153,8 @@
"env: \\{ MISTRAL_API_K[E]Y: \"sk-\\.\\.\\.\" \\},",
"\"ap[i]Key\": \"xxxxx\"(,)?",
"ap[i]Key: \"A[I]za\\.\\.\\.\",",
- "\"ap[i]Key\": \"(resolved|normalized|legacy)-key\"(,)?"
+ "\"ap[i]Key\": \"(resolved|normalized|legacy)-key\"(,)?",
+ "sparkle:edSignature=\"[A-Za-z0-9+/=]+\""
]
},
{
@@ -180,29 +181,6 @@
"line_number": 15
}
],
- "appcast.xml": [
- {
- "type": "Base64 High Entropy String",
- "filename": "appcast.xml",
- "hashed_secret": "7afea670e53d801f1f881c99c40aa177e3395bfa",
- "is_verified": false,
- "line_number": 365
- },
- {
- "type": "Base64 High Entropy String",
- "filename": "appcast.xml",
- "hashed_secret": "6e1ba26139ac4e73427e68a7eec2abf96bcf1fd4",
- "is_verified": false,
- "line_number": 584
- },
- {
- "type": "Base64 High Entropy String",
- "filename": "appcast.xml",
- "hashed_secret": "c0baa9660a8d3b11874c63a535d8369f4a8fa8fa",
- "is_verified": false,
- "line_number": 723
- }
- ],
"apps/android/app/src/test/java/ai/openclaw/android/node/AppUpdateHandlerTest.kt": [
{
"type": "Hex High Entropy String",
@@ -13035,5 +13013,5 @@
}
]
},
- "generated_at": "2026-03-09T06:30:58Z"
+ "generated_at": "2026-03-09T08:37:13Z"
}
diff --git a/apps/android/app/build.gradle.kts b/apps/android/app/build.gradle.kts
index e300d4fb2e4..3b52bcf50de 100644
--- a/apps/android/app/build.gradle.kts
+++ b/apps/android/app/build.gradle.kts
@@ -63,8 +63,8 @@ android {
applicationId = "ai.openclaw.app"
minSdk = 31
targetSdk = 36
- versionCode = 202603081
- versionName = "2026.3.8"
+ versionCode = 202603090
+ versionName = "2026.3.9"
ndk {
// Support all major ABIs — native libs are tiny (~47 KB per ABI)
abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
diff --git a/apps/ios/ActivityWidget/Info.plist b/apps/ios/ActivityWidget/Info.plist
index e1ed12b4aa1..4c2d89e1566 100644
--- a/apps/ios/ActivityWidget/Info.plist
+++ b/apps/ios/ActivityWidget/Info.plist
@@ -17,7 +17,7 @@
CFBundlePackageType
XPC!
CFBundleShortVersionString
- 2026.3.8
+ 2026.3.9
CFBundleVersion
20260308
NSExtension
diff --git a/apps/ios/ShareExtension/Info.plist b/apps/ios/ShareExtension/Info.plist
index b2e9f1eeebb..90a7e09e0fc 100644
--- a/apps/ios/ShareExtension/Info.plist
+++ b/apps/ios/ShareExtension/Info.plist
@@ -17,7 +17,7 @@
CFBundlePackageType
XPC!
CFBundleShortVersionString
- 2026.3.8
+ 2026.3.9
CFBundleVersion
20260308
NSExtension
diff --git a/apps/ios/Sources/Info.plist b/apps/ios/Sources/Info.plist
index 99bd6f180c5..2f1f03d24a1 100644
--- a/apps/ios/Sources/Info.plist
+++ b/apps/ios/Sources/Info.plist
@@ -23,7 +23,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 2026.3.8
+ 2026.3.9
CFBundleURLTypes
diff --git a/apps/ios/Tests/Info.plist b/apps/ios/Tests/Info.plist
index 80205f42821..46e3fb97eb1 100644
--- a/apps/ios/Tests/Info.plist
+++ b/apps/ios/Tests/Info.plist
@@ -17,7 +17,7 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 2026.3.8
+ 2026.3.9
CFBundleVersion
20260308
diff --git a/apps/ios/WatchApp/Info.plist b/apps/ios/WatchApp/Info.plist
index b0d365e4f7a..fa45d719b9c 100644
--- a/apps/ios/WatchApp/Info.plist
+++ b/apps/ios/WatchApp/Info.plist
@@ -17,7 +17,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 2026.3.8
+ 2026.3.9
CFBundleVersion
20260308
WKCompanionAppBundleIdentifier
diff --git a/apps/ios/WatchExtension/Info.plist b/apps/ios/WatchExtension/Info.plist
index 4d0bdb2ca13..1d898d43757 100644
--- a/apps/ios/WatchExtension/Info.plist
+++ b/apps/ios/WatchExtension/Info.plist
@@ -15,7 +15,7 @@
CFBundleName
$(PRODUCT_NAME)
CFBundleShortVersionString
- 2026.3.8
+ 2026.3.9
CFBundleVersion
20260308
NSExtension
diff --git a/apps/ios/project.yml b/apps/ios/project.yml
index 3d2bc93af80..0664db9c6be 100644
--- a/apps/ios/project.yml
+++ b/apps/ios/project.yml
@@ -107,7 +107,7 @@ targets:
- CFBundleURLName: ai.openclaw.ios
CFBundleURLSchemes:
- openclaw
- CFBundleShortVersionString: "2026.3.8"
+ CFBundleShortVersionString: "2026.3.9"
CFBundleVersion: "20260308"
UILaunchScreen: {}
UIApplicationSceneManifest:
@@ -168,7 +168,7 @@ targets:
path: ShareExtension/Info.plist
properties:
CFBundleDisplayName: OpenClaw Share
- CFBundleShortVersionString: "2026.3.8"
+ CFBundleShortVersionString: "2026.3.9"
CFBundleVersion: "20260308"
NSExtension:
NSExtensionPointIdentifier: com.apple.share-services
@@ -205,7 +205,7 @@ targets:
path: ActivityWidget/Info.plist
properties:
CFBundleDisplayName: OpenClaw Activity
- CFBundleShortVersionString: "2026.3.8"
+ CFBundleShortVersionString: "2026.3.9"
CFBundleVersion: "20260308"
NSSupportsLiveActivities: true
NSExtension:
@@ -231,7 +231,7 @@ targets:
path: WatchApp/Info.plist
properties:
CFBundleDisplayName: OpenClaw
- CFBundleShortVersionString: "2026.3.8"
+ CFBundleShortVersionString: "2026.3.9"
CFBundleVersion: "20260308"
WKCompanionAppBundleIdentifier: "$(OPENCLAW_APP_BUNDLE_ID)"
WKWatchKitApp: true
@@ -256,7 +256,7 @@ targets:
path: WatchExtension/Info.plist
properties:
CFBundleDisplayName: OpenClaw
- CFBundleShortVersionString: "2026.3.8"
+ CFBundleShortVersionString: "2026.3.9"
CFBundleVersion: "20260308"
NSExtension:
NSExtensionAttributes:
@@ -293,7 +293,7 @@ targets:
path: Tests/Info.plist
properties:
CFBundleDisplayName: OpenClawTests
- CFBundleShortVersionString: "2026.3.8"
+ CFBundleShortVersionString: "2026.3.9"
CFBundleVersion: "20260308"
OpenClawLogicTests:
@@ -319,5 +319,5 @@ targets:
path: Tests/Info.plist
properties:
CFBundleDisplayName: OpenClawLogicTests
- CFBundleShortVersionString: "2026.3.8"
+ CFBundleShortVersionString: "2026.3.9"
CFBundleVersion: "20260308"
diff --git a/apps/macos/Sources/OpenClaw/Resources/Info.plist b/apps/macos/Sources/OpenClaw/Resources/Info.plist
index d394013fb43..706fe7029c4 100644
--- a/apps/macos/Sources/OpenClaw/Resources/Info.plist
+++ b/apps/macos/Sources/OpenClaw/Resources/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 2026.3.8
+ 2026.3.9
CFBundleVersion
202603080
CFBundleIconFile
diff --git a/docs/platforms/mac/release.md b/docs/platforms/mac/release.md
index 1bea6a839a0..180a52075ed 100644
--- a/docs/platforms/mac/release.md
+++ b/docs/platforms/mac/release.md
@@ -39,7 +39,7 @@ Notes:
# Default is auto-derived from APP_VERSION when omitted.
SKIP_NOTARIZE=1 \
BUNDLE_ID=ai.openclaw.mac \
-APP_VERSION=2026.3.8 \
+APP_VERSION=2026.3.9 \
BUILD_CONFIG=release \
SIGN_IDENTITY="Developer ID Application: ()" \
scripts/package-mac-dist.sh
@@ -47,10 +47,10 @@ scripts/package-mac-dist.sh
# `package-mac-dist.sh` already creates the zip + DMG.
# If you used `package-mac-app.sh` directly instead, create them manually:
# If you want notarization/stapling in this step, use the NOTARIZE command below.
-ditto -c -k --sequesterRsrc --keepParent dist/OpenClaw.app dist/OpenClaw-2026.3.8.zip
+ditto -c -k --sequesterRsrc --keepParent dist/OpenClaw.app dist/OpenClaw-2026.3.9.zip
# Optional: build a styled DMG for humans (drag to /Applications)
-scripts/create-dmg.sh dist/OpenClaw.app dist/OpenClaw-2026.3.8.dmg
+scripts/create-dmg.sh dist/OpenClaw.app dist/OpenClaw-2026.3.9.dmg
# Recommended: build + notarize/staple zip + DMG
# First, create a keychain profile once:
@@ -58,13 +58,13 @@ scripts/create-dmg.sh dist/OpenClaw.app dist/OpenClaw-2026.3.8.dmg
# --apple-id "" --team-id "" --password ""
NOTARIZE=1 NOTARYTOOL_PROFILE=openclaw-notary \
BUNDLE_ID=ai.openclaw.mac \
-APP_VERSION=2026.3.8 \
+APP_VERSION=2026.3.9 \
BUILD_CONFIG=release \
SIGN_IDENTITY="Developer ID Application: ()" \
scripts/package-mac-dist.sh
# Optional: ship dSYM alongside the release
-ditto -c -k --keepParent apps/macos/.build/release/OpenClaw.app.dSYM dist/OpenClaw-2026.3.8.dSYM.zip
+ditto -c -k --keepParent apps/macos/.build/release/OpenClaw.app.dSYM dist/OpenClaw-2026.3.9.dSYM.zip
```
## Appcast entry
@@ -72,7 +72,7 @@ ditto -c -k --keepParent apps/macos/.build/release/OpenClaw.app.dSYM dist/OpenCl
Use the release note generator so Sparkle renders formatted HTML notes:
```bash
-SPARKLE_PRIVATE_KEY_FILE=/path/to/ed25519-private-key scripts/make_appcast.sh dist/OpenClaw-2026.3.8.zip https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml
+SPARKLE_PRIVATE_KEY_FILE=/path/to/ed25519-private-key scripts/make_appcast.sh dist/OpenClaw-2026.3.9.zip https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml
```
Generates HTML release notes from `CHANGELOG.md` (via [`scripts/changelog-to-html.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/changelog-to-html.sh)) and embeds them in the appcast entry.
@@ -80,7 +80,7 @@ Commit the updated `appcast.xml` alongside the release assets (zip + dSYM) when
## Publish & verify
-- Upload `OpenClaw-2026.3.8.zip` (and `OpenClaw-2026.3.8.dSYM.zip`) to the GitHub release for tag `v2026.3.8`.
+- Upload `OpenClaw-2026.3.9.zip` (and `OpenClaw-2026.3.9.dSYM.zip`) to the GitHub release for tag `v2026.3.9`.
- Ensure the raw appcast URL matches the baked feed: `https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml`.
- Sanity checks:
- `curl -I https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml` returns 200.
diff --git a/extensions/acpx/package.json b/extensions/acpx/package.json
index ae560c8e9af..27d9296a9a2 100644
--- a/extensions/acpx/package.json
+++ b/extensions/acpx/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/acpx",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw ACP runtime backend via acpx",
"type": "module",
"dependencies": {
diff --git a/extensions/bluebubbles/package.json b/extensions/bluebubbles/package.json
index 80d314cee38..3c8605ef312 100644
--- a/extensions/bluebubbles/package.json
+++ b/extensions/bluebubbles/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/bluebubbles",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw BlueBubbles channel plugin",
"type": "module",
"dependencies": {
diff --git a/extensions/copilot-proxy/package.json b/extensions/copilot-proxy/package.json
index 9d72a353069..e060ddd67f1 100644
--- a/extensions/copilot-proxy/package.json
+++ b/extensions/copilot-proxy/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/copilot-proxy",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw Copilot Proxy provider plugin",
"type": "module",
diff --git a/extensions/diagnostics-otel/package.json b/extensions/diagnostics-otel/package.json
index 27dcdda7fb1..29c9b0ac79b 100644
--- a/extensions/diagnostics-otel/package.json
+++ b/extensions/diagnostics-otel/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/diagnostics-otel",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw diagnostics OpenTelemetry exporter",
"type": "module",
"dependencies": {
diff --git a/extensions/diffs/package.json b/extensions/diffs/package.json
index 5df160b125a..b685f985108 100644
--- a/extensions/diffs/package.json
+++ b/extensions/diffs/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/diffs",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw diff viewer plugin",
"type": "module",
diff --git a/extensions/discord/package.json b/extensions/discord/package.json
index 607a0a8dd3b..f30f10ade51 100644
--- a/extensions/discord/package.json
+++ b/extensions/discord/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/discord",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw Discord channel plugin",
"type": "module",
"openclaw": {
diff --git a/extensions/feishu/package.json b/extensions/feishu/package.json
index 7fcd26f67fc..fc38816e1bd 100644
--- a/extensions/feishu/package.json
+++ b/extensions/feishu/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/feishu",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw Feishu/Lark channel plugin (community maintained by @m1heng)",
"type": "module",
"dependencies": {
diff --git a/extensions/google-gemini-cli-auth/package.json b/extensions/google-gemini-cli-auth/package.json
index 2e5eca8365a..2ab1c6a6ca8 100644
--- a/extensions/google-gemini-cli-auth/package.json
+++ b/extensions/google-gemini-cli-auth/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/google-gemini-cli-auth",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw Gemini CLI OAuth provider plugin",
"type": "module",
diff --git a/extensions/googlechat/package.json b/extensions/googlechat/package.json
index 3fbfb30a472..2abe2abbe38 100644
--- a/extensions/googlechat/package.json
+++ b/extensions/googlechat/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/googlechat",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw Google Chat channel plugin",
"type": "module",
diff --git a/extensions/imessage/package.json b/extensions/imessage/package.json
index 1a350de2146..3f38e01efe1 100644
--- a/extensions/imessage/package.json
+++ b/extensions/imessage/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/imessage",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw iMessage channel plugin",
"type": "module",
diff --git a/extensions/irc/package.json b/extensions/irc/package.json
index 44040e8428b..34c7de1dcfb 100644
--- a/extensions/irc/package.json
+++ b/extensions/irc/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/irc",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw IRC channel plugin",
"type": "module",
"dependencies": {
diff --git a/extensions/line/package.json b/extensions/line/package.json
index 227da7e8f84..9ec37f833e7 100644
--- a/extensions/line/package.json
+++ b/extensions/line/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/line",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw LINE channel plugin",
"type": "module",
diff --git a/extensions/llm-task/package.json b/extensions/llm-task/package.json
index 1cdcdf7cb83..8a74b2ead7e 100644
--- a/extensions/llm-task/package.json
+++ b/extensions/llm-task/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/llm-task",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw JSON-only LLM task plugin",
"type": "module",
diff --git a/extensions/lobster/package.json b/extensions/lobster/package.json
index 67495efb300..4c137401fbb 100644
--- a/extensions/lobster/package.json
+++ b/extensions/lobster/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/lobster",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "Lobster workflow tool plugin (typed pipelines + resumable approvals)",
"type": "module",
"dependencies": {
diff --git a/extensions/matrix/CHANGELOG.md b/extensions/matrix/CHANGELOG.md
index 8a8bbcb87f4..a3b32a18c85 100644
--- a/extensions/matrix/CHANGELOG.md
+++ b/extensions/matrix/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 2026.3.9
+
+### Changes
+
+- Version alignment with core OpenClaw release numbers.
+
## 2026.3.8-beta.1
### Changes
diff --git a/extensions/matrix/package.json b/extensions/matrix/package.json
index 11fa647936a..c1b5859b43e 100644
--- a/extensions/matrix/package.json
+++ b/extensions/matrix/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/matrix",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw Matrix channel plugin",
"type": "module",
"dependencies": {
diff --git a/extensions/mattermost/package.json b/extensions/mattermost/package.json
index 1b823e4d08b..d532764db87 100644
--- a/extensions/mattermost/package.json
+++ b/extensions/mattermost/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/mattermost",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw Mattermost channel plugin",
"type": "module",
"dependencies": {
diff --git a/extensions/memory-core/package.json b/extensions/memory-core/package.json
index ce7521de44a..ca697290047 100644
--- a/extensions/memory-core/package.json
+++ b/extensions/memory-core/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/memory-core",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw core memory search plugin",
"type": "module",
diff --git a/extensions/memory-lancedb/package.json b/extensions/memory-lancedb/package.json
index 067b32446eb..abd920833ca 100644
--- a/extensions/memory-lancedb/package.json
+++ b/extensions/memory-lancedb/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/memory-lancedb",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw LanceDB-backed long-term memory plugin with auto-recall/capture",
"type": "module",
diff --git a/extensions/minimax-portal-auth/package.json b/extensions/minimax-portal-auth/package.json
index b588a963474..9443f37d524 100644
--- a/extensions/minimax-portal-auth/package.json
+++ b/extensions/minimax-portal-auth/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/minimax-portal-auth",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw MiniMax Portal OAuth provider plugin",
"type": "module",
diff --git a/extensions/msteams/CHANGELOG.md b/extensions/msteams/CHANGELOG.md
index 4ca638b8f7c..38d5614305c 100644
--- a/extensions/msteams/CHANGELOG.md
+++ b/extensions/msteams/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 2026.3.9
+
+### Changes
+
+- Version alignment with core OpenClaw release numbers.
+
## 2026.3.8-beta.1
### Changes
diff --git a/extensions/msteams/package.json b/extensions/msteams/package.json
index c6b4106ee05..c4453f82f6e 100644
--- a/extensions/msteams/package.json
+++ b/extensions/msteams/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/msteams",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw Microsoft Teams channel plugin",
"type": "module",
"dependencies": {
diff --git a/extensions/nextcloud-talk/package.json b/extensions/nextcloud-talk/package.json
index bef40590adc..96797d4b76e 100644
--- a/extensions/nextcloud-talk/package.json
+++ b/extensions/nextcloud-talk/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/nextcloud-talk",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw Nextcloud Talk channel plugin",
"type": "module",
"dependencies": {
diff --git a/extensions/nostr/CHANGELOG.md b/extensions/nostr/CHANGELOG.md
index 7daad7c06f9..3088efcc2bb 100644
--- a/extensions/nostr/CHANGELOG.md
+++ b/extensions/nostr/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 2026.3.9
+
+### Changes
+
+- Version alignment with core OpenClaw release numbers.
+
## 2026.3.8-beta.1
### Changes
diff --git a/extensions/nostr/package.json b/extensions/nostr/package.json
index c6fdf0056d4..dbee4bc09d7 100644
--- a/extensions/nostr/package.json
+++ b/extensions/nostr/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/nostr",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw Nostr channel plugin for NIP-04 encrypted DMs",
"type": "module",
"dependencies": {
diff --git a/extensions/open-prose/package.json b/extensions/open-prose/package.json
index d323b6ca9e6..240a2bbcb41 100644
--- a/extensions/open-prose/package.json
+++ b/extensions/open-prose/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/open-prose",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenProse VM skill pack plugin (slash command + telemetry).",
"type": "module",
diff --git a/extensions/signal/package.json b/extensions/signal/package.json
index 88fe04ac1e4..743c8212d31 100644
--- a/extensions/signal/package.json
+++ b/extensions/signal/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/signal",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw Signal channel plugin",
"type": "module",
diff --git a/extensions/slack/package.json b/extensions/slack/package.json
index cf62b6ce627..539541bdc6d 100644
--- a/extensions/slack/package.json
+++ b/extensions/slack/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/slack",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw Slack channel plugin",
"type": "module",
diff --git a/extensions/synology-chat/package.json b/extensions/synology-chat/package.json
index ff83998b456..00503898817 100644
--- a/extensions/synology-chat/package.json
+++ b/extensions/synology-chat/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/synology-chat",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "Synology Chat channel plugin for OpenClaw",
"type": "module",
"dependencies": {
diff --git a/extensions/telegram/package.json b/extensions/telegram/package.json
index eba1967b064..6602b46f2c8 100644
--- a/extensions/telegram/package.json
+++ b/extensions/telegram/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/telegram",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw Telegram channel plugin",
"type": "module",
diff --git a/extensions/tlon/package.json b/extensions/tlon/package.json
index 159daa5e69d..0cb79328d89 100644
--- a/extensions/tlon/package.json
+++ b/extensions/tlon/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/tlon",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw Tlon/Urbit channel plugin",
"type": "module",
"dependencies": {
diff --git a/extensions/twitch/CHANGELOG.md b/extensions/twitch/CHANGELOG.md
index 3ef565f84a9..48160f427e8 100644
--- a/extensions/twitch/CHANGELOG.md
+++ b/extensions/twitch/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 2026.3.9
+
+### Changes
+
+- Version alignment with core OpenClaw release numbers.
+
## 2026.3.8-beta.1
### Changes
diff --git a/extensions/twitch/package.json b/extensions/twitch/package.json
index 04bdf10977b..5fbf49cc971 100644
--- a/extensions/twitch/package.json
+++ b/extensions/twitch/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/twitch",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw Twitch channel plugin",
"type": "module",
"dependencies": {
diff --git a/extensions/voice-call/CHANGELOG.md b/extensions/voice-call/CHANGELOG.md
index 6bd0d2aadeb..a8a4586116c 100644
--- a/extensions/voice-call/CHANGELOG.md
+++ b/extensions/voice-call/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 2026.3.9
+
+### Changes
+
+- Version alignment with core OpenClaw release numbers.
+
## 2026.3.8-beta.1
### Changes
diff --git a/extensions/voice-call/package.json b/extensions/voice-call/package.json
index c01c2194cb4..420f8b41560 100644
--- a/extensions/voice-call/package.json
+++ b/extensions/voice-call/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/voice-call",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw voice-call plugin",
"type": "module",
"dependencies": {
diff --git a/extensions/whatsapp/package.json b/extensions/whatsapp/package.json
index b3cf0a655c3..c87a5f26c2b 100644
--- a/extensions/whatsapp/package.json
+++ b/extensions/whatsapp/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/whatsapp",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"private": true,
"description": "OpenClaw WhatsApp channel plugin",
"type": "module",
diff --git a/extensions/zalo/CHANGELOG.md b/extensions/zalo/CHANGELOG.md
index 647dc8c3f45..5ae5323034f 100644
--- a/extensions/zalo/CHANGELOG.md
+++ b/extensions/zalo/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 2026.3.9
+
+### Changes
+
+- Version alignment with core OpenClaw release numbers.
+
## 2026.3.8-beta.1
### Changes
diff --git a/extensions/zalo/package.json b/extensions/zalo/package.json
index 30de1e0ea03..6de5909736f 100644
--- a/extensions/zalo/package.json
+++ b/extensions/zalo/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/zalo",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw Zalo channel plugin",
"type": "module",
"dependencies": {
diff --git a/extensions/zalouser/CHANGELOG.md b/extensions/zalouser/CHANGELOG.md
index 15ecfd974cc..10c22ce4029 100644
--- a/extensions/zalouser/CHANGELOG.md
+++ b/extensions/zalouser/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 2026.3.9
+
+### Changes
+
+- Version alignment with core OpenClaw release numbers.
+
## 2026.3.8-beta.1
### Changes
diff --git a/extensions/zalouser/package.json b/extensions/zalouser/package.json
index 9f352c14361..79bf5723d48 100644
--- a/extensions/zalouser/package.json
+++ b/extensions/zalouser/package.json
@@ -1,6 +1,6 @@
{
"name": "@openclaw/zalouser",
- "version": "2026.3.8-beta.1",
+ "version": "2026.3.9",
"description": "OpenClaw Zalo Personal Account plugin via native zca-js integration",
"type": "module",
"dependencies": {
diff --git a/package.json b/package.json
index 5f6d8930124..bc625b74e71 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "openclaw",
- "version": "2026.3.8",
+ "version": "2026.3.9",
"description": "Multi-channel AI gateway with extensible messaging integrations",
"keywords": [],
"homepage": "https://github.com/openclaw/openclaw#readme",
diff --git a/src/commands/onboard-non-interactive.provider-auth.test.ts b/src/commands/onboard-non-interactive.provider-auth.test.ts
index 390d19b0154..d72de28a61d 100644
--- a/src/commands/onboard-non-interactive.provider-auth.test.ts
+++ b/src/commands/onboard-non-interactive.provider-auth.test.ts
@@ -42,6 +42,11 @@ let upsertAuthProfile: typeof import("../agents/auth-profiles.js").upsertAuthPro
type ProviderAuthConfigSnapshot = {
auth?: { profiles?: Record };
agents?: { defaults?: { model?: { primary?: string } } };
+ talk?: {
+ provider?: string;
+ apiKey?: string | { source?: string; id?: string };
+ providers?: Record;
+ };
models?: {
providers?: Record<
string,
@@ -357,6 +362,38 @@ describe("onboard (non-interactive): provider auth", () => {
});
});
+ it("does not persist talk fallback secrets when OpenAI ref onboarding starts from an empty config", async () => {
+ await withOnboardEnv("openclaw-onboard-openai-ref-no-talk-leak-", async (env) => {
+ await withEnvAsync(
+ {
+ OPENAI_API_KEY: "sk-openai-env-key", // pragma: allowlist secret
+ ELEVENLABS_API_KEY: "elevenlabs-env-key", // pragma: allowlist secret
+ },
+ async () => {
+ const cfg = await runOnboardingAndReadConfig(env, {
+ authChoice: "openai-api-key",
+ secretInputMode: "ref", // pragma: allowlist secret
+ });
+
+ expect(cfg.agents?.defaults?.model?.primary).toBe(OPENAI_DEFAULT_MODEL);
+ expect(cfg.talk).toBeUndefined();
+
+ const store = ensureAuthProfileStore();
+ const profile = store.profiles["openai:default"];
+ expect(profile?.type).toBe("api_key");
+ if (profile?.type === "api_key") {
+ expect(profile.key).toBeUndefined();
+ expect(profile.keyRef).toEqual({
+ source: "env",
+ provider: "default",
+ id: "OPENAI_API_KEY",
+ });
+ }
+ },
+ );
+ });
+ });
+
it.each([
{
name: "anthropic",
diff --git a/src/commands/onboard-non-interactive.ts b/src/commands/onboard-non-interactive.ts
index 4b4d1223226..ee2b3498180 100644
--- a/src/commands/onboard-non-interactive.ts
+++ b/src/commands/onboard-non-interactive.ts
@@ -20,7 +20,7 @@ export async function runNonInteractiveOnboarding(
return;
}
- const baseConfig: OpenClawConfig = snapshot.valid ? snapshot.config : {};
+ const baseConfig: OpenClawConfig = snapshot.valid ? (snapshot.exists ? snapshot.config : {}) : {};
const mode = opts.mode ?? "local";
if (mode !== "local" && mode !== "remote") {
runtime.error(`Invalid --mode "${String(mode)}" (use local|remote).`);
diff --git a/src/daemon/launchd.ts b/src/daemon/launchd.ts
index 11e0bd50d20..492eb2e4d6e 100644
--- a/src/daemon/launchd.ts
+++ b/src/daemon/launchd.ts
@@ -276,8 +276,8 @@ export async function uninstallLegacyLaunchAgents({
return agents;
}
- const home = resolveHomeDir(env);
- const trashDir = path.join(home, ".Trash");
+ const home = toPosixPath(resolveHomeDir(env));
+ const trashDir = path.posix.join(home, ".Trash");
try {
await fs.mkdir(trashDir, { recursive: true });
} catch {
@@ -323,8 +323,8 @@ export async function uninstallLaunchAgent({
return;
}
- const home = resolveHomeDir(env);
- const trashDir = path.join(home, ".Trash");
+ const home = toPosixPath(resolveHomeDir(env));
+ const trashDir = path.posix.join(home, ".Trash");
const dest = path.join(trashDir, `${label}.plist`);
try {
await fs.mkdir(trashDir, { recursive: true });
@@ -415,9 +415,10 @@ export async function installLaunchAgent({
}
const plistPath = resolveLaunchAgentPlistPathForLabel(env, label);
- const home = resolveHomeDir(env);
+ const home = toPosixPath(resolveHomeDir(env));
+ const libraryDir = path.posix.join(home, "Library");
await ensureSecureDirectory(home);
- await ensureSecureDirectory(path.join(home, "Library"));
+ await ensureSecureDirectory(libraryDir);
await ensureSecureDirectory(path.dirname(plistPath));
const serviceDescription = resolveGatewayServiceDescription({ env, environment, description });
diff --git a/src/infra/git-commit.test.ts b/src/infra/git-commit.test.ts
index 26be4322ad8..d00c50fbf6f 100644
--- a/src/infra/git-commit.test.ts
+++ b/src/infra/git-commit.test.ts
@@ -198,7 +198,7 @@ describe("git commit resolution", () => {
await fs.mkdir(path.join(packageRoot, "dist"), { recursive: true });
await fs.writeFile(
path.join(packageRoot, "package.json"),
- JSON.stringify({ name: "openclaw", version: "2026.3.8" }),
+ JSON.stringify({ name: "openclaw", version: "2026.3.9" }),
"utf-8",
);
const moduleUrl = pathToFileURL(path.join(packageRoot, "dist", "entry.js")).href;
diff --git a/src/install-sh-version.test.ts b/src/install-sh-version.test.ts
index 4a7135925b8..824a5366efd 100644
--- a/src/install-sh-version.test.ts
+++ b/src/install-sh-version.test.ts
@@ -73,10 +73,10 @@ describe("install.sh version resolution", () => {
it.runIf(process.platform !== "win32")(
"extracts the semantic version from decorated CLI output",
() => {
- const fixture = withFakeCli("OpenClaw 2026.3.8 (abcdef0)");
+ const fixture = withFakeCli("OpenClaw 2026.3.9 (abcdef0)");
tempRoots.push(fixture.root);
- expect(resolveVersionFromInstaller(fixture.cliPath)).toBe("2026.3.8");
+ expect(resolveVersionFromInstaller(fixture.cliPath)).toBe("2026.3.9");
},
);
@@ -93,7 +93,7 @@ describe("install.sh version resolution", () => {
it.runIf(process.platform !== "win32")(
"does not source version helpers from cwd when installer runs via stdin",
() => {
- const fixture = withFakeCli("OpenClaw 2026.3.8 (abcdef0)");
+ const fixture = withFakeCli("OpenClaw 2026.3.9 (abcdef0)");
tempRoots.push(fixture.root);
const hostileCwd = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-install-stdin-"));
@@ -115,7 +115,7 @@ extract_openclaw_semver() {
"utf-8",
);
- expect(resolveVersionFromInstallerViaStdin(fixture.cliPath, hostileCwd)).toBe("2026.3.8");
+ expect(resolveVersionFromInstallerViaStdin(fixture.cliPath, hostileCwd)).toBe("2026.3.9");
},
);
});
diff --git a/src/wizard/onboarding.ts b/src/wizard/onboarding.ts
index e2a81537eb7..47825eeae52 100644
--- a/src/wizard/onboarding.ts
+++ b/src/wizard/onboarding.ts
@@ -81,7 +81,7 @@ export async function runOnboardingWizard(
await requireRiskAcknowledgement({ opts, prompter });
const snapshot = await readConfigFileSnapshot();
- let baseConfig: OpenClawConfig = snapshot.valid ? snapshot.config : {};
+ let baseConfig: OpenClawConfig = snapshot.valid ? (snapshot.exists ? snapshot.config : {}) : {};
if (snapshot.exists && !snapshot.valid) {
await prompter.note(onboardHelpers.summarizeExistingConfig(baseConfig), "Invalid config");