Skip to content

sync: merge upstream main through 0acece45912 - #4

Merged
devSejung merged 78 commits into
mainfrom
sync/upstream-20260718-refresh
Jul 20, 2026
Merged

devSejung merged 78 commits into
mainfrom
sync/upstream-20260718-refresh

Conversation

@devSejung

Copy link
Copy Markdown
Owner

Merged 71 upstream OpenClaw commits from 5057fd9 through 0acece4. Updated docs/upstream/status.md. Validation: git diff --check passed. Remote Linux Testbox validation is pending because the local Crabbox binary is unavailable.

steipete and others added 30 commits July 18, 2026 10:31
* fix(plugins): bound marketplace manifest file reads

* fix(plugins): distinguish oversized marketplace manifest from other read failures

* fix(plugins): follow symlinked marketplace manifests while bounding reads

* test(plugins): cover oversized symlinked marketplace manifest target
…10277)

* fix(gateway): bound session workspace reveal opener

* refactor(gateway): share bounded path opener lifecycle

---------

Co-authored-by: Peter Steinberger <peter@steipete.me>
* fix(codex): persist automatic compaction counts

* test(codex): stress compaction and restart recovery

* test(codex): bind compaction waves to fresh counts

* chore: keep Codex release note in PR
Co-authored-by: Peter Steinberger <steipete@gmail.com>
#101773 removed the node:fs/promises import while switching plugin manifest
reads to fs-safe helpers, but getSkillCodeSafetySummary (added later by
#109363) still reads SKILL.md via fs.readFile. Main has been red since the
merge (check-prod-types, check-lint, check-test-types, package-boundary
compile, compact-large-5). Restore the import; skill-file reads keep their
pre-existing unbounded contract.
* fix(gateway): bound usage.list days parameter to 100 years

parseDays accepted any finite number including 1e300, which downstream
resolveTrailingDays would feed into Date arithmetic as a day offset,
overflowing the ECMAScript Date range and surfacing as a misleading
"calendar day does not exist in requested time zone" error. Reject
day counts above 100 years (36600); callers wanting truly unbounded
history should use `range: "all"`.

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>

* fix(gateway): clamp oversized usage day ranges

---------

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(cron): fail empty isolated agent completions

* fix: surface cron errors for empty isolated agent replies

* fix(cron): preserve intentional terminal progress

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
…786)

* fix(config): restore process.env after invalid config rejection

When config validation fails, env vars from the rejected config
(env.vars in openclaw.json) leaked into process.env and were never
cleaned up. In long-running gateways this meant rejected config
values could persist until process restart.

Add restoreEnvChangesIfUnchanged calls in both sync (loadConfigLocal)
and async (readConfigFileSnapshotInternal) validation-failure paths,
matching the pattern already used by suspicious-config recovery paths.

* fix(config): restore env before observer and on duplicate-agent-dir rejection

- Add restoreEnvChangesIfUnchanged before DuplicateAgentDirError throw
  in the sync loadConfigLocal path so env vars from rejected config
  do not leak when duplicate agent directories are detected.
- Move restoreEnvChangesIfUnchanged before observeLoadConfigSnapshot
  in the sync validation-failure path so config health/audit
  observation does not see rejected env values.
- Add entry-point regression tests exercising sync loadConfig,
  async readConfigFileSnapshot, and duplicate-agent-dir rejection
  paths through createConfigIO with real config files.

* fix(config): restore env after invalid snapshot

Co-authored-by: xialonglee <li.xialong@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: chengzhichao-xydt <chengzhichao-xydt@users.noreply.github.com>
…554)

* fix(shared): reject HTTP status codes outside the 100-599 range

extractHttpStatusMatch only checked Number.isFinite, so 3-digit
sequences such as "000", "099", "600", and "999" were accepted as
valid HTTP statuses. Downstream code then surfaced them as "HTTP 0"
in user-visible messages and fed them into retry/classification
branches (e.g. isCloudflareOrHtmlErrorPage checks `code < 500` and
`code < 600`). Restrict the extracted code to the IANA HTTP status
code range (100-599).

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>

* fix(shared): validate all parsed HTTP status prefixes

---------

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
…d merge"

This reverts commit 39528ed.

That push was an accident: the fs-import fix it described had already landed
on main, and a rebase reduced the commit to unrelated in-progress
gateway-protocol schema edits (nodes/session-placement) that were staged in
the pushing worktree and belong to another work stream. Restore the reviewed
main state; the protocol work can land through its own PR.
* fix(config): use Object.hasOwn in restoreEnvVarRefs to avoid prototype pollution

