* feat(config): give shared channel settings help text
* fix(ui): space the settings tiers and stop repeating help on list items
* feat(ui): link each channel detail to its docs page
* test(ui): mirror production channel hints in the mock dev server
* docs: note the shared channel help inheritance for plugin authors
* fix(config): let a channel suppress shared help with an empty string
* chore(config): regenerate bundled channel metadata for the new WhatsApp hints
* fix(ci): check bundled channel metadata locally
* chore(release): keep changelog release-owned
* chore(release): keep changelog release-owned
* fix(ui): keep shared channel help contract-neutral
scripts/pr review artifacts carried no PR identity, so a review authored for
another PR validated clean and could gate someone else's landing. Stamp both
review.json and review.md with the reviewed PR number and head, anchor
pr-meta.json to the guarded pr-meta.env, and re-stamp foreign artifacts on init
instead of silently adopting them. review-claim now works in the PR worktree so
no subcommand writes review state to the shared canonical checkout.
* feat(plugins): deliver sessions.changed to plugin services
* docs: regenerate docs map
* refactor(clickclack): split reconcile scheduler and history formatting out of the discussion service
* style: format discussion service
* perf(logging): flush file transport asynchronously off the request path
* fix(ci): record flushLogger surface growth and drain before log reads
- +1 public export/callable budget with annotation: logger file-transport
flush for graceful shutdown drains; regenerate SDK API baseline
- three tests that read the log file right after logging now drain the
async file transport first (flushLogger) instead of racing the flusher
* test: drain async log transport before reading talk and request-trace logs
* test: drain async log transport in CLI logger file tests
* test: drop unused withTempDirSync import
* fix(ui): restore chat flow e2e coverage
(cherry picked from commit 16a094eaec4ae121db09f67c094a41262aa9cefc)
* test(ui): align browser Talk mocks with voice sessions
(cherry picked from commit ef0649334539954b253ab8c51ff436bd8ce757c6)
* test(ui): wait for chat startup in update E2E
(cherry picked from commit 586e1046320dd56398fd8a3b995a1a465f6c6fe2)
* test(ui): update sidebar session route expectation
(cherry picked from commit 9692985027556fad7bb7819c8e140a101e181c47)
* test(ui): update session management e2e contracts
(cherry picked from commit 4e99348dabf08fb8886d55e25a9f9eda1dfe1056)
* test(ui): align Codex session E2E contracts
Update the catalog layout assertion for reorderable sibling sections, expose advanced plugin settings explicitly, and make adopted sessions resolvable through the current path router.
(cherry picked from commit 1a03f924a32facb23302c5618a2b15004feeccff)
* test(ui): align composer e2e with metadata hydration
(cherry picked from commit eca1902e773be32c993ddb22594925f7da82f98f)
* fix(ui): restore usage hint click behavior
(cherry picked from commit ea63b5dab7c3c54048a04d60703e529e5b900df6)
* fix(ui): give reveal-only tooltips an explicit click-to-open opt-in
#112602 made the shared tooltip dismiss on pointer activation so an action
button never strands one open. The usage summary hint exists only to be read,
so clicking it did nothing on touch or in browsers that skip focus on click.
Opt that trigger in rather than bouncing focus through blur/focus, which
briefly drops focus for assistive tech.
(cherry picked from commit 16d165857a4006ae0a0df42168f34a40f4cc9117)
* test(ui): follow sidebar dock resize ownership
(cherry picked from commit fd4792a2dd9fc81fc63f8c9e25291ff2246d235a)
* test(ui): prove the dock resize persists off its clamp
Asserting the post-End width equals SIDEBAR_MIN_WIDTH_PX compared the clamp
to itself across reload, so the check would pass even if the persisted width
were dropped and the column fell back to its minimum. Step off the clamp
first and assert that value survives.
(cherry picked from commit 3636124c326a93b80006ccc4064415ec1a6c2c9f)
* test(ui): align native link routing e2e contracts
Use a non-link bubble hit target after flat assistant styling, assert modified clicks at the routing boundary instead of relying on Chromium tab creation, and preserve native context menus for internal anchors.
(cherry picked from commit 55fbd3052a40c5c03f00f0bf595ef356ac0d1f10)
* test(ui): align native catalog host assertions
(cherry picked from commit 9db9a2fcd5633675a88296b2ccd874563a00cb80)
* test(ui): target tool outcome rollup at dashboard session
Completed-work groups are dashboard-only, so the legacy main session never rendered the disclosure exercised by this test.
(cherry picked from commit ba84b617ef038866451ad03491298349d966a54f)
* test(ui): track discussion panel close action
The flexible multi-sidebar layout replaced the generic Close sidebar action with a panel-specific Close Discussion action. Keep the E2E toggle proof aligned with that intentional accessible-name contract.
(cherry picked from commit 422b1f2bd8fae2a7571881d0455c3040c2ef2de9)
* test(ui): mock pairing list in WhatsApp logout e2e
(cherry picked from commit 3730de075bbb50071fc0cb57c007ab894688a7a1)
* test(ui): open build info from identity menu
(cherry picked from commit b1626a6a723ec13c2cf50444b4c7a65fec289213)
* fix(ui): let the board fixture host page own its theme
The fixture module unconditionally re-added `wa-dark` at import time, which
runs after the host page's inline theme script. #111998 gave that page the
real prefers-color-scheme contract, leaving the line from #112076 stale: in
light mode the root ended up with both `wa-light` and `wa-dark`, so Web
Awesome rendered dropdowns dark.
(cherry picked from commit 43e50de9728f3d5feac9609142d28821896b4f77)
* test(ui): align approval E2E with scoped errors
(cherry picked from commit 6435fe995491c6bae2c28fa374d06cd77f3c46ac)
* test(ui): use radio role in Set Default E2E
(cherry picked from commit acc8d5a487aac4d56515ae35d976fd347efa0be5)
* ci: gate merges on the Control UI e2e suite
test/vitest/vitest.ui-e2e.config.ts was referenced only by package.json and
mantis-web-ui-chat-proof.yml, so nothing in the merge gate ever ran it and 39
failures accumulated across 21 files (#114438). Give it its own job: the suite
runs one file at a time because each owns a Chromium context and a mocked
Gateway, ~21 min measured, which does not fit checks-ui's 20-minute budget.
Also route the config file itself through the Control UI changed-scope so a
change to it triggers the job.
* test(ui): isolate MCP app conformance from sidecars
(cherry picked from commit c2bfd0a00edad804474ebb23449d3150557c7f78)
* test(ui): list newly created E2E sessions
(cherry picked from commit e1a2188699011e818e040358d4eaf6ce26eb0732)
* test(ui): synchronize full-suite e2e setup
* test(ui): drop implied-eval module import and align the e2e workflow guard
* test(ui): wait for pin editor roving focus before keyboard nav
* test(ui): read the startle class in one in-page step
* test(ui): synchronize transient e2e assertions
* fix: reject malformed UTF-8 in live provider model catalog responses
Add { fatal: true } to TextDecoder in readLiveModelCatalogJson so
invalid UTF-8 bytes throw a TypeError before JSON.parse instead of
silently becoming U+FFFD.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(plugin-sdk): add fallback proof for malformed UTF-8 in live catalog
Adds a focused test that constructs raw bytes with an invalid 0xFE byte
inside a JSON string value and validates that buildLiveModelProviderConfig
catches the Typeerror and falls back to the static catalog rows.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(pr): classify auto-merge failures without ripgrep
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* feat(plugins): mirror local coding sessions to a remote Beam receiver
* fix(plugins): satisfy static gates for the Beam mirror seam
* fix(plugins): import the config type from the narrow contracts subpath
* fix(plugins): require catalog consent and loopback-only plaintext for the Beam mirror
* fix(config): compaction.enabled is rejected as invalid config
Setting agents.defaults.compaction.enabled in openclaw.json made the
whole config fail to load with "agents.defaults.compaction: Invalid
input", so auto-compaction could not be turned off.
The runtime already reads the field (SettingsManager.getCompactionEnabled
returns settings.compaction?.enabled ?? true, and setCompactionEnabled
writes it), and the documented config example in
docs/reference/session-management-compaction.md already shows
"enabled: true". Only the zod schema was missing the key, and the
compaction object is .strict(), so the unknown key rejected the config.
Adds enabled to AgentDefaultsSchema and to AgentCompactionConfig.
Closes#110065
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(config): wire compaction enablement through runtime
Align the accepted compaction.enabled contract across runtime precedence, help, labels, docs, and generated schema baselines.
Co-authored-by: Zakaria Rahali <zakariarahali288@gmail.com>
* test(config): preserve omitted compaction setting
Document the reload lifecycle and lock in project-setting precedence when the OpenClaw config key is absent.
Co-authored-by: Zakaria Rahali <zakariarahali288@gmail.com>
* refactor(config): centralize compaction runtime override
* fix(config): preserve compaction safety guards
* fix(scripts): avoid ripgrep in merge fallback
* docs(config): refresh current main baseline
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* test(ui): make channel settings renderable in the mock dev server
* fix(ui): hide advanced channel settings behind the shared advanced tier
* fix(ui): widen the tier renderer callback to lit's nothing
* fix(ui): keep the advanced collapse control on advanced-only channel forms
* docs: note the shared advanced tier on channel settings
* feat(ui): serve DM pairing fixtures from the mock dev harness
* refactor(ui): align channels DM access requests with the settings design language and drop the channel-health JSON card
* fix(agents): make global loop breaker reachable
Record loop-detector vetoes as typed no-progress outcomes so repeated blocked calls continue the existing streak without colliding with plugin or approval denials. Extract streak accounting into its own owner module and keep completed veto records out of argument reconciliation.\n\nFixes #109435.
* test: harden isolated project routing
Route registry-sensitive UI tests through the isolated project for both focused and broad runs, centralize the isolated file list, and register the Codex prewarm test in the full extension shard.
* test(qa): prove global loop breaker runtime
Drive 31 identical read attempts through the real QA Gateway agent loop and verify the typed veto streak reaches the global circuit breaker before the turn returns a final marker.
* test: keep isolated UI files out of shared runs
Always exclude registry-sensitive files from the shared UI project and reject broad watch targets that would span shared and isolated projects.
* fix(ui): keep channel action labels on one line and surface QR next to actions
* fix(test): drop duplicate prewarm test from attempt-extra shard config
* perf(gateway): stop per-row store and registry rediscovery in sessions.list
* fix(gateway): satisfy kysely guardrail and knip on sessions.list rediscovery fix
* refactor(state): split registered agent database listing from the registry
* chore(state): allowlist the split registry listing module for raw sqlite probes
* perf(sessions): serve session entries from a data_version-validated memory store
* fix(sessions): pair data_version with total_changes for entry cache validity
* chore(sessions): keep the cache publication token type module-local
* fix(sessions): drop the entry cache when tracked publications cannot prove freshness