* fix(extensions): make indexed access explicit across channel plugins
Transport-payload-safe burn-down: malformed Telegram/Discord/QQ/LINE
and sibling channel input keeps existing skip paths; no synthesized
fields, no new throws in delivery loops. Zalo escape sentinels preserve
literal matches instead of undefined replacements.
* fix(extensions): make indexed access explicit across provider and memory plugins
Stream and model iteration, tool-block guards, capture guards, and
sparse accumulators; singleton model reads carry named invariants.
* fix(extensions): make indexed access explicit across tooling plugins, flip the extensions lane
Remaining plugins (oc-path, qa-lab, browser, logbook, and siblings) plus
the tsconfig.extensions.json flag flip. Cleanup: logbook sampleFrames
NaN index at max=1, QA retry clamp at non-positive attempts, dead Canvas
probe and OpenShell no-op slice removed, twitch test setup leak excluded
from the prod lane.
* refactor(plugin-sdk): expose expectDefined via a focused SDK subpath
Extensions imported @openclaw/normalization-core directly, crossing the
external-plugin packaging boundary (it only worked because the runtime
builder bundles undeclared workspace helpers). expect-runtime joins the
canonical entrypoints JSON, generated exports, API baseline, docs, and
subpath contract test; all 78 extension imports now use the SDK seam.
Two scanner-shaped locals renamed for review-bundle hygiene.
* chore(plugin-sdk): raise surface budgets for the expect-runtime subpath
One new entrypoint with one callable export, added intentionally as the
packaging-honest seam for extension invariant helpers.
* fix(google-meet): force English UI when reusing existing Chrome tab
* fix(google-meet): narrow reused tab before forcing English UI
* test(google-meet): assert /navigate target id is adopted in reused tabs
* fix(google-meet): preserve active call tabs and normalize English before recovery
* fix(google-meet): preserve localized active tabs
* test(google-meet): avoid shadowing path import
* test(google-meet): align mocks with English-pinned tab reuse
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(google-meet): use truncateUtf16Safe for log value truncation
One .slice(0, 180) truncation site in the Google Meet extension
may cut UTF-16 surrogate pairs in half when the log value contains
multi-byte characters such as emoji. Replace it with
truncateUtf16Safe to keep the truncated output valid Unicode.
* test(google-meet): cover UTF-16 model log boundary
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(google-meet): bound JSON response body reads to prevent OOM
Replace raw response.json() with readProviderJsonResponse (16 MiB cap)
across meet.ts, calendar.ts, and oauth.ts to prevent unbounded memory
allocation from oversized HTTP response bodies.
Also extract duplicated hasConfig check in createGoogleMeetSpace.
Test: loopback HTTP server test with 4 MiB oversized body + valid body.
* fix(test): prove readProviderJsonResponse bounds the 200 success path
Replace loopback server with synthetic Response objects. The oversized
test now returns HTTP 200 with a 17 MiB body — readProviderJsonResponse
rejects it at its 16 MiB cap, proving the bounded read fires on the
success path (not just the already-bounded 500 error path the old test
exercised).
Ref. https://github.com/openclaw/openclaw/pull/98850
* fix(test): add real HTTP transport integration tests for bounded JSON reads
- Add two vitest integration tests that start a real local TCP server,
fetch through native HTTP transport, and verify readProviderJsonResponse
correctly rejects oversized responses and passes normal ones.
- Existing synthetic-boundary tests unchanged.
Ref. https://github.com/openclaw/openclaw/pull/98850
* fix(test): wrap server.listen in promise executor to satisfy oxlint no-promise-executor-return
* fix(google-meet): add real SSRF-guard transport integration tests for bounded JSON reads
Adds two new integration tests that route meet.googleapis.com requests
through a local TCP server via spyOnGoogleMeetFetch, exercising the
actual fetchGoogleMeetSpace function end-to-end through the SSRF guard
mock. This addresses ClawSweeper review feedback requesting real
transport-level proof of the bounded read contract.
* fix(google-meet): preserve original fetch reference in spyOnGoogleMeetFetch to avoid recursion
The mockImplementation replaced globalThis.fetch, so calling fetch() inside
the mock called the mock itself. Capture globalThis.fetch before spying and
use the saved reference inside the implementation to avoid infinite recursion.
* fix(google-meet): add console.log debug output to loopback proof tests
Add structured console.log evidence markers to the four real HTTP
transport integration tests so that reviewers can see the bounded-read
contract working through actual TCP connections. Format matches the
established pattern from Alix-007's approved bound-read PRs.
* Revert "fix(google-meet): add console.log debug output to loopback proof tests"
This reverts commit e64c26d17e.
* fix(google-meet): tighten response body limits
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Summary:
- The branch adds `forceMeetEnglishUi()` for Google Meet URLs, applies it to join/create browser opens, canonicalizes browser-created meeting links, and updates focused Google Meet tests.
- PR surface: Source +18, Tests +19. Total +37 across 6 files.
- Reproducibility: yes. Current main opens raw Meet URLs while the browser automation matches English-only lab ... R body provides after-fix CDP output showing non-English pages render expected English labels with `hl=en`.
Automerge notes:
- PR branch already contained follow-up commit before automerge: chore(tooling): add unused agent-cache-store files to knip optional a…
- PR branch already contained follow-up commit before automerge: fix(google-meet): repair non-Latin mic regex matching boundary
- PR branch already contained follow-up commit before automerge: revert(tooling): preserve current main deadcode allowlist guard
- PR branch already contained follow-up commit before automerge: revert(tooling): perfectly match origin/main deadcode list
- PR branch already contained follow-up commit before automerge: revert: match origin/main deadcode list exactly
Validation:
- ClawSweeper review passed for head 880a41b6f0.
- Required merge gates passed before the squash merge.
Prepared head SHA: 880a41b6f0
Review: https://github.com/openclaw/openclaw/pull/89671#issuecomment-4608725456
Co-authored-by: Chen Chia Yang <unayung@gmail.com>
Approved-by: hxy91819
The Google Meet OAuth login binds a fixed localhost:8085 callback listener
and let listener failures propagate, so meet auth login aborted entirely when
port 8085 was already in use. The sibling Gemini CLI OAuth path already
recovers by switching to the manual copy/paste flow on EADDRINUSE/listen
errors; bring Google Meet to parity by catching listener errors and reusing
the existing manual-paste handler instead of failing the login.
* chore(release): close out 2026.6.10 on main
* chore(release): align native app metadata for 2026.6.10
* chore(release): sync Android 2026.6.10 notes
* docs(changelog): preserve 2026.6.9 history
* docs(changelog): preserve 2026.6.9 history