Skip to content

Commit ce91ed5

Browse files
author
snowzlm
committed
Merge remote-tracking branch 'origin/main' into fix/responses-store-false-replay
2 parents 26b6931 + ed4c4af commit ce91ed5

693 files changed

Lines changed: 35403 additions & 8494 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/autoreview/SKILL.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Use when:
2222
- Read dependency docs/source/types when the finding depends on external behavior.
2323
- Reject unrealistic edge cases, speculative risks, broad rewrites, and fixes that over-complicate the codebase.
2424
- Prefer small fixes at the right ownership boundary; no refactor unless it clearly improves the bug class.
25+
- When an accepted finding shows a bug class or repeated pattern, inspect the current PR scope for sibling instances before fixing.
26+
- Fix the scoped bug class at once when practical; stop at touched surfaces, owner boundaries, and clear follow-up territory.
2527
- Keep going until structured review returns no accepted/actionable findings.
2628
- If a review-triggered fix changes code, rerun focused tests and rerun the structured review helper.
2729
- For security-audit suppression changes, verify accepted findings remain auditable: suppressed findings stay in structured output, active output keeps an unsuppressible suppression notice, and aggregate findings cannot hide unrelated active risk.

.github/workflows/crabbox-hydrate.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,21 @@ jobs:
120120
append_pnpm_option_arg PNPM_CONFIG_MODULES_DIR modules-dir
121121
append_pnpm_option_arg PNPM_CONFIG_NETWORK_CONCURRENCY network-concurrency
122122
append_pnpm_option_arg PNPM_CONFIG_VIRTUAL_STORE_DIR virtual-store-dir
123+
reset_crabbox_pnpm_path() {
124+
local path="$1"
125+
if [ -z "$path" ]; then
126+
return
127+
fi
128+
case "$path" in
129+
/var/tmp/openclaw-pnpm-*) rm -rf "$path" ;;
130+
esac
131+
}
132+
reset_crabbox_pnpm_path "${PNPM_CONFIG_MODULES_DIR:-}"
133+
reset_crabbox_pnpm_path "${PNPM_CONFIG_STORE_DIR:-}"
134+
reset_crabbox_pnpm_path "${PNPM_CONFIG_VIRTUAL_STORE_DIR:-}"
135+
if [ -L node_modules ] && [ "$(readlink node_modules)" = "${PNPM_CONFIG_MODULES_DIR:-}" ]; then
136+
rm -f node_modules
137+
fi
123138
if [ -n "${PNPM_CONFIG_MODULES_DIR:-}" ]; then
124139
mkdir -p "$PNPM_CONFIG_MODULES_DIR"
125140
ln -sfn . "$PNPM_CONFIG_MODULES_DIR/node_modules"

