Commit Graph

70037 Commits

Author SHA1 Message Date
Peter Steinberger
57a3739622 fix(ci): regenerate docs_map for the live-tests heading 2026-07-17 21:25:29 -04:00
Wynne668
83da9500ae fix(node-host): guard Claude CLI pipe errors (#109794)
* fix(node-host): guard Claude CLI stdout/stderr pipe errors

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(node-host): make request mock generic to fix test-types CI failure

* test(node-host): harden child pipe regression

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 02:24:02 +01:00
sheyanmin
e57acb1d94 fix(tools-manager): bound GitHub releases response body to prevent unbounded read (#98480)
* fix(tools-manager): bound GitHub releases response body to prevent unbounded read

The agent helper-tool fallback for fd and ripgrep read GitHub's
latest-release response with Response.json(). That consumes the
complete remote body before parsing it, so a faulty or compromised
response could grow agent memory without a bound.

This change makes the release-metadata fetch use the shared
readResponseWithLimit helper with a 1 MiB cap.

Ref. https://github.com/openclaw/openclaw/pull/98480

* fix(tools-manager): use bounded release reader

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 02:22:49 +01:00
LiLan0125
3ec5ee6bb6 fix(cron): skip completed restart catchup slots (#101998)
* fix(cron): preserve exact restart boundaries

Co-authored-by: 李兰 0668001394 <li.lan3@xydigit.com>

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>

* fix(cron): suppress skipped restart slots

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
2026-07-18 02:19:00 +01:00
Peter Steinberger
7915203f47 test(ui): stabilize chat popover layout bounds (#110290) 2026-07-18 02:17:03 +01:00
Peter Steinberger
8fc859a26a fix: isolate macOS sessions.send follow-up test (#110291)
* test(gateway): isolate follow-up message count

* style(gateway): format follow-up status test
2026-07-18 02:15:58 +01:00
Peter Steinberger
afcca01f40 feat(sessions): raise default session-store disk budget to 10 GiB (#110221) 2026-07-18 02:14:39 +01:00
Peter Steinberger
71b9705029 test(agents): isolate model-call listener state (#110288) 2026-07-18 02:13:49 +01:00
ZOOWH
1c331b9b0f fix(clawrouter): sanitize attribution headers to ByteString (#106454)
* fix(clawrouter): sanitize bounded header ids

Co-authored-by: ZOOWH <xu.wenhan1@xydigit.com>

* fix(clawrouter): keep sanitized ids collision-resistant

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 02:12:53 +01:00
Peter Steinberger
9a30b607c5 test: speed up gateway async polling (#110289) 2026-07-18 02:11:50 +01:00
Peter Steinberger
0e3afe62c6 test: remove SIGTERM fixture readiness race (#110283) 2026-07-18 02:07:02 +01:00
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
Leon-SK668
dcd8f962e3 fix(qqbot): add timeouts to API response reads (#103855)
* fix(qqbot): add timeouts to API response reads

* fix(qqbot): use guarded request deadlines

---------

Co-authored-by: Alix-007 <li.long15@xydigit.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 02:06:09 +01:00
Wynne668
bcc44ba1b1 fix(whatsapp): resolve abortPromise when stop signal already fired (#109903)
* fix(whatsapp): resolve abortPromise when stop signal already fired

waitForClose() races on abortPromise, but a pre-aborted gateway stop
signal never settled that promise because the abort listener was skipped.
Resolve abortPromise immediately when abortSignal.aborted is already true.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(whatsapp): resolve tsgo TS18048 and test mock in pre-aborted abortPromise fix

- Extract params.abortSignal to local const so tsgo can narrow the type
  through else-if control flow, fixing TS18048: possibly undefined
- Remove setupAbortController/ownerAcquireAbortController.abort() from
  the constructor's pre-aborted branch so openConnection() still works
  when the stop signal was already fired at construction time
- Use createSocketWithTransportEmitter() mock in the new test so
  shutdown() cleanup has sock.end() and ws.removeListener() available

* fix(whatsapp): preserve pre-aborted setup cancellation

* fix(whatsapp): unify connection abort handling

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 02:04:59 +01: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
Peter Steinberger
6f0f6af62e fix(discord): preserve gateway messages across dispatch crashes (#110274)
* fix(discord): adopt durable ingress drain for gateway messages

Gateway MESSAGE_CREATE events dispatched with only an in-memory/persistent
5-minute dedupe; a crash between receive and dispatch lost the message (live
sessions replay via RESUME, but session state is memory-only so a cold
restart re-IDENTIFYs — stated platform limitation: the drain closes the
receive->dispatch window, not cold downtime). Raw API messages now journal
durably (event_id = message snowflake, lane per channel/thread) before
normalization; dispatch runs through the core drain with deferred claims,
fan-out adoption, gated settlement, and 30d/5k tombstones. The persistent
guard is deleted after its RESUME duplicate-delivery parity test. Edits stay
outside the queue: only MessageCreateListener is registered, MESSAGE_UPDATE
never dispatches, so snowflake tombstones cannot swallow edit turns; a future
edit dispatcher must namespace its event ids.

Autoreview blocked by codex sandbox network in the build stage; full manual
review performed. Part of the #109657 fleet adoption program (wave 2).

* style(discord): keep drain-internal types and dispatcher unexported

* refactor(discord): move message dispatcher to its own module for the dead-export gate

* fix(discord): shutdown dispatch releases claims instead of tombstoning

Landing autoreview reproduced a real loss race: a dispatch entering after
dispatcher shutdown (or with an aborted signal) returned completed, so the
drain tombstoned a message that never ran and a restarted gateway skipped it
forever. Aborted-before-dispatch now returns failed-retryable so the claim
releases for replay. Test type imports of drain-internal types converted to
factory-derived types so the dead-export gate and typecheck agree.
2026-07-18 01:58:19 +01:00
Peter Steinberger
2ca4d92f1a docs: live-test gateway isolation policy (session-owned dev gateway, operator approval for real instances) 2026-07-17 17:55:33 -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
Masato Hoshino
cc0a977dd5 fix(memory-wiki): prevent source ingest content loss during concurrent vault writes (#104209)
* fix(memory-wiki): serialize source ingest with vault mutations

* test(memory-wiki): make ingest lock proof deterministic

* test(memory-wiki): type queue spy receiver

* test(memory-wiki): keep queue spy lint-safe

* style(memory-wiki): format ingest lock proof

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 01:47:01 +01:00
wanyongstar
e244a2b2f6 fix(ci): bound docs-agent git fetch operations with timeout (#110026) 2026-07-17 17:40:14 -07:00
wanyongstar
ef75d4fcce fix(ci): bound linux-app-release git fetch with timeout (#110027) 2026-07-17 17:40:04 -07:00
wanyongstar
b130f96c6f fix(ci): bound macos-release git fetch with timeout (#109174)
## Summary
- Problem: The `git fetch` in `macos-release.yml` had no timeout bound, risking indefinite CI hangs on network stalls. Same pattern already fixed for Mantis Crabbox workflows in #108940.
- Solution: Add `timeout --signal=TERM --kill-after=10s 120s` before the `git fetch` command.
- What changed: Wrapped the `git fetch --no-tags origin` command with timeout.
- What did NOT change: All release logic remains unchanged.

## Real behavior proof
- **Behavior addressed:** CI macos-release could hang during git fetch.
- **Evidence:** Same timeout pattern as merged Crabbox fix (#108940 / 16c2bbb).
- **Change:** `timeout --signal=TERM --kill-after=10s 120s git fetch --no-tags origin` replaces `git fetch --no-tags origin`.

## Root Cause
- The git fetch was added before the timeout-bounding pattern was standardized across CI workflows.
2026-07-17 17:39:53 -07:00
wanyongstar
64dd2535dc fix(ci): bound docs-sync publish repo git clone (#109173)
## Summary
- Problem: The `git clone` of `openclaw/docs.git` in `docs-sync-publish.yml` had no timeout bound, risking indefinite CI hangs on network stalls. Same pattern already fixed for Mantis Crabbox workflows in #108940.
- Solution: Add `timeout --signal=TERM --kill-after=10s 120s` before the `git clone` command.
- What changed: Wrapped the `git clone` command with timeout, matching the bounded pattern from #108940.
- What did NOT change: All retry logic, publish sync steps, and non-network operations remain unchanged.

## Real behavior proof
- **Behavior addressed:** CI docs-sync-publish workflow could hang indefinitely during git clone of external docs repo.
- **Real environment tested:** Pattern analysis and cross-reference with already-merged Crabbox fix (#108940 / 16c2bbb).
- **Exact change:** `if timeout --signal=TERM --kill-after=10s 120s git clone \` replaces `if git clone \`.
- **Evidence after fix:** Same `timeout --signal=TERM --kill-after=10s 120s` wrapper applied to Crabbox source retrieval.
- **What was not tested:** Live CI run.

## Root Cause
- The git clone was added before the timeout-bounding pattern was standardized across CI workflows. Missing automated check for unbounded external git operations.
2026-07-17 17:39:45 -07:00
Peter Steinberger
4ed7273662 test: remove orphan module tests (#110272) 2026-07-18 01:37:57 +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
wangmiao0668000666
dc0285366e fix(msteams): bound probe token acquisition to request deadline (#106386)
* fix(msteams): bound probe token acquisition to request deadline

probeMSTeams() at extensions/msteams/src/probe.ts:75 and :89 awaited
tokenProvider.getAccessToken(...) for the Bot Framework and Microsoft
Graph token endpoints with no surrounding deadline. The Microsoft
Teams SDK does not carry an inherent timeout on these calls, so a
stalled Azure AD token endpoint pinned the probe indefinitely.

Wrap both awaits with withMSTeamsRequestDeadline (default
MSTEAMS_REQUEST_TIMEOUT_MS = 30_000), matching the pattern already
used by six other MS Teams call sites: attachments/bot-framework.ts:252,
attachments/graph.ts:258, monitor-handler/message-handler.ts:594/654/685/692,
attachments/download.ts:167, team-identity.ts:37.

The probe was the one missing site. No new helper, no SDK change.
The existing outer catch at probe.ts:138 and inner catch at probe.ts:110
convert the timeout into a ProbeMSTeamsResult with ok: false and a
structured error field.

Added probe.timeout.test.ts: real probeMSTeams() with vi.mock
injected never-resolving getBotToken/getGraphToken; asserts the call
returns within the 30s bound instead of hanging to the proof budget.

* test(msteams): drive probe timeout test with vi.useFakeTimers

The original probe.timeout.test.ts waited 90 seconds of wall-clock per
focused run (3 stalled cases racing against a real setTimeout budget).
Per ClawSweeper P2 (automation), this material deterministic CI cost can
slow or time out test shards.

Drive the withTimeout race (from @openclaw/fs-safe/dist/timing.js, uses
setTimeout + clearTimeout) via vi.useFakeTimers() so each stalled case
resolves in milliseconds. Add one new case that spies on withTimeout's
timeoutMs argument to assert the production default deadline is exactly
MSTEAMS_REQUEST_TIMEOUT_MS = 30_000, so the production contract is not
silently weakened by the fake-timer change.

Per-case wall-clock: 25ms / 3ms / 2ms / 1ms / 2ms (was: 30s / 30s / 30s /
2ms / n/a).

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

* fix(msteams): bound remaining token acquisition

* test(msteams): keep credential fixture unchanged

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 01:21:49 +01: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
13c0e7492a fix(test): converge Slack harness state across module reloads (#110255)
* fix(test): converge Slack harness state across module reloads

Five reaction tests in monitor.tool-result.test.ts failed whenever a sibling
file's vi.resetModules() ran earlier in the same non-isolated worker: the
cached globalThis __slackClient kept routing reactions to the OLD test-helpers
module's mocks while tests asserted on the recreated module's fresh mocks —
reactions 'never fired' (replies survived via freshly injected runtime).
slackTestState is now a globalThis-backed singleton so every module
incarnation and the cached client share one state object. Also: reaction
assertions wait on the mock (reactions apply via detached debounce/queue
work), and stale Bolt handler registrations clear per test/stop so
waitForSlackEvent cannot match a previous provider's handler. Proven with six
consecutive full extensions/slack runs (was ~50% failure).

* style(slack): bracket global test-state access for underscore lint
2026-07-18 01:17:11 +01: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
9a3231547b fix(macos): stop Canvas presents from stealing focus (#110245)
* fix(macos): stop Canvas presents from stealing focus

Agent-driven canvas.present/canvas.navigate activated the app with
NSApp.activate(ignoringOtherApps:), yanking keyboard focus from
whatever the user was doing. The Canvas panel's elevated window level
already keeps it visible without app activation, and user entry points
(AppNavigationActions) activate explicitly, so presentation now orders
the panel front without switching apps.

* fix(macos): order Canvas front without taking key focus

* fix(macos): drop showWindow from Canvas window presentation
2026-07-18 00:54:15 +01:00