Adds optional `gateway.tailscale.serviceName` support for Tailscale Serve so the Gateway Control UI can be exposed through a named Tailscale Service while existing hostname-based Serve and Funnel behavior stays unchanged.
The implementation validates `svc:<dns-label>`, passes the Service name to `tailscale serve`, clears named Service config with `tailscale serve clear <service>` when resetOnExit runs, and uses the derived Service hostname in startup logs, status output, and pairing URLs.
Verification:
- node scripts/run-vitest.mjs src/infra/tailscale.test.ts src/gateway/server-tailscale.test.ts src/config/config.gateway-tailscale-bind.test.ts src/gateway/startup-auth.test.ts src/commands/status.scan.shared.test.ts src/pairing/setup-code.test.ts
- .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main --parallel-tests "node scripts/run-vitest.mjs src/infra/tailscale.test.ts src/gateway/server-tailscale.test.ts src/config/config.gateway-tailscale-bind.test.ts src/gateway/startup-auth.test.ts src/commands/status.scan.shared.test.ts src/pairing/setup-code.test.ts"
- git diff --check
- git merge-tree --write-tree origin/main origin/pr/88691
Closes#88629.
Co-authored-by: Charles OpenClaw <charles-openclaw@9bcfae.inboxapi.ai>
Expose the existing virtual Communication > Notifications settings tab for Web Push controls, while keeping it out of the unscoped root settings view. Adds browser regression coverage for the scoped virtual tab.
Thanks @VladyslavLevchuk.
Co-authored-by: Vladyslav Levchuk <32742736+VladyslavLevchuk@users.noreply.github.com>
Extract ACP runtime-option command flows from `AcpSessionManager` into `manager.runtime-options-commands.ts`.
Verification:
- `pnpm format:fix src/acp/control-plane/manager.core.ts src/acp/control-plane/manager.runtime-options-commands.ts`
- `node scripts/run-oxlint.mjs src/acp/control-plane/manager.core.ts src/acp/control-plane/manager.runtime-options-commands.ts`
- `pnpm tsgo:prod`
- `pnpm test src/acp/control-plane/manager.runtime-config.test.ts src/acp/control-plane/manager.runtime-handles.test.ts src/acp/control-plane/manager.test.ts`
- `pnpm format:check src/acp/control-plane/manager.core.ts src/acp/control-plane/manager.runtime-options-commands.ts`
- `git diff --check`
- `pnpm check:test-types`
- `.agents/skills/autoreview/scripts/autoreview --mode local`
- GitHub PR checks for #88747 passed
Real behavior proof:
Behavior addressed: ACP runtime-option mutation ownership moved out of `AcpSessionManager` without changing set-mode, set-config-option, raw update, reset, persistence, or runtime-cache invalidation semantics.
Real environment tested: Local OpenClaw checkout, Node/pnpm repo toolchain, GitHub Actions PR CI.
Exact steps or command run after this patch: Focused ACP runtime config/handle/manager tests plus prod/test type checks, lint, format, diff check, autoreview, and PR CI.
Evidence after fix: All listed local commands passed, autoreview reported no accepted/actionable findings, and GitHub PR checks passed.
Observed result after fix: `manager.core.ts` is down to 885 LOC, with runtime-option command logic isolated in `manager.runtime-options-commands.ts`.
What was not tested: Live ACP backend mode/config option mutation against a real external ACP provider.
Prefer the clean channel command body when ACP decides whether an inbound message should bypass the agent loop for local OpenClaw commands.
This keeps envelope-wrapped channel text, such as WhatsApp display bodies, from hiding commands like /status when the channel already provided a normalized command body. The ACP runtime prefilter now uses the same command-text resolution as dispatch, and dispatch still requires registry-backed local commands before bypassing.
Co-authored-by: RoeeJ <RoeeJ@users.noreply.github.com>
Force required preflight context compaction before oversized turns can enter the agent runtime. Treat required preflight compaction as a hard gate: compact, skip only explicit harmless no-op reasons, or surface a visible recovery message when compaction cannot recover.
Fixes#87234.
Co-authored-by: ArthurNie <264332276+ArthurNie@users.noreply.github.com>
Refactor ACP close-session ownership by extracting the runtime close/recovery lifecycle into `manager.close-session.ts`.
Verification:
- `pnpm test src/acp/control-plane/manager.test.ts src/acp/control-plane/manager.runtime-config.test.ts src/acp/control-plane/manager.runtime-handles.test.ts`
- `pnpm tsgo:prod`
- `pnpm check:test-types`
- `node scripts/run-oxlint.mjs src/acp/control-plane/manager.core.ts src/acp/control-plane/manager.close-session.ts`
- `pnpm format:check src/acp/control-plane/manager.core.ts src/acp/control-plane/manager.close-session.ts`
- `git diff --check`
- `.agents/skills/autoreview/scripts/autoreview --mode local`
- GitHub PR checks for #88744 passed
Real behavior proof:
Behavior addressed: ACP close-session ownership moved out of `AcpSessionManager` without changing close/recovery behavior.
Real environment tested: Local OpenClaw checkout, Node/pnpm repo toolchain, GitHub Actions PR CI.
Exact steps or command run after this patch: Focused ACP manager tests covering close-session behavior, runtime config, and runtime handles, plus prod/test type checks, lint, format, diff check, autoreview, and PR CI.
Evidence after fix: All listed local commands passed, autoreview reported no accepted/actionable findings, and GitHub PR checks passed.
Observed result after fix: `manager.core.ts` dropped from 1149 LOC to 1038 LOC while close-session runtime lifecycle handling lives in `manager.close-session.ts`.
What was not tested: Live ACP backend close/recovery against a real external ACP provider.
Bounds skills watcher subscriptions and workspace snapshot-version state to active workspaces on the current `src/skills/runtime` implementation.
The fix keeps shared path watchers as the owner boundary, evicts idle workspace subscriptions after 1 hour without closing watchers still used by other workspaces, and clears per-workspace version keys only after preserving/advancing invalidation so cached skill snapshots cannot miss changes across teardown or re-enable.
Thanks @fede-kamel.
Fixes#77997.
Co-authored-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Refactor ACP turn execution ownership by extracting the backend attempt and cleanup loop into `manager.turn-runner.ts`.
Verification:
- `pnpm test src/acp/control-plane/manager.test.ts src/acp/control-plane/manager.turn-results.test.ts src/acp/control-plane/manager.failover.test.ts src/acp/control-plane/manager.runtime-handles.test.ts src/acp/control-plane/manager.runtime-config.test.ts`
- `pnpm tsgo:prod`
- `pnpm check:test-types`
- `node scripts/run-oxlint.mjs src/acp/control-plane/manager.core.ts src/acp/control-plane/manager.turn-runner.ts`
- `pnpm format:check src/acp/control-plane/manager.core.ts src/acp/control-plane/manager.turn-runner.ts`
- `git diff --check`
- `.agents/skills/autoreview/scripts/autoreview --mode local`
- GitHub PR checks for #88739 passed
Real behavior proof:
Behavior addressed: ACP turn execution ownership moved out of `AcpSessionManager` without changing runtime behavior.
Real environment tested: Local OpenClaw checkout, Node/pnpm repo toolchain, GitHub Actions PR CI.
Exact steps or command run after this patch: Focused ACP manager tests covering turn results, failover, runtime handles, runtime config, plus prod/test type checks, lint, format, diff check, autoreview, and PR CI.
Evidence after fix: All listed local commands passed, autoreview reported no accepted/actionable findings, and GitHub PR checks passed.
Observed result after fix: `manager.core.ts` dropped from 1495 LOC to 1149 LOC while turn execution lives in `manager.turn-runner.ts`.
What was not tested: Live ACP backend process recovery against a real external ACP provider.
Sanitize credential-shaped provider HTTP 401 failures in embedded-agent replies so chat users see a re-authentication hint instead of raw provider text such as `HTTP 401: "Invalid token"`.
The classifier now requires auth classification plus positive 401 evidence, and it stays narrow to credential-shaped failures so billing, scope, replay-invalid, schema, message-only auth, and plain 403 paths keep their existing behavior.
Fixes#56197. Thanks @lokamir.
Co-authored-by: jeffrey701 <jeffreyconradtucker@gmail.com>
Phase-signal store reads now recover only missing files and corrupt JSON. Nonrecoverable filesystem read failures propagate so dreaming aborts before overwriting existing phase-signal history with an empty replacement.
Fixes#77881.
Thanks @bennewell35.
Co-authored-by: bennewell35 <newelljben@gmail.com>
Extract ACP runtime resume/discard recovery helpers from `AcpSessionManager` into `manager.runtime-resume-state.ts`, and share the manager session-meta writer callback type from `manager.types.ts`. Keeps close-time fresh-session recovery, early-turn retry, persisted resume identifier clearing, and discard-persistent-state behavior intact while reducing `manager.core.ts` from 1655 LOC to 1495 LOC.
Proof: focused ACP manager runtime-handle/runtime-config/turn-result tests, prod + test type checks, narrow oxlint, format check, diff check, autoreview clean, PR CI green.
Bound DiscordEntityCache entries with a write-time expired-entry sweep and a default 5,000-entry cap while preserving current safe expiry timestamp normalization. This prevents high-cardinality Discord user/channel/guild/member fetches from retaining stale Map entries for the gateway lifetime.
Fixes#77975.
Thanks @fede-kamel.
Co-authored-by: Federico Kamelhar <federico.kamelhar@oracle.com>
Guard group display-name generation behind group/channel classification so direct Telegram sessions fall back to their explicit or origin labels. Keep session-list search aligned with that visible fallback.
Fixes#55354.
Thanks @sebuh-infsol.
Summary:
- Add forced provider re-login support that clears cached auth profiles before running provider login again.
- Add provider-auth remediation guidance and a session-scoped skip cache for known-bad fallback auth attempts.
- Wire session ids through agent command, auto-reply, and embedded compaction fallback callers so the skip cache applies on real run paths.
- Fail closed when forced auth profile removal cannot update the profile store.
Verification:
- Local format, lint, diff-check, focused Vitest shards, and autoreview passed.
- PR CI, CodeQL Security High, and Critical Quality agent-runtime-boundary passed on head 1b4e9e753e.
Co-authored-by: Mert Basar <MertBasar0@users.noreply.github.com>
Fix approval fallback text so exec and plugin approval messages render a concrete request id in the chat copy-paste command instead of the literal <id> placeholder.
This makes the Reply with: /approve ... line directly usable for owners while keeping the existing approval resolver contract unchanged.
Proof:
- git diff --check origin/main...HEAD
- pnpm test src/infra/exec-approval-forwarder.test.ts src/infra/plugin-approval-forwarder.test.ts src/plugin-sdk/approval-renderers.test.ts
- .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main
- CI run 26720052738 passed
Thanks @itsuzef.
Serialize QMD update and embed writes with one per-agent store lock so foreground memory search/index and gateway background QMD work do not write the same index.sqlite concurrently.
The embed path now waits for global embed capacity before taking the per-store lock, so queued embeds do not block same-agent foreground updates while no store write is active.
Fixes#66339
Thanks @openperf.
Co-authored-by: Chunyue Wang <16864032@qq.com>
Refresh pinned node:24-bookworm and node:24-bookworm-slim manifest-list digests across the root, smoke, and e2e Dockerfiles. Update digest pin assertions to cover the plugin-binding e2e Dockerfile.
Verified with live Docker digest inspection, targeted Dockerfile tests, root base-runtime build, install-sh smoke build, and plugin-binding e2e build.
Thanks @LibraHo.
Detect OpenClaw gateway units installed in the system systemd scope, including marker-owned custom unit names such as `openclaw.service`. Route status/restart/stop through the system manager when appropriate, and show non-root users the matching `sudo systemctl ...` command instead of falling back to unmanaged process signaling.
Fixes#87577.
Thanks @yetval.
Verification:
- `node scripts/run-vitest.mjs src/daemon/systemd.test.ts src/cli/daemon-cli/lifecycle.test.ts src/daemon/inspect.test.ts src/cli/daemon-cli/lifecycle-core.test.ts src/cli/daemon-cli/status.gather.test.ts src/cli/daemon-cli/response.test.ts src/commands/doctor-gateway-daemon-flow.test.ts src/cli/update-cli/restart-helper.test.ts src/infra/outbound/message-action-runner.core-send.test.ts`
- AWS Crabbox `cbx_69f97dff5e5c`, run `run_a68431b3dad6`: exact SHA checkout, focused tests, real `/etc/systemd/system/openclaw.service` status/restart/stop proof.