Commit Graph

69859 Commits

Author SHA1 Message Date
Peter Steinberger
fee4490fe4 fix(docs): preserve canonical maturity product labels 2026-07-17 09:44:52 -04:00
Peter Steinberger
4ef4323db9 fix: keep memory SecretRef failures agent-scoped (#109977)
* test: normalize Copilot token fixture

* test: normalize Copilot auth fixtures

* test: use explicit Copilot placeholders

* test: use neutral Copilot fixture host

* refactor: clarify Copilot embedding auth values

* refactor: keep Copilot profile result intact

* test: normalize embedding credential fixtures

* fix: isolate memory SecretRef owners

* refactor: isolate memory secret collection
2026-07-17 14:44:03 +01:00
Peter Steinberger
649a8b35f8 refactor(mcp): reuse plugin cache primitives (#110013) 2026-07-17 14:42:58 +01:00
Peter Steinberger
7835c03930 test(release): align plugin validation expectations (#110012) 2026-07-17 14:36:12 +01:00
openclaw-mantis[bot]
71c1d612a6 chore(ui): refresh control ui locales (#109751)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-17 14:33:48 +01:00
Peter Steinberger
b48c801623 test(release): repair extension runtime fixtures 2026-07-17 14:24:13 +01:00
Stephen Hebson
cc9d80c3d6 perf(mcp): cache immutable config discovery (#79882)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 14:20:48 +01:00
Peter Steinberger
2c43e86787 refactor(discord): adopt shared realtime voice session harness (#110000) 2026-07-17 14:17:37 +01:00
Peter Steinberger
0c17cd4f1f fix(sqlite): keep additive agent schema at version 11 (#109999) 2026-07-17 14:15:40 +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
da69daeb72 feat(onboarding): recommend plugins and skills from installed apps (#109668)
* feat(onboarding): recommend plugins and skills from installed apps

Scan installed macOS apps during classic onboarding (TCC-free), gather
candidates from official catalogs + ClawHub search, let the configured
model pick genuine matches, and offer an opt-in multiselect install step.
Adds a device.apps node-host command (default-off sharing, Android-parity
envelope) so remote gateways can request a paired Mac's inventory, and a
wizard.appRecommendations kill switch. Custom setup-inference completions
no longer inherit the 32-token verification-probe output cap.

* feat(onboarding): recommend apps in guided flow

* fix(onboarding): harden app recommendations against ClawHub self-promotion

Third-party ClawHub skills are never pre-selected regardless of model tier
(publisher-controlled listing text reaches the matcher prompt and could
promote itself); their labels now say they install third-party code.
Installed-app scans follow symlinked .app bundles. Matcher output stays
bounded by the resolved model's own maxTokens budget (documented invariant).

* fix(onboarding): key official catalog candidates by resolved plugin id

Real catalog entries are package manifests without a top-level id; keying the
candidate map and channel/provider classification by entry.id collapsed the
whole official catalog into one undefined-keyed entry, so no official plugin
or channel was ever recommended. Regression test runs against the bundled
catalogs.

* fix(onboarding): satisfy lint, types, deadcode, and migration gates

Split the guided-onboarding test into a self-contained custodian suite to stay
under max-lines. Narrow app-recommendation exports (drop dead node-payload
normalizer, unexport internal types/helpers, route candidate tests through the
public API), replace map-spread with a helper, unexport device.apps result
types, add installedAppsSharing to node-host migration expectations, cast the
wizard multiselect mock, and regenerate the docs map.

* test(onboarding): register new live test in the shard classifier
2026-07-17 14:07:59 +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
Peter Steinberger
62407b36d7 fix(doctor): repair ALTER-appended operator approval schema instead of wedging startup (#109876) 2026-07-17 13:47:06 +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
bf754b8a34 feat: align native macOS chat with the web chat capability set (#109712)
* feat(macos): wire sessions manager, assistant trace, talk, voice notes, and Listen into native chat

* feat(clients): add input history, reply quoting, and per-session drafts to native chat composer

* fix(clients): capture TTS server lease before gateway check and dedupe restored input-history entries

* docs(clients): document reply-chip consume parity with web accepted-send semantics

* fix(clients): retire sent-text recall stash and keep recall markers stable under prepends

* test(clients): wait for outbox restore before asserting live-send paths

* docs(clients): note cross-session outbox flush scheduling contract

* chore(clients): split oversized chat files to satisfy SwiftLint length caps

* chore(i18n): sync native app i18n inventory for new chat strings

* chore: retrigger ci

* chore(i18n): translate new chat strings and regenerate Apple catalogs

* chore(i18n): regenerate Android localization resources for new chat strings

* test(clients): await lifecycle cleanup before modeling replacement gateway traffic

* chore(clients): split invoke timeout helper to satisfy SwiftLint length cap

* chore(clients): drop unused OpenClawProtocol import from invoke timeout split
2026-07-17 13:44:48 +01:00
Peter Steinberger
1ec4f3e0ed chore(plugin-sdk): refresh generated API baseline (#109987) 2026-07-17 13:44:31 +01:00
Peter Steinberger
662e79d574 test(release): harden extension prerelease contracts 2026-07-17 13:43:12 +01:00
Peter Steinberger
f341a013af test(release): repair plugin prerelease coverage 2026-07-17 13:43:12 +01:00
Peter Steinberger
363e8b09ec fix(release): honor explicit unreleased dry-run input 2026-07-17 13:43:12 +01:00
Peter Steinberger
a291cf7296 test(release): align prerelease scan contracts 2026-07-17 13:43:12 +01:00
Peter Steinberger
6f3aa0f7ae fix(release): point locale drift at generated sync 2026-07-17 13:43:12 +01:00
Peter Steinberger
c149489703 ci: trim release metadata and ClawHub checkouts 2026-07-17 13:43:12 +01:00
Peter Steinberger
cb70d7104e ci: speed up release preparation 2026-07-17 13:43:12 +01:00
Peter Steinberger
8bd78de5da test(macos): fix timestamp-anchoring flakes in chat haptics and stream replay tests (#109954)
Both flakes (CI run 29573675642, macos-swift) were the same mechanism:
fixture timestamps anchored to wall clock at test start, raced against
the optimistic user-echo timestamp captured later at send time. The
pending-run drain (clearPendingRunIfAssistantMessagePresent ->
assistantHapticEvent(after:)) only matches assistant rows timestamped
at or after the user echo, and the fake transports' default
waitForRunCompletion returns .unavailable, so this comparison is the
only drain path in both tests.

ChatHapticsTests "durable assistant failure fires run failed": the
durable failure row was stamped test start + 1000ms. Under CI load a
>1s stall between fixture creation and send() left the row permanently
older than the user echo, so .runFailed never fired for either
parameterized case. Fix: HapticsTestTransport now takes a history
closure and the test stamps the failure row at requestHistory time,
which is always post-send by event order.

ChatStreamReplayTests "reconnect mid-run converges via history
refetch": the completed transcript rows were stamped test start +
100/900ms; the scripted payload has no inFlightRun/sessionInfo, so the
foreground refetch cannot drain and only the pending-run owner's
timestamp comparison can. Bootstrap plus send taking >900ms made the
assistant row older than the echo and the run never drained. Fix:
anchor the reconnect transcript to a timestamp captured after the send
completed.

Proof: injecting a 1.5s/1.2s stall before send reproduced both CI
failures exactly (timeout after ~16.5s/16.2s, both haptics cases
failing); with the fixes the tests pass even with the stalls injected.
Full ChatHapticsTests + ChatStreamReplayTests suites green; both fixed
tests stressed 10x with zero failures.
2026-07-17 13:35:54 +01:00
DinoMC
017217bae3 fix(heartbeat): remember silent task results for the next user turn (#95838)
* fix(heartbeat): retain silent task outcomes

Co-authored-by: DinoMC <9079110+DinoMC@users.noreply.github.com>

* fix(heartbeat): keep outcome type internal

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 13:24:48 +01:00
Peter Steinberger
ee762ad761 feat(teams-meetings): join Microsoft Teams meetings via the meeting-bot core (#109964)
* feat(teams-meetings): join Microsoft Teams meetings via the meeting-bot core

* fix(teams-meetings): satisfy lint and package-boundary contracts
2026-07-17 13:23:39 +01:00
ooiuuii
db3213264a fix: avoid model-not-found fallback on OpenRouter image-input 404s (#99079)
* fix: classify OpenRouter image-input 404s as format errors

* test(agents): prove OpenRouter 404 fallback classification

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

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 13:13:54 +01:00
WhatsSkiLL
6bd9e5f158 fix(android): keep composer media with its chat (#109200)
* fix(android): keep composer media with its chat

* fix(android): retry shared media after chat switch

* fix(android): bind composer media synchronously

* fix(android): bind composer state to chat owners

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

* chore(android): keep release notes app-scoped

* refactor(android): reuse localized outbox failure text

* style: format web push state migration

* style: format google meet setup test

* fix(android): restore composer build compatibility

* chore(android): sync native i18n inventory

* fix(android): satisfy composer warning gate

* fix(android): align composer ownership tests

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

* test(android): align durable composer assertions

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

* test(android): bound outbox scheduler advances

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

* fix(ci): recalibrate status startup memory budget (#109887)

* fix(android): admit live composer payload

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

* fix(android): refresh native i18n inventory

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

* fix(android): bound composer admission receipts

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

* fix(android): preserve owner-bound async state

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

* fix(android): bind composer drafts to saved state

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

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-17 13:05:38 +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
max
907f5552f5 feat(feishu): handle opt-in VC meeting invites (#92340)
* feat(feishu): handle VC meeting invites

* fix(feishu): route VC invites through DM ingress

* fix(feishu): keep VC invite chat id canonical

* fix(feishu): handle VC invite pairing

* fix(feishu): simplify VC invite dispatch

* fix(feishu): guard VC invite pairing

* refactor(feishu): canonicalize VC invite ingress

Co-authored-by: renaocheng <renaocheng@bytedance.com>

* refactor(feishu): keep synthetic routing internal

Co-authored-by: renaocheng <renaocheng@bytedance.com>

* refactor(feishu): hide VC invite internals

Co-authored-by: renaocheng <renaocheng@bytedance.com>

* fix(feishu): gate VC invitation auto-join

* chore(config): refresh Feishu config baseline

* test(feishu): use synthetic VC fixture credential

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 12:36:42 +01:00
Peter Steinberger
56907458ac fix(skills): keep healthy skills available when one secret fails (#109791)
* fix(skills): isolate unavailable skill secrets

* fix(skills): preserve snapshot catalog during degradation

* fix(skills): fail closed for legacy snapshot aliases

* fix(skills): preserve empty runtime catalogs

* fix(skills): migrate snapshots to owner identities

* fix(skills): filter degraded captured prompts

* fix(skills): narrow snapshot owner keys

* style(skills): satisfy captured prompt lint
2026-07-17 12:31:29 +01:00
Peter Steinberger
c3f5526285 fix(desktop): use native system notifications (#109901)
* fix(desktop): use native system notifications

* fix(desktop): declare notification dependency MSRV

* fix(desktop): select notification backends per platform
2026-07-17 12:24:46 +01:00
Peter Steinberger
9b5eb04221 improve(tests): tighten async polling across suites (#109919)
* test: tighten signal delivery polling

* test: tighten async polling across suites

* test: use virtual time for signal ingress drain
2026-07-17 12:20:58 +01:00
ooiuuii
ecfcaa07e6 fix(shell): keep Git Bash coreutils on PATH (#108136)
* fix(windows): expose Git Bash coreutils to commands

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

* test(windows): inject duplicate PATH variants

* test(windows): run Git Bash integration in CI

* refactor(windows): keep shell env helper private

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 12:15:46 +01:00
Peter Steinberger
f3d1f02dc1 refactor: move MCP OAuth state to SQLite (#109844)
* refactor(mcp): move OAuth state to SQLite

* refactor(mcp): tighten OAuth module boundaries

* chore: refresh PR merge ref

* fix(mcp): align storage docs and merge checks

* fix(mcp): surface OAuth reauthorization status
2026-07-17 12:15:16 +01:00
Peter Steinberger
00a64f6e95 ci: bound Blacksmith sticky disk growth (#109934) 2026-07-17 12:13:28 +01:00
Kyle Klouzal
e316e1c440 feat(discord): show subagent progress (#95604)
* feat(discord): show subagent progress

Co-authored-by: Kyle Klouzal <kklouzal@users.noreply.github.com>

* fix(discord): serialize progress cleanup ownership

Co-authored-by: Kyle Klouzal <kklouzal@users.noreply.github.com>

* test(discord): type progress state fixtures

* refactor(discord): split subagent progress state

* fix(discord): persist terminal progress outcomes

* fix(discord): narrow persisted cleanup rows

* refactor(discord): keep progress internals private

* perf(discord): preserve lazy progress loading

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

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Kyle Klouzal <kklouzal@users.noreply.github.com>
2026-07-17 12:02:33 +01:00
Peter Steinberger
b2e34b03b5 test: serialize Vitest mock resolution in isolate:false shared workers (#109874)
* test: serialize concurrent vitest mock resolution in the non-isolated runner

Root-causes the subagent-orphan-recovery flake (main run 29566318167, shard
agentic-agents-core-subagents): "includes last human message in resume when
available" and "adds config change hint..." received the bare resume template
because prod code called a different readSessionMessagesAsync mock instance
than the one the test configured.

Mechanism: vitest's BareModuleMocker.resolveMocks has no in-flight guard.
pendingIds is cleared only after all parallel resolveId RPCs settle, and every
registration re-invalidates the mock module node. In a shared isolate:false
worker, leaked async work from an earlier file (a real-timer dynamic import)
triggers a fetchModule while the next file's vi.mock registrations are still
pending, starting a second concurrent resolution pass over the same
pendingIds. The slower pass re-registers each manual mock and wipes the
already-evaluated mock module mid-import-chain: importers evaluated before the
wipe (the test file's own binding, subagent-orphan-recovery.test.ts:8) keep
factory instance A while later importers (subagent-orphan-recovery.ts via
test line 16) instantiate a fresh instance B. Only inline-factory mocks split;
vi.hoisted-stable mocks are immune, matching the CI failure signature exactly.

Fix: OpenClawNonIsolatedRunner installs a coalescing wrapper around
moduleRunner.mocker.resolveMocks (once per worker) so concurrent callers share
one pass and registration happens exactly once before any awaiting import
proceeds.

Proof:
- Deterministic repro (poison file leaving a 1ms recurring dynamic-import
  timer + resolveId jitter on session-transcript-readers) reproduced the exact
  CI assertion failures at lines 755/772 on the unfixed runner and passes 5/5
  with the fix.
- New unit tests cover coalescing, idempotent install, and fresh passes.
- Stress: 10x subagent-orphan-recovery.test.ts and 5x the full
  agentic-agents-core-subagents file set (63 files, 1220 tests) at
  OPENCLAW_VITEST_MAX_WORKERS=6, all green.

* test: requeue mock ids queued during an in-flight resolveMocks pass

Review follow-up to the resolveMocks serialization pin: upstream snapshots the
pendingIds contents at pass start and reassigns the static to [] at the end,
so ids queued during the pass's RPC window land in the abandoned array. Pure
coalescing would silently drop those registrations (upstream's racy second
pass previously processed them). The wrapper now captures the queue reference
before each pass, requeues ids pushed past the processed count, and drains
until the queue is empty, so every coalesced caller's vi.mock registration is
applied before its fetch proceeds.

Proof: new unit test "registers ids queued while a pass is in flight before
callers proceed"; deterministic zombie+jitter repro still passes 5/5; full
agentic-agents-core-subagents file set green at OPENCLAW_VITEST_MAX_WORKERS=6.

* test: chain resolveMocks passes per caller instead of sharing one pass

The coalescing pin regressed shard agentic-agents-core-auth
(models-config.providers.auth-provenance.test.ts, runs 29570918219 and
29571513381): sharing one in-flight pass broke the mocker's freshness
invariant. Upstream gives every resolveMocks caller a pass that starts at or
after its call, so ids the caller queued (vi.doUnmock before dynamic imports
in that file's beforeAll/beforeEach) are always registered before its fetch
proceeds. A coalesced caller could instead ride a pass snapshotted before its
ids were queued and import with mock state unresolved. Reproduced locally on a
cold transform cache: the file then loaded the real provider-auth warm worker
plus a live oauth-manager refresh guarded by a 120s withRefreshCallTimeout
(the 105-142s stalls and the "Test timed out in 120000ms" CI failure), and the
real resolveProviderSyntheticAuthWithPlugin returned undefined (the
mode:"none" assertion failure at line 348).

The wrapper now chains each caller onto its own sequential pass. This keeps
both invariants: serialization (a pass queued behind an in-flight one sees the
cleared queue and no-ops, so a snapshot is never registered or its mock
modules invalidated twice - the original subagent-orphan-recovery disease) and
freshness (each caller's pass starts at or after its call). Abandoned-id
requeue is preserved so ids pushed during a pass's RPC window are registered
by the next chained pass instead of dropped.

Proof:
- Cold-cache auth shard (37 files, 528 tests): failed 105-142s with the
  coalescing pin (also with a coalescing-only variant), passed 20s with the
  unfixed runner, passes 3/3 in ~20-30s with the chained pin.
- Long-timer instrumentation pinpointed the stall: provider-auth warm worker
  spawn plus oauth-manager withRefreshCallTimeout delay=120000.
- Original zombie+jitter orphan-recovery repro still passes 5/5.
- Warm agentic-agents-core-subagents (63 files, 1220 tests) and auth shard
  green at OPENCLAW_VITEST_MAX_WORKERS=6; wrapper unit tests updated to
  assert serialization, freshness, requeue, idempotent install.
2026-07-17 11:54:54 +01:00
Peter Steinberger
15959f34f4 refactor(ci): remove retired window-open declaration (#109936) 2026-07-17 11:53:57 +01:00
Peter Steinberger
66aa2eda9d fix(cli): report malformed plugin JSON paths (#109916)
* fix(cli): report malformed plugin JSON paths

Co-authored-by: 丁宇婷0668001435 <ding.yuting@xydigit.com>

* test(google-meet): keep CLI test on plugin boundary

---------

Co-authored-by: 丁宇婷0668001435 <ding.yuting@xydigit.com>
2026-07-17 11:53:23 +01:00
Peter Steinberger
d3143ced6d perf(ci): collapse remaining per-PR sticky-disk minters to O(1) keys (#109929)
The installation hit Blacksmith's backing-disk cap because sticky keys
embedded PR numbers and content hashes, minting a new disk per PR and
per input change until every mount 429-failed fleet-wide. node-deps
(#109752) and ext-boundary (#109804) were already re-keyed; this
converts the last two minters and audits the third suspect.

Keys changed:
- Vitest fs transform cache: `vitest-fs-v2-<pr-N|protected>-...` ->
  the one existing `vitest-fs-v2-protected-<os>-<arch>-node-<ver>`
  disk. Entries are content-hash keyed (vitest sha1 over
  id+content+NODE_ENV+version+env config), so cross-PR sharing is safe
  by construction: PRs now mount the protected snapshot directly
  (read-only, commit false) and the separate PR-only seed mount is
  deleted. Writers (non-PR shard writer + scheduled warm run) keep
  explicit commit true. Disk count: 1 + O(open PRs) -> 1.
- Gradle: `gradle-v1-<task>-<pr-N|protected>-<hashFiles(deps)>` ->
  `gradle-v2-<task>`. Task scope stays (light ktlint must not seed
  heavy build lanes); PR number and dependency hash leave the key. The
  dependency hash moved to an in-job fingerprint marker that makes the
  non-PR writer rebuild its snapshot cold when inputs change, bounding
  disk growth; PR mounts are read-only and safely reuse stale
  snapshots because Gradle caches are content-addressed. Disk count:
  O(tasks x PRs x dependency bumps) -> O(tasks) (7 today).
- Docker builder (useblacksmith/setup-docker-builder): audited, out of
  scope. The action owns its key internally and always uses the repo
  name only (src/setup_builder.ts getStickyDisk), so it is already one
  disk per installation repo and cannot mint per-PR disks.

PR warm-path behavior changes:
- Vitest: PRs lose only PR-local warm entries for files the PR itself
  changed (previously persisted on the pr-N disk between pushes);
  changed files re-transform once per push, unchanged files still hit
  the protected snapshot. PRs touching transform inputs
  (lockfile/tsconfig/package.json) run cold per push since the
  generation wipe is now local to the discarded clone.
- Gradle: dependency-bump PRs get warmer (stale-but-valid protected
  snapshot instead of a cold fresh key); other PRs are unchanged.

Deleted `.github/workflows/pr-cache-cleanup.yml`: it existed for the
per-PR cache layer (#109425) and only deleted GitHub actions/cache
archives, which GitHub's own LRU/TTL eviction already handles for the
remaining fork/Windows per-PR archive paths.

Guards: pinned the O(1) vitest key + non-PR commit gate, added a
Gradle per-task key/writer/fingerprint guard, added a repo-wide scan
asserting no useblacksmith/stickydisk key ever contains
github.event.pull_request.number or hashFiles(), and replaced the
cleanup-workflow assertions with a stays-deleted check.
2026-07-17 11:52:32 +01:00
Peter Steinberger
d96c279c39 refactor(whatsapp): scope temp cleanup to each test (#109925)
* test(whatsapp): use shared temp-dir cleanup

* test(whatsapp): keep temp cleanup plugin-local
2026-07-17 11:47:27 +01:00
Peter Steinberger
5c21b70144 fix(google-meet): preserve attendance CSV row boundaries (#109926)
* fix(google-meet): harden attendance CSV export

* chore: defer google meet release note
2026-07-17 11:47:00 +01:00
Peter Steinberger
819c92d175 fix(line): prevent silent webhook loss after acknowledgment (#109819)
* fix(line): adopt durable ingress drain with ack gated on spool write

LINE acked webhooks 200 before processing events detached, so a crash or
dispatch failure silently lost inbound messages. Events now enqueue their raw
JSON into the channel ingress queue before the webhook responds; dispatch,
retry, dead-letter, and completion tombstones run through the core drain.
The in-memory replay guard is deleted; tombstone retention (30d/4096)
strictly covers its old 10min/4096 window, and message-id keys preserve the
guard keyspace so redeliveries under changed webhookEventIds still dedupe.

Autoreview: secret scanner false-positive on HMAC test fixtures
(test-channel-secret); full manual review of all five files + test matrix
performed instead. Part of the #109657 fleet adoption program (wave 1).

* style(line): oxfmt pass on drain adoption files

* fix(line): cap repeated ingress drain deliveries

* fix(line): preserve ingress lifecycle bounds

* style(line): satisfy ingress lint gates
2026-07-17 11:45:18 +01:00
Max Huang
3e838782b1 feat(feishu): bot-to-bot conversation support with @mention handling (#89783)
* feat(feishu): support bot-authored mentions

Co-authored-by: heyumeng154-alt <260365965+heyumeng154-alt@users.noreply.github.com>

* test(feishu): isolate bot name resolver state

* fix(feishu): verify bot mention identity

* docs: refresh Feishu channel map

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: heyumeng154-alt <260365965+heyumeng154-alt@users.noreply.github.com>
2026-07-17 11:44:00 +01:00
wuqxuan
d7056abbc8 fix(cli): reject missing separator after config path brackets (#109580)
* fix(cli): reject missing separator after config path brackets

* fix(cli): simplify bracket path separator validation

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 11:42:58 +01:00
mushuiyu886
3a268c08df fix(sqlite): stop mount probes blocking database startup (#109432)
* fix(sqlite): bound fallback mount classification

* test(sqlite): cover mount probe failure policy

* test(sqlite): use tracked mount probe fixtures

* perf(sqlite): keep mount result import type-only

* style(sqlite): format mount probe result

* perf(sqlite): defer mount process module loading

* perf(sqlite): avoid eager mount parser dependency

* refactor(sqlite): isolate lock error detection

* revert: keep sqlite lock errors colocated

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 11:41:25 +01:00
Peter Steinberger
c45f299cea fix(slack): adopt durable ingress across Bolt and relay (#109910)
* fix(slack): adopt durable ingress drain across Bolt and relay with logical twin guard

Slack events now enqueue their raw envelope durably before the transport ack
on all three modes: the Bolt receiver wrap covers Socket Mode and HTTP
(event_id = Events API event_id), and relay frames enqueue before the router
ack (keyed by logical team:channel:ts since router delivery-id redelivery
stability is undocumented). Dispatch, retry, dead-letter, and 30d/20k
tombstones run through the core drain; claimed relay events retry until the
relay source reattaches after a restart. The in-memory + persistent inbound
delivery caches and the app-mention race machinery are deleted.

One dedupe layer deliberately survives: Slack emits both a message and an
app_mention event (distinct event_ids) for a single mention post, so a new
claim-based dispatch guard keyed on logical (team, channel, ts) collapses the
twins — commit at turn adoption, release on gated/abandoned dispatch so the
surviving twin can re-run the same gate. 24h/20k retention mirrors the
retired persistent cache.

Slack monitor test state now scopes a fresh OPENCLAW_STATE_DIR per test;
persisted guard keys otherwise dedupe unrelated fixture messages that reuse
ts values. Five reaction tests in monitor.tool-result.test.ts are flaky on
clean origin/main under full-suite load (verified 2-of-3 baseline runs);
tracked separately.

Autoreview: secret scanner false-positives on token-shaped test fixtures
(three files); full manual review performed instead, which caught and fixed
the twin-guard regression. Part of the #109657 fleet adoption program.

* fix(slack): remove unused ingress exports

* chore(slack): prune max-lines baseline

* docs(plugin-sdk): refresh API baseline hash

* test(slack): type dispatch mock argument

* test(slack): use managed temp root
2026-07-17 11:38:54 +01:00
Peter Steinberger
7817a6cf24 fix(ollama): failed inspections must not advertise tools capability (#109921) 2026-07-17 11:38:21 +01:00
clawsweeper[bot]
2dee283ad0 Open fix(infra): import legacy plugin state partially (newest-first) instead of skipping when capacity is short (#109679) 2026-07-17 16:08:04 +05:30