.github/workflows/full-release-validation.yml

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ jobs:
229229
needs: [resolve_target]
230230
if: inputs.rerun_group == 'all'
231231
runs-on: ubuntu-24.04
232-
timeout-minutes: 45
232+
timeout-minutes: 20
233233
permissions:
234234
contents: read
235235
steps:
@@ -245,54 +245,11 @@ jobs:
245245
DOCKER_BUILDKIT: "1"
246246
run: |
247247
set -euo pipefail
248-
timeout --kill-after=30s 35m docker build \
248+
timeout --kill-after=30s 15m docker build \
249249
--target runtime-assets \
250250
--build-arg OPENCLAW_EXTENSIONS="diagnostics-otel,codex" \
251251
.
252252
253-
- name: Build and smoke test final Docker runtime image
254-
env:
255-
DOCKER_BUILDKIT: "1"
256-
TARGET_SHA: ${{ needs.resolve_target.outputs.sha }}
257-
run: |
258-
set -euo pipefail
259-
image_ref="openclaw-release-runtime-smoke:${TARGET_SHA}"
260-
timeout --kill-after=30s 35m docker build \
261-
--build-arg OPENCLAW_EXTENSIONS="diagnostics-otel,codex" \
262-
-t "${image_ref}" \
263-
.
264-
docker run --rm --entrypoint /bin/sh "${image_ref}" -lc '
265-
set -eu
266-
test -f /app/src/agents/templates/HEARTBEAT.md
267-
temp_root="$(mktemp -d)"
268-
trap "rm -rf \"${temp_root}\"" EXIT
269-
mkdir -p "${temp_root}/home" "${temp_root}/cwd"
270-
cd "${temp_root}/cwd"
271-
set +e
272-
HOME="${temp_root}/home" \
273-
USERPROFILE="${temp_root}/home" \
274-
OPENCLAW_HOME="${temp_root}/home" \
275-
OPENCLAW_NO_ONBOARD=1 \
276-
OPENCLAW_SUPPRESS_NOTES=1 \
277-
OPENCLAW_DISABLE_BUNDLED_PLUGINS=1 \
278-
OPENCLAW_DISABLE_BUNDLED_ENTRY_SOURCE_FALLBACK=1 \
279-
AWS_EC2_METADATA_DISABLED=true \
280-
AWS_SHARED_CREDENTIALS_FILE="${temp_root}/home/.aws/credentials" \
281-
AWS_CONFIG_FILE="${temp_root}/home/.aws/config" \
282-
node /app/openclaw.mjs agent --message "workspace bootstrap smoke" --session-id "workspace-bootstrap-smoke" --local --timeout 1 --json \
283-
>"${temp_root}/out.log" 2>&1
284-
status="$?"
285-
set -e
286-
if grep -F "Missing workspace template:" "${temp_root}/out.log"; then
287-
cat "${temp_root}/out.log"
288-
exit 1
289-
fi
290-
test -f "${temp_root}/home/.openclaw/workspace/HEARTBEAT.md"
291-
if [ "${status}" -ne 0 ]; then
292-
cat "${temp_root}/out.log"
293-
fi
294-
'
295-
296253
normal_ci:
297254
name: Run normal full CI
298255
needs: [resolve_target, docker_runtime_assets_preflight]

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,27 @@ Docs: https://docs.openclaw.ai
4545

4646
### Fixes
4747

