Commit Graph

855 Commits

Author SHA1 Message Date
Peter Steinberger
b6bac30e33 refactor(agent-core): delete the unused session harness layer (#110287) 2026-07-18 02:27:48 +01:00
Patrick Erichsen
f9b860fc84 feat(plugins): order featured catalog by recency (#110273) 2026-07-17 18:06:13 -07:00
Peter Steinberger
92e8e8bca6 test: move deferred-event-buffer test to its packages/ai owner and drop dead protocol test 2026-07-17 17:36:48 -07:00
Peter Steinberger
897198b9f5 feat(gateway): typed structured questions on openclaw.chat with live option cards (#110242)
* feat(gateway): typed structured questions on openclaw.chat

The chat result gains an additive optional question field (2-4 options, one
recommended max, per-option reply text). Producers: the two onboarding welcome
variants (apply-setup yes/ask, ready next-step) and hosted wizard select/confirm
steps, which mirror the awaited step so card clients render real wizard choices.
Prose replies always stand alone for text-only clients (macOS app, TUI). The
custodian page consumes the typed field and drops the PR1 string-marker parser
(never shipped in a release); cards send the option reply while the transcript
shows the label.

* chore: keep OnboardingWelcome type module-local

* chore(protocol): regenerate Swift bindings for the chat question field
2026-07-18 01:14:44 +01:00
Peter Steinberger
ec8f6e5e03 feat(browser): add secure per-tab copilot panel (#109817)
* feat(browser): add copilot security contracts

* fix(gateway): expose verified client identity to handlers

* feat(browser): add secure per-tab copilot panel

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* refactor(browser): separate copilot gateway hint custody

* fix(browser): preserve legacy pairing parse shape

* fix(browser): harden copilot lifecycle custody

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): enforce copilot lifecycle boundaries

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* style(browser): format copilot sources

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): preserve copilot consent revocation

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* refactor(browser): split copilot custody owners

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(browser): normalize websocket array buffers

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* chore(protocol): regenerate Swift gateway models

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* refactor(browser): model copilot runtime entrypoints

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): honor extension build boundaries

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(gateway): assert targeted chat delivery

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(gateway): cover targeted delivery calls

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): declare copilot build dependencies

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(ci): clear browser copilot gate failures

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(ci): cover copilot lint exclusion

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* fix(browser): gate copilot on relay custody

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

* test(browser): bound copilot relay frames

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>

