Commit Graph

727 Commits

Author SHA1 Message Date
wings1029
e779abf70e fix(agent-core): handle stdout/stderr stream errors in harness exec (#101370)
* fix(agent-core): handle stdout/stderr stream errors in harness exec

Register error handlers on stdout and stderr streams in
NodeExecutionEnv.exec() to prevent uncaught exceptions when
a pipe breaks (e.g. EPIPE after child process exit).

Without these listeners, Node.js throws an uncaught exception
that crashes the entire agent-core process.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(agent-core): address review — hoist-safe mock and curly lint

- Use vi.hoisted pattern for spawnMock to fix ReferenceError in CI
- Wrap one-line if guard in braces per repo curly rule

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: keep release notes in PR context

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 07:34:11 +01:00
snowzlmbot
53580e13a4 fix(usage): preserve provider-billed zero totals (#101177)
* fix(usage): preserve provider-billed zero totals

* fix(usage): harden provider-billed cost provenance

* fix(openrouter): retry delayed generation metadata

* fix(openrouter): satisfy retry lint

* refactor(openrouter): consume streamed billed cost

* chore: keep release notes out of contributor PR

---------

Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 06:22:28 +01:00
Peter Steinberger
473b3cf789 fix(anthropic): keep error tool results non-empty (#101373)
Co-authored-by: Galin Iliev <5711535+galiniliev@users.noreply.github.com>
2026-07-07 06:17:27 +01:00
Vincent Koc
85d6d94afd refactor(memory): remove unused host SDK exports (#101362) 2026-07-06 21:54:06 -07:00
Peter Steinberger
c5d42593be fix(anthropic): guard SDK client transport (#101357)
Co-authored-by: wangmiao0668000666 <wang.miao86@xydigit.com>
2026-07-07 05:45:49 +01:00
NickNMorty
59097783e2 fix(markdown-core): CJK-friendly emphasis flanking so **标签:**正文 renders bold (#101120) (#101230)
* test(telegram): reproduce CJK emphasis flanking bug

* fix(markdown-core): support CJK emphasis flanking

* fix(markdown-core): type CJK delimiter state (#101120)

* fix(markdown-core): mirror markdown-it Unicode whitespace in CJK delimiter override

Preserves markdown-it isWhiteSpace classification (U+3000, U+00A0, U+2000-200A, etc.) before forcing CJK-adjacent delimiter flags, and adds U+3000/U+2009 regressions. Addresses clawsweeper P1 finding on #101230.

* refactor(markdown): use maintained CJK flanking plugin

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 05:43:42 +01:00
Vincent Koc
84e5327720 fix(text): keep bounded outputs UTF-16 safe (#101355)
Co-authored-by: Alix-007 <li.long15@xydigit.com>
2026-07-06 21:33:24 -07:00
Peter Steinberger
ad5b81e884 fix(memory): trust structured cron archive provenance (#101322)
Prevent user-authored [cron:] text from clearing reset or deleted session memory while preserving structured cron-run opacity.

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
2026-07-07 04:52:21 +01:00
Ayaan Zaidi
c718afe247 refactor(agents): thread runtime-context carrier indexes 2026-07-06 20:34:01 -07:00
Peter Lindsey
f5931f5516 fix(agents): carry current-turn inbound metadata in a tail runtime-context message for byte-stable prompt caching
The active user turn was decorated at request-build time with an inbound
metadata block (Conversation info / reply-target / sender / forwarded /
chat-history), but the session store persists the bare text and the LLM boundary
strips that block from historical replay. So a user message's serialized bytes
changed retroactively — decorated as the active turn, bare as history — on every
turn, invalidating any prefix/exact-match provider prompt cache from that point
onward, every turn. (#90811 fixed the timestamp half of this same asymmetry.)

Rework of the earlier "strip the active turn" approach (which lost model-visible
context — ClawSweeper's P1) into one that keeps the context AND recovers the
cache cost:

- Route current-turn inbound metadata out of the user prompt and into the hidden
  runtime-context custom message (the mechanism from openclaw#89428), and
  relocate that carrier to the ABSOLUTE TAIL of the wire request (after the
  active user turn and any tool-call scaffolding). The user turn stays bare and
  byte-identical in both the active and historical positions; the volatile
  carrier vanishes next turn exactly where the assistant reply begins anyway, so
  the request is an append-only prefix-extension through the active user turn.
- A durable marker (UserMessage.runtimeContextCarrier, set by convertToLlm from
  the carrier's details) lets the Anthropic SDK transport, the managed Anthropic
  transport (anthropic-transport-stream / anthropic-payload-policy), and
  OpenAI-completions skip the carrier when selecting the deepest cache_control
  breakpoint, keeping the anchor on the last stable user turn.

Storage stays BARE (invariant preserved); runtime-only turns (room events) keep
their existing inline behavior, which is byte-stable because room-event/system
context is not strip-eligible; legacy bare-stored sessions are unchanged.

Reviewed with adversarial gpt-5.5/codex sweeps (correctness, byte-identity,
compatibility, test adequacy): found + fixed the managed Anthropic transport
cache-anchor path and added the missing OpenAI-completions/managed-transport
breakpoint tests; a theoretical runtime-only mutation was verified unreachable
and pinned with a test. Final sweep clean.

Co-authored-by: openclaw#89428 (runtime-context handoff approach)
2026-07-06 20:34:01 -07:00
Peter Lindsey
3d87932541 fix(agents): send session_id affinity header to ChatGPT Responses backend
The ChatGPT backend routes requests by session_id (codex-cli sends it); without it each request lands on an arbitrary machine and the prompt cache misses. Measured on live traffic: 56.0% -> 81.8% TRUE cache hit rate (12-turn A/B, identical prompts).
2026-07-06 20:33:51 -07:00
Peter Steinberger
1a307be2e0 feat(skills): add lifecycle curator for workshop-created skills (#101214)
Tracks per-skill usage from the skill.used diagnostic event (trusted-only
delivery, file-scoped identity), sweeps workshop-created skills daily from
gateway maintenance (active -> stale 30d -> archived 90d, pinned bypass,
restore-only unarchive, files never touched), filters archived skills from
snapshots fail-open, reports workspace-scoped overlap candidates, and adds
openclaw skills curator CLI, additive gateway methods, and a warn-only
doctor finding. Zero new config keys; SQLite/Kysely state only.
2026-07-07 03:25:44 +01:00
Ayaan Zaidi
486033b183 fix(agents): normalize compaction recovery tails
Compaction failure and timeout recovery can no longer leave a session transcript assistant-last and wedged after restoring pre-compaction state.

Transcript-continuation failures now carry a typed agent-core error code and no longer demote the active model through model fallback scoring.

Surface: embedded agent runner compaction recovery, model fallback classification, packages/agent-core.

Refs #100312. Includes regression coverage for #99943.
2026-07-07 02:09:21 +00:00
qingminlong
d6f097b3de fix(agents): normalize surrogate cache fingerprints (#101009)
* fix(agents): normalize surrogate cache fingerprints

* fix(agents): reuse provider surrogate sanitizer

* chore(agents): keep transport imports grouped

* fix(agents): avoid runtime import for surrogate sanitizer

* fix(agents): scope surrogate cache normalization

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 03:06:56 +01:00
Vincent Koc
f305e707a3 feat(models): add Claude Mythos 5 support (#101238) 2026-07-06 17:19:49 -07:00
Dallin Romney
95e3b9243b test: execute media and Talk runtime boundaries (#101091)
* test: execute media and Talk runtime boundaries

* test(qa): centralize gateway fixture startup

* test(qa): check in voice call plugin fixture
2026-07-06 16:25:33 -07:00
Vortex Openclaw
1f6ddb5df0 feat(models): add Claude Sonnet 5 support (#98254)
* feat(models): add Claude Sonnet 5 support

Co-authored-by: Ariel Bravy <ariel@vortexradar.com>

* fix(models): align Sonnet 5 validation baselines

* fix(models): satisfy Sonnet 5 CI contracts

* fix(models): enforce Sonnet 5 provider contracts

* docs(changelog): defer Sonnet 5 release note

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Ariel Bravy <ariel@vortexradar.com>
2026-07-07 00:05:35 +01:00
Peter Steinberger
80537c1ba4 feat(macos): load provider catalog during AI onboarding (#101132)
* feat(macos): load onboarding providers from gateway

* test(crestodian): widen setup config mock

* fix(crestodian): satisfy onboarding lint gate

* chore(macos): refresh onboarding localization inventory

* test(plugins): cover guided Copilot secret metadata
2026-07-06 20:57:56 +01:00
Peter Steinberger
912af0a56f fix(gateway): keep N-1 nodes manageable during upgrades (#101109)
* fix(gateway): allow N-1 node protocol maintenance

* docs: refresh generated map for node upgrade guide
2026-07-06 20:01:20 +01:00
Vincent Koc
65a9cb4ed1 refactor(packages): localize internal helper types (#101041) 2026-07-06 10:30:58 -07:00
Peter Steinberger
553acdfc1a feat(gateway): add tts.speak method returning synthesized audio inline (#100770)
* feat(gateway): add tts.speak method returning synthesized audio inline

* test(gateway): type tts.speak synthesis mock for failure shapes

* fix(gateway): restore lowercase normalizer import used by talk catalog

* test(gateway): shift advertised-method window for tts.speak

* fix(gateway): ready tts speak for landing

* docs(changelog): record tts speak gateway API

* test(agents): stabilize fast auto startup synchronization

* test(crabbox): stabilize sparse checkout exit guard
2026-07-06 18:25:08 +01:00
Vincent Koc
bf8626c0e9 feat(providers): add LongCat API support (#100501)
* fix(ai): honor provider reasoning compatibility

* feat(longcat): add hosted provider plugin

* chore(longcat): register package metadata

* docs(longcat): add provider setup guide

* docs(longcat): document self-hosted model routing

* refactor(longcat): externalize provider plugin

* chore(longcat): add npm release artifacts
2026-07-06 10:07:08 -07:00
Peter Steinberger
06789ca4c2 fix(ios): keep offline chat sends on their original route (#100942) 2026-07-06 17:53:05 +01:00
ZZIPP
979d198fd1 fix(media): recognize m2a as MPEG audio (#92167)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 17:48:37 +01:00
Peter Steinberger
84f21bd9fc feat(ui): clickable file links in chat with a workspace file viewer sidebar (#100679)
* feat(ui): link file paths in chat and add workspace file viewer sidebar

Auto-detect file paths in chat markdown (plain paths, path:line, inline
code, explicit/absolute links) and render them as clickable links that
open a dedicated file viewer sidebar with line numbers, highlight.js
syntax highlighting, scroll-to-line, in-file search, reveal-in-rail,
open-in-editor, and copy actions. Workspace rail browser entries are
now previewable even when the transcript never touched them;
sessions.files.get serves any file inside the workspace root with the
existing containment, symlink/hardlink, and size guards.

Closes #100615

* feat(ui): linkify file paths in sidebar markdown and fix file-view gutter width

Markdown rendered in the chat detail sidebar now gets the same clickable
file links as chat messages, opening files via the panel's own click
delegation. File viewer gutter uses a fixed per-file digit width so
short lines no longer indent their code past longer ones.

* fix(ui): keep browser-entry active highlight and narrow file content for editor open

loadWorkspace no longer clears the rail active marker for browser-only
entries, so Show in Files keeps the revealed file highlighted after the
forced reload. openInEditor narrows the sidebar content kind before use,
fixing the tsgo type error.

* chore(ui): fix lint findings in file viewer helpers

* fix(ui): harden workspace file previews

* fix(ui): wire file previews through chat panes

* fix(ui): preserve workspace file targets

* fix(ui): preserve workspace file targets
2026-07-06 17:47:28 +01:00
Dallin Romney
5af7ba92ce refactor: consolidate byte-size formatting (#99768)
* refactor: consolidate byte-size formatting

* fix: stabilize byte formatter import boundary

* fix: keep byte formatter within SDK budget

* fix: emit byte formatter package entry

* refactor: trim byte formatter surface

* fix: use narrow byte formatter import

* refactor: remove byte formatter dependency changes

* fix: refresh rebased byte formatter baseline
2026-07-06 09:26:04 -07:00
Peter Steinberger
30e5dfcf02 feat(gateway): read-only agents.workspace list/get browsing RPCs (#100738)
* feat(gateway): add read-only agents.workspace list/get browsing RPCs

* fix(gateway): gate workspace image reads on sniffed magic bytes, not extension

* fix(gateway): tighten workspace browsing boundary

* docs(gateway): clarify workspace read trust scope

* chore(gateway): leave release notes to release flow
2026-07-06 16:41:24 +01:00
Brian Bell
bacb33a909 fix: keep Bedrock live smoke on Bedrock runtime (#99607)
* fix: preserve Bedrock live API providers

* fix: derive Bedrock smoke region from AWS config

* fix: honor Bedrock discovery region in smoke

* fix: keep Bedrock live smoke on Bedrock runtime

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
2026-07-06 08:19:42 -07:00
Peter Steinberger
88f1ec38d4 feat(sessions): grouping, unread state, and full session controls on web, iOS, and Android (#100814)
Gateway (additive, no protocol version bump): SessionEntry gains
lastReadAt/markedUnreadAt/lastActivityAt; session rows expose a derived
unread flag (explicit mark, or last read before latest activity; never-read
sessions stay read so upgrades do not light up). lastActivityAt is stamped
in the canonical post-run store update - user, channel, and cron runs count
as activity; heartbeat, internal-event, and preserved-state runs do not.
sessions.patch gains unread; sessions.create gains fork (transcript fork
from parentSessionKey under the parent lifecycle lock, refusing active,
concurrently-changed, and oversized parents, cross-agent aware).

Web sidebar: Pinned/custom-group/Ungrouped sections, unread dots, kebab and
right-click context menu (pin, mark unread/read, rename, fork, move to group,
archive, delete guarded for agent main sessions and active runs), mark-read
on view with loop-safe re-acknowledgement and failure retry; sessions page
gets unread + fork actions and shared custom-group helpers.

iOS Command Center: grouped sections, unread/pin indicators, Show Archived
gated on per-entry state, full context menu with rename/new-group alerts and
delete confirmation, current-session preview guarantee, read-episode
re-acknowledgement; new patch/delete/fork transport calls; Swift protocol
models regenerated.

Android SessionsScreen: grouped headers, unread/pin indicators, Archived
filter gated on per-entry state, long-press menu with the full control set,
agent-scoped forks, explicit label/category clears from session events,
main-session fallback when archiving/deleting the open chat, read-episode
re-acknowledgement with failure retry.

Closes #100739
2026-07-06 14:30:55 +01:00
Vincent Koc
709be93ca8 fix(anthropic): restore subscription OAuth billing routing 2026-07-06 06:18:52 -07:00
Peter Steinberger
f53346944d feat: correlate native search outcomes in audit history (#98704)
* feat: correlate native search outcomes in audit history

Metadata-only audit ledger for agent runs and tool actions in the shared
state DB: stable event identity, closed action/status/error vocabularies,
one-way-hashed tool-call ids, never-inferred terminal outcomes for native
web-search (explicit completed/failed only; otherwise unknown), bounded
retention, audit.list gateway RPC and openclaw audit CLI. Squashed from
the 82-commit audit stack for replay onto current main.

* feat(audit): add audit.enabled config gate (default on)

The metadata-only audit ledger records by default: an audit trail enabled
only after an incident cannot explain the incident, and the rows are
strictly less sensitive than the transcripts every install already
stores. audit.enabled=false stops new writes at the gateway subscription
seam; audit.list and openclaw audit keep serving existing records until
they expire. Documented in the configuration reference, protocol page,
and CLI reference.

* fix: repair full-matrix CI findings after rebase

- break the dynamic-tools/dynamic-tool-execution import cycle by
  extracting resolveCodexToolAbortTerminalReason into a leaf module
- restore main's session-worktree protocol exports lost in the
  index.ts auto-merge
- register the audit event writer worker as a knip entry point
- docs table formatting; subagent wait-cancellation test scoped to its
  audit intent (outcome + timing) and advanced past main's new
  lifecycle-timeout retry grace
2026-07-06 12:30:12 +01:00
Vincent Koc
8ce620f3e6 fix(protocol): remove duplicate worktree result exports 2026-07-06 03:37:09 -07:00
Vincent Koc
17777b3a9f refactor: remove proven dead code across runtime surfaces (#100823)
* refactor: remove unused internal helpers

* refactor(ui): remove unused compatibility helpers

* refactor(android): remove unused talk cleanup shim

* refactor(android): remove orphaned legacy UI

* refactor: remove unused private exports

* refactor(docs-i18n): remove dead matcher and satisfy lint
2026-07-06 03:31:19 -07:00
Peter Steinberger
704c584686 fix(protocol): export managed worktree session result types (#100804)
* fix: complete managed worktree surfaces

* chore: drop landed locale changes
2026-07-06 11:23:58 +01:00
Peter Steinberger
fda01a64a7 fix(protocol): export session worktree result types (#100793) 2026-07-06 03:21:38 -07:00
Peter Steinberger
b4b1984fe7 feat(gateway): start a new chat session in a managed worktree (#100788)
Adds an additive worktree flag to sessions.create so any new chat can run in an
isolated managed worktree of the agent's git workspace, with the branch checked
out and .worktreeinclude provisioning applied. The session's spawnedCwd points at
the matching subdirectory inside the worktree so chat runs, CLI, and the file
browser execute there. agents.list gains workspaceGit (workspace or an ancestor
is a git checkout) to gate the affordance; web sidebar, iOS, and Android expose a
New-Chat-in-worktree action. Uses the method's operator.write scope, but the
.openclaw/worktree-setup.sh step runs only for operator.admin callers since it
executes repo code. Deleting the session, or leaving via a plain New Chat, clears
the cwd and lossless-removes the worktree; idle GC treats recent session activity
as worktree activity so an active session's checkout is never swept.

Live-verified end-to-end on a real gateway; follow-up to #100535 (issue #100534).
2026-07-06 10:23:41 +01:00
jincheng-xydt
ba9700d59a fix #99163: harden large chat attachment parsing (#99213)
* fix(gateway): harden large chat attachment parsing

* test(ui): prove large chat image paste

* fix(media): preserve short MIME rejection

---------

Co-authored-by: xjch <267882353+jincheng-xydt@users.noreply.github.com>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-07-06 01:47:21 -07:00
wm0018
e53131ea1c fix(mistral): correct model id typo in usesReasoningEffort helper (#100688)
* fix(mistral): correct model id typo in usesReasoningEffort helper

* chore: re-trigger CI

* test(mistral): cover medium reasoning effort

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 08:57:27 +01:00
lin-hongkuan
aca316ee16 fix(anthropic): normalize tuple tool schemas for Opus 4.8 (#100492)
* fix(anthropic): normalize tuple tool schemas

* fix(anthropic): preserve schema instance values

* test(anthropic): cover Opus tuple schemas live

---------

Co-authored-by: lin-hongkuan <lin-hongkuan@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-05 22:28:37 -07:00
Peter Steinberger
0acd851a3b feat(agents): add managed git worktree lifecycle (create/provision/snapshot/restore/GC) (#100535)
Centralized managed worktrees under <state-dir>/worktrees/<repo-fingerprint>/<name>
with branch-per-task (openclaw/<name>), .worktreeinclude provisioning, an optional
.openclaw/worktree-setup.sh repo hook, and a SQLite registry in the shared state DB.
Removal always snapshots the tree (untracked included, gitignored excluded) to
refs/openclaw/snapshots/<id>; restore rebuilds the branch at the original commit with
the snapshot content as uncommitted state. Lossless run-end cleanup, 7-day idle GC for
run-owned worktrees (manual exempt), orphan reconciliation, 30-day snapshot retention.
Surfaces: worktrees.* gateway RPC (operator.admin mutations), openclaw worktrees CLI,
Control UI page, plugin-SDK facade + Workboard kind:"worktree" materialization.

E2E-verified on Testbox: full create->work->remove->restore->gc lifecycle.
2026-07-06 05:24:58 +01:00
Peter Steinberger
f53103de72 fix(skills): make Skill Workshop lifecycle approvals decidable and non-wedging (#91266, #94249, #93173) (#100498)
Approval wait now fits inside the Codex dynamic-tool watchdog (70s +10s
gateway grace under the 90s kill), approval cards carry proposal id,
skill name, description, file count, and body size (spoof-safe
rendering), and timeouts return a structured pending-not-failed outcome
instead of a bare error. Expired requests cannot execute late; no
auto-apply; generic plugin approvals unchanged.
2026-07-06 04:54:48 +01:00
Peter Steinberger
2bed394793 feat(gateway): add system.info RPC and Gateway Host card in Settings (#100478)
* feat(gateway): add system.info RPC and Gateway Host card in Settings

Settings quick page now shows where the Gateway runs and how the host
is doing: machine name, LAN address and runtime port, OS, Node/PID,
uptime, CPU count and load, RAM, and free disk on the state-dir volume.
Backed by a new additive operator.read RPC (system.info); the card
polls every 10s while visible and hides for clients without the read
scope or against older gateways.

Refs #100465

* docs: regenerate docs map for Gateway host status section

* fix(gateway): harden system info compatibility

* fix(ui): clear stale gateway host info

* docs(changelog): note gateway host status
2026-07-06 04:29:19 +01:00
Peter Steinberger
fdc9aa82d7 feat(cron): declarative jobs with owner attribution and richer status (#100480)
Adds scope-local declaration-key convergence, immutable owner attribution, richer status projection, and delivery validation to canonical cron jobs.

Supersedes the #98727 routines registry approach; no parallel registry, RPC namespace, or CLI noun.
2026-07-06 03:35:26 +01:00
Ben.Li
5199f55ebe fix(gateway-protocol): trim connect error detail codes in readConnectErrorDetailCode (#99555)
* fix(gateway-protocol): trim connect error detail codes in readConnectErrorDetailCode

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore: add connect error detail code trim proof script

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(gateway-protocol): drop proof-only trim script

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 00:59:12 +01:00
Peter Steinberger
a4b032e5d7 fix: harden subprocess, maintenance, and output paths (#100440)
* fix(agents): contain exec output stream failures

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

* fix(tui): contain local shell stream failures

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

* fix(process): contain command output stream failures

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

* fix(skills): isolate remote bin refresh failures

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

* fix(agents): contain background subagent sweep failures

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

* fix(skills): report directory scan failures

Co-authored-by: wendy-chsy <wan.wenyan@xydigit.com>

* fix(agents): classify plugin approval gateway failures

Co-authored-by: 唐梓夷0668001293 <tang.ziyi@xydigit.com>

* fix(exec): preserve sanitized control-byte evidence

Co-authored-by: Lavya Tandel <lavya@loom.local>

* fix(shared): unwrap standalone parameter tags

Co-authored-by: nankingjing <1079826437@qq.com>

* fix(android): fail shared capture on audio read errors

Co-authored-by: NianJiuZst <3235467914@qq.com>

* docs(changelog): record small bugfix sweep

* fix(output): preserve sanitizer boundary semantics

* test: align sanitizer and sweeper regressions

* fix(terminal): preserve text after lone C1 controls

---------

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>
Co-authored-by: wendy-chsy <wan.wenyan@xydigit.com>
Co-authored-by: 唐梓夷0668001293 <tang.ziyi@xydigit.com>
Co-authored-by: Lavya Tandel <lavya@loom.local>
Co-authored-by: nankingjing <1079826437@qq.com>
Co-authored-by: NianJiuZst <3235467914@qq.com>
2026-07-05 22:21:54 +01:00
Peter Steinberger
5e0504aa43 feat(ui): simplify Talk settings (#100453)
Co-authored-by: Peter Steinberger <steipete@openai.com>
2026-07-05 21:31:52 +01:00
Peter Steinberger
c730d8f1f1 feat(logbook): automatic work journal plugin with Control UI timeline tab (#99930)
* feat(logbook): automatic work journal plugin with a plugin-contributed Control UI tab

Squash of PR #99930 work for rebase onto the Control UI route refactor:
- extensions/logbook: Dayflow-style capture -> observations -> timeline cards
  pipeline with SQLite store, node capture commands, standup/ask, retention
- plugin SDK/gateway seam: surface "tab" Control UI descriptors projected
  into hello-ok controlUiTabs (scope-filtered, deterministic order)
- Control UI: dynamic plugin tabs with bundled Logbook view
- docs, tests, labeler wiring

* feat(ui): port plugin tabs and Logbook to the route-owned Control UI architecture

- shared /plugin route carries the tab id in the query (?id=<tab>), matching
  the router's exact-path contract
- openclaw-plugin-page renders bundled views (Logbook), sandboxed plugin
  frames (descriptor path), or the unavailable card
- sidebar renders hello controlUiTabs after each group's static routes
- Logbook view/controller live under ui/src/pages/plugin/

* fix(ui): namespace plugin tabs by pluginId to prevent cross-plugin tab id collisions

* fix(logbook): prefer app capture nodes and rotate off failing nodes

* fix(plugins): reject protocol-relative Control UI tab paths

* fix(logbook): harden automatic journal

* docs(changelog): remove maintainer self-credit

* chore(ui): refresh locale metadata after rebase

* fix(logbook): preserve analysis window boundaries

* fix(logbook): align status privacy and timezone

* fix(ui): stop hidden plugin tab polling
2026-07-05 11:50:44 -07:00
Peter Steinberger
b22c36f112 fix: land ten small reliability fixes (#100399)
* fix(cron): reject sub-millisecond durations

* fix(skill-workshop): preserve proposal terminal newline

Preserve proposal_content exactly at the agent tool boundary and make
renderProposalMarkdown defensively emit a terminal newline.

Add focused regressions for the tool write path and markdown renderer.

* fix(skill-workshop): reject blank raw proposal content

* fix: treat empty-string optional integer tool params as unset

Optional positive-integer tool params (e.g. Telegram replyTo/threadId)
threw ToolInputError when a tool-calling model populated them with an
empty-string or whitespace-only default. Those defaults carry no value,
so readPositiveIntegerParam/readNonNegativeIntegerParam now treat a
blank string as unset (undefined) instead of throwing, while still
rejecting genuinely invalid present values (0, "42.5", "-3"). This
prevents silent message-delivery failures when models emit empty
routing-param defaults. Adds unit tests covering blank vs invalid.

* fix(gateway): log start session persistence failures

The gateway session-lifecycle "start" event persistence
(persistGatewaySessionLifecycleEvent, which surfaces write failures via
requireWriteSuccess) was fired as void ...catch(() => undefined), swallowing
the rejection with zero logging. A failed start-marker write silently dropped
the run's start record from restart-recovery accounting, with no
operator-visible trace.

The sibling terminal-phase catch already logs this since #97839; the start
path was the unfixed sibling. Mirror that fix: log the swallowed start-phase
persistence failure with the same redacted message shape via formatForLog,
keeping the fire-and-forget semantics unchanged. Adds a focused regression
test asserting the log fires on start-persist rejection.

* fix(memory): report close-time pending work failures

* fix(shared): return "" from sliceUtf16Safe when end <= start, matching native .slice

sliceUtf16Safe silently swapped reversed bounds (to < from) instead of
returning "" like String.prototype.slice, creating a subtle footgun for
callers with dynamic start/end pairs.

Caller scan across src/, extensions/, and packages/ confirmed no production
code relies on the old swap behavior — all callers use (text, 0, N) or
(text, -N) forms only.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(plugins): require plugin manifest in npm verifier

* fix(android): propagate CancellationException in CameraHandler catch blocks

Catch (err: Throwable) swallows kotlinx.coroutines.CancellationException,
breaking structured concurrency when the coroutine scope is cancelled
during camera operations (handleList/handleSnap/handleClip).

Add CancellationException rethrow before each Throwable catch to match
the existing pattern used in GatewaySession and TalkModeManager.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(android): propagate CancellationException past GatewaySession invoke boundary

* chore: sync native i18n inventory after gateway session line shift

* fix(agents): prevent native hook relay bridge race condition on renew and registration

Remove synchronous bridge record write after server.listen() that races
before the TCP server binds, and guard renew handler with server.listening
check to prevent stale relay registrations.

Closes #98650

* fix: harden small reliability fixes

Co-authored-by: cxbAsDev <cxbAsDev@users.noreply.github.com>

* docs(agents): explain buffered LSP spawn failures

* docs(agents): clarify LSP spawn timeout invariant

---------

Co-authored-by: qingminlong <qing.minlong@xydigit.com>
Co-authored-by: anyech <anyech@gmail.com>
Co-authored-by: snotty <snotty@users.noreply.github.com>
Co-authored-by: masatohoshino <g515hoshino@gmail.com>
Co-authored-by: lin-hongkuan <lin-hongkuan@users.noreply.github.com>
Co-authored-by: simon-w <weng.qimeng@xydigit.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: 宇宙熊Yzx <53250620+849261680@users.noreply.github.com>
Co-authored-by: xialonglee <li.xialong@xydigit.com>
Co-authored-by: nankingjing <1079826437@qq.com>
Co-authored-by: cxbAsDev <cxbAsDev@users.noreply.github.com>
2026-07-05 11:12:55 -07:00
Peter Steinberger
f607ba0691 feat(control-ui): session grouping with drag & drop and channel categorization (#100262)
* feat(control-ui): session grouping with drag & drop and channel categorization

* fix(control-ui): restrict session drag&drop to private session-key payloads

* chore(i18n): translate session grouping strings across control ui locales

* chore(protocol): regenerate swift gateway models for session category

* chore(protocol): regenerate swift gateway models for session category
2026-07-05 09:13:17 -07:00
Jason
95ebb3dc1e fix(tui): surface safe tool-validation abort diagnostics (#91002)
* fix(tui): show last tool-error summary on aborted runs

When a run ends while looping on tool-call validation errors the TUI showed
only "run aborted". Carry the last tool failure on the terminal lifecycle
metadata and render a sanitized one-line summary on the abort line, e.g.
"run aborted: edit tool validation failed: edits: must have required properties edits".
Argument dumps are stripped; with no summary it stays "run aborted".

Refs #90982

* fix(tui): secure abort validation diagnostics

* docs(changelog): move TUI fix to unreleased

* docs(changelog): aggregate TUI fixes

* fix(tui): scope abort validation diagnostics

* docs(changelog): restore unreleased spacing

* fix(tui): scope abort validation diagnostics

* fix(tui): scope abort validation diagnostics

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 08:30:20 -07:00