Commit Graph

39111 Commits

Author SHA1 Message Date
Peter Steinberger
d2e07d89ae test(config): split help quality fixtures (#110268) 2026-07-18 02:06:38 +01:00
Patrick Erichsen
f9b860fc84 feat(plugins): order featured catalog by recency (#110273) 2026-07-17 18:06:13 -07:00
Peter Steinberger
1ca26c508d fix(gateway): reject malformed MCP sandbox policy (#110264)
Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-07-17 18:00:46 -07:00
maweibin
3a4e2ef65f fix(auto-reply): treat U+2028/U+2029 as paragraph boundaries when chunking (#103518)
* fix(auto-reply): treat U+2028/U+2029 as paragraph boundaries when chunking

chunkByParagraph normalized only CR/CRLF before blank-line paragraph detection,
so model output using Unicode LINE/PARAGRAPH SEPARATOR (U+2028/U+2029) instead
of a blank line was not split at those boundaries and fell back to length-based
splitting. Normalize U+2028/U+2029 to \n alongside CR/CRLF, matching how the
Control UI markdown renderer handles them.

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

* fix(auto-reply): normalize U+2028 as line break, U+2029 as blank-line paragraph boundary

Distinguish U+2028 (LINE SEPARATOR) from U+2029 (PARAGRAPH SEPARATOR):
U+2029 becomes \n\n (blank line — paragraph boundary) while U+2028
becomes \n (single newline — intra-paragraph line break).

The original fix mapped both to \n, so standalone U+2029 still
produced single-line text without a blank-line gap — paragraph
detection failed. The combined U+2028
 input accidentally
produced the right blank-line sequence, which masked the bug.

Adds individual tests for lone U+2029 (splits at paragraph boundary),
lone U+2028 (stays within paragraph), and consecutive U+2028

(combined blank line — matches \n\n behavior).

* test(auto-reply): simplify Unicode separator cases

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 01:53:25 +01:00
Peter Steinberger
96add8ec3a fix(gateway): reject malformed MCP sandbox policy (#110275)
* fix(gateway): reject malformed MCP sandbox policy

* style(test): format MCP sandbox cases
2026-07-18 01:50:55 +01:00
Peter Steinberger
92e8e8bca6 test: move deferred-event-buffer test to its packages/ai owner and drop dead protocol test 2026-07-17 17:36:48 -07:00
zengLingbiao
88263e34b4 test(cron): add unit tests for assertCronDeliveryInputNonBlankFields (#98668) 2026-07-17 17:21:27 -07:00
zengLingbiao
2666cf7174 test(shared): add unit tests for createDeferredEventBuffer (#98670) 2026-07-17 17:21:18 -07:00
zengLingbiao
5982882055 test(tools): add unit tests for toToolProtocolDescriptor and toToolProtocolDescriptors (#98797) 2026-07-17 17:21:08 -07:00
zengLingbiao
256a2ece73 test(shared): add unit tests for modelKey (#98795) 2026-07-17 17:20:59 -07:00
zengLingbiao
e517d187d2 test(utils): add unit tests for parseJsonWithJson5Fallback (#98801)
* test(utils): add unit tests for parseJsonWithJson5Fallback

* test(utils): verify JSON.parse fast path with spy, per ClawSweeper review

- Add vi.spyOn to prove JSON.parse is called (not JSON5) for strict JSON
- Add spy to prove JSON5.parse is called on fallback path
- Run full src/utils test suite (263 tests passed)
2026-07-17 17:20:16 -07:00
zengLingbiao
f64c35be30 test(utils): add unit tests for safeJsonStringify (#98667) 2026-07-17 17:20:03 -07:00
zengLingbiao
1d64790bf2 test(shared): add unit tests for normalizeNodePresenceAliveReason (#98802)
* test(shared): add unit tests for normalizeNodePresenceAliveReason

* fix(test): add missing bg_app_refresh and significant_location assertions
2026-07-17 17:19:54 -07:00
DaigoSoup
025cecf1f9 fix: avoid false macOS gateway restart failures (#109955)
* fix: wait through launchd KeepAlive restart throttling

* ci: retrigger checks

* test: make update restart test platform-independent

---------

Co-authored-by: Josh Lehman <josh@martian.engineering>
2026-07-17 17:19:23 -07:00
Peter Steinberger
897198b9f5 feat(gateway): typed structured questions on openclaw.chat with live option cards (#110242)
* feat(gateway): typed structured questions on openclaw.chat

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

* chore: keep OnboardingWelcome type module-local

* chore(protocol): regenerate Swift bindings for the chat question field
2026-07-18 01:14:44 +01:00
Heming Zeng
72e4b77921 fix(config): prune cron-run descendant sessions (#105633) 2026-07-18 01:10:33 +01:00
zengLingbiao
73685b4e7c fix(mcp): guard malformed CSP JSON decode (#108883)
When decodeMcpAppSandboxCsp receives a base64-encoded value that
decodes to non-JSON text, JSON.parse throws an unhandled exception.
Add a try-catch so the function returns undefined instead of crashing.
2026-07-17 17:09:21 -07:00
zengLingbiao
ec35d6b5ba test(shared): add unit tests for agent liveness state helpers (#98546) 2026-07-17 17:09:02 -07:00
zengLingbiao
58a86297f8 test(shared): add unit tests for parseConfigPathArrayIndex (#98543) 2026-07-17 17:08:50 -07:00
zengLingbiao
bd966771a7 test(utils): add unit tests for formatTokenCount (#98541)
* test(utils): add unit tests for formatTokenCount

* fix(test): use Number.NaN/Number.POSITIVE_INFINITY per oxlint unicorn/prefer-number-properties

* test(utils): fold formatTokenCount boundary tests into existing usage-format test

Move edge case coverage (invalid inputs, zero/negative, exact boundaries,
thousands overflow) into src/utils/usage-format.test.ts instead of a
separate colocated test file per reviewer feedback.
2026-07-17 17:08:42 -07:00
Peter Steinberger
a6102690dd perf(ci): cut the pre-fan-out critical path and bin canonical main runs (#110183)
* perf(ci): cut the pre-fan-out critical path on canonical runs

Two changes to the run head and matrix shape:

1. runner-admission was a hosted 90s sleep every run queued behind
(observed 1.7min hosted-queue latency before the sleep started). The
debounce now lives at the tail of preflight: heavy jobs all need
preflight, so a superseding main push still cancels the run before
fan-out while only one 4 vCPU runner has been spent, and preflight's
own work usually exceeds the window so the residual sleep is zero.
security-fast (hosted, dependency-free) starts immediately.

2. Canonical main pushes now use the compact bin plan like PRs: the
82-job named matrix drained the runner pool for ~4.5min (job starts
trickled from minute 5.2 to 9.7 in run 29592647843) with no
branch-protection consumer for per-shard names on main. Coverage is
identical; dispatch/release-gate runs keep the full named matrix.

* perf(test): boot TUI PTY suite fixtures concurrently

tsx+TUI startup dominated the harness file's wall time and the three
suite PTYs booted serially. Boot them concurrently in beforeAll
(allSettled so a failed boot still assigns survivors for afterAll
cleanup); the env-specific fixtures never receive input, so their tests
only await their own readiness output. The slow-startup test now proves
frame ordering on the append-only output, which the old sequential
waits did not. File wall 10.2s -> ~4.9s, 3/3 repeat runs green.

* docs(ci): align gate and debounce descriptions with the removed admission job

* test(tooling): wait for readiness file content, not existence

writeFileSync creates the file before its bytes land, so the existence
poll raced the child's write on loaded runners and read an empty ready
file (observed in compact-small-4, run 29615028678). Poll for non-empty
content at both readiness sites.
2026-07-18 01:05:07 +01:00
Peter Steinberger
987e2ff436 fix(gateway): preserve provider failure outcomes (#110252) 2026-07-18 01:04:37 +01:00
Peter Steinberger
d371ea1f01 perf(agents): wave-1 tool output contracts for code mode (#110215)
* feat(agents): keep output contracts complete across opaque schema leaves

* test(agents): add code mode schema-hint hot-path micro-benchmark

* test(agents): count raw-first inspection execs per tool in live bench

* feat(agents): expand compact output contract hints

* feat(agents): declare wave one tool output contracts

* docs(tools): list built-in output contracts

* fix(agents): bound union scans before literal-union analysis

* fix(agents): keep wave-1 contract schemas module-local and type-exact
2026-07-18 01:02:18 +01:00
Peter Steinberger
ec8f6e5e03 feat(browser): add secure per-tab copilot panel (#109817)
* feat(browser): add copilot security contracts

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

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

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

* refactor(browser): separate copilot gateway hint custody

* fix(browser): preserve legacy pairing parse shape

* fix(browser): harden copilot lifecycle custody

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

* fix(browser): enforce copilot lifecycle boundaries

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

* style(browser): format copilot sources

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

* fix(browser): preserve copilot consent revocation

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

* refactor(browser): split copilot custody owners

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

* test(browser): normalize websocket array buffers

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

* chore(protocol): regenerate Swift gateway models

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

* refactor(browser): model copilot runtime entrypoints

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

* fix(browser): honor extension build boundaries

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

* test(gateway): assert targeted chat delivery

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

* test(gateway): cover targeted delivery calls

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

* fix(browser): declare copilot build dependencies

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

* fix(ci): clear browser copilot gate failures

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

* test(ci): cover copilot lint exclusion

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

* fix(browser): gate copilot on relay custody

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

* test(browser): bound copilot relay frames

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

---------

Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>
2026-07-18 01:00:23 +01:00
xingzhou
c6d4559811 fix(mcp): doctor probes no longer start every server at once (#109870)
* fix(mcp): bound doctor server checks

* fix(mcp): defer doctor concurrency helper loading

* fix(mcp): preserve doctor check coverage

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 00:59:10 +01:00
Peter Steinberger
601ffa2530 refactor(channels): move inbound turn execution into core (#110095)
* refactor(channels): centralize turn execution lifecycle

* refactor(extensions): adopt core channel turn plans

* test(channels): ratchet modern dispatch ownership

* chore(channels): drop stale max-lines exemption

* fix(channels): allow async delivery error cleanup

* test(channels): await async delivery cleanup

* test(channels): await delivery error callbacks

* fix(channels): preserve delivery error contract

* fix(plugin-sdk): preserve channel inbound declarations

* test(channels): exercise core delivery plans

* fix(channels): await delivery error cleanup

* fix(channels): preserve async cleanup contract

* refactor(channels): trim dispatch boilerplate

* fix(channels): mask observe-only dispatch results

* refactor(channels): delete unused dispatch exports

* fix(msteams): preserve resolver config overrides

* refactor(channels): keep Teams turn config internal

* test(plugins): drop retired Teams runtime export guard
2026-07-18 00:55:46 +01:00
Peter Steinberger
f7e386d26d feat(plugins): emit agent_settled when a session run fully quiesces (#110174) 2026-07-18 00:53:40 +01:00
Patrick Erichsen
d7d358d3f6 fix(sessions): enforce maintenance cap ownership (#110241) 2026-07-17 16:52:17 -07:00
Peter Steinberger
1607da89b7 fix: Claude CLI turns avoid observability overhead when unused (#110246)
* perf(agents): gate Claude CLI diagnostics on listeners

* refactor(infra): keep diagnostic listener state private

* fix(agents): bound serialized Claude diagnostics

* chore: remove release-owned changelog entry
2026-07-18 00:51:32 +01:00
VectorPeak
af917f9235 fix(config): render validation array indices with brackets (#104935)
* fix(config): format validation indexes at display boundary

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>

Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>

* fix(config): preserve identity avatar issue paths

Co-authored-by: VectorPeak <73048950+VectorPeak@users.noreply.github.com>

---------

Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 00:48:39 +01:00
wings1029
20172aa3ca fix(sessions): estimate file content size before Buffer allocation (#105477)
* fix(sessions): check file content size before Buffer allocation

Move the UTF-8 byte-length pre-check before Buffer.from() so oversized
session file content is rejected without first materialising the full
encoded payload. Buffer.byteLength is a native C++ call that counts
bytes without allocating.

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

* test(gateway): prove oversized session write avoids buffer

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 00:48:24 +01:00
Peter Steinberger
03d5d88a14 refactor(config): split root zod schema (#110238) 2026-07-18 00:38:12 +01:00
Peter Steinberger
c1ee9c6fb1 fix: network error hardening, session short-id entropy, extension load caching (#110196)
* fix(infra): harden network client errors, session short ids, and extension load caching

* fix(infra): preserve injected dispatcher seams and drop the uncached extension loader
2026-07-18 00:35:13 +01:00
tzy-17
e113b40789 fix(skills): filter NaN from Date.parse in history scan session cursors (#109741)
* fix(skills): filter NaN from Date.parse in history scan reviewed times

* fix(skills): filter NaN from Date.parse in history scan session cursors

runSkillHistoryScanCore built pending.sessionCursors by mapping
batch.sessions through Date.parse(session.updatedAt) without filtering
NaN. An invalid updatedAt timestamp would produce a cursor whose
updatedAtMs is NaN, breaking the resumed-candidate equality check
(candidate.updatedAtMs === cursor.updatedAtMs is always false for NaN)
and forcing every resume into the unreplayable-scan recovery branch.

Mirror the reviewedTimes NaN filter added in the previous commit by
dropping cursors whose Date.parse result is not finite. This keeps the
resumed-candidate matching predicate sound when an upstream feed ever
hands us a non-ISO timestamp.

* fix(skills): export toStoredState directly instead of __testing wrapper

The knip production deadcode scan flags __testing as an unused export
because test files are not entry points in that mode. Export toStoredState
as a named export instead of wrapping it in a __testing object, matching
the pattern of other test-accessible helpers in the codebase.

* fix(skills): remove toStoredState export to avoid knip unused-export flag

The knip production deadcode scan flags any export that is only
referenced by test files. Since toStoredState is not called from
production code, exporting it (whether as __testing or as a named
export) triggers the check-dependencies CI gate.

Remove the export and the toStoredState-specific regression tests.
The core fix (filtering NaN sessionCursors in resumePendingForBatchScan)
is still covered by the existing scan-cursor tests.

* fix(skills): remove unused SkillHistoryScanPromptSession type import

Cherry-picking the reviewedTimes NaN filter restored a type import
that was only needed by the original __testing-based unit tests.
Those tests were removed in a later commit, leaving the import
unused and tripping eslint(no-unused-vars).

* fix(skills): preserve history scan resume batches

---------

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-07-17 16:34:21 -07:00
Vito Cappello
748fc04419 fix(update): classify unreadable plugin manifests (#110200)
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
2026-07-17 16:33:04 -07:00
wm0018
8c292ccd7d fix(cron): batch pending-media snapshot in session reaper to avoid O(SxT) loop (#105903)
* fix(cron): batch pending-media lookup in session reaper to avoid O(SxT) loop

* fix(cron): make pending-media snapshot lazy to avoid regressing idle sweeps

* fix(cron): defer unsorted pending-media snapshot

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 00:23:44 +01:00
Peter Steinberger
a428765337 fix(agents): run embedded gateway fallback on a fresh session after abnormal close (#110226) 2026-07-18 00:18:45 +01:00
qingminlong
07d97f6e8d fix(plugins): hide bundle commands when frontmatter uses on (#105013)
* fix(plugins): honor on frontmatter for bundle commands

* fix(plugins): honor bundle command invocation policy

Co-authored-by: qingminlong <qing.minlong@xydigit.com>

* test(plugins): tighten bundle command policy coverage

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 00:18:16 +01:00
Peter Steinberger
b0a2d02427 fix(ci): make plugin SDK API manifest mergeable (#110228) 2026-07-18 00:16:39 +01:00
Dallin Romney
a9dc393f7e test(qa): prove Codex auth product migration (#109291) 2026-07-17 16:10:23 -07:00
Peter Steinberger
abc7dffe4c fix(gateway): stop reporting user cancellations as gateway draining (#110220)
* fix(gateway): preserve agent cancel attribution

* chore: keep release note in PR body
2026-07-18 00:08:05 +01:00
Peter Steinberger
efd76b7392 refactor(config): split schema help metadata (#110218) 2026-07-18 00:02:17 +01:00
Peter Steinberger
781913025b improve: stream native sessions as hosts finish (#110211)
* perf: stream native session catalogs by host

* fix: satisfy session catalog CI contracts

* fix: retain changed-session refresh timing

* fix: keep catalog refresh helpers private
2026-07-17 23:59:57 +01:00
Peter Steinberger
9c2d38a596 fix: keep broken SSH sandbox refs agent-scoped (#110081)
* fix: isolate agent sandbox SecretRef owners

* fix: preserve SSH sandbox lifecycle secrets

* fix: preserve default SSH sandbox lifecycle secrets
2026-07-17 23:56:43 +01:00
wangyan2026
ccaaa42f52 fix(infra): archive plugin-state sidecar when canonical rows are equal or newer (#109832) (#110083)
* [AI] fix(infra): archive plugin-state sidecar when canonical rows are strictly newer (#109832)

Conflict detection in migrateLegacyPluginStateSidecar compared rows for byte equality but treated every mismatch as a conflict. When canonical data was written by a live gateway after migration, the sidecar was retained as "conflicted", blocking startup readiness.

Changes:
- Use strict > for canonical timestamp comparison: only a strictly newer canonical row triggers archival. Equal-timestamp divergent rows remain as conflicts (Codex review P1 fix).
- Update error message: "have different values; sidecar data is newer" instead of misleading "already existed in shared state"
- 17 plugin-state migration tests covering all timestamp scenarios

Related to #109832

* fix(state): clarify plugin sidecar conflicts

---------

Co-authored-by: Josh Lehman <josh@martian.engineering>
2026-07-17 15:55:16 -07:00
Leon-SK668
6caf637163 fix(hooks): prevent rejected inbound conversation claims (#109857)
* fix(hooks): honor rejected inbound conversations

* test(hooks): trim rejection fixture

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 23:52:58 +01:00
Peter Steinberger
9a93a52a8a feat(onboard): recommendations store with once-semantics and self-naming bootstrap (#110173)
* feat(onboarding): persist app recommendations once

* feat(onboarding): add self-naming birth sequence

* chore(wizard): hoist bootstrap-defer imports to the top of the module

* docs(bootstrap): persist agreed identity into IDENTITY.md and SOUL.md as well

* docs: regenerate docs map after onboarding plan merge

* fix(wizard): reuse a pending stored offer instead of rescanning apps

* fix(onboard): deduplicate bootstrap recommendations
2026-07-17 23:42:01 +01:00
Peter Steinberger
d957b157e0 fix(cron): queued jobs are lost after Gateway restart (#110159)
* fix(cron): recover queued runs after gateway restart

* chore: leave release notes to release automation
2026-07-17 23:24:59 +01:00
Peter Steinberger
5bab0c2ea8 feat(slack): support running as a real Slack user (user identity) (#109837)
* feat(slack): add user-identity config surface (session token/cookie)

Introduce an account-level identity discriminator ("bot" default | "user") for
the Slack channel, plus sessionToken/sessionCookie secret fields for the
browser-session (user) path. Schema enforces structural coupling only
(identity="user" rejects appToken/signingSecret/relay/non-default mode);
credential presence is deferred to runtime like bot/app tokens. Account entries
inherit the top-level identity. Adds env fallback (SLACK_SESSION_TOKEN/COOKIE,
default account only), secret-contract registration, provenance *Source fields,
and UI hints. Config surface only; resolver/transport are later phases.

* refactor(slack): identity-aware operation-token resolver + dedup

Route Slack read/write token selection through a single identity-aware
resolveSlackOperationToken: identity="user" selects the browser-session token
for both operations (companion cookie attached later at client construction),
identity="bot" keeps the exact userToken/botToken + userTokenReadOnly behavior.
Delete the duplicated token-selection gate in action-runtime and route direct
sends/DM opens through the shared resolver with identity-neutral error wording.
Behavior-neutral for bot identity; net non-test LOC -2.

* refactor(slack): retarget user identity to xoxp + companion app

Replace the abandoned browser-session (xoxc/xoxd) approach for identity="user"
with the official path: authenticate as the human via the existing userToken
(xoxp) while a companion app (appToken/socket or signingSecret/http) carries
events. Remove sessionToken/sessionCookie config, env vars, secret-contract
entries, resolver fields, and their tests. Invert the schema coupling so
identity="user" permits the companion-app transport credentials, and drop the
now-vestigial user-identity structural guard entirely (identity is a permissive
discriminator; credential presence is a runtime concern). Resolver returns the
user token for user-identity reads and writes. Behavior-neutral for bot
identity.

* feat(slack): user-identity provider transport (xoxp + companion app)

Wire the identity="user" event transport. The companion Slack app runs Socket
Mode (appToken) or HTTP (signingSecret) while Bolt authenticates as the human
via the user token (no bot token). Startup auth.test runs on the user token and
its user_id becomes the self/mention target and self-send dedupe id (Bolt's
lazy per-event authorize populates context.botUserId=user_id, so the existing
self-event middleware drops the human's own messages). Identity-aware token
requirements and diagnostics; the bot-token identity warning is suppressed for
user identity. Behavior-neutral for identity="bot".

* feat(slack): user-identity setup, doctor, and docs

Add the setup wizard, doctor/status, and documentation for identity="user".
The wizard collects a user token plus the companion-app transport credential
(app token for socket, signing secret for http) and only persists identity when
"user" so bot setups keep byte-identical generated config; doctor validates the
user token via auth.test and warns on a missing transport credential; account
inspection reports user-token status. Message actions are gated on the active
identity's credential so user accounts expose actions. Docs add the exact
companion-app recipe (user scopes, on-behalf-of-user message events, socket/http
examples, the DM/group-DM-only-via-user-scope note, and self-send dedupe).
Behavior-neutral for identity="bot".

* test(slack): isolate user-identity provider tests to fix parallel flake

The new user-identity provider tests shared the globalThis-stored Slack test
client/handlers across files under parallel isolate:false, so their reaction
closures could reference a prior file's state and intermittently fail sibling
monitor tests (monitor.tool-result reactions). Track started monitors and
abort/await them all in afterEach (even on failed assertions), reset the shared
auth.test/mock state, and dispose the global Slack test runtime per file via a
new disposeSlackTestRuntime helper. Full Slack suite green across repeated
parallel runs.

* fix(slack): regenerate channel config metadata after rebase

* fix(slack): resolve setup consistent-return and doctor dead-export lint

* style: format install script test

* docs(slack): regenerate docs map for user-identity section

* test(slack): use renamed createSlackBoltApp token param in interop test

The rebase folded main's new wrapReceiver test into the renamed
createSlackBoltApp signature (botToken -> token); update the call site.
2026-07-17 23:23:21 +01:00
Peter Steinberger
ecd285222c fix: harden recovered meeting browser sessions (#110089)
* fix(meeting-bot): harden browser session recovery

* chore: leave meeting notes to release generation

* docs: fix release-gate example lint
2026-07-17 23:20:51 +01:00