Commit Graph

78866 Commits

Author SHA1 Message Date
Peter Steinberger ccc1920068 improve(telegram): cut cold channel setup import latency (#122955)
* perf(telegram): keep setup entry on light graph

* fix(plugin-sdk): complete private UI hint boundaries
2026-08-13 01:55:47 -07:00
Peter Steinberger 7235943790 fix(release): align survivor session metadata assertion (#123068)
* fix(release): align survivor session metadata assertion

* test(release): cover SQLite survivor metadata
2026-08-13 01:41:53 -07:00
Peter Steinberger 1c5fc517db fix(ui): deduplicate projects in the What picker (#123072) 2026-08-13 01:40:57 -07:00
Peter Steinberger e3b27fec64 test: trim prepared reply import graph (#123061)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-13 01:32:13 -07:00
Peter Steinberger 792b2054df refactor(agents): move recovery tests to owners (#123022)
* test(agents): move recovery tests to owners

* test(discord): split send coverage by surface

* test(discord): share send mock lifecycle

* test(discord): isolate draft timer coverage
2026-08-13 01:29:05 -07:00
Vincent Koc 4c60b3b985 fix(plugins): preserve bundled install ownership (#123063)
Punchcard-Session: ember-meadow-river-68
2026-08-13 16:22:31 +08:00
Peter Steinberger 3b6e54041f ci: replace dependency sticky disk with exact cache (#123040)
Amp-Thread-ID: https://ampcode.com/threads/T-019ff3db-c467-70ad-8ed3-81f2ba94b0c0

Co-authored-by: Amp <amp@ampcode.com>
2026-08-13 01:13:25 -07:00
Peter Steinberger b54034d5c2 fix: isolated gateways list and open the operator's HOME Claude/Codex/OpenCode/Pi sessions (#122983)
* fix(sessions): isolated gateways no longer inherit HOME external session catalogs

A gateway on isolated state (custom OPENCLAW_STATE_DIR/CONFIG_PATH/OPENCLAW_HOME,
relocated home, or any named profile) listed, read, continued, archived, and
reopened the operator's real Claude Code/Codex/OpenCode/Pi sessions from the
process HOME. External catalogs now require the default install identity for
process-HOME scans: every catalog verb receives the isolation policy and rejects
HOME-fallback local targets, unknown providers fail closed unless they declare
supportsProcessHomeIsolation, and one structured warning records the skip.
Paired-node hosts and explicitly rooted stores (CLAUDE_CONFIG_DIR, CODEX_HOME,
OPENCODE_DB, Pi session dirs) keep working; default-identity gateways are
unchanged.

* fix(sessions): inject catalog HOME-isolation fact at registry construction

* chore(sdk): regenerate plugin API baselines after rebase

* chore(sdk): regenerate plugin API baselines after rebase
2026-08-13 01:12:03 -07:00
Peter Steinberger 683d37a35f test(telegram): align ingress fixtures with Bot API (#123059) 2026-08-13 00:58:17 -07:00
Peter Steinberger cc2fc55f9b feat: portals — expose agent-run dev servers to the operator (#122536)
* feat(protocol): add portal methods and event

Bump the reviewed protocol owner-module count from 55 to 56.

* feat(gateway): add portal service and reverse proxy

* feat(agents): add portal tool

* fix(gateway): refine portal URL and proxy auth

* refactor(gateway): keep portal helper types private

* fix(gateway): declare portal transport service

* test(gateway): satisfy portal proxy lint

* test(gateway): narrow websocket payload types

* refactor(protocol): compact portal schema exports

* fix(gateway): export portal protocol types

* feat(ui): add portals page

* docs(gateway): add portals guide

* fix(gateway): dial portal targets via localhost dual-stack

Vite and other Node >=17 dev servers bind ::1 only for localhost, so a
fixed 127.0.0.1 dial 502s on the default path. Use hostname localhost
with family autoselection and rewrite Host to match.

* fix(gateway): type portal dual-stack connection

* fix: satisfy portal integration gates

* fix(gateway): isolate portal cookie jars per target

Cookies are hostname-scoped, not port-scoped, so the per-port origin
split alone let Gateway plugin-auth cookies reach agent-run targets.
Forward only cookies carrying this portal's own name prefix (stripped),
rewrite target Set-Cookie names to the prefixed form incl. the WS 101
handshake, and drop Domain attributes.

* fix(ui): detect unreachable portals behind proxied gateways

Probe the portal origin from the browser (no-cors, 4s timeout) and show
a recovery notice with the gateway-host URL instead of a dead iframe
when only the gateway port is exposed (Serve/Funnel/reverse proxy).
Docs: cookie isolation + reachability; zh-CN glossary entry.

* test(ui): satisfy portal reachability lint

* test(gateway): provide control UI request hosts

* chore(protocol): regenerate after rebase

* fix(gateway): namespace portal auth cookies by listener

* fix(gateway): scope portal token URLs to write-capable clients

The portal bearer token rides in the summary url/tokenQuery; portal.list
is operator.read and portal.changed fans out to read subscribers, so a
read-only client could harvest an openable URL. Make those fields
optional, redact them from read-scope list responses, and drop them from
every portal.changed broadcast; write/admin clients still receive them
and the UI refetches the list on change.

* docs(web): list the portals route

* fix(gateway): type portal open credentials

* docs(gateway): clarify portals PORT/PUBLIC_URL are agent-set

Opening a portal creates only the proxy listener; the agent sets PORT
and PUBLIC_URL in its own exec command, matching the portal tool
contract. Removes the implication of an automatic env handoff.

* chore(protocol): regenerate portal models

* style(gateway): format portal method-order assertions

Rebase union-merge left the portal.list assertion wrapped; oxfmt fits it
on one line.

* chore(plugin-sdk): refresh API baseline after rebase

* chore(plugin-sdk): refresh API baseline after rebase

* chore(protocol): refresh portal event order after rebase

* chore(plugin-sdk): refresh API baseline after rebase

* fix(gateway): pin portal referrer policy to no-referrer

The portal URL carries its bearer token in the query, and upstream
response headers are copied verbatim, so a target answering with
Referrer-Policy: unsafe-url could leak that URL to every third-party
origin it references. Force no-referrer after the copy and drop any
inbound Referer that still carries the token before forwarding.
2026-08-13 00:46:11 -07:00
Dallin Romney 4afccbdaa4 fix(sessions): exclude protected sessions from entry cap (#123014) 2026-08-13 15:42:55 +08:00
Peter Steinberger fce5b6688a refactor(tooling): enforce zero wrapper and export debt (#123020) 2026-08-13 00:40:32 -07:00
Vincent Koc 732b3da091 fix(sqlite): preserve Windows private-directory diagnostics (#123023) 2026-08-13 15:34:12 +08:00
Peter Steinberger dbe4ce9f33 fix(telegram): prevent multi-agent cache ownership startup failures (#123029)
* fix(telegram): scope runtime caches by account owner

* test(telegram): type partial owner runtime stub

* refactor(telegram): remove obsolete default owner seam

* fix(telegram): tolerate partial durable updates

* test(telegram): request raw progress detail explicitly
2026-08-13 00:33:38 -07:00
Vincent Koc 6966301523 fix(plugins): restore runtime child policy on reinstall (#123043) 2026-08-13 15:31:02 +08:00
Dallin Romney 1d45930162 chore(cua-computer): upgrade CUA Driver to 0.19.3 (#122191)
* chore(cua-computer): upgrade CUA Driver to 0.19.3

* test(cua-computer): verify CUA Driver enum contract
2026-08-13 15:19:35 +08:00
Jesse Merhi 7eaf2fccf7 fix(plugins): preserve lightweight runtime scope imports 2026-08-13 17:03:19 +10:00
Jesse Merhi a646df9275 test(perf): align resolver contracts 2026-08-13 17:03:19 +10:00
Jesse Merhi a7a0399fea fix(gateway): keep lifecycle thinking active-only 2026-08-13 17:03:19 +10:00
Jesse Merhi 02272c345f fix(perf): close prepared runtime regressions 2026-08-13 17:03:19 +10:00
Jesse Merhi b9f2eba177 fix(perf): reuse prepared plugin generations 2026-08-13 17:03:19 +10:00
Jesse Merhi b2e023adc6 test(perf): benchmark gateway plugin snapshot load 2026-08-13 17:03:19 +10:00
SunnyShu 66e83a17e6 fix(sessions): distinguish transient lookup failures from policy denials (#117305)
* fix(sessions): distinguish transient lookup failures from policy denials

Make spawned-session ownership lookup failures observable and
distinguishable from genuine tree-visibility policy denials, with
retryability classification so permanent credential/configuration
failures are not mis-framed as transient. Addresses issue #114653.

Diagnostic layer only — does not add retry (maintainer product decision)
and does not address the recency-window denial path (#114180).

Core changes:
- session-visibility-internal: add a core-private three-state lookup result
  (ok / failed with retryable flag) plus classifyLookupRetryable (transport
  closes/timeouts and retryable request errors => retryable; credential/auth/
  unknown => non-retryable) and a shared lookupFailedDenialSuffix.
- session-visibility guard: pick the denial text by retryability so transient
  failures say "retry" and permanent failures say "check gateway configuration
  and credentials"; both still fail closed. Preserves the shipped public
  SessionAccessResult, Set<string> checker input, and test-hook contracts.
- sessions-resolution sandbox resolver: propagate the same retryability-
  classified denial; pass allowMissing: true on the speculative
  sessions.resolve probe and suppress the warn for the expected "No session
  found" miss so ordinary non-owned targets do not log as operational lookup
  failures (reuses callGatewayResolveSession for older-gateway compatibility).
- Tests: transient + permanent error coverage for both guard and sandbox
  resolver paths; classification contract locks; non-owned-miss quietness
  regression; redaction through formatErrorMessage.

* fix(lint): remove unnecessary Boolean() conversion in sessions-resolution

oxlint typescript(no-unnecessary-type-conversion) flagged the redundant
Boolean() wrapper around String.includes() which already returns boolean.
Use ?? false to preserve the undefined->false semantics from the optional
chain.

* fix(sessions): keep unknown lookup failures generic

* fix(sessions): narrow ownership lookup diagnostics

* test(sessions): format visibility coverage

* fix(sessions): preserve cross-agent denials on lookup failure

A failed spawned-session ownership lookup override was relabeling the row
checker's deterministic cross-agent policy denial as a retryable lookup
failure. Retrying the spawned ownership lookup cannot make a known
agent:other:* target eligible, so the cross-visibility refusal must be
preserved as-is.

Constrain the lookup-failure override to same-agent targets by mirroring
the row checker's agent resolution: when the target resolves to a
different agent than the requester, keep the original cross-agent denial
rather than overriding it. Add regression coverage for the cross-agent
case under a failed tree-visibility lookup.

ClawSweeper review P2: preserve cross-agent policy denials on lookup
failure.

* fix(lint): avoid implicit boolean coercion in cross-agent check

Replace the `!!id` coercions in `isCrossAgentTarget` with an explicit
empty-check so the return value reads as a plain inequality. The
`no-implicit-coercion` lint rule flags `!!` on already-resolved strings;
both ids are guaranteed non-empty by the resolve-or-return-false guards
above, so the explicit form is equivalent.

* fix(sessions): preserve lookup failures for owned children

* fix(sessions): preserve ownership lookup failures

* fix(sessions): carry ownership proof through tool access

* fix(plugin-sdk): remove stale visibility imports

* fix(sessions): preserve legacy ownership fallback

* fix(sessions): block incognito status access

* fix(sessions): preserve deterministic policy denials

* fix(sessions): block incognito semantic-current status

* test(channels): isolate env preflight contracts

* test(sessions): align ownership checks with access owner

* style(sessions): format rebased access paths

* fix(sessions): require resolved owners at access checks

* test(gateway): supply explicit session owners

* test(sessions): model expected key misses precisely

* fix(sessions): scope delegated access to target owner

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-08-13 15:03:09 +08:00
Ayaan Zaidi 0b9842d138 fix(agent): finish turns when providers fail after tools complete (#123005)
Safely finalize settled Codex turns when an overload arrives after tool completion. Keep other provider failures fail-closed and preserve channel delivery.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-13 12:17:28 +05:30
Vincent Koc 7812d1540e fix(config): repair legacy multi-agent roster upgrades (#123027) 2026-08-13 14:45:58 +08:00
Jason (Json) ad4856c51c fix: prevent bundled plugin startup convergence loops (#122871)
* fix: stop bundled plugin startup refresh loops

* feat: continue web sessions in the terminal (#122870)

* feat: continue sessions in terminal

Add a credential-free Control UI continuation command and allow openclaw resume to reuse current-profile authentication only for byte-exact configured Gateway targets.

* fix(gateway): separate public origin TLS ownership

Allow exact public-origin resume targets to reuse local authentication without inheriting the direct local listener certificate fingerprint.

* fix(gateway): scope exact targets to gateway mode

Prevent remote profiles from reusing dormant local Gateway authentication for explicit loopback or public-origin targets.

* fix(cli): encode terminal resume handoffs

Replace shell-specific quoting with a strict credential-free base64url handoff, gate configured auth reuse to validated handoffs, and skip unused session discovery.

* fix(gateway): isolate handoff auth identity

Suppress ambient Gateway auth fallback for validated handoffs while preserving explicit credentials, configured SecretRefs, stored device auth, and exact-target TLS ownership.

* fix(cli): harden terminal resume handoffs

* fix(cli): parse terminal handoff outcomes

* fix(cli): bind handoffs to resolved agent

* test(ui): align terminal continuation proof

* docs(plan): track terminal continuation

* refactor(ui): keep terminal handoff result local

* fix(ui): keep composer capability menus within the viewport (#122296)

* fix(ui): constrain composer capability menus

* fix(ui): cap composer capability menu height

* test(ui): cover long capability menu states

* test(ui): capture capability menu interaction states

* fix(ui): keep dark capability states legible

* test(cron): focus runtime config composition (#122867)

Co-authored-by: Amp <amp@ampcode.com>

* feat(cli): allow editing automation display names (#122702)

* feat(cli): allow editing automation display names

* feat(cli): allow clearing automation display names

* fix(ui): show progress during new session startup (#122713)

* fix(ui): show progress during new session startup

Refs #122703

* oc-1fa: keep new-session progress through handoff

* fix(ui): keep new-session handoff live

* fix(ui): preserve navigation callback contract

* fix: make live updater checkout portable (oc-237) (#122873)

* refactor(media): remove orphan generation facades (#122874)

* refactor(agents): split subagent-control.ts into owner modules (#122875)

* fix(ui): archived sessions leave sidebar after navigation (#122876)

* oc-ad0.1: fix archived child session retention

* oc-37c: evict archived child on navigation

* fix(ci): expose AI pack diagnostics (#122786)

* fix(recovery): reclaim proven-stale reply-only ownership with zero queued backlog (#122265)

* fix(recovery): reclaim proven-stale reply-only ownership with zero queued backlog

Stuck-session recovery kept reply-only ownership forever when the queued
backlog was empty: isActiveRunProgressStale short-circuits to false at
queueDepth 0, so stale active_reply_work was never reclaimed even after
the durable session became killed. Evaluate staleness for reply-only
ownership without the queue gate (the gate stays for run-handle paths),
so proven-stale reply work expires through the existing abort-and-drain
owner path while global-lane and deferred-maintenance exemptions and
live reply work with recent progress are preserved.

Closes #122227

* fix(recovery): keep maintenance phases out of zero-backlog stale reclaim

The zero-backlog reclaim path (requireQueueBacklog: false) applied to
every reply-only operation, including preflight_compacting and
memory_flushing. Those phases are explicitly recognized as compaction
and may honor a configured timeout above the stale threshold, so a valid
long-running maintenance operation could be force-cleared early.

Restore the queue-backlog guard for the maintenance phases so an
unqueued compaction or memory flush is never reclaimed by this path;
ordinary reply-only ownership keeps the zero-backlog expiry. Adds
regressions for both maintenance phases.

* fix(ci): ignore zombie-only Vitest process groups (#122759)

* test(agents): scope extension fixtures to explicit owners (#122883)

* ci: fingerprint preferred pnpm hooks (#122852)

Co-authored-by: Amp <amp@ampcode.com>

* fix(ci): record startup JS growth in the Control UI budget baseline

Startup JS gzip reached 329483 B on main (build-artifacts, af49764206),
1198 B over the 328285 B baseline + 1024 B tolerance, after cumulative
chat/session UI growth landed in #122296, #122713, #122870, and #122876.
Record the CI-measured bytes (within the 4096 B ratchet) to restore green
build-artifacts and QA Smoke lanes.

* fix(codex): keep sessionless mirror warnings out of onboarding (#122831)

* fix(codex): skip mirrors for sessionless runs

* fix(codex): restore openai model provider on media understanding turns

PR #122163 made thread/start modelProvider caller-supplied and updated the
web-search caller but missed media understanding, breaking its tests on main
full runs (cross-lane gap). Pass the provider explicitly and export the
retire binding prod now touches from the shared-client test mock.

* test(codex): align prompt assertions with reworded guidance

PR #121522 reworded the Skill Workshop guidance and cd7b7f639d reworded
the message-tool final-reply text; both updated core tests but missed
these codex mirror assertions (cross-lane gap breaking main full runs).

* test(codex): scope agent-projection fixture session to its agent

PR #114388 made multi-agent session ownership explicit; the atlas-scoped
projection test still used the shared main-scoped session key and now
trips AgentSelectionRequiredError (fourth cross-lane escape on main).

* fix(telegram): prevent multi-agent startup migration false positives (#122877)

* fix(telegram): resolve legacy state owners explicitly

* docs(changelog): note Telegram migration ownership fix

* Revert "docs(changelog): note Telegram migration ownership fix"

This reverts commit e02962eb4b2e2475854adf8c2a2915bcfd1cf65a.

* fix(reef): redact relay errors containing credentials (#119603)

* feat: let limited browsers request admin access (#121459)

* feat(gateway): add live device scope upgrades

* feat(ui): add limited-access upgrade flow

* fix(protocol): refresh Swift scope upgrade models

* perf(ui): lazy-load device scope upgrades

* fix(ci): complete scope upgrade generated surfaces

* perf(ui): lazy-load GitHub link hovercards

* fix(ui): keep admin repair guidance focusable

* fix(ui): gate and refresh scope upgrade banner

* refactor(ui): keep gateway client within line budget

* fix(ci): align rebased scope upgrade checks

* fix(ui): resolve scope upgrade in browser tests

* fix(gateway): honor refreshed scope upgrade deadline

* fix(gateway): honor refreshed scope upgrade deadline

* fix(gateway): coalesce scope upgrade waiters

* fix(ui): gate scope upgrade actions

* chore(plugin-sdk): refresh rebased API baseline

* fix(scope-upgrade): return canonical request ids

* fix(ui): preserve gateway event type binding

* fix(protocol): generate scope upgrade result models

* fix(ui): preserve scope upgrade recovery guidance

* chore(plugin-sdk): refresh rebased API baseline

* test(ui): avoid scope upgrade navigation race

* docs(control-ui): clarify scope upgrade approver

* test(gateway): align appended method counts

* chore(plugin-sdk): refresh rebased API baseline

* refactor(ui): keep place picker within line budget

* chore(plugin-sdk): refresh rebased API baseline

* chore(plugin-sdk): refresh rebased API baseline

* chore(plugin-sdk): refresh rebased API baseline

* chore(plugin-sdk): refresh rebased API baseline

* chore(plugin-sdk): refresh rebased API baseline

* chore(plugin-sdk): refresh rebased API baseline

* chore(plugin-sdk): refresh rebased API baseline

* chore(plugin-sdk): refresh rebased API baseline

* chore(plugin-sdk): refresh rebased API baseline

* chore(plugin-sdk): refresh rebased API baseline

* chore(plugin-sdk): refresh rebased API baseline

* fix(gateway): preserve scope-upgrade browser origin

* fix(matrix): retain previews when replacement delivery fails

* test(matrix): tighten replacement proof

* test(matrix): bind live replacement marker

* test(matrix): type redaction ledger

* test(matrix): observe nonvisible cleanup

* fix(matrix): retain visible drafts on handler abort

* test(commands): stub plugin metadata snapshot in onboard-inference test (#122901)

The configured-model case lacked a current plugin metadata snapshot, so model normalization cold-discovered every bundled manifest; the prepared empty snapshot keeps the test on its intended boundary and reduced Vitest file wall time from 26.72s to 2.57s (the shell measurements were 194.45s and 56.21s including unrelated lock queues).

* docs(skills): document session and transcript fetching in openclaw-debugging (#122904)

Adds a Fetching Sessions and Transcripts section: sessions CLI first, then
the per-agent SQLite data plane (session_nodes lookup from chat URL
fragments, transcript_events shape, __openclaw sender provenance,
session_transcript_fts, media://inbound mapping) and a dependency-free
node:sqlite read-only recipe for hosts without sqlite3. Read-only-against-
live-gateway rule stated inline.

* fix: preserve compaction history when final audit fails

* fix: redact compaction rejection diagnostics

* fix: redact compaction retry errors

* fix: isolate compaction structure audit

* fix(ui): preserve picked image previews (#122905)

Fall back to stored attachment data URLs when object URL previews are unavailable in the shared composer surface.

* fix(zalo): keep packaged setup wizard loadable (#122902)

* fix(zalo): package setup runtime surface

* fix(tooling): track setup surface artifacts

* fix(ci): run affected extension suites when changed-test planning falls back (#122885)

The PR-changed test planner fails safe to the compact full-suite plan for any diff touching packages/**, but that compact plan excludes all extension test configs, so mixed package+extension PRs landed with zero extension test execution (escapes: PR #120534 breaking extensions/codex run-attempt.native-hook-relay.test.ts, PRs #122163/#121522 and cd7b7f639d breaking media-understanding-provider.test.ts and thread-lifecycle.test.ts on main full runs). The preflight now appends whole-config shards for the diff's touched extensions whenever the precise plan fails safe; whole configs (not precise targets) because the fail-safe cause leaves the non-extension diff's extension impact unbounded.

* fix(gateway): resolve agent list model identity (#122907)

Publish canonical resolved primary models with matching runtime and thinking metadata in agents.list.

* test(microsoft-foundry): remove global test bridge (#122881)

* test(microsoft-foundry): remove global test bridge

* test(microsoft-foundry): type boundary fixtures

* perf(ui): keep route transition out of startup

* fix(e2e): verify suspend control over WebSocket (#122888)

* fix(slack): prevent duplicate Socket Mode connections after reconnect errors (#122624)

* fix(codex): read canonical transcript session targets (#1)

* test(slack): reproduce reconnect timer surviving shutdown

* fix(slack): keep reconnects within one socket lifecycle

* test(slack): exercise native reconnect over loopback

* test(slack): satisfy reconnect integration checks

* fix(msteams): honor inbound channel media limit (#122315)

* fix(msteams): honor inbound channel media limit

* test(msteams): update lifecycle runtime mock

* style(msteams): avoid resolver config shadowing

* style(msteams): format lifecycle resolver mock

* refactor(msteams): inline media fallback

---------

Co-authored-by: DanielCardenas <djerez@lean-tech.io>
Co-authored-by: Jason (Json) <263060202+fuller-stack-dev@users.noreply.github.com>

* improve: speed up CLI spawn tests (#122891)

* test(agents): trim cli spawn test imports

* test(agents): distinguish prerelease policies

---------

Co-authored-by: Amp <amp@ampcode.com>

* fix(plugins): repair status and CLI fixtures (#122925)

* fix: internal recovery prompts appear as operator-authored messages (#122908)

* fix(agents): hide recovery prompts from transcripts

Suppress settled-turn finalization and reasoning/empty-response control prompts at the session writer boundary.

* test(agents): align hidden recovery prompt expectations

* fix(ci): rotate stale dependency snapshot (#122921)

Co-authored-by: Amp <amp@ampcode.com>

* docs(gateway): clarify dynamic operator scopes (#122931)

* fix: code mode dead-ends on oversized tool results instead of returning bounded output (#122924)

* fix(agents): bound code mode bridge results

Return oversized bridge, guest output, and final values as bounded successful projections with actionable narrowing guidance.

* refactor(agents): absorb code mode output bounds

* fix(ci): prevent channel add command test timeout (#122879)

* test(channels): isolate add env setup contracts

* test(channels): cover adapter env setup

* fix(parallels): preserve plugin inventory during updates (#122912)

* fix(parallels): preserve plugin inventory during updates

* fix(parallels): preserve dev update plugin inventory

* fix(ui): contain OAuth wizard modal content (#122892)

* fix(ui): contain OAuth wizard modal content

* test(ui): poll OAuth modal containment

* refactor(ai): internalize ChatGPT SSE protocol (#122930)

* feat(ui): show useful environment facts in the picker (#122923)

* feat(ui): show environment facts in Where picker

Preserve environment platform, trust, session-host, and capability metadata through new-session discovery while keeping placement availability tied to live executable nodes. Render bounded quiet device/cloud facts and add mocked browser coverage for task #33.

* docs(plan): track picker environment facts

* refactor(ui): split place browser rendering

* docs(agents): require screenshot/video proof for UI-visible and gateway-behavior changes (#122920)

Adds hard policy: UI-visible changes need before/after screenshots or a
short video as PR evidence; gateway-behavior changes provable in the
Control UI need an isolated dev-gateway live run with a recorded video.
Documents the verified video upload flow (user-attachments endpoint,
mp4/webm both served) and the bare-URL embed rule for GitHub's player.

* fix(tools): preserve partial web fetch status (#122866)

* fix(ui): deliver failed steer retries as a new turn when the session is idle (#122919)

A steer rejected on the run/leaf fence parks as a failed steered queue row.
Retry previously refused whenever the target run was gone, leaving the
user's message permanently stuck with 'that run is no longer active'.
Retry now converts the parked row into a plain queued send when the session
is idle, so the text delivers as a fresh turn; active-run retries keep the
original steer binding, and disconnected retries keep the existing error.

* fix: stopping a session leaves subagents running with no stop control (#122909)

* fix(gateway): cascade session stop to subagents

Cascade exact and session-wide aborts through the subagent registry and keep Control UI Stop visible while descendants remain active.

* refactor(gateway): absorb stop cascade orchestration

* chore(gateway): refresh plugin SDK API contract for abort refactor

Regenerates the export-closure contract after the stop-cascade refactor
moved gateway abort orchestration exports, and drops a redundant Boolean()
wrapper flagged by lint. Public SDK surface gate is unchanged.

* chore(gateway): regenerate plugin SDK API baseline

* fix(qa): preserve Code Mode reads in model-switch mock (#122935)

* fix(ci): prevent flaky extension wrapper SIGTERM test (#122917)

* test(scripts): wait for valid wrapper pids

* test(scripts): harden PID marker reads

* fix: session model selection replaced by response aliases and fallback wins (#122910)

* fix(agents): keep session model selection canonical

Preserve configured session model identity across response aliases and turn-local fallbacks.

* fix(gateway): align session model projection consumers

* test(gateway): mark session event model selection

* test(gateway): stabilize sender avatar fixture (#122942)

* perf(test): cut workflow guard import overhead (#122940)

Co-authored-by: Amp <amp@ampcode.com>

* test(extensions): remove duplicate runtime replays (#122949)

* fix(ui): fence stale recovery scope work (#122944)

* docs(deploy): add verification, cost, observability, and troubleshooting to the Cloudflare guide (#122932)

The template shipped without the operator-facing half: no way to prove the
restore path works before depending on it, no cost signal for the always-on
versus webhook-only choice, no log surfaces, and no failure-mode index.

Adds an architecture diagram, a restore rehearsal, measured recovery numbers
from the real-R2 proof, provisioned-resource cost guidance, wrangler tail
observability, and a troubleshooting index covering image architecture,
Litestream S3 credentials, the startupz/readyz split, and ephemeral-disk
config loss.

* fix: prompt caching breaks on Claude Opus 5 and Sonnet 5 (#121283)

* fix: prompt caching breaks on Claude Opus 5 and Sonnet 5

shouldPreserveThinkingBlocks() matched modern Claude ids with a hardcoded
family list plus /claude-[5-9]/ future-proofing. That regex assumes the
generation follows the prefix (claude-5-x), but shipped generation-5 ids
place the family in between (claude-opus-5, claude-sonnet-5, claude-mythos-5),
so none matched and dropThinkingBlocks flipped to true. Signed thinking blocks
were stripped from replayed history, diverging every request and invalidating
the Anthropic prompt cache on the default opus/sonnet aliases.

Read the generation from the id instead, preserving blocks for generation 4
and newer. This handles both id shapes and matches the idiom already used in
audit-extra.sync.ts and live-model-filter.ts.

Closes #121251

* fix: correct Claude thinking replay contract

Use the canonical Claude model identity and exact Anthropic preservation contract when deciding whether replay may retain prior thinking blocks. Carry deployment metadata through provider-family and fallback paths, and include canonicalModelId in the transcript policy cache key.

Release note: Restore prompt-cache reuse for Claude Opus 5 and Sonnet 5 while continuing to strip unsupported Sonnet and Haiku 4.5 thinking history.

* refactor: remove unused replay compatibility helper

Use the canonical Claude drop predicate at the remaining test call sites and remove the unconsumed preservation export so the dependency/dead-code gate stays clean.

* fix: keep Claude replay contract internal

Use canonical llm-core identity resolution without exporting a new llm-core capability, avoiding unintended Plugin SDK API drift.

---------

Co-authored-by: FullerStackDev <263060202+fuller-stack-dev@users.noreply.github.com>

* fix(sessions): highWaterBytes 0 no longer deletes all session history (#119909)

* fix(sessions): zero highWaterBytes no longer clears all session history

resolveHighWaterBytes passed an explicit non-positive highWaterBytes through
verbatim. The resolved value is the disk-budget cleanup loop's stop condition,
so a zero target made enforce mode evict every unprotected session and prune
its extracted archives instead of trimming to the documented 80% default.

Route the non-positive case to the function's existing unusable-value branch
(computeDefault). Not null: that disables the budget and permits unbounded
growth, which is right for a cap but wrong for a target.

Sibling of #119422, which fixed the same harm for maxDiskBytes and guarded
only resolveMaxDiskBytes.

* test(infra): isolate worktree migration discovery

Keep worktree migration coverage focused on its real filesystem, Git, and SQLite owner while avoiding unrelated channel and plugin doctor cold starts on fork CI.

Co-authored-by: masatohoshino <g515hoshino@gmail.com>

* test(ci): carry owner-approved SDK and doctor gate repairs

Carry the already-approved plugin SDK contract manifest and focused doctor-flow test isolation from the maintainer-owned CI repair. Preserve real config migration, persistence, snapshot, and SQLite cleanup coverage; no production behavior changes.

Co-authored-by: masatohoshino <g515hoshino@gmail.com>

* fix(sessions): use the renamed withTestDir helper in the new budget test

* fix(sessions): align high-water zero contract

* style(sessions): format high-water changes

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: FullerStackDev <263060202+fuller-stack-dev@users.noreply.github.com>

* fix(ui): model picker shifts when another user starts typing (#122809)

* fix(ui): keep composer model picker stable while typing

* test(ui): prove typing keeps model picker stable

Co-authored-by: Colin Johnson <colin@solvely.net>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>

* feat(ui): split new session place picker (#122938)

* feat(ui): split new session place picker

* test(ui): cover three-chip session picker

* fix(gateway): allow downloading zero-byte artifacts (#122928)

* fix(gateway): preserve zero-byte artifacts

* fix(gateway): keep non-string data out of artifact lists

* test(gateway): compact zero-byte artifact coverage

* feat(ui): open subagent details in chat sidebar (#122941)

* feat(ui): open subagent details in chat sidebar

* chore: drop changelog edit (release generation owns it)

* refactor(ui): drop duplicate close in subagent detail panel

The sidebar region header already owns a Close Details control in both
wide and narrow layouts; the panel-local X duplicated it 40px away.

* fix(ui): stop subagent transcript loader when pane presentation retires

Pane retention wipes sidebarContent directly, so the detail slot's
render-time reset can never run again; a pending refresh timer plus
incoming task events kept refetching chat.history for a hidden panel.

* docs(ui): note close-control ownership in subagent detail header

* fix(ui): break transcript renderer import cycle

* fix(ui): use shared action cursor for subagent rows

* fix: install or review the publisher you picked when ClawHub skills share a slug (#121697)

* fix(skills): keep ClawHub publisher identity from search through install

ClawHub search returns one entry per publisher, so several results can share a
slug. Every client collapsed the selection to that bare slug before calling
skills.detail and skills.install, and ClawHub answered 409 AMBIGUOUS_SKILL_SLUG
with no in-product way forward.

searchClawHubSkills now records the publisher-qualified reference once, on the
result that carries it, and the Gateway protocol documents it. skills.detail
parses the same reference grammar skills.install already accepted, so review and
install cannot resolve to different publishers. Control UI carries that one
reference through row actions, detail, busy state, and acknowledgement retries,
and shows it so otherwise identical rows are distinguishable.

Fixes #117633

* fix(apps): send the ClawHub publisher reference from native skill browsers

macOS, iOS, and Android read the qualified reference from search results and use
it for skills.detail, install, busy state, installed matching, and list identity,
so two publishers sharing a slug stay distinct instead of collapsing into one
ambiguous request.

* fix(skills): refuse external-source skill detail instead of reading a same-slug skill

ClawHub has no source-qualified read endpoint, so a skills-sh reference parsed
down to its bare slug would have returned a registry skill's card while install
resolved the external artifact. Review and install could name different skills.

skills.detail now fails closed on any reference that carries a source, and the
macOS and AgentPro rows show the publisher reference next to the summary instead
of only when a summary is missing, so same-slug rows stay distinguishable.

* chore(apps): refresh native i18n source baseline for the skill row references

* refactor(skills): drop the unread search-result ownerHandle field

installRef is the one reference clients send back, and no client reads the
publisher handle separately, so the protocol and Control UI carry one field
instead of two.

* fix(skills): name the next step when external skill detail is refused

Clients that gate install behind a successful review would otherwise see only a
refusal, so the error names the direct install path and the CLI equivalent.

* fix(macos): use a doc comment on the ClawHub row subtitle

swift-format's docComments rule requires doc comments on declarations; the
subtitle property carried a regular comment and failed macos-swift.

* fix(skills): carry ClawHub trust state to clients that can install

Forwarding installRef let clients install the exact publisher the operator
picked, including external skills-sh sources. It did not forward the trust
state that says ClawHub never scanned that source, so iOS AgentPro — the one
surface that installs in a single tap with no review step — could install an
unscanned artifact with nothing on screen saying so. The CLI already labels
these (docs/clawhub/cli.md, docs/cli/skills.md); native clients could not,
because trustState was never on the wire.

trustState becomes an optional field on SkillsSearchResultSchema. It is purely
additive: older clients ignore an unknown key and the field is absent for
registry results, so downgraded readers are unaffected and no protocol version
moves.

Every client that renders a search row now shows "Not scanned by ClawHub",
matching the CLI wording exactly: iOS AgentPro in the row above the install
button, macOS and Android beside the review action, and Control UI on the row
that explains why review is refused for these sources.

Covered by a wire assertion that the state reaches clients for an external
source and stays absent for registry rows, plus decode-and-label tests on the
shared Swift kit and the Android parser, and a Control UI render assertion.

* fix(ui): size the ClawHub detail dialog to a refusal message

Refusing detail for an external source made an error-only dialog reachable.
The shared preview panel reserves a tall reader height for skill documents, so
a two-line refusal rendered in a mostly empty dialog and read as broken rather
than deliberate. Found by inspecting the review captures.

* revert(ui,apps): drop the ClawHub trust label layer

Maintainer product decision: skills.sh runs its own scanners, so OpenClaw does
not add a second alert layer in the apps. Removes the label from Control UI,
iOS, macOS and Android, and drops the trustState wire field that nothing would
render. The CLI keeps its existing label; changing that is a separate call.

Publisher identity, the fail-closed detail refusal, and the message-only dialog
are unchanged. Splits the oversized skills view test file to satisfy max-lines
without a suppression.

* test(ui): fix ClawHub skill fixture checks

* chore(plugin-sdk): refresh API baseline

---------

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

* oc-e35: restore explicit multi-agent UI ownership (#122889)

* fix(agents): hydrate CLI images from agent workspaces (#122684)

* fix(agents): hydrate CLI images from agent workspace

* fix(agents): preserve resolved CLI workspace owner

* fix(agents): keep workspace owner in prepared params

* fix(agents): resolve CLI owner before preparation

* fix(agents): preserve CLI runtime policy owner

---------

Co-authored-by: Adkid-Zephyr <169631528+Adkid-Zephyr@users.noreply.github.com>
Co-authored-by: FullerStackDev <263060202+fuller-stack-dev@users.noreply.github.com>

* fix(ai): honor embedded transport policy (#122946)

* refactor: remove residual normalization aliases (#122956)

* refactor: remove residual normalization aliases

* test(gateway): isolate approval authority handshake

* fix(qa): isolate staged auth state (#122958)

* fix(wizard): honor gateway overrides in manual flow (#122961)

* refactor(config): retire dead streaming.progress.render key (#122927)

* refactor(config): retire dead streaming.progress.render key

The key had zero runtime consumers after #122552. Core doctor now strips it via stripRetiredTuningKnobs, and production LOC is net -13.

* fix(tooling): pin plugin SDK surface counts to the reduced export set

The retired progress-draft render reader counted twice via channel-outbound and channel-message's wildcard re-export.

* fix(projects): avoid stale GitHub results after token rotation (#122613)

* fix(projects): avoid stale GitHub results after token rotation

* fix(gateway): scope GitHub caches by credential

* style(gateway): format GitHub credential scope

---------

Co-authored-by: FullerStackDev <263060202+fuller-stack-dev@users.noreply.github.com>

* fix(cli): avoid restart hint for unchanged config (#122953)

* fix(cli): avoid restart hint for unchanged config

* docs(cli): clarify no-op restart guidance

* fix(onboard): allow imports after runtime scaffolding (#122967)

* fix(cli): fail fast when onboarding profile is busy (#122968)

* fix: GitHub project selection cloned repos before Start Session (#122906)

* fix(ui): defer GitHub project clone until submit

Keep remote project selection as draft state and materialize it before sessions.create on Start Session.

* fix(ui): consolidate deferred project selection

* test(ui): drop duplicate remote project assertion

* fix(deploy): repair probes that silently pass and a blueprint that cannot boot (#122963)

Three defects proven by running the shipped configs:

Kubernetes probes checked only the status code against /startupz, but the
pinned image predates that route and the Control UI answers unknown paths
with a catch-all 200. A wedged pod was therefore marked Ready forever.
Probes now assert the JSON probe contract and target routes the pinned
image actually serves; verified in a kind cluster where the old command
exits 0 on the missing route and the new one exits 1.

render.yaml set no dockerCommand, so the image CMD ran without
--allow-unconfigured and a fresh Render disk exited 78 with 'Missing
config' before binding. Reproduced locally with Render's exact env.

The Cloudflare Container readiness poll had the same route mismatch
against operator-supplied official image digests; it now polls /healthz,
which every published image serves.

Also replaces an R2 verification step that could never fail: wrangler
cannot list object keys, so the documented command 404'd into || true.

* docs: repair spellcheck and anchor drift (#122960)

* docs: repair spellcheck and anchor drift

* docs: satisfy markdown anchor lint

* docs(hosting): fix unsafe deployment instructions (#122971)

* test(agents): remove global test APIs (#122972)

* fix(slack): accept org-wide user IDs in Enterprise Grid policies (#122934)

* test(slack): accept org-wide enterprise users

* fix(slack): allow org-wide enterprise users

* style(slack): format enterprise user policy

* test(slack): preserve enterprise user identity scope

* fix(slack): preserve enterprise user identity scope

* fix(slack): import workspace identity normalizer

* fix(slack): normalize enterprise owner ids

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>

* refactor(state): simplify schema migration validation (#122959)

* perf(test): avoid embedded runtime imports in btw suite (#122957)

Co-authored-by: Amp <amp@ampcode.com>

* fix(agents): preserve setup inference auth owner (#122975)

* feat(ui): open bare pair command without a chat turn (#120855)

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

* test(extensions): repair stale full-config extension tests (#122978)

clickclack inbound mention gating: #114388 (1ca60fbc3a) made multi-agent fallback ownership explicit, so the #115484 fixture now declares its clickclack:default service-bot binding.

policy CLI: #114388 (1ca60fbc3a) removed ambient ownership from normalized multi-agent configs, so the #111087 routing-probe fixture uses the sole main agent and still reaches the intended findings exit.

Teams and Zoom node invoke policy: #118451 (7d4066639e) added trusted audio backend, buffer size, and format forwarding; assert those fields alongside the configured commands.

Teams node host: #118451 (7d4066639e) made default audio commands platform-dependent at import time after #111455 added the sox dedupe test; reset modules and mock Darwin before importing defaults.

* fix(cli): rejected profile commands no longer create state (#122970)

* fix(cli): defer profile state creation past argument validation

* test(cli): use tracked profile temp directory

* test(doctor): align checkpoint expectation with pristine roots

* fix(agents): report recovered compaction runs as completed (#122974)

* refactor(gateway): remove suspension mock replay (#122977)

* test(gateway): remove suspension mock replay

* test(agents): stabilize headless timeout assertion

* feat(node-host): add negotiated private worker controls (#122939)

* feat(node-host): add private worker supervisor controls

* refactor(node-host): harden private worker controls

* refactor(node-host): simplify private worker controls

* docs(plan): track private worker controls

* fix(node-host): satisfy private control CI guards

* test(gateway): follow worker service construction boundary

* test(gateway): register private control release train

* fix(gateway): retain worker dialect across reapproval

* fix(sessions): preserve durable transcript ownership (#122729)

Resolve transcript writes through the durable SQLite session-window owner, reject owner changes transactionally, and repair unambiguous stolen-owner aliases with Doctor.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-authored-by: Thorsten Stresow <185197304+thostr1@users.noreply.github.com>

* feat(xai): add Grok 4.6 catalog and preserve OAuth xhigh (#122762)

* feat(xai): add Grok 4.6 catalog and preserve OAuth xhigh

Add first-class Grok 4.6 discovery, pricing, and reasoning metadata while
keeping the existing Grok 4.3 API-key and server-tool defaults unchanged.
Preserve xhigh only for Grok 4.6 so OAuth auto no longer inherits the
Grok 4.5 high downgrade.

Closes nothing; tracks #122734.

* fix(xai): resolve the OAuth auto alias to its canonical model in the thinking policy

The OAuth catalog row keeps id "auto" and records the provider-selected
target in params.canonicalModelId; judging the raw alias collapsed the
default OAuth route to an off-only thinking picker for every model.

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

* test(xai): refresh catalog-order assertions and restore stream deadlines for Grok 4.6

Exact-order catalog and onboarding arrays now include the new row with its
metadata assertion; payload-capture timeouts return to their original
values, Grok 4.5 off-clamp and Grok 4.3 modern-model coverage are
restored, and the Grok 4.6 xhigh boundary test passes its id explicitly.

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

* feat(agents): add Grok 4.6 to the curated high-signal live matrix

xai is a curated-only high-signal provider, so the new flagship was
structurally excluded from default live sweeps; add it alongside
Grok 4.5 with its test and docs mirrors, matching the 4.5 precedent.

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

* fix(xai): align Grok frontier metadata

* fix(xai): align Grok 4.6 catalog contract

Remove the unsupported moving alias, centralize OAuth auto target resolution, correct cached pricing, and keep live coverage on the stable xhigh completion path.

Co-authored-by: Kiran Magic <262980978+kiranmagic7@users.noreply.github.com>

---------

Co-authored-by: Kiran Magic <262980978+kiranmagic7@users.noreply.github.com>
Co-authored-by: Kiran Magic <kiran@Alices-Laptop.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Kiran <kiranmagic7@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>

* test(plugins): refresh fixture contracts (#122986)

* improve: one channel picker and one model picker across the Control UI (#122964)

* fix(ui): unify channel pickers with icons

Preserve channel values and mutation ownership across Automations, pairing, setup, and Workboard while sharing accessible picker rendering and artwork.

* refactor(ui): unify model pickers

Share provider-aware model selection across chat, new sessions, Automations, Agents, model defaults, Session Observer, Talk, and Memory while preserving owner-specific values and locks.

* fix(ui): keep picker change callbacks value-only

Keep the Web Awesome element private to model-picker custom-mode handling while preserving one-argument callbacks for every picker consumer.

* fix(ui): satisfy model picker types

Keep custom sentinel options within the shared model option shape and guard optional Memory placeholder translation keys.

* refactor(ui): remove obsolete model option template import

Drop the Lit import after Agents model options became pure shared-picker data.

* fix(ui): satisfy picker lint gates

Use explicit model option mapping, remove stale E2E locals, and keep the Cron behavior suite within its enforced line budget.

* test(ui): target unified session model picker

* fix(ci): rename state migration assertion map off the env-var pattern

OPENCLAW_STATE_MIGRATION_ASSERTIONS (a module-local const introduced by
#122959) matches the OPENCLAW_[A-Z0-9_]+ source scan in
scripts/check-env-var-count.mts, pushing the env-var ratchet to 503/502
and failing check:env-var-count on every branch based on current main.
It is not an environment variable; rename it to STATE_MIGRATION_ASSERTIONS
so the ratchet stays an honest env-var count.

* test(oc-path): make perf budgets robust to CI scheduler noise (#122994)

* fix(memory): keep session reconciliation off search path (#120837)

* fix(memory): keep session reconciliation off search path

* test(memory): decouple reconciliation test from provider fixture

---------

Co-authored-by: Jason (Json) <263060202+fuller-stack-dev@users.noreply.github.com>

* fix(agents): preserve headless timeout ownership (#122997)

* fix(gateway): preserve system agent ownership (#122987)

* fix(gateway): preserve system agent ownership

* chore(plugin-sdk): refresh ownership API baseline

* fix(gateway): preserve global system event routing

* refactor(ui): one task-detail surface for rail and subagent clicks (#123003)

* refactor(ui): unify task details in sidebar panel

* docs(ui): describe task detail sidebar

* refactor(ui): collapse onSelectTask into onOpenTaskDetail

Two names for the same open-the-panel action; rows now call the
callback directly.

* fix(ui): clear rail open-task highlight when detail slot closes

openTaskId derived from sidebarContent alone, but region close only
collapses the layout and retains content, leaving a stale
aria-current row; gate the highlight on detail-slot visibility.

* fix(ui): keep requester sessions out of subagent transcripts and let reopen retry failed lookups

A queued subagent has no child session yet; falling back to its
sessionKey rendered the requester's conversation as the task
transcript. And a failed tasks.get permanently suppressed the panel's
render-driven load; selection now clears the recorded error so
reopening retries, matching the old rail behavior.

* test(buzz): add opt-in thread QA coverage (#116081)

* test(buzz): add opt-in thread QA coverage

* fix(buzz): preserve QA conversation kind

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>

* perf(test): avoid unrelated runtime imports in MCP suite (#122998)

Remove duplicate adversarial filter integration coverage, replace broad plugin/auth imports with contract-complete test leaves, and repair the main env-var ratchet broken by an unrelated newly added internal constant.

Amp-Thread-ID: https://ampcode.com/threads/T-019fee8d-665d-707b-a380-23f2a6a1ce03

Co-authored-by: Amp <amp@ampcode.com>

* fix(ci): sanitize AI manifest during installer pack (#122952)

* test(agents): move recovery transcript proof to QA (#123006)

* fix(discord): chunk long thread initial messages (#117354)

Discord rejected over-limit starter messages and could leave ordinary threads empty after creation.

Split initial content through the existing Discord chunking and nonce-retry path while preserving confirmed-versus-ambiguous partial-delivery results.

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

* refactor(plugin-sdk): remove retired Copilot login chain (#122988)

* refactor(plugin-sdk): remove retired Copilot login chain

* chore(plugin-sdk): refresh generated API baselines

* build(github-copilot): remove unused prompt dependency

* chore(plugin-sdk): reconcile API baselines after rebase

* fix(e2e): declare agents-delete fixture owners (#123000)

* fix(sessions): preserve pinned sessions during maintenance (#122990)

* fix(state): accept shipped commitments schema (#122945)

* fix(parallels): recover migration-refused gateway startup

* fix(signal): fail probe when RPC verification fails (#123001)

* feat(worker): expose supervised terminal outcomes (#123013)

* feat(worker): expose supervised terminal outcomes

* docs(plan): track supervisor terminal outcomes

* test: speed up attempt execution helpers (#123012)

Co-authored-by: Amp <amp@ampcode.com>

* fix(replies): keep approval-unavailable notices durable (#121179)

Punchcard-Session: clear-lantern-summit-v2

* fix(ui): stop misreporting limited Custodian access (#123011)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Vyctor H. Brzezowski <krzyszchweski@gmail.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: Jacqueline Henriksen <jjjhenriksen@gmail.com>
Co-authored-by: Josh Lehman <josh@martian.engineering>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: licheer-zte <li.qi16@xydigit.com>
Co-authored-by: sunlit-deng <yang.jiajun1@xydigit.com>
Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
Co-authored-by: Calin Laurentiu Ilie <calinilielaur@gmail.com>
Co-authored-by: Daniel Cárdenas <dacardenasj@unal.edu.co>
Co-authored-by: DanielCardenas <djerez@lean-tech.io>
Co-authored-by: Colin Johnson <colin@solvely.net>
Co-authored-by: Chinmay Rawat <88652081+Chinmayrawat15@users.noreply.github.com>
Co-authored-by: Masato Hoshino <g515hoshino@gmail.com>
Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
Co-authored-by: Feng <laufs0310@163.com>
Co-authored-by: Adkid-Zephyr <169631528+Adkid-Zephyr@users.noreply.github.com>
Co-authored-by: PIYUSH RATHORE <163632958+Piyushrathoree@users.noreply.github.com>
Co-authored-by: Sarah Fortune <sjf@openai.com>
Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-authored-by: Thorsten Stresow <185197304+thostr1@users.noreply.github.com>
Co-authored-by: kiranmagic7 <kiranmagic@proton.me>
Co-authored-by: Kiran Magic <262980978+kiranmagic7@users.noreply.github.com>
Co-authored-by: Kiran Magic <kiran@Alices-Laptop.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Kiran <kiranmagic7@users.noreply.github.com>
Co-authored-by: Dallin Romney <dallinromney@gmail.com>
Co-authored-by: xingzhou <zhang.guiping@xydigit.com>
Co-authored-by: Leon-SK668 <0668001470@xydigit.com>
2026-08-12 23:39:17 -07:00
Vincent Koc 8371831eba fix(ci): validate duplicate coverage on frozen targets release-publish/8371831eba5e-1786610071 2026-08-13 14:37:21 +08:00
joshavant be7a2c23e9 fix(discord): cancel started ingress jobs on abort 2026-08-13 01:34:05 -05:00
joshavant 0bea408976 fix(discord): cancel skipped queued ingress 2026-08-13 01:34:05 -05:00
joshavant 59c382b717 fix(tests): respect plugin helper boundary 2026-08-13 01:34:05 -05:00
joshavant 13750feff3 fix(plugin-sdk): preserve cancellation receivers 2026-08-13 01:34:05 -05:00
joshavant b0a8cdb6f7 fix(discord): settle mixed cancellation fan-in 2026-08-13 01:34:05 -05:00
joshavant 0901efe3dd test(mattermost): align tool preview fixture with privacy default 2026-08-13 01:34:05 -05:00
joshavant 5af3d49621 fix(plugin-sdk): make ingress cancellation fan-in safe 2026-08-13 01:34:05 -05:00
joshavant 06600e2ca0 fix(discord): unblock ingress after retry exhaustion 2026-08-13 01:34:05 -05:00
Vincent Koc ac110917e1 fix(ci): stream npm pack receipt to disk (#123019) 2026-08-13 14:30:27 +08:00
Peter Steinberger 5bdfa69e82 feat(worker): add durable node launch adapter (#123033)
* feat(worker): add durable node launch adapter

* docs(plan): track durable node launch adapter
2026-08-12 23:29:29 -07:00
Peter Steinberger cd42bc8cda test(config): trim IO compatibility suite imports (#123024)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-12 23:25:40 -07:00
Peter Steinberger 2464c17ab5 fix(ui): open the current session desktop directly (#122992)
* fix(ui): open session desktop directly

* fix(ui): make session desktop retryable
2026-08-12 23:24:27 -07:00
Leon-SK668 cc2ed816be fix(mac): preserve Xcode preflight failure diagnostics (#121170) 2026-08-13 14:17:32 +08:00
Peter Steinberger 3f4f57a021 test(extensions): scope remaining multi-agent fixtures to explicit owners (#123021)
Class provenance: #114388 made multi-agent ownership explicit; prior partial sweeps #122883 and #122978 repaired Codex, Copilot, ClickClack, and policy fixtures.

Per-file changes:
- extensions/telegram/src/bot.create-telegram-bot.test.ts: declare startup owners for the four reload fixtures and add the default Telegram binding for the topic override case while preserving dynamic account/topic routing assertions.
2026-08-12 23:14:34 -07:00
machine3at 7620a58b29 fix(memory-wiki): guard wiki_get against missing or wrong-typed lookup (#122549)
* fix(memory-wiki): return clean error from wiki_get on missing lookup

wiki_get crashed with "Cannot read properties of undefined (reading
'trim')" when called with a wrong parameter name (e.g. path instead of
lookup), leaving lookup undefined.

- Validate and trim lookup at the wiki_get tool boundary; return a clean
  error (found: false) when it is missing or empty instead of falling
  through to page resolution
- Add regression test covering the wrong-param call path

* fix(memory-wiki): normalize wiki_get parameters

Punchcard-Session: calm-workshop-cedar-hx

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-13 14:08:36 +08:00
Leon-SK668 d94c755eb7 fix(skills): invalidate plugin skill memo when ACP availability changes (#121181) 2026-08-13 14:04:35 +08:00
Peter Steinberger 7c8f08a88c fix(ci): split discord thread-creation tests under the max-lines cap
#117354 added 246 lines of thread initial-message chunking coverage, taking send.creates-thread.test.ts to 1082 counted lines against the 1000-line cap and leaving main check-lint red.

Move the 9 chunking tests to a sibling file. The suite remains 51 tests total: 51 before; 42 + 9 after.
2026-08-12 22:57:48 -07:00
Alix-007 2dffeae126 fix(gateway): scope task-owned terminals by child session (#121192)
Punchcard-Session: calm-workshop-cedar-hx
2026-08-13 13:28:12 +08:00
Dallin Romney eda22ae1d5 fix(ui): stop misreporting limited Custodian access (#123011) 2026-08-13 13:25:58 +08:00
Leon-SK668 7d6dfa1939 fix(replies): keep approval-unavailable notices durable (#121179)
Punchcard-Session: clear-lantern-summit-v2
2026-08-13 13:23:58 +08:00
Peter Steinberger 568c07191a test: speed up attempt execution helpers (#123012)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-12 22:20:09 -07:00
Peter Steinberger 3f4d89505a feat(worker): expose supervised terminal outcomes (#123013)
* feat(worker): expose supervised terminal outcomes

* docs(plan): track supervisor terminal outcomes
2026-08-12 22:19:49 -07:00
Peter Steinberger 009e53d582 fix(signal): fail probe when RPC verification fails (#123001) 2026-08-12 22:19:46 -07:00