19240 Commits

Author SHA1 Message Date
Peter Steinberger 4d54c3f1a1 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.
2026-08-12 20:36:40 -07:00
Josh Avant 705f043e04 fix(qa): isolate staged auth state (#122958) 2026-08-12 22:30:46 -05:00
Peter Steinberger 08f9c3a5cb test(extensions): remove duplicate runtime replays (#122949) 2026-08-12 19:58:04 -07:00
Vincent Koc ce3d1d22be fix(qa): preserve Code Mode reads in model-switch mock (#122935) 2026-08-13 10:41:42 +08:00
Vincent Koc dabf55727b fix(ci): prevent channel add command test timeout (#122879)
* test(channels): isolate add env setup contracts

* test(channels): cover adapter env setup
2026-08-12 19:24:31 -07:00
Daniel Cárdenas 326501fce3 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>
2026-08-12 19:06:47 -07:00
Calin Laurentiu Ilie 95bbd117ef 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
2026-08-12 18:57:04 -07:00
Peter Steinberger fd0fc80c8c 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
2026-08-12 18:53:44 -07:00
Peter Steinberger 10a1a43f4b fix(zalo): keep packaged setup wizard loadable (#122902)
* fix(zalo): package setup runtime surface

* fix(tooling): track setup surface artifacts
2026-08-12 18:49:41 -07:00
joshavant 93cf912695 fix(matrix): retain visible drafts on handler abort 2026-08-12 20:32:32 -05:00
joshavant b8af033514 test(matrix): observe nonvisible cleanup 2026-08-12 20:32:32 -05:00
joshavant 0aceebb97d test(matrix): type redaction ledger 2026-08-12 20:32:32 -05:00
joshavant 228d0a5264 test(matrix): bind live replacement marker 2026-08-12 20:32:32 -05:00
joshavant d9b598ce1f test(matrix): tighten replacement proof 2026-08-12 20:32:32 -05:00
joshavant 4408ceb68e fix(matrix): retain previews when replacement delivery fails 2026-08-12 20:32:32 -05:00
sunlit-deng 0417abdfaa fix(reef): redact relay errors containing credentials (#119603) 2026-08-12 18:21:31 -07:00
Peter Steinberger c2d8b3be4d 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.
2026-08-12 18:13:45 -07:00
Peter Steinberger 469be48967 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).
2026-08-12 18:13:16 -07:00
Peter Steinberger e4acf43813 test(agents): scope extension fixtures to explicit owners (#122883) 2026-08-12 17:52:03 -07:00
Peter Steinberger abe0cd691d refactor(media): remove orphan generation facades (#122874) 2026-08-12 17:19:22 -07:00
Peter Steinberger 52cda537a4 test(discord): move ready abort proof to lifecycle (#122869) 2026-08-12 16:54:20 -07:00
Peter Steinberger 5c2e099374 fix(codex): restore promoted approval regression coverage (#122861)
* test(codex): align projector fixtures with verbose policy

* test(codex): supply admitted host context to hook relay fixtures
2026-08-12 16:30:30 -07:00
Peter Steinberger d003e08756 refactor(plugin-sdk): remove final test-only facades (#122844) 2026-08-12 15:28:22 -07:00
Kimi Yu f9316c4697 fix(slack): stop repeated outage notices in active threads (#122782) 2026-08-12 14:41:41 -07:00
Peter Steinberger c58dbaff22 fix(slack): session card stuck on Working after concurrent mentions (#122816)
* fix(slack): terminalize a progress card detached by a concurrent mention

Rapid mentions in one Slack conversation fire the draft-message boundary
notifier, which calls forceNewMessage and clears the draft stream's message
identity so later output lands below the human message. The already-posted
Working card survives in Slack but becomes unreachable: finalize(), clear(),
and the drop-on-failed-finalize fallback all key on the stream's current
identity, so the card stays at Working forever.

Retain messages the draft stream abandons while un-finalized, expose
dropDetachedMessages(), and drain it from the card's finalize path so final
delivery, error closeout, and turn rotation all terminalize. Also implement
onQueuedFollowupSettled so a queued turn draining after its dispatch already
returned cannot leave a card in Working state. Both cleanups are gated on the
session-card mode: partial/append previews hold streamed assistant text the
human already replied to and must stay visible.

* fix(slack): drain detached cards appended during an in-flight delete

The detached-card drain snapshotted its queue, so a human message routed
synchronously through the conversation boundary during an awaited delete
appended a card the same drain would never remove. The silent-turn closeout
also dropped before its clear(), leaving that window unowned.

Drain until the queue is stable and make the drain the last act on the silent
exit path, so a card detached mid-cleanup still reaches removal.
2026-08-12 14:31:46 -07:00
Peter Steinberger b6548e509a refactor(state): retire commitments schema (#122176)
* refactor(state): retire commitments schema

* fix(state): complete commitments retirement safeguards

* test(state): expect doctor retirement report

* test(state): prove doctor v7 markers atomically

* fix(state): align schema support metadata

* fix(state): report actual commitments retirement

* fix(state): validate retired commitments schema

* fix(state): preserve early commitments upgrades

* fix(state): require exact commitments index set

* fix(state): reject non-exact retired schemas

* fix(state): recognize supported retirement layouts

* fix(state): expose commitments retirement to doctor

* fix(voice-call): describe commitments retirement

* test(state): align v7 rebase proof

* fix(state): protect commitments retirement dependencies

* fix(state): accept partial commitments layouts

* chore(docs): refresh v7 api baselines
2026-08-12 14:21:34 -07:00
sunlit-deng 120a75da51 fix(slack): surface unavailable forwarded images (#122108)
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-12 16:07:18 -05:00
Peter Steinberger 79380000e0 refactor(plugin-sdk): remove test-only facades (#122807) 2026-08-12 13:57:07 -07:00
Peter Steinberger 468dc55a39 fix(matrix): silence empty inbound dedupe migration receipt on fresh installs (#122808)
On a pristine profile, onboarding/doctor printed "Auto-migrated legacy
state: Recorded Matrix inbound dedupe migration completion (0 SQLite
roots, 0 JSON roots scanned)" even though nothing was migrated. Keep
the durable empty-scan receipt (it still prevents later historical
databases from being opened) but only emit the user-visible change line
when at least one SQLite/JSON root was scanned.
2026-08-12 13:56:04 -07:00
Kimi Yu e1b8150a06 fix(codex): let owners install plugins from discovered marketplaces (#122389)
* fix(codex): allow owner-approved marketplace plugins

* fix(codex): preserve marketplace validation and remove unused exports

* docs(codex): clarify already-installed plugin authorization
2026-08-12 20:29:40 +00:00
Peter Steinberger 9013ab80a8 fix(whatsapp): keep distinct-id repeated messages (#122785) 2026-08-12 13:07:22 -07:00
Peter Steinberger b4ffa3106f refactor(extensions): remove orphan test exports (#122784) 2026-08-12 12:45:33 -07:00
Peter Steinberger dceb2c343c refactor: retire due compat-ledger surfaces (context-engine host params, deactivate alias, logging internals) (#121845)
* refactor(plugins): retire deactivate hook alias

* refactor(plugin-sdk): prune retired facade exports

* test(logging): isolate logger test controls

* refactor(logging): internalize file transport controls

* test(plugin-sdk): preserve retired facade coverage

* test(auto-reply): remove stale diagnostic imports

* refactor(logging): delete dead config-read guard

shouldSkipMutatingLoggingConfigRead had no production caller even on main;
it survived the dead-export scan only via logger's testApi re-export. The
test-isolation commit removed that mask, exposing the fossil. Delete the
guard, its test-only re-export, its mock entry, and its dedicated test file.

* refactor(plugin-sdk): retire due compatibility subpaths

* test(plugin-sdk): type group policy predicates

* refactor(plugin-sdk): split removed subpath records

* refactor(secrets): remove retired collector barrel

* test(plugin-sdk): tighten wildcard surface pin

* refactor(plugin-sdk): retire matrix facade metadata

* style(plugin-sdk): format facade metadata

* fix(ci): load channel setup contracts from source

Repair the main-owned regression from 99d662473c (Peter Steinberger): the new env-contract test could consume stale ignored dist metadata instead of the checked-in plugin declaration.

* test(plugin-sdk): refresh API baseline after rebase
2026-08-12 12:41:27 -07:00
Peter Steinberger 49092ebab3 fix(tlon): report unavailable inbound images (#122783) 2026-08-12 12:40:03 -07:00
Vitor Cepeda Lopes a9ee6618fe fix(memory): recall prior conversation after session reset (#122051)
* fix(memory): recall archived session generations after reset

* test(memory): prove private recall across reset

* fix(memory): keep deleted transcripts outside reset recall

* fix(memory): reject deleted archives from reset recall

* fix(memory): isolate recall across sqlite resets

* test(memory): split reset recall coverage

* fix(memory): keep reset recall metadata private

* fix(memory): keep reset authority scoped

---------

Co-authored-by: TheAngryPit <16145902+TheAngryPit@users.noreply.github.com>
2026-08-12 12:38:13 -07:00
Peter Steinberger 40af3646d7 test(extensions): remove shared helper replays (#122773) 2026-08-12 12:19:38 -07:00
Peter Steinberger 9da43d67e1 refactor: remove residual normalization adapters (#122771) 2026-08-12 11:51:45 -07:00
Peter Steinberger 8bbc0a9bc7 fix(config): keep named profiles off the default gateway port (#122751)
* fix(config): derive profile gateway ports like the Mac app instead of defaulting to 18789

* fix(config): use canonical profile normalization
2026-08-12 11:47:44 -07:00
Peter Steinberger 343850d0df fix(googlechat): preserve partial delivery evidence (#122760) 2026-08-12 11:34:59 -07:00
Peter Steinberger 39c733ff73 refactor(opencode-go): compose provider stream wrappers (#122749)
Amp-Thread-ID: https://ampcode.com/threads/T-019ff438-3b93-77b8-9828-1d3c586cb127

Co-authored-by: Amp <amp@ampcode.com>
2026-08-12 10:53:53 -07:00
Peter Steinberger 2e86f7cc95 fix(telegram): preserve pre-dispatch send custody (#122741) 2026-08-12 10:47:08 -07:00
Peter Steinberger e689231e42 fix: make Codex onboarding survive inherited Node loader paths (#122731)
* fix(codex): sanitize inherited runtime loader paths

* fix(onboard): preserve candidate failure details
2026-08-12 10:42:34 -07:00
Peter Steinberger 144a598831 refactor(discord): remove thread binding test API (#122744) 2026-08-12 10:40:53 -07:00
Peter Steinberger 508dd471b0 feat(slack): live session cards as the default progress mode (#122552)
* feat(slack): render live session cards as the default Slack progress mode

Slack streaming.mode default flips partial->progress.
Progress mode renders one live Block Kit session card with a status header, narration, plan, activity, diff stat, and elapsed time; it is edited in place and finalized to success or error with an Open in OpenClaw button when gateway.publicOrigin is set.
Final assistant text always delivers separately.
The shared progress compositor gains a success-only additive per-turn diffStat mirroring the task ledger fold.
resolveGatewayPublicOrigin is exported through the plugin SDK.
The diffs viewer URL falls back to publicOrigin.
The old rich/text progress render fork is deleted.
Native task cards remain unchanged and opt-in.

* chore(config): regenerate bundled channel config metadata

* refactor(slack): keep session card state type internal

* refactor(slack): split session-card and diff-stat owners under lint ceilings

* refactor(channels): reuse diff-stat type from its owner module

Import ChannelProgressDraftDiffStat from progress-draft-diffstat instead of
redeclaring it in the compositor, resolving the all-exports deadcode scan.

* chore(plugin-sdk): regenerate api baselines for channel barrels

Baselines drifted after the rebase reconciled them against main; regenerate to
match the branch's actual channel-message/channel-outbound surface.

* fix(slack): drop a session card that cannot terminalize after final delivery

If the final reply is delivered but the terminal card edit fails, the caller
now clears the stale card instead of leaving it stuck in its Working state
(mirrors the pre-card preview cleanup). Adds a transport-failure regression and
corrects three tests that asserted the prior ignore-the-result behavior.

Documents resolveGatewayPublicOrigin as a dependency-light runtime helper on the
config-contracts SDK subpath, which previously described a type-only surface.

Addresses ClawSweeper P2 (unfinalized card) and P1 (runtime SDK contract).

* fix(slack): suppress default tool messages under the default progress card

resolveChannelStreamingSuppressDefaultToolProgressMessages re-derived the stream
mode from config with an "off" default, unlike its sibling resolvers which take
a caller-resolved mode override. After this branch made progress the Slack
default, a default-config channel turn saw mode "off" and left a stray
"Using tool: X" plain message posting alongside the session card. Thread the
caller-resolved mode through (compositor passes params.mode; Slack dispatch passes
slackStreaming.mode), matching resolveChannelStreamingPreviewToolProgress.

Retarget the progress-session-card delivery-trace golden at an EMPTY Slack config
so it proves the real default path; the regenerated golden is byte-identical,
confirming defaults now yield the clean card sequence (one card post, separate
final text, one terminal update with the Open in OpenClaw button, no stray tool
message). Switch the dispatch delivery-mode mock to the real resolver so the card
tests exercise the true channel default (automatic), not a hand-rolled one.

* chore(plugin-sdk): regenerate api baselines for the streaming mode param

resolveChannelStreamingSuppressDefaultToolProgressMessages gained an optional
mode override; the changed signature reflows the surface hash of every barrel
that re-exports it, so regenerate the affected baselines.

* chore(config): regenerate config baselines
2026-08-12 10:38:31 -07:00
Vincent Koc 6e880b5107 fix(qa): preserve model switch failure evidence (#122710) 2026-08-13 01:24:10 +08:00
Peter Steinberger 99d662473c fix(channels): fail-fast headless channel setup with plugin-declared env contracts (#122530)
* fix(channels): validate headless channel setup

* docs(channels): document headless provisioning

* fix(channels): repair setup metadata typing

* chore(channels): regenerate official channel catalog for env metadata

* fix(slack): keep mode-conditional env contract plugin-owned

Static --use-env declaration keeps only the unconditional SLACK_BOT_TOKEN;
socket-vs-HTTP conditional requirements (app token, signing secret) stay in
Slack's own setup validation so HTTP mode no longer demands an irrelevant
SLACK_APP_TOKEN.

* chore(sdk): regenerate api baselines and catalog after rebase

* fix(slack): align manifest env declaration with runtime contract

* chore(sdk): regenerate api baselines after rebase

* chore(sdk): regenerate api baselines after rebase

* chore(sdk): regenerate api baselines after rebase
2026-08-12 17:12:15 +00:00
Sarah Fortune bea0e398fa fix(slack): expose channel reaction events to thread turns (#122363)
* test: cover routed Slack system events

* fix: deliver route events to thread turns

* style: format routed event test

* fix: scope parent event routing to Slack

* test: isolate routed event admission proof

* fix(slack): keep reaction route handoff internal

* fix(slack): preserve channel turn public types

* fix(slack): hide reaction route carrier from sdk

* style: keep channel lifecycle within lint budget

* style: trim channel lifecycle carrier setup

* test: preserve route events on busy admission

* fix(reply): defer system event drain until admission

* test: prove deferred system event drain

---------

Co-authored-by: Sarah Fortune <sarah.fortune@gmail.com>
2026-08-12 10:04:57 -07:00
wanyongstar 7e21533841 fix(browser): validate extension relay frame fields before handling (#120283)
* fix(browser): validate extension relay frame fields before handling

* refactor(browser): clarify relay frame validation

* style(browser): format relay frame guards

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-08-13 00:46:15 +08:00
Peter Steinberger df4e6666c6 refactor(voice): promote realtime voice policy to talk owner (#122668)
* refactor(voice): promote realtime voice policy to talk owner

Move the exact-speech protocol (typed consult-call outcome instead of
string scraping), agent-proxy session instructions, and consult/wake-name/
barge-in policy defaults from the Discord plugin into src/talk, exported
additively via openclaw/plugin-sdk/realtime-voice. Wake-name enablement now
keys on a supportsActivationNameGating provider capability instead of a
hardcoded provider id. Follow-up to the voice split (#122479).

* fix(talk): bind exact-speech bypass to retained session state

Per ClawSweeper review on #122668: the protocol marker is untrusted model
tool-call text; only a parsed answer matching a currently retained
exact-speech text may select the privileged replay path. Unretained
marker calls route to a normal consult.
2026-08-12 09:44:19 -07:00
Peter Steinberger c23d66e3b5 refactor: consolidate coercion ownership (#122692)
* refactor: consolidate coercion ownership

* test: align shard check with weighted planning

* chore: refresh plugin SDK API baseline
2026-08-12 09:25:28 -07:00