Commit Graph

39265 Commits

Author SHA1 Message Date
Peter Steinberger
897ac2d4b0 fix(auto-reply): surface stale Codex sessions (#110856) 2026-07-18 18:47:04 +01:00
Peter Steinberger
8a5c8690e1 fix(secrets): keep unaffected owners live during reload failures (#110779)
* fix(secrets): isolate reload failures per owner

* refactor(secrets): split runtime activation helpers

* fix(secrets): export web warning type

* fix(secrets): reject unsafe degraded config writes

* fix(secrets): derive reload defaults type

* fix(secrets): defer reload state publication

* fix(secrets): preserve partial refresh state

* fix(secrets): retry superseded reload preflight

* fix(secrets): bind stale credentials to owner contracts

* fix(secrets): scope degraded credential contracts

* fix(secrets): restore source ownership guards

* fix(secrets): recover provider-only degradation

* fix(secrets): enforce degraded reload contracts

* fix(secrets): preserve scoped reload state

* fix(secrets): reconcile deferred descendant state

* fix(secrets): commit reload state atomically

* fix(secrets): preserve source transaction lineage

* test(secrets): use non-secret lineage marker

* chore(plugin-sdk): refresh API baseline

* fix(secrets): canonicalize web owner contracts

* fix(plugin-sdk): preserve legacy secret owner contracts

* fix(secrets): satisfy startup activation types

* test(secrets): align reload fixtures with owner contracts

* refactor(secrets): move source recovery scope helper

* fix(secrets): preserve owner contracts on web failures

* fix(secrets): bind legacy web resolution contract

* fix(secrets): retry stale auth publication
2026-07-18 18:29:24 +01:00
Peter Steinberger
f1a8c04aea fix(cron): clean up recurring jobs converted to one-shot (#110431)
* fix(cron): default updated one-shots to cleanup

* test(cron): type schedule transition fixtures

* chore: leave cron notes to release generation
2026-07-18 18:16:40 +01:00
Peter Steinberger
4d27b5b67e refactor(macos): move PortGuardian state to SQLite (#110527)
* refactor: compose native SQLite bootstrap tables

* refactor: share native SQLite state bootstrap

* refactor(macos): move PortGuardian state to SQLite

* test: align PortGuardian future-schema fixture

* fix(macos): reserve PortGuardian ledger across tunnel spawn

* fix(ci): align PortGuardian migration gates

* fix(macos): tolerate vanished SQLite sidecars

* fix(macos): revalidate PortGuardian writes

* test(macos): use sqlite identity bootstrap
2026-07-18 18:15:17 +01:00
Wynne668
c1eba30949 fix(qa): discard ignored guarded response bodies (#110443)
* fix(qa-lab): release failed suite gateway response bodies

* fix(qa): discard ignored guarded response bodies

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 18:08:16 +01:00
Peter Steinberger
98410d986e refactor(state): move device identity into canonical SQLite state (#110392)
* refactor: store device identities in SQLite

* style: satisfy Swift identity lint limits

* test: harden device identity migration fixtures

* fix: harden SQLite device identity recovery

* chore: remove stale identity helper

* refactor: isolate device identity repair

* chore: remove stale migration import

* test: validate migrated identity key types

* fix: harden device identity repair

* style: format device identity assertion

* fix: derive repaired identity key from PEM

* style: remove redundant PEM conversions

* fix: align native identity store with schema v4

* fix(state): satisfy SQLite identity CI gates

* fix(state): coordinate native identity migration

* test(doctor): include native identity claim path

* fix(infra): preserve coordinator release error

* fix(state): clear identity validation gates

* refactor(apple): remove identity test-only APIs

* refactor(apple): remove dead identity error type

* test(apple): use canonical identity test seam

* test(macos): isolate gateway readiness identity
2026-07-18 17:43:56 +01:00
Peter Steinberger
7a35e243c4 refactor(channels): adopt durable Nextcloud Talk and Nostr ingress (#110653)
Accepted Nextcloud Talk webhook and Nostr relay messages now use the shared durable channel-ingress queue. Claims stay owned until reply-lane terminal completion; bounded append and delivery retries fail closed into dead-letter handling; restart recovery owns redelivery; and Nostr cursors advance only after relay EOSE and durable progress.

Related: #109657
2026-07-18 17:30:37 +01:00
Peter Steinberger
88e5af7097 feat(ui): interleaved sidebar zone with custom session icons and drag ordering (#110682)
* feat(ui): custom session icons with agent-drawable SVG and nav-parity pinned rows

* wip: slice-2 interleaved sidebar zone (pre-review)

* fix(ui): trim icon exports, bypass protocol barrel in startup bundle, regen Swift protocol client

* fix(ui): preserve unknown-agent zone entries on writes, prune entries on any unpin

* fix(ui): reset keeps unloaded session slots; enforce SVG byte cap on canonical form

* fix(ui): archiving a pinned session retires its sidebar zone slot

* fix(ui): persist drag-pinned zone slot only after the pin patch lands

* fix(ui): recompute drop insertion against freshest zone order on pin ack

* fix(ui): consume self-drop events before the zone bailout

* docs(ui): note the non-sidebar unpin pruning contract on pruneSidebarSessionEntry

* refactor(ui): extract pure session-tree projection; drop unused zone type export
2026-07-18 17:13:09 +01:00
Peter Steinberger
3fd3ad8301 fix(ci): restore plugin prerelease validation (#110787)
* test: align plugin prerelease assertions

* test: remove stale vitest import
2026-07-18 17:00:15 +01:00
Peter Steinberger
63a32e360b fix(qa): stop retries after overall health deadline (#110753) 2026-07-18 16:07:35 +01:00
cxbAsDev
80f6acc8de fix(agents): bound IDENTITY.md reads to prevent OOM (#101447)
* fix(agents): bound IDENTITY.md reads to prevent OOM

* fix(agents): reuse shared workspace bootstrap file size limit for IDENTITY.md

* chore: retrigger CI after cancelled gate run

* chore: retrigger CI after runner tooling flake

* chore: retrigger CI after main typecheck fix and runner brew flake

* fix(identity): bound explicit --identity-file imports through shared loader

* fix(agents): unexport parseIdentityMarkdown to satisfy production deadcode scan

* chore: retrigger CI after stuck previous run

* chore: retrigger CI after stuck checks-node-compact-large-4 run

* chore: retrigger CI after stuck checks-node-compact-large-4 and flaky small-9

* fix(agents): report oversized identity file size to the user

When `--identity-file` points at a file exceeding the size limit, the
`no identity data found` error is misleading. Re-throw the fs-safe
`exceeds` error with a human-readable message so the CLI surfaces the
actual cause.

* fix(agents): update test assertion for oversized identity diagnostic

* fix(agents): attach caught error as cause in oversized identity diagnostic

* fix(agents): preserve symlinked identity files

* fix(agents): classify identity size errors exactly

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

* fix(agents): preserve supported identity avatars

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

* fix(agents): keep identity limit private

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

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-18 16:05:45 +01:00
Peter Steinberger
d7b0bacf10 fix(teams-meetings): join and transcribe live meetings reliably (#110615)
* fix(teams-meetings): validate live web flows

* chore(plugin-sdk): update meeting runtime baseline

* test(teams-meetings): align live validation fixtures

* fix(teams-meetings): harden live browser validation

* fix(teams-meetings): preserve live transition lifecycles

* fix(meeting-bot): pass wait budget during recovery

* test(teams-meetings): satisfy extension lint

* fix(teams-meetings): preserve browser session ownership

* fix(teams-meetings): retire audio bridges after leave

* fix(teams-meetings): harden leave and audio ownership

* fix(teams-meetings): preserve leave transition ownership

* fix(teams-meetings): serialize leave cleanup safely

* fix(teams-meetings): guard live transition cleanup

* fix(teams-meetings): preserve adapter boundaries

* fix(teams-meetings): await caption readiness

* fix(teams-meetings): surface caption blockers

* fix(teams-meetings): retry transient media playback

* chore(teams-meetings): defer release notes

* refactor(meeting-bot): isolate navigation error helper

* test(teams-meetings): keep page control helper private

* fix(meeting-bot): bound caption lifecycle cleanup

* chore(plugin-sdk): refresh API baseline

* test(teams-meetings): split caption ownership coverage

* fix(teams-meetings): retry pending audio routing

* fix(teams-meetings): retain leave transition ownership

* fix(teams-meetings): refresh transcript target

* fix(teams-meetings): bound audio routing retries

* fix(teams-meetings): retry pending remote audio

* fix(teams-meetings): harden media source ownership
2026-07-18 15:57:22 +01:00
xingzhou
33151cbc40 fix(apns): keep diagnostics valid when response capture reaches its byte limit (#110483)
* fix(apns): preserve UTF-8 response captures

* test(apns): cover UTF-8 at the real capture limit

* fix(apns): preserve UTF-8 in bounded response captures

Co-authored-by: zhang-guiping <zhang.guiping@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 15:51:31 +01:00
Peter Steinberger
d8846a1dcb refactor(cli): read-only database access for pure-read commands (#110732) 2026-07-18 15:42:28 +01:00
cxbAsDev
593423ecc0 fix(shared): bound ignore-file reads during workspace scans (#101429)
* fix(shared): bound ignore-file reads during workspace scans

* fix(shared): import bounded reader through infra policy wrapper

* fix(shared): preserve chained-symlink ignore files while bounding reads

* fix(shared): correct ignore-rules test calls and remove dead return

* fix(shared): restore ignore matcher return value from addIgnoreRules

* fix(shared): fail closed on oversized ignore files during scans

* style(shared): format ignore-rules signature

* test(shared): rename misleading under-cap ignore-file test

* chore: retrigger CI for unrelated flaky run-with-env shutdown test

* fix(shared): make oversized ignore-file exclusion terminal

* test(shared): remove loadSkillsFromDir dependency for main compat

* chore: retrigger dead-code scan after Periphery/Homebrew flake

* fix(scans): fail closed on ignore read races

* fix(scans): treat fail-closed ignore paths literally

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

* fix(scans): preserve native ignore path semantics

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

* fix(scans): bound ignore rule amplification

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

* fix(scans): preserve case-insensitive fail-closed matching

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

* fix(scans): preserve bounded ignore composition

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

* fix(scans): satisfy matcher method binding lint

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

* fix(scans): preserve ignore matcher case mode

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

* fix(scans): keep matcher options internal

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

* fix(scans): require matcher case contract

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

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-18 15:31:42 +01:00
Peter Steinberger
3f976a949a test(signal): isolate tool-result harness lifecycle (#110720) 2026-07-18 15:06:19 +01:00
Peter Steinberger
e8566596e0 refactor(state): split openclaw-agent-db into focused modules under the line limit (#110707) 2026-07-18 15:04:57 +01:00
Peter Steinberger
0acece4591 feat(chat): rewind and fork a session from a message bubble (#110660)
* 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
2026-07-18 14:46:34 +01:00
Peter Steinberger
9710a1339e refactor(canvas): promote inline-widget hosting and show_widget to core (#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
2026-07-18 14:40:45 +01:00
cxbAsDev
881b0a619f fix(doctor): bound AGENTS.md and root-memory file reads (#101448)
* 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>
2026-07-18 14:05:51 +01:00
Peter Steinberger
40793e6f8b fix: bound pasted input and provider response bodies (#110627)
* 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>
2026-07-18 13:54:56 +01:00
Peter Steinberger
e01a880084 refactor(state): split openclaw-state-db into focused modules under the line limit (#110666) 2026-07-18 13:47:57 +01:00
Peter Steinberger
f6de912efe refactor(update): split update-runner into focused modules under the line limit (#110664) 2026-07-18 12:52:54 +01:00
cxbAsDev
e976e357ea fix(security): bound mcporter registry read in audit (#101772)
* fix(security): bound mcporter registry read in audit

* refactor(security): extract bounded mcporter registry read to own module

Keeps src/security/audit.ts under the TS max-LOC ceiling after the
bounded-read security fix.

* fix(security): preserve bounded symlinked mcporter registry reads in audit

* fix(security): warn when an existing mcporter registry cannot be inspected

* fix(security): consume shared mcporter outcome type and exhaust rejection switch

* fix(security): scope mcporter registry audit

* fix(security): reject named-pipe mcporter registries

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

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 12:33:20 +01:00
cxbAsDev
05fb8e6e61 fix(cli): bound --message-file reads for agent command (#101442)
* fix(cli): bound --message-file reads for agent command

* fix(cli): preserve symlinked --message-file paths with bounded reads

* fix(cli): preserve FIFO message files with bounded reads, document 4 MiB cap

* fix(cli): accept FIFO --message-file targets via bounded descriptor read

* test(cli): drop duplicate FIFO message-file read test

* docs(cli): note 4 MiB --message-file cap in agent help text

* style(commands): format agent-via-gateway test

* fix(cli): preserve procfs message-file reads

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

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-18 12:29:33 +01:00
Peter Steinberger
b95035491c fix: repair model refs after provider deletion (#110648)
* fix(doctor): repair stale provider model refs

* test(doctor): satisfy type and export gates
2026-07-18 12:23:54 +01:00
Peter Steinberger
105aebacea fix: report agent deletion cleanup failures (#110560) 2026-07-18 12:23:39 +01:00
Peter Steinberger
0bbb862c55 fix(gateway): keep setup.detect off the event loop so health stays live (#110625) 2026-07-18 12:19:59 +01:00
Peter Steinberger
01a9e1d398 feat(memory): default cross-conversation recall for personal installs (#110597)
* feat(memory): default private recall for personal installs

* fix(memory): repair remember-across CI checks
2026-07-18 12:16:49 +01:00
Peter Steinberger
3b2797f09b improve(ui): settings cleanup batch — universal config.changed emitter, synced chat prefs, dedupe and copy fixes (#110581)
* fix(gateway): emit config.changed from the reload committer for every accepted write

Agent config_set, CLI, and doctor writes reach the gateway through the file
watcher's reload path, which never broadcast config.changed - only direct RPC
writes did. Move the broadcast to a single onConfigCandidateCommitted hook in
the reload committer so all writers notify connected UIs, including
runtime-skipped commits (writer-intent echo suppression, reload mode off),
and delete the duplicate RPC-side broadcasts.

* feat(ui): sync chat follow-up and commentary prefs across devices

Add chatPersistCommentary and chatFollowUpMode to the ui.prefs sync surface
(schema, types, docs) with clearable null removal for the follow-up override.
Rewrite server-prefs around a descriptor table so a synced pref is one entry
instead of five hand-written code sites. Caption synced rows/sections
(chat prefs, theme, language) and refresh the stale Settings subtitle.

* refactor(ui): dedupe settings constants, drop dead composer branch, refresh copy and docs

Derive the Security tool-profile options from PROFILE_OPTIONS and General's
thinking levels from BASE_THINKING_LEVELS instead of parallel literals.
Remove the unused composer mode:"model" branch, the orphaned
.config-view-toggle CSS family, and stale quick-settings wording. Add static
settings-search entries for the Sessions and Managed Worktrees pages plus a
provenance-row test, and update docs/cli/openclaw.md to describe the current
system-agent config-write policy (denylist roots, route-backing plugin guard,
per-agent routing escalations).

* chore: refresh plugin SDK API baseline after rebase onto current main
2026-07-18 12:10:20 +01:00
Peter Steinberger
347ee45895 fix(secrets): surface degradation in logs and doctor (#109792)
* fix(secrets): surface degraded owners safely

* fix(secrets): preserve degradation ownership across reloads

* fix(secrets): require cold ownership for source recovery

* refactor(secrets): keep assignment provenance internal

* test(secrets): use provider error contract

* fix(secrets): attribute provider failures to active co-owners

* test(secrets): clarify provider failure fixture

* fix(secrets): redact doctor degradation reasons

* test(secrets): align reload harness with runtime state

* test(secrets): cover atomic source publication

* fix(secrets): preserve web owner degradation context

* fix(secrets): retain active web degradation co-owners

* fix(secrets): keep web provider error internal

* refactor(secrets): unify reload degradation state

* refactor(config): remove obsolete source snapshot setter
2026-07-18 11:46:53 +01:00
Peter Steinberger
9d97e10efe refactor: move non-session runtime journals to SQLite (#109427)
* refactor: migrate runtime JSONL state to SQLite

* chore: refresh SQLite migration validation

* fix: preserve safe audit migration order

* fix: sanitize retired audit archives safely

* fix: satisfy SQLite storage architecture gates

* fix: serialize plugin doctor state migrations

* fix: bound memory event SQLite projections

* fix: rotate memory event projections safely

* fix: preserve imported event retention age

* fix: harden memory event export projection

* fix: canonicalize memory event migrations

* fix: harden legacy journal migrations

* fix: report unsafe legacy journal paths

* fix: preserve journal ownership during migration

* fix: keep legacy file imports doctor-only

* fix: align SQLite audit CI coverage

* refactor: keep state helpers module-private

* fix: harden legacy state migration recovery

* fix: reconcile SQLite state audit migration

* test: use neutral audit redaction fixtures

* fix: close SQLite migration recovery gaps

* refactor: split audit migration recovery helpers

* test: prove completed audit pads stay out of backups

* fix: preserve audit record ordinals across blank lines

* fix: align SQLite audit CI contracts

* build: package SQLite audit E2E entries

* fix: preserve audit ordinals in backup snapshots
2026-07-18 11:42:14 +01:00
Peter Steinberger
bc6d9eb16a fix: custom Anthropic models work without maxTokens (#110617)
* fix(agents): default Anthropic max output tokens

* fix(agents): bound omitted Anthropic output cap
2026-07-18 11:39:01 +01:00
mushuiyu886
5360c75de2 fix(tui): stop Codex login lookup hanging the terminal (#109452)
* fix(tui): bound Codex CLI lookup

* fix(tui): bound Codex CLI lookup asynchronously

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

* style(tui): format Codex auth flow

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

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 11:34:21 +01:00
mushuiyu886
adff355caf fix(plugin-sdk): failed raw channel sends report success (#109906)
* fix(plugin-sdk): reject failed raw channel sends

* fix(plugin-sdk): preserve raw result helper compatibility

* test(plugin-sdk): cover raw send fallback errors

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

* fix(security): bound skill-file audit read via safe reader (restore removed fs dependency) (#110589)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 11:30:13 +01:00
cxbAsDev
e22c2dfaaa fix(gateway): bound BOOT.md file read size (#101776)
* 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>
2026-07-18 11:27:40 +01:00
cxbAsDev
2e21d53c84 fix(plugins): bound plugin manifest metadata file reads (#110036)
* 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>
2026-07-18 11:22:30 +01:00
mushuiyu886
04d7462806 fix(plugin-sdk): attached send results report the configured channel (#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>
2026-07-18 11:10:39 +01:00
snowzlmbot
21bd5a49c3 fix(chat): preserve explicit current-source sends in Control UI history (#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>
2026-07-18 11:09:33 +01:00
Peter Steinberger
fab3cdf1d8 refactor(gateway): simplify lifecycle mutation contracts (#110583)
* refactor(gateway): simplify lifecycle mutation contracts

* refactor(cli): unexport internal emitDaemonActionMessage
2026-07-18 11:09:21 +01:00
Peter Steinberger
bf20509c46 fix: prevent TUI PTY tests from aborting after completion (#110610)
* test(tui): await PTY teardown before worker exit

* test(tui): avoid unbound PTY mock assertion
2026-07-18 11:06:32 +01:00
Peter Steinberger
b3650b7012 fix(tui): exit reliably after quit (#110595) 2026-07-18 11:05:09 +01:00
Peter Steinberger
a068d38b66 refactor(plugins)!: remove experimental workspaces plugin (#110416)
* 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
2026-07-18 10:56:37 +01:00
zengLingbiao
fcdf06ed29 fix(config): ignore inherited keys when restoring env refs (#109463)
* 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>
2026-07-18 10:49:53 +01:00
tzy-17
a941d3ab72 fix(shared): reject HTTP status codes outside the 100-599 range (#110554)
* 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>
2026-07-18 10:44:31 +01:00
Peter Steinberger
95d632e644 fix(security): bound skill-file audit read via safe reader (restore removed fs dependency) (#110589) 2026-07-18 10:44:01 +01:00
Peter Lee
2b04c350a3 fix(config): restore process.env after invalid config rejection (#103786)
* 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>
2026-07-18 10:41:44 +01:00
xingzhou
1af6d99658 fix: surface cron errors for empty isolated agent replies (#100229)
* 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>
2026-07-18 10:41:31 +01:00
tzy-17
b34d0a8bb6 fix(gateway): bound usage.list days parameter to 100 years (#110552)
* 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>
2026-07-18 10:40:05 +01:00
Peter Steinberger
f14947d256 fix(codex): persist automatic compaction history (#110587)
* 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
2026-07-18 10:37:25 +01:00