---------

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>
2026-07-18 01:00:23 +01:00
Peter Steinberger
c1ee9c6fb1 fix: network error hardening, session short-id entropy, extension load caching (#110196)
* fix(infra): harden network client errors, session short ids, and extension load caching

* fix(infra): preserve injected dispatcher seams and drop the uncached extension loader
2026-07-18 00:35:13 +01:00
Peter Steinberger
781913025b improve: stream native sessions as hosts finish (#110211)
* perf: stream native session catalogs by host

* fix: satisfy session catalog CI contracts

* fix: retain changed-session refresh timing

* fix: keep catalog refresh helpers private
2026-07-17 23:59:57 +01:00
Peter Steinberger
da44d52ac6 feat: ask_user — structured questions from the agent with web card, channel buttons, and text answers (#109922)
* feat(gateway): add transient question runtime (question.* methods + broadcasts)

* feat(agents): add blocking ask_user question tool with chat prompt delivery and text-reply claim

* feat(ui): interactive in-thread question cards for ask_user

* feat(channels): native tap-to-answer buttons for ask_user on Telegram, Discord, and Slack

* feat(ui): unify codex and gateway question cards with interactive gateway answering

* refactor(agents): collapse ask_user pending state to one registry; docs for ask_user

* fix(agents): include ask_user in normal gateway runs; add question-flow control-ui e2e

* test(ui): avoid credential-shaped fixture in question card test

* refactor(ui): reorder stream-group context keys

* fix(gateway,ui): validate question answers at resolve; reject secret/duplicate-label questions; UI retry and reconnect hardening

* fix(gateway,agents): canonicalize accepted option answers; bound ask_user option labels to 64 chars

* chore(ci): prune unused question exports, allowlist mobile question events, fix discord lint

* chore(ci): regenerate protocol/i18n/docs/tool-display artifacts for question surface

* fix(protocol): flatten QuestionRecord for native codegen; drop TS-only alias from schema registry

* chore(android): regenerate ask-user localization resources

* docs: regenerate docs map after rebase

* fix(ci): avoid stale read-only dependency disks

* test: remove stale reef lint suppression ratchet

* fix(ci): keep source locale drift advisory in release gates

* fix(ci): scope locale advisory handling to parity check
2026-07-17 22:24:17 +01:00
Peter Steinberger
b319493a52 improve: let Code Mode use declared tool result shapes (#109813)
* feat(agents): add Code Mode output contracts

* perf(agents): defer untrusted tool schemas

* chore(plugin-sdk): refresh API baseline

* fix(agents): preserve deferred schema markers

* fix(agents): preserve policy-blocked tool results

* fix(agents): preserve nullable output contracts

* fix(agents): reject policy blocks from success contracts

* fix(agents): preserve output contracts through normalization

* test(agents): type normalized tool fixtures

* fix(agents): validate catalog results before projection

* fix(agents): keep result snapshots internal

* fix(agents): fail closed on unrenderable unions

* fix(agents): preserve empty result markers

* test(agents): keep result fixture discriminator literal

* test(agents): use native own-property check
2026-07-17 14:46:37 +01:00
Peter Steinberger
cbaf112355 fix: compaction usage guards and agent-loop turn correctness (#109709)
* fix(agents): compaction usage guards and agent-loop turn correctness

* fix(agents): manual compaction replans with zero retention for small sessions

* ci: retrigger pull-request validation

* ci: refresh pull-request validation

* test(agents): live end-to-end agent session coverage

* fix(agents): keep yielded runs settled so external delivery can claim the session

* docs(agents): clarify length retry bookkeeping
2026-07-17 14:13:29 +01:00
Peter Steinberger
8020dd3e08 fix(reef): discover trusted peers as conversations (#109905)
* fix(reef): discover trusted peer conversations

* test(reef): document temporary state cleanup

* test(gateway): include conversation discovery in method order

* chore: leave changelog to release automation

* fix(gateway): preserve configured conversation discovery

* fix(gateway): validate turns before session binding

* fix(gateway): preserve directory conversation identity
2026-07-17 13:55:30 +01:00
WhatsSkiLL
4d3b18811e feat(android): add Wear real-time Talk controls (#109483)
* feat(android): add Wear real-time Talk controls

* fix(android): satisfy Wear Talk CI checks

* fix(talk): remove unused client language parameter

* fix(android): harden Wear realtime Talk routing

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* chore(android): refresh Wear Talk metadata

* chore(android): align native i18n baseline

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 13:46:05 +01:00
Peter Steinberger
6745f9a553 fix: provider usage accounting, retry/overflow classification, and output clamping (#109796)
* fix(ai): provider usage accounting, retry and overflow classification, output clamping

* ci: refresh pull-request validation

* test(ai): live-probe overflow classification and output clamping
2026-07-17 12:40:01 +01:00
Peter Steinberger
6ac15970a7 feat(onboarding): unified empty-state with provider icons, websites, and recommended installs (#109681)
* feat(onboarding): unify setup recommendations

* fix(control-ui): proxy model setup icons

* fix(onboarding): refresh landing artifacts

* chore(ui): sync translated i18n catalogs

* chore(ui): keep generated locale artifacts on the refresh workflow
2026-07-17 01:01:06 -07:00
ooiuuii
6651813bd0 fix(logging): redact auth-style HTTP headers (#107999)
* fix(logging): redact auth-style HTTP headers

* fix(logging): redact structured auth headers

* test(logging): keep auth fixtures synthetic

* test(logging): preserve existing gateway fixtures

* fix(logging): cover serialized auth credentials

* fix(logging): harden auth header redaction

* fix(logging): cover serialized auth whitespace

* chore(logging): refresh reviewed PR head

* test(logging): expect complete API key redaction

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 00:25:15 -07:00
Peter Steinberger
a2ec3f6904 refactor: separate external conversations from local sessions (#109411)
* feat: separate external conversations from sessions

* test: cover conversation tool authorization

* chore: refresh session schema baseline

* fix: persist effective conversation delivery text

* fix: bind conversation identity to delivery target

* fix: preserve pending conversation deliveries

* fix: make conversation delivery outcomes synchronous

* refactor: make conversation delivery durable

* fix: harden durable conversation retries

* fix: close durable conversation pre-send gaps

* fix: terminally reject invalid conversation deliveries

* refactor: route external conversations through gateway

* fix: namespace conversation delivery queue intents

* refactor: remove obsolete transcript replacement path

* test: prove conversation delivery v10 migration

* test: keep conversation action mock typed

* fix: clear conversation refactor CI gates

* test: align Reef delivery coverage

* chore: refresh Android conversation strings

* fix: harden external conversation state

* fix: close conversation race edges

* fix: preserve conversation delivery identity

* fix: replay durable conversation operations

* fix: unify agent schema at version 11

* chore: move release note context to PR

* fix: make required queue persistence force core delivery

* chore: refresh plugin SDK baseline
2026-07-17 00:09:51 -07:00
Peter Steinberger
b84199644d fix: silent credential-save failures and session/tool hygiene gaps (#109622)
* fix(agents): surface auth persistence failures and harden session, model, and shell tool hygiene

* refactor(agents): keep shell invocation types module-local

* test(agents): derive shell config type locally
2026-07-17 00:02:45 -07:00
Peter Steinberger
0c989568b3 fix: OpenAI-compatible provider compat and error-body surfacing (#109556)
* fix(ai): harden OpenAI-compatible provider compat and error surfacing

* test(ai): add live completions compat coverage

* test(infra): mirror packages live glob in live-config test
2026-07-17 00:02:08 -07:00
Edward Abrams
8fa4867ab4 fix(memory): avoid rebuilding unchanged QMD session exports (#77158)
* perf(memory): cache qmd exports by corpus revision

Co-authored-by: Edward Abrams <zeroaltitude@gmail.com>

* test(memory): track qmd exporter temp dirs

* test(memory): use plugin SDK temp fixture

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 23:22:40 -07:00
Peter Steinberger
03d287d111 fix: Responses streams mishandle interleaved output items and silent truncation (#109615)
* fix(ai): track Responses output items per index and require terminal stream events

* test(ai): add live Responses stream coverage

* test(infra): mirror packages live glob in live-config test
2026-07-16 23:15:35 -07:00
Erick Kinnee
571f1dcef9 fix(dreaming): drop heartbeat assistant responses from dream corpus (#109403)
* fix(dreaming): drop heartbeat assistant responses from dream corpus

The dreaming ingestion pipeline filters heartbeat user messages
(containing [OpenClaw heartbeat poll]) via sanitizeSessionText, but the
paired assistant response is only dropped when it is the exact string
HEARTBEAT_OK. Local models frequently respond with natural-language
acknowledgments (e.g. "Heartbeat received. Main is active.") which pass
through the sanitizer unchanged and enter the dream corpus as
low-confidence (0.58) memory snippets.

Fix: track heartbeat user message drops in buildSessionEntry and skip
the immediately following assistant response. This cross-message coupling
is safe because the heartbeat prompt pattern is injected by the runtime
and cannot be spoofed by user input, unlike [cron:...] or
System (untrusted): ... patterns (see PR #70737).

Refs: #103720

* test(dreaming): add heartbeat assistant response filter test

* fix(dreaming): use provenance-based heartbeat detection instead of text matching

Replace text-based heartbeat detection (isGeneratedHeartbeatPromptMessage)
with provenance-based authentication. The heartbeat turn now carries
provenance: { kind: "heartbeat" } when persisted to the transcript,
and buildSessionEntry checks for this provenance instead of matching
user-spoofable text content.

Changes:
- src/sessions/input-provenance.ts: Add "heartbeat" to
  INPUT_PROVENANCE_KIND_VALUES
- src/auto-reply/reply/get-reply-run.ts: Attach heartbeat provenance
  to user turn input when isHeartbeat is true
- packages/memory-host-sdk/src/host/session-files.ts: Check
  message.provenance.kind === "heartbeat" instead of text matching
- packages/memory-host-sdk/src/host/session-files.test.ts: Update
  heartbeat test to include provenance; add lookalike regression test

This addresses the ClawSweeper review finding [P1] about user-spoofable
text matching. The cross-message coupling is now authenticated by
runtime provenance, not user-typed content.

Refs: #103720

* fix(dreaming): add targeted heartbeat-derived corpus repair

* fix(dreaming): fix TS return type for clearScopedLegacySessionIngestionJson catch

* fix(dreaming): match chunked SQLite seen-state keys by stored scope

* fix(dreaming): repair SQLite-backed session transcript lookup in doctor

The findHeartbeatContaminatedCorpusLines function could not read
SQLite-backed session transcripts. When a corpus ref had no .jsonl
extension (SQLite logical path format), it appended .jsonl, read an
empty file, and silently skipped — leaving pre-fix heartbeat
contamination intact for SQLite users.

Fix:
- Add loadTranscriptLinesFromSqlite helper that reads events via
  the canonical loadTranscriptEventsSync API
- Serialize all events to preserve original event positions for
  corpus #L<n> line-number references
- Fall back to SQLite reader when filesystem read fails on a
  non-.jsonl corpus ref path

Test: add SQLite-backed session regression test that seeds a
session, writes corpus refs without .jsonl extension, and
verifies both audit detection and targeted repair.

* fix(dreaming): address autoreview P1 and P2 for checkpoint clearing and early return

P1: Remove clearScopedSessionIngestionState call after heartbeat line
removal. Clearing the cursor causes the next ingestion to re-process the
transcript from the beginning, duplicating normal corpus lines that were
deliberately retained.

P2: Remove early return after heartbeat cleanup so the self-ingestion
narrative content check and archiveDiary request still run.

* fix(dreaming): resolve corpus ref session path without duplicate agent ID

The session path in corpus refs is already in the format
'sessions/main/abc.jsonl' (includes agent subdirectory). The
previous code prepended source.agentId again, creating a path
like 'agents/main/sessions/main/abc.jsonl' — which silently
returned empty in production workspaces.

Fix: use path.basename to extract just the filename from the
session path, then construct the transcript path correctly.

* refactor(dreaming): split repair utils into separate file to satisfy LOC ratchet

The dreaming-repair.ts file grew from 337 to 831 lines, exceeding the
500-line LOC ratchet limit. Split helper utilities into a new
dreaming-repair-utils.ts file:

- dreaming-repair.ts (365 lines): imports, types, public API functions
  (auditDreamingArtifacts, repairDreamingArtifacts)
- dreaming-repair-utils.ts (498 lines): all helper functions, constants,
  and internal types

* fix(ts): add missing type imports for return types in dreaming-repair.ts

* fix(deadcode): remove unused exports from dreaming-repair-utils.ts

* fix: resolve merge conflict marker in get-reply-run.ts

* fix: remove unnecessary export from INPUT_PROVENANCE_KIND_VALUES

* fix(dreaming): converge targeted repair path with wholesale archive+clear

When heartbeat contamination is found, archive the entire session-corpus directory and clear all SQLite checkpoints instead of doing targeted line-by-line rewrite. This ensures the cleaned corpus gets re-ingested under the new provenance-based forward filter.

* fix(dreaming): authenticate heartbeat transcript turns

Co-authored-by: Erick Kinnee <1707617+ekinnee@users.noreply.github.com>

---------

Co-authored-by: Erick Kinnee <erick@ekinnee.dev>
Co-authored-by: Erick Kinnee <ekinnee@gmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 22:00:21 -07:00
Peter Steinberger
a77c0770ff refactor(speech-core): share TTS request pre-resolution across discord and voice-call (#109640) 2026-07-16 21:47:06 -07:00
ooiuuii
7641aa80c2 fix: plugins update rewrites config for install-record-only updates (#98422)
* Avoid config rewrites for plugin index updates

* Preserve config freshness for records-only plugin updates

* Validate records-only plugin update config

* fix(plugins): reload index-only updates

Co-authored-by: luyifan <al3060388206@gmail.com>

* chore(protocol): refresh generated clients

Co-authored-by: luyifan <al3060388206@gmail.com>

* fix(gateway): wire plugin refresh handler

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 21:38:45 -07:00
Peter Steinberger
a0fac37f14 feat: add OpenAI Video Talk (#109579)
* feat(talk): add OpenAI Video Talk

Co-authored-by: wuxuanshu <1064076525@qq.com>

* fix(protocol): refresh native Talk capability model

* chore(i18n): refresh control UI fallback baseline

* chore(i18n): defer locale refresh to workflow

---------

Co-authored-by: wuxuanshu <1064076525@qq.com>
2026-07-16 21:25:09 -07:00
snowzlmbot
17c2ce05d8 fix(secrets): keep startup alive when TTS SecretRefs are missing (#101265)
* fix(secrets): degrade missing TTS SecretRefs at startup

* test(secrets): keep non-activating startup strict

* test(secrets): mark denied key fixture synthetic

* test(secrets): use synthetic TTS key fixture

* test(secrets): use neutral TTS key placeholder

* test(secrets): isolate TTS key placeholder

* test(secrets): shorten TTS ref fixture name

* test(secrets): normalize synthetic credential fixtures

* test(secrets): isolate optional redaction coverage

* fix(secrets): preserve degraded TTS ref ownership

* refactor(secrets): keep optional resolver internal

* test(secrets): cover default provider alias misses

* test(secrets): pin explicit provider ownership

* style(secrets): format optional assignment imports

* refactor(secrets): keep optional metadata private

* style(secrets): restore collector file header

* fix(secrets): isolate unavailable SecretRef owners

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

* test(secrets): complete provider fixtures

* style(status): avoid degraded path shadowing

* style(secrets): satisfy runtime lint

* refactor(secrets): keep error codes internal

* fix(secrets): keep unowned assignments fail closed

* fix(secrets): preserve provider resolution batching

* fix(secrets): normalize stalled resolution errors

* fix(secrets): reject provider limit violations

---------

Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 21:07:01 -07:00
Patrick Erichsen
55bb6cfa2e feat(control-ui): proxy plugin catalog icons (#109510) 2026-07-16 20:31:27 -07:00
Yuval Dinodia
a06799ab2a fix(acpx): keep leaked non-openai model out of the Codex ACP thinking slot (#95852)
* fix(acpx): keep leaked non-openai model out of the Codex ACP thinking slot

Codex ACP spawn mis-routed an inherited non-OpenAI fleet default into the
reasoning-effort slot and aborted (#95780). Replace the splitter with a closed
classifier and make the spawn path provenance-aware: drop an inherited leaked
default so Codex starts on its own default, but fail closed with
ACP_INVALID_RUNTIME_OPTION when a caller explicitly selects an unsupported or
malformed model. Thread a modelExplicit flag from resolveAcpSpawnRuntimeOptions
through the ACP runtime ensure contract; strip it before the acpx delegate.

Dropping the inherited default only at ensureSession was not enough: the manager
still persisted the leaked model in runtimeOptions, and the first turn replayed
it through applyRuntimeControls -> setConfigOption(model), which the new
fail-closed Codex control path then rejected. ensureSession now reports the
effective model it applied on the returned handle (applied | dropped), and the
manager persists that effective model, so a dropped inherited default is never
saved or replayed as a model control before the first turn. Explicit unsupported
selections still fail closed at spawn and never persist.

* test(acp): split runtime config validation tests

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 20:15:03 -07:00
Peter Steinberger
00a6ecb906 feat(ui): always-on chat title bar with inline rename and workspace actions (#109422)
* feat(gateway): add sessions.files.reveal to open a session workspace on the gateway host

Resolves the session's workspace root server-side (same resolution as
sessions.files.list), refuses exec-node and cloud-worker placements, and
opens the directory with the platform opener. The opener helpers move out
of config.ts into a shared open-path module that config.openFile now uses.

* feat(ui): always-on chat title bar with inline rename and workspace menu

Every chat pane now renders its header: click the session title to rename
it inline (Enter commits via sessions.patch, Escape cancels), a workspace
chip names the session's checkout with reveal/copy-path/copy-branch
actions, and cloud-worker sessions show a globe. The single-pane floating
toggle cluster and the transcript's reserved titlebar drag band fold into
the header, which keeps native macOS window dragging.

* fix(ui): resolve title-bar session aliases and clear the collapsed-nav overlay

Live verification found two gaps: route aliases like ?session=main showed
the generic key-derived title instead of the session's label (resolve via
hello defaults + key equivalence, matching the pane), and the floating
sidebar-expand pill overlapped the header title on plain web while the nav
was collapsed (52px inset, mirroring the native-shell clearances).

* fix(ui): keep the protocol schema layer out of the Control UI startup bundle

The title-bar change made session-row-badges runtime-import the
gateway-protocol barrel for one classifier, dragging typebox and every
schema into startup JS (395 KiB gzip vs the 370 KiB budget). The placement
vocabulary now lives in a dependency-free session-placement-state module:
the schema union derives from it, the barrel re-exports it, and the UI
deep-imports it (startup back to 361.8 KiB).

* fix(gateway-protocol): keep SessionPlacementStateSchema statically typed

Type.Union over a mapped array loses tuple inference and collapses Static
to never; the literal list stays explicit with a compile-time guard tying
it to the shared SESSION_PLACEMENT_STATES vocabulary.

* chore(protocol): regenerate Swift/Kotlin bindings for sessions.files.reveal

* chore: narrow new exports flagged by the deadcode gate

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

The generated-artifact isolation gate (067635cb51) landed mid-flight;
source PRs now carry en.ts only.
2026-07-16 20:04:12 -07:00
Peter Steinberger
6d20432a29 improve: reduce agent startup cost from TTS imports (#109344)
* perf(tts): split lightweight settings imports

* fix(tts): drop redundant internal exports

* fix(tts): remove unused settings type import

* docs(sdk): refresh speech settings API baseline

* fix(tts): align SDK surface gates

* fix(tts): ignore non-object preference roots
2026-07-16 15:50:59 -07:00
Peter Steinberger
0f6ed10e78 docs(errors): explain formatter redaction boundary 2026-07-16 14:59:40 -07:00
Peter Steinberger
093b8859c4 perf(test): fix env-dependent failures, stop verifier lazy-fetch, balance CI stripes (#109332)
* test: fix environment-dependent failures on built and partial-clone checkouts

Canvas A2UI fixtures now pin the resolved root through a new canvas
test-api hook: dev checkouts with a locally built a2ui.bundle.js won
candidate resolution and shadowed the fixture root. Speech-core prefs
tests resolve the canonical tmpdir (macOS /tmp symlink breaks fs-safe
store roots), and the bundled plugin install test asks discovery for
the canonical bundled path instead of hardcoding the source tree.

* fix(release): keep evidence verifier blob reads local-deterministic

git show against a forged or missing SHA lazily fetched from the
promisor remote on partial clones, hanging a security check on network
state (266s observed). GIT_NO_LAZY_FETCH pins verification to local
objects; missing blobs fail closed as before.

* perf(test): pay the command-handler barrel once and merge subagent command tests

commands-name and commands-login imported the full handler barrel
(~1,700 modules) for registration assertions; those now live in a
dedicated registration test, dropping the two files from 12.6s/4.6s to
1.4s/1.0s locally. Five subagent command test files merged into one so
the auto-reply module graph evaluates once instead of five times.

* perf(ci): stripe node test bins by measured file cost

Round-robin striping packed the whale files together, leaving
auto-reply-commands-1 at ~220s while sibling stripes idled at ~30s.
Greedy LPT over advisory per-file seconds hints balances the commands,
cli-runner, and tooling stripes deterministically; group hints for the
restriped bins are equalized at the old totals.
2026-07-16 13:38:56 -07:00
Peter Steinberger
a9f82837a1 feat: inspect background tasks across web and mobile (#109150)
* feat: add background task details across clients

* fix: refresh background task clients and translations

* fix: keep background task details fresh

* fix: ignore deleted background task details

* refactor: split background task rendering

* fix: use canonical background task ids

* refactor: extract background task view types

* fix(apps): regenerate task localizations

* fix(ios): remove unused task screen import

* fix(apps): refresh task localization inventory
2026-07-16 13:08:42 -07:00
thomas.szbay
b06fe2a673 fix(kill-tree): verify process group leader before using group kill to prevent gateway SIGTERM (#76259) (#94697)
* fix(kill-tree): verify process group leader before group kill to prevent gateway SIGTERM (#76259)

- Add isProcessGroupLeader() to killProcessTree/signalProcessTree: ps -p <pid> -o pgid= primary check with /proc/<pid>/stat fallback on Linux. Group kill only when the PID is its own process group leader; non-leaders fall back to single-pid kill, preventing accidental gateway SIGTERM when a non-detached child shares the gateway's process group.
- Propagate detached: true to all detached-spawn cleanup callers (exec-termination, agent-bundle LSP, mcp-stdio, bash, supervisor pty, agent-core nodejs) so detached group cleanup survives leader exit.
- Gateway/daemon cleanup paths (schtasks, restart-health) keep the leader-checked default (detached omitted).

Closes #76259

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

* refactor(process): tighten process-group ownership checks

* refactor(daemon): split restart diagnostics

* refactor(daemon): isolate restart health types

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 12:30:51 -07:00
DaigoSoup
fa08ab28ca fix(telegram): preserve word boundaries in proactive sends (#108801)
* fix(telegram): preserve proactive message word boundaries

* fix(markdown): retain whitespace across rendered chunks

* fix(telegram): preserve links in plain fallbacks

* fix(channels): preserve chunk boundary semantics

* test(sms): verify lossless chunk whitespace

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 11:18:17 -07:00
Peter Steinberger
cb84dc76fc feat(control-ui): approval attention chip + approval history page (#108776)
Adds the sidebar approval attention chip and a dedicated approval history
page backed by the new approval.history gateway RPC (30-day retention
window). Extracts buildSidebarAttentionItems into its own module so the Lit
component consumes it as a real cross-module dependency, and wires the strict
i18n catalog for the new strings (fallbacks=0).
2026-07-16 10:32:05 -07:00
Peter Steinberger
20d748a4f0 feat(agents): agent-owned gateway terminals with operator co-attach 2026-07-16 09:12:50 -07:00
Paul Pitchford
efa8075c68 fix: external plugin tabs fail under gateway auth (#107323)
* fix: load plugin tabs with gateway auth

* fix: harden plugin tab cookie signature compare

* fix(gateway): authenticate external plugin tabs

Co-authored-by: Paul Pitchford <paul@paulpitchford.co.uk>

* refactor(gateway): simplify plugin frame auth proof

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 07:26:00 -07:00
Peter Steinberger
cf029ea29e feat(agents): screen tool drives Control UI layout 2026-07-16 05:43:02 -07:00
Peter Steinberger
68694599af fix(exec): resolve no-route approvals immediately (#108935)
Fixes #104413. Supersedes the implementation direction in #104923 after preserving its contributor work and extending route detection across approval clients.

Co-authored-by: RickLin <83101411+ObliviateRickLin@users.noreply.github.com>
2026-07-16 04:26:38 -07:00
Peter Steinberger
a719a851bb refactor(gateway-client): centralize challenge timeout resolution (#108932) 2026-07-16 04:19:54 -07:00
Peter Steinberger
0d31fbf5f0 fix(skills): canonical frontmatter parser + per-file diagnostics (#108926)
* fix(skills): load JSON5-style metadata frontmatter

* fix(skills): diagnose invalid frontmatter

* test(skills): adapt session loader coverage

* ci: refresh merge ref

---------

Co-authored-by: jincheng-xydt <xu.jincheng@xydigit.com>
2026-07-16 04:18:06 -07:00
Peter Steinberger
d5eebf02e2 fix(workboard): record resolved runtime metadata instead of hardcoded codex engine (#108887)
* fix(workboard): record resolved runtime metadata instead of hardcoded codex engine

Workboard executions labeled every dispatched run engine=codex, model=default,
and id suffix :codex even for Claude/other harness agents. The gateway agent
admission phase now returns the resolved {harness, provider, model} for plugin
subagent runs; the dispatcher records it verbatim and omits engine/model when
unresolved. Engine becomes an open runtime identifier in the workboard
contract (built-in launch choices stay a closed list), store/UI normalizers
preserve historical labels as written instead of inventing codex, and new
execution ids use an :agent-session suffix. Fixes #108362

* fix(workboard): accept undefined engine in ui engineModel helper
2026-07-16 04:10:27 -07:00
Wynne668
b7e099d36e fix(gateway): agent model overrides cannot be cleared (#108734)
* fix(gateway): allow clearing agent model overrides

* fix(protocol): preserve Swift agent model compatibility

* fix(protocol): preserve null when Swift decodes agent updates

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:46:37 -07:00
NIO
dacf164793 fix(gateway-client): bound websocket opening handshake waits (#108348)
* fix(gateway-client): bound websocket opening handshake waits

* test(gateway-client): harden handshake timeout proof

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:36:17 -07:00
wangmiao0668000666
8090cb1c64 fix(discord): honor abortSignal during gateway READY retry backoff (#108561)
* fix(discord): honor abortSignal during gateway READY retry backoff

* fix(discord): avoid __testing alias to satisfy Knip production scan

* test(discord): make READY abort proof deterministic

Co-authored-by: wangmiao0668000666 <wang.miao86@xydigit.com>

* fix(retry): support unref abort sleeps

Co-authored-by: wangmiao0668000666 <wang.miao86@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:14:46 -07:00
zhanxingxin1998
4bc84db398 fix(cron): allow clearing failure alert routing fields (#108578)
* fix(cron): clear failure alert routing fields

Send explicit nulls for cleared Control UI failure-alert overrides and accept those clears only in cron update patches.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test(cron): satisfy serialized alert patch types

Narrow the serialized failure-alert fixture before asserting its cleared fields.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cron): clear failure alert overrides

Co-authored-by: 詹幸心0668001037 <zhan.xingxin@xydigit.com>

---------

Co-authored-by: OpenAI Codex <noreply@openai.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 02:52:19 -07:00
Peter Steinberger
30ae21fca7 fix: prevent SQLite lock stalls and schema drift (#108663)
* fix: harden SQLite state storage

* build: allow strict SQLite migration SQL

* test: align SQLite and model-default assertions
2026-07-16 01:45:06 -07:00
Peter Steinberger
5a4b48ead6 refactor(ai): centralize tool image payload guard (#108775) 2026-07-16 01:44:37 -07:00
Peter Steinberger
dde90a345a refactor(plugin-sdk): narrow wildcard barrels to explicit used exports (#108440)
* refactor(plugin-sdk): narrow wildcard barrels to explicit used exports

* refactor(tools): delete dead tool-planning module exposed by barrel narrowing

* fix(plugin-sdk): restore deprecation tag on OpenClawSchemaType alias

* test(agents): drop test for deleted runtime proxy module

* refactor(tools): trim descriptor types to cache consumers

* refactor(deadcode): harvest exports orphaned by barrel narrowing

* refactor(deadcode): harvest exports orphaned by barrel narrowing (rest)

* fix(agents): restore sdk imports and test markers via public predicate

* fix(plugin-sdk): named type re-exports in plugin-entry; trim types barrel precisely

* chore(plugin-sdk): account unmasked deprecated provider types in budgets

* fix(plugins): name star-only type rows for dts bundling

* fix(plugins): restore host-hook surface; unexport internal api compositions

* fix(plugins): named type imports for api composition; restore needed source exports

* fix(plugins): knip-visible type imports for registry surfaces

* test: adapt tests to privatized media and command internals

* fix(qa-lab): re-export snapshot conversation type

* style: format sessions sdk imports

* fix(plugins): restore smoke entry export; pin budgets to exact actuals

* fix(plugins): canonical smoke-entry import; drop orphaned root shims

* fix(plugins): allowlist manifest probe, repoint qa web import, drop dead browser barrels

* fix(plugin-sdk): pin codex auth marker and scaffold provider type

* fix(qa-lab): keep web-facing model-selection shim within boundary rules

* fix(plugin-sdk): preserve merged contracts through narrowed barrels

* chore(plugin-sdk): pin post-rebase surface budgets
2026-07-16 00:45:23 -07:00
Peter Steinberger
73ada8fd4c fix(ai): preserve tool-result text for payload-less media (#108697)
* fix(ai): require payload bytes for tool media

Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>

Co-authored-by: 0668000539 <shu.zongyu@xydigit.com>

* chore: keep release notes out of PR

---------

Co-authored-by: 0668000539 <shu.zongyu@xydigit.com>
2026-07-16 00:42:36 -07:00