* test(agents): include Ollama in small live model matrix
* test: avoid Ollama cloud key in local live runs
* test: recognize Ollama env secret refs
* test: type Ollama live key fixtures
* test: prevent Ollama cloud auth in local live probes
* test: preserve equivalent Ollama live credentials
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Make the iOS app a universal iPhone+iPad app by targeting device family 1,2 in the XcodeGen source of truth.
Update iOS docs and App Store metadata so user-facing copy no longer describes the app as iPhone-only.
Verification:
- git diff --check
- cd apps/ios && xcodegen generate
- xcodebuild -project apps/ios/OpenClaw.xcodeproj -scheme OpenClaw -configuration Debug -destination 'platform=iOS Simulator,id=410B81D3-784E-4A01-B69C-490B79EAFCEA' CODE_SIGNING_ALLOWED=NO build
- GitHub CI: Real behavior proof, macos-swift, macos-node, check-docs, preflight, security-fast, actionlint, no-tabs, dependency-guard, OpenGrep
Thanks @EmpX2025.
Restore TUI switch-back adoption for backgrounded visible chat-send runs by surfacing a bounded `chat.history.inFlightRun` snapshot.
The snapshot keeps the run id even when buffered text is empty or over budget, filters live text through the same projection path as streaming chat, scopes bare global history to the default agent, and excludes hidden internal agent runs.
Proof:
- node scripts/run-vitest.mjs run src/gateway/chat-abort.test.ts src/tui/tui-session-actions.test.ts
- node scripts/run-tsgo.mjs -p tsconfig.core.json
- pnpm --silent exec oxfmt --check src/gateway/chat-abort.ts src/gateway/chat-abort.test.ts src/gateway/server-methods/chat.ts src/tui/tui-session-actions.ts src/tui/tui-session-actions.test.ts
- .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main
- CI: Real behavior proof, TUI PTY, dependency guard, OpenGrep precise diff, workflow sanity passed on PR head 2b8bf5f214.
Co-authored-by: William Liu <william@williamliu.ai>
Respect explicit PI/OpenClaw runtime policy when deciding whether Codex plugin diagnostics are actionable.
Diagnostics now use the resolved OpenAI route: intentional PI and custom OpenAI-compatible routes suppress only the missing `plugins.entries.codex` noise, while enabled/stale Codex policy still warns.
Proof: focused doctor/config/agent routing Vitest coverage, full lint, test types, dependency checks, isolated live doctor configs, autoreview clean, and GitHub CI green at c5a84de4ca.
Fixes#88706.
Co-authored-by: Elfka Toruviel <aeb31988340aa87b@toruviel.online>
Fixes#88333
Preserves contributor workspace contents when an attested workspace disappears or is partially regenerated, and clears OpenClaw-owned attestation state on delete/reset/uninstall.
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>
Resolve gateway auth SecretRef targets in status deep audit.
The static secret target coverage now includes gateway auth and remote token/password keys for both status and security audit scans. Focused status/secret-target tests passed, Auto Review reported no actionable findings, and CI is running on rebased head 41b052a181.
Fixes#87815
* fix(config): skip state-dir dotenv values that are unresolved shell references
readStateDirDotEnvVarsFromStateDir accepted any non-empty value from the
state-dir .env file and passed it into the managed service env. When a value
contains an unresolved shell variable reference such as "${SUPERMEMORY_KEY}"
or "$MY_VAR", dotenv preserves the literal string. The value then reaches
the LaunchAgent/systemd wrapper as a single-quoted literal, so the credential
is never resolved.
Add containsUnresolvedShellReference() and skip any value matching
$IDENTIFIER, ${...}, or $(...) in parseStateDirDotEnvContent(). Real credential
values (e.g. "sm_abc123") are unaffected.
Fixes#88274
* fix(config): narrow shell-reference detector to whole-value patterns only
The previous /$[\w{(]/ regex matched any value containing $ followed by
a word character, which would incorrectly drop real credentials that merely
contain a dollar sign (e.g. a password like abc$2!xyz).
Replace with isUnresolvedShellReference() that only matches values whose
ENTIRE content is a recognised reference form:
- $VAR_NAME (simple reference)
- ${VAR_NAME} (brace-form reference)
- $(command) (command substitution)
Add a regression test that verifies dollar-bearing real secrets are kept.
* fix(config): use letter/underscore-anchored pattern to avoid matching dollar-numbers
$100, $2, etc. are NOT shell variable references — shell variable names must
begin with a letter or underscore. The previous /^$[\w_]/ would match them.
Change to /^$[A-Za-z_]\w*$/ so only genuine named-variable references like
$MY_VAR are rejected. Dollar-number sequences are now preserved.
* fix(daemon): drop stale systemd env-file refs for skipped state-dir dotenv keys
When a state-dir .env value is an unresolved shell reference ($VAR/${VAR}/$(cmd))
the parser skips it from the managed environment. A prior install could have
written that literal reference into gateway.systemd.env; because the skipped key
no longer appeared in the incoming env or the managed-key removal sets, the stale
literal survived re-stage and could override fresh inline Environment= values.
Surface the skipped shell-reference keys from the state-dir dotenv parser and add
them to the systemd env-file managed-key removal set so re-staging strips the
obsolete literal while preserving operator-only secrets that were never managed
via state-dir .env. launchd regenerates its env file wholesale, so it is
unaffected.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(config): skip quoted shell parameter dotenv refs
* fix(config): preserve lowercase dollar-prefixed dotenv literals
* fix(daemon): clear stale unresolved systemd env refs
* fix(daemon): avoid re-staging unresolved file env refs
* fix(daemon): drop unresolved file env refs inline
* fix(daemon): drop inline-and-file unresolved env refs
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Preserve the active per-plugin managed npm project when npm-backed install validation blocks a candidate after npm has already mutated local state.
This snapshots package.json, package-lock.json, and node_modules before managed npm installs, restores that exact project state on failed validation, and rolls back staged npm-pack archives so blocked pack installs do not leave candidate debris.
Validation:
- OPENCLAW_VITEST_MAX_WORKERS=1 node scripts/run-vitest.mjs src/plugins/install.npm-spec.test.ts
- pnpm tsgo:core && pnpm tsgo:core:test
- node scripts/run-oxlint.mjs src/plugins/install.ts src/plugins/install.npm-spec.test.ts
- .agents/skills/autoreview/scripts/autoreview --mode local
- GitHub CI 26729255950
- Crabbox run_26e9f9f7591c
Thanks @zhuisDEV.
Co-authored-by: Brian <95547369+zhuisDEV@users.noreply.github.com>
Adds regression coverage for Google Vertex API-key model config planning when the credential comes from an env-backed auth profile. This keeps the planner-level guard around the Vertex static catalog rows that fixed#88816 on main.
Verification:
- `node scripts/run-vitest.mjs src/agents/models-config.applies-config-env-vars.test.ts extensions/google/provider-catalog.test.ts extensions/google/provider-models.test.ts`
- `./node_modules/.bin/oxfmt --check --threads=1 src/agents/models-config.applies-config-env-vars.test.ts extensions/ollama/src/stream.ts extensions/qa-lab/src/mantis/slack-desktop-smoke.runtime.ts extensions/qa-lab/src/mantis/telegram-desktop-builder.runtime.ts extensions/qa-lab/src/mantis/visual-task.runtime.ts`
- `git diff --check`
- `pnpm deadcode:dependencies`
CI note: PR CI had an unrelated `check-dependencies` failure for `ui/package.json: three`; the PR diff is one `src/agents` test file.
Refs #88816
Routes MiniMax OAuth device-code and token polling directly to account-hosted OAuth2 endpoints for global and CN regions, avoiding guarded-fetch cross-origin redirect body stripping. Keeps provider API base URLs unchanged and adds regression coverage for both endpoint pairs.
Proof: local minimax OAuth tests, oxfmt check, lint, autoreview clean, official MiniMax CLI/source check, live MiniMax endpoint probes, and CI run 26729242892 on 6bfe20eb06.
Co-authored-by: Matt Schleder <schledermatthew@gmail.com>
Fixes#88520.
Adds focused regression coverage for the embedded attempt trajectory recorder cleanup boundary so a stalled trajectory flush resolves after the cleanup timeout and logs pending write details instead of rejecting attempt cleanup.
Verification:
- node scripts/run-vitest.mjs src/agents/run-cleanup-timeout.test.ts
- git diff --check origin/main...origin/pr/88802
- PR CI green: https://github.com/openclaw/openclaw/actions/runs/26727232564
Co-authored-by: Andy Ye <35905412+TurboTheTurtle@users.noreply.github.com>