When key comes from Object.entries(incoming) on user config data,
'key in parsed' traverses the prototype chain. If a config key
collides with an Object.prototype property (e.g. 'toString'),
the check incorrectly returns true and calls restoreEnvVarRefs
with a prototype function instead of a config value.

Replace with Object.hasOwn(parsed, key) to check only own properties.

* test(config): prove inherited env refs are ignored

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
* refactor(plugins)!: remove experimental workspaces plugin

* fix(doctor): remove retired workspaces plugin state

* refactor(doctor): settle retired-workspaces cleanup before legacy-state detect

* chore(i18n): leave workflow-owned locale artifacts to the locale refresh

* ci: retrigger after GitHub scheduling outage
* fix(browser): soften transient retry guidance

* style(browser): format retry hint test

* chore: keep release note in PR body
* test(tui): await PTY teardown before worker exit

* test(tui): avoid unbound PTY mock assertion
* refactor(gateway): simplify lifecycle mutation contracts

* refactor(cli): unexport internal emitDaemonActionMessage
…ry (#106073)

* fix(gateway): retain explicit source replies in history

Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>

* test(infra): update source reply mirror mock

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
…(#110069)

* fix(plugin-sdk): keep attached channel authoritative

* refactor(plugin-sdk): simplify channel attachment

Co-authored-by: 杨浩宇0668001029 <yang.haoyu@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(opencode): add Zen GPT-5.6 models

* test(opencode): narrow GPT-5.6 policy fixture

* fix(opencode): align GPT-5.6 thinking levels

Co-authored-by: 杨浩宇0668001029 <yang.haoyu@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
…era toggle (#110576)

* feat(ui): merge voice and video talk into one button with in-call camera toggle

* fix(ui): avoid stale TS narrowing on talk status re-check in camera toggle
* fix(plugins): bound plugin manifest metadata file reads

* fix(plugins): use correct Error type check in oversized manifest catch

readRegularFileSync throws a plain Error (not RangeError) when the file
exceeds maxBytes. Change the catch-block type check from RangeError to
Error to properly detect oversized plugin manifests and emit the
subsystem warning.

* test(plugins): exercise valid oversized manifests

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(gateway): bound BOOT.md file read size

* fix(gateway): treat non-regular BOOT.md as empty/missing and add coverage

* fix(gateway): preserve non-size BOOT.md failures while bounding oversized reads

* fix(gateway): preserve readable BOOT.md symlink behavior

* fix(gateway): treat dangling BOOT.md symlink as missing

* fix(gateway): report oversized BOOT files

* fix(gateway): preserve missing BOOT race behavior

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
steipete and others added 19 commits July 18, 2026 12:52
* feat(ui): manage MCP servers directly on the Settings MCP page

* refactor(ui): mcp config section owned by the MCP settings page only

* chore(ui): drop test-only McpServersCard export for knip
…#110632)

* feat(linux): stream Quick Chat gateway events

* feat(linux): render streamed Quick Chat replies

* fix(linux): correlate Quick Chat streams by run

* style(linux): rustfmt

* test(linux): move Quick Chat stream helper tests into the tooling vitest project

* test: type the Linux quickchat stream harness for strict checks

* test: explicit harness shape for the root test typecheck
* feat(macos): render system chat option cards

* fix(macos): localize question card controls

* test(macos): stabilize main actor attachment tests
…#110687)

The entry stylesheet aggregated approval, config, config-quick, and
lobster-pet styles even though every consumer is a lazy route chunk or
lazily defined element, and two small UI landings tipped startup CSS to
exactly the 42.0 KiB budget, failing all QA Smoke profiles on main (run
29643357786). Move each stylesheet to its owning lazy module — pages
already own their CSS this way (chat, agents, cron) — and keep only the
shell's pre-hydration approval booting subset in the entry via the new
approval-boot.css. Startup CSS drops 42.0 -> 36.0 KiB gzip; tighten the
budget 42 -> 38 KiB to lock in the recovery, matching the startup-JS
precedent from #110528.
…ton (#110651)

* fix(ios): shrink chat jump-to-latest pill to a compact icon button

* fix(ios): drop removed jump-to-latest string from native locale artifacts
…8333)

* fix(reef): bound relay request duration

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

* test(reef): satisfy timeout fixture lint

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
* refactor(runtime): centralize bounded I/O handling

* fix(runtime): finalize bounded I/O contracts

* chore(security): drop stale audit import

* docs(changelog): credit bounded I/O fixes

Co-authored-by: Pick-cat <huang.ting3@xydigit.com>

* fix(agents): keep provider HTTP options private

* fix(ai): traverse OpenAI schema maps by value

* fix(runtime): preserve absolute download deadlines

* ci(ui): stabilize compressed CSS budget

* fix(ai): traverse legacy schema applicators

---------

Co-authored-by: Pick-cat <huang.ting3@xydigit.com>
* fix(doctor): bound AGENTS.md and root-memory file reads

* chore(doctor): retrigger CI after QA smoke flake

* fix(doctor): validate root-memory inputs before archiving

* fix(doctor): distinguish oversized root-memory reads from other read failures

* fix(doctor): preserve legacy memory on bounded-read races

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

* fix(doctor): preserve archives on restoration failure

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

* fix(doctor): keep independent archive on migration races

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

* fix(doctor): preserve symlinked workspace guidance

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

* fix(doctor): report atomic archive failures

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
…-aware creation for native chat (#110347)

* feat(clients): gateway session groups, batch operations, session inspector, and new-session options

* chore(i18n): translate session management strings and regenerate catalogs

* chore(i18n): complete translation artifacts for session management strings

* fix(clients): fail closed when a transport cannot honor agent or base-ref session options

* fix(clients): authoritative agent identity for new-session parents and revision-keyed sidebar group refresh

* fix(clients): refetch session groups on remote catalog events and correct Swedish repository-root translation

* fix(clients): resilient new-session popover, revision-keyed group manager, and popover string translations

* fix(clients): scope reset fallback to plain new-session requests and revision-key the inspector groups

* fix(clients): reject empty agent catalogs and refresh sessions on remote group events

* refactor(clients): drop unused agents fetch wrapper and runtime memberwise init flagged by periphery

* chore(i18n): realign locale artifacts after rebase onto model-controls main

* chore(clients): split session creation into the session-actions extension and realign i18n after ask-user main rebase

* chore(i18n): resync derived artifacts after question-card main rebase
* fix(memory): bound qmd taskkill cleanup

* test(memory): satisfy qmd process lint
…ions settings (#110646)

* feat(mac): show native notification permission in dashboard Notifications settings

The Mac app's embedded Control UI showed the web-push section as
Unsupported/Not subscribed even though the app delivers notifications
natively. The dashboard now installs an openclawNotifications WebKit
bridge (status / request-permission / send-test) and the Notifications
settings page renders native permission state with Enable, Open System
Settings, and Send test actions when hosted in the Mac app. Browsers
keep the existing web-push UI. The notifications section renderer moved
out of the oversized config view module.

* fix(ui): break config view import cycle and satisfy lint/deadcode/i18n gates

Move the notifications section props to a leaf contract (no view.ts
type import), unexport the status-event constant, use bracket access
for the injected dunder global, default-case the status switch, and
refresh the native i18n inventory line offset.
…re (#110475)

* refactor(canvas): promote inline widgets to core

* docs(agents): note discord show_widget ownership at core registration

* ci: retrigger after GitHub scheduling outage

* fix(canvas): satisfy dead-code and test type checks
* feat(chat): rewind and fork a session from a message bubble

* docs(web): document chat rewind and fork bubble actions

* fix(chat): lint cleanups, protocol regen, and test splits for rewind/fork CI

* fix(ui): fit chat rewind disabled styles inside the startup CSS budget
@devSejung
devSejung marked this pull request as ready for review July 18, 2026 13:54
@github-actions

Copy link
Copy Markdown
Contributor

Dependency Guard

This PR changes dependency-related files. Maintainers should confirm these changes are intentional.

Changed files:

  • extensions/workspaces/package.json
  • pnpm-lock.yaml

Maintainer follow-up:

  • Review whether the dependency changes are intentional.
  • Inspect resolved package deltas when lockfile, shrinkwrap, or workspace dependency policy changes are present.
  • Treat package-lock.json and npm-shrinkwrap.json diffs as security-review surfaces.
  • Run pnpm deps:changes:report -- --base-ref origin/main --markdown /tmp/dependency-changes.md --json /tmp/dependency-changes.json locally for detailed release-style evidence.

@github-actions

github-actions Bot commented Jul 18, 2026 •

Copy link
Copy Markdown
Contributor

Dependency graph changes noted

This PR includes dependency graph changes. The dependency guard is informational because the PR author is a repository admin or a member of @openclaw/openclaw-secops.

  • Current SHA: 9a5fc441e701ce0c1c40696a74346f7b7719dce2
  • Trusted actor: @devSejung
  • Trusted role: pull request author; repository admin

Security review is still recommended before merge when the dependency graph change is intentional.

@devSejung
devSejung merged commit ba2dbad into main Jul 20, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.