48+
- Agents/providers: avoid loading owner plugin runtimes for explicitly configured custom provider models during OpenAI-compatible transport setup.
49+
- Release/CI/E2E: fail early when Crabbox sparse-sync full checkouts do not have enough local disk, with guidance for moving the sync root.
50+
- Release/CI/E2E: reset shared Crabbox pnpm hydrate state before installs so stale `/var/tmp` stores cannot leave `pnpm install` spinning after completion.
51+
- Release/CI/E2E: print heartbeat progress during centralized Docker builds while keeping successful build logs quiet.
52+
- Release/CI/E2E: avoid heartbeat-tail delays in Docker E2E log wrappers while reporting captured log bytes during long runs.
53+
- Release/CI/E2E: keep release user-journey logs and temporary plugin fixtures under per-run scratch roots so parallel runs cannot collide or leak artifacts.
54+
- Release/CI/E2E: bound release candidate GitHub API calls so stalled network requests cannot wedge workflow and artifact polling.
55+
- Control UI: lazy-load the usage view so the initial app bundle stays below the chunk warning threshold.
56+
- Build: keep Baileys optional image backends external so source builds do not warn about missing `jimp` or `sharp`.
57+
- Build: render independent CLI startup metadata help snapshots concurrently to cut cold build-all metadata time.
58+
- Plugins: stop timed-out package-boundary prep steps by process group so descendant TypeScript/helper processes do not survive local check cleanup.
59+
- Control UI: serve static assets asynchronously after safe-open checks so large UI files do not block Gateway request handling.
60+
- Scripts/UI: forward direct wrapper SIGHUP shutdown to child processes so terminal hangups do not leave wrapped dev commands running.
61+
- Gateway: return the post-expiration pending-work revision from node drains so reconnecting nodes do not observe stale queue revisions after expired items are pruned.
62+
- Release/CI/E2E: keep temporary full-sync checkouts alive while slow Crabbox leases boot, so sparse worktree runs do not lose their sync source before file-list generation.
63+
- Release/CI/E2E: normalize inherited Linux `C.UTF-8` locale settings before raw AWS macOS Crabbox bootstrap commands, avoiding macOS locale warnings during package-manager hydration.
64+
- Release/CI/E2E: keep gateway watch regression checks from copying large static plugin assets inside the measured idle window.
65+
- Update: keep core updates nonblocking when a missing external plugin repair download stalls, while still blocking installed active plugin payload smoke failures.
66+
- Agents/providers: keep streaming tool-call argument parsing record-shaped when providers emit valid non-object JSON such as `null` or arrays.
67+
- Release/CI/E2E: reset incremental log readers when watched log files rotate without shrinking, so same-size replacements do not hide new readiness or RPC lines.
68+
- Talk: preserve explicit `null` payloads on controller-created turn and output-audio lifecycle events.
4869
- Agents/TUI: keep local custom provider runs from loading plugin runtime and auth alias metadata when plugins are disabled.
4970
- Agents/TUI: restore in-flight TUI run switch-back behavior, keep no-policy native hook fallback available, guard vanished workspaces, and keep lightweight isolated subagents lightweight.
5071
- Agents/media: keep async image, music, and video generation starts from ending the Codex turn, so mixed requests can continue with summaries or other work while media renders in the background.
@@ -64,6 +85,7 @@ Docs: https://docs.openclaw.ai
6485
- Cron: keep SQLite cron migrations compatible with legacy run-log tables, archived job stores, diagnostic cron names, and legacy one-shot delete-after-run behavior. (#88285)
6586
- Cron: keep update delivery validation scoped, harden restart state, and retire MCP runtimes on isolated cron cleanup.
6687
- Memory: serialize QMD update/embed writes per store, preserve phase signals on read errors, harden envelope metadata sanitization, and rewrite generated transcript paths on rollover so memory/search state survives concurrent gateway and CLI activity. (#66339, #85931) Thanks @openperf and @amittell.
88+
- Memory: keep vector-disabled FTS indexes from resolving embedding providers during sync and search.
6789
- Providers: bound generated media downloads from OpenAI, Runway, xAI, MiniMax, BytePlus, DashScope-compatible, FAL, OpenRouter, Google, Vydra, and Comfy providers.
6890
- Providers: resolve Google defaults to `google-generative-ai`, register Vertex static catalog rows, align Foundry reasoning metadata, skip DeepSeek V4 thinking params on Foundry fallback, use MiniMax account OAuth endpoints, preserve Copilot Claude 1M capabilities, suppress disabled Ollama reasoning output, keep OpenAI stop-finished tool calls, and avoid replay ids when the Responses store is disabled. (#88480, #88512)
6991
- Providers: cap GitHub Copilot OAuth request timeouts before creating abort signals.

apps/android/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ Current OpenClaw Android implication:
218218
- Google Play build excludes SMS send/search, Call Log search, and recent-photo access unless the product is intentionally positioned and approved under the relevant policy exception.
219219
- The repo now ships this split as Android product flavors:
220220
- `play`: removes `READ_SMS`, `SEND_SMS`, `READ_CALL_LOG`, `READ_MEDIA_IMAGES`, `READ_MEDIA_VISUAL_USER_SELECTED`, and `READ_EXTERNAL_STORAGE`; hides SMS, Call Log, and Photos surfaces in onboarding, settings, and advertised node capabilities.
221+
- Installed-app listing is user controlled. `device.apps` is advertised only after the user enables **Settings > Phone Capabilities > Installed Apps**. The command defaults to launcher-visible apps and does not require `QUERY_ALL_PACKAGES`.
221222
- `thirdParty`: keeps the full permission set and the existing SMS / Call Log / Photos functionality.
222223

223224
Policy links:

apps/android/app/src/main/java/ai/openclaw/app/MainViewModel.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class MainViewModel(
148148
val gatewayBootstrapToken: StateFlow<String> = prefs.gatewayBootstrapToken
149149
val onboardingCompleted: StateFlow<Boolean> = prefs.onboardingCompleted
150150
val canvasDebugStatusEnabled: StateFlow<Boolean> = prefs.canvasDebugStatusEnabled
151+
val installedAppsSharingEnabled: StateFlow<Boolean> = prefs.installedAppsSharingEnabled
151152
val speakerEnabled: StateFlow<Boolean> = prefs.speakerEnabled
152153
val voiceCaptureMode: StateFlow<VoiceCaptureMode> = runtimeState(initial = VoiceCaptureMode.Off) { it.voiceCaptureMode }
153154
val micEnabled: StateFlow<Boolean> = runtimeState(initial = false) { it.micEnabled }
@@ -299,6 +300,10 @@ class MainViewModel(
299300
prefs.setCanvasDebugStatusEnabled(value)
300301
}
301302

303+
fun setInstalledAppsSharingEnabled(value: Boolean) {
304+
ensureRuntime().setInstalledAppsSharingEnabled(value)
305+
}
306+
302307
fun setNotificationForwardingEnabled(value: Boolean) {
303308
ensureRuntime().setNotificationForwardingEnabled(value)
304309
}

apps/android/app/src/main/java/ai/openclaw/app/NodeRuntime.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ class NodeRuntime(
207207
callLogAvailable = { SensitiveFeatureConfig.callLogEnabled },
208208
photosAvailable = { SensitiveFeatureConfig.photosEnabled },
209209
hasRecordAudioPermission = { hasRecordAudioPermission() },
210+
installedAppsSharingEnabled = { installedAppsSharingEnabled.value },
210211
manualTls = { manualTls.value },
211212
)
212213

@@ -245,6 +246,7 @@ class NodeRuntime(
245246
smsTelephonyAvailable = { sms.hasTelephonyFeature() },
246247
callLogAvailable = { SensitiveFeatureConfig.callLogEnabled },
247248
photosAvailable = { SensitiveFeatureConfig.photosEnabled },
249+
installedAppsSharingEnabled = { installedAppsSharingEnabled.value },
248250
debugBuild = { BuildConfig.DEBUG },
249251
onCanvasA2uiPush = {
250252
_canvasA2uiHydrated.value = true
@@ -866,6 +868,7 @@ class NodeRuntime(
866868

867869
val lastDiscoveredStableId: StateFlow<String> = prefs.lastDiscoveredStableId
868870
val canvasDebugStatusEnabled: StateFlow<Boolean> = prefs.canvasDebugStatusEnabled
871+
val installedAppsSharingEnabled: StateFlow<Boolean> = prefs.installedAppsSharingEnabled
869872
val notificationForwardingEnabled: StateFlow<Boolean> = prefs.notificationForwardingEnabled
870873
val notificationForwardingMode: StateFlow<NotificationPackageFilterMode> =
871874
prefs.notificationForwardingMode
@@ -1077,6 +1080,12 @@ class NodeRuntime(
10771080
prefs.setCanvasDebugStatusEnabled(value)
10781081
}
10791082

1083+
fun setInstalledAppsSharingEnabled(value: Boolean) {
1084+
if (prefs.installedAppsSharingEnabled.value == value) return
1085+
prefs.setInstalledAppsSharingEnabled(value)
1086+
refreshNodeSurfaceAfterSharingChange()
1087+
}
1088+
10801089
fun setNotificationForwardingEnabled(value: Boolean) {
10811090
prefs.setNotificationForwardingEnabled(value)
10821091
}
@@ -1414,6 +1423,11 @@ class NodeRuntime(
14141423
connectWithAuth(endpoint = endpoint, auth = resolveGatewayConnectAuth(), reconnect = true)
14151424
}
14161425

1426+
private fun refreshNodeSurfaceAfterSharingChange() {
1427+
val endpoint = connectedEndpoint ?: return
1428+
connectWithAuth(endpoint = endpoint, auth = resolveGatewayConnectAuth(), reconnect = true)
1429+
}
1430+
14171431
private fun connectWithAuth(
14181432
endpoint: GatewayEndpoint,
14191433
auth: GatewayConnectAuth,

apps/android/app/src/main/java/ai/openclaw/app/SecurePrefs.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,13 @@ class SecurePrefs(
4040
private const val notificationsForwardingMaxEventsPerMinuteKey =
4141
"notifications.forwarding.maxEventsPerMinute"
4242
private const val notificationsForwardingSessionKeyKey = "notifications.forwarding.sessionKey"
43+
private const val installedAppsSharingEnabledKey = "device.apps.sharing.enabled"
4344
private const val voiceMicEnabledKey = "voice.micEnabled"
4445
}
4546

4647
private val appContext = context.applicationContext
4748
private val json = Json { ignoreUnknownKeys = true }
49+
4850
// Non-secret UI/runtime preferences stay readable for migration and backup behavior.
4951
private val plainPrefs: SharedPreferences =
5052
appContext.getSharedPreferences(plainPrefsName, Context.MODE_PRIVATE)
@@ -114,6 +116,10 @@ class SecurePrefs(
114116
MutableStateFlow(plainPrefs.getBoolean("canvas.debugStatusEnabled", false))
115117
val canvasDebugStatusEnabled: StateFlow<Boolean> = _canvasDebugStatusEnabled
116118

119+
private val _installedAppsSharingEnabled =
120+
MutableStateFlow(plainPrefs.getBoolean(installedAppsSharingEnabledKey, false))
121+
val installedAppsSharingEnabled: StateFlow<Boolean> = _installedAppsSharingEnabled
122+
117123
private val _notificationForwardingEnabled =
118124
MutableStateFlow(plainPrefs.getBoolean(notificationsForwardingEnabledKey, defaultNotificationForwardingEnabled))
119125
val notificationForwardingEnabled: StateFlow<Boolean> = _notificationForwardingEnabled
@@ -252,6 +258,11 @@ class SecurePrefs(
252258
_canvasDebugStatusEnabled.value = value
253259
}
254260

261+
fun setInstalledAppsSharingEnabled(value: Boolean) {
262+
plainPrefs.edit { putBoolean(installedAppsSharingEnabledKey, value) }
263+
_installedAppsSharingEnabled.value = value
264+
}
265+
255266
internal fun getNotificationForwardingPolicy(appPackageName: String): NotificationForwardingPolicy {
256267
val modeRaw = plainPrefs.getString(notificationsForwardingModeKey, null)
257268
val mode = NotificationPackageFilterMode.fromRawValue(modeRaw)

apps/android/app/src/main/java/ai/openclaw/app/node/ConnectionManager.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ConnectionManager(
2828
private val callLogAvailable: () -> Boolean,
2929
private val photosAvailable: () -> Boolean,
3030
private val hasRecordAudioPermission: () -> Boolean,
31+
private val installedAppsSharingEnabled: () -> Boolean,
3132
private val manualTls: () -> Boolean,
3233
) {
3334
companion object {
@@ -115,6 +116,7 @@ class ConnectionManager(
115116
voiceWakeEnabled = voiceWakeMode() != VoiceWakeMode.Off && hasRecordAudioPermission(),
116117
motionActivityAvailable = motionActivityAvailable(),
117118
motionPedometerAvailable = motionPedometerAvailable(),
119+
installedAppsSharingEnabled = installedAppsSharingEnabled(),
118120
debugBuild = BuildConfig.DEBUG,
119121
)
120122

0 commit comments

Comments
 (0)