Commit Graph

66940 Commits

Author SHA1 Message Date
Peter Steinberger
63e00eb573 fix(tui): preserve terminal errors across history reloads (#104864) 2026-07-11 19:18:06 -07:00
Peter Steinberger
4eb1f5225c feat(ui): add standalone operator approval links (#103698)
* feat(gateway): standalone approval deep-link page

Squash-rebased #103698 segment onto the typed-actions tip on current main.
Adds the tokenless /approve/{id} standalone approval UI served by the
gateway control-UI router, gateway-store ephemeral login fix (selectGateway
only on changed URL), and approval-page i18n strings.

Drift reconciliation: union-merged i18n translation-memory caches and
regenerated locale metadata via control-ui-i18n sync (33 approvalPage keys
remain English fallbacks in minor locales, as on the original branch).

(cherry picked from commit c82f56011bfe9f0debb8ebe052f14590c187340d)
(cherry picked from commit 80f5636a8b67a3d6a5f330620541a39d4ef3fe6f)
(cherry picked from commit a3e300d337a92bf1b593a0bb52b7ec4549910a21)
(cherry picked from commit 860ad01f9658bba54cb3d59644e5e1a032c0bb3f)
(cherry picked from commit d8b697b28a847950a1797da07fc0ae4c24928492)
(cherry picked from commit 8a654e3271fd5721358812f961a7a7bb386d6726)
(cherry picked from commit 2f776d2e7bf910271fcbd9697597f6f5478b0f30)
(cherry picked from commit 14e64e6e4d763be830830801eeec1a6f17441688)
(cherry picked from commit 4df9ec828d0034fdc76540ff0fe341e599b0f281)
(cherry picked from commit e52968f4ab)
(cherry picked from commit 7214fc25013966f99ff4b2d506aa2f5f789e2113)
(cherry picked from commit c6259ff79787c759c136086e1a54c9ead8e89539)
(cherry picked from commit a58d9f271d27481615f0c94a828704c563d5354f)
(cherry picked from commit dcf1cb6d98)

* fix(ui): preserve approval page gateway auth

* fix(ui): keep approval disconnects fail closed

* style(ui): format approval disconnect copy
2026-07-11 19:16:23 -07:00
Shakker
50400c92bc docs: note assistant action alignment (#104884) 2026-07-12 03:13:11 +01:00
Shakker
78368518aa fix: keep message context preview compact 2026-07-12 03:13:11 +01:00
Shakker
6599149f0b feat: left-align assistant message actions 2026-07-12 03:13:11 +01:00
Vincent Koc
1507069d22 refactor(ui): consolidate workboard runtime state (#104891) 2026-07-12 10:11:39 +08:00
Peter Steinberger
2d4f09de22 fix(ci): repair typed approval main gates (#104882) 2026-07-11 19:03:25 -07:00
Vincent Koc
dfa580e989 fix(plugins): complete session catalog contracts 2026-07-12 03:49:16 +02:00
Vincent Koc
28954c8ab0 fix(release): ship Crabbox lease helper 2026-07-12 03:49:10 +02:00
Vincent Koc
b575b5ee9b fix(gateway): restore chat protocol type import 2026-07-12 03:49:04 +02:00
Peter Steinberger
7a456e362d feat(channels): add typed cross-surface approval actions (#103679)
* fix(gateway): approval registry hardening and protocol-surface follow-ups

Follow-up delta to the merged #103579 head, rebased onto current main:
- gateway-protocol wire types derive from owner-module schema consts
  (types.ts tombstone) and ProtocolSchemas leaves the package index so the
  public plugin-sdk d.ts graph tree-shakes the registry declaration
- approval access authority follows the operator.approvals scope tier with
  reviewerDeviceIds as the opt-in restriction (cross-surface
  first-answer-wins; requester identity gates only legacy adapters)
- plugin node.invoke approvals register directly so unrenderable
  presentations fail closed before request routing
- exec-approval manager reconciliation with #103515 revocation hardening
  (resolution source attribution, one-shot ask-fallback consumption)
- surface-report pins and plugin-sdk API baseline refreshed; Swift models
  regenerated

* feat(channels): add typed operator approval actions

Squash-rebased #103679 segment onto the durable-approval-registry tip on
current main. Typed approval/command/select presentation actions replace
raw-string inference across slack/telegram/discord/matrix/imessage/whatsapp,
approval.resolve carries an explicit kind, and channel adapters map native
callback envelopes through the typed action registry.

Drift reconciliation: deprecated buildExecApprovalInteractiveReply assertions
dropped (#104650 removed the shims); worker_environments bootstrap-column
migration kept alongside the approval resolution_ref backfill; plugin-sdk API
baseline regenerated.

(cherry picked from commit 68765a5d39d2118c88a7a54d00387337912d4494)
(cherry picked from commit 8642ac12af142e4b751f4f30d4b114615e7e5f66)
(cherry picked from commit 036c4bc39499925fc03de16ec9302e346769350a)
(cherry picked from commit 19dc350d6bc34e29a5169c6bc80971b0ad12adde)
(cherry picked from commit fc978b0bad86aef421c79f6a211b25cc1b743c01)
(cherry picked from commit 10de4d1ed5071f9be6ad1ee5d1e32c0fa8c9d11c)
(cherry picked from commit 9a664ced1b1fa740172b258f355f1a82925ae41c)
(cherry picked from commit c5ff69abbf444139e9e007bfa45beb0f00ffea54)
(cherry picked from commit d466a80795)
(cherry picked from commit f5b4fe40dd5c961322f8553cc80b2fdfb3f6503e)
(cherry picked from commit 7340b4749a4cc4c72f7a41cce1bc9cb550cae038)
(cherry picked from commit a151f41808f23ae60b10305ccd2bc959b9169a86)

* fix(approvals): preserve typed transport ownership

* test(imessage): narrow chunked approval text

* refactor(protocol): remove retired type tombstone

* fix(plugin-sdk): align surface budgets after rebase

* docs(changelog): note typed operator approvals

* docs(changelog): defer typed approval release note
2026-07-11 18:31:05 -07:00
Vincent Koc
350c810256 fix(codex): preserve beta5 MCP bindings 2026-07-12 09:30:50 +08:00
Peter Steinberger
11ea4df29c feat(fleet): per-cell disk limits, egress policy, backup/restore, and cell diagnostics (#104828)
* feat(fleet): per-cell disk limits, egress policy, backup/restore, logs, and doctor

- fleet create --disk <size> caps the container writable layer via --storage-opt;
  unsupported storage backends fail create with an actionable support-matrix
  error, and the limit replays across upgrade/restore through a fleet-owned
  container label because Podman inspect has no HostConfig.StorageOpt.
- fleet create --network bridge|internal adds an opt-in no-egress mode on
  Podman (published loopback port keeps working, verified live); Docker
  internal cells are rejected fail-closed because Docker does not publish
  loopback ports on internal networks.
- fleet backup/restore: per-tenant 0600 tar archives with manifest tenant
  binding, symlink/hardlink rejection, byte and path-segment budgets,
  root-bounded extraction, atomic no-overwrite publish, lease fencing, and
  Gateway token rotation on restore; failures preserve displaced data and
  never leave a force-stopped or half-started cell serving silently.
- fleet logs: ownership-asserted, bounded, token-redacted on both streams,
  with a generation re-check so a concurrent restore cannot leak a rotated
  token.
- fleet doctor: read-only per-cell audit of ownership labels, health,
  hardening drift, loopback port binding, token presence, network egress
  mode, and 0700 state-dir permissions; any failed finding exits nonzero.
  Cross-runtime checks are grounded in live-verified Docker 28/Podman 4.9
  inspect shapes (CapDrop vs EffectiveCaps, missing StorageOpt, missing
  network containers map).

Related: #104436 (v1 shipped in #104527)

* fix(fleet): harden streamed log redaction and root restore ownership

- redacting stream writer honors target backpressure, retains secret-prefix
  overlap across forced long-line flushes, and never splits a token between
  emitted chunks
- root-invoked restores repair ownership for explicit non-root user mappings
  instead of leaving root-owned 0700 state trees
- fleet logs merges the shipped --follow streaming surface (#104669) with the
  v1.1 token-redaction contract

* fix(fleet): stream partial log lines live and report phase-accurate restore recovery paths

- the redacting log writer emits safe text on every chunk (retaining only a
  possible token prefix) so unterminated progress output streams immediately
- restore failure notes distinguish pre-swap, displaced, and swapped states so
  operators recover the correct tree, and an unavailable runtime inspection is
  reported as an unverified replacement instead of silence

* fix(fleet): reject backslash archive paths, guard stderr pipes, and validate disk-limit labels in doctor

- restore/backup path rules reject literal backslashes so a tampered entry
  cannot validate as one path and extract as another on POSIX
- fleet logs handles broken pipes on stderr as well as stdout
- fleet doctor fails malformed disk-limit labels that would break
  upgrade/restore replay instead of reporting them as passing
2026-07-11 18:24:01 -07:00
Peter Steinberger
508f6a2996 refactor(config): retire legacy flat streaming keys to doctor-owned migration (#104693)
* chore(config): regenerate bundled channel config metadata for retired flat streaming keys

* refactor(config): retire legacy flat streaming keys to doctor-owned migration

* fix(config): restore zod locale installer dropped in rebase and repin SDK surface
2026-07-11 18:15:03 -07:00
Peter Steinberger
f2bd7f5916 fix(docs): preserve translated inline code 2026-07-11 21:13:48 -04:00
Peter Steinberger
2829fe107c improve(ui): retire the Overview page for a chat-first start screen (#104819)
* feat(ui): replace Overview page with Connection settings and sidebar attention chips

* feat(ui): open new-session drafts on the chat start screen hero

* refactor(ui): drop old overview-hints paths after rename

* chore(i18n): sync control-ui locale bundles for connection/palette/attention keys

* test(ui): expect attention slot above the sidebar update card

* chore(i18n): re-sync locale bundles after rebase onto main

* test(ui): stub sidebar-attention RPCs in app-sidebar unit tests

* test(ui): use a non-secret-shaped token fixture in connection view test

* refactor(ui): destructure gateway connection in connection settings draft

* refactor(ui): keep connection settings code out of secret-scanner shapes

* test(ui): expect Connection in the settings Connections group

* improve(ui): idle-refresh sidebar attention chips for always-visible windows

* chore(i18n): refresh raw-copy baseline after rebase

* docs(ui): note the unknown-route chat fallback covers retired paths
2026-07-11 18:11:14 -07:00
Peter Steinberger
9a04fb40ce feat(ui): replace composer run-status pill with a transcript working spark (#104768)
* feat(ui): redesign composer run-status indicator as chrome-free status text

* feat(ui): replace run-status text with transcript working spark

* fix(ui): keep working spark through reloads, dodge running tool rows, show mobile interrupted toast

* fix(ui): satisfy lint on tool-stream marker access
2026-07-11 18:08:43 -07:00
Peter Steinberger
4b6bbd52e6 fix(mac): prevent onboarding installer output hang (#104827) 2026-07-11 18:05:06 -07:00
Peter Steinberger
3fe61030be fix: rebuild mac app for generated protocol changes (#104839) 2026-07-11 18:00:42 -07:00
Ayaan Zaidi
4bbca30990 fix(plugin-sdk): keep shipped ErrorKind/detectErrorKind as deprecated compat
The latest stable package exposes both names via the deprecated
openclaw/plugin-sdk/infra-runtime subpath. Compat now lives in the barrel
itself with the old substring semantics and a removal plan; core runtime no
longer uses them. Also converts the chat mapping switch to an if-chain for
switch-exhaustiveness lint.
2026-07-12 06:25:54 +05:30
Ayaan Zaidi
a303ca607c fix(gateway): badge timeout only for timeout-shaped errors
FailoverReason timeout is the retryable-transient bucket and deliberately
swallows generic 5xx, so it cannot drive the user-facing timeout badge.
Rate-limit/overload/context mapping stays on the canonical reason; the
timeout badge now requires isTimeoutError. HTTP 500 badges stay unknown.
2026-07-12 06:25:54 +05:30
Ayaan Zaidi
5ffa6db0de fix(gateway): classify chat error kind via canonical failover reasons
Deletes the naive substring detectErrorKind from infra/errors; the chat error
badge now maps resolveFailoverReasonFromError into the protocol errorKind set,
with refusal kept as a chat-local stop-reason check. Fixes drift where a Groq
TPM 413 showed context_length instead of rate_limit and quota/CJK/socket
errors showed unknown.

Part of #104219 (seam 5, slice 1).
2026-07-12 06:25:54 +05:30
Peter Steinberger
0d84eb4e70 fix(skills): read node-hosted skills from their publishing node (#104832)
* fix(skills): make node skill locators readable

* test(skills): track node skill temp directory

* chore: defer node skill changelog to release process
2026-07-11 17:54:14 -07:00
Peter Steinberger
d05391b9b3 fix: prevent Slack startup from loading stale builds (#104831) 2026-07-11 17:51:19 -07:00
Peter Steinberger
ecefc6cab6 fix(slack): align App Home with active commands 2026-07-11 17:47:25 -07:00
Peter Steinberger
12f7d9c784 fix(slack): honor configured App Home command
Co-authored-by: Jonathan Tsai <jontsai@users.noreply.github.com>
2026-07-11 17:47:25 -07:00
Alix-007
e7c3f7be6c fix(discord): add timeouts to PluralKit lookup requests (#104121)
* fix(discord): add timeouts to PluralKit lookup requests

* fix(discord): bound PluralKit preflight cancellation

* docs(changelog): note PluralKit lookup deadline

* chore: keep changelog release-owned

* test(discord): reject PluralKit aborts with errors

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 17:44:52 -07:00
Peter Steinberger
a37962e90c refactor(cron): compress trigger tool guidance (#104826) 2026-07-11 17:42:49 -07:00
Vincent Koc
12f6a79481 fix(test): contain TUI validation abort teardown 2026-07-12 08:40:22 +08:00
Vincent Koc
c2819d5cfa test(gateway): expect provider policy context 2026-07-12 08:40:22 +08:00
Vincent Koc
d826581d26 test(gateway): mock provider policy surface 2026-07-12 08:40:22 +08:00
Vincent Koc
38b2494bfc test(lint): allow external public surface loader 2026-07-12 08:40:22 +08:00
Vincent Koc
bbdb24a278 test(agents): mock provider policy surface 2026-07-12 08:40:22 +08:00
Vincent Koc
16a647041c fix(providers): load trusted external thinking policies 2026-07-12 08:40:22 +08:00
Erick Kinnee
43634f616b fix(control-ui): use canonical thinkingDefault key in Quick Config (#104523)
* fix(control-ui): use canonical thinkingDefault key in Quick Config

The Control UI Quick Config panel was reading and writing the
non-canonical key agents.defaults.thinkingLevel, which is rejected
by the gateway's strict Zod schema with INVALID_REQUEST errors.

Fix: read from and write to agents.defaults.thinkingDefault instead.
The schema already defines this key and the runtime already reads it
at cfg.agents?.defaults?.thinkingDefault, so this is purely a UI path
correction with zero runtime changes.

The fast-mode control is left unchanged pending a maintainer decision
on its intended scope (per-agent, per-model, or new global default).

Refs #104501

* test(control-ui): prove quick thinking persistence

* docs(changelog): note Quick Config thinking fix

* chore: keep changelog release-owned

---------

Co-authored-by: Erick Kinnee <erick@ekinnee.dev>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 17:40:11 -07:00
Peter Steinberger
82667a66e5 feat(ui): editable file panel with CodeMirror and sessions.files.set hash-CAS writes (#104757)
* feat(gateway): add sessions.files.set workspace file write with hash CAS (#104698)

* feat(ui): CodeMirror file editor panel with CAS save + clickable tool-card paths (#104698)

* fix(gateway): issue the file CAS hash only for strict-UTF-8 text (#104698)

* docs(web): document the editable file detail panel (#104698)

* fix(gateway,ui): round-trip BOM and CRLF bytes through the file editor (#104698)

* fix(ui): keep mixed-line-ending files read-only in the file editor (#104698)

* fix(ui): re-gate editability when a conflict reload returns non-editable content (#104698)

* fix(gateway): reject NUL bytes in sessions.files.set replacement content (#104698)

* fix(gateway,ui): regenerate protocol bindings, fix prod types and lint for file editor (#104698)
2026-07-11 17:36:28 -07:00
Vincent Koc
39e2da5bb6 fix(cli): cap usage cost RPC timeout (#104823) 2026-07-12 08:36:23 +08:00
llagy007
d8bcd014c7 fix(signal): align supported message actions (#104788)
* fix(signal): align supported message actions

* test(signal): clarify supported message actions

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 17:34:07 -07:00
litang9
a0c4c31a17 fix(feishu): configure websocket ping timeout (#103763) 2026-07-11 17:31:59 -07:00
Peter Steinberger
04f945fabe feat(cloud-workers): durable transcript commit protocol for worker sessions (#104809)
* feat(cloud-workers): add transcript commit protocol

* feat(cloud-workers): persist transcript commit replay state

* feat(cloud-workers): apply transcript commits to sessions

* fix(cloud-workers): harden transcript commit admission

* fix(cloud-workers): recover branched transcript commits

* fix(cloud-workers): preserve diagnostic semantics
2026-07-11 17:29:07 -07:00
Peter Steinberger
2e6c1090c1 fix: quiet expected live updater warnings (#104813) 2026-07-11 17:27:01 -07:00
Peter Steinberger
3255b3218a feat: unify external sessions with native catalog pagination (#104717)
* feat(gateway): add generic sessions.catalog surface with plugin SDK registration seam

* feat(agents): support one-shot forked CLI session resume with successor rebinding

* feat(anthropic): adopt local Claude CLI sessions into native chats via catalog continue

* feat(codex): register the session catalog provider independently of supervision

* refactor(ui): delete the retired custom Claude/Codex session tab views

* feat(ui): render external session catalogs as native sidebar sessions and chat panes

* docs: describe the unified native session catalog

* fix: harden forked CLI resume and catalog transcript mapping after review

* fix: satisfy strict typecheck for catalog source guard and imported message cast

* chore(i18n): regenerate session catalog locales

* fix(codex): simplify session source guard type

* fix(ui): paginate sidebar session catalogs

* chore(i18n): refresh catalog metadata after main merge

* fix(ui): harden session catalog pagination refresh

* test(agents): use sqlite session accessor in fork tests

* fix(ci): refresh session catalog generated surfaces

* fix(ui): align session catalog locales

* fix: address session catalog review findings

* fix(sessions): roll back failed plugin catalog adoption

* test(sessions): preserve CLI binding literals

* fix(ui): restore native session pagination label

* docs: note external session catalogs

* Revert "docs: note external session catalogs"

This reverts commit cfb503f160.
2026-07-11 17:26:26 -07:00
NIO
9c0c932c33 fix(mcp): bound short-lived OAuth requests (#103704)
* fix(mcp): bound CLI OAuth login through guarded fetch timeout

* fix(mcp): bound OAuth request lifecycles

Co-authored-by: NIO <nocodet@mail.com>

* fix(mcp): preserve caller cancellation

* test(mcp): centralize timeout rejection capture

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: NIO <nocodet@mail.com>
2026-07-11 17:22:55 -07:00
snowzlmbot
be373ea516 improve(android): show provider-configured model details (#101912)
* feat(android): show provider model inventory

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

* fix(gateway): project provider inventory routes

* style(android): satisfy provider inventory ktlint

* chore(android): sync provider inventory i18n

* style(android): finish provider inventory formatting

* fix(android): harden provider inventory refresh

* test(gateway): type provider inventory fixture

* chore(protocol): regenerate Swift model choice

* chore(android): sync provider inventory i18n

* test(gateway): pin provider inventory discovery mode

* chore(android): sync provider inventory landing

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
2026-07-11 17:22:16 -07:00
Peter Steinberger
b5251c4274 fix(sessions): read zstd transcript archives through a materialized cache (#104795)
* fix(sessions): read zstd transcript archives through a materialized cache

Compressed archives were discovered but unreadable: the reset-archive
header probe read raw zstd bytes and every JSONL reader parsed them as
malformed lines, so compressed archives silently contributed zero
history and zero usage. Archives are write-once, so they materialize
once into a plain JSONL cache under the OpenClaw tmp dir and every
downstream reader (index, tail chunks, probes, usage scans) works
unchanged; the usage scanner also decompresses directly for whole-file
iteration.

* fix(sessions): keep usage byte-range semantics for compressed archives

Route zstd archive usage reads through the materialized plain-JSONL
cache so persisted incremental-scan offsets always measure decompressed
bytes; the whole-file decompress branch ignored requested ranges and
could overcount archived usage.

* fix(sessions): normalize compressed archives to decompressed space at usage discovery

Sizes, incremental offsets, and cache signatures for zstd archives now
all measure the materialized plain-JSONL cache, closing the truncation
window when persisted offsets from the compressed path met decompressed
reads.

* fix(sessions): gate the archive read cache on source identity

Every materialized-cache hit now stats the source archive: a deleted or
budget-evicted archive scrubs its cache entries instead of serving
stale plaintext, and the cache name carries the source size so a
same-path rewrite can never alias.

* fix(sessions): include source mtime in the archive cache identity

Same-path same-size rewrites can no longer alias a stale plaintext
cache entry; any source change mints a new cache name and the previous
entries are scrubbed on the next materialization.

* fix(sessions): bound and isolate the materialized archive cache

Cache entries expire on a 24h TTL sweep so budget-evicted archives
cannot leave plaintext copies behind, stale-identity scrubbing skips
the live identity and in-flight temp files, and unique temp names plus
last-rename-wins make concurrent materialization race-free.

* fix(sessions): drop useless probe-path initializer flagged by lint
2026-07-11 17:20:32 -07:00
Vincent Koc
603ce7e84d test(ci): cover OCM release pin 2026-07-12 08:16:22 +08:00
Vincent Koc
65695bc5bb ci(perf): pin OCM v0.2.25 2026-07-12 08:16:22 +08:00
Peter Steinberger
4e50f1ebc2 ci: allow frozen UI fixture headroom (#104805) 2026-07-11 17:14:06 -07:00
Sarah Fortune
fd37c0318d fix(slack): prefer configured slash command (#104736)
* fix(slack): preserve resolved secrets for slash replies

* fix(slack): register configured slash command with native commands

* fix(slack): preserve slash config refresh semantics

* refactor(slack): keep slash fix focused

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-07-11 17:14:02 -07:00
Alix-007
78a98a7efa fix(telegram): add timeouts to getChat lookup requests (#104289)
* fix(telegram): add timeouts to getChat lookup requests

* fix(telegram): reuse shared timeout abort helper
2026-07-11 17:13:14 